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
00012 digi.setPresamples(presamples);
00013 digi.setReadoutIds(eid);
00014
00015
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 {
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
00062 const HcalDCCHeader* dccHeader=(const HcalDCCHeader*)(raw.data());
00063 int dccid=dccHeader->getSourceId()-sourceIdOffset_;
00064
00065
00066
00067
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
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
00110 int nps=htr.getNPS()-startSample_;
00111
00112
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);
00121
00123 int currFiberChan=0x3F;
00124 int ncurr=0;
00125 bool valid=false;
00126
00127 bool tpgSOIbitInUse=htr.getFormatVersion()>=3;
00128 bool isHOtpg=htr.getFormatVersion()>=3 && htr.getFirmwareFlavor()==0;
00129 int npre=0;
00130
00131
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;
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
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;
00180 if (tp_work->slbAndChan()!=currFiberChan) {
00181 npre=0;
00182 currFiberChan=tp_work->slbAndChan();
00183
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
00197 valid=false;
00198 continue;
00199 }
00200 HcalTrigTowerDetId id(did);
00201 colls.tpCont->push_back(HcalTriggerPrimitiveDigi(id));
00202
00203 if (!tpgSOIbitInUse) colls.tpCont->back().setPresamples(nps);
00204
00205 ncurr=0;
00206 valid=true;
00207 }
00208
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
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);
00225
00227 currFiberChan=0x3F;
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;
00235 }
00236
00237 currFiberChan=qie_work->fiberAndChan();
00238
00239
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
00329 const HcalDCCHeader* dccHeader=(const HcalDCCHeader*)(raw.data());
00330 int dccid=dccHeader->getSourceId()-sourceIdOffset_;
00331
00332
00333
00334
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
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
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;
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)));
00374 HcalHistogramDigi& digi=histoDigis.back();
00375
00376
00377 for (int capid=0; capid<4; capid++)
00378 htr.unpackHistogram(f[nf],fc,capid,digi.getArray(capid));
00379
00380 }
00381 }
00382 }
00383 }
00384