Back to home page

Project CMSSW displayed by LXR

 
 

    


File indexing completed on 2024-11-07 06:12:39

0001 #include "CondTools/RunInfo/interface/LHCInfoPerLSPopConSourceHandler.h"
0002 #include "CondCore/CondDB/interface/ConnectionPool.h"
0003 #include "CondCore/CondDB/interface/Types.h"
0004 #include "CondFormats/Common/interface/TimeConversions.h"
0005 #include "CondTools/RunInfo/interface/LHCInfoHelper.h"
0006 #include "CondTools/RunInfo/interface/OMSAccess.h"
0007 #include "CoralBase/Attribute.h"
0008 #include "CoralBase/AttributeList.h"
0009 #include "CoralBase/AttributeSpecification.h"
0010 #include "CoralBase/TimeStamp.h"
0011 #include "FWCore/MessageLogger/interface/MessageLogger.h"
0012 #include "FWCore/ParameterSet/interface/ParameterSet.h"
0013 #include "RelationalAccess/ICursor.h"
0014 #include "RelationalAccess/IQuery.h"
0015 #include "RelationalAccess/ISchema.h"
0016 #include "RelationalAccess/ISessionProxy.h"
0017 #include <boost/date_time/posix_time/posix_time.hpp>
0018 #include <sstream>
0019 
0020 using std::make_pair;
0021 using std::pair;
0022 
0023 namespace theLHCInfoPerLSImpl {
0024   bool comparePayloads(const LHCInfoPerLS& rhs, const LHCInfoPerLS& lhs) {
0025     if (rhs.fillNumber() != lhs.fillNumber() || rhs.runNumber() != lhs.runNumber() ||
0026         rhs.crossingAngleX() != lhs.crossingAngleX() || rhs.crossingAngleY() != lhs.crossingAngleY() ||
0027         rhs.betaStarX() != lhs.betaStarX() || rhs.betaStarY() != lhs.betaStarY()) {
0028       return false;
0029     }
0030     return true;
0031   }
0032 
0033   size_t transferPayloads(const std::vector<pair<cond::Time_t, std::shared_ptr<LHCInfoPerLS>>>& buffer,
0034                           std::map<cond::Time_t, std::shared_ptr<LHCInfoPerLS>>& iovsToTransfer,
0035                           std::shared_ptr<LHCInfoPerLS>& prevPayload,
0036                           const std::map<pair<cond::Time_t, unsigned int>, pair<cond::Time_t, unsigned int>>& lsIdMap,
0037                           cond::Time_t startStableBeamTime,
0038                           cond::Time_t endStableBeamTime) {
0039     int lsMissingInPPS = 0;
0040     int xAngleBothZero = 0, xAngleBothNonZero = 0, xAngleNegative = 0;
0041     int betaNegative = 0;
0042     size_t niovs = 0;
0043     std::stringstream condIovs;
0044     std::stringstream missingLsList;
0045     for (auto& iov : buffer) {
0046       bool add = false;
0047       auto payload = iov.second;
0048       cond::Time_t since = iov.first;
0049       if (iovsToTransfer.empty()) {
0050         add = true;
0051       } else {
0052         LHCInfoPerLS& lastAdded = *iovsToTransfer.rbegin()->second;
0053         if (!comparePayloads(lastAdded, *payload)) {
0054           add = true;
0055         }
0056       }
0057       auto id = make_pair(payload->runNumber(), payload->lumiSection());
0058       bool stableBeam = since >= startStableBeamTime && since <= endStableBeamTime;
0059       bool isMissing = lsIdMap.find(id) != lsIdMap.end() && id != lsIdMap.at(id);
0060       if (stableBeam && isMissing) {
0061         missingLsList << id.first << "_" << id.second << " ";
0062         lsMissingInPPS += isMissing;
0063       }
0064       if (add && !isMissing) {
0065         niovs++;
0066         if (stableBeam) {
0067           if (payload->crossingAngleX() == 0 && payload->crossingAngleY() == 0)
0068             xAngleBothZero++;
0069           if (payload->crossingAngleX() != 0 && payload->crossingAngleY() != 0)
0070             xAngleBothNonZero++;
0071           if (payload->crossingAngleX() < 0 || payload->crossingAngleY() < 0)
0072             xAngleNegative++;
0073           if (payload->betaStarX() < 0 || payload->betaStarY() < 0)
0074             betaNegative++;
0075         }
0076 
0077         condIovs << since << " ";
0078         iovsToTransfer.insert(make_pair(since, payload));
0079         prevPayload = iov.second;
0080       }
0081     }
0082     unsigned short fillNumber = (!buffer.empty()) ? buffer.front().second->fillNumber() : 0;
0083     if (lsMissingInPPS > 0) {
0084       edm::LogWarning("transferPayloads")
0085           << "Number of stable beam LS in OMS without corresponding record in PPS DB for fill " << fillNumber << ": "
0086           << lsMissingInPPS;
0087       edm::LogWarning("transferPayloads")
0088           << "Stable beam LS in OMS without corresponding record in PPS DB (run_LS):  " << missingLsList.str();
0089     }
0090     if (xAngleBothZero > 0) {
0091       edm::LogWarning("transferPayloads")
0092           << "Number of payloads written with crossingAngle == 0 for both X and Y for fill " << fillNumber << ": "
0093           << xAngleBothZero;
0094     }
0095     if (xAngleBothNonZero > 0) {
0096       edm::LogWarning("transferPayloads")
0097           << "Number of payloads written with crossingAngle != 0 for both X and Y for fill " << fillNumber << ": "
0098           << xAngleBothNonZero;
0099     }
0100     if (xAngleNegative > 0) {
0101       edm::LogWarning("transferPayloads")
0102           << "Number of payloads written with negative crossingAngle for fill " << fillNumber << ": " << xAngleNegative;
0103     }
0104     if (betaNegative > 0) {
0105       edm::LogWarning("transferPayloads")
0106           << "Number of payloads written with negative betaSta for fill " << fillNumber << ": " << betaNegative;
0107     }
0108 
0109     edm::LogInfo("transferPayloads") << "TRANSFERED COND IOVS: " << condIovs.str();
0110     return niovs;
0111   }
0112 
0113 }  // namespace theLHCInfoPerLSImpl
0114 
0115 LHCInfoPerLSPopConSourceHandler::LHCInfoPerLSPopConSourceHandler(edm::ParameterSet const& pset)
0116     : m_debug(pset.getUntrackedParameter<bool>("debug", false)),
0117       m_startTime(),
0118       m_endTime(),
0119       m_endFillMode(pset.getUntrackedParameter<bool>("endFill", true)),
0120       m_name(pset.getUntrackedParameter<std::string>("name", "LHCInfoPerLSPopConSourceHandler")),
0121       m_connectionString(pset.getUntrackedParameter<std::string>("connectionString", "")),
0122       m_authpath(pset.getUntrackedParameter<std::string>("authenticationPath", "")),
0123       m_omsBaseUrl(pset.getUntrackedParameter<std::string>("omsBaseUrl", "")),
0124       m_debugLogic(pset.getUntrackedParameter<bool>("debugLogic", false)),
0125       m_defaultCrossingAngleX(pset.getUntrackedParameter<double>("defaultCrossingAngleX", 0)),
0126       m_defaultCrossingAngleY(pset.getUntrackedParameter<double>("defaultCrossingAngleY", 0)),
0127       m_defaultBetaStarX(pset.getUntrackedParameter<double>("defaultBetaStarX", 0)),
0128       m_defaultBetaStarY(pset.getUntrackedParameter<double>("defaultBetaStarY", 0)),
0129       m_minBetaStar(pset.getUntrackedParameter<double>("minBetaStar", 0.1)),
0130       m_maxBetaStar(pset.getUntrackedParameter<double>("maxBetaStar", 100.)),
0131       m_minCrossingAngle(pset.getUntrackedParameter<double>("minCrossingAngle", 10.)),
0132       m_maxCrossingAngle(pset.getUntrackedParameter<double>("maxCrossingAngle", 500.)),
0133       m_fillPayload(),
0134       m_prevPayload(),
0135       m_tmpBuffer() {
0136   if (!pset.getUntrackedParameter<std::string>("startTime").empty()) {
0137     m_startTime = boost::posix_time::time_from_string(pset.getUntrackedParameter<std::string>("startTime"));
0138   }
0139   boost::posix_time::ptime now = boost::posix_time::second_clock::local_time();
0140   m_endTime = now;
0141   if (!pset.getUntrackedParameter<std::string>("endTime").empty()) {
0142     m_endTime = boost::posix_time::time_from_string(pset.getUntrackedParameter<std::string>("endTime"));
0143     if (m_endTime > now)
0144       m_endTime = now;
0145   }
0146   if (m_debugLogic && m_endFillMode) {
0147     throw cms::Exception("invalid argument") << "debugLogic == true not supported for endFillMode == true";
0148   }
0149 }
0150 
0151 LHCInfoPerLSPopConSourceHandler::~LHCInfoPerLSPopConSourceHandler() = default;
0152 
0153 void LHCInfoPerLSPopConSourceHandler::getNewObjects() {
0154   populateIovs();
0155   if (!m_endFillMode) {  // duringFill mode
0156     filterInvalidPayloads();
0157   }
0158 }
0159 
0160 void LHCInfoPerLSPopConSourceHandler::filterInvalidPayloads() {
0161   // note: at the moment used only in duringFill mode so the m_iovs is quaranteed to have size() <= 1
0162   // but iterating through the whole map is implemented just in case the way it's used changes
0163   auto it = m_iovs.begin();
0164   while (it != m_iovs.end()) {
0165     std::stringstream payloadData;
0166     payloadData << "LS = " << it->second->lumiSection() << ", run = " << it->second->runNumber() << ", "
0167                 << "xAngleX = " << it->second->crossingAngleX() << " urad, "
0168                 << "xAngleY = " << it->second->crossingAngleY() << " urad, "
0169                 << "beta*X = " << it->second->betaStarX() << " m, "
0170                 << "beta*Y = " << it->second->betaStarY() << " m";
0171     if (!isPayloadValid(*(it->second))) {
0172       edm::LogWarning(m_name) << "Skipping upload of payload with invalid values: " << payloadData.str();
0173       m_iovs.erase(it++);  // note: post-increment necessary to avoid using invalidated iterators
0174     } else {
0175       edm::LogInfo(m_name) << "Payload to be uploaded: " << payloadData.str();
0176       ++it;
0177     }
0178   }
0179 }
0180 
0181 bool LHCInfoPerLSPopConSourceHandler::isPayloadValid(const LHCInfoPerLS& payload) const {
0182   if ((payload.crossingAngleX() == 0. && payload.crossingAngleY() == 0.) ||
0183       (payload.crossingAngleX() != 0. && payload.crossingAngleY() != 0.))
0184     return false;
0185   auto non0CrossingAngle = payload.crossingAngleX() != 0. ? payload.crossingAngleX() : payload.crossingAngleY();
0186   if ((non0CrossingAngle < m_minCrossingAngle || m_maxCrossingAngle < non0CrossingAngle) ||
0187       (payload.betaStarX() < m_minBetaStar || m_maxBetaStar < payload.betaStarX()) ||
0188       (payload.betaStarX() < m_minBetaStar || m_maxBetaStar < payload.betaStarX()))
0189     return false;
0190   return true;
0191 }
0192 
0193 void LHCInfoPerLSPopConSourceHandler::populateIovs() {
0194   //if a new tag is created, transfer fake fill from 1 to the first fill for the first time
0195   if (tagInfo().size == 0) {
0196     edm::LogInfo(m_name) << "New tag " << tagInfo().name << "; from " << m_name << "::getNewObjects";
0197   } else {
0198     //check what is already inside the database
0199     edm::LogInfo(m_name) << "got info for tag " << tagInfo().name << ": size " << tagInfo().size
0200                          << ", last object valid since " << tagInfo().lastInterval.since << " ( "
0201                          << boost::posix_time::to_iso_extended_string(
0202                                 cond::time::to_boost(tagInfo().lastInterval.since))
0203                          << " ); from " << m_name << "::getNewObjects";
0204   }
0205 
0206   cond::Time_t lastSince = tagInfo().lastInterval.since;
0207   if (tagInfo().isEmpty()) {
0208     // for a new or empty tag in endFill mode, an empty payload should be added on top with since=1
0209     if (m_endFillMode) {
0210       addEmptyPayload(1);
0211       lastSince = 1;
0212     } else {  //duringFill mode
0213       edm::LogInfo(m_name) << "Empty or new tag: uploading a default payload and ending the job";
0214       cond::OMSService oms;
0215       oms.connect(m_omsBaseUrl);
0216       addDefaultPayload(1, 1, 1, 1);
0217       return;
0218     }
0219   } else {
0220     edm::LogInfo(m_name) << "The last Iov in tag " << tagInfo().name << " valid since " << lastSince << "from "
0221                          << m_name << "::getNewObjects";
0222   }
0223 
0224   //retrieve the data from the relational database source
0225   cond::persistency::ConnectionPool connection;
0226   //configure the connection
0227   if (m_debug) {
0228     connection.setMessageVerbosity(coral::Debug);
0229   } else {
0230     connection.setMessageVerbosity(coral::Error);
0231   }
0232   connection.setAuthenticationPath(m_authpath);
0233   connection.configure();
0234   //create the sessions
0235   cond::persistency::Session session = connection.createSession(m_connectionString, false);
0236   // fetch last payload when available
0237   if (!tagInfo().lastInterval.payloadId.empty()) {
0238     cond::persistency::Session session3 = dbSession();
0239     session3.transaction().start(true);
0240     m_prevPayload = session3.fetchPayload<LHCInfoPerLS>(tagInfo().lastInterval.payloadId);
0241     session3.transaction().commit();
0242 
0243     // find startFillTime and endFillTime of the most recent fill already saved in the tag
0244     if (m_prevPayload->fillNumber() != 0) {
0245       cond::OMSService oms;
0246       oms.connect(m_omsBaseUrl);
0247       auto query = oms.query("fills");
0248       query->addOutputVar("end_time");
0249       query->addOutputVar("start_time");
0250       query->filterEQ("fill_number", m_prevPayload->fillNumber());
0251       bool foundFill = query->execute();
0252       if (foundFill) {
0253         auto result = query->result();
0254 
0255         if (!result.empty()) {
0256           std::string endTimeStr = (*result.begin()).get<std::string>("end_time");
0257           m_prevEndFillTime = (endTimeStr == "null")
0258                                   ? 0
0259                                   : cond::time::from_boost((*result.begin()).get<boost::posix_time::ptime>("end_time"));
0260           auto startFillTime = (*result.begin()).get<boost::posix_time::ptime>("start_time");
0261           m_prevStartFillTime = cond::time::from_boost(startFillTime);
0262         } else {
0263           foundFill = false;
0264         }
0265       }
0266       if (!foundFill) {
0267         edm::LogError(m_name) << "Could not find end time of fill #" << m_prevPayload->fillNumber();
0268       }
0269     } else {
0270       m_prevEndFillTime = 0;
0271       m_prevStartFillTime = 0;
0272     }
0273   }
0274 
0275   boost::posix_time::ptime executionTime = boost::posix_time::second_clock::local_time();
0276   cond::Time_t executionTimeIov = cond::time::from_boost(executionTime);
0277 
0278   cond::Time_t startTimestamp = m_startTime.is_not_a_date_time() ? 0 : cond::time::from_boost(m_startTime);
0279   cond::Time_t nextFillSearchTimestamp = std::max(startTimestamp, m_endFillMode ? lastSince : m_prevEndFillTime);
0280 
0281   edm::LogInfo(m_name) << "Starting sampling at "
0282                        << boost::posix_time::to_simple_string(cond::time::to_boost(nextFillSearchTimestamp));
0283 
0284   while (true) {
0285     if (nextFillSearchTimestamp >= executionTimeIov) {
0286       edm::LogInfo(m_name) << "Sampling ended at the time "
0287                            << boost::posix_time::to_simple_string(cond::time::to_boost(executionTimeIov));
0288       break;
0289     }
0290     boost::posix_time::ptime nextFillSearchTime = cond::time::to_boost(nextFillSearchTimestamp);
0291     boost::posix_time::ptime startSampleTime;
0292     boost::posix_time::ptime endSampleTime;
0293 
0294     cond::OMSService oms;
0295     oms.connect(m_omsBaseUrl);
0296     auto query = oms.query("fills");
0297 
0298     if (m_debugLogic)
0299       m_prevEndFillTime = 0ULL;
0300 
0301     if (!m_endFillMode and m_prevPayload->fillNumber() and m_prevEndFillTime == 0ULL) {
0302       // continue processing unfinished fill with some payloads already in the tag
0303       edm::LogInfo(m_name) << "Searching started fill #" << m_prevPayload->fillNumber();
0304       query->filterEQ("fill_number", m_prevPayload->fillNumber());
0305       bool foundFill = query->execute();
0306       if (foundFill)
0307         foundFill = makeFillPayload(m_fillPayload, query->result());
0308       if (!foundFill) {
0309         edm::LogError(m_name) << "Could not find fill #" << m_prevPayload->fillNumber();
0310         break;
0311       }
0312     } else {
0313       edm::LogInfo(m_name) << "Searching new fill after " << boost::posix_time::to_simple_string(nextFillSearchTime);
0314       query->filterNotNull("start_stable_beam").filterNotNull("fill_number");
0315       if (nextFillSearchTime > cond::time::to_boost(m_prevStartFillTime)) {
0316         query->filterGE("start_time", nextFillSearchTime);
0317       } else {
0318         query->filterGT("start_time", nextFillSearchTime);
0319       }
0320 
0321       query->filterLT("start_time", m_endTime);
0322       if (m_endFillMode)
0323         query->filterNotNull("end_time");
0324       else
0325         query->filterEQ("end_time", cond::OMSServiceQuery::SNULL);
0326 
0327       bool querySuccess = query->execute();
0328       if (!querySuccess) {
0329         edm::LogError(m_name) << "OMS fill query failed (http status not 200 nor 201). Request URL:\n" << query->url();
0330       }
0331       bool foundFill = querySuccess ? makeFillPayload(m_fillPayload, query->result()) : false;
0332 
0333       if (!foundFill) {
0334         if (m_endFillMode) {
0335           edm::LogInfo(m_name) << "No fill found - END of job.";
0336         } else {  //duringFill mode
0337           edm::LogInfo(m_name) << "No ongoing fill found.";
0338           addDefaultPayload(1, m_prevPayload->fillNumber(), oms);  //IOV doesn't matter here in duringFill mode
0339         }
0340         break;
0341       }
0342     }
0343     startSampleTime = cond::time::to_boost(m_startFillTime);
0344 
0345     unsigned short lhcFill = m_fillPayload->fillNumber();
0346     bool ongoingFill = m_endFillTime == 0ULL;
0347     if (ongoingFill) {
0348       edm::LogInfo(m_name) << "Found ongoing fill " << lhcFill << " created at "
0349                            << cond::time::to_boost(m_startFillTime);
0350       endSampleTime = executionTime;
0351       nextFillSearchTimestamp = executionTimeIov;
0352     } else {
0353       edm::LogInfo(m_name) << "Found fill " << lhcFill << " created at " << cond::time::to_boost(m_startFillTime)
0354                            << " ending at " << cond::time::to_boost(m_endFillTime);
0355       endSampleTime = cond::time::to_boost(m_endFillTime);
0356       nextFillSearchTimestamp = m_endFillTime;
0357     }
0358 
0359     if (m_endFillMode || ongoingFill) {
0360       getLumiData(oms, lhcFill, startSampleTime, endSampleTime);
0361 
0362       if (!m_tmpBuffer.empty()) {
0363         boost::posix_time::ptime flumiStart = cond::time::to_boost(m_tmpBuffer.front().first);
0364         boost::posix_time::ptime flumiStop = cond::time::to_boost(m_tmpBuffer.back().first);
0365         edm::LogInfo(m_name) << "First buffered lumi starts at " << flumiStart << " last lumi starts at " << flumiStop;
0366         session.transaction().start(true);
0367         getCTPPSData(session, startSampleTime, endSampleTime);
0368         session.transaction().commit();
0369       }
0370     }
0371 
0372     if (!m_endFillMode) {
0373       if (m_tmpBuffer.size() > 1) {
0374         throw cms::Exception("LHCInfoPerFillPopConSourceHandler")
0375             << "More than 1 payload buffered for writing in duringFill mode.\
0376            In this mode only up to 1 payload can be written";
0377       } else if (m_tmpBuffer.size() == 1) {
0378         if (theLHCInfoPerLSImpl::comparePayloads(*(m_tmpBuffer.begin()->second), *m_prevPayload)) {
0379           m_tmpBuffer.clear();
0380           edm::LogInfo(m_name)
0381               << "The buffered payload has the same data as the previous payload in the tag. It will not be written.";
0382         }
0383       } else if (m_tmpBuffer.empty()) {
0384         // note: the IOV doesn't matter when using OnlinePopCon:
0385         addDefaultPayload(1, lhcFill, oms);
0386       }
0387     }
0388 
0389     size_t niovs = theLHCInfoPerLSImpl::transferPayloads(
0390         m_tmpBuffer, m_iovs, m_prevPayload, m_lsIdMap, m_startStableBeamTime, m_endStableBeamTime);
0391     edm::LogInfo(m_name) << "Added " << niovs << " iovs within the Fill time";
0392     m_tmpBuffer.clear();
0393     m_lsIdMap.clear();
0394 
0395     if (!m_endFillMode) {
0396       return;
0397     }
0398 
0399     // endFill mode only:
0400     if (niovs) {
0401       m_prevEndFillTime = m_endFillTime;
0402       m_prevStartFillTime = m_startFillTime;
0403     }
0404     if (m_prevPayload->fillNumber() and !ongoingFill) {
0405       if (m_endFillMode) {
0406         addEmptyPayload(m_endFillTime);
0407       }
0408     }
0409   }
0410 }
0411 
0412 std::string LHCInfoPerLSPopConSourceHandler::id() const { return m_name; }
0413 
0414 void LHCInfoPerLSPopConSourceHandler::addEmptyPayload(cond::Time_t iov) {
0415   bool add = false;
0416   if (m_iovs.empty()) {
0417     if (!m_lastPayloadEmpty)
0418       add = true;
0419   } else {
0420     auto lastAdded = m_iovs.rbegin()->second;
0421     if (lastAdded->fillNumber() != 0) {
0422       add = true;
0423     }
0424   }
0425   if (add) {
0426     auto newPayload = std::make_shared<LHCInfoPerLS>();
0427     m_iovs.insert(make_pair(iov, newPayload));
0428     m_prevPayload = newPayload;
0429     m_prevEndFillTime = 0;
0430     m_prevStartFillTime = 0;
0431     edm::LogInfo(m_name) << "Added empty payload with IOV" << iov << " ( "
0432                          << boost::posix_time::to_iso_extended_string(cond::time::to_boost(iov)) << " )";
0433   }
0434 }
0435 
0436 void LHCInfoPerLSPopConSourceHandler::addDefaultPayload(cond::Time_t iov,
0437                                                         unsigned short fill,
0438                                                         const cond::OMSService& oms) {
0439   auto defaultPayload = std::make_shared<LHCInfoPerLS>();
0440   defaultPayload->setFillNumber(fill);
0441   auto [lastRun, lastLumi] = cond::lhcInfoHelper::getFillLastRunAndLS(oms, fill);
0442   addDefaultPayload(iov, fill, lastRun, lastLumi);
0443 }
0444 
0445 void LHCInfoPerLSPopConSourceHandler::addDefaultPayload(cond::Time_t iov,
0446                                                         unsigned short fill,
0447                                                         int run,
0448                                                         unsigned short lumi) {
0449   auto defaultPayload = std::make_shared<LHCInfoPerLS>();
0450   defaultPayload->setFillNumber(fill);
0451   defaultPayload->setRunNumber(run);
0452   defaultPayload->setLumiSection(lumi);
0453   defaultPayload->setCrossingAngleX(m_defaultCrossingAngleX);
0454   defaultPayload->setCrossingAngleY(m_defaultCrossingAngleY);
0455   defaultPayload->setBetaStarX(m_defaultBetaStarX);
0456   defaultPayload->setBetaStarY(m_defaultBetaStarY);
0457 
0458   if (m_prevPayload && theLHCInfoPerLSImpl::comparePayloads(*defaultPayload, *m_prevPayload)) {
0459     edm::LogInfo(m_name)
0460         << "The default payload has the same data as the previous payload in the tag. It will not be written.";
0461   } else {
0462     m_iovs.insert(make_pair(iov, defaultPayload));
0463     edm::LogInfo(m_name) << "Uploading the default payload.";
0464   }
0465 }
0466 
0467 bool LHCInfoPerLSPopConSourceHandler::makeFillPayload(std::unique_ptr<LHCInfoPerLS>& targetPayload,
0468                                                       const cond::OMSServiceResult& queryResult) {
0469   bool ret = false;
0470   if (!queryResult.empty()) {
0471     auto row = *queryResult.begin();
0472     auto currentFill = row.get<unsigned short>("fill_number");
0473     m_startFillTime = cond::time::from_boost(row.get<boost::posix_time::ptime>("start_time"));
0474     std::string endTimeStr = row.get<std::string>("end_time");
0475     if (m_debugLogic) {
0476       m_endFillTime = 0;
0477     } else {
0478       m_endFillTime =
0479           (endTimeStr == "null") ? 0 : cond::time::from_boost(row.get<boost::posix_time::ptime>("end_time"));
0480     }
0481     m_startStableBeamTime = cond::time::from_boost(row.get<boost::posix_time::ptime>("start_stable_beam"));
0482     m_endStableBeamTime = cond::time::from_boost(row.get<boost::posix_time::ptime>("end_stable_beam"));
0483     targetPayload = std::make_unique<LHCInfoPerLS>();
0484     targetPayload->setFillNumber(currentFill);
0485     ret = true;
0486   }
0487   return ret;
0488 }
0489 
0490 void LHCInfoPerLSPopConSourceHandler::addPayloadToBuffer(cond::OMSServiceResultRef& row) {
0491   auto lumiTime = row.get<boost::posix_time::ptime>("start_time");
0492   LHCInfoPerLS* thisLumiSectionInfo = new LHCInfoPerLS(*m_fillPayload);
0493   thisLumiSectionInfo->setLumiSection(std::stoul(row.get<std::string>("lumisection_number")));
0494   thisLumiSectionInfo->setRunNumber(std::stoul(row.get<std::string>("run_number")));
0495   m_lsIdMap[make_pair(thisLumiSectionInfo->runNumber(), thisLumiSectionInfo->lumiSection())] = make_pair(-1, -1);
0496   if (m_endFillMode) {
0497     m_tmpBuffer.emplace_back(make_pair(cond::time::from_boost(lumiTime), thisLumiSectionInfo));
0498   } else {
0499     m_tmpBuffer.emplace_back(
0500         make_pair(cond::time::lumiTime(thisLumiSectionInfo->runNumber(), thisLumiSectionInfo->lumiSection()),
0501                   thisLumiSectionInfo));
0502   }
0503 }
0504 
0505 size_t LHCInfoPerLSPopConSourceHandler::bufferAllLS(const cond::OMSServiceResult& queryResult) {
0506   for (auto r : queryResult) {
0507     addPayloadToBuffer(r);
0508   }
0509   return queryResult.size();
0510 }
0511 
0512 size_t LHCInfoPerLSPopConSourceHandler::getLumiData(const cond::OMSService& oms,
0513                                                     unsigned short fillId,
0514                                                     const boost::posix_time::ptime& beginFillTime,
0515                                                     const boost::posix_time::ptime& endFillTime) {
0516   auto query = oms.query("lumisections");
0517   query->addOutputVars({"start_time", "run_number", "beams_stable", "lumisection_number"});
0518   query->filterEQ("fill_number", fillId);
0519   query->filterGT("start_time", beginFillTime).filterLT("start_time", endFillTime);
0520   query->limit(cond::lhcInfoHelper::kLumisectionsQueryLimit);
0521   size_t nlumi = 0;
0522   if (query->execute()) {
0523     auto queryResult = query->result();
0524     if (m_endFillMode) {
0525       nlumi = bufferAllLS(queryResult);
0526     } else if (!queryResult.empty()) {
0527       auto newestPayload = queryResult.back();
0528       if (newestPayload.get<std::string>("beams_stable") == "true" || m_debugLogic) {
0529         addPayloadToBuffer(newestPayload);
0530         nlumi = 1;
0531         edm::LogInfo(m_name) << "Buffered most recent lumisection:"
0532                              << " LS: " << newestPayload.get<std::string>("lumisection_number")
0533                              << " run: " << newestPayload.get<std::string>("run_number");
0534       }
0535     }
0536     edm::LogInfo(m_name) << "Found " << queryResult.size() << " lumisections during the fill " << fillId;
0537   } else {
0538     edm::LogInfo(m_name) << "OMS query for lumisections of fill " << fillId << "failed, status:" << query->status();
0539   }
0540   return nlumi;
0541 }
0542 bool LHCInfoPerLSPopConSourceHandler::getCTPPSData(cond::persistency::Session& session,
0543                                                    const boost::posix_time::ptime& beginFillTime,
0544                                                    const boost::posix_time::ptime& endFillTime) {
0545   //run the fifth query against the CTPPS schema
0546   //Initializing the CMS_CTP_CTPPS_COND schema.
0547   coral::ISchema& CTPPS = session.coralSession().schema("CMS_PPS_SPECT_COND");
0548   //execute query for CTPPS Data
0549   std::unique_ptr<coral::IQuery> CTPPSDataQuery(CTPPS.newQuery());
0550   //FROM clause
0551   CTPPSDataQuery->addToTableList(std::string("PPS_LHC_MACHINE_PARAMS"));
0552   //SELECT clause
0553   CTPPSDataQuery->addToOutputList(std::string("DIP_UPDATE_TIME"));
0554   CTPPSDataQuery->addToOutputList(std::string("LUMI_SECTION"));
0555   CTPPSDataQuery->addToOutputList(std::string("RUN_NUMBER"));
0556   CTPPSDataQuery->addToOutputList(std::string("FILL_NUMBER"));
0557   CTPPSDataQuery->addToOutputList(std::string("XING_ANGLE_P5_X_URAD"));
0558   CTPPSDataQuery->addToOutputList(std::string("XING_ANGLE_P5_Y_URAD"));
0559   CTPPSDataQuery->addToOutputList(std::string("BETA_STAR_P5_X_M"));
0560   CTPPSDataQuery->addToOutputList(std::string("BETA_STAR_P5_Y_M"));
0561   //WHERE CLAUSE
0562   coral::AttributeList CTPPSDataBindVariables;
0563   CTPPSDataBindVariables.extend<coral::TimeStamp>(std::string("beginFillTime"));
0564   CTPPSDataBindVariables.extend<coral::TimeStamp>(std::string("endFillTime"));
0565   CTPPSDataBindVariables[std::string("beginFillTime")].data<coral::TimeStamp>() = coral::TimeStamp(beginFillTime);
0566   CTPPSDataBindVariables[std::string("endFillTime")].data<coral::TimeStamp>() = coral::TimeStamp(endFillTime);
0567   std::string conditionStr = std::string("DIP_UPDATE_TIME>= :beginFillTime and DIP_UPDATE_TIME< :endFillTime");
0568   CTPPSDataQuery->setCondition(conditionStr, CTPPSDataBindVariables);
0569   //ORDER BY clause
0570   CTPPSDataQuery->addToOrderList(std::string("DIP_UPDATE_TIME"));
0571   //define query output
0572   coral::AttributeList CTPPSDataOutput;
0573   CTPPSDataOutput.extend<coral::TimeStamp>(std::string("DIP_UPDATE_TIME"));
0574   CTPPSDataOutput.extend<int>(std::string("LUMI_SECTION"));
0575   CTPPSDataOutput.extend<int>(std::string("RUN_NUMBER"));
0576   CTPPSDataOutput.extend<int>(std::string("FILL_NUMBER"));
0577   CTPPSDataOutput.extend<float>(std::string("XING_ANGLE_P5_X_URAD"));
0578   CTPPSDataOutput.extend<float>(std::string("XING_ANGLE_P5_Y_URAD"));
0579   CTPPSDataOutput.extend<float>(std::string("BETA_STAR_P5_X_M"));
0580   CTPPSDataOutput.extend<float>(std::string("BETA_STAR_P5_Y_M"));
0581   CTPPSDataQuery->defineOutput(CTPPSDataOutput);
0582   //execute the query
0583   coral::ICursor& CTPPSDataCursor = CTPPSDataQuery->execute();
0584   unsigned int lumiSection = 0;
0585   cond::Time_t runNumber = 0;
0586   int fillNumber = 0;
0587   float crossingAngleX = 0., betaStarX = 0.;
0588   float crossingAngleY = 0., betaStarY = 0.;
0589 
0590   bool ret = false;
0591   int wrongFillNumbers = 0;
0592   std::stringstream wrongFills;
0593   std::vector<pair<cond::Time_t, std::shared_ptr<LHCInfoPerLS>>>::iterator current = m_tmpBuffer.begin();
0594   while (CTPPSDataCursor.next()) {
0595     if (m_debug) {
0596       std::ostringstream CTPPS;
0597       CTPPSDataCursor.currentRow().toOutputStream(CTPPS);
0598     }
0599     coral::Attribute const& dipTimeAttribute = CTPPSDataCursor.currentRow()[std::string("DIP_UPDATE_TIME")];
0600     if (!dipTimeAttribute.isNull()) {
0601       ret = true;
0602       coral::Attribute const& lumiSectionAttribute = CTPPSDataCursor.currentRow()[std::string("LUMI_SECTION")];
0603       if (!lumiSectionAttribute.isNull()) {
0604         lumiSection = lumiSectionAttribute.data<int>();
0605       }
0606       coral::Attribute const& runNumberAttribute = CTPPSDataCursor.currentRow()[std::string("RUN_NUMBER")];
0607       if (!runNumberAttribute.isNull()) {
0608         runNumber = runNumberAttribute.data<int>();
0609       }
0610       coral::Attribute const& fillNumberAttribute = CTPPSDataCursor.currentRow()[std::string("FILL_NUMBER")];
0611       if (!fillNumberAttribute.isNull()) {
0612         fillNumber = fillNumberAttribute.data<int>();
0613       }
0614       coral::Attribute const& crossingAngleXAttribute =
0615           CTPPSDataCursor.currentRow()[std::string("XING_ANGLE_P5_X_URAD")];
0616       if (!crossingAngleXAttribute.isNull()) {
0617         crossingAngleX = crossingAngleXAttribute.data<float>();
0618       }
0619       coral::Attribute const& crossingAngleYAttribute =
0620           CTPPSDataCursor.currentRow()[std::string("XING_ANGLE_P5_Y_URAD")];
0621       if (!crossingAngleYAttribute.isNull()) {
0622         crossingAngleY = crossingAngleYAttribute.data<float>();
0623       }
0624       coral::Attribute const& betaStarXAttribute = CTPPSDataCursor.currentRow()[std::string("BETA_STAR_P5_X_M")];
0625       if (!betaStarXAttribute.isNull()) {
0626         betaStarX = betaStarXAttribute.data<float>();
0627       }
0628       coral::Attribute const& betaStarYAttribute = CTPPSDataCursor.currentRow()[std::string("BETA_STAR_P5_Y_M")];
0629       if (!betaStarYAttribute.isNull()) {
0630         betaStarY = betaStarYAttribute.data<float>();
0631       }
0632       if (current != m_tmpBuffer.end() && current->second->fillNumber() != fillNumber) {
0633         wrongFills << "( " << runNumber << "_" << lumiSection << " fill: OMS: " << current->second->fillNumber()
0634                    << " PPSdb: " << fillNumber << " ) ";
0635         wrongFillNumbers++;
0636       }
0637       for (; current != m_tmpBuffer.end() && make_pair(current->second->runNumber(), current->second->lumiSection()) <=
0638                                                  make_pair(runNumber, lumiSection);
0639            current++) {
0640         LHCInfoPerLS& payload = *(current->second);
0641         payload.setCrossingAngleX(crossingAngleX);
0642         payload.setCrossingAngleY(crossingAngleY);
0643         payload.setBetaStarX(betaStarX);
0644         payload.setBetaStarY(betaStarY);
0645         payload.setLumiSection(lumiSection);
0646         payload.setRunNumber(runNumber);
0647         if (m_lsIdMap.find(make_pair(payload.runNumber(), payload.lumiSection())) != m_lsIdMap.end()) {
0648           m_lsIdMap[make_pair(payload.runNumber(), payload.lumiSection())] = make_pair(runNumber, lumiSection);
0649         }
0650       }
0651     }
0652   }
0653   if (wrongFillNumbers) {
0654     edm::LogWarning("getCTPPSData") << "Number of records from PPS DB with fillNumber different from OMS: "
0655                                     << wrongFillNumbers;
0656     edm::LogWarning("getCTPPSData") << "Records from PPS DB with fillNumber different from OMS: " << wrongFills.str();
0657   }
0658   return ret;
0659 }