Belle II Software development
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
20using namespace std;
21using namespace Belle2;
22
23//-----------------------------------------------------------------
24// Register the Module
25//-----------------------------------------------------------------
26REG_MODULE(DQMHistAnalysisOutputMonObj);
27
28//-----------------------------------------------------------------
29// Implementation
30//-----------------------------------------------------------------
31
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
50{
51 B2DEBUG(20, "DQMHistAnalysisOutputMonObj: initialized.");
52 // create file metadata
54 m_metaData->setProcessingID(m_procID);
55}
56
57
59{
60 B2DEBUG(20, "DQMHistAnalysisOutputMonObj: beginRun called.");
61}
62
63
65{
66 B2DEBUG(20, "DQMHistAnalysisOutputMonObj: event called.");
67}
68
70{
71 B2INFO("DQMHistAnalysisOutputMonObj: endRun called");
72
74
75 B2INFO("open file");
76 TH1* hrun = findHist("DQMInfo/runno");
77 TH1* hexp = findHist("DQMInfo/expno");
78
79 int run = hrun ? std::stoi(hrun->GetTitle()) : m_run;
80 int exp = hexp ? std::stoi(hexp->GetTitle()) : m_exp;
81 TString fname;
82 if (m_filename.length()) fname = m_filename;
83 else fname = TString::Format("mon_e%04dr%06d_%s.root", exp, run, m_procID.c_str());
84
85 TH1* runtype = findHist("DQMInfo/rtype");
86 if (runtype) m_metaData->setRunType(std::string(runtype->GetTitle()));
87 else m_metaData->setRunType(m_runtype);
88 TH1* hnevt = findHist("DAQ/Nevent");
89 if (hnevt) m_metaData->setNEvents(hnevt->GetEntries());
90 else m_metaData->setNEvents(m_nevt);
91
92 TFile* f = new TFile(fname, "NEW");
93 int exist = 0;
94 if (f->IsZombie()) {
95 B2WARNING("File " << LogVar("MonitoringObject file",
96 fname) << " already exists additional data will be appended! previous metadata is kept.");
97 f = new TFile(fname, "UPDATE");
98 exist = 1;
99 }
100
101 // set and write meta data info if first input
102 if (!exist) {
103 m_metaData->setExperimentRun(exp, run);
104 time_t ts = lastEvtMeta->getTime() / 1e9;
105 struct tm* timeinfo;
106 timeinfo = localtime(&ts);
107 char buf[50];
108 m_metaData->setRunDate(asctime_r(timeinfo, buf));
109 m_metaData->Write();
110 }
111
112 // get list of existing monitoring objects
113 const MonObjList& objts = getMonObjList();
114 // write them to the output file
115 for (const auto& obj : objts) {
116 // of object already exists rewrite it
117 if (exist) f->Delete(obj.second.GetName() + TString(";*"));
118 obj.second.Write();
119 }
120 f->Close();
121
122 if (m_treeFile.length() > 0) addTreeEntry();
123
124}
125
127{
128
129 TFile* treeFile = new TFile(m_treeFile.c_str(), "update");
130 auto* tree = (TTree*)treeFile->Get("tree");
131
132 if (tree == NULL) tree = new TTree("tree", "tree");
133
134 int run = m_metaData->getRun();
135 int expe = m_metaData->getExperiment();
136 int nevt = m_metaData->getNEvents();
137 //int rune = 0;
138 //int expee = 0;
139 char* rel = const_cast<char*>(m_metaData->getRelease().c_str());
140 char* db = const_cast<char*>(m_metaData->getDatabaseGlobalTag().c_str());
141 char* date = const_cast<char*>(m_metaData->getRunDate().c_str());
142 char* rtype = const_cast<char*>(m_metaData->getRunType().c_str());
143 char* procID = const_cast<char*>(m_metaData->getProcessingID().c_str());
144
145 auto b_run = tree->GetBranch("run");
146 auto b_exp = tree->GetBranch("exp");
147 auto b_release = tree->GetBranch("release");
148 auto b_gt = tree->GetBranch("gt");
149 auto b_datetime = tree->GetBranch("datetime");
150 auto b_rtype = tree->GetBranch("rtype");
151 auto b_procID = tree->GetBranch("procID");
152 auto b_nevt = tree->GetBranch("nevt");
153
154 // this still needs to be sorted out
155 /*if(b_run){
156 b_run->SetAddress(&rune);
157 b_exp->SetAddress(&expee);
158 for(int ie = 0; ie<b_run->GetEntries(); ie++){
159 b_run->GetEntry(ir);
160 b_exp->GetEntry(ir);
161 if(rune == run && expee = expe){
162
163 }
164 }
165 }*/
166
167
168 if (!b_run) tree->Branch("run", &run, "run/I");
169 else b_run->SetAddress(&run);
170 if (!b_exp) tree->Branch("exp", &expe, "exp/I");
171 else b_exp->SetAddress(&expe);
172 if (!b_nevt) tree->Branch("nevt", &nevt, "nevt/I");
173 else b_nevt->SetAddress(&nevt);
174 if (!b_release) tree->Branch("release", rel, "release/C");
175 else b_release->SetAddress(rel);
176 if (!b_gt) tree->Branch("gt", db, "gt/C");
177 else b_gt->SetAddress(db);
178 if (!b_datetime) tree->Branch("datetime", date, "datetime/C");
179 else b_datetime->SetAddress(date);
180 if (!b_rtype) tree->Branch("rtype", rtype, "rtype/C");
181 else b_rtype->SetAddress(rtype);
182 if (!b_procID) tree->Branch("procID", procID, "procID/C");
183 else b_procID->SetAddress(procID);
184
185
186 auto& objts = getMonObjList();
187 // write them to the output file
188 for (auto& obj : objts) {
189 auto& vars = const_cast<std::map<std::string, float>&>(obj.second.getVariables());
190 auto& upErr = const_cast<std::map<std::string, float>&>(obj.second.getUpError());
191 auto& lowErr = const_cast<std::map<std::string, float>&>(obj.second.getLowError());
192 auto& strVars = obj.second.getStringVariables();
193
194 for (auto& var : vars) {
195 std::string brname = obj.first + "_" + var.first;
196 auto branch = tree->GetBranch((brname).c_str());
197 if (!branch) {
198 branch = tree->Branch((brname).c_str(), &(var.second));
199 fillBranch(branch);
200 } else branch->SetAddress(&(var.second));
201
202 auto vvE1 = upErr.find(var.first);
203 auto vvE2 = lowErr.find(var.first);
204
205 if (vvE1 != upErr.end() && vvE2 == lowErr.end()) {
206 auto errBranch = tree->GetBranch((brname).c_str() + TString("_err"));
207 if (!errBranch) {
208 errBranch = tree->Branch((brname).c_str() + TString("_err"), &(vvE1->second));
209 fillBranch(errBranch);
210 } else errBranch->SetAddress(&(vvE1->second));
211 }
212
213 if (vvE1 != upErr.end() && vvE2 != lowErr.end()) {
214 auto errBranch1 = tree->GetBranch((brname).c_str() + TString("_upErr"));
215 if (!errBranch1) {
216 errBranch1 = tree->Branch((brname).c_str() + TString("_upErr"), &(vvE1->second));
217 fillBranch(errBranch1);
218 } else errBranch1->SetAddress(&(vvE1->second));
219
220 auto errBranch2 = tree->GetBranch((brname).c_str() + TString("_dwErr"));
221 if (!errBranch2) {
222 errBranch2 = tree->Branch((brname).c_str() + TString("_dwErr"), &(vvE2->second));
223 fillBranch(errBranch2);
224 } else errBranch2->SetAddress(&(vvE2->second));
225
226 }
227 }
228
229 for (auto& var : strVars) {
230 std::string brname = obj.first + "_" + var.first;
231 char* cc = const_cast<char*>((var.second).c_str());
232 auto branch = tree->GetBranch((brname).c_str());
233 if (!branch) {
234 std::string ty = brname + "/C";
235 branch = tree->Branch((brname).c_str(), cc, ty.c_str());
236 fillBranch(branch);
237 } else branch->SetAddress(cc);
238 }
239 }
240
241 tree->Fill();
242 tree->Write(0, TObject::kWriteDelete, 0);
243 treeFile->Close();
244
245}
246
248{
249 TTree* tree = (TTree*)branch->GetTree();
250 int nentr = tree->GetEntries();
251 for (int i = 0; i < nentr; i++) {
252 tree->GetEntry(i);
253 branch->Fill();
254 }
255}
256
257
258
260{
261 B2INFO("DQMHistAnalysisOutputMonObj: terminate called");
262// Attention, we can not do that in Terminate, as then the memFile is already closed by previous task!
263
264}
265
Metadata information about a DQM file.
std::map< std::string, MonitoringObject > MonObjList
The type of list of MonitoringObjects.
static TH1 * findHist(const std::string &histname, bool onlyIfUpdated=false)
Get histogram from list (no other search).
DQMHistAnalysisModule()
Constructor / Destructor.
static 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:559
#define REG_MODULE(moduleName)
Register the given module (without 'Module' suffix) with the framework.
Definition Module.h:649
Abstract base class for different kinds of events.
STL namespace.