CMS 3D CMS Logo

ExpressLumiProducer.cc
Go to the documentation of this file.
1 // -*- C++ -*-
2 //
3 // Package: LumiProducer
4 // Class: ExpressLumiProducer
5 //
9 // read lumi from dip database and dump to express stream
10 
23 
24 #include "CoralBase/Exception.h"
25 #include "CoralBase/AttributeList.h"
26 #include "CoralBase/Attribute.h"
27 #include "CoralBase/AttributeSpecification.h"
28 #include "CoralBase/Exception.h"
29 #include "CoralBase/Blob.h"
30 #include "RelationalAccess/ISessionProxy.h"
31 #include "RelationalAccess/ITransaction.h"
32 #include "RelationalAccess/AccessMode.h"
33 #include "RelationalAccess/ITypeConverter.h"
34 #include "RelationalAccess/IQuery.h"
35 #include "RelationalAccess/ICursor.h"
36 #include "RelationalAccess/ISchema.h"
37 #include "RelationalAccess/ITable.h"
38 
42 #include <iostream>
43 #include <sstream>
44 #include <string>
45 #include <memory>
46 #include <algorithm>
47 #include <vector>
48 #include <cstring>
49 #include <iterator>
50 #include <filesystem>
51 
52 #include <boost/tokenizer.hpp>
53 
54 namespace edm {
55  class EventSetup;
56 }
57 
58 //
59 // class declaration
60 //
61 class ExpressLumiProducer : public edm::one::EDProducer<edm::BeginLuminosityBlockProducer> {
62 public:
63  struct PerLSData {
64  unsigned int lsnum = 0;
65  float lumivalue = 0.0;
66  unsigned long long deadcount = 0;
67  unsigned int numorbit = 0;
68  unsigned int startorbit = 0;
69  unsigned int bitzerocount = 0;
70  std::vector<float> bunchlumivalue;
71  std::vector<float> bunchlumierror;
72  std::vector<short> bunchlumiquality;
73  };
74 
75  explicit ExpressLumiProducer(const edm::ParameterSet&);
76 
77  ~ExpressLumiProducer() override;
78 
79 private:
80  void produce(edm::Event&, const edm::EventSetup&) final;
81 
82  void beginLuminosityBlockProduce(edm::LuminosityBlock& iLBlock, edm::EventSetup const& iSetup) final;
83 
84  bool fillLumi(edm::LuminosityBlock& iLBlock);
85  void fillLSCache(unsigned int runnum, unsigned int luminum);
86  void writeProductsForEntry(edm::LuminosityBlock& iLBlock, unsigned int luminum);
88  unsigned int maxavailableLSforRun(coral::ISchema& schema, const std::string& tablename, unsigned int runnumber);
90  unsigned int m_cachedrun;
91  bool m_isNullRun; //if lumi data exist for this run
92  unsigned int m_cachesize;
93  std::map<unsigned int, PerLSData> m_lscache;
94 };
95 
96 ExpressLumiProducer::ExpressLumiProducer::ExpressLumiProducer(const edm::ParameterSet& iConfig)
97  : m_cachedrun(0), m_isNullRun(false), m_cachesize(0) {
98  // register your products
99  produces<LumiSummary, edm::Transition::BeginLuminosityBlock>();
100  produces<LumiDetails, edm::Transition::BeginLuminosityBlock>();
101  // set up cache
102  m_connectStr = iConfig.getParameter<std::string>("connect");
103  m_cachesize = iConfig.getUntrackedParameter<unsigned int>("ncacheEntries", 5);
104 }
105 
107 
108 //
109 // member functions
110 //
112 
114  iLBlock.put(std::make_unique<LumiSummary>());
115  iLBlock.put(std::make_unique<LumiDetails>());
116 }
118  unsigned int currentrun = iLBlock.run();
119  unsigned int currentls = iLBlock.luminosityBlock();
120  //if is null run, fill empty values and return
121  if (m_isNullRun) {
122  writeEmptyProductForEntry(iLBlock);
123  return;
124  }
125  if (m_cachedrun != currentrun) {
126  fillLSCache(currentrun, currentls);
127  } else {
128  if (m_lscache.find(currentls) == m_lscache.end()) {
129  //if runnumber is cached but LS is not, this is the first LS, fill LS cache to full capacity
130  fillLSCache(currentrun, currentls);
131  }
132  }
133  if (m_lscache.empty()) {
134  writeEmptyProductForEntry(iLBlock);
135  return;
136  }
137  unsigned int lstowriteout = 0;
138  if (m_lscache.find(currentls) == m_lscache.end()) { //if the currentls is not in the cache
139  std::vector<unsigned int> v;
140  for (std::map<unsigned int, ExpressLumiProducer::PerLSData>::iterator it = m_lscache.begin(); it != m_lscache.end();
141  ++it) {
142  v.push_back(it->first);
143  }
144  lstowriteout = v.back(); //last available
145  } else { //if the current ls is cached
146  lstowriteout = currentls;
147  }
148  //here the presence of ls is guaranteed
149  //std::cout<<"writing "<<runnumber<<" "<<luminum<<std::endl;
150  if (lstowriteout == 0) {
151  writeEmptyProductForEntry(iLBlock);
152  } else {
153  writeProductsForEntry(iLBlock, lstowriteout);
154  }
155 }
156 
157 unsigned int ExpressLumiProducer::maxavailableLSforRun(coral::ISchema& schema,
158  const std::string& tablename,
159  unsigned int runnumber) {
163  unsigned int result = 0;
164  coral::AttributeList bindVariables;
165  bindVariables.extend("runnumber", typeid(unsigned int));
166  bindVariables["runnumber"].data<unsigned int>() = runnumber;
167  std::string conditionStr("RUNNUMBER=:runnumber");
168  coral::AttributeList MyOutput;
169  MyOutput.extend("maxavailablels", typeid(unsigned int));
170  coral::IQuery* myQuery = schema.newQuery();
171  myQuery->addToTableList(tablename);
172  myQuery->addToOutputList("max(LUMISECTION)", "maxavailablels");
173  myQuery->setCondition(conditionStr, bindVariables);
174  myQuery->defineOutput(MyOutput);
175  coral::ICursor& mycursor = myQuery->execute();
176  while (mycursor.next()) {
177  const coral::AttributeList& row = mycursor.currentRow();
178  if (!row["maxavailablels"].isNull()) {
179  result = row["maxavailablels"].data<unsigned int>();
180  }
181  }
182  return result;
183 }
184 void ExpressLumiProducer::fillLSCache(unsigned int runnumber, unsigned int currentlsnum) {
185  m_lscache.clear();
187  //
188  //queries once per cache refill
189  //
190  //select lumisection,instlumi,delivlumi,livelumi from cms_runtime_logger.lumi_sections where lumisection>=:lsmin and lumisection<:lsmax and runnumber=:runnumber;
191  //
193  if (!mydbservice.isAvailable()) {
194  throw cms::Exception("Non existing service lumi::service::DBService");
195  }
196  auto session = mydbservice->connectReadOnly(m_connectStr);
197  coral::ITypeConverter& tconverter = session->typeConverter();
198  tconverter.setCppTypeForSqlType(std::string("float"), std::string("FLOAT(63)"));
199  tconverter.setCppTypeForSqlType(std::string("unsigned int"), std::string("NUMBER(10)"));
200  tconverter.setCppTypeForSqlType(std::string("unsigned short"), std::string("NUMBER(1)"));
201  unsigned int lsmin = 1;
202  unsigned int lsmax = currentlsnum;
203  try {
204  session->transaction().start(true);
205  coral::ISchema& schema = session->nominalSchema();
206  unsigned int maxavailableLS = maxavailableLSforRun(schema, std::string("LUMI_SECTIONS"), m_cachedrun);
207  if (maxavailableLS != 0 && maxavailableLS < currentlsnum) {
208  lsmax = maxavailableLS;
209  } else if (maxavailableLS == 0) {
210  //this run not existing (yet)
211  session->transaction().commit();
212  return;
213  }
214  if (m_cachesize != 0) {
215  lsmin = (lsmax - m_cachesize) > 0 ? (lsmax - m_cachesize + 1) : 1;
216  }
217  for (unsigned int n = lsmin; n <= lsmax; ++n) {
218  m_lscache.insert(std::make_pair(
219  n, PerLSData{.bunchlumivalue = {3564, 0.0}, .bunchlumierror = {3564, 0.0}, .bunchlumiquality = {3564, 0}}));
220  }
221 
222  coral::AttributeList lumisummaryBindVariables;
223  lumisummaryBindVariables.extend("lsmin", typeid(unsigned int));
224  lumisummaryBindVariables.extend("runnumber", typeid(unsigned int));
225  lumisummaryBindVariables["runnumber"].data<unsigned int>() = m_cachedrun;
226  lumisummaryBindVariables["lsmin"].data<unsigned int>() = lsmin;
227  std::string conditionStr(" RUNNUMBER=:runnumber AND LUMISECTION>=:lsmin ");
228  coral::AttributeList lumisummaryOutput;
229  lumisummaryOutput.extend("LUMISECTION", typeid(unsigned int));
230  lumisummaryOutput.extend("INSTLUMI", typeid(float));
231  lumisummaryOutput.extend("DELIVLUMISECTION", typeid(float));
232  lumisummaryOutput.extend("LIVELUMISECTION", typeid(float));
233  lumisummaryOutput.extend("STARTORBIT", typeid(unsigned long long));
234  if (m_cachesize != 0) {
235  lumisummaryBindVariables.extend("lsmax", typeid(unsigned int));
236  conditionStr = conditionStr + "AND LUMISECTION<=:lsmax";
237  lumisummaryBindVariables["lsmax"].data<unsigned int>() = lsmax;
238  }
239  coral::IQuery* lumisummaryQuery = schema.newQuery();
240  lumisummaryQuery->addToTableList(std::string("LUMI_SECTIONS"));
241  lumisummaryQuery->addToOutputList("LUMISECTION");
242  lumisummaryQuery->addToOutputList("INSTLUMI");
243  lumisummaryQuery->addToOutputList("DELIVLUMISECTION");
244  lumisummaryQuery->addToOutputList("LIVELUMISECTION");
245  lumisummaryQuery->addToOutputList("STARTORBIT");
246  lumisummaryQuery->setCondition(conditionStr, lumisummaryBindVariables);
247  lumisummaryQuery->defineOutput(lumisummaryOutput);
248  coral::ICursor& lumisummarycursor = lumisummaryQuery->execute();
249  unsigned int rowcounter = 0;
250  while (lumisummarycursor.next()) {
251  const coral::AttributeList& row = lumisummarycursor.currentRow();
252  unsigned int lsnum = row["LUMISECTION"].data<unsigned int>();
253  float instlumi = 0.0;
254  if (!row["INSTLUMI"].isNull()) {
255  instlumi = row["INSTLUMI"].data<float>(); //Hz/ub
256  }
257  float deadfrac = 1.0;
258  float intgdellumi = 0.0;
259  float intgreclumi = 0.0;
260  unsigned long long startorbit = 0;
261  if (!row["DELIVLUMISECTION"].isNull()) {
262  intgdellumi = row["DELIVLUMISECTION"].data<float>() * 1000.0; //convert to /ub
263  }
264  if (!row["LIVELUMISECTION"].isNull()) {
265  intgreclumi = row["LIVELUMISECTION"].data<float>() * 1000.0; //convert to /ub
266  }
267  if (intgdellumi > 0) {
268  deadfrac = 1.0 - intgreclumi / intgdellumi;
269  }
270  if (!row["STARTORBIT"].isNull()) {
271  startorbit = row["STARTORBIT"].data<unsigned long long>(); //convert to /ub
272  }
273  unsigned long long deadcount = deadfrac * 10000.0;
274  unsigned long long bitzerocount = 10000.0;
275  PerLSData& lsdata = m_lscache[lsnum];
276  lsdata.lsnum = lsnum;
277  lsdata.lumivalue = instlumi;
278  lsdata.deadcount = deadcount;
279  lsdata.bitzerocount = bitzerocount;
280  lsdata.startorbit = startorbit;
281  lsdata.numorbit = 262144;
282  ++rowcounter;
283  }
284  if (rowcounter == 0) {
285  m_isNullRun = true;
286  }
287  delete lumisummaryQuery;
288  if (m_isNullRun)
289  return;
290  //
291  //queries once per cache refill
292  //
293  //select lumisection,bunch,bunchlumi from cms_runtime_logger.bunch_lumi_sections where lumisection>=:lsmin and lumisection<:lsmax and runnumber=:runnumber;
294  //
295  coral::AttributeList lumidetailBindVariables;
296  lumidetailBindVariables.extend("lsmin", typeid(unsigned int));
297  lumidetailBindVariables.extend("runnumber", typeid(unsigned int));
298  lumidetailBindVariables["runnumber"].data<unsigned int>() = m_cachedrun;
299  lumidetailBindVariables["lsmin"].data<unsigned int>() = lsmin;
300  std::string detailconditionStr(" RUNNUMBER=:runnumber AND LUMISECTION>=:lsmin AND BUNCHLUMI>0 ");
301  coral::AttributeList lumidetailOutput;
302  lumidetailOutput.extend("LUMISECTION", typeid(unsigned int));
303  lumidetailOutput.extend("BUNCH", typeid(unsigned int));
304  lumidetailOutput.extend("BUNCHLUMI", typeid(float));
305  if (m_cachesize != 0) {
306  lumidetailBindVariables.extend("lsmax", typeid(unsigned int));
307  detailconditionStr = detailconditionStr + "AND LUMISECTION<=:lsmax";
308  lumidetailBindVariables["lsmax"].data<unsigned int>() = lsmax;
309  }
310  coral::IQuery* lumidetailQuery = schema.newQuery();
311  lumidetailQuery->addToTableList(std::string("BUNCH_LUMI_SECTIONS"));
312  lumidetailQuery->addToOutputList("LUMISECTION");
313  lumidetailQuery->addToOutputList("BUNCH");
314  lumidetailQuery->addToOutputList("BUNCHLUMI");
315  lumidetailQuery->setCondition(detailconditionStr, lumidetailBindVariables);
316  lumidetailQuery->defineOutput(lumidetailOutput);
317  coral::ICursor& lumidetailcursor = lumidetailQuery->execute();
318  while (lumidetailcursor.next()) {
319  const coral::AttributeList& row = lumidetailcursor.currentRow();
320  unsigned int lsnum = row["LUMISECTION"].data<unsigned int>();
321  unsigned int bxidx = row["BUNCH"].data<unsigned int>();
322  float bxlumi = row["BUNCHLUMI"].data<float>(); //Hz/ub
323  m_lscache[lsnum].bunchlumivalue[bxidx] = bxlumi;
324  }
325  delete lumidetailQuery;
326  session->transaction().commit();
327  } catch (const coral::Exception& er) {
328  session->transaction().rollback();
329  throw cms::Exception("DatabaseError ") << er.what();
330  }
331 }
333  //std::cout<<"writing runnumber,luminum "<<runnumber<<" "<<luminum<<std::endl;
334  auto pIn1 = std::make_unique<LumiSummary>();
335  auto pIn2 = std::make_unique<LumiDetails>();
336  if (m_isNullRun) {
337  pIn1->setLumiVersion("DIP");
338  pIn2->setLumiVersion("DIP");
339  iLBlock.put(std::move(pIn1));
340  iLBlock.put(std::move(pIn2));
341  return;
342  }
343  PerLSData& lsdata = m_lscache[luminum];
344  pIn1->setLumiVersion("DIP");
345  pIn1->setLumiData(lsdata.lumivalue, 0.0, 0.0);
346  pIn1->setDeadCount(lsdata.deadcount);
347  pIn1->setBitZeroCount(lsdata.bitzerocount);
348  pIn1->setlsnumber(lsdata.lsnum);
349  pIn1->setOrbitData(lsdata.startorbit, lsdata.numorbit);
350 
351  pIn2->setLumiVersion("DIP");
352  pIn2->fill(LumiDetails::kOCC1, lsdata.bunchlumivalue, lsdata.bunchlumierror, lsdata.bunchlumiquality);
353  iLBlock.put(std::move(pIn1));
354  iLBlock.put(std::move(pIn2));
355 }
T getParameter(std::string const &) const
Definition: ParameterSet.h:307
int runnum
ISessionProxyPtr connectReadOnly(const std::string &connectstring)
Definition: DBService.cc:19
std::vector< short > bunchlumiquality
T getUntrackedParameter(std::string const &, T const &) const
void put(std::unique_ptr< PROD > product)
Put a new product.
void fillLSCache(unsigned int runnum, unsigned int luminum)
void produce(edm::Event &, const edm::EventSetup &) final
#define DEFINE_FWK_MODULE(type)
Definition: MakerMacros.h:16
void writeProductsForEntry(edm::LuminosityBlock &iLBlock, unsigned int luminum)
void writeEmptyProductForEntry(edm::LuminosityBlock &iLBlock)
void beginLuminosityBlockProduce(edm::LuminosityBlock &iLBlock, edm::EventSetup const &iSetup) final
unsigned int maxavailableLSforRun(coral::ISchema &schema, const std::string &tablename, unsigned int runnumber)
HLT enums.
ExpressLumiProducer(const edm::ParameterSet &)
bool isAvailable() const
Definition: Service.h:40
LuminosityBlockNumber_t luminosityBlock() const
std::map< unsigned int, PerLSData > m_lscache
def move(src, dest)
Definition: eostools.py:511
bool fillLumi(edm::LuminosityBlock &iLBlock)