Back to home page

Project CMSSW displayed by LXR

 
 

    


File indexing completed on 2024-04-06 12:03:18

0001 #include "CondCore/CondDB/interface/ConnectionPool.h"
0002 #include "CondCore/PopCon/interface/PopConAnalyzer.h"
0003 #include "CondCore/PopCon/interface/PopConSourceHandler.h"
0004 #include "CondFormats/Common/interface/TimeConversions.h"
0005 #include "CondFormats/RunInfo/interface/LHCInfoPerFill.h"
0006 #include "CondTools/RunInfo/interface/LumiSectionFilter.h"
0007 #include "CondTools/RunInfo/interface/LHCInfoHelper.h"
0008 #include "CondTools/RunInfo/interface/OMSAccess.h"
0009 #include "CoralBase/Attribute.h"
0010 #include "CoralBase/AttributeList.h"
0011 #include "CoralBase/AttributeSpecification.h"
0012 #include "CoralBase/TimeStamp.h"
0013 #include "FWCore/Framework/interface/MakerMacros.h"
0014 #include "FWCore/MessageLogger/interface/MessageLogger.h"
0015 #include "FWCore/ParameterSet/interface/ParameterSet.h"
0016 #include "FWCore/ParameterSet/interface/ParameterSetfwd.h"
0017 #include "RelationalAccess/ICursor.h"
0018 #include "RelationalAccess/IQuery.h"
0019 #include "RelationalAccess/ISchema.h"
0020 #include "RelationalAccess/ISessionProxy.h"
0021 
0022 class LHCInfoPerFillPopConSourceHandler;
0023 
0024 typedef popcon::PopConAnalyzer<LHCInfoPerFillPopConSourceHandler> LHCInfoPerFillPopConAnalyzer;
0025 //define this as a plug-in
0026 DEFINE_FWK_MODULE(LHCInfoPerFillPopConAnalyzer);
0027 
0028 namespace cond {
0029   namespace theLHCInfoPerFillPopConImpl {
0030 
0031     static const std::pair<const char*, LHCInfoPerFill::FillType> s_fillTypeMap[] = {
0032         std::make_pair("PROTONS", LHCInfoPerFill::PROTONS),
0033         std::make_pair("IONS", LHCInfoPerFill::IONS),
0034         std::make_pair("COSMICS", LHCInfoPerFill::COSMICS),
0035         std::make_pair("GAP", LHCInfoPerFill::GAP)};
0036 
0037     static const std::pair<const char*, LHCInfoPerFill::ParticleType> s_particleTypeMap[] = {
0038         std::make_pair("PROTON", LHCInfoPerFill::PROTON),
0039         std::make_pair("PB82", LHCInfoPerFill::PB82),
0040         std::make_pair("AR18", LHCInfoPerFill::AR18),
0041         std::make_pair("D", LHCInfoPerFill::D),
0042         std::make_pair("XE54", LHCInfoPerFill::XE54)};
0043 
0044     LHCInfoPerFill::FillType fillTypeFromString(const std::string& s_fill_type) {
0045       for (auto const& i : s_fillTypeMap)
0046         if (s_fill_type == i.first)
0047           return i.second;
0048       return LHCInfoPerFill::UNKNOWN;
0049     }
0050 
0051     LHCInfoPerFill::ParticleType particleTypeFromString(const std::string& s_particle_type) {
0052       for (auto const& i : s_particleTypeMap)
0053         if (s_particle_type == i.first)
0054           return i.second;
0055       return LHCInfoPerFill::NONE;
0056     }
0057   }  // namespace theLHCInfoPerFillPopConImpl
0058 
0059   namespace impl {
0060 
0061     template <>
0062     LHCInfoPerFill::FillType from_string(const std::string& attributeValue) {
0063       return from_string_impl<LHCInfoPerFill::FillType, &theLHCInfoPerFillPopConImpl::fillTypeFromString>(
0064           attributeValue, LHCInfoPerFill::UNKNOWN);
0065     }
0066 
0067     template <>
0068     LHCInfoPerFill::ParticleType from_string(const std::string& attributeValue) {
0069       return from_string_impl<LHCInfoPerFill::ParticleType, &theLHCInfoPerFillPopConImpl::particleTypeFromString>(
0070           attributeValue, LHCInfoPerFill::NONE);
0071     }
0072 
0073   }  // namespace impl
0074 }  // namespace cond
0075 
0076 namespace theLHCInfoPerFillImpl {
0077 
0078   bool makeFillPayload(std::unique_ptr<LHCInfoPerFill>& targetPayload, const cond::OMSServiceResult& queryResult) {
0079     bool ret = false;
0080     if (!queryResult.empty()) {
0081       auto row = *queryResult.begin();
0082       auto currentFill = row.get<unsigned short>("fill_number");
0083       auto bunches1 = row.get<unsigned short>("bunches_beam1");
0084       auto bunches2 = row.get<unsigned short>("bunches_beam2");
0085       auto collidingBunches = row.get<unsigned short>("bunches_colliding");
0086       auto targetBunches = row.get<unsigned short>("bunches_target");
0087       auto fillType = row.get<LHCInfoPerFill::FillType>("fill_type_runtime");
0088       auto particleType1 = row.get<LHCInfoPerFill::ParticleType>("fill_type_party1");
0089       auto particleType2 = row.get<LHCInfoPerFill::ParticleType>("fill_type_party2");
0090       auto intensityBeam1 = row.get<float>("intensity_beam1");
0091       auto intensityBeam2 = row.get<float>("intensity_beam2");
0092       auto energy = row.get<float>("energy");
0093       auto creationTime = row.get<boost::posix_time::ptime>("start_time");
0094       auto stableBeamStartTime = row.get<boost::posix_time::ptime>("start_stable_beam");
0095       std::string endTimeStr = row.get<std::string>("end_time");
0096       auto beamDumpTime =
0097           (endTimeStr == "null") ? 0 : cond::time::from_boost(row.get<boost::posix_time::ptime>("end_time"));
0098       auto injectionScheme = row.get<std::string>("injection_scheme");
0099       targetPayload = std::make_unique<LHCInfoPerFill>();
0100       targetPayload->setFillNumber(currentFill);
0101       targetPayload->setBunchesInBeam1(bunches1);
0102       targetPayload->setBunchesInBeam2(bunches2);
0103       targetPayload->setCollidingBunches(collidingBunches);
0104       targetPayload->setTargetBunches(targetBunches);
0105       targetPayload->setFillType(fillType);
0106       targetPayload->setParticleTypeForBeam1(particleType1);
0107       targetPayload->setParticleTypeForBeam2(particleType2);
0108       targetPayload->setIntensityForBeam1(intensityBeam1);
0109       targetPayload->setIntensityForBeam2(intensityBeam2);
0110       targetPayload->setEnergy(energy);
0111       targetPayload->setCreationTime(cond::time::from_boost(creationTime));
0112       targetPayload->setBeginTime(cond::time::from_boost(stableBeamStartTime));
0113       targetPayload->setEndTime(beamDumpTime);
0114       targetPayload->setInjectionScheme(injectionScheme);
0115       ret = true;
0116     }
0117     return ret;
0118   }
0119 }  // namespace theLHCInfoPerFillImpl
0120 
0121 namespace theLHCInfoPerFillImpl {
0122   static const std::map<std::string, int> vecMap = {
0123       {"Beam1/beamPhaseMean", 1}, {"Beam2/beamPhaseMean", 2}, {"Beam1/cavPhaseMean", 3}, {"Beam2/cavPhaseMean", 4}};
0124   void setElementData(cond::Time_t since,
0125                       const std::string& dipVal,
0126                       unsigned int elementNr,
0127                       float value,
0128                       LHCInfoPerFill& payload,
0129                       std::set<cond::Time_t>& initList) {
0130     if (initList.find(since) == initList.end()) {
0131       payload.beam1VC().resize(LHCInfoPerFill::bunchSlots, 0.);
0132       payload.beam2VC().resize(LHCInfoPerFill::bunchSlots, 0.);
0133       payload.beam1RF().resize(LHCInfoPerFill::bunchSlots, 0.);
0134       payload.beam2RF().resize(LHCInfoPerFill::bunchSlots, 0.);
0135       initList.insert(since);
0136     }
0137     // set the current values to all of the payloads of the lumi section samples after the current since
0138     if (elementNr < LHCInfoPerFill::bunchSlots) {
0139       switch (vecMap.at(dipVal)) {
0140         case 1:
0141           payload.beam1VC()[elementNr] = value;
0142           break;
0143         case 2:
0144           payload.beam2VC()[elementNr] = value;
0145           break;
0146         case 3:
0147           payload.beam1RF()[elementNr] = value;
0148           break;
0149         case 4:
0150           payload.beam2RF()[elementNr] = value;
0151           break;
0152         default:
0153           break;
0154       }
0155     }
0156   }
0157 }  // namespace theLHCInfoPerFillImpl
0158 
0159 namespace theLHCInfoPerFillImpl {
0160   bool comparePayloads(const LHCInfoPerFill& rhs, const LHCInfoPerFill& lhs) {
0161     if (rhs.fillNumber() != lhs.fillNumber() || rhs.delivLumi() != lhs.delivLumi() || rhs.recLumi() != lhs.recLumi() ||
0162         rhs.instLumi() != lhs.instLumi() || rhs.instLumiError() != lhs.instLumiError() ||
0163         rhs.lhcState() != lhs.lhcState() || rhs.lhcComment() != lhs.lhcComment() ||
0164         rhs.ctppsStatus() != lhs.ctppsStatus()) {
0165       return false;
0166     }
0167     return true;
0168   }
0169 
0170   size_t transferPayloads(const std::vector<std::pair<cond::Time_t, std::shared_ptr<LHCInfoPerFill>>>& buffer,
0171                           std::map<cond::Time_t, std::shared_ptr<LHCInfoPerFill>>& iovsToTransfer,
0172                           std::shared_ptr<LHCInfoPerFill>& prevPayload) {
0173     size_t niovs = 0;
0174     std::stringstream condIovs;
0175     std::stringstream formattedIovs;
0176     for (auto& iov : buffer) {
0177       bool add = false;
0178       auto payload = iov.second;
0179       cond::Time_t since = iov.first;
0180       if (iovsToTransfer.empty()) {
0181         add = true;
0182       } else {
0183         LHCInfoPerFill& lastAdded = *iovsToTransfer.rbegin()->second;
0184         if (!comparePayloads(lastAdded, *payload)) {
0185           add = true;
0186         }
0187       }
0188       if (add) {
0189         niovs++;
0190         condIovs << since << " ";
0191         formattedIovs << boost::posix_time::to_iso_extended_string(cond::time::to_boost(since)) << " ";
0192         iovsToTransfer.insert(std::make_pair(since, payload));
0193         prevPayload = iov.second;
0194       }
0195     }
0196     edm::LogInfo("transferPayloads") << "TRANSFERED IOVS: " << condIovs.str();
0197     edm::LogInfo("transferPayloads") << "FORMATTED TRANSFERED IOVS: " << formattedIovs.str();
0198     return niovs;
0199   }
0200 
0201 }  // namespace theLHCInfoPerFillImpl
0202 class LHCInfoPerFillPopConSourceHandler : public popcon::PopConSourceHandler<LHCInfoPerFill> {
0203 public:
0204   LHCInfoPerFillPopConSourceHandler(edm::ParameterSet const& pset)
0205       : m_debug(pset.getUntrackedParameter<bool>("debug", false)),
0206         m_startTime(),
0207         m_endTime(),
0208         m_endFillMode(pset.getUntrackedParameter<bool>("endFill", true)),
0209         m_name(pset.getUntrackedParameter<std::string>("name", "LHCInfoPerFillPopConSourceHandler")),
0210         m_connectionString(pset.getUntrackedParameter<std::string>("connectionString", "")),
0211         m_ecalConnectionString(pset.getUntrackedParameter<std::string>("ecalConnectionString", "")),
0212         m_authpath(pset.getUntrackedParameter<std::string>("authenticationPath", "")),
0213         m_omsBaseUrl(pset.getUntrackedParameter<std::string>("omsBaseUrl", "")),
0214         m_fillPayload(),
0215         m_prevPayload(),
0216         m_tmpBuffer() {
0217     if (!pset.getUntrackedParameter<std::string>("startTime").empty()) {
0218       m_startTime = boost::posix_time::time_from_string(pset.getUntrackedParameter<std::string>("startTime"));
0219     }
0220     boost::posix_time::ptime now = boost::posix_time::second_clock::local_time();
0221     m_endTime = now;
0222     if (!pset.getUntrackedParameter<std::string>("endTime").empty()) {
0223       m_endTime = boost::posix_time::time_from_string(pset.getUntrackedParameter<std::string>("endTime"));
0224       if (m_endTime > now)
0225         m_endTime = now;
0226     }
0227   }
0228 
0229   ~LHCInfoPerFillPopConSourceHandler() override = default;
0230 
0231   void getNewObjects() override {
0232     //if a new tag is created, transfer fake fill from 1 to the first fill for the first time
0233     if (tagInfo().size == 0) {
0234       edm::LogInfo(m_name) << "New tag " << tagInfo().name << "; from " << m_name << "::getNewObjects";
0235     } else {
0236       //check what is already inside the database
0237       edm::LogInfo(m_name) << "got info for tag " << tagInfo().name << ": size " << tagInfo().size
0238                            << ", last object valid since " << tagInfo().lastInterval.since << " ( "
0239                            << boost::posix_time::to_iso_extended_string(
0240                                   cond::time::to_boost(tagInfo().lastInterval.since))
0241                            << " ); from " << m_name << "::getNewObjects";
0242     }
0243 
0244     cond::Time_t lastSince = tagInfo().lastInterval.since;
0245     if (tagInfo().isEmpty()) {
0246       // for a new or empty tag, an empty payload should be added on top with since=1
0247       if (m_endFillMode) {
0248         addEmptyPayload(1);
0249         lastSince = 1;
0250       } else {
0251         addEmptyPayload(cond::time::lumiTime(1, 1));
0252         lastSince = cond::time::lumiTime(1, 1);
0253       }
0254     } else {
0255       edm::LogInfo(m_name) << "The last Iov in tag " << tagInfo().name << " valid since " << lastSince << "from "
0256                            << m_name << "::getNewObjects";
0257     }
0258 
0259     //retrieve the data from the relational database source
0260     cond::persistency::ConnectionPool connection;
0261     //configure the connection
0262     if (m_debug) {
0263       connection.setMessageVerbosity(coral::Debug);
0264     } else {
0265       connection.setMessageVerbosity(coral::Error);
0266     }
0267     connection.setAuthenticationPath(m_authpath);
0268     connection.configure();
0269     //create the sessions
0270     cond::persistency::Session session = connection.createSession(m_connectionString, false);
0271     cond::persistency::Session session2 = connection.createSession(m_ecalConnectionString, false);
0272     // fetch last payload when available
0273     if (!tagInfo().lastInterval.payloadId.empty()) {
0274       cond::persistency::Session session3 = dbSession();
0275       session3.transaction().start(true);
0276       m_prevPayload = session3.fetchPayload<LHCInfoPerFill>(tagInfo().lastInterval.payloadId);
0277       session3.transaction().commit();
0278     }
0279 
0280     boost::posix_time::ptime executionTime = boost::posix_time::second_clock::local_time();
0281     cond::Time_t executionTimeIov = cond::time::from_boost(executionTime);
0282 
0283     cond::Time_t startTimestamp = m_startTime.is_not_a_date_time() ? 0 : cond::time::from_boost(m_startTime);
0284     cond::Time_t nextFillSearchTimestamp =
0285         std::max(startTimestamp, m_endFillMode ? lastSince : m_prevPayload->createTime());
0286 
0287     edm::LogInfo(m_name) << "Starting sampling at "
0288                          << boost::posix_time::to_simple_string(cond::time::to_boost(nextFillSearchTimestamp));
0289 
0290     while (true) {
0291       if (nextFillSearchTimestamp >= executionTimeIov) {
0292         edm::LogInfo(m_name) << "Sampling ended at the time "
0293                              << boost::posix_time::to_simple_string(cond::time::to_boost(executionTimeIov));
0294         break;
0295       }
0296       boost::posix_time::ptime nextFillSearchTime = cond::time::to_boost(nextFillSearchTimestamp);
0297       boost::posix_time::ptime startSampleTime;
0298       boost::posix_time::ptime endSampleTime;
0299 
0300       cond::OMSService oms;
0301       oms.connect(m_omsBaseUrl);
0302       auto query = oms.query("fills");
0303 
0304       edm::LogInfo(m_name) << "Searching new fill after " << boost::posix_time::to_simple_string(nextFillSearchTime);
0305       query->filterNotNull("start_stable_beam").filterNotNull("fill_number");
0306       if (nextFillSearchTime > cond::time::to_boost(m_prevPayload->createTime())) {
0307         query->filterGE("start_time", nextFillSearchTime);
0308       } else {
0309         query->filterGT("start_time", nextFillSearchTime);
0310       }
0311 
0312       query->filterLT("start_time", m_endTime);
0313       if (m_endFillMode)
0314         query->filterNotNull("end_time");
0315       bool foundFill = query->execute();
0316       if (foundFill)
0317         foundFill = theLHCInfoPerFillImpl::makeFillPayload(m_fillPayload, query->result());
0318       if (!foundFill) {
0319         edm::LogInfo(m_name) << "No fill found - END of job.";
0320         break;
0321       }
0322 
0323       startSampleTime = cond::time::to_boost(m_fillPayload->createTime());
0324       cond::Time_t startFillTime = m_fillPayload->createTime();
0325       cond::Time_t endFillTime = m_fillPayload->endTime();
0326       unsigned short lhcFill = m_fillPayload->fillNumber();
0327       bool ongoingFill = endFillTime == 0ULL;
0328       if (ongoingFill) {
0329         edm::LogInfo(m_name) << "Found ongoing fill " << lhcFill << " created at "
0330                              << cond::time::to_boost(startFillTime);
0331         endSampleTime = executionTime;
0332         nextFillSearchTimestamp = executionTimeIov;
0333       } else {
0334         edm::LogInfo(m_name) << "Found fill " << lhcFill << " created at " << cond::time::to_boost(startFillTime)
0335                              << " ending at " << cond::time::to_boost(endFillTime);
0336         endSampleTime = cond::time::to_boost(endFillTime);
0337         nextFillSearchTimestamp = endFillTime;
0338       }
0339       if (m_endFillMode || ongoingFill) {
0340         getDipData(oms, startSampleTime, endSampleTime);
0341         getLumiData(oms, lhcFill, startSampleTime, endSampleTime);
0342         if (!m_tmpBuffer.empty()) {
0343           boost::posix_time::ptime flumiStart = cond::time::to_boost(m_tmpBuffer.front().first);
0344           boost::posix_time::ptime flumiStop = cond::time::to_boost(m_tmpBuffer.back().first);
0345           edm::LogInfo(m_name) << "First lumi starts at " << flumiStart << " last lumi starts at " << flumiStop;
0346           session.transaction().start(true);
0347           getCTPPSData(session, startSampleTime, endSampleTime);
0348           session.transaction().commit();
0349           session2.transaction().start(true);
0350           getEcalData(session2, startSampleTime, endSampleTime);
0351           session2.transaction().commit();
0352         }
0353       }
0354 
0355       // In duringFill mode, convert the timestamp-type IOVs to lumiid-type IOVs
0356       // before transferring the payloads from the buffer to the final collection
0357       if (!m_endFillMode) {
0358         convertBufferedIovsToLumiid(m_timestampToLumiid);
0359       }
0360 
0361       size_t niovs = theLHCInfoPerFillImpl::transferPayloads(m_tmpBuffer, m_iovs, m_prevPayload);
0362       edm::LogInfo(m_name) << "Added " << niovs << " iovs within the Fill time";
0363       m_tmpBuffer.clear();
0364       m_timestampToLumiid.clear();
0365       if (m_prevPayload->fillNumber() and !ongoingFill) {
0366         if (m_endFillMode) {
0367           addEmptyPayload(endFillTime);
0368         } else {
0369           addEmptyPayload(cond::lhcInfoHelper::getFillLastLumiIOV(oms, lhcFill));
0370         }
0371       }
0372     }
0373   }
0374 
0375   std::string id() const override { return m_name; }
0376 
0377   static constexpr unsigned int kLumisectionsQueryLimit = 4000;
0378 
0379 private:
0380   void addEmptyPayload(cond::Time_t iov) {
0381     bool add = false;
0382     if (m_iovs.empty()) {
0383       if (!m_lastPayloadEmpty)
0384         add = true;
0385     } else {
0386       auto lastAdded = m_iovs.rbegin()->second;
0387       if (lastAdded->fillNumber() != 0) {
0388         add = true;
0389       }
0390     }
0391     if (add) {
0392       auto newPayload = std::make_shared<LHCInfoPerFill>();
0393       m_iovs.insert(std::make_pair(iov, newPayload));
0394       m_prevPayload = newPayload;
0395       edm::LogInfo(m_name) << "Added empty payload with IOV " << iov << " ( "
0396                            << boost::posix_time::to_iso_extended_string(cond::time::to_boost(iov)) << " )";
0397     }
0398   }
0399 
0400   // Add payload to buffer and store corresponding lumiid IOV in m_timestampToLumiid map
0401   void addPayloadToBuffer(cond::OMSServiceResultRef& row) {
0402     auto startTime = row.get<boost::posix_time::ptime>("start_time");
0403     auto delivLumi = row.get<float>("delivered_lumi");
0404     auto recLumi = row.get<float>("recorded_lumi");
0405     auto runNumber = std::stoul(row.get<std::string>("run_number"));
0406     auto lsNumber = std::stoul(row.get<std::string>("lumisection_number"));
0407     auto lumiid = cond::time::lumiTime(runNumber, lsNumber);
0408 
0409     LHCInfoPerFill* thisLumiSectionInfo = m_fillPayload->cloneFill();
0410     m_tmpBuffer.emplace_back(std::make_pair(cond::time::from_boost(startTime), thisLumiSectionInfo));
0411     if (!m_endFillMode) {
0412       m_timestampToLumiid.insert(std::make_pair(cond::time::from_boost(startTime), lumiid));
0413     }
0414     LHCInfoPerFill& payload = *thisLumiSectionInfo;
0415     payload.setDelivLumi(delivLumi);
0416     payload.setRecLumi(recLumi);
0417   }
0418 
0419   void convertBufferedIovsToLumiid(std::map<cond::Time_t, cond::Time_t> timestampToLumiid) {
0420     for (auto& item : m_tmpBuffer) {
0421       // Check if the lumiid IOV corresponding to the timestamp is present in the map
0422       if (timestampToLumiid.find(item.first) == timestampToLumiid.end()) {
0423         throw cms::Exception("LHCInfoPerFillPopConSourceHandler")
0424             << "Can't find corresponding lumiid IOV for timestamp " << item.first << "\n";
0425       }
0426       // Update the buffer with the lumiid-type IOV
0427       item.first = timestampToLumiid.at(item.first);
0428     }
0429   }
0430 
0431   size_t getLumiData(const cond::OMSService& oms,
0432                      unsigned short fillId,
0433                      const boost::posix_time::ptime& beginFillTime,
0434                      const boost::posix_time::ptime& endFillTime) {
0435     auto query = oms.query("lumisections");
0436     query->addOutputVars(
0437         {"start_time", "delivered_lumi", "recorded_lumi", "beams_stable", "run_number", "lumisection_number"});
0438     query->filterEQ("fill_number", fillId);
0439     query->filterGT("start_time", beginFillTime).filterLT("start_time", endFillTime);
0440     query->filterEQ("beams_stable", "true");
0441     query->limit(kLumisectionsQueryLimit);
0442     if (query->execute()) {
0443       auto queryResult = query->result();
0444       edm::LogInfo(m_name) << "Found " << queryResult.size() << " lumisections with STABLE BEAM during the fill "
0445                            << fillId;
0446 
0447       if (!queryResult.empty()) {
0448         if (m_endFillMode) {
0449           auto firstRow = queryResult.front();
0450           addPayloadToBuffer(firstRow);
0451         }
0452 
0453         auto lastRow = queryResult.back();
0454         addPayloadToBuffer(lastRow);
0455       }
0456     }
0457     return 0;
0458   }
0459 
0460   void getDipData(const cond::OMSService& oms,
0461                   const boost::posix_time::ptime& beginFillTime,
0462                   const boost::posix_time::ptime& endFillTime) {
0463     // unsure how to handle this.
0464     // the old implementation is not helping: apparently it is checking only the bunchconfiguration for the first diptime set of values...
0465     auto query1 = oms.query("diplogger/dip/acc/LHC/RunControl/CirculatingBunchConfig/Beam1");
0466     query1->filterGT("dip_time", beginFillTime).filterLT("dip_time", endFillTime);
0467     //This query is limited to 100 rows, but currently only one is used
0468     //If all this data is needed and saved properly the limit has to be set: query1->limit(...)
0469     if (query1->execute()) {
0470       auto res = query1->result();
0471       if (!res.empty()) {
0472         std::bitset<LHCInfoPerFill::bunchSlots + 1> bunchConfiguration1(0ULL);
0473         auto row = *res.begin();
0474         auto vbunchConf1 = row.getArray<unsigned short>("value");
0475         for (auto vb : vbunchConf1) {
0476           if (vb != 0) {
0477             unsigned short slot = (vb - 1) / 10 + 1;
0478             bunchConfiguration1[slot] = true;
0479           }
0480         }
0481         m_fillPayload->setBunchBitsetForBeam1(bunchConfiguration1);
0482       }
0483     }
0484     auto query2 = oms.query("diplogger/dip/acc/LHC/RunControl/CirculatingBunchConfig/Beam2");
0485     query2->filterGT("dip_time", beginFillTime).filterLT("dip_time", endFillTime);
0486     //This query is limited to 100 rows, but currently only one is used
0487     if (query2->execute()) {
0488       auto res = query2->result();
0489       if (!res.empty()) {
0490         std::bitset<LHCInfoPerFill::bunchSlots + 1> bunchConfiguration2(0ULL);
0491         auto row = *res.begin();
0492         auto vbunchConf2 = row.getArray<unsigned short>("value");
0493         for (auto vb : vbunchConf2) {
0494           if (vb != 0) {
0495             unsigned short slot = (vb - 1) / 10 + 1;
0496             bunchConfiguration2[slot] = true;
0497           }
0498         }
0499         m_fillPayload->setBunchBitsetForBeam2(bunchConfiguration2);
0500       }
0501     }
0502 
0503     auto query3 = oms.query("diplogger/dip/CMS/LHC/LumiPerBunch");
0504     query3->filterGT("dip_time", beginFillTime).filterLT("dip_time", endFillTime);
0505     //This query is limited to 100 rows, but currently only one is used
0506     if (query3->execute()) {
0507       auto res = query3->result();
0508       if (!res.empty()) {
0509         std::vector<float> lumiPerBX;
0510         auto row = *res.begin();
0511         auto lumiBunchInst = row.getArray<float>("lumi_bunch_inst");
0512         for (auto lb : lumiBunchInst) {
0513           if (lb != 0.) {
0514             lumiPerBX.push_back(lb);
0515           }
0516         }
0517         m_fillPayload->setLumiPerBX(lumiPerBX);
0518       }
0519     }
0520   }
0521 
0522   bool getCTPPSData(cond::persistency::Session& session,
0523                     const boost::posix_time::ptime& beginFillTime,
0524                     const boost::posix_time::ptime& endFillTime) {
0525     //run the fifth query against the CTPPS schema
0526     //Initializing the CMS_CTP_CTPPS_COND schema.
0527     coral::ISchema& CTPPS = session.coralSession().schema("CMS_PPS_SPECT_COND");
0528     //execute query for CTPPS Data
0529     std::unique_ptr<coral::IQuery> CTPPSDataQuery(CTPPS.newQuery());
0530     //FROM clause
0531     CTPPSDataQuery->addToTableList(std::string("PPS_LHC_MACHINE_PARAMS"));
0532     //SELECT clause
0533     CTPPSDataQuery->addToOutputList(std::string("DIP_UPDATE_TIME"));
0534     CTPPSDataQuery->addToOutputList(std::string("LHC_STATE"));
0535     CTPPSDataQuery->addToOutputList(std::string("LHC_COMMENT"));
0536     if (m_debug) {
0537       CTPPSDataQuery->addToOutputList(std::string("RUN_NUMBER"));
0538       CTPPSDataQuery->addToOutputList(std::string("LUMI_SECTION"));
0539     }
0540     //WHERE CLAUSE
0541     coral::AttributeList CTPPSDataBindVariables;
0542     CTPPSDataBindVariables.extend<coral::TimeStamp>(std::string("beginFillTime"));
0543     CTPPSDataBindVariables.extend<coral::TimeStamp>(std::string("endFillTime"));
0544     CTPPSDataBindVariables[std::string("beginFillTime")].data<coral::TimeStamp>() = coral::TimeStamp(beginFillTime);
0545     CTPPSDataBindVariables[std::string("endFillTime")].data<coral::TimeStamp>() = coral::TimeStamp(endFillTime);
0546     std::string conditionStr = std::string("DIP_UPDATE_TIME>= :beginFillTime and DIP_UPDATE_TIME< :endFillTime");
0547     CTPPSDataQuery->setCondition(conditionStr, CTPPSDataBindVariables);
0548     //ORDER BY clause
0549     CTPPSDataQuery->addToOrderList(std::string("DIP_UPDATE_TIME"));
0550     //define query output
0551     coral::AttributeList CTPPSDataOutput;
0552     CTPPSDataOutput.extend<coral::TimeStamp>(std::string("DIP_UPDATE_TIME"));
0553     CTPPSDataOutput.extend<std::string>(std::string("LHC_STATE"));
0554     CTPPSDataOutput.extend<std::string>(std::string("LHC_COMMENT"));
0555     if (m_debug) {
0556       CTPPSDataOutput.extend<int>(std::string("RUN_NUMBER"));
0557       CTPPSDataOutput.extend<int>(std::string("LUMI_SECTION"));
0558     }
0559     CTPPSDataQuery->defineOutput(CTPPSDataOutput);
0560     //execute the query
0561     coral::ICursor& CTPPSDataCursor = CTPPSDataQuery->execute();
0562     cond::Time_t dipTime = 0;
0563     std::string lhcState = "", lhcComment = "", ctppsStatus = "";
0564 
0565     //debug informations
0566     unsigned int lumiSection = 0;
0567     cond::Time_t runNumber = 0;
0568     cond::Time_t savedDipTime = 0;
0569     unsigned int savedLumiSection = 0;
0570     cond::Time_t savedRunNumber = 0;
0571 
0572     bool ret = false;
0573     LumiSectionFilter<LHCInfoPerFill> filter(m_tmpBuffer);
0574     while (CTPPSDataCursor.next()) {
0575       if (m_debug) {
0576         std::ostringstream CTPPS;
0577         CTPPSDataCursor.currentRow().toOutputStream(CTPPS);
0578       }
0579       coral::Attribute const& dipTimeAttribute = CTPPSDataCursor.currentRow()[std::string("DIP_UPDATE_TIME")];
0580       if (!dipTimeAttribute.isNull()) {
0581         dipTime = cond::time::from_boost(dipTimeAttribute.data<coral::TimeStamp>().time());
0582         if (filter.process(dipTime)) {
0583           ret = true;
0584           coral::Attribute const& lhcStateAttribute = CTPPSDataCursor.currentRow()[std::string("LHC_STATE")];
0585           if (!lhcStateAttribute.isNull()) {
0586             lhcState = lhcStateAttribute.data<std::string>();
0587           }
0588           coral::Attribute const& lhcCommentAttribute = CTPPSDataCursor.currentRow()[std::string("LHC_COMMENT")];
0589           if (!lhcCommentAttribute.isNull()) {
0590             lhcComment = lhcCommentAttribute.data<std::string>();
0591           }
0592 
0593           if (m_debug) {
0594             coral::Attribute const& runNumberAttribute = CTPPSDataCursor.currentRow()[std::string("RUN_NUMBER")];
0595             if (!runNumberAttribute.isNull()) {
0596               runNumber = runNumberAttribute.data<int>();
0597             }
0598             coral::Attribute const& lumiSectionAttribute = CTPPSDataCursor.currentRow()[std::string("LUMI_SECTION")];
0599             if (!lumiSectionAttribute.isNull()) {
0600               lumiSection = lumiSectionAttribute.data<int>();
0601             }
0602           }
0603 
0604           for (auto it = filter.current(); it != m_tmpBuffer.end(); it++) {
0605             // set the current values to all of the payloads of the lumi section samples after the current since
0606             LHCInfoPerFill& payload = *(it->second);
0607             payload.setLhcState(lhcState);
0608             payload.setLhcComment(lhcComment);
0609             payload.setCtppsStatus(ctppsStatus);
0610 
0611             if (m_debug) {
0612               savedDipTime = dipTime;
0613               savedLumiSection = lumiSection;
0614               savedRunNumber = runNumber;
0615             }
0616           }
0617         }
0618       }
0619     }
0620     if (m_debug) {
0621       edm::LogInfo(m_name) << "Last assigned: "
0622                            << "DipTime: " << savedDipTime << " "
0623                            << "LumiSection: " << savedLumiSection << " "
0624                            << "RunNumber: " << savedRunNumber;
0625     }
0626     return ret;
0627   }
0628 
0629   bool getEcalData(cond::persistency::Session& session,
0630                    const boost::posix_time::ptime& lowerTime,
0631                    const boost::posix_time::ptime& upperTime) {
0632     //run the sixth query against the CMS_DCS_ENV_PVSS_COND schema
0633     //Initializing the CMS_DCS_ENV_PVSS_COND schema.
0634     coral::ISchema& ECAL = session.nominalSchema();
0635     //start the transaction against the fill logging schema
0636     //execute query for ECAL Data
0637     std::unique_ptr<coral::IQuery> ECALDataQuery(ECAL.newQuery());
0638     //FROM clause
0639     ECALDataQuery->addToTableList(std::string("BEAM_PHASE"));
0640     //SELECT clause
0641     ECALDataQuery->addToOutputList(std::string("CHANGE_DATE"));
0642     ECALDataQuery->addToOutputList(std::string("DIP_value"));
0643     ECALDataQuery->addToOutputList(std::string("element_nr"));
0644     ECALDataQuery->addToOutputList(std::string("VALUE_NUMBER"));
0645     //WHERE CLAUSE
0646     coral::AttributeList ECALDataBindVariables;
0647     ECALDataBindVariables.extend<coral::TimeStamp>(std::string("lowerTime"));
0648     ECALDataBindVariables.extend<coral::TimeStamp>(std::string("upperTime"));
0649     ECALDataBindVariables[std::string("lowerTime")].data<coral::TimeStamp>() = coral::TimeStamp(lowerTime);
0650     ECALDataBindVariables[std::string("upperTime")].data<coral::TimeStamp>() = coral::TimeStamp(upperTime);
0651     std::string conditionStr = std::string(
0652         "(DIP_value LIKE '%beamPhaseMean%' OR DIP_value LIKE '%cavPhaseMean%') AND CHANGE_DATE >= :lowerTime AND "
0653         "CHANGE_DATE < :upperTime");
0654 
0655     ECALDataQuery->setCondition(conditionStr, ECALDataBindVariables);
0656     //ORDER BY clause
0657     ECALDataQuery->addToOrderList(std::string("CHANGE_DATE"));
0658     ECALDataQuery->addToOrderList(std::string("DIP_value"));
0659     ECALDataQuery->addToOrderList(std::string("element_nr"));
0660     //define query output
0661     coral::AttributeList ECALDataOutput;
0662     ECALDataOutput.extend<coral::TimeStamp>(std::string("CHANGE_DATE"));
0663     ECALDataOutput.extend<std::string>(std::string("DIP_value"));
0664     ECALDataOutput.extend<unsigned int>(std::string("element_nr"));
0665     ECALDataOutput.extend<float>(std::string("VALUE_NUMBER"));
0666     //ECALDataQuery->limitReturnedRows( 14256 ); //3564 entries per vector.
0667     ECALDataQuery->defineOutput(ECALDataOutput);
0668     //execute the query
0669     coral::ICursor& ECALDataCursor = ECALDataQuery->execute();
0670     cond::Time_t changeTime = 0;
0671     cond::Time_t firstTime = 0;
0672     std::string dipVal = "";
0673     unsigned int elementNr = 0;
0674     float value = 0.;
0675     std::set<cond::Time_t> initializedVectors;
0676     LumiSectionFilter<LHCInfoPerFill> filter(m_tmpBuffer);
0677     bool ret = false;
0678     if (m_prevPayload.get()) {
0679       for (auto& lumiSlot : m_tmpBuffer) {
0680         lumiSlot.second->setBeam1VC(m_prevPayload->beam1VC());
0681         lumiSlot.second->setBeam2VC(m_prevPayload->beam2VC());
0682         lumiSlot.second->setBeam1RF(m_prevPayload->beam1RF());
0683         lumiSlot.second->setBeam2RF(m_prevPayload->beam2RF());
0684       }
0685     }
0686     std::map<cond::Time_t, cond::Time_t> iovMap;
0687     if (m_tmpBuffer.empty()) {
0688       return ret;
0689     }
0690     cond::Time_t lowerLumi = m_tmpBuffer.front().first;
0691     while (ECALDataCursor.next()) {
0692       if (m_debug) {
0693         std::ostringstream ECAL;
0694         ECALDataCursor.currentRow().toOutputStream(ECAL);
0695       }
0696       coral::Attribute const& changeDateAttribute = ECALDataCursor.currentRow()[std::string("CHANGE_DATE")];
0697       if (!changeDateAttribute.isNull()) {
0698         ret = true;
0699         boost::posix_time::ptime chTime = changeDateAttribute.data<coral::TimeStamp>().time();
0700         // move the first IOV found to the start of the fill interval selected
0701         if (changeTime == 0) {
0702           firstTime = cond::time::from_boost(chTime);
0703         }
0704         changeTime = cond::time::from_boost(chTime);
0705         cond::Time_t iovTime = changeTime;
0706         if (changeTime == firstTime)
0707           iovTime = lowerLumi;
0708         coral::Attribute const& dipValAttribute = ECALDataCursor.currentRow()[std::string("DIP_value")];
0709         coral::Attribute const& valueNumberAttribute = ECALDataCursor.currentRow()[std::string("VALUE_NUMBER")];
0710         coral::Attribute const& elementNrAttribute = ECALDataCursor.currentRow()[std::string("element_nr")];
0711         if (!dipValAttribute.isNull() and !valueNumberAttribute.isNull()) {
0712           dipVal = dipValAttribute.data<std::string>();
0713           elementNr = elementNrAttribute.data<unsigned int>();
0714           value = valueNumberAttribute.data<float>();
0715           if (std::isnan(value))
0716             value = 0.;
0717           if (filter.process(iovTime)) {
0718             iovMap.insert(std::make_pair(changeTime, filter.current()->first));
0719             for (auto it = filter.current(); it != m_tmpBuffer.end(); it++) {
0720               LHCInfoPerFill& payload = *(it->second);
0721               theLHCInfoPerFillImpl::setElementData(it->first, dipVal, elementNr, value, payload, initializedVectors);
0722             }
0723           }
0724         }
0725       }
0726     }
0727     if (m_debug) {
0728       for (auto& im : iovMap) {
0729         edm::LogInfo(m_name) << "Found iov=" << im.first << " (" << cond::time::to_boost(im.first) << " ) moved to "
0730                              << im.second << " ( " << cond::time::to_boost(im.second) << " )";
0731       }
0732     }
0733     return ret;
0734   }
0735 
0736 private:
0737   bool m_debug;
0738   // starting date for sampling
0739   boost::posix_time::ptime m_startTime;
0740   boost::posix_time::ptime m_endTime;
0741   bool m_endFillMode = true;
0742   std::string m_name;
0743   //for reading from relational database source
0744   std::string m_connectionString, m_ecalConnectionString;
0745   std::string m_authpath;
0746   std::string m_omsBaseUrl;
0747   std::unique_ptr<LHCInfoPerFill> m_fillPayload;
0748   std::shared_ptr<LHCInfoPerFill> m_prevPayload;
0749   std::vector<std::pair<cond::Time_t, std::shared_ptr<LHCInfoPerFill>>> m_tmpBuffer;
0750   bool m_lastPayloadEmpty = false;
0751   // to hold correspondance between timestamp-type IOVs and lumiid-type IOVs
0752   std::map<cond::Time_t, cond::Time_t> m_timestampToLumiid;
0753 };