From 05951078d7fb66290e44c950b8c3414346af29fa Mon Sep 17 00:00:00 2001 From: "s.zharko@gsi.de" <s.zharko@gsi.de> Date: Thu, 23 Jan 2025 19:57:01 +0100 Subject: [PATCH] reco_mcbm.sh and KFPF lambda in mCBM: 1. reco_mcbm.sh: New options (separate directory for different steps, lambda in mCBM, retrieving a tsa file name from and index list) 2. reco_mcbm_job.sh: Settings to run reco_mcbm.sh from the box on virgo (vs. runID and jobID) 3. cbm::kfp::V0FinderTask: minor bug fixes --- macro/beamtime/mcbm2024/mcbm_event_reco_L1.C | 2 +- macro/beamtime/mcbm2024/reco_mcbm.sh | 324 ++++++++++++++++--- macro/beamtime/mcbm2024/reco_mcbm_job.sh | 131 ++++++++ macro/mcbm/mcbm_hadron_kfp_ana.C | 7 +- reco/KF/CbmKFV0FinderQa.cxx | 4 + reco/KF/CbmKFV0FinderQa.h | 2 +- reco/KF/CbmKFV0FinderTask.cxx | 23 +- reco/KF/CbmKFV0FinderTask.h | 1 + reco/L1/CbmL1.cxx | 9 +- 9 files changed, 456 insertions(+), 47 deletions(-) create mode 100755 macro/beamtime/mcbm2024/reco_mcbm_job.sh diff --git a/macro/beamtime/mcbm2024/mcbm_event_reco_L1.C b/macro/beamtime/mcbm2024/mcbm_event_reco_L1.C index 7be5360c69..67e2848c21 100644 --- a/macro/beamtime/mcbm2024/mcbm_event_reco_L1.C +++ b/macro/beamtime/mcbm2024/mcbm_event_reco_L1.C @@ -727,7 +727,7 @@ Bool_t mcbm_event_reco_L1(UInt_t uRunId = 3105, // ----- Function needed for CTest runtime dependency ----------------- - // RemoveGeoManager(); + RemoveGeoManager(); // ------------------------------------------------------------------------ /// --- Screen output for automatic tests diff --git a/macro/beamtime/mcbm2024/reco_mcbm.sh b/macro/beamtime/mcbm2024/reco_mcbm.sh index 51c9e57176..cd5ac8a665 100755 --- a/macro/beamtime/mcbm2024/reco_mcbm.sh +++ b/macro/beamtime/mcbm2024/reco_mcbm.sh @@ -1,5 +1,5 @@ #!/bin/bash -# Copyright (C) 2024 GSI Helmholtzzentrum fuer Schwerionenforschung, Darmstadt +# Copyright (C) 2024-2025 GSI Helmholtzzentrum fuer Schwerionenforschung, Darmstadt # SPDX-License-Identifier: GPL-3.0-only # Authors: Sergei Zharko [committer], Pierre-Alain Loizeau # @@ -9,7 +9,7 @@ # @author Sergei Zharko <s.zharko@gsi.de> # # ********************************************************************************************************************** -# *** User Manual (v. 0.0.2, 05.07.2024) *** +# *** User Manual (v. 0.1.0, 22.01.2025) *** # ********************************************************************************************************************** # # 1. Definitions @@ -24,22 +24,44 @@ # 2. Introduction # # This script aims to provide a generic data reconstruction scenario in mCBM, which includes: -# - setup files generation: [--setup] -# - TSA file unpacking [--unpack] -# - reconstruction [--reco] -# - main QA [--qa] -# - reconstruciton QA (Alex) [--qa-module] +# - setup files generation: [--setup] +# - setup files generation: [--setup-only] (Special flag, to be called, if the other steps must not be selected) +# - TSA file unpacking [--unpack] +# - reconstruction [--reco] +# - main QA [--qa] +# - reconstruciton QA (Alex) [--qa-module] +# - KF Particle Finder (Lambda) [--kfpf] # # Required options: # --tsa <path> Path to the input TSA file # NOTE: must contain a run index as a first integer in its base name. +# OR +# +# --tsa-index-file <file> A path to a text file with a list of TSAs. The line of the file equals to the job number +# +# OR +# +# --run <runID> Run identifier, BUT ONLY, IF ONLY THE SETUP IS NEEDED (--setup-only) +# # Auxiliary options: # -n [--nts] <N_TS> Number of timeslices to procede # --setup, --unpack, --reco, --qa, --qa-module -# --data-dir Path to output directory +# --data-dir <path> Path to output directory # --param-online <path> Path to the online parameters # NOTE: should be ${VMCWORKDIR}/parameters/online, but local user may have copy for testing # +# --setup-dir <path> Path to the setup output +# --unpack-dir <path> Path to the unpacking output +# --reco-dir <path> Path to the reconstruction output +# --qa-dir <path> Path to the QA output +# --kfpf-dir <path> Path to the KFPF output +# NOTE: if any of these parameters are not provided, the corresponding data will be stored to the <top_dir>. If the +# corresponding path is a relative path (!=realpath), the <top_dir> will be selected is the parent directory +# +# Options for running on the batch farm: +# -j [--job] <jobId> Index of the job (default == 1) +# +# # 3. File names involved: # <geo>: Input geometry file: <top_dir>/<setup>.geo.root # <par>: Input parameter file: <top_dir>/<setup>.par.root --copy--> <top_dir>/<label>.par.root @@ -48,6 +70,8 @@ # <reco>: Reconstruction output: <top_dir>/<label>.reco.root --ln--> <top_dir>/<label>.rec.root # <qa>: Main QA output: <top_dir>/<label>.qa.root # <qa-module>: Reconstruction module QA: <top_dir>/<label>.rqa.root +# <kfp.ana>: Output from the lambda analysis: <top_dir>/<label>.kfp.ana.root +# [optional] QA file: <top_dir>/<label>.qa.kfp.ana.root # # 4. Knwon missing features # @@ -96,6 +120,7 @@ RECO_EvB=1 RECO_CA=1 RECO_PV=1 RECO_QA=0 +LAMBDA_MIXED_EVENT=0 # ---------------------------------------------------------------------------------------------------------------------- @@ -107,37 +132,67 @@ RECO_QA=0 # ************************* # ----- Execution steps +I_WANT_ONLY_SETUP=0 DO_CREATE_SETUP=0 DO_UNPACK=0 DO_RECO=0 DO_QA=0 # Main QA Macro DO_QA_MODULE=0 # QA Macro by Alexandru +DO_LAMBDA=0 # Lambda analysis using KFParticleFinder +STEPS_TO_PRINT="" + ONLINE_PAR=${VMCWORKDIR}/parameters/online + +# ----- Subdirectories +DIR_SETUP="" +DIR_UNPACK="" +DIR_RECO="" +DIR_QA="" +DIR_KFPF="" + # ----- Run information RUN=-1 +RUN_IF_ONLY_SETUP_NEEDED=0 TSA= N_TS=-1 +TSA_INDEX=0 +JOB_ID=1 while [[ $# -gt 0 ]]; do case ${1} in --setup ) DO_CREATE_SETUP=1 + STEPS_TO_PRINT="${STEPS_TO_PRINT} --setup" ;; --unpack ) DO_UNPACK=1 + STEPS_TO_PRINT="${STEPS_TO_PRINT} --unpack" ;; --reco ) DO_RECO=1 + STEPS_TO_PRINT="${STEPS_TO_PRINT} --reco" ;; --qa ) DO_QA=1 + STEPS_TO_PRINT="${STEPS_TO_PRINT} --qa" ;; --qa-module ) DO_QA_MODULE=1 + STEPS_TO_PRINT="${STEPS_TO_PRINT} --qa-module" + ;; + --kfpf ) + DO_LAMBDA=1 + STEPS_TO_PRINT="${STEPS_TO_PRINT} --kfpf" ;; --tsa ) TSA=${2} ;; + --tsa-index-file ) + TSA_INDEX=${2} + ;; + -j | --job ) + JOB_ID=${2} + ;; --param-online ) ONLINE_PAR=${2} ;; @@ -147,10 +202,105 @@ while [[ $# -gt 0 ]]; do --data-dir ) DATA_TOP_DIR=${2} ;; + --setup-dir ) + DIR_SETUP=${2} + ;; + --unpack-dir ) + DIR_UNPACK=${2} + ;; + --reco-dir ) + DIR_RECO=${2} + ;; + --qa-dir ) + DIR_QA=${2} + ;; + --kfpf-dir ) + DIR_KFPF=${2} + ;; + --setup-only ) + I_WANT_ONLY_SETUP=1 + ;; + --run ) + RUN_IF_ONLY_SETUP_NEEDED=${2} + ;; esac shift done + +# ------ Re-define the paths to step directories +DATA_TOP_DIR=$(realpath -m ${DATA_TOP_DIR}) + +if [[ -z ${DIR_SETUP} ]]; then + DIR_SETUP=${DATA_TOP_DIR} +else + DIR_SETUP=$(realpath -m ${DIR_SETUP}) +fi + +if [[ -z ${DIR_UNPACK} ]]; then + DIR_UNPACK=${DATA_TOP_DIR} +else + DIR_UNPACK=$(realpath -m ${DIR_UNPACK}) +fi + + +if [[ -z ${DIR_RECO} ]]; then + DIR_RECO=${DATA_TOP_DIR} +else + DIR_RECO=$(realpath -m ${DIR_RECO}) +fi + +if [[ -z ${DIR_QA} ]]; then + DIR_QA=${DATA_TOP_DIR} +else + DIR_QA=$(realpath -m ${DIR_QA}) +fi + +if [[ -z ${DIR_KFPF} ]]; then + DIR_KFPF=${DATA_TOP_DIR} +else + DIR_KFPF=$(realpath -m ${DIR_KFPF}) +fi + +printf "\n" +printf "\n" +printf "\t********************************************************************************************\n" +printf "\t*** ***\n" +printf "\t*** --- The Compressed Baryonic Matter Experiment: Data Reconstruction Routine --- ***\n" +printf "\t*** ***\n" +printf "\t********************************************************************************************\n\n\n" + + + +printf "***\n" +printf "*** Data directories:\n" +printf "***\n\n" +printf "\tSetup: ${DIR_SETUP}\n" +printf "\tUnpacking output: ${DIR_UNPACK}\n" +printf "\tReconstruction output: ${DIR_RECO}\n" +printf "\tQA output: ${DIR_QA}\n" +printf "\tKFPF output: ${DIR_KFPF}\n\n\n" + +# ----- Redifine the TSA input, if the TSA index and job were provided +# +# TODO: Add check on the integer for JOB_ID +if [[ ${TSA_INDEX} != 0 && ! -z ${TSA_INDEX} ]]; then + if [[ ${JOB_ID} -le 0 ]]; then + exit 100; # illegal job number + fi + TSA=$(sed -n "${JOB_ID}p" "${TSA_INDEX}") +fi +printf "***\n" +printf "*** Input:\n" +printf "***\n\n" +printf "\tTSA: ${TSA}\n" +printf "\tJOB: ${JOB_ID}\n" +printf "\tROUTINE STEPS: ${STEPS_TO_PRINT}\n" +printf "\n\n" + + + + # ----- Check the environment # if [[ -z "${VMCWORKDIR}" ]]; then @@ -177,19 +327,48 @@ fi printf "I- Online binary path: %s, with parameters: %s\n" ${ONLINE_BINARY} ${ONLINE_PAR} + # ----- Check the TSA input and retrieve the run index -if [[ -z ${TSA} ]]; then - printf "E- TSA input file is not defined\n" - exit 3 +if [[ ${I_WANT_ONLY_SETUP} -ne 1 ]]; then + if [[ -z ${TSA} ]]; then + printf "E- TSA input file is not defined\n" + exit 3 + fi + TSA_INFO=($(basename $(echo ${TSA}) | grep -oE '[0-9]*')) + + RUN=${TSA_INFO[0]} # Implying, that TSA basename contains run index as the first integer +fi + + +if [[ ${I_WANT_ONLY_SETUP} -eq 1 ]]; then + DO_CREATE_SETUP=1 + DO_UNPACK=0 + DO_RECO=0 + DO_QA=0 + DO_QA_MODULE=0 + DO_LAMBDA=0 + STEPS_TO_PRINT=" --setup" + if [[ ${RUN} -lt 0 ]]; then + RUN=${RUN_IF_ONLY_SETUP_NEEDED} + fi fi -TSA_INFO=($(basename $(echo ${TSA}) | grep -oE '[0-9]*')) -RUN=${TSA_INFO[0]} # Implying, that TSA basename contains run index as the first integer if [[ ${RUN} -lt 0 ]]; then printf "E- Run number is undefined, please try again with option -r <RUN> or --run <RUN>\n" fi -mkdir -p ${DATA_TOP_DIR} +if [[ DO_UNPACK -eq 1 ]]; then + mkdir -p ${DIR_UNPACK} +fi +if [[ DO_RECO -eq 1 ]]; then + mkdir -p ${DIR_RECO} +fi +if [[ DO_QA -eq 1 && DO_QA_MODULE -eq 1 ]]; then + mkdir -p ${DIR_QA} +fi +if [[ DO_LAMBDA -eq 1 ]]; then + mkdir -p ${DIR_KFPF} +fi # ----- Filenames definition TSA_INP=${TSA} @@ -197,10 +376,14 @@ MACRO_SETUP="${VMCWORKDIR}/macro/run/create_mcbm_geo_setup.C" MACRO_RECO="${VMCWORKDIR}/macro/beamtime/mcbm2022/mcbm_event_reco_L1.C" MACRO_QA="${VMCWORKDIR}/macro/mcbm/mcbm_qa.C" MACRO_QA_MODULE="${VMCWORKDIR}/macro/qa/run_recoQa.C" +MACRO_KFPF="${VMCWORKDIR}/macro/mcbm/mcbm_hadron_kfp_ana.C" SETUP_NAME= -# ----- !!! Setting selections vs. - +# ----- !!! Setting selections vs. run number +# FIXME: map of the run number range to a particular setup geometry tag must be stored in a text (yaml/ascii/json/...) file +# in the cbmroot_parameters or cbmroot_geometry. Until then the setup tags are defined here explicitly. +# +# if [[ ${RUN} -ge 2350 && ${RUN} -le 2397 ]]; then SETUP_NAME="mcbm_beam_2022_05_23_nickel" MACRO_RECO="${VMCWORKDIR}/macro/beamtime/mcbm2022/mcbm_event_reco_L1.C" @@ -222,10 +405,21 @@ else fi # ----- -# File -FILE_LABEL=$(printf $(basename ${TSA_INP}) | cut -f 1 -d '.') -OUT_DIGI="${DATA_TOP_DIR}/${FILE_LABEL}.digi.out" -INP_FILE="${DATA_TOP_DIR}/${FILE_LABEL}.digi.root" +# Data file names +FILE_LABEL="test" +if [[ ${I_WANT_ONLY_SETUP} -ne 1 ]]; then + FILE_LABEL=$(printf $(basename ${TSA_INP}) | cut -f 1 -d '.') +fi +DIGI_ONLINE_FILE="${DIR_UNPACK}/${FILE_LABEL}.digi.out" +DIGI_OFFLINE_FILE="${DIR_UNPACK}/${FILE_LABEL}.digi.root" +SETUP_PAR_FILE="${DIR_SETUP}/${SETUP_NAME}.par.root" +SETUP_GEO_FILE="${DIR_SETUP}/${SETUP_NAME}.geo.root" +RECO_PAR_FILE="${DIR_RECO}/${FILE_LABEL}.par.root" +RECO_FILE="${DIR_RECO}/${FILE_LABEL}.rec.root" +KF_SETUP_FILE="${DIR_RECO}/${FILE_LABEL}.rec.kf.setup" +KF_MATERIAL="${DIR_RECO}/${SETUP_NAME}." +CA_PAR_FILE="${DIR_RECO}/${FILE_LABEL}.rec.ca.par" + # ----- # Log Files @@ -234,6 +428,7 @@ UNPACK_LOG="run_mcbm_unpack.log" RECO_LOG="run_mcbm_reco.log" RECO_QA_LOG="run_mcbm_reco_qa.log" QA_LOG="run_mcbm_qa.log" +KFPF_LOG="run_mcbm_kfpf.log" # ********************* # ** Steps execution ** @@ -241,7 +436,7 @@ QA_LOG="run_mcbm_qa.log" # ----- Create setup files if [[ ${DO_CREATE_SETUP} -eq 1 ]]; then - root -b -l -q ${MACRO_SETUP}"(${RUN}, \"${DATA_TOP_DIR}\")" &> ${SETUP_LOG} + root -b -l -q ${MACRO_SETUP}"(${RUN}, \"${DIR_SETUP}\")" &> ${SETUP_LOG} cat ${SETUP_LOG} if [[ (1 -ne $(grep -c " Test passed" "${SETUP_LOG}")) || (1 -ne $(grep -c " All ok " "${SETUP_LOG}")) ]]; then @@ -252,14 +447,18 @@ if [[ ${DO_CREATE_SETUP} -eq 1 ]]; then rm ${SETUP_LOG} fi +if [[ ${I_WANT_ONLY_SETUP} -eq 1 ]]; then + exit 0 +fi + # ----- Run unpacker if [[ ${DO_UNPACK} -eq 1 ]]; then # TODO: Define unpack options for different setups - ${ONLINE_BINARY} --steps Unpack -i ${TSA_INP} -r ${RUN} -p ${ONLINE_PAR} -O DigiTimeslice -o ${OUT_DIGI} -s STS BMON TOF TRD RICH -n ${N_TS} + ${ONLINE_BINARY} --steps Unpack -i ${TSA_INP} -r ${RUN} -p ${ONLINE_PAR} -O DigiTimeslice -o ${DIGI_ONLINE_FILE} -s STS BMON TOF TRD RICH -n ${N_TS} - root -l -b -q ${VMCWORKDIR}/macro/run/run_inspect_digi_timeslice.C"(\"${OUT_DIGI}\", \"${INP_FILE}\")" &> ${UNPACK_LOG} + root -l -b -q ${VMCWORKDIR}/macro/run/run_inspect_digi_timeslice.C"(\"${DIGI_ONLINE_FILE}\", \"${DIGI_OFFLINE_FILE}\")" &> ${UNPACK_LOG} cat ${UNPACK_LOG} - rm ${OUT_DIGI} + rm ${DIGI_ONLINE_FILE} if [[ 1 -ne $(grep -c "Macro finished successfully." "${UNPACK_LOG}") ]]; then printf "\nUnpacked data file conversion of %s failed, stopping there\n" "${TSA_INP}" @@ -272,11 +471,26 @@ fi # ----- Run reconstruction if [[ ${DO_RECO} -eq 1 ]]; then UNP_FILE_ID=-1 - cp "${DATA_TOP_DIR}/${SETUP_NAME}.par.root" "${DATA_TOP_DIR}/${FILE_LABEL}.par.root" - DATA_PREF="${DATA_TOP_DIR}" - PARS="${RUN},${N_TS},\"${DATA_PREF}\",\"${DATA_PREF}\",${UNP_FILE_ID},${RECO_MVD},${RECO_STS},${RECO_TRD}" + RECO_DIGI_INPUT="${DIR_RECO}/${FILE_LABEL}.digi.root"; + RECO_GEO_INPUT="${DIR_RECO}/${SETUP_NAME}.geo.root" + if [[ ${RECO_DIGI_INPUT} != ${DIGI_OFFLINE_FILE} ]]; then + pushd . + cd ${DIR_RECO} + ln -s -f ${DIGI_OFFLINE_FILE} $(basename ${RECO_DIGI_INPUT}) + popd + fi + if [[ ${SETUP_GEO_FILE} != ${RECO_GEO_INPUT} ]]; then + pushd . + cd ${DIR_RECO} + ln -s -f ${SETUP_GEO_FILE} $(basename ${RECO_GEO_INPUT}) + popd + fi + + cp ${SETUP_PAR_FILE} ${RECO_PAR_FILE} + + PARS="${RUN},${N_TS},\"${DIR_RECO}\",\"${DIR_RECO}\",${UNP_FILE_ID},${RECO_MVD},${RECO_STS},${RECO_TRD}" PARS="${PARS},${RECO_TRD2d},${RECO_RICH},${RECO_MUCH},${RECO_TOF},${RECO_TOFtr},${RECO_PSD},${RECO_ALI},${RECO_EvB}" - PARS="${PARS},${RECO_CA},${RECO_QA},${RECO_FSD},\"${INP_FILE}\"" + PARS="${PARS},${RECO_CA},${RECO_QA},${RECO_FSD},\"${RECO_DIGI_INPUT}\"" if [[ ${MACRO_RECO} == "*.mcbm2024*" ]]; then PARS="${PARS},${RECO_PV}" fi @@ -290,16 +504,35 @@ if [[ ${DO_RECO} -eq 1 ]]; then fi rm ${RECO_LOG} - ln -s -f "${FILE_LABEL}.digi.root" "${DATA_TOP_DIR}/${FILE_LABEL}.raw.root" # TMP for QA + # 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 fi # ----- Run QA of reco modules if [[ ${DO_QA_MODULE} -eq 1 ]]; then - QA_GEO="${DATA_TOP_DIR}/${SETUP_NAME}.geo.root" - QA_REC="${DATA_TOP_DIR}/${FILE_LABEL}.rec.root" - ln -s -f ${QA_GEO} "${SETUP_NAME}.geo.root" + QA_GEO="${DIR_QA}/${SETUP_NAME}.geo.root" + QA_REC="${DIR_QA}/${FILE_LABEL}.rec.root" + QA_PAR="${DIR_QA}/${FILE_LABEL}.par.root" + if [[ ${QA_REC} != ${RECO_FILE} ]]; then + pushd . + cd ${DIR_QA} + ln -s -f $(realpath ${RECO_FILE}) $(basename ${QA_REC}) + popd + fi + if [[ ${QA_GEO} != ${SETUP_GEO_FILE} ]]; then + pushd . + cd ${DIR_QA} + ln -s -f $(realpath ${SETUP_GEO_FILE}) $(basename ${QA_GEO}) + popd + fi + if [[ ${QA_REC} != ${RECO_FILE} ]]; then + pushd . + cd ${DIR_QA} + ln -s -f $(realpath ${RECO_PAR_FILE}) $(basename ${QA_PAR}) + popd + fi + PARS="-1,\"${QA_REC}\",\"${SETUP_NAME}\",kFALSE,${RECO_ALI}" root -b -l -q ${MACRO_QA_MODULE}"(${PARS})" &> ${RECO_QA_LOG} cat ${RECO_QA_LOG} @@ -318,11 +551,11 @@ if [[ ${DO_QA} -eq 1 ]]; then CONFIG="" BENCHMARK="" #PARS="1,\"${DATA_TOP_DIR}/${FILE_LABEL}\",\"${SETUP_NAME}\",${USE_MC},\"${CONFIG}\",\"${BENCHMARK}\"" - QA_RAW="${DATA_TOP_DIR}/${FILE_LABEL}.raw.root" - QA_REC="${DATA_TOP_DIR}/${FILE_LABEL}.rec.root" - QA_PAR="${DATA_TOP_DIR}/${FILE_LABEL}.par.root" - QA_GEO="${DATA_TOP_DIR}/${SETUP_NAME}.geo.root" - QA_OUT="${DATA_TOP_DIR}/${FILE_LABEL}.qa.root" + QA_RAW=${DIGI_OFFLINE_FILE} + QA_REC=${RECO_FILE} + QA_PAR=${RECO_PAR_FILE} + QA_GEO=${SETUP_QA_LOG} + QA_OUT="${DIR_QA}/${FILE_LABEL}.qa.root" PARS="0,\"\",\"${QA_RAW}\",\"${QA_REC}\",\"${QA_PAR}\",\"${QA_GEO}\",\"${QA_OUT}\",\"${SETUP_NAME}\"" PARS="${PARS},${USE_MC},\"${CONFIG}\",\"${BENCHMARK}\",${RECO_ALI}" @@ -338,4 +571,21 @@ if [[ ${DO_QA} -eq 1 ]]; then rm ${QA_LOG} fi +# ----- Run Lambda reconstuction using the KFParticleFinder +if [[ ${DO_LAMBDA} -eq 1 ]]; then + LAMBDA_FST_TS=0 + LAMBDA_LST_TS=0 # Run all the data produced by reconstruction + LAMBDA_IN_REC=${RECO_FILE} + LAMBDA_IN_TRA="\"\",\"\",\"\"" # Empty for real data + LAMBDA_OUT="${DIR_KFPF}/${FILE_LABEL}.kfp.ana.root" + LAMBDA_IN_GEO=${SETUP_QA_LOG} + LAMBDA_IN_PAR=${RECO_PAR_FILE} + LAMBDA_USE_MC="false" + PARS="${RUN},${LAMBDA_FST_TS},${LAMBDA_LST_TS},\"${LAMBDA_IN_REC}\",${LAMBDA_IN_TRA},\"${LAMBDA_OUT}\",\"${LAMBDA_IN_GEO}\"" + PARS="${PARS},\"${LAMBDA_IN_PAR}\",${RECO_ALI},${LAMBDA_MIXED_EVENT},${LAMBDA_USE_MC}" + + root -b -l -q ${MACRO_KFPF}"(${PARS})" +fi + + printf "Reconstruction of %s succeeded\n" "${TSA_INP}" diff --git a/macro/beamtime/mcbm2024/reco_mcbm_job.sh b/macro/beamtime/mcbm2024/reco_mcbm_job.sh new file mode 100755 index 0000000000..e549d0d36a --- /dev/null +++ b/macro/beamtime/mcbm2024/reco_mcbm_job.sh @@ -0,0 +1,131 @@ +#!/bin/bash +# Copyright (C) 2025 GSI Helmholtzzentrum fuer Schwerionenforschung, Darmstadt +# SPDX-License-Identifier: GPL-3.0-only +# Authors: Sergei Zharko [committer] +# +# @file reco_mcbm_job.sh +# @brief Script to run a particular job on VIRGO +# @since 23.01.2025 +# @author Sergei Zharko <s.zharko@gsi.de> +# +# The script defines environment to reconstruct time slices vs. a particular job using VIRGO. +# To run the script one has to export a variable MCBM_DATA_DIR -- a path to the real data directory. +# +# +# OPTIONS: +# +# 1. Required: +# (A) SETUP GENERATION: +# --setup: Runs in setup generation mode +# --run <num> Sets run ID (<num> must be an integer with 4 digits) +# +# (B) DATA RECONSTRUCTION: +# --tsa-index <path> Path to the text file with absolute paths to input TSA files +# Each line of the file corresponds to the job index. +# --job | -j <num> Job index (from 1 to number of files, defined under the option --tsa-index) +# --run <num> Sets run ID (<num> must be an integer with 4 digits) +# +# +# 2. Optional (in mode (B)): +# --unpack, --reco, --qa, --qa-module, --kfpf, -n -- See the reco_mcbm.sh script for details +# + +RECO_OPTIONS="" +RUN="" +JOB="" +DO_GENERATE_SETUP=0 +TSA_INDEX= +# ------ Option selection ---------------------------------------------------------------------------------------------- +while [[ $# -gt 0 ]]; do + case ${1} in + --setup ) + DO_GENERATE_SETUP=1 + ;; + --unpack ) + RECO_OPTIONS="${RECO_OPTIONS} --unpack" + ;; + --reco ) + RECO_OPTIONS="${RECO_OPTIONS} --reco" + ;; + --qa ) + RECO_OPTIONS="${RECO_OPTIONS} --qa" + ;; + --qa-module ) + RECO_OPTIONS="${RECO_OPTIONS} --qa-module" + ;; + --kfpf ) + RECO_OPTIONS="${RECO_OPTIONS} --kfpf" + ;; + --run ) + RUN=${2} + ;; + -n ) + RECO_OPTIONS="${RECO_OPTIONS} -n ${2}" + ;; + -j | --job ) + JOB=${2} + ;; + --tsa-index ) + TSA_INDEX=${2} + ;; + esac + shift +done + +# ------ Variable check ------------------------------------------------------------------------------------------------ +if [[ -z "${VMCWORKDIR}" ]]; then + printf "E- CBM environment is not defined (VMCWORKDIR is not found). Please, configure your CbmRoot\n" + exit 1 +fi + +if [[ -z ${RUN} ]]; then + printf "E- The run identifier is not specified. Please, specify it using the option \"--run <run_id>\"\n" + exit 2 +fi + +if [[ -z ${JOB} && ${DO_GENERATE_SETUP} -ne 1 ]]; then + printf "E- The job number is not specified. Please set the job number using the option \"-j <job>\"\n" + exit 3 +fi + +if [[ -z ${MCBM_DATA_DIR} ]]; then + printf "E- The data directory is not identified. Please provide the path to the directory, using the following bash " + printf "command\n\t export MCBM_DATA_DIR=<path to data directory>\n" + exit 4 +fi + +# ------ Script execution ---------------------------------------------------------------------------------------------- +mkdir -p ${MCBM_DATA_DIR} + +DIR_UNPACK=${MCBM_DATA_DIR}/unpacked_data/${RUN} +DIR_RECO=${MCBM_DATA_DIR}/reconstructed_data/${RUN} +DIR_SETUP=${MCBM_DATA_DIR}/setups +DIR_QA=${MCBM_DATA_DIR}/qa/${RUN} +DIR_KFPF=${MCBM_DATA_DIR}/kfpf/${RUN} + +# NOTE: either the setup is generated, or the data are produced. +if [[ ${DO_GENERATE_SETUP} -eq 1 ]]; then + RECO_OPTIONS=" --setup-only --run ${RUN}" +else + if [[ -f ${TSA_INDEX} ]]; then + TSA_INDEX=$(realpath ${TSA_INDEX}) + RECO_OPTIONS="${RECO_OPTIONS} --tsa-index-file ${TSA_INDEX}" + else + printf "E- TSA index file ${TSA_INDEX} was not found\n" + exit 5 + fi +fi + +RECO_OPTIONS="${RECO_OPTIONS} --setup-dir ${DIR_SETUP} --unpack-dir ${DIR_UNPACK} --reco-dir ${DIR_RECO} --qa-dir ${DIR_QA} --kfpf-dir ${DIR_KFPF}" + +RECO_SCRIPT=${VMCWORKDIR}/macro/beamtime/mcbm2024/reco_mcbm.sh + +if [[ ! -x ${RECO_SCRIPT} ]]; then + printf "E- The reco script (${RECO_SCRIPT}) either does not exist, or is not executable. Please make it executable " + printf "with the \"chmod +x\" command\n" + exit 6 +fi + +${RECO_SCRIPT} ${RECO_OPTIONS} + + diff --git a/macro/mcbm/mcbm_hadron_kfp_ana.C b/macro/mcbm/mcbm_hadron_kfp_ana.C index b48dd99436..bd44f80b29 100644 --- a/macro/mcbm/mcbm_hadron_kfp_ana.C +++ b/macro/mcbm/mcbm_hadron_kfp_ana.C @@ -47,7 +47,7 @@ /* clang-format off */ Bool_t mcbm_hadron_kfp_ana(UInt_t uRunId = 2391, Int_t firstTimeslice = 0, - Int_t nTimeslices = 10, + Int_t nTimeslices = 0, TString sRecoFile = "./data/2391_first20Ts.rec.root", TString sCollTraFile = "", TString sSignTraFile = "", @@ -182,7 +182,8 @@ Bool_t mcbm_hadron_kfp_ana(UInt_t uRunId = 2391, // The task parameters: pV0->SetMinPionDca(1.5); pV0->SetMinProtonDca(0.5); - pV0->SetTzeroOffset(0.12); + //pV0->SetTzeroOffset(0.12); + pV0->SetTzeroOffset(0.); pV0->SetQpAssignedUncertainty(0.10); // 10% uncertainty for track q/p pV0->SetMixedEventMode(bMixEvent); pV0->SetProcessingMode(cbm::kfp::V0FinderTask::EProcessingMode::TimeBased); @@ -201,7 +202,7 @@ Bool_t mcbm_hadron_kfp_ana(UInt_t uRunId = 2391, // QA output setting { TString sQaFile{sSinkFile}; - sQaFile.ReplaceAll(".ana.", "_qa.ana."); + sQaFile.ReplaceAll(".kfp.ana.", ".qa.kfp.ana."); pV0->SetQaOutputFileName(sQaFile); pV0->SetRunQa(true); } diff --git a/reco/KF/CbmKFV0FinderQa.cxx b/reco/KF/CbmKFV0FinderQa.cxx index 6b6b1e5463..a079aa3b5e 100644 --- a/reco/KF/CbmKFV0FinderQa.cxx +++ b/reco/KF/CbmKFV0FinderQa.cxx @@ -46,6 +46,10 @@ void V0FinderQa::InitHistograms() n = "dca_projectionY"; t = "DCA to the origin of the selected tracks;dca_{y} [cm];Counts"; fph_dca_projectionY = MakeQaObject<TH1D>(n, t, 240, -6., 6.); + + n = "lambda_cand_mass"; + t = "Mass of lambda candidate;m [GeV/^{2}];Counts"; + fph_lambda_cand_mass = MakeQaObject<TH1D>(n, t, 200, 1.05, 1.15); } } diff --git a/reco/KF/CbmKFV0FinderQa.h b/reco/KF/CbmKFV0FinderQa.h index 53091e0112..bf608d4aae 100644 --- a/reco/KF/CbmKFV0FinderQa.h +++ b/reco/KF/CbmKFV0FinderQa.h @@ -56,7 +56,7 @@ namespace cbm::kfp TH2D* fph_track_rapidity_vs_pt_all{nullptr}; ///< Phase space of all accepted tracks TH2D* fph_track_rapidity_vs_pt_pion{nullptr}; ///< Phase space of pion candidates TH2D* fph_track_rapidity_vs_pt_proton{nullptr}; ///< Phase space of proton candidates - + TH1D* fph_lambda_cand_mass{nullptr}; ///< Mass of lambda candidates private: bool fbUseMc{false}; diff --git a/reco/KF/CbmKFV0FinderTask.cxx b/reco/KF/CbmKFV0FinderTask.cxx index 2ec69f809c..e29f13b209 100644 --- a/reco/KF/CbmKFV0FinderTask.cxx +++ b/reco/KF/CbmKFV0FinderTask.cxx @@ -119,7 +119,11 @@ bool V0FinderTask::ProcessEvent(const CbmEvent* pEvent) // ----- Shift TOF hit times to t0 if constexpr (UseEvent) { - ShiftTofHitsToTzero(pEvent); + auto t0 = ShiftTofHitsToTzero(pEvent); + if (std::isnan(t0)) { + ++fCounters[ECounter::EventsWoTzero]; + return false; + } } // ----- Select tracks @@ -176,8 +180,16 @@ bool V0FinderTask::ProcessEvent(const CbmEvent* pEvent) fpTopoReconstructorEvent->ReconstructParticles(); // ----- Count number of found lambda-candidates - const auto& particles = fpTopoReconstructorEvent->GetParticles(); - int nLambda = std::count_if(particles.begin(), particles.end(), [](const auto& p) { return p.GetPDG() == 3122; }); + int nLambda = 0; + //std::count_if(particles.begin(), particles.end(), [](const auto& p) { return p.GetPDG() == 3122; }); + for (const auto& particle : fpTopoReconstructorEvent->GetParticles()) { + if (particle.GetPDG() == 3122) { + ++nLambda; + if (fbRunQa) { + fpQa->fph_lambda_cand_mass->Fill(particle.GetMass()); + } + } + } fCounters[ECounter::KfpLambdaCandidates] += nLambda; if (nLambda > 0) { ++fCounters[ECounter::KfpEventsLambdaCand]; @@ -346,6 +358,7 @@ void V0FinderTask::Finish() msg << "\n pion candidates: " << fCounters[ECounter::Pions]; msg << "\n proton candidates: " << fCounters[ECounter::Protons]; msg << "\n events total: " << fCounters[ECounter::EventsTotal]; + msg << "\n events w/o t-zero: " << fCounters[ECounter::EventsWoTzero]; msg << "\n events w/ potential Lambda-candidate: " << fCounters[ECounter::EventsLambdaCand]; msg << "\n events w/ Lambda-candidate from KFPF: " << fCounters[ECounter::KfpEventsLambdaCand]; msg << "\n Lambda-candidates: " << fCounters[ECounter::KfpLambdaCandidates]; @@ -680,7 +693,9 @@ double V0FinderTask::ShiftTofHitsToTzero(const CbmEvent* pEvent) // NOTE: t0 must be defined for each event, since the Bmon digis are used to seed the digi event builder. Basically, // the tZero must be defined as a field of CbmEvent, e.g. in a separate FairTask, or directly // in CbmAlgoBuildRawEvent - assert(!std::isnan(t0)); + if (std::isnan(t0)) { + return t0; + } // Shift TOF times to found t0: for (int iTofHitEvt{0}; iTofHitEvt < nTofHits; ++iTofHitEvt) { diff --git a/reco/KF/CbmKFV0FinderTask.h b/reco/KF/CbmKFV0FinderTask.h index 567c0e721f..6fb0bbf368 100644 --- a/reco/KF/CbmKFV0FinderTask.h +++ b/reco/KF/CbmKFV0FinderTask.h @@ -73,6 +73,7 @@ namespace cbm::kfp Pions, //< Number of pion-candidates Protons, //< Number of proton-candidates EventsTotal, //< Total number of events + EventsWoTzero, //< Number of events with undefined t-zero EventsLambdaCand, //< Events with at least one pion and one proton candidate KfpEventsLambdaCand, //< Events with lambda-candidates in KF-particle KfpLambdaCandidates, //< Number of lambda-candidates diff --git a/reco/L1/CbmL1.cxx b/reco/L1/CbmL1.cxx index 593b352728..37d8c61be3 100644 --- a/reco/L1/CbmL1.cxx +++ b/reco/L1/CbmL1.cxx @@ -446,7 +446,14 @@ try { // ************************* { auto trackerSetup = pSetupBuilder->MakeSetup<float>(cbm::algo::kf::EFieldMode::Intrpl); - TString outputFile = fSTAPDataDir + "/" + fSTAPDataPrefix + "." + TString(kSTAPSetupSuffix.data()); + TString geoTag = ""; + if (auto* pSetup = CbmSetup::Instance()) { + geoTag = pSetup->GetProvider()->GetSetup().GetTag(); + } + if (geoTag.IsNull()) { + geoTag = fSTAPDataPrefix; + } + TString outputFile = fSTAPDataDir + "/" + geoTag + "." + TString(kSTAPSetupSuffix.data()); cbm::algo::kf::SetupBuilder::Store(trackerSetup, outputFile.Data()); fInitManager.SetGeometrySetup(trackerSetup); } -- GitLab