Back to home page

Project CMSSW displayed by LXR

 
 

    


File indexing completed on 2025-03-13 02:31:34

0001 /*
0002  * \file OnlineBeamMonitor.cc
0003  * \author Lorenzo Uplegger/FNAL
0004  * modified by Simone Gennai INFN/Bicocca
0005  */
0006 
0007 // system includes
0008 #include <memory>
0009 #include <numeric>
0010 
0011 // user includes
0012 #include "DQM/BeamMonitor/plugins/OnlineBeamMonitor.h"
0013 #include "DataFormats/Common/interface/Handle.h"
0014 #include "DataFormats/Common/interface/View.h"
0015 #include "FWCore/Framework/interface/ConsumesCollector.h"
0016 #include "FWCore/Framework/interface/ESHandle.h"
0017 #include "FWCore/Framework/interface/EventSetup.h"
0018 #include "FWCore/Framework/interface/LuminosityBlock.h"
0019 #include "FWCore/Framework/interface/MakerMacros.h"
0020 #include "FWCore/Framework/interface/Run.h"
0021 #include "FWCore/MessageLogger/interface/MessageLogger.h"
0022 #include "FWCore/ServiceRegistry/interface/Service.h"
0023 #include "RecoVertex/BeamSpotProducer/interface/BeamFitter.h"
0024 #include "RecoVertex/BeamSpotProducer/interface/PVFitter.h"
0025 
0026 using namespace std;
0027 using namespace edm;
0028 using namespace reco;
0029 
0030 //----------------------------------------------------------------------------------------------------------------------
0031 OnlineBeamMonitor::OnlineBeamMonitor(const ParameterSet& ps)
0032     : monitorName_(ps.getUntrackedParameter<string>("MonitorName")),
0033       bsOnlineToken_(consumes(ps.getUntrackedParameter<edm::InputTag>("OnlineBeamSpotLabel"))),
0034       bsHLTToken_(esConsumes()),
0035       bsLegacyToken_(esConsumes()),
0036       numberOfValuesToSave_(0),
0037       appendRunTxt_(ps.getUntrackedParameter<bool>("AppendRunToFileName")),
0038       writeDIPTxt_(ps.getUntrackedParameter<bool>("WriteDIPAscii")),
0039       outputDIPTxt_(ps.getUntrackedParameter<std::string>("DIPFileName")),
0040       shouldReadEvent_(true) {
0041   if (!monitorName_.empty())
0042     monitorName_ = monitorName_ + "/";
0043 
0044   processedLumis_.clear();
0045 
0046   varNamesV_.push_back("x");
0047   varNamesV_.push_back("y");
0048   varNamesV_.push_back("z");
0049   varNamesV_.push_back("sigmaX");
0050   varNamesV_.push_back("sigmaY");
0051   varNamesV_.push_back("sigmaZ");
0052 
0053   //histoByCategoryNames_.insert(pair<string, string>("run", "Coordinate"));
0054   //histoByCategoryNames_.insert(pair<string, string>("run", "PrimaryVertex fit-DataBase"));
0055   //histoByCategoryNames_.insert(pair<string, string>("run", "PrimaryVertex fit-BeamFit"));
0056   //histoByCategoryNames_.insert(pair<string, string>("run", "PrimaryVertex fit-Scalers"));
0057   //histoByCategoryNames_.insert(pair<string, string>("run", "PrimaryVertex-DataBase"));
0058   //histoByCategoryNames_.insert(pair<string, string>("run", "PrimaryVertex-BeamFit"));
0059   //histoByCategoryNames_.insert(pair<string, string>("run", "PrimaryVertex-Scalers"));
0060 
0061   histoByCategoryNames_.insert(pair<string, string>("lumi", "Lumibased BeamSpotHLT"));
0062   histoByCategoryNames_.insert(pair<string, string>("lumi", "Lumibased BeamSpotLegacy"));
0063   histoByCategoryNames_.insert(pair<string, string>("lumi", "Lumibased BeamSpotOnline"));
0064 
0065   for (const auto& itV : varNamesV_) {
0066     for (const auto& itM : histoByCategoryNames_) {
0067       histosMap_[itV][itM.first][itM.second] = nullptr;
0068     }
0069   }
0070 }
0071 
0072 void OnlineBeamMonitor::fillDescriptions(edm::ConfigurationDescriptions& iDesc) {
0073   edm::ParameterSetDescription ps;
0074   ps.addUntracked<std::string>("MonitorName", "YourSubsystemName");
0075   ps.addUntracked<edm::InputTag>("OnlineBeamSpotLabel", edm::InputTag("hltOnlineBeamSpot"));
0076   ps.addUntracked<bool>("AppendRunToFileName", false);
0077   ps.addUntracked<bool>("WriteDIPAscii", true);
0078   ps.addUntracked<std::string>("DIPFileName", "BeamFitResultsForDIP.txt");
0079 
0080   iDesc.addWithDefaultLabel(ps);
0081 }
0082 
0083 //----------------------------------------------------------------------------------------------------------------------
0084 void OnlineBeamMonitor::bookHistograms(DQMStore::IBooker& ibooker,
0085                                        edm::Run const& iRun,
0086                                        edm::EventSetup const& iSetup) {
0087   string name;
0088   string title;
0089   int firstLumi = 1;
0090   int lastLumi = 3000;
0091   for (auto& itM : histosMap_) {
0092     //Making histos per Lumi
0093     // x,y,z,sigmaX,sigmaY,sigmaZ
0094     for (auto& itMM : itM.second) {
0095       if (itMM.first != "run") {
0096         for (auto& itMMM : itMM.second) {
0097           name = string("h") + itM.first + itMMM.first;
0098           title = itM.first + "_{0} " + itMMM.first;
0099           if (itMM.first == "lumi") {
0100             ibooker.setCurrentFolder(monitorName_ + "Debug");
0101             itMMM.second = ibooker.book1D(name, title, lastLumi - firstLumi + 1, firstLumi - 0.5, lastLumi + 0.5);
0102             itMMM.second->setEfficiencyFlag();
0103           } else {
0104             LogInfo("OnlineBeamMonitorClient") << "Unrecognized category " << itMM.first;
0105           }
0106           if (itMMM.second != nullptr) {
0107             if (itMMM.first.find('-') != string::npos) {
0108               itMMM.second->setAxisTitle(string("#Delta ") + itM.first + "_{0} (cm)", 2);
0109             } else {
0110               itMMM.second->setAxisTitle(itM.first + "_{0} (cm)", 2);
0111             }
0112             itMMM.second->setAxisTitle("Lumisection", 1);
0113           }
0114         }
0115       }
0116     }
0117   }
0118 
0119   // create and cd into new folder
0120   ibooker.setCurrentFolder(monitorName_ + "Validation");
0121   //Book histograms
0122   bsChoice_ = ibooker.bookProfile("bsChoice",
0123                                   "BS Choice: +1=HLT / -1=Legacy / -10=Fake (fallback to PCL) / 0=No Transient ",
0124                                   lastLumi - firstLumi + 1,
0125                                   firstLumi - 0.5,
0126                                   lastLumi + 0.5,
0127                                   100,
0128                                   -10,
0129                                   1,
0130                                   "");
0131   bsChoice_->setAxisTitle("Lumisection", 1);
0132   bsChoice_->setAxisTitle("Choice", 2);
0133 }
0134 
0135 //----------------------------------------------------------------------------------------------------------------------
0136 // Handle exceptions for the schema evolution of the BeamSpotOnline CondFormat
0137 
0138 // Slightly better error handler
0139 static void print_error(const std::exception& e) { edm::LogError("BeamSpotOnlineParameters") << e.what() << '\n'; }
0140 
0141 // Generic try-catch template
0142 template <typename T, typename Func>
0143 T tryCatch(Func f, T errorValue) {
0144   try {
0145     LogDebug("BeamSpotOnlineParameters") << "Trying function" << std::endl;
0146     return f();
0147   } catch (const std::exception& e) {
0148     LogDebug("BeamSpotOnlineParameters") << "Caught exception" << std::endl;
0149     print_error(e);
0150     return errorValue;
0151   }
0152 }
0153 
0154 // Enum the BS string parameters
0155 enum BSparameters {
0156   startTime = 0,  // 0 additional std::string parameters
0157   endTime = 1,    // 1
0158   lumiRange = 2,  // 2
0159   events = 3,     // 3 additional int parameters
0160   maxPV = 4,      // 4
0161   nPV = 5,        // 5
0162   meanPV = 6,     // 6 additional float parameters
0163   meanErrPV = 7,  // 7
0164   rmsPV = 8,      // 8
0165   rmsErrPV = 9,   // 9
0166   END_OF_TYPES = 10,
0167 };
0168 
0169 // Unified functor
0170 using BeamSpotFunctor =
0171     std::function<std::variant<std::string, int, float>(BSparameters, const BeamSpotOnlineObjects&)>;
0172 
0173 BeamSpotFunctor beamSpotFunctor = [](BSparameters param,
0174                                      const BeamSpotOnlineObjects& payload) -> std::variant<std::string, int, float> {
0175   switch (param) {
0176     case BSparameters::startTime:
0177       return payload.startTime();
0178     case BSparameters::endTime:
0179       return payload.endTime();
0180     case BSparameters::lumiRange:
0181       return payload.lumiRange();
0182     case BSparameters::events:
0183       return payload.usedEvents();
0184     case BSparameters::maxPV:
0185       return payload.maxPVs();
0186     case BSparameters::nPV:
0187       return payload.numPVs();
0188     case BSparameters::meanPV:
0189       return payload.meanPV();
0190     case BSparameters::meanErrPV:
0191       return payload.meanErrorPV();
0192     case BSparameters::rmsPV:
0193       return payload.rmsPV();
0194     case BSparameters::rmsErrPV:
0195       return payload.rmsErrorPV();
0196     default:
0197       throw std::invalid_argument("Unknown BS parameter");
0198   }
0199 };
0200 
0201 //----------------------------------------------------------------------------------------------------------------------
0202 std::shared_ptr<onlinebeammonitor::BeamSpotInfo> OnlineBeamMonitor::globalBeginLuminosityBlock(
0203     const LuminosityBlock& iLumi, const EventSetup& iSetup) const {
0204   // Always create a beamspot group for each lumi weather we have results or not! Each Beamspot will be of unknown type!
0205   auto beamSpotInfo = std::make_shared<onlinebeammonitor::BeamSpotInfo>();
0206   return beamSpotInfo;
0207 }
0208 
0209 void OnlineBeamMonitor::fetchBeamSpotInformation(const Event& iEvent, const EventSetup& iSetup) {
0210   auto const& iLumi = iEvent.getLuminosityBlock();
0211   auto beamSpotInfo = luminosityBlockCache(iLumi.index());
0212   //Read BeamSpot from DB
0213   ESHandle<BeamSpotOnlineObjects> bsHLTHandle;
0214   ESHandle<BeamSpotOnlineObjects> bsLegacyHandle;
0215   ESHandle<BeamSpotObjects> bsOnlineHandle;
0216 
0217   // Additional values for DIP publication
0218   std::string startTimeStamp_ = "0";
0219   std::string startTimeStampHLT_ = "0";
0220   std::string startTimeStampLegacy_ = "0";
0221   std::string stopTimeStamp_ = "0";
0222   std::string stopTimeStampHLT_ = "0";
0223   std::string stopTimeStampLegacy_ = "0";
0224   std::string lumiRange_ = "0 - 0";
0225   std::string lumiRangeHLT_ = "0 - 0";
0226   std::string lumiRangeLegacy_ = "0 - 0";
0227   int events_ = 0;
0228   int eventsHLT_ = 0;
0229   int eventsLegacy_ = 0;
0230   int maxPV_ = 0;
0231   int maxPVHLT_ = 0;
0232   int maxPVLegacy_ = 0;
0233   int nPV_ = 0;
0234   int nPVHLT_ = 0;
0235   int nPVLegacy_ = 0;
0236   float meanPV_ = 0.;
0237   float meanPVHLT_ = 0.;
0238   float meanPVLegacy_ = 0.;
0239   float meanErrPV_ = 0.;
0240   float meanErrPVHLT_ = 0.;
0241   float meanErrPVLegacy_ = 0.;
0242   float rmsPV_ = 0.;
0243   float rmsPVHLT_ = 0.;
0244   float rmsPVLegacy_ = 0.;
0245   float rmsErrPV_ = 0.;
0246   float rmsErrPVHLT_ = 0.;
0247   float rmsErrPVLegacy_ = 0.;
0248 
0249   if (auto bsHLTHandle = iSetup.getHandle(bsHLTToken_)) {
0250     auto const& spotDB = *bsHLTHandle;
0251 
0252     auto fetchValue = [&](BSparameters param, auto defaultValue) {
0253       return tryCatch([&]() { return std::get<decltype(defaultValue)>(beamSpotFunctor(param, spotDB)); }, defaultValue);
0254     };
0255 
0256     startTimeStampHLT_ = fetchValue(BSparameters::startTime, std::string("0"));
0257     stopTimeStampHLT_ = fetchValue(BSparameters::endTime, std::string("0"));
0258     lumiRangeHLT_ = fetchValue(BSparameters::lumiRange, std::string("0 - 0"));
0259     eventsHLT_ = fetchValue(BSparameters::events, -999);
0260     maxPVHLT_ = fetchValue(BSparameters::maxPV, -999);
0261     nPVHLT_ = fetchValue(BSparameters::nPV, -999);
0262     meanPVHLT_ = fetchValue(BSparameters::meanPV, -999.0f);
0263     meanErrPVHLT_ = fetchValue(BSparameters::meanErrPV, -999.0f);
0264     rmsPVHLT_ = fetchValue(BSparameters::rmsPV, -999.0f);
0265     rmsErrPVHLT_ = fetchValue(BSparameters::rmsErrPV, -999.0f);
0266 
0267     // translate from BeamSpotObjects to reco::BeamSpot
0268     BeamSpot::Point apoint(spotDB.x(), spotDB.y(), spotDB.z());
0269 
0270     BeamSpot::CovarianceMatrix matrix;
0271     for (int i = 0; i < reco::BeamSpot::dimension; ++i) {
0272       for (int j = 0; j < reco::BeamSpot::dimension; ++j) {
0273         matrix(i, j) = spotDB.covariance(i, j);
0274       }
0275     }
0276 
0277     beamSpotInfo->beamSpotsMap_["HLT"] =
0278         BeamSpot(apoint, spotDB.sigmaZ(), spotDB.dxdz(), spotDB.dydz(), spotDB.beamWidthX(), matrix);
0279 
0280     BeamSpot* aSpot = &(beamSpotInfo->beamSpotsMap_["HLT"]);
0281 
0282     aSpot->setBeamWidthY(spotDB.beamWidthY());
0283     aSpot->setEmittanceX(spotDB.emittanceX());
0284     aSpot->setEmittanceY(spotDB.emittanceY());
0285     aSpot->setbetaStar(spotDB.betaStar());
0286 
0287     if (spotDB.beamType() == 2) {
0288       aSpot->setType(reco::BeamSpot::Tracker);
0289     } else {
0290       aSpot->setType(reco::BeamSpot::Fake);
0291     }
0292     //LogInfo("OnlineBeamMonitor")
0293     //  << *aSpot << std::endl;
0294   } else {
0295     LogError("OnlineBeamMonitor") << "The database BeamSpot (hlt record) is not valid at lumi: "
0296                                   << iLumi.id().luminosityBlock();
0297   }
0298 
0299   if (auto bsLegacyHandle = iSetup.getHandle(bsLegacyToken_)) {
0300     auto const& spotDB = *bsLegacyHandle;
0301 
0302     auto fetchValue = [&](BSparameters param, auto defaultValue) {
0303       return tryCatch([&]() { return std::get<decltype(defaultValue)>(beamSpotFunctor(param, spotDB)); }, defaultValue);
0304     };
0305 
0306     startTimeStampLegacy_ = fetchValue(BSparameters::startTime, std::string("0"));
0307     stopTimeStampLegacy_ = fetchValue(BSparameters::endTime, std::string("0"));
0308     lumiRangeLegacy_ = fetchValue(BSparameters::lumiRange, std::string("0 - 0"));
0309     eventsLegacy_ = fetchValue(BSparameters::events, -999);
0310     maxPVLegacy_ = fetchValue(BSparameters::maxPV, -999);
0311     nPVLegacy_ = fetchValue(BSparameters::nPV, -999);
0312     meanPVLegacy_ = fetchValue(BSparameters::meanPV, -999.0f);
0313     meanErrPVLegacy_ = fetchValue(BSparameters::meanErrPV, -999.0f);
0314     rmsPVLegacy_ = fetchValue(BSparameters::rmsPV, -999.0f);
0315     rmsErrPVLegacy_ = fetchValue(BSparameters::rmsErrPV, -999.0f);
0316 
0317     // translate from BeamSpotObjects to reco::BeamSpot
0318     BeamSpot::Point apoint(spotDB.x(), spotDB.y(), spotDB.z());
0319 
0320     BeamSpot::CovarianceMatrix matrix;
0321     for (int i = 0; i < reco::BeamSpot::dimension; ++i) {
0322       for (int j = 0; j < reco::BeamSpot::dimension; ++j) {
0323         matrix(i, j) = spotDB.covariance(i, j);
0324       }
0325     }
0326 
0327     beamSpotInfo->beamSpotsMap_["Legacy"] =
0328         BeamSpot(apoint, spotDB.sigmaZ(), spotDB.dxdz(), spotDB.dydz(), spotDB.beamWidthX(), matrix);
0329 
0330     BeamSpot* aSpot = &(beamSpotInfo->beamSpotsMap_["Legacy"]);
0331 
0332     aSpot->setBeamWidthY(spotDB.beamWidthY());
0333     aSpot->setEmittanceX(spotDB.emittanceX());
0334     aSpot->setEmittanceY(spotDB.emittanceY());
0335     aSpot->setbetaStar(spotDB.betaStar());
0336 
0337     if (spotDB.beamType() == 2) {
0338       aSpot->setType(reco::BeamSpot::Tracker);
0339     } else {
0340       aSpot->setType(reco::BeamSpot::Fake);
0341     }
0342     //LogInfo("OnlineBeamMonitor")
0343     //  << *aSpot << std::endl;
0344   } else {
0345     LogError("OnlineBeamMonitor") << "The database BeamSpot (legacy record) is not valid at lumi: "
0346                                   << iLumi.id().luminosityBlock();
0347   }
0348 
0349   if (auto bsOnlineHandle = iEvent.getHandle(bsOnlineToken_)) {
0350     auto const& spotOnline = *bsOnlineHandle;
0351 
0352     beamSpotInfo->beamSpotsMap_["Online"] = spotOnline;
0353 
0354     if (writeDIPTxt_) {
0355       std::ofstream outFile;
0356 
0357       std::string tmpname = outputDIPTxt_;
0358       int frun = iLumi.getRun().run();
0359 
0360       char index[15];
0361       if (appendRunTxt_ && writeDIPTxt_) {
0362         sprintf(index, "%s%i", "_Run", frun);
0363         tmpname.insert(outputDIPTxt_.length() - 4, index);
0364       }
0365 
0366       if (beamSpotInfo->beamSpotsMap_.find("Online") != beamSpotInfo->beamSpotsMap_.end()) {
0367         if (beamSpotInfo->beamSpotsMap_.find("HLT") != beamSpotInfo->beamSpotsMap_.end() &&
0368             beamSpotInfo->beamSpotsMap_["Online"].x0() == beamSpotInfo->beamSpotsMap_["HLT"].x0()) {
0369           startTimeStamp_ = startTimeStampHLT_;
0370           stopTimeStamp_ = stopTimeStampHLT_;
0371           lumiRange_ = lumiRangeHLT_;
0372           events_ = eventsHLT_;
0373           maxPV_ = maxPVHLT_;
0374           nPV_ = nPVHLT_;
0375           meanPV_ = meanPVHLT_;
0376           meanErrPV_ = meanErrPVHLT_;
0377           rmsPV_ = rmsPVHLT_;
0378           rmsErrPV_ = rmsErrPVHLT_;
0379         } else if (beamSpotInfo->beamSpotsMap_.find("Legacy") != beamSpotInfo->beamSpotsMap_.end() &&
0380                    beamSpotInfo->beamSpotsMap_["Online"].x0() == beamSpotInfo->beamSpotsMap_["Legacy"].x0()) {
0381           startTimeStamp_ = startTimeStampLegacy_;
0382           stopTimeStamp_ = stopTimeStampLegacy_;
0383           lumiRange_ = lumiRangeLegacy_;
0384           events_ = eventsLegacy_;
0385           maxPV_ = maxPVLegacy_;
0386           nPV_ = nPVLegacy_;
0387           meanPV_ = meanPVLegacy_;
0388           meanErrPV_ = meanErrPVLegacy_;
0389           rmsPV_ = rmsPVLegacy_;
0390           rmsErrPV_ = rmsErrPVLegacy_;
0391         }
0392       }
0393 
0394       outFile.open(tmpname.c_str());
0395 
0396       // Write out file for DIP publication
0397       outFile << "Runnumber " << frun << std::endl;
0398       outFile << "BeginTimeOfFit " << startTimeStamp_ << " " << 0 << std::endl;
0399       outFile << "EndTimeOfFit " << stopTimeStamp_ << " " << 0 << std::endl;
0400       outFile << "LumiRange " << lumiRange_ << std::endl;
0401       outFile << "Type " << spotOnline.type() << std::endl;
0402       outFile << "X0 " << spotOnline.x0() << std::endl;
0403       outFile << "Y0 " << spotOnline.y0() << std::endl;
0404       outFile << "Z0 " << spotOnline.z0() << std::endl;
0405       outFile << "sigmaZ0 " << spotOnline.sigmaZ() << std::endl;
0406       outFile << "dxdz " << spotOnline.dxdz() << std::endl;
0407       outFile << "dydz " << spotOnline.dydz() << std::endl;
0408       outFile << "BeamWidthX " << spotOnline.BeamWidthX() << std::endl;
0409       outFile << "BeamWidthY " << spotOnline.BeamWidthY() << std::endl;
0410       for (int i = 0; i < reco::BeamSpot::dimension; ++i) {
0411         outFile << "Cov(" << i << ",j) ";
0412         for (int j = 0; j < reco::BeamSpot::dimension; ++j) {
0413           outFile << spotOnline.covariance(i, j) << " ";
0414         }
0415         outFile << std::endl;
0416       }
0417       outFile << "EmittanceX " << spotOnline.emittanceX() << std::endl;
0418       outFile << "EmittanceY " << spotOnline.emittanceY() << std::endl;
0419       outFile << "BetaStar " << spotOnline.betaStar() << std::endl;
0420       outFile << "events " << events_ << std::endl;
0421       outFile << "meanPV " << meanPV_ << std::endl;
0422       outFile << "meanErrPV " << meanErrPV_ << std::endl;
0423       outFile << "rmsPV " << rmsPV_ << std::endl;
0424       outFile << "rmsErrPV " << rmsErrPV_ << std::endl;
0425       outFile << "maxPV " << maxPV_ << std::endl;
0426       outFile << "nPV " << nPV_ << std::endl;
0427 
0428       outFile.close();
0429     }
0430     //LogInfo("OnlineBeamMonitor")
0431     //  << *spotOnline << std::endl;
0432   } else {
0433     LogError("OnlineBeamMonitor") << "The online BeamSpot collection is not valid at lumi: "
0434                                   << iLumi.id().luminosityBlock();
0435   }
0436 }
0437 
0438 //----------------------------------------------------------------------------------------------------------------------
0439 void OnlineBeamMonitor::globalEndLuminosityBlock(const LuminosityBlock& iLumi, const EventSetup& iSetup) {
0440   processedLumis_.push_back(iLumi.id().luminosityBlock());
0441   auto beamSpotInfo = luminosityBlockCache(iLumi.index());
0442 
0443   //Setting up the choice
0444   if (beamSpotInfo->beamSpotsMap_.find("Online") != beamSpotInfo->beamSpotsMap_.end()) {
0445     if (beamSpotInfo->beamSpotsMap_.find("HLT") != beamSpotInfo->beamSpotsMap_.end() &&
0446         beamSpotInfo->beamSpotsMap_["Online"].x0() == beamSpotInfo->beamSpotsMap_["HLT"].x0()) {
0447       bsChoice_->Fill(iLumi.id().luminosityBlock(), 1);
0448       bsChoice_->setBinError(iLumi.id().luminosityBlock(), 0.05);
0449     } else if (beamSpotInfo->beamSpotsMap_.find("Legacy") != beamSpotInfo->beamSpotsMap_.end() &&
0450                beamSpotInfo->beamSpotsMap_["Online"].x0() == beamSpotInfo->beamSpotsMap_["Legacy"].x0()) {
0451       bsChoice_->Fill(iLumi.id().luminosityBlock(), -1);
0452       bsChoice_->setBinError(iLumi.id().luminosityBlock(), 0.05);
0453     } else {
0454       bsChoice_->Fill(iLumi.id().luminosityBlock(), -10);
0455       bsChoice_->setBinError(iLumi.id().luminosityBlock(), 0.05);
0456     }
0457   } else {
0458     bsChoice_->Fill(iLumi.id().luminosityBlock(), 0);
0459     bsChoice_->setBinError(iLumi.id().luminosityBlock(), 0.05);
0460   }
0461 
0462   //    "PV,BF..."      Value,Error
0463   map<std::string, pair<double, double> > resultsMap;
0464   vector<pair<double, double> > vertexResults;
0465   MonitorElement* histo = nullptr;
0466   for (const auto& itV : varNamesV_) {
0467     resultsMap.clear();
0468     for (const auto& itBS : beamSpotInfo->beamSpotsMap_) {
0469       if (itBS.second.type() == BeamSpot::Tracker) {
0470         if (itV == "x") {
0471           resultsMap[itBS.first] = pair<double, double>(itBS.second.x0(), itBS.second.x0Error());
0472         } else if (itV == "y") {
0473           resultsMap[itBS.first] = pair<double, double>(itBS.second.y0(), itBS.second.y0Error());
0474         } else if (itV == "z") {
0475           resultsMap[itBS.first] = pair<double, double>(itBS.second.z0(), itBS.second.z0Error());
0476         } else if (itV == "sigmaX") {
0477           resultsMap[itBS.first] = pair<double, double>(itBS.second.BeamWidthX(), itBS.second.BeamWidthXError());
0478         } else if (itV == "sigmaY") {
0479           resultsMap[itBS.first] = pair<double, double>(itBS.second.BeamWidthY(), itBS.second.BeamWidthYError());
0480         } else if (itV == "sigmaZ") {
0481           resultsMap[itBS.first] = pair<double, double>(itBS.second.sigmaZ(), itBS.second.sigmaZ0Error());
0482         } else {
0483           LogInfo("OnlineBeamMonitor") << "The histosMap_ has been built with the name " << itV
0484                                        << " that I can't recognize!";
0485         }
0486       }
0487     }
0488 
0489     for (const auto& itM : histoByCategoryNames_) {
0490       if ((histo = histosMap_[itV][itM.first][itM.second]) == nullptr)
0491         continue;
0492       if (itM.second == "Lumibased BeamSpotHLT") {
0493         if (resultsMap.find("HLT") != resultsMap.end()) {
0494           histo->setBinContent(iLumi.id().luminosityBlock(), resultsMap["HLT"].first);
0495           histo->setBinError(iLumi.id().luminosityBlock(), resultsMap["HLT"].second);
0496         }
0497       } else if (itM.second == "Lumibased BeamSpotLegacy") {
0498         if (resultsMap.find("Legacy") != resultsMap.end()) {
0499           histo->setBinContent(iLumi.id().luminosityBlock(), resultsMap["Legacy"].first);
0500           histo->setBinError(iLumi.id().luminosityBlock(), resultsMap["Legacy"].second);
0501         }
0502       } else if (itM.second == "Lumibased BeamSpotOnline") {
0503         if (resultsMap.find("Online") != resultsMap.end()) {
0504           histo->setBinContent(iLumi.id().luminosityBlock(), resultsMap["Online"].first);
0505           histo->setBinError(iLumi.id().luminosityBlock(), resultsMap["Online"].second);
0506         }
0507       } else {
0508         LogInfo("OnlineBeamMonitor") << "The histosMap_ have a histogram named " << itM.second
0509                                      << " that I can't recognize in this loop!";
0510       }
0511     }
0512   }
0513   shouldReadEvent_ = true;
0514 }
0515 
0516 void OnlineBeamMonitor::dqmEndRun(edm::Run const&, edm::EventSetup const&) {
0517   if (processedLumis_.empty()) {
0518     return;
0519   }
0520 
0521   const double bigNumber = 1000000.;
0522   std::sort(processedLumis_.begin(), processedLumis_.end());
0523   int firstLumi = *processedLumis_.begin();
0524   int lastLumi = *(--processedLumis_.end());
0525   bsChoice_->getTH1()->GetXaxis()->SetRangeUser(firstLumi - 0.5, lastLumi + 0.5);
0526   for (auto& itH : histosMap_) {
0527     for (auto& itHH : itH.second) {
0528       double min = bigNumber;
0529       double max = -bigNumber;
0530       if (itHH.first != "run") {
0531         for (auto& itHHH : itHH.second) {
0532           if (itHHH.second != nullptr) {
0533             for (int bin = 1; bin <= itHHH.second->getTH1()->GetNbinsX(); bin++) {
0534               if (itHHH.second->getTH1()->GetBinError(bin) != 0 || itHHH.second->getTH1()->GetBinContent(bin) != 0) {
0535                 if (itHHH.first == "Lumibased BeamSpotHLT" || itHHH.first == "Lumibased BeamSpotLegacy" ||
0536                     itHHH.first == "Lumibased BeamSpotOnline") {
0537                   if (min > itHHH.second->getTH1()->GetBinContent(bin)) {
0538                     min = itHHH.second->getTH1()->GetBinContent(bin);
0539                   }
0540                   if (max < itHHH.second->getTH1()->GetBinContent(bin)) {
0541                     max = itHHH.second->getTH1()->GetBinContent(bin);
0542                   }
0543                 } else {
0544                   LogInfo("OnlineBeamMonitorClient") << "The histosMap_ have a histogram named " << itHHH.first
0545                                                      << " that I can't recognize in this loop!";
0546                 }
0547               }
0548             }
0549           }
0550         }
0551         for (auto& itHHH : itHH.second) {
0552           if (itHHH.second != nullptr) {
0553             if (itHHH.first == "Lumibased BeamSpotHLT" || itHHH.first == "Lumibased BeamSpotLegacy" ||
0554                 itHHH.first == "Lumibased BeamSpotOnline") {
0555               if ((max == -bigNumber && min == bigNumber) || max - min == 0) {
0556                 itHHH.second->getTH1()->SetMinimum(itHHH.second->getTH1()->GetMinimum() - 0.01);
0557                 itHHH.second->getTH1()->SetMaximum(itHHH.second->getTH1()->GetMaximum() + 0.01);
0558               } else {
0559                 itHHH.second->getTH1()->SetMinimum(min - 0.1 * (max - min));
0560                 itHHH.second->getTH1()->SetMaximum(max + 0.1 * (max - min));
0561               }
0562             } else {
0563               LogInfo("OnlineBeamMonitorClient")
0564                   << "The histosMap_ have a histogram named " << itHHH.first << " that I can't recognize in this loop!";
0565             }
0566             itHHH.second->getTH1()->GetXaxis()->SetRangeUser(firstLumi - 0.5, lastLumi + 0.5);
0567           }
0568         }
0569       }
0570     }
0571   }
0572 }
0573 
0574 void OnlineBeamMonitor::analyze(edm::Event const& iEvent, edm::EventSetup const& iSetup) {
0575   if (shouldReadEvent_) {
0576     fetchBeamSpotInformation(iEvent, iSetup);
0577     shouldReadEvent_ = false;
0578   }
0579 }
0580 
0581 DEFINE_FWK_MODULE(OnlineBeamMonitor);