Newer
Older
/* Copyright (C) 2016-2021 GSI Helmholtzzentrum fuer Schwerionenforschung, Darmstadt
SPDX-License-Identifier: GPL-3.0-only
Authors: Sergey Gorbunov, Sergei Zharko [committer] */
/************************************************************************************************************
* @file L1InitManager.cxx
* @bried Input data management class for L1Algo
* @since 19.01.2022
***********************************************************************************************************/
#include "L1InitManager.h"
//-----------------------------------------------------------------------------------------------------------------------
//
L1InitManager::L1InitManager(L1Parameters* pParameters) : fpParameters(pParameters) {}
//-----------------------------------------------------------------------------------------------------------------------
//
void L1InitManager::AddStation(const L1BaseStationInfo& inStation)
{
// Check if other fields were defined already
// Active detector IDs
L1MASSERT(0, fInitController.GetFlag(InitKey::keActiveDetectorIDs),
"Attempt to add a station info before the active detetors set had been initialized");
L1MASSERT(0, fInitController.GetFlag(InitKey::keStationsNumberCrosscheck),
"Attempt to add a station info before the numbers of stations for each detector had been initialized");
L1MASSERT(0, fInitController.GetFlag(InitKey::keFieldFunction),
"Attempt to add a station info before the magnetic field function had been intialized");
// Check activeness of this station type
bool isDetectorActive = fActiveDetectorIDs.find(inStation.GetDetectorID()) != fActiveDetectorIDs.end();
if (isDetectorActive) {
// initialize magnetic field slice
L1BaseStationInfo inStationCopy = L1BaseStationInfo(inStation); // make a copy of station so it can be initialized
inStationCopy.SetFieldSlice(fFieldFunction);
LOG(debug) << "L1InitManager::AddStation:(original) L1BaseStationInfo "
<< inStation.GetInitController().ToString();
LOG(debug) << "L1InitManager::AddStation:(copy) L1BaseStationInfo "
<< inStation.GetInitController().ToString();
std::stringstream aStream;
aStream << "Attempt to add an incompletely initialized station info object (detectorID = "
<< static_cast<int>(inStationCopy.GetDetectorID()) << ", stationID = " << inStationCopy.GetStationID()
<< ")";
L1MASSERT(0, inStationCopy.GetInitController().IsFinalized(), aStream.str().c_str());
}
// insert the station in a set
auto insertionResult = fStationsInfo.insert(std::move(inStationCopy));
// Check insertion
{
std::stringstream aStream;
aStream << "Attempt to add a dublicating station info object (detectorID = "
<< static_cast<int>(inStationCopy.GetDetectorID()) << ", stationID = " << inStationCopy.GetStationID()
<< ")";
L1MASSERT(0, insertionResult.second, aStream.str().c_str());
LOG(debug) << "L1InitManager: adding a station with stationID = " << inStation.GetStationID()
<< " and detectorID = " << static_cast<int>(inStation.GetDetectorID())
<< ". Is active: " << isDetectorActive;
}
//-----------------------------------------------------------------------------------------------------------------------
//
void L1InitManager::CheckInit()
{
this->CheckCAIterationsInit();
this->CheckStationsInfoInit();
}
//-----------------------------------------------------------------------------------------------------------------------
//
int L1InitManager::GetStationsNumber(L1DetectorID detectorID) const
auto ifDetectorIdDesired = [&detectorID](const L1BaseStationInfo& station) {
return station.GetDetectorID() == detectorID;
};
return std::count_if(fStationsInfo.begin(), fStationsInfo.end(), ifDetectorIdDesired);
}
//-----------------------------------------------------------------------------------------------------------------------
//
void L1InitManager::InitTargetField(double zStep)
if (fInitController.GetFlag(InitKey::kePrimaryVertexField)) {
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(InitKey::keFieldFunction),
"Attempt to initialze the field value and field region near target before initializing field function");
// Check for target defined
L1MASSERT(
0, fInitController.GetFlag(InitKey::keTargetPos),
"Attempt to initialize the field value and field region near target before the target position initialization");
constexpr int nDimensions {3};
constexpr int nPointsNodal {3};
std::array<double, nPointsNodal> inputNodalZ {fTargetPos[2], fTargetPos[2] + zStep, fTargetPos[2] + 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
fTargetFieldRegion.Set(B[0], z[0], B[1], z[1], B[2], z[2]);
fTargetFieldValue = B[0];
fInitController.SetFlag(InitKey::kePrimaryVertexField);
//-----------------------------------------------------------------------------------------------------------------------
//
void L1InitManager::PrintCAIterations(int verbosityLevel) const
for (const auto& iteration : fpParameters->CAIterationsContainer()) {
iteration.Print(verbosityLevel);
//-----------------------------------------------------------------------------------------------------------------------
//
void L1InitManager::PrintStations(int verbosityLevel) const
for (const auto& station : fStationsInfo) {
station.Print(verbosityLevel);
//-----------------------------------------------------------------------------------------------------------------------
//
void L1InitManager::PushBackCAIteration(const L1CAIteration& iteration)
// TODO: probably some checks must be inserted here (S.Zharko)
bool control = fInitController.GetFlag(InitKey::keCAIterationsNumberCrosscheck);
//std::cout << "L1InitManager::PushBackCAIteration " << control << '\n';
L1MASSERT(0, control, //fInitController.GetFlag(InitKey::keCAIterationsNumberCrosscheck),
"Attempt to push back a CA track finder iteration before the number of iterations was defined");
L1Vector<L1CAIteration>& iterationsContainer = fpParameters->CAIterationsContainer();
iterationsContainer.push_back(iteration);
//-----------------------------------------------------------------------------------------------------------------------
//
void L1InitManager::SetActiveDetectorIDs(const L1DetectorIDSet_t& detectorIDs)
// TODO: To think about redifinition possibilities: should it be allowed or not? (S.Zh.)
fActiveDetectorIDs = detectorIDs;
fInitController.SetFlag(InitKey::keActiveDetectorIDs);
}
//-----------------------------------------------------------------------------------------------------------------------
//
void L1InitManager::SetCAIterationsNumberCrosscheck(int nIterations)
fCAIterationsNumberCrosscheck = nIterations;
L1Vector<L1CAIteration>& iterationsContainer = fpParameters->CAIterationsContainer();
// NOTE: should be called to prevent multiple copyings of objects between the memory realocations
iterationsContainer.reserve(nIterations);
fInitController.SetFlag(InitKey::keCAIterationsNumberCrosscheck);
}
//-----------------------------------------------------------------------------------------------------------------------
//
void L1InitManager::SetFieldFunction(const L1FieldFunction_t& fieldFunction)
if (!fInitController.GetFlag(InitKey::keFieldFunction)) {
fFieldFunction = fieldFunction;
fInitController.SetFlag(InitKey::keFieldFunction);
LOG(warn) << "L1InitManager::SetFieldFunction: attempt to reinitialize the field function. Ignored";
}
}
//-----------------------------------------------------------------------------------------------------------------------
//
void L1InitManager::SetStationsNumberCrosscheck(L1DetectorID detectorID, int nStations)
{
// 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()) {
fStationsNumberCrosscheck[detectorID] = nStations;
}
// Check if all the station numbers for active detectors are initialized now:
LOG(debug) << "SetStationsNumberCrosscheck called for detectorID = " << static_cast<int>(detectorID);
if (!fInitController.GetFlag(InitKey::keStationsNumberCrosscheck)) {
for (auto item : fActiveDetectorIDs) {
if (fStationsNumberCrosscheck.find(item) == fStationsNumberCrosscheck.end()) {
ifInitialized = false;
break;
}
}
fInitController.SetFlag(InitKey::keStationsNumberCrosscheck, ifInitialized);
//-----------------------------------------------------------------------------------------------------------------------
//
void L1InitManager::SetTargetPosition(double x, double y, double z)
if (fInitController.GetFlag(InitKey::keTargetPos)) {
LOG(warn) << "L1InitManager::SetTargetPosition: attempt to reinitialize the target position. Ignore";
return;
}
fTargetPos[0] = x;
fTargetPos[1] = y;
fTargetPos[2] = z;
fInitController.SetFlag(InitKey::keTargetPos);
}
//-----------------------------------------------------------------------------------------------------------------------
//
void L1InitManager::TransferL1StationArray(std::array<L1Station, L1Parameters::kMaxNstations>& destinationArray)
//
// 1) Check, if all fields of this were initialized
//
{
std::stringstream aStream;
aStream << "Attempt to pass L1Station array to L1Algo core before all necessary fields initialization\n"
<< "L1InitManager " << fInitController.ToString();
L1MASSERT(0, fInitController.IsFinalized(), aStream.str().c_str());
//
// 2) Check, if destinationArraySize is enough for the transfer
//
{
int nStationsTotal = this->GetStationsNumber();
std::stringstream aStream;
aStream << "Destination array size (" << destinationArray.size()
<< ") is smaller then the actual number of active tracking stations (" << nStationsTotal << ")";
L1MASSERT(0, nStationsTotal <= static_cast<int>(destinationArray.size()), aStream.str().c_str());
auto destinationArrayIterator = destinationArray.begin();
for (const auto& item : fStationsInfo) {
*destinationArrayIterator = std::move(item.GetL1Station());
++destinationArrayIterator;
LOG(info) << "L1InitManager: L1Station vector was successfully transfered to L1Algo core :)";
}
//
// INIT CHECKERS
//
//-----------------------------------------------------------------------------------------------------------------------
//
void L1InitManager::CheckCAIterationsInit()
{
//
// 1) Check number of iterations
//
bool ifInitPassed = true;
if (!fInitController.GetFlag(InitKey::keCAIterations)) {
int nIterationsActual = fpParameters->CAIterationsContainer().size();
int nIterationsExpected = fCAIterationsNumberCrosscheck;
if (nIterationsActual != nIterationsExpected) {
LOG(warn) << "L1InitManager::CheckCAIterations: incorrect number of iterations registered: " << nIterationsActual
<< " of " << nIterationsExpected << " expected";
ifInitPassed = false;
}
fInitController.SetFlag(InitKey::keCAIterations, ifInitPassed);
}
//-----------------------------------------------------------------------------------------------------------------------
// TODO: REWRITE! and add const qualifier (S.Zharko)
void L1InitManager::CheckStationsInfoInit()
bool ifInitPassed = true;
if (!fInitController.GetFlag(InitKey::keStationsInfo)) {
//
// 1) Check numbers of stations passed
//
// loop over active detectors
for (const auto& itemDetector : fActiveDetectorIDs) {
int nStationsActual = GetStationsNumber(itemDetector);
int nStationsExpected = fStationsNumberCrosscheck.at(itemDetector);
if (nStationsActual != nStationsExpected) {
LOG(error) << "L1InitManager::IsStationsInfoInitialized: Incorrect number of L1BaseStationInfo objects passed"
<< " to the L1Manager for L1DetectorID = " << static_cast<int>(itemDetector) << ": "
<< nStationsActual << " of " << nStationsExpected << " expected";
ifInitPassed = false;
} // loop over active detectors: end
L1MASSERT(0, ifInitPassed, "Station info initialization failed");
//
// 2) Check for maximum allowed number of stations
//
int nStationsTotal = GetStationsNumber();
if (nStationsTotal > L1Parameters::kMaxNstations) {
aStream << "Actual total number of registered stations (" << nStationsTotal << ") is larger then designed one ("
<< L1Parameters::kMaxNstations << "). Please, select another set of active tracking detectors";
// TODO: We have to provide an instruction of how to increase the kMaxNstations
// number keeping the code consistent (S.Zharko)
ifInitPassed = false;
fInitController.SetFlag(InitKey::keStationsInfo, ifInitPassed);