CMS 3D CMS Logo

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