9#include <top/calibration/TOPAlignmentAlgorithm.h>
10#include <top/dbobjects/TOPCalModuleAlignment.h>
33 setDescription(
"Calibration algorithm for geometrcal alignment of TOP module");
41 auto h1 = getObjectPtr<TH2F>(
"tracks_per_slot");
43 B2ERROR(
"histogram 'tracks_per_slot' not found");
46 unsigned numModules = h1->GetNbinsX();
47 unsigned numSets = h1->GetNbinsY();
55 for (
unsigned set = 0; set < numSets; set++) {
59 std::string name =
"alignTree" + to_string(set);
60 auto alignTree = getObjectPtr<TTree>(name);
62 B2ERROR(
"TOPAlignmentAlgorithm: 'alignTree' not found");
66 alignTree->SetBranchAddress(
"ModuleId", &
m_moduleID);
67 alignTree->SetBranchAddress(
"iter", &
m_iter);
68 alignTree->SetBranchAddress(
"ntrk", &
m_ntrk);
69 alignTree->SetBranchAddress(
"errorCode", &
m_errorCode);
72 alignTree->SetBranchAddress(
"valid", &
m_valid);
76 std::map<int, int> lastIterations;
77 std::map<int, int> lastIterationEntries;
78 for (
int i = 0; i < alignTree->GetEntries(); i++) {
79 alignTree->GetEntry(i);
88 for (
const auto& lastIterationEntry : lastIterationEntries) {
89 alignTree->GetEntry(lastIterationEntry.second);
91 B2ERROR(
"slot " <<
m_moduleID <<
", set=" << set <<
92 ": sizes of vectors of alignment parameters and errors differ. "
110 string expNo = to_string(expRun[0].first);
111 while (expNo.length() < 4) expNo.insert(0,
"0");
112 string runNo = to_string(expRun[0].second);
113 while (runNo.length() < 5) runNo.insert(0,
"0");
114 string outputFileName =
"alignment-e" + expNo +
"-r" + runNo +
".root";
115 auto* file = TFile::Open(outputFileName.c_str(),
"recreate");
120 TDirectory* oldDir = gDirectory;
121 for (
unsigned slot = 1; slot <= numModules; slot++) {
122 std::string slotName =
"_s" + to_string(slot);
123 auto h2 = getObjectPtr<TH1F>(
"local_z" + slotName);
124 auto h3 = getObjectPtr<TH2F>(
"cth_vs_p" + slotName);
125 auto h4 = getObjectPtr<TH2F>(
"poca_xy" + slotName);
126 auto h5 = getObjectPtr<TH1F>(
"poca_z" + slotName);
127 auto h6 = getObjectPtr<TH1F>(
"Ecms" + slotName);
128 auto h7 = getObjectPtr<TH1F>(
"charge" + slotName);
129 auto h8 = getObjectPtr<TH2F>(
"timeHits" + slotName);
130 auto h9 = getObjectPtr<TH1F>(
"numPhot" + slotName);
132 std::string name =
"slot_" + to_string(slot);
133 oldDir->mkdir(name.c_str())->cd();
147 auto h_valid =
new TH1F(
"valid",
"Valid results",
148 numModules, 0.5, numModules + 0.5);
149 h_valid->SetXTitle(
"slot number");
150 h_valid->SetYTitle(
"valid flag");
152 auto h_iter =
new TH1F(
"iterations",
"Number of iterations",
153 numModules, 0.5, numModules + 0.5);
154 h_iter->SetXTitle(
"slot number");
155 h_iter->SetYTitle(
"iterations");
157 auto h_ntrk =
new TH1F(
"ntrk",
"Number of tracks",
158 numModules, 0.5, numModules + 0.5);
159 h_ntrk->SetXTitle(
"slot number");
160 h_ntrk->SetYTitle(
"tracks");
162 std::vector<TH1F*> h_params;
164 auto h_x =
new TH1F(
"delta_x",
"Displacement in x",
165 numModules, 0.5, numModules + 0.5);
166 h_x->SetXTitle(
"slot number");
167 h_x->SetYTitle(
"#Deltax [cm]");
168 h_params.push_back(h_x);
170 auto h_y =
new TH1F(
"delta_y",
"Displacement in y",
171 numModules, 0.5, numModules + 0.5);
172 h_y->SetXTitle(
"slot number");
173 h_y->SetYTitle(
"#Deltay [cm]");
174 h_params.push_back(h_y);
176 auto h_z =
new TH1F(
"delta_z",
"Displacement in z",
177 numModules, 0.5, numModules + 0.5);
178 h_z->SetXTitle(
"slot number");
179 h_z->SetYTitle(
"#Deltaz [cm]");
180 h_params.push_back(h_z);
182 auto h_alpha =
new TH1F(
"alpha",
"Rotation angle around x",
183 numModules, 0.5, numModules + 0.5);
184 h_alpha->SetXTitle(
"slot number");
185 h_alpha->SetYTitle(
"#alpha [rad]");
186 h_params.push_back(h_alpha);
188 auto h_beta =
new TH1F(
"beta",
"Rotation angle around y",
189 numModules, 0.5, numModules + 0.5);
190 h_beta->SetXTitle(
"slot number");
191 h_beta->SetYTitle(
"#beta [rad]");
192 h_params.push_back(h_beta);
194 auto h_gamma =
new TH1F(
"gamma",
"Rotation angle around z",
195 numModules, 0.5, numModules + 0.5);
196 h_gamma->SetXTitle(
"slot number");
197 h_gamma->SetYTitle(
"#gamma [rad]");
198 h_params.push_back(h_gamma);
200 auto h_t0 =
new TH1F(
"t0",
"Module T0",
201 numModules, 0.5, numModules + 0.5);
202 h_t0->SetXTitle(
"slot number");
203 h_t0->SetYTitle(
"t_{0} [ns]");
204 h_params.push_back(h_t0);
206 auto h_refind =
new TH1F(
"dn_n",
"Refractive index scale factor",
207 numModules, 0.5, numModules + 0.5);
208 h_refind->SetXTitle(
"slot number");
209 h_refind->SetYTitle(
"#Deltan/n");
210 h_params.push_back(h_refind);
223 int moduleID = element.first;
224 const auto& data = element.second;
225 h_valid->SetBinContent(moduleID, data.valid);
226 h_iter->SetBinContent(moduleID, data.iter);
227 h_ntrk->SetBinContent(moduleID, data.ntrk);
228 auto vsize = std::min(data.alignPars.size(), data.alignErrs.size());
229 for (
unsigned i = 0; i < std::min(h_params.size(), vsize); i++) {
230 h_params[i]->SetBinContent(moduleID, data.alignPars[i]);
231 h_params[i]->SetBinError(moduleID, data.alignErrs[i]);
234 B2ERROR(
"slot " << moduleID <<
235 ": too few alignment parameters found in ntuple, npar = " << vsize);
238 alignment->setX(moduleID, data.alignPars[0], data.alignErrs[0]);
239 alignment->setY(moduleID, data.alignPars[1], data.alignErrs[1]);
240 alignment->setZ(moduleID, data.alignPars[2], data.alignErrs[2]);
241 alignment->setAlpha(moduleID, data.alignPars[3], data.alignErrs[3]);
242 alignment->setBeta(moduleID, data.alignPars[4], data.alignErrs[4]);
243 alignment->setGamma(moduleID, data.alignPars[5], data.alignErrs[5]);
245 alignment->setCalibrated(moduleID);
247 alignment->setUnusable(moduleID);
258 if (not alignment->areAllCalibrated()) {
259 B2INFO(
"Alignment not successful for all slots");
264 B2INFO(
"Alignment successful but precision worse than required");
285 std::set<int> slotIDs;
287 slotIDs.insert(element.first);
292 auto h_pulls =
new TH1F(
"pulls",
"Pulls of statistically independent results",
294 h_pulls->SetXTitle(
"pulls");
298 for (
auto slot : slotIDs) {
300 std::vector<AlignData> data;
301 for (
auto it = range.first; it != range.second; ++it) {
302 data.push_back(it->second);
304 for (
size_t i = 0; i < data.size(); i++) {
305 const auto& pars1 = data[i].alignPars;
306 const auto& errs1 = data[i].alignErrs;
307 for (
size_t j = i + 1; j < data.size(); j++) {
308 const auto& pars2 = data[j].alignPars;
309 const auto& errs2 = data[j].alignErrs;
310 for (
size_t k = 0; k < std::min(pars1.size(), pars2.size()); k++) {
311 double e1 = errs1[k];
312 double e2 = errs2[k];
313 if (e1 == 0 or e2 == 0)
continue;
314 double pull = (pars1[k] - pars2[k]) /
sqrt(e1 * e1 + e2 * e2);
323 double scaleFact = 1;
324 if (h_pulls->GetEntries() > 1) scaleFact = h_pulls->GetRMS();
328 for (
auto slot : slotIDs) {
330 if (range.first == range.second)
continue;
332 for (
auto it = range.first; it != range.second; ++it) {
333 mergedData.
add(it->second);
346 if (not data.valid)
return;
348 for (
size_t i =
alignPars.size(); i < data.alignPars.size(); i++) {
353 for (
size_t i = 0; i < data.alignPars.size(); i++) {
354 auto e = data.alignErrs[i];
355 if (e == 0)
continue;
356 auto wt = 1 / (e * e);
366 for (
size_t i = 0; i < alignPars.size(); i++) {
367 auto wt = alignErrs[i];
368 if (wt == 0)
continue;
370 alignErrs[i] = 1 /
sqrt(wt) * scaleFact;
Base class for calibration algorithms.
void saveCalibration(TClonesArray *data, const std::string &name)
Store DBArray payload with given name with default IOV.
void setDescription(const std::string &description)
Set algorithm description (in constructor)
const std::vector< Calibration::ExpRun > & getRunList() const
Get the list of runs for which calibration is called.
EResult
The result of calibration.
@ c_OK
Finished successfully =0 in Python.
@ c_NotEnoughData
Needs more data =2 in Python.
@ c_Failure
Failed =3 in Python.
Alignment constants for all 16 modules.
std::vector< float > * m_vAlignPars
alignment parameters
double m_spatialPrecision
required precision of displacements
TBranch * m_bAlignParsErr
branch of error on alignment parameters
std::multimap< int, AlignData > m_inputData
input from ntuples
virtual EResult calibrate() final
algorithm implementation
TOPAlignmentAlgorithm()
Constructor.
double m_angularPrecision
required precision of rotation angles
std::vector< float > * m_vAlignParsErr
error on alignment parameters
TBranch * m_bAlignPars
branch of alignment parameters
int m_iter
iteration counter
bool m_valid
true if alignment parameters are valid
int m_errorCode
error code of the alignment procedure
void mergeData()
merge subsamples and rescale errors
std::map< int, AlignData > m_mergedData
merged subsamples
int m_ntrk
number of tracks used
double sqrt(double a)
sqrt for double
Abstract base class for different kinds of events.
void add(const AlignData &data)
Merge another data structure to this one.
bool valid
true if alignment parameters are valid
void finalize(double scaleFact)
Calculate weighted averages and rescale errors.
std::vector< float > alignPars
alignment parameters
int ntrk
number of tracks used
int iter
iteration counter
std::vector< float > alignErrs
uncertainties on alignment parameters