Belle II Software  release-06-02-00
TOPLaserCalibratorModule.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 // Own include
10 #include <top/modules/TOPLaserCalibrator/TOPLaserCalibratorModule.h>
11 #include <top/modules/TOPLaserCalibrator/LaserCalibratorFit.h>
12 
13 // framework - DataStore
14 #include <framework/datastore/StoreArray.h>
15 
16 // framework aux
17 #include <framework/logging/Logger.h>
18 
19 // DataStore classes
20 //#include <framework/dataobjects/EventMetaData.h>
21 #include <top/dataobjects/TOPDigit.h>
22 
23 #include <TFile.h>
24 #include <TH1F.h>
25 #include <TMath.h>
26 #include <TTree.h>
27 #include <sstream>
28 
29 
30 using namespace std;
31 
32 namespace Belle2 {
37  //-----------------------------------------------------------------
38  // Register module
39  //-----------------------------------------------------------------
40 
41  REG_MODULE(TOPLaserCalibrator)
42 
43  //-----------------------------------------------------------------
44  // Implementation
45  //-----------------------------------------------------------------
46 
48  {
49  setDescription("T0 Calibration using the laser calibration system");
50 
51  std::vector<double> frange = {100, 0., 1.};
52  // Add parameters
53  addParam("dataFitOutput", m_dataFitOutput, "Output root file for data",
54  string("")); //output fitting results
55  addParam("mcInput", m_mcInput, "Input root file from MC", string(""));
56  addParam("channelT0constant", m_chT0C, "Output of channel T0 constant", string(""));
57  addParam("fitChannel", m_fitChannel, "set 0 - 511 to a specific channel; set 0 to all channels in the fit",
58  512);
59  addParam("barID", m_barID, "ID of TOP module to calibrate");
60  addParam("refCh", m_refCh, "reference channel of T0 constant");
61  addParam("fitMethod", m_fitMethod, "gauss: single gaussian; cb: single Crystal Ball; cb2: double Crystal Ball", string("gauss"));
62  addParam("fitRange", m_fitRange, "fit range[nbins, xmin, xmax]", frange);
63 
64  for (int i = 0; i < c_NumChannels; ++i) {
65  m_histo[i] = 0;
66  }
67  }
68 
69  TOPLaserCalibratorModule::~TOPLaserCalibratorModule()
70  {
71  }
72 
73  void TOPLaserCalibratorModule::initialize()
74  {
75  B2WARNING("You are using an old version of the laser fitter, now deprecated. This module has been superseded by the CAF collector TOPLaserCalibratorCollector and the CAF fitter TOPLocalCalFitter.");
76  m_digits.isRequired();
77  }
78 
79  void TOPLaserCalibratorModule::beginRun()
80  {
81  }
82 
83  void TOPLaserCalibratorModule::event()
84  {
85  for (auto& digit : m_digits) {
86  if (m_barID != 0 && digit.getModuleID() != m_barID) continue; //if m_barID == 0, use all 16 slots(for MC test)
87  unsigned channel = digit.getChannel();
88  if (channel < c_NumChannels) {
89  auto histo = m_histo[channel];
90  if (!histo) {
91  stringstream ss;
92  ss << "chan" << channel ;
93  string name;
94  ss >> name;
95  string title = "Times " + name;
96  histo = new TH1F(name.c_str(), title.c_str(), (int)m_fitRange[0], m_fitRange[1], m_fitRange[2]);
97  m_histo[channel] = histo;
98  }
99  if (digit.getHitQuality() != TOPDigit::EHitQuality::c_Good) continue;
100  if (digit.getTime() < m_fitRange[1] || digit.getTime() > m_fitRange[2]) continue;
101  if (!digit.isTimeBaseCalibrated()) continue;
102  histo->Fill(digit.getTime()); //get Time from TOPDigit
103  }
104  }
105  }
106 
107  void TOPLaserCalibratorModule::endRun()
108  {
109  }
110 
111  void TOPLaserCalibratorModule::terminate()
112  {
113  std::vector<TH1F*> v_histo;
114  for (int i = 0; i < c_NumChannels; ++i) {
115  v_histo.push_back(m_histo[i]);
116  }
117 
118  double dataT[c_NumChannels] = {0};
119  double dataTErr[c_NumChannels] = {0};
120  double mcT[c_NumChannels] = {0};
121 
122  TOP::LaserCalibratorFit t0fit(m_barID);
123  t0fit.setHist(v_histo); //set time hist vector
124  t0fit.setFitMethod(m_fitMethod);
125  t0fit.setFitRange(m_fitRange[1], m_fitRange[2]);
126  if (m_fitChannel == c_NumChannels) {
127  for (int i = 0; i < c_NumChannels; ++i) {
128  t0fit.fitChannel(i);
129  dataT[i] = t0fit.getFitT();
130  dataTErr[i] = t0fit.getFitTErr();
131  }
132  } else {
133  t0fit.fitChannel(m_fitChannel);
134  dataT[m_fitChannel] = t0fit.getFitT();
135  }
136  //cout<<"chisq=\t"<<t0fit.getFitChisq(6)<<endl;
137  t0fit.writeFile(m_dataFitOutput); //write to root file
138 
139  //read laser propagation time from MC (TOPChannelT0MC)
140  auto mcFile = new TFile(m_mcInput.c_str());
141  auto tree = static_cast<TTree*>(mcFile->Get("t0MC"));
142  int channel_mc;
143  double maxpos;
144 
145  tree->SetBranchAddress("channel", &channel_mc);
146  tree->SetBranchAddress("maxpos", &maxpos);
147  for (int i = 0; i < tree->GetEntries(); i++) {
148  tree->GetEntry(i);
149  mcT[channel_mc] = maxpos;
150  }
151 
152  //w.r.t. ref. channel
153  for (int i = 0; i < c_NumChannels; i++) {
154  if (i == m_refCh) continue;
155  dataT[i] = dataT[i] - dataT[m_refCh];
156  mcT[i] = mcT[i] - mcT[m_refCh];
157  }
158 
159  delete tree;
160  mcFile->Close();
161  delete mcFile;
162 
163  //calculate T0 Const, write to root file
164  auto file = new TFile(m_chT0C.c_str(), "RECREATE");
165  auto otree = new TTree("chT0", "Channel T0 Const");
166 
167  unsigned channel = 0;
168  double t0_const = 0;
169  double t0ConstRaw = 0;
170  double fittedTime = 0;
171  double fittedTimeError = 0;
172  double mcTime = 0;
173  double mcCorrection = 0;
174  double t0ConstError = 0;
175 
176  otree->Branch("fittedTime", &fittedTime, "fittedTime/D");
177  otree->Branch("fittedTimeError", &fittedTimeError, "fittedTimeError/D");
178  otree->Branch("mcTime", &mcTime, "mcTime/D");
179  otree->Branch("t0ConstRaw", &t0ConstRaw, "t0ConstRaw/D");
180  otree->Branch("mcCorrection", &mcCorrection, "mcCorrection/D");
181  otree->Branch("t0Const", &t0_const, "t0_const/D");
182  otree->Branch("t0ConstError", &t0ConstError, "t0ConstError/D");
183  otree->Branch("channel", &channel, "channel/I");
184  otree->Branch("slot", &m_barID, "slot/I");
185 
186  for (int i = 0; i < c_NumChannels; i++) {
187  if (i == m_refCh) {
188  fittedTime = dataT[i];
189  mcTime = mcT[i];
190  } else {
191  fittedTime = dataT[i] + dataT[m_refCh];
192  mcTime = mcT[i] + mcT[m_refCh];
193  }
194  fittedTimeError = dataTErr[i];
195  t0ConstRaw = dataT[i];
196  mcCorrection = mcT[i];
197  channel = i;
198  t0_const = dataT[i] - mcT[i];
199  // assuming that the MC error is negligible
200  t0ConstError = TMath::Sqrt(dataTErr[i] * dataTErr[i] + dataTErr[m_refCh] * dataTErr[m_refCh]);
201  if (i == m_refCh) {
202  t0_const = 0;
203  t0ConstError = dataTErr[m_refCh];
204  }
205  otree->Fill();
206  }
207  otree->Write();
208  delete otree;
209  file->Close();
210  delete file;
211 
212  // ...
213  // write to database; next to do ...
214  // ...
215  }
217 } // end Belle2 namespace
218 
Base class for Modules.
Definition: Module.h:72
T0 Laser calibration module (under development)
A class do laser calibration fit provide different fitting method (under development)
void setHist(const std::vector< TH1F * > &hist)
set time hist of all channels in one moduleID
double getFitT()
get mean positon after fit
void setFitMethod(const std::string &method)
set time fit function
void setFitRange(double xmin=-200, double xmax=200)
set x range in the fit
int fitChannel(unsigned channel)
fit for a specific channel
double getFitTErr()
returns the error mean positon after fit
void writeFile(const std::string &outfile)
write fit result to a root file
#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.