Back to home page

Project CMSSW displayed by LXR

 
 

    


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

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