Back to home page

Project CMSSW displayed by LXR

 
 

    


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

0001 /*! \file testSortAlgo.cpp
0002  * \test file for testing the electron sorter
0003  *
0004  *  This test program reads in dummy data, followed by testing
0005  *  the electron sorter methods are working correctly. 
0006  *  
0007  *
0008  * \author Maria Hansen
0009  * \date March 2006
0010  */
0011 
0012 #include "L1Trigger/GlobalCaloTrigger/interface/L1GctElectronSorter.h"
0013 #include "DataFormats/L1GlobalCaloTrigger/interface/L1GctEmCand.h"
0014 #include "DataFormats/L1CaloTrigger/interface/L1CaloEmCand.h"
0015 #include "FWCore/Utilities/interface/Exception.h"
0016 
0017 //Standard library headers
0018 #include <fstream>  //for file IO
0019 #include <string>
0020 #include <vector>
0021 #include <iostream>
0022 #include <exception>  //for exception handling
0023 #include <stdexcept>  //for std::runtime_error()
0024 
0025 using namespace std;
0026 
0027 //Typedefs and other definitions
0028 typedef vector<L1CaloEmCand> EmInputCandVec;
0029 typedef vector<L1GctEmCand> EmOutputCandVec;
0030 ifstream file;
0031 ofstream ofile;
0032 EmInputCandVec indata;
0033 EmOutputCandVec gctData;
0034 
0035 //  Function for reading in the dummy data
0036 void LoadFileData(const string& inputFile, int electrons, bool isolation);
0037 //Function that outputs a txt file with the output
0038 void WriteFileData(EmOutputCandVec outputs);
0039 //Function to easily output a gctEmCand vector to screen
0040 void print(EmOutputCandVec cands);
0041 
0042 //Function to convert from CaloEmCand to GctEmCand, copied from private method in ElectronSorter
0043 void convertToGct(EmInputCandVec cands);
0044 
0045 int main() {
0046   indata.clear();
0047   gctData.clear();
0048 
0049   cout << "**************************************" << endl;
0050   cout << "  L1GctElectronSorter class unit tester." << endl;
0051   cout << "****************************************" << endl;
0052 
0053   EmInputCandVec inputs;
0054   EmOutputCandVec outputs;
0055   bool checkIn = false;
0056   bool checkOut = false;
0057   bool nInputs = false;
0058   bool nOutputs = false;
0059 
0060   // Number of electrons in sorter
0061   unsigned int noElectrons = 16;
0062   // Name of file with test data
0063   // testElectrons_0 and 9 contain 1 electron iso/non-iso per bunch crossing, split over all cards and region combinations
0064   // testElectrons_1 and 10 contain 0 electrons, all entries are 0
0065   // testElectrons_2 and 11 have energy of electron 0, but still got 4 bits position information
0066   // testElectrons_3 and 12 contain 2 iso/non-iso electrons per bunch crossing
0067   // testElectrons_4 and 13 contain 3 iso/non-iso electrons per bunch crossing
0068   // testElectrons_5 and 14 contain 4 iso/non-iso electrons per bunch crossing
0069   // testElectrons_6 and 15 contain electrons with rank but no position information
0070   // testElectrons_7 and 16 contain electrons with equal energies
0071   // testElectrons_8 and 17 contain electrons with equal energies and phi
0072   // testElectrons_9 and 10 contain electrons with equal energy, phi and rank
0073 
0074   const string testFile = "data/testElectrons_0";
0075 
0076   try {
0077     //Constructor with noElectrons non iso (iso = 0) electron candidates
0078     L1GctElectronSorter* testSort = new L1GctElectronSorter(noElectrons / 4, 1);
0079 
0080     // Check the number of inputs/size of input vector corresponds to the expected value
0081     inputs = testSort->getInputCands();
0082     if (inputs.size() != noElectrons) {
0083       throw cms::Exception("ErrorSizeOfInput")
0084           << "The electronSorter constructor holds the wrong number of inputs" << endl;
0085       nInputs = true;
0086     }
0087 
0088     // Check the number of ouputs/size of output vector corresponds to the expected value
0089     outputs = testSort->getOutputCands();
0090     if (outputs.size() != 4) {
0091       throw cms::Exception("ErrorSizeOfOutput")
0092           << "The size of the output vector in electron sorter is incorrect" << endl;
0093       nOutputs = true;
0094     }
0095 
0096     //Looking at data passed through the sort algorithm
0097     //Load data from file " " and no of electrons and isolation given as in electron sorter constructor
0098     LoadFileData(testFile, noElectrons, 1);
0099     cout << " Data loaded in from input file" << endl;
0100     print(gctData);
0101     for (unsigned int i = 0; i < indata.size(); i++) {
0102       testSort->setInputEmCand(indata[i]);
0103     }
0104     inputs = testSort->getInputCands();
0105 
0106     //This part checks that the data read in is what is stored in the private vector of the sort algorithm
0107     //is the same as what was read in from the data file
0108     for (unsigned int i = 0; i != indata.size(); i++) {
0109       if (indata[i].rank() != inputs[i].rank()) {
0110         throw cms::Exception("ErrorInPrivateVectorRank")
0111             << "Error in data: Discrepancy between Rank in file and input buffer!" << endl;
0112         checkIn = true;
0113       }
0114       if (indata[i].rctRegion() != inputs[i].rctRegion()) {
0115         throw cms::Exception("ErrorInRegion")
0116             << "Error in data:Discrepancy between region in file and input buffer!" << endl;
0117         checkIn = true;
0118       }
0119       if (indata[i].rctCard() != inputs[i].rctCard()) {
0120         throw cms::Exception("ErrorInCard")
0121             << "Error in data:Discrepancy between card in file and input buffer!" << endl;
0122         checkIn = true;
0123       }
0124     }
0125 
0126     //sort the electron candidates by rank
0127     testSort->process();
0128 
0129     //This part checks that the values returned by the getOutput() method are indeed the largest 4 electron candidates sorted by rank
0130     outputs = testSort->getOutputCands();
0131     cout << "Output from sort algorithm: " << endl;
0132     print(outputs);
0133     for (unsigned int n = 0; n != outputs.size(); n++) {
0134       int count = 0;
0135       for (unsigned int i = 0; i != indata.size(); i++) {
0136         if (indata[i].rank() > outputs[n].rank()) {
0137           count = count + 1;
0138           if (n == 0 && count > 1) {
0139             cout << "Error in getOutput method, highest ranking electron candidate isn't returned" << endl;
0140             checkOut = true;
0141           }
0142           if (n == 1 && count > 2) {
0143             cout << "Error in getOutput method, 2nd highest ranking electron candidate isn't returned" << endl;
0144             checkOut = true;
0145           }
0146           if (n == 2 && count > 3) {
0147             cout << "Error in getOutput method, 3rd highest ranking electron candidate isn't returned" << endl;
0148             checkOut = true;
0149           }
0150           if (n == 3 && count > 4) {
0151             cout << "Error in getOutput method, 4th highest ranking electron candidate isn't returned" << endl;
0152             checkOut = true;
0153           }
0154         }
0155       }
0156     }
0157 
0158     if (checkIn) {
0159       cout << "Error: Discrepancy between data read in and data stored as inputs!" << endl;
0160     }
0161     if (checkIn) {
0162       cout << "Error: Discrepancy between the sorted data and data outputted!" << endl;
0163     }
0164     if (nInputs) {
0165       cout << "The number of inputs/size of input vector in electron sorter is incorrect" << endl;
0166     }
0167     if (nOutputs) {
0168       cout << "The number of outputs/size of output vector in electron sorter is incorrect" << endl;
0169     }
0170     if (!nInputs && !nOutputs && !checkIn && !checkOut) {
0171       cout << "============================================" << endl;
0172       cout << " Class ElectronSorter has passed unit tester" << endl;
0173       cout << "============================================" << endl;
0174     }
0175 
0176     WriteFileData(outputs);
0177     delete testSort;
0178 
0179   } catch (cms::Exception& e) {
0180     if (e.category() == "ErrorOpenFile") {
0181       std::cout << "No input file - exiting" << std::endl;
0182     } else {
0183       cerr << e.what() << endl;
0184     }
0185   }
0186   return 0;
0187 }
0188 
0189 // Function definition of function that reads in dummy data and load it into inputCands vector
0190 void LoadFileData(const string& inputFile, int elecs, bool iso) {
0191   //Number of bunch crossings to read in
0192   int bx = elecs / 4;
0193 
0194   //Opens the file
0195   file.open(inputFile.c_str(), ios::in);
0196 
0197   if (!file) {
0198     throw cms::Exception("ErrorOpenFile") << "Cannot open input data file" << endl;
0199   }
0200 
0201   unsigned candRank = 0, candRegion = 0, candCard = 0, candCrate = 0;
0202   short dummy;
0203   string bxNo = "poels";
0204   bool candIso = 0;
0205 
0206   //Reads in first crossing, then crossing no
0207   //then 8 electrons, 4 first is iso, next non iso.
0208   //The 3x14 jet stuff and 8 mip and quiet bits are skipped over.
0209 
0210   for (int n = 0; n < bx; n++) {  //Loop over the bx bunch crossings
0211     file >> bxNo;
0212     file >> std::dec >> dummy;
0213     for (int i = 0; i < 58; i++) {  //Loops over one bunch-crossing
0214       if (i < 8) {
0215         if (i > 3 && iso) {
0216           file >> std::hex >> dummy;
0217           candRank = dummy & 0x3f;
0218           candRegion = (dummy >> 6) & 0x1;
0219           candCard = (dummy >> 7) & 0x7;
0220           candIso = 1;
0221           L1CaloEmCand electrons(candRank, candRegion, candCard, candCrate, candIso);
0222           indata.push_back(electrons);
0223         } else {
0224           if (i < 4 && !iso) {
0225             file >> std::hex >> dummy;
0226             candRank = dummy & 0x3f;
0227             candRegion = (dummy >> 6) & 0x1;
0228             candCard = (dummy >> 7) & 0x7;
0229             candIso = 0;
0230             L1CaloEmCand electrons(candRank, candRegion, candCard, candCrate, candIso);
0231             indata.push_back(electrons);
0232           } else {
0233             file >> dummy;
0234           }
0235         }
0236       } else {
0237         file >> std::hex >> dummy;
0238       }
0239     }
0240   }
0241   file.close();
0242   convertToGct(indata);
0243 
0244   return;
0245 }
0246 
0247 //Function definition, that writes the output to a file
0248 void WriteFileData(EmOutputCandVec outputs) {
0249   EmOutputCandVec writeThis = outputs;
0250   ofile.open("sortOutput.txt", ios::out);
0251   for (unsigned int i = 0; i != writeThis.size(); i++) {
0252     ofile << std::hex << writeThis[i].rank();
0253     ofile << " ";
0254     ofile << std::hex << writeThis[i].etaIndex();
0255     ofile << " ";
0256     ofile << std::hex << writeThis[i].phiIndex();
0257     ofile << "\n";
0258   }
0259   return;
0260 }
0261 
0262 void print(EmOutputCandVec candidates) {
0263   EmOutputCandVec cands = candidates;
0264   for (unsigned int i = 0; i != cands.size(); i++) {
0265     cout << "          Rank: " << cands[i].rank() << "  Eta: " << cands[i].etaIndex()
0266          << "  Phi: " << cands[i].phiIndex() << endl;
0267   }
0268   return;
0269 }
0270 
0271 // Copy of the private function in ElectronSorter to convert a CaloEmCand to a gctEmCand
0272 void convertToGct(EmInputCandVec candidates) {
0273   EmInputCandVec cand = candidates;
0274   for (unsigned int i = 0; i != cand.size(); i++) {
0275     unsigned rank = cand[i].rank();
0276     unsigned card = cand[i].rctCard();
0277     unsigned region = cand[i].rctRegion();
0278     //unsigned crate = cand[i].rctCrate();
0279     //bool sign = (crate<9?-1:1); to be used later when giving sign to phi regions
0280     bool isolation = cand[i].isolated();
0281     unsigned eta = 10;  //initialisation value, outside eta range
0282     unsigned phi = 50;
0283 
0284     switch (card) {
0285       case 0:
0286         phi = 1;
0287         if (region == 0) {
0288           eta = 0;
0289         } else {
0290           eta = 1;
0291         }
0292         break;
0293       case 1:
0294         phi = 1;
0295         if (region == 0) {
0296           eta = 2;
0297         } else {
0298           eta = 3;
0299         }
0300         break;
0301       case 2:
0302         phi = 1;
0303         if (region == 0) {
0304           eta = 4;
0305         } else {
0306           eta = 5;
0307         }
0308         [[fallthrough]];
0309       case 3:
0310         phi = 0;
0311         if (region == 0) {
0312           eta = 0;
0313         } else {
0314           eta = 1;
0315         }
0316         break;
0317       case 4:
0318         phi = 0;
0319         if (region == 0) {
0320           eta = 2;
0321         } else {
0322           eta = 3;
0323         }
0324         [[fallthrough]];
0325       case 5:
0326         phi = 0;
0327         if (region == 0) {
0328           eta = 4;
0329         } else {
0330           eta = 5;
0331         }
0332         break;
0333       case 6:
0334         if (region == 0) {
0335           eta = 6;
0336           phi = 1;
0337         } else {
0338           eta = 6;
0339           phi = 0;
0340         }
0341         break;
0342     }
0343     L1GctEmCand gctTemp(rank, phi, eta, isolation);
0344     gctData.push_back(gctTemp);
0345   }
0346   return;
0347 }