Back to home page

Project CMSSW displayed by LXR

 
 

    


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

0001 /*! \file testJetFinalStage.cpp
0002  * \brief Procedural unit-test code for the L1GctJetFinalStage class.
0003  *
0004  *  This is code that tests each public method of the L1GctJetFinalStage
0005  *  class.  It takes data from a file to test the methods against known
0006  *  results.  Results are also output to file to allow debugging.
0007  *
0008  * \author Robert Frazier
0009  * \date March 2006
0010  */
0011 
0012 #include "L1Trigger/GlobalCaloTrigger/interface/L1GctJetFinalStage.h"  //The class to be tested
0013 
0014 //Custom headers needed for this test
0015 #include "DataFormats/L1GlobalCaloTrigger/interface/L1GctJetCand.h"
0016 
0017 #include "L1Trigger/GlobalCaloTrigger/test/produceTrivialCalibrationLut.h"
0018 
0019 #include "L1Trigger/GlobalCaloTrigger/interface/L1GctJet.h"
0020 #include "L1Trigger/GlobalCaloTrigger/interface/L1GctJetFinderBase.h"
0021 #include "L1Trigger/GlobalCaloTrigger/interface/L1GctJetLeafCard.h"
0022 #include "L1Trigger/GlobalCaloTrigger/interface/L1GctWheelJetFpga.h"
0023 #include "L1Trigger/GlobalCaloTrigger/interface/L1GctJetEtCalibrationLut.h"
0024 #include "FWCore/Utilities/interface/Exception.h"
0025 
0026 #include "CondFormats/L1TObjects/interface/L1CaloEtScale.h"
0027 
0028 //Standard library headers
0029 #include <fstream>  //for file IO
0030 #include <string>
0031 #include <vector>
0032 #include <iostream>
0033 #include <exception>  //for exception handling
0034 #include <stdexcept>  //for std::runtime_error()
0035 
0036 using namespace std;
0037 
0038 //Typedefs for the vector templates and other types used
0039 typedef vector<L1GctJetCand> JetsVector;
0040 typedef vector<L1GctJet> RawJetsVector;
0041 typedef unsigned long int ULong;
0042 
0043 typedef L1GctJetFinderBase::lutPtr lutPtr;
0044 typedef L1GctJetFinderBase::lutPtrVector lutPtrVector;
0045 
0046 // Name of the files for test input data and results output.
0047 const string testDataFile = "testJetFinalStageInput.txt";
0048 const string resultsFile = "testJetFinalStageOutput.txt";
0049 
0050 // Global constants to tell the program how many jets to read in from file
0051 // THESE ARE TOTAL GUESSES!
0052 const int numInputJets = 8;   //Num. jets of each type given as input
0053 const int numOutputJets = 4;  //Num. Jets of each type outputted.
0054 
0055 //  FUNCTION PROTOTYPES
0056 /// Runs the test on the L1GctJetFinalStage instance passed into it.
0057 void classTest(L1GctJetFinalStage *myJetFinalStage, const lutPtrVector myLut);
0058 /// Loads test input and also the known results from a file.
0059 void loadTestData(JetsVector &inputCentralJets,
0060                   JetsVector &inputForwardJets,
0061                   JetsVector &inputTauJets,
0062                   JetsVector &trueCentralJets,
0063                   JetsVector &trueForwardJets,
0064                   JetsVector &trueTauJets,
0065                   const lutPtrVector lut);
0066 /// Sanity checks on the data read from file.
0067 bool checkTestData(JetsVector &inputCentralJets,
0068                    JetsVector &inputForwardJets,
0069                    JetsVector &inputTauJets,
0070                    JetsVector &trueCentralJets,
0071                    JetsVector &trueForwardJets,
0072                    JetsVector &trueTauJets);
0073 /// Function to safely open input files of any name, using a referenced return ifstream
0074 void safeOpenInputFile(ifstream &fin, const string name);
0075 /// Function to safely open output files of any name, using a referenced return ofstream
0076 void safeOpenOutputFile(ofstream &fout, const string name);
0077 /// Reads jets from file and pushes the specified number into a vector of jets
0078 void putJetsInVector(ifstream &fin, JetsVector &jets, const int numJets, const lutPtrVector lut);
0079 /// Gets the data of a single jet from the testDataFile (reasonably safely).
0080 L1GctJet readSingleJet(ifstream &fin);
0081 /// Compares JetsVectors, prints a message about the comparison, returns true if identical, else false.
0082 bool compareJetsVectors(JetsVector &vector1, JetsVector &vector2, const string description);
0083 /// Writes out the entire contents of a JetsVector to the given file output stream
0084 void outputJetsVector(ofstream &fout, JetsVector &jets, string description = "Jets");
0085 
0086 /// Entrypoint of unit test code + error handling
0087 int main(int argc, char **argv) {
0088   cout << "\n*************************************" << endl;
0089   cout << "L1GctJetFinalStage class unit tester." << endl;
0090   cout << "*************************************" << endl;
0091 
0092   try {
0093     //Create a whole bunch of objects to allow various other objects
0094     //to be constructed...
0095     //create jet calibration lookup table
0096     produceTrivialCalibrationLut *lutProducer = new produceTrivialCalibrationLut();
0097 
0098     // Instance of the class
0099     lutPtrVector myJetEtCalLut = lutProducer->produce();
0100     delete lutProducer;
0101 
0102     vector<L1GctJetLeafCard *> jetLeafCrds(L1GctWheelJetFpga::MAX_LEAF_CARDS);
0103     for (unsigned i = 0; i < L1GctWheelJetFpga::MAX_LEAF_CARDS; ++i) {
0104       jetLeafCrds[i] = new L1GctJetLeafCard(0, 0);
0105       jetLeafCrds[i]->getJetFinderA()->setJetEtCalibrationLuts(myJetEtCalLut);
0106       jetLeafCrds[i]->getJetFinderB()->setJetEtCalibrationLuts(myJetEtCalLut);
0107       jetLeafCrds[i]->getJetFinderC()->setJetEtCalibrationLuts(myJetEtCalLut);
0108     }
0109 
0110     vector<L1GctWheelJetFpga *> wheelJetFpgas(L1GctJetFinalStage::MAX_WHEEL_FPGAS);
0111     for (unsigned i = 0; i < L1GctJetFinalStage::MAX_WHEEL_FPGAS; ++i) {
0112       wheelJetFpgas[i] = new L1GctWheelJetFpga((int)i, jetLeafCrds);
0113     }
0114 
0115     L1GctJetFinalStage *myJetFinalStage = new L1GctJetFinalStage(wheelJetFpgas);  //TEST OBJECT on heap;
0116     classTest(myJetFinalStage, myJetEtCalLut);                                    //run the test
0117 
0118     //clean up
0119     delete myJetFinalStage;
0120     for (vector<L1GctWheelJetFpga *>::iterator it = wheelJetFpgas.begin(); it != wheelJetFpgas.end(); ++it) {
0121       delete *it;
0122     }
0123     for (vector<L1GctJetLeafCard *>::iterator it = jetLeafCrds.begin(); it != jetLeafCrds.end(); ++it) {
0124       delete *it;
0125     }
0126   } catch (cms::Exception &e) {
0127     if (e.category() == "FileReadError") {
0128       std::cout << "No input file - exiting" << std::endl;
0129     } else {
0130       cerr << e.what() << endl;
0131     }
0132   } catch (...) {
0133     cerr << "\nError! An unknown exception has occurred!" << endl;
0134   }
0135 
0136   return 0;
0137 }
0138 
0139 // Runs the test on the L1GctJetFinalStage passed into it.
0140 void classTest(L1GctJetFinalStage *myJetFinalStage, const lutPtrVector lut) {
0141   bool testPass = true;  //flag to mark test failure
0142 
0143   // Vectors for reading in test data from the text file.
0144   JetsVector inputCentralJets;  //Size?
0145   JetsVector inputForwardJets;  //Size?
0146   JetsVector inputTauJets;      //Size?
0147   JetsVector trueCentralJets;   //Size?
0148   JetsVector trueForwardJets;   //Size?
0149   JetsVector trueTauJets;       //Size?
0150 
0151   // Vectors for receiving the output from the object under test.
0152   JetsVector outputInCentralJets;
0153   JetsVector outputInForwardJets;
0154   JetsVector outputInTauJets;
0155   JetsVector outputCentralJets;
0156   JetsVector outputForwardJets;
0157   JetsVector outputTauJets;
0158 
0159   // Load our test input data and known results
0160   loadTestData(inputCentralJets, inputForwardJets, inputTauJets, trueCentralJets, trueForwardJets, trueTauJets, lut);
0161 
0162   if (checkTestData(inputCentralJets, inputForwardJets, inputTauJets, trueCentralJets, trueForwardJets, trueTauJets)) {
0163     testPass = false;
0164   }
0165 
0166   //Fill the L1GctJetFinalStage with input data. See me care that I'm doing this three times...
0167   for (int i = 0; i < numInputJets; ++i) {
0168     myJetFinalStage->setInputCentralJet(i, inputCentralJets[i]);
0169   }
0170 
0171   for (int i = 0; i < numInputJets; ++i) {
0172     myJetFinalStage->setInputForwardJet(i, inputForwardJets[i]);
0173   }
0174 
0175   for (int i = 0; i < numInputJets; ++i) {
0176     myJetFinalStage->setInputTauJet(i, inputTauJets[i]);
0177   }
0178 
0179   // Test the getInputJets() method
0180   outputInCentralJets = myJetFinalStage->getInputCentralJets();
0181   if (!compareJetsVectors(outputInCentralJets, inputCentralJets, "central jets initial data input/output")) {
0182     testPass = false;
0183   }
0184   outputInForwardJets = myJetFinalStage->getInputForwardJets();
0185   if (!compareJetsVectors(outputInForwardJets, inputForwardJets, "forward jets initial data input/output")) {
0186     testPass = false;
0187   }
0188   outputInTauJets = myJetFinalStage->getInputTauJets();
0189   if (!compareJetsVectors(outputInTauJets, inputTauJets, "tau jets initial data input/output")) {
0190     testPass = false;
0191   }
0192 
0193   myJetFinalStage->process();  //Run algorithm
0194 
0195   //Get the outputted jets and store locally
0196   outputCentralJets = myJetFinalStage->getCentralJets();
0197   outputForwardJets = myJetFinalStage->getForwardJets();
0198   outputTauJets = myJetFinalStage->getTauJets();
0199 
0200   //Test the outputted jets against the known true results
0201   if (!compareJetsVectors(outputCentralJets, trueCentralJets, "central jets")) {
0202     testPass = false;
0203   }
0204   if (!compareJetsVectors(outputForwardJets, trueForwardJets, "forward jets")) {
0205     testPass = false;
0206   }
0207   if (!compareJetsVectors(outputTauJets, trueTauJets, "tau jets")) {
0208     testPass = false;
0209   }
0210 
0211   //Write out all outputtable information to file
0212   cout << "\nWriting results of processing to file " << resultsFile << "..." << endl;
0213   ;
0214   ofstream fout;
0215   safeOpenOutputFile(fout, resultsFile);
0216   outputJetsVector(fout, outputInCentralJets, "Inputted Central Jets");
0217   outputJetsVector(fout, outputInForwardJets, "Inputted Forward Jets");
0218   outputJetsVector(fout, outputInTauJets, "Inputted Tau Jets");
0219   outputJetsVector(fout, outputCentralJets, "Central Jets");
0220   outputJetsVector(fout, outputForwardJets, "Forward Jets");
0221   outputJetsVector(fout, outputTauJets, "Tau Jets");
0222   fout.close();
0223   cout << "Done!" << endl;
0224 
0225   //Run the reset method.
0226   myJetFinalStage->reset();
0227 
0228   //get all the data again - should all be empty
0229   outputInCentralJets = myJetFinalStage->getInputCentralJets();
0230   outputInForwardJets = myJetFinalStage->getInputForwardJets();
0231   outputInTauJets = myJetFinalStage->getInputTauJets();
0232   outputCentralJets = myJetFinalStage->getCentralJets();
0233   outputForwardJets = myJetFinalStage->getForwardJets();
0234   outputTauJets = myJetFinalStage->getTauJets();
0235 
0236   //vectors just for reset comparison
0237   JetsVector empty8JetVec(8);
0238   JetsVector emtpy4JetVec(4);
0239 
0240   //Test that all the outputted vectors are indeed empty
0241   if (!compareJetsVectors(outputInCentralJets, empty8JetVec, "input central jets reset")) {
0242     testPass = false;
0243   }
0244   if (!compareJetsVectors(outputInForwardJets, empty8JetVec, "input forward jets reset")) {
0245     testPass = false;
0246   }
0247   if (!compareJetsVectors(outputInTauJets, empty8JetVec, "input tau jets reset")) {
0248     testPass = false;
0249   }
0250   if (!compareJetsVectors(outputCentralJets, emtpy4JetVec, "output central jets reset")) {
0251     testPass = false;
0252   }
0253   if (!compareJetsVectors(outputForwardJets, emtpy4JetVec, "output forward jets reset")) {
0254     testPass = false;
0255   }
0256   if (!compareJetsVectors(outputTauJets, emtpy4JetVec, "output tau jets reset")) {
0257     testPass = false;
0258   }
0259 
0260   //Print overall results summary to screen
0261   if (testPass) {
0262     cout << "\n*************************************" << endl;
0263     cout << "      Class has passed testing." << endl;
0264     cout << "*************************************" << endl;
0265   } else {
0266     cout << "\n*************************************" << endl;
0267     cout << "      Class has FAILED testing!" << endl;
0268     cout << "*************************************" << endl;
0269   }
0270 
0271   return;
0272 }
0273 
0274 /// Loads test input and also the known results from a file.
0275 void loadTestData(JetsVector &inputCentralJets,
0276                   JetsVector &inputForwardJets,
0277                   JetsVector &inputTauJets,
0278                   JetsVector &trueCentralJets,
0279                   JetsVector &trueForwardJets,
0280                   JetsVector &trueTauJets,
0281                   const lutPtrVector lut) {
0282   // File input stream
0283   ifstream fin;
0284 
0285   safeOpenInputFile(fin, testDataFile);  //open the file
0286 
0287   // Loads the input data, and the correct results of processing from the file
0288   putJetsInVector(fin, inputCentralJets, numInputJets, lut);
0289   putJetsInVector(fin, inputForwardJets, numInputJets, lut);
0290   putJetsInVector(fin, inputTauJets, numInputJets, lut);
0291   putJetsInVector(fin, trueCentralJets, numOutputJets, lut);
0292   putJetsInVector(fin, trueForwardJets, numOutputJets, lut);
0293   putJetsInVector(fin, trueTauJets, numOutputJets, lut);
0294 
0295   fin.close();
0296 
0297   return;
0298 }
0299 
0300 /// Loads test input and also the known results from a file.
0301 bool checkTestData(JetsVector &inputCentralJets,
0302                    JetsVector &inputForwardJets,
0303                    JetsVector &inputTauJets,
0304                    JetsVector &trueCentralJets,
0305                    JetsVector &trueForwardJets,
0306                    JetsVector &trueTauJets) {
0307   bool checkOk = true;
0308 
0309   // Check the data read from file makes sense before we try to use it for testing
0310   JetsVector::const_iterator jet;
0311   for (jet = inputCentralJets.begin(); jet != inputCentralJets.end(); ++jet) {
0312     checkOk &= jet->isCentral();
0313     if (!jet->isCentral() && !jet->empty()) {
0314       cout << "data check fail input Central rank=" << jet->rank() << endl;
0315     }
0316   }
0317   for (jet = inputForwardJets.begin(); jet != inputForwardJets.end(); ++jet) {
0318     checkOk &= jet->isForward();
0319     if (!jet->isForward() && !jet->empty()) {
0320       cout << "data check fail input Forward rank=" << jet->rank() << endl;
0321     }
0322   }
0323   for (jet = inputTauJets.begin(); jet != inputTauJets.end(); ++jet) {
0324     checkOk &= jet->isTau();
0325     if (!jet->isTau() && !jet->empty()) {
0326       cout << "data check fail input Tau rank=" << jet->rank() << endl;
0327     }
0328   }
0329   for (jet = trueCentralJets.begin(); jet != trueCentralJets.end(); ++jet) {
0330     checkOk &= jet->isCentral();
0331     if (!jet->isCentral() && !jet->empty()) {
0332       cout << "data check fail true Central rank=" << jet->rank() << endl;
0333     }
0334   }
0335   for (jet = trueForwardJets.begin(); jet != trueForwardJets.end(); ++jet) {
0336     checkOk &= jet->isForward();
0337     if (!jet->isForward() && !jet->empty()) {
0338       cout << "data check fail true Forward rank=" << jet->rank() << endl;
0339     }
0340   }
0341   for (jet = trueTauJets.begin(); jet != trueTauJets.end(); ++jet) {
0342     checkOk &= jet->isTau();
0343     if (!jet->isTau() && !jet->empty()) {
0344       cout << "data check fail true Tau rank=" << jet->rank() << endl;
0345     }
0346   }
0347   return checkOk;
0348 }
0349 
0350 // Function to safely open input files of any name, using a referenced return ifstream
0351 void safeOpenInputFile(ifstream &fin, const string name) {
0352   //Opens the file
0353   fin.open(name.c_str(), ios::in);
0354 
0355   //Throw an exception if something is wrong
0356   if (!fin.good()) {
0357     throw cms::Exception("FileReadError") << "Couldn't open the file " << name << " for reading!\n";
0358   }
0359   return;
0360 }
0361 
0362 // Function to safely open output files of any name, using a referenced return ofstream
0363 void safeOpenOutputFile(ofstream &fout, const string name) {
0364   //Opens the file
0365   fout.open(name.c_str(), ios::trunc);
0366 
0367   //Throw an exception if something is wrong
0368   if (!fout.good()) {
0369     throw cms::Exception("FileWriteError") << "Couldn't open the file " << name << " for writing!\n";
0370   }
0371   return;
0372 }
0373 
0374 //Reads jets from file and pushes the specified number into a vector of jets
0375 void putJetsInVector(ifstream &fin, JetsVector &jets, const int numJets, const lutPtrVector lut) {
0376   for (int i = 0; i < numJets; ++i) {
0377     L1GctJet tempJet = readSingleJet(fin);
0378     jets.push_back(tempJet.jetCand(lut.at(tempJet.rctEta())));
0379   }
0380 }
0381 
0382 //Gets the data of a single jet from the testDataFile (reasonably safely).
0383 L1GctJet readSingleJet(ifstream &fin) {
0384   //This reperesents how many numbers there are per line for a jet in the input file
0385   const int numJetComponents = 4;  //4 since we have rank, eta, phi & tauVeto.
0386 
0387   ULong jetComponents[numJetComponents];
0388 
0389   //read in the data from the file
0390   for (int i = 0; i < numJetComponents; ++i) {
0391     //check to see if the input stream is still ok first
0392     if (fin.eof() || fin.bad()) {
0393       throw cms::Exception("FileReadError") << "Error reading jet data from " << testDataFile << "!\n";
0394     } else {
0395       fin >> jetComponents[i];  //read in the components.
0396     }
0397   }
0398 
0399   //return object
0400   // Arguments to ctor are: rank, eta, phi, overFlow, forwardJet, tauVeto, bx
0401   L1GctJet tempJet(jetComponents[0],
0402                    jetComponents[1],
0403                    jetComponents[2],
0404                    false,
0405                    ((jetComponents[1] < 4) || (jetComponents[1] >= 18)),
0406                    static_cast<bool>(jetComponents[3]),
0407                    0);
0408 
0409   std::cout << "Read jet " << tempJet << std::endl;
0410   return tempJet;
0411 }
0412 
0413 // Compares JetsVectors, prints a message about the comparison, returns true if identical, else false.
0414 bool compareJetsVectors(JetsVector &vector1, JetsVector &vector2, const string description) {
0415   // vector1 is output from the JetFinalStage
0416   // vector2 is expected based on file input
0417   bool testPass = true;
0418 
0419   if (vector1.size() != vector2.size())  //First check overall size is the same
0420   {
0421     testPass = false;
0422   } else {
0423     if (!vector1.empty())  //Make sure it isn't empty
0424     {
0425       cout << "Number of jets to compare is " << vector1.size() << endl;
0426       //compare the vectors
0427       for (ULong i = 0; i < vector1.size(); ++i) {
0428         cout << "jet1: " << vector1[i] << endl;
0429         cout << "jet2: " << vector2[i] << endl;
0430         if (vector1[i].rank() != vector2[i].rank()) {
0431           cout << "rank fail " << endl;
0432           cout << "found " << vector1[i].rank() << " expected " << vector2[i].rank() << endl;
0433           testPass = false;
0434           break;
0435         }
0436         if ((vector1[i].etaIndex() != vector2[i].etaIndex()) || (vector1[i].etaSign() != vector2[i].etaSign())) {
0437           cout << "eta fail " << endl;
0438           cout << "found " << vector1[i].etaIndex() << " " << vector1[i].etaSign() << " expected "
0439                << vector2[i].etaIndex() << " " << vector2[i].etaSign() << endl;
0440           testPass = false;
0441           break;
0442         }
0443         if (vector1[i].phiIndex() != vector2[i].phiIndex()) {
0444           cout << "phi fail " << endl;
0445           testPass = false;
0446           break;
0447         }
0448         if (vector1[i].isTau() != vector2[i].isTau()) {
0449           cout << "tau fail " << endl;
0450           testPass = false;
0451           break;
0452         }
0453         if (vector1[i].isForward() != vector2[i].isForward()) {
0454           cout << "fwd fail " << endl;
0455           testPass = false;
0456           break;
0457         }
0458       }
0459     }
0460   }
0461 
0462   //Print results to screen
0463   if (testPass == false) {
0464     cout << "\nTest class has FAILED " << description << " comparison!" << endl;
0465     return false;
0466   } else {
0467     cout << "\nTest class has passed " << description << " comparison." << endl;
0468   }
0469   return true;
0470 }
0471 
0472 // Writes out the entire contents of a JetsVector to the given file output stream
0473 void outputJetsVector(ofstream &fout, JetsVector &jets, string description) {
0474   fout << description << endl;  //brief description of the JetsVector content
0475 
0476   if (!jets.empty())  //check it isn't an empty vector
0477   {
0478     for (ULong i = 0; i < jets.size(); ++i) {
0479       fout << jets[i].rank() << "\t" << jets[i].etaIndex() << "\t" << jets[i].etaSign() << "\t" << jets[i].phiIndex()
0480            << "\t" << jets[i].isTau() << "\t" << jets[i].isForward() << endl;
0481     }
0482   }
0483   fout << endl;  //write a blank line to separate data
0484 }