12 #include <top/calibration/TOPAlignmentAlgorithm.h>
13 #include <top/dbobjects/TOPCalModuleAlignment.h>
33 TOPAlignmentAlgorithm::TOPAlignmentAlgorithm():
36 setDescription(
"Calibration algorithm for geometrcal alignment of TOP module");
44 auto h1 = getObjectPtr<TH2F>(
"tracks_per_slot");
46 B2ERROR(
"histogram 'tracks_per_slot' not found");
49 unsigned numModules = h1->GetNbinsX();
50 unsigned numSets = h1->GetNbinsY();
58 for (
unsigned set = 0; set < numSets; set++) {
62 std::string name =
"alignTree" + to_string(set);
63 auto alignTree = getObjectPtr<TTree>(name);
65 B2ERROR(
"TOPAlignmentAlgorithm: 'alignTree' not found");
69 alignTree->SetBranchAddress(
"ModuleId", &
m_moduleID);
70 alignTree->SetBranchAddress(
"iter", &
m_iter);
71 alignTree->SetBranchAddress(
"ntrk", &
m_ntrk);
72 alignTree->SetBranchAddress(
"errorCode", &
m_errorCode);
75 alignTree->SetBranchAddress(
"valid", &
m_valid);
79 std::map<int, int> lastIterations;
80 std::map<int, int> lastIterationEntries;
81 for (
int i = 0; i < alignTree->GetEntries(); i++) {
82 alignTree->GetEntry(i);
91 for (
const auto& lastIterationEntry : lastIterationEntries) {
92 alignTree->GetEntry(lastIterationEntry.second);
94 B2ERROR(
"slot " <<
m_moduleID <<
", set=" << set <<
95 ": sizes of vectors of alignment parameters and errors differ. "
113 string expNo = to_string(expRun[0].first);
114 while (expNo.length() < 4) expNo.insert(0,
"0");
115 string runNo = to_string(expRun[0].second);
116 while (runNo.length() < 5) runNo.insert(0,
"0");
117 string outputFileName =
"alignment-e" + expNo +
"-r" + runNo +
".root";
118 auto* file = TFile::Open(outputFileName.c_str(),
"recreate");
123 TDirectory* oldDir = gDirectory;
124 for (
unsigned slot = 1; slot <= numModules; slot++) {
125 std::string slotName =
"_s" + to_string(slot);
126 auto h2 = getObjectPtr<TH1F>(
"local_z" + slotName);
127 auto h3 = getObjectPtr<TH2F>(
"cth_vs_p" + slotName);
128 auto h4 = getObjectPtr<TH2F>(
"poca_xy" + slotName);
129 auto h5 = getObjectPtr<TH1F>(
"poca_z" + slotName);
130 auto h6 = getObjectPtr<TH1F>(
"Ecms" + slotName);
131 auto h7 = getObjectPtr<TH1F>(
"charge" + slotName);
132 auto h8 = getObjectPtr<TH2F>(
"timeHits" + slotName);
133 auto h9 = getObjectPtr<TH1F>(
"numPhot" + slotName);
135 std::string name =
"slot_" + to_string(slot);
136 oldDir->mkdir(name.c_str())->cd();
150 auto h_valid =
new TH1F(
"valid",
"Valid results",
151 numModules, 0.5, numModules + 0.5);
152 h_valid->SetXTitle(
"slot number");
153 h_valid->SetYTitle(
"valid flag");
155 auto h_iter =
new TH1F(
"iterations",
"Number of iterations",
156 numModules, 0.5, numModules + 0.5);
157 h_iter->SetXTitle(
"slot number");
158 h_iter->SetYTitle(
"iterations");
160 auto h_ntrk =
new TH1F(
"ntrk",
"Number of tracks",
161 numModules, 0.5, numModules + 0.5);
162 h_ntrk->SetXTitle(
"slot number");
163 h_ntrk->SetYTitle(
"tracks");
165 std::vector<TH1F*> h_params;
167 auto h_x =
new TH1F(
"delta_x",
"Displacement in x",
168 numModules, 0.5, numModules + 0.5);
169 h_x->SetXTitle(
"slot number");
170 h_x->SetYTitle(
"#Deltax [cm]");
171 h_params.push_back(h_x);
173 auto h_y =
new TH1F(
"delta_y",
"Displacement in y",
174 numModules, 0.5, numModules + 0.5);
175 h_y->SetXTitle(
"slot number");
176 h_y->SetYTitle(
"#Deltay [cm]");
177 h_params.push_back(h_y);
179 auto h_z =
new TH1F(
"delta_z",
"Displacement in z",
180 numModules, 0.5, numModules + 0.5);
181 h_z->SetXTitle(
"slot number");
182 h_z->SetYTitle(
"#Deltaz [cm]");
183 h_params.push_back(h_z);
185 auto h_alpha =
new TH1F(
"alpha",
"Rotation angle around x",
186 numModules, 0.5, numModules + 0.5);
187 h_alpha->SetXTitle(
"slot number");
188 h_alpha->SetYTitle(
"#alpha [rad]");
189 h_params.push_back(h_alpha);
191 auto h_beta =
new TH1F(
"beta",
"Rotation angle around y",
192 numModules, 0.5, numModules + 0.5);
193 h_beta->SetXTitle(
"slot number");
194 h_beta->SetYTitle(
"#beta [rad]");
195 h_params.push_back(h_beta);
197 auto h_gamma =
new TH1F(
"gamma",
"Rotation angle around z",
198 numModules, 0.5, numModules + 0.5);
199 h_gamma->SetXTitle(
"slot number");
200 h_gamma->SetYTitle(
"#gamma [rad]");
201 h_params.push_back(h_gamma);
203 auto h_t0 =
new TH1F(
"t0",
"Module T0",
204 numModules, 0.5, numModules + 0.5);
205 h_t0->SetXTitle(
"slot number");
206 h_t0->SetYTitle(
"t_{0} [ns]");
207 h_params.push_back(h_t0);
209 auto h_refind =
new TH1F(
"dn_n",
"Refractive index scale factor",
210 numModules, 0.5, numModules + 0.5);
211 h_refind->SetXTitle(
"slot number");
212 h_refind->SetYTitle(
"#Deltan/n");
213 h_params.push_back(h_refind);
226 int moduleID = element.first;
227 const auto& data = element.second;
228 h_valid->SetBinContent(moduleID, data.valid);
229 h_iter->SetBinContent(moduleID, data.iter);
230 h_ntrk->SetBinContent(moduleID, data.ntrk);
231 auto vsize = std::min(data.alignPars.size(), data.alignErrs.size());
232 for (
unsigned i = 0; i < std::min(h_params.size(), vsize); i++) {
233 h_params[i]->SetBinContent(moduleID, data.alignPars[i]);
234 h_params[i]->SetBinError(moduleID, data.alignErrs[i]);
237 B2ERROR(
"slot " << moduleID <<
238 ": too few alignment parameters found in ntuple, npar = " << vsize);
241 alignment->setX(moduleID, data.alignPars[0], data.alignErrs[0]);
242 alignment->setY(moduleID, data.alignPars[1], data.alignErrs[1]);
243 alignment->setZ(moduleID, data.alignPars[2], data.alignErrs[2]);
244 alignment->setAlpha(moduleID, data.alignPars[3], data.alignErrs[3]);
245 alignment->setBeta(moduleID, data.alignPars[4], data.alignErrs[4]);
246 alignment->setGamma(moduleID, data.alignPars[5], data.alignErrs[5]);
248 alignment->setCalibrated(moduleID);
250 alignment->setUnusable(moduleID);
261 if (not alignment->areAllCalibrated()) {
262 B2INFO(
"Alignment not successful for all slots");
267 B2INFO(
"Alignment successful but precision worse than required");
288 std::set<int> slotIDs;
290 slotIDs.insert(element.first);
295 auto h_pulls =
new TH1F(
"pulls",
"Pulls of statistically independent results",
297 h_pulls->SetXTitle(
"pulls");
301 for (
auto slot : slotIDs) {
303 std::vector<AlignData> data;
304 for (
auto it = range.first; it != range.second; ++it) {
305 data.push_back(it->second);
307 for (
size_t i = 0; i < data.size(); i++) {
308 const auto& pars1 = data[i].alignPars;
309 const auto& errs1 = data[i].alignErrs;
310 for (
size_t j = i + 1; j < data.size(); j++) {
311 const auto& pars2 = data[j].alignPars;
312 const auto& errs2 = data[j].alignErrs;
313 for (
size_t k = 0; k < std::min(pars1.size(), pars2.size()); k++) {
314 double e1 = errs1[k];
315 double e2 = errs2[k];
316 if (e1 == 0 or e2 == 0)
continue;
317 double pull = (pars1[k] - pars2[k]) / sqrt(e1 * e1 + e2 * e2);
326 double scaleFact = 1;
327 if (h_pulls->GetEntries() > 1) scaleFact = h_pulls->GetRMS();
331 for (
auto slot : slotIDs) {
333 if (range.first == range.second)
continue;
335 for (
auto it = range.first; it != range.second; ++it) {
336 mergedData.
add(it->second);
349 if (not data.valid)
return;
351 for (
size_t i =
alignPars.size(); i < data.alignPars.size(); i++) {
356 for (
size_t i = 0; i < data.alignPars.size(); i++) {
357 auto e = data.alignErrs[i];
358 if (e == 0)
continue;
359 auto wt = 1 / (e * e);
369 for (
size_t i = 0; i < alignPars.size(); i++) {
370 auto wt = alignErrs[i];
371 if (wt == 0)
continue;
373 alignErrs[i] = 1 / sqrt(wt) * scaleFact;