Back to home page

Project CMSSW displayed by LXR

 
 

    


File indexing completed on 2024-09-07 04:36:08

0001 //-------------------------------------------------
0002 //
0003 //   Class: DTuROSRawToDigi
0004 //
0005 //   L1 DT uROS Raw-to-Digi
0006 //
0007 //
0008 //
0009 //   Author :
0010 //   C. Heidemann - RWTH Aachen
0011 //   J. Troconiz  - UAM
0012 //
0013 //
0014 //--------------------------------------------------
0015 
0016 #include "EventFilter/DTRawToDigi/plugins/DTuROSRawToDigi.h"
0017 
0018 #include "FWCore/MessageLogger/interface/MessageLogger.h"
0019 
0020 #include "DataFormats/DTDigi/interface/DTuROSControlData.h"
0021 #include "DataFormats/MuonDetId/interface/DTWireId.h"
0022 #include "EventFilter/DTRawToDigi/interface/DTROChainCoding.h"
0023 #include "EventFilter/Utilities/interface/DTCRC.h"
0024 
0025 #include <iostream>
0026 
0027 DTuROSRawToDigi::DTuROSRawToDigi(const edm::ParameterSet& pset) {
0028   produces<DTDigiCollection>();
0029   produces<std::vector<DTuROSFEDData>>();
0030 
0031   DTuROSInputTag_ = pset.getParameter<edm::InputTag>("inputLabel");
0032 
0033   debug_ = pset.getUntrackedParameter<bool>("debug", false);
0034 
0035   for (int i = FEDNumbering::MINDTUROSFEDID; i <= FEDNumbering::MAXDTUROSFEDID; i++)
0036     feds_.push_back(i);
0037 
0038   nfeds_ = feds_.size();
0039 
0040   Raw_token = consumes<FEDRawDataCollection>(DTuROSInputTag_);
0041   mapping_token_ = esConsumes<DTReadOutMapping, DTReadOutMappingRcd>();
0042 }
0043 
0044 DTuROSRawToDigi::~DTuROSRawToDigi() {}
0045 
0046 void DTuROSRawToDigi::produce(edm::Event& e, const edm::EventSetup& c) {
0047   DTDigiCollection digis;
0048   std::vector<DTuROSFEDData> words;
0049 
0050   if (!fillRawData(e, c, digis, words))
0051     return;
0052 
0053   auto uROSDTDigi_product = std::make_unique<DTDigiCollection>(digis);
0054   auto uROSDTWord_product = std::make_unique<std::vector<DTuROSFEDData>>(words);
0055 
0056   e.put(std::move(uROSDTDigi_product));
0057   e.put(std::move(uROSDTWord_product));
0058 }
0059 
0060 bool DTuROSRawToDigi::fillRawData(edm::Event& e,
0061                                   const edm::EventSetup& c,
0062                                   DTDigiCollection& digis,
0063                                   std::vector<DTuROSFEDData>& words) {
0064   edm::Handle<FEDRawDataCollection> data;
0065   e.getByToken(Raw_token, data);
0066 
0067   edm::ESHandle<DTReadOutMapping> mapping = c.getHandle(mapping_token_);
0068 
0069   for (int w_i = 0; w_i < nfeds_; ++w_i) {
0070     DTuROSFEDData fwords;
0071     process(feds_[w_i], data, mapping, digis, fwords);
0072     if (fwords.getfed() >= 0)
0073       words.push_back(fwords);
0074   }
0075 
0076   return true;
0077 }
0078 
0079 void DTuROSRawToDigi::process(int DTuROSFED,
0080                               edm::Handle<FEDRawDataCollection> data,
0081                               edm::ESHandle<DTReadOutMapping> mapping,
0082                               DTDigiCollection& digis,
0083                               DTuROSFEDData& fwords) {
0084   // Container
0085   std::vector<long> DTuROSWordContainer;
0086 
0087   // Header constituents
0088   int BOEevTy, DTuROSId;
0089 
0090   // Trailer constituents
0091   int chkEOE, evtLgth, CRC;
0092 
0093   // Hit counter
0094   std::map<uint32_t, int> hitOrder;
0095 
0096   //--> Header - line 1
0097 
0098   FEDRawData dturosdata = data->FEDData(DTuROSFED);
0099   if (dturosdata.size() == 0)
0100     return;
0101 
0102   lineFED = dturosdata.data();
0103   long dataWord = 0;
0104   int lines = 0;  // counting including header
0105   readline(lines, dataWord);
0106   const int posBOEevTy = 60;  // positions 60 -> 63
0107   const int posDTuROSId = 8;  // positions 8 -> 19
0108   const int posNslost = 52;   // positions 52 -> 55
0109   const int posSlotFED = 16;  // positions 16 -> 19
0110 
0111   BOEevTy = (dataWord >> posBOEevTy) & 0xF;
0112   DTuROSId = (dataWord >> posDTuROSId) & 0xFFF;
0113 
0114   if ((BOEevTy != 0x5) || (DTuROSId != DTuROSFED)) {
0115     if (debug_)
0116       edm::LogWarning("dturos_unpacker") << "Not a DTuROS FED " << DTuROSFED << " or header " << std::hex << dataWord;
0117     return;
0118   }
0119 
0120   fwords.setfed(DTuROSId);
0121   fwords.setheader1(dataWord);
0122 
0123   int newCRC = 0xFFFF;
0124   dt_crc::calcCRC(dataWord, newCRC);
0125 
0126   int crate = DTuROSId;
0127 
0128   //--> Header - line 2
0129 
0130   readline(lines, dataWord);
0131   dt_crc::calcCRC(dataWord, newCRC);
0132 
0133   int nslots = (dataWord >> posNslost) & 0xF;
0134 
0135   fwords.setheader2(dataWord);
0136   fwords.setnslots(nslots);
0137 
0138   //--> AMC - line 3 to 2+nslots
0139   std::map<int, int> slot_size;
0140   for (int j = 0; j < nslots; ++j) {
0141     readline(lines, dataWord);
0142     dt_crc::calcCRC(dataWord, newCRC);
0143 
0144     int slot = (dataWord >> posSlotFED) & 0xF;
0145 
0146     if ((slot < 1) || (slot > 12)) {
0147       if (debug_)
0148         edm::LogWarning("dturos_unpacker") << "AMCnumber " << std::dec << slot << " out of range (1-12)";
0149       return;
0150     }
0151 
0152     slot_size[slot] = (dataWord >> 32) & 0xFFFFFF;  // positions 32 -> 55
0153 
0154     fwords.setslotsize(slot, slot_size[slot]);
0155   }
0156 
0157   //--> DTuROS data
0158 
0159   std::map<int, int>::iterator sziterator = slot_size.begin();
0160   std::map<int, int>::iterator szitend = slot_size.end();
0161   for (; sziterator != szitend; ++sziterator) {
0162     for (int k = 0; k < sziterator->second; ++k) {
0163       readline(lines, dataWord);
0164       dt_crc::calcCRC(dataWord, newCRC);
0165 
0166       DTuROSWordContainer.push_back(dataWord);
0167     }
0168   }
0169 
0170   //--> Trailer - line 1
0171 
0172   readline(lines, dataWord);
0173   dt_crc::calcCRC(dataWord, newCRC);
0174 
0175   //--> Trailer - line 2
0176 
0177   readline(lines, dataWord);
0178 
0179   const int posEOE = 60;        // positions 60 -> 63
0180   const int posEvtLenght = 32;  // positions 33 ->55
0181   const int posCRC = 16;        // positions 16 ->31
0182   chkEOE = (dataWord >> posEOE) & 0xF;
0183 
0184   if (chkEOE != 0xA) {
0185     if (debug_)
0186       edm::LogWarning("dturos_unpacker") << "Trailer " << std::hex << dataWord << " does not start with 0xA";
0187     return;
0188   }
0189 
0190   evtLgth = (dataWord >> posEvtLenght) & 0xFFFFFF;
0191   CRC = (dataWord >> posCRC) & 0xFFFF;
0192 
0193   dt_crc::calcCRC(dataWord & 0xFFFFFFFF0000FFFF, newCRC);
0194 
0195   if (newCRC != CRC) {
0196     if (debug_)
0197       edm::LogWarning("dturos_unpacker") << "Calculated CRC " << std::hex << newCRC << " differs from CRC in trailer "
0198                                          << std::hex << CRC;
0199     return;
0200   }
0201 
0202   if (lines != evtLgth) {
0203     if (debug_)
0204       edm::LogWarning("dturos_unpacker") << "Number of words read != event length " << std::dec << lines << " "
0205                                          << evtLgth;
0206     return;
0207   }
0208 
0209   fwords.settrailer(dataWord);
0210   fwords.setevtlgth(evtLgth);
0211 
0212   //--> analyze event
0213 
0214   std::vector<long>::iterator DTuROSiterator = DTuROSWordContainer.begin();
0215   std::vector<long>::iterator DTuROSitend = DTuROSWordContainer.end();
0216 
0217   const int posSlot = 56;  // positions 56 -> 59
0218 
0219   for (; DTuROSiterator != DTuROSitend; ++DTuROSiterator) {
0220     DTuROSROSData rwords;
0221 
0222     dataWord = (*DTuROSiterator);  // Header AMC 1
0223 
0224     int slot = (dataWord >> posSlot) & 0xF;
0225 
0226     if ((slot < 1) || (slot > 12)) {
0227       if (debug_)
0228         edm::LogWarning("dturos_unpacker") << "Slot " << std::dec << slot << " out of range (1-12) in crate " << crate;
0229       break;
0230     }
0231 
0232     rwords.setslot(slot);
0233     rwords.setheader1(dataWord);
0234 
0235     ++DTuROSiterator;
0236     dataWord = (*DTuROSiterator);  // Header AMC 2
0237 
0238     rwords.setheader2(dataWord);
0239     int slotMap = dataWord & 0xF;
0240     if (slotMap == 0)
0241       slotMap = slot;
0242     const int posSel1 = 60;                // positions 60 -> 6
0243     const int posSel2 = 28;                // position  28
0244     const int posTDCTime = 32;             // positions  32 -> 45
0245     const int posTDCChannel = 46;          // positions  46 -> 50
0246     const int posTDCId = 51;               // positions  51 -> 52
0247     const int posLink = 53;                // positions  53 -> 59
0248     const int posTDCChannelSel2Null = 14;  // positions  14 -> 18
0249     const int posTDCIdSel2Null = 19;       // positions  19 -> 20
0250     const int posLinkSel2Null = 21;        // positions  21 -> 27
0251     const int posErrorSel3 = 32;           // positions  32 -> 60
0252 
0253     for (int k = 2; k < slot_size[slot] - 1; ++k) {
0254       ++DTuROSiterator;
0255       dataWord = (*DTuROSiterator);
0256       int selector = (dataWord >> posSel1) & 0xF;
0257       int selector2 = (dataWord >> posSel2) & 0x1;
0258 
0259       if (selector == 4) {  // OK word
0260 
0261         if (rwords.getokword1()) {
0262           rwords.setokword2(dataWord);
0263         } else {
0264           rwords.setokword1(dataWord);
0265         }
0266 
0267       } else if (selector >= 8 && selector <= 13) {  // OK xword
0268 
0269         rwords.setokxword(selector - 8, dataWord);
0270 
0271       } else if (selector == 15) {  // extra word
0272 
0273         rwords.setexword(dataWord);
0274 
0275       } else {
0276         if (selector == 2) {  // TDC word
0277 
0278           int tdcTime = (dataWord >> posTDCTime) & 0x3FFF;
0279           int tdcChannel = (dataWord >> posTDCChannel) & 0x1F;
0280           int tdcId = (dataWord >> posTDCId) & 0x3;
0281           int link = (dataWord >> posLink) & 0x7F;
0282 
0283           int dummy = 0;
0284 
0285           bool tenDDU = !mapping->readOutToGeometry(779, 7, 1, 1, 1, dummy, dummy, dummy, dummy, dummy, dummy);
0286 
0287           int dduId = theDDU(crate, slotMap, link, tenDDU);
0288           int rosId = theROS(slotMap, link);
0289           int robId = theROB(slotMap, link);
0290 
0291           DTROChainCoding channelIndex(dduId, rosId, robId, tdcId, tdcChannel);
0292           if (hitOrder.find(channelIndex.getCode()) == hitOrder.end())
0293             hitOrder[channelIndex.getCode()] = 0;
0294           else
0295             hitOrder[channelIndex.getCode()]++;
0296 
0297           int wheelId, stationId, sectorId, slId, layerId, cellId;
0298           if (!mapping->readOutToGeometry(
0299                   dduId, rosId, robId, tdcId, tdcChannel, wheelId, stationId, sectorId, slId, layerId, cellId)) {
0300             DTWireId detId = DTWireId(wheelId, stationId, sectorId, slId, layerId, cellId);
0301             int wire = detId.wire();
0302 
0303             DTDigi digi(wire, tdcTime, hitOrder[channelIndex.getCode()]);
0304             digis.insertDigi(detId.layerId(), digi);
0305           }
0306 
0307         } else if (selector == 3) {  // error word
0308 
0309           if (debug_)
0310             edm::LogWarning("dturos_unpacker") << "Error word [" << std::dec << k << "] : " << std::hex << dataWord
0311                                                << std::dec << " in slot " << slot << " in crate " << crate;
0312 
0313           int error = (dataWord >> posErrorSel3) & 0x1FFFFFFF;
0314           rwords.seterror(error);
0315         }
0316 
0317         if ((dataWord & 0x1FFFFFFF) == 0x1FFFFFFF)
0318           continue;
0319 
0320         if (selector2 == 0) {  // TDC word
0321 
0322           int tdcTime = (dataWord) & 0x3FFF;  // positions   0 -> 13
0323           int tdcChannel = (dataWord >> posTDCChannelSel2Null) & 0x1F;
0324           int tdcId = (dataWord >> posTDCIdSel2Null) & 0x3;
0325           int link = (dataWord >> posLinkSel2Null) & 0x7F;  // positions  21 -> 27
0326 
0327           if (tdcTime == 16383)
0328             continue;
0329 
0330           int dummy = 0;
0331 
0332           bool tenDDU = !mapping->readOutToGeometry(779, 7, 1, 1, 1, dummy, dummy, dummy, dummy, dummy, dummy);
0333 
0334           int dduId = theDDU(crate, slotMap, link, tenDDU);
0335           int rosId = theROS(slotMap, link);
0336           int robId = theROB(slotMap, link);
0337 
0338           DTROChainCoding channelIndex(dduId, rosId, robId, tdcId, tdcChannel);
0339           if (hitOrder.find(channelIndex.getCode()) == hitOrder.end())
0340             hitOrder[channelIndex.getCode()] = 0;
0341           else
0342             hitOrder[channelIndex.getCode()]++;
0343 
0344           int wheelId, stationId, sectorId, slId, layerId, cellId;
0345           if (!mapping->readOutToGeometry(
0346                   dduId, rosId, robId, tdcId, tdcChannel, wheelId, stationId, sectorId, slId, layerId, cellId)) {
0347             DTWireId detId = DTWireId(wheelId, stationId, sectorId, slId, layerId, cellId);
0348             int wire = detId.wire();
0349 
0350             DTDigi digi(wire, tdcTime, hitOrder[channelIndex.getCode()]);
0351             digis.insertDigi(detId.layerId(), digi);
0352           }
0353 
0354         } else if (selector2 == 1) {  // error word
0355 
0356           if (debug_)
0357             edm::LogWarning("dturos_unpacker") << "Error word [" << std::dec << k << "] : " << std::hex << dataWord
0358                                                << std::dec << " in slot " << slot << " in crate " << crate;
0359 
0360           int error = (dataWord) & 0x1FFFFFFF;  // positions   0 -> 28
0361           rwords.seterror(error);
0362         }
0363       }
0364     }
0365 
0366     ++DTuROSiterator;
0367     dataWord = (*DTuROSiterator);  // Trailer AMC
0368 
0369     rwords.settrailer(dataWord);
0370     fwords.setuROS(slot, rwords);
0371 
0372   }  // end for-loop container content
0373 
0374   return;
0375 }
0376 
0377 int DTuROSRawToDigi::theDDU(int crate, int slot, int link, bool tenDDU) {
0378   int ros = theROS(slot, link);
0379 
0380   int ddu = 772;
0381 
0382   //if (crate == 1368) { ddu = 775; }
0383   ////Needed just in case this FED should be used due to fibers lenght
0384 
0385   if (crate == FEDNumbering::MINDTUROSFEDID) {
0386     if (slot < 7)
0387       ddu = 770;
0388     else
0389       ddu = 771;
0390   }
0391 
0392   if (crate == (FEDNumbering::MINDTUROSFEDID + 1)) {
0393     ddu = 772;
0394   }
0395 
0396   if (crate == FEDNumbering::MAXDTUROSFEDID) {
0397     if (slot < 7)
0398       ddu = 773;
0399     else
0400       ddu = 774;
0401   }
0402 
0403   if (ros > 6 && tenDDU && ddu < 775)
0404     ddu += 5;
0405 
0406   return ddu;
0407 }
0408 
0409 int DTuROSRawToDigi::theROS(int slot, int link) {
0410   if (slot % 6 == 5)
0411     return link + 1;
0412 
0413   int ros = (link / 24) + 3 * (slot % 6) - 2;
0414   return ros;
0415 }
0416 
0417 int DTuROSRawToDigi::theROB(int slot, int link) {
0418   if (slot % 6 == 5)
0419     return 23;
0420 
0421   int rob = link % 24;
0422   if (rob < 15)
0423     return rob;
0424   if (rob == 15)
0425     return 24;
0426   return rob - 1;
0427 }
0428 
0429 #include "FWCore/Framework/interface/MakerMacros.h"
0430 DEFINE_FWK_MODULE(DTuROSRawToDigi);