Belle II Software  release-08-01-10
DQMHistAnalysisOutputMonObj.cc
1 /**************************************************************************
2  * basf2 (Belle II Analysis Software Framework) *
3  * Author: The Belle II Collaboration *
4  * *
5  * See git log for contributors and copyright holders. *
6  * This file is licensed under LGPL-3.0, see LICENSE.md. *
7  **************************************************************************/
8 
9 
10 #include <dqm/analysis/modules/DQMHistAnalysisOutputMonObj.h>
11 #include <framework/dataobjects/EventMetaData.h>
12 #include <framework/datastore/DataStore.h>
13 #include <framework/datastore/StoreObjPtr.h>
14 #include "TFile.h"
15 #include "TTree.h"
16 #include "TString.h"
17 #include <time.h>
18 
19 
20 using namespace std;
21 using namespace Belle2;
22 
23 //-----------------------------------------------------------------
24 // Register the Module
25 //-----------------------------------------------------------------
26 REG_MODULE(DQMHistAnalysisOutputMonObj);
27 
28 //-----------------------------------------------------------------
29 // Implementation
30 //-----------------------------------------------------------------
31 
32 DQMHistAnalysisOutputMonObjModule::DQMHistAnalysisOutputMonObjModule()
34 {
35  setDescription("Module to process run information.");
36 
37  //Parameter definition
38  addParam("Filename", m_filename, "Output root filename (if not set mon_e{exp}r{run}.root is used", std::string(""));
39  addParam("TreeFile", m_treeFile, "If set, entry to run summary TTree from TreeFile is made", std::string(""));
40  addParam("ProcID", m_procID, "Processing id (online,proc10, etc.)", std::string("online"));
41  addParam("run", m_run, "Run number", 0);
42  addParam("exp", m_exp, "Experiment number", 0);
43  addParam("nevt", m_nevt, "Number of events", 0);
44  addParam("runtype", m_runtype, "Run type", std::string(""));
45 
46  B2DEBUG(20, "DQMHistAnalysisOutputMonObj: Constructor done.");
47 }
48 
49 
51 
53 {
54  B2DEBUG(20, "DQMHistAnalysisOutputMonObj: initialized.");
55  // create file metadata
58 }
59 
60 
62 {
63  B2DEBUG(20, "DQMHistAnalysisOutputMonObj: beginRun called.");
64 }
65 
66 
68 {
69  B2DEBUG(20, "DQMHistAnalysisOutputMonObj: event called.");
70 }
71 
73 {
74  B2INFO("DQMHistAnalysisOutputMonObj: endRun called");
75 
76  StoreObjPtr<EventMetaData> lastEvtMeta;
77 
78  B2INFO("open file");
79  TH1* hrun = findHist("DQMInfo/runno");
80  TH1* hexp = findHist("DQMInfo/expno");
81 
82  int run = hrun ? std::stoi(hrun->GetTitle()) : m_run;
83  int exp = hexp ? std::stoi(hexp->GetTitle()) : m_exp;
84  TString fname;
85  if (m_filename.length()) fname = m_filename;
86  else fname = TString::Format("mon_e%04dr%06d_%s.root", exp, run, m_procID.c_str());
87 
88  TH1* runtype = findHist("DQMInfo/rtype");
89  if (runtype) m_metaData->setRunType(std::string(runtype->GetTitle()));
91  TH1* hnevt = findHist("DAQ/Nevent");
92  if (hnevt) m_metaData->setNEvents(hnevt->GetEntries());
94 
95  TFile f(fname, "NEW");
96 
97  if (f.IsZombie()) {
98  B2WARNING("File " << LogVar("MonitoringObject file",
99  fname) << " already exists and it will not be rewritten. If desired please delete file and re-run.");
100  return;
101  }
102 
103  // set meta data info
104  // m_metaData->setNEvents(lastEvtMeta->getEvent());
105  m_metaData->setExperimentRun(exp, run);
106  time_t ts = lastEvtMeta->getTime() / 1e9;
107  struct tm* timeinfo;
108  timeinfo = localtime(&ts);
109  // cppcheck-suppress asctimeCalled
110  m_metaData->setRunDate(asctime(timeinfo));
111 
112  m_metaData->Write();
113  // get list of existing monitoring objects
114  const MonObjList& objts = getMonObjList();
115  // write them to the output file
116  for (const auto& obj : objts)(obj.second)->Write();
117 
118  f.Close();
119 
120  if (m_treeFile.length() > 0) addTreeEntry();
121 
122 }
123 
125 {
126 
127  TFile* treeFile = new TFile(m_treeFile.c_str(), "update");
128  auto* tree = (TTree*)treeFile->Get("tree");
129 
130  if (tree == NULL) tree = new TTree("tree", "tree");
131 
132  int run = m_metaData->getRun();
133  int expe = m_metaData->getExperiment();
134  int nevt = m_metaData->getNEvents();
135  //int rune = 0;
136  //int expee = 0;
137  char* rel = const_cast<char*>(m_metaData->getRelease().c_str());
138  char* db = const_cast<char*>(m_metaData->getDatabaseGlobalTag().c_str());
139  char* datee = const_cast<char*>(m_metaData->getRunDate().c_str());
140  char* rtype = const_cast<char*>(m_metaData->getRunType().c_str());
141  char* procID = const_cast<char*>(m_metaData->getProcessingID().c_str());
142 
143  auto b_run = tree->GetBranch("run");
144  auto b_exp = tree->GetBranch("exp");
145  auto b_release = tree->GetBranch("release");
146  auto b_gt = tree->GetBranch("gt");
147  auto b_datetime = tree->GetBranch("datetime");
148  auto b_rtype = tree->GetBranch("rtype");
149  auto b_procID = tree->GetBranch("procID");
150  auto b_nevt = tree->GetBranch("nevt");
151 
152  // this still needs to be sorted out
153  /*if(b_run){
154  b_run->SetAddress(&rune);
155  b_exp->SetAddress(&expee);
156  for(int ie = 0; ie<b_run->GetEntries(); ie++){
157  b_run->GetEntry(ir);
158  b_exp->GetEntry(ir);
159  if(rune == run && expee = expe){
160 
161  }
162  }
163  }*/
164 
165 
166  if (!b_run) tree->Branch("run", &run, "run/I");
167  else b_run->SetAddress(&run);
168  if (!b_exp) tree->Branch("exp", &expe, "exp/I");
169  else b_exp->SetAddress(&expe);
170  if (!b_nevt) tree->Branch("nevt", &nevt, "nevt/I");
171  else b_nevt->SetAddress(&nevt);
172  if (!b_release) tree->Branch("release", rel, "release/C");
173  else b_release->SetAddress(rel);
174  if (!b_gt) tree->Branch("gt", db, "gt/C");
175  else b_gt->SetAddress(db);
176  if (!b_datetime) tree->Branch("datetime", datee, "datetime/C");
177  else b_datetime->SetAddress(datee);
178  if (!b_rtype) tree->Branch("rtype", rtype, "rtype/C");
179  else b_rtype->SetAddress(rtype);
180  if (!b_procID) tree->Branch("procID", procID, "procID/C");
181  else b_procID->SetAddress(procID);
182 
183 
184  const MonObjList& objts = getMonObjList();
185  // write them to the output file
186  for (const auto& obj : objts) {
187  std::map<std::string, float>& vars = const_cast<std::map<std::string, float>&>((obj.second)->getVariables());
188  std::map<std::string, float>& upErr = const_cast<std::map<std::string, float>&>((obj.second)->getUpError());
189  std::map<std::string, float>& lowErr = const_cast<std::map<std::string, float>&>((obj.second)->getLowError());
190 
191  const std::vector<std::pair<std::string, std::string>>& strVars = (obj.second)->getStringVariables();
192 
193  for (auto& var : vars) {
194  std::string brname = obj.first + "_" + var.first;
195  auto branch = tree->GetBranch((brname).c_str());
196  if (!branch) {
197  branch = tree->Branch((brname).c_str(), &(var.second));
198  fillBranch(branch);
199  } else branch->SetAddress(&(var.second));
200 
201  auto vvE1 = upErr.find(var.first);
202  auto vvE2 = lowErr.find(var.first);
203 
204  if (vvE1 != upErr.end() && vvE2 == lowErr.end()) {
205  auto errBranch = tree->GetBranch((brname).c_str() + TString("_err"));
206  if (!errBranch) {
207  errBranch = tree->Branch((brname).c_str() + TString("_err"), &(vvE1->second));
208  fillBranch(errBranch);
209  } else errBranch->SetAddress(&(vvE1->second));
210  }
211 
212  if (vvE1 != upErr.end() && vvE2 != lowErr.end()) {
213  auto errBranch1 = tree->GetBranch((brname).c_str() + TString("_upErr"));
214  if (!errBranch1) {
215  errBranch1 = tree->Branch((brname).c_str() + TString("_upErr"), &(vvE1->second));
216  fillBranch(errBranch1);
217  } else errBranch1->SetAddress(&(vvE1->second));
218 
219  auto errBranch2 = tree->GetBranch((brname).c_str() + TString("_dwErr"));
220  if (!errBranch2) {
221  errBranch2 = tree->Branch((brname).c_str() + TString("_dwErr"), &(vvE2->second));
222  fillBranch(errBranch2);
223  } else errBranch2->SetAddress(&(vvE2->second));
224 
225  }
226  }
227 
228  for (auto& var : strVars) {
229  std::string brname = obj.first + "_" + var.first;
230  char* cc = const_cast<char*>((var.second).c_str());
231  auto branch = tree->GetBranch((brname).c_str());
232  if (!branch) {
233  std::string ty = brname + "/C";
234  branch = tree->Branch((brname).c_str(), cc, ty.c_str());
235  fillBranch(branch);
236  } else branch->SetAddress(cc);
237  }
238  }
239 
240  tree->Fill();
241  tree->Write(0, TObject::kWriteDelete, 0);
242  treeFile->Close();
243 
244 }
245 
247 {
248  TTree* tree = (TTree*)branch->GetTree();
249  int nentr = tree->GetEntries();
250  for (int i = 0; i < nentr; i++) {
251  tree->GetEntry(i);
252  branch->Fill();
253  }
254 }
255 
256 
257 
259 {
260  B2INFO("DQMHistAnalysisOutputMonObj: terminate called");
261 // Attention, we can not do that in Terminate, as then the memFile is already closed by previous task!
262 
263 }
264 
Metadata information about a DQM file.
void setExperimentRun(int experiment, int run)
Set experiment and run.
unsigned int getNEvents() const
Number of events getter.
void setRunType(const std::string &rtype)
set run type
int getRun() const
run number getter.
const std::string & getRunDate() const
Run date getter (UTC)
void setProcessingID(const std::string &procID)
set processing ID
void setRunDate(const std::string &date)
set run date
const std::string & getDatabaseGlobalTag() const
Get the database global tag used when creating this file.
const std::string & getRelease() const
Software release version getter.
int getExperiment() const
experiment number getter.
const std::string & getRunType() const
Run type getter.
void setNEvents(unsigned int nEvents)
Number of events setter.
const std::string & getProcessingID() const
Processing ID getter.
The base class for the histogram analysis module.
static TH1 * findHist(const std::string &histname, bool onlyIfUpdated=false)
Get histogram from list (no other search).
std::map< std::string, MonitoringObject * > MonObjList
The type of list of MonitoringObjects.
static const MonObjList & getMonObjList()
Get the list of MonitoringObjects.
void terminate() override final
This method is called at the end of the event processing.
void event() override final
This method is called for each event.
std::string m_procID
processing id (online,proc10,etc)
void fillBranch(TBranch *br)
if new variables is added to run summary TTree this files
void endRun() override final
This method is called if the current run ends.
void beginRun() override final
Called when entering a new run.
void addTreeEntry()
Makes entry with monitoring variables in the run summary TTree.
DQMFileMetaData * m_metaData
output file meta data
std::string m_treeFile
if set, entry with monitoring variables is made in the run summary TTree
void setDescription(const std::string &description)
Sets the description of the module.
Definition: Module.cc:214
Type-safe access to single objects in the data store.
Definition: StoreObjPtr.h:96
Class to store variables with their name which were sent to the logging service.
void addParam(const std::string &name, T &paramVariable, const std::string &description, const T &defaultValue)
Adds a new parameter to the module.
Definition: Module.h:560
#define REG_MODULE(moduleName)
Register the given module (without 'Module' suffix) with the framework.
Definition: Module.h:650
Abstract base class for different kinds of events.