Back to home page

Project CMSSW displayed by LXR

 
 

    


File indexing completed on 2022-05-31 22:25:55

0001 // -*- C++ -*-
0002 //
0003 // Package:    L1EmEtScaleOnlineProd
0004 // Class:      L1EmEtScaleOnlineProd
0005 //
0006 /**\class L1EmEtScaleOnlineProd L1EmEtScaleOnlineProd.h L1Trigger/L1EmEtScaleProducers/src/L1EmEtScaleOnlineProd.cc
0007 
0008  Description: <one line class summary>
0009 
0010  Implementation:
0011      <Notes on implementation>
0012 */
0013 //
0014 // Original Author:  Werner Man-Li Sun
0015 //         Created:  Tue Sep 16 22:43:22 CEST 2008
0016 //
0017 //
0018 
0019 // system include files
0020 
0021 // user include files
0022 #include "CondTools/L1Trigger/interface/L1ConfigOnlineProdBase.h"
0023 #include "CondFormats/L1TObjects/interface/L1CaloHcalScale.h"
0024 #include "CondFormats/DataRecord/interface/L1CaloHcalScaleRcd.h"
0025 #include "Geometry/HcalTowerAlgo/interface/HcalTrigTowerGeometry.h"
0026 #include "Geometry/Records/interface/CaloGeometryRecord.h"
0027 #include "CalibCalorimetry/CaloTPG/interface/CaloTPGTranscoderULUT.h"
0028 #include "CondTools/L1Trigger/interface/OMDSReader.h"
0029 #include "FWCore/MessageLogger/interface/MessageLogger.h"
0030 
0031 #include <cmath>
0032 #include <iostream>
0033 #include <iomanip>
0034 
0035 //
0036 // class declaration
0037 //
0038 
0039 class L1CaloHcalScaleConfigOnlineProd : public L1ConfigOnlineProdBase<L1CaloHcalScaleRcd, L1CaloHcalScale> {
0040 public:
0041   L1CaloHcalScaleConfigOnlineProd(const edm::ParameterSet& iConfig);
0042   ~L1CaloHcalScaleConfigOnlineProd() override;
0043 
0044   std::unique_ptr<L1CaloHcalScale> produce(const L1CaloHcalScaleRcd& iRecord) override;
0045 
0046   std::unique_ptr<L1CaloHcalScale> newObject(const std::string& objectKey) override;
0047 
0048 private:
0049   edm::ESGetToken<HcalTrigTowerGeometry, CaloGeometryRecord> theTrigTowerGeometryToken;
0050   const HcalTrigTowerGeometry* theTrigTowerGeometry;
0051   CaloTPGTranscoderULUT* caloTPG;
0052   typedef std::vector<double> RCTdecompression;
0053   std::vector<RCTdecompression> hcaluncomp;
0054 
0055   //  HcaluLUTTPGCoder* tpgCoder;// = new    HcaluLUTTPGCoder();
0056 
0057   HcalTrigTowerDetId* ttDetId;
0058 
0059   // ----------member data ---------------------------
0060 };
0061 
0062 //
0063 // constants, enums and typedefs
0064 //
0065 
0066 //
0067 // static data member definitions
0068 //
0069 
0070 //
0071 // constructors and destructor
0072 //
0073 L1CaloHcalScaleConfigOnlineProd::L1CaloHcalScaleConfigOnlineProd(const edm::ParameterSet& iConfig)
0074     : L1ConfigOnlineProdBase<L1CaloHcalScaleRcd, L1CaloHcalScale>(iConfig), theTrigTowerGeometry(nullptr) {
0075   theTrigTowerGeometryToken = m_consumesCollector->consumes();
0076   caloTPG = new CaloTPGTranscoderULUT();
0077 }
0078 
0079 L1CaloHcalScaleConfigOnlineProd::~L1CaloHcalScaleConfigOnlineProd() {
0080   // do anything here that needs to be done at desctruction time
0081   // (e.g. close files, deallocate resources etc.)
0082 
0083   if (caloTPG != nullptr)
0084     delete caloTPG;
0085 }
0086 
0087 std::unique_ptr<L1CaloHcalScale> L1CaloHcalScaleConfigOnlineProd::newObject(const std::string& objectKey) {
0088   assert(theTrigTowerGeometry != nullptr);
0089 
0090   edm::LogInfo("L1CaloHcalScaleConfigOnlineProd") << "object Key " << objectKey;
0091 
0092   if (objectKey == "NULL" || objectKey.empty()) {  // return default blank ecal scale
0093     return std::make_unique<L1CaloHcalScale>(0);
0094   }
0095   if (objectKey == "IDENTITY") {  // return identity ecal scale
0096     return std::make_unique<L1CaloHcalScale>(1);
0097   }
0098 
0099   std::vector<unsigned int> analyticalLUT(1024, 0);
0100   std::vector<unsigned int> identityLUT(1024, 0);
0101 
0102   // Compute compression LUT
0103   for (unsigned int i = 0; i < 1024; i++) {
0104     analyticalLUT[i] = (unsigned int)(sqrt(14.94 * log(1. + i / 14.94) * i) + 0.5);
0105     identityLUT[i] = std::min(i, 0xffu);
0106   }
0107 
0108   hcaluncomp.clear();
0109   for (int i = 0; i < 4176; i++) {
0110     RCTdecompression decompressionTable(256, 0);
0111     hcaluncomp.push_back(decompressionTable);
0112   }
0113 
0114   std::vector<std::string> mainStrings;
0115   mainStrings.push_back("HCAL_LUT_METADATA");
0116   mainStrings.push_back("HCAL_LUT_CHAN_DATA");
0117 
0118   // ~~~~~~~~~ Cut values ~~~~~~~~~
0119 
0120   std::vector<std::string> metaStrings;
0121   metaStrings.push_back("RCTLSB");
0122   metaStrings.push_back("NOMINAL_GAIN");
0123 
0124   l1t::OMDSReader::QueryResults paramResults =
0125       m_omdsReader.basicQueryView(metaStrings,
0126                                   "CMS_HCL_HCAL_COND",
0127                                   "V_HCAL_LUT_METADATA_V1",
0128                                   "V_HCAL_LUT_METADATA_V1.TAG_NAME",
0129                                   m_omdsReader.basicQuery("HCAL_LUT_METADATA",
0130                                                           "CMS_RCT",
0131                                                           "HCAL_SCALE_KEY",
0132                                                           "HCAL_SCALE_KEY.HCAL_TAG",
0133                                                           m_omdsReader.singleAttribute(objectKey)));
0134 
0135   if (paramResults.queryFailed() || (paramResults.numberRows() != 1))  // check query successful
0136   {
0137     edm::LogError("L1-O2O") << "Problem with L1CaloHcalScale key.  Unable to find lutparam dat table";
0138     return std::unique_ptr<L1CaloHcalScale>();
0139   }
0140 
0141   double hcalLSB, nominal_gain;
0142   paramResults.fillVariable("RCTLSB", hcalLSB);
0143   paramResults.fillVariable("NOMINAL_GAIN", nominal_gain);
0144 
0145   float rctlsb = hcalLSB;
0146 
0147   l1t::OMDSReader::QueryResults chanKey = m_omdsReader.basicQuery("HCAL_LUT_CHAN_DATA",
0148                                                                   "CMS_RCT",
0149                                                                   "HCAL_SCALE_KEY",
0150                                                                   "HCAL_SCALE_KEY.HCAL_TAG",
0151                                                                   m_omdsReader.singleAttribute(objectKey));
0152 
0153   //coral::AttributeList myresult;
0154   //    myresult.extend(
0155 
0156   std::string schemaName("CMS_HCL_HCAL_COND");
0157   coral::ISchema& schema = m_omdsReader.dbSession().coralSession().schema(schemaName);
0158   coral::IQuery* query = schema.newQuery();
0159   ;
0160 
0161   std::vector<std::string> channelStrings;
0162   channelStrings.push_back("IPHI");
0163   channelStrings.push_back("IETA");
0164   channelStrings.push_back("DEPTH");
0165   channelStrings.push_back("LUT_GRANULARITY");
0166   channelStrings.push_back("OUTPUT_LUT_THRESHOLD");
0167   channelStrings.push_back("OBJECTNAME");
0168 
0169   std::vector<std::string>::const_iterator it = channelStrings.begin();
0170   std::vector<std::string>::const_iterator end = channelStrings.end();
0171   for (; it != end; ++it) {
0172     query->addToOutputList(*it);
0173   }
0174 
0175   std::string ob = "OBJECTNAME";
0176   coral::AttributeList myresult;
0177   myresult.extend("IPHI", typeid(int));
0178   myresult.extend("IETA", typeid(int));
0179   myresult.extend("DEPTH", typeid(int));
0180   myresult.extend("LUT_GRANULARITY", typeid(int));
0181   myresult.extend("OUTPUT_LUT_THRESHOLD", typeid(int));
0182   myresult.extend(ob, typeid(std::string));  //, typeid(std::string));
0183 
0184   query->defineOutput(myresult);
0185 
0186   query->addToTableList("V_HCAL_LUT_CHAN_DATA_V1");
0187 
0188   query->setCondition("V_HCAL_LUT_CHAN_DATA_V1.TAG_NAME = :" + chanKey.columnNames().front(),
0189                       chanKey.attributeLists().front());
0190 
0191   coral::ICursor& cursor = query->execute();
0192 
0193   // when the query goes out of scope.
0194   std::vector<coral::AttributeList> atts;
0195   while (cursor.next()) {
0196     atts.push_back(cursor.currentRow());
0197   };
0198 
0199   delete query;
0200 
0201   l1t::OMDSReader::QueryResults chanResults(channelStrings, atts);
0202   if (chanResults.queryFailed() || (chanResults.numberRows() == 0))  // check query successful
0203   {
0204     edm::LogError("L1-O2O") << "Problem with L1CaloHcalScale key.  Unable to find lutparam dat table nrows"
0205                             << chanResults.numberRows();
0206     return std::unique_ptr<L1CaloHcalScale>();
0207   }
0208 
0209   chanResults.attributeLists();
0210   for (int i = 0; i < chanResults.numberRows(); ++i) {
0211     std::string objectName;
0212     chanResults.fillVariableFromRow("OBJECTNAME", i, objectName);
0213     //       int
0214     if (objectName == "HcalTrigTowerDetId") {  //trig tower
0215       int ieta, iphi, depth, lutGranularity, threshold;
0216 
0217       chanResults.fillVariableFromRow("LUT_GRANULARITY", i, lutGranularity);
0218       chanResults.fillVariableFromRow("IPHI", i, iphi);
0219       chanResults.fillVariableFromRow("IETA", i, ieta);
0220       chanResults.fillVariableFromRow("DEPTH", i, depth);
0221       chanResults.fillVariableFromRow("OUTPUT_LUT_THRESHOLD", i, threshold);
0222 
0223       unsigned int outputLut[1024];
0224 
0225       const int tp_version = depth / 10;
0226       uint32_t lutId = caloTPG->getOutputLUTId(ieta, iphi, tp_version);
0227 
0228       double eta_low = 0., eta_high = 0.;
0229       theTrigTowerGeometry->towerEtaBounds(ieta, tp_version, eta_low, eta_high);
0230       double cosh_ieta = fabs(cosh((eta_low + eta_high) / 2.));
0231 
0232       if (!caloTPG->HTvalid(ieta, iphi, tp_version))
0233         continue;
0234       double factor = 0.;
0235       if (abs(ieta) >= theTrigTowerGeometry->firstHFTower(tp_version))
0236         factor = rctlsb;
0237       else
0238         factor = nominal_gain / cosh_ieta * lutGranularity;
0239       for (int k = 0; k < threshold; ++k)
0240         outputLut[k] = 0;
0241 
0242       for (unsigned int k = threshold; k < 1024; ++k)
0243         outputLut[k] = (abs(ieta) < theTrigTowerGeometry->firstHFTower(tp_version)) ? analyticalLUT[k] : identityLUT[k];
0244 
0245       // tpg - compressed value
0246       unsigned int tpg = outputLut[0];
0247 
0248       int low = 0;
0249 
0250       for (unsigned int k = 0; k < 1024; ++k) {
0251         if (outputLut[k] != tpg) {
0252           unsigned int mid = (low + k) / 2;
0253           hcaluncomp[lutId][tpg] = (tpg == 0 ? low : factor * mid);
0254           low = k;
0255           tpg = outputLut[k];
0256         }
0257       }
0258       hcaluncomp[lutId][tpg] = factor * low;
0259     }
0260   }
0261 
0262   auto hcalScale = std::make_unique<L1CaloHcalScale>(0);
0263 
0264   // XXX L1CaloHcalScale is only setup for 2x3 TP
0265   const int tp_version = 0;
0266   for (unsigned short ieta = 1; ieta <= L1CaloHcalScale::nBinEta; ++ieta) {
0267     for (int pos = 0; pos <= 1; pos++) {
0268       for (unsigned short irank = 0; irank < L1CaloHcalScale::nBinRank; ++irank) {
0269         int zside = (int)pow(-1, pos);
0270         int nphi = 0;
0271         double etvalue = 0.;
0272 
0273         for (int iphi = 1; iphi <= 72; iphi++) {
0274           if (!caloTPG->HTvalid(ieta, iphi, tp_version))
0275             continue;
0276           uint32_t lutId = caloTPG->getOutputLUTId(ieta, iphi, tp_version);
0277           nphi++;
0278           etvalue += (double)hcaluncomp[lutId][irank];
0279 
0280         }  // phi
0281         if (nphi > 0)
0282           etvalue /= nphi;
0283 
0284         hcalScale->setBin(irank, ieta, zside, etvalue);
0285 
0286       }  // rank
0287     }    // zside
0288   }      // eta
0289 
0290   std::stringstream s;
0291   s << std::setprecision(10);
0292   hcalScale->print(s);
0293   edm::LogInfo("L1CaloHcalScaleConfigOnlineProd") << s.str();
0294   // ------------ method called to produce the data  ------------
0295   return hcalScale;
0296 }
0297 
0298 std::unique_ptr<L1CaloHcalScale> L1CaloHcalScaleConfigOnlineProd::produce(const L1CaloHcalScaleRcd& iRecord) {
0299   theTrigTowerGeometry = &iRecord.get(theTrigTowerGeometryToken);
0300 
0301   return (L1ConfigOnlineProdBase<L1CaloHcalScaleRcd, L1CaloHcalScale>::produce(iRecord));
0302 }
0303 
0304 //define this as a plug-in
0305 DEFINE_FWK_EVENTSETUP_MODULE(L1CaloHcalScaleConfigOnlineProd);