Belle II Software development
TOPAlignmentCollectorModule.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#include <top/modules/collectors/TOPAlignmentCollectorModule.h>
10#include <top/geometry/TOPGeometryPar.h>
11#include <top/reconstruction_cpp/TOPTrack.h>
12
13// framework aux
14#include <framework/logging/Logger.h>
15
16// root
17#include <TTree.h>
18#include <TH1F.h>
19#include <TH2F.h>
20#include <TRandom.h>
21
22using namespace std;
23
24namespace Belle2 {
30 using namespace TOP;
31
32 //-----------------------------------------------------------------
34 //-----------------------------------------------------------------
35
36 REG_MODULE(TOPAlignmentCollector);
37
38 //-----------------------------------------------------------------
39 // Implementation
40 //-----------------------------------------------------------------
41
43 {
44 // set module description and processing properties
45 setDescription("A collector for geometrical alignment of a TOP module with dimuons or Bhabhas. Iterative alignment procedure (NIMA 876 (2017) 260-264) is run here, algorithm just collects the results.");
47
48 // module parameters
49 addParam("targetModule", m_targetMid,
50 "Module to be aligned. Must be 1 <= Mid <= 16.");
51 addParam("maxFails", m_maxFails,
52 "Maximum number of consecutive failed iterations before resetting the procedure", 100);
53 addParam("sample", m_sample,
54 "sample type: one of dimuon or bhabha", std::string("dimuon"));
55 addParam("deltaEcms", m_deltaEcms,
56 "c.m.s energy window (half size) if sample is dimuon or bhabha", 0.1);
57 addParam("dr", m_dr, "cut on POCA in r", 1.0);
58 addParam("dz", m_dz, "cut on POCA in abs(z)", 2.0);
59 addParam("minZ", m_minZ, "minimal local z of extrapolated hit", -130.0);
60 addParam("maxZ", m_maxZ, "maximal local z of extrapolated hit", 130.0);
61 addParam("stepPosition", m_stepPosition, "step size for translations", 1.0);
62 addParam("stepAngle", m_stepAngle, "step size for rotations", 0.01);
63 addParam("stepTime", m_stepTime, "step size for t0", 0.05);
64 std::string names;
65 auto align = ModuleAlignment();
66 for (const auto& parName : align.getParameterNames()) names += parName + ", ";
67 names.pop_back();
68 names.pop_back();
69 addParam("parInit", m_parInit,
70 "initial parameter values in the order [" + names + "]. "
71 "If list is too short, the missing ones are set to 0.", m_parInit);
72 auto parFixed = m_parFixed;
73 addParam("parFixed", m_parFixed, "list of names of parameters to be fixed. "
74 "Valid names are: " + names, parFixed);
75
76 }
77
78
80 {
81 // input collections
82
83 m_digits.isRequired();
84 m_tracks.isRequired();
85 m_extHits.isRequired();
86 m_recBunch.isRequired();
87
88 // check if target module ID is valid
89
90 const auto* geo = TOPGeometryPar::Instance()->getGeometry();
91 if (!geo->isModuleIDValid(m_targetMid)) {
92 B2FATAL("Target module ID = " << m_targetMid << " is invalid. Exiting...");
93 }
94
95 // set track selector
96
97 if (m_sample == "dimuon" or m_sample == "bhabha") {
102 } else {
103 B2ERROR("Invalid sample type '" << m_sample << "'");
104 }
105
106 // set alignment objects
107
108 for (int set = 0; set < c_numSets; set++) {
109 auto align = ModuleAlignment();
110 align.setModuleID(m_targetMid);
111 align.setSteps(m_stepPosition, m_stepAngle, m_stepTime);
112 align.setParameters(m_parInit);
113 for (const auto& parName : m_parFixed) {
114 align.fixParameter(parName);
115 }
116 m_align.push_back(align);
117 m_countFails.push_back(0);
118 }
119
120 // create and register output histograms and ntuples
121
122 int numModules = geo->getNumModules();
123 auto h1 = new TH2F("tracks_per_slot", "Number of tracks per slot and sample",
124 numModules, 0.5, numModules + 0.5, c_numSets, 0, c_numSets);
125 h1->SetXTitle("slot number");
126 h1->SetYTitle("sample number");
127 registerObject<TH2F>("tracks_per_slot", h1);
128
129 for (int slot = 1; slot <= numModules; slot++) {
130 std::string slotName = "_s" + to_string(slot);
131 std::string slotTitle = "(slot " + to_string(slot) + ")";
132
133 std::string hname = "local_z" + slotName;
134 std::string title = "Distribution of tracks along bar " + slotTitle;
135 auto h2 = new TH1F(hname.c_str(), title.c_str(), 100, -150.0, 150.0);
136 h2->SetXTitle("local z [cm]");
137 registerObject<TH1F>(hname, h2);
138
139 hname = "cth_vs_p" + slotName;
140 title = "Track momentum " + slotTitle;
141 auto h3 = new TH2F(hname.c_str(), title.c_str(), 100, 0.0, 7.0, 100, -1.0, 1.0);
142 h3->SetXTitle("p [GeV/c]");
143 h3->SetYTitle("cos #theta");
144 registerObject<TH2F>(hname, h3);
145
146 hname = "poca_xy" + slotName;
147 title = "Track POCA in x-y " + slotTitle;
148 auto h4 = new TH2F(hname.c_str(), title.c_str(), 100, -m_dr, m_dr, 100, -m_dr, m_dr);
149 h4->SetXTitle("x [cm]");
150 h4->SetYTitle("y [cm]");
151 registerObject<TH2F>(hname, h4);
152
153 hname = "poca_z" + slotName;
154 title = "Track POCA in z " + slotTitle;
155 auto h5 = new TH1F(hname.c_str(), title.c_str(), 100, -m_dz, m_dz);
156 h5->SetXTitle("z [cm]");
157 registerObject<TH1F>(hname, h5);
158
159 hname = "Ecms" + slotName;
160 title = "Track c.m.s. energy " + slotTitle;
161 auto h6 = new TH1F(hname.c_str(), title.c_str(), 100, 5.1, 5.4);
162 h6->SetXTitle("E_{cms} [GeV]");
163 registerObject<TH1F>(hname, h6);
164
165 hname = "charge" + slotName;
166 title = "Charge of track " + slotTitle;
167 auto h7 = new TH1F(hname.c_str(), title.c_str(), 3, -1.5, 1.5);
168 h7->SetXTitle("charge");
169 registerObject<TH1F>(hname, h7);
170
171 hname = "timeHits" + slotName;
172 title = "Photon time distribution " + slotTitle;
173 auto h8 = new TH2F(hname.c_str(), title.c_str(), 512, 0, 512, 200, 0, 50);
174 h8->SetXTitle("channel number");
175 h8->SetYTitle("time [ns]");
176 registerObject<TH2F>(hname, h8);
177
178 hname = "numPhot" + slotName;
179 title = "Number of photons " + slotTitle;
180 auto h9 = new TH1F(hname.c_str(), title.c_str(), 100, 0, 100);
181 h9->SetXTitle("photons per track");
182 registerObject<TH1F>(hname, h9);
183 }
184
185 for (int set = 0; set < c_numSets; set++) {
186 std::string name = "alignTree" + to_string(set);
187 m_treeNames.push_back(name);
188 auto alignTree = new TTree(name.c_str(), "TOP alignment results");
189 alignTree->Branch("ModuleId", &m_targetMid);
190 alignTree->Branch("iter", &m_iter);
191 alignTree->Branch("ntrk", &m_ntrk);
192 alignTree->Branch("errorCode", &m_errorCode);
193 alignTree->Branch("iterPars", &m_vAlignPars);
194 alignTree->Branch("iterParsErr", &m_vAlignParsErr);
195 alignTree->Branch("valid", &m_valid);
196 alignTree->Branch("numPhot", &m_numPhot);
197 alignTree->Branch("x", &m_x);
198 alignTree->Branch("y", &m_y);
199 alignTree->Branch("z", &m_z);
200 alignTree->Branch("p", &m_p);
201 alignTree->Branch("theta", &m_theta);
202 alignTree->Branch("phi", &m_phi);
203 alignTree->Branch("r_poca", &m_pocaR);
204 alignTree->Branch("z_poca", &m_pocaZ);
205 alignTree->Branch("x_poca", &m_pocaX);
206 alignTree->Branch("y_poca", &m_pocaY);
207 alignTree->Branch("Ecms", &m_cmsE);
208 alignTree->Branch("charge", &m_charge);
209 alignTree->Branch("PDG", &m_PDG);
210 registerObject<TTree>(name, alignTree);
211 }
212
213 }
214
215
217 {
218 // bunch must be reconstructed
219
220 if (not m_recBunch.isValid()) return;
221 if (not m_recBunch->isReconstructed()) return;
222
223 // track-by-track iterations
224
225 for (const auto& track : m_tracks) {
226
227 // construct TOPTrack from mdst track
228 TOPTrack trk(track);
229 if (not trk.isValid()) continue;
230
231 // skip if track not hitting target module
232 if (trk.getModuleID() != m_targetMid) continue;
233
234 // track selection
235 if (not m_selector.isSelected(trk)) continue;
236
237 // generate sub-sample number
238 int sub = gRandom->Integer(c_numSets);
239 auto& align = m_align[sub];
240 auto& countFails = m_countFails[sub];
241 const auto& name = m_treeNames[sub];
242 auto h1 = getObjectPtr<TH2F>("tracks_per_slot");
243 h1->Fill(trk.getModuleID(), sub);
244
245 // do an iteration
246 int err = align.iterate(trk, m_selector.getChargedStable());
247 m_iter++;
248
249 // check number of consecutive failures, and in case reset
250 if (err == 0) {
251 countFails = 0;
252 } else if (countFails <= m_maxFails) {
253 countFails++;
254 } else {
255 B2INFO("Reached maximum allowed number of failed iterations. "
256 "Resetting TOPalign object of set = " << sub << " at iter = " << m_iter);
257 align.reset();
258 countFails = 0;
259 }
260
261 // get new parameter values and estimated errors
262 m_vAlignPars = align.getParameters();
263 m_vAlignParsErr = align.getErrors();
264 m_ntrk = align.getNumUsedTracks();
265 m_errorCode = err;
266 m_valid = align.isValid();
267 m_numPhot = align.getNumOfPhotons();
268
269 // set other ntuple variables
270 const auto& localPosition = m_selector.getLocalPosition();
271 m_x = localPosition.X();
272 m_y = localPosition.Y();
273 m_z = localPosition.Z();
274 const auto& localMomentum = m_selector.getLocalMomentum();
275 m_p = localMomentum.R();
276 m_theta = localMomentum.Theta();
277 m_phi = localMomentum.Phi();
278 const auto& pocaPosition = m_selector.getPOCAPosition();
279 m_pocaR = pocaPosition.Rho();
280 m_pocaZ = pocaPosition.Z();
281 m_pocaX = pocaPosition.X();
282 m_pocaY = pocaPosition.Y();
284 m_charge = trk.getCharge();
285 m_PDG = trk.getPDGCode();
286
287 // fill output tree
288 auto alignTree = getObjectPtr<TTree>(name);
289 alignTree->Fill();
290
291 // fill control histograms
292 std::string slotName = "_s" + to_string(m_targetMid);
293 auto h2 = getObjectPtr<TH1F>("local_z" + slotName);
294 h2->Fill(m_z);
295 auto h3 = getObjectPtr<TH2F>("cth_vs_p" + slotName);
296 h3->Fill(m_p, cos(m_theta));
297 auto h4 = getObjectPtr<TH2F>("poca_xy" + slotName);
298 h4->Fill(m_pocaX, m_pocaY);
299 auto h5 = getObjectPtr<TH1F>("poca_z" + slotName);
300 h5->Fill(m_pocaZ);
301 auto h6 = getObjectPtr<TH1F>("Ecms" + slotName);
302 h6->Fill(m_cmsE);
303 auto h7 = getObjectPtr<TH1F>("charge" + slotName);
304 h7->Fill(m_charge);
305 auto h8 = getObjectPtr<TH2F>("timeHits" + slotName);
306 for (const auto& digit : m_digits) {
307 if (digit.getHitQuality() != TOPDigit::c_Good) continue;
308 if (digit.getModuleID() != m_targetMid) continue;
309 h8->Fill(digit.getChannel(), digit.getTime());
310 }
311 auto h9 = getObjectPtr<TH1F>("numPhot" + slotName);
312 h9->Fill(m_numPhot);
313
314 } // tracks
315
316 }
317
319} // Belle2
void setDescription(const std::string &description)
Sets the description of the module.
Definition: Module.cc:214
void setPropertyFlags(unsigned int propertyFlags)
Sets the flags for the module properties.
Definition: Module.cc:208
@ c_ParallelProcessingCertified
This module can be run in parallel processing mode safely (All I/O must be done through the data stor...
Definition: Module.h:80
std::vector< float > m_vAlignParsErr
error on alignment parameters
std::vector< TOP::ModuleAlignment > m_align
alignment objects
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
std::vector< float > m_vAlignPars
alignment parameters
std::vector< std::string > m_parFixed
names of parameters to be fixed
std::vector< int > m_countFails
counters for failed iterations
std::vector< std::string > m_treeNames
tree names
double m_maxZ
maximal local z of extrapolated hit
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
StoreArray< Track > m_tracks
collection of tracks
@ c_numSets
number of statistically independent subsamples
int m_errorCode
error code of the alignment procedure
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
float m_z
track: extrapolated hit coordinate in local (module) frame
float m_x
track: extrapolated hit coordinate in local (module) frame
float m_theta
track: extrapolated hit momentum in local (module) frame
Alignment of a TOP module.
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.
const ROOT::Math::XYZPoint & getLocalPosition() const
Returns position at TOP in local frame of the track in last isSelected call.
void setDeltaEcms(double deltaEcms)
Sets cut on c.m.s.
Definition: TrackSelector.h:63
void setCutOnPOCA(double dr, double dz)
Sets cut on point of closest approach to (0, 0, 0)
Definition: TrackSelector.h:70
const ROOT::Math::XYZVector & getPOCAPosition() const
Returns position of POCA of the track in last isSelected call.
bool isSelected(const TOPTrack &track) const
Returns selection status.
const ROOT::Math::XYZVector & getLocalMomentum() const
Returns momentum 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
const Const::ChargedStable & getChargedStable() const
Returns track hypothesis.
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
virtual void collect() final
Replacement for event().
virtual void prepare() final
Replacement for initialize().
Abstract base class for different kinds of events.
STL namespace.