Diana Software
MRootNtpDumper.cc
Go to the documentation of this file.
1 #include "MRootNtpDumper.hh"
2 #include "QEvent.hh"
3 #include "QAliases.hh"
4 #include "QObjectInspector.hh"
5 #include "QEventInspector.hh"
6 #include <TFile.h>
7 #include <TTree.h>
8 #include <sstream>
9 
10 using namespace Diana;
11 
13 
14 MRootNtpDumper::MRootNtpDumper() : QFileWriter(".root")
15 {
16  // called once in a sequence
17 }
18 
20 {
21  // called once in a sequence
22 }
23 
24 void MRootNtpDumper::Require(const Diana::QEventInspector& evi)
25 {
26  Debug("Requiring QObjects");
27  QAliases aliases = evi.GetAliases();
28  std::string AliasFileName = GetString("AliasFileName","cfg/aliases.txt");
29  if(AliasFileName != "") {
30  Debug("Adding aliases from %s",AliasFileName.c_str());
31  QError err = aliases.FillFromFile(AliasFileName);
32  if(err != QERR_SUCCESS) {
33  std::stringstream str;
34  str<<err;
35  Error("%s",str.str().c_str());
36  }
37  }
38  std::string CustomAliasFileName = GetString("CustomAliasFileName","",false);
39  if(CustomAliasFileName != "") {
40  Debug("Adding aliases from %s",CustomAliasFileName.c_str());
41  QError err = aliases.FillFromFile(CustomAliasFileName);
42  if(err != QERR_SUCCESS) {
43  std::stringstream str;
44  str<<err;
45  Error("%s",str.str().c_str());
46  }
47  }
48 
49  fAliasMap = aliases.Get() ;
50  if(fAliasMap.empty()) Warn("Alias list is empty");
51  fAddPackedNeighbours = GetBool("AddPackedNeighbours",false,false);
52  std::string neighboursPrefix;
53  if(fAddPackedNeighbours) {
54  neighboursPrefix = GetString("NeighboursPrefix","N",false);
55  }
56 
57  std::map<std::string,QAliases::AliasInfo>::iterator aliasIter = fAliasMap.begin();
58  for(;aliasIter != fAliasMap.end();aliasIter++) {
59  std::string alias = aliasIter->first;
60  //Debug("Alias %s:",alias.c_str());
61  if(GetBool("Alias:"+alias,false,false)) {
62  std::string path = aliasIter->second.fPath;
63  QEventLabel label = aliasIter->second.fLabel;
64  QObject** peventData = evi.Get(label.owner.c_str(),label.name.c_str());
65  if(!peventData) continue;
66  QObject* eventData = (*peventData);
67  if(!eventData) continue;
68 
69  QObjectInspector insp;
70  QObjectInspector::MemberInfo memberInfo = insp.FindBaseType(eventData,path.c_str());
71  std::string type = memberInfo.fBranchType;
72  void* addr = memberInfo.fAddress;
73  if(type == "Unknown"){
74  Error("Cannot handle type %s (variable %s)",type.c_str(),alias.c_str());
75  } else {
76  std::string brvariable = alias + "/" + type;
77  AliasBranch branch;
78  branch.name = alias;
79  branch.address = addr;
80  branch.type = brvariable.c_str();
81  eventData->SetIsRequired();
82  fAliasBranches.push_back(branch);
83  if(fAddPackedNeighbours) {
84  int nneigh = GetInt("MaximumNumberOfNeighbours",2);
85  if(nneigh < 1) Panic("MaximumNumberOfNeighbours = %d not allowed",nneigh);
86  for(int n = 0; n < nneigh; n++) {
87  std::stringstream neighowner;
88  neighowner<<neighboursPrefix<<n+1<<"_"<<label.owner;
89  QEventLabel nLabel;
90  nLabel.owner = neighowner.str();
91  nLabel.name = label.name;
92  peventData = evi.Get(nLabel.owner.c_str(),nLabel.name.c_str());
93  if(!peventData) continue;
94  QObject* eventData = (*peventData);
95  if(!eventData) continue;
96  memberInfo = insp.FindBaseType(eventData,path.c_str());
97  branch.address = memberInfo.fAddress;
98  std::stringstream nbranchAlias;
99  nbranchAlias<<neighboursPrefix<<n+1<<"_"<<alias;
100  branch.name = nbranchAlias.str();
101  brvariable = nbranchAlias.str() + "/" + type;
102  branch.type = brvariable.c_str();
103  eventData->SetIsRequired();
104  fAliasBranches.push_back(branch);
105  }
106  }
107  }
108  }
109  }
110 
111  std::vector<QEventLabel> evDataLabels = evi.GetWriteLabels();
112  std::vector<QEventLabel>::const_iterator evLabelIter = evDataLabels.begin();
113  while(evLabelIter != evDataLabels.end()) {
114  QEventLabel label = *evLabelIter;
115  QObject** peventData = evi.Get(label.owner.c_str(),label.name.c_str());
116  QObject* eventData = (*peventData);
117 
118  std::string labelstr = label.GetStringLabel();
119  bool process = false;
120  if(GetBool(std::string("Member:") + labelstr,false,false)) {
121  process = true;
122  } else if(fAddPackedNeighbours && !neighboursPrefix.empty()
123  && labelstr[0] == neighboursPrefix[0]) {
124  int pos = labelstr.find_first_of("_");
125  QVdt num(labelstr.substr(1,pos-1));
126  std::string rest = labelstr.substr(pos+1,std::string::npos);
127  if(num.GetType() == QVdt::Int_QVdt && GetBool(std::string("Member:") + rest,false,false)) process = true;
128 
129  }
130  if(process){
131  std::string brnamestr = labelstr + ".";
132  Branch branch;
133  branch.name = brnamestr;
134  branch.type = eventData->GetName();
135  branch.address = peventData;
136  eventData->SetIsRequired();
137  fBranches.push_back(branch);
138 
139  std::map<std::string, std::string> branchAliasMap = aliases.Find(label);
140  std::map<std::string, std::string>::const_iterator iter = branchAliasMap.begin();
141  while(iter != branchAliasMap.end()) {
142  std::string path;
143  if(iter->second =="") {
144  path = labelstr;
145  } else {
146  path = labelstr+std::string(".")+iter->second;
147  }
148  fBranchAliasMap[iter->first] = path;
149  iter++;
150  }
151 
152  }
153 
154  evLabelIter++;
155  }
156 
157 
158 }
159 
160 void MRootNtpDumper::Open(const std::string& filename, const QEventInspector& evi)
161 {
162  // Get parameters from cfg
163  // and open file filename
164  fFileName = filename;
165 
166  fRootOutput = new TFile(filename.c_str(),"RECREATE");
167  std::string treeDescription = GetString("Description", "Diana NTP",false);
168  fTree = new TTree(GetString("TreeName","qtree",false).c_str(),treeDescription.c_str());
169 
170  std::string saveMesg = "";
171  // Aliases
172  for(size_t i = 0; i < fAliasBranches.size(); i++) {
173  AliasBranch branch = fAliasBranches[i];
174  TBranch* br = fTree->Branch(branch.name.c_str(),branch.address,branch.type.c_str());
175  if(br) {
176  Debug("Adding alias branch %s of type %s",branch.name.c_str(),branch.type.c_str());
177  saveMesg += branch.name + " ";
178  }
179  else Error("Cannot handle variable %s",branch.name.c_str());
180 
181  }
182  bool saveSomething = false;
183  if(!saveMesg.empty()) {
184  Info("Saving aliases: %s",saveMesg.c_str());
185  saveSomething = true;
186  }
187 
188  // branches
189  saveMesg = "";
190  for(size_t i = 0; i < fBranches.size(); i++) {
191  Branch branch = fBranches[i];
192  Debug("Adding branch %s of type %s",branch.name.c_str(),branch.type.c_str());
193  saveMesg += branch.name + " ";
194  fTree->Branch(branch.name.c_str(),branch.type.c_str(),branch.address);
195  }
196 
197  if(!saveMesg.empty()) {
198  Info("Saving full members: %s",saveMesg.c_str());
199  saveSomething = true;
200  }
201 
202  if(!saveSomething) {
203  Error("Nothing is going to be written");
204  return;
205  }
206 
207  std::map<std::string,std::string>::const_iterator branchAliasIter = fBranchAliasMap.begin();
208 
209  while(branchAliasIter != fBranchAliasMap.end()) {
210  const char* al = branchAliasIter->first.c_str();
211  const char* ap = branchAliasIter->second.c_str();
212  Debug("Adding alias %s for %s",al,ap);
213  fTree->SetAlias(al,ap);
214  branchAliasIter++;
215  }
216 
217 
218 }
219 
220 
222 {
223  fTree->Fill();
224 
225  return;
226 }
227 
229 {
230  // close file
231  if(fRootOutput) {
232  fRootOutput->Write();
233  fRootOutput->Close();
234  delete fRootOutput;
235  fTree = NULL;
236  fRootOutput = NULL;
237  }
238 }
ap
Definition: CheckOFShape.C:47
err
Definition: CheckOF.C:114
#define REGISTER_MODULE(clazz)
Definition: QDriver.hh:133
@ QERR_SUCCESS
Definition: QError.hh:27
Diana::QObject ** address
ROOT ntuple dumper.
void Require(const Diana::QEventInspector &evi)
void Open(const std::string &filename, const Diana::QEventInspector &evi)
Open file.
void Dump(const Diana::QEventInspector &evi)
Write event to file.
~MRootNtpDumper()
destructor
QError FillFromFile(const std::string &filename)
Definition: QAliases.cc:63
std::map< std::string, std::string > Find(const QEventLabel &label) const
Definition: QAliases.cc:25
std::map< std::string, AliasInfo > Get() const
Definition: QAliases.hh:24
error class with error type and description
Definition: QError.hh:115
Visitor class to inspect the QEvent content.
label for QObject in the QEvent
Definition: QEventLabel.hh:23
std::string GetStringLabel() const
get string in the format "owner@name"
Definition: QEventLabel.cc:48
std::string owner
owner of the QObject
Definition: QEventLabel.hh:60
std::string name
name of the QObject
Definition: QEventLabel.hh:62
MemberInfo FindBaseType(QObject *obj, const char *member)
Variable Data Type.
Definition: QVdt.hh:26
@ Int_QVdt
Definition: QVdt.hh:31
QVdt_type GetType() const
Definition: QVdt.hh:96
the Diana namespace is needed because sometimes we use Qt libraries, that use same class names of our...