Back to home page

Project CMSSW displayed by LXR

 
 

    


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