CMS 3D CMS Logo

CMSSW_4_4_3_patch1/src/EventFilter/HcalRawToDigi/src/HcalUnpacker.cc

Go to the documentation of this file.
00001 #include "EventFilter/HcalRawToDigi/interface/HcalUnpacker.h"
00002 #include "EventFilter/HcalRawToDigi/interface/HcalDCCHeader.h"
00003 #include "EventFilter/HcalRawToDigi/interface/HcalHTRData.h"
00004 #include "DataFormats/HcalDetId/interface/HcalOtherDetId.h"
00005 #include "DataFormats/HcalDigi/interface/HcalQIESample.h"
00006 #include "FWCore/MessageLogger/interface/MessageLogger.h"
00007 #include "EventFilter/HcalRawToDigi/interface/HcalTTPUnpacker.h"
00008 
00009 namespace HcalUnpacker_impl {
00010   template <class DigiClass>
00011   const HcalQIESample* unpack(const HcalQIESample* startPoint, const HcalQIESample* limit, DigiClass& digi, int presamples, const HcalElectronicsId& eid, int startSample, int endSample, int expectedTime, const HcalHTRData& hhd) {
00012     // set parameters
00013     digi.setPresamples(presamples);
00014     digi.setReadoutIds(eid);
00015     int fiber=startPoint->fiber();
00016     int fiberchan=startPoint->fiberChan();
00017     uint32_t zsmask=hhd.zsBunchMask()>>startSample;
00018     digi.setZSInfo(hhd.isUnsuppressed(),hhd.wasMarkAndPassZS(fiber,fiberchan),zsmask);
00019 
00020     if (expectedTime>=0 && !hhd.isUnsuppressed()) {
00021       //      std::cout << hhd.getFibOrbMsgBCN(fiber) << " " << expectedTime << std::endl;
00022       digi.setFiberIdleOffset(hhd.getFibOrbMsgBCN(fiber)-expectedTime);
00023     }
00024 
00025     // what is my sample number?
00026     int myFiberChan=startPoint->fiberAndChan();
00027     int ncurr=0,ntaken=0;
00028     const HcalQIESample* qie_work=startPoint;
00029     while (qie_work!=limit && qie_work->fiberAndChan()==myFiberChan) {
00030       if (ncurr>=startSample && ncurr<=endSample) {
00031         digi.setSample(ntaken,*qie_work);
00032         ++ntaken;
00033       }
00034       ncurr++;
00035       qie_work++;
00036     }
00037     digi.setSize(ntaken);
00038     return qie_work;
00039   }
00040 }
00041 
00042 static inline bool isTPGSOI(const HcalTriggerPrimitiveSample& s) {
00043   return (s.raw()&0x200)!=0;
00044 }
00045 
00046 
00047 struct HOUnrolledTP { // parts of an HO trigger primitive, unpacked
00048   bool valid, checked;
00049   int ieta, iphi, samples, soi;
00050   unsigned int databits;
00051   HOUnrolledTP() {
00052     valid=false;
00053     checked=false;
00054     ieta=0;
00055     iphi=0;
00056     samples=0;
00057     soi=0;
00058     databits=0;
00059   }
00060   void setbit(int i) { databits|=(1<<i); }    
00061 };
00062 
00063 void HcalUnpacker::unpack(const FEDRawData& raw, const HcalElectronicsMap& emap,
00064                           Collections& colls, HcalUnpackerReport& report, bool silent) {
00065 
00066   if (raw.size()<16) {
00067     if (!silent) edm::LogWarning("Invalid Data") << "Empty/invalid DCC data, size = " << raw.size();
00068     return;
00069   }
00070 
00071   // get the DCC header
00072   const HcalDCCHeader* dccHeader=(const HcalDCCHeader*)(raw.data());
00073   int dccid=dccHeader->getSourceId()-sourceIdOffset_;
00074 
00075   // check the summary status
00076   
00077   // walk through the HTR data...
00078   HcalHTRData htr;
00079   const unsigned short* daq_first, *daq_last, *tp_first, *tp_last;
00080   const HcalQIESample* qie_begin, *qie_end, *qie_work;
00081   const HcalTriggerPrimitiveSample *tp_begin, *tp_end, *tp_work; 
00082   for (int spigot=0; spigot<HcalDCCHeader::SPIGOT_COUNT; spigot++) {
00083     if (!dccHeader->getSpigotPresent(spigot)) continue;
00084 
00085     int retval=dccHeader->getSpigotData(spigot,htr,raw.size());
00086     if (retval!=0) {
00087       if (retval==-1) {
00088         if (!silent) edm::LogWarning("Invalid Data") << "Invalid HTR data (data beyond payload size) observed on spigot " << spigot << " of DCC with source id " << dccHeader->getSourceId();
00089         report.countSpigotFormatError();
00090       }
00091       continue;
00092     }
00093     // check
00094     if (dccHeader->getSpigotCRCError(spigot)) {
00095       if (!silent) 
00096         edm::LogWarning("Invalid Data") << "CRC Error on HTR data observed on spigot " << spigot << " of DCC with source id " << dccHeader->getSourceId();
00097       report.countSpigotFormatError();
00098       continue;
00099     }  
00100     if (!htr.check()) {
00101       if (!silent) 
00102         edm::LogWarning("Invalid Data") << "Invalid HTR data observed on spigot " << spigot << " of DCC with source id " << dccHeader->getSourceId();
00103       report.countSpigotFormatError();
00104       continue;
00105     }  
00106     if (htr.isHistogramEvent()) {
00107       if (!silent) edm::LogWarning("Invalid Data") << "Histogram data passed to non-histogram unpacker on spigot " << spigot << " of DCC with source id " << dccHeader->getSourceId();
00108       continue;
00109     }
00110     if ((htr.getFirmwareFlavor()&0xE0)==0x80) { // some kind of TTP data
00111       if (colls.ttp!=0) {
00112         HcalTTPUnpacker ttpUnpack;
00113         colls.ttp->push_back(HcalTTPDigi());
00114         ttpUnpack.unpack(htr,colls.ttp->back());
00115       } else {
00116         LogDebug("HcalTechTrigProcessor") << "Skipping data on spigot " << spigot << " of DCC with source id " << dccHeader->getSourceId() << " which is from the TechTrigProcessor (use separate unpacker!)";
00117       }
00118       continue;
00119     }
00120     if (htr.getFirmwareFlavor()>=0x80) {
00121       if (!silent) edm::LogWarning("HcalUnpacker") << "Skipping data on spigot " << spigot << " of DCC with source id " << dccHeader->getSourceId() << " which is of unknown flavor " << htr.getFirmwareFlavor();
00122       continue;
00123     }
00124 
00125     // calculate "real" number of presamples
00126     int nps=htr.getNPS()-startSample_;
00127     
00128     // get pointers
00129     htr.dataPointers(&daq_first,&daq_last,&tp_first,&tp_last);
00130     unsigned int smid=htr.getSubmodule();
00131     int htr_tb=smid&0x1;
00132     int htr_slot=(smid>>1)&0x1F;
00133     int htr_cr=(smid>>6)&0x1F;
00134     
00135     tp_begin=(HcalTriggerPrimitiveSample*)tp_first;
00136     tp_end=(HcalTriggerPrimitiveSample*)(tp_last+1); // one beyond last..
00137     
00139     int currFiberChan=0x3F; // invalid fiber+channel...
00140     int ncurr=0;
00141     bool valid=false;
00142 
00143     bool tpgSOIbitInUse=htr.getFormatVersion()>=3; // version 3 and later
00144     bool isHOtpg=htr.getFormatVersion()>=3 && htr.getFirmwareFlavor()==0; // HO is flavor zero
00145     int npre=0;
00146     /*
00147       Unpack the trigger primitives
00148     */
00149     if (isHOtpg) {
00150       HOUnrolledTP unrolled[24];
00151       for (tp_work=tp_begin; tp_work!=tp_end; tp_work++) {
00152         if (tp_work->raw()==0xFFFF) continue; // filler word
00153         int sector=tp_work->slbChan();
00154         if (sector>2) continue;
00155 
00156         for (int ibit=0; ibit<8; ibit++) {
00157           int linear=sector*8+ibit; 
00158           if (!unrolled[linear].checked) {
00159             unrolled[linear].checked=true;
00160             int fiber=(linear/3)+1;
00161             int fc=(linear%3);
00162             // electronics id (use precision match for HO TP)
00163             HcalElectronicsId eid(fc,fiber,spigot,dccid);       
00164             eid.setHTR(htr_cr,htr_slot,htr_tb);
00165             DetId did=emap.lookup(eid);
00166             if (!did.null()) {
00167               if (did.det()==DetId::Hcal && ((HcalSubdetector)did.subdetId())==HcalOuter ) {
00168                 HcalDetId hid(did);
00169                 unrolled[linear].valid=true;
00170                 unrolled[linear].ieta=hid.ieta();
00171                 unrolled[linear].iphi=hid.iphi();
00172               }
00173             } else {
00174               report.countUnmappedTPDigi(eid);
00175             }
00176           }
00177           if (unrolled[linear].valid) {
00178             if (isTPGSOI(*tp_work)) unrolled[linear].soi=unrolled[linear].samples;
00179             if (tp_work->raw()&(1<<ibit)) unrolled[linear].setbit(unrolled[linear].samples);
00180             unrolled[linear].samples++;
00181           }
00182         }
00183       }
00184       for (int i=0; i<24; i++) {
00185         if (unrolled[i].valid) 
00186           colls.tphoCont->push_back(HOTriggerPrimitiveDigi(
00187                                                            unrolled[i].ieta,
00188                                                            unrolled[i].iphi,
00189                                                            unrolled[i].samples,
00190                                                            unrolled[i].soi,
00191                                                            unrolled[i].databits));
00192       }
00193     } else { // regular TPs (not HO)
00194       for (tp_work=tp_begin; tp_work!=tp_end; tp_work++) {
00195         if (tp_work->raw()==0xFFFF) continue; // filler word
00196         if (tp_work->slbAndChan()!=currFiberChan) { // start new set
00197           npre=0;
00198           currFiberChan=tp_work->slbAndChan();
00199           // lookup the right channel
00200           HcalElectronicsId eid(tp_work->slbChan(),tp_work->slb(),spigot,dccid,htr_cr,htr_slot,htr_tb);
00201           DetId did=emap.lookupTrigger(eid);
00202           if (did.null()) {
00203             report.countUnmappedTPDigi(eid);
00204             if (unknownIdsTrig_.find(eid)==unknownIdsTrig_.end()) {
00205               if (!silent) edm::LogWarning("HCAL") << "HcalUnpacker: No trigger primitive match found for electronics id :" << eid;
00206               unknownIdsTrig_.insert(eid);
00207             }
00208             valid=false;
00209             continue;
00210           } else if (did==HcalTrigTowerDetId::Undefined || 
00211                      (did.det()==DetId::Hcal && did.subdetId()==0)) {
00212             // known to be unmapped
00213             valid=false;
00214             continue;
00215           }
00216           HcalTrigTowerDetId id(did);
00217           colls.tpCont->push_back(HcalTriggerPrimitiveDigi(id));
00218           // set the various bits
00219           if (!tpgSOIbitInUse) colls.tpCont->back().setPresamples(nps);
00220           colls.tpCont->back().setZSInfo(htr.isUnsuppressed(),htr.wasMarkAndPassZSTP(tp_work->slb(),tp_work->slbChan()));
00221 
00222           // no hits recorded for current
00223           ncurr=0;
00224           valid=true;
00225         }      
00226         // add the word (if within settings or recent firmware [recent firmware ignores startSample/endSample])
00227         if (valid && ((tpgSOIbitInUse && ncurr<10) || (ncurr>=startSample_ && ncurr<=endSample_))) {
00228           colls.tpCont->back().setSample(colls.tpCont->back().size(),*tp_work);
00229           colls.tpCont->back().setSize(colls.tpCont->back().size()+1);
00230         }
00231         // set presamples,if SOI
00232         if (valid && tpgSOIbitInUse && isTPGSOI(*tp_work)) {
00233           colls.tpCont->back().setPresamples(ncurr);
00234         }
00235         ncurr++;
00236         npre++;
00237       }
00238     }
00239   
00240 
00241     qie_begin=(HcalQIESample*)daq_first;
00242     qie_end=(HcalQIESample*)(daq_last+1); // one beyond last..
00243 
00245     currFiberChan=0x3F; // invalid fiber+channel...
00246     ncurr=0;
00247     valid=false;
00248 
00249     
00250     for (qie_work=qie_begin; qie_work!=qie_end; ) {
00251       if (qie_work->raw()==0xFFFF) {
00252         qie_work++;
00253         continue; // filler word
00254       }
00255       // always at the beginning ...
00256       currFiberChan=qie_work->fiberAndChan();
00257 
00258       // lookup the right channel
00259       HcalElectronicsId eid(qie_work->fiberChan(),qie_work->fiber(),spigot,dccid);
00260       eid.setHTR(htr_cr,htr_slot,htr_tb);
00261       DetId did=emap.lookup(eid);
00262 
00263       if (!did.null()) {
00264         if (did.det()==DetId::Calo && did.subdetId()==HcalZDCDetId::SubdetectorId) {
00265           colls.zdcCont->push_back(ZDCDataFrame(HcalZDCDetId(did)));
00266           qie_work=HcalUnpacker_impl::unpack<ZDCDataFrame>(qie_work, qie_end, colls.zdcCont->back(), nps, eid, startSample_, endSample_, expectedOrbitMessageTime_, htr); 
00267         } else if (did.det()==DetId::Hcal) {
00268           switch (((HcalSubdetector)did.subdetId())) {
00269           case (HcalBarrel):
00270           case (HcalEndcap): {
00271             colls.hbheCont->push_back(HBHEDataFrame(HcalDetId(did)));
00272             qie_work=HcalUnpacker_impl::unpack<HBHEDataFrame>(qie_work, qie_end, colls.hbheCont->back(), nps, eid, startSample_, endSample_, expectedOrbitMessageTime_, htr);
00273           } break;
00274           case (HcalOuter): {
00275             colls.hoCont->push_back(HODataFrame(HcalDetId(did)));
00276             qie_work=HcalUnpacker_impl::unpack<HODataFrame>(qie_work, qie_end, colls.hoCont->back(), nps, eid, startSample_, endSample_, expectedOrbitMessageTime_, htr);
00277           } break;
00278           case (HcalForward): {
00279             colls.hfCont->push_back(HFDataFrame(HcalDetId(did)));
00280             qie_work=HcalUnpacker_impl::unpack<HFDataFrame>(qie_work, qie_end, colls.hfCont->back(), nps, eid, startSample_, endSample_, expectedOrbitMessageTime_, htr);
00281           } break;
00282           case (HcalOther) : {
00283             HcalOtherDetId odid(did);
00284             if (odid.subdet()==HcalCalibration) {
00285               colls.calibCont->push_back(HcalCalibDataFrame(HcalCalibDetId(did)));
00286               qie_work=HcalUnpacker_impl::unpack<HcalCalibDataFrame>(qie_work, qie_end, colls.calibCont->back(), nps, eid, startSample_, endSample_, expectedOrbitMessageTime_, htr); 
00287             }
00288           } break;
00289           case (HcalEmpty): 
00290           default: {
00291             for (int fiberC=qie_work->fiberAndChan();
00292                  qie_work!=qie_end && qie_work->fiberAndChan()==fiberC;
00293                  qie_work++);
00294           }
00295           break;
00296           }
00297         }
00298       } else {
00299         report.countUnmappedDigi(eid);
00300         if (unknownIds_.find(eid)==unknownIds_.end()) {
00301           if (!silent) edm::LogWarning("HCAL") << "HcalUnpacker: No match found for electronics id :" << eid;
00302           unknownIds_.insert(eid);
00303         }
00304         for (int fiberC=qie_work->fiberAndChan();
00305              qie_work!=qie_end && qie_work->fiberAndChan()==fiberC;
00306              qie_work++);
00307       }
00308     }
00309   }
00310 }
00311 
00312 HcalUnpacker::Collections::Collections() {
00313   hbheCont=0;
00314   hoCont=0;
00315   hfCont=0;
00316   tpCont=0;
00317   zdcCont=0;
00318   calibCont=0;
00319   ttp=0;
00320 }
00321 
00322 void HcalUnpacker::unpack(const FEDRawData& raw, const HcalElectronicsMap& emap, std::vector<HBHEDataFrame>& container, std::vector<HcalTriggerPrimitiveDigi>& tp) {
00323   Collections c;
00324   c.hbheCont=&container;
00325   c.tpCont=&tp;
00326   HcalUnpackerReport r;
00327   unpack(raw,emap,c,r);
00328 }
00329 
00330 void HcalUnpacker::unpack(const FEDRawData& raw, const HcalElectronicsMap& emap, std::vector<HODataFrame>& container, std::vector<HcalTriggerPrimitiveDigi>& tp) {
00331   Collections c;
00332   c.hoCont=&container;
00333   c.tpCont=&tp;
00334   HcalUnpackerReport r;
00335   unpack(raw,emap,c,r);
00336 }
00337 
00338 void HcalUnpacker::unpack(const FEDRawData& raw, const HcalElectronicsMap& emap, std::vector<HFDataFrame>& container, std::vector<HcalTriggerPrimitiveDigi>& tp) {
00339   Collections c;
00340   c.hfCont=&container;
00341   c.tpCont=&tp;
00342   HcalUnpackerReport r;
00343   unpack(raw,emap,c,r);
00344 }
00345 
00346 void HcalUnpacker::unpack(const FEDRawData& raw, const HcalElectronicsMap& emap, std::vector<HcalHistogramDigi>& histoDigis) {
00347 
00348   // get the DCC header
00349   const HcalDCCHeader* dccHeader=(const HcalDCCHeader*)(raw.data());
00350   int dccid=dccHeader->getSourceId()-sourceIdOffset_;
00351   
00352   // check the summary status
00353   
00354   // walk through the HTR data...
00355   HcalHTRData htr;
00356   for (int spigot=0; spigot<HcalDCCHeader::SPIGOT_COUNT; spigot++) {
00357     if (!dccHeader->getSpigotPresent(spigot)) continue;
00358     
00359     int retval=dccHeader->getSpigotData(spigot,htr,raw.size());
00360     // check
00361     if (retval || !htr.check()) {
00362       edm::LogWarning("Invalid Data") << "Invalid HTR data observed on spigot " << spigot << " of DCC with source id " << dccHeader->getSourceId();
00363       continue;
00364     }
00365     if (!htr.isHistogramEvent()) {
00366       edm::LogWarning("Invalid Data") << "Non-histogram data passed to histogram unpacker on spigot " << spigot << " of DCC with source id " << dccHeader->getSourceId();
00367       continue;
00368     }
00369 
00370     unsigned int smid=htr.getSubmodule();
00371     int htr_tb=smid&0x1;
00372     int htr_slot=(smid>>1)&0x1F;
00373     int htr_cr=(smid>>6)&0x1F;
00374     
00375     // find out the fibers
00376     int f[2],fc;
00377     htr.getHistogramFibers(f[0],f[1]);
00378 
00379     for (int nf=0; nf<2; nf++) {
00380       if (f[nf]<0 || (nf==1 && f[0]==f[1])) continue; // skip if invalid or the same
00381       for (fc=0; fc<=2; fc++) {
00382         HcalElectronicsId eid(fc,f[nf],spigot,dccid);     
00383         eid.setHTR(htr_cr,htr_slot,htr_tb);
00384         DetId did=emap.lookup(eid);
00385 
00386         if (did.null() || did.det()!=DetId::Hcal || did.subdetId()==0) {
00387           if (unknownIds_.find(eid)==unknownIds_.end()) {
00388             edm::LogWarning("HCAL") << "HcalHistogramUnpacker: No match found for electronics id :" << eid;
00389             unknownIds_.insert(eid);
00390           }       
00391           continue;
00392         }
00393         histoDigis.push_back(HcalHistogramDigi(HcalDetId(did))); // add it!
00394         HcalHistogramDigi& digi=histoDigis.back();
00395         
00396         // unpack the four capids
00397         for (int capid=0; capid<4; capid++) 
00398           htr.unpackHistogram(f[nf],fc,capid,digi.getArray(capid));
00399         
00400       }
00401     }
00402   }
00403 }      
00404