/
githubmirror
/
cmssw
Обзор
Документация
Войти
/
githubmirror
/
cmssw
Код
Запросы
0
Пакеты
0
Релизы
0
Аналитика
Безопасность
master
CalibPPS/ESProducers/plugins/CTPPSCompositeESSource.cc
548 строк
24 KB
Christopher Jones
Made CTPPSCompositeESSource a concurrent Finder
01 июл 2026, 21:01
01 июл 2026, 21:01
e248f33
Код
Авторство
О чём код?
/**************************************************************************** * * Authors: * Jan Kaspar (jan.kaspar@gmail.com) * Christopher Misan (krzysmisan@gmail.com) * ****************************************************************************/ #include "FWCore/Framework/interface/MakerMacros.h" #include "FWCore/Framework/interface/SourceFactory.h" #include "FWCore/Framework/interface/ESHandle.h" #include "FWCore/ParameterSet/interface/ParameterSet.h" #include "FWCore/Framework/interface/ESProducer.h" #include "FWCore/Framework/interface/EventSetupRecordIntervalFinder.h" #include "FWCore/Framework/interface/ESProducts.h" #include "CondFormats/RunInfo/interface/LHCInfo.h" #include "CondFormats/PPSObjects/interface/LHCOpticalFunctionsSetCollection.h" #include "CondFormats/PPSObjects/interface/CTPPSRPAlignmentCorrectionsData.h" #include "CondFormats/PPSObjects/interface/PPSDirectSimulationData.h" #include "CondFormats/DataRecord/interface/LHCInfoRcd.h" #include "CondFormats/DataRecord/interface/CTPPSOpticsRcd.h" #include "CondFormats/DataRecord/interface/PPSDirectSimulationDataRcd.h" #include "Geometry/VeryForwardGeometryBuilder/interface/CTPPSGeometry.h" #include "Geometry/VeryForwardGeometryBuilder/interface/CTPPSGeometryESCommon.h" #include "Geometry/VeryForwardGeometryBuilder/interface/DetGeomDescBuilder.h" #include "Geometry/Records/interface/IdealGeometryRecord.h" #include "Geometry/Records/interface/VeryForwardMisalignedGeometryRecord.h" #include "Geometry/Records/interface/VeryForwardRealGeometryRecord.h" #include "CalibPPS/ESProducers/interface/CTPPSRPAlignmentCorrectionsDataESSourceXMLCommon.h" #include "CLHEP/Random/RandFlat.h" #include "CLHEP/Random/JamesRandom.h" #include <memory> #include <vector> #include <string> #include <map> #include <set> #include <mutex> #include "TFile.h" #include "TH2D.h" //---------------------------------------------------------------------------------------------------- class CTPPSCompositeESSource : public edm::ESProducer, public edm::EventSetupRecordIntervalFinder { public: CTPPSCompositeESSource(const edm::ParameterSet &); static void fillDescriptions(edm::ConfigurationDescriptions &); std::unique_ptr<LHCInfo> produceLhcInfo(const LHCInfoRcd &); std::unique_ptr<LHCOpticalFunctionsSetCollection> produceOptics(const CTPPSOpticsRcd &); std::unique_ptr<PPSDirectSimulationData> produceDirectSimuData(const PPSDirectSimulationDataRcd &); std::shared_ptr<CTPPSRPAlignmentCorrectionsData> produceRealAlignments(const RPRealAlignmentRecord &); std::shared_ptr<CTPPSRPAlignmentCorrectionsData> produceMisalignedAlignments(const RPMisalignedAlignmentRecord &); std::shared_ptr<CTPPSGeometry> produceRealTG(const VeryForwardRealGeometryRecord &); std::shared_ptr<CTPPSGeometry> produceMisalignedTG(const VeryForwardMisalignedGeometryRecord &); private: // config parameters std::string compactViewTag_; std::string lhcInfoLabel_; std::string opticsLabel_; unsigned int generateEveryNEvents_; unsigned int verbosity_; const bool isRun2_; // ES tokens edm::ESGetToken<DDCompactView, IdealGeometryRecord> tokenCompactViewReal_, tokenCompactViewMisaligned_; template <typename T> struct BinData { double min, max; T data; }; struct ProfileData { // LHCInfo double beamEnergy, xangle, betaStar; std::vector<BinData<std::pair<double, double>>> xangleBetaStarBins; // optics LHCOpticalFunctionsSetCollection lhcOptical; // geometry std::shared_ptr<DDCompactView> ddCompactView; std::shared_ptr<DetGeomDesc> misalignedGD; std::shared_ptr<DetGeomDesc> realGD; std::shared_ptr<CTPPSGeometry> misalignedTG; std::shared_ptr<CTPPSGeometry> realTG; // alignment std::shared_ptr<CTPPSRPAlignmentCorrectionsData> acReal, acMisaligned; // direct simulation configuration PPSDirectSimulationData directSimuData; }; // profile variables std::vector<BinData<ProfileData>> profile_bins_; std::vector<std::pair<edm::IOVSyncValue, int>> startIOVToBinIndex_; mutable std::mutex protectIndex_; //can't write while reading startIOVToBinIndex_; // random engine std::unique_ptr<CLHEP::HepRandomEngine> m_engine_; // methods to pre-compute profile data void buildLHCInfo(const edm::ParameterSet &profile, ProfileData &pData); void buildOptics(const edm::ParameterSet &profile, ProfileData &pData); void buildAlignment(const edm::ParameterSet &profile, ProfileData &pData); void buildDirectSimuData(const edm::ParameterSet &profile, ProfileData &pData); // flag whether the geometry (for all profiles) has been built bool geometryBuilt_; // this build method is different from all others - it is only called at the first // geometry request since the ideal geometry must be obtained from ES; // this method updates all profiles and builds all flavours of geometries void buildGeometry(const DDCompactView &cpv); // event id for which method "setIntervalFor" set new profile edm::EventID previously_set_eventID_; // method set IOV (common to all products) void setIntervalFor(const edm::eventsetup::EventSetupRecordKey &, const edm::IOVSyncValue &, edm::ValidityInterval &) final; bool isConcurrentFinder() const final { return true; } const ProfileData &findProfileFor(edm::ValidityInterval const &) const; }; //---------------------------------------------------------------------------------------------------- CTPPSCompositeESSource::CTPPSCompositeESSource(const edm::ParameterSet &conf) : compactViewTag_(conf.getParameter<std::string>("compactViewTag")), lhcInfoLabel_(conf.getParameter<std::string>("lhcInfoLabel")), opticsLabel_(conf.getParameter<std::string>("opticsLabel")), generateEveryNEvents_(conf.getUntrackedParameter<unsigned int>("generateEveryNEvents")), verbosity_(conf.getUntrackedParameter<unsigned int>("verbosity")), isRun2_(conf.getParameter<bool>("isRun2")), m_engine_(new CLHEP::HepJamesRandom(conf.getParameter<unsigned int>("seed"))), geometryBuilt_(false) { double l_int_sum = 0; for (const auto &cfg : conf.getParameter<std::vector<edm::ParameterSet>>("periods")) { double l_int = cfg.getParameter<double>("L_int"); profile_bins_.emplace_back(BinData<ProfileData>{l_int_sum, l_int_sum + l_int, ProfileData()}); l_int_sum += l_int; auto &pData = profile_bins_.back().data; buildLHCInfo(cfg, pData); buildOptics(cfg, pData); buildAlignment(cfg, pData); buildDirectSimuData(cfg, pData); } // normalise L_int sums to probabilities for (auto &bin : profile_bins_) { bin.min /= l_int_sum; bin.max /= l_int_sum; } // framework registrations setWhatProduced(this, &CTPPSCompositeESSource::produceLhcInfo, edm::es::Label(lhcInfoLabel_)); setWhatProduced(this, &CTPPSCompositeESSource::produceOptics, edm::es::Label(opticsLabel_)); setWhatProduced(this, &CTPPSCompositeESSource::produceDirectSimuData); tokenCompactViewReal_ = setWhatProduced(this, &CTPPSCompositeESSource::produceRealTG) .consumesFrom<DDCompactView, IdealGeometryRecord>(edm::ESInputTag("", compactViewTag_)); tokenCompactViewMisaligned_ = setWhatProduced(this, &CTPPSCompositeESSource::produceMisalignedTG) .consumesFrom<DDCompactView, IdealGeometryRecord>(edm::ESInputTag("", compactViewTag_)); findingRecord<LHCInfoRcd>(); findingRecord<CTPPSOpticsRcd>(); findingRecord<PPSDirectSimulationDataRcd>(); findingRecord<RPRealAlignmentRecord>(); findingRecord<RPMisalignedAlignmentRecord>(); findingRecord<VeryForwardRealGeometryRecord>(); findingRecord<VeryForwardMisalignedGeometryRecord>(); } //---------------------------------------------------------------------------------------------------- void CTPPSCompositeESSource::fillDescriptions(edm::ConfigurationDescriptions &descriptions) { edm::ParameterSetDescription desc; desc.add<std::string>("compactViewTag", "")->setComment("label of the geometry compact view"); desc.add<std::string>("lhcInfoLabel", "")->setComment("label of the LHCInfo record"); desc.add<std::string>("opticsLabel", "")->setComment("label of the optics record"); desc.add<unsigned int>("seed", 1)->setComment("random seed"); desc.add<bool>("isRun2", false)->setComment("use diamond's run 2 geometry definition?"); desc.addUntracked<unsigned int>("generateEveryNEvents", 1)->setComment("how often to switch conditions"); desc.addUntracked<unsigned int>("verbosity", 0); edm::ParameterSetDescription desc_profile; std::vector<edm::ParameterSet> vp; desc_profile.add<double>("L_int", 0.)->setComment("integrated luminosity"); // lhcInfo edm::ParameterSetDescription desc_profile_ctppsLHCInfo; desc_profile_ctppsLHCInfo.add<double>("xangle", -1) ->setComment("constant xangle, if negative, the xangle/beta* distribution will be used"); desc_profile_ctppsLHCInfo.add<double>("betaStar", 0.)->setComment("constant beta*"); desc_profile_ctppsLHCInfo.add<double>("beamEnergy", 0.)->setComment("beam energy"); desc_profile_ctppsLHCInfo.add<std::string>("xangleBetaStarHistogramFile", "") ->setComment("ROOT file with xangle/beta* distribution"); desc_profile_ctppsLHCInfo.add<std::string>("xangleBetaStarHistogramObject", "") ->setComment("xangle distribution object in the ROOT file"); desc_profile.add<edm::ParameterSetDescription>("ctppsLHCInfo", desc_profile_ctppsLHCInfo); // optics edm::ParameterSetDescription desc_profile_ctppsOpticalFunctions; edm::ParameterSetDescription of_desc; of_desc.add<double>("xangle")->setComment("half crossing angle value in urad"); of_desc.add<edm::FileInPath>("fileName")->setComment("ROOT file with optical functions"); std::vector<edm::ParameterSet> of; desc_profile_ctppsOpticalFunctions.addVPSet("opticalFunctions", of_desc, of) ->setComment("list of optical functions at different crossing angles"); edm::ParameterSetDescription sp_desc; sp_desc.add<unsigned int>("rpId")->setComment("associated detector DetId"); sp_desc.add<std::string>("dirName")->setComment("associated path to the optical functions file"); sp_desc.add<double>("z")->setComment("longitudinal position at scoring plane/detector"); std::vector<edm::ParameterSet> sp; desc_profile_ctppsOpticalFunctions.addVPSet("scoringPlanes", sp_desc, sp) ->setComment("list of sensitive planes/detectors stations"); desc_profile.add<edm::ParameterSetDescription>("ctppsOpticalFunctions", desc_profile_ctppsOpticalFunctions); // alignment edm::ParameterSetDescription desc_profile_ctppsRPAlignmentCorrectionsDataXML; desc_profile_ctppsRPAlignmentCorrectionsDataXML.add<std::vector<std::string>>("MeasuredFiles"); desc_profile_ctppsRPAlignmentCorrectionsDataXML.add<std::vector<std::string>>("RealFiles"); desc_profile_ctppsRPAlignmentCorrectionsDataXML.add<std::vector<std::string>>("MisalignedFiles"); desc_profile.add<edm::ParameterSetDescription>("ctppsRPAlignmentCorrectionsDataXML", desc_profile_ctppsRPAlignmentCorrectionsDataXML); // direct simu config edm::ParameterSetDescription desc_profile_ctppsDirectSimuData; desc_profile_ctppsDirectSimuData.add<std::string>("empiricalAperture45"); desc_profile_ctppsDirectSimuData.add<std::string>("empiricalAperture56"); desc_profile_ctppsDirectSimuData.add<std::string>("timeResolutionDiamonds45"); desc_profile_ctppsDirectSimuData.add<std::string>("timeResolutionDiamonds56"); edm::ParameterSetDescription eps_desc; eps_desc.add<unsigned int>("rpId")->setComment("RP id"); eps_desc.add<std::string>("file")->setComment("file name"); eps_desc.add<std::string>("object")->setComment("path to the efficiency histogram"); desc_profile_ctppsDirectSimuData.addVPSet("efficienciesPerRP", eps_desc, std::vector<edm::ParameterSet>()); desc_profile_ctppsDirectSimuData.addVPSet("efficienciesPerPlane", eps_desc, std::vector<edm::ParameterSet>()); desc_profile.add<edm::ParameterSetDescription>("ctppsDirectSimuData", desc_profile_ctppsDirectSimuData); desc.addVPSet("periods", desc_profile, vp)->setComment("profiles"); descriptions.add("ctppsCompositeESSource", desc); } //---------------------------------------------------------------------------------------------------- void CTPPSCompositeESSource::buildDirectSimuData(const edm::ParameterSet &profile, ProfileData &pData) { const auto &ctppsDirectSimuData = profile.getParameter<edm::ParameterSet>("ctppsDirectSimuData"); pData.directSimuData.setEmpiricalAperture45(ctppsDirectSimuData.getParameter<std::string>("empiricalAperture45")); pData.directSimuData.setEmpiricalAperture56(ctppsDirectSimuData.getParameter<std::string>("empiricalAperture56")); pData.directSimuData.setTimeResolutionDiamonds45( ctppsDirectSimuData.getParameter<std::string>("timeResolutionDiamonds45")); pData.directSimuData.setTimeResolutionDiamonds56( ctppsDirectSimuData.getParameter<std::string>("timeResolutionDiamonds56")); for (const auto &ps : ctppsDirectSimuData.getParameterSetVector("efficienciesPerRP")) { const auto rpId = ps.getParameter<unsigned int>("rpId"); const auto &file = ps.getParameter<std::string>("file"); const auto &object = ps.getParameter<std::string>("object"); pData.directSimuData.getEfficienciesPerRP()[rpId] = {file, object}; } for (const auto &ps : ctppsDirectSimuData.getParameterSetVector("efficienciesPerPlane")) { const auto rpId = ps.getParameter<unsigned int>("rpId"); const auto &file = ps.getParameter<std::string>("file"); const auto &object = ps.getParameter<std::string>("object"); pData.directSimuData.getEfficienciesPerPlane()[rpId] = {file, object}; } } //---------------------------------------------------------------------------------------------------- void CTPPSCompositeESSource::buildGeometry(const DDCompactView &cpv) { std::unique_ptr<DetGeomDesc> idealGD = detgeomdescbuilder::buildDetGeomDescFromCompactView(cpv, isRun2_); for (auto &pb : profile_bins_) { auto &p = pb.data; p.misalignedGD = CTPPSGeometryESCommon::applyAlignments(*(idealGD), p.acMisaligned.get()); p.misalignedTG = std::make_shared<CTPPSGeometry>(p.misalignedGD.get(), verbosity_); p.realGD = CTPPSGeometryESCommon::applyAlignments(*(idealGD), p.acReal.get()); p.realTG = std::make_shared<CTPPSGeometry>(p.realGD.get(), verbosity_); } geometryBuilt_ = true; } //---------------------------------------------------------------------------------------------------- void CTPPSCompositeESSource::buildOptics(const edm::ParameterSet &profile, ProfileData &pData) { const auto &ctppsOpticalFunctions = profile.getParameter<edm::ParameterSet>("ctppsOpticalFunctions"); struct FileInfo { double m_xangle; std::string m_fileName; }; std::vector<FileInfo> fileInfo; for (const auto &pset : ctppsOpticalFunctions.getParameter<std::vector<edm::ParameterSet>>("opticalFunctions")) { fileInfo.emplace_back(pset.getParameter<double>("xangle"), pset.getParameter<edm::FileInPath>("fileName").fullPath()); } struct RPInfo { std::string m_dirName; double m_scoringPlaneZ; }; std::unordered_map<unsigned int, RPInfo> rpInfo; for (const auto &pset : ctppsOpticalFunctions.getParameter<std::vector<edm::ParameterSet>>("scoringPlanes")) { rpInfo.emplace(pset.getParameter<unsigned int>("rpId"), RPInfo{pset.getParameter<std::string>("dirName"), pset.getParameter<double>("z")}); } for (const auto &fi : fileInfo) { std::unordered_map<unsigned int, LHCOpticalFunctionsSet> xa_data; for (const auto &rpi : rpInfo) { LHCOpticalFunctionsSet fcn(fi.m_fileName, rpi.second.m_dirName, rpi.second.m_scoringPlaneZ); xa_data.emplace(rpi.first, std::move(fcn)); } pData.lhcOptical.emplace(fi.m_xangle, xa_data); } } //---------------------------------------------------------------------------------------------------- void CTPPSCompositeESSource::buildAlignment(const edm::ParameterSet &cfg, ProfileData &pData) { // load alignment data auto ctppsRPAlignmentCorrectionsDataXMLPSet = cfg.getParameter<edm::ParameterSet>("ctppsRPAlignmentCorrectionsDataXML"); ctppsRPAlignmentCorrectionsDataXMLPSet.addUntrackedParameter("verbosity", verbosity_); CTPPSRPAlignmentCorrectionsDataESSourceXMLCommon ctppsRPAlignmentCorrectionsDataESSourceXMLCommon( ctppsRPAlignmentCorrectionsDataXMLPSet); // store the first entry from the alignment sequence (more cannot be done) pData.acReal = std::make_shared<CTPPSRPAlignmentCorrectionsData>( ctppsRPAlignmentCorrectionsDataESSourceXMLCommon.acsReal.empty() ? CTPPSRPAlignmentCorrectionsData() : ctppsRPAlignmentCorrectionsDataESSourceXMLCommon.acsReal[0].second); pData.acMisaligned = std::make_shared<CTPPSRPAlignmentCorrectionsData>( ctppsRPAlignmentCorrectionsDataESSourceXMLCommon.acsMisaligned.empty() ? CTPPSRPAlignmentCorrectionsData() : ctppsRPAlignmentCorrectionsDataESSourceXMLCommon.acsMisaligned[0].second); } //---------------------------------------------------------------------------------------------------- void CTPPSCompositeESSource::buildLHCInfo(const edm::ParameterSet &profile, ProfileData &pData) { const auto &ctppsLHCInfo = profile.getParameter<edm::ParameterSet>("ctppsLHCInfo"); pData.beamEnergy = ctppsLHCInfo.getParameter<double>("beamEnergy"); pData.betaStar = ctppsLHCInfo.getParameter<double>("betaStar"); pData.xangle = ctppsLHCInfo.getParameter<double>("xangle"); // continue only if distributed xangle/beta* shall be used if (pData.xangle > 0) return; edm::FileInPath fip(ctppsLHCInfo.getParameter<std::string>("xangleBetaStarHistogramFile").c_str()); std::unique_ptr<TFile> f_in(TFile::Open(fip.fullPath().c_str())); if (!f_in) throw cms::Exception("PPS") << "Cannot open input file '" << ctppsLHCInfo.getParameter<std::string>("xangleBetaStarHistogramFile") << "'."; TH2D *h_xangle_beta_star = (TH2D *)f_in->Get(ctppsLHCInfo.getParameter<std::string>("xangleBetaStarHistogramObject").c_str()); if (!h_xangle_beta_star) throw cms::Exception("PPS") << "Cannot load input object '" << ctppsLHCInfo.getParameter<std::string>("xangleBetaStarHistogramObject") << "'."; // extract non-empty bins, calculate weights double sum = 0.; for (int bi = 1; bi <= h_xangle_beta_star->GetNcells(); ++bi) sum += h_xangle_beta_star->GetBinContent(bi); double cw = 0.; for (int x = 1; x <= h_xangle_beta_star->GetNbinsX(); ++x) for (int y = 1; y <= h_xangle_beta_star->GetNbinsY(); ++y) { const double w = h_xangle_beta_star->GetBinContent(h_xangle_beta_star->GetBin(x, y)) / sum; if (w > 0.) { pData.xangleBetaStarBins.emplace_back(cw, cw + w, std::make_pair(h_xangle_beta_star->GetXaxis()->GetBinCenter(x), h_xangle_beta_star->GetYaxis()->GetBinCenter(y))); cw += w; } } } //---------------------------------------------------------------------------------------------------- void CTPPSCompositeESSource::setIntervalFor(const edm::eventsetup::EventSetupRecordKey &key, const edm::IOVSyncValue &iosv, edm::ValidityInterval &oValidity) { // determine new IOV edm::EventID beginEvent = iosv.eventID(); edm::EventID endEvent(beginEvent.run(), beginEvent.luminosityBlock(), beginEvent.event() + generateEveryNEvents_); oValidity = edm::ValidityInterval(edm::IOVSyncValue(beginEvent), edm::IOVSyncValue(endEvent)); std::lock_guard guard(protectIndex_); if (not startIOVToBinIndex_.empty()) { if (oValidity.first() == startIOVToBinIndex_.back().first) { return; } } // randomly pick the next profile const double u = CLHEP::RandFlat::shoot(m_engine_.get(), 0., 1.); size_t index = 0; for (const auto &bin : profile_bins_) { if (bin.min <= u && u <= bin.max) { break; } ++index; } assert(index != profile_bins_.size()); startIOVToBinIndex_.emplace_back(beginEvent, index); } //---------------------------------------------------------------------------------------------------- const CTPPSCompositeESSource::ProfileData &CTPPSCompositeESSource::findProfileFor( edm::ValidityInterval const &iIOV) const { std::lock_guard guard{protectIndex_}; size_t index = profile_bins_.size(); for (auto it = startIOVToBinIndex_.rbegin(); it != startIOVToBinIndex_.rend(); ++it) { if (iIOV.validFor(it->first) or (iIOV.last() == edm::IOVSyncValue::invalidIOVSyncValue() and iIOV.first() <= it->first)) { index = it->second; break; } } assert(index < profile_bins_.size()); return profile_bins_[index].data; } //---------------------------------------------------------------------------------------------------- std::shared_ptr<CTPPSRPAlignmentCorrectionsData> CTPPSCompositeESSource::produceRealAlignments( const RPRealAlignmentRecord &iRecord) { return findProfileFor(iRecord.validityInterval()).acReal; } //---------------------------------------------------------------------------------------------------- std::shared_ptr<CTPPSRPAlignmentCorrectionsData> CTPPSCompositeESSource::produceMisalignedAlignments( const RPMisalignedAlignmentRecord &iRecord) { return findProfileFor(iRecord.validityInterval()).acMisaligned; } //---------------------------------------------------------------------------------------------------- std::shared_ptr<CTPPSGeometry> CTPPSCompositeESSource::produceRealTG(const VeryForwardRealGeometryRecord &iRecord) { if (!geometryBuilt_) buildGeometry(iRecord.getRecord<IdealGeometryRecord>().get(tokenCompactViewReal_)); return findProfileFor(iRecord.validityInterval()).realTG; } //---------------------------------------------------------------------------------------------------- std::shared_ptr<CTPPSGeometry> CTPPSCompositeESSource::produceMisalignedTG( const VeryForwardMisalignedGeometryRecord &iRecord) { if (!geometryBuilt_) buildGeometry(iRecord.getRecord<IdealGeometryRecord>().get(tokenCompactViewMisaligned_)); return findProfileFor(iRecord.validityInterval()).misalignedTG; } //---------------------------------------------------------------------------------------------------- std::unique_ptr<PPSDirectSimulationData> CTPPSCompositeESSource::produceDirectSimuData( const PPSDirectSimulationDataRcd &iRecord) { return std::make_unique<PPSDirectSimulationData>(findProfileFor(iRecord.validityInterval()).directSimuData); } //---------------------------------------------------------------------------------------------------- std::unique_ptr<LHCOpticalFunctionsSetCollection> CTPPSCompositeESSource::produceOptics(const CTPPSOpticsRcd &iRecord) { return std::make_unique<LHCOpticalFunctionsSetCollection>(findProfileFor(iRecord.validityInterval()).lhcOptical); } //---------------------------------------------------------------------------------------------------- std::unique_ptr<LHCInfo> CTPPSCompositeESSource::produceLhcInfo(const LHCInfoRcd &iRecord) { auto const &profile = findProfileFor(iRecord.validityInterval()); double xangle = profile.xangle; double betaStar = profile.betaStar; if (profile.xangle < 0) { const double u = CLHEP::RandFlat::shoot(m_engine_.get(), 0., 1.); for (const auto &d : profile.xangleBetaStarBins) { if (d.min <= u && u <= d.max) { xangle = d.data.first; betaStar = d.data.second; break; } } } auto lhcInfo = std::make_unique<LHCInfo>(); lhcInfo->setEnergy(profile.beamEnergy); lhcInfo->setCrossingAngle(xangle); lhcInfo->setBetaStar(betaStar); edm::LogInfo("PPS") << "new LHCInfo: xangle=" << xangle << ", betaStar=" << betaStar; return lhcInfo; } //---------------------------------------------------------------------------------------------------- DEFINE_FWK_EVENTSETUP_SOURCE(CTPPSCompositeESSource);