CMS 3D CMS Logo

/afs/cern.ch/work/a/aaltunda/public/www/CMSSW_5_3_13_patch3/src/EventFilter/CastorRawToDigi/src/CastorUnpacker.cc

Go to the documentation of this file.
00001 #include "EventFilter/CastorRawToDigi/interface/CastorUnpacker.h"
00002 #include "EventFilter/HcalRawToDigi/interface/HcalDCCHeader.h"
00003 #include "EventFilter/HcalRawToDigi/interface/HcalHTRData.h"
00004 #include "EventFilter/HcalRawToDigi/interface/HcalTTPUnpacker.h"
00005 #include "DataFormats/HcalDetId/interface/HcalOtherDetId.h"
00006 #include "DataFormats/HcalDigi/interface/HcalQIESample.h"
00007 #include "DataFormats/HcalDigi/interface/CastorDataFrame.h"
00008 #include "DataFormats/HcalDigi/interface/HcalTriggerPrimitiveSample.h"
00009 #include <iostream>
00010 #include "FWCore/MessageLogger/interface/MessageLogger.h"
00011 
00012 namespace CastorUnpacker_impl {
00013   template <class DigiClass>
00014   const HcalQIESample* unpack(const HcalQIESample* startPoint, const HcalQIESample* limit, DigiClass& digi, int presamples, const CastorElectronicsId& eid, int startSample, int endSample, int expectedTime, const HcalHTRData& hhd) {
00015     // set parameters
00016     digi.setPresamples(presamples);
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  //   digi.setReadoutIds(eid);
00023  //   setReadoutIds is missing in  CastorDataFrame class  digi.setReadoutIds(eid);
00024     if (expectedTime>=0 && !hhd.isUnsuppressed()) {
00025            // std::cout << hhd.getFibOrbMsgBCN(fiber) << " " << expectedTime << " fiber="<<fiber<< std::endl;
00026       digi.setFiberIdleOffset(hhd.getFibOrbMsgBCN(fiber)-expectedTime);
00027     }
00028     // what is my sample number?
00029     int myFiberChan=startPoint->fiberAndChan();
00030     int ncurr=0,ntaken=0;
00031     const HcalQIESample* qie_work=startPoint;
00032     while (qie_work!=limit && qie_work->fiberAndChan()==myFiberChan) {
00033       if (ncurr>=startSample && ncurr<=endSample) {
00034         digi.setSample(ntaken,*qie_work);
00035         ++ntaken;
00036       }
00037       ncurr++;
00038       qie_work++;
00039     }
00040     digi.setSize(ntaken);
00041     return qie_work;
00042   }
00043 }
00044 
00045 namespace { inline bool isTPGSOI(const HcalTriggerPrimitiveSample& s) {
00046   return (s.raw()&0x200)!=0;
00047 }
00048 }
00049 
00050 
00051 CastorUnpacker::CastorUnpacker(int sourceIdOffset, int beg, int end) : sourceIdOffset_(sourceIdOffset) , expectedOrbitMessageTime_(-1)
00052 {
00053  if ( beg >= 0 && beg <= CastorDataFrame::MAXSAMPLES -1 ) {
00054         startSample_ = beg;
00055  } else {
00056         startSample_ = 0;
00057  }
00058  if ( end >= 0 && end <= CastorDataFrame::MAXSAMPLES -1 && end >= beg ) {
00059         endSample_ = end;
00060  } else {
00061         endSample_ = CastorDataFrame::MAXSAMPLES -1;
00062  }
00063 }
00064 
00065 
00066 void CastorUnpacker::unpack(const FEDRawData& raw, const CastorElectronicsMap& emap,
00067                           CastorRawCollections& colls, HcalUnpackerReport& report, bool silent) {
00068 
00069   if (raw.size()<16) {
00070     if (!silent) edm::LogWarning("Invalid Data") << "Empty/invalid DCC data, size = " << raw.size();
00071     return;
00072   }
00073 
00074   // get the DCC header
00075   const HcalDCCHeader* dccHeader=(const HcalDCCHeader*)(raw.data());
00076   int dccid=dccHeader->getSourceId()-sourceIdOffset_;
00077 
00078   // check the summary status
00079   
00080   // walk through the HTR data...
00081   HcalHTRData htr;
00082   const unsigned short* daq_first, *daq_last, *tp_first, *tp_last;
00083   const HcalQIESample* qie_begin, *qie_end, *qie_work;
00084   const HcalTriggerPrimitiveSample *tp_begin, *tp_end, *tp_work; 
00085   for (int spigot=0; spigot<HcalDCCHeader::SPIGOT_COUNT; spigot++) {
00086     if (!dccHeader->getSpigotPresent(spigot)) continue;
00087 
00088     int retval=dccHeader->getSpigotData(spigot,htr,raw.size());
00089     if (retval!=0) {
00090       if (retval==-1) {
00091         if (!silent) edm::LogWarning("Invalid Data") << "Invalid HTR data (data beyond payload size) observed on spigot " << spigot << " of DCC with source id " << dccHeader->getSourceId();
00092         report.countSpigotFormatError();
00093       }
00094       continue;
00095     }
00096     // check
00097     if (dccHeader->getSpigotCRCError(spigot)) {
00098       if (!silent) 
00099         edm::LogWarning("Invalid Data") << "CRC Error on HTR data observed on spigot " << spigot << " of DCC with source id " << dccHeader->getSourceId();
00100      report.countSpigotFormatError();
00101      continue;
00102     }  
00103     if (!htr.check()) {
00104                 if (!silent) 
00105       edm::LogWarning("Invalid Data") << "Invalid HTR data observed on spigot " << spigot << " of DCC with source id " << dccHeader->getSourceId();
00106       report.countSpigotFormatError();
00107       continue;
00108     }
00109     if (htr.isHistogramEvent()) {
00110                 if (!silent) 
00111       edm::LogWarning("Invalid Data") << "Histogram data passed to non-histogram unpacker on spigot " << spigot << " of DCC with source id " << dccHeader->getSourceId();
00112       continue;
00113 
00114     }
00115     if ((htr.getFirmwareFlavor()&0xE0)==0x80) { // some kind of TTP data
00116       if (colls.ttp!=0) {
00117         HcalTTPUnpacker ttpUnpack;
00118         colls.ttp->push_back(HcalTTPDigi());
00119         ttpUnpack.unpack(htr,colls.ttp->back());
00120       } else {
00121         LogDebug("CastorUnpackerHcalTechTrigProcessor") << "Skipping data on spigot " << spigot << " of DCC with source id " << dccHeader->getSourceId() << " which is from the TechTrigProcessor (use separate unpacker!)";
00122       }
00123       continue;
00124     }
00125     if (htr.getFirmwareFlavor()>=0x80) {
00126       if (!silent) edm::LogWarning("CastorUnpacker") << "Skipping data on spigot " << spigot << " of DCC with source id " << dccHeader->getSourceId() << " which is of unknown flavor " << htr.getFirmwareFlavor();
00127       continue;
00128     }
00129     // calculate "real" number of presamples
00130     int nps=htr.getNPS()-startSample_;
00131     
00132     // get pointers
00133     htr.dataPointers(&daq_first,&daq_last,&tp_first,&tp_last);
00134     unsigned int smid=htr.getSubmodule();
00135     int htr_tb=smid&0x1;
00136     int htr_slot=(smid>>1)&0x1F;
00137     int htr_cr=(smid>>6)&0x1F;
00138     
00139     tp_begin=(HcalTriggerPrimitiveSample*)tp_first;
00140     tp_end=(HcalTriggerPrimitiveSample*)(tp_last+1); // one beyond last..
00141        
00143     int currFiberChan=0x3F; // invalid fiber+channel...
00144     int ncurr=0;
00145     bool valid=false;
00147     bool tpgSOIbitInUse=htr.getFormatVersion()>=3; // version 3 and later
00148     // bool isHOtpg=htr.getFormatVersion()>=3 && htr.getFirmwareFlavor()==0; // HO is flavor zero
00149     int npre=0;
00150     /*
00151       Unpack the trigger primitives
00152     */
00153               // lookup the right channel
00154           bool dotp = true;
00155       CastorElectronicsId eid(0,1,spigot,dccid);
00156       eid.setHTR(htr_cr,htr_slot,htr_tb);
00157       DetId did=emap.lookup(eid);
00158           if ( did.null() ) dotp = false;
00159           HcalCastorDetId id1(did);
00160           HcalCastorDetId id((id1.zside()==0),id1.sector(),1);
00161                 if ( id1.module() > 12 ) dotp = false;
00162                 if ( dotp ) {
00163         // std::cout << " tp_first="<< tp_first << " tp_last="<< tp_last<< " tb="<<htr_tb<<" slot="<<htr_slot<<" crate="<<htr_cr<<" dccid="<< dccid<< std::endl;
00164  // regular TPs (not HO)
00165       for (tp_work=tp_begin; tp_work!=tp_end; tp_work++) {
00166         //        std::cout << "raw=0x"<<std::hex<< tp_work->raw()<<std::dec <<std::endl;
00167         if (tp_work->raw()==0xFFFF) continue; // filler word
00168         if (tp_work->slbAndChan()!=currFiberChan) { // start new set
00169           npre=0;
00170           currFiberChan=tp_work->slbAndChan();
00171           
00172                 // std::cout<< " NEW SET "<<std::endl;
00173           //HcalElectronicsId eid(tp_work->slbChan(),tp_work->slb(),spigot,dccid,htr_cr,htr_slot,htr_tb);
00174           //DetId did=emap.lookupTrigger(eid);
00175           //if (did.null()) {
00176             //report.countUnmappedTPDigi(eid);
00177             //if (unknownIdsTrig_.find(eid)==unknownIdsTrig_.end()) {
00178               //if (!silent) edm::LogWarning("HCAL") << "HcalUnpacker: No trigger primitive match found for electronics id :" << eid;
00179               //unknownIdsTrig_.insert(eid);
00180             //}
00181             //valid=false;
00182             //continue;
00183           //} else if (did==HcalTrigTowerDetId::Undefined || 
00184                      //(did.det()==DetId::Hcal && did.subdetId()==0)) {
00186             //valid=false;
00187             //continue;
00188           //}
00189 
00190           colls.tpCont->push_back(CastorTriggerPrimitiveDigi(id));
00191           // set the various bits
00192           if (!tpgSOIbitInUse) colls.tpCont->back().setPresamples(nps);
00193           colls.tpCont->back().setZSInfo(htr.isUnsuppressed(),htr.wasMarkAndPassZSTP(tp_work->slb(),tp_work->slbChan()));
00194 
00195           // no hits recorded for current
00196           ncurr=0;
00197           valid=true;
00198         }      
00199         // add the word (if within settings or recent firmware [recent firmware ignores startSample/endSample])
00200         if (valid && ((tpgSOIbitInUse && ncurr<10) || (ncurr>=startSample_ && ncurr<=endSample_))) {
00201           colls.tpCont->back().setSample(colls.tpCont->back().size(),*tp_work);
00202           colls.tpCont->back().setSize(colls.tpCont->back().size()+1);
00203         }
00204         // set presamples,if SOI
00205         if (valid && tpgSOIbitInUse && isTPGSOI(*tp_work)) {
00206           colls.tpCont->back().setPresamples(ncurr);
00207         }
00208         ncurr++;
00209         npre++;
00210       }
00211      }
00212 
00214     qie_begin=(HcalQIESample*)daq_first;
00215     qie_end=(HcalQIESample*)(daq_last+1); // one beyond last..
00216 
00218     currFiberChan=0x3F; // invalid fiber+channel...
00219     ncurr=0;
00220     valid=false;
00221     
00222     for (qie_work=qie_begin; qie_work!=qie_end; ) {
00223       if (qie_work->raw()==0xFFFF) {
00224         qie_work++;
00225         continue; // filler word
00226       }
00227       // always at the beginning ...
00228       currFiberChan=qie_work->fiberAndChan();
00229 
00230       // lookup the right channel
00231       CastorElectronicsId eid(qie_work->fiberChan(),qie_work->fiber(),spigot,dccid);
00232       eid.setHTR(htr_cr,htr_slot,htr_tb);
00233       DetId did=emap.lookup(eid);
00234 
00235       if (!did.null()) {
00236             colls.castorCont->push_back(CastorDataFrame(HcalCastorDetId(did)));
00237             qie_work=CastorUnpacker_impl::unpack<CastorDataFrame>(qie_work, qie_end, colls.castorCont->back(), nps, eid, startSample_, endSample_, expectedOrbitMessageTime_, htr);
00238       } else {
00239         report.countUnmappedDigi();
00240         if (unknownIds_.find(eid)==unknownIds_.end()) {
00241                 if (!silent) 
00242           edm::LogWarning("CASTOR") << "CastorUnpacker: No match found for electronics id :" << eid;
00243           unknownIds_.insert(eid);
00244         }
00245         for (int fiberC=qie_work->fiberAndChan();
00246              qie_work!=qie_end && qie_work->fiberAndChan()==fiberC;
00247              qie_work++);
00248       }
00249     }
00250   }
00251 }
00252