Newer
Older
/* Copyright (C) 2022 GSI Helmholtzzentrum fuer Schwerionenforschung, Darmstadt
SPDX-License-Identifier: GPL-3.0-only
Authors: Sergey Gorbunov, Sergei Zharko [committer] */
/// \file L1InitManager.cxx
/// \brief Input parameters management class for L1Algo
/// \since 19.01.2022
// ----------------------------------------------------------------------------------------------------------------------
//
void L1InitManager::AddStation(const L1BaseStationInfo& inStation)
{
// Check if other fields were defined already
// Active detector IDs
L1MASSERT(0, fInitController.GetFlag(EInitKey::kActiveDetectorIDs),
"Attempt to add a station info before the active detectors set had been initialized");
L1MASSERT(0, fInitController.GetFlag(EInitKey::kStationsNumberCrosscheck),
"Attempt to add a station info before the numbers of stations for each detector had been initialized");
L1MASSERT(0, fInitController.GetFlag(EInitKey::kFieldFunction),
"Attempt to add a station info before the magnetic field function had been initialized");
// Check activeness of this station type
bool isStationActive =
inStation.GetTrackingStatus() && fActiveDetectorIDs.find(inStation.GetDetectorID()) != fActiveDetectorIDs.end();
if (isStationActive) {
L1BaseStationInfo inStationCopy = L1BaseStationInfo(inStation); // make a copy of station so it can be initialized
inStationCopy.SetFieldFunction(fFieldFunction);
// check, if material map is used
if (!inStationCopy.GetInitController().GetFlag(L1BaseStationInfo::EInitKey::kThicknessMap)) {
LOG(warn) << "Station material map was not set for detectorID = "
<< static_cast<int>(inStationCopy.GetDetectorID()) << ", stationID = " << inStationCopy.GetStationID()
<< ". Homogeneous material budget will be used: " << inStationCopy.GetRadThick()[0];
L1Material material;
material.SetBins(1, 100);
material.SetRadThick(0, 0, inStationCopy.GetRadThick()[0]);
inStationCopy.SetMaterialMap(std::move(material));
}
LOG(debug) << "L1InitManager::AddStation:(original) L1BaseStationInfo " << inStation.GetInitController().ToString();
LOG(debug) << "L1InitManager::AddStation:(copy) L1BaseStationInfo " << inStation.GetInitController().ToString();
Sergei Zharko
committed
if (!inStationCopy.GetInitController().IsFinalized()) {
LOG(fatal) << "Attempt to add an incompletely initialized station info object (detectorID = "
<< static_cast<int>(inStationCopy.GetDetectorID()) << ", stationID = " << inStationCopy.GetStationID()
<< ")";
}
// insert the station in a set
auto insertionResult = fStationsInfo.insert(std::move(inStationCopy));
Sergei Zharko
committed
if (!insertionResult.second) {
LOG(fatal) << "Attempt to add a duplicated station info object (detectorID = "
Sergei Zharko
committed
<< static_cast<int>(inStationCopy.GetDetectorID()) << ", stationID = " << inStationCopy.GetStationID()
<< ")";
Sergei Zharko
committed
int index = fStationsInfo.size() - 1 + fParameters.fNstationsGeometryTotal - fParameters.fNstationsActiveTotal;
Sergei Zharko
committed
fParameters.fActiveStationGlobalIDs[index] = fStationsInfo.size() - 1;
int index = fStationsInfo.size() + fParameters.fNstationsGeometryTotal - fParameters.fNstationsActiveTotal;
Sergei Zharko
committed
fParameters.fActiveStationGlobalIDs[index] = -1;
fParameters.fNstationsActive[static_cast<L1DetectorID_t>(inStation.GetDetectorID())]--;
fParameters.fNstationsActiveTotal--;
LOG(debug) << "L1InitManager: adding a station with stationID = " << inStation.GetStationID()
<< " and detectorID = " << static_cast<int>(inStation.GetDetectorID())
<< ". Is active: " << isStationActive;
// ----------------------------------------------------------------------------------------------------------------------
void L1InitManager::CheckInit()
{
this->CheckCAIterationsInit();
this->CheckStationsInfoInit();
// ----------------------------------------------------------------------------------------------------------------------
//
void L1InitManager::ClearCAIterations()
{
fParameters.fCAIterations.clear();
fCAIterationsNumberCrosscheck = -1;
fInitController.SetFlag(EInitKey::kCAIterations, false);
}
// ----------------------------------------------------------------------------------------------------------------------
// NOTE: this function should be called once in the SendParameters
Sergei Zharko
committed
void L1InitManager::FormParametersContainer()
{
// Read configuration file
// NOTE: We consider parameters from the configuration file as ones with a higher priority, so all the defined
// variables there would be rewritten by the configuration
if (fConfigInputName != "") { fConfigRW.ReadYaml(fConfigInputName); }
Sergei Zharko
committed
// Check initialization
this->CheckInit();
Sergei Zharko
committed
if (!fInitController.IsFinalized()) {
LOG(fatal) << "Attempt to form parameters container before all necessary fields were initialized"
<< fInitController.ToString();
}
// Form array of stations
auto destinationArrayIterator = fParameters.fStations.begin();
for (const auto& item : fStationsInfo) {
*destinationArrayIterator = item.GetL1Station();
++destinationArrayIterator;
}
// Form array of material map
auto thickMapIt = fParameters.fThickMap.begin();
for (auto it = fStationsInfo.begin(); it != fStationsInfo.end(); ++it) {
auto node = fStationsInfo.extract(it);
Sergei Zharko
committed
*thickMapIt = std::move(node.value().TakeMaterialMap());
fStationsInfo.insert(std::move(node));
++thickMapIt;
}
Sergei Zharko
committed
// Check the consistency of the parameters object. If object inconsistent, it throws std::logic_error
fParameters.CheckConsistency();
Sergei Zharko
committed
}
// ----------------------------------------------------------------------------------------------------------------------
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);
//std::cout << "L1InitManager::PushBackCAIteration " << control << '\n';
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);
// ---------------------------------------------------------------------------------------------------------------------
//
bool L1InitManager::SendParameters(L1Algo* pAlgo)
{
// Form parameters cotainer
this->FormParametersContainer();
assert(pAlgo);
pAlgo->ReceiveParameters(std::move(fParameters));
return true;
}
// ----------------------------------------------------------------------------------------------------------------------
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::SetMomentumCutOff(float momentumCutOff)
{
if (fInitController.GetFlag(EInitKey::kMomentumCutOff)) {
Sergei Zharko
committed
LOG(warn) << "L1InitManager::SetMomentumCutOff: attempt of reinitializating the momentum cutoff value. Ignore";
return;
}
fParameters.fMomentumCutOff = momentumCutOff;
fInitController.SetFlag(EInitKey::kMomentumCutOff);
Sergei Zharko
committed
}
// ----------------------------------------------------------------------------------------------------------------------
void L1InitManager::SetNstations(L1DetectorID detectorID, int nStations)
L1MASSERT(0, fInitController.GetFlag(EInitKey::kActiveDetectorIDs),
"Attempt to set crosscheck number of stations before the active detetors set had been initialized");
// NOTE: We add and check only those detectors which will be active (?)
// For INACTIVE detectors the initialization code for it inside CbmL1/BmnL1 can (and must) be still in,
// but it will be ignored inside L1InitManager.
if (fActiveDetectorIDs.find(detectorID) != fActiveDetectorIDs.end()) {
if (nStations) {
fParameters.fNstationsGeometry[static_cast<L1DetectorID_t>(detectorID)] = nStations;
fParameters.fNstationsActive[static_cast<L1DetectorID_t>(detectorID)] = nStations;
else {
// TODO: Probably it is better to replace fatal with warn and remove the detectorID from active detectors (S.Zharko)
LOG(fatal) << "L1InitManager::SetNstations: attempt to initialize zero stations for active detector: "
<< static_cast<L1DetectorID_t>(detectorID);
// Check if all the station numbers for active detectors are initialized now:
LOG(debug) << "L1InitManager::SetNstations called for detectorID = " << static_cast<int>(detectorID);
if (!fInitController.GetFlag(EInitKey::kStationsNumberCrosscheck)) {
for (auto item : fActiveDetectorIDs) {
if (fParameters.fNstationsGeometry[static_cast<L1DetectorID_t>(item)] == 0) {
ifInitialized = false;
break;
}
}
fInitController.SetFlag(EInitKey::kStationsNumberCrosscheck, ifInitialized);
}
if (fInitController.GetFlag(EInitKey::kStationsNumberCrosscheck)) {
fParameters.fNstationsGeometryTotal =
std::accumulate(fParameters.fNstationsGeometry.begin(), fParameters.fNstationsGeometry.end(), 0);
fParameters.fNstationsActiveTotal = fParameters.fNstationsGeometryTotal;
// ----------------------------------------------------------------------------------------------------------------------
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::SetTrackingLevel(int trackingLevel)
{
if (fInitController.GetFlag(EInitKey::kTrackingLevel)) {
Sergei Zharko
committed
LOG(warn) << "L1InitManager::SetTrackingLevel: attempt of reinitialization the tracking level. Ignore";
return;
}
fParameters.fTrackingLevel = trackingLevel;
fInitController.SetFlag(EInitKey::kTrackingLevel);
Sergei Zharko
committed
}
//
// INIT CHECKERS
//
// ----------------------------------------------------------------------------------------------------------------------
//
void L1InitManager::CheckCAIterationsInit()
{
//
// 1) Check number of iterations
//
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)) {
//
// 1) Check numbers of stations passed
//
// loop over active detectors
for (auto itemDetector : fActiveDetectorIDs) {
auto selectDetector = [&itemDetector](const L1BaseStationInfo& station) {
return station.GetDetectorID() == itemDetector;
};
int nStationsExpected = GetNstationsActive(itemDetector);
int nStations = std::count_if(fStationsInfo.begin(), fStationsInfo.end(), selectDetector);
if (nStations != nStationsExpected) {
LOG(error) << "L1InitManager::CheckStationsInfoInit: Incorrect number of L1BaseStationInfo objects passed"
<< " to the L1Manager for L1DetectorID = " << static_cast<int>(itemDetector) << ": " << nStations
<< " of " << nStationsExpected << " expected";
} // loop over active detectors: end
L1MASSERT(0, ifInitPassed, "Station info initialization failed");
//
// 2) Check for maximum allowed number of stations
//
int nStationsTotal = fParameters.fNstationsGeometryTotal;
Sergei Zharko
committed
if (nStationsTotal > L1Constants::size::kMaxNstations) {
Sergei Zharko
committed
LOG(fatal) << "Actual total number of registered stations in geometry (" << nStationsTotal
<< ") 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";
Sergei Zharko
committed
fInitController.SetFlag(EInitKey::kStationsInfo, ifInitPassed);