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