ROOTPWA
convertTFitResultTree.C
Go to the documentation of this file.
1 //
2 // converts uDst tree to other formats
3 //
4 
5 
6 #include <string>
7 #include <vector>
8 #include <libgen.h> // dirname()
9 #ifdef basename
10 #undef basename
11 #endif
12 #include <string.h> // basename()
13 
14 #include "TFile.h"
15 #include "TChain.h"
16 #include "TTree.h"
17 #include "TObject.h"
18 
19 #include "reportingUtils.hpp"
20 #include "fileUtils.hpp"
21 #include "TFitResult.h"
22 #include "fitResult.h"
23 
24 
25 using namespace std;
26 using namespace rpwa;
27 
28 
29 #ifdef USE_TFITRESULT
30 
31 
32 void
33 convertTFitResultTree(const string& inFileNamePattern = "./*.root",
34  const string& outDirName = "", // if empty, files are modified in place
35  const unsigned long int maxNmbEvents = -1,
36  const string& inTreeName = "pwa",
37  const string& outTreeName = "pwa",
38  const string& inBranchName = "fitResult",
39  const string& outBranchName = "fitResult_v2")
40 {
41 
42  // modify files in place, if outDirName is not specified
43  string _outDirName = outDirName;
44  if (outDirName == "") {
45  char* s = strdup(inFileNamePattern.c_str()); // dummy required by dirname()
46  _outDirName = dirname(s);
47  }
48 
49  printInfo << "converting TFitResult trees in '" << inFileNamePattern << "' "
50  << "into fitResult trees." << endl;
51  cout << " writing to '" << _outDirName << "'" << endl;
52 
53  // get file list
54  const vector<string> inFileNames = filesMatchingGlobPattern(inFileNamePattern);
55  const unsigned int nmbInFiles = inFileNames.size();
56  cout << " found " << nmbInFiles << " files." << endl;
57  if (inFileNames.size() == 0) {
58  printErr << "no files do match pattern '" << inFileNamePattern << "'. exiting." << endl;
59  return;
60  }
61 
62  // process file list
63  unsigned long int countEntriesWritten = 0;
64  for (unsigned int fileIndex = 0; fileIndex < nmbInFiles; ++fileIndex) {
65  const string outFileName = _outDirName + "/" + basename(inFileNames[fileIndex].c_str());
66  const bool updateMode = (outFileName == inFileNames[fileIndex]) ? true : false;
67 
68  // open input file
69  cout << " reading from input file '" << inFileNames[fileIndex] << "' "
70  << "[" << fileIndex << "/" << nmbInFiles << "]" << endl;
71  TFile* inFile = TFile::Open(inFileNames[fileIndex].c_str(), (updateMode) ? "UPDATE" : "READ");
72  if (!inFile || inFile->IsZombie()) {
73  printWarn << "cannot open file '" << inFileNames[fileIndex] << "'. skipping." << endl;
74  continue;
75  }
76 
77  // create output file, if necessary
78  cout << " writing to output file '" << outFileName << "'" << endl;
79  TFile* outFile = 0;
80  if (updateMode)
81  outFile = inFile;
82  else
83  outFile = TFile::Open(outFileName.c_str(), "RECREATE");
84  if (!outFile || outFile->IsZombie()) {
85  printWarn << "cannot open file '" << outFileName << "'. skipping." << endl;
86  continue;
87  }
88 
89  // get input tree
90  TTree* inTree = 0;
91  inFile->GetObject(inTreeName.c_str(), inTree);
92  if (!inTree) {
93  printWarn << "cannot find tree '" << inTreeName << "'. skipping." << endl;
94  continue;
95  }
96  TFitResult* inResult = 0;
97  TBranch* inBranch = 0;
98  inTree->SetBranchAddress(inBranchName.c_str(), &inResult, &inBranch);
99  // renaming old branch does not work for some reason; same name leafs are getting mixed up
100  // if (updateMode && (outBranchName == inBranchName))
101  // inBranch->SetName((inBranchName + "_old").c_str());
102 
103  // create output tree
104  outFile->cd();
105 
106  TTree* outTree = 0;
107  if (updateMode)
108  outTree = inTree;
109  else
110  //outTree = new TTree(outTreeName.c_str(), "converted from TFitResult");
111  outTree = new TTree(outTreeName.c_str(), outTreeName.c_str());
112  fitResult* outResult = 0;
113  string _outBranchName = outBranchName;
114  if (updateMode && (outBranchName == inBranchName))
115  _outBranchName += "_v2";
116  if (outTree->FindBranch(_outBranchName.c_str())) {
117  printWarn << "branch '" << _outBranchName << "' already exists in output file. "
118  << "skipping." << endl;
119  continue;
120  }
121  TBranch* outBranch = outTree->Branch(_outBranchName.c_str(), &outResult);
122 
123  // loop over events and fill output tree
124  const unsigned long int nmbEvents = inTree->GetEntriesFast();
125  for (unsigned long int eventIndex = 0; eventIndex < nmbEvents; ++eventIndex) {
126  inTree->GetEntry(eventIndex);
127  if (!inResult) {
128  printWarn << "zero pointer for TFitResult at index " << eventIndex << ". skipping." << endl;
129  continue;
130  }
131  // copy data
132  outResult = new fitResult(*inResult);
133  if (updateMode && (outTreeName == inTreeName))
134  outBranch->Fill();
135  else
136  outTree->Fill();
137  delete outResult;
138  outResult = 0;
139  ++countEntriesWritten;
140  if (countEntriesWritten >= maxNmbEvents)
141  break;
142  }
143 
144  outTree->Write("", TObject::kOverwrite);
145  outFile->Close();
146  delete outFile;
147  if (inFile != outFile) {
148  inFile->Close();
149  delete inFile;
150  }
151 
152  if (countEntriesWritten >= maxNmbEvents)
153  break;
154  }
155  printInfo << "wrote " << countEntriesWritten << " entries to file." << endl;
156 
157 }
158 
159 
160 #endif // USE_TFITRESULT