Back to home page

Project CMSSW displayed by LXR

 
 

    


File indexing completed on 2021-02-14 14:22:11

0001 #include "L1Trigger/GlobalCaloTrigger/test/gctTestFirmware.h"
0002 
0003 #include "FWCore/Utilities/interface/Exception.h"
0004 
0005 #include "L1Trigger/GlobalCaloTrigger/interface/L1GlobalCaloTrigger.h"
0006 #include "L1Trigger/GlobalCaloTrigger/interface/L1GctGlobalEnergyAlgos.h"
0007 #include "L1Trigger/GlobalCaloTrigger/interface/L1GctJetFinderBase.h"
0008 
0009 #include <iostream>
0010 #include <cassert>
0011 
0012 using std::cout;
0013 using std::endl;
0014 using std::vector;
0015 
0016 //=================================================================================================================
0017 //
0018 /// Constructor and destructor
0019 
0020 gctTestFirmware::gctTestFirmware() : jetsFromFile(L1CaloRegionDetId::N_PHI) {}
0021 gctTestFirmware::~gctTestFirmware() {}
0022 
0023 void gctTestFirmware::fillJetsFromFirmware(const std::string& fileName, const int bxStart, const int numOfBx) {
0024   //Open the file
0025   if (!jetsFromFirmwareInputFile.is_open()) {
0026     jetsFromFirmwareInputFile.open(fileName.c_str(), std::ios::in);
0027   }
0028 
0029   //Error message and abandon ship if we can't read the file
0030   if (!jetsFromFirmwareInputFile.good()) {
0031     throw cms::Exception("fileReadError")
0032         << " in gctTestFirmware::checkJetFinder(const L1GlobalCaloTrigger*, const std::string &)\n"
0033         << "Couldn't read data from file " << fileName << "!";
0034   }
0035 
0036   jetsFromFile = getJetsFromFile(bxStart, numOfBx);
0037 }
0038 
0039 //
0040 //=========================================================================
0041 // Here's the procedure for checking the jet finding
0042 //=========================================================================
0043 //
0044 /// Check the jet finder against results from the firmware
0045 bool gctTestFirmware::checkJetFinder(const L1GlobalCaloTrigger* gct) const {
0046   bool testPass = true;
0047   unsigned jf = 0;
0048   for (int jlc = 0; jlc < L1GlobalCaloTrigger::N_JET_LEAF_CARDS; ++jlc) {
0049     testPass &= (jetsFromFile.at(jf++) == gct->getJetLeafCards().at(jlc)->getJetFinderA()->getRawJets());
0050     testPass &= (jetsFromFile.at(jf++) == gct->getJetLeafCards().at(jlc)->getJetFinderB()->getRawJets());
0051     testPass &= (jetsFromFile.at(jf++) == gct->getJetLeafCards().at(jlc)->getJetFinderC()->getRawJets());
0052   }
0053 
0054   // Diagnostics if we've found an error
0055   if (!testPass) {
0056     cout << "checkJetFinder() failed" << endl;
0057     unsigned jf = 0;
0058     for (int jlc = 0; jlc < L1GlobalCaloTrigger::N_JET_LEAF_CARDS; ++jlc) {
0059       for (int i = 0; i < 3; i++) {
0060         JetsVector jetlist1, jetlist2;
0061         cout << "Jet Finder " << jf << endl;
0062         jetlist1 = jetsFromFile.at(jf++);
0063         switch (i) {
0064           case 0:
0065             jetlist2 = gct->getJetLeafCards().at(jlc)->getJetFinderA()->getRawJets();
0066             break;
0067           case 1:
0068             jetlist2 = gct->getJetLeafCards().at(jlc)->getJetFinderB()->getRawJets();
0069             break;
0070           case 2:
0071             jetlist2 = gct->getJetLeafCards().at(jlc)->getJetFinderC()->getRawJets();
0072             break;
0073         }
0074         unsigned numOfBx = jetlist1.size() / L1GctJetFinderBase::MAX_JETS_OUT;
0075         unsigned jj = 0;
0076         for (unsigned i = 0; i < numOfBx; i++) {
0077           cout << "   Bunch crossing " << i;
0078           bool ok = true;
0079           for (unsigned j = 0; j < L1GctJetFinderBase::MAX_JETS_OUT; j++) {
0080             if (jetlist1.at(jj) != jetlist2.at(jj)) {
0081               cout << "\nJet Number " << j;
0082               cout << "\nexpected " << jetlist1.at(jj);
0083               cout << "\nfound    " << jetlist2.at(jj) << endl;
0084               ok = false;
0085             }
0086             ++jj;
0087           }
0088           if (ok) {
0089             cout << " all ok!" << endl;
0090           }
0091         }
0092       }
0093     }
0094   }
0095 
0096   return testPass;
0097 }
0098 
0099 /// Read one event's worth of jets from the file
0100 vector<gctTestFirmware::JetsVector> gctTestFirmware::getJetsFromFile(const int bxStart, const int numOfBx) {
0101   vector<JetsVector> result(L1CaloRegionDetId::N_PHI);
0102   char textFromFile[10];
0103   std::string strFromFile;
0104   unsigned jf, ev;
0105 
0106   int bx = bxStart;
0107   for (int i = 0; i < numOfBx && jetsFromFirmwareInputFile.good(); i++) {
0108     jetsFromFirmwareInputFile.width(10);
0109     jetsFromFirmwareInputFile >> textFromFile;
0110     jetsFromFirmwareInputFile >> ev;
0111     strFromFile = textFromFile;
0112     assert(strFromFile == "Event");
0113     for (unsigned j = 0; j < L1CaloRegionDetId::N_PHI; ++j) {
0114       jetsFromFirmwareInputFile >> textFromFile;
0115       jetsFromFirmwareInputFile >> jf;
0116       strFromFile = textFromFile;
0117       assert((strFromFile == "JetFinder") && (jf == j));
0118       JetsVector temp;
0119       for (unsigned i = 0; i < L1GctJetFinderBase::MAX_JETS_OUT; ++i) {
0120         temp.push_back(nextJetFromFile(jf, bx));
0121       }
0122       // Sort the jets coming from the hardware to match the order from the jetFinderBase
0123       // *** The sort is currently commented. Note that it won't work unless the ***
0124       // *** same et->rank lookup table is used in the test and in the emulator  ***
0125       // sort(temp.begin(), temp.end(), L1GctJet::rankGreaterThan());
0126 
0127       // Shift the jetfinders around in phi
0128       static const unsigned JF_PHI_OFFSET = 1;
0129       static const unsigned JF_NPHI = L1CaloRegionDetId::N_PHI / 2;
0130       unsigned pos = JF_NPHI * (j / JF_NPHI) + (j + JF_PHI_OFFSET) % JF_NPHI;
0131       JetsVector::iterator itr = result.at(pos).end();
0132       result.at(pos).insert(itr, temp.begin(), temp.end());
0133     }
0134     bx++;
0135   }
0136   return result;
0137 }
0138 
0139 /// Read a single jet
0140 L1GctJet gctTestFirmware::nextJetFromFile(const unsigned jf, const int bx) {
0141   unsigned et, eta, phi;
0142   bool of, tv;
0143   jetsFromFirmwareInputFile >> et;
0144   jetsFromFirmwareInputFile >> of;
0145   jetsFromFirmwareInputFile >> tv;
0146   jetsFromFirmwareInputFile >> eta;
0147   jetsFromFirmwareInputFile >> phi;
0148 
0149   // Declare local constants to save typing
0150   const unsigned NE = L1CaloRegionDetId::N_ETA / 2;
0151   const unsigned NP = L1CaloRegionDetId::N_PHI / 2;
0152   // Convert local jetfinder to global coordinates
0153   // Note about phi - the jetfinders are mapped onto
0154   // the RCT crates with jf #0 covering 50-90 degrees
0155   // and jf #8 covering 90-130 degrees
0156   unsigned globalEta = (eta == NE + 1) ? 0 : ((jf < NP) ? (NE - eta) : (NE + eta - 1));
0157   unsigned globalPhi = (eta == NE + 1) ? 0 : ((2 * (NP + 1 - (jf % NP)) + 3 * phi) % (2 * NP));
0158 
0159   L1GctJet temp(et, globalEta, globalPhi, of, (eta > 7), tv);
0160   temp.setBx(bx);
0161   return temp;
0162 }
0163 
0164 /// Analyse calculation of energy sums in firmware
0165 bool gctTestFirmware::checkEnergySumsFromFirmware(const L1GlobalCaloTrigger* gct,
0166                                                   const std::string& fileName,
0167                                                   const int numOfBx) {
0168   bool testPass = true;
0169 
0170   //Open the file
0171   if (!esumsFromFirmwareInputFile.is_open()) {
0172     esumsFromFirmwareInputFile.open(fileName.c_str(), std::ios::in);
0173   }
0174 
0175   //Error message and abandon ship if we can't read the file
0176   if (!esumsFromFirmwareInputFile.good()) {
0177     throw cms::Exception("fileReadError")
0178         << " in gctTestFirmware::checkEnergySumsFromFirmware(const L1GlobalCaloTrigger*, const std::string &)\n"
0179         << "Couldn't read data from file " << fileName << "!";
0180   }
0181 
0182   //Loop reading events from the file (one event per line)
0183   for (int bx = 0; bx < numOfBx; bx++) {
0184     unsigned evno;
0185     unsigned etGct, htGct, magGct, phiGct;
0186     unsigned etEmv, htEmv, magEmv, phiEmv;
0187     int exGct, eyGct;
0188     unsigned magTest, phiTest;
0189 
0190     esumsFromFirmwareInputFile >> evno;
0191     // Values output from the GCT firmware
0192     esumsFromFirmwareInputFile >> etGct;
0193     esumsFromFirmwareInputFile >> htGct;
0194     esumsFromFirmwareInputFile >> magGct;
0195     esumsFromFirmwareInputFile >> phiGct;
0196     // Values output from "procedural VHDL" emulator
0197     esumsFromFirmwareInputFile >> etEmv;
0198     esumsFromFirmwareInputFile >> htEmv;
0199     esumsFromFirmwareInputFile >> magEmv;
0200     esumsFromFirmwareInputFile >> phiEmv;
0201     // Values of ex, ey components input
0202     esumsFromFirmwareInputFile >> exGct;
0203     esumsFromFirmwareInputFile >> eyGct;
0204     // Values of missing Et from VHDL "algorithm-under-test"
0205     esumsFromFirmwareInputFile >> magTest;
0206     esumsFromFirmwareInputFile >> phiTest;
0207 
0208     // Check total Et calculation
0209     if (etGct != etEmv) {
0210       cout << "Reading firmware values from file, et from Gct vhdl " << etGct << " from procedural VHDL " << etEmv
0211            << endl;
0212       testPass = false;
0213     }
0214     if (etGct != gct->getEtSumCollection().at(bx).et()) {
0215       cout << "Checking firmware values from file, et from Gct " << etGct << " from CMSSW "
0216            << gct->getEtSumCollection().at(bx).et() << endl;
0217       testPass = false;
0218     }
0219 
0220     // Ignore ht check against emulator since it depends on the jet calibration
0221     // Just check the two firmware values against each other
0222     if (htGct != htEmv) {
0223       cout << "Reading firmware values from file, ht from Gct vhdl " << htGct << " from procedural VHDL " << htEmv
0224            << endl;
0225       testPass = false;
0226     }
0227 
0228     int exPlus = gct->getEnergyFinalStage()->getInputExValPlusWheel().at(bx).value();
0229     int eyPlus = gct->getEnergyFinalStage()->getInputEyValPlusWheel().at(bx).value();
0230     int exMinus = gct->getEnergyFinalStage()->getInputExVlMinusWheel().at(bx).value();
0231     int eyMinus = gct->getEnergyFinalStage()->getInputEyVlMinusWheel().at(bx).value();
0232 
0233     int exEmu = exPlus + exMinus;
0234     int eyEmu = eyPlus + eyMinus;
0235     if (exGct != exEmu || eyGct != eyEmu) {
0236       cout << "Checking firmware values from file, met components from Gct vhdl " << exGct << " and " << eyGct
0237            << "; from CMSSW " << exEmu << " and " << eyEmu << endl;
0238       testPass = false;
0239     }
0240 
0241     if (magTest != gct->getEtMissCollection().at(bx).et() || phiTest != gct->getEtMissCollection().at(bx).phi()) {
0242       cout << "Checking met calculation, components from vhdl " << exGct << " and " << eyGct << ", result mag "
0243            << magTest << " phi " << phiTest << endl;
0244       cout << "Components from CMSSW " << exEmu << " and " << eyEmu << ", result mag "
0245            << gct->getEtMissCollection().at(bx).et() << " phi " << gct->getEtMissCollection().at(bx).phi() << endl;
0246       testPass = false;
0247     }
0248   }
0249 
0250   return testPass;
0251 }