Belle II Software  release-08-01-10
TOPAlignerModule.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 header.
10 #include <top/modules/TOPAligner/TOPAlignerModule.h>
11 
12 // TOP headers.
13 #include <top/geometry/TOPGeometryPar.h>
14 #include <top/reconstruction_cpp/TOPTrack.h>
15 
16 // Basf2 headers.
17 #include <framework/logging/Logger.h>
18 
19 // root
20 #include <TH1F.h>
21 #include <TH2F.h>
22 
23 
24 using namespace std;
25 
26 namespace Belle2 {
31  using namespace TOP;
32 
33  //-----------------------------------------------------------------
35  //-----------------------------------------------------------------
36 
37  REG_MODULE(TOPAligner);
38 
39 
40  //-----------------------------------------------------------------
41  // Implementation
42  //-----------------------------------------------------------------
43 
44  TOPAlignerModule::TOPAlignerModule() : Module()
45 
46  {
47  // set module description
48  setDescription("Alignment of TOP");
49  // setPropertyFlags(c_ParallelProcessingCertified);
50 
51  // Add parameters
52  addParam("targetModule", m_targetMid,
53  "Module to be aligned. Must be 1 <= Mid <= 16.", 1);
54  addParam("maxFails", m_maxFails,
55  "Maximum number of consecutive failed iterations before resetting the procedure", 100);
56  addParam("sample", m_sample,
57  "sample type: one of dimuon, bhabha or cosmics", std::string("dimuon"));
58  addParam("minMomentum", m_minMomentum,
59  "minimal track momentum if sample is cosmics", 1.0);
60  addParam("deltaEcms", m_deltaEcms,
61  "c.m.s energy window (half size) if sample is dimuon or bhabha", 0.1);
62  addParam("dr", m_dr, "cut on POCA in r", 2.0);
63  addParam("dz", m_dz, "cut on POCA in abs(z)", 4.0);
64  addParam("minZ", m_minZ,
65  "minimal local z of extrapolated hit", -130.0);
66  addParam("maxZ", m_maxZ,
67  "maximal local z of extrapolated hit", 130.0);
68  addParam("outFileName", m_outFileName,
69  "Root output file name containing alignment results",
70  std::string("TopAlignPars.root"));
71  addParam("stepPosition", m_stepPosition, "step size for translations", 1.0);
72  addParam("stepAngle", m_stepAngle, "step size for rotations", 0.01);
73  addParam("stepTime", m_stepTime, "step size for t0", 0.05);
74  std::string names;
75  for (const auto& parName : m_align.getParameterNames()) names += parName + ", ";
76  names.pop_back();
77  names.pop_back();
78  addParam("parInit", m_parInit,
79  "initial parameter values in the order [" + names + "]. "
80  "If list is too short, the missing ones are set to 0.", m_parInit);
81  auto parFixed = m_parFixed;
82  addParam("parFixed", m_parFixed, "list of names of parameters to be fixed. "
83  "Valid names are: " + names, parFixed);
84 
85  }
86 
88  {
89  // check if target module ID is valid
90 
91  const auto* geo = TOPGeometryPar::Instance()->getGeometry();
92  if (not geo->isModuleIDValid(m_targetMid)) {
93  B2ERROR("Target module ID = " << m_targetMid << " is invalid.");
94  }
95 
96  // check if sample type is valid
97 
98  if (not(m_sample == "dimuon" or m_sample == "bhabha" or m_sample == "cosmics")) {
99  B2ERROR("Invalid sample type '" << m_sample << "'");
100  }
101  if (m_sample == "bhabha") m_chargedStable = Const::electron;
102 
103  // set track selector
104 
110 
111  // set alignment object
112 
116  for (const auto& parName : m_parFixed) {
117  m_align.fixParameter(parName);
118  }
119 
120  // input
121 
122  m_digits.isRequired();
123  m_tracks.isRequired();
124  m_extHits.isRequired();
125  m_recBunch.isOptional();
126 
127  // open output file
128 
129  m_file = TFile::Open(m_outFileName.c_str(), "RECREATE");
130  if (m_file->IsZombie()) {
131  B2FATAL("Couldn't open file '" << m_outFileName << "' for writing!");
132  return;
133  }
134 
135  // create output tree
136 
137  m_alignTree = new TTree("alignTree", "TOP alignment results");
138  m_alignTree->Branch("ModuleId", &m_targetMid);
139  m_alignTree->Branch("iter", &m_iter);
140  m_alignTree->Branch("ntrk", &m_ntrk);
141  m_alignTree->Branch("errorCode", &m_errorCode);
142  m_alignTree->Branch("iterPars", &m_vAlignPars);
143  m_alignTree->Branch("iterParsErr", &m_vAlignParsErr);
144  m_alignTree->Branch("valid", &m_valid);
145  m_alignTree->Branch("numPhot", &m_numPhot);
146  m_alignTree->Branch("x", &m_x);
147  m_alignTree->Branch("y", &m_y);
148  m_alignTree->Branch("z", &m_z);
149  m_alignTree->Branch("p", &m_p);
150  m_alignTree->Branch("theta", &m_theta);
151  m_alignTree->Branch("phi", &m_phi);
152  m_alignTree->Branch("r_poca", &m_pocaR);
153  m_alignTree->Branch("z_poca", &m_pocaZ);
154  m_alignTree->Branch("x_poca", &m_pocaX);
155  m_alignTree->Branch("y_poca", &m_pocaY);
156  m_alignTree->Branch("Ecms", &m_cmsE);
157  m_alignTree->Branch("charge", &m_charge);
158  m_alignTree->Branch("PDG", &m_PDG);
159 
160  }
161 
163  {
164 
165  // check bunch reconstruction status and run alignment:
166  // - if object exists and bunch is found (collision data w/ bunch finder in the path)
167  // - if object doesn't exist (cosmic data and other cases w/o bunch finder)
168 
169  if (m_recBunch.isValid()) {
170  if (not m_recBunch->isReconstructed()) return;
171  }
172 
173  // track-by-track iterations
174 
175  for (const auto& track : m_tracks) {
176 
177  // construct TOPtrack from mdst track
178  TOPTrack trk(track);
179  if (not trk.isValid()) continue;
180 
181  // skip if track not hitting target module
182  if (trk.getModuleID() != m_targetMid) continue;
183 
184  // track selection
185  if (not m_selector.isSelected(trk)) continue;
186 
187  // do an iteration
188  int err = m_align.iterate(trk, m_chargedStable);
189  m_iter++;
190 
191  // check number of consecutive failures, and in case reset
192  if (err == 0) {
193  m_countFails = 0;
194  } else if (m_countFails <= m_maxFails) {
195  m_countFails++;
196  } else {
197  B2INFO("Reached maximum allowed number of failed iterations. "
198  "Resetting TOPalign object");
199  m_align.reset();
200  m_countFails = 0;
201  }
202 
203  // get new parameter values and estimated errors
207  m_errorCode = err;
208  m_valid = m_align.isValid();
210 
211  // set other ntuple variables
212  const auto& localPosition = m_selector.getLocalPosition();
213  m_x = localPosition.X();
214  m_y = localPosition.Y();
215  m_z = localPosition.Z();
216  const auto& localMomentum = m_selector.getLocalMomentum();
217  m_p = localMomentum.R();
218  m_theta = localMomentum.Theta();
219  m_phi = localMomentum.Phi();
220  const auto& pocaPosition = m_selector.getPOCAPosition();
221  m_pocaR = pocaPosition.Rho();
222  m_pocaZ = pocaPosition.Z();
223  m_pocaX = pocaPosition.X();
224  m_pocaY = pocaPosition.Y();
226  m_charge = trk.getCharge();
227  m_PDG = trk.getPDGCode();
228 
229  // fill output tree
230  m_alignTree->Fill();
231 
232  // print info
233  TString resMsg = "M= ";
234  resMsg += m_align.getModuleID();
235  resMsg += " ntr=";
236  resMsg += m_ntrk;
237  resMsg += " err=";
238  resMsg += m_errorCode;
239  resMsg += " v=";
240  resMsg += m_align.isValid();
241  for (auto par : m_vAlignPars) {
242  resMsg += " ";
243  resMsg += par;
244  }
245  B2DEBUG(20, resMsg);
246 
247  }
248 
249  }
250 
251 
253  {
254 
255  m_file->cd();
256  m_alignTree->Write();
257 
258  TH1F valid("valid", "status valid", 16, 0.5, 16.5);
259  valid.SetXTitle("slot ID");
260  valid.SetBinContent(m_targetMid, m_valid);
261  valid.Write();
262 
263  TH1F ntrk("ntrk", "number of tracks", 16, 0.5, 16.5);
264  ntrk.SetXTitle("slot ID");
265  ntrk.SetBinContent(m_targetMid, m_ntrk);
266  ntrk.Write();
267 
268  std::string name, title;
269  name = "results_slot" + to_string(m_targetMid);
270  title = "alignment parameters, slot " + to_string(m_targetMid);
271  int npar = m_align.getParams().size();
272  TH1F h0(name.c_str(), title.c_str(), npar, 0, npar);
273  const auto& par = m_align.getParams();
274  const auto& err = m_align.getErrors();
275  for (int i = 0; i < npar; i++) {
276  h0.SetBinContent(i + 1, par[i]);
277  h0.SetBinError(i + 1, err[i]);
278  }
279  h0.Write();
280 
281  name = "errMatrix_slot" + to_string(m_targetMid);
282  title = "error matrix, slot " + to_string(m_targetMid);
283  TH2F h1(name.c_str(), title.c_str(), npar, 0, npar, npar, 0, npar);
284  const auto& errMatrix = m_align.getErrorMatrix();
285  for (int i = 0; i < npar; i++) {
286  for (int k = 0; k < npar; k++) {
287  h1.SetBinContent(i + 1, k + 1, errMatrix[i][k]);
288  }
289  }
290  h1.Write();
291 
292  name = "corMatrix_slot" + to_string(m_targetMid);
293  title = "correlation matrix, slot " + to_string(m_targetMid);
294  TH2F h2(name.c_str(), title.c_str(), npar, 0, npar, npar, 0, npar);
295  std::vector<double> diag;
296  for (int i = 0; i < npar; i++) {
297  double d = errMatrix[i][i];
298  if (d != 0) d = 1.0 / sqrt(d);
299  diag.push_back(d);
300  }
301  for (int i = 0; i < npar; i++) {
302  for (int k = 0; k < npar; k++) {
303  h2.SetBinContent(i + 1, k + 1, diag[i] * diag[k] * errMatrix[i][k]);
304  }
305  }
306  h2.Write();
307 
308  m_file->Close();
309 
310  if (m_valid) {
311  B2RESULT("TOPAligner: slot = " << m_targetMid << ", status = successful, "
312  << "iterations = " << m_iter << ", tracks used = " << m_ntrk);
313  } else {
314  B2RESULT("TOPAligner: slot = " << m_targetMid << ", status = failed, "
315  << "error code = " << m_errorCode
316  << ", iterations = " << m_iter << ", tracks used = " << m_ntrk);
317  }
318  }
319 
320 
322 } // end Belle2 namespace
323 
static const ChargedStable electron
electron particle
Definition: Const.h:650
Base class for Modules.
Definition: Module.h:72
void setDescription(const std::string &description)
Sets the description of the module.
Definition: Module.cc:214
std::vector< float > m_vAlignParsErr
error on alignment parameters
Const::ChargedStable m_chargedStable
track hypothesis
StoreObjPtr< TOPRecBunch > m_recBunch
reconstructed bunch
TOP::TrackSelector m_selector
track selection utility
int m_PDG
track MC truth (simulated data only)
float m_phi
track: extrapolated hit momentum in local (module) frame
double m_minMomentum
minimal track momentum if sample is "cosmics"
std::vector< float > m_vAlignPars
alignment parameters
double m_dz
cut on POCA in z
std::vector< std::string > m_parFixed
names of parameters to be fixed
double m_stepTime
step size for t0
int m_targetMid
target module to align.
TOP::ModuleAlignment m_align
alignment object
double m_maxZ
maximal local z of extrapolated hit
int m_countFails
counter for failed iterations
int m_iter
iteration counter
double m_stepPosition
step size for translations
double m_minZ
minimal local z of extrapolated hit
float m_p
track: extrapolated hit momentum in local (module) frame
bool m_valid
true if alignment parameters are valid
double m_dr
cut on POCA in r
StoreArray< Track > m_tracks
collection of tracks
int m_errorCode
error code of the alignment procedure
double m_stepAngle
step size for rotations
std::vector< double > m_parInit
initial parameter values
double m_deltaEcms
c.m.s energy window if sample is "dimuon" or "bhabha"
int m_maxFails
maximum allowed number of failed iterations
int m_numPhot
number of photons used for log likelihood in this iteration
float m_y
track: extrapolated hit coordinate in local (module) frame
StoreArray< TOPDigit > m_digits
collection of digits
StoreArray< ExtHit > m_extHits
collection of extrapolated hits
TTree * m_alignTree
TTree containing alignment parameters.
std::string m_outFileName
Root output file name containing results.
float m_z
track: extrapolated hit coordinate in local (module) frame
float m_x
track: extrapolated hit coordinate in local (module) frame
std::string m_sample
sample type
int m_ntrk
number of tracks used
float m_theta
track: extrapolated hit momentum in local (module) frame
int getNumUsedTracks() const
Returns number of tracks used in current result.
void setModuleID(int moduleID)
Sets module ID.
bool isValid() const
Checks if the results are valid.
const TMatrixDSym & getErrorMatrix() const
Returns error matrix of alignment parameters Order is: translations in x, y, z, rotation angles aroun...
void fixParameter(const std::string &name)
Fixes parameter with its name given as argument.
void setParameters(const std::vector< double > &parInit)
Sets initial values of parameters (overwrites current parameters!) Order is: translations in x,...
std::vector< float > getParameters() const
Returns alignment parameters.
int getModuleID() const
Returns module ID.
const std::vector< double > & getParams() const
Returns alignment parameters.
void setSteps(double position, double angle, double time)
Sets steps for numerical calculation of derivatives.
int iterate(TOPTrack &track, const Const::ChargedStable &hypothesis)
Run a single alignment iteration, on success update alignment parameters.
const std::vector< std::string > & getParameterNames() const
Returns alignment parameter names.
std::vector< float > getErrors() const
Returns errors on alignment parameters.
void reset()
Reset the object.
int getNumOfPhotons() const
Returns number of photons used for log likelihood calculation.
const TOPGeometry * getGeometry() const
Returns pointer to geometry object using basf2 units.
static TOPGeometryPar * Instance()
Static method to obtain the pointer to its instance.
Reconstructed track at TOP.
Definition: TOPTrack.h:39
int getPDGCode() const
Returns PDG code of associated MCParticle (returns 0 if none)
Definition: TOPTrack.h:228
double getCharge() const
Returns charge.
Definition: TOPTrack.h:161
bool isValid() const
Checks if track is successfully constructed.
Definition: TOPTrack.h:137
int getModuleID() const
Returns slot ID.
Definition: TOPTrack.h:143
Utility for the track selection - used in various calibration modules.
Definition: TrackSelector.h:27
double getCMSEnergy() const
Returns c.m.s energy of the track in last isSelected call.
void setDeltaEcms(double deltaEcms)
Sets cut on c.m.s.
Definition: TrackSelector.h:63
const ROOT::Math::XYZVector & getPOCAPosition() const
Returns position of POCA of the track in last isSelected call.
void setMinMomentum(double minMomentum)
Sets momentum cut (used for "cosmics" only)
Definition: TrackSelector.h:57
const ROOT::Math::XYZVector & getLocalMomentum() const
Returns momentum at TOP in local frame of the track in last isSelected call.
void setCutOnPOCA(double dr, double dz)
Sets cut on point of closest approach to (0, 0, 0)
Definition: TrackSelector.h:70
bool isSelected(const TOPTrack &track) const
Returns selection status.
const ROOT::Math::XYZPoint & getLocalPosition() const
Returns position at TOP in local frame of the track in last isSelected call.
void setCutOnLocalZ(double minZ, double maxZ)
Sets cut on local z coordinate (module frame) of the track extrapolated to TOP.
Definition: TrackSelector.h:81
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:560
#define REG_MODULE(moduleName)
Register the given module (without 'Module' suffix) with the framework.
Definition: Module.h:650
double sqrt(double a)
sqrt for double
Definition: beamHelpers.h:28
virtual void initialize() override
Initialize the Module.
virtual void event() override
Event processor.
virtual void terminate() override
Termination action.
Abstract base class for different kinds of events.