Belle II Software  release-08-01-10
RootTracer.cc
1 /**************************************************************************
2  * basf2 (Belle II Analysis Software Framework) *
3  * Author: The Belle II Collaboration *
4  * *
5  * Forked from https://github.com/iLCSoft/MarlinKinfit *
6  * *
7  * Further information about the fit engine and the user interface *
8  * provided in MarlinKinfit can be found at *
9  * https://www.desy.de/~blist/kinfit/doc/html/ *
10  * and in the LCNotes LC-TOOL-2009-001 and LC-TOOL-2009-004 available *
11  * from http://www-flc.desy.de/lcnotes/ *
12  * *
13  * See git log for contributors and copyright holders. *
14  * This file is licensed under LGPL-3.0, see LICENSE.md. *
15  **************************************************************************/
16 
17 #ifdef MARLIN_USE_ROOT
18 
19 #include "analysis/OrcaKinFit/RootTracer.h"
20 #include "analysis/OrcaKinFit/BaseFitter.h"
21 #include "analysis/OrcaKinFit/BaseFitObject.h"
22 #include "analysis/OrcaKinFit/BaseHardConstraint.h"
23 #include "analysis/OrcaKinFit/BaseSoftConstraint.h"
24 #include <framework/logging/Logger.h>
25 #undef NDEBUG
26 #include <cassert>
27 #include <cstring>
28 #include <iostream>
29 using namespace std;
30 
31 namespace Belle2 {
37  namespace OrcaKinFit {
38 
39  RootTracer::RootTracer(const char* filename, const char* option)
40  : file(0), tree(0), eventtree(0),
41  istep(0), isubstep(0),
42  eventnumber(0), stepnumber(0), substepnumber(0), chi2(0)
43  {
44  file = new TFile(filename, option);
45  tree = new TTree("trace", "Fit Tracing");
46  CreateBranches();
47  SetBranchAddresses();
48  eventnumber = 0;
49  }
50 
51  RootTracer::~RootTracer()
52  {
53  file->Write();
54  file->Close();
55  }
56 
57 
58  void RootTracer::initialize(BaseFitter& fitter)
59  {
60  B2INFO("=============== Starting fit ======================\n");
61 
62  printFitObjects(fitter);
63  printConstraints(fitter);
64 
65  ++eventnumber;
66  istep = 1;
67  isubstep = 0;
68 
69 
70  TString name("event");
71  TString title("Event ");
72  name += eventnumber;
73  title += eventnumber;
74  eventtree = new TTree(name, title);
75  CreateEventBranches(fitter);
76 
77 
78  BaseTracer::initialize(fitter);
79  }
80 
81  void RootTracer::step(BaseFitter& fitter)
82  {
83  isubstep = 1;
84  B2INFO("--------------- Step " << istep << " --------------------\n");
85 
86  printFitObjects(fitter);
87  printConstraints(fitter);
88 
89  stepnumber = istep;
90  substepnumber = isubstep;
91  chi2 = fitter.getChi2();
92  B2INFO("chi2=" << chi2);
93  FillParameterValues(fitter);
94 
95  tree->Fill();
96  eventtree->Fill();
97 
98  ++istep;
99  BaseTracer::step(fitter);
100  }
101 
102  void RootTracer::substep(BaseFitter& fitter, int flag)
103  {
104  B2INFO("---- Substep " << istep << "." << isubstep << " ----\n");
105 
106  printFitObjects(fitter);
107  printConstraints(fitter);
108 
109  ++isubstep;
110  BaseTracer::substep(fitter, flag);
111  }
112 
113  void RootTracer::finish(BaseFitter& fitter)
114  {
115 
116  B2INFO("=============== Final result ======================\n");
117  printFitObjects(fitter);
118  printConstraints(fitter);
119 
120  B2INFO("=============== Finished fit ======================\n");
121 
122 
123  BaseTracer::finish(fitter);
124  }
125 
126  void RootTracer::printFitObjects(BaseFitter& fitter)
127  {
128  FitObjectContainer* fitobjects = fitter.getFitObjects();
129  if (!fitobjects) return;
130  B2INFO("Fit objects:\n");
131  for (FitObjectIterator i = fitobjects->begin(); i != fitobjects->end(); ++i) {
132  BaseFitObject* fo = *i;
133  assert(fo);
134  B2INFO(fo->getName() << ": " << *fo << ", chi2=" << fo->getChi2());
135  }
136  }
137  void RootTracer::printConstraints(BaseFitter& fitter)
138  {
139  ConstraintContainer* constraints = fitter.getConstraints();
140  if (!constraints) return;
141  B2INFO("(Hard) Constraints:\n");
142  for (ConstraintIterator i = constraints->begin(); i != constraints->end(); ++i) {
143  BaseHardConstraint* c = *i;
144  assert(c);
145  B2INFO(i - constraints->begin() << " " << c->getName() << ": " << c->getValue() << "+-" << c->getError());
146  }
147  SoftConstraintContainer* softconstraints = fitter.getSoftConstraints();
148  if (!softconstraints) return;
149  B2INFO("Soft Constraints:\n");
150  for (SoftConstraintIterator i = softconstraints->begin(); i != softconstraints->end(); ++i) {
151  BaseSoftConstraint* c = *i;
152  assert(c);
153  B2INFO(i - softconstraints->begin() << " " << c->getName() << ": " << c->getValue() << "+-" << c->getError());
154  }
155  }
156 
157  void RootTracer::SetBranchAddresses()
158  {
159  tree->SetBranchAddress("event", &eventnumber);
160  tree->SetBranchAddress("step", &stepnumber);
161  tree->SetBranchAddress("substep", &substepnumber);
162 
163  }
164 
165  void RootTracer::CreateBranches()
166  {
167 // create branch with addresses for own datamembers
168  tree->Branch("event", &eventnumber, "event/I");
169  tree->Branch("step", &stepnumber, "step/I");
170  tree->Branch("substep", &substepnumber, "substep/I");
171  }
172  void RootTracer::CreateEventBranches(BaseFitter& fitter)
173  {
174 // create branch with addresses for own datamembers
175  eventtree->Branch("step", &stepnumber, "step/I");
176  eventtree->SetBranchAddress("step", &stepnumber);
177  eventtree->Branch("substep", &substepnumber, "substep/I");
178  eventtree->SetBranchAddress("substep", &substepnumber);
179  eventtree->Branch("chi2", &chi2, "chi2/D");
180  eventtree->SetBranchAddress("chi2", &chi2);
181  FitObjectContainer* fitobjects = fitter.getFitObjects();
182  if (!fitobjects) return;
183  B2INFO("RootTracer: Fit objects:\n");
184  for (FitObjectIterator i = fitobjects->begin(); i != fitobjects->end(); ++i) {
185  BaseFitObject* fo = *i;
186  assert(fo);
187  TString foname = fo->getName();
188  for (int ilocal = 0; ilocal < fo->getNPar(); ilocal++) {
189  int iglobal = fo->getGlobalParNum(ilocal);
190  if (iglobal >= 0 && iglobal < NPARMAX) {
191  TString parname = "Par";
192  parname += iglobal;
193  parname += "_";
194  parname += fo->getParamName(ilocal);
195  B2INFO("Parameter " << iglobal << " '" << parname << "'\n");
196  eventtree->Branch(parname, parvalue + iglobal, parname + "/D");
197  eventtree->SetBranchAddress(parname, parvalue + iglobal);
198 
199  }
200  }
201  }
202  B2INFO("RootTracer: (Hard) Constraints:\n");
203  ConstraintContainer* constraints = fitter.getConstraints();
204  for (ConstraintIterator i = constraints->begin(); i != constraints->end(); ++i) {
205  BaseHardConstraint* c = *i;
206  assert(c);
207  int iglobal = c->getGlobalNum();
208  if (iglobal >= 0 && iglobal < NPARMAX) {
209  TString cname = "Const";
210  cname += (i - constraints->begin());
211  cname += "_";
212  cname += c->getName();
213  eventtree->Branch(cname, parvalue + iglobal, cname + "/D");
214  eventtree->SetBranchAddress(cname, parvalue + iglobal);
215  B2INFO("Constraint " << (i - constraints->begin()) << " '" << cname);
216  }
217  }
218 // B2INFO("RootTracer: Soft Constraints:\n");
219 // SoftConstraintContainer* softconstraints = fitter.getSoftConstraints();
220 // for (SoftConstraintIterator i = softconstraints->begin(); i != softconstraints->end(); ++i) {
221 // BaseSoftConstraint *c = *i;
222 // assert (c);
223 // int iglobal = c->getGlobalNum();
224 // if (iglobal >= 0 && iglobal < NPARMAX) {
225 // TString cname = "Const";
226 // // cname += iglobal;
227 // cname += (i-softconstraints->begin());
228 // cname += "_";
229 // cname += c->getName();
230 // eventtree->Branch(cname, parvalue+iglobal, cname+"/D");
231 // eventtree->SetBranchAddress(cname,parvalue+iglobal);
232 // // B2INFO("Constraint " << iglobal << " '" << cname);
233 // B2INFO("Constraint " << (i-softconstraints->begin()) << " '" << cname);
234 // }
235 // }
236  }
237 
238  void RootTracer::FillParameterValues(BaseFitter& fitter)
239  {
240  FitObjectContainer* fitobjects = fitter.getFitObjects();
241  if (!fitobjects) return;
242  for (FitObjectIterator i = fitobjects->begin(); i != fitobjects->end(); ++i) {
243  BaseFitObject* fo = *i;
244  assert(fo);
245  B2INFO("fo " << fo->getName());
246  for (int ilocal = 0; ilocal < fo->getNPar(); ilocal++) {
247  int iglobal = fo->getGlobalParNum(ilocal);
248  if (iglobal >= 0 && iglobal < NPARMAX) {
249  parvalue[iglobal] = fo->getParam(ilocal);
250  B2INFO("Par " << ilocal << ": global " << iglobal << " = " << parvalue[iglobal]);
251  }
252  }
253  }
254  ConstraintContainer* constraints = fitter.getConstraints();
255  for (ConstraintIterator i = constraints->begin(); i != constraints->end(); ++i) {
256  BaseHardConstraint* c = *i;
257  assert(c);
258  int iglobal = c->getGlobalNum();
259  if (iglobal >= 0 && iglobal < NPARMAX) {
260  parvalue[iglobal] = c->getValue();
261  B2INFO("Const " << c->getName() << ": global " << iglobal << " = " << parvalue[iglobal]);
262  }
263  }
264  }
265 
266  }// end OrcaKinFit namespace
268 } // end Belle2 namespace
269 
270 #endif // MARLIN_USE_ROOT
Abstract base class for different kinds of events.