00001 #include "DataFormats/FEDRawData/interface/FEDRawData.h" 00002 #include "DataFormats/HcalDigi/interface/HcalLaserDigi.h" 00003 #include "RecoLocalCalo/HcalLaserReco/src/HcalLaserUnpacker.h" 00004 #include "FWCore/Utilities/interface/Exception.h" 00005 #include <ostream> 00006 00007 HcalLaserUnpacker::HcalLaserUnpacker(){} 00008 00009 struct CombinedTDCQDCDataFormat { 00010 unsigned int cdfHeader0,cdfHeader1,cdfHeader2,cdfHeader3; 00011 unsigned int n_qdc_hits; // Count of QDC channels 00012 unsigned int n_tdc_hits; // upper/lower TDC counts 00013 unsigned short qdc_values[4]; 00014 }; 00015 00016 void HcalLaserUnpacker::unpack(const FEDRawData& raw, 00017 HcalLaserDigi& digi) const { 00018 00019 if (raw.size()<3*8) { 00020 throw cms::Exception("Missing Data") << "No data in the block"; 00021 } 00022 00023 const CombinedTDCQDCDataFormat* qdctdc=(const CombinedTDCQDCDataFormat*)raw.data(); 00024 00025 // first, we do the QADC 00026 std::vector<uint16_t> qadcvals; 00027 for (unsigned int i=0;i<qdctdc->n_qdc_hits;i++) { 00028 qadcvals.push_back(qdctdc->qdc_values[i]&0xFFF); 00029 } 00030 digi.setQADC(qadcvals); 00031 00032 // next, we do the TDC 00033 const unsigned int* hitbase=(&(qdctdc->n_tdc_hits))+1; // base is one beyond 00034 unsigned int totalhits=0; 00035 00036 hitbase+=qdctdc->n_qdc_hits/2; // two unsigned short per unsigned long 00037 totalhits=qdctdc->n_tdc_hits&0xFFFF; // mask off high bits 00038 00039 for (unsigned int i=0; i<totalhits; i++) { 00040 int channel=(hitbase[i]&0x7FC00000)>>22; // hardcode channel assignment 00041 int time=(hitbase[i]&0xFFFFF); 00042 if (channel==0 && time==0 && i==(totalhits-1)) continue; // ignore "filler" hit 00043 digi.addTDCHit(channel,time); 00044 } 00045 }