Belle II Software  release-06-01-15
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 
34 {
35  //Parameter definition
36  addParam("Filename", m_filename, "Output root filename (if not set mon_e{exp}r{run}.root is used", std::string(""));
37  addParam("TreeFile", m_treeFile, "If set, entry to run summary TTree from TreeFile is made", std::string(""));
38  addParam("ProcID", m_procID, "Processing id (online,proc10, etc.)", std::string("online"));
39  addParam("run", m_run, "Run number", 0);
40  addParam("exp", m_exp, "Experiment number", 0);
41  addParam("nevt", m_nevt, "Number of events", 0);
42  addParam("runtype", m_runtype, "Run type", std::string(""));
43 
44  B2DEBUG(20, "DQMHistAnalysisOutputMonObj: Constructor done.");
45 }
46 
47 
48 DQMHistAnalysisOutputMonObjModule::~DQMHistAnalysisOutputMonObjModule() { }
49 
50 void DQMHistAnalysisOutputMonObjModule::initialize()
51 {
52  B2DEBUG(20, "DQMHistAnalysisOutputMonObj: initialized.");
53  // create file metadata
54  m_metaData = new DQMFileMetaData();
55  m_metaData->setProcessingID(m_procID);
56 }
57 
58 
59 void DQMHistAnalysisOutputMonObjModule::beginRun()
60 {
61  B2DEBUG(20, "DQMHistAnalysisOutputMonObj: beginRun called.");
62 }
63 
64 
65 void DQMHistAnalysisOutputMonObjModule::event()
66 {
67  B2DEBUG(20, "DQMHistAnalysisOutputMonObj: event called.");
68 }
69 
70 void DQMHistAnalysisOutputMonObjModule::endRun()
71 {
72  B2INFO("DQMHistAnalysisOutputMonObj: endRun called");
73 
74  StoreObjPtr<EventMetaData> lastEvtMeta;
75 
76  B2INFO("open file");
77  TH1* hrun = findHist("DQMInfo/runno");
78  TH1* hexp = findHist("DQMInfo/expno");
79 
80  int run = hrun ? std::stoi(hrun->GetTitle()) : m_run;
81  int exp = hexp ? std::stoi(hexp->GetTitle()) : m_exp;
82  TString fname;
83  if (m_filename.length()) fname = m_filename;
84  else fname = TString::Format("mon_e%04dr%06d_%s.root", exp, run, m_procID.c_str());
85 
86  TH1* runtype = findHist("DQMInfo/rtype");
87  if (runtype) m_metaData->setRunType(std::string(runtype->GetTitle()));
88  else m_metaData->setRunType(m_runtype);
89  TH1* hnevt = findHist("DAQ/Nevent");
90  if (hnevt) m_metaData->setNEvents(hnevt->GetEntries());
91  else m_metaData->setNEvents(m_nevt);
92 
93  TFile f(fname, "NEW");
94 
95  if (f.IsZombie()) {
96  B2WARNING("File " << LogVar("MonitoringObject file",
97  fname) << " already exists and it will not be rewritten. If desired please delete file and re-run.");
98  return;
99  }
100 
101  // set meta data info
102  // m_metaData->setNEvents(lastEvtMeta->getEvent());
103  m_metaData->setExperimentRun(exp, run);
104  time_t ts = lastEvtMeta->getTime() / 1e9;
105  struct tm* timeinfo;
106  timeinfo = localtime(&ts);
107  // cppcheck-suppress asctimeCalled
108  m_metaData->setRunDate(asctime(timeinfo));
109 
110  m_metaData->Write();
111  // get list of existing monitoring objects
112  const MonObjList& objts = getMonObjList();
113  // write them to the output file
114  for (const auto& obj : objts)(obj.second)->Write();
115 
116  f.Close();
117 
118  if (m_treeFile.length() > 0) addTreeEntry();
119 
120 }
121 
122 void DQMHistAnalysisOutputMonObjModule::addTreeEntry()
123 {
124 
125  TFile* treeFile = new TFile(m_treeFile.c_str(), "update");
126  auto* tree = (TTree*)treeFile->Get("tree");
127 
128  if (tree == NULL) tree = new TTree("tree", "tree");
129 
130  int run = m_metaData->getRun();
131  int expe = m_metaData->getExperiment();
132  int nevt = m_metaData->getNEvents();
133  //int rune = 0;
134  //int expee = 0;
135  char* rel = const_cast<char*>(m_metaData->getRelease().c_str());
136  char* db = const_cast<char*>(m_metaData->getDatabaseGlobalTag().c_str());
137  char* datee = const_cast<char*>(m_metaData->getRunDate().c_str());
138  char* rtype = const_cast<char*>(m_metaData->getRunType().c_str());
139  char* procID = const_cast<char*>(m_metaData->getProcessingID().c_str());
140 
141  auto b_run = tree->GetBranch("run");
142  auto b_exp = tree->GetBranch("exp");
143  auto b_release = tree->GetBranch("release");
144  auto b_gt = tree->GetBranch("gt");
145  auto b_datetime = tree->GetBranch("datetime");
146  auto b_rtype = tree->GetBranch("rtype");
147  auto b_procID = tree->GetBranch("procID");
148  auto b_nevt = tree->GetBranch("nevt");
149 
150  // this still needs to be sorted out
151  /*if(b_run){
152  b_run->SetAddress(&rune);
153  b_exp->SetAddress(&expee);
154  for(int ie = 0; ie<b_run->GetEntries(); ie++){
155  b_run->GetEntry(ir);
156  b_exp->GetEntry(ir);
157  if(rune == run && expee = expe){
158 
159  }
160  }
161  }*/
162 
163 
164  if (!b_run) tree->Branch("run", &run, "run/I");
165  else b_run->SetAddress(&run);
166  if (!b_exp) tree->Branch("exp", &expe, "exp/I");
167  else b_exp->SetAddress(&expe);
168  if (!b_nevt) tree->Branch("nevt", &nevt, "nevt/I");
169  else b_nevt->SetAddress(&nevt);
170  if (!b_release) tree->Branch("release", rel, "release/C");
171  else b_release->SetAddress(rel);
172  if (!b_gt) tree->Branch("gt", db, "gt/C");
173  else b_gt->SetAddress(db);
174  if (!b_datetime) tree->Branch("datetime", datee, "datetime/C");
175  else b_datetime->SetAddress(datee);
176  if (!b_rtype) tree->Branch("rtype", rtype, "rtype/C");
177  else b_rtype->SetAddress(rtype);
178  if (!b_procID) tree->Branch("procID", procID, "procID/C");
179  else b_procID->SetAddress(procID);
180 
181 
182  const MonObjList& objts = getMonObjList();
183  // write them to the output file
184  for (const auto& obj : objts) {
185  std::map<std::string, float>& vars = const_cast<std::map<std::string, float>&>((obj.second)->getVariables());
186  std::map<std::string, float>& upErr = const_cast<std::map<std::string, float>&>((obj.second)->getUpError());
187  std::map<std::string, float>& lowErr = const_cast<std::map<std::string, float>&>((obj.second)->getLowError());
188 
189  const std::vector<std::pair<std::string, std::string>>& strVars = (obj.second)->getStringVariables();
190 
191  for (auto& var : vars) {
192  std::string brname = obj.first + "_" + var.first;
193  auto branch = tree->GetBranch((brname).c_str());
194  if (!branch) {
195  branch = tree->Branch((brname).c_str(), &(var.second));
196  fillBranch(branch);
197  } else branch->SetAddress(&(var.second));
198 
199  auto vvE1 = upErr.find(var.first);
200  auto vvE2 = lowErr.find(var.first);
201 
202  if (vvE1 != upErr.end() && vvE2 == lowErr.end()) {
203  auto errBranch = tree->GetBranch((brname).c_str() + TString("_err"));
204  if (!errBranch) {
205  errBranch = tree->Branch((brname).c_str() + TString("_err"), &(vvE1->second));
206  fillBranch(errBranch);
207  } else errBranch->SetAddress(&(vvE1->second));
208  }
209 
210  if (vvE1 != upErr.end() && vvE2 != lowErr.end()) {
211  auto errBranch1 = tree->GetBranch((brname).c_str() + TString("_upErr"));
212  if (!errBranch1) {
213  errBranch1 = tree->Branch((brname).c_str() + TString("_upErr"), &(vvE1->second));
214  fillBranch(errBranch1);
215  } else errBranch1->SetAddress(&(vvE1->second));
216 
217  auto errBranch2 = tree->GetBranch((brname).c_str() + TString("_dwErr"));
218  if (!errBranch2) {
219  errBranch2 = tree->Branch((brname).c_str() + TString("_dwErr"), &(vvE2->second));
220  fillBranch(errBranch2);
221  } else errBranch2->SetAddress(&(vvE2->second));
222 
223  }
224  }
225 
226  for (auto& var : strVars) {
227  std::string brname = obj.first + "_" + var.first;
228  char* cc = const_cast<char*>((var.second).c_str());
229  auto branch = tree->GetBranch((brname).c_str());
230  if (!branch) {
231  std::string ty = brname + "/C";
232  branch = tree->Branch((brname).c_str(), cc, ty.c_str());
233  fillBranch(branch);
234  } else branch->SetAddress(cc);
235  }
236  }
237 
238  tree->Fill();
239  tree->Write(0, TObject::kWriteDelete, 0);
240  treeFile->Close();
241 
242 }
243 
244 void DQMHistAnalysisOutputMonObjModule::fillBranch(TBranch* branch)
245 {
246  TTree* tree = (TTree*)branch->GetTree();
247  int nentr = tree->GetEntries();
248  for (int i = 0; i < nentr; i++) {
249  tree->GetEntry(i);
250  branch->Fill();
251  }
252 }
253 
254 
255 
256 void DQMHistAnalysisOutputMonObjModule::terminate()
257 {
258  B2INFO("DQMHistAnalysisOutputMonObj: terminate called");
259 // Attention, we can not do that in Terminate, as then the memFile is already closed by previous task!
260 
261 }
262 
Metadata information about a DQM file.
The base class for the histogram analysis module.
std::map< std::string, MonitoringObject * > MonObjList
The type of list of MonitoringObjects.
Class definition for the module to store MonitoringObject to output root file.
Type-safe access to single objects in the data store.
Definition: StoreObjPtr.h:95
Class to store variables with their name which were sent to the logging service.
#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.