CMS 3D CMS Logo

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

Generated on Tue Jun 9 17:34:41 2009 for CMSSW by  doxygen 1.5.4