110int mp2prep(
const char* fileListPath =
"/home/igor/bmnroot/align_new/cfg/run8/7466.noa_rlerr.list",
111 const char* constraintsPath =
"/home/igor/bmnroot/align_new/cfg/run8/constraints/cnstr_38e_lin4.json",
112 const char* presigmaPath =
"/home/igor/bmnroot/align_new/cfg/run8/presigmas/psg_38e_lin4.json",
113 const char* outDir =
"/home/igor/bmnroot/align_new/mp2/out",
116 fair::Logger::SetConsoleColor(
true);
117 fair::Logger::SetConsoleSeverity(
"info");
123 LOG(info) <<
" detector model : " << model.
Description();
124 LOG(info) <<
" measure model : " << measure.
Description();
127 const std::vector<BmnDetectorModel::Composite> composites{model.
Composites()};
129 std::map<std::string, Int_t> compByName;
130 for (std::size_t c = 0; c < composites.size(); c++) {
131 compByName[composites[c].name] = c;
132 for (
Int_t leaf : composites[c].leaves)
136 if (compOf[leaf] < 0) {
137 LOG(error) <<
" <!> element " << leaf <<
" belongs to no composite";
140 LOG(info) <<
" parametrization : " << model.
Alignables() <<
" elements + " << composites.size()
141 <<
" composites, " << kParams
142 <<
" parameters each = " << (model.
Alignables() + (
Int_t)composites.size()) * kParams
143 <<
" global parameters";
145 const std::string out{outDir};
149 std::ofstream ofs(out +
"/mp2labels.txt");
151 LOG(error) <<
" <!> cannot write into " << out <<
" (does it exist?)";
154 ofs <<
"# label object param owner\n";
156 for (
Int_t p = 0; p < kParams; p++)
157 ofs << LeafLabel(leaf, p) <<
' ' << model.
EncodedID(leaf) <<
' ' << kName[p] <<
' '
158 << composites[compOf[leaf]].name <<
'\n';
159 for (std::size_t c = 0; c < composites.size(); c++)
160 for (
Int_t p = 0; p < kParams; p++)
161 ofs << CompLabel(c, p) <<
' ' << composites[c].name <<
' ' << kName[p] <<
" -\n";
166 std::ifstream ifs(presigmaPath);
168 LOG(error) <<
" <!> failed to open presigmas file " << presigmaPath;
174 std::array<Double_t, kParams> leafSigma{};
175 std::vector<std::array<Double_t, kParams>> compSigma(composites.size());
177 for (
const nlohmann::json& e : js) {
178 if (!e.contains(
"ParamName") || !e.contains(
"Sigma")) {
179 LOG(error) <<
" <!> presigma entry without ParamName/Sigma:"
180 " only the (ParamName[, NodeName], Sigma) form is supported";
183 const Int_t p{SlotByName(e[
"ParamName"].get<std::string>())};
189 if (!e.contains(
"NodeName")) {
190 leafSigma[p] = sigma;
193 const std::string node{e[
"NodeName"].get<std::string>()};
194 const auto it{compByName.find(node)};
195 if (it == compByName.end()) {
196 LOG(error) <<
" <!> presigma NodeName '" << node <<
"' is not a composite of the model";
199 compSigma[it->second][p] = sigma;
201 LOG_IF(warning, dropped) <<
" ! " << dropped <<
" presigma entrie(s) on phi/theta ignored";
203 std::ofstream ofs(out +
"/mp2par.txt");
204 ofs <<
"* label initial value pre-sigma (0 = free)\n"
207 for (
Int_t p = 0; p < kParams; p++)
208 ofs << LeafLabel(leaf, p) <<
" 0.0 " << leafSigma[p] <<
'\n';
209 for (std::size_t c = 0; c < composites.size(); c++)
210 for (
Int_t p = 0; p < kParams; p++)
211 ofs << CompLabel(c, p) <<
" 0.0 " << compSigma[c][p] <<
'\n';
212 LOG(info) <<
" " << out <<
"/mp2par.txt : pre-sigmas written";
217 std::ifstream ifs(constraintsPath);
219 LOG(error) <<
" <!> failed to open constraints file " << constraintsPath;
225 std::ofstream ofs(out +
"/mp2con.txt");
226 Int_t written{0}, skipped{0};
227 for (
const nlohmann::json& jc : js) {
228 std::map<Int_t, Double_t> coef;
231 std::string comment{jc.value(
"Comment", std::string{})};
233 for (
const nlohmann::json& jco : jc[
"Coefficients"]) {
234 if (jco.contains(
"RHS")) {
238 if (!jco.contains(
"ParamName") || !jco.contains(
"Value")) {
239 LOG(error) <<
" <!> constraint coefficient without ParamName/Value:"
240 " only the (ParamName, DetectorID|NodeName, Value)"
241 " form is supported";
244 const Int_t p{SlotByName(jco[
"ParamName"].get<std::string>())};
250 if (jco.contains(
"NodeName")) {
251 const std::string node{jco[
"NodeName"].get<std::string>()};
252 const auto it{compByName.find(node)};
253 if (it == compByName.end()) {
254 LOG(error) <<
" <!> constraint NodeName '" << node <<
"' is not a composite of the model";
257 coef[CompLabel(it->second, p)] += value;
258 }
else if (jco.contains(
"DetectorID")) {
259 const Int_t id{jco[
"DetectorID"].get<
Int_t>()};
261 LOG(error) <<
" <!> constraint DetectorID " <<
id <<
" is not an element of the model";
269 coef[LeafLabel(leaf, p)] += value;
270 coef[CompLabel(compOf[leaf], p)] += value;
272 LOG(error) <<
" <!> constraint coefficient with neither NodeName"
277 if (!alive || coef.empty()) {
279 LOG(info) <<
" skipped (phi/theta only): " << comment;
282 ofs <<
"\n* " << comment <<
"\nConstraint " << rhs <<
'\n';
283 for (
const auto& [label, value] : coef)
284 ofs <<
" " << label <<
" " << value <<
'\n';
287 LOG(info) <<
" " << out <<
"/mp2con.txt : " << written <<
" constraint(s) written, " << skipped
288 <<
" skipped as meaningless for this model";
293 std::ofstream ofs(out +
"/mp2steer.txt");
294 ofs <<
"* Millepede-II steering, generated by mp2prep.C\n"
300 <<
"* full inversion: 196 parameters, and it is the covariance matrix\n"
301 <<
"* that makes the result comparable with BmnAligner's reported errors\n"
302 <<
"method inversion 5 0.001\n"
307 Mille mille((out +
"/mp2mille.bin").c_str());
310 LOG(error) <<
" <!> failed to open the dataset " << fileListPath;
314 std::vector<HitRec> hits;
315 Long64_t nTracks{0}, nHits{0}, nBadFit{0};
322 LOG(error) <<
" <!> unknown detector module encoding " << detID;
332 Double_t alphaX, betaX, alphaY, betaY;
333 if (!FitLine(hits,
kFALSE, alphaX, betaX) || !FitLine(hits,
kTRUE, alphaY, betaY)) {
338 const SVectLC lc{alphaX, betaX, alphaY, betaY};
340 for (
const HitRec& h : hits) {
342 const Int_t comp{compOf[h.leaf]};
344 Int_t label[2 * kParams];
345 float derGl[2 * kParams];
346 for (
Int_t p = 0; p < kParams; p++) {
347 label[p] = LeafLabel(h.leaf, p);
348 label[kParams + p] = CompLabel(comp, p);
352 for (
Int_t p = 0; p < kParams; p++)
353 derGl[p] = derGl[kParams + p] = (
float)gx(kSlot[p]);
355 (
float)(1.0 / std::sqrt(h.wx)));
360 derLc[3] = (float)h.z;
361 for (
Int_t p = 0; p < kParams; p++)
362 derGl[p] = derGl[kParams + p] = (
float)gy(kSlot[p]);
364 (
float)(1.0 / std::sqrt(h.wy)));
368 nHits += hits.size();
369 if (++nTracks % 500000 == 0)
370 LOG(info) <<
" " << nTracks <<
" tracks written...";
374 LOG(info) <<
" " << out <<
"/mp2mille.bin : " << nTracks <<
" records, " << nHits <<
" hits (" << 2 * nHits
376 LOG_IF(warning, nBadFit) <<
" ! " << nBadFit <<
" track(s) skipped: degenerate line fit";
377 LOG(state) <<
" < mp2prep : done, run pede from " << out;