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 <boost/tokenizer.hpp>
51 #include "boost/filesystem/path.hpp"
52 #include "boost/filesystem/operations.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;
65  float lumivalue;
66  unsigned long long deadcount;
67  unsigned int numorbit;
68  unsigned int startorbit;
69  unsigned int bitzerocount;
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);
87  void writeEmptyProductForEntry(edm::LuminosityBlock& iLBlock);
88  unsigned int maxavailableLSforRun(coral::ISchema& schema, const std::string& tablename, unsigned int runnumber);
89  std::string m_connectStr;
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 
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();
186  m_cachedrun = runnumber;
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  PerLSData l;
219  std::vector<float> mytmp(3564, 0.0);
220  l.bunchlumivalue.swap(mytmp);
221  std::vector<float> myerrtmp(3564, 0.0);
222  l.bunchlumierror.swap(myerrtmp);
223  std::vector<short> myqtmp(3564, 0);
224  l.bunchlumiquality.swap(myqtmp);
225  m_lscache.insert(std::make_pair(n, l));
226  }
227 
228  coral::AttributeList lumisummaryBindVariables;
229  lumisummaryBindVariables.extend("lsmin", typeid(unsigned int));
230  lumisummaryBindVariables.extend("runnumber", typeid(unsigned int));
231  lumisummaryBindVariables["runnumber"].data<unsigned int>() = m_cachedrun;
232  lumisummaryBindVariables["lsmin"].data<unsigned int>() = lsmin;
233  std::string conditionStr(" RUNNUMBER=:runnumber AND LUMISECTION>=:lsmin ");
234  coral::AttributeList lumisummaryOutput;
235  lumisummaryOutput.extend("LUMISECTION", typeid(unsigned int));
236  lumisummaryOutput.extend("INSTLUMI", typeid(float));
237  lumisummaryOutput.extend("DELIVLUMISECTION", typeid(float));
238  lumisummaryOutput.extend("LIVELUMISECTION", typeid(float));
239  lumisummaryOutput.extend("STARTORBIT", typeid(unsigned long long));
240  if (m_cachesize != 0) {
241  lumisummaryBindVariables.extend("lsmax", typeid(unsigned int));
242  conditionStr = conditionStr + "AND LUMISECTION<=:lsmax";
243  lumisummaryBindVariables["lsmax"].data<unsigned int>() = lsmax;
244  }
245  coral::IQuery* lumisummaryQuery = schema.newQuery();
246  lumisummaryQuery->addToTableList(std::string("LUMI_SECTIONS"));
247  lumisummaryQuery->addToOutputList("LUMISECTION");
248  lumisummaryQuery->addToOutputList("INSTLUMI");
249  lumisummaryQuery->addToOutputList("DELIVLUMISECTION");
250  lumisummaryQuery->addToOutputList("LIVELUMISECTION");
251  lumisummaryQuery->addToOutputList("STARTORBIT");
252  lumisummaryQuery->setCondition(conditionStr, lumisummaryBindVariables);
253  lumisummaryQuery->defineOutput(lumisummaryOutput);
254  coral::ICursor& lumisummarycursor = lumisummaryQuery->execute();
255  unsigned int rowcounter = 0;
256  while (lumisummarycursor.next()) {
257  const coral::AttributeList& row = lumisummarycursor.currentRow();
258  unsigned int lsnum = row["LUMISECTION"].data<unsigned int>();
259  float instlumi = 0.0;
260  if (!row["INSTLUMI"].isNull()) {
261  instlumi = row["INSTLUMI"].data<float>(); //Hz/ub
262  }
263  float deadfrac = 1.0;
264  float intgdellumi = 0.0;
265  float intgreclumi = 0.0;
266  unsigned long long startorbit = 0;
267  if (!row["DELIVLUMISECTION"].isNull()) {
268  intgdellumi = row["DELIVLUMISECTION"].data<float>() * 1000.0; //convert to /ub
269  }
270  if (!row["LIVELUMISECTION"].isNull()) {
271  intgreclumi = row["LIVELUMISECTION"].data<float>() * 1000.0; //convert to /ub
272  }
273  if (intgdellumi > 0) {
274  deadfrac = 1.0 - intgreclumi / intgdellumi;
275  }
276  if (!row["STARTORBIT"].isNull()) {
277  startorbit = row["STARTORBIT"].data<unsigned long long>(); //convert to /ub
278  }
279  unsigned long long deadcount = deadfrac * 10000.0;
280  unsigned long long bitzerocount = 10000.0;
281  PerLSData& lsdata = m_lscache[lsnum];
282  lsdata.lsnum = lsnum;
283  lsdata.lumivalue = instlumi;
284  lsdata.deadcount = deadcount;
285  lsdata.bitzerocount = bitzerocount;
286  lsdata.startorbit = startorbit;
287  lsdata.numorbit = 262144;
288  ++rowcounter;
289  }
290  if (rowcounter == 0) {
291  m_isNullRun = true;
292  }
293  delete lumisummaryQuery;
294  if (m_isNullRun)
295  return;
296  //
297  //queries once per cache refill
298  //
299  //select lumisection,bunch,bunchlumi from cms_runtime_logger.bunch_lumi_sections where lumisection>=:lsmin and lumisection<:lsmax and runnumber=:runnumber;
300  //
301  coral::AttributeList lumidetailBindVariables;
302  lumidetailBindVariables.extend("lsmin", typeid(unsigned int));
303  lumidetailBindVariables.extend("runnumber", typeid(unsigned int));
304  lumidetailBindVariables["runnumber"].data<unsigned int>() = m_cachedrun;
305  lumidetailBindVariables["lsmin"].data<unsigned int>() = lsmin;
306  std::string detailconditionStr(" RUNNUMBER=:runnumber AND LUMISECTION>=:lsmin AND BUNCHLUMI>0 ");
307  coral::AttributeList lumidetailOutput;
308  lumidetailOutput.extend("LUMISECTION", typeid(unsigned int));
309  lumidetailOutput.extend("BUNCH", typeid(unsigned int));
310  lumidetailOutput.extend("BUNCHLUMI", typeid(float));
311  if (m_cachesize != 0) {
312  lumidetailBindVariables.extend("lsmax", typeid(unsigned int));
313  detailconditionStr = detailconditionStr + "AND LUMISECTION<=:lsmax";
314  lumidetailBindVariables["lsmax"].data<unsigned int>() = lsmax;
315  }
316  coral::IQuery* lumidetailQuery = schema.newQuery();
317  lumidetailQuery->addToTableList(std::string("BUNCH_LUMI_SECTIONS"));
318  lumidetailQuery->addToOutputList("LUMISECTION");
319  lumidetailQuery->addToOutputList("BUNCH");
320  lumidetailQuery->addToOutputList("BUNCHLUMI");
321  lumidetailQuery->setCondition(detailconditionStr, lumidetailBindVariables);
322  lumidetailQuery->defineOutput(lumidetailOutput);
323  coral::ICursor& lumidetailcursor = lumidetailQuery->execute();
324  while (lumidetailcursor.next()) {
325  const coral::AttributeList& row = lumidetailcursor.currentRow();
326  unsigned int lsnum = row["LUMISECTION"].data<unsigned int>();
327  unsigned int bxidx = row["BUNCH"].data<unsigned int>();
328  float bxlumi = row["BUNCHLUMI"].data<float>(); //Hz/ub
329  m_lscache[lsnum].bunchlumivalue[bxidx] = bxlumi;
330  }
331  delete lumidetailQuery;
332  session->transaction().commit();
333  } catch (const coral::Exception& er) {
334  session->transaction().rollback();
335  throw cms::Exception("DatabaseError ") << er.what();
336  }
337 }
339  //std::cout<<"writing runnumber,luminum "<<runnumber<<" "<<luminum<<std::endl;
340  auto pIn1 = std::make_unique<LumiSummary>();
341  auto pIn2 = std::make_unique<LumiDetails>();
342  if (m_isNullRun) {
343  pIn1->setLumiVersion("DIP");
344  pIn2->setLumiVersion("DIP");
345  iLBlock.put(std::move(pIn1));
346  iLBlock.put(std::move(pIn2));
347  return;
348  }
349  PerLSData& lsdata = m_lscache[luminum];
350  pIn1->setLumiVersion("DIP");
351  pIn1->setLumiData(lsdata.lumivalue, 0.0, 0.0);
352  pIn1->setDeadCount(lsdata.deadcount);
353  pIn1->setBitZeroCount(lsdata.bitzerocount);
354  pIn1->setlsnumber(lsdata.lsnum);
355  pIn1->setOrbitData(lsdata.startorbit, lsdata.numorbit);
356 
357  pIn2->setLumiVersion("DIP");
358  pIn2->fill(LumiDetails::kOCC1, lsdata.bunchlumivalue, lsdata.bunchlumierror, lsdata.bunchlumiquality);
359  iLBlock.put(std::move(pIn1));
360  iLBlock.put(std::move(pIn2));
361 }
ISessionProxyPtr connectReadOnly(const std::string &connectstring)
Definition: DBService.cc:19
std::vector< short > bunchlumiquality
LuminosityBlockNumber_t luminosityBlock() const
#define DEFINE_FWK_MODULE(type)
Definition: MakerMacros.h:16
void put(std::unique_ptr< PROD > product)
Put a new product.
void fillLSCache(unsigned int runnum, unsigned int luminum)
bool isAvailable() const
Definition: Service.h:40
RunNumber_t run() const
void produce(edm::Event &, const edm::EventSetup &) final
Definition: Binary.h:9
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.
def move(src, dest)
Definition: eostools.py:511