Back to home page

Project CMSSW displayed by LXR

 
 

    


File indexing completed on 2021-12-06 04:00:40

0001 // -*- C++ -*-
0002 //
0003 // Package:    CondTools/SiPhase2Tracker
0004 // Class:      DTCCablingMapProducer
0005 //
0006 /**\class DTCCablingMapProducer DTCCablingMapProducer.cc CondTools/SiPhase2Tracker/plugins/DTCCablingMapProducer.cc
0007 
0008 Description: [one line class summary]
0009 
0010 Implementation:
0011         [Notes on implementation]
0012 */
0013 //
0014 // Original Author:  Luigi Calligaris, SPRACE, São Paulo, BR
0015 // Created        :  Wed, 27 Feb 2019 21:41:13 GMT
0016 //
0017 //
0018 
0019 #include <memory>
0020 #include <cstdint>
0021 #include <unordered_map>
0022 #include <utility>
0023 
0024 #include "FWCore/Framework/interface/Frameworkfwd.h"
0025 // #include "FWCore/Framework/interface/ESHandle.h"
0026 #include "FWCore/Framework/interface/Event.h"
0027 #include "FWCore/Framework/interface/EventSetup.h"
0028 #include "FWCore/Framework/interface/MakerMacros.h"
0029 #include "FWCore/Framework/interface/one/EDAnalyzer.h"
0030 #include "FWCore/ParameterSet/interface/ParameterSet.h"
0031 #include "FWCore/ServiceRegistry/interface/Service.h"
0032 #include "FWCore/MessageLogger/interface/MessageLogger.h"
0033 
0034 #include "CondCore/DBOutputService/interface/PoolDBOutputService.h"
0035 
0036 #include "CondFormats/Common/interface/Time.h"
0037 #include "CondFormats/DataRecord/interface/TrackerDetToDTCELinkCablingMapRcd.h"
0038 #include "CondFormats/SiPhase2TrackerObjects/interface/TrackerDetToDTCELinkCablingMap.h"
0039 #include "CondFormats/SiPhase2TrackerObjects/interface/DTCELinkId.h"
0040 
0041 //
0042 // CONSTANTS
0043 //
0044 
0045 static constexpr const unsigned int gbt_id_minvalue = 0;
0046 static constexpr const unsigned int gbt_id_maxvalue = 71;
0047 static constexpr const unsigned int elink_id_minvalue = 0;
0048 static constexpr const unsigned int elink_id_maxvalue = 6;
0049 
0050 enum { DUMMY_FILL_DISABLED = 0, DUMMY_FILL_ELINK_ID = 1, DUMMY_FILL_ELINK_ID_AND_GBT_ID = 2 };
0051 
0052 //
0053 // SOME HELPER FUNCTIONS
0054 //
0055 
0056 // trim from start (in place)
0057 static inline void ltrim(std::string& s) {
0058   s.erase(s.begin(), std::find_if(s.begin(), s.end(), [](int ch) { return !std::isspace(ch); }));
0059 }
0060 
0061 // trim from end (in place)
0062 static inline void rtrim(std::string& s) {
0063   s.erase(std::find_if(s.rbegin(), s.rend(), [](int ch) { return !std::isspace(ch); }).base(), s.end());
0064 }
0065 
0066 // trim from both ends (in place)
0067 static inline void trim(std::string& s) {
0068   ltrim(s);
0069   rtrim(s);
0070 }
0071 
0072 class DTCCablingMapProducer : public edm::one::EDAnalyzer<> {
0073 public:
0074   explicit DTCCablingMapProducer(const edm::ParameterSet&);
0075   ~DTCCablingMapProducer() override;
0076 
0077   static void fillDescriptions(edm::ConfigurationDescriptions& descriptions);
0078 
0079 private:
0080   void beginJob() override;
0081   void analyze(const edm::Event&, const edm::EventSetup&) override;
0082   void endJob() override;
0083 
0084   virtual void LoadModulesToDTCCablingMapFromCSV(std::vector<std::string> const&);
0085 
0086 private:
0087   int dummy_fill_mode_;
0088   int verbosity_;
0089   unsigned csvFormat_ncolumns_;
0090   unsigned csvFormat_idetid_;
0091   unsigned csvFormat_idtcid_;
0092   unsigned csvFormat_igbtlinkid_;
0093   unsigned csvFormat_ielinkid_;
0094   cond::Time_t iovBeginTime_;
0095   std::unique_ptr<TrackerDetToDTCELinkCablingMap> pCablingMap_;
0096   std::string record_;
0097 };
0098 
0099 void DTCCablingMapProducer::fillDescriptions(edm::ConfigurationDescriptions& descriptions) {
0100   edm::ParameterSetDescription desc;
0101   desc.setComment("Stores a TrackerDetToDTCELinkCablingMap object into the database from a CSV file.");
0102   desc.add<std::string>("dummy_fill_mode", "DUMMY_FILL_DISABLED");
0103   desc.add<int>("verbosity", 0);
0104   desc.add<unsigned>("csvFormat_ncolumns", 15);
0105   desc.add<unsigned>("csvFormat_idetid", 0);
0106   desc.add<unsigned>("csvFormat_idtcid", 0);
0107   desc.add<unsigned>("csvFormat_igbtlinkid", 0);
0108   desc.add<unsigned>("csvFormat_ielinkid", 0);
0109   desc.add<long long unsigned int>("iovBeginTime", 1);
0110   desc.add<std::string>("record", "TrackerDTCCablingMapRcd");
0111   desc.add<std::vector<std::string>>("modulesToDTCCablingCSVFileNames", std::vector<std::string>());
0112   descriptions.add("DTCCablingMapProducer", desc);
0113 }
0114 
0115 DTCCablingMapProducer::DTCCablingMapProducer(const edm::ParameterSet& iConfig)
0116     : verbosity_(iConfig.getParameter<int>("verbosity")),
0117       csvFormat_ncolumns_(iConfig.getParameter<unsigned>("csvFormat_ncolumns")),
0118       csvFormat_idetid_(iConfig.getParameter<unsigned>("csvFormat_idetid")),
0119       csvFormat_idtcid_(iConfig.getParameter<unsigned>("csvFormat_idtcid")),
0120       csvFormat_igbtlinkid_(iConfig.getParameter<unsigned>("csvFormat_igbtlinkid")),
0121       csvFormat_ielinkid_(iConfig.getParameter<unsigned>("csvFormat_ielinkid")),
0122       iovBeginTime_(iConfig.getParameter<long long unsigned int>("iovBeginTime")),
0123       pCablingMap_(std::make_unique<TrackerDetToDTCELinkCablingMap>()),
0124       record_(iConfig.getParameter<std::string>("record")) {
0125   std::string const dummy_fill_mode_param = iConfig.getParameter<std::string>("dummy_fill_mode");
0126 
0127   // We pass from the easy to use string to an int representation for this mode flag, as it is more efficient in comparisons
0128   if (dummy_fill_mode_param == "DUMMY_FILL_DISABLED")
0129     dummy_fill_mode_ = DUMMY_FILL_DISABLED;
0130   else if (dummy_fill_mode_param == "DUMMY_FILL_ELINK_ID")
0131     dummy_fill_mode_ = DUMMY_FILL_ELINK_ID;
0132   else if (dummy_fill_mode_param == "DUMMY_FILL_ELINK_ID_AND_GBT_ID")
0133     dummy_fill_mode_ = DUMMY_FILL_ELINK_ID_AND_GBT_ID;
0134   else {
0135     throw cms::Exception("InvalidDummyFillMode")
0136         << "Parameter dummy_fill_mode with invalid value: " << dummy_fill_mode_param;
0137   }
0138 
0139   LoadModulesToDTCCablingMapFromCSV(iConfig.getParameter<std::vector<std::string>>("modulesToDTCCablingCSVFileNames"));
0140 }
0141 
0142 void DTCCablingMapProducer::beginJob() {}
0143 
0144 void DTCCablingMapProducer::LoadModulesToDTCCablingMapFromCSV(
0145     std::vector<std::string> const& modulesToDTCCablingCSVFileNames) {
0146   using namespace std;
0147 
0148   for (std::string const& csvFileName : modulesToDTCCablingCSVFileNames) {
0149     edm::FileInPath csvFilePath(csvFileName);
0150 
0151     ifstream csvFile;
0152     csvFile.open(csvFilePath.fullPath().c_str());
0153 
0154     if (csvFile.is_open()) {
0155       string csvLine;
0156 
0157       unsigned lineNumber = 0;
0158 
0159       while (std::getline(csvFile, csvLine)) {
0160         if (verbosity_ >= 1) {
0161           edm::LogInfo("CSVParser") << "Reading CSV file line: " << ++lineNumber << ": \"" << csvLine << "\"" << endl;
0162         }
0163 
0164         istringstream csvStream(csvLine);
0165         vector<string> csvColumn;
0166         string csvElement;
0167 
0168         while (std::getline(csvStream, csvElement, ',')) {
0169           trim(csvElement);
0170           csvColumn.push_back(csvElement);
0171         }
0172 
0173         if (verbosity_ >= 2) {
0174           ostringstream splitted_line_info;
0175 
0176           splitted_line_info << "-- split line is: [";
0177 
0178           for (string const& s : csvColumn)
0179             splitted_line_info << "\"" << s << "\", ";
0180 
0181           splitted_line_info << "]" << endl;
0182 
0183           edm::LogInfo("CSVParser") << splitted_line_info.str();
0184         }
0185 
0186         if (csvColumn.size() == csvFormat_ncolumns_) {
0187           // Skip the legend lines
0188           if (0 == csvColumn[0].compare(std::string("Module_DetId/U"))) {
0189             if (verbosity_ >= 1) {
0190               edm::LogInfo("CSVParser") << "-- skipping legend line" << endl;
0191             }
0192             continue;
0193           }
0194 
0195           uint32_t detIdRaw;
0196 
0197           try {
0198             detIdRaw = std::stoi(csvColumn.at(csvFormat_idetid_));
0199           } catch (std::exception const& e) {
0200             if (verbosity_ >= 0) {
0201               edm::LogError("CSVParser") << "-- malformed DetId string in CSV file: \"" << csvLine << "\"" << endl;
0202             }
0203             throw e;
0204           }
0205 
0206           unsigned const dtc_id = strtoul(csvColumn.at(csvFormat_idtcid_).c_str(), nullptr, 10);
0207           unsigned gbt_id;
0208           unsigned elink_id;
0209 
0210           switch (dummy_fill_mode_) {
0211             default:
0212             case DUMMY_FILL_DISABLED:
0213               gbt_id = strtoul(csvColumn.at(csvFormat_igbtlinkid_).c_str(), nullptr, 10);
0214               elink_id = strtoul(csvColumn.at(csvFormat_ielinkid_).c_str(), nullptr, 10);
0215               break;
0216             case DUMMY_FILL_ELINK_ID:
0217               gbt_id = strtoul(csvColumn.at(csvFormat_igbtlinkid_).c_str(), nullptr, 10);
0218               for (elink_id = elink_id_minvalue; elink_id < elink_id_maxvalue + 1u; ++elink_id) {
0219                 if (!(pCablingMap_->knowsDTCELinkId(DTCELinkId(dtc_id, gbt_id, elink_id))))
0220                   break;
0221               }
0222               break;
0223             case DUMMY_FILL_ELINK_ID_AND_GBT_ID:
0224               for (gbt_id = gbt_id_minvalue; gbt_id < gbt_id_maxvalue + 1u; ++gbt_id) {
0225                 for (elink_id = elink_id_minvalue; elink_id < elink_id_maxvalue + 1u; ++elink_id) {
0226                   if (!(pCablingMap_->knowsDTCELinkId(DTCELinkId(dtc_id, gbt_id, elink_id))))
0227                     goto gbtlink_and_elinkid_generator_end;  //break out of this double loop, this is one of the few "proper" uses of goto
0228                 }
0229               }
0230             gbtlink_and_elinkid_generator_end:
0231               ((void)0);  // This is a NOP, it's here just to have a valid (although dummy) instruction after the goto tag
0232               break;
0233           }
0234 
0235           DTCELinkId dtcELinkId(dtc_id, gbt_id, elink_id);
0236 
0237           if (verbosity_ >= 3) {
0238             edm::LogInfo("CSVParser") << "-- DetId = " << detIdRaw << " (dtc_id, gbt_id, elink_id) = (" << dtc_id << ","
0239                                       << gbt_id << "," << elink_id << ")" << endl;
0240           }
0241 
0242           if (pCablingMap_->knowsDTCELinkId(dtcELinkId)) {
0243             throw cms::Exception("DuplicateDTCELinkIdInCSV")
0244                 << "Reading CSV file: CRITICAL ERROR, duplicate dtcELinkId entry about (dtc_id, gbt_id, elink_id) = ("
0245                 << dtc_id << "," << gbt_id << "," << elink_id << ")";
0246           }
0247 
0248           pCablingMap_->insert(dtcELinkId, detIdRaw);
0249         } else {
0250           if (verbosity_ >= 3) {
0251             edm::LogInfo("CSVParser") << "Reading CSV file: Skipped a short line: \"" << csvLine << "\"" << endl;
0252           }
0253         }
0254       }
0255     } else {
0256       throw cms::Exception("CSVFileNotFound") << "Unable to open input CSV file" << csvFilePath << endl;
0257     }
0258 
0259     csvFile.close();
0260   }
0261 }
0262 
0263 void DTCCablingMapProducer::analyze(const edm::Event& iEvent, const edm::EventSetup& iSetup) {}
0264 
0265 void DTCCablingMapProducer::endJob() {
0266   //    using namespace edm;
0267   using namespace std;
0268 
0269   edm::Service<cond::service::PoolDBOutputService> poolDbService;
0270 
0271   if (poolDbService.isAvailable()) {
0272     poolDbService->writeOneIOV(*pCablingMap_, iovBeginTime_, record_);
0273   } else {
0274     throw cms::Exception("PoolDBServiceNotFound") << "A running PoolDBService instance is required.";
0275   }
0276 }
0277 
0278 DTCCablingMapProducer::~DTCCablingMapProducer() {}
0279 
0280 //define this as a plug-in
0281 DEFINE_FWK_MODULE(DTCCablingMapProducer);