Back to home page

Project CMSSW displayed by LXR

 
 

    


File indexing completed on 2021-02-14 13:15:06

0001 #include "EventFilter/HcalRawToDigi/interface/HcalUnpacker.h"
0002 #include "EventFilter/HcalRawToDigi/interface/HcalDCCHeader.h"
0003 #include "EventFilter/HcalRawToDigi/interface/HcalDTCHeader.h"
0004 #include "EventFilter/HcalRawToDigi/interface/AMC13Header.h"
0005 #include "EventFilter/HcalRawToDigi/interface/HcalHTRData.h"
0006 #include "EventFilter/HcalRawToDigi/interface/HcalUHTRData.h"
0007 #include "DataFormats/HcalDetId/interface/HcalOtherDetId.h"
0008 #include "DataFormats/HcalDigi/interface/HcalQIESample.h"
0009 #include "FWCore/MessageLogger/interface/MessageLogger.h"
0010 #include "EventFilter/HcalRawToDigi/interface/HcalTTPUnpacker.h"
0011 
0012 //#define DebugLog
0013 
0014 namespace HcalUnpacker_impl {
0015   template <class DigiClass>
0016   const HcalQIESample* unpack(const HcalQIESample* startPoint,
0017                               const HcalQIESample* limit,
0018                               DigiClass& digi,
0019                               int presamples,
0020                               const HcalElectronicsId& eid,
0021                               int startSample,
0022                               int endSample,
0023                               int expectedTime,
0024                               const HcalHTRData& hhd) {
0025     // set parameters
0026     digi.setPresamples(presamples);
0027     digi.setReadoutIds(eid);
0028 
0029     int fiber = startPoint->fiber();
0030     int fiberchan = startPoint->fiberChan();
0031     uint32_t zsmask = hhd.zsBunchMask() >> startSample;
0032     digi.setZSInfo(hhd.isUnsuppressed(), hhd.wasMarkAndPassZS(fiber, fiberchan), zsmask);
0033 
0034     if (expectedTime >= 0 && !hhd.isUnsuppressed()) {
0035 #ifdef DebugLog
0036       std::cout << hhd.getFibOrbMsgBCN(fiber) << " " << expectedTime << std::endl;
0037 #endif
0038       digi.setFiberIdleOffset(hhd.getFibOrbMsgBCN(fiber) - expectedTime);
0039     }
0040 
0041     // what is my sample number?
0042     int myFiberChan = startPoint->fiberAndChan();
0043     int ncurr = 0, ntaken = 0;
0044     const HcalQIESample* qie_work = startPoint;
0045     while (qie_work != limit && qie_work->fiberAndChan() == myFiberChan) {
0046       if (ncurr >= startSample && ncurr <= endSample) {
0047         digi.setSample(ntaken, *qie_work);
0048         ++ntaken;
0049       }
0050       ncurr++;
0051       qie_work++;
0052     }
0053     digi.setSize(ntaken);
0054     return qie_work;
0055   }
0056 
0057   template <class DigiClass>
0058   const unsigned short* unpack_compact(const unsigned short* startPoint,
0059                                        const unsigned short* limit,
0060                                        DigiClass& digi,
0061                                        int presamples,
0062                                        const HcalElectronicsId& eid,
0063                                        int startSample,
0064                                        int endSample,
0065                                        int expectedTime,
0066                                        const HcalHTRData& hhd) {
0067     // set parameters
0068     digi.setPresamples(presamples);
0069     digi.setReadoutIds(eid);
0070     int flavor, error_flags, capid0, channelid;
0071 
0072     HcalHTRData::unpack_per_channel_header(*startPoint, flavor, error_flags, capid0, channelid);
0073     bool isCapRotating = !(error_flags & 0x1);
0074     bool fiberErr = (error_flags & 0x2);
0075     bool dataValid = !(error_flags & 0x2);
0076     int fiberchan = channelid & 0x3;
0077     int fiber = ((channelid >> 2) & 0x7) + 1;
0078 
0079     uint32_t zsmask = hhd.zsBunchMask() >> startSample;
0080     digi.setZSInfo(hhd.isUnsuppressed(), hhd.wasMarkAndPassZS(fiber, fiberchan), zsmask);
0081 
0082     if (expectedTime >= 0 && !hhd.isUnsuppressed()) {
0083 #ifdef DebugLog
0084       std::cout << hhd.getFibOrbMsgBCN(fiber) << " " << expectedTime << std::endl;
0085 #endif
0086       digi.setFiberIdleOffset(hhd.getFibOrbMsgBCN(fiber) - expectedTime);
0087     }
0088 
0089     // what is my sample number?
0090     int ncurr = 0, ntaken = 0;
0091     const unsigned short* qie_work = startPoint;
0092     // we branch here between normal (flavor=5) and error mode (flavor=6)
0093     if (flavor == 5) {
0094       for (qie_work++; qie_work != limit && !HcalHTRData::is_channel_header(*qie_work); qie_work++) {
0095         int capidn = (isCapRotating) ? ((capid0 + ncurr) % 4) : (capid0);
0096         int capidn1 = (isCapRotating) ? ((capid0 + ncurr + 1) % 4) : (capid0);
0097         // two samples in one...
0098         HcalQIESample s0((*qie_work) & 0x7F, capidn, fiber, fiberchan, dataValid, fiberErr);
0099         HcalQIESample s1(((*qie_work) >> 8) & 0x7F, capidn1, fiber, fiberchan, dataValid, fiberErr);
0100 
0101         if (ncurr >= startSample && ncurr <= endSample) {
0102           digi.setSample(ntaken, s0);
0103           ++ntaken;
0104         }
0105         ncurr++;
0106         if (ncurr >= startSample && ncurr <= endSample) {
0107           digi.setSample(ntaken, s1);
0108           ++ntaken;
0109         }
0110         ncurr++;
0111       }
0112       digi.setSize(ntaken);
0113     } else if (flavor == 6) {
0114       for (qie_work++; qie_work != limit && !HcalHTRData::is_channel_header(*qie_work); qie_work++) {
0115         if (ncurr >= startSample && ncurr <= endSample) {
0116           HcalQIESample sample((*qie_work) & 0x7F,
0117                                ((*qie_work) >> 8) & 0x3,
0118                                fiber,
0119                                fiberchan,
0120                                ((*qie_work) >> 10) & 0x1,
0121                                ((*qie_work) >> 11) & 0x1);
0122           digi.setSample(ntaken, sample);
0123           ++ntaken;
0124         }
0125 
0126         ncurr++;
0127       }
0128       digi.setSize(ntaken);
0129     } else {
0130       edm::LogWarning("Bad Data") << "Invalid flavor " << flavor;
0131       qie_work = limit;
0132     }
0133     return qie_work;
0134   }
0135 
0136   template <class DigiClass>
0137   void unpack_compact(HcalUHTRData::const_iterator& i,
0138                       const HcalUHTRData::const_iterator& iend,
0139                       DigiClass& digi,
0140                       int presamples,
0141                       const HcalElectronicsId& eid,
0142                       int startSample,
0143                       int endSample) {
0144     // set parameters
0145     digi.setPresamples(presamples - startSample);
0146     digi.setReadoutIds(eid);
0147     int error_flags = i.errFlags();
0148     int capid0 = i.capid0();
0149     int flavor = i.flavor();
0150 
0151     bool isCapRotating = !(error_flags & 0x1);
0152     bool fiberErr = (error_flags & 0x2);
0153     bool dataValid = !(error_flags & 0x2);
0154     int fiberchan = i.channelid() & 0x3;
0155     int fiber = ((i.channelid() >> 2) & 0x7) + 1;
0156 
0157     //    digi.setZSInfo(hhd.isUnsuppressed(),hhd.wasMarkAndPassZS(fiber,fiberchan),zsmask);
0158 
0159     // what is my sample number?
0160     int ncurr = 0, ntaken = 0;
0161     if (flavor == 5) {
0162       for (++i; i != iend && !i.isHeader(); ++i) {
0163         int capidn = (isCapRotating) ? ((capid0 + ncurr) % 4) : (capid0);
0164 
0165         HcalQIESample s(i.adc(), capidn, fiber, fiberchan, dataValid, fiberErr);
0166 
0167         if (ncurr >= startSample && ncurr <= endSample) {
0168           digi.setSample(ntaken, s);
0169           ++ntaken;
0170         }
0171         ncurr++;
0172       }
0173       digi.setSize(ntaken);
0174     } else if (flavor == 7) {  //similar to VME flavor 6, used for premix in MC
0175       for (++i; i != iend && !i.isHeader(); ++i) {
0176         if (ncurr >= startSample && ncurr <= endSample) {
0177           HcalQIESample sample(i.adc(), i.capid(), fiber, fiberchan, i.dataValid(), i.errFlags());
0178           digi.setSample(ntaken, sample);
0179           ++ntaken;
0180         }
0181         ncurr++;
0182       }
0183       digi.setSize(ntaken);
0184     }
0185   }
0186 
0187 }  // namespace HcalUnpacker_impl
0188 
0189 static inline bool isTPGSOI(const HcalTriggerPrimitiveSample& s) { return (s.raw() & 0x200) != 0; }
0190 
0191 struct HOUnrolledTP {  // parts of an HO trigger primitive, unpacked
0192   bool valid, checked;
0193   int ieta, iphi, samples, soi;
0194   unsigned int databits;
0195   HOUnrolledTP() {
0196     valid = false;
0197     checked = false;
0198     ieta = 0;
0199     iphi = 0;
0200     samples = 0;
0201     soi = 0;
0202     databits = 0;
0203   }
0204   void setbit(int i) { databits |= (1 << i); }
0205 };
0206 
0207 void HcalUnpacker::unpack(const FEDRawData& raw,
0208                           const HcalElectronicsMap& emap,
0209                           Collections& colls,
0210                           HcalUnpackerReport& report,
0211                           bool silent) {
0212   if (raw.size() < 16) {
0213     if (!silent)
0214       edm::LogWarning("Invalid Data") << "Empty/invalid data, size = " << raw.size();
0215     return;
0216   }
0217 
0218   // get the DCC header
0219   const HcalDCCHeader* dccHeader = (const HcalDCCHeader*)(raw.data());
0220 
0221   if (dccHeader->BOEshouldBeZeroAlways() == 0)  // also includes uTCA before the common AMC13XG firmware
0222     unpackVME(raw, emap, colls, report, silent);
0223   else
0224     unpackUTCA(raw, emap, colls, report, silent);
0225 }
0226 
0227 static int slb(uint16_t theSample) { return ((theSample >> 13) & 0x7); }
0228 static int slbChan(uint16_t theSample) { return (theSample >> 11) & 0x3; }
0229 static int slbAndChan(uint16_t theSample) { return (theSample >> 11) & 0x1F; }
0230 
0231 void HcalUnpacker::unpackVME(const FEDRawData& raw,
0232                              const HcalElectronicsMap& emap,
0233                              Collections& colls,
0234                              HcalUnpackerReport& report,
0235                              bool silent) {
0236   // get the DCC header
0237   const HcalDCCHeader* dccHeader = (const HcalDCCHeader*)(raw.data());
0238   const HcalDTCHeader* dtcHeader = (const HcalDTCHeader*)(raw.data());
0239   bool is_VME_DCC = (dccHeader->getDCCDataFormatVersion() < 0x10) || ((mode_ & 0x1) == 0);
0240 
0241   int dccid =
0242       (is_VME_DCC) ? (dccHeader->getSourceId() - sourceIdOffset_) : (dtcHeader->getSourceId() - sourceIdOffset_);
0243 
0244   // check the summary status
0245 
0246   // walk through the HTR data.  For the uTCA, use spigot=slot+1
0247   HcalHTRData htr;
0248   const unsigned short *daq_first, *daq_last, *tp_first, *tp_last;
0249   const HcalQIESample *qie_begin, *qie_end, *qie_work;
0250   const HcalTriggerPrimitiveSample *tp_begin, *tp_end, *tp_work;
0251   for (int spigot = 0; spigot < HcalDCCHeader::SPIGOT_COUNT; spigot++) {
0252     if (is_VME_DCC) {
0253       if (!dccHeader->getSpigotPresent(spigot))
0254         continue;
0255 
0256       int retval = dccHeader->getSpigotData(spigot, htr, raw.size());
0257       if (retval != 0) {
0258         if (retval == -1) {
0259           if (!silent)
0260             edm::LogWarning("Invalid Data") << "Invalid HTR data (data beyond payload size) observed on spigot "
0261                                             << spigot << " of DCC with source id " << dccHeader->getSourceId();
0262           report.countSpigotFormatError();
0263         }
0264         continue;
0265       }
0266       // check
0267       if (dccHeader->getSpigotCRCError(spigot)) {
0268         if (!silent)
0269           edm::LogWarning("Invalid Data") << "CRC Error on HTR data observed on spigot " << spigot
0270                                           << " of DCC with source id " << dccHeader->getSourceId();
0271         report.countSpigotFormatError();
0272         continue;
0273       }
0274     } else {  // is_uTCA (!is_VME_DCC)
0275       int slot = spigot + 1;
0276       if (slot > HcalDTCHeader::MAXIMUM_SLOT)
0277         continue;
0278 
0279       if (!dtcHeader->getSlotPresent(slot))
0280         continue;
0281 
0282       int retval = dtcHeader->getSlotData(slot, htr, raw.size());
0283       if (retval != 0) {
0284         if (retval == -1) {
0285           if (!silent)
0286             edm::LogWarning("Invalid Data") << "Invalid uHTR data (data beyond payload size) observed on slot " << slot
0287                                             << " of DTC with source id " << dtcHeader->getSourceId();
0288           report.countSpigotFormatError();
0289         }
0290         continue;
0291       }
0292       // check
0293       if (dtcHeader->getSlotCRCError(slot)) {
0294         if (!silent)
0295           edm::LogWarning("Invalid Data") << "CRC Error on uHTR data observed on slot " << slot
0296                                           << " of DTC with source id " << dtcHeader->getSourceId();
0297         report.countSpigotFormatError();
0298         continue;
0299       }
0300     }
0301 
0302     // check for EE
0303     if (htr.isEmptyEvent()) {
0304       report.countEmptyEventSpigot();
0305     }
0306     if (htr.isOverflowWarning()) {
0307       report.countOFWSpigot();
0308     }
0309     if (htr.isBusy()) {
0310       report.countBusySpigot();
0311     }
0312     if (!htr.check()) {
0313       if (!silent)
0314         edm::LogWarning("Invalid Data") << "Invalid HTR data observed on spigot " << spigot << " of DCC with source id "
0315                                         << dccHeader->getSourceId();
0316       report.countSpigotFormatError();
0317       continue;
0318     }
0319     if (htr.isHistogramEvent()) {
0320       if (!silent)
0321         edm::LogWarning("Invalid Data") << "Histogram data passed to non-histogram unpacker on spigot " << spigot
0322                                         << " of DCC with source id " << dccHeader->getSourceId();
0323       continue;
0324     }
0325     if ((htr.getFirmwareFlavor() & 0xE0) == 0x80) {  // some kind of TTP data
0326       if (colls.ttp != nullptr) {
0327         HcalTTPUnpacker ttpUnpack;
0328         colls.ttp->push_back(HcalTTPDigi());
0329         ttpUnpack.unpack(htr, colls.ttp->back());
0330       } else {
0331         LogDebug("HcalTechTrigProcessor")
0332             << "Skipping data on spigot " << spigot << " of DCC with source id " << dccHeader->getSourceId()
0333             << " which is from the TechTrigProcessor (use separate unpacker!)";
0334       }
0335       continue;
0336     }
0337     if (htr.getFirmwareFlavor() >= 0x80) {
0338       if (!silent)
0339         edm::LogWarning("HcalUnpacker") << "Skipping data on spigot " << spigot << " of DCC with source id "
0340                                         << dccHeader->getSourceId() << " which is of unknown flavor "
0341                                         << htr.getFirmwareFlavor();
0342       continue;
0343     }
0344 
0345     // calculate "real" number of presamples
0346     int nps = htr.getNPS() - startSample_;
0347 
0348     // get pointers
0349     htr.dataPointers(&daq_first, &daq_last, &tp_first, &tp_last);
0350     unsigned int smid = htr.getSubmodule();
0351     int htr_tb = smid & 0x1;
0352     int htr_slot = (smid >> 1) & 0x1F;
0353     int htr_cr = (smid >> 6) & 0x1F;
0354 
0355     tp_begin = (const HcalTriggerPrimitiveSample*)tp_first;
0356     tp_end = (const HcalTriggerPrimitiveSample*)(tp_last + 1);  // one beyond last..
0357 
0358     /// work through the samples
0359     int currFiberChan = 0x3F;  // invalid fiber+channel...
0360     int ncurr = 0;
0361     bool valid = false;
0362 
0363     bool tpgSOIbitInUse = htr.getFormatVersion() >= 3;                           // version 3 and later
0364     bool isHOtpg = htr.getFormatVersion() >= 3 && htr.getFirmwareFlavor() == 0;  // HO is flavor zero
0365     int npre = 0;
0366     /*
0367       Unpack the trigger primitives
0368     */
0369     if (isHOtpg) {
0370       HOUnrolledTP unrolled[24];
0371       for (tp_work = tp_begin; tp_work != tp_end; tp_work++) {
0372         if (tp_work->raw() == 0xFFFF)
0373           continue;  // filler word
0374         int sector = slbChan(tp_work->raw());
0375         if (sector > 2)
0376           continue;
0377 
0378         for (int ibit = 0; ibit < 8; ibit++) {
0379           int linear = sector * 8 + ibit;
0380           if (!unrolled[linear].checked) {
0381             unrolled[linear].checked = true;
0382             int fiber = (linear / 3) + 1;
0383             int fc = (linear % 3);
0384             // electronics id (use precision match for HO TP)
0385             HcalElectronicsId eid(fc, fiber, spigot, dccid);
0386             eid.setHTR(htr_cr, htr_slot, htr_tb);
0387             DetId did = emap.lookup(eid);
0388             if (!did.null()) {
0389               if (did.det() == DetId::Hcal && ((HcalSubdetector)did.subdetId()) == HcalOuter) {
0390                 HcalDetId hid(did);
0391                 unrolled[linear].valid = true;
0392                 unrolled[linear].ieta = hid.ieta();
0393                 unrolled[linear].iphi = hid.iphi();
0394               }
0395             } else {
0396               report.countUnmappedTPDigi(eid);
0397             }
0398           }
0399           if (unrolled[linear].valid) {
0400             if (isTPGSOI(*tp_work))
0401               unrolled[linear].soi = unrolled[linear].samples;
0402             if (tp_work->raw() & (1 << ibit))
0403               unrolled[linear].setbit(unrolled[linear].samples);
0404             unrolled[linear].samples++;
0405           }
0406         }
0407       }
0408       for (int i = 0; i < 24; i++) {
0409         if (unrolled[i].valid)
0410           colls.tphoCont->push_back(HOTriggerPrimitiveDigi(
0411               unrolled[i].ieta, unrolled[i].iphi, unrolled[i].samples, unrolled[i].soi, unrolled[i].databits));
0412       }
0413     } else {  // regular TPs (not HO)
0414       for (tp_work = tp_begin; tp_work != tp_end; tp_work++) {
0415         if (tp_work->raw() == 0xFFFF)
0416           continue;                                         // filler word
0417         if (slbAndChan(tp_work->raw()) != currFiberChan) {  // start new set
0418           npre = 0;
0419           currFiberChan = slbAndChan(tp_work->raw());
0420           // lookup the right channel
0421           HcalElectronicsId eid(slbChan(tp_work->raw()), slb(tp_work->raw()), spigot, dccid, htr_cr, htr_slot, htr_tb);
0422           DetId did = emap.lookupTrigger(eid);
0423           if (did.null()) {
0424             report.countUnmappedTPDigi(eid);
0425             if (unknownIdsTrig_.find(eid) == unknownIdsTrig_.end()) {
0426               if (!silent)
0427                 edm::LogWarning("HCAL") << "HcalUnpacker: No trigger primitive match found for electronics id :" << eid;
0428               unknownIdsTrig_.insert(eid);
0429             }
0430             valid = false;
0431             continue;
0432           } else if (did == HcalTrigTowerDetId::Undefined || (did.det() == DetId::Hcal && did.subdetId() == 0)) {
0433             // known to be unmapped
0434             valid = false;
0435             continue;
0436           }
0437           HcalTrigTowerDetId id(did);
0438           colls.tpCont->push_back(HcalTriggerPrimitiveDigi(id));
0439           // set the various bits
0440           if (!tpgSOIbitInUse)
0441             colls.tpCont->back().setPresamples(nps);
0442           colls.tpCont->back().setZSInfo(htr.isUnsuppressed(),
0443                                          htr.wasMarkAndPassZSTP(slb(tp_work->raw()), slbChan(tp_work->raw())));
0444 
0445           // no hits recorded for current
0446           ncurr = 0;
0447           valid = true;
0448         }
0449         // add the word (if within settings or recent firmware [recent firmware ignores startSample/endSample])
0450         if (valid && ((tpgSOIbitInUse && ncurr < 10) || (ncurr >= startSample_ && ncurr <= endSample_))) {
0451           colls.tpCont->back().setSample(colls.tpCont->back().size(), *tp_work);
0452           colls.tpCont->back().setSize(colls.tpCont->back().size() + 1);
0453         }
0454         // set presamples,if SOI
0455         if (valid && tpgSOIbitInUse && isTPGSOI(*tp_work)) {
0456           colls.tpCont->back().setPresamples(ncurr);
0457         }
0458         ncurr++;
0459         npre++;
0460       }
0461     }
0462 
0463     /// branch point between 2006-2011 data format and 2012+ data format
0464     if (htr.getFormatVersion() < HcalHTRData::FORMAT_VERSION_COMPACT_DATA) {
0465       qie_begin = (const HcalQIESample*)daq_first;
0466       qie_end = (const HcalQIESample*)(daq_last + 1);  // one beyond last..
0467 
0468       /// work through the samples
0469 
0470       for (qie_work = qie_begin; qie_work != qie_end;) {
0471         if (qie_work->raw() == 0xFFFF) {
0472           qie_work++;
0473           continue;  // filler word
0474         }
0475         // always at the beginning ...
0476 
0477         // lookup the right channel
0478         HcalElectronicsId eid(qie_work->fiberChan(), qie_work->fiber(), spigot, dccid);
0479         eid.setHTR(htr_cr, htr_slot, htr_tb);
0480         DetId did = emap.lookup(eid);
0481 
0482         if (!did.null()) {
0483           if (did.det() == DetId::Calo && did.subdetId() == HcalZDCDetId::SubdetectorId) {
0484             colls.zdcCont->push_back(ZDCDataFrame(HcalZDCDetId(did)));
0485             qie_work = HcalUnpacker_impl::unpack<ZDCDataFrame>(qie_work,
0486                                                                qie_end,
0487                                                                colls.zdcCont->back(),
0488                                                                nps,
0489                                                                eid,
0490                                                                startSample_,
0491                                                                endSample_,
0492                                                                expectedOrbitMessageTime_,
0493                                                                htr);
0494           } else if (did.det() == DetId::Hcal) {
0495             switch (((HcalSubdetector)did.subdetId())) {
0496               case (HcalBarrel):
0497               case (HcalEndcap): {
0498                 colls.hbheCont->push_back(HBHEDataFrame(HcalDetId(did)));
0499                 qie_work = HcalUnpacker_impl::unpack<HBHEDataFrame>(qie_work,
0500                                                                     qie_end,
0501                                                                     colls.hbheCont->back(),
0502                                                                     nps,
0503                                                                     eid,
0504                                                                     startSample_,
0505                                                                     endSample_,
0506                                                                     expectedOrbitMessageTime_,
0507                                                                     htr);
0508               } break;
0509               case (HcalOuter): {
0510                 colls.hoCont->push_back(HODataFrame(HcalDetId(did)));
0511                 qie_work = HcalUnpacker_impl::unpack<HODataFrame>(qie_work,
0512                                                                   qie_end,
0513                                                                   colls.hoCont->back(),
0514                                                                   nps,
0515                                                                   eid,
0516                                                                   startSample_,
0517                                                                   endSample_,
0518                                                                   expectedOrbitMessageTime_,
0519                                                                   htr);
0520               } break;
0521               case (HcalForward): {
0522                 colls.hfCont->push_back(HFDataFrame(HcalDetId(did)));
0523                 qie_work = HcalUnpacker_impl::unpack<HFDataFrame>(qie_work,
0524                                                                   qie_end,
0525                                                                   colls.hfCont->back(),
0526                                                                   nps,
0527                                                                   eid,
0528                                                                   startSample_,
0529                                                                   endSample_,
0530                                                                   expectedOrbitMessageTime_,
0531                                                                   htr);
0532               } break;
0533               case (HcalOther): {
0534                 HcalOtherDetId odid(did);
0535                 if (odid.subdet() == HcalCalibration) {
0536                   colls.calibCont->push_back(HcalCalibDataFrame(HcalCalibDetId(did)));
0537                   qie_work = HcalUnpacker_impl::unpack<HcalCalibDataFrame>(qie_work,
0538                                                                            qie_end,
0539                                                                            colls.calibCont->back(),
0540                                                                            nps,
0541                                                                            eid,
0542                                                                            startSample_,
0543                                                                            endSample_,
0544                                                                            expectedOrbitMessageTime_,
0545                                                                            htr);
0546                 }
0547               } break;
0548               case (HcalEmpty):
0549               default: {
0550                 for (int fiberC = qie_work->fiberAndChan(); qie_work != qie_end && qie_work->fiberAndChan() == fiberC;
0551                      qie_work++)
0552                   ;
0553               } break;
0554             }
0555           }
0556         } else {
0557           report.countUnmappedDigi(eid);
0558           if (unknownIds_.find(eid) == unknownIds_.end()) {
0559             if (!silent)
0560               edm::LogWarning("HCAL") << "HcalUnpacker: No match found for electronics id :" << eid;
0561             unknownIds_.insert(eid);
0562           }
0563           for (int fiberC = qie_work->fiberAndChan(); qie_work != qie_end && qie_work->fiberAndChan() == fiberC;
0564                qie_work++)
0565             ;
0566         }
0567       }
0568     } else {
0569       // this is the branch for unpacking the compact data format with per-channel headers
0570       const unsigned short* ptr_header = daq_first;
0571       const unsigned short* ptr_end = daq_last + 1;
0572       int flavor, error_flags, capid0, channelid;
0573 
0574       while (ptr_header != ptr_end) {
0575         if (*ptr_header == 0xFFFF) {  // impossible filler word
0576           ptr_header++;
0577           continue;
0578         }
0579         // unpack the header word
0580         bool isheader = HcalHTRData::unpack_per_channel_header(*ptr_header, flavor, error_flags, capid0, channelid);
0581         if (!isheader) {
0582           ptr_header++;
0583           continue;
0584         }
0585 
0586         int fiberchan = channelid & 0x3;
0587         int fiber = ((channelid >> 2) & 0x7) + 1;
0588 
0589         // lookup the right channel
0590         HcalElectronicsId eid(fiberchan, fiber, spigot, dccid);
0591         eid.setHTR(htr_cr, htr_slot, htr_tb);
0592         DetId did = emap.lookup(eid);
0593 
0594         if (!did.null()) {
0595           if (did.det() == DetId::Calo && did.subdetId() == HcalZDCDetId::SubdetectorId) {
0596             colls.zdcCont->push_back(ZDCDataFrame(HcalZDCDetId(did)));
0597             ptr_header = HcalUnpacker_impl::unpack_compact<ZDCDataFrame>(ptr_header,
0598                                                                          ptr_end,
0599                                                                          colls.zdcCont->back(),
0600                                                                          nps,
0601                                                                          eid,
0602                                                                          startSample_,
0603                                                                          endSample_,
0604                                                                          expectedOrbitMessageTime_,
0605                                                                          htr);
0606           } else if (did.det() == DetId::Hcal) {
0607             switch (((HcalSubdetector)did.subdetId())) {
0608               case (HcalBarrel):
0609               case (HcalEndcap): {
0610                 colls.hbheCont->push_back(HBHEDataFrame(HcalDetId(did)));
0611                 ptr_header = HcalUnpacker_impl::unpack_compact<HBHEDataFrame>(ptr_header,
0612                                                                               ptr_end,
0613                                                                               colls.hbheCont->back(),
0614                                                                               nps,
0615                                                                               eid,
0616                                                                               startSample_,
0617                                                                               endSample_,
0618                                                                               expectedOrbitMessageTime_,
0619                                                                               htr);
0620               } break;
0621               case (HcalOuter): {
0622                 colls.hoCont->push_back(HODataFrame(HcalDetId(did)));
0623                 ptr_header = HcalUnpacker_impl::unpack_compact<HODataFrame>(ptr_header,
0624                                                                             ptr_end,
0625                                                                             colls.hoCont->back(),
0626                                                                             nps,
0627                                                                             eid,
0628                                                                             startSample_,
0629                                                                             endSample_,
0630                                                                             expectedOrbitMessageTime_,
0631                                                                             htr);
0632               } break;
0633               case (HcalForward): {
0634                 colls.hfCont->push_back(HFDataFrame(HcalDetId(did)));
0635                 ptr_header = HcalUnpacker_impl::unpack_compact<HFDataFrame>(ptr_header,
0636                                                                             ptr_end,
0637                                                                             colls.hfCont->back(),
0638                                                                             nps,
0639                                                                             eid,
0640                                                                             startSample_,
0641                                                                             endSample_,
0642                                                                             expectedOrbitMessageTime_,
0643                                                                             htr);
0644               } break;
0645               case (HcalOther): {
0646                 HcalOtherDetId odid(did);
0647                 if (odid.subdet() == HcalCalibration) {
0648                   colls.calibCont->push_back(HcalCalibDataFrame(HcalCalibDetId(did)));
0649                   ptr_header = HcalUnpacker_impl::unpack_compact<HcalCalibDataFrame>(ptr_header,
0650                                                                                      ptr_end,
0651                                                                                      colls.calibCont->back(),
0652                                                                                      nps,
0653                                                                                      eid,
0654                                                                                      startSample_,
0655                                                                                      endSample_,
0656                                                                                      expectedOrbitMessageTime_,
0657                                                                                      htr);
0658                 }
0659               } break;
0660               case (HcalEmpty):
0661               default: {
0662                 for (ptr_header++; ptr_header != ptr_end && !HcalHTRData::is_channel_header(*ptr_header); ptr_header++)
0663                   ;
0664               } break;
0665             }
0666           }
0667         } else {
0668           report.countUnmappedDigi(eid);
0669           if (unknownIds_.find(eid) == unknownIds_.end()) {
0670             if (!silent)
0671               edm::LogWarning("HCAL") << "HcalUnpacker: No match found for electronics id :" << eid;
0672             unknownIds_.insert(eid);
0673           }
0674           for (ptr_header++; ptr_header != ptr_end && !HcalHTRData::is_channel_header(*ptr_header); ptr_header++)
0675             ;
0676         }
0677       }
0678     }
0679   }
0680 }
0681 
0682 void HcalUnpacker::unpackUTCA(const FEDRawData& raw,
0683                               const HcalElectronicsMap& emap,
0684                               Collections& colls,
0685                               HcalUnpackerReport& report,
0686                               bool silent) {
0687   const hcal::AMC13Header* amc13 = (const hcal::AMC13Header*)(raw.data());
0688 
0689   // how many AMC in this packet
0690   int namc = amc13->NAMC();
0691   for (int iamc = 0; iamc < namc; iamc++) {
0692     // if not enabled, ignore
0693     if (!amc13->AMCEnabled(iamc))
0694       continue;
0695 
0696     if (!amc13->AMCDataPresent(iamc)) {
0697       if (!silent)
0698         edm::LogWarning("Invalid Data") << "Missing data observed on iamc " << iamc << " of AMC13 with source id "
0699                                         << amc13->sourceId();
0700       report.countSpigotFormatError();
0701       continue;
0702     }
0703     if (!amc13->AMCCRCOk(iamc)) {
0704       if (!silent)
0705         edm::LogWarning("Invalid Data") << "CRC Error on uHTR data observed on iamc " << iamc
0706                                         << " of AMC13 with source id " << amc13->sourceId();
0707       report.countSpigotFormatError();
0708       //      continue;
0709     }
0710     // this unpacker cannot handle segmented data!
0711     if (amc13->AMCSegmented(iamc)) {
0712       if (!silent)
0713         edm::LogWarning("Invalid Data") << "Unpacker cannot handle segmented data observed on iamc " << iamc
0714                                         << " of AMC13 with source id " << amc13->sourceId();
0715       report.countSpigotFormatError();
0716       continue;
0717     }
0718 
0719     // ok, now we're work-able
0720     int slot = amc13->AMCSlot(iamc);
0721     int crate = amc13->AMCId(iamc) & 0xFF;
0722 
0723     HcalUHTRData uhtr(amc13->AMCPayload(iamc), amc13->AMCSize(iamc));
0724     //Check to make sure uMNio is not unpacked here
0725     if (uhtr.getFormatVersion() != 1) {
0726       unpackUMNio(raw, slot, colls);
0727       continue;
0728     }
0729 #ifdef DebugLog
0730     //debug printouts
0731     int nwords = uhtr.getRawLengthBytes() / 2;
0732     for (int iw = 0; iw < nwords; iw++)
0733       printf("%04d %04x\n", iw, uhtr.getRawData16()[iw]);
0734 #endif
0735 
0736     //use uhtr presamples since amc header not properly packed in simulation
0737     int nps = uhtr.presamples();
0738 
0739     HcalUHTRData::const_iterator i = uhtr.begin(), iend = uhtr.end();
0740     while (i != iend) {
0741 #ifdef DebugLog
0742       std::cout << "This data is flavored:" << i.flavor() << std::endl;
0743 #endif
0744 
0745       if (!i.isHeader()) {
0746         ++i;
0747 #ifdef DebugLog
0748         std::cout << "its not a header" << std::endl;
0749 #endif
0750         continue;
0751       }
0752       ///////////////////////////////////////////////HE UNPACKER//////////////////////////////////////////////////////////////////////////////////////
0753       if (i.flavor() == 1 || i.flavor() == 0 || i.flavor() == 3) {
0754         int ifiber = ((i.channelid() >> 3) & 0x1F);
0755         int ichan = (i.channelid() & 0x7);
0756         HcalElectronicsId eid(crate, slot, ifiber, ichan, false);
0757         DetId did = emap.lookup(eid);
0758         // Count from current position to next header, or equal to end
0759         const uint16_t* head_pos = i.raw();
0760         int ns = 0;
0761         for (++i; i != iend && !i.isHeader(); ++i) {
0762           ns++;
0763         }
0764         // Check QEI11 container exists
0765         if (colls.qie11 == nullptr) {
0766           colls.qie11 = new QIE11DigiCollection(ns);
0767         } else if (colls.qie11->samples() != ns) {
0768           // if this sample type hasn't been requested to be saved
0769           // warn the user to provide a configuration that prompts it to be saved
0770           if (colls.qie11Addtl.find(ns) == colls.qie11Addtl.end()) {
0771             printInvalidDataMessage("QIE11", colls.qie11->samples(), ns, true);
0772           }
0773         }
0774 
0775         // Insert data
0776         /////////////////////////////////////////////CODE FROM OLD STYLE DIGIS///////////////////////////////////////////////////////////////
0777         if (!did.null()) {  // unpack and store...
0778           // only fill the default collection if we have the correct number of samples
0779           if (colls.qie11->samples() == ns) {
0780             colls.qie11->addDataFrame(did, head_pos);
0781           }
0782           // fill the additional qie11 collections
0783           if (colls.qie11Addtl.find(ns) != colls.qie11Addtl.end()) {
0784             colls.qie11Addtl[ns]->addDataFrame(did, head_pos);
0785           }
0786         } else {
0787           report.countUnmappedDigi(eid);
0788           if (unknownIds_.find(eid) == unknownIds_.end()) {
0789             if (!silent)
0790               edm::LogWarning("HCAL") << "HcalUnpacker: No match found for electronics id :" << eid;
0791             unknownIds_.insert(eid);
0792 #ifdef DebugLog
0793             std::cout << "HcalUnpacker: No match found for electronics id :" << eid << std::endl;
0794 #endif
0795           }
0796 #ifdef DebugLog
0797           std::cout << "OH NO! detector id is null!" << std::endl;
0798 #endif
0799         }
0800       } else if (i.flavor() == 2) {
0801         //////////////////////////////////////////////////HF UNPACKER/////////////////////////////////////////////////////////////////////
0802 
0803         int ifiber = ((i.channelid() >> 3) & 0x1F);
0804         int ichan = (i.channelid() & 0x7);
0805         HcalElectronicsId eid(crate, slot, ifiber, ichan, false);
0806         DetId did = emap.lookup(eid);
0807 
0808         // Count from current position to next header, or equal to end
0809         const uint16_t* head_pos = i.raw();
0810         int ns = 0;
0811         for (++i; i != iend && !i.isHeader(); ++i) {
0812           ns++;
0813         }
0814 
0815         bool isZDC = (did.det() == DetId::Calo && did.subdetId() == HcalZDCDetId::SubdetectorId);
0816         bool isLasmon = (did.det() == DetId::Hcal && (HcalSubdetector)did.subdetId() == HcalOther &&
0817                          HcalCalibDetId(did).calibFlavor() == 5);
0818 
0819         if (isZDC) {
0820           if (colls.qie10ZDC == nullptr) {
0821             colls.qie10ZDC = new QIE10DigiCollection(ns);
0822           } else if (colls.qie10ZDC->samples() != ns) {
0823             printInvalidDataMessage("QIE10ZDC", colls.qie10ZDC->samples(), ns, false);
0824           }
0825         } else if (isLasmon) {
0826           if (colls.qie10Lasermon == nullptr) {
0827             colls.qie10Lasermon = new QIE10DigiCollection(ns);
0828           } else if (colls.qie10Lasermon->samples() != ns) {
0829             printInvalidDataMessage("QIE10LASMON", colls.qie10Lasermon->samples(), ns, false);
0830           }
0831         } else {  // these are the default qie10 channels
0832           if (colls.qie10 == nullptr) {
0833             colls.qie10 = new QIE10DigiCollection(ns);
0834           } else if (colls.qie10->samples() != ns) {
0835             // if this sample type hasn't been requested to be saved
0836             // warn the user to provide a configuration that prompts it to be saved
0837             if (colls.qie10Addtl.find(ns) == colls.qie10Addtl.end()) {
0838               printInvalidDataMessage("QIE10", colls.qie10->samples(), ns, true);
0839             }
0840           }
0841         }
0842 
0843         // Insert data
0844         /////////////////////////////////////////////CODE FROM OLD STYLE DIGIS///////////////////////////////////////////////////////////////
0845         if (!did.null()) {  // unpack and store...
0846           // fill the additional qie10 collections
0847           if (isZDC)
0848             colls.qie10ZDC->addDataFrame(did, head_pos);
0849           else if (isLasmon)
0850             colls.qie10Lasermon->addDataFrame(did, head_pos);
0851           else {
0852             // only fill the default collection if we have the correct number of samples
0853             if (colls.qie10->samples() == ns) {
0854               colls.qie10->addDataFrame(did, head_pos);
0855             }
0856 
0857             // fill the additional qie10 collections
0858             if (colls.qie10Addtl.find(ns) != colls.qie10Addtl.end()) {
0859               colls.qie10Addtl[ns]->addDataFrame(did, head_pos);
0860             }
0861           }
0862         } else {
0863           report.countUnmappedDigi(eid);
0864           if (unknownIds_.find(eid) == unknownIds_.end()) {
0865             if (!silent)
0866               edm::LogWarning("HCAL") << "HcalUnpacker: No match found for electronics id :" << eid;
0867             unknownIds_.insert(eid);
0868 #ifdef DebugLog
0869             std::cout << "HcalUnpacker: No match found for electronics id :" << eid << std::endl;
0870 #endif
0871           }
0872 #ifdef DebugLog
0873           std::cout << "OH NO! HcalUnpacker: No match found for electronics id :" << eid << std::endl;
0874 #endif
0875         }
0876       } else if (i.flavor() == 5 || (i.flavor() == 7 && i.technicalDataType() == 15)) {  // Old-style digis
0877         int ifiber = ((i.channelid() >> 2) & 0x1F);
0878         int ichan = (i.channelid() & 0x3);
0879         HcalElectronicsId eid(crate, slot, ifiber, ichan, false);
0880         DetId did = emap.lookup(eid);
0881 
0882         if (!did.null()) {  // unpack and store...
0883           if (did.det() == DetId::Calo && did.subdetId() == HcalZDCDetId::SubdetectorId) {
0884             colls.zdcCont->push_back(ZDCDataFrame(HcalZDCDetId(did)));
0885             HcalUnpacker_impl::unpack_compact<ZDCDataFrame>(
0886                 i, iend, colls.zdcCont->back(), nps, eid, startSample_, endSample_);
0887           } else if (did.det() == DetId::Hcal) {
0888             switch (((HcalSubdetector)did.subdetId())) {
0889               case (HcalBarrel):
0890               case (HcalEndcap): {
0891                 colls.hbheCont->push_back(HBHEDataFrame(HcalDetId(did)));
0892                 HcalUnpacker_impl::unpack_compact<HBHEDataFrame>(
0893                     i, iend, colls.hbheCont->back(), nps, eid, startSample_, endSample_);
0894               } break;
0895               case (HcalOuter): {
0896                 colls.hoCont->push_back(HODataFrame(HcalDetId(did)));
0897                 HcalUnpacker_impl::unpack_compact<HODataFrame>(
0898                     i, iend, colls.hoCont->back(), nps, eid, startSample_, endSample_);
0899               } break;
0900               case (HcalForward): {
0901                 colls.hfCont->push_back(HFDataFrame(HcalDetId(did)));
0902                 HcalUnpacker_impl::unpack_compact<HFDataFrame>(
0903                     i, iend, colls.hfCont->back(), nps, eid, startSample_, endSample_);
0904               } break;
0905               case (HcalOther): {
0906                 HcalOtherDetId odid(did);
0907                 if (odid.subdet() == HcalCalibration) {
0908                   colls.calibCont->push_back(HcalCalibDataFrame(HcalCalibDetId(did)));
0909                   HcalUnpacker_impl::unpack_compact<HcalCalibDataFrame>(
0910                       i, iend, colls.calibCont->back(), nps, eid, startSample_, endSample_);
0911                 }
0912               } break;
0913               case (HcalEmpty):
0914               default: {
0915                 for (++i; i != iend && !i.isHeader(); ++i)
0916                   ;
0917               } break;
0918             }
0919           }
0920         } else {
0921           report.countUnmappedDigi(eid);
0922           if (unknownIds_.find(eid) == unknownIds_.end()) {
0923             if (!silent)
0924               edm::LogWarning("HCAL") << "HcalUnpacker: No match found for electronics id :" << eid;
0925             unknownIds_.insert(eid);
0926           }
0927           for (++i; i != iend && !i.isHeader(); ++i)
0928             ;
0929         }
0930       } else if (i.flavor() == 0x4) {  // TP digis
0931         int ilink = ((i.channelid() >> 4) & 0xF);
0932         int itower = (i.channelid() & 0xF);
0933         HcalElectronicsId eid(crate, slot, ilink, itower, true);
0934         DetId did = emap.lookupTrigger(eid);
0935 #ifdef DebugLog
0936         std::cout << "Unpacking " << eid << " " << i.channelid() << std::endl;
0937 #endif
0938         if (did.null()) {
0939           report.countUnmappedTPDigi(eid);
0940           if (unknownIdsTrig_.find(eid) == unknownIdsTrig_.end()) {
0941             if (!silent)
0942               edm::LogWarning("HCAL") << "HcalUnpacker: No trigger primitive match found for electronics id :" << eid;
0943             unknownIdsTrig_.insert(eid);
0944           }
0945           // Skip it
0946           for (++i; i != iend && !i.isHeader(); ++i)
0947             ;
0948         } else if (did == HcalTrigTowerDetId::Undefined || (did.det() == DetId::Hcal && did.subdetId() == 0)) {
0949           for (++i; i != iend && !i.isHeader(); ++i)
0950             ;
0951         } else {
0952           HcalTrigTowerDetId id(did);
0953 #ifdef DebugLog
0954           std::cout << "Unpacking " << id << std::endl;
0955 #endif
0956           colls.tpCont->push_back(HcalTriggerPrimitiveDigi(id));
0957           int j = 0;
0958           for (++i; i != iend && !i.isHeader(); ++i) {
0959             colls.tpCont->back().setSample(j, i.value());
0960             if (i.soi())
0961               colls.tpCont->back().setPresamples(j);
0962             j++;
0963           }
0964           colls.tpCont->back().setSize(j);
0965         }
0966       } else {
0967         // consume any not-understood channel data
0968         for (++i; i != iend && !i.isHeader(); ++i)
0969           ;
0970       }
0971     }
0972   }
0973 }
0974 
0975 HcalUnpacker::Collections::Collections() {
0976   hbheCont = nullptr;
0977   hoCont = nullptr;
0978   hfCont = nullptr;
0979   tpCont = nullptr;
0980   zdcCont = nullptr;
0981   calibCont = nullptr;
0982   ttp = nullptr;
0983   qie10 = nullptr;
0984   qie10ZDC = nullptr;
0985   qie10Lasermon = nullptr;
0986   qie11 = nullptr;
0987   umnio = nullptr;
0988 }
0989 
0990 void HcalUnpacker::unpack(const FEDRawData& raw,
0991                           const HcalElectronicsMap& emap,
0992                           std::vector<HcalHistogramDigi>& histoDigis) {
0993   // get the DCC header
0994   const HcalDCCHeader* dccHeader = (const HcalDCCHeader*)(raw.data());
0995   int dccid = dccHeader->getSourceId() - sourceIdOffset_;
0996 
0997   // check the summary status
0998 
0999   // walk through the HTR data...
1000   HcalHTRData htr;
1001   for (int spigot = 0; spigot < HcalDCCHeader::SPIGOT_COUNT; spigot++) {
1002     if (!dccHeader->getSpigotPresent(spigot))
1003       continue;
1004 
1005     int retval = dccHeader->getSpigotData(spigot, htr, raw.size());
1006     // check
1007     if (retval || !htr.check()) {
1008       edm::LogWarning("Invalid Data") << "Invalid HTR data observed on spigot " << spigot << " of DCC with source id "
1009                                       << dccHeader->getSourceId();
1010       continue;
1011     }
1012     if (!htr.isHistogramEvent()) {
1013       edm::LogWarning("Invalid Data") << "Non-histogram data passed to histogram unpacker on spigot " << spigot
1014                                       << " of DCC with source id " << dccHeader->getSourceId();
1015       continue;
1016     }
1017 
1018     unsigned int smid = htr.getSubmodule();
1019     int htr_tb = smid & 0x1;
1020     int htr_slot = (smid >> 1) & 0x1F;
1021     int htr_cr = (smid >> 6) & 0x1F;
1022 
1023     // find out the fibers
1024     int f[2], fc;
1025     htr.getHistogramFibers(f[0], f[1]);
1026 
1027     for (int nf = 0; nf < 2; nf++) {
1028       if (f[nf] < 0 || (nf == 1 && f[0] == f[1]))
1029         continue;  // skip if invalid or the same
1030       for (fc = 0; fc <= 2; fc++) {
1031         HcalElectronicsId eid(fc, f[nf], spigot, dccid);
1032         eid.setHTR(htr_cr, htr_slot, htr_tb);
1033         DetId did = emap.lookup(eid);
1034 
1035         if (did.null() || did.det() != DetId::Hcal || did.subdetId() == 0) {
1036           if (unknownIds_.find(eid) == unknownIds_.end()) {
1037             edm::LogWarning("HCAL") << "HcalHistogramUnpacker: No match found for electronics id :" << eid;
1038             unknownIds_.insert(eid);
1039           }
1040           continue;
1041         }
1042         histoDigis.push_back(HcalHistogramDigi(HcalDetId(did)));  // add it!
1043         HcalHistogramDigi& digi = histoDigis.back();
1044 
1045         // unpack the four capids
1046         for (int capid = 0; capid < 4; capid++)
1047           htr.unpackHistogram(f[nf], fc, capid, digi.getArray(capid));
1048       }
1049     }
1050   }
1051 }
1052 // Method to unpack uMNio data
1053 void HcalUnpacker::unpackUMNio(const FEDRawData& raw, int slot, Collections& colls) {
1054   const hcal::AMC13Header* amc13 = (const hcal::AMC13Header*)(raw.data());
1055   int namc = amc13->NAMC();
1056   //Find AMC corresponding to uMNio slot
1057   for (int iamc = 0; iamc < namc; iamc++) {
1058     if (amc13->AMCSlot(iamc) == slot)
1059       namc = iamc;
1060   }
1061   if (namc == amc13->NAMC()) {
1062     return;
1063   }
1064   const uint16_t* data = (const uint16_t*)(amc13->AMCPayload(namc));
1065   size_t nwords = amc13->AMCSize(namc) * (sizeof(uint64_t) / sizeof(uint16_t));
1066   *(colls.umnio) = HcalUMNioDigi(data, nwords);
1067 }
1068 
1069 void HcalUnpacker::printInvalidDataMessage(const std::string& coll_type,
1070                                            int default_ns,
1071                                            int conflict_ns,
1072                                            bool extended) {
1073   nPrinted_++;
1074 
1075   constexpr int limit = 2;  //print up to limit-1 messages
1076   if (nPrinted_ >= limit) {
1077     if (nPrinted_ == limit)
1078       edm::LogInfo("Invalid Data") << "Suppressing further error messages";
1079 
1080     return;
1081   }
1082 
1083   std::stringstream message;
1084 
1085   message << "The default " << coll_type << " Collection has " << default_ns
1086           << " samples per digi, while the current data has " << conflict_ns
1087           << "!  This data cannot be included with the default collection.";
1088 
1089   if (extended) {
1090     message << "\nIn order to store this data in the event, it must have a unique tag.  "
1091             << "To accomplish this, provide two lists to HcalRawToDigi \n"
1092             << "1) that specifies the number of samples and "
1093             << "2) that gives tags with which these data are saved.\n"
1094             << "For example in this case you might add \n"
1095             << "process.hcalDigis.save" << coll_type << "DataNSamples = cms.untracked.vint32( " << conflict_ns
1096             << ") \nprocess.hcalDigis.save" << coll_type << "DataTags = cms.untracked.vstring( \"MYDATA\" )";
1097   }
1098 
1099   edm::LogWarning("Invalid Data") << message.str();
1100 }