diff --git a/algo/ca/TrackingChain.cxx b/algo/ca/TrackingChain.cxx index 3810670e9f5fa6910491a97d4d2a17067cd3564c..1d481261a1af5143deb8128a969175122fcf94eb 100644 --- a/algo/ca/TrackingChain.cxx +++ b/algo/ca/TrackingChain.cxx @@ -13,6 +13,7 @@ #include "CaHit.h" #include "CaInitManager.h" #include "CaParameters.h" +#include "KfSetupBuilder.h" #include "ParFiles.h" #include "compat/OpenMP.h" #include "yaml/Yaml.h" @@ -66,6 +67,8 @@ void TrackingChain::Init() L_(info) << "Tracking Chain: reading geometry from CA parameters file " << GNb << geomCfgFile << CL << '\n'; L_(info) << "Tracking Chain: reading geometry setup file " << GNb << setupCfgFile << CL << '\n'; L_(info) << "Tracking Chain: reading parameters from CA main config " << GNb << mainCfgFile << CL << '\n'; + + //* InitManager instantiation auto manager = InitManager{}; manager.SetDetectorNames(ca::kDetName); manager.SetConfigMain(mainCfgFile); @@ -73,10 +76,36 @@ void TrackingChain::Init() L_(info) << "Tracking Chain: applying user configuration from " << GNb << userCfgFile << CL << '\n'; manager.SetConfigUser(userCfgFile); } - manager.ReadParametersObject(geomCfgFile); // geometry setup - manager.ReadInputConfigs(); - manager.ReadGeometrySetup(setupCfgFile); + + //* Read parameters object from the geomCfgFile to intialize tracking stations + { + manager.ReadParametersObject(geomCfgFile); // geometry setup + auto paramIn = manager.TakeParameters(); + manager.ClearSetupInfo(); + + //* Read setup + auto geoSetup = kf::SetupBuilder::Load<ca::fvec>(setupCfgFile); + kf::Target<double> target(geoSetup.GetTarget()); + + //* Initialize tracking parameters + manager.SetFieldFunction([](const double(&)[3], double(&outB)[3]) { + outB[0] = 0.; + outB[1] = 0.; + outB[2] = 0.; + }); + manager.SetTargetPosition(target.GetX(), target.GetY(), target.GetZ()); + manager.InitTargetField(2.5 /*cm*/); + manager.AddStations(paramIn); // Initialize stations + manager.InitStationLayout(); + manager.ReadInputConfigs(); + manager.SetGeometrySetup(geoSetup); + manager.DevSetIsParSearchWUsed(false); + if (!manager.FormParametersContainer()) { + throw std::runtime_error("Initialization of CA parameters failed"); + } + } auto parameters = manager.TakeParameters(); + L_(info) << "Tracking Chain: parameters object: \n" << parameters.ToString(1) << '\n'; // ------ Used detector subsystem flags diff --git a/algo/ca/core/pars/CaConfigReader.cxx b/algo/ca/core/pars/CaConfigReader.cxx index 5df9fc277ea0d55275171c03e252f0b97c74fd01..1c84cc1665f8a38d7d264950070665facc411917 100644 --- a/algo/ca/core/pars/CaConfigReader.cxx +++ b/algo/ca/core/pars/CaConfigReader.cxx @@ -33,7 +33,8 @@ ConfigReader::ConfigReader(InitManager* pInitManager, int verbose) : fpInitManag // --------------------------------------------------------------------------------------------------------------------- // -YAML::Node ConfigReader::GetNode(std::function<YAML::Node(YAML::Node)> fn) const +// TODO: switch to the Yaml library by Felix +YAML::Node ConfigReader::GetNode(std::function<YAML::Node(YAML::Node)> fn, bool optional) const { auto node = YAML::Node(YAML::NodeType::Undefined); if (fUserConfigNode) { @@ -42,7 +43,7 @@ YAML::Node ConfigReader::GetNode(std::function<YAML::Node(YAML::Node)> fn) const if (!node) { node = fn(fMainConfigNode); } - if (!node) { + if (!node && !optional) { std::stringstream msg; msg << "requested node was not found "; if (fUserConfigNode) { @@ -250,7 +251,10 @@ std::vector<std::set<int>> ConfigReader::ReadInactiveStationMap() { // Check, if the "skip_stations" branch exists either in the user config or in the main config std::string sNodePath = "ca/core/common/inactive_stations"; - auto node = this->GetNode([](YAML::Node n) { return n["core"]["common"]["inactive_stations"]; }); + auto node = GetNode([](YAML::Node n) { return n["core"]["common"]["inactive_stations"]; }, true); + if (!node) { + return std::vector<std::set<int>>{}; + } // Fill map of inactive stations std::vector<std::set<int>> vGeoIdToTrackingStatus(constants::size::MaxNdetectors); diff --git a/algo/ca/core/pars/CaConfigReader.h b/algo/ca/core/pars/CaConfigReader.h index 9178f975c14a8d0aec99adf0dd92b94f1048f040..7729c9c36cdbcaab151e578f7e87ad7cf4a62e93 100644 --- a/algo/ca/core/pars/CaConfigReader.h +++ b/algo/ca/core/pars/CaConfigReader.h @@ -78,14 +78,15 @@ namespace cbm::algo::ca void ReadMisalignmentTolerance(); /// \brief Accesses a node either from user config or from main config - /// \param fn A function, which returns a YAML::Node reference object + /// \param fn A function, which returns a YAML::Node reference object + /// \param optional true: node is not mandatory /// \note If the node is not found in both configs /// \throw std::runtime_error, if the path does not exist in the config /// /// This function is to be used, if the desired node should exist either in main or in user config. Firstly, /// the user config is checked, if it is provided. If the node is not found in user config, the main config /// is checked. If the node does not exist in the main config as well, an exception will be thrown. - YAML::Node GetNode(std::function<YAML::Node(YAML::Node)> fn) const; + YAML::Node GetNode(std::function<YAML::Node(YAML::Node)> fn, bool optional = false) const; /// \brief Reads iteration from config file /// \param node YAML node containing an iteration diff --git a/algo/ca/core/pars/CaInitManager.cxx b/algo/ca/core/pars/CaInitManager.cxx index 4bdf43f9e60f21534d6d14f74703eb59f9f11ca4..744709404d42e06ec724cd43bd5ce36dccec40ea 100644 --- a/algo/ca/core/pars/CaInitManager.cxx +++ b/algo/ca/core/pars/CaInitManager.cxx @@ -26,6 +26,29 @@ namespace cbm::algo::ca // void InitManager::AddStation(const StationInitializer& inStation) { fvStationInfo.push_back(inStation); } + // -------------------------------------------------------------------------------------------------------------------- + // + void InitManager::AddStations(const Parameters<fvec>& par) + { + const auto& stations = par.GetStations(); + for (int iSt = 0; iSt < par.GetNstationsActive(); ++iSt) { + auto stationIn = Station<double>(stations[iSt]); + // Get detector ID of the station + auto [detId, locId] = par.GetStationIndexLocal(par.GetActiveToGeoMap()[iSt]); + auto stationInfo = ca::StationInitializer(detId, locId); + stationInfo.SetStationType(stationIn.type); + stationInfo.SetZmin(0.); // NOTE: Deprecated (not used) + stationInfo.SetZmax(0.); // NOTE: Deprecated (not used) + stationInfo.SetZref(stationIn.fZ); + stationInfo.SetXmax(stationIn.Xmax); + stationInfo.SetYmax(stationIn.Ymax); + stationInfo.SetFieldStatus(stationIn.fieldStatus); + stationInfo.SetTimeInfo(stationIn.timeInfo); + stationInfo.SetTrackingStatus(true); + this->AddStation(stationInfo); + } + } + // -------------------------------------------------------------------------------------------------------------------- // void InitManager::CheckInit() @@ -78,6 +101,8 @@ namespace cbm::algo::ca fParameters.fDevIsExtendTracksViaMc = false; fParameters.fDevIsSuppressOverlapHitsViaMc = false; fParameters.fDevIsParSearchWUsed = false; + + fbGeometryConfigLock = false; } // -------------------------------------------------------------------------------------------------------------------- diff --git a/algo/ca/core/pars/CaInitManager.h b/algo/ca/core/pars/CaInitManager.h index b1dc5118f102aae2d8682a4b5aca126ec619fd54..4e00f2658610751d7126ef79d84ad53641e07e28 100644 --- a/algo/ca/core/pars/CaInitManager.h +++ b/algo/ca/core/pars/CaInitManager.h @@ -105,6 +105,16 @@ namespace cbm::algo::ca /// \note The added station stays uninitialized until the Parameters object is formed void AddStation(const StationInitializer& station); + /// \brief Adds tracking stations from the parameters file + /// \param par A valid instance of parameters, created for ACTIVE + INACTIVE tracking stations + /// + // TODO: Probably, we have to remove stations from the parameters and place them into a class ca::Geometery + // together with instances of active and geometry kf::Setup. ca::Parameters should contain only tracking + // parameters, which should be fully defined from the config. Search windows should be stored as an + // independent object, which depends on the ca::Parameters(iterations) and ca::Geometry(active station + // layout). + void AddStations(const Parameters<fvec>& par); + /// \brief Provides final checks of the parameters object void CheckInit(); diff --git a/algo/detectors/trd/Cluster2D.cxx b/algo/detectors/trd/Cluster2D.cxx index 19d6d2dcecdf1c511bf6b357c4ce183e5365e8ea..b6285317197eabe6ef6bfb3eae7b16a165e75e79 100644 --- a/algo/detectors/trd/Cluster2D.cxx +++ b/algo/detectors/trd/Cluster2D.cxx @@ -162,7 +162,7 @@ namespace cbm::algo::trd // check column order for cluster /// TO DO: we can probably drop this check if (last_col >= 0 && colT != last_col + 1) { - L_(error) << "TrdModuleRec2D::LoadDigis : digis in cluster not in increasing order !"; + L_(debug) << "TrdModuleRec2D::LoadDigis : digis in cluster not in increasing order !"; return false; } last_col = colT; diff --git a/external/InstallParameter.cmake b/external/InstallParameter.cmake index c8f4d23f40419581d3a49b55358f9c81dc0d612f..77e3f424dc53079799a63e8be1dd5d1b94720f0d 100644 --- a/external/InstallParameter.cmake +++ b/external/InstallParameter.cmake @@ -1,4 +1,4 @@ -set(PARAMETER_VERSION db53df993ef7b4b977bae554763ebff7f5bf84f7) # 2025/02/14 +set(PARAMETER_VERSION cf6a880a56a8695b485efe358231270e9179cb82) # 2025/02/15 set(PARAMETER_SRC_URL "https://git.cbm.gsi.de/CbmSoft/cbmroot_parameter.git") download_project_if_needed(PROJECT Parameter_source diff --git a/macro/beamtime/mcbm2024/reco_mcbm.sh b/macro/beamtime/mcbm2024/reco_mcbm.sh index c3053f4cd7c8036431ab4398337a166f76bc2682..f004b131b993ba68abf4cfa365f8a1d8b334b348 100755 --- a/macro/beamtime/mcbm2024/reco_mcbm.sh +++ b/macro/beamtime/mcbm2024/reco_mcbm.sh @@ -61,6 +61,7 @@ # Options for running on the batch farm: # -j [--job] <jobId> Index of the job (default == 1) # +# --disable-logs Disables storing output in the temporary log files # # 3. File names involved: # <geo>: Input geometry file: <top_dir>/<setup>.geo.root @@ -101,6 +102,7 @@ # Data directory DATA_TOP_DIR='./data' +DISABLE_LOGS=0 # Subsystem flags RECO_MVD=0 @@ -223,6 +225,9 @@ while [[ $# -gt 0 ]]; do --run ) RUN_IF_ONLY_SETUP_NEEDED=${2} ;; + --disable-logs ) + DISABLE_LOGS=1 + ;; esac shift done @@ -485,16 +490,20 @@ if [[ ${DO_RECO} -eq 1 ]]; then if [[ ${MACRO_RECO} == "*.mcbm2024*" ]]; then PARS="${PARS},${RECO_PV}" fi - root -b -l -q ${MACRO_RECO}"(${PARS})" &> ${RECO_LOG} - cat ${RECO_LOG} - if [[ (1 -ne $(grep -c " Test passed" "${RECO_LOG}")) || (1 -ne $(grep -c " All ok " "${RECO_LOG}")) ]]; then - printf "\nReconstruction of %s failed, stopping there\n" "${TSA_INP}" + if [[ ${DISABLE_LOGS} -eq 1 ]]; then + root -b -l -q ${MACRO_RECO}"(${PARS})" + else + root -b -l -q ${MACRO_RECO}"(${PARS})" &> ${RECO_LOG} + cat ${RECO_LOG} + + if [[ (1 -ne $(grep -c " Test passed" "${RECO_LOG}")) || (1 -ne $(grep -c " All ok " "${RECO_LOG}")) ]]; then + printf "\nReconstruction of %s failed, stopping there\n" "${TSA_INP}" + rm ${RECO_LOG} + exit 7 + fi rm ${RECO_LOG} - exit 7 fi - rm ${RECO_LOG} - # ln -s -f "${FILE_LABEL}.digi.root" "${DATA_TOP_DIR}/${FILE_LABEL}.raw.root" # TMP for QA # Commented out as the output of mcbm_event_reco_L1.C is already [...].rec.root # ln -s -f "${FILE_LABEL}.reco.root" "${DATA_TOP_DIR}/${FILE_LABEL}.rec.root" # TMP for QA @@ -526,15 +535,19 @@ if [[ ${DO_QA_MODULE} -eq 1 ]]; then ln -s ${SETUP_GEO_FILE} $(basename ${QA_GEO}) PARS="-1,\"${QA_REC}\",\"${SETUP_NAME}\",kFALSE,${RECO_ALI}" - root -b -l -q ${MACRO_QA_MODULE}"(${PARS})" &> ${RECO_QA_LOG} - cat ${RECO_QA_LOG} - - if [[ (1 -ne $(grep -c " Test passed" "${RECO_QA_LOG}")) || (1 -ne $(grep -c " All ok " "${RECO_QA_LOG}")) ]]; then - printf "\nReco Modules QA for %s failed, stopping there\n" "${TSA_INP}" + if [[ ${DISABLE_LOGS} -eq 1 ]]; then + root -b -l -q ${MACRO_QA_MODULE}"(${PARS})" + else + root -b -l -q ${MACRO_QA_MODULE}"(${PARS})" &> ${RECO_QA_LOG} + cat ${RECO_QA_LOG} + + if [[ (1 -ne $(grep -c " Test passed" "${RECO_QA_LOG}")) || (1 -ne $(grep -c " All ok " "${RECO_QA_LOG}")) ]]; then + printf "\nReco Modules QA for %s failed, stopping there\n" "${TSA_INP}" + rm ${RECO_QA_LOG} + exit 8 + fi rm ${RECO_QA_LOG} - exit 8 fi - rm ${RECO_QA_LOG} fi # ----- Run QA @@ -551,16 +564,21 @@ if [[ ${DO_QA} -eq 1 ]]; then PARS="0,\"\",\"${QA_RAW}\",\"${QA_REC}\",\"${QA_PAR}\",\"${QA_GEO}\",\"${QA_OUT}\",\"${SETUP_NAME}\"" PARS="${PARS},${USE_MC},\"${CONFIG}\",\"${BENCHMARK}\",${RECO_ALI}" - root -b -l -q ${MACRO_QA}"(${PARS})" &> ${QA_LOG} - cat ${QA_LOG} - - if [[ (1 -eq $(grep -c " QA checks failed" "${QA_LOG}")) || (1 -ne $(grep -c " Test passed" "${QA_LOG}")) - || (1 -ne $(grep -c " All ok " "${QA_LOG}")) ]]; then - printf "\nFull QA for %s failed, stopping there\n" "${TSA_INP}" + + if [[ ${DISABLE_LOGS} -eq 1 ]]; then + root -b -l -q ${MACRO_QA}"(${PARS})" + else + root -b -l -q ${MACRO_QA}"(${PARS})" &> ${QA_LOG} + cat ${QA_LOG} + + if [[ (1 -eq $(grep -c " QA checks failed" "${QA_LOG}")) || (1 -ne $(grep -c " Test passed" "${QA_LOG}")) + || (1 -ne $(grep -c " All ok " "${QA_LOG}")) ]]; then + printf "\nFull QA for %s failed, stopping there\n" "${TSA_INP}" + rm ${QA_LOG} + exit 9 + fi rm ${QA_LOG} - exit 9 fi - rm ${QA_LOG} fi # ----- Run Lambda reconstuction using the KFParticleFinder diff --git a/macro/mcbm/mcbm_qa.C b/macro/mcbm/mcbm_qa.C index 5310cba1e0d43c9ac22fd9ae6abebe1efdc39de6..3025d5783c9b41ee903aa5dab524c89aefd4fff7 100644 --- a/macro/mcbm/mcbm_qa.C +++ b/macro/mcbm/mcbm_qa.C @@ -227,7 +227,7 @@ void mcbm_qa(Int_t nEvents = 0, run->SetSink(sink); TString monitorFile{sinkFile}; - monitorFile.ReplaceAll("qa", "qa.monitor"); + monitorFile.ReplaceAll(".qa.root", ".qa.monitor.root"); FairMonitor::GetMonitor()->EnableMonitor(kTRUE, monitorFile); // ------------------------------------------------------------------------ diff --git a/reco/L1/qa/CbmCaInputQaSetup.cxx b/reco/L1/qa/CbmCaInputQaSetup.cxx index 5ef74c3bb82632a79e1ff059a2c76e13318647ec..3b1489087a3636b92b04ff597d77ecc9de84da1a 100644 --- a/reco/L1/qa/CbmCaInputQaSetup.cxx +++ b/reco/L1/qa/CbmCaInputQaSetup.cxx @@ -12,6 +12,7 @@ #include "CbmCaParametersHandler.h" #include "CbmL1DetectorID.h" #include "CbmMCDataManager.h" +#include "CbmSetup.h" #include "FairRootManager.h" #include "TAxis.h" @@ -49,6 +50,23 @@ void InputQaSetup::CheckInit() const } } +// --------------------------------------------------------------------------------------------------------------------- +// +void InputQaSetup::CheckoutDetectors() +{ + auto CheckDetector = [&](ca::EDetectorID detID) { + if (CbmSetup::Instance()->IsActive(ToCbmModuleId(detID))) { + fvbUseDet[detID] = true; + } + L_(info) << fName << ": " << ToString(ToCbmModuleId(detID)) << " " << fvbUseDet[detID]; + }; + CheckDetector(ca::EDetectorID::kMvd); + CheckDetector(ca::EDetectorID::kSts); + CheckDetector(ca::EDetectorID::kMuch); + CheckDetector(ca::EDetectorID::kTrd); + CheckDetector(ca::EDetectorID::kTof); +} + // --------------------------------------------------------------------------------------------------------------------- // void InputQaSetup::CreateSummary() @@ -252,6 +270,7 @@ void InputQaSetup::ExecQa() InitStatus InputQaSetup::InitQa() try { LOG(info) << fName << ": initializing... "; + CheckoutDetectors(); // Tracking parameters fpParameters = cbm::ca::ParametersHandler::Instance()->Get(fsParametersFilename); @@ -285,6 +304,9 @@ try { auto InitHitBranch = [&](const char* brName, ca::EDetectorID detID) { if (fvbUseDet[detID]) { fvpBrHits[detID] = dynamic_cast<TClonesArray*>(pFairManager->GetObject(brName)); + if (!fvpBrHits[detID]) { + fvbUseDet[detID] = false; // Disable detectors without hits + } } return static_cast<bool>(fvpBrHits[detID]); }; diff --git a/reco/L1/qa/CbmCaInputQaSetup.h b/reco/L1/qa/CbmCaInputQaSetup.h index 3cf3ad887a4a3eec64f2ce89ac56c78b23abea13..2196339f45beb504e99c3797c8a5e2d80b2e9f7d 100644 --- a/reco/L1/qa/CbmCaInputQaSetup.h +++ b/reco/L1/qa/CbmCaInputQaSetup.h @@ -64,6 +64,9 @@ namespace cbm::ca private: + /// \brief Check out initialized detectors + void CheckoutDetectors(); + /// \brief Checks branches initialization void CheckInit() const;