59 Data[barID].NextBar.Clear();
60 Data[barID].NextBarLog.clear();
63 Data[barID].NextPlane[b].Clear();
64 Data[barID].NextPlaneLog[b].clear();
74 Data[barID - 1].NextBar.Clear();
75 Data[barID - 1].NextBarLog.clear();
84 Data[b].NextPlane[bar].Clear();
85 Data[b].NextPlaneLog[bar].clear();
99 if ((
HitMask[plane] & (1UL << bar)) == 0UL)
103 auto& barData =
Data[barID];
118 barData.NextBarLog.push_back(tdiff);
122 for (
auto t : barData.NextBarLog)
125 barData.NextBar = TH1F(
"",
"",
NBins, max - 10, max + 10);
126 barData.NextBar.SetDirectory(
nullptr);
127 for (
auto t : barData.NextBarLog)
128 barData.NextBar.Fill(t);
133 barData.NextBar.Fill(tdiff);
137 const auto nextPlane = plane + 1;
141 for (
auto barInNextPlane = 0; barInNextPlane <
BarsPerPlane; ++barInNextPlane)
143 if ((
HitMask[nextPlane] & (1UL << barInNextPlane)) == 0UL)
146 const auto nextPlaneBarID = nextPlane *
BarsPerPlane + barInNextPlane;
158 barData.NextPlaneLog[barInNextPlane].push_back(tdiff);
162 for (
auto t : barData.NextPlaneLog[barInNextPlane])
165 barData.NextPlane[barInNextPlane] = TH1F(
"",
"",
NBins, max - 25, max + 25);
166 barData.NextPlane[barInNextPlane].SetDirectory(
nullptr);
167 for (
auto t : barData.NextPlaneLog[barInNextPlane])
168 barData.NextPlane[barInNextPlane].Fill(t);
173 barData.NextPlane[barInNextPlane].Fill(tdiff);
185 std::vector<ValueErrorPair> solution(nBars, {
NaN,
NaN });
186 std::vector<Double_t> scaleFactors(nBars, 0.);
190 UInt_t numberOfEquations = 0;
191 for (
auto b = 0; b < nBars; ++b)
193 if (!std::isnan(
Data[b].TSyncNextBar.Value))
195 scaleFactors[b] += 1. /
Sqr(
Data[b].TSyncNextBar.Error);
196 scaleFactors[b + 1] += 1. /
Sqr(
Data[b].TSyncNextBar.Error);
206 if (!std::isnan(
Data[b].TSyncNextPlane[ob].Value))
208 scaleFactors[b] += 1. /
Sqr(
Data[b].TSyncNextPlane[ob].Error);
217 if (numberOfEquations < nBars)
219 LOG(info) <<
"Can not synchronize NeuLAND. Not enough equations (" << numberOfEquations <<
").";
223 for (
auto b = 0; b < nBars; ++b)
224 scaleFactors[b] = 1. / sqrt(scaleFactors[b]);
235 std::array<UInt_t, 2> Index;
236 std::array<Double_t, 2> Value;
239 std::vector<Element> lhs(numberOfEquations);
241 auto function = [&lhs, numberOfVariables](
244 double* x = xVec->elements;
245 double* y = yVec->elements;
249 for (uint r = 0; r < lhs.size(); ++r)
251 *y += x[lhs[r].Index[0]] * lhs[r].Value[0] + x[lhs[r].Index[1]] * lhs[r].Value[1];
258 for (uint r = 0; r < lhs.size(); ++r)
260 x[lhs[r].Index[0]] += (*y) * lhs[r].Value[0];
261 x[lhs[r].Index[1]] += (*y) * lhs[r].Value[1];
268 y = yVec->elements + lhs.size();
272 for (
auto i = 0; i < numberOfVariables; i++)
277 for (
auto i = 0; i < numberOfVariables; i++)
282 alloc_lsqr_mem(&input, &output, &work, numberOfEquations + 1, nBars);
284 input->
num_rows = numberOfEquations;
294 for (UInt_t
id = 0;
id <
Data.size(); ++id)
297 if (!std::isnan(
Data[
id].TSyncNextBar.Value))
299 const auto weight = 1. /
Data[id].TSyncNextBar.Error;
300 lhs[nEQ] = { { id,
id + 1U }, { -weight * scaleFactors[id], weight * scaleFactors[
id + 1U] } };
304 for (UInt_t barInNextPlane = 0; barInNextPlane <
BarsPerPlane; ++barInNextPlane)
306 if (!std::isnan(
Data[
id].TSyncNextPlane[barInNextPlane].Value))
308 const auto barInNextPlaneID =
BarsPerPlane * (plane + 1) + barInNextPlane;
309 const auto weight = 1. /
Data[id].TSyncNextPlane[barInNextPlane].Error;
310 lhs[nEQ] = { { id, barInNextPlaneID },
311 { -weight * scaleFactors[id], weight * scaleFactors[barInNextPlaneID] } };
318 for (
auto bar = 0; bar < nBars; ++bar)
323 LOG(debug) <<
"Syncing Neuland with " << numberOfEquations <<
" equations...";
325 lsqr(input, output, work, function, &lhs);
327 for (
auto id = 0;
id < nBars; ++id)
339 for (
auto& bar :
Data)
341 bar.TSyncNextBar = {
NaN,
NaN };
342 if (bar.NextBar.Integral() > bar.NextBar.GetEntries() * 0.5 &&
345 bar.TSyncNextBar = { bar.NextBar.GetMean(), bar.NextBar.GetStdDev() };
350 bar.TSyncNextPlane[nb] = {
NaN,
NaN };
351 if (bar.NextPlane[nb].Integral() > bar.NextPlane[nb].GetEntries() * 0.5 &&
354 bar.TSyncNextPlane[nb] = { bar.NextPlane[nb].GetMean(), bar.NextPlane[nb].GetStdDev() };
void lsqr(lsqr_input *input, lsqr_output *output, lsqr_work *work, std::function< void(long, dvec *, dvec *, void *)> mat_vec_prod, void *prod)
void alloc_lsqr_mem(lsqr_input **in_struct, lsqr_output **out_struct, lsqr_work **wrk_struct, long max_num_rows, long max_num_cols)