Back to home page

Project CMSSW displayed by LXR

 
 

    


File indexing completed on 2024-09-07 04:35:07

0001 // -*- C++ -*-
0002 //
0003 // Package:    SiPixelFedFillerWordEventNumber
0004 // Class:      SiPixelFedFillerWordEventNumber
0005 //
0006 /**\class SiPixelFedFillerWordEventNumber  SiPixelFedFillerWordEventNumber .cc FedFillerWords/SiPixelFedFillerWordEventNumber /src/SiPixelFedFillerWordEventNumber .cc
0007    
0008 Description: <one line class summary>
0009 
0010 Implementation:
0011 <Notes on implementation>
0012 */
0013 //
0014 // Original Author:  Andres Carlos FLOREZ B
0015 //         Created:  Thu Jun 26 09:02:02 CEST 2008
0016 //
0017 //
0018 
0019 // system include files
0020 #include <memory>
0021 #include "SiPixelFedFillerWordEventNumber.h"
0022 
0023 //======= constructors and destructor
0024 SiPixelFedFillerWordEventNumber ::SiPixelFedFillerWordEventNumber(const edm::ParameterSet& iConfig) {
0025   SaveFillerWordsbool = iConfig.getParameter<bool>("SaveFillerWords");
0026   label = iConfig.getUntrackedParameter<std::string>("InputLabel", "source");
0027   instance = iConfig.getUntrackedParameter<std::string>("InputInstance", "");
0028   produces<std::vector<uint32_t>>("FillerWordEventNumber1");
0029   produces<std::vector<uint32_t>>("FillerWordEventNumber2");
0030   if (SaveFillerWordsbool == true) {
0031     produces<std::vector<uint32_t>>("SaveFillerWord");
0032   }
0033   consumes<FEDRawDataCollection>(label);
0034 }
0035 
0036 SiPixelFedFillerWordEventNumber ::~SiPixelFedFillerWordEventNumber() {}
0037 unsigned int SiPixelFedFillerWordEventNumber ::CalibStatFillWord(unsigned int totword, int status) {
0038   //===== Variables to get each filler word out of the totword and
0039   //      to conform the last 16 bit filler word if Filler3 is zero.
0040   unsigned int Filler1 = (totword) & 0x000000ff;
0041   unsigned int Filler2 = ((totword) & 0x0000ff00) >> 8;
0042   unsigned int Filler3 = ((totword) & 0x00ff0000) >> 16;
0043   unsigned int Filler4 = ((totword) & 0xffff0000) >> 16;
0044   unsigned int maskFiller4 = ((totword) & 0xff000000) >> 16;
0045   unsigned int Filler14 = (Filler1 & maskFiller4);
0046   unsigned int Filler24 = (Filler2 & maskFiller4);
0047   unsigned int CalibFiller1 = 0;
0048   unsigned int CalibFiller2 = 0;
0049   bool BoolStat = false;
0050   //=====Possible cases for the totword. "CalibFiller1" and "CalibFiller2" take their valur
0051   //     according to the value of the totword.
0052   if ((status == 0x1) || (status == 0x9)) {
0053     CalibFiller1 = Filler1;
0054     if (status == 0x9) {
0055       CalibFiller2 = Filler14;
0056     }
0057   }
0058   if ((status == 0x2) || (status == 0xa)) {
0059     CalibFiller1 = Filler2;
0060     if (status == 0xa) {
0061       CalibFiller2 = Filler24;
0062     }
0063   }
0064   if ((status == 0x4) || (status == 0xc)) {
0065     CalibFiller1 = Filler3;
0066     if (status == 0xc) {
0067       CalibFiller2 = Filler4;
0068     }
0069   }
0070   if (status == 0x8) {
0071     CalibFiller2 = Filler4;
0072   }
0073   if ((status == 0x7) || (status == 0xf)) {
0074     if ((Filler1 == Filler2) && (Filler1 == Filler3) && (Filler2 == Filler3)) {
0075       CalibFiller1 = Filler1;
0076       BoolStat = true;
0077       if (status == 0xf) {
0078         CalibFiller2 = Filler4;
0079       }
0080     } else {
0081       edm::LogError("AnazrFedFillerWords")
0082           << "Status: " << status << "Event ID in Filler words don't match" << '\t' << "Filler1: " << (Filler1 % 256)
0083           << '\t' << "Filler2: " << (Filler2 % 256) << '\t' << "Filler3: " << (Filler3 % 256) << std::endl;
0084     }
0085   }
0086   if ((status == 0x3) || (status == 0xb)) {
0087     if (Filler1 == Filler2) {
0088       CalibFiller1 = Filler1;
0089       BoolStat = true;
0090       if (status == 0xb) {
0091         CalibFiller2 = Filler14;
0092       }
0093     } else {
0094       edm::LogError("AnazrFedFillerWords")
0095           << "Status: " << status << "Event ID in Filler words don't match" << '\t' << "Filler1: " << (Filler1 % 256)
0096           << '\t' << "Filler2: " << (Filler2 % 256) << std::endl;
0097     }
0098   }
0099   if ((status == 0x5) || (status == 0xd)) {
0100     if (Filler1 == Filler3) {
0101       CalibFiller1 = Filler1;
0102       BoolStat = true;
0103       if (status == 0xd) {
0104         CalibFiller2 = Filler4;
0105       }
0106     } else {
0107       edm::LogError("AnazrFedFillerWords")
0108           << "Status: " << status << "Event ID in Filler words don't match" << '\t' << "Filler1: " << (Filler1 % 256)
0109           << '\t' << "Filler3: " << (Filler3 % 256) << std::endl;
0110     }
0111   }
0112   if ((status == 0x6) || (status == 0xe)) {
0113     if (Filler2 == Filler3) {
0114       CalibFiller1 = Filler2;
0115       BoolStat = true;
0116       if (status == 0xe) {
0117         CalibFiller2 = Filler4;
0118       }
0119     } else {
0120       edm::LogError("AnazrFedFillerWords")
0121           << "Status: " << status << "Event ID Filler words don't match" << '\t' << "Filler2: " << (Filler2 % 256)
0122           << '\t' << "Filler3: " << (Filler3 % 256) << std::endl;
0123     }
0124   }
0125   //===== Using the Event number from CMSSW to get a value to compare with the value encoded
0126   //      in the filler words.
0127   unsigned int CalibEvtNum = ((EventNum - 1) / 10);
0128   if ((CalibFiller1 != 0) && (CalibEvtNum != CalibFiller1)) {
0129     edm::LogError("AnazrFedFillerWords") << "Error, Event ID Numbers Don't match---->"
0130                                          << "Filler1 Event ID: " << CalibFiller1 << '\t'
0131                                          << "Run Event ID: " << CalibEvtNum << '\t' << std::endl;
0132   } else if ((CalibFiller1 != 0) && (CalibEvtNum == CalibFiller1)) {
0133     vecFillerWordsEventNumber1.push_back((CalibFiller1 % 256));
0134     edm::LogInfo("AnazrFedFillerWords") << "Filler1 Event ID: " << (CalibFiller1 % 256) << std::endl;
0135   } else if ((CalibFiller2 != 0) && (BoolStat == true)) {
0136     vecFillerWordsEventNumber2.push_back((((CalibFiller2 % 65536) & (0xff00)) >> 8));
0137     edm::LogInfo("AnazrFedFillerWords") << "Filler2 Event ID:" << (((CalibFiller2 % 65536) & (0xff00)) >> 8)
0138                                         << std::endl;
0139   } else if ((CalibFiller2 != 0) && (BoolStat == false)) {
0140     if ((status == 0x9) || (status == 0xa) || (status == 0xc)) {
0141       vecFillerWordsEventNumber2.push_back((((CalibFiller2 % 65536) & (0xff00)) >> 8));
0142       edm::LogInfo("AnazrFedFillerWords")
0143           << "Filler2 Event ID:" << (((CalibFiller2 % 65536) & (0xff00)) >> 8) << std::endl;
0144     } else if (status == 0x8) {
0145       edm::LogError("AnazrFedFillerWords")
0146           << "Status: " << status << " No Filler1 found, is not possible get any Event ID Number" << std::endl;
0147     }
0148   }
0149 
0150   return 0;
0151 }
0152 //========== Function to decode data words ==================================================
0153 int SiPixelFedFillerWordEventNumber ::PwordSlink64(uint64_t* ldata, const int length, uint32_t& totword) {
0154   edm::LogInfo("FedFillerWords") << "Begin of data" << std::endl;
0155 
0156   if ((ldata[0] & 0xf000000000000000LL) != 0x5000000000000000LL)  //header
0157   {
0158     return 0;
0159   }
0160 
0161   //========= analyze the data buffer to find private words ================================
0162   int fif2cnt = 0;
0163   int dumcnt = 0;
0164   int gapcnt = 0;
0165 
0166   uint32_t gap[8];
0167   uint32_t dum[8];
0168   uint32_t word1 = 0;
0169   uint32_t word2 = 0;
0170 
0171   uint32_t chan = 0;
0172   uint32_t roc = 0;
0173 
0174   const uint32_t rocmsk = 0x3e00000;
0175   const uint32_t chnlmsk = 0xfc000000;
0176 
0177   for (int jk = 0; jk < 8; jk++)
0178     gap[jk] = 0;
0179   for (int jk = 0; jk < 8; jk++)
0180     dum[jk] = 0;
0181   totword = 0;
0182   int fifcnt = 1;
0183   for (int kk = 1; kk < length - 1; kk++) {
0184     //======= if statement to make analize just data with the right format ===================
0185     if ((((ldata[kk] & 0xff00000000000000LL) >> 32) == 0xa0000000) &&
0186         (((ldata[kk] & 0xffffff00000000LL) >> 32) == (uint64_t)(kk + 1))) {
0187       break;
0188     }
0189 
0190     word2 = (uint32_t)ldata[kk];
0191     word1 = (uint32_t)(ldata[kk] >> 32);
0192 
0193     //======= 1st word ======================================================================
0194 
0195     chan = ((word1 & chnlmsk) >> 26);
0196     roc = ((word1 & rocmsk) >> 21);
0197 
0198     //======count non-error words
0199     if (roc < 25) {
0200       if (dumcnt > 0) {
0201         dumcnt = 0;
0202       }  //stale dummy!
0203       if ((chan < 5) && (fifcnt != 1)) {
0204         edm::LogError("FedFillerWords") << " error in fifo counting!" << std::endl;
0205       }
0206       if ((chan > 4) && (chan < 10) && (fifcnt != 2)) {
0207         fif2cnt = 0;
0208         fifcnt = 2;
0209       }
0210       if ((chan > 9) && (chan < 14) && (fifcnt != 3)) {
0211         fif2cnt = 0;
0212         fifcnt = 3;
0213       }
0214       if ((chan > 13) && (chan < 19) && (fifcnt != 4)) {
0215         fif2cnt = 0;
0216         fifcnt = 4;
0217       }
0218       if ((chan > 18) && (chan < 23) && (fifcnt != 5)) {
0219         fif2cnt = 0;
0220         fifcnt = 5;
0221       }
0222       if ((chan > 22) && (chan < 28) && (fifcnt != 6)) {
0223         fif2cnt = 0;
0224         fifcnt = 6;
0225       }
0226       if ((chan > 27) && (chan < 32) && (fifcnt != 7)) {
0227         fif2cnt = 0;
0228         fifcnt = 7;
0229       }
0230       if ((chan > 31) && (fifcnt != 8)) {
0231         fif2cnt = 0;
0232         fifcnt = 8;
0233       }
0234       fif2cnt++;
0235     }
0236     //====== Gap Word
0237     if (roc == 26) {
0238       gap[fifcnt - 1] = (0x1000 + (word1 & 0xff));
0239       gapcnt++;
0240     }
0241     //====== Dummy Word
0242     if ((roc == 27) && ((fif2cnt + dumcnt) < 6)) {
0243       dum[fifcnt - 1] = (0x1000 + (word1 & 0xff));
0244       dumcnt++;
0245     } else if ((roc == 27) && ((fif2cnt + dumcnt) > 6)) {
0246       dumcnt = 1;
0247       fif2cnt = 0;
0248       fifcnt++;
0249     }
0250 
0251     //======== 2nd word ============================================================
0252 
0253     chan = ((word2 & chnlmsk) >> 26);
0254     roc = ((word2 & rocmsk) >> 21);
0255 
0256     if (roc < 25) {
0257       if (dumcnt > 0) {
0258         dumcnt = 0;
0259         edm::LogInfo("FedFillerWords") << " ***Stale dummy!" << std::endl;
0260       }  //stale dummy!
0261       if ((chan < 5) && (fifcnt != 1)) {
0262         edm::LogError("FedFillerWords") << " error in fifo counting!" << std::endl;
0263       }
0264       if ((chan > 4) && (chan < 10) && (fifcnt != 2)) {
0265         fif2cnt = 0;
0266         fifcnt = 2;
0267       }
0268       if ((chan > 9) && (chan < 14) && (fifcnt != 3)) {
0269         fif2cnt = 0;
0270         fifcnt = 3;
0271       }
0272       if ((chan > 13) && (chan < 19) && (fifcnt != 4)) {
0273         fif2cnt = 0;
0274         fifcnt = 4;
0275       }
0276       if ((chan > 18) && (chan < 23) && (fifcnt != 5)) {
0277         fif2cnt = 0;
0278         fifcnt = 5;
0279       }
0280       if ((chan > 22) && (chan < 28) && (fifcnt != 6)) {
0281         fif2cnt = 0;
0282         fifcnt = 6;
0283       }
0284       if ((chan > 27) && (chan < 32) && (fifcnt != 7)) {
0285         fif2cnt = 0;
0286         fifcnt = 7;
0287       }
0288       if ((chan > 31) && (fifcnt != 8)) {
0289         fif2cnt = 0;
0290         fifcnt = 8;
0291       }
0292       fif2cnt++;
0293     }
0294     if (roc == 26) {
0295       gap[fifcnt - 1] = (0x1000 + (word2 & 0xff));
0296       gapcnt++;
0297     }
0298     if ((roc == 27) && ((fif2cnt + dumcnt) < 6)) {
0299       dum[fifcnt - 1] = (0x1000 + (word1 & 0xff));
0300       dumcnt++;
0301     } else if ((roc == 27) && ((fif2cnt + dumcnt) > 6)) {
0302       dumcnt = 1;
0303       fif2cnt = 0;
0304       fifcnt++;
0305     }
0306 
0307     //word check complete
0308     if (((fif2cnt + dumcnt) == 6) && (dumcnt > 0)) {  //done with this fifo
0309       dumcnt = 0;
0310       fif2cnt = 0;
0311       fifcnt++;
0312     }
0313     if ((gapcnt > 0) && ((dumcnt + fif2cnt) > 5)) {  //done with this fifo
0314       gapcnt = 0;
0315       fifcnt++;
0316       fif2cnt = 0;
0317       dumcnt = 0;
0318     } else if ((gapcnt > 0) && ((dumcnt + fif2cnt) < 6)) {
0319       gapcnt = 0;
0320     }
0321 
0322   }  //==End of fifo-3 word loop
0323   //========== FPGAs Status ==================================================
0324   status = 0;
0325 
0326   if (gap[0] > 0) {
0327     totword = (gap[0] & 0xff);
0328     status = 1;
0329   } else if (gap[1] > 0) {
0330     totword = (gap[1] & 0xff);
0331     status = 1;
0332   } else if (dum[0] > 0) {
0333     totword = (dum[0] & 0xff);
0334     status = 1;
0335   } else if (dum[1] > 0) {
0336     totword = (dum[1] & 0xff);
0337     status = 1;
0338   }
0339 
0340   if (gap[2] > 0) {
0341     totword = totword | ((gap[2] & 0xff) << 8);
0342     status = status | 0x2;
0343   } else if (gap[3] > 0) {
0344     totword = totword | ((gap[3] & 0xff) << 8);
0345     status = status | 0x2;
0346   } else if (dum[2] > 0) {
0347     totword = totword | ((dum[2] & 0xff) << 8);
0348     status = status | 0x2;
0349   } else if (dum[3] > 0) {
0350     totword = totword | ((dum[3] & 0xff) << 8);
0351     status = status | 0x2;
0352   }
0353 
0354   if (gap[4] > 0) {
0355     totword = totword | ((gap[4] & 0xff) << 16);
0356     status = status | 0x4;
0357   } else if (gap[5] > 0) {
0358     totword = totword | ((gap[5] & 0xff) << 16);
0359     status = status | 0x4;
0360   } else if (dum[4] > 0) {
0361     totword = totword | ((dum[4] & 0xff) << 16);
0362     status = status | 0x4;
0363   } else if (dum[5] > 0) {
0364     totword = totword | ((dum[5] & 0xff) << 16);
0365     status = status | 0x4;
0366   }
0367 
0368   if (gap[6] > 0) {
0369     totword = totword | ((gap[6] & 0xff) << 24);
0370     status = status | 0x8;
0371   } else if (gap[7] > 0) {
0372     totword = totword | ((gap[7] & 0xff) << 24);
0373     status = status | 0x8;
0374   } else if (dum[6] > 0) {
0375     totword = totword | ((dum[6] & 0xff) << 24);
0376     status = status | 0x8;
0377   } else if (dum[7] > 0) {
0378     totword = totword | ((dum[7] & 0xff) << 24);
0379     status = status | 0x8;
0380   }
0381   vecSaveFillerWords.push_back(totword);
0382   if ((EventNum % 10) == 0) {
0383     CalibStatFill = CalibStatFillWord(totword, status);
0384   }
0385   edm::LogInfo("FedFillerWords") << "total word = 0x" << std::hex << totword << std::hex << " Status = 0x" << status
0386                                  << std::dec << std::endl;
0387   return (status);
0388 }
0389 
0390 void SiPixelFedFillerWordEventNumber ::produce(edm::Event& iEvent, const edm::EventSetup& iSetup) {
0391   EventNum = iEvent.id().event();
0392   edm::Handle<FEDRawDataCollection> buffers;
0393   iEvent.getByLabel(label, instance, buffers);
0394   auto FillerWordEventNumbers1 = std::make_unique<std::vector<uint32_t>>();
0395   auto FillerWordEventNumbers2 = std::make_unique<std::vector<uint32_t>>();
0396   auto SaveFillerWords = std::make_unique<std::vector<uint32_t>>();
0397   //===== Loop over all the FEDs ========================================================
0398   std::pair<int, int> fedIds;
0399   fedIds.first = 0;
0400   fedIds.second = 39;
0401 
0402   for (int fedId = fedIds.first; fedId <= fedIds.second; fedId++) {
0403     edm::LogInfo("FedFillerWords") << " examining FED: " << fedId << std::endl;
0404     const FEDRawData& fedRawData = buffers->FEDData(fedId);  //get event data for this fed
0405     //======== Run the fill word finder...
0406     if (fedRawData.size() != 0) {
0407       uint32_t totword;
0408       int value = PwordSlink64((uint64_t*)fedRawData.data(), (int)fedRawData.size(), totword);
0409       if (value != 0) {
0410         //====== Verify that the vector is not empty
0411         if (!vecSaveFillerWords.empty()) {
0412           for (vecSaveFillerWords_It = vecSaveFillerWords.begin(); vecSaveFillerWords_It != vecSaveFillerWords.end();
0413                vecSaveFillerWords_It++) {
0414             SaveFillerWords->push_back(*vecSaveFillerWords_It);
0415           }
0416         } else {
0417           edm::LogWarning("FedFillerWords") << "========= Filler Words Vector is empty! ==========" << std::endl;
0418         }
0419       }
0420       edm::LogInfo("FedFillerWords") << "Found " << value << " filler words in FED " << fedId << std::endl;
0421       for (vecFillerWordsEventNumber1_It = vecFillerWordsEventNumber1.begin();
0422            vecFillerWordsEventNumber1_It != vecFillerWordsEventNumber1.end();
0423            vecFillerWordsEventNumber1_It++) {
0424         FillerWordEventNumbers1->push_back(*vecFillerWordsEventNumber1_It);
0425       }
0426       for (vecFillerWordsEventNumber2_It = vecFillerWordsEventNumber2.begin();
0427            vecFillerWordsEventNumber2_It != vecFillerWordsEventNumber2.end();
0428            vecFillerWordsEventNumber2_It++) {
0429         FillerWordEventNumbers2->push_back(*vecFillerWordsEventNumber2_It);
0430       }
0431     }
0432   }
0433   iEvent.put(std::move(FillerWordEventNumbers1), "FillerWordEventNumber1");
0434   iEvent.put(std::move(FillerWordEventNumbers2), "FillerWordEventNumber2");
0435   //====== bool variable to be controled in the config file, allows the user to put or
0436   //       the filler words inside the output root file
0437   if (SaveFillerWordsbool == true) {
0438     iEvent.put(std::move(SaveFillerWords), "SaveFillerWord");
0439   }
0440   vecSaveFillerWords.erase(vecSaveFillerWords.begin(), vecSaveFillerWords.end());
0441   vecFillerWordsEventNumber1.erase(vecFillerWordsEventNumber1.begin(), vecFillerWordsEventNumber1.end());
0442 }
0443 
0444 //===== define this as a plug-in
0445 DEFINE_FWK_MODULE(SiPixelFedFillerWordEventNumber);