Back to home page

Project CMSSW displayed by LXR

 
 

    


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

0001 #include "EventFilter/CastorRawToDigi/interface/CastorUnpacker.h"
0002 #include "EventFilter/HcalRawToDigi/interface/HcalDCCHeader.h"
0003 #include "EventFilter/HcalRawToDigi/interface/HcalHTRData.h"
0004 #include "EventFilter/HcalRawToDigi/interface/HcalTTPUnpacker.h"
0005 #include "DataFormats/HcalDetId/interface/HcalOtherDetId.h"
0006 #include "DataFormats/HcalDigi/interface/HcalQIESample.h"
0007 #include "DataFormats/HcalDigi/interface/CastorDataFrame.h"
0008 #include "DataFormats/HcalDigi/interface/HcalTriggerPrimitiveSample.h"
0009 #include <iostream>
0010 #include "FWCore/MessageLogger/interface/MessageLogger.h"
0011 
0012 namespace CastorUnpacker_impl {
0013   template <class DigiClass>
0014   const HcalQIESample* unpack(const HcalQIESample* startPoint,
0015                               const HcalQIESample* limit,
0016                               DigiClass& digi,
0017                               int presamples,
0018                               const CastorElectronicsId& eid,
0019                               int startSample,
0020                               int endSample,
0021                               int expectedTime,
0022                               const HcalHTRData& hhd) {
0023     // set parameters
0024     digi.setPresamples(presamples);
0025     int fiber = startPoint->fiber();
0026     int fiberchan = startPoint->fiberChan();
0027     uint32_t zsmask = hhd.zsBunchMask() >> startSample;
0028     digi.setZSInfo(hhd.isUnsuppressed(), hhd.wasMarkAndPassZS(fiber, fiberchan), zsmask);
0029 
0030     //   digi.setReadoutIds(eid);
0031     //   setReadoutIds is missing in  CastorDataFrame class  digi.setReadoutIds(eid);
0032     if (expectedTime >= 0 && !hhd.isUnsuppressed()) {
0033       // std::cout << hhd.getFibOrbMsgBCN(fiber) << " " << expectedTime << " fiber="<<fiber<< std::endl;
0034       digi.setFiberIdleOffset(hhd.getFibOrbMsgBCN(fiber) - expectedTime);
0035     }
0036     // what is my sample number?
0037     int myFiberChan = startPoint->fiberAndChan();
0038     int ncurr = 0, ntaken = 0;
0039     const HcalQIESample* qie_work = startPoint;
0040     while (qie_work != limit && qie_work->fiberAndChan() == myFiberChan) {
0041       if (ncurr >= startSample && ncurr <= endSample) {
0042         digi.setSample(ntaken, *qie_work);
0043         ++ntaken;
0044       }
0045       ncurr++;
0046       qie_work++;
0047     }
0048     digi.setSize(ntaken);
0049     return qie_work;
0050   }
0051 }  // namespace CastorUnpacker_impl
0052 
0053 namespace {
0054   inline bool isTPGSOI(const HcalTriggerPrimitiveSample& s) { return (s.raw() & 0x200) != 0; }
0055 }  // namespace
0056 
0057 CastorUnpacker::CastorUnpacker(int sourceIdOffset, int beg, int end)
0058     : sourceIdOffset_(sourceIdOffset), expectedOrbitMessageTime_(-1) {
0059   if (beg >= 0 && beg <= CastorDataFrame::MAXSAMPLES - 1) {
0060     startSample_ = beg;
0061   } else {
0062     startSample_ = 0;
0063   }
0064   if (end >= 0 && end <= CastorDataFrame::MAXSAMPLES - 1 && end >= beg) {
0065     endSample_ = end;
0066   } else {
0067     endSample_ = CastorDataFrame::MAXSAMPLES - 1;
0068   }
0069 }
0070 
0071 static int slb(const HcalTriggerPrimitiveSample& theSample) { return ((theSample.raw() >> 13) & 0x7); }
0072 static int slbChan(const HcalTriggerPrimitiveSample& theSample) { return (theSample.raw() >> 11) & 0x3; }
0073 static int slbAndChan(const HcalTriggerPrimitiveSample& theSample) { return (theSample.raw() >> 11) & 0x1F; }
0074 
0075 void CastorUnpacker::unpack(const FEDRawData& raw,
0076                             const CastorElectronicsMap& emap,
0077                             CastorRawCollections& colls,
0078                             HcalUnpackerReport& report,
0079                             bool silent) {
0080   if (raw.size() < 16) {
0081     if (!silent)
0082       edm::LogWarning("Invalid Data") << "Empty/invalid DCC data, size = " << raw.size();
0083     return;
0084   }
0085 
0086   // get the DCC header
0087   const HcalDCCHeader* dccHeader = (const HcalDCCHeader*)(raw.data());
0088   int dccid = dccHeader->getSourceId() - sourceIdOffset_;
0089 
0090   // check the summary status
0091 
0092   // walk through the HTR data...
0093   HcalHTRData htr;
0094   const unsigned short *daq_first, *daq_last, *tp_first, *tp_last;
0095   const HcalQIESample *qie_begin, *qie_end, *qie_work;
0096   const HcalTriggerPrimitiveSample *tp_begin, *tp_end, *tp_work;
0097   for (int spigot = 0; spigot < HcalDCCHeader::SPIGOT_COUNT; spigot++) {
0098     if (!dccHeader->getSpigotPresent(spigot))
0099       continue;
0100 
0101     int retval = dccHeader->getSpigotData(spigot, htr, raw.size());
0102     if (retval != 0) {
0103       if (retval == -1) {
0104         if (!silent)
0105           edm::LogWarning("Invalid Data") << "Invalid HTR data (data beyond payload size) observed on spigot " << spigot
0106                                           << " of DCC with source id " << dccHeader->getSourceId();
0107         report.countSpigotFormatError();
0108       }
0109       continue;
0110     }
0111     // check
0112     if (dccHeader->getSpigotCRCError(spigot)) {
0113       if (!silent)
0114         edm::LogWarning("Invalid Data") << "CRC Error on HTR data observed on spigot " << spigot
0115                                         << " of DCC with source id " << dccHeader->getSourceId();
0116       report.countSpigotFormatError();
0117       continue;
0118     }
0119     if (!htr.check()) {
0120       if (!silent)
0121         edm::LogWarning("Invalid Data") << "Invalid HTR data observed on spigot " << spigot << " of DCC with source id "
0122                                         << dccHeader->getSourceId();
0123       report.countSpigotFormatError();
0124       continue;
0125     }
0126     if (htr.isHistogramEvent()) {
0127       if (!silent)
0128         edm::LogWarning("Invalid Data") << "Histogram data passed to non-histogram unpacker on spigot " << spigot
0129                                         << " of DCC with source id " << dccHeader->getSourceId();
0130       continue;
0131     }
0132     if ((htr.getFirmwareFlavor() & 0xE0) == 0x80) {  // some kind of TTP data
0133       if (colls.ttp != nullptr) {
0134         HcalTTPUnpacker ttpUnpack;
0135         colls.ttp->push_back(HcalTTPDigi());
0136         ttpUnpack.unpack(htr, colls.ttp->back());
0137       } else {
0138         LogDebug("CastorUnpackerHcalTechTrigProcessor")
0139             << "Skipping data on spigot " << spigot << " of DCC with source id " << dccHeader->getSourceId()
0140             << " which is from the TechTrigProcessor (use separate unpacker!)";
0141       }
0142       continue;
0143     }
0144     if (htr.getFirmwareFlavor() >= 0x80) {
0145       if (!silent)
0146         edm::LogWarning("CastorUnpacker")
0147             << "Skipping data on spigot " << spigot << " of DCC with source id " << dccHeader->getSourceId()
0148             << " which is of unknown flavor " << htr.getFirmwareFlavor();
0149       continue;
0150     }
0151     // calculate "real" number of presamples
0152     int nps = htr.getNPS() - startSample_;
0153 
0154     // get pointers
0155     htr.dataPointers(&daq_first, &daq_last, &tp_first, &tp_last);
0156     unsigned int smid = htr.getSubmodule();
0157     int htr_tb = smid & 0x1;
0158     int htr_slot = (smid >> 1) & 0x1F;
0159     int htr_cr = (smid >> 6) & 0x1F;
0160 
0161     tp_begin = (const HcalTriggerPrimitiveSample*)tp_first;
0162     tp_end = (const HcalTriggerPrimitiveSample*)(tp_last + 1);  // one beyond last..
0163 
0164     /// work through the samples
0165     int currFiberChan = 0x3F;  // invalid fiber+channel...
0166     int ncurr = 0;
0167     bool valid = false;
0168     //////////////////////////////////////////////
0169     bool tpgSOIbitInUse = htr.getFormatVersion() >= 3;  // version 3 and later
0170     // bool isHOtpg=htr.getFormatVersion()>=3 && htr.getFirmwareFlavor()==0; // HO is flavor zero
0171     /*
0172       Unpack the trigger primitives
0173     */
0174     // lookup the right channel
0175     bool dotp = true;
0176     CastorElectronicsId eid(0, 1, spigot, dccid);
0177     eid.setHTR(htr_cr, htr_slot, htr_tb);
0178     DetId did = emap.lookup(eid);
0179     if (did.null())
0180       dotp = false;
0181     HcalCastorDetId id1(did);
0182     HcalCastorDetId id((id1.zside() == 0), id1.sector(), 1);
0183     if (id1.module() > 12)
0184       dotp = false;
0185     if (dotp) {
0186       // std::cout << " tp_first="<< tp_first << " tp_last="<< tp_last<< " tb="<<htr_tb<<" slot="<<htr_slot<<" crate="<<htr_cr<<" dccid="<< dccid<< std::endl;
0187       // regular TPs (not HO)
0188       for (tp_work = tp_begin; tp_work != tp_end; tp_work++) {
0189         //    std::cout << "raw=0x"<<std::hex<< tp_work->raw()<<std::dec <<std::endl;
0190         if (tp_work->raw() == 0xFFFF)
0191           continue;                                   // filler word
0192         if (slbAndChan(*tp_work) != currFiberChan) {  // start new set
0193           currFiberChan = slbAndChan(*tp_work);
0194 
0195           // std::cout<< " NEW SET "<<std::endl;
0196           //HcalElectronicsId eid(tp_work->slbChan(),tp_work->slb(),spigot,dccid,htr_cr,htr_slot,htr_tb);
0197           //DetId did=emap.lookupTrigger(eid);
0198           //if (did.null()) {
0199           //report.countUnmappedTPDigi(eid);
0200           //if (unknownIdsTrig_.find(eid)==unknownIdsTrig_.end()) {
0201           //if (!silent) edm::LogWarning("HCAL") << "HcalUnpacker: No trigger primitive match found for electronics id :" << eid;
0202           //unknownIdsTrig_.insert(eid);
0203           //}
0204           //valid=false;
0205           //continue;
0206           //} else if (did==HcalTrigTowerDetId::Undefined ||
0207           //(did.det()==DetId::Hcal && did.subdetId()==0)) {
0208           //// known to be unmapped
0209           //valid=false;
0210           //continue;
0211           //}
0212 
0213           colls.tpCont->push_back(CastorTriggerPrimitiveDigi(id));
0214           // set the various bits
0215           if (!tpgSOIbitInUse)
0216             colls.tpCont->back().setPresamples(nps);
0217           colls.tpCont->back().setZSInfo(htr.isUnsuppressed(),
0218                                          htr.wasMarkAndPassZSTP(slb(*tp_work), slbChan(*tp_work)));
0219 
0220           // no hits recorded for current
0221           ncurr = 0;
0222           valid = true;
0223         }
0224         // add the word (if within settings or recent firmware [recent firmware ignores startSample/endSample])
0225         if (valid && ((tpgSOIbitInUse && ncurr < 10) || (ncurr >= startSample_ && ncurr <= endSample_))) {
0226           colls.tpCont->back().setSample(colls.tpCont->back().size(), *tp_work);
0227           colls.tpCont->back().setSize(colls.tpCont->back().size() + 1);
0228         }
0229         // set presamples,if SOI
0230         if (valid && tpgSOIbitInUse && isTPGSOI(*tp_work)) {
0231           colls.tpCont->back().setPresamples(ncurr);
0232         }
0233         ncurr++;
0234       }
0235     }
0236 
0237     //////////////////////////////////////////////
0238     qie_begin = (const HcalQIESample*)daq_first;
0239     qie_end = (const HcalQIESample*)(daq_last + 1);  // one beyond last..
0240 
0241     /// work through the samples
0242 
0243     for (qie_work = qie_begin; qie_work != qie_end;) {
0244       if (qie_work->raw() == 0xFFFF) {
0245         qie_work++;
0246         continue;  // filler word
0247       }
0248 
0249       // lookup the right channel
0250       CastorElectronicsId eid(qie_work->fiberChan(), qie_work->fiber(), spigot, dccid);
0251       eid.setHTR(htr_cr, htr_slot, htr_tb);
0252       DetId did = emap.lookup(eid);
0253 
0254       if (!did.null()) {
0255         colls.castorCont->push_back(CastorDataFrame(HcalCastorDetId(did)));
0256         qie_work = CastorUnpacker_impl::unpack<CastorDataFrame>(qie_work,
0257                                                                 qie_end,
0258                                                                 colls.castorCont->back(),
0259                                                                 nps,
0260                                                                 eid,
0261                                                                 startSample_,
0262                                                                 endSample_,
0263                                                                 expectedOrbitMessageTime_,
0264                                                                 htr);
0265       } else {
0266         report.countUnmappedDigi();
0267         if (unknownIds_.find(eid) == unknownIds_.end()) {
0268           if (!silent)
0269             edm::LogWarning("CASTOR") << "CastorUnpacker: No match found for electronics id :" << eid;
0270           unknownIds_.insert(eid);
0271         }
0272         for (int fiberC = qie_work->fiberAndChan(); qie_work != qie_end && qie_work->fiberAndChan() == fiberC;
0273              qie_work++)
0274           ;
0275       }
0276     }
0277   }
0278 }