00001 #include "EventFilter/SiPixelRawToDigi/interface/PixelDataFormatter.h"
00002
00003 #include "CondFormats/SiPixelObjects/interface/SiPixelFrameConverter.h"
00004
00005 #include "DataFormats/FEDRawData/interface/FEDRawData.h"
00006 #include "DataFormats/FEDRawData/interface/FEDHeader.h"
00007 #include "DataFormats/FEDRawData/interface/FEDTrailer.h"
00008
00009 #include "CondFormats/SiPixelObjects/interface/PixelROC.h"
00010
00011
00012 #include "FWCore/Utilities/interface/Exception.h"
00013 #include "FWCore/MessageLogger/interface/MessageLogger.h"
00014
00015 #include <bitset>
00016 #include <sstream>
00017 #include <iostream>
00018
00019 using namespace std;
00020 using namespace edm;
00021 using namespace sipixelobjects;
00022
00023 const int PixelDataFormatter::LINK_bits = 6;
00024 const int PixelDataFormatter::ROC_bits = 5;
00025 const int PixelDataFormatter::DCOL_bits = 5;
00026 const int PixelDataFormatter::PXID_bits = 8;
00027 const int PixelDataFormatter::ADC_bits = 8;
00028
00029 const int PixelDataFormatter::ADC_shift = 0;
00030 const int PixelDataFormatter::PXID_shift = ADC_shift + ADC_bits;
00031 const int PixelDataFormatter::DCOL_shift = PXID_shift + PXID_bits;
00032 const int PixelDataFormatter::ROC_shift = DCOL_shift + DCOL_bits;
00033 const int PixelDataFormatter::LINK_shift = ROC_shift + ROC_bits;
00034
00035
00036 PixelDataFormatter::PixelDataFormatter( const SiPixelFedCablingMap * map)
00037 : theDigiCounter(0), theWordCounter(0), theCablingMap(map)
00038 {
00039 int s32 = sizeof(Word32);
00040 int s64 = sizeof(Word64);
00041 int s8 = sizeof(char);
00042 if ( s8 != 1 || s32 != 4*s8 || s64 != 2*s32) {
00043 LogError("**PixelDataFormatter**")
00044 <<" unexpected sizes: "
00045 <<" size of char is: " << s8
00046 <<", size of Word32 is: " << s32
00047 <<", size of Word64 is: " << s64
00048 <<", send exception" ;
00049 }
00050 includeErrors = false;
00051 checkOrder = false;
00052 }
00053
00054 void PixelDataFormatter::setErrorStatus(bool ErrorStatus, bool OrderStatus)
00055 {
00056 includeErrors = ErrorStatus;
00057 checkOrder = OrderStatus;
00058 errorcheck.setErrorStatus(includeErrors);
00059 }
00060
00061 void PixelDataFormatter::interpretRawData(bool& errorsInEvent, int fedId, const FEDRawData& rawData, Digis& digis, Errors& errors)
00062 {
00063 int nWords = rawData.size()/sizeof(Word64);
00064 if (nWords==0) return;
00065
00066 SiPixelFrameConverter * converter = (theCablingMap) ?
00067 new SiPixelFrameConverter(theCablingMap, fedId) : 0;
00068
00069
00070 const Word64* trailer = reinterpret_cast<const Word64* >(rawData.data())+(nWords-1);
00071 bool CRC_OK = errorcheck.checkCRC(errorsInEvent, fedId, trailer, errors);
00072
00073 if(CRC_OK) {
00074
00075 const Word64* header = reinterpret_cast<const Word64* >(rawData.data()); header--;
00076 bool moreHeaders = true;
00077 while (moreHeaders) {
00078 header++;
00079 LogTrace("")<<"HEADER: " << print(*header);
00080 bool headerStatus = errorcheck.checkHeader(errorsInEvent, fedId, header, errors);
00081 moreHeaders = headerStatus;
00082 }
00083
00084
00085 bool moreTrailers = true;
00086 trailer++;
00087 while (moreTrailers) {
00088 trailer--;
00089 LogTrace("")<<"TRAILER: " << print(*trailer);
00090 bool trailerStatus = errorcheck.checkTrailer(errorsInEvent, fedId, nWords, trailer, errors);
00091 moreTrailers = trailerStatus;
00092 }
00093
00094
00095 theWordCounter += 2*(nWords-2);
00096 LogTrace("")<<"data words: "<< (trailer-header-1);
00097 for (const Word64* word = header+1; word != trailer; word++) {
00098 LogTrace("")<<"DATA: " << print(*word);
00099 static const Word64 WORD32_mask = 0xffffffff;
00100 Word32 w1 = *word & WORD32_mask;
00101 Word32 w2 = *word >> 32 & WORD32_mask;
00102 if (w1==0) theWordCounter--;
00103 if (w2==0) theWordCounter--;
00104
00105
00106 bool notErrorROC1 = errorcheck.checkROC(errorsInEvent, fedId, converter, w1, errors);
00107 if (notErrorROC1) {
00108 int status1 = word2digi(converter, includeErrors, w1, digis);
00109 if (status1) {
00110 LogDebug("PixelDataFormatter::interpretRawData")
00111 << "status #" <<status1<<" returned for word1";
00112 errorsInEvent = true;
00113 errorcheck.conversionError(fedId, converter, status1, w1, errors);
00114 }
00115 }
00116 bool notErrorROC2 = errorcheck.checkROC(errorsInEvent, fedId, converter, w2, errors);
00117 if (notErrorROC2) {
00118 int status2 = word2digi(converter, includeErrors, w2, digis);
00119 if (status2) {
00120 LogDebug("PixelDataFormatter::interpretRawData")
00121 << "status #" <<status2<<" returned for word2";
00122 errorsInEvent = true;
00123 errorcheck.conversionError(fedId, converter, status2, w2, errors);
00124 }
00125 }
00126 }
00127 }
00128 delete converter;
00129 }
00130
00131
00132 FEDRawData * PixelDataFormatter::formatData(unsigned int lvl1_ID, int fedId, const Digis & digis)
00133 {
00134 vector<Word32> words;
00135
00136 static int allDetDigis = 0;
00137 static int hasDetDigis = 0;
00138 SiPixelFrameConverter converter(theCablingMap, fedId);
00139 for (Digis::const_iterator im = digis.begin(); im != digis.end(); im++) {
00140 allDetDigis++;
00141
00142 uint32_t rawId = im->first;
00143 if ( !converter.hasDetUnit(rawId) ) continue;
00144 hasDetDigis++;
00145
00146 const DetDigis & detDigis = im->second;
00147 for (DetDigis::const_iterator it = detDigis.begin(); it != detDigis.end(); it++) {
00148 theDigiCounter++;
00149 const PixelDigi & digi = (*it);
00150 int status = digi2word( &converter, rawId, digi, words);
00151 if (status) {
00152 LogError("PixelDataFormatter::formatData exception")
00153 <<" digi2word returns error #"<<status
00154 <<" Ndigis: "<<theDigiCounter << endl
00155 <<" detector: "<<rawId<< endl
00156 << print(digi) <<endl;
00157 }
00158 }
00159 }
00160 LogTrace(" allDetDigis/hasDetDigis : ") << allDetDigis<<"/"<<hasDetDigis;
00161
00162
00163
00164
00165
00166 if (words.size() %2 != 0) words.push_back( Word32(0) );
00167
00168
00169
00170
00171
00172 int dataSize = words.size() * sizeof(Word32);
00173 int nHeaders = 1;
00174 int nTrailers = 1;
00175 dataSize += (nHeaders+nTrailers)*sizeof(Word64);
00176 FEDRawData * rawData = new FEDRawData(dataSize);
00177
00178
00179
00180 Word64 * word = reinterpret_cast<Word64* >(rawData->data());
00181
00182
00183
00184 FEDHeader::set( reinterpret_cast<unsigned char*>(word), 0, lvl1_ID, 0, fedId);
00185 word++;
00186
00187
00188
00189 for (unsigned int i=0; i < words.size(); i+=2) {
00190 *word = (Word64(words[i]) << 32 ) | words[i+1];
00191 LogDebug("PixelDataFormatter") << print(*word);
00192 word++;
00193 }
00194
00195
00196 FEDTrailer::set( reinterpret_cast<unsigned char*>(word), dataSize/sizeof(Word64), 0,0,0);
00197 word++;
00198
00199
00200
00201
00202 if (word != reinterpret_cast<Word64* >(rawData->data()+dataSize)) {
00203 string s = "** PROBLEM in PixelDataFormatter !!!";
00204 throw cms::Exception(s);
00205 }
00206
00207 return rawData;
00208 }
00209
00210 int PixelDataFormatter::digi2word( const SiPixelFrameConverter* converter,
00211 uint32_t detId, const PixelDigi& digi, std::vector<Word32> & words) const
00212 {
00213 LogDebug("PixelDataFormatter")
00214
00215 <<print(digi);
00216
00217 DetectorIndex detector = {detId, digi.row(), digi.column()};
00218 ElectronicIndex cabling;
00219 int status = converter->toCabling(cabling, detector);
00220 if (status) return status;
00221
00222 Word32 word =
00223 (cabling.link << LINK_shift)
00224 | (cabling.roc << ROC_shift)
00225 | (cabling.dcol << DCOL_shift)
00226 | (cabling.pxid << PXID_shift)
00227 | (digi.adc() << ADC_shift);
00228 words.push_back(word);
00229 theWordCounter++;
00230 return 0;
00231 }
00232
00233
00234 int PixelDataFormatter::word2digi(const SiPixelFrameConverter* converter,
00235 const bool includeErrors, const Word32 & word, Digis & digis) const
00236 {
00237
00238 if (word == 0 ) return 0;
00239
00240 static const Word32 LINK_mask = ~(~Word32(0) << LINK_bits);
00241 static const Word32 ROC_mask = ~(~Word32(0) << ROC_bits);
00242 static const Word32 DCOL_mask = ~(~Word32(0) << DCOL_bits);
00243 static const Word32 PXID_mask = ~(~Word32(0) << PXID_bits);
00244 static const Word32 ADC_mask = ~(~Word32(0) << ADC_bits);
00245
00246 ElectronicIndex cabling;
00247 cabling.dcol = (word >> DCOL_shift) & DCOL_mask;
00248 cabling.pxid = (word >> PXID_shift) & PXID_mask;
00249 cabling.link = (word >> LINK_shift) & LINK_mask;
00250 cabling.roc = (word >> ROC_shift) & ROC_mask;
00251 int adc = (word >> ADC_shift) & ADC_mask;
00252
00253 static ElectronicIndex lastcabl;
00254 static bool lastcablexists = false;
00255
00256
00257
00258 if (checkOrder && lastcablexists && (lastcabl.roc == cabling.roc) ) {
00259 if ((cabling.dcol < lastcabl.dcol) || (cabling.dcol==lastcabl.dcol && cabling.pxid < lastcabl.pxid)) {
00260 LogError("PixelDataFormatter::raw2digi exception")
00261 <<" pixel not in correct order (pxid low to high, dcol low to high)"
00262 <<" link: "<<cabling.link<<", ROC: "<<cabling.roc<<", dcol: "
00263 <<cabling.dcol<<", pxid: "<<cabling.pxid;
00264 return 4;
00265 }
00266 }
00267
00268
00269 static bool debug = edm::MessageDrop::instance()->debugEnabled;
00270 if (debug) {
00271 LocalPixel::DcolPxid pixel = {cabling.dcol,cabling.pxid};
00272 LocalPixel local(pixel);
00273 LogTrace("")<<" link: "<<cabling.link<<", roc: "<<cabling.roc
00274 <<" rocRow: "<<local.rocRow()<<", rocCol:"<<local.rocCol()
00275 <<" (dcol: "<<cabling.dcol<<",pxid:"<<cabling.pxid<<"), adc:"<<adc;
00276 }
00277
00278 if (!converter) return 0;
00279
00280 DetectorIndex detIdx;
00281 int status = converter->toDetector(cabling, detIdx);
00282 if (status) return status;
00283
00284 PixelDigi pd(detIdx.row, detIdx.col, adc);
00285 digis[detIdx.rawId].push_back(pd);
00286
00287 theDigiCounter++;
00288 if (checkOrder) {
00289 lastcabl = cabling;
00290 lastcablexists = true;
00291 }
00292 if (debug) LogTrace("") << print(pd);
00293 return 0;
00294 }
00295
00296 std::string PixelDataFormatter::print(const PixelDigi & digi) const
00297 {
00298 ostringstream str;
00299 str << " DIGI: row: " << digi.row() <<", col: " << digi.column() <<", adc: " << digi.adc();
00300 return str.str();
00301 }
00302
00303 std::string PixelDataFormatter::print(const Word64 & word) const
00304 {
00305 ostringstream str;
00306
00307 str <<"word64: " << reinterpret_cast<const bitset<64>&> (word);
00308 return str.str();
00309 }
00310