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 edm::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<edm::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 std::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 std::cout<<"ESUnpacker::ESUnpacker : Look up table file can not be found in "<<lookup_.fullPath().c_str()<<std::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, kPACE[4], kFlag1, kFlag2, kBC, kEC, optoBC, optoEC;
00059 int kid = -1;
00060
00061 ESDCCHeaderBlock ESDCCHeader;
00062 ESDCCHeader.setFedId(fedId);
00063
00064
00065 const Word64* header = reinterpret_cast<const Word64* >(rawData.data()); --header;
00066 bool moreHeaders = true;
00067 while (moreHeaders) {
00068 ++header;
00069 FEDHeader ESHeader( reinterpret_cast<const unsigned char*>(header) );
00070 if ( !ESHeader.check() ) {
00071 if (debug_) edm::LogWarning("Invalid Data")<<"ES : Failed header check !";
00072 return;
00073 }
00074
00075 fedId_ = ESHeader.sourceID();
00076 lv1_ = ESHeader.lvl1ID();
00077 bx_ = ESHeader.bxID();
00078
00079 if (debug_) {
00080 std::cout<<"[ESUnpacker]: FED Header candidate. Is header? "<< ESHeader.check();
00081 if (ESHeader.check())
00082 std::cout <<". BXID: "<<bx_<<" SourceID : "<<fedId_<<" L1ID: "<<lv1_<<std::endl;
00083 else std::cout<<" WARNING!, this is not a ES Header"<<std::endl;
00084 }
00085
00086 moreHeaders = ESHeader.moreHeaders();
00087 }
00088 if ( fedId != fedId_) {
00089 if (debug_) edm::LogWarning("Invalid Data")<<"Invalid ES data with source id " <<fedId_;
00090 ESDCCHeader.setDCCErrors(1);
00091 dccs.push_back(ESDCCHeader);
00092 return;
00093 }
00094 ESDCCHeader.setLV1(lv1_);
00095 ESDCCHeader.setBX(bx_);
00096
00097
00098 int slinkCRC = 1;
00099 const Word64* trailer = reinterpret_cast<const Word64* >(rawData.data())+(nWords-1); ++trailer;
00100 bool moreTrailers = true;
00101 while (moreTrailers) {
00102 --trailer;
00103 FEDTrailer ESTrailer(reinterpret_cast<const unsigned char*>(trailer));
00104 if ( !ESTrailer.check()) {
00105 ++trailer;
00106 if (debug_) edm::LogWarning("Invalid Data")<<"ES : Failed trailer check !";
00107 return;
00108 }
00109 if ( ESTrailer.lenght() != nWords) {
00110 if (debug_) edm::LogWarning("Invalid Data")<<"Invalid ES data : the length is not correct !";
00111 ESDCCHeader.setDCCErrors(2);
00112 dccs.push_back(ESDCCHeader);
00113 return;
00114 }
00115 if ( ESTrailer.lenght() < 8) {
00116 if (debug_) edm::LogWarning("Invalid Data")<<"Invalid ES data : the length is not correct !";
00117 ESDCCHeader.setDCCErrors(3);
00118 dccs.push_back(ESDCCHeader);
00119 return;
00120 }
00121 slinkCRC = (*trailer >> 2 ) & 0x1;
00122 if (debug_) {
00123 std::cout<<"[ESUnpacker]: FED Trailer candidate. Is trailer? "<<ESTrailer.check();
00124 if (ESTrailer.check())
00125 std::cout<<". Length of the ES event: "<<ESTrailer.lenght()<<std::endl;
00126 else std::cout<<" WARNING!, this is not a ES Trailer"<<std::endl;
00127 }
00128
00129 moreTrailers = ESTrailer.moreTrailers();
00130 }
00131
00132 if (slinkCRC != 0) {
00133 ESDCCHeader.setDCCErrors(101);
00134 dccs.push_back(ESDCCHeader);
00135 return;
00136 }
00137
00138
00139 std::vector<int> FEch_status;
00140 int dccHeaderCount = 0;
00141 int dccLineCount = 0;
00142 int dccHead, dccLine;
00143 int dccCRC1_ = 0;
00144 int dccCRC2_ = 0;
00145 int dccCRC3_ = 0;
00146 for (const Word64* word=(header+1); word!=(header+dccWords+1); ++word) {
00147 if (debug_) std::cout<<"DCC : "<<print(*word)<<std::endl;
00148 dccHead = (*word >> 60) & m4;
00149 if (dccHead == 3) dccHeaderCount++;
00150 dccLine = (*word >> 56) & m4;
00151 dccLineCount++;
00152 if (dccLine != dccLineCount) {
00153 if (debug_) edm::LogWarning("Invalid Data")<<"Invalid ES data : DCC header order is not correct !";
00154 ESDCCHeader.setDCCErrors(4);
00155 dccs.push_back(ESDCCHeader);
00156 return;
00157 }
00158 if (dccLineCount == 1) {
00159 dccCRC1_ = (*word >> 24) & m1;
00160 dccCRC2_ = (*word >> 25) & m1;
00161 dccCRC3_ = (*word >> 26) & m1;
00162 } else if (dccLineCount == 2) {
00163 runtype_ = (*word >> 0) & m4;
00164 seqtype_ = (*word >> 4) & m4;
00165 dac_ = (*word >> 8) & m12;
00166 gain_ = (*word >> 20) & m1;
00167 precision_ = (*word >> 21) & m1;
00168 trgtype_ = (*word >> 34) & m6;
00169
00170 ESDCCHeader.setRunType(runtype_);
00171 ESDCCHeader.setSeqType(seqtype_);
00172 ESDCCHeader.setTriggerType(trgtype_);
00173 ESDCCHeader.setDAC(dac_);
00174 ESDCCHeader.setGain(gain_);
00175 ESDCCHeader.setPrecision(precision_);
00176 }
00177 if (dccLineCount == 3) {
00178 orbit_number_ = (*word >> 0) & m32;
00179 vminor_ = (*word >> 40) & m8;
00180 vmajor_ = (*word >> 48) & m8;
00181
00182 ESDCCHeader.setOrbitNumber(orbit_number_);
00183 ESDCCHeader.setMajorVersion(vmajor_);
00184 ESDCCHeader.setMinorVersion(vminor_);
00185 }
00186 if (dccLineCount == 4) optoRX0_ = (*word >> 48) & m8;
00187 if (dccLineCount == 5) optoRX1_ = (*word >> 48) & m8;
00188 if (dccLineCount == 6) optoRX2_ = (*word >> 48) & m8;
00189 if (dccLineCount >=4) {
00190 for (unsigned int j=0; j<12; ++j) {
00191 FEch_[(dccLineCount-4)*12+j] = (*word >> (j*4)) & m4;
00192 FEch_status.push_back(FEch_[(dccLineCount-4)*12+j]);
00193 }
00194 }
00195 }
00196 if (vmajor_ < 4) {
00197 if (debug_)
00198 edm::LogWarning("Invalid Data")<<"Invalid ES data format : "<<vmajor_<<" "<<vminor_;
00199 return;
00200 }
00201 if (dccHeaderCount != 6) {
00202 edm::LogWarning("Invalid Data")<<"Invalid ES data : DCC header lines are "<<dccHeaderCount;
00203 ESDCCHeader.setDCCErrors(5);
00204 dccs.push_back(ESDCCHeader);
00205 return;
00206 }
00207 ESDCCHeader.setOptoRX0(optoRX0_ + dccCRC1_);
00208 ESDCCHeader.setOptoRX1(optoRX1_ + dccCRC2_);
00209 ESDCCHeader.setOptoRX2(optoRX2_ + dccCRC3_);
00210 ESDCCHeader.setFEChannelStatus(FEch_status);
00211
00212
00213 int opto = 0;
00214 for (const Word64* word=(header+dccWords+1); word!=trailer; ++word) {
00215 if (debug_) std::cout<<"Event : "<<print(*word)<<std::endl;
00216
00217 head = (*word >> 60) & m4;
00218
00219 if (head == 12) {
00220 if ((opto==1 && ESDCCHeader.getOptoRX0()==129) || (opto==2 && ESDCCHeader.getOptoRX1()==129) || (opto==3 && ESDCCHeader.getOptoRX2()==129))
00221 word2digi(kid, kPACE, *word, digis);
00222 } else if (head == 9) {
00223 kid = (*word >> 2) & 0x07ff;
00224 kPACE[0] = (*word >> 16) & m1;
00225 kPACE[1] = (*word >> 17) & m1;
00226 kPACE[2] = (*word >> 18) & m1;
00227 kPACE[3] = (*word >> 19) & m1;
00228 kFlag2 = (*word >> 20) & m4;
00229 kFlag1 = (*word >> 24) & m8;
00230 kBC = (*word >> 32) & m16;
00231 kEC = (*word >> 48) & m8;
00232
00233 ESKCHIPBlock ESKCHIP;
00234 ESKCHIP.setId(kid);
00235 ESKCHIP.setBC(kBC);
00236 ESKCHIP.setEC(kEC);
00237 ESKCHIP.setOptoBC(optoBC);
00238 ESKCHIP.setOptoEC(optoEC);
00239 ESKCHIP.setFlag1(kFlag1);
00240 ESKCHIP.setFlag2(kFlag2);
00241 kchips.push_back(ESKCHIP);
00242 } else if (head == 6) {
00243 optoBC = (*word >> 32) & m16;
00244 optoEC = (*word >> 48) & m8;
00245 if (opto==0) ESDCCHeader.setOptoBC0(optoBC);
00246 else if (opto==1) ESDCCHeader.setOptoBC1(optoBC);
00247 else if (opto==2) ESDCCHeader.setOptoBC2(optoBC);
00248 opto++;
00249 }
00250 }
00251
00252 dccs.push_back(ESDCCHeader);
00253 }
00254
00255 void ESUnpacker::word2digi(int kid, int kPACE[4], const Word64 & word, ESDigiCollection & digis)
00256 {
00257
00258 int pace = (word >> 53) & m2;
00259 if (kPACE[pace]==0) return;
00260 if (kid > 1511 || kid < 1) return;
00261
00262 int adc[3];
00263 adc[0] = (word >> 0) & m16;
00264 adc[1] = (word >> 16) & m16;
00265 adc[2] = (word >> 32) & m16;
00266 int strip = (word >> 48) & m5;
00267
00268 if (debug_) std::cout<<kid<<" "<<strip<<" "<<pace<<" "<<adc[0]<<" "<<adc[1]<<" "<<adc[2]<<std::endl;
00269
00270 int zside, plane, ix, iy;
00271 zside = zside_[kid-1][pace];
00272 plane = pl_[kid-1][pace];
00273 ix = x_[kid-1][pace];
00274 iy = y_[kid-1][pace];
00275
00276
00277 if (vmajor_ == 4 && (vminor_==2 || vminor_==3)) {
00278 if (zside == 1 && plane == 1 && iy <= 20) strip = 31 - strip;
00279 if (zside == 1 && plane == 2 && ix > 20) strip = 31 - strip;
00280 if (zside == -1 && plane == 1 && iy > 20) strip = 31 - strip;
00281 if (zside == -1 && plane == 2 && ix <= 20) strip = 31 - strip;
00282 }
00283
00284 if (debug_) std::cout<<"DetId : "<<zside<<" "<<plane<<" "<<ix<<" "<<iy<<" "<<strip+1<<std::endl;
00285
00286 if (ESDetId::validDetId(strip+1, ix, iy, plane, zside)) {
00287
00288 ESDetId detId(strip+1, ix, iy, plane, zside);
00289 ESDataFrame df(detId);
00290 df.setSize(3);
00291
00292 for (int i=0; i<3; i++) df.setSample(i, adc[i]);
00293
00294 digis.push_back(df);
00295
00296 if (debug_)
00297 std::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()<<std::endl;
00298 }
00299
00300 }
00301
00302 std::string ESUnpacker::print(const Word64 & word) const
00303 {
00304 std::ostringstream str;
00305 str << "Word64: " << reinterpret_cast<const std::bitset<64>&> (word);
00306 return str.str();
00307 }
00308