CbmRoot
Loading...
Searching...
No Matches
CaParameters.cxx
Go to the documentation of this file.
1/* Copyright (C) 2022-2023 GSI Helmholtzzentrum fuer Schwerionenforschung, Darmstadt
2 SPDX-License-Identifier: GPL-3.0-only
3 Authors: Sergey Gorbunov, Sergei Zharko [committer] */
4
9
10#include "CaParameters.h"
11
13
14#include <boost/filesystem.hpp>
15
16#include <iomanip>
17
18#include <fmt/format.h>
19
25
26namespace fs = boost::filesystem;
27
28// ---------------------------------------------------------------------------------------------------------------------
29//
30template<typename DataT>
32 ca::SearchWindowMapContainer&& searchWindows)
33 : fSetup(std::move(setup))
34 , fConfig(std::move(config))
35 , fSwMaps(std::move(searchWindows))
36{
37}
38
39
40// ---------------------------------------------------------------------------------------------------------------------
41//
42template<typename DataT>
44{
45 LOG(info) << "Consistency test for L1 parameters object... ";
46 /*
47 * Array of active station IDs
48 *
49 * In the array of active station IDs,
50 * (i) sum of elements, which are not equal -1, must be equal the number of stations,
51 * (ii) subsequence of all the elements, which are not equal -1, must be a gapless subset of integer numbers starting with 0
52 */
53
54 // TODO: rewrite or remove
55 //auto filterInactiveStationIDs = [](int x) { return x != -1; };
56 //int nStationsCheck = std::count_if(fvGeoToActiveMap.cbegin(), fvGeoToActiveMap.cend(), filterInactiveStationIDs);
57 //if (nStationsCheck != fNstationsActiveTotal) {
58 // std::stringstream msg;
59 // msg << "ca::Parameters: invalid object condition: array of active station IDs is not consistent "
60 // << "with the total number of stations (" << nStationsCheck << " vs. " << fNstationsActiveTotal << ' '
61 // << "expected)";
62 // throw std::logic_error(msg.str());
63 //}
64
65 // Check, if the subsequence of all the elements, which are not equal -1, must be a gapless subset of integer numbers
66 // starting from 0. If it is, the testValue in the end must be equal the number of non -1 elements
68 // TODO: rewrite or remove
69 //std::vector<int> idsCheck(
70 // nStationsCheck); // temporary vector containing a sequence of active station IDs without -1 elements
71 //std::copy_if(fvGeoToActiveMap.cbegin(), fvGeoToActiveMap.cend(), idsCheck.begin(), filterInactiveStationIDs);
72 //bool isStationIDsOk = true;
73 //for (int id = 0; id < nStationsCheck; ++id) {
74 // isStationIDsOk = isStationIDsOk && idsCheck[id] == id;
75 //}
76 //if (!isStationIDsOk) {
77 // std::stringstream msg;
78 // msg << "ca::Parameters: invalid object condition: array of active station IDs is not a gapless subset "
79 // << "of integer numbers starting from 0:\n\t";
80 // for (auto id : fvGeoToActiveMap) {
81 // msg << std::setw(3) << std::setfill(' ') << id << ' ';
82 // }
83 // throw std::logic_error(msg.str());
84 //}
85
86 /*
87 * Check magnetic field flags of the stations
88 *
89 * In a current version of tracking there are three configurations possible to be proceeded:
90 * A. All the stations are inside magnetic field
91 * B. There is no magnetic field in a setup
92 * C. All the first stations are inside magnetic field, all the last stations are outside the field
93 * In all the cases the fieldStatus flags should be sorted containing all non-zero elements in the beginning
94 * (representing stations placed into magnetic field) and all zero elements in the end of z-axis.
95 */
96
97 // TODO: rewrite for the active setup
98 //bool ifFieldStatusFlagsOk = std::is_sorted(fStations.cbegin(), fStations.cbegin() + fNstationsActiveTotal,
99 // [&](const ca::Station<DataT>& lhs, const ca::Station<DataT>& rhs) {
100 // return bool(lhs.fieldStatus) > bool(rhs.fieldStatus);
101 // });
102
103 //if (!ifFieldStatusFlagsOk) {
104 // std::stringstream msg;
105 // msg << "ca::Parameters: invalid object condition: L1 tracking is impossible for a given field configuration:\n";
106 // for (int iSt = 0; iSt < fNstationsActiveTotal; ++iSt) {
107 // msg << "- station ID: " << iSt << ", field status: " << fStations[iSt].fieldStatus << '\n';
108 // }
109 // throw std::logic_error(msg.str());
110 //}
111
112
113 /*
114 * Check if each station object is consistent itself, and if all of them are placed after the target
115 * NOTE: If a station was not set up, it is accounted inconsistent (uninitialized). In the array of stations there are uninitialized
116 * stations possible (with id > NstationsActiveTotal), thus one should NOT run the loop above over all the stations in array
117 * but only until *(fNstationsActive.cend() - 1) (== NstationsActiveTotal).
118 * TODO: Probably, we should introduce methods, which check the consistency of fully initialized objects such as ca::Station,
119 * L1MaterialInfo, etc. (S.Zharko)
120 */
121
122 // TODO: Rewrite for active setup
123 //{
124 // auto trgZ = kfutils::simd::Cast<DataT, float>(fActiveSetup.GetTarget().GetZ(), 0);
125 // for (int iSt = 0; iSt < fNstationsActiveTotal; ++iSt) {
126 // fStations[iSt].CheckConsistency();
127 // auto zSta = kfutils::simd::Cast<DataT, float>(fStations[iSt].fZ, 0);
128 // if (zSta < trgZ) {
129 // std::stringstream msg;
130 // msg << "ca::Parameters: station with global ID = " << iSt << " is placed before target "
131 // << "(z_st = " << zSta << " [cm] < z_targ = " << trgZ << " [cm])";
132 // throw std::logic_error(msg.str());
133 // }
134 // }
135 //}
136
137 /*
138 * Check thickness maps
139 * NOTE: If a ca::MaterialMap map was not set up, it is accounted inconsistent (uninitialized). In the array of thickness maps for each
140 * there are uninitialized elements possible (with id > NstationsActiveTotal), thus one should NOT run the loop above over
141 * all the stations in array but only until *(fNstationsActive.cend() - 1) (== NstationsActiveTotal).
142 */
143 // TODO: Provide these checks in the kf::Setup
144 //for (int iSt = 0; iSt < fNstationsActiveTotal; ++iSt) {
145 // fThickMap[iSt].CheckConsistency();
146 //}
147
148 /*
149 * Check equality of station indices in setups:
150 */
151 // TODO: rewrite
152 //{
153 // if (fActiveSetup.GetNofLayers() != this->GetNstationsActive()) {
154 // std::stringstream msg;
155 // msg << "ca::Parameters: number of stations in active kf setup (" << fActiveSetup.GetNofLayers()
156 // << ") differes from the actual number of active tracking stations (" << GetNstationsActive() << ')';
157 // throw std::logic_error(msg.str());
158 // }
159
160 // if (fGeometrySetup.GetNofLayers() != this->GetNstationsGeometry()) {
161 // std::stringstream msg;
162 // msg << "ca::Parameters: number of stations in geometry kf setup (" << fGeometrySetup.GetNofLayers()
163 // << ") differes from the actual number of geometry tracking stations (" << GetNstationsGeometry() << ')';
164 // throw std::logic_error(msg.str());
165 // }
166
167 // {
168 // std::stringstream msg;
169 // msg << "ca::Parameters: inconsistency in geometry station indexing in kf-setup and old init:";
170 // bool bConsistent = true;
171 // for (int iStGeo = 0; iStGeo < GetNstationsGeometry(); ++iStGeo) {
172 // auto [detId, locId] = GetStationIndexLocal(iStGeo);
173 // auto [detIdSetup, locIdSetup] = fGeometrySetup.GetIndexMap().template GlobalToLocal<EDetectorID>(iStGeo);
174 // if (detId != detIdSetup || locId != locIdSetup) {
175 // bConsistent = false;
176 // }
177 // msg << "\n- (old) detId = " << static_cast<int>(detId) << ", locId = " << locId
178 // << " ---- (kf) detId = " << static_cast<int>(detIdSetup) << ", locId = " << locIdSetup;
179 // }
180 // if (!bConsistent) {
181 // throw std::logic_error(msg.str());
182 // }
183 // }
184
185 // {
186 // std::stringstream msg;
187 // msg << "ca::Parameters: inconsistency in active station indexing in kf-setup and old init:";
188 // bool bConsistent = true;
189 // for (int iStGeo = 0; iStGeo < GetNstationsGeometry(); ++iStGeo) {
190 // auto [detId, locId] = GetStationIndexLocal(iStGeo);
191 // int iStActive = GetStationIndexActive(locId, detId);
192 // if (iStActive < 0) {
193 // continue;
194 // }
195 // auto [detIdSetup, locIdSetup] = fActiveSetup.GetIndexMap().template GlobalToLocal<EDetectorID>(iStActive);
196 // if (detId != detIdSetup || locId != locIdSetup) {
197 // bConsistent = false;
198 // }
199 // msg << "\n- (old) detId = " << static_cast<int>(detId) << ", locId = " << locId
200 // << " ---- (kf) detId = " << static_cast<int>(detIdSetup) << ", locId = " << locIdSetup;
201 // }
202 // if (!bConsistent) {
203 // throw std::logic_error(msg.str());
204 // }
205 // }
206 //}
207
208
209 /*
210 * Check iterations sequence
211 * 1. Number of iterations should be larger then zero
212 * 2. Each iteration should contain values within predefined limits
213 * 3. Number of iterations with TrackFromTriplets flag turned on no more then 1
214 * 4. If the TrackFromTriplets iteration exists, it should be the last one in the sequence
215 */
216 // TODO: move this to the ca::Config validation
217 {
218 const auto& iterations = GetCAIterations();
219 if (iterations.empty()) {
220 std::stringstream msg;
221 msg << "L1Parameters: 0 track finder iterations were found. Please, define at least one iteration";
222 throw std::logic_error(msg.str());
223 }
224
225 std::string names = "";
226 for (const auto& iter : iterations) {
227 if (!iter.Check()) {
228 names += iter.GetName() + " ";
229 }
230 }
231 if (names.size()) {
232 std::stringstream msg;
233 msg << "L1Parameters: some parameters are out of range for the following iterations: " << names;
234 throw std::logic_error(msg.str());
235 }
236
237 int nTrackFromTripletIterations = std::count_if(iterations.begin(), iterations.end(),
238 [=](const auto& it) { return it.GetTrackFromTripletsFlag(); });
239 if (nTrackFromTripletIterations > 1) {
240 std::stringstream msg;
241 msg << "L1Parameters: found " << nTrackFromTripletIterations
242 << " iterations with GetTrackFromTripletsFlag() == true:\n";
243 for (const auto& iter : iterations) {
244 if (iter.GetTrackFromTripletsFlag()) {
245 msg << '\t' << "- " << iter.GetName() << '\n';
246 }
247 }
248 msg << "Only the one iteration can have GetTrackFromTripletsFlag() == true, and this iteration should be ";
249 msg << "the last one";
250 throw std::logic_error(msg.str());
251 }
252
253 if (nTrackFromTripletIterations == 1 && !(iterations.end() - 1)->GetTrackFromTripletsFlag()) {
254 std::stringstream msg;
255 msg << "L1Parameters: iteration with GetTrackFromTripletsFlag() == true is not the last in a sequence. ";
256 msg << "The GetTrackFromTripletsFlag() value in the iterations sequence: \n";
257 for (const auto& iter : iterations) {
258 msg << '\t' << "- " << std::setw(15) << std::setfill(' ') << iter.GetName() << ' ';
259 msg << std::setw(6) << std::setfill(' ') << iter.GetTrackFromTripletsFlag() << '\n';
260 }
261 throw std::logic_error(msg.str());
262 }
263 }
264
265 LOG(info) << "Consistency test for L1 parameters object... \033[1;32mpassed\033[0m";
266}
267
268// ---------------------------------------------------------------------------------------------------------------------
269//
270template<typename DataT>
271void Parameters<DataT>::Print(int /*verbosityLevel*/) const
272{
273 LOG(info) << ToString();
274}
275
276// ---------------------------------------------------------------------------------------------------------------------
277//
278template<typename DataT>
279std::string Parameters<DataT>::ToString(int verbosity, int indentLevel) const
280{
281 using namespace constants;
282 using std::setfill;
283 using std::setw;
284 std::stringstream msg{};
285 if (verbosity < 1) {
286 return msg.str();
287 }
288
289 constexpr char indentCh = '\t';
290 std::string indent(indentLevel, indentCh);
291
293 auto ClrFlg = [&](bool flag) { return (flag ? clrs::GN : clrs::RD); };
294
295 msg << " ----- CA parameters list -----\n";
296 msg << indent << clrs::CLb << "COMPILE TIME CONSTANTS:\n" << clrs::CL;
297 msg << indent << indentCh << "Bits to code one station: " << constants::size::StationBits << '\n';
298 msg << indent << indentCh << "Bits to code one triplet: " << constants::size::TripletBits << '\n';
299 msg << indent << indentCh << "Max number of detectors: " << constants::size::MaxNdetectors << '\n';
300 msg << indent << indentCh << "Max number of stations: " << constants::size::MaxNstations << '\n';
301 msg << indent << indentCh << "Max number of triplets: " << constants::size::MaxNtriplets << '\n';
302 msg << indent << clrs::CLb << "GEOMETRY:\n" << clrs::CL;
303 msg << indent << indentCh << clrs::CLb << "NUMBER OF STATIONS:\n" << clrs::CL;
304 msg << indent << indentCh << indentCh << "Number of stations (Geometry): ";
305 for (int iDet = 0; iDet < constants::size::MaxNdetectors; ++iDet) {
306 msg << setw(2) << this->GetNstationsGeometry(static_cast<EDetectorID>(iDet)) << ' ';
307 }
308 msg << " | total = " << setw(2) << this->GetNstationsGeometry();
309 msg << '\n';
310 msg << indent << indentCh << indentCh << "Number of stations (Active): ";
311 for (int iDet = 0; iDet < constants::size::MaxNdetectors; ++iDet) {
312 msg << setw(2) << setfill(' ') << this->GetNstationsActive(static_cast<EDetectorID>(iDet)) << ' ';
313 }
314 msg << " | total = " << setw(2) << this->GetNstationsActive();
315 msg << '\n' << indent << indentCh << indentCh << clrs::CL << "Geometry station indices: ";
316 for (int iStGeo = 0; iStGeo < this->GetNstationsGeometry(); ++iStGeo) {
317 bool isActive = fSetup.GeoToActStationId(iStGeo) != -1;
318 msg << ClrFlg(isActive) << setw(3) << iStGeo << ' ';
319 }
320 msg << '\n' << indent << indentCh << indentCh << clrs::CL << "Local station indices: ";
321 for (int iStGeo = 0; iStGeo < this->GetNstationsGeometry(); ++iStGeo) {
322 bool isActive = fSetup.GeoToActStationId(iStGeo) != -1;
323 auto [detId, locId] = fSetup.GeoToLocStationId(iStGeo);
324 msg << ClrFlg(isActive) << setw(3) << locId << ' ';
325 }
326 msg << '\n' << indent << indentCh << indentCh << clrs::CL << "Detector indices: ";
327 for (int iStGeo = 0; iStGeo < this->GetNstationsGeometry(); ++iStGeo) {
328 bool isActive = fSetup.GeoToActStationId(iStGeo) != -1;
329 auto [detId, locId] = fSetup.GeoToLocStationId(iStGeo);
330 msg << ClrFlg(isActive) << setw(3) << static_cast<int>(detId) << ' ';
331 }
332 msg << '\n' << indent << indentCh << indentCh << clrs::CL << "Active station indices: ";
333 for (int iStGeo = 0; iStGeo < this->GetNstationsGeometry(); ++iStGeo) {
334 int iStAct = fSetup.GeoToActStationId(iStGeo);
335 msg << ClrFlg(iStAct != -1) << setw(3) << iStAct << ' ';
336 }
337 msg << clrs::CL << '\n';
338
339 if (fConfig.DevUseParSearchWindows()) {
340 msg << indent << "DOUBLET SEARCH WINDOWS:\n";
341 for (int iSt = 1; iSt < fSetup.GetNofActStations(); ++iSt) {
342 for (int iIter = 0; iIter < GetNcaIterations(); ++iIter) {
343 const auto& iter = fConfig.GetIteration(iIter);
344 for (int gap = 0; gap <= iter.GetMaxStationGap(); gap++) {
345 msg << indent << "- station: " << iSt << ", iteration: " << iIter << ", gap: " << gap << '\n';
346 msg << fSwMaps.DoubletSw(iIter, iSt, gap).ToString() << '\n';
347 }
348 }
349 }
350 msg << indent << "TRIPLET SEARCH WINDOWS:\n";
351 for (int iSt = 1; iSt < fSetup.GetNofActStations(); ++iSt) {
352 for (int iIter = 0; iIter < GetNcaIterations(); ++iIter) {
353 const auto& iter = fConfig.GetIteration(iIter);
354 for (int gapL = 0; gapL <= iter.GetMaxStationGap(); gapL++) {
355 for (int gapM = 0; gapM <= iter.GetMaxStationGap(); gapM++) {
356 msg << indent << "- station: " << iSt << ", iteration: " << iIter << ", gapL: " << gapL
357 << ", gapM: " << gapM << '\n';
358 msg << fSwMaps.TripletSw(iIter, iSt, gapL, gapM).ToString() << '\n';
359 }
360 }
361 }
362 }
363 }
364
365 msg << '\n';
366 msg << fConfig.ToString(indentLevel) << '\n';
367 return msg.str();
368}
369
370// ---------------------------------------------------------------------------------------------------------------------
371//
372void cbm::algo::ca::ParametersIO::Store(const Parameters<double>& parameters, const std::string& fileName)
373{
374 auto path = fs::absolute(fs::weakly_canonical(fileName));
375 fs::create_directories(path.parent_path());
376
377 std::ofstream ofs(path.string(), std::ios::binary);
378 if (!ofs) {
379 throw std::runtime_error(
380 fmt::format("ca::ParametersIO::Store: failed opening file \"{}\" to store the setup", path.string()));
381 }
382 LOG(info) << "ca::ParametersIO: writing parameters into file \"" << path.string() << '\"';
383 boost::archive::binary_oarchive oa(ofs);
384 oa << parameters;
385}
386
387
388namespace cbm::algo::ca
389{
390 template class Parameters<fvec>;
391 template class Parameters<float>;
392 template class Parameters<double>;
393} // namespace cbm::algo::ca
std::string ToString(CbmCutId id)
Convert CbmCutId to a string representation.
Definition CbmCutId.cxx:7
Parameters()=default
Default constructor.
Configuration of the CA tracking (excluding geometry)
Definition CaConfig.h:36
A set of parameters for the CA Track finder iteration.
Definition CaIteration.h:31
A container for all external parameters of the CA tracking algorithm.
Config fConfig
Configuration.
Setup< DataT > fSetup
Setup representation.
int GetNstationsGeometry() const
Gets total number of stations, provided by setup geometry.
std::string ToString(int verbosity=0, int indentLevel=0) const
String representation of the class contents.
int GetNstationsActive() const
Gets total number of active stations.
SearchWindowMapContainer fSwMaps
Search window map.
void Print(int verbosityLevel=0) const
Prints configuration.
void CheckConsistency() const
Class invariant checker.
int GetNcaIterations() const
Provides number of iterations.
Setup representation for tracking.
Definition CaSetup.h:54
constexpr int MaxNstations
Max number of stations, 2^6 = 64.
Definition CaDefs.h:44
constexpr unsigned int StationBits
Amount of bits to code a station or triplet. This values determine the maximum number of stations and...
Definition CaDefs.h:40
constexpr unsigned int TripletBits
Amount of bits to code one triplet.
Definition CaDefs.h:41
constexpr int MaxNtriplets
Max number of triplets, 2^26 = 67,108,864.
Definition CaDefs.h:45
constexpr int MaxNdetectors
Max number of tracking detectors.
Definition CaDefs.h:43
TODO: SZh 8.11.2022: add selection of parameterisation.
Definition CaBranch.h:14
EDetectorID
Enumeration for the tracking detector subsystems in CBM-CA.
Definition CbmDefs.h:216
void CheckSimdVectorEquality(fvec v, const char *name)
Checks, if a SIMD vector horizontally equal TODO: Find this method in the VC!
Definition KfUtils.cxx:29
Hash for CbmL1LinkKey.
static void Store(const Parameters< double > &parameters, const std::string &fileName)
Stores parameter to file.