Back to home page

Project CMSSW displayed by LXR

 
 

    


File indexing completed on 2024-04-06 12:21:35

0001 #include "L1Trigger/RegionalCaloTrigger/interface/L1RCTLutWriter.h"
0002 
0003 #include "L1Trigger/RegionalCaloTrigger/interface/L1RCTLookupTables.h"
0004 
0005 #include "CondFormats/DataRecord/interface/L1RCTChannelMaskRcd.h"
0006 #include "CondFormats/DataRecord/interface/L1RCTNoisyChannelMaskRcd.h"
0007 #include "CondFormats/DataRecord/interface/L1RCTParametersRcd.h"
0008 #include "CondFormats/L1TObjects/interface/L1RCTChannelMask.h"
0009 #include "CondFormats/L1TObjects/interface/L1RCTNoisyChannelMask.h"
0010 #include "CondFormats/L1TObjects/interface/L1RCTParameters.h"
0011 
0012 // default scales
0013 #include "CondFormats/DataRecord/interface/L1CaloEcalScaleRcd.h"
0014 #include "CondFormats/DataRecord/interface/L1CaloHcalScaleRcd.h"
0015 #include "CondFormats/L1TObjects/interface/L1CaloEcalScale.h"
0016 #include "CondFormats/L1TObjects/interface/L1CaloHcalScale.h"
0017 
0018 // debug scales
0019 #include "CalibCalorimetry/EcalTPGTools/interface/EcalTPGScale.h"
0020 #include "CalibFormats/CaloTPG/interface/CaloTPGRecord.h"
0021 #include "CalibFormats/CaloTPG/interface/CaloTPGTranscoder.h"
0022 
0023 #include "CondFormats/DataRecord/interface/L1EmEtScaleRcd.h"
0024 #include "CondFormats/L1TObjects/interface/L1CaloEtScale.h"
0025 
0026 //
0027 // constants, enums and typedefs
0028 //
0029 
0030 //
0031 // static data member definitions
0032 //
0033 
0034 //
0035 // constructors and destructor
0036 //
0037 L1RCTLutWriter::L1RCTLutWriter(const edm::ParameterSet &iConfig)
0038     : lookupTable_(new L1RCTLookupTables),
0039       keyName_(iConfig.getParameter<std::string>("key")),
0040       rctParametersToken_(esConsumes<L1RCTParameters, L1RCTParametersRcd>()),
0041       emScaleToken_(esConsumes<L1CaloEtScale, L1EmEtScaleRcd>()),
0042       transcoderToken_(esConsumes<CaloTPGTranscoder, CaloTPGRecord>()),
0043       hcalScaleToken_(esConsumes<L1CaloHcalScale, L1CaloHcalScaleRcd>()),
0044       ecalScaleToken_(esConsumes<L1CaloEcalScale, L1CaloEcalScaleRcd>()),
0045       useDebugTpgScales_(iConfig.getParameter<bool>("useDebugTpgScales")),
0046       tokens_(consumesCollector()) {
0047   // now do what ever initialization is needed
0048 }
0049 
0050 L1RCTLutWriter::~L1RCTLutWriter() {
0051   // do anything here that needs to be done at destruction time
0052   // (e.g. close files, deallocate resources etc.)
0053 
0054   if (lookupTable_ != nullptr)
0055     delete lookupTable_;
0056 }
0057 
0058 //
0059 // member functions
0060 //
0061 
0062 // ------------ method called to for each event  ------------
0063 void L1RCTLutWriter::analyze(const edm::Event &iEvent, const edm::EventSetup &iSetup) {
0064   // get all the configuration information from the event, set it
0065   // in the lookuptable
0066   edm::ESHandle<L1RCTParameters> rctParameters = iSetup.getHandle(rctParametersToken_);
0067   rctParameters_ = rctParameters.product();
0068   edm::ESHandle<L1CaloEtScale> emScale = iSetup.getHandle(emScaleToken_);
0069   const L1CaloEtScale *s = emScale.product();
0070 
0071   // make dummy channel mask -- we don't want to mask
0072   // any channels when writing LUTs, that comes afterwards
0073   L1RCTChannelMask *m = new L1RCTChannelMask;
0074   for (int i = 0; i < 18; i++) {
0075     for (int j = 0; j < 2; j++) {
0076       for (int k = 0; k < 28; k++) {
0077         m->ecalMask[i][j][k] = false;
0078         m->hcalMask[i][j][k] = false;
0079       }
0080       for (int k = 0; k < 4; k++) {
0081         m->hfMask[i][j][k] = false;
0082       }
0083     }
0084   }
0085 
0086   // Same for Noisy mask
0087   // make dummy channel mask -- we don't want to mask
0088   // any channels when writing LUTs, that comes afterwards
0089   L1RCTNoisyChannelMask *m2 = new L1RCTNoisyChannelMask;
0090   for (int i = 0; i < 18; i++) {
0091     for (int j = 0; j < 2; j++) {
0092       for (int k = 0; k < 28; k++) {
0093         m2->ecalMask[i][j][k] = false;
0094         m2->hcalMask[i][j][k] = false;
0095       }
0096       for (int k = 0; k < 4; k++) {
0097         m2->hfMask[i][j][k] = false;
0098       }
0099     }
0100   }
0101   m2->ecalThreshold = 0.0;
0102   m2->hcalThreshold = 0.0;
0103   m2->hfThreshold = 0.0;
0104 
0105   // use these dummies to get the delete right when using old-style
0106   // scales to create set of L1CaloXcalScales
0107   L1CaloEcalScale *dummyE(nullptr);
0108   L1CaloHcalScale *dummyH(nullptr);
0109 
0110   if (useDebugTpgScales_)  // generate new-style scales from tpg scales
0111   {
0112     std::cout << "Using old-style TPG scales!" << std::endl;
0113 
0114     // old version of hcal energy scale to convert input
0115     edm::ESHandle<CaloTPGTranscoder> transcoder = iSetup.getHandle(transcoderToken_);
0116     const CaloTPGTranscoder *h_tpg = transcoder.product();
0117 
0118     // old version of ecal energy scale to convert input
0119     EcalTPGScale e_tpg(tokens_, iSetup);
0120 
0121     L1CaloEcalScale *ecalScale = new L1CaloEcalScale();
0122     L1CaloHcalScale *hcalScale = new L1CaloHcalScale();
0123 
0124     // generate L1CaloXcalScales from old-style scales (thanks, werner!)
0125 
0126     // ECAL
0127     for (unsigned short ieta = 1; ieta <= L1CaloEcalScale::nBinEta; ++ieta) {
0128       for (unsigned short irank = 0; irank < L1CaloEcalScale::nBinRank; ++irank) {
0129         EcalSubdetector subdet = (ieta <= 17) ? EcalBarrel : EcalEndcap;
0130         double etGeVPos = e_tpg.getTPGInGeV(irank,
0131                                             EcalTrigTowerDetId(1,  // +ve eta
0132                                                                subdet,
0133                                                                ieta,
0134                                                                1));  // dummy phi value
0135         ecalScale->setBin(irank, ieta, 1, etGeVPos);
0136       }
0137     }
0138 
0139     for (unsigned short ieta = 1; ieta <= L1CaloEcalScale::nBinEta; ++ieta) {
0140       for (unsigned short irank = 0; irank < L1CaloEcalScale::nBinRank; ++irank) {
0141         EcalSubdetector subdet = (ieta <= 17) ? EcalBarrel : EcalEndcap;
0142 
0143         double etGeVNeg = e_tpg.getTPGInGeV(irank,
0144                                             EcalTrigTowerDetId(-1,  // -ve eta
0145                                                                subdet,
0146                                                                ieta,
0147                                                                2));  // dummy phi value
0148         ecalScale->setBin(irank, ieta, -1, etGeVNeg);
0149       }
0150     }
0151 
0152     // HCAL
0153     for (unsigned short ieta = 1; ieta <= L1CaloHcalScale::nBinEta; ++ieta) {
0154       for (unsigned short irank = 0; irank < L1CaloHcalScale::nBinRank; ++irank) {
0155         double etGeV = h_tpg->hcaletValue(ieta, irank);
0156 
0157         hcalScale->setBin(irank, ieta, 1, etGeV);
0158         hcalScale->setBin(irank, ieta, -1, etGeV);
0159       }
0160     }
0161 
0162     // set the input scales
0163     lookupTable_->setEcalScale(ecalScale);
0164     lookupTable_->setHcalScale(hcalScale);
0165 
0166     dummyE = ecalScale;
0167     dummyH = hcalScale;
0168 
0169   } else {
0170     // get energy scale to convert input from ECAL
0171     edm::ESHandle<L1CaloEcalScale> ecalScale = iSetup.getHandle(ecalScaleToken_);
0172     const L1CaloEcalScale *e = ecalScale.product();
0173 
0174     // get energy scale to convert input from HCAL
0175     edm::ESHandle<L1CaloHcalScale> hcalScale = iSetup.getHandle(hcalScaleToken_);
0176     const L1CaloHcalScale *h = hcalScale.product();
0177 
0178     // set scales
0179     lookupTable_->setEcalScale(e);
0180     lookupTable_->setHcalScale(h);
0181   }
0182 
0183   lookupTable_->setRCTParameters(rctParameters_);
0184   lookupTable_->setChannelMask(m);
0185   lookupTable_->setNoisyChannelMask(m2);
0186   // lookupTable_->setHcalScale(h);
0187   // lookupTable_->setEcalScale(e);
0188   lookupTable_->setL1CaloEtScale(s);
0189 
0190   for (unsigned short nCard = 0; nCard <= 6; nCard = nCard + 2) {
0191     writeRcLutFile(nCard);
0192     writeEicLutFile(nCard);
0193   }
0194   writeJscLutFile();
0195 
0196   unsigned int eicThreshold = rctParameters_->eicIsolationThreshold();
0197   unsigned int jscThresholdBarrel = rctParameters_->jscQuietThresholdBarrel();
0198   unsigned int jscThresholdEndcap = rctParameters_->jscQuietThresholdEndcap();
0199   writeThresholdsFile(eicThreshold, jscThresholdBarrel, jscThresholdEndcap);
0200 
0201   if (dummyE != nullptr)
0202     delete dummyE;
0203   if (dummyH != nullptr)
0204     delete dummyH;
0205 }
0206 
0207 // ------------ method called once each job just after ending the event loop
0208 // ------------
0209 void L1RCTLutWriter::endJob() {}
0210 
0211 // ------------ method to write one receiver card lut file
0212 void L1RCTLutWriter::writeRcLutFile(unsigned short card) {
0213   // don't mess yet with name
0214   char filename[256];
0215   char command[264];
0216   if (card != 6) {
0217     int card2 = card + 1;
0218     sprintf(filename, "RC%i%i-%s.dat", card, card2, keyName_.c_str());
0219     // sprintf(filename, "RC%i%i.dat", card, card2);
0220   } else {
0221     sprintf(filename, "RC6-%s.dat", keyName_.c_str());
0222     // sprintf(filename, "RC6.dat");
0223   }
0224   // open file for writing, delete any existing content
0225   lutFile_.open(filename, std::ios::trunc);
0226   lutFile_ << "Emulator-parameter generated lut file, card " << card << " key " << keyName_ << "   ";
0227 
0228   // close to append timestamp info
0229   lutFile_.close();
0230   sprintf(command, "date >> %s", filename);
0231   system(command);
0232 
0233   // reopen file for writing values
0234   lutFile_.open(filename, std::ios::app);
0235 
0236   unsigned long data = 0;
0237 
0238   // write all memory addresses in increasing order
0239   // address = (1<<22)+(nLUT<<19)+(eG?<18)+(hcalEt<<10)+(ecalfg<<9)+(ecalEt<<1)
0240 
0241   // loop through the physical LUTs on the card, 0-7
0242   for (unsigned short nLUT = 0; nLUT < 8; nLUT++) {
0243     // determine ieta, iphi, etc. everything
0244     unsigned short iAbsEta = 0;
0245     if (card != 6) {
0246       iAbsEta = (card / 2) * 8 + nLUT + 1;
0247     } else {
0248       if (nLUT < 4) {
0249         iAbsEta = (card / 2) * 8 + nLUT + 1;
0250       } else {
0251         iAbsEta = (card / 2) * 8 + (3 - (nLUT % 4)) + 1;
0252       }
0253       // std::cout << "LUT is " << nLUT << " iAbsEta is " << iAbsEta <<
0254       // std::endl;
0255     }
0256 
0257     // All RCT stuff uniform in phi, symmetric wrt eta = 0
0258 
0259     // below line always gives crate in +eta; makes no difference to us
0260     unsigned short crate = rctParameters_->calcCrate(1, iAbsEta);
0261     unsigned short tower = rctParameters_->calcTower(1, iAbsEta);
0262 
0263     // first do region sums half of LUTs, bit 18 of address is 0
0264     // loop through 8 bits of hcal energy, 2^8 is 256
0265     for (unsigned int hcalEt = 0; hcalEt < 256; hcalEt++) {
0266       // loop through 1 bit of ecal fine grain
0267       for (unsigned short ecalfg = 0; ecalfg < 2; ecalfg++) {
0268         // loop through 8 bits of ecal energy
0269         for (unsigned int ecalEt = 0; ecalEt < 256; ecalEt++) {
0270           // assign 10-bit (9et,1mip) sums data here!
0271           unsigned long output = lookupTable_->lookup(ecalEt, hcalEt, ecalfg, crate, card, tower);
0272           unsigned short etIn9Bits = (output >> 8) & 511;
0273           unsigned short tauActivityBit = (output >> 17) & 1;
0274           data = (tauActivityBit << 9) + etIn9Bits;
0275           lutFile_ << std::hex << data << std::dec << std::endl;
0276         }
0277       }
0278     }
0279     // second do egamma half of LUTs, bit 18 of address is 1
0280     // loop through 8 bits of hcal energy
0281     for (unsigned int hcalEt = 0; hcalEt < 256; hcalEt++) {
0282       // loop through 1 bit of ecal fine grain
0283       for (unsigned short ecalfg = 0; ecalfg < 2; ecalfg++) {
0284         // loop through 8 bits of ecal energy
0285         for (unsigned int ecalEt = 0; ecalEt < 256; ecalEt++) {
0286           // assign 8-bit (7et,1veto) egamma data here!
0287           unsigned long output = lookupTable_->lookup(ecalEt, hcalEt, ecalfg, crate, card, tower);
0288           unsigned short etIn7Bits = output & 127;
0289           unsigned short heFgVetoBit = (output >> 7) & 1;
0290           data = (heFgVetoBit << 7) + etIn7Bits;
0291           lutFile_ << std::hex << data << std::dec << std::endl;
0292         }
0293       }
0294     }
0295   }
0296 
0297   lutFile_.close();
0298   return;
0299 }
0300 
0301 // ------------ method to write one electron isolation card lut file
0302 void L1RCTLutWriter::writeEicLutFile(unsigned short card) {
0303   // try timestamp
0304   char filename[256];
0305   char command[264];
0306   if (card != 6) {
0307     int card2 = card + 1;
0308     sprintf(filename, "EIC%i%i-%s.dat", card, card2, keyName_.c_str());
0309   } else {
0310     sprintf(filename, "EIC6-%s.dat", keyName_.c_str());
0311   }
0312   // open file for writing, delete any existing content
0313   lutFile_.open(filename, std::ios::trunc);
0314   lutFile_ << "Emulator-parameter generated EIC lut file, card " << card << " key " << keyName_ << "   ";
0315   // close to append timestamp info
0316   lutFile_.close();
0317   sprintf(command, "date >> %s", filename);
0318   system(command);
0319 
0320   // reopen file for writing values
0321   lutFile_.open(filename, std::ios::app);
0322 
0323   unsigned long data = 0;
0324 
0325   // write all memory addresses in increasing order
0326   // address = (1<<22) + (etIn7Bits<<1)
0327 
0328   // 2^7 = 0x7f = 128
0329   for (int etIn7Bits = 0; etIn7Bits < 128; etIn7Bits++) {
0330     data = lookupTable_->emRank(etIn7Bits);
0331     if (data > 0x3f) {
0332       data = 0x3f;
0333     }
0334     lutFile_ << std::hex << data << std::dec << std::endl;
0335   }
0336   lutFile_.close();
0337   return;
0338 }
0339 
0340 // ------------ method to write one jet summary card lut file
0341 void L1RCTLutWriter::writeJscLutFile() {
0342   char filename[256];
0343   char command[264];
0344   sprintf(filename, "JSC-%s.dat", keyName_.c_str());
0345 
0346   // open file; if it already existed, delete existing content
0347   lutFile_.open(filename, std::ios::trunc);
0348   lutFile_ << "Emulator parameter-generated lut file, key " << keyName_ << "   ";
0349   // close to append time-stamp
0350   lutFile_.close();
0351   sprintf(command, "date >> %s", filename);
0352   system(command);
0353   // reopen file for writing
0354   lutFile_.open(filename, std::ios::app);
0355 
0356   unsigned long data = 0;
0357   unsigned long data0 = 0;
0358   unsigned long data1 = 0;
0359 
0360   // write all memory addresses in increasing order
0361   // address = (1<<22) + (lutbits<<17) + (phi1et<<9) + (phi0et<<1);
0362 
0363   // ecl and U93/U225 lut id bits, identify eta segment of hf
0364   for (int lutbits = 0; lutbits < 4; lutbits++) {
0365     // 8-bit phi_1 et for each eta partition
0366     for (unsigned int phi1et = 0; phi1et < 256; phi1et++) {
0367       // 8-bit phi_0 et for each eta
0368       for (unsigned int phi0et = 0; phi0et < 256; phi0et++) {
0369         // lookup takes "(hf_et, crate, card, tower)"
0370         // "card" convention for hf is 999, tower is 0-7
0371         // but equivalent to 0-3 == lutbits
0372         // crate doesn't matter, take 0
0373         // only |ieta| matters
0374         data0 = lookupTable_->lookup(phi0et, 0, 999, lutbits);
0375         if (data0 > 0xff) {
0376           data0 = 0xff;  // 8-bit output energy for each phi region
0377         }
0378         data1 = lookupTable_->lookup(phi1et, 0, 999, lutbits);
0379         if (data1 > 0xff) {
0380           data1 = 0xff;  // 8-bit output energy for each phi region
0381         }
0382         data = (data1 << 8) + (data0);
0383         lutFile_ << std::hex << data << std::dec << std::endl;
0384         /*
0385         if (phi0et < 10 && phi1et < 10)
0386           {
0387             std::cout << "Writer: jsc. lutbits=" << lutbits
0388                       << " phi0et=" << phi0et << " data0=" << data0
0389                       << " phi1et=" << phi1et << " data1=" << data1
0390                       << std::endl;
0391           }
0392         */
0393       }
0394     }
0395   }
0396 
0397   lutFile_.close();
0398   return;
0399 }
0400 
0401 //-----------Write text file containing the 1 JSC and 2 EIC thresholds
0402 void L1RCTLutWriter::writeThresholdsFile(unsigned int eicThreshold,
0403                                          unsigned int jscThresholdBarrel,
0404                                          unsigned int jscThresholdEndcap) {
0405   //
0406   std::ofstream thresholdsFile;
0407   char filename[256];
0408   sprintf(filename, "Thresholds-%s.dat", keyName_.c_str());
0409   thresholdsFile.open(filename, std::ios::trunc);
0410 
0411   thresholdsFile << "key is " << keyName_ << std::endl << std::endl;
0412   thresholdsFile << "eicIsolationThreshold " << eicThreshold << std::endl;
0413   thresholdsFile << "jscQuietThresholdBarrel " << jscThresholdBarrel << std::endl;
0414   thresholdsFile << "jscQuietThresholdEndcap " << jscThresholdEndcap << std::endl;
0415 
0416   thresholdsFile.close();
0417 }
0418 
0419 // define this as a plug-in
0420 // DEFINE_FWK_MODULE(L1RCTLutWriter); // done in SealModule.cc