Back to home page

Project CMSSW displayed by LXR

 
 

    


File indexing completed on 2023-08-30 02:33:01

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