Back to home page

Project CMSSW displayed by LXR

 
 

    


File indexing completed on 2024-11-11 23:31:24

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