Back to home page

Project CMSSW displayed by LXR

 
 

    


File indexing completed on 2024-04-06 12:11:00

0001 /** \class SiPixelRawDumper_H
0002  * To find hot pixels from raw data
0003  * Works in  v352
0004  */
0005 
0006 #include "FWCore/Framework/interface/one/EDAnalyzer.h"
0007 #include "FWCore/Framework/interface/Event.h"
0008 #include "FWCore/ParameterSet/interface/ParameterSet.h"
0009 
0010 #include "DataFormats/Common/interface/Handle.h"
0011 
0012 #include "FWCore/MessageLogger/interface/MessageLogger.h"
0013 #include "DataFormats/FEDRawData/interface/FEDRawDataCollection.h"
0014 #include "DataFormats/FEDRawData/interface/FEDRawData.h"
0015 
0016 #include "DataFormats/FEDRawData/interface/FEDNumbering.h"
0017 
0018 #include "EventFilter/SiPixelRawToDigi/interface/PixelDataFormatter.h"
0019 
0020 #include <iostream>
0021 #include <fstream>
0022 #include <sstream>
0023 #include <string>
0024 #include <iomanip>
0025 
0026 namespace {
0027   const bool printErrors = true;
0028   const bool printData = false;
0029   const bool printHeaders = false;
0030   int count1 = 0, count2 = 0, count3 = 0;
0031 }  // namespace
0032 
0033 using namespace std;
0034 
0035 // Include the helper decoding class
0036 /////////////////////////////////////////////////////////////////////////////
0037 class MyDecode {
0038 public:
0039   MyDecode() {}
0040   ~MyDecode() {}
0041   static int error(int error, bool print = false);
0042   static int data(int error, int &channel, int &roc, int &dcol, int &pix, bool print = false);
0043   static int header(unsigned long long word64, bool print);
0044   static int trailer(unsigned long long word64, bool print);
0045 
0046 private:
0047 };
0048 /////////////////////////////////////////////////////////////////////////////
0049 int MyDecode::header(unsigned long long word64, bool printFlag) {
0050   int fed_id = (word64 >> 8) & 0xfff;
0051   int event_id = (word64 >> 32) & 0xffffff;
0052   unsigned int bx_id = (word64 >> 20) & 0xfff;
0053   //   if(bx_id!=101) {
0054   //     cout<<" Header "<<" for FED "
0055   //   <<fed_id<<" event "<<event_id<<" bx "<<bx_id<<endl;
0056   //     int dummy=0;
0057   //     cout<<" : ";
0058   //     cin>>dummy;
0059   //   }
0060   if (printFlag)
0061     cout << " Header "
0062          << " for FED " << fed_id << " event " << event_id << " bx " << bx_id << endl;
0063 
0064   return event_id;
0065 }
0066 //
0067 int MyDecode::trailer(unsigned long long word64, bool printFlag) {
0068   int slinkLength = int((word64 >> 32) & 0xffffff);
0069   int crc = int((word64 & 0xffff0000) >> 16);
0070   int tts = int((word64 & 0xf0) >> 4);
0071   int slinkError = int((word64 & 0xf00) >> 8);
0072   if (printFlag)
0073     cout << " Trailer "
0074          << " len " << slinkLength << " tts " << tts << " error " << slinkError << " crc " << hex << crc << dec << endl;
0075   return slinkLength;
0076 }
0077 //
0078 // Decode error FIFO
0079 // Works for both, the error FIFO and the SLink error words. d.k. 25/04/07
0080 int MyDecode::error(int word, bool printFlag) {
0081   int status = -1;
0082   const unsigned int errorMask = 0x3e00000;
0083   const unsigned int dummyMask = 0x03600000;
0084   const unsigned int gapMask = 0x03400000;
0085   const unsigned int timeOut = 0x3a00000;
0086   const unsigned int eventNumError = 0x3e00000;
0087   const unsigned int trailError = 0x3c00000;
0088   const unsigned int fifoError = 0x3800000;
0089 
0090   //  const unsigned int  timeOutChannelMask = 0x1f;  // channel mask for timeouts
0091   //const unsigned int  eventNumMask = 0x1fe000; // event number mask
0092   const unsigned int channelMask = 0xfc000000;  // channel num mask
0093   const unsigned int tbmEventMask = 0xff;       // tbm event num mask
0094   const unsigned int overflowMask = 0x100;      // data overflow
0095   const unsigned int tbmStatusMask = 0xff;      //TBM trailer info
0096   const unsigned int BlkNumMask = 0x700;        //pointer to error fifo #
0097   const unsigned int FsmErrMask = 0x600;        //pointer to FSM errors
0098   const unsigned int RocErrMask = 0x800;        //pointer to #Roc errors
0099   const unsigned int ChnFifMask = 0x1f;         //channel mask for fifo error
0100   const unsigned int Fif2NFMask = 0x40;         //mask for fifo2 NF
0101   const unsigned int TrigNFMask = 0x80;         //mask for trigger fifo NF
0102 
0103   const int offsets[8] = {0, 4, 9, 13, 18, 22, 27, 31};
0104 
0105   //cout<<"error word "<<hex<<word<<dec<<endl;
0106 
0107   if ((word & errorMask) == dummyMask) {  // DUMMY WORD
0108     //cout<<" Dummy word";
0109     return 0;
0110   } else if ((word & errorMask) == gapMask) {  // GAP WORD
0111     //cout<<" Gap word";
0112     return 0;
0113   } else if ((word & errorMask) == timeOut) {  // TIMEOUT
0114     // More than 1 channel within a group can have a timeout error
0115     unsigned int index = (word & 0x1F);  // index within a group of 4/5
0116     unsigned int chip = (word & BlkNumMask) >> 8;
0117     int offset = offsets[chip];
0118     if (printErrors) {
0119       cout << "Timeout Error- channels: ";
0120       for (int i = 0; i < 5; i++) {
0121         if ((index & 0x1) != 0) {
0122           int chan = offset + i + 1;
0123           cout << chan << " ";
0124         }
0125         index = index >> 1;
0126       }
0127       cout << endl;
0128     }
0129     //end of timeout  chip and channel decoding
0130 
0131   } else if ((word & errorMask) == eventNumError) {  // EVENT NUMBER ERROR
0132     unsigned int channel = (word & channelMask) >> 26;
0133     unsigned int tbm_event = (word & tbmEventMask);
0134 
0135     if (printErrors)
0136       cout << "Event Number Error- channel: " << channel << " tbm event nr. " << tbm_event << endl;
0137 
0138   } else if (((word & errorMask) == trailError)) {
0139     unsigned int channel = (word & channelMask) >> 26;
0140     unsigned int tbm_status = (word & tbmStatusMask);
0141     if (word & RocErrMask)
0142       if (printErrors)
0143         cout << "Number of Rocs Error- "
0144              << "channel: " << channel << " " << endl;
0145     if (word & FsmErrMask)
0146       if (printErrors)
0147         cout << "Finite State Machine Error- "
0148              << "channel: " << channel << " Error status:0x" << hex << ((word & FsmErrMask) >> 9) << dec << " " << endl;
0149     if (word & overflowMask)
0150       if (printErrors)
0151         cout << "Overflow Error- "
0152              << "channel: " << channel << " " << endl;
0153     //if(!((word & RocErrMask)|(word & FsmErrMask)|(word & overflowMask)))
0154     if (tbm_status != 0)
0155       if (printErrors)
0156         cout << "Trailer Error- "
0157              << "channel: " << channel << " TBM status:0x" << hex << tbm_status << dec << " " << endl;
0158 
0159   } else if ((word & errorMask) == fifoError) {
0160     if (printErrors) {
0161       if (word & Fif2NFMask)
0162         cout << "A fifo 2 is Nearly full- ";
0163       if (word & TrigNFMask)
0164         cout << "The trigger fifo is nearly Full - ";
0165       if (word & ChnFifMask)
0166         cout << "fifo-1 is nearly full for channel" << (word & ChnFifMask);
0167       cout << endl;
0168     }
0169   } else {
0170     cout << " Unknown error?";
0171   }
0172 
0173   //unsigned int event   =  (word & eventNumMask) >>13;
0174   //unsigned int tbm_status   =  (word & tbmStatusMask);
0175   //if(event>0) cout<<":event: "<<event;
0176   //cout<<endl;
0177 
0178   return status;
0179 }
0180 // ///////////////////////////////////////////////////////////////////////////
0181 int MyDecode::data(int word, int &c, int &r, int &d, int &p, bool printFlag) {
0182   const bool CHECK_PIXELS = true;
0183   //const bool PRINT_PIXELS = printData;
0184   const bool PRINT_PIXELS = false;
0185 
0186   const int ROCMAX = 24;
0187   const unsigned int plsmsk = 0xff;    // pulse height
0188   const unsigned int pxlmsk = 0xff00;  // pixel index
0189   const unsigned int dclmsk = 0x1f0000;
0190   const unsigned int rocmsk = 0x3e00000;
0191   const unsigned int chnlmsk = 0xfc000000;
0192   int status = 0;
0193 
0194   int roc = ((word & rocmsk) >> 21);
0195   // Check for embeded special words
0196   if (roc > 0 && roc < 25) {  // valid ROCs go from 1-24
0197     //if(PRINT_PIXELS) cout<<"data "<<hex<<word<<dec;
0198     unsigned int channel = ((word & chnlmsk) >> 26);
0199     if (channel > 0 && channel < 37) {  // valid channels 1-36
0200       //cout<<hex<<word<<dec;
0201       int dcol = (word & dclmsk) >> 16;
0202       int pix = (word & pxlmsk) >> 8;
0203       int adc = (word & plsmsk);
0204       // print the roc number according to the online 0-15 scheme
0205       if (PRINT_PIXELS)
0206         cout << " Channel- " << channel << " ROC- " << (roc - 1) << " DCOL- " << dcol << " Pixel- " << pix << " ADC- "
0207              << adc << endl;
0208       if (CHECK_PIXELS) {
0209         if (roc > ROCMAX)
0210           cout << " wrong roc number " << channel << "/" << roc << "/" << dcol << "/" << pix << "/" << adc << endl;
0211         if (dcol < 0 || dcol > 25)
0212           cout << " wrong dcol number " << channel << "/" << roc << "/" << dcol << "/" << pix << "/" << adc << endl;
0213         if (pix < 2 || pix > 181)
0214           cout << " wrong pix number chan/roc/dcol/pix/adc = " << channel << "/" << roc << "/" << dcol << "/" << pix
0215                << "/" << adc << endl;
0216       }
0217       c = channel;
0218       r = roc - 1;  // start roc counting from 0
0219       d = dcol;
0220       p = pix;
0221       status++;
0222     } else {
0223       cout << "Wrong channel " << channel << endl;
0224       return -2;
0225     }
0226   } else {  // error word
0227     //cout<<"error word "<<hex<<word<<dec;
0228     status = error(word);
0229   }
0230 
0231   return status;
0232 }
0233 ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
0234 // Class to get names
0235 class MyConvert {
0236 public:
0237   MyConvert() {}
0238   ~MyConvert() {}
0239   static string moduleNameFromFedChan(int fed, int fedChan, string &tbm);
0240 
0241 private:
0242 };
0243 
0244 // Method returns the module name and the tbm type as strings
0245 // input: int fed, fedChan
0246 // output: string name, tbm ("A" or "B")
0247 string MyConvert::moduleNameFromFedChan(int fed0, int fedChan0, string &tbm0) {
0248   if (fed0 < 0 || fed0 > 31)
0249     return " ";
0250   if (fedChan0 < 1 || fedChan0 > 36)
0251     return " ";
0252 
0253   ifstream infile;                               //input file, name data_file uniqe
0254   infile.open("translation_bpix.dat", ios::in);  // open data file
0255 
0256   //cout << infile.eof() << " " << infile.bad() << " "
0257   //   << infile.fail() << " " << infile.good()<<endl;
0258 
0259   if (infile.fail()) {
0260     cout << " File not found " << endl;
0261     return (" ");  // signal error
0262   }
0263 
0264   //string line;
0265   char line[500];
0266   infile.getline(line, 500, '\n');
0267 
0268   string name, modName = " ";
0269   int fec, mfec, mfecChan, hub, port, rocId, fed, fedChan, rocOrder;
0270   string tbm = " ";
0271   int fedOld = -1, fedChanOld = -1;
0272   bool found = false;
0273   for (int i = 0; i < 100000; ++i) {
0274     //bool print = false;
0275 
0276     infile >> name >> tbm >> fec >> mfec >> mfecChan >> hub >> port >> rocId >> fed >> fedChan >> rocOrder;
0277 
0278     if (name == " ")
0279       continue;
0280 
0281     if (infile.eof() != 0) {
0282       cout << " end of file " << endl;
0283       break;
0284       ;
0285     } else if (infile.fail()) {  // check for errors
0286       cout << "Cannot read data file" << endl;
0287       return (" ");
0288     }
0289 
0290     if (fed == fedOld && fedChanOld == fedChan)
0291       continue;
0292     fedOld = fed;
0293     fedChanOld = fedChan;
0294 
0295     if (fed == fed0 && fedChan == fedChan0) {  // found
0296       found = true;
0297       tbm0 = tbm;
0298 
0299       string::size_type idx;
0300       idx = name.find("_ROC");
0301       if (idx != string::npos) {
0302         //      cout<<" ROC0 "<<idx<<endl;
0303         //name.replace(idx,idx+4,"     ");
0304         modName = name.substr(0, (idx));
0305       }
0306 
0307       break;
0308     }
0309   }  // end line loop
0310 
0311   infile.close();
0312   if (!found)
0313     cout << " Module not found " << fed0 << " " << fedChan0 << endl;
0314 
0315   return modName;
0316 }
0317 
0318 //////////////////////////////////////////////////////////////////////////////////////////////////////////
0319 
0320 const int NumPixels = 100000;
0321 class HotPixels {
0322 public:
0323   HotPixels() {
0324     count = 0;
0325     for (int i = 0; i < NumPixels; ++i) {
0326       array[i] = 0;
0327       data[i] = 0;
0328     }
0329   }
0330   ~HotPixels() {}
0331   void update(int channel, int roc, int dcol, int pix);
0332   int code(int channel, int roc, int dcol, int pix);
0333   void decode(int index, int &channel, int &roc, int &dcol, int &pix);
0334   void print(int, int);
0335 
0336 private:
0337   int count;
0338   int array[NumPixels];
0339   int data[NumPixels];
0340 };
0341 
0342 int HotPixels::code(int channel, int roc, int dcol, int pix) {
0343   // pix 0 - 182, dcol 0 - 26 , roc 0 -15, chan 1-36
0344   int index = pix + 1000 * dcol + 100000 * roc + 10000000 * channel;
0345   return index;
0346 }
0347 void HotPixels::decode(int index, int &channel, int &roc, int &dcol, int &pix) {
0348   //int index = pix + 1000 * dcol + 100000 * roc + 10000000 * channel;
0349   channel = index / 10000000;
0350   roc = (index % 10000000) / 100000;
0351   dcol = (index % 100000) / 1000;
0352   pix = (index % 1000);
0353 }
0354 void HotPixels::update(int channel, int roc, int dcol, int pix) {
0355   int index = code(channel, roc, dcol, pix);
0356   //cout<<channel<<"   "<<roc<<"    "<<dcol<<"    "<<pix<<"    "<<index<<endl;
0357   bool found = false;
0358   for (int i = 0; i < count; ++i) {
0359     if (index == array[i]) {
0360       data[i]++;
0361       found = true;
0362       break;
0363     }
0364   }
0365   if (!found) {
0366     if (count >= NumPixels) {
0367       cout << " array too small " << count << " " << endl;
0368     } else {
0369       data[count] = 1;
0370       array[count] = index;
0371       count++;
0372     }
0373   }
0374 }
0375 void HotPixels::print(int events, int fed_id) {
0376   int channel = 0, roc = 0, dcol = 0, pix = 0;
0377   int num = 0;
0378   int cut1 = events / 100;
0379   int cut2 = events / 1000;
0380   int cut3 = events / 10000;
0381 
0382   int cut = events / 1000;
0383   //int cut = 2;
0384   if (cut < 2)
0385     cut = 10;
0386 
0387   if (fed_id == 0) {
0388     cout << " Threshold of " << cut << endl;
0389     cout << "fed chan     module                  tbm roc dcol  pix  colR ";
0390     cout << "rowR count  num roc-local" << endl;
0391   }
0392   for (int i = 0; i < count; ++i) {
0393     if (data[i] > cut1)
0394       count1++;
0395     if (data[i] > cut2)
0396       count2++;
0397     if (data[i] > cut3)
0398       count3++;
0399 
0400     if (data[i] > cut) {
0401       num++;
0402       int index = array[i];
0403       decode(index, channel, roc, dcol, pix);
0404 
0405       // First find if we are in the first or 2nd col of a dcol.
0406       int colEvenOdd = pix % 2;  // module(2), 0-1st sol, 1-2nd col.
0407       // Transform
0408       int colROC = dcol * 2 + colEvenOdd;   // col address, starts from 0
0409       int rowROC = abs(int(pix / 2) - 80);  // row addres, starts from 0
0410       //cout<<index<<" ";
0411 
0412       // Get the module name and tbm type
0413       string modName = " ", tbm = " ";
0414       modName = MyConvert::moduleNameFromFedChan(fed_id, channel, tbm);
0415       int realRocNum = roc;
0416       if (tbm == "B")
0417         realRocNum = roc + 8;  // shift for TBM-N
0418       cout << setw(3) << fed_id << " " << setw(3) << channel << " " << setw(30) << modName << " " << tbm << " "
0419            << setw(3) << realRocNum << "  " << setw(3) << dcol << "  " << setw(3) << pix << "   " << setw(3) << colROC
0420            << "  " << setw(3) << rowROC << "  " << setw(4) << data[i] << "  " << setw(3) << num << "  " << setw(3)
0421            << roc << endl;
0422     }
0423   }
0424   //cout<<num<<" total 'noisy' pixels above the cut = "<<cut<<endl;
0425 }
0426 
0427 /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
0428 // Main program
0429 class findHotPixels : public edm::one::EDAnalyzer<> {
0430 public:
0431   /// ctor
0432   explicit findHotPixels(const edm::ParameterSet &cfg) : theConfig(cfg) {
0433     consumes<FEDRawDataCollection>(theConfig.getUntrackedParameter<std::string>("InputLabel", "source"));
0434   }
0435 
0436   /// dtor
0437   virtual ~findHotPixels() = default;
0438 
0439   void beginJob();
0440 
0441   // end of job
0442   void endJob();
0443 
0444   /// get data, convert to digis attach againe to Event
0445   virtual void analyze(const edm::Event &, const edm::EventSetup &);
0446 
0447 private:
0448   edm::ParameterSet theConfig;
0449   int countEvents, countAllEvents;
0450   float sumPixels, sumFedPixels[40];
0451   HotPixels hotPixels[40];
0452 };
0453 
0454 void findHotPixels::endJob() {
0455   if (countEvents > 0) {
0456     sumPixels /= float(countEvents);
0457     for (int i = 0; i < 40; ++i)
0458       sumFedPixels[i] /= float(countEvents);
0459   }
0460 
0461   cout << " Total/non-empty events " << countAllEvents << " / " << countEvents << " average number of pixels "
0462        << sumPixels << endl;
0463 
0464   //for(int i=0;i<40;++i) cout<<sumFedPixels[i]<<" ";
0465   //cout<<endl;
0466 
0467   for (int i = 0; i < 40; ++i) {
0468     hotPixels[i].print(countAllEvents, i);
0469   }
0470   cout << " Number of noisy pixels: 1% " << count1 << " 0.1% " << count2 << " 0.01% " << count3 << endl;
0471 }
0472 
0473 void findHotPixels::beginJob() {
0474   countEvents = 0;
0475   countAllEvents = 0;
0476   sumPixels = 0.;
0477   for (int i = 0; i < 40; ++i)
0478     sumFedPixels[i] = 0;
0479 }
0480 
0481 void findHotPixels::analyze(const edm::Event &ev, const edm::EventSetup &es) {
0482   edm::Handle<FEDRawDataCollection> buffers;
0483   static std::string label = theConfig.getUntrackedParameter<std::string>("InputLabel", "source");
0484   static std::string instance = theConfig.getUntrackedParameter<std::string>("InputInstance", "");
0485 
0486   ev.getByLabel(label, instance, buffers);
0487 
0488   std::pair<int, int> fedIds(FEDNumbering::MINSiPixelFEDID, FEDNumbering::MAXSiPixelFEDID);
0489 
0490   //PixelDataFormatter formatter(0); // to get digis
0491   //bool dummyErrorBool;
0492 
0493   typedef uint32_t Word32;
0494   typedef uint64_t Word64;
0495   int status = 0;
0496   int countPixels = 0;
0497   int countErrors = 0;
0498   int eventId = -1;
0499   int channel = -1, roc = -1, dcol = -1, pix = -1;
0500 
0501   countAllEvents++;
0502   if (printHeaders)
0503     cout << " Event = " << countEvents << endl;
0504 
0505   //edm::DetSetVector<PixelDigi> collection; // for digis only
0506 
0507   // Loop over FEDs
0508   for (int fedId = fedIds.first; fedId <= fedIds.second; fedId++) {
0509     LogDebug("findHotPixels") << " GET DATA FOR FED: " << fedId;
0510     if (printHeaders)
0511       cout << " For FED = " << fedId << endl;
0512 
0513     PixelDataFormatter::Errors errors;
0514 
0515     //get event data for this fed
0516     const FEDRawData &rawData = buffers->FEDData(fedId);
0517 
0518     int nWords = rawData.size() / sizeof(Word64);
0519     //cout<<" size "<<nWords<<endl;
0520 
0521     // check headers
0522     const Word64 *header = reinterpret_cast<const Word64 *>(rawData.data());
0523     //cout<<hex<<*header<<dec<<endl;
0524     eventId = MyDecode::header(*header, printHeaders);
0525     //if(fedId = fedIds.first)
0526 
0527     const Word64 *trailer = reinterpret_cast<const Word64 *>(rawData.data()) + (nWords - 1);
0528     //cout<<hex<<*trailer<<dec<<endl;
0529     status = MyDecode::trailer(*trailer, printHeaders);
0530 
0531     int countPixelsInFed = 0;
0532     int countErrorsInFed = 0;
0533     // Loop over payload words
0534     for (const Word64 *word = header + 1; word != trailer; word++) {
0535       static const Word64 WORD32_mask = 0xffffffff;
0536       Word32 w1 = *word & WORD32_mask;
0537       status = MyDecode::data(w1, channel, roc, dcol, pix, printData);
0538       if (status > 0) {
0539         countPixels++;
0540         countPixelsInFed++;
0541         hotPixels[fedId].update(channel, roc, dcol, pix);
0542       } else if (status < 0)
0543         countErrorsInFed++;
0544       Word32 w2 = *word >> 32 & WORD32_mask;
0545       status = MyDecode::data(w2, channel, roc, dcol, pix, printData);
0546       if (status > 0) {
0547         countPixels++;
0548         countPixelsInFed++;
0549         hotPixels[fedId].update(channel, roc, dcol, pix);
0550       } else if (status < 0)
0551         countErrorsInFed++;
0552       //cout<<hex<<w1<<" "<<w2<<dec<<endl;
0553     }  // loop over words
0554 
0555     countErrors += countErrorsInFed;
0556 
0557     //convert data to digi (dummy for the moment)
0558     //formatter.interpretRawData( dummyErrorBool, fedId, rawData,  collection, errors);
0559     //cout<<dummyErrorBool<<" "<<digis.size()<<" "<<errors.size()<<endl;
0560 
0561     if (countPixelsInFed > 0) {
0562       sumFedPixels[fedId] += countPixelsInFed;
0563     }
0564 
0565   }  // loop over feds
0566 
0567   if (countPixels > 0) {
0568     cout << "EVENT: " << countEvents << " " << eventId << " pixels " << countPixels << " errors " << countErrors
0569          << endl;
0570     sumPixels += countPixels;
0571     countEvents++;
0572     //int dummy=0;
0573     //cout<<" : ";
0574     //cin>>dummy;
0575   }
0576 }
0577 
0578 #include "FWCore/Framework/interface/MakerMacros.h"
0579 DEFINE_FWK_MODULE(findHotPixels);