Back to home page

Project CMSSW displayed by LXR

 
 

    


File indexing completed on 2024-10-16 05:03:32

0001 /****************************************************************************
0002 *
0003 * Authors:
0004 *  Jan Kaspar (jan.kaspar@gmail.com)
0005 *  Christopher Misan (krzysmisan@gmail.com)
0006 *
0007 ****************************************************************************/
0008 
0009 #include "FWCore/Framework/interface/MakerMacros.h"
0010 #include "FWCore/Framework/interface/SourceFactory.h"
0011 #include "FWCore/Framework/interface/ESHandle.h"
0012 #include "FWCore/ParameterSet/interface/ParameterSet.h"
0013 #include "FWCore/Framework/interface/ESProducer.h"
0014 #include "FWCore/Framework/interface/EventSetupRecordIntervalFinder.h"
0015 #include "FWCore/Framework/interface/ESProducts.h"
0016 
0017 #include "CondFormats/RunInfo/interface/LHCInfo.h"
0018 #include "CondFormats/PPSObjects/interface/LHCOpticalFunctionsSetCollection.h"
0019 #include "CondFormats/PPSObjects/interface/CTPPSRPAlignmentCorrectionsData.h"
0020 #include "CondFormats/PPSObjects/interface/PPSDirectSimulationData.h"
0021 
0022 #include "CondFormats/DataRecord/interface/LHCInfoRcd.h"
0023 #include "CondFormats/DataRecord/interface/CTPPSOpticsRcd.h"
0024 #include "CondFormats/DataRecord/interface/PPSDirectSimulationDataRcd.h"
0025 
0026 #include "Geometry/VeryForwardGeometryBuilder/interface/CTPPSGeometry.h"
0027 #include "Geometry/VeryForwardGeometryBuilder/interface/CTPPSGeometryESCommon.h"
0028 #include "Geometry/VeryForwardGeometryBuilder/interface/DetGeomDescBuilder.h"
0029 
0030 #include "Geometry/Records/interface/IdealGeometryRecord.h"
0031 #include "Geometry/Records/interface/VeryForwardMisalignedGeometryRecord.h"
0032 #include "Geometry/Records/interface/VeryForwardRealGeometryRecord.h"
0033 
0034 #include "CalibPPS/ESProducers/interface/CTPPSRPAlignmentCorrectionsDataESSourceXMLCommon.h"
0035 
0036 #include "CLHEP/Random/RandFlat.h"
0037 #include "CLHEP/Random/JamesRandom.h"
0038 
0039 #include <memory>
0040 #include <vector>
0041 #include <string>
0042 #include <map>
0043 #include <set>
0044 
0045 #include "TFile.h"
0046 #include "TH2D.h"
0047 
0048 //----------------------------------------------------------------------------------------------------
0049 
0050 class CTPPSCompositeESSource : public edm::ESProducer, public edm::EventSetupRecordIntervalFinder {
0051 public:
0052   CTPPSCompositeESSource(const edm::ParameterSet &);
0053 
0054   static void fillDescriptions(edm::ConfigurationDescriptions &);
0055 
0056   std::unique_ptr<LHCInfo> produceLhcInfo(const LHCInfoRcd &);
0057   std::unique_ptr<LHCOpticalFunctionsSetCollection> produceOptics(const CTPPSOpticsRcd &);
0058   std::unique_ptr<PPSDirectSimulationData> produceDirectSimuData(const PPSDirectSimulationDataRcd &);
0059 
0060   std::shared_ptr<CTPPSRPAlignmentCorrectionsData> produceRealAlignments(const RPRealAlignmentRecord &);
0061   std::shared_ptr<CTPPSRPAlignmentCorrectionsData> produceMisalignedAlignments(const RPMisalignedAlignmentRecord &);
0062 
0063   std::shared_ptr<CTPPSGeometry> produceRealTG(const VeryForwardRealGeometryRecord &);
0064   std::shared_ptr<CTPPSGeometry> produceMisalignedTG(const VeryForwardMisalignedGeometryRecord &);
0065 
0066 private:
0067   // config parameters
0068   std::string compactViewTag_;
0069   std::string lhcInfoLabel_;
0070   std::string opticsLabel_;
0071   unsigned int generateEveryNEvents_;
0072   unsigned int verbosity_;
0073   const bool isRun2_;
0074 
0075   // ES tokens
0076   edm::ESGetToken<DDCompactView, IdealGeometryRecord> tokenCompactViewReal_, tokenCompactViewMisaligned_;
0077 
0078   template <typename T>
0079   struct BinData {
0080     double min, max;
0081     T data;
0082   };
0083 
0084   struct ProfileData {
0085     // LHCInfo
0086     double beamEnergy, xangle, betaStar;
0087     std::vector<BinData<std::pair<double, double>>> xangleBetaStarBins;
0088 
0089     // optics
0090     LHCOpticalFunctionsSetCollection lhcOptical;
0091 
0092     // geometry
0093     std::shared_ptr<DDCompactView> ddCompactView;
0094     std::shared_ptr<DetGeomDesc> misalignedGD;
0095     std::shared_ptr<DetGeomDesc> realGD;
0096     std::shared_ptr<CTPPSGeometry> misalignedTG;
0097     std::shared_ptr<CTPPSGeometry> realTG;
0098 
0099     // alignment
0100     std::shared_ptr<CTPPSRPAlignmentCorrectionsData> acReal, acMisaligned;
0101 
0102     // direct simulation configuration
0103     PPSDirectSimulationData directSimuData;
0104   };
0105 
0106   // profile variables
0107   std::vector<BinData<ProfileData>> profile_bins_;
0108   const ProfileData *currentProfile_;
0109 
0110   // random engine
0111   std::unique_ptr<CLHEP::HepRandomEngine> m_engine_;
0112 
0113   // methods to pre-compute profile data
0114   void buildLHCInfo(const edm::ParameterSet &profile, ProfileData &pData);
0115   void buildOptics(const edm::ParameterSet &profile, ProfileData &pData);
0116   void buildAlignment(const edm::ParameterSet &profile, ProfileData &pData);
0117   void buildDirectSimuData(const edm::ParameterSet &profile, ProfileData &pData);
0118 
0119   // flag whether the geometry (for all profiles) has been built
0120   bool geometryBuilt_;
0121 
0122   // this build method is different from all others - it is only called at the first
0123   // geometry request since the ideal geometry must be obtained from ES;
0124   // this method updates all profiles and builds all flavours of geometries
0125   void buildGeometry(const DDCompactView &cpv);
0126 
0127   // event id for which method "setIntervalFor" set new profile
0128   edm::EventID previously_set_eventID_;
0129 
0130   // method set IOV (common to all products)
0131   void setIntervalFor(const edm::eventsetup::EventSetupRecordKey &,
0132                       const edm::IOVSyncValue &,
0133                       edm::ValidityInterval &) override;
0134 };
0135 
0136 //----------------------------------------------------------------------------------------------------
0137 
0138 CTPPSCompositeESSource::CTPPSCompositeESSource(const edm::ParameterSet &conf)
0139     : compactViewTag_(conf.getParameter<std::string>("compactViewTag")),
0140       lhcInfoLabel_(conf.getParameter<std::string>("lhcInfoLabel")),
0141       opticsLabel_(conf.getParameter<std::string>("opticsLabel")),
0142       generateEveryNEvents_(conf.getUntrackedParameter<unsigned int>("generateEveryNEvents")),
0143       verbosity_(conf.getUntrackedParameter<unsigned int>("verbosity")),
0144       isRun2_(conf.getParameter<bool>("isRun2")),
0145       m_engine_(new CLHEP::HepJamesRandom(conf.getParameter<unsigned int>("seed"))),
0146       geometryBuilt_(false) {
0147   double l_int_sum = 0;
0148 
0149   for (const auto &cfg : conf.getParameter<std::vector<edm::ParameterSet>>("periods")) {
0150     double l_int = cfg.getParameter<double>("L_int");
0151 
0152     profile_bins_.emplace_back(BinData<ProfileData>{l_int_sum, l_int_sum + l_int, ProfileData()});
0153 
0154     l_int_sum += l_int;
0155 
0156     auto &pData = profile_bins_.back().data;
0157 
0158     buildLHCInfo(cfg, pData);
0159     buildOptics(cfg, pData);
0160     buildAlignment(cfg, pData);
0161     buildDirectSimuData(cfg, pData);
0162   }
0163 
0164   // normalise L_int sums to probabilities
0165   for (auto &bin : profile_bins_) {
0166     bin.min /= l_int_sum;
0167     bin.max /= l_int_sum;
0168   }
0169 
0170   // framework registrations
0171   setWhatProduced(this, &CTPPSCompositeESSource::produceLhcInfo, edm::es::Label(lhcInfoLabel_));
0172   setWhatProduced(this, &CTPPSCompositeESSource::produceOptics, edm::es::Label(opticsLabel_));
0173   setWhatProduced(this, &CTPPSCompositeESSource::produceDirectSimuData);
0174 
0175   tokenCompactViewReal_ = setWhatProduced(this, &CTPPSCompositeESSource::produceRealTG)
0176                               .consumesFrom<DDCompactView, IdealGeometryRecord>(edm::ESInputTag("", compactViewTag_));
0177   tokenCompactViewMisaligned_ =
0178       setWhatProduced(this, &CTPPSCompositeESSource::produceMisalignedTG)
0179           .consumesFrom<DDCompactView, IdealGeometryRecord>(edm::ESInputTag("", compactViewTag_));
0180 
0181   findingRecord<LHCInfoRcd>();
0182   findingRecord<CTPPSOpticsRcd>();
0183   findingRecord<PPSDirectSimulationDataRcd>();
0184   findingRecord<RPRealAlignmentRecord>();
0185   findingRecord<RPMisalignedAlignmentRecord>();
0186   findingRecord<VeryForwardRealGeometryRecord>();
0187   findingRecord<VeryForwardMisalignedGeometryRecord>();
0188 }
0189 
0190 //----------------------------------------------------------------------------------------------------
0191 
0192 void CTPPSCompositeESSource::fillDescriptions(edm::ConfigurationDescriptions &descriptions) {
0193   edm::ParameterSetDescription desc;
0194   desc.add<std::string>("compactViewTag", "")->setComment("label of the geometry compact view");
0195   desc.add<std::string>("lhcInfoLabel", "")->setComment("label of the LHCInfo record");
0196   desc.add<std::string>("opticsLabel", "")->setComment("label of the optics record");
0197   desc.add<unsigned int>("seed", 1)->setComment("random seed");
0198   desc.add<bool>("isRun2", false)->setComment("use diamond's run 2 geometry definition?");
0199   desc.addUntracked<unsigned int>("generateEveryNEvents", 1)->setComment("how often to switch conditions");
0200   desc.addUntracked<unsigned int>("verbosity", 0);
0201 
0202   edm::ParameterSetDescription desc_profile;
0203   std::vector<edm::ParameterSet> vp;
0204   desc_profile.add<double>("L_int", 0.)->setComment("integrated luminosity");
0205 
0206   // lhcInfo
0207   edm::ParameterSetDescription desc_profile_ctppsLHCInfo;
0208   desc_profile_ctppsLHCInfo.add<double>("xangle", -1)
0209       ->setComment("constant xangle, if negative, the xangle/beta* distribution will be used");
0210   desc_profile_ctppsLHCInfo.add<double>("betaStar", 0.)->setComment("constant beta*");
0211   desc_profile_ctppsLHCInfo.add<double>("beamEnergy", 0.)->setComment("beam energy");
0212   desc_profile_ctppsLHCInfo.add<std::string>("xangleBetaStarHistogramFile", "")
0213       ->setComment("ROOT file with xangle/beta* distribution");
0214   desc_profile_ctppsLHCInfo.add<std::string>("xangleBetaStarHistogramObject", "")
0215       ->setComment("xangle distribution object in the ROOT file");
0216   desc_profile.add<edm::ParameterSetDescription>("ctppsLHCInfo", desc_profile_ctppsLHCInfo);
0217 
0218   // optics
0219   edm::ParameterSetDescription desc_profile_ctppsOpticalFunctions;
0220   edm::ParameterSetDescription of_desc;
0221   of_desc.add<double>("xangle")->setComment("half crossing angle value in urad");
0222   of_desc.add<edm::FileInPath>("fileName")->setComment("ROOT file with optical functions");
0223   std::vector<edm::ParameterSet> of;
0224   desc_profile_ctppsOpticalFunctions.addVPSet("opticalFunctions", of_desc, of)
0225       ->setComment("list of optical functions at different crossing angles");
0226 
0227   edm::ParameterSetDescription sp_desc;
0228   sp_desc.add<unsigned int>("rpId")->setComment("associated detector DetId");
0229   sp_desc.add<std::string>("dirName")->setComment("associated path to the optical functions file");
0230   sp_desc.add<double>("z")->setComment("longitudinal position at scoring plane/detector");
0231   std::vector<edm::ParameterSet> sp;
0232   desc_profile_ctppsOpticalFunctions.addVPSet("scoringPlanes", sp_desc, sp)
0233       ->setComment("list of sensitive planes/detectors stations");
0234   desc_profile.add<edm::ParameterSetDescription>("ctppsOpticalFunctions", desc_profile_ctppsOpticalFunctions);
0235 
0236   // alignment
0237   edm::ParameterSetDescription desc_profile_ctppsRPAlignmentCorrectionsDataXML;
0238   desc_profile_ctppsRPAlignmentCorrectionsDataXML.add<std::vector<std::string>>("MeasuredFiles");
0239   desc_profile_ctppsRPAlignmentCorrectionsDataXML.add<std::vector<std::string>>("RealFiles");
0240   desc_profile_ctppsRPAlignmentCorrectionsDataXML.add<std::vector<std::string>>("MisalignedFiles");
0241   desc_profile.add<edm::ParameterSetDescription>("ctppsRPAlignmentCorrectionsDataXML",
0242                                                  desc_profile_ctppsRPAlignmentCorrectionsDataXML);
0243 
0244   // direct simu config
0245   edm::ParameterSetDescription desc_profile_ctppsDirectSimuData;
0246   desc_profile_ctppsDirectSimuData.add<std::string>("empiricalAperture45");
0247   desc_profile_ctppsDirectSimuData.add<std::string>("empiricalAperture56");
0248 
0249   desc_profile_ctppsDirectSimuData.add<std::string>("timeResolutionDiamonds45");
0250   desc_profile_ctppsDirectSimuData.add<std::string>("timeResolutionDiamonds56");
0251 
0252   edm::ParameterSetDescription eps_desc;
0253   eps_desc.add<unsigned int>("rpId")->setComment("RP id");
0254   eps_desc.add<std::string>("file")->setComment("file name");
0255   eps_desc.add<std::string>("object")->setComment("path to the efficiency histogram");
0256   desc_profile_ctppsDirectSimuData.addVPSet("efficienciesPerRP", eps_desc, std::vector<edm::ParameterSet>());
0257   desc_profile_ctppsDirectSimuData.addVPSet("efficienciesPerPlane", eps_desc, std::vector<edm::ParameterSet>());
0258 
0259   desc_profile.add<edm::ParameterSetDescription>("ctppsDirectSimuData", desc_profile_ctppsDirectSimuData);
0260 
0261   desc.addVPSet("periods", desc_profile, vp)->setComment("profiles");
0262 
0263   descriptions.add("ctppsCompositeESSource", desc);
0264 }
0265 
0266 //----------------------------------------------------------------------------------------------------
0267 
0268 void CTPPSCompositeESSource::buildDirectSimuData(const edm::ParameterSet &profile, ProfileData &pData) {
0269   const auto &ctppsDirectSimuData = profile.getParameter<edm::ParameterSet>("ctppsDirectSimuData");
0270 
0271   pData.directSimuData.setEmpiricalAperture45(ctppsDirectSimuData.getParameter<std::string>("empiricalAperture45"));
0272   pData.directSimuData.setEmpiricalAperture56(ctppsDirectSimuData.getParameter<std::string>("empiricalAperture56"));
0273 
0274   pData.directSimuData.setTimeResolutionDiamonds45(
0275       ctppsDirectSimuData.getParameter<std::string>("timeResolutionDiamonds45"));
0276   pData.directSimuData.setTimeResolutionDiamonds56(
0277       ctppsDirectSimuData.getParameter<std::string>("timeResolutionDiamonds56"));
0278 
0279   for (const auto &ps : ctppsDirectSimuData.getParameterSetVector("efficienciesPerRP")) {
0280     const auto rpId = ps.getParameter<unsigned int>("rpId");
0281     const auto &file = ps.getParameter<std::string>("file");
0282     const auto &object = ps.getParameter<std::string>("object");
0283     pData.directSimuData.getEfficienciesPerRP()[rpId] = {file, object};
0284   }
0285 
0286   for (const auto &ps : ctppsDirectSimuData.getParameterSetVector("efficienciesPerPlane")) {
0287     const auto rpId = ps.getParameter<unsigned int>("rpId");
0288     const auto &file = ps.getParameter<std::string>("file");
0289     const auto &object = ps.getParameter<std::string>("object");
0290     pData.directSimuData.getEfficienciesPerPlane()[rpId] = {file, object};
0291   }
0292 }
0293 
0294 //----------------------------------------------------------------------------------------------------
0295 
0296 void CTPPSCompositeESSource::buildGeometry(const DDCompactView &cpv) {
0297   std::unique_ptr<DetGeomDesc> idealGD = detgeomdescbuilder::buildDetGeomDescFromCompactView(cpv, isRun2_);
0298 
0299   for (auto &pb : profile_bins_) {
0300     auto &p = pb.data;
0301 
0302     p.misalignedGD = CTPPSGeometryESCommon::applyAlignments(*(idealGD), p.acMisaligned.get());
0303     p.misalignedTG = std::make_shared<CTPPSGeometry>(p.misalignedGD.get(), verbosity_);
0304 
0305     p.realGD = CTPPSGeometryESCommon::applyAlignments(*(idealGD), p.acReal.get());
0306     p.realTG = std::make_shared<CTPPSGeometry>(p.realGD.get(), verbosity_);
0307   }
0308 
0309   geometryBuilt_ = true;
0310 }
0311 
0312 //----------------------------------------------------------------------------------------------------
0313 
0314 void CTPPSCompositeESSource::buildOptics(const edm::ParameterSet &profile, ProfileData &pData) {
0315   const auto &ctppsOpticalFunctions = profile.getParameter<edm::ParameterSet>("ctppsOpticalFunctions");
0316 
0317   struct FileInfo {
0318     double m_xangle;
0319     std::string m_fileName;
0320   };
0321 
0322   std::vector<FileInfo> fileInfo;
0323 
0324   for (const auto &pset : ctppsOpticalFunctions.getParameter<std::vector<edm::ParameterSet>>("opticalFunctions")) {
0325     fileInfo.emplace_back(pset.getParameter<double>("xangle"),
0326                           pset.getParameter<edm::FileInPath>("fileName").fullPath());
0327   }
0328 
0329   struct RPInfo {
0330     std::string m_dirName;
0331     double m_scoringPlaneZ;
0332   };
0333 
0334   std::unordered_map<unsigned int, RPInfo> rpInfo;
0335 
0336   for (const auto &pset : ctppsOpticalFunctions.getParameter<std::vector<edm::ParameterSet>>("scoringPlanes")) {
0337     rpInfo.emplace(pset.getParameter<unsigned int>("rpId"),
0338                    RPInfo{pset.getParameter<std::string>("dirName"), pset.getParameter<double>("z")});
0339   }
0340 
0341   for (const auto &fi : fileInfo) {
0342     std::unordered_map<unsigned int, LHCOpticalFunctionsSet> xa_data;
0343 
0344     for (const auto &rpi : rpInfo) {
0345       LHCOpticalFunctionsSet fcn(fi.m_fileName, rpi.second.m_dirName, rpi.second.m_scoringPlaneZ);
0346       xa_data.emplace(rpi.first, std::move(fcn));
0347     }
0348 
0349     pData.lhcOptical.emplace(fi.m_xangle, xa_data);
0350   }
0351 }
0352 
0353 //----------------------------------------------------------------------------------------------------
0354 
0355 void CTPPSCompositeESSource::buildAlignment(const edm::ParameterSet &cfg, ProfileData &pData) {
0356   // load alignment data
0357   auto ctppsRPAlignmentCorrectionsDataXMLPSet =
0358       cfg.getParameter<edm::ParameterSet>("ctppsRPAlignmentCorrectionsDataXML");
0359   ctppsRPAlignmentCorrectionsDataXMLPSet.addUntrackedParameter("verbosity", verbosity_);
0360 
0361   CTPPSRPAlignmentCorrectionsDataESSourceXMLCommon ctppsRPAlignmentCorrectionsDataESSourceXMLCommon(
0362       ctppsRPAlignmentCorrectionsDataXMLPSet);
0363 
0364   // store the first entry from the alignment sequence (more cannot be done)
0365   pData.acReal = std::make_shared<CTPPSRPAlignmentCorrectionsData>(
0366       ctppsRPAlignmentCorrectionsDataESSourceXMLCommon.acsReal.empty()
0367           ? CTPPSRPAlignmentCorrectionsData()
0368           : ctppsRPAlignmentCorrectionsDataESSourceXMLCommon.acsReal[0].second);
0369 
0370   pData.acMisaligned = std::make_shared<CTPPSRPAlignmentCorrectionsData>(
0371       ctppsRPAlignmentCorrectionsDataESSourceXMLCommon.acsMisaligned.empty()
0372           ? CTPPSRPAlignmentCorrectionsData()
0373           : ctppsRPAlignmentCorrectionsDataESSourceXMLCommon.acsMisaligned[0].second);
0374 }
0375 
0376 //----------------------------------------------------------------------------------------------------
0377 
0378 void CTPPSCompositeESSource::buildLHCInfo(const edm::ParameterSet &profile, ProfileData &pData) {
0379   const auto &ctppsLHCInfo = profile.getParameter<edm::ParameterSet>("ctppsLHCInfo");
0380 
0381   pData.beamEnergy = ctppsLHCInfo.getParameter<double>("beamEnergy");
0382   pData.betaStar = ctppsLHCInfo.getParameter<double>("betaStar");
0383   pData.xangle = ctppsLHCInfo.getParameter<double>("xangle");
0384 
0385   // continue only if distributed xangle/beta* shall be used
0386   if (pData.xangle > 0)
0387     return;
0388 
0389   edm::FileInPath fip(ctppsLHCInfo.getParameter<std::string>("xangleBetaStarHistogramFile").c_str());
0390   std::unique_ptr<TFile> f_in(TFile::Open(fip.fullPath().c_str()));
0391   if (!f_in)
0392     throw cms::Exception("PPS") << "Cannot open input file '"
0393                                 << ctppsLHCInfo.getParameter<std::string>("xangleBetaStarHistogramFile") << "'.";
0394 
0395   TH2D *h_xangle_beta_star =
0396       (TH2D *)f_in->Get(ctppsLHCInfo.getParameter<std::string>("xangleBetaStarHistogramObject").c_str());
0397   if (!h_xangle_beta_star)
0398     throw cms::Exception("PPS") << "Cannot load input object '"
0399                                 << ctppsLHCInfo.getParameter<std::string>("xangleBetaStarHistogramObject") << "'.";
0400 
0401   // extract non-empty bins, calculate weights
0402   double sum = 0.;
0403   for (int bi = 1; bi <= h_xangle_beta_star->GetNcells(); ++bi)
0404     sum += h_xangle_beta_star->GetBinContent(bi);
0405 
0406   double cw = 0.;
0407   for (int x = 1; x <= h_xangle_beta_star->GetNbinsX(); ++x)
0408     for (int y = 1; y <= h_xangle_beta_star->GetNbinsY(); ++y) {
0409       const double w = h_xangle_beta_star->GetBinContent(h_xangle_beta_star->GetBin(x, y)) / sum;
0410       if (w > 0.) {
0411         pData.xangleBetaStarBins.emplace_back(cw,
0412                                               cw + w,
0413                                               std::make_pair(h_xangle_beta_star->GetXaxis()->GetBinCenter(x),
0414                                                              h_xangle_beta_star->GetYaxis()->GetBinCenter(y)));
0415         cw += w;
0416       }
0417     }
0418 }
0419 
0420 //----------------------------------------------------------------------------------------------------
0421 
0422 void CTPPSCompositeESSource::setIntervalFor(const edm::eventsetup::EventSetupRecordKey &key,
0423                                             const edm::IOVSyncValue &iosv,
0424                                             edm::ValidityInterval &oValidity) {
0425   // determine new IOV
0426   edm::EventID beginEvent = iosv.eventID();
0427   edm::EventID endEvent(beginEvent.run(), beginEvent.luminosityBlock(), beginEvent.event() + generateEveryNEvents_);
0428   oValidity = edm::ValidityInterval(edm::IOVSyncValue(beginEvent), edm::IOVSyncValue(endEvent));
0429 
0430   // stop if new profile has already been generated
0431   if (beginEvent.run() == previously_set_eventID_.run() &&
0432       beginEvent.luminosityBlock() == previously_set_eventID_.luminosityBlock())
0433     return;
0434 
0435   previously_set_eventID_ = beginEvent;
0436 
0437   // randomly pick the next profile
0438   const double u = CLHEP::RandFlat::shoot(m_engine_.get(), 0., 1.);
0439 
0440   for (const auto &bin : profile_bins_) {
0441     if (bin.min <= u && u <= bin.max) {
0442       currentProfile_ = &bin.data;
0443       break;
0444     }
0445   }
0446 }
0447 
0448 //----------------------------------------------------------------------------------------------------
0449 
0450 std::shared_ptr<CTPPSRPAlignmentCorrectionsData> CTPPSCompositeESSource::produceRealAlignments(
0451     const RPRealAlignmentRecord &) {
0452   return currentProfile_->acReal;
0453 }
0454 
0455 //----------------------------------------------------------------------------------------------------
0456 
0457 std::shared_ptr<CTPPSRPAlignmentCorrectionsData> CTPPSCompositeESSource::produceMisalignedAlignments(
0458     const RPMisalignedAlignmentRecord &) {
0459   return currentProfile_->acMisaligned;
0460 }
0461 
0462 //----------------------------------------------------------------------------------------------------
0463 
0464 std::shared_ptr<CTPPSGeometry> CTPPSCompositeESSource::produceRealTG(const VeryForwardRealGeometryRecord &iRecord) {
0465   if (!geometryBuilt_)
0466     buildGeometry(iRecord.getRecord<IdealGeometryRecord>().get(tokenCompactViewReal_));
0467 
0468   return currentProfile_->realTG;
0469 }
0470 
0471 //----------------------------------------------------------------------------------------------------
0472 
0473 std::shared_ptr<CTPPSGeometry> CTPPSCompositeESSource::produceMisalignedTG(
0474     const VeryForwardMisalignedGeometryRecord &iRecord) {
0475   if (!geometryBuilt_)
0476     buildGeometry(iRecord.getRecord<IdealGeometryRecord>().get(tokenCompactViewMisaligned_));
0477 
0478   return currentProfile_->misalignedTG;
0479 }
0480 
0481 //----------------------------------------------------------------------------------------------------
0482 
0483 std::unique_ptr<PPSDirectSimulationData> CTPPSCompositeESSource::produceDirectSimuData(
0484     const PPSDirectSimulationDataRcd &) {
0485   return std::make_unique<PPSDirectSimulationData>(currentProfile_->directSimuData);
0486 }
0487 
0488 //----------------------------------------------------------------------------------------------------
0489 
0490 std::unique_ptr<LHCOpticalFunctionsSetCollection> CTPPSCompositeESSource::produceOptics(const CTPPSOpticsRcd &) {
0491   return std::make_unique<LHCOpticalFunctionsSetCollection>(currentProfile_->lhcOptical);
0492 }
0493 
0494 //----------------------------------------------------------------------------------------------------
0495 
0496 std::unique_ptr<LHCInfo> CTPPSCompositeESSource::produceLhcInfo(const LHCInfoRcd &) {
0497   double xangle = currentProfile_->xangle;
0498   double betaStar = currentProfile_->betaStar;
0499 
0500   if (currentProfile_->xangle < 0) {
0501     const double u = CLHEP::RandFlat::shoot(m_engine_.get(), 0., 1.);
0502     for (const auto &d : currentProfile_->xangleBetaStarBins) {
0503       if (d.min <= u && u <= d.max) {
0504         xangle = d.data.first;
0505         betaStar = d.data.second;
0506         break;
0507       }
0508     }
0509   }
0510 
0511   auto lhcInfo = std::make_unique<LHCInfo>();
0512   lhcInfo->setEnergy(currentProfile_->beamEnergy);
0513   lhcInfo->setCrossingAngle(xangle);
0514   lhcInfo->setBetaStar(betaStar);
0515 
0516   edm::LogInfo("PPS") << "new LHCInfo: xangle=" << xangle << ", betaStar=" << betaStar;
0517 
0518   return lhcInfo;
0519 }
0520 
0521 //----------------------------------------------------------------------------------------------------
0522 
0523 DEFINE_FWK_EVENTSETUP_SOURCE(CTPPSCompositeESSource);