00001 #include "EventFilter/ESRawToDigi/interface/ESUnpacker.h"
00002 #include "DataFormats/FEDRawData/interface/FEDNumbering.h"
00003 #include "DataFormats/EcalDetId/interface/EcalDetIdCollections.h"
00004 #include "DataFormats/FEDRawData/interface/FEDHeader.h"
00005 #include "DataFormats/FEDRawData/interface/FEDTrailer.h"
00006 #include "FWCore/MessageLogger/interface/MessageLogger.h"
00007
00008 #include <fstream>
00009
00010 ESUnpacker::ESUnpacker(const ParameterSet& ps)
00011 : pset_(ps), fedId_(0), run_number_(0), orbit_number_(0), bx_(0), lv1_(0), trgtype_(0)
00012 {
00013
00014 debug_ = pset_.getUntrackedParameter<bool>("debugMode", false);
00015 lookup_ = ps.getParameter<FileInPath>("LookupTable");
00016
00017 m1 = ~(~Word64(0) << 1);
00018 m2 = ~(~Word64(0) << 2);
00019 m4 = ~(~Word64(0) << 4);
00020 m5 = ~(~Word64(0) << 5);
00021 m6 = ~(~Word64(0) << 6);
00022 m8 = ~(~Word64(0) << 8);
00023 m12 = ~(~Word64(0) << 12);
00024 m16 = ~(~Word64(0) << 16);
00025 m32 = ~(~Word64(0) << 32);
00026
00027
00028 int nLines, iz, ip, ix, iy, fed, kchip, pace, bundle, fiber, optorx;
00029 ifstream file;
00030 file.open(lookup_.fullPath().c_str());
00031 if( file.is_open() ) {
00032
00033 file >> nLines;
00034
00035 for (int i=0; i<nLines; ++i) {
00036 file>> iz >> ip >> ix >> iy >> fed >> kchip >> pace >> bundle >> fiber >> optorx;
00037
00038 zside_[kchip-1][pace-1] = iz;
00039 pl_[kchip-1][pace-1] = ip;
00040 x_[kchip-1][pace-1] = ix;
00041 y_[kchip-1][pace-1] = iy;
00042 }
00043
00044 } else {
00045 cout<<"ESUnpacker::ESUnpacker : Look up table file can not be found in "<<lookup_.fullPath().c_str()<<endl;
00046 }
00047
00048 }
00049
00050 ESUnpacker::~ESUnpacker() {
00051 }
00052
00053 void ESUnpacker::interpretRawData(int fedId, const FEDRawData & rawData, ESRawDataCollection & dccs, ESLocalRawDataCollection & kchips, ESDigiCollection & digis) {
00054
00055 int nWords = rawData.size()/sizeof(Word64);
00056 if (nWords==0) return;
00057 int dccWords = 6;
00058 int head, kid, kPACE[4], kFlag1, kFlag2, kBC, kEC, optoBC, optoEC, ttcEC;
00059
00060 ESDCCHeaderBlock ESDCCHeader;
00061 ESDCCHeader.setFedId(fedId);
00062
00063
00064 const Word64* header = reinterpret_cast<const Word64* >(rawData.data()); --header;
00065 bool moreHeaders = true;
00066 while (moreHeaders) {
00067 ++header;
00068 FEDHeader ESHeader( reinterpret_cast<const unsigned char*>(header) );
00069 if ( !ESHeader.check() ) {
00070 if (debug_) edm::LogWarning("Invalid Data")<<"ES : Failed header check !";
00071 return;
00072 }
00073
00074 fedId_ = ESHeader.sourceID();
00075 lv1_ = ESHeader.lvl1ID();
00076 bx_ = ESHeader.bxID();
00077
00078 if (debug_) {
00079 cout<<"[ESUnpacker]: FED Header candidate. Is header? "<< ESHeader.check();
00080 if (ESHeader.check())
00081 cout <<". BXID: "<<bx_<<" SourceID : "<<fedId_<<" L1ID: "<<lv1_<<endl;
00082 else cout<<" WARNING!, this is not a ES Header"<<endl;
00083 }
00084
00085 moreHeaders = ESHeader.moreHeaders();
00086 }
00087 if ( fedId != fedId_) {
00088 if (debug_) edm::LogWarning("Invalid Data")<<"Invalid ES data with source id " <<fedId_;
00089 ESDCCHeader.setDCCErrors(1);
00090 dccs.push_back(ESDCCHeader);
00091 return;
00092 }
00093 ESDCCHeader.setLV1(lv1_);
00094 ESDCCHeader.setBX(bx_);
00095
00096
00097 const Word64* trailer = reinterpret_cast<const Word64* >(rawData.data())+(nWords-1); ++trailer;
00098 bool moreTrailers = true;
00099 while (moreTrailers) {
00100 --trailer;
00101 FEDTrailer ESTrailer(reinterpret_cast<const unsigned char*>(trailer));
00102 if ( !ESTrailer.check()) {
00103 ++trailer;
00104 if (debug_) edm::LogWarning("Invalid Data")<<"ES : Failed trailer check !";
00105 return;
00106 }
00107 if ( ESTrailer.lenght() != nWords) {
00108 if (debug_) edm::LogWarning("Invalid Data")<<"Invalid ES data : the length is not correct !";
00109 ESDCCHeader.setDCCErrors(2);
00110 dccs.push_back(ESDCCHeader);
00111 return;
00112 }
00113 if ( ESTrailer.lenght() < 8) {
00114 if (debug_) edm::LogWarning("Invalid Data")<<"Invalid ES data : the length is not correct !";
00115 ESDCCHeader.setDCCErrors(3);
00116 dccs.push_back(ESDCCHeader);
00117 return;
00118 }
00119
00120 if (debug_) {
00121 cout<<"[ESUnpacker]: FED Trailer candidate. Is trailer? "<<ESTrailer.check();
00122 if (ESTrailer.check())
00123 cout<<". Length of the ES event: "<<ESTrailer.lenght()<<endl;
00124 else cout<<" WARNING!, this is not a ES Trailer"<<endl;
00125 }
00126
00127 moreTrailers = ESTrailer.moreTrailers();
00128 }
00129
00130
00131 vector<int> FEch_status;
00132 int dccHeaderCount = 0;
00133 int dccLineCount = 0;
00134 int dccHead, dccLine;
00135 for (const Word64* word=(header+1); word!=(header+dccWords+1); ++word) {
00136 if (debug_) cout<<"DCC : "<<print(*word)<<endl;
00137 dccHead = (*word >> 60) & m4;
00138 if (dccHead == 3) dccHeaderCount++;
00139 dccLine = (*word >> 56) & m4;
00140 dccLineCount++;
00141 if (dccLine != dccLineCount) {
00142 if (debug_) edm::LogWarning("Invalid Data")<<"Invalid ES data : DCC header order is not correct !";
00143 ESDCCHeader.setDCCErrors(4);
00144 dccs.push_back(ESDCCHeader);
00145 return;
00146 }
00147 if (dccLineCount == 2) {
00148 runtype_ = (*word >> 0) & m4;
00149 seqtype_ = (*word >> 4) & m4;
00150 dac_ = (*word >> 8) & m12;
00151 gain_ = (*word >> 20) & m1;
00152 precision_ = (*word >> 21) & m1;
00153 trgtype_ = (*word >> 34) & m6;
00154
00155 ESDCCHeader.setRunType(runtype_);
00156 ESDCCHeader.setSeqType(seqtype_);
00157 ESDCCHeader.setTriggerType(trgtype_);
00158 ESDCCHeader.setDAC(dac_);
00159 ESDCCHeader.setGain(gain_);
00160 ESDCCHeader.setPrecision(precision_);
00161 }
00162 if (dccLineCount == 3) {
00163 vminor_ = (*word >> 40) & m8;
00164 vmajor_ = (*word >> 48) & m8;
00165 }
00166 if (dccLineCount == 4) optoRX0_ = (*word >> 48) & m8;
00167 if (dccLineCount == 5) optoRX1_ = (*word >> 48) & m8;
00168 if (dccLineCount == 6) optoRX2_ = (*word >> 48) & m8;
00169 if (dccLineCount >=4) {
00170 for (unsigned int j=0; j<12; ++j) {
00171 FEch_[(dccLineCount-4)*12+j] = (*word >> (j*4)) & m4;
00172 FEch_status.push_back(FEch_[(dccLineCount-4)*12+j]);
00173 }
00174 }
00175 }
00176 if (vmajor_ < 4) {
00177 if (debug_)
00178 edm::LogWarning("Invalid Data")<<"Invalid ES data format : "<<vmajor_<<" "<<vminor_;
00179 return;
00180 }
00181 if (dccHeaderCount != 6) {
00182 edm::LogWarning("Invalid Data")<<"Invalid ES data : DCC header lines are "<<dccHeaderCount;
00183 ESDCCHeader.setDCCErrors(5);
00184 dccs.push_back(ESDCCHeader);
00185 return;
00186 }
00187 ESDCCHeader.setOptoRX0(optoRX0_);
00188 ESDCCHeader.setOptoRX1(optoRX1_);
00189 ESDCCHeader.setOptoRX2(optoRX2_);
00190 ESDCCHeader.setFEChannelStatus(FEch_status);
00191
00192
00193 int opto = 0;
00194 for (const Word64* word=(header+dccWords+1); word!=trailer; ++word) {
00195 if (debug_) cout<<"Event : "<<print(*word)<<endl;
00196
00197 head = (*word >> 60) & m4;
00198
00199 if (head == 12) {
00200 word2digi(kid, kPACE, *word, digis);
00201 } else if (head == 9) {
00202 kid = (*word >> 2) & 0x07ff;
00203 kPACE[0] = (*word >> 16) & m1;
00204 kPACE[1] = (*word >> 17) & m1;
00205 kPACE[2] = (*word >> 18) & m1;
00206 kPACE[3] = (*word >> 19) & m1;
00207 kFlag2 = (*word >> 20) & m4;
00208 kFlag1 = (*word >> 24) & m8;
00209 kBC = (*word >> 32) & m16;
00210 kEC = (*word >> 48) & m8;
00211
00212 ESKCHIPBlock ESKCHIP;
00213 ESKCHIP.setId(kid);
00214 ESKCHIP.setBC(kBC);
00215 ESKCHIP.setEC(kEC);
00216 ESKCHIP.setOptoBC(optoBC);
00217 ESKCHIP.setOptoEC(optoEC);
00218 ESKCHIP.setFlag1(kFlag1);
00219 ESKCHIP.setFlag2(kFlag2);
00220 kchips.push_back(ESKCHIP);
00221 } else if (head == 6) {
00222 ttcEC = (*word >> 0) & m32;
00223 optoBC = (*word >> 32) & m16;
00224 optoEC = (*word >> 48) & m8;
00225 if (opto==0) ESDCCHeader.setOptoBC0(optoBC);
00226 else if (opto==1) ESDCCHeader.setOptoBC1(optoBC);
00227 else if (opto==2) ESDCCHeader.setOptoBC2(optoBC);
00228 opto++;
00229 }
00230 }
00231
00232 dccs.push_back(ESDCCHeader);
00233 }
00234
00235 void ESUnpacker::word2digi(int kid, int kPACE[4], const Word64 & word, ESDigiCollection & digis)
00236 {
00237
00238 int pace = (word >> 53) & m2;
00239 if (kPACE[pace]==0) return;
00240
00241 int adc[3];
00242 adc[0] = (word >> 0) & m16;
00243 adc[1] = (word >> 16) & m16;
00244 adc[2] = (word >> 32) & m16;
00245 int strip = (word >> 48) & m5;
00246 if (debug_) cout<<kid<<" "<<strip<<" "<<pace<<" "<<adc[0]<<" "<<adc[1]<<" "<<adc[2]<<endl;
00247
00248 int zside, plane, ix, iy;
00249 zside = zside_[kid-1][pace];
00250 plane = pl_[kid-1][pace];
00251 ix = x_[kid-1][pace];
00252 iy = y_[kid-1][pace];
00253
00254 if (debug_) cout<<"DetId : "<<zside<<" "<<plane<<" "<<ix<<" "<<iy<<" "<<strip+1<<endl;
00255
00256 if (ESDetId::validDetId(strip+1, ix, iy, plane, zside)) {
00257
00258 ESDetId detId(strip+1, ix, iy, plane, zside);
00259 ESDataFrame df(detId);
00260 df.setSize(3);
00261
00262 for (int i=0; i<3; i++) df.setSample(i, adc[i]);
00263
00264 digis.push_back(df);
00265
00266 if (debug_)
00267 cout<<"Si : "<<detId.zside()<<" "<<detId.plane()<<" "<<detId.six()<<" "<<detId.siy()<<" "<<detId.strip()<<" ("<<kid<<","<<pace<<") "<<df.sample(0).adc()<<" "<<df.sample(1).adc()<<" "<<df.sample(2).adc()<<endl;
00268 }
00269
00270 }
00271
00272 string ESUnpacker::print(const Word64 & word) const
00273 {
00274 ostringstream str;
00275 str << "Word64: " << reinterpret_cast<const bitset<64>&> (word);
00276 return str.str();
00277 }
00278