diff --git a/core/detectors/tof/CbmTofCreateDigiPar.cxx b/core/detectors/tof/CbmTofCreateDigiPar.cxx index 5114d18495532a78e9cd68aab5704a2fa489ecaf..94849055d9038be501f7dbdcd014b5e7da0e13bd 100644 --- a/core/detectors/tof/CbmTofCreateDigiPar.cxx +++ b/core/detectors/tof/CbmTofCreateDigiPar.cxx @@ -147,8 +147,8 @@ InitStatus CbmTofCreateDigiPar::Init() gGeoManager->FindNode(fChannelInfo->GetX(), fChannelInfo->GetY(), fChannelInfo->GetZ()); TGeoNode* tGeoNode = gGeoManager->GetCurrentNode(); nodemap.insert(std::pair<Int_t, TGeoNode*>(iAddr, tGeoNode)); - LOG(debug) << Form("Digipar for %d, addr 0x%08x: Node=%p, x %6.2f, y %6.2f, z %6.2f ", iCell, iAddr, tGeoNode, - fChannelInfo->GetX(), fChannelInfo->GetY(), fChannelInfo->GetZ()); + LOG(debug2) << Form("Digipar for %d, addr 0x%08x: Node=%p, x %6.2f, y %6.2f, z %6.2f ", iCell, iAddr, tGeoNode, + fChannelInfo->GetX(), fChannelInfo->GetY(), fChannelInfo->GetZ()); } fDigiPar->SetNodeMap(nodemap); diff --git a/reco/L1/CMakeLists.txt b/reco/L1/CMakeLists.txt index 2740dfcbd1b2b9009e11f518206685a81e331f69..10f7756defcb531c9980bca17fe1b0dd5abdc7db 100644 --- a/reco/L1/CMakeLists.txt +++ b/reco/L1/CMakeLists.txt @@ -270,6 +270,7 @@ Install(FILES CbmL1Counters.h L1Algo/L1TrackParFit.h L1Algo/L1Triplet.h L1Algo/L1Vector.h + L1Algo/L1ObjectInitController.h L1Algo/L1MaterialInfo.h L1Algo/L1UMeasurementInfo.h L1Algo/L1XYMeasurementInfo.h diff --git a/reco/L1/CbmL1.cxx b/reco/L1/CbmL1.cxx index d04bafadd323f47662b808c890a5a767775f475f..4f7590f2037cf6ae96852714043ff3b0905ed921 100644 --- a/reco/L1/CbmL1.cxx +++ b/reco/L1/CbmL1.cxx @@ -808,7 +808,7 @@ InitStatus CbmL1::Init() LOG(error) << "-E- CbmL1: Read geometry from file " << fSTAPDataDir + "geo_algo.txt was NOT successful."; } - algo->SetL1Parameters(fL1Parameters); + //algo->SetParameters(fParameters); #ifdef FEATURING_L1ALGO_INIT @@ -818,7 +818,7 @@ InitStatus CbmL1::Init() { //L1Algo new init start // Step 0: Get reference to the L1Algo initialization manager - L1InitManager* initMan = algo->GetL1InitManager(); + L1InitManager* initMan = algo->GetInitManager(); // Step 1: Initialize magnetic field function // Set magnetic field slices @@ -970,7 +970,7 @@ InitStatus CbmL1::Init() fscal tofBackSigma = 1.; stationInfo.SetFrontBackStripsGeometry(tofFrontPhi, tofFrontSigma, tofBackPhi, tofBackSigma); } - initMan->PrintStations(/*vebosity = */ 1); + //initMan->PrintStations(/*vebosity = */ 1); // Step 7: initialize iterations and form a vector of them { @@ -1088,7 +1088,6 @@ InitStatus CbmL1::Init() initMan->PushBackCAIteration(trackingIterAllSec); } else { - std::cout << "HERE"; initMan->SetCAIterationsNumberCrosscheck(9); // Initialize CA track finder iterations sequence initMan->PushBackCAIteration(trackingIterFastPrim); @@ -1101,7 +1100,6 @@ InitStatus CbmL1::Init() initMan->PushBackCAIteration(trackingIterFastPrim2); initMan->PushBackCAIteration(trackingIterAllSecJump); } - initMan->PrintCAIterations(); // Set special cuts } diff --git a/reco/L1/CbmL1.h b/reco/L1/CbmL1.h index 30f6ded6cf850fcc4ca5343389e99aabb8da296b..f40650d36119c34c80be3dd457b27a27a46baf3d 100644 --- a/reco/L1/CbmL1.h +++ b/reco/L1/CbmL1.h @@ -118,7 +118,8 @@ enum class L1CAIterationType // /// L1Algo runtime constants modification can be performed in run_reco.C. Example: /// -/// l1->GetL1Parameters()->SetMaxDoubletsPerSinglet(149); +/// l1->GetInitManager()->GetParameters()->SetMaxDoubletsPerSinglet(149); +/// TODO: L1InitManager - main interface of communication between cbmroot/bmnroot and L1Algo (S.Zharko) /// class CbmL1 : public FairTask { private: @@ -157,7 +158,7 @@ public: ~CbmL1(/*if (targetFieldSlice) delete;*/); - L1Parameters* GetL1Parameters() { return &fL1Parameters; } + //L1Parameters* GetParameters() { return &fParameters; } /// Gets a set of active detectors used in tracking // TODO: think about return (value, reference or const reference?) (S.Zh.) @@ -272,7 +273,8 @@ public: private: static CbmL1* fInstance; - L1Parameters fL1Parameters; + + L1InitManager* fpInitManager {nullptr}; ///< Pointer to L1InitManager object of L1 algorithm core std::set<L1DetectorID> fActiveTrackingDetectorIDs {L1DetectorID::kMvd, L1DetectorID::kSts}; ///< Set of detectors active in tracking diff --git a/reco/L1/L1Algo/L1Algo.cxx b/reco/L1/L1Algo/L1Algo.cxx index 0fd6b67e52ce42ccbdecdf80357a5721894cfe07..bebda2986c90a210e4d5296f66fc92760045e07d 100644 --- a/reco/L1/L1Algo/L1Algo.cxx +++ b/reco/L1/L1Algo/L1Algo.cxx @@ -61,8 +61,6 @@ void L1Algo::SetNThreads(unsigned int n) void L1Algo::Init(const L1Vector<fscal>& geo, const bool UseHitErrors, const TrackingMode mode, const bool MissingHits) { - fL1Parameters.Print(); // TODO: Wrap this line into debug (S.Zh.) - for (int iProc = 0; iProc < 4; iProc++) { for (int i = 0; i < 8; i++) { threadNumberToCpuMap[2 * i + 0 + iProc * 20] = 4 * i + iProc; @@ -231,12 +229,19 @@ void L1Algo::Init(const L1Vector<fscal>& geo, const bool UseHitErrors, const Tra // NEW INITIALIZATION (BETA) // + // Final init checks (the function provides purity of fields initialization and turn on the last bits of + // the L1ObjectInitController): + fInitManager.CheckInit(); // NOTE: after passing this frontier L1Algo is (will be) accounted as initialized + + // Check initialization + LOG(info) << "InitManager " << fInitManager.GetInitController().ToString(); + // Get number of stations - int NStationsNew = fInitManager.GetStationsNumber(); + int nStationsNew = fInitManager.GetStationsNumber(); // TODO: we must to get rid of station specification in the L1Algo (S.Zh.) - int NMvdStationsNew = fInitManager.GetStationsNumber(static_cast<L1DetectorID>(0)); - int NStsStationsNew = fInitManager.GetStationsNumber(static_cast<L1DetectorID>(1)); - int NfieldStationsNew = NMvdStationsNew + NStsStationsNew; + int nMvdStationsNew = fInitManager.GetStationsNumber(static_cast<L1DetectorID>(0)); + int nStsStationsNew = fInitManager.GetStationsNumber(static_cast<L1DetectorID>(1)); + int nFieldStationsNew = nMvdStationsNew + nStsStationsNew; // Get field near target L1FieldValue vtxFieldValueNew = fInitManager.GetTargetFieldValue(); @@ -245,7 +250,6 @@ void L1Algo::Init(const L1Vector<fscal>& geo, const bool UseHitErrors, const Tra // Fill L1Station array fInitManager.TransferL1StationArray(fStationsNew); - LOG(info) << "**********************************************************************"; LOG(info) << "* New L1Algo initialization cross check (tmp log, to be removed!) *"; LOG(info) << "**********************************************************************"; @@ -255,10 +259,10 @@ void L1Algo::Init(const L1Vector<fscal>& geo, const bool UseHitErrors, const Tra LOG(info) << "\tSTS: " << NStsStations; LOG(info) << "\tField: " << fNfieldStations; LOG(info) << "** Number of stations (new) **"; - LOG(info) << "\tTotal: " << NStationsNew; - LOG(info) << "\tMVD: " << NMvdStationsNew; - LOG(info) << "\tSTS: " << NStsStationsNew; - LOG(info) << "\tField: " << NfieldStationsNew; + LOG(info) << "\tTotal: " << nStationsNew; + LOG(info) << "\tMVD: " << nMvdStationsNew; + LOG(info) << "\tSTS: " << nStsStationsNew; + LOG(info) << "\tField: " << nFieldStationsNew; LOG(info) << "** Magnetic field near target (original)**"; LOG(info) << "\tField Value: " << '\n' << vtxFieldValue.ToString(/*indent = */ 1) << '\n'; @@ -280,6 +284,9 @@ void L1Algo::Init(const L1Vector<fscal>& geo, const bool UseHitErrors, const Tra LOG(info) << "Station Global No: " << iSt; LOG(info) << '\n' << fStationsNew[iSt].ToString(/*verbosity = */ 3); } + + // Print L1Parameters + fParameters.Print(/*verbosity=*/0); } @@ -448,5 +455,3 @@ void L1Algo::CreateHitPoint(const L1Hit& hit, L1HitPoint& point) // } // // inline int L1Algo::UnPackIndex(const int& i, int& a, int& b, int& c) { -// return (a) + ((b)*10000) + (c*100000000); -// } diff --git a/reco/L1/L1Algo/L1Algo.h b/reco/L1/L1Algo/L1Algo.h index 6513fa82e1a3740cc2e02931723ac7feb83420d4..5f4077e342e1f8a6252d3de4ebf6875691d4957b 100644 --- a/reco/L1/L1Algo/L1Algo.h +++ b/reco/L1/L1Algo/L1Algo.h @@ -81,7 +81,8 @@ class L1AlgoEfficiencyPerformance; #endif typedef int Tindex; - +/// Central class of L1 tracking +/// class L1Algo { public: L1Algo(unsigned int nThreads = 1); @@ -360,20 +361,19 @@ public: /// Sets L1Algo parameters object - void SetL1Parameters(const L1Parameters& other) { fL1Parameters = other; } - /// Gets a constant reference to the L1Algo parameters object - const L1Parameters& GetL1Parameters() const { return fL1Parameters; } - // TODO: We should think about, where non-constexpr L1Algo parameters can be modified. At the moment we can create a - // L1Parameters object somewhere outside the L1Algo, fill its fields there and then pass it directly to - // the L1Algo instance. (S.Zh.) - L1InitManager* GetL1InitManager() { return &fInitManager; } + void SetParameters(const L1Parameters& other) { fParameters = other; } + + /// Gets a pointer to the L1Algo parameters object + L1Parameters* GetParameters() { return &fParameters; } + /// Gets a pointer to the L1Algo initialization object + L1InitManager* GetInitManager() { return &fInitManager; } fvec GetCbmTargetZ() const { return fCbmTargetZ; } private: - /// Object containing L1Parameters. Default consturctor is used - L1Parameters fL1Parameters; ///< Object of L1Algo parameters class - L1InitManager fInitManager; ///< Object of L1Algo initialization manager class + L1Parameters fParameters {}; ///< Object of L1Algo parameters class + L1InitManager fInitManager {&fParameters}; ///< Object of L1Algo initialization manager class + /// ================================= FUNCTIONAL PART ================================= diff --git a/reco/L1/L1Algo/L1BaseStationInfo.cxx b/reco/L1/L1Algo/L1BaseStationInfo.cxx index 81ebddd8ad04253ef964b0b490af4879dfc50287..648cb0fd32f06692b5cbb38ff3da68be1c7ebc37 100644 --- a/reco/L1/L1Algo/L1BaseStationInfo.cxx +++ b/reco/L1/L1Algo/L1BaseStationInfo.cxx @@ -20,7 +20,6 @@ #include "L1BaseStationInfo.h" #include "L1Def.h" #include "L1Parameters.h" - // C++ STL #include <iomanip> #include <sstream> @@ -44,8 +43,8 @@ L1BaseStationInfo::L1BaseStationInfo(L1DetectorID detectorID, int stationID) noe , fStationID(stationID) { LOG(debug) << "L1BaseStationInfo: Constructor (detectorID, stationID) called for " << this << '\n'; // Temporary - fInitFlags[keDetectorID] = true; - fInitFlags[keStationID] = true; + fInitController.SetFlag(InitKey::keDetectorID); + fInitController.SetFlag(InitKey::keStationID); } //----------------------------------------------------------------------------------------------------------------------// @@ -64,7 +63,7 @@ L1BaseStationInfo::L1BaseStationInfo(const L1BaseStationInfo& other) noexcept , fYmax(other.fYmax) , fZPos(other.fZPos) , fL1Station(other.fL1Station) - , fInitFlags(other.fInitFlags) + , fInitController(other.fInitController) { LOG(debug) << "L1BaseStationInfo: Copy constructor called: " << &other << " was copied into " << this; } @@ -98,18 +97,6 @@ L1BaseStationInfo& L1BaseStationInfo::operator=(L1BaseStationInfo&& other) noexc return *this; } -//----------------------------------------------------------------------------------------------------------------------// -// -void L1BaseStationInfo::Swap(L1BaseStationInfo& other) noexcept -{ - std::swap(fDetectorID, other.fDetectorID); - std::swap(fStationID, other.fStationID); - std::swap(fXmax, other.fXmax); - std::swap(fYmax, other.fYmax); - std::swap(fZPos, other.fZPos); - std::swap(fL1Station, other.fL1Station); - std::swap(fInitFlags, other.fInitFlags); -} // // BASIC METHODS @@ -139,19 +126,18 @@ void L1BaseStationInfo::Print(int verbosity) const void L1BaseStationInfo::Reset() { L1BaseStationInfo other; - std::swap(*this, other); + this->Swap(other); } // // GETTERS // - //----------------------------------------------------------------------------------------------------------------------// // const L1Station& L1BaseStationInfo::GetL1Station() const { - bool isStationInitialized = IsInitialized(); + bool isStationInitialized = fInitController.IsFinalized(); if (!isStationInitialized) { LOG(error) << "L1BaseStationInfo::GetL1Station: attempt to get an L1Staion object from uninitialized L1BaseStation with " @@ -161,31 +147,17 @@ const L1Station& L1BaseStationInfo::GetL1Station() const return fL1Station; } - // // SETTERS // -//----------------------------------------------------------------------------------------------------------------------// -// -void L1BaseStationInfo::SetStationID(int inID) -{ - if (!fInitFlags[keStationID]) { - fStationID = inID; - fInitFlags[keStationID] = true; - } - else { - LOG(warn) << "L1BaseStationInfo::SetStationID: Attempt of station ID redifinition"; - } -} - //----------------------------------------------------------------------------------------------------------------------// // void L1BaseStationInfo::SetDetectorID(L1DetectorID inID) { - if (!fInitFlags[keDetectorID]) { - fDetectorID = inID; - fInitFlags[keDetectorID] = true; + if (!fInitController.GetFlag(InitKey::keDetectorID)) { + fDetectorID = inID; + fInitController.SetFlag(InitKey::keDetectorID); } else { LOG(warn) << "L1BaseStationInfo::SetDetectorID: Attempt of detector ID redifinition"; @@ -194,70 +166,25 @@ void L1BaseStationInfo::SetDetectorID(L1DetectorID inID) //----------------------------------------------------------------------------------------------------------------------// // -void L1BaseStationInfo::SetStationType(int inType) -{ - if (!fInitFlags[keType]) { - fL1Station.type = inType; - fInitFlags[keType] = true; - } - else { - LOG(warn) << "L1BaseStationInfo::SetStationType: Attempt of station type redifinition"; - } -} - -//----------------------------------------------------------------------------------------------------------------------// -// -void L1BaseStationInfo::SetTimeInfo(int inTimeInfo) -{ - fL1Station.timeInfo = inTimeInfo; - fInitFlags[keTimeInfo] = true; -} - -//----------------------------------------------------------------------------------------------------------------------// -// -void L1BaseStationInfo::SetZ(double inZ) +void L1BaseStationInfo::SetRmax(double inRmax) { - fL1Station.z = inZ; // setting simd vector of single-precision floats, which is passed to high performanced L1Algo - fZPos = inZ; // setting precised value to use in field approximation etc - fInitFlags[keZ] = true; + fL1Station.Rmax = inRmax; + fInitController.SetFlag(InitKey::keRmax); } //----------------------------------------------------------------------------------------------------------------------// // void L1BaseStationInfo::SetRmin(double inRmin) { - fL1Station.Rmin = inRmin; - fInitFlags[keRmin] = true; -} - -//----------------------------------------------------------------------------------------------------------------------// -// -void L1BaseStationInfo::SetRmax(double inRmax) -{ - fL1Station.Rmax = inRmax; - fInitFlags[keRmax] = true; -} - -//----------------------------------------------------------------------------------------------------------------------// -// -void L1BaseStationInfo::SetMaterial(double inThickness, double inRL) -{ -#ifndef L1_NO_ASSERT // check for zero denominator - L1_ASSERT(inRL, "Attempt of entering zero inRL (radiational length) value"); -#endif - fL1Station.materialInfo.thick = inThickness; - fL1Station.materialInfo.RL = inRL; - fL1Station.materialInfo.RadThick = fL1Station.materialInfo.thick / fL1Station.materialInfo.RL; - fL1Station.materialInfo.logRadThick = log(fL1Station.materialInfo.RadThick); - fInitFlags[keMaterialInfoThick] = true; - fInitFlags[keMaterialInfoRL] = true; + fL1Station.Rmin = inRmin; + fInitController.SetFlag(InitKey::keRmin); } //----------------------------------------------------------------------------------------------------------------------// // void L1BaseStationInfo::SetFieldSlice(const double* Cx, const double* Cy, const double* Cz) { - if (fInitFlags[keFieldSlice]) { + if (fInitController.GetFlag(InitKey::keFieldSlice)) { LOG(warn) << "L1BaseStationInfo::SetFieldSlice: Attempt to redifine field slice for station with detectorID = " << static_cast<int>(fDetectorID) << " and stationID = " << fStationID << ". Redifinition ignored"; return; @@ -269,23 +196,26 @@ void L1BaseStationInfo::SetFieldSlice(const double* Cx, const double* Cy, const fL1Station.fieldSlice.cz[idx] = Cz[idx]; } - fInitFlags[keFieldSlice] = true; + fInitController.SetFlag(InitKey::keFieldSlice); } //----------------------------------------------------------------------------------------------------------------------// // void L1BaseStationInfo::SetFieldSlice(const std::function<void(const double (&xyz)[3], double (&B)[3])>& getFieldValue) { - if (fInitFlags[keFieldSlice]) { + if (fInitController.GetFlag(InitKey::keFieldSlice)) { LOG(warn) << "L1BaseStationInfo::SetFieldSlice: Attempt to redifine field slice for station with detectorID = " << static_cast<int>(fDetectorID) << " and stationID = " << fStationID << ". Redifinition ignored"; return; } #ifndef L1_NO_ASSERT // check for zero denominator - L1_ASSERT(fInitFlags[keZ], "Attempt to set magnetic field slice before setting z position of the station"); - L1_ASSERT(fInitFlags[keXmax], "Attempt to set magnetic field slice before setting Xmax size of the station"); - L1_ASSERT(fInitFlags[keYmax], "Attempt to set magnetic field slice before setting Ymax size of the station"); + L1_ASSERT(fInitController.GetFlag(InitKey::keZ), + "Attempt to set magnetic field slice before setting z position of the station"); + L1_ASSERT(fInitController.GetFlag(InitKey::keXmax), + "Attempt to set magnetic field slice before Xmax size of the station"); + L1_ASSERT(fInitController.GetFlag(InitKey::keYmax), + "Attempt to set magnetic field slice before Ymax size of the station"); #endif // TODO: Change names of variables according to convention (S.Zh.) constexpr int M = L1Parameters::kMaxFieldApproxPolynomialOrder; @@ -355,7 +285,7 @@ void L1BaseStationInfo::SetFieldSlice(const std::function<void(const double (&xy fL1Station.fieldSlice.cz[j] = A[j][N + 2] / A[j][j]; } - fInitFlags[keFieldSlice] = true; + fInitController.SetFlag(InitKey::keFieldSlice); } //----------------------------------------------------------------------------------------------------------------------// @@ -369,7 +299,6 @@ void L1BaseStationInfo::SetFrontBackStripsGeometry(double frontPhi, double front double sBack = sin(backPhi); // NOTE: Here additional double variables are used to save the precission - fL1Station.frontInfo.cos_phi = cFront; fL1Station.frontInfo.sin_phi = sFront; fL1Station.frontInfo.sigma2 = frontSigma * frontSigma; @@ -378,21 +307,6 @@ void L1BaseStationInfo::SetFrontBackStripsGeometry(double frontPhi, double front fL1Station.backInfo.sin_phi = sBack; fL1Station.backInfo.sigma2 = backSigma * backSigma; - //if (fabs(b_phi - f_phi) < .1) { - // double th = b_phi - f_phi; - // double det = cos(th); - // det *= det; - // fL1Station.XYInfo.C00 = (s_b * s_b * f_sigma * f_sigma + s_f * s_f * b_sigma * b_sigma) / det; - // fL1Station.XYInfo.C10 = -(s_b * c_b * f_sigma * f_sigma + s_f * c_f * b_sigma * b_sigma) / det; - // fL1Station.XYInfo.C11 = (c_b * c_b * f_sigma * f_sigma + c_f * c_f * b_sigma * b_sigma) / det; - //} else { - // double det = c_f * s_b - s_f * c_b; - // det *= det; - // fL1Station.XYInfo.C00 = (s_b * s_b * f_sigma * f_sigma + s_f * s_f * b_sigma * b_sigma) / det; - // fL1Station.XYInfo.C10 = -(s_b * c_b * f_sigma * f_sigma + s_f * c_f * b_sigma * b_sigma) / det; - // fL1Station.XYInfo.C11 = (c_b * c_b * f_sigma * f_sigma + c_f * c_f * b_sigma * b_sigma) / det; - //} - double det = (fabs(backPhi - frontPhi) < 0.1) ? cos(backPhi - frontPhi) : (cFront * sBack - sFront * cBack); det *= det; fL1Station.XYInfo.C00 = (sBack * sBack * frontSigma * frontSigma + sFront * sFront * backSigma * backSigma) / det; @@ -408,26 +322,97 @@ void L1BaseStationInfo::SetFrontBackStripsGeometry(double frontPhi, double front fL1Station.yInfo.sigma2 = fL1Station.XYInfo.C11; //-----------------------------------------------------------------------------------------------------// - fInitFlags[keStripsFrontPhi] = true; - fInitFlags[keStripsFrontSigma] = true; - fInitFlags[keStripsBackPhi] = true; - fInitFlags[keStripsBackSigma] = true; + fInitController.SetFlag(InitKey::keStripsFrontPhi); + fInitController.SetFlag(InitKey::keStripsFrontSigma); + fInitController.SetFlag(InitKey::keStripsBackPhi); + fInitController.SetFlag(InitKey::keStripsBackSigma); +} + +//----------------------------------------------------------------------------------------------------------------------// +// +void L1BaseStationInfo::SetMaterial(double inThickness, double inRL) +{ +#ifndef L1_NO_ASSERT // check for zero denominator + L1_ASSERT(inRL, "Attempt of entering zero inRL (radiational length) value"); +#endif + fL1Station.materialInfo.thick = inThickness; + fL1Station.materialInfo.RL = inRL; + fL1Station.materialInfo.RadThick = fL1Station.materialInfo.thick / fL1Station.materialInfo.RL; + fL1Station.materialInfo.logRadThick = log(fL1Station.materialInfo.RadThick); + fInitController.SetFlag(InitKey::keMaterialInfoThick); + fInitController.SetFlag(InitKey::keMaterialInfoRL); +} + +//----------------------------------------------------------------------------------------------------------------------// +// +void L1BaseStationInfo::SetStationID(int inID) +{ + if (!fInitController.GetFlag(InitKey::keStationID)) { + fStationID = inID; + fInitController.SetFlag(InitKey::keStationID); + } + else { + LOG(warn) << "L1BaseStationInfo::SetStationID: Attempt of station ID redifinition"; + } +} + +//----------------------------------------------------------------------------------------------------------------------// +// +void L1BaseStationInfo::SetStationType(int inType) +{ + if (!fInitController.GetFlag(InitKey::keType)) { + fL1Station.type = inType; + fInitController.SetFlag(InitKey::keType); + } + else { + LOG(warn) << "L1BaseStationInfo::SetStationType: Attempt of station type redifinition"; + } } //----------------------------------------------------------------------------------------------------------------------// // void L1BaseStationInfo::SetXmax(double aSize) { - fXmax = aSize; - fInitFlags[keXmax] = true; + fXmax = aSize; + fInitController.SetFlag(InitKey::keXmax); } //----------------------------------------------------------------------------------------------------------------------// // void L1BaseStationInfo::SetYmax(double aSize) { - fYmax = aSize; - fInitFlags[keYmax] = true; + fYmax = aSize; + fInitController.SetFlag(InitKey::keYmax); +} + +//----------------------------------------------------------------------------------------------------------------------// +// +void L1BaseStationInfo::SetTimeInfo(int inTimeInfo) +{ + fL1Station.timeInfo = inTimeInfo; + fInitController.SetFlag(InitKey::keTimeInfo); +} + +//----------------------------------------------------------------------------------------------------------------------// +// +void L1BaseStationInfo::SetZ(double inZ) +{ + fL1Station.z = inZ; // setting simd vector of single-precision floats, which is passed to high performanced L1Algo + fZPos = inZ; // setting precised value to use in field approximation etc + fInitController.SetFlag(InitKey::keZ); +} + +//----------------------------------------------------------------------------------------------------------------------// +// +void L1BaseStationInfo::Swap(L1BaseStationInfo& other) noexcept +{ + std::swap(fDetectorID, other.fDetectorID); + std::swap(fStationID, other.fStationID); + std::swap(fXmax, other.fXmax); + std::swap(fYmax, other.fYmax); + std::swap(fZPos, other.fZPos); + std::swap(fL1Station, other.fL1Station); + std::swap(fInitController, other.fInitController); } //----------------------------------------------------------------------------------------------------------------------// diff --git a/reco/L1/L1Algo/L1BaseStationInfo.h b/reco/L1/L1Algo/L1BaseStationInfo.h index 17f511e2548216dc9b6b061024c55998bcef2b5e..9120ccd6d0f3c380547f70f5f173946217afbcd4 100644 --- a/reco/L1/L1Algo/L1BaseStationInfo.h +++ b/reco/L1/L1Algo/L1BaseStationInfo.h @@ -15,43 +15,48 @@ #ifndef L1BaseStationInfo_h #define L1BaseStationInfo_h 1 +// L1 Core +#include "L1ObjectInitController.h" +#include "L1Station.h" // C++ std -#include <bitset> #include <functional> #include <string> -#include "L1Station.h" - enum class L1DetectorID; /// A base class which provides interface to L1Algo station geometry class L1BaseStationInfo { -private: - enum - { // Here we list all the fields, which must be initialized by user +public: + /// Enumeration of fields, which must be initialized so the object can pass the threshold + enum class InitKey + { // Basic fields initialization - keDetectorID, - keStationID, - keXmax, - keYmax, + keDetectorID, ///< detector ID + keStationID, ///< station ID + keXmax, ///< max size in X direction + keYmax, ///< max size in Y direction // L1Station initialization - keType, - keTimeInfo, - keZ, - keRmin, - keRmax, - keMaterialInfoThick, - keMaterialInfoRL, - keFieldSlice, - keStripsFrontPhi, - keStripsFrontSigma, - keStripsBackPhi, - keStripsBackSigma, + keType, ///< station type + keTimeInfo, ///< if time info is used (flag) + keZ, ///< z coordinate of the station position + keRmin, ///< internal radius of station (gap size) + keRmax, ///< exteranl radius of station + keMaterialInfoThick, ///< thickness of the station + keMaterialInfoRL, ///< rad length of the station + keFieldSlice, ///< L1Station.L1FieldSlice object initialization + keStripsFrontPhi, ///< strips geometry initialization + keStripsFrontSigma, ///< + keStripsBackPhi, ///< + keStripsBackSigma, ///< // The last item is equal to the number of bits in fInitFlags keEnd }; -public: + using L1ObjectInitController_t = L1ObjectInitController<static_cast<int>(InitKey::keEnd), InitKey>; + + // + // CONSTRUCTORS AND DESTRUCTORS + // /// Default constructor L1BaseStationInfo() noexcept; /// Constructor from stationID and detectorID @@ -62,28 +67,14 @@ public: L1BaseStationInfo(const L1BaseStationInfo& other) noexcept; /// Move constructor L1BaseStationInfo(L1BaseStationInfo&& other) noexcept; - /// Copy operator= + /// Copy assignment operator L1BaseStationInfo& operator=(const L1BaseStationInfo& other) noexcept; - /// Move operator= + /// Move assignment operator L1BaseStationInfo& operator=(L1BaseStationInfo&& other) noexcept; - /// Swap method for easier implementation of above ones (NOTE: all the fields must be accounted carefully here) - void Swap(L1BaseStationInfo& other) noexcept; // // BASIC METHODS // - - /// Checks if all the necessary fields are initialized by user - bool IsInitialized() const { return fInitFlags.size() == fInitFlags.count(); } - /// Prints registered fields - /// verbosity = 0: print only station id, detector id and address in one line - /// verbosity = 1: print basic L1Station fields - /// verbosity = 2: print all L1Staion fields - void Print(int verbosity = 0) const; - /// Print initialization flags (debug function) - void PrintInit() const; - /// Resets fields to the default values - void Reset(); /// Less operator for L1BaseStationInfo object to perform their sorts. Sorting is carried out first by fDetectorID, /// and then by fStationID bool operator<(const L1BaseStationInfo& right) const @@ -91,84 +82,65 @@ public: return fDetectorID != right.fDetectorID ? fDetectorID < right.fDetectorID : fStationID < right.fStationID; } - // // GETTERS // - - /// Gets station ID - int GetStationID() const { return fStationID; } /// Gets detector ID L1DetectorID GetDetectorID() const { return fDetectorID; } - /// Gets station type - int GetStationType() const { return fL1Station.type; } - /// Gets SIMD vectorized z position of the station - fvec GetZsimdVec() const { return fL1Station.z; } - /// Gets double precised z position of the station - double GetZdouble() const { return fZPos; } - /// Gets min transverse size of the station - fvec GetRmin() const { return fL1Station.Rmin; } - /// Gets max transverse size of the station - fvec GetRmax() const { return fL1Station.Rmax; } - - /// Gets material thickness - fvec GetMaterialThickness() const { return fL1Station.materialInfo.thick; } - /// Gets the radiation length of the station material - fvec GetMaterialRadLength() const { return fL1Station.materialInfo.RL; } - /// Gets the relative material thickness in units of the radiational length - fvec GetMaterialRadThick() const { return fL1Station.materialInfo.RadThick; } - /// Gets log of the relative material thickness in units of the radiational length - fvec GetMaterialLogRadThick() const { return fL1Station.materialInfo.logRadThick; } - /// Gets a coefficient with idx for the field x-component approximation fvec GetFieldSliceCx(int idx) const { return fL1Station.fieldSlice.cx[idx]; } /// Gets a coefficient with idx for the field y-component approximation fvec GetFieldSliceCy(int idx) const { return fL1Station.fieldSlice.cy[idx]; } /// Gets a coefficient with idx for the field z-component approximation fvec GetFieldSliceCz(int idx) const { return fL1Station.fieldSlice.cz[idx]; } - /// Gets array of the coefficients for the field x-component approximation const fvec* GetFieldSliceCx() const { return fL1Station.fieldSlice.cx; } /// Gets array of the coefficients for the field y-component approximation const fvec* GetFieldSliceCy() const { return fL1Station.fieldSlice.cy; } /// Gets array of the coefficients for the field z-component approximation const fvec* GetFieldSliceCz() const { return fL1Station.fieldSlice.cz; } - + /// Gets a const reference to the L1ObjectInitController object + const L1ObjectInitController_t& GetInitController() const { return fInitController; } + /// Gets a reference to L1Station info field of the L1BaseStation info + const L1Station& GetL1Station() const; + /// Gets material thickness + fvec GetMaterialThickness() const { return fL1Station.materialInfo.thick; } + /// Gets the radiation length of the station material + fvec GetMaterialRadLength() const { return fL1Station.materialInfo.RL; } + /// Gets the relative material thickness in units of the radiational length + fvec GetMaterialRadThick() const { return fL1Station.materialInfo.RadThick; } + /// Gets log of the relative material thickness in units of the radiational length + fvec GetMaterialLogRadThick() const { return fL1Station.materialInfo.logRadThick; } + /// Gets min transverse size of the station + fvec GetRmin() const { return fL1Station.Rmin; } + /// Gets max transverse size of the station + fvec GetRmax() const { return fL1Station.Rmax; } + /// Gets station ID + int GetStationID() const { return fStationID; } + /// Gets station type + int GetStationType() const { return fL1Station.type; } /// Gets maximum distance between station center and its edge in x direction double GetXmax() const { return fXmax; } /// Gets maximum distance between station center and its edge in y direction double GetYmax() const { return fYmax; } + /// Gets double precised z position of the station + double GetZdouble() const { return fZPos; } + /// Gets SIMD vectorized z position of the station + fvec GetZsimdVec() const { return fL1Station.z; } - /// Gets a reference to L1Station info field of the L1BaseStation info - const L1Station& GetL1Station() const; - /// Gets a reference to Bitset object of initialization bits - const std::bitset<L1BaseStationInfo::keEnd>& GetInitFlags() const { return fInitFlags; } - + /// Prints registered fields + /// verbosity = 0: print only station id, detector id and address in one line + /// verbosity = 1: print basic L1Station fields + /// verbosity = 2: print all L1Staion fields + void Print(int verbosity = 0) const; + /// Resets fields to the default values + void Reset(); // // SETTERS // - - /// Sets station ID - void SetStationID(int inID); /// Sets detector ID void SetDetectorID(L1DetectorID inID); - - /// Sets type of station - void SetStationType(int inType); // TODO: this is a temporary solution (S.Zh.) - /// Sets flag: 0 - time information is not provided by this detector type - // 1 - time information is provided by the detector and can be used in tracking - void SetTimeInfo(int inTimeInfo); - /// Sets nominal z position of the station - void SetZ(double inZ); - /// Sets min transverse size of the station - void SetRmin(double inRmin); - /// Sets max transverse size of the station - void SetRmax(double inRmax); - /// Sets station thickness and radiational length - /// \param thickness thickness of station - /// \param radiationalLength radiational length of station - void SetMaterial(double thickness, double radiationalLength); /// Sets field approximation at the station plain /// \param Cx Array of approximation coefficients for x field component /// \param Cy Array of approximation coefficients for y field component @@ -184,10 +156,31 @@ public: /// \param b_phi Stereoangle of back strips /// \param b_sigma Sigma of back strips void SetFrontBackStripsGeometry(double fPhi, double fSigma, double bPhi, double bSigma); + /// Sets station thickness and radiational length + /// \param thickness thickness of station + /// \param radiationalLength radiational length of station + void SetMaterial(double thickness, double radiationalLength); + /// Sets max transverse size of the station + void SetRmax(double inRmax); + /// Sets min transverse size of the station + void SetRmin(double inRmin); + /// Sets station ID + void SetStationID(int inID); + /// Sets type of station + void SetStationType(int inType); // TODO: this is a temporary solution (S.Zh.) + /// Sets flag: 0 - time information is not provided by this detector type + /// 1 - time information is provided by the detector and can be used in tracking + void SetTimeInfo(int inTimeInfo); /// Sets maximum distance between station center and its edge in x direction void SetXmax(double aSize); /// Sets maximum distance between station center and its edge in y direction void SetYmax(double aSize); + /// Sets nominal z position of the station + void SetZ(double inZ); + + /// Swap method for easier implementation of above ones (NOTE: all the fields must be accounted carefully here) + void Swap(L1BaseStationInfo& other) noexcept; + /// String representation of class contents /// \param indentLevel number of indent characters in the output std::string ToString(int verbosityLevel = 0, int indentLevel = 0) const; @@ -199,7 +192,7 @@ private: double fYmax {0}; ///< Maximum distance between station center and its edge in y direction double fZPos {0}; ///< z position of the station in double precision, used in field approximation L1Station fL1Station {}; ///< L1Station structure, describes a station in L1Algo - std::bitset<L1BaseStationInfo::keEnd> fInitFlags; ///< Class fileds initialization flags + L1ObjectInitController_t fInitController {}; ///< Class fileds initialization flags }; /// swap function for two L1BaseStationInfo objects, expected to be used instead of std::swap diff --git a/reco/L1/L1Algo/L1CAIteration.cxx b/reco/L1/L1Algo/L1CAIteration.cxx index b96eacd1a36aafb4a75d50f77035cc3d9d8468d3..9bd07054db86b0c50157327093f62e76af39d591 100644 --- a/reco/L1/L1Algo/L1CAIteration.cxx +++ b/reco/L1/L1Algo/L1CAIteration.cxx @@ -89,8 +89,9 @@ L1CAIteration::L1CAIteration(const std::string& name) noexcept : fName(name) // void L1CAIteration::Print(int verbosityLevel) const { - LOG(info) << "CA Track Finder Iteration: " << fName; + if (verbosityLevel == 0) { LOG(info) << " - " << fName; } if (verbosityLevel > 0) { + LOG(info) << "L1CAIteration: " << fName; LOG(info) << "\tTrack chi2 cut: " << fTrackChi2Cut; LOG(info) << "\tTriplet chi2 cut: " << fTripletChi2Cut; LOG(info) << "\tDoublet chi2 cut: " << fDoubletChi2Cut; diff --git a/reco/L1/L1Algo/L1CAIteration.h b/reco/L1/L1Algo/L1CAIteration.h index e81bd35272e7e3097627adbe6f7877499ba7b708..372f12d163a6fc0e758413ab4a3ebf609144a6df 100644 --- a/reco/L1/L1Algo/L1CAIteration.h +++ b/reco/L1/L1Algo/L1CAIteration.h @@ -7,7 +7,6 @@ * @file L1CAIteration.h * @brief Class for L1 CA Track Finder Iteration * @since 01.15.2022 - * ***********************************************************************************************************/ #ifndef L1CAIteration_h diff --git a/reco/L1/L1Algo/L1CATrackFinder.cxx b/reco/L1/L1Algo/L1CATrackFinder.cxx index 56dff8798412053eff3ae5bbb99e6db5b832b247..6cc6f718f7b6c1b3a633864bff23d6c6ae6fc94c 100644 --- a/reco/L1/L1Algo/L1CATrackFinder.cxx +++ b/reco/L1/L1Algo/L1CATrackFinder.cxx @@ -539,10 +539,10 @@ inline void L1Algo::f20( #ifndef FAST_CODE //TODO: optimise triplet portion limit and put a warning -// assert(Ndoublets < fL1Parameters.GetMaxDoubletsPerSinglet()); +// assert(Ndoublets < fParameters.GetMaxDoubletsPerSinglet()); #endif // FAST_CODE - if (Ndoublets >= fL1Parameters.GetMaxDoubletsPerSinglet()) { + if (Ndoublets >= fParameters.GetMaxDoubletsPerSinglet()) { n2 = n2 - Ndoublets; i1_2.reduce(i1_2.size() - Ndoublets); hitsm_2.reduce(hitsm_2.size() - Ndoublets); @@ -867,9 +867,9 @@ inline void L1Algo::f30( // input #ifndef FAST_CODE //TODO: optimise triplet portion limit and put a warning -// assert(Ntriplets < fL1Parameters.GetMaxTripletPerDoublets()); +// assert(Ntriplets < fParameters.GetMaxTripletPerDoublets()); #endif // FAST_CODE - if (Ntriplets >= fL1Parameters.GetMaxTripletPerDoublets()) { + if (Ntriplets >= fParameters.GetMaxTripletPerDoublets()) { n3 = n3 - Ntriplets; diff --git a/reco/L1/L1Algo/L1InitManager.cxx b/reco/L1/L1Algo/L1InitManager.cxx index 9a867b145fe2a77bf0b4d686cac7f4145c20d2cb..9a94d47a8bda5cf14a16486c3614413dc328a09a 100644 --- a/reco/L1/L1Algo/L1InitManager.cxx +++ b/reco/L1/L1Algo/L1InitManager.cxx @@ -6,13 +6,15 @@ * @file L1InitManager.cxx * @bried Input data management class for L1Algo * @since 19.01.2022 - * ***********************************************************************************************************/ #include "L1InitManager.h" #include <algorithm> +//----------------------------------------------------------------------------------------------------------------------- +// +L1InitManager::L1InitManager(L1Parameters* pParameters) : fpParameters(pParameters) {} //----------------------------------------------------------------------------------------------------------------------- // @@ -20,25 +22,25 @@ void L1InitManager::AddStation(const L1BaseStationInfo& inStation) { // Check if other fields were defined already // Active detector IDs - if (!fInitFlags[L1InitManager::keActiveDetectorIDs]) { + if (!fInitController.GetFlag(InitKey::keActiveDetectorIDs)) { LOG(error) << "L1InitManager::AddStation: station initialization called before the active detectors set had been " "initialized"; - assert((fInitFlags[L1InitManager::keActiveDetectorIDs])); + assert((fInitController.GetFlag(InitKey::keActiveDetectorIDs))); } // Number of stations check - if (!fInitFlags[L1InitManager::keStationsNumberCrosscheck]) { + if (!fInitController.GetFlag(InitKey::keStationsNumberCrosscheck)) { LOG(error) << "L1InitManager::AddStation: station initialization called before the numbers of stations for each detector " << "had been initialized"; - assert((fInitFlags[L1InitManager::keStationsNumberCrosscheck])); + assert((fInitController.GetFlag(InitKey::keStationsNumberCrosscheck))); } // Field function - if (!fInitFlags[L1InitManager::keFieldFunction]) { + if (!fInitController.GetFlag(InitKey::keFieldFunction)) { LOG(error) << "L1InitManager::AddStation: station initialization called before the magnetic field function was intialized"; - assert((fInitFlags[L1InitManager::keFieldFunction])); + assert((fInitController.GetFlag(InitKey::keFieldFunction))); } // Check activeness of this station type @@ -47,10 +49,12 @@ void L1InitManager::AddStation(const L1BaseStationInfo& inStation) // initialize magnetic field slice L1BaseStationInfo inStationCopy = L1BaseStationInfo(inStation); // make a copy of station so it can be initialized inStationCopy.SetFieldSlice(fFieldFunction); - bool isStationInitialized = inStationCopy.IsInitialized(); + bool isStationInitialized = inStationCopy.GetInitController().IsFinalized(); if (!isStationInitialized) { - LOG(debug) << "L1InitManager::AddStation: station init flags (original)" << inStation.GetInitFlags(); - LOG(debug) << "L1InitManager::AddStation: station init flags (copy) " << inStation.GetInitFlags(); + LOG(debug) << "L1InitManager::AddStation:(original) L1BaseStationInfo " + << inStation.GetInitController().ToString(); + LOG(debug) << "L1InitManager::AddStation:(copy) L1BaseStationInfo " + << inStation.GetInitController().ToString(); LOG(error) << "L1InitManager::AddStation: attempt to add incompletely initialized object with detectorID = " << static_cast<int>(inStationCopy.GetDetectorID()) << " and stationID = " << inStationCopy.GetStationID(); @@ -76,121 +80,129 @@ void L1InitManager::AddStation(const L1BaseStationInfo& inStation) //----------------------------------------------------------------------------------------------------------------------- // -void L1InitManager::Init() const -{ // To be implemented - // Plans: - // 1. Must make a final check of the inititalization and turn on a corresponding trigger in L1Algo class to accept - // the incoming data +void L1InitManager::CheckInit() +{ + this->CheckCAIterationsInit(); + this->CheckStationsInfoInit(); } //----------------------------------------------------------------------------------------------------------------------- // -void L1InitManager::PrintStations(int verbosityLevel) const +int L1InitManager::GetStationsNumber(L1DetectorID detectorID) const { - for (const auto& station : fStationsInfo) { - station.Print(verbosityLevel); - } + auto ifDetectorIdDesired = [&detectorID](const L1BaseStationInfo& station) { + return station.GetDetectorID() == detectorID; + }; + return std::count_if(fStationsInfo.begin(), fStationsInfo.end(), ifDetectorIdDesired); } //----------------------------------------------------------------------------------------------------------------------- // -void L1InitManager::PrintCAIterations(int verbosityLevel) const +void L1InitManager::InitTargetField(double zStep) { - for (const auto& iteration : fCAIterationsContainer) { - iteration.Print(verbosityLevel); + 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 + if (!fInitController.GetFlag(InitKey::keFieldFunction)) { + LOG(error) << "L1InitManager::InitTargetField: attempt to initialze the field value and field region near " + << "target before initializing field function"; + assert((fInitController.GetFlag(InitKey::keFieldFunction))); + } + + // Check for target defined + if (!fInitController.GetFlag(InitKey::keTargetPos)) { + LOG(error) << "L1InitManager::InitTargetField: attempt to initialize the field value and field region near " + << "target before the target position initialization"; + assert((fInitController.GetFlag(InitKey::keTargetPos))); + } + + 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::PushBackCAIteration(const L1CAIteration& iteration) +void L1InitManager::PrintCAIterations(int verbosityLevel) const { - // TODO: probably some checks must be inserted here - if (!fInitFlags[L1InitManager::keCAIterationsNumberCrosscheck]) { - LOG(error) << "L1InitManager::PushBackCAIteration: attempt to push back a CA track finder iteration before the " - << "number of iterations was defined"; - assert((fInitFlags[L1InitManager::keCAIterationsNumberCrosscheck])); + for (const auto& iteration : fpParameters->CAIterationsContainer()) { + iteration.Print(verbosityLevel); } - fCAIterationsContainer.push_back(iteration); } //----------------------------------------------------------------------------------------------------------------------- // -void L1InitManager::TransferL1StationArray(std::array<L1Station, L1Parameters::kMaxNstations>& destinationArray) +void L1InitManager::PrintStations(int verbosityLevel) const { - /// First of all, we must check if L1Station was properly initialized - // TODO: actually, false condition will never reached (must think about it, may be remove assertions from - // CheckStationInfo and leave only warnings and flag) (S.Zh.) - bool ifStationsInitialized = CheckStationsInfo(); - if (!ifStationsInitialized) { - LOG(error) << "L1InitManager::TransferL1StationArray: attempt to pass unitialized L1Station array to L1Algo core"; - assert((ifStationsInitialized)); - } - - /// Check if destinationArraySize is enough for the transfer - int totalStationsNumber = this->GetStationsNumber(); - bool ifDestinationArraySizeOk = totalStationsNumber <= static_cast<int>(destinationArray.size()); - if (!ifDestinationArraySizeOk) { - LOG(error) << "L1InitManager::TransferL1StationArray: destination array size (" << destinationArray.size() - << ") is smaller then actual number of active tracking stations (" << totalStationsNumber << ")"; - assert((ifDestinationArraySizeOk)); - } - - auto destinationArrayIterator = destinationArray.begin(); - for (const auto& item : fStationsInfo) { - *destinationArrayIterator = std::move(item.GetL1Station()); - ++destinationArrayIterator; + for (const auto& station : fStationsInfo) { + station.Print(verbosityLevel); } - LOG(info) << "L1InitManager: L1Station vector was successfully transfered to L1Algo core :)"; } //----------------------------------------------------------------------------------------------------------------------- // -void L1InitManager::TransferCAIterationsContainer(L1Vector<L1CAIteration>& destinationVector) +void L1InitManager::PushBackCAIteration(const L1CAIteration& iteration) { - bool ifCAIterationsInitialized = CheckCAIterations(); - if (!ifCAIterationsInitialized) { - LOG(error) << "L1InitManager::TransferCAIterationsContainer: the CA track finder iterations container was not " - << "initialized properly"; - assert((ifCAIterationsInitialized)); + // TODO: probably some checks must be inserted here + if (!fInitController.GetFlag(InitKey::keCAIterationsNumberCrosscheck)) { + LOG(error) << "L1InitManager::PushBackCAIteration: attempt to push back a CA track finder iteration before the " + << "number of iterations was defined"; + assert((fInitController.GetFlag(InitKey::keCAIterationsNumberCrosscheck))); } - std::copy(fCAIterationsContainer.begin(), fCAIterationsContainer.end(), destinationVector.begin()); + //fCAIterationsContainer.push_back(iteration); + L1Vector<L1CAIteration>& iterationsContainer = fpParameters->CAIterationsContainer(); + iterationsContainer.push_back(iteration); } -// -// GETTERS -// - //----------------------------------------------------------------------------------------------------------------------- // -int L1InitManager::GetStationsNumber(L1DetectorID detectorID) const +void L1InitManager::SetActiveDetectorIDs(const std::set<L1DetectorID>& detectorIDs) { - auto ifDetectorIdDesired = [&detectorID](const L1BaseStationInfo& station) { - return station.GetDetectorID() == detectorID; - }; - return std::count_if(fStationsInfo.begin(), fStationsInfo.end(), ifDetectorIdDesired); + // TODO: To think about redifinition possibilities: should it be allowed or not? (S.Zh.) + fActiveDetectorIDs = detectorIDs; + fInitController.SetFlag(InitKey::keActiveDetectorIDs); } -// -// SETTERS -// - //----------------------------------------------------------------------------------------------------------------------- // -void L1InitManager::SetActiveDetectorIDs(const std::set<L1DetectorID>& detectorIDs) +void L1InitManager::SetCAIterationsNumberCrosscheck(int nIterations) { - // TODO: To think about redifinition possibilities: should it be allowed or not? (S.Zh.) - fActiveDetectorIDs = detectorIDs; - fInitFlags[L1InitManager::keActiveDetectorIDs] = true; + 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 std::function<void(const double (&xyz)[3], double (&B)[3])>& fieldFunction) +void L1InitManager::SetFieldFunction(const L1FieldFunction_t& fieldFunction) { - if (!fInitFlags[L1InitManager::keFieldFunction]) { - fFieldFunction = fieldFunction; - fInitFlags[L1InitManager::keFieldFunction] = true; + if (!fInitController.GetFlag(InitKey::keFieldFunction)) { + fFieldFunction = fieldFunction; + fInitController.SetFlag(InitKey::keFieldFunction); } else { LOG(warn) << "L1InitManager::SetFieldFunction: attempt to reinitialize the field function. Ignored"; @@ -210,154 +222,129 @@ void L1InitManager::SetStationsNumberCrosscheck(L1DetectorID detectorID, int nSt // Check if all the station numbers for active detectors are initialized now: LOG(debug) << "SetStationsNumberCrosscheck called for detectorID = " << static_cast<int>(detectorID); - if (!fInitFlags[L1InitManager::keStationsNumberCrosscheck]) { + if (!fInitController.GetFlag(InitKey::keStationsNumberCrosscheck)) { bool ifInitialized = true; for (auto item : fActiveDetectorIDs) { if (fStationsNumberCrosscheck.find(item) == fStationsNumberCrosscheck.end()) { - LOG(warn) << "L1InitManager::SetStationsNumberCrosscheck: uninitialized number of stations for detectorID = " - << static_cast<int>(item); ifInitialized = false; break; } } - fInitFlags[L1InitManager::keStationsNumberCrosscheck] = ifInitialized; + fInitController.SetFlag(InitKey::keStationsNumberCrosscheck, ifInitialized); } - LOG(debug) << "InitResult: " << fInitFlags[L1InitManager::keStationsNumberCrosscheck]; -} - -//----------------------------------------------------------------------------------------------------------------------- -// -void L1InitManager::SetCAIterationsNumberCrosscheck(int nIterations) -{ - fCAIterationsNumberCrosscheck = nIterations; - fInitFlags[L1InitManager::keCAIterationsNumberCrosscheck] = true; } //----------------------------------------------------------------------------------------------------------------------- // void L1InitManager::SetTargetPosition(double x, double y, double z) { - if (fInitFlags[L1InitManager::keTargetPos]) { + 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; - fInitFlags[L1InitManager::keTargetPos] = true; + fTargetPos[0] = x; + fTargetPos[1] = y; + fTargetPos[2] = z; + fInitController.SetFlag(InitKey::keTargetPos); } //----------------------------------------------------------------------------------------------------------------------- // -void L1InitManager::InitTargetField(double zStep) +void L1InitManager::TransferL1StationArray(std::array<L1Station, L1Parameters::kMaxNstations>& destinationArray) { - if (fInitFlags[L1InitManager::kePrimaryVertexField]) { - LOG(warn) << "L1InitManager::InitTargetField: attempt to reinitialize the field value and field region " - << "near target. Ignore"; - return; + // + // 1) Check, if all fields of this were initialized + // + if (!fInitController.IsFinalized()) { + LOG(error) << "L1InitManager::TransferL1StationArray: attempt to pass L1Station array to L1Algo core before " + << "all necessary fields initialization"; + LOG(error) << "L1InitManager " << fInitController.ToString(); + assert((fInitController.IsFinalized())); } - // Check for field function - if (!fInitFlags[L1InitManager::keFieldFunction]) { - LOG(error) << "L1InitManager::InitTargetField: attempt to initialze the field value and field region near " - << "target before initializing field function"; - assert((fInitFlags[L1InitManager::keFieldFunction])); + // + // 2) Check, if destinationArraySize is enough for the transfer + // + int nStationsTotal = this->GetStationsNumber(); + bool ifDestinationArraySizeOk = nStationsTotal <= static_cast<int>(destinationArray.size()); + if (!ifDestinationArraySizeOk) { + LOG(error) << "L1InitManager::TransferL1StationArray: destination array size (" << destinationArray.size() + << ") is smaller then actual number of active tracking stations (" << nStationsTotal << ")"; + assert((ifDestinationArraySizeOk)); } - // Check for target defined - if (!fInitFlags[L1InitManager::keTargetPos]) { - LOG(error) << "L1InitManager::InitTargetField: attempt to initialize the field value and field region near " - << "target before the target position initialization"; - assert((fInitFlags[L1InitManager::keTargetPos])); + 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 :)"; +} - constexpr int numberOfDimensions {3}; - constexpr int numberOfReferencePoints {3}; +// +// INIT CHECKERS +// - std::array<double, numberOfReferencePoints> inputNodalZ {fTargetPos[2], fTargetPos[2] + zStep, - fTargetPos[2] + 2. * zStep}; - std::array<L1FieldValue, numberOfReferencePoints> B = {}; - std::array<fvec, numberOfReferencePoints> z = {}; - for (int idx = 0; idx < numberOfReferencePoints; ++idx) { - double point[numberOfDimensions] = {0., 0., inputNodalZ[idx]}; - double field[numberOfDimensions] = {}; - fFieldFunction(point, field); - z[idx] = inputNodalZ[idx]; - B[idx].x = field[0]; - B[idx].y = field[1]; - B[idx].z = field[2]; +//----------------------------------------------------------------------------------------------------------------------- +// +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; + } } - fTargetFieldRegion.Set(B[0], z[0], B[1], z[1], B[2], z[2]); - fTargetFieldValue = B[0]; - - fInitFlags[L1InitManager::kePrimaryVertexField] = true; + fInitController.SetFlag(InitKey::keCAIterations, ifInitPassed); } - //----------------------------------------------------------------------------------------------------------------------- -// -bool L1InitManager::CheckStationsInfo() +// TODO: REWRITE! and add const qualifier (S.Zharko) +void L1InitManager::CheckStationsInfoInit() { - if (!fInitFlags[L1InitManager::keStationsInfo]) { - bool ifInitPassed = true; - - if (!fInitFlags[L1InitManager::keIfStationNumbersChecked]) { - for (const auto& itemDetector : fActiveDetectorIDs) { - int actualStationsNumber = GetStationsNumber(itemDetector); - int expectedStationsNumber = fStationsNumberCrosscheck.at(itemDetector); - if (actualStationsNumber != expectedStationsNumber) { - LOG(error) << "L1InitManager::CheckStationsInfo: Incorrect number of L1BaseStationInfo objects passed to the " - "L1Manager " - << "for L1DetectorID = " << static_cast<int>(itemDetector) << ": " << actualStationsNumber - << " of " << expectedStationsNumber << " expected"; - ifInitPassed = false; - } + 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; } - fInitFlags[L1InitManager::keIfStationNumbersChecked] = ifInitPassed; - } + } // loop over active detectors: end + if (!ifInitPassed) { - LOG(error) << "L1InitManager::CheckStationsInfo: initialization failed"; + LOG(error) << "L1InitManager::IsStationsInfo: initialization failed"; assert((ifInitPassed)); } - // Check for maximum allowed number of stations - int totalStationsNumber = GetStationsNumber(); - if (totalStationsNumber > L1Parameters::kMaxNstations) { - LOG(fatal) << "Actual total number of registered stations (" << totalStationsNumber + // + // 2) Check for maximum allowed number of stations + // + int nStationsTotal = GetStationsNumber(); + if (nStationsTotal > L1Parameters::kMaxNstations) { + LOG(fatal) << "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.Zh.) - assert((totalStationsNumber <= L1Parameters::kMaxNstations)); + // TODO: We have to provide an instruction of how to increase the kMaxNstations + // number keeping the code consistent (S.Zharko) + ifInitPassed = false; + assert((nStationsTotal <= L1Parameters::kMaxNstations)); } - - fInitFlags[L1InitManager::keStationsInfo] = true; - } - else { - LOG(warn) << "L1InitManager: L1BaseStationInfo set has already been initialized"; } - // NOTE: we return a flag here to reduce a number of calls outside the funcition. In other hands we keep this flag - // to be consistent with other class fields initialization rules - return fInitFlags[L1InitManager::keStationsInfo]; -} - -//----------------------------------------------------------------------------------------------------------------------- -// -bool L1InitManager::CheckCAIterations() -{ - // Check number of iterations - if (!fInitFlags[L1InitManager::keCAIterations]) { - int actualIterationsNumber = fCAIterationsContainer.size(); - int expectedIterationsNumber = fCAIterationsNumberCrosscheck; - if (actualIterationsNumber != expectedIterationsNumber) { - LOG(warn) << "L1InitManager::CheckCAIterations: incorrect number of iterations registered: " - << actualIterationsNumber << " of " << expectedIterationsNumber << " expected"; - fInitFlags[L1InitManager::keCAIterations] = false; - } - else { - fInitFlags[L1InitManager::keCAIterations] = true; - } - } - - return fInitFlags[L1InitManager::keCAIterations]; + fInitController.SetFlag(InitKey::keStationsInfo, ifInitPassed); } diff --git a/reco/L1/L1Algo/L1InitManager.h b/reco/L1/L1Algo/L1InitManager.h index 29986cbba36eaddd0d86f7e7d06f81f042b41297..f6540bc7aaeec9ef364519d20fe79e408ca1a6f1 100644 --- a/reco/L1/L1Algo/L1InitManager.h +++ b/reco/L1/L1Algo/L1InitManager.h @@ -6,7 +6,6 @@ * @file L1InitManager.h * @bried Input data management class for L1Algo * @since 24.12.2021 - * ***********************************************************************************************************/ #ifndef L1InitManager_h #define L1InitManager_h 1 @@ -14,6 +13,7 @@ #include "L1BaseStationInfo.h" #include "L1CAIteration.h" #include "L1Field.h" +#include "L1ObjectInitController.h" #include "L1Parameters.h" #include "L1Utils.h" @@ -55,32 +55,38 @@ enum class L1DetectorID; /// initMan->SetStationsNumberCrosscheck(L1DetectorID::kMvd, NMvdStations) /// initMan->SetStationsNumberCrosscheck(L1DetectorID::kMvd, NStsStations); /// -/// 3. Initialize each station using L1BaseStationInfo: +/// 4. Initialize each station using L1BaseStationInfo: /// class L1InitManager { private: - enum + enum class InitKey { - keActiveDetectorIDs, ///< If the detector sequence is set - keStationsNumberCrosscheck, ///< If the crosscheck station numbers were setup - keFieldFunction, ///< If magnetic field getter funciton is set - keTargetPos, ///< If target position was defined - kePrimaryVertexField, ///< If magnetic field value and region defined at primary vertex - keIfStationNumbersChecked, ///< If the station number was already checked - keStationsInfo, ///< If all the planned stations were added to the manager - keL1StationTransfered, ///< If the L1Station vector was already transfered to destination array - keCAIterationsNumberCrosscheck, ///< If the CA trackfinder iterations were initialized - keCAIterations, ///< If the CA trackfinder iterations were initialized - keEnd + // NOTE: Please, keep the numbers of enum items in the existing order: it helps to debug the initialization with + // this->GetObjectInitController().ToString() method call (S.Zharko) + keActiveDetectorIDs, ///< 0) If the detector sequence is set + keStationsNumberCrosscheck, ///< 1) If the crosscheck station numbers were setup + keFieldFunction, ///< 2) If magnetic field getter funciton is set + keTargetPos, ///< 3) If target position was defined + kePrimaryVertexField, ///< 4) If magnetic field value and region defined at primary vertex + keStationsInfo, ///< 5) If all the planned stations were added to the manager + keCAIterationsNumberCrosscheck, ///< 6) If the number of CA track finder is initialized + keCAIterations, ///< 7) If the CA track finder iterations were initialized + keEnd ///< 8 - number of entries in the enum }; + using L1DetectorIDIntMap_t = std::unordered_map<L1DetectorID, int, L1Utils::EnumClassHash>; + using L1DetectorIDSet_t = std::set<L1DetectorID>; + using L1FieldFunction_t = std::function<void(const double (&xyz)[3], double (&B)[3])>; + using L1ObjectInitController_t = L1ObjectInitController<static_cast<int>(InitKey::keEnd), InitKey>; + public: // // CONSTRUCTORS AND DESTRUCTOR // - /// Default constructor - L1InitManager() = default; + L1InitManager() = delete; + /// Constructor from ptr to L1Paramters object + L1InitManager(L1Parameters* pParameters); /// Destructor ~L1InitManager() = default; /// Copy constructor is forbidden @@ -92,103 +98,101 @@ public: /// Move assignment operator is forbidden L1InitManager& operator=(L1InitManager&& /*other*/) = delete; - // // BASIC METHODS // - - /// Adds another station of a given type using reference to a L1BaseStationInfo object - void AddStation(const L1BaseStationInfo& inStation); + void AddStation(const L1BaseStationInfo& station); /// Adds another station of a given type using pointer to a L1BaseStationInfo object - void AddStation(const L1BaseStationInfo* inStationRawPtr) { AddStation(*inStationRawPtr); } + void AddStation(const L1BaseStationInfo* pStation) { AddStation(*pStation); } /// Adds another station of a given type using std::unique_ptr-wraped pointer to L1BaseStationInfo - void AddStation(const std::unique_ptr<L1BaseStationInfo>& inStationUPtr) { AddStation(*inStationUPtr); } - - /// Initializes L1Algo: transfers all caputred data to the L1 tracking core - void Init() const; - /// Prints a list of stations - void PrintStations(int verbosityLevel = 0) const; - /// Prints a list of CA track finder iterations - void PrintCAIterations(int verbosityLevel = 0) const; - - /// Pushes an CA track finder iteration into a sequence of iteration using reference - void PushBackCAIteration(const L1CAIteration& iteration); - /// Pushes an CA track finder iteration into a sequence of iteration using raw pointer - void PushBackCAIteration(const L1CAIteration* iterationRawPtr) { PushBackCAIteration(*iterationRawPtr); } - /// Pushes an CA track finder iteration into a sequence of iteration using std::unique_ptr - void PushBackCAIteration(const std::unique_ptr<L1CAIteration>& iterationUPtr) { PushBackCAIteration(*iterationUPtr); } - - /// Transfers an array of L1Stations formed inside a set of L1BaseStationInfo to a destination std::array - void TransferL1StationArray(std::array<L1Station, L1Parameters::kMaxNstations>& destinationArray); - /// Transfers a vector of the CA track finder iterations - void TransferCAIterationsContainer(L1Vector<L1CAIteration>& destinationVector); + void AddStation(const std::unique_ptr<L1BaseStationInfo>& puStation) { AddStation(*puStation); } + /// Provides final checks of large fields initialization calling Check"Object"Init() privat methods, + /// must be called in the begining of L1Algo::Init() + void CheckInit(); + // NOTE: This method calls checkers of large fields initializations like a station or an iteration. The method must be + // called in the L1Algo class. (S.Zharko) // // GETTERS // - /// Gets a set of actie detectors for this analysis - std::set<L1DetectorID> GetActiveDetectorIDs() const { return fActiveDetectorIDs; } + const L1DetectorIDSet_t& GetActiveDetectorIDs() const { return fActiveDetectorIDs; } + /// Gets a const reference to L1ObjectInitController + const L1ObjectInitController_t& GetInitController() const { return fInitController; } + /// Gets a pointer to L1Parameters instance with a posibility of its fields modification + const L1Parameters* GetParameters() const { return fpParameters; } /// Gets a total number of stations (NOTE: this number includes both active and unactive stations!) int GetStationsNumber() const { return static_cast<int>(fStationsInfo.size()); } /// Gets a number of stations for a particualr detector ID int GetStationsNumber(L1DetectorID detectorID) const; - /// Gets a target position - const std::array<double, 3>& GetTargetPosition() const { return fTargetPos; } // TODO: define enum of dimensions.... (S.Zh.) /// Gets a L1FieldRegion object at primary vertex const L1FieldRegion& GetTargetFieldRegion() const { return fTargetFieldRegion; } /// Gets a L1FieldValue object at primary vertex const L1FieldValue& GetTargetFieldValue() const { return fTargetFieldValue; } + /// Gets a target position + const std::array<double, 3>& GetTargetPosition() const { return fTargetPos; } + + /// Calculates L1FieldValue and L1FieldReference values for a selected step in z coordinate from the target position + /// \param zStep step between nodal points + // TODO: Consider posibility for linear approximation (S.Zh.) + void InitTargetField(double zStep); + + /// Prints a list of CA track finder iterations + void PrintCAIterations(int verbosityLevel = 0) const; + /// Prints a list of stations + void PrintStations(int verbosityLevel = 0) const; + + /// Pushes an CA track finder iteration into a sequence of iteration using reference + void PushBackCAIteration(const L1CAIteration& iteration); + /// Pushes an CA track finder iteration into a sequence of iteration using raw pointer + void PushBackCAIteration(const L1CAIteration* pIteration) { PushBackCAIteration(*pIteration); } + /// Pushes an CA track finder iteration into a sequence of iteration using std::unique_ptr + void PushBackCAIteration(const std::unique_ptr<L1CAIteration>& puIteration) { PushBackCAIteration(*puIteration); } // // SETTERS // - /// Sets a set of active tracking detector IDs - void SetActiveDetectorIDs(const std::set<L1DetectorID>& detectorIDs); + void SetActiveDetectorIDs(const L1DetectorIDSet_t& detectorIDs); + /// Sets a number of CA track finder iterations to provide initialization cross-check + void SetCAIterationsNumberCrosscheck(int nIterations); /// Sets a magnetic field function, which will be applied for all the stations - void SetFieldFunction(const std::function<void(const double (&xyz)[3], double (&B)[3])>& fieldFcn); + void SetFieldFunction(const L1FieldFunction_t& fieldFcn); /// Sets a number of stations for a particular tracking detector ID to provide initialization cross-check void SetStationsNumberCrosscheck(L1DetectorID detectorID, int nStations); - /// Sets a number of CA track finder iterations to provide initialization cross-check - void SetCAIterationsNumberCrosscheck(int nIterations); /// Sets target poisition void SetTargetPosition(double x, double y, double z); - /// Calculates L1FieldValue and L1FieldReference values for a selected step in z coordinate from the target position - /// \param zStep step between nodal points - // TODO: Consider posibility for linear approximation (S.Zh.) - void InitTargetField(double zStep); + /// Transfers an array of L1Stations formed inside a set of L1BaseStationInfo to a destination std::array + void TransferL1StationArray(std::array<L1Station, L1Parameters::kMaxNstations>& destinationArray); private: - /// Checker for L1BaseStationInfo set initialization - /// \return true If all L1BaseStationInfo objects were initialized properly. Similar effect can be achieved by - /// calling the fInitFlags[L1InitManager::keStationsInfo] flag - bool CheckStationsInfo(); - /// Checker for L1CAIteration container initialization + /// Checker for L1CAIteration container initialization (sets InitKey::keCAIterations) /// \return true If all L1CAIteration objects were initialized properly - bool CheckCAIterations(); + void CheckCAIterationsInit(); + /// Checker for L1BaseStationInfo set initialization (sets InitKey::keStationsInfo) + /// \return true If all L1BaseStationInfo objects were initialized properly. Similar effect can be achieved by + void CheckStationsInfoInit(); /* Basic fields */ - std::bitset<L1InitManager::keEnd> fInitFlags {}; ///< Initialization flags - std::set<L1DetectorID> fActiveDetectorIDs {}; ///< Set of tracking detectors, active during this analysis session + L1ObjectInitController_t fInitController {}; ///< Initialization flags + L1DetectorIDSet_t fActiveDetectorIDs {}; ///< Set of tracking detectors, active during this analysis session /* Target fields */ - std::array<double, 3> fTargetPos {}; ///< Nominal target position coordinates + std::array<double, /*nDimensions=*/3> fTargetPos {}; ///< Nominal target position coordinates /* Stations related fields */ std::set<L1BaseStationInfo> fStationsInfo {}; ///< Set of L1BaseStationInfo objects /// Map of station numbers used for initialization crosscheck - std::unordered_map<L1DetectorID, int, L1Utils::EnumClassHash> fStationsNumberCrosscheck {}; + L1DetectorIDIntMap_t fStationsNumberCrosscheck {}; /// A function which returns magnetic field vector B in a radius-vector xyz - std::function<void(const double (&xyz)[3], double (&B)[3])> fFieldFunction { - [](const double (&)[3], double (&)[3]) {}}; + L1FieldFunction_t fFieldFunction {[](const double (&)[3], double (&)[3]) {}}; // NOTE: Stations of daetectors which will not be assigned as active, will not be included in the tracking!!!!!!! // NOTE: fTotalNumberOfStations is excess field for logic, but it's imortant to track L1Algo initialization @@ -199,11 +203,12 @@ private: /* CA track finder iterations related */ - L1Vector<L1CAIteration> fCAIterationsContainer {}; ///> Container for CA track finder iterations + //L1Vector<L1CAIteration> fCAIterationsContainer {}; ///> Container for CA track finder iterations int fCAIterationsNumberCrosscheck {-1}; ///> Number of iterations to be passed (must be used for cross-checks) - /// Pointer to L1Parameters object, which will be copied to L1Algo after checks - L1Parameters* fParametersPtr {nullptr}; + /// Pointer to L1Parameters object + // NOTE: Owner of the object is L1Algo instance + L1Parameters* fpParameters {nullptr}; }; #endif diff --git a/reco/L1/L1Algo/L1ObjectInitController.h b/reco/L1/L1Algo/L1ObjectInitController.h new file mode 100644 index 0000000000000000000000000000000000000000..1a384508902f2f7f2a1a3d7d476b98407e32f60b --- /dev/null +++ b/reco/L1/L1Algo/L1ObjectInitController.h @@ -0,0 +1,85 @@ +/* Copyright (C) 2021 GSI Helmholtzzentrum fuer Schwerionenforschung, Darmstadt + SPDX-License-Identifier: GPL-3.0-only + Authors: Sergey Gorbunov, Sergei Zharko [committer] */ + +#ifndef L1ObjectInitController_h +#define L1ObjectInitController_h 1 + +/// @file L1ObjectInitController.h +/// @author Sergei Zharko +/// @date 22.02.2022 + +#include "FairLogger.h" + +#include <bitset> +#include <cassert> +#include <iomanip> +#include <iostream> +#include <sstream> +#include <string> + +/// L1ObjectInitController is a class, which provides flags system +/// and functionality needed for L1 algorithm objects initialization +/// +// TODO: Possible improvement: introduce another template parameter, which represents a local enum class... +template<int NumberOfFlags, class InitKeyEnum> +class L1ObjectInitController { +public: + /// Gets an initialization status of the flag placed at bitIndex + /// \param bitIndex index of bit + bool GetFlag(InitKeyEnum bitKey) const + { +#ifndef FAST_CODE + int bitIndex = static_cast<int>(bitKey); + if (bitIndex >= NumberOfFlags || bitIndex < 0) { + LOG(fatal) << "L1OnjectInitController::GetFlagStatus: attempt of flag access with index = " << bitIndex + << " outside the range [0, " << NumberOfFlags << ']'; + assert((!(bitIndex >= NumberOfFlags || bitIndex < 0))); + } +#endif // FAST_CODE + return fInitFlags[static_cast<int>(bitKey)]; + } + + /// Checks, if the object is finalized, i.e. all its fields were setup + bool IsFinalized() const { return fInitFlags.size() == fInitFlags.count(); } + + /// Sets an initialization status of the flag placed at bitIndex + /// \param bitIndex index of bit + /// \param newStatus flag value (true is default) + void SetFlag(InitKeyEnum bitKey, bool newStatus = true) + { +#ifndef FAST_CODE + int bitIndex = static_cast<int>(bitKey); + if (bitIndex >= NumberOfFlags || bitIndex < 0) { + LOG(fatal) << "L1OnjectInitController::GetFlagStatus: attempt of flag access with index = " << bitIndex + << " outside the range [0, " << NumberOfFlags << ']'; + assert((!(bitIndex >= NumberOfFlags || bitIndex < 0))); + } +#endif // FAST_CODE + fInitFlags[static_cast<int>(bitKey)] = newStatus; + } + + /// String representation of initialization flags contents + /// \param indentLevel number of indent charachets int output + std::string ToString(int indentLevel = 0) const + { + std::stringstream aStream {}; + constexpr char indentChar = '\t'; + std::string indent(indentLevel, indentChar); + aStream << indent << "L1ObjectInitController: flag values"; + aStream << '\n' << indent << "index: "; + for (int idx = 0; idx < NumberOfFlags; ++idx) { + aStream << std::setw(3) << std::setfill(' ') << idx << ' '; + } + aStream << '\n' << indent << "value: "; + for (int idx = 0; idx < NumberOfFlags; ++idx) { + aStream << " " << static_cast<int>(fInitFlags[idx]) << ' '; + } + return aStream.str(); + } + +private: + std::bitset<NumberOfFlags> fInitFlags {}; ///< object of flags sets +}; + +#endif // L1ObjectInitController_h diff --git a/reco/L1/L1Algo/L1Parameters.cxx b/reco/L1/L1Algo/L1Parameters.cxx index 03c56812868d171705a334e960fe11214ac6567c..2927946e6779e79c1f74ecffc716846c21991e21 100644 --- a/reco/L1/L1Algo/L1Parameters.cxx +++ b/reco/L1/L1Algo/L1Parameters.cxx @@ -11,7 +11,7 @@ #include <FairLogger.h> -void L1Parameters::Print() const +void L1Parameters::Print(int verbosityLevel) const { LOG(info) << "== L1Algo parameters =============================================================="; LOG(info) << ""; @@ -27,6 +27,9 @@ void L1Parameters::Print() const LOG(info) << " Max number of doublets per singlet: " << fMaxDoubletsPerSinglet; LOG(info) << " Max number of triplets per doublet: " << fMaxTripletPerDoublets; LOG(info) << ""; - LOG(info) << " TRACK FINDER ITERATION DEPENDENT CONSTANTS"; + LOG(info) << " TRACK FINDER ITERATIONS"; + for (const auto& iteration : fCAIterationsContainer) { + iteration.Print(verbosityLevel); + } LOG(info) << "==================================================================================="; } diff --git a/reco/L1/L1Algo/L1Parameters.h b/reco/L1/L1Algo/L1Parameters.h index 74396339d3551c7bb977609462a8ccc91d7b5532..16613ea84d8ab694e1b2bfc39b4464073682f42a 100644 --- a/reco/L1/L1Algo/L1Parameters.h +++ b/reco/L1/L1Algo/L1Parameters.h @@ -60,7 +60,7 @@ public: // /// Prints configuration - void Print() const; + void Print(int verbosityLevel = 0) const; // TODO: change constant names with actual (human) names