CMS 3D CMS Logo

/data/refman/pasoursint/CMSSW_6_1_2_SLHC4_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/HcalDTCHeader.h"
00004 #include "EventFilter/HcalRawToDigi/interface/HcalHTRData.h"
00005 #include "DataFormats/HcalDetId/interface/HcalOtherDetId.h"
00006 #include "DataFormats/HcalDigi/interface/HcalQIESample.h"
00007 #include "FWCore/MessageLogger/interface/MessageLogger.h"
00008 #include "EventFilter/HcalRawToDigi/interface/HcalTTPUnpacker.h"
00009 
00010 namespace HcalUnpacker_impl {
00011   template <class DigiClass>
00012   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) {
00013     // set parameters
00014     digi.setPresamples(presamples);
00015     digi.setReadoutIds(eid);
00016 
00017     int fiber=startPoint->fiber();
00018     int fiberchan=startPoint->fiberChan();
00019     uint32_t zsmask=hhd.zsBunchMask()>>startSample;
00020     digi.setZSInfo(hhd.isUnsuppressed(),hhd.wasMarkAndPassZS(fiber,fiberchan),zsmask);
00021 
00022     if (expectedTime>=0 && !hhd.isUnsuppressed()) {
00023       //      std::cout << hhd.getFibOrbMsgBCN(fiber) << " " << expectedTime << std::endl;
00024       digi.setFiberIdleOffset(hhd.getFibOrbMsgBCN(fiber)-expectedTime);
00025     }
00026 
00027     // what is my sample number?
00028     int myFiberChan=startPoint->fiberAndChan();
00029     int ncurr=0,ntaken=0;
00030     const HcalQIESample* qie_work=startPoint;
00031     while (qie_work!=limit && qie_work->fiberAndChan()==myFiberChan) {
00032       if (ncurr>=startSample && ncurr<=endSample) {
00033         digi.setSample(ntaken,*qie_work);
00034         ++ntaken;
00035       }
00036       ncurr++;
00037       qie_work++;
00038     }
00039     digi.setSize(ntaken);
00040     return qie_work;
00041   }
00042 
00043 
00044   template <class DigiClass>
00045   const unsigned short* unpack_compact(const unsigned short* startPoint, const unsigned short* limit, DigiClass& digi, 
00046                                        int presamples, const HcalElectronicsId& eid, int startSample, int endSample, 
00047                                        int expectedTime, const HcalHTRData& hhd) {
00048     // set parameters
00049     digi.setPresamples(presamples);
00050     digi.setReadoutIds(eid);
00051     int flavor, error_flags, capid0, channelid;
00052 
00053     HcalHTRData::unpack_per_channel_header(*startPoint,flavor,error_flags,capid0,channelid);
00054     bool isCapRotating=!(error_flags&0x1);
00055     bool fiberErr=(error_flags&0x2);
00056     bool dataValid=!(error_flags&0x2);
00057     int fiberchan=channelid&0x3;
00058     int fiber=((channelid>>2)&0x7)+1;
00059 
00060     uint32_t zsmask=hhd.zsBunchMask()>>startSample;
00061     digi.setZSInfo(hhd.isUnsuppressed(),hhd.wasMarkAndPassZS(fiber,fiberchan),zsmask);
00062 
00063     if (expectedTime>=0 && !hhd.isUnsuppressed()) {
00064       //      std::cout << hhd.getFibOrbMsgBCN(fiber) << " " << expectedTime << std::endl;
00065       digi.setFiberIdleOffset(hhd.getFibOrbMsgBCN(fiber)-expectedTime);
00066     }
00067 
00068     // what is my sample number?
00069     int ncurr=0,ntaken=0;
00070     const unsigned short* qie_work=startPoint;
00071     // we branch here between normal (flavor=5) and error mode (flavor=6)
00072     if (flavor==5) {
00073       for (qie_work++; qie_work!=limit && !HcalHTRData::is_channel_header(*qie_work); qie_work++) {
00074         int capidn=(isCapRotating)?((capid0+ncurr)%4):(capid0);
00075         int capidn1=(isCapRotating)?((capid0+ncurr+1)%4):(capid0);
00076         // two samples in one...
00077         HcalQIESample s0((*qie_work)&0x7F,capidn,fiber,fiberchan,dataValid,fiberErr);
00078         HcalQIESample s1(((*qie_work)>>8)&0x7F,capidn1,fiber,fiberchan,dataValid,fiberErr);
00079         
00080         if (ncurr>=startSample && ncurr<=endSample) {
00081           digi.setSample(ntaken,s0);
00082           ++ntaken;
00083         }
00084         ncurr++;
00085         if (ncurr>=startSample && ncurr<=endSample) {
00086           digi.setSample(ntaken,s1);
00087           ++ntaken;
00088         }
00089         ncurr++;
00090       }
00091       digi.setSize(ntaken);
00092     } else if (flavor==6) {
00093       for (qie_work++; qie_work!=limit && !HcalHTRData::is_channel_header(*qie_work); qie_work++) {
00094         if (ncurr>=startSample && ncurr<=endSample) {
00095           HcalQIESample sample((*qie_work)&0x7F,((*qie_work)>>8)&0x3,fiber,fiberchan,((*qie_work)>>10)&0x1,((*qie_work)>>11)&0x1);
00096           digi.setSample(ntaken,sample);
00097           ++ntaken;
00098         }
00099         ncurr++;
00100       }
00101       digi.setSize(ntaken);
00102     }
00103     return qie_work;
00104   }
00105 
00106 }
00107 
00108 static inline bool isTPGSOI(const HcalTriggerPrimitiveSample& s) {
00109   return (s.raw()&0x200)!=0;
00110 }
00111 
00112 
00113 struct HOUnrolledTP { // parts of an HO trigger primitive, unpacked
00114   bool valid, checked;
00115   int ieta, iphi, samples, soi;
00116   unsigned int databits;
00117   HOUnrolledTP() {
00118     valid=false;
00119     checked=false;
00120     ieta=0;
00121     iphi=0;
00122     samples=0;
00123     soi=0;
00124     databits=0;
00125   }
00126   void setbit(int i) { databits|=(1<<i); }    
00127 };
00128 
00129 void HcalUnpacker::unpack(const FEDRawData& raw, const HcalElectronicsMap& emap,
00130                           Collections& colls, HcalUnpackerReport& report, bool silent) {
00131 
00132   if (raw.size()<16) {
00133     if (!silent) edm::LogWarning("Invalid Data") << "Empty/invalid DCC data, size = " << raw.size();
00134     return;
00135   }
00136 
00137   // get the DCC header
00138   const HcalDCCHeader* dccHeader=(const HcalDCCHeader*)(raw.data());
00139   const HcalDTCHeader* dtcHeader=(const HcalDTCHeader*)(raw.data());
00140   bool is_VME_DCC=(dccHeader->getDCCDataFormatVersion()<0x10) || ((mode_&0x1)==0);
00141   
00142   int dccid=(is_VME_DCC)?(dccHeader->getSourceId()-sourceIdOffset_):(dtcHeader->getSourceId()-sourceIdOffset_);
00143 
00144   // check the summary status
00145   
00146   // walk through the HTR data.  For the uTCA, use spigot=slot+1
00147   HcalHTRData htr;
00148   const unsigned short* daq_first, *daq_last, *tp_first, *tp_last;
00149   const HcalQIESample* qie_begin, *qie_end, *qie_work;
00150   const HcalTriggerPrimitiveSample *tp_begin, *tp_end, *tp_work; 
00151   for (int spigot=0; spigot<HcalDCCHeader::SPIGOT_COUNT; spigot++) {
00152     
00153     if (is_VME_DCC) {
00154       if (!dccHeader->getSpigotPresent(spigot)) continue;
00155 
00156       int retval=dccHeader->getSpigotData(spigot,htr,raw.size());
00157       if (retval!=0) {
00158         if (retval==-1) {
00159           if (!silent) edm::LogWarning("Invalid Data") << "Invalid HTR data (data beyond payload size) observed on spigot " << spigot << " of DCC with source id " << dccHeader->getSourceId();
00160           report.countSpigotFormatError();
00161         }
00162         continue;
00163       }
00164       // check
00165       if (dccHeader->getSpigotCRCError(spigot)) {
00166         if (!silent) 
00167           edm::LogWarning("Invalid Data") << "CRC Error on HTR data observed on spigot " << spigot << " of DCC with source id " << dccHeader->getSourceId();
00168         report.countSpigotFormatError();
00169         continue;
00170       } 
00171     } else { // is_uTCA (!is_VME_DCC)
00172       int slot=spigot+1;
00173       if (slot>HcalDTCHeader::MAXIMUM_SLOT) continue;
00174 
00175       if (!dtcHeader->getSlotPresent(slot)) continue;
00176 
00177       int retval=dtcHeader->getSlotData(slot,htr,raw.size());
00178       if (retval!=0) {
00179         if (retval==-1) {
00180           if (!silent) edm::LogWarning("Invalid Data") << "Invalid uHTR data (data beyond payload size) observed on slot " << slot << " of DTC with source id " << dtcHeader->getSourceId();
00181           report.countSpigotFormatError();
00182         }
00183         continue;
00184       }
00185       // check
00186       if (dtcHeader->getSlotCRCError(slot)) {
00187         if (!silent) 
00188           edm::LogWarning("Invalid Data") << "CRC Error on uHTR data observed on slot " << slot << " of DTC with source id " << dtcHeader->getSourceId();
00189         report.countSpigotFormatError();
00190         continue;
00191       } 
00192     }
00193 
00194 
00195     // check for EE
00196     if (htr.isEmptyEvent()) {
00197       report.countEmptyEventSpigot();
00198     }
00199     if (htr.isOverflowWarning()) {
00200       report.countOFWSpigot();
00201     }
00202     if (htr.isBusy()) {
00203       report.countBusySpigot();
00204     }
00205     if (!htr.check()) {
00206       if (!silent) 
00207         edm::LogWarning("Invalid Data") << "Invalid HTR data observed on spigot " << spigot << " of DCC with source id " << dccHeader->getSourceId();
00208       report.countSpigotFormatError();
00209       continue;
00210     }  
00211     if (htr.isHistogramEvent()) {
00212       if (!silent) edm::LogWarning("Invalid Data") << "Histogram data passed to non-histogram unpacker on spigot " << spigot << " of DCC with source id " << dccHeader->getSourceId();
00213       continue;
00214     }
00215     if ((htr.getFirmwareFlavor()&0xE0)==0x80) { // some kind of TTP data
00216       if (colls.ttp!=0) {
00217         HcalTTPUnpacker ttpUnpack;
00218         colls.ttp->push_back(HcalTTPDigi());
00219         ttpUnpack.unpack(htr,colls.ttp->back());
00220       } else {
00221         LogDebug("HcalTechTrigProcessor") << "Skipping data on spigot " << spigot << " of DCC with source id " << dccHeader->getSourceId() << " which is from the TechTrigProcessor (use separate unpacker!)";
00222       }
00223       continue;
00224     }
00225     if (htr.getFirmwareFlavor()>=0x80) {
00226       if (!silent) edm::LogWarning("HcalUnpacker") << "Skipping data on spigot " << spigot << " of DCC with source id " << dccHeader->getSourceId() << " which is of unknown flavor " << htr.getFirmwareFlavor();
00227       continue;
00228     }
00229 
00230     // calculate "real" number of presamples
00231     int nps=htr.getNPS()-startSample_;
00232     
00233     // get pointers
00234     htr.dataPointers(&daq_first,&daq_last,&tp_first,&tp_last);
00235     unsigned int smid=htr.getSubmodule();
00236     int htr_tb=smid&0x1;
00237     int htr_slot=(smid>>1)&0x1F;
00238     int htr_cr=(smid>>6)&0x1F;
00239     
00240     tp_begin=(HcalTriggerPrimitiveSample*)tp_first;
00241     tp_end=(HcalTriggerPrimitiveSample*)(tp_last+1); // one beyond last..
00242     
00244     int currFiberChan=0x3F; // invalid fiber+channel...
00245     int ncurr=0;
00246     bool valid=false;
00247 
00248     bool tpgSOIbitInUse=htr.getFormatVersion()>=3; // version 3 and later
00249     bool isHOtpg=htr.getFormatVersion()>=3 && htr.getFirmwareFlavor()==0; // HO is flavor zero
00250     int npre=0;
00251     /*
00252       Unpack the trigger primitives
00253     */
00254     if (isHOtpg) {
00255       HOUnrolledTP unrolled[24];
00256       for (tp_work=tp_begin; tp_work!=tp_end; tp_work++) {
00257         if (tp_work->raw()==0xFFFF) continue; // filler word
00258         int sector=tp_work->slbChan();
00259         if (sector>2) continue;
00260 
00261         for (int ibit=0; ibit<8; ibit++) {
00262           int linear=sector*8+ibit; 
00263           if (!unrolled[linear].checked) {
00264             unrolled[linear].checked=true;
00265             int fiber=(linear/3)+1;
00266             int fc=(linear%3);
00267             // electronics id (use precision match for HO TP)
00268             HcalElectronicsId eid(fc,fiber,spigot,dccid);       
00269             eid.setHTR(htr_cr,htr_slot,htr_tb);
00270             DetId did=emap.lookup(eid);
00271             if (!did.null()) {
00272               if (did.det()==DetId::Hcal && ((HcalSubdetector)did.subdetId())==HcalOuter ) {
00273                 HcalDetId hid(did);
00274                 unrolled[linear].valid=true;
00275                 unrolled[linear].ieta=hid.ieta();
00276                 unrolled[linear].iphi=hid.iphi();
00277               }
00278             } else {
00279               report.countUnmappedTPDigi(eid);
00280             }
00281           }
00282           if (unrolled[linear].valid) {
00283             if (isTPGSOI(*tp_work)) unrolled[linear].soi=unrolled[linear].samples;
00284             if (tp_work->raw()&(1<<ibit)) unrolled[linear].setbit(unrolled[linear].samples);
00285             unrolled[linear].samples++;
00286           }
00287         }
00288       }
00289       for (int i=0; i<24; i++) {
00290         if (unrolled[i].valid) 
00291           colls.tphoCont->push_back(HOTriggerPrimitiveDigi(
00292                                                            unrolled[i].ieta,
00293                                                            unrolled[i].iphi,
00294                                                            unrolled[i].samples,
00295                                                            unrolled[i].soi,
00296                                                            unrolled[i].databits));
00297       }
00298     } else { // regular TPs (not HO)
00299       for (tp_work=tp_begin; tp_work!=tp_end; tp_work++) {
00300         if (tp_work->raw()==0xFFFF) continue; // filler word
00301         if (tp_work->slbAndChan()!=currFiberChan) { // start new set
00302           npre=0;
00303           currFiberChan=tp_work->slbAndChan();
00304           // lookup the right channel
00305           HcalElectronicsId eid(tp_work->slbChan(),tp_work->slb(),spigot,dccid,htr_cr,htr_slot,htr_tb);
00306           DetId did=emap.lookupTrigger(eid);
00307           if (did.null()) {
00308             report.countUnmappedTPDigi(eid);
00309             if (unknownIdsTrig_.find(eid)==unknownIdsTrig_.end()) {
00310               if (!silent) edm::LogWarning("HCAL") << "HcalUnpacker: No trigger primitive match found for electronics id :" << eid;
00311               unknownIdsTrig_.insert(eid);
00312             }
00313             valid=false;
00314             continue;
00315           } else if (did==HcalTrigTowerDetId::Undefined || 
00316                      (did.det()==DetId::Hcal && did.subdetId()==0)) {
00317             // known to be unmapped
00318             valid=false;
00319             continue;
00320           }
00321           HcalTrigTowerDetId id(did);
00322           colls.tpCont->push_back(HcalTriggerPrimitiveDigi(id));
00323           // set the various bits
00324           if (!tpgSOIbitInUse) colls.tpCont->back().setPresamples(nps);
00325           colls.tpCont->back().setZSInfo(htr.isUnsuppressed(),htr.wasMarkAndPassZSTP(tp_work->slb(),tp_work->slbChan()));
00326 
00327           // no hits recorded for current
00328           ncurr=0;
00329           valid=true;
00330         }      
00331         // add the word (if within settings or recent firmware [recent firmware ignores startSample/endSample])
00332         if (valid && ((tpgSOIbitInUse && ncurr<10) || (ncurr>=startSample_ && ncurr<=endSample_))) {
00333           colls.tpCont->back().setSample(colls.tpCont->back().size(),*tp_work);
00334           colls.tpCont->back().setSize(colls.tpCont->back().size()+1);
00335         }
00336         // set presamples,if SOI
00337         if (valid && tpgSOIbitInUse && isTPGSOI(*tp_work)) {
00338           colls.tpCont->back().setPresamples(ncurr);
00339         }
00340         ncurr++;
00341         npre++;
00342       }
00343     }
00344 
00346     if (htr.getFormatVersion() < HcalHTRData::FORMAT_VERSION_COMPACT_DATA) {
00347  
00348       qie_begin=(HcalQIESample*)daq_first;
00349       qie_end=(HcalQIESample*)(daq_last+1); // one beyond last..
00350 
00352       currFiberChan=0x3F; // invalid fiber+channel...
00353       ncurr=0;
00354       valid=false;
00355 
00356     
00357       for (qie_work=qie_begin; qie_work!=qie_end; ) {
00358         if (qie_work->raw()==0xFFFF) {
00359           qie_work++;
00360           continue; // filler word
00361         }
00362         // always at the beginning ...
00363         currFiberChan=qie_work->fiberAndChan();
00364         
00365         // lookup the right channel
00366         HcalElectronicsId eid(qie_work->fiberChan(),qie_work->fiber(),spigot,dccid);
00367         eid.setHTR(htr_cr,htr_slot,htr_tb);
00368         DetId did=emap.lookup(eid);
00369         
00370         if (!did.null()) {
00371           if (did.det()==DetId::Calo && did.subdetId()==HcalZDCDetId::SubdetectorId) {
00372             colls.zdcCont->push_back(ZDCDataFrame(HcalZDCDetId(did)));
00373             qie_work=HcalUnpacker_impl::unpack<ZDCDataFrame>(qie_work, qie_end, colls.zdcCont->back(), nps, eid, startSample_, endSample_, expectedOrbitMessageTime_, htr); 
00374           } else if (did.det()==DetId::Hcal) {
00375             switch (((HcalSubdetector)did.subdetId())) {
00376             case (HcalBarrel):
00377             case (HcalEndcap): {
00378               colls.hbheCont->push_back(HBHEDataFrame(HcalDetId(did)));
00379               qie_work=HcalUnpacker_impl::unpack<HBHEDataFrame>(qie_work, qie_end, colls.hbheCont->back(), nps, eid, startSample_, endSample_, expectedOrbitMessageTime_, htr);
00380             } break;
00381             case (HcalOuter): {
00382               colls.hoCont->push_back(HODataFrame(HcalDetId(did)));
00383               qie_work=HcalUnpacker_impl::unpack<HODataFrame>(qie_work, qie_end, colls.hoCont->back(), nps, eid, startSample_, endSample_, expectedOrbitMessageTime_, htr);
00384           } break;
00385             case (HcalForward): {
00386               colls.hfCont->push_back(HFDataFrame(HcalDetId(did)));
00387               qie_work=HcalUnpacker_impl::unpack<HFDataFrame>(qie_work, qie_end, colls.hfCont->back(), nps, eid, startSample_, endSample_, expectedOrbitMessageTime_, htr);
00388             } break;
00389             case (HcalOther) : {
00390               HcalOtherDetId odid(did);
00391               if (odid.subdet()==HcalCalibration) {
00392                 colls.calibCont->push_back(HcalCalibDataFrame(HcalCalibDetId(did)));
00393                 qie_work=HcalUnpacker_impl::unpack<HcalCalibDataFrame>(qie_work, qie_end, colls.calibCont->back(), nps, eid, startSample_, endSample_, expectedOrbitMessageTime_, htr); 
00394               }
00395             } break;
00396             case (HcalEmpty): 
00397             default: {
00398               for (int fiberC=qie_work->fiberAndChan();
00399                    qie_work!=qie_end && qie_work->fiberAndChan()==fiberC;
00400                    qie_work++);
00401             }
00402             break;
00403             }
00404           }
00405         } else {
00406           report.countUnmappedDigi(eid);
00407           if (unknownIds_.find(eid)==unknownIds_.end()) {
00408             if (!silent) edm::LogWarning("HCAL") << "HcalUnpacker: No match found for electronics id :" << eid;
00409             unknownIds_.insert(eid);
00410         }
00411           for (int fiberC=qie_work->fiberAndChan();
00412                qie_work!=qie_end && qie_work->fiberAndChan()==fiberC;
00413                qie_work++);
00414         }
00415       }
00416     } else {
00417       // this is the branch for unpacking the compact data format with per-channel headers
00418       const unsigned short* ptr_header=daq_first;
00419       const unsigned short* ptr_end=daq_last+1;
00420       int flavor, error_flags, capid0, channelid;
00421 
00422       while (ptr_header!=ptr_end) {
00423         if (*ptr_header==0xFFFF) { // impossible filler word
00424           ptr_header++;
00425           continue;
00426         }
00427         // unpack the header word
00428         bool isheader=HcalHTRData::unpack_per_channel_header(*ptr_header,flavor,error_flags,capid0,channelid);
00429         if (!isheader) {
00430           ptr_header++;
00431           continue;
00432         }
00433 
00434         int fiberchan=channelid&0x3;
00435         int fiber=((channelid>>2)&0x7)+1;
00436 
00437         // lookup the right channel
00438         HcalElectronicsId eid(fiberchan,fiber,spigot,dccid);
00439         eid.setHTR(htr_cr,htr_slot,htr_tb);
00440         DetId did=emap.lookup(eid);
00441         
00442         if (!did.null()) {
00443           if (did.det()==DetId::Calo && did.subdetId()==HcalZDCDetId::SubdetectorId) {
00444             colls.zdcCont->push_back(ZDCDataFrame(HcalZDCDetId(did)));
00445             ptr_header=HcalUnpacker_impl::unpack_compact<ZDCDataFrame>(ptr_header, ptr_end, colls.zdcCont->back(), nps, eid, startSample_, endSample_, expectedOrbitMessageTime_, htr); 
00446           } else if (did.det()==DetId::Hcal) {
00447             switch (((HcalSubdetector)did.subdetId())) {
00448             case (HcalBarrel):
00449             case (HcalEndcap): {
00450               colls.hbheCont->push_back(HBHEDataFrame(HcalDetId(did)));
00451               ptr_header=HcalUnpacker_impl::unpack_compact<HBHEDataFrame>(ptr_header, ptr_end, colls.hbheCont->back(), nps, eid, startSample_, endSample_, expectedOrbitMessageTime_, htr);
00452             } break;
00453             case (HcalOuter): {
00454               colls.hoCont->push_back(HODataFrame(HcalDetId(did)));
00455               ptr_header=HcalUnpacker_impl::unpack_compact<HODataFrame>(ptr_header, ptr_end, colls.hoCont->back(), nps, eid, startSample_, endSample_, expectedOrbitMessageTime_, htr);
00456           } break;
00457             case (HcalForward): {
00458               colls.hfCont->push_back(HFDataFrame(HcalDetId(did)));
00459               ptr_header=HcalUnpacker_impl::unpack_compact<HFDataFrame>(ptr_header, ptr_end, colls.hfCont->back(), nps, eid, startSample_, endSample_, expectedOrbitMessageTime_, htr);
00460             } break;
00461             case (HcalOther) : {
00462               HcalOtherDetId odid(did);
00463               if (odid.subdet()==HcalCalibration) {
00464                 colls.calibCont->push_back(HcalCalibDataFrame(HcalCalibDetId(did)));
00465                 ptr_header=HcalUnpacker_impl::unpack_compact<HcalCalibDataFrame>(ptr_header, ptr_end, colls.calibCont->back(), nps, eid, startSample_, endSample_, expectedOrbitMessageTime_, htr); 
00466               }
00467             } break;
00468             case (HcalEmpty): 
00469             default: {
00470               for (ptr_header++;
00471                    ptr_header!=ptr_end && !HcalHTRData::is_channel_header(*ptr_header);
00472                    ptr_header++);
00473             }
00474             break;
00475             }
00476           }
00477         } else {
00478           report.countUnmappedDigi(eid);
00479           if (unknownIds_.find(eid)==unknownIds_.end()) {
00480             if (!silent) edm::LogWarning("HCAL") << "HcalUnpacker: No match found for electronics id :" << eid;
00481             unknownIds_.insert(eid);
00482           }
00483           for (ptr_header++;
00484                ptr_header!=ptr_end && !HcalHTRData::is_channel_header(*ptr_header);
00485                ptr_header++);
00486         }
00487       }
00488 
00489     }
00490   }
00491 }
00492 
00493 HcalUnpacker::Collections::Collections() {
00494   hbheCont=0;
00495   hoCont=0;
00496   hfCont=0;
00497   tpCont=0;
00498   zdcCont=0;
00499   calibCont=0;
00500   ttp=0;
00501 }
00502 
00503 void HcalUnpacker::unpack(const FEDRawData& raw, const HcalElectronicsMap& emap, std::vector<HBHEDataFrame>& container, std::vector<HcalTriggerPrimitiveDigi>& tp) {
00504   Collections c;
00505   c.hbheCont=&container;
00506   c.tpCont=&tp;
00507   HcalUnpackerReport r;
00508   unpack(raw,emap,c,r);
00509 }
00510 
00511 void HcalUnpacker::unpack(const FEDRawData& raw, const HcalElectronicsMap& emap, std::vector<HODataFrame>& container, std::vector<HcalTriggerPrimitiveDigi>& tp) {
00512   Collections c;
00513   c.hoCont=&container;
00514   c.tpCont=&tp;
00515   HcalUnpackerReport r;
00516   unpack(raw,emap,c,r);
00517 }
00518 
00519 void HcalUnpacker::unpack(const FEDRawData& raw, const HcalElectronicsMap& emap, std::vector<HFDataFrame>& container, std::vector<HcalTriggerPrimitiveDigi>& tp) {
00520   Collections c;
00521   c.hfCont=&container;
00522   c.tpCont=&tp;
00523   HcalUnpackerReport r;
00524   unpack(raw,emap,c,r);
00525 }
00526 
00527 void HcalUnpacker::unpack(const FEDRawData& raw, const HcalElectronicsMap& emap, std::vector<HcalHistogramDigi>& histoDigis) {
00528 
00529   // get the DCC header
00530   const HcalDCCHeader* dccHeader=(const HcalDCCHeader*)(raw.data());
00531   int dccid=dccHeader->getSourceId()-sourceIdOffset_;
00532   
00533   // check the summary status
00534   
00535   // walk through the HTR data...
00536   HcalHTRData htr;
00537   for (int spigot=0; spigot<HcalDCCHeader::SPIGOT_COUNT; spigot++) {
00538     if (!dccHeader->getSpigotPresent(spigot)) continue;
00539     
00540     int retval=dccHeader->getSpigotData(spigot,htr,raw.size());
00541     // check
00542     if (retval || !htr.check()) {
00543       edm::LogWarning("Invalid Data") << "Invalid HTR data observed on spigot " << spigot << " of DCC with source id " << dccHeader->getSourceId();
00544       continue;
00545     }
00546     if (!htr.isHistogramEvent()) {
00547       edm::LogWarning("Invalid Data") << "Non-histogram data passed to histogram unpacker on spigot " << spigot << " of DCC with source id " << dccHeader->getSourceId();
00548       continue;
00549     }
00550 
00551     unsigned int smid=htr.getSubmodule();
00552     int htr_tb=smid&0x1;
00553     int htr_slot=(smid>>1)&0x1F;
00554     int htr_cr=(smid>>6)&0x1F;
00555     
00556     // find out the fibers
00557     int f[2],fc;
00558     htr.getHistogramFibers(f[0],f[1]);
00559 
00560     for (int nf=0; nf<2; nf++) {
00561       if (f[nf]<0 || (nf==1 && f[0]==f[1])) continue; // skip if invalid or the same
00562       for (fc=0; fc<=2; fc++) {
00563         HcalElectronicsId eid(fc,f[nf],spigot,dccid);     
00564         eid.setHTR(htr_cr,htr_slot,htr_tb);
00565         DetId did=emap.lookup(eid);
00566 
00567         if (did.null() || did.det()!=DetId::Hcal || did.subdetId()==0) {
00568           if (unknownIds_.find(eid)==unknownIds_.end()) {
00569             edm::LogWarning("HCAL") << "HcalHistogramUnpacker: No match found for electronics id :" << eid;
00570             unknownIds_.insert(eid);
00571           }       
00572           continue;
00573         }
00574         histoDigis.push_back(HcalHistogramDigi(HcalDetId(did))); // add it!
00575         HcalHistogramDigi& digi=histoDigis.back();
00576         
00577         // unpack the four capids
00578         for (int capid=0; capid<4; capid++) 
00579           htr.unpackHistogram(f[nf],fc,capid,digi.getArray(capid));
00580         
00581       }
00582     }
00583   }
00584 }      
00585