Back to home page

Project CMSSW displayed by LXR

 
 

    


File indexing completed on 2021-02-14 14:25:22

0001 // -*- C++ -*-
0002 //
0003 // Package:    RecoLuminosity/LumiProducer
0004 // Class:      LumiProducerFromBrilcalc
0005 //
0006 /**\class LumiProducerFromBrilcalc LumiProducerFromBrilcalc.cc RecoLuminosity/LumiProducer/plugins/LumiProducerFromBrilcalc.cc
0007 
0008    Description: Takes a csv file with luminosity information produced by brilcalc and reads it into the event.
0009 
0010    Implementation:
0011    [Notes on implementation]
0012 */
0013 //
0014 // Original Author:  Paul Lujan
0015 //         Created:  Fri, 28 Feb 2020 16:32:38 GMT
0016 //
0017 //
0018 
0019 // system include files
0020 #include <memory>
0021 #include <sstream>
0022 #include <fstream>
0023 
0024 // user include files
0025 #include "FWCore/Framework/interface/Frameworkfwd.h"
0026 #include "FWCore/Framework/interface/global/EDProducer.h"
0027 
0028 #include "FWCore/Framework/interface/Event.h"
0029 #include "FWCore/Framework/interface/MakerMacros.h"
0030 
0031 #include "FWCore/ParameterSet/interface/ParameterSet.h"
0032 #include "FWCore/Utilities/interface/StreamID.h"
0033 
0034 #include "FWCore/MessageLogger/interface/MessageLogger.h"
0035 
0036 #include "DataFormats/Luminosity/interface/LumiInfo.h"
0037 
0038 //
0039 // class declaration
0040 //
0041 
0042 class LumiProducerFromBrilcalc : public edm::global::EDProducer<> {
0043 public:
0044   explicit LumiProducerFromBrilcalc(const edm::ParameterSet&);
0045   ~LumiProducerFromBrilcalc() override = default;
0046 
0047   static void fillDescriptions(edm::ConfigurationDescriptions& descriptions);
0048 
0049 private:
0050   void produce(edm::StreamID, edm::Event&, const edm::EventSetup&) const override;
0051 
0052   // ----------member data ---------------------------
0053   const std::string lumiFile_;
0054   const bool throwIfNotFound_;
0055   const bool doBunchByBunch_;
0056   std::map<std::pair<int, int>, std::pair<float, float> > lumiData_;
0057 };
0058 
0059 //
0060 // constructor
0061 //
0062 
0063 LumiProducerFromBrilcalc::LumiProducerFromBrilcalc(const edm::ParameterSet& iConfig)
0064     : lumiFile_(iConfig.getParameter<std::string>("lumiFile")),
0065       throwIfNotFound_(iConfig.getParameter<bool>("throwIfNotFound")),
0066       doBunchByBunch_(iConfig.getParameter<bool>("doBunchByBunch")) {
0067   //register your products
0068   produces<LumiInfo>("brilcalc");
0069 
0070   //now do what ever other initialization is needed
0071   if (doBunchByBunch_) {
0072     throw cms::Exception("LumiProducerFromBrilcalc")
0073         << "Sorry, bunch-by-bunch luminosity is not yet supported. Please bug your friendly lumi expert!";
0074   }
0075 
0076   // Read luminosity data and store it in lumiData_.
0077   edm::LogInfo("LumiProducerFromBrilcalc") << "Reading luminosity data from " << lumiFile_ << "...one moment...";
0078   std::ifstream lumiFile(lumiFile_);
0079   if (!lumiFile.is_open()) {
0080     throw cms::Exception("LumiProducerFromBrilcalc") << "Failed to open input luminosity file " << lumiFile_;
0081   }
0082 
0083   int nLS = 0;
0084   std::string line;
0085   while (true) {
0086     std::getline(lumiFile, line);
0087     if (lumiFile.eof() || lumiFile.fail())
0088       break;
0089     if (line.empty())
0090       continue;  // skip blank lines
0091     if (line.at(0) == '#')
0092       continue;  // skip comment lines
0093 
0094     // Break into fields. These should be, in order: run:fill, brills:cmsls, time, beam status, beam energy,
0095     // delivered lumi, recorded lumi, average pileup, source.
0096     std::stringstream ss(line);
0097     std::string field;
0098     std::vector<std::string> fields;
0099 
0100     while (std::getline(ss, field, ','))
0101       fields.push_back(field);
0102 
0103     if (fields.size() != 9) {
0104       edm::LogWarning("LumiProducerFromBrilcalc") << "Malformed line in csv file: " << line;
0105       continue;
0106     }
0107 
0108     // Extract the run number from fields[0] and the lumisection number from fields[1]. Fortunately since the
0109     // thing we want is before the colon, we don't have to split them again.
0110     int run, ls;
0111     std::stringstream runfill(fields[0]);
0112     runfill >> run;
0113     std::stringstream lsls(fields[1]);
0114     lsls >> ls;
0115 
0116     // Extract the delivered and recorded lumi from fields[5] and fields[6].
0117     float lumiDel, lumiRec, dtFrac;
0118     std::stringstream lumiDelString(fields[5]);
0119     lumiDelString >> lumiDel;
0120     std::stringstream lumiRecString(fields[6]);
0121     lumiRecString >> lumiRec;
0122 
0123     // Calculate the deadtime fraction
0124     dtFrac = 1.0 - lumiRec / lumiDel;
0125 
0126     // Finally, store it all.
0127     lumiData_[std::make_pair(run, ls)] = std::make_pair(lumiDel, dtFrac);
0128     nLS++;
0129   }
0130   edm::LogInfo("LumiProducerFromBrilcalc") << "Read " << nLS << " lumisections from " << lumiFile_;
0131   lumiFile.close();
0132 }
0133 
0134 //
0135 // member functions
0136 //
0137 
0138 // ------------ method called to produce the data  ------------
0139 void LumiProducerFromBrilcalc::produce(edm::StreamID iStreamID,
0140                                        edm::Event& iEvent,
0141                                        const edm::EventSetup& iSetup) const {
0142   std::vector<float> bxlumi(3564, 0);
0143   std::pair<int, int> runls = std::make_pair(iEvent.run(), iEvent.luminosityBlock());
0144   if (lumiData_.count(runls) == 1) {
0145     // if we have data for this run/LS, put it in the event
0146     LogDebug("LumiProducerFromBrilcalc") << "Filling for run " << runls.first << " ls " << runls.second
0147                                          << " with delivered " << lumiData_.at(runls).first << " dt "
0148                                          << lumiData_.at(runls).second;
0149     iEvent.put(std::make_unique<LumiInfo>(lumiData_.at(runls).second, bxlumi, lumiData_.at(runls).first), "brilcalc");
0150   } else {
0151     if (throwIfNotFound_) {
0152       throw cms::Exception("LumiProducerFromBrilcalc")
0153           << "Failed to find luminosity for run " << runls.first << " LS " << runls.second;
0154     } else {
0155       // just put in zeroes
0156       edm::LogWarning("LumiProducerFromBrilcalc")
0157           << "Failed to find luminosity for run " << runls.first << " ls " << runls.second;
0158       iEvent.put(std::make_unique<LumiInfo>(0, bxlumi, 0), "brilcalc");
0159     }
0160   }
0161 }
0162 
0163 // ------------ method fills 'descriptions' with the allowed parameters for the module  ------------
0164 void LumiProducerFromBrilcalc::fillDescriptions(edm::ConfigurationDescriptions& descriptions) {
0165   // Allowed parameters
0166   edm::ParameterSetDescription desc;
0167   desc.add<std::string>("lumiFile");
0168   desc.add<bool>("throwIfNotFound", false);
0169   desc.add<bool>("doBunchByBunch", false);
0170   descriptions.addDefault(desc);
0171 }
0172 
0173 //define this as a plug-in
0174 DEFINE_FWK_MODULE(LumiProducerFromBrilcalc);