Newer
Older
/* Copyright (C) 2022 GSI Helmholtzzentrum fuer Schwerionenforschung, Darmstadt
SPDX-License-Identifier: GPL-3.0-only
Authors: Sergey Gorbunov, Sergei Zharko [committer] */
Sergei Zharko
committed
/// \file L1InitManager.cxx
/// \brief Input parameters management class for L1Algo
/// \since 19.01.2022
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
using L1Constants::clrs::kCL; // end colored log
using L1Constants::clrs::kGNb; // bold green log
using L1Constants::clrs::kRDb; // bold red log
// ----------------------------------------------------------------------------------------------------------------------
//
void L1InitManager::AddStation(const L1BaseStationInfo& inStation)
{
Sergei Zharko
committed
// TODO: SZh 15.08.2023: Replace L1MASSERT with throw logic_error
L1MASSERT(0, fInitController.GetFlag(EInitKey::kActiveDetectorIDs),
"Attempt to add a station info before the active detectors set had been initialized");
Sergei Zharko
committed
// Check, if the detector subsystem for this station is active
if (fActiveDetectorIDs.find(inStation.GetDetectorID()) != fActiveDetectorIDs.end()) {
fvStationInfo.push_back(inStation);
// ----------------------------------------------------------------------------------------------------------------------
void L1InitManager::CheckInit()
{
this->CheckCAIterationsInit();
this->CheckStationsInfoInit();
Sergei Zharko
committed
// ----------------------------------------------------------------------------------------------------------------------
//
void L1InitManager::ClearSetupInfo()
{
// Clear stations set and a thickness map
Sergei Zharko
committed
fvStationInfo.clear();
fParameters.fThickMap.fill(L1Material());
Sergei Zharko
committed
fInitController.SetFlag(EInitKey::kStationsInfo, false);
// Set number of stations do default values
this->ClearStationLayout();
Sergei Zharko
committed
// Clear active detectors
fActiveDetectorIDs.clear();
fInitController.SetFlag(EInitKey::kActiveDetectorIDs, false);
// Clear field info
fParameters.fVertexFieldRegion = L1FieldRegion();
fParameters.fVertexFieldValue = L1FieldValue();
fInitController.SetFlag(EInitKey::kPrimaryVertexField, false);
// Clear target position
fParameters.fTargetPos.fill(L1Utils::kNaN);
Sergei Zharko
committed
fTargetZ = 0.;
fInitController.SetFlag(EInitKey::kTargetPos, false);
// Clear field function
fFieldFunction = L1FieldFunction_t([](const double(&)[3], double(&)[3]) {});
fInitController.SetFlag(EInitKey::kFieldFunction, false);
// Clear other flags
fParameters.fRandomSeed = 1;
Sergei Zharko
committed
fParameters.fGhostSuppression = 0;
fInitController.SetFlag(EInitKey::kRandomSeed, false);
Sergei Zharko
committed
fInitController.SetFlag(EInitKey::kGhostSuppression, false);
fParameters.fDevIsIgnoreHitSearchAreas = false;
fParameters.fDevIsUseOfOriginalField = false;
fParameters.fDevIsMatchDoubletsViaMc = false;
fParameters.fDevIsMatchTripletsViaMc = false;
fParameters.fDevIsExtendTracksViaMc = false;
fParameters.fDevIsSuppressOverlapHitsViaMc = false;
Sergei Zharko
committed
}
// ----------------------------------------------------------------------------------------------------------------------
//
void L1InitManager::ClearCAIterations()
{
fParameters.fCAIterations.clear();
fCAIterationsNumberCrosscheck = -1;
fInitController.SetFlag(EInitKey::kCAIterations, false);
Sergei Zharko
committed
fInitController.SetFlag(EInitKey::kCAIterationsNumberCrosscheck, false);
}
// ----------------------------------------------------------------------------------------------------------------------
// NOTE: this function should be called once in the SendParameters
Sergei Zharko
committed
bool L1InitManager::FormParametersContainer()
Sergei Zharko
committed
{
// Read configuration files
LOG(info) << "L1InitManager: reading parameter configuration ...";
try {
fConfigRW.Read();
LOG(info) << "L1InitManager: reading parameter configuration ... \033[1;32mdone\033[0m";
}
catch (const std::runtime_error& err) {
LOG(error) << "L1InitManager: reading parameter configuration ... \033[1;31mfail\033[0m. Reason: " << err.what();
return false;
if (!fParameters.fDevIsParSearchWUsed) { fInitController.SetFlag(EInitKey::kSearchWindows, true); }
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) << "L1InitManager: Attempt to form parameters container before all necessary fields were initialized"
Sergei Zharko
committed
<< fInitController.ToString();
Sergei Zharko
committed
}
Sergei Zharko
committed
{ // Form array of stations
auto destIt = fParameters.fStations.begin();
for (const auto& station : fvStationInfo) {
if (!station.GetTrackingStatus()) { continue; }
*destIt = station.GetL1Station();
++destIt;
}
Sergei Zharko
committed
}
Sergei Zharko
committed
{ // Form array of material map
auto destIt = fParameters.fThickMap.begin();
for (auto& station : fvStationInfo) {
if (!station.GetTrackingStatus()) { continue; }
*destIt = std::move(station.TakeMaterialMap());
++destIt;
}
Sergei Zharko
committed
}
Sergei Zharko
committed
// Check the consistency of the parameters object. If object inconsistent, it throws std::logic_error
Sergei Zharko
committed
try {
fParameters.CheckConsistency();
}
catch (const std::logic_error& err) {
LOG(error) << "L1InitManager: parameters container consistency check failed. Reason: " << err.what();
return false;
}
return true;
Sergei Zharko
committed
}
Sergei Zharko
committed
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
// ----------------------------------------------------------------------------------------------------------------------
//
int L1InitManager::GetNstationsActive() const
{
LOG_IF(fatal, !fInitController.GetFlag(EInitKey::kStationLayoutInitialized))
<< "L1InitManager: number of active stations cannot be accessed until the station layout is initialized";
return fParameters.GetNstationsActive();
}
// ----------------------------------------------------------------------------------------------------------------------
//
int L1InitManager::GetNstationsActive(L1DetectorID detectorID) const
{
LOG_IF(fatal, !fInitController.GetFlag(EInitKey::kStationLayoutInitialized))
<< "L1InitManager: number of active stations cannot be accessed until the station layout is initialized";
return fParameters.GetNstationsActive(detectorID);
}
// ----------------------------------------------------------------------------------------------------------------------
//
int L1InitManager::GetNstationsGeometry() const
{
LOG_IF(fatal, !fInitController.GetFlag(EInitKey::kStationLayoutInitialized))
<< "L1InitManager: number of geometry stations cannot be accessed until the station layout is initialized";
return fParameters.GetNstationsGeometry();
}
// ----------------------------------------------------------------------------------------------------------------------
//
int L1InitManager::GetNstationsGeometry(L1DetectorID detectorID) const
{
LOG_IF(fatal, !fInitController.GetFlag(EInitKey::kStationLayoutInitialized))
<< "L1InitManager: number of geometry stations cannot be accessed until the station layout is initialized";
return fParameters.GetNstationsGeometry(detectorID);
}
// ----------------------------------------------------------------------------------------------------------------------
//
std::vector<L1BaseStationInfo>& L1InitManager::GetStationInfo()
{
LOG_IF(fatal, !fInitController.GetFlag(EInitKey::kStationLayoutInitialized))
<< "L1InitManager: station info container cannot be accessed until the station layout is initialized";
return fvStationInfo;
}
// ----------------------------------------------------------------------------------------------------------------------
//
void L1InitManager::InitStationLayout()
{
this->ClearStationLayout();
Sergei Zharko
committed
std::sort(fvStationInfo.begin(), fvStationInfo.end());
for (const auto& aStation : fvStationInfo) {
++fParameters.fvFirstGeoId[static_cast<int>(aStation.GetDetectorID()) + 1];
}
for (int iDet = 1; iDet < static_cast<int>(fParameters.fvFirstGeoId.size()); ++iDet) {
fParameters.fvFirstGeoId[iDet + 1] += fParameters.fvFirstGeoId[iDet];
}
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);
Sergei Zharko
committed
// 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);
}
// ----------------------------------------------------------------------------------------------------------------------
void L1InitManager::InitTargetField(double zStep)
if (fInitController.GetFlag(EInitKey::kPrimaryVertexField)) {
LOG(warn) << "L1InitManager::InitTargetField: attempt to reinitialize the field value and field region "
<< "near target. Ignore";
return;
// Check for field function
L1MASSERT(0, fInitController.GetFlag(EInitKey::kFieldFunction),
"Attempt to initialize the field value and field region near target before initializing field function");
// Check for target defined
0, fInitController.GetFlag(EInitKey::kTargetPos),
"Attempt to initialize the field value and field region near target before the target position initialization");
constexpr int nDimensions {3};
constexpr int nPointsNodal {3};
Sergei Zharko
committed
std::array<double, nPointsNodal> inputNodalZ {fTargetZ, fTargetZ + zStep, fTargetZ + 2. * zStep};
std::array<L1FieldValue, 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].x = field[0];
B[idx].y = field[1];
B[idx].z = field[2];
} // loop over nodal points: end
Sergei Zharko
committed
fParameters.fVertexFieldRegion.Set(B[0], z[0], B[1], z[1], B[2], z[2]);
fParameters.fVertexFieldValue = B[0];
fInitController.SetFlag(EInitKey::kPrimaryVertexField);
// ----------------------------------------------------------------------------------------------------------------------
void L1InitManager::PushBackCAIteration(const L1CAIteration& iteration)
// TODO: probably some checks must be inserted here (S.Zharko)
bool control = fInitController.GetFlag(EInitKey::kCAIterationsNumberCrosscheck);
L1MASSERT(0, control, //fInitController.GetFlag(EInitKey::kCAIterationsNumberCrosscheck),
"Attempt to push back a CA track finder iteration before the number of iterations was defined");
Sergei Zharko
committed
fParameters.fCAIterations.push_back(iteration);
// ---------------------------------------------------------------------------------------------------------------------
//
Sergei Zharko
committed
void L1InitManager::ReadParametersObject(const std::string& fileName)
Sergei Zharko
committed
// Open input binary file
Sergei Zharko
committed
std::ifstream ifs(fileName, std::ios::binary);
if (!ifs) { LOG(fatal) << "L1InitManager: parameters data file \"" << kGNb << fileName << kCL << "\" was not found"; }
Sergei Zharko
committed
// Get L1InputData object
try {
Sergei Zharko
committed
boost::archive::binary_iarchive ia(ifs);
Sergei Zharko
committed
ia >> fParameters;
}
catch (const std::exception&) {
Sergei Zharko
committed
LOG(fatal) << "L1InitManager: parameters file \"" << kGNb << fileName << kCL
<< "\" has incorrect data format or was corrupted";
Sergei Zharko
committed
}
}
// ---------------------------------------------------------------------------------------------------------------------
//
void L1InitManager::ReadSearchWindows(const std::string& fileName)
{
// Open input binary file
std::ifstream ifs(fileName);
if (!ifs) { LOG(fatal) << "L1InitManager: search window file \"" << fileName << "\" was not found"; }
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
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
ia >> nWindows;
std::stringstream errMsg;
for (int iW = 0; iW < nWindows; ++iW) {
L1SearchWindow swBuffer;
ia >> swBuffer;
int iStationID = swBuffer.GetStationID();
int iTrackGrID = swBuffer.GetTrackGroupID();
if (iStationID < 0 || iStationID > L1Constants::size::kMaxNstations) {
errMsg << "\t- wrong station id for entry " << iW << ": " << iStationID << " (should be between 0 and "
<< L1Constants::size::kMaxNstations << ")\n";
}
if (iTrackGrID < 0 || iTrackGrID > L1Constants::size::kMaxNtrackGroups) {
errMsg << "\t- wrong track group id for entry " << iW << ": " << iTrackGrID << " (should be between 0 and "
<< L1Constants::size::kMaxNtrackGroups << ")\n";
}
fParameters.fSearchWindows[iTrackGrID * L1Constants::size::kMaxNstations + iStationID] = swBuffer;
}
if (errMsg.str().size()) {
LOG(fatal) << "L1InitManager: some errors occurred while reading search windows: " << errMsg.str();
}
}
catch (const std::exception&) {
LOG(fatal) << "L1InitManager: search windows file \"" << fileName
<< "\" has incorrect data format or was corrupted";
}
fInitController.SetFlag(EInitKey::kSearchWindows, true);
}
Sergei Zharko
committed
// ---------------------------------------------------------------------------------------------------------------------
//
bool L1InitManager::SendParameters(L1Algo* pAlgo)
{
assert(pAlgo);
pAlgo->ReceiveParameters(std::move(fParameters));
Sergei Zharko
committed
LOG(info) << "L1InitManager: parameters object was sent to the tracking algorithm";
return true;
}
// ---------------------------------------------------------------------------------------------------------------------
//
bool L1InitManager::SendParameters(L1Parameters& destination)
{
destination = std::move(fParameters);
LOG(info) << "L1InitManager: parameters object was sent to an external destination";
// ----------------------------------------------------------------------------------------------------------------------
void L1InitManager::SetActiveDetectorIDs(const L1DetectorIDSet_t& detectorIDs)
// TODO: To think about redefinition possibilities: should it be allowed or not? (S.Zh.)
fActiveDetectorIDs = detectorIDs;
fInitController.SetFlag(EInitKey::kActiveDetectorIDs);
// ----------------------------------------------------------------------------------------------------------------------
void L1InitManager::SetCAIterationsNumberCrosscheck(int nIterations)
fCAIterationsNumberCrosscheck = nIterations;
Sergei Zharko
committed
L1Vector<L1CAIteration>& iterationsContainer = fParameters.fCAIterations;
// NOTE: should be called to prevent multiple copies of objects between the memory reallocations
iterationsContainer.reserve(nIterations);
fInitController.SetFlag(EInitKey::kCAIterationsNumberCrosscheck);
// ----------------------------------------------------------------------------------------------------------------------
void L1InitManager::SetFieldFunction(const L1FieldFunction_t& fieldFunction)
if (!fInitController.GetFlag(EInitKey::kFieldFunction)) {
fFieldFunction = fieldFunction;
fInitController.SetFlag(EInitKey::kFieldFunction);
LOG(warn) << "L1InitManager::SetFieldFunction: attempt to reinitialize the field function. Ignored";
// ----------------------------------------------------------------------------------------------------------------------
Sergei Zharko
committed
//
void L1InitManager::SetGhostSuppression(int ghostSuppression)
{
if (fInitController.GetFlag(EInitKey::kGhostSuppression)) {
Sergei Zharko
committed
LOG(warn) << "L1InitManager::SetGhostSuppression: attempt of reinitializating the ghost suppresion flag. Ignore";
return;
}
fParameters.fGhostSuppression = ghostSuppression;
fInitController.SetFlag(EInitKey::kGhostSuppression);
Sergei Zharko
committed
}
// ----------------------------------------------------------------------------------------------------------------------
Sergei Zharko
committed
//
void L1InitManager::SetRandomSeed(unsigned int seed)
Sergei Zharko
committed
{
if (fInitController.GetFlag(EInitKey::kRandomSeed)) {
LOG(warn) << "L1InitManager::SetRandomSeed: attempt of reinitializating the random seed. Ignore";
Sergei Zharko
committed
return;
}
fParameters.fRandomSeed = seed;
fInitController.SetFlag(EInitKey::kRandomSeed);
Sergei Zharko
committed
}
// ----------------------------------------------------------------------------------------------------------------------
void L1InitManager::SetTargetPosition(double x, double y, double z)
if (fInitController.GetFlag(EInitKey::kTargetPos)) {
LOG(warn) << "L1InitManager::SetTargetPosition: attempt to reinitialize the target position. Ignore";
return;
}
/// Fill fvec target fields
Sergei Zharko
committed
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);
Sergei Zharko
committed
// ----------------------------------------------------------------------------------------------------------------------
//
void L1InitManager::WriteParametersObject(const std::string& fileName) const
{
// Open output binary file
std::ofstream ofs(fileName, std::ios::binary);
if (!ofs) {
Sergei Zharko
committed
LOG(error) << "L1InitManager: failed opening file \"" << kGNb << fileName << kCL << "\" to write parameters object";
Sergei Zharko
committed
return;
}
Sergei Zharko
committed
LOG(info) << "L1InitManager: writing CA parameters object to file \"" << kGNb << fileName << '\"' << kCL;
Sergei Zharko
committed
// Serialize L1Parameters object and write
boost::archive::binary_oarchive oa(ofs);
oa << fParameters;
}
//
// INIT CHECKERS
//
// ----------------------------------------------------------------------------------------------------------------------
//
void L1InitManager::CheckCAIterationsInit()
{
bool ifInitPassed = true;
if (!fInitController.GetFlag(EInitKey::kCAIterations)) {
Sergei Zharko
committed
int nIterationsActual = fParameters.fCAIterations.size();
int nIterationsExpected = fCAIterationsNumberCrosscheck;
if (nIterationsActual != nIterationsExpected) {
LOG(warn) << "L1InitManager::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 L1InitManager::CheckStationsInfoInit()
if (!fInitController.GetFlag(EInitKey::kStationsInfo)) {
Sergei Zharko
committed
// (1) Check the stations themselves
bool bStationsFinalized = std::all_of(fvStationInfo.begin(), fvStationInfo.end(),
[](const auto& st) { return st.GetInitController().IsFinalized(); });
if (!bStationsFinalized) { LOG(fatal) << "At least one of the L1BaseStationInfo objects is not finalized"; }
// (2) Check for maximum allowed number of stations
if (fParameters.GetNstationsGeometry() > L1Constants::size::kMaxNstations) {
LOG(fatal) << "Actual total number of registered stations in geometry (" << fParameters.GetNstationsGeometry()
Sergei Zharko
committed
<< ") is larger then possible (" << L1Constants::size::kMaxNstations
<< "). Please, select another set of active tracking detectors or recompile the code with enlarged"
<< " L1Constants::size::kMaxNstations value";
fInitController.SetFlag(EInitKey::kStationsInfo, ifInitPassed);
// ---------------------------------------------------------------------------------------------------------------------
//
void L1InitManager::ClearStationLayout()
{
fParameters.fvFirstGeoId.fill(0);
fParameters.fvLocalToGeoIdMap.fill(0);
fParameters.fvGeoToLocalIdMap.fill(std::make_pair(static_cast<L1DetectorID>(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);
}