CMS 3D CMS Logo

/afs/cern.ch/work/a/aaltunda/public/www/CMSSW_6_2_5/src/L1Trigger/RegionalCaloTrigger/plugins/L1RCTLutWriter.cc

Go to the documentation of this file.
00001 #include "L1Trigger/RegionalCaloTrigger/interface/L1RCTLutWriter.h"
00002 
00003 #include "L1Trigger/RegionalCaloTrigger/interface/L1RCTLookupTables.h"
00004 
00005 #include "CondFormats/L1TObjects/interface/L1RCTParameters.h"
00006 #include "CondFormats/DataRecord/interface/L1RCTParametersRcd.h"
00007 #include "CondFormats/L1TObjects/interface/L1RCTChannelMask.h"
00008 #include "CondFormats/DataRecord/interface/L1RCTChannelMaskRcd.h"
00009 #include "CondFormats/L1TObjects/interface/L1RCTNoisyChannelMask.h"
00010 #include "CondFormats/DataRecord/interface/L1RCTNoisyChannelMaskRcd.h"
00011 
00012 // default scales
00013 #include "CondFormats/DataRecord/interface/L1CaloEcalScaleRcd.h"
00014 #include "CondFormats/L1TObjects/interface/L1CaloEcalScale.h"
00015 #include "CondFormats/DataRecord/interface/L1CaloHcalScaleRcd.h"
00016 #include "CondFormats/L1TObjects/interface/L1CaloHcalScale.h"
00017 
00018 // debug scales
00019 #include "CalibCalorimetry/EcalTPGTools/interface/EcalTPGScale.h"
00020 #include "CalibFormats/CaloTPG/interface/CaloTPGTranscoder.h"
00021 #include "CalibFormats/CaloTPG/interface/CaloTPGRecord.h"
00022 
00023 #include "CondFormats/DataRecord/interface/L1EmEtScaleRcd.h"
00024 #include "CondFormats/L1TObjects/interface/L1CaloEtScale.h"
00025 
00026 //
00027 // constants, enums and typedefs
00028 //
00029 
00030 //
00031 // static data member definitions
00032 //
00033 
00034 //
00035 // constructors and destructor
00036 //
00037 L1RCTLutWriter::L1RCTLutWriter(const edm::ParameterSet& iConfig) :
00038   lookupTable_(new L1RCTLookupTables),
00039   keyName_(iConfig.getParameter<std::string>("key")),
00040   useDebugTpgScales_(iConfig.getParameter<bool>("useDebugTpgScales"))
00041 {
00042    //now do what ever initialization is needed
00043  
00044 }
00045 
00046 
00047 L1RCTLutWriter::~L1RCTLutWriter()
00048 {
00049  
00050    // do anything here that needs to be done at destruction time
00051    // (e.g. close files, deallocate resources etc.)
00052   
00053   if (lookupTable_ != 0) delete lookupTable_;
00054 }
00055 
00056 
00057 //
00058 // member functions
00059 //
00060 
00061 // ------------ method called to for each event  ------------
00062 void
00063 L1RCTLutWriter::analyze(const edm::Event& iEvent, const edm::EventSetup& iSetup)
00064 {
00065    
00066    // get all the configuration information from the event, set it
00067    // in the lookuptable
00068    edm::ESHandle<L1RCTParameters> rctParameters;
00069    iSetup.get<L1RCTParametersRcd>().get(rctParameters);
00070    rctParameters_ = rctParameters.product();
00071    edm::ESHandle<L1CaloEtScale> emScale;
00072    iSetup.get<L1EmEtScaleRcd>().get(emScale);
00073    const L1CaloEtScale* s = emScale.product();
00074 
00075    // make dummy channel mask -- we don't want to mask
00076    // any channels when writing LUTs, that comes afterwards
00077    L1RCTChannelMask* m = new L1RCTChannelMask;
00078    for (int i = 0; i < 18; i++)
00079      {
00080        for (int j = 0; j < 2; j++)
00081          {
00082            for (int k = 0; k < 28; k++)
00083              {
00084                m->ecalMask[i][j][k] = false;
00085                m->hcalMask[i][j][k] = false;
00086              }
00087            for (int k = 0; k < 4; k++)
00088              {
00089                m->hfMask[i][j][k] = false;
00090              }
00091          }
00092      }
00093 
00094 
00095    //Same for Noisy mask
00096    // make dummy channel mask -- we don't want to mask
00097    // any channels when writing LUTs, that comes afterwards
00098    L1RCTNoisyChannelMask* m2 = new L1RCTNoisyChannelMask;
00099    for (int i = 0; i < 18; i++)
00100      {
00101        for (int j = 0; j < 2; j++)
00102          {
00103            for (int k = 0; k < 28; k++)
00104              {
00105                m2->ecalMask[i][j][k] = false;
00106                m2->hcalMask[i][j][k] = false;
00107              }
00108            for (int k = 0; k < 4; k++)
00109              {
00110                m2->hfMask[i][j][k] = false;
00111              }
00112          }
00113      }
00114    m2->ecalThreshold = 0.0;
00115    m2->hcalThreshold = 0.0;
00116    m2->hfThreshold = 0.0;
00117 
00118 
00119    
00120   // use these dummies to get the delete right when using old-style
00121   // scales to create set of L1CaloXcalScales
00122   L1CaloEcalScale* dummyE(0);
00123   L1CaloHcalScale* dummyH(0);
00124 
00125   if (useDebugTpgScales_) // generate new-style scales from tpg scales
00126     {
00127 
00128       std::cout << "Using old-style TPG scales!" << std::endl;
00129 
00130       // old version of hcal energy scale to convert input
00131       edm::ESHandle<CaloTPGTranscoder> transcoder;
00132       iSetup.get<CaloTPGRecord>().get(transcoder);
00133       const CaloTPGTranscoder* h_tpg = transcoder.product();
00134 
00135       // old version of ecal energy scale to convert input
00136       EcalTPGScale* e_tpg = new EcalTPGScale();
00137       e_tpg->setEventSetup(iSetup);
00138 
00139       L1CaloEcalScale* ecalScale = new L1CaloEcalScale();
00140       L1CaloHcalScale* hcalScale = new L1CaloHcalScale();
00141 
00142       // generate L1CaloXcalScales from old-style scales (thanks, werner!)
00143 
00144       // ECAL
00145       for( unsigned short ieta = 1 ; ieta <= L1CaloEcalScale::nBinEta; ++ieta )
00146         {
00147           for( unsigned short irank = 0 ; irank < L1CaloEcalScale::nBinRank; ++irank )
00148             {
00149               EcalSubdetector subdet = ( ieta <= 17 ) ? EcalBarrel : EcalEndcap ;
00150               double etGeVPos =
00151                 e_tpg->getTPGInGeV
00152                 ( irank, EcalTrigTowerDetId(1, // +ve eta
00153                                             subdet,
00154                                             ieta,
00155                                             1 )); // dummy phi value
00156               ecalScale->setBin( irank, ieta, 1, etGeVPos ) ;
00157             }
00158         }
00159       
00160       for( unsigned short ieta = 1 ; ieta <= L1CaloEcalScale::nBinEta; ++ieta )
00161         {
00162           for( unsigned short irank = 0 ; irank < L1CaloEcalScale::nBinRank; ++irank )
00163             {
00164               EcalSubdetector subdet = ( ieta <= 17 ) ? EcalBarrel : EcalEndcap ;
00165               
00166               double etGeVNeg =
00167                 e_tpg->getTPGInGeV
00168                 ( irank,
00169                   EcalTrigTowerDetId(-1, // -ve eta
00170                                      subdet,
00171                                      ieta,
00172                                      2 )); // dummy phi value
00173               ecalScale->setBin( irank, ieta, -1, etGeVNeg ) ;
00174             }
00175         }
00176 
00177       // HCAL
00178       for( unsigned short ieta = 1 ; ieta <= L1CaloHcalScale::nBinEta; ++ieta )
00179         {
00180           for( unsigned short irank = 0 ; irank < L1CaloHcalScale::nBinRank; ++irank )
00181             {
00182               double etGeV = h_tpg->hcaletValue( ieta, irank ) ;
00183 
00184               hcalScale->setBin( irank, ieta, 1, etGeV ) ;
00185               hcalScale->setBin( irank, ieta, -1, etGeV ) ;
00186             }
00187         }
00188 
00189       // set the input scales
00190       lookupTable_->setEcalScale(ecalScale);
00191       lookupTable_->setHcalScale(hcalScale);
00192 
00193       dummyE = ecalScale;
00194       dummyH = hcalScale;
00195 
00196       delete e_tpg;
00197 
00198     }
00199   else
00200     {
00201 
00202       // get energy scale to convert input from ECAL
00203       edm::ESHandle<L1CaloEcalScale> ecalScale;
00204       iSetup.get<L1CaloEcalScaleRcd>().get(ecalScale);
00205       const L1CaloEcalScale* e = ecalScale.product();
00206       
00207       // get energy scale to convert input from HCAL
00208       edm::ESHandle<L1CaloHcalScale> hcalScale;
00209       iSetup.get<L1CaloHcalScaleRcd>().get(hcalScale);
00210       const L1CaloHcalScale* h = hcalScale.product();
00211 
00212       // set scales
00213       lookupTable_->setEcalScale(e);
00214       lookupTable_->setHcalScale(h);
00215 
00216     }
00217 
00218    lookupTable_->setRCTParameters(rctParameters_);
00219    lookupTable_->setChannelMask(m);
00220    lookupTable_->setNoisyChannelMask(m2);
00221    //lookupTable_->setHcalScale(h);
00222    //lookupTable_->setEcalScale(e);
00223    lookupTable_->setL1CaloEtScale(s);
00224 
00225    for (unsigned short nCard = 0; nCard <= 6; nCard = nCard + 2)
00226      {
00227        writeRcLutFile(nCard);
00228        writeEicLutFile(nCard);
00229      }
00230    writeJscLutFile();
00231 
00232    unsigned int eicThreshold = rctParameters_->eicIsolationThreshold();
00233    unsigned int jscThresholdBarrel = rctParameters_->jscQuietThresholdBarrel();
00234    unsigned int jscThresholdEndcap = rctParameters_->jscQuietThresholdEndcap();
00235    writeThresholdsFile(eicThreshold, jscThresholdBarrel, jscThresholdEndcap);
00236 
00237   if (dummyE != 0) delete dummyE;
00238   if (dummyH != 0) delete dummyH;
00239 
00240 }
00241 
00242 
00243 
00244 
00245 // ------------ method called once each job just after ending the event loop  ------------
00246 void 
00247 L1RCTLutWriter::endJob() {
00248 }
00249 
00250 
00251 // ------------ method to write one receiver card lut file
00252 void
00253 L1RCTLutWriter::writeRcLutFile(unsigned short card)
00254 {
00255 
00256   // don't mess yet with name
00257   char filename[256];
00258   char command[64];
00259   if (card != 6)
00260     {
00261       int card2 = card + 1;
00262       sprintf(filename,"RC%i%i-%s.dat",card,card2,keyName_.c_str() );
00263       //sprintf(filename, "RC%i%i.dat", card, card2);
00264     }
00265   else
00266     {
00267       sprintf(filename,"RC6-%s.dat",keyName_.c_str() );
00268       //sprintf(filename, "RC6.dat");
00269     }
00270   // open file for writing, delete any existing content
00271   lutFile_.open(filename, std::ios::trunc);
00272   lutFile_ << "Emulator-parameter generated lut file, card " 
00273            << card << " key " << keyName_ << "   ";
00274 
00275   // close to append timestamp info
00276   lutFile_.close();
00277   sprintf(command, "date >> %s", filename);
00278   system(command);
00279 
00280   // reopen file for writing values
00281   lutFile_.open(filename, std::ios::app);
00282 
00283   unsigned long data = 0;
00284 
00285   // write all memory addresses in increasing order
00286   // address = (1<<22)+(nLUT<<19)+(eG?<18)+(hcalEt<<10)+(ecalfg<<9)+(ecalEt<<1)
00287 
00288   // loop through the physical LUTs on the card, 0-7
00289   for (unsigned short nLUT = 0; nLUT < 8; nLUT++)
00290     {
00291       // determine ieta, iphi, etc. everything
00292       unsigned short iAbsEta = 0;
00293       if (card != 6)
00294         {
00295           iAbsEta = (card/2)*8 + nLUT + 1;
00296         }
00297       else
00298         {
00299           if (nLUT < 4)
00300             {
00301               iAbsEta = (card/2)*8 + nLUT + 1;
00302             }
00303           else
00304             {
00305               iAbsEta = (card/2)*8 + (3 - (nLUT%4) ) + 1;             
00306             }
00307           //std::cout << "LUT is " << nLUT << " iAbsEta is " << iAbsEta << std::endl;
00308         }
00309 
00310 
00311       // All RCT stuff uniform in phi, symmetric wrt eta = 0
00312 
00313       // below line always gives crate in +eta; makes no difference to us
00314       unsigned short crate = rctParameters_->calcCrate(1, iAbsEta); 
00315       unsigned short tower = rctParameters_->calcTower(1, iAbsEta);
00316 
00317       // first do region sums half of LUTs, bit 18 of address is 0
00318       // loop through 8 bits of hcal energy, 2^8 is 256
00319       for (unsigned int hcalEt = 0; hcalEt < 256; hcalEt++)
00320         {
00321           // loop through 1 bit of ecal fine grain
00322           for (unsigned short ecalfg = 0; ecalfg < 2; ecalfg++)
00323             {
00324               // loop through 8 bits of ecal energy
00325               for (unsigned int ecalEt = 0; ecalEt < 256; ecalEt++)
00326                 {
00327                   // assign 10-bit (9et,1mip) sums data here!
00328                   unsigned long output = lookupTable_->
00329                     lookup(ecalEt, hcalEt, ecalfg, crate, card, tower);
00330                   unsigned short etIn9Bits = (output>>8)&511;
00331                   unsigned short tauActivityBit = (output>>17)&1;
00332                   data = (tauActivityBit<<9)+etIn9Bits;
00333                   lutFile_ << std::hex << data << std::dec << std::endl;
00334                 }
00335             }
00336         }
00337       // second do egamma half of LUTs, bit 18 of address is 1
00338       // loop through 8 bits of hcal energy
00339       for (unsigned int hcalEt = 0; hcalEt < 256; hcalEt++)
00340         {
00341           // loop through 1 bit of ecal fine grain
00342           for (unsigned short ecalfg = 0; ecalfg < 2; ecalfg++)
00343             {
00344               // loop through 8 bits of ecal energy
00345               for (unsigned int ecalEt = 0; ecalEt < 256; ecalEt++)
00346                 {
00347                   // assign 8-bit (7et,1veto) egamma data here!
00348                   unsigned long output = lookupTable_->
00349                     lookup(ecalEt, hcalEt, ecalfg, crate, card, tower);
00350                   unsigned short etIn7Bits = output&127;
00351                   unsigned short heFgVetoBit = (output>>7)&1;
00352                   data = (heFgVetoBit<<7)+etIn7Bits;
00353                   lutFile_ << std::hex << data << std::dec << std::endl;
00354                 }
00355             }
00356         }
00357     }
00358 
00359   lutFile_.close();
00360   return;
00361 
00362 }
00363 
00364 // ------------ method to write one electron isolation card lut file
00365 void
00366 L1RCTLutWriter::writeEicLutFile(unsigned short card)
00367 {
00368   // try timestamp
00369   char filename[256];
00370   char command[64];
00371   if (card != 6)
00372     {
00373       int card2 = card + 1;
00374       sprintf(filename,"EIC%i%i-%s.dat", card, card2, keyName_.c_str() );
00375     }
00376   else
00377     {
00378       sprintf(filename,"EIC6-%s.dat", keyName_.c_str() );
00379     }
00380   // open file for writing, delete any existing content
00381   lutFile_.open(filename, std::ios::trunc);
00382   lutFile_ << "Emulator-parameter generated EIC lut file, card " 
00383            << card << " key " << keyName_ << "   ";
00384   // close to append timestamp info
00385   lutFile_.close();
00386   sprintf(command, "date >> %s", filename);
00387   system(command);
00388 
00389   // reopen file for writing values
00390   lutFile_.open(filename, std::ios::app);
00391 
00392   unsigned long data = 0;
00393 
00394   // write all memory addresses in increasing order
00395   // address = (1<<22) + (etIn7Bits<<1)
00396 
00397   // 2^7 = 0x7f = 128
00398   for (int etIn7Bits = 0; etIn7Bits < 128; etIn7Bits++)
00399     {
00400       data = lookupTable_->emRank(etIn7Bits);
00401       if (data > 0x3f)
00402         {
00403           data = 0x3f;
00404         }
00405       lutFile_ << std::hex << data << std::dec << std::endl;
00406     }
00407   lutFile_.close();
00408   return;
00409 }
00410 
00411 // ------------ method to write one jet summary card lut file
00412 void 
00413 L1RCTLutWriter::writeJscLutFile()
00414 {
00415   char filename[256];
00416   char command[64];
00417   sprintf(filename, "JSC-%s.dat", keyName_.c_str() );
00418 
00419   // open file; if it already existed, delete existing content
00420   lutFile_.open(filename, std::ios::trunc);
00421   lutFile_ << "Emulator parameter-generated lut file, key " << keyName_ 
00422            << "   ";
00423   // close to append time-stamp
00424   lutFile_.close();
00425   sprintf(command, "date >> %s", filename);
00426   system(command);
00427   // reopen file for writing
00428   lutFile_.open(filename, std::ios::app);
00429 
00430   unsigned long data = 0;
00431   unsigned long data0 = 0;
00432   unsigned long data1 = 0;
00433 
00434   // write all memory addresses in increasing order
00435   // address = (1<<22) + (lutbits<<17) + (phi1et<<9) + (phi0et<<1);
00436 
00437   // ecl and U93/U225 lut id bits, identify eta segment of hf
00438   for (int lutbits = 0; lutbits < 4; lutbits++)
00439     {
00440       // 8-bit phi_1 et for each eta partition
00441       for (unsigned int phi1et = 0; phi1et < 256; phi1et++)
00442         {
00443           // 8-bit phi_0 et for each eta
00444           for (unsigned int phi0et = 0; phi0et < 256; phi0et++)
00445             {
00446               // lookup takes "(hf_et, crate, card, tower)"
00447               // "card" convention for hf is 999, tower is 0-7
00448               // but equivalent to 0-3 == lutbits
00449               // crate doesn't matter, take 0
00450               // only |ieta| matters
00451               data0 = lookupTable_->lookup(phi0et, 0, 999, lutbits);
00452               if (data0 > 0xff)
00453                 {
00454                   data0 = 0xff;   // 8-bit output energy for each phi region
00455                 }
00456               data1 = lookupTable_->lookup(phi1et, 0, 999, lutbits);
00457               if (data1 > 0xff)
00458                 {
00459                   data1 = 0xff;   // 8-bit output energy for each phi region
00460                 }
00461               data = (data1<<8) + (data0);
00462               lutFile_ << std::hex << data << std::dec << std::endl;
00463               /*
00464               if (phi0et < 10 && phi1et < 10)
00465                 {
00466                   std::cout << "Writer: jsc. lutbits=" << lutbits 
00467                             << " phi0et=" << phi0et << " data0=" << data0
00468                             << " phi1et=" << phi1et << " data1=" << data1
00469                             << std::endl;
00470                 }
00471               */
00472             }
00473         }
00474     }
00475   
00476   lutFile_.close();
00477   return;
00478 }
00479 
00480 //-----------Write text file containing the 1 JSC and 2 EIC thresholds
00481 void
00482 L1RCTLutWriter::writeThresholdsFile(unsigned int eicThreshold, 
00483                                     unsigned int jscThresholdBarrel,
00484                                     unsigned int jscThresholdEndcap)
00485 {
00486   //
00487   std::ofstream thresholdsFile;
00488   char filename[256];
00489   sprintf(filename, "Thresholds-%s.dat", keyName_.c_str() );
00490   thresholdsFile.open(filename, std::ios::trunc);
00491 
00492   thresholdsFile << "key is " << keyName_ << std::endl << std::endl;
00493   thresholdsFile << "eicIsolationThreshold " << eicThreshold << std::endl;
00494   thresholdsFile << "jscQuietThresholdBarrel " << jscThresholdBarrel << std::endl;
00495   thresholdsFile << "jscQuietThresholdEndcap " << jscThresholdEndcap << std::endl;
00496 
00497   thresholdsFile.close();
00498 }
00499 
00500 //define this as a plug-in
00501 //DEFINE_FWK_MODULE(L1RCTLutWriter); // done in SealModule.cc