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
00013 digi.setPresamples(presamples);
00014 digi.setReadoutIds(eid);
00015 int fiber=startPoint->fiber();
00016 int fiberchan=startPoint->fiberChan();
00017 uint32_t zsmask=hhd.zsBunchMask()>>startSample;
00018 digi.setZSInfo(hhd.isUnsuppressed(),hhd.wasMarkAndPassZS(fiber,fiberchan),zsmask);
00019
00020 if (expectedTime>=0 && !hhd.isUnsuppressed()) {
00021
00022 digi.setFiberIdleOffset(hhd.getFibOrbMsgBCN(fiber)-expectedTime);
00023 }
00024
00025
00026 int myFiberChan=startPoint->fiberAndChan();
00027 int ncurr=0,ntaken=0;
00028 const HcalQIESample* qie_work=startPoint;
00029 while (qie_work!=limit && qie_work->fiberAndChan()==myFiberChan) {
00030 if (ncurr>=startSample && ncurr<=endSample) {
00031 digi.setSample(ntaken,*qie_work);
00032 ++ntaken;
00033 }
00034 ncurr++;
00035 qie_work++;
00036 }
00037 digi.setSize(ntaken);
00038 return qie_work;
00039 }
00040 }
00041
00042 static inline bool isTPGSOI(const HcalTriggerPrimitiveSample& s) {
00043 return (s.raw()&0x200)!=0;
00044 }
00045
00046
00047 struct HOUnrolledTP {
00048 bool valid, checked;
00049 int ieta, iphi, samples, soi;
00050 unsigned int databits;
00051 HOUnrolledTP() {
00052 valid=false;
00053 checked=false;
00054 ieta=0;
00055 iphi=0;
00056 samples=0;
00057 soi=0;
00058 databits=0;
00059 }
00060 void setbit(int i) { databits|=(1<<i); }
00061 };
00062
00063 void HcalUnpacker::unpack(const FEDRawData& raw, const HcalElectronicsMap& emap,
00064 Collections& colls, HcalUnpackerReport& report, bool silent) {
00065
00066 if (raw.size()<16) {
00067 if (!silent) edm::LogWarning("Invalid Data") << "Empty/invalid DCC data, size = " << raw.size();
00068 return;
00069 }
00070
00071
00072 const HcalDCCHeader* dccHeader=(const HcalDCCHeader*)(raw.data());
00073 int dccid=dccHeader->getSourceId()-sourceIdOffset_;
00074
00075
00076
00077
00078 HcalHTRData htr;
00079 const unsigned short* daq_first, *daq_last, *tp_first, *tp_last;
00080 const HcalQIESample* qie_begin, *qie_end, *qie_work;
00081 const HcalTriggerPrimitiveSample *tp_begin, *tp_end, *tp_work;
00082 for (int spigot=0; spigot<HcalDCCHeader::SPIGOT_COUNT; spigot++) {
00083 if (!dccHeader->getSpigotPresent(spigot)) continue;
00084
00085 int retval=dccHeader->getSpigotData(spigot,htr,raw.size());
00086 if (retval!=0) {
00087 if (retval==-1) {
00088 if (!silent) edm::LogWarning("Invalid Data") << "Invalid HTR data (data beyond payload size) observed on spigot " << spigot << " of DCC with source id " << dccHeader->getSourceId();
00089 report.countSpigotFormatError();
00090 }
00091 continue;
00092 }
00093
00094 if (dccHeader->getSpigotCRCError(spigot)) {
00095 if (!silent)
00096 edm::LogWarning("Invalid Data") << "CRC Error on HTR data observed on spigot " << spigot << " of DCC with source id " << dccHeader->getSourceId();
00097 report.countSpigotFormatError();
00098 continue;
00099 }
00100 if (!htr.check()) {
00101 if (!silent)
00102 edm::LogWarning("Invalid Data") << "Invalid HTR data observed on spigot " << spigot << " of DCC with source id " << dccHeader->getSourceId();
00103 report.countSpigotFormatError();
00104 continue;
00105 }
00106 if (htr.isHistogramEvent()) {
00107 if (!silent) edm::LogWarning("Invalid Data") << "Histogram data passed to non-histogram unpacker on spigot " << spigot << " of DCC with source id " << dccHeader->getSourceId();
00108 continue;
00109 }
00110 if ((htr.getFirmwareFlavor()&0xE0)==0x80) {
00111 if (colls.ttp!=0) {
00112 HcalTTPUnpacker ttpUnpack;
00113 colls.ttp->push_back(HcalTTPDigi());
00114 ttpUnpack.unpack(htr,colls.ttp->back());
00115 } else {
00116 LogDebug("HcalTechTrigProcessor") << "Skipping data on spigot " << spigot << " of DCC with source id " << dccHeader->getSourceId() << " which is from the TechTrigProcessor (use separate unpacker!)";
00117 }
00118 continue;
00119 }
00120 if (htr.getFirmwareFlavor()>=0x80) {
00121 if (!silent) edm::LogWarning("HcalUnpacker") << "Skipping data on spigot " << spigot << " of DCC with source id " << dccHeader->getSourceId() << " which is of unknown flavor " << htr.getFirmwareFlavor();
00122 continue;
00123 }
00124
00125
00126 int nps=htr.getNPS()-startSample_;
00127
00128
00129 htr.dataPointers(&daq_first,&daq_last,&tp_first,&tp_last);
00130 unsigned int smid=htr.getSubmodule();
00131 int htr_tb=smid&0x1;
00132 int htr_slot=(smid>>1)&0x1F;
00133 int htr_cr=(smid>>6)&0x1F;
00134
00135 tp_begin=(HcalTriggerPrimitiveSample*)tp_first;
00136 tp_end=(HcalTriggerPrimitiveSample*)(tp_last+1);
00137
00139 int currFiberChan=0x3F;
00140 int ncurr=0;
00141 bool valid=false;
00142
00143 bool tpgSOIbitInUse=htr.getFormatVersion()>=3;
00144 bool isHOtpg=htr.getFormatVersion()>=3 && htr.getFirmwareFlavor()==0;
00145 int npre=0;
00146
00147
00148
00149 if (isHOtpg) {
00150 HOUnrolledTP unrolled[24];
00151 for (tp_work=tp_begin; tp_work!=tp_end; tp_work++) {
00152 if (tp_work->raw()==0xFFFF) continue;
00153 int sector=tp_work->slbChan();
00154 if (sector>2) continue;
00155
00156 for (int ibit=0; ibit<8; ibit++) {
00157 int linear=sector*8+ibit;
00158 if (!unrolled[linear].checked) {
00159 unrolled[linear].checked=true;
00160 int fiber=(linear/3)+1;
00161 int fc=(linear%3);
00162
00163 HcalElectronicsId eid(fc,fiber,spigot,dccid);
00164 eid.setHTR(htr_cr,htr_slot,htr_tb);
00165 DetId did=emap.lookup(eid);
00166 if (!did.null()) {
00167 if (did.det()==DetId::Hcal && ((HcalSubdetector)did.subdetId())==HcalOuter ) {
00168 HcalDetId hid(did);
00169 unrolled[linear].valid=true;
00170 unrolled[linear].ieta=hid.ieta();
00171 unrolled[linear].iphi=hid.iphi();
00172 }
00173 } else {
00174 report.countUnmappedTPDigi(eid);
00175 }
00176 }
00177 if (unrolled[linear].valid) {
00178 if (isTPGSOI(*tp_work)) unrolled[linear].soi=unrolled[linear].samples;
00179 if (tp_work->raw()&(1<<ibit)) unrolled[linear].setbit(unrolled[linear].samples);
00180 unrolled[linear].samples++;
00181 }
00182 }
00183 }
00184 for (int i=0; i<24; i++) {
00185 if (unrolled[i].valid)
00186 colls.tphoCont->push_back(HOTriggerPrimitiveDigi(
00187 unrolled[i].ieta,
00188 unrolled[i].iphi,
00189 unrolled[i].samples,
00190 unrolled[i].soi,
00191 unrolled[i].databits));
00192 }
00193 } else {
00194 for (tp_work=tp_begin; tp_work!=tp_end; tp_work++) {
00195 if (tp_work->raw()==0xFFFF) continue;
00196 if (tp_work->slbAndChan()!=currFiberChan) {
00197 npre=0;
00198 currFiberChan=tp_work->slbAndChan();
00199
00200 HcalElectronicsId eid(tp_work->slbChan(),tp_work->slb(),spigot,dccid,htr_cr,htr_slot,htr_tb);
00201 DetId did=emap.lookupTrigger(eid);
00202 if (did.null()) {
00203 report.countUnmappedTPDigi(eid);
00204 if (unknownIdsTrig_.find(eid)==unknownIdsTrig_.end()) {
00205 if (!silent) edm::LogWarning("HCAL") << "HcalUnpacker: No trigger primitive match found for electronics id :" << eid;
00206 unknownIdsTrig_.insert(eid);
00207 }
00208 valid=false;
00209 continue;
00210 } else if (did==HcalTrigTowerDetId::Undefined ||
00211 (did.det()==DetId::Hcal && did.subdetId()==0)) {
00212
00213 valid=false;
00214 continue;
00215 }
00216 HcalTrigTowerDetId id(did);
00217 colls.tpCont->push_back(HcalTriggerPrimitiveDigi(id));
00218
00219 if (!tpgSOIbitInUse) colls.tpCont->back().setPresamples(nps);
00220 colls.tpCont->back().setZSInfo(htr.isUnsuppressed(),htr.wasMarkAndPassZSTP(tp_work->slb(),tp_work->slbChan()));
00221
00222
00223 ncurr=0;
00224 valid=true;
00225 }
00226
00227 if (valid && ((tpgSOIbitInUse && ncurr<10) || (ncurr>=startSample_ && ncurr<=endSample_))) {
00228 colls.tpCont->back().setSample(colls.tpCont->back().size(),*tp_work);
00229 colls.tpCont->back().setSize(colls.tpCont->back().size()+1);
00230 }
00231
00232 if (valid && tpgSOIbitInUse && isTPGSOI(*tp_work)) {
00233 colls.tpCont->back().setPresamples(ncurr);
00234 }
00235 ncurr++;
00236 npre++;
00237 }
00238 }
00239
00240
00241 qie_begin=(HcalQIESample*)daq_first;
00242 qie_end=(HcalQIESample*)(daq_last+1);
00243
00245 currFiberChan=0x3F;
00246 ncurr=0;
00247 valid=false;
00248
00249
00250 for (qie_work=qie_begin; qie_work!=qie_end; ) {
00251 if (qie_work->raw()==0xFFFF) {
00252 qie_work++;
00253 continue;
00254 }
00255
00256 currFiberChan=qie_work->fiberAndChan();
00257
00258
00259 HcalElectronicsId eid(qie_work->fiberChan(),qie_work->fiber(),spigot,dccid);
00260 eid.setHTR(htr_cr,htr_slot,htr_tb);
00261 DetId did=emap.lookup(eid);
00262
00263 if (!did.null()) {
00264 if (did.det()==DetId::Calo && did.subdetId()==HcalZDCDetId::SubdetectorId) {
00265 colls.zdcCont->push_back(ZDCDataFrame(HcalZDCDetId(did)));
00266 qie_work=HcalUnpacker_impl::unpack<ZDCDataFrame>(qie_work, qie_end, colls.zdcCont->back(), nps, eid, startSample_, endSample_, expectedOrbitMessageTime_, htr);
00267 } else if (did.det()==DetId::Hcal) {
00268 switch (((HcalSubdetector)did.subdetId())) {
00269 case (HcalBarrel):
00270 case (HcalEndcap): {
00271 colls.hbheCont->push_back(HBHEDataFrame(HcalDetId(did)));
00272 qie_work=HcalUnpacker_impl::unpack<HBHEDataFrame>(qie_work, qie_end, colls.hbheCont->back(), nps, eid, startSample_, endSample_, expectedOrbitMessageTime_, htr);
00273 } break;
00274 case (HcalOuter): {
00275 colls.hoCont->push_back(HODataFrame(HcalDetId(did)));
00276 qie_work=HcalUnpacker_impl::unpack<HODataFrame>(qie_work, qie_end, colls.hoCont->back(), nps, eid, startSample_, endSample_, expectedOrbitMessageTime_, htr);
00277 } break;
00278 case (HcalForward): {
00279 colls.hfCont->push_back(HFDataFrame(HcalDetId(did)));
00280 qie_work=HcalUnpacker_impl::unpack<HFDataFrame>(qie_work, qie_end, colls.hfCont->back(), nps, eid, startSample_, endSample_, expectedOrbitMessageTime_, htr);
00281 } break;
00282 case (HcalOther) : {
00283 HcalOtherDetId odid(did);
00284 if (odid.subdet()==HcalCalibration) {
00285 colls.calibCont->push_back(HcalCalibDataFrame(HcalCalibDetId(did)));
00286 qie_work=HcalUnpacker_impl::unpack<HcalCalibDataFrame>(qie_work, qie_end, colls.calibCont->back(), nps, eid, startSample_, endSample_, expectedOrbitMessageTime_, htr);
00287 }
00288 } break;
00289 case (HcalEmpty):
00290 default: {
00291 for (int fiberC=qie_work->fiberAndChan();
00292 qie_work!=qie_end && qie_work->fiberAndChan()==fiberC;
00293 qie_work++);
00294 }
00295 break;
00296 }
00297 }
00298 } else {
00299 report.countUnmappedDigi(eid);
00300 if (unknownIds_.find(eid)==unknownIds_.end()) {
00301 if (!silent) edm::LogWarning("HCAL") << "HcalUnpacker: No match found for electronics id :" << eid;
00302 unknownIds_.insert(eid);
00303 }
00304 for (int fiberC=qie_work->fiberAndChan();
00305 qie_work!=qie_end && qie_work->fiberAndChan()==fiberC;
00306 qie_work++);
00307 }
00308 }
00309 }
00310 }
00311
00312 HcalUnpacker::Collections::Collections() {
00313 hbheCont=0;
00314 hoCont=0;
00315 hfCont=0;
00316 tpCont=0;
00317 zdcCont=0;
00318 calibCont=0;
00319 ttp=0;
00320 }
00321
00322 void HcalUnpacker::unpack(const FEDRawData& raw, const HcalElectronicsMap& emap, std::vector<HBHEDataFrame>& container, std::vector<HcalTriggerPrimitiveDigi>& tp) {
00323 Collections c;
00324 c.hbheCont=&container;
00325 c.tpCont=&tp;
00326 HcalUnpackerReport r;
00327 unpack(raw,emap,c,r);
00328 }
00329
00330 void HcalUnpacker::unpack(const FEDRawData& raw, const HcalElectronicsMap& emap, std::vector<HODataFrame>& container, std::vector<HcalTriggerPrimitiveDigi>& tp) {
00331 Collections c;
00332 c.hoCont=&container;
00333 c.tpCont=&tp;
00334 HcalUnpackerReport r;
00335 unpack(raw,emap,c,r);
00336 }
00337
00338 void HcalUnpacker::unpack(const FEDRawData& raw, const HcalElectronicsMap& emap, std::vector<HFDataFrame>& container, std::vector<HcalTriggerPrimitiveDigi>& tp) {
00339 Collections c;
00340 c.hfCont=&container;
00341 c.tpCont=&tp;
00342 HcalUnpackerReport r;
00343 unpack(raw,emap,c,r);
00344 }
00345
00346 void HcalUnpacker::unpack(const FEDRawData& raw, const HcalElectronicsMap& emap, std::vector<HcalHistogramDigi>& histoDigis) {
00347
00348
00349 const HcalDCCHeader* dccHeader=(const HcalDCCHeader*)(raw.data());
00350 int dccid=dccHeader->getSourceId()-sourceIdOffset_;
00351
00352
00353
00354
00355 HcalHTRData htr;
00356 for (int spigot=0; spigot<HcalDCCHeader::SPIGOT_COUNT; spigot++) {
00357 if (!dccHeader->getSpigotPresent(spigot)) continue;
00358
00359 int retval=dccHeader->getSpigotData(spigot,htr,raw.size());
00360
00361 if (retval || !htr.check()) {
00362 edm::LogWarning("Invalid Data") << "Invalid HTR data observed on spigot " << spigot << " of DCC with source id " << dccHeader->getSourceId();
00363 continue;
00364 }
00365 if (!htr.isHistogramEvent()) {
00366 edm::LogWarning("Invalid Data") << "Non-histogram data passed to histogram unpacker on spigot " << spigot << " of DCC with source id " << dccHeader->getSourceId();
00367 continue;
00368 }
00369
00370 unsigned int smid=htr.getSubmodule();
00371 int htr_tb=smid&0x1;
00372 int htr_slot=(smid>>1)&0x1F;
00373 int htr_cr=(smid>>6)&0x1F;
00374
00375
00376 int f[2],fc;
00377 htr.getHistogramFibers(f[0],f[1]);
00378
00379 for (int nf=0; nf<2; nf++) {
00380 if (f[nf]<0 || (nf==1 && f[0]==f[1])) continue;
00381 for (fc=0; fc<=2; fc++) {
00382 HcalElectronicsId eid(fc,f[nf],spigot,dccid);
00383 eid.setHTR(htr_cr,htr_slot,htr_tb);
00384 DetId did=emap.lookup(eid);
00385
00386 if (did.null() || did.det()!=DetId::Hcal || did.subdetId()==0) {
00387 if (unknownIds_.find(eid)==unknownIds_.end()) {
00388 edm::LogWarning("HCAL") << "HcalHistogramUnpacker: No match found for electronics id :" << eid;
00389 unknownIds_.insert(eid);
00390 }
00391 continue;
00392 }
00393 histoDigis.push_back(HcalHistogramDigi(HcalDetId(did)));
00394 HcalHistogramDigi& digi=histoDigis.back();
00395
00396
00397 for (int capid=0; capid<4; capid++)
00398 htr.unpackHistogram(f[nf],fc,capid,digi.getArray(capid));
00399
00400 }
00401 }
00402 }
00403 }
00404