Back to home page

Project CMSSW displayed by LXR

 
 

    


File indexing completed on 2024-04-06 12:20:43

0001 #include <iostream>  // std::cout
0002 #include <fstream>   // std::ofstream
0003 
0004 #include "FWCore/ParameterSet/interface/ParameterSet.h"
0005 #include "FWCore/Framework/interface/stream/EDAnalyzer.h"
0006 #include "FWCore/Framework/interface/ESHandle.h"
0007 #include "FWCore/Framework/interface/EventSetup.h"
0008 #include "FWCore/Framework/interface/MakerMacros.h"
0009 
0010 #include "DataFormats/ForwardDetId/interface/ForwardSubdetector.h"
0011 #include "DataFormats/ForwardDetId/interface/HGCalDetId.h"
0012 #include "DataFormats/ForwardDetId/interface/HGCScintillatorDetId.h"
0013 #include "DataFormats/ForwardDetId/interface/HGCSiliconDetId.h"
0014 #include "DataFormats/ForwardDetId/interface/HFNoseTriggerDetId.h"
0015 #include "DataFormats/ForwardDetId/interface/HGCalTriggerDetId.h"
0016 #include "DataFormats/ForwardDetId/interface/HGCalTriggerModuleDetId.h"
0017 #include "DataFormats/ForwardDetId/interface/HGCalTriggerBackendDetId.h"
0018 
0019 #include "Geometry/Records/interface/CaloGeometryRecord.h"
0020 #include "L1Trigger/L1THGCal/interface/HGCalTriggerGeometryBase.h"
0021 #include "L1Trigger/L1THGCal/interface/HGCalTriggerTools.h"
0022 
0023 #include "L1Trigger/L1THGCal/interface/backend/HGCalStage1TruncationImpl_SA.h"
0024 
0025 #include <nlohmann/json.hpp>
0026 using json = nlohmann::ordered_json;  // using ordered_json for readability
0027 
0028 class HGCalBackendStage1ParameterExtractor : public edm::stream::EDAnalyzer<> {
0029 public:
0030   explicit HGCalBackendStage1ParameterExtractor(const edm::ParameterSet&);
0031   ~HGCalBackendStage1ParameterExtractor();
0032 
0033   virtual void beginRun(const edm::Run&, const edm::EventSetup&);
0034   virtual void analyze(const edm::Event&, const edm::EventSetup&);
0035 
0036 private:
0037   void fillTriggerGeometry(json& json_file);
0038   uint32_t getTCaddress(int& tc_ueta, int& tc_vphi, bool isScint);
0039   uint32_t getRoZBin(double roverz);
0040   uint32_t getPhiBin(uint32_t roverzbin, double phi);
0041   double rotatedphi(double phi, int sector);
0042 
0043   uint32_t getReducedModuleHash(const HGCalTriggerModuleDetId& moduleId);
0044 
0045   HGCalTriggerTools triggerTools_;
0046 
0047   edm::ESHandle<HGCalTriggerGeometryBase> triggerGeometry_;
0048   edm::ESGetToken<HGCalTriggerGeometryBase, CaloGeometryRecord> triggerGeomToken_;
0049 
0050   HGCalStage1TruncationImplSA theAlgo_;
0051 
0052   // Metadata
0053   std::string detector_version_;
0054   int the_fpga_;
0055 
0056   // geometry data
0057   std::vector<uint32_t> disconnected_layers_;
0058   std::string json_mapping_file_;
0059   uint32_t scintillator_trigger_cell_size_;
0060   std::string trigger_geom_;
0061 
0062   // truncation parameters
0063   double roz_min_;
0064   double roz_max_;
0065   uint32_t roz_bins_;
0066   std::vector<uint32_t> max_tcs_per_bins_;
0067   std::vector<double> phi_edges_;
0068 
0069   // TC map parameters:
0070   std::map<std::pair<uint32_t, uint32_t>, uint32_t> tc_coord_uv_;
0071 
0072   // output json name:
0073   std::string outJSONname_;
0074 
0075   typedef std::unordered_map<uint32_t, std::unordered_set<uint32_t>> trigger_map_set;
0076 };
0077 
0078 HGCalBackendStage1ParameterExtractor::HGCalBackendStage1ParameterExtractor(const edm::ParameterSet& conf)
0079     : triggerGeomToken_(esConsumes<HGCalTriggerGeometryBase, CaloGeometryRecord, edm::Transition::BeginRun>())
0080 
0081 {
0082   // get name of output JSON config file
0083   outJSONname_ = conf.getParameter<std::string>("outJSONname");
0084 
0085   // get ID of tested FPGA
0086   the_fpga_ = conf.getParameter<int>("testedFpga");
0087 
0088   // get meta data
0089   const edm::ParameterSet& metaData = conf.getParameterSet("MetaData");
0090   detector_version_ = metaData.getParameter<std::string>("geometryVersion");
0091 
0092   // get geometry configuration
0093   const edm::ParameterSet& triggerGeom = conf.getParameterSet("TriggerGeometryParam");
0094   disconnected_layers_ = triggerGeom.getParameter<std::vector<uint32_t>>("DisconnectedLayers");
0095   json_mapping_file_ = triggerGeom.getParameter<edm::FileInPath>("JsonMappingFile").relativePath();
0096   scintillator_trigger_cell_size_ = triggerGeom.getParameter<uint32_t>("ScintillatorTriggerCellSize");
0097   trigger_geom_ = triggerGeom.getParameter<std::string>("TriggerGeometryName");
0098 
0099   // get TCid -> uv coordinate correspondance
0100   const edm::ParameterSet& TCcoord_uv = conf.getParameterSet("TCcoord_UV");
0101   std::vector<uint32_t> tc_coord_u = TCcoord_uv.getParameter<std::vector<uint32_t>>("TCu");
0102   std::vector<uint32_t> tc_coord_v = TCcoord_uv.getParameter<std::vector<uint32_t>>("TCv");
0103   if (tc_coord_u.size() != tc_coord_v.size())
0104     throw cms::Exception("BadParameter") << "TCu and TCv vectors should be of same size";
0105   for (size_t i = 0; i < tc_coord_u.size(); ++i)
0106     tc_coord_uv_.emplace(std::make_pair(tc_coord_u.at(i), tc_coord_v.at(i)), i);
0107 
0108   // Get truncation parameters
0109   const edm::ParameterSet& truncationParamConfig = conf.getParameterSet("BackendStage1Params");
0110   roz_min_ = truncationParamConfig.getParameter<double>("rozMin");
0111   roz_max_ = truncationParamConfig.getParameter<double>("rozMax");
0112   roz_bins_ = truncationParamConfig.getParameter<uint32_t>("rozBins");
0113 
0114   max_tcs_per_bins_ = truncationParamConfig.getParameter<std::vector<uint32_t>>("maxTcsPerBin");
0115   phi_edges_ = truncationParamConfig.getParameter<std::vector<double>>("phiSectorEdges");
0116 }
0117 
0118 HGCalBackendStage1ParameterExtractor::~HGCalBackendStage1ParameterExtractor() {}
0119 
0120 void HGCalBackendStage1ParameterExtractor::beginRun(const edm::Run& /*run*/, const edm::EventSetup& es) {
0121   triggerGeometry_ = es.getHandle(triggerGeomToken_);
0122   triggerTools_.setGeometry(triggerGeometry_.product());
0123 
0124   json outJSON;
0125 
0126   // fill MetaData
0127   outJSON["MetaData"]["GeometryVersion"] = detector_version_;
0128   outJSON["MetaData"]["fpgaId"] = the_fpga_;
0129 
0130   // fill geometry configuration
0131   outJSON["TriggerGeometryConfig"]["TriggerGeometryName"] = trigger_geom_;
0132   outJSON["TriggerGeometryConfig"]["DisconnectedLayers"] = disconnected_layers_;
0133   outJSON["TriggerGeometryConfig"]["JsonMappingFile"] = json_mapping_file_;
0134   outJSON["TriggerGeometryConfig"]["ScintillatorTriggerCellSize"] = scintillator_trigger_cell_size_;
0135 
0136   // fill truncation parameters
0137   outJSON["TruncationConfig"]["rozMin"] = roz_min_;
0138   outJSON["TruncationConfig"]["rozMax"] = roz_max_;
0139   outJSON["TruncationConfig"]["rozBins"] = roz_bins_;
0140   outJSON["TruncationConfig"]["maxTcsPerBin"] = max_tcs_per_bins_;
0141   outJSON["TruncationConfig"]["phiSectorEdges"] = phi_edges_;
0142 
0143   // fill trigger geometry
0144   fillTriggerGeometry(outJSON);
0145 
0146   // write out JSON file
0147   std::ofstream outputfile(outJSONname_.c_str());
0148   outputfile << std::setw(4) << outJSON << std::endl;
0149 }
0150 
0151 void HGCalBackendStage1ParameterExtractor::fillTriggerGeometry(json& json_file) {
0152   std::unordered_set<uint32_t> trigger_cells;
0153 
0154   // retrieve valid trigger cells
0155   for (const auto& id : triggerGeometry_->eeGeometry()->getValidDetIds()) {
0156     HGCSiliconDetId detid(id);
0157     if (triggerGeometry_->eeTopology().valid(id))
0158       trigger_cells.insert(triggerGeometry_->getTriggerCellFromCell(id));
0159   }
0160   for (const auto& id : triggerGeometry_->hsiGeometry()->getValidDetIds()) {
0161     HGCSiliconDetId detid(id);
0162     if (triggerGeometry_->hsiTopology().valid(id))
0163       trigger_cells.insert(triggerGeometry_->getTriggerCellFromCell(id));
0164   }
0165   for (const auto& id : triggerGeometry_->hscGeometry()->getValidDetIds()) {
0166     trigger_cells.insert(triggerGeometry_->getTriggerCellFromCell(id));
0167   }
0168 
0169   // loop over trigger cells
0170   edm::LogPrint("JSONFilling") << "Filling JSON map";
0171 
0172   //filling tmp json to get TCs per module
0173   json tmp_json;
0174 
0175   for (const auto& triggercell : trigger_cells) {
0176     DetId id(triggercell);
0177     // get module ID and check if relevant module (sector0, zside=1, and connected to FPGA)
0178     uint32_t moduleId = triggerGeometry_->getModuleFromTriggerCell(id);
0179     if (moduleId == 0 || triggerGeometry_->disconnectedModule(moduleId))
0180       continue;
0181     HGCalTriggerModuleDetId tc_module(moduleId);
0182     if (!(tc_module.isHGCalModuleDetId()) || (tc_module.zside() < 0) || (tc_module.sector() != 0))
0183       continue;
0184 
0185     uint32_t moduleHash = getReducedModuleHash(tc_module);
0186     if (moduleHash == 0)
0187       throw cms::Exception("BadModule") << "Invalid module (u/eta,v/phi)";
0188 
0189     // only retrieve mapping for the tested fpga
0190     uint32_t fpgaId = triggerGeometry_->getStage1FpgaFromModule(moduleId);
0191     HGCalTriggerBackendDetId tc_fpga(fpgaId);
0192     if (!(tc_fpga.isStage1FPGA()) || (tc_fpga.sector() != 0) || (tc_fpga.zside() < 0))
0193       continue;
0194     if (tc_fpga.label() != the_fpga_)
0195       continue;
0196 
0197     // retrieve information to be saved
0198     int triggerCellSubdet = 0;
0199     int triggerCellLayer = 0;
0200     int triggerCellUEta = 0;
0201     int triggerCellVPhi = 0;
0202 
0203     bool isScintillatorCell = triggerTools_.isScintillator(id);
0204     if (isScintillatorCell) {
0205       HGCScintillatorDetId id_sc(triggercell);
0206       triggerCellSubdet = id_sc.subdet();
0207       triggerCellLayer = id_sc.layer();
0208       triggerCellUEta = id_sc.ietaAbs();
0209       triggerCellVPhi = id_sc.iphi();
0210     } else {
0211       HGCalTriggerDetId id_si_trig(triggercell);
0212       triggerCellSubdet = id_si_trig.subdet();
0213       triggerCellLayer = id_si_trig.layer();
0214       triggerCellUEta = id_si_trig.triggerCellU();
0215       triggerCellVPhi = id_si_trig.triggerCellV();
0216     }
0217     GlobalPoint position = triggerGeometry_->getTriggerCellPosition(triggercell);
0218     float triggerCellX = position.x();
0219     float triggerCellY = position.y();
0220     float triggerCellZ = position.z();
0221     float triggerCellEta = position.eta();
0222     float triggerCellPhi = position.phi();
0223     float triggerCellRoverZ = sqrt(triggerCellX * triggerCellX + triggerCellY * triggerCellY) / triggerCellZ;
0224 
0225     uint32_t triggerCellRoZBin = theAlgo_.rozBin(triggerCellRoverZ, roz_min_, roz_max_, roz_bins_);
0226     double triggerCellRotatedPhi = theAlgo_.rotatedphi(triggerCellX, triggerCellY, triggerCellZ, tc_fpga.sector());
0227     uint32_t triggerCellPhiBin = theAlgo_.phiBin(triggerCellRoZBin, triggerCellRotatedPhi, phi_edges_);
0228 
0229     uint32_t tcAddress = getTCaddress(triggerCellUEta, triggerCellVPhi, isScintillatorCell);
0230 
0231     // save TC info into JSON
0232     json theTC;
0233     theTC["tcid"] = tcAddress;
0234     theTC["subdet"] = triggerCellSubdet;
0235     theTC["layer"] = triggerCellLayer;
0236     theTC["ueta"] = triggerCellUEta;
0237     theTC["vphi"] = triggerCellVPhi;
0238     theTC["x"] = triggerCellX;
0239     theTC["y"] = triggerCellY;
0240     theTC["z"] = triggerCellZ;
0241     theTC["roz"] = triggerCellRoverZ;
0242     theTC["eta"] = triggerCellEta;
0243     theTC["phi"] = triggerCellPhi;
0244     theTC["roz_bin"] = triggerCellRoZBin;
0245     theTC["phi_bin"] = triggerCellPhiBin;
0246 
0247     std::string strModId = std::to_string(moduleHash);
0248     tmp_json[strModId].push_back(theTC);
0249   }
0250 
0251   // fill output JSON
0252   for (auto& module_json : tmp_json.items()) {
0253     json j1;
0254     j1["hash"] = module_json.key();
0255     j1["tcs"] = module_json.value();
0256     json_file["TriggerCellMap"]["Module"].push_back(j1);
0257   }
0258 }
0259 
0260 uint32_t HGCalBackendStage1ParameterExtractor::getTCaddress(int& tc_ueta, int& tc_vphi, bool isScintillator) {
0261   // transform HGCalHSc TC coordinates to define a TC address in [0,47]
0262   if (isScintillator) {  // HGCalHSc
0263     tc_vphi = (tc_vphi - 1) % 4;
0264     if (tc_ueta > 3) {
0265       if (tc_ueta <= 9) {
0266         tc_ueta = tc_ueta - 4;
0267       } else if (tc_ueta <= 13) {
0268         tc_ueta = tc_ueta - 10;
0269       } else if (tc_ueta <= 17) {
0270         tc_ueta = tc_ueta - 14;
0271       } else {
0272         tc_ueta = tc_ueta - 18;
0273       }
0274     }
0275   }
0276 
0277   // attribute ID to TC according to subdetector
0278   if (isScintillator) {  //HGCalHSc(10)
0279     return (tc_ueta << 2) + tc_vphi;
0280   } else {  //HGCalHSiTrigger(2) or HGCalEE(1)
0281     return tc_coord_uv_.find(std::make_pair(tc_ueta, tc_vphi))->second;
0282   }
0283 }
0284 
0285 uint32_t HGCalBackendStage1ParameterExtractor::getReducedModuleHash(const HGCalTriggerModuleDetId& moduleId) {
0286   uint32_t subdetId = (uint32_t)(triggerTools_.isScintillator(moduleId));
0287   uint32_t layer = triggerTools_.layerWithOffset(moduleId);
0288   int moduleUEta = moduleId.moduleU();  //returns eta if scintillator
0289   int moduleVPhi = moduleId.moduleV();  // returns phi if scintillator
0290   if (moduleUEta < 0 || moduleVPhi < 0)
0291     return 0;
0292 
0293   uint32_t reducedHash = (subdetId << 14) + (layer << 8) + (moduleUEta << 4) + moduleVPhi;
0294 
0295   return reducedHash;
0296 }
0297 
0298 void HGCalBackendStage1ParameterExtractor::analyze(const edm::Event& e, const edm::EventSetup& es) {}
0299 
0300 // define this as a plug-in
0301 DEFINE_FWK_MODULE(HGCalBackendStage1ParameterExtractor);