Back to home page

Project CMSSW displayed by LXR

 
 

    


File indexing completed on 2024-04-06 12:10:31

0001 /** \file
0002  *
0003  *  \author  M. Zanetti - INFN Padova
0004  * FRC 060906
0005  */
0006 
0007 #include "DataFormats/FEDRawData/interface/FEDHeader.h"
0008 #include "DataFormats/FEDRawData/interface/FEDTrailer.h"
0009 #include "DataFormats/DTDigi/interface/DTDDUWords.h"
0010 #include "FWCore/ServiceRegistry/interface/Service.h"
0011 #include "FWCore/MessageLogger/interface/MessageLogger.h"
0012 #include "EventFilter/DTRawToDigi/plugins/DTDDUUnpacker.h"
0013 
0014 #include <iostream>
0015 
0016 using namespace std;
0017 using namespace edm;
0018 
0019 DTDDUUnpacker::DTDDUUnpacker(const edm::ParameterSet& ps) : dduPSet(ps) {
0020   // the ROS unpacker
0021   ros25Unpacker = new DTROS25Unpacker(dduPSet.getParameter<edm::ParameterSet>("rosParameters"));
0022 
0023   // parameters
0024   localDAQ = dduPSet.getUntrackedParameter<bool>("localDAQ", false);
0025   debug = dduPSet.getUntrackedParameter<bool>("debug", false);
0026 }
0027 
0028 DTDDUUnpacker::~DTDDUUnpacker() { delete ros25Unpacker; }
0029 
0030 void DTDDUUnpacker::interpretRawData(const unsigned int* index32,
0031                                      int datasize,
0032                                      int dduID,
0033                                      edm::ESHandle<DTReadOutMapping>& mapping,
0034                                      std::unique_ptr<DTDigiCollection>& detectorProduct,
0035                                      std::unique_ptr<DTLocalTriggerCollection>& triggerProduct,
0036                                      uint16_t rosList) {
0037   // Definitions
0038   const int wordSize_32 = 4;
0039   const int wordSize_64 = 8;
0040 
0041   int numberOf32Words = datasize / wordSize_32;
0042 
0043   const unsigned char* index8 = reinterpret_cast<const unsigned char*>(index32);
0044 
0045   //////////////////////
0046   /*  D D U   d a t a */
0047   //////////////////////
0048 
0049   // DDU header
0050   FEDHeader dduHeader(index8);
0051   if (dduHeader.check()) {
0052     if (debug)
0053       cout << "[DTDDUUnpacker] FED Header. BXID: " << dduHeader.bxID() << " L1ID: " << dduHeader.lvl1ID() << endl;
0054   } else {
0055     LogWarning("DTRawToDigi|DTDDUUnpacker")
0056         << "[DTDDUUnpacker] WARNING!, this is not a DDU Header, FED ID: " << dduID << endl;
0057   }
0058 
0059   // DDU trailer
0060   // [BITS] stop before FED trailer := 8 bytes
0061   FEDTrailer dduTrailer(index8 + datasize - 1 * wordSize_64);
0062 
0063   if (dduTrailer.check()) {
0064     if (debug)
0065       cout << "[DTDDUUnpacker] FED Trailer. Length of the DT event: " << dduTrailer.fragmentLength() << endl;
0066   } else {
0067     LogWarning("DTRawToDigi|DTDDUUnpacker")
0068         << "[DTDDUUnpacker] WARNING!, this is not a DDU Trailer, FED ID: " << dduID << endl;
0069   }
0070 
0071   // Initialize control data
0072   controlData.clean();
0073   controlData.addDDUHeader(dduHeader);
0074   controlData.addDDUTrailer(dduTrailer);
0075   // check the CRC set in the FED trailer (FCRC errors)
0076   controlData.checkCRCBit(index8 + datasize - 1 * wordSize_64);
0077 
0078   // Check Status Words
0079   vector<DTDDUFirstStatusWord> rosStatusWords;
0080   // [BITS] 3 words of 8 bytes + "rosId" bytes
0081   // In the case we are reading from DMA, the status word are swapped as the ROS data
0082   if (localDAQ) {
0083     // DDU channels from 1 to 4
0084     for (int rosId = 0; rosId < 4; rosId++) {
0085       int wordIndex8 = numberOf32Words * wordSize_32 - 3 * wordSize_64 + wordSize_32 + rosId;
0086       controlData.addROSStatusWord(DTDDUFirstStatusWord(index8[wordIndex8]));
0087     }
0088     // DDU channels from 5 to 8
0089     for (int rosId = 0; rosId < 4; rosId++) {
0090       int wordIndex8 = numberOf32Words * wordSize_32 - 3 * wordSize_64 + rosId;
0091       controlData.addROSStatusWord(DTDDUFirstStatusWord(index8[wordIndex8]));
0092     }
0093     // DDU channels from 9 to 12
0094     for (int rosId = 0; rosId < 4; rosId++) {
0095       int wordIndex8 = numberOf32Words * wordSize_32 - 2 * wordSize_64 + wordSize_32 + rosId;
0096       controlData.addROSStatusWord(DTDDUFirstStatusWord(index8[wordIndex8]));
0097     }
0098   } else {
0099     for (int rosId = 0; rosId < 12; rosId++) {
0100       int wordIndex8 = numberOf32Words * wordSize_32 - 3 * wordSize_64 + rosId;
0101       controlData.addROSStatusWord(DTDDUFirstStatusWord(index8[wordIndex8]));
0102     }
0103   }
0104 
0105   int theROSList;
0106   // [BITS] 2 words of 8 bytes + 4 bytes (half 64 bit word)
0107   // In the case we are reading from DMA, the status word are swapped as the ROS data
0108   if (localDAQ) {
0109     DTDDUSecondStatusWord dduStatusWord(index32[numberOf32Words - 2 * wordSize_64 / wordSize_32]);
0110     controlData.addDDUStatusWord(dduStatusWord);
0111     theROSList = dduStatusWord.rosList();
0112   } else {
0113     DTDDUSecondStatusWord dduStatusWord(index32[numberOf32Words - 2 * wordSize_64 / wordSize_32 + 1]);
0114     controlData.addDDUStatusWord(dduStatusWord);
0115     theROSList = dduStatusWord.rosList();
0116   }
0117 
0118   //////////////////////
0119   /*  R O S   d a t a */
0120   //////////////////////
0121 
0122   // Set the index to start looping on ROS data
0123   // [BITS] one 8 bytes word
0124   index32 += (wordSize_64) / wordSize_32;
0125 
0126   // Set the datasize to look only at ROS data
0127   // [BITS] header, trailer, 2 status words
0128   datasize -= 4 * wordSize_64;
0129 
0130   // unpacking the ROS payload
0131   ros25Unpacker->interpretRawData(index32, datasize, dduID, mapping, detectorProduct, triggerProduct, theROSList);
0132 }