CMS 3D CMS Logo

/afs/cern.ch/work/a/aaltunda/public/www/CMSSW_5_3_14/src/EventFilter/DTRawToDigi/plugins/DTDDUUnpacker.cc

Go to the documentation of this file.
00001 
00009 #include <DataFormats/FEDRawData/interface/FEDHeader.h>
00010 #include <DataFormats/FEDRawData/interface/FEDTrailer.h>
00011 
00012 #include <EventFilter/DTRawToDigi/interface/DTDDUWords.h>
00013 #include <EventFilter/DTRawToDigi/interface/DTControlData.h>
00014 
00015 #include <EventFilter/DTRawToDigi/interface/DTDataMonitorInterface.h>
00016 #include "FWCore/ServiceRegistry/interface/Service.h"
00017 
00018 #include <EventFilter/DTRawToDigi/plugins/DTDDUUnpacker.h>
00019 #include <EventFilter/DTRawToDigi/plugins/DTROS25Unpacker.h>
00020 
00021 #include "FWCore/MessageLogger/interface/MessageLogger.h"
00022 
00023 #include <iostream>
00024 
00025 using namespace std;
00026 using namespace edm;
00027 
00028 DTDDUUnpacker::DTDDUUnpacker(const edm::ParameterSet& ps) : dduPSet(ps) { 
00029   
00030   // the ROS unpacker
00031   ros25Unpacker = new DTROS25Unpacker(dduPSet.getParameter<edm::ParameterSet>("rosParameters"));
00032   
00033   // parameters
00034   localDAQ = dduPSet.getUntrackedParameter<bool>("localDAQ",false);
00035   performDataIntegrityMonitor = dduPSet.getUntrackedParameter<bool>("performDataIntegrityMonitor",false);
00036   debug = dduPSet.getUntrackedParameter<bool>("debug",false);
00037 
00038   // enable DQM if Service is available
00039   if(performDataIntegrityMonitor) {
00040     if (edm::Service<DTDataMonitorInterface>().isAvailable()) {
00041       dataMonitor = edm::Service<DTDataMonitorInterface>().operator->(); 
00042     } else {
00043       LogWarning("DTRawToDigi|DTDDUUnpacker") << 
00044         "[DTDDUUnpacker] WARNING! Data Integrity Monitoring requested but no DTDataMonitorInterface Service available" << endl;
00045       performDataIntegrityMonitor = false;
00046     }
00047   }
00048 
00049 }
00050 
00051 
00052 DTDDUUnpacker::~DTDDUUnpacker() {
00053   delete ros25Unpacker;
00054 }
00055 
00056 
00057 void DTDDUUnpacker::interpretRawData(const unsigned int* index32, int datasize,
00058                                      int dduID,
00059                                      edm::ESHandle<DTReadOutMapping>& mapping, 
00060                                      std::auto_ptr<DTDigiCollection>& detectorProduct,
00061                                      std::auto_ptr<DTLocalTriggerCollection>& triggerProduct,
00062                                      uint16_t rosList) {
00063 
00064   // Definitions
00065   const int wordSize_32 = 4;
00066   const int wordSize_64 = 8;
00067 
00068   int numberOf32Words = datasize/wordSize_32;
00069 
00070   const unsigned char* index8 = reinterpret_cast<const unsigned char*>(index32);
00071 
00072 
00074   /*  D D U   d a t a */
00076 
00077   // DDU header
00078   FEDHeader dduHeader(index8);
00079   if (dduHeader.check()) {
00080     if(debug) cout << "[DTDDUUnpacker] FED Header. BXID: "<<dduHeader.bxID()
00081                    << " L1ID: "<<dduHeader.lvl1ID() <<endl;
00082   } else {
00083     LogWarning("DTRawToDigi|DTDDUUnpacker") << "[DTDDUUnpacker] WARNING!, this is not a DDU Header, FED ID: "
00084                                             << dduID << endl;
00085   }
00086 
00087   // DDU trailer
00088   // [BITS] stop before FED trailer := 8 bytes
00089   FEDTrailer dduTrailer(index8 + datasize - 1*wordSize_64); 
00090 
00091   if (dduTrailer.check()) {
00092     if(debug) cout << "[DTDDUUnpacker] FED Trailer. Lenght of the DT event: "
00093                    << dduTrailer.lenght() << endl;
00094   } else {
00095     LogWarning("DTRawToDigi|DTDDUUnpacker") << "[DTDDUUnpacker] WARNING!, this is not a DDU Trailer, FED ID: "
00096                                             << dduID << endl;
00097   }
00098 
00099 
00100   // Control DDU data
00101   DTDDUData controlData(dduHeader,dduTrailer);
00102   // check the CRC set in the FED trailer (FCRC errors)
00103   controlData.checkCRCBit(index8 + datasize - 1*wordSize_64);
00104 
00105   // Check Status Words 
00106   vector<DTDDUFirstStatusWord> rosStatusWords;
00107   // [BITS] 3 words of 8 bytes + "rosId" bytes
00108   // In the case we are reading from DMA, the status word are swapped as the ROS data
00109   if (localDAQ) {
00110     // DDU channels from 1 to 4
00111     for (int rosId = 0; rosId < 4; rosId++ ) {
00112       int wordIndex8 = numberOf32Words*wordSize_32 - 3*wordSize_64 + wordSize_32 + rosId; 
00113       controlData.addROSStatusWord(DTDDUFirstStatusWord(index8[wordIndex8]));
00114     }
00115     // DDU channels from 5 to 8
00116     for (int rosId = 0; rosId < 4; rosId++ ) {
00117       int wordIndex8 = numberOf32Words*wordSize_32 - 3*wordSize_64 + rosId; 
00118       controlData.addROSStatusWord(DTDDUFirstStatusWord(index8[wordIndex8]));
00119     }
00120     // DDU channels from 9 to 12
00121     for (int rosId = 0; rosId < 4; rosId++ ) {
00122       int wordIndex8 = numberOf32Words*wordSize_32 - 2*wordSize_64 + wordSize_32 + rosId; 
00123       controlData.addROSStatusWord(DTDDUFirstStatusWord(index8[wordIndex8]));
00124     }
00125   }
00126   else {
00127     for (int rosId = 0; rosId < 12; rosId++ ) {
00128       int wordIndex8 = numberOf32Words*wordSize_32 - 3*wordSize_64 + rosId; 
00129       controlData.addROSStatusWord(DTDDUFirstStatusWord(index8[wordIndex8]));
00130     }
00131   }
00132 
00133   int theROSList;
00134   // [BITS] 2 words of 8 bytes + 4 bytes (half 64 bit word)
00135   // In the case we are reading from DMA, the status word are swapped as the ROS data
00136   if (localDAQ) {
00137     DTDDUSecondStatusWord dduStatusWord(index32[numberOf32Words - 2*wordSize_64/wordSize_32]);
00138     controlData.addDDUStatusWord(dduStatusWord);
00139     theROSList =  dduStatusWord.rosList();
00140   }
00141   else {
00142     DTDDUSecondStatusWord dduStatusWord(index32[numberOf32Words - 2*wordSize_64/wordSize_32 + 1]);
00143     controlData.addDDUStatusWord(dduStatusWord);
00144     theROSList =  dduStatusWord.rosList();
00145   }
00146 
00147 
00149   /*  R O S   d a t a */
00151 
00152   // Set the index to start looping on ROS data
00153   // [BITS] one 8 bytes word
00154   index32 += (wordSize_64)/wordSize_32; 
00155 
00156   // Set the datasize to look only at ROS data 
00157   // [BITS] header, trailer, 2 status words
00158   datasize -= 4*wordSize_64; 
00159 
00160   // unpacking the ROS payload
00161   ros25Unpacker->interpretRawData(index32, datasize, dduID, mapping, detectorProduct, triggerProduct, theROSList);
00162 
00163   // Perform DQM if requested
00164   if (performDataIntegrityMonitor) 
00165     dataMonitor->processFED(controlData, ros25Unpacker->getROSsControlData(),dduID);  
00166   
00167 }