Newer
Older
/* Copyright (C) 2022 GSI Helmholtzzentrum fuer Schwerionenforschung, Darmstadt
SPDX-License-Identifier: GPL-3.0-only
Authors: Sergey Gorbunov, Sergei Zharko [committer] */
/// \file CaInitManager.cxx
/// \brief Input data management class for the CA tracking algorithm (implementation)
/// \since 19.01.2022
/// \author Sergei Zharko <s.zharko@gsi.de>
#include "CaInitManager.h"
#include "KfSetupBuilder.h"
Sergei Zharko
committed
#include <boost/archive/binary_iarchive.hpp>
#include <boost/archive/binary_oarchive.hpp>
#include <boost/archive/text_iarchive.hpp>
Sergei Zharko
committed
Sergei Zharko
committed
#include <fstream>
Sergei Zharko
committed
namespace cbm::algo::ca
{
// --------------------------------------------------------------------------------------------------------------------
//
void InitManager::AddStation(const StationInitializer& inStation) { fvStationInfo.push_back(inStation); }
// --------------------------------------------------------------------------------------------------------------------
//
void InitManager::AddStations(const Parameters<fvec>& par)
{
const auto& stations = par.GetStations();
for (int iSt = 0; iSt < par.GetNstationsActive(); ++iSt) {
auto stationIn = Station<double>(stations[iSt]);
// Get detector ID of the station
auto [detId, locId] = par.GetStationIndexLocal(par.GetActiveToGeoMap()[iSt]);
auto stationInfo = ca::StationInitializer(detId, locId);
stationInfo.SetStationType(stationIn.type);
stationInfo.SetZmin(0.); // NOTE: Deprecated (not used)
stationInfo.SetZmax(0.); // NOTE: Deprecated (not used)
stationInfo.SetZref(stationIn.fZ);
stationInfo.SetXmax(stationIn.Xmax);
stationInfo.SetYmax(stationIn.Ymax);
stationInfo.SetFieldStatus(stationIn.fieldStatus);
stationInfo.SetTimeInfo(stationIn.timeInfo);
stationInfo.SetTrackingStatus(true);
this->AddStation(stationInfo);
}
}
Sergei Zharko
committed
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
// --------------------------------------------------------------------------------------------------------------------
//
void InitManager::CheckInit()
{
this->CheckCAIterationsInit();
this->CheckStationsInfoInit();
fbConfigIsRead = false;
fbGeometryConfigLock = false;
}
// --------------------------------------------------------------------------------------------------------------------
//
void InitManager::ClearSetupInfo()
{
// Clear stations set and a thickness map
fvStationInfo.clear();
fInitController.SetFlag(EInitKey::kStationsInfo, false);
// Set number of stations do default values
this->ClearStationLayout();
// Clear field info
fParameters.fVertexFieldRegion = kf::FieldRegion<fvec>();
fParameters.fVertexFieldValue = kf::FieldValue<fvec>();
fInitController.SetFlag(EInitKey::kPrimaryVertexField, false);
// Clear target position
fParameters.fTargetPos.fill(Undef<float>);
fTargetZ = 0.;
fInitController.SetFlag(EInitKey::kTargetPos, false);
// Clear field function
fFieldFunction = FieldFunction_t([](const double(&)[3], double(&)[3]) {});
fInitController.SetFlag(EInitKey::kFieldFunction, false);
// Clear other flags
fParameters.fRandomSeed = 1;
fParameters.fGhostSuppression = 0;
fInitController.SetFlag(EInitKey::kRandomSeed, false);
fInitController.SetFlag(EInitKey::kGhostSuppression, false);
fParameters.fMisalignmentX.fill(0.);
fParameters.fMisalignmentY.fill(0.);
fParameters.fMisalignmentT.fill(0.);
fParameters.fDevIsIgnoreHitSearchAreas = false;
fParameters.fDevIsUseOfOriginalField = false;
fParameters.fDevIsMatchDoubletsViaMc = false;
fParameters.fDevIsMatchTripletsViaMc = false;
fParameters.fDevIsExtendTracksViaMc = false;
fParameters.fDevIsSuppressOverlapHitsViaMc = false;
fParameters.fDevIsParSearchWUsed = false;
fbGeometryConfigLock = false;
Sergei Zharko
committed
}
// --------------------------------------------------------------------------------------------------------------------
//
void InitManager::ClearCAIterations()
{
fParameters.fCAIterations.clear();
fCAIterationsNumberCrosscheck = -1;
fInitController.SetFlag(EInitKey::kCAIterations, false);
fInitController.SetFlag(EInitKey::kCAIterationsNumberCrosscheck, false);
}
// --------------------------------------------------------------------------------------------------------------------
// NOTE: this function should be called once in the SendParameters
bool InitManager::FormParametersContainer()
{
// Read configuration files
this->ReadInputConfigs();
if (!fbConfigIsRead) { // Check config reading status
return false;
}
Sergei Zharko
committed
if (!fParameters.fDevIsParSearchWUsed) {
fInitController.SetFlag(EInitKey::kSearchWindows, true);
}
Sergei Zharko
committed
Sergei Zharko
committed
// Apply magnetic field to the station info objects
std::for_each(fvStationInfo.begin(), fvStationInfo.end(), [&](auto& st) { st.SetFieldFunction(fFieldFunction); });
Sergei Zharko
committed
// Check initialization
this->CheckInit();
Sergei Zharko
committed
if (!fInitController.IsFinalized()) {
LOG(error) << "ca::InitManager: Attempt to form parameters container before all necessary fields were initialized"
<< fInitController.ToString();
return false;
}
Sergei Zharko
committed
{ // Form array of stations
auto destIt = fParameters.fStations.begin();
for (const auto& station : fvStationInfo) {
if (!station.GetTrackingStatus()) {
continue;
}
*destIt = station.GetStation();
++destIt;
}
}
Sergei Zharko
committed
Sergei Zharko
committed
// Check the consistency of the parameters object. If object inconsistent, it throws std::logic_error
try {
fParameters.CheckConsistency();
}
catch (const std::logic_error& err) {
LOG(error) << "ca::InitManager: parameters container consistency check failed. Reason: " << err.what();
return false;
}
Sergei Zharko
committed
return true;
Sergei Zharko
committed
}
Sergei Zharko
committed
// --------------------------------------------------------------------------------------------------------------------
//
int InitManager::GetNstationsActive() const
{
if (!fInitController.GetFlag(EInitKey::kStationLayoutInitialized)) {
std::stringstream msg;
msg << "ca::InitManager: number of active stations cannot be accessed until the station layout is initialized";
throw std::runtime_error(msg.str());
Sergei Zharko
committed
}
Sergei Zharko
committed
return fParameters.GetNstationsActive();
Sergei Zharko
committed
}
Sergei Zharko
committed
// --------------------------------------------------------------------------------------------------------------------
//
int InitManager::GetNstationsActive(EDetectorID detectorID) const
{
if (!fInitController.GetFlag(EInitKey::kStationLayoutInitialized)) {
std::stringstream msg;
msg << "ca::InitManager: number of active stations cannot be accessed until the station layout is initialized";
throw std::runtime_error(msg.str());
}
return fParameters.GetNstationsActive(detectorID);
Sergei Zharko
committed
}
Sergei Zharko
committed
// --------------------------------------------------------------------------------------------------------------------
//
int InitManager::GetNstationsGeometry() const
{
if (!fInitController.GetFlag(EInitKey::kStationLayoutInitialized)) {
std::stringstream msg;
msg << "ca::InitManager: number of geometry stations cannot be accessed until the station layout is initialized";
throw std::runtime_error(msg.str());
}
return fParameters.GetNstationsGeometry();
Sergei Zharko
committed
Sergei Zharko
committed
// --------------------------------------------------------------------------------------------------------------------
//
int InitManager::GetNstationsGeometry(EDetectorID detectorID) const
{
if (!fInitController.GetFlag(EInitKey::kStationLayoutInitialized)) {
std::stringstream msg;
msg << "ca::InitManager: number of geometry stations cannot be accessed until the station layout is initialized";
throw std::runtime_error(msg.str());
}
return fParameters.GetNstationsGeometry(detectorID);
Sergei Zharko
committed
Sergei Zharko
committed
// --------------------------------------------------------------------------------------------------------------------
//
std::vector<StationInitializer>& InitManager::GetStationInfo()
{
if (!fInitController.GetFlag(EInitKey::kStationLayoutInitialized)) {
std::stringstream msg;
msg << "ca::InitManager: station info container cannot be accessed until the station layout is initialized";
throw std::runtime_error(msg.str());
}
return fvStationInfo;
Sergei Zharko
committed
Sergei Zharko
committed
// --------------------------------------------------------------------------------------------------------------------
//
void InitManager::InitStationLayout()
{
LOG(info) << "ca::InitManager::InitStationLayout(): ....";
this->ClearStationLayout();
std::sort(fvStationInfo.begin(), fvStationInfo.end());
Sergei Zharko
committed
Sergei Zharko
committed
for (const auto& aStation : fvStationInfo) {
++fParameters.fvFirstGeoId[static_cast<int>(aStation.GetDetectorID()) + 1];
}
for (int iDet = 1; iDet < static_cast<int>(fParameters.fvFirstGeoId.size()) - 1; ++iDet) {
fParameters.fvFirstGeoId[iDet + 1] += fParameters.fvFirstGeoId[iDet];
}
Sergei Zharko
committed
Sergei Zharko
committed
fParameters.fNstationsActiveTotal = 0;
for (int iStGeo = 0; iStGeo < static_cast<int>(fvStationInfo.size()); ++iStGeo) {
const auto& aStation = fvStationInfo[iStGeo];
int iDet = static_cast<int>(aStation.GetDetectorID());
int iStLocal = aStation.GetStationID();
// Fill local -> geo map
fParameters.fvGeoToLocalIdMap[iStGeo] = std::make_pair(aStation.GetDetectorID(), iStLocal);
// Fill geo -> local map
fParameters.fvLocalToGeoIdMap[fParameters.fvFirstGeoId[iDet] + iStLocal] = iStGeo;
// Fill geo <-> active map
int iStActive = aStation.GetTrackingStatus() ? fParameters.fNstationsActiveTotal++ : -1;
fParameters.fvGeoToActiveMap[iStGeo] = iStActive;
if (iStActive > -1) {
fParameters.fvActiveToGeoMap[iStActive] = iStGeo;
}
}
fInitController.SetFlag(EInitKey::kStationLayoutInitialized, true);
Sergei Zharko
committed
Sergei Zharko
committed
for (auto& aStation : fvStationInfo) {
aStation.SetGeoLayerID(fParameters.GetStationIndexGeometry(aStation.GetStationID(), aStation.GetDetectorID()));
}
Sergei Zharko
committed
}
Sergei Zharko
committed
// --------------------------------------------------------------------------------------------------------------------
//
void InitManager::InitTargetField(double zStep)
{
if (fInitController.GetFlag(EInitKey::kPrimaryVertexField)) {
LOG(warn) << "ca::InitManager::InitTargetField: attempt to reinitialize the field value and field region "
<< "near target. Ignore";
return;
Sergei Zharko
committed
Sergei Zharko
committed
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
// Check for field function
if (!fInitController.GetFlag(EInitKey::kFieldFunction)) {
std::stringstream msg;
msg << "Attempt to initialize the field value and field region near target before initializing field function";
throw std::runtime_error(msg.str());
}
// Check for target defined
if (!fInitController.GetFlag(EInitKey::kTargetPos)) {
std::stringstream msg;
msg << "Attempt to initialize the field value and field region near target before the target position"
<< "initialization";
throw std::runtime_error(msg.str());
}
constexpr int nDimensions{3};
constexpr int nPointsNodal{3};
std::array<double, nPointsNodal> inputNodalZ{fTargetZ, fTargetZ + zStep, fTargetZ + 2. * zStep};
std::array<kf::FieldValue<fvec>, nPointsNodal> B{};
std::array<fvec, nPointsNodal> z{};
// loop over nodal points
for (int idx = 0; idx < nPointsNodal; ++idx) {
double point[nDimensions]{0., 0., inputNodalZ[idx]};
double field[nDimensions]{};
fFieldFunction(point, field);
z[idx] = inputNodalZ[idx];
B[idx].Set(field[0], field[1], field[2]);
} // loop over nodal points: end
fParameters.fVertexFieldRegion.Set(B[0], z[0], B[1], z[1], B[2], z[2]);
fParameters.fVertexFieldValue = B[0];
fInitController.SetFlag(EInitKey::kPrimaryVertexField);
}
// --------------------------------------------------------------------------------------------------------------------
//
void InitManager::PushBackCAIteration(const Iteration& iteration)
{
// TODO: probably some checks must be inserted here (S.Zharko)
if (!fInitController.GetFlag(EInitKey::kCAIterationsNumberCrosscheck)) {
std::stringstream msg;
msg << "Attempt to push back a CA track finder iteration before the number of iterations was defined";
throw std::runtime_error(msg.str());
}
fParameters.fCAIterations.push_back(iteration);
}
// -------------------------------------------------------------------------------------------------------------------
//
void InitManager::ReadInputConfigs()
{
if (!fbConfigIsRead) {
LOG(info) << "ca::InitManager: reading parameter configuration ...";
try {
auto configReader = ConfigReader(this, 4);
configReader.SetMainConfigPath(fsConfigInputMain);
configReader.SetUserConfigPath(fsConfigInputUser);
configReader.SetGeometryLock(fbGeometryConfigLock);
configReader.Read();
fbConfigIsRead = true;
LOG(info) << "ca::InitManager: reading parameter configuration ... \033[1;32mdone\033[0m";
}
catch (const std::runtime_error& err) {
LOG(error) << "ca::InitManager: reading parameter configuration ... \033[1;31mfail\033[0m. Reason: "
<< err.what();
}
}
Sergei Zharko
committed
}
Sergei Zharko
committed
Sergei Zharko
committed
// -------------------------------------------------------------------------------------------------------------------
//
void InitManager::ReadGeometrySetup(const std::string& fileName)
{
// Open input binary file
this->SetGeometrySetup(cbm::algo::kf::SetupBuilder::Load<fvec>(fileName));
Sergei Zharko
committed
// -------------------------------------------------------------------------------------------------------------------
//
void InitManager::ReadParametersObject(const std::string& fileName)
{
using namespace constants;
// clrs::CL - end colored log
// clrs::GNb - bold green log
// clrs::RDb - bold red log
Sergei Zharko
committed
// Open input binary file
std::ifstream ifs(fileName, std::ios::binary);
if (!ifs) {
std::stringstream msg;
msg << "ca::InitManager: parameters data file \"" << clrs::GNb << fileName << clrs::CL << "\" was not found";
throw std::runtime_error(msg.str());
}
Sergei Zharko
committed
// Get L1InputData object
try {
boost::archive::binary_iarchive ia(ifs);
ia >> fParameters;
fbGeometryConfigLock = true;
}
catch (const std::exception&) {
std::stringstream msg;
msg << "ca::InitManager: parameters file \"" << clrs::GNb << fileName << clrs::CL
<< "\" has incorrect data format or was corrupted";
throw std::runtime_error(msg.str());
}
Sergei Zharko
committed
Sergei Zharko
committed
fInitController.SetFlag(EInitKey::kStationLayoutInitialized, true);
fInitController.SetFlag(EInitKey::kPrimaryVertexField, true);
fInitController.SetFlag(EInitKey::kSearchWindows, true);
Sergei Zharko
committed
}
Sergei Zharko
committed
// -------------------------------------------------------------------------------------------------------------------
//
void InitManager::ReadSearchWindows(const std::string& fileName)
{
// Open input binary file
std::ifstream ifs(fileName);
if (!ifs) {
std::stringstream msg;
msg << "ca::InitManager: search window file \"" << fileName << "\" was not found";
throw std::runtime_error(msg.str());
}
Sergei Zharko
committed
try {
boost::archive::text_iarchive ia(ifs);
int nPars = -1;
int nWindows = -1;
ia >> nPars;
assert(nPars == 1); // Currently only the constant windows are available
ia >> nWindows;
std::stringstream errMsg;
for (int iW = 0; iW < nWindows; ++iW) {
SearchWindow swBuffer;
ia >> swBuffer;
int iStationID = swBuffer.GetStationID();
int iTrackGrID = swBuffer.GetTrackGroupID();
if (iStationID < 0 || iStationID > constants::size::MaxNstations) {
errMsg << "\t- wrong station id for entry " << iW << ": " << iStationID << " (should be between 0 and "
<< constants::size::MaxNstations << ")\n";
}
if (iTrackGrID < 0 || iTrackGrID > constants::size::MaxNtrackGroups) {
errMsg << "\t- wrong track group id for entry " << iW << ": " << iTrackGrID << " (should be between 0 and "
<< constants::size::MaxNtrackGroups << ")\n";
}
fParameters.fSearchWindows[iTrackGrID * constants::size::MaxNstations + iStationID] = swBuffer;
Sergei Zharko
committed
if (errMsg.str().size()) {
std::stringstream msg;
msg << "ca::InitManager: some errors occurred while reading search windows: " << errMsg.str();
throw std::runtime_error(msg.str());
Sergei Zharko
committed
catch (const std::exception& err) {
std::stringstream msg;
Sergei Zharko
committed
msg << "search windows file \"" << fileName << "\" has incorrect data format or was corrupted. ";
msg << "Exception catched: " << err.what();
throw std::runtime_error(msg.str());
Sergei Zharko
committed
fInitController.SetFlag(EInitKey::kSearchWindows, true);
Sergei Zharko
committed
// --------------------------------------------------------------------------------------------------------------------
//
void InitManager::SetCAIterationsNumberCrosscheck(int nIterations)
{
fCAIterationsNumberCrosscheck = nIterations;
auto& iterationsContainer = fParameters.fCAIterations;
Sergei Zharko
committed
Sergei Zharko
committed
// NOTE: should be called to prevent multiple copies of objects between the memory reallocations
iterationsContainer.reserve(nIterations);
fInitController.SetFlag(EInitKey::kCAIterationsNumberCrosscheck);
Sergei Zharko
committed
}
Sergei Zharko
committed
// --------------------------------------------------------------------------------------------------------------------
//
void InitManager::SetFieldFunction(const FieldFunction_t& fieldFunction)
{
if (!fInitController.GetFlag(EInitKey::kFieldFunction)) {
fFieldFunction = fieldFunction;
fInitController.SetFlag(EInitKey::kFieldFunction);
}
else {
LOG(warn) << "ca::InitManager::SetFieldFunction: attempt to reinitialize the field function. Ignored";
}
Sergei Zharko
committed
// --------------------------------------------------------------------------------------------------------------------
//
void InitManager::SetGhostSuppression(int ghostSuppression)
{
if (fInitController.GetFlag(EInitKey::kGhostSuppression)) {
LOG(warn)
<< "ca::InitManager::SetGhostSuppression: attempt of reinitializating the ghost suppresion flag. Ignore";
return;
}
fParameters.fGhostSuppression = ghostSuppression;
fInitController.SetFlag(EInitKey::kGhostSuppression);
Sergei Zharko
committed
}
Sergei Zharko
committed
// --------------------------------------------------------------------------------------------------------------------
//
void InitManager::SetRandomSeed(unsigned int seed)
{
if (fInitController.GetFlag(EInitKey::kRandomSeed)) {
LOG(warn) << "ca::InitManager::SetRandomSeed: attempt of reinitializating the random seed. Ignore";
return;
Sergei Zharko
committed
fParameters.fRandomSeed = seed;
fInitController.SetFlag(EInitKey::kRandomSeed);
Sergei Zharko
committed
// --------------------------------------------------------------------------------------------------------------------
//
void InitManager::SetTargetPosition(double x, double y, double z)
{
if (fInitController.GetFlag(EInitKey::kTargetPos)) {
LOG(warn) << "ca::InitManager::SetTargetPosition: attempt to reinitialize the target position. Ignore";
return;
Sergei Zharko
committed
Sergei Zharko
committed
/// Fill fvec target fields
fParameters.fTargetPos[0] = x;
fParameters.fTargetPos[1] = y;
fParameters.fTargetPos[2] = z;
/// Set additional field for z component in double precision
fTargetZ = z;
fInitController.SetFlag(EInitKey::kTargetPos);
}
// --------------------------------------------------------------------------------------------------------------------
//
Parameters<fvec>&& InitManager::TakeParameters() { return std::move(fParameters); }
// --------------------------------------------------------------------------------------------------------------------
//
void InitManager::WriteParametersObject(const std::string& fileName) const
{
using constants::clrs::CL;
using constants::clrs::GNb;
// Open output binary file
std::ofstream ofs(fileName, std::ios::binary);
if (!ofs) {
std::stringstream msg;
Sergei Zharko
committed
msg << "ca::InitManager: failed opening file \"" << GNb << fileName << CL << "\" to write parameters object";
throw std::runtime_error(msg.str());
Sergei Zharko
committed
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
LOG(info) << "ca::InitManager: writing CA parameters object to file \"" << GNb << fileName << '\"' << CL;
// Serialize L1Parameters object and write
boost::archive::binary_oarchive oa(ofs);
oa << fParameters;
}
// --------------------------------------------------------------------------------------------------------------------
//
void InitManager::CheckCAIterationsInit()
{
bool ifInitPassed = true;
if (!fInitController.GetFlag(EInitKey::kCAIterations)) {
int nIterationsActual = fParameters.fCAIterations.size();
int nIterationsExpected = fCAIterationsNumberCrosscheck;
if (nIterationsActual != nIterationsExpected) {
LOG(warn) << "ca::InitManager::CheckCAIterations: incorrect number of iterations registered: "
<< nIterationsActual << " of " << nIterationsExpected << " expected";
ifInitPassed = false;
}
}
fInitController.SetFlag(EInitKey::kCAIterations, ifInitPassed);
}
// --------------------------------------------------------------------------------------------------------------------
// TODO: REWRITE! and add const qualifier (S.Zharko)
void InitManager::CheckStationsInfoInit()
{
bool ifInitPassed = true;
if (!fInitController.GetFlag(EInitKey::kStationsInfo)) {
// (1) Check the stations themselves
bool bStationsFinalized = std::all_of(fvStationInfo.begin(), fvStationInfo.end(),
[](const auto& st) { return st.GetInitController().IsFinalized(); });
if (!bStationsFinalized) {
std::stringstream msg;
msg << "ca::InitManager: At least one of the StationInitializer objects is not finalized";
}
// (2) Check for maximum allowed number of stations
if (fParameters.GetNstationsGeometry() > constants::size::MaxNstations) {
std::stringstream msg;
msg << "Actual total number of registered stations in geometry (" << fParameters.GetNstationsGeometry()
<< ") is larger then possible (" << constants::size::MaxNstations
<< "). Please, select another set of active tracking detectors or recompile the code with enlarged"
<< " constants::size::MaxNstations value";
throw std::runtime_error(msg.str());
}
}
fInitController.SetFlag(EInitKey::kStationsInfo, ifInitPassed);
}
// -------------------------------------------------------------------------------------------------------------------
//
void InitManager::ClearStationLayout()
{
fParameters.fvFirstGeoId.fill(0);
fParameters.fvLocalToGeoIdMap.fill(0);
fParameters.fvGeoToLocalIdMap.fill(std::make_pair(static_cast<EDetectorID>(0), -1));
fParameters.fvGeoToActiveMap.fill(-1); // Note: by default all the stations are inactive
fParameters.fvActiveToGeoMap.fill(0);
fParameters.fNstationsActiveTotal = -1;
fInitController.SetFlag(EInitKey::kStationLayoutInitialized, false);
}
Sergei Zharko
committed
} // namespace cbm::algo::ca