CMS 3D CMS Logo

/data/refman/pasoursint/CMSSW_5_3_1/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     if (!htr.check()) {
00152       if (!silent) 
00153         edm::LogWarning("Invalid Data") << "Invalid HTR data observed on spigot " << spigot << " of DCC with source id " << dccHeader->getSourceId();
00154       report.countSpigotFormatError();
00155       continue;
00156     }  
00157     if (htr.isHistogramEvent()) {
00158       if (!silent) edm::LogWarning("Invalid Data") << "Histogram data passed to non-histogram unpacker on spigot " << spigot << " of DCC with source id " << dccHeader->getSourceId();
00159       continue;
00160     }
00161     if ((htr.getFirmwareFlavor()&0xE0)==0x80) { // some kind of TTP data
00162       if (colls.ttp!=0) {
00163         HcalTTPUnpacker ttpUnpack;
00164         colls.ttp->push_back(HcalTTPDigi());
00165         ttpUnpack.unpack(htr,colls.ttp->back());
00166       } else {
00167         LogDebug("HcalTechTrigProcessor") << "Skipping data on spigot " << spigot << " of DCC with source id " << dccHeader->getSourceId() << " which is from the TechTrigProcessor (use separate unpacker!)";
00168       }
00169       continue;
00170     }
00171     if (htr.getFirmwareFlavor()>=0x80) {
00172       if (!silent) edm::LogWarning("HcalUnpacker") << "Skipping data on spigot " << spigot << " of DCC with source id " << dccHeader->getSourceId() << " which is of unknown flavor " << htr.getFirmwareFlavor();
00173       continue;
00174     }
00175 
00176     // calculate "real" number of presamples
00177     int nps=htr.getNPS()-startSample_;
00178     
00179     // get pointers
00180     htr.dataPointers(&daq_first,&daq_last,&tp_first,&tp_last);
00181     unsigned int smid=htr.getSubmodule();
00182     int htr_tb=smid&0x1;
00183     int htr_slot=(smid>>1)&0x1F;
00184     int htr_cr=(smid>>6)&0x1F;
00185     
00186     tp_begin=(HcalTriggerPrimitiveSample*)tp_first;
00187     tp_end=(HcalTriggerPrimitiveSample*)(tp_last+1); // one beyond last..
00188     
00190     int currFiberChan=0x3F; // invalid fiber+channel...
00191     int ncurr=0;
00192     bool valid=false;
00193 
00194     bool tpgSOIbitInUse=htr.getFormatVersion()>=3; // version 3 and later
00195     bool isHOtpg=htr.getFormatVersion()>=3 && htr.getFirmwareFlavor()==0; // HO is flavor zero
00196     int npre=0;
00197     /*
00198       Unpack the trigger primitives
00199     */
00200     if (isHOtpg) {
00201       HOUnrolledTP unrolled[24];
00202       for (tp_work=tp_begin; tp_work!=tp_end; tp_work++) {
00203         if (tp_work->raw()==0xFFFF) continue; // filler word
00204         int sector=tp_work->slbChan();
00205         if (sector>2) continue;
00206 
00207         for (int ibit=0; ibit<8; ibit++) {
00208           int linear=sector*8+ibit; 
00209           if (!unrolled[linear].checked) {
00210             unrolled[linear].checked=true;
00211             int fiber=(linear/3)+1;
00212             int fc=(linear%3);
00213             // electronics id (use precision match for HO TP)
00214             HcalElectronicsId eid(fc,fiber,spigot,dccid);       
00215             eid.setHTR(htr_cr,htr_slot,htr_tb);
00216             DetId did=emap.lookup(eid);
00217             if (!did.null()) {
00218               if (did.det()==DetId::Hcal && ((HcalSubdetector)did.subdetId())==HcalOuter ) {
00219                 HcalDetId hid(did);
00220                 unrolled[linear].valid=true;
00221                 unrolled[linear].ieta=hid.ieta();
00222                 unrolled[linear].iphi=hid.iphi();
00223               }
00224             } else {
00225               report.countUnmappedTPDigi(eid);
00226             }
00227           }
00228           if (unrolled[linear].valid) {
00229             if (isTPGSOI(*tp_work)) unrolled[linear].soi=unrolled[linear].samples;
00230             if (tp_work->raw()&(1<<ibit)) unrolled[linear].setbit(unrolled[linear].samples);
00231             unrolled[linear].samples++;
00232           }
00233         }
00234       }
00235       for (int i=0; i<24; i++) {
00236         if (unrolled[i].valid) 
00237           colls.tphoCont->push_back(HOTriggerPrimitiveDigi(
00238                                                            unrolled[i].ieta,
00239                                                            unrolled[i].iphi,
00240                                                            unrolled[i].samples,
00241                                                            unrolled[i].soi,
00242                                                            unrolled[i].databits));
00243       }
00244     } else { // regular TPs (not HO)
00245       for (tp_work=tp_begin; tp_work!=tp_end; tp_work++) {
00246         if (tp_work->raw()==0xFFFF) continue; // filler word
00247         if (tp_work->slbAndChan()!=currFiberChan) { // start new set
00248           npre=0;
00249           currFiberChan=tp_work->slbAndChan();
00250           // lookup the right channel
00251           HcalElectronicsId eid(tp_work->slbChan(),tp_work->slb(),spigot,dccid,htr_cr,htr_slot,htr_tb);
00252           DetId did=emap.lookupTrigger(eid);
00253           if (did.null()) {
00254             report.countUnmappedTPDigi(eid);
00255             if (unknownIdsTrig_.find(eid)==unknownIdsTrig_.end()) {
00256               if (!silent) edm::LogWarning("HCAL") << "HcalUnpacker: No trigger primitive match found for electronics id :" << eid;
00257               unknownIdsTrig_.insert(eid);
00258             }
00259             valid=false;
00260             continue;
00261           } else if (did==HcalTrigTowerDetId::Undefined || 
00262                      (did.det()==DetId::Hcal && did.subdetId()==0)) {
00263             // known to be unmapped
00264             valid=false;
00265             continue;
00266           }
00267           HcalTrigTowerDetId id(did);
00268           colls.tpCont->push_back(HcalTriggerPrimitiveDigi(id));
00269           // set the various bits
00270           if (!tpgSOIbitInUse) colls.tpCont->back().setPresamples(nps);
00271           colls.tpCont->back().setZSInfo(htr.isUnsuppressed(),htr.wasMarkAndPassZSTP(tp_work->slb(),tp_work->slbChan()));
00272 
00273           // no hits recorded for current
00274           ncurr=0;
00275           valid=true;
00276         }      
00277         // add the word (if within settings or recent firmware [recent firmware ignores startSample/endSample])
00278         if (valid && ((tpgSOIbitInUse && ncurr<10) || (ncurr>=startSample_ && ncurr<=endSample_))) {
00279           colls.tpCont->back().setSample(colls.tpCont->back().size(),*tp_work);
00280           colls.tpCont->back().setSize(colls.tpCont->back().size()+1);
00281         }
00282         // set presamples,if SOI
00283         if (valid && tpgSOIbitInUse && isTPGSOI(*tp_work)) {
00284           colls.tpCont->back().setPresamples(ncurr);
00285         }
00286         ncurr++;
00287         npre++;
00288       }
00289     }
00290 
00292     if (htr.getFormatVersion() < HcalHTRData::FORMAT_VERSION_COMPACT_DATA) {
00293  
00294       qie_begin=(HcalQIESample*)daq_first;
00295       qie_end=(HcalQIESample*)(daq_last+1); // one beyond last..
00296 
00298       currFiberChan=0x3F; // invalid fiber+channel...
00299       ncurr=0;
00300       valid=false;
00301 
00302     
00303       for (qie_work=qie_begin; qie_work!=qie_end; ) {
00304         if (qie_work->raw()==0xFFFF) {
00305           qie_work++;
00306           continue; // filler word
00307         }
00308         // always at the beginning ...
00309         currFiberChan=qie_work->fiberAndChan();
00310         
00311         // lookup the right channel
00312         HcalElectronicsId eid(qie_work->fiberChan(),qie_work->fiber(),spigot,dccid);
00313         eid.setHTR(htr_cr,htr_slot,htr_tb);
00314         DetId did=emap.lookup(eid);
00315         
00316         if (!did.null()) {
00317           if (did.det()==DetId::Calo && did.subdetId()==HcalZDCDetId::SubdetectorId) {
00318             colls.zdcCont->push_back(ZDCDataFrame(HcalZDCDetId(did)));
00319             qie_work=HcalUnpacker_impl::unpack<ZDCDataFrame>(qie_work, qie_end, colls.zdcCont->back(), nps, eid, startSample_, endSample_, expectedOrbitMessageTime_, htr); 
00320           } else if (did.det()==DetId::Hcal) {
00321             switch (((HcalSubdetector)did.subdetId())) {
00322             case (HcalBarrel):
00323             case (HcalEndcap): {
00324               colls.hbheCont->push_back(HBHEDataFrame(HcalDetId(did)));
00325               qie_work=HcalUnpacker_impl::unpack<HBHEDataFrame>(qie_work, qie_end, colls.hbheCont->back(), nps, eid, startSample_, endSample_, expectedOrbitMessageTime_, htr);
00326             } break;
00327             case (HcalOuter): {
00328               colls.hoCont->push_back(HODataFrame(HcalDetId(did)));
00329               qie_work=HcalUnpacker_impl::unpack<HODataFrame>(qie_work, qie_end, colls.hoCont->back(), nps, eid, startSample_, endSample_, expectedOrbitMessageTime_, htr);
00330           } break;
00331             case (HcalForward): {
00332               colls.hfCont->push_back(HFDataFrame(HcalDetId(did)));
00333               qie_work=HcalUnpacker_impl::unpack<HFDataFrame>(qie_work, qie_end, colls.hfCont->back(), nps, eid, startSample_, endSample_, expectedOrbitMessageTime_, htr);
00334             } break;
00335             case (HcalOther) : {
00336               HcalOtherDetId odid(did);
00337               if (odid.subdet()==HcalCalibration) {
00338                 colls.calibCont->push_back(HcalCalibDataFrame(HcalCalibDetId(did)));
00339                 qie_work=HcalUnpacker_impl::unpack<HcalCalibDataFrame>(qie_work, qie_end, colls.calibCont->back(), nps, eid, startSample_, endSample_, expectedOrbitMessageTime_, htr); 
00340               }
00341             } break;
00342             case (HcalEmpty): 
00343             default: {
00344               for (int fiberC=qie_work->fiberAndChan();
00345                    qie_work!=qie_end && qie_work->fiberAndChan()==fiberC;
00346                    qie_work++);
00347             }
00348             break;
00349             }
00350           }
00351         } else {
00352           report.countUnmappedDigi(eid);
00353           if (unknownIds_.find(eid)==unknownIds_.end()) {
00354             if (!silent) edm::LogWarning("HCAL") << "HcalUnpacker: No match found for electronics id :" << eid;
00355             unknownIds_.insert(eid);
00356         }
00357           for (int fiberC=qie_work->fiberAndChan();
00358                qie_work!=qie_end && qie_work->fiberAndChan()==fiberC;
00359                qie_work++);
00360         }
00361       }
00362     } else {
00363       // this is the branch for unpacking the compact data format with per-channel headers
00364       const unsigned short* ptr_header=daq_first;
00365       const unsigned short* ptr_end=daq_last+1;
00366       int flavor, error_flags, capid0, channelid;
00367 
00368       while (ptr_header!=ptr_end) {
00369         if (*ptr_header==0xFFFF) { // impossible filler word
00370           ptr_header++;
00371           continue;
00372         }
00373         // unpack the header word
00374         bool isheader=HcalHTRData::unpack_per_channel_header(*ptr_header,flavor,error_flags,capid0,channelid);
00375         if (!isheader) {
00376           ptr_header++;
00377           continue;
00378         }
00379 
00380         int fiberchan=channelid&0x3;
00381         int fiber=((channelid>>2)&0x7)+1;
00382 
00383         // lookup the right channel
00384         HcalElectronicsId eid(fiberchan,fiber,spigot,dccid);
00385         eid.setHTR(htr_cr,htr_slot,htr_tb);
00386         DetId did=emap.lookup(eid);
00387         
00388         if (!did.null()) {
00389           if (did.det()==DetId::Calo && did.subdetId()==HcalZDCDetId::SubdetectorId) {
00390             colls.zdcCont->push_back(ZDCDataFrame(HcalZDCDetId(did)));
00391             ptr_header=HcalUnpacker_impl::unpack_compact<ZDCDataFrame>(ptr_header, ptr_end, colls.zdcCont->back(), nps, eid, startSample_, endSample_, expectedOrbitMessageTime_, htr); 
00392           } else if (did.det()==DetId::Hcal) {
00393             switch (((HcalSubdetector)did.subdetId())) {
00394             case (HcalBarrel):
00395             case (HcalEndcap): {
00396               colls.hbheCont->push_back(HBHEDataFrame(HcalDetId(did)));
00397               ptr_header=HcalUnpacker_impl::unpack_compact<HBHEDataFrame>(ptr_header, ptr_end, colls.hbheCont->back(), nps, eid, startSample_, endSample_, expectedOrbitMessageTime_, htr);
00398             } break;
00399             case (HcalOuter): {
00400               colls.hoCont->push_back(HODataFrame(HcalDetId(did)));
00401               ptr_header=HcalUnpacker_impl::unpack_compact<HODataFrame>(ptr_header, ptr_end, colls.hoCont->back(), nps, eid, startSample_, endSample_, expectedOrbitMessageTime_, htr);
00402           } break;
00403             case (HcalForward): {
00404               colls.hfCont->push_back(HFDataFrame(HcalDetId(did)));
00405               ptr_header=HcalUnpacker_impl::unpack_compact<HFDataFrame>(ptr_header, ptr_end, colls.hfCont->back(), nps, eid, startSample_, endSample_, expectedOrbitMessageTime_, htr);
00406             } break;
00407             case (HcalOther) : {
00408               HcalOtherDetId odid(did);
00409               if (odid.subdet()==HcalCalibration) {
00410                 colls.calibCont->push_back(HcalCalibDataFrame(HcalCalibDetId(did)));
00411                 ptr_header=HcalUnpacker_impl::unpack_compact<HcalCalibDataFrame>(ptr_header, ptr_end, colls.calibCont->back(), nps, eid, startSample_, endSample_, expectedOrbitMessageTime_, htr); 
00412               }
00413             } break;
00414             case (HcalEmpty): 
00415             default: {
00416               for (ptr_header++;
00417                    ptr_header!=ptr_end && !HcalHTRData::is_channel_header(*ptr_header);
00418                    ptr_header++);
00419             }
00420             break;
00421             }
00422           }
00423         } else {
00424           report.countUnmappedDigi(eid);
00425           if (unknownIds_.find(eid)==unknownIds_.end()) {
00426             if (!silent) edm::LogWarning("HCAL") << "HcalUnpacker: No match found for electronics id :" << eid;
00427             unknownIds_.insert(eid);
00428           }
00429           for (ptr_header++;
00430                ptr_header!=ptr_end && !HcalHTRData::is_channel_header(*ptr_header);
00431                ptr_header++);
00432         }
00433       }
00434 
00435     }
00436   }
00437 }
00438 
00439 HcalUnpacker::Collections::Collections() {
00440   hbheCont=0;
00441   hoCont=0;
00442   hfCont=0;
00443   tpCont=0;
00444   zdcCont=0;
00445   calibCont=0;
00446   ttp=0;
00447 }
00448 
00449 void HcalUnpacker::unpack(const FEDRawData& raw, const HcalElectronicsMap& emap, std::vector<HBHEDataFrame>& container, std::vector<HcalTriggerPrimitiveDigi>& tp) {
00450   Collections c;
00451   c.hbheCont=&container;
00452   c.tpCont=&tp;
00453   HcalUnpackerReport r;
00454   unpack(raw,emap,c,r);
00455 }
00456 
00457 void HcalUnpacker::unpack(const FEDRawData& raw, const HcalElectronicsMap& emap, std::vector<HODataFrame>& container, std::vector<HcalTriggerPrimitiveDigi>& tp) {
00458   Collections c;
00459   c.hoCont=&container;
00460   c.tpCont=&tp;
00461   HcalUnpackerReport r;
00462   unpack(raw,emap,c,r);
00463 }
00464 
00465 void HcalUnpacker::unpack(const FEDRawData& raw, const HcalElectronicsMap& emap, std::vector<HFDataFrame>& container, std::vector<HcalTriggerPrimitiveDigi>& tp) {
00466   Collections c;
00467   c.hfCont=&container;
00468   c.tpCont=&tp;
00469   HcalUnpackerReport r;
00470   unpack(raw,emap,c,r);
00471 }
00472 
00473 void HcalUnpacker::unpack(const FEDRawData& raw, const HcalElectronicsMap& emap, std::vector<HcalHistogramDigi>& histoDigis) {
00474 
00475   // get the DCC header
00476   const HcalDCCHeader* dccHeader=(const HcalDCCHeader*)(raw.data());
00477   int dccid=dccHeader->getSourceId()-sourceIdOffset_;
00478   
00479   // check the summary status
00480   
00481   // walk through the HTR data...
00482   HcalHTRData htr;
00483   for (int spigot=0; spigot<HcalDCCHeader::SPIGOT_COUNT; spigot++) {
00484     if (!dccHeader->getSpigotPresent(spigot)) continue;
00485     
00486     int retval=dccHeader->getSpigotData(spigot,htr,raw.size());
00487     // check
00488     if (retval || !htr.check()) {
00489       edm::LogWarning("Invalid Data") << "Invalid HTR data observed on spigot " << spigot << " of DCC with source id " << dccHeader->getSourceId();
00490       continue;
00491     }
00492     if (!htr.isHistogramEvent()) {
00493       edm::LogWarning("Invalid Data") << "Non-histogram data passed to histogram unpacker on spigot " << spigot << " of DCC with source id " << dccHeader->getSourceId();
00494       continue;
00495     }
00496 
00497     unsigned int smid=htr.getSubmodule();
00498     int htr_tb=smid&0x1;
00499     int htr_slot=(smid>>1)&0x1F;
00500     int htr_cr=(smid>>6)&0x1F;
00501     
00502     // find out the fibers
00503     int f[2],fc;
00504     htr.getHistogramFibers(f[0],f[1]);
00505 
00506     for (int nf=0; nf<2; nf++) {
00507       if (f[nf]<0 || (nf==1 && f[0]==f[1])) continue; // skip if invalid or the same
00508       for (fc=0; fc<=2; fc++) {
00509         HcalElectronicsId eid(fc,f[nf],spigot,dccid);     
00510         eid.setHTR(htr_cr,htr_slot,htr_tb);
00511         DetId did=emap.lookup(eid);
00512 
00513         if (did.null() || did.det()!=DetId::Hcal || did.subdetId()==0) {
00514           if (unknownIds_.find(eid)==unknownIds_.end()) {
00515             edm::LogWarning("HCAL") << "HcalHistogramUnpacker: No match found for electronics id :" << eid;
00516             unknownIds_.insert(eid);
00517           }       
00518           continue;
00519         }
00520         histoDigis.push_back(HcalHistogramDigi(HcalDetId(did))); // add it!
00521         HcalHistogramDigi& digi=histoDigis.back();
00522         
00523         // unpack the four capids
00524         for (int capid=0; capid<4; capid++) 
00525           htr.unpackHistogram(f[nf],fc,capid,digi.getArray(capid));
00526         
00527       }
00528     }
00529   }
00530 }      
00531