diff --git a/CODEOWNERS b/CODEOWNERS index a3090ef0e..5cc844348 100644 --- a/CODEOWNERS +++ b/CODEOWNERS @@ -17,9 +17,10 @@ /DATA/testing/detectors/TRD /DATA/testing/detectors/ZDC -/MC @sawenzel @chiarazampolli @jackal1-66 +/MC @sawenzel @jackal1-66 # PWG experts +/MC/*/ALICE3 @njacazio /MC/*/PWGHF @AliceO2Group/reviewers-pwg-hf /MC/*/PWGLF @AliceO2Group/reviewers-pwg-lf /MC/*/PWGEM @AliceO2Group/reviewers-pwg-em diff --git a/DATA/README.md b/DATA/README.md index f6a10ef84..f3533ca26 100644 --- a/DATA/README.md +++ b/DATA/README.md @@ -227,7 +227,7 @@ export WORKFLOW_PARAMETERS= # Additiona export RECO_NUM_NODES_OVERRIDE=0 # Override the number of EPN compute nodes to use (default is specified in description library file) export NHBPERTF=256 # Number of HBF per TF -/opt/alisw/el8/GenTopo/bin/gen_topo.sh > $HOME/gen_topo_output.xml +/opt/alisw/el9/GenTopo/bin/gen_topo.sh > $HOME/gen_topo_output.xml [drohr@epn245 test]$ ./run.sh Loading ODC/0.36-1 Loading requirement: BASE/1.0 GCC-Toolchain/v10.2.0-alice2-3 fmt/7.1.0-10 FairLogger/v1.9.1-7 zlib/v1.2.8-8 OpenSSL/v1.0.2o-9 libpng/v1.6.34-9 sqlite/v3.15.0-2 libffi/v3.2.1-2 FreeType/v2.10.1-8 Python/v3.6.10-12 Python-modules/1.0-16 boost/v1.75.0-13 ZeroMQ/v4.3.3-6 ofi/v1.7.1-8 asio/v1.19.1-2 asiofi/v0.5.1-2 DDS/3.5.16-5 FairMQ/v1.4.40-4 @@ -277,7 +277,7 @@ export WORKFLOW_PARAMETERS=EVENT_DISPLAY,CTF,GPU # Additiona export RECO_NUM_NODES_OVERRIDE=0 # Override the number of EPN compute nodes to use (default is specified in description library file) export NHBPERTF=256 # Number of HBF per TF -/opt/alisw/el8/GenTopo/bin/gen_topo.sh > $HOME/gen_topo_output.xml +/opt/alisw/el9/GenTopo/bin/gen_topo.sh > $HOME/gen_topo_output.xml [drohr@epn245 test]$ ./run.sh Loading ODC/0.36-1 Loading requirement: BASE/1.0 GCC-Toolchain/v10.2.0-alice2-3 fmt/7.1.0-10 FairLogger/v1.9.1-7 zlib/v1.2.8-8 OpenSSL/v1.0.2o-9 libpng/v1.6.34-9 sqlite/v3.15.0-2 libffi/v3.2.1-2 FreeType/v2.10.1-8 Python/v3.6.10-12 Python-modules/1.0-16 boost/v1.75.0-13 ZeroMQ/v4.3.3-6 ofi/v1.7.1-8 asio/v1.19.1-2 asiofi/v0.5.1-2 DDS/3.5.16-5 FairMQ/v1.4.40-4 diff --git a/DATA/common/README.md b/DATA/common/README.md index b93622c0a..702565f69 100644 --- a/DATA/common/README.md +++ b/DATA/common/README.md @@ -1,51 +1 @@ -The `setenv-sh` script sets the following environment options -* `NTIMEFRAMES`: Number of time frames to process. -* `TFDELAY`: Delay in seconds between publishing time frames (1 / rate). -* `NGPUS`: Number of GPUs to use, data distributed round-robin. -* `GPUTYPE`: GPU Tracking backend to use, can be CPU / CUDA / HIP / OCL / OCL2. -* `SHMSIZE`: Size of the global shared memory segment. -* `DDSHMSIZE`: Size of shared memory unmanaged region for DataDistribution Input. -* `GPUMEMSIZE`: Size of allocated GPU memory (if GPUTYPE != CPU) -* `HOSTMEMSIZE`: Size of allocated host memory for GPU reconstruction (0 = default). - * For `GPUTYPE = CPU`: TPC Tracking scratch memory size. (Default 0 -> dynamic allocation.) - * Otherwise : Size of page-locked host memory for GPU processing. (Defauls 0 -> 1 GB.) -* `CREATECTFDICT`: Create CTF dictionary. -* `SAVECTF`: Save the CTF to a root file. - * 0: Read `ctf_dictionary.root` as input. - * 1: Create `ctf_dictionary.root`. Note that this was already done automatically if the raw data was simulated with `full_system_test.sh`. -* `SYNCMODE`: Run only reconstruction steps of the synchronous reconstruction. - * Note that there is no `ASYNCMODE` but instead the `CTFINPUT` option already enforces asynchronous processing. -* `NUMAGPUIDS`: NUMAID-aware GPU id selection. Needed for the full EPN configuration with 8 GPUs, 2 NUMA domains, 4 GPUs per domain. - In this configuration, 2 instances of `dpl-workflow.sh` must run in parallel. - To be used in combination with `NUMAID` to select the id per workflow. - `start_tmux.sh` will set up these variables automatically. -* `NUMAID`: SHM segment id to use for shipping data as well as set of GPUs to use (use `0` / `1` for 2 NUMA domains, 0 = GPUS `0` to `NGPUS - 1`, 1 = GPUS `NGPUS` to `2 * NGPUS - 1`) -* 0: Runs all reconstruction steps, of sync and of async reconstruction, using raw data input. -* 1: Runs only the steps of synchronous reconstruction, using raw data input. -* `EXTINPUT`: Receive input from raw FMQ channel instead of running o2-raw-file-reader. - * 0: `dpl-workflow.sh` can run as standalone benchmark, and will read the input itself. - * 1: To be used in combination with either `datadistribution.sh` or `raw-reader.sh` or with another DataDistribution instance. -* `CTFINPUT`: Read input from CTF ROOT file. This option is incompatible to EXTINPUT=1. The CTF ROOT file can be stored via SAVECTF=1. -* `NHBPERTF`: Time frame length (in HBF) -* `GLOBALDPLOPT`: Global DPL workflow options appended to o2-dpl-run. -* `EPNPIPELINES`: Set default EPN pipeline multiplicities. - Normally the workflow will start 1 dpl device per processor. - For some of the CPU parts, this is insufficient to keep step with the GPU processing rate, e.g. one ITS-TPC matcher on the CPU is slower than the TPC tracking on multiple GPUs. - This option adds some multiplicies for CPU processes using DPL's pipeline feature. - The settings were tuned for EPN processing with 4 GPUs (i.e. the default multiplicities are per NUMA domain). - The multiplicities are scaled with the `NGPUS` setting, i.e. with 1 GPU only 1/4th are applied. - You can pass an option different to 1, and than it will be applied as factor on top of the multiplicities. - It is auto-selected by `start-tmux.sh`. -* `SEVERITY`: Log verbosity (e.g. info or error, default: info) -* `INFOLOGGER_SEVERITY`: Min severity for messages sent to Infologger. (default: `$SEVERITY`) -* `SHMTHROW`: Throw exception when running out of SHM memory. - It is suggested to leave this enabled (default) on tests on the laptop to get an actual error when it runs out of memory. - This is disabled in `start_tmux.sh`, to avoid breaking the processing while there is a chance that another process might free memory and we can continue. -* `NORATELOG`: Disable FairMQ Rate Logging. -* `INRAWCHANNAME`: FairMQ channel name used by the raw proxy, must match the name used by DataDistribution. -* `WORKFLOWMODE`: run (run the workflow (default)), print (print the command to stdout), dds (create partial DDS topology) -* `FILEWORKDIR`: directory for all input / output files. E.g. grp / geometry / dictionaries etc. are read from here, and dictionaries / ctf / etc. are written to there. - Some files have more fine grained control via other environment variables (e.g. to store the CTF to somewhere else). Such variables are initialized to `$FILEWORKDIR` by default but can be overridden. -* `EPNSYNCMODE`: Specify that this is a workflow running on the EPN for synchronous processing, e.g. logging goes to InfoLogger, DPL metrics to to the AliECS monitoring, etc. -* `BEAMTYPE`: Beam type, must be PbPb, pp, pPb, cosmic, technical. -* `IS_SIMULATED_DATA` : 1 for MC data, 0 for RAW data. +For a reference to available env-variables, please check https://github.com/AliceO2Group/AliceO2/blob/dev/prodtests/full-system-test/documentation/env-variables.md diff --git a/DATA/common/gen_topo_helper_functions.sh b/DATA/common/gen_topo_helper_functions.sh index 0ce33047b..c868411b2 100755 --- a/DATA/common/gen_topo_helper_functions.sh +++ b/DATA/common/gen_topo_helper_functions.sh @@ -49,11 +49,21 @@ has_detector_matching() [[ $WORKFLOW_DETECTORS_MATCHING =~ (^|,)"ALL"(,|$) ]] || [[ $WORKFLOW_DETECTORS_MATCHING =~ (^|,)"$1"(,|$) ]] } +has_detector_gpu() +{ + has_detector $1 && [[ $WORKFLOW_DETECTORS_GPU =~ (^|,)"$1"(,|$) ]] +} + has_secvtx_source() { [[ $SVERTEXING_SOURCES =~ (^|,)"ALL"(,|$) ]] || [[ $SVERTEXING_SOURCES =~ (^|,)"$1"(,|$) ]] } +has_detector_in_secvtx_sources() +{ + [[ $SVERTEXING_SOURCES =~ (^|,)"ALL"(,|$) ]] || [[ $SVERTEXING_SOURCES =~ (^|,|-)"$1"(-|,|$) ]] +} + has_detector_qc() { has_detector $1 && [[ $WORKFLOW_DETECTORS_QC =~ (^|,)"$1"(,|$) ]] @@ -137,6 +147,11 @@ has_detectors_flp_processing() _check_multiple has_detector_flp_processing "$@" } +has_detectors_gpu() +{ + _check_multiple has_detector_gpu "$@" +} + workflow_has_parameters() { _check_multiple workflow_has_parameter "$@" @@ -252,19 +267,22 @@ add_W() # Add binarry to workflow command USAGE: add_W [BINARY] [COMMAND_LINE_OP WORKFLOW+=$WFADD } -if [[ "${GEN_TOPO_DEPLOYMENT_TYPE:-}" == "ALICE_STAGING" ]]; then - GEN_TOPO_QC_CONSUL_SERVER=ali-staging.cern.ch -else - GEN_TOPO_QC_CONSUL_SERVER=alio2-cr1-hv-con01.cern.ch +if [[ ${EPNSYNCMODE:-0} == 1 ]]; then + if [[ "${GEN_TOPO_DEPLOYMENT_TYPE:-}" == "ALICE_STAGING" ]]; then + GEN_TOPO_QC_CONSUL_SERVER=ali-staging.cern.ch + else + GEN_TOPO_QC_CONSUL_SERVER=alio2-cr1-hv-con01.cern.ch + fi + GEN_TOPO_QC_APRICOT_SERVER=`curl -s "http://${GEN_TOPO_QC_CONSUL_SERVER}:8500/v1/kv/o2/runtime/aliecs/vars/apricot_endpoint?raw"` fi -GEN_TOPO_QC_APRICOT_SERVER=`curl -s "http://${GEN_TOPO_QC_CONSUL_SERVER}:8500/v1/kv/o2/runtime/aliecs/vars/apricot_endpoint?raw"` add_QC_from_consul() { + [[ ${EPNSYNCMODE:-0} == 1 ]] || { echo "Error fetching QC JSON $1: consul server only set for EPNSYNCMODE == 1 " 1>&2 && exit 1; } if [[ ! -z ${GEN_TOPO_QC_JSON_FILE:-} ]]; then curl -s -o $GEN_TOPO_QC_JSON_FILE "http://${GEN_TOPO_QC_CONSUL_SERVER}:8500/v1/kv${1}?raw" if [[ $? != 0 ]]; then - echo "Error fetching QC JSON $1" + echo "Error fetching QC JSON $1 (1)" 1>&2 exit 1 fi QC_CONFIG_ARG="json://${GEN_TOPO_QC_JSON_FILE}" @@ -276,14 +294,15 @@ add_QC_from_consul() add_QC_from_apricot() { + [[ ${EPNSYNCMODE:-0} == 1 ]] || { echo "Error fetching QC JSON $1: apricot server only set for EPNSYNCMODE == 1 " 1>&2 && exit 1; } if [[ ! -z ${GEN_TOPO_QC_JSON_FILE:-} ]]; then - if [[ ${1} =~ "?" ]]; then - curl -s -o $GEN_TOPO_QC_JSON_FILE "${GEN_TOPO_QC_APRICOT_SERVER}/${1}\&process=true" - else - curl -s -o $GEN_TOPO_QC_JSON_FILE "${GEN_TOPO_QC_APRICOT_SERVER}/${1}?process=true" - fi + if [[ ${1} =~ "?" ]]; then + curl -s -o $GEN_TOPO_QC_JSON_FILE "${GEN_TOPO_QC_APRICOT_SERVER}/${1}\&process=true" + else + curl -s -o $GEN_TOPO_QC_JSON_FILE "${GEN_TOPO_QC_APRICOT_SERVER}/${1}?process=true" + fi if [[ $? != 0 ]]; then - echo "Error fetching QC JSON $1" + echo "Error fetching QC JSON $1 (2)" 1>&2 exit 1 fi QC_CONFIG_ARG="json://${GEN_TOPO_QC_JSON_FILE}" diff --git a/DATA/common/setenv.sh b/DATA/common/setenv.sh index 2f11efdf8..5dc2c3513 100755 --- a/DATA/common/setenv.sh +++ b/DATA/common/setenv.sh @@ -43,6 +43,7 @@ if [[ ! -z ${WORKFLOW_DETECTORS_EXCLUDE:-} ]]; then done fi +if [[ -z "${WORKFLOW_DETECTORS_GPU+x}" ]]; then export WORKFLOW_DETECTORS_GPU="TPC"; fi if [[ -z "${WORKFLOW_DETECTORS_QC+x}" ]] || [[ "0$WORKFLOW_DETECTORS_QC" == "0ALL" ]]; then export WORKFLOW_DETECTORS_QC="$WORKFLOW_DETECTORS,$LIST_OF_GLORECO,TOF_MATCH"; fi if [[ -z "${WORKFLOW_DETECTORS_CALIB+x}" ]] || [[ "0$WORKFLOW_DETECTORS_CALIB" == "0ALL" ]]; then export WORKFLOW_DETECTORS_CALIB=$WORKFLOW_DETECTORS; fi if [[ -z "${WORKFLOW_DETECTORS_RECO+x}" ]] || [[ "0$WORKFLOW_DETECTORS_RECO" == "0ALL" ]]; then export WORKFLOW_DETECTORS_RECO=$WORKFLOW_DETECTORS; fi @@ -90,7 +91,7 @@ if [[ -z "${FILEWORKDIR:-}" ]]; then export FILEWORKDIR=`pwd`; fi # if [[ -z "${FILEWORKDIRRUN:-}" ]]; then export FILEWORKDIRRUN=$FILEWORKDIR; fi # directory where to find the run-related files (grp, collision context) if [[ -z "${RAWINPUTDIR:-}" ]]; then export RAWINPUTDIR=$FILEWORKDIR; fi # Directory where to find input files (raw files / raw tf files / ctf files) if [[ -z "${EPNSYNCMODE:-}" ]]; then export EPNSYNCMODE=0; fi # Is this workflow supposed to run on EPN for sync processing? Will enable InfoLogger / metrics / fetching QC JSONs from consul... -if [[ -z "${BEAMTYPE:-}" ]]; then export BEAMTYPE=PbPb; fi # Beam type, must be PbPb, pp, pPb, cosmic, technical +if [[ -z "${BEAMTYPE:-}" ]]; then export BEAMTYPE=PbPb; fi # Beam type, must be PbPb, pp, pPb, pO, Op, OO, NeNe cosmic, technical if [[ -z "${RUNTYPE:-}" ]]; then export RUNTYPE=Standalone; fi # Run Type, standalone for local tests, otherwise PHYSICS, COSMICS, TECHNICAL, SYNTHETIC if [[ -z "${IS_SIMULATED_DATA:-}" && $RUNTYPE == "SYNTHETIC" ]]; then export IS_SIMULATED_DATA=1; fi # For SYNTHETIC runs we always process simulated data if [[ -z "${IS_SIMULATED_DATA:-}" && ( $RUNTYPE == "PHYSICS" || $RUNTYPE == "COSMICS" ) ]]; then export IS_SIMULATED_DATA=0; fi # For PHYSICS runs we always process simulated data @@ -102,6 +103,12 @@ if [[ -z "${EPN2EOS_METAFILES_DIR:-}" ]]; then EPN2EOS_METAFILES_DIR="/dev/null" if [[ -z "${DCSCCDBSERVER:-}" ]]; then export DCSCCDBSERVER="http://alio2-cr1-flp199-ib:8083"; fi # server for transvering calibration data to DCS if [[ -z "${DCSCCDBSERVER_PERS:-}" ]]; then export DCSCCDBSERVER_PERS="http://alio2-cr1-flp199-ib:8084"; fi # persistent server for transvering calibration data to DCS +if [[ $BEAMTYPE == "pO" ]] || [[ $BEAMTYPE == "Op" ]] || [[ $BEAMTYPE == "Op" ]] || [[ $BEAMTYPE == "OO" ]] || [[ $BEAMTYPE == "NeNe" ]] ; then + export LIGHTNUCLEI=1 +else + export LIGHTNUCLEI=0 +fi + if [[ $EPNSYNCMODE == 0 ]]; then if [[ -z "${SHMSIZE:-}" ]]; then export SHMSIZE=$(( 8 << 30 )); fi # Size of shared memory for messages if [[ -z "${NGPUS:-}" ]]; then export NGPUS=1; fi # Number of GPUs to use, data distributed round-robin @@ -143,7 +150,7 @@ if [[ `uname` == Darwin ]]; then export UDS_PREFIX=; else export UDS_PREFIX="@"; # Env variables required for workflow setup if [[ $SYNCMODE == 1 ]]; then - if [[ -z "${WORKFLOW_DETECTORS_MATCHING+x}" ]]; then export WORKFLOW_DETECTORS_MATCHING="ITSTPC,ITSTPCTRD,ITSTPCTOF,ITSTPCTRDTOF,PRIMVTX"; fi # Select matchings that are enabled in sync mode + if [[ -z "${WORKFLOW_DETECTORS_MATCHING+x}" ]]; then export WORKFLOW_DETECTORS_MATCHING="ITSTPC,ITSTPCTRD,ITSTPCTOF,ITSTPCTRDTOF,PRIMVTX,SECVTX"; fi # Select matchings that are enabled in sync mode else if [[ -z "${WORKFLOW_DETECTORS_MATCHING+x}" ]]; then export WORKFLOW_DETECTORS_MATCHING="ALL"; fi # All matching / vertexing enabled in async mode fi @@ -157,8 +164,8 @@ DISABLE_ROOT_INPUT="--disable-root-input" # Special detector related settings if [[ -z "${TPC_CORR_SCALING:-}" ]]; then # TPC corr.map lumi scaling options, any combination of --lumi-type <0,1,2> --corrmap-lumi-mode <0,1> and TPCCorrMap... configurable param TPC_CORR_SCALING= - if [[ $BEAMTYPE == "pp" ]] && has_detector CTP; then TPC_CORR_SCALING+="--lumi-type 1"; fi - if [[ $BEAMTYPE == "PbPb" ]] && has_detector CTP; then TPC_CORR_SCALING+="--lumi-type 1 TPCCorrMap.lumiInstFactor=2.414"; fi + if [[ $BEAMTYPE == "pp" || $LIGHTNUCLEI == "1" ]] && has_detector CTP; then TPC_CORR_SCALING+="--lumi-type 1 --corrmap-lumi-mode 1"; fi + if [[ $BEAMTYPE == "PbPb" ]] && has_detector CTP; then TPC_CORR_SCALING+="--lumi-type 1 --corrmap-lumi-mode 1 TPCCorrMap.lumiInstFactor=2.414"; fi if [[ $BEAMTYPE == "cosmic" ]]; then TPC_CORR_SCALING=" TPCCorrMap.lumiMean=-1;"; fi # for COSMICS we disable all corrections export TPC_CORR_SCALING=$TPC_CORR_SCALING fi @@ -188,6 +195,7 @@ TRD_SOURCES= TOF_SOURCES= HMP_SOURCES= TRACK_SOURCES= +: ${TRACK_SOURCES_GLO:=} has_detectors_reco ITS TPC && has_detector_matching ITSTPC && add_comma_separated TRACK_SOURCES "ITS-TPC" has_detectors_reco TPC TRD && has_detector_matching TPCTRD && { add_comma_separated TRD_SOURCES TPC; add_comma_separated TRACK_SOURCES "TPC-TRD"; } has_detectors_reco ITS TPC TRD && has_detector_matching ITSTPC && has_detector_matching ITSTPCTRD && { add_comma_separated TRD_SOURCES ITS-TPC; add_comma_separated TRACK_SOURCES "ITS-TPC-TRD"; } @@ -204,6 +212,8 @@ has_detectors_reco HMP TPC TOF && has_detector_matching TPCTOF && add_comma_sepa has_detectors_reco HMP TPC TRD TOF && has_detector_matching TPCTRD && has_detector_matching TPCTRDTOF && add_comma_separated HMP_SOURCES "TPC-TRD-TOF" has_detectors_reco MFT MCH && has_detector_matching MFTMCH && add_comma_separated TRACK_SOURCES "MFT-MCH" has_detectors_reco MCH MID && has_detector_matching MCHMID && add_comma_separated TRACK_SOURCES "MCH-MID" +[[ "0$TRACK_SOURCES_GLO" == "0" ]] && TRACK_SOURCES_GLO=$TRACK_SOURCES + for det in `echo $LIST_OF_DETECTORS | sed "s/,/ /g"`; do if [[ $LIST_OF_ASYNC_RECO_STEPS =~ (^| )${det}( |$) ]]; then has_detector ${det} && has_processing_step ${det}_RECO && add_comma_separated TRACK_SOURCES "$det" @@ -234,12 +244,6 @@ fi [[ ! -z $VERTEXING_SOURCES ]] && PVERTEX_CONFIG+=" --vertexing-sources $VERTEXING_SOURCES" [[ ! -z $VERTEX_TRACK_MATCHING_SOURCES ]] && PVERTEX_CONFIG+=" --vertex-track-matching-sources $VERTEX_TRACK_MATCHING_SOURCES" -if [[ -z ${SVERTEXING_SOURCES:-} ]]; then - SVERTEXING_SOURCES="$VERTEXING_SOURCES" -elif [[ "${SVERTEXING_SOURCES^^}" == "NONE" ]]; then - SVERTEXING_SOURCES= -fi - # this option requires well calibrated timing beween different detectors, at the moment suppress it #has_detector_reco FT0 && PVERTEX_CONFIG+=" --validate-with-ft0" diff --git a/DATA/common/setenv_calib.sh b/DATA/common/setenv_calib.sh index 2011e14ba..59d457889 100755 --- a/DATA/common/setenv_calib.sh +++ b/DATA/common/setenv_calib.sh @@ -17,10 +17,10 @@ if has_detector_calib ITS ; then CAN_DO_CALIB_ITS_DEADMAP_TIME=1; else CAN_DO_CA if has_detector_calib MFT ; then CAN_DO_CALIB_MFT_DEADMAP_TIME=1; else CAN_DO_CALIB_MFT_DEADMAP_TIME=0; fi if has_detector_calib TOF && has_detector_reco TOF; then CAN_DO_CALIB_TOF_DIAGNOSTICS=1; CAN_DO_CALIB_TOF_INTEGRATEDCURR=1; else CAN_DO_CALIB_TOF_DIAGNOSTICS=0; CAN_DO_CALIB_TOF_INTEGRATEDCURR=0; fi if has_detector_calib TOF && has_detector_reco TOF && ( ( has_detectors_reco ITS TPC && has_detector_matching ITSTPCTOF ) || ( has_detectors_reco ITS TPC TRD && has_detector_matching ITSTPCTRDTOF ) ); then CAN_DO_CALIB_TOF_LHCPHASE=1; CAN_DO_CALIB_TOF_CHANNELOFFSETS=1; else CAN_DO_CALIB_TOF_LHCPHASE=0; CAN_DO_CALIB_TOF_CHANNELOFFSETS=0; fi -if has_detector_calib TPC && has_detectors ITS TPC TOF TRD && has_detector_matching ITSTPCTRDTOF; then CAN_DO_CALIB_TPC_SCDCALIB=1; else CAN_DO_CALIB_TPC_SCDCALIB=0; fi +if has_detector_calib TPC && has_detectors ITS TPC && has_detector_matching ITSTPC; then CAN_DO_CALIB_TPC_SCDCALIB=1; else CAN_DO_CALIB_TPC_SCDCALIB=0; fi if has_detector_calib TPC && has_processing_step TPC_DEDX; then CAN_DO_CALIB_TPC_TIMEGAIN=1; CAN_DO_CALIB_TPC_RESPADGAIN=1; else CAN_DO_CALIB_TPC_TIMEGAIN=0; CAN_DO_CALIB_TPC_RESPADGAIN=0; fi if has_detector_calib TPC && has_detectors ITS TPC && has_detector_matching ITSTPC; then CAN_DO_CALIB_TPC_VDRIFTTGL=1; else CAN_DO_CALIB_TPC_VDRIFTTGL=0; fi -if has_detector_calib TPC; then CAN_DO_CALIB_TPC_IDC=1; CAN_DO_CALIB_TPC_SAC=1; else CAN_DO_CALIB_TPC_IDC=0; CAN_DO_CALIB_TPC_SAC=0; fi +if has_detector_calib TPC; then CAN_DO_CALIB_TPC_IDC=1; CAN_DO_CALIB_TPC_SAC=1; CAN_DO_CALIB_TPC_CMV=1; else CAN_DO_CALIB_TPC_IDC=0; CAN_DO_CALIB_TPC_SAC=0; CAN_DO_CALIB_TPC_CMV=0; fi if [[ ! -z ${FLP_IDS:-} && ! $FLP_IDS =~ (^|,)"145"(,|$) ]] || [[ "${GEN_TOPO_DEPLOYMENT_TYPE:-}" == "ALICE_STAGING" ]]; then CAN_DO_CALIB_TPC_SAC=0; fi if has_detector_calib TRD && has_detectors ITS TPC TRD && has_detector_matching ITSTPCTRD; then CAN_DO_CALIB_TRD_VDRIFTEXB=1; CAN_DO_CALIB_TRD_GAIN=1; CAN_DO_CALIB_TRD_T0=1; else CAN_DO_CALIB_TRD_VDRIFTEXB=0; CAN_DO_CALIB_TRD_GAIN=0; CAN_DO_CALIB_TRD_T0=0; fi if has_detector_calib EMC && has_detector_reco EMC; then CAN_DO_CALIB_EMC_BADCHANNELCALIB=1; CAN_DO_CALIB_EMC_TIMECALIB=1; else CAN_DO_CALIB_EMC_BADCHANNELCALIB=0; CAN_DO_CALIB_EMC_TIMECALIB=0; fi @@ -34,13 +34,13 @@ if [[ $SYNCMODE == 1 ]] && has_processing_step ENTROPY_ENCODER && [[ ! -z "$WORK # for async recalibration if has_detector_calib EMC && has_detector_reco EMC && [[ $SYNCMODE != 1 ]]; then CAN_DO_CALIB_EMC_ASYNC_RECALIB=1; else CAN_DO_CALIB_EMC_ASYNC_RECALIB=0; fi if [[ $SYNCMODE != 1 ]] && has_detector_reco TPC; then CAN_DO_CALIB_ASYNC_EXTRACTTPCCURRENTS=1; else CAN_DO_CALIB_ASYNC_EXTRACTTPCCURRENTS=0; fi -if [[ $SYNCMODE != 1 ]] && has_detector_reco TPC && has_detector_reco ITS && has_detector_reco FT0; then CAN_DO_CALIB_ASYNC_EXTRACTTIMESERIES=1; else CAN_DO_CALIB_ASYNC_EXTRACTTIMESERIES=0; fi +if [[ $SYNCMODE != 1 ]] && has_detector_reco TPC; then CAN_DO_CALIB_ASYNC_EXTRACTTIMESERIES=1; else CAN_DO_CALIB_ASYNC_EXTRACTTIMESERIES=0; fi # additional individual settings for calibration workflows if has_detector CTP; then export CALIB_TPC_SCDCALIB_CTP_INPUT="--enable-ctp"; else export CALIB_TPC_SCDCALIB_CTP_INPUT=""; fi if [[ ${DISABLE_TRD_PH:-} == 1 ]]; then CAN_DO_CALIB_TRD_T0=0; fi -: ${CALIB_TPC_SCDCALIB_SLOTLENGTH:=600} # the slot length needs to be known both on the aggregator and the processing nodes, therefore it is defined (in seconds!) here +: ${CALIB_TPC_SCDCALIB_SLOTLENGTH:=300} # the slot length needs to be known both on the aggregator and the processing nodes, therefore it is defined (in seconds!) here : ${CALIB_TPC_SCDCALIB_SENDTRKDATA:=1} # by default, we want to write the track information in addition to unbinned residuals to allow finer filtering offline if [[ $BEAMTYPE != "cosmic" ]] || [[ ${FORCECALIBRATIONS:-} == 1 ]] ; then # Calibrations enabled in non-COSMIC runs @@ -51,17 +51,17 @@ if [[ $BEAMTYPE != "cosmic" ]] || [[ ${FORCECALIBRATIONS:-} == 1 ]] ; then # Cal if [[ $CAN_DO_CALIB_PRIMVTX_MEANVTX == 1 ]]; then if [[ -z ${CALIB_PRIMVTX_MEANVTX+x} ]]; then CALIB_PRIMVTX_MEANVTX=1; fi fi - + # calibrations for ITS if [[ $CAN_DO_CALIB_ITS_DEADMAP_TIME == 1 ]]; then if [[ -z ${CALIB_ITS_DEADMAP_TIME+x} ]]; then CALIB_ITS_DEADMAP_TIME=1; fi fi - + # calibrations for MFT if [[ $CAN_DO_CALIB_MFT_DEADMAP_TIME == 1 ]]; then if [[ -z ${CALIB_MFT_DEADMAP_TIME+x} ]]; then CALIB_MFT_DEADMAP_TIME=1; fi fi - + # calibrations for TOF if [[ $CAN_DO_CALIB_TOF_DIAGNOSTICS == 1 ]]; then if [[ -z ${CALIB_TOF_DIAGNOSTICS+x} ]]; then CALIB_TOF_DIAGNOSTICS=1; fi @@ -178,6 +178,12 @@ if [[ $CAN_DO_CALIB_TPC_SAC == 1 ]]; then fi fi fi +# CMV (be default, it is always disabled for now) +if [[ $CAN_DO_CALIB_TPC_CMV == 1 ]]; then + if [[ -z ${CALIB_TPC_CMV+x} ]]; then + CALIB_TPC_CMV=0; + fi +fi ( [[ -z ${CALIB_FT0_INTEGRATEDCURR:-} ]] || [[ $CAN_DO_CALIB_FT0_INTEGRATEDCURR == 0 ]] ) && CALIB_FT0_INTEGRATEDCURR=0 ( [[ -z ${CALIB_FV0_INTEGRATEDCURR:-} ]] || [[ $CAN_DO_CALIB_FV0_INTEGRATEDCURR == 0 ]] ) && CALIB_FV0_INTEGRATEDCURR=0 @@ -193,6 +199,7 @@ fi ( [[ -z ${CALIB_TPC_RESPADGAIN:-} ]] || [[ $CAN_DO_CALIB_TPC_RESPADGAIN == 0 ]] ) && CALIB_TPC_RESPADGAIN=0 ( [[ -z ${CALIB_TPC_IDC:-} ]] || [[ $CAN_DO_CALIB_TPC_IDC == 0 ]] ) && CALIB_TPC_IDC=0 ( [[ -z ${CALIB_TPC_SAC:-} ]] || [[ $CAN_DO_CALIB_TPC_SAC == 0 ]] ) && CALIB_TPC_SAC=0 +( [[ -z ${CALIB_TPC_CMV:-} ]] || [[ $CAN_DO_CALIB_TPC_CMV == 0 ]] ) && CALIB_TPC_CMV=0 ( [[ -z ${CALIB_TPC_VDRIFTTGL:-} ]] || [[ $CAN_DO_CALIB_TPC_VDRIFTTGL == 0 ]] ) && CALIB_TPC_VDRIFTTGL=0 ( [[ -z ${CALIB_TRD_VDRIFTEXB:-} ]] || [[ $CAN_DO_CALIB_TRD_VDRIFTEXB == 0 ]] ) && CALIB_TRD_VDRIFTEXB=0 ( [[ -z ${CALIB_TRD_GAIN:-} ]] || [[ $CAN_DO_CALIB_TRD_GAIN == 0 ]] ) && CALIB_TRD_GAIN=0 @@ -256,11 +263,14 @@ if [[ -z ${CALIBDATASPEC_BARREL_TF:-} ]]; then if [[ $CALIB_PRIMVTX_MEANVTX == 1 ]]; then add_semicolon_separated CALIBDATASPEC_BARREL_TF "pvtx:GLO/PVTX/0"; fi # ITS - if [[ $CALIB_ITS_DEADMAP_TIME == 1 ]]; then add_semicolon_separated CALIBDATASPEC_BARREL_TF "itsChipStatus:ITS/CHIPSSTATUS/0"; fi + if [[ $CALIB_ITS_DEADMAP_TIME == 1 ]]; then + add_semicolon_separated CALIBDATASPEC_BARREL_TF "itsChipStatus:ITS/CHIPSSTATUS/0" + add_semicolon_separated CALIBDATASPEC_BARREL_TF "itsErrorInfo:ITS/ErrorInfo/0" + fi # MFT if [[ $CALIB_MFT_DEADMAP_TIME == 1 ]]; then add_semicolon_separated CALIBDATASPEC_BARREL_TF "mftChipStatus:MFT/CHIPSSTATUS/0"; fi - + # TOF if [[ $CALIB_TOF_LHCPHASE == 1 ]] || [[ $CALIB_TOF_CHANNELOFFSETS == 1 ]]; then add_semicolon_separated CALIBDATASPEC_BARREL_TF "calibTOF:TOF/CALIBDATA/0"; fi if [[ $CALIB_TOF_DIAGNOSTICS == 1 ]]; then add_semicolon_separated CALIBDATASPEC_BARREL_TF "diagWords:TOF/DIAFREQ/0"; fi @@ -268,6 +278,7 @@ if [[ -z ${CALIBDATASPEC_BARREL_TF:-} ]]; then # TPC if [[ $CALIB_TPC_SCDCALIB == 1 ]]; then add_semicolon_separated CALIBDATASPEC_BARREL_TF "unbinnedTPCResiduals:GLO/UNBINNEDRES/0" + add_semicolon_separated CALIBDATASPEC_BARREL_TF "detectorInfoResiduals:GLO/DETINFORES/0" add_semicolon_separated CALIBDATASPEC_BARREL_TF "trackReferences:GLO/TRKREFS/0" fi if [[ $CALIB_TPC_SCDCALIB == 1 ]] && [[ ${CALIB_TPC_SCDCALIB_SENDTRKDATA:-} == "1" ]]; then add_semicolon_separated CALIBDATASPEC_BARREL_TF "tpcInterpTrkData:GLO/TRKDATA/0"; fi @@ -306,6 +317,14 @@ if [[ -z ${CALIBDATASPEC_TPCIDC_C:-} ]]; then # TPC if [[ $CALIB_TPC_IDC == 1 ]]; then add_semicolon_separated CALIBDATASPEC_TPCIDC_C "idcsgroupc:TPC/IDCGROUPC"; fi fi +# define spec for proxy for TPC CMVs +if [[ -z ${CALIBDATASPEC_TPCCMV:-} ]]; then + # TPC + if [[ $CALIB_TPC_CMV == 1 ]]; then + add_semicolon_separated CALIBDATASPEC_TPCCMV "cmvgroup:TPC/CMVGROUP"; + add_semicolon_separated CALIBDATASPEC_TPCCMV "cmvorbit:TPC/CMVORBITINFO"; + fi +fi # define spec for proxy for TPC SAC if [[ -z ${CALIBDATASPEC_TPCSAC:-} ]]; then diff --git a/DATA/production/README.md b/DATA/production/README.md index fd44b56d9..236e4201b 100644 --- a/DATA/production/README.md +++ b/DATA/production/README.md @@ -8,61 +8,8 @@ Standalone calibration workflows are contained in `standalone-calibration.desc`. If processing is to be disabled, please use the `no-processing` workflow in `no-processing.desc`. -# Configuration options -You can use the following options to change the workflow behavior: -- `DDMODE` (default `processing`) : Must be `processing` (synchronous processing) or `processing-disk` (synchronous processing + storing of raw time frames to disk, note that this is the raw time frame not the CTF!). The `DDMODE` `discard` and `disk` are not compatible with the synchronous processing workflow, you must use the `no-processing.desc` workflow instead!. -- `WORKFLOW_DETECTORS` (default `ALL`) : Comma-separated list of detectors for which the processing is enabled. If these are less detectors than participating in the run, data of the other detectors is ignored. If these are more detectors than participating in the run, the processes for the additional detectors will be started but will not do anything. -- `WORKFLOW_DETECTORS_QC` (default `ALL`) : Comma-separated list of detectors for which to run QC, can be a subset of `WORKFLOW_DETECTORS` (for standalone detectors QC) and `WORKFLOW_DETECTORS_MATCHING` (for matching/vertexing QC). If a detector (matching/vertexing step) is not listed in `WORKFLOW_DETECTORS` (`WORKFLOW_DETECTORS_MATCHING`), the QC is automatically disabled for that detector. Only active if the `WORKFLOW_PARAMETER=QC` is set. -- `WORKFLOW_DETECTORS_CALIB` (default `ALL`) : Comma-separated list of detectors for which to run calibration, can be a subset of `WORKFLOW_DETECTORS`. If a detector is not listed in `WORKFLOW_DETECTORS`, the calibration is automatically disabled for that detector. Only active if the `WORKFLOW_PARAMETER=CALIB` is set. -- `WORKFLOW_DETECTORS_FLP_PROCESSING` (default `TOF` for sync processing on EPN, `NONE` otherwise) : Signals that these detectors have processing on the FLP enabled. The corresponding steps are thus inactive in the EPN epl-workflow, and the raw-proxy is configured to receive the FLP-processed data instead of the raw data in that case. -- `WORKFLOW_DETECTORS_RECO` (default `ALL`) : Comma-separated list of detectors for which to run reconstruction. -- `WORKFLOW_DETECTORS_CTF` (default `ALL`) : Comma-separated list of detectors to include in CTF. -- `WORKFLOW_DETECTORS_MATCHING` (default selected corresponding to default workflow for sync or async mode respectively) : Comma-separated list of matching / vertexing algorithms to run. Use `ALL` to enable all of them. Currently supported options (see LIST_OF_GLORECO in common/setenv.h): `ITSTPC`, `TPCTRD`, `ITSTPCTRD`, `TPCTOF`, `ITSTPCTOF`, `MFTMCH`, `PRIMVTX`, `SECVTX`. -- `WORKFLOW_EXTRA_PROCESSING_STEPS` Enable additional processing steps not in the preset for the SYNC / ASYNC mode. Possible values are: `MID_RECO` `MCH_RECO` `MFT_RECO` `FDD_RECO` `FV0_RECO` `ZDC_RECO` `ENTROPY_ENCODER` `MATCH_ITSTPC` `MATCH_TPCTRD` `MATCH_ITSTPCTRD` `MATCH_TPCTOF` `MATCH_ITSTPCTOF` `MATCH_MFTMCH` `MATCH_MFTMCH` `MATCH_PRIMVTX` `MATCH_SECVTX`. (Here `_RECO` means full async reconstruction, and can be used to enable it also in sync mode.) -- `WORKFLOW_PARAMETERS` (default `NONE`) : Comma-separated list, enables additional features of the workflow. Currently the following features are available: - - `GPU` : Performs the TPC processing on the GPU, otherwise everything is processed on the CPU. - - `CTF` : Write the CTF to disk (CTF creation is always enabled, but if this parameter is missing, it is not stored). - - `EVENT_DISPLAY` : Enable JSON export for event display. - - `QC` : Enable QC. - - `CALIB` : Enable calibration (not yet working!) -- `RECO_NUM_NODES_OVERRIDE` (default `0`) : Overrides the number of EPN nodes used for the reconstruction (`0` or empty means default). -- `MULTIPLICITY_FACTOR_RAWDECODERS` (default `1`) : Scales the number of parallel processes used for raw decoding by this factor. -- `MULTIPLICITY_FACTOR_CTFENCODERS` (default `1`) : Scales the number of parallel processes used for CTF encoding by this factor. -- `MULTIPLICITY_FACTOR_REST` (default `1`) : Scales the number of other reconstruction processes by this factor. -- `QC_JSON_EXTRA` (default `NONE`) : extra QC jsons to add (if does not fit to those defined in WORKFLOW_DETECTORS_QC & (WORKFLOW_DETECTORS | WORKFLOW_DETECTORS_MATCHING) -Most of these settings are configurable in the AliECS GUI. But some of the uncommon settings (`WORKFLOW_DETECTORS_FLP_PROCESSING`, `WORKFLOW_DETECTORS_CTF`, `WORKFLOW_DETECTORS_RECO`, `WORKFLOW_DETECTORS_MATCHING`, `WORKFLOW_EXTRA_PROCESSING_STEPS`, advanced `MULTIPLICITY_FACTOR` settings) can only be set via the "Additional environment variables field" in the GUI using bash syntax, e.g. `WORKFLOW_DETECTORS_FLP_PROCESSING=TPC`. - -# Process multiplicity factors -- The production workflow has internally a default value how many instances of a process to run in parallel (which was tuned for Pb-Pb processing) -- Some critical processes for synchronous pp processing are automatically scaled by the inverse of the number of nodes, i.e. the multiplicity is increased by a factor of 2 if 125 instead of 250 nodes are used, to enable the processing using only a subset of the nodes. -- Factors can be provided externally to scale the multiplicity of processes further. All these factors are multiplied. - - One factor can be provided based on the type of the processes: raw decoder (`MULTIPLICITY_FACTOR_RAWDECODERS`), CTF encoder (`MULTIPLICITY_FACTOR_CTFENCODERS`), or other reconstruction process (`MULTIPLICITY_FACTOR_REST`) - - One factor can be provided per detector via `MULTIPLICITY_FACTOR_DETECTOR_[DET]` using the 3 character detector representation, or `MATCH` for the global matching and vertexing workflows. - - One factor can be provided per process via `MULTIPLICITY_FACTOR_PROCESS_[PROCESS_NAME]`. In the process name, dashes `-` must be replaced by underscores `_`. -- The multiplicity of an individual process can be overridden externally (this is an override, no scaling factor) by using `MULTIPLICITY_PROCESS_[PROCESS_NAME]`. In the process name, dashes `-` must be replaced by underscores `_`. -- For example, creating the workflow with `MULTIPLICITY_FACTOR_RAWDECODERS=2 MULTIPLICITY_FACTOR_DETECTOR_ITS=3 MULTIPLICITY_FACTOR_PROCESS_mft_stf_decoder=5` will scale the number of ITS raw decoders by 6, of other ITS processes by 3, of other raw decoders by 2, and will run exactly 5 `mft-stf-decoder` processes. - -# Additional custom control variables -For user modification of the workflow settings, the folloing *EXTRA* environment variables exist: -- `ARGS_ALL_EXTRA` : Extra command line options added to all workflows -- `ALL_EXTRA_CONFIG` : Extra config key values added to all workflows -- `GPU_EXTRA_CONFIG` : Extra options added to the configKeyValues of the GPU workflow -- `ARGS_EXTRA_PROCESS_[WORKFLOW_NAME]` : Extra command line arguments for the workflow binary `WORKFLOW_NAME`. Dashes `-` must be replaced by underscores `_` in the name! E.g. `ARGS_EXTRA_PROCESS_o2_tof_reco_workflow='--output-type clusters'` -- `CONFIG_EXTRA_PROCESS_[WORKFLOW_NAME]` : Extra `--configKeyValues` arguments for the workflow binary `WORKFLOW_NAME`. Dashes `-` must be replaced by underscores `_` in the name! E.g. `CONFIG_EXTRA_PROCESS_o2_gpu_reco_workflow='GPU_proc.debugLevel=1;GPU_proc.ompKernels=0;'` - -**IMPORTANT:** When providing additional environment variables please always use single quotes `'` instead of double quotes `"`, because otherwise there can be issues with whitespaces. E.g. `ARGS_EXTRA_PROCESS_o2_eve_display='--filter-time-min 0 --filter-time-max 120'` does work while `ARGS_EXTRA_PROCESS_o2_eve_display="--filter-time-min 0 --filter-time-max 120"` does not. - -In case the CTF dictionaries were created from the data drastically different from the one being compressed, the default memory allocation for the CTF buffer might be insufficient. One can apply scaling factor to the buffer size estimate (default=1.5) of particular detector by defining variable e.g. `TPC_ENC_MEMFACT=3.5` - -# File input for ctf-reader / raw-tf-reader -- The variable `$INPUT_FILE_LIST` can be a comma-seperated list of files, or a file with a file-list of CTFs/raw TFs. -- The variable `$INPUT_FILE_COPY_CMD` can provide a custom copy command (default is to fetch the files from EOS). - -# Remarks on QC -The JSON files for the individual detectors are merged into one JSON file, which is cached during the run on the shared EPN home folder. -The default JSON file per detector is defined in `qc-workflow.sh`. -JSONs per detector can be overridden by exporting `QC_JSON_[DETECTOR_NAME]`, e.g. `QC_JSON_TPC`, when creating the workflow. -The global section of the merged qc JSON config is taken from qc-sync/qc-global.json +# Options for dpl-workflow.sh +Refer to https://github.com/AliceO2Group/AliceO2/blob/dev/prodtests/full-system-test/documentation/dpl-workflow-options.md # run-workflow-on-inputlist.sh `O2/prodtests/full-system-test/run-workflow-on-inputlist.sh` is a small tool to run the `dpl-workflow.sh` on a list of files. diff --git a/DATA/production/calib/its-threshold-aggregator.sh b/DATA/production/calib/its-threshold-aggregator.sh index 4540bcb3e..b0449e1fb 100755 --- a/DATA/production/calib/its-threshold-aggregator.sh +++ b/DATA/production/calib/its-threshold-aggregator.sh @@ -10,7 +10,7 @@ PROXY_INSPEC="tunestring:ITS/TSTR;runtype:ITS/RUNT;fittype:ITS/FITT;scantype:ITS CCDBPATH1="" CCDBPATH2="" -if [ $RUNTYPE_ITS == "tuning" ] || [ $RUNTYPE_ITS == "digital" ] || [ $RUNTYPE_ITS == "tuningbb" ]; then +if [[ $RUNTYPE_ITS == "tuning" ]] || [[ $RUNTYPE_ITS == *digital* ]] || [[ $RUNTYPE_ITS == "tuningbb" ]]; then CCDBPATH1="$DCSCCDBSERVER_PERS" CCDBPATH2="http://o2-ccdb.internal" else @@ -26,7 +26,7 @@ WORKFLOW= add_W o2-dpl-raw-proxy "--exit-transition-timeout 20 --proxy-name its-thr-input-proxy --dataspec \"$PROXY_INSPEC\" --network-interface ib0 --channel-config \"name=its-thr-input-proxy,method=bind,type=pull,rateLogging=0,transport=zeromq\"" "" 0 add_W o2-its-threshold-aggregator-workflow "-b" "" 0 add_W o2-calibration-ccdb-populator-workflow "--ccdb-path=\"$CCDBPATH1\" --sspec-min 0 --sspec-max 0 --name-extention dcs" -if [ $RUNTYPE_ITS == "digital" ]; then +if [[ $RUNTYPE_ITS == *digital* ]]; then add_W o2-calibration-ccdb-populator-workflow "--ccdb-path=\"$CCDBPATH2\" --sspec-min 1 --sspec-max 1" fi diff --git a/DATA/production/calib/its-threshold-processing.sh b/DATA/production/calib/its-threshold-processing.sh index dc4079b4b..8bb2a6fdf 100755 --- a/DATA/production/calib/its-threshold-processing.sh +++ b/DATA/production/calib/its-threshold-processing.sh @@ -14,19 +14,23 @@ PROXY_OUTSPEC="tunestring:ITS/TSTR;runtype:ITS/RUNT;fittype:ITS/FITT;scantype:IT CHIPMODBASE=5 NDECODERS=6 +ADDITIONAL_OPTIONS_DEC="" +ADDITIONAL_OPTIONS_CAL="" if [ $RUNTYPE_ITS == "digital" ]; then CHIPMODBASE=10 fi +if [ $RUNTYPE_ITS == "digitalnomask" ]; then + CHIPMODBASE=10 + ADDITIONAL_OPTIONS_CAL="--ninj 5" +fi if [ $RUNTYPE_ITS == "thrfull" ]; then CHIPMODBASE=20 NDECODERS=10 fi -ADDITIONAL_OPTIONS_DEC="" -ADDITIONAL_OPTIONS_CAL="" if [ $RUNTYPE_ITS == "tuningbb" ]; then ADDITIONAL_OPTIONS_CAL="--min-vcasn 30 --max-vcasn 130" fi -if [[ $RUNTYPE_ITS == "tot1row" || $RUNTYPE_ITS == "vresetd" ]]; then +if [[ $RUNTYPE_ITS == "tot1row" || $RUNTYPE_ITS == "vresetd-2d" ]]; then ADDITIONAL_OPTIONS_CAL="--ninj 10" fi if [ $RUNTYPE_ITS == "totfullfast" ]; then diff --git a/DATA/production/calib/mch-badchannel-aggregator.sh b/DATA/production/calib/mch-badchannel-aggregator.sh index 91920a495..0f962b8f4 100755 --- a/DATA/production/calib/mch-badchannel-aggregator.sh +++ b/DATA/production/calib/mch-badchannel-aggregator.sh @@ -15,12 +15,25 @@ MCH_MAX_NOISE=${MCH_MAX_NOISE:-2.0} MCH_MIN_ENTRIES=${MCH_MIN_ENTRIES:-100} MCH_MIN_FRACTION=${MCH_MIN_FRACTION:-0.5} MCH_END_OF_STREAM_ONLY=${MCH_END_OF_STREAM_ONLY:-true} -BADCHANNEL_CONFIG="${ARGS_ALL_CONFIG};MCHBadChannelCalibratorParam.maxPed=${MCH_MAX_PEDESTAL};MCHBadChannelCalibratorParam.maxNoise=${MCH_MAX_NOISE};MCHBadChannelCalibratorParam.minRequiredNofEntriesPerChannel=${MCH_MIN_ENTRIES};MCHBadChannelCalibratorParam.minRequiredCalibratedFraction=${MCH_MIN_FRACTION};MCHBadChannelCalibratorParam.onlyAtEndOfStream=${MCH_END_OF_STREAM_ONLY}" +BADCHANNEL_CONFIG="${ARGS_ALL_CONFIG};MCHBadChannelCalibratorParam.maxPed=${MCH_MAX_PEDESTAL};MCHBadChannelCalibratorParam.maxNoise=${MCH_MAX_NOISE};MCHBadChannelCalibratorParam.minRequiredNofEntriesPerChannel=${MCH_MIN_ENTRIES};MCHBadChannelCalibratorParam.minRequiredCalibratedFraction=${MCH_MIN_FRACTION};MCHBadChannelCalibratorParam.onlyAtEndOfStream=${MCH_END_OF_STREAM_ONLY};" + +if [ -n "${MCH_NTHREADS}" ]; then + BADCHANNEL_CONFIG+="MCHBadChannelCalibratorParam.nThreads=${MCH_NTHREADS};" +fi + +MCH_LOGGING_OPT= +if [ -n "${MCH_LOGGING_INTERVAL}" ]; then + MCH_LOGGING_OPT="--logging-interval ${MCH_LOGGING_INTERVAL}" +fi WORKFLOW="o2-dpl-raw-proxy $ARGS_ALL --proxy-name mch-badchannel-input-proxy --dataspec \"$PROXY_INSPEC\" --network-interface ib0 --channel-config \"name=mch-badchannel-input-proxy,method=bind,type=pull,rateLogging=0,transport=zeromq\" | " -WORKFLOW+="o2-calibration-mch-badchannel-calib-workflow $ARGS_ALL --configKeyValues \"$BADCHANNEL_CONFIG\" | " -WORKFLOW+="o2-calibration-ccdb-populator-workflow $ARGS_ALL --configKeyValues \"$ARGS_ALL_CONFIG\" --ccdb-path=\"http://o2-ccdb.internal\" --sspec-min 0 --sspec-max 0 | " -WORKFLOW+="o2-calibration-ccdb-populator-workflow $ARGS_ALL --configKeyValues \"$ARGS_ALL_CONFIG\" --ccdb-path=\"$DCSCCDBSERVER_PERS\" --sspec-min 1 --sspec-max 1 --name-extention dcs | " +WORKFLOW+="o2-calibration-mch-badchannel-calib-workflow $ARGS_ALL --configKeyValues \"$BADCHANNEL_CONFIG\" ${MCH_LOGGING_OPT} | " + +if [ -z "${MCH_SKIP_CCDB_UPLOAD}" ]; then + WORKFLOW+="o2-calibration-ccdb-populator-workflow $ARGS_ALL --configKeyValues \"$ARGS_ALL_CONFIG\" --ccdb-path=\"http://o2-ccdb.internal\" --sspec-min 0 --sspec-max 0 | " + WORKFLOW+="o2-calibration-ccdb-populator-workflow $ARGS_ALL --configKeyValues \"$ARGS_ALL_CONFIG\" --ccdb-path=\"$DCSCCDBSERVER_PERS\" --sspec-min 1 --sspec-max 1 --name-extention dcs | " +fi + add_QC_from_consul "/o2/components/qc/ANY/any/mch-badchannel" "" WORKFLOW+="o2-dpl-run $ARGS_ALL $GLOBALDPLOPT" diff --git a/DATA/production/calib/mft-noise-aggregator.sh b/DATA/production/calib/mft-noise-aggregator.sh index 6155032ca..5bb5feeca 100755 --- a/DATA/production/calib/mft-noise-aggregator.sh +++ b/DATA/production/calib/mft-noise-aggregator.sh @@ -9,7 +9,7 @@ source common/getCommonArgs.sh PROXY_INSPEC="A:MFT/DIGITS/0;B:MFT/DIGITSROF/0" WORKFLOW="o2-dpl-raw-proxy $ARGS_ALL --proxy-name mft-noise-input-proxy --dataspec \"$PROXY_INSPEC\" --network-interface ib0 --channel-config \"name=mft-noise-input-proxy,method=bind,type=pull,rateLogging=0,transport=zeromq\" | " -WORKFLOW+="o2-calibration-mft-calib-workflow $ARGS_ALL --configKeyValues \"$ARGS_ALL_CONFIG\" --useDigits --prob-threshold 1e-5 --send-to-server DCS-CCDB --path-CCDB \"/MFT/Calib/NoiseMap\" --path-DCS \"/MFT/Config/NoiseMap\" | " +WORKFLOW+="o2-calibration-mft-calib-workflow $ARGS_ALL --configKeyValues \"$ARGS_ALL_CONFIG\" --useDigits --prob-threshold 1e-5 --send-to-server DCS-CCDB --path-CCDB \"/MFT/Calib/NoiseMap\" --path-DCS \"/MFT/Config/NoiseMap\" --path-CCDB-single \"/MFT/Calib/NoiseMapSingle\" | " WORKFLOW+="o2-calibration-ccdb-populator-workflow $ARGS_ALL --configKeyValues \"$ARGS_ALL_CONFIG\" --ccdb-path=\"http://o2-ccdb.internal\" --sspec-min 0 --sspec-max 0 | " WORKFLOW+="o2-calibration-ccdb-populator-workflow $ARGS_ALL --configKeyValues \"$ARGS_ALL_CONFIG\" --ccdb-path=\"$DCSCCDBSERVER_PERS\" --sspec-min 1 --sspec-max 1 --name-extention dcs | " WORKFLOW+="o2-dpl-run $ARGS_ALL $GLOBALDPLOPT" diff --git a/DATA/production/calib/mid-badchannels.sh b/DATA/production/calib/mid-badchannels.sh index 01a09ca74..594c0406e 100755 --- a/DATA/production/calib/mid-badchannels.sh +++ b/DATA/production/calib/mid-badchannels.sh @@ -44,7 +44,7 @@ workflow_has_parameter CTF && { add_W o2-mid-calibration-workflow "" "" 0 add_W o2-calibration-ccdb-populator-workflow "--ccdb-path=\"$CCDB_POPULATOR_UPLOAD_PATH\" --sspec-min 0 --sspec-max 0" add_W o2-calibration-ccdb-populator-workflow "--ccdb-path=\"$CCDB_POPULATOR_UPLOAD_PATH_DCS\" --sspec-min 1 --sspec-max 1 --name-extention dcs" -workflow_has_parameter QC && add_QC_from_consul "/o2/components/qc/ANY/any/mid-calib-qcmn" "--local --host localhost" +workflow_has_parameter QC && add_QC_from_apricot "components/qc/ANY/any/mid-calib-qcmn" "--local --host localhost" WORKFLOW+="o2-dpl-run $ARGS_ALL $GLOBALDPLOPT" if [ "$WORKFLOWMODE" == "print" ]; then diff --git a/DATA/production/calib/tpc-laser-aggregator.sh b/DATA/production/calib/tpc-laser-aggregator.sh index 8d0acc5bf..5dd282ade 100755 --- a/DATA/production/calib/tpc-laser-aggregator.sh +++ b/DATA/production/calib/tpc-laser-aggregator.sh @@ -8,9 +8,9 @@ FILEWORKDIR="/home/wiechula/processData/inputFilesTracking/triggeredLaser" PROXY_INSPEC="A:TPC/LASERTRACKS;B:TPC/CEDIGITS;D:TPC/CLUSREFS" -CALIB_CONFIG="TPCCalibPulser.FirstTimeBin=450;TPCCalibPulser.LastTimeBin=550;TPCCalibPulser.NbinsQtot=300;TPCCalibPulser.XminQtot=2;TPCCalibPulser.XmaxQtot=602;TPCCalibPulser.MinimumQtot=8;TPCCalibPulser.MinimumQmax=6;TPCCalibPulser.XminT0=450;TPCCalibPulser.XmaxT0=550;TPCCalibPulser.NbinsT0=400;keyval.output_dir=/dev/null" +CALIB_CONFIG="TPCCalibPulser.FirstTimeBin=450;TPCCalibPulser.LastTimeBin=550;TPCCalibPulser.NbinsQtot=600;TPCCalibPulser.XminQtot=2;TPCCalibPulser.XmaxQtot=1202;TPCCalibPulser.MinimumQtot=8;TPCCalibPulser.MinimumQmax=6;TPCCalibPulser.XminT0=450;TPCCalibPulser.XmaxT0=550;TPCCalibPulser.NbinsT0=400;keyval.output_dir=/dev/null" -CCDB_PATH="http://o2-ccdb.internal" +[[ $RUNTYPE == "SYNTHETIC" ]] && CCDB_PATH="http://ccdb-test.cern.ch:8080" || CCDB_PATH="http://o2-ccdb.internal" HOST=localhost diff --git a/DATA/production/calib/tpc-laser-filter.sh b/DATA/production/calib/tpc-laser-filter.sh index c64c0e9f0..1bc4be8ab 100755 --- a/DATA/production/calib/tpc-laser-filter.sh +++ b/DATA/production/calib/tpc-laser-filter.sh @@ -4,7 +4,7 @@ source common/setenv.sh source common/getCommonArgs.sh -source common/gen_topo_helper_functions.sh +source common/gen_topo_helper_functions.sh FILEWORKDIR="/home/wiechula/processData/inputFilesTracking/triggeredLaser" @@ -13,6 +13,14 @@ FILEWORKDIR2="/home/epn/odc/files/" #ARGS_ALL_CONFIG+="NameConf.mDirGRP=$FILEWORKDIR;NameConf.mDirGeom=$FILEWORKDIR2;NameConf.mDirCollContext=$FILEWORKDIR;NameConf.mDirMatLUT=$FILEWORKDIR;keyval.input_dir=$FILEWORKDIR;keyval.output_dir=/dev/null" #ARGS_ALL_CONFIG+="NameConf.mDirGRP=$FILEWORKDIR;NameConf.mDirGeom=$FILEWORKDIR2;NameConf.mDirCollContext=$FILEWORKDIR;NameConf.mDirMatLUT=$FILEWORKDIR" +GPUTYPE=${GPUTYPE:-CPU} +HOSTMEMSIZE=0 +if workflow_has_parameter GPU; then + GPUTYPE=HIP + GPUMEMSIZE=$(( 24 << 30 )) + HOSTMEMSIZE=$(( 5 << 30 )) +fi + if [ ${NUMAGPUIDS} != 0 ]; then ARGS_ALL+=" --child-driver 'numactl --membind $NUMAID --cpunodebind $NUMAID'" fi @@ -55,7 +63,7 @@ REMAP="--condition-remap \"file://${FILEWORKDIR}=GLO/Config/GRPECS,GLO/Config/GR RECO_CONFIG="NameConf.mDirGRP=$FILEWORKDIR;" RECO_CONFIG+="NameConf.mDirGeom=$FILEWORKDIR2;" RECO_CONFIG+="NameConf.mDirCollContext=$FILEWORKDIR;" -RECO_CONFIG+="NameConf.mDirMatLUT=$FILEWORKDIR;" +RECO_CONFIG+="NameConf.mDirMatLUT=$FILEWORKDIR;" RECO_CONFIG+="align-geom.mDetectors=none;" RECO_CONFIG+="GPU_global.deviceType=$GPUTYPE;" RECO_CONFIG+="GPU_proc.tpcIncreasedMinClustersPerRow=500000;" @@ -73,7 +81,8 @@ RECO_CONFIG+="GPU_rec_tpc.trackFollowingMaxRowGap=15;GPU_rec_tpc.trackFollowingM WORKFLOW= add_W o2-dpl-raw-proxy "--dataspec \"$PROXY_INSPEC\" --inject-missing-data --channel-config \"name=readout-proxy,type=pull,method=connect,address=ipc://@tf-builder-pipe-0,transport=shmem,rateLogging=1\"" "" 0 add_W o2-tpc-raw-to-digits-workflow "--ignore-grp --input-spec \"$CALIB_INSPEC\" --remove-duplicates --pipeline tpc-raw-to-digits-0:20 --send-ce-digits " "${RAWDIGIT_CONFIG}" -add_W o2-tpc-reco-workflow " ${TPC_CORR_SCALING:-} --disable-ctp-lumi-request --input-type digitizer --output-type \"tracks,disable-writer,clusters\" --disable-mc --pipeline tpc-zsEncoder:20,tpc-tracker:8 ${GPU_CONFIG} ${REMAP} " "${RECO_CONFIG}" +add_W o2-tpc-scaler-workflow "--disable-IDC-scalers --disable-ctp-lumi-request" +add_W o2-tpc-reco-workflow " --input-type digitizer --output-type \"tracks,disable-writer,clusters\" --disable-mc --pipeline tpc-zsEncoder:20,tpc-tracker:8 ${GPU_CONFIG} ${REMAP} " "${RECO_CONFIG}" add_W o2-tpc-laser-track-filter "" "" 0 add_W o2-dpl-output-proxy " --proxy-name tpc-laser-input-proxy --proxy-channel-name tpc-laser-input-proxy --dataspec \"$PROXY_OUTSPEC\" --channel-config \"name=tpc-laser-input-proxy,method=connect,type=push,transport=zeromq,rateLogging=0\" " "" 0 add_QC_from_apricot "${QC_CONFIG}" "--local --host localhost" diff --git a/DATA/production/calib/tpc-laser.sh b/DATA/production/calib/tpc-laser.sh index b15b9311a..0ace43717 100755 --- a/DATA/production/calib/tpc-laser.sh +++ b/DATA/production/calib/tpc-laser.sh @@ -4,12 +4,20 @@ source common/setenv.sh source common/getCommonArgs.sh -source common/gen_topo_helper_functions.sh +source common/gen_topo_helper_functions.sh FILEWORKDIR="/home/wiechula/processData/inputFilesTracking/triggeredLaser" FILEWORKDIR2="/home/epn/odc/files/" +GPUTYPE=${GPUTYPE:-CPU} +HOSTMEMSIZE=0 +if workflow_has_parameter GPU; then + GPUTYPE=HIP + GPUMEMSIZE=$(( 24 << 30 )) + HOSTMEMSIZE=$(( 5 << 30 )) +fi + if [ $NUMAGPUIDS != 0 ]; then ARGS_ALL+=" --child-driver 'numactl --membind $NUMAID --cpunodebind $NUMAID'" fi @@ -40,7 +48,7 @@ fi PROXY_INSPEC="A:TPC/RAWDATA;dd:FLP/DISTSUBTIMEFRAME/0" CALIB_INSPEC="A:TPC/RAWDATA;dd:FLP/DISTSUBTIMEFRAME/0" -CALIB_CONFIG="TPCCalibPulser.FirstTimeBin=450;TPCCalibPulser.LastTimeBin=550;TPCCalibPulser.NbinsQtot=250;TPCCalibPulser.XminQtot=2;TPCCalibPulser.XmaxQtot=502;TPCCalibPulser.MinimumQtot=8;TPCCalibPulser.MinimumQmax=6;TPCCalibPulser.XminT0=450;TPCCalibPulser.XmaxT0=550;TPCCalibPulser.NbinsT0=400;keyval.output_dir=/dev/null" +CALIB_CONFIG="TPCCalibPulser.FirstTimeBin=450;TPCCalibPulser.LastTimeBin=550;TPCCalibPulser.NbinsQtot=400;TPCCalibPulser.XminQtot=2;TPCCalibPulser.XmaxQtot=802;TPCCalibPulser.MinimumQtot=8;TPCCalibPulser.MinimumQmax=6;TPCCalibPulser.XminT0=450;TPCCalibPulser.XmaxT0=550;TPCCalibPulser.NbinsT0=400;keyval.output_dir=/dev/null" CCDB_PATH="http://o2-ccdb.internal" @@ -69,7 +77,7 @@ if [[ ! -z ${TPC_CALIB_LANES_PAD_RAW:-} ]]; then num_lanes=${TPC_CALIB_LANES_PAD_RAW} fi -EXTRA_CONFIG="--calib-type ce --publish-after-tfs ${publish_after} --max-events ${max_events} --lanes ${num_lanes} --check-calib-infos" +EXTRA_CONFIG="--calib-type ce --publish-after-tfs ${publish_after} --max-events ${max_events} --lanes ${num_lanes} --check-calib-infos" LASER_DECODER_ADD='' @@ -92,7 +100,8 @@ RECO_CONFIG+="GPU_rec_tpc.trackFollowingMaxRowGap=15;GPU_rec_tpc.trackFollowingM WORKFLOW= add_W o2-dpl-raw-proxy "--dataspec \"$PROXY_INSPEC\" --inject-missing-data --channel-config \"name=readout-proxy,type=pull,method=connect,address=ipc://@tf-builder-pipe-0,transport=shmem,rateLogging=1\"" "" 0 add_W o2-tpc-raw-to-digits-workflow "--ignore-grp --input-spec \"$CALIB_INSPEC\" --remove-duplicates --pipeline tpc-raw-to-digits-0:20 --send-ce-digits " "${RAWDIGIT_CONFIG}" -add_W o2-tpc-reco-workflow " --disable-ctp-lumi-request --input-type digitizer --output-type \"tracks,disable-writer\" --disable-mc --pipeline tpc-zsEncoder:20,tpc-tracker:8 ${GPU_CONFIG} ${REMAP}" "${RECO_CONFIG}" +add_W o2-tpc-scaler-workflow "--disable-IDC-scalers --disable-ctp-lumi-request" +add_W o2-tpc-reco-workflow "--input-type digitizer --output-type \"tracks,disable-writer\" --disable-mc --pipeline tpc-zsEncoder:20,tpc-tracker:8 ${GPU_CONFIG} ${REMAP}" "${RECO_CONFIG}" add_W o2-tpc-laser-track-filter "" "" 0 add_W o2-tpc-calib-laser-tracks "--use-filtered-tracks ${EXTRA_CONFIG_TRACKS} --min-tfs=${min_tracks}" add_W o2-tpc-calib-pad-raw " ${EXTRA_CONFIG}" "${CALIB_CONFIG}" diff --git a/DATA/production/calib/tpc-pedestal.sh b/DATA/production/calib/tpc-pedestal.sh index cbcf4bd2f..22fbd4392 100755 --- a/DATA/production/calib/tpc-pedestal.sh +++ b/DATA/production/calib/tpc-pedestal.sh @@ -21,26 +21,32 @@ HOST=localhost QC_CONFIG="components/qc/ANY/any/tpc-pedestal-calib-qcmn?run_type=${RUNTYPE:-}" CALIB_CONFIG="TPCCalibPedestal.ADCMin=20" - -max_events=50 -publish_after=400 - -if [[ ! -z ${TPC_CALIB_MAX_EVENTS:-} ]]; then - max_events=${TPC_CALIB_MAX_EVENTS} -fi - -if [[ ! -z ${TPC_CALIB_PUBLISH_AFTER:-} ]]; then - publish_after=${TPC_CALIB_PUBLISH_AFTER} -fi - +# ===| configuration from environment variables |=============================== +max_events=${TPC_CALIB_MAX_EVENTS:-50} +publish_after=${TPC_CALIB_PUBLISH_AFTER:-400} +sendToDCS=${TPC_CALIB_SEND_TO_DCS:-1} + +# ===| ccdb populator setup |=================================================== +# the production CCDB populator will accept subspecs in this range +CCDBPRO_SUBSPEC_MIN=0 +CCDBPRO_SUBSPEC_MAX=32767 +CCDBPATHPRO="http://o2-ccdb.internal" + +# the DCS CCDB populator will accept subspecs in this range +CCDBDCS_SUBSPEC_MIN=32768 +CCDBDCS_SUBSPEC_MAX=65535 +CCDBPATHDCS="$DCSCCDBSERVER_PERS" ################################################################################################################################# WORKFLOW= add_W o2-dpl-raw-proxy "--dataspec \"$PROXY_INSPEC\" --inject-missing-data --channel-config \"name=readout-proxy,type=pull,method=connect,address=ipc://@tf-builder-pipe-0,transport=shmem,rateLogging=1\"" "" 0 -add_W o2-tpc-calib-pad-raw "--input-spec \"$CALIB_INSPEC\" --publish-after-tfs ${publish_after} --max-events ${max_events} --lanes 36" "${CALIB_CONFIG}" -add_W o2-calibration-ccdb-populator-workflow "--ccdb-path \"http://o2-ccdb.internal\" " "" 0 +add_W o2-tpc-calib-pad-raw "--input-spec \"$CALIB_INSPEC\" --publish-after-tfs ${publish_after} --max-events ${max_events} --lanes 36 --send-to-dcs-ccdb $sendToDCS" "${CALIB_CONFIG}" +add_W o2-calibration-ccdb-populator-workflow "--ccdb-path \"$CCDBPATHPRO\" --sspec-min $CCDBPRO_SUBSPEC_MIN --sspec-max $CCDBPRO_SUBSPEC_MAX" "" 0 +if [[ $sendToDCS -eq 1 ]]; then + add_W o2-calibration-ccdb-populator-workflow "--ccdb-path \"$CCDBPATHDCS\" --sspec-min $CCDBDCS_SUBSPEC_MIN --sspec-max $CCDBDCS_SUBSPEC_MAX --name-extention dcs" "" 0 +fi add_QC_from_apricot "${QC_CONFIG}" "--local --host localhost" WORKFLOW+="o2-dpl-run ${ARGS_ALL} ${GLOBALDPLOPT}" diff --git a/DATA/production/common/readAO2Ds.C b/DATA/production/common/readAO2Ds.C index 2574b8230..3a25e4342 100644 --- a/DATA/production/common/readAO2Ds.C +++ b/DATA/production/common/readAO2Ds.C @@ -35,6 +35,17 @@ int readAO2Ds(const char* filename = "AO2D.root") std::cout << onameKeyInDir.Data() << std::endl; } TTree* t = (TTree*)d->Get(onameKeyInDir.Data()); + // Check that every branch has the same number of entries as the tree itself. + // A mismatch indicates a corrupted or truncated write. + long long treeEntries = t->GetEntries(); + for (auto* b : *t->GetListOfBranches()) { + auto* br = (TBranch*)b; + if (br->GetEntries() != treeEntries) { + printf("MISMATCH %s/%s branch %s: tree=%lld branch=%lld\n", + onameKeyInFile.Data(), onameKeyInDir.Data(), br->GetName(), treeEntries, br->GetEntries()); + retCode |= 4; + } + } if (onameKeyInDir.BeginsWith("O2track") && !onameKeyInDir.Contains("O2tracked") && !onameKeyInDir.Contains("O2trackqa")) { vectNEntriesPerTree.push_back({onameKeyInDir.Data(), t->GetEntries()}); } diff --git a/DATA/production/configurations/CTFSkimming/ctf-skim-workflow.sh b/DATA/production/configurations/CTFSkimming/ctf-skim-workflow.sh index fbf38cbda..8ede2eff4 100755 --- a/DATA/production/configurations/CTFSkimming/ctf-skim-workflow.sh +++ b/DATA/production/configurations/CTFSkimming/ctf-skim-workflow.sh @@ -89,7 +89,7 @@ done if [[ -z ${IRFRAMES:-} ]] || [[ -z ${CTFLIST:-} ]] ; then echo "Format: ${0##*/} -f -c " - exit 1 + exit 1 fi [[ "0${ALLOW_MISSING_DET:-}" == "00" ]] && ALLOW_MISSING_DET= || ALLOW_MISSING_DET="--allow-missing-detectors" @@ -107,12 +107,12 @@ add_W o2-ctf-reader-workflow "--ctf-data-subspec 1 --ir-frames-files $IRFRAMES $ if [[ -z ${NO_ITSMFT_MASKING:-} ]] ; then has_detector_ctf ITS && add_W o2-its-reco-workflow "--digits-from-upstream --disable-mc --disable-tracking --disable-root-output --pipeline $(get_N its-tracker ITS REST 1 ITSTRK)" "ITSClustererParam.maxBCDiffToMaskBias=10;" - has_detector_ctf MFT && add_W o2-mft-reco-workflow "--digits-from-upstream --disable-mc --disable-tracking --disable-root-output --pipeline $(get_N mft-tracker MFT REST 1 MFTTRK)" "MFTClustererParam.maxBCDiffToMaskBias=10;" + has_detector_ctf MFT && add_W o2-mft-reco-workflow "--digits-from-upstream --disable-mc --disable-tracking --disable-root-output --pipeline $(get_N mft-tracker MFT REST 1 MFTTRK)" "MFTClustererParam.maxBCDiffToMaskBias=10;" fi has_detector_ctf ITS && add_W o2-itsmft-entropy-encoder-workflow "$RANS_OPT --select-ir-frames --irframe-margin-bwd ${ITS_MARGIN_BWD:-$DEF_MARGIN_BWD} --irframe-margin-fwd ${ITS_MARGIN_FWD:-$DEF_MARGIN_FWD} --mem-factor ${ITS_ENC_MEMFACT:-1.5} --pipeline $(get_N its-entropy-encoder ITS CTF 1)" has_detector_ctf MFT && add_W o2-itsmft-entropy-encoder-workflow "$RANS_OPT --select-ir-frames --irframe-margin-bwd ${MFT_MARGIN_BWD:-$DEF_MARGIN_BWD} --irframe-margin-fwd ${MFT_MARGIN_FWD:-$DEF_MARGIN_FWD} --mem-factor ${MFT_ENC_MEMFACT:-1.5} --runmft true --pipeline $(get_N mft-entropy-encoder MFT CTF 1)" -has_detector_ctf TPC && add_W o2-tpc-reco-workflow "$RANS_OPT --select-ir-frames --irframe-margin-bwd ${TPC_MARGIN_BWD:-$DEF_MARGIN_BWD} --irframe-margin-fwd ${TPC_MARGIN_FWD:-$DEF_MARGIN_FWD} --mem-factor ${TPC_ENC_MEMFACT:-1.} --input-type compressed-clusters-flat --output-type encoded-clusters,disable-writer --pipeline $(get_N tpc-entropy-encoder TPC CTF 1 TPCENT)" +has_detector_ctf TPC && add_W o2-tpc-reco-workflow "$RANS_OPT --select-ir-frames --irframe-margin-bwd ${TPC_MARGIN_BWD:-$DEF_MARGIN_BWD} --irframe-margin-fwd ${TPC_MARGIN_FWD:-$DEF_MARGIN_FWD} --mem-factor ${TPC_ENC_MEMFACT:-1.} --input-type compressed-clusters-flat-for-encode --output-type encoded-clusters,disable-writer --pipeline $(get_N tpc-entropy-encoder TPC CTF 1 TPCENT)" has_detector_ctf TRD && add_W o2-trd-entropy-encoder-workflow "$RANS_OPT --select-ir-frames --irframe-margin-bwd ${TRD_MARGIN_BWD:-$DEF_MARGIN_BWD} --irframe-margin-fwd ${TRD_MARGIN_FWD:-$DEF_MARGIN_FWD} --mem-factor ${TRD_ENC_MEMFACT:-1.5} --pipeline $(get_N trd-entropy-encoder TRD CTF 1 TRDENT)" has_detector_ctf TOF && add_W o2-tof-entropy-encoder-workflow "$RANS_OPT --select-ir-frames --irframe-margin-bwd ${TOF_MARGIN_BWD:-$DEF_MARGIN_BWD} --irframe-margin-fwd ${TOF_MARGIN_FWD:-$DEF_MARGIN_FWD} --mem-factor ${TOF_ENC_MEMFACT:-1.5} --pipeline $(get_N tof-entropy-encoder TOF CTF 1)" has_detector_ctf FT0 && add_W o2-ft0-entropy-encoder-workflow "$RANS_OPT --select-ir-frames --irframe-margin-bwd ${FT0_MARGIN_BWD:-$DEF_MARGIN_BWD} --irframe-margin-fwd ${FT0_MARGIN_FWD:-$DEF_MARGIN_FWD} --mem-factor ${FT0_ENC_MEMFACT:-1.5} --pipeline $(get_N ft0-entropy-encoder FT0 CTF 1)" diff --git a/DATA/production/configurations/asyncReco/async_pass.sh b/DATA/production/configurations/asyncReco/async_pass.sh index 9b5f3d12b..5a178344d 100755 --- a/DATA/production/configurations/asyncReco/async_pass.sh +++ b/DATA/production/configurations/asyncReco/async_pass.sh @@ -205,6 +205,10 @@ if [[ "$ALIEN_JDL_EXTRACTTIMESERIES" == "1" ]]; then export ADD_CALIB=1 fi +if [[ "$ALIEN_JDL_DOTPCTIMEGAINCALIB" == "1" ]]; then + export ADD_CALIB=1 +fi + # AOD file size if [[ -n "$ALIEN_JDL_AODFILESIZE" ]]; then export AOD_FILE_SIZE="$ALIEN_JDL_AODFILESIZE" @@ -280,16 +284,13 @@ fi ln -sf $O2DPG_ROOT/DATA/common/setenv.sh ln -sf $O2DPG_ROOT/DATA/common/getCommonArgs.sh -# TFDELAY and throttling -export TFDELAYSECONDS=40 -if [[ -n "$ALIEN_JDL_TFDELAYSECONDS" ]]; then - TFDELAYSECONDS="$ALIEN_JDL_TFDELAYSECONDS" -# ...otherwise, it depends on whether we have throttling -elif [[ -n "$ALIEN_JDL_USETHROTTLING" ]]; then - TFDELAYSECONDS=1 - if [[ -n "$ALIEN_JDL_NOTFDELAY" ]]; then - TFDELAYSECONDS=0 - fi +# throttling and TF-delay +: ${TFDELAYSECONDS:=0} +if [[ -n "$ALIEN_JDL_NOTFDELAY" ]] && [[ "$ALIEN_JDL_NOTFDELAY" -gt 0 ]] ; then + TFDELAYSECONDS=0 +fi + +if [[ -n "$ALIEN_JDL_USETHROTTLING" ]] && [[ -z "$TIMEFRAME_RATE_LIMIT" ]] ; then export TIMEFRAME_RATE_LIMIT=1 fi @@ -307,7 +308,7 @@ fi if [[ $ALIEN_JDL_DOEMCCALIB == "1" ]]; then SETTING_ROOT_OUTPUT+="ENABLE_ROOT_OUTPUT_o2_emcal_emc_offline_calib_workflow= " fi -if [[ $DO_TPC_RESIDUAL_EXTRACTION == "1" ]]; then +if [[ -n "$DO_TPC_RESIDUAL_EXTRACTION" && $DO_TPC_RESIDUAL_EXTRACTION != "0" ]]; then SETTING_ROOT_OUTPUT+="ENABLE_ROOT_OUTPUT_o2_calibration_residual_aggregator= " fi if [[ $ALIEN_JDL_DOTRDVDRIFTEXBCALIB == "1" ]]; then @@ -396,13 +397,13 @@ if [[ -n $ALIEN_JDL_PACKAGES ]]; then # if we have this env variable, it means t else # in LOCAL mode, by default we keep all intermediate files echo -e "\n\n**** RUNNING IN LOCAL MODE ****" - keep=1 if [[ "$DO_NOT_KEEP_OUTPUT_IN_LOCAL" -eq 1 ]]; then - echo -e "**** ONLY SOME WORKFLOWS WILL HAVE THE ROOT OUTPUT SAVED ****\n\n" + echo -e "**** DO_NOT_KEEP_OUTPUT_IN_LOCAL ENABLED, NOT SETTING keep=0, NOT ENFORCING FULL ROOT OUTPUT ****\n\n" keep=0; else echo -e "**** WE KEEP ALL ROOT OUTPUT ****"; echo -e "**** IF YOU WANT TO REMOVE ROOT OUTPUT FILES FOR PERFORMANCE STUDIES OR SIMILAR, PLEASE SET THE ENV VAR DO_NOT_KEEP_OUTPUT_IN_LOCAL ****\n\n" + keep=1 fi fi @@ -412,67 +413,58 @@ fi echo "SETTING_ROOT_OUTPUT = $SETTING_ROOT_OUTPUT" # Enabling GPUs -if [[ -n "$ALIEN_JDL_USEGPUS" && $ALIEN_JDL_USEGPUS != 0 ]] ; then - echo "Enabling GPUS" - [[ -z ${GPUTYPE:-} ]] && export GPUTYPE="HIP" - [[ -z ${GPUMEMSIZE:-} ]] && export GPUMEMSIZE=$((25 << 30)) - if [[ "0$ASYNC_PASS_NO_OPTIMIZED_DEFAULTS" != "01" ]]; then - if [[ "ALIEN_JDL_USEFULLNUMADOMAIN" == 0 ]]; then +if [[ $ASYNC_PASS_NO_OPTIMIZED_DEFAULTS != 1 ]]; then + export OPTIMIZED_PARALLEL_ASYNC_AUTO_SHM_LIMIT=1 + if [[ $ALIEN_JDL_USEGPUS == 1 ]] ; then + echo "Enabling GPUS" + if [[ -z $ALIEN_JDL_SITEARCH ]]; then echo "ERROR: Must set ALIEN_JDL_SITEARCH to define GPU architecture!"; exit 1; fi + if [[ $ALIEN_JDL_SITEARCH == "NERSC" || $ALIEN_JDL_SITEARCH == "GENERIC_NVIDIA" || $ALIEN_JDL_SITEARCH == "GENERIC_AMD" ]]; then # Disable mlock / ulimit / gpu memory registration - has performance impact, but doesn't work at NERSC for now + export SETENV_NO_ULIMIT=1 + export CONFIG_EXTRA_PROCESS_o2_gpu_reco_workflow+="GPU_proc.noGPUMemoryRegistration=1;" + fi + ALIEN_JDL_SITEARCH_TMP=$ALIEN_JDL_SITEARCH + if [[ $ALIEN_JDL_SITEARCH == "EPN_MI100" ]]; then + ALIEN_JDL_SITEARCH_TMP=EPN + export EPN_NODE_MI100=1 + elif [[ $ALIEN_JDL_SITEARCH == "EPN_MI50" ]]; then + ALIEN_JDL_SITEARCH_TMP=EPN + fi + if [[ $ALIEN_JDL_SITEARCH == "GENERIC_NVIDIA" ]]; then + export OPTIMIZED_PARALLEL_ASYNC=8cpu_NVIDIA + elif [[ $ALIEN_JDL_SITEARCH == "GENERIC_AMD" ]]; then + export OPTIMIZED_PARALLEL_ASYNC=8cpu_AMD + elif [[ "ALIEN_JDL_USEFULLNUMADOMAIN" == 0 ]]; then if [[ $keep -eq 0 ]]; then if [[ $ALIEN_JDL_UNOPTIMIZEDGPUSETTINGS != 1 ]]; then - export OPTIMIZED_PARALLEL_ASYNC=pp_1gpu # sets the multiplicities to optimized defaults for this configuration (1 job with 1 gpu on EPNs) - export OPTIMIZED_PARALLEL_ASYNC_AUTO_SHM_LIMIT=1 + export OPTIMIZED_PARALLEL_ASYNC=pp_1gpu_${ALIEN_JDL_SITEARCH_TMP} # (16 cores, 1 gpu per job, pp) else - # forcing multiplicities to be 1 - export MULTIPLICITY_PROCESS_tof_matcher=1 - export MULTIPLICITY_PROCESS_mch_cluster_finder=1 - export MULTIPLICITY_PROCESS_tpc_entropy_decoder=1 - export MULTIPLICITY_PROCESS_itstpc_track_matcher=1 - export MULTIPLICITY_PROCESS_its_tracker=1 - export OMP_NUM_THREADS=4 - export TIMEFRAME_RATE_LIMIT=8 - export SHMSIZE=30000000000 + export OPTIMIZED_PARALLEL_ASYNC=pp_1gpu_${ALIEN_JDL_SITEARCH_TMP}_unoptimized # (16 cores, 1 gpu per job, pp, low CPU multiplicities) fi else - export TIMEFRAME_RATE_LIMIT=4 - export SHMSIZE=30000000000 + export OPTIMIZED_PARALLEL_ASYNC=keep_root fi else if [[ $BEAMTYPE == "pp" ]]; then - export OPTIMIZED_PARALLEL_ASYNC=pp_4gpu # sets the multiplicities to optimized defaults for this configuration (1 Numa, pp) - export OPTIMIZED_PARALLEL_ASYNC_AUTO_SHM_LIMIT=1 + if [[ $ALIEN_JDL_SITEARCH =~ ^EPN ]]; then + export OPTIMIZED_PARALLEL_ASYNC=pp_4gpu_${ALIEN_JDL_SITEARCH_TMP} # (64 cores, 1 NUMA, 4 gpu per job, pp) + else + export OPTIMIZED_PARALLEL_ASYNC=pp_gpu_${ALIEN_JDL_SITEARCH_TMP} # (64 cores, 1 gpu per job, pp) + fi else # PbPb - export OPTIMIZED_PARALLEL_ASYNC=PbPb_4gpu # sets the multiplicities to optimized defaults for this configuration (1 Numa, PbPb) - export OPTIMIZED_PARALLEL_ASYNC_AUTO_SHM_LIMIT=1 - fi - fi - fi -else - # David, Oct 13th - # the optimized settings for the 8 core GRID queue without GPU are - # (overwriting the values above) - # - if [[ "0$ASYNC_PASS_NO_OPTIMIZED_DEFAULTS" != "01" ]]; then - if [[ "$ALIEN_JDL_EPNFULLNUMACPUONLY" != 1 ]]; then - if [[ $BEAMTYPE == "pp" ]]; then - if (( $(echo "$RUN_IR > 800000" | bc -l) )); then - export TIMEFRAME_RATE_LIMIT=1 - elif (( $(echo "$RUN_IR < 50000" | bc -l) )); then - export TIMEFRAME_RATE_LIMIT=6 + if [[ $ALIEN_JDL_SITEARCH =~ ^EPN ]]; then + export OPTIMIZED_PARALLEL_ASYNC=PbPb_4gpu_${ALIEN_JDL_SITEARCH_TMP} # (64 cores, 1 NUMA 4 gpu per job, PbPb) else - export TIMEFRAME_RATE_LIMIT=3 + export OPTIMIZED_PARALLEL_ASYNC=PbPb_gpu_${ALIEN_JDL_SITEARCH_TMP} # (64 cores, 1 gpu per job, PbPb) fi - export OPTIMIZED_PARALLEL_ASYNC=pp_8cpu # sets the multiplicities to optimized defaults for this configuration (grid) - export SHMSIZE=16000000000 - else # PbPb - export TIMEFRAME_RATE_LIMIT=2 - export OPTIMIZED_PARALLEL_ASYNC=pp_8cpu - export SHMSIZE=16000000000 - export SVERTEX_THREADS=5 fi + fi + else + export SETENV_NO_ULIMIT=1 + export DPL_DEFAULT_PIPELINE_LENGTH=16 # to avoid memory issues - affects performance, so don't do with GPUs + if [[ $ALIEN_JDL_EPNFULLNUMACPUONLY != 1 ]]; then + export OPTIMIZED_PARALLEL_ASYNC=8cpu # (8 cores per job, grid) else - export OPTIMIZED_PARALLEL_ASYNC=pp_64cpu # to use EPNs with full NUMA domain but without GPUs - export OPTIMIZED_PARALLEL_ASYNC_AUTO_SHM_LIMIT=1 + export OPTIMIZED_PARALLEL_ASYNC=pp_64cpu # (64 cores per job, 1 NUMA, EPN) fi fi fi @@ -500,6 +492,12 @@ WORKFLOW_DETECTORS_EXCLUDE_QC_SCRIPT=${ALIEN_JDL_WORKFLOWDETECTORSEXCLUDEQC:-} # print workflow if [[ $ALIEN_JDL_SSPLITWF != "1" ]]; then env $SETTING_ROOT_OUTPUT IS_SIMULATED_DATA=0 WORKFLOWMODE=print TFDELAY=$TFDELAYSECONDS WORKFLOW_DETECTORS_EXCLUDE_QC=$WORKFLOW_DETECTORS_EXCLUDE_QC_SCRIPT ./run-workflow-on-inputlist.sh $INPUT_TYPE list.list > workflowconfig.log + exitcode=$? + if [[ $exitcode -ne 0 ]]; then + echo "exit code from printing workflow is $exitcode" > validation_error.message + echo "exit code from printing workflow is $exitcode" + exit $exitcode + fi # run it if [[ "0$RUN_WORKFLOW" != "00" ]]; then timeStart=`date +%s` @@ -540,6 +538,12 @@ else export WORKFLOW_PARAMETERS=$(echo $WORKFLOW_PARAMETERS | sed -e "s/,$i,/,/g" -e "s/^$i,//" -e "s/,$i"'$'"//" -e "s/^$i"'$'"//") done env DISABLE_ROOT_OUTPUT=0 IS_SIMULATED_DATA=0 WORKFLOWMODE=print TFDELAY=$TFDELAYSECONDS WORKFLOW_DETECTORS=TPC,CTP WORKFLOW_DETECTORS_MATCHING= ./run-workflow-on-inputlist.sh $INPUT_TYPE list.list >> workflowconfig.log + exitcode=$? + if [[ $exitcode -ne 0 ]]; then + echo "exit code from printing workflow (Step 1) is $exitcode" > validation_error.message + echo "exit code from printing workflow (Step 1) is $exitcode" + exit $exitcode + fi # run it if [[ "0$RUN_WORKFLOW" != "00" ]]; then timeStart=`date +%s` @@ -578,6 +582,12 @@ else export WORKFLOW_PARAMETERS=$(echo $WORKFLOW_PARAMETERS | sed -e "s/,$i,/,/g" -e "s/^$i,//" -e "s/,$i"'$'"//" -e "s/^$i"'$'"//") done env DISABLE_ROOT_OUTPUT=0 IS_SIMULATED_DATA=0 WORKFLOWMODE=print TFDELAY=$TFDELAYSECONDS WORKFLOW_DETECTORS=ALL WORKFLOW_DETECTORS_EXCLUDE=TPC,$DETECTORS_EXCLUDE WORKFLOW_DETECTORS_MATCHING= ./run-workflow-on-inputlist.sh $INPUT_TYPE list.list >> workflowconfig.log + exitcode=$? + if [[ $exitcode -ne 0 ]]; then + echo "exit code from printing workflow (Step 2) is $exitcode" > validation_error.message + echo "exit code from printing workflow (Step 2) is $exitcode" + exit $exitcode + fi # run it if [[ "0$RUN_WORKFLOW" != "00" ]]; then timeStart=`date +%s` @@ -663,6 +673,12 @@ else STEP_3_ROOT_OUTPUT=$SETTING_ROOT_OUTPUT fi env $STEP_3_ROOT_OUTPUT IS_SIMULATED_DATA=0 WORKFLOWMODE=print TFDELAY=$TFDELAYSECONDS WORKFLOW_DETECTORS=ALL WORKFLOW_DETECTORS_EXCLUDE=$DETECTORS_EXCLUDE WORKFLOW_DETECTORS_USE_GLOBAL_READER_TRACKS=$READ_TRACKS WORKFLOW_DETECTORS_USE_GLOBAL_READER_CLUSTERS=$READ_CLUSTERS WORKFLOW_DETECTORS_EXCLUDE_GLOBAL_READER_TRACKS=HMP WORKFLOW_DETECTORS_EXCLUDE_QC=$WORKFLOW_DETECTORS_EXCLUDE_QC_SCRIPT,$DETECTORS_EXCLUDE ./run-workflow-on-inputlist.sh $INPUT_TYPE list.list >> workflowconfig.log + exitcode=$? + if [[ $exitcode -ne 0 ]]; then + echo "exit code from printing workflow (Step 3) is $exitcode" > validation_error.message + echo "exit code from printing workflow (Step 3) is $exitcode" + exit $exitcode + fi # run it if [[ "0$RUN_WORKFLOW" != "00" ]]; then timeStart=`date +%s` @@ -701,6 +717,12 @@ else WORKFLOW_DETECTORS_EXCLUDE_QC_SCRIPT+=",CPV" echo "QC_JSON_FROM_OUTSIDE = $QC_JSON_FROM_OUTSIDE" env $SETTING_ROOT_OUTPUT IS_SIMULATED_DATA=0 WORKFLOWMODE=print TFDELAY=$TFDELAYSECONDS WORKFLOW_DETECTORS=ALL WORKFLOW_DETECTORS_EXCLUDE=$DETECTORS_EXCLUDE WORKFLOW_DETECTORS_USE_GLOBAL_READER_TRACKS=$READ_TRACKS WORKFLOW_DETECTORS_USE_GLOBAL_READER_CLUSTERS=$READ_CLUSTERS WORKFLOW_DETECTORS_EXCLUDE_GLOBAL_READER_TRACKS= WORKFLOW_DETECTORS_EXCLUDE_QC=$WORKFLOW_DETECTORS_EXCLUDE_QC_SCRIPT,$DETECTORS_EXCLUDE ./run-workflow-on-inputlist.sh $INPUT_TYPE list.list >> workflowconfig.log + exitcode=$? + if [[ $exitcode -ne 0 ]]; then + echo "exit code from printing workflow (Step 4) is $exitcode" > validation_error.message + echo "exit code from printing workflow (Step 4) is $exitcode" + exit $exitcode + fi # run it if [[ "0$RUN_WORKFLOW" != "00" ]]; then timeStart=`date +%s` diff --git a/DATA/production/configurations/asyncReco/setenv_extra.sh b/DATA/production/configurations/asyncReco/setenv_extra.sh index ff4500ac8..c414dc716 100644 --- a/DATA/production/configurations/asyncReco/setenv_extra.sh +++ b/DATA/production/configurations/asyncReco/setenv_extra.sh @@ -3,15 +3,6 @@ # process flags passed to the script -if [[ -z "$ALIEN_JDL_USEGPUS" || $ALIEN_JDL_USEGPUS != 1 ]]; then - export SETENV_NO_ULIMIT=1 -fi - -# to avoid memory issues - we don't do this on the EPNs, since it can affect the performance -if [[ $ALIEN_JDL_USEGPUS != 1 ]]; then - export DPL_DEFAULT_PIPELINE_LENGTH=16 -fi - # check if this is a production on skimmed data if grep -q /skimmed/ wn.xml ; then export ON_SKIMMED_DATA=1; @@ -21,7 +12,7 @@ if [[ $RUNNUMBER -lt 544772 ]]; then # these runs were using external dictionaries : ${RANS_OPT:="--ans-version compat"} export RANS_OPT -fi +fi echo "RSRUNNUMBER = $RUNNUMBER RANS_OPT = $RANS_OPT" # IR, duration, B field, detector list @@ -38,11 +29,15 @@ if [[ -z $RUN_IR ]] || [[ -z $RUN_DURATION ]] || [[ -z $RUN_BFIELD ]]; then export RUN_BFIELD=`cat BField.txt` export RUN_DETECTOR_LIST=`cat DetList.txt` fi + +BABSI=$(printf "%.0f" "${RUN_BFIELD#-}") +[[ "$BABSI" -lt 12500 && "$BABSI" -gt 11500 ]] && LOWFIELD=1 || LOWFIELD=0 + echo -e "\n" echo "Printing run features" echo "DETECTOR LIST for current run ($RUNNUMBER) = $RUN_DETECTOR_LIST" echo "DURATION for current run ($RUNNUMBER) = $RUN_DURATION" -echo "B FIELD for current run ($RUNNUMBER) = $RUN_BFIELD" +echo "B FIELD for current run ($RUNNUMBER) = $RUN_BFIELD (LOWFIELD = ${LOWFIELD})" echo "IR for current run ($RUNNUMBER) = $RUN_IR" if (( $(echo "$RUN_IR <= 0" | bc -l) )); then echo "Changing run IR to 1 Hz, because $RUN_IR makes no sense" @@ -51,6 +46,14 @@ fi echo "BeamType = $BEAMTYPE" echo "PERIOD = $PERIOD" + +if [[ $BEAMTYPE == "pO" ]] || [[ $BEAMTYPE == "Op" ]] || [[ $BEAMTYPE == "Op" ]] || [[ $BEAMTYPE == "OO" ]] || [[ $BEAMTYPE == "NeNe" ]] ; then + export LIGHTNUCLEI=1 +else + export LIGHTNUCLEI=0 +fi + + # detector list echo -e "\n" echo "Printing detector list for reconstruction" @@ -82,7 +85,7 @@ echo "WORKFLOW_DETECTORS_EXCLUDE = $WORKFLOW_DETECTORS_EXCLUDE" # ad-hoc settings for CTF reader: we are on the grid, we read the files remotely echo -e "\nProcessing mode = ${MODE}" -unset ARGS_EXTRA_PROCESS_o2_ctf_reader_workflow +#unset ARGS_EXTRA_PROCESS_o2_ctf_reader_workflow if [[ $MODE == "remote" ]]; then if [[ $ALIEN_JDL_REMOTEREADING != 1 ]]; then @@ -119,6 +122,15 @@ if [[ $remappingITS == 1 ]] || [[ $remappingMFT == 1 ]]; then REMAPPING=$REMAPPING\" fi +# generic remapping string +if [[ -n "$ALIEN_JDL_REMAPPINGS" ]]; then + if [[ -n "$REMAPPING" ]]; then + REMAPPING="${REMAPPING::-1};$ALIEN_JDL_REMAPPINGS\"" + else + REMAPPING="--condition-remap \"$ALIEN_JDL_REMAPPINGS\"" + fi +fi + echo "Remapping = $REMAPPING" # needed if we need more wf @@ -139,8 +151,7 @@ fi # other settings echo RUN = $RUNNUMBER if [[ $RUNNUMBER -ge 521889 ]]; then - export ARGS_EXTRA_PROCESS_o2_ctf_reader_workflow+=" --its-digits --mft-digits" - export DISABLE_DIGIT_CLUSTER_INPUT="--digits-from-upstream" + export ITSMFT_RECO_RERUN_CLUSTERIZER=1 MAXBCDIFFTOMASKBIAS_ITS="ITSClustererParam.maxBCDiffToMaskBias=-10" # this explicitly disables ITS masking MAXBCDIFFTOSQUASHBIAS_ITS="ITSClustererParam.maxBCDiffToSquashBias=10" # this explicitly enables ITS squashing MAXBCDIFFTOMASKBIAS_MFT="MFTClustererParam.maxBCDiffToMaskBias=-10" # this explicitly disables MFT masking @@ -278,7 +289,7 @@ isFT0inDataTaking=`echo $RUN_DETECTOR_LIST | grep FT0` # For runs shorter than 10 minutes we have only a single slot. # In that case we have to adopt the slot length in order to # set the maximum number of processed tracks per TF correctly -if (( RUN_DURATION < 600 )); then +if (( RUN_DURATION < 300 )); then export CALIB_TPC_SCDCALIB_SLOTLENGTH=$RUN_DURATION fi @@ -291,13 +302,30 @@ else export ENABLE_METRICS=0 fi +if [ -z ${ALIEN_JDL_LPMANCHOREDPASSNUMBER+x} ]; then + export ANCHORED_PASS_NUMBER=$(echo $ALIEN_JDL_LPMPASSNAME | sed 's/^apass//' | cut -c1-1) + echo "using ANCHORED_PASS_NUMBER from pass name $ALIEN_JDL_LPMPASSNAME, ANCHORED_PASS_NUMBER=$ANCHORED_PASS_NUMBER" +else + # variable exported, takes precedence over anything else + export ANCHORED_PASS_NUMBER=$ALIEN_JDL_LPMANCHOREDPASSNUMBER + echo "using ANCHORED_PASS_NUMBER from $ALIEN_JDL_LPMANCHOREDPASSNUMBER defined by JDL, ANCHORED_PASS_NUMBER=$ANCHORED_PASS_NUMBER" +fi + +echo "Checking ANCHORED_PASS_NUMBER" +if [ -n "$ANCHORED_PASS_NUMBER" ] && [ "$ANCHORED_PASS_NUMBER" -eq "$ANCHORED_PASS_NUMBER" ] 2>/dev/null; then + echo "ANCHORED_PASS_NUMBER set to $ANCHORED_PASS_NUMBER" +else + echo "[Warning] undetermined ANCHORED_PASS_NUMBER" +fi + + #ALIGNLEVEL=0: before December 2022 alignment, 1: after December 2022 alignment ALIGNLEVEL=1 if [[ "0$OLDVERSION" == "01" ]] && [[ $BEAMTYPE == "PbPb" || $PERIOD == "MAY" || $PERIOD == "JUN" || $PERIOD == "LHC22c" || $PERIOD == "LHC22d" || $PERIOD == "LHC22e" || $PERIOD == "LHC22f" ]]; then ALIGNLEVEL=0 if [[ $ALIEN_JDL_LPMPRODUCTIONTYPE == "MC" ]]; then # extract pass number - ANCHORED_PASS=$ALIEN_JDL_LPMANCHOREPASSNAME + ANCHORED_PASS=$ALIEN_JDL_LPMANCHOREDPASSNAME ANCHORED_PASS_NUMBER=`echo $ANCHORED_PASS | sed 's/^apass//'` echo "ANCHORED_PASS_NUMER = $ANCHORED_PASS_NUMBER" if [[ $PERIOD == "MAY" || $PERIOD == "JUN" ]] && [[ $ANCHORED_PASS_NUMBER -gt 1 ]]; then @@ -308,6 +336,8 @@ if [[ "0$OLDVERSION" == "01" ]] && [[ $BEAMTYPE == "PbPb" || $PERIOD == "MAY" || fi fi +EXTRA_PRIMVTX_TimeMargin="" + # some settings in common between workflows and affecting ITS-TPC matching : ${CUT_MATCH_CHI2:=250} if [[ $ALIGNLEVEL == 0 ]]; then @@ -320,9 +350,8 @@ elif [[ $ALIGNLEVEL == 1 ]]; then ERRIB="100e-8" ERROB="100e-8" [[ -z $TPCITSTIMEERR ]] && TPCITSTIMEERR="0.2" - [[ -z $ITS_CONFIG || "$ITS_CONFIG" != *"--tracking-mode"* ]] && export ITS_CONFIG+=" --tracking-mode async" - [[ $ALIEN_JDL_LPMANCHORYEAR == "2023" ]] && [[ $BEAMTYPE == "PbPb" ]] && CUT_MATCH_CHI2=80 || CUT_MATCH_CHI2=100 - if [[ $ALIEN_JDL_LPMANCHORYEAR == "2023" && $BEAMTYPE == "PbPb" ]] || [[ $PERIOD == "LHC24al" ]] ; then + if [[ $ALIEN_JDL_LPMANCHORYEAR == "2023" && $BEAMTYPE == "PbPb" && $ANCHORED_PASS_NUMBER -lt 5 ]] || [[ $PERIOD == "LHC24al" ]] ; then + [[ $ALIEN_JDL_LPMANCHORYEAR == "2023" ]] && [[ $BEAMTYPE == "PbPb" ]] && CUT_MATCH_CHI2=80 || CUT_MATCH_CHI2=100 export ITSTPCMATCH="tpcitsMatch.safeMarginTimeCorrErr=2.;tpcitsMatch.XMatchingRef=60.;tpcitsMatch.cutMatchingChi2=$CUT_MATCH_CHI2;;tpcitsMatch.crudeAbsDiffCut[0]=6;tpcitsMatch.crudeAbsDiffCut[1]=6;tpcitsMatch.crudeAbsDiffCut[2]=0.3;tpcitsMatch.crudeAbsDiffCut[3]=0.3;tpcitsMatch.crudeAbsDiffCut[4]=2.5;tpcitsMatch.crudeNSigma2Cut[0]=64;tpcitsMatch.crudeNSigma2Cut[1]=64;tpcitsMatch.crudeNSigma2Cut[2]=64;tpcitsMatch.crudeNSigma2Cut[3]=64;tpcitsMatch.crudeNSigma2Cut[4]=64;" export ITSTPCMATCH="${ITSTPCMATCH};tpcitsMatch.askMinTPCRow[0]=20;tpcitsMatch.askMinTPCRow[1]=20;tpcitsMatch.askMinTPCRow[2]=20;tpcitsMatch.askMinTPCRow[3]=20;tpcitsMatch.askMinTPCRow[4]=20;tpcitsMatch.askMinTPCRow[5]=20;tpcitsMatch.askMinTPCRow[6]=20;tpcitsMatch.askMinTPCRow[7]=20;tpcitsMatch.askMinTPCRow[8]=20;tpcitsMatch.askMinTPCRow[9]=20;tpcitsMatch.askMinTPCRow[10]=20;tpcitsMatch.askMinTPCRow[12]=20;tpcitsMatch.askMinTPCRow[13]=20;tpcitsMatch.askMinTPCRow[14]=20;" export ITSTPCMATCH="${ITSTPCMATCH};tpcitsMatch.askMinTPCRow[15]=20;tpcitsMatch.askMinTPCRow[16]=20;tpcitsMatch.askMinTPCRow[17]=20;tpcitsMatch.askMinTPCRow[18]=20;tpcitsMatch.askMinTPCRow[19]=20;tpcitsMatch.askMinTPCRow[20]=20;tpcitsMatch.askMinTPCRow[21]=20;tpcitsMatch.askMinTPCRow[22]=20;tpcitsMatch.askMinTPCRow[23]=20;tpcitsMatch.askMinTPCRow[24]=20;tpcitsMatch.askMinTPCRow[25]=20;tpcitsMatch.askMinTPCRow[26]=20;tpcitsMatch.askMinTPCRow[27]=20;tpcitsMatch.askMinTPCRow[28]=20;tpcitsMatch.askMinTPCRow[29]=20;" @@ -339,10 +368,49 @@ elif [[ $ALIGNLEVEL == 1 ]]; then done fi [[ $APPLYS11 == 1 ]] && export ITSTPCMATCH="${ITSTPCMATCH};tpcitsMatch.askMinTPCRow[11]=78;" || export ITSTPCMATCH="${ITSTPCMATCH};tpcitsMatch.askMinTPCRow[11]=20;" + elif [[ $BEAMTYPE == "PbPb" && ( ( $ALIEN_JDL_LPMANCHORYEAR == "2023" && $ANCHORED_PASS_NUMBER -gt 4 ) || ( $ALIEN_JDL_LPMANCHORYEAR == "2024" && $ANCHORED_PASS_NUMBER -gt 1 ) ) ]] ; then + export ITSTPCMATCH="${ITSTPCMATCH};tpcitsMatch.askMinTPCRow[0]=78;tpcitsMatch.askMinTPCRow[1]=78;tpcitsMatch.askMinTPCRow[2]=78;tpcitsMatch.askMinTPCRow[3]=78;tpcitsMatch.askMinTPCRow[4]=78;tpcitsMatch.askMinTPCRow[5]=78;tpcitsMatch.askMinTPCRow[6]=78;tpcitsMatch.askMinTPCRow[7]=78;tpcitsMatch.askMinTPCRow[8]=78;tpcitsMatch.askMinTPCRow[9]=78;tpcitsMatch.askMinTPCRow[10]=78;tpcitsMatch.askMinTPCRow[11]=78;tpcitsMatch.askMinTPCRow[12]=78;tpcitsMatch.askMinTPCRow[13]=78;tpcitsMatch.askMinTPCRow[14]=78;tpcitsMatch.askMinTPCRow[15]=78;tpcitsMatch.askMinTPCRow[16]=78;tpcitsMatch.askMinTPCRow[17]=78;tpcitsMatch.askMinTPCRow[18]=78;tpcitsMatch.askMinTPCRow[19]=78;tpcitsMatch.askMinTPCRow[20]=78;tpcitsMatch.askMinTPCRow[21]=78;tpcitsMatch.askMinTPCRow[22]=78;tpcitsMatch.askMinTPCRow[23]=78;tpcitsMatch.askMinTPCRow[24]=78;tpcitsMatch.askMinTPCRow[25]=78;tpcitsMatch.askMinTPCRow[26]=78;tpcitsMatch.askMinTPCRow[27]=78;tpcitsMatch.askMinTPCRow[28]=78;tpcitsMatch.askMinTPCRow[29]=78;tpcitsMatch.askMinTPCRow[30]=78;tpcitsMatch.askMinTPCRow[31]=78;tpcitsMatch.askMinTPCRow[32]=78;tpcitsMatch.askMinTPCRow[33]=78;tpcitsMatch.askMinTPCRow[34]=78;tpcitsMatch.askMinTPCRow[35]=78;" + elif [[ $BEAMTYPE == "pp" || $LIGHTNUCLEI == "1" ]] ; then + export ITSTPCMATCH="${ITSTPCMATCH};tpcitsMatch.askMinTPCRow[0]=78;tpcitsMatch.askMinTPCRow[1]=78;tpcitsMatch.askMinTPCRow[2]=78;tpcitsMatch.askMinTPCRow[3]=78;tpcitsMatch.askMinTPCRow[4]=78;tpcitsMatch.askMinTPCRow[5]=78;tpcitsMatch.askMinTPCRow[6]=78;tpcitsMatch.askMinTPCRow[7]=78;tpcitsMatch.askMinTPCRow[8]=78;tpcitsMatch.askMinTPCRow[9]=78;tpcitsMatch.askMinTPCRow[10]=78;tpcitsMatch.askMinTPCRow[11]=78;tpcitsMatch.askMinTPCRow[12]=78;tpcitsMatch.askMinTPCRow[13]=78;tpcitsMatch.askMinTPCRow[14]=78;tpcitsMatch.askMinTPCRow[15]=78;tpcitsMatch.askMinTPCRow[16]=78;tpcitsMatch.askMinTPCRow[17]=78;tpcitsMatch.askMinTPCRow[18]=78;tpcitsMatch.askMinTPCRow[19]=78;tpcitsMatch.askMinTPCRow[20]=78;tpcitsMatch.askMinTPCRow[21]=78;tpcitsMatch.askMinTPCRow[22]=78;tpcitsMatch.askMinTPCRow[23]=78;tpcitsMatch.askMinTPCRow[24]=78;tpcitsMatch.askMinTPCRow[25]=78;tpcitsMatch.askMinTPCRow[26]=78;tpcitsMatch.askMinTPCRow[27]=78;tpcitsMatch.askMinTPCRow[28]=78;tpcitsMatch.askMinTPCRow[29]=78;tpcitsMatch.askMinTPCRow[30]=78;tpcitsMatch.askMinTPCRow[31]=78;tpcitsMatch.askMinTPCRow[32]=78;tpcitsMatch.askMinTPCRow[33]=78;tpcitsMatch.askMinTPCRow[34]=78;tpcitsMatch.askMinTPCRow[35]=78;" fi + + # settings to improve inner pad-rows contribution - export CONFIG_EXTRA_PROCESS_o2_gpu_reco_workflow+=";GPU_rec_tpc.trackletMinSharedNormFactor=1.;GPU_rec_tpc.trackletMaxSharedFraction=0.3;GPU_rec_tpc.globalTrackingRowRange=100;GPU_rec_tpc.rejectIFCLowRadiusCluster=1;" - + export CONFIG_EXTRA_PROCESS_o2_gpu_reco_workflow+=";GPU_rec_tpc.trackletMinSharedNormFactor=1.;GPU_rec_tpc.trackletMaxSharedFraction=0.3;GPU_rec_tpc.rejectIFCLowRadiusCluster=1;" + if grep extrapolationTrackingRowRange $O2_ROOT/include/GPU/GPUSettingsList.h &> /dev/null ; then + export CONFIG_EXTRA_PROCESS_o2_gpu_reco_workflow+="GPU_rec_tpc.extrapolationTrackingRowRange=100;" + else + export CONFIG_EXTRA_PROCESS_o2_gpu_reco_workflow+="GPU_rec_tpc.globalTrackingRowRange=100;" + fi + + if [[ -n "$ALIEN_JDL_TPCDEDXCLMASK" ]]; then + CONFIG_EXTRA_PROCESS_o2_gpu_reco_workflow+="GPU_rec_tpc.dEdxClusterRejectionFlagMask=$ALIEN_JDL_TPCDEDXCLMASK;" + fi + + if [[ -n "$ALIEN_JDL_TPCDEDXCLMASKALT" ]]; then + CONFIG_EXTRA_PROCESS_o2_gpu_reco_workflow+="GPU_rec_tpc.dEdxClusterRejectionFlagMaskAlt=$ALIEN_JDL_TPCDEDXCLMASKALT;" + fi + + if [[ -n "$ALIEN_JDL_TPCEDGETWOPADS" ]]; then + CONFIG_EXTRA_PROCESS_o2_gpu_reco_workflow+="GPU_rec_tpc.cfEdgeTwoPads=$ALIEN_JDL_TPCEDGETWOPADS;" + fi + + if [[ -n "$ALIEN_JDL_TPCCLUSTERFILTER" ]]; then + CONFIG_EXTRA_PROCESS_o2_gpu_reco_workflow+="GPU_proc.tpcUseOldCPUDecoding=1;GPU_proc.tpcApplyClusterFilterOnCPU=$ALIEN_JDL_TPCCLUSTERFILTER;" + fi + + if [[ -n "$ALIEN_JDL_TPCMEMORYSCALING" ]]; then + CONFIG_EXTRA_PROCESS_o2_gpu_reco_workflow+="GPU_proc.memoryScalingFactor=$ALIEN_JDL_TPCMEMORYSCALING;" + fi + + if [[ -n "$ALIEN_JDL_TPCCHICUTOPT" ]]; then # 0 or 1 to disable or enable (default) the chi2 cut both on one-side and smoothed Kalman chi2 + CONFIG_EXTRA_PROCESS_o2_gpu_reco_workflow+="GPU_rec_tpc.mergerInterpolateRejectAlsoOnCurrentPosition=$ALIEN_JDL_TPCCHICUTOPT;" + fi + + if [[ -n "$ALIEN_JDL_TPCCLUSEDGEREDEF" ]]; then # if >0 (float) undo the edge cluster bit for TPC clusters with distance to the edge exceeding this value + CONFIG_EXTRA_PROCESS_o2_gpu_reco_workflow+="GPU_rec_tpc.clustersEdgeFixDistance=$ALIEN_JDL_TPCCLUSEDGEREDEF;" + fi + #-------------------------------------- TPC corrections ----------------------------------------------- # we need to provide to TPC # 1) interaction rate info (lumi) used for scaling or errors and possible of the corrections : INST_IR_FOR_TPC @@ -352,6 +420,8 @@ elif [[ $ALIGNLEVEL == 1 ]]; then TPC_SCALING_SOURCE=${ALIEN_JDL_TPCSCALINGSOURCE-IDCCCDB} # MEAN_IR_FOR_TPC allows (1) to alter the map mean IR if >0 or (2) disable all corrections if <0 MEAN_IR_FOR_TPC=${ALIEN_JDL_MEANIRFORTPC-} + # optional mean IR to impose for the ref. map + MEAN_IR_REF_FOR_TPC=${ALIEN_JDL_MEANIRREFFORTPC-} if [[ $ALIEN_JDL_LPMANCHORYEAR == "2022" ]]; then INST_IR_FOR_TPC=${ALIEN_JDL_INSTIRFORTPC-CTPCCDB} # by default override inst.IR by the mean IR from CCDB and use it for scaling @@ -369,12 +439,12 @@ elif [[ $ALIGNLEVEL == 1 ]]; then DISABLE_CORRECTIONS= [[ -n "$ALIEN_JDL_MSHAPECORRECTION" && $ALIEN_JDL_MSHAPECORRECTION == "0" ]] && ENABLE_MSHAPE=0 || ENABLE_MSHAPE=1 - + if [[ -n $MEAN_IR_FOR_TPC ]] ; then # firs check if corrections were not disabled via MEAN_IR_FOR_TPC - if [[ $MEAN_IR_FOR_TPC -gt 0 ]] ; then # positive value overrides map mean lumi - echo "Applying externally provided map mean IR for scaling, $MEAN_IR_FOR_TPC Hz" + if (( $(echo "$MEAN_IR_FOR_TPC > 0" | bc -l) )) ; then # positive value overrides map mean lumi + echo "Applying externally provided map mean IR for scaling, $MEAN_IR_FOR_TPC" export TPC_CORR_SCALING+=";TPCCorrMap.lumiMean=$MEAN_IR_FOR_TPC;" # take mean lumy at face value - elif [[ $MEAN_IR_FOR_TPC -lt 0 ]] ; then # negative mean lumi disables all corrections + elif (( $(echo "$MEAN_IR_FOR_TPC < 0" | bc -l) )) ; then # negative mean lumi disables all corrections echo "Negative MEAN_IR_FOR_TPC -> all TPC corrections will be ignored" export TPC_CORR_SCALING+=" --lumi-type 0 " export TPC_CORR_SCALING+=";TPCCorrMap.lumiMean=$MEAN_IR_FOR_TPC;" @@ -382,12 +452,18 @@ elif [[ $ALIGNLEVEL == 1 ]]; then DISABLE_CORRECTIONS=1 else echo "Did not recognize MEAN_IR_FOR_TPC = $MEAN_IR_FOR_TPC" - return 1 + return 1 fi fi # MEAN_IR_FOR_TPC overridden + if [[ -n $MEAN_IR_REF_FOR_TPC ]] ; then + echo "Applying externally provided map mean reference map IR, $MEAN_IR_REF_FOR_TPC" + export TPC_CORR_SCALING+=";TPCCorrMap.lumiMeanRef=$MEAN_IR_REF_FOR_TPC" + fi + + # set IR for TPC, even if it is not used for corrections scaling - if [[ $INST_IR_FOR_TPC -gt 0 ]]; then # externally imposed CTP IR + if [[ "$INST_IR_FOR_TPC" =~ ^-?[0-9]*\.?[0-9]+$ ]] && (( $(echo "$INST_IR_FOR_TPC > 0" | bc -l) )) ; then # externally imposed CTP IR echo "Applying externally provided istantaneous IR $INST_IR_FOR_TPC Hz" export TPC_CORR_SCALING+=";TPCCorrMap.lumiInst=$INST_IR_FOR_TPC" elif [[ $INST_IR_FOR_TPC == "CTP" ]]; then @@ -408,9 +484,12 @@ elif [[ $ALIGNLEVEL == 1 ]]; then if [[ $TPC_SCALING_SOURCE == "NO_SCALING" ]]; then echo "NO SCALING is requested: only TPC/Calib/CorrectionMapsV2... will be applied" export TPC_CORR_SCALING+=" --lumi-type 0 " - elif [[ $TPC_SCALING_SOURCE == "CTP" ]]; then + elif [[ $TPC_SCALING_SOURCE == "CTP" ]]; then echo "CTP Lumi from data will be used for TPC scaling" export TPC_CORR_SCALING+=" --lumi-type 1 " + if [[ $ALIEN_JDL_USEDERIVATIVESFORSCALING == "1" ]]; then + export TPC_CORR_SCALING+=" --corrmap-lumi-mode 1 " + fi elif [[ $TPC_SCALING_SOURCE == "IDCCCDB" ]]; then echo "TPC correction with IDC from CCDB will be used" export TPC_CORR_SCALING+=" --lumi-type 2 " @@ -426,11 +505,11 @@ elif [[ $ALIGNLEVEL == 1 ]]; then echo "CTP is not in the list of detectors, disabling CTP Lumi input request" export TPC_CORR_SCALING+=" --disable-ctp-lumi-request " fi - + if [[ $ENABLE_MSHAPE == "1" ]]; then export TPC_CORR_SCALING+=" --enable-M-shape-correction " fi - + if [[ $ALIEN_JDL_LPMANCHORYEAR -ge 2023 ]] && [[ $BEAMTYPE == "PbPb" ]] ; then # adding additional cluster errors # the values below should be squared, but the validation of those values (0.01 and 0.0225) is ongoing @@ -474,12 +553,23 @@ export ITSEXTRAERR="ITSCATrackerParam.sysErrY2[0]=$ERRIB;ITSCATrackerParam.sysEr # ad-hoc options for ITS reco workflow EXTRA_ITSRECO_CONFIG= if [[ $BEAMTYPE == "PbPb" ]]; then - EXTRA_ITSRECO_CONFIG="ITSCATrackerParam.deltaRof=0;ITSVertexerParam.clusterContributorsCut=16;ITSVertexerParam.lowMultBeamDistCut=0;ITSCATrackerParam.nROFsPerIterations=12;ITSCATrackerParam.perPrimaryVertexProcessing=false;ITSCATrackerParam.fataliseUponFailure=false;ITSCATrackerParam.dropTFUponFailure=true" + # tracker memory + EXTRA_ITSRECO_CONFIG=";ITSCATrackerParam.perPrimaryVertexProcessing=false;ITSCATrackerParam.fataliseUponFailure=false;ITSCATrackerParam.dropTFUponFailure=true;ITSCATrackerParam.maxMemory=21474836480;" if [[ -z "$ALIEN_JDL_DISABLE_UPC" || $ALIEN_JDL_DISABLE_UPC != 1 ]]; then EXTRA_ITSRECO_CONFIG+=";ITSVertexerParam.nIterations=2;ITSCATrackerParam.doUPCIteration=true;" fi -elif [[ $BEAMTYPE == "pp" ]]; then - EXTRA_ITSRECO_CONFIG="ITSVertexerParam.phiCut=0.5;ITSVertexerParam.clusterContributorsCut=3;ITSVertexerParam.tanLambdaCut=0.2;" + if [[ $LOWFIELD == "1" ]]; then + EXTRA_ITSRECO_CONFIG+=";ITSCATrackerParam.minPt=2.5;" # disables B-field scaling + fi +elif [[ $BEAMTYPE == "pp" || $LIGHTNUCLEI == "1" ]]; then + # allowed start layers + EXTRA_ITSRECO_CONFIG=";ITSCATrackerParam.startLayerMask[0]=127;ITSCATrackerParam.startLayerMask[1]=127;ITSCATrackerParam.startLayerMask[2]=127;" + # low pt-cutoffs + EXTRA_ITSRECO_CONFIG+=";ITSCATrackerParam.minPtIterLgt[0]=0.05;ITSCATrackerParam.minPtIterLgt[1]=0.05;ITSCATrackerParam.minPtIterLgt[2]=0.05;ITSCATrackerParam.minPtIterLgt[3]=0.05;ITSCATrackerParam.minPtIterLgt[4]=0.05;ITSCATrackerParam.minPtIterLgt[5]=0.05;ITSCATrackerParam.minPtIterLgt[6]=0.05;ITSCATrackerParam.minPtIterLgt[7]=0.05;ITSCATrackerParam.minPtIterLgt[8]=0.05;ITSCATrackerParam.minPtIterLgt[9]=0.09;ITSCATrackerParam.minPtIterLgt[10]=0.167;ITSCATrackerParam.minPtIterLgt[11]=0.125;" + # enable delta-rof tracking + EXTRA_ITSRECO_CONFIG+=";ITSCATrackerParam.addTimeError[0]=30;ITSCATrackerParam.addTimeError[1]=30;ITSCATrackerParam.addTimeError[2]=30;ITSCATrackerParam.addTimeError[3]=30;ITSCATrackerParam.addTimeError[4]=30;ITSCATrackerParam.addTimeError[5]=30;ITSCATrackerParam.addTimeError[6]=30;ITSVertexerParam.seedMemberRadiusTime=1;" +# this is to impose old pp pT cuts (overriding hardcoded pbpb24 apass1 settings) +# EXTRA_ITSRECO_CONFIG+=";ITSCATrackerParam.minPtIterLgt[0]=0.05;ITSCATrackerParam.minPtIterLgt[1]=0.05;ITSCATrackerParam.minPtIterLgt[2]=0.05;ITSCATrackerParam.minPtIterLgt[3]=0.05;ITSCATrackerParam.minPtIterLgt[4]=0.05;ITSCATrackerParam.minPtIterLgt[5]=0.05;ITSCATrackerParam.minPtIterLgt[6]=0.05;ITSCATrackerParam.minPtIterLgt[7]=0.05;ITSCATrackerParam.minPtIterLgt[8]=0.05;ITSCATrackerParam.minPtIterLgt[9]=0.05;ITSCATrackerParam.minPtIterLgt[10]=0.05;ITSCATrackerParam.minPtIterLgt[11]=0.05;" fi export CONFIG_EXTRA_PROCESS_o2_its_reco_workflow+=";$MAXBCDIFFTOMASKBIAS_ITS;$MAXBCDIFFTOSQUASHBIAS_ITS;$EXTRA_ITSRECO_CONFIG;" @@ -490,9 +580,10 @@ fi # ad-hoc options for GPU reco workflow export CONFIG_EXTRA_PROCESS_o2_gpu_reco_workflow+=";GPU_global.dEdxDisableResidualGainMap=1;$TRACKTUNETPC;$VDRIFTPARAMOPTION;" -if [[ $ALIEN_JDL_LPMPRODUCTIONTYPE == "MC" ]]; then - export CONFIG_EXTRA_PROCESS_o2_gpu_reco_workflow+=";GPU_global.dEdxDisableResidualGain=1" -fi + +# if ITS is running on GPU we need to give the workflow most options from ITS reco +has_detector_gpu ITS && export CONFIG_EXTRA_PROCESS_o2_gpu_reco_workflow+=";$CONFIG_EXTRA_PROCESS_o2_its_reco_workflow;" + [[ ! -z $TPCCLUSTERTIMESHIFT ]] && [[ $ALIEN_JDL_LPMPRODUCTIONTYPE != "MC" ]] && export CONFIG_EXTRA_PROCESS_o2_gpu_reco_workflow+=";GPU_rec_tpc.clustersShiftTimebins=$TPCCLUSTERTIMESHIFT;" # ad-hoc settings for TOF reco @@ -505,18 +596,19 @@ export ARGS_EXTRA_PROCESS_o2_tof_reco_workflow+=" --use-ccdb" # following comment https://alice.its.cern.ch/jira/browse/O2-2691?focusedCommentId=278262&page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel#comment-278262 #export PVERTEXER="pvertexer.acceptableScale2=9;pvertexer.minScale2=2.;pvertexer.nSigmaTimeTrack=4.;pvertexer.timeMarginTrackTime=0.5;pvertexer.timeMarginVertexTime=7.;pvertexer.nSigmaTimeCut=10;pvertexer.dbscanMaxDist2=36;pvertexer.dcaTolerance=3.;pvertexer.pullIniCut=100;pvertexer.addZSigma2=0.1;pvertexer.tukey=20.;pvertexer.addZSigma2Debris=0.01;pvertexer.addTimeSigma2Debris=1.;pvertexer.maxChi2Mean=30;pvertexer.timeMarginReattach=3.;pvertexer.addTimeSigma2Debris=1.;pvertexer.dbscanDeltaT=24;pvertexer.maxChi2TZDebris=100;pvertexer.maxMultRatDebris=1.;pvertexer.dbscanAdaptCoef=20.;pvertexer.timeMarginVertexTime=1.3" # updated on 7 Sept 2022 -EXTRA_PRIMVTX_TimeMargin="" if [[ $BEAMTYPE == "PbPb" || $PERIOD == "MAY" || $PERIOD == "JUN" || $PERIOD == LHC22* || $PERIOD == LHC23* ]]; then EXTRA_PRIMVTX_TimeMargin="pvertexer.timeMarginVertexTime=1.3" fi export PVERTEXER+=";pvertexer.acceptableScale2=9;pvertexer.minScale2=2;$EXTRA_PRIMVTX_TimeMargin;" if [[ $ALIGNLEVEL == 1 ]]; then - if [[ $BEAMTYPE == "pp" ]]; then - export PVERTEXER+=";pvertexer.maxChi2TZDebris=40;pvertexer.maxChi2Mean=12;pvertexer.maxMultRatDebris=1.;pvertexer.addTimeSigma2Debris=1e-2;pvertexer.meanVertexExtraErrSelection=0.03;" - elif [[ $BEAMTYPE == "PbPb" ]]; then + if [[ $BEAMTYPE == "PbPb" ]]; then export PVERTEXER+=";pvertexer.addTimeSigma2Debris=1e-2;pvertexer.meanVertexExtraErrSelection=0.03;pvertexer.maxITSOnlyFraction=0.85;pvertexer.maxTDiffDebris=1.5;pvertexer.maxZDiffDebris=0.3;pvertexer.addZSigma2Debris=0.09;pvertexer.addTimeSigma2Debris=2.25;pvertexer.maxChi2TZDebris=100;pvertexer.maxMultRatDebris=1.;pvertexer.maxTDiffDebrisExtra=-1.;pvertexer.dbscanDeltaT=-0.55;pvertexer.maxTMAD=1.;pvertexer.maxZMAD=0.04;" has_detector_reco FT0 && PVERTEX_CONFIG+=" --validate-with-ft0 " + elif [[ $BEAMTYPE == "pp" ]]; then + export PVERTEXER+=";pvertexer.maxChi2TZDebris=40;pvertexer.maxChi2Mean=12;pvertexer.maxMultRatDebris=1.;pvertexer.addTimeSigma2Debris=1e-2;pvertexer.meanVertexExtraErrSelection=0.03;" + elif [[ $LIGHTNUCLEI == "1" ]]; then + export PVERTEXER+="pvertexer.maxChi2TZDebris=3000;pvertexer.maxTDiffDebris=0.7;pvertexer.maxZDiffDebris=0.5;pvertexer.maxMultRatDebris=0.25;pvertexer.addTimeSigma2Debris=0.2;pvertexer.addZSigma2Debris=0.2;pvertexer.maxChi2TZDebrisExtra=50;pvertexer.maxTDiffDebrisExtra=-1;pvertexer.maxZDiffDebrisExtra=0.03;pvertexer.maxMultRatDebrisExtra=0.25;pvertexer.meanVertexExtraErrSelection=0.03;pvertexer.maxITSOnlyFraction=0.8;pvertexer.meanVertexExtraErrSelection=0.03;" fi fi @@ -554,6 +646,14 @@ fi # ad-hoc settings for TRD matching export CONFIG_EXTRA_PROCESS_o2_trd_global_tracking+=";$ITSEXTRAERR;$TRACKTUNETPC;$VDRIFTPARAMOPTION;GPU_rec_trd.minTrackPt=0.3;" +# Pb26 reconstruction uses improved alignment with shifted ITS (mean vertex) +if [[ $RUNNUMBER -ge 572013 ]] ; then + export CONFIG_EXTRA_PROCESS_o2_trd_global_tracking+=";GPU_rec_trd.trkltResRPhiIdeal=0.2;GPU_rec_trd.trkltResVsTanPhiMisalign=1.;" + if [[ -z $ALIEN_JDL_MVBIAS ]]; then + export O2_DPL_MVBIAS=";mvbias.xyz[0]=0.0332;mvbias.xyz[1]=-0.1825;mvbias.xyz[2]=-0.2846;mvbias.slopeX=-4.27e-05;mvbias.slopeY=-6.96e-05;"; + fi +fi + # ad-hoc settings for FT0 export ARGS_EXTRA_PROCESS_o2_ft0_reco_workflow+=" --ft0-reconstructor" if [[ $BEAMTYPE == "PbPb" ]]; then @@ -567,17 +667,30 @@ export ARGS_EXTRA_PROCESS_o2_fv0_reco_workflow+=" --fv0-reconstructor" #... # ad-hoc settings for MFT -if [[ $BEAMTYPE == "pp" || $PERIOD == "LHC22s" ]]; then +if [[ $BEAMTYPE == "pp" || $LIGHTNUCLEI == "1" || $PERIOD == "LHC22s" ]]; then export CONFIG_EXTRA_PROCESS_o2_mft_reco_workflow+=";MFTTracking.RBins=30;MFTTracking.PhiBins=120;MFTTracking.ZVtxMin=-13;MFTTracking.ZVtxMax=13;MFTTracking.MFTRadLength=0.084;$MAXBCDIFFTOMASKBIAS_MFT;$MAXBCDIFFTOSQUASHBIAS_MFT" else export CONFIG_EXTRA_PROCESS_o2_mft_reco_workflow+=";MFTTracking.MFTRadLength=0.084;$MAXBCDIFFTOMASKBIAS_MFT;$MAXBCDIFFTOSQUASHBIAS_MFT" fi # ad-hoc settings for MCH -if [[ $BEAMTYPE == "pp" ]]; then +if [[ $BEAMTYPE == "pp" || $LIGHTNUCLEI == "1" ]]; then export CONFIG_EXTRA_PROCESS_o2_mch_reco_workflow+=";MCHTracking.chamberResolutionX=0.4;MCHTracking.chamberResolutionY=0.4;MCHTracking.sigmaCutForTracking=7;MCHTracking.sigmaCutForImprovement=6" fi +# ad-hoc settings for MFT-MCH matching +# Number of MFT-MCH matching candidates to be stored in AO2Ds +# Setting MUON_MATCHING_NCANDIDATES=0 disables the storage of multiple candidates +if [[ -z "${MUON_MATCHING_NCANDIDATES:-}" ]]; then + MUON_MATCHING_NCANDIDATES=0 # disable the saving of nCandidated by default + if [[ $BEAMTYPE == "pp" || $LIGHTNUCLEI == "1" ]]; then MUON_MATCHING_NCANDIDATES=5; fi + if [[ $BEAMTYPE == "PbPb" ]]; then MUON_MATCHING_NCANDIDATES=20; fi +fi +if [[ "x${MUON_MATCHING_NCANDIDATES}" != "x0" ]]; then + export CONFIG_EXTRA_PROCESS_o2_globalfwd_matcher_workflow+=";FwdMatching.saveMode=3;FwdMatching.nCandidates=${MUON_MATCHING_NCANDIDATES};" +fi + + # possibly adding calib steps as done online # could be done better, so that more could be enabled in one go if [[ $ADD_CALIB == "1" ]]; then @@ -611,16 +724,21 @@ if [[ $ADD_CALIB == "1" ]]; then export CALIB_TOF_INTEGRATEDCURR=0 export CALIB_ITS_DEADMAP_TIME=0 export CALIB_MFT_DEADMAP_TIME=0 - if [[ $DO_TPC_RESIDUAL_EXTRACTION == "1" ]]; then + if [[ -n "$DO_TPC_RESIDUAL_EXTRACTION" && $DO_TPC_RESIDUAL_EXTRACTION != "0" ]]; then + : ${ALIEN_JDL_TPCRESIDUALTRKSOURCESMAPEXTRACTION:="ITS-TPC"} + : ${ALIEN_JDL_TPCRESIDUALMAXTRACKSPERSLOT:=-1} + : ${ALIEN_JDL_TPCRESIDUALADDTRACKSMAP:=35000000} export CALIB_TPC_SCDCALIB=1 export CALIB_TPC_SCDCALIB_SENDTRKDATA=1 - export CONFIG_EXTRA_PROCESS_o2_tpc_scdcalib_interpolation_workflow+=";scdcalib.additionalTracksMap=35000000;scdcalib.minPtNoOuterPoint=0.2;scdcalib.maxQ2Pt=5;scdcalib.minITSNClsNoOuterPoint=6;scdcalib.minITSNCls=4;scdcalib.minTPCNClsNoOuterPoint=90;scdcalib.minTOFTRDPVContributors=2" - export ARGS_EXTRA_PROCESS_o2_tpc_scdcalib_interpolation_workflow+=" --tracking-sources-map-extraction ITS-TPC" - # ad-hoc settings for TPC residual extraction - export ARGS_EXTRA_PROCESS_o2_calibration_residual_aggregator+=" --output-type trackParams,unbinnedResid" - if [[ $ALIEN_JDL_DEBUGRESIDUALEXTRACTION == "1" ]]; then - export CONFIG_EXTRA_PROCESS_o2_tpc_scdcalib_interpolation_workflow+=";scdcalib.maxTracksPerCalibSlot=-1;scdcalib.minPtNoOuterPoint=0.8;scdcalib.minTPCNClsNoOuterPoint=120" - export ARGS_EXTRA_PROCESS_o2_trd_global_tracking+=" --enable-qc" + export CONFIG_EXTRA_PROCESS_o2_tpc_scdcalib_interpolation_workflow+=";scdcalib.maxTracksPerCalibSlot=$ALIEN_JDL_TPCRESIDUALMAXTRACKSPERSLOT;scdcalib.additionalTracksMap=$ALIEN_JDL_TPCRESIDUALADDTRACKSMAP;scdcalib.minPtNoOuterPoint=0.2;scdcalib.maxQ2Pt=5;scdcalib.minITSNClsNoOuterPoint=6;scdcalib.minITSNCls=4;scdcalib.minTPCNClsNoOuterPoint=50;scdcalib.minTOFTRDPVContributors=2" + export ARGS_EXTRA_PROCESS_o2_tpc_scdcalib_interpolation_workflow+=" --tracking-sources-map-extraction $ALIEN_JDL_TPCRESIDUALTRKSOURCESMAPEXTRACTION" + if [[ ! $DO_TPC_RESIDUAL_EXTRACTION =~ "NOEXTCLROAD" ]]; then + clusterErrors=";GPU_rec_tpc.clusterError2AdditionalY=0.3;GPU_rec_tpc.clusterError2AdditionalZ=0.3" + + export CONFIG_EXTRA_PROCESS_o2_gpu_reco_workflow+=";$clusterErrors" + export CONFIG_EXTRA_PROCESS_o2_tpcits_match_workflow+=";$clusterErrors" + export CONFIG_EXTRA_PROCESS_o2_tof_matcher_workflow+=";$clusterErrors" + export CONFIG_EXTRA_PROCESS_o2_trd_global_tracking+=";$clusterErrors" fi fi export CALIB_EMC_ASYNC_RECALIB="$ALIEN_JDL_DOEMCCALIB" @@ -666,6 +784,16 @@ if [[ $ADD_CALIB == "1" ]]; then if [[ $ALIEN_JDL_DOUPLOADSLOCALLY == 1 ]]; then export CCDB_POPULATOR_UPLOAD_PATH="file://$PWD" fi + + # enable time gain calibration + if [[ $ALIEN_JDL_DOTPCTIMEGAINCALIB == 1 ]]; then + echo "Enabling TPC time gain calibration" + export CALIB_TPC_TIMEGAIN=1 + export ARGS_EXTRA_PROCESS_o2_tpc_calibrator_dedx+=" --dump-histograms 1 --min-entries 1" # write full calibration objects for time gain without rejecting low statistics timeslots + export ARGS_EXTRA_PROCESS_o2_tpc_miptrack_filter+=" --use-global-tracks" + export SCALEEVENTS_TPC_TIMEGAIN=${SCALEEVENTS_TPC_TIMEGAIN:-1} # use all TFs + export SCALETRACKS_TPC_TIMEGAIN=${SCALETRACKS_TPC_TIMEGAIN:--1} # use all tracks + fi fi # Enabling AOD @@ -708,6 +836,15 @@ if [[ $ALIEN_JDL_THINAODS == "1" ]] ; then export ARGS_EXTRA_PROCESS_o2_aod_producer_workflow+=" --thin-tracks" fi +if [[ $ALIEN_JDL_PREPROPAGATE == "1" ]] ; then + export ARGS_EXTRA_PROCESS_o2_aod_producer_workflow+=" --propagate-tracks --propagate-tracks-max-xiu 5" +fi + +# possibility to bias the MeanVertex from the CCDB, see https://github.com/AliceO2Group/AliceO2/pull/15549 +if [[ -n $ALIEN_JDL_MVBIAS ]]; then + export O2_DPL_MVBIAS=$ALIEN_JDL_MVBIAS +fi + # Enabling QC if [[ $ALIEN_JDL_QCOFF != "1" ]]; then export WORKFLOW_PARAMETERS="QC,${WORKFLOW_PARAMETERS}" diff --git a/DATA/production/o2dpg_qc_postproc_workflow.py b/DATA/production/o2dpg_qc_postproc_workflow.py index 679f51777..0c7402936 100755 --- a/DATA/production/o2dpg_qc_postproc_workflow.py +++ b/DATA/production/o2dpg_qc_postproc_workflow.py @@ -78,7 +78,7 @@ def add_QC_postprocessing(taskName, qcConfigPath, needs, runSpecific, periodSpec stages.append(task) ## The list of QC Post-processing workflows, add the new ones below - add_QC_postprocessing('example', 'json://${O2DPG_ROOT}/DATA/production/qc-postproc-async/example.json', needs=[], runSpecific=False, periodSpecific=False, passSpecific=True) + add_QC_postprocessing('example', 'json://${O2DPG_ROOT}/DATA/production/qc-postproc-async/example.json', needs=[], runSpecific=False, periodSpecific=True, passSpecific=True) add_QC_postprocessing('EMC', 'json://${O2DPG_ROOT}/DATA/production/qc-postproc-async/emc.json', needs=[], runSpecific=False, periodSpecific=True, passSpecific=True) add_QC_postprocessing('MCH', 'json://${O2DPG_ROOT}/DATA/production/qc-postproc-async/mch.json', needs=[], runSpecific=True, periodSpecific=True, passSpecific=True) add_QC_postprocessing('ZDC', 'json://${O2DPG_ROOT}/DATA/production/qc-postproc-async/zdc.json', needs=[], runSpecific=True, periodSpecific=True, passSpecific=True) diff --git a/DATA/production/production.desc b/DATA/production/production.desc index 509adf585..0691ccdeb 100644 --- a/DATA/production/production.desc +++ b/DATA/production/production.desc @@ -1,3 +1,3 @@ synchronous-workflow: "O2PDPSuite" reco,128,126,"GPU_NUM_MEM_REG_CALLBACKS=5 SYNCMODE=1 NUMAGPUIDS=1 NUMAID=0 production/dpl-workflow.sh" reco,128,126,"GPU_NUM_MEM_REG_CALLBACKS=5 SYNCMODE=1 NUMAGPUIDS=1 NUMAID=1 production/dpl-workflow.sh" synchronous-workflow-1numa: "O2PDPSuite" reco,128,126,"SYNCMODE=1 production/dpl-workflow.sh" -synchronous-workflow-calib: "O2PDPSuite" reco,128,126,"GPU_NUM_MEM_REG_CALLBACKS=5 SYNCMODE=1 NUMAGPUIDS=1 NUMAID=0 WORKFLOW_PARAMETERS+=,CALIB_PROXIES production/dpl-workflow.sh" reco,128,126,"GPU_NUM_MEM_REG_CALLBACKS=5 SYNCMODE=1 NUMAGPUIDS=1 NUMAID=1 WORKFLOW_PARAMETERS+=,CALIB_PROXIES production/dpl-workflow.sh" calib,32,"AGGREGATOR_TASKS=BARREL_TF SYNCMODE=1 SHMSIZE=68719476736 WORKFLOW_PARAMETERS+=,CALIB_PROXIES production/aggregator-workflow.sh" calib,32,"AGGREGATOR_TASKS=BARREL_SPORADIC SYNCMODE=1 SHMSIZE=68719476736 WORKFLOW_PARAMETERS+=,CALIB_PROXIES production/aggregator-workflow.sh" calib,16,"AGGREGATOR_TASKS=CALO_TF SYNCMODE=1 SHMSIZE=34359738368 WORKFLOW_PARAMETERS+=,CALIB_PROXIES production/aggregator-workflow.sh" calib,16,"AGGREGATOR_TASKS=CALO_SPORADIC SYNCMODE=1 SHMSIZE=34359738368 WORKFLOW_PARAMETERS+=,CALIB_PROXIES production/aggregator-workflow.sh" calib,16,"AGGREGATOR_TASKS=MUON_TF SYNCMODE=1 SHMSIZE=34359738368 WORKFLOW_PARAMETERS+=,CALIB_PROXIES production/aggregator-workflow.sh" calib,16,"AGGREGATOR_TASKS=MUON_SPORADIC SYNCMODE=1 SHMSIZE=34359738368 WORKFLOW_PARAMETERS+=,CALIB_PROXIES production/aggregator-workflow.sh" calib,16,"AGGREGATOR_TASKS=FORWARD_TF SYNCMODE=1 SHMSIZE=34359738368 WORKFLOW_PARAMETERS+=,CALIB_PROXIES production/aggregator-workflow.sh" calib,16,"AGGREGATOR_TASKS=FORWARD_SPORADIC SYNCMODE=1 SHMSIZE=34359738368 WORKFLOW_PARAMETERS+=,CALIB_PROXIES production/aggregator-workflow.sh" calib,128,"AGGREGATOR_TASKS=TPC_IDCBOTH_SAC SHMSIZE=137438953472 WORKFLOW_PARAMETERS+=,CALIB_PROXIES production/aggregator-workflow.sh" +synchronous-workflow-calib: "O2PDPSuite" reco,128,126,"GPU_NUM_MEM_REG_CALLBACKS=5 SYNCMODE=1 NUMAGPUIDS=1 NUMAID=0 WORKFLOW_PARAMETERS+=,CALIB_PROXIES production/dpl-workflow.sh" reco,128,126,"GPU_NUM_MEM_REG_CALLBACKS=5 SYNCMODE=1 NUMAGPUIDS=1 NUMAID=1 WORKFLOW_PARAMETERS+=,CALIB_PROXIES production/dpl-workflow.sh" calib,32,"AGGREGATOR_TASKS=BARREL_TF SYNCMODE=1 SHMSIZE=68719476736 WORKFLOW_PARAMETERS+=,CALIB_PROXIES production/aggregator-workflow.sh" calib,32,"AGGREGATOR_TASKS=BARREL_SPORADIC SYNCMODE=1 SHMSIZE=68719476736 WORKFLOW_PARAMETERS+=,CALIB_PROXIES production/aggregator-workflow.sh" calib,16,"AGGREGATOR_TASKS=CALO_TF SYNCMODE=1 SHMSIZE=34359738368 WORKFLOW_PARAMETERS+=,CALIB_PROXIES production/aggregator-workflow.sh" calib,16,"AGGREGATOR_TASKS=CALO_SPORADIC SYNCMODE=1 SHMSIZE=34359738368 WORKFLOW_PARAMETERS+=,CALIB_PROXIES production/aggregator-workflow.sh" calib,16,"AGGREGATOR_TASKS=MUON_TF SYNCMODE=1 SHMSIZE=34359738368 WORKFLOW_PARAMETERS+=,CALIB_PROXIES production/aggregator-workflow.sh" calib,16,"AGGREGATOR_TASKS=MUON_SPORADIC SYNCMODE=1 SHMSIZE=34359738368 WORKFLOW_PARAMETERS+=,CALIB_PROXIES production/aggregator-workflow.sh" calib,16,"AGGREGATOR_TASKS=FORWARD_TF SYNCMODE=1 SHMSIZE=34359738368 WORKFLOW_PARAMETERS+=,CALIB_PROXIES production/aggregator-workflow.sh" calib,16,"AGGREGATOR_TASKS=FORWARD_SPORADIC SYNCMODE=1 SHMSIZE=34359738368 WORKFLOW_PARAMETERS+=,CALIB_PROXIES production/aggregator-workflow.sh" calib,128,"AGGREGATOR_TASKS=TPC_IDCBOTH_SAC SHMSIZE=137438953472 WORKFLOW_PARAMETERS+=,CALIB_PROXIES production/aggregator-workflow.sh" calib,128,"AGGREGATOR_TASKS=TPC_CMV SHMSIZE=137438953472 WORKFLOW_PARAMETERS+=,CALIB_PROXIES production/aggregator-workflow.sh" diff --git a/DATA/production/qc-async/ft0.json b/DATA/production/qc-async/ft0.json index efb6516ab..f06d73d1c 100644 --- a/DATA/production/qc-async/ft0.json +++ b/DATA/production/qc-async/ft0.json @@ -35,7 +35,17 @@ "type": "direct", "query": "recpoints:FT0/RECPOINTS/0;channels:FT0/RECCHDATA/0" }, - "saveObjectsToFile":"QC_FT0.root" + "saveObjectsToFile":"QC_FT0.root", + "grpGeomRequest" : { + "geomRequest": "None", + "askGRPECS": "false", + "askGRPLHCIF": "true", + "askGRPMagField": "false", + "askMatLUT": "false", + "askTime": "false", + "askOnceAllButField": "false", + "needPropagatorD": "false" + } } } } diff --git a/DATA/production/qc-async/itstpc.json b/DATA/production/qc-async/itstpc.json index a4b02689a..d0ca44d88 100644 --- a/DATA/production/qc-async/itstpc.json +++ b/DATA/production/qc-async/itstpc.json @@ -39,12 +39,12 @@ "dataSource" : { "type" : "direct", "query_comment" : "checking every matched track", - "query" : "trackITSTPC:GLO/TPCITS/0;trackITSTPCABREFS:GLO/TPCITSAB_REFS/0;trackITSTPCABCLID:GLO/TPCITSAB_CLID/0;trackTPC:TPC/TRACKS;trackTPCClRefs:TPC/CLUSREFS;trackITS:ITS/TRACKS/0;trackITSROF:ITS/ITSTrackROF/0;trackITSClIdx:ITS/TRACKCLSID/0;alpparITS:ITS/ALPIDEPARAM/0?lifetime=condition&ccdb-path=ITS/Config/AlpideParam;SVParam:GLO/SVPARAM/0?lifetime=condition&ccdb-path=GLO/Config/SVertexerParam;p2decay3body:GLO/PVTX_3BODYREFS/0;decay3body:GLO/DECAYS3BODY/0;decay3bodyIdx:GLO/DECAYS3BODY_IDX/0;p2cascs:GLO/PVTX_CASCREFS/0;cascs:GLO/CASCS/0;cascsIdx:GLO/CASCS_IDX/0;p2v0s:GLO/PVTX_V0REFS/0;v0s:GLO/V0S/0;v0sIdx:GLO/V0S_IDX/0;pvtx_tref:GLO/PVTX_TRMTCREFS/0;pvtx_trmtc:GLO/PVTX_TRMTC/0;pvtx:GLO/PVTX/0;SVParam:GLO/SVPARAM/0?lifetime=condition&ccdb-path=GLO/Config/SVertexerParam;clusTPCoccmap:TPC/TPCOCCUPANCYMAP/0;clusTPC:TPC/CLUSTERNATIVE;clusTPCshmap:TPC/CLSHAREDMAP/0;trigTPC:TPC/TRIGGERWORDS/0;trigITSTPCTRD:TRD/TRGREC_ITSTPC/0;trackITSTPCTRD:TRD/MATCH_ITSTPC/0;matchITSTPCTOF:TOF/MTC_ITSTPC/0;matchITSTPCTRDTOF:TOF/MTC_ITSTPCTRD/0;trigTPCTRD:TRD/TRGREC_TPC/0;trackTPCTRD:TRD/MATCH_TPC/0;matchTPCTOF:TOF/MTC_TPC/0;trackTPCTOF:TOF/TOFTRACKS_TPC/0;matchTPCTRDTOF/TOF/MTC_TPCTRD/0;tofcluster:TOF/CLUSTERS/0" + "query" : "" }, "taskParameters" : { "GID" : "ITS-TPC,ITS", "verbose" : "false", - "minPtITSCut": "0.f", + "minPtITSCut": "0.1f", "etaITSCut": "1e10f", "minNITSClustersCut": "0", "maxChi2PerClusterITS": "100000", @@ -53,13 +53,13 @@ "minNTPCClustersCut": "60", "minDCACut": "100.f", "minDCACutY": "10.f", - "minPtCut": "0.f", - "maxPtCut": "1e10f", + "minPtCut": "0.1f", + "maxPtCut": "20.f", "etaCut": "1e10f", "cutK0Mass": "0.05f", "maxEtaK0": "0.8f", "doK0QC": "true", - "trackSourcesK0": "ITS,TPC,ITS-TPC,ITS-TPC-TOF,TPC-TOF,TPC-TRD,ITS-TPC-TRD,TPC-TRD-TOF,ITS-TPC-TOF,ITS-TPC-TRD-TOF" + "trackSourcesK0": "" }, "grpGeomRequest" : { "geomRequest": "None", diff --git a/DATA/production/qc-async/mch-digits.json b/DATA/production/qc-async/mch-digits.json index cf3594bc5..4b867fce6 100644 --- a/DATA/production/qc-async/mch-digits.json +++ b/DATA/production/qc-async/mch-digits.json @@ -36,7 +36,12 @@ "type": "direct", "query": "digits:MCH/DIGITS" }, + "movingWindows": [ + "RateSignalPerDualSampa" + ], "taskParameters": { + "Enable1DRateMaps": "true", + "Enable2DRateMaps": "false", "Diagnostic": "false" }, "grpGeomRequest": { diff --git a/DATA/production/qc-async/mch-reco.json b/DATA/production/qc-async/mch-reco.json index 55a18d32f..0fec68d6b 100644 --- a/DATA/production/qc-async/mch-reco.json +++ b/DATA/production/qc-async/mch-reco.json @@ -49,6 +49,13 @@ "dataSource": { "type": "direct", "query": "preclusters:MCH/PRECLUSTERS/0;preclusterdigits:MCH/PRECLUSTERDIGITS/0" + }, + "movingWindows": [ + "PseudoeffPerDualSampa" + ], + "taskParameters": { + "Enable1DPseudoeffMaps": "true", + "Enable2DPseudoeffMaps": "false" } }, "FRofs": { @@ -68,4 +75,4 @@ } } } -} \ No newline at end of file +} diff --git a/DATA/production/qc-async/mchmid-tracks.json b/DATA/production/qc-async/mchmid-tracks.json index ebd6843d1..f87a75ce4 100644 --- a/DATA/production/qc-async/mchmid-tracks.json +++ b/DATA/production/qc-async/mchmid-tracks.json @@ -11,7 +11,7 @@ "maxNumberCycles": "-1", "dataSource": { "type": "direct", - "query": "trackMCH:MCH/TRACKS;trackMCHROF:MCH/TRACKROFS;trackMCHTRACKCLUSTERS:MCH/TRACKCLUSTERS;mchtrackdigits:MCH/CLUSTERDIGITS;trackMID:MID/TRACKS;trackMIDROF:MID/TRACKROFS;trackMIDTRACKCLUSTERS:MID/TRACKCLUSTERS;trackClMIDROF:MID/TRCLUSROFS;matchMCHMID:GLO/MTC_MCHMID" + "query": "trackMCH:MCH/TRACKS;trackMCHROF:MCH/TRACKROFS;trackMCHTRACKCLUSTERS:MCH/TRACKCLUSTERS;mchtrackdigits:MCH/CLUSTERDIGITS;trackMID:MID/TRACKS/0;trackMIDROF:MID/TRACKROFS/0;trackMIDTRACKCLUSTERS:MID/TRACKCLUSTERS/0;trackClMIDROF:MID/TRCLUSROFS/0;matchMCHMID:GLO/MTC_MCHMID" }, "movingWindows": [ "WithCuts/TracksPerTF", diff --git a/DATA/production/qc-async/mftmchmid-tracks.json b/DATA/production/qc-async/mftmchmid-tracks.json index b2cebb8d0..2b892e070 100644 --- a/DATA/production/qc-async/mftmchmid-tracks.json +++ b/DATA/production/qc-async/mftmchmid-tracks.json @@ -11,7 +11,9 @@ "maxNumberCycles": "-1", "dataSource": { "type": "direct", - "query": "trackMCH:MCH/TRACKS;trackMCHROF:MCH/TRACKROFS;trackMCHTRACKCLUSTERS:MCH/TRACKCLUSTERS;mchtrackdigits:MCH/CLUSTERDIGITS;trackMFT:MFT/TRACKS;trackMFTROF:MFT/MFTTrackROF;trackMFTClIdx:MFT/TRACKCLSID;alpparMFT:MFT/ALPIDEPARAM/0?lifetime=condition&ccdb-path=MFT/Config/AlpideParam;fwdtracks:GLO/GLFWD;trackMID:MID/TRACKS;trackMIDROF:MID/TRACKROFS;trackMIDTRACKCLUSTERS:MID/TRACKCLUSTERS;trackClMIDROF:MID/TRCLUSROFS;matchMCHMID:GLO/MTC_MCHMID" + "_type": "dataSamplingPolicy", + "name": "muon-tracks", + "query": "trackMCH:MCH/TRACKS;trackMCHROF:MCH/TRACKROFS;trackMCHTRACKCLUSTERS:MCH/TRACKCLUSTERS;mchtrackdigits:MCH/CLUSTERDIGITS;trackMFT:MFT/TRACKS;trackMFTROF:MFT/MFTTrackROF;trackMFTClIdx:MFT/TRACKCLSID;alpparMFT:MFT/ALPIDEPARAM/0?lifetime=condition&ccdb-path=MFT/Config/AlpideParam;fwdtracks:GLO/GLFWD;trackMID:MID/TRACKS/0;trackMIDROF:MID/TRACKROFS/0;trackMIDTRACKCLUSTERS:MID/TRACKCLUSTERS/0;trackClMIDROF:MID/TRCLUSROFS/0;matchMCHMID:GLO/MTC_MCHMID" }, "movingWindows": [ "WithCuts/TracksPerTF", @@ -59,15 +61,12 @@ "cycleDurationSeconds": "300", "maxNumberCycles": "-1", "dataSource": { - "type": "direct", - "query": "trackMCH:MCH/TRACKS;trackMCHROF:MCH/TRACKROFS;trackMCHTRACKCLUSTERS:MCH/TRACKCLUSTERS;mchtrackdigits:MCH/CLUSTERDIGITS;trackMFT:MFT/TRACKS;trackMFTROF:MFT/MFTTrackROF;trackMFTClIdx:MFT/TRACKCLSID;alpparMFT:MFT/ALPIDEPARAM/0?lifetime=condition&ccdb-path=MFT/Config/AlpideParam;fwdtracks:GLO/GLFWD;trackMID:MID/TRACKS;trackMIDROF:MID/TRACKROFS;trackMIDTRACKCLUSTERS:MID/TRACKCLUSTERS;trackClMIDROF:MID/TRCLUSROFS;matchMCHMID:GLO/MTC_MCHMID" + "_type": "direct", + "type": "dataSamplingPolicy", + "name": "glo-mu-tracks", + "query": "trackMCH:MCH/TRACKS;trackMCHROF:MCH/TRACKROFS;trackMCHTRACKCLUSTERS:MCH/TRACKCLUSTERS;mchtrackdigits:MCH/CLUSTERDIGITS;trackMFT:MFT/TRACKS;trackMFTROF:MFT/MFTTrackROF;trackMFTClIdx:MFT/TRACKCLSID;alpparMFT:MFT/ALPIDEPARAM/0?lifetime=condition&ccdb-path=MFT/Config/AlpideParam;fwdtracks:GLO/GLFWD;trackMID:MID/TRACKS/0;trackMIDROF:MID/TRACKROFS/0;trackMIDTRACKCLUSTERS:MID/TRACKCLUSTERS/0;trackClMIDROF:MID/TRCLUSROFS/0;matchMCHMID:GLO/MTC_MCHMID" }, "movingWindows": [ - "MFT-MCH/WithCuts/TracksPerTF", - "MFT-MCH/WithCuts/TrackPt", - "MFT-MCH/WithCuts/TrackEta", - "MFT-MCH/WithCuts/TrackPhi", - "MFT-MCH/WithCuts/Minv", "MCH-MID/WithCuts/TracksPerTF", "MCH-MID/WithCuts/TrackPt", "MCH-MID/WithCuts/TrackEta", @@ -91,7 +90,7 @@ "matchChi2MaxMFT": "45", "diMuonTimeCut": "100", "fullHistos": "0", - "GID" : "MCH,MFT-MCH,MCH-MID,MFT-MCH-MID" + "GID" : "MCH-MID,MFT-MCH-MID" }, "grpGeomRequest": { "geomRequest": "Aligned", @@ -106,5 +105,35 @@ "location": "remote" } } - } + }, + "dataSamplingPolicies": [ + { + "id": "muon-tracks", + "active": "true", + "machines": [], + "query": "trackMCH:MCH/TRACKS;trackMCHROF:MCH/TRACKROFS;trackMCHTRACKCLUSTERS:MCH/TRACKCLUSTERS;mchtrackdigits:MCH/CLUSTERDIGITS;trackMFT:MFT/TRACKS;trackMFTROF:MFT/MFTTrackROF;trackMFTClIdx:MFT/TRACKCLSID;alpparMFT:MFT/ALPIDEPARAM/0?lifetime=condition&ccdb-path=MFT/Config/AlpideParam;fwdtracks:GLO/GLFWD;trackMID:MID/TRACKS/0;trackMIDROF:MID/TRACKROFS/0;trackMIDTRACKCLUSTERS:MID/TRACKCLUSTERS/0;trackClMIDROF:MID/TRCLUSROFS/0;matchMCHMID:GLO/MTC_MCHMID", + "samplingConditions": [ + { + "condition": "random", + "fraction": "0.1", + "seed": "0" + } + ], + "blocking": "false" + }, + { + "id": "glo-mu-tracks", + "active": "true", + "machines": [], + "query": "trackMCH:MCH/TRACKS;trackMCHROF:MCH/TRACKROFS;trackMCHTRACKCLUSTERS:MCH/TRACKCLUSTERS;mchtrackdigits:MCH/CLUSTERDIGITS;trackMFT:MFT/TRACKS;trackMFTROF:MFT/MFTTrackROF;trackMFTClIdx:MFT/TRACKCLSID;alpparMFT:MFT/ALPIDEPARAM/0?lifetime=condition&ccdb-path=MFT/Config/AlpideParam;fwdtracks:GLO/GLFWD;trackMID:MID/TRACKS/0;trackMIDROF:MID/TRACKROFS/0;trackMIDTRACKCLUSTERS:MID/TRACKCLUSTERS/0;trackClMIDROF:MID/TRCLUSROFS/0;matchMCHMID:GLO/MTC_MCHMID", + "samplingConditions": [ + { + "condition": "random", + "fraction": "0.1", + "seed": "0" + } + ], + "blocking": "false" + } + ] } diff --git a/DATA/production/qc-async/mid.json b/DATA/production/qc-async/mid.json index 4f49f2ce9..2007b84bd 100644 --- a/DATA/production/qc-async/mid.json +++ b/DATA/production/qc-async/mid.json @@ -3,10 +3,9 @@ "config": { "database": { "implementation": "CCDB", - "host": "ccdb-test.cern.ch:8080" - }, - "Activity": { + "host": "ccdb-test.cern.ch:8080" }, + "Activity": {}, "monitoring": { "url": "infologger:///debug?qc" }, @@ -25,9 +24,25 @@ "moduleName": "QcMID", "detectorName": "MID", "cycleDurationSeconds": "60", + "movingWindows": [ "mLocalBoardsMap", "mLocalBoardsMap11","mLocalBoardsMap12","mLocalBoardsMap21","mLocalBoardsMap22", + "BendHitsMap11", "BendHitsMap12", "BendHitsMap21", "BendHitsMap22", + "NBendHitsMap11", "NBendHitsMap12", "NBendHitsMap21", "NBendHitsMap22" + ], "dataSource": { "type": "direct", - "query": "digits:MID/DATA;digits_rof:MID/DATAROF" + "query": "digits:MID/DATA/0;digits_rof:MID/DATAROF/0" + } + }, + "MIDFilteredDigits": { + "active": "true", + "taskName": "FilteredDigits", + "className": "o2::quality_control_modules::mid::DigitsQcTask", + "moduleName": "QcMID", + "detectorName": "MID", + "cycleDurationSeconds": "60", + "dataSource": { + "type": "direct", + "query": "digits:MID/FDATA/0;digits_rof:MID/FDATAROF/0" } }, "MIDClusters": { @@ -39,7 +54,7 @@ "cycleDurationSeconds": "60", "dataSource": { "type": "direct", - "query": "clusters:MID/TRACKCLUSTERS;clusterrofs:MID/TRCLUSROFS" + "query": "clusters:MID/TRACKCLUSTERS/0;clusterrofs:MID/TRCLUSROFS/0" } }, "MIDTracks": { @@ -51,7 +66,7 @@ "cycleDurationSeconds": "60", "dataSource": { "type": "direct", - "query": "tracks:MID/TRACKS;trackrofs:MID/TRACKROFS" + "query": "tracks:MID/TRACKS/0;trackrofs:MID/TRACKROFS/0" } } }, @@ -79,6 +94,29 @@ } ] }, + "MIDFilteredDigits": { + "active": "true", + "checkName": "FilteredDigits", + "className": "o2::quality_control_modules::mid::DigitsQcCheck", + "moduleName": "QcMID", + "detectorName": "MID", + "policy": "OnAny", + "checkParameters": { + "MeanMultThreshold": "100.", + "MinMultThreshold": "0.0", + "NbOrbitPerTF": "32.", + "LocalBoardScale": "200.0", + "LocalBoardThreshold": "800.0", + "NbBadLocalBoard": "10.", + "NbEmptyLocalBoard": "117." + }, + "dataSource": [ + { + "type": "Task", + "name": "MIDFilteredDigits" + } + ] + }, "MIDClusters": { "active": "true", "checkName": "Clusters", diff --git a/DATA/production/qc-async/tpc.json b/DATA/production/qc-async/tpc.json index 32548958e..f172cffe4 100644 --- a/DATA/production/qc-async/tpc.json +++ b/DATA/production/qc-async/tpc.json @@ -83,7 +83,7 @@ "query": "inputTracks:TPC/TRACKS/0;inputClusters:TPC/CLUSTERNATIVE;inputClusRefs:TPC/CLUSREFS/0" }, "taskParameters": { - "cutAbsEta": "1.", + "cutAbsEta": "1.5", "cutMinNCluster": "60", "cutMindEdxTot": "20.", "seed": "0", @@ -97,7 +97,7 @@ "moduleName": "QcTPC", "detectorName": "TPC", "cycleDurationSeconds": "300", - "movingWindows" : [ "h2DNClustersEta" ], + "movingWindows" : [ "h2DNClustersEta","hDCArVsEtaPos", "hDCArVsEtaNeg","hDCArVsEtaPos_pTmin","hDCArVsEtaNeg_pTmin" ], "dataSource": { "type": "dataSamplingPolicy", "name": "tpc-tracks", diff --git a/DATA/production/qc-async/zdc.json b/DATA/production/qc-async/zdc.json index 2f74fb164..5059a95c9 100644 --- a/DATA/production/qc-async/zdc.json +++ b/DATA/production/qc-async/zdc.json @@ -36,28 +36,29 @@ "query": "zdc-bcrec:ZDC/BCREC/0;zdc-energyrec:ZDC/ENERGY/0;zdc-tdcrec:ZDC/TDCDATA/0;zdc-inforec:ZDC/INFO/0" }, "taskParameters": { - "ADC": "3600; -3;357", + "ADC": "3025;-100;12000", "ADCZEM": "3025;-100;12000", - "ADCH": "2300;-3;20", + "ADCH": "3100;-100;3000", "TDCT": "2400;-13.5;11.45", - "TDCA": "3600; -3;357", + "TDCA": "2050;-0.5;4099.5", "TDCAZEM": "2050;-0.5;4099.5", - "TDCAH": "2300;-3;20", - "ADCSUMvsTC": "144;-3;357;144;-3;357", + "TDCAH": "1010;-10;1000", + "ADCSUMvsTC": "121;-100;12000;121;-100;12000", "ADCZEMvsADCZEM": "121;-100;12000;121;-100;12000", - "ADCZEMvsTC": "144;-3;357;121;-100;12000", - "ADCvsTDCT": "120;-13.5;11.45;144;-3;357", + "ADCZEMvsTC": "121;-100;12000;121;-100;12000", + "ADCvsTDCT": "120;-13.5;11.45;121;-100;12000", "ADCZEMvsTDCT": "120;-13.5;11.45;121;-100;12000", "TDCDIFF": "240;-27;22.90;240;-27;22.90", - "TDCAvsTDCT": "120;-13.5;11.45;144;-3;357", + "TDCAvsTDCT": "120;-13.5;11.45;125;-1;3999", "TDCAZEMvsTDCT": "120;-13.5;11.45;125;-1;3999", - "TDCAvsTDCA": "144;-3;357;144;-3;357", + "TDCAvsTDCA": "125;-1;3999;125;-1;3999", "TDCAZEMvsTDCAZEM": "125;-1;3999;125;-1;3999", - "TDCAZEMvsTDCA": "144;-3;357;125;-1;3999", + "TDCAZEMvsTDCA": "125;-1;3999;125;-1;3999", "CENTR_ZNA": "200;-2;2;200;-2;2", "CENTR_ZNC": "200;-2;2;200;-2;2", "CENTR_ZPA": "2240;0;22.4", - "CENTR_ZPC": "2240;-22.4;0" + "CENTR_ZPC": "2240;-22.4;0", + "CENTRAL_EVENT_CONFIG": "2.5;1" } } } diff --git a/DATA/production/qc-async/zdcPbPb.json b/DATA/production/qc-async/zdcPbPb.json index 1d1ae0577..0407e0d90 100644 --- a/DATA/production/qc-async/zdcPbPb.json +++ b/DATA/production/qc-async/zdcPbPb.json @@ -50,14 +50,15 @@ "ADCZEMvsTDCT": "120;-13.5;11.45;121;-100;12000", "TDCDIFF": "240;-27;22.90;240;-27;22.90", "TDCAvsTDCT": "120;-13.5;11.45;144;-3;357", - "TDCAZEMvsTDCT": ";125;-1;3999;120;-13.5;11.45", + "TDCAZEMvsTDCT": "120;-13.5;11.45;125;-1;3999", "TDCAvsTDCA": "144;-3;357;144;-3;357", "TDCAZEMvsTDCAZEM": "125;-1;3999;125;-1;3999", "TDCAZEMvsTDCA": "125;-1;3999;144;-3;357;", "CENTR_ZNA": "200;-2;2;200;-2;2", "CENTR_ZNC": "200;-2;2;200;-2;2", "CENTR_ZPA": "2240;0;22.4", - "CENTR_ZPC": "2240;-22.4;0" + "CENTR_ZPC": "2240;-22.4;0", + "CENTRAL_EVENT_CONFIG": "2.5;1" } } } diff --git a/DATA/production/qc-postproc-async/emc.json b/DATA/production/qc-postproc-async/emc.json index 9908bb047..6342060ae 100644 --- a/DATA/production/qc-postproc-async/emc.json +++ b/DATA/production/qc-postproc-async/emc.json @@ -496,7 +496,7 @@ "moduleName": "QualityControl", "detectorName": "EMC", "resumeTrend": "false", - "producePlotsOnUpdate": "true", + "producePlotsOnUpdate": "false", "dataSources": [ { "type": "repository", diff --git a/DATA/production/qc-postproc-async/zdc.json b/DATA/production/qc-postproc-async/zdc.json index a744a53d1..986d0bd28 100644 --- a/DATA/production/qc-postproc-async/zdc.json +++ b/DATA/production/qc-postproc-async/zdc.json @@ -87,6 +87,48 @@ ] } ], + "dataSourcesTDCA": [ + { + "type": "repository", + "path": "ZDC/MO/Rec", + "names": [ + "ZNAC:h_TDC_ZNA_TC_A", + "ZNAS:h_TDC_ZNA_SUM_A", + "ZPAC:h_TDC_ZPA_TC_A", + "ZPAS:h_TDC_ZPA_SUM_A", + "ZEM1:h_TDC_ZEM1_A", + "ZEM2:h_TDC_ZEM2_A", + "ZNCC:h_TDC_ZNC_TC_A", + "ZNCS:h_TDC_ZNC_SUM_A", + "ZPCC:h_TDC_ZPC_TC_A", + "ZPCS:h_TDC_ZPC_SUM_A" + ] + } + ], + "dataSourcesPeak1n": [ + { + "type": "repository", + "path": "ZDC/MO/Rec", + "names": [ + "ZNAC:h_TDC_ZNA_TC_A", + "ZNAS:h_TDC_ZNA_SUM_A", + "ZNCC:h_TDC_ZNC_TC_A", + "ZNCS:h_TDC_ZNC_SUM_A" + ] + } + ], + "dataSourcesPeak1p": [ + { + "type": "repository", + "path": "ZDC/MO/Rec", + "names": [ + "ZPAC:h_TDC_ZPA_TC_A", + "ZPAS:h_TDC_ZPA_SUM_A", + "ZPCC:h_TDC_ZPC_TC_A", + "ZPCS:h_TDC_ZPC_SUM_A" + ] + } + ], "initTrigger": [ "userorcontrol" ], @@ -117,7 +159,7 @@ { "name": "ZDCQuality/ZDCQuality", "title": "ZDC Quality", - "messageBad": "Inform on-call immediately", + "messageBad": "Bad histograms", "messageMedium": "Add bookkeeping entry", "messageGood": "All checks are OK", "messageNull": "Some histograms are empty!!!" @@ -156,53 +198,77 @@ "detectorName": "ZDC", "policy": "OnAny", "checkParameters": { - "ADC_ZNAC": "700;200;400", - "ADC_ZNA1": "260;100;200", - "ADC_ZNA2": "300;100;200", - "ADC_ZNA3": "170;100;200", - "ADC_ZNA4": "170;100;200", - "ADC_ZNAS": "700;200;400", - "ADC_ZPAC": "700;200;400", - "ADC_ZPA1": "60;50;100", - "ADC_ZPA2": "80;50;100", - "ADC_ZPA3": "245;50;100", - "ADC_ZPA4": "700;200;400", - "ADC_ZPAS": "850;200;400", - "ADC_ZEM1": "1230;200;400", - "ADC_ZEM2": "1275;200;400", - "ADC_ZNCC": "700;200;400", - "ADC_ZNC1": "130;100;200", - "ADC_ZNC2": "280;100;200", - "ADC_ZNC3": "130;100;200", - "ADC_ZNC4": "260;100;200", - "ADC_ZNCS": "600;200;400", - "ADC_ZPCC": "790;200;400", - "ADC_ZPC1": "770;200;400", - "ADC_ZPC2": "350;100;200", - "ADC_ZPC3": "97;50;100", - "ADC_ZPC4": "67;50;67", - "ADC_ZPCS": "1044;200;400", - "ADC_POS_MSG_X": "0.15", - "ADC_POS_MSG_Y": "0.92", - "TDC_ZNAC": "0.0;2.0;4.0", - "TDC_ZNAS": "0.0;2.0;4.0", - "TDC_ZPAC": "0.0;2.0;4.0", - "TDC_ZPAS": "0.0;2.0;4.0", - "TDC_ZEM1": "0.0;2.0;4.0", - "TDC_ZEM2": "0.0;2.0;4.0", - "TDC_ZNCC": "0.0;2.0;4.0", - "TDC_ZNCS": "0.0;2.0;4.0", - "TDC_ZPCC": "0.0;2.0;4.0", - "TDC_ZPCS": "0.0;2.0;4.0", - "TDC_POS_MSG_X": "0.01", - "TDC_POS_MSG_Y": "0.92" + "ADC_ZNAC" : "40.2;10;20", + "ADC_ZNA1" : "10.6;1000;2000", + "ADC_ZNA2" : "11.8;1000;2000", + "ADC_ZNA3" : "8.6;1000;2000", + "ADC_ZNA4" : "6.9;1000;2000", + "ADC_ZNAS" : "41.7;1000;2000", + "ADC_ZPAC" : "17.7;1000;2000", + "ADC_ZPA1" : "1.63;1000;2000", + "ADC_ZPA2" : "2.86;1000;2000", + "ADC_ZPA3" : "5.30;1000;2000", + "ADC_ZPA4" : "12.25;1000;2000", + "ADC_ZPAS" : "20.2;1000;2000", + "ADC_ZEM1" : "803.2;1000;2000", + "ADC_ZEM2" : "891.2;1000;2000", + "ADC_ZNCC" : "40.7;1000;2000", + "ADC_ZNC1" : "9.7;1000;2000", + "ADC_ZNC2" : "15.8;1000;2000", + "ADC_ZNC3" : "6.2;1000;2000", + "ADC_ZNC4" : "8.6;1000;2000", + "ADC_ZNCS" : "42.3;1000;2000", + "ADC_ZPCC" : "19.6;1000;2000", + "ADC_ZPC1" : "14.19;1000;2000", + "ADC_ZPC2" : "7.63;1000;2000", + "ADC_ZPC3" : "2.96;1000;2000", + "ADC_ZPC4" : "1.21;1000;2000", + "ADC_ZPCS" : "20.9;1000;2000", + "ADC_POS_MSG_X": "0.15", + "ADC_POS_MSG_Y": "0.92", + "TDC_ZNAC" : "0.14;1000;2000", + "TDC_ZNAS" : "0.05;1000;2000", + "TDC_ZPAC" : "-0.39;1000;2000", + "TDC_ZPAS" : "-0.11;1000;2000", + "TDC_ZEM1" : "0.07;1000;2000", + "TDC_ZEM2" : "0.02;1000;2000", + "TDC_ZNCC" : "0.19;1000;2000", + "TDC_ZNCS" : "0.08;1000;2000", + "TDC_ZPCC" : "-0.29;1000;2000", + "TDC_ZPCS" : "-0.20;1000;2000", + "TDC_POS_MSG_X": "0.01", + "TDC_POS_MSG_Y": "0.92", + "TDCA_ZNAC" : "326;1000;2000", + "TDCA_ZNAS" : "331;1000;2000", + "TDCA_ZPAC" : "130;1000;2000", + "TDCA_ZPAS" : "146;1000;2000", + "TDCA_ZEM1" : "1203;1000;2000", + "TDCA_ZEM2" : "1265;1000;2000", + "TDCA_ZNCC" : "329;1000;2000", + "TDCA_ZNCS" : "339;1000;2000", + "TDCA_ZPCC" : "146;1000;2000", + "TDCA_ZPCS" : "150;1000;2000", + "TDCA_POS_MSG_X": "0.01", + "TDCA_POS_MSG_Y": "0.92", + "PEAK1N_ZNAC" : "40;1000;2000", + "PEAK1N_ZNAS" : "40;1000;2000", + "PEAK1N_ZNCC" : "40;1000;2000", + "PEAK1N_ZNCS" : "40;1000;2000", + "PEAK1N_POS_MSG_X": "0.01", + "PEAK1N_POS_MSG_Y": "0.92", + "PEAK1P_ZPAC" : "52;1000;2000", + "PEAK1P_ZPAS" : "52;1000;2000", + "PEAK1P_ZPCC" : "52;1000;2000", + "PEAK1P_ZPCS" : "52;1000;2000", + "PEAK1P_POS_MSG_X": "0.01", + "PEAK1P_POS_MSG_Y": "0.92" }, "dataSource": [ { "type": "PostProcessing", "name": "RecPP", "MOs": [ - "h_summary_ADC", "h_summary_TDC" + "h_summary_ADC" , "h_summary_TDC", "h_summary_TDCA", "h_summary_Peak1n", "h_summary_Peak1p" ] } ] diff --git a/DATA/production/qc-sync/glo-itstpc-mtch-qcmn-epn.json b/DATA/production/qc-sync/glo-itstpc-mtch-qcmn-epn.json index a28ae70f3..36aee3ed9 100644 --- a/DATA/production/qc-sync/glo-itstpc-mtch-qcmn-epn.json +++ b/DATA/production/qc-sync/glo-itstpc-mtch-qcmn-epn.json @@ -37,7 +37,7 @@ "taskParameters" : { "GID": "ITS-TPC,ITS", "verbose": "false", - "minPtITSCut": "0.f", + "minPtITSCut": "0.1f", "etaITSCut": "1e10f", "minNITSClustersCut": "0", "maxChi2PerClusterITS": "100000", @@ -46,8 +46,8 @@ "minNTPCClustersCut": "60", "minDCACut": "100.f", "minDCACutY": "10.f", - "minPtCut": "0.f", - "maxPtCut": "1e10f", + "minPtCut": "0.1f", + "maxPtCut": "20.f", "etaCut": "1e10f", "cutK0Mass": "0.05f", "maxEtaK0": "0.8f", @@ -56,8 +56,8 @@ }, "grpGeomRequest" : { "geomRequest": "None", - "askGRPECS": "false", - "askGRPLHCIF": "false", + "askGRPECS": "true", + "askGRPLHCIF": "true", "askGRPMagField": "true", "askMatLUT": "false", "askTime": "false", diff --git a/DATA/production/qc-sync/glo-mchmid-mtch-qcmn-epn.json b/DATA/production/qc-sync/glo-mchmid-mtch-qcmn-epn.json index 74d113268..d34062b50 100644 --- a/DATA/production/qc-sync/glo-mchmid-mtch-qcmn-epn.json +++ b/DATA/production/qc-sync/glo-mchmid-mtch-qcmn-epn.json @@ -33,7 +33,7 @@ "disableLastCycle": "true", "dataSource": { "type": "direct", - "query": "trackMCH:MCH/TRACKS;trackMCHROF:MCH/TRACKROFS;trackMCHTRACKCLUSTERS:MCH/TRACKCLUSTERS;mchtrackdigits:MCH/CLUSTERDIGITS;trackMID:MID/TRACKS;trackMIDROF:MID/TRACKROFS;trackMIDTRACKCLUSTERS:MID/TRACKCLUSTERS;trackClMIDROF:MID/TRCLUSROFS;matchMCHMID:GLO/MTC_MCHMID" + "query": "trackMCH:MCH/TRACKS;trackMCHROF:MCH/TRACKROFS;trackMCHTRACKCLUSTERS:MCH/TRACKCLUSTERS;mchtrackdigits:MCH/CLUSTERDIGITS;trackMID:MID/TRACKS/0;trackMIDROF:MID/TRACKROFS/0;trackMIDTRACKCLUSTERS:MID/TRACKCLUSTERS/0;trackClMIDROF:MID/TRCLUSROFS/0;matchMCHMID:GLO/MTC_MCHMID" }, "taskParameters": { "maxTracksPerTF": "600", diff --git a/DATA/production/qc-sync/glo-mftmchmid-mtch-qcmn-epn.json b/DATA/production/qc-sync/glo-mftmchmid-mtch-qcmn-epn.json index f7e73bf55..3806ed288 100644 --- a/DATA/production/qc-sync/glo-mftmchmid-mtch-qcmn-epn.json +++ b/DATA/production/qc-sync/glo-mftmchmid-mtch-qcmn-epn.json @@ -33,7 +33,7 @@ "disableLastCycle": "true", "dataSource": { "type": "direct", - "query": "trackMCH:MCH/TRACKS;trackMCHROF:MCH/TRACKROFS;trackMCHTRACKCLUSTERS:MCH/TRACKCLUSTERS;mchtrackdigits:MCH/CLUSTERDIGITS;trackMFT:MFT/TRACKS;trackMFTROF:MFT/MFTTrackROF;trackMFTClIdx:MFT/TRACKCLSID;alpparMFT:MFT/ALPIDEPARAM/0?lifetime=condition&ccdb-path=MFT/Config/AlpideParam;fwdtracks:GLO/GLFWD;trackMID:MID/TRACKS;trackMIDROF:MID/TRACKROFS;trackMIDTRACKCLUSTERS:MID/TRACKCLUSTERS;trackClMIDROF:MID/TRCLUSROFS;matchMCHMID:GLO/MTC_MCHMID" + "query": "trackMCH:MCH/TRACKS;trackMCHROF:MCH/TRACKROFS;trackMCHTRACKCLUSTERS:MCH/TRACKCLUSTERS;mchtrackdigits:MCH/CLUSTERDIGITS;trackMFT:MFT/TRACKS;trackMFTROF:MFT/MFTTrackROF;trackMFTClIdx:MFT/TRACKCLSID;alpparMFT:MFT/ALPIDEPARAM/0?lifetime=condition&ccdb-path=MFT/Config/AlpideParam;fwdtracks:GLO/GLFWD;trackMID:MID/TRACKS/0;trackMIDROF:MID/TRACKROFS/0;trackMIDTRACKCLUSTERS:MID/TRACKCLUSTERS/0;trackClMIDROF:MID/TRCLUSROFS/0;matchMCHMID:GLO/MTC_MCHMID" }, "taskParameters": { "maxTracksPerTF": "600", diff --git a/DATA/production/qc-sync/mid-digits.json b/DATA/production/qc-sync/mid-digits.json index 7bf1bda58..1539c4e1f 100644 --- a/DATA/production/qc-sync/mid-digits.json +++ b/DATA/production/qc-sync/mid-digits.json @@ -55,7 +55,7 @@ "id": "middigits", "active": "true", "machines": [], - "query": "digits:MID/DATA;digits_rof:MID/DATAROF", + "query": "digits:MID/DATA/0;digits_rof:MID/DATAROF/0", "samplingConditions": [ { "condition": "random", diff --git a/DATA/production/qc-sync/mid.json b/DATA/production/qc-sync/mid.json index fea6f247e..5775dc714 100644 --- a/DATA/production/qc-sync/mid.json +++ b/DATA/production/qc-sync/mid.json @@ -148,7 +148,7 @@ "epn", "localhost" ], - "query": "tracks:MID/TRACKS;trackrofs:MID/TRACKROFS", + "query": "tracks:MID/TRACKS/0;trackrofs:MID/TRACKROFS/0", "samplingConditions": [ { "condition": "random", @@ -165,7 +165,7 @@ "epn", "localhost" ], - "query": "clusters:MID/TRACKCLUSTERS;clusterrofs:MID/TRCLUSROFS", + "query": "clusters:MID/TRACKCLUSTERS/0;clusterrofs:MID/TRCLUSROFS/0", "samplingConditions": [ { "condition": "random", @@ -182,7 +182,7 @@ "epn", "localhost" ], - "query": "digits:MID/DATA;digits_rof:MID/DATAROF", + "query": "digits:MID/DATA/0;digits_rof:MID/DATAROF/0", "samplingConditions": [ { "condition": "random", diff --git a/DATA/production/qc-sync/tpc.json b/DATA/production/qc-sync/tpc.json index daabaa239..d4fa3a484 100644 --- a/DATA/production/qc-sync/tpc.json +++ b/DATA/production/qc-sync/tpc.json @@ -106,7 +106,7 @@ "name": "tpc-tracks" }, "taskParameters": { - "cutAbsEta": "1.", + "cutAbsEta": "1.5", "cutMinNCluster": "60", "cutMindEdxTot": "20." }, diff --git a/DATA/production/qc-workflow.sh b/DATA/production/qc-workflow.sh index 79cccfeb1..6ce392301 100755 --- a/DATA/production/qc-workflow.sh +++ b/DATA/production/qc-workflow.sh @@ -20,22 +20,24 @@ OUTPUT_SUFFIX= add_QC_JSON() { if [[ ${2} =~ ^consul://.* ]]; then + [[ $EPNSYNCMODE == 1 ]] || { echo "Error fetching QC JSON $2: consul server is used for EPNSYNCMODE == 1 only" 1>&2 && exit 1; } TMP_FILENAME=$FETCHTMPDIR/$1.$RANDOM.$RANDOM.json curl -s -o $TMP_FILENAME "http://${GEN_TOPO_QC_CONSUL_SERVER}:8500/v1/kv/${2/consul:\/\//}?raw" if [[ $? != 0 ]]; then - echo "Error fetching QC JSON $2" + echo "Error fetching QC JSON $2 (3)" 1>&2 exit 1 fi elif [[ ${2} =~ ^apricot://.* ]]; then + [[ $EPNSYNCMODE == 1 ]] || { echo "Error fetching QC JSON $2: apricot server is used for EPNSYNCMODE == 1 only" 1>&2 && exit 1; } TMP_FILENAME=$FETCHTMPDIR/$1.$RANDOM.$RANDOM.json - if [[ ${2} =~ "?" ]]; then - curl -s -o $TMP_FILENAME "${GEN_TOPO_QC_APRICOT_SERVER}/${2/apricot:\/\/o2\//}\&run_type=${RUNTYPE:-}\&beam_type=${BEAMTYPE:-}\&process=true" - else - curl -s -o $TMP_FILENAME "${GEN_TOPO_QC_APRICOT_SERVER}/${2/apricot:\/\/o2\//}?run_type=${RUNTYPE:-}\&beam_type=${BEAMTYPE:-}\&process=true" - fi - + if [[ ${2} =~ "?" ]]; then + curl -s -o $TMP_FILENAME "${GEN_TOPO_QC_APRICOT_SERVER}/${2/apricot:\/\/o2\//}\&run_type=${RUNTYPE:-}\&beam_type=${BEAMTYPE:-}\&process=true" + else + curl -s -o $TMP_FILENAME "${GEN_TOPO_QC_APRICOT_SERVER}/${2/apricot:\/\/o2\//}?run_type=${RUNTYPE:-}\&beam_type=${BEAMTYPE:-}\&process=true" + fi + if [[ $? != 0 ]]; then - echo "Error fetching QC JSON $2" + echo "Error fetching QC JSON $2 (4)" 1>&2 exit 1 fi else @@ -75,9 +77,9 @@ elif [[ -z ${QC_JSON_FROM_OUTSIDE:-} ]]; then QC_JSON_TOF=apricot://o2/components/qc/ANY/any/tof-full-epn-qcmn-on-epn fi fi - [[ -z "${QC_JSON_FDD:-}" ]] && QC_JSON_FDD=apricot://o2/components/qc/ANY/any/fdd-digits-qc-epn - [[ -z "${QC_JSON_FT0:-}" ]] && QC_JSON_FT0=apricot://o2/components/qc/ANY/any/ft0-digits-qc-epn - [[ -z "${QC_JSON_FV0:-}" ]] && QC_JSON_FV0=apricot://o2/components/qc/ANY/any/fv0-digits-qc-epn + [[ -z "${QC_JSON_FDD:-}" ]] && QC_JSON_FDD=apricot://o2/components/qc/ANY/any/fdd-digits-qcmn-epn + [[ -z "${QC_JSON_FT0:-}" ]] && QC_JSON_FT0=apricot://o2/components/qc/ANY/any/ft0-digits-qcmn-epn + [[ -z "${QC_JSON_FV0:-}" ]] && QC_JSON_FV0=apricot://o2/components/qc/ANY/any/fv0-digits-qcmn-epn if [[ -z "${QC_JSON_EMC:-}" ]]; then if [[ "$BEAMTYPE" == "PbPb" ]]; then if has_detector CTP; then @@ -115,6 +117,7 @@ elif [[ -z ${QC_JSON_FROM_OUTSIDE:-} ]]; then [[ -z "${QC_JSON_CPV:-}" ]] && QC_JSON_CPV=apricot://o2/components/qc/ANY/any/cpv-physics-qcmn-epn [[ -z "${QC_JSON_TRD:-}" ]] && QC_JSON_TRD=apricot://o2/components/qc/ANY/any/trd-full-qcmn [[ -z "${QC_JSON_PHS:-}" ]] && QC_JSON_PHS=apricot://o2/components/qc/ANY/any/phos-raw-clusters-epn + [[ -z "${QC_JSON_CTP:-}" ]] && QC_JSON_CTP=apricot://o2/components/qc/ANY/any/ctp-raw-qc-epn [[ -z "${QC_JSON_GLO_PRIMVTX:-}" ]] && QC_JSON_GLO_PRIMVTX=apricot://o2/components/qc/ANY/any/glo-vtx-qcmn-epn [[ -z "${QC_JSON_GLO_ITSTPC:-}" ]] && QC_JSON_GLO_ITSTPC=apricot://o2/components/qc/ANY/any/glo-itstpc-mtch-qcmn-epn if [[ -z "${QC_JSON_TOF_MATCH:-}" ]]; then @@ -196,7 +199,7 @@ elif [[ -z ${QC_JSON_FROM_OUTSIDE:-} ]]; then else QC_JSON_ZDC=$O2DPG_ROOT/DATA/production/qc-async/zdc.json fi - fi + fi if [[ -z "${QC_JSON_EMC:-}" ]]; then if [[ "$BEAMTYPE" == "PbPb" ]]; then QC_JSON_EMC=$O2DPG_ROOT/DATA/production/qc-async/emc_PbPb.json @@ -270,13 +273,13 @@ elif [[ -z ${QC_JSON_FROM_OUTSIDE:-} ]]; then if [[ $i == "PRIMVTX" ]] && ! has_detector_reco ITS; then continue; fi if [[ $i == "ITSTPC" ]] && ! has_detectors_reco ITS TPC; then continue; fi add_QC_JSON GLO_$i ${!DET_JSON_FILE} - + if [[ $i == "ITSTPC" ]]; then LOCAL_FILENAME=${JSON_FILES//*\ /} # replace the input sources depending on the detector compostition and matching detectors ITSTPCMatchQuery="trackITSTPC:GLO/TPCITS/0;trackITSTPCABREFS:GLO/TPCITSAB_REFS/0;trackITSTPCABCLID:GLO/TPCITSAB_CLID/0;trackTPC:TPC/TRACKS;trackTPCClRefs:TPC/CLUSREFS/0;trackITS:ITS/TRACKS/0;trackITSROF:ITS/ITSTrackROF/0;trackITSClIdx:ITS/TRACKCLSID/0;alpparITS:ITS/ALPIDEPARAM/0?lifetime=condition&ccdb-path=ITS/Config/AlpideParam;SVParam:GLO/SVPARAM/0?lifetime=condition&ccdb-path=GLO/Config/SVertexerParam" TRACKSOURCESK0="ITS,TPC,ITS-TPC" - if has_processing_step MATCH_SECVTX || has_detector_matching SECVTX; then + if [[ $BEAMTYPE != "cosmic" ]] && (has_processing_step MATCH_SECVTX || has_detector_matching SECVTX); then if [[ $SYNCMODE == 1 ]] || [[ $EPNSYNCMODE == 1 ]]; then HAS_K0_ENABLED=$(jq -r .qc.tasks.MTCITSTPC.taskParameters.doK0QC "${LOCAL_FILENAME}") else @@ -308,9 +311,9 @@ elif [[ -z ${QC_JSON_FROM_OUTSIDE:-} ]]; then ITSTPCMatchQuery+=";matchTPCTRDTOF/TOF/MTC_TPCTRD/0" TRACKSOURCESK0+=",TPC-TRD-TOF" fi - if has_secvtx_source TOF; then + if has_detector_in_secvtx_sources TOF; then ITSTPCMatchQuery+=";tofcluster:TOF/CLUSTERS/0" - TRACKSOURCESK0+=",TOF" + has_secvtx_source TOF && TRACKSOURCESK0+=",TOF" fi if has_secvtx_source TRD; then TRACKSOURCESK0+=",TRD" diff --git a/DATA/production/standalone-calibration.desc b/DATA/production/standalone-calibration.desc index 2c8bf7c7a..169f2ff9b 100644 --- a/DATA/production/standalone-calibration.desc +++ b/DATA/production/standalone-calibration.desc @@ -18,13 +18,17 @@ ITS-thr-full: "O2PDPSuite" reco,80,80,"RUNTYPE_ITS=thrfull production/calib/its- ITS-digital: "O2PDPSuite" reco,40,40,"RUNTYPE_ITS=digital production/calib/its-threshold-processing.sh" calib,40,"RUNTYPE_ITS=digital production/calib/its-threshold-aggregator.sh" +ITS-digital-no-mask: "O2PDPSuite" reco,40,40,"RUNTYPE_ITS=digitalnomask production/calib/its-threshold-processing.sh" calib,40,"RUNTYPE_ITS=digitalnomask production/calib/its-threshold-aggregator.sh" + ITS-pulselength: "O2PDPSuite" reco,40,40,"RUNTYPE_ITS=pulselength production/calib/its-threshold-processing.sh" calib,40,"RUNTYPE_ITS=pulselength production/calib/its-threshold-aggregator.sh" ITS-tot-1row: "O2PDPSuite" reco,40,40,"RUNTYPE_ITS=tot1row production/calib/its-threshold-processing.sh" calib,40,"RUNTYPE_ITS=tot1row production/calib/its-threshold-aggregator.sh" ITS-tot-fullfast: "O2PDPSuite" reco,40,40,"RUNTYPE_ITS=totfullfast production/calib/its-threshold-processing.sh" calib,40,"RUNTYPE_ITS=totfullfast production/calib/its-threshold-aggregator.sh" -ITS-vresetd: "O2PDPSuite" reco,5,5,"RUNTYPE_ITS=vresetd production/calib/its-threshold-processing.sh" calib,5,"RUNTYPE_ITS=vresetd production/calib/its-threshold-aggregator.sh" +ITS-vresetd-1d: "O2PDPSuite" reco,5,5,"RUNTYPE_ITS=vresetd-1d production/calib/its-threshold-processing.sh" calib,5,"RUNTYPE_ITS=vresetd-1d production/calib/its-threshold-aggregator.sh" + +ITS-vresetd-2d: "O2PDPSuite" reco,5,5,"RUNTYPE_ITS=vresetd-2d production/calib/its-threshold-processing.sh" calib,5,"RUNTYPE_ITS=vresetd-2d production/calib/its-threshold-aggregator.sh" TOF-diagnostic-calibration: "O2PDPSuite" reco,10,10,"SHMSIZE=120376524800 production/calib/tof-standalone-reco.sh" calib,4,"production/calib/tof-diagn-aggregator.sh" @@ -36,9 +40,9 @@ TPC-pulser-long: "O2PDPSuite" reco,1,1," production/calib/tpc-pulser-long.sh" TPC-pedestal: "O2PDPSuite" reco,1,1," production/calib/tpc-pedestal.sh" -TPC-laser: "O2PDPSuite" reco,1,1,"SHMSIZE=$((128 << 30)) GPUTYPE=HIP GPUMEMSIZE=$(( 24 << 30 )) HOSTMEMSIZE=$(( 5 << 30 )) production/calib/tpc-laser.sh" +TPC-laser: "O2PDPSuite" reco,1,1,"SHMSIZE=$((128 << 30)) production/calib/tpc-laser.sh" -TPC-laser-multi: "O2PDPSuite" reco,10,10,"SHMSIZE=$((128 << 30)) GPUTYPE=HIP GPUMEMSIZE=$(( 24 << 30 )) HOSTMEMSIZE=$(( 5 << 30 )) production/calib/tpc-laser-filter.sh" calib,1,"production/calib/tpc-laser-aggregator.sh" +TPC-laser-multi: "O2PDPSuite" reco,10,10,"SHMSIZE=$((128 << 30)) production/calib/tpc-laser-filter.sh" calib,1,"production/calib/tpc-laser-aggregator.sh" MFT-noise-calibration: "O2PDPSuite" reco,20,20,"production/calib/mft-noise-processing.sh" calib,20,"production/calib/mft-noise-aggregator.sh" diff --git a/DATA/production/workflow-multiplicities.sh b/DATA/production/workflow-multiplicities.sh index cda4b6d1f..213eeb2e1 100644 --- a/DATA/production/workflow-multiplicities.sh +++ b/DATA/production/workflow-multiplicities.sh @@ -11,10 +11,15 @@ SOURCE_GUARD_MULTIPLICITIES=1 : ${NMFTTHREADS:=2} -: ${SVERTEX_THREADS:=$(( $SYNCMODE == 1 ? 1 : 2 ))} +: ${SVERTEX_THREADS:=2} +if [[ $SYNCMODE == 1 ]]; then : ${ITSTRK_THREADS:=1} : ${ITSTPC_THREADS:=1} +else +: ${ITSTRK_THREADS:=2} +: ${ITSTPC_THREADS:=2} +fi : ${TPCTIMESERIES_THREADS:=1} @@ -48,11 +53,34 @@ if [[ ! -z ${OPTIMIZED_PARALLEL_ASYNC:-} ]]; then [[ ! -z ${TIMEFRAME_RATE_LIMIT:-} ]] && unset TIMEFRAME_RATE_LIMIT [[ ! -z ${SHMSIZE:-} ]] && unset SHMSIZE fi - if [[ $OPTIMIZED_PARALLEL_ASYNC == "pp_8cpu" ]]; then + if [[ $OPTIMIZED_PARALLEL_ASYNC == "8cpu" || $OPTIMIZED_PARALLEL_ASYNC == "8cpu_NVIDIA" || $OPTIMIZED_PARALLEL_ASYNC == "8cpu_AMD" ]]; then [[ -z ${TIMEFRAME_RATE_LIMIT:-} ]] && TIMEFRAME_RATE_LIMIT=3 [[ -z ${SHMSIZE:-} ]] && SHMSIZE=16000000000 + if [[ $OPTIMIZED_PARALLEL_ASYNC == "8cpu_NVIDIA" ]]; then + NGPUS=1 + GPUTYPE=CUDA + GPUMEMSIZE=$((25 << 30)) + N_TPCTRK=$NGPUS + elif [[ $OPTIMIZED_PARALLEL_ASYNC == "8cpu_AMD" ]]; then + NGPUS=1 + GPUTYPE=HIP + GPUMEMSIZE=$((25 << 30)) + N_TPCTRK=$NGPUS + fi NGPURECOTHREADS=5 - elif [[ $OPTIMIZED_PARALLEL_ASYNC == "pp_16cpu" ]]; then + if [[ $BEAMTYPE == "pp" ]]; then + if (( $(echo "$RUN_IR > 800000" | bc -l) )); then + TIMEFRAME_RATE_LIMIT=1 + elif (( $(echo "$RUN_IR < 50000" | bc -l) )); then + TIMEFRAME_RATE_LIMIT=6 + else + TIMEFRAME_RATE_LIMIT=3 + fi + else # PbPb + TIMEFRAME_RATE_LIMIT=2 + SVERTEX_THREADS=5 + fi + elif [[ $OPTIMIZED_PARALLEL_ASYNC == "16cpu" ]]; then [[ -z ${TIMEFRAME_RATE_LIMIT:-} ]] && TIMEFRAME_RATE_LIMIT=8 [[ -z ${SHMSIZE:-} ]] && SHMSIZE=22000000000 NGPURECOTHREADS=9 @@ -73,20 +101,28 @@ if [[ ! -z ${OPTIMIZED_PARALLEL_ASYNC:-} ]]; then N_MCHCL=3 N_TOFMATCH=2 N_TPCENTDEC=3 - elif [[ $OPTIMIZED_PARALLEL_ASYNC == "pp_1gpu" ]]; then + elif [[ $OPTIMIZED_PARALLEL_ASYNC == "pp_1gpu_EPN" || $OPTIMIZED_PARALLEL_ASYNC == "pp_1gpu_EPN_unoptimized" ]]; then [[ -z ${TIMEFRAME_RATE_LIMIT:-} ]] && TIMEFRAME_RATE_LIMIT=8 [[ -z ${SHMSIZE:-} ]] && SHMSIZE=30000000000 - N_TOFMATCH=2 - N_MCHCL=3 - N_TPCENTDEC=2 - N_TPCITS=3 + NGPUS=1 + GPUTYPE=HIP + GPUMEMSIZE=$((25 << 30)) N_MCHTRK=2 - N_ITSTRK=3 - NGPURECOTHREADS=8 + N_TPCTRK=$NGPUS + if [[ $OPTIMIZED_PARALLEL_ASYNC == "pp_1gpu_EPN" ]]; then + N_TOFMATCH=2 + N_MCHCL=3 + N_TPCENTDEC=2 + N_TPCITS=3 + N_ITSTRK=3 + NGPURECOTHREADS=8 + else + NGPURECOTHREADS=4 + fi NTRDTRKTHREADS=3 ITSTRK_THREADS=2 ITSTPC_THREADS=2 - elif [[ $OPTIMIZED_PARALLEL_ASYNC == "pp_4gpu" ]]; then + elif [[ $OPTIMIZED_PARALLEL_ASYNC == "pp_gpu_NERSC" || $OPTIMIZED_PARALLEL_ASYNC == "pp_4gpu_EPN" ]]; then if [[ -z ${TIMEFRAME_RATE_LIMIT:-} ]]; then if [[ ! -z ${ALIEN_JDL_LPMANCHORYEAR} && ${ALIEN_JDL_LPMANCHORYEAR} -lt 2023 ]]; then TIMEFRAME_RATE_LIMIT=45 @@ -95,14 +131,21 @@ if [[ ! -z ${OPTIMIZED_PARALLEL_ASYNC:-} ]]; then fi fi [[ -z ${SHMSIZE:-} ]] && SHMSIZE=100000000000 + if [[ $OPTIMIZED_PARALLEL_ASYNC == "pp_gpu_NERSC" ]]; then + NGPUS=1 + GPUTYPE=CUDA + else + NGPUS=4 + GPUTYPE=HIP + fi + GPUMEMSIZE=$((25 << 30)) NGPURECOTHREADS=8 NTRDTRKTHREADS=2 ITSTRK_THREADS=2 ITSTPC_THREADS=2 SVERTEX_THREADS=4 TPCTIMESERIES_THREADS=2 - NGPUS=4 - N_TPCTRK=4 + N_TPCTRK=$NGPUS N_FWDMATCH=2 N_PRIMVTXMATCH=1 N_PRIMVTX=1 @@ -118,11 +161,18 @@ if [[ ! -z ${OPTIMIZED_PARALLEL_ASYNC:-} ]]; then N_ITSTRK=12 N_ITSCL=2 export DPL_SMOOTH_RATE_LIMITING=1 - elif [[ $OPTIMIZED_PARALLEL_ASYNC == "PbPb_4gpu" ]]; then + elif [[ $OPTIMIZED_PARALLEL_ASYNC == "PbPb_gpu_NERSC" || $OPTIMIZED_PARALLEL_ASYNC == "PbPb_4gpu_EPN" ]]; then [[ -z ${TIMEFRAME_RATE_LIMIT:-} ]] && TIMEFRAME_RATE_LIMIT=35 [[ -z ${SHMSIZE:-} ]] && SHMSIZE=100000000000 # SHM_LIMIT 3/4 [[ -z ${TIMEFRAME_SHM_LIMIT:-} ]] && TIMEFRAME_SHM_LIMIT=$(($SHMSIZE / 3)) - [[ -z ${NGPUS:-} ]] && NGPUS=4 + if [[ $OPTIMIZED_PARALLEL_ASYNC == "PbPb_gpu_NERSC" ]]; then + NGPUS=1 + GPUTYPE=CUDA + else + NGPUS=4 + GPUTYPE=HIP + fi + GPUMEMSIZE=$((25 << 30)) NGPURECOTHREADS=8 NTRDTRKTHREADS=8 ITSTRK_THREADS=5 @@ -140,7 +190,7 @@ if [[ ! -z ${OPTIMIZED_PARALLEL_ASYNC:-} ]]; then N_TOFMATCH=$(math_max $((5 * $NGPUS / 4)) 1) N_HMPCLUS=$(math_max $((3 * $NGPUS / 4)) 1) N_ITSCL=4 - N_AODPROD=2 + N_AODPROD=3 N_MCHCL=9 N_HMPMATCH=1 N_MCHTRK=7 @@ -157,6 +207,9 @@ if [[ ! -z ${OPTIMIZED_PARALLEL_ASYNC:-} ]]; then N_MCHTRK=1 N_TOFMATCH=9 N_TPCTRK=6 + elif [[ $OPTIMIZED_PARALLEL_ASYNC == "keep_root" ]]; then + TIMEFRAME_RATE_LIMIT=4 + SHMSIZE=30000000000 else echo "Invalid optimized setting '$OPTIMIZED_PARALLEL_ASYNC'" 1>&2 exit 1 @@ -171,12 +224,13 @@ elif [[ $EPNPIPELINES != 0 ]]; then ITSTRK_THREADS=2 ITSTPC_THREADS=2 # Tuned multiplicities for sync pp / Pb-Pb processing - if [[ $BEAMTYPE == "pp" ]]; then + if [[ $BEAMTYPE == "pp" || $LIGHTNUCLEI == "1" ]]; then N_ITSRAWDEC=$(math_max $((6 * $EPNPIPELINES * $NGPUS / 4)) 1) N_MFTRAWDEC=$(math_max $((2 * $EPNPIPELINES * $NGPUS / 4)) 1) if [[ "${GEN_TOPO_AUTOSCALE_PROCESSES:-}" == "1" && $RUNTYPE == "PHYSICS" ]]; then N_MCHCL=$(math_max $((6 * 100 / $RECO_NUM_NODES_WORKFLOW_CMP)) 1) fi + N_MCHRAWDEC=2 if [[ "$HIGH_RATE_PP" == "1" ]]; then N_TPCITS=$(math_max $((5 * $EPNPIPELINES * $NGPUS / 4)) 1) N_TPCENT=$(math_max $((4 * $EPNPIPELINES * $NGPUS / 4)) 1) @@ -193,6 +247,7 @@ elif [[ $EPNPIPELINES != 0 ]]; then else if [[ $BEAMTYPE == "PbPb" ]]; then N_ITSTRK=$(math_max $((2 * $EPNPIPELINES * $NGPUS / 4)) 1) + N_MCHRAWDEC=2 elif [[ $BEAMTYPE == "cosmic" ]]; then N_ITSTRK=$(math_max $((4 * $EPNPIPELINES * $NGPUS / 4)) 1) fi @@ -214,7 +269,7 @@ elif [[ $EPNPIPELINES != 0 ]]; then N_ITSRAWDEC=$(math_max $((3 * 60 / $RECO_NUM_NODES_WORKFLOW_CMP)) ${N_ITSRAWDEC:-1}) # This means, if we have 60 EPN nodes, we need at least 3 ITS RAW decoders (will be scaled down by a factor of two automatically if we have 2 NUMA domains) N_MFTRAWDEC=$(math_max $((3 * 60 / $RECO_NUM_NODES_WORKFLOW_CMP)) ${N_MFTRAWDEC:-1}) if [[ $RUNTYPE == "PHYSICS" || $RUNTYPE == "COSMICS" ]]; then - if [[ $BEAMTYPE == "pp" ]]; then + if [[ $BEAMTYPE == "pp" || $LIGHTNUCLEI == "1" ]]; then N_ITSTRK=$(math_max $((9 * 200 / $RECO_NUM_NODES_WORKFLOW_CMP)) ${N_ITSTRK:-1}) elif [[ $BEAMTYPE == "cosmic" ]]; then N_ITSTRK=$(math_max $((5 * 200 / $RECO_NUM_NODES_WORKFLOW_CMP)) ${N_ITSTRK:-1}) @@ -234,7 +289,7 @@ if [[ -z ${EVE_NTH_EVENT:-} ]]; then EVE_NTH_EVENT=2 elif [[ "$HIGH_RATE_PP" == "1" ]]; then EVE_NTH_EVENT=10 - elif [[ $BEAMTYPE == "pp" ]]; then + elif [[ $BEAMTYPE == "pp" || $LIGHTNUCLEI == "1" ]]; then EVE_NTH_EVENT=$((4 * 250 / $RECO_NUM_NODES_WORKFLOW_CMP)) else # COSMICS / TECHNICALS / ... EVE_NTH_EVENT=1 @@ -246,13 +301,27 @@ if [[ "$HIGH_RATE_PP" == "1" ]]; then : ${CUT_RANDOM_FRACTION_ITS:=0.97} elif [[ $BEAMTYPE == "PbPb" ]]; then : ${CUT_RANDOM_FRACTION_ITS:=-1} - : ${CUT_MULT_MIN_ITS:=100} - : ${CUT_MULT_MAX_ITS:=200} + : ${CUT_MULT_MIN_ITS:=0} + : ${CUT_MULT_MAX_ITS:=400} : ${CUT_MULT_VTX_ITS:=20} else : ${CUT_RANDOM_FRACTION_ITS:=0.95} fi -[[ $RUNTYPE != "COSMICS" ]] && : ${CUT_RANDOM_FRACTION_MCH:=0.7} + +# Random data sampling fraction for MCH +if [[ $BEAMTYPE == "pp" || $LIGHTNUCLEI == "1" ]]; then + : ${CUT_RANDOM_FRACTION_MCH_WITH_ITS:=0.5} + : ${CUT_RANDOM_FRACTION_MCH_NO_ITS:=0.995} +elif [[ "$HIGH_RATE_PP" == "1" ]]; then + : ${CUT_RANDOM_FRACTION_MCH_WITH_ITS:=0.7} + : ${CUT_RANDOM_FRACTION_MCH_NO_ITS:=0.995} +elif [[ $BEAMTYPE == "PbPb" ]]; then + : ${CUT_RANDOM_FRACTION_MCH_WITH_ITS:=0.9} + : ${CUT_RANDOM_FRACTION_MCH_NO_ITS:=0.995} +else + : ${CUT_RANDOM_FRACTION_MCH_WITH_ITS:=0.99} + : ${CUT_RANDOM_FRACTION_MCH_NO_ITS:=0.99} +fi #if [[ "$HIGH_RATE_PP" == "1" ]]; then # Extra settings for HIGH_RATE_PP diff --git a/DATA/testing/detectors/FDD/run_fdd_ctf.sh b/DATA/testing/detectors/FDD/run_fdd_ctf.sh index ebcd5dd8c..c413798e9 100755 --- a/DATA/testing/detectors/FDD/run_fdd_ctf.sh +++ b/DATA/testing/detectors/FDD/run_fdd_ctf.sh @@ -25,7 +25,7 @@ export MULTIPLICITY_FACTOR_REST=1 # Factor to export OUTPUT_FILE_NAME=$HOME/topologies/fdd-ctf.xml -/opt/alisw/el8/GenTopo/bin/gen_topo.sh > $OUTPUT_FILE_NAME +/opt/alisw/el9/GenTopo/bin/gen_topo.sh > $OUTPUT_FILE_NAME if [ $? == 0 ]; then echo Generated XML topology $OUTPUT_FILE_NAME fi diff --git a/DATA/testing/detectors/FDD/run_fdd_digits_ctf.sh b/DATA/testing/detectors/FDD/run_fdd_digits_ctf.sh index 4430d0f29..c8ac580d6 100755 --- a/DATA/testing/detectors/FDD/run_fdd_digits_ctf.sh +++ b/DATA/testing/detectors/FDD/run_fdd_digits_ctf.sh @@ -25,7 +25,7 @@ export MULTIPLICITY_FACTOR_REST=1 # Factor to export OUTPUT_FILE_NAME=$HOME/topologies/fdd-digits-ctf.xml -/opt/alisw/el8/GenTopo/bin/gen_topo.sh > $OUTPUT_FILE_NAME +/opt/alisw/el9/GenTopo/bin/gen_topo.sh > $OUTPUT_FILE_NAME if [ $? == 0 ]; then echo Generated XML topology $OUTPUT_FILE_NAME fi diff --git a/DATA/testing/detectors/FDD/run_fdd_digits_qc_ctf.sh b/DATA/testing/detectors/FDD/run_fdd_digits_qc_ctf.sh index d7c37ac7b..797cf88c6 100755 --- a/DATA/testing/detectors/FDD/run_fdd_digits_qc_ctf.sh +++ b/DATA/testing/detectors/FDD/run_fdd_digits_qc_ctf.sh @@ -25,7 +25,7 @@ export MULTIPLICITY_FACTOR_REST=1 # Factor to export OUTPUT_FILE_NAME=$HOME/topologies/fdd-digits-qc-ctf.xml -/opt/alisw/el8/GenTopo/bin/gen_topo.sh > $OUTPUT_FILE_NAME +/opt/alisw/el9/GenTopo/bin/gen_topo.sh > $OUTPUT_FILE_NAME if [ $? == 0 ]; then echo Generated XML topology $OUTPUT_FILE_NAME fi diff --git a/DATA/testing/detectors/FT0/run_ft0_ctf.sh b/DATA/testing/detectors/FT0/run_ft0_ctf.sh index 8f1878d1b..6cc1d8252 100755 --- a/DATA/testing/detectors/FT0/run_ft0_ctf.sh +++ b/DATA/testing/detectors/FT0/run_ft0_ctf.sh @@ -25,7 +25,7 @@ export MULTIPLICITY_FACTOR_REST=1 # Factor to export OUTPUT_FILE_NAME=$HOME/topologies/ft0-ctf.xml -/opt/alisw/el8/GenTopo/bin/gen_topo.sh > $OUTPUT_FILE_NAME +/opt/alisw/el9/GenTopo/bin/gen_topo.sh > $OUTPUT_FILE_NAME if [ $? == 0 ]; then echo Generated XML topology $OUTPUT_FILE_NAME fi diff --git a/DATA/testing/detectors/FT0/run_ft0_digits_ctf.sh b/DATA/testing/detectors/FT0/run_ft0_digits_ctf.sh index caf0de573..7de20e592 100755 --- a/DATA/testing/detectors/FT0/run_ft0_digits_ctf.sh +++ b/DATA/testing/detectors/FT0/run_ft0_digits_ctf.sh @@ -25,7 +25,7 @@ export MULTIPLICITY_FACTOR_REST=1 # Factor to export OUTPUT_FILE_NAME=$HOME/topologies/ft0-digits-ctf.xml -/opt/alisw/el8/GenTopo/bin/gen_topo.sh > $OUTPUT_FILE_NAME +/opt/alisw/el9/GenTopo/bin/gen_topo.sh > $OUTPUT_FILE_NAME if [ $? == 0 ]; then echo Generated XML topology $OUTPUT_FILE_NAME fi diff --git a/DATA/testing/detectors/FT0/run_ft0_digits_qc_ctf.sh b/DATA/testing/detectors/FT0/run_ft0_digits_qc_ctf.sh index 8528245f0..97ec8eadc 100755 --- a/DATA/testing/detectors/FT0/run_ft0_digits_qc_ctf.sh +++ b/DATA/testing/detectors/FT0/run_ft0_digits_qc_ctf.sh @@ -25,7 +25,7 @@ export MULTIPLICITY_FACTOR_REST=1 # Factor to export OUTPUT_FILE_NAME=$HOME/topologies/ft0-digits-qc-ctf.xml -/opt/alisw/el8/GenTopo/bin/gen_topo.sh > $OUTPUT_FILE_NAME +/opt/alisw/el9/GenTopo/bin/gen_topo.sh > $OUTPUT_FILE_NAME if [ $? == 0 ]; then echo Generated XML topology $OUTPUT_FILE_NAME fi diff --git a/DATA/testing/detectors/FV0/run_fv0_ctf.sh b/DATA/testing/detectors/FV0/run_fv0_ctf.sh index a40f395f0..f8078d223 100755 --- a/DATA/testing/detectors/FV0/run_fv0_ctf.sh +++ b/DATA/testing/detectors/FV0/run_fv0_ctf.sh @@ -25,7 +25,7 @@ export MULTIPLICITY_FACTOR_REST=1 # Factor to export OUTPUT_FILE_NAME=$HOME/topologies/fv0-ctf.xml -/opt/alisw/el8/GenTopo/bin/gen_topo.sh > $OUTPUT_FILE_NAME +/opt/alisw/el9/GenTopo/bin/gen_topo.sh > $OUTPUT_FILE_NAME if [ $? == 0 ]; then echo Generated XML topology $OUTPUT_FILE_NAME fi diff --git a/DATA/testing/detectors/FV0/run_fv0_digits_ctf.sh b/DATA/testing/detectors/FV0/run_fv0_digits_ctf.sh index 213ec4828..307d0c682 100755 --- a/DATA/testing/detectors/FV0/run_fv0_digits_ctf.sh +++ b/DATA/testing/detectors/FV0/run_fv0_digits_ctf.sh @@ -25,7 +25,7 @@ export MULTIPLICITY_FACTOR_REST=1 # Factor to export OUTPUT_FILE_NAME=$HOME/topologies/fv0-digits-ctf.xml -/opt/alisw/el8/GenTopo/bin/gen_topo.sh > $OUTPUT_FILE_NAME +/opt/alisw/el9/GenTopo/bin/gen_topo.sh > $OUTPUT_FILE_NAME if [ $? == 0 ]; then echo Generated XML topology $OUTPUT_FILE_NAME fi diff --git a/DATA/testing/detectors/FV0/run_fv0_digits_qc_ctf.sh b/DATA/testing/detectors/FV0/run_fv0_digits_qc_ctf.sh index e86d80f6a..e11a16fea 100755 --- a/DATA/testing/detectors/FV0/run_fv0_digits_qc_ctf.sh +++ b/DATA/testing/detectors/FV0/run_fv0_digits_qc_ctf.sh @@ -25,7 +25,7 @@ export MULTIPLICITY_FACTOR_REST=1 # Factor to export OUTPUT_FILE_NAME=$HOME/topologies/fv0-digits-qc-ctf.xml -/opt/alisw/el8/GenTopo/bin/gen_topo.sh > $OUTPUT_FILE_NAME +/opt/alisw/el9/GenTopo/bin/gen_topo.sh > $OUTPUT_FILE_NAME if [ $? == 0 ]; then echo Generated XML topology $OUTPUT_FILE_NAME fi diff --git a/DATA/testing/detectors/MID/mid-qcmn-epn-digits.json b/DATA/testing/detectors/MID/mid-qcmn-epn-digits.json index f63e66e8c..cf20c554c 100644 --- a/DATA/testing/detectors/MID/mid-qcmn-epn-digits.json +++ b/DATA/testing/detectors/MID/mid-qcmn-epn-digits.json @@ -55,7 +55,7 @@ "id": "mid-digits", "active": "true", "machines": [], - "query": "digits:MID/DATA;digits_rof:MID/DATAROF", + "query": "digits:MID/DATA/0;digits_rof:MID/DATAROF/0", "samplingConditions": [ { "condition": "random", diff --git a/DATA/testing/private/afurs/run_fdd_ft0_fv0_ctf.sh b/DATA/testing/private/afurs/run_fdd_ft0_fv0_ctf.sh index 00f79f4e3..cef2b6338 100755 --- a/DATA/testing/private/afurs/run_fdd_ft0_fv0_ctf.sh +++ b/DATA/testing/private/afurs/run_fdd_ft0_fv0_ctf.sh @@ -25,7 +25,7 @@ export MULTIPLICITY_FACTOR_REST=1 # Factor to export OUTPUT_FILE_NAME=$HOME/topologies/fdd-ft0-fv0-ctf.xml -/opt/alisw/el8/GenTopo/bin/gen_topo.sh > $OUTPUT_FILE_NAME +/opt/alisw/el9/GenTopo/bin/gen_topo.sh > $OUTPUT_FILE_NAME if [ $? == 0 ]; then echo Generated XML topology $OUTPUT_FILE_NAME fi diff --git a/DATA/testing/private/afurs/run_fdd_ft0_fv0_digits_qc_ctf.sh b/DATA/testing/private/afurs/run_fdd_ft0_fv0_digits_qc_ctf.sh index a86068b24..c3494c6cb 100755 --- a/DATA/testing/private/afurs/run_fdd_ft0_fv0_digits_qc_ctf.sh +++ b/DATA/testing/private/afurs/run_fdd_ft0_fv0_digits_qc_ctf.sh @@ -24,7 +24,7 @@ export MULTIPLICITY_FACTOR_REST=1 # Factor to export OUTPUT_FILE_NAME=$HOME/topologies/fdd-ft0-fv0-digits-qc-ctf.xml -/opt/alisw/el8/GenTopo/bin/gen_topo.sh > $OUTPUT_FILE_NAME +/opt/alisw/el9/GenTopo/bin/gen_topo.sh > $OUTPUT_FILE_NAME if [ $? == 0 ]; then echo Generated XML topology $OUTPUT_FILE_NAME fi diff --git a/DATA/testing/private/afurs/run_ft0_fv0_ctf.sh b/DATA/testing/private/afurs/run_ft0_fv0_ctf.sh index 50d7f6a4a..45b7e2678 100755 --- a/DATA/testing/private/afurs/run_ft0_fv0_ctf.sh +++ b/DATA/testing/private/afurs/run_ft0_fv0_ctf.sh @@ -25,7 +25,7 @@ export MULTIPLICITY_FACTOR_REST=1 # Factor to export OUTPUT_FILE_NAME=$HOME/topologies/ft0-fv0-ctf.xml -/opt/alisw/el8/GenTopo/bin/gen_topo.sh > $OUTPUT_FILE_NAME +/opt/alisw/el9/GenTopo/bin/gen_topo.sh > $OUTPUT_FILE_NAME if [ $? == 0 ]; then echo Generated XML topology $OUTPUT_FILE_NAME fi diff --git a/DATA/testing/private/afurs/run_ft0_fv0_digits_qc_ctf.sh b/DATA/testing/private/afurs/run_ft0_fv0_digits_qc_ctf.sh index 375ba8281..6ccc3315b 100755 --- a/DATA/testing/private/afurs/run_ft0_fv0_digits_qc_ctf.sh +++ b/DATA/testing/private/afurs/run_ft0_fv0_digits_qc_ctf.sh @@ -24,7 +24,7 @@ export MULTIPLICITY_FACTOR_REST=1 # Factor to export OUTPUT_FILE_NAME=$HOME/topologies/ft0-fv0-digits-qc-ctf.xml -/opt/alisw/el8/GenTopo/bin/gen_topo.sh > $OUTPUT_FILE_NAME +/opt/alisw/el9/GenTopo/bin/gen_topo.sh > $OUTPUT_FILE_NAME if [ $? == 0 ]; then echo Generated XML topology $OUTPUT_FILE_NAME fi diff --git a/DATA/testing/private/shahoian/runTF_PB.sh b/DATA/testing/private/shahoian/runTF_PB.sh index 5882ebce0..c841c7043 100755 --- a/DATA/testing/private/shahoian/runTF_PB.sh +++ b/DATA/testing/private/shahoian/runTF_PB.sh @@ -60,5 +60,5 @@ do export GEN_TOPO_WORKFLOW_NAME=$wf EXT="xml" [ ! -z $WORKFLOWMODE ] && [ $WORKFLOWMODE == "print" ] && EXT="sh" - /opt/alisw/el8/GenTopo/bin/gen_topo.sh > "$HOME/gen_topo/PB/${GEN_TOPO_WORKFLOW_NAME}.${EXT}" + /opt/alisw/el9/GenTopo/bin/gen_topo.sh > "$HOME/gen_topo/PB/${GEN_TOPO_WORKFLOW_NAME}.${EXT}" done diff --git a/DATA/testing/private/shahoian/runTF_ext_dpl.sh b/DATA/testing/private/shahoian/runTF_ext_dpl.sh index d9e80b3fe..d4e91f89f 100755 --- a/DATA/testing/private/shahoian/runTF_ext_dpl.sh +++ b/DATA/testing/private/shahoian/runTF_ext_dpl.sh @@ -41,5 +41,5 @@ do export GEN_TOPO_WORKFLOW_NAME=$wf EXT="xml" [ ! -z $WORKFLOWMODE ] && [ $WORKFLOWMODE == "print" ] && EXT="sh" - /opt/alisw/el8/GenTopo/bin/gen_topo.sh > "$HOME/gen_topo/dpl/${GEN_TOPO_WORKFLOW_NAME}.${EXT}" + /opt/alisw/el9/GenTopo/bin/gen_topo.sh > "$HOME/gen_topo/dpl/${GEN_TOPO_WORKFLOW_NAME}.${EXT}" done diff --git a/DATA/testing/private/shahoian/run_PB.sh b/DATA/testing/private/shahoian/run_PB.sh index f17c0637d..3b0dd807c 100755 --- a/DATA/testing/private/shahoian/run_PB.sh +++ b/DATA/testing/private/shahoian/run_PB.sh @@ -57,5 +57,5 @@ do export GEN_TOPO_WORKFLOW_NAME=$wf EXT="xml" [ ! -z $WORKFLOWMODE ] && [ $WORKFLOWMODE == "print" ] && EXT="sh" - /opt/alisw/el8/GenTopo/bin/gen_topo.sh > "$HOME/gen_topo/PB/${GEN_TOPO_WORKFLOW_NAME}.${EXT}" + /opt/alisw/el9/GenTopo/bin/gen_topo.sh > "$HOME/gen_topo/PB/${GEN_TOPO_WORKFLOW_NAME}.${EXT}" done diff --git a/DATA/testing/private/shahoian/run_ext.sh b/DATA/testing/private/shahoian/run_ext.sh index ac5e4a566..0288e169c 100755 --- a/DATA/testing/private/shahoian/run_ext.sh +++ b/DATA/testing/private/shahoian/run_ext.sh @@ -33,5 +33,5 @@ jq -n 'reduce inputs as $s (input; .qc.tasks += ($s.qc.tasks) | .qc.checks += ($ for wf in "$@" do export GEN_TOPO_WORKFLOW_NAME=$wf - /opt/alisw/el8/GenTopo/bin/gen_topo.sh > $HOME/gen_topo/test/${GEN_TOPO_WORKFLOW_NAME}.xml + /opt/alisw/el9/GenTopo/bin/gen_topo.sh > $HOME/gen_topo/test/${GEN_TOPO_WORKFLOW_NAME}.xml done diff --git a/DATA/testing/private/shahoian/run_ext_dpl.sh b/DATA/testing/private/shahoian/run_ext_dpl.sh index 039d36a46..348d54c7f 100755 --- a/DATA/testing/private/shahoian/run_ext_dpl.sh +++ b/DATA/testing/private/shahoian/run_ext_dpl.sh @@ -43,5 +43,5 @@ do export GEN_TOPO_WORKFLOW_NAME=$wf EXT="xml" [ ! -z $WORKFLOWMODE ] && [ $WORKFLOWMODE == "print" ] && EXT="sh" - /opt/alisw/el8/GenTopo/bin/gen_topo.sh > "$HOME/gen_topo/dpl/${GEN_TOPO_WORKFLOW_NAME}.${EXT}" + /opt/alisw/el9/GenTopo/bin/gen_topo.sh > "$HOME/gen_topo/dpl/${GEN_TOPO_WORKFLOW_NAME}.${EXT}" done diff --git a/DATA/testing/private/shahoian/run_test.sh b/DATA/testing/private/shahoian/run_test.sh index 21650c063..1c994f317 100755 --- a/DATA/testing/private/shahoian/run_test.sh +++ b/DATA/testing/private/shahoian/run_test.sh @@ -44,5 +44,5 @@ export WORKFLOWMODE=print for wf in "$@" do export GEN_TOPO_WORKFLOW_NAME=$wf - /opt/alisw/el8/GenTopo/bin/gen_topo.sh > $HOME/gen_topo/test/${GEN_TOPO_WORKFLOW_NAME}.xml + /opt/alisw/el9/GenTopo/bin/gen_topo.sh > $HOME/gen_topo/test/${GEN_TOPO_WORKFLOW_NAME}.xml done diff --git a/DATA/testing/private/zampolli/calib/run.sh b/DATA/testing/private/zampolli/calib/run.sh index e5f8b7ebb..bf4dc2a53 100755 --- a/DATA/testing/private/zampolli/calib/run.sh +++ b/DATA/testing/private/zampolli/calib/run.sh @@ -31,9 +31,9 @@ do echo Processing workflow $wf export GEN_TOPO_WORKFLOW_NAME=$wf export WORKFLOWMODE=dds - /opt/alisw/el8/GenTopo/bin/gen_topo.sh > $HOME/gen_topo_calib/dplTest/${GEN_TOPO_WORKFLOW_NAME}.xml + /opt/alisw/el9/GenTopo/bin/gen_topo.sh > $HOME/gen_topo_calib/dplTest/${GEN_TOPO_WORKFLOW_NAME}.xml # export WORKFLOWMODE=print - # /opt/alisw/el8/GenTopo/bin/gen_topo.sh > $HOME/gen_topo_calib/dpl/${GEN_TOPO_WORKFLOW_NAME}.sh + # /opt/alisw/el9/GenTopo/bin/gen_topo.sh > $HOME/gen_topo_calib/dpl/${GEN_TOPO_WORKFLOW_NAME}.sh done diff --git a/DATA/testing/private/zampolli/runTF_ext_dpl.sh b/DATA/testing/private/zampolli/runTF_ext_dpl.sh index 5de8c7367..4f2279639 100755 --- a/DATA/testing/private/zampolli/runTF_ext_dpl.sh +++ b/DATA/testing/private/zampolli/runTF_ext_dpl.sh @@ -43,5 +43,5 @@ do echo echo Processing workflow $wf export GEN_TOPO_WORKFLOW_NAME=$wf - /opt/alisw/el8/GenTopo/bin/gen_topo.sh > $HOME/gen_topo/dpl/${GEN_TOPO_WORKFLOW_NAME}.xml + /opt/alisw/el9/GenTopo/bin/gen_topo.sh > $HOME/gen_topo/dpl/${GEN_TOPO_WORKFLOW_NAME}.xml done diff --git a/DATA/testing/private/zampolli/run_ext_dpl.sh b/DATA/testing/private/zampolli/run_ext_dpl.sh index 855fb2f1d..d7506480f 100755 --- a/DATA/testing/private/zampolli/run_ext_dpl.sh +++ b/DATA/testing/private/zampolli/run_ext_dpl.sh @@ -45,8 +45,8 @@ do echo Processing workflow $wf export GEN_TOPO_WORKFLOW_NAME=$wf export WORKFLOWMODE=dds - /opt/alisw/el8/GenTopo/bin/gen_topo.sh > $HOME/gen_topo/dplTest/${GEN_TOPO_WORKFLOW_NAME}.xml + /opt/alisw/el9/GenTopo/bin/gen_topo.sh > $HOME/gen_topo/dplTest/${GEN_TOPO_WORKFLOW_NAME}.xml # export WORKFLOWMODE=print -# /opt/alisw/el8/GenTopo/bin/gen_topo.sh > $HOME/gen_topo/dpl/${GEN_TOPO_WORKFLOW_NAME}.sh +# /opt/alisw/el9/GenTopo/bin/gen_topo.sh > $HOME/gen_topo/dpl/${GEN_TOPO_WORKFLOW_NAME}.sh done diff --git a/DATA/tools/datadistribution_workflows/dd-discard.xml b/DATA/tools/datadistribution_workflows/dd-discard.xml index 361e690cf..3a5178b63 100644 --- a/DATA/tools/datadistribution_workflows/dd-discard.xml +++ b/DATA/tools/datadistribution_workflows/dd-discard.xml @@ -1,7 +1,7 @@ - GEN_TOPO_TFBUILDER_ENV_VARIABLES /home/epn/odc/tfbuilder.sh standalone + GEN_TOPO_TFBUILDER_ENV_VARIABLES /usr/local/bin/tfbuilder.sh standalone TfBuilderRequirement diff --git a/DATA/tools/datadistribution_workflows/dd-disk.xml b/DATA/tools/datadistribution_workflows/dd-disk.xml index 094c79c8f..9651e83f1 100644 --- a/DATA/tools/datadistribution_workflows/dd-disk.xml +++ b/DATA/tools/datadistribution_workflows/dd-disk.xml @@ -1,7 +1,7 @@ - GEN_TOPO_TFBUILDER_ENV_VARIABLES /home/epn/odc/tfbuilder.sh disk2G + GEN_TOPO_TFBUILDER_ENV_VARIABLES /usr/local/bin/tfbuilder.sh disk2G TfBuilderRequirement diff --git a/DATA/tools/datadistribution_workflows/dd-processing-disk.xml b/DATA/tools/datadistribution_workflows/dd-processing-disk.xml index 005db63af..baa2fb917 100644 --- a/DATA/tools/datadistribution_workflows/dd-processing-disk.xml +++ b/DATA/tools/datadistribution_workflows/dd-processing-disk.xml @@ -1,7 +1,7 @@ - GEN_TOPO_TFBUILDER_ENV_VARIABLES /home/epn/odc/tfbuilder.sh disk2G_data + GEN_TOPO_TFBUILDER_ENV_VARIABLES /usr/local/bin/tfbuilder.sh disk2G_data TfBuilderRequirement diff --git a/DATA/tools/datadistribution_workflows/dd-processing.xml b/DATA/tools/datadistribution_workflows/dd-processing.xml index cb6cd7c79..1e13d2023 100644 --- a/DATA/tools/datadistribution_workflows/dd-processing.xml +++ b/DATA/tools/datadistribution_workflows/dd-processing.xml @@ -1,7 +1,7 @@ - GEN_TOPO_TFBUILDER_ENV_VARIABLES /home/epn/odc/tfbuilder.sh data + GEN_TOPO_TFBUILDER_ENV_VARIABLES /usr/local/bin/tfbuilder.sh data TfBuilderRequirement diff --git a/DATA/tools/epn/gen_topo.sh b/DATA/tools/epn/gen_topo.sh index b48c1de39..0a90ab1da 100755 --- a/DATA/tools/epn/gen_topo.sh +++ b/DATA/tools/epn/gen_topo.sh @@ -4,7 +4,7 @@ # Author: David Rohr # This script is developed within O2DPG: https://github.com/AliceO2Group/O2DPG/blob/master/DATA/tools/epn/gen_topo.sh -# It is installed as package GenTopo to the updateable RPM path /opt/alisw/el8/GenTopo/bin/ on the EPNs +# It is installed as package GenTopo to the updateable RPM path /opt/alisw/el9/GenTopo/bin/ on the EPNs # The purpose of this script is to separate the topology generation (which is in O2DPG) from the setting of the EPN-related settings # This script contains only the EPN related settings @@ -41,11 +41,7 @@ fi # Extra arguments for topology merger if [[ -z "$GEN_TOPO_ODC_EPN_TOPO_POST_CACHING_ARGS" ]]; then - if [[ "${GEN_TOPO_DEPLOYMENT_TYPE:-}" == "ALICE_STAGING" ]]; then - export GEN_TOPO_ODC_EPN_TOPO_POST_CACHING_ARGS="--recozone staging-mi50 --reco100zone staging-mi100 --calibzone calib" - else - export GEN_TOPO_ODC_EPN_TOPO_POST_CACHING_ARGS="--recozone online-mi50 --reco100zone online-mi100 --calibzone calib" - fi + export GEN_TOPO_ODC_EPN_TOPO_POST_CACHING_ARGS="--recozone online-mi50 --reco100zone online-mi100 --calibzone calib" fi if [[ -z "$GEN_TOPO_MI100_NODES" ]]; then export GEN_TOPO_MI100_NODES=-1; fi @@ -59,8 +55,7 @@ else fi fi # Run stage 2 of GenTopo, which does the PDP part, still from hardcoded updatable RPM path -/opt/alisw/el8/GenTopo/bin/gen_topo_o2dpg.sh +/opt/alisw/el9/GenTopo/bin/gen_topo_o2dpg.sh if [ $? != 0 ]; then - echo topology generation failed 1>&2 exit 1 fi diff --git a/DATA/tools/epn/gen_topo_logged.sh b/DATA/tools/epn/gen_topo_logged.sh index 9533712c7..7d2afbb37 100755 --- a/DATA/tools/epn/gen_topo_logged.sh +++ b/DATA/tools/epn/gen_topo_logged.sh @@ -17,7 +17,7 @@ if [[ ! -z $GEN_TOPO_LOGDATE ]]; then fi STDERRFILE=$(mktemp) -/opt/alisw/el8/GenTopo/bin/gen_topo.sh 2> $STDERRFILE +/opt/alisw/el9/GenTopo/bin/gen_topo.sh 2> $STDERRFILE RETVAL=$? if [[ ! -z $GEN_TOPO_LOGDATE ]]; then @@ -26,6 +26,8 @@ if [[ ! -z $GEN_TOPO_LOGDATE ]]; then while read STDERRLINE; do echo "$GEN_TOPO_LOGDATE $ECS_ENVIRONMENT_ID : $STDERRLINE" >> /var/log/topology/gen-topo.log done < $STDERRFILE + echo "FATAL $(tail -n 1 $STDERRFILE)" 1>&2 + echo -e "\n - full stderr output:" 1>&2 fi fi diff --git a/DATA/tools/epn/gen_topo_o2dpg.sh b/DATA/tools/epn/gen_topo_o2dpg.sh index 39bdfc98a..217ddba21 100755 --- a/DATA/tools/epn/gen_topo_o2dpg.sh +++ b/DATA/tools/epn/gen_topo_o2dpg.sh @@ -24,10 +24,10 @@ if [[ -z "$DDSHMSIZE" ]]; then echo \$DDSHMSIZE missing; exit 1; fi # SHM Size f # In case of debug mode, overwrite some settings if [[ "${DEBUG_TOPOLOGY_GENERATION:=0}" == "1" ]]; then echo "Debugging mode enabled. Setting options accordingly" 1>&2 - RECO_NUM_NODES_OVERRIDE=1 # to avoid slurm query, specify number of nodes to fixed value - GEN_TOPO_MI100_NODES=1 # also for MI100 nodes - GEN_TOPO_OVERRIDE_TEMPDIR=$PWD # keep temporary files like QC jsons in local directory - EPN2EOS_METAFILES_DIR=/tmp # nothing is written here, just needs to be set to something + export RECO_NUM_NODES_OVERRIDE=1 # to avoid slurm query, specify number of nodes to fixed value + export GEN_TOPO_MI100_NODES=1 # also for MI100 nodes + export GEN_TOPO_OVERRIDE_TEMPDIR=$PWD # keep temporary files like QC jsons in local directory + export EPN2EOS_METAFILES_DIR=/tmp # nothing is written here, just needs to be set to something unset ECS_ENVIRONMENT_ID unset GEN_TOPO_CACHE_HASH fi @@ -94,7 +94,7 @@ while true; do done git checkout $GEN_TOPO_SOURCE &> /dev/null if [[ $? != 0 ]]; then - git fetch --tags origin 1>&2 || { echo Repository update failed 1>&2; exit 1; } + git fetch -f --tags origin 1>&2 || { echo Repository update failed 1>&2; exit 1; } git checkout $GEN_TOPO_SOURCE &> /dev/null || { echo commit does not exist 1>&2; exit 1; } fi # At a tag, or a detached non-dirty commit, but not on a branch @@ -134,7 +134,7 @@ if [[ ! -z "$GEN_TOPO_ODC_EPN_TOPO_POST_CACHING_CMD" ]] && [[ "0$WORKFLOWMODE" ! fi TMP_POST_CACHING_CMD+=" -o $GEN_TOPO_WORKDIR/output.xml.new $GEN_TOPO_WORKDIR/output.xml" echo "Running post-caching topo-merger command: $TMP_POST_CACHING_CMD" 1>&2 - eval $TMP_POST_CACHING_CMD 1>&2 || { echo Error during EPN topology-merger resource allocation 1>&2; exit 1; } + eval $TMP_POST_CACHING_CMD 1>&2 || { echo Error during EPN resource allocation 1>&2; exit 1; } mv -f $GEN_TOPO_WORKDIR/output.xml.new $GEN_TOPO_WORKDIR/output.xml 1>&2 fi diff --git a/DATA/tools/epn/run.sh b/DATA/tools/epn/run.sh index f16c074fe..cdd422c0a 100755 --- a/DATA/tools/epn/run.sh +++ b/DATA/tools/epn/run.sh @@ -35,8 +35,8 @@ if [[ "0$GEN_TOPO_RUN_HOME" == "01" ]]; then [[ -z $O2DPG_ROOT || -z $O2_ROOT ]] && { echo "ERROR: O2 and O2DPG must be in the environment!"; exit 1; } $O2DPG_ROOT/DATA/tools/epn/gen_topo.sh > $OUTPUT_FILE_NAME else - [[ ! -f /opt/alisw/el8/GenTopo/bin/gen_topo.sh ]] && { echo "ERROR: EPN installation of gen_topo.sh missing. Are you trying to run at home? Then please set GEN_TOPO_RUN_HOME=1!"; exit 1; } - /opt/alisw/el8/GenTopo/bin/gen_topo.sh > $OUTPUT_FILE_NAME + [[ ! -f /opt/alisw/el9/GenTopo/bin/gen_topo.sh ]] && { echo "ERROR: EPN installation of gen_topo.sh missing. Are you trying to run at home? Then please set GEN_TOPO_RUN_HOME=1!"; exit 1; } + /opt/alisw/el9/GenTopo/bin/gen_topo.sh > $OUTPUT_FILE_NAME fi if [[ $? == 0 ]]; then echo Generated XML topology $OUTPUT_FILE_NAME diff --git a/DATA/tools/parse b/DATA/tools/parse index e5b1d2d87..cf0335f3f 100755 --- a/DATA/tools/parse +++ b/DATA/tools/parse @@ -60,9 +60,9 @@ else: modulecmd = " module purge ; " if 'GEN_TOPO_OVERRIDE_MODULE_DIR' in os.environ: - mod.module('unuse', '/opt/alisw/el8/modulefiles') + mod.module('unuse', '/opt/alisw/el9/modulefiles') mod.module('use', os.environ['GEN_TOPO_OVERRIDE_MODULE_DIR']) - modulecmd += ' module unuse /opt/alisw/el8/modulefiles 2>&1 ; module use ' + os.environ['GEN_TOPO_OVERRIDE_MODULE_DIR'] + ' 2>&1 ; ' + modulecmd += ' module unuse /opt/alisw/el9/modulefiles 2>&1 ; module use ' + os.environ['GEN_TOPO_OVERRIDE_MODULE_DIR'] + ' 2>&1 ; ' f = open(sys.argv[1], 'r') for line in f: @@ -141,6 +141,10 @@ for line in f: command_preopt += ' SHMSIZE=' + (str(int(int(os.environ['RECOSHMSIZE']) * 3 / 2)) if mi100node else os.environ['RECOSHMSIZE']) if mi100node: command_preopt += ' EPN_NODE_MI100=1 EPN_GLOBAL_SCALING="3/2"' + if os.getenv('DISABLE_MI100_SERIALIZATION', '0') == '1': + command_preopt += ' DISABLE_MI100_SERIALIZATION=1' + if os.getenv('FULL_MI100_SERIALIZATION', '0') == '1': + command_preopt += ' FULL_MI100_SERIALIZATION=1' if reco_num_nodes_override == 0: command_preopt += ' RECO_NUM_NODES_WORKFLOW=' + wf[1] if is_calib_workflow: @@ -219,7 +223,7 @@ for line in f: odccommand += ' ' + os.environ['GEN_TOPO_ODC_EPN_TOPO_ARGS'] if True: replacestring = '' - dd_env_variables = ['DD_DISK_FRACTION', 'EPN_DD_TEST', 'EPN_DD_TEST_2', 'EPN_DD_TEST_3', 'SHM_MANAGER_SHMID'] + dd_env_variables = ['DD_DISK_FRACTION', 'TF_SINK_NUM_TFS', 'DD_STF_MIN_ID', 'DD_STF_MAX_ID', 'EPN_DD_TEST', 'EPN_DD_TEST_2', 'EPN_DD_TEST_3', 'SHM_MANAGER_SHMID'] for i in dd_env_variables: if i in os.environ: replacestring += ' ' + i + '=' + os.environ[i] diff --git a/GRID/utils/fetch_output_onfailure.sh b/GRID/utils/fetch_output_onfailure.sh index a9f991109..08a5ab452 100755 --- a/GRID/utils/fetch_output_onfailure.sh +++ b/GRID/utils/fetch_output_onfailure.sh @@ -25,11 +25,11 @@ RecycleBase="" for ((i = 0; i < job_number; i++)); do jobid=${FAILEDSUBJOBIDS[i]} if [ ! "${RecycleBase}" ]; then - RecycleOutputDir=$(alien.py ps --trace ${jobid} | awk '/Going to uploadOutputFiles/' | sed 's/.*outputDir=//' | sed 's/)//') + RecycleOutputDir=$(alien.py ps --trace ${jobid} | awk '/Going to uploadOutputFiles/' | sed 's/.*outputDir=//' | sed 's/)//' | sort -u | head -n1) # /alice/cern.ch/user/a/aliprod/recycle/alien-job-2974093751 RecycleBase=${RecycleOutputDir%-${jobid}} # Removes the ${jobid} and yields the recycle base path fi - $(alien.py registerOutput ${jobid}) 2> /dev/null + alien.py registerOutput ${jobid} > /dev/null 2>&1 done # wait a bit to allow propagation of "registerOutput" diff --git a/GRID/utils/getReproducerScript.sh b/GRID/utils/getReproducerScript.sh new file mode 100755 index 000000000..6d3ab119b --- /dev/null +++ b/GRID/utils/getReproducerScript.sh @@ -0,0 +1,80 @@ +#!/bin/bash +ALIEN_PID=$1 + +if [ ${JALIEN_TOKEN_CERT} ]; then + TOKENCERT=${JALIEN_TOKEN_CERT} + TOKENKEY=${JALIEN_TOKEN_KEY} +else + if [ -f ${TMPDIR:-/tmp}/tokencert_`id -u`.pem ]; then + TOKENCERT=${TMPDIR:-/tmp}/tokencert_`id -u`.pem; + fi + if [ -f ${TMPDIR:-/tmp}/tokenkey_`id -u`.pem ]; then + TOKENKEY=${TMPDIR:-/tmp}/tokenkey_`id -u`.pem; + fi +fi + +if [ ! ${TOKENCERT} ]; then + echo "This needs a tokencert and tokenkey file in the tmp folder" + exit 1 +fi + +SCRIPT=reproducer_script_${ALIEN_PID}.sh +# talk to MonaLisa to fetch the script provided by Costin +curl 'https://alimonitor.cern.ch/users/jobenv.jsp?pid='${ALIEN_PID} \ + -H 'User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/132.0.0.0 Safari/537.36' \ + --insecure --cert ${TOKENCERT} --key ${TOKENKEY} -o ${SCRIPT} + +# Define the Apptainer injection block which makes sure +# that the job script is automatically executed in apptainer +INJECTION=' +export ALIEN_PID=#ALIEN_PID# +# Check if the script is running inside an Apptainer (Singularity) container +if [ -z "$APPTAINER_NAME" ] && [ -z "$SINGULARITY_NAME" ]; then + # Relaunch this script inside the container + + export WORKDIR=/tmp/foo-${ALIEN_PID} + if [ ! -d ${WORKDIR} ]; then + mkdir ${WORKDIR} + fi + + # - copy the certificate token into /tmp/ inside the container + mkdir ${WORKDIR}/tmp + cp /tmp/token*pem ${WORKDIR}/tmp + + # - copy the job script into workdir + cp $0 ${WORKDIR} + + # detect architecture (ARM or X86) + ARCH=$(uname -i) + if [ "$ARCH" == "aarch64" ] || [ "$ARCH" == "x86_64" ]; then + echo "Detected hardware architecture : $ARCH" + else + echo "Invalid architecture ${ARCH} detected. Exiting" + exit 1 + fi + if [ "$ARCH" == "aarch64" ]; then + ISAARCH64="1" + fi + + CONTAINER="/cvmfs/alice.cern.ch/containers/fs/apptainer/compat_el9-${ARCH}" + APPTAINER_EXEC="/cvmfs/alice.cern.ch/containers/bin/apptainer/${ARCH}/current/bin/apptainer" + + # we can actually analyse the local JDL to find the package and set it up for the container + ${APPTAINER_EXEC} exec -C -B /cvmfs:/cvmfs,${WORKDIR}:/workdir,${WORKDIR}/tmp:/tmp --pwd /workdir -C ${CONTAINER} "$0" + exit $? +fi +' + +# Inject the block after the first line (shebang) +awk -v block="$INJECTION" 'NR==1 {print; print block; next} 1' "$SCRIPT" > tmpfile && mv tmpfile "$SCRIPT" + +# take out sandboxing structure +sed -i "/echo \"Create a fresh sandbox at every attempt of running the job: alien-job-$ALIEN_PID\"/d" "$SCRIPT" +sed -i "/rm -rf alien-job-$ALIEN_PID/d" "$SCRIPT" +sed -i "/mkdir -p alien-job-$ALIEN_PID\/tmp/d" "$SCRIPT" +sed -i "/cd alien-job-$ALIEN_PID/d" "$SCRIPT" + +# replace the PID +sed -i "s/#ALIEN_PID#/${ALIEN_PID}/g" "$SCRIPT" + +chmod +x "${SCRIPT}" diff --git a/GRID/utils/grid_submit.sh b/GRID/utils/grid_submit.sh index ba4b2a843..dcf6f78da 100755 --- a/GRID/utils/grid_submit.sh +++ b/GRID/utils/grid_submit.sh @@ -208,7 +208,7 @@ while [ $# -gt 0 ] ; do --cores) CPUCORES=$2; shift 2 ;; # allow to specify the CPU cores (check compatibility with partition !) --dry) DRYRUN="ON"; shift 1 ;; # do a try run and not actually interact with the GRID (just produce local jdl file) --o2tag) O2TAG=$2; shift 2 ;; # - --packagespec) PACKAGESPEC=$2; shift 2 ;; # the alisw, cvmfs package list (command separated - example: '"VO_ALICE@FLUKA_VMC::4-1.1-vmc3-1","VO_ALICE@O2::daily-20230628-0200-1"') + --packagespec) PACKAGESPEC=$2; shift 2 ;; # the alisw, cvmfs package list (command separated - example: '"VO_ALICE@FLUKA_VMC::4-1.1-vmc3-1","VO_ALICE@O2::daily-20230628-0200-1"') --asuser) ASUSER=$2; shift 2 ;; # --label) JOBLABEL=$2; shift 2 ;; # label identifying the production (e.g. as a production identifier) --mattermost) MATTERMOSTHOOK=$2; shift 2 ;; # if given, status and metric information about the job will be sent to this hook @@ -216,8 +216,10 @@ while [ $# -gt 0 ] ; do --prodsplit) PRODSPLIT=$2; shift 2 ;; # allows to set JDL production split level (useful to easily replicate workflows) --singularity) SINGULARITY=ON; shift 1 ;; # run everything inside singularity --wait) WAITFORALIEN=ON; shift 1 ;; #wait for alien jobs to finish + --wait-any) WAITFORALIENANY=ON; WAITFORALIEN=ON; shift 1 ;; #wait for any good==done alien jobs to return --outputspec) OUTPUTSPEC=$2; shift 2 ;; #provide comma separate list of JDL file specs to be put as part of JDL Output field (example '"*.log@disk=1","*.root@disk=2"') - -h) Usage ; exit ;; + --split-on-collection) DATACOLLECTION=$2; shift 2 ;; # this will split the jobs on InputDataCollection and "file" mode + -h) Usage ; exit ;; --help) Usage ; exit ;; --fetch-output) FETCHOUTPUT=ON; shift 1 ;; # if to fetch all JOB output locally (to make this job as if it ran locally); only works when we block until all JOBS EXIT *) break ;; @@ -227,7 +229,14 @@ export JOBTTL export JOBLABEL export MATTERMOSTHOOK export CONTROLSERVER -[[ $PRODSPLIT -gt 100 ]] && echo "Production split needs to be smaller than 100 for the moment" && exit 1 + +# Validate the production split level and derive the zero-padding width used for the +# per-subjob OutputDir counter (#alien_counter_i#) and for local fetching. The width +# adapts to PRODSPLIT (minimum 3, so existing 3-digit layouts are unchanged), which lifts +# the former hard cap of 100 while keeping OutputDir naming consistent at any scale. +[[ ! $PRODSPLIT =~ ^[0-9]+$ || $PRODSPLIT -lt 1 ]] && echo "Production split must be a positive integer (got '${PRODSPLIT}')" && exit 1 +COUNTERWIDTH=${#PRODSPLIT} +[[ $COUNTERWIDTH -lt 3 ]] && COUNTERWIDTH=3 # check for presence of jq (needed in code path to fetch output files) [[ "$FETCHOUTPUT" ]] && { which jq &> /dev/null || { echo "Could not find jq command. Please load or install" && exit 1; }; } @@ -270,9 +279,10 @@ pok "Set the job name by running $0 " # Generate local workdir # if [[ "${ONGRID}" == "0" ]]; then - WORKDIR=${WORKDIR:-/tmp/alien_work/$(basename "$MY_JOBWORKDIR")} - [ ! -d "${WORKDIR}" ] && mkdir -p ${WORKDIR} - [ ! "${CONTINUE_WORKDIR}" ] && cp "${MY_JOBSCRIPT}" "${WORKDIR}/alien_jobscript.sh" + GRID_SUBMIT_WORKDIR=${GRID_SUBMIT_WORKDIR:-${TMPDIR:-/tmp}/alien_work/$(basename "$MY_JOBWORKDIR")} + echo "WORKDIR FOR THIS JOB IS ${GRID_SUBMIT_WORKDIR}" + [ ! -d "${GRID_SUBMIT_WORKDIR}" ] && mkdir -p ${GRID_SUBMIT_WORKDIR} + [ ! "${CONTINUE_WORKDIR}" ] && cp "${MY_JOBSCRIPT}" "${GRID_SUBMIT_WORKDIR}/alien_jobscript.sh" fi # @@ -349,17 +359,25 @@ if [[ "${IS_ALIEN_JOB_SUBMITTER}" ]]; then cd "$(dirname "$0")" THIS_SCRIPT="$PWD/$(basename "$0")" - cd "${WORKDIR}" + cd "${GRID_SUBMIT_WORKDIR}" QUOT='"' + SPLITMODE="production:1-${PRODSPLIT}" + if [ "${DATACOLLECTION}" ]; then + SPLITMODE="file" + fi # ---- Generate JDL ---------------- # TODO: Make this configurable or read from a preamble section in the jobfile cat > "${MY_JOBNAMEDATE}.jdl" <> "${MY_JOBNAMEDATE}.jdl" # add error output files [ $IMAGESPEC ] && echo "DebugTag = {\"${IMAGESPEC}\"};" >> "${MY_JOBNAMEDATE}.jdl" # use special singularity image to run job # echo "Requirements = {"${REQUIREMENTSSPEC}"} >> "${MY_JOBNAMEDATE}.jdl" - [ $REQUIRESPEC ] && echo "Requirements = ${REQUIRESPEC}" >> "${MY_JOBNAMEDATE}.jdl" + [ "$REQUIRESPEC" ] && echo "Requirements = ${REQUIRESPEC}" >> "${MY_JOBNAMEDATE}.jdl" # "output_arch.zip:output/*@disk=2", # "checkpoint*.tar@disk=2" @@ -379,10 +397,21 @@ EOF if [ ! "${DRYRUN}" ]; then command_file="alien_commands.txt" + if [ "$DATACOLLECTION" ]; then + pok "Preparing data collection XML file" + alien.py toXml $(cat ${DATACOLLECTION}) > collection.xml + if [ "$?" != "0" ]; then + per "Problem with data collection preparation" + exit 1 + fi + fi + pok "Preparing job \"$MY_JOBNAMEDATE\"" ( # assemble all GRID interaction in a single script / transaction [ -f "${command_file}" ] && rm ${command_file} + echo "user ${MY_USER}" >> ${command_file} + echo "whoami" >> ${command_file} [ ! "${CONTINUE_WORKDIR}" ] && echo "rmdir ${MY_JOBWORKDIR}" >> ${command_file} # remove existing job dir # echo "mkdir ${MY_BINDIR}" >> ${command_file} # create bindir echo "mkdir ${MY_JOBPREFIX}" >> ${command_file} # create job output prefix @@ -391,6 +420,9 @@ EOF echo "rm ${MY_BINDIR}/${MY_JOBNAMEDATE}.sh" >> ${command_file} # remove current job script echo "cp file:${PWD}/${MY_JOBNAMEDATE}.jdl alien://${MY_JOBWORKDIR}/${MY_JOBNAMEDATE}.jdl@DISK=1" >> ${command_file} # copy the jdl echo "cp file:${THIS_SCRIPT} alien://${MY_BINDIR}/${MY_JOBNAMEDATE}.sh@DISK=1" >> ${command_file} # copy current job script to AliEn + if [ "${DATACOLLECTION}" ]; then + echo "cp file:collection.xml alien://${MY_JOBWORKDIR}/collection.xml" >> ${command_file} + fi [ ! "${CONTINUE_WORKDIR}" ] && echo "cp file:${MY_JOBSCRIPT} alien://${MY_JOBWORKDIR}/alien_jobscript.sh" >> ${command_file} ) > alienlog.txt 2>&1 @@ -434,11 +466,29 @@ EOF continue fi let counter=0 # reset counter - JOBSTATUS=$(alien.py ps -j ${MY_JOBID} | awk '//{print $4}') - # echo -ne "Waiting for jobs to return; Last status ${JOBSTATUS}" + + # this is the global job status (a D here means the production is done) + JOBSTATUS=$(alien.py ps -j ${MY_JOBID} | awk '//{print $3}') # this is the global job status + # in addition we may query individual splits + if [ -n "${WAITFORALIENANY}" ]; then + DETAILED_STATUS_JSON=$(ALIENPY_JSON=true alien.py ps -a -m "${MY_JOBID}") + # check if any is already marked as DONE + if jq -e '.results | any(.status == "DONE")' <<<"${DETAILED_STATUS_JSON}" >/dev/null; then + JOBSTATUS="D" + echo "At least one good job" + else + # check if there are still jobs running/waiting; if not also finish + # this could happen when all jobs are zombies (in which case we also finish) + if ! jq -e '.results | any(.status == "WAITING" or .status == "RUNNING" or .status == "SAVING" or .status == "INSERTING")' \ + <<<"${DETAILED_STATUS_JSON}" >/dev/null; then + JOBSTATUS="D" # some job finished successfully + echo "No remaining good job" + fi + fi + fi if [ "${JOBSTATUS}" == "D" ]; then - echo "Job done" + echo "${WAITFORALIENANY:+At least one }Job(s) done" WAITFORALIEN="" # guarantees to go out of outer while loop if [ "${FETCHOUTPUT}" ]; then @@ -460,7 +510,7 @@ EOF THIS_JOB=${SUBJOBIDS[jobindex]} echo "Fetching for job ${THIS_JOB}" if [ "${THIS_STATUS}" == "DONE" ]; then - SPLITOUTDIR=$(printf "%03d" ${splitcounter}) + SPLITOUTDIR=$(printf "%0${COUNTERWIDTH}d" ${splitcounter}) [ ! -f ${SPLITOUTDIR} ] && mkdir ${SPLITOUTDIR} echo "Fetching result files for subjob ${splitcounter} into ${PWD}" CPCMD="alien.py cp ${MY_JOBWORKDIR}/${SPLITOUTDIR}/* file:./${SPLITOUTDIR}" @@ -471,10 +521,6 @@ EOF done fi fi - if [[ "${FOO:0:1}" == [EK] ]]; then - echo "Job error occured" - exit 1 - fi done # get the job data products locally if requested @@ -488,16 +534,33 @@ if [[ ${SINGULARITY} ]]; then # if singularity was asked we restart this script within a container # it's actually much like the GRID mode --> which is why we set JALIEN_TOKEN_CERT set -x - cp $0 ${WORKDIR} - singularity exec -C -B /cvmfs:/cvmfs,${WORKDIR}:/workdir --env JALIEN_TOKEN_CERT="foo" --pwd /workdir /cvmfs/alice.cern.ch/containers/fs/singularity/centos7 $0 \ + cp $0 ${GRID_SUBMIT_WORKDIR} + + # detect architecture (ARM or X86) + ARCH=$(uname -i) + if [ "$ARCH" == "aarch64" ] || [ "$ARCH" == "x86_64" ]; then + echo "Detected hardware architecture : $ARCH" + else + echo "Invalid architecture ${ARCH} detected. Exiting" + exit 1 + fi + if [ "$ARCH" == "aarch64" ]; then + ISAARCH64="1" + fi + + CONTAINER="/cvmfs/alice.cern.ch/containers/fs/apptainer/compat_el9-${ARCH}" + APPTAINER_EXEC="/cvmfs/alice.cern.ch/containers/bin/apptainer/${ARCH}/current/bin/apptainer" + + # we can actually analyse the local JDL to find the package and set it up for the container + ${APPTAINER_EXEC} exec -C -B /cvmfs:/cvmfs,${GRID_SUBMIT_WORKDIR}:/workdir --pwd /workdir -C ${CONTAINER} /workdir/grid_submit.sh \ ${CONTINUE_WORKDIR:+"-c ${CONTINUE_WORKDIR}"} --local ${O2TAG:+--o2tag ${O2TAG}} --ttl ${JOBTTL} --label ${JOBLABEL:-label} ${MATTERMOSTHOOK:+--mattermost ${MATTERMOSTHOOK}} ${CONTROLSERVER:+--controlserver ${CONTROLSERVER}} set +x exit $? fi if [[ "${ONGRID}" == 0 ]]; then - banner "Executing job in directory ${WORKDIR}" - cd "${WORKDIR}" 2> /dev/null + banner "Executing job in directory ${GRID_SUBMIT_WORKDIR}" + cd "${GRID_SUBMIT_WORKDIR}" 2> /dev/null fi exec &> >(tee -a alien_log_${ALIEN_PROC_ID:-0}.txt) @@ -515,7 +578,6 @@ banner "Limits" ulimit -a banner "OS detection" -lsb_release -a || true cat /etc/os-release || true cat /etc/redhat-release || true @@ -543,6 +605,7 @@ cat /proc/meminfo > alien_meminfo.log # ----------- PREPARE SOME ALIEN ENV -- useful for the job ----------- if [ "${ONGRID}" = "1" ]; then + export ALIENPY_JCENTRAL=alice-jcentral.cern.ch notify_mattermost "STARTING GRID ${ALIEN_PROC_ID} CHECK $(which alien.py)" alien.py ps --jdl ${ALIEN_PROC_ID} > this_jdl.jdl ALIEN_JOB_OUTPUTDIR=$(grep "OutputDir" this_jdl.jdl | awk '//{print $3}' | sed 's/"//g' | sed 's/;//') @@ -576,10 +639,6 @@ if [ "${ONGRID}" = "1" ]; then fi fi -# ----------- DOWNLOAD ADDITIONAL HELPERS ---------------------------- -# curl -o analyse_CPU.py https://raw.githubusercontent.com/sawenzel/AliceO2/swenzel/cpuana/Utilities/Tools/analyse_CPU.py &> /dev/null -# chmod +x analyse_CPU.py -export PATH=$PATH:$PWD # export JOBUTILS_MONITORCPU=ON # export JOBUTILS_WRAPPER_SLEEP=5 # export JOBUTILS_JOB_KILLINACTIVE=180 # kill inactive jobs after 3 minutes --> will be the task of pipeline runner? (or make it optional) diff --git a/GRID/utils/querymasterjob.sh b/GRID/utils/querymasterjob.sh index 2f300c52f..1034ebe42 100755 --- a/GRID/utils/querymasterjob.sh +++ b/GRID/utils/querymasterjob.sh @@ -29,5 +29,5 @@ erroredjobs=${tokens[8]} echo "MasterID $masterid" echo "TotalJobs $totaljobs" echo "DoneJobs $donejobs" -echo "RunningJobs $donejobs" +echo "RunningJobs $runningjobs" echo "ErroredJobs $erroredjobs" diff --git a/GRID/utils/runGRIDContainerized.sh b/GRID/utils/runGRIDContainerized.sh index 75bacc182..3fc2380a4 100755 --- a/GRID/utils/runGRIDContainerized.sh +++ b/GRID/utils/runGRIDContainerized.sh @@ -15,11 +15,8 @@ else echo "Invalid architecture ${ARCH} detected. Exiting" exit 1 fi -if [ "$ARCH" == "aarch64" ]; then - ISAARCH64="1" -fi # we just use the default singularity container (if not already set) -APPTAINER_CONTAINER=${APPTAINER_CONTAINER:-/cvmfs/alice.cern.ch/containers/fs/singularity/default${ISAARCH64+"-aarch64"}} +APPTAINER_CONTAINER=${APPTAINER_CONTAINER:-/cvmfs/alice.cern.ch/containers/fs/apptainer/compat_el9-${ARCH}} # create workdir if not specified externally if [ ! "${WORK_DIR}" ]; then @@ -47,7 +44,21 @@ cp ${ALIEN_KEYFILE} ${WORK_DIR}/userkey.pem echo "JALIEN_TOKEN_CERT=/workdir/usercert.pem" > ${WORK_DIR}/envfile echo "JALIEN_TOKEN_KEY=/workdir/userkey.pem" >> ${WORK_DIR}/envfile +if [ "${GRID_CVMFS_PACKAGE}" ]; then + echo "GRID_CVMFS_PACKAGE=${GRID_CVMFS_PACKAGE}" >> ${WORK_DIR}/envfile +fi + +# load a CVMFS package if we are asked to do so -- but do it as part of the job +LOADER='if [ "${GRID_CVMFS_PACKAGE}" ]; then + /cvmfs/alice.cern.ch/bin/alienv printenv ${GRID_CVMFS_PACKAGE} > cvmfs_env + source cvmfs_env +fi' +# Inject the block after the first line (shebang) +JOBSCRIPT=${WORK_DIR}/job.sh +awk -v block="$LOADER" 'NR==1 {print; print block; next} 1' "$JOBSCRIPT" > tmpfile && mv tmpfile "$JOBSCRIPT" +chmod +x "${JOBSCRIPT}" # launch job = script inside the container in the workdir -/cvmfs/alice.cern.ch/containers/bin/apptainer/current${ISAARCH64+"-aarch64"}/bin/apptainer exec -C -B /cvmfs:/cvmfs,${WORK_DIR}:/workdir \ - --pwd /workdir --env-file ${WORK_DIR}/envfile ${APPTAINER_CONTAINER} /workdir/job.sh +APPTAINER_EXEC=${APPTAINER_EXEC:-"/cvmfs/alice.cern.ch/containers/bin/apptainer/${ARCH}/current/bin/apptainer"} +${APPTAINER_SUDO:+sudo} ${APPTAINER_EXEC} exec -C -B /cvmfs:/cvmfs,${WORK_DIR}:/workdir \ + --pwd /workdir --env-file ${WORK_DIR}/envfile ${APPTAINER_CONTAINER} bash /workdir/job.sh diff --git a/MC/bin/o2_dpg_workflow_runner.py b/MC/bin/o2_dpg_workflow_runner.py index 03d69a5bc..229125c3c 100755 --- a/MC/bin/o2_dpg_workflow_runner.py +++ b/MC/bin/o2_dpg_workflow_runner.py @@ -14,6 +14,7 @@ import traceback import platform import tarfile +from copy import deepcopy try: from graphviz import Digraph havegraphviz=True @@ -65,6 +66,9 @@ parser.add_argument('--retry-on-failure', help=argparse.SUPPRESS, default=0) # number of times a failing task is retried parser.add_argument('--no-rootinit-speedup', help=argparse.SUPPRESS, action='store_true') # disable init of ROOT environment vars to speedup init/startup +parser.add_argument('--remove-files-early', type=str, default="", help="Delete intermediate files early (using the file graph information in the given file)") + + # Logging parser.add_argument('--action-logfile', help='Logfilename for action logs. If none given, pipeline_action_#PID.log will be used') parser.add_argument('--metric-logfile', help='Logfilename for metric logs. If none given, pipeline_metric_#PID.log will be used') @@ -85,7 +89,8 @@ def setup_logger(name, log_file, level=logging.INFO): return logger # first file logger -actionlogger = setup_logger('pipeline_action_logger', ('pipeline_action_' + str(os.getpid()) + '.log', args.action_logfile)[args.action_logfile!=None], level=logging.DEBUG) +actionlogger_file = ('pipeline_action_' + str(os.getpid()) + '.log', args.action_logfile)[args.action_logfile!=None] +actionlogger = setup_logger('pipeline_action_logger', actionlogger_file, level=logging.DEBUG) # second file logger metriclogger = setup_logger('pipeline_metric_logger', ('pipeline_metric_' + str(os.getpid()) + '.log', args.action_logfile)[args.action_logfile!=None]) @@ -95,6 +100,7 @@ def setup_logger(name, log_file, level=logging.INFO): meta["cpu_limit"] = args.cpu_limit meta["mem_limit"] = args.mem_limit meta["workflow_file"] = os.path.abspath(args.workflowfile) +args.target_tasks = [f.strip('"').strip("'") for f in args.target_tasks] # strip quotes from the shell meta["target_task"] = args.target_tasks meta["rerun_from"] = args.rerun_from meta["target_labels"] = args.target_labels @@ -316,12 +322,12 @@ def load_json(workflowfile): # filters the original workflowspec according to wanted targets or labels -# returns a new workflowspec +# returns a new workflowspec and the list of "final" workflowtargets def filter_workflow(workflowspec, targets=[], targetlabels=[]): if len(targets)==0: - return workflowspec + return workflowspec, [] if len(targetlabels)==0 and len(targets)==1 and targets[0]=="*": - return workflowspec + return workflowspec, [] transformedworkflowspec = workflowspec @@ -329,7 +335,7 @@ def task_matches(t): for filt in targets: if filt=="*": return True - if re.match(filt, t)!=None: + if re.match(filt, t) != None: return True return False @@ -367,6 +373,8 @@ def canBeDone(t,cache={}): ok = False break cache[t['name']] = ok + if ok == False: + print (f"Disabling target {t['name']} due to unsatisfied requirements") return ok okcache = {} @@ -399,7 +407,7 @@ def needed_by_targets(name): # we finaly copy everything matching the targets as well # as all their requirements transformedworkflowspec['stages']=[ l for l in workflowspec['stages'] if needed_by_targets(l['name']) ] - return transformedworkflowspec + return transformedworkflowspec, full_target_name_list # builds topological orderings (for each timeframe) @@ -432,6 +440,7 @@ def getweight(tid): # update the resource estimates of a workflow based on resources given via JSON def update_resource_estimates(workflow, resource_json): + # the resource_dict here is generated by tool o2dpg_sim_metrics.py json-stat resource_dict = load_json(resource_json) stages = workflow["stages"] @@ -447,17 +456,18 @@ def update_resource_estimates(workflow, resource_json): new_resources = resource_dict[name] # memory - newmem = new_resources.get("mem", None) + newmem = new_resources.get("pss", {}).get("max", None) if newmem is not None: oldmem = task["resources"]["mem"] actionlogger.info("Updating mem estimate for " + task["name"] + " from " + str(oldmem) + " to " + str(newmem)) task["resources"]["mem"] = newmem - newcpu = new_resources.get("cpu", None) # cpu + newcpu = new_resources.get("cpu", {}).get("mean", None) if newcpu is not None: oldcpu = task["resources"]["cpu"] rel_cpu = task["resources"]["relative_cpu"] + # TODO: No longer sure about this since we inject numbers from actually measured workloads if rel_cpu is not None: # respect the relative CPU settings # By default, the CPU value in the workflow is already scaled if relative_cpu is given. @@ -470,8 +480,44 @@ def update_resource_estimates(workflow, resource_json): # a python dictionary def get_alienv_software_environment(packagestring): """ - packagestring is something like O2::v202298081-1,O2Physics::xxx + packagestring is something like O2::v202298081-1,O2Physics::xxx representing packages + published on CVMFS ... or ... a file containing directly the software environment to apply """ + + # the trivial cases do nothing + if packagestring == None or packagestring == "" or packagestring == "None": + return {} + + def load_env_file(env_file): + """Transform an environment file generated with 'export > env.txt' into a python dictionary.""" + env_vars = {} + with open(env_file, "r") as f: + for line in f: + line = line.strip() + + # Ignore empty lines or comments + if not line or line.startswith("#"): + continue + + # Remove 'declare -x ' if present + if line.startswith("declare -x "): + line = line.replace("declare -x ", "", 1) + + # Handle case: "FOO" without "=" (assign empty string) + if "=" not in line: + key, value = line.strip(), "" + else: + key, value = line.split("=", 1) + value = value.strip('"') # Remove surrounding quotes if present + + env_vars[key.strip()] = value + return env_vars + + # see if this is a file + if os.path.exists(packagestring) and os.path.isfile(packagestring): + actionlogger.info("Taking software environment from file " + packagestring) + return load_env_file(packagestring) + # alienv printenv packagestring --> dictionary # for the moment this works with CVMFS only cmd="/cvmfs/alice.cern.ch/bin/alienv printenv " + packagestring @@ -553,7 +599,7 @@ def __init__(self, tid, name, cpu, cpu_relative, mem, resource_boundaries): # sampled resources of this self.cpu_sampled = None self.mem_sampled = None - # Set these after a task has finished to compute new estomates for related tasks + # Set these after a task has finished to compute new estimates for related tasks self.walltime = None self.cpu_taken = None self.mem_taken = None @@ -857,6 +903,44 @@ def ok_to_submit_backfill(res, backfill_cpu_factor=1.5, backfill_mem_factor=1.5) break +def filegraph_expand_timeframes(data: dict, timeframes: set, target_namelist) -> dict: + """ + A utility function for the fileaccess logic. Takes a template and duplicates + for the multi-timeframe structure. + """ + tf_entries = [ + entry for entry in data.get("file_report", []) + if re.match(r"^\./tf\d+/", entry["file"]) + ] + + result = {} + for i in timeframes: + if i == -1: + continue + # Deepcopy to avoid modifying original + new_entries = deepcopy(tf_entries) + for entry in new_entries: + # Fix filepath + entry["file"] = re.sub(r"^\./tf\d+/", f"./tf{i}/", entry["file"]) + # Fix written_by and read_by (preserve prefix, change numeric suffix) + entry["written_by"] = [ + re.sub(r"_\d+$", f"_{i}", w) for w in entry["written_by"] + ] + # for now we mark some files as keep if they are written + # by a target in the runner targetlist. TODO: Add other mechanisms + # to ask for file keeping (such as via regex or the like) + for e in entry["written_by"]: + if e in target_namelist: + entry["keep"] = True + entry["read_by"] = [ + re.sub(r"_\d+$", f"_{i}", r) for r in entry["read_by"] + ] + result[f"timeframe-{i}"] = new_entries + + return result + + + class WorkflowExecutor: # Constructor def __init__(self, workflowfile, args, jmax=100): @@ -872,7 +956,8 @@ def __init__(self, workflowfile, args, jmax=100): os.environ[e] = str(value) # only keep those tasks that are necessary to be executed based on user's filters - self.workflowspec = filter_workflow(self.workflowspec, args.target_tasks, args.target_labels) + self.full_target_namelist = [] + self.workflowspec, self.full_target_namelist = filter_workflow(self.workflowspec, args.target_tasks, args.target_labels) if not self.workflowspec['stages']: if args.target_tasks: @@ -892,6 +977,7 @@ def __init__(self, workflowfile, args, jmax=100): # construct task ID <-> task name lookup self.idtotask = [ 0 for _ in self.taskuniverse ] self.tasktoid = {} + self.idtotf = [ l['timeframe'] for l in self.workflowspec['stages'] ] for i, name in enumerate(self.taskuniverse): self.tasktoid[name]=i self.idtotask[i]=name @@ -933,6 +1019,78 @@ def __init__(self, workflowfile, args, jmax=100): # init alternative software environments self.init_alternative_software_environments() + # initialize container to keep track of file-task relationsships + self.file_removal_candidates = {} + self.do_early_file_removal = False + self.timeframeset = set([ task["timeframe"] for task in self.workflowspec['stages'] ]) + if args.remove_files_early != "": + with open(args.remove_files_early) as f: + filegraph_data = json.load(f) + self.do_early_file_removal = True + self.file_removal_candidates = filegraph_expand_timeframes(filegraph_data, self.timeframeset, self.full_target_namelist) + + def apply_global_env(self, environ_dict): + for e in self.globalinit['env']: + if environ_dict.get(e, None) == None: + value = self.globalinit['env'][e] + actionlogger.info("Applying global environment from init section " + str(e) + " : " + str(value)) + environ_dict[e] = str(value) + + def perform_early_file_removal(self, taskids): + """ + This function checks which files can be deleted upon completion of task + and optionally does so. + """ + + def remove_if_exists(filepath: str) -> None: + """ + Check if a file exists, and remove it if found. + """ + if os.path.exists(filepath): + fsize = os.path.getsize(filepath) + os.remove(filepath) + actionlogger.info(f"Removing {filepath} since no longer needed. Freeing {fsize/1024./1024.} MB.") + return True + + return False + + def remove_for_task_id(taskname, file_dict, timeframe_id, listofalltimeframes): + marked_for_removal = [] + + timeframestoscan = [ timeframe_id ] + if timeframe_id == -1: + timeframestoscan = [ i for i in listofalltimeframes if i != -1 ] + + # TODO: Note that this traversal of files is not certainly not optimal + # We should (and will) keep an mapping of tasks->potential files and just + # scan these. This is already provided by the FileIOGraph analysis tool. + for tid in timeframestoscan: + for i,file_entry in enumerate(file_dict[f"timeframe-{tid}"]): + filename = file_entry['file'] + read_by = file_entry['read_by'] + written_by = file_entry['written_by'] + if taskname in read_by: + file_entry['read_by'].remove(taskname) + if taskname in written_by: + file_entry['written_by'].remove(taskname) + + # TODO: in principle the written_by criterion might not be needed + if len(file_entry['read_by']) == 0 and len(file_entry['written_by']) == 0 and file_entry.get('keep', False) == False: + # the filename mentioned here is no longer needed and we can remove it + # make sure it is there and then delete it + if remove_if_exists(filename): + # also take out the file entry from the dict altogether + marked_for_removal.append(file_entry) + + #for k in marked_for_removal: + # file_dict[f"timeframe-{tid}"].remove(k) + + for tid in taskids: + taskname = self.idtotask[tid] + timeframe_id = self.idtotf[tid] + remove_for_task_id(taskname, self.file_removal_candidates, timeframe_id, self.timeframeset) + + def SIGHandler(self, signum, frame): """ basically forcing shut down of all child processes @@ -1089,19 +1247,32 @@ def submit(self, tid, nice): return subprocess.Popen(['/bin/bash','-c',drycommand], cwd=workdir) taskenv = os.environ.copy() - # add task specific environment - if self.workflowspec['stages'][tid].get('env')!=None: - taskenv.update(self.workflowspec['stages'][tid]['env']) - # apply specific (non-default) software version, if any # (this was setup earlier) alternative_env = self.alternative_envs.get(tid, None) - if alternative_env != None: + if alternative_env != None and len(alternative_env) > 0: actionlogger.info('Applying alternative software environment to task ' + self.idtotask[tid]) - for entry in alternative_env: + if alternative_env.get('TERM') != None: + # the environment is a complete environment + taskenv = {} + taskenv = alternative_env + else: + for entry in alternative_env: # overwrite what is present in default taskenv[entry] = alternative_env[entry] + # add task specific environment + if self.workflowspec['stages'][tid].get('env')!=None: + taskenv.update(self.workflowspec['stages'][tid]['env']) + + # add global workflow environment + self.apply_global_env(taskenv) + + if os.environ.get('PIPELINE_RUNNER_DUMP_TASKENVS') != None: + envfilename = "taskenv_" + str(tid) + ".log" + with open(envfilename, "w") as file: + json.dump(taskenv, file, indent=2) + p = psutil.Popen(['/bin/bash','-c',c], cwd=workdir, env=taskenv) try: p.nice(nice) @@ -1180,6 +1351,17 @@ def monitor(self, process_list): globalPSS=0. resources_per_task = {} + # On a global level, we are interested in total disc space used (not differential in tasks) + # We can call system "du" as the fastest impl + def disk_usage_du(path: str) -> int: + """Use system du to get total size in bytes.""" + out = subprocess.check_output(['du', '-sb', path], text=True) + return int(out.split()[0]) + + disc_usage = -1 + if os.getenv("MONITOR_DISC_USAGE"): + disc_usage = disk_usage_du(os.getcwd()) / 1024. / 1024 # in MB + for tid, proc in process_list: # proc is Popen object @@ -1250,7 +1432,15 @@ def monitor(self, process_list): totalUSS = totalUSS / 1024 / 1024 totalPSS = totalPSS / 1024 / 1024 nice_value = proc.nice() - resources_per_task[tid]={'iter':self.internalmonitorid, 'name':self.idtotask[tid], 'cpu':totalCPU, 'uss':totalUSS, 'pss':totalPSS, 'nice':nice_value, 'swap':totalSWAP, 'label':self.workflowspec['stages'][tid]['labels']} + resources_per_task[tid]={'iter':self.internalmonitorid, + 'name':self.idtotask[tid], + 'cpu':totalCPU, + 'uss':totalUSS, + 'pss':totalPSS, + 'nice':nice_value, + 'swap':totalSWAP, + 'label':self.workflowspec['stages'][tid]['labels'], + 'disc': disc_usage} self.resource_manager.add_monitored_resources(tid, time_delta, totalCPU / 100, totalPSS) if nice_value == self.resource_manager.nice_default: globalCPU += totalCPU @@ -1406,7 +1596,7 @@ def get_tar_command(dir='./', flags='cf', findtype='f', filename='checkpoint.tar def init_alternative_software_environments(self): """ - Initiatialises alternative software environments for specific tasks, if there + Initialises alternative software environments for specific tasks, if there is an annotation in the workflow specificiation. """ @@ -1599,6 +1789,7 @@ def speedup_ROOT_Init(): if not (args.no_rootinit_speedup == True): print ("setting up ROOT system") os.environ['ROOT_LDSYSPATH'] = libpath.decode() + os.environ['CLING_LDSYSPATH'] = libpath.decode() # b) the PATH for compiler includes needed by Cling cmd = "LC_ALL=C c++ -xc++ -E -v /dev/null 2>&1 | sed -n '/^#include/,${/^ \\/.*++/{p}}'" @@ -1609,6 +1800,7 @@ def speedup_ROOT_Init(): if not (args.no_rootinit_speedup == True): actionlogger.info("Determined ROOT_CPPSYSINCL=" + joined) os.environ['ROOT_CPPSYSINCL'] = joined + os.environ['CLING_CPPSYSINCL'] = joined speedup_ROOT_Init() @@ -1691,6 +1883,10 @@ def speedup_ROOT_Init(): actionlogger.debug("finished now :" + str(finished_from_started)) finishedtasks = finishedtasks + finished + # perform file cleanup + if self.do_early_file_removal: + self.perform_early_file_removal(finished_from_started) + if self.is_productionmode: # we can do some generic cleanup of finished tasks in non-interactive/GRID mode # TODO: this can run asynchronously @@ -1763,5 +1959,46 @@ def speedup_ROOT_Init(): exit(code) actionlogger.info("Running in cgroup") -executor=WorkflowExecutor(args.workflowfile,jmax=int(args.maxjobs),args=args) -exit (executor.execute()) + +# This starts the fanotify fileaccess monitoring process +# if asked for +o2dpg_filegraph_exec = os.getenv("O2DPG_PRODUCE_FILEGRAPH") # switches filegraph monitoring on and contains the executable name +if o2dpg_filegraph_exec: + env = os.environ.copy() + env["FILEACCESS_MON_ROOTPATH"] = os.getcwd() + env["MAXMOTHERPID"] = f"{os.getpid()}" + + fileaccess_log_file_name = f"pipeline_fileaccess_{os.getpid()}.log" + fileaccess_log_file = open(fileaccess_log_file_name, "w") + fileaccess_monitor_proc = subprocess.Popen( + [o2dpg_filegraph_exec], + stdout=fileaccess_log_file, + stderr=subprocess.STDOUT, + env=env) +else: + fileaccess_monitor_proc = None + +try: + # This is core workflow runner invocation + executor=WorkflowExecutor(args.workflowfile,jmax=int(args.maxjobs),args=args) + rc = executor.execute() +finally: + if fileaccess_monitor_proc: + fileaccess_monitor_proc.terminate() # sends SIGTERM + try: + fileaccess_monitor_proc.wait(timeout=5) + except subprocess.TimeoutExpired: + fileaccess_monitor_proc.kill() # force kill if not stopping + # now produce the final filegraph output + o2dpg_root = os.getenv("O2DPG_ROOT") + analyse_cmd = [ + sys.executable, # runs with same Python interpreter + f"{o2dpg_root}/UTILS/FileIOGraph/analyse_FileIO.py", + "--actionFile", actionlogger_file, + "--monitorFile", fileaccess_log_file_name, + "-o", f"pipeline_fileaccess_report_{os.getpid()}.json", + "--basedir", os.getcwd() ] + print (f"Producing FileIOGraph with command {analyse_cmd}") + subprocess.run(analyse_cmd, check=True) + +sys.exit(rc) \ No newline at end of file diff --git a/MC/bin/o2dpg_determine_eventstat.py b/MC/bin/o2dpg_determine_eventstat.py index 9e91a24c8..2daddd870 100755 --- a/MC/bin/o2dpg_determine_eventstat.py +++ b/MC/bin/o2dpg_determine_eventstat.py @@ -121,9 +121,11 @@ def read_AO2D_eventcount(file): return eventcount AO2D_eventcount = read_AO2D_eventcount(args.aod_file) -GEANT_eventcount = read_accumulated_GEANT_eventcount() -if AO2D_eventcount != GEANT_eventcount: - print ("WARN: AO2D MC event count and GEANT event count differ") + +# for debugging +# GEANT_eventcount = read_accumulated_GEANT_eventcount() +# if AO2D_eventcount != GEANT_eventcount: +# print ("WARN: AO2D MC event count and GEANT event count differ") print ("Found " + str(AO2D_eventcount) + " events in AO2D file") write_stat_file(AO2D_eventcount) diff --git a/MC/bin/o2dpg_dpl_config_tools.py b/MC/bin/o2dpg_dpl_config_tools.py new file mode 100755 index 000000000..6849ea3dc --- /dev/null +++ b/MC/bin/o2dpg_dpl_config_tools.py @@ -0,0 +1,377 @@ +#!/usr/bin/env python3 + +import json +import re +import sys +from collections import defaultdict +from copy import deepcopy +import os +from o2dpg_workflow_utils import merge_dicts +import shlex + +BUILTIN_BLACKLIST = { + "--session", "--severity", "--shm-segment-id", "--shm-segment-size", + "--resources-monitoring", "--resources-monitoring-dump-interval", + "--delay", "--loop", "--early-forward-policy", "--fairmq-rate-logging", + "--pipeline", "--disable-mc", "--disable-root-input", "--timeframes-rate-limit", + "--timeframes-rate-limit-ipcid", + "--lumi-type", # TPC corrections are treated separately in o2dpg_sim_workflow + "--corrmap-lumi-mode", # TPC corrections are treated separately in o2dpg_sim_workflow + "--enable-M-shape-correction" # TPC correction option not needed in MC +} + +def parse_command_string(cmd_str): + """ + Parse a DPL command string into structured config_base: + { + "executable": str, + "options": {key: val, ...}, + "configKeyValues": {"Group": {subkey: val}} + } + """ + try: + tokens = shlex.split(cmd_str, posix=False) + except ValueError as e: + print(f"[ERROR] Failed to parse command string: {cmd_str}") + raise e + + if not tokens: + return {} + + exe = tokens[0] + opts = {} + config_keyvals_raw = None + + i = 1 + while i < len(tokens): + token = tokens[i] + if token.startswith('--') or (token.startswith('-') and len(token) == 2): + key = token # preserve the dash prefix: "-b" or "--run-number" + if i + 1 < len(tokens) and not tokens[i + 1].startswith('-'): + value = tokens[i + 1].strip('"').strip("'") + i += 1 + else: + value = True + if key == "--configKeyValues": + config_keyvals_raw = value + else: + opts[key] = value + i += 1 + + config_kv_parsed, config_groups = {}, set() + if config_keyvals_raw: + config_kv_parsed, config_groups = parse_configKeyValues_block(config_keyvals_raw) + + return { + "executable": exe, + "options": opts, + "configKeyValues": config_kv_parsed, + "configKeyGroups": sorted(config_groups) + } + +def parse_command_string_symmetric(cmd_str, configname = None): + """ + Parses a DPL command string into the same structure as parse_workflow_config(...): + { + "ConfigParams": { group: {key: value, ...} }, + "Executables": { + "o2-executable": { + "full": {...}, + "filtered": {...}, + "blacklisted": [], + "configKeyValues": [group, ...] + } + } + } + """ + try: + tokens = shlex.split(cmd_str, posix=False) + except ValueError as e: + print(f"[ERROR] Failed to parse command string: {cmd_str}") + raise e + + if not tokens: + return {} + + exe = os.path.basename(tokens[0]) if configname == None else configname + opts = {} + config_kv_raw = None + + i = 1 + while i < len(tokens): + token = tokens[i] + if token.startswith('--') or (token.startswith('-') and len(token) == 2): + key = token # preserve the dash prefix: "-b" or "--run-number" + if i + 1 < len(tokens) and not tokens[i + 1].startswith('-'): + value = tokens[i + 1].strip('"').strip("'") + i += 1 + else: + value = True + if key == "--configKeyValues": + config_kv_raw = value + else: + opts[key] = value + i += 1 + + config_params = {} + config_key_groups = [] + + if config_kv_raw: + parsed_kv, groups = parse_configKeyValues_block(config_kv_raw) + config_params = parsed_kv + config_key_groups = sorted(groups) + + return { + "ConfigParams": config_params, + "Executables": { + exe: { + "full": opts, + "filtered": dict(opts), + "blacklisted": [], + "configKeyValues": config_key_groups + } + } + } + + +def parse_configKeyValues_block(raw_value): + result = defaultdict(dict) + seen_groups = set() + raw_value = raw_value.replace('\\"', '"').replace("\\'", "'") + parts = raw_value.split(";") + for part in parts: + part = part.strip() + if not part or "=" not in part: + continue + key, val = part.split("=", 1) + key = key.strip() + val = val.strip() + if "." in key: + group, subkey = key.split(".", 1) + result[group][subkey] = val + seen_groups.add(group) + return dict(result), seen_groups + +def log_line(logger, message): + if logger is None or logger == sys.stdout: + print(message) + elif isinstance(logger, str): + with open(logger, "a") as f: + f.write(message + "\n") + else: + logger.write(message + "\n") + +def quote_for_nested_string(val): + s = str(val) + # Already double-quoted? + if s.startswith('"') and s.endswith('"'): + return s + # Escape inner quotes + s_escaped = s.replace('"', r'\"') + return f'"{s_escaped}"' + +def quote_if_needed(val): + # Only quote values that are likely to break shell parsing + # or contain nested shell-sensitive characters + s = str(val) + if re.search(r'[ \t;:&|<>]', s): + return quote_for_nested_string(s) + return s + +def modify_dpl_command(cmd_str, config_anchor, allow_overwrite=False, logger=None, configname=None): + # check if cmd_str is given as list, in which case we transfrom to string + if isinstance(cmd_str, list) == True: + cmd_str = " ".join(filter(None, cmd_str)) + + base = parse_command_string(cmd_str) + exe = base["executable"] + existing_opts = base["options"] + existing_kv = base["configKeyValues"] + + # Start building new command + new_cmd = [exe] + added = [] + overwritten = [] + + exe_basename = os.path.basename(exe) if configname == None else configname + anchor_exec = None + if "Executables" in config_anchor: + anchor_exec = config_anchor["Executables"].get(exe_basename, None) + if anchor_exec == None: + # try without the Executable section + anchor_exec = config_anchor.get(exe_basename, None) + + if anchor_exec == None: + print(f"[WARN] No anchor config found for {exe}") + return cmd_str + + anchor_opts = anchor_exec.get("filtered", {}) + anchor_kv_groups = anchor_exec.get("configKeyValues", []) + + # --- Step 1: Reconstruct executable and its CLI options + new_cmd = [exe] + added = [] + overwritten = [] + + # Step 1: Existing options (preserved or overwritten) + for key, val in existing_opts.items(): + if allow_overwrite and key in anchor_opts: + val = anchor_opts[key] + overwritten.append(key) + new_cmd.append(f"{key} {quote_if_needed(val)}" if val is not True else f"{key}") + + # Step 2: Add missing options from anchor + for key, val in anchor_opts.items(): + if key not in existing_opts: + new_cmd.append(f"{key} {quote_if_needed(val)}" if val is not True else f"{key}") + added.append(key) + + # what about config-key values (should already be done) Merge configKeyValues + merged_kv = deepcopy(existing_kv) + # for group in anchor_kv_groups: + # group_kvs = config_anchor.get("ConfigParams", {}).get(group, {}) + # if group not in merged_kv: + # merged_kv[group] = group_kvs + # elif allow_overwrite: + # merged_kv[group].update(group_kvs) + + if merged_kv: + kv_flat = [f"{g}.{k}={v}" for g, kv in merged_kv.items() for k, v in kv.items()] + new_cmd.append('--configKeyValues "' + ";".join(kv_flat) + '"') + + # log changes + log_line(logger, f"\n[Executable: {exe}]") + if added: + log_line(logger, f" Added options: {added}") + if overwritten: + log_line(logger, f" Overwritten options: {overwritten}") + if not added and not overwritten: + log_line(logger, f" No changes made to command.") + + return " ".join(new_cmd) + +# CLI: Parse log + blacklist into output.json +def parse_configKeyValues(raw_value): + return parse_configKeyValues_block(raw_value) + +def parse_workflow_config(log_path): + config_params = defaultdict(dict) + executables = {} + + with open(log_path) as f: + for line in f: + line = line.strip() + if not line or line.startswith("#"): + continue + + parsed = parse_command_string(line) + exe = parsed["executable"] + config_groups_used = parsed["configKeyGroups"] + full_opts = parsed["options"] + + for group, kv in parsed["configKeyValues"].items(): + config_params[group].update(kv) + + executables[exe] = { + "configKeyValues": sorted(config_groups_used), + "full": full_opts + } + + return config_params, executables + + +def apply_blacklist(executables, blacklist_cfg): + for exe, data in executables.items(): + full_opts = data["full"] + exe_blacklist = set(blacklist_cfg.get(exe, [])) + total_blacklist = BUILTIN_BLACKLIST.union(exe_blacklist) + + blacklisted = [] + filtered = {} + + for key, val in full_opts.items(): + if key in total_blacklist: + blacklisted.append(key) + else: + filtered[key] = val + + data["blacklisted"] = sorted(blacklisted) + data["filtered"] = filtered + data["full"] = deepcopy(full_opts) # keep original + return executables + +def dpl_option_from_config(config, dpl_workflow, key, section = "filtered", default_value = None): + """ + Utility to extract a DPL option for workflow dpl_workflow from + the configuration dict "config". The configuration is: + - either a flattish JSON produced by older tool parse-async-WorkflowConfig.py + - more structured version produced by o2dpg_dpl_config_tools (this tool) + """ + if "Executables" in config: + # new standard + value = config["Executables"].get(dpl_workflow,{}).get(section,{}).get(key, None) + if value == None: + print (f"Could not lookup key/option {key} from {dpl_workflow}") + value = default_value + return value + else: + # backward compatible versions + dpl_workflow_key = dpl_workflow + '-options' + if dpl_workflow_key in config: + return config.get(dpl_workflow_key, {}).get(key, default_value) + dpl_workflow_key = dpl_workflow_key + if dpl_workflow_key in config: + return config.get(dpl_workflow_key, {}).get(key, default_value) + return default_value + +def main(): + if len(sys.argv) == 4: + log_path = sys.argv[1] + blacklist_path = sys.argv[2] + output_path = sys.argv[3] + + with open(blacklist_path) as f: + blacklist_data = json.load(f) + + config_params, executables = parse_workflow_config(log_path) + executables = apply_blacklist(executables, blacklist_data) + + result = { + "ConfigParams": dict(config_params), + "Executables": executables + } + + with open(output_path, "w") as out: + json.dump(result, out, indent=2) + + print(f"[INFO] Wrote structured config to: {output_path}") + else: + print("Usage:") + print(" CLI parsing: python3 dpl_config_tools.py workflowconfig.log blacklist.json output.json") + print(" Python usage: import and call parse_command_string() or modify_dpl_command()") + + +class TaskFinalizer: + def __init__(self, anchor_config, allow_overwrite=False, logger=None): + self.anchor_config = anchor_config + self.allow_overwrite = allow_overwrite + self.logger = logger + self.final_config = { + "ConfigParams": {}, + "Executables": {} + } + + def __call__(self, cmd_str_or_list, configname = None): + final_cmd = modify_dpl_command(cmd_str_or_list, self.anchor_config.get("Executables",{}), logger=self.logger, configname=configname) + this_config_final = parse_command_string_symmetric(final_cmd, configname) + print (this_config_final) + merge_dicts (self.final_config, this_config_final) + return final_cmd + + def dump_collected_config(self, path): + with open(path, "w") as f: + json.dump(self.final_config, f, indent=2) + + +if __name__ == "__main__": + main() diff --git a/MC/bin/o2dpg_qc_finalization_workflow.py b/MC/bin/o2dpg_qc_finalization_workflow.py index 569026aa5..815425968 100755 --- a/MC/bin/o2dpg_qc_finalization_workflow.py +++ b/MC/bin/o2dpg_qc_finalization_workflow.py @@ -14,6 +14,7 @@ import argparse from os import environ, mkdir from os.path import join, dirname, isdir +import re sys.path.append(join(dirname(__file__), '.', 'o2dpg_workflow_utils')) @@ -45,12 +46,20 @@ def add_QC_finalization(taskName, qcConfigPath, needs=None): if standalone == True: needs = [] elif needs == None: - needs = [taskName + '_local' + str(tf) for tf in range(1, ntimeframes + 1)] + needs = [taskName + '_local_' + str(tf) for tf in range(1, ntimeframes + 1)] task = createTask(name=QC_finalize_name(taskName), needs=needs, cwd=qcdir, lab=["QC"], cpu=1, mem='2000') - task['cmd'] = f'o2-qc --config {qcConfigPath} --remote-batch {taskName}.root' + \ + def remove_json_prefix(path): + return re.sub(r'^json://', '', path) + + configFilePathOnDisk = remove_json_prefix(qcConfigPath) + # we check if the configFilePath actually exists in the currently loaded software. Otherwise we exit immediately and gracefully + task['cmd'] = ' if [ -f ' + configFilePathOnDisk + ' ]; then { ' + task['cmd'] += f'o2-qc --config {qcConfigPath} --remote-batch {taskName}.root' + \ f' --override-values "qc.config.database.host={qcdbHost};qc.config.Activity.number={run};qc.config.Activity.type=PHYSICS;qc.config.Activity.periodName={productionTag};qc.config.Activity.beamType={beamType};qc.config.conditionDB.url={conditionDB}"' + \ ' ' + getDPL_global_options() + task['cmd'] += ' ;} else { echo "Task ' + taskName + ' not performed due to config file not found "; } fi' + stages.append(task) ## Adds a postprocessing QC workflow @@ -76,27 +85,40 @@ def add_QC_postprocessing(taskName, qcConfigPath, needs, runSpecific, prodSpecif ## The list of remote-batch workflows (reading the merged QC tasks results, applying Checks, uploading them to QCDB) MFTDigitsQCneeds = [] - for flp in range(5): - MFTDigitsQCneeds.extend(['mftDigitsQC'+str(flp)+'_local'+str(tf) for tf in range(1, ntimeframes + 1)]) - add_QC_finalization('mftDigitsQC', 'json://${O2DPG_ROOT}/MC/config/QC/json/mft-digits-0.json', MFTDigitsQCneeds) - add_QC_finalization('mftClustersQC', 'json://${O2DPG_ROOT}/MC/config/QC/json/mft-clusters.json') - add_QC_finalization('mftTracksQC', 'json://${O2DPG_ROOT}/MC/config/QC/json/mft-tracks.json') - add_QC_finalization('mftMCTracksQC', 'json://${O2DPG_ROOT}/MC/config/QC/json/mft-tracks-mc.json') - add_QC_finalization('emcRecoQC', 'json://${O2DPG_ROOT}/MC/config/QC/json/emc-reco-tasks.json') - add_QC_finalization('emcBCQC', 'json://${O2DPG_ROOT}/MC/config/QC/json/emc-reco-tasks.json') - #add_QC_finalization('tpcTrackingQC', 'json://${O2DPG_ROOT}/MC/config/QC/json/tpc-qc-tracking-direct.json') + if isActive('MFT'): + for flp in range(5): + MFTDigitsQCneeds.extend(['mftDigitsQC'+str(flp)+'_local'+str(tf) for tf in range(1, ntimeframes + 1)]) + add_QC_finalization('mftDigitsQC', 'json://${O2DPG_ROOT}/MC/config/QC/json/mft-digits-0.json', MFTDigitsQCneeds) + add_QC_finalization('mftClustersQC', 'json://${O2DPG_ROOT}/MC/config/QC/json/mft-clusters.json') + add_QC_finalization('mftTracksQC', 'json://${O2DPG_ROOT}/MC/config/QC/json/mft-tracks.json') + add_QC_finalization('mftMCTracksQC', 'json://${O2DPG_ROOT}/MC/config/QC/json/mft-tracks-mc.json') + if isActive('EMC'): + add_QC_finalization('emcRecoQC', 'json://${O2DPG_ROOT}/MC/config/QC/json/emc-reco-tasks.json') + add_QC_finalization('emcBCQC', 'json://${O2DPG_ROOT}/MC/config/QC/json/emc-reco-tasks.json') add_QC_finalization('tpcStandardQC', 'json://${O2DPG_ROOT}/MC/config/QC/json/tpc-qc-standard-direct.json') - add_QC_finalization('trdDigitsQC', 'json://${O2DPG_ROOT}/MC/config/QC/json/trd-standalone-task.json') - add_QC_finalization('trdTrackingQC', 'json://${O2DPG_ROOT}/MC/config/QC/json/trd-tracking-task.json') + if isActive('TRD'): + add_QC_finalization('trdDigitsQC', 'json://${O2DPG_ROOT}/MC/config/QC/json/trd-standalone-task.json') + add_QC_finalization('trdTrackingQC', 'json://${O2DPG_ROOT}/MC/config/QC/json/trd-tracking-task.json') add_QC_finalization('vertexQC', 'json://${O2DPG_ROOT}/MC/config/QC/json/vertexing-qc-direct-mc.json') add_QC_finalization('ITSTPCmatchQC', 'json://${O2DPG_ROOT}/MC/config/QC/json/ITSTPCmatchedTracks_direct_MC.json') add_QC_finalization('TOFMatchQC', 'json://${O2DPG_ROOT}/MC/config/QC/json/tofMatchedTracks_ITSTPCTOF_TPCTOF_direct_MC.json') add_QC_finalization('tofDigitsQC', 'json://${O2DPG_ROOT}/MC/config/QC/json/tofdigits.json') add_QC_finalization('TOFMatchWithTRDQC', 'json://${O2DPG_ROOT}/MC/config/QC/json/tofMatchedTracks_AllTypes_direct_MC.json') - add_QC_finalization('ITSTrackSimTask', 'json://${O2DPG_ROOT}/MC/config/QC/json/its-mc-tracks-qc.json') - add_QC_finalization('ITSTracksClusters', 'json://${O2DPG_ROOT}/MC/config/QC/json/its-clusters-tracks-qc.json') + add_QC_finalization('ITSTrackSimTaskQC', 'json://${O2DPG_ROOT}/MC/config/QC/json/its-mc-tracks-qc.json') + add_QC_finalization('ITSTracksClustersQC', 'json://${O2DPG_ROOT}/MC/config/QC/json/its-clusters-tracks-qc.json') if isActive('MID'): add_QC_finalization('MIDTaskQC', 'json://${O2DPG_ROOT}/MC/config/QC/json/mid-task.json') + if isActive('MCH'): + add_QC_finalization('MCHDigitsTaskQC', 'json://${O2DPG_ROOT}/MC/config/QC/json/mch-digits-task.json') + add_QC_finalization('MCHErrorsTaskQC', 'json://${O2DPG_ROOT}/MC/config/QC/json/mch-errors-task.json') + add_QC_finalization('MCHRecoTaskQC', 'json://${O2DPG_ROOT}/MC/config/QC/json/mch-reco-task.json') + add_QC_finalization('MCHTracksTaskQC', 'json://${O2DPG_ROOT}/MC/config/QC/json/mch-tracks-task.json') + if isActive('MCH') and isActive('MID'): + add_QC_finalization('MCHMIDTracksTaskQC', 'json://${O2DPG_ROOT}/MC/config/QC/json/mchmid-tracks-task.json') + if isActive('MCH') and isActive('MID') and isActive('MFT'): + add_QC_finalization('MUONTracksMFTTaskQC', 'json://${O2DPG_ROOT}/MC/config/QC/json/mftmchmid-tracks-task.json') + elif isActive('MCH') and isActive('MFT'): + add_QC_finalization('MCHMFTTaskQC', 'json://${O2DPG_ROOT}/MC/config/QC/json/mftmch-tracks-task.json') if isActive('FT0') and isActive('TRD'): add_QC_finalization('tofft0PIDQC', 'json://${O2DPG_ROOT}/MC/config/QC/json/pidft0tof.json') elif isActive('FT0'): @@ -106,12 +128,19 @@ def add_QC_postprocessing(taskName, qcConfigPath, needs, runSpecific, prodSpecif else: add_QC_finalization('tofPIDQC', 'json://${O2DPG_ROOT}/MC/config/QC/json/pidtofNoTRD.json') add_QC_finalization('RecPointsQC', 'json://${O2DPG_ROOT}/MC/config/QC/json/ft0-reconstruction-config.json') - add_QC_finalization('CPVDigitsQC', 'json://${O2DPG_ROOT}/MC/config/QC/json/cpv-digits-task.json') - add_QC_finalization('CPVClustersQC', 'json://${O2DPG_ROOT}/MC/config/QC/json/cpv-clusters-task.json') - add_QC_finalization('PHSCellsClustersQC', 'json://${O2DPG_ROOT}/MC/config/QC/json/phs-cells-clusters-task.json') + if isActive('FV0'): + add_QC_finalization('FV0DigitsQC', 'json://${O2DPG_ROOT}/MC/config/QC/json/fv0-digits.json') + if isActive('FDD'): + add_QC_finalization('FDDRecPointsQC', 'json://${O2DPG_ROOT}/MC/config/QC/json/fdd-recpoints.json') + if isActive('CPV'): + add_QC_finalization('CPVDigitsQC', 'json://${O2DPG_ROOT}/MC/config/QC/json/cpv-digits-task.json') + add_QC_finalization('CPVClustersQC', 'json://${O2DPG_ROOT}/MC/config/QC/json/cpv-clusters-task.json') + if isActive('PHS'): + add_QC_finalization('PHSCellsClustersQC', 'json://${O2DPG_ROOT}/MC/config/QC/json/phs-cells-clusters-task.json') # The list of QC Post-processing workflows - add_QC_postprocessing('tofTrendingHits', 'json://${O2DPG_ROOT}/MC/config/QC/json/tof-trending-hits.json', [QC_finalize_name('tofDigitsQC')], runSpecific=False, prodSpecific=True) + if isActive('TOF'): + add_QC_postprocessing('tofTrendingHits', 'json://${O2DPG_ROOT}/MC/config/QC/json/tof-trending-hits.json', [QC_finalize_name('tofDigitsQC')], runSpecific=False, prodSpecific=True) return stages diff --git a/MC/bin/o2dpg_sim_config.py b/MC/bin/o2dpg_sim_config.py index 945403804..79c6a4179 100755 --- a/MC/bin/o2dpg_sim_config.py +++ b/MC/bin/o2dpg_sim_config.py @@ -28,9 +28,19 @@ def add(cfg, flatconfig): if 302000 <= int(args.run) and int(args.run) < 309999: add(config, {"ITSAlpideParam.roFrameLengthInBC" : 198}) # ITS reco settings - add(config, {"ITSVertexerParam.phiCut" : 0.5, - "ITSVertexerParam.clusterContributorsCut" : 3, - "ITSVertexerParam.tanLambdaCut" : 0.2}) + add(config, {"ITSVertexerParam.phiCut": 0.4, + "ITSVertexerParam.tanLambdaCut": 0.17, + "ITSVertexerParam.pairCut": 0.0317563, + "ITSVertexerParam.clusterCut": 0.6640964, + "ITSVertexerParam.coarseZWindow": 0.2049018, + "ITSVertexerParam.seedDedupZCut": 0.0711793, + "ITSVertexerParam.refitDedupZCut": 0.0680009, + "ITSVertexerParam.duplicateZCut": 0.1582193, + "ITSVertexerParam.finalSelectionZCut": 0.1081465, + "ITSVertexerParam.duplicateDistance2Cut": 0.0117033, + "ITSVertexerParam.clusterContributorsCut": 2, + "ITSVertexerParam.seedMemberRadiusZ": 0, + "ITSVertexerParam.nSigmaCut": 0.032841}) # primary vertexing settings if 301000 <= int(args.run) and int(args.run) <= 301999: add(config, {"pvertexer.acceptableScale2" : 9, @@ -86,14 +96,64 @@ def add(cfg, flatconfig): if args.fwdmatching_cut_4_param == True: add(config, {"FwdMatching.cutFcn" : "cut3SigmaXYAngles"}) - # deal with larger combinatorics - if args.col == "PbPb" or (args.embedding and args.colBkg == "PbPb"): - add(config, {"ITSVertexerParam.lowMultBeamDistCut": "0."}) - - # FIT digitizer settings for 2023 PbPb + # FIT digitizer settings + #2023 pp + if 534125 <= int(args.run) and int(args.run) <= 543113: + if COLTYPEIR == "pp": + # central and semicentral FT0 thresholds + add(config, {"FT0DigParam.mtrg_central_trh": "40", "FT0DigParam.mtrg_semicentral_trh": "20"}) + # FV0 trigger settings + add(config, {"FV0DigParam.NchannelsLevel": "2", "FV0DigParam.InnerChargeLevel": "4", "FV0DigParam.OuterChargeLevel": "4", "FV0DigParam.ChargeLevel": "8"}) + # 2023 PbPb if 543437 <= int(args.run) and int(args.run) <= 545367: add(config, {"FT0DigParam.mMip_in_V": "7", "FT0DigParam.mMV_2_Nchannels": "2", "FT0DigParam.mMV_2_NchannelsInverse": "0.5"}) add(config, {"FV0DigParam.adcChannelsPerMip": "4"}) + # central and semicentral FT0 thresholds + add(config, {"FT0DigParam.mtrg_central_trh": "1433", "FT0DigParam.mtrg_semicentral_trh": "35"}) + # FV0 trigger settings + add(config, {"FV0DigParam.NchannelsLevel": "2", "FV0DigParam.InnerChargeLevel": "4", "FV0DigParam.OuterChargeLevel": "4", "FV0DigParam.ChargeLevel": "1080"}) + # 2024 + # first and last run of 2024 + if 546088 <= int(args.run) and int(args.run) <= 560623: + # 14 ADC channels / MIP for FT0 + add(config, {"FT0DigParam.mMip_in_V": "7", "FT0DigParam.mMV_2_Nchannels": "2", "FT0DigParam.mMV_2_NchannelsInverse": "0.5"}) + # 15 ADC channels / MIP for FV0 + add(config, {"FV0DigParam.adcChannelsPerMip": "15"}) + if COLTYPEIR == "PbPb": + # 4 ADC channels / MIP + add(config, {"FV0DigParam.adcChannelsPerMip": "4"}) + # central and semicentral FT0 thresholds + add(config, {"FT0DigParam.mtrg_central_trh": "1433", "FT0DigParam.mtrg_semicentral_trh": "35"}) + # FV0 trigger settings + add(config, {"FV0DigParam.NchannelsLevel": "2", "FV0DigParam.InnerChargeLevel": "4", "FV0DigParam.OuterChargeLevel": "4", "FV0DigParam.ChargeLevel": "1080"}) + if COLTYPEIR == "pp": + # central and semicentral FT0 thresholds + add(config, {"FT0DigParam.mtrg_central_trh": "40", "FT0DigParam.mtrg_semicentral_trh": "20"}) + # FV0 trigger settings + add(config, {"FV0DigParam.NchannelsLevel": "2", "FV0DigParam.InnerChargeLevel": "4", "FV0DigParam.OuterChargeLevel": "4", "FV0DigParam.ChargeLevel": "8"}) + # 2025 + # first and last run of 2025 + if 562260 <= int(args.run) and int(args.run) <= 568721: + # 14 ADC channels / MIP for FT0 + add(config, {"FT0DigParam.mMip_in_V": "7", "FT0DigParam.mMV_2_Nchannels": "2", "FT0DigParam.mMV_2_NchannelsInverse": "0.5"}) + if COLTYPEIR == "PbPb": + # 4 ADC channels / MIP + add(config, {"FV0DigParam.adcChannelsPerMip": "4"}) + # central and semicentral FT0 thresholds + add(config, {"FT0DigParam.mtrg_central_trh": "1433", "FT0DigParam.mtrg_semicentral_trh": "35"}) + # FV0 trigger settings + add(config, {"FV0DigParam.NchannelsLevel": "2", "FV0DigParam.InnerChargeLevel": "4", "FV0DigParam.OuterChargeLevel": "4", "FV0DigParam.ChargeLevel": "1080"}) + if COLTYPEIR == "pp" or COLTYPEIR == "OO" or COLTYPEIR == "NeNe" or COLTYPEIR == "pO": + # central and semicentral FT0 thresholds + add(config, {"FT0DigParam.mtrg_central_trh": "40", "FT0DigParam.mtrg_semicentral_trh": "20"}) + # FV0 trigger settings + add(config, {"FV0DigParam.NchannelsLevel": "2", "FV0DigParam.InnerChargeLevel": "4", "FV0DigParam.OuterChargeLevel": "4", "FV0DigParam.ChargeLevel": "8"}) + if COLTYPEIR == "pp": + # 15 ADC channels / MIP + add(config, {"FV0DigParam.adcChannelsPerMip": "15"}) + if COLTYPEIR == "OO" or COLTYPEIR == "NeNe" or COLTYPEIR == "pO": + # 11 ADC channels / MIP + add(config, {"FV0DigParam.adcChannelsPerMip": "11"}) return config @@ -123,6 +183,7 @@ def add(cfg, flatconfig): # ----- add default settings ----- add(config, {"MFTBase.buildAlignment" : "true"}) + add(config, {"GenTPCLoopers.colsys" : args.col}) # ----- apply external overwrites from command line ------- for keyval in externalConfigString.split(";"): @@ -180,7 +241,7 @@ def parse_dpl_help_output(executable, envfile): # the DEVNULL is important for o2-dpl workflows not to hang on non-interactive missing tty environments # it is cleaner that the echo | trick - output = subprocess.check_output([executable, "--help", "full"], env=env, text=True, stdin=subprocess.DEVNULL, timeout = 10) + output = subprocess.check_output([executable, "--help", "full"], env=env, text=True, stdin=subprocess.DEVNULL, timeout = 100) except subprocess.CalledProcessError: return {}, {} @@ -211,6 +272,15 @@ def get_dpl_options_for_executable(executable, envfile): def option_if_available(executable, option, envfile = None): """Checks if an option is available for a given executable and returns it as a string. Otherwise empty string""" - # _, inverse_lookup = get_dpl_options_for_executable(executable, envfile) - # return ' ' + option if option in inverse_lookup else '' - return option + _, inverse_lookup = get_dpl_options_for_executable(executable, envfile) + return ' ' + option if option in inverse_lookup else '' + + +# helper function to overwrite some values; prints out stuff that it changes +def overwrite_config(config, mainkey, subkey, value): + oldvalue = config.get(mainkey,{}).get(subkey, None) + print (f"Overwriting {mainkey}.{subkey}: {'None' if oldvalue is None else oldvalue} -> {value}") + if mainkey not in config: + # Initialize the main key in the dictionary if it does not already exist + config[mainkey] = {} + config[mainkey][subkey] = value diff --git a/MC/bin/o2dpg_sim_workflow.py b/MC/bin/o2dpg_sim_workflow.py index 0731784db..89827daea 100755 --- a/MC/bin/o2dpg_sim_workflow.py +++ b/MC/bin/o2dpg_sim_workflow.py @@ -8,15 +8,18 @@ # # Execution examples: # - pp PYTHIA jets, 2 events, triggered on high pT decay photons on all barrel calorimeters acceptance, eCMS 13 TeV -# ./o2dpg_sim_workflow.py -e TGeant3 -ns 2 -j 8 -tf 1 -mod "--skipModules ZDC" -col pp -eCM 13000 \ +# ./o2dpg_sim_workflow.py -e TGeant3 -ns 2 -j 8 -tf 1 -col pp -eCM 13000 \ # -proc "jets" -ptHatBin 3 \ # -trigger "external" -ini "\$O2DPG_ROOT/MC/config/PWGGAJE/ini/trigger_decay_gamma_allcalo_TrigPt3_5.ini" # # - pp PYTHIA ccbar events embedded into heavy-ion environment, 2 PYTHIA events into 1 bkg event, beams energy 2.510 -# ./o2dpg_sim_workflow.py -e TGeant3 -nb 1 -ns 2 -j 8 -tf 1 -mod "--skipModules ZDC" \ +# ./o2dpg_sim_workflow.py -e TGeant3 -nb 1 -ns 2 -j 8 -tf 1 \ # -col pp -eA 2.510 -proc "ccbar" --embedding # +# TODO: +# - pickup the final list of configKey values from the anchorConfig + import sys import importlib.util import argparse @@ -39,7 +42,11 @@ from o2dpg_workflow_utils import createTask, createGlobalInitTask, dump_workflow, adjust_RECO_environment, isActive, activate_detector, deactivate_detector, compute_n_workers, merge_dicts from o2dpg_qc_finalization_workflow import include_all_QC_finalization -from o2dpg_sim_config import create_sim_config, create_geant_config, constructConfigKeyArg, option_if_available +from o2dpg_sim_config import create_sim_config, create_geant_config, constructConfigKeyArg, option_if_available, overwrite_config +from o2dpg_dpl_config_tools import dpl_option_from_config, TaskFinalizer, quote_if_needed + +# for some JAliEn interaction +from alienpy.alien import JAlien parser = argparse.ArgumentParser(description='Create an ALICE (Run3) MC simulation workflow') @@ -63,7 +70,8 @@ parser.add_argument('-proc',help='process type: inel, dirgamma, jets, ccbar, ...', default='none') parser.add_argument('-trigger',help='event selection: particle, external', default='') parser.add_argument('-ini',help='generator init parameters file (full paths required), for example: ${O2DPG_ROOT}/MC/config/PWGHF/ini/GeneratorHF.ini', default='') -parser.add_argument('-confKey',help='generator or trigger configuration key values, for example: "GeneratorPythia8.config=pythia8.cfg;A.x=y"', default='') +parser.add_argument('-confKey',help='o2sim, generator or trigger configuration key values, for example: "GeneratorPythia8.config=pythia8.cfg;A.x=y"', default='') +parser.add_argument('--detectorList',help='pick which version of ALICE should be simulated', default='ALICE2') parser.add_argument('--readoutDets',help='comma separated string of detectors readout (does not modify material budget - only hit creation)', default='all') parser.add_argument('--make-evtpool', help='Generate workflow for event pool creation.', action='store_true') @@ -89,6 +97,7 @@ parser.add_argument('-iniBkg',help='embedding background generator init parameters file (full path required)', default='${O2DPG_ROOT}/MC/config/common/ini/basic.ini') parser.add_argument('-confKeyBkg',help='embedding background configuration key values, for example: "GeneratorPythia8.config=pythia8bkg.cfg"', default='') parser.add_argument('-colBkg',help='embedding background collision system', default='PbPb') +parser.add_argument('-confKeyQED',help='Config key parameters influencing the QED background simulator', default='') parser.add_argument('-e',help='simengine', default='TGeant4', choices=['TGeant4', 'TGeant3', 'TFluka']) parser.add_argument('-tf',type=int,help='number of timeframes', default=2) @@ -99,7 +108,8 @@ parser.add_argument('--force-n-workers', dest='force_n_workers', action='store_true', help='by default, number of workers is re-computed ' 'for given interaction rate; ' 'pass this to avoid that') -parser.add_argument('-mod',help='Active modules (deprecated)', default='--skipModules ZDC') +parser.add_argument('--skipModules',nargs="*", help="List of modules to skip in geometry budget (and therefore processing)", default=["ZDC"]) +parser.add_argument('--skipReadout',nargs="*", help="List of modules to take out from readout", default=[""]) parser.add_argument('--with-ZDC', action='store_true', help='Enable ZDC in workflow') parser.add_argument('-seed',help='random seed number', default=None) parser.add_argument('-o',help='output workflow file', default='workflow.json') @@ -115,6 +125,9 @@ # power features (for playing) --> does not appear in help message # help='Treat smaller sensors in a single digitization') parser.add_argument('--pregenCollContext', action='store_true', help=argparse.SUPPRESS) # Now the default, giving this option or not makes not difference. We keep it for backward compatibility +parser.add_argument('--data-anchoring', type=str, default='', help="Take collision contexts (from data) stored in this path") +parser.add_argument('--aod-output-folder', type=str, default='', help="Force this AOD folder in the AOD producer") +parser.add_argument('--aod-parent-file', type=str, default='', help="Link this as parent file in the AOD") parser.add_argument('--no-combine-smaller-digi', action='store_true', help=argparse.SUPPRESS) parser.add_argument('--no-combine-dpl-devices', action='store_true', help=argparse.SUPPRESS) parser.add_argument('--no-mc-labels', action='store_true', default=False, help=argparse.SUPPRESS) @@ -145,6 +158,7 @@ # TPC options parser.add_argument('--tpc-distortion-type', default=0, type=int, help='Simulate distortions in the TPC (0=no distortions, 1=distortions without scaling, 2=distortions with CTP scaling)') +parser.add_argument('--tpc-corrmap-lumi-mode', default=2, type=int, help='TPC corrections mode (0=linear, 1=derivative, 2=derivative for special MC maps') parser.add_argument('--ctp-scaler', default=0, type=float, help='CTP raw scaler value used for distortion simulation') # Global Forward reconstruction configuration parser.add_argument('--fwdmatching-assessment-full', action='store_true', help='enables complete assessment of global forward reco') @@ -162,6 +176,7 @@ O2_ROOT=environ.get('O2_ROOT') QUALITYCONTROL_ROOT=environ.get('QUALITYCONTROL_ROOT') O2PHYSICS_ROOT=environ.get('O2PHYSICS_ROOT') +ccdbRemap = environ.get('ALIEN_JDL_REMAPPINGS') if O2DPG_ROOT == None: print('Error: This needs O2DPG loaded') @@ -195,50 +210,117 @@ def load_external_config(configfile): return config anchorConfig = {} +anchorConfig_generic = { "ConfigParams": create_sim_config(args) } if args.anchor_config != '': print ("** Using external config **") anchorConfig = load_external_config(args.anchor_config) + # adjust the anchorConfig with keys from the generic config, not mentioned in the external config + # (useful for instance for digitization parameters or others not usually mentioned in async reco) + for key in anchorConfig_generic["ConfigParams"]: + if not key in anchorConfig["ConfigParams"]: + print (f"Transcribing key {key} from generic config into final config") + anchorConfig["ConfigParams"][key] = anchorConfig_generic["ConfigParams"][key] + else: # we load a generic config print ("** Using generic config **") - anchorConfig = create_sim_config(args) + anchorConfig = anchorConfig_generic # we apply additional external user choices for the configuration # this will overwrite config from earlier stages if args.overwrite_config != '': # apply final JSON overwrite config_overwrite = load_external_config(args.overwrite_config) + # let's make sure the configs follow the same format + if ("ConfigParams" in anchorConfig) != ("ConfigParams" in config_overwrite): + print ("Error: overwrite config not following same format as base config; Cannot merge") + exit (1) + # merge the dictionaries into anchorConfig, the latter takes precedence merge_dicts(anchorConfig, config_overwrite) +# We still may need adjust configurations manually for consistency: +# +# * Force simpler TPC digitization of if TPC reco does not have the mc-time-gain option or remap to a different CCDB object if we are anchored to 2023: +async_envfile = 'env_async.env' if environ.get('ALIEN_JDL_O2DPG_ASYNC_RECO_TAG') is not None else None +tpcreco_mctimegain = option_if_available('o2-tpc-reco-workflow', '--tpc-mc-time-gain', envfile=async_envfile) +if tpcreco_mctimegain == '': + # TODO: Upload all MC time gain objects to TestReco and remove year dependence + year = environ.get('ALIEN_JDL_LPMANCHORYEAR') if environ.get('ALIEN_JDL_LPMANCHORYEAR') is not None else environ.get('ANCHORYEAR') + if year == '2023': + print("TPC reco does not support --tpc-mc-time-gain. Remapping time gain objects for 2023 MC") + # Year dependent workaround for MC anchored to 2023, solving the issue with 2tag mechanism + extra = 'https://alice-ccdb.cern.ch/TestReco/=TPC/Calib/TimeGain' + environ['ALIEN_JDL_REMAPPINGS'] = (ccdbRemap + ';' + extra) if ccdbRemap else extra + # Keep the cached variable in sync, since getDPL_global_options uses it + ccdbRemap = environ.get('ALIEN_JDL_REMAPPINGS') + else: + # this was communicated by Jens Wiechula@TPC; avoids dEdX issue https://its.cern.ch/jira/browse/O2-5486 for the 2tag mechanism + print ("TPC reco does not support --tpc-mc-time-gain. Adjusting some config for TPC digitization") + overwrite_config(anchorConfig['ConfigParams'],'TPCGasParam','OxygenCont',5e-6) + overwrite_config(anchorConfig['ConfigParams'],'TPCGEMParam','TotalGainStack',2000) + overwrite_config(anchorConfig['ConfigParams'],'GPU_global','dEdxDisableResidualGain',1) +# TODO: put into it's own function for better modularity + +# with the config, we'll create a task_finalizer functor +# this object takes care of customizing/finishing task command with externally given (anchor) config +task_finalizer = TaskFinalizer(anchorConfig, logger="o2dpg_config_replacements.log") + # write this config config_key_param_path = args.dump_config with open(config_key_param_path, "w") as f: print(f"INFO: Written additional config key parameters to JSON {config_key_param_path}") json.dump(anchorConfig, f, indent=2) -def get_anchor_env_var(key, default): - return anchorConfig.get('env_vars',{}).get(key, default) +# Processing skipped material budget (modules): +# - If user did NOT specify --with-ZDC +# - AND ZDC is not already in the list +# --> append ZDC automatically +if args.with_ZDC: + # User wants ZDC to *not* be skipped → ensure it's removed + args.skipModules = [m for m in args.skipModules if m != "ZDC"] +else: + # If user did not request --with-ZDC, + # auto-append ZDC unless already present + if "ZDC" not in args.skipModules: + args.skipModules.append("ZDC") # with this we can tailor the workflow to the presence of # certain detectors # these are all detectors that should be assumed active readout_detectors = args.readoutDets # here are all detectors that have been set in an anchored script -activeDetectors = anchorConfig.get('o2-ctf-reader-workflow-options',{}).get('onlyDet','all') +activeDetectors = dpl_option_from_config(anchorConfig, 'o2-ctf-reader-workflow', key='--onlyDet', default_value='all') if activeDetectors == 'all': # if "all" here, there was in fact nothing in the anchored script, set to what is passed to this script (which it either also "all" or a subset) activeDetectors = readout_detectors elif readout_detectors != 'all' and activeDetectors != 'all': - # in this case both are comma-seperated lists. Take intersection + # in this case both are comma-separated lists. Take intersection r = set(readout_detectors.split(',')) a = set(activeDetectors.split(',')) activeDetectors = ','.join(r & a) # the last case: simply take what comes from the anchored config # convert to set/hashmap -activeDetectors = { det:1 for det in activeDetectors.split(',') } +activeDetectors = { det:1 for det in activeDetectors.split(',') if det not in args.skipModules and det not in args.skipReadout} for det in activeDetectors: activate_detector(det) +for det in args.skipModules: + print(f"Skipping detector {det} in simulation") + deactivate_detector(det) + +# function to finalize detector source lists based on activeDetectors +# detector source lists are comma separated lists of DET1, DET2, DET1-DET2, ... +def cleanDetectorInputList(inputlist): + if inputlist == "all": + return inputlist + sources_list = inputlist.split(",") + # Filter the sources + filtered_sources = [ + src for src in sources_list + if all(isActive(part) for part in src.split("-")) + ] + # Recompose into a comma-separated string + return ",".join(filtered_sources) if not args.with_ZDC: # deactivate to be able to use isActive consistently for ZDC @@ -358,7 +440,9 @@ def extractVertexArgs(configKeyValuesStr, finalDiamondDict): NTIMEFRAMES=int(args.tf) NWORKERS=args.n_workers -MODULES = "--skipModules ZDC" if not isActive("ZDC") else "" + + +SKIPMODULES = " ".join(["--skipModules"] + args.skipModules) if len(args.skipModules) > 0 else "" SIMENGINE=args.e BFIELD=args.field RNDSEED=args.seed # typically the argument should be the jobid, but if we get None the current time is used for the initialisation @@ -389,40 +473,28 @@ def extractVertexArgs(configKeyValuesStr, finalDiamondDict): PTHATMIN=float(args.ptHatMin) PTHATMAX=float(args.ptHatMax) -# translate here collision type to PDG +colsys = {'pp':[2212,2212], 'pPb':[2212,1000822080], 'Pbp':[1000822080,2212], 'PbPb':[1000822080,1000822080], 'pO':[2212,1000080160], 'Op':[1000080160,2212], 'HeO':[1000020040,1000080160], 'OHe':[1000080160,1000020040], 'OO':[1000080160,1000080160], 'NeNe':[1000100200,1000100200]} +# translate here collision type to PDG of allowed particles COLTYPE=args.col +if COLTYPE in colsys.keys(): + PDGA=colsys[COLTYPE][0] + PDGB=colsys[COLTYPE][1] +else: + print('o2dpg_sim_workflow: Error! Unknown collision system %s' % COLTYPE) + exit(1) doembedding=True if args.embedding=='True' or args.embedding==True else False -if COLTYPE == 'pp': - PDGA=2212 # proton - PDGB=2212 # proton - -if COLTYPE == 'PbPb': - PDGA=1000822080 # Pb - PDGB=1000822080 # Pb - if ECMS < 0: # assign 5.02 TeV to Pb-Pb - print('o2dpg_sim_workflow: Set CM Energy to PbPb case 5.02 TeV') - ECMS=5020.0 - -if COLTYPE == 'pPb': - PDGA=2212 # proton - PDGB=1000822080 # Pb - -if COLTYPE == 'Pbp': - PDGA=1000822080 # Pb - PDGB=2212 # proton - # If not set previously, set beam energy B equal to A if EBEAMB < 0 and ECMS < 0: EBEAMB=EBEAMA print('o2dpg_sim_workflow: Set beam energy same in A and B beams') - if COLTYPE=="pPb" or COLTYPE=="Pbp": - print('o2dpg_sim_workflow: Careful! both beam energies are the same') + if PDGA != PDGB: + print('o2dpg_sim_workflow: Careful! Set same energies for different particle beams!') if ECMS > 0: - if COLTYPE=="pPb" or COLTYPE=="Pbp": - print('o2dpg_sim_workflow: Careful! ECM set for pPb/Pbp collisions!') + if PDGA != PDGB: + print('o2dpg_sim_workflow: Careful! ECM set for for different particle beams!') if ECMS < 0 and EBEAMA < 0 and EBEAMB < 0: print('o2dpg_sim_workflow: Error! CM or Beam Energy not set!!!') @@ -449,12 +521,27 @@ def extractVertexArgs(configKeyValuesStr, finalDiamondDict): workflow['stages'].append(globalinittask) #### -def getDPL_global_options(bigshm=False, ccdbbackend=True): - common=" -b --run " +usebkgcache=args.use_bkg_from!=None +includeFullQC=args.include_qc=='True' or args.include_qc==True +includeLocalQC=args.include_local_qc=='True' or args.include_local_qc==True +includeAnalysis = args.include_analysis +includeTPCResiduals=True if environ.get('ALIEN_JDL_DOTPCRESIDUALEXTRACTION') == '1' else False +includeTPCSyncMode=True if environ.get('ALIEN_JDL_DOTPCSYNCMODE') == '1' else False + +qcdir = "QC" +if (includeLocalQC or includeFullQC) and not isdir(qcdir): + mkdir(qcdir) + +def getDPL_global_options(bigshm=False, ccdbbackend=True, runcommand=True): + common=" " + if runcommand: + common=common + ' -b --run ' if len(args.dpl_child_driver) > 0: common=common + ' --child-driver ' + str(args.dpl_child_driver) if ccdbbackend: common=common + " --condition-not-after " + str(args.condition_not_after) + if ccdbRemap != None: + common=common + f" --condition-remap {quote_if_needed(ccdbRemap)} " if args.noIPC!=None: return common + " --no-IPC " if bigshm: @@ -462,21 +549,62 @@ def getDPL_global_options(bigshm=False, ccdbbackend=True): else: return common -usebkgcache=args.use_bkg_from!=None -includeFullQC=args.include_qc=='True' or args.include_qc==True -includeLocalQC=args.include_local_qc=='True' or args.include_local_qc==True -includeAnalysis = args.include_analysis -qcdir = "QC" -if (includeLocalQC or includeFullQC) and not isdir(qcdir): - mkdir(qcdir) +# prefetch the aligned geometry object (for use in reconstruction) +GEOM_PREFETCH_TASK = createTask(name='geomprefetch', cpu='0') +# We need to query the config if this is done with or without parallel world. This needs to be improved +# as it could be defaulted in the ConfigKey system +with_parallel_world = 1 if args.confKey.find("useParallelWorld=1") != -1 else 0 +geom_cmd = f''' +# -- Create aligned geometry using ITS ideal alignment to avoid overlaps in geant +ENABLEPW={with_parallel_world} + +# when parallel world processing is disabled we need to switch off ITS alignment +if [ "${{ENABLEPW}}" == "0" ]; then + CCDBOBJECTS_IDEAL_MC="ITS/Calib/Align" + TIMESTAMP_IDEAL_MC=1 + ${{O2_ROOT}}/bin/o2-ccdb-downloadccdbfile --host http://alice-ccdb.cern.ch/ -p ${{CCDBOBJECTS_IDEAL_MC}} \ + -d ${{ALICEO2_CCDB_LOCALCACHE}} --timestamp ${{TIMESTAMP_IDEAL_MC}} + CCDB_RC="$?" + if [ ! "${{CCDB_RC}}" == "0" ]; then + echo "Problem during CCDB prefetching of ${{CCDBOBJECTS_IDEAL_MC}}. Exiting." + exit ${{CCDB_RC}} + fi +fi + +if [ "$ENABLEPW" == "0" ]; then + REMAP_OPT="--condition-remap=file://${{ALICEO2_CCDB_LOCALCACHE}}=ITS/Calib/Align" +else + REMAP_OPT="" +fi + +# fetch the global alignment geometry +${{O2_ROOT}}/bin/o2-create-aligned-geometry-workflow ${{ALIEN_JDL_CCDB_CONDITION_NOT_AFTER:+--condition-not-after $ALIEN_JDL_CCDB_CONDITION_NOT_AFTER}} \ + --configKeyValues "HBFUtils.startTime={args.timestamp}" -b --run ${{REMAP_OPT}} + +# copy the object into the CCDB cache +mkdir -p $ALICEO2_CCDB_LOCALCACHE/GLO/Config/GeometryAligned +ln -s -f $PWD/o2sim_geometry-aligned.root $ALICEO2_CCDB_LOCALCACHE/GLO/Config/GeometryAligned/snapshot.root +if [ "$ENABLEPW" == "0" ]; then + [[ -f $PWD/its_GeometryTGeo.root ]] && mkdir -p $ALICEO2_CCDB_LOCALCACHE/ITS/Config/Geometry && ln -s -f $PWD/its_GeometryTGeo.root $ALICEO2_CCDB_LOCALCACHE/ITS/Config/Geometry/snapshot.root +fi + +# MFT +[[ -f $PWD/mft_GeometryTGeo.root ]] && mkdir -p $ALICEO2_CCDB_LOCALCACHE/MFT/Config/Geometry && ln -s -f $PWD/mft_GeometryTGeo.root $ALICEO2_CCDB_LOCALCACHE/MFT/Config/Geometry/snapshot.root +''' + +with open("geomprefetcher_script.sh",'w') as f: + f.write(geom_cmd) +GEOM_PREFETCH_TASK['cmd'] = 'chmod +x ${PWD}/geomprefetcher_script.sh; ${PWD}/geomprefetcher_script.sh' +workflow['stages'].append(GEOM_PREFETCH_TASK) + # create/publish the GRPs and other GLO objects for consistent use further down the pipeline orbitsPerTF=int(args.orbitsPerTF) -GRP_TASK = createTask(name='grpcreate', cpu='0') +GRP_TASK = createTask(name='grpcreate', needs=["geomprefetch"], cpu='0') GRP_TASK['cmd'] = 'o2-grp-simgrp-tool createGRPs --timestamp ' + str(args.timestamp) + ' --run ' + str(args.run) + ' --publishto ${ALICEO2_CCDB_LOCALCACHE:-.ccdb} -o grp --hbfpertf ' + str(orbitsPerTF) + ' --field ' + args.field -GRP_TASK['cmd'] += ' --readoutDets ' + " ".join(activeDetectors) + ' --print ' + ('','--lhcif-CCDB')[args.run_anchored] -if (not args.run_anchored == True) and len(args.bcPatternFile) > 0: +GRP_TASK['cmd'] += ' --detectorList ' + args.detectorList + ' --readoutDets ' + " ".join(activeDetectors) + ' --print ' + ('','--lhcif-CCDB')[args.run_anchored] +if len(args.bcPatternFile) > 0: GRP_TASK['cmd'] += ' --bcPatternFile ' + str(args.bcPatternFile) if len(CONFKEYMV) > 0: # this is allowing the possibility to setup/use a different MeanVertex object than the one from CCDB @@ -484,19 +612,32 @@ def getDPL_global_options(bigshm=False, ccdbbackend=True): workflow['stages'].append(GRP_TASK) -includeQED = (COLTYPE == 'PbPb' or (doembedding and COLTYPEBKG == "PbPb")) or (args.with_qed == True) +# QED is enabled only for same beam species for now +QED_enabled = True if (PDGA==PDGB and PDGA!=2212) else False +includeQED = (QED_enabled or (doembedding and QED_enabled)) or (args.with_qed == True) signalprefix='sgn' # No vertexing for event pool generation; otherwise the vertex comes from CCDB and later from CollContext # (Note that the CCDB case covers the kDiamond case, since this is picked up in GRP_TASK) vtxmode_precoll = 'kNoVertex' if args.make_evtpool else 'kCCDB' -vtxmode_sgngen = 'kCollContext' +vtxmode_sgngen = 'kNoVertex' if args.make_evtpool else 'kCollContext' # preproduce the collision context / timeframe structure for all timeframes at once precollneeds=[GRP_TASK['name']] -NEventsQED=10000 # max number of QED events to simulate per timeframe -PbPbXSec=8. # expected PbPb cross section -QEDXSecExpected=35237.5 # expected magnitude of QED cross section +# max number of QED events simulated per timeframe. +# A large pool of QED events (0.6*INTRATE) is needed to avoid repetition of events in the same or +# neighbouring ITS readout frames, which would fire already activated pixel, discarding the event. +# Discussed in detail in https://its.cern.ch/jira/browse/O2-5861 +NEventsQED = max(10000, int(INTRATE*0.6)) +# Hadronic cross section values are taken from Glauber MC +XSecSys = {'PbPb': 8., 'OO': 1.273, 'NeNe': 1.736} +# QED cross section values were calculated with TEPEMGEN +# OO and NeNe at 5.36 TeV, while the old PbPb value was kept as before +# If the collision energy changes these values need to be updated +# More info on the calculation can be found in the TEPEMGEN folder of AEGIS +# specifically in the epemgen.f file +QEDXSecExpected = {'PbPb': 35237.5, 'OO': 3.17289, 'NeNe': 7.74633} # expected magnitude of QED cross section from TEPEMGEN +Zsys = {'PbPb': 82, 'OO': 8, 'NeNe': 10} # atomic number of colliding species PreCollContextTask=createTask(name='precollcontext', needs=precollneeds, cpu='1') # adapt timeframeID + orbits + seed + qed @@ -506,26 +647,38 @@ def getDPL_global_options(bigshm=False, ccdbbackend=True): if doembedding: interactionspecification = 'bkg,' + str(INTRATE) + ',' + str(NTIMEFRAMES*args.ns) + ':' + str(args.nb) + ' ' + signalprefix + ',' + args.embeddPattern -PreCollContextTask['cmd']='${O2_ROOT}/bin/o2-steer-colcontexttool -i ' + interactionspecification \ - + ' --show-context ' \ - + ' --timeframeID ' + str(int(args.production_offset)*NTIMEFRAMES) \ - + ' --orbitsPerTF ' + str(orbitsPerTF) \ - + ' --orbits ' + str(NTIMEFRAMES * (orbitsPerTF)) \ - + ' --seed ' + str(RNDSEED) \ - + ' --noEmptyTF --first-orbit ' + str(args.first_orbit) \ - + ' --extract-per-timeframe tf:sgn' \ - + ' --with-vertices ' + vtxmode_precoll \ - + ' --maxCollsPerTF ' + str(args.ns) \ - + ' --orbitsEarly ' + str(args.orbits_early) - -PreCollContextTask['cmd'] += ' --bcPatternFile ccdb' # <--- the object should have been set in (local) CCDB +qedspec="" if includeQED: - qedrate = INTRATE * QEDXSecExpected / PbPbXSec # hadronic interaction rate * cross_section_ratio - qedspec = 'qed' + ',' + str(qedrate) + ',10000000:' + str(NEventsQED) - PreCollContextTask['cmd'] += ' --QEDinteraction ' + qedspec + if PDGA==2212 or PDGB==2212: + # QED is not enabled for pp and pA collisions + print('o2dpg_sim_workflow: Warning! QED is not enabled for pp or pA collisions') + includeQED = False + else: + qedrate = INTRATE * QEDXSecExpected[COLTYPE] / XSecSys[COLTYPE] # hadronic interaction rate * cross_section_ratio + qedspec = 'qed' + ',' + str(qedrate) + ',10000000:' + str(NEventsQED) + +PreCollContextTask['cmd'] = task_finalizer([ + '${O2_ROOT}/bin/o2-steer-colcontexttool', + f'-i {interactionspecification}', + '--show-context', + f'--timeframeID {int(args.production_offset)*NTIMEFRAMES}', + f'--orbitsPerTF {orbitsPerTF}', + f'--orbits {NTIMEFRAMES * (orbitsPerTF)}', + f'--seed {RNDSEED}', + '--noEmptyTF', + f'--first-orbit {args.first_orbit}', + '--extract-per-timeframe tf:sgn', + f'--with-vertices {vtxmode_precoll}', + f'--maxCollsPerTF {args.ns}', + f'--orbitsEarly {args.orbits_early}', + f'--timestamp {args.timestamp}', + f'--import-external {args.data_anchoring}' if len(args.data_anchoring) > 0 else None, + '--bcPatternFile ccdb', + ' --nontrivial-mu-distribution ccdb://https://alice-ccdb.cern.ch/FT0/Calib/EventsPerBc', + f'--QEDinteraction {qedspec}' if includeQED else None + ], configname = 'precollcontext') workflow['stages'].append(PreCollContextTask) - if doembedding: if not usebkgcache: # ---- do background transport task ------- @@ -535,18 +688,20 @@ def getDPL_global_options(bigshm=False, ccdbbackend=True): print('o2dpg_sim_workflow: Error! embedding background generator name not provided') exit(1) + # PDG translation for background + if COLTYPEBKG in colsys.keys(): + PDGABKG=colsys[COLTYPEBKG][0] + PDGBBKG=colsys[COLTYPEBKG][1] + else: + print('o2dpg_sim_workflow: Error! Unknown background collision system %s' % COLTYPEBKG) + exit(1) + PROCESSBKG=args.procBkg ECMSBKG=float(args.eCM) EBEAMABKG=float(args.eA) EBEAMBBKG=float(args.eB) - if COLTYPEBKG == 'pp': - PDGABKG=2212 # proton - PDGBBKG=2212 # proton - if COLTYPEBKG == 'PbPb': - PDGABKG=1000822080 # Pb - PDGBBKG=1000822080 # Pb if ECMSBKG < 0: # assign 5.02 TeV to Pb-Pb print('o2dpg_sim_workflow: Set BKG CM Energy to PbPb case 5.02 TeV') ECMSBKG=5020.0 @@ -554,24 +709,16 @@ def getDPL_global_options(bigshm=False, ccdbbackend=True): PROCESSBKG = 'heavy_ion' print('o2dpg_sim_workflow: Process type not considered for Pythia8 PbPb') - if COLTYPEBKG == 'pPb': - PDGABKG=2212 # proton - PDGBBKG=1000822080 # Pb - - if COLTYPEBKG == 'Pbp': - PDGABKG=1000822080 # Pb - PDGBBKG=2212 # proton - # If not set previously, set beam energy B equal to A if EBEAMBBKG < 0 and ECMSBKG < 0: EBEAMBBKG=EBEAMABKG print('o2dpg_sim_workflow: Set beam energy same in A and B beams') - if COLTYPEBKG=="pPb" or COLTYPEBKG=="Pbp": - print('o2dpg_sim_workflow: Careful! both beam energies in bkg are the same') + if PDGABKG != PDGBBKG: + print('o2dpg_sim_workflow: Careful! Set same energies for different background beams!') if ECMSBKG > 0: - if COLTYPEBKG=="pPb" or COLTYPEBKG=="Pbp": - print('o2dpg_sim_workflow: Careful! bkg ECM set for pPb/Pbp collisions!') + if PDGABKG != PDGBBKG: + print('o2dpg_sim_workflow: Careful! ECM set for different background beams!') if ECMSBKG < 0 and EBEAMABKG < 0 and EBEAMBBKG < 0: print('o2dpg_sim_workflow: Error! bkg ECM or Beam Energy not set!!!') @@ -608,11 +755,12 @@ def getDPL_global_options(bigshm=False, ccdbbackend=True): bkgsimneeds = [BKG_CONFIG_task['name'], GRP_TASK['name'], PreCollContextTask['name']] BKGtask=createTask(name='bkgsim', lab=["GEANT"], needs=bkgsimneeds, cpu=NWORKERS) BKGtask['cmd']='${O2_ROOT}/bin/o2-sim -e ' + SIMENGINE + ' -j ' + str(NWORKERS) + ' -n ' + str(NBKGEVENTS) \ - + ' -g ' + str(GENBKG) + ' ' + str(MODULES) + ' -o bkg ' + str(INIBKG) \ + + ' -g ' + str(GENBKG) + ' ' + str(SKIPMODULES) + ' -o bkg ' + str(INIBKG) \ + ' --field ccdb ' + str(CONFKEYBKG) \ + ('',' --timestamp ' + str(args.timestamp))[args.timestamp!=-1] + ' --run ' + str(args.run) \ - + ' --vertexMode kCCDB' \ - + ' --fromCollContext collisioncontext.root:bkg' + + ' --vertexMode ' + vtxmode_sgngen \ + + ' --fromCollContext collisioncontext.root:bkg ' \ + + ' --detectorList ' + args.detectorList if not isActive('all'): BKGtask['cmd'] += ' --readoutDetectors ' + " ".join(activeDetectors) @@ -646,6 +794,9 @@ def getDPL_global_options(bigshm=False, ccdbbackend=True): # a list of smaller sensors (used to construct digitization tasks in a parametrized way) smallsensorlist = [ "ITS", "TOF", "FDD", "MCH", "MID", "MFT", "HMP", "PHS", "CPV", "ZDC" ] +if args.detectorList == 'ALICE2.1': + smallsensorlist = ['IT3' if sensor == 'ITS' else sensor for sensor in smallsensorlist] + # a list of detectors that serve as input for the trigger processor CTP --> these need to be processed together for now ctp_trigger_inputlist = [ "FT0", "FV0", "EMC" ] @@ -667,14 +818,6 @@ def getDPL_global_options(bigshm=False, ccdbbackend=True): # We download some binary files, necessary for processing # Eventually, these files/objects should be queried directly from within these tasks? -# We download trivial TPC space charge corrections to be applied during -# reco. This is necessary to have consistency (decalibration and calibration) between digitization and reconstruction ... until digitization can -# also apply this effect via CCDB. -TPC_SPACECHARGE_DOWNLOADER_TASK = createTask(name='tpc_spacecharge_downloader', cpu='0') -TPC_SPACECHARGE_DOWNLOADER_TASK['cmd'] = '[ "${O2DPG_ENABLE_TPC_DISTORTIONS}" ] || { ${O2_ROOT}/bin/o2-ccdb-downloadccdbfile --host http://alice-ccdb.cern.ch -p TPC/Calib/CorrectionMapRef --timestamp 1 --created-not-after ' + str(args.condition_not_after) + ' -d ${ALICEO2_CCDB_LOCALCACHE} ; ' \ - '${O2_ROOT}/bin/o2-ccdb-downloadccdbfile --host http://alice-ccdb.cern.ch -p TPC/Calib/CorrectionMap --timestamp 1 --created-not-after ' + str(args.condition_not_after) + ' -d ${ALICEO2_CCDB_LOCALCACHE} ; }' -workflow['stages'].append(TPC_SPACECHARGE_DOWNLOADER_TASK) - # Fix (residual) geometry alignment for simulation stage # Detectors that prefer to apply special alignments (for example residual effects) should be listed here and download these files. # These object will take precedence over ordinary align objects **and** will only be applied in transport simulation @@ -700,7 +843,6 @@ def getDPL_global_options(bigshm=False, ccdbbackend=True): QEDdigiargs = "" if includeQED: - NEventsQED=10000 # 35K for a full timeframe? qedneeds=[GRP_TASK['name'], PreCollContextTask['name']] QED_task=createTask(name='qedsim_'+str(tf), needs=qedneeds, tf=tf, cwd=timeframeworkdir, cpu='1') ######################################################################################################## @@ -708,19 +850,28 @@ def getDPL_global_options(bigshm=False, ccdbbackend=True): # ATTENTION: CHANGING THE PARAMETERS/CUTS HERE MIGHT INVALIDATE THE QED INTERACTION RATES USED ELSEWHERE # ######################################################################################################## + + # determine final conf key for QED simulation + QEDBaseConfig = "GeneratorExternal.fileName=$O2_ROOT/share/Generators/external/QEDLoader.C;QEDGenParam.yMin=-7;QEDGenParam.yMax=7;QEDGenParam.ptMin=0.001;QEDGenParam.ptMax=1.;QEDGenParam.xSectionHad="+str(XSecSys[COLTYPE])+";QEDGenParam.Z="+str(Zsys[COLTYPE])+";QEDGenParam.cmEnergy="+str(ECMS)+";Diamond.width[2]=6.;" + QEDCONFKEY = constructConfigKeyArg(create_geant_config(args, QEDBaseConfig + args.confKeyQED)) + qed_detectorlist = ' ITS MFT FT0 FV0 FDD ' + if args.detectorList == 'ALICE2.1': + qed_detectorlist = qed_detectorlist.replace('ITS', 'IT3') QED_task['cmd'] = 'o2-sim -e TGeant3 --field ccdb -j ' + str('1') + ' -o qed' \ - + ' -n ' + str(NEventsQED) + ' -m PIPE ITS MFT FT0 FV0 FDD ' \ + + ' -n ' + str(NEventsQED) + ' -m ' + qed_detectorlist \ + ('', ' --timestamp ' + str(args.timestamp))[args.timestamp!=-1] + ' --run ' + str(args.run) \ + ' --seed ' + str(TFSEED) \ - + ' -g extgen --configKeyValues \"GeneratorExternal.fileName=$O2_ROOT/share/Generators/external/QEDLoader.C;QEDGenParam.yMin=-7;QEDGenParam.yMax=7;QEDGenParam.ptMin=0.001;QEDGenParam.ptMax=1.;Diamond.width[2]=6.\"' # + ' --fromCollContext collisioncontext.root' + + ' -g extgen ' \ + + ' --detectorList ' + args.detectorList + ' ' \ + + QEDCONFKEY QED_task['cmd'] += '; RC=$?; QEDXSecCheck=`grep xSectionQED qedgenparam.ini | sed \'s/xSectionQED=//\'`' - QED_task['cmd'] += '; echo "CheckXSection ' + str(QEDXSecExpected) + ' = $QEDXSecCheck"; [[ ${RC} == 0 ]]' + QED_task['cmd'] += '; echo "CheckXSection ' + str(QEDXSecExpected[COLTYPE]) + ' = $QEDXSecCheck"; [[ ${RC} == 0 ]]' # TODO: propagate the Xsecion ratio dynamically - QEDdigiargs=' --simPrefixQED qed' + ' --qed-x-section-ratio ' + str(QEDXSecExpected/PbPbXSec) + QEDdigiargs=' --simPrefixQED qed' + ' --qed-x-section-ratio ' + str(QEDXSecExpected[COLTYPE]/XSecSys[COLTYPE]) workflow['stages'].append(QED_task) # recompute the number of workers to increase CPU efficiency - NWORKERS_TF = compute_n_workers(INTRATE, COLTYPE) if (not args.force_n_workers) else NWORKERS + NWORKERS_TF = compute_n_workers(INTRATE, COLTYPE, n_workers_user = NWORKERS) if (not args.force_n_workers) else NWORKERS # produce the signal configuration SGN_CONFIG_task=createTask(name='gensgnconf_'+str(tf), tf=tf, cwd=timeframeworkdir) @@ -815,6 +966,7 @@ def getDPL_global_options(bigshm=False, ccdbbackend=True): + ' -g ' + str(GENERATOR) + ' ' + str(INIFILE) + ' -o genevents ' + embeddinto \ + ('', ' --timestamp ' + str(args.timestamp))[args.timestamp!=-1] \ + ' --seed ' + str(TFSEED) + ' -n ' + str(NSIGEVENTS) \ + + ' --detectorList ' + args.detectorList \ + ' --fromCollContext collisioncontext.root:' + signalprefix if GENERATOR=="hepmc": SGNGENtask['cmd'] += "; RC=$?; ${O2DPG_ROOT}/UTILS/UpdateHepMCEventSkip.sh ../HepMCEventSkip.json " + str(tf) + '; [[ ${RC} == 0 ]]' @@ -834,8 +986,9 @@ def getDPL_global_options(bigshm=False, ccdbbackend=True): sgnmem = 6000 if COLTYPE == 'PbPb' else 4000 SGNtask=createTask(name='sgnsim_'+str(tf), needs=signalneeds, tf=tf, cwd='tf'+str(tf), lab=["GEANT"], relative_cpu=7/8, n_workers=NWORKERS_TF, mem=str(sgnmem)) - sgncmdbase = '${O2_ROOT}/bin/o2-sim -e ' + str(SIMENGINE) + ' ' + str(MODULES) + ' -n ' + str(NSIGEVENTS) + ' --seed ' + str(TFSEED) \ + sgncmdbase = '${O2_ROOT}/bin/o2-sim -e ' + str(SIMENGINE) + ' ' + str(SKIPMODULES) + ' -n ' + str(NSIGEVENTS) + ' --seed ' + str(TFSEED) \ + ' --field ccdb -j ' + str(NWORKERS_TF) + ' ' + str(CONFKEY) + ' ' + str(INIFILE) + ' -o ' + signalprefix + ' ' + embeddinto \ + + ' --detectorList ' + args.detectorList \ + ('', ' --timestamp ' + str(args.timestamp))[args.timestamp!=-1] + ' --run ' + str(args.run) if sep_event_mode: SGNtask['cmd'] = sgncmdbase + ' -g extkinO2 --extKinFile genevents_Kine.root ' + ' --vertexMode kNoVertex' @@ -906,41 +1059,25 @@ def getDPL_global_options(bigshm=False, ccdbbackend=True): if (args.sor != -1): globalTFConfigValues["HBFUtils.startTime"] = args.sor - def putConfigValues(localCF = {}): - """ - Creates the final --configValues string to be passed to the workflows. - Uses the globalTFConfigValues and merges/overrides them with the local settings. - localCF is supposed to be a dictionary mapping key to param - """ - returnstring = ' --configKeyValues "' - cf = globalTFConfigValues.copy() - isfirst=True - for e in localCF: - cf[e] = localCF[e] - - for e in cf: - returnstring += (';','')[isfirst] + str(e) + "=" + str(cf[e]) - isfirst=False - - returnstring = returnstring + '"' - return returnstring - - def putConfigValuesNew(listOfMainKeys=[], localCF = {}): + def putConfigValues(listOfMainKeys=[], localCF = {}, globalTFConfig = True): """ Creates the final --configValues string to be passed to the workflows. Uses the globalTFConfigValues and applies other parameters on top listOfMainKeys : list of keys to be applied from the global configuration object localCF: a dictionary mapping key to param - possibly overrides settings taken from global config """ - returnstring = ' --configKeyValues "' - cf = globalTFConfigValues.copy() + returnstring = ' --configKeyValues "' + cf = globalTFConfigValues.copy() if globalTFConfig else {} isfirst=True # now bring in the relevant keys # from the external config for key in listOfMainKeys: - # it this key exists + # try to find key flat in dict (backward compatible) keydict = anchorConfig.get(key) + if keydict == None: + # try to find under the ConfigurableKey entry (standard) + keydict = anchorConfig.get("ConfigParams",{}).get(key) if keydict != None: for k in keydict: cf[key+"."+k] = keydict[k] @@ -969,7 +1106,7 @@ def putConfigValuesNew(listOfMainKeys=[], localCF = {}): ContextTask['cmd'] = '${O2_ROOT}/bin/o2-sim-digitizer-workflow --only-context --interactionRate ' + str(INTRATE) \ + ' ' + getDPL_global_options(ccdbbackend=False) + ' -n ' + str(args.ns) + simsoption \ + ' --seed ' + str(TFSEED) \ - + ' ' + putConfigValuesNew({"DigiParams.maxOrbitsToDigitize" : str(orbitsPerTF)},{"DigiParams.passName" : str(PASSNAME)}) \ + + ' ' + putConfigValues({"DigiParams.maxOrbitsToDigitize" : str(orbitsPerTF)},{"DigiParams.passName" : str(PASSNAME)}) \ + ' --incontext ' + CONTEXTFILE + QEDdigiargs ContextTask['cmd'] += ' --bcPatternFile ccdb' workflow['stages'].append(ContextTask) @@ -978,34 +1115,39 @@ def putConfigValuesNew(listOfMainKeys=[], localCF = {}): CTPSCALER = args.ctp_scaler tpcDistortionType=args.tpc_distortion_type print(f"TPC distortion simulation: type = {tpcDistortionType}, CTP scaler value {CTPSCALER}"); - tpcdigineeds=[ContextTask['name'], LinkGRPFileTask['name'], TPC_SPACECHARGE_DOWNLOADER_TASK['name']] + tpcdigineeds=[ContextTask['name'], LinkGRPFileTask['name']] if usebkgcache: tpcdigineeds += [ BKG_HITDOWNLOADER_TASKS['TPC']['name'] ] tpcLocalCF={"DigiParams.maxOrbitsToDigitize" : str(orbitsPerTF), "DigiParams.seed" : str(TFSEED)} + # force TPC common mode correction in all cases to avoid issues the CMk values stored in the CCDB + tpcLocalCF['TPCEleParam.DigiMode'] = str(2) # 2 = o2::tpc::DigitzationMode::ZeroSuppressionCMCorr from TPCBase/ParameterElectronics.h + # handle distortions and scaling using MC maps # this assumes the lumi inside the maps is stored in FT0 (pp) scalers # in case of PbPb the conversion factor ZDC ->FT0 (pp) must be taken into account in the scalers if tpcDistortionType == 2 and CTPSCALER <= 0: print('Warning: lumi scaling requested, but no ctp scaler value set. Full map will be applied at face value.') tpcDistortionType=1 - lumiInstFactor=1 if COLTYPE == 'PbPb': lumiInstFactor=2.414 - if tpcDistortionType == 2: tpcLocalCF['TPCCorrMap.lumiInst'] = str(CTPSCALER * lumiInstFactor) + tpcdigimem = 12000 if havePbPb else 9000 TPCDigitask=createTask(name='tpcdigi_'+str(tf), needs=tpcdigineeds, tf=tf, cwd=timeframeworkdir, lab=["DIGI"], cpu=NWORKERS_TF, mem=str(tpcdigimem)) TPCDigitask['cmd'] = ('','ln -nfs ../bkg_HitsTPC.root . ;')[doembedding] - TPCDigitask['cmd'] += '${O2_ROOT}/bin/o2-sim-digitizer-workflow ' + getDPL_global_options() + ' -n ' + str(args.ns) + simsoption \ + TPCDigitask['cmd'] += '${O2_ROOT}/bin/o2-ccdb-downloadccdbfile --host http://alice-ccdb.cern.ch -p TPC/Config/RunInfoV2 --timestamp ' \ + + str(args.timestamp) + ' --created-not-after ' + str(args.condition_not_after) + ' -d ${ALICEO2_CCDB_LOCALCACHE} ; ' + TPCDigitask['cmd'] += '${O2_ROOT}/bin/o2-sim-digitizer-workflow ' + getDPL_global_options(bigshm=True) + ' -n ' + str(args.ns) + simsoption \ + ' --onlyDet TPC --TPCuseCCDB --interactionRate ' + str(INTRATE) + ' --tpc-lanes ' + str(NWORKERS_TF) \ + ' --incontext ' + str(CONTEXTFILE) + ' --disable-write-ini --early-forward-policy always --forceSelectedDets ' \ + ' --tpc-distortion-type ' + str(tpcDistortionType) \ - + putConfigValuesNew(["TPCGasParam","TPCGEMParam","TPCEleParam","TPCITCorr","TPCDetParam"], + + ' --n-threads-distortions 1 ' \ + + putConfigValues(["TPCGasParam","TPCGEMParam","TPCEleParam","TPCITCorr","TPCDetParam"], localCF=tpcLocalCF) TPCDigitask['cmd'] += (' --tpc-chunked-writer','')[args.no_tpc_digitchunking] TPCDigitask['cmd'] += ('',' --disable-mc')[args.no_mc_labels] @@ -1023,9 +1165,10 @@ def putConfigValuesNew(listOfMainKeys=[], localCF = {}): TRDDigitask['cmd'] = ('','ln -nfs ../bkg_HitsTRD.root . ;')[doembedding] TRDDigitask['cmd'] += '${O2_ROOT}/bin/o2-sim-digitizer-workflow ' + getDPL_global_options() + ' -n ' + str(args.ns) + simsoption \ + ' --onlyDet TRD --interactionRate ' + str(INTRATE) + ' --incontext ' + str(CONTEXTFILE) + ' --disable-write-ini' \ - + putConfigValuesNew(localCF={"TRDSimParams.digithreads" : NWORKERS_TF, "DigiParams.seed" : str(TFSEED)}) + " --forceSelectedDets" + + putConfigValues(localCF={"TRDSimParams.digithreads" : NWORKERS_TF, "DigiParams.seed" : str(TFSEED)}) + " --forceSelectedDets" TRDDigitask['cmd'] += ('',' --disable-mc')[args.no_mc_labels] - workflow['stages'].append(TRDDigitask) + if isActive("TRD"): + workflow['stages'].append(TRDDigitask) # these are digitizers which are single threaded def createRestDigiTask(name, det='ALLSMALLER'): @@ -1034,7 +1177,7 @@ def createRestDigiTask(name, det='ALLSMALLER'): tneeds += [QED_task['name']] commondigicmd = '${O2_ROOT}/bin/o2-sim-digitizer-workflow ' + getDPL_global_options() + ' -n ' + str(args.ns) + simsoption \ + ' --interactionRate ' + str(INTRATE) + ' --incontext ' + str(CONTEXTFILE) + ' --disable-write-ini' \ - + putConfigValuesNew(["MFTAlpideParam", "ITSAlpideParam", "ITSDigitizerParam"], + + putConfigValues(["MFTAlpideParam", "ITSAlpideParam", "ITSDigitizerParam" if args.detectorList == 'ALICE2' else "IT3DigitizerParam"], localCF={"DigiParams.seed" : str(TFSEED), "MCHDigitizer.seed" : str(TFSEED)}) + QEDdigiargs if det=='ALLSMALLER': # here we combine all smaller digits in one DPL workflow @@ -1046,6 +1189,7 @@ def createRestDigiTask(name, det='ALLSMALLER'): t['cmd'] = ('','ln -nfs ../bkg_Hits*.root . ;')[doembedding] detlist = '' detlist = ','.join(smallsensorlist) + detlist = cleanDetectorInputList(detlist) t['cmd'] += commondigicmd + ' --onlyDet ' + detlist t['cmd'] += ' --ccdb-tof-sa --forceSelectedDets ' t['cmd'] += (' --combine-devices ','')[args.no_combine_dpl_devices] @@ -1076,18 +1220,29 @@ def createRestDigiTask(name, det='ALLSMALLER'): det_to_digitask[det]=t # detectors serving CTP need to be treated somewhat special since CTP needs - # these inputs at the same time --> still need to be made better + # these inputs at the same time --> still need to be made better. tneeds = [ContextTask['name']] if includeQED: tneeds += [QED_task['name']] FT0FV0EMCCTPDIGItask = createTask(name="ft0fv0emcctp_digi_" + str(tf), needs=tneeds, - tf=tf, cwd=timeframeworkdir, lab=["DIGI","SMALLDIGI"], cpu='1') + tf=tf, cwd=timeframeworkdir, lab=["DIGI","SMALLDIGI"], cpu='1') FT0FV0EMCCTPDIGItask['cmd'] = ('','ln -nfs ../bkg_HitsFT0.root . ; ln -nfs ../bkg_HitsFV0.root . ; ln -nfs ../bkg_HitsEMC.root; ln -nfs ../bkg_Kine.root; ')[doembedding] - FT0FV0EMCCTPDIGItask['cmd'] += '${O2_ROOT}/bin/o2-sim-digitizer-workflow ' + getDPL_global_options() + ' -n ' + str(args.ns) + simsoption \ - + ' --onlyDet FT0,FV0,EMC,CTP --interactionRate ' + str(INTRATE) + ' --incontext ' + str(CONTEXTFILE) \ - + ' --disable-write-ini' + putConfigValuesNew(listOfMainKeys=['EMCSimParam'], localCF={"DigiParams.seed" : str(TFSEED)}) \ - + (' --combine-devices','')[args.no_combine_dpl_devices] + ('',' --disable-mc')[args.no_mc_labels] + QEDdigiargs \ - + ' --forceSelectedDets' + FT0FV0EMCCTPDIGItask['cmd'] += task_finalizer([ + '${O2_ROOT}/bin/o2-sim-digitizer-workflow', + getDPL_global_options(), + f'-n {args.ns}', + simsoption, + '--onlyDet ' + ','.join([det for det in ['FT0', 'FV0', 'EMC', 'CTP'] if isActive(det)]), + f'--interactionRate {INTRATE}', + f'--incontext {CONTEXTFILE}', + f'--store-ctp-lumi {CTPSCALER}', + '--disable-write-ini', + putConfigValues(listOfMainKeys=['EMCSimParam','FV0DigParam','FT0DigParam'], localCF={"DigiParams.seed" : str(TFSEED)}), + ('--combine-devices','')[args.no_combine_dpl_devices], + ('',' --disable-mc')[args.no_mc_labels], + QEDdigiargs, + '--forceSelectedDets'], configname = 'ft0fv0emcctp_digi') + workflow['stages'].append(FT0FV0EMCCTPDIGItask) det_to_digitask["FT0"]=FT0FV0EMCCTPDIGItask det_to_digitask["FV0"]=FT0FV0EMCCTPDIGItask @@ -1104,6 +1259,7 @@ def getDigiTaskName(det): # reco # ----------- tpcreconeeds=[FT0FV0EMCCTPDIGItask['name']] + tpcclusterneed=[TPCDigitask['name'], FT0FV0EMCCTPDIGItask['name']] if not args.combine_tpc_clusterization: # We treat TPC clusterization in multiple (sector) steps in order to # stay within the memory limit or to parallelize over sector from outside (not yet supported within cluster algo) @@ -1112,10 +1268,25 @@ def getDigiTaskName(det): for s in range(0,35,sectorpertask): taskname = 'tpcclusterpart' + str((int)(s/sectorpertask)) + '_' + str(tf) tpcclustertasks.append(taskname) - tpcclussect = createTask(name=taskname, needs=[TPCDigitask['name']], tf=tf, cwd=timeframeworkdir, lab=["RECO"], cpu='2', mem='8000') + tpcclussect = createTask(name=taskname, needs=tpcclusterneed, tf=tf, cwd=timeframeworkdir, lab=["RECO"], cpu='2', mem='8000') digitmergerstr = '${O2_ROOT}/bin/o2-tpc-chunkeddigit-merger --tpc-sectors ' + str(s)+'-'+str(s+sectorpertask-1) + ' --tpc-lanes ' + str(NWORKERS_TF) + ' | ' - tpcclussect['cmd'] = (digitmergerstr,'')[args.no_tpc_digitchunking] + ' ${O2_ROOT}/bin/o2-tpc-reco-workflow ' + getDPL_global_options(bigshm=True) + ' --input-type ' + ('digitizer','digits')[args.no_tpc_digitchunking] + ' --output-type clusters,send-clusters-per-sector --tpc-native-cluster-writer \" --outfile tpc-native-clusters-part'+ str((int)(s/sectorpertask)) + '.root\" --tpc-sectors ' + str(s)+'-'+str(s+sectorpertask-1) + ' ' + putConfigValuesNew(["GPU_global"], {"GPU_proc.ompThreads" : 4}) + ('',' --disable-mc')[args.no_mc_labels] - tpcclussect['env'] = { "OMP_NUM_THREADS" : "4" } + tpcclussect['cmd'] = (digitmergerstr,'')[args.no_tpc_digitchunking] + task_finalizer( + [ + '${O2_ROOT}/bin/o2-tpc-reco-workflow', + getDPL_global_options(bigshm=True), + '--input-type ' + ('digitizer','digits')[args.no_tpc_digitchunking], + '--output-type clusters,send-clusters-per-sector', + f'--tpc-native-cluster-writer \" --outfile tpc-native-clusters-part{(int)(s/sectorpertask)}.root\"', + f'--tpc-sectors {s}-{s+sectorpertask-1}', + putConfigValues(["GPU_global", + "GPU_proc_nn", + "TPCCorrMap", + "TPCGasParam"], {"GPU_proc.ompThreads" : 4}), + '--disable-mc' if args.no_mc_labels else None + ], configname="tpcclusterizertask" + ) + + tpcclussect['env'] = { "OMP_NUM_THREADS" : "4" , "TBB_NUM_THREADS" : "4" } tpcclussect['semaphore'] = "tpctriggers.root" tpcclussect['retry_count'] = 2 # the task has a race condition --> makes sense to retry workflow['stages'].append(tpcclussect) @@ -1125,9 +1296,10 @@ def getDigiTaskName(det): workflow['stages'].append(TPCCLUSMERGEtask) tpcreconeeds.append(TPCCLUSMERGEtask['name']) else: - tpcclus = createTask(name='tpccluster_' + str(tf), needs=[TPCDigitask['name']], tf=tf, cwd=timeframeworkdir, lab=["RECO"], cpu=NWORKERS_TF, mem='2000') + # TODO: adapt this to the case above and merge code / avoid code duplication + tpcclus = createTask(name='tpccluster_' + str(tf), needs=tpcclusterneed, tf=tf, cwd=timeframeworkdir, lab=["RECO"], cpu=NWORKERS_TF, mem='2000') tpcclus['cmd'] = '${O2_ROOT}/bin/o2-tpc-chunkeddigit-merger --tpc-lanes ' + str(NWORKERS_TF) - tpcclus['cmd'] += ' | ${O2_ROOT}/bin/o2-tpc-reco-workflow ' + getDPL_global_options() + ' --input-type digitizer --output-type clusters,send-clusters-per-sector ' + putConfigValuesNew(["GPU_global","TPCGasParam","TPCCorrMap"],{"GPU_proc.ompThreads" : 1}) + ('',' --disable-mc')[args.no_mc_labels] + tpcclus['cmd'] += ' | ${O2_ROOT}/bin/o2-tpc-reco-workflow ' + getDPL_global_options() + ' --input-type digitizer --output-type clusters,send-clusters-per-sector ' + putConfigValues(["GPU_global","TPCGasParam","TPCCorrMap"],{"GPU_proc.ompThreads" : 1}) + ('',' --disable-mc')[args.no_mc_labels] workflow['stages'].append(tpcclus) tpcreconeeds.append(tpcclus['name']) @@ -1139,206 +1311,610 @@ def getDigiTaskName(det): # in case of PbPb the conversion factor ZDC ->FT0 (pp) must be set tpc_corr_options_mc='' + tpcCorrmapLumiMode = args.tpc_corrmap_lumi_mode + if tpcDistortionType == 0: # disable distortion corrections tpc_corr_options_mc=' --corrmap-lumi-mode 0 ' tpcLocalCFreco['TPCCorrMap.lumiMean'] = '-1'; elif tpcDistortionType == 1: # disable scaling - tpc_corr_options_mc=' --corrmap-lumi-mode 2 ' + tpc_corr_options_mc=' --corrmap-lumi-mode ' + str(tpcCorrmapLumiMode) + ' ' tpcLocalCFreco['TPCCorrMap.lumiInst'] = str(CTPSCALER) tpcLocalCFreco['TPCCorrMap.lumiMean'] = str(CTPSCALER) elif tpcDistortionType == 2: # full scaling with CTP values if COLTYPE == 'PbPb': tpcLocalCFreco['TPCCorrMap.lumiInstFactor'] = str(lumiInstFactor) - tpc_corr_options_mc=' --corrmap-lumi-mode 2 ' + tpc_corr_options_mc=' --corrmap-lumi-mode ' + str(tpcCorrmapLumiMode) + ' ' tpcLocalCFreco['TPCCorrMap.lumiInst'] = str(CTPSCALER) - # TODO: Is this still used? - tpc_corr_scaling_options = anchorConfig.get('tpc-corr-scaling','') - tpc_envfile = 'env_async.env' if environ.get('ALIEN_JDL_O2DPG_ASYNC_RECO_TAG') is not None else None - TPCRECOtask=createTask(name='tpcreco_'+str(tf), needs=tpcreconeeds, tf=tf, cwd=timeframeworkdir, lab=["RECO"], relative_cpu=3/8, mem='16000') - TPCRECOtask['cmd'] = '${O2_ROOT}/bin/o2-tpc-reco-workflow ' + getDPL_global_options(bigshm=True) + ' --input-type clusters --output-type tracks,send-clusters-per-sector ' \ - + putConfigValuesNew(["GPU_global","TPCGasParam", "TPCCorrMap", "GPU_rec_tpc", "trackTuneParams"], {"GPU_proc.ompThreads":NWORKERS_TF} | tpcLocalCFreco) + ('',' --disable-mc')[args.no_mc_labels] \ - + tpc_corr_scaling_options + tpc_corr_options_mc \ - + option_if_available('o2-tpc-reco-workflow', '--tpc-mc-time-gain', envfile=tpc_envfile) + # Setup the TPC correction scaling options for reco; They come from the anchoring setup + # Some useful comments from Ruben: + # - lumi-type == 0 means no-scaling of corrections with any measure of the lumi rather than no corrections at all. + # - The "no corrections" mode is imposed by the TPCCorrMap.lumiMean configurable being negative, in this case all other options in the corrections treatment are ignored. + # - But if the MC simulation was done with distortions, then the reco needs --lumy-type 1 (i.e. scale with the CTP lumi) even if the corresponding anchor run reco was using --lumy-type 2 + # (i.e. scaling according to the TPC IDC, which don't exist in the MC). + + anchor_lumi_type = dpl_option_from_config(anchorConfig, 'o2-tpcits-match-workflow', '--lumi-type', section = 'full', default_value = '') + if anchor_lumi_type != '': + anchor_lumi_type = '--lumi-type ' + anchor_lumi_type + anchor_corrmaplumi_mode = dpl_option_from_config(anchorConfig, 'o2-tpcits-match-workflow', '--corrmap-lumi-mode', section = 'full', default_value = '') + if anchor_corrmaplumi_mode != '': + anchor_corrmaplumi_mode = '--corrmap-lumi-mode ' + anchor_corrmaplumi_mode - workflow['stages'].append(TPCRECOtask) + tpc_corr_scaling_options = anchor_lumi_type + ' ' + anchor_corrmaplumi_mode + + # why not simply? + # tpc_corr_scaling_options = ('--lumi-type 1', '')[tpcDistortionType != 0] + + #<--------- TPC reco task + if includeTPCSyncMode: + tpcSyncreconeeds = tpcreconeeds.copy() + TPCSyncRECOtask=createTask(name='tpcSyncreco_'+str(tf), needs=tpcSyncreconeeds, tf=tf, cwd=timeframeworkdir, lab=["RECO"], relative_cpu=3/8, mem='16000') + TPCSyncRECOtask['cmd'] = '${O2_ROOT}/bin/o2-tpc-reco-workflow ' + getDPL_global_options(bigshm=True, ccdbbackend=False, runcommand=False) \ + + '--input-type clusters --output-type clusters,disable-writer ' \ + + putConfigValues() + TPCSyncRECOtask['cmd'] += ' | ${O2_ROOT}/bin/o2-gpu-reco-workflow' + getDPL_global_options(bigshm=True, ccdbbackend=True, runcommand=False) \ + + '--input-type clusters --output-type compressed-clusters-flat,clusters,send-clusters-per-sector --filtered-output-specs ' \ + + tpc_corr_scaling_options + ' ' + tpc_corr_options_mc \ + + putConfigValues(["TPCGasParam", "TPCCorrMap", "trackTuneParams"], + localCF={"GPU_proc.ompThreads":NWORKERS_TF, \ + "GPU_proc.tpcWriteClustersAfterRejection":1, \ + "GPU_rec_tpc.compressionTypeMask":0, \ + "GPU_global.synchronousProcessing":1, \ + "GPU_proc.tpcIncreasedMinClustersPerRow":500000}, + globalTFConfig=False) + TPCSyncRECOtask['cmd'] += ' | ${O2_ROOT}/bin/o2-tpc-reco-workflow ' + getDPL_global_options(bigshm=True, ccdbbackend=False, runcommand=True) + ' --filtered-input --input-type pass-through --output-type clusters,send-clusters-per-sector ' + TPCSyncRECOtask['cmd'] += ' ; mv tpc-filtered-native-clusters.root tpc-native-clusters.root' + workflow['stages'].append(TPCSyncRECOtask) + tpcreconeeds.append(TPCSyncRECOtask['name']) - # END TPC reco + TPCRECOtask=createTask(name='tpcreco_'+str(tf), needs=tpcreconeeds, tf=tf, cwd=timeframeworkdir, lab=["RECO"], relative_cpu=3/8, mem='16000') + TPCRECOtask['cmd'] = task_finalizer([ + '${O2_ROOT}/bin/o2-tpc-reco-workflow', + getDPL_global_options(bigshm=True), + '--input-type clusters', + '--output-type tracks,send-clusters-per-sector', + putConfigValues(["GPU_global", + "TPCGasParam", + "TPCCorrMap", + "GPU_rec_tpc", + "trackTuneParams"], + {"GPU_proc.ompThreads":NWORKERS_TF} | tpcLocalCFreco), + ('',' --disable-mc')[args.no_mc_labels], + tpc_corr_scaling_options, + tpc_corr_options_mc, + tpcreco_mctimegain]) + workflow['stages'].append(TPCRECOtask) + #<--------- ITS reco task ITSMemEstimate = 12000 if havePbPb else 2000 # PbPb has much large mem requirement for now (in worst case) - ITSRECOtask=createTask(name='itsreco_'+str(tf), needs=[getDigiTaskName("ITS")], + ITSRECOtask=createTask(name='itsreco_'+str(tf), needs=[getDigiTaskName("ITS" if args.detectorList == 'ALICE2' else "IT3")], tf=tf, cwd=timeframeworkdir, lab=["RECO"], cpu='1', mem=str(ITSMemEstimate)) - ITSRECOtask['cmd'] = '${O2_ROOT}/bin/o2-its-reco-workflow --trackerCA --tracking-mode async ' + getDPL_global_options(bigshm=havePbPb) \ - + putConfigValuesNew(["ITSVertexerParam", "ITSAlpideParam", - "ITSClustererParam", "ITSCATrackerParam"], {"NameConf.mDirMatLUT" : ".."}) - ITSRECOtask['cmd'] += ('',' --disable-mc')[args.no_mc_labels] + ITSRECOtask['cmd'] = task_finalizer([ + "${O2_ROOT}/bin/o2-its-reco-workflow" if args.detectorList == 'ALICE2' else "${O2_ROOT}/bin/o2-its3-reco-workflow", + getDPL_global_options(bigshm=havePbPb), + '--tracking-mode async', + putConfigValues(["ITSVertexerParam", + "ITSAlpideParam", + "ITSClustererParam", + "ITSCATrackerParam"], + {"NameConf.mDirMatLUT" : ".."}), + ('',' --disable-mc')[args.no_mc_labels] + ]) workflow['stages'].append(ITSRECOtask) - FT0RECOtask=createTask(name='ft0reco_'+str(tf), needs=[getDigiTaskName("FT0")], tf=tf, cwd=timeframeworkdir, lab=["RECO"], mem='1000') - # note: when calibrations (or CCDB objects) are reenabled, we need to say ccdbbackend=True - FT0RECOtask['cmd'] = '${O2_ROOT}/bin/o2-ft0-reco-workflow --disable-time-offset-calib --disable-slewing-calib ' + getDPL_global_options(ccdbbackend=False) + putConfigValues() + #<--------- FT0 reco task + FT0RECOtask = createTask(name='ft0reco_'+str(tf), needs=[getDigiTaskName("FT0")], tf=tf, cwd=timeframeworkdir, lab=["RECO"], mem='1000') + FT0RECOtask["cmd"] = task_finalizer([ + '${O2_ROOT}/bin/o2-ft0-reco-workflow', + getDPL_global_options(ccdbbackend=False), # note: when calibrations (or CCDB objects) are reenabled, we need to say ccdbbackend=True + '--disable-time-offset-calib', # because effect not simulated in MC + '--disable-slewing-calib', # because effect not simulated in MC + putConfigValues() + ]) workflow['stages'].append(FT0RECOtask) - ITSTPCMATCHtask=createTask(name='itstpcMatch_'+str(tf), needs=[TPCRECOtask['name'], ITSRECOtask['name'], FT0RECOtask['name']], tf=tf, cwd=timeframeworkdir, lab=["RECO"], mem='8000', relative_cpu=3/8) - ITSTPCMATCHtask['cmd'] = '${O2_ROOT}/bin/o2-tpcits-match-workflow ' + getDPL_global_options(bigshm=True) + ' --tpc-track-reader \"tpctracks.root\" --tpc-native-cluster-reader \"--infile tpc-native-clusters.root\" --use-ft0' \ - + putConfigValuesNew(['MFTClustererParam', 'ITSCATrackerParam', 'tpcitsMatch', 'TPCGasParam', 'TPCCorrMap', 'ITSClustererParam', 'GPU_rec_tpc', 'trackTuneParams', 'ft0tag'], {"NameConf.mDirMatLUT" : ".."} | tpcLocalCFreco) \ - + tpc_corr_scaling_options + tpc_corr_options_mc + #<--------- ITS-TPC track matching task + ITSTPCMATCHtask=createTask(name='itstpcMatch_'+str(tf), needs=[TPCRECOtask['name'], ITSRECOtask['name'], FT0RECOtask['name'] if isActive("FT0") else None], tf=tf, cwd=timeframeworkdir, lab=["RECO"], mem='8000', relative_cpu=3/8) + ITSTPCMATCHtask["cmd"] = task_finalizer([ + '${O2_ROOT}/bin/o2-tpcits-match-workflow', + getDPL_global_options(bigshm=True), + ' --tpc-track-reader tpctracks.root', + '--tpc-native-cluster-reader \"--infile tpc-native-clusters.root\"', + '--use-ft0' if isActive("FT0") else None, + putConfigValues(['MFTClustererParam', + 'ITSCATrackerParam', + 'tpcitsMatch', + 'TPCGasParam', + 'TPCCorrMap', + 'ITSClustererParam', + 'GPU_rec_tpc', + 'trackTuneParams', + 'GlobalParams', + 'ft0tag'], + {"NameConf.mDirMatLUT" : ".."} | tpcLocalCFreco), + tpc_corr_scaling_options, + tpc_corr_options_mc + ]) workflow['stages'].append(ITSTPCMATCHtask) + #<--------- ITS-TPC track matching task TRDTRACKINGtask = createTask(name='trdreco_'+str(tf), needs=[TRDDigitask['name'], ITSTPCMATCHtask['name'], TPCRECOtask['name'], ITSRECOtask['name']], tf=tf, cwd=timeframeworkdir, lab=["RECO"], cpu='1', mem='2000') - TRDTRACKINGtask['cmd'] = '${O2_ROOT}/bin/o2-trd-tracklet-transformer ' + getDPL_global_options() + putConfigValues() + ('',' --disable-mc')[args.no_mc_labels] - workflow['stages'].append(TRDTRACKINGtask) - + TRDTRACKINGtask['cmd'] = task_finalizer(['${O2_ROOT}/bin/o2-trd-tracklet-transformer', + getDPL_global_options(), + putConfigValues(), + ('',' --disable-mc')[args.no_mc_labels]]) + if isActive("TRD"): + workflow['stages'].append(TRDTRACKINGtask) + + #<--------- TRD global tracking # FIXME This is so far a workaround to avoud a race condition for trdcalibratedtracklets.root TRDTRACKINGtask2 = createTask(name='trdreco2_'+str(tf), needs=[TRDTRACKINGtask['name']], tf=tf, cwd=timeframeworkdir, lab=["RECO"], cpu='1', mem='2000') - trd_track_sources = anchorConfig.get('o2-trd-global-tracking-options', {}).get('track-sources', 'TPC,ITS-TPC') - TRDTRACKINGtask2['cmd'] = '${O2_ROOT}/bin/o2-trd-global-tracking ' + getDPL_global_options(bigshm=True) + ('',' --disable-mc')[args.no_mc_labels] \ - + putConfigValuesNew(['ITSClustererParam', - 'ITSCATrackerParam', - 'trackTuneParams', - 'GPU_rec_tpc', - 'TPCGasParam', - 'TPCCorrMap'], {"NameConf.mDirMatLUT" : ".."} | tpcLocalCFreco) \ - + " --track-sources " + trd_track_sources \ - + tpc_corr_scaling_options + tpc_corr_options_mc - workflow['stages'].append(TRDTRACKINGtask2) - + trd_track_sources = cleanDetectorInputList(dpl_option_from_config(anchorConfig, 'o2-trd-global-tracking', '--track-sources', default_value='TPC,ITS-TPC')) + TRDTRACKINGtask2['cmd'] = task_finalizer([ + '${O2_ROOT}/bin/o2-trd-global-tracking', + getDPL_global_options(bigshm=True), + ('',' --disable-mc')[args.no_mc_labels], + putConfigValues(['ITSClustererParam', + 'ITSCATrackerParam', + 'trackTuneParams', + 'GPU_rec_tpc', + 'TPCGasParam', + 'GlobalParams', + 'TPCCorrMap'], {"NameConf.mDirMatLUT" : ".."} | tpcLocalCFreco), + '--track-sources ' + trd_track_sources, + tpc_corr_scaling_options, + tpc_corr_options_mc]) + if isActive("TRD"): + workflow['stages'].append(TRDTRACKINGtask2) + + #<--------- TOF reco task TOFRECOtask = createTask(name='tofmatch_'+str(tf), needs=[ITSTPCMATCHtask['name'], getDigiTaskName("TOF")], tf=tf, cwd=timeframeworkdir, lab=["RECO"], mem='1500') - TOFRECOtask['cmd'] = '${O2_ROOT}/bin/o2-tof-reco-workflow --use-ccdb ' + getDPL_global_options() + putConfigValuesNew() + ('',' --disable-mc')[args.no_mc_labels] - workflow['stages'].append(TOFRECOtask) - - - toftpcmatchneeds = [TOFRECOtask['name'], TPCRECOtask['name'], ITSTPCMATCHtask['name'], TRDTRACKINGtask2['name']] - toftracksrcdefault = anchorConfig.get('o2-tof-matcher-workflow-options', {}).get('track-sources', 'TPC,ITS-TPC,TPC-TRD,ITS-TPC-TRD') + TOFRECOtask["cmd"] = task_finalizer([ + '${O2_ROOT}/bin/o2-tof-reco-workflow', + getDPL_global_options(), + '--use-ccdb', + putConfigValues(), + ('',' --disable-mc')[args.no_mc_labels] + ]) + if isActive('TOF'): + workflow['stages'].append(TOFRECOtask) + + #<--------- TOF-TPC(-ITS) global track matcher workflow + toftpcmatchneeds = [TOFRECOtask['name'], + TPCRECOtask['name'], + ITSTPCMATCHtask['name'], + TRDTRACKINGtask2['name'] if isActive("TRD") else None] + toftracksrcdefault = cleanDetectorInputList(dpl_option_from_config(anchorConfig, 'o2-tof-matcher-workflow', '--track-sources', default_value='TPC,ITS-TPC,TPC-TRD,ITS-TPC-TRD')) + tofusefit = option_if_available('o2-tof-matcher-workflow', '--use-fit', envfile=async_envfile) TOFTPCMATCHERtask = createTask(name='toftpcmatch_'+str(tf), needs=toftpcmatchneeds, tf=tf, cwd=timeframeworkdir, lab=["RECO"], mem='1000') - TOFTPCMATCHERtask['cmd'] = '${O2_ROOT}/bin/o2-tof-matcher-workflow ' + getDPL_global_options() \ - + putConfigValuesNew(["ITSClustererParam", - 'TPCGasParam', - 'TPCCorrMap', - 'ITSCATrackerParam', - 'MFTClustererParam', - 'GPU_rec_tpc', - 'trackTuneParams'], tpcLocalCFreco) \ - + " --track-sources " + toftracksrcdefault + (' --combine-devices','')[args.no_combine_dpl_devices] \ - + tpc_corr_scaling_options + tpc_corr_options_mc - workflow['stages'].append(TOFTPCMATCHERtask) + tofmatcher_cmd_parts = [ + '${O2_ROOT}/bin/o2-tof-matcher-workflow', + getDPL_global_options(), + putConfigValues(['ITSClustererParam', + 'TPCGasParam', + 'TPCCorrMap', + 'ITSCATrackerParam', + 'MFTClustererParam', + 'GPU_rec_tpc', + 'ft0tag', + 'trackTuneParams'], tpcLocalCFreco), + ' --track-sources ' + toftracksrcdefault, + (' --combine-devices','')[args.no_combine_dpl_devices], + tofusefit if isActive("FT0") else None, + tpc_corr_scaling_options, + tpc_corr_options_mc + ] + TOFTPCMATCHERtask['cmd'] = task_finalizer(tofmatcher_cmd_parts) + if isActive('TOF'): + workflow['stages'].append(TOFTPCMATCHERtask) # MFT reco: needing access to kinematics (when assessment enabled) mftreconeeds = [getDigiTaskName("MFT")] if usebkgcache: mftreconeeds += [ BKG_KINEDOWNLOADER_TASK['name'] ] + #<--------- MFT reco workflow MFTRECOtask = createTask(name='mftreco_'+str(tf), needs=mftreconeeds, tf=tf, cwd=timeframeworkdir, lab=["RECO"], mem='1500') MFTRECOtask['cmd'] = ('','ln -nfs ../bkg_Kine.root . ;')[doembedding] - MFTRECOtask['cmd'] += '${O2_ROOT}/bin/o2-mft-reco-workflow ' + getDPL_global_options() + putConfigValuesNew(['MFTTracking', 'MFTAlpideParam', 'ITSClustererParam','MFTClustererParam']) - MFTRECOtask['cmd'] += ('',' --disable-mc')[args.no_mc_labels] - if args.mft_assessment_full == True: - MFTRECOtask['cmd']+= ' --run-assessment ' - workflow['stages'].append(MFTRECOtask) + MFTRECOtask['cmd'] += task_finalizer([ + '${O2_ROOT}/bin/o2-mft-reco-workflow', + getDPL_global_options(), + putConfigValues(['MFTTracking', + 'MFTAlpideParam', + 'ITSClustererParam', + 'MFTClustererParam']), + ('','--disable-mc')[args.no_mc_labels], + ('','--run-assessment')[args.mft_assessment_full]]) + if isActive("MFT"): + workflow['stages'].append(MFTRECOtask) # MCH reco: needing access to kinematics ... so some extra logic needed here mchreconeeds = [getDigiTaskName("MCH")] if usebkgcache: mchreconeeds += [ BKG_KINEDOWNLOADER_TASK['name'] ] + #<--------- MCH reco workflow MCHRECOtask = createTask(name='mchreco_'+str(tf), needs=mchreconeeds, tf=tf, cwd=timeframeworkdir, lab=["RECO"], mem='1500') MCHRECOtask['cmd'] = ('','ln -nfs ../bkg_Kine.root . ;')[doembedding] - MCHRECOtask['cmd'] += '${O2_ROOT}/bin/o2-mch-reco-workflow ' + getDPL_global_options() + putConfigValues() - MCHRECOtask['cmd'] += ('',' --disable-mc')[args.no_mc_labels] + MCHRECOtask['cmd'] += task_finalizer( + ['${O2_ROOT}/bin/o2-mch-reco-workflow', + getDPL_global_options(), + putConfigValues(), + ('',' --disable-mc')[args.no_mc_labels], + '--enable-clusters-root-output']) workflow['stages'].append(MCHRECOtask) + #<--------- MID reco workflow MIDRECOtask = createTask(name='midreco_'+str(tf), needs=[getDigiTaskName("MID")], tf=tf, cwd=timeframeworkdir, lab=["RECO"], mem='1500') - MIDRECOtask['cmd'] = '${O2_ROOT}/bin/o2-mid-digits-reader-workflow ' + ('',' --disable-mc')[args.no_mc_labels] + ' | ${O2_ROOT}/bin/o2-mid-reco-workflow ' + getDPL_global_options() + putConfigValues() - MIDRECOtask['cmd'] += ('',' --disable-mc')[args.no_mc_labels] - workflow['stages'].append(MIDRECOtask) - + MIDRECOtask['cmd'] = task_finalizer( + ['${O2_ROOT}/bin/o2-mid-digits-reader-workflow', + ('',' --disable-mc')[args.no_mc_labels]]) + MIDRECOtask['cmd'] += ' | ' + MIDRECOtask['cmd'] += task_finalizer(['${O2_ROOT}/bin/o2-mid-reco-workflow', + getDPL_global_options(), + putConfigValues(),('',' --disable-mc')[args.no_mc_labels]]) + if isActive('MID'): + workflow['stages'].append(MIDRECOtask) + + #<--------- FDD reco workflow FDDRECOtask = createTask(name='fddreco_'+str(tf), needs=[getDigiTaskName("FDD")], tf=tf, cwd=timeframeworkdir, lab=["RECO"], mem='1500') - FDDRECOtask['cmd'] = '${O2_ROOT}/bin/o2-fdd-reco-workflow ' + getDPL_global_options(ccdbbackend=False) + putConfigValues() - FDDRECOtask['cmd'] += ('',' --disable-mc')[args.no_mc_labels] + FDDRECOtask['cmd'] = task_finalizer(['${O2_ROOT}/bin/o2-fdd-reco-workflow', + getDPL_global_options(ccdbbackend=False), + putConfigValues(), + ('',' --disable-mc')[args.no_mc_labels]]) workflow['stages'].append(FDDRECOtask) + #<--------- FV0 reco workflow FV0RECOtask = createTask(name='fv0reco_'+str(tf), needs=[getDigiTaskName("FV0")], tf=tf, cwd=timeframeworkdir, lab=["RECO"], mem='1500') - FV0RECOtask['cmd'] = '${O2_ROOT}/bin/o2-fv0-reco-workflow ' + getDPL_global_options() + putConfigValues() - FV0RECOtask['cmd'] += ('',' --disable-mc')[args.no_mc_labels] + FV0RECOtask['cmd'] = task_finalizer(['${O2_ROOT}/bin/o2-fv0-reco-workflow', + getDPL_global_options(), + putConfigValues(), + ('',' --disable-mc')[args.no_mc_labels]]) workflow['stages'].append(FV0RECOtask) # calorimeters + #<--------- EMC reco workflow EMCRECOtask = createTask(name='emcalreco_'+str(tf), needs=[getDigiTaskName("EMC")], tf=tf, cwd=timeframeworkdir, lab=["RECO"], mem='1500') - EMCRECOtask['cmd'] = '${O2_ROOT}/bin/o2-emcal-reco-workflow --input-type digits --output-type cells --infile emcaldigits.root --disable-root-output --subspecificationOut 1 ' + putConfigValues() - EMCRECOtask['cmd'] += ('',' --disable-mc')[args.no_mc_labels] - EMCRECOtask['cmd'] += ' | ${O2_ROOT}/bin/o2-emcal-cell-recalibrator-workflow --input-subspec 1 --output-subspec 0 --no-timecalib --no-gaincalib ' + putConfigValues() - EMCRECOtask['cmd'] += (' --isMC','')[args.no_mc_labels] - EMCRECOtask['cmd'] += ' | ${O2_ROOT}/bin/o2-emcal-cell-writer-workflow --subspec 0 ' + getDPL_global_options() - EMCRECOtask['cmd'] += ('',' --disable-mc')[args.no_mc_labels] + # first part + EMCRECOtask['cmd'] = task_finalizer([ + '${O2_ROOT}/bin/o2-emcal-reco-workflow', + putConfigValues(), + '--input-type digits', + '--output-type cells', + '--infile emcaldigits.root', + '--disable-root-output', + '--subspecificationOut 1', + ('',' --disable-mc')[args.no_mc_labels]]) + # second part + EMCRECOtask['cmd'] += ' | ' + EMCRECOtask['cmd'] += task_finalizer([ + '${O2_ROOT}/bin/o2-emcal-cell-recalibrator-workflow', + putConfigValues(), + '--input-subspec 1', + '--output-subspec 0', + '--no-timecalib', + '--no-gaincalib', + (' --isMC','')[args.no_mc_labels]]) + # third part + EMCRECOtask['cmd'] += ' | ' + EMCRECOtask['cmd'] += task_finalizer([ + '${O2_ROOT}/bin/o2-emcal-cell-writer-workflow', + getDPL_global_options(), + '--subspec 0', + ('',' --disable-mc')[args.no_mc_labels]]) workflow['stages'].append(EMCRECOtask) + #<--------- PHS reco workflow PHSRECOtask = createTask(name='phsreco_'+str(tf), needs=[getDigiTaskName("PHS")], tf=tf, cwd=timeframeworkdir, lab=["RECO"], mem='1500') - PHSRECOtask['cmd'] = '${O2_ROOT}/bin/o2-phos-reco-workflow ' + getDPL_global_options() + putConfigValues() - PHSRECOtask['cmd'] += ('',' --disable-mc')[args.no_mc_labels] - workflow['stages'].append(PHSRECOtask) - + PHSRECOtask['cmd'] = task_finalizer([ + '${O2_ROOT}/bin/o2-phos-reco-workflow', + getDPL_global_options(), + putConfigValues(), + ('',' --disable-mc')[args.no_mc_labels]]) + if isActive("PHS"): + workflow['stages'].append(PHSRECOtask) + + #<--------- CPV reco workflow CPVRECOtask = createTask(name='cpvreco_'+str(tf), needs=[getDigiTaskName("CPV")], tf=tf, cwd=timeframeworkdir, lab=["RECO"], mem='1500') - CPVRECOtask['cmd'] = '${O2_ROOT}/bin/o2-cpv-reco-workflow ' + getDPL_global_options() + putConfigValues() - CPVRECOtask['cmd'] += ('',' --disable-mc')[args.no_mc_labels] - workflow['stages'].append(CPVRECOtask) - + CPVRECOtask['cmd'] = task_finalizer( + ['${O2_ROOT}/bin/o2-cpv-reco-workflow', + getDPL_global_options(), + putConfigValues(), + ('',' --disable-mc')[args.no_mc_labels]]) + if isActive("CPV"): + workflow['stages'].append(CPVRECOtask) + + #<--------- ZDC reco workflow ZDCRECOtask = createTask(name='zdcreco_'+str(tf), needs=[getDigiTaskName("ZDC")], tf=tf, cwd=timeframeworkdir, lab=["RECO", "ZDC"]) - ZDCRECOtask['cmd'] = '${O2_ROOT}/bin/o2-zdc-digits-reco ' + getDPL_global_options() + putConfigValues() - ZDCRECOtask['cmd'] += ('',' --disable-mc')[args.no_mc_labels] - workflow['stages'].append(ZDCRECOtask) + ZDCRECOtask['cmd'] = task_finalizer( + ['${O2_ROOT}/bin/o2-zdc-digits-reco', + getDPL_global_options(), + putConfigValues(), + ('',' --disable-mc')[args.no_mc_labels]]) + if isActive("ZDC"): + workflow['stages'].append(ZDCRECOtask) ## forward matching + #<--------- MCH-MID forward matching MCHMIDMATCHtask = createTask(name='mchmidMatch_'+str(tf), needs=[MCHRECOtask['name'], MIDRECOtask['name']], tf=tf, cwd=timeframeworkdir, lab=["RECO"], mem='1500') - MCHMIDMATCHtask['cmd'] = '${O2_ROOT}/bin/o2-muon-tracks-matcher-workflow ' + getDPL_global_options(ccdbbackend=False) - MCHMIDMATCHtask['cmd'] += ('',' --disable-mc')[args.no_mc_labels] - workflow['stages'].append(MCHMIDMATCHtask) + MCHMIDMATCHtask['cmd'] = task_finalizer( + ['${O2_ROOT}/bin/o2-muon-tracks-matcher-workflow', + getDPL_global_options(ccdbbackend=False), + putConfigValues(), + ('',' --disable-mc')[args.no_mc_labels]]) + if isActive("MID") and isActive("MCH"): + workflow['stages'].append(MCHMIDMATCHtask) + + #<--------- MFT-MCH forward matching + forwardmatchneeds = [MCHRECOtask['name'], + MFTRECOtask['name'] if isActive("MFT") else None, + MCHMIDMATCHtask['name'] if isActive("MID") else None] + MFTMCHMATCHtask = createTask(name='mftmchMatch_'+str(tf), needs=forwardmatchneeds, tf=tf, cwd=timeframeworkdir, lab=["RECO"], mem='1500') + MFTMCHMATCHtask['cmd'] = task_finalizer( + ['${O2_ROOT}/bin/o2-globalfwd-matcher-workflow', + putConfigValues(['ITSAlpideConfig', + 'MFTAlpideConfig', + 'FwdMatching'],{"FwdMatching.useMIDMatch": "true" if isActive("MID") else "false"}), + ('',' --disable-mc')[args.no_mc_labels]]) - MFTMCHMATCHtask = createTask(name='mftmchMatch_'+str(tf), needs=[MCHMIDMATCHtask['name'], MFTRECOtask['name']], tf=tf, cwd=timeframeworkdir, lab=["RECO"], mem='1500') - MFTMCHMATCHtask['cmd'] = '${O2_ROOT}/bin/o2-globalfwd-matcher-workflow ' + putConfigValuesNew(['ITSAlpideConfig','MFTAlpideConfig','FwdMatching'],{"FwdMatching.useMIDMatch":"true"}) if args.fwdmatching_assessment_full == True: - MFTMCHMATCHtask['cmd']+= ' | o2-globalfwd-assessment-workflow ' - MFTMCHMATCHtask['cmd']+= getDPL_global_options() + ('',' --disable-mc')[args.no_mc_labels] + MFTMCHMATCHtask['cmd'] += ' | ' + MFTMCHMATCHtask['cmd'] += task_finalizer( + ['${O2_ROOT}/bin/o2-globalfwd-assessment-workflow', + getDPL_global_options(), + ('',' --disable-mc')[args.no_mc_labels]]) workflow['stages'].append(MFTMCHMATCHtask) if args.fwdmatching_save_trainingdata == True: MFTMCHMATCHTraintask = createTask(name='mftmchMatchTrain_'+str(tf), needs=[MCHMIDMATCHtask['name'], MFTRECOtask['name']], tf=tf, cwd=timeframeworkdir, lab=["RECO"], mem='1500') - MFTMCHMATCHTraintask['cmd'] = '${O2_ROOT}/bin/o2-globalfwd-matcher-workflow ' + putConfigValuesNew(['ITSAlpideConfig','MFTAlpideConfig'],{"FwdMatching.useMIDMatch":"true"}) + MFTMCHMATCHTraintask['cmd'] = '${O2_ROOT}/bin/o2-globalfwd-matcher-workflow ' + putConfigValues(['ITSAlpideConfig','MFTAlpideConfig'],{"FwdMatching.useMIDMatch":"true"}) MFTMCHMATCHTraintask['cmd']+= getDPL_global_options() workflow['stages'].append(MFTMCHMATCHTraintask) # HMP tasks + #<--------- HMP forward matching HMPRECOtask = createTask(name='hmpreco_'+str(tf), needs=[getDigiTaskName('HMP')], tf=tf, cwd=timeframeworkdir, lab=["RECO"], mem='1000') - HMPRECOtask['cmd'] = '${O2_ROOT}/bin/o2-hmpid-digits-to-clusters-workflow ' + getDPL_global_options(ccdbbackend=False) + putConfigValuesNew() + HMPRECOtask['cmd'] = task_finalizer( + ['${O2_ROOT}/bin/o2-hmpid-digits-to-clusters-workflow', + getDPL_global_options(ccdbbackend=False), + putConfigValues()]) workflow['stages'].append(HMPRECOtask) - hmpmatchneeds = [HMPRECOtask['name'], ITSTPCMATCHtask['name'], TOFTPCMATCHERtask['name'], TRDTRACKINGtask2['name']] - hmp_match_sources = anchorConfig.get('o2-hmpid-matcher-workflow', {}).get('track-sources', 'ITS-TPC,ITS-TPC-TRD,TPC-TRD') + #<--------- HMP forward matching + hmpmatchneeds = [HMPRECOtask['name'], + ITSTPCMATCHtask['name'], + TOFTPCMATCHERtask['name'] if isActive("TOF") else None, + TRDTRACKINGtask2['name'] if isActive("TRD") else None] + hmpmatchneeds = [ n for n in hmpmatchneeds if n != None ] + hmp_match_sources = cleanDetectorInputList(dpl_option_from_config(anchorConfig, 'o2-hmpid-matcher-workflow', '--track-sources', default_value='ITS-TPC,ITS-TPC-TRD,TPC-TRD')) HMPMATCHtask = createTask(name='hmpmatch_'+str(tf), needs=hmpmatchneeds, tf=tf, cwd=timeframeworkdir, lab=["RECO"], mem='1000') - HMPMATCHtask['cmd'] = '${O2_ROOT}/bin/o2-hmpid-matcher-workflow --track-sources ' + hmp_match_sources + getDPL_global_options() + putConfigValuesNew() + HMPMATCHtask['cmd'] = task_finalizer( + ['${O2_ROOT}/bin/o2-hmpid-matcher-workflow', + '--track-sources ' + hmp_match_sources, + getDPL_global_options(), + putConfigValues() + ]) workflow['stages'].append(HMPMATCHtask) - # Take None as default, we only add more if nothing from anchorConfig - pvfinder_sources = anchorConfig.get('o2-primary-vertexing-workflow-options', {}).get('vertexing-sources', 'ITS-TPC,TPC-TRD,ITS-TPC-TRD,TPC-TOF,ITS-TPC-TOF,TPC-TRD-TOF,ITS-TPC-TRD-TOF,MFT-MCH,MCH-MID,ITS,MFT,TPC,TOF,FT0,MID,EMC,PHS,CPV,FDD,HMP,FV0,TRD,MCH,CTP') - pvfinder_matching_sources = anchorConfig.get('', {}).get('vertex-track-matching-sources', 'ITS-TPC,TPC-TRD,ITS-TPC-TRD,TPC-TOF,ITS-TPC-TOF,TPC-TRD-TOF,ITS-TPC-TRD-TOF,MFT-MCH,MCH-MID,ITS,MFT,TPC,TOF,FT0,MID,EMC,PHS,CPV,ZDC,FDD,HMP,FV0,TRD,MCH,CTP') - pvfinderneeds = [TRDTRACKINGtask2['name'], FT0RECOtask['name'], FV0RECOtask['name'], EMCRECOtask['name'], PHSRECOtask['name'], CPVRECOtask['name'], FDDRECOtask['name'], ZDCRECOtask['name'], HMPMATCHtask['name'], HMPMATCHtask['name'], ITSTPCMATCHtask['name'], TOFTPCMATCHERtask['name'], MFTMCHMATCHtask['name'], MCHMIDMATCHtask['name']] + #<---------- primary vertex finding + pvfinder_sources = dpl_option_from_config(anchorConfig, + 'o2-primary-vertexing-workflow', + '--vertexing-sources', + default_value='ITS-TPC,TPC-TRD,ITS-TPC-TRD,TPC-TOF,ITS-TPC-TOF,TPC-TRD-TOF,ITS-TPC-TRD-TOF,MFT-MCH,MCH-MID,ITS,MFT,TPC,TOF,FT0,MID,EMC,PHS,CPV,FDD,HMP,FV0,TRD,MCH,CTP') + pvfinder_sources = cleanDetectorInputList(pvfinder_sources) + + pvfinder_matching_sources = dpl_option_from_config(anchorConfig, + 'o2-primary-vertexing-workflow', + '--vertex-track-matching-sources', + default_value='ITS-TPC,TPC-TRD,ITS-TPC-TRD,TPC-TOF,ITS-TPC-TOF,TPC-TRD-TOF,ITS-TPC-TRD-TOF,MFT-MCH,MCH-MID,ITS,MFT,TPC,TOF,FT0,MID,EMC,PHS,CPV,FDD,HMP,FV0,TRD,MCH,CTP') + pvfinder_matching_sources = cleanDetectorInputList(pvfinder_matching_sources) + + pvfinderneeds = [TRDTRACKINGtask2['name'] if isActive("TRD") else None, + FT0RECOtask['name'] if isActive("FT0") else None, + FV0RECOtask['name'] if isActive("FV0") else None, + EMCRECOtask['name'] if isActive("EMC") else None, + PHSRECOtask['name'] if isActive("PHS") else None, + CPVRECOtask['name'] if isActive("CPV") else None, + FDDRECOtask['name'] if isActive("FDD") else None, + ZDCRECOtask['name'] if isActive("ZDC") else None, + HMPMATCHtask['name'] if isActive("HMP") else None, + ITSTPCMATCHtask['name'] if isActive("ITS") and isActive("TPC") else None, + TOFTPCMATCHERtask['name'] if isActive("TPC") and isActive("TOF") else None, + MFTMCHMATCHtask['name'] if isActive("MFT") and isActive("MCH") else None, + MCHMIDMATCHtask['name'] if isActive("MCH") and isActive("MID") else None] + pvfinderneeds = [ p for p in pvfinderneeds if p != None ] PVFINDERtask = createTask(name='pvfinder_'+str(tf), needs=pvfinderneeds, tf=tf, cwd=timeframeworkdir, lab=["RECO"], cpu=NWORKERS_TF, mem='4000') - PVFINDERtask['cmd'] = '${O2_ROOT}/bin/o2-primary-vertexing-workflow ' \ - + getDPL_global_options() + putConfigValuesNew(['ITSAlpideParam','MFTAlpideParam', 'pvertexer', 'TPCGasParam', 'TPCCorrMap', 'ft0tag'], {"NameConf.mDirMatLUT" : ".."}) - PVFINDERtask['cmd'] += ' --vertexing-sources ' + pvfinder_sources + ' --vertex-track-matching-sources ' + pvfinder_matching_sources + (' --combine-source-devices','')[args.no_combine_dpl_devices] - PVFINDERtask['cmd'] += ('',' --disable-mc')[args.no_mc_labels] + PVFINDERtask['cmd'] = task_finalizer( + [ '${O2_ROOT}/bin/o2-primary-vertexing-workflow', + getDPL_global_options(), + putConfigValues(['ITSAlpideParam', + 'MFTAlpideParam', + 'pvertexer', + 'TPCGasParam', + 'TPCCorrMap', + 'ft0tag'], + {"NameConf.mDirMatLUT" : ".."}), + '--vertexing-sources ' + pvfinder_sources, + '--vertex-track-matching-sources ' + pvfinder_matching_sources, + (' --combine-source-devices','')[args.no_combine_dpl_devices], + ('',' --disable-mc')[args.no_mc_labels] + ]) workflow['stages'].append(PVFINDERtask) + #<------------- secondary vertexer + svfinder_threads = ' --threads 1 ' + svfinder_cpu = 1 + if COLTYPE == "PbPb" or (doembedding and COLTYPEBKG == "PbPb"): + svfinder_threads = ' --threads 8 ' + svfinder_cpu = 8 + + svfinder_sources = dpl_option_from_config(anchorConfig, + 'o2-primary-vertexing-workflow', + '--vertex-track-matching-sources', + default_value='ITS-TPC,TPC-TRD,ITS-TPC-TRD,TPC-TOF,ITS-TPC-TOF,TPC-TRD-TOF,ITS-TPC-TRD-TOF,MFT-MCH,MCH-MID,ITS,MFT,TPC,TOF,FT0,MID,EMC,PHS,CPV,ZDC,FDD,HMP,FV0,TRD,MCH,CTP') + svfinder_sources = cleanDetectorInputList(svfinder_sources) + SVFINDERtask = createTask(name='svfinder_'+str(tf), needs=[PVFINDERtask['name'], FT0FV0EMCCTPDIGItask['name']], tf=tf, cwd=timeframeworkdir, lab=["RECO"], cpu=svfinder_cpu, mem='5000') + SVFINDERtask['cmd'] = task_finalizer( + [ '${O2_ROOT}/bin/o2-secondary-vertexing-workflow', + getDPL_global_options(bigshm=True), + svfinder_threads, + putConfigValues(['svertexer', 'TPCCorrMap', 'GlobalParams'], {"NameConf.mDirMatLUT" : ".."} | tpcLocalCFreco), + tpc_corr_scaling_options, + tpc_corr_options_mc, + '--vertexing-sources ' + svfinder_sources, + ('--combine-source-devices','')[args.no_combine_dpl_devices], + ('',' --disable-strangeness-tracker')[args.no_strangeness_tracking], + ('',' --disable-mc')[args.no_mc_labels and not args.no_strangeness_tracking] # strangeness tracking may require MC labels + ]) + workflow['stages'].append(SVFINDERtask) + + #<------------- AOD producer + # TODO This needs further refinement, sources and dependencies should be constructed dynamically + aod_info_souces_default = 'ITS-TPC,TPC-TRD,ITS-TPC-TRD,TPC-TOF,ITS-TPC-TOF,TPC-TRD-TOF,ITS-TPC-TRD-TOF,MFT-MCH,MCH-MID,ITS,MFT,TPC,TOF,FT0,MID,EMC,PHS,CPV,ZDC,FDD,HMP,FV0,TRD,MCH,CTP' + aodinfosources = dpl_option_from_config(anchorConfig, 'o2-aod-producer-workflow', '--info-sources', default_value=aod_info_souces_default) + aodinfosources = cleanDetectorInputList(aodinfosources) + aodneeds = [PVFINDERtask['name'], SVFINDERtask['name']] + + if usebkgcache: + aodneeds += [ BKG_KINEDOWNLOADER_TASK['name'] ] + + aod_df_id = '{0:03}'.format(tf) + + import os + aod_creator = os.getenv("JALIEN_USER") + if aod_creator == None: + # we use JAliEn to determine the user and capture it's output into a variable via redirect_stdout + import io + from contextlib import redirect_stdout + f = io.StringIO() + with redirect_stdout(f): + if JAlien(['whoami']) == 0: + aod_creator = f.getvalue().strip() + print (f"Determined GRID username {aod_creator}") + + # this option might not be universally available + created_by_option = option_if_available('o2-aod-producer-workflow', '--created-by', envfile=async_envfile) + if created_by_option != '': + created_by_option += ' ' + aod_creator + + aod_parent_option = option_if_available('o2-aod-producer-workflow', '--aod-parent', envfile=async_envfile) + if aod_parent_option != '' and len(args.aod_parent_file) > 0: + aod_parent_option += ' ' + args.aod_parent_file + else: + aod_parent_option = '' + + aod_timeframe_id = f"${{ALIEN_PROC_ID}}{aod_df_id}" if not args.run_anchored else "" + if len(args.aod_output_folder) > 0: + aod_timeframe_id = args.aod_output_folder + + AODtask = createTask(name='aod_'+str(tf), needs=aodneeds, tf=tf, cwd=timeframeworkdir, lab=["AOD"], mem='4000', cpu='1') + AODtask['cmd'] = ('','ln -nfs ../bkg_Kine.root . ;')[doembedding] + AODtask['cmd'] += '[ -f AO2D.root ] && rm AO2D.root; ' + AODtask['cmd'] += task_finalizer([ + "${O2_ROOT}/bin/o2-aod-producer-workflow", + "--reco-mctracks-only 1", + "--aod-writer-keep dangling", + "--aod-writer-resfile AO2D", + '--aod-writer-resmode "UPDATE"', + f"--run-number {args.run}", + getDPL_global_options(bigshm=True), + f"--info-sources {aodinfosources}", + f"--lpmp-prod-tag {args.productionTag}", + "--anchor-pass ${ALIEN_JDL_LPMANCHORPASSNAME:-unknown}", + "--anchor-prod ${ALIEN_JDL_LPMANCHORPRODUCTION:-unknown}", + "--reco-pass ${ALIEN_JDL_LPMPASSNAME:-unknown}", + aod_parent_option, + created_by_option, + "--combine-source-devices" if not args.no_combine_dpl_devices else "", + "--disable-mc" if args.no_mc_labels else "", + "--enable-truncation 0" if environ.get("O2DPG_AOD_NOTRUNCATE") or environ.get("ALIEN_JDL_O2DPG_AOD_NOTRUNCATE") else "", + "--disable-strangeness-tracker" if args.no_strangeness_tracking else "", + f"--aod-timeframe-id {aod_timeframe_id}" if len(aod_timeframe_id) > 0 else "" + ]) + # Consider in future: AODtask['disable_alternative_reco_software'] = True # do not apply reco software here (we prefer latest aod converter) + workflow['stages'].append(AODtask) + + if includeTPCResiduals: + print ("Adding TPC residuals extraction and aggregation") + + #<------------- TPC residuals extraction + scdcalib_vertex_sources = cleanDetectorInputList(dpl_option_from_config(anchorConfig, + 'o2-tpc-scdcalib-interpolation-workflow', + '--vtx-sources', + default_value='ITS-TPC,TPC-TRD,ITS-TPC-TRD,TPC-TOF,ITS-TPC-TOF,TPC-TRD-TOF,ITS-TPC-TRD-TOF,MFT-MCH,MCH-MID,ITS,MFT,TPC,TOF,FT0,MID,EMC,PHS,CPV,FDD,HMP,FV0,TRD,MCH,CTP')) + + scdcalib_track_sources = cleanDetectorInputList(dpl_option_from_config(anchorConfig, + 'o2-tpc-scdcalib-interpolation-workflow', + '--tracking-sources', + default_value='ITS-TPC,TPC-TRD,ITS-TPC-TRD,TPC-TOF,ITS-TPC-TOF,TPC-TRD-TOF,ITS-TPC-TRD-TOF,MFT-MCH,MCH-MID,ITS,MFT,TPC,TOF,FT0,MID,EMC,PHS,CPV,FDD,HMP,FV0,TRD,MCH,CTP')) + + scdcalib_track_extraction = cleanDetectorInputList(dpl_option_from_config(anchorConfig, + 'o2-tpc-scdcalib-interpolation-workflow', + '--tracking-sources-map-extraction', + default_value='ITS-TPC')) + + SCDCALIBtask = createTask(name='scdcalib_'+str(tf), needs=[PVFINDERtask['name']], tf=tf, cwd=timeframeworkdir, lab=["CALIB"], mem='4000') + SCDCALIBtask['cmd'] = task_finalizer( + [ '${O2_ROOT}/bin/o2-tpc-scdcalib-interpolation-workflow', + getDPL_global_options(bigshm=True), + putConfigValues(['scdcalib']), + '--vtx-sources ' + scdcalib_vertex_sources, + '--tracking-sources ' + scdcalib_track_sources, + '--tracking-sources-map-extraction ' + scdcalib_track_extraction, + '--sec-per-slot 1 ', + '--send-track-data' + ]) + workflow['stages'].append(SCDCALIBtask) + + #<------------- TPC residuals aggregator + scdaggreg_secperslot = dpl_option_from_config(anchorConfig, + 'o2-calibration-residual-aggregator', + '--sec-per-slot', + default_value='600') + scdaggreg_outputtype = dpl_option_from_config(anchorConfig, + 'o2-calibration-residual-aggregator', + '--output-type', + default_value='trackParams,unbinnedResid') + + SCDAGGREGtask = createTask(name='scdaggreg_'+str(tf), needs=[SCDCALIBtask['name']], tf=tf, cwd=timeframeworkdir, lab=["CALIB"], mem='1500') + SCDAGGREGtask['cmd'] = task_finalizer( + [ '${O2_ROOT}/bin/o2-calibration-residual-aggregator', + getDPL_global_options(bigshm=True), + '--sec-per-slot ' + scdaggreg_secperslot, + '--enable-ctp ', + '--enable-track-input', + '--output-dir ./', + '--output-type ' + scdaggreg_outputtype, + '--meta-output-dir /dev/null' + ]) + workflow['stages'].append(SCDAGGREGtask) + + # conditional + # + # QC tasks follow + # + if includeFullQC or includeLocalQC: def addQCPerTF(taskName, needs, readerCommand, configFilePath, objectsFile=''): - task = createTask(name=taskName + '_local' + str(tf), needs=needs, tf=tf, cwd=timeframeworkdir, lab=["QC"], cpu=1, mem='2000') + task = createTask(name=taskName + '_local_' + str(tf), needs=needs, tf=tf, cwd=timeframeworkdir, lab=["QC"], cpu=1, mem='2000') objectsFile = objectsFile if len(objectsFile) > 0 else taskName + '.root' - # the --local-batch argument will make QC Tasks store their results in a file and merge with any existing objects - task['cmd'] = f'{readerCommand} | o2-qc --config {configFilePath}' + \ + + def remove_json_prefix(path): + return re.sub(r'^json://', '', path) + + configFilePathOnDisk = remove_json_prefix(configFilePath) + # we check if the configFilePath actually exists in the currently loaded software. Otherwise we exit immediately and gracefully + task['cmd'] = ' if [ -f ' + configFilePathOnDisk + ' ]; then { ' + # The actual QC command + # the --local-batch argument will make QC Tasks store their results in a file and merge with any existing objects + task['cmd'] += f'{readerCommand} | o2-qc --config {configFilePath}' + \ f' --local-batch ../{qcdir}/{objectsFile}' + \ f' --override-values "qc.config.database.host={args.qcdbHost};qc.config.Activity.number={args.run};qc.config.Activity.type=PHYSICS;qc.config.Activity.periodName={args.productionTag};qc.config.Activity.beamType={args.col};qc.config.Activity.start={args.timestamp};qc.config.conditionDB.url={args.conditionDB}"' + \ ' ' + getDPL_global_options(ccdbbackend=False) + task['cmd'] += ' ;} else { echo "Task ' + taskName + ' not performed due to config file not found "; } fi' + # Prevents this task from being run for multiple TimeFrames at the same time, thus trying to modify the same file. task['semaphore'] = objectsFile workflow['stages'].append(task) @@ -1346,21 +1922,22 @@ def addQCPerTF(taskName, needs, readerCommand, configFilePath, objectsFile=''): ### MFT # to be enabled once MFT Digits should run 5 times with different configurations - for flp in range(5): - addQCPerTF(taskName='mftDigitsQC' + str(flp), - needs=[getDigiTaskName("MFT")], - readerCommand='o2-qc-mft-digits-root-file-reader --mft-digit-infile=mftdigits.root', - configFilePath='json://${O2DPG_ROOT}/MC/config/QC/json/mft-digits-' + str(flp) + '.json', - objectsFile='mftDigitsQC.root') - addQCPerTF(taskName='mftClustersQC', + if isActive("MFT"): + for flp in range(5): + addQCPerTF(taskName='mftDigitsQC' + str(flp), + needs=[getDigiTaskName("MFT")], + readerCommand='o2-qc-mft-digits-root-file-reader --mft-digit-infile=mftdigits.root', + configFilePath='json://${O2DPG_ROOT}/MC/config/QC/json/mft-digits-' + str(flp) + '.json', + objectsFile='mftDigitsQC.root') + addQCPerTF(taskName='mftClustersQC', needs=[MFTRECOtask['name']], readerCommand='o2-global-track-cluster-reader --track-types none --cluster-types MFT', configFilePath='json://${O2DPG_ROOT}/MC/config/QC/json/mft-clusters.json') - addQCPerTF(taskName='mftTracksQC', + addQCPerTF(taskName='mftTracksQC', needs=[MFTRECOtask['name']], readerCommand='o2-global-track-cluster-reader --track-types MFT --cluster-types MFT', configFilePath='json://${O2DPG_ROOT}/MC/config/QC/json/mft-tracks.json') - addQCPerTF(taskName='mftMCTracksQC', + addQCPerTF(taskName='mftMCTracksQC', needs=[MFTRECOtask['name']], readerCommand='o2-global-track-cluster-reader --track-types MFT --cluster-types MFT', configFilePath='json://${O2DPG_ROOT}/MC/config/QC/json/mft-tracks-mc.json') @@ -1377,44 +1954,47 @@ def addQCPerTF(taskName, needs, readerCommand, configFilePath, objectsFile=''): configFilePath='json://${O2DPG_ROOT}/MC/config/QC/json/tpc-qc-standard-direct.json') ### TRD - addQCPerTF(taskName='trdDigitsQC', + # TODO: check if the readerCommand also reperforms tracklet construction (which already done in digitization) + if isActive('TRD'): + addQCPerTF(taskName='trdDigitsQC', needs=[TRDDigitask['name']], - readerCommand='o2-trd-trap-sim', + readerCommand='o2-trd-trap-sim --disable-root-output true', configFilePath='json://${O2DPG_ROOT}/MC/config/QC/json/trd-standalone-task.json') - addQCPerTF(taskName='trdTrackingQC', + addQCPerTF(taskName='trdTrackingQC', needs=[TRDTRACKINGtask2['name']], readerCommand='o2-global-track-cluster-reader --track-types "ITS-TPC-TRD,TPC-TRD" --cluster-types none', configFilePath='json://${O2DPG_ROOT}/MC/config/QC/json/trd-tracking-task.json') ### TOF - addQCPerTF(taskName='tofDigitsQC', - needs=[getDigiTaskName("TOF")], - readerCommand='${O2_ROOT}/bin/o2-tof-reco-workflow --delay-1st-tf 3 --input-type digits --output-type none', - configFilePath='json://${O2DPG_ROOT}/MC/config/QC/json/tofdigits.json', - objectsFile='tofDigitsQC.root') - - # depending if TRD and FT0 are available - if isActive('FT0') and isActive('TRD'): - addQCPerTF(taskName='tofft0PIDQC', + if isActive('TOF'): + addQCPerTF(taskName='tofDigitsQC', + needs=[getDigiTaskName("TOF")], + readerCommand='${O2_ROOT}/bin/o2-tof-reco-workflow --delay-1st-tf 3 --input-type digits --output-type none', + configFilePath='json://${O2DPG_ROOT}/MC/config/QC/json/tofdigits.json', + objectsFile='tofDigitsQC.root') + + # depending if TRD and FT0 are available + if isActive('FT0') and isActive('TRD'): + addQCPerTF(taskName='tofft0PIDQC', needs=[TOFTPCMATCHERtask['name'], FT0RECOtask['name']], readerCommand='o2-global-track-cluster-reader --track-types "ITS-TPC-TOF,TPC-TOF,TPC,ITS-TPC-TRD,ITS-TPC-TRD-TOF,TPC-TRD,TPC-TRD-TOF" --cluster-types FT0', configFilePath='json://${O2DPG_ROOT}/MC/config/QC/json/pidft0tof.json') - elif isActive('FT0'): - addQCPerTF(taskName='tofft0PIDQC', + elif isActive('FT0'): + addQCPerTF(taskName='tofft0PIDQC', needs=[TOFTPCMATCHERtask['name']], readerCommand='o2-global-track-cluster-reader --track-types "ITS-TPC-TOF,TPC-TOF,TPC" --cluster-types FT0', - configFilePath='json://${O2DPG_ROOT}/MC/config/QC/json/pidft0tofNoTRD.json') - elif isActive('TRD'): - addQCPerTF(taskName='tofPIDQC', + configFilePath='json://${O2DPG_ROOT}/MC/config/QC/json/pidft0tofNoTRD.json') + elif isActive('TRD'): + addQCPerTF(taskName='tofPIDQC', needs=[TOFTPCMATCHERtask['name']], readerCommand='o2-global-track-cluster-reader --track-types "ITS-TPC-TOF,TPC-TOF,TPC,ITS-TPC-TRD,ITS-TPC-TRD-TOF,TPC-TRD,TPC-TRD-TOF" --cluster-types none', - configFilePath='json://${O2DPG_ROOT}/MC/config/QC/json/pidtof.json') - else: - addQCPerTF(taskName='tofPIDQC', + configFilePath='json://${O2DPG_ROOT}/MC/config/QC/json/pidtof.json') + else: + addQCPerTF(taskName='tofPIDQC', needs=[TOFTPCMATCHERtask['name']], readerCommand='o2-global-track-cluster-reader --track-types "ITS-TPC-TOF,TPC-TOF,TPC" --cluster-types none', - configFilePath='json://${O2DPG_ROOT}/MC/config/QC/json/pidtofNoTRD.json') + configFilePath='json://${O2DPG_ROOT}/MC/config/QC/json/pidtofNoTRD.json') ### EMCAL if isActive('EMC'): @@ -1428,11 +2008,26 @@ def addQCPerTF(taskName, needs, readerCommand, configFilePath, objectsFile=''): readerCommand='o2-emcal-cell-reader-workflow --infile emccells.root | o2-ctp-digit-reader --inputfile ctpdigits.root --disable-mc', configFilePath='json://${O2DPG_ROOT}/MC/config/QC/json/emc-bc-task.json') ### FT0 - addQCPerTF(taskName='RecPointsQC', + if isActive("FT0"): + addQCPerTF(taskName='RecPointsQC', needs=[FT0RECOtask['name']], - readerCommand='o2-ft0-recpoints-reader-workflow --infile o2reco_ft0.root', + readerCommand='o2-ft0-recpoints-reader-workflow --infile o2reco_ft0.root', configFilePath='json://${O2DPG_ROOT}/MC/config/QC/json/ft0-reconstruction-config.json') + ### FV0 + if isActive("FV0"): + addQCPerTF(taskName='FV0DigitsQC', + needs=[getDigiTaskName("FV0")], + readerCommand='o2-fv0-digit-reader-workflow --fv0-digit-infile fv0digits.root', + configFilePath='json://${O2DPG_ROOT}/MC/config/QC/json/fv0-digits.json') + + ### FDD + if isActive("FDD"): + addQCPerTF(taskName='FDDRecPointsQC', + needs=[FDDRECOtask['name']], + readerCommand='o2-fdd-recpoints-reader-workflow --fdd-recpoints-infile o2reco_fdd.root', + configFilePath='json://${O2DPG_ROOT}/MC/config/QC/json/fdd-recpoints.json') + ### GLO + RECO addQCPerTF(taskName='vertexQC', needs=[PVFINDERtask['name']], @@ -1453,12 +2048,12 @@ def addQCPerTF(taskName, needs, readerCommand, configFilePath, objectsFile=''): readerCommand='o2-global-track-cluster-reader --track-types "ITS-TPC-TOF,TPC-TOF,TPC,ITS-TPC-TRD,ITS-TPC-TRD-TOF,TPC-TRD,TPC-TRD-TOF" --cluster-types none', configFilePath='json://${O2DPG_ROOT}/MC/config/QC/json/tofMatchedTracks_AllTypes_direct_MC.json') ### ITS - addQCPerTF(taskName='ITSTrackSimTask', + addQCPerTF(taskName='ITSTrackSimTaskQC', needs=[ITSRECOtask['name']], readerCommand='o2-global-track-cluster-reader --track-types "ITS" --cluster-types "ITS"', configFilePath='json://${O2DPG_ROOT}/MC/config/QC/json/its-mc-tracks-qc.json') - addQCPerTF(taskName='ITSTracksClusters', + addQCPerTF(taskName='ITSTracksClustersQC', needs=[ITSRECOtask['name']], readerCommand='o2-global-track-cluster-reader --track-types "ITS" --cluster-types "ITS"', configFilePath='json://${O2DPG_ROOT}/MC/config/QC/json/its-clusters-tracks-qc.json') @@ -1487,100 +2082,64 @@ def addQCPerTF(taskName, needs, readerCommand, configFilePath, objectsFile=''): needs=[MIDRECOtask['name']], readerCommand='o2-mid-digits-reader-workflow | o2-mid-tracks-reader-workflow', configFilePath='json://${O2DPG_ROOT}/MC/config/QC/json/mid-task.json') - - #secondary vertexer - svfinder_threads = ' --threads 1 ' - svfinder_cpu = 1 - if COLTYPE == "PbPb" or (doembedding and COLTYPEBKG == "PbPb"): - svfinder_threads = ' --threads 8 ' - svfinder_cpu = 8 - SVFINDERtask = createTask(name='svfinder_'+str(tf), needs=[PVFINDERtask['name'], FT0FV0EMCCTPDIGItask['name']], tf=tf, cwd=timeframeworkdir, lab=["RECO"], cpu=svfinder_cpu, mem='5000') - SVFINDERtask = createTask(name='svfinder_'+str(tf), needs=[PVFINDERtask['name']], tf=tf, cwd=timeframeworkdir, lab=["RECO"], cpu=svfinder_cpu, mem='5000') - SVFINDERtask['cmd'] = '${O2_ROOT}/bin/o2-secondary-vertexing-workflow ' - SVFINDERtask['cmd'] += getDPL_global_options(bigshm=True) + svfinder_threads + putConfigValuesNew(['svertexer', 'TPCCorrMap'], {"NameConf.mDirMatLUT" : ".."} | tpcLocalCFreco) \ - + tpc_corr_scaling_options + tpc_corr_options_mc - # Take None as default, we only add more if nothing from anchorConfig - svfinder_sources = anchorConfig.get('o2-secondary-vertexing-workflow-options', {}). get('vertexing-sources', 'ITS-TPC,TPC-TRD,ITS-TPC-TRD,TPC-TOF,ITS-TPC-TOF,TPC-TRD-TOF,ITS-TPC-TRD-TOF,MFT-MCH,MCH-MID,ITS,MFT,TPC,TOF,FT0,MID,EMC,PHS,CPV,ZDC,FDD,HMP,FV0,TRD,MCH,CTP') - SVFINDERtask['cmd'] += ' --vertexing-sources ' + svfinder_sources + (' --combine-source-devices','')[args.no_combine_dpl_devices] - # strangeness tracking is now called from the secondary vertexer - if args.no_strangeness_tracking: - SVFINDERtask['cmd'] += ' --disable-strangeness-tracker' - # if enabled, it may require MC labels - else: - SVFINDERtask['cmd'] += ('',' --disable-mc')[args.no_mc_labels] - workflow['stages'].append(SVFINDERtask) - - # ----------- - # produce AOD - # ----------- - # TODO This needs further refinement, sources and dependencies should be constructed dynamically - aodinfosources = anchorConfig.get('o2-aod-producer-workflow-options', {}).get('info-sources', 'ITS-TPC,TPC-TRD,ITS-TPC-TRD,TPC-TOF,ITS-TPC-TOF,TPC-TRD-TOF,ITS-TPC-TRD-TOF,MFT-MCH,MCH-MID,ITS,MFT,TPC,TOF,FT0,MID,EMC,PHS,CPV,ZDC,FDD,HMP,FV0,TRD,MCH,CTP') - aodneeds = [PVFINDERtask['name'], SVFINDERtask['name']] - - if usebkgcache: - aodneeds += [ BKG_KINEDOWNLOADER_TASK['name'] ] - - aod_df_id = '{0:03}'.format(tf) - - AODtask = createTask(name='aod_'+str(tf), needs=aodneeds, tf=tf, cwd=timeframeworkdir, lab=["AOD"], mem='4000', cpu='1') - AODtask['cmd'] = ('','ln -nfs ../bkg_Kine.root . ;')[doembedding] - AODtask['cmd'] += '[ -f AO2D.root ] && rm AO2D.root; ${O2_ROOT}/bin/o2-aod-producer-workflow --reco-mctracks-only 1 --aod-writer-keep dangling --aod-writer-resfile AO2D' - # next line needed for meta data writing (otherwise lost) - AODtask['cmd'] += ' --aod-writer-resmode "UPDATE"' - AODtask['cmd'] += ' --run-number ' + str(args.run) - # only in non-anchored runs - if args.run_anchored == False: - AODtask['cmd'] += ' --aod-timeframe-id ${ALIEN_PROC_ID}' + aod_df_id - AODtask['cmd'] += ' ' + getDPL_global_options(bigshm=True) - AODtask['cmd'] += ' --info-sources ' + aodinfosources - AODtask['cmd'] += ' --lpmp-prod-tag ${ALIEN_JDL_LPMPRODUCTIONTAG:-unknown}' - AODtask['cmd'] += ' --anchor-pass ${ALIEN_JDL_LPMANCHORPASSNAME:-unknown}' - AODtask['cmd'] += ' --anchor-prod ${ALIEN_JDL_LPMANCHORPASSNAME:-unknown}' - AODtask['cmd'] += (' --combine-source-devices ','')[args.no_combine_dpl_devices] - AODtask['cmd'] += ('',' --disable-mc')[args.no_mc_labels] - if environ.get('O2DPG_AOD_NOTRUNCATE') != None or environ.get('ALIEN_JDL_O2DPG_AOD_NOTRUNCATE') != None: - AODtask['cmd'] += ' --enable-truncation 0' # developer option to suppress precision truncation - - if args.no_strangeness_tracking: - AODtask['cmd'] += ' --disable-strangeness-tracker' - - workflow['stages'].append(AODtask) - - # TPC - time-series objects + + ### MCH + if isActive('MCH'): + addQCPerTF(taskName='MCHDigitsTaskQC', + needs=[MCHRECOtask['name']], + readerCommand='o2-mch-digits-reader-workflow', + configFilePath='json://${O2DPG_ROOT}/MC/config/QC/json/mch-digits-task.json') + addQCPerTF(taskName='MCHErrorsTaskQC', + needs=[MCHRECOtask['name']], + readerCommand='o2-mch-errors-reader-workflow', + configFilePath='json://${O2DPG_ROOT}/MC/config/QC/json/mch-errors-task.json') + addQCPerTF(taskName='MCHRecoTaskQC', + needs=[MCHRECOtask['name']], + readerCommand='o2-mch-reco-workflow --disable-root-output', + configFilePath='json://${O2DPG_ROOT}/MC/config/QC/json/mch-reco-task.json') + addQCPerTF(taskName='MCHTracksTaskQC', + needs=[MCHRECOtask['name']], + readerCommand='o2-global-track-cluster-reader --track-types MCH --cluster-types MCH', + configFilePath='json://${O2DPG_ROOT}/MC/config/QC/json/mch-tracks-task.json') + + ### MCH + MID + if isActive('MCH') and isActive('MID'): + addQCPerTF(taskName='MCHMIDTracksTaskQC', + needs=[MCHMIDMATCHtask['name']], + readerCommand='o2-global-track-cluster-reader --track-types "MCH,MID,MCH-MID" --cluster-types "MCH,MID"', + configFilePath='json://${O2DPG_ROOT}/MC/config/QC/json/mchmid-tracks-task.json') + + ### MCH && MID && MFT || MCH && MFT + if isActive('MCH') and isActive('MID') and isActive('MFT') : + addQCPerTF(taskName='MUONTracksMFTTaskQC', + needs=[MFTMCHMATCHtask['name'], MCHMIDMATCHtask['name']], + readerCommand='o2-global-track-cluster-reader --track-types "MFT,MCH,MID,MCH-MID,MFT-MCH,MFT-MCH-MID" --cluster-types "MCH,MID,MFT"', + configFilePath='json://${O2DPG_ROOT}/MC/config/QC/json/mftmchmid-tracks-task.json') + elif isActive('MCH') and isActive('MFT') : + addQCPerTF(taskName='MCHMFTTaskQC', + needs=[MFTMCHMATCHtask['name']], + readerCommand='o2-global-track-cluster-reader --track-types "MCH,MFT,MFT-MCH" --cluster-types "MCH,MFT"', + configFilePath='json://${O2DPG_ROOT}/MC/config/QC/json/mftmch-tracks-task.json') + + + #<------------------ TPC - time-series objects # initial implementation taken from comments in https://its.cern.ch/jira/browse/O2-4612 # TODO: this needs to be made configurable (as a function of which detectors are actually present) tpctsneeds = [ TPCRECOtask['name'], ITSTPCMATCHtask['name'], TOFTPCMATCHERtask['name'], - PVFINDERtask['name'] + FT0RECOtask['name'], + PVFINDERtask['name'], + TRDTRACKINGtask2['name'] ] TPCTStask = createTask(name='tpctimeseries_'+str(tf), needs=tpctsneeds, tf=tf, cwd=timeframeworkdir, lab=["RECO"], mem='2000', cpu='1') TPCTStask['cmd'] = 'o2-global-track-cluster-reader --disable-mc --cluster-types "FT0,TOF,TPC" --track-types "ITS,TPC,ITS-TPC,ITS-TPC-TOF,ITS-TPC-TRD-TOF"' TPCTStask['cmd'] += ' --primary-vertices ' TPCTStask['cmd'] += ' | o2-tpc-time-series-workflow --enable-unbinned-root-output --sample-unbinned-tsallis --sampling-factor 0.01 ' - TPCTStask['cmd'] += putConfigValuesNew() + ' ' + getDPL_global_options(bigshm=True) - workflow['stages'].append(TPCTStask) - - # AOD merging / combination step (as individual stages) --> for the moment deactivated in favor or more stable global merging - """ - aodmergerneeds = [ AODtask['name'] ] - if tf > 1: - # we can only merge this if the previous timeframe was already merged in order - # to keep time ordering of BCs intact - aodmergerneeds += [ 'aodmerge_' + str(tf-1) ] - - AOD_merge_task = createTask(name='aodmerge_'+str(tf), needs = aodmergerneeds, tf=tf, cwd=timeframeworkdir, lab=["AOD"], mem='2000', cpu='1') - AOD_merge_task['cmd'] = ' root -q -b -l ${O2DPG_ROOT}/UTILS/repairAOD.C\\(\\"AO2D.root\\",\\"AO2D_repaired.root\\"\\); ' - # AOD_merge_task['cmd'] += ' mv AO2D.root AO2D_old.root && mv AO2D_repaired.root AO2D.root ; ' - AOD_merge_task['cmd'] += '[ -f ../AO2D.root ] && mv ../AO2D.root ../AO2D_old.root;' - AOD_merge_task['cmd'] += ' [ -f input.txt ] && rm input.txt; ' - AOD_merge_task['cmd'] += ' [ -f ../AO2D_old.root ] && echo "../AO2D_old.root" > input.txt;' - AOD_merge_task['cmd'] += ' echo "./AO2D_repaired.root" >> input.txt;' - AOD_merge_task['cmd'] += ' o2-aod-merger --output ../AO2D.root;' - AOD_merge_task['cmd'] += ' rm ../AO2D_old.root || true' - AOD_merge_task['semaphore'] = 'aodmerge' #<---- this is making sure that only one merge is running at any time - workflow['stages'].append(AOD_merge_task) - """ + TPCTStask['cmd'] += putConfigValues() + ' ' + getDPL_global_options(bigshm=True) + if isActive('TOF') and isActive('TPC') and isActive('FT0'): + # could be relaxed or changed once the timerseries worklow is more reactive to input cluster- and track-types + workflow['stages'].append(TPCTStask) # cleanup # -------- @@ -1600,9 +2159,13 @@ def addQCPerTF(taskName, needs, readerCommand, configFilePath, objectsFile=''): AOD_merge_task = createTask(name='aodmerge', needs = aodmergerneeds, lab=["AOD"], mem='2000', cpu='1') AOD_merge_task['cmd'] = ' set -e ; [ -f aodmerge_input.txt ] && rm aodmerge_input.txt; ' AOD_merge_task['cmd'] += ' for i in `seq 1 ' + str(NTIMEFRAMES) + '`; do echo "tf${i}/AO2D.root" >> aodmerge_input.txt; done; ' - AOD_merge_task['cmd'] += ' o2-aod-merger --input aodmerge_input.txt --output AO2D.root' + AOD_merge_task['cmd'] += ' o2-aod-merger --input aodmerge_input.txt --output AO2D_pre.root' + # reindex the BC + connected tables because it there could be duplicate BC entries due to the orbit-early treatment + # see https://its.cern.ch/jira/browse/O2-6227 + AOD_merge_task['cmd'] += ' ; root -q -b -l "${O2DPG_ROOT}/MC/utils/AODBcRewriter.C(\\\"AO2D_pre.root\\\",\\\"AO2D.root\\\")"' # produce MonaLisa event stat file AOD_merge_task['cmd'] += ' ; ${O2DPG_ROOT}/MC/bin/o2dpg_determine_eventstat.py' + AOD_merge_task['alternative_alienv_package'] = "None" # we want latest software for this step workflow['stages'].append(AOD_merge_task) job_merging = False @@ -1623,9 +2186,22 @@ def addQCPerTF(taskName, needs, readerCommand, configFilePath, objectsFile=''): POOL_merge_task['cmd'] += '; RC=$?; root -l -q -b -e "auto f=TFile::Open(\\\"evtpool.root\\\"); auto t=(TTree*)f->Get(\\\"o2sim\\\"); int n=t->GetEntries(); std::ofstream((\\\"0_0_0_\\\"+std::to_string(n)+\\\".stat\\\").c_str()) << \\\"# MonaLisa stat file for event pools\\\";" ; [[ ${RC} == 0 ]]' workflow['stages'].append(POOL_merge_task) +# if TPC residuals extraction was requested, we have to merge per-tf trees +if includeTPCResiduals: + tpcResidMergingNeeds = ['scdaggreg_' + str(tf) for tf in range(1, NTIMEFRAMES + 1)] + TPCResid_merge_task = createTask(name='tpcresidmerge', needs = tpcResidMergingNeeds, lab=["CALIB"], mem='2000', cpu='1') + TPCResid_merge_task['cmd'] = ' set -e ; [ -f tpcresidmerge_input.txt ] && rm tpcresidmerge_input.txt; ' + TPCResid_merge_task['cmd'] += ' for i in `seq 1 ' + str(NTIMEFRAMES) + '`; do find tf${i} -name "o2tpc_residuals_*.root" >> tpcresidmerge_input.txt; done; ' + TPCResid_merge_task['cmd'] += '${O2DPG_ROOT}/UTILS/root_merger.py -o o2tpc_residuals.root -i $(grep -v \"^$\" tpcresidmerge_input.txt | paste -sd, -)' + workflow['stages'].append(TPCResid_merge_task) + + # adjust for alternate (RECO) software environments adjust_RECO_environment(workflow, args.alternative_reco_software) dump_workflow(workflow['stages'], args.o, meta=vars(args)) +# dump a config that can be used to reproduce this workflow +task_finalizer.dump_collected_config("final_config.json") + exit (0) diff --git a/MC/bin/o2dpg_sim_workflow_anchored.py b/MC/bin/o2dpg_sim_workflow_anchored.py index 85356a918..e777b9acf 100755 --- a/MC/bin/o2dpg_sim_workflow_anchored.py +++ b/MC/bin/o2dpg_sim_workflow_anchored.py @@ -14,6 +14,17 @@ import json import math import pandas as pd +import subprocess +import shlex + +# hack to find the script for meta upload +o2dpg_root = os.environ.get("O2DPG_ROOT") +if o2dpg_root is None: + raise EnvironmentError("O2DPG_ROOT is not set in the environment.") +mc_prodinfo_path = os.path.abspath(os.path.join(o2dpg_root, "MC", "prodinfo")) +sys.path.append(mc_prodinfo_path) +from mcprodinfo_ccdb_upload import MCProdInfo, publish_MCProdInfo +import dataclasses # Creates a time anchored MC workflow; positioned within a given run-number (as function of production size etc) @@ -111,6 +122,14 @@ def retrieve_Aggregated_RunInfos(run_number): detList = o2.detectors.DetID.getNames(runInfo.grpECS.getDetsReadOut()) assert (run_number == runInfo.runNumber) assert (run_number == runInfo.grpECS.getRun()) + + print (f"Detector list from RunInfo/GRPECS is {detList}") + # potential overwrite in detector list if special env variable ALIEN_JDL_WORKFLOWDETECTORS is set + detlist_overwrite = os.getenv("ALIEN_JDL_WORKFLOWDETECTORS") + if detlist_overwrite: + detList = detlist_overwrite + print (f"Detector list is overwritten to {detList} via JDL") + return {"SOR" : runInfo.sor, "EOR" : runInfo.eor, "FirstOrbit" : runInfo.orbitSOR, @@ -207,6 +226,12 @@ def retrieve_params_fromGRPECS_and_OrbitReset(ccdbreader, run_number, run_start, detList = o2.detectors.DetID.getNames(grp["mDetsReadout"]['v']) print ("Detector list is ", detList) + # potential reduction in detector list if special env variable ALIEN_JDL_WORKFLOWDETECTORS is set + detlist_overwrite = os.getenv("ALIEN_JDL_WORKFLOWDETECTORS") + if detlist_overwrite: + detList = detlist_overwrite + print ("Detector list is overwritten to ", detList) + # orbitReset.get(run_number) return {"FirstOrbit" : orbitFirst, "LastOrbit" : orbitLast, "OrbitsPerTF" : int(grp["mNHBFPerTF"]), "detList" : detList} @@ -241,27 +266,66 @@ def retrieve_CTPScalers(ccdbreader, run_number, timestamp=None): return ctpscaler return None +def retrieve_ITS_RampDuration(ccdbreader, timestamp): + """ + Retrieves the ITS ramp-up duration for a given timestamp and + returns it in milliseconds. + ITS does not deliver digits during a certain ramp-up period so + the start of run is adjusted accordingly using this value. + """ + _, ramp_duration = ccdbreader.fetch("ITS/Calib/RampDuration", "vector", timestamp=timestamp) + if ramp_duration and len(ramp_duration) > 0: + # The vector contains the duration in seconds, convert to milliseconds + duration_ms = int(ramp_duration[0] * 1000) + return duration_ms + print("WARNING: ITS ramp duration vector is empty, using 0") + return 0 + def retrieve_MinBias_CTPScaler_Rate(ctpscaler, finaltime, trig_eff_arg, NBunches, ColSystem, eCM): """ retrieves the CTP scalers object for a given timestamp and calculates the interation rate to be applied in Monte Carlo digitizers. Uses trig_eff_arg when positive, otherwise calculates the effTrigger. """ + trigger_effs = { + "pp": { + "1000": 0.68, + "6000": 0.737, + "default": 0.759 + }, + "pO": { + "default": 0.8222 + }, + "Op": { + "default": 0.8222 + }, + "OO": { + "default": 0.8677 + }, + "NeNe": { + "default": 0.9147 + }, + "PbPb": { + "default": 28.0 # this is ZDC + } + } # determine first of all the trigger efficiency effTrigger = trig_eff_arg if effTrigger < 0: - if ColSystem == "pp": - if eCM < 1000: - effTrigger = 0.68 - elif eCM < 6000: - effTrigger = 0.737 + # Check if ColSystem is defined in trigger_effs + if ColSystem in trigger_effs: + if ColSystem == "pp": + if eCM < 1000: + effTrigger = trigger_effs["pp"]["1000"] + elif eCM < 6000: + effTrigger = trigger_effs["pp"]["6000"] + else: + effTrigger = trigger_effs["pp"]["default"] else: - effTrigger = 0.759 - elif ColSystem == "PbPb": - effTrigger = 28.0 # this is ZDC + effTrigger = trigger_effs[ColSystem]["default"] else: - effTrigger = 0.759 + effTrigger = 0.759 # The simulation will fail later if the collision system is not defined # this is the default for pp ctpclass = 0 # <---- we take the scaler for FT0 @@ -345,6 +409,29 @@ def determine_timestamp(sor, eor, splitinfo, cycle, ntf, HBF_per_timeframe = 256 assert (timestamp_of_production <= eor) return int(timestamp_of_production), production_offset +def determine_timestamp_from_timeframeID(sor, eor, timeframeID, HBF_per_timeframe = 256): + """ + Determines the timestamp based on the given timeframeID within a run + Args: + sor: int + start-of-run in milliseconds since epoch + eor: int + end-of-run in milliseconds since epoch + timeframeID: int + timeframe id + HBF_per_timeframe: int + number of orbits per timeframe + Returns: + int: timestamp in milliseconds + """ + # length of this run in micro seconds, since we use the orbit duration in micro seconds + + timestamp_of_production = sor + timeframeID * HBF_per_timeframe * LHCOrbitMUS / 1000 + # this is a closure test. If we had perfect floating point precision everywhere, it wouldn't fail. + # But since we don't have that and there are some int casts as well, better check again. + assert (timestamp_of_production >= sor) + assert (timestamp_of_production <= eor) + return int(timestamp_of_production) def exclude_timestamp(ts, orbit, run, filename, global_run_params): """ @@ -415,6 +502,8 @@ def parse_file(filename): print(f"This run as globally {total_excluded_fraction} of it's data marked to be exluded") return excluded + + def main(): parser = argparse.ArgumentParser(description='Creates an O2DPG simulation workflow, anchored to a given LHC run. The workflows are time anchored at regular positions within a run as a function of production size, split-id and cycle.') @@ -429,6 +518,8 @@ def main(): parser.add_argument("--run-time-span-file", type=str, dest="run_span_file", help="Run-time-span-file for exclusions of timestamps (bad data periods etc.)", default="") parser.add_argument("--invert-irframe-selection", action='store_true', help="Inverts the logic of --run-time-span-file") parser.add_argument("--orbitsPerTF", type=str, help="Force a certain orbits-per-timeframe number; Automatically taken from CCDB if not given.", default="") + parser.add_argument('--publish-mcprodinfo', action='store_true', default=False, help="Publish MCProdInfo metadata to CCDB") + parser.add_argument('--timeframeID', type=int, help="If given, anchor to this specific timeframe id within a run. Takes precendence over determination based on (split-id, prod-split, cycle)", default=-1) parser.add_argument('forward', nargs=argparse.REMAINDER) # forward args passed to actual workflow creation args = parser.parse_args() print (args) @@ -444,7 +535,11 @@ def main(): run_start = GLOparams["SOR"] run_end = GLOparams["EOR"] - mid_run_timestamp = (run_start + run_end) // 2 + # Adjust start of run using ITS ramp-up period + ITS_rampup = retrieve_ITS_RampDuration(ccdbreader, run_start) + print(f"ITS ramp-up time: {ITS_rampup} ms") + effective_run_start = run_start + ITS_rampup + mid_run_timestamp = (effective_run_start + run_end) // 2 # -------- # fetch other important global properties needed further below @@ -459,21 +554,34 @@ def main(): # determine some fundamental physics quantities eCM = grplhcif.getSqrtS() + eA = grplhcif.getBeamEnergyPerNucleonInGeV(o2.constants.lhc.BeamDirection.BeamC) + eB = grplhcif.getBeamEnergyPerNucleonInGeV(o2.constants.lhc.BeamDirection.BeamA) A1 = grplhcif.getAtomicNumberB1() A2 = grplhcif.getAtomicNumberB2() # determine collision system and energy - print ("Determined eMC ", eCM) + print ("Determined eCM ", eCM) + print ("Determined eA ", eA) + print ("Determined eB ", eB) print ("Determined atomic number A1 ", A1) print ("Determined atomic number A2 ", A2) ColSystem = "" - if A1 == 82 and A2 == 82: - ColSystem = "PbPb" - elif A1 == 1 and A2 == 1: - ColSystem = "pp" - else: - print ("Unknown collision system ... exiting") - exit (1) + col_systems = { + "pp": (1, 1), + "pO": (1, 8), + "Op": (8, 1), + "OO": (8, 8), + "NeNe": (10, 10), + "PbPb": (82, 82) + } + # check if we have a known collision system + for system, (a1, a2) in col_systems.items(): + if A1 == a1 and A2 == a2: + ColSystem = system + break + if ColSystem == "": + print(f"ERROR: Unknown collision system for A1={A1}, A2={A2}. Check the GRPLHCIF object.") + exit(1) print ("Collision system ", ColSystem) @@ -488,13 +596,19 @@ def main(): GLOparams["OrbitsPerTF"] = determined_orbits # determine timestamp, and production offset for the final MC job to run - timestamp, prod_offset = determine_timestamp(run_start, run_end, [args.split_id - 1, args.prod_split], args.cycle, args.tf, GLOparams["OrbitsPerTF"]) + timestamp = 0 + prod_offset = 0 + if args.timeframeID != -1: + timestamp = determine_timestamp_from_timeframeID(effective_run_start, run_end, args.timeframeID, GLOparams["OrbitsPerTF"]) + prod_offset = args.timeframeID + else: + timestamp, prod_offset = determine_timestamp(effective_run_start, run_end, [args.split_id - 1, args.prod_split], args.cycle, args.tf, GLOparams["OrbitsPerTF"]) # determine orbit corresponding to timestamp (mainly used in exclude_timestamp function) orbit = GLOparams["FirstOrbit"] + int((timestamp - GLOparams["SOR"]) / ( LHCOrbitMUS / 1000)) # this is anchored to - print ("Determined start-of-run to be: ", run_start) + print ("Determined start-of-run to be: ", effective_run_start) print ("Determined end-of-run to be: ", run_end) print ("Determined timestamp to be : ", timestamp) print ("Determined offset to be : ", prod_offset) @@ -531,10 +645,21 @@ def main(): forwardargs += ' --ctp-scaler ' + str(ctp_local_rate_raw) # we finally pass forward to the unanchored MC workflow creation - # TODO: this needs to be done in a pythonic way clearly - # NOTE: forwardargs can - in principle - contain some of the arguments that are appended here. However, the last passed argument wins, so they would be overwritten. - forwardargs += " -tf " + str(args.tf) + " --sor " + str(run_start) + " --timestamp " + str(timestamp) + " --production-offset " + str(prod_offset) + " -run " + str(args.run_number) + " --run-anchored --first-orbit " \ - + str(GLOparams["FirstOrbit"]) + " -field ccdb -bcPatternFile ccdb" + " --orbitsPerTF " + str(GLOparams["OrbitsPerTF"]) + " -col " + str(ColSystem) + " -eCM " + str(eCM) + ' --readoutDets ' + GLOparams['detList'] + # NOTE: forwardargs can - in principle - contain some of the arguments that are appended here. + # However, the last passed argument wins, so they would be overwritten. If this should not happen, the option + # needs to be handled as further below: + energyarg = (" -eCM " + str(eCM)) if A1 == A2 else (" -eA " + str(eA) + " -eB " + str(eB)) + forwardargs += " -tf " + str(args.tf) + " --sor " + str(effective_run_start) + " --timestamp " + str(timestamp) + " --production-offset " + str(prod_offset) + " -run " + str(args.run_number) + " --run-anchored --first-orbit " \ + + str(GLOparams["FirstOrbit"]) + " --orbitsPerTF " + str(GLOparams["OrbitsPerTF"]) + str(energyarg) + # the following options can be overwritten/influenced from the outside + if not '-col' in forwardargs: + forwardargs += ' -col ' + ColSystem + if not '--readoutDets' in forwardargs: + forwardargs += ' --readoutDets ' + GLOparams['detList'] + if not '-field' in forwardargs: + forwardargs += ' -field ccdb ' + if not '-bcPatternFile' in forwardargs: + forwardargs += ' -bcPatternFile ccdb ' print ("forward args ", forwardargs) cmd = "${O2DPG_ROOT}/MC/bin/o2dpg_sim_workflow.py " + forwardargs @@ -542,7 +667,34 @@ def main(): print ("TIMESTAMP IS EXCLUDED IN RUN") else: print ("Creating time-anchored workflow...") - os.system(cmd) + print ("Executing: " + cmd) + try: + cmd_list = shlex.split(os.path.expandvars(cmd)) + output = subprocess.check_output(cmd_list, text=True, stdin=subprocess.DEVNULL, timeout = 120) + print (output) + + # when we get here, we can publish info about the production (optionally) + if args.publish_mcprodinfo == True or os.getenv("PUBLISH_MCPRODINFO") != None: + prod_tag = os.getenv("ALIEN_JDL_LPMPRODUCTIONTAG") + grid_user_name = os.getenv("JALIEN_USER") + mcprod_ccdb_server = os.getenv("PUBLISH_MCPRODINFO_CCDBSERVER") + if mcprod_ccdb_server == None: + mcprod_ccdb_server = "https://alice-ccdb.cern.ch" + if prod_tag != None and grid_user_name != None: + info = MCProdInfo(LPMProductionTag = prod_tag, + Col = ColSystem, + IntRate =rate, + RunNumber = args.run_number, + OrbitsPerTF = GLOparams["OrbitsPerTF"]) + publish_MCProdInfo(info, username = grid_user_name, ccdb_url = mcprod_ccdb_server) + else: + print("No production tag or GRID user name known. Not publishing MCProdInfo") + + except subprocess.CalledProcessError as e: + print(f"Command failed with return code {e.returncode}") + print("Output:") + print(e.output) + return {}, {} if __name__ == "__main__": sys.exit(main()) diff --git a/MC/bin/o2dpg_workflow_utils.py b/MC/bin/o2dpg_workflow_utils.py index a196a9c86..763c472ab 100755 --- a/MC/bin/o2dpg_workflow_utils.py +++ b/MC/bin/o2dpg_workflow_utils.py @@ -22,7 +22,13 @@ def deactivate_detector(det): INACTIVE_DETECTORS.append(det) def isActive(det): - return det not in INACTIVE_DETECTORS and ("all" in ACTIVE_DETECTORS or det in ACTIVE_DETECTORS) + def check(detector): + return detector not in INACTIVE_DETECTORS and ("all" in ACTIVE_DETECTORS or detector in ACTIVE_DETECTORS) + + if det == "ITS": # special remapping for upgrade only needed in one direction since IT3 output pretends to be ITS + return check("ITS") or check("IT3") + else: + return check(det) def compute_n_workers(interaction_rate, collision_system, n_workers_user=8, n_workers_min=1, interaction_rate_linear_below=300000): """ @@ -172,6 +178,9 @@ def dump_workflow(workflow, filename, meta=None): s['cmd'] = '. ' + taskwrapper_string + ' ' + s['name']+'.log \'' + s['cmd'] + '\'' # remove unnecessary whitespaces for better readibility s['cmd'] = trimString(s['cmd']) + # remove None entries from needs list + s['needs'] = [ n for n in s['needs'] if n != None ] + # make the final dict to be dumped to_dump = {"stages": to_dump} filename = make_workflow_filename(filename) @@ -274,6 +283,14 @@ def adjust_RECO_environment(workflowspec, package = ""): if len(package) == 0: return + # we try to extract the stage from the path (can be given via '@' separation) + # example O2sim::daily-xxx@DIGI ---> apply this environment from the DIGI phase + # example O2sim::daily-xxx@RECO ---> apply this environment from the RECO phase + # example O2sim::daily-xxx ---> apply this environment from the RECO phase == default case + from_stage = "RECO" + if package.count('@') == 1: + package, from_stage = package.split('@') + # We essentially need to go through the graph and apply the mapping # so take the workflow spec and see if the task itself or any child # is labeled RECO ---> typical graph traversal with caching @@ -305,9 +322,11 @@ def matches_or_inherits_label(taskid, label, cache): # fills the matches_label dictionary for taskid in range(len(workflowspec['stages'])): - if (matches_or_inherits_label(taskid, "RECO", matches_label)): + if (matches_or_inherits_label(taskid, from_stage, matches_label)): # now we do the final adjust (as annotation) in the workflow itself - workflowspec['stages'][taskid]["alternative_alienv_package"] = package + if workflowspec['stages'][taskid].get('disable_alternative_reco_software', False) != True: + if workflowspec['stages'][taskid].get("alternative_alienv_package") == None: + workflowspec['stages'][taskid]["alternative_alienv_package"] = package def merge_dicts(dict1, dict2): """ diff --git a/MC/bin/tests/wf_test_pp.sh b/MC/bin/tests/wf_test_pp.sh index 4ce7068c7..2d7d04a63 100644 --- a/MC/bin/tests/wf_test_pp.sh +++ b/MC/bin/tests/wf_test_pp.sh @@ -10,8 +10,6 @@ [ ! "${O2DPG_ROOT}" ] && echo "Error: This needs O2DPG loaded" && exit 1 [ ! "${O2_ROOT}" ] && echo "Error: This needs O2 loaded" && exit 1 -# ----------- LOAD UTILITY FUNCTIONS -------------------------- -. ${O2_ROOT}/share/scripts/jobutils.sh # ----------- START ACTUAL JOB ----------------------------- diff --git a/MC/config/ALICE3/ini/central_strangeness_PbPb_552tev.ini b/MC/config/ALICE3/ini/central_strangeness_PbPb_552tev.ini new file mode 100644 index 000000000..30c665813 --- /dev/null +++ b/MC/config/ALICE3/ini/central_strangeness_PbPb_552tev.ini @@ -0,0 +1,9 @@ +[Diamond] +width[2]=6.0 + +[GeneratorExternal] +fileName=${O2DPG_MC_CONFIG_ROOT}/MC/config/ALICE3/pythia8/generator_pythia8_central_strangeness_gun_PbPb.C +funcName=generatePYTHIA() + +[GeneratorPythia8] +config=${O2DPG_MC_CONFIG_ROOT}/MC/config/ALICE3/pythia8/generator/pythia8_central_hi.cfg diff --git a/MC/config/ALICE3/ini/pythia8_PbPb_D0toKpi.ini b/MC/config/ALICE3/ini/pythia8_PbPb_D0toKpi.ini new file mode 100644 index 000000000..04f617fa0 --- /dev/null +++ b/MC/config/ALICE3/ini/pythia8_PbPb_D0toKpi.ini @@ -0,0 +1,9 @@ +[Diamond] +width[2]=6.0 + +[GeneratorExternal] +fileName=${O2DPG_MC_CONFIG_ROOT}/MC/config/ALICE3/pythia8/generator_pythia8_ALICE3.C +funcName=generator_pythia8_ALICE3() + +[GeneratorPythia8] +config=${O2DPG_MC_CONFIG_ROOT}/MC/config/ALICE3/pythia8/generator/pythia8_PbPb_D0toKpi.cfg diff --git a/MC/config/ALICE3/ini/pythia8_pp_502tev.ini b/MC/config/ALICE3/ini/pythia8_pp_502tev.ini new file mode 100644 index 000000000..3c73b4e1a --- /dev/null +++ b/MC/config/ALICE3/ini/pythia8_pp_502tev.ini @@ -0,0 +1,9 @@ +[Diamond] +width[2]=6.0 + +[GeneratorExternal] +fileName=${O2DPG_MC_CONFIG_ROOT}/MC/config/ALICE3/pythia8/generator_pythia8_ALICE3.C +funcName=generator_pythia8_ALICE3() + +[GeneratorPythia8] +config=${O2DPG_MC_CONFIG_ROOT}/MC/config/ALICE3/pythia8/generator/pythia8_pp_502tev.cfg diff --git a/MC/config/ALICE3/ini/pythia8_pp_536tev.ini b/MC/config/ALICE3/ini/pythia8_pp_536tev.ini new file mode 100644 index 000000000..528de37c2 --- /dev/null +++ b/MC/config/ALICE3/ini/pythia8_pp_536tev.ini @@ -0,0 +1,9 @@ +[Diamond] +width[2]=6.0 + +[GeneratorExternal] +fileName=${O2DPG_MC_CONFIG_ROOT}/MC/config/ALICE3/pythia8/generator_pythia8_ALICE3.C +funcName=generator_pythia8_ALICE3() + +[GeneratorPythia8] +config=${O2DPG_MC_CONFIG_ROOT}/MC/config/ALICE3/pythia8/generator/pythia8_pp_536tev.cfg diff --git a/MC/config/ALICE3/ini/pythia8_pp_7tev.ini b/MC/config/ALICE3/ini/pythia8_pp_7tev.ini new file mode 100644 index 000000000..5c4b1336e --- /dev/null +++ b/MC/config/ALICE3/ini/pythia8_pp_7tev.ini @@ -0,0 +1,9 @@ +[Diamond] +width[2]=6.0 + +[GeneratorExternal] +fileName=${O2DPG_MC_CONFIG_ROOT}/MC/config/ALICE3/pythia8/generator_pythia8_ALICE3.C +funcName=generator_pythia8_ALICE3() + +[GeneratorPythia8] +config=${O2DPG_MC_CONFIG_ROOT}/MC/config/ALICE3/pythia8/generator/pythia8_pp_7tev.cfg diff --git a/MC/config/ALICE3/ini/pythia8_pp_clr-blc0_13tev.ini b/MC/config/ALICE3/ini/pythia8_pp_clr-blc0_13tev.ini new file mode 100644 index 000000000..a08d45738 --- /dev/null +++ b/MC/config/ALICE3/ini/pythia8_pp_clr-blc0_13tev.ini @@ -0,0 +1,9 @@ +[Diamond] +width[2]=6.0 + +[GeneratorExternal] +fileName=${O2DPG_MC_CONFIG_ROOT}/MC/config/ALICE3/pythia8/generator_pythia8_ALICE3.C +funcName=generator_pythia8_ALICE3() + +[GeneratorPythia8] +config=${O2DPG_MC_CONFIG_ROOT}/MC/config/ALICE3/pythia8/generator/pythia8_pp_clr-blc0_13tev.cfg diff --git a/MC/config/ALICE3/ini/pythia8_pp_clr-blc2_13tev.ini b/MC/config/ALICE3/ini/pythia8_pp_clr-blc2_13tev.ini new file mode 100644 index 000000000..25474d61c --- /dev/null +++ b/MC/config/ALICE3/ini/pythia8_pp_clr-blc2_13tev.ini @@ -0,0 +1,9 @@ +[Diamond] +width[2]=6.0 + +[GeneratorExternal] +fileName=${O2DPG_MC_CONFIG_ROOT}/MC/config/ALICE3/pythia8/generator_pythia8_ALICE3.C +funcName=generator_pythia8_ALICE3() + +[GeneratorPythia8] +config=${O2DPG_MC_CONFIG_ROOT}/MC/config/ALICE3/pythia8/generator/pythia8_pp_clr-blc2_13tev.cfg diff --git a/MC/config/ALICE3/ini/pythia8_pp_clr-blc3_13tev.ini b/MC/config/ALICE3/ini/pythia8_pp_clr-blc3_13tev.ini new file mode 100644 index 000000000..00ee82a3f --- /dev/null +++ b/MC/config/ALICE3/ini/pythia8_pp_clr-blc3_13tev.ini @@ -0,0 +1,9 @@ +[Diamond] +width[2]=6.0 + +[GeneratorExternal] +fileName=${O2DPG_MC_CONFIG_ROOT}/MC/config/ALICE3/pythia8/generator_pythia8_ALICE3.C +funcName=generator_pythia8_ALICE3() + +[GeneratorPythia8] +config=${O2DPG_MC_CONFIG_ROOT}/MC/config/ALICE3/pythia8/generator/pythia8_pp_clr-blc3_13tev.cfg diff --git a/MC/config/ALICE3/ini/pythia8_pp_cr_136tev.ini b/MC/config/ALICE3/ini/pythia8_pp_cr_136tev.ini new file mode 100644 index 000000000..420f99495 --- /dev/null +++ b/MC/config/ALICE3/ini/pythia8_pp_cr_136tev.ini @@ -0,0 +1,9 @@ +[Diamond] +width[2]=6.0 + +[GeneratorExternal] +fileName=${O2DPG_MC_CONFIG_ROOT}/MC/config/ALICE3/pythia8/generator_pythia8_ALICE3.C +funcName=generator_pythia8_ALICE3() + +[GeneratorPythia8] +config=${O2DPG_MC_CONFIG_ROOT}/MC/config/ALICE3/pythia8/generator/pythia8_pp_cr_136tev.cfg diff --git a/MC/config/ALICE3/ini/pythia8_pp_rescattering_136tev.ini b/MC/config/ALICE3/ini/pythia8_pp_rescattering_136tev.ini new file mode 100644 index 000000000..4189c775a --- /dev/null +++ b/MC/config/ALICE3/ini/pythia8_pp_rescattering_136tev.ini @@ -0,0 +1,9 @@ +[Diamond] +width[2]=6.0 + +[GeneratorExternal] +fileName=${O2DPG_MC_CONFIG_ROOT}/MC/config/ALICE3/pythia8/generator_pythia8_ALICE3.C +funcName=generator_pythia8_ALICE3() + +[GeneratorPythia8] +config=${O2DPG_MC_CONFIG_ROOT}/MC/config/ALICE3/pythia8/generator/pythia8_pp_rescattering_136tev.cfg diff --git a/MC/config/ALICE3/ini/tests/central_strangeness_PbPb_552tev.C b/MC/config/ALICE3/ini/tests/central_strangeness_PbPb_552tev.C new file mode 100644 index 000000000..bdb092295 --- /dev/null +++ b/MC/config/ALICE3/ini/tests/central_strangeness_PbPb_552tev.C @@ -0,0 +1,36 @@ +int External() +{ + std::string path{"o2sim_Kine.root"}; + + TFile file(path.c_str(), "READ"); + if (file.IsZombie()) { + std::cerr << "Cannot open ROOT file " << path << "\n"; + return 1; + } + + auto tree = (TTree *)file.Get("o2sim"); + if (!tree) { + std::cerr << "Cannot find tree o2sim in file " << path << "\n"; + return 1; + } + + std::vector *tracks{}; + tree->SetBranchAddress("MCTrack", &tracks); + auto nEvents = tree->GetEntries(); + int nTracks = 0; + for (int i = 0; i < nEvents; i++) { + tree->GetEntry(i); + nTracks += tracks->size(); + } + + const int meanNTracksPerEvent = nTracks / nEvents; + + // Expecting only events with a 0-10% centrality + // 0-100% gives a mean of ~1350 + // 2300 should be enough + if (meanNTracksPerEvent < 2300) { + return 1; + } + + return 0; +} \ No newline at end of file diff --git a/MC/config/ALICE3/ini/tests/pythia8_ArAr.C b/MC/config/ALICE3/ini/tests/pythia8_ArAr.C index 49c15680f..0676e4c22 100644 --- a/MC/config/ALICE3/ini/tests/pythia8_ArAr.C +++ b/MC/config/ALICE3/ini/tests/pythia8_ArAr.C @@ -2,7 +2,7 @@ int External() { return 0; } -int Pythia8() +int pythia8() { return External(); } \ No newline at end of file diff --git a/MC/config/ALICE3/ini/tests/pythia8_KrKr.C b/MC/config/ALICE3/ini/tests/pythia8_KrKr.C index 49c15680f..0676e4c22 100644 --- a/MC/config/ALICE3/ini/tests/pythia8_KrKr.C +++ b/MC/config/ALICE3/ini/tests/pythia8_KrKr.C @@ -2,7 +2,7 @@ int External() { return 0; } -int Pythia8() +int pythia8() { return External(); } \ No newline at end of file diff --git a/MC/config/ALICE3/ini/tests/pythia8_OO.C b/MC/config/ALICE3/ini/tests/pythia8_OO.C index 49c15680f..0676e4c22 100644 --- a/MC/config/ALICE3/ini/tests/pythia8_OO.C +++ b/MC/config/ALICE3/ini/tests/pythia8_OO.C @@ -2,7 +2,7 @@ int External() { return 0; } -int Pythia8() +int pythia8() { return External(); } \ No newline at end of file diff --git a/MC/config/ALICE3/ini/tests/pythia8_PbPb.C b/MC/config/ALICE3/ini/tests/pythia8_PbPb.C index 49c15680f..0676e4c22 100644 --- a/MC/config/ALICE3/ini/tests/pythia8_PbPb.C +++ b/MC/config/ALICE3/ini/tests/pythia8_PbPb.C @@ -2,7 +2,7 @@ int External() { return 0; } -int Pythia8() +int pythia8() { return External(); } \ No newline at end of file diff --git a/MC/config/ALICE3/ini/tests/pythia8_PbPb_536tev.C b/MC/config/ALICE3/ini/tests/pythia8_PbPb_536tev.C index 49c15680f..0676e4c22 100644 --- a/MC/config/ALICE3/ini/tests/pythia8_PbPb_536tev.C +++ b/MC/config/ALICE3/ini/tests/pythia8_PbPb_536tev.C @@ -2,7 +2,7 @@ int External() { return 0; } -int Pythia8() +int pythia8() { return External(); } \ No newline at end of file diff --git a/MC/config/ALICE3/ini/tests/pythia8_XeXe.C b/MC/config/ALICE3/ini/tests/pythia8_XeXe.C index 49c15680f..0676e4c22 100644 --- a/MC/config/ALICE3/ini/tests/pythia8_XeXe.C +++ b/MC/config/ALICE3/ini/tests/pythia8_XeXe.C @@ -2,7 +2,7 @@ int External() { return 0; } -int Pythia8() +int pythia8() { return External(); } \ No newline at end of file diff --git a/MC/config/ALICE3/ini/tests/pythia8_pp.C b/MC/config/ALICE3/ini/tests/pythia8_pp.C index 49c15680f..0676e4c22 100644 --- a/MC/config/ALICE3/ini/tests/pythia8_pp.C +++ b/MC/config/ALICE3/ini/tests/pythia8_pp.C @@ -2,7 +2,7 @@ int External() { return 0; } -int Pythia8() +int pythia8() { return External(); } \ No newline at end of file diff --git a/MC/config/ALICE3/ini/tests/pythia8_pp_136tev.C b/MC/config/ALICE3/ini/tests/pythia8_pp_136tev.C index 49c15680f..0676e4c22 100644 --- a/MC/config/ALICE3/ini/tests/pythia8_pp_136tev.C +++ b/MC/config/ALICE3/ini/tests/pythia8_pp_136tev.C @@ -2,7 +2,7 @@ int External() { return 0; } -int Pythia8() +int pythia8() { return External(); } \ No newline at end of file diff --git a/MC/config/ALICE3/ini/tests/pythia8_pp_clr-blc0_13tev.C b/MC/config/ALICE3/ini/tests/pythia8_pp_clr-blc0_13tev.C new file mode 100644 index 000000000..d258500c3 --- /dev/null +++ b/MC/config/ALICE3/ini/tests/pythia8_pp_clr-blc0_13tev.C @@ -0,0 +1,19 @@ +int External() +{ + std::string path{"o2sim_Kine.root"}; + + TFile file(path.c_str(), "read"); + if (file.IsZombie()) { + std::cerr << "Cannot open ROOT file " << path << std::endl; + return 1; + } + + TTree* tree = (TTree*)file.Get("o2sim"); + + if (!tree) { + std::cerr << "Cannot find tree o2sim in file " << path << "\n"; + return 1; + } + + return 0; +} diff --git a/MC/config/ALICE3/ini/tests/pythia8_pp_clr-blc2_13tev.C b/MC/config/ALICE3/ini/tests/pythia8_pp_clr-blc2_13tev.C new file mode 120000 index 000000000..fbe2c4ed8 --- /dev/null +++ b/MC/config/ALICE3/ini/tests/pythia8_pp_clr-blc2_13tev.C @@ -0,0 +1 @@ +pythia8_pp_clr-blc0_13tev.C \ No newline at end of file diff --git a/MC/config/ALICE3/ini/tests/pythia8_pp_clr-blc3_13tev.C b/MC/config/ALICE3/ini/tests/pythia8_pp_clr-blc3_13tev.C new file mode 120000 index 000000000..fbe2c4ed8 --- /dev/null +++ b/MC/config/ALICE3/ini/tests/pythia8_pp_clr-blc3_13tev.C @@ -0,0 +1 @@ +pythia8_pp_clr-blc0_13tev.C \ No newline at end of file diff --git a/MC/config/ALICE3/ini/tests/pythia8_pp_hardQCD_136tev.C b/MC/config/ALICE3/ini/tests/pythia8_pp_hardQCD_136tev.C index 49c15680f..0676e4c22 100644 --- a/MC/config/ALICE3/ini/tests/pythia8_pp_hardQCD_136tev.C +++ b/MC/config/ALICE3/ini/tests/pythia8_pp_hardQCD_136tev.C @@ -2,7 +2,7 @@ int External() { return 0; } -int Pythia8() +int pythia8() { return External(); } \ No newline at end of file diff --git a/MC/config/ALICE3/ini/tests/pythia8_pp_hf_hardQCD_136tev.C b/MC/config/ALICE3/ini/tests/pythia8_pp_hf_hardQCD_136tev.C index 49c15680f..0676e4c22 100644 --- a/MC/config/ALICE3/ini/tests/pythia8_pp_hf_hardQCD_136tev.C +++ b/MC/config/ALICE3/ini/tests/pythia8_pp_hf_hardQCD_136tev.C @@ -2,7 +2,7 @@ int External() { return 0; } -int Pythia8() +int pythia8() { return External(); } \ No newline at end of file diff --git a/MC/config/ALICE3/ini/tests/pythia8_pp_rescattering_136tev.C b/MC/config/ALICE3/ini/tests/pythia8_pp_rescattering_136tev.C new file mode 100644 index 000000000..9b21ec151 --- /dev/null +++ b/MC/config/ALICE3/ini/tests/pythia8_pp_rescattering_136tev.C @@ -0,0 +1,24 @@ +int External() { + std::string path{"o2sim_Kine.root"}; + + TFile file(path.c_str(), "READ"); + if (file.IsZombie()) { + std::cerr << "Cannot open ROOT file " << path << "\n"; + return 1; + } + + auto tree = (TTree *)file.Get("o2sim"); + if (!tree) { + std::cerr << "Cannot find tree o2sim in file " << path << "\n"; + return 1; + } + std::vector *tracks{}; + tree->SetBranchAddress("MCTrack", &tracks); + + auto nEvents = tree->GetEntries(); + if (nEvents == 0) { + std::cerr << "No event of interest\n"; + return 1; + } + return 0; +} \ No newline at end of file diff --git a/MC/config/ALICE3/ini/tests/pythia8_pp_ropes.C b/MC/config/ALICE3/ini/tests/pythia8_pp_ropes.C index 49c15680f..0676e4c22 100644 --- a/MC/config/ALICE3/ini/tests/pythia8_pp_ropes.C +++ b/MC/config/ALICE3/ini/tests/pythia8_pp_ropes.C @@ -2,7 +2,7 @@ int External() { return 0; } -int Pythia8() +int pythia8() { return External(); } \ No newline at end of file diff --git a/MC/config/ALICE3/ini/tests/pythia8_pp_ropes_136tev.C b/MC/config/ALICE3/ini/tests/pythia8_pp_ropes_136tev.C index 49c15680f..0676e4c22 100644 --- a/MC/config/ALICE3/ini/tests/pythia8_pp_ropes_136tev.C +++ b/MC/config/ALICE3/ini/tests/pythia8_pp_ropes_136tev.C @@ -2,7 +2,7 @@ int External() { return 0; } -int Pythia8() +int pythia8() { return External(); } \ No newline at end of file diff --git a/MC/config/ALICE3/ini/tests/pythia8_pp_shoving.C b/MC/config/ALICE3/ini/tests/pythia8_pp_shoving.C index 49c15680f..0676e4c22 100644 --- a/MC/config/ALICE3/ini/tests/pythia8_pp_shoving.C +++ b/MC/config/ALICE3/ini/tests/pythia8_pp_shoving.C @@ -2,7 +2,7 @@ int External() { return 0; } -int Pythia8() +int pythia8() { return External(); } \ No newline at end of file diff --git a/MC/config/ALICE3/ini/tests/pythia8_pp_shoving_136tev.C b/MC/config/ALICE3/ini/tests/pythia8_pp_shoving_136tev.C index 49c15680f..0676e4c22 100644 --- a/MC/config/ALICE3/ini/tests/pythia8_pp_shoving_136tev.C +++ b/MC/config/ALICE3/ini/tests/pythia8_pp_shoving_136tev.C @@ -2,7 +2,7 @@ int External() { return 0; } -int Pythia8() +int pythia8() { return External(); } \ No newline at end of file diff --git a/MC/config/ALICE3/ini/tests/xi_PbPb.C b/MC/config/ALICE3/ini/tests/xi_PbPb.C new file mode 100644 index 000000000..5d55db370 --- /dev/null +++ b/MC/config/ALICE3/ini/tests/xi_PbPb.C @@ -0,0 +1,46 @@ +int External() +{ + std::string path{"o2sim_Kine.root"}; + int pdgToCheck = 3312; + + TFile file(path.c_str(), "read"); + if (file.IsZombie()) { + std::cerr << "Cannot open ROOT file " << path << std::endl; + return 1; + } + + int nInjectedParticles = 0; + TTree* tree = (TTree*)file.Get("o2sim"); + + if (!tree) { + std::cerr << "Cannot find tree o2sim in file " << path << std::endl; + return 1; + } + + std::vector *tracks{}; + tree->SetBranchAddress("MCTrack", &tracks); + + int nEvents = tree->GetEntries(); + for (int i = 0; i < nEvents; i++) { + tree->GetEntry(i); + for (auto& track : *tracks) { + auto pdgCode = track.GetPdgCode(); + if (pdgCode == pdgToCheck) { + // not injecting anti-particle + nInjectedParticles++; + } + } + } + + if (nInjectedParticles < nEvents) { + // Check that we are correctly injecting 15 + // particle per event + return 1; + } + + return 0; +} + + + + diff --git a/MC/config/ALICE3/ini/tests/xi_pp.C b/MC/config/ALICE3/ini/tests/xi_pp.C new file mode 100644 index 000000000..9a09b788e --- /dev/null +++ b/MC/config/ALICE3/ini/tests/xi_pp.C @@ -0,0 +1,46 @@ +int External() +{ + std::string path{"o2sim_Kine.root"}; + int pdgToCheck = 3312; + + TFile file(path.c_str(), "read"); + if (file.IsZombie()) { + std::cerr << "Cannot open ROOT file " << path << std::endl; + return 1; + } + + int nInjectedParticles = 0; + TTree* tree = (TTree*)file.Get("o2sim"); + + if (!tree) { + std::cerr << "Cannot find tree o2sim in file " << path << "\n"; + return 1; + } + + std::vector *tracks{}; + tree->SetBranchAddress("MCTrack", &tracks); + + int nEvents = tree->GetEntries(); + for (int i = 0; i < nEvents; i++) { + tree->GetEntry(i); + for (auto& track : *tracks) { + auto pdgCode = track.GetPdgCode(); + if (pdgCode == pdgToCheck) { + // not injecting anti-particle + nInjectedParticles++; + } + } + } + + if (nInjectedParticles < nEvents) { + // Check that we are correctly injecting one + // particle per event + return 1; + } + + return 0; +} + + + + diff --git a/MC/config/ALICE3/ini/tests/xic_PbPb.C b/MC/config/ALICE3/ini/tests/xic_PbPb.C new file mode 100644 index 000000000..8286b733b --- /dev/null +++ b/MC/config/ALICE3/ini/tests/xic_PbPb.C @@ -0,0 +1,46 @@ +int External() +{ + std::string path{"o2sim_Kine.root"}; + int pdgToCheck = 4232; + + TFile file(path.c_str(), "read"); + if (file.IsZombie()) { + std::cerr << "Cannot open ROOT file " << path << std::endl; + return 1; + } + + int nInjectedParticles = 0; + TTree* tree = (TTree*)file.Get("o2sim"); + + if (!tree) { + std::cerr << "Cannot find tree o2sim in file " << path << std::endl; + return 1; + } + + std::vector *tracks{}; + tree->SetBranchAddress("MCTrack", &tracks); + + int nEvents = tree->GetEntries(); + for (int i = 0; i < nEvents; i++) { + tree->GetEntry(i); + for (auto& track : *tracks) { + auto pdgCode = track.GetPdgCode(); + if (pdgCode == pdgToCheck) { + // not injecting anti-particle + nInjectedParticles++; + } + } + } + + if (nInjectedParticles < nEvents) { + // Check that we are correctly injecting 15 + // particle per event + return 1; + } + + return 0; +} + + + + diff --git a/MC/config/ALICE3/ini/tests/xic_pp.C b/MC/config/ALICE3/ini/tests/xic_pp.C new file mode 100644 index 000000000..5b531f7b8 --- /dev/null +++ b/MC/config/ALICE3/ini/tests/xic_pp.C @@ -0,0 +1,46 @@ +int External() +{ + std::string path{"o2sim_Kine.root"}; + int pdgToCheck = 4232; + + TFile file(path.c_str(), "read"); + if (file.IsZombie()) { + std::cerr << "Cannot open ROOT file " << path << std::endl; + return 1; + } + + int nInjectedParticles = 0; + TTree* tree = (TTree*)file.Get("o2sim"); + + if (!tree) { + std::cerr << "Cannot find tree o2sim in file " << path << "\n"; + return 1; + } + + std::vector *tracks{}; + tree->SetBranchAddress("MCTrack", &tracks); + + int nEvents = tree->GetEntries(); + for (int i = 0; i < nEvents; i++) { + tree->GetEntry(i); + for (auto& track : *tracks) { + auto pdgCode = track.GetPdgCode(); + if (pdgCode == pdgToCheck) { + // not injecting anti-particle + nInjectedParticles++; + } + } + } + + if (nInjectedParticles < nEvents) { + // Check that we are correctly injecting one + // particle per event + return 1; + } + + return 0; +} + + + + diff --git a/MC/config/ALICE3/ini/tests/xicc_background_PbPb.C b/MC/config/ALICE3/ini/tests/xicc_background_PbPb.C new file mode 100644 index 000000000..63ce4a977 --- /dev/null +++ b/MC/config/ALICE3/ini/tests/xicc_background_PbPb.C @@ -0,0 +1,38 @@ +int External() +{ + std::string path{"o2sim_Kine.root"}; + + TFile file(path.c_str(), "READ"); + if (file.IsZombie()) { + std::cerr << "Cannot open ROOT file " << path << "\n"; + return 1; + } + + auto tree = (TTree *)file.Get("o2sim"); + if (!tree) { + std::cerr << "Cannot find tree o2sim in file " << path << "\n"; + return 1; + } + + std::vector *tracks{}; + tree->SetBranchAddress("MCTrack", &tracks); + auto nEvents = tree->GetEntries(); + int nInjected = 0; + for (int i = 0; i < nEvents; i++) { + tree->GetEntry(i); + for (auto& track : *tracks) { + auto pdgCode = std::fabs(track.GetPdgCode()); + if (pdgCode == 3312) { + nInjected++; + } + } + } + + // Check if we are above typical Angantyr numbers + if (nInjected < 5 * nEvents) { + std::cerr << "Too few particles injected\n"; + return 1; + } + + return 0; +} \ No newline at end of file diff --git a/MC/config/ALICE3/ini/xi_PbPb.ini b/MC/config/ALICE3/ini/xi_PbPb.ini new file mode 100755 index 000000000..efa324ead --- /dev/null +++ b/MC/config/ALICE3/ini/xi_PbPb.ini @@ -0,0 +1,6 @@ +[GeneratorExternal] +fileName=${O2DPG_MC_CONFIG_ROOT}/MC/config/ALICE3/pythia8/generator_pythia8_gun_PbPb.C +funcName=generateNativeXi() + +[GeneratorPythia8] +config=${O2DPG_MC_CONFIG_ROOT}/MC/config/ALICE3/pythia8/generator/config_custom_xicc.cfg \ No newline at end of file diff --git a/MC/config/ALICE3/ini/xi_pp.ini b/MC/config/ALICE3/ini/xi_pp.ini new file mode 100755 index 000000000..90039ae12 --- /dev/null +++ b/MC/config/ALICE3/ini/xi_pp.ini @@ -0,0 +1,6 @@ +[GeneratorExternal] +fileName=${O2DPG_MC_CONFIG_ROOT}/MC/config/ALICE3/pythia8/generator_pythia8_gun_pp.C +funcName=generateNativeXi() + +[GeneratorPythia8] +config=${O2DPG_MC_CONFIG_ROOT}/MC/config/ALICE3/pythia8/generator/config_custom_xicc.cfg \ No newline at end of file diff --git a/MC/config/ALICE3/ini/xic_PbPb.ini b/MC/config/ALICE3/ini/xic_PbPb.ini new file mode 100755 index 000000000..4e8c02141 --- /dev/null +++ b/MC/config/ALICE3/ini/xic_PbPb.ini @@ -0,0 +1,6 @@ +[GeneratorExternal] +fileName=${O2DPG_MC_CONFIG_ROOT}/MC/config/ALICE3/pythia8/generator_pythia8_gun_PbPb.C +funcName=generateNativeXiC() + +[GeneratorPythia8] +config=${O2DPG_MC_CONFIG_ROOT}/MC/config/ALICE3/pythia8/generator/config_custom_xicc.cfg \ No newline at end of file diff --git a/MC/config/ALICE3/ini/xic_pp.ini b/MC/config/ALICE3/ini/xic_pp.ini new file mode 100755 index 000000000..df8a3d220 --- /dev/null +++ b/MC/config/ALICE3/ini/xic_pp.ini @@ -0,0 +1,6 @@ +[GeneratorExternal] +fileName=${O2DPG_MC_CONFIG_ROOT}/MC/config/ALICE3/pythia8/generator_pythia8_gun_pp.C +funcName=generateNativeXiC() + +[GeneratorPythia8] +config=${O2DPG_MC_CONFIG_ROOT}/MC/config/ALICE3/pythia8/generator/config_custom_xicc.cfg \ No newline at end of file diff --git a/MC/config/ALICE3/ini/xicc_background_PbPb.ini b/MC/config/ALICE3/ini/xicc_background_PbPb.ini new file mode 100644 index 000000000..cc6c54be5 --- /dev/null +++ b/MC/config/ALICE3/ini/xicc_background_PbPb.ini @@ -0,0 +1,9 @@ +[Diamond] +width[2]=6.0 + +[GeneratorExternal] +fileName=${O2DPG_MC_CONFIG_ROOT}/MC/config/ALICE3/pythia8/generator_pythia8_strangeness_gun_PbPb.C +funcName=generatePYTHIA() + +[GeneratorPythia8] +config=${O2DPG_MC_CONFIG_ROOT}/MC/config/ALICE3/pythia8/generator/pythia8_PbPb.cfg diff --git a/MC/config/ALICE3/pythia8/generator/pythia8_PbPb_D0toKpi.cfg b/MC/config/ALICE3/pythia8/generator/pythia8_PbPb_D0toKpi.cfg new file mode 100644 index 000000000..039d501a5 --- /dev/null +++ b/MC/config/ALICE3/pythia8/generator/pythia8_PbPb_D0toKpi.cfg @@ -0,0 +1,20 @@ +### Specify beams +Beams:idA = 1000822080 +Beams:idB = 1000822080 +Beams:eCM = 5520.0 ### energy + +Beams:frameType = 1 +ParticleDecays:limitTau0 = on +ParticleDecays:tau0Max = 10. ### match alice: 1cm/c = 10.0mm/c + +### Initialize the Angantyr model to fit the total and semi-includive +### cross sections in Pythia within some tolerance. +HeavyIon:SigFitErr = 0.02,0.02,0.1,0.05,0.05,0.0,0.1,0.0 + +### These parameters are typicall suitable for sqrt(S_NN)=5TeV +HeavyIon:SigFitDefPar = 17.24,2.15,0.33,0.0,0.0,0.0,0.0,0.0 + +### Force decay of D0 into Kpi +421:oneChannel = 1 0.0389 0 -321 211 + +Random:setSeed = on diff --git a/MC/config/ALICE3/pythia8/generator/pythia8_central_hi.cfg b/MC/config/ALICE3/pythia8/generator/pythia8_central_hi.cfg new file mode 100755 index 000000000..cb7e7cec0 --- /dev/null +++ b/MC/config/ALICE3/pythia8/generator/pythia8_central_hi.cfg @@ -0,0 +1,20 @@ +### Specify beams +Beams:idA = 1000822080 +Beams:idB = 1000822080 +Beams:eCM = 5520.0 ### energy + +Beams:frameType = 1 +ParticleDecays:limitTau0 = on +ParticleDecays:tau0Max = 10. ### match alice: 1cm/c = 10.0mm/c + +### Initialize the Angantyr model to fit the total and semi-includive +### cross sections in Pythia within some tolerance. +HeavyIon:SigFitErr = 0.02,0.02,0.1,0.05,0.05,0.0,0.1,0.0 + +### These parameters are typicall suitable for sqrt(S_NN)=5TeV +HeavyIon:SigFitNGen = 0 +HeavyIon:SigFitDefPar = 13.88,1.84,0.22,0.0,0.0,0.0,0.0,0.0 +HeavyIon:bWidth = 4.43 + + +Random:setSeed = on \ No newline at end of file diff --git a/MC/config/ALICE3/pythia8/generator/pythia8_central_hi.cmnd b/MC/config/ALICE3/pythia8/generator/pythia8_central_hi.cmnd new file mode 100755 index 000000000..713f1b36d --- /dev/null +++ b/MC/config/ALICE3/pythia8/generator/pythia8_central_hi.cmnd @@ -0,0 +1,21 @@ +### beams +Beams:idA 1000822080 # Pb +Beams:idB 1000822080 # Pb +Beams:eCM 5520. # GeV + +### heavy-ion settings (valid for Pb-Pb 5520 only) +HeavyIon:SigFitNGen = 0 +HeavyIon:SigFitDefPar = 13.88,1.84,0.22,0.0,0.0,0.0,0.0,0.0 +HeavyIon:bWidth = 4.43 + +### processes (apparently not to be defined) + +### decays +ParticleDecays:limitTau0 on +ParticleDecays:tau0Max 0.001 + +! 2) Seed settings +! Seed is set inside the generator +! If run on the grid, seed is set to job id +! If run locally, seed is set to 0 +Random:setSeed = on ! Random seed on diff --git a/MC/config/ALICE3/pythia8/generator/pythia8_pp_502tev.cfg b/MC/config/ALICE3/pythia8/generator/pythia8_pp_502tev.cfg new file mode 100644 index 000000000..68e3ef034 --- /dev/null +++ b/MC/config/ALICE3/pythia8/generator/pythia8_pp_502tev.cfg @@ -0,0 +1,16 @@ +### Specify beams +Beams:idA = 2212 +Beams:idB = 2212 +Beams:eCM = 5020. ### energy + +Beams:frameType = 1 +ParticleDecays:limitTau0 = on +ParticleDecays:tau0Max = 10. ### match alice: 1cm/c = 10.0mm/c + +### processes +SoftQCD:inelastic = on # all inelastic processes + +# default: do nothing, Monash 2013 will do its thing +Tune:pp = 14 + +Random:setSeed = on diff --git a/MC/config/ALICE3/pythia8/generator/pythia8_pp_536tev.cfg b/MC/config/ALICE3/pythia8/generator/pythia8_pp_536tev.cfg new file mode 100644 index 000000000..1f270e206 --- /dev/null +++ b/MC/config/ALICE3/pythia8/generator/pythia8_pp_536tev.cfg @@ -0,0 +1,16 @@ +### Specify beams +Beams:idA = 2212 +Beams:idB = 2212 +Beams:eCM = 5360. ### energy + +Beams:frameType = 1 +ParticleDecays:limitTau0 = on +ParticleDecays:tau0Max = 10. ### match alice: 1cm/c = 10.0mm/c + +### processes +SoftQCD:inelastic = on # all inelastic processes + +# default: do nothing, Monash 2013 will do its thing +Tune:pp = 14 + +Random:setSeed = on diff --git a/MC/config/ALICE3/pythia8/generator/pythia8_pp_7tev.cfg b/MC/config/ALICE3/pythia8/generator/pythia8_pp_7tev.cfg new file mode 100644 index 000000000..c1bc3b3c0 --- /dev/null +++ b/MC/config/ALICE3/pythia8/generator/pythia8_pp_7tev.cfg @@ -0,0 +1,16 @@ +### Specify beams +Beams:idA = 2212 +Beams:idB = 2212 +Beams:eCM = 7000. ### energy + +Beams:frameType = 1 +ParticleDecays:limitTau0 = on +ParticleDecays:tau0Max = 10. ### match alice: 1cm/c = 10.0mm/c + +### processes +SoftQCD:inelastic = on # all inelastic processes + +# default: do nothing, Monash 2013 will do its thing +Tune:pp = 14 + +Random:setSeed = on diff --git a/MC/config/ALICE3/pythia8/generator/pythia8_pp_clr-blc0_13tev.cfg b/MC/config/ALICE3/pythia8/generator/pythia8_pp_clr-blc0_13tev.cfg new file mode 100644 index 000000000..a5fc8e17f --- /dev/null +++ b/MC/config/ALICE3/pythia8/generator/pythia8_pp_clr-blc0_13tev.cfg @@ -0,0 +1,44 @@ +### ============================================ +### PYTHIA 8 — CLR-BLC Mode 0 configuration +### Based on table: Monash vs CLR-BLC (Mode 0) https://link.springer.com/article/10.1007/JHEP08(2015)003 in Appendix A +### ============================================ + +### Beams +Beams:idA = 2212 +Beams:idB = 2212 +Beams:eCM = 13000. +Beams:frameType = 1 + +### Decays (match ALICE) +ParticleDecays:limitTau0 = on +ParticleDecays:tau0Max = 10.0 + +### Processes and base tune +SoftQCD:inelastic = on # all inelastic processes +Tune:pp = 14 # Monash 2013 as baseline + +### String fragmentation +StringPT:sigma = 0.335 +StringZ:aLund = 0.36 +StringZ:bLund = 0.56 +StringFlav:probQQtoQ = 0.078 # probQQtoQ → Q (Mode 0,2,3) +StringFlav:probStoUD = 0.20 # s/u,d suppression (Mode 0,2,3) + +# Diquark–diquark join probabilities (vector of 4 numbers) +StringFlav:probQQ1toQQ0join = 0.0275,0.0275,0.0275,0.0275 # (Mode 0,2,3) +### Multi-parton interactions +MultiPartonInteractions:pT0Ref = 2.12 # Mode 0 pT0Ref + +### Beam remnants +BeamRemnants:remnantMode = 1 # required for CR mode 1 +BeamRemnants:saturation = 5 + +### Colour reconnection: CLR-BLC Mode 0 +ColourReconnection:mode = 1 # new CR scheme +ColourReconnection:allowDoubleJunRem = off # as in table +ColourReconnection:m0 = 2.9 # Mode 0 mass scale +ColourReconnection:allowJunctions = on +ColourReconnection:junctionCorrection = 1.43 # Mode 0 +ColourReconnection:timeDilationMode = 0 # Mode 0 + +Random:setSeed = on diff --git a/MC/config/ALICE3/pythia8/generator/pythia8_pp_clr-blc2_13tev.cfg b/MC/config/ALICE3/pythia8/generator/pythia8_pp_clr-blc2_13tev.cfg new file mode 100644 index 000000000..405de08bb --- /dev/null +++ b/MC/config/ALICE3/pythia8/generator/pythia8_pp_clr-blc2_13tev.cfg @@ -0,0 +1,45 @@ +### ============================================ +### PYTHIA 8 — CLR-BLC Mode 2 configuration +### Based on table: Monash vs CLR-BLC (Mode 2) https://link.springer.com/article/10.1007/JHEP08(2015)003 in Appendix A +### ============================================ + +### Beams +Beams:idA = 2212 +Beams:idB = 2212 +Beams:eCM = 13000. +Beams:frameType = 1 + +### Decays (match ALICE) +ParticleDecays:limitTau0 = on +ParticleDecays:tau0Max = 10.0 + +### Processes and base tune +SoftQCD:inelastic = on # all inelastic processes +Tune:pp = 14 # Monash 2013 as baseline + +### String fragmentation +StringPT:sigma = 0.335 +StringZ:aLund = 0.36 +StringZ:bLund = 0.56 +StringFlav:probQQtoQ = 0.078 # probQQtoQ → Q (Mode 0,2,3) +StringFlav:probStoUD = 0.20 # s/u,d suppression (Mode 0,2,3) + +# Diquark–diquark join probabilities (vector of 4 numbers) +StringFlav:probQQ1toQQ0join = 0.0275,0.0275,0.0275,0.0275 # (Mode 0,2,3) +### Multi-parton interactions +MultiPartonInteractions:pT0Ref = 2.15 # Mode 2 pT0Ref + +### Beam remnants +BeamRemnants:remnantMode = 1 # required for CR mode 1 +BeamRemnants:saturation = 5 + +### Colour reconnection: CLR-BLC Mode 2 +ColourReconnection:mode = 1 # new CR scheme +ColourReconnection:allowDoubleJunRem = off # as in table +ColourReconnection:m0 = 0.3 # Mode 2 mass scale +ColourReconnection:allowJunctions = on +ColourReconnection:junctionCorrection = 1.2 # Mode 2 +ColourReconnection:timeDilationMode = 2 # Mode 2 +ColourReconnection:timeDilationPar = 0.18 # Mode 2 + +Random:setSeed = on diff --git a/MC/config/ALICE3/pythia8/generator/pythia8_pp_clr-blc3_13tev.cfg b/MC/config/ALICE3/pythia8/generator/pythia8_pp_clr-blc3_13tev.cfg new file mode 100644 index 000000000..34c006469 --- /dev/null +++ b/MC/config/ALICE3/pythia8/generator/pythia8_pp_clr-blc3_13tev.cfg @@ -0,0 +1,45 @@ +### ============================================ +### PYTHIA 8 — CLR-BLC Mode 3 configuration +### Based on table: Monash vs CLR-BLC (Mode 3) https://link.springer.com/article/10.1007/JHEP08(2015)003 in Appendix A +### ============================================ + +### Beams +Beams:idA = 2212 +Beams:idB = 2212 +Beams:eCM = 13000. +Beams:frameType = 1 + +### Decays (match ALICE) +ParticleDecays:limitTau0 = on +ParticleDecays:tau0Max = 10.0 + +### Processes and base tune +SoftQCD:inelastic = on # all inelastic processes +Tune:pp = 14 # Monash 2013 as baseline + +### String fragmentation +StringPT:sigma = 0.335 +StringZ:aLund = 0.36 +StringZ:bLund = 0.56 +StringFlav:probQQtoQ = 0.078 # probQQtoQ → Q (Mode 0,2,3) +StringFlav:probStoUD = 0.20 # s/u,d suppression (Mode 0,2,3) + +# Diquark–diquark join probabilities (vector of 4 numbers) +StringFlav:probQQ1toQQ0join = 0.0275,0.0275,0.0275,0.0275 # (Mode 0,2,3) +### Multi-parton interactions +MultiPartonInteractions:pT0Ref = 2.05 # Mode 3 pT0Ref + +### Beam remnants +BeamRemnants:remnantMode = 1 # required for CR mode 1 +BeamRemnants:saturation = 5 + +### Colour reconnection: CLR-BLC Mode 3 +ColourReconnection:mode = 1 # new CR scheme +ColourReconnection:allowDoubleJunRem = off # as in table +ColourReconnection:m0 = 0.3 # Mode 3 mass scale +ColourReconnection:allowJunctions = on +ColourReconnection:junctionCorrection = 1.15 # Mode 3 +ColourReconnection:timeDilationMode = 3 # Mode 3 +ColourReconnection:timeDilationPar = 0.073 # Mode 3 + +Random:setSeed = on diff --git a/MC/config/ALICE3/pythia8/generator/pythia8_pp_cr_136tev.cfg b/MC/config/ALICE3/pythia8/generator/pythia8_pp_cr_136tev.cfg new file mode 100644 index 000000000..c3303726e --- /dev/null +++ b/MC/config/ALICE3/pythia8/generator/pythia8_pp_cr_136tev.cfg @@ -0,0 +1,21 @@ +### Specify beams +Beams:idA = 2212 +Beams:idB = 2212 +Beams:eCM = 13600. ### energy + +Beams:frameType = 1 +ParticleDecays:limitTau0 = on +ParticleDecays:tau0Max = 10. ### match alice: 1cm/c = 10.0mm/c + +### processes +SoftQCD:inelastic = on # all inelastic processes +# default: Monash 2013 +Tune:pp = 14 + +### CR configurations +ColourReconnection:mode = 1 # new colour reconnection scheme +ColourReconnection:allowJunctions = on + +BeamRemnants:remnantMode = 1 # work with CR mode = 1 + + diff --git a/MC/config/ALICE3/pythia8/generator/pythia8_pp_rescattering_136tev.cfg b/MC/config/ALICE3/pythia8/generator/pythia8_pp_rescattering_136tev.cfg new file mode 100644 index 000000000..9d0adf1fe --- /dev/null +++ b/MC/config/ALICE3/pythia8/generator/pythia8_pp_rescattering_136tev.cfg @@ -0,0 +1,23 @@ +### Specify beams +Beams:idA = 2212 +Beams:idB = 2212 +Beams:eCM = 13600. ### energy + +Beams:frameType = 1 +ParticleDecays:limitTau0 = on +ParticleDecays:tau0Max = 10. ### match alice: 1cm/c = 10.0mm/c + +### processes +SoftQCD:inelastic = on # all inelastic processes + +# default: do nothing, Monash 2013 will do its thing +Tune:pp = 14 + +### enable hadronic rescattering +HadronLevel:Rescatter = on # default = off +Fragmentation:setVertices = on # default = off +PartonVertex:setVertex = on # default = off +Rescattering:nearestNeighbours = off # default = on (but "require a larger retuning effort") +Rescattering:inelastic = on # default = on + +Random:setSeed = on diff --git a/MC/config/ALICE3/pythia8/generator_pythia8_central_strangeness_gun_PbPb.C b/MC/config/ALICE3/pythia8/generator_pythia8_central_strangeness_gun_PbPb.C new file mode 100755 index 000000000..150bfd3ab --- /dev/null +++ b/MC/config/ALICE3/pythia8/generator_pythia8_central_strangeness_gun_PbPb.C @@ -0,0 +1,611 @@ +#if !defined(__CLING__) || defined(__ROOTCLING__) +#include "Pythia8/Pythia.h" +#include "Pythia8/HeavyIons.h" +#include "FairGenerator.h" +#include "FairPrimaryGenerator.h" +#include "Generators/GeneratorPythia8.h" +#include "TRandom3.h" +#include "TParticlePDG.h" +#include "TDatabasePDG.h" + +#include +#include + +using namespace Pythia8; +#endif +class GeneratorPythia8Gun : public o2::eventgen::GeneratorPythia8{ +public: + /// default constructor + GeneratorPythia8Gun() = default; + + /// constructor + GeneratorPythia8Gun(int input_pdg){ + genMinPt=0.0; + genMaxPt=20.0; + genminY=-1.5; + genmaxY=1.5; + genminEta=-1.5; + genmaxEta=1.5; + + UEOverSampling = 20; + genEventCountUse = 2000; //start at large number: regen + + pdg = input_pdg; + E=0; + px=0; + py=0; + pz=0; + p=0; + y=0; + eta=0; + xProd=0; + yProd=0; + zProd=0; + xProd=0.; yProd=0.; zProd=0.; + //addFurtherPion=false; + + randomizePDGsign=false; + + //fSpectra = new TF1("fPtDist",myLevyPt,0.0,10,3); + fSpectra = STAR_BlastWave("fSpectra", m, 20); + fSpectra ->SetNpx( 1000 ); + fSpectraXi = STAR_BlastWave("fSpectraXi", 1.32171, 20); + fSpectraXi ->SetNpx( 1000 ); + fSpectraOm = STAR_BlastWave("fSpectraOm", 1.67245, 20); + fSpectraOm ->SetNpx( 1000 ); + + fSpectra->SetParameter(0, m); //mass: automatic! + fSpectra->SetParameter(1,0.6615); //beta-max + fSpectra->SetParameter(2,0.0905); //T + fSpectra->SetParameter(3,0.7355); //n + fSpectra->SetParameter(4,1000); //norm (not relevant) + + fSpectraXi->SetParameter(0,1.32171); //beta-max + fSpectraXi->SetParameter(1,0.6615); //beta-max + fSpectraXi->SetParameter(2,0.0905); //T + fSpectraXi->SetParameter(3,0.7355); //n + fSpectraXi->SetParameter(4,1000); //norm (not relevant) + + fSpectraOm->SetParameter(0,1.67245); //beta-max + fSpectraOm->SetParameter(1,0.6615); //beta-max + fSpectraOm->SetParameter(2,0.0905); //T + fSpectraOm->SetParameter(3,0.7355); //n + fSpectraOm->SetParameter(4,1000); //norm (not relevant) + + fLVHelper = new TLorentzVector(); + + if( input_pdg!=0 ) m = getMass(input_pdg); + if( input_pdg==4444 ) m = 4.797; + if( input_pdg==0 ) m = 1.0; + furtherPrim={}; + keys_furtherPrim={}; + cout<<"Initalizing extra PYTHIA object"<SetParameters(mt, pt, beta_max, temp, n); + + integral = fIntegrandXi->Integral(0., 1.); + } + if(TMath::Abs(mass-1.67245)<0.002){ + if (!fIntegrandOm) + fIntegrandOm = new TF1("fIntegrandOm", this, &GeneratorPythia8Gun::STAR_BlastWave_Integrand_Improved, 0., 1., 5, "GeneratorPythia8Gun", "STAR_BlastWave_Integrand_Improved"); + fIntegrandOm->SetParameters(mt, pt, beta_max, temp, n); + + integral = fIntegrandOm->Integral(0., 1.); + } + if(TMath::Abs(mass-1.67245)>0.002&&TMath::Abs(mass-1.32171)>0.002){ + if (!fIntegrand) + fIntegrand = new TF1("fIntegrand", this, &GeneratorPythia8Gun::STAR_BlastWave_Integrand_Improved, 0., 1., 5, "GeneratorPythia8Gun", "STAR_BlastWave_Integrand_Improved"); + fIntegrand->SetParameters(mt, pt, beta_max, temp, n); + + integral = fIntegrand->Integral(0., 1.); + } + return norm * pt * integral; + } + + //___________________________________________________________________ + + Double_t STAR_BlastWave_Integrand_Improved(const Double_t *x, const Double_t *p) { + + /* + x[0] -> r (radius) + p[0] -> mT (transverse mass) + p[1] -> pT (transverse momentum) + p[2] -> beta_max (surface velocity) + p[3] -> T (freezout temperature) + p[4] -> n (velocity profile) + */ + + Double_t r = x[0]; + Double_t mt = p[0]; + Double_t pt = p[1]; + Double_t beta_max = p[2]; + Double_t temp_1 = 1. / p[3]; + Double_t n = p[4]; + + Double_t beta = beta_max * TMath::Power(r, n); + Double_t rho = TMath::ATanH(beta); + Double_t argI0 = pt * TMath::SinH(rho) * temp_1; + Double_t argK1 = mt * TMath::CosH(rho) * temp_1; + // if (argI0 > 100 || argI0 < -100) + // printf("r=%f, pt=%f, beta_max=%f, temp=%f, n=%f, mt=%f, beta=%f, rho=%f, argI0=%f, argK1=%f\n", r, pt, beta_max, 1. / temp_1, n, mt, beta, rho, argI0, argK1); + return r * mt * TMath::BesselI0(argI0) * TMath::BesselK1(argK1); + + } + + //___________________________________________________________________ + + TF1 *STAR_BlastWave(const Char_t *name, Double_t mass,Float_t upperlim, Double_t beta_max = 0.9, Double_t temp = 0.1, Double_t n = 1., Double_t norm = 1.e6) { + + //new TF1("fSpectra",this ,&GeneratorPythia8GunPbPb::myLevyPt, 0.0,20,3, "GeneratorPythia8GunPbPb","myLevyPt"); + TF1 *fBlastWave = new TF1(name, this, &GeneratorPythia8Gun::STAR_BlastWave_Func, 0., upperlim, 5, "GeneratorPythia8Gun", "STAR_BlastWave_Func"); + fBlastWave->SetParameters(mass, beta_max, temp, n, norm); + fBlastWave->SetParNames("mass", "beta_max", "T", "n", "norm"); + fBlastWave->FixParameter(0, mass); + fBlastWave->SetParLimits(1, 0.1, 0.9); // don't touch :) adding some 99 youu get floating point exception + fBlastWave->SetParLimits(2, 0.03,1.);//0.05, 1.); // no negative values!! for the following as well + fBlastWave->SetParLimits(3, 0.25,4.5); // was 2.5 // omega-->at limit even moving it to 4.5 but yield same + return fBlastWave; + } + + Double_t y2eta(Double_t pt, Double_t mass, Double_t y){ + Double_t mt = TMath::Sqrt(mass * mass + pt * pt); + return TMath::ASinH(mt / pt * TMath::SinH(y)); + } + + /// set mass + void setMass(int input_m){m=input_m;} + + /// set 4-momentum + void set4momentum(double input_px, double input_py, double input_pz){ + px = input_px; + py = input_py; + pz = input_pz; + E = sqrt( m*m+px*px+py*py+pz*pz ); + fourMomentum.px(px); + fourMomentum.py(py); + fourMomentum.pz(pz); + fourMomentum.e(E); + p = sqrt( px*px+py*py+pz*pz ); + y = 0.5*log( (E+pz)/(E-pz) ); + eta = 0.5*log( (p+pz)/(p-pz) ); + + ////std::cout << "##### Particle #####" << std::endl; + ////std::cout << " - PDG code: " << pdg << std::endl; + ////std::cout << " - mass: " << m << std::endl; + ////std::cout << " - (px,py,pz): (" << px << "," << py << "," << pz << ")" << std::endl; + ////std::cout << " - momentum: " << p << std::endl; + ////std::cout << " - energy: " << E << std::endl; + ////std::cout << " - rapidity: " << y << std::endl; + ////std::cout << " - pseudorapidity: " << eta << std::endl; + ////std::cout << " - production vertex: (" << xProd << "," << yProd << "," << zProd << ")" << std::endl; + } + + /// set 3-momentum + void setMomentum(double input_p){p=input_p;} + + /// set x,y,z of production vertex + void setProdVtx(double input_xProd, double input_yProd, double input_zProd){xProd=input_xProd; yProd=input_xProd; zProd=input_zProd;} + + /// setter to add further primary particles to the event + void setAddFurtherPrimaries(const int pdgCode, const int howMany){ + /// check if this species has been already added + const int map_counts = furtherPrim.count(pdgCode); + if(map_counts==1){ // species already present + const int howMany_already = furtherPrim[pdgCode]; + std::cout << "BEWARE: " << howMany_already << " particles of species " << pdgCode << " already required."; + std::cout << " Ignoring the command setAddFurtherPrimaries(" << pdgCode << "," << howMany << ")" << std::endl; + return; + } + /// add particles, if not yet present + furtherPrim[pdgCode] = howMany; + keys_furtherPrim.insert(pdgCode); + } + + /// set add a further primary pion + //void setAddFurtherPion(){addFurtherPion=true;} + + /// get mass from TParticlePDG + double getMass(int input_pdg){ + double mass = 0; + if(TDatabasePDG::Instance()){ + TParticlePDG* particle = TDatabasePDG::Instance()->GetParticle(input_pdg); + if(particle) mass = particle->Mass(); + else std::cout << "===> particle mass equal to 0" << std::endl; + } + return mass; + } + + //_________________________________________________________________________________ + /// generate uniform eta and uniform momentum + void genUniformMomentumEta(double minP, double maxP, double minY, double maxY){ + // random generator + std::unique_ptr ranGenerator { new TRandom3() }; + ranGenerator->SetSeed(0); + + // momentum + const double gen_p = ranGenerator->Uniform(minP,maxP); + // eta + const double gen_eta = ranGenerator->Uniform(minY,maxY); + // z-component momentum from eta + const double cosTheta = ( exp(2*gen_eta)-1 ) / ( exp(2*gen_eta)+1 ); // starting from eta = -ln(tan(theta/2)) = 1/2*ln( (1+cos(theta))/(1-cos(theta)) ) ---> NB: valid for cos(theta)!=1 + const double gen_pz = gen_p*cosTheta; + // y-component: random uniform + const double maxVal = sqrt( gen_p*gen_p-gen_pz*gen_pz ); + double sign_py = ranGenerator->Uniform(0,1); + sign_py = (sign_py>0.5)?1.:-1.; + const double gen_py = ranGenerator->Uniform(0.,maxVal)*sign_py; + // x-component momentum + double sign_px = ranGenerator->Uniform(0,1); + sign_px = (sign_px>0.5)?1.:-1.; + const double gen_px = sqrt( gen_p*gen_p-gen_pz*gen_pz-gen_py*gen_py )*sign_px; + + set4momentum(gen_px,gen_py,gen_pz); + } + + //_________________________________________________________________________________ + /// generate uniform eta and uniform momentum + void genSpectraMomentumEta(double minP, double maxP, double minY, double maxY){ + // random generator + std::unique_ptr ranGenerator { new TRandom3() }; + ranGenerator->SetSeed(0); + + // generate transverse momentum + const double gen_pT = fSpectra->GetRandom(minP,maxP); + + //Actually could be something else without loss of generality but okay + const double gen_phi = ranGenerator->Uniform(0,2*TMath::Pi()); + + // sample flat in rapidity, calculate eta + Double_t gen_Y=10, gen_eta=10; + + while( gen_eta>genmaxEta || gen_etaUniform(minY,maxY); + //(Double_t pt, Double_t mass, Double_t y) + gen_eta = y2eta(gen_pT, m, gen_Y); + } + + fLVHelper->SetPtEtaPhiM(gen_pT, gen_eta, gen_phi, m); + set4momentum(fLVHelper->Px(),fLVHelper->Py(),fLVHelper->Pz()); + } + + //_________________________________________________________________________________ + /// generate uniform eta and uniform momentum + void genSpectraMomentumEtaXi(double minP, double maxP, double minY, double maxY){ + // random generator + std::unique_ptr ranGenerator { new TRandom3() }; + ranGenerator->SetSeed(0); + + // generate transverse momentum + const double gen_pT = fSpectraXi->GetRandom(minP,maxP); + + //Actually could be something else without loss of generality but okay + const double gen_phi = ranGenerator->Uniform(0,2*TMath::Pi()); + + // sample flat in rapidity, calculate eta + Double_t gen_Y=10, gen_eta=10; + + while( gen_eta>genmaxEta || gen_etaUniform(minY,maxY); + //(Double_t pt, Double_t mass, Double_t y) + gen_eta = y2eta(gen_pT, m, gen_Y); + } + + fLVHelper->SetPtEtaPhiM(gen_pT, gen_eta, gen_phi, m); + set4momentum(fLVHelper->Px(),fLVHelper->Py(),fLVHelper->Pz()); + } + + //_________________________________________________________________________________ + /// generate uniform eta and uniform momentum + void genSpectraMomentumEtaOm(double minP, double maxP, double minY, double maxY){ + // random generator + std::unique_ptr ranGenerator { new TRandom3() }; + ranGenerator->SetSeed(0); + + // generate transverse momentum + const double gen_pT = fSpectraOm->GetRandom(minP,maxP); + + //Actually could be something else without loss of generality but okay + const double gen_phi = ranGenerator->Uniform(0,2*TMath::Pi()); + + // sample flat in rapidity, calculate eta + Double_t gen_Y=10, gen_eta=10; + + while( gen_eta>genmaxEta || gen_etaUniform(minY,maxY); + //(Double_t pt, Double_t mass, Double_t y) + gen_eta = y2eta(gen_pT, m, gen_Y); + } + + fLVHelper->SetPtEtaPhiM(gen_pT, gen_eta, gen_phi, m); + set4momentum(fLVHelper->Px(),fLVHelper->Py(),fLVHelper->Pz()); + } + +protected: + + //__________________________________________________________________ + Pythia8::Particle createParticle(){ + //std::cout << "createParticle() mass " << m << " pdgCode " << pdg << std::endl; + Pythia8::Particle myparticle; + myparticle.id(pdg); + myparticle.status(11); + myparticle.px(px); + myparticle.py(py); + myparticle.pz(pz); + myparticle.e(E); + myparticle.m(m); + myparticle.xProd(xProd); + myparticle.yProd(yProd); + myparticle.zProd(zProd); + + return myparticle; + } + + //__________________________________________________________________ + int randomizeSign(){ + + std::unique_ptr gen_random {new TRandom3(0)}; + const float n = gen_random->Uniform(-1,1); + + return n/abs(n); + } + + //__________________________________________________________________ + Bool_t generateEvent() override { + + double original_m = m; + int original_pdg = pdg; + + /// reset event + mPythia.event.reset(); + + if(original_pdg!=211){ + for(Int_t ii=0; ii<15; ii++){ + xProd=0.0; + yProd=0.0; + zProd=0.0; + genSpectraMomentumEta(genMinPt,genMaxPt,genminY,genmaxY); + Pythia8::Particle lAddedParticle = createParticle(); + mPythia.event.append(lAddedParticle); + lAddedParticles++; + } + } + + //+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + Bool_t lPythiaOK = kFALSE; + while (!lPythiaOK){ + lPythiaOK = pythiaObject.next(); + //Select rough central events, please, disregard + //if( pythiaObject.info.hiInfo->b() > 6) lPythiaOK = kFALSE; //regenerate, please + } + //+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + // use event + Long_t nParticles = pythiaObject.event.size(); + Long_t nChargedParticlesAtMidRap = 0; + Long_t nPionsAtMidRap = 0; + lAddedParticles = 0; + for ( Long_t j=0; j < nParticles; j++ ) { + Int_t pypid = pythiaObject.event[j].id(); + Float_t pypx = pythiaObject.event[j].px(); + Float_t pypy = pythiaObject.event[j].py(); + Float_t pypz = pythiaObject.event[j].pz(); + Float_t pypt = pythiaObject.event[j].pT(); + Float_t pyrap = pythiaObject.event[j].y(); + Float_t pyeta = pythiaObject.event[j].eta(); + Int_t pystate = pythiaObject.event[j].status(); + //if(TMath::Abs(state > 89)) {continue;} + Float_t pyenergy = pythiaObject.event[j].e(); + Int_t pycharge = pythiaObject.event[j].charge(); + + //Per-species loop: skip outside of mid-rapidity, please + if ( TMath::Abs(pyeta) > 4.0 ) continue; //only within ALICE 3 acceptance + + //final only + if (!pythiaObject.event[j].isFinal()) continue; + + if ( TMath::Abs(pyeta) < 0.5 ){ + if ( TMath::Abs(pythiaObject.event[j].charge())>1e-5 ) nChargedParticlesAtMidRap++; + if ( TMath::Abs(pypid)==211 ) nPionsAtMidRap++; + } + + pdg = pypid; + px = pypx; + py = pypy; + pz = pypz; + E = pyenergy; + m = pythiaObject.event[j].m(); + xProd = pythiaObject.event[j].xProd(); + yProd = pythiaObject.event[j].yProd(); + zProd = pythiaObject.event[j].zProd(); + + Pythia8::Particle lAddedParticle = createParticle(); + mPythia.event.append(lAddedParticle); + lAddedParticles++; + } + //+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + + //+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + // XI ABUNDANCE FIX +// FCN=0.35879 FROM MINOS STATUS=SUCCESSFUL 126 CALLS 634 TOTAL +// EDM=3.7456e-09 STRATEGY= 1 ERROR MATRIX ACCURATE +// EXT PARAMETER STEP FIRST +// NO. NAME VALUE ERROR SIZE DERIVATIVE +// 1 p0 4.74929e-03 3.29248e-04 -3.35914e-06 5.38225e+00 +// 2 p1 -4.08255e-03 8.62587e-04 -2.02577e-05 2.45132e+00 +// 3 p2 4.76660e+00 1.93593e+00 1.93593e+00 2.70369e-04 +// Info in : created default TCanvas with name c1 + //Adjust relative abundance of multi-strange particles by injecting some + Double_t lExpectedXiToPion = TMath::Max(4.74929e-03 - 4.08255e-03*TMath::Exp(-nChargedParticlesAtMidRap/4.76660e+00) - 0.00211334,0.); + Double_t lExpectedXi = nPionsAtMidRap*lExpectedXiToPion; + Int_t lXiYield = gRandom->Poisson(3*lExpectedXi); //factor 3: fix the rapidity acceptance + m = 1.32171; + pdg = 3312; + cout<<"Adding extra xi: "<Uniform()>0.5?+1:-1; + xProd=0.0; + yProd=0.0; + zProd=0.0; + genSpectraMomentumEtaXi(genMinPt,genMaxPt,genminY,genmaxY); + Pythia8::Particle lAddedParticle = createParticle(); + mPythia.event.append(lAddedParticle); + lAddedParticles++; + } + //+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + + //+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + // OMEGA ABUNDANCE FIX + //Adjust relative abundance of multi-strange particles by injecting some + Double_t lExpectedOmegaToPion = TMath::Max(8.55057e-04 - 7.38732e-04*TMath::Exp(-nChargedParticlesAtMidRap/2.40545e+01) - 6.56785e-05,0.); + Double_t lExpectedOmega = nPionsAtMidRap*lExpectedOmegaToPion; + Int_t lOmegaYield = gRandom->Poisson(3*lExpectedOmega); //factor 3: fix the rapidity acceptance + m = 1.67245; + pdg = 3334; + cout<<"Adding extra omegas: "<Uniform()>0.5?+1:-1; + xProd=0.0; + yProd=0.0; + zProd=0.0; + genSpectraMomentumEtaOm(genMinPt,genMaxPt,genminY,genmaxY); + Pythia8::Particle lAddedParticle = createParticle(); + mPythia.event.append(lAddedParticle); + lAddedParticles++; + } + //+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + + //Revert back or else there'll be trouble next time! + m = original_m; + pdg = original_pdg; + + /// go to next Pythia event + mPythia.next(); + + return true; + } + +private: + + double genMinPt; /// minimum 3-momentum for generated particles + double genMaxPt; /// maximum 3-momentum for generated particles + double genminY; /// minimum pseudorapidity for generated particles + double genmaxY; /// maximum pseudorapidity for generated particles + double genminEta; + double genmaxEta; + int UEOverSampling; //number of times to repeat underlying event + int genEventCountUse; + + Pythia8::Vec4 fourMomentum; /// four-momentum (px,py,pz,E) + double E; /// energy: sqrt( m*m+px*px+py*py+pz*pz ) [GeV/c] + double m; /// particle mass [GeV/c^2] + int pdg; /// particle pdg code + double px; /// x-component momentum [GeV/c] + double py; /// y-component momentum [GeV/c] + double pz; /// z-component momentum [GeV/c] + double p; /// momentum + double y; /// rapidity + double eta; /// pseudorapidity + double xProd; /// x-coordinate position production vertex [cm] + double yProd; /// y-coordinate position production vertex [cm] + double zProd; /// z-coordinate position production vertex [cm] + + //Max number: max number of particles to be added + long lAddedParticles; + float ue_E[5000]; + float ue_m[5000]; + float ue_px[5000]; + float ue_py[5000]; + float ue_pz[5000]; + float ue_xProd[5000]; + float ue_yProd[5000]; + float ue_zProd[5000]; + int ue_pdg[5000]; + + bool randomizePDGsign; /// bool to randomize the PDG code of the core particle + + TF1 *fSpectra; /// TF1 to store more realistic shape of spectrum + TF1 *fSpectraXi; /// TF1 to store more realistic shape of spectrum + TF1 *fSpectraOm; /// TF1 to store more realistic shape of spectrum + + //BW integrand + TF1 *fIntegrand = NULL; + TF1 *fIntegrandXi = NULL; + TF1 *fIntegrandOm = NULL; + + TLorentzVector *fLVHelper; + + Pythia8::Pythia pythiaObject; ///Generate a full event if requested to do so + + //bool addFurtherPion; /// bool to attach an additional primary pion + std::map furtherPrim; /// key: PDG code; value: how many further primaries of this species to be added + std::unordered_set keys_furtherPrim; /// keys of the above map (NB: only unique elements allowed!) +}; + +FairGenerator* generateNativeOmegaCCC(){ + return reinterpret_cast(new GeneratorPythia8Gun(4444)); +} + +FairGenerator* generateNativeOmegaCC(){ + return reinterpret_cast(new GeneratorPythia8Gun(4432)); +} + +FairGenerator* generateNativeOmegaC(){ + return reinterpret_cast(new GeneratorPythia8Gun(4332)); +} + +FairGenerator* generateNativeOmega(){ + return reinterpret_cast(new GeneratorPythia8Gun(3334)); +} + +FairGenerator* generatePYTHIA(){ + return reinterpret_cast(new GeneratorPythia8Gun(211)); +} diff --git a/MC/config/ALICE3/pythia8/generator_pythia8_strangeness_gun_PbPb.C b/MC/config/ALICE3/pythia8/generator_pythia8_strangeness_gun_PbPb.C new file mode 100755 index 000000000..a810d7ef4 --- /dev/null +++ b/MC/config/ALICE3/pythia8/generator_pythia8_strangeness_gun_PbPb.C @@ -0,0 +1,612 @@ +#if !defined(__CLING__) || defined(__ROOTCLING__) +#include "Pythia8/Pythia.h" +#include "Pythia8/HeavyIons.h" +#include "FairGenerator.h" +#include "FairPrimaryGenerator.h" +#include "Generators/GeneratorPythia8.h" +#include "TRandom3.h" +#include "TParticlePDG.h" +#include "TDatabasePDG.h" + +#include +#include +//#include // for std::pair + +using namespace Pythia8; +#endif +class GeneratorPythia8Gun : public o2::eventgen::GeneratorPythia8{ +public: + /// default constructor + GeneratorPythia8Gun() = default; + + /// constructor + GeneratorPythia8Gun(int input_pdg){ + genMinPt=0.0; + genMaxPt=20.0; + genminY=-1.5; + genmaxY=1.5; + genminEta=-1.5; + genmaxEta=1.5; + + UEOverSampling = 20; + genEventCountUse = 2000; //start at large number: regen + + pdg = input_pdg; + E=0; + px=0; + py=0; + pz=0; + p=0; + y=0; + eta=0; + xProd=0; + yProd=0; + zProd=0; + xProd=0.; yProd=0.; zProd=0.; + //addFurtherPion=false; + + randomizePDGsign=false; + + //fSpectra = new TF1("fPtDist",myLevyPt,0.0,10,3); + fSpectra = STAR_BlastWave("fSpectra", m, 20); + fSpectra ->SetNpx( 1000 ); + fSpectraXi = STAR_BlastWave("fSpectraXi", 1.32171, 20); + fSpectraXi ->SetNpx( 1000 ); + fSpectraOm = STAR_BlastWave("fSpectraOm", 1.67245, 20); + fSpectraOm ->SetNpx( 1000 ); + + fSpectra->SetParameter(0, m); //mass: automatic! + fSpectra->SetParameter(1,0.6615); //beta-max + fSpectra->SetParameter(2,0.0905); //T + fSpectra->SetParameter(3,0.7355); //n + fSpectra->SetParameter(4,1000); //norm (not relevant) + + fSpectraXi->SetParameter(0,1.32171); //beta-max + fSpectraXi->SetParameter(1,0.6615); //beta-max + fSpectraXi->SetParameter(2,0.0905); //T + fSpectraXi->SetParameter(3,0.7355); //n + fSpectraXi->SetParameter(4,1000); //norm (not relevant) + + fSpectraOm->SetParameter(0,1.67245); //beta-max + fSpectraOm->SetParameter(1,0.6615); //beta-max + fSpectraOm->SetParameter(2,0.0905); //T + fSpectraOm->SetParameter(3,0.7355); //n + fSpectraOm->SetParameter(4,1000); //norm (not relevant) + + fLVHelper = new TLorentzVector(); + + if( input_pdg!=0 ) m = getMass(input_pdg); + if( input_pdg==4444 ) m = 4.797; + if( input_pdg==0 ) m = 1.0; + furtherPrim={}; + keys_furtherPrim={}; + cout<<"Initalizing extra PYTHIA object"<SetParameters(mt, pt, beta_max, temp, n); + + integral = fIntegrandXi->Integral(0., 1.); + } + if(TMath::Abs(mass-1.67245)<0.002){ + if (!fIntegrandOm) + fIntegrandOm = new TF1("fIntegrandOm", this, &GeneratorPythia8Gun::STAR_BlastWave_Integrand_Improved, 0., 1., 5, "GeneratorPythia8Gun", "STAR_BlastWave_Integrand_Improved"); + fIntegrandOm->SetParameters(mt, pt, beta_max, temp, n); + + integral = fIntegrandOm->Integral(0., 1.); + } + if(TMath::Abs(mass-1.67245)>0.002&&TMath::Abs(mass-1.32171)>0.002){ + if (!fIntegrand) + fIntegrand = new TF1("fIntegrand", this, &GeneratorPythia8Gun::STAR_BlastWave_Integrand_Improved, 0., 1., 5, "GeneratorPythia8Gun", "STAR_BlastWave_Integrand_Improved"); + fIntegrand->SetParameters(mt, pt, beta_max, temp, n); + + integral = fIntegrand->Integral(0., 1.); + } + return norm * pt * integral; + } + + //___________________________________________________________________ + + Double_t STAR_BlastWave_Integrand_Improved(const Double_t *x, const Double_t *p) { + + /* + x[0] -> r (radius) + p[0] -> mT (transverse mass) + p[1] -> pT (transverse momentum) + p[2] -> beta_max (surface velocity) + p[3] -> T (freezout temperature) + p[4] -> n (velocity profile) + */ + + Double_t r = x[0]; + Double_t mt = p[0]; + Double_t pt = p[1]; + Double_t beta_max = p[2]; + Double_t temp_1 = 1. / p[3]; + Double_t n = p[4]; + + Double_t beta = beta_max * TMath::Power(r, n); + Double_t rho = TMath::ATanH(beta); + Double_t argI0 = pt * TMath::SinH(rho) * temp_1; + Double_t argK1 = mt * TMath::CosH(rho) * temp_1; + // if (argI0 > 100 || argI0 < -100) + // printf("r=%f, pt=%f, beta_max=%f, temp=%f, n=%f, mt=%f, beta=%f, rho=%f, argI0=%f, argK1=%f\n", r, pt, beta_max, 1. / temp_1, n, mt, beta, rho, argI0, argK1); + return r * mt * TMath::BesselI0(argI0) * TMath::BesselK1(argK1); + + } + + //___________________________________________________________________ + + TF1 *STAR_BlastWave(const Char_t *name, Double_t mass,Float_t upperlim, Double_t beta_max = 0.9, Double_t temp = 0.1, Double_t n = 1., Double_t norm = 1.e6) { + + //new TF1("fSpectra",this ,&GeneratorPythia8GunPbPb::myLevyPt, 0.0,20,3, "GeneratorPythia8GunPbPb","myLevyPt"); + TF1 *fBlastWave = new TF1(name, this, &GeneratorPythia8Gun::STAR_BlastWave_Func, 0., upperlim, 5, "GeneratorPythia8Gun", "STAR_BlastWave_Func"); + fBlastWave->SetParameters(mass, beta_max, temp, n, norm); + fBlastWave->SetParNames("mass", "beta_max", "T", "n", "norm"); + fBlastWave->FixParameter(0, mass); + fBlastWave->SetParLimits(1, 0.1, 0.9); // don't touch :) adding some 99 youu get floating point exception + fBlastWave->SetParLimits(2, 0.03,1.);//0.05, 1.); // no negative values!! for the following as well + fBlastWave->SetParLimits(3, 0.25,4.5); // was 2.5 // omega-->at limit even moving it to 4.5 but yield same + return fBlastWave; + } + + Double_t y2eta(Double_t pt, Double_t mass, Double_t y){ + Double_t mt = TMath::Sqrt(mass * mass + pt * pt); + return TMath::ASinH(mt / pt * TMath::SinH(y)); + } + + /// set mass + void setMass(int input_m){m=input_m;} + + /// set 4-momentum + void set4momentum(double input_px, double input_py, double input_pz){ + px = input_px; + py = input_py; + pz = input_pz; + E = sqrt( m*m+px*px+py*py+pz*pz ); + fourMomentum.px(px); + fourMomentum.py(py); + fourMomentum.pz(pz); + fourMomentum.e(E); + p = sqrt( px*px+py*py+pz*pz ); + y = 0.5*log( (E+pz)/(E-pz) ); + eta = 0.5*log( (p+pz)/(p-pz) ); + + ////std::cout << "##### Particle #####" << std::endl; + ////std::cout << " - PDG code: " << pdg << std::endl; + ////std::cout << " - mass: " << m << std::endl; + ////std::cout << " - (px,py,pz): (" << px << "," << py << "," << pz << ")" << std::endl; + ////std::cout << " - momentum: " << p << std::endl; + ////std::cout << " - energy: " << E << std::endl; + ////std::cout << " - rapidity: " << y << std::endl; + ////std::cout << " - pseudorapidity: " << eta << std::endl; + ////std::cout << " - production vertex: (" << xProd << "," << yProd << "," << zProd << ")" << std::endl; + } + + /// set 3-momentum + void setMomentum(double input_p){p=input_p;} + + /// set x,y,z of production vertex + void setProdVtx(double input_xProd, double input_yProd, double input_zProd){xProd=input_xProd; yProd=input_xProd; zProd=input_zProd;} + + /// setter to add further primary particles to the event + void setAddFurtherPrimaries(const int pdgCode, const int howMany){ + /// check if this species has been already added + const int map_counts = furtherPrim.count(pdgCode); + if(map_counts==1){ // species already present + const int howMany_already = furtherPrim[pdgCode]; + std::cout << "BEWARE: " << howMany_already << " particles of species " << pdgCode << " already required."; + std::cout << " Ignoring the command setAddFurtherPrimaries(" << pdgCode << "," << howMany << ")" << std::endl; + return; + } + /// add particles, if not yet present + furtherPrim[pdgCode] = howMany; + keys_furtherPrim.insert(pdgCode); + } + + /// set add a further primary pion + //void setAddFurtherPion(){addFurtherPion=true;} + + /// get mass from TParticlePDG + double getMass(int input_pdg){ + double mass = 0; + if(TDatabasePDG::Instance()){ + TParticlePDG* particle = TDatabasePDG::Instance()->GetParticle(input_pdg); + if(particle) mass = particle->Mass(); + else std::cout << "===> particle mass equal to 0" << std::endl; + } + return mass; + } + + //_________________________________________________________________________________ + /// generate uniform eta and uniform momentum + void genUniformMomentumEta(double minP, double maxP, double minY, double maxY){ + // random generator + std::unique_ptr ranGenerator { new TRandom3() }; + ranGenerator->SetSeed(0); + + // momentum + const double gen_p = ranGenerator->Uniform(minP,maxP); + // eta + const double gen_eta = ranGenerator->Uniform(minY,maxY); + // z-component momentum from eta + const double cosTheta = ( exp(2*gen_eta)-1 ) / ( exp(2*gen_eta)+1 ); // starting from eta = -ln(tan(theta/2)) = 1/2*ln( (1+cos(theta))/(1-cos(theta)) ) ---> NB: valid for cos(theta)!=1 + const double gen_pz = gen_p*cosTheta; + // y-component: random uniform + const double maxVal = sqrt( gen_p*gen_p-gen_pz*gen_pz ); + double sign_py = ranGenerator->Uniform(0,1); + sign_py = (sign_py>0.5)?1.:-1.; + const double gen_py = ranGenerator->Uniform(0.,maxVal)*sign_py; + // x-component momentum + double sign_px = ranGenerator->Uniform(0,1); + sign_px = (sign_px>0.5)?1.:-1.; + const double gen_px = sqrt( gen_p*gen_p-gen_pz*gen_pz-gen_py*gen_py )*sign_px; + + set4momentum(gen_px,gen_py,gen_pz); + } + + //_________________________________________________________________________________ + /// generate uniform eta and uniform momentum + void genSpectraMomentumEta(double minP, double maxP, double minY, double maxY){ + // random generator + std::unique_ptr ranGenerator { new TRandom3() }; + ranGenerator->SetSeed(0); + + // generate transverse momentum + const double gen_pT = fSpectra->GetRandom(minP,maxP); + + //Actually could be something else without loss of generality but okay + const double gen_phi = ranGenerator->Uniform(0,2*TMath::Pi()); + + // sample flat in rapidity, calculate eta + Double_t gen_Y=10, gen_eta=10; + + while( gen_eta>genmaxEta || gen_etaUniform(minY,maxY); + //(Double_t pt, Double_t mass, Double_t y) + gen_eta = y2eta(gen_pT, m, gen_Y); + } + + fLVHelper->SetPtEtaPhiM(gen_pT, gen_eta, gen_phi, m); + set4momentum(fLVHelper->Px(),fLVHelper->Py(),fLVHelper->Pz()); + } + + //_________________________________________________________________________________ + /// generate uniform eta and uniform momentum + void genSpectraMomentumEtaXi(double minP, double maxP, double minY, double maxY){ + // random generator + std::unique_ptr ranGenerator { new TRandom3() }; + ranGenerator->SetSeed(0); + + // generate transverse momentum + const double gen_pT = fSpectraXi->GetRandom(minP,maxP); + + //Actually could be something else without loss of generality but okay + const double gen_phi = ranGenerator->Uniform(0,2*TMath::Pi()); + + // sample flat in rapidity, calculate eta + Double_t gen_Y=10, gen_eta=10; + + while( gen_eta>genmaxEta || gen_etaUniform(minY,maxY); + //(Double_t pt, Double_t mass, Double_t y) + gen_eta = y2eta(gen_pT, m, gen_Y); + } + + fLVHelper->SetPtEtaPhiM(gen_pT, gen_eta, gen_phi, m); + set4momentum(fLVHelper->Px(),fLVHelper->Py(),fLVHelper->Pz()); + } + + //_________________________________________________________________________________ + /// generate uniform eta and uniform momentum + void genSpectraMomentumEtaOm(double minP, double maxP, double minY, double maxY){ + // random generator + std::unique_ptr ranGenerator { new TRandom3() }; + ranGenerator->SetSeed(0); + + // generate transverse momentum + const double gen_pT = fSpectraOm->GetRandom(minP,maxP); + + //Actually could be something else without loss of generality but okay + const double gen_phi = ranGenerator->Uniform(0,2*TMath::Pi()); + + // sample flat in rapidity, calculate eta + Double_t gen_Y=10, gen_eta=10; + + while( gen_eta>genmaxEta || gen_etaUniform(minY,maxY); + //(Double_t pt, Double_t mass, Double_t y) + gen_eta = y2eta(gen_pT, m, gen_Y); + } + + fLVHelper->SetPtEtaPhiM(gen_pT, gen_eta, gen_phi, m); + set4momentum(fLVHelper->Px(),fLVHelper->Py(),fLVHelper->Pz()); + } + +protected: + + //__________________________________________________________________ + Pythia8::Particle createParticle(){ + //std::cout << "createParticle() mass " << m << " pdgCode " << pdg << std::endl; + Pythia8::Particle myparticle; + myparticle.id(pdg); + myparticle.status(11); + myparticle.px(px); + myparticle.py(py); + myparticle.pz(pz); + myparticle.e(E); + myparticle.m(m); + myparticle.xProd(xProd); + myparticle.yProd(yProd); + myparticle.zProd(zProd); + + return myparticle; + } + + //__________________________________________________________________ + int randomizeSign(){ + + std::unique_ptr gen_random {new TRandom3(0)}; + const float n = gen_random->Uniform(-1,1); + + return n/abs(n); + } + + //__________________________________________________________________ + Bool_t generateEvent() override { + + double original_m = m; + int original_pdg = pdg; + + /// reset event + mPythia.event.reset(); + + if(original_pdg!=211){ + for(Int_t ii=0; ii<15; ii++){ + xProd=0.0; + yProd=0.0; + zProd=0.0; + genSpectraMomentumEta(genMinPt,genMaxPt,genminY,genmaxY); + Pythia8::Particle lAddedParticle = createParticle(); + mPythia.event.append(lAddedParticle); + lAddedParticles++; + } + } + + //+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + Bool_t lPythiaOK = kFALSE; + while (!lPythiaOK){ + lPythiaOK = pythiaObject.next(); + //Select rough central events, please, disregard + //if( pythiaObject.info.hiInfo->b() > 6) lPythiaOK = kFALSE; //regenerate, please + } + //+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + // use event + Long_t nParticles = pythiaObject.event.size(); + Long_t nChargedParticlesAtMidRap = 0; + Long_t nPionsAtMidRap = 0; + lAddedParticles = 0; + for ( Long_t j=0; j < nParticles; j++ ) { + Int_t pypid = pythiaObject.event[j].id(); + Float_t pypx = pythiaObject.event[j].px(); + Float_t pypy = pythiaObject.event[j].py(); + Float_t pypz = pythiaObject.event[j].pz(); + Float_t pypt = pythiaObject.event[j].pT(); + Float_t pyrap = pythiaObject.event[j].y(); + Float_t pyeta = pythiaObject.event[j].eta(); + Int_t pystate = pythiaObject.event[j].status(); + //if(TMath::Abs(state > 89)) {continue;} + Float_t pyenergy = pythiaObject.event[j].e(); + Int_t pycharge = pythiaObject.event[j].charge(); + + //Per-species loop: skip outside of mid-rapidity, please + if ( TMath::Abs(pyeta) > 4.0 ) continue; //only within ALICE 3 acceptance + + //final only + if (!pythiaObject.event[j].isFinal()) continue; + + if ( TMath::Abs(pyeta) < 0.5 ){ + if ( TMath::Abs(pythiaObject.event[j].charge())>1e-5 ) nChargedParticlesAtMidRap++; + if ( TMath::Abs(pypid)==211 ) nPionsAtMidRap++; + } + + pdg = pypid; + px = pypx; + py = pypy; + pz = pypz; + E = pyenergy; + m = pythiaObject.event[j].m(); + xProd = pythiaObject.event[j].xProd(); + yProd = pythiaObject.event[j].yProd(); + zProd = pythiaObject.event[j].zProd(); + + Pythia8::Particle lAddedParticle = createParticle(); + mPythia.event.append(lAddedParticle); + lAddedParticles++; + } + //+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + + //+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + // XI ABUNDANCE FIX +// FCN=0.35879 FROM MINOS STATUS=SUCCESSFUL 126 CALLS 634 TOTAL +// EDM=3.7456e-09 STRATEGY= 1 ERROR MATRIX ACCURATE +// EXT PARAMETER STEP FIRST +// NO. NAME VALUE ERROR SIZE DERIVATIVE +// 1 p0 4.74929e-03 3.29248e-04 -3.35914e-06 5.38225e+00 +// 2 p1 -4.08255e-03 8.62587e-04 -2.02577e-05 2.45132e+00 +// 3 p2 4.76660e+00 1.93593e+00 1.93593e+00 2.70369e-04 +// Info in : created default TCanvas with name c1 + //Adjust relative abundance of multi-strange particles by injecting some + Double_t lExpectedXiToPion = TMath::Max(4.74929e-03 - 4.08255e-03*TMath::Exp(-nChargedParticlesAtMidRap/4.76660e+00) - 0.00211334,0.); + Double_t lExpectedXi = nPionsAtMidRap*lExpectedXiToPion; + Int_t lXiYield = gRandom->Poisson(3*lExpectedXi); //factor 3: fix the rapidity acceptance + m = 1.32171; + pdg = 3312; + cout<<"Adding extra xi: "<Uniform()>0.5?+1:-1; + xProd=0.0; + yProd=0.0; + zProd=0.0; + genSpectraMomentumEtaXi(genMinPt,genMaxPt,genminY,genmaxY); + Pythia8::Particle lAddedParticle = createParticle(); + mPythia.event.append(lAddedParticle); + lAddedParticles++; + } + //+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + + //+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + // OMEGA ABUNDANCE FIX + //Adjust relative abundance of multi-strange particles by injecting some + Double_t lExpectedOmegaToPion = TMath::Max(8.55057e-04 - 7.38732e-04*TMath::Exp(-nChargedParticlesAtMidRap/2.40545e+01) - 6.56785e-05,0.); + Double_t lExpectedOmega = nPionsAtMidRap*lExpectedOmegaToPion; + Int_t lOmegaYield = gRandom->Poisson(3*lExpectedOmega); //factor 3: fix the rapidity acceptance + m = 1.67245; + pdg = 3334; + cout<<"Adding extra omegas: "<Uniform()>0.5?+1:-1; + xProd=0.0; + yProd=0.0; + zProd=0.0; + genSpectraMomentumEtaOm(genMinPt,genMaxPt,genminY,genmaxY); + Pythia8::Particle lAddedParticle = createParticle(); + mPythia.event.append(lAddedParticle); + lAddedParticles++; + } + //+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + + //Revert back or else there'll be trouble next time! + m = original_m; + pdg = original_pdg; + + /// go to next Pythia event + mPythia.next(); + + return true; + } + +private: + + double genMinPt; /// minimum 3-momentum for generated particles + double genMaxPt; /// maximum 3-momentum for generated particles + double genminY; /// minimum pseudorapidity for generated particles + double genmaxY; /// maximum pseudorapidity for generated particles + double genminEta; + double genmaxEta; + int UEOverSampling; //number of times to repeat underlying event + int genEventCountUse; + + Pythia8::Vec4 fourMomentum; /// four-momentum (px,py,pz,E) + double E; /// energy: sqrt( m*m+px*px+py*py+pz*pz ) [GeV/c] + double m; /// particle mass [GeV/c^2] + int pdg; /// particle pdg code + double px; /// x-component momentum [GeV/c] + double py; /// y-component momentum [GeV/c] + double pz; /// z-component momentum [GeV/c] + double p; /// momentum + double y; /// rapidity + double eta; /// pseudorapidity + double xProd; /// x-coordinate position production vertex [cm] + double yProd; /// y-coordinate position production vertex [cm] + double zProd; /// z-coordinate position production vertex [cm] + + //Max number: max number of particles to be added + long lAddedParticles; + float ue_E[5000]; + float ue_m[5000]; + float ue_px[5000]; + float ue_py[5000]; + float ue_pz[5000]; + float ue_xProd[5000]; + float ue_yProd[5000]; + float ue_zProd[5000]; + int ue_pdg[5000]; + + bool randomizePDGsign; /// bool to randomize the PDG code of the core particle + + TF1 *fSpectra; /// TF1 to store more realistic shape of spectrum + TF1 *fSpectraXi; /// TF1 to store more realistic shape of spectrum + TF1 *fSpectraOm; /// TF1 to store more realistic shape of spectrum + + //BW integrand + TF1 *fIntegrand = NULL; + TF1 *fIntegrandXi = NULL; + TF1 *fIntegrandOm = NULL; + + TLorentzVector *fLVHelper; + + Pythia8::Pythia pythiaObject; ///Generate a full event if requested to do so + + //bool addFurtherPion; /// bool to attach an additional primary pion + std::map furtherPrim; /// key: PDG code; value: how many further primaries of this species to be added + std::unordered_set keys_furtherPrim; /// keys of the above map (NB: only unique elements allowed!) +}; + +FairGenerator* generateNativeOmegaCCC(){ + return reinterpret_cast(new GeneratorPythia8Gun(4444)); +} + +FairGenerator* generateNativeOmegaCC(){ + return reinterpret_cast(new GeneratorPythia8Gun(4432)); +} + +FairGenerator* generateNativeOmegaC(){ + return reinterpret_cast(new GeneratorPythia8Gun(4332)); +} + +FairGenerator* generateNativeOmega(){ + return reinterpret_cast(new GeneratorPythia8Gun(3334)); +} + +FairGenerator* generatePYTHIA(){ + return reinterpret_cast(new GeneratorPythia8Gun(211)); +} diff --git a/MC/config/PWGDQ/EvtGen/DecayTablesEvtgen/BTOPSIJPSITODIELECTRON.DEC b/MC/config/PWGDQ/EvtGen/DecayTablesEvtgen/BTOPSIJPSITODIELECTRON.DEC index 64a835910..4c3e5a129 100644 --- a/MC/config/PWGDQ/EvtGen/DecayTablesEvtgen/BTOPSIJPSITODIELECTRON.DEC +++ b/MC/config/PWGDQ/EvtGen/DecayTablesEvtgen/BTOPSIJPSITODIELECTRON.DEC @@ -13,7 +13,7 @@ Decay B0 0.0001 psi(2S) K+ pi- pi0 PHSP; 0.0004 psi(2S) K_10 PHSP; ### -0.000620000 psi(2S) K0 PHSP; #[New mode added] #[Reconstructed PDG2011] +0.000620000 psi(2S) K0 SVS; #[New mode added] #[Reconstructed PDG2011] 0.000435500 J/psi K_S0 SVS; #[Reconstructed PDG2011] 0.000435500 J/psi K_L0 SVS; #[Reconstructed PDG2011] @@ -30,7 +30,7 @@ Decay B0 0.0005 J/psi K_2*0 PHSP; 0.000094000 J/psi phi K0 PHSP; #[Reconstructed PDG2011] #### -0.000871000 J/psi K0 PHSP; #[New mode added] #[Reconstructed PDG2011] +0.000871000 J/psi K0 SVS; #[New mode added] #[Reconstructed PDG2011] 0.000310000 J/psi omega K0 PHSP; #[New mode added] #[Reconstructed PDG2011] 0.000009500 J/psi eta PHSP; #[New mode added] #[Reconstructed PDG2011] 0.000019000 J/psi pi+ pi- PHSP; #[New mode added] #[Reconstructed PDG2011] @@ -38,6 +38,20 @@ Decay B0 0.000540000 J/psi K0 rho0 PHSP; #[New mode added] #[Reconstructed PDG2011] 0.000800000 J/psi K*+ pi- PHSP; #[New mode added] #[Reconstructed PDG2011] 0.000660000 J/psi K*0 pi+ pi- PHSP; #[New mode added] #[Reconstructed PDG2011] + +# --- chi_c1 --- + 0.000011200 chi_c1 pi0 PHSP; + 0.000395000 chi_c1 K0 SVS; + 0.000497000 chi_c1 K+ pi- PHSP; + 0.000320000 chi_c1 K0 pi+ pi- PHSP; + 0.000350000 chi_c1 K+ pi0 pi- PHSP; + +# --- chi_c2 --- + 0.000015000 chi_c2 K0 STS; + 0.000049000 chi_c2 K*0 PHSP; + 0.000072000 chi_c2 K+ pi- PHSP; + 0.000174000 chi_c2 pi+ pi- K0 PHSP; + 0.000074000 chi_c2 pi- pi0 K+ PHSP; Enddecay Decay anti-B0 @@ -53,7 +67,7 @@ Decay anti-B0 0.0001 psi(2S) K- pi+ pi0 PHSP; 0.0004 psi(2S) anti-K_10 PHSP; ### -0.000620000 psi(2S) anti-K0 PHSP; #[New mode added] #[Reconstructed PDG2011] +0.000620000 psi(2S) anti-K0 SVS; #[New mode added] #[Reconstructed PDG2011] 0.000435500 J/psi K_S0 SVS; #[Reconstructed PDG2011] 0.000435500 J/psi K_L0 SVS; #[Reconstructed PDG2011] @@ -70,7 +84,7 @@ Decay anti-B0 0.0005 J/psi anti-K_2*0 PHSP; 0.000094000 J/psi phi anti-K0 PHSP; #[Reconstructed PDG2011] ### -0.000871000 J/psi anti-K0 PHSP; #[New mode added] #[Reconstructed PDG2011] +0.000871000 J/psi anti-K0 SVS; #[New mode added] #[Reconstructed PDG2011] 0.000310000 J/psi omega anti-K0 PHSP; #[New mode added] #[Reconstructed PDG2011] 0.000009500 J/psi eta PHSP; #[New mode added] #[Reconstructed PDG2011] 0.000019000 J/psi pi- pi+ PHSP; #[New mode added] #[Reconstructed PDG2011] @@ -78,6 +92,20 @@ Decay anti-B0 0.000540000 J/psi anti-K0 rho0 PHSP; #[New mode added] #[Reconstructed PDG2011] 0.000800000 J/psi K*- pi+ PHSP; #[New mode added] #[Reconstructed PDG2011] 0.000660000 J/psi anti-K*0 pi- pi+ PHSP; #[New mode added] #[Reconstructed PDG2011] + +# --- chi_c1 --- + 0.000011200 chi_c1 pi0 PHSP; + 0.000395000 chi_c1 anti-K0 SVS; + 0.000497000 chi_c1 K- pi+ PHSP; + 0.000320000 chi_c1 anti-K0 pi- pi+ PHSP; + 0.000350000 chi_c1 K- pi0 pi+ PHSP; + +# --- chi_c2 --- + 0.000015000 chi_c2 anti-K0 STS; + 0.000049000 chi_c2 anti-K*0 PHSP; + 0.000072000 chi_c2 K- pi+ PHSP; + 0.000174000 chi_c2 pi- pi+ anti-K0 PHSP; + 0.000074000 chi_c2 pi+ pi0 K- PHSP; Enddecay Decay B+ @@ -109,6 +137,21 @@ Decay B+ 0.000108000 J/psi eta K+ PHSP; #[New mode added] #[Reconstructed PDG2011] 0.000350000 J/psi omega K+ PHSP; #[New mode added] #[Reconstructed PDG2011] 0.000011800 J/psi p+ anti-Lambda0 PHSP; #[New mode added] #[Reconstructed PDG2011] + +# --- chi_c1 --- + 0.000022000 chi_c1 pi+ PHSP; + 0.000474000 chi_c1 K+ SVS; + 0.000300000 chi_c1 K*+ SVV_HELAMP PKHplus PKphHplus PKHzero PKphHzero PKHminus PKphHminus; + 0.000329000 chi_c1 K+ pi0 PHSP; + 0.000580000 chi_c1 K0 pi+ PHSP; + 0.000374000 chi_c1 K+ pi+ pi- PHSP; + +# --- chi_c2 --- + 0.000110000 chi_c2 K+ STS; + 0.000120000 chi_c2 K*+ PHSP; + 0.000062000 chi_c2 K+ pi0 PHSP; + 0.000124000 chi_c2 K0 pi+ PHSP; + 0.000134000 chi_c2 K+ pi+ pi- PHSP; Enddecay Decay B- @@ -139,6 +182,21 @@ Decay B- 0.000108000 J/psi eta K- PHSP; #[New mode added] #[Reconstructed PDG2011] 0.000350000 J/psi omega K- PHSP; #[New mode added] #[Reconstructed PDG2011] 0.000011800 J/psi anti-p- Lambda0 PHSP; #[New mode added] #[Reconstructed PDG2011] + +# --- chi_c1 --- + 0.000022000 chi_c1 pi- PHSP; + 0.000474000 chi_c1 K- SVS; + 0.000300000 chi_c1 K*- SVV_HELAMP PKHminus PKphHminus PKHzero PKphHzero PKHplus PKphHplus; + 0.000329000 chi_c1 K- pi0 PHSP; + 0.000580000 chi_c1 anti-K0 pi- PHSP; + 0.000374000 chi_c1 K- pi- pi+ PHSP; + +# --- chi_c2 --- + 0.000110000 chi_c2 K- STS; + 0.000120000 chi_c2 K*- PHSP; + 0.000062000 chi_c2 K- pi0 PHSP; + 0.000124000 chi_c2 anti-K0 pi- PHSP; + 0.000134000 chi_c2 K- pi- pi+ PHSP; Enddecay Decay B_s0 @@ -182,6 +240,9 @@ Decay B_s0 0.0002 J/psi pi0 pi0 PHSP; # PR LHCb 04/08/2004 : add Bs -> phi mu mu, phi e e 0.0000023 phi e+ e- BTOSLLALI; + +# --- chi_c1 --- + 0.0001970 chi_c1 phi SVV_HELAMP 1.0 0.0 1.0 0.0 1.0 0.0; Enddecay Decay anti-B_s0 @@ -224,18 +285,29 @@ Decay anti-B_s0 0.0002 J/psi pi0 pi0 PHSP; # PR LHCb 04/08/2004 : add Bs -> phi mu mu, phi e e 0.0000023 phi e- e+ BTOSLLALI; + +# --- chi_c1 --- + 0.0001970 chi_c1 phi SVV_HELAMP 1.0 0.0 1.0 0.0 1.0 0.0; Enddecay Decay Lambda_b0 ### 0.00038 Lambda0 psi(2S) PHSP; 0.00047 Lambda0 J/psi PHSP; + 0.0000760 chi_c1 p+ K- PHSP; + 0.0000050 chi_c1 p+ pi- PHSP; + 0.0000770 chi_c2 p+ K- PHSP; + 0.0000048 chi_c2 p+ pi- PHSP; Enddecay Decay anti-Lambda_b0 ### 0.00038 anti-Lambda0 psi(2S) PHSP; 0.00047 anti-Lambda0 J/psi PHSP; + 0.0000760 chi_c1 anti-p- K+ PHSP; + 0.0000050 chi_c1 anti-p- pi+ PHSP; + 0.0000770 chi_c2 anti-p- K+ PHSP; + 0.0000048 chi_c2 anti-p- pi+ PHSP; Enddecay Decay Xi_b- @@ -264,6 +336,19 @@ Decay anti-Omega_b+ Enddecay +# ============================================================================================================================= +# JPsi, Psi(2S), ChiC Decays +# ============================================================================================================================= +### +Decay chi_c1 + 1.000 J/psi gamma PHSP; +Enddecay + +### +Decay chi_c2 + 1.000 J/psi gamma PHSP; +Enddecay + Decay psi(2S) ### from DECAY.DEC 1.000 e+ e- PHOTOS VLL; diff --git a/MC/config/PWGDQ/EvtGen/DecayTablesEvtgen/BTOPSITOJPSIPIPI.DEC b/MC/config/PWGDQ/EvtGen/DecayTablesEvtgen/BTOPSITOJPSIPIPI.DEC new file mode 100644 index 000000000..82102bf60 --- /dev/null +++ b/MC/config/PWGDQ/EvtGen/DecayTablesEvtgen/BTOPSITOJPSIPIPI.DEC @@ -0,0 +1,167 @@ +#### +Decay B0 +# B -> cc= s +0.000310000 psi(2S) K_S0 SVS; #[Reconstructed PDG2011] +0.000310000 psi(2S) K_L0 SVS; #[Reconstructed PDG2011] +# +# +0.000610000 psi(2S) K*0 SVV_HELAMP PKHplus PKphHplus PKHzero PKphHzero PKHminus PKphHminus; #[Reconstructed PDG2011] + +0.0004 psi(2S) K+ pi- PHSP; +0.0002 psi(2S) K0 pi0 PHSP; +0.0002 psi(2S) K0 pi- pi+ PHSP; +0.0001 psi(2S) K0 pi0 pi0 PHSP; +0.0001 psi(2S) K+ pi- pi0 PHSP; +0.0004 psi(2S) K_10 PHSP; +# +#### +0.000620000 psi(2S) K0 PHSP; #[New mode added] #[Reconstructed PDG2011] + +Enddecay + +Decay anti-B0 +# +0.000310000 psi(2S) K_S0 SVS; #[Reconstructed PDG2011] +0.000310000 psi(2S) K_L0 SVS; #[Reconstructed PDG2011] +# +# +0.000610000 psi(2S) anti-K*0 SVV_HELAMP PKHminus PKphHminus PKHzero PKphHzero PKHplus PKphHplus; #[Reconstructed PDG2011] + +0.0004 psi(2S) K- pi+ PHSP; +0.0002 psi(2S) anti-K0 pi0 PHSP; +0.0002 psi(2S) anti-K0 pi+ pi- PHSP; +0.0001 psi(2S) anti-K0 pi0 pi0 PHSP; +0.0001 psi(2S) K- pi+ pi0 PHSP; +0.0004 psi(2S) anti-K_10 PHSP; +# +0.000620000 psi(2S) anti-K0 PHSP; #[New mode added] #[Reconstructed PDG2011] +#### +Enddecay + +Decay B- +# +# B -> cc= s sum = 1.92% +# +0.000646000 psi(2S) K- SVS; #[Reconstructed PDG2011] +0.000620000 psi(2S) K*- SVV_HELAMP PKHminus PKphHminus PKHzero PKphHzero PKHplus PKphHplus; #[Reconstructed PDG2011] +0.0004 psi(2S) anti-K0 pi- PHSP; +0.0002 psi(2S) K- pi0 PHSP; +0.001900000 psi(2S) K- pi+ pi- PHSP; #[Reconstructed PDG2011] +0.0001 psi(2S) K- pi0 pi0 PHSP; +0.0001 psi(2S) anti-K0 pi- pi0 PHSP; +0.0004 psi(2S) K_1- PHSP; +# +0.000025800 psi(2S) pi- PHSP; #[New mode added] #[Reconstructed PDG2011] + +Enddecay + +Decay B+ +# +# B -> cc= s sum = 1.92% +# +0.000646000 psi(2S) K+ SVS; #[Reconstructed PDG2011] +0.000620000 psi(2S) K*+ SVV_HELAMP PKHplus PKphHplus PKHzero PKphHzero PKHminus PKphHminus; #[Reconstructed PDG2011] +0.0004 psi(2S) K0 pi+ PHSP; +0.0002 psi(2S) K+ pi0 PHSP; +0.001900000 psi(2S) K+ pi- pi+ PHSP; #[Reconstructed PDG2011] +0.0001 psi(2S) K+ pi0 pi0 PHSP; +0.0001 psi(2S) K0 pi+ pi0 PHSP; +0.0004 psi(2S) K_1+ PHSP; +# +#### +0.000025800 psi(2S) pi+ PHSP; #[New mode added] #[Reconstructed PDG2011] + +Enddecay + +Decay B_s0 +# psi' = 0.34% CLNS 94/1315 +0.000465 psi(2S) eta' SVS; +0.000235 psi(2S) eta SVS; +0.000680000 psi(2S) phi SVV_HELAMP 1.0 0.0 1.0 0.0 1.0 0.0; #[Reconstructed PDG2011] +0.0003 psi(2S) K- K+ PHSP; +0.0003 psi(2S) anti-K0 K0 PHSP; +0.0003 psi(2S) K0 K- pi+ PHSP; +0.0003 psi(2S) anti-K0 K0 pi0 PHSP; +0.0003 psi(2S) K- K+ pi0 PHSP; +0.00034 psi(2S) phi pi+ pi- PHSP; +0.00034 psi(2S) phi pi0 pi0 PHSP; +0.0002 psi(2S) eta pi+ pi- PHSP; +0.0002 psi(2S) eta pi0 pi0 PHSP; +0.0004 psi(2S) eta' pi+ pi- PHSP; +0.0004 psi(2S) eta' pi0 pi0 PHSP; +0.0002 psi(2S) pi+ pi- PHSP; +0.0002 psi(2S) pi0 pi0 PHSP; +# +# PR LHCb 04/08/2004 : add Bs -> phi mu mu, phi e e +0.0000023 phi e+ e- BTOSLLALI; +Enddecay + +Decay anti-B_s0 +# psi' = 0.34% CLNS 94/1315 +# +0.000465 psi(2S) eta' SVS; +0.000235 psi(2S) eta SVS; +0.000680000 psi(2S) phi SVV_HELAMP 1.0 0.0 1.0 0.0 1.0 0.0; #[Reconstructed PDG2011] +0.0003 psi(2S) K- K+ PHSP; +0.0003 psi(2S) anti-K0 K0 PHSP; +0.0003 psi(2S) anti-K0 K+ pi- PHSP; +0.0003 psi(2S) anti-K0 K0 pi0 PHSP; +0.0003 psi(2S) K- K+ pi0 PHSP; +0.00034 psi(2S) phi pi+ pi- PHSP; +0.00034 psi(2S) phi pi0 pi0 PHSP; +0.0002 psi(2S) eta pi+ pi- PHSP; +0.0002 psi(2S) eta pi0 pi0 PHSP; +0.0004 psi(2S) eta' pi+ pi- PHSP; +0.0004 psi(2S) eta' pi0 pi0 PHSP; +0.0002 psi(2S) pi+ pi- PHSP; +0.0002 psi(2S) pi0 pi0 PHSP; +# +# PR LHCb 04/08/2004 : add Bs -> phi mu mu, phi e e +0.0000023 phi e- e+ BTOSLLALI; + +Enddecay + +Decay Lambda_b0 + 0.00038 Lambda0 psi(2S) PHSP; +Enddecay + +Decay anti-Lambda_b0 + 0.00038 anti-Lambda0 psi(2S) PHSP; +Enddecay + +Decay Xi_b- + 0.00038 Xi- psi(2S) PHSP; +Enddecay + +Decay anti-Xi_b+ + 0.00038 anti-Xi+ psi(2S) PHSP; +Enddecay + +Decay Omega_b- + 0.00038 Omega- psi(2S) PHSP; +Enddecay + +Decay anti-Omega_b+ + 0.00038 anti-Omega+ psi(2S) PHSP; +Enddecay + +Decay B_c- +# SemiLeptonic Decays +0.00094 psi(2S) e- anti-nu_e PHOTOS PHSP; +Enddecay + +Decay B_c+ +# SemiLeptonic Decays +0.00094 psi(2S) e+ nu_e PHOTOS PHSP; +Enddecay + +Decay psi(2S) +1.000 J/psi pi+ pi- VVPIPI; +Enddecay + +Decay J/psi +### from DECAY.DEC +1.000 e+ e- PHOTOS VLL; +Enddecay + +End \ No newline at end of file diff --git a/MC/config/PWGDQ/EvtGen/GeneratorEvtGen.C b/MC/config/PWGDQ/EvtGen/GeneratorEvtGen.C index da0b1aa6a..1f6d6b867 100644 --- a/MC/config/PWGDQ/EvtGen/GeneratorEvtGen.C +++ b/MC/config/PWGDQ/EvtGen/GeneratorEvtGen.C @@ -42,6 +42,7 @@ enum DecayModeEvt { kEvtAll = 0, kEvtElectronEM, kEvtDiElectronEM, kEvtGammaEM, + kEvtBtoPsi2SToJpsiPiPi, kEvtBeautyUpgrade }; namespace o2 @@ -105,10 +106,10 @@ class GeneratorEvtGen : public T { auto nparticles = T::mParticles.size(); for (Int_t iparticle = 0; iparticle < nparticles; ++iparticle) { - auto particle = (TParticle)T::mParticles.at(iparticle); + const auto& particle = T::mParticles.at(iparticle); if (checkPdg(particle.GetPdgCode())) { if (mDebug) - std::cout << "particles in the array (before decay): PDG " << particle.GetPdgCode() << " STATUS " << particle.GetStatusCode() << " position in the array" << iparticle << " First daughter" << particle.GetFirstDaughter() << " Last daughter " << particle.GetLastDaughter() << std::endl; + std::cout << "particles in the array (before decay): PDG " << particle.GetPdgCode() << " STATUS " << particle.GetStatusCode() << " position in the array " << iparticle << " First daughter " << particle.GetFirstDaughter() << " Last daughter " << particle.GetLastDaughter() << std::endl; TLorentzVector* momentum = new TLorentzVector(); momentum->SetPxPyPzE(particle.Px(), particle.Py(), particle.Pz(), particle.Energy()); DecayEvtGen(particle.GetPdgCode(), momentum, mPolarization); @@ -117,7 +118,7 @@ class GeneratorEvtGen : public T return kFALSE; } if (mDebug) - std::cout << "particles in the array (after decay): PDG " << particle.GetPdgCode() << " STATUS " << particle.GetStatusCode() << " position in the array" << iparticle << " First daughter" << particle.GetFirstDaughter() << " Last daughter " << particle.GetLastDaughter() << std::endl; + std::cout << "particles in the array (after decay): PDG " << particle.GetPdgCode() << " STATUS " << particle.GetStatusCode() << " position in the array " << iparticle << " First daughter " << particle.GetFirstDaughter() << " Last daughter " << particle.GetLastDaughter() << std::endl; } } return kTRUE; @@ -355,6 +356,9 @@ class GeneratorEvtGen : public T case kEvtBeautyUpgrade: SetDecayTable(Form("%s/BEAUTYUPGRADE.DEC", pathO2.Data())); break; + case kEvtBtoPsi2SToJpsiPiPi: + SetDecayTable(Form("%s/BTOPSITOJPSIPIPI.DEC", pathO2.Data())); + break; } return; }; diff --git a/MC/config/PWGDQ/external/generator/GeneratorCocktailPromptCharmoniaToMuonEvtGen_pp5TeV.C b/MC/config/PWGDQ/external/generator/GeneratorCocktailPromptCharmoniaToMuonEvtGen_pp5TeV.C new file mode 100644 index 000000000..63174d4b4 --- /dev/null +++ b/MC/config/PWGDQ/external/generator/GeneratorCocktailPromptCharmoniaToMuonEvtGen_pp5TeV.C @@ -0,0 +1,194 @@ +// usage +// o2-sim -j 4 -n 10 -g external -o sgn --configKeyValues "GeneratorExternal.fileName=GeneratorCocktailPromptCharmoniaToMuonEvtGen_pp5TeV.C;GeneratorExternal.funcName=GeneratorCocktailPromptCharmoniaToMuonEvtGen_pp5TeV()" +// +R__ADD_INCLUDE_PATH($O2DPG_MC_CONFIG_ROOT/MC/config/PWGDQ/EvtGen) +R__ADD_INCLUDE_PATH($O2DPG_MC_CONFIG_ROOT/MC/config/PWGDQ/PromptQuarkonia) +R__LOAD_LIBRARY(libpythia6) +#include "GeneratorCocktail.C" +#include "GeneratorEvtGen.C" + +namespace o2 +{ +namespace eventgen +{ + +class O2_GeneratorParamJpsi : public GeneratorTGenerator +{ + + public: + O2_GeneratorParamJpsi() : GeneratorTGenerator("ParamJpsi") + { + paramJpsi = new GeneratorParam(1, -1, PtJPsipp5TeV, YJPsipp5TeV, V2JPsipp5TeV, IpJPsipp5TeV); + paramJpsi->SetMomentumRange(0., 1.e6); + paramJpsi->SetPtRange(0, 999.); + paramJpsi->SetYRange(-4.2, -2.3); + paramJpsi->SetPhiRange(0., 360.); + paramJpsi->SetDecayer(new TPythia6Decayer()); + paramJpsi->SetForceDecay(kNoDecay); // particle left undecayed + // - - paramJpsi->SetTrackingFlag(1); // (from AliGenParam) -> check this + setTGenerator(paramJpsi); + }; + + ~O2_GeneratorParamJpsi() + { + delete paramJpsi; + }; + + Bool_t Init() override + { + GeneratorTGenerator::Init(); + paramJpsi->Init(); + return true; + } + + void SetNSignalPerEvent(Int_t nsig) { paramJpsi->SetNumberParticles(nsig); } + + //-------------------------------------------------------------------------// + static Double_t PtJPsipp5TeV(const Double_t* px, const Double_t* /*dummy*/) + { + // jpsi pT in pp at 5.02 TeV, tuned on https://www.hepdata.net/record/ins1935680 + Double_t x = *px; + Float_t p0, p1, p2, p3; + p0 = 1; + p1 = 4.30923; + p2 = 1.82061; + p3 = 4.37563; + return p0 * x / TMath::Power(1. + TMath::Power(x / p1, p2), p3); + } + + //-------------------------------------------------------------------------// + static Double_t YJPsipp5TeV(const Double_t* py, const Double_t* /*dummy*/) + { + // jpsi y in pp at 5.02 TeV, tuned on https://www.hepdata.net/record/ins1935680 + Double_t y = *py; + Float_t p0, p1, p2; + p0 = 1; + p1 = 0.0338222; + p2 = 2.96748; + return p0 * TMath::Exp(-(1. / 2.) * TMath::Power(((y - p1) / p2), 2)); + } + + //-------------------------------------------------------------------------// + static Double_t V2JPsipp5TeV(const Double_t* /*dummy*/, const Double_t* /*dummy*/) + { + // jpsi v2 + return 0.; + } + + //-------------------------------------------------------------------------// + static Int_t IpJPsipp5TeV(TRandom*) + { + return 443; + } + + private: + GeneratorParam* paramJpsi = nullptr; +}; + +class O2_GeneratorParamPsi : public GeneratorTGenerator +{ + + public: + O2_GeneratorParamPsi() : GeneratorTGenerator("ParamPsi") + { + paramPsi = new GeneratorParam(1, -1, PtPsipp5TeV, YPsipp5TeV, V2Psipp5TeV, IpPsipp5TeV); + paramPsi->SetMomentumRange(0., 1.e6); + paramPsi->SetPtRange(0, 999.); + paramPsi->SetYRange(-4.2, -2.3); + paramPsi->SetPhiRange(0., 360.); + paramPsi->SetDecayer(new TPythia6Decayer()); + paramPsi->SetForceDecay(kNoDecay); // particle left undecayed + // - - paramJpsi->SetTrackingFlag(1); // check this + setTGenerator(paramPsi); + }; + + ~O2_GeneratorParamPsi() + { + delete paramPsi; + }; + + Bool_t Init() override + { + GeneratorTGenerator::Init(); + paramPsi->Init(); + return true; + } + + void SetNSignalPerEvent(Int_t nsig) { paramPsi->SetNumberParticles(nsig); } + + //-------------------------------------------------------------------------// + static Double_t PtPsipp5TeV(const Double_t* px, const Double_t* /*dummy*/) + { + // psi2s pT in pp at 5.02 TeV, tuned on https://www.hepdata.net/record/ins1935680 + Double_t x = *px; + Float_t p0, p1, p2, p3; + p0 = 1; + p1 = 2.6444; + p2 = 6.17572; + p3 = 0.701753; + return p0 * x / TMath::Power(1. + TMath::Power(x / p1, p2), p3); + } + + //-------------------------------------------------------------------------// + static Double_t YPsipp5TeV(const Double_t* py, const Double_t* /*dummy*/) + { + // psi2s y in pp at 5.02 TeV, tuned on https://www.hepdata.net/record/ins1935680 + // WARNING! The shape extracted from data provide wired rapidity shape (low stat.), the J/psi one is used + Double_t y = *py; + Float_t p0, p1, p2; + // Extracted from Psi(2S) Run 2 data + //p0 = 1; + //p1 = -17.4857; + //p2 = 2.98887; + // Same parametrization as J/psi + p0 = 1; + p1 = 0.0338222; + p2 = 2.96748; + return p0 * TMath::Exp(-(1. / 2.) * TMath::Power(((y - p1) / p2), 2)); + } + + //-------------------------------------------------------------------------// + static Double_t V2Psipp5TeV(const Double_t* /*dummy*/, const Double_t* /*dummy*/) + { + // jpsi v2 + return 0.; + } + + //-------------------------------------------------------------------------// + static Int_t IpPsipp5TeV(TRandom*) + { + return 100443; + } + + private: + GeneratorParam* paramPsi = nullptr; +}; + +} // namespace eventgen +} // namespace o2 + +FairGenerator* GeneratorCocktailPromptCharmoniaToMuonEvtGen_pp5TeV() +{ + + auto genCocktailEvtGen = new o2::eventgen::GeneratorEvtGen(); + + auto genJpsi = new o2::eventgen::O2_GeneratorParamJpsi; + genJpsi->SetNSignalPerEvent(4); // 4 J/psi generated per event by GeneratorParam + auto genPsi = new o2::eventgen::O2_GeneratorParamPsi; + genPsi->SetNSignalPerEvent(2); // 2 Psi(2S) generated per event by GeneratorParam + genCocktailEvtGen->AddGenerator(genJpsi, 1); // 2/3 J/psi + genCocktailEvtGen->AddGenerator(genPsi, 1); // 1/3 Psi(2S) + + TString pdgs = "443;100443"; + std::string spdg; + TObjArray* obj = pdgs.Tokenize(";"); + genCocktailEvtGen->SetSizePdg(obj->GetEntriesFast()); + for (int i = 0; i < obj->GetEntriesFast(); i++) { + spdg = obj->At(i)->GetName(); + genCocktailEvtGen->AddPdg(std::stoi(spdg), i); + printf("PDG %d \n", std::stoi(spdg)); + } + genCocktailEvtGen->SetForceDecay(kEvtDiMuon); + + return genCocktailEvtGen; +} diff --git a/MC/config/PWGDQ/external/generator/GeneratorParamMuon.C b/MC/config/PWGDQ/external/generator/GeneratorParamMuon.C deleted file mode 100644 index 8e9176070..000000000 --- a/MC/config/PWGDQ/external/generator/GeneratorParamMuon.C +++ /dev/null @@ -1,142 +0,0 @@ -// Parameterized generator for muons -// Port of the Run 2 generator by P. Pillot: -// https://github.com/alisw/AliDPG/blob/master/MC/CustomGenerators/PWGDQ/Muon_GenParamSingle_PbPb5TeV_1.C - -// clang-format off -R__ADD_INCLUDE_PATH($O2DPG_MC_CONFIG_ROOT/MC/config/PWGDQ/EvtGen) -// clang-format on -R__LOAD_LIBRARY(libpythia6) - -#include "GeneratorEvtGen.C" - -namespace o2 -{ -namespace eventgen -{ - -class O2_GeneratorParamMuon : public GeneratorTGenerator -{ - public: - // parameters tuned to Pb-Pb @ 5.02 TeV - inline static Double_t fPtP0{797.446}; - inline static Double_t fPtP1{0.830278}; - inline static Double_t fPtP2{0.632177}; - inline static Double_t fPtP3{10.2202}; - inline static Double_t fPtP4{-0.000614809}; - inline static Double_t fPtP5{-1.70993}; - - inline static Double_t fYP0{1.87732}; - inline static Double_t fYP1{0.00658212}; - inline static Double_t fYP2{-0.0988071}; - inline static Double_t fYP3{-0.000452746}; - inline static Double_t fYP4{0.00269782}; - - O2_GeneratorParamMuon() : GeneratorTGenerator("ParamMuon") - { - fParamMuon = new GeneratorParam(2, -1, PtMuon, YMuon, V2Muon, IpMuon); - fParamMuon->SetPtRange(0.1, 999.); - fParamMuon->SetYRange(-4.3, -2.3); - fParamMuon->SetPhiRange(0., 360.); - fParamMuon->SetDecayer(new TPythia6Decayer()); // "no decayer" error otherwise - fParamMuon->SetForceDecay(kNoDecay); - setTGenerator(fParamMuon); - } - - ~O2_GeneratorParamMuon() { delete fParamMuon; }; - - Bool_t Init() override - { - GeneratorTGenerator::Init(); - fParamMuon->Init(); - return true; - } - - // for tuning steps - static void SetPtPars(Double_t p0, Double_t p1, Double_t p2, Double_t p3, - Double_t p4, Double_t p5) - { - fPtP0 = p0; - fPtP1 = p1; - fPtP2 = p2; - fPtP3 = p3; - fPtP4 = p4; - fPtP5 = p5; - } - - // for tuning steps - static void SetYPars(Double_t p0, Double_t p1, Double_t p2, Double_t p3, - Double_t p4) - { - fYP0 = p0; - fYP1 = p1; - fYP2 = p2; - fYP3 = p3; - fYP4 = p4; - } - - void SetNSignalPerEvent(Int_t nsig) { fParamMuon->SetNumberParticles(nsig); } - - // muon composition - static Int_t IpMuon(TRandom* ran) - { - if (ran->Rndm() < 0.5) { - return 13; - } else { - return -13; - } - } - - // muon pT - static Double_t PtMuon(const Double_t* px, const Double_t*) - { - Double_t x = px[0]; - return fPtP0 * (1. / TMath::Power(fPtP1 + TMath::Power(x, fPtP2), fPtP3) + - fPtP4 * TMath::Exp(fPtP5 * x)); - } - - // muon y - static Double_t YMuon(const Double_t* py, const Double_t*) - { - Double_t y = py[0]; - return fYP0 * (1. + fYP1 * y + fYP2 * y * y + fYP3 * y * y * y + - fYP4 * y * y * y * y); - } - - static Double_t V2Muon(const Double_t*, const Double_t*) - { - // muon v2 - return 0.; - } - - private: - GeneratorParam* fParamMuon{nullptr}; -}; - -} // namespace eventgen -} // namespace o2 - -FairGenerator* paramMuGen(Double_t ptP0 = 797.446, Double_t ptP1 = 0.830278, - Double_t ptP2 = 0.632177, Double_t ptP3 = 10.2202, - Double_t ptP4 = -0.000614809, Double_t ptP5 = -1.70993, - Double_t yP0 = 1.87732, Double_t yP1 = 0.00658212, - Double_t yP2 = -0.0988071, Double_t yP3 = -0.000452746, - Double_t yP4 = 0.00269782, Int_t nMuons = 2) -{ - auto gen = new o2::eventgen::GeneratorEvtGen(); - o2::eventgen::O2_GeneratorParamMuon::SetPtPars(ptP0, ptP1, ptP2, ptP3, ptP4, ptP5); - o2::eventgen::O2_GeneratorParamMuon::SetYPars(yP0, yP1, yP2, yP3, yP4); - gen->SetNSignalPerEvent(nMuons); // number of muons per event - - TString pdgs = "13"; - std::string spdg; - TObjArray* obj = pdgs.Tokenize(";"); - gen->SetSizePdg(obj->GetEntriesFast()); - for (int i = 0; i < obj->GetEntriesFast(); i++) { - spdg = obj->At(i)->GetName(); - gen->AddPdg(std::stoi(spdg), i); - printf("PDG %d \n", std::stoi(spdg)); - } - - gen->PrintDebug(); - return gen; -} \ No newline at end of file diff --git a/MC/config/PWGDQ/external/generator/GeneratorParamSingleMuon_PbPb_5TeV.C b/MC/config/PWGDQ/external/generator/GeneratorParamSingleMuon_PbPb_5TeV.C new file mode 100644 index 000000000..91f20acd4 --- /dev/null +++ b/MC/config/PWGDQ/external/generator/GeneratorParamSingleMuon_PbPb_5TeV.C @@ -0,0 +1,161 @@ +// Parameterized generator for muons +// Adaptation of the Run 2 generator by P. Pillot: +// https://github.com/alisw/AliDPG/blob/master/MC/CustomGenerators/PWGDQ/Muon_GenParamSingle_PbPb5TeV_1.C + +#include "FairGenerator.h" +#include "TF1.h" +#include "TRandom.h" +#include "TDatabasePDG.h" +#include "TParticlePDG.h" + +class O2_GeneratorParamMuon : public FairGenerator +{ + public: + O2_GeneratorParamMuon(int npart = 2, int pdg = 13, double ymin = -4.3, double ymax = -2.3, double ptmin = 0.1, double ptmax = 999.) + : FairGenerator("ParaMuon"), fNParticles(npart), fPDGCode(pdg), fYMin(ymin), fYMax(ymax), fPtMin(ptmin), fPtMax(ptmax) + { + TParticlePDG* particle = TDatabasePDG::Instance()->GetParticle(fPDGCode); + fMass = particle->Mass(); + fMass2 = fMass * fMass; + } + + ~O2_GeneratorParamMuon() = default; + + void SetRandomCharge(bool flag) { fRandomizeCharge = flag; } + + void SetPtPars(double p0, double p1, double p2, double p3, double p4, double p5) + { + fPtP0 = p0; + fPtP1 = p1; + fPtP2 = p2; + fPtP3 = p3; + fPtP4 = p4; + fPtP5 = p5; + } + + void SetYPars(double p0, double p1, double p2, double p3, double p4) + { + fYP0 = p0; + fYP1 = p1; + fYP2 = p2; + fYP3 = p3; + fYP4 = p4; + } + + void InitParaFuncs() + { + fPtPara = new TF1("pt-para", PtMuon, fPtMin, fPtMax, 6); + fPtPara->SetParameter(0, fPtP0); + fPtPara->SetParameter(1, fPtP1); + fPtPara->SetParameter(2, fPtP2); + fPtPara->SetParameter(3, fPtP3); + fPtPara->SetParameter(4, fPtP4); + fPtPara->SetParameter(5, fPtP5); + fYPara = new TF1("y-para", YMuon, fYMin, fYMax, 5); + fYPara->SetParameter(0, fYP0); + fYPara->SetParameter(1, fYP1); + fYPara->SetParameter(2, fYP2); + fYPara->SetParameter(3, fYP3); + fYPara->SetParameter(4, fYP4); + } + + static double PtMuon(const double* xx, const double* par) + { + double x = xx[0]; + double p0 = par[0]; + double p1 = par[1]; + double p2 = par[2]; + double p3 = par[3]; + double p4 = par[4]; + double p5 = par[5]; + return p0 * (1. / std::pow(p1 + std::pow(x, p2), p3) + p4 * std::exp(p5 * x)); + } + + static double YMuon(const double* xx, const double* par) + { + double x = xx[0]; + double p0 = par[0]; + double p1 = par[1]; + double p2 = par[2]; + double p3 = par[3]; + double p4 = par[4]; + double x2 = x * x; + return p0 * (1. + p1 * x + p2 * x2 + p3 * x2 * x + p4 * x2 * x2); + } + + bool ReadEvent(FairPrimaryGenerator* primGen) override + { + // no kinematic cuts -> accepting all + for (int i = 0; i < fNParticles; ++i) { + double pt = fPtPara->GetRandom(); + double ty = std::tanh(fYPara->GetRandom()); + double xmt = std::sqrt(pt * pt + fMass2); + double pl = xmt * ty / std::sqrt((1. - ty * ty)); + double phi = gRandom->Uniform(0., 2. * M_PI); + double px = pt * std::cos(phi); + double py = pt * std::sin(phi); + int pdg = fPDGCode; + if (fRandomizeCharge) { + int charge; + if (gRandom->Rndm() < 0.5) { + charge = 1; + } else { + charge = -1; + } + pdg = std::abs(pdg) * charge; + } + primGen->AddTrack(pdg, px, py, pl, 0, 0, 0); + printf("Add track %d %.2f %.2f %.2f \n", pdg, px, py, pl); + } + return kTRUE; + } + + private: + TF1* fPtPara{nullptr}; + TF1* fYPara{nullptr}; + TF1* fdNdPhi{nullptr}; + + // parameters tuned to Pb-Pb @ 5.02 TeV + double fPtP0{797.446}; + double fPtP1{0.830278}; + double fPtP2{0.632177}; + double fPtP3{10.2202}; + double fPtP4{-0.000614809}; + double fPtP5{-1.70993}; + + double fYP0{1.87732}; + double fYP1{0.00658212}; + double fYP2{-0.0988071}; + double fYP3{-0.000452746}; + double fYP4{0.00269782}; + + // configuration + int fPDGCode{13}; + int fNParticles{2}; + double fYMin{-4.3}; + double fYMax{-2.3}; + double fPtMin{0.1}; + double fPtMax{999.}; + bool fRandomizeCharge{true}; + double fMass{0.10566}; + double fMass2{0}; +}; + +FairGenerator* paramMuGen(double ptP0 = 797.446, double ptP1 = 0.830278, + double ptP2 = 0.632177, double ptP3 = 10.2202, + double ptP4 = -0.000614809, double ptP5 = -1.70993, + double yP0 = 1.87732, double yP1 = 0.00658212, + double yP2 = -0.0988071, double yP3 = -0.000452746, + double yP4 = 0.00269782, + int nPart = 2, int pdg = 13, + double ymin = -4.3, double ymax = -2.3, + double ptmin = 0.1, float ptmax = 999., + int randCharge = 1) +{ + auto* gen = new O2_GeneratorParamMuon(nPart, pdg, ymin, ymax, ptmin, ptmax); + gen->SetPtPars(ptP0, ptP1, ptP2, ptP3, ptP4, ptP5); + gen->SetYPars(yP0, yP1, yP2, yP3, yP4); + gen->InitParaFuncs(); + gen->SetRandomCharge(randCharge); + return gen; +} \ No newline at end of file diff --git a/MC/config/PWGDQ/external/generator/GeneratorPromptCharmonia.C b/MC/config/PWGDQ/external/generator/GeneratorPromptCharmonia.C index ceff8e6a6..86a9fd47b 100644 --- a/MC/config/PWGDQ/external/generator/GeneratorPromptCharmonia.C +++ b/MC/config/PWGDQ/external/generator/GeneratorPromptCharmonia.C @@ -168,6 +168,294 @@ class O2_GeneratorParamPsiMidY : public GeneratorTGenerator GeneratorParam* paramPsi = nullptr; }; +class O2_GeneratorParamJpsiMidY_5TeV : public GeneratorTGenerator +{ + + public: + O2_GeneratorParamJpsiMidY_5TeV() : GeneratorTGenerator("paramJpsi") + { + paramJpsi = new GeneratorParam(1, -1, PtJPsipp5TeV, YJPsipp5TeV, V2JPsipp5TeV, IpJPsipp5TeV); + paramJpsi->SetMomentumRange(0., 1.e6); + paramJpsi->SetPtRange(0., 1000.); + paramJpsi->SetYRange(-1.0, 1.0); + paramJpsi->SetPhiRange(0., 360.); + paramJpsi->SetDecayer(new TPythia6Decayer()); // Pythia + paramJpsi->SetForceDecay(kNoDecay); // particle left undecayed + setTGenerator(paramJpsi); + }; + + ~O2_GeneratorParamJpsiMidY_5TeV() + { + delete paramJpsi; + }; + + Bool_t Init() override + { + GeneratorTGenerator::Init(); + paramJpsi->Init(); + return true; + } + + void SetNSignalPerEvent(Int_t nsig) { paramJpsi->SetNumberParticles(nsig); } + + //-------------------------------------------------------------------------// + static Double_t PtJPsipp5TeV(const Double_t* px, const Double_t* /*dummy*/) + { + // JPSi pt at 5.02 TeV: https: // https://www.hepdata.net/record/ins1899703 (2108.02523) + // + const Double_t kC = 1.10642; + const Double_t kpt0 = 4.5504; + const Double_t kn = 3.58669; + Double_t pt = px[0]; + + return kC * pt / TMath::Power((1. + (pt / kpt0) * (pt / kpt0)), kn); + } + + //-------------------------------------------------------------------------// + static Double_t YJPsipp5TeV(const Double_t* py, const Double_t* /*dummy*/) + { + // Taken the same as: jpsi y in pp at 13 TeV, tuned on data, prompt jpsi ALICE+LHCb, 13 TeV + Double_t y = *py; + Float_t p0, p1, p2; + p0 = 7.79382e+00; + p1 = 2.87827e-06; + p2 = 4.41847e+00; + return p0 * TMath::Exp(-(1. / 2.) * TMath::Power(((y - p1) / p2), 2)); + } + + //-------------------------------------------------------------------------// + static Double_t V2JPsipp5TeV(const Double_t* /*dummy*/, const Double_t* /*dummy*/) + { + // jpsi v2 + return 0.; + } + + //-------------------------------------------------------------------------// + static Int_t IpJPsipp5TeV(TRandom*) + { + return 443; + } + + private: + GeneratorParam* paramJpsi = nullptr; +}; + +class O2_GeneratorParamPsiMidY_5TeV : public GeneratorTGenerator +{ + + public: + O2_GeneratorParamPsiMidY_5TeV() : GeneratorTGenerator("ParamPsi") + { + paramPsi = new GeneratorParam(1, -1, PtPsipp5TeV, YPsipp5TeV, V2Psipp5TeV, IpPsipp5TeV); + paramPsi->SetMomentumRange(0., 1.e6); // Momentum range added from me + paramPsi->SetPtRange(0., 1000.); // transverse of momentum range + paramPsi->SetYRange(-1.0, 1.0); // rapidity range + paramPsi->SetPhiRange(0., 360.); // phi range + paramPsi->SetDecayer(new TPythia6Decayer()); // Pythia decayer + paramPsi->SetForceDecay(kNoDecay); // particle left undecayed + setTGenerator(paramPsi); // Setting parameters to ParamPsi for Psi(2S) + }; + + ~O2_GeneratorParamPsiMidY_5TeV() + { + delete paramPsi; + }; + + Bool_t Init() override + { + GeneratorTGenerator::Init(); + paramPsi->Init(); + return true; + } + void SetNSignalPerEvent(Int_t nsig) { paramPsi->SetNumberParticles(nsig); } + + //-------------------------------------------------------------------------// + static Double_t PtPsipp5TeV(const Double_t* px, const Double_t* /*dummy*/) + { + // Same as JPsi at 5.02 TeV since ratio is almost flat in pT + // + const Double_t kC = 1.10642; + const Double_t kpt0 = 4.55041; + const Double_t kn = 3.58669; + Double_t pt = px[0]; + + return kC * pt / TMath::Power((1. + (pt / kpt0) * (pt / kpt0)), kn); + } + + //-------------------------------------------------------------------------// + static Double_t YPsipp5TeV(const Double_t* py, const Double_t* /*dummy*/) + { + // Taken same as jpsi y in pp at 13 TeV, tuned on data, prompt jpsi ALICE+LHCb, 13 TeV + Double_t y = *py; + Float_t p0, p1, p2; + p0 = 7.79382e+00; + p1 = 2.87827e-06; + p2 = 4.41847e+00; + return p0 * TMath::Exp(-(1. / 2.) * TMath::Power(((y - p1) / p2), 2)); + } + + //-------------------------------------------------------------------------// + static Double_t V2Psipp5TeV(const Double_t* /*dummy*/, const Double_t* /*dummy*/) + { + // jpsi v2 + return 0.; + } + + //-------------------------------------------------------------------------// + static Int_t IpPsipp5TeV(TRandom*) + { + return 100443; + } + + private: + GeneratorParam* paramPsi = nullptr; +}; + +//==================================================================================================== +class O2_GeneratorParamJpsiMidY_96TeV : public GeneratorTGenerator +{ + + public: + O2_GeneratorParamJpsiMidY_96TeV() : GeneratorTGenerator("paramJpsi") + { + paramJpsi = new GeneratorParam(1, -1, PtJPsipp96TeV, YJPsipp96TeV, V2JPsipp96TeV, IpJPsipp96TeV); + paramJpsi->SetMomentumRange(0., 1.e6); + paramJpsi->SetPtRange(0., 1000.); + paramJpsi->SetYRange(-1.0, 1.0); + paramJpsi->SetPhiRange(0., 360.); + paramJpsi->SetDecayer(new TPythia6Decayer()); // Pythia + paramJpsi->SetForceDecay(kNoDecay); // particle left undecayed + setTGenerator(paramJpsi); + }; + + ~O2_GeneratorParamJpsiMidY_96TeV() + { + delete paramJpsi; + }; + + Bool_t Init() override + { + GeneratorTGenerator::Init(); + paramJpsi->Init(); + return true; + } + + void SetNSignalPerEvent(Int_t nsig) { paramJpsi->SetNumberParticles(nsig); } + + //-------------------------------------------------------------------------// + static Double_t PtJPsipp96TeV(const Double_t* px, const Double_t* /*dummy*/) + { + // JPSi pt extrapolated at 9.6 TeV: https: // https://www.hepdata.net/record/ins1899703 (2108.02523) + // + const Double_t kC = 1.48862; + const Double_t kpt0 = 4.64005; + const Double_t kn = 3.57353; + Double_t pt = px[0]; + + return kC * pt / TMath::Power((1. + (pt / kpt0) * (pt / kpt0)), kn); + } + + //-------------------------------------------------------------------------// + static Double_t YJPsipp96TeV(const Double_t* py, const Double_t* /*dummy*/) + { + // Taken the same as: jpsi y in pp at 13 TeV, tuned on data, prompt jpsi ALICE+LHCb, 13 TeV + Double_t y = *py; + Float_t p0, p1, p2; + p0 = 7.79382e+00; + p1 = 2.87827e-06; + p2 = 4.41847e+00; + return p0 * TMath::Exp(-(1. / 2.) * TMath::Power(((y - p1) / p2), 2)); + } + + //-------------------------------------------------------------------------// + static Double_t V2JPsipp96TeV(const Double_t* /*dummy*/, const Double_t* /*dummy*/) + { + // jpsi v2 + return 0.; + } + + //-------------------------------------------------------------------------// + static Int_t IpJPsipp96TeV(TRandom*) + { + return 443; + } + + private: + GeneratorParam* paramJpsi = nullptr; +}; + +class O2_GeneratorParamPsiMidY_96TeV : public GeneratorTGenerator +{ + + public: + O2_GeneratorParamPsiMidY_96TeV() : GeneratorTGenerator("ParamPsi") + { + paramPsi = new GeneratorParam(1, -1, PtPsipp96TeV, YPsipp96TeV, V2Psipp96TeV, IpPsipp96TeV); + paramPsi->SetMomentumRange(0., 1.e6); // Momentum range added from me + paramPsi->SetPtRange(0., 1000.); // transverse of momentum range + paramPsi->SetYRange(-1.0, 1.0); // rapidity range + paramPsi->SetPhiRange(0., 360.); // phi range + paramPsi->SetDecayer(new TPythia6Decayer()); // Pythia decayer + paramPsi->SetForceDecay(kNoDecay); // particle left undecayed + setTGenerator(paramPsi); // Setting parameters to ParamPsi for Psi(2S) + }; + + ~O2_GeneratorParamPsiMidY_96TeV() + { + delete paramPsi; + }; + + Bool_t Init() override + { + GeneratorTGenerator::Init(); + paramPsi->Init(); + return true; + } + void SetNSignalPerEvent(Int_t nsig) { paramPsi->SetNumberParticles(nsig); } + + //-------------------------------------------------------------------------// + static Double_t PtPsipp96TeV(const Double_t* px, const Double_t* /*dummy*/) + { + // Same as JPsi at JPSi pt extrapolated at 9.6 TeV (since ratio is almost flat in pT) + // + // + const Double_t kC = 1.48862; + const Double_t kpt0 = 4.64005; + const Double_t kn = 3.57353; + Double_t pt = px[0]; + + return kC * pt / TMath::Power((1. + (pt / kpt0) * (pt / kpt0)), kn); + } + + //-------------------------------------------------------------------------// + static Double_t YPsipp96TeV(const Double_t* py, const Double_t* /*dummy*/) + { + // Taken same as jpsi y in pp at 13 TeV, tuned on data, prompt jpsi ALICE+LHCb, 13 TeV + Double_t y = *py; + Float_t p0, p1, p2; + p0 = 7.79382e+00; + p1 = 2.87827e-06; + p2 = 4.41847e+00; + return p0 * TMath::Exp(-(1. / 2.) * TMath::Power(((y - p1) / p2), 2)); + } + + //-------------------------------------------------------------------------// + static Double_t V2Psipp96TeV(const Double_t* /*dummy*/, const Double_t* /*dummy*/) + { + // jpsi v2 + return 0.; + } + + //-------------------------------------------------------------------------// + static Int_t IpPsipp96TeV(TRandom*) + { + return 100443; + } + + private: + GeneratorParam* paramPsi = nullptr; +}; +//==================================================================================================== class O2_GeneratorParamJpsiFwdY : public GeneratorTGenerator { @@ -213,26 +501,350 @@ class O2_GeneratorParamJpsiFwdY : public GeneratorTGenerator } //-------------------------------------------------------------------------// - static Double_t YJPsipp13TeV(const Double_t* py, const Double_t* /*dummy*/) + static Double_t YJPsipp13TeV(const Double_t* py, const Double_t* /*dummy*/) + { + // jpsi y in pp at 13 TeV, tuned on data (2015) + Double_t y = *py; + Float_t p0, p1, p2; + p0 = 1; + p1 = 0; + p2 = 2.98887; + return p0 * TMath::Exp(-(1. / 2.) * TMath::Power(((y - p1) / p2), 2)); + } + + //-------------------------------------------------------------------------// + static Double_t V2JPsipp13TeV(const Double_t* /*dummy*/, const Double_t* /*dummy*/) + { + // jpsi v2 + return 0.; + } + + //-------------------------------------------------------------------------// + static Int_t IpJPsipp13TeV(TRandom*) + { + return 443; + } + + private: + GeneratorParam* paramJpsi = nullptr; +}; + +class O2_GeneratorParamPsiFwdY : public GeneratorTGenerator +{ + + public: + O2_GeneratorParamPsiFwdY() : GeneratorTGenerator("ParamPsi") + { + paramPsi = new GeneratorParam(1, -1, PtPsipp13TeV, YPsipp13TeV, V2Psipp13TeV, IpPsipp13TeV); + paramPsi->SetMomentumRange(0., 1.e6); + paramPsi->SetPtRange(0, 999.); + paramPsi->SetYRange(-4.2, -2.3); + paramPsi->SetPhiRange(0., 360.); + paramPsi->SetDecayer(new TPythia6Decayer()); + paramPsi->SetForceDecay(kNoDecay); // particle left undecayed + // - - paramJpsi->SetTrackingFlag(1); // check this + setTGenerator(paramPsi); + }; + + ~O2_GeneratorParamPsiFwdY() + { + delete paramPsi; + }; + + Bool_t Init() override + { + GeneratorTGenerator::Init(); + paramPsi->Init(); + return true; + } + + void SetNSignalPerEvent(Int_t nsig) { paramPsi->SetNumberParticles(nsig); } + + //-------------------------------------------------------------------------// + static Double_t PtPsipp13TeV(const Double_t* px, const Double_t* /*dummy*/) + { + // jpsi pT in pp at 13 TeV, tuned on data (2015) + Double_t x = *px; + Float_t p0, p1, p2, p3; + p0 = 1; + p1 = 4.75208; + p2 = 1.69247; + p3 = 4.49224; + return p0 * x / TMath::Power(1. + TMath::Power(x / p1, p2), p3); + } + + //-------------------------------------------------------------------------// + static Double_t YPsipp13TeV(const Double_t* py, const Double_t* /*dummy*/) + { + // jpsi y in pp at 13 TeV, tuned on data (2015) + Double_t y = *py; + Float_t p0, p1, p2; + p0 = 1; + p1 = 0; + p2 = 2.98887; + return p0 * TMath::Exp(-(1. / 2.) * TMath::Power(((y - p1) / p2), 2)); + } + + //-------------------------------------------------------------------------// + static Double_t V2Psipp13TeV(const Double_t* /*dummy*/, const Double_t* /*dummy*/) + { + // jpsi v2 + return 0.; + } + + //-------------------------------------------------------------------------// + static Int_t IpPsipp13TeV(TRandom*) + { + return 100443; + } + + private: + GeneratorParam* paramPsi = nullptr; +}; + + +class O2_GeneratorParamChiC1 : public GeneratorTGenerator +{ + + public: + O2_GeneratorParamChiC1() : GeneratorTGenerator("ParamChiC1") + { + paramChiC1 = new GeneratorParam(1, -1, PtChiC1pp13TeV, YChiC1pp13TeV, V2ChiC1pp13TeV, IpChiC1pp13TeV); + paramChiC1->SetMomentumRange(0., 1.e6); + paramChiC1->SetPtRange(0., 1000.); + paramChiC1->SetYRange(-1.0, 1.0); + paramChiC1->SetPhiRange(0., 360.); + paramChiC1->SetDecayer(new TPythia6Decayer()); // Pythia + paramChiC1->SetForceDecay(kNoDecay); // particle left undecayed + setTGenerator(paramChiC1); + }; + + ~O2_GeneratorParamChiC1() + { + delete paramChiC1; + }; + + Bool_t Init() override + { + GeneratorTGenerator::Init(); + paramChiC1->Init(); + return true; + } + + void SetNSignalPerEvent(Int_t nsig) { paramChiC1->SetNumberParticles(nsig); } + + //-------------------------------------------------------------------------// + static Double_t PtChiC1pp13TeV(const Double_t* px, const Double_t* /*dummy*/) + { + // prompt J/Psi pT + // pp, 13TeV (tuned on pp 13 TeV, 2016-2018) + // + // ChiC1 R/(1+R12) Jpsi R= Ra+Rb pT(Jpsi), R12 = R12a + R12b pT(Jpsi)+ R12c pT(Jpsi)^2 + // C. Rosenthal, Y. Pachmayer. LHCb chiC/Jpsi and chiC1/chiC2, + // PLB 718 (2012) 431 + // JHEP 10 (2013) 115, PLB 714 (2012) 215 + // Linear function for chiC to Jpsi and quadratic for ChiC2/ChiC1 + + const Double_t Ra = 0.121; + const Double_t Rb = 0.011; + + const Double_t R12a = 1.43953; + const Double_t R12b = -0.145874; + const Double_t R12c = 0.00638469; + + const Double_t kC = 2.28550e+00; + const Double_t kpt0 = 3.73619e+00; + const Double_t kn = 2.81708e+00; + Double_t pt = px[0]; + + Double_t scaleChiC1 = (Ra+ Rb*pt)/(1+R12a+R12b*pt+R12c*pt*pt); + + + return scaleChiC1 * kC * pt / TMath::Power((1. + (pt / kpt0) * (pt / kpt0)), kn); + } + + //-------------------------------------------------------------------------// + static Double_t YChiC1pp13TeV(const Double_t* py, const Double_t* /*dummy*/) + { + // jpsi y in pp at 13 TeV, tuned on data, prompt jpsi ALICE+LHCb, 13 TeV + Double_t y = *py; + Float_t p0, p1, p2; + p0 = 7.79382e+00; + p1 = 2.87827e-06; + p2 = 4.41847e+00; + return p0 * TMath::Exp(-(1. / 2.) * TMath::Power(((y - p1) / p2), 2)); + } + + + //-------------------------------------------------------------------------// + static Double_t V2ChiC1pp13TeV(const Double_t* /*dummy*/, const Double_t* /*dummy*/) + { + // jpsi v2 + return 0.; + } + + //-------------------------------------------------------------------------// + static Int_t IpChiC1pp13TeV(TRandom*) + { + return 20443; + } + + private: + GeneratorParam* paramChiC1 = nullptr; +}; + +class O2_GeneratorParamChiC2 : public GeneratorTGenerator +{ + + public: + O2_GeneratorParamChiC2() : GeneratorTGenerator("ParamChiC2") + { + paramChiC2 = new GeneratorParam(1, -1, PtChiC2pp13TeV, YChiC2pp13TeV, V2ChiC2pp13TeV, IpChiC2pp13TeV); + paramChiC2->SetMomentumRange(0., 1.e6); // Momentum range added from me + paramChiC2->SetPtRange(0., 1000.); // transverse of momentum range + paramChiC2->SetYRange(-1.0, 1.0); // rapidity range + paramChiC2->SetPhiRange(0., 360.); // phi range + paramChiC2->SetDecayer(new TPythia6Decayer()); // Pythia decayer + paramChiC2->SetForceDecay(kNoDecay); // particle left undecayed + setTGenerator(paramChiC2); // Setting parameters to ParamPsi for Psi(2S) + }; + + ~O2_GeneratorParamChiC2() + { + delete paramChiC2; + }; + + Bool_t Init() override + { + GeneratorTGenerator::Init(); + paramChiC2->Init(); + return true; + } + void SetNSignalPerEvent(Int_t nsig) { paramChiC2->SetNumberParticles(nsig); } + + //-------------------------------------------------------------------------// + static Double_t PtChiC2pp13TeV(const Double_t* px, const Double_t* /*dummy*/) + { + + // ChiC2 R/(1+1/R12) Jpsi R= Ra+Rb pT(Jpsi), R12 = R12a + R12b pT(Jpsi)+ R12c pT(Jpsi)^2 + // prompt J/Psi pT + // pp, 13TeV (tuned on pp 13 TeV, 2016-2018) + // + const Double_t Ra = 0.121; + const Double_t Rb = 0.011; + + const Double_t R12a = 1.43953; + const Double_t R12b = -0.145874; + const Double_t R12c = 0.00638469; + + + + + const Double_t kC = 2.28550e+00; + const Double_t kpt0 = 3.73619e+00; + const Double_t kn = 2.81708e+00; + Double_t pt = px[0]; + Double_t scaleChiC2 = (Ra+ Rb*pt)/(1.+1./(R12a+R12b*pt+R12c*pt*pt)); + + + return scaleChiC2 * kC * pt / TMath::Power((1. + (pt / kpt0) * (pt / kpt0)), kn); + } + + + //-------------------------------------------------------------------------// + static Double_t YChiC2pp13TeV(const Double_t* py, const Double_t* /*dummy*/) + { + // jpsi y in pp at 13 TeV, tuned on data, prompt jpsi ALICE+LHCb, 13 TeV + Double_t y = *py; + Float_t p0, p1, p2; + p0 = 7.79382e+00; + p1 = 2.87827e-06; + p2 = 4.41847e+00; + return p0 * TMath::Exp(-(1. / 2.) * TMath::Power(((y - p1) / p2), 2)); + } + + //-------------------------------------------------------------------------// + static Double_t V2ChiC2pp13TeV(const Double_t* /*dummy*/, const Double_t* /*dummy*/) + { + // jpsi v2 + return 0.; + } + + //-------------------------------------------------------------------------// + static Int_t IpChiC2pp13TeV(TRandom*) + { + return 445; + } + + private: + GeneratorParam* paramChiC2 = nullptr; +}; + +class O2_GeneratorParamJpsipp5TeV : public GeneratorTGenerator +{ + + public: + O2_GeneratorParamJpsipp5TeV() : GeneratorTGenerator("ParamJpsi") + { + paramJpsi = new GeneratorParam(1, -1, PtJPsipp5TeV, YJPsipp5TeV, V2JPsipp5TeV, IpJPsipp5TeV); + paramJpsi->SetMomentumRange(0., 1.e6); + paramJpsi->SetPtRange(0, 999.); + paramJpsi->SetYRange(-4.2, -2.3); + paramJpsi->SetPhiRange(0., 360.); + paramJpsi->SetDecayer(new TPythia6Decayer()); + paramJpsi->SetForceDecay(kNoDecay); // particle left undecayed + // - - paramJpsi->SetTrackingFlag(1); // (from AliGenParam) -> check this + setTGenerator(paramJpsi); + }; + + ~O2_GeneratorParamJpsipp5TeV() + { + delete paramJpsi; + }; + + Bool_t Init() override + { + GeneratorTGenerator::Init(); + paramJpsi->Init(); + return true; + } + + void SetNSignalPerEvent(Int_t nsig) { paramJpsi->SetNumberParticles(nsig); } + + //-------------------------------------------------------------------------// + static Double_t PtJPsipp5TeV(const Double_t* px, const Double_t* /*dummy*/) + { + // jpsi pT in pp at 5.02 TeV, tuned on https://www.hepdata.net/record/ins1935680 + Double_t x = *px; + Float_t p0, p1, p2, p3; + p0 = 1; + p1 = 4.30923; + p2 = 1.82061; + p3 = 4.37563; + return p0 * x / TMath::Power(1. + TMath::Power(x / p1, p2), p3); + } + + //-------------------------------------------------------------------------// + static Double_t YJPsipp5TeV(const Double_t* py, const Double_t* /*dummy*/) { - // jpsi y in pp at 13 TeV, tuned on data (2015) + // jpsi y in pp at 5.02 TeV, tuned on https://www.hepdata.net/record/ins1935680 Double_t y = *py; Float_t p0, p1, p2; p0 = 1; - p1 = 0; - p2 = 2.98887; + p1 = 0.0338222; + p2 = 2.96748; return p0 * TMath::Exp(-(1. / 2.) * TMath::Power(((y - p1) / p2), 2)); } //-------------------------------------------------------------------------// - static Double_t V2JPsipp13TeV(const Double_t* /*dummy*/, const Double_t* /*dummy*/) + static Double_t V2JPsipp5TeV(const Double_t* /*dummy*/, const Double_t* /*dummy*/) { // jpsi v2 return 0.; } //-------------------------------------------------------------------------// - static Int_t IpJPsipp13TeV(TRandom*) + static Int_t IpJPsipp5TeV(TRandom*) { return 443; } @@ -241,13 +853,13 @@ class O2_GeneratorParamJpsiFwdY : public GeneratorTGenerator GeneratorParam* paramJpsi = nullptr; }; -class O2_GeneratorParamPsiFwdY : public GeneratorTGenerator +class O2_GeneratorParamPsipp5TeV : public GeneratorTGenerator { public: - O2_GeneratorParamPsiFwdY() : GeneratorTGenerator("ParamPsi") + O2_GeneratorParamPsipp5TeV() : GeneratorTGenerator("ParamPsi") { - paramPsi = new GeneratorParam(1, -1, PtPsipp13TeV, YPsipp13TeV, V2Psipp13TeV, IpPsipp13TeV); + paramPsi = new GeneratorParam(1, -1, PtPsipp5TeV, YPsipp5TeV, V2Psipp5TeV, IpPsipp5TeV); paramPsi->SetMomentumRange(0., 1.e6); paramPsi->SetPtRange(0, 999.); paramPsi->SetYRange(-4.2, -2.3); @@ -258,7 +870,7 @@ class O2_GeneratorParamPsiFwdY : public GeneratorTGenerator setTGenerator(paramPsi); }; - ~O2_GeneratorParamPsiFwdY() + ~O2_GeneratorParamPsipp5TeV() { delete paramPsi; }; @@ -273,39 +885,45 @@ class O2_GeneratorParamPsiFwdY : public GeneratorTGenerator void SetNSignalPerEvent(Int_t nsig) { paramPsi->SetNumberParticles(nsig); } //-------------------------------------------------------------------------// - static Double_t PtPsipp13TeV(const Double_t* px, const Double_t* /*dummy*/) + static Double_t PtPsipp5TeV(const Double_t* px, const Double_t* /*dummy*/) { - // jpsi pT in pp at 13 TeV, tuned on data (2015) + // psi2s pT in pp at 5.02 TeV, tuned on https://www.hepdata.net/record/ins1935680 Double_t x = *px; Float_t p0, p1, p2, p3; p0 = 1; - p1 = 4.75208; - p2 = 1.69247; - p3 = 4.49224; + p1 = 2.6444; + p2 = 6.17572; + p3 = 0.701753; return p0 * x / TMath::Power(1. + TMath::Power(x / p1, p2), p3); } //-------------------------------------------------------------------------// - static Double_t YPsipp13TeV(const Double_t* py, const Double_t* /*dummy*/) + static Double_t YPsipp5TeV(const Double_t* py, const Double_t* /*dummy*/) { - // jpsi y in pp at 13 TeV, tuned on data (2015) + // psi2s y in pp at 5.02 TeV, tuned on https://www.hepdata.net/record/ins1935680 + // WARNING! The shape extracted from data provide wired rapidity shape (low stat.), the J/psi one is used Double_t y = *py; Float_t p0, p1, p2; + // Extracted from Psi(2S) Run 2 data + //p0 = 1; + //p1 = -17.4857; + //p2 = 2.98887; + // Same parametrization as J/psi p0 = 1; - p1 = 0; - p2 = 2.98887; + p1 = 0.0338222; + p2 = 2.96748; return p0 * TMath::Exp(-(1. / 2.) * TMath::Power(((y - p1) / p2), 2)); } //-------------------------------------------------------------------------// - static Double_t V2Psipp13TeV(const Double_t* /*dummy*/, const Double_t* /*dummy*/) + static Double_t V2Psipp5TeV(const Double_t* /*dummy*/, const Double_t* /*dummy*/) { // jpsi v2 return 0.; } //-------------------------------------------------------------------------// - static Int_t IpPsipp13TeV(TRandom*) + static Int_t IpPsipp5TeV(TRandom*) { return 100443; } @@ -314,184 +932,157 @@ class O2_GeneratorParamPsiFwdY : public GeneratorTGenerator GeneratorParam* paramPsi = nullptr; }; - -class O2_GeneratorParamChiC1 : public GeneratorTGenerator +class O2_GeneratorParamJpsipp96TeV : public GeneratorTGenerator { public: - O2_GeneratorParamChiC1() : GeneratorTGenerator("ParamChiC1") + O2_GeneratorParamJpsipp96TeV() : GeneratorTGenerator("ParamJpsi") { - paramChiC1 = new GeneratorParam(1, -1, PtChiC1pp13TeV, YChiC1pp13TeV, V2ChiC1pp13TeV, IpChiC1pp13TeV); - paramChiC1->SetMomentumRange(0., 1.e6); - paramChiC1->SetPtRange(0., 1000.); - paramChiC1->SetYRange(-1.0, 1.0); - paramChiC1->SetPhiRange(0., 360.); - paramChiC1->SetDecayer(new TPythia6Decayer()); // Pythia - paramChiC1->SetForceDecay(kNoDecay); // particle left undecayed - setTGenerator(paramChiC1); + paramJpsi = new GeneratorParam(1, -1, PtJPsipp96TeV, YJPsipp96TeV, V2JPsipp96TeV, IpJPsipp96TeV); + paramJpsi->SetMomentumRange(0., 1.e6); + paramJpsi->SetPtRange(0, 999.); + paramJpsi->SetYRange(-4.2, -2.0); + paramJpsi->SetPhiRange(0., 360.); + paramJpsi->SetDecayer(new TPythia6Decayer()); + paramJpsi->SetForceDecay(kNoDecay); // particle left undecayed + // - - paramJpsi->SetTrackingFlag(1); // (from AliGenParam) -> check this + setTGenerator(paramJpsi); }; - ~O2_GeneratorParamChiC1() + ~O2_GeneratorParamJpsipp96TeV() { - delete paramChiC1; + delete paramJpsi; }; Bool_t Init() override { GeneratorTGenerator::Init(); - paramChiC1->Init(); + paramJpsi->Init(); return true; } - void SetNSignalPerEvent(Int_t nsig) { paramChiC1->SetNumberParticles(nsig); } + void SetNSignalPerEvent(Int_t nsig) { paramJpsi->SetNumberParticles(nsig); } //-------------------------------------------------------------------------// - static Double_t PtChiC1pp13TeV(const Double_t* px, const Double_t* /*dummy*/) + static Double_t PtJPsipp96TeV(const Double_t* px, const Double_t* /*dummy*/) { - // prompt J/Psi pT - // pp, 13TeV (tuned on pp 13 TeV, 2016-2018) - // - // ChiC1 R/(1+R12) Jpsi R= Ra+Rb pT(Jpsi), R12 = R12a + R12b pT(Jpsi)+ R12c pT(Jpsi)^2 - // C. Rosenthal, Y. Pachmayer. LHCb chiC/Jpsi and chiC1/chiC2, - // PLB 718 (2012) 431 - // JHEP 10 (2013) 115, PLB 714 (2012) 215 - // Linear function for chiC to Jpsi and quadratic for ChiC2/ChiC1 - - const Double_t Ra = 0.121; - const Double_t Rb = 0.011; - - const Double_t R12a = 1.43953; - const Double_t R12b = -0.145874; - const Double_t R12c = 0.00638469; - - const Double_t kC = 2.28550e+00; - const Double_t kpt0 = 3.73619e+00; - const Double_t kn = 2.81708e+00; - Double_t pt = px[0]; - - Double_t scaleChiC1 = (Ra+ Rb*pt)/(1+R12a+R12b*pt+R12c*pt*pt); - - - return scaleChiC1 * kC * pt / TMath::Power((1. + (pt / kpt0) * (pt / kpt0)), kn); + // Parameters extrapolated linearly between 5 TeV and 13 TeV as a function of log(sqrt(s)) + Double_t x = *px; + Float_t p0, p1, p2, p3; + p0 = 1; + p1 = 4.61097; + p2 = 1.7333; + p3 = 4.45508; + return p0 * x / TMath::Power(1. + TMath::Power(x / p1, p2), p3); } //-------------------------------------------------------------------------// - static Double_t YChiC1pp13TeV(const Double_t* py, const Double_t* /*dummy*/) + static Double_t YJPsipp96TeV(const Double_t* py, const Double_t* /*dummy*/) { - // jpsi y in pp at 13 TeV, tuned on data, prompt jpsi ALICE+LHCb, 13 TeV + // Parameters extrapolated linearly between 5 TeV and 13 TeV as a function of log(sqrt(s)), shifted by a rapidity boost dy=0.35 Double_t y = *py; + Double_t deltaY = 0.35; + Double_t yCM = y - deltaY; Float_t p0, p1, p2; - p0 = 7.79382e+00; - p1 = 2.87827e-06; - p2 = 4.41847e+00; - return p0 * TMath::Exp(-(1. / 2.) * TMath::Power(((y - p1) / p2), 2)); + p0 = 1; + p1 = 0.0107769; + p2 = 2.98205; + return p0 * TMath::Exp(-(1. / 2.) * TMath::Power(((yCM - p1) / p2), 2)); } - //-------------------------------------------------------------------------// - static Double_t V2ChiC1pp13TeV(const Double_t* /*dummy*/, const Double_t* /*dummy*/) + static Double_t V2JPsipp96TeV(const Double_t* /*dummy*/, const Double_t* /*dummy*/) { // jpsi v2 return 0.; } //-------------------------------------------------------------------------// - static Int_t IpChiC1pp13TeV(TRandom*) + static Int_t IpJPsipp96TeV(TRandom*) { - return 20443; + return 443; } private: - GeneratorParam* paramChiC1 = nullptr; + GeneratorParam* paramJpsi = nullptr; }; -class O2_GeneratorParamChiC2 : public GeneratorTGenerator +class O2_GeneratorParamPsipp96TeV : public GeneratorTGenerator { public: - O2_GeneratorParamChiC2() : GeneratorTGenerator("ParamChiC2") + O2_GeneratorParamPsipp96TeV() : GeneratorTGenerator("ParamPsi") { - paramChiC2 = new GeneratorParam(1, -1, PtChiC2pp13TeV, YChiC2pp13TeV, V2ChiC2pp13TeV, IpChiC2pp13TeV); - paramChiC2->SetMomentumRange(0., 1.e6); // Momentum range added from me - paramChiC2->SetPtRange(0., 1000.); // transverse of momentum range - paramChiC2->SetYRange(-1.0, 1.0); // rapidity range - paramChiC2->SetPhiRange(0., 360.); // phi range - paramChiC2->SetDecayer(new TPythia6Decayer()); // Pythia decayer - paramChiC2->SetForceDecay(kNoDecay); // particle left undecayed - setTGenerator(paramChiC2); // Setting parameters to ParamPsi for Psi(2S) + paramPsi = new GeneratorParam(1, -1, PtPsipp96TeV, YPsipp96TeV, V2Psipp96TeV, IpPsipp96TeV); + paramPsi->SetMomentumRange(0., 1.e6); + paramPsi->SetPtRange(0, 999.); + paramPsi->SetYRange(-4.2, -2.0); + paramPsi->SetPhiRange(0., 360.); + paramPsi->SetDecayer(new TPythia6Decayer()); + paramPsi->SetForceDecay(kNoDecay); // particle left undecayed + // - - paramJpsi->SetTrackingFlag(1); // check this + setTGenerator(paramPsi); }; - ~O2_GeneratorParamChiC2() + ~O2_GeneratorParamPsipp96TeV() { - delete paramChiC2; + delete paramPsi; }; Bool_t Init() override { GeneratorTGenerator::Init(); - paramChiC2->Init(); + paramPsi->Init(); return true; } - void SetNSignalPerEvent(Int_t nsig) { paramChiC2->SetNumberParticles(nsig); } + + void SetNSignalPerEvent(Int_t nsig) { paramPsi->SetNumberParticles(nsig); } //-------------------------------------------------------------------------// - static Double_t PtChiC2pp13TeV(const Double_t* px, const Double_t* /*dummy*/) + static Double_t PtPsipp96TeV(const Double_t* px, const Double_t* /*dummy*/) { - - // ChiC2 R/(1+1/R12) Jpsi R= Ra+Rb pT(Jpsi), R12 = R12a + R12b pT(Jpsi)+ R12c pT(Jpsi)^2 - // prompt J/Psi pT - // pp, 13TeV (tuned on pp 13 TeV, 2016-2018) - // - const Double_t Ra = 0.121; - const Double_t Rb = 0.011; - - const Double_t R12a = 1.43953; - const Double_t R12b = -0.145874; - const Double_t R12c = 0.00638469; - - - - - const Double_t kC = 2.28550e+00; - const Double_t kpt0 = 3.73619e+00; - const Double_t kn = 2.81708e+00; - Double_t pt = px[0]; - Double_t scaleChiC2 = (Ra+ Rb*pt)/(1.+1./(R12a+R12b*pt+R12c*pt*pt)); - - - return scaleChiC2 * kC * pt / TMath::Power((1. + (pt / kpt0) * (pt / kpt0)), kn); + // Taking same parameters as Psi(2S) at 13 TeV + Double_t x = *px; + Float_t p0, p1, p2, p3; + p0 = 1; + p1 = 4.75208; + p2 = 1.69247; + p3 = 4.49224; + return p0 * x / TMath::Power(1. + TMath::Power(x / p1, p2), p3); } - //-------------------------------------------------------------------------// - static Double_t YChiC2pp13TeV(const Double_t* py, const Double_t* /*dummy*/) + static Double_t YPsipp96TeV(const Double_t* py, const Double_t* /*dummy*/) { - // jpsi y in pp at 13 TeV, tuned on data, prompt jpsi ALICE+LHCb, 13 TeV + // Taking same parameters as Psi(2S) at 13 TeV Double_t y = *py; + Double_t deltaY = 0.35; + Double_t yCM = y - deltaY; Float_t p0, p1, p2; - p0 = 7.79382e+00; - p1 = 2.87827e-06; - p2 = 4.41847e+00; - return p0 * TMath::Exp(-(1. / 2.) * TMath::Power(((y - p1) / p2), 2)); + p0 = 1; + p1 = 0; + p2 = 2.98887; + return p0 * TMath::Exp(-(1. / 2.) * TMath::Power(((yCM - p1) / p2), 2)); } //-------------------------------------------------------------------------// - static Double_t V2ChiC2pp13TeV(const Double_t* /*dummy*/, const Double_t* /*dummy*/) + static Double_t V2Psipp96TeV(const Double_t* /*dummy*/, const Double_t* /*dummy*/) { // jpsi v2 return 0.; } //-------------------------------------------------------------------------// - static Int_t IpChiC2pp13TeV(TRandom*) + static Int_t IpPsipp96TeV(TRandom*) { - return 445; + return 100443; } private: - GeneratorParam* paramChiC2 = nullptr; + GeneratorParam* paramPsi = nullptr; }; + class O2_GeneratorParamJpsiPbPb5TeV : public GeneratorTGenerator { @@ -810,6 +1401,110 @@ FairGenerator* GeneratorCocktailPromptCharmoniaToMuonEvtGen_pp13TeV() return genCocktailEvtGen; } +FairGenerator* GeneratorCocktailPromptCharmoniaToMuonEvtGen_pp5TeV() +{ + + auto genCocktailEvtGen = new o2::eventgen::GeneratorEvtGen(); + + auto genJpsi = new o2::eventgen::O2_GeneratorParamJpsipp5TeV; + genJpsi->SetNSignalPerEvent(1); // 1 J/psi generated per event by GeneratorParam + auto genPsi = new o2::eventgen::O2_GeneratorParamPsipp5TeV; + genPsi->SetNSignalPerEvent(1); // 1 Psi(2S) generated per event by GeneratorParam + genCocktailEvtGen->AddGenerator(genJpsi, 1); // add J/psi generator + genCocktailEvtGen->AddGenerator(genPsi, 1); // add Psi(2S) generator + + TString pdgs = "443;100443"; + std::string spdg; + TObjArray* obj = pdgs.Tokenize(";"); + genCocktailEvtGen->SetSizePdg(obj->GetEntriesFast()); + for (int i = 0; i < obj->GetEntriesFast(); i++) { + spdg = obj->At(i)->GetName(); + genCocktailEvtGen->AddPdg(std::stoi(spdg), i); + printf("PDG %d \n", std::stoi(spdg)); + } + genCocktailEvtGen->SetForceDecay(kEvtDiMuon); + + return genCocktailEvtGen; +} + +FairGenerator* GeneratorCocktailPromptCharmoniaToMuonEvtGen_pp96TeV() +{ + + auto genCocktailEvtGen = new o2::eventgen::GeneratorEvtGen(); + + auto genJpsi = new o2::eventgen::O2_GeneratorParamJpsipp96TeV; + genJpsi->SetNSignalPerEvent(1); // 1 J/psi generated per event by GeneratorParam + auto genPsi = new o2::eventgen::O2_GeneratorParamPsipp96TeV; + genPsi->SetNSignalPerEvent(1); // 1 Psi(2S) generated per event by GeneratorParam + genCocktailEvtGen->AddGenerator(genJpsi, 1); // add J/psi generator + genCocktailEvtGen->AddGenerator(genPsi, 1); // add Psi(2S) generator + + TString pdgs = "443;100443"; + std::string spdg; + TObjArray* obj = pdgs.Tokenize(";"); + genCocktailEvtGen->SetSizePdg(obj->GetEntriesFast()); + for (int i = 0; i < obj->GetEntriesFast(); i++) { + spdg = obj->At(i)->GetName(); + genCocktailEvtGen->AddPdg(std::stoi(spdg), i); + printf("PDG %d \n", std::stoi(spdg)); + } + genCocktailEvtGen->SetForceDecay(kEvtDiMuon); + + return genCocktailEvtGen; +} + + +FairGenerator* GeneratorCocktailPromptCharmoniaToElectronEvtGen_pp5TeV() +{ + + auto genCocktailEvtGen = new o2::eventgen::GeneratorEvtGen(); + + auto genJpsi = new o2::eventgen::O2_GeneratorParamJpsiMidY_5TeV; + genJpsi->SetNSignalPerEvent(1); // 1 J/psi generated per event by GeneratorParam + auto genPsi = new o2::eventgen::O2_GeneratorParamPsiMidY_5TeV; + genPsi->SetNSignalPerEvent(1); // 1 Psi(2S) generated per event by GeneratorParam + genCocktailEvtGen->AddGenerator(genJpsi, 1); // add J/psi generator + genCocktailEvtGen->AddGenerator(genPsi, 1); // add Psi(2S) generator + + TString pdgs = "443;100443"; + std::string spdg; + TObjArray* obj = pdgs.Tokenize(";"); + genCocktailEvtGen->SetSizePdg(obj->GetEntriesFast()); + for (int i = 0; i < obj->GetEntriesFast(); i++) { + spdg = obj->At(i)->GetName(); + genCocktailEvtGen->AddPdg(std::stoi(spdg), i); + printf("PDG %d \n", std::stoi(spdg)); + } + genCocktailEvtGen->SetForceDecay(kEvtDiElectron); + + return genCocktailEvtGen; +} + +FairGenerator* GeneratorCocktailPromptCharmoniaToElectronEvtGen_pp96TeV() +{ + + auto genCocktailEvtGen = new o2::eventgen::GeneratorEvtGen(); + + auto genJpsi = new o2::eventgen::O2_GeneratorParamJpsiMidY_96TeV; + genJpsi->SetNSignalPerEvent(1); // 1 J/psi generated per event by GeneratorParam + auto genPsi = new o2::eventgen::O2_GeneratorParamPsiMidY_96TeV; + genPsi->SetNSignalPerEvent(1); // 1 Psi(2S) generated per event by GeneratorParam + genCocktailEvtGen->AddGenerator(genJpsi, 1); // add J/psi generator + genCocktailEvtGen->AddGenerator(genPsi, 1); // add Psi(2S) generator + + TString pdgs = "443;100443"; + std::string spdg; + TObjArray* obj = pdgs.Tokenize(";"); + genCocktailEvtGen->SetSizePdg(obj->GetEntriesFast()); + for (int i = 0; i < obj->GetEntriesFast(); i++) { + spdg = obj->At(i)->GetName(); + genCocktailEvtGen->AddPdg(std::stoi(spdg), i); + printf("PDG %d \n", std::stoi(spdg)); + } + genCocktailEvtGen->SetForceDecay(kEvtDiElectron); + + return genCocktailEvtGen; +} FairGenerator* GeneratorParamPromptPsiToJpsiPiPiEvtGen_pp13TeV(TString pdgs = "100443") diff --git a/MC/config/PWGDQ/external/generator/generator_pythia8_HadronTriggered_PbPb.C b/MC/config/PWGDQ/external/generator/generator_pythia8_HadronTriggered_PbPb.C new file mode 100644 index 000000000..3c3034f80 --- /dev/null +++ b/MC/config/PWGDQ/external/generator/generator_pythia8_HadronTriggered_PbPb.C @@ -0,0 +1,422 @@ +#include "FairGenerator.h" +#include "Generators/GeneratorPythia8.h" +#include "Pythia8/Pythia.h" +#include "TRandom.h" +#include "TParticle.h" + +R__ADD_INCLUDE_PATH($O2DPG_MC_CONFIG_ROOT/MC/config/PWGDQ/EvtGen) +#include "GeneratorEvtGen.C" + +#include + +using namespace o2::eventgen; + +namespace o2 +{ +namespace eventgen +{ + +class GeneratorPythia8HadronTriggeredPbPb : public o2::eventgen::GeneratorPythia8 { +public: + + /// constructor + GeneratorPythia8HadronTriggeredPbPb(int inputTriggerRatio = 5) { + + mGeneratedEvents = 0; + mInverseTriggerRatio = inputTriggerRatio; + // define minimum bias event generator + auto seed = (gRandom->TRandom::GetSeed() % 900000000); + TString pathconfigMB = gSystem->ExpandPathName("${O2DPG_MC_CONFIG_ROOT}/MC/config/ALICE3/pythia8/generator/pythia8_PbPb_536tev.cfg"); + pythiaMBgen.readFile(pathconfigMB.Data()); + pythiaMBgen.readString("Random:setSeed on"); + pythiaMBgen.readString("Random:seed " + std::to_string(seed)); + mConfigMBdecays = ""; + mRapidityMin = -1.; + mRapidityMax = 1.; + mVerbose = false; + } + + /// Destructor + ~GeneratorPythia8HadronTriggeredPbPb() = default; + + void addHadronPDGs(int pdg) { mHadronsPDGs.push_back(pdg); }; + + void setRapidityRange(double valMin, double valMax) + { + mRapidityMin = valMin; + mRapidityMax = valMax; + }; + + void setTriggerGap(int triggerGap) {mInverseTriggerRatio = triggerGap;} + + void setConfigMBdecays(TString val){mConfigMBdecays = val;} + + void setVerbose(bool val) { mVerbose = val; }; + +protected: + + bool generateEvent() override { + return true; + } + + bool Init() override { + if(mConfigMBdecays.Contains("cfg")) { + pythiaMBgen.readFile(mConfigMBdecays.Data()); + } + GeneratorPythia8::Init(); + pythiaMBgen.init(); + return true; + } + + std::vector findAllCharmonia(const Pythia8::Event& event) { + std::vector out; out.reserve(4); + + for (int ipa = 0; ipa < event.size(); ++ipa) { + + auto daughterList = event[ipa].daughterList(); + + for (auto ida : daughterList) { + for (int pdg : mHadronsPDGs) { // check that at least one of the pdg code is found in the event + if (event[ida].id() == pdg) { + if ((event[ida].y() > mRapidityMin) && (event[ida].y() < mRapidityMax)) { + //cout << "============= Found jpsi y,pt " << event[ida].y() << ", " << event[ida].pT() << endl; + out.push_back(ida); + } + } + } + } + } + + return out; + } + + bool keepAncestor(int idabs){ + // charmonium + int mid2 = (idabs / 10) % 100; // 443,100443,20443,445... + if (mid2 == 44) return true; + + // open charm/beauty hadron (D, B, charmed/bottom baryon...) + int flav = (idabs / 100) % 10; + if (flav == 4 || flav == 5) return true; + + return false; +} + +void collectAncestors(const Pythia8::Event& event, int idx, std::vector& decayChains, std::vector& visited) { + if (idx < 0 || idx >= event.size()) return; + if (visited[idx]) return; + visited[idx] = 1; + + const int idabs = std::abs(event[idx].id()); + if (idabs == 4 || idabs == 5 || idabs == 21) return; + + int mother1 = event[idx].mother1(); + int mother2 = event[idx].mother2(); + if (mother1 < 0) return; + if (mother2 < mother1) mother2 = mother1; + for (int m = mother1; m <= mother2; ++m) { + if (m == idx) continue; + collectAncestors(event, m, decayChains, visited); + } + + if (keepAncestor(idabs)) decayChains.push_back(idx); +} + +void collectDaughters(const Pythia8::Event& event, int idx, std::vector& decayChains, std::vector& visited) { + if (idx < 0 || idx >= event.size()) return; + if (visited[idx] == 0) { + decayChains.push_back(idx); + } + + if (visited[idx] == 2) return; + visited[idx] = 2; + + int daughter1 = event[idx].daughter1(); + int daughter2 = event[idx].daughter2(); + if (daughter1 < 0) return; + if (daughter2 < daughter1) daughter2 = daughter1; + + for (int d = daughter1; d <= daughter2; ++d) { + if (d == idx) continue; + collectDaughters(event, d, decayChains, visited); + } +} + +TParticle makeTParticleTemp(const Pythia8::Event& event, int idx) { + const auto& q = event[idx]; + int status = q.daughter1() < 0? 1 : 2; + + int m1 = q.mother1(); + int m2 = q.mother2(); + int d1 = q.daughter1(); + int d2 = q.daughter2(); + TParticle tparticle(q.id(), status, m1, m2, d1, d2, + q.px(), q.py(), q.pz(), q.e(), + q.xProd(), q.yProd(), q.zProd(), q.tProd()); + + if (tparticle.GetStatusCode() == 1) { + tparticle.SetStatusCode( + o2::mcgenstatus::MCGenStatusEncoding(1, 91).fullEncoding); + tparticle.SetBit(ParticleStatus::kToBeDone, true); + } else { + tparticle.SetStatusCode( + o2::mcgenstatus::MCGenStatusEncoding(2, -91).fullEncoding); + tparticle.SetBit(ParticleStatus::kToBeDone, false); + } + + return tparticle; + +} + +Bool_t importParticles() override +{ + //LOG(info) << ""; + //LOG(info) << "*************************************************************"; + //LOG(info) << "************** New signal event considered **************"; + //LOG(info) << "*************************************************************"; + //LOG(info) << ""; + + const int nSig = std::max(1, (int)std::lround(mNumSigEvs)); + for (int isig=0; isig charmonia; + while (! (genOk && !charmonia.empty())) { + /// reset event + mPythia.event.reset(); + genOk = GeneratorPythia8::generateEvent(); + if (!genOk) continue; + charmonia = findAllCharmonia(mPythia.event); + } + + std::vector decayChains; + std::vector visited(mPythia.event.size(), 0); + decayChains.reserve(mPythia.event.size()); + + //int originalSize = mParticles.size(); + + // find all ancestors of the charmonia + for (size_t ic = 0; ic < charmonia.size(); ++ic) { + int cidx = charmonia[ic]; + collectAncestors(mPythia.event, cidx, decayChains, visited); + } + + // find all daughters of the charmonia + for (size_t ic = 0; ic < charmonia.size(); ++ic) { + int cidx = charmonia[ic]; + collectDaughters(mPythia.event, cidx, decayChains, visited); + } + + std::vector idxMap(mPythia.event.size(), -1); + mParticles.reserve(mParticles.size() + (int)decayChains.size()); + + for (int i = 0; i < (int)decayChains.size(); ++i) { + const int srcIdx = decayChains[i]; + if (srcIdx < 0 || srcIdx >= mPythia.event.size()) continue; + + TParticle part = makeTParticleTemp(mPythia.event, srcIdx); + + int newIdx = (int)mParticles.size(); + mParticles.push_back(part); + idxMap[srcIdx] = newIdx; + } + + for (int iLoc = 0; iLoc < (int) decayChains.size(); ++iLoc) { + const int srcIdx = decayChains[iLoc]; + if (srcIdx < 0 || srcIdx >= (int)idxMap.size()) continue; + const int outIdx = idxMap[srcIdx]; + if (outIdx < 0) continue; + + const auto& src = mPythia.event[srcIdx]; + + const int mother1 = (src.mother1() >= 0 ? idxMap[src.mother1()] : -1); + const int mother2 = (src.mother2() >= 0 ? idxMap[src.mother2()] : -1); + const int daughter1 = (src.daughter1()>= 0 ? idxMap[src.daughter1()] : -1); + const int daughter2 = (src.daughter2()>= 0 ? idxMap[src.daughter2()] : -1); + + // update TParticle + TParticle& particle = mParticles[outIdx]; + particle.SetFirstMother(mother1); + particle.SetLastMother(mother2); + particle.SetFirstDaughter(daughter1); + particle.SetLastDaughter(daughter2); + } + //LOG(info) << "-----------------------------------------------"; + //LOG(info) << "============ After event " << isig << " (size " << decayChains.size() << ")"; + //LOG(info) << "Full stack (size " << mParticles.size() << "):"; + //LOG(info) << "New particles from signal event " << isig; + //for (int id = originalSize; id < (int)mParticles.size(); ++id) { + // const auto& p = mParticles[id]; + // LOG(info) << " id = " << id + // << ", pdg = " << p.GetPdgCode() + // << " --> firstMother=" << p.GetFirstMother() + // << ", lastMother=" << p.GetSecondMother() + // << ", firstDaughter=" << p.GetFirstDaughter() + // << ", lastDaughter=" << p.GetLastDaughter(); + //} + //LOG(info) << "-----------------------------------------------"; + } + + if (mVerbose) mOutputEvent.list(); + + return kTRUE; +} + +void notifyEmbedding(const o2::dataformats::MCEventHeader* bkgHeader) override { + LOG(info) << "[notifyEmbedding] ----- Function called"; + + /// Impact parameter between the two nuclei + const float x = bkgHeader->GetB(); + LOG(info) << "[notifyEmbedding] ----- Collision impact parameter: " << x; + + /// number of events to be embedded in a background event + mNumSigEvs = 5 + 0.886202881*std::pow(std::max(0.0f, 17.5f - x),1.7); + LOG(info) << "[notifyEmbedding] ----- generating " << mNumSigEvs << " signal events " << std::endl; +}; + +private: + // Interface to override import particles + Pythia8::Event mOutputEvent; + + // Control gap-triggering + unsigned long long mGeneratedEvents; + int mInverseTriggerRatio; + Pythia8::Pythia pythiaMBgen; // minimum bias event + TString mConfigMBdecays; + std::vector mHadronsPDGs; + double mRapidityMin; + double mRapidityMax; + bool mVerbose; + + // number of signal events to be embedded in a background event + int mNumSigEvs{1}; +}; + +} + +} + +// Predefined generators: +FairGenerator* + GeneratorPromptJpsi_EvtGenMidY(int triggerGap, double rapidityMin = -1.5, double rapidityMax = 1.5, bool verbose = false, bool embedding = false) +{ + auto gen = new o2::eventgen::GeneratorEvtGen(); + gen->setTriggerGap(triggerGap); + gen->setRapidityRange(rapidityMin, rapidityMax); + gen->addHadronPDGs(443); + gen->setVerbose(verbose); + + TString pathO2table = gSystem->ExpandPathName("${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGDQ/pythia8/decayer/switchOffJpsi.cfg"); + gen->readFile(pathO2table.Data()); + gen->setConfigMBdecays(pathO2table); + gen->PrintDebug(true); + + gen->SetSizePdg(1); + gen->AddPdg(443, 0); + + gen->SetForceDecay(kEvtDiElectron); + + // set random seed + gen->readString("Random:setSeed on"); + uint random_seed; + unsigned long long int random_value = 0; + ifstream urandom("/dev/urandom", ios::in|ios::binary); + urandom.read(reinterpret_cast(&random_value), sizeof(random_seed)); + gen->readString(Form("Random:seed = %llu", random_value % 900000001)); + + // print debug + // gen->PrintDebug(); + + return gen; +} + +FairGenerator* + GeneratorPromptJpsiPsi2S_EvtGenMidY(int triggerGap, double rapidityMin = -1.5, double rapidityMax = 1.5, bool verbose = false, bool embedding = false) +{ + auto gen = new o2::eventgen::GeneratorEvtGen(); + gen->setTriggerGap(triggerGap); + gen->setRapidityRange(rapidityMin, rapidityMax); + gen->addHadronPDGs(443); + gen->addHadronPDGs(100443); + gen->setVerbose(verbose); + TString pathO2table = gSystem->ExpandPathName("${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGDQ/pythia8/decayer/switchOffJpsi.cfg"); + gen->readFile(pathO2table.Data()); + gen->setConfigMBdecays(pathO2table); + gen->PrintDebug(true); + gen->SetSizePdg(2); + gen->AddPdg(443, 0); + gen->AddPdg(100443, 1); + gen->SetForceDecay(kEvtDiElectron); + // set random seed + gen->readString("Random:setSeed on"); + uint random_seed; + unsigned long long int random_value = 0; + ifstream urandom("/dev/urandom", ios::in|ios::binary); + urandom.read(reinterpret_cast(&random_value), sizeof(random_seed)); + gen->readString(Form("Random:seed = %llu", random_value % 900000001)); + // print debug + // gen->PrintDebug(); + return gen; +} + +FairGenerator* + GeneratorPromptJpsi_EvtGenFwdy(int triggerGap, double rapidityMin = -4.3, double rapidityMax = -2.3, bool verbose = false, bool embedding = false) +{ + auto gen = new o2::eventgen::GeneratorEvtGen(); + gen->setTriggerGap(triggerGap); + gen->setRapidityRange(rapidityMin, rapidityMax); + gen->addHadronPDGs(443); + gen->setVerbose(verbose); + + TString pathO2table = gSystem->ExpandPathName("${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGDQ/pythia8/decayer/switchOffJpsi.cfg"); + gen->readFile(pathO2table.Data()); + gen->setConfigMBdecays(pathO2table); + gen->PrintDebug(true); + + gen->SetSizePdg(1); + gen->AddPdg(443, 0); + + gen->SetForceDecay(kEvtDiMuon); + + // set random seed + gen->readString("Random:setSeed on"); + uint random_seed; + unsigned long long int random_value = 0; + ifstream urandom("/dev/urandom", ios::in|ios::binary); + urandom.read(reinterpret_cast(&random_value), sizeof(random_seed)); + gen->readString(Form("Random:seed = %llu", random_value % 900000001)); + + // print debug + // gen->PrintDebug(); + + return gen; +} + +FairGenerator* + GeneratorPromptJpsiPsi2S_EvtGenFwdY(int triggerGap, double rapidityMin = -4.3, double rapidityMax = -2.3, bool verbose = false, bool embedding = false) +{ + auto gen = new o2::eventgen::GeneratorEvtGen(); + gen->setTriggerGap(triggerGap); + gen->setRapidityRange(rapidityMin, rapidityMax); + gen->addHadronPDGs(443); + gen->addHadronPDGs(100443); + gen->setVerbose(verbose); + TString pathO2table = gSystem->ExpandPathName("${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGDQ/pythia8/decayer/switchOffJpsi.cfg"); + gen->readFile(pathO2table.Data()); + gen->setConfigMBdecays(pathO2table); + gen->PrintDebug(true); + gen->SetSizePdg(2); + gen->AddPdg(443, 0); + gen->AddPdg(100443, 1); + gen->SetForceDecay(kEvtDiMuon); + // set random seed + gen->readString("Random:setSeed on"); + uint random_seed; + unsigned long long int random_value = 0; + ifstream urandom("/dev/urandom", ios::in|ios::binary); + urandom.read(reinterpret_cast(&random_value), sizeof(random_seed)); + gen->readString(Form("Random:seed = %llu", random_value % 900000001)); + // print debug + // gen->PrintDebug(); + return gen; +} diff --git a/MC/config/PWGDQ/external/generator/generator_pythia8_HadronTriggered_withGap.C b/MC/config/PWGDQ/external/generator/generator_pythia8_HadronTriggered_withGap.C index 8e8f46938..d34092a8c 100644 --- a/MC/config/PWGDQ/external/generator/generator_pythia8_HadronTriggered_withGap.C +++ b/MC/config/PWGDQ/external/generator/generator_pythia8_HadronTriggered_withGap.C @@ -211,4 +211,42 @@ FairGenerator* // gen->PrintDebug(); return gen; -} \ No newline at end of file +} +FairGenerator * +GeneratorInclusiveJpsiPsi2SChiC_EvtGenMidY(int triggerGap, double rapidityMin = -1.5, double rapidityMax = 1.5, bool verbose = false) +{ + auto gen = new o2::eventgen::GeneratorEvtGen(); + gen->setTriggerGap(triggerGap); + gen->setRapidityRange(rapidityMin, rapidityMax); + gen->addHadronPDGs(443); + gen->addHadronPDGs(100443); + gen->addHadronPDGs(445); + gen->addHadronPDGs(200443); + gen->setVerbose(verbose); + + TString pathO2table = gSystem->ExpandPathName("${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGDQ/pythia8/decayer/switchOffJpsi.cfg"); + gen->readFile(pathO2table.Data()); + gen->setConfigMBdecays(pathO2table); + gen->PrintDebug(true); + + gen->SetSizePdg(4); + gen->AddPdg(443, 0); + gen->AddPdg(100443, 1); + gen->AddPdg(443, 2); + gen->AddPdg(100443, 3); + + gen->SetForceDecay(kEvtDiElectron); + + // set random seed + gen->readString("Random:setSeed on"); + uint random_seed; + unsigned long long int random_value = 0; + ifstream urandom("/dev/urandom", ios::in | ios::binary); + urandom.read(reinterpret_cast(&random_value), sizeof(random_seed)); + gen->readString(Form("Random:seed = %llu", random_value % 900000001)); + + // print debug + // gen->PrintDebug(); + + return gen; +} diff --git a/MC/config/PWGDQ/external/generator/generator_pythia8_NonPromptSignals_OO_gaptriggered_dq.C b/MC/config/PWGDQ/external/generator/generator_pythia8_NonPromptSignals_OO_gaptriggered_dq.C new file mode 100644 index 000000000..0673ca60f --- /dev/null +++ b/MC/config/PWGDQ/external/generator/generator_pythia8_NonPromptSignals_OO_gaptriggered_dq.C @@ -0,0 +1,336 @@ +#include "FairGenerator.h" +#include "Generators/GeneratorPythia8.h" +#include "Pythia8/Pythia.h" +#include "TRandom.h" + +R__ADD_INCLUDE_PATH($O2DPG_MC_CONFIG_ROOT/MC/config/PWGDQ/EvtGen) +#include "GeneratorEvtGen.C" + +#include + +using namespace o2::eventgen; + +namespace o2 +{ +namespace eventgen +{ + +class GeneratorPythia8NonPromptInjectedOOGapTriggeredDQ : public o2::eventgen::GeneratorPythia8 { +public: + + /// constructor + GeneratorPythia8NonPromptInjectedOOGapTriggeredDQ(int inputTriggerRatio = 2) { + + mGeneratedEvents = 0; + mInverseTriggerRatio = inputTriggerRatio; + + // Read INPUT_TRIGGER_RATIO from the shell environment. + // If it is not defined, keep the default constructor value. + const char* envTriggerRatio = gSystem->Getenv("INPUT_TRIGGER_RATIO"); + + if (envTriggerRatio && envTriggerRatio[0] != '\0') { + const int valueFromEnv = TString(envTriggerRatio).Atoi(); + + if (valueFromEnv > 0) { + inputTriggerRatio = valueFromEnv; + } else { + printf( + "WARNING: invalid INPUT_TRIGGER_RATIO=%s, using default value %d\n", + envTriggerRatio, + inputTriggerRatio); + } + } + + mGeneratedEvents = 0; + mInverseTriggerRatio = inputTriggerRatio; + + printf("Input trigger ratio: %d\n", mInverseTriggerRatio); + + // define minimum bias event generator + auto seed = (gRandom->TRandom::GetSeed() % 900000000); + + TString pathconfigMB = gSystem->ExpandPathName("${O2DPG_MC_CONFIG_ROOT}/MC/config/common/pythia8/generator/pythia8_OO_536.cfg"); + pythiaMBgen.readFile(pathconfigMB.Data()); + pythiaMBgen.readString("Random:setSeed on"); + pythiaMBgen.readString("Random:seed " + std::to_string(seed)); + mConfigMBdecays = ""; + mPDG = 5; + mRapidityMin = -1.; + mRapidityMax = 1.; + mHadronMultiplicity = -1; + mHadronRapidityMin = -1.; + mHadronRapidityMax = 1.; + mVerbose = false; + } + + /// Destructor + ~GeneratorPythia8NonPromptInjectedOOGapTriggeredDQ() = default; + + void setPDG(int val) { mPDG = val; }; + void addHadronPDGs(int pdg) { mHadronsPDGs.push_back(pdg); }; + void setHadronMultiplicity(int val) { mHadronMultiplicity = val; }; + void setRapidity(double valMin, double valMax) + { + mRapidityMin = valMin; + mRapidityMax = valMax; + }; + + void setRapidityHadron(double valMin, double valMax) + { + mHadronRapidityMin = valMin; + mHadronRapidityMax = valMax; + }; + + void setConfigMBdecays(TString val){mConfigMBdecays = val;} + + void setVerbose(bool val) { mVerbose = val; }; + +protected: + +Bool_t generateEvent() override + { + // reset event + bool genOk = false; + if (mGeneratedEvents % mInverseTriggerRatio == 0){ + bool ancestor = false; + while (! (genOk && ancestor) ){ + /// reset event + mPythia.event.reset(); + genOk = GeneratorPythia8::generateEvent(); + // find the q-qbar ancestor + ancestor = findHeavyQuarkPair(mPythia.event); + } + } else { + /// reset event + pythiaMBgen.event.reset(); + while (!genOk) { + genOk = pythiaMBgen.next(); + } + mPythia.event = pythiaMBgen.event; + } + mGeneratedEvents++; + if (mVerbose) mOutputEvent.list(); + return true; + } + +Bool_t Init() override + { + if(mConfigMBdecays.Contains("cfg")) pythiaMBgen.readFile(mConfigMBdecays.Data()); + GeneratorPythia8::Init(); + pythiaMBgen.init(); + return true; + } + + // search for q-qbar mother with at least one q in a selected rapidity window + bool findHeavyQuarkPair(Pythia8::Event& event) + { + int countH[mHadronsPDGs.size()]; for(int ipdg=0; ipdg < mHadronsPDGs.size(); ipdg++) countH[ipdg]=0; + bool hasq = false, hasqbar = false, atSelectedY = false, isOkAtPartonicLevel = false; + for (int ipa = 0; ipa < event.size(); ++ipa) { + + if(!isOkAtPartonicLevel){ + auto daughterList = event[ipa].daughterList(); + hasq = false; hasqbar = false; atSelectedY = false; + for (auto ida : daughterList) { + if (event[ida].id() == mPDG) + hasq = true; + if (event[ida].id() == -mPDG) + hasqbar = true; + if ((event[ida].y() > mRapidityMin) && (event[ida].y() < mRapidityMax)) + atSelectedY = true; + } + if (hasq && hasqbar && atSelectedY) isOkAtPartonicLevel = true; + } + + if( (mHadronMultiplicity <= 0) && isOkAtPartonicLevel) return true; // no selection at hadron level + + /// check at hadron level if needed + int ipdg=0; + for (auto& pdgVal : mHadronsPDGs){ + if ( (TMath::Abs(event[ipa].id()) == pdgVal) && (event[ipa].y() > mHadronRapidityMin) && (event[ipa].y() < mHadronRapidityMax) ) countH[ipdg]++; + if(isOkAtPartonicLevel && countH[ipdg] >= mHadronMultiplicity) return true; + ipdg++; + } + } + return false; + }; + + +private: +// Interface to override import particles +Pythia8::Event mOutputEvent; + + // Control gap-triggering + unsigned long long mGeneratedEvents; + int mInverseTriggerRatio; + Pythia8::Pythia pythiaMBgen; // minimum bias event + TString mConfigMBdecays; + int mPDG; + std::vector mHadronsPDGs; + int mHadronMultiplicity; + double mRapidityMin; + double mRapidityMax; + double mHadronRapidityMin; + double mHadronRapidityMax; + bool mVerbose; + }; + +} + +} + +// Predefined generators: +FairGenerator* + GeneratorBeautyToJpsi_EvtGenMidY_OO(double rapidityMin = -1.5, double rapidityMax = 1.5, bool verbose = false, TString pdgs = "511;521;531;541;5112;5122;5232;5132;5332") +{ + auto gen = new o2::eventgen::GeneratorEvtGen(); + gen->setRapidity(rapidityMin, rapidityMax); + gen->setPDG(5); + gen->setRapidityHadron(-1.5,1.5); + gen->setHadronMultiplicity(1); + TString pathO2table = gSystem->ExpandPathName("${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGDQ/pythia8/decayer/switchOffBhadrons.cfg"); + gen->readFile(pathO2table.Data()); + gen->setConfigMBdecays(pathO2table); + gen->setVerbose(verbose); + + std::string spdg; + TObjArray* obj = pdgs.Tokenize(";"); + gen->SetSizePdg(obj->GetEntriesFast()); + for (int i = 0; i < obj->GetEntriesFast(); i++) { + spdg = obj->At(i)->GetName(); + gen->AddPdg(std::stoi(spdg), i); + gen->addHadronPDGs(std::stoi(spdg)); + printf("PDG %d \n", std::stoi(spdg)); + } + gen->SetForceDecay(kEvtBJpsiDiElectron); + + // set random seed + gen->readString("Random:setSeed on"); + uint random_seed; + unsigned long long int random_value = 0; + ifstream urandom("/dev/urandom", ios::in|ios::binary); + urandom.read(reinterpret_cast(&random_value), sizeof(random_seed)); + gen->readString(Form("Random:seed = %d", random_value % 900000001)); + + // print debug + // gen->PrintDebug(); + + return gen; +} + +FairGenerator* + GeneratorBeautyToPsiAndJpsi_EvtGenMidY_OO(double rapidityMin = -1.5, double rapidityMax = 1.5, bool verbose = false, TString pdgs = "511;521;531;541;5112;5122;5232;5132;5332") +{ + auto gen = new o2::eventgen::GeneratorEvtGen(); + gen->setRapidity(rapidityMin, rapidityMax); + gen->setPDG(5); + gen->setRapidityHadron(rapidityMin,rapidityMax); + gen->setHadronMultiplicity(1); + TString pathO2table = gSystem->ExpandPathName("${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGDQ/pythia8/decayer/switchOffBhadrons.cfg"); + gen->readFile(pathO2table.Data()); + gen->setConfigMBdecays(pathO2table); + gen->setVerbose(verbose); + + std::string spdg; + TObjArray* obj = pdgs.Tokenize(";"); + gen->SetSizePdg(obj->GetEntriesFast()); + for (int i = 0; i < obj->GetEntriesFast(); i++) { + spdg = obj->At(i)->GetName(); + gen->AddPdg(std::stoi(spdg), i); + printf("PDG %d \n", std::stoi(spdg)); + gen->addHadronPDGs(std::stoi(spdg)); + } + gen->SetForceDecay(kEvtBPsiAndJpsiDiElectron); + + // set random seed + gen->readString("Random:setSeed on"); + uint random_seed; + unsigned long long int random_value = 0; + ifstream urandom("/dev/urandom", ios::in|ios::binary); + urandom.read(reinterpret_cast(&random_value), sizeof(random_seed)); + gen->readString(Form("Random:seed = %d", random_value % 900000001)); + + // print debug + // gen->PrintDebug(); + + return gen; +} + +// Predefined generators: +FairGenerator* + GeneratorBeautyToJpsi_EvtGenFwdY_OO(double rapidityMin = -4.3, double rapidityMax = -2.3, bool verbose = false, TString pdgs = "511;521;531;541;5112;5122;5232;5132;5332") +{ + auto gen = new o2::eventgen::GeneratorEvtGen(); + gen->setRapidity(rapidityMin, rapidityMax); + gen->setPDG(5); + gen->setRapidityHadron(rapidityMin,rapidityMax); + gen->setHadronMultiplicity(1); + TString pathO2table = gSystem->ExpandPathName("${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGDQ/pythia8/decayer/switchOffBhadrons.cfg"); + gen->readFile(pathO2table.Data()); + gen->setConfigMBdecays(pathO2table); + gen->setVerbose(verbose); + + std::string spdg; + TObjArray* obj = pdgs.Tokenize(";"); + gen->SetSizePdg(obj->GetEntriesFast()); + for (int i = 0; i < obj->GetEntriesFast(); i++) { + spdg = obj->At(i)->GetName(); + gen->AddPdg(std::stoi(spdg), i); + gen->addHadronPDGs(std::stoi(spdg)); + printf("PDG %d \n", std::stoi(spdg)); + } + gen->SetForceDecay(kEvtBJpsiDiMuon); + + // set random seed + gen->readString("Random:setSeed on"); + uint random_seed; + unsigned long long int random_value = 0; + ifstream urandom("/dev/urandom", ios::in|ios::binary); + urandom.read(reinterpret_cast(&random_value), sizeof(random_seed)); + gen->readString(Form("Random:seed = %d", random_value % 900000001)); + + // print debug + // gen->PrintDebug(); + + return gen; +} + + +FairGenerator* + GeneratorBeautyToPsiAndJpsi_EvtGenFwdY_OO(double rapidityMin = -4.3, double rapidityMax = -2.3, bool verbose = false, TString pdgs = "511;521;531;541;5112;5122;5232;5132;5332") +{ + auto gen = new o2::eventgen::GeneratorEvtGen(); + gen->setRapidity(rapidityMin, rapidityMax); + gen->setPDG(5); + gen->setRapidityHadron(rapidityMin,rapidityMax); + gen->setHadronMultiplicity(1); + TString pathO2table = gSystem->ExpandPathName("${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGDQ/pythia8/decayer/switchOffBhadrons.cfg"); + gen->readFile(pathO2table.Data()); + gen->setConfigMBdecays(pathO2table); + gen->setVerbose(verbose); + + std::string spdg; + TObjArray* obj = pdgs.Tokenize(";"); + gen->SetSizePdg(obj->GetEntriesFast()); + for (int i = 0; i < obj->GetEntriesFast(); i++) { + spdg = obj->At(i)->GetName(); + gen->AddPdg(std::stoi(spdg), i); + printf("PDG %d \n", std::stoi(spdg)); + gen->addHadronPDGs(std::stoi(spdg)); + } + gen->SetForceDecay(kEvtBPsiAndJpsiDiMuon); + + // set random seed + gen->readString("Random:setSeed on"); + uint random_seed; + unsigned long long int random_value = 0; + ifstream urandom("/dev/urandom", ios::in|ios::binary); + urandom.read(reinterpret_cast(&random_value), sizeof(random_seed)); + gen->readString(Form("Random:seed = %d", random_value % 900000001)); + + // print debug + // gen->PrintDebug(); + + return gen; +} + diff --git a/MC/config/PWGDQ/external/generator/generator_pythia8_NonPromptSignals_gaptriggered_dq.C b/MC/config/PWGDQ/external/generator/generator_pythia8_NonPromptSignals_gaptriggered_dq.C index eb26e89f3..b2050175b 100644 --- a/MC/config/PWGDQ/external/generator/generator_pythia8_NonPromptSignals_gaptriggered_dq.C +++ b/MC/config/PWGDQ/external/generator/generator_pythia8_NonPromptSignals_gaptriggered_dq.C @@ -351,3 +351,41 @@ FairGenerator* return gen; } +FairGenerator* + GeneratorBeautyToPsiToJpsi_EvtGenMidY(double rapidityMin = -1.5, double rapidityMax = 1.5, bool verbose = false, TString pdgs = "511;521;531;541;5112;5122;5232;5132;5332") +{ + auto gen = new o2::eventgen::GeneratorEvtGen(); + gen->setRapidity(rapidityMin, rapidityMax); + gen->setPDG(5); + gen->setRapidityHadron(rapidityMin,rapidityMax); + gen->setHadronMultiplicity(1); + TString pathO2table = gSystem->ExpandPathName("${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGDQ/pythia8/decayer/switchOffBhadrons.cfg"); + gen->readFile(pathO2table.Data()); + gen->setConfigMBdecays(pathO2table); + gen->setVerbose(verbose); + + std::string spdg; + TObjArray* obj = pdgs.Tokenize(";"); + gen->SetSizePdg(obj->GetEntriesFast()); + for (int i = 0; i < obj->GetEntriesFast(); i++) { + spdg = obj->At(i)->GetName(); + gen->AddPdg(std::stoi(spdg), i); + printf("PDG %d \n", std::stoi(spdg)); + gen->addHadronPDGs(std::stoi(spdg)); + } + gen->SetForceDecay(kEvtBtoPsi2SToJpsiPiPi); + + // set random seed + gen->readString("Random:setSeed on"); + uint random_seed; + unsigned long long int random_value = 0; + ifstream urandom("/dev/urandom", ios::in|ios::binary); + urandom.read(reinterpret_cast(&random_value), sizeof(random_seed)); + gen->readString(Form("Random:seed = %d", random_value % 900000001)); + + // print debug + // gen->PrintDebug(); + + return gen; +} + diff --git a/MC/config/PWGDQ/external/generator/generator_pythia8_NonPromptSignals_pO_gaptriggered_dq.C b/MC/config/PWGDQ/external/generator/generator_pythia8_NonPromptSignals_pO_gaptriggered_dq.C new file mode 100644 index 000000000..f4aab2fea --- /dev/null +++ b/MC/config/PWGDQ/external/generator/generator_pythia8_NonPromptSignals_pO_gaptriggered_dq.C @@ -0,0 +1,312 @@ +#include "FairGenerator.h" +#include "Generators/GeneratorPythia8.h" +#include "Pythia8/Pythia.h" +#include "TRandom.h" + +R__ADD_INCLUDE_PATH($O2DPG_MC_CONFIG_ROOT/MC/config/PWGDQ/EvtGen) +#include "GeneratorEvtGen.C" + +#include + +using namespace o2::eventgen; + +namespace o2 +{ +namespace eventgen +{ + +class GeneratorPythia8NonPromptInjectedpOGapTriggeredDQ : public o2::eventgen::GeneratorPythia8 { +public: + + /// constructor + GeneratorPythia8NonPromptInjectedpOGapTriggeredDQ(int inputTriggerRatio = 5) { + + mGeneratedEvents = 0; + mInverseTriggerRatio = inputTriggerRatio; + // define minimum bias event generator + auto seed = (gRandom->TRandom::GetSeed() % 900000000); + TString pathconfigMB = gSystem->ExpandPathName("${O2DPG_MC_CONFIG_ROOT}/MC/config/common/pythia8/generator/pythia8_pO_961.cfg"); + pythiaMBgen.readFile(pathconfigMB.Data()); + pythiaMBgen.readString("Random:setSeed on"); + pythiaMBgen.readString("Random:seed " + std::to_string(seed)); + mConfigMBdecays = ""; + mPDG = 5; + mRapidityMin = -1.; + mRapidityMax = 1.; + mHadronMultiplicity = -1; + mHadronRapidityMin = -1.; + mHadronRapidityMax = 1.; + mVerbose = false; + } + + /// Destructor + ~GeneratorPythia8NonPromptInjectedpOGapTriggeredDQ() = default; + + void setPDG(int val) { mPDG = val; }; + void addHadronPDGs(int pdg) { mHadronsPDGs.push_back(pdg); }; + void setHadronMultiplicity(int val) { mHadronMultiplicity = val; }; + void setRapidity(double valMin, double valMax) + { + mRapidityMin = valMin; + mRapidityMax = valMax; + }; + + void setRapidityHadron(double valMin, double valMax) + { + mHadronRapidityMin = valMin; + mHadronRapidityMax = valMax; + }; + + void setConfigMBdecays(TString val){mConfigMBdecays = val;} + + void setVerbose(bool val) { mVerbose = val; }; + +protected: + +Bool_t generateEvent() override + { + // reset event + bool genOk = false; + if (mGeneratedEvents % mInverseTriggerRatio == 0){ + bool ancestor = false; + while (! (genOk && ancestor) ){ + /// reset event + mPythia.event.reset(); + genOk = GeneratorPythia8::generateEvent(); + // find the q-qbar ancestor + ancestor = findHeavyQuarkPair(mPythia.event); + } + } else { + /// reset event + pythiaMBgen.event.reset(); + while (!genOk) { + genOk = pythiaMBgen.next(); + } + mPythia.event = pythiaMBgen.event; + } + mGeneratedEvents++; + if (mVerbose) mOutputEvent.list(); + return true; + } + +Bool_t Init() override + { + if(mConfigMBdecays.Contains("cfg")) pythiaMBgen.readFile(mConfigMBdecays.Data()); + GeneratorPythia8::Init(); + pythiaMBgen.init(); + return true; + } + + // search for q-qbar mother with at least one q in a selected rapidity window + bool findHeavyQuarkPair(Pythia8::Event& event) + { + int countH[mHadronsPDGs.size()]; for(int ipdg=0; ipdg < mHadronsPDGs.size(); ipdg++) countH[ipdg]=0; + bool hasq = false, hasqbar = false, atSelectedY = false, isOkAtPartonicLevel = false; + for (int ipa = 0; ipa < event.size(); ++ipa) { + + if(!isOkAtPartonicLevel){ + auto daughterList = event[ipa].daughterList(); + hasq = false; hasqbar = false; atSelectedY = false; + for (auto ida : daughterList) { + if (event[ida].id() == mPDG) + hasq = true; + if (event[ida].id() == -mPDG) + hasqbar = true; + if ((event[ida].y() > mRapidityMin) && (event[ida].y() < mRapidityMax)) + atSelectedY = true; + } + if (hasq && hasqbar && atSelectedY) isOkAtPartonicLevel = true; + } + + if( (mHadronMultiplicity <= 0) && isOkAtPartonicLevel) return true; // no selection at hadron level + + /// check at hadron level if needed + int ipdg=0; + for (auto& pdgVal : mHadronsPDGs){ + if ( (TMath::Abs(event[ipa].id()) == pdgVal) && (event[ipa].y() > mHadronRapidityMin) && (event[ipa].y() < mHadronRapidityMax) ) countH[ipdg]++; + if(isOkAtPartonicLevel && countH[ipdg] >= mHadronMultiplicity) return true; + ipdg++; + } + } + return false; + }; + + +private: +// Interface to override import particles +Pythia8::Event mOutputEvent; + + // Control gap-triggering + unsigned long long mGeneratedEvents; + int mInverseTriggerRatio; + Pythia8::Pythia pythiaMBgen; // minimum bias event + TString mConfigMBdecays; + int mPDG; + std::vector mHadronsPDGs; + int mHadronMultiplicity; + double mRapidityMin; + double mRapidityMax; + double mHadronRapidityMin; + double mHadronRapidityMax; + bool mVerbose; + }; + +} + +} + +// Predefined generators: +FairGenerator* + GeneratorBeautyToJpsi_EvtGenMidY_pO(double rapidityMin = -1.5, double rapidityMax = 1.5, bool verbose = false, TString pdgs = "511;521;531;541;5112;5122;5232;5132;5332") +{ + auto gen = new o2::eventgen::GeneratorEvtGen(); + gen->setRapidity(rapidityMin, rapidityMax); + gen->setPDG(5); + gen->setRapidityHadron(-1.5,1.5); + gen->setHadronMultiplicity(1); + TString pathO2table = gSystem->ExpandPathName("${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGDQ/pythia8/decayer/switchOffBhadrons.cfg"); + gen->readFile(pathO2table.Data()); + gen->setConfigMBdecays(pathO2table); + gen->setVerbose(verbose); + + std::string spdg; + TObjArray* obj = pdgs.Tokenize(";"); + gen->SetSizePdg(obj->GetEntriesFast()); + for (int i = 0; i < obj->GetEntriesFast(); i++) { + spdg = obj->At(i)->GetName(); + gen->AddPdg(std::stoi(spdg), i); + gen->addHadronPDGs(std::stoi(spdg)); + printf("PDG %d \n", std::stoi(spdg)); + } + gen->SetForceDecay(kEvtBJpsiDiElectron); + + // set random seed + gen->readString("Random:setSeed on"); + uint random_seed; + unsigned long long int random_value = 0; + ifstream urandom("/dev/urandom", ios::in|ios::binary); + urandom.read(reinterpret_cast(&random_value), sizeof(random_seed)); + gen->readString(Form("Random:seed = %d", random_value % 900000001)); + + // print debug + // gen->PrintDebug(); + + return gen; +} + +FairGenerator* + GeneratorBeautyToPsiAndJpsi_EvtGenMidY_pO(double rapidityMin = -1.5, double rapidityMax = 1.5, bool verbose = false, TString pdgs = "511;521;531;541;5112;5122;5232;5132;5332") +{ + auto gen = new o2::eventgen::GeneratorEvtGen(); + gen->setRapidity(rapidityMin, rapidityMax); + gen->setPDG(5); + gen->setRapidityHadron(rapidityMin,rapidityMax); + gen->setHadronMultiplicity(1); + TString pathO2table = gSystem->ExpandPathName("${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGDQ/pythia8/decayer/switchOffBhadrons.cfg"); + gen->readFile(pathO2table.Data()); + gen->setConfigMBdecays(pathO2table); + gen->setVerbose(verbose); + + std::string spdg; + TObjArray* obj = pdgs.Tokenize(";"); + gen->SetSizePdg(obj->GetEntriesFast()); + for (int i = 0; i < obj->GetEntriesFast(); i++) { + spdg = obj->At(i)->GetName(); + gen->AddPdg(std::stoi(spdg), i); + printf("PDG %d \n", std::stoi(spdg)); + gen->addHadronPDGs(std::stoi(spdg)); + } + gen->SetForceDecay(kEvtBPsiAndJpsiDiElectron); + + // set random seed + gen->readString("Random:setSeed on"); + uint random_seed; + unsigned long long int random_value = 0; + ifstream urandom("/dev/urandom", ios::in|ios::binary); + urandom.read(reinterpret_cast(&random_value), sizeof(random_seed)); + gen->readString(Form("Random:seed = %d", random_value % 900000001)); + + // print debug + // gen->PrintDebug(); + + return gen; +} + +// Predefined generators: +FairGenerator* + GeneratorBeautyToJpsi_EvtGenFwdY_pO(double rapidityMin = -4.3, double rapidityMax = -2.3, bool verbose = false, TString pdgs = "511;521;531;541;5112;5122;5232;5132;5332") +{ + auto gen = new o2::eventgen::GeneratorEvtGen(); + gen->setRapidity(rapidityMin, rapidityMax); + gen->setPDG(5); + gen->setRapidityHadron(rapidityMin,rapidityMax); + gen->setHadronMultiplicity(1); + TString pathO2table = gSystem->ExpandPathName("${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGDQ/pythia8/decayer/switchOffBhadrons.cfg"); + gen->readFile(pathO2table.Data()); + gen->setConfigMBdecays(pathO2table); + gen->setVerbose(verbose); + + std::string spdg; + TObjArray* obj = pdgs.Tokenize(";"); + gen->SetSizePdg(obj->GetEntriesFast()); + for (int i = 0; i < obj->GetEntriesFast(); i++) { + spdg = obj->At(i)->GetName(); + gen->AddPdg(std::stoi(spdg), i); + gen->addHadronPDGs(std::stoi(spdg)); + printf("PDG %d \n", std::stoi(spdg)); + } + gen->SetForceDecay(kEvtBJpsiDiMuon); + + // set random seed + gen->readString("Random:setSeed on"); + uint random_seed; + unsigned long long int random_value = 0; + ifstream urandom("/dev/urandom", ios::in|ios::binary); + urandom.read(reinterpret_cast(&random_value), sizeof(random_seed)); + gen->readString(Form("Random:seed = %d", random_value % 900000001)); + + // print debug + // gen->PrintDebug(); + + return gen; +} + + +FairGenerator* + GeneratorBeautyToPsiAndJpsi_EvtGenFwdY_pO(double rapidityMin = -4.3, double rapidityMax = -2.3, bool verbose = false, TString pdgs = "511;521;531;541;5112;5122;5232;5132;5332") +{ + auto gen = new o2::eventgen::GeneratorEvtGen(); + gen->setRapidity(rapidityMin, rapidityMax); + gen->setPDG(5); + gen->setRapidityHadron(rapidityMin,rapidityMax); + gen->setHadronMultiplicity(1); + TString pathO2table = gSystem->ExpandPathName("${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGDQ/pythia8/decayer/switchOffBhadrons.cfg"); + gen->readFile(pathO2table.Data()); + gen->setConfigMBdecays(pathO2table); + gen->setVerbose(verbose); + + std::string spdg; + TObjArray* obj = pdgs.Tokenize(";"); + gen->SetSizePdg(obj->GetEntriesFast()); + for (int i = 0; i < obj->GetEntriesFast(); i++) { + spdg = obj->At(i)->GetName(); + gen->AddPdg(std::stoi(spdg), i); + printf("PDG %d \n", std::stoi(spdg)); + gen->addHadronPDGs(std::stoi(spdg)); + } + gen->SetForceDecay(kEvtBPsiAndJpsiDiMuon); + + // set random seed + gen->readString("Random:setSeed on"); + uint random_seed; + unsigned long long int random_value = 0; + ifstream urandom("/dev/urandom", ios::in|ios::binary); + urandom.read(reinterpret_cast(&random_value), sizeof(random_seed)); + gen->readString(Form("Random:seed = %d", random_value % 900000001)); + + // print debug + // gen->PrintDebug(); + + return gen; +} + diff --git a/MC/config/PWGDQ/external/generator/generator_pythia8_withInjectedPromptSignals_gaptriggered_dq.C b/MC/config/PWGDQ/external/generator/generator_pythia8_withInjectedPromptSignals_gaptriggered_dq.C index c0d6bfd85..896bb7ed5 100644 --- a/MC/config/PWGDQ/external/generator/generator_pythia8_withInjectedPromptSignals_gaptriggered_dq.C +++ b/MC/config/PWGDQ/external/generator/generator_pythia8_withInjectedPromptSignals_gaptriggered_dq.C @@ -53,6 +53,18 @@ public: break; case 10: // generate cocktail of prompt X_1(3872) and psi2S to Jpsi pi pi at midrapidity mGeneratorParam = (Generator*)GeneratorCocktailX3872AndPsi2StoJpsi_pp13TeV(); + break; + case 11: // generate prompt charmonium at forward rapidity at 5TeV + mGeneratorParam = (Generator*)GeneratorCocktailPromptCharmoniaToMuonEvtGen_pp5TeV(); + break; + case 12: // generate prompt charmonia cocktail at mid rapidity at 5TeV + mGeneratorParam = (Generator*)GeneratorCocktailPromptCharmoniaToElectronEvtGen_pp5TeV(); + break; + case 13: // generate prompt charmonia cocktail at fwd rapidity at 9.6TeV + mGeneratorParam = (Generator*)GeneratorCocktailPromptCharmoniaToMuonEvtGen_pp96TeV(); + break; + case 14: // generate prompt charmonia cocktail at mid rapidity at 9.6TeV + mGeneratorParam = (Generator*)GeneratorCocktailPromptCharmoniaToElectronEvtGen_pp96TeV(); break; } mGeneratorParam->Init(); diff --git a/MC/config/PWGDQ/ini/GeneratorHF_bbbar_PsiAndJpsi_fwdy_triggerGap_OO5TeV.ini b/MC/config/PWGDQ/ini/GeneratorHF_bbbar_PsiAndJpsi_fwdy_triggerGap_OO5TeV.ini new file mode 100644 index 000000000..a76404bb9 --- /dev/null +++ b/MC/config/PWGDQ/ini/GeneratorHF_bbbar_PsiAndJpsi_fwdy_triggerGap_OO5TeV.ini @@ -0,0 +1,15 @@ +### The setup uses an external event generator +### This part sets the path of the file and the function call to retrieve it + +[GeneratorExternal] +fileName = ${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGDQ/external/generator/generator_pythia8_NonPromptSignals_OO_gaptriggered_dq.C +funcName = GeneratorBeautyToPsiAndJpsi_EvtGenFwdY_OO() + +### The external generator derives from GeneratorPythia8. +### This part configures the bits of the interface: configuration and user hooks + +[GeneratorPythia8] +config = ${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGDQ/pythia8/generator/pythia8_hf_OO_536.cfg +hooksFileName = ${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGHF/pythia8/hooks/pythia8_userhooks_qqbar.C +hooksFuncName = pythia8_userhooks_bbbar(-4.3,-2.3) + diff --git a/MC/config/PWGDQ/ini/GeneratorHF_bbbar_PsiAndJpsi_fwdy_triggerGap_pO96TeV.ini b/MC/config/PWGDQ/ini/GeneratorHF_bbbar_PsiAndJpsi_fwdy_triggerGap_pO96TeV.ini new file mode 100644 index 000000000..1e4c5b84e --- /dev/null +++ b/MC/config/PWGDQ/ini/GeneratorHF_bbbar_PsiAndJpsi_fwdy_triggerGap_pO96TeV.ini @@ -0,0 +1,15 @@ +### The setup uses an external event generator +### This part sets the path of the file and the function call to retrieve it + +[GeneratorExternal] +fileName = ${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGDQ/external/generator/generator_pythia8_NonPromptSignals_pO_gaptriggered_dq.C +funcName = GeneratorBeautyToPsiAndJpsi_EvtGenFwdY_pO() + +### The external generator derives from GeneratorPythia8. +### This part configures the bits of the interface: configuration and user hooks + +[GeneratorPythia8] +config = ${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGDQ/pythia8/generator/pythia8_hf_pO_961.cfg +hooksFileName = ${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGHF/pythia8/hooks/pythia8_userhooks_qqbar.C +hooksFuncName = pythia8_userhooks_bbbar(-4.3,-2.3) + diff --git a/MC/config/PWGDQ/ini/GeneratorHF_bbbar_PsiAndJpsi_midy_triggerGap_OO5TeV.ini b/MC/config/PWGDQ/ini/GeneratorHF_bbbar_PsiAndJpsi_midy_triggerGap_OO5TeV.ini new file mode 100644 index 000000000..8643e68d6 --- /dev/null +++ b/MC/config/PWGDQ/ini/GeneratorHF_bbbar_PsiAndJpsi_midy_triggerGap_OO5TeV.ini @@ -0,0 +1,15 @@ +### The setup uses an external event generator +### This part sets the path of the file and the function call to retrieve it + +[GeneratorExternal] +fileName = ${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGDQ/external/generator/generator_pythia8_NonPromptSignals_OO_gaptriggered_dq.C +funcName = GeneratorBeautyToPsiAndJpsi_EvtGenMidY_OO() + +### The external generator derives from GeneratorPythia8. +### This part configures the bits of the interface: configuration and user hooks + +[GeneratorPythia8] +config = ${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGDQ/pythia8/generator/pythia8_hf_OO_536.cfg +hooksFileName = ${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGHF/pythia8/hooks/pythia8_userhooks_qqbar.C +hooksFuncName = pythia8_userhooks_bbbar(-1.5,1.5) + diff --git a/MC/config/PWGDQ/ini/GeneratorHF_bbbar_PsiAndJpsi_midy_triggerGap_pO96TeV.ini b/MC/config/PWGDQ/ini/GeneratorHF_bbbar_PsiAndJpsi_midy_triggerGap_pO96TeV.ini new file mode 100644 index 000000000..ca57f2515 --- /dev/null +++ b/MC/config/PWGDQ/ini/GeneratorHF_bbbar_PsiAndJpsi_midy_triggerGap_pO96TeV.ini @@ -0,0 +1,15 @@ +### The setup uses an external event generator +### This part sets the path of the file and the function call to retrieve it + +[GeneratorExternal] +fileName = ${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGDQ/external/generator/generator_pythia8_NonPromptSignals_pO_gaptriggered_dq.C +funcName = GeneratorBeautyToPsiAndJpsi_EvtGenMidY_pO() + +### The external generator derives from GeneratorPythia8. +### This part configures the bits of the interface: configuration and user hooks + +[GeneratorPythia8] +config = ${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGDQ/pythia8/generator/pythia8_hf_pO_961.cfg +hooksFileName = ${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGHF/pythia8/hooks/pythia8_userhooks_qqbar.C +hooksFuncName = pythia8_userhooks_bbbar(-1.5,1.5) + diff --git a/MC/config/PWGDQ/ini/GeneratorHF_bbbar_PsiToJpsi_midy_triggerGap.ini b/MC/config/PWGDQ/ini/GeneratorHF_bbbar_PsiToJpsi_midy_triggerGap.ini new file mode 100644 index 000000000..a891cc8d1 --- /dev/null +++ b/MC/config/PWGDQ/ini/GeneratorHF_bbbar_PsiToJpsi_midy_triggerGap.ini @@ -0,0 +1,14 @@ +### The setup uses an external event generator +### This part sets the path of the file and the function call to retrieve it + +[GeneratorExternal] +fileName = ${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGDQ/external/generator/generator_pythia8_NonPromptSignals_gaptriggered_dq.C +funcName = GeneratorBeautyToPsiToJpsi_EvtGenMidY() + +### The external generator derives from GeneratorPythia8. +### This part configures the bits of the interface: configuration and user hooks + +[GeneratorPythia8] +config = ${O2DPG_MC_CONFIG_ROOT}/MC/config/common/pythia8/generator/pythia8_hf.cfg +hooksFileName = ${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGHF/pythia8/hooks/pythia8_userhooks_qqbar.C +hooksFuncName = pythia8_userhooks_bbbar(-1.5,1.5) \ No newline at end of file diff --git a/MC/config/PWGDQ/ini/Generator_InjectedCharmoniaMidy_PbPb5TeV.ini b/MC/config/PWGDQ/ini/Generator_InjectedCharmoniaMidy_PbPb5TeV.ini new file mode 100755 index 000000000..d3e0e5931 --- /dev/null +++ b/MC/config/PWGDQ/ini/Generator_InjectedCharmoniaMidy_PbPb5TeV.ini @@ -0,0 +1,7 @@ +### The external generator derives from GeneratorPythia8. +[GeneratorExternal] +fileName=${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGDQ/external/generator/generator_pythia8_HadronTriggered_PbPb.C +funcName=GeneratorPromptJpsiPsi2S_EvtGenMidY(1,-1,1,false) + +[GeneratorPythia8] +config=${O2DPG_MC_CONFIG_ROOT}/MC/config/ALICE3/pythia8/generator/pythia8_PbPb_536tev.cfg diff --git a/MC/config/PWGDQ/ini/Generator_InjectedInclusiveJpsiPsi2SMidy_2026_Pythia8_TriggerGap.ini b/MC/config/PWGDQ/ini/Generator_InjectedInclusiveJpsiPsi2SMidy_2026_Pythia8_TriggerGap.ini new file mode 100644 index 000000000..7843272c2 --- /dev/null +++ b/MC/config/PWGDQ/ini/Generator_InjectedInclusiveJpsiPsi2SMidy_2026_Pythia8_TriggerGap.ini @@ -0,0 +1,7 @@ +### The external generator derives from GeneratorPythia8. +[GeneratorExternal] +fileName=${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGDQ/external/generator/generator_pythia8_HadronTriggered_withGap.C +funcName=GeneratorInclusiveJpsiPsi2SChiC_EvtGenMidY(5,-1.5,1.5) + +[GeneratorPythia8] +config=${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGDQ/pythia8/generator/pythia8_inel_triggerGap.cfg diff --git a/MC/config/PWGDQ/ini/Generator_InjectedInclusiveJpsiPsi2SMidy_Pythia8_TriggerGap_pO96TeV.ini b/MC/config/PWGDQ/ini/Generator_InjectedInclusiveJpsiPsi2SMidy_Pythia8_TriggerGap_pO96TeV.ini new file mode 100644 index 000000000..c660aae24 --- /dev/null +++ b/MC/config/PWGDQ/ini/Generator_InjectedInclusiveJpsiPsi2SMidy_Pythia8_TriggerGap_pO96TeV.ini @@ -0,0 +1,7 @@ +### The external generator derives from GeneratorPythia8. +[GeneratorExternal] +fileName=${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGDQ/external/generator/generator_pythia8_HadronTriggered_withGap.C +funcName=GeneratorInclusiveJpsiPsi2S_EvtGenMidY(5,-1.5,1.5) + +[GeneratorPythia8] +config=${O2DPG_MC_CONFIG_ROOT}/MC/config/common/pythia8/generator/pythia8_pO_961.cfg diff --git a/MC/config/PWGDQ/ini/Generator_InjectedPromptCharmoniaFwdy_TriggerGap_NeNe5TeV.ini b/MC/config/PWGDQ/ini/Generator_InjectedPromptCharmoniaFwdy_TriggerGap_NeNe5TeV.ini new file mode 100644 index 000000000..3668ce8df --- /dev/null +++ b/MC/config/PWGDQ/ini/Generator_InjectedPromptCharmoniaFwdy_TriggerGap_NeNe5TeV.ini @@ -0,0 +1,7 @@ +### The external generator derives from GeneratorPythia8. +[GeneratorExternal] +fileName=${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGDQ/external/generator/generator_pythia8_withInjectedPromptSignals_gaptriggered_dq.C +funcName=GeneratorPythia8InjectedPromptCharmoniaGapTriggered(2,11) + +[GeneratorPythia8] +config=${O2DPG_MC_CONFIG_ROOT}/MC/config/common/pythia8/generator/pythia8_NeNe_536.cfg diff --git a/MC/config/PWGDQ/ini/Generator_InjectedPromptCharmoniaFwdy_TriggerGap_OO5TeV.ini b/MC/config/PWGDQ/ini/Generator_InjectedPromptCharmoniaFwdy_TriggerGap_OO5TeV.ini new file mode 100755 index 000000000..112685838 --- /dev/null +++ b/MC/config/PWGDQ/ini/Generator_InjectedPromptCharmoniaFwdy_TriggerGap_OO5TeV.ini @@ -0,0 +1,7 @@ +### The external generator derives from GeneratorPythia8. +[GeneratorExternal] +fileName=${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGDQ/external/generator/generator_pythia8_withInjectedPromptSignals_gaptriggered_dq.C +funcName=GeneratorPythia8InjectedPromptCharmoniaGapTriggered(5,11) + +[GeneratorPythia8] +config=${O2DPG_MC_CONFIG_ROOT}/MC/config/common/pythia8/generator/pythia8_OO_536.cfg diff --git a/MC/config/PWGDQ/ini/Generator_InjectedPromptCharmoniaFwdy_TriggerGap_PbPb5TeV.ini b/MC/config/PWGDQ/ini/Generator_InjectedPromptCharmoniaFwdy_TriggerGap_PbPb5TeV.ini index a7415ccf8..1a5877afe 100644 --- a/MC/config/PWGDQ/ini/Generator_InjectedPromptCharmoniaFwdy_TriggerGap_PbPb5TeV.ini +++ b/MC/config/PWGDQ/ini/Generator_InjectedPromptCharmoniaFwdy_TriggerGap_PbPb5TeV.ini @@ -4,4 +4,6 @@ fileName=${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGDQ/external/generator/generator_py funcName=GeneratorPythia8InjectedPromptCharmoniaGapTriggered(5,7) [GeneratorPythia8] -config=${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGDQ/pythia8/generator/pythia8_inel_triggerGap_5TeV.cfg \ No newline at end of file +### config=${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGDQ/pythia8/generator/pythia8_inel_triggerGap_5TeV.cfg +### config=${O2DPG_MC_CONFIG_ROOT}/MC/config/common/pythia8/generator/pythia8_hi.cfg +config=${O2DPG_MC_CONFIG_ROOT}/MC/config/ALICE3/pythia8/generator/pythia8_PbPb_536tev.cfg diff --git a/MC/config/PWGDQ/ini/Generator_InjectedPromptCharmoniaFwdy_TriggerGap_PbPb5TeV_TriggerRatio2.ini b/MC/config/PWGDQ/ini/Generator_InjectedPromptCharmoniaFwdy_TriggerGap_PbPb5TeV_TriggerRatio2.ini new file mode 100644 index 000000000..d3611a518 --- /dev/null +++ b/MC/config/PWGDQ/ini/Generator_InjectedPromptCharmoniaFwdy_TriggerGap_PbPb5TeV_TriggerRatio2.ini @@ -0,0 +1,9 @@ +### The external generator derives from GeneratorPythia8. +[GeneratorExternal] +fileName=${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGDQ/external/generator/generator_pythia8_withInjectedPromptSignals_gaptriggered_dq.C +funcName=GeneratorPythia8InjectedPromptCharmoniaGapTriggered(2,7) + +[GeneratorPythia8] +### config=${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGDQ/pythia8/generator/pythia8_inel_triggerGap_5TeV.cfg +### config=${O2DPG_MC_CONFIG_ROOT}/MC/config/common/pythia8/generator/pythia8_hi.cfg +config=${O2DPG_MC_CONFIG_ROOT}/MC/config/ALICE3/pythia8/generator/pythia8_PbPb_536tev.cfg diff --git a/MC/config/PWGDQ/ini/Generator_InjectedPromptCharmoniaFwdy_TriggerGap_pO96TeV.ini b/MC/config/PWGDQ/ini/Generator_InjectedPromptCharmoniaFwdy_TriggerGap_pO96TeV.ini new file mode 100755 index 000000000..b4822ef37 --- /dev/null +++ b/MC/config/PWGDQ/ini/Generator_InjectedPromptCharmoniaFwdy_TriggerGap_pO96TeV.ini @@ -0,0 +1,7 @@ +### The external generator derives from GeneratorPythia8. +[GeneratorExternal] +fileName=${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGDQ/external/generator/generator_pythia8_withInjectedPromptSignals_gaptriggered_dq.C +funcName=GeneratorPythia8InjectedPromptCharmoniaGapTriggered(5,13) + +[GeneratorPythia8] +config=${O2DPG_MC_CONFIG_ROOT}/MC/config/common/pythia8/generator/pythia8_pO_961.cfg diff --git a/MC/config/PWGDQ/ini/Generator_InjectedPromptCharmoniaFwdy_TriggerGap_pp5TeV.ini b/MC/config/PWGDQ/ini/Generator_InjectedPromptCharmoniaFwdy_TriggerGap_pp5TeV.ini new file mode 100755 index 000000000..50de50adb --- /dev/null +++ b/MC/config/PWGDQ/ini/Generator_InjectedPromptCharmoniaFwdy_TriggerGap_pp5TeV.ini @@ -0,0 +1,7 @@ +### The external generator derives from GeneratorPythia8. +[GeneratorExternal] +fileName=${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGDQ/external/generator/generator_pythia8_withInjectedPromptSignals_gaptriggered_dq.C +funcName=GeneratorPythia8InjectedPromptCharmoniaGapTriggered(5,11) + +[GeneratorPythia8] +config=${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGDQ/pythia8/generator/pythia8_inel_triggerGap_5TeV.cfg diff --git a/MC/config/PWGDQ/ini/Generator_InjectedPromptCharmoniaMidy_TriggerGap_2_OO5TeV.ini b/MC/config/PWGDQ/ini/Generator_InjectedPromptCharmoniaMidy_TriggerGap_2_OO5TeV.ini new file mode 100644 index 000000000..21ba911d3 --- /dev/null +++ b/MC/config/PWGDQ/ini/Generator_InjectedPromptCharmoniaMidy_TriggerGap_2_OO5TeV.ini @@ -0,0 +1,7 @@ +### The external generator derives from GeneratorPythia8. +[GeneratorExternal] +fileName=${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGDQ/external/generator/generator_pythia8_withInjectedPromptSignals_gaptriggered_dq.C +funcName=GeneratorPythia8InjectedPromptCharmoniaGapTriggered(2,12) + +[GeneratorPythia8] +config=${O2DPG_MC_CONFIG_ROOT}/MC/config/common/pythia8/generator/pythia8_OO_536.cfg diff --git a/MC/config/PWGDQ/ini/Generator_InjectedPromptCharmoniaMidy_TriggerGap_OO5TeV.ini b/MC/config/PWGDQ/ini/Generator_InjectedPromptCharmoniaMidy_TriggerGap_OO5TeV.ini new file mode 100644 index 000000000..c8c6d2ee4 --- /dev/null +++ b/MC/config/PWGDQ/ini/Generator_InjectedPromptCharmoniaMidy_TriggerGap_OO5TeV.ini @@ -0,0 +1,7 @@ +### The external generator derives from GeneratorPythia8. +[GeneratorExternal] +fileName=${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGDQ/external/generator/generator_pythia8_withInjectedPromptSignals_gaptriggered_dq.C +funcName=GeneratorPythia8InjectedPromptCharmoniaGapTriggered(5,12) + +[GeneratorPythia8] +config=${O2DPG_MC_CONFIG_ROOT}/MC/config/common/pythia8/generator/pythia8_OO_536.cfg diff --git a/MC/config/PWGDQ/ini/Generator_InjectedPromptCharmoniaMidy_TriggerGap_pO96TeV.ini b/MC/config/PWGDQ/ini/Generator_InjectedPromptCharmoniaMidy_TriggerGap_pO96TeV.ini new file mode 100644 index 000000000..0f184d019 --- /dev/null +++ b/MC/config/PWGDQ/ini/Generator_InjectedPromptCharmoniaMidy_TriggerGap_pO96TeV.ini @@ -0,0 +1,7 @@ +### The external generator derives from GeneratorPythia8. +[GeneratorExternal] +fileName=${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGDQ/external/generator/generator_pythia8_withInjectedPromptSignals_gaptriggered_dq.C +funcName=GeneratorPythia8InjectedPromptCharmoniaGapTriggered(5,14) + +[GeneratorPythia8] +config=${O2DPG_MC_CONFIG_ROOT}/MC/config/common/pythia8/generator/pythia8_pO_961.cfg diff --git a/MC/config/PWGDQ/ini/Generator_InjectedPromptJpsiFwdy_PythiaOnia_TriggerGap_pp5TeV.ini b/MC/config/PWGDQ/ini/Generator_InjectedPromptJpsiFwdy_PythiaOnia_TriggerGap_pp5TeV.ini new file mode 100644 index 000000000..751e1cf68 --- /dev/null +++ b/MC/config/PWGDQ/ini/Generator_InjectedPromptJpsiFwdy_PythiaOnia_TriggerGap_pp5TeV.ini @@ -0,0 +1,7 @@ +### The external generator derives from GeneratorPythia8. +[GeneratorExternal] +fileName=${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGDQ/external/generator/generator_pythia8Onia_PromptSignals_gaptriggered.C +funcName=GeneratorPromptJpsi_EvtGenFwdy(5,-4.3,-2.3) + +[GeneratorPythia8] +config=${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGDQ/pythia8/generator/pythia8_onia_triggerGap_pp5TeV.cfg diff --git a/MC/config/PWGDQ/ini/Generator_InjectedPromptJpsiPsi2SFwdy_Pythia8_TriggerGap_pp5TeV.ini b/MC/config/PWGDQ/ini/Generator_InjectedPromptJpsiPsi2SFwdy_Pythia8_TriggerGap_pp5TeV.ini new file mode 100644 index 000000000..a653d7ba1 --- /dev/null +++ b/MC/config/PWGDQ/ini/Generator_InjectedPromptJpsiPsi2SFwdy_Pythia8_TriggerGap_pp5TeV.ini @@ -0,0 +1,7 @@ +### The external generator derives from GeneratorPythia8. +[GeneratorExternal] +fileName=${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGDQ/external/generator/generator_pythia8Onia_PromptSignals_gaptriggered.C +funcName=GeneratorPromptJpsiPsi2S_EvtGenFwdY(5,-4.3,-2.3) + +[GeneratorPythia8] +config=${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGDQ/pythia8/generator/pythia8_onia_triggerGap_pp5TeV.cfg diff --git a/MC/config/PWGDQ/ini/tests/GeneratorHF_bbbar_PsiAndJpsi_fwdy_triggerGap_OO5TeV.C b/MC/config/PWGDQ/ini/tests/GeneratorHF_bbbar_PsiAndJpsi_fwdy_triggerGap_OO5TeV.C new file mode 100644 index 000000000..d68eb1bcf --- /dev/null +++ b/MC/config/PWGDQ/ini/tests/GeneratorHF_bbbar_PsiAndJpsi_fwdy_triggerGap_OO5TeV.C @@ -0,0 +1,93 @@ +int External() +{ + int checkPdgSignal[] = {443,100443}; + int checkPdgDecay = 13; + double rapiditymin = -4.3; double rapiditymax = -2.3; + std::string path{"o2sim_Kine.root"}; + std::cout << "Check for\nsignal PDG " << checkPdgSignal << "\ndecay PDG " << checkPdgDecay << "\n"; + TFile file(path.c_str(), "READ"); + if (file.IsZombie()) { + std::cerr << "Cannot open ROOT file " << path << "\n"; + return 1; + } + + auto tree = (TTree*)file.Get("o2sim"); + std::vector* tracks{}; + tree->SetBranchAddress("MCTrack", &tracks); + + int nLeptons{}; + int nAntileptons{}; + int nLeptonPairs{}; + int nLeptonPairsToBeDone{}; + int nSignalJpsi{}; + int nSignalPsi2S{}; + int nSignalJpsiWithinAcc{}; + int nSignalPsi2SWithinAcc{}; + auto nEvents = tree->GetEntries(); + o2::steer::MCKinematicsReader mcreader("o2sim", o2::steer::MCKinematicsReader::Mode::kMCKine); + Int_t bpdgs[] = {511, 521, 531, 5112, 5122, 5232, 5132}; + Int_t sizePdg = sizeof(bpdgs)/sizeof(Int_t); + Bool_t hasBeautyMoth = kFALSE; + + for (int i = 0; i < nEvents; i++) { + tree->GetEntry(i); + for (auto& track : *tracks) { + auto pdg = track.GetPdgCode(); + auto rapidity = track.GetRapidity(); + auto idMoth = track.getMotherTrackId(); + if (pdg == checkPdgDecay) { + // count leptons + nLeptons++; + } else if(pdg == -checkPdgDecay) { + // count anti-leptons + nAntileptons++; + } else if (pdg == checkPdgSignal[0] || pdg == checkPdgSignal[1]) { + // check if mothers are beauty hadrons + hasBeautyMoth = kFALSE; + if(idMoth){ // check beauty mother + auto tdM = mcreader.getTrack(i, idMoth); + for(int i=0; iGetPdgCode()) == bpdgs[i] ) hasBeautyMoth = kTRUE; } + } + if(hasBeautyMoth){ + // count signal PDG + pdg == checkPdgSignal[0] ? nSignalJpsi++ : nSignalPsi2S++; + // count signal PDG within acceptance + if(rapidity > rapiditymin && rapidity < rapiditymax) { pdg == checkPdgSignal[0] ? nSignalJpsiWithinAcc++ : nSignalPsi2SWithinAcc++;} + } + auto child0 = o2::mcutils::MCTrackNavigator::getDaughter0(track, *tracks); + auto child1 = o2::mcutils::MCTrackNavigator::getDaughter1(track, *tracks); + if (child0 != nullptr && child1 != nullptr) { + // check for parent-child relations + auto pdg0 = child0->GetPdgCode(); + auto pdg1 = child1->GetPdgCode(); + std::cout << "First and last children of parent " << checkPdgSignal << " are PDG0: " << pdg0 << " PDG1: " << pdg1 << "\n"; + if (std::abs(pdg0) == checkPdgDecay && std::abs(pdg1) == checkPdgDecay && pdg0 == -pdg1) { + nLeptonPairs++; + if (child0->getToBeDone() && child1->getToBeDone()) { + nLeptonPairsToBeDone++; + } + } + } + } + } + } + std::cout << "#events: " << nEvents << "\n" + << "#leptons: " << nLeptons << "\n" + << "#antileptons: " << nAntileptons << "\n" + << "#signal (jpsi <- b): " << nSignalJpsi << "; within acceptance " << rapiditymin << " < y < " << rapiditymax << " : " << nSignalJpsiWithinAcc << "\n" + << "#signal (psi2S <- b): " << nSignalPsi2S << "; within acceptance " << rapiditymin << " < y < " << rapiditymax << " : " << nSignalPsi2SWithinAcc << "\n" + << "#lepton pairs: " << nLeptonPairs << "\n" + << "#lepton pairs to be done: " << nLeptonPairs << "\n"; + + + if (nLeptonPairs == 0 || nLeptons == 0 || nAntileptons == 0) { + std::cerr << "Number of leptons, number of anti-leptons as well as number of lepton pairs should all be greater than 1.\n"; + return 1; + } + if (nLeptonPairs != nLeptonPairsToBeDone) { + std::cerr << "The number of lepton pairs should be the same as the number of lepton pairs which should be transported.\n"; + return 1; + } + + return 0; +} diff --git a/MC/config/PWGDQ/ini/tests/GeneratorHF_bbbar_PsiAndJpsi_fwdy_triggerGap_pO96TeV.C b/MC/config/PWGDQ/ini/tests/GeneratorHF_bbbar_PsiAndJpsi_fwdy_triggerGap_pO96TeV.C new file mode 100644 index 000000000..d68eb1bcf --- /dev/null +++ b/MC/config/PWGDQ/ini/tests/GeneratorHF_bbbar_PsiAndJpsi_fwdy_triggerGap_pO96TeV.C @@ -0,0 +1,93 @@ +int External() +{ + int checkPdgSignal[] = {443,100443}; + int checkPdgDecay = 13; + double rapiditymin = -4.3; double rapiditymax = -2.3; + std::string path{"o2sim_Kine.root"}; + std::cout << "Check for\nsignal PDG " << checkPdgSignal << "\ndecay PDG " << checkPdgDecay << "\n"; + TFile file(path.c_str(), "READ"); + if (file.IsZombie()) { + std::cerr << "Cannot open ROOT file " << path << "\n"; + return 1; + } + + auto tree = (TTree*)file.Get("o2sim"); + std::vector* tracks{}; + tree->SetBranchAddress("MCTrack", &tracks); + + int nLeptons{}; + int nAntileptons{}; + int nLeptonPairs{}; + int nLeptonPairsToBeDone{}; + int nSignalJpsi{}; + int nSignalPsi2S{}; + int nSignalJpsiWithinAcc{}; + int nSignalPsi2SWithinAcc{}; + auto nEvents = tree->GetEntries(); + o2::steer::MCKinematicsReader mcreader("o2sim", o2::steer::MCKinematicsReader::Mode::kMCKine); + Int_t bpdgs[] = {511, 521, 531, 5112, 5122, 5232, 5132}; + Int_t sizePdg = sizeof(bpdgs)/sizeof(Int_t); + Bool_t hasBeautyMoth = kFALSE; + + for (int i = 0; i < nEvents; i++) { + tree->GetEntry(i); + for (auto& track : *tracks) { + auto pdg = track.GetPdgCode(); + auto rapidity = track.GetRapidity(); + auto idMoth = track.getMotherTrackId(); + if (pdg == checkPdgDecay) { + // count leptons + nLeptons++; + } else if(pdg == -checkPdgDecay) { + // count anti-leptons + nAntileptons++; + } else if (pdg == checkPdgSignal[0] || pdg == checkPdgSignal[1]) { + // check if mothers are beauty hadrons + hasBeautyMoth = kFALSE; + if(idMoth){ // check beauty mother + auto tdM = mcreader.getTrack(i, idMoth); + for(int i=0; iGetPdgCode()) == bpdgs[i] ) hasBeautyMoth = kTRUE; } + } + if(hasBeautyMoth){ + // count signal PDG + pdg == checkPdgSignal[0] ? nSignalJpsi++ : nSignalPsi2S++; + // count signal PDG within acceptance + if(rapidity > rapiditymin && rapidity < rapiditymax) { pdg == checkPdgSignal[0] ? nSignalJpsiWithinAcc++ : nSignalPsi2SWithinAcc++;} + } + auto child0 = o2::mcutils::MCTrackNavigator::getDaughter0(track, *tracks); + auto child1 = o2::mcutils::MCTrackNavigator::getDaughter1(track, *tracks); + if (child0 != nullptr && child1 != nullptr) { + // check for parent-child relations + auto pdg0 = child0->GetPdgCode(); + auto pdg1 = child1->GetPdgCode(); + std::cout << "First and last children of parent " << checkPdgSignal << " are PDG0: " << pdg0 << " PDG1: " << pdg1 << "\n"; + if (std::abs(pdg0) == checkPdgDecay && std::abs(pdg1) == checkPdgDecay && pdg0 == -pdg1) { + nLeptonPairs++; + if (child0->getToBeDone() && child1->getToBeDone()) { + nLeptonPairsToBeDone++; + } + } + } + } + } + } + std::cout << "#events: " << nEvents << "\n" + << "#leptons: " << nLeptons << "\n" + << "#antileptons: " << nAntileptons << "\n" + << "#signal (jpsi <- b): " << nSignalJpsi << "; within acceptance " << rapiditymin << " < y < " << rapiditymax << " : " << nSignalJpsiWithinAcc << "\n" + << "#signal (psi2S <- b): " << nSignalPsi2S << "; within acceptance " << rapiditymin << " < y < " << rapiditymax << " : " << nSignalPsi2SWithinAcc << "\n" + << "#lepton pairs: " << nLeptonPairs << "\n" + << "#lepton pairs to be done: " << nLeptonPairs << "\n"; + + + if (nLeptonPairs == 0 || nLeptons == 0 || nAntileptons == 0) { + std::cerr << "Number of leptons, number of anti-leptons as well as number of lepton pairs should all be greater than 1.\n"; + return 1; + } + if (nLeptonPairs != nLeptonPairsToBeDone) { + std::cerr << "The number of lepton pairs should be the same as the number of lepton pairs which should be transported.\n"; + return 1; + } + + return 0; +} diff --git a/MC/config/PWGDQ/ini/tests/GeneratorHF_bbbar_PsiAndJpsi_midy_triggerGap_OO5TeV.C b/MC/config/PWGDQ/ini/tests/GeneratorHF_bbbar_PsiAndJpsi_midy_triggerGap_OO5TeV.C new file mode 100644 index 000000000..8a0964910 --- /dev/null +++ b/MC/config/PWGDQ/ini/tests/GeneratorHF_bbbar_PsiAndJpsi_midy_triggerGap_OO5TeV.C @@ -0,0 +1,92 @@ +int External() +{ + int checkPdgSignal[] = {443,100443}; + int checkPdgDecay = 11; + std::string path{"o2sim_Kine.root"}; + std::cout << "Check for\nsignal PDG " << checkPdgSignal << "\ndecay PDG " << checkPdgDecay << "\n"; + TFile file(path.c_str(), "READ"); + if (file.IsZombie()) { + std::cerr << "Cannot open ROOT file " << path << "\n"; + return 1; + } + + auto tree = (TTree*)file.Get("o2sim"); + std::vector* tracks{}; + tree->SetBranchAddress("MCTrack", &tracks); + + int nLeptons{}; + int nAntileptons{}; + int nLeptonPairs{}; + int nLeptonPairsToBeDone{}; + int nSignalJpsi{}; + int nSignalPsi2S{}; + int nSignalJpsiWithinAcc{}; + int nSignalPsi2SWithinAcc{}; + auto nEvents = tree->GetEntries(); + o2::steer::MCKinematicsReader mcreader("o2sim", o2::steer::MCKinematicsReader::Mode::kMCKine); + Int_t bpdgs[] = {511, 521, 531, 5112, 5122, 5232, 5132}; + Int_t sizePdg = sizeof(bpdgs)/sizeof(Int_t); + Bool_t hasBeautyMoth = kFALSE; + + for (int i = 0; i < nEvents; i++) { + tree->GetEntry(i); + for (auto& track : *tracks) { + auto pdg = track.GetPdgCode(); + auto rapidity = track.GetRapidity(); + auto idMoth = track.getMotherTrackId(); + if (pdg == checkPdgDecay) { + // count leptons + nLeptons++; + } else if(pdg == -checkPdgDecay) { + // count anti-leptons + nAntileptons++; + } else if (pdg == checkPdgSignal[0] || pdg == checkPdgSignal[1]) { + // check if mothers are beauty hadrons + hasBeautyMoth = kFALSE; + if(idMoth){ // check beauty mother + auto tdM = mcreader.getTrack(i, idMoth); + for(int i=0; iGetPdgCode()) == bpdgs[i] ) hasBeautyMoth = kTRUE; } + } + if(hasBeautyMoth){ + // count signal PDG + pdg == checkPdgSignal[0] ? nSignalJpsi++ : nSignalPsi2S++; + // count signal PDG within acceptance + if(std::abs(rapidity) < 1.0) { pdg == checkPdgSignal[0] ? nSignalJpsiWithinAcc++ : nSignalPsi2SWithinAcc++;} + } + auto child0 = o2::mcutils::MCTrackNavigator::getDaughter0(track, *tracks); + auto child1 = o2::mcutils::MCTrackNavigator::getDaughter1(track, *tracks); + if (child0 != nullptr && child1 != nullptr) { + // check for parent-child relations + auto pdg0 = child0->GetPdgCode(); + auto pdg1 = child1->GetPdgCode(); + std::cout << "First and last children of parent " << checkPdgSignal << " are PDG0: " << pdg0 << " PDG1: " << pdg1 << "\n"; + if (std::abs(pdg0) == checkPdgDecay && std::abs(pdg1) == checkPdgDecay && pdg0 == -pdg1) { + nLeptonPairs++; + if (child0->getToBeDone() && child1->getToBeDone()) { + nLeptonPairsToBeDone++; + } + } + } + } + } + } + std::cout << "#events: " << nEvents << "\n" + << "#leptons: " << nLeptons << "\n" + << "#antileptons: " << nAntileptons << "\n" + << "#signal (jpsi <- b): " << nSignalJpsi << "; within acceptance (|y| < 1): " << nSignalJpsiWithinAcc << "\n" + << "#signal (psi2S <- b): " << nSignalPsi2S << "; within acceptance (|y| < 1): " << nSignalPsi2SWithinAcc << "\n" + << "#lepton pairs: " << nLeptonPairs << "\n" + << "#lepton pairs to be done: " << nLeptonPairs << "\n"; + + + if (nLeptonPairs == 0 || nLeptons == 0 || nAntileptons == 0) { + std::cerr << "Number of leptons, number of anti-leptons as well as number of lepton pairs should all be greater than 1.\n"; + return 1; + } + if (nLeptonPairs != nLeptonPairsToBeDone) { + std::cerr << "The number of lepton pairs should be the same as the number of lepton pairs which should be transported.\n"; + return 1; + } + + return 0; +} diff --git a/MC/config/PWGDQ/ini/tests/GeneratorHF_bbbar_PsiAndJpsi_midy_triggerGap_pO96TeV.C b/MC/config/PWGDQ/ini/tests/GeneratorHF_bbbar_PsiAndJpsi_midy_triggerGap_pO96TeV.C new file mode 100644 index 000000000..8a0964910 --- /dev/null +++ b/MC/config/PWGDQ/ini/tests/GeneratorHF_bbbar_PsiAndJpsi_midy_triggerGap_pO96TeV.C @@ -0,0 +1,92 @@ +int External() +{ + int checkPdgSignal[] = {443,100443}; + int checkPdgDecay = 11; + std::string path{"o2sim_Kine.root"}; + std::cout << "Check for\nsignal PDG " << checkPdgSignal << "\ndecay PDG " << checkPdgDecay << "\n"; + TFile file(path.c_str(), "READ"); + if (file.IsZombie()) { + std::cerr << "Cannot open ROOT file " << path << "\n"; + return 1; + } + + auto tree = (TTree*)file.Get("o2sim"); + std::vector* tracks{}; + tree->SetBranchAddress("MCTrack", &tracks); + + int nLeptons{}; + int nAntileptons{}; + int nLeptonPairs{}; + int nLeptonPairsToBeDone{}; + int nSignalJpsi{}; + int nSignalPsi2S{}; + int nSignalJpsiWithinAcc{}; + int nSignalPsi2SWithinAcc{}; + auto nEvents = tree->GetEntries(); + o2::steer::MCKinematicsReader mcreader("o2sim", o2::steer::MCKinematicsReader::Mode::kMCKine); + Int_t bpdgs[] = {511, 521, 531, 5112, 5122, 5232, 5132}; + Int_t sizePdg = sizeof(bpdgs)/sizeof(Int_t); + Bool_t hasBeautyMoth = kFALSE; + + for (int i = 0; i < nEvents; i++) { + tree->GetEntry(i); + for (auto& track : *tracks) { + auto pdg = track.GetPdgCode(); + auto rapidity = track.GetRapidity(); + auto idMoth = track.getMotherTrackId(); + if (pdg == checkPdgDecay) { + // count leptons + nLeptons++; + } else if(pdg == -checkPdgDecay) { + // count anti-leptons + nAntileptons++; + } else if (pdg == checkPdgSignal[0] || pdg == checkPdgSignal[1]) { + // check if mothers are beauty hadrons + hasBeautyMoth = kFALSE; + if(idMoth){ // check beauty mother + auto tdM = mcreader.getTrack(i, idMoth); + for(int i=0; iGetPdgCode()) == bpdgs[i] ) hasBeautyMoth = kTRUE; } + } + if(hasBeautyMoth){ + // count signal PDG + pdg == checkPdgSignal[0] ? nSignalJpsi++ : nSignalPsi2S++; + // count signal PDG within acceptance + if(std::abs(rapidity) < 1.0) { pdg == checkPdgSignal[0] ? nSignalJpsiWithinAcc++ : nSignalPsi2SWithinAcc++;} + } + auto child0 = o2::mcutils::MCTrackNavigator::getDaughter0(track, *tracks); + auto child1 = o2::mcutils::MCTrackNavigator::getDaughter1(track, *tracks); + if (child0 != nullptr && child1 != nullptr) { + // check for parent-child relations + auto pdg0 = child0->GetPdgCode(); + auto pdg1 = child1->GetPdgCode(); + std::cout << "First and last children of parent " << checkPdgSignal << " are PDG0: " << pdg0 << " PDG1: " << pdg1 << "\n"; + if (std::abs(pdg0) == checkPdgDecay && std::abs(pdg1) == checkPdgDecay && pdg0 == -pdg1) { + nLeptonPairs++; + if (child0->getToBeDone() && child1->getToBeDone()) { + nLeptonPairsToBeDone++; + } + } + } + } + } + } + std::cout << "#events: " << nEvents << "\n" + << "#leptons: " << nLeptons << "\n" + << "#antileptons: " << nAntileptons << "\n" + << "#signal (jpsi <- b): " << nSignalJpsi << "; within acceptance (|y| < 1): " << nSignalJpsiWithinAcc << "\n" + << "#signal (psi2S <- b): " << nSignalPsi2S << "; within acceptance (|y| < 1): " << nSignalPsi2SWithinAcc << "\n" + << "#lepton pairs: " << nLeptonPairs << "\n" + << "#lepton pairs to be done: " << nLeptonPairs << "\n"; + + + if (nLeptonPairs == 0 || nLeptons == 0 || nAntileptons == 0) { + std::cerr << "Number of leptons, number of anti-leptons as well as number of lepton pairs should all be greater than 1.\n"; + return 1; + } + if (nLeptonPairs != nLeptonPairsToBeDone) { + std::cerr << "The number of lepton pairs should be the same as the number of lepton pairs which should be transported.\n"; + return 1; + } + + return 0; +} diff --git a/MC/config/PWGDQ/ini/tests/GeneratorHF_bbbar_PsiToJpsi_midy_triggerGap.C b/MC/config/PWGDQ/ini/tests/GeneratorHF_bbbar_PsiToJpsi_midy_triggerGap.C new file mode 100644 index 000000000..5c50cd1af --- /dev/null +++ b/MC/config/PWGDQ/ini/tests/GeneratorHF_bbbar_PsiToJpsi_midy_triggerGap.C @@ -0,0 +1,104 @@ +int External() +{ + int checkPdgSignal[] = {100443}; + int checkPdgDecay[] = {443, 211, -211}; + int leptonPdg = 11; + Double_t rapidityWindow = 1.0; + std::string path{"o2sim_Kine.root"}; + std::cout << "Check for\nsignal PDG " << checkPdgSignal[0] << "\n decay PDG " << checkPdgDecay[0] << ", " << checkPdgDecay[1] << ", " << checkPdgDecay[2] << "\n"; + TFile file(path.c_str(), "READ"); + if (file.IsZombie()) { + std::cerr << "Cannot open ROOT file " << path << "\n"; + return 1; + } + auto tree = (TTree*)file.Get("o2sim"); + std::vector* tracks{}; + tree->SetBranchAddress("MCTrack", &tracks); + + int nLeptons{}; + int nAntileptons{}; + int nLeptonPairs{}; + int nLeptonPairsToBeDone{}; + int nSignalJpsi{}; + int nSignalPionsPos{}; + int nSignalPionsNeg{}; + int nSignalPsi2S{}; + int nSignalJpsiWithinAcc{}; + int nSignalPionsPosWithinAcc{}; + int nSignalPionsNegWithinAcc{}; + auto nEvents = tree->GetEntries(); + o2::steer::MCKinematicsReader mcreader("o2sim", o2::steer::MCKinematicsReader::Mode::kMCKine); + Int_t bpdgs[] = {511, 521, 531, 5112, 5122, 5232, 5132}; + Int_t sizePdg = sizeof(bpdgs)/sizeof(Int_t); + Bool_t hasBeautyMoth = kFALSE; + + for (int i = 0; i < nEvents; i++) { + tree->GetEntry(i); + for (auto& track : *tracks) { + auto pdg = track.GetPdgCode(); + auto rapidity = track.GetRapidity(); + auto idMoth = track.getMotherTrackId(); + int idJpsi = -1; int IdChild0 = -1; int IdChild1 = -1; + if (pdg == leptonPdg) { + // count leptons + nLeptons++; + } else if(pdg == -leptonPdg) { + // count anti-leptons + nAntileptons++; + } else if (pdg == checkPdgSignal[0]) { + hasBeautyMoth = kFALSE; + if(idMoth){ // check beauty mother + auto tdM = mcreader.getTrack(i, idMoth); + for(int i=0; iGetPdgCode()) == bpdgs[i] ) hasBeautyMoth = kTRUE; } + } + if(hasBeautyMoth){ + nSignalPsi2S++; + for (int j{track.getFirstDaughterTrackId()}; j <= track.getLastDaughterTrackId(); ++j) { + auto pdgDau = tracks->at(j).GetPdgCode(); + if(TMath::Abs(pdgDau) == checkPdgDecay[0] ) { nSignalJpsi++; if( std::abs(track.GetRapidity()) < rapidityWindow) nSignalJpsiWithinAcc++; idJpsi = j; } + if(pdgDau == checkPdgDecay[1] ) { nSignalPionsPos++; if( std::abs(track.GetRapidity()) < rapidityWindow) nSignalPionsPosWithinAcc++; } + if(pdgDau == checkPdgDecay[2] ) { nSignalPionsNeg++; if( std::abs(track.GetRapidity()) < rapidityWindow) nSignalPionsNegWithinAcc++; } + } + + auto trackJpsi = tracks->at(idJpsi); + for (int j{trackJpsi.getFirstDaughterTrackId()}; j <= trackJpsi.getLastDaughterTrackId(); ++j) { + auto pdgDau = tracks->at(j).GetPdgCode(); + if(pdgDau == leptonPdg ) IdChild0 = j; + if(pdgDau == -leptonPdg ) IdChild1 = j; + } + auto child0 = tracks->at(IdChild0); + auto child1 = tracks->at(IdChild1); + // check for parent-child relations + auto pdg0 = child0.GetPdgCode(); + auto pdg1 = child1.GetPdgCode(); + if (std::abs(pdg0) == leptonPdg && std::abs(pdg1) == leptonPdg && pdg0 == -pdg1) { + nLeptonPairs++; + if (child0.getToBeDone() && child1.getToBeDone()) { + nLeptonPairsToBeDone++; + } + } + } + } + } + } + std::cout << "#events: " << nEvents << "\n" + << "#leptons: " << nLeptons << "\n" + << "#antileptons: " << nAntileptons << "\n" + << "#signal (jpsi <- psi2S): " << nSignalJpsi << "; within acceptance (|y| < " << rapidityWindow << "): " << nSignalJpsiWithinAcc << "\n" + << "#signal (pi+ <- psi2S): " << nSignalPionsPos << "; within acceptance (|y| < " << rapidityWindow << "): " << nSignalPionsPosWithinAcc << "\n" + << "#signal (pi- <- psi2S): " << nSignalPionsNeg << "; within acceptance (|y| < " << rapidityWindow << "): " << nSignalPionsNegWithinAcc << "\n" + << "#lepton pairs: " << nLeptonPairs << "\n" + << "#lepton pairs to be done: " << nLeptonPairs << "\n"; + + + if (nLeptonPairs == 0 || nLeptons == 0 || nAntileptons == 0) { + std::cerr << "Number of leptons, number of anti-leptons as well as number of lepton pairs should all be greater than 1.\n"; + return 1; + } + if (nLeptonPairs != nLeptonPairsToBeDone) { + std::cerr << "The number of lepton pairs should be the same as the number of lepton pairs which should be transported.\n"; + return 1; + } + + return 0; +} \ No newline at end of file diff --git a/MC/config/PWGDQ/ini/tests/Generator_InjectedCharmoniaMidy_PbPb5TeV.C b/MC/config/PWGDQ/ini/tests/Generator_InjectedCharmoniaMidy_PbPb5TeV.C new file mode 100644 index 000000000..b155ec9ac --- /dev/null +++ b/MC/config/PWGDQ/ini/tests/Generator_InjectedCharmoniaMidy_PbPb5TeV.C @@ -0,0 +1,84 @@ +int External() +{ + int checkPdgSignal[] = {443,100443}; + int checkPdgDecay = 11; + std::string path{"o2sim_Kine.root"}; + std::cout << "Check for\nsignal PDG " << checkPdgSignal << "\ndecay PDG " << checkPdgDecay << "\n"; + TFile file(path.c_str(), "READ"); + if (file.IsZombie()) { + std::cerr << "Cannot open ROOT file " << path << "\n"; + return 1; + } + + auto tree = (TTree*)file.Get("o2sim"); + std::vector* tracks{}; + tree->SetBranchAddress("MCTrack", &tracks); + + int nLeptons{}; + int nAntileptons{}; + int nLeptonPairs{}; + int nLeptonPairsToBeDone{}; + int nSignalJpsi{}; + int nSignalPsi2S{}; + int nSignalJpsiWithinAcc{}; + int nSignalPsi2SWithinAcc{}; + auto nEvents = tree->GetEntries(); + o2::steer::MCKinematicsReader mcreader("o2sim", o2::steer::MCKinematicsReader::Mode::kMCKine); + Bool_t isInjected = kFALSE; + + for (int i = 0; i < nEvents; i++) { + tree->GetEntry(i); + for (auto& track : *tracks) { + auto pdg = track.GetPdgCode(); + auto rapidity = track.GetRapidity(); + auto idMoth = track.getMotherTrackId(); + if (pdg == checkPdgDecay) { + // count leptons + nLeptons++; + } else if(pdg == -checkPdgDecay) { + // count anti-leptons + nAntileptons++; + } else if (pdg == checkPdgSignal[0] || pdg == checkPdgSignal[1]) { + if(idMoth < 0){ + // count signal PDG + pdg == checkPdgSignal[0] ? nSignalJpsi++ : nSignalPsi2S++; + // count signal PDG within acceptance + if(std::abs(rapidity) < 1.0) { pdg == checkPdgSignal[0] ? nSignalJpsiWithinAcc++ : nSignalPsi2SWithinAcc++;} + } + auto child0 = o2::mcutils::MCTrackNavigator::getDaughter0(track, *tracks); + auto child1 = o2::mcutils::MCTrackNavigator::getDaughter1(track, *tracks); + if (child0 != nullptr && child1 != nullptr) { + // check for parent-child relations + auto pdg0 = child0->GetPdgCode(); + auto pdg1 = child1->GetPdgCode(); + std::cout << "First and last children of parent " << checkPdgSignal << " are PDG0: " << pdg0 << " PDG1: " << pdg1 << "\n"; + if (std::abs(pdg0) == checkPdgDecay && std::abs(pdg1) == checkPdgDecay && pdg0 == -pdg1) { + nLeptonPairs++; + if (child0->getToBeDone() && child1->getToBeDone()) { + nLeptonPairsToBeDone++; + } + } + } + } + } + } + std::cout << "#events: " << nEvents << "\n" + << "#leptons: " << nLeptons << "\n" + << "#antileptons: " << nAntileptons << "\n" + << "#signal (prompt Jpsi): " << nSignalJpsi << "; within acceptance (|y| < 1): " << nSignalJpsiWithinAcc << "\n" + << "#signal (prompt Psi(2S)): " << nSignalPsi2S << "; within acceptance (|y| < 1): " << nSignalPsi2SWithinAcc << "\n" + << "#lepton pairs: " << nLeptonPairs << "\n" + << "#lepton pairs to be done: " << nLeptonPairs << "\n"; + + + if (nLeptonPairs == 0 || nLeptons == 0 || nAntileptons == 0) { + std::cerr << "Number of leptons, number of anti-leptons as well as number of lepton pairs should all be greater than 1.\n"; + return 1; + } + if (nLeptonPairs != nLeptonPairsToBeDone) { + std::cerr << "The number of lepton pairs should be the same as the number of lepton pairs which should be transported.\n"; + return 1; + } + + return 0; +} diff --git a/MC/config/PWGDQ/ini/tests/Generator_InjectedInclusiveJpsiMidy_Pythia8_TriggerGap.C b/MC/config/PWGDQ/ini/tests/Generator_InjectedInclusiveJpsiMidy_Pythia8_TriggerGap.C new file mode 100644 index 000000000..45dafa928 --- /dev/null +++ b/MC/config/PWGDQ/ini/tests/Generator_InjectedInclusiveJpsiMidy_Pythia8_TriggerGap.C @@ -0,0 +1,102 @@ +int External() +{ + int checkPdgSignal[] = {443, 100443}; + int checkPdgDecay = 11; + double rapiditymin = -4.3; + double rapiditymax = -2.3; + std::string path{"o2sim_Kine.root"}; + std::cout << "Check for\nsignal PDG " << checkPdgSignal << "\ndecay PDG " << checkPdgDecay << "\n"; + TFile file(path.c_str(), "READ"); + if (file.IsZombie()) + { + std::cerr << "Cannot open ROOT file " << path << "\n"; + return 1; + } + + auto tree = (TTree *)file.Get("o2sim"); + std::vector *tracks{}; + tree->SetBranchAddress("MCTrack", &tracks); + + int nLeptons{}; + int nAntileptons{}; + int nLeptonPairs{}; + int nLeptonPairsToBeDone{}; + int nSignalJpsi{}; + int nSignalPsi2S{}; + int nSignalJpsiWithinAcc{}; + int nSignalPsi2SWithinAcc{}; + auto nEvents = tree->GetEntries(); + o2::steer::MCKinematicsReader mcreader("o2sim", o2::steer::MCKinematicsReader::Mode::kMCKine); + Bool_t isInjected = kFALSE; + + for (int i = 0; i < nEvents; i++) + { + tree->GetEntry(i); + for (auto &track : *tracks) + { + auto pdg = track.GetPdgCode(); + auto rapidity = track.GetRapidity(); + auto idMoth = track.getMotherTrackId(); + if (pdg == checkPdgDecay) + { + // count leptons + nLeptons++; + } + else if (pdg == -checkPdgDecay) + { + // count anti-leptons + nAntileptons++; + } + else if (pdg == checkPdgSignal[0] || pdg == checkPdgSignal[1]) + { + if (idMoth < 0) + { + // count signal PDG + pdg == checkPdgSignal[0] ? nSignalJpsi++ : nSignalPsi2S++; + // count signal PDG within acceptance + if (rapidity > rapiditymin && rapidity < rapiditymax) + { + pdg == checkPdgSignal[0] ? nSignalJpsiWithinAcc++ : nSignalPsi2SWithinAcc++; + } + } + auto child0 = o2::mcutils::MCTrackNavigator::getDaughter0(track, *tracks); + auto child1 = o2::mcutils::MCTrackNavigator::getDaughter1(track, *tracks); + if (child0 != nullptr && child1 != nullptr) + { + // check for parent-child relations + auto pdg0 = child0->GetPdgCode(); + auto pdg1 = child1->GetPdgCode(); + std::cout << "First and last children of parent " << checkPdgSignal << " are PDG0: " << pdg0 << " PDG1: " << pdg1 << "\n"; + if (std::abs(pdg0) == checkPdgDecay && std::abs(pdg1) == checkPdgDecay && pdg0 == -pdg1) + { + nLeptonPairs++; + if (child0->getToBeDone() && child1->getToBeDone()) + { + nLeptonPairsToBeDone++; + } + } + } + } + } + } + std::cout << "#events: " << nEvents << "\n" + << "#leptons: " << nLeptons << "\n" + << "#antileptons: " << nAntileptons << "\n" + << "#signal (prompt Jpsi): " << nSignalJpsi << "; within acceptance " << rapiditymin << " < y < " << rapiditymax << " : " << nSignalJpsiWithinAcc << "\n" + << "#signal (prompt Psi(2S)): " << nSignalPsi2S << "; within acceptance " << rapiditymin << " < y < " << rapiditymax << " : " << nSignalPsi2SWithinAcc << "\n" + << "#lepton pairs: " << nLeptonPairs << "\n" + << "#lepton pairs to be done: " << nLeptonPairs << "\n"; + + if (nLeptonPairs == 0 || nLeptons == 0 || nAntileptons == 0) + { + std::cerr << "Number of leptons, number of anti-leptons as well as number of lepton pairs should all be greater than 1.\n"; + return 1; + } + if (nLeptonPairs != nLeptonPairsToBeDone) + { + std::cerr << "The number of lepton pairs should be the same as the number of lepton pairs which should be transported.\n"; + return 1; + } + + return 0; +} diff --git a/MC/config/PWGDQ/ini/tests/Generator_InjectedInclusiveJpsiPsi2SMidy_2026_Pythia8_TriggerGap.C b/MC/config/PWGDQ/ini/tests/Generator_InjectedInclusiveJpsiPsi2SMidy_2026_Pythia8_TriggerGap.C new file mode 100644 index 000000000..45dafa928 --- /dev/null +++ b/MC/config/PWGDQ/ini/tests/Generator_InjectedInclusiveJpsiPsi2SMidy_2026_Pythia8_TriggerGap.C @@ -0,0 +1,102 @@ +int External() +{ + int checkPdgSignal[] = {443, 100443}; + int checkPdgDecay = 11; + double rapiditymin = -4.3; + double rapiditymax = -2.3; + std::string path{"o2sim_Kine.root"}; + std::cout << "Check for\nsignal PDG " << checkPdgSignal << "\ndecay PDG " << checkPdgDecay << "\n"; + TFile file(path.c_str(), "READ"); + if (file.IsZombie()) + { + std::cerr << "Cannot open ROOT file " << path << "\n"; + return 1; + } + + auto tree = (TTree *)file.Get("o2sim"); + std::vector *tracks{}; + tree->SetBranchAddress("MCTrack", &tracks); + + int nLeptons{}; + int nAntileptons{}; + int nLeptonPairs{}; + int nLeptonPairsToBeDone{}; + int nSignalJpsi{}; + int nSignalPsi2S{}; + int nSignalJpsiWithinAcc{}; + int nSignalPsi2SWithinAcc{}; + auto nEvents = tree->GetEntries(); + o2::steer::MCKinematicsReader mcreader("o2sim", o2::steer::MCKinematicsReader::Mode::kMCKine); + Bool_t isInjected = kFALSE; + + for (int i = 0; i < nEvents; i++) + { + tree->GetEntry(i); + for (auto &track : *tracks) + { + auto pdg = track.GetPdgCode(); + auto rapidity = track.GetRapidity(); + auto idMoth = track.getMotherTrackId(); + if (pdg == checkPdgDecay) + { + // count leptons + nLeptons++; + } + else if (pdg == -checkPdgDecay) + { + // count anti-leptons + nAntileptons++; + } + else if (pdg == checkPdgSignal[0] || pdg == checkPdgSignal[1]) + { + if (idMoth < 0) + { + // count signal PDG + pdg == checkPdgSignal[0] ? nSignalJpsi++ : nSignalPsi2S++; + // count signal PDG within acceptance + if (rapidity > rapiditymin && rapidity < rapiditymax) + { + pdg == checkPdgSignal[0] ? nSignalJpsiWithinAcc++ : nSignalPsi2SWithinAcc++; + } + } + auto child0 = o2::mcutils::MCTrackNavigator::getDaughter0(track, *tracks); + auto child1 = o2::mcutils::MCTrackNavigator::getDaughter1(track, *tracks); + if (child0 != nullptr && child1 != nullptr) + { + // check for parent-child relations + auto pdg0 = child0->GetPdgCode(); + auto pdg1 = child1->GetPdgCode(); + std::cout << "First and last children of parent " << checkPdgSignal << " are PDG0: " << pdg0 << " PDG1: " << pdg1 << "\n"; + if (std::abs(pdg0) == checkPdgDecay && std::abs(pdg1) == checkPdgDecay && pdg0 == -pdg1) + { + nLeptonPairs++; + if (child0->getToBeDone() && child1->getToBeDone()) + { + nLeptonPairsToBeDone++; + } + } + } + } + } + } + std::cout << "#events: " << nEvents << "\n" + << "#leptons: " << nLeptons << "\n" + << "#antileptons: " << nAntileptons << "\n" + << "#signal (prompt Jpsi): " << nSignalJpsi << "; within acceptance " << rapiditymin << " < y < " << rapiditymax << " : " << nSignalJpsiWithinAcc << "\n" + << "#signal (prompt Psi(2S)): " << nSignalPsi2S << "; within acceptance " << rapiditymin << " < y < " << rapiditymax << " : " << nSignalPsi2SWithinAcc << "\n" + << "#lepton pairs: " << nLeptonPairs << "\n" + << "#lepton pairs to be done: " << nLeptonPairs << "\n"; + + if (nLeptonPairs == 0 || nLeptons == 0 || nAntileptons == 0) + { + std::cerr << "Number of leptons, number of anti-leptons as well as number of lepton pairs should all be greater than 1.\n"; + return 1; + } + if (nLeptonPairs != nLeptonPairsToBeDone) + { + std::cerr << "The number of lepton pairs should be the same as the number of lepton pairs which should be transported.\n"; + return 1; + } + + return 0; +} diff --git a/MC/config/PWGDQ/ini/tests/Generator_InjectedInclusiveJpsiPsi2SMidy_Pythia8_TriggerGap.C b/MC/config/PWGDQ/ini/tests/Generator_InjectedInclusiveJpsiPsi2SMidy_Pythia8_TriggerGap.C new file mode 100644 index 000000000..80ae5d71f --- /dev/null +++ b/MC/config/PWGDQ/ini/tests/Generator_InjectedInclusiveJpsiPsi2SMidy_Pythia8_TriggerGap.C @@ -0,0 +1,72 @@ +int External() +{ + int checkPdgSignal = 443; + int checkPdgDecay = 11; + std::string path{"o2sim_Kine.root"}; + std::cout << "Check for\nsignal PDG " << checkPdgSignal << "\ndecay PDG " << checkPdgDecay << "\n"; + TFile file(path.c_str(), "READ"); + if (file.IsZombie()) { + std::cerr << "Cannot open ROOT file " << path << "\n"; + return 1; + } + + auto tree = (TTree*)file.Get("o2sim"); + std::vector* tracks{}; + tree->SetBranchAddress("MCTrack", &tracks); + + int nLeptons{}; + int nAntileptons{}; + int nLeptonPairs{}; + int nLeptonPairsToBeDone{}; + int nSignal{}; + auto nEvents = tree->GetEntries(); + + for (int i = 0; i < nEvents; i++) { + tree->GetEntry(i); + for (auto& track : *tracks) { + auto pdg = track.GetPdgCode(); + if (pdg == checkPdgDecay) { + // count leptons + nLeptons++; + } else if(pdg == -checkPdgDecay) { + // count anti-leptons + nAntileptons++; + } else if (pdg == checkPdgSignal) { + // count signal PDG + nSignal++; + auto child0 = o2::mcutils::MCTrackNavigator::getDaughter0(track, *tracks); + auto child1 = o2::mcutils::MCTrackNavigator::getDaughter1(track, *tracks); + if (child0 != nullptr && child1 != nullptr) { + // check for parent-child relations + auto pdg0 = child0->GetPdgCode(); + auto pdg1 = child1->GetPdgCode(); + std::cout << "First and last children of parent " << checkPdgSignal << " are PDG0: " << pdg0 << " PDG1: " << pdg1 << "\n"; + if (std::abs(pdg0) == checkPdgDecay && std::abs(pdg1) == checkPdgDecay && pdg0 == -pdg1) { + nLeptonPairs++; + if (child0->getToBeDone() && child1->getToBeDone()) { + nLeptonPairsToBeDone++; + } + } + } + } + } + } + std::cout << "#events: " << nEvents << "\n" + << "#leptons: " << nLeptons << "\n" + << "#antileptons: " << nAntileptons << "\n" + << "#signal: " << nSignal << "\n" + << "#lepton pairs: " << nLeptonPairs << "\n" + << "#lepton pairs to be done: " << nLeptonPairs << "\n"; + + + if (nLeptonPairs == 0 || nLeptons == 0 || nAntileptons == 0) { + std::cerr << "Number of leptons, number of anti-leptons as well as number of lepton pairs should all be greater than 1.\n"; + return 1; + } + if (nLeptonPairs != nLeptonPairsToBeDone) { + std::cerr << "The number of lepton pairs should be the same as the number of lepton pairs which should be transported.\n"; + return 1; + } + + return 0; +} diff --git a/MC/config/PWGDQ/ini/tests/Generator_InjectedInclusiveJpsiPsi2SMidy_Pythia8_TriggerGap_pO96TeV.C b/MC/config/PWGDQ/ini/tests/Generator_InjectedInclusiveJpsiPsi2SMidy_Pythia8_TriggerGap_pO96TeV.C new file mode 100644 index 000000000..b155ec9ac --- /dev/null +++ b/MC/config/PWGDQ/ini/tests/Generator_InjectedInclusiveJpsiPsi2SMidy_Pythia8_TriggerGap_pO96TeV.C @@ -0,0 +1,84 @@ +int External() +{ + int checkPdgSignal[] = {443,100443}; + int checkPdgDecay = 11; + std::string path{"o2sim_Kine.root"}; + std::cout << "Check for\nsignal PDG " << checkPdgSignal << "\ndecay PDG " << checkPdgDecay << "\n"; + TFile file(path.c_str(), "READ"); + if (file.IsZombie()) { + std::cerr << "Cannot open ROOT file " << path << "\n"; + return 1; + } + + auto tree = (TTree*)file.Get("o2sim"); + std::vector* tracks{}; + tree->SetBranchAddress("MCTrack", &tracks); + + int nLeptons{}; + int nAntileptons{}; + int nLeptonPairs{}; + int nLeptonPairsToBeDone{}; + int nSignalJpsi{}; + int nSignalPsi2S{}; + int nSignalJpsiWithinAcc{}; + int nSignalPsi2SWithinAcc{}; + auto nEvents = tree->GetEntries(); + o2::steer::MCKinematicsReader mcreader("o2sim", o2::steer::MCKinematicsReader::Mode::kMCKine); + Bool_t isInjected = kFALSE; + + for (int i = 0; i < nEvents; i++) { + tree->GetEntry(i); + for (auto& track : *tracks) { + auto pdg = track.GetPdgCode(); + auto rapidity = track.GetRapidity(); + auto idMoth = track.getMotherTrackId(); + if (pdg == checkPdgDecay) { + // count leptons + nLeptons++; + } else if(pdg == -checkPdgDecay) { + // count anti-leptons + nAntileptons++; + } else if (pdg == checkPdgSignal[0] || pdg == checkPdgSignal[1]) { + if(idMoth < 0){ + // count signal PDG + pdg == checkPdgSignal[0] ? nSignalJpsi++ : nSignalPsi2S++; + // count signal PDG within acceptance + if(std::abs(rapidity) < 1.0) { pdg == checkPdgSignal[0] ? nSignalJpsiWithinAcc++ : nSignalPsi2SWithinAcc++;} + } + auto child0 = o2::mcutils::MCTrackNavigator::getDaughter0(track, *tracks); + auto child1 = o2::mcutils::MCTrackNavigator::getDaughter1(track, *tracks); + if (child0 != nullptr && child1 != nullptr) { + // check for parent-child relations + auto pdg0 = child0->GetPdgCode(); + auto pdg1 = child1->GetPdgCode(); + std::cout << "First and last children of parent " << checkPdgSignal << " are PDG0: " << pdg0 << " PDG1: " << pdg1 << "\n"; + if (std::abs(pdg0) == checkPdgDecay && std::abs(pdg1) == checkPdgDecay && pdg0 == -pdg1) { + nLeptonPairs++; + if (child0->getToBeDone() && child1->getToBeDone()) { + nLeptonPairsToBeDone++; + } + } + } + } + } + } + std::cout << "#events: " << nEvents << "\n" + << "#leptons: " << nLeptons << "\n" + << "#antileptons: " << nAntileptons << "\n" + << "#signal (prompt Jpsi): " << nSignalJpsi << "; within acceptance (|y| < 1): " << nSignalJpsiWithinAcc << "\n" + << "#signal (prompt Psi(2S)): " << nSignalPsi2S << "; within acceptance (|y| < 1): " << nSignalPsi2SWithinAcc << "\n" + << "#lepton pairs: " << nLeptonPairs << "\n" + << "#lepton pairs to be done: " << nLeptonPairs << "\n"; + + + if (nLeptonPairs == 0 || nLeptons == 0 || nAntileptons == 0) { + std::cerr << "Number of leptons, number of anti-leptons as well as number of lepton pairs should all be greater than 1.\n"; + return 1; + } + if (nLeptonPairs != nLeptonPairsToBeDone) { + std::cerr << "The number of lepton pairs should be the same as the number of lepton pairs which should be transported.\n"; + return 1; + } + + return 0; +} diff --git a/MC/config/PWGDQ/ini/tests/Generator_InjectedPromptCharmoniaFwdy_TriggerGap_NeNe5TeV.C b/MC/config/PWGDQ/ini/tests/Generator_InjectedPromptCharmoniaFwdy_TriggerGap_NeNe5TeV.C new file mode 100644 index 000000000..5dd26f49d --- /dev/null +++ b/MC/config/PWGDQ/ini/tests/Generator_InjectedPromptCharmoniaFwdy_TriggerGap_NeNe5TeV.C @@ -0,0 +1,85 @@ +int External() +{ + int checkPdgSignal[] = {443,100443}; + int checkPdgDecay = 13; + double rapiditymin = -4.3; double rapiditymax = -2.3; + std::string path{"o2sim_Kine.root"}; + std::cout << "Check for\nsignal PDG " << checkPdgSignal << "\ndecay PDG " << checkPdgDecay << "\n"; + TFile file(path.c_str(), "READ"); + if (file.IsZombie()) { + std::cerr << "Cannot open ROOT file " << path << "\n"; + return 1; + } + + auto tree = (TTree*)file.Get("o2sim"); + std::vector* tracks{}; + tree->SetBranchAddress("MCTrack", &tracks); + + int nLeptons{}; + int nAntileptons{}; + int nLeptonPairs{}; + int nLeptonPairsToBeDone{}; + int nSignalJpsi{}; + int nSignalPsi2S{}; + int nSignalJpsiWithinAcc{}; + int nSignalPsi2SWithinAcc{}; + auto nEvents = tree->GetEntries(); + o2::steer::MCKinematicsReader mcreader("o2sim", o2::steer::MCKinematicsReader::Mode::kMCKine); + Bool_t isInjected = kFALSE; + + for (int i = 0; i < nEvents; i++) { + tree->GetEntry(i); + for (auto& track : *tracks) { + auto pdg = track.GetPdgCode(); + auto rapidity = track.GetRapidity(); + auto idMoth = track.getMotherTrackId(); + if (pdg == checkPdgDecay) { + // count leptons + nLeptons++; + } else if(pdg == -checkPdgDecay) { + // count anti-leptons + nAntileptons++; + } else if (pdg == checkPdgSignal[0] || pdg == checkPdgSignal[1]) { + if(idMoth < 0) { + // count signal PDG + pdg == checkPdgSignal[0] ? nSignalJpsi++ : nSignalPsi2S++; + // count signal PDG within acceptance + if(rapidity > rapiditymin && rapidity < rapiditymax) { pdg == checkPdgSignal[0] ? nSignalJpsiWithinAcc++ : nSignalPsi2SWithinAcc++;} + } + auto child0 = o2::mcutils::MCTrackNavigator::getDaughter0(track, *tracks); + auto child1 = o2::mcutils::MCTrackNavigator::getDaughter1(track, *tracks); + if (child0 != nullptr && child1 != nullptr) { + // check for parent-child relations + auto pdg0 = child0->GetPdgCode(); + auto pdg1 = child1->GetPdgCode(); + std::cout << "First and last children of parent " << checkPdgSignal << " are PDG0: " << pdg0 << " PDG1: " << pdg1 << "\n"; + if (std::abs(pdg0) == checkPdgDecay && std::abs(pdg1) == checkPdgDecay && pdg0 == -pdg1) { + nLeptonPairs++; + if (child0->getToBeDone() && child1->getToBeDone()) { + nLeptonPairsToBeDone++; + } + } + } + } + } + } + std::cout << "#events: " << nEvents << "\n" + << "#leptons: " << nLeptons << "\n" + << "#antileptons: " << nAntileptons << "\n" + << "#signal (prompt Jpsi): " << nSignalJpsi << "; within acceptance " << rapiditymin << " < y < " << rapiditymax << " : " << nSignalJpsiWithinAcc << "\n" + << "#signal (prompt Psi(2S)): " << nSignalPsi2S << "; within acceptance " << rapiditymin << " < y < " << rapiditymax << " : " << nSignalPsi2SWithinAcc << "\n" + << "#lepton pairs: " << nLeptonPairs << "\n" + << "#lepton pairs to be done: " << nLeptonPairs << "\n"; + + + if (nLeptonPairs == 0 || nLeptons == 0 || nAntileptons == 0) { + std::cerr << "Number of leptons, number of anti-leptons as well as number of lepton pairs should all be greater than 1.\n"; + return 1; + } + if (nLeptonPairs != nLeptonPairsToBeDone) { + std::cerr << "The number of lepton pairs should be the same as the number of lepton pairs which should be transported.\n"; + return 1; + } + + return 0; +} diff --git a/MC/config/PWGDQ/ini/tests/Generator_InjectedPromptCharmoniaFwdy_TriggerGap_OO5TeV.C b/MC/config/PWGDQ/ini/tests/Generator_InjectedPromptCharmoniaFwdy_TriggerGap_OO5TeV.C new file mode 100644 index 000000000..5dd26f49d --- /dev/null +++ b/MC/config/PWGDQ/ini/tests/Generator_InjectedPromptCharmoniaFwdy_TriggerGap_OO5TeV.C @@ -0,0 +1,85 @@ +int External() +{ + int checkPdgSignal[] = {443,100443}; + int checkPdgDecay = 13; + double rapiditymin = -4.3; double rapiditymax = -2.3; + std::string path{"o2sim_Kine.root"}; + std::cout << "Check for\nsignal PDG " << checkPdgSignal << "\ndecay PDG " << checkPdgDecay << "\n"; + TFile file(path.c_str(), "READ"); + if (file.IsZombie()) { + std::cerr << "Cannot open ROOT file " << path << "\n"; + return 1; + } + + auto tree = (TTree*)file.Get("o2sim"); + std::vector* tracks{}; + tree->SetBranchAddress("MCTrack", &tracks); + + int nLeptons{}; + int nAntileptons{}; + int nLeptonPairs{}; + int nLeptonPairsToBeDone{}; + int nSignalJpsi{}; + int nSignalPsi2S{}; + int nSignalJpsiWithinAcc{}; + int nSignalPsi2SWithinAcc{}; + auto nEvents = tree->GetEntries(); + o2::steer::MCKinematicsReader mcreader("o2sim", o2::steer::MCKinematicsReader::Mode::kMCKine); + Bool_t isInjected = kFALSE; + + for (int i = 0; i < nEvents; i++) { + tree->GetEntry(i); + for (auto& track : *tracks) { + auto pdg = track.GetPdgCode(); + auto rapidity = track.GetRapidity(); + auto idMoth = track.getMotherTrackId(); + if (pdg == checkPdgDecay) { + // count leptons + nLeptons++; + } else if(pdg == -checkPdgDecay) { + // count anti-leptons + nAntileptons++; + } else if (pdg == checkPdgSignal[0] || pdg == checkPdgSignal[1]) { + if(idMoth < 0) { + // count signal PDG + pdg == checkPdgSignal[0] ? nSignalJpsi++ : nSignalPsi2S++; + // count signal PDG within acceptance + if(rapidity > rapiditymin && rapidity < rapiditymax) { pdg == checkPdgSignal[0] ? nSignalJpsiWithinAcc++ : nSignalPsi2SWithinAcc++;} + } + auto child0 = o2::mcutils::MCTrackNavigator::getDaughter0(track, *tracks); + auto child1 = o2::mcutils::MCTrackNavigator::getDaughter1(track, *tracks); + if (child0 != nullptr && child1 != nullptr) { + // check for parent-child relations + auto pdg0 = child0->GetPdgCode(); + auto pdg1 = child1->GetPdgCode(); + std::cout << "First and last children of parent " << checkPdgSignal << " are PDG0: " << pdg0 << " PDG1: " << pdg1 << "\n"; + if (std::abs(pdg0) == checkPdgDecay && std::abs(pdg1) == checkPdgDecay && pdg0 == -pdg1) { + nLeptonPairs++; + if (child0->getToBeDone() && child1->getToBeDone()) { + nLeptonPairsToBeDone++; + } + } + } + } + } + } + std::cout << "#events: " << nEvents << "\n" + << "#leptons: " << nLeptons << "\n" + << "#antileptons: " << nAntileptons << "\n" + << "#signal (prompt Jpsi): " << nSignalJpsi << "; within acceptance " << rapiditymin << " < y < " << rapiditymax << " : " << nSignalJpsiWithinAcc << "\n" + << "#signal (prompt Psi(2S)): " << nSignalPsi2S << "; within acceptance " << rapiditymin << " < y < " << rapiditymax << " : " << nSignalPsi2SWithinAcc << "\n" + << "#lepton pairs: " << nLeptonPairs << "\n" + << "#lepton pairs to be done: " << nLeptonPairs << "\n"; + + + if (nLeptonPairs == 0 || nLeptons == 0 || nAntileptons == 0) { + std::cerr << "Number of leptons, number of anti-leptons as well as number of lepton pairs should all be greater than 1.\n"; + return 1; + } + if (nLeptonPairs != nLeptonPairsToBeDone) { + std::cerr << "The number of lepton pairs should be the same as the number of lepton pairs which should be transported.\n"; + return 1; + } + + return 0; +} diff --git a/MC/config/PWGDQ/ini/tests/Generator_InjectedPromptCharmoniaFwdy_TriggerGap_PbPb5TeV_TriggerRatio2.C b/MC/config/PWGDQ/ini/tests/Generator_InjectedPromptCharmoniaFwdy_TriggerGap_PbPb5TeV_TriggerRatio2.C new file mode 100644 index 000000000..e88864af3 --- /dev/null +++ b/MC/config/PWGDQ/ini/tests/Generator_InjectedPromptCharmoniaFwdy_TriggerGap_PbPb5TeV_TriggerRatio2.C @@ -0,0 +1,85 @@ +int External() +{ + int checkPdgSignal[] = {443,100443}; + int checkPdgDecay = 13; + double rapiditymin = -4.3; double rapiditymax = -2.3; + std::string path{"o2sim_Kine.root"}; + std::cout << "Check for\nsignal PDG " << checkPdgSignal << "\ndecay PDG " << checkPdgDecay << "\n"; + TFile file(path.c_str(), "READ"); + if (file.IsZombie()) { + std::cerr << "Cannot open ROOT file " << path << "\n"; + return 1; + } + + auto tree = (TTree*)file.Get("o2sim"); + std::vector* tracks{}; + tree->SetBranchAddress("MCTrack", &tracks); + + int nLeptons{}; + int nAntileptons{}; + int nLeptonPairs{}; + int nLeptonPairsToBeDone{}; + int nSignalJpsi{}; + int nSignalPsi2S{}; + int nSignalJpsiWithinAcc{}; + int nSignalPsi2SWithinAcc{}; + auto nEvents = tree->GetEntries(); + o2::steer::MCKinematicsReader mcreader("o2sim", o2::steer::MCKinematicsReader::Mode::kMCKine); + Bool_t isInjected = kFALSE; + + for (int i = 0; i < nEvents; i++) { + tree->GetEntry(i); + for (auto& track : *tracks) { + auto pdg = track.GetPdgCode(); + auto rapidity = track.GetRapidity(); + auto idMoth = track.getMotherTrackId(); + if (pdg == checkPdgDecay) { + // count leptons + nLeptons++; + } else if(pdg == -checkPdgDecay) { + // count anti-leptons + nAntileptons++; + } else if (pdg == checkPdgSignal[0] || pdg == checkPdgSignal[1]) { + if(idMoth < 0){ + // count signal PDG + pdg == checkPdgSignal[0] ? nSignalJpsi++ : nSignalPsi2S++; + // count signal PDG within acceptance + if(rapidity > rapiditymin && rapidity < rapiditymax) { pdg == checkPdgSignal[0] ? nSignalJpsiWithinAcc++ : nSignalPsi2SWithinAcc++;} + } + auto child0 = o2::mcutils::MCTrackNavigator::getDaughter0(track, *tracks); + auto child1 = o2::mcutils::MCTrackNavigator::getDaughter1(track, *tracks); + if (child0 != nullptr && child1 != nullptr) { + // check for parent-child relations + auto pdg0 = child0->GetPdgCode(); + auto pdg1 = child1->GetPdgCode(); + std::cout << "First and last children of parent " << checkPdgSignal << " are PDG0: " << pdg0 << " PDG1: " << pdg1 << "\n"; + if (std::abs(pdg0) == checkPdgDecay && std::abs(pdg1) == checkPdgDecay && pdg0 == -pdg1) { + nLeptonPairs++; + if (child0->getToBeDone() && child1->getToBeDone()) { + nLeptonPairsToBeDone++; + } + } + } + } + } + } + std::cout << "#events: " << nEvents << "\n" + << "#leptons: " << nLeptons << "\n" + << "#antileptons: " << nAntileptons << "\n" + << "#signal (prompt Jpsi): " << nSignalJpsi << "; within acceptance " << rapiditymin << " < y < " << rapiditymax << " : " << nSignalJpsiWithinAcc << "\n" + << "#signal (prompt Psi(2S)): " << nSignalPsi2S << "; within acceptance " << rapiditymin << " < y < " << rapiditymax << " : " << nSignalPsi2SWithinAcc << "\n" + << "#lepton pairs: " << nLeptonPairs << "\n" + << "#lepton pairs to be done: " << nLeptonPairs << "\n"; + + + if (nLeptonPairs == 0 || nLeptons == 0 || nAntileptons == 0) { + std::cerr << "Number of leptons, number of anti-leptons as well as number of lepton pairs should all be greater than 1.\n"; + return 1; + } + if (nLeptonPairs != nLeptonPairsToBeDone) { + std::cerr << "The number of lepton pairs should be the same as the number of lepton pairs which should be transported.\n"; + return 1; + } + + return 0; +} diff --git a/MC/config/PWGDQ/ini/tests/Generator_InjectedPromptCharmoniaFwdy_TriggerGap_pO96TeV.C b/MC/config/PWGDQ/ini/tests/Generator_InjectedPromptCharmoniaFwdy_TriggerGap_pO96TeV.C new file mode 100644 index 000000000..5dd26f49d --- /dev/null +++ b/MC/config/PWGDQ/ini/tests/Generator_InjectedPromptCharmoniaFwdy_TriggerGap_pO96TeV.C @@ -0,0 +1,85 @@ +int External() +{ + int checkPdgSignal[] = {443,100443}; + int checkPdgDecay = 13; + double rapiditymin = -4.3; double rapiditymax = -2.3; + std::string path{"o2sim_Kine.root"}; + std::cout << "Check for\nsignal PDG " << checkPdgSignal << "\ndecay PDG " << checkPdgDecay << "\n"; + TFile file(path.c_str(), "READ"); + if (file.IsZombie()) { + std::cerr << "Cannot open ROOT file " << path << "\n"; + return 1; + } + + auto tree = (TTree*)file.Get("o2sim"); + std::vector* tracks{}; + tree->SetBranchAddress("MCTrack", &tracks); + + int nLeptons{}; + int nAntileptons{}; + int nLeptonPairs{}; + int nLeptonPairsToBeDone{}; + int nSignalJpsi{}; + int nSignalPsi2S{}; + int nSignalJpsiWithinAcc{}; + int nSignalPsi2SWithinAcc{}; + auto nEvents = tree->GetEntries(); + o2::steer::MCKinematicsReader mcreader("o2sim", o2::steer::MCKinematicsReader::Mode::kMCKine); + Bool_t isInjected = kFALSE; + + for (int i = 0; i < nEvents; i++) { + tree->GetEntry(i); + for (auto& track : *tracks) { + auto pdg = track.GetPdgCode(); + auto rapidity = track.GetRapidity(); + auto idMoth = track.getMotherTrackId(); + if (pdg == checkPdgDecay) { + // count leptons + nLeptons++; + } else if(pdg == -checkPdgDecay) { + // count anti-leptons + nAntileptons++; + } else if (pdg == checkPdgSignal[0] || pdg == checkPdgSignal[1]) { + if(idMoth < 0) { + // count signal PDG + pdg == checkPdgSignal[0] ? nSignalJpsi++ : nSignalPsi2S++; + // count signal PDG within acceptance + if(rapidity > rapiditymin && rapidity < rapiditymax) { pdg == checkPdgSignal[0] ? nSignalJpsiWithinAcc++ : nSignalPsi2SWithinAcc++;} + } + auto child0 = o2::mcutils::MCTrackNavigator::getDaughter0(track, *tracks); + auto child1 = o2::mcutils::MCTrackNavigator::getDaughter1(track, *tracks); + if (child0 != nullptr && child1 != nullptr) { + // check for parent-child relations + auto pdg0 = child0->GetPdgCode(); + auto pdg1 = child1->GetPdgCode(); + std::cout << "First and last children of parent " << checkPdgSignal << " are PDG0: " << pdg0 << " PDG1: " << pdg1 << "\n"; + if (std::abs(pdg0) == checkPdgDecay && std::abs(pdg1) == checkPdgDecay && pdg0 == -pdg1) { + nLeptonPairs++; + if (child0->getToBeDone() && child1->getToBeDone()) { + nLeptonPairsToBeDone++; + } + } + } + } + } + } + std::cout << "#events: " << nEvents << "\n" + << "#leptons: " << nLeptons << "\n" + << "#antileptons: " << nAntileptons << "\n" + << "#signal (prompt Jpsi): " << nSignalJpsi << "; within acceptance " << rapiditymin << " < y < " << rapiditymax << " : " << nSignalJpsiWithinAcc << "\n" + << "#signal (prompt Psi(2S)): " << nSignalPsi2S << "; within acceptance " << rapiditymin << " < y < " << rapiditymax << " : " << nSignalPsi2SWithinAcc << "\n" + << "#lepton pairs: " << nLeptonPairs << "\n" + << "#lepton pairs to be done: " << nLeptonPairs << "\n"; + + + if (nLeptonPairs == 0 || nLeptons == 0 || nAntileptons == 0) { + std::cerr << "Number of leptons, number of anti-leptons as well as number of lepton pairs should all be greater than 1.\n"; + return 1; + } + if (nLeptonPairs != nLeptonPairsToBeDone) { + std::cerr << "The number of lepton pairs should be the same as the number of lepton pairs which should be transported.\n"; + return 1; + } + + return 0; +} diff --git a/MC/config/PWGDQ/ini/tests/Generator_InjectedPromptCharmoniaFwdy_TriggerGap_pp5TeV.C b/MC/config/PWGDQ/ini/tests/Generator_InjectedPromptCharmoniaFwdy_TriggerGap_pp5TeV.C new file mode 100644 index 000000000..5dd26f49d --- /dev/null +++ b/MC/config/PWGDQ/ini/tests/Generator_InjectedPromptCharmoniaFwdy_TriggerGap_pp5TeV.C @@ -0,0 +1,85 @@ +int External() +{ + int checkPdgSignal[] = {443,100443}; + int checkPdgDecay = 13; + double rapiditymin = -4.3; double rapiditymax = -2.3; + std::string path{"o2sim_Kine.root"}; + std::cout << "Check for\nsignal PDG " << checkPdgSignal << "\ndecay PDG " << checkPdgDecay << "\n"; + TFile file(path.c_str(), "READ"); + if (file.IsZombie()) { + std::cerr << "Cannot open ROOT file " << path << "\n"; + return 1; + } + + auto tree = (TTree*)file.Get("o2sim"); + std::vector* tracks{}; + tree->SetBranchAddress("MCTrack", &tracks); + + int nLeptons{}; + int nAntileptons{}; + int nLeptonPairs{}; + int nLeptonPairsToBeDone{}; + int nSignalJpsi{}; + int nSignalPsi2S{}; + int nSignalJpsiWithinAcc{}; + int nSignalPsi2SWithinAcc{}; + auto nEvents = tree->GetEntries(); + o2::steer::MCKinematicsReader mcreader("o2sim", o2::steer::MCKinematicsReader::Mode::kMCKine); + Bool_t isInjected = kFALSE; + + for (int i = 0; i < nEvents; i++) { + tree->GetEntry(i); + for (auto& track : *tracks) { + auto pdg = track.GetPdgCode(); + auto rapidity = track.GetRapidity(); + auto idMoth = track.getMotherTrackId(); + if (pdg == checkPdgDecay) { + // count leptons + nLeptons++; + } else if(pdg == -checkPdgDecay) { + // count anti-leptons + nAntileptons++; + } else if (pdg == checkPdgSignal[0] || pdg == checkPdgSignal[1]) { + if(idMoth < 0) { + // count signal PDG + pdg == checkPdgSignal[0] ? nSignalJpsi++ : nSignalPsi2S++; + // count signal PDG within acceptance + if(rapidity > rapiditymin && rapidity < rapiditymax) { pdg == checkPdgSignal[0] ? nSignalJpsiWithinAcc++ : nSignalPsi2SWithinAcc++;} + } + auto child0 = o2::mcutils::MCTrackNavigator::getDaughter0(track, *tracks); + auto child1 = o2::mcutils::MCTrackNavigator::getDaughter1(track, *tracks); + if (child0 != nullptr && child1 != nullptr) { + // check for parent-child relations + auto pdg0 = child0->GetPdgCode(); + auto pdg1 = child1->GetPdgCode(); + std::cout << "First and last children of parent " << checkPdgSignal << " are PDG0: " << pdg0 << " PDG1: " << pdg1 << "\n"; + if (std::abs(pdg0) == checkPdgDecay && std::abs(pdg1) == checkPdgDecay && pdg0 == -pdg1) { + nLeptonPairs++; + if (child0->getToBeDone() && child1->getToBeDone()) { + nLeptonPairsToBeDone++; + } + } + } + } + } + } + std::cout << "#events: " << nEvents << "\n" + << "#leptons: " << nLeptons << "\n" + << "#antileptons: " << nAntileptons << "\n" + << "#signal (prompt Jpsi): " << nSignalJpsi << "; within acceptance " << rapiditymin << " < y < " << rapiditymax << " : " << nSignalJpsiWithinAcc << "\n" + << "#signal (prompt Psi(2S)): " << nSignalPsi2S << "; within acceptance " << rapiditymin << " < y < " << rapiditymax << " : " << nSignalPsi2SWithinAcc << "\n" + << "#lepton pairs: " << nLeptonPairs << "\n" + << "#lepton pairs to be done: " << nLeptonPairs << "\n"; + + + if (nLeptonPairs == 0 || nLeptons == 0 || nAntileptons == 0) { + std::cerr << "Number of leptons, number of anti-leptons as well as number of lepton pairs should all be greater than 1.\n"; + return 1; + } + if (nLeptonPairs != nLeptonPairsToBeDone) { + std::cerr << "The number of lepton pairs should be the same as the number of lepton pairs which should be transported.\n"; + return 1; + } + + return 0; +} diff --git a/MC/config/PWGDQ/ini/tests/Generator_InjectedPromptCharmoniaMidy_TriggerGap_2_OO5TeV.C b/MC/config/PWGDQ/ini/tests/Generator_InjectedPromptCharmoniaMidy_TriggerGap_2_OO5TeV.C new file mode 100644 index 000000000..b155ec9ac --- /dev/null +++ b/MC/config/PWGDQ/ini/tests/Generator_InjectedPromptCharmoniaMidy_TriggerGap_2_OO5TeV.C @@ -0,0 +1,84 @@ +int External() +{ + int checkPdgSignal[] = {443,100443}; + int checkPdgDecay = 11; + std::string path{"o2sim_Kine.root"}; + std::cout << "Check for\nsignal PDG " << checkPdgSignal << "\ndecay PDG " << checkPdgDecay << "\n"; + TFile file(path.c_str(), "READ"); + if (file.IsZombie()) { + std::cerr << "Cannot open ROOT file " << path << "\n"; + return 1; + } + + auto tree = (TTree*)file.Get("o2sim"); + std::vector* tracks{}; + tree->SetBranchAddress("MCTrack", &tracks); + + int nLeptons{}; + int nAntileptons{}; + int nLeptonPairs{}; + int nLeptonPairsToBeDone{}; + int nSignalJpsi{}; + int nSignalPsi2S{}; + int nSignalJpsiWithinAcc{}; + int nSignalPsi2SWithinAcc{}; + auto nEvents = tree->GetEntries(); + o2::steer::MCKinematicsReader mcreader("o2sim", o2::steer::MCKinematicsReader::Mode::kMCKine); + Bool_t isInjected = kFALSE; + + for (int i = 0; i < nEvents; i++) { + tree->GetEntry(i); + for (auto& track : *tracks) { + auto pdg = track.GetPdgCode(); + auto rapidity = track.GetRapidity(); + auto idMoth = track.getMotherTrackId(); + if (pdg == checkPdgDecay) { + // count leptons + nLeptons++; + } else if(pdg == -checkPdgDecay) { + // count anti-leptons + nAntileptons++; + } else if (pdg == checkPdgSignal[0] || pdg == checkPdgSignal[1]) { + if(idMoth < 0){ + // count signal PDG + pdg == checkPdgSignal[0] ? nSignalJpsi++ : nSignalPsi2S++; + // count signal PDG within acceptance + if(std::abs(rapidity) < 1.0) { pdg == checkPdgSignal[0] ? nSignalJpsiWithinAcc++ : nSignalPsi2SWithinAcc++;} + } + auto child0 = o2::mcutils::MCTrackNavigator::getDaughter0(track, *tracks); + auto child1 = o2::mcutils::MCTrackNavigator::getDaughter1(track, *tracks); + if (child0 != nullptr && child1 != nullptr) { + // check for parent-child relations + auto pdg0 = child0->GetPdgCode(); + auto pdg1 = child1->GetPdgCode(); + std::cout << "First and last children of parent " << checkPdgSignal << " are PDG0: " << pdg0 << " PDG1: " << pdg1 << "\n"; + if (std::abs(pdg0) == checkPdgDecay && std::abs(pdg1) == checkPdgDecay && pdg0 == -pdg1) { + nLeptonPairs++; + if (child0->getToBeDone() && child1->getToBeDone()) { + nLeptonPairsToBeDone++; + } + } + } + } + } + } + std::cout << "#events: " << nEvents << "\n" + << "#leptons: " << nLeptons << "\n" + << "#antileptons: " << nAntileptons << "\n" + << "#signal (prompt Jpsi): " << nSignalJpsi << "; within acceptance (|y| < 1): " << nSignalJpsiWithinAcc << "\n" + << "#signal (prompt Psi(2S)): " << nSignalPsi2S << "; within acceptance (|y| < 1): " << nSignalPsi2SWithinAcc << "\n" + << "#lepton pairs: " << nLeptonPairs << "\n" + << "#lepton pairs to be done: " << nLeptonPairs << "\n"; + + + if (nLeptonPairs == 0 || nLeptons == 0 || nAntileptons == 0) { + std::cerr << "Number of leptons, number of anti-leptons as well as number of lepton pairs should all be greater than 1.\n"; + return 1; + } + if (nLeptonPairs != nLeptonPairsToBeDone) { + std::cerr << "The number of lepton pairs should be the same as the number of lepton pairs which should be transported.\n"; + return 1; + } + + return 0; +} diff --git a/MC/config/PWGDQ/ini/tests/Generator_InjectedPromptCharmoniaMidy_TriggerGap_OO5TeV.C b/MC/config/PWGDQ/ini/tests/Generator_InjectedPromptCharmoniaMidy_TriggerGap_OO5TeV.C new file mode 100644 index 000000000..b155ec9ac --- /dev/null +++ b/MC/config/PWGDQ/ini/tests/Generator_InjectedPromptCharmoniaMidy_TriggerGap_OO5TeV.C @@ -0,0 +1,84 @@ +int External() +{ + int checkPdgSignal[] = {443,100443}; + int checkPdgDecay = 11; + std::string path{"o2sim_Kine.root"}; + std::cout << "Check for\nsignal PDG " << checkPdgSignal << "\ndecay PDG " << checkPdgDecay << "\n"; + TFile file(path.c_str(), "READ"); + if (file.IsZombie()) { + std::cerr << "Cannot open ROOT file " << path << "\n"; + return 1; + } + + auto tree = (TTree*)file.Get("o2sim"); + std::vector* tracks{}; + tree->SetBranchAddress("MCTrack", &tracks); + + int nLeptons{}; + int nAntileptons{}; + int nLeptonPairs{}; + int nLeptonPairsToBeDone{}; + int nSignalJpsi{}; + int nSignalPsi2S{}; + int nSignalJpsiWithinAcc{}; + int nSignalPsi2SWithinAcc{}; + auto nEvents = tree->GetEntries(); + o2::steer::MCKinematicsReader mcreader("o2sim", o2::steer::MCKinematicsReader::Mode::kMCKine); + Bool_t isInjected = kFALSE; + + for (int i = 0; i < nEvents; i++) { + tree->GetEntry(i); + for (auto& track : *tracks) { + auto pdg = track.GetPdgCode(); + auto rapidity = track.GetRapidity(); + auto idMoth = track.getMotherTrackId(); + if (pdg == checkPdgDecay) { + // count leptons + nLeptons++; + } else if(pdg == -checkPdgDecay) { + // count anti-leptons + nAntileptons++; + } else if (pdg == checkPdgSignal[0] || pdg == checkPdgSignal[1]) { + if(idMoth < 0){ + // count signal PDG + pdg == checkPdgSignal[0] ? nSignalJpsi++ : nSignalPsi2S++; + // count signal PDG within acceptance + if(std::abs(rapidity) < 1.0) { pdg == checkPdgSignal[0] ? nSignalJpsiWithinAcc++ : nSignalPsi2SWithinAcc++;} + } + auto child0 = o2::mcutils::MCTrackNavigator::getDaughter0(track, *tracks); + auto child1 = o2::mcutils::MCTrackNavigator::getDaughter1(track, *tracks); + if (child0 != nullptr && child1 != nullptr) { + // check for parent-child relations + auto pdg0 = child0->GetPdgCode(); + auto pdg1 = child1->GetPdgCode(); + std::cout << "First and last children of parent " << checkPdgSignal << " are PDG0: " << pdg0 << " PDG1: " << pdg1 << "\n"; + if (std::abs(pdg0) == checkPdgDecay && std::abs(pdg1) == checkPdgDecay && pdg0 == -pdg1) { + nLeptonPairs++; + if (child0->getToBeDone() && child1->getToBeDone()) { + nLeptonPairsToBeDone++; + } + } + } + } + } + } + std::cout << "#events: " << nEvents << "\n" + << "#leptons: " << nLeptons << "\n" + << "#antileptons: " << nAntileptons << "\n" + << "#signal (prompt Jpsi): " << nSignalJpsi << "; within acceptance (|y| < 1): " << nSignalJpsiWithinAcc << "\n" + << "#signal (prompt Psi(2S)): " << nSignalPsi2S << "; within acceptance (|y| < 1): " << nSignalPsi2SWithinAcc << "\n" + << "#lepton pairs: " << nLeptonPairs << "\n" + << "#lepton pairs to be done: " << nLeptonPairs << "\n"; + + + if (nLeptonPairs == 0 || nLeptons == 0 || nAntileptons == 0) { + std::cerr << "Number of leptons, number of anti-leptons as well as number of lepton pairs should all be greater than 1.\n"; + return 1; + } + if (nLeptonPairs != nLeptonPairsToBeDone) { + std::cerr << "The number of lepton pairs should be the same as the number of lepton pairs which should be transported.\n"; + return 1; + } + + return 0; +} diff --git a/MC/config/PWGDQ/ini/tests/Generator_InjectedPromptCharmoniaMidy_TriggerGap_pO96TeV.C b/MC/config/PWGDQ/ini/tests/Generator_InjectedPromptCharmoniaMidy_TriggerGap_pO96TeV.C new file mode 100644 index 000000000..b155ec9ac --- /dev/null +++ b/MC/config/PWGDQ/ini/tests/Generator_InjectedPromptCharmoniaMidy_TriggerGap_pO96TeV.C @@ -0,0 +1,84 @@ +int External() +{ + int checkPdgSignal[] = {443,100443}; + int checkPdgDecay = 11; + std::string path{"o2sim_Kine.root"}; + std::cout << "Check for\nsignal PDG " << checkPdgSignal << "\ndecay PDG " << checkPdgDecay << "\n"; + TFile file(path.c_str(), "READ"); + if (file.IsZombie()) { + std::cerr << "Cannot open ROOT file " << path << "\n"; + return 1; + } + + auto tree = (TTree*)file.Get("o2sim"); + std::vector* tracks{}; + tree->SetBranchAddress("MCTrack", &tracks); + + int nLeptons{}; + int nAntileptons{}; + int nLeptonPairs{}; + int nLeptonPairsToBeDone{}; + int nSignalJpsi{}; + int nSignalPsi2S{}; + int nSignalJpsiWithinAcc{}; + int nSignalPsi2SWithinAcc{}; + auto nEvents = tree->GetEntries(); + o2::steer::MCKinematicsReader mcreader("o2sim", o2::steer::MCKinematicsReader::Mode::kMCKine); + Bool_t isInjected = kFALSE; + + for (int i = 0; i < nEvents; i++) { + tree->GetEntry(i); + for (auto& track : *tracks) { + auto pdg = track.GetPdgCode(); + auto rapidity = track.GetRapidity(); + auto idMoth = track.getMotherTrackId(); + if (pdg == checkPdgDecay) { + // count leptons + nLeptons++; + } else if(pdg == -checkPdgDecay) { + // count anti-leptons + nAntileptons++; + } else if (pdg == checkPdgSignal[0] || pdg == checkPdgSignal[1]) { + if(idMoth < 0){ + // count signal PDG + pdg == checkPdgSignal[0] ? nSignalJpsi++ : nSignalPsi2S++; + // count signal PDG within acceptance + if(std::abs(rapidity) < 1.0) { pdg == checkPdgSignal[0] ? nSignalJpsiWithinAcc++ : nSignalPsi2SWithinAcc++;} + } + auto child0 = o2::mcutils::MCTrackNavigator::getDaughter0(track, *tracks); + auto child1 = o2::mcutils::MCTrackNavigator::getDaughter1(track, *tracks); + if (child0 != nullptr && child1 != nullptr) { + // check for parent-child relations + auto pdg0 = child0->GetPdgCode(); + auto pdg1 = child1->GetPdgCode(); + std::cout << "First and last children of parent " << checkPdgSignal << " are PDG0: " << pdg0 << " PDG1: " << pdg1 << "\n"; + if (std::abs(pdg0) == checkPdgDecay && std::abs(pdg1) == checkPdgDecay && pdg0 == -pdg1) { + nLeptonPairs++; + if (child0->getToBeDone() && child1->getToBeDone()) { + nLeptonPairsToBeDone++; + } + } + } + } + } + } + std::cout << "#events: " << nEvents << "\n" + << "#leptons: " << nLeptons << "\n" + << "#antileptons: " << nAntileptons << "\n" + << "#signal (prompt Jpsi): " << nSignalJpsi << "; within acceptance (|y| < 1): " << nSignalJpsiWithinAcc << "\n" + << "#signal (prompt Psi(2S)): " << nSignalPsi2S << "; within acceptance (|y| < 1): " << nSignalPsi2SWithinAcc << "\n" + << "#lepton pairs: " << nLeptonPairs << "\n" + << "#lepton pairs to be done: " << nLeptonPairs << "\n"; + + + if (nLeptonPairs == 0 || nLeptons == 0 || nAntileptons == 0) { + std::cerr << "Number of leptons, number of anti-leptons as well as number of lepton pairs should all be greater than 1.\n"; + return 1; + } + if (nLeptonPairs != nLeptonPairsToBeDone) { + std::cerr << "The number of lepton pairs should be the same as the number of lepton pairs which should be transported.\n"; + return 1; + } + + return 0; +} diff --git a/MC/config/PWGDQ/ini/tests/Generator_InjectedPromptJpsiFwdy_PythiaOnia_TriggerGap_pp5TeV.C b/MC/config/PWGDQ/ini/tests/Generator_InjectedPromptJpsiFwdy_PythiaOnia_TriggerGap_pp5TeV.C new file mode 100644 index 000000000..2b75fcdbd --- /dev/null +++ b/MC/config/PWGDQ/ini/tests/Generator_InjectedPromptJpsiFwdy_PythiaOnia_TriggerGap_pp5TeV.C @@ -0,0 +1,82 @@ +int External() +{ + int checkPdgSignal[] = {443}; + int checkPdgDecay = 13; + double rapiditymin = -4.3; double rapiditymax = -2.3; + std::string path{"o2sim_Kine.root"}; + std::cout << "Check for\nsignal PDG " << checkPdgSignal[0] << "\n decay PDG " << checkPdgDecay << "\n"; + TFile file(path.c_str(), "READ"); + if (file.IsZombie()) { + std::cerr << "Cannot open ROOT file " << path << "\n"; + return 1; + } + + auto tree = (TTree*)file.Get("o2sim"); + std::vector* tracks{}; + tree->SetBranchAddress("MCTrack", &tracks); + + int nLeptons{}; + int nAntileptons{}; + int nLeptonPairs{}; + int nLeptonPairsToBeDone{}; + int nSignalJpsi{}; + int nSignalJpsiWithinAcc{}; + auto nEvents = tree->GetEntries(); + o2::steer::MCKinematicsReader mcreader("o2sim", o2::steer::MCKinematicsReader::Mode::kMCKine); + Bool_t isInjected = kFALSE; + + for (int i = 0; i < nEvents; i++) { + tree->GetEntry(i); + for (auto& track : *tracks) { + auto pdg = track.GetPdgCode(); + auto rapidity = track.GetRapidity(); + auto idMoth = track.getMotherTrackId(); + if (pdg == checkPdgDecay) { + // count leptons + nLeptons++; + } else if(pdg == -checkPdgDecay) { + // count anti-leptons + nAntileptons++; + } else if (pdg == checkPdgSignal[0]) { + if(idMoth < 0){ + // count signal PDG + nSignalJpsi++; + // count signal PDG within acceptance + if(rapidity > rapiditymin && rapidity < rapiditymax) nSignalJpsiWithinAcc++; + } + auto child0 = o2::mcutils::MCTrackNavigator::getDaughter0(track, *tracks); + auto child1 = o2::mcutils::MCTrackNavigator::getDaughter1(track, *tracks); + if (child0 != nullptr && child1 != nullptr) { + // check for parent-child relations + auto pdg0 = child0->GetPdgCode(); + auto pdg1 = child1->GetPdgCode(); + std::cout << "First and last children of parent " << checkPdgSignal << " are PDG0: " << pdg0 << " PDG1: " << pdg1 << "\n"; + if (std::abs(pdg0) == checkPdgDecay && std::abs(pdg1) == checkPdgDecay && pdg0 == -pdg1) { + nLeptonPairs++; + if (child0->getToBeDone() && child1->getToBeDone()) { + nLeptonPairsToBeDone++; + } + } + } + } + } + } + std::cout << "#events: " << nEvents << "\n" + << "#leptons: " << nLeptons << "\n" + << "#antileptons: " << nAntileptons << "\n" + << "#signal (prompt Jpsi): " << nSignalJpsi << "; within acceptance " << rapiditymin << " < y < " << rapiditymax << " : " << nSignalJpsiWithinAcc << "\n" + << "#lepton pairs: " << nLeptonPairs << "\n" + << "#lepton pairs to be done: " << nLeptonPairs << "\n"; + + + if (nLeptonPairs == 0 || nLeptons == 0 || nAntileptons == 0) { + std::cerr << "Number of leptons, number of anti-leptons as well as number of lepton pairs should all be greater than 1.\n"; + return 1; + } + if (nLeptonPairs != nLeptonPairsToBeDone) { + std::cerr << "The number of lepton pairs should be the same as the number of lepton pairs which should be transported.\n"; + return 1; + } + + return 0; +} diff --git a/MC/config/PWGDQ/pythia8/generator/pythia8_hf_OO_536.cfg b/MC/config/PWGDQ/pythia8/generator/pythia8_hf_OO_536.cfg new file mode 100644 index 000000000..c2f4e063d --- /dev/null +++ b/MC/config/PWGDQ/pythia8/generator/pythia8_hf_OO_536.cfg @@ -0,0 +1,19 @@ +### OO beams +Beams:idA = 1000080160 +Beams:idB = 1000080160 +Beams:eCM = 5360.0 ### energy + +Beams:frameType = 1 +ParticleDecays:limitTau0 = on +ParticleDecays:tau0Max = 10. ### match alice: 1cm/c = 10.0mm/c + +### Save some CPU at init of jobs +### To avoid refitting, add the following lines to your configuration file: +HeavyIon:SigFitNGen = 0 +HeavyIon:SigFitDefPar = 2.15,18.42,0.33 + +Random:setSeed = on + +### processes +HardQCD:hardccbar on # scatterings g-g / q-qbar -> c-cbar +HardQCD:hardbbbar on # scatterings g-g / q-qbar -> b-bbar diff --git a/MC/config/PWGDQ/pythia8/generator/pythia8_hf_pO_961.cfg b/MC/config/PWGDQ/pythia8/generator/pythia8_hf_pO_961.cfg new file mode 100644 index 000000000..4a1b25f2e --- /dev/null +++ b/MC/config/PWGDQ/pythia8/generator/pythia8_hf_pO_961.cfg @@ -0,0 +1,19 @@ +### OO beams +Beams:frameType 2 # back-to-back beams of different energies and particles +Beams:idA 2212 # proton +Beams:idB 1000080160 # Oxygen +Beams:eA 6800. # Energy of proton beam in GeV moving in the +z direction +Beams:eB 3400. # Energy in GeV per Oxygen nucleon (6.8 Z TeV) moving in the -z direction + +ParticleDecays:limitTau0 = on +ParticleDecays:tau0Max = 10. ### match alice: 1cm/c = 10.0mm/c + +### To avoid refitting, add the following lines to your configuration file: +HeavyIon:SigFitNGen = 0 +HeavyIon:SigFitDefPar = 2.17,17.56,0.30 + +Random:setSeed = on + +### processes +HardQCD:hardccbar on # scatterings g-g / q-qbar -> c-cbar +HardQCD:hardbbbar on # scatterings g-g / q-qbar -> b-bbar diff --git a/MC/config/PWGDQ/pythia8/generator/pythia8_inel_triggerGap_OO5TeV.cfg b/MC/config/PWGDQ/pythia8/generator/pythia8_inel_triggerGap_OO5TeV.cfg new file mode 100644 index 000000000..ff4c5ae6f --- /dev/null +++ b/MC/config/PWGDQ/pythia8/generator/pythia8_inel_triggerGap_OO5TeV.cfg @@ -0,0 +1,16 @@ +### beams +Beams:idA 1000080160 # oxygen +Beams:idB 1000080160 # oxygen +Beams:eCM 5360. # GeV +Beams:frameType = 1 + +### processes +SoftQCD:inelastic on # all inelastic processes + +### decays +ParticleDecays:limitTau0 on +ParticleDecays:tau0Max 10. + +#### Heavy ion settings +HeavyIon:SigFitErr = 0.02,0.02,0.1,0.05,0.05,0.0,0.1,0.0 +HeavyIon:SigFitDefPar = 17.24,2.15,0.33,0.0,0.0,0.0,0.0,0.0 \ No newline at end of file diff --git a/MC/config/PWGDQ/pythia8/generator/pythia8_onia_triggerGap_pp5TeV.cfg b/MC/config/PWGDQ/pythia8/generator/pythia8_onia_triggerGap_pp5TeV.cfg new file mode 100644 index 000000000..3b4d393b4 --- /dev/null +++ b/MC/config/PWGDQ/pythia8/generator/pythia8_onia_triggerGap_pp5TeV.cfg @@ -0,0 +1,12 @@ +### beams +Beams:idA 2212 # proton +Beams:idB 2212 # proton +Beams:eCM 5360. # GeV + +### processes +SoftQCD:inelastic on # all inelastic processes +CharmoniumShower:all = on + +### decays +ParticleDecays:limitTau0 on +ParticleDecays:tau0Max 10. diff --git a/MC/config/PWGEM/decaytables/decaytable_LMee.dat b/MC/config/PWGEM/decaytables/decaytable_LMee.dat index 23276c76c..03f88f65a 100644 --- a/MC/config/PWGEM/decaytables/decaytable_LMee.dat +++ b/MC/config/PWGEM/decaytables/decaytable_LMee.dat @@ -279,66 +279,67 @@ 1 2 0.011740 22 -11 11 0 0 1 0 0.000000 -11 11 -11 11 0 1 0 0.000000 -11 11 0 0 0 - 221 eta 0 0 0 0.54786 0.000001 0.00000 1.50886E-07 0 1 - 1 0 0.394074 22 22 0 0 0 - 1 0 0.326777 111 111 111 0 0 - 1 0 0.000256 111 22 22 0 0 - 1 0 0.229189 211 -211 111 0 0 - 1 0 0.042199 22 211 -211 0 0 - 1 2 0.006899 22 11 -11 0 0 - 1 0 0.000309 22 13 -13 0 0 - 1 0 0.000006 -13 13 0 0 0 - 1 0 0.000000 -11 11 -11 11 0 - 1 0 0.000000 211 -211 11 -11 0 - 331 eta' 0 0 0 0.95778 0.000197 0.002 1.00336E-09 0 1 - 1 0 0.428744 211 -211 221 0 0 - 1 0 0.290822 22 113 0 0 0 - 1 0 0.221809 111 111 221 0 0 - 1 0 0.027458 22 223 0 0 0 - 1 0 0.000200 223 -11 11 0 0 - 1 0 0.021980 22 22 0 0 0 - 1 0 0.002136 111 111 111 0 0 - 1 0 0.000108 22 -13 13 0 0 - 1 0 0.003794 211 -211 111 0 0 - 1 0 0.000001 211 -211 211 -211 0 - 1 0 0.000180 211 -211 111 111 0 - 1 0 0.000000 211 -211 -11 11 0 - 1 2 0.000473 22 11 -11 0 0 - 1 0 0.000000 -11 11 -11 11 0 - 113 rho0 0 0 0 0.77526 0.149100 0.40000 1.33000E-12 0 1 + 221 eta 0 0 0 0.54786 0.001308 0.00000 1.50886E-07 0 1 + 1 0 0.393588 22 22 0 0 0 + 1 0 0.325618 111 111 111 0 0 + 1 0 0.000255 111 22 22 0 0 + 1 0 0.230188 211 -211 111 0 0 + 1 0 0.042769 22 211 -211 0 0 + 1 2 0.007004 22 11 -11 0 0 + 1 0 0.000310 22 13 -13 0 0 + 1 0 0.000006 -13 13 0 0 0 + 1 0 0.000001 -11 11 0 0 0 + 1 0 0.000000 -11 11 -11 11 0 + 1 0 0.000000 211 -211 11 -11 0 + 331 eta' 0 0 0 0.95778 0.000188 0.002 1.00336E-09 0 1 + 1 0 0.424687 211 -211 221 0 0 + 1 0 0.294809 22 113 0 0 0 + 1 0 0.223714 111 111 221 0 0 + 1 0 0.025190 22 223 0 0 0 + 1 0 0.000197 223 -11 11 0 0 + 1 0 0.023068 22 22 0 0 0 + 1 0 0.002499 111 111 111 0 0 + 1 0 0.000113 22 -13 13 0 0 + 1 0 0.003606 211 -211 111 0 0 + 1 0 0.000001 211 -211 211 -211 0 + 1 0 0.000180 211 -211 111 111 0 + 1 0 0.000000 211 -211 -11 11 0 + 1 2 0.000480 22 11 -11 0 0 + 1 0 0.000000 -11 11 -11 11 0 + 113 rho0 0 0 0 0.77526 0.14739 0.40000 1.33000E-12 0 1 1 3 0.988927 211 -211 0 0 0 1 0 0.009900 211 -211 22 0 0 - 1 0 0.000600 111 22 0 0 0 - 1 0 0.000300 221 22 0 0 0 - 1 0 0.000045 111 111 22 0 0 - 1 0 0.000047 11 -11 0 0 0 - 1 0 0.000046 13 -13 0 0 0 + 1 0 0.000467 111 22 0 0 0 + 1 0 0.000300 221 22 0 0 0 + 1 0 0.000045 111 111 22 0 0 + 1 0 0.000047 11 -11 0 0 0 + 1 0 0.000046 13 -13 0 0 0 1 0 0.000101 211 -211 111 0 0 1 0 0.000018 -211 211 -211 211 0 1 0 0.000016 -211 211 111 111 0 - 223 omega 0 0 0 0.78265 0.008490 0.10000 2.33000E-11 0 1 - 1 1 0.899500 211 -211 111 0 0 - 1 0 0.083500 22 111 0 0 0 - 1 3 0.015380 211 -211 0 0 0 - 1 0 0.000460 221 22 0 0 0 - 1 0 0.000140 111 13 -13 0 0 - 1 0 0.000770 111 11 -11 0 0 - 1 0 0.000074 11 -11 0 0 0 - 1 0 0.000070 111 111 22 0 0 - 1 0 0.000100 13 -13 0 0 0 - 333 phi 0 0 0 1.01946 0.004266 0.01500 4.63000E-11 0 1 - 1 3 0.489092 321 -321 0 0 0 - 1 3 0.342092 130 310 0 0 0 + 223 omega 0 0 0 0.78266 0.00868 0.10000 2.33000E-11 0 1 + 1 1 0.892458 211 -211 111 0 0 + 1 0 0.083264 22 111 0 0 0 + 1 3 0.015349 211 -211 0 0 0 + 1 0 0.000448 221 22 0 0 0 + 1 0 0.000134 111 13 -13 0 0 + 1 0 0.000767 111 11 -11 0 0 + 1 0 0.000074 11 -11 0 0 0 + 1 0 0.000067 111 111 22 0 0 + 1 0 0.000074 13 -13 0 0 0 + 333 phi 0 0 0 1.01946 0.004249 0.01500 4.63000E-11 0 1 + 1 3 0.498884 321 -321 0 0 0 + 1 3 0.336407 130 310 0 0 0 1 0 0.042259 213 -211 0 0 0 1 0 0.042259 -213 211 0 0 0 1 0 0.042259 113 111 0 0 0 1 1 0.026534 211 -211 111 0 0 - 1 0 0.013108 221 22 0 0 0 - 1 0 0.001274 111 22 0 0 0 - 1 0 0.000297 11 -11 0 0 0 - 1 0 0.000283 13 -13 0 0 0 + 1 0 0.013062 221 22 0 0 0 + 1 0 0.001328 111 22 0 0 0 + 1 0 0.000296 11 -11 0 0 0 + 1 0 0.000286 13 -13 0 0 0 1 0 0.000108 221 -11 11 0 0 - 1 0 0.000075 211 -211 0 0 0 + 1 0 0.000095 211 -211 0 0 0 1 0 0.000047 223 111 0 0 0 1 0 0.000041 -211 211 22 0 0 1 0 0.000113 111 111 22 0 0 @@ -346,7 +347,7 @@ 1 0 0.000013 111 -11 11 0 0 1 0 0.000073 111 221 22 0 0 1 0 0.000063 331 22 0 0 0 - 1 0 0.000014 -13 13 22 0 0 + 1 0 0.000014 -13 13 22 0 0 443 J/Psi 0 0 0 3.09690 0.000093 0.00000 2.13000E-09 0 1 1 12 0.881200 82 -82 0 0 0 1 0 0.059710 11 -11 0 0 0 diff --git a/MC/config/PWGEM/external/generator/Generator_pythia8_GapTriggered_DYll.C b/MC/config/PWGEM/external/generator/Generator_pythia8_GapTriggered_DYll.C new file mode 100644 index 000000000..3a1ff8df1 --- /dev/null +++ b/MC/config/PWGEM/external/generator/Generator_pythia8_GapTriggered_DYll.C @@ -0,0 +1,151 @@ +#include "Pythia8/Pythia.h" +#include "Pythia8/HeavyIons.h" +#include "FairGenerator.h" +#include "FairPrimaryGenerator.h" +#include "Generators/GeneratorPythia8.h" +#include "TString.h" +#include "TRandom3.h" +#include "TParticlePDG.h" +#include "TDatabasePDG.h" + +#include +#include + +using namespace Pythia8; + +class GeneratorPythia8GapTriggeredDY : public o2::eventgen::GeneratorPythia8 +{ +public: + /// default constructor + GeneratorPythia8GapTriggeredDY() = default; + + /// constructor + GeneratorPythia8GapTriggeredDY(TString configsignal, int leptonPdg = 11, int lInputTriggerRatio = 5, int lInputExternalID = 1, int idA = 2212, int idB = 2212, float eCM = 13600.0) + { + lGeneratedEvents = 0; + lInverseTriggerRatio = lInputTriggerRatio; + lExternalID = lInputExternalID; + mLeptonPdg = leptonPdg; + + auto seed = (gRandom->TRandom::GetSeed() % 900000000); + + int offset = (int)(gRandom->Uniform(lInverseTriggerRatio)); // create offset to mitigate edge effects due to small number of events per job + lGeneratedEvents += offset; + + cout << "Initalizing extra PYTHIA object used to generate min-bias events..." << endl; + TString pathconfigMB = gSystem->ExpandPathName("${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGEM/pythia8/generator/pythia8_MB_gapevent.cfg"); + pythiaObjectMinimumBias.readFile(pathconfigMB.Data()); + pythiaObjectMinimumBias.readString("Random:setSeed on"); + pythiaObjectMinimumBias.readString("Random:seed " + std::to_string(seed)); + // overwrite basic configration + pythiaObjectMinimumBias.readString(Form("Beams:idA %d", idA)); + pythiaObjectMinimumBias.readString(Form("Beams:idB %d", idB)); + pythiaObjectMinimumBias.readString(Form("Beams:eCM %f", eCM)); + pythiaObjectMinimumBias.init(); + cout << "Initalization complete" << endl; + cout << "Initalizing extra PYTHIA object used to generate signal events..." << endl; + TString pathconfigSignal = gSystem->ExpandPathName(configsignal.Data()); + pythiaObjectSignal.readFile(pathconfigSignal.Data()); + pythiaObjectSignal.readString("Random:setSeed on"); + pythiaObjectSignal.readString("Random:seed " + std::to_string(seed)); + pythiaObjectSignal.readString(Form("23:onIfMatch %d %d", -mLeptonPdg, mLeptonPdg)); + // overwrite basic configration + pythiaObjectSignal.readString(Form("Beams:idA %d", idA)); + pythiaObjectSignal.readString(Form("Beams:idB %d", idB)); + pythiaObjectSignal.readString(Form("Beams:eCM %f", eCM)); + + pythiaObjectSignal.init(); + cout << "Initalization complete" << endl; + addSubGenerator(0, "default generator"); + addSubGenerator(lExternalID, "Drell-Yan"); + } + + /// Destructor + ~GeneratorPythia8GapTriggeredDY() = default; + + void setZRapidity(float yMin, float yMax) + { + mZRapidityMin = yMin; + mZRapidityMax = yMax; + }; + +protected: + //__________________________________________________________________ + Bool_t generateEvent() override + { + /// reset event + mPythia.event.reset(); + + // Simple straightforward check to alternate generators + if (lGeneratedEvents % lInverseTriggerRatio == 0) { + // Generate event of interest + Bool_t lGenerationOK = kFALSE; + while (!lGenerationOK) { + if (pythiaObjectSignal.next()) { + lGenerationOK = selectEvent(pythiaObjectSignal.event); + } + } + mPythia.event = pythiaObjectSignal.event; + notifySubGenerator(lExternalID); + } else { + // Generate minimum-bias event + Bool_t lGenerationOK = kFALSE; + while (!lGenerationOK) { + lGenerationOK = pythiaObjectMinimumBias.next(); + } + mPythia.event = pythiaObjectMinimumBias.event; + notifySubGenerator(0); + } + + lGeneratedEvents++; + // mPythia.next(); + + return true; + } + + bool selectEvent(const Pythia8::Event& event) + { + for (size_t iPart = 0; iPart < event.size(); ++iPart) { + if (event[iPart].id() == 23 && event[iPart].daughterList().size() == 2 && (mZRapidityMin < event[iPart].y() && event[iPart].y() < mZRapidityMax) + && std::abs(event[event[iPart].daughter1()].id()) == mLeptonPdg && std::abs(event[event[iPart].daughter2()].id()) == mLeptonPdg && event[event[iPart].daughter1()].id() * event[event[iPart].daughter2()].id() < 0) { // Z/gamma* -> l+l- + printf("Z/gamma* is found. rapidity = %f, event[iPart].daughterList().size() = %zu\n", event[iPart].y(), event[iPart].daughterList().size()); + printf("event[event[iPart].daughter1()].id() = %d\n", event[event[iPart].daughter1()].id()); + printf("event[event[iPart].daughter2()].id() = %d\n", event[event[iPart].daughter2()].id()); + return true; + } + } // end of particle loop + return false; + }; + +private: + // Interface to override import particles + Pythia8::Event mOutputEvent; + + // Properties of selection + int mLeptonPdg; + float mZRapidityMin; + float mZRapidityMax; + + // Control gap-triggering + Long64_t lGeneratedEvents; + int lInverseTriggerRatio; + // ID for different generators + int lExternalID; + + // Base event generators + Pythia8::Pythia pythiaObjectMinimumBias; ///Minimum bias collision generator + Pythia8::Pythia pythiaObjectSignal; ///Signal collision generator +}; + +// Predefined generators: + +FairGenerator* GeneratorPythia8GapTriggeredDYll(int inputTriggerRatio, int inputExternalID, int pdgLepton = 11, float yMin = -1.5, float yMax = 1.5, int idA = 2212, int idB = 2212, float eCM = 13600.0) +{ + auto myGen = new GeneratorPythia8GapTriggeredDY("${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGEM/pythia8/generator/pythia8_DY.cfg", pdgLepton, inputTriggerRatio, inputExternalID, idA, idB, eCM); + auto seed = (gRandom->TRandom::GetSeed() % 900000000); + myGen->readString("Random:setSeed on"); + myGen->readString("Random:seed " + std::to_string(seed)); + myGen->setZRapidity(yMin, yMax); + return myGen; +} + diff --git a/MC/config/PWGEM/external/generator/Generator_pythia8_GapTriggered_HFLepton_OO.C b/MC/config/PWGEM/external/generator/Generator_pythia8_GapTriggered_HFLepton_OO.C new file mode 100644 index 000000000..439d7e3ce --- /dev/null +++ b/MC/config/PWGEM/external/generator/Generator_pythia8_GapTriggered_HFLepton_OO.C @@ -0,0 +1,227 @@ +#include "Pythia8/Pythia.h" +#include "Pythia8/HeavyIons.h" +#include "FairGenerator.h" +#include "FairPrimaryGenerator.h" +#include "Generators/GeneratorPythia8.h" +#include "TRandom3.h" +#include "TParticlePDG.h" +#include "TDatabasePDG.h" + +#include +#include +//#include // for std::pair + +using namespace Pythia8; + +class GeneratorPythia8GapTriggeredHFLeptonOO : public o2::eventgen::GeneratorPythia8 +{ +public: + /// default constructor + GeneratorPythia8GapTriggeredHFLeptonOO() = default; + + /// constructor + GeneratorPythia8GapTriggeredHFLeptonOO(TString configsignal, int quarkPdg = 4, int lInputTriggerRatio = 5, int lInputExternalID = 0) + { + + lGeneratedEvents = 0; + lInverseTriggerRatio = lInputTriggerRatio; + lExternalID = lInputExternalID; + mQuarkPdg = quarkPdg; + + auto seed = (gRandom->TRandom::GetSeed() % 900000000); + + int offset = (int)(gRandom->Uniform(lInverseTriggerRatio)); // create offset to mitigate edge effects due to small number of events per job + lGeneratedEvents += offset; + + cout << "Initalizing extra PYTHIA object used to generate min-bias events..." << endl; + TString pathconfigMB = gSystem->ExpandPathName("${O2DPG_MC_CONFIG_ROOT}//MC/config/common/pythia8/generator/pythia8_OO_536.cfg"); + pythiaObjectMinimumBias.readFile(pathconfigMB.Data()); + pythiaObjectMinimumBias.readString("Random:setSeed on"); + pythiaObjectMinimumBias.readString("Random:seed " + std::to_string(seed)); + pythiaObjectMinimumBias.init(); + cout << "Initalization of gap event is complete" << endl; + + cout << "Initalizing extra PYTHIA object used to generate signal events..." << endl; + TString pathconfigSignal = gSystem->ExpandPathName(configsignal.Data()); + pythiaObjectSignal.readFile(pathconfigSignal.Data()); + pythiaObjectSignal.readString("Random:setSeed on"); + pythiaObjectSignal.readString("Random:seed " + std::to_string(seed)); + pythiaObjectSignal.init(); + cout << "Initalization of signal event is complete" << endl; + + // flag the generators using type + // addCocktailConstituent(type, "interesting"); + // addCocktailConstitent(0, "minbias"); + // Add Sub generators + addSubGenerator(0, "default generator"); + addSubGenerator(1, "charm lepton"); + addSubGenerator(2, "beauty forced decay"); + addSubGenerator(3, "beauty no foced decay"); + } + + /// Destructor + ~GeneratorPythia8GapTriggeredHFLeptonOO() = default; + + void addTriggerOnDaughter(int nb, int pdg) + { + mNbDaughter = nb; + mPdgDaughter = pdg; + }; + void setQuarkRapidity(float yMin, float yMax) + { + mQuarkRapidityMin = yMin; + mQuarkRapidityMax = yMax; + }; + void setDaughterRapidity(float yMin, float yMax) + { + mDaughterRapidityMin = yMin; + mDaughterRapidityMax = yMax; + }; + +protected: + //__________________________________________________________________ + Bool_t generateEvent() override + { + /// reset event + mPythia.event.reset(); + + // Simple straightforward check to alternate generators + if (lGeneratedEvents % lInverseTriggerRatio == 0) { + // Generate event of interest + Bool_t lGenerationOK = kFALSE; + while (!lGenerationOK) { + if (pythiaObjectSignal.next()) { + lGenerationOK = selectEvent(pythiaObjectSignal.event); + } + } + mPythia.event = pythiaObjectSignal.event; + notifySubGenerator(lExternalID); + } else { + // Generate minimum-bias event + Bool_t lGenerationOK = kFALSE; + while (!lGenerationOK) { + lGenerationOK = pythiaObjectMinimumBias.next(); + } + mPythia.event = pythiaObjectMinimumBias.event; + notifySubGenerator(0); + } + + lGeneratedEvents++; + // mPythia.next(); + + return true; + } + + bool selectEvent(const Pythia8::Event& event) + { + bool isGoodAtPartonLevel = false, isGoodAtDaughterLevel = (mPdgDaughter != 0) ? false : true; + int nbDaughter = 0; + for (auto iPart{0}; iPart < event.size(); ++iPart) { + // search for Q-Qbar mother with at least one Q in rapidity window + if (!isGoodAtPartonLevel) { + auto daughterList = event[iPart].daughterList(); + bool hasQ = false, hasQbar = false, atSelectedY = false; + for (auto iDau : daughterList) { + if (event[iDau].id() == mQuarkPdg) { + hasQ = true; + } + if (event[iDau].id() == -mQuarkPdg) { + hasQbar = true; + } + if ((std::abs(event[iDau].id()) == mQuarkPdg) && (event[iDau].y() > mQuarkRapidityMin) && (event[iDau].y() < mQuarkRapidityMax)) + atSelectedY = true; + } + if (hasQ && hasQbar && atSelectedY) { + isGoodAtPartonLevel = true; + } + } + // search for mNbDaughter daughters of type mPdgDaughter in rapidity window + if (!isGoodAtDaughterLevel) { + int id = std::abs(event[iPart].id()); + float rap = event[iPart].y(); + if (id == mPdgDaughter) { + int motherindexa = event[iPart].mother1(); + if (motherindexa > 0) { + int idmother = std::abs(event[motherindexa].id()); + if (int(std::abs(idmother) / 100.) == 4 || int(std::abs(idmother) / 1000.) == 4 || int(std::abs(idmother) / 100.) == 5 || int(std::abs(idmother) / 1000.) == 5) { + if (rap > mDaughterRapidityMin && rap < mDaughterRapidityMax) { + nbDaughter++; + if (nbDaughter >= mNbDaughter) isGoodAtDaughterLevel = true; + } + } + } + } + } + // we send the trigger + if (isGoodAtPartonLevel && isGoodAtDaughterLevel) { + return true; + } + } + return false; + }; + +private: + // Interface to override import particles + Pythia8::Event mOutputEvent; + + // Properties of selection + int mQuarkPdg; + float mQuarkRapidityMin; + float mQuarkRapidityMax; + int mPdgDaughter; + int mNbDaughter; + float mDaughterRapidityMin; + float mDaughterRapidityMax; + + // Control gap-triggering + Long64_t lGeneratedEvents; + int lInverseTriggerRatio; + // ID for different generators + int lExternalID; + + // Base event generators + Pythia8::Pythia pythiaObjectMinimumBias; ///Minimum bias collision generator + Pythia8::Pythia pythiaObjectSignal; ///Signal collision generator +}; + +// Predefined generators: + +// Charm-enriched forced decay +FairGenerator* GeneratorPythia8GapTriggeredCharmLepton(int inputTriggerRatio, int inputExternalID, int pdgLepton, float yMinQ = -1.5, float yMaxQ = 1.5, float yMinL = -1, float yMaxL = 1) +{ + auto myGen = new GeneratorPythia8GapTriggeredHFLeptonOO("${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGEM/pythia8/generator/pythia8_OO_536_ccbar.cfg", 4, inputTriggerRatio, inputExternalID); + auto seed = (gRandom->TRandom::GetSeed() % 900000000); + myGen->readString("Random:setSeed on"); + myGen->readString("Random:seed " + std::to_string(seed)); + myGen->setQuarkRapidity(yMinQ, yMaxQ); + myGen->addTriggerOnDaughter(2, pdgLepton); + myGen->setDaughterRapidity(yMinL, yMaxL); + return myGen; +} + + +// Beauty-enriched forced decay +FairGenerator* GeneratorPythia8GapTriggeredBeautyForcedDecays(int inputTriggerRatio, int inputExternalID, int pdgLepton, float yMinQ = -1.5, float yMaxQ = 1.5, float yMinL = -1, float yMaxL = 1) +{ + auto myGen = new GeneratorPythia8GapTriggeredHFLeptonOO("${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGEM/pythia8/generator/pythia8_bbbar_OO_536_forceddecayscharmbeauty.cfg", 5, inputTriggerRatio, inputExternalID); + auto seed = (gRandom->TRandom::GetSeed() % 900000000); + myGen->readString("Random:setSeed on"); + myGen->readString("Random:seed " + std::to_string(seed)); + myGen->setQuarkRapidity(yMinQ, yMaxQ); + myGen->addTriggerOnDaughter(2, pdgLepton); + myGen->setDaughterRapidity(yMinL, yMaxL); + return myGen; +} + +// Beauty-enriched no forced decay +FairGenerator* GeneratorPythia8GapTriggeredBeautyNoForcedDecays(int inputTriggerRatio, int inputExternalID, int pdgLepton, float yMinQ = -1.5, float yMaxQ = 1.5, float yMinL = -1, float yMaxL = 1) +{ + auto myGen = new GeneratorPythia8GapTriggeredHFLeptonOO("${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGEM/pythia8/generator/pythia8_OO_536_bbbar.cfg", 5, inputTriggerRatio, inputExternalID); + auto seed = (gRandom->TRandom::GetSeed() % 900000000); + myGen->readString("Random:setSeed on"); + myGen->readString("Random:seed " + std::to_string(seed)); + myGen->setQuarkRapidity(yMinQ, yMaxQ); + myGen->addTriggerOnDaughter(2, pdgLepton); + myGen->setDaughterRapidity(yMinL, yMaxL); + return myGen; +} diff --git a/MC/config/PWGEM/external/generator/Generator_pythia8_GapTriggered_HFLepton_pp5360.C b/MC/config/PWGEM/external/generator/Generator_pythia8_GapTriggered_HFLepton_pp5360.C new file mode 100644 index 000000000..3daa246ae --- /dev/null +++ b/MC/config/PWGEM/external/generator/Generator_pythia8_GapTriggered_HFLepton_pp5360.C @@ -0,0 +1,224 @@ +#include "Pythia8/Pythia.h" +#include "Pythia8/HeavyIons.h" +#include "FairGenerator.h" +#include "FairPrimaryGenerator.h" +#include "Generators/GeneratorPythia8.h" +#include "TRandom3.h" +#include "TParticlePDG.h" +#include "TDatabasePDG.h" + +#include +#include +//#include // for std::pair + +using namespace Pythia8; + +class GeneratorPythia8GapTriggeredHFLepton : public o2::eventgen::GeneratorPythia8 +{ +public: + /// default constructor + GeneratorPythia8GapTriggeredHFLepton() = default; + + /// constructor + GeneratorPythia8GapTriggeredHFLepton(TString configsignal, int quarkPdg = 4, int lInputTriggerRatio = 5, int lInputExternalID = 0) + { + + lGeneratedEvents = 0; + lInverseTriggerRatio = lInputTriggerRatio; + lExternalID = lInputExternalID; + mQuarkPdg = quarkPdg; + + auto seed = (gRandom->TRandom::GetSeed() % 900000000); + + int offset = (int)(gRandom->Uniform(lInverseTriggerRatio)); // create offset to mitigate edge effects due to small number of events per job + lGeneratedEvents += offset; + + cout << "Initalizing extra PYTHIA object used to generate min-bias events..." << endl; + TString pathconfigMB = gSystem->ExpandPathName("${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGEM/pythia8/generator/pythia8_pp_5360_MB_gapevent.cfg"); + pythiaObjectMinimumBias.readFile(pathconfigMB.Data()); + pythiaObjectMinimumBias.readString("Random:setSeed on"); + pythiaObjectMinimumBias.readString("Random:seed " + std::to_string(seed)); + pythiaObjectMinimumBias.init(); + cout << "Initalization complete" << endl; + cout << "Initalizing extra PYTHIA object used to generate signal events..." << endl; + TString pathconfigSignal = gSystem->ExpandPathName(configsignal.Data()); + pythiaObjectSignal.readFile(pathconfigSignal.Data()); + pythiaObjectSignal.readString("Random:setSeed on"); + pythiaObjectSignal.readString("Random:seed " + std::to_string(seed)); + pythiaObjectSignal.init(); + cout << "Initalization complete" << endl; + // flag the generators using type + // addCocktailConstituent(type, "interesting"); + // addCocktailConstitent(0, "minbias"); + // Add Sub generators + addSubGenerator(0, "default generator"); + addSubGenerator(1, "charm lepton"); + addSubGenerator(2, "beauty forced decay"); + addSubGenerator(3, "beauty no foced decay"); + } + + /// Destructor + ~GeneratorPythia8GapTriggeredHFLepton() = default; + + void addTriggerOnDaughter(int nb, int pdg) + { + mNbDaughter = nb; + mPdgDaughter = pdg; + }; + void setQuarkRapidity(float yMin, float yMax) + { + mQuarkRapidityMin = yMin; + mQuarkRapidityMax = yMax; + }; + void setDaughterRapidity(float yMin, float yMax) + { + mDaughterRapidityMin = yMin; + mDaughterRapidityMax = yMax; + }; + +protected: + //__________________________________________________________________ + Bool_t generateEvent() override + { + /// reset event + mPythia.event.reset(); + + // Simple straightforward check to alternate generators + if (lGeneratedEvents % lInverseTriggerRatio == 0) { + // Generate event of interest + Bool_t lGenerationOK = kFALSE; + while (!lGenerationOK) { + if (pythiaObjectSignal.next()) { + lGenerationOK = selectEvent(pythiaObjectSignal.event); + } + } + mPythia.event = pythiaObjectSignal.event; + notifySubGenerator(lExternalID); + } else { + // Generate minimum-bias event + Bool_t lGenerationOK = kFALSE; + while (!lGenerationOK) { + lGenerationOK = pythiaObjectMinimumBias.next(); + } + mPythia.event = pythiaObjectMinimumBias.event; + notifySubGenerator(0); + } + + lGeneratedEvents++; + // mPythia.next(); + + return true; + } + + bool selectEvent(const Pythia8::Event& event) + { + bool isGoodAtPartonLevel = false, isGoodAtDaughterLevel = (mPdgDaughter != 0) ? false : true; + int nbDaughter = 0; + for (auto iPart{0}; iPart < event.size(); ++iPart) { + // search for Q-Qbar mother with at least one Q in rapidity window + if (!isGoodAtPartonLevel) { + auto daughterList = event[iPart].daughterList(); + bool hasQ = false, hasQbar = false, atSelectedY = false; + for (auto iDau : daughterList) { + if (event[iDau].id() == mQuarkPdg) { + hasQ = true; + } + if (event[iDau].id() == -mQuarkPdg) { + hasQbar = true; + } + if ((std::abs(event[iDau].id()) == mQuarkPdg) && (event[iDau].y() > mQuarkRapidityMin) && (event[iDau].y() < mQuarkRapidityMax)) + atSelectedY = true; + } + if (hasQ && hasQbar && atSelectedY) { + isGoodAtPartonLevel = true; + } + } + // search for mNbDaughter daughters of type mPdgDaughter in rapidity window + if (!isGoodAtDaughterLevel) { + int id = std::abs(event[iPart].id()); + float rap = event[iPart].y(); + if (id == mPdgDaughter) { + int motherindexa = event[iPart].mother1(); + if (motherindexa > 0) { + int idmother = std::abs(event[motherindexa].id()); + if (int(std::abs(idmother) / 100.) == 4 || int(std::abs(idmother) / 1000.) == 4 || int(std::abs(idmother) / 100.) == 5 || int(std::abs(idmother) / 1000.) == 5) { + if (rap > mDaughterRapidityMin && rap < mDaughterRapidityMax) { + nbDaughter++; + if (nbDaughter >= mNbDaughter) isGoodAtDaughterLevel = true; + } + } + } + } + } + // we send the trigger + if (isGoodAtPartonLevel && isGoodAtDaughterLevel) { + return true; + } + } + return false; + }; + +private: + // Interface to override import particles + Pythia8::Event mOutputEvent; + + // Properties of selection + int mQuarkPdg; + float mQuarkRapidityMin; + float mQuarkRapidityMax; + int mPdgDaughter; + int mNbDaughter; + float mDaughterRapidityMin; + float mDaughterRapidityMax; + + // Control gap-triggering + Long64_t lGeneratedEvents; + int lInverseTriggerRatio; + // ID for different generators + int lExternalID; + + // Base event generators + Pythia8::Pythia pythiaObjectMinimumBias; ///Minimum bias collision generator + Pythia8::Pythia pythiaObjectSignal; ///Signal collision generator +}; + +// Predefined generators: + +// Charm-enriched forced decay +FairGenerator* GeneratorPythia8GapTriggeredCharmLepton(int inputTriggerRatio, int inputExternalID, float yMin = -1.5, float yMax = 1.5) +{ + auto myGen = new GeneratorPythia8GapTriggeredHFLepton("${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGEM/pythia8/generator/pythia8_pp_5360_cr2_forceddecayscharm.cfg", 4, inputTriggerRatio, inputExternalID); + auto seed = (gRandom->TRandom::GetSeed() % 900000000); + myGen->readString("Random:setSeed on"); + myGen->readString("Random:seed " + std::to_string(seed)); + myGen->setQuarkRapidity(yMin, yMax); + myGen->addTriggerOnDaughter(2, 11); + myGen->setDaughterRapidity(-1., 1.); + return myGen; +} + +// Beauty-enriched forced decay +FairGenerator* GeneratorPythia8GapTriggeredBeautyForcedDecays(int inputTriggerRatio, int inputExternalID, float yMin = -1.5, float yMax = 1.5) +{ + auto myGen = new GeneratorPythia8GapTriggeredHFLepton("${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGEM/pythia8/generator/pythia8_pp_5360_bbbar_forceddecayscharmbeauty.cfg", 5, inputTriggerRatio, inputExternalID); + auto seed = (gRandom->TRandom::GetSeed() % 900000000); + myGen->readString("Random:setSeed on"); + myGen->readString("Random:seed " + std::to_string(seed)); + myGen->setQuarkRapidity(yMin, yMax); + myGen->addTriggerOnDaughter(2, 11); + myGen->setDaughterRapidity(-1., 1.); + return myGen; +} + +// Beauty-enriched no forced decay +FairGenerator* GeneratorPythia8GapTriggeredBeautyNoForcedDecays(int inputTriggerRatio, int inputExternalID, float yMin = -1.5, float yMax = 1.5) +{ + auto myGen = new GeneratorPythia8GapTriggeredHFLepton("${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGEM/pythia8/generator/pythia8_pp_5360_bbbar.cfg", 5, inputTriggerRatio, inputExternalID); + auto seed = (gRandom->TRandom::GetSeed() % 900000000); + myGen->readString("Random:setSeed on"); + myGen->readString("Random:seed " + std::to_string(seed)); + myGen->setQuarkRapidity(yMin, yMax); + myGen->addTriggerOnDaughter(2, 11); + myGen->setDaughterRapidity(-1., 1.); + return myGen; +} diff --git a/MC/config/PWGEM/external/generator/Generator_pythia8_GapTriggered_LFmumu.C b/MC/config/PWGEM/external/generator/Generator_pythia8_GapTriggered_LFmumu.C index 16bff075a..5fb499d0a 100644 --- a/MC/config/PWGEM/external/generator/Generator_pythia8_GapTriggered_LFmumu.C +++ b/MC/config/PWGEM/external/generator/Generator_pythia8_GapTriggered_LFmumu.C @@ -71,7 +71,7 @@ class GeneratorPythia8GapTriggeredLFmumu : public GeneratorPythia8 { // eta auto geneta = new GeneratorParam(nPart,emlib,GeneratorParamEMlib::kEta,"eta"); // 221 geneta->SetName("eta"); - geneta->SetMomentumRange(0., 25.); + geneta->SetMomentumRange(0., 200.); geneta->SetPtRange(minPt, maxPt); geneta->SetYRange(yMin, yMax); geneta->SetPhiRange(phiMin, phiMax); @@ -86,7 +86,7 @@ class GeneratorPythia8GapTriggeredLFmumu : public GeneratorPythia8 { // etaprime auto genetaprime = new GeneratorParam(nPart,emlib,GeneratorParamEMlib::kEtaprime,"etaprime"); // 331 genetaprime->SetName("etaprime"); - genetaprime->SetMomentumRange(0., 25.); + genetaprime->SetMomentumRange(0., 200.); genetaprime->SetPtRange(minPt, maxPt); genetaprime->SetYRange(yMin, yMax); genetaprime->SetPhiRange(phiMin, phiMax); @@ -101,7 +101,7 @@ class GeneratorPythia8GapTriggeredLFmumu : public GeneratorPythia8 { // rho auto genrho = new GeneratorParam(nPart,emlib,GeneratorParamEMlib::kRho0,"rho"); // 113 genrho->SetName("rho"); - genrho->SetMomentumRange(0., 25.); + genrho->SetMomentumRange(0., 200.); genrho->SetPtRange(minPt, maxPt); genrho->SetYRange(yMin, yMax); genrho->SetPhiRange(phiMin, phiMax); @@ -116,7 +116,7 @@ class GeneratorPythia8GapTriggeredLFmumu : public GeneratorPythia8 { // Omega auto genomega = new GeneratorParam(nPart,emlib,GeneratorParamEMlib::kOmega,"omega"); //223 genomega->SetName("omega"); - genomega->SetMomentumRange(0., 25.); + genomega->SetMomentumRange(0., 200.); genomega->SetPtRange(minPt, maxPt); genomega->SetYRange(yMin, yMax); genomega->SetPhiRange(phiMin, phiMax); @@ -131,7 +131,7 @@ class GeneratorPythia8GapTriggeredLFmumu : public GeneratorPythia8 { // phi auto genphi = new GeneratorParam(nPart,emlib,GeneratorParamEMlib::kPhi,"phi"); //333 genphi->SetName("phi"); - genphi->SetMomentumRange(0., 25.); + genphi->SetMomentumRange(0., 200.); genphi->SetPtRange(minPt, maxPt); genphi->SetYRange(yMin, yMax); genphi->SetPhiRange(phiMin, phiMax); diff --git a/MC/config/PWGEM/external/generator/Generator_pythia8_HFLepton_pp.C b/MC/config/PWGEM/external/generator/Generator_pythia8_HFLepton_pp.C new file mode 100644 index 000000000..854d6ff42 --- /dev/null +++ b/MC/config/PWGEM/external/generator/Generator_pythia8_HFLepton_pp.C @@ -0,0 +1,202 @@ +#include "Pythia8/Pythia.h" +#include "Pythia8/HeavyIons.h" +#include "FairGenerator.h" +#include "FairPrimaryGenerator.h" +#include "Generators/GeneratorPythia8.h" +#include "TRandom3.h" +#include "TParticlePDG.h" +#include "TDatabasePDG.h" + +#include +#include + +using namespace Pythia8; + +class GeneratorPythia8HFLeptonpp : public o2::eventgen::GeneratorPythia8 +{ +public: + /// default constructor + GeneratorPythia8HFLeptonpp() = default; + + /// constructor + GeneratorPythia8HFLeptonpp(TString configsignal, int quarkPdg = 4, int lInputExternalID = 0) + { + + lGeneratedEvents = 0; + lExternalID = lInputExternalID; + mQuarkPdg = quarkPdg; + + auto seed = (gRandom->TRandom::GetSeed() % 900000000); + + int offset = (int)(gRandom->Uniform(1)); // create offset to mitigate edge effects due to small number of events per job + lGeneratedEvents += offset; + + cout << "Initalizing PYTHIA object used to generate signal events..." << endl; + TString pathconfigSignal = gSystem->ExpandPathName(configsignal.Data()); + pythiaObjectSignal.readFile(pathconfigSignal.Data()); + pythiaObjectSignal.readString("Random:setSeed on"); + pythiaObjectSignal.readString("Random:seed " + std::to_string(seed)); + pythiaObjectSignal.readString("Beams:eCM = 5360.0"); + pythiaObjectSignal.init(); + cout << "Initalization of signal event is complete" << endl; + + // flag the generators using type + // addCocktailConstituent(type, "interesting"); + // addCocktailConstitent(0, "minbias"); + // Add Sub generators + addSubGenerator(1, "charm lepton"); + addSubGenerator(2, "beauty forced decay"); + addSubGenerator(3, "beauty no foced decay"); + } + + /// Destructor + ~GeneratorPythia8HFLeptonpp() = default; + + void addTriggerOnDaughter(int nb, int pdg) + { + mNbDaughter = nb; + mPdgDaughter = pdg; + }; + void setQuarkRapidity(float yMin, float yMax) + { + mQuarkRapidityMin = yMin; + mQuarkRapidityMax = yMax; + }; + void setDaughterRapidity(float yMin, float yMax) + { + mDaughterRapidityMin = yMin; + mDaughterRapidityMax = yMax; + }; + +protected: + //__________________________________________________________________ + Bool_t generateEvent() override + { + /// reset event + mPythia.event.reset(); + + // Generate event of interest + Bool_t lGenerationOK = kFALSE; + while (!lGenerationOK) { + if (pythiaObjectSignal.next()) { + lGenerationOK = selectEvent(pythiaObjectSignal.event); + } + } + mPythia.event = pythiaObjectSignal.event; + notifySubGenerator(lExternalID); + + lGeneratedEvents++; + // mPythia.next(); + + return true; + } + + bool selectEvent(const Pythia8::Event& event) + { + bool isGoodAtPartonLevel = false, isGoodAtDaughterLevel = (mPdgDaughter != 0) ? false : true; + int nbDaughter = 0; + for (auto iPart{0}; iPart < event.size(); ++iPart) { + // search for Q-Qbar mother with at least one Q in rapidity window + if (!isGoodAtPartonLevel) { + auto daughterList = event[iPart].daughterList(); + bool hasQ = false, hasQbar = false, atSelectedY = false; + for (auto iDau : daughterList) { + if (event[iDau].id() == mQuarkPdg) { + hasQ = true; + } + if (event[iDau].id() == -mQuarkPdg) { + hasQbar = true; + } + if ((std::abs(event[iDau].id()) == mQuarkPdg) && (event[iDau].y() > mQuarkRapidityMin) && (event[iDau].y() < mQuarkRapidityMax)) + atSelectedY = true; + } + if (hasQ && hasQbar && atSelectedY) { + isGoodAtPartonLevel = true; + } + } + // search for mNbDaughter daughters of type mPdgDaughter in rapidity window + if (!isGoodAtDaughterLevel) { + int id = std::abs(event[iPart].id()); + float rap = event[iPart].y(); + if (id == mPdgDaughter) { + int motherindexa = event[iPart].mother1(); + if (motherindexa > 0) { + int idmother = std::abs(event[motherindexa].id()); + if (int(std::abs(idmother) / 100.) == 4 || int(std::abs(idmother) / 1000.) == 4 || int(std::abs(idmother) / 100.) == 5 || int(std::abs(idmother) / 1000.) == 5) { + if (rap > mDaughterRapidityMin && rap < mDaughterRapidityMax) { + nbDaughter++; + if (nbDaughter >= mNbDaughter) isGoodAtDaughterLevel = true; + } + } + } + } + } + // we send the trigger + if (isGoodAtPartonLevel && isGoodAtDaughterLevel) { + return true; + } + } + return false; + }; + +private: + // Interface to override import particles + Pythia8::Event mOutputEvent; + + // Properties of selection + int mQuarkPdg; + float mQuarkRapidityMin; + float mQuarkRapidityMax; + int mPdgDaughter; + int mNbDaughter; + float mDaughterRapidityMin; + float mDaughterRapidityMax; + + Long64_t lGeneratedEvents; + // ID for different generators + int lExternalID; + + // Base event generators + Pythia8::Pythia pythiaObjectSignal; ///Signal collision generator +}; + +// Predefined generators: + +// Charm-enriched forced decay +FairGenerator* GeneratorPythia8CharmLepton(int inputExternalID, int pdgLepton, float yMinQ = -1.5, float yMaxQ = 1.5, float yMinL = -1, float yMaxL = 1) +{ + auto myGen = new GeneratorPythia8HFLeptonpp("${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGEM/pythia8/generator/pythia8_pp_cr2_forceddecayscharm.cfg", 4, inputExternalID); + auto seed = (gRandom->TRandom::GetSeed() % 900000000); + myGen->readString("Random:setSeed on"); + myGen->readString("Random:seed " + std::to_string(seed)); + myGen->setQuarkRapidity(yMinQ, yMaxQ); + myGen->addTriggerOnDaughter(2, pdgLepton); + myGen->setDaughterRapidity(yMinL, yMaxL); + return myGen; +} + +// Beauty-enriched forced decay +FairGenerator* GeneratorPythia8BeautyForcedDecays(int inputExternalID, int pdgLepton, float yMinQ = -1.5, float yMaxQ = 1.5, float yMinL = -1, float yMaxL = 1) +{ + auto myGen = new GeneratorPythia8HFLeptonpp("${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGEM/pythia8/generator/pythia8_bbbar_forceddecayscharmbeauty.cfg", 5, inputExternalID); + auto seed = (gRandom->TRandom::GetSeed() % 900000000); + myGen->readString("Random:setSeed on"); + myGen->readString("Random:seed " + std::to_string(seed)); + myGen->setQuarkRapidity(yMinQ, yMaxQ); + myGen->addTriggerOnDaughter(2, pdgLepton); + myGen->setDaughterRapidity(yMinL, yMaxL); + return myGen; +} + +// Beauty-enriched no forced decay +FairGenerator* GeneratorPythia8BeautyNoForcedDecays(int inputExternalID, int pdgLepton, float yMinQ = -1.5, float yMaxQ = 1.5, float yMinL = -1, float yMaxL = 1) +{ + auto myGen = new GeneratorPythia8HFLeptonpp("${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGEM/pythia8/generator/pythia8_bbbar.cfg", 5, inputExternalID); + auto seed = (gRandom->TRandom::GetSeed() % 900000000); + myGen->readString("Random:setSeed on"); + myGen->readString("Random:seed " + std::to_string(seed)); + myGen->setQuarkRapidity(yMinQ, yMaxQ); + myGen->addTriggerOnDaughter(2, pdgLepton); + myGen->setDaughterRapidity(yMinL, yMaxL); + return myGen; +} diff --git a/MC/config/PWGEM/external/generator/Generator_pythia8_embed_HFLepton.C b/MC/config/PWGEM/external/generator/Generator_pythia8_embed_HFLepton.C new file mode 100644 index 000000000..fe55587aa --- /dev/null +++ b/MC/config/PWGEM/external/generator/Generator_pythia8_embed_HFLepton.C @@ -0,0 +1,396 @@ +/////////////////////////////////////////////////////////////////////////////// +/// /// +/// HF MC generator for Pb-Pb /// +/// Option 1: generate N PYTHIA events triggered on ccbar and/or bbbar /// +/// to be embedded with a underlying Pb-Pb event /// +/// /// +/////////////////////////////////////////////////////////////////////////////// + +#include "Generator_pythia8_HFLepton_pp.C" + +using namespace Pythia8; + +#include +namespace hf_generators +{ + enum GenType : int { + Charm = 0, // --> GeneratorPythia8CharmLepton: charm enriched + Beauty, // --> GeneratorPythia8BeautyForcedDecays: beauty enriched with forced decays + BeautyNoForcedDecays, // --> GeneratorPythia8BeautyNoForcedDecays: beauty enriched no forced decays + NGenType + }; +} + +class GeneratorPythia8EmbedHFLepton : public o2::eventgen::GeneratorPythia8 +{ +public: + + /// default constructor + GeneratorPythia8EmbedHFLepton() = default; + + /// Destructor + ~GeneratorPythia8EmbedHFLepton() { + // Clean up the internally created HF generator if any + if (mGeneratorEvHFLepton) { + delete mGeneratorEvHFLepton; + mGeneratorEvHFLepton = nullptr; + } + } + + /// Init + bool Init() override + { + return o2::eventgen::GeneratorPythia8::Init(); + } + + /// @brief setup the event generator for HF signals + /// \param gentype generator type (only ccbar, only bbbar, both) + /// \param usePtHardBins flag to enable/disable pt-hard bins + /// \param yQuarkMin minimum quark rapidity + /// \param yQuarkMax maximum quark rapidity + /// \param yHadronMin minimum hadron rapidity + /// \param yHadronMax maximum hadron rapidity + /// \param hadronPdgList list of PDG codes for hadrons to be used in trigger + /// \param quarkPdgList list of PDG codes for quarks to be enriched in the trigger + void setupGeneratorEvHFLepton(int genType, int inputExternalID, int pdgLepton, float yMinQ = -1.5, float yMaxQ = 1.5, float yMinL = -1, float yMaxL = 1) { + mGeneratorEvHFLepton = nullptr; + switch (genType) + { + case hf_generators::Charm: + LOG(info) << "********** [GeneratorPythia8EmbedHFLepton] configuring GeneratorPythia8CharmLepton **********"; + LOG(info) << "********** Default number of HF signal events to be merged (updated by notifyEmbedding): " << mNumSigEvs; + mGeneratorEvHFLepton = dynamic_cast(GeneratorPythia8CharmLepton(inputExternalID, pdgLepton, yMinQ, yMaxQ, yMinL, yMaxL)); + break; + case hf_generators::Beauty: + LOG(info) << "********** [GeneratorPythia8EmbedHFLepton] configuring GeneratorPythia8BeautyForcedDecays **********"; + LOG(info) << "********** Default number of HF signal events to be merged (updated by notifyEmbedding): " << mNumSigEvs; + mGeneratorEvHFLepton = dynamic_cast(GeneratorPythia8BeautyForcedDecays(inputExternalID, pdgLepton, yMinQ, yMaxQ, yMinL, yMaxL)); + break; + case hf_generators::BeautyNoForcedDecays: + LOG(info) << "********** [GeneratorPythia8EmbedHFLepton] configuring GeneratorPythia8BeautyNoForcedDecays **********"; + LOG(info) << "********** Default number of HF signal events to be merged (updated by notifyEmbedding): " << mNumSigEvs; + mGeneratorEvHFLepton = dynamic_cast(GeneratorPythia8BeautyNoForcedDecays(inputExternalID, pdgLepton, yMinQ, yMaxQ, yMinL, yMaxL)); + break; + default: + LOG(fatal) << "********** [GeneratorPythia8EmbedHFLepton] bad configuration, fix it! **********"; + break; + } + mGeneratorEvHFLepton->Init(); + } + + // This function is called by the primary generator + // for each event in case we are in embedding mode. + // We use it to setup the number of signal events + // to be generated and to be embedded on the background. + void notifyEmbedding(const o2::dataformats::MCEventHeader* bkgHeader) override + { + LOG(info) << "[notifyEmbedding] ----- Function called"; + + /// Impact parameter between the two nuclei + const float x = bkgHeader->GetB(); + LOG(info) << "[notifyEmbedding] ----- Collision impact parameter: " << x; + + /// number of events to be embedded in a background event + // gen->setFormula("max(1.,120.*(x<5.)+80.*(1.-x/20.)*(x>5.)*(x<11.)+240.*(1.-x/13.)*(x>11.))"); + //mNumSigEvs = static_cast(std::lround(5.0 + 0.886202881 * std::pow(std::max(0.0f, 17.5f - x), 1.7))); + mNumSigEvs = static_cast(std::max(1.,120.*(x<5.)+80.*(1.-x/20.)*(x>5.)*(x<11.)+240.*(1.-x/13.)*(x>11.))); + //mNumSigEvs = 1; + LOG(info) << "[notifyEmbedding] ----- generating " << mNumSigEvs << " signal events " << std::endl; + }; + +protected: + +/// @brief Main function for event generation +bool generateEvent() override +{ + /// Overriding that from GeneratorPythia8, to avoid the simulation of an untriggered event as first + return true; +} + +/// @brief Main function to find out whether the particle comes charm or beauty quark +/// @param partId is the index of the particle under study +/// @param particles are the particles of the full event +bool isFromCharmOrBeauty(const int partId, std::vector const& particles) { + + // Let's check wheter this is already a c or b quark? + const TParticle& part = particles.at(partId); + const int pdgAbs = std::abs(part.GetPdgCode()); + if(pdgAbs == 4 || pdgAbs == 5) { + return true; + } + + // Let's check the mother particles of the hadron at all stages + // and look for the charm or beauty quark + std::vector> arrayIds{}; + std::vector initVec{partId}; + arrayIds.push_back(initVec); // the first vector contains the index of the original particle + int stage = 0; + while(arrayIds[-stage].size() > 0) { + + //LOG(info) << "### stage " << stage << ", arrayIds[-stage].size() = " << arrayIds[-stage].size(); + + std::vector arrayIdsStage{}; + + for (auto& iPart : arrayIds[-stage]) { // check all the particles that were the mothers at the previous stage + const TParticle& partStage = particles.at(iPart); + + // check the first mother + const int firstMotherId = partStage.GetFirstMother(); + if( firstMotherId >= 0) { + const TParticle& firstMother = particles.at(firstMotherId); + const int pdgAbsFirstMother = std::abs(firstMother.GetPdgCode()); + if(pdgAbsFirstMother == 4 || pdgAbsFirstMother == 5) { + return true; + } + // the first mother is not a charm or beauty quark + arrayIdsStage.push_back(firstMotherId); + } + + // let's check all other mothers, if any + const int lastMotherId = partStage.GetSecondMother(); + if(lastMotherId >=0 && lastMotherId != firstMotherId) { + for(int motherId = firstMotherId+1 /*first mother already considered*/; motherId <= lastMotherId; motherId++) { + const TParticle& mother = particles.at(motherId); + const int pdgAbsMother = std::abs(mother.GetPdgCode()); + if(pdgAbsMother == 4 || pdgAbsMother == 5) { + return true; + } + // this mother is not a charm or beauty quark + arrayIdsStage.push_back(motherId); + } + } + + } + + /* + All light-flavour mothers are not considered with this approach + eg: D+ coming from c and uBar --> uBar lost + --> TODO: check if the current particle has a charm or beauty hadron as daughter. If yes, keep it + >>> we can ignore it! This might be useful only for jet analyses, however this approach of embedding N pp events into a Pb-Pb one might be not ideal for them + */ + + // none of the particle mothers is a charm or beauty quark, let's consider their indices for the next stage + arrayIds.push_back(arrayIdsStage); + stage--; // ready to go to next stage + + } /// end while(arrayIds[-stage].size() > 0) + + return false; +} + + +void printParticleVector(std::vector v) { + for(int id=0; id idFirstMother=" << idFirstMother << ", idLastMother=" << idLastMother << ", idFirstDaughter=" << idFirstDaughter << ", idLastDaughter=" << idLastDaughter; + } +} + + +int findKey(const std::map& m, int value) { + for(std::pair p : m) { + if(p.second /*index*/ == value) { + return p.first; // key --> it becomes the new index + } + } + return -1; +} + + +/// @brief Main function to copy the generated particles in mPythia.event into the stack (this.mParticles) +Bool_t importParticles() override +{ + /// Import particles from generated event + /// This should not do anything now, since we override generateEvent + GeneratorPythia8::importParticles(); + + LOG(info) << ""; + LOG(info) << "*************************************************************"; + LOG(info) << "************** New signal event considered **************"; + LOG(info) << "*************************************************************"; + LOG(info) << ""; + + /// Generate mNumSigEvs HF events to be merged in one + int nEvsHF = 0; + while(nEvsHF < mNumSigEvs) { + + /// generate the HF event + bool genOk = false; + while(!genOk) { + genOk = (mGeneratorEvHFLepton->generateEvent() && mGeneratorEvHFLepton->importParticles() /*copy particles from mGeneratorEvHF.mPythia.event to mGeneratorEvHF.mParticles*/ ); + } + + int originalSize = mParticles.size(); // stack of this event generator + + // for debug + // LOG(info) << ""; + // LOG(info) << "============ Before HF event " << nEvsHF; + // LOG(info) << "Full stack (size " << originalSize << "):"; + // printParticleVector(mParticles); + + /// copy the particles from the HF event in the particle stack + auto particlesHfEvent = mGeneratorEvHFLepton->getParticles(); + std::map mapHfParticles = {}; + int counterHfParticles = 0; + + // for debug + // LOG(info) << "-----------------------------------------------"; + // LOG(info) << ">>> HF event " << nEvsHF; + // LOG(info) << " HF event stack:"; + // printParticleVector(particlesHfEvent); + + for(int iPart=0; iPart>>"; + // LOG(info) << " >>> printing mapHfParticles:"; + // for(auto& p : mapHfParticles) { + // const int pdgCodeFromMap = particlesHfEvent.at(p.second).GetPdgCode(); + // LOG(info) << " >>> entry " << p.first << ", original id = " << p.second << ", pdgCode=" << pdgCodeFromMap << " --> firstMotherId=" << particlesHfEvent.at(p.second).GetFirstMother() << ", lastMotherId=" << particlesHfEvent.at(p.second).GetSecondMother() << ", firstDaughterId=" << particlesHfEvent.at(p.second).GetFirstDaughter() << ", lastDaughterId=" << particlesHfEvent.at(p.second).GetLastDaughter(); + // } + + + // In the map we have only the particles from charm or beauty + // Let's readapt the mother/daughter indices accordingly + int offset = originalSize; + for(int iHfPart=0; iHfPart= 0) { + idFirstMother = findKey(mapHfParticles, idFirstMother); + /// If idFirstMother>=0, the 1st mother is from charm or beauty, i.e. is not a light-flavoured parton + /// Instead, if idFirstMother==-1 from findKey this means that the first mother was a light-flavoured parton --> not stored in the map + if(idFirstMother >=0) { + /// the 1st mother is from charm or beauty, i.e. is not a light-flavoured parton + if(idLastMother != idFirstMotherOrig) { + if(idLastMother != -1) { + /// idLastMother is >= 0 + } + } else { + /// idLastMother is equal to idFirstMother + idLastMother = idFirstMother; + } + isFirstMotherOk = true; + } + } + if(!isFirstMotherOk) { + /// - If we are here, it means that the 1st mother was not from charm or beauty + /// - No need to check whether idLastMother>=0, + /// because this would mean that none of the mother is from charm or beauty and this was checked already in isFromCharmOrBeauty + /// - Need to loop between 1st and last mother, to treat cases like these + /// [11:52:13][INFO] id = 565, pdgCode = -2 --> idFirstMother=519, idLastMother=519 + /// [11:52:13][INFO] id = 566, pdgCode = -4 --> idFirstMother=520, idLastMother=520 + /// [11:52:13][INFO] id = 567, pdgCode = -1 --> idFirstMother=518, idLastMother=518 + /// [11:52:13][INFO] id = 568, pdgCode = -311 --> idFirstMother=565, idLastMother=567 + /// [11:52:13][INFO] id = 569, pdgCode = -4212 --> idFirstMother=565, idLastMother=567 + /// --> w/o loop between 1st and last mother, the mother Ids assigned to this Sc+ (4212) by findKey are -1, both first and last + bool foundAnyMother = false; + for(int idMotherOrig=(idFirstMotherOrig+1); idMotherOrig<=idLastMother; idMotherOrig++) { + const int idMother = findKey(mapHfParticles, idMotherOrig); + if(idMother >= 0) { + /// this should mean that the mother is from HF, i.e. that we found the correct one + idFirstMother = idMother; + idLastMother = idFirstMother; + foundAnyMother = true; + break; + } + } + // set last mother to -1 if no mother has been found so far + if (!foundAnyMother) { + idLastMother = -1; + } + } + + /// fix daughter indices + idFirstDaughter = findKey(mapHfParticles, idFirstDaughter); + idLastDaughter = findKey(mapHfParticles, idLastDaughter); + + /// adjust the particle mother and daughter indices + particle.SetFirstMother((idFirstMother >= 0) ? idFirstMother + offset : idFirstMother); + particle.SetLastMother((idLastMother >= 0) ? idLastMother + offset : idLastMother); + particle.SetFirstDaughter((idFirstDaughter >= 0) ? idFirstDaughter + offset : idFirstDaughter); + particle.SetLastDaughter((idLastDaughter >= 0) ? idLastDaughter + offset : idLastDaughter); + + /// copy inside this.mParticles from mGeneratorEvHF.mParticles, i.e. the particles generated in mGeneratorEvHF + mParticles.push_back(particle); + + } + + // for debug + // LOG(info) << "-----------------------------------------------"; + // LOG(info) << "============ After HF event " << nEvsHF; + // LOG(info) << "Full stack:"; + // printParticleVector(mParticles); + + /// one more event generated, let's update the counter and clear it, to allow the next generation + nEvsHF++; + //mGeneratedEvents++; + mGeneratorEvHFLepton->clearParticles(); + } + + return true; +} + +private: + + Generator* mGeneratorEvHFLepton; // to generate HF signal events + + int mNumSigEvs{1}; // number of HF signal events to be merged in one Pythia event + //unsigned long long mGeneratedEvents; + +}; + +// Charm enriched +FairGenerator * GeneratorPythia8EmbedHFLeptonCharm(int inputExternalID, int pdgLepton, float yMinQ = -1.5, float yMaxQ = 1.5, float yMinL = -1, float yMaxL = 1) +{ + auto myGen = new GeneratorPythia8EmbedHFLepton(); + + /// setup the internal generator for HF events + myGen->setupGeneratorEvHFLepton(hf_generators::Charm, inputExternalID, pdgLepton, yMinQ = -1.5, yMaxQ = 1.5, yMinL = -1, yMaxL = 1); + + return myGen; +} + +// Beauty enriched +FairGenerator * GeneratorPythia8EmbedHFLeptonBeauty(int inputExternalID, int pdgLepton, float yMinQ = -1.5, float yMaxQ = 1.5, float yMinL = -1, float yMaxL = 1) +{ + auto myGen = new GeneratorPythia8EmbedHFLepton(); + + /// setup the internal generator for HF events + myGen->setupGeneratorEvHFLepton(hf_generators::Beauty, inputExternalID, pdgLepton, yMinQ = -1.5, yMaxQ = 1.5, yMinL = -1, yMaxL = 1); + + return myGen; +} + +// Charm and beauty enriched (with same ratio) +FairGenerator * GeneratorPythia8EmbedHFLeptonBeautyNoForcedDecays(int inputExternalID, int pdgLepton, float yMinQ = -1.5, float yMaxQ = 1.5, float yMinL = -1, float yMaxL = 1) +{ + auto myGen = new GeneratorPythia8EmbedHFLepton(); + + /// setup the internal generator for HF events + myGen->setupGeneratorEvHFLepton(hf_generators::BeautyNoForcedDecays, inputExternalID, pdgLepton, yMinQ = -1.5, yMaxQ = 1.5, yMinL = -1, yMaxL = 1); + + return myGen; +} diff --git a/MC/config/PWGEM/ini/GeneratorDYee_GapTriggered_Gap2_OO5360GeV.ini b/MC/config/PWGEM/ini/GeneratorDYee_GapTriggered_Gap2_OO5360GeV.ini new file mode 100644 index 000000000..a83045099 --- /dev/null +++ b/MC/config/PWGEM/ini/GeneratorDYee_GapTriggered_Gap2_OO5360GeV.ini @@ -0,0 +1,7 @@ +[GeneratorExternal] +fileName = ${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGEM/external/generator/Generator_pythia8_GapTriggered_DYll.C +funcName = GeneratorPythia8GapTriggeredDYll(2, 1, 11, -1.5, +1.5, 1000080160, 1000080160, 5360.0) + +[GeneratorPythia8] +config = ${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGEM/pythia8/generator/configPythiaEmpty.cfg +includePartonEvent = true diff --git a/MC/config/PWGEM/ini/GeneratorDYee_GapTriggered_Gap5_OO5360GeV.ini b/MC/config/PWGEM/ini/GeneratorDYee_GapTriggered_Gap5_OO5360GeV.ini new file mode 100644 index 000000000..f07e285dd --- /dev/null +++ b/MC/config/PWGEM/ini/GeneratorDYee_GapTriggered_Gap5_OO5360GeV.ini @@ -0,0 +1,7 @@ +[GeneratorExternal] +fileName = ${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGEM/external/generator/Generator_pythia8_GapTriggered_DYll.C +funcName = GeneratorPythia8GapTriggeredDYll(5, 1, 11, -1.5, +1.5, 1000080160, 1000080160, 5360.0) + +[GeneratorPythia8] +config = ${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGEM/pythia8/generator/configPythiaEmpty.cfg +includePartonEvent = true diff --git a/MC/config/PWGEM/ini/GeneratorDYee_GapTriggered_Gap5_pp13600GeV.ini b/MC/config/PWGEM/ini/GeneratorDYee_GapTriggered_Gap5_pp13600GeV.ini new file mode 100644 index 000000000..7ecf763cf --- /dev/null +++ b/MC/config/PWGEM/ini/GeneratorDYee_GapTriggered_Gap5_pp13600GeV.ini @@ -0,0 +1,7 @@ +[GeneratorExternal] +fileName = ${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGEM/external/generator/Generator_pythia8_GapTriggered_DYll.C +funcName = GeneratorPythia8GapTriggeredDYll(5, 1, 11, -1.5, +1.5, 2212, 2212, 13600.0) + +[GeneratorPythia8] +config = ${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGEM/pythia8/generator/configPythiaEmpty.cfg +includePartonEvent = true diff --git a/MC/config/PWGEM/ini/GeneratorDYee_GapTriggered_Gap5_pp5360GeV.ini b/MC/config/PWGEM/ini/GeneratorDYee_GapTriggered_Gap5_pp5360GeV.ini new file mode 100644 index 000000000..70e802dec --- /dev/null +++ b/MC/config/PWGEM/ini/GeneratorDYee_GapTriggered_Gap5_pp5360GeV.ini @@ -0,0 +1,7 @@ +[GeneratorExternal] +fileName = ${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGEM/external/generator/Generator_pythia8_GapTriggered_DYll.C +funcName = GeneratorPythia8GapTriggeredDYll(5, 1, 11, -1.5, +1.5, 2212, 2212, 5360.0) + +[GeneratorPythia8] +config = ${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGEM/pythia8/generator/configPythiaEmpty.cfg +includePartonEvent = true diff --git a/MC/config/PWGEM/ini/GeneratorDYmumu_GapTriggered_Gap5_OO5360GeV.ini b/MC/config/PWGEM/ini/GeneratorDYmumu_GapTriggered_Gap5_OO5360GeV.ini new file mode 100644 index 000000000..67001defd --- /dev/null +++ b/MC/config/PWGEM/ini/GeneratorDYmumu_GapTriggered_Gap5_OO5360GeV.ini @@ -0,0 +1,7 @@ +[GeneratorExternal] +fileName = ${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGEM/external/generator/Generator_pythia8_GapTriggered_DYll.C +funcName = GeneratorPythia8GapTriggeredDYll(5, 1, 13, -6, -1, 1000080160, 1000080160, 5360.0) + +[GeneratorPythia8] +config = ${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGEM/pythia8/generator/configPythiaEmpty.cfg +includePartonEvent = true diff --git a/MC/config/PWGEM/ini/GeneratorDYmumu_GapTriggered_Gap5_pp5360GeV.ini b/MC/config/PWGEM/ini/GeneratorDYmumu_GapTriggered_Gap5_pp5360GeV.ini new file mode 100644 index 000000000..82c45f3fd --- /dev/null +++ b/MC/config/PWGEM/ini/GeneratorDYmumu_GapTriggered_Gap5_pp5360GeV.ini @@ -0,0 +1,7 @@ +[GeneratorExternal] +fileName = ${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGEM/external/generator/Generator_pythia8_GapTriggered_DYll.C +funcName = GeneratorPythia8GapTriggeredDYll(5, 1, 13, -6, -1, 2212, 2212, 5360.0) + +[GeneratorPythia8] +config = ${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGEM/pythia8/generator/configPythiaEmpty.cfg +includePartonEvent = true diff --git a/MC/config/PWGEM/ini/GeneratorEMCocktail.ini b/MC/config/PWGEM/ini/GeneratorEMCocktail_502PbPb_0005.ini similarity index 100% rename from MC/config/PWGEM/ini/GeneratorEMCocktail.ini rename to MC/config/PWGEM/ini/GeneratorEMCocktail_502PbPb_0005.ini diff --git a/MC/config/PWGEM/ini/GeneratorEMCocktail_502PbPb_0510.ini b/MC/config/PWGEM/ini/GeneratorEMCocktail_502PbPb_0510.ini new file mode 100644 index 000000000..2e26ba807 --- /dev/null +++ b/MC/config/PWGEM/ini/GeneratorEMCocktail_502PbPb_0510.ini @@ -0,0 +1,6 @@ +### The setup uses an external event generator +### This part sets the path of the file and the function call to retrieve it + +[GeneratorExternal] +fileName = ${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGEM/external/generator/GeneratorEMCocktailV2.C +funcName=GenerateEMCocktail(400,0,3,63,"${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGEM/parametrizations/PbPb5TeV_central.json","5TeV_0510_wRatio_etatest",350,0.0,30.0,10000,1,1,0,0,"",0,1.1,"${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGEM/decaytables/decaytable_LMee.dat",1) \ No newline at end of file diff --git a/MC/config/PWGEM/ini/GeneratorEMCocktail_502PbPb_1020.ini b/MC/config/PWGEM/ini/GeneratorEMCocktail_502PbPb_1020.ini new file mode 100644 index 000000000..a492a4a1e --- /dev/null +++ b/MC/config/PWGEM/ini/GeneratorEMCocktail_502PbPb_1020.ini @@ -0,0 +1,6 @@ +### The setup uses an external event generator +### This part sets the path of the file and the function call to retrieve it + +[GeneratorExternal] +fileName = ${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGEM/external/generator/GeneratorEMCocktailV2.C +funcName=GenerateEMCocktail(400,0,3,63,"${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGEM/parametrizations/PbPb5TeV_central.json","5TeV_1020_wRatio_etatest",350,0.0,30.0,10000,1,1,0,0,"",0,1.1,"${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGEM/decaytables/decaytable_LMee.dat",1) \ No newline at end of file diff --git a/MC/config/PWGEM/ini/GeneratorEMCocktail_502PbPb_2030.ini b/MC/config/PWGEM/ini/GeneratorEMCocktail_502PbPb_2030.ini new file mode 100644 index 000000000..0cc122f7b --- /dev/null +++ b/MC/config/PWGEM/ini/GeneratorEMCocktail_502PbPb_2030.ini @@ -0,0 +1,6 @@ +### The setup uses an external event generator +### This part sets the path of the file and the function call to retrieve it + +[GeneratorExternal] +fileName = ${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGEM/external/generator/GeneratorEMCocktailV2.C +funcName=GenerateEMCocktail(400,0,3,63,"${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGEM/parametrizations/PbPb5TeV_central.json","5TeV_2030_wRatio_etatest",350,0.0,30.0,10000,1,1,0,0,"",0,1.1,"${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGEM/decaytables/decaytable_LMee.dat",1) \ No newline at end of file diff --git a/MC/config/PWGEM/ini/GeneratorEMCocktail_502PbPb_3040.ini b/MC/config/PWGEM/ini/GeneratorEMCocktail_502PbPb_3040.ini new file mode 100644 index 000000000..73960d0e8 --- /dev/null +++ b/MC/config/PWGEM/ini/GeneratorEMCocktail_502PbPb_3040.ini @@ -0,0 +1,6 @@ +### The setup uses an external event generator +### This part sets the path of the file and the function call to retrieve it + +[GeneratorExternal] +fileName = ${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGEM/external/generator/GeneratorEMCocktailV2.C +funcName=GenerateEMCocktail(400,0,3,63,"${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGEM/parametrizations/PbPb5TeV_central.json","5TeV_3040_wRatio_etatest",350,0.0,30.0,10000,1,1,0,0,"",0,1.1,"${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGEM/decaytables/decaytable_LMee.dat",1) \ No newline at end of file diff --git a/MC/config/PWGEM/ini/GeneratorEMCocktail_502PbPb_4050.ini b/MC/config/PWGEM/ini/GeneratorEMCocktail_502PbPb_4050.ini new file mode 100644 index 000000000..25d78e2f1 --- /dev/null +++ b/MC/config/PWGEM/ini/GeneratorEMCocktail_502PbPb_4050.ini @@ -0,0 +1,6 @@ +### The setup uses an external event generator +### This part sets the path of the file and the function call to retrieve it + +[GeneratorExternal] +fileName = ${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGEM/external/generator/GeneratorEMCocktailV2.C +funcName=GenerateEMCocktail(400,0,3,63,"${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGEM/parametrizations/PbPb5TeV_central.json","5TeV_4050_wRatio_etatest",350,0.0,30.0,10000,1,1,0,0,"",0,1.1,"${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGEM/decaytables/decaytable_LMee.dat",1) \ No newline at end of file diff --git a/MC/config/PWGEM/ini/GeneratorEMCocktail_502PbPb_5060.ini b/MC/config/PWGEM/ini/GeneratorEMCocktail_502PbPb_5060.ini new file mode 100644 index 000000000..4e74682df --- /dev/null +++ b/MC/config/PWGEM/ini/GeneratorEMCocktail_502PbPb_5060.ini @@ -0,0 +1,6 @@ +### The setup uses an external event generator +### This part sets the path of the file and the function call to retrieve it + +[GeneratorExternal] +fileName = ${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGEM/external/generator/GeneratorEMCocktailV2.C +funcName=GenerateEMCocktail(400,0,3,63,"${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGEM/parametrizations/PbPb5TeV_peripheral.json","5TeV_5060_wRatio_pi0corr",350,0.0,30.0,10000,1,1,0,0,"",0,1.1,"${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGEM/decaytables/decaytable_LMee.dat",1) \ No newline at end of file diff --git a/MC/config/PWGEM/ini/GeneratorEMCocktail_502PbPb_6070.ini b/MC/config/PWGEM/ini/GeneratorEMCocktail_502PbPb_6070.ini new file mode 100644 index 000000000..0cc3b1065 --- /dev/null +++ b/MC/config/PWGEM/ini/GeneratorEMCocktail_502PbPb_6070.ini @@ -0,0 +1,6 @@ +### The setup uses an external event generator +### This part sets the path of the file and the function call to retrieve it + +[GeneratorExternal] +fileName = ${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGEM/external/generator/GeneratorEMCocktailV2.C +funcName=GenerateEMCocktail(400,0,3,63,"${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGEM/parametrizations/PbPb5TeV_peripheral.json","5TeV_6070_wRatio_pi0corr",350,0.0,30.0,10000,1,1,0,0,"",0,1.1,"${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGEM/decaytables/decaytable_LMee.dat",1) \ No newline at end of file diff --git a/MC/config/PWGEM/ini/GeneratorEMCocktail_502PbPb_7080.ini b/MC/config/PWGEM/ini/GeneratorEMCocktail_502PbPb_7080.ini new file mode 100644 index 000000000..524067a5e --- /dev/null +++ b/MC/config/PWGEM/ini/GeneratorEMCocktail_502PbPb_7080.ini @@ -0,0 +1,6 @@ +### The setup uses an external event generator +### This part sets the path of the file and the function call to retrieve it + +[GeneratorExternal] +fileName = ${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGEM/external/generator/GeneratorEMCocktailV2.C +funcName=GenerateEMCocktail(400,0,3,63,"${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGEM/parametrizations/PbPb5TeV_peripheral.json","5TeV_7080_wRatio_pi0corr",350,0.0,30.0,10000,1,1,0,0,"",0,1.1,"${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGEM/decaytables/decaytable_LMee.dat",1) \ No newline at end of file diff --git a/MC/config/PWGEM/ini/GeneratorEMCocktail_502PbPb_8090.ini b/MC/config/PWGEM/ini/GeneratorEMCocktail_502PbPb_8090.ini new file mode 100644 index 000000000..596653424 --- /dev/null +++ b/MC/config/PWGEM/ini/GeneratorEMCocktail_502PbPb_8090.ini @@ -0,0 +1,6 @@ +### The setup uses an external event generator +### This part sets the path of the file and the function call to retrieve it + +[GeneratorExternal] +fileName = ${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGEM/external/generator/GeneratorEMCocktailV2.C +funcName=GenerateEMCocktail(400,0,3,63,"${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGEM/parametrizations/PbPb5TeV_peripheral.json","5TeV_8090_wRatio_pi0corr",350,0.0,30.0,10000,1,1,0,0,"",0,1.1,"${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGEM/decaytables/decaytable_LMee.dat",1) \ No newline at end of file diff --git a/MC/config/PWGEM/ini/GeneratorEMCocktail_Run3_OO.ini b/MC/config/PWGEM/ini/GeneratorEMCocktail_Run3_OO.ini new file mode 100644 index 000000000..83898beae --- /dev/null +++ b/MC/config/PWGEM/ini/GeneratorEMCocktail_Run3_OO.ini @@ -0,0 +1,6 @@ +### The setup uses an external event generator +### This part sets the path of the file and the function call to retrieve it + +[GeneratorExternal] +fileName = ${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGEM/external/generator/GeneratorEMCocktailV2.C +funcName=GenerateEMCocktail(200,0,3,63,"${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGEM/parametrizations/OO_536TeV_param.json","536TeV_MB_pythia",200,0.0,30.0,10000,1,1,0,0,"",0,1.1,"${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGEM/decaytables/decaytable_LMee.dat",1) diff --git a/MC/config/PWGEM/ini/GeneratorEMCocktail_Run3pp_lowBeta.ini b/MC/config/PWGEM/ini/GeneratorEMCocktail_Run3pp_lowBeta.ini new file mode 100644 index 000000000..372a2e1a5 --- /dev/null +++ b/MC/config/PWGEM/ini/GeneratorEMCocktail_Run3pp_lowBeta.ini @@ -0,0 +1,6 @@ +### The setup uses an external event generator +### This part sets the path of the file and the function call to retrieve it + +[GeneratorExternal] +fileName = ${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGEM/external/generator/GeneratorEMCocktailV2.C +funcName=GenerateEMCocktail(200,0,3,63,"${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGEM/parametrizations/pp136TeV_run3.json","13TeV_MB_default",200,0.0,30.0,10000,1,1,0,0,"",0,1.1,"${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGEM/decaytables/decaytable_LMee.dat",1) diff --git a/MC/config/PWGEM/ini/GeneratorEMCocktail_Run3pp_v2.ini b/MC/config/PWGEM/ini/GeneratorEMCocktail_Run3pp_v2.ini new file mode 100644 index 000000000..09a5e36ab --- /dev/null +++ b/MC/config/PWGEM/ini/GeneratorEMCocktail_Run3pp_v2.ini @@ -0,0 +1,6 @@ +### The setup uses an external event generator +### This part sets the path of the file and the function call to retrieve it + +[GeneratorExternal] +fileName = ${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGEM/external/generator/GeneratorEMCocktailV2.C +funcName=GenerateEMCocktail(200,0,3,63,"${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGEM/parametrizations/pp13TeV_run2.json","13TeV_MB_default",200,0.0,30.0,10000,1,1,0,0,"",0,1.1,"${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGEM/decaytables/decaytable_LMee.dat",1) \ No newline at end of file diff --git a/MC/config/PWGEM/ini/GeneratorHFGapTriggered_BeautyForcedDecay_Gap2_OO_electron.ini b/MC/config/PWGEM/ini/GeneratorHFGapTriggered_BeautyForcedDecay_Gap2_OO_electron.ini new file mode 100644 index 000000000..f25401e61 --- /dev/null +++ b/MC/config/PWGEM/ini/GeneratorHFGapTriggered_BeautyForcedDecay_Gap2_OO_electron.ini @@ -0,0 +1,8 @@ +#NEV_TEST> 5 +[GeneratorExternal] +fileName = ${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGEM/external/generator/Generator_pythia8_GapTriggered_HFLepton_OO.C +funcName = GeneratorPythia8GapTriggeredBeautyForcedDecays(2, 2, 11, -1.5, +1.5, -1.2, +1.2) + +[GeneratorPythia8] +config = ${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGEM/pythia8/generator/configPythiaEmpty.cfg +includePartonEvent = true diff --git a/MC/config/PWGEM/ini/GeneratorHFGapTriggered_BeautyForcedDecay_Gap2_OO_muon.ini b/MC/config/PWGEM/ini/GeneratorHFGapTriggered_BeautyForcedDecay_Gap2_OO_muon.ini new file mode 100644 index 000000000..b129f9fe8 --- /dev/null +++ b/MC/config/PWGEM/ini/GeneratorHFGapTriggered_BeautyForcedDecay_Gap2_OO_muon.ini @@ -0,0 +1,8 @@ +#NEV_TEST> 5 +[GeneratorExternal] +fileName = ${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGEM/external/generator/Generator_pythia8_GapTriggered_HFLepton_OO.C +funcName = GeneratorPythia8GapTriggeredBeautyForcedDecays(2, 2, 13, -6, 0, -5, -1) + +[GeneratorPythia8] +config = ${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGEM/pythia8/generator/configPythiaEmpty.cfg +includePartonEvent = true diff --git a/MC/config/PWGEM/ini/GeneratorHFGapTriggered_BeautyForcedDecay_Gap5_pp5360GeV.ini b/MC/config/PWGEM/ini/GeneratorHFGapTriggered_BeautyForcedDecay_Gap5_pp5360GeV.ini new file mode 100644 index 000000000..54de7afa1 --- /dev/null +++ b/MC/config/PWGEM/ini/GeneratorHFGapTriggered_BeautyForcedDecay_Gap5_pp5360GeV.ini @@ -0,0 +1,7 @@ +[GeneratorExternal] +fileName = ${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGEM/external/generator/Generator_pythia8_GapTriggered_HFLepton_pp5360.C +funcName = GeneratorPythia8GapTriggeredBeautyForcedDecays(5,2) + +[GeneratorPythia8] +config = ${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGEM/pythia8/generator/configPythiaEmpty.cfg +includePartonEvent = true diff --git a/MC/config/PWGEM/ini/GeneratorHFGapTriggered_BeautyNoForcedDecay_Gap2_OO_electron.ini b/MC/config/PWGEM/ini/GeneratorHFGapTriggered_BeautyNoForcedDecay_Gap2_OO_electron.ini new file mode 100644 index 000000000..8cd7e5ab6 --- /dev/null +++ b/MC/config/PWGEM/ini/GeneratorHFGapTriggered_BeautyNoForcedDecay_Gap2_OO_electron.ini @@ -0,0 +1,8 @@ +#NEV_TEST> 5 +[GeneratorExternal] +fileName = ${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGEM/external/generator/Generator_pythia8_GapTriggered_HFLepton_OO.C +funcName = GeneratorPythia8GapTriggeredBeautyNoForcedDecays(2, 3, 11, -1.5, +1.5, -1.2, +1.2) + +[GeneratorPythia8] +config = ${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGEM/pythia8/generator/configPythiaEmpty.cfg +includePartonEvent = true diff --git a/MC/config/PWGEM/ini/GeneratorHFGapTriggered_BeautyNoForcedDecay_Gap2_OO_muon.ini b/MC/config/PWGEM/ini/GeneratorHFGapTriggered_BeautyNoForcedDecay_Gap2_OO_muon.ini new file mode 100644 index 000000000..97741b31b --- /dev/null +++ b/MC/config/PWGEM/ini/GeneratorHFGapTriggered_BeautyNoForcedDecay_Gap2_OO_muon.ini @@ -0,0 +1,8 @@ +#NEV_TEST> 5 +[GeneratorExternal] +fileName = ${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGEM/external/generator/Generator_pythia8_GapTriggered_HFLepton_OO.C +funcName = GeneratorPythia8GapTriggeredBeautyNoForcedDecays(2, 3, 13, -6, 0, -5, -1) + +[GeneratorPythia8] +config = ${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGEM/pythia8/generator/configPythiaEmpty.cfg +includePartonEvent = true diff --git a/MC/config/PWGEM/ini/GeneratorHFGapTriggered_BeautyNoForcedDecay_Gap5_pp5360GeV.ini b/MC/config/PWGEM/ini/GeneratorHFGapTriggered_BeautyNoForcedDecay_Gap5_pp5360GeV.ini new file mode 100644 index 000000000..0cc38a529 --- /dev/null +++ b/MC/config/PWGEM/ini/GeneratorHFGapTriggered_BeautyNoForcedDecay_Gap5_pp5360GeV.ini @@ -0,0 +1,7 @@ +[GeneratorExternal] +fileName = ${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGEM/external/generator/Generator_pythia8_GapTriggered_HFLepton_pp5360.C +funcName = GeneratorPythia8GapTriggeredBeautyNoForcedDecays(5,3) + +[GeneratorPythia8] +config = ${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGEM/pythia8/generator/configPythiaEmpty.cfg +includePartonEvent = true diff --git a/MC/config/PWGEM/ini/GeneratorHFGapTriggered_Charm_Gap2_OO_electron.ini b/MC/config/PWGEM/ini/GeneratorHFGapTriggered_Charm_Gap2_OO_electron.ini new file mode 100644 index 000000000..9691afc04 --- /dev/null +++ b/MC/config/PWGEM/ini/GeneratorHFGapTriggered_Charm_Gap2_OO_electron.ini @@ -0,0 +1,8 @@ +#NEV_TEST> 5 +[GeneratorExternal] +fileName = ${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGEM/external/generator/Generator_pythia8_GapTriggered_HFLepton_OO.C +funcName = GeneratorPythia8GapTriggeredCharmLepton(2, 1, 11, -1.5, +1.5, -1.2, +1.2) + +[GeneratorPythia8] +config = ${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGEM/pythia8/generator/configPythiaEmpty.cfg +includePartonEvent = true diff --git a/MC/config/PWGEM/ini/GeneratorHFGapTriggered_Charm_Gap2_OO_muon.ini b/MC/config/PWGEM/ini/GeneratorHFGapTriggered_Charm_Gap2_OO_muon.ini new file mode 100644 index 000000000..59d5babf4 --- /dev/null +++ b/MC/config/PWGEM/ini/GeneratorHFGapTriggered_Charm_Gap2_OO_muon.ini @@ -0,0 +1,8 @@ +#NEV_TEST> 5 +[GeneratorExternal] +fileName = ${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGEM/external/generator/Generator_pythia8_GapTriggered_HFLepton_OO.C +funcName = GeneratorPythia8GapTriggeredCharmLepton(2, 1, 13, -6, 0, -5, -1) + +[GeneratorPythia8] +config = ${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGEM/pythia8/generator/configPythiaEmpty.cfg +includePartonEvent = true diff --git a/MC/config/PWGEM/ini/GeneratorHFGapTriggered_Charm_Gap5_pp5360GeV.ini b/MC/config/PWGEM/ini/GeneratorHFGapTriggered_Charm_Gap5_pp5360GeV.ini new file mode 100644 index 000000000..e653a993b --- /dev/null +++ b/MC/config/PWGEM/ini/GeneratorHFGapTriggered_Charm_Gap5_pp5360GeV.ini @@ -0,0 +1,7 @@ +[GeneratorExternal] +fileName = ${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGEM/external/generator/Generator_pythia8_GapTriggered_HFLepton_pp5360.C +funcName = GeneratorPythia8GapTriggeredCharmLepton(5,1) + +[GeneratorPythia8] +config = ${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGEM/pythia8/generator/configPythiaEmpty.cfg +includePartonEvent = true diff --git a/MC/config/PWGEM/ini/GeneratorHF_BeautyNoForcedDecay_PbPb_electron.ini b/MC/config/PWGEM/ini/GeneratorHF_BeautyNoForcedDecay_PbPb_electron.ini new file mode 100644 index 000000000..f24c66d3e --- /dev/null +++ b/MC/config/PWGEM/ini/GeneratorHF_BeautyNoForcedDecay_PbPb_electron.ini @@ -0,0 +1,9 @@ +#NEV_TEST> 10 +### The external generator derives from GeneratorPythia8 +[GeneratorExternal] +fileName=${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGEM/external/generator/Generator_pythia8_embed_HFLepton.C +funcName=GeneratorPythia8EmbedHFLeptonBeautyNoForcedDecays(3, 11) + +[GeneratorPythia8] +config=${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGEM/pythia8/generator/configPythiaEmpty.cfg +includePartonEvent=true diff --git a/MC/config/PWGEM/ini/GeneratorHF_Charm_PbPb_electron.ini b/MC/config/PWGEM/ini/GeneratorHF_Charm_PbPb_electron.ini new file mode 100644 index 000000000..b72cfb523 --- /dev/null +++ b/MC/config/PWGEM/ini/GeneratorHF_Charm_PbPb_electron.ini @@ -0,0 +1,9 @@ +#NEV_TEST> 10 +### The external generator derives from GeneratorPythia8 +[GeneratorExternal] +fileName=${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGEM/external/generator/Generator_pythia8_embed_HFLepton.C +funcName=GeneratorPythia8EmbedHFLeptonCharm(1, 11) + +[GeneratorPythia8] +config=${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGEM/pythia8/generator/configPythiaEmpty.cfg +includePartonEvent=true diff --git a/MC/config/PWGEM/ini/Pythia8_Beauty_Cocktail_pp13.ini b/MC/config/PWGEM/ini/Pythia8_Beauty_Cocktail_pp13.ini new file mode 100644 index 000000000..4a0f54f13 --- /dev/null +++ b/MC/config/PWGEM/ini/Pythia8_Beauty_Cocktail_pp13.ini @@ -0,0 +1,13 @@ +[GeneratorExternal] +fileName = ${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGEM/external/generator/Generator_pythia8_forcedDecays.C +funcName=GeneratePythia8ForcedDecays("411;421;431;4122;4232;4132;4332") + +[GeneratorPythia8] +config = ${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGEM/pythia8/generator/pythia8_hf_cocktail_pp13.cfg +hooksFileName = ${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGHF/pythia8/hooks/pythia8_userhooks_qqbar.C +hooksFuncName = pythia8_userhooks_bbbar(-12.,12.) +includePartonEvent=true + +[DecayerPythia8] +config[0] = ${O2DPG_MC_CONFIG_ROOT}/MC/config/common/pythia8/decayer/base.cfg +config[1] = ${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGEM/pythia8/decayer/force_semileptonic_charm.cfg diff --git a/MC/config/PWGEM/ini/Pythia8_Beauty_Cocktail_pp502.ini b/MC/config/PWGEM/ini/Pythia8_Beauty_Cocktail_pp502.ini new file mode 100644 index 000000000..a9fcaf789 --- /dev/null +++ b/MC/config/PWGEM/ini/Pythia8_Beauty_Cocktail_pp502.ini @@ -0,0 +1,13 @@ +[GeneratorExternal] +fileName = ${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGEM/external/generator/Generator_pythia8_forcedDecays.C +funcName=GeneratePythia8ForcedDecays("411;421;431;4122;4232;4132;4332") + +[GeneratorPythia8] +config = ${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGEM/pythia8/generator/pythia8_hf_cocktail_pp502.cfg +hooksFileName = ${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGHF/pythia8/hooks/pythia8_userhooks_qqbar.C +hooksFuncName = pythia8_userhooks_bbbar(-12.,12.) +includePartonEvent=true + +[DecayerPythia8] +config[0] = ${O2DPG_MC_CONFIG_ROOT}/MC/config/common/pythia8/decayer/base.cfg +config[1] = ${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGEM/pythia8/decayer/force_semileptonic_charm.cfg diff --git a/MC/config/PWGEM/ini/Pythia8_Beauty_Cocktail_pp536.ini b/MC/config/PWGEM/ini/Pythia8_Beauty_Cocktail_pp536.ini new file mode 100644 index 000000000..1de490707 --- /dev/null +++ b/MC/config/PWGEM/ini/Pythia8_Beauty_Cocktail_pp536.ini @@ -0,0 +1,13 @@ +[GeneratorExternal] +fileName = ${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGEM/external/generator/Generator_pythia8_forcedDecays.C +funcName=GeneratePythia8ForcedDecays("411;421;431;4122;4232;4132;4332") + +[GeneratorPythia8] +config = ${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGEM/pythia8/generator/pythia8_hf_cocktail_pp536.cfg +hooksFileName = ${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGHF/pythia8/hooks/pythia8_userhooks_qqbar.C +hooksFuncName = pythia8_userhooks_bbbar(-12.,12.) +includePartonEvent=true + +[DecayerPythia8] +config[0] = ${O2DPG_MC_CONFIG_ROOT}/MC/config/common/pythia8/decayer/base.cfg +config[1] = ${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGEM/pythia8/decayer/force_semileptonic_charm.cfg diff --git a/MC/config/PWGEM/ini/Pythia8_Charm_Cocktail_pp13.ini b/MC/config/PWGEM/ini/Pythia8_Charm_Cocktail_pp13.ini new file mode 100644 index 000000000..cad2afe89 --- /dev/null +++ b/MC/config/PWGEM/ini/Pythia8_Charm_Cocktail_pp13.ini @@ -0,0 +1,13 @@ +[GeneratorExternal] +fileName = ${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGEM/external/generator/Generator_pythia8_forcedDecays.C +funcName=GeneratePythia8ForcedDecays("411;421;431;4122;4232;4132;4332") + +[GeneratorPythia8] +config = ${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGEM/pythia8/generator/pythia8_hf_cocktail_pp13.cfg +hooksFileName = ${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGHF/pythia8/hooks/pythia8_userhooks_qqbar.C +hooksFuncName = pythia8_userhooks_ccbar(-12.,12.) +includePartonEvent=true + +[DecayerPythia8] +config[0] = ${O2DPG_MC_CONFIG_ROOT}/MC/config/common/pythia8/decayer/base.cfg +config[1] = ${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGEM/pythia8/decayer/force_semileptonic_charm.cfg diff --git a/MC/config/PWGEM/ini/Pythia8_Charm_Cocktail_pp502.ini b/MC/config/PWGEM/ini/Pythia8_Charm_Cocktail_pp502.ini new file mode 100644 index 000000000..42f30b441 --- /dev/null +++ b/MC/config/PWGEM/ini/Pythia8_Charm_Cocktail_pp502.ini @@ -0,0 +1,13 @@ +[GeneratorExternal] +fileName = ${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGEM/external/generator/Generator_pythia8_forcedDecays.C +funcName=GeneratePythia8ForcedDecays("411;421;431;4122;4232;4132;4332") + +[GeneratorPythia8] +config = ${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGEM/pythia8/generator/pythia8_hf_cocktail_pp502.cfg +hooksFileName = ${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGHF/pythia8/hooks/pythia8_userhooks_qqbar.C +hooksFuncName = pythia8_userhooks_ccbar(-12.,12.) +includePartonEvent=true + +[DecayerPythia8] +config[0] = ${O2DPG_MC_CONFIG_ROOT}/MC/config/common/pythia8/decayer/base.cfg +config[1] = ${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGEM/pythia8/decayer/force_semileptonic_charm.cfg diff --git a/MC/config/PWGEM/ini/Pythia8_Charm_Cocktail_pp536.ini b/MC/config/PWGEM/ini/Pythia8_Charm_Cocktail_pp536.ini new file mode 100644 index 000000000..1b5d0e378 --- /dev/null +++ b/MC/config/PWGEM/ini/Pythia8_Charm_Cocktail_pp536.ini @@ -0,0 +1,13 @@ +[GeneratorExternal] +fileName = ${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGEM/external/generator/Generator_pythia8_forcedDecays.C +funcName=GeneratePythia8ForcedDecays("411;421;431;4122;4232;4132;4332") + +[GeneratorPythia8] +config = ${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGEM/pythia8/generator/pythia8_hf_cocktail_pp536.cfg +hooksFileName = ${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGHF/pythia8/hooks/pythia8_userhooks_qqbar.C +hooksFuncName = pythia8_userhooks_ccbar(-12.,12.) +includePartonEvent=true + +[DecayerPythia8] +config[0] = ${O2DPG_MC_CONFIG_ROOT}/MC/config/common/pythia8/decayer/base.cfg +config[1] = ${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGEM/pythia8/decayer/force_semileptonic_charm.cfg diff --git a/MC/config/PWGEM/ini/pythia8_OO_536_VM2ll.ini b/MC/config/PWGEM/ini/pythia8_OO_536_VM2ll.ini new file mode 100644 index 000000000..953d909ce --- /dev/null +++ b/MC/config/PWGEM/ini/pythia8_OO_536_VM2ll.ini @@ -0,0 +1,9 @@ +[Diamond] +width[2]=6.0 + +[GeneratorExternal] +fileName=${O2DPG_MC_CONFIG_ROOT}/MC/config/ALICE3/pythia8/generator_pythia8_ALICE3.C +funcName=generator_pythia8_ALICE3() + +[GeneratorPythia8] +config=${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGEM/pythia8/generator/pythia8_OO_536_VM2ll.cfg diff --git a/MC/config/PWGEM/ini/pythia8_PbPb_5360_VM2ll.ini b/MC/config/PWGEM/ini/pythia8_PbPb_5360_VM2ll.ini new file mode 100644 index 000000000..503e77188 --- /dev/null +++ b/MC/config/PWGEM/ini/pythia8_PbPb_5360_VM2ll.ini @@ -0,0 +1,10 @@ +#NEV_TEST> 5 +[Diamond] +width[2]=6.0 + +[GeneratorExternal] +fileName=${O2DPG_MC_CONFIG_ROOT}/MC/config/ALICE3/pythia8/generator_pythia8_ALICE3.C +funcName=generator_pythia8_ALICE3() + +[GeneratorPythia8] +config=${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGEM/pythia8/generator/pythia8_PbPb_5360_VM2ll.cfg diff --git a/MC/config/PWGEM/ini/pythia8_pp_13600_ForcedDalitz.ini b/MC/config/PWGEM/ini/pythia8_pp_13600_ForcedDalitz.ini new file mode 100644 index 000000000..1cc9c5b5b --- /dev/null +++ b/MC/config/PWGEM/ini/pythia8_pp_13600_ForcedDalitz.ini @@ -0,0 +1,8 @@ +[Diamond] +width[2]=6.0 + +[GeneratorPythia8] +config=${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGEM/pythia8/generator/configPythia_ForcedDalitz.cfg + +[DecayerPythia8] +config[0]=${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGEM/pythia8/decayer/force_dummy.cfg diff --git a/MC/config/PWGEM/ini/pythia8_pp_13600_VM2ll.ini b/MC/config/PWGEM/ini/pythia8_pp_13600_VM2ll.ini new file mode 100644 index 000000000..e261498c4 --- /dev/null +++ b/MC/config/PWGEM/ini/pythia8_pp_13600_VM2ll.ini @@ -0,0 +1,10 @@ +#NEV_TEST> 5 +[Diamond] +width[2]=6.0 + +[GeneratorExternal] +fileName=${O2DPG_MC_CONFIG_ROOT}/MC/config/ALICE3/pythia8/generator_pythia8_ALICE3.C +funcName=generator_pythia8_ALICE3() + +[GeneratorPythia8] +config=${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGEM/pythia8/generator/pythia8_pp_13600_VM2ll.cfg diff --git a/MC/config/PWGEM/ini/pythia8_pp_5360_VM2ee.ini b/MC/config/PWGEM/ini/pythia8_pp_5360_VM2ee.ini new file mode 100644 index 000000000..5b17885ed --- /dev/null +++ b/MC/config/PWGEM/ini/pythia8_pp_5360_VM2ee.ini @@ -0,0 +1,10 @@ +#NEV_TEST> 5 +[Diamond] +width[2]=6.0 + +[GeneratorExternal] +fileName=${O2DPG_MC_CONFIG_ROOT}/MC/config/ALICE3/pythia8/generator_pythia8_ALICE3.C +funcName=generator_pythia8_ALICE3() + +[GeneratorPythia8] +config=${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGEM/pythia8/generator/pythia8_pp_5360_VM2ee.cfg diff --git a/MC/config/PWGEM/ini/pythia8_pp_5360_VM2ll.ini b/MC/config/PWGEM/ini/pythia8_pp_5360_VM2ll.ini new file mode 100644 index 000000000..49be058cf --- /dev/null +++ b/MC/config/PWGEM/ini/pythia8_pp_5360_VM2ll.ini @@ -0,0 +1,10 @@ +#NEV_TEST> 5 +[Diamond] +width[2]=6.0 + +[GeneratorExternal] +fileName=${O2DPG_MC_CONFIG_ROOT}/MC/config/ALICE3/pythia8/generator_pythia8_ALICE3.C +funcName=generator_pythia8_ALICE3() + +[GeneratorPythia8] +config=${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGEM/pythia8/generator/pythia8_pp_5360_VM2ll.cfg diff --git a/MC/config/PWGEM/ini/tests/GeneratorDYee_GapTriggered_Gap2_OO5360GeV.C b/MC/config/PWGEM/ini/tests/GeneratorDYee_GapTriggered_Gap2_OO5360GeV.C new file mode 100644 index 000000000..aca7bb427 --- /dev/null +++ b/MC/config/PWGEM/ini/tests/GeneratorDYee_GapTriggered_Gap2_OO5360GeV.C @@ -0,0 +1,51 @@ +int External() { + std::string path{"o2sim_Kine.root"}; + // Check that file exists, can be opened and has the correct tree + TFile file(path.c_str(), "READ"); + if (file.IsZombie()) + { + std::cerr << "Cannot open ROOT file " << path << "\n"; + return 1; + } + auto tree = (TTree *)file.Get("o2sim"); + if (!tree) + { + std::cerr << "Cannot find tree o2sim in file " << path << "\n"; + return 1; + } + std::vector *tracks{}; + tree->SetBranchAddress("MCTrack", &tracks); + + // Check if all events are filled + auto nEvents = tree->GetEntries(); + for (Long64_t i = 0; i < nEvents; ++i) + { + tree->GetEntry(i); + if (tracks->empty()) + { + std::cerr << "Empty entry found at event " << i << "\n"; + return 1; + } + } + // check if each event has at least two oxygen ions + for (int i = 0; i < nEvents; i++) + { + auto check = tree->GetEntry(i); + int count = 0; + for (int idxMCTrack = 0; idxMCTrack < tracks->size(); ++idxMCTrack) + { + auto track = tracks->at(idxMCTrack); + if (track.GetPdgCode() == 1000080160) + { + count++; + } + } + if (count < 2) + { + std::cerr << "Event " << i << " has less than 2 oxygen ions\n"; + return 1; + } + } + + return 0; +} diff --git a/MC/config/PWGEM/ini/tests/GeneratorDYee_GapTriggered_Gap5_OO5360GeV.C b/MC/config/PWGEM/ini/tests/GeneratorDYee_GapTriggered_Gap5_OO5360GeV.C new file mode 100644 index 000000000..aca7bb427 --- /dev/null +++ b/MC/config/PWGEM/ini/tests/GeneratorDYee_GapTriggered_Gap5_OO5360GeV.C @@ -0,0 +1,51 @@ +int External() { + std::string path{"o2sim_Kine.root"}; + // Check that file exists, can be opened and has the correct tree + TFile file(path.c_str(), "READ"); + if (file.IsZombie()) + { + std::cerr << "Cannot open ROOT file " << path << "\n"; + return 1; + } + auto tree = (TTree *)file.Get("o2sim"); + if (!tree) + { + std::cerr << "Cannot find tree o2sim in file " << path << "\n"; + return 1; + } + std::vector *tracks{}; + tree->SetBranchAddress("MCTrack", &tracks); + + // Check if all events are filled + auto nEvents = tree->GetEntries(); + for (Long64_t i = 0; i < nEvents; ++i) + { + tree->GetEntry(i); + if (tracks->empty()) + { + std::cerr << "Empty entry found at event " << i << "\n"; + return 1; + } + } + // check if each event has at least two oxygen ions + for (int i = 0; i < nEvents; i++) + { + auto check = tree->GetEntry(i); + int count = 0; + for (int idxMCTrack = 0; idxMCTrack < tracks->size(); ++idxMCTrack) + { + auto track = tracks->at(idxMCTrack); + if (track.GetPdgCode() == 1000080160) + { + count++; + } + } + if (count < 2) + { + std::cerr << "Event " << i << " has less than 2 oxygen ions\n"; + return 1; + } + } + + return 0; +} diff --git a/MC/config/PWGEM/ini/tests/GeneratorDYee_GapTriggered_Gap5_pp13600GeV.C b/MC/config/PWGEM/ini/tests/GeneratorDYee_GapTriggered_Gap5_pp13600GeV.C new file mode 100644 index 000000000..0332e54fc --- /dev/null +++ b/MC/config/PWGEM/ini/tests/GeneratorDYee_GapTriggered_Gap5_pp13600GeV.C @@ -0,0 +1,51 @@ +int External() { + std::string path{"o2sim_Kine.root"}; + // Check that file exists, can be opened and has the correct tree + TFile file(path.c_str(), "READ"); + if (file.IsZombie()) + { + std::cerr << "Cannot open ROOT file " << path << "\n"; + return 1; + } + auto tree = (TTree *)file.Get("o2sim"); + if (!tree) + { + std::cerr << "Cannot find tree o2sim in file " << path << "\n"; + return 1; + } + std::vector *tracks{}; + tree->SetBranchAddress("MCTrack", &tracks); + + // Check if all events are filled + auto nEvents = tree->GetEntries(); + for (Long64_t i = 0; i < nEvents; ++i) + { + tree->GetEntry(i); + if (tracks->empty()) + { + std::cerr << "Empty entry found at event " << i << "\n"; + return 1; + } + } + // check if each event has at least two oxygen ions + for (int i = 0; i < nEvents; i++) + { + auto check = tree->GetEntry(i); + int count = 0; + for (int idxMCTrack = 0; idxMCTrack < tracks->size(); ++idxMCTrack) + { + auto track = tracks->at(idxMCTrack); + if (track.GetPdgCode() == 2212) + { + count++; + } + } + if (count < 2) + { + std::cerr << "Event " << i << " has less than 2 oxygen ions\n"; + return 1; + } + } + + return 0; +} diff --git a/MC/config/PWGEM/ini/tests/GeneratorDYee_GapTriggered_Gap5_pp5360GeV.C b/MC/config/PWGEM/ini/tests/GeneratorDYee_GapTriggered_Gap5_pp5360GeV.C new file mode 100644 index 000000000..0332e54fc --- /dev/null +++ b/MC/config/PWGEM/ini/tests/GeneratorDYee_GapTriggered_Gap5_pp5360GeV.C @@ -0,0 +1,51 @@ +int External() { + std::string path{"o2sim_Kine.root"}; + // Check that file exists, can be opened and has the correct tree + TFile file(path.c_str(), "READ"); + if (file.IsZombie()) + { + std::cerr << "Cannot open ROOT file " << path << "\n"; + return 1; + } + auto tree = (TTree *)file.Get("o2sim"); + if (!tree) + { + std::cerr << "Cannot find tree o2sim in file " << path << "\n"; + return 1; + } + std::vector *tracks{}; + tree->SetBranchAddress("MCTrack", &tracks); + + // Check if all events are filled + auto nEvents = tree->GetEntries(); + for (Long64_t i = 0; i < nEvents; ++i) + { + tree->GetEntry(i); + if (tracks->empty()) + { + std::cerr << "Empty entry found at event " << i << "\n"; + return 1; + } + } + // check if each event has at least two oxygen ions + for (int i = 0; i < nEvents; i++) + { + auto check = tree->GetEntry(i); + int count = 0; + for (int idxMCTrack = 0; idxMCTrack < tracks->size(); ++idxMCTrack) + { + auto track = tracks->at(idxMCTrack); + if (track.GetPdgCode() == 2212) + { + count++; + } + } + if (count < 2) + { + std::cerr << "Event " << i << " has less than 2 oxygen ions\n"; + return 1; + } + } + + return 0; +} diff --git a/MC/config/PWGEM/ini/tests/GeneratorDYmumu_GapTriggered_Gap5_OO5360GeV.C b/MC/config/PWGEM/ini/tests/GeneratorDYmumu_GapTriggered_Gap5_OO5360GeV.C new file mode 100644 index 000000000..aca7bb427 --- /dev/null +++ b/MC/config/PWGEM/ini/tests/GeneratorDYmumu_GapTriggered_Gap5_OO5360GeV.C @@ -0,0 +1,51 @@ +int External() { + std::string path{"o2sim_Kine.root"}; + // Check that file exists, can be opened and has the correct tree + TFile file(path.c_str(), "READ"); + if (file.IsZombie()) + { + std::cerr << "Cannot open ROOT file " << path << "\n"; + return 1; + } + auto tree = (TTree *)file.Get("o2sim"); + if (!tree) + { + std::cerr << "Cannot find tree o2sim in file " << path << "\n"; + return 1; + } + std::vector *tracks{}; + tree->SetBranchAddress("MCTrack", &tracks); + + // Check if all events are filled + auto nEvents = tree->GetEntries(); + for (Long64_t i = 0; i < nEvents; ++i) + { + tree->GetEntry(i); + if (tracks->empty()) + { + std::cerr << "Empty entry found at event " << i << "\n"; + return 1; + } + } + // check if each event has at least two oxygen ions + for (int i = 0; i < nEvents; i++) + { + auto check = tree->GetEntry(i); + int count = 0; + for (int idxMCTrack = 0; idxMCTrack < tracks->size(); ++idxMCTrack) + { + auto track = tracks->at(idxMCTrack); + if (track.GetPdgCode() == 1000080160) + { + count++; + } + } + if (count < 2) + { + std::cerr << "Event " << i << " has less than 2 oxygen ions\n"; + return 1; + } + } + + return 0; +} diff --git a/MC/config/PWGEM/ini/tests/GeneratorDYmumu_GapTriggered_Gap5_pp5360GeV.C b/MC/config/PWGEM/ini/tests/GeneratorDYmumu_GapTriggered_Gap5_pp5360GeV.C new file mode 100644 index 000000000..0332e54fc --- /dev/null +++ b/MC/config/PWGEM/ini/tests/GeneratorDYmumu_GapTriggered_Gap5_pp5360GeV.C @@ -0,0 +1,51 @@ +int External() { + std::string path{"o2sim_Kine.root"}; + // Check that file exists, can be opened and has the correct tree + TFile file(path.c_str(), "READ"); + if (file.IsZombie()) + { + std::cerr << "Cannot open ROOT file " << path << "\n"; + return 1; + } + auto tree = (TTree *)file.Get("o2sim"); + if (!tree) + { + std::cerr << "Cannot find tree o2sim in file " << path << "\n"; + return 1; + } + std::vector *tracks{}; + tree->SetBranchAddress("MCTrack", &tracks); + + // Check if all events are filled + auto nEvents = tree->GetEntries(); + for (Long64_t i = 0; i < nEvents; ++i) + { + tree->GetEntry(i); + if (tracks->empty()) + { + std::cerr << "Empty entry found at event " << i << "\n"; + return 1; + } + } + // check if each event has at least two oxygen ions + for (int i = 0; i < nEvents; i++) + { + auto check = tree->GetEntry(i); + int count = 0; + for (int idxMCTrack = 0; idxMCTrack < tracks->size(); ++idxMCTrack) + { + auto track = tracks->at(idxMCTrack); + if (track.GetPdgCode() == 2212) + { + count++; + } + } + if (count < 2) + { + std::cerr << "Event " << i << " has less than 2 oxygen ions\n"; + return 1; + } + } + + return 0; +} diff --git a/MC/config/PWGEM/ini/tests/GeneratorEMCocktail.C b/MC/config/PWGEM/ini/tests/GeneratorEMCocktail.C deleted file mode 100644 index 600908d2e..000000000 --- a/MC/config/PWGEM/ini/tests/GeneratorEMCocktail.C +++ /dev/null @@ -1,179 +0,0 @@ -int External() -{ - - std::string path{"o2sim_Kine.root"}; - TFile file(path.c_str(), "READ"); - if (file.IsZombie()) { - std::cerr << "Cannot open ROOT file " << path << "\n"; - return 1; - } - - auto tree = (TTree*)file.Get("o2sim"); - std::vector* tracks{}; - tree->SetBranchAddress("MCTrack", &tracks); - - int nElectrons = 0; - int nPositrons = 0; - int nPions = 0; - int nEtas = 0; - int nEtaPrimes = 0; - int nRhos = 0; - int nPhis = 0; - int nOmegas = 0; - int nJPsis = 0; - int nPhotons = 0; - int nElectronsFromPion = 0; - int nElectronsFromEta = 0; - int nElectronsFromEtaPrime = 0; - int nElectronsFromOmega = 0; - int nElectronsFromRho = 0; - int nElectronsFromPhi = 0; - int nElectronsFromJPsi = 0; - int nLeptonsToBeDone = 0; - auto nEvents = tree->GetEntries(); - for (int i = 0; i < nEvents; i++) { - tree->GetEntry(i); - for (auto& track : *tracks) { - bool hasMother = track.getMotherTrackId()>-1; - auto pdg = track.GetPdgCode(); - switch (pdg){ - case 11: - nElectrons++; - if (track.getToBeDone()){ - nLeptonsToBeDone++; - } - break; - case -11: - nPositrons++; - if (track.getToBeDone()){ - nLeptonsToBeDone++; - } - break; - case 111: - if (!hasMother) - nPions++; - break; - case 221: - if (!hasMother) - nEtas++; - break; - case 331: - if (!hasMother) - nEtaPrimes++; - break; - case 113: - if (!hasMother) - nRhos++; - break; - case 223: - if (!hasMother) - nOmegas++; - break; - case 333: - if (!hasMother) - nPhis++; - break; - case 443: - if (!hasMother) - nJPsis++; - break; - case 22: - nPhotons++; - } - if (pdg == 11){ - int imother = track.getMotherTrackId(); - if (imother > -1) { - auto mother = (*tracks)[imother]; - int mpdg = mother.GetPdgCode(); - switch (mpdg){ - case 111: - nElectronsFromPion++; - break; - case 221: - nElectronsFromEta++; - break; - case 331: - nElectronsFromEtaPrime++; - break; - case 113: - nElectronsFromRho++; - break; - case 223: - nElectronsFromOmega++; - break; - case 333: - nElectronsFromPhi++; - break; - case 443: - nElectronsFromJPsi++; - break; - default: - std::cout << "Found electron with mother pdg " << mpdg << "\n"; - } - } else { - std::cerr << "Found electron with no mother" << "\n"; - return 1; - } - } - } - } - int nMothers = nPions+nEtas+nEtaPrimes+nRhos+nOmegas+nPhis+nJPsis; - std::cout << "#Events: " << nEvents << "\n" - << "#Electrons: " << nElectrons << "\n" - << "#Positrons: " << nPositrons << "\n" - << "#Leptons: " << nElectrons+nPositrons << ", #LeptonsToDone: " << nLeptonsToBeDone << "\n" - << "#Photons: " << nPhotons << "\n" - << "#Pions: " << nPions << ", #ElectronsFromPion: " << nElectronsFromPion << "\n" - << "#Etas: " << nEtas << ", #ElectronsFromEta: " << nElectronsFromEta << "\n" - << "#EtaPrimes: " << nEtaPrimes << ", #ElectronsFromEtaPrime: " << nElectronsFromEtaPrime << "\n" - << "#Rhos: " << nRhos << ", #ElectronsFromRho: " << nElectronsFromRho << "\n" - << "#Omegas: " << nOmegas << ", #ElectronsFromOmega: " << nElectronsFromOmega << "\n" - << "#Phis: " << nPhis << ", #ElectronsFromPhi: " << nElectronsFromPhi << "\n" - << "#JPsis: " << nJPsis << ", #ElectronsFromJPsi: " << nElectronsFromJPsi << "\n"; - if (nElectrons == 0) { - std::cerr << "No electrons found\n"; - return 1; - } - if (nElectrons != nPositrons) { - std::cerr << "Number of electrons should match number of positrons\n"; - return 1; - } - if (nLeptonsToBeDone != nElectrons+nPositrons) { - std::cerr << "The number of leptons should be the same as the number of leptons which should be transported.\n"; - return 1; - } - if (nMothers < nEvents) { - std::cerr << "The number of mother particles (pi0, eta, etaprime, rho, omega, phi, JPsi) must be at least the number of events\n"; - return 1; - } - if (nElectronsFromPion < nPions) { - std::cerr << "Number of of electrons from pions has to be at least the number of pions\n"; - return 1; - } - if (nElectronsFromEta < nEtas) { - std::cerr << "Number of of electrons from etas has to be at least the number of etas\n"; - return 1; - } - if (nElectronsFromEtaPrime < nEtaPrimes) { - std::cerr << "Number of of electrons from etaprimes has to be at least the number of etaprimes\n"; - return 1; - } - if (nElectronsFromRho < nRhos) { - std::cerr << "Number of of electrons from rhos has to be at least the number of rhos\n"; - return 1; - } - if (nElectronsFromOmega < nOmegas) { - std::cerr << "Number of of electrons from omegas has to be at least the number of omegas\n"; - return 1; - } - if (nElectronsFromPhi < nPhis) { - std::cerr << "Number of of electrons from phis has to be at least the number of phis\n"; - return 1; - } - if (nElectronsFromJPsi < nJPsis) { - std::cerr << "Number of of electrons from JPsis has to be at least the number of JPsis\n"; - return 1; - } - - return 0; -} diff --git a/MC/config/PWGEM/ini/tests/GeneratorEMCocktail_502PbPb_0005.C b/MC/config/PWGEM/ini/tests/GeneratorEMCocktail_502PbPb_0005.C new file mode 100644 index 000000000..a78a0cc8e --- /dev/null +++ b/MC/config/PWGEM/ini/tests/GeneratorEMCocktail_502PbPb_0005.C @@ -0,0 +1,64 @@ +int External() +{ + + int checkPdgDecay = -11; + std::string path{"o2sim_Kine.root"}; + TFile file(path.c_str(), "READ"); + if (file.IsZombie()) { + std::cerr << "Cannot open ROOT file " << path << "\n"; + return 1; + } + + auto tree = (TTree*)file.Get("o2sim"); + std::vector* tracks{}; + tree->SetBranchAddress("MCTrack", &tracks); + + int nMesons{}; + int nMesonsDiElectronDecay{}; + auto nEvents = tree->GetEntries(); + + for (int i = 0; i < nEvents; i++) { + tree->GetEntry(i); + for (auto& track : *tracks) { + auto pdg = track.GetPdgCode(); + auto y = track.GetRapidity(); + if ((pdg == 111) || (pdg == 221) || (pdg == 331) || (pdg == 223) || (pdg == 113) || (pdg == 333)) { + if ((y>-1.2) && (y<1.2)) { + nMesons++; + Int_t counterel = 0; + Int_t counterpos = 0; + int k1 = track.getFirstDaughterTrackId(); + int k2 = track.getLastDaughterTrackId(); + // k1 < k2 and no -1 for k2 + for (int d=k1; d <= k2; d++) { + if (d>0) { + auto decay = (*tracks)[d]; + int pdgdecay = decay.GetPdgCode(); + if (pdgdecay == 11) { + counterel++; + } + if (pdgdecay == -11) { + counterpos++; + } + } + } + if ((counterel>0) && (counterpos>0)) nMesonsDiElectronDecay++; + } + } + } + } + + std::cout << "#events: " << nEvents << "\n" + << "#mesons: " << nMesons << "\n" + << "#mesons which decay semi-electronicly: " << nMesonsDiElectronDecay << "\n"; + if (nMesonsDiElectronDecay < nEvents) { + std::cerr << "One should have at least one meson that decays into dielectrons per event.\n"; + return 1; + } + if (nMesons < nEvents) { + std::cerr << "One meson per event should be produced.\n"; + return 1; + } + + return 0; +} diff --git a/MC/config/PWGEM/ini/tests/GeneratorEMCocktail_502PbPb_0510.C b/MC/config/PWGEM/ini/tests/GeneratorEMCocktail_502PbPb_0510.C new file mode 100644 index 000000000..a78a0cc8e --- /dev/null +++ b/MC/config/PWGEM/ini/tests/GeneratorEMCocktail_502PbPb_0510.C @@ -0,0 +1,64 @@ +int External() +{ + + int checkPdgDecay = -11; + std::string path{"o2sim_Kine.root"}; + TFile file(path.c_str(), "READ"); + if (file.IsZombie()) { + std::cerr << "Cannot open ROOT file " << path << "\n"; + return 1; + } + + auto tree = (TTree*)file.Get("o2sim"); + std::vector* tracks{}; + tree->SetBranchAddress("MCTrack", &tracks); + + int nMesons{}; + int nMesonsDiElectronDecay{}; + auto nEvents = tree->GetEntries(); + + for (int i = 0; i < nEvents; i++) { + tree->GetEntry(i); + for (auto& track : *tracks) { + auto pdg = track.GetPdgCode(); + auto y = track.GetRapidity(); + if ((pdg == 111) || (pdg == 221) || (pdg == 331) || (pdg == 223) || (pdg == 113) || (pdg == 333)) { + if ((y>-1.2) && (y<1.2)) { + nMesons++; + Int_t counterel = 0; + Int_t counterpos = 0; + int k1 = track.getFirstDaughterTrackId(); + int k2 = track.getLastDaughterTrackId(); + // k1 < k2 and no -1 for k2 + for (int d=k1; d <= k2; d++) { + if (d>0) { + auto decay = (*tracks)[d]; + int pdgdecay = decay.GetPdgCode(); + if (pdgdecay == 11) { + counterel++; + } + if (pdgdecay == -11) { + counterpos++; + } + } + } + if ((counterel>0) && (counterpos>0)) nMesonsDiElectronDecay++; + } + } + } + } + + std::cout << "#events: " << nEvents << "\n" + << "#mesons: " << nMesons << "\n" + << "#mesons which decay semi-electronicly: " << nMesonsDiElectronDecay << "\n"; + if (nMesonsDiElectronDecay < nEvents) { + std::cerr << "One should have at least one meson that decays into dielectrons per event.\n"; + return 1; + } + if (nMesons < nEvents) { + std::cerr << "One meson per event should be produced.\n"; + return 1; + } + + return 0; +} diff --git a/MC/config/PWGEM/ini/tests/GeneratorEMCocktail_502PbPb_1020.C b/MC/config/PWGEM/ini/tests/GeneratorEMCocktail_502PbPb_1020.C new file mode 100644 index 000000000..a78a0cc8e --- /dev/null +++ b/MC/config/PWGEM/ini/tests/GeneratorEMCocktail_502PbPb_1020.C @@ -0,0 +1,64 @@ +int External() +{ + + int checkPdgDecay = -11; + std::string path{"o2sim_Kine.root"}; + TFile file(path.c_str(), "READ"); + if (file.IsZombie()) { + std::cerr << "Cannot open ROOT file " << path << "\n"; + return 1; + } + + auto tree = (TTree*)file.Get("o2sim"); + std::vector* tracks{}; + tree->SetBranchAddress("MCTrack", &tracks); + + int nMesons{}; + int nMesonsDiElectronDecay{}; + auto nEvents = tree->GetEntries(); + + for (int i = 0; i < nEvents; i++) { + tree->GetEntry(i); + for (auto& track : *tracks) { + auto pdg = track.GetPdgCode(); + auto y = track.GetRapidity(); + if ((pdg == 111) || (pdg == 221) || (pdg == 331) || (pdg == 223) || (pdg == 113) || (pdg == 333)) { + if ((y>-1.2) && (y<1.2)) { + nMesons++; + Int_t counterel = 0; + Int_t counterpos = 0; + int k1 = track.getFirstDaughterTrackId(); + int k2 = track.getLastDaughterTrackId(); + // k1 < k2 and no -1 for k2 + for (int d=k1; d <= k2; d++) { + if (d>0) { + auto decay = (*tracks)[d]; + int pdgdecay = decay.GetPdgCode(); + if (pdgdecay == 11) { + counterel++; + } + if (pdgdecay == -11) { + counterpos++; + } + } + } + if ((counterel>0) && (counterpos>0)) nMesonsDiElectronDecay++; + } + } + } + } + + std::cout << "#events: " << nEvents << "\n" + << "#mesons: " << nMesons << "\n" + << "#mesons which decay semi-electronicly: " << nMesonsDiElectronDecay << "\n"; + if (nMesonsDiElectronDecay < nEvents) { + std::cerr << "One should have at least one meson that decays into dielectrons per event.\n"; + return 1; + } + if (nMesons < nEvents) { + std::cerr << "One meson per event should be produced.\n"; + return 1; + } + + return 0; +} diff --git a/MC/config/PWGEM/ini/tests/GeneratorEMCocktail_502PbPb_2030.C b/MC/config/PWGEM/ini/tests/GeneratorEMCocktail_502PbPb_2030.C new file mode 100644 index 000000000..a78a0cc8e --- /dev/null +++ b/MC/config/PWGEM/ini/tests/GeneratorEMCocktail_502PbPb_2030.C @@ -0,0 +1,64 @@ +int External() +{ + + int checkPdgDecay = -11; + std::string path{"o2sim_Kine.root"}; + TFile file(path.c_str(), "READ"); + if (file.IsZombie()) { + std::cerr << "Cannot open ROOT file " << path << "\n"; + return 1; + } + + auto tree = (TTree*)file.Get("o2sim"); + std::vector* tracks{}; + tree->SetBranchAddress("MCTrack", &tracks); + + int nMesons{}; + int nMesonsDiElectronDecay{}; + auto nEvents = tree->GetEntries(); + + for (int i = 0; i < nEvents; i++) { + tree->GetEntry(i); + for (auto& track : *tracks) { + auto pdg = track.GetPdgCode(); + auto y = track.GetRapidity(); + if ((pdg == 111) || (pdg == 221) || (pdg == 331) || (pdg == 223) || (pdg == 113) || (pdg == 333)) { + if ((y>-1.2) && (y<1.2)) { + nMesons++; + Int_t counterel = 0; + Int_t counterpos = 0; + int k1 = track.getFirstDaughterTrackId(); + int k2 = track.getLastDaughterTrackId(); + // k1 < k2 and no -1 for k2 + for (int d=k1; d <= k2; d++) { + if (d>0) { + auto decay = (*tracks)[d]; + int pdgdecay = decay.GetPdgCode(); + if (pdgdecay == 11) { + counterel++; + } + if (pdgdecay == -11) { + counterpos++; + } + } + } + if ((counterel>0) && (counterpos>0)) nMesonsDiElectronDecay++; + } + } + } + } + + std::cout << "#events: " << nEvents << "\n" + << "#mesons: " << nMesons << "\n" + << "#mesons which decay semi-electronicly: " << nMesonsDiElectronDecay << "\n"; + if (nMesonsDiElectronDecay < nEvents) { + std::cerr << "One should have at least one meson that decays into dielectrons per event.\n"; + return 1; + } + if (nMesons < nEvents) { + std::cerr << "One meson per event should be produced.\n"; + return 1; + } + + return 0; +} diff --git a/MC/config/PWGEM/ini/tests/GeneratorEMCocktail_502PbPb_3040.C b/MC/config/PWGEM/ini/tests/GeneratorEMCocktail_502PbPb_3040.C new file mode 100644 index 000000000..a78a0cc8e --- /dev/null +++ b/MC/config/PWGEM/ini/tests/GeneratorEMCocktail_502PbPb_3040.C @@ -0,0 +1,64 @@ +int External() +{ + + int checkPdgDecay = -11; + std::string path{"o2sim_Kine.root"}; + TFile file(path.c_str(), "READ"); + if (file.IsZombie()) { + std::cerr << "Cannot open ROOT file " << path << "\n"; + return 1; + } + + auto tree = (TTree*)file.Get("o2sim"); + std::vector* tracks{}; + tree->SetBranchAddress("MCTrack", &tracks); + + int nMesons{}; + int nMesonsDiElectronDecay{}; + auto nEvents = tree->GetEntries(); + + for (int i = 0; i < nEvents; i++) { + tree->GetEntry(i); + for (auto& track : *tracks) { + auto pdg = track.GetPdgCode(); + auto y = track.GetRapidity(); + if ((pdg == 111) || (pdg == 221) || (pdg == 331) || (pdg == 223) || (pdg == 113) || (pdg == 333)) { + if ((y>-1.2) && (y<1.2)) { + nMesons++; + Int_t counterel = 0; + Int_t counterpos = 0; + int k1 = track.getFirstDaughterTrackId(); + int k2 = track.getLastDaughterTrackId(); + // k1 < k2 and no -1 for k2 + for (int d=k1; d <= k2; d++) { + if (d>0) { + auto decay = (*tracks)[d]; + int pdgdecay = decay.GetPdgCode(); + if (pdgdecay == 11) { + counterel++; + } + if (pdgdecay == -11) { + counterpos++; + } + } + } + if ((counterel>0) && (counterpos>0)) nMesonsDiElectronDecay++; + } + } + } + } + + std::cout << "#events: " << nEvents << "\n" + << "#mesons: " << nMesons << "\n" + << "#mesons which decay semi-electronicly: " << nMesonsDiElectronDecay << "\n"; + if (nMesonsDiElectronDecay < nEvents) { + std::cerr << "One should have at least one meson that decays into dielectrons per event.\n"; + return 1; + } + if (nMesons < nEvents) { + std::cerr << "One meson per event should be produced.\n"; + return 1; + } + + return 0; +} diff --git a/MC/config/PWGEM/ini/tests/GeneratorEMCocktail_502PbPb_4050.C b/MC/config/PWGEM/ini/tests/GeneratorEMCocktail_502PbPb_4050.C new file mode 100644 index 000000000..a78a0cc8e --- /dev/null +++ b/MC/config/PWGEM/ini/tests/GeneratorEMCocktail_502PbPb_4050.C @@ -0,0 +1,64 @@ +int External() +{ + + int checkPdgDecay = -11; + std::string path{"o2sim_Kine.root"}; + TFile file(path.c_str(), "READ"); + if (file.IsZombie()) { + std::cerr << "Cannot open ROOT file " << path << "\n"; + return 1; + } + + auto tree = (TTree*)file.Get("o2sim"); + std::vector* tracks{}; + tree->SetBranchAddress("MCTrack", &tracks); + + int nMesons{}; + int nMesonsDiElectronDecay{}; + auto nEvents = tree->GetEntries(); + + for (int i = 0; i < nEvents; i++) { + tree->GetEntry(i); + for (auto& track : *tracks) { + auto pdg = track.GetPdgCode(); + auto y = track.GetRapidity(); + if ((pdg == 111) || (pdg == 221) || (pdg == 331) || (pdg == 223) || (pdg == 113) || (pdg == 333)) { + if ((y>-1.2) && (y<1.2)) { + nMesons++; + Int_t counterel = 0; + Int_t counterpos = 0; + int k1 = track.getFirstDaughterTrackId(); + int k2 = track.getLastDaughterTrackId(); + // k1 < k2 and no -1 for k2 + for (int d=k1; d <= k2; d++) { + if (d>0) { + auto decay = (*tracks)[d]; + int pdgdecay = decay.GetPdgCode(); + if (pdgdecay == 11) { + counterel++; + } + if (pdgdecay == -11) { + counterpos++; + } + } + } + if ((counterel>0) && (counterpos>0)) nMesonsDiElectronDecay++; + } + } + } + } + + std::cout << "#events: " << nEvents << "\n" + << "#mesons: " << nMesons << "\n" + << "#mesons which decay semi-electronicly: " << nMesonsDiElectronDecay << "\n"; + if (nMesonsDiElectronDecay < nEvents) { + std::cerr << "One should have at least one meson that decays into dielectrons per event.\n"; + return 1; + } + if (nMesons < nEvents) { + std::cerr << "One meson per event should be produced.\n"; + return 1; + } + + return 0; +} diff --git a/MC/config/PWGEM/ini/tests/GeneratorEMCocktail_502PbPb_5060.C b/MC/config/PWGEM/ini/tests/GeneratorEMCocktail_502PbPb_5060.C new file mode 100644 index 000000000..a78a0cc8e --- /dev/null +++ b/MC/config/PWGEM/ini/tests/GeneratorEMCocktail_502PbPb_5060.C @@ -0,0 +1,64 @@ +int External() +{ + + int checkPdgDecay = -11; + std::string path{"o2sim_Kine.root"}; + TFile file(path.c_str(), "READ"); + if (file.IsZombie()) { + std::cerr << "Cannot open ROOT file " << path << "\n"; + return 1; + } + + auto tree = (TTree*)file.Get("o2sim"); + std::vector* tracks{}; + tree->SetBranchAddress("MCTrack", &tracks); + + int nMesons{}; + int nMesonsDiElectronDecay{}; + auto nEvents = tree->GetEntries(); + + for (int i = 0; i < nEvents; i++) { + tree->GetEntry(i); + for (auto& track : *tracks) { + auto pdg = track.GetPdgCode(); + auto y = track.GetRapidity(); + if ((pdg == 111) || (pdg == 221) || (pdg == 331) || (pdg == 223) || (pdg == 113) || (pdg == 333)) { + if ((y>-1.2) && (y<1.2)) { + nMesons++; + Int_t counterel = 0; + Int_t counterpos = 0; + int k1 = track.getFirstDaughterTrackId(); + int k2 = track.getLastDaughterTrackId(); + // k1 < k2 and no -1 for k2 + for (int d=k1; d <= k2; d++) { + if (d>0) { + auto decay = (*tracks)[d]; + int pdgdecay = decay.GetPdgCode(); + if (pdgdecay == 11) { + counterel++; + } + if (pdgdecay == -11) { + counterpos++; + } + } + } + if ((counterel>0) && (counterpos>0)) nMesonsDiElectronDecay++; + } + } + } + } + + std::cout << "#events: " << nEvents << "\n" + << "#mesons: " << nMesons << "\n" + << "#mesons which decay semi-electronicly: " << nMesonsDiElectronDecay << "\n"; + if (nMesonsDiElectronDecay < nEvents) { + std::cerr << "One should have at least one meson that decays into dielectrons per event.\n"; + return 1; + } + if (nMesons < nEvents) { + std::cerr << "One meson per event should be produced.\n"; + return 1; + } + + return 0; +} diff --git a/MC/config/PWGEM/ini/tests/GeneratorEMCocktail_502PbPb_6070.C b/MC/config/PWGEM/ini/tests/GeneratorEMCocktail_502PbPb_6070.C new file mode 100644 index 000000000..a78a0cc8e --- /dev/null +++ b/MC/config/PWGEM/ini/tests/GeneratorEMCocktail_502PbPb_6070.C @@ -0,0 +1,64 @@ +int External() +{ + + int checkPdgDecay = -11; + std::string path{"o2sim_Kine.root"}; + TFile file(path.c_str(), "READ"); + if (file.IsZombie()) { + std::cerr << "Cannot open ROOT file " << path << "\n"; + return 1; + } + + auto tree = (TTree*)file.Get("o2sim"); + std::vector* tracks{}; + tree->SetBranchAddress("MCTrack", &tracks); + + int nMesons{}; + int nMesonsDiElectronDecay{}; + auto nEvents = tree->GetEntries(); + + for (int i = 0; i < nEvents; i++) { + tree->GetEntry(i); + for (auto& track : *tracks) { + auto pdg = track.GetPdgCode(); + auto y = track.GetRapidity(); + if ((pdg == 111) || (pdg == 221) || (pdg == 331) || (pdg == 223) || (pdg == 113) || (pdg == 333)) { + if ((y>-1.2) && (y<1.2)) { + nMesons++; + Int_t counterel = 0; + Int_t counterpos = 0; + int k1 = track.getFirstDaughterTrackId(); + int k2 = track.getLastDaughterTrackId(); + // k1 < k2 and no -1 for k2 + for (int d=k1; d <= k2; d++) { + if (d>0) { + auto decay = (*tracks)[d]; + int pdgdecay = decay.GetPdgCode(); + if (pdgdecay == 11) { + counterel++; + } + if (pdgdecay == -11) { + counterpos++; + } + } + } + if ((counterel>0) && (counterpos>0)) nMesonsDiElectronDecay++; + } + } + } + } + + std::cout << "#events: " << nEvents << "\n" + << "#mesons: " << nMesons << "\n" + << "#mesons which decay semi-electronicly: " << nMesonsDiElectronDecay << "\n"; + if (nMesonsDiElectronDecay < nEvents) { + std::cerr << "One should have at least one meson that decays into dielectrons per event.\n"; + return 1; + } + if (nMesons < nEvents) { + std::cerr << "One meson per event should be produced.\n"; + return 1; + } + + return 0; +} diff --git a/MC/config/PWGEM/ini/tests/GeneratorEMCocktail_502PbPb_7080.C b/MC/config/PWGEM/ini/tests/GeneratorEMCocktail_502PbPb_7080.C new file mode 100644 index 000000000..a78a0cc8e --- /dev/null +++ b/MC/config/PWGEM/ini/tests/GeneratorEMCocktail_502PbPb_7080.C @@ -0,0 +1,64 @@ +int External() +{ + + int checkPdgDecay = -11; + std::string path{"o2sim_Kine.root"}; + TFile file(path.c_str(), "READ"); + if (file.IsZombie()) { + std::cerr << "Cannot open ROOT file " << path << "\n"; + return 1; + } + + auto tree = (TTree*)file.Get("o2sim"); + std::vector* tracks{}; + tree->SetBranchAddress("MCTrack", &tracks); + + int nMesons{}; + int nMesonsDiElectronDecay{}; + auto nEvents = tree->GetEntries(); + + for (int i = 0; i < nEvents; i++) { + tree->GetEntry(i); + for (auto& track : *tracks) { + auto pdg = track.GetPdgCode(); + auto y = track.GetRapidity(); + if ((pdg == 111) || (pdg == 221) || (pdg == 331) || (pdg == 223) || (pdg == 113) || (pdg == 333)) { + if ((y>-1.2) && (y<1.2)) { + nMesons++; + Int_t counterel = 0; + Int_t counterpos = 0; + int k1 = track.getFirstDaughterTrackId(); + int k2 = track.getLastDaughterTrackId(); + // k1 < k2 and no -1 for k2 + for (int d=k1; d <= k2; d++) { + if (d>0) { + auto decay = (*tracks)[d]; + int pdgdecay = decay.GetPdgCode(); + if (pdgdecay == 11) { + counterel++; + } + if (pdgdecay == -11) { + counterpos++; + } + } + } + if ((counterel>0) && (counterpos>0)) nMesonsDiElectronDecay++; + } + } + } + } + + std::cout << "#events: " << nEvents << "\n" + << "#mesons: " << nMesons << "\n" + << "#mesons which decay semi-electronicly: " << nMesonsDiElectronDecay << "\n"; + if (nMesonsDiElectronDecay < nEvents) { + std::cerr << "One should have at least one meson that decays into dielectrons per event.\n"; + return 1; + } + if (nMesons < nEvents) { + std::cerr << "One meson per event should be produced.\n"; + return 1; + } + + return 0; +} diff --git a/MC/config/PWGEM/ini/tests/GeneratorEMCocktail_502PbPb_8090.C b/MC/config/PWGEM/ini/tests/GeneratorEMCocktail_502PbPb_8090.C new file mode 100644 index 000000000..a78a0cc8e --- /dev/null +++ b/MC/config/PWGEM/ini/tests/GeneratorEMCocktail_502PbPb_8090.C @@ -0,0 +1,64 @@ +int External() +{ + + int checkPdgDecay = -11; + std::string path{"o2sim_Kine.root"}; + TFile file(path.c_str(), "READ"); + if (file.IsZombie()) { + std::cerr << "Cannot open ROOT file " << path << "\n"; + return 1; + } + + auto tree = (TTree*)file.Get("o2sim"); + std::vector* tracks{}; + tree->SetBranchAddress("MCTrack", &tracks); + + int nMesons{}; + int nMesonsDiElectronDecay{}; + auto nEvents = tree->GetEntries(); + + for (int i = 0; i < nEvents; i++) { + tree->GetEntry(i); + for (auto& track : *tracks) { + auto pdg = track.GetPdgCode(); + auto y = track.GetRapidity(); + if ((pdg == 111) || (pdg == 221) || (pdg == 331) || (pdg == 223) || (pdg == 113) || (pdg == 333)) { + if ((y>-1.2) && (y<1.2)) { + nMesons++; + Int_t counterel = 0; + Int_t counterpos = 0; + int k1 = track.getFirstDaughterTrackId(); + int k2 = track.getLastDaughterTrackId(); + // k1 < k2 and no -1 for k2 + for (int d=k1; d <= k2; d++) { + if (d>0) { + auto decay = (*tracks)[d]; + int pdgdecay = decay.GetPdgCode(); + if (pdgdecay == 11) { + counterel++; + } + if (pdgdecay == -11) { + counterpos++; + } + } + } + if ((counterel>0) && (counterpos>0)) nMesonsDiElectronDecay++; + } + } + } + } + + std::cout << "#events: " << nEvents << "\n" + << "#mesons: " << nMesons << "\n" + << "#mesons which decay semi-electronicly: " << nMesonsDiElectronDecay << "\n"; + if (nMesonsDiElectronDecay < nEvents) { + std::cerr << "One should have at least one meson that decays into dielectrons per event.\n"; + return 1; + } + if (nMesons < nEvents) { + std::cerr << "One meson per event should be produced.\n"; + return 1; + } + + return 0; +} diff --git a/MC/config/PWGEM/ini/tests/GeneratorEMCocktail_Run3_OO.C b/MC/config/PWGEM/ini/tests/GeneratorEMCocktail_Run3_OO.C new file mode 100644 index 000000000..a78a0cc8e --- /dev/null +++ b/MC/config/PWGEM/ini/tests/GeneratorEMCocktail_Run3_OO.C @@ -0,0 +1,64 @@ +int External() +{ + + int checkPdgDecay = -11; + std::string path{"o2sim_Kine.root"}; + TFile file(path.c_str(), "READ"); + if (file.IsZombie()) { + std::cerr << "Cannot open ROOT file " << path << "\n"; + return 1; + } + + auto tree = (TTree*)file.Get("o2sim"); + std::vector* tracks{}; + tree->SetBranchAddress("MCTrack", &tracks); + + int nMesons{}; + int nMesonsDiElectronDecay{}; + auto nEvents = tree->GetEntries(); + + for (int i = 0; i < nEvents; i++) { + tree->GetEntry(i); + for (auto& track : *tracks) { + auto pdg = track.GetPdgCode(); + auto y = track.GetRapidity(); + if ((pdg == 111) || (pdg == 221) || (pdg == 331) || (pdg == 223) || (pdg == 113) || (pdg == 333)) { + if ((y>-1.2) && (y<1.2)) { + nMesons++; + Int_t counterel = 0; + Int_t counterpos = 0; + int k1 = track.getFirstDaughterTrackId(); + int k2 = track.getLastDaughterTrackId(); + // k1 < k2 and no -1 for k2 + for (int d=k1; d <= k2; d++) { + if (d>0) { + auto decay = (*tracks)[d]; + int pdgdecay = decay.GetPdgCode(); + if (pdgdecay == 11) { + counterel++; + } + if (pdgdecay == -11) { + counterpos++; + } + } + } + if ((counterel>0) && (counterpos>0)) nMesonsDiElectronDecay++; + } + } + } + } + + std::cout << "#events: " << nEvents << "\n" + << "#mesons: " << nMesons << "\n" + << "#mesons which decay semi-electronicly: " << nMesonsDiElectronDecay << "\n"; + if (nMesonsDiElectronDecay < nEvents) { + std::cerr << "One should have at least one meson that decays into dielectrons per event.\n"; + return 1; + } + if (nMesons < nEvents) { + std::cerr << "One meson per event should be produced.\n"; + return 1; + } + + return 0; +} diff --git a/MC/config/PWGEM/ini/tests/GeneratorHFGapTriggered_BeautyForcedDecay_Gap2_OO_electron.C b/MC/config/PWGEM/ini/tests/GeneratorHFGapTriggered_BeautyForcedDecay_Gap2_OO_electron.C new file mode 100644 index 000000000..d4c7056e4 --- /dev/null +++ b/MC/config/PWGEM/ini/tests/GeneratorHFGapTriggered_BeautyForcedDecay_Gap2_OO_electron.C @@ -0,0 +1,117 @@ +int External() +{ + int checkPdgDecay = 11; + std::string path{"o2sim_Kine.root"}; + TFile file(path.c_str(), "READ"); + if (file.IsZombie()) { + std::cerr << "Cannot open ROOT file " << path << "\n"; + return 1; + } + + float ratioTrigger = 1./3; // one event triggered out of 3 + auto tree = (TTree*)file.Get("o2sim"); + std::vector* tracks{}; + tree->SetBranchAddress("MCTrack", &tracks); + + int nLeptonsInAcceptance{}; + int nLeptons{}; + int nAntileptons{}; + int nLeptonsToBeDone{}; + int nAntileptonsToBeDone{}; + int nSignalPairs{}; + int nLeptonPairs{}; + int nLeptonPairsToBeDone{}; + auto nEvents = tree->GetEntries(); + + for (int i = 0; i < nEvents; i++) { + printf("Event %d\n",i); + tree->GetEntry(i); + int nElectrons = 0; + int nPositrons = 0; + int nElectronsToBeDone = 0; + int nPositronsToBeDone = 0; + int nOpenBeautyPos = 0; + int nOpenBeautyNeg = 0; + int nPositronsElectronsInAcceptance = 0; + for (auto& track : *tracks) { + auto pdg = track.GetPdgCode(); + auto y = track.GetRapidity(); + if (pdg == checkPdgDecay) { + int igmother = track.getMotherTrackId(); + if (igmother > 0) { + auto gmTrack = (*tracks)[igmother]; + int gmpdg = gmTrack.GetPdgCode(); + if (int(std::abs(gmpdg)/100.) == 5 || int(std::abs(gmpdg)/1000.) == 5 || int(std::abs(gmpdg)/100.) == 4 || int(std::abs(gmpdg)/1000.) == 4) { + nLeptons++; + nElectrons++; + if (-1 < y && y < 1) nPositronsElectronsInAcceptance++; + if (track.getToBeDone()) { + nLeptonsToBeDone++; + nElectronsToBeDone++; + } + } + } + } else if (pdg == -checkPdgDecay) { + int igmother = track.getMotherTrackId(); + if (igmother > 0) { + auto gmTrack = (*tracks)[igmother]; + int gmpdg = gmTrack.GetPdgCode(); + if (int(TMath::Abs(gmpdg)/100.) == 4 || int(TMath::Abs(gmpdg)/1000.) == 4 || int(std::abs(gmpdg)/100.) == 5 || int(std::abs(gmpdg)/1000.) == 5) { + nAntileptons++; + nPositrons++; + if (-1 < y && y < 1) nPositronsElectronsInAcceptance++; + if (track.getToBeDone()) { + nAntileptonsToBeDone++; + nPositronsToBeDone++; + } + } + } + } else if (pdg == 511 || pdg == 521 || pdg == 531 || pdg == 5122 || pdg == 5132 || pdg == 5232 || pdg == 5332) { + nOpenBeautyPos++; + } else if (pdg == -511 || pdg == -521 || pdg == -531 || pdg == -5122 || pdg == -5132 || pdg == -5232 || pdg == -5332) { + nOpenBeautyNeg++; + } + } + if (nOpenBeautyPos > 0 && nOpenBeautyNeg > 0) { + nSignalPairs++; + } + if (nPositronsElectronsInAcceptance > 1) { + nLeptonsInAcceptance++; + } + if (nElectrons > 0 && nPositrons > 0) { + nLeptonPairs++; + } + if (nElectronsToBeDone > 0 && nPositronsToBeDone > 0) nLeptonPairsToBeDone++; + } + std::cout << "#events: " << nEvents << "\n" + << "#leptons: " << nLeptons << "\n" + << "#antileptons: " << nAntileptons << "\n" + << "#leptons to be done: " << nLeptonsToBeDone << "\n" + << "#antileptons to be done: " << nAntileptonsToBeDone << "\n" + << "#Open-beauty hadron pairs: " << nSignalPairs << "\n" + << "#leptons in acceptance: " << nLeptonsInAcceptance << "\n" + << "#Electron-positron pairs " << nLeptonPairs << "\n" + << "#Electron-positron pairs to be done: " << nLeptonPairsToBeDone << "\n"; + if (nLeptons == 0 && nAntileptons == 0) { + std::cerr << "Number of leptons, number of anti-leptons should all be greater than 1.\n"; + return 1; + } + if (nLeptonPairs != nLeptonPairsToBeDone) { + std::cerr << "The number of electron-positron pairs should be the same as the number of electron-positron pairs which should be transported.\n"; + return 1; + } + if (nLeptons != nLeptonsToBeDone) { + std::cerr << "The number of leptons should be the same as the number of leptons which should be transported.\n"; + return 1; + } + if (nLeptonsInAcceptance == (nEvents/ratioTrigger)) { + std::cerr << "The number of leptons in acceptance should be at least equaled to the number of events.\n"; + return 1; + } + if (nLeptonPairs < nLeptonsInAcceptance) { + std::cerr << "The number of positron-electron pairs should be at least equaled to the number of leptons in acceptance.\n"; + return 1; + } + + return 0; +} diff --git a/MC/config/PWGEM/ini/tests/GeneratorHFGapTriggered_BeautyForcedDecay_Gap2_OO_muon.C b/MC/config/PWGEM/ini/tests/GeneratorHFGapTriggered_BeautyForcedDecay_Gap2_OO_muon.C new file mode 100644 index 000000000..dea67792e --- /dev/null +++ b/MC/config/PWGEM/ini/tests/GeneratorHFGapTriggered_BeautyForcedDecay_Gap2_OO_muon.C @@ -0,0 +1,117 @@ +int External() +{ + int checkPdgDecay = 13; + std::string path{"o2sim_Kine.root"}; + TFile file(path.c_str(), "READ"); + if (file.IsZombie()) { + std::cerr << "Cannot open ROOT file " << path << "\n"; + return 1; + } + + float ratioTrigger = 1./3; // one event triggered out of 3 + auto tree = (TTree*)file.Get("o2sim"); + std::vector* tracks{}; + tree->SetBranchAddress("MCTrack", &tracks); + + int nLeptonsInAcceptance{}; + int nLeptons{}; + int nAntileptons{}; + int nLeptonsToBeDone{}; + int nAntileptonsToBeDone{}; + int nSignalPairs{}; + int nLeptonPairs{}; + int nLeptonPairsToBeDone{}; + auto nEvents = tree->GetEntries(); + + for (int i = 0; i < nEvents; i++) { + printf("Event %d\n",i); + tree->GetEntry(i); + int nElectrons = 0; + int nPositrons = 0; + int nElectronsToBeDone = 0; + int nPositronsToBeDone = 0; + int nOpenBeautyPos = 0; + int nOpenBeautyNeg = 0; + int nPositronsElectronsInAcceptance = 0; + for (auto& track : *tracks) { + auto pdg = track.GetPdgCode(); + auto y = track.GetRapidity(); + if (pdg == checkPdgDecay) { + int igmother = track.getMotherTrackId(); + if (igmother > 0) { + auto gmTrack = (*tracks)[igmother]; + int gmpdg = gmTrack.GetPdgCode(); + if (int(std::abs(gmpdg)/100.) == 5 || int(std::abs(gmpdg)/1000.) == 5 || int(std::abs(gmpdg)/100.) == 4 || int(std::abs(gmpdg)/1000.) == 4) { + nLeptons++; + nElectrons++; + if (-1 < y && y < 1) nPositronsElectronsInAcceptance++; + if (track.getToBeDone()) { + nLeptonsToBeDone++; + nElectronsToBeDone++; + } + } + } + } else if (pdg == -checkPdgDecay) { + int igmother = track.getMotherTrackId(); + if (igmother > 0) { + auto gmTrack = (*tracks)[igmother]; + int gmpdg = gmTrack.GetPdgCode(); + if (int(TMath::Abs(gmpdg)/100.) == 4 || int(TMath::Abs(gmpdg)/1000.) == 4 || int(std::abs(gmpdg)/100.) == 5 || int(std::abs(gmpdg)/1000.) == 5) { + nAntileptons++; + nPositrons++; + if (-1 < y && y < 1) nPositronsElectronsInAcceptance++; + if (track.getToBeDone()) { + nAntileptonsToBeDone++; + nPositronsToBeDone++; + } + } + } + } else if (pdg == 511 || pdg == 521 || pdg == 531 || pdg == 5122 || pdg == 5132 || pdg == 5232 || pdg == 5332) { + nOpenBeautyPos++; + } else if (pdg == -511 || pdg == -521 || pdg == -531 || pdg == -5122 || pdg == -5132 || pdg == -5232 || pdg == -5332) { + nOpenBeautyNeg++; + } + } + if (nOpenBeautyPos > 0 && nOpenBeautyNeg > 0) { + nSignalPairs++; + } + if (nPositronsElectronsInAcceptance > 1) { + nLeptonsInAcceptance++; + } + if (nElectrons > 0 && nPositrons > 0) { + nLeptonPairs++; + } + if (nElectronsToBeDone > 0 && nPositronsToBeDone > 0) nLeptonPairsToBeDone++; + } + std::cout << "#events: " << nEvents << "\n" + << "#leptons: " << nLeptons << "\n" + << "#antileptons: " << nAntileptons << "\n" + << "#leptons to be done: " << nLeptonsToBeDone << "\n" + << "#antileptons to be done: " << nAntileptonsToBeDone << "\n" + << "#Open-beauty hadron pairs: " << nSignalPairs << "\n" + << "#leptons in acceptance: " << nLeptonsInAcceptance << "\n" + << "#Electron-positron pairs " << nLeptonPairs << "\n" + << "#Electron-positron pairs to be done: " << nLeptonPairsToBeDone << "\n"; + if (nLeptons == 0 && nAntileptons == 0) { + std::cerr << "Number of leptons, number of anti-leptons should all be greater than 1.\n"; + return 1; + } + if (nLeptonPairs != nLeptonPairsToBeDone) { + std::cerr << "The number of electron-positron pairs should be the same as the number of electron-positron pairs which should be transported.\n"; + return 1; + } + if (nLeptons != nLeptonsToBeDone) { + std::cerr << "The number of leptons should be the same as the number of leptons which should be transported.\n"; + return 1; + } + if (nLeptonsInAcceptance == (nEvents/ratioTrigger)) { + std::cerr << "The number of leptons in acceptance should be at least equaled to the number of events.\n"; + return 1; + } + if (nLeptonPairs < nLeptonsInAcceptance) { + std::cerr << "The number of positron-electron pairs should be at least equaled to the number of leptons in acceptance.\n"; + return 1; + } + + return 0; +} diff --git a/MC/config/PWGEM/ini/tests/GeneratorHFGapTriggered_BeautyForcedDecay_Gap5_pp5360GeV.C b/MC/config/PWGEM/ini/tests/GeneratorHFGapTriggered_BeautyForcedDecay_Gap5_pp5360GeV.C new file mode 100644 index 000000000..5bee390cc --- /dev/null +++ b/MC/config/PWGEM/ini/tests/GeneratorHFGapTriggered_BeautyForcedDecay_Gap5_pp5360GeV.C @@ -0,0 +1,118 @@ +int External() +{ + + int checkPdgDecay = -11; + std::string path{"o2sim_Kine.root"}; + TFile file(path.c_str(), "READ"); + if (file.IsZombie()) { + std::cerr << "Cannot open ROOT file " << path << "\n"; + return 1; + } + + float ratioTrigger = 1./3; // one event triggered out of 3 + auto tree = (TTree*)file.Get("o2sim"); + std::vector* tracks{}; + tree->SetBranchAddress("MCTrack", &tracks); + + int nLeptonsInAcceptance{}; + int nLeptons{}; + int nAntileptons{}; + int nLeptonsToBeDone{}; + int nAntileptonsToBeDone{}; + int nSignalPairs{}; + int nLeptonPairs{}; + int nLeptonPairsToBeDone{}; + auto nEvents = tree->GetEntries(); + + for (int i = 0; i < nEvents; i++) { + printf("Event %d\n",i); + tree->GetEntry(i); + int nElectrons = 0; + int nPositrons = 0; + int nElectronsToBeDone = 0; + int nPositronsToBeDone = 0; + int nOpenBeautyPos = 0; + int nOpenBeautyNeg = 0; + int nPositronsElectronsInAcceptance = 0; + for (auto& track : *tracks) { + auto pdg = track.GetPdgCode(); + auto y = track.GetRapidity(); + if (pdg == checkPdgDecay) { + int igmother = track.getMotherTrackId(); + if (igmother > 0) { + auto gmTrack = (*tracks)[igmother]; + int gmpdg = gmTrack.GetPdgCode(); + if (int(std::abs(gmpdg)/100.) == 5 || int(std::abs(gmpdg)/1000.) == 5 || int(std::abs(gmpdg)/100.) == 4 || int(std::abs(gmpdg)/1000.) == 4) { + nLeptons++; + nElectrons++; + if (-1 < y && y < 1) nPositronsElectronsInAcceptance++; + if (track.getToBeDone()) { + nLeptonsToBeDone++; + nElectronsToBeDone++; + } + } + } + } else if (pdg == -checkPdgDecay) { + int igmother = track.getMotherTrackId(); + if (igmother > 0) { + auto gmTrack = (*tracks)[igmother]; + int gmpdg = gmTrack.GetPdgCode(); + if (int(TMath::Abs(gmpdg)/100.) == 4 || int(TMath::Abs(gmpdg)/1000.) == 4 || int(std::abs(gmpdg)/100.) == 5 || int(std::abs(gmpdg)/1000.) == 5) { + nAntileptons++; + nPositrons++; + if (-1 < y && y < 1) nPositronsElectronsInAcceptance++; + if (track.getToBeDone()) { + nAntileptonsToBeDone++; + nPositronsToBeDone++; + } + } + } + } else if (pdg == 511 || pdg == 521 || pdg == 531 || pdg == 5122 || pdg == 5132 || pdg == 5232 || pdg == 5332) { + nOpenBeautyPos++; + } else if (pdg == -511 || pdg == -521 || pdg == -531 || pdg == -5122 || pdg == -5132 || pdg == -5232 || pdg == -5332) { + nOpenBeautyNeg++; + } + } + if (nOpenBeautyPos > 0 && nOpenBeautyNeg > 0) { + nSignalPairs++; + } + if (nPositronsElectronsInAcceptance > 1) { + nLeptonsInAcceptance++; + } + if (nElectrons > 0 && nPositrons > 0) { + nLeptonPairs++; + } + if (nElectronsToBeDone > 0 && nPositronsToBeDone > 0) nLeptonPairsToBeDone++; + } + std::cout << "#events: " << nEvents << "\n" + << "#leptons: " << nLeptons << "\n" + << "#antileptons: " << nAntileptons << "\n" + << "#leptons to be done: " << nLeptonsToBeDone << "\n" + << "#antileptons to be done: " << nAntileptonsToBeDone << "\n" + << "#Open-beauty hadron pairs: " << nSignalPairs << "\n" + << "#leptons in acceptance: " << nLeptonsInAcceptance << "\n" + << "#Electron-positron pairs " << nLeptonPairs << "\n" + << "#Electron-positron pairs to be done: " << nLeptonPairsToBeDone << "\n"; + if (nLeptons == 0 && nAntileptons == 0) { + std::cerr << "Number of leptons, number of anti-leptons should all be greater than 1.\n"; + return 1; + } + if (nLeptonPairs != nLeptonPairsToBeDone) { + std::cerr << "The number of electron-positron pairs should be the same as the number of electron-positron pairs which should be transported.\n"; + return 1; + } + if (nLeptons != nLeptonsToBeDone) { + std::cerr << "The number of leptons should be the same as the number of leptons which should be transported.\n"; + return 1; + } + if (nLeptonsInAcceptance == (nEvents/ratioTrigger)) { + std::cerr << "The number of leptons in acceptance should be at least equaled to the number of events.\n"; + return 1; + } + if (nLeptonPairs < nLeptonsInAcceptance) { + std::cerr << "The number of positron-electron pairs should be at least equaled to the number of leptons in acceptance.\n"; + return 1; + } + + return 0; +} diff --git a/MC/config/PWGEM/ini/tests/GeneratorHFGapTriggered_BeautyNoForcedDecay_Gap2_OO_electron.C b/MC/config/PWGEM/ini/tests/GeneratorHFGapTriggered_BeautyNoForcedDecay_Gap2_OO_electron.C new file mode 100644 index 000000000..ac2a627cf --- /dev/null +++ b/MC/config/PWGEM/ini/tests/GeneratorHFGapTriggered_BeautyNoForcedDecay_Gap2_OO_electron.C @@ -0,0 +1,112 @@ +int External() +{ + int checkPdgDecay = 11; + std::string path{"o2sim_Kine.root"}; + TFile file(path.c_str(), "READ"); + if (file.IsZombie()) { + std::cerr << "Cannot open ROOT file " << path << "\n"; + return 1; + } + + float ratioTrigger = 1./3; // one event triggered out of 3 + auto tree = (TTree*)file.Get("o2sim"); + std::vector* tracks{}; + tree->SetBranchAddress("MCTrack", &tracks); + + int nLeptonsInAcceptance{}; + int nLeptons{}; + int nAntileptons{}; + int nLeptonsToBeDone{}; + int nAntileptonsToBeDone{}; + int nSignalPairs{}; + int nLeptonPairs{}; + int nLeptonPairsToBeDone{}; + auto nEvents = tree->GetEntries(); + + for (int i = 0; i < nEvents; i++) { + tree->GetEntry(i); + int nElectrons = 0; + int nPositrons = 0; + int nElectronsToBeDone = 0; + int nPositronsToBeDone = 0; + int nOpenBeautyPos = 0; + int nOpenBeautyNeg = 0; + int nPositronsElectronsInAcceptance = 0; + for (auto& track : *tracks) { + auto pdg = track.GetPdgCode(); + auto y = track.GetRapidity(); + if (pdg == checkPdgDecay) { + int igmother = track.getMotherTrackId(); + if (igmother > 0) { + auto gmTrack = (*tracks)[igmother]; + int gmpdg = gmTrack.GetPdgCode(); + if (int(std::abs(gmpdg)/100.) == 5 || int(std::abs(gmpdg)/1000.) == 5 || int(std::abs(gmpdg)/100.) == 4 || int(std::abs(gmpdg)/1000.) == 4) { + nLeptons++; + nElectrons++; + if (-1 < y && y < 1) nPositronsElectronsInAcceptance++; + if (track.getToBeDone()) { + nLeptonsToBeDone++; + nElectronsToBeDone++; + } + } + } + } else if (pdg == -checkPdgDecay) { + int igmother = track.getMotherTrackId(); + if (igmother > 0) { + auto gmTrack = (*tracks)[igmother]; + int gmpdg = gmTrack.GetPdgCode(); + if (int(TMath::Abs(gmpdg)/100.) == 4 || int(TMath::Abs(gmpdg)/1000.) == 4 || int(std::abs(gmpdg)/100.) == 5 || int(std::abs(gmpdg)/1000.) == 5) { + nAntileptons++; + nPositrons++; + if (-1 < y && y < 1) nPositronsElectronsInAcceptance++; + if (track.getToBeDone()) { + nAntileptonsToBeDone++; + nPositronsToBeDone++; + } + } + } + } else if (pdg == 511 || pdg == 521 || pdg == 531 || pdg == 5122 || pdg == 5132 || pdg == 5232 || pdg == 5332) { + nOpenBeautyPos++; + } else if (pdg == -511 || pdg == -521 || pdg == -531 || pdg == -5122 || pdg == -5132 || pdg == -5232 || pdg == -5332) { + nOpenBeautyNeg++; + } + } + if (nOpenBeautyPos > 0 && nOpenBeautyNeg > 0) { + nSignalPairs++; + } + if (nPositronsElectronsInAcceptance > 1) { + nLeptonsInAcceptance++; + } + if (nElectrons > 0 && nPositrons > 0) { + nLeptonPairs++; + } + if (nElectronsToBeDone > 0 && nPositronsToBeDone > 0) nLeptonPairsToBeDone++; + } + std::cout << "#events: " << nEvents << "\n" + << "#leptons: " << nLeptons << "\n" + << "#antileptons: " << nAntileptons << "\n" + << "#leptons to be done: " << nLeptonsToBeDone << "\n" + << "#antileptons to be done: " << nAntileptonsToBeDone << "\n" + << "#Open-beauty hadron pairs: " << nSignalPairs << "\n" + << "#leptons in acceptance: " << nLeptonsInAcceptance << "\n" + << "#Electron-positron pairs: " << nLeptonPairs << "\n" + << "#Electron-positron pairs to be done: " << nLeptonPairsToBeDone << "\n"; + if (nLeptons == 0 && nAntileptons == 0) { + std::cerr << "Number of leptons, number of anti-leptons should all be greater than 1.\n"; + return 1; + } + if (nLeptonPairs != nLeptonPairsToBeDone) { + std::cerr << "The number of lepton pairs should be the same as the number of lepton pairs which should be transported.\n"; + return 1; + } + if (nLeptons != nLeptonsToBeDone) { + std::cerr << "The number of leptons should be the same as the number of leptons which should be transported.\n"; + return 1; + } + if (nLeptonsInAcceptance == (nEvents/ratioTrigger)) { + std::cerr << "The number of leptons in acceptance should be at least equaled to the number of events.\n"; + return 1; + } + + return 0; +} diff --git a/MC/config/PWGEM/ini/tests/GeneratorHFGapTriggered_BeautyNoForcedDecay_Gap2_OO_muon.C b/MC/config/PWGEM/ini/tests/GeneratorHFGapTriggered_BeautyNoForcedDecay_Gap2_OO_muon.C new file mode 100644 index 000000000..ac2a627cf --- /dev/null +++ b/MC/config/PWGEM/ini/tests/GeneratorHFGapTriggered_BeautyNoForcedDecay_Gap2_OO_muon.C @@ -0,0 +1,112 @@ +int External() +{ + int checkPdgDecay = 11; + std::string path{"o2sim_Kine.root"}; + TFile file(path.c_str(), "READ"); + if (file.IsZombie()) { + std::cerr << "Cannot open ROOT file " << path << "\n"; + return 1; + } + + float ratioTrigger = 1./3; // one event triggered out of 3 + auto tree = (TTree*)file.Get("o2sim"); + std::vector* tracks{}; + tree->SetBranchAddress("MCTrack", &tracks); + + int nLeptonsInAcceptance{}; + int nLeptons{}; + int nAntileptons{}; + int nLeptonsToBeDone{}; + int nAntileptonsToBeDone{}; + int nSignalPairs{}; + int nLeptonPairs{}; + int nLeptonPairsToBeDone{}; + auto nEvents = tree->GetEntries(); + + for (int i = 0; i < nEvents; i++) { + tree->GetEntry(i); + int nElectrons = 0; + int nPositrons = 0; + int nElectronsToBeDone = 0; + int nPositronsToBeDone = 0; + int nOpenBeautyPos = 0; + int nOpenBeautyNeg = 0; + int nPositronsElectronsInAcceptance = 0; + for (auto& track : *tracks) { + auto pdg = track.GetPdgCode(); + auto y = track.GetRapidity(); + if (pdg == checkPdgDecay) { + int igmother = track.getMotherTrackId(); + if (igmother > 0) { + auto gmTrack = (*tracks)[igmother]; + int gmpdg = gmTrack.GetPdgCode(); + if (int(std::abs(gmpdg)/100.) == 5 || int(std::abs(gmpdg)/1000.) == 5 || int(std::abs(gmpdg)/100.) == 4 || int(std::abs(gmpdg)/1000.) == 4) { + nLeptons++; + nElectrons++; + if (-1 < y && y < 1) nPositronsElectronsInAcceptance++; + if (track.getToBeDone()) { + nLeptonsToBeDone++; + nElectronsToBeDone++; + } + } + } + } else if (pdg == -checkPdgDecay) { + int igmother = track.getMotherTrackId(); + if (igmother > 0) { + auto gmTrack = (*tracks)[igmother]; + int gmpdg = gmTrack.GetPdgCode(); + if (int(TMath::Abs(gmpdg)/100.) == 4 || int(TMath::Abs(gmpdg)/1000.) == 4 || int(std::abs(gmpdg)/100.) == 5 || int(std::abs(gmpdg)/1000.) == 5) { + nAntileptons++; + nPositrons++; + if (-1 < y && y < 1) nPositronsElectronsInAcceptance++; + if (track.getToBeDone()) { + nAntileptonsToBeDone++; + nPositronsToBeDone++; + } + } + } + } else if (pdg == 511 || pdg == 521 || pdg == 531 || pdg == 5122 || pdg == 5132 || pdg == 5232 || pdg == 5332) { + nOpenBeautyPos++; + } else if (pdg == -511 || pdg == -521 || pdg == -531 || pdg == -5122 || pdg == -5132 || pdg == -5232 || pdg == -5332) { + nOpenBeautyNeg++; + } + } + if (nOpenBeautyPos > 0 && nOpenBeautyNeg > 0) { + nSignalPairs++; + } + if (nPositronsElectronsInAcceptance > 1) { + nLeptonsInAcceptance++; + } + if (nElectrons > 0 && nPositrons > 0) { + nLeptonPairs++; + } + if (nElectronsToBeDone > 0 && nPositronsToBeDone > 0) nLeptonPairsToBeDone++; + } + std::cout << "#events: " << nEvents << "\n" + << "#leptons: " << nLeptons << "\n" + << "#antileptons: " << nAntileptons << "\n" + << "#leptons to be done: " << nLeptonsToBeDone << "\n" + << "#antileptons to be done: " << nAntileptonsToBeDone << "\n" + << "#Open-beauty hadron pairs: " << nSignalPairs << "\n" + << "#leptons in acceptance: " << nLeptonsInAcceptance << "\n" + << "#Electron-positron pairs: " << nLeptonPairs << "\n" + << "#Electron-positron pairs to be done: " << nLeptonPairsToBeDone << "\n"; + if (nLeptons == 0 && nAntileptons == 0) { + std::cerr << "Number of leptons, number of anti-leptons should all be greater than 1.\n"; + return 1; + } + if (nLeptonPairs != nLeptonPairsToBeDone) { + std::cerr << "The number of lepton pairs should be the same as the number of lepton pairs which should be transported.\n"; + return 1; + } + if (nLeptons != nLeptonsToBeDone) { + std::cerr << "The number of leptons should be the same as the number of leptons which should be transported.\n"; + return 1; + } + if (nLeptonsInAcceptance == (nEvents/ratioTrigger)) { + std::cerr << "The number of leptons in acceptance should be at least equaled to the number of events.\n"; + return 1; + } + + return 0; +} diff --git a/MC/config/PWGEM/ini/tests/GeneratorHFGapTriggered_BeautyNoForcedDecay_Gap5_pp5360GeV.C b/MC/config/PWGEM/ini/tests/GeneratorHFGapTriggered_BeautyNoForcedDecay_Gap5_pp5360GeV.C new file mode 100644 index 000000000..10907110b --- /dev/null +++ b/MC/config/PWGEM/ini/tests/GeneratorHFGapTriggered_BeautyNoForcedDecay_Gap5_pp5360GeV.C @@ -0,0 +1,113 @@ +int External() +{ + + int checkPdgDecay = -11; + std::string path{"o2sim_Kine.root"}; + TFile file(path.c_str(), "READ"); + if (file.IsZombie()) { + std::cerr << "Cannot open ROOT file " << path << "\n"; + return 1; + } + + float ratioTrigger = 1./3; // one event triggered out of 3 + auto tree = (TTree*)file.Get("o2sim"); + std::vector* tracks{}; + tree->SetBranchAddress("MCTrack", &tracks); + + int nLeptonsInAcceptance{}; + int nLeptons{}; + int nAntileptons{}; + int nLeptonsToBeDone{}; + int nAntileptonsToBeDone{}; + int nSignalPairs{}; + int nLeptonPairs{}; + int nLeptonPairsToBeDone{}; + auto nEvents = tree->GetEntries(); + + for (int i = 0; i < nEvents; i++) { + tree->GetEntry(i); + int nElectrons = 0; + int nPositrons = 0; + int nElectronsToBeDone = 0; + int nPositronsToBeDone = 0; + int nOpenBeautyPos = 0; + int nOpenBeautyNeg = 0; + int nPositronsElectronsInAcceptance = 0; + for (auto& track : *tracks) { + auto pdg = track.GetPdgCode(); + auto y = track.GetRapidity(); + if (pdg == checkPdgDecay) { + int igmother = track.getMotherTrackId(); + if (igmother > 0) { + auto gmTrack = (*tracks)[igmother]; + int gmpdg = gmTrack.GetPdgCode(); + if (int(std::abs(gmpdg)/100.) == 5 || int(std::abs(gmpdg)/1000.) == 5 || int(std::abs(gmpdg)/100.) == 4 || int(std::abs(gmpdg)/1000.) == 4) { + nLeptons++; + nElectrons++; + if (-1 < y && y < 1) nPositronsElectronsInAcceptance++; + if (track.getToBeDone()) { + nLeptonsToBeDone++; + nElectronsToBeDone++; + } + } + } + } else if (pdg == -checkPdgDecay) { + int igmother = track.getMotherTrackId(); + if (igmother > 0) { + auto gmTrack = (*tracks)[igmother]; + int gmpdg = gmTrack.GetPdgCode(); + if (int(TMath::Abs(gmpdg)/100.) == 4 || int(TMath::Abs(gmpdg)/1000.) == 4 || int(std::abs(gmpdg)/100.) == 5 || int(std::abs(gmpdg)/1000.) == 5) { + nAntileptons++; + nPositrons++; + if (-1 < y && y < 1) nPositronsElectronsInAcceptance++; + if (track.getToBeDone()) { + nAntileptonsToBeDone++; + nPositronsToBeDone++; + } + } + } + } else if (pdg == 511 || pdg == 521 || pdg == 531 || pdg == 5122 || pdg == 5132 || pdg == 5232 || pdg == 5332) { + nOpenBeautyPos++; + } else if (pdg == -511 || pdg == -521 || pdg == -531 || pdg == -5122 || pdg == -5132 || pdg == -5232 || pdg == -5332) { + nOpenBeautyNeg++; + } + } + if (nOpenBeautyPos > 0 && nOpenBeautyNeg > 0) { + nSignalPairs++; + } + if (nPositronsElectronsInAcceptance > 1) { + nLeptonsInAcceptance++; + } + if (nElectrons > 0 && nPositrons > 0) { + nLeptonPairs++; + } + if (nElectronsToBeDone > 0 && nPositronsToBeDone > 0) nLeptonPairsToBeDone++; + } + std::cout << "#events: " << nEvents << "\n" + << "#leptons: " << nLeptons << "\n" + << "#antileptons: " << nAntileptons << "\n" + << "#leptons to be done: " << nLeptonsToBeDone << "\n" + << "#antileptons to be done: " << nAntileptonsToBeDone << "\n" + << "#Open-beauty hadron pairs: " << nSignalPairs << "\n" + << "#leptons in acceptance: " << nLeptonsInAcceptance << "\n" + << "#Electron-positron pairs: " << nLeptonPairs << "\n" + << "#Electron-positron pairs to be done: " << nLeptonPairsToBeDone << "\n"; + if (nLeptons == 0 && nAntileptons == 0) { + std::cerr << "Number of leptons, number of anti-leptons should all be greater than 1.\n"; + return 1; + } + if (nLeptonPairs != nLeptonPairsToBeDone) { + std::cerr << "The number of lepton pairs should be the same as the number of lepton pairs which should be transported.\n"; + return 1; + } + if (nLeptons != nLeptonsToBeDone) { + std::cerr << "The number of leptons should be the same as the number of leptons which should be transported.\n"; + return 1; + } + if (nLeptonsInAcceptance == (nEvents/ratioTrigger)) { + std::cerr << "The number of leptons in acceptance should be at least equaled to the number of events.\n"; + return 1; + } + + return 0; +} diff --git a/MC/config/PWGEM/ini/tests/GeneratorHFGapTriggered_Charm_Gap2_OO_electron.C b/MC/config/PWGEM/ini/tests/GeneratorHFGapTriggered_Charm_Gap2_OO_electron.C new file mode 100644 index 000000000..ed19c336e --- /dev/null +++ b/MC/config/PWGEM/ini/tests/GeneratorHFGapTriggered_Charm_Gap2_OO_electron.C @@ -0,0 +1,117 @@ +int External() +{ + + int checkPdgDecay = 11; + std::string path{"o2sim_Kine.root"}; + TFile file(path.c_str(), "READ"); + if (file.IsZombie()) { + std::cerr << "Cannot open ROOT file " << path << "\n"; + return 1; + } + + float ratioTrigger = 1./3.; // one event triggered out of 3 + auto tree = (TTree*)file.Get("o2sim"); + std::vector* tracks{}; + tree->SetBranchAddress("MCTrack", &tracks); + + int nLeptonsInAcceptance{}; + int nLeptons{}; + int nAntileptons{}; + int nLeptonsToBeDone{}; + int nAntileptonsToBeDone{}; + int nSignalPairs{}; + int nLeptonPairs{}; + int nLeptonPairsToBeDone{}; + auto nEvents = tree->GetEntries(); + + for (int i = 0; i < nEvents; i++) { + tree->GetEntry(i); + int nElectrons = 0; + int nPositrons = 0; + int nElectronsToBeDone = 0; + int nPositronsToBeDone = 0; + int nOpenCharmPos = 0; + int nOpenCharmNeg = 0; + int nPositronsElectronsInAcceptance = 0; + for (auto& track : *tracks) { + auto pdg = track.GetPdgCode(); + auto y = track.GetRapidity(); + if (pdg == checkPdgDecay) { + int igmother = track.getMotherTrackId(); + if (igmother > 0) { + auto gmTrack = (*tracks)[igmother]; + int gmpdg = gmTrack.GetPdgCode(); + if (int(std::abs(gmpdg)/100.) == 4 || int(std::abs(gmpdg)/1000.) == 4) { + nLeptons++; + nElectrons++; + if (-1 < y && y < 1) nPositronsElectronsInAcceptance++; + if (track.getToBeDone()) { + nLeptonsToBeDone++; + nElectronsToBeDone++; + } + } + } + } else if (pdg == -checkPdgDecay) { + int igmother = track.getMotherTrackId(); + if (igmother > 0) { + auto gmTrack = (*tracks)[igmother]; + int gmpdg = gmTrack.GetPdgCode(); + if (int(TMath::Abs(gmpdg)/100.) == 4 || int(TMath::Abs(gmpdg)/1000.) == 4) { + nAntileptons++; + nPositrons++; + if (-1 < y && y < 1) nPositronsElectronsInAcceptance++; + if (track.getToBeDone()) { + nAntileptonsToBeDone++; + nPositronsToBeDone++; + } + } + } + } else if (pdg == 411 || pdg == 421 || pdg == 431 || pdg == 4122 || pdg == 4132 || pdg == 4232 || pdg == 4332) { + nOpenCharmPos++; + } else if (pdg == -411 || pdg == -421 || pdg == -431 || pdg == -4122 || pdg == -4132 || pdg == -4232 || pdg == -4332) { + nOpenCharmNeg++; + } + } + if (nOpenCharmPos > 0 && nOpenCharmNeg > 0) { + nSignalPairs++; + } + if (nPositronsElectronsInAcceptance > 1) { + nLeptonsInAcceptance++; + } + if (nElectrons > 0 && nPositrons > 0) { + nLeptonPairs++; + } + if (nElectronsToBeDone > 0 && nPositronsToBeDone > 0) nLeptonPairsToBeDone++; + } + std::cout << "#events: " << nEvents << "\n" + << "#leptons: " << nLeptons << "\n" + << "#antileptons: " << nAntileptons << "\n" + << "#leptons to be done: " << nLeptonsToBeDone << "\n" + << "#antileptons to be done: " << nAntileptonsToBeDone << "\n" + << "#open-charm hadron pairs: " << nSignalPairs << "\n" + << "#leptons in acceptance: " << nLeptonsInAcceptance << "\n" + << "#Electron-positron pairs: " << nLeptonPairs << "\n" + << "#Electron-positron pairs to be done: " << nLeptonPairsToBeDone << "\n"; + if (nLeptons == 0 && nAntileptons == 0) { + std::cerr << "Number of leptons, number of anti-leptons should all be greater than 1.\n"; + return 1; + } + if (nLeptonPairs != nLeptonPairsToBeDone) { + std::cerr << "The number of electron-positron pairs should be the same as the number of electron-positron pairs which should be transported.\n"; + return 1; + } + if (nLeptons != nLeptonsToBeDone) { + std::cerr << "The number of leptons should be the same as the number of leptons which should be transported.\n"; + return 1; + } + if (nLeptonsInAcceptance == (nEvents/ratioTrigger)) { + std::cerr << "The number of leptons in acceptance should be at least equaled to the number of events.\n"; + return 1; + } + if (nLeptonPairs < nLeptonsInAcceptance) { + std::cerr << "The number of positron-electron pairs should be at least equaled to the number of leptons in acceptance.\n"; + return 1; + } + + return 0; +} diff --git a/MC/config/PWGEM/ini/tests/GeneratorHFGapTriggered_Charm_Gap2_OO_muon.C b/MC/config/PWGEM/ini/tests/GeneratorHFGapTriggered_Charm_Gap2_OO_muon.C new file mode 100644 index 000000000..0b837b413 --- /dev/null +++ b/MC/config/PWGEM/ini/tests/GeneratorHFGapTriggered_Charm_Gap2_OO_muon.C @@ -0,0 +1,116 @@ +int External() +{ + int checkPdgDecay = 13; + std::string path{"o2sim_Kine.root"}; + TFile file(path.c_str(), "READ"); + if (file.IsZombie()) { + std::cerr << "Cannot open ROOT file " << path << "\n"; + return 1; + } + + float ratioTrigger = 1./3.; // one event triggered out of 3 + auto tree = (TTree*)file.Get("o2sim"); + std::vector* tracks{}; + tree->SetBranchAddress("MCTrack", &tracks); + + int nLeptonsInAcceptance{}; + int nLeptons{}; + int nAntileptons{}; + int nLeptonsToBeDone{}; + int nAntileptonsToBeDone{}; + int nSignalPairs{}; + int nLeptonPairs{}; + int nLeptonPairsToBeDone{}; + auto nEvents = tree->GetEntries(); + + for (int i = 0; i < nEvents; i++) { + tree->GetEntry(i); + int nElectrons = 0; + int nPositrons = 0; + int nElectronsToBeDone = 0; + int nPositronsToBeDone = 0; + int nOpenCharmPos = 0; + int nOpenCharmNeg = 0; + int nPositronsElectronsInAcceptance = 0; + for (auto& track : *tracks) { + auto pdg = track.GetPdgCode(); + auto y = track.GetRapidity(); + if (pdg == checkPdgDecay) { + int igmother = track.getMotherTrackId(); + if (igmother > 0) { + auto gmTrack = (*tracks)[igmother]; + int gmpdg = gmTrack.GetPdgCode(); + if (int(std::abs(gmpdg)/100.) == 4 || int(std::abs(gmpdg)/1000.) == 4) { + nLeptons++; + nElectrons++; + if (-1 < y && y < 1) nPositronsElectronsInAcceptance++; + if (track.getToBeDone()) { + nLeptonsToBeDone++; + nElectronsToBeDone++; + } + } + } + } else if (pdg == -checkPdgDecay) { + int igmother = track.getMotherTrackId(); + if (igmother > 0) { + auto gmTrack = (*tracks)[igmother]; + int gmpdg = gmTrack.GetPdgCode(); + if (int(TMath::Abs(gmpdg)/100.) == 4 || int(TMath::Abs(gmpdg)/1000.) == 4) { + nAntileptons++; + nPositrons++; + if (-1 < y && y < 1) nPositronsElectronsInAcceptance++; + if (track.getToBeDone()) { + nAntileptonsToBeDone++; + nPositronsToBeDone++; + } + } + } + } else if (pdg == 411 || pdg == 421 || pdg == 431 || pdg == 4122 || pdg == 4132 || pdg == 4232 || pdg == 4332) { + nOpenCharmPos++; + } else if (pdg == -411 || pdg == -421 || pdg == -431 || pdg == -4122 || pdg == -4132 || pdg == -4232 || pdg == -4332) { + nOpenCharmNeg++; + } + } + if (nOpenCharmPos > 0 && nOpenCharmNeg > 0) { + nSignalPairs++; + } + if (nPositronsElectronsInAcceptance > 1) { + nLeptonsInAcceptance++; + } + if (nElectrons > 0 && nPositrons > 0) { + nLeptonPairs++; + } + if (nElectronsToBeDone > 0 && nPositronsToBeDone > 0) nLeptonPairsToBeDone++; + } + std::cout << "#events: " << nEvents << "\n" + << "#leptons: " << nLeptons << "\n" + << "#antileptons: " << nAntileptons << "\n" + << "#leptons to be done: " << nLeptonsToBeDone << "\n" + << "#antileptons to be done: " << nAntileptonsToBeDone << "\n" + << "#open-charm hadron pairs: " << nSignalPairs << "\n" + << "#leptons in acceptance: " << nLeptonsInAcceptance << "\n" + << "#Electron-positron pairs: " << nLeptonPairs << "\n" + << "#Electron-positron pairs to be done: " << nLeptonPairsToBeDone << "\n"; + if (nLeptons == 0 && nAntileptons == 0) { + std::cerr << "Number of leptons, number of anti-leptons should all be greater than 1.\n"; + return 1; + } + if (nLeptonPairs != nLeptonPairsToBeDone) { + std::cerr << "The number of electron-positron pairs should be the same as the number of electron-positron pairs which should be transported.\n"; + return 1; + } + if (nLeptons != nLeptonsToBeDone) { + std::cerr << "The number of leptons should be the same as the number of leptons which should be transported.\n"; + return 1; + } + if (nLeptonsInAcceptance == (nEvents/ratioTrigger)) { + std::cerr << "The number of leptons in acceptance should be at least equaled to the number of events.\n"; + return 1; + } + if (nLeptonPairs < nLeptonsInAcceptance) { + std::cerr << "The number of positron-electron pairs should be at least equaled to the number of leptons in acceptance.\n"; + return 1; + } + + return 0; +} diff --git a/MC/config/PWGEM/ini/tests/GeneratorHFGapTriggered_Charm_Gap5_pp5360GeV.C b/MC/config/PWGEM/ini/tests/GeneratorHFGapTriggered_Charm_Gap5_pp5360GeV.C new file mode 100644 index 000000000..9081b8a81 --- /dev/null +++ b/MC/config/PWGEM/ini/tests/GeneratorHFGapTriggered_Charm_Gap5_pp5360GeV.C @@ -0,0 +1,117 @@ +int External() +{ + + int checkPdgDecay = -11; + std::string path{"o2sim_Kine.root"}; + TFile file(path.c_str(), "READ"); + if (file.IsZombie()) { + std::cerr << "Cannot open ROOT file " << path << "\n"; + return 1; + } + + float ratioTrigger = 1./3.; // one event triggered out of 3 + auto tree = (TTree*)file.Get("o2sim"); + std::vector* tracks{}; + tree->SetBranchAddress("MCTrack", &tracks); + + int nLeptonsInAcceptance{}; + int nLeptons{}; + int nAntileptons{}; + int nLeptonsToBeDone{}; + int nAntileptonsToBeDone{}; + int nSignalPairs{}; + int nLeptonPairs{}; + int nLeptonPairsToBeDone{}; + auto nEvents = tree->GetEntries(); + + for (int i = 0; i < nEvents; i++) { + tree->GetEntry(i); + int nElectrons = 0; + int nPositrons = 0; + int nElectronsToBeDone = 0; + int nPositronsToBeDone = 0; + int nOpenCharmPos = 0; + int nOpenCharmNeg = 0; + int nPositronsElectronsInAcceptance = 0; + for (auto& track : *tracks) { + auto pdg = track.GetPdgCode(); + auto y = track.GetRapidity(); + if (pdg == checkPdgDecay) { + int igmother = track.getMotherTrackId(); + if (igmother > 0) { + auto gmTrack = (*tracks)[igmother]; + int gmpdg = gmTrack.GetPdgCode(); + if (int(std::abs(gmpdg)/100.) == 4 || int(std::abs(gmpdg)/1000.) == 4) { + nLeptons++; + nElectrons++; + if (-1 < y && y < 1) nPositronsElectronsInAcceptance++; + if (track.getToBeDone()) { + nLeptonsToBeDone++; + nElectronsToBeDone++; + } + } + } + } else if (pdg == -checkPdgDecay) { + int igmother = track.getMotherTrackId(); + if (igmother > 0) { + auto gmTrack = (*tracks)[igmother]; + int gmpdg = gmTrack.GetPdgCode(); + if (int(TMath::Abs(gmpdg)/100.) == 4 || int(TMath::Abs(gmpdg)/1000.) == 4) { + nAntileptons++; + nPositrons++; + if (-1 < y && y < 1) nPositronsElectronsInAcceptance++; + if (track.getToBeDone()) { + nAntileptonsToBeDone++; + nPositronsToBeDone++; + } + } + } + } else if (pdg == 411 || pdg == 421 || pdg == 431 || pdg == 4122 || pdg == 4132 || pdg == 4232 || pdg == 4332) { + nOpenCharmPos++; + } else if (pdg == -411 || pdg == -421 || pdg == -431 || pdg == -4122 || pdg == -4132 || pdg == -4232 || pdg == -4332) { + nOpenCharmNeg++; + } + } + if (nOpenCharmPos > 0 && nOpenCharmNeg > 0) { + nSignalPairs++; + } + if (nPositronsElectronsInAcceptance > 1) { + nLeptonsInAcceptance++; + } + if (nElectrons > 0 && nPositrons > 0) { + nLeptonPairs++; + } + if (nElectronsToBeDone > 0 && nPositronsToBeDone > 0) nLeptonPairsToBeDone++; + } + std::cout << "#events: " << nEvents << "\n" + << "#leptons: " << nLeptons << "\n" + << "#antileptons: " << nAntileptons << "\n" + << "#leptons to be done: " << nLeptonsToBeDone << "\n" + << "#antileptons to be done: " << nAntileptonsToBeDone << "\n" + << "#open-charm hadron pairs: " << nSignalPairs << "\n" + << "#leptons in acceptance: " << nLeptonsInAcceptance << "\n" + << "#Electron-positron pairs: " << nLeptonPairs << "\n" + << "#Electron-positron pairs to be done: " << nLeptonPairsToBeDone << "\n"; + if (nLeptons == 0 && nAntileptons == 0) { + std::cerr << "Number of leptons, number of anti-leptons should all be greater than 1.\n"; + return 1; + } + if (nLeptonPairs != nLeptonPairsToBeDone) { + std::cerr << "The number of electron-positron pairs should be the same as the number of electron-positron pairs which should be transported.\n"; + return 1; + } + if (nLeptons != nLeptonsToBeDone) { + std::cerr << "The number of leptons should be the same as the number of leptons which should be transported.\n"; + return 1; + } + if (nLeptonsInAcceptance == (nEvents/ratioTrigger)) { + std::cerr << "The number of leptons in acceptance should be at least equaled to the number of events.\n"; + return 1; + } + if (nLeptonPairs < nLeptonsInAcceptance) { + std::cerr << "The number of positron-electron pairs should be at least equaled to the number of leptons in acceptance.\n"; + return 1; + } + + return 0; +} diff --git a/MC/config/PWGEM/ini/tests/GeneratorHF_BeautyNoForcedDecay_PbPb_electron.C b/MC/config/PWGEM/ini/tests/GeneratorHF_BeautyNoForcedDecay_PbPb_electron.C new file mode 100644 index 000000000..375e79b75 --- /dev/null +++ b/MC/config/PWGEM/ini/tests/GeneratorHF_BeautyNoForcedDecay_PbPb_electron.C @@ -0,0 +1,111 @@ +int External() +{ + int checkPdgDecay = 11; + std::string path{"o2sim_Kine.root"}; + TFile file(path.c_str(), "READ"); + if (file.IsZombie()) { + std::cerr << "Cannot open ROOT file " << path << "\n"; + return 1; + } + + auto tree = (TTree*)file.Get("o2sim"); + std::vector* tracks{}; + tree->SetBranchAddress("MCTrack", &tracks); + + int nLeptonsInAcceptance{}; + int nLeptons{}; + int nAntileptons{}; + int nLeptonsToBeDone{}; + int nAntileptonsToBeDone{}; + int nSignalPairs{}; + int nLeptonPairs{}; + int nLeptonPairsToBeDone{}; + auto nEvents = tree->GetEntries(); + + for (int i = 0; i < nEvents; i++) { + tree->GetEntry(i); + int nElectrons = 0; + int nPositrons = 0; + int nElectronsToBeDone = 0; + int nPositronsToBeDone = 0; + int nOpenBeautyPos = 0; + int nOpenBeautyNeg = 0; + int nPositronsElectronsInAcceptance = 0; + for (auto& track : *tracks) { + auto pdg = track.GetPdgCode(); + auto y = track.GetRapidity(); + if (pdg == checkPdgDecay) { + int igmother = track.getMotherTrackId(); + if (igmother > 0) { + auto gmTrack = (*tracks)[igmother]; + int gmpdg = gmTrack.GetPdgCode(); + if (int(std::abs(gmpdg)/100.) == 5 || int(std::abs(gmpdg)/1000.) == 5 || int(std::abs(gmpdg)/100.) == 4 || int(std::abs(gmpdg)/1000.) == 4) { + nLeptons++; + nElectrons++; + if (-1 < y && y < 1) nPositronsElectronsInAcceptance++; + if (track.getToBeDone()) { + nLeptonsToBeDone++; + nElectronsToBeDone++; + } + } + } + } else if (pdg == -checkPdgDecay) { + int igmother = track.getMotherTrackId(); + if (igmother > 0) { + auto gmTrack = (*tracks)[igmother]; + int gmpdg = gmTrack.GetPdgCode(); + if (int(TMath::Abs(gmpdg)/100.) == 4 || int(TMath::Abs(gmpdg)/1000.) == 4 || int(std::abs(gmpdg)/100.) == 5 || int(std::abs(gmpdg)/1000.) == 5) { + nAntileptons++; + nPositrons++; + if (-1 < y && y < 1) nPositronsElectronsInAcceptance++; + if (track.getToBeDone()) { + nAntileptonsToBeDone++; + nPositronsToBeDone++; + } + } + } + } else if (pdg == 511 || pdg == 521 || pdg == 531 || pdg == 5122 || pdg == 5132 || pdg == 5232 || pdg == 5332) { + nOpenBeautyPos++; + } else if (pdg == -511 || pdg == -521 || pdg == -531 || pdg == -5122 || pdg == -5132 || pdg == -5232 || pdg == -5332) { + nOpenBeautyNeg++; + } + } + if (nOpenBeautyPos > 0 && nOpenBeautyNeg > 0) { + nSignalPairs++; + } + if (nPositronsElectronsInAcceptance > 1) { + nLeptonsInAcceptance++; + } + if (nElectrons > 0 && nPositrons > 0) { + nLeptonPairs++; + } + if (nElectronsToBeDone > 0 && nPositronsToBeDone > 0) nLeptonPairsToBeDone++; + } + std::cout << "#events: " << nEvents << "\n" + << "#leptons: " << nLeptons << "\n" + << "#antileptons: " << nAntileptons << "\n" + << "#leptons to be done: " << nLeptonsToBeDone << "\n" + << "#antileptons to be done: " << nAntileptonsToBeDone << "\n" + << "#Open-beauty hadron pairs: " << nSignalPairs << "\n" + << "#leptons in acceptance: " << nLeptonsInAcceptance << "\n" + << "#Electron-positron pairs: " << nLeptonPairs << "\n" + << "#Electron-positron pairs to be done: " << nLeptonPairsToBeDone << "\n"; + if (nLeptons == 0 && nAntileptons == 0) { + std::cerr << "Number of leptons, number of anti-leptons should all be greater than 1.\n"; + return 1; + } + if (nLeptonPairs != nLeptonPairsToBeDone) { + std::cerr << "The number of lepton pairs should be the same as the number of lepton pairs which should be transported.\n"; + return 1; + } + if (nLeptons != nLeptonsToBeDone) { + std::cerr << "The number of leptons should be the same as the number of leptons which should be transported.\n"; + return 1; + } + if (nLeptonsInAcceptance != nEvents) { + std::cerr << "The number of leptons in acceptance should be at least equaled to the number of events.\n"; + return 1; + } + + return 0; +} diff --git a/MC/config/PWGEM/ini/tests/GeneratorHF_Charm_PbPb_electron.C b/MC/config/PWGEM/ini/tests/GeneratorHF_Charm_PbPb_electron.C new file mode 100644 index 000000000..d55c16c11 --- /dev/null +++ b/MC/config/PWGEM/ini/tests/GeneratorHF_Charm_PbPb_electron.C @@ -0,0 +1,116 @@ +int External() +{ + + int checkPdgDecay = 11; + std::string path{"o2sim_Kine.root"}; + TFile file(path.c_str(), "READ"); + if (file.IsZombie()) { + std::cerr << "Cannot open ROOT file " << path << "\n"; + return 1; + } + + auto tree = (TTree*)file.Get("o2sim"); + std::vector* tracks{}; + tree->SetBranchAddress("MCTrack", &tracks); + + int nLeptonsInAcceptance{}; + int nLeptons{}; + int nAntileptons{}; + int nLeptonsToBeDone{}; + int nAntileptonsToBeDone{}; + int nSignalPairs{}; + int nLeptonPairs{}; + int nLeptonPairsToBeDone{}; + auto nEvents = tree->GetEntries(); + + for (int i = 0; i < nEvents; i++) { + tree->GetEntry(i); + int nElectrons = 0; + int nPositrons = 0; + int nElectronsToBeDone = 0; + int nPositronsToBeDone = 0; + int nOpenCharmPos = 0; + int nOpenCharmNeg = 0; + int nPositronsElectronsInAcceptance = 0; + for (auto& track : *tracks) { + auto pdg = track.GetPdgCode(); + auto y = track.GetRapidity(); + if (pdg == checkPdgDecay) { + int igmother = track.getMotherTrackId(); + if (igmother > 0) { + auto gmTrack = (*tracks)[igmother]; + int gmpdg = gmTrack.GetPdgCode(); + if (int(std::abs(gmpdg)/100.) == 4 || int(std::abs(gmpdg)/1000.) == 4) { + nLeptons++; + nElectrons++; + if (-1 < y && y < 1) nPositronsElectronsInAcceptance++; + if (track.getToBeDone()) { + nLeptonsToBeDone++; + nElectronsToBeDone++; + } + } + } + } else if (pdg == -checkPdgDecay) { + int igmother = track.getMotherTrackId(); + if (igmother > 0) { + auto gmTrack = (*tracks)[igmother]; + int gmpdg = gmTrack.GetPdgCode(); + if (int(TMath::Abs(gmpdg)/100.) == 4 || int(TMath::Abs(gmpdg)/1000.) == 4) { + nAntileptons++; + nPositrons++; + if (-1 < y && y < 1) nPositronsElectronsInAcceptance++; + if (track.getToBeDone()) { + nAntileptonsToBeDone++; + nPositronsToBeDone++; + } + } + } + } else if (pdg == 411 || pdg == 421 || pdg == 431 || pdg == 4122 || pdg == 4132 || pdg == 4232 || pdg == 4332) { + nOpenCharmPos++; + } else if (pdg == -411 || pdg == -421 || pdg == -431 || pdg == -4122 || pdg == -4132 || pdg == -4232 || pdg == -4332) { + nOpenCharmNeg++; + } + } + if (nOpenCharmPos > 0 && nOpenCharmNeg > 0) { + nSignalPairs++; + } + if (nPositronsElectronsInAcceptance > 1) { + nLeptonsInAcceptance++; + } + if (nElectrons > 0 && nPositrons > 0) { + nLeptonPairs++; + } + if (nElectronsToBeDone > 0 && nPositronsToBeDone > 0) nLeptonPairsToBeDone++; + } + std::cout << "#events: " << nEvents << "\n" + << "#leptons: " << nLeptons << "\n" + << "#antileptons: " << nAntileptons << "\n" + << "#leptons to be done: " << nLeptonsToBeDone << "\n" + << "#antileptons to be done: " << nAntileptonsToBeDone << "\n" + << "#open-charm hadron pairs: " << nSignalPairs << "\n" + << "#leptons in acceptance: " << nLeptonsInAcceptance << "\n" + << "#Electron-positron pairs: " << nLeptonPairs << "\n" + << "#Electron-positron pairs to be done: " << nLeptonPairsToBeDone << "\n"; + if (nLeptons == 0 && nAntileptons == 0) { + std::cerr << "Number of leptons, number of anti-leptons should all be greater than 1.\n"; + return 1; + } + if (nLeptonPairs != nLeptonPairsToBeDone) { + std::cerr << "The number of electron-positron pairs should be the same as the number of electron-positron pairs which should be transported.\n"; + return 1; + } + if (nLeptons != nLeptonsToBeDone) { + std::cerr << "The number of leptons should be the same as the number of leptons which should be transported.\n"; + return 1; + } + if (nLeptonsInAcceptance != nEvents) { + std::cerr << "The number of leptons in acceptance should be at least equaled to the number of events.\n"; + return 1; + } + if (nLeptonPairs < nLeptonsInAcceptance) { + std::cerr << "The number of positron-electron pairs should be at least equaled to the number of leptons in acceptance.\n"; + return 1; + } + + return 0; +} diff --git a/MC/config/PWGEM/ini/tests/pythia8_OO_536_VM2ll.C b/MC/config/PWGEM/ini/tests/pythia8_OO_536_VM2ll.C new file mode 100644 index 000000000..ac9df9f68 --- /dev/null +++ b/MC/config/PWGEM/ini/tests/pythia8_OO_536_VM2ll.C @@ -0,0 +1,56 @@ +int External() { + std::string path{"o2sim_Kine.root"}; + // Check that file exists, can be opened and has the correct tree + TFile file(path.c_str(), "READ"); + if (file.IsZombie()) + { + std::cerr << "Cannot open ROOT file " << path << "\n"; + return 1; + } + auto tree = (TTree *)file.Get("o2sim"); + if (!tree) + { + std::cerr << "Cannot find tree o2sim in file " << path << "\n"; + return 1; + } + std::vector *tracks{}; + tree->SetBranchAddress("MCTrack", &tracks); + + // Check if all events are filled + auto nEvents = tree->GetEntries(); + for (Long64_t i = 0; i < nEvents; ++i) + { + tree->GetEntry(i); + if (tracks->empty()) + { + std::cerr << "Empty entry found at event " << i << "\n"; + return 1; + } + } + // check if each event has at least two oxygen ions + for (int i = 0; i < nEvents; i++) + { + auto check = tree->GetEntry(i); + int count = 0; + for (int idxMCTrack = 0; idxMCTrack < tracks->size(); ++idxMCTrack) + { + auto track = tracks->at(idxMCTrack); + if (track.GetPdgCode() == 1000080160) + { + count++; + } + } + if (count < 2) + { + std::cerr << "Event " << i << " has less than 2 oxygen ions\n"; + return 1; + } + } + + return 0; +} + +int pythia8() +{ + return External(); +} diff --git a/MC/config/PWGEM/ini/tests/pythia8_PbPb_5360_VM2ll.C b/MC/config/PWGEM/ini/tests/pythia8_PbPb_5360_VM2ll.C new file mode 100644 index 000000000..b00728e80 --- /dev/null +++ b/MC/config/PWGEM/ini/tests/pythia8_PbPb_5360_VM2ll.C @@ -0,0 +1,56 @@ +int External() { + std::string path{"o2sim_Kine.root"}; + // Check that file exists, can be opened and has the correct tree + TFile file(path.c_str(), "READ"); + if (file.IsZombie()) + { + std::cerr << "Cannot open ROOT file " << path << "\n"; + return 1; + } + auto tree = (TTree *)file.Get("o2sim"); + if (!tree) + { + std::cerr << "Cannot find tree o2sim in file " << path << "\n"; + return 1; + } + std::vector *tracks{}; + tree->SetBranchAddress("MCTrack", &tracks); + + // Check if all events are filled + auto nEvents = tree->GetEntries(); + for (Long64_t i = 0; i < nEvents; ++i) + { + tree->GetEntry(i); + if (tracks->empty()) + { + std::cerr << "Empty entry found at event " << i << "\n"; + return 1; + } + } + // check if each event has at least two oxygen ions + for (int i = 0; i < nEvents; i++) + { + auto check = tree->GetEntry(i); + int count = 0; + for (int idxMCTrack = 0; idxMCTrack < tracks->size(); ++idxMCTrack) + { + auto track = tracks->at(idxMCTrack); + if (track.GetPdgCode() == 1000822080) + { + count++; + } + } + if (count < 2) + { + std::cerr << "Event " << i << " has less than 2 lead ions\n"; + return 1; + } + } + + return 0; +} + +int pythia8() +{ + return External(); +} diff --git a/MC/config/PWGEM/ini/tests/pythia8_pp_13600_ForcedDalitz.C b/MC/config/PWGEM/ini/tests/pythia8_pp_13600_ForcedDalitz.C new file mode 100644 index 000000000..4829e48d5 --- /dev/null +++ b/MC/config/PWGEM/ini/tests/pythia8_pp_13600_ForcedDalitz.C @@ -0,0 +1,39 @@ +int External() { + std::string path{"o2sim_Kine.root"}; + // Check that file exists, can be opened and has the correct tree + TFile file(path.c_str(), "READ"); + if (file.IsZombie()) + { + std::cerr << "Cannot open ROOT file " << path << "\n"; + return 1; + } + auto tree = (TTree *)file.Get("o2sim"); + if (!tree) + { + std::cerr << "Cannot find tree o2sim in file " << path << "\n"; + return 1; + } + std::vector *tracks{}; + tree->SetBranchAddress("MCTrack", &tracks); + + // Check if all events are filled + auto nEvents = tree->GetEntries(); + for (Long64_t i = 0; i < nEvents; ++i) + { + tree->GetEntry(i); + if (tracks->empty()) + { + std::cerr << "Empty entry found at event " << i << "\n"; + return 1; + } + } + + + return 0; + } + + int pythia8() + { + return External(); + } + \ No newline at end of file diff --git a/MC/config/PWGEM/ini/tests/pythia8_pp_13600_VM2ll.C b/MC/config/PWGEM/ini/tests/pythia8_pp_13600_VM2ll.C new file mode 100644 index 000000000..aaee11ffc --- /dev/null +++ b/MC/config/PWGEM/ini/tests/pythia8_pp_13600_VM2ll.C @@ -0,0 +1,56 @@ +int External() { + std::string path{"o2sim_Kine.root"}; + // Check that file exists, can be opened and has the correct tree + TFile file(path.c_str(), "READ"); + if (file.IsZombie()) + { + std::cerr << "Cannot open ROOT file " << path << "\n"; + return 1; + } + auto tree = (TTree *)file.Get("o2sim"); + if (!tree) + { + std::cerr << "Cannot find tree o2sim in file " << path << "\n"; + return 1; + } + std::vector *tracks{}; + tree->SetBranchAddress("MCTrack", &tracks); + + // Check if all events are filled + auto nEvents = tree->GetEntries(); + for (Long64_t i = 0; i < nEvents; ++i) + { + tree->GetEntry(i); + if (tracks->empty()) + { + std::cerr << "Empty entry found at event " << i << "\n"; + return 1; + } + } + // // check if each event has at least two oxygen ions + // for (int i = 0; i < nEvents; i++) + // { + // auto check = tree->GetEntry(i); + // int count = 0; + // for (int idxMCTrack = 0; idxMCTrack < tracks->size(); ++idxMCTrack) + // { + // auto track = tracks->at(idxMCTrack); + // if (track.GetPdgCode() == 1000080160) + // { + // count++; + // } + // } + // if (count < 2) + // { + // std::cerr << "Event " << i << " has less than 2 oxygen ions\n"; + // return 1; + // } + // } + + return 0; +} + +int pythia8() +{ + return External(); +} diff --git a/MC/config/PWGEM/ini/tests/pythia8_pp_5360_VM2ee.C b/MC/config/PWGEM/ini/tests/pythia8_pp_5360_VM2ee.C new file mode 100644 index 000000000..aaee11ffc --- /dev/null +++ b/MC/config/PWGEM/ini/tests/pythia8_pp_5360_VM2ee.C @@ -0,0 +1,56 @@ +int External() { + std::string path{"o2sim_Kine.root"}; + // Check that file exists, can be opened and has the correct tree + TFile file(path.c_str(), "READ"); + if (file.IsZombie()) + { + std::cerr << "Cannot open ROOT file " << path << "\n"; + return 1; + } + auto tree = (TTree *)file.Get("o2sim"); + if (!tree) + { + std::cerr << "Cannot find tree o2sim in file " << path << "\n"; + return 1; + } + std::vector *tracks{}; + tree->SetBranchAddress("MCTrack", &tracks); + + // Check if all events are filled + auto nEvents = tree->GetEntries(); + for (Long64_t i = 0; i < nEvents; ++i) + { + tree->GetEntry(i); + if (tracks->empty()) + { + std::cerr << "Empty entry found at event " << i << "\n"; + return 1; + } + } + // // check if each event has at least two oxygen ions + // for (int i = 0; i < nEvents; i++) + // { + // auto check = tree->GetEntry(i); + // int count = 0; + // for (int idxMCTrack = 0; idxMCTrack < tracks->size(); ++idxMCTrack) + // { + // auto track = tracks->at(idxMCTrack); + // if (track.GetPdgCode() == 1000080160) + // { + // count++; + // } + // } + // if (count < 2) + // { + // std::cerr << "Event " << i << " has less than 2 oxygen ions\n"; + // return 1; + // } + // } + + return 0; +} + +int pythia8() +{ + return External(); +} diff --git a/MC/config/PWGEM/ini/tests/pythia8_pp_5360_VM2ll.C b/MC/config/PWGEM/ini/tests/pythia8_pp_5360_VM2ll.C new file mode 100644 index 000000000..aaee11ffc --- /dev/null +++ b/MC/config/PWGEM/ini/tests/pythia8_pp_5360_VM2ll.C @@ -0,0 +1,56 @@ +int External() { + std::string path{"o2sim_Kine.root"}; + // Check that file exists, can be opened and has the correct tree + TFile file(path.c_str(), "READ"); + if (file.IsZombie()) + { + std::cerr << "Cannot open ROOT file " << path << "\n"; + return 1; + } + auto tree = (TTree *)file.Get("o2sim"); + if (!tree) + { + std::cerr << "Cannot find tree o2sim in file " << path << "\n"; + return 1; + } + std::vector *tracks{}; + tree->SetBranchAddress("MCTrack", &tracks); + + // Check if all events are filled + auto nEvents = tree->GetEntries(); + for (Long64_t i = 0; i < nEvents; ++i) + { + tree->GetEntry(i); + if (tracks->empty()) + { + std::cerr << "Empty entry found at event " << i << "\n"; + return 1; + } + } + // // check if each event has at least two oxygen ions + // for (int i = 0; i < nEvents; i++) + // { + // auto check = tree->GetEntry(i); + // int count = 0; + // for (int idxMCTrack = 0; idxMCTrack < tracks->size(); ++idxMCTrack) + // { + // auto track = tracks->at(idxMCTrack); + // if (track.GetPdgCode() == 1000080160) + // { + // count++; + // } + // } + // if (count < 2) + // { + // std::cerr << "Event " << i << " has less than 2 oxygen ions\n"; + // return 1; + // } + // } + + return 0; +} + +int pythia8() +{ + return External(); +} diff --git a/MC/config/PWGEM/parametrizations/OO_536TeV_param.json b/MC/config/PWGEM/parametrizations/OO_536TeV_param.json new file mode 100644 index 000000000..bad021d49 --- /dev/null +++ b/MC/config/PWGEM/parametrizations/OO_536TeV_param.json @@ -0,0 +1,10 @@ +{ + "536TeV_MB_pythia": { + "111_pt": "56.6336*x*pow(1+(sqrt(x*x+0.138918*0.138918)-0.138918)/(6.8304*0.139501),-6.8304)", + "221_pt": "1939.44*x*pow(1+(sqrt(x*x+-0.424653*-0.424653)--0.424653)/(6.84504*0.0745758),-6.84504)", + "331_pt": "2.89402*x*pow(1+(sqrt(x*x+-0.322689*-0.322689)--0.322689)/(8.32826*0.211736),-8.32826)", + "113_pt": "75.4035*x*pow(1+(sqrt(x*x+-0.360389*-0.360389)--0.360389)/(7.74615*0.16301),-7.74615)", + "223_pt": "2.29*x*pow(1+(sqrt(x*x+0.405007*0.405007)-0.405007)/(7.61366*0.243978),-7.61366)", + "333_pt": "0.646087*x*pow(1+(sqrt(x*x+-0.257169*-0.257169)--0.257169)/(8.17199*0.261382),-8.17199)" + } +} \ No newline at end of file diff --git a/MC/config/PWGEM/parametrizations/PbPb5TeV_central.json b/MC/config/PWGEM/parametrizations/PbPb5TeV_central.json index 6cc9cb0bd..546802e7f 100644 --- a/MC/config/PWGEM/parametrizations/PbPb5TeV_central.json +++ b/MC/config/PWGEM/parametrizations/PbPb5TeV_central.json @@ -1,283 +1,333 @@ { - "5TeV_0005_wRatio": { + "5TeV_0005_wRatio_etatest": { "histoMtScaleFactor": { "113": 0.85, "223": 0.7, "331": 0.4 }, "111_pt": "TMath::TwoPi()*x*(219.382*exp(-(sqrt(x*x+0.139571*0.139571)-0.139571)/0.384303)+2471.6*pow(exp(-1.12373*x-0.752507*x*x)+x/0.438343,-5.45943))", - "221_pt": "(TMath::TwoPi()*x*(219.382*exp(-(sqrt(x*x+0.139571*0.139571)-0.139571)/0.384303)+2471.6*pow(exp(-1.12373*x-0.752507*x*x)+x/0.438343,-5.45943)))*(((x<=4.303300)*(0.385689/(1+exp(-(x-0.442495)/0.303977))+-0.324645*TMath::Gaus(x,0.364119,1.01338)+-0.268261*TMath::Gaus(x,8.32791,4.74697)+0.318614)+(x>4.303300)*(0.0836242/(1+exp(-(x-6.88914)/2.15587))+0.757533*TMath::Gaus(x,1.19329,1.35263)+40382.9*TMath::Gaus(x,-92.3117,-16.5516)+0.442)+((0.550454*exp((((0.995785*x)-sqrt((x*x)+(0.5478530000*0.5478530000)))/sqrt(1-(0.995785*0.995785)))/1.71099))+(0.0106936*(0.620714*TMath::Power(1+((x/29.189)*(x/29.189)),-(506.895)))))/(exp((((0.995785*x)-sqrt((x*x)+(0.1349770000*0.1349770000)))/sqrt(1-(0.995785*0.995785)))/1.71099)+(0.620714*TMath::Power(1+((x/29.189)*(x/29.189)),-(506.895)))))/2.)", + "221_pt": "(TMath::TwoPi()*x*(219.382*exp(-(sqrt(x*x+0.139571*0.139571)-0.139571)/0.384303)+2471.6*pow(exp(-1.12373*x-0.752507*x*x)+x/0.438343,-5.45943)))*((9.36242e-05*TMath::Power((exp(- -2.56458*sqrt(x*x+0.547*0.547-0.139*0.139)-0.742625*(x*x+0.547*0.547-0.139*0.139))+TMath::Power(0.457041/9.36242e-05,-1./8.15756)*sqrt(x*x+0.547*0.547-0.139*0.139)/0.0235913),-8.15756)/TMath::Power((exp(- -2.56458*x-0.742625*x*x)+x/0.0235913),-8.15756)+1.50683*TMath::Landau(x,2.1159,0.843387)))", "333_pt": "(TMath::TwoPi()*x*(219.382*exp(-(sqrt(x*x+0.139571*0.139571)-0.139571)/0.384303)+2471.6*pow(exp(-1.12373*x-0.752507*x*x)+x/0.438343,-5.45943)))*(0.1191/(1+exp(-(x- -0.316437)/0.554431))+-0.507618*TMath::Gaus(x,1.69654,1.62649)+0.494136*TMath::Gaus(x,2.56805,1.6193)+0.0789659)" }, - "5TeV_0510_wRatio": { + "5TeV_0005_wRatio_etatest_ratiosup": { "histoMtScaleFactor": { - "113": 0.85, - "223": 0.7, - "331": 0.4 + "113": 1.02, + "223": 0.84, + "331": 0.48 }, - "111_pt": "TMath::TwoPi()*x*(156.897*exp(-(sqrt(x*x+0.139571*0.139571)-0.139571)/0.390093)+1835.17*pow(exp(-1.1618*x-0.514011*x*x)+x/0.465575,-5.50332))", - "221_pt": "(TMath::TwoPi()*x*(156.897*exp(-(sqrt(x*x+0.139571*0.139571)-0.139571)/0.390093)+1835.17*pow(exp(-1.1618*x-0.514011*x*x)+x/0.465575,-5.50332)))*(((x<=4.125494)*(0.462257/(1+exp(-(x-0.489168)/0.259816))+-0.338875*TMath::Gaus(x,0.655039,0.915494)+-0.277601*TMath::Gaus(x,5.26982,2.67864)+0.291403)+(x>4.125494)*(0.197492/(1+exp(-(x-5.11825)/1.30203))+-596719*TMath::Gaus(x,0.710032,0.569486)+1.82757*TMath::Gaus(x,-2.55348,2.83425)+0.33265)+((0.550454*exp((((0.995785*x)-sqrt((x*x)+(0.5478530000*0.5478530000)))/sqrt(1-(0.995785*0.995785)))/1.71099))+(0.0106936*(0.620714*TMath::Power(1+((x/29.189)*(x/29.189)),-(506.895)))))/(exp((((0.995785*x)-sqrt((x*x)+(0.1349770000*0.1349770000)))/sqrt(1-(0.995785*0.995785)))/1.71099)+(0.620714*TMath::Power(1+((x/29.189)*(x/29.189)),-(506.895)))))/2.)", - "333_pt": "(TMath::TwoPi()*x*(156.897*exp(-(sqrt(x*x+0.139571*0.139571)-0.139571)/0.390093)+1835.17*pow(exp(-1.1618*x-0.514011*x*x)+x/0.465575,-5.50332)))*(0.1191/(1+exp(-(x- -0.316437)/0.554431))+-0.507618*TMath::Gaus(x,1.69654,1.62649)+0.494136*TMath::Gaus(x,2.56805,1.6193)+0.0789659)" + "111_pt": "TMath::TwoPi()*x*(219.382*exp(-(sqrt(x*x+0.139571*0.139571)-0.139571)/0.384303)+2471.6*pow(exp(-1.12373*x-0.752507*x*x)+x/0.438343,-5.45943))", + "221_pt": "(TMath::TwoPi()*x*(219.382*exp(-(sqrt(x*x+0.139571*0.139571)-0.139571)/0.384303)+2471.6*pow(exp(-1.12373*x-0.752507*x*x)+x/0.438343,-5.45943)))*((((x<9.168)*(TMath::Max(TMath::Max(0.00147786*TMath::Power((exp(- -0.297384*sqrt(x*x+0.547*0.547-0.139*0.139)-0.0282388*(x*x+0.547*0.547-0.139*0.139))+TMath::Power(0.464407/0.00147786,-1./1.14468)*sqrt(x*x+0.547*0.547-0.139*0.139)/0.0102013),-1.14468)/TMath::Power((exp(- -0.297384*x-0.0282388*x*x)+x/0.0102013),-1.14468)+2.16163*TMath::Landau(x,3.97083,1.44648),0.00489879*TMath::Power((exp(- -2.36164*sqrt(x*x+0.547*0.547-0.139*0.139)-0.72334*(x*x+0.547*0.547-0.139*0.139))+TMath::Power(0.478277/0.00489879,-1./1.05253)*sqrt(x*x+0.547*0.547-0.139*0.139)/0.0139668),-1.05253)/TMath::Power((exp(- -2.36164*x-0.72334*x*x)+x/0.0139668),-1.05253)+1.73053*TMath::Landau(x,2.39399,0.879267)),TMath::Max(0.000175259*TMath::Power((exp(- -2.1325*sqrt(x*x+0.547*0.547-0.139*0.139)-0.591882*(x*x+0.547*0.547-0.139*0.139))+TMath::Power(0.482288/0.000175259,-1./15.7215)*sqrt(x*x+0.547*0.547-0.139*0.139)/0.027171),-15.7215)/TMath::Power((exp(- -2.1325*x-0.591882*x*x)+x/0.027171),-15.7215)+1.7109*TMath::Landau(x,2.36532,0.973179),0.00489879*TMath::Power((exp(- -2.36164*sqrt(x*x+0.547*0.547-0.139*0.139)-0.72334*(x*x+0.547*0.547-0.139*0.139))+TMath::Power(0.478277/0.00489879,-1./1.05253)*sqrt(x*x+0.547*0.547-0.139*0.139)/0.0139668),-1.05253)/TMath::Power((exp(- -2.36164*x-0.72334*x*x)+x/0.0139668),-1.05253)+1.73053*TMath::Landau(x,2.39399,0.879267))))+(x>=9.168)*1.08*(((0.499605*1.)+(155.836*(-0.00300369*TMath::Power(1.+((x/1.09373)*(x/1.09373)),-(0.672088)))))/(1.+(-0.00300369*TMath::Power(1.+((x/1.09373)*(x/1.09373)),-(0.672088))))))))", + "333_pt": "(TMath::TwoPi()*x*(219.382*exp(-(sqrt(x*x+0.139571*0.139571)-0.139571)/0.384303)+2471.6*pow(exp(-1.12373*x-0.752507*x*x)+x/0.438343,-5.45943)))*((x<=0.5)*(-0.3/0.5*x+1.5)*(0.1191/(1+exp(-(x- -0.316437)/0.554431))+-0.507618*TMath::Gaus(x,1.69654,1.62649)+0.494136*TMath::Gaus(x,2.56805,1.6193)+0.0789659)+(x>0.5)*1.2*(0.1191/(1+exp(-(x- -0.316437)/0.554431))+-0.507618*TMath::Gaus(x,1.69654,1.62649)+0.494136*TMath::Gaus(x,2.56805,1.6193)+0.0789659))" }, - "5TeV_3040_wRatio": { + "5TeV_0005_wRatio_etatest_ratiosdown": { "histoMtScaleFactor": { - "113": 0.85, - "223": 0.7, - "331": 0.4 + "113": 0.68, + "223": 0.56, + "331": 0.32 }, - "111_pt": "TMath::TwoPi()*x*(24.3786*exp(-(sqrt(x*x+0.139571*0.139571)-0.139571)/0.412015)+908.266*pow(exp(-0.735883*x-0.425837*x*x)+x/0.505017,-5.68841))", - "221_pt": "(TMath::TwoPi()*x*(24.3786*exp(-(sqrt(x*x+0.139571*0.139571)-0.139571)/0.412015)+908.266*pow(exp(-0.735883*x-0.425837*x*x)+x/0.505017,-5.68841)))*((0.317347/(1+exp(-(x-0.475129)/0.245111))+-0.265641*TMath::Gaus(x,0.276828,1.17016)+-0.0289536*TMath::Gaus(x,5.40691,2.58911)+0.249861+((0.550454*exp((((0.995785*x)-sqrt((x*x)+(0.5478530000*0.5478530000)))/sqrt(1-(0.995785*0.995785)))/1.71099))+(0.0106936*(0.620714*TMath::Power(1+((x/29.189)*(x/29.189)),-(506.895)))))/(exp((((0.995785*x)-sqrt((x*x)+(0.1349770000*0.1349770000)))/sqrt(1-(0.995785*0.995785)))/1.71099)+(0.620714*TMath::Power(1+((x/29.189)*(x/29.189)),-(506.895)))))/2.)", - "333_pt": "(TMath::TwoPi()*x*(24.3786*exp(-(sqrt(x*x+0.139571*0.139571)-0.139571)/0.412015)+908.266*pow(exp(-0.735883*x-0.425837*x*x)+x/0.505017,-5.68841)))*(0.106572/(1+exp(-(x-1.71328)/1.68645))+-0.54012*TMath::Gaus(x,0.754082,1.88026)+0.452996*TMath::Gaus(x,1.49283,2.4567)+0.0943071)", - "111_v2_def": "x*x*(0.29722*exp(-x/0.318227)+0.560172*pow(1+x/0.401715,-2.04434)+0.193576*exp(-x/1.2557))", - "310_v2_def": "x*x*(0.0280321*exp(-x/0.49621)+0.328197*pow(1+x/0.0128527,-0.853155)+0.214485*exp(-x/1.29581))", - "333_v2_def": "x*x*(1.2367*exp(-x/0.629473)+-3.9919*pow(1+x/0.886275,-3.11899)+0.274776*exp(-x/1.82705))" + "111_pt": "TMath::TwoPi()*x*(219.382*exp(-(sqrt(x*x+0.139571*0.139571)-0.139571)/0.384303)+2471.6*pow(exp(-1.12373*x-0.752507*x*x)+x/0.438343,-5.45943))", + "221_pt": "(TMath::TwoPi()*x*(219.382*exp(-(sqrt(x*x+0.139571*0.139571)-0.139571)/0.384303)+2471.6*pow(exp(-1.12373*x-0.752507*x*x)+x/0.438343,-5.45943)))*((((x<11.6581)*(TMath::Min(TMath::Min(0.00302888*TMath::Power((exp(-0.246982*sqrt(x*x+0.547*0.547-0.139*0.139)-0.204843*(x*x+0.547*0.547-0.139*0.139))+TMath::Power(0.485848/0.00302888,-1./335.069)*sqrt(x*x+0.547*0.547-0.139*0.139)/2.46929),-335.069)/TMath::Power((exp(-0.246982*x-0.204843*x*x)+x/2.46929),-335.069)+2.62546*TMath::Landau(x,3.61147,1.38592),0.926*(9.36242e-05*TMath::Power((exp(- -2.56458*sqrt(x*x+0.547*0.547-0.139*0.139)-0.742625*(x*x+0.547*0.547-0.139*0.139))+TMath::Power(0.457041/9.36242e-05,-1./8.15756)*sqrt(x*x+0.547*0.547-0.139*0.139)/0.0235913),-8.15756)/TMath::Power((exp(- -2.56458*x-0.742625*x*x)+x/0.0235913),-8.15756)+1.50683*TMath::Landau(x,2.1159,0.843387))),TMath::Min(0.00624935*TMath::Power((exp(- -2.56471*sqrt(x*x+0.547*0.547-0.139*0.139)-2.49586*(x*x+0.547*0.547-0.139*0.139))+TMath::Power(0.45/0.00624935,-1./44.8766)*sqrt(x*x+0.547*0.547-0.139*0.139)/0.202909),-44.8766)/TMath::Power((exp(- -2.56471*x-2.49586*x*x)+x/0.202909),-44.8766)+1.58602*TMath::Landau(x,2.23166,0.861224),0.926*(9.36242e-05*TMath::Power((exp(- -2.56458*sqrt(x*x+0.547*0.547-0.139*0.139)-0.742625*(x*x+0.547*0.547-0.139*0.139))+TMath::Power(0.457041/9.36242e-05,-1./8.15756)*sqrt(x*x+0.547*0.547-0.139*0.139)/0.0235913),-8.15756)/TMath::Power((exp(- -2.56458*x-0.742625*x*x)+x/0.0235913),-8.15756)+1.50683*TMath::Landau(x,2.1159,0.843387)))))+(x>=11.6581)*0.426)))", + "333_pt": "(TMath::TwoPi()*x*(219.382*exp(-(sqrt(x*x+0.139571*0.139571)-0.139571)/0.384303)+2471.6*pow(exp(-1.12373*x-0.752507*x*x)+x/0.438343,-5.45943)))*((x<=0.5)*(0.3/0.5*x+0.5)*(0.1191/(1+exp(-(x- -0.316437)/0.554431))+-0.507618*TMath::Gaus(x,1.69654,1.62649)+0.494136*TMath::Gaus(x,2.56805,1.6193)+0.0789659)+(x>0.5)*0.8*(0.1191/(1+exp(-(x- -0.316437)/0.554431))+-0.507618*TMath::Gaus(x,1.69654,1.62649)+0.494136*TMath::Gaus(x,2.56805,1.6193)+0.0789659))" }, - "5TeV_4050_wRatio": { + "5TeV_0005_wRatio_etatest_pi0up": { "histoMtScaleFactor": { "113": 0.85, "223": 0.7, "331": 0.4 }, - "111_pt": "TMath::TwoPi()*x*(9.00063*exp(-(sqrt(x*x+0.139571*0.139571)-0.139571)/0.428379)+636.492*pow(exp(-0.659016*x-0.397367*x*x)+x/0.512428,-5.72313))", - "221_pt": "(TMath::TwoPi()*x*(9.00063*exp(-(sqrt(x*x+0.139571*0.139571)-0.139571)/0.428379)+636.492*pow(exp(-0.659016*x-0.397367*x*x)+x/0.512428,-5.72313)))*((0.298649/(1+exp(-(x-0.494749)/0.23628))+-0.255064*TMath::Gaus(x,0.170043,1.31558)+-0.024999*TMath::Gaus(x,8.22033,2.71373)+0.251236+((0.550454*exp((((0.995785*x)-sqrt((x*x)+(0.5478530000*0.5478530000)))/sqrt(1-(0.995785*0.995785)))/1.71099))+(0.0106936*(0.620714*TMath::Power(1+((x/29.189)*(x/29.189)),-(506.895)))))/(exp((((0.995785*x)-sqrt((x*x)+(0.1349770000*0.1349770000)))/sqrt(1-(0.995785*0.995785)))/1.71099)+(0.620714*TMath::Power(1+((x/29.189)*(x/29.189)),-(506.895)))))/2.)", - "333_pt": "(TMath::TwoPi()*x*(9.00063*exp(-(sqrt(x*x+0.139571*0.139571)-0.139571)/0.428379)+636.492*pow(exp(-0.659016*x-0.397367*x*x)+x/0.512428,-5.72313)))*(0.0979137/(1+exp(-(x-1.53259)/0.370136))+-0.537275*TMath::Gaus(x,0.706186,2.03543)+0.45201*TMath::Gaus(x,1.18876,2.40911)+0.104985)", - "111_v2_def": "x*x*(0.171282*exp(-x/0.353318)+1.13749*pow(1+x/0.290699,-2.02699)+0.20604*exp(-x/1.19178))", - "310_v2_def": "x*x*(-0.524086*exp(-x/0.402378)+0.891134*pow(1+x/1.15413,-3.07832)+0.0812177*exp(-x/1.22691))", - "333_v2_def": "x*x*(-2.78876*exp(-x/0.581864)+3.6669*pow(1+x/3.01301,-6.60505)+0.0436791*exp(-x/1.23285))" + "111_pt": "TMath::TwoPi()*x*(236.555*exp(-(sqrt(x*x+0.139571*0.139571)-0.139571)/0.382365)+2787.27*pow(exp(-1.05343*x-0.780376*x*x)+x/0.43017,-5.45613))", + "221_pt": "(TMath::TwoPi()*x*(236.555*exp(-(sqrt(x*x+0.139571*0.139571)-0.139571)/0.382365)+2787.27*pow(exp(-1.05343*x-0.780376*x*x)+x/0.43017,-5.45613)))*((9.36242e-05*TMath::Power((exp(- -2.56458*sqrt(x*x+0.547*0.547-0.139*0.139)-0.742625*(x*x+0.547*0.547-0.139*0.139))+TMath::Power(0.457041/9.36242e-05,-1./8.15756)*sqrt(x*x+0.547*0.547-0.139*0.139)/0.0235913),-8.15756)/TMath::Power((exp(- -2.56458*x-0.742625*x*x)+x/0.0235913),-8.15756)+1.50683*TMath::Landau(x,2.1159,0.843387)))", + "333_pt": "(TMath::TwoPi()*x*(219.382*exp(-(sqrt(x*x+0.139571*0.139571)-0.139571)/0.384303)+2471.6*pow(exp(-1.12373*x-0.752507*x*x)+x/0.438343,-5.45943)))*(0.1191/(1+exp(-(x- -0.316437)/0.554431))+-0.507618*TMath::Gaus(x,1.69654,1.62649)+0.494136*TMath::Gaus(x,2.56805,1.6193)+0.0789659)" }, - "5TeV_4050_wRatio_pi0up": { + "5TeV_0005_wRatio_etatest_pi0down": { "histoMtScaleFactor": { "113": 0.85, "223": 0.7, "331": 0.4 }, - "111_pt": "TMath::TwoPi()*x*(10.1537*exp(-(sqrt(x*x+0.139571*0.139571)-0.139571)/0.423934)+708.793*pow(exp(-0.595237*x-0.468542*x*x)+x/0.502946,-5.71377))", - "221_pt": "(TMath::TwoPi()*x*(10.1537*exp(-(sqrt(x*x+0.139571*0.139571)-0.139571)/0.423934)+708.793*pow(exp(-0.595237*x-0.468542*x*x)+x/0.502946,-5.71377)))*((0.298649/(1+exp(-(x-0.494749)/0.23628))+-0.255064*TMath::Gaus(x,0.170043,1.31558)+-0.024999*TMath::Gaus(x,8.22033,2.71373)+0.251236+((0.550454*exp((((0.995785*x)-sqrt((x*x)+(0.5478530000*0.5478530000)))/sqrt(1-(0.995785*0.995785)))/1.71099))+(0.0106936*(0.620714*TMath::Power(1+((x/29.189)*(x/29.189)),-(506.895)))))/(exp((((0.995785*x)-sqrt((x*x)+(0.1349770000*0.1349770000)))/sqrt(1-(0.995785*0.995785)))/1.71099)+(0.620714*TMath::Power(1+((x/29.189)*(x/29.189)),-(506.895)))))/2.)", - "333_pt": "(TMath::TwoPi()*x*(9.00063*exp(-(sqrt(x*x+0.139571*0.139571)-0.139571)/0.428379)+636.492*pow(exp(-0.659016*x-0.397367*x*x)+x/0.512428,-5.72313)))*(0.0979137/(1+exp(-(x-1.53259)/0.370136))+-0.537275*TMath::Gaus(x,0.706186,2.03543)+0.45201*TMath::Gaus(x,1.18876,2.40911)+0.104985)", - "111_v2_def": "x*x*(0.171282*exp(-x/0.353318)+1.13749*pow(1+x/0.290699,-2.02699)+0.20604*exp(-x/1.19178))", - "310_v2_def": "x*x*(-0.524086*exp(-x/0.402378)+0.891134*pow(1+x/1.15413,-3.07832)+0.0812177*exp(-x/1.22691))", - "333_v2_def": "x*x*(-2.78876*exp(-x/0.581864)+3.6669*pow(1+x/3.01301,-6.60505)+0.0436791*exp(-x/1.23285))" + "111_pt": "TMath::TwoPi()*x*(202.506*exp(-(sqrt(x*x+0.139571*0.139571)-0.139571)/0.386428)+2172.76*pow(exp(-1.20019*x-0.719277*x*x)+x/0.447319,-5.46279))", + "221_pt": "(TMath::TwoPi()*x*(202.506*exp(-(sqrt(x*x+0.139571*0.139571)-0.139571)/0.386428)+2172.76*pow(exp(-1.20019*x-0.719277*x*x)+x/0.447319,-5.46279)))*((9.36242e-05*TMath::Power((exp(- -2.56458*sqrt(x*x+0.547*0.547-0.139*0.139)-0.742625*(x*x+0.547*0.547-0.139*0.139))+TMath::Power(0.457041/9.36242e-05,-1./8.15756)*sqrt(x*x+0.547*0.547-0.139*0.139)/0.0235913),-8.15756)/TMath::Power((exp(- -2.56458*x-0.742625*x*x)+x/0.0235913),-8.15756)+1.50683*TMath::Landau(x,2.1159,0.843387)))", + "333_pt": "(TMath::TwoPi()*x*(219.382*exp(-(sqrt(x*x+0.139571*0.139571)-0.139571)/0.384303)+2471.6*pow(exp(-1.12373*x-0.752507*x*x)+x/0.438343,-5.45943)))*(0.1191/(1+exp(-(x- -0.316437)/0.554431))+-0.507618*TMath::Gaus(x,1.69654,1.62649)+0.494136*TMath::Gaus(x,2.56805,1.6193)+0.0789659)" }, - "5TeV_3040_wRatio_pi0up": { + "5TeV_0510_wRatio_etatest": { "histoMtScaleFactor": { "113": 0.85, "223": 0.7, "331": 0.4 }, - "111_pt": "TMath::TwoPi()*x*(26.8208*exp(-(sqrt(x*x+0.139571*0.139571)-0.139571)/0.408437)+1019.42*pow(exp(-0.662498*x-0.498822*x*x)+x/0.495404,-5.68121))", - "221_pt": "(TMath::TwoPi()*x*(26.8208*exp(-(sqrt(x*x+0.139571*0.139571)-0.139571)/0.408437)+1019.42*pow(exp(-0.662498*x-0.498822*x*x)+x/0.495404,-5.68121)))*((0.317347/(1+exp(-(x-0.475129)/0.245111))+-0.265641*TMath::Gaus(x,0.276828,1.17016)+-0.0289536*TMath::Gaus(x,5.40691,2.58911)+0.249861+((0.550454*exp((((0.995785*x)-sqrt((x*x)+(0.5478530000*0.5478530000)))/sqrt(1-(0.995785*0.995785)))/1.71099))+(0.0106936*(0.620714*TMath::Power(1+((x/29.189)*(x/29.189)),-(506.895)))))/(exp((((0.995785*x)-sqrt((x*x)+(0.1349770000*0.1349770000)))/sqrt(1-(0.995785*0.995785)))/1.71099)+(0.620714*TMath::Power(1+((x/29.189)*(x/29.189)),-(506.895)))))/2.)", - "333_pt": "(TMath::TwoPi()*x*(24.3786*exp(-(sqrt(x*x+0.139571*0.139571)-0.139571)/0.412015)+908.266*pow(exp(-0.735883*x-0.425837*x*x)+x/0.505017,-5.68841)))*(0.106572/(1+exp(-(x-1.71328)/1.68645))+-0.54012*TMath::Gaus(x,0.754082,1.88026)+0.452996*TMath::Gaus(x,1.49283,2.4567)+0.0943071)", - "111_v2_def": "x*x*(0.29722*exp(-x/0.318227)+0.560172*pow(1+x/0.401715,-2.04434)+0.193576*exp(-x/1.2557))", - "310_v2_def": "x*x*(0.0280321*exp(-x/0.49621)+0.328197*pow(1+x/0.0128527,-0.853155)+0.214485*exp(-x/1.29581))", - "333_v2_def": "x*x*(1.2367*exp(-x/0.629473)+-3.9919*pow(1+x/0.886275,-3.11899)+0.274776*exp(-x/1.82705))" + "111_pt": "TMath::TwoPi()*x*(156.897*exp(-(sqrt(x*x+0.139571*0.139571)-0.139571)/0.390093)+1835.17*pow(exp(-1.1618*x-0.514011*x*x)+x/0.465575,-5.50332))", + "221_pt": "(TMath::TwoPi()*x*(156.897*exp(-(sqrt(x*x+0.139571*0.139571)-0.139571)/0.390093)+1835.17*pow(exp(-1.1618*x-0.514011*x*x)+x/0.465575,-5.50332)))*((0.000246618*TMath::Power((exp(- -3.44417*sqrt(x*x+0.547*0.547-0.139*0.139)-0.952884*(x*x+0.547*0.547-0.139*0.139))+TMath::Power(0.476466/0.000246618,-1./8.8133)*sqrt(x*x+0.547*0.547-0.139*0.139)/0.0060628),-8.8133)/TMath::Power((exp(- -3.44417*x-0.952884*x*x)+x/0.0060628),-8.8133)+1.09231*TMath::Landau(x,2.04517,0.864605)))", + "333_pt": "(TMath::TwoPi()*x*(156.897*exp(-(sqrt(x*x+0.139571*0.139571)-0.139571)/0.390093)+1835.17*pow(exp(-1.1618*x-0.514011*x*x)+x/0.465575,-5.50332)))*(0.1191/(1+exp(-(x- -0.316437)/0.554431))+-0.507618*TMath::Gaus(x,1.69654,1.62649)+0.494136*TMath::Gaus(x,2.56805,1.6193)+0.0789659)" + }, + "5TeV_0510_wRatio_etatest_ratiosup": { + "histoMtScaleFactor": { + "113": 1.02, + "223": 0.84, + "331": 0.48 + }, + "111_pt": "TMath::TwoPi()*x*(156.897*exp(-(sqrt(x*x+0.139571*0.139571)-0.139571)/0.390093)+1835.17*pow(exp(-1.1618*x-0.514011*x*x)+x/0.465575,-5.50332))", + "221_pt": "(TMath::TwoPi()*x*(156.897*exp(-(sqrt(x*x+0.139571*0.139571)-0.139571)/0.390093)+1835.17*pow(exp(-1.1618*x-0.514011*x*x)+x/0.465575,-5.50332)))*((((x<10.278)*(TMath::Max(TMath::Max(0.000295533*TMath::Power((exp(- -1.60043*sqrt(x*x+0.547*0.547-0.139*0.139)-0.655985*(x*x+0.547*0.547-0.139*0.139))+TMath::Power(0.500931/0.000295533,-1./16.3545)*sqrt(x*x+0.547*0.547-0.139*0.139)/0.130844),-16.3545)/TMath::Power((exp(- -1.60043*x-0.655985*x*x)+x/0.130844),-16.3545)+1.5704*TMath::Landau(x,2.17776,0.921819),0.00540987*TMath::Power((exp(-0.202531*sqrt(x*x+0.547*0.547-0.139*0.139)-0.404918*(x*x+0.547*0.547-0.139*0.139))+TMath::Power(0.496965/0.00540987,-1./0.457227)*sqrt(x*x+0.547*0.547-0.139*0.139)/0.010344),-0.457227)/TMath::Power((exp(-0.202531*x-0.404918*x*x)+x/0.010344),-0.457227)+1.48331*TMath::Landau(x,2.17198,0.823192)),TMath::Max(3.85365e-05*TMath::Power((exp(- -0.50908*sqrt(x*x+0.547*0.547-0.139*0.139)-0.0438035*(x*x+0.547*0.547-0.139*0.139))+TMath::Power(0.463429/3.85365e-05,-1./6.0698)*sqrt(x*x+0.547*0.547-0.139*0.139)/0.0472676),-6.0698)/TMath::Power((exp(- -0.50908*x-0.0438035*x*x)+x/0.0472676),-6.0698)+2.34475*TMath::Landau(x,3.86817,1.59145),0.00540987*TMath::Power((exp(-0.202531*sqrt(x*x+0.547*0.547-0.139*0.139)-0.404918*(x*x+0.547*0.547-0.139*0.139))+TMath::Power(0.496965/0.00540987,-1./0.457227)*sqrt(x*x+0.547*0.547-0.139*0.139)/0.010344),-0.457227)/TMath::Power((exp(-0.202531*x-0.404918*x*x)+x/0.010344),-0.457227)+1.48331*TMath::Landau(x,2.17198,0.823192))))+(x>=10.278)*1.08*(((0.499605*1.)+(155.836*(-0.00300369*TMath::Power(1.+((x/1.09373)*(x/1.09373)),-(0.672088)))))/(1.+(-0.00300369*TMath::Power(1.+((x/1.09373)*(x/1.09373)),-(0.672088))))))))", + "333_pt": "(TMath::TwoPi()*x*(156.897*exp(-(sqrt(x*x+0.139571*0.139571)-0.139571)/0.390093)+1835.17*pow(exp(-1.1618*x-0.514011*x*x)+x/0.465575,-5.50332)))*((x<=0.5)*(-0.3/0.5*x+1.5)*(0.1191/(1+exp(-(x- -0.316437)/0.554431))+-0.507618*TMath::Gaus(x,1.69654,1.62649)+0.494136*TMath::Gaus(x,2.56805,1.6193)+0.0789659)+(x>0.5)*1.2*(0.1191/(1+exp(-(x- -0.316437)/0.554431))+-0.507618*TMath::Gaus(x,1.69654,1.62649)+0.494136*TMath::Gaus(x,2.56805,1.6193)+0.0789659))" + }, + "5TeV_0510_wRatio_etatest_ratiosdown": { + "histoMtScaleFactor": { + "113": 0.68, + "223": 0.56, + "331": 0.32 + }, + "111_pt": "TMath::TwoPi()*x*(156.897*exp(-(sqrt(x*x+0.139571*0.139571)-0.139571)/0.390093)+1835.17*pow(exp(-1.1618*x-0.514011*x*x)+x/0.465575,-5.50332))", + "221_pt": "(TMath::TwoPi()*x*(156.897*exp(-(sqrt(x*x+0.139571*0.139571)-0.139571)/0.390093)+1835.17*pow(exp(-1.1618*x-0.514011*x*x)+x/0.465575,-5.50332)))*((((x<11.6581)*(TMath::Min(TMath::Min(0.00302888*TMath::Power((exp(-0.246982*sqrt(x*x+0.547*0.547-0.139*0.139)-0.204843*(x*x+0.547*0.547-0.139*0.139))+TMath::Power(0.485848/0.00302888,-1./335.069)*sqrt(x*x+0.547*0.547-0.139*0.139)/2.46929),-335.069)/TMath::Power((exp(-0.246982*x-0.204843*x*x)+x/2.46929),-335.069)+2.62546*TMath::Landau(x,3.61147,1.38592),0.926*(9.36242e-05*TMath::Power((exp(- -2.56458*sqrt(x*x+0.547*0.547-0.139*0.139)-0.742625*(x*x+0.547*0.547-0.139*0.139))+TMath::Power(0.457041/9.36242e-05,-1./8.15756)*sqrt(x*x+0.547*0.547-0.139*0.139)/0.0235913),-8.15756)/TMath::Power((exp(- -2.56458*x-0.742625*x*x)+x/0.0235913),-8.15756)+1.50683*TMath::Landau(x,2.1159,0.843387))),TMath::Min(0.00624935*TMath::Power((exp(- -2.56471*sqrt(x*x+0.547*0.547-0.139*0.139)-2.49586*(x*x+0.547*0.547-0.139*0.139))+TMath::Power(0.45/0.00624935,-1./44.8766)*sqrt(x*x+0.547*0.547-0.139*0.139)/0.202909),-44.8766)/TMath::Power((exp(- -2.56471*x-2.49586*x*x)+x/0.202909),-44.8766)+1.58602*TMath::Landau(x,2.23166,0.861224),0.926*(9.36242e-05*TMath::Power((exp(- -2.56458*sqrt(x*x+0.547*0.547-0.139*0.139)-0.742625*(x*x+0.547*0.547-0.139*0.139))+TMath::Power(0.457041/9.36242e-05,-1./8.15756)*sqrt(x*x+0.547*0.547-0.139*0.139)/0.0235913),-8.15756)/TMath::Power((exp(- -2.56458*x-0.742625*x*x)+x/0.0235913),-8.15756)+1.50683*TMath::Landau(x,2.1159,0.843387)))))+(x>=11.6581)*0.426)))", + "333_pt": "(TMath::TwoPi()*x*(156.897*exp(-(sqrt(x*x+0.139571*0.139571)-0.139571)/0.390093)+1835.17*pow(exp(-1.1618*x-0.514011*x*x)+x/0.465575,-5.50332)))*((x<=0.5)*(0.3/0.5*x+0.5)*(0.1191/(1+exp(-(x- -0.316437)/0.554431))+-0.507618*TMath::Gaus(x,1.69654,1.62649)+0.494136*TMath::Gaus(x,2.56805,1.6193)+0.0789659)+(x>0.5)*0.8*(0.1191/(1+exp(-(x- -0.316437)/0.554431))+-0.507618*TMath::Gaus(x,1.69654,1.62649)+0.494136*TMath::Gaus(x,2.56805,1.6193)+0.0789659))" }, - "5TeV_0510_wRatio_pi0up": { + "5TeV_0510_wRatio_etatest_pi0up": { "histoMtScaleFactor": { "113": 0.85, "223": 0.7, "331": 0.4 }, "111_pt": "TMath::TwoPi()*x*(170.514*exp(-(sqrt(x*x+0.139571*0.139571)-0.139571)/0.38767)+2102.92*pow(exp(-1.0722*x-0.567406*x*x)+x/0.45525,-5.49867))", - "221_pt": "(TMath::TwoPi()*x*(170.514*exp(-(sqrt(x*x+0.139571*0.139571)-0.139571)/0.38767)+2102.92*pow(exp(-1.0722*x-0.567406*x*x)+x/0.45525,-5.49867)))*(((x<=4.125494)*(0.462257/(1+exp(-(x-0.489168)/0.259816))+-0.338875*TMath::Gaus(x,0.655039,0.915494)+-0.277601*TMath::Gaus(x,5.26982,2.67864)+0.291403)+(x>4.125494)*(0.197492/(1+exp(-(x-5.11825)/1.30203))+-596719*TMath::Gaus(x,0.710032,0.569486)+1.82757*TMath::Gaus(x,-2.55348,2.83425)+0.33265)+((0.550454*exp((((0.995785*x)-sqrt((x*x)+(0.5478530000*0.5478530000)))/sqrt(1-(0.995785*0.995785)))/1.71099))+(0.0106936*(0.620714*TMath::Power(1+((x/29.189)*(x/29.189)),-(506.895)))))/(exp((((0.995785*x)-sqrt((x*x)+(0.1349770000*0.1349770000)))/sqrt(1-(0.995785*0.995785)))/1.71099)+(0.620714*TMath::Power(1+((x/29.189)*(x/29.189)),-(506.895)))))/2.)", + "221_pt": "(TMath::TwoPi()*x*(170.514*exp(-(sqrt(x*x+0.139571*0.139571)-0.139571)/0.38767)+2102.92*pow(exp(-1.0722*x-0.567406*x*x)+x/0.45525,-5.49867)))*((0.000246618*TMath::Power((exp(- -3.44417*sqrt(x*x+0.547*0.547-0.139*0.139)-0.952884*(x*x+0.547*0.547-0.139*0.139))+TMath::Power(0.476466/0.000246618,-1./8.8133)*sqrt(x*x+0.547*0.547-0.139*0.139)/0.0060628),-8.8133)/TMath::Power((exp(- -3.44417*x-0.952884*x*x)+x/0.0060628),-8.8133)+1.09231*TMath::Landau(x,2.04517,0.864605)))", "333_pt": "(TMath::TwoPi()*x*(156.897*exp(-(sqrt(x*x+0.139571*0.139571)-0.139571)/0.390093)+1835.17*pow(exp(-1.1618*x-0.514011*x*x)+x/0.465575,-5.50332)))*(0.1191/(1+exp(-(x- -0.316437)/0.554431))+-0.507618*TMath::Gaus(x,1.69654,1.62649)+0.494136*TMath::Gaus(x,2.56805,1.6193)+0.0789659)" }, - "5TeV_0005_wRatio_pi0up": { + "5TeV_0510_wRatio_etatest_pi0down": { "histoMtScaleFactor": { "113": 0.85, "223": 0.7, "331": 0.4 }, - "111_pt": "TMath::TwoPi()*x*(236.555*exp(-(sqrt(x*x+0.139571*0.139571)-0.139571)/0.382365)+2787.27*pow(exp(-1.05343*x-0.780376*x*x)+x/0.43017,-5.45613))", - "221_pt": "(TMath::TwoPi()*x*(236.555*exp(-(sqrt(x*x+0.139571*0.139571)-0.139571)/0.382365)+2787.27*pow(exp(-1.05343*x-0.780376*x*x)+x/0.43017,-5.45613)))*(((x<=4.303300)*(0.385689/(1+exp(-(x-0.442495)/0.303977))+-0.324645*TMath::Gaus(x,0.364119,1.01338)+-0.268261*TMath::Gaus(x,8.32791,4.74697)+0.318614)+(x>4.303300)*(0.0836242/(1+exp(-(x-6.88914)/2.15587))+0.757533*TMath::Gaus(x,1.19329,1.35263)+40382.9*TMath::Gaus(x,-92.3117,-16.5516)+0.442)+((0.550454*exp((((0.995785*x)-sqrt((x*x)+(0.5478530000*0.5478530000)))/sqrt(1-(0.995785*0.995785)))/1.71099))+(0.0106936*(0.620714*TMath::Power(1+((x/29.189)*(x/29.189)),-(506.895)))))/(exp((((0.995785*x)-sqrt((x*x)+(0.1349770000*0.1349770000)))/sqrt(1-(0.995785*0.995785)))/1.71099)+(0.620714*TMath::Power(1+((x/29.189)*(x/29.189)),-(506.895)))))/2.)", - "333_pt": "(TMath::TwoPi()*x*(219.382*exp(-(sqrt(x*x+0.139571*0.139571)-0.139571)/0.384303)+2471.6*pow(exp(-1.12373*x-0.752507*x*x)+x/0.438343,-5.45943)))*(0.1191/(1+exp(-(x- -0.316437)/0.554431))+-0.507618*TMath::Gaus(x,1.69654,1.62649)+0.494136*TMath::Gaus(x,2.56805,1.6193)+0.0789659)" + "111_pt": "TMath::TwoPi()*x*(143.633*exp(-(sqrt(x*x+0.139571*0.139571)-0.139571)/0.392747)+1585.64*pow(exp(-1.25879*x-0.453071*x*x)+x/0.476927,-5.50804))", + "221_pt": "(TMath::TwoPi()*x*(143.633*exp(-(sqrt(x*x+0.139571*0.139571)-0.139571)/0.392747)+1585.64*pow(exp(-1.25879*x-0.453071*x*x)+x/0.476927,-5.50804)))*((0.000246618*TMath::Power((exp(- -3.44417*sqrt(x*x+0.547*0.547-0.139*0.139)-0.952884*(x*x+0.547*0.547-0.139*0.139))+TMath::Power(0.476466/0.000246618,-1./8.8133)*sqrt(x*x+0.547*0.547-0.139*0.139)/0.0060628),-8.8133)/TMath::Power((exp(- -3.44417*x-0.952884*x*x)+x/0.0060628),-8.8133)+1.09231*TMath::Landau(x,2.04517,0.864605)))", + "333_pt": "(TMath::TwoPi()*x*(156.897*exp(-(sqrt(x*x+0.139571*0.139571)-0.139571)/0.390093)+1835.17*pow(exp(-1.1618*x-0.514011*x*x)+x/0.465575,-5.50332)))*(0.1191/(1+exp(-(x- -0.316437)/0.554431))+-0.507618*TMath::Gaus(x,1.69654,1.62649)+0.494136*TMath::Gaus(x,2.56805,1.6193)+0.0789659)" }, - "5TeV_0005_wRatio_pi0down": { + "5TeV_1020_wRatio_etatest": { "histoMtScaleFactor": { "113": 0.85, "223": 0.7, "331": 0.4 }, - "111_pt": "TMath::TwoPi()*x*(202.506*exp(-(sqrt(x*x+0.139571*0.139571)-0.139571)/0.386428)+2172.76*pow(exp(-1.20019*x-0.719277*x*x)+x/0.447319,-5.46279))", - "221_pt": "(TMath::TwoPi()*x*(202.506*exp(-(sqrt(x*x+0.139571*0.139571)-0.139571)/0.386428)+2172.76*pow(exp(-1.20019*x-0.719277*x*x)+x/0.447319,-5.46279)))*(((x<=4.303300)*(0.385689/(1+exp(-(x-0.442495)/0.303977))+-0.324645*TMath::Gaus(x,0.364119,1.01338)+-0.268261*TMath::Gaus(x,8.32791,4.74697)+0.318614)+(x>4.303300)*(0.0836242/(1+exp(-(x-6.88914)/2.15587))+0.757533*TMath::Gaus(x,1.19329,1.35263)+40382.9*TMath::Gaus(x,-92.3117,-16.5516)+0.442)+((0.550454*exp((((0.995785*x)-sqrt((x*x)+(0.5478530000*0.5478530000)))/sqrt(1-(0.995785*0.995785)))/1.71099))+(0.0106936*(0.620714*TMath::Power(1+((x/29.189)*(x/29.189)),-(506.895)))))/(exp((((0.995785*x)-sqrt((x*x)+(0.1349770000*0.1349770000)))/sqrt(1-(0.995785*0.995785)))/1.71099)+(0.620714*TMath::Power(1+((x/29.189)*(x/29.189)),-(506.895)))))/2.)", - "333_pt": "(TMath::TwoPi()*x*(219.382*exp(-(sqrt(x*x+0.139571*0.139571)-0.139571)/0.384303)+2471.6*pow(exp(-1.12373*x-0.752507*x*x)+x/0.438343,-5.45943)))*(0.1191/(1+exp(-(x- -0.316437)/0.554431))+-0.507618*TMath::Gaus(x,1.69654,1.62649)+0.494136*TMath::Gaus(x,2.56805,1.6193)+0.0789659)" + "111_pt": "TMath::TwoPi()*x*(102.279*exp(-(sqrt(x*x+0.139571*0.139571)-0.139571)/0.395141)+1545.4*pow(exp(-1.0113*x-0.476997*x*x)+x/0.47739,-5.54937))", + "221_pt": "(2.25035e-05*TMath::Power((exp(--2.8764*sqrt(x*x+0.547*0.547-0.139*0.139)-0.734747*(x*x+0.547*0.547-0.139*0.139))+TMath::Power(0.477784/2.25035e-05,-1./8.26791)*sqrt(x*x+0.547*0.547-0.139*0.139)/0.00603254),-8.26791)/TMath::Power((exp(--2.8764*x-0.734747*x*x)+x/0.00603254),-8.26791)+1.14358*TMath::Landau(x,2.10694,0.888101))*(TMath::TwoPi()*x*(102.279*exp(-(sqrt(x*x+0.139571*0.139571)-0.139571)/0.395141)+1545.4*pow(exp(-1.0113*x-0.476997*x*x)+x/0.47739,-5.54937)))", + "333_pt": "(TMath::TwoPi()*x*(102.279*exp(-(sqrt(x*x+0.139571*0.139571)-0.139571)/0.395141)+1545.4*pow(exp(-1.0113*x-0.476997*x*x)+x/0.47739,-5.54937)))*(0.161108/(1+exp(-(x-1.093)/0.625883))+-0.463285*TMath::Gaus(x,1.78683,1.67212)+0.486619*TMath::Gaus(x,2.62071,2.10312)+0.0149748)" }, - "5TeV_0510_wRatio_pi0down": { + "5TeV_1020_wRatio_etatest_ratiosup": { "histoMtScaleFactor": { - "113": 0.85, - "223": 0.7, - "331": 0.4 + "113": 1.02, + "223": 0.84, + "331": 0.48 }, - "111_pt": "TMath::TwoPi()*x*(143.633*exp(-(sqrt(x*x+0.139571*0.139571)-0.139571)/0.392747)+1585.64*pow(exp(-1.25879*x-0.453071*x*x)+x/0.476927,-5.50804))", - "221_pt": "(TMath::TwoPi()*x*(143.633*exp(-(sqrt(x*x+0.139571*0.139571)-0.139571)/0.392747)+1585.64*pow(exp(-1.25879*x-0.453071*x*x)+x/0.476927,-5.50804)))*(((x<=4.125494)*(0.462257/(1+exp(-(x-0.489168)/0.259816))+-0.338875*TMath::Gaus(x,0.655039,0.915494)+-0.277601*TMath::Gaus(x,5.26982,2.67864)+0.291403)+(x>4.125494)*(0.197492/(1+exp(-(x-5.11825)/1.30203))+-596719*TMath::Gaus(x,0.710032,0.569486)+1.82757*TMath::Gaus(x,-2.55348,2.83425)+0.33265)+((0.550454*exp((((0.995785*x)-sqrt((x*x)+(0.5478530000*0.5478530000)))/sqrt(1-(0.995785*0.995785)))/1.71099))+(0.0106936*(0.620714*TMath::Power(1+((x/29.189)*(x/29.189)),-(506.895)))))/(exp((((0.995785*x)-sqrt((x*x)+(0.1349770000*0.1349770000)))/sqrt(1-(0.995785*0.995785)))/1.71099)+(0.620714*TMath::Power(1+((x/29.189)*(x/29.189)),-(506.895)))))/2.)", - "333_pt": "(TMath::TwoPi()*x*(156.897*exp(-(sqrt(x*x+0.139571*0.139571)-0.139571)/0.390093)+1835.17*pow(exp(-1.1618*x-0.514011*x*x)+x/0.465575,-5.50332)))*(0.1191/(1+exp(-(x- -0.316437)/0.554431))+-0.507618*TMath::Gaus(x,1.69654,1.62649)+0.494136*TMath::Gaus(x,2.56805,1.6193)+0.0789659)" + "111_pt": "TMath::TwoPi()*x*(102.279*exp(-(sqrt(x*x+0.139571*0.139571)-0.139571)/0.395141)+1545.4*pow(exp(-1.0113*x-0.476997*x*x)+x/0.47739,-5.54937))", + "221_pt": "(TMath::TwoPi()*x*(102.279*exp(-(sqrt(x*x+0.139571*0.139571)-0.139571)/0.395141)+1545.4*pow(exp(-1.0113*x-0.476997*x*x)+x/0.47739,-5.54937)))*((TMath::TwoPi()*x*(102.279*exp(-(sqrt(x*x+0.139571*0.139571)-0.139571)/0.395141)+1545.4*pow(exp(-1.0113*x-0.476997*x*x)+x/0.47739,-5.54937)))*((x<=0.5)*(-0.3/0.5*x+1.5)*((0.161108/(1+exp(-(x-1.093)/0.625883))+-0.463285*TMath::Gaus(x,1.78683,1.67212)+0.486619*TMath::Gaus(x,2.62071,2.10312)+0.0149748)) +(x>0.5)*1.2*((0.161108/(1+exp(-(x-1.093)/0.625883))+-0.463285*TMath::Gaus(x,1.78683,1.67212)+0.486619*TMath::Gaus(x,2.62071,2.10312)+0.0149748))))", + "333_pt": "(TMath::TwoPi()*x*(102.279*exp(-(sqrt(x*x+0.139571*0.139571)-0.139571)/0.395141)+1545.4*pow(exp(-1.0113*x-0.476997*x*x)+x/0.47739,-5.54937))) *((x<=0.5)*(-0.3/0.5*x+1.5)*((0.161108/(1+exp(-(x-1.093)/0.625883))+-0.463285*TMath::Gaus(x,1.78683,1.67212)+0.486619*TMath::Gaus(x,2.62071,2.10312)+0.0149748)) +(x>0.5)*1.2*((0.161108/(1+exp(-(x-1.093)/0.625883))+-0.463285*TMath::Gaus(x,1.78683,1.67212)+0.486619*TMath::Gaus(x,2.62071,2.10312)+0.0149748)))" }, - "5TeV_3040_wRatio_pi0down": { + "5TeV_1020_wRatio_etatest_ratiosdown": { + "histoMtScaleFactor": { + "113": 0.68, + "223": 0.56, + "331": 0.32 + }, + "111_pt": "TMath::TwoPi()*x*(102.279*exp(-(sqrt(x*x+0.139571*0.139571)-0.139571)/0.395141)+1545.4*pow(exp(-1.0113*x-0.476997*x*x)+x/0.47739,-5.54937))", + "221_pt": "(TMath::TwoPi()*x*(102.279*exp(-(sqrt(x*x+0.139571*0.139571)-0.139571)/0.395141)+1545.4*pow(exp(-1.0113*x-0.476997*x*x)+x/0.47739,-5.54937)))*((x<=0.5)*(0.3/0.5*x+0.5)*((0.161108/(1+exp(-(x-1.093)/0.625883))+-0.463285*TMath::Gaus(x,1.78683,1.67212)+0.486619*TMath::Gaus(x,2.62071,2.10312)+0.0149748)) +(x>0.5)*0.8*((0.161108/(1+exp(-(x-1.093)/0.625883))+-0.463285*TMath::Gaus(x,1.78683,1.67212)+0.486619*TMath::Gaus(x,2.62071,2.10312)+0.0149748)))", + "333_pt": "(TMath::TwoPi()*x*(102.279*exp(-(sqrt(x*x+0.139571*0.139571)-0.139571)/0.395141)+1545.4*pow(exp(-1.0113*x-0.476997*x*x)+x/0.47739,-5.54937))) *((x<=0.5)*(0.3/0.5*x+0.5)*((0.161108/(1+exp(-(x-1.093)/0.625883))+-0.463285*TMath::Gaus(x,1.78683,1.67212)+0.486619*TMath::Gaus(x,2.62071,2.10312)+0.0149748)) +(x>0.5)*0.8*((0.161108/(1+exp(-(x-1.093)/0.625883))+-0.463285*TMath::Gaus(x,1.78683,1.67212)+0.486619*TMath::Gaus(x,2.62071,2.10312)+0.0149748)))" + }, + "5TeV_1020_wRatio_etatest_pi0up": { "histoMtScaleFactor": { "113": 0.85, "223": 0.7, "331": 0.4 }, - "111_pt": "TMath::TwoPi()*x*(22.2048*exp(-(sqrt(x*x+0.139571*0.139571)-0.139571)/0.41549)+802.356*pow(exp(-0.814916*x-0.343908*x*x)+x/0.515668,-5.69624))", - "221_pt": "(TMath::TwoPi()*x*(22.2048*exp(-(sqrt(x*x+0.139571*0.139571)-0.139571)/0.41549)+802.356*pow(exp(-0.814916*x-0.343908*x*x)+x/0.515668,-5.69624)))*((0.317347/(1+exp(-(x-0.475129)/0.245111))+-0.265641*TMath::Gaus(x,0.276828,1.17016)+-0.0289536*TMath::Gaus(x,5.40691,2.58911)+0.249861+((0.550454*exp((((0.995785*x)-sqrt((x*x)+(0.5478530000*0.5478530000)))/sqrt(1-(0.995785*0.995785)))/1.71099))+(0.0106936*(0.620714*TMath::Power(1+((x/29.189)*(x/29.189)),-(506.895)))))/(exp((((0.995785*x)-sqrt((x*x)+(0.1349770000*0.1349770000)))/sqrt(1-(0.995785*0.995785)))/1.71099)+(0.620714*TMath::Power(1+((x/29.189)*(x/29.189)),-(506.895)))))/2.)", - "333_pt": "(TMath::TwoPi()*x*(24.3786*exp(-(sqrt(x*x+0.139571*0.139571)-0.139571)/0.412015)+908.266*pow(exp(-0.735883*x-0.425837*x*x)+x/0.505017,-5.68841)))*(0.106572/(1+exp(-(x-1.71328)/1.68645))+-0.54012*TMath::Gaus(x,0.754082,1.88026)+0.452996*TMath::Gaus(x,1.49283,2.4567)+0.0943071)", - "111_v2_def": "x*x*(0.29722*exp(-x/0.318227)+0.560172*pow(1+x/0.401715,-2.04434)+0.193576*exp(-x/1.2557))", - "310_v2_def": "x*x*(0.0280321*exp(-x/0.49621)+0.328197*pow(1+x/0.0128527,-0.853155)+0.214485*exp(-x/1.29581))", - "333_v2_def": "x*x*(1.2367*exp(-x/0.629473)+-3.9919*pow(1+x/0.886275,-3.11899)+0.274776*exp(-x/1.82705))" + "111_pt": "TMath::TwoPi()*x*(111.543*exp(-(sqrt(x*x+0.139571*0.139571)-0.139571)/0.392547)+1748.52*pow(exp(-0.930464*x-0.532639*x*x)+x/0.467782,-5.54415))", + "221_pt": "(TMath::TwoPi()*x*(111.543*exp(-(sqrt(x*x+0.139571*0.139571)-0.139571)/0.392547)+1748.52*pow(exp(-0.930464*x-0.532639*x*x)+x/0.467782,-5.54415)))*(2.25035e-05*TMath::Power((exp(--2.8764*sqrt(x*x+0.547*0.547-0.139*0.139)-0.734747*(x*x+0.547*0.547-0.139*0.139))+TMath::Power(0.477784/2.25035e-05,-1./8.26791)*sqrt(x*x+0.547*0.547-0.139*0.139)/0.00603254),-8.26791)/TMath::Power((exp(--2.8764*x-0.734747*x*x)+x/0.00603254),-8.26791)+1.14358*TMath::Landau(x,2.10694,0.888101))", + "333_pt": "(TMath::TwoPi()*x*(102.279*exp(-(sqrt(x*x+0.139571*0.139571)-0.139571)/0.395141)+1545.4*pow(exp(-1.0113*x-0.476997*x*x)+x/0.47739,-5.54937)))*(0.161108/(1+exp(-(x-1.093)/0.625883))+-0.463285*TMath::Gaus(x,1.78683,1.67212)+0.486619*TMath::Gaus(x,2.62071,2.10312)+0.0149748)" }, - "5TeV_4050_wRatio_pi0down": { + "5TeV_1020_wRatio_etatest_pi0down": { "histoMtScaleFactor": { "113": 0.85, "223": 0.7, "331": 0.4 }, - "111_pt": "TMath::TwoPi()*x*(8.04609*exp(-(sqrt(x*x+0.139571*0.139571)-0.139571)/0.432276)+566.92*pow(exp(-0.727741*x-0.316795*x*x)+x/0.523032,-5.73361))", - "221_pt": "(TMath::TwoPi()*x*(8.04609*exp(-(sqrt(x*x+0.139571*0.139571)-0.139571)/0.432276)+566.92*pow(exp(-0.727741*x-0.316795*x*x)+x/0.523032,-5.73361)))*((0.298649/(1+exp(-(x-0.494749)/0.23628))+-0.255064*TMath::Gaus(x,0.170043,1.31558)+-0.024999*TMath::Gaus(x,8.22033,2.71373)+0.251236+((0.550454*exp((((0.995785*x)-sqrt((x*x)+(0.5478530000*0.5478530000)))/sqrt(1-(0.995785*0.995785)))/1.71099))+(0.0106936*(0.620714*TMath::Power(1+((x/29.189)*(x/29.189)),-(506.895)))))/(exp((((0.995785*x)-sqrt((x*x)+(0.1349770000*0.1349770000)))/sqrt(1-(0.995785*0.995785)))/1.71099)+(0.620714*TMath::Power(1+((x/29.189)*(x/29.189)),-(506.895)))))/2.)", - "333_pt": "(TMath::TwoPi()*x*(9.00063*exp(-(sqrt(x*x+0.139571*0.139571)-0.139571)/0.428379)+636.492*pow(exp(-0.659016*x-0.397367*x*x)+x/0.512428,-5.72313)))*(0.0979137/(1+exp(-(x-1.53259)/0.370136))+-0.537275*TMath::Gaus(x,0.706186,2.03543)+0.45201*TMath::Gaus(x,1.18876,2.40911)+0.104985)", - "111_v2_def": "x*x*(0.171282*exp(-x/0.353318)+1.13749*pow(1+x/0.290699,-2.02699)+0.20604*exp(-x/1.19178))", - "310_v2_def": "x*x*(-0.524086*exp(-x/0.402378)+0.891134*pow(1+x/1.15413,-3.07832)+0.0812177*exp(-x/1.22691))", - "333_v2_def": "x*x*(-2.78876*exp(-x/0.581864)+3.6669*pow(1+x/3.01301,-6.60505)+0.0436791*exp(-x/1.23285))" + "111_pt": "TMath::TwoPi()*x*(93.2981*exp(-(sqrt(x*x+0.139571*0.139571)-0.139571)/0.397978)+1354.67*pow(exp(-1.09806*x-0.414866*x*x)+x/0.487866,-5.55472))", + "221_pt": "(TMath::TwoPi()*x*(93.2981*exp(-(sqrt(x*x+0.139571*0.139571)-0.139571)/0.397978)+1354.67*pow(exp(-1.09806*x-0.414866*x*x)+x/0.487866,-5.55472)))*(2.25035e-05*TMath::Power((exp(--2.8764*sqrt(x*x+0.547*0.547-0.139*0.139)-0.734747*(x*x+0.547*0.547-0.139*0.139))+TMath::Power(0.477784/2.25035e-05,-1./8.26791)*sqrt(x*x+0.547*0.547-0.139*0.139)/0.00603254),-8.26791)/TMath::Power((exp(--2.8764*x-0.734747*x*x)+x/0.00603254),-8.26791)+1.14358*TMath::Landau(x,2.10694,0.888101))", + "333_pt": "(TMath::TwoPi()*x*(102.279*exp(-(sqrt(x*x+0.139571*0.139571)-0.139571)/0.395141)+1545.4*pow(exp(-1.0113*x-0.476997*x*x)+x/0.47739,-5.54937)))*(0.161108/(1+exp(-(x-1.093)/0.625883))+-0.463285*TMath::Gaus(x,1.78683,1.67212)+0.486619*TMath::Gaus(x,2.62071,2.10312)+0.0149748)" }, - "5TeV_4050_wRatio_ratiosdown": { + "5TeV_2030_wRatio_etatest": { "histoMtScaleFactor": { - "113": 0.68, - "223": 0.56, - "331": 0.32 + "113": 0.85, + "223": 0.7, + "331": 0.4 }, - "111_pt": "TMath::TwoPi()*x*(9.00063*exp(-(sqrt(x*x+0.139571*0.139571)-0.139571)/0.428379)+636.492*pow(exp(-0.659016*x-0.397367*x*x)+x/0.512428,-5.72313))", - "221_pt": "(TMath::TwoPi()*x*(9.00063*exp(-(sqrt(x*x+0.139571*0.139571)-0.139571)/0.428379)+636.492*pow(exp(-0.659016*x-0.397367*x*x)+x/0.512428,-5.72313)))*(((0.550454*exp((((0.995785*x)-sqrt((x*x)+(0.5478530000*0.5478530000)))/sqrt(1-(0.995785*0.995785)))/1.71099))+(0.0106936*(0.620714*TMath::Power(1+((x/29.189)*(x/29.189)),-(506.895)))))/(exp((((0.995785*x)-sqrt((x*x)+(0.1349770000*0.1349770000)))/sqrt(1-(0.995785*0.995785)))/1.71099)+(0.620714*TMath::Power(1+((x/29.189)*(x/29.189)),-(506.895)))))", - "333_pt": "(TMath::TwoPi()*x*(9.00063*exp(-(sqrt(x*x+0.139571*0.139571)-0.139571)/0.428379)+636.492*pow(exp(-0.659016*x-0.397367*x*x)+x/0.512428,-5.72313)))*((x<=0.5)*(0.3/0.5*x+0.5)*(0.0979137/(1+exp(-(x-1.53259)/0.370136))+-0.537275*TMath::Gaus(x,0.706186,2.03543)+0.45201*TMath::Gaus(x,1.18876,2.40911)+0.104985)+(x>0.5)*0.8*(0.0979137/(1+exp(-(x-1.53259)/0.370136))+-0.537275*TMath::Gaus(x,0.706186,2.03543)+0.45201*TMath::Gaus(x,1.18876,2.40911)+0.104985))", - "111_v2_def": "x*x*(0.171282*exp(-x/0.353318)+1.13749*pow(1+x/0.290699,-2.02699)+0.20604*exp(-x/1.19178))", - "310_v2_def": "x*x*(-0.524086*exp(-x/0.402378)+0.891134*pow(1+x/1.15413,-3.07832)+0.0812177*exp(-x/1.22691))", - "333_v2_def": "x*x*(-2.78876*exp(-x/0.581864)+3.6669*pow(1+x/3.01301,-6.60505)+0.0436791*exp(-x/1.23285))" + "111_pt": "TMath::TwoPi()*x*(49.8609*exp(-(sqrt(x*x+0.139571*0.139571)-0.139571)/0.407854)+1273.88*pow(exp(-0.824661*x-0.498002*x*x)+x/0.487977,-5.62108))", + "221_pt": "(TMath::TwoPi()*x*(49.8609*exp(-(sqrt(x*x+0.139571*0.139571)-0.139571)/0.407854)+1273.88*pow(exp(-0.824661*x-0.498002*x*x)+x/0.487977,-5.62108)))*(0.00038991*TMath::Power((exp(--2.8689*sqrt(x*x+0.547*0.547-0.139*0.139)-0.716403*(x*x+0.547*0.547-0.139*0.139))+TMath::Power(0.478705/0.00038991,-1./7.39763)*sqrt(x*x+0.547*0.547-0.139*0.139)/0.00709108),-7.39763)/TMath::Power((exp(--2.8689*x-0.716403*x*x)+x/0.00709108),-7.39763)+0.917471*TMath::Landau(x,2.17426,0.976011))", + "333_pt": "(TMath::TwoPi()*x*(49.8609*exp(-(sqrt(x*x+0.139571*0.139571)-0.139571)/0.407854)+1273.88*pow(exp(-0.824661*x-0.498002*x*x)+x/0.487977,-5.62108)))*(0.120134/(1+exp(-(x--0.905858)/0.386723))+-0.558917*TMath::Gaus(x,1.59687,1.87228)+0.524197*TMath::Gaus(x,2.55436,1.78153)+0.0923629)" }, - "5TeV_3040_wRatio_ratiosdown": { + "5TeV_2030_wRatio_etatest_ratiosup": { "histoMtScaleFactor": { - "113": 0.68, - "223": 0.56, - "331": 0.32 + "113": 1.02, + "223": 0.84, + "331": 0.48 }, - "111_pt": "TMath::TwoPi()*x*(24.3786*exp(-(sqrt(x*x+0.139571*0.139571)-0.139571)/0.412015)+908.266*pow(exp(-0.735883*x-0.425837*x*x)+x/0.505017,-5.68841))", - "221_pt": "(TMath::TwoPi()*x*(24.3786*exp(-(sqrt(x*x+0.139571*0.139571)-0.139571)/0.412015)+908.266*pow(exp(-0.735883*x-0.425837*x*x)+x/0.505017,-5.68841)))*(((0.550454*exp((((0.995785*x)-sqrt((x*x)+(0.5478530000*0.5478530000)))/sqrt(1-(0.995785*0.995785)))/1.71099))+(0.0106936*(0.620714*TMath::Power(1+((x/29.189)*(x/29.189)),-(506.895)))))/(exp((((0.995785*x)-sqrt((x*x)+(0.1349770000*0.1349770000)))/sqrt(1-(0.995785*0.995785)))/1.71099)+(0.620714*TMath::Power(1+((x/29.189)*(x/29.189)),-(506.895)))))", - "333_pt": "(TMath::TwoPi()*x*(24.3786*exp(-(sqrt(x*x+0.139571*0.139571)-0.139571)/0.412015)+908.266*pow(exp(-0.735883*x-0.425837*x*x)+x/0.505017,-5.68841)))*((x<=0.5)*(0.3/0.5*x+0.5)*(0.106572/(1+exp(-(x-1.71328)/1.68645))+-0.54012*TMath::Gaus(x,0.754082,1.88026)+0.452996*TMath::Gaus(x,1.49283,2.4567)+0.0943071)+(x>0.5)*0.8*(0.106572/(1+exp(-(x-1.71328)/1.68645))+-0.54012*TMath::Gaus(x,0.754082,1.88026)+0.452996*TMath::Gaus(x,1.49283,2.4567)+0.0943071))", - "111_v2_def": "x*x*(0.29722*exp(-x/0.318227)+0.560172*pow(1+x/0.401715,-2.04434)+0.193576*exp(-x/1.2557))", - "310_v2_def": "x*x*(0.0280321*exp(-x/0.49621)+0.328197*pow(1+x/0.0128527,-0.853155)+0.214485*exp(-x/1.29581))", - "333_v2_def": "x*x*(1.2367*exp(-x/0.629473)+-3.9919*pow(1+x/0.886275,-3.11899)+0.274776*exp(-x/1.82705))" + "111_pt": "TMath::TwoPi()*x*(49.8609*exp(-(sqrt(x*x+0.139571*0.139571)-0.139571)/0.407854)+1273.88*pow(exp(-0.824661*x-0.498002*x*x)+x/0.487977,-5.62108))", + "221_pt": "(TMath::TwoPi()*x*(49.8609*exp(-(sqrt(x*x+0.139571*0.139571)-0.139571)/0.407854)+1273.88*pow(exp(-0.824661*x-0.498002*x*x)+x/0.487977,-5.62108)))*((x<11.3582)*(TMath::Max(TMath::Max(0.0622931*TMath::Power((exp(--0.430138*sqrt(x*x+0.547*0.547-0.139*0.139)-0.308378*(x*x+0.547*0.547-0.139*0.139))+TMath::Power(0.497447/0.0622931,-1./7.93993)*sqrt(x*x+0.547*0.547-0.139*0.139)/1.24166),-7.93993)/TMath::Power((exp(--0.430138*x-0.308378*x*x)+x/1.24166),-7.93993)+0.909031*TMath::Landau(x,2.74364,1.23978),0.00172495*TMath::Power((exp(-1.13225*sqrt(x*x+0.547*0.547-0.139*0.139)-0.126955*(x*x+0.547*0.547-0.139*0.139))+TMath::Power(0.496991/0.00172495,-1./0.657116)*sqrt(x*x+0.547*0.547-0.139*0.139)/0.064674),-0.657116)/TMath::Power((exp(-1.13225*x-0.126955*x*x)+x/0.064674),-0.657116)+1.64346*TMath::Landau(x,2.12011,0.856277)),TMath::Max(0.000832695*TMath::Power((exp(-0.26446*sqrt(x*x+0.547*0.547-0.139*0.139)-0.0253786*(x*x+0.547*0.547-0.139*0.139))+TMath::Power(0.48268/0.000832695,-1./4.34962)*sqrt(x*x+0.547*0.547-0.139*0.139)/0.110892),-4.34962)/TMath::Power((exp(-0.26446*x-0.0253786*x*x)+x/0.110892),-4.34962)+0.846008*TMath::Landau(x,3.42622,1.68176),0.00172495*TMath::Power((exp(-1.13225*sqrt(x*x+0.547*0.547-0.139*0.139)-0.126955*(x*x+0.547*0.547-0.139*0.139))+TMath::Power(0.496991/0.00172495,-1./0.657116)*sqrt(x*x+0.547*0.547-0.139*0.139)/0.064674),-0.657116)/TMath::Power((exp(-1.13225*x-0.126955*x*x)+x/0.064674),-0.657116)+1.64346*TMath::Landau(x,2.12011,0.856277))))+(x>=11.3582)*1.08*(((0.499605*1.)+(155.836*(-0.00300369*TMath::Power(1.+((x/1.09373)*(x/1.09373)),-(0.672088)))))/(1.+(-0.00300369*TMath::Power(1.+((x/1.09373)*(x/1.09373)),-(0.672088))))))", + "333_pt": "(TMath::TwoPi()*x*(49.8609*exp(-(sqrt(x*x+0.139571*0.139571)-0.139571)/0.407854)+1273.88*pow(exp(-0.824661*x-0.498002*x*x)+x/0.487977,-5.62108)))*((x<=0.5)*(-0.3/0.5*x+1.5)*((0.120134/(1+exp(-(x--0.905858)/0.386723))+-0.558917*TMath::Gaus(x,1.59687,1.87228)+0.524197*TMath::Gaus(x,2.55436,1.78153)+0.0923629))+(x>0.5)*1.2*((0.120134/(1+exp(-(x--0.905858)/0.386723))+-0.558917*TMath::Gaus(x,1.59687,1.87228)+0.524197*TMath::Gaus(x,2.55436,1.78153)+0.0923629)))" }, - "5TeV_0510_wRatio_ratiosdown": { + "5TeV_2030_wRatio_etatest_ratiosdown": { "histoMtScaleFactor": { "113": 0.68, "223": 0.56, "331": 0.32 }, - "111_pt": "TMath::TwoPi()*x*(156.897*exp(-(sqrt(x*x+0.139571*0.139571)-0.139571)/0.390093)+1835.17*pow(exp(-1.1618*x-0.514011*x*x)+x/0.465575,-5.50332))", - "221_pt": "(TMath::TwoPi()*x*(156.897*exp(-(sqrt(x*x+0.139571*0.139571)-0.139571)/0.390093)+1835.17*pow(exp(-1.1618*x-0.514011*x*x)+x/0.465575,-5.50332)))*(((0.550454*exp((((0.995785*x)-sqrt((x*x)+(0.5478530000*0.5478530000)))/sqrt(1-(0.995785*0.995785)))/1.71099))+(0.0106936*(0.620714*TMath::Power(1+((x/29.189)*(x/29.189)),-(506.895)))))/(exp((((0.995785*x)-sqrt((x*x)+(0.1349770000*0.1349770000)))/sqrt(1-(0.995785*0.995785)))/1.71099)+(0.620714*TMath::Power(1+((x/29.189)*(x/29.189)),-(506.895)))))", - "333_pt": "(TMath::TwoPi()*x*(156.897*exp(-(sqrt(x*x+0.139571*0.139571)-0.139571)/0.390093)+1835.17*pow(exp(-1.1618*x-0.514011*x*x)+x/0.465575,-5.50332)))*((x<=0.5)*(0.3/0.5*x+0.5)*(0.1191/(1+exp(-(x- -0.316437)/0.554431))+-0.507618*TMath::Gaus(x,1.69654,1.62649)+0.494136*TMath::Gaus(x,2.56805,1.6193)+0.0789659)+(x>0.5)*0.8*(0.1191/(1+exp(-(x- -0.316437)/0.554431))+-0.507618*TMath::Gaus(x,1.69654,1.62649)+0.494136*TMath::Gaus(x,2.56805,1.6193)+0.0789659))" + "111_pt": "TMath::TwoPi()*x*(49.8609*exp(-(sqrt(x*x+0.139571*0.139571)-0.139571)/0.407854)+1273.88*pow(exp(-0.824661*x-0.498002*x*x)+x/0.487977,-5.62108))", + "221_pt": "(TMath::TwoPi()*x*(49.8609*exp(-(sqrt(x*x+0.139571*0.139571)-0.139571)/0.407854)+1273.88*pow(exp(-0.824661*x-0.498002*x*x)+x/0.487977,-5.62108)))*((x<6.000000)*(0.940000*(TMath::Min(TMath::Min(0.00779577*TMath::Power((exp(--0.684847*sqrt(x*x+0.547*0.547-0.139*0.139)-1.53786*(x*x+0.547*0.547-0.139*0.139))+TMath::Power(0.45/0.00779577,-1./60.1223)*sqrt(x*x+0.547*0.547-0.139*0.139)/0.685219),-60.1223)/TMath::Power((exp(--0.684847*x-1.53786*x*x)+x/0.685219),-60.1223)+1.63771*TMath::Landau(x,2.42852,0.955009),1.92417*TMath::Power((exp(-0.0810564*sqrt(x*x+0.547*0.547-0.139*0.139)-0.616729*(x*x+0.547*0.547-0.139*0.139))+TMath::Power(0.45/1.92417,-1./68.3973)*sqrt(x*x+0.547*0.547-0.139*0.139)/0.973421),-68.3973)/TMath::Power((exp(-0.0810564*x-0.616729*x*x)+x/0.973421),-68.3973)+1.5307*TMath::Landau(x,2.72093,1.07219)),TMath::Min(0.000514864*TMath::Power((exp(-1.38498*sqrt(x*x+0.547*0.547-0.139*0.139)-2.57506*(x*x+0.547*0.547-0.139*0.139))+TMath::Power(0.466/0.000514864,-1./7.53845)*sqrt(x*x+0.547*0.547-0.139*0.139)/1e-09),-7.53845)/TMath::Power((exp(-1.38498*x-2.57506*x*x)+x/1e-09),-7.53845)+0.22292*TMath::Landau(x,0.338702,0.226932),1.92417*TMath::Power((exp(-0.0810564*sqrt(x*x+0.547*0.547-0.139*0.139)-0.616729*(x*x+0.547*0.547-0.139*0.139))+TMath::Power(0.45/1.92417,-1./68.3973)*sqrt(x*x+0.547*0.547-0.139*0.139)/0.973421),-68.3973)/TMath::Power((exp(-0.0810564*x-0.616729*x*x)+x/0.973421),-68.3973)+1.5307*TMath::Landau(x,2.72093,1.07219)))))+(x>=6.000000)*0.426)", + "333_pt": "(TMath::TwoPi()*x*(49.8609*exp(-(sqrt(x*x+0.139571*0.139571)-0.139571)/0.407854)+1273.88*pow(exp(-0.824661*x-0.498002*x*x)+x/0.487977,-5.62108)))*((x<=0.5)*(0.3/0.5*x+0.5)*((0.120134/(1+exp(-(x--0.905858)/0.386723))+-0.558917*TMath::Gaus(x,1.59687,1.87228)+0.524197*TMath::Gaus(x,2.55436,1.78153)+0.0923629)) +(x>0.5)*0.8*((0.120134/(1+exp(-(x--0.905858)/0.386723))+-0.558917*TMath::Gaus(x,1.59687,1.87228)+0.524197*TMath::Gaus(x,2.55436,1.78153)+0.0923629)))" }, - "5TeV_0005_wRatio_ratiosdown": { + "5TeV_2030_wRatio_etatest_pi0up": { "histoMtScaleFactor": { - "113": 0.68, - "223": 0.56, - "331": 0.32 + "113": 0.85, + "223": 0.7, + "331": 0.4 }, - "111_pt": "TMath::TwoPi()*x*(219.382*exp(-(sqrt(x*x+0.139571*0.139571)-0.139571)/0.384303)+2471.6*pow(exp(-1.12373*x-0.752507*x*x)+x/0.438343,-5.45943))", - "221_pt": "(TMath::TwoPi()*x*(219.382*exp(-(sqrt(x*x+0.139571*0.139571)-0.139571)/0.384303)+2471.6*pow(exp(-1.12373*x-0.752507*x*x)+x/0.438343,-5.45943)))*(((0.550454*exp((((0.995785*x)-sqrt((x*x)+(0.5478530000*0.5478530000)))/sqrt(1-(0.995785*0.995785)))/1.71099))+(0.0106936*(0.620714*TMath::Power(1+((x/29.189)*(x/29.189)),-(506.895)))))/(exp((((0.995785*x)-sqrt((x*x)+(0.1349770000*0.1349770000)))/sqrt(1-(0.995785*0.995785)))/1.71099)+(0.620714*TMath::Power(1+((x/29.189)*(x/29.189)),-(506.895)))))", - "333_pt": "(TMath::TwoPi()*x*(219.382*exp(-(sqrt(x*x+0.139571*0.139571)-0.139571)/0.384303)+2471.6*pow(exp(-1.12373*x-0.752507*x*x)+x/0.438343,-5.45943)))*((x<=0.5)*(0.3/0.5*x+0.5)*(0.1191/(1+exp(-(x- -0.316437)/0.554431))+-0.507618*TMath::Gaus(x,1.69654,1.62649)+0.494136*TMath::Gaus(x,2.56805,1.6193)+0.0789659)+(x>0.5)*0.8*(0.1191/(1+exp(-(x- -0.316437)/0.554431))+-0.507618*TMath::Gaus(x,1.69654,1.62649)+0.494136*TMath::Gaus(x,2.56805,1.6193)+0.0789659))" + "111_pt": "TMath::TwoPi()*x*(54.9157*exp(-(sqrt(x*x+0.139571*0.139571)-0.139571)/0.404309)+1436.73*pow(exp(-0.74937*x-0.556775*x*x)+x/0.478695,-5.61584))", + "221_pt": "(TMath::TwoPi()*x*(54.9157*exp(-(sqrt(x*x+0.139571*0.139571)-0.139571)/0.404309)+1436.73*pow(exp(-0.74937*x-0.556775*x*x)+x/0.478695,-5.61584)))*(0.00038991*TMath::Power((exp(--2.8689*sqrt(x*x+0.547*0.547-0.139*0.139)-0.716403*(x*x+0.547*0.547-0.139*0.139))+TMath::Power(0.478705/0.00038991,-1./7.39763)*sqrt(x*x+0.547*0.547-0.139*0.139)/0.00709108),-7.39763)/TMath::Power((exp(--2.8689*x-0.716403*x*x)+x/0.00709108),-7.39763)+0.917471*TMath::Landau(x,2.17426,0.976011))", + "333_pt": "(TMath::TwoPi()*x*(49.8609*exp(-(sqrt(x*x+0.139571*0.139571)-0.139571)/0.407854)+1273.88*pow(exp(-0.824661*x-0.498002*x*x)+x/0.487977,-5.62108)))*(0.120134/(1+exp(-(x--0.905858)/0.386723))+-0.558917*TMath::Gaus(x,1.59687,1.87228)+0.524197*TMath::Gaus(x,2.55436,1.78153)+0.0923629)" }, - "5TeV_0005_wRatio_ratiosup": { + "5TeV_2030_wRatio_etatest_pi0down": { "histoMtScaleFactor": { - "113": 1.02, - "223": 0.84, - "331": 0.48 + "113": 0.85, + "223": 0.7, + "331": 0.4 }, - "111_pt": "TMath::TwoPi()*x*(219.382*exp(-(sqrt(x*x+0.139571*0.139571)-0.139571)/0.384303)+2471.6*pow(exp(-1.12373*x-0.752507*x*x)+x/0.438343,-5.45943))", - "221_pt": "(TMath::TwoPi()*x*(219.382*exp(-(sqrt(x*x+0.139571*0.139571)-0.139571)/0.384303)+2471.6*pow(exp(-1.12373*x-0.752507*x*x)+x/0.438343,-5.45943)))*((x<=4.303300)*(0.385689/(1+exp(-(x-0.442495)/0.303977))+-0.324645*TMath::Gaus(x,0.364119,1.01338)+-0.268261*TMath::Gaus(x,8.32791,4.74697)+0.318614)+(x>4.303300)*(0.0836242/(1+exp(-(x-6.88914)/2.15587))+0.757533*TMath::Gaus(x,1.19329,1.35263)+40382.9*TMath::Gaus(x,-92.3117,-16.5516)+0.442))", - "333_pt": "(TMath::TwoPi()*x*(219.382*exp(-(sqrt(x*x+0.139571*0.139571)-0.139571)/0.384303)+2471.6*pow(exp(-1.12373*x-0.752507*x*x)+x/0.438343,-5.45943)))*((x<=0.5)*(-0.3/0.5*x+1.5)*(0.1191/(1+exp(-(x- -0.316437)/0.554431))+-0.507618*TMath::Gaus(x,1.69654,1.62649)+0.494136*TMath::Gaus(x,2.56805,1.6193)+0.0789659)+(x>0.5)*1.2*(0.1191/(1+exp(-(x- -0.316437)/0.554431))+-0.507618*TMath::Gaus(x,1.69654,1.62649)+0.494136*TMath::Gaus(x,2.56805,1.6193)+0.0789659))" + "111_pt": "TMath::TwoPi()*x*(45.066*exp(-(sqrt(x*x+0.139571*0.139571)-0.139571)/0.41167)+1119.91*pow(exp(-0.905844*x-0.432426*x*x)+x/0.498136,-5.62645))", + "221_pt": "(TMath::TwoPi()*x*(45.066*exp(-(sqrt(x*x+0.139571*0.139571)-0.139571)/0.41167)+1119.91*pow(exp(-0.905844*x-0.432426*x*x)+x/0.498136,-5.62645)))*(0.00038991*TMath::Power((exp(--2.8689*sqrt(x*x+0.547*0.547-0.139*0.139)-0.716403*(x*x+0.547*0.547-0.139*0.139))+TMath::Power(0.478705/0.00038991,-1./7.39763)*sqrt(x*x+0.547*0.547-0.139*0.139)/0.00709108),-7.39763)/TMath::Power((exp(--2.8689*x-0.716403*x*x)+x/0.00709108),-7.39763)+0.917471*TMath::Landau(x,2.17426,0.976011))", + "333_pt": "(TMath::TwoPi()*x*(49.8609*exp(-(sqrt(x*x+0.139571*0.139571)-0.139571)/0.407854)+1273.88*pow(exp(-0.824661*x-0.498002*x*x)+x/0.487977,-5.62108)))*(0.120134/(1+exp(-(x--0.905858)/0.386723))+-0.558917*TMath::Gaus(x,1.59687,1.87228)+0.524197*TMath::Gaus(x,2.55436,1.78153)+0.0923629)" }, - "5TeV_0510_wRatio_ratiosup": { + "5TeV_3040_wRatio_etatest": { "histoMtScaleFactor": { - "113": 1.02, - "223": 0.84, - "331": 0.48 + "113": 0.85, + "223": 0.7, + "331": 0.4 }, - "111_pt": "TMath::TwoPi()*x*(156.897*exp(-(sqrt(x*x+0.139571*0.139571)-0.139571)/0.390093)+1835.17*pow(exp(-1.1618*x-0.514011*x*x)+x/0.465575,-5.50332))", - "221_pt": "(TMath::TwoPi()*x*(156.897*exp(-(sqrt(x*x+0.139571*0.139571)-0.139571)/0.390093)+1835.17*pow(exp(-1.1618*x-0.514011*x*x)+x/0.465575,-5.50332)))*((x<=4.125494)*(0.462257/(1+exp(-(x-0.489168)/0.259816))+-0.338875*TMath::Gaus(x,0.655039,0.915494)+-0.277601*TMath::Gaus(x,5.26982,2.67864)+0.291403)+(x>4.125494)*(0.197492/(1+exp(-(x-5.11825)/1.30203))+-596719*TMath::Gaus(x,0.710032,0.569486)+1.82757*TMath::Gaus(x,-2.55348,2.83425)+0.33265))", - "333_pt": "(TMath::TwoPi()*x*(156.897*exp(-(sqrt(x*x+0.139571*0.139571)-0.139571)/0.390093)+1835.17*pow(exp(-1.1618*x-0.514011*x*x)+x/0.465575,-5.50332)))*((x<=0.5)*(-0.3/0.5*x+1.5)*(0.1191/(1+exp(-(x- -0.316437)/0.554431))+-0.507618*TMath::Gaus(x,1.69654,1.62649)+0.494136*TMath::Gaus(x,2.56805,1.6193)+0.0789659)+(x>0.5)*1.2*(0.1191/(1+exp(-(x- -0.316437)/0.554431))+-0.507618*TMath::Gaus(x,1.69654,1.62649)+0.494136*TMath::Gaus(x,2.56805,1.6193)+0.0789659))" + "111_pt": "TMath::TwoPi()*x*(24.3786*exp(-(sqrt(x*x+0.139571*0.139571)-0.139571)/0.412015)+908.266*pow(exp(-0.735883*x-0.425837*x*x)+x/0.505017,-5.68841))", + "221_pt": "(TMath::TwoPi()*x*(24.3786*exp(-(sqrt(x*x+0.139571*0.139571)-0.139571)/0.412015)+908.266*pow(exp(-0.735883*x-0.425837*x*x)+x/0.505017,-5.68841)))*(0.00028072*TMath::Power((exp(- -3.25466*sqrt(x*x+0.547*0.547-0.139*0.139)-0.761446*(x*x+0.547*0.547-0.139*0.139))+TMath::Power(0.471621/0.00028072,-1./6.66634)*sqrt(x*x+0.547*0.547-0.139*0.139)/0.00480919),-6.66634)/TMath::Power((exp(- -3.25466*x-0.761446*x*x)+x/0.00480919),-6.66634)+1.12405*TMath::Landau(x,2.5931,1.14043))", + "333_pt": "(TMath::TwoPi()*x*(24.3786*exp(-(sqrt(x*x+0.139571*0.139571)-0.139571)/0.412015)+908.266*pow(exp(-0.735883*x-0.425837*x*x)+x/0.505017,-5.68841)))*(0.106572/(1+exp(-(x-1.71328)/1.68645))+-0.54012*TMath::Gaus(x,0.754082,1.88026)+0.452996*TMath::Gaus(x,1.49283,2.4567)+0.0943071)", + "111_v2_def": "x*x*(0.29722*exp(-x/0.318227)+0.560172*pow(1+x/0.401715,-2.04434)+0.193576*exp(-x/1.2557))", + "310_v2_def": "x*x*(0.0280321*exp(-x/0.49621)+0.328197*pow(1+x/0.0128527,-0.853155)+0.214485*exp(-x/1.29581))", + "333_v2_def": "x*x*(1.2367*exp(-x/0.629473)+-3.9919*pow(1+x/0.886275,-3.11899)+0.274776*exp(-x/1.82705))" }, - "5TeV_3040_wRatio_ratiosup": { + "5TeV_3040_wRatio_etatest_ratiosup": { "histoMtScaleFactor": { "113": 1.02, "223": 0.84, "331": 0.48 }, "111_pt": "TMath::TwoPi()*x*(24.3786*exp(-(sqrt(x*x+0.139571*0.139571)-0.139571)/0.412015)+908.266*pow(exp(-0.735883*x-0.425837*x*x)+x/0.505017,-5.68841))", - "221_pt": "(TMath::TwoPi()*x*(24.3786*exp(-(sqrt(x*x+0.139571*0.139571)-0.139571)/0.412015)+908.266*pow(exp(-0.735883*x-0.425837*x*x)+x/0.505017,-5.68841)))*(0.317347/(1+exp(-(x-0.475129)/0.245111))+-0.265641*TMath::Gaus(x,0.276828,1.17016)+-0.0289536*TMath::Gaus(x,5.40691,2.58911)+0.249861)", + "221_pt": "(TMath::TwoPi()*x*(24.3786*exp(-(sqrt(x*x+0.139571*0.139571)-0.139571)/0.412015)+908.266*pow(exp(-0.735883*x-0.425837*x*x)+x/0.505017,-5.68841)))*(((x<11.3582)*(TMath::Max(TMath::Max(3.62635e-06*TMath::Power((exp(-1.04848*sqrt(x*x+0.547*0.547-0.139*0.139)-0.00760898*(x*x+0.547*0.547-0.139*0.139))+TMath::Power(0.494194/3.62635e-06,-1./6.52441)*sqrt(x*x+0.547*0.547-0.139*0.139)/1.37753),-6.52441)/TMath::Power((exp(-1.04848*x-0.00760898*x*x)+x/1.37753),-6.52441)+1.85024*TMath::Landau(x,2.3343,0.982346),2.67119e-07*TMath::Power((exp(-0.504012*sqrt(x*x+0.547*0.547-0.139*0.139)-0.192368*(x*x+0.547*0.547-0.139*0.139))+TMath::Power(0.495159/2.67119e-07,-1./2.55351)*sqrt(x*x+0.547*0.547-0.139*0.139)/0.0853583),-2.55351)/TMath::Power((exp(-0.504012*x-0.192368*x*x)+x/0.0853583),-2.55351)+1.96831*TMath::Landau(x,2.25187,0.92394)),TMath::Max(0.00152416*TMath::Power((exp(-1.50417*sqrt(x*x+0.547*0.547-0.139*0.139)- -0.0524029*(x*x+0.547*0.547-0.139*0.139))+TMath::Power(0.496824/0.00152416,-1./3.48956)*sqrt(x*x+0.547*0.547-0.139*0.139)/8.34972),-3.48956)/TMath::Power((exp(-1.50417*x- -0.0524029*x*x)+x/8.34972),-3.48956)+1.90397*TMath::Landau(x,2.2369,0.884653),2.67119e-07*TMath::Power((exp(-0.504012*sqrt(x*x+0.547*0.547-0.139*0.139)-0.192368*(x*x+0.547*0.547-0.139*0.139))+TMath::Power(0.495159/2.67119e-07,-1./2.55351)*sqrt(x*x+0.547*0.547-0.139*0.139)/0.0853583),-2.55351)/TMath::Power((exp(-0.504012*x-0.192368*x*x)+x/0.0853583),-2.55351)+1.96831*TMath::Landau(x,2.25187,0.92394))))+(x>=11.3582)*1.08*(((0.499605*1.)+(155.836*(-0.00300369*TMath::Power(1.+((x/1.09373)*(x/1.09373)),-(0.672088)))))/(1.+(-0.00300369*TMath::Power(1.+((x/1.09373)*(x/1.09373)),-(0.672088)))))))", "333_pt": "(TMath::TwoPi()*x*(24.3786*exp(-(sqrt(x*x+0.139571*0.139571)-0.139571)/0.412015)+908.266*pow(exp(-0.735883*x-0.425837*x*x)+x/0.505017,-5.68841)))*((x<=0.5)*(-0.3/0.5*x+1.5)*(0.106572/(1+exp(-(x-1.71328)/1.68645))+-0.54012*TMath::Gaus(x,0.754082,1.88026)+0.452996*TMath::Gaus(x,1.49283,2.4567)+0.0943071)+(x>0.5)*1.2*(0.106572/(1+exp(-(x-1.71328)/1.68645))+-0.54012*TMath::Gaus(x,0.754082,1.88026)+0.452996*TMath::Gaus(x,1.49283,2.4567)+0.0943071))", "111_v2_def": "x*x*(0.29722*exp(-x/0.318227)+0.560172*pow(1+x/0.401715,-2.04434)+0.193576*exp(-x/1.2557))", "310_v2_def": "x*x*(0.0280321*exp(-x/0.49621)+0.328197*pow(1+x/0.0128527,-0.853155)+0.214485*exp(-x/1.29581))", "333_v2_def": "x*x*(1.2367*exp(-x/0.629473)+-3.9919*pow(1+x/0.886275,-3.11899)+0.274776*exp(-x/1.82705))" }, - "5TeV_4050_wRatio_ratiosup": { + "5TeV_3040_wRatio_etatest_ratiosdown": { "histoMtScaleFactor": { - "113": 1.02, - "223": 0.84, - "331": 0.48 + "113": 0.68, + "223": 0.56, + "331": 0.32 }, - "111_pt": "TMath::TwoPi()*x*(9.00063*exp(-(sqrt(x*x+0.139571*0.139571)-0.139571)/0.428379)+636.492*pow(exp(-0.659016*x-0.397367*x*x)+x/0.512428,-5.72313))", - "221_pt": "(TMath::TwoPi()*x*(9.00063*exp(-(sqrt(x*x+0.139571*0.139571)-0.139571)/0.428379)+636.492*pow(exp(-0.659016*x-0.397367*x*x)+x/0.512428,-5.72313)))*(0.298649/(1+exp(-(x-0.494749)/0.23628))+-0.255064*TMath::Gaus(x,0.170043,1.31558)+-0.024999*TMath::Gaus(x,8.22033,2.71373)+0.251236)", - "333_pt": "(TMath::TwoPi()*x*(9.00063*exp(-(sqrt(x*x+0.139571*0.139571)-0.139571)/0.428379)+636.492*pow(exp(-0.659016*x-0.397367*x*x)+x/0.512428,-5.72313)))*((x<=0.5)*(-0.3/0.5*x+1.5)*(0.0979137/(1+exp(-(x-1.53259)/0.370136))+-0.537275*TMath::Gaus(x,0.706186,2.03543)+0.45201*TMath::Gaus(x,1.18876,2.40911)+0.104985)+(x>0.5)*1.2*(0.0979137/(1+exp(-(x-1.53259)/0.370136))+-0.537275*TMath::Gaus(x,0.706186,2.03543)+0.45201*TMath::Gaus(x,1.18876,2.40911)+0.104985))", - "111_v2_def": "x*x*(0.171282*exp(-x/0.353318)+1.13749*pow(1+x/0.290699,-2.02699)+0.20604*exp(-x/1.19178))", - "310_v2_def": "x*x*(-0.524086*exp(-x/0.402378)+0.891134*pow(1+x/1.15413,-3.07832)+0.0812177*exp(-x/1.22691))", - "333_v2_def": "x*x*(-2.78876*exp(-x/0.581864)+3.6669*pow(1+x/3.01301,-6.60505)+0.0436791*exp(-x/1.23285))" + "111_pt": "TMath::TwoPi()*x*(24.3786*exp(-(sqrt(x*x+0.139571*0.139571)-0.139571)/0.412015)+908.266*pow(exp(-0.735883*x-0.425837*x*x)+x/0.505017,-5.68841))", + "221_pt": "(TMath::TwoPi()*x*(24.3786*exp(-(sqrt(x*x+0.139571*0.139571)-0.139571)/0.412015)+908.266*pow(exp(-0.735883*x-0.425837*x*x)+x/0.505017,-5.68841)))*(((x<6.7544)*(0.9*(TMath::Min(TMath::Min(0.000624633*TMath::Power((exp(- -0.139403*sqrt(x*x+0.547*0.547-0.139*0.139)-0.883882*(x*x+0.547*0.547-0.139*0.139))+TMath::Power(0.45/0.000624633,-1./91.7456)*sqrt(x*x+0.547*0.547-0.139*0.139)/1.27557),-91.7456)/TMath::Power((exp(- -0.139403*x-0.883882*x*x)+x/1.27557),-91.7456)+1.93275*TMath::Landau(x,2.96282,1.17967),0.806467*TMath::Power((exp(-0.123521*sqrt(x*x+0.547*0.547-0.139*0.139)-0.533763*(x*x+0.547*0.547-0.139*0.139))+TMath::Power(0.45/0.806467,-1./80.3123)*sqrt(x*x+0.547*0.547-0.139*0.139)/1.16637),-80.3123)/TMath::Power((exp(-0.123521*x-0.533763*x*x)+x/1.16637),-80.3123)+1.6774*TMath::Landau(x,3.13342,1.2489)),TMath::Min(0.0105235*TMath::Power((exp(- -0.843626*sqrt(x*x+0.547*0.547-0.139*0.139)-1.26105*(x*x+0.547*0.547-0.139*0.139))+TMath::Power(0.450001/0.0105235,-1./22.4747)*sqrt(x*x+0.547*0.547-0.139*0.139)/0.776751),-22.4747)/TMath::Power((exp(- -0.843626*x-1.26105*x*x)+x/0.776751),-22.4747)+0.774392*TMath::Landau(x,2.71895,1.26325),0.806467*TMath::Power((exp(-0.123521*sqrt(x*x+0.547*0.547-0.139*0.139)-0.533763*(x*x+0.547*0.547-0.139*0.139))+TMath::Power(0.45/0.806467,-1./80.3123)*sqrt(x*x+0.547*0.547-0.139*0.139)/1.16637),-80.3123)/TMath::Power((exp(-0.123521*x-0.533763*x*x)+x/1.16637),-80.3123)+1.6774*TMath::Landau(x,3.13342,1.2489)))))+(x>=6.7544)*0.426))", + "333_pt": "(TMath::TwoPi()*x*(24.3786*exp(-(sqrt(x*x+0.139571*0.139571)-0.139571)/0.412015)+908.266*pow(exp(-0.735883*x-0.425837*x*x)+x/0.505017,-5.68841)))*((x<=0.5)*(0.3/0.5*x+0.5)*(0.106572/(1+exp(-(x-1.71328)/1.68645))+-0.54012*TMath::Gaus(x,0.754082,1.88026)+0.452996*TMath::Gaus(x,1.49283,2.4567)+0.0943071)+(x>0.5)*0.8*(0.106572/(1+exp(-(x-1.71328)/1.68645))+-0.54012*TMath::Gaus(x,0.754082,1.88026)+0.452996*TMath::Gaus(x,1.49283,2.4567)+0.0943071))", + "111_v2_def": "x*x*(0.29722*exp(-x/0.318227)+0.560172*pow(1+x/0.401715,-2.04434)+0.193576*exp(-x/1.2557))", + "310_v2_def": "x*x*(0.0280321*exp(-x/0.49621)+0.328197*pow(1+x/0.0128527,-0.853155)+0.214485*exp(-x/1.29581))", + "333_v2_def": "x*x*(1.2367*exp(-x/0.629473)+-3.9919*pow(1+x/0.886275,-3.11899)+0.274776*exp(-x/1.82705))" }, - "5TeV_0005_wRatio_etatest": { + "5TeV_3040_wRatio_etatest_pi0up": { "histoMtScaleFactor": { "113": 0.85, "223": 0.7, "331": 0.4 }, - "111_pt": "TMath::TwoPi()*x*(219.382*exp(-(sqrt(x*x+0.139571*0.139571)-0.139571)/0.384303)+2471.6*pow(exp(-1.12373*x-0.752507*x*x)+x/0.438343,-5.45943))", - "221_pt": "(TMath::TwoPi()*x*(219.382*exp(-(sqrt(x*x+0.139571*0.139571)-0.139571)/0.384303)+2471.6*pow(exp(-1.12373*x-0.752507*x*x)+x/0.438343,-5.45943)))*((9.36242e-05*TMath::Power((exp(- -2.56458*sqrt(x*x+0.547*0.547-0.139*0.139)-0.742625*(x*x+0.547*0.547-0.139*0.139))+TMath::Power(0.457041/9.36242e-05,-1./8.15756)*sqrt(x*x+0.547*0.547-0.139*0.139)/0.0235913),-8.15756)/TMath::Power((exp(- -2.56458*x-0.742625*x*x)+x/0.0235913),-8.15756)+1.50683*TMath::Landau(x,2.1159,0.843387)))", - "333_pt": "(TMath::TwoPi()*x*(219.382*exp(-(sqrt(x*x+0.139571*0.139571)-0.139571)/0.384303)+2471.6*pow(exp(-1.12373*x-0.752507*x*x)+x/0.438343,-5.45943)))*(0.1191/(1+exp(-(x- -0.316437)/0.554431))+-0.507618*TMath::Gaus(x,1.69654,1.62649)+0.494136*TMath::Gaus(x,2.56805,1.6193)+0.0789659)" + "111_pt": "TMath::TwoPi()*x*(26.8208*exp(-(sqrt(x*x+0.139571*0.139571)-0.139571)/0.408437)+1019.42*pow(exp(-0.662498*x-0.498822*x*x)+x/0.495404,-5.68121))", + "221_pt": "(TMath::TwoPi()*x*(26.8208*exp(-(sqrt(x*x+0.139571*0.139571)-0.139571)/0.408437)+1019.42*pow(exp(-0.662498*x-0.498822*x*x)+x/0.495404,-5.68121)))*(0.00028072*TMath::Power((exp(- -3.25466*sqrt(x*x+0.547*0.547-0.139*0.139)-0.761446*(x*x+0.547*0.547-0.139*0.139))+TMath::Power(0.471621/0.00028072,-1./6.66634)*sqrt(x*x+0.547*0.547-0.139*0.139)/0.00480919),-6.66634)/TMath::Power((exp(- -3.25466*x-0.761446*x*x)+x/0.00480919),-6.66634)+1.12405*TMath::Landau(x,2.5931,1.14043))", + "333_pt": "(TMath::TwoPi()*x*(24.3786*exp(-(sqrt(x*x+0.139571*0.139571)-0.139571)/0.412015)+908.266*pow(exp(-0.735883*x-0.425837*x*x)+x/0.505017,-5.68841)))*(0.106572/(1+exp(-(x-1.71328)/1.68645))+-0.54012*TMath::Gaus(x,0.754082,1.88026)+0.452996*TMath::Gaus(x,1.49283,2.4567)+0.0943071)", + "111_v2_def": "x*x*(0.29722*exp(-x/0.318227)+0.560172*pow(1+x/0.401715,-2.04434)+0.193576*exp(-x/1.2557))", + "310_v2_def": "x*x*(0.0280321*exp(-x/0.49621)+0.328197*pow(1+x/0.0128527,-0.853155)+0.214485*exp(-x/1.29581))", + "333_v2_def": "x*x*(1.2367*exp(-x/0.629473)+-3.9919*pow(1+x/0.886275,-3.11899)+0.274776*exp(-x/1.82705))" }, - "5TeV_0005_wRatio_etatestup": { + "5TeV_3040_wRatio_etatest_pi0down": { "histoMtScaleFactor": { "113": 0.85, "223": 0.7, "331": 0.4 }, - "111_pt": "TMath::TwoPi()*x*(219.382*exp(-(sqrt(x*x+0.139571*0.139571)-0.139571)/0.384303)+2471.6*pow(exp(-1.12373*x-0.752507*x*x)+x/0.438343,-5.45943))", - "221_pt": "(TMath::TwoPi()*x*(219.382*exp(-(sqrt(x*x+0.139571*0.139571)-0.139571)/0.384303)+2471.6*pow(exp(-1.12373*x-0.752507*x*x)+x/0.438343,-5.45943)))*((((x<9.168)*(TMath::Max(TMath::Max(0.00147786*TMath::Power((exp(- -0.297384*sqrt(x*x+0.547*0.547-0.139*0.139)-0.0282388*(x*x+0.547*0.547-0.139*0.139))+TMath::Power(0.464407/0.00147786,-1./1.14468)*sqrt(x*x+0.547*0.547-0.139*0.139)/0.0102013),-1.14468)/TMath::Power((exp(- -0.297384*x-0.0282388*x*x)+x/0.0102013),-1.14468)+2.16163*TMath::Landau(x,3.97083,1.44648),0.00489879*TMath::Power((exp(- -2.36164*sqrt(x*x+0.547*0.547-0.139*0.139)-0.72334*(x*x+0.547*0.547-0.139*0.139))+TMath::Power(0.478277/0.00489879,-1./1.05253)*sqrt(x*x+0.547*0.547-0.139*0.139)/0.0139668),-1.05253)/TMath::Power((exp(- -2.36164*x-0.72334*x*x)+x/0.0139668),-1.05253)+1.73053*TMath::Landau(x,2.39399,0.879267)),TMath::Max(0.000175259*TMath::Power((exp(- -2.1325*sqrt(x*x+0.547*0.547-0.139*0.139)-0.591882*(x*x+0.547*0.547-0.139*0.139))+TMath::Power(0.482288/0.000175259,-1./15.7215)*sqrt(x*x+0.547*0.547-0.139*0.139)/0.027171),-15.7215)/TMath::Power((exp(- -2.1325*x-0.591882*x*x)+x/0.027171),-15.7215)+1.7109*TMath::Landau(x,2.36532,0.973179),0.00489879*TMath::Power((exp(- -2.36164*sqrt(x*x+0.547*0.547-0.139*0.139)-0.72334*(x*x+0.547*0.547-0.139*0.139))+TMath::Power(0.478277/0.00489879,-1./1.05253)*sqrt(x*x+0.547*0.547-0.139*0.139)/0.0139668),-1.05253)/TMath::Power((exp(- -2.36164*x-0.72334*x*x)+x/0.0139668),-1.05253)+1.73053*TMath::Landau(x,2.39399,0.879267))))+(x>=9.168)*1.08*(((0.499605*1.)+(155.836*(-0.00300369*TMath::Power(1.+((x/1.09373)*(x/1.09373)),-(0.672088)))))/(1.+(-0.00300369*TMath::Power(1.+((x/1.09373)*(x/1.09373)),-(0.672088))))))))", - "333_pt": "(TMath::TwoPi()*x*(219.382*exp(-(sqrt(x*x+0.139571*0.139571)-0.139571)/0.384303)+2471.6*pow(exp(-1.12373*x-0.752507*x*x)+x/0.438343,-5.45943)))*(0.1191/(1+exp(-(x- -0.316437)/0.554431))+-0.507618*TMath::Gaus(x,1.69654,1.62649)+0.494136*TMath::Gaus(x,2.56805,1.6193)+0.0789659)" + "111_pt": "TMath::TwoPi()*x*(22.2048*exp(-(sqrt(x*x+0.139571*0.139571)-0.139571)/0.41549)+802.356*pow(exp(-0.814916*x-0.343908*x*x)+x/0.515668,-5.69624))", + "221_pt": "(TMath::TwoPi()*x*(22.2048*exp(-(sqrt(x*x+0.139571*0.139571)-0.139571)/0.41549)+802.356*pow(exp(-0.814916*x-0.343908*x*x)+x/0.515668,-5.69624)))*(0.00028072*TMath::Power((exp(- -3.25466*sqrt(x*x+0.547*0.547-0.139*0.139)-0.761446*(x*x+0.547*0.547-0.139*0.139))+TMath::Power(0.471621/0.00028072,-1./6.66634)*sqrt(x*x+0.547*0.547-0.139*0.139)/0.00480919),-6.66634)/TMath::Power((exp(- -3.25466*x-0.761446*x*x)+x/0.00480919),-6.66634)+1.12405*TMath::Landau(x,2.5931,1.14043))", + "333_pt": "(TMath::TwoPi()*x*(24.3786*exp(-(sqrt(x*x+0.139571*0.139571)-0.139571)/0.412015)+908.266*pow(exp(-0.735883*x-0.425837*x*x)+x/0.505017,-5.68841)))*(0.106572/(1+exp(-(x-1.71328)/1.68645))+-0.54012*TMath::Gaus(x,0.754082,1.88026)+0.452996*TMath::Gaus(x,1.49283,2.4567)+0.0943071)", + "111_v2_def": "x*x*(0.29722*exp(-x/0.318227)+0.560172*pow(1+x/0.401715,-2.04434)+0.193576*exp(-x/1.2557))", + "310_v2_def": "x*x*(0.0280321*exp(-x/0.49621)+0.328197*pow(1+x/0.0128527,-0.853155)+0.214485*exp(-x/1.29581))", + "333_v2_def": "x*x*(1.2367*exp(-x/0.629473)+-3.9919*pow(1+x/0.886275,-3.11899)+0.274776*exp(-x/1.82705))" }, - "5TeV_0005_wRatio_etatestdown": { + "5TeV_4050_wRatio_etatest": { "histoMtScaleFactor": { "113": 0.85, "223": 0.7, "331": 0.4 }, - "111_pt": "TMath::TwoPi()*x*(219.382*exp(-(sqrt(x*x+0.139571*0.139571)-0.139571)/0.384303)+2471.6*pow(exp(-1.12373*x-0.752507*x*x)+x/0.438343,-5.45943))", - "221_pt": "(TMath::TwoPi()*x*(219.382*exp(-(sqrt(x*x+0.139571*0.139571)-0.139571)/0.384303)+2471.6*pow(exp(-1.12373*x-0.752507*x*x)+x/0.438343,-5.45943)))*((((x<11.6581)*(TMath::Min(TMath::Min(0.00302888*TMath::Power((exp(-0.246982*sqrt(x*x+0.547*0.547-0.139*0.139)-0.204843*(x*x+0.547*0.547-0.139*0.139))+TMath::Power(0.485848/0.00302888,-1./335.069)*sqrt(x*x+0.547*0.547-0.139*0.139)/2.46929),-335.069)/TMath::Power((exp(-0.246982*x-0.204843*x*x)+x/2.46929),-335.069)+2.62546*TMath::Landau(x,3.61147,1.38592),0.926*(9.36242e-05*TMath::Power((exp(- -2.56458*sqrt(x*x+0.547*0.547-0.139*0.139)-0.742625*(x*x+0.547*0.547-0.139*0.139))+TMath::Power(0.457041/9.36242e-05,-1./8.15756)*sqrt(x*x+0.547*0.547-0.139*0.139)/0.0235913),-8.15756)/TMath::Power((exp(- -2.56458*x-0.742625*x*x)+x/0.0235913),-8.15756)+1.50683*TMath::Landau(x,2.1159,0.843387))),TMath::Min(0.00624935*TMath::Power((exp(- -2.56471*sqrt(x*x+0.547*0.547-0.139*0.139)-2.49586*(x*x+0.547*0.547-0.139*0.139))+TMath::Power(0.45/0.00624935,-1./44.8766)*sqrt(x*x+0.547*0.547-0.139*0.139)/0.202909),-44.8766)/TMath::Power((exp(- -2.56471*x-2.49586*x*x)+x/0.202909),-44.8766)+1.58602*TMath::Landau(x,2.23166,0.861224),0.926*(9.36242e-05*TMath::Power((exp(- -2.56458*sqrt(x*x+0.547*0.547-0.139*0.139)-0.742625*(x*x+0.547*0.547-0.139*0.139))+TMath::Power(0.457041/9.36242e-05,-1./8.15756)*sqrt(x*x+0.547*0.547-0.139*0.139)/0.0235913),-8.15756)/TMath::Power((exp(- -2.56458*x-0.742625*x*x)+x/0.0235913),-8.15756)+1.50683*TMath::Landau(x,2.1159,0.843387)))))+(x>=11.6581)*0.426)))", - "333_pt": "(TMath::TwoPi()*x*(219.382*exp(-(sqrt(x*x+0.139571*0.139571)-0.139571)/0.384303)+2471.6*pow(exp(-1.12373*x-0.752507*x*x)+x/0.438343,-5.45943)))*(0.1191/(1+exp(-(x- -0.316437)/0.554431))+-0.507618*TMath::Gaus(x,1.69654,1.62649)+0.494136*TMath::Gaus(x,2.56805,1.6193)+0.0789659)" + "111_pt": "TMath::TwoPi()*x*(9.00063*exp(-(sqrt(x*x+0.139571*0.139571)-0.139571)/0.428379)+636.492*pow(exp(-0.659016*x-0.397367*x*x)+x/0.512428,-5.72313))", + "221_pt": "(TMath::TwoPi()*x*(9.00063*exp(-(sqrt(x*x+0.139571*0.139571)-0.139571)/0.428379)+636.492*pow(exp(-0.659016*x-0.397367*x*x)+x/0.512428,-5.72313)))*(0.00028072*TMath::Power((exp(- -3.25466*sqrt(x*x+0.547*0.547-0.139*0.139)-0.761446*(x*x+0.547*0.547-0.139*0.139))+TMath::Power(0.471621/0.00028072,-1./6.66634)*sqrt(x*x+0.547*0.547-0.139*0.139)/0.00480919),-6.66634)/TMath::Power((exp(- -3.25466*x-0.761446*x*x)+x/0.00480919),-6.66634)+1.12405*TMath::Landau(x,2.5931,1.14043))", + "333_pt": "(TMath::TwoPi()*x*(9.00063*exp(-(sqrt(x*x+0.139571*0.139571)-0.139571)/0.428379)+636.492*pow(exp(-0.659016*x-0.397367*x*x)+x/0.512428,-5.72313)))*(0.0979137/(1+exp(-(x-1.53259)/0.370136))+-0.537275*TMath::Gaus(x,0.706186,2.03543)+0.45201*TMath::Gaus(x,1.18876,2.40911)+0.104985)", + "111_v2_def": "x*x*(0.171282*exp(-x/0.353318)+1.13749*pow(1+x/0.290699,-2.02699)+0.20604*exp(-x/1.19178))", + "310_v2_def": "x*x*(-0.524086*exp(-x/0.402378)+0.891134*pow(1+x/1.15413,-3.07832)+0.0812177*exp(-x/1.22691))", + "333_v2_def": "x*x*(-2.78876*exp(-x/0.581864)+3.6669*pow(1+x/3.01301,-6.60505)+0.0436791*exp(-x/1.23285))" }, - "5TeV_0510_wRatio_etatest": { + "5TeV_4050_wRatio_etatest_ratiosup": { + "histoMtScaleFactor": { + "113": 1.02, + "223": 0.84, + "331": 0.48 + }, + "111_pt": "TMath::TwoPi()*x*(9.00063*exp(-(sqrt(x*x+0.139571*0.139571)-0.139571)/0.428379)+636.492*pow(exp(-0.659016*x-0.397367*x*x)+x/0.512428,-5.72313))", + "221_pt": "(TMath::TwoPi()*x*(9.00063*exp(-(sqrt(x*x+0.139571*0.139571)-0.139571)/0.428379)+636.492*pow(exp(-0.659016*x-0.397367*x*x)+x/0.512428,-5.72313)))*(((x<11.3582)*(TMath::Max(TMath::Max(3.62635e-06*TMath::Power((exp(-1.04848*sqrt(x*x+0.547*0.547-0.139*0.139)-0.00760898*(x*x+0.547*0.547-0.139*0.139))+TMath::Power(0.494194/3.62635e-06,-1./6.52441)*sqrt(x*x+0.547*0.547-0.139*0.139)/1.37753),-6.52441)/TMath::Power((exp(-1.04848*x-0.00760898*x*x)+x/1.37753),-6.52441)+1.85024*TMath::Landau(x,2.3343,0.982346),2.67119e-07*TMath::Power((exp(-0.504012*sqrt(x*x+0.547*0.547-0.139*0.139)-0.192368*(x*x+0.547*0.547-0.139*0.139))+TMath::Power(0.495159/2.67119e-07,-1./2.55351)*sqrt(x*x+0.547*0.547-0.139*0.139)/0.0853583),-2.55351)/TMath::Power((exp(-0.504012*x-0.192368*x*x)+x/0.0853583),-2.55351)+1.96831*TMath::Landau(x,2.25187,0.92394)),TMath::Max(0.00152416*TMath::Power((exp(-1.50417*sqrt(x*x+0.547*0.547-0.139*0.139)- -0.0524029*(x*x+0.547*0.547-0.139*0.139))+TMath::Power(0.496824/0.00152416,-1./3.48956)*sqrt(x*x+0.547*0.547-0.139*0.139)/8.34972),-3.48956)/TMath::Power((exp(-1.50417*x- -0.0524029*x*x)+x/8.34972),-3.48956)+1.90397*TMath::Landau(x,2.2369,0.884653),2.67119e-07*TMath::Power((exp(-0.504012*sqrt(x*x+0.547*0.547-0.139*0.139)-0.192368*(x*x+0.547*0.547-0.139*0.139))+TMath::Power(0.495159/2.67119e-07,-1./2.55351)*sqrt(x*x+0.547*0.547-0.139*0.139)/0.0853583),-2.55351)/TMath::Power((exp(-0.504012*x-0.192368*x*x)+x/0.0853583),-2.55351)+1.96831*TMath::Landau(x,2.25187,0.92394))))+(x>=11.3582)*1.08*(((0.499605*1.)+(155.836*(-0.00300369*TMath::Power(1.+((x/1.09373)*(x/1.09373)),-(0.672088)))))/(1.+(-0.00300369*TMath::Power(1.+((x/1.09373)*(x/1.09373)),-(0.672088)))))))", + "333_pt": "(TMath::TwoPi()*x*(9.00063*exp(-(sqrt(x*x+0.139571*0.139571)-0.139571)/0.428379)+636.492*pow(exp(-0.659016*x-0.397367*x*x)+x/0.512428,-5.72313)))*((x<=0.5)*(-0.3/0.5*x+1.5)*(0.0979137/(1+exp(-(x-1.53259)/0.370136))+-0.537275*TMath::Gaus(x,0.706186,2.03543)+0.45201*TMath::Gaus(x,1.18876,2.40911)+0.104985)+(x>0.5)*1.2*(0.0979137/(1+exp(-(x-1.53259)/0.370136))+-0.537275*TMath::Gaus(x,0.706186,2.03543)+0.45201*TMath::Gaus(x,1.18876,2.40911)+0.104985))", + "111_v2_def": "x*x*(0.171282*exp(-x/0.353318)+1.13749*pow(1+x/0.290699,-2.02699)+0.20604*exp(-x/1.19178))", + "310_v2_def": "x*x*(-0.524086*exp(-x/0.402378)+0.891134*pow(1+x/1.15413,-3.07832)+0.0812177*exp(-x/1.22691))", + "333_v2_def": "x*x*(-2.78876*exp(-x/0.581864)+3.6669*pow(1+x/3.01301,-6.60505)+0.0436791*exp(-x/1.23285))" + }, + "5TeV_4050_wRatio_etatest_ratiosdown": { + "histoMtScaleFactor": { + "113": 0.68, + "223": 0.56, + "331": 0.32 + }, + "111_pt": "TMath::TwoPi()*x*(9.00063*exp(-(sqrt(x*x+0.139571*0.139571)-0.139571)/0.428379)+636.492*pow(exp(-0.659016*x-0.397367*x*x)+x/0.512428,-5.72313))", + "221_pt": "(TMath::TwoPi()*x*(9.00063*exp(-(sqrt(x*x+0.139571*0.139571)-0.139571)/0.428379)+636.492*pow(exp(-0.659016*x-0.397367*x*x)+x/0.512428,-5.72313)))*(((x<6.7544)*(0.9*(TMath::Min(TMath::Min(0.000624633*TMath::Power((exp(- -0.139403*sqrt(x*x+0.547*0.547-0.139*0.139)-0.883882*(x*x+0.547*0.547-0.139*0.139))+TMath::Power(0.45/0.000624633,-1./91.7456)*sqrt(x*x+0.547*0.547-0.139*0.139)/1.27557),-91.7456)/TMath::Power((exp(- -0.139403*x-0.883882*x*x)+x/1.27557),-91.7456)+1.93275*TMath::Landau(x,2.96282,1.17967),0.806467*TMath::Power((exp(-0.123521*sqrt(x*x+0.547*0.547-0.139*0.139)-0.533763*(x*x+0.547*0.547-0.139*0.139))+TMath::Power(0.45/0.806467,-1./80.3123)*sqrt(x*x+0.547*0.547-0.139*0.139)/1.16637),-80.3123)/TMath::Power((exp(-0.123521*x-0.533763*x*x)+x/1.16637),-80.3123)+1.6774*TMath::Landau(x,3.13342,1.2489)),TMath::Min(0.0105235*TMath::Power((exp(- -0.843626*sqrt(x*x+0.547*0.547-0.139*0.139)-1.26105*(x*x+0.547*0.547-0.139*0.139))+TMath::Power(0.450001/0.0105235,-1./22.4747)*sqrt(x*x+0.547*0.547-0.139*0.139)/0.776751),-22.4747)/TMath::Power((exp(- -0.843626*x-1.26105*x*x)+x/0.776751),-22.4747)+0.774392*TMath::Landau(x,2.71895,1.26325),0.806467*TMath::Power((exp(-0.123521*sqrt(x*x+0.547*0.547-0.139*0.139)-0.533763*(x*x+0.547*0.547-0.139*0.139))+TMath::Power(0.45/0.806467,-1./80.3123)*sqrt(x*x+0.547*0.547-0.139*0.139)/1.16637),-80.3123)/TMath::Power((exp(-0.123521*x-0.533763*x*x)+x/1.16637),-80.3123)+1.6774*TMath::Landau(x,3.13342,1.2489)))))+(x>=6.7544)*0.426))", + "333_pt": "(TMath::TwoPi()*x*(9.00063*exp(-(sqrt(x*x+0.139571*0.139571)-0.139571)/0.428379)+636.492*pow(exp(-0.659016*x-0.397367*x*x)+x/0.512428,-5.72313)))*((x<=0.5)*(0.3/0.5*x+0.5)*(0.0979137/(1+exp(-(x-1.53259)/0.370136))+-0.537275*TMath::Gaus(x,0.706186,2.03543)+0.45201*TMath::Gaus(x,1.18876,2.40911)+0.104985)+(x>0.5)*0.8*(0.0979137/(1+exp(-(x-1.53259)/0.370136))+-0.537275*TMath::Gaus(x,0.706186,2.03543)+0.45201*TMath::Gaus(x,1.18876,2.40911)+0.104985))", + "111_v2_def": "x*x*(0.171282*exp(-x/0.353318)+1.13749*pow(1+x/0.290699,-2.02699)+0.20604*exp(-x/1.19178))", + "310_v2_def": "x*x*(-0.524086*exp(-x/0.402378)+0.891134*pow(1+x/1.15413,-3.07832)+0.0812177*exp(-x/1.22691))", + "333_v2_def": "x*x*(-2.78876*exp(-x/0.581864)+3.6669*pow(1+x/3.01301,-6.60505)+0.0436791*exp(-x/1.23285))" + }, + "5TeV_4050_wRatio_etatest_pi0up": { "histoMtScaleFactor": { "113": 0.85, "223": 0.7, "331": 0.4 }, - "111_pt": "TMath::TwoPi()*x*(156.897*exp(-(sqrt(x*x+0.139571*0.139571)-0.139571)/0.390093)+1835.17*pow(exp(-1.1618*x-0.514011*x*x)+x/0.465575,-5.50332))", - "221_pt": "(TMath::TwoPi()*x*(156.897*exp(-(sqrt(x*x+0.139571*0.139571)-0.139571)/0.390093)+1835.17*pow(exp(-1.1618*x-0.514011*x*x)+x/0.465575,-5.50332)))*((0.000246618*TMath::Power((exp(- -3.44417*sqrt(x*x+0.547*0.547-0.139*0.139)-0.952884*(x*x+0.547*0.547-0.139*0.139))+TMath::Power(0.476466/0.000246618,-1./8.8133)*sqrt(x*x+0.547*0.547-0.139*0.139)/0.0060628),-8.8133)/TMath::Power((exp(- -3.44417*x-0.952884*x*x)+x/0.0060628),-8.8133)+1.09231*TMath::Landau(x,2.04517,0.864605)))", - "333_pt": "(TMath::TwoPi()*x*(156.897*exp(-(sqrt(x*x+0.139571*0.139571)-0.139571)/0.390093)+1835.17*pow(exp(-1.1618*x-0.514011*x*x)+x/0.465575,-5.50332)))*(0.1191/(1+exp(-(x- -0.316437)/0.554431))+-0.507618*TMath::Gaus(x,1.69654,1.62649)+0.494136*TMath::Gaus(x,2.56805,1.6193)+0.0789659)" + "111_pt": "TMath::TwoPi()*x*(10.1537*exp(-(sqrt(x*x+0.139571*0.139571)-0.139571)/0.423934)+708.793*pow(exp(-0.595237*x-0.468542*x*x)+x/0.502946,-5.71377))", + "221_pt": "(TMath::TwoPi()*x*(10.1537*exp(-(sqrt(x*x+0.139571*0.139571)-0.139571)/0.423934)+708.793*pow(exp(-0.595237*x-0.468542*x*x)+x/0.502946,-5.71377)))*(0.00028072*TMath::Power((exp(- -3.25466*sqrt(x*x+0.547*0.547-0.139*0.139)-0.761446*(x*x+0.547*0.547-0.139*0.139))+TMath::Power(0.471621/0.00028072,-1./6.66634)*sqrt(x*x+0.547*0.547-0.139*0.139)/0.00480919),-6.66634)/TMath::Power((exp(- -3.25466*x-0.761446*x*x)+x/0.00480919),-6.66634)+1.12405*TMath::Landau(x,2.5931,1.14043))", + "333_pt": "(TMath::TwoPi()*x*(9.00063*exp(-(sqrt(x*x+0.139571*0.139571)-0.139571)/0.428379)+636.492*pow(exp(-0.659016*x-0.397367*x*x)+x/0.512428,-5.72313)))*(0.0979137/(1+exp(-(x-1.53259)/0.370136))+-0.537275*TMath::Gaus(x,0.706186,2.03543)+0.45201*TMath::Gaus(x,1.18876,2.40911)+0.104985)", + "111_v2_def": "x*x*(0.171282*exp(-x/0.353318)+1.13749*pow(1+x/0.290699,-2.02699)+0.20604*exp(-x/1.19178))", + "310_v2_def": "x*x*(-0.524086*exp(-x/0.402378)+0.891134*pow(1+x/1.15413,-3.07832)+0.0812177*exp(-x/1.22691))", + "333_v2_def": "x*x*(-2.78876*exp(-x/0.581864)+3.6669*pow(1+x/3.01301,-6.60505)+0.0436791*exp(-x/1.23285))" }, - "5TeV_0510_wRatio_etatestup": { + "5TeV_4050_wRatio_etatest_pi0down": { "histoMtScaleFactor": { "113": 0.85, "223": 0.7, "331": 0.4 }, - "111_pt": "TMath::TwoPi()*x*(156.897*exp(-(sqrt(x*x+0.139571*0.139571)-0.139571)/0.390093)+1835.17*pow(exp(-1.1618*x-0.514011*x*x)+x/0.465575,-5.50332))", - "221_pt": "(TMath::TwoPi()*x*(156.897*exp(-(sqrt(x*x+0.139571*0.139571)-0.139571)/0.390093)+1835.17*pow(exp(-1.1618*x-0.514011*x*x)+x/0.465575,-5.50332)))*((((x<10.278)*(TMath::Max(TMath::Max(0.000295533*TMath::Power((exp(- -1.60043*sqrt(x*x+0.547*0.547-0.139*0.139)-0.655985*(x*x+0.547*0.547-0.139*0.139))+TMath::Power(0.500931/0.000295533,-1./16.3545)*sqrt(x*x+0.547*0.547-0.139*0.139)/0.130844),-16.3545)/TMath::Power((exp(- -1.60043*x-0.655985*x*x)+x/0.130844),-16.3545)+1.5704*TMath::Landau(x,2.17776,0.921819),0.00540987*TMath::Power((exp(-0.202531*sqrt(x*x+0.547*0.547-0.139*0.139)-0.404918*(x*x+0.547*0.547-0.139*0.139))+TMath::Power(0.496965/0.00540987,-1./0.457227)*sqrt(x*x+0.547*0.547-0.139*0.139)/0.010344),-0.457227)/TMath::Power((exp(-0.202531*x-0.404918*x*x)+x/0.010344),-0.457227)+1.48331*TMath::Landau(x,2.17198,0.823192)),TMath::Max(3.85365e-05*TMath::Power((exp(- -0.50908*sqrt(x*x+0.547*0.547-0.139*0.139)-0.0438035*(x*x+0.547*0.547-0.139*0.139))+TMath::Power(0.463429/3.85365e-05,-1./6.0698)*sqrt(x*x+0.547*0.547-0.139*0.139)/0.0472676),-6.0698)/TMath::Power((exp(- -0.50908*x-0.0438035*x*x)+x/0.0472676),-6.0698)+2.34475*TMath::Landau(x,3.86817,1.59145),0.00540987*TMath::Power((exp(-0.202531*sqrt(x*x+0.547*0.547-0.139*0.139)-0.404918*(x*x+0.547*0.547-0.139*0.139))+TMath::Power(0.496965/0.00540987,-1./0.457227)*sqrt(x*x+0.547*0.547-0.139*0.139)/0.010344),-0.457227)/TMath::Power((exp(-0.202531*x-0.404918*x*x)+x/0.010344),-0.457227)+1.48331*TMath::Landau(x,2.17198,0.823192))))+(x>=10.278)*1.08*(((0.499605*1.)+(155.836*(-0.00300369*TMath::Power(1.+((x/1.09373)*(x/1.09373)),-(0.672088)))))/(1.+(-0.00300369*TMath::Power(1.+((x/1.09373)*(x/1.09373)),-(0.672088))))))))", - "333_pt": "(TMath::TwoPi()*x*(156.897*exp(-(sqrt(x*x+0.139571*0.139571)-0.139571)/0.390093)+1835.17*pow(exp(-1.1618*x-0.514011*x*x)+x/0.465575,-5.50332)))*(0.1191/(1+exp(-(x- -0.316437)/0.554431))+-0.507618*TMath::Gaus(x,1.69654,1.62649)+0.494136*TMath::Gaus(x,2.56805,1.6193)+0.0789659)" + "111_pt": "TMath::TwoPi()*x*(8.04609*exp(-(sqrt(x*x+0.139571*0.139571)-0.139571)/0.432276)+566.92*pow(exp(-0.727741*x-0.316795*x*x)+x/0.523032,-5.73361))", + "221_pt": "(TMath::TwoPi()*x*(8.04609*exp(-(sqrt(x*x+0.139571*0.139571)-0.139571)/0.432276)+566.92*pow(exp(-0.727741*x-0.316795*x*x)+x/0.523032,-5.73361)))*(0.00028072*TMath::Power((exp(- -3.25466*sqrt(x*x+0.547*0.547-0.139*0.139)-0.761446*(x*x+0.547*0.547-0.139*0.139))+TMath::Power(0.471621/0.00028072,-1./6.66634)*sqrt(x*x+0.547*0.547-0.139*0.139)/0.00480919),-6.66634)/TMath::Power((exp(- -3.25466*x-0.761446*x*x)+x/0.00480919),-6.66634)+1.12405*TMath::Landau(x,2.5931,1.14043))", + "333_pt": "(TMath::TwoPi()*x*(9.00063*exp(-(sqrt(x*x+0.139571*0.139571)-0.139571)/0.428379)+636.492*pow(exp(-0.659016*x-0.397367*x*x)+x/0.512428,-5.72313)))*(0.0979137/(1+exp(-(x-1.53259)/0.370136))+-0.537275*TMath::Gaus(x,0.706186,2.03543)+0.45201*TMath::Gaus(x,1.18876,2.40911)+0.104985)", + "111_v2_def": "x*x*(0.171282*exp(-x/0.353318)+1.13749*pow(1+x/0.290699,-2.02699)+0.20604*exp(-x/1.19178))", + "310_v2_def": "x*x*(-0.524086*exp(-x/0.402378)+0.891134*pow(1+x/1.15413,-3.07832)+0.0812177*exp(-x/1.22691))", + "333_v2_def": "x*x*(-2.78876*exp(-x/0.581864)+3.6669*pow(1+x/3.01301,-6.60505)+0.0436791*exp(-x/1.23285))" }, "5TeV_0005_wRatio_etatestcenter_pp13": { "histoMtScaleFactor": { @@ -309,26 +359,6 @@ "221_pt": "(TMath::TwoPi()*x*(156.897*exp(-(sqrt(x*x+0.139571*0.139571)-0.139571)/0.390093)+1835.17*pow(exp(-1.1618*x-0.514011*x*x)+x/0.465575,-5.50332)))*((0.000946307*TMath::Power((exp(- -0.678673*sqrt(x*x+0.547*0.547-0.139*0.139)-1.46197*(x*x+0.547*0.547-0.139*0.139))+TMath::Power(0.475252/0.000946307,-1./42.0453)*sqrt(x*x+0.547*0.547-0.139*0.139)/0.718978),-42.0453)/TMath::Power((exp(- -0.678673*x-1.46197*x*x)+x/0.718978),-42.0453)+1.5622*TMath::Landau(x,2.61642,1.08512)))", "333_pt": "(TMath::TwoPi()*x*(156.897*exp(-(sqrt(x*x+0.139571*0.139571)-0.139571)/0.390093)+1835.17*pow(exp(-1.1618*x-0.514011*x*x)+x/0.465575,-5.50332)))*(0.1191/(1+exp(-(x- -0.316437)/0.554431))+-0.507618*TMath::Gaus(x,1.69654,1.62649)+0.494136*TMath::Gaus(x,2.56805,1.6193)+0.0789659)" }, - "5TeV_0005_wRatio_etatestpi0down": { - "histoMtScaleFactor": { - "113": 0.85, - "223": 0.7, - "331": 0.4 - }, - "111_pt": "TMath::TwoPi()*x*(202.506*exp(-(sqrt(x*x+0.139571*0.139571)-0.139571)/0.386428)+2172.76*pow(exp(-1.20019*x-0.719277*x*x)+x/0.447319,-5.46279))", - "221_pt": "(TMath::TwoPi()*x*(202.506*exp(-(sqrt(x*x+0.139571*0.139571)-0.139571)/0.386428)+2172.76*pow(exp(-1.20019*x-0.719277*x*x)+x/0.447319,-5.46279)))*((9.36242e-05*TMath::Power((exp(- -2.56458*sqrt(x*x+0.547*0.547-0.139*0.139)-0.742625*(x*x+0.547*0.547-0.139*0.139))+TMath::Power(0.457041/9.36242e-05,-1./8.15756)*sqrt(x*x+0.547*0.547-0.139*0.139)/0.0235913),-8.15756)/TMath::Power((exp(- -2.56458*x-0.742625*x*x)+x/0.0235913),-8.15756)+1.50683*TMath::Landau(x,2.1159,0.843387)))", - "333_pt": "(TMath::TwoPi()*x*(219.382*exp(-(sqrt(x*x+0.139571*0.139571)-0.139571)/0.384303)+2471.6*pow(exp(-1.12373*x-0.752507*x*x)+x/0.438343,-5.45943)))*(0.1191/(1+exp(-(x- -0.316437)/0.554431))+-0.507618*TMath::Gaus(x,1.69654,1.62649)+0.494136*TMath::Gaus(x,2.56805,1.6193)+0.0789659)" - }, - "5TeV_0005_wRatio_etatestpi0up": { - "histoMtScaleFactor": { - "113": 0.85, - "223": 0.7, - "331": 0.4 - }, - "111_pt": "TMath::TwoPi()*x*(236.555*exp(-(sqrt(x*x+0.139571*0.139571)-0.139571)/0.382365)+2787.27*pow(exp(-1.05343*x-0.780376*x*x)+x/0.43017,-5.45613))", - "221_pt": "(TMath::TwoPi()*x*(236.555*exp(-(sqrt(x*x+0.139571*0.139571)-0.139571)/0.382365)+2787.27*pow(exp(-1.05343*x-0.780376*x*x)+x/0.43017,-5.45613)))*((9.36242e-05*TMath::Power((exp(- -2.56458*sqrt(x*x+0.547*0.547-0.139*0.139)-0.742625*(x*x+0.547*0.547-0.139*0.139))+TMath::Power(0.457041/9.36242e-05,-1./8.15756)*sqrt(x*x+0.547*0.547-0.139*0.139)/0.0235913),-8.15756)/TMath::Power((exp(- -2.56458*x-0.742625*x*x)+x/0.0235913),-8.15756)+1.50683*TMath::Landau(x,2.1159,0.843387)))", - "333_pt": "(TMath::TwoPi()*x*(219.382*exp(-(sqrt(x*x+0.139571*0.139571)-0.139571)/0.384303)+2471.6*pow(exp(-1.12373*x-0.752507*x*x)+x/0.438343,-5.45943)))*(0.1191/(1+exp(-(x- -0.316437)/0.554431))+-0.507618*TMath::Gaus(x,1.69654,1.62649)+0.494136*TMath::Gaus(x,2.56805,1.6193)+0.0789659)" - }, "5TeV_0005_wRatio_etatestpi0up_pp13": { "histoMtScaleFactor": { "113": 0.85, @@ -349,26 +379,6 @@ "221_pt": "(TMath::TwoPi()*x*(202.506*exp(-(sqrt(x*x+0.139571*0.139571)-0.139571)/0.386428)+2172.76*pow(exp(-1.20019*x-0.719277*x*x)+x/0.447319,-5.46279)))*((0.000376932*TMath::Power((exp(-0.821512*sqrt(x*x+0.547*0.547-0.139*0.139)-0.143837*(x*x+0.547*0.547-0.139*0.139))+TMath::Power(0.4615/0.000376932,-1./13.0537)*sqrt(x*x+0.547*0.547-0.139*0.139)/4.58538),-13.0537)/TMath::Power((exp(-0.821512*x-0.143837*x*x)+x/4.58538),-13.0537)+1.65536*TMath::Landau(x,2.12278,0.816391)))", "333_pt": "(TMath::TwoPi()*x*(219.382*exp(-(sqrt(x*x+0.139571*0.139571)-0.139571)/0.384303)+2471.6*pow(exp(-1.12373*x-0.752507*x*x)+x/0.438343,-5.45943)))*(0.1191/(1+exp(-(x- -0.316437)/0.554431))+-0.507618*TMath::Gaus(x,1.69654,1.62649)+0.494136*TMath::Gaus(x,2.56805,1.6193)+0.0789659)" }, - "5TeV_0510_wRatio_etatestpi0down": { - "histoMtScaleFactor": { - "113": 0.85, - "223": 0.7, - "331": 0.4 - }, - "111_pt": "TMath::TwoPi()*x*(143.633*exp(-(sqrt(x*x+0.139571*0.139571)-0.139571)/0.392747)+1585.64*pow(exp(-1.25879*x-0.453071*x*x)+x/0.476927,-5.50804))", - "221_pt": "(TMath::TwoPi()*x*(143.633*exp(-(sqrt(x*x+0.139571*0.139571)-0.139571)/0.392747)+1585.64*pow(exp(-1.25879*x-0.453071*x*x)+x/0.476927,-5.50804)))*((0.000246618*TMath::Power((exp(- -3.44417*sqrt(x*x+0.547*0.547-0.139*0.139)-0.952884*(x*x+0.547*0.547-0.139*0.139))+TMath::Power(0.476466/0.000246618,-1./8.8133)*sqrt(x*x+0.547*0.547-0.139*0.139)/0.0060628),-8.8133)/TMath::Power((exp(- -3.44417*x-0.952884*x*x)+x/0.0060628),-8.8133)+1.09231*TMath::Landau(x,2.04517,0.864605)))", - "333_pt": "(TMath::TwoPi()*x*(156.897*exp(-(sqrt(x*x+0.139571*0.139571)-0.139571)/0.390093)+1835.17*pow(exp(-1.1618*x-0.514011*x*x)+x/0.465575,-5.50332)))*(0.1191/(1+exp(-(x- -0.316437)/0.554431))+-0.507618*TMath::Gaus(x,1.69654,1.62649)+0.494136*TMath::Gaus(x,2.56805,1.6193)+0.0789659)" - }, - "5TeV_0510_wRatio_etatestpi0up": { - "histoMtScaleFactor": { - "113": 0.85, - "223": 0.7, - "331": 0.4 - }, - "111_pt": "TMath::TwoPi()*x*(170.514*exp(-(sqrt(x*x+0.139571*0.139571)-0.139571)/0.38767)+2102.92*pow(exp(-1.0722*x-0.567406*x*x)+x/0.45525,-5.49867))", - "221_pt": "(TMath::TwoPi()*x*(170.514*exp(-(sqrt(x*x+0.139571*0.139571)-0.139571)/0.38767)+2102.92*pow(exp(-1.0722*x-0.567406*x*x)+x/0.45525,-5.49867)))*((0.000246618*TMath::Power((exp(- -3.44417*sqrt(x*x+0.547*0.547-0.139*0.139)-0.952884*(x*x+0.547*0.547-0.139*0.139))+TMath::Power(0.476466/0.000246618,-1./8.8133)*sqrt(x*x+0.547*0.547-0.139*0.139)/0.0060628),-8.8133)/TMath::Power((exp(- -3.44417*x-0.952884*x*x)+x/0.0060628),-8.8133)+1.09231*TMath::Landau(x,2.04517,0.864605)))", - "333_pt": "(TMath::TwoPi()*x*(156.897*exp(-(sqrt(x*x+0.139571*0.139571)-0.139571)/0.390093)+1835.17*pow(exp(-1.1618*x-0.514011*x*x)+x/0.465575,-5.50332)))*(0.1191/(1+exp(-(x- -0.316437)/0.554431))+-0.507618*TMath::Gaus(x,1.69654,1.62649)+0.494136*TMath::Gaus(x,2.56805,1.6193)+0.0789659)" - }, "5TeV_0510_wRatio_etatestpi0up_pp13": { "histoMtScaleFactor": { "113": 0.85, @@ -389,16 +399,6 @@ "221_pt": "(TMath::TwoPi()*x*(143.633*exp(-(sqrt(x*x+0.139571*0.139571)-0.139571)/0.392747)+1585.64*pow(exp(-1.25879*x-0.453071*x*x)+x/0.476927,-5.50804)))*((0.000946307*TMath::Power((exp(- -0.678673*sqrt(x*x+0.547*0.547-0.139*0.139)-1.46197*(x*x+0.547*0.547-0.139*0.139))+TMath::Power(0.475252/0.000946307,-1./42.0453)*sqrt(x*x+0.547*0.547-0.139*0.139)/0.718978),-42.0453)/TMath::Power((exp(- -0.678673*x-1.46197*x*x)+x/0.718978),-42.0453)+1.5622*TMath::Landau(x,2.61642,1.08512)))", "333_pt": "(TMath::TwoPi()*x*(156.897*exp(-(sqrt(x*x+0.139571*0.139571)-0.139571)/0.390093)+1835.17*pow(exp(-1.1618*x-0.514011*x*x)+x/0.465575,-5.50332)))*(0.1191/(1+exp(-(x- -0.316437)/0.554431))+-0.507618*TMath::Gaus(x,1.69654,1.62649)+0.494136*TMath::Gaus(x,2.56805,1.6193)+0.0789659)" }, - "5TeV_0510_wRatio_etatestdown": { - "histoMtScaleFactor": { - "113": 0.85, - "223": 0.7, - "331": 0.4 - }, - "111_pt": "TMath::TwoPi()*x*(156.897*exp(-(sqrt(x*x+0.139571*0.139571)-0.139571)/0.390093)+1835.17*pow(exp(-1.1618*x-0.514011*x*x)+x/0.465575,-5.50332))", - "221_pt": "(TMath::TwoPi()*x*(156.897*exp(-(sqrt(x*x+0.139571*0.139571)-0.139571)/0.390093)+1835.17*pow(exp(-1.1618*x-0.514011*x*x)+x/0.465575,-5.50332)))*((((x<11.6581)*(TMath::Min(TMath::Min(0.00302888*TMath::Power((exp(-0.246982*sqrt(x*x+0.547*0.547-0.139*0.139)-0.204843*(x*x+0.547*0.547-0.139*0.139))+TMath::Power(0.485848/0.00302888,-1./335.069)*sqrt(x*x+0.547*0.547-0.139*0.139)/2.46929),-335.069)/TMath::Power((exp(-0.246982*x-0.204843*x*x)+x/2.46929),-335.069)+2.62546*TMath::Landau(x,3.61147,1.38592),0.926*(9.36242e-05*TMath::Power((exp(- -2.56458*sqrt(x*x+0.547*0.547-0.139*0.139)-0.742625*(x*x+0.547*0.547-0.139*0.139))+TMath::Power(0.457041/9.36242e-05,-1./8.15756)*sqrt(x*x+0.547*0.547-0.139*0.139)/0.0235913),-8.15756)/TMath::Power((exp(- -2.56458*x-0.742625*x*x)+x/0.0235913),-8.15756)+1.50683*TMath::Landau(x,2.1159,0.843387))),TMath::Min(0.00624935*TMath::Power((exp(- -2.56471*sqrt(x*x+0.547*0.547-0.139*0.139)-2.49586*(x*x+0.547*0.547-0.139*0.139))+TMath::Power(0.45/0.00624935,-1./44.8766)*sqrt(x*x+0.547*0.547-0.139*0.139)/0.202909),-44.8766)/TMath::Power((exp(- -2.56471*x-2.49586*x*x)+x/0.202909),-44.8766)+1.58602*TMath::Landau(x,2.23166,0.861224),0.926*(9.36242e-05*TMath::Power((exp(- -2.56458*sqrt(x*x+0.547*0.547-0.139*0.139)-0.742625*(x*x+0.547*0.547-0.139*0.139))+TMath::Power(0.457041/9.36242e-05,-1./8.15756)*sqrt(x*x+0.547*0.547-0.139*0.139)/0.0235913),-8.15756)/TMath::Power((exp(- -2.56458*x-0.742625*x*x)+x/0.0235913),-8.15756)+1.50683*TMath::Landau(x,2.1159,0.843387)))))+(x>=11.6581)*0.426)))", - "333_pt": "(TMath::TwoPi()*x*(156.897*exp(-(sqrt(x*x+0.139571*0.139571)-0.139571)/0.390093)+1835.17*pow(exp(-1.1618*x-0.514011*x*x)+x/0.465575,-5.50332)))*(0.1191/(1+exp(-(x- -0.316437)/0.554431))+-0.507618*TMath::Gaus(x,1.69654,1.62649)+0.494136*TMath::Gaus(x,2.56805,1.6193)+0.0789659)" - }, "5TeV_0510_wRatio_etatestdown_pp13": { "histoMtScaleFactor": { "113": 0.85, diff --git a/MC/config/PWGEM/parametrizations/PbPb5TeV_peripheral.json b/MC/config/PWGEM/parametrizations/PbPb5TeV_peripheral.json new file mode 100644 index 000000000..937481744 --- /dev/null +++ b/MC/config/PWGEM/parametrizations/PbPb5TeV_peripheral.json @@ -0,0 +1,282 @@ +{ + "5TeV_5060_wRatio_pi0corr": { + "histoMtScaleFactor": { + "113": 0.84, + "331": 0.4 + }, + "111_pt": "(TMath::TwoPi()*x*(2.37689*exp(-(sqrt(x*x+0.139571*0.139571)-0.139571)/0.448898)+416.404*pow(exp(-0.582249*x-0.314888*x*x)+x/0.528081,-5.81419)))/(7.50435e-01+(9.92566e-01-7.50435e-01)*(1-exp(-x/3.90154e-01)))", + "221_pt": "((TMath::TwoPi()*x*(2.37689*exp(-(sqrt(x*x+0.139571*0.139571)-0.139571)/0.448898)+416.404*pow(exp(-0.582249*x-0.314888*x*x)+x/0.528081,-5.81419)))/(7.50435e-01+(9.92566e-01-7.50435e-01)*(1-exp(-x/3.90154e-01))))*(((TMath::TwoPi()*x*(2.37689*exp(-(sqrt(x*x+0.139571*0.139571)-0.139571)/0.448898)+416.404*pow(exp(-0.582249*x-0.314888*x*x)+x/0.528081,-5.81419)))*((0.406052/(1+exp(-(x-0.411746)/0.334347))+-0.248337*TMath::Gaus(x,-0.64255,2.29301)+-0.0467237*TMath::Gaus(x,6.03639,1.43975)+0.150899+((0.550454*exp((((0.995785*x)-sqrt((x*x)+(0.5478530000*0.5478530000)))/sqrt(1-(0.995785*0.995785)))/1.71099))+(0.0106936*(0.620714*TMath::Power(1+((x/29.189)*(x/29.189)),-(506.895)))))/(exp((((0.995785*x)-sqrt((x*x)+(0.1349770000*0.1349770000)))/sqrt(1-(0.995785*0.995785)))/1.71099)+(0.620714*TMath::Power(1+((x/29.189)*(x/29.189)),-(506.895)))))/2.))/(TMath::TwoPi()*x*(2.37689*exp(-(sqrt(x*x+0.139571*0.139571)-0.139571)/0.448898)+416.404*pow(exp(-0.582249*x-0.314888*x*x)+x/0.528081,-5.81419))))", + "223_pt": "(TMath::TwoPi()*x*(2.37689*exp(-(sqrt(x*x+0.139571*0.139571)-0.139571)/0.448898)+416.404*pow(exp(-0.582249*x-0.314888*x*x)+x/0.528081,-5.81419)))*(0.324086/(1+exp(-(x-0.573304)/0.143352))+-0.106092*TMath::Gaus(x,0.857984,0.27756)+-0.35343*TMath::Gaus(x,-0.266188,-1.4987)+0.358613)", + "333_pt": "(TMath::TwoPi()*x*(2.37689*exp(-(sqrt(x*x+0.139571*0.139571)-0.139571)/0.448898)+416.404*pow(exp(-0.582249*x-0.314888*x*x)+x/0.528081,-5.81419)))*(0.107098/(1+exp(-(x-1.38974)/1.10537))+-0.544628*TMath::Gaus(x,0.660805,1.77065)+0.445236*TMath::Gaus(x,1.03665,2.09659)+0.0915189)" + }, + "5TeV_5060_wRatio_pi0corrup": { + "histoMtScaleFactor": { + "113": 0.84, + "331": 0.4 + }, + "111_pt": "(TMath::TwoPi()*x*(2.37689*exp(-(sqrt(x*x+0.139571*0.139571)-0.139571)/0.448898)+416.404*pow(exp(-0.582249*x-0.314888*x*x)+x/0.528081,-5.81419)))/(7.50435e-01*0.95+(9.92566e-01-7.50435e-01*0.95)*(1-exp(-x/3.90154e-01)))", + "221_pt": "((TMath::TwoPi()*x*(2.37689*exp(-(sqrt(x*x+0.139571*0.139571)-0.139571)/0.448898)+416.404*pow(exp(-0.582249*x-0.314888*x*x)+x/0.528081,-5.81419)))/(7.50435e-01*0.95+(9.92566e-01-7.50435e-01*0.95)*(1-exp(-x/3.90154e-01))))*(((TMath::TwoPi()*x*(2.37689*exp(-(sqrt(x*x+0.139571*0.139571)-0.139571)/0.448898)+416.404*pow(exp(-0.582249*x-0.314888*x*x)+x/0.528081,-5.81419)))*((0.406052/(1+exp(-(x-0.411746)/0.334347))+-0.248337*TMath::Gaus(x,-0.64255,2.29301)+-0.0467237*TMath::Gaus(x,6.03639,1.43975)+0.150899+((0.550454*exp((((0.995785*x)-sqrt((x*x)+(0.5478530000*0.5478530000)))/sqrt(1-(0.995785*0.995785)))/1.71099))+(0.0106936*(0.620714*TMath::Power(1+((x/29.189)*(x/29.189)),-(506.895)))))/(exp((((0.995785*x)-sqrt((x*x)+(0.1349770000*0.1349770000)))/sqrt(1-(0.995785*0.995785)))/1.71099)+(0.620714*TMath::Power(1+((x/29.189)*(x/29.189)),-(506.895)))))/2.))/(TMath::TwoPi()*x*(2.37689*exp(-(sqrt(x*x+0.139571*0.139571)-0.139571)/0.448898)+416.404*pow(exp(-0.582249*x-0.314888*x*x)+x/0.528081,-5.81419))))", + "223_pt": "(TMath::TwoPi()*x*(2.37689*exp(-(sqrt(x*x+0.139571*0.139571)-0.139571)/0.448898)+416.404*pow(exp(-0.582249*x-0.314888*x*x)+x/0.528081,-5.81419)))*(0.324086/(1+exp(-(x-0.573304)/0.143352))+-0.106092*TMath::Gaus(x,0.857984,0.27756)+-0.35343*TMath::Gaus(x,-0.266188,-1.4987)+0.358613)", + "333_pt": "(TMath::TwoPi()*x*(2.37689*exp(-(sqrt(x*x+0.139571*0.139571)-0.139571)/0.448898)+416.404*pow(exp(-0.582249*x-0.314888*x*x)+x/0.528081,-5.81419)))*(0.107098/(1+exp(-(x-1.38974)/1.10537))+-0.544628*TMath::Gaus(x,0.660805,1.77065)+0.445236*TMath::Gaus(x,1.03665,2.09659)+0.0915189)" + }, + "5TeV_5060_wRatio_pi0corrdown": { + "histoMtScaleFactor": { + "113": 0.84, + "331": 0.4 + }, + "111_pt": "(TMath::TwoPi()*x*(2.37689*exp(-(sqrt(x*x+0.139571*0.139571)-0.139571)/0.448898)+416.404*pow(exp(-0.582249*x-0.314888*x*x)+x/0.528081,-5.81419)))/(7.50435e-01*1.05+(9.92566e-01-7.50435e-01*1.05)*(1-exp(-x/3.90154e-01)))", + "221_pt": "((TMath::TwoPi()*x*(2.37689*exp(-(sqrt(x*x+0.139571*0.139571)-0.139571)/0.448898)+416.404*pow(exp(-0.582249*x-0.314888*x*x)+x/0.528081,-5.81419)))/(7.50435e-01*1.05+(9.92566e-01-7.50435e-01*1.05)*(1-exp(-x/3.90154e-01))))*(((TMath::TwoPi()*x*(2.37689*exp(-(sqrt(x*x+0.139571*0.139571)-0.139571)/0.448898)+416.404*pow(exp(-0.582249*x-0.314888*x*x)+x/0.528081,-5.81419)))*((0.406052/(1+exp(-(x-0.411746)/0.334347))+-0.248337*TMath::Gaus(x,-0.64255,2.29301)+-0.0467237*TMath::Gaus(x,6.03639,1.43975)+0.150899+((0.550454*exp((((0.995785*x)-sqrt((x*x)+(0.5478530000*0.5478530000)))/sqrt(1-(0.995785*0.995785)))/1.71099))+(0.0106936*(0.620714*TMath::Power(1+((x/29.189)*(x/29.189)),-(506.895)))))/(exp((((0.995785*x)-sqrt((x*x)+(0.1349770000*0.1349770000)))/sqrt(1-(0.995785*0.995785)))/1.71099)+(0.620714*TMath::Power(1+((x/29.189)*(x/29.189)),-(506.895)))))/2.))/(TMath::TwoPi()*x*(2.37689*exp(-(sqrt(x*x+0.139571*0.139571)-0.139571)/0.448898)+416.404*pow(exp(-0.582249*x-0.314888*x*x)+x/0.528081,-5.81419))))", + "223_pt": "(TMath::TwoPi()*x*(2.37689*exp(-(sqrt(x*x+0.139571*0.139571)-0.139571)/0.448898)+416.404*pow(exp(-0.582249*x-0.314888*x*x)+x/0.528081,-5.81419)))*(0.324086/(1+exp(-(x-0.573304)/0.143352))+-0.106092*TMath::Gaus(x,0.857984,0.27756)+-0.35343*TMath::Gaus(x,-0.266188,-1.4987)+0.358613)", + "333_pt": "(TMath::TwoPi()*x*(2.37689*exp(-(sqrt(x*x+0.139571*0.139571)-0.139571)/0.448898)+416.404*pow(exp(-0.582249*x-0.314888*x*x)+x/0.528081,-5.81419)))*(0.107098/(1+exp(-(x-1.38974)/1.10537))+-0.544628*TMath::Gaus(x,0.660805,1.77065)+0.445236*TMath::Gaus(x,1.03665,2.09659)+0.0915189)" + }, + "5TeV_5060_wRatio_pi0corr_up": { + "histoMtScaleFactor": { + "113": 0.84, + "331": 0.4 + }, + "111_pt": "(TMath::TwoPi()*x*(2.60114*exp(-(sqrt(x*x+0.139571*0.139571)-0.139571)/0.447208)+465.994*pow(exp(-0.521709*x-0.39326*x*x)+x/0.516902,-5.79931)))/(7.50435e-01+(9.92566e-01-7.50435e-01)*(1-exp(-x/3.90154e-01)))", + "221_pt": "((TMath::TwoPi()*x*(2.60114*exp(-(sqrt(x*x+0.139571*0.139571)-0.139571)/0.447208)+465.994*pow(exp(-0.521709*x-0.39326*x*x)+x/0.516902,-5.79931)))/(7.50435e-01+(9.92566e-01-7.50435e-01)*(1-exp(-x/3.90154e-01))))*(((TMath::TwoPi()*x*(2.60114*exp(-(sqrt(x*x+0.139571*0.139571)-0.139571)/0.447208)+465.994*pow(exp(-0.521709*x-0.39326*x*x)+x/0.516902,-5.79931)))*((0.406052/(1+exp(-(x-0.411746)/0.334347))+-0.248337*TMath::Gaus(x,-0.64255,2.29301)+-0.0467237*TMath::Gaus(x,6.03639,1.43975)+0.150899+((0.550454*exp((((0.995785*x)-sqrt((x*x)+(0.5478530000*0.5478530000)))/sqrt(1-(0.995785*0.995785)))/1.71099))+(0.0106936*(0.620714*TMath::Power(1+((x/29.189)*(x/29.189)),-(506.895)))))/(exp((((0.995785*x)-sqrt((x*x)+(0.1349770000*0.1349770000)))/sqrt(1-(0.995785*0.995785)))/1.71099)+(0.620714*TMath::Power(1+((x/29.189)*(x/29.189)),-(506.895)))))/2.))/(TMath::TwoPi()*x*(2.60114*exp(-(sqrt(x*x+0.139571*0.139571)-0.139571)/0.447208)+465.994*pow(exp(-0.521709*x-0.39326*x*x)+x/0.516902,-5.79931))))", + "223_pt": "(TMath::TwoPi()*x*(2.60114*exp(-(sqrt(x*x+0.139571*0.139571)-0.139571)/0.447208)+465.994*pow(exp(-0.521709*x-0.39326*x*x)+x/0.516902,-5.79931)))*(0.324086/(1+exp(-(x-0.573304)/0.143352))+-0.106092*TMath::Gaus(x,0.857984,0.27756)+-0.35343*TMath::Gaus(x,-0.266188,-1.4987)+0.358613)", + "333_pt": "(TMath::TwoPi()*x*(2.60114*exp(-(sqrt(x*x+0.139571*0.139571)-0.139571)/0.447208)+465.994*pow(exp(-0.521709*x-0.39326*x*x)+x/0.516902,-5.79931)))*(0.107098/(1+exp(-(x-1.38974)/1.10537))+-0.544628*TMath::Gaus(x,0.660805,1.77065)+0.445236*TMath::Gaus(x,1.03665,2.09659)+0.0915189)" + }, + "5TeV_5060_wRatio_pi0corr_down": { + "histoMtScaleFactor": { + "113": 0.84, + "331": 0.4 + }, + "111_pt": "(TMath::TwoPi()*x*(2.38584*exp(-(sqrt(x*x+0.139571*0.139571)-0.139571)/0.444595)+367.741*pow(exp(-0.649054*x-0.220079*x*x)+x/0.541328,-5.83225)))/(7.50435e-01+(9.92566e-01-7.50435e-01)*(1-exp(-x/3.90154e-01)))", + "221_pt": "((TMath::TwoPi()*x*(2.38584*exp(-(sqrt(x*x+0.139571*0.139571)-0.139571)/0.444595)+367.741*pow(exp(-0.649054*x-0.220079*x*x)+x/0.541328,-5.83225)))/(7.50435e-01+(9.92566e-01-7.50435e-01)*(1-exp(-x/3.90154e-01))))*(((TMath::TwoPi()*x*(2.38584*exp(-(sqrt(x*x+0.139571*0.139571)-0.139571)/0.444595)+367.741*pow(exp(-0.649054*x-0.220079*x*x)+x/0.541328,-5.83225)))*((0.406052/(1+exp(-(x-0.411746)/0.334347))+-0.248337*TMath::Gaus(x,-0.64255,2.29301)+-0.0467237*TMath::Gaus(x,6.03639,1.43975)+0.150899+((0.550454*exp((((0.995785*x)-sqrt((x*x)+(0.5478530000*0.5478530000)))/sqrt(1-(0.995785*0.995785)))/1.71099))+(0.0106936*(0.620714*TMath::Power(1+((x/29.189)*(x/29.189)),-(506.895)))))/(exp((((0.995785*x)-sqrt((x*x)+(0.1349770000*0.1349770000)))/sqrt(1-(0.995785*0.995785)))/1.71099)+(0.620714*TMath::Power(1+((x/29.189)*(x/29.189)),-(506.895)))))/2.))/(TMath::TwoPi()*x*(2.38584*exp(-(sqrt(x*x+0.139571*0.139571)-0.139571)/0.444595)+367.741*pow(exp(-0.649054*x-0.220079*x*x)+x/0.541328,-5.83225))))", + "223_pt": "(TMath::TwoPi()*x*(2.38584*exp(-(sqrt(x*x+0.139571*0.139571)-0.139571)/0.444595)+367.741*pow(exp(-0.649054*x-0.220079*x*x)+x/0.541328,-5.83225)))*(0.324086/(1+exp(-(x-0.573304)/0.143352))+-0.106092*TMath::Gaus(x,0.857984,0.27756)+-0.35343*TMath::Gaus(x,-0.266188,-1.4987)+0.358613)", + "333_pt": "(TMath::TwoPi()*x*(2.38584*exp(-(sqrt(x*x+0.139571*0.139571)-0.139571)/0.444595)+367.741*pow(exp(-0.649054*x-0.220079*x*x)+x/0.541328,-5.83225)))*(0.107098/(1+exp(-(x-1.38974)/1.10537))+-0.544628*TMath::Gaus(x,0.660805,1.77065)+0.445236*TMath::Gaus(x,1.03665,2.09659)+0.0915189)" + }, + "5TeV_5060_wRatio_pi0corr_ratiosup": { + "histoMtScaleFactor": { + "113": 1.01, + "331": 0.48 + }, + "111_pt": "(TMath::TwoPi()*x*(2.37689*exp(-(sqrt(x*x+0.139571*0.139571)-0.139571)/0.448898)+416.404*pow(exp(-0.582249*x-0.314888*x*x)+x/0.528081,-5.81419)))/(7.50435e-01+(9.92566e-01-7.50435e-01)*(1-exp(-x/3.90154e-01)))", + "221_pt": "((TMath::TwoPi()*x*(2.37689*exp(-(sqrt(x*x+0.139571*0.139571)-0.139571)/0.448898)+416.404*pow(exp(-0.582249*x-0.314888*x*x)+x/0.528081,-5.81419)))/(7.50435e-01+(9.92566e-01-7.50435e-01)*(1-exp(-x/3.90154e-01))))*(((x<0.25)*(1.5*(1-0.8*x)))*(((TMath::TwoPi()*x*(2.37689*exp(-(sqrt(x*x+0.139571*0.139571)-0.139571)/0.448898)+416.404*pow(exp(-0.582249*x-0.314888*x*x)+x/0.528081,-5.81419)))*((0.406052/(1+exp(-(x-0.411746)/0.334347))+-0.248337*TMath::Gaus(x,-0.64255,2.29301)+-0.0467237*TMath::Gaus(x,6.03639,1.43975)+0.150899+((0.550454*exp((((0.995785*x)-sqrt((x*x)+(0.5478530000*0.5478530000)))/sqrt(1-(0.995785*0.995785)))/1.71099))+(0.0106936*(0.620714*TMath::Power(1+((x/29.189)*(x/29.189)),-(506.895)))))/(exp((((0.995785*x)-sqrt((x*x)+(0.1349770000*0.1349770000)))/sqrt(1-(0.995785*0.995785)))/1.71099)+(0.620714*TMath::Power(1+((x/29.189)*(x/29.189)),-(506.895)))))/2.))/(TMath::TwoPi()*x*(2.37689*exp(-(sqrt(x*x+0.139571*0.139571)-0.139571)/0.448898)+416.404*pow(exp(-0.582249*x-0.314888*x*x)+x/0.528081,-5.81419))))+(x>=0.25)*1.2*(((TMath::TwoPi()*x*(2.37689*exp(-(sqrt(x*x+0.139571*0.139571)-0.139571)/0.448898)+416.404*pow(exp(-0.582249*x-0.314888*x*x)+x/0.528081,-5.81419)))*((0.406052/(1+exp(-(x-0.411746)/0.334347))+-0.248337*TMath::Gaus(x,-0.64255,2.29301)+-0.0467237*TMath::Gaus(x,6.03639,1.43975)+0.150899+((0.550454*exp((((0.995785*x)-sqrt((x*x)+(0.5478530000*0.5478530000)))/sqrt(1-(0.995785*0.995785)))/1.71099))+(0.0106936*(0.620714*TMath::Power(1+((x/29.189)*(x/29.189)),-(506.895)))))/(exp((((0.995785*x)-sqrt((x*x)+(0.1349770000*0.1349770000)))/sqrt(1-(0.995785*0.995785)))/1.71099)+(0.620714*TMath::Power(1+((x/29.189)*(x/29.189)),-(506.895)))))/2.))/(TMath::TwoPi()*x*(2.37689*exp(-(sqrt(x*x+0.139571*0.139571)-0.139571)/0.448898)+416.404*pow(exp(-0.582249*x-0.314888*x*x)+x/0.528081,-5.81419)))))", + "223_pt": "(TMath::TwoPi()*x*(2.37689*exp(-(sqrt(x*x+0.139571*0.139571)-0.139571)/0.448898)+416.404*pow(exp(-0.582249*x-0.314888*x*x)+x/0.528081,-5.81419)))*(((x<0.25)*(1.5*(1-0.8*x)))*(0.324086/(1+exp(-(x-0.573304)/0.143352))+-0.106092*TMath::Gaus(x,0.857984,0.27756)+-0.35343*TMath::Gaus(x,-0.266188,-1.4987)+0.358613)+((x>=0.25)*1.2*(0.324086/(1+exp(-(x-0.573304)/0.143352))+-0.106092*TMath::Gaus(x,0.857984,0.27756)+-0.35343*TMath::Gaus(x,-0.266188,-1.4987)+0.358613)))", + "333_pt": "(TMath::TwoPi()*x*(2.37689*exp(-(sqrt(x*x+0.139571*0.139571)-0.139571)/0.448898)+416.404*pow(exp(-0.582249*x-0.314888*x*x)+x/0.528081,-5.81419)))*(1.2*(0.107098/(1+exp(-(x-1.38974)/1.10537))+-0.544628*TMath::Gaus(x,0.660805,1.77065)+0.445236*TMath::Gaus(x,1.03665,2.09659)+0.0915189))" + }, + "5TeV_5060_wRatio_pi0corr_ratiosdown": { + "histoMtScaleFactor": { + "223": 0.62, + "331": 0.32 + }, + "111_pt": "(TMath::TwoPi()*x*(2.37689*exp(-(sqrt(x*x+0.139571*0.139571)-0.139571)/0.448898)+416.404*pow(exp(-0.582249*x-0.314888*x*x)+x/0.528081,-5.81419)))/(7.50435e-01+(9.92566e-01-7.50435e-01)*(1-exp(-x/3.90154e-01)))", + "221_pt": "((TMath::TwoPi()*x*(2.37689*exp(-(sqrt(x*x+0.139571*0.139571)-0.139571)/0.448898)+416.404*pow(exp(-0.582249*x-0.314888*x*x)+x/0.528081,-5.81419)))/(7.50435e-01+(9.92566e-01-7.50435e-01)*(1-exp(-x/3.90154e-01))))*(((x<0.4)*(0.4*(1+2.5*x)))*(((TMath::TwoPi()*x*(2.37689*exp(-(sqrt(x*x+0.139571*0.139571)-0.139571)/0.448898)+416.404*pow(exp(-0.582249*x-0.314888*x*x)+x/0.528081,-5.81419)))*((0.406052/(1+exp(-(x-0.411746)/0.334347))+-0.248337*TMath::Gaus(x,-0.64255,2.29301)+-0.0467237*TMath::Gaus(x,6.03639,1.43975)+0.150899+((0.550454*exp((((0.995785*x)-sqrt((x*x)+(0.5478530000*0.5478530000)))/sqrt(1-(0.995785*0.995785)))/1.71099))+(0.0106936*(0.620714*TMath::Power(1+((x/29.189)*(x/29.189)),-(506.895)))))/(exp((((0.995785*x)-sqrt((x*x)+(0.1349770000*0.1349770000)))/sqrt(1-(0.995785*0.995785)))/1.71099)+(0.620714*TMath::Power(1+((x/29.189)*(x/29.189)),-(506.895)))))/2.))/(TMath::TwoPi()*x*(2.37689*exp(-(sqrt(x*x+0.139571*0.139571)-0.139571)/0.448898)+416.404*pow(exp(-0.582249*x-0.314888*x*x)+x/0.528081,-5.81419))))+(x>=0.4)*0.8*(((TMath::TwoPi()*x*(2.37689*exp(-(sqrt(x*x+0.139571*0.139571)-0.139571)/0.448898)+416.404*pow(exp(-0.582249*x-0.314888*x*x)+x/0.528081,-5.81419)))*((0.406052/(1+exp(-(x-0.411746)/0.334347))+-0.248337*TMath::Gaus(x,-0.64255,2.29301)+-0.0467237*TMath::Gaus(x,6.03639,1.43975)+0.150899+((0.550454*exp((((0.995785*x)-sqrt((x*x)+(0.5478530000*0.5478530000)))/sqrt(1-(0.995785*0.995785)))/1.71099))+(0.0106936*(0.620714*TMath::Power(1+((x/29.189)*(x/29.189)),-(506.895)))))/(exp((((0.995785*x)-sqrt((x*x)+(0.1349770000*0.1349770000)))/sqrt(1-(0.995785*0.995785)))/1.71099)+(0.620714*TMath::Power(1+((x/29.189)*(x/29.189)),-(506.895)))))/2.))/(TMath::TwoPi()*x*(2.37689*exp(-(sqrt(x*x+0.139571*0.139571)-0.139571)/0.448898)+416.404*pow(exp(-0.582249*x-0.314888*x*x)+x/0.528081,-5.81419)))))", + "113_pt": "(TMath::TwoPi()*x*(2.37689*exp(-(sqrt(x*x+0.139571*0.139571)-0.139571)/0.448898)+416.404*pow(exp(-0.582249*x-0.314888*x*x)+x/0.528081,-5.81419)))*((x>1.951)*(0.451114/(1+exp(-(x-0.707439)/0.374928))+-0.307087*TMath::Gaus(x,-0.577264,1.60957)+-0.20694*TMath::Gaus(x,-2.50098,4.31777)+0.337195)+(x<=1.951)*((((0.52988/(1+exp(-((x-0.303965)/0.287856))))+(-0.281848*TMath::Gaus(x,0.497102,0.688973)))+(-0.249068*TMath::Gaus(x,1.09157,1.16378)))+0.253347))", + "333_pt": "(TMath::TwoPi()*x*(2.37689*exp(-(sqrt(x*x+0.139571*0.139571)-0.139571)/0.448898)+416.404*pow(exp(-0.582249*x-0.314888*x*x)+x/0.528081,-5.81419)))*(0.8*(0.107098/(1+exp(-(x-1.38974)/1.10537))+-0.544628*TMath::Gaus(x,0.660805,1.77065)+0.445236*TMath::Gaus(x,1.03665,2.09659)+0.0915189))" + }, + "5TeV_6070_wRatio_pi0corr": { + "histoMtScaleFactor": { + "113": 0.84, + "331": 0.4 + }, + "111_pt": "(TMath::TwoPi()*x*(0*exp(-(sqrt(x*x+0.139571*0.139571)-0.139571)/0.1)+237.396*pow(exp(-0.450001*x-0.267691*x*x)+x/0.561352,-5.96452)))/(7.50435e-01+(9.92566e-01-7.50435e-01)*(1-exp(-x/3.90154e-01)))", + "221_pt": "((TMath::TwoPi()*x*(0*exp(-(sqrt(x*x+0.139571*0.139571)-0.139571)/0.1)+237.396*pow(exp(-0.450001*x-0.267691*x*x)+x/0.561352,-5.96452)))/(7.50435e-01+(9.92566e-01-7.50435e-01)*(1-exp(-x/3.90154e-01))))*(((TMath::TwoPi()*x*(0*exp(-(sqrt(x*x+0.139571*0.139571)-0.139571)/0.1)+237.396*pow(exp(-0.450001*x-0.267691*x*x)+x/0.561352,-5.96452)))*((0.287493/(1+exp(-(x-0.381675)/0.227939))+-0.301666*TMath::Gaus(x,0.0639027,1.54263)+-0.0271521*TMath::Gaus(x,4.71408,1.51159)+0.274684+((0.550454*exp((((0.995785*x)-sqrt((x*x)+(0.5478530000*0.5478530000)))/sqrt(1-(0.995785*0.995785)))/1.71099))+(0.0106936*(0.620714*TMath::Power(1+((x/29.189)*(x/29.189)),-(506.895)))))/(exp((((0.995785*x)-sqrt((x*x)+(0.1349770000*0.1349770000)))/sqrt(1-(0.995785*0.995785)))/1.71099)+(0.620714*TMath::Power(1+((x/29.189)*(x/29.189)),-(506.895)))))/2.))/(TMath::TwoPi()*x*(0*exp(-(sqrt(x*x+0.139571*0.139571)-0.139571)/0.1)+237.396*pow(exp(-0.450001*x-0.267691*x*x)+x/0.561352,-5.96452))))", + "223_pt": "(TMath::TwoPi()*x*(0*exp(-(sqrt(x*x+0.139571*0.139571)-0.139571)/0.1)+237.396*pow(exp(-0.450001*x-0.267691*x*x)+x/0.561352,-5.96452)))*(0.324086/(1+exp(-(x-0.573304)/0.143352))+-0.106092*TMath::Gaus(x,0.857984,0.27756)+-0.35343*TMath::Gaus(x,-0.266188,-1.4987)+0.358613)", + "333_pt": "(TMath::TwoPi()*x*(0*exp(-(sqrt(x*x+0.139571*0.139571)-0.139571)/0.1)+237.396*pow(exp(-0.450001*x-0.267691*x*x)+x/0.561352,-5.96452)))*(0.109761/(1+exp(-(x-1.3902)/1.35693))+-0.549036*TMath::Gaus(x,0.570177,1.69368)+0.441093*TMath::Gaus(x,0.836878,1.93285)+0.089258)" + }, + "5TeV_6070_wRatio_pi0corrup": { + "histoMtScaleFactor": { + "113": 0.84, + "331": 0.4 + }, + "111_pt": "(TMath::TwoPi()*x*(0*exp(-(sqrt(x*x+0.139571*0.139571)-0.139571)/0.1)+237.396*pow(exp(-0.450001*x-0.267691*x*x)+x/0.561352,-5.96452)))/(7.50435e-01*0.95+(9.92566e-01-7.50435e-01*0.95)*(1-exp(-x/3.90154e-01)))", + "221_pt": "((TMath::TwoPi()*x*(0*exp(-(sqrt(x*x+0.139571*0.139571)-0.139571)/0.1)+237.396*pow(exp(-0.450001*x-0.267691*x*x)+x/0.561352,-5.96452)))/(7.50435e-01*0.95+(9.92566e-01-7.50435e-01*0.95)*(1-exp(-x/3.90154e-01))))*(((TMath::TwoPi()*x*(0*exp(-(sqrt(x*x+0.139571*0.139571)-0.139571)/0.1)+237.396*pow(exp(-0.450001*x-0.267691*x*x)+x/0.561352,-5.96452)))*((0.287493/(1+exp(-(x-0.381675)/0.227939))+-0.301666*TMath::Gaus(x,0.0639027,1.54263)+-0.0271521*TMath::Gaus(x,4.71408,1.51159)+0.274684+((0.550454*exp((((0.995785*x)-sqrt((x*x)+(0.5478530000*0.5478530000)))/sqrt(1-(0.995785*0.995785)))/1.71099))+(0.0106936*(0.620714*TMath::Power(1+((x/29.189)*(x/29.189)),-(506.895)))))/(exp((((0.995785*x)-sqrt((x*x)+(0.1349770000*0.1349770000)))/sqrt(1-(0.995785*0.995785)))/1.71099)+(0.620714*TMath::Power(1+((x/29.189)*(x/29.189)),-(506.895)))))/2.))/(TMath::TwoPi()*x*(0*exp(-(sqrt(x*x+0.139571*0.139571)-0.139571)/0.1)+237.396*pow(exp(-0.450001*x-0.267691*x*x)+x/0.561352,-5.96452))))", + "223_pt": "(TMath::TwoPi()*x*(0*exp(-(sqrt(x*x+0.139571*0.139571)-0.139571)/0.1)+237.396*pow(exp(-0.450001*x-0.267691*x*x)+x/0.561352,-5.96452)))*(0.324086/(1+exp(-(x-0.573304)/0.143352))+-0.106092*TMath::Gaus(x,0.857984,0.27756)+-0.35343*TMath::Gaus(x,-0.266188,-1.4987)+0.358613)", + "333_pt": "(TMath::TwoPi()*x*(0*exp(-(sqrt(x*x+0.139571*0.139571)-0.139571)/0.1)+237.396*pow(exp(-0.450001*x-0.267691*x*x)+x/0.561352,-5.96452)))*(0.109761/(1+exp(-(x-1.3902)/1.35693))+-0.549036*TMath::Gaus(x,0.570177,1.69368)+0.441093*TMath::Gaus(x,0.836878,1.93285)+0.089258)" + }, + "5TeV_6070_wRatio_pi0corrdown": { + "histoMtScaleFactor": { + "113": 0.84, + "331": 0.4 + }, + "111_pt": "(TMath::TwoPi()*x*(0*exp(-(sqrt(x*x+0.139571*0.139571)-0.139571)/0.1)+237.396*pow(exp(-0.450001*x-0.267691*x*x)+x/0.561352,-5.96452)))/(7.50435e-01*1.05+(9.92566e-01-7.50435e-01*1.05)*(1-exp(-x/3.90154e-01)))", + "221_pt": "((TMath::TwoPi()*x*(0*exp(-(sqrt(x*x+0.139571*0.139571)-0.139571)/0.1)+237.396*pow(exp(-0.450001*x-0.267691*x*x)+x/0.561352,-5.96452)))/(7.50435e-01*1.05+(9.92566e-01-7.50435e-01*1.05)*(1-exp(-x/3.90154e-01))))*(((TMath::TwoPi()*x*(0*exp(-(sqrt(x*x+0.139571*0.139571)-0.139571)/0.1)+237.396*pow(exp(-0.450001*x-0.267691*x*x)+x/0.561352,-5.96452)))*((0.287493/(1+exp(-(x-0.381675)/0.227939))+-0.301666*TMath::Gaus(x,0.0639027,1.54263)+-0.0271521*TMath::Gaus(x,4.71408,1.51159)+0.274684+((0.550454*exp((((0.995785*x)-sqrt((x*x)+(0.5478530000*0.5478530000)))/sqrt(1-(0.995785*0.995785)))/1.71099))+(0.0106936*(0.620714*TMath::Power(1+((x/29.189)*(x/29.189)),-(506.895)))))/(exp((((0.995785*x)-sqrt((x*x)+(0.1349770000*0.1349770000)))/sqrt(1-(0.995785*0.995785)))/1.71099)+(0.620714*TMath::Power(1+((x/29.189)*(x/29.189)),-(506.895)))))/2.))/(TMath::TwoPi()*x*(0*exp(-(sqrt(x*x+0.139571*0.139571)-0.139571)/0.1)+237.396*pow(exp(-0.450001*x-0.267691*x*x)+x/0.561352,-5.96452))))", + "223_pt": "(TMath::TwoPi()*x*(0*exp(-(sqrt(x*x+0.139571*0.139571)-0.139571)/0.1)+237.396*pow(exp(-0.450001*x-0.267691*x*x)+x/0.561352,-5.96452)))*(0.324086/(1+exp(-(x-0.573304)/0.143352))+-0.106092*TMath::Gaus(x,0.857984,0.27756)+-0.35343*TMath::Gaus(x,-0.266188,-1.4987)+0.358613)", + "333_pt": "(TMath::TwoPi()*x*(0*exp(-(sqrt(x*x+0.139571*0.139571)-0.139571)/0.1)+237.396*pow(exp(-0.450001*x-0.267691*x*x)+x/0.561352,-5.96452)))*(0.109761/(1+exp(-(x-1.3902)/1.35693))+-0.549036*TMath::Gaus(x,0.570177,1.69368)+0.441093*TMath::Gaus(x,0.836878,1.93285)+0.089258)" + }, + "5TeV_6070_wRatio_pi0corr_up": { + "histoMtScaleFactor": { + "113": 0.84, + "331": 0.4 + }, + "111_pt": "(TMath::TwoPi()*x*(0*exp(-(sqrt(x*x+0.139571*0.139571)-0.139571)/0.1)+258.434*pow(exp(-0.409765*x-0.32565*x*x)+x/0.554505,-5.9546)))/(7.50435e-01+(9.92566e-01-7.50435e-01)*(1-exp(-x/3.90154e-01)))", + "221_pt": "((TMath::TwoPi()*x*(0*exp(-(sqrt(x*x+0.139571*0.139571)-0.139571)/0.1)+258.434*pow(exp(-0.409765*x-0.32565*x*x)+x/0.554505,-5.9546)))/(7.50435e-01+(9.92566e-01-7.50435e-01)*(1-exp(-x/3.90154e-01))))*(((TMath::TwoPi()*x*(0*exp(-(sqrt(x*x+0.139571*0.139571)-0.139571)/0.1)+258.434*pow(exp(-0.409765*x-0.32565*x*x)+x/0.554505,-5.9546)))*((0.287493/(1+exp(-(x-0.381675)/0.227939))+-0.301666*TMath::Gaus(x,0.0639027,1.54263)+-0.0271521*TMath::Gaus(x,4.71408,1.51159)+0.274684+((0.550454*exp((((0.995785*x)-sqrt((x*x)+(0.5478530000*0.5478530000)))/sqrt(1-(0.995785*0.995785)))/1.71099))+(0.0106936*(0.620714*TMath::Power(1+((x/29.189)*(x/29.189)),-(506.895)))))/(exp((((0.995785*x)-sqrt((x*x)+(0.1349770000*0.1349770000)))/sqrt(1-(0.995785*0.995785)))/1.71099)+(0.620714*TMath::Power(1+((x/29.189)*(x/29.189)),-(506.895)))))/2.))/(TMath::TwoPi()*x*(0*exp(-(sqrt(x*x+0.139571*0.139571)-0.139571)/0.1)+258.434*pow(exp(-0.409765*x-0.32565*x*x)+x/0.554505,-5.9546))))", + "223_pt": "(TMath::TwoPi()*x*(0*exp(-(sqrt(x*x+0.139571*0.139571)-0.139571)/0.1)+258.434*pow(exp(-0.409765*x-0.32565*x*x)+x/0.554505,-5.9546)))*(0.324086/(1+exp(-(x-0.573304)/0.143352))+-0.106092*TMath::Gaus(x,0.857984,0.27756)+-0.35343*TMath::Gaus(x,-0.266188,-1.4987)+0.358613)", + "333_pt": "(TMath::TwoPi()*x*(0*exp(-(sqrt(x*x+0.139571*0.139571)-0.139571)/0.1)+258.434*pow(exp(-0.409765*x-0.32565*x*x)+x/0.554505,-5.9546)))*(0.109761/(1+exp(-(x-1.3902)/1.35693))+-0.549036*TMath::Gaus(x,0.570177,1.69368)+0.441093*TMath::Gaus(x,0.836878,1.93285)+0.089258)" + }, + "5TeV_6070_wRatio_pi0corr_down": { + "histoMtScaleFactor": { + "113": 0.84, + "331": 0.4 + }, + "111_pt": "(TMath::TwoPi()*x*(0*exp(-(sqrt(x*x+0.139571*0.139571)-0.139571)/0.1)+217.529*pow(exp(-0.488748*x-0.208088*x*x)+x/0.56927,-5.97798)))/(7.50435e-01+(9.92566e-01-7.50435e-01)*(1-exp(-x/3.90154e-01)))", + "221_pt": "((TMath::TwoPi()*x*(0*exp(-(sqrt(x*x+0.139571*0.139571)-0.139571)/0.1)+217.529*pow(exp(-0.488748*x-0.208088*x*x)+x/0.56927,-5.97798)))/(7.50435e-01+(9.92566e-01-7.50435e-01)*(1-exp(-x/3.90154e-01))))*(((TMath::TwoPi()*x*(0*exp(-(sqrt(x*x+0.139571*0.139571)-0.139571)/0.1)+217.529*pow(exp(-0.488748*x-0.208088*x*x)+x/0.56927,-5.97798)))*((0.287493/(1+exp(-(x-0.381675)/0.227939))+-0.301666*TMath::Gaus(x,0.0639027,1.54263)+-0.0271521*TMath::Gaus(x,4.71408,1.51159)+0.274684+((0.550454*exp((((0.995785*x)-sqrt((x*x)+(0.5478530000*0.5478530000)))/sqrt(1-(0.995785*0.995785)))/1.71099))+(0.0106936*(0.620714*TMath::Power(1+((x/29.189)*(x/29.189)),-(506.895)))))/(exp((((0.995785*x)-sqrt((x*x)+(0.1349770000*0.1349770000)))/sqrt(1-(0.995785*0.995785)))/1.71099)+(0.620714*TMath::Power(1+((x/29.189)*(x/29.189)),-(506.895)))))/2.))/(TMath::TwoPi()*x*(0*exp(-(sqrt(x*x+0.139571*0.139571)-0.139571)/0.1)+217.529*pow(exp(-0.488748*x-0.208088*x*x)+x/0.56927,-5.97798))))", + "223_pt": "(TMath::TwoPi()*x*(0*exp(-(sqrt(x*x+0.139571*0.139571)-0.139571)/0.1)+217.529*pow(exp(-0.488748*x-0.208088*x*x)+x/0.56927,-5.97798)))*(0.324086/(1+exp(-(x-0.573304)/0.143352))+-0.106092*TMath::Gaus(x,0.857984,0.27756)+-0.35343*TMath::Gaus(x,-0.266188,-1.4987)+0.358613)", + "333_pt": "(TMath::TwoPi()*x*(0*exp(-(sqrt(x*x+0.139571*0.139571)-0.139571)/0.1)+217.529*pow(exp(-0.488748*x-0.208088*x*x)+x/0.56927,-5.97798)))*(0.109761/(1+exp(-(x-1.3902)/1.35693))+-0.549036*TMath::Gaus(x,0.570177,1.69368)+0.441093*TMath::Gaus(x,0.836878,1.93285)+0.089258)" + }, + "5TeV_6070_wRatio_pi0corr_ratiosup": { + "histoMtScaleFactor": { + "113": 1.01, + "331": 0.48 + }, + "111_pt": "(TMath::TwoPi()*x*(0*exp(-(sqrt(x*x+0.139571*0.139571)-0.139571)/0.1)+237.396*pow(exp(-0.450001*x-0.267691*x*x)+x/0.561352,-5.96452)))/(7.50435e-01+(9.92566e-01-7.50435e-01)*(1-exp(-x/3.90154e-01)))", + "221_pt": "((TMath::TwoPi()*x*(0*exp(-(sqrt(x*x+0.139571*0.139571)-0.139571)/0.1)+237.396*pow(exp(-0.450001*x-0.267691*x*x)+x/0.561352,-5.96452)))/(7.50435e-01+(9.92566e-01-7.50435e-01)*(1-exp(-x/3.90154e-01))))*(((x<0.25)*(1.5*(1-0.8*x)))*(((TMath::TwoPi()*x*(0*exp(-(sqrt(x*x+0.139571*0.139571)-0.139571)/0.1)+237.396*pow(exp(-0.450001*x-0.267691*x*x)+x/0.561352,-5.96452)))*((0.287493/(1+exp(-(x-0.381675)/0.227939))+-0.301666*TMath::Gaus(x,0.0639027,1.54263)+-0.0271521*TMath::Gaus(x,4.71408,1.51159)+0.274684+((0.550454*exp((((0.995785*x)-sqrt((x*x)+(0.5478530000*0.5478530000)))/sqrt(1-(0.995785*0.995785)))/1.71099))+(0.0106936*(0.620714*TMath::Power(1+((x/29.189)*(x/29.189)),-(506.895)))))/(exp((((0.995785*x)-sqrt((x*x)+(0.1349770000*0.1349770000)))/sqrt(1-(0.995785*0.995785)))/1.71099)+(0.620714*TMath::Power(1+((x/29.189)*(x/29.189)),-(506.895)))))/2.))/(TMath::TwoPi()*x*(0*exp(-(sqrt(x*x+0.139571*0.139571)-0.139571)/0.1)+237.396*pow(exp(-0.450001*x-0.267691*x*x)+x/0.561352,-5.96452))))+(x>=0.25)*1.2*(((TMath::TwoPi()*x*(0*exp(-(sqrt(x*x+0.139571*0.139571)-0.139571)/0.1)+237.396*pow(exp(-0.450001*x-0.267691*x*x)+x/0.561352,-5.96452)))*((0.287493/(1+exp(-(x-0.381675)/0.227939))+-0.301666*TMath::Gaus(x,0.0639027,1.54263)+-0.0271521*TMath::Gaus(x,4.71408,1.51159)+0.274684+((0.550454*exp((((0.995785*x)-sqrt((x*x)+(0.5478530000*0.5478530000)))/sqrt(1-(0.995785*0.995785)))/1.71099))+(0.0106936*(0.620714*TMath::Power(1+((x/29.189)*(x/29.189)),-(506.895)))))/(exp((((0.995785*x)-sqrt((x*x)+(0.1349770000*0.1349770000)))/sqrt(1-(0.995785*0.995785)))/1.71099)+(0.620714*TMath::Power(1+((x/29.189)*(x/29.189)),-(506.895)))))/2.))/(TMath::TwoPi()*x*(0*exp(-(sqrt(x*x+0.139571*0.139571)-0.139571)/0.1)+237.396*pow(exp(-0.450001*x-0.267691*x*x)+x/0.561352,-5.96452)))))", + "223_pt": "(TMath::TwoPi()*x*(0*exp(-(sqrt(x*x+0.139571*0.139571)-0.139571)/0.1)+237.396*pow(exp(-0.450001*x-0.267691*x*x)+x/0.561352,-5.96452)))*(((x<0.25)*(1.5*(1-0.8*x)))*(0.324086/(1+exp(-(x-0.573304)/0.143352))+-0.106092*TMath::Gaus(x,0.857984,0.27756)+-0.35343*TMath::Gaus(x,-0.266188,-1.4987)+0.358613)+((x>=0.25)*1.2*(0.324086/(1+exp(-(x-0.573304)/0.143352))+-0.106092*TMath::Gaus(x,0.857984,0.27756)+-0.35343*TMath::Gaus(x,-0.266188,-1.4987)+0.358613)))", + "333_pt": "(TMath::TwoPi()*x*(0*exp(-(sqrt(x*x+0.139571*0.139571)-0.139571)/0.1)+237.396*pow(exp(-0.450001*x-0.267691*x*x)+x/0.561352,-5.96452)))*(1.2*(0.109761/(1+exp(-(x-1.3902)/1.35693))+-0.549036*TMath::Gaus(x,0.570177,1.69368)+0.441093*TMath::Gaus(x,0.836878,1.93285)+0.089258))" + }, + "5TeV_6070_wRatio_pi0corr_ratiosdown": { + "histoMtScaleFactor": { + "223": 0.62, + "331": 0.32 + }, + "111_pt": "(TMath::TwoPi()*x*(0*exp(-(sqrt(x*x+0.139571*0.139571)-0.139571)/0.1)+237.396*pow(exp(-0.450001*x-0.267691*x*x)+x/0.561352,-5.96452)))/(7.50435e-01+(9.92566e-01-7.50435e-01)*(1-exp(-x/3.90154e-01)))", + "221_pt": "((TMath::TwoPi()*x*(0*exp(-(sqrt(x*x+0.139571*0.139571)-0.139571)/0.1)+237.396*pow(exp(-0.450001*x-0.267691*x*x)+x/0.561352,-5.96452)))/(7.50435e-01+(9.92566e-01-7.50435e-01)*(1-exp(-x/3.90154e-01))))*(((x<0.4)*(0.4*(1+2.5*x)))*(((TMath::TwoPi()*x*(0*exp(-(sqrt(x*x+0.139571*0.139571)-0.139571)/0.1)+237.396*pow(exp(-0.450001*x-0.267691*x*x)+x/0.561352,-5.96452)))*((0.287493/(1+exp(-(x-0.381675)/0.227939))+-0.301666*TMath::Gaus(x,0.0639027,1.54263)+-0.0271521*TMath::Gaus(x,4.71408,1.51159)+0.274684+((0.550454*exp((((0.995785*x)-sqrt((x*x)+(0.5478530000*0.5478530000)))/sqrt(1-(0.995785*0.995785)))/1.71099))+(0.0106936*(0.620714*TMath::Power(1+((x/29.189)*(x/29.189)),-(506.895)))))/(exp((((0.995785*x)-sqrt((x*x)+(0.1349770000*0.1349770000)))/sqrt(1-(0.995785*0.995785)))/1.71099)+(0.620714*TMath::Power(1+((x/29.189)*(x/29.189)),-(506.895)))))/2.))/(TMath::TwoPi()*x*(0*exp(-(sqrt(x*x+0.139571*0.139571)-0.139571)/0.1)+237.396*pow(exp(-0.450001*x-0.267691*x*x)+x/0.561352,-5.96452))))+(x>=0.4)*0.8*(((TMath::TwoPi()*x*(0*exp(-(sqrt(x*x+0.139571*0.139571)-0.139571)/0.1)+237.396*pow(exp(-0.450001*x-0.267691*x*x)+x/0.561352,-5.96452)))*((0.287493/(1+exp(-(x-0.381675)/0.227939))+-0.301666*TMath::Gaus(x,0.0639027,1.54263)+-0.0271521*TMath::Gaus(x,4.71408,1.51159)+0.274684+((0.550454*exp((((0.995785*x)-sqrt((x*x)+(0.5478530000*0.5478530000)))/sqrt(1-(0.995785*0.995785)))/1.71099))+(0.0106936*(0.620714*TMath::Power(1+((x/29.189)*(x/29.189)),-(506.895)))))/(exp((((0.995785*x)-sqrt((x*x)+(0.1349770000*0.1349770000)))/sqrt(1-(0.995785*0.995785)))/1.71099)+(0.620714*TMath::Power(1+((x/29.189)*(x/29.189)),-(506.895)))))/2.))/(TMath::TwoPi()*x*(0*exp(-(sqrt(x*x+0.139571*0.139571)-0.139571)/0.1)+237.396*pow(exp(-0.450001*x-0.267691*x*x)+x/0.561352,-5.96452)))))", + "113_pt": "(TMath::TwoPi()*x*(0*exp(-(sqrt(x*x+0.139571*0.139571)-0.139571)/0.1)+237.396*pow(exp(-0.450001*x-0.267691*x*x)+x/0.561352,-5.96452)))*((x>1.951)*(0.451114/(1+exp(-(x-0.707439)/0.374928))+-0.307087*TMath::Gaus(x,-0.577264,1.60957)+-0.20694*TMath::Gaus(x,-2.50098,4.31777)+0.337195)+(x<=1.951)*((((0.52988/(1+exp(-((x-0.303965)/0.287856))))+(-0.281848*TMath::Gaus(x,0.497102,0.688973)))+(-0.249068*TMath::Gaus(x,1.09157,1.16378)))+0.253347))", + "333_pt": "(TMath::TwoPi()*x*(0*exp(-(sqrt(x*x+0.139571*0.139571)-0.139571)/0.1)+237.396*pow(exp(-0.450001*x-0.267691*x*x)+x/0.561352,-5.96452)))*(0.8*(0.109761/(1+exp(-(x-1.3902)/1.35693))+-0.549036*TMath::Gaus(x,0.570177,1.69368)+0.441093*TMath::Gaus(x,0.836878,1.93285)+0.089258))" + }, + "5TeV_7080_wRatio_pi0corr": { + "histoMtScaleFactor": { + "113": 0.84, + "331": 0.4 + }, + "111_pt": "(TMath::TwoPi()*x*(0*exp(-(sqrt(x*x+0.139571*0.139571)-0.139571)/0.1)+116.441*pow(exp(-0.453438*x-0.157659*x*x)+x/0.569422,-6.02001)))/(7.18342e-01+(9.86860e-01-7.18342e-01)*(1-exp(-x/3.07386e-01)))", + "221_pt": "((TMath::TwoPi()*x*(0*exp(-(sqrt(x*x+0.139571*0.139571)-0.139571)/0.1)+116.441*pow(exp(-0.453438*x-0.157659*x*x)+x/0.569422,-6.02001)))/(7.18342e-01+(9.86860e-01-7.18342e-01)*(1-exp(-x/3.07386e-01))))*(((TMath::TwoPi()*x*(0*exp(-(sqrt(x*x+0.139571*0.139571)-0.139571)/0.1)+116.441*pow(exp(-0.453438*x-0.157659*x*x)+x/0.569422,-6.02001)))*((0.509043/(1+exp(-(x-0.37759)/0.335237))+-0.159762*TMath::Gaus(x,0.948373,1.33321)+-0.0429426*TMath::Gaus(x,2.4898,2.67569)+0.0428236+((0.550454*exp((((0.995785*x)-sqrt((x*x)+(0.5478530000*0.5478530000)))/sqrt(1-(0.995785*0.995785)))/1.71099))+(0.0106936*(0.620714*TMath::Power(1+((x/29.189)*(x/29.189)),-(506.895)))))/(exp((((0.995785*x)-sqrt((x*x)+(0.1349770000*0.1349770000)))/sqrt(1-(0.995785*0.995785)))/1.71099)+(0.620714*TMath::Power(1+((x/29.189)*(x/29.189)),-(506.895)))))/2.))/(TMath::TwoPi()*x*(0*exp(-(sqrt(x*x+0.139571*0.139571)-0.139571)/0.1)+116.441*pow(exp(-0.453438*x-0.157659*x*x)+x/0.569422,-6.02001))))", + "223_pt": "(TMath::TwoPi()*x*(0*exp(-(sqrt(x*x+0.139571*0.139571)-0.139571)/0.1)+116.441*pow(exp(-0.453438*x-0.157659*x*x)+x/0.569422,-6.02001)))*(0.324086/(1+exp(-(x-0.573304)/0.143352))+-0.106092*TMath::Gaus(x,0.857984,0.27756)+-0.35343*TMath::Gaus(x,-0.266188,-1.4987)+0.358613)", + "333_pt": "(TMath::TwoPi()*x*(0*exp(-(sqrt(x*x+0.139571*0.139571)-0.139571)/0.1)+116.441*pow(exp(-0.453438*x-0.157659*x*x)+x/0.569422,-6.02001)))*(0.0822258/(1+exp(-(x-1.07925)/1.16509))+-0.551967*TMath::Gaus(x,0.203349,1.77693)+0.438271*TMath::Gaus(x,0.266864,2.0576)+0.0913634)" + }, + "5TeV_7080_wRatio_pi0corrup": { + "histoMtScaleFactor": { + "113": 0.84, + "331": 0.4 + }, + "111_pt": "(TMath::TwoPi()*x*(0*exp(-(sqrt(x*x+0.139571*0.139571)-0.139571)/0.1)+116.441*pow(exp(-0.453438*x-0.157659*x*x)+x/0.569422,-6.02001)))/(7.18342e-01*0.95+(9.86860e-01-7.18342e-01*0.95)*(1-exp(-x/3.07386e-01)))", + "221_pt": "((TMath::TwoPi()*x*(0*exp(-(sqrt(x*x+0.139571*0.139571)-0.139571)/0.1)+116.441*pow(exp(-0.453438*x-0.157659*x*x)+x/0.569422,-6.02001)))/(7.18342e-01*0.95+(9.86860e-01-7.18342e-01*0.95)*(1-exp(-x/3.07386e-01))))*(((TMath::TwoPi()*x*(0*exp(-(sqrt(x*x+0.139571*0.139571)-0.139571)/0.1)+116.441*pow(exp(-0.453438*x-0.157659*x*x)+x/0.569422,-6.02001)))*((0.509043/(1+exp(-(x-0.37759)/0.335237))+-0.159762*TMath::Gaus(x,0.948373,1.33321)+-0.0429426*TMath::Gaus(x,2.4898,2.67569)+0.0428236+((0.550454*exp((((0.995785*x)-sqrt((x*x)+(0.5478530000*0.5478530000)))/sqrt(1-(0.995785*0.995785)))/1.71099))+(0.0106936*(0.620714*TMath::Power(1+((x/29.189)*(x/29.189)),-(506.895)))))/(exp((((0.995785*x)-sqrt((x*x)+(0.1349770000*0.1349770000)))/sqrt(1-(0.995785*0.995785)))/1.71099)+(0.620714*TMath::Power(1+((x/29.189)*(x/29.189)),-(506.895)))))/2.))/(TMath::TwoPi()*x*(0*exp(-(sqrt(x*x+0.139571*0.139571)-0.139571)/0.1)+116.441*pow(exp(-0.453438*x-0.157659*x*x)+x/0.569422,-6.02001))))", + "223_pt": "(TMath::TwoPi()*x*(0*exp(-(sqrt(x*x+0.139571*0.139571)-0.139571)/0.1)+116.441*pow(exp(-0.453438*x-0.157659*x*x)+x/0.569422,-6.02001)))*(0.324086/(1+exp(-(x-0.573304)/0.143352))+-0.106092*TMath::Gaus(x,0.857984,0.27756)+-0.35343*TMath::Gaus(x,-0.266188,-1.4987)+0.358613)", + "333_pt": "(TMath::TwoPi()*x*(0*exp(-(sqrt(x*x+0.139571*0.139571)-0.139571)/0.1)+116.441*pow(exp(-0.453438*x-0.157659*x*x)+x/0.569422,-6.02001)))*(0.0822258/(1+exp(-(x-1.07925)/1.16509))+-0.551967*TMath::Gaus(x,0.203349,1.77693)+0.438271*TMath::Gaus(x,0.266864,2.0576)+0.0913634)" + }, + "5TeV_7080_wRatio_pi0corrdown": { + "histoMtScaleFactor": { + "113": 0.84, + "331": 0.4 + }, + "111_pt": "(TMath::TwoPi()*x*(0*exp(-(sqrt(x*x+0.139571*0.139571)-0.139571)/0.1)+116.441*pow(exp(-0.453438*x-0.157659*x*x)+x/0.569422,-6.02001)))/(7.18342e-01*1.05+(9.86860e-01-7.18342e-01*1.05)*(1-exp(-x/3.07386e-01)))", + "221_pt": "((TMath::TwoPi()*x*(0*exp(-(sqrt(x*x+0.139571*0.139571)-0.139571)/0.1)+116.441*pow(exp(-0.453438*x-0.157659*x*x)+x/0.569422,-6.02001)))/(7.18342e-01*1.05+(9.86860e-01-7.18342e-01*1.05)*(1-exp(-x/3.07386e-01))))*(((TMath::TwoPi()*x*(0*exp(-(sqrt(x*x+0.139571*0.139571)-0.139571)/0.1)+116.441*pow(exp(-0.453438*x-0.157659*x*x)+x/0.569422,-6.02001)))*((0.509043/(1+exp(-(x-0.37759)/0.335237))+-0.159762*TMath::Gaus(x,0.948373,1.33321)+-0.0429426*TMath::Gaus(x,2.4898,2.67569)+0.0428236+((0.550454*exp((((0.995785*x)-sqrt((x*x)+(0.5478530000*0.5478530000)))/sqrt(1-(0.995785*0.995785)))/1.71099))+(0.0106936*(0.620714*TMath::Power(1+((x/29.189)*(x/29.189)),-(506.895)))))/(exp((((0.995785*x)-sqrt((x*x)+(0.1349770000*0.1349770000)))/sqrt(1-(0.995785*0.995785)))/1.71099)+(0.620714*TMath::Power(1+((x/29.189)*(x/29.189)),-(506.895)))))/2.))/(TMath::TwoPi()*x*(0*exp(-(sqrt(x*x+0.139571*0.139571)-0.139571)/0.1)+116.441*pow(exp(-0.453438*x-0.157659*x*x)+x/0.569422,-6.02001))))", + "223_pt": "(TMath::TwoPi()*x*(0*exp(-(sqrt(x*x+0.139571*0.139571)-0.139571)/0.1)+116.441*pow(exp(-0.453438*x-0.157659*x*x)+x/0.569422,-6.02001)))*(0.324086/(1+exp(-(x-0.573304)/0.143352))+-0.106092*TMath::Gaus(x,0.857984,0.27756)+-0.35343*TMath::Gaus(x,-0.266188,-1.4987)+0.358613)", + "333_pt": "(TMath::TwoPi()*x*(0*exp(-(sqrt(x*x+0.139571*0.139571)-0.139571)/0.1)+116.441*pow(exp(-0.453438*x-0.157659*x*x)+x/0.569422,-6.02001)))*(0.0822258/(1+exp(-(x-1.07925)/1.16509))+-0.551967*TMath::Gaus(x,0.203349,1.77693)+0.438271*TMath::Gaus(x,0.266864,2.0576)+0.0913634)" + }, + "5TeV_7080_wRatio_pi0corr_up": { + "histoMtScaleFactor": { + "113": 0.84, + "331": 0.4 + }, + "111_pt": "(TMath::TwoPi()*x*(0*exp(-(sqrt(x*x+0.139571*0.139571)-0.139571)/0.1)+126.267*pow(exp(-0.426848*x-0.209316*x*x)+x/0.559286,-5.99183)))/(7.18342e-01+(9.86860e-01-7.18342e-01)*(1-exp(-x/3.07386e-01)))", + "221_pt": "((TMath::TwoPi()*x*(0*exp(-(sqrt(x*x+0.139571*0.139571)-0.139571)/0.1)+126.267*pow(exp(-0.426848*x-0.209316*x*x)+x/0.559286,-5.99183)))/(7.18342e-01+(9.86860e-01-7.18342e-01)*(1-exp(-x/3.07386e-01))))*(((TMath::TwoPi()*x*(0*exp(-(sqrt(x*x+0.139571*0.139571)-0.139571)/0.1)+126.267*pow(exp(-0.426848*x-0.209316*x*x)+x/0.559286,-5.99183)))*((0.509043/(1+exp(-(x-0.37759)/0.335237))+-0.159762*TMath::Gaus(x,0.948373,1.33321)+-0.0429426*TMath::Gaus(x,2.4898,2.67569)+0.0428236+((0.550454*exp((((0.995785*x)-sqrt((x*x)+(0.5478530000*0.5478530000)))/sqrt(1-(0.995785*0.995785)))/1.71099))+(0.0106936*(0.620714*TMath::Power(1+((x/29.189)*(x/29.189)),-(506.895)))))/(exp((((0.995785*x)-sqrt((x*x)+(0.1349770000*0.1349770000)))/sqrt(1-(0.995785*0.995785)))/1.71099)+(0.620714*TMath::Power(1+((x/29.189)*(x/29.189)),-(506.895)))))/2.))/(TMath::TwoPi()*x*(0*exp(-(sqrt(x*x+0.139571*0.139571)-0.139571)/0.1)+126.267*pow(exp(-0.426848*x-0.209316*x*x)+x/0.559286,-5.99183))))", + "223_pt": "(TMath::TwoPi()*x*(0*exp(-(sqrt(x*x+0.139571*0.139571)-0.139571)/0.1)+126.267*pow(exp(-0.426848*x-0.209316*x*x)+x/0.559286,-5.99183)))*(0.324086/(1+exp(-(x-0.573304)/0.143352))+-0.106092*TMath::Gaus(x,0.857984,0.27756)+-0.35343*TMath::Gaus(x,-0.266188,-1.4987)+0.358613)", + "333_pt": "(TMath::TwoPi()*x*(0*exp(-(sqrt(x*x+0.139571*0.139571)-0.139571)/0.1)+126.267*pow(exp(-0.426848*x-0.209316*x*x)+x/0.559286,-5.99183)))*(0.0822258/(1+exp(-(x-1.07925)/1.16509))+-0.551967*TMath::Gaus(x,0.203349,1.77693)+0.438271*TMath::Gaus(x,0.266864,2.0576)+0.0913634)" + }, + "5TeV_7080_wRatio_pi0corr_down": { + "histoMtScaleFactor": { + "113": 0.84, + "331": 0.4 + }, + "111_pt": "(TMath::TwoPi()*x*(0*exp(-(sqrt(x*x+0.139571*0.139571)-0.139571)/0.1)+107.412*pow(exp(-0.472618*x-0.107443*x*x)+x/0.581829,-6.05744)))/(7.18342e-01+(9.86860e-01-7.18342e-01)*(1-exp(-x/3.07386e-01)))", + "221_pt": "((TMath::TwoPi()*x*(0*exp(-(sqrt(x*x+0.139571*0.139571)-0.139571)/0.1)+107.412*pow(exp(-0.472618*x-0.107443*x*x)+x/0.581829,-6.05744)))/(7.18342e-01+(9.86860e-01-7.18342e-01)*(1-exp(-x/3.07386e-01))))*(((TMath::TwoPi()*x*(0*exp(-(sqrt(x*x+0.139571*0.139571)-0.139571)/0.1)+107.412*pow(exp(-0.472618*x-0.107443*x*x)+x/0.581829,-6.05744)))*((0.509043/(1+exp(-(x-0.37759)/0.335237))+-0.159762*TMath::Gaus(x,0.948373,1.33321)+-0.0429426*TMath::Gaus(x,2.4898,2.67569)+0.0428236+((0.550454*exp((((0.995785*x)-sqrt((x*x)+(0.5478530000*0.5478530000)))/sqrt(1-(0.995785*0.995785)))/1.71099))+(0.0106936*(0.620714*TMath::Power(1+((x/29.189)*(x/29.189)),-(506.895)))))/(exp((((0.995785*x)-sqrt((x*x)+(0.1349770000*0.1349770000)))/sqrt(1-(0.995785*0.995785)))/1.71099)+(0.620714*TMath::Power(1+((x/29.189)*(x/29.189)),-(506.895)))))/2.))/(TMath::TwoPi()*x*(0*exp(-(sqrt(x*x+0.139571*0.139571)-0.139571)/0.1)+107.412*pow(exp(-0.472618*x-0.107443*x*x)+x/0.581829,-6.05744))))", + "223_pt": "(TMath::TwoPi()*x*(0*exp(-(sqrt(x*x+0.139571*0.139571)-0.139571)/0.1)+107.412*pow(exp(-0.472618*x-0.107443*x*x)+x/0.581829,-6.05744)))*(0.324086/(1+exp(-(x-0.573304)/0.143352))+-0.106092*TMath::Gaus(x,0.857984,0.27756)+-0.35343*TMath::Gaus(x,-0.266188,-1.4987)+0.358613)", + "333_pt": "(TMath::TwoPi()*x*(0*exp(-(sqrt(x*x+0.139571*0.139571)-0.139571)/0.1)+107.412*pow(exp(-0.472618*x-0.107443*x*x)+x/0.581829,-6.05744)))*(0.0822258/(1+exp(-(x-1.07925)/1.16509))+-0.551967*TMath::Gaus(x,0.203349,1.77693)+0.438271*TMath::Gaus(x,0.266864,2.0576)+0.0913634)" + }, + "5TeV_7080_wRatio_pi0corr_ratiosup": { + "histoMtScaleFactor": { + "113": 1.01, + "331": 0.48 + }, + "111_pt": "(TMath::TwoPi()*x*(0*exp(-(sqrt(x*x+0.139571*0.139571)-0.139571)/0.1)+116.441*pow(exp(-0.453438*x-0.157659*x*x)+x/0.569422,-6.02001)))/(7.18342e-01+(9.86860e-01-7.18342e-01)*(1-exp(-x/3.07386e-01)))", + "221_pt": "((TMath::TwoPi()*x*(0*exp(-(sqrt(x*x+0.139571*0.139571)-0.139571)/0.1)+116.441*pow(exp(-0.453438*x-0.157659*x*x)+x/0.569422,-6.02001)))/(7.18342e-01+(9.86860e-01-7.18342e-01)*(1-exp(-x/3.07386e-01))))*(((x<0.25)*(1.5*(1-0.8*x)))*(((TMath::TwoPi()*x*(0*exp(-(sqrt(x*x+0.139571*0.139571)-0.139571)/0.1)+116.441*pow(exp(-0.453438*x-0.157659*x*x)+x/0.569422,-6.02001)))*((0.509043/(1+exp(-(x-0.37759)/0.335237))+-0.159762*TMath::Gaus(x,0.948373,1.33321)+-0.0429426*TMath::Gaus(x,2.4898,2.67569)+0.0428236+((0.550454*exp((((0.995785*x)-sqrt((x*x)+(0.5478530000*0.5478530000)))/sqrt(1-(0.995785*0.995785)))/1.71099))+(0.0106936*(0.620714*TMath::Power(1+((x/29.189)*(x/29.189)),-(506.895)))))/(exp((((0.995785*x)-sqrt((x*x)+(0.1349770000*0.1349770000)))/sqrt(1-(0.995785*0.995785)))/1.71099)+(0.620714*TMath::Power(1+((x/29.189)*(x/29.189)),-(506.895)))))/2.))/(TMath::TwoPi()*x*(0*exp(-(sqrt(x*x+0.139571*0.139571)-0.139571)/0.1)+116.441*pow(exp(-0.453438*x-0.157659*x*x)+x/0.569422,-6.02001))))+(x>=0.25)*1.2*(((TMath::TwoPi()*x*(0*exp(-(sqrt(x*x+0.139571*0.139571)-0.139571)/0.1)+116.441*pow(exp(-0.453438*x-0.157659*x*x)+x/0.569422,-6.02001)))*((0.509043/(1+exp(-(x-0.37759)/0.335237))+-0.159762*TMath::Gaus(x,0.948373,1.33321)+-0.0429426*TMath::Gaus(x,2.4898,2.67569)+0.0428236+((0.550454*exp((((0.995785*x)-sqrt((x*x)+(0.5478530000*0.5478530000)))/sqrt(1-(0.995785*0.995785)))/1.71099))+(0.0106936*(0.620714*TMath::Power(1+((x/29.189)*(x/29.189)),-(506.895)))))/(exp((((0.995785*x)-sqrt((x*x)+(0.1349770000*0.1349770000)))/sqrt(1-(0.995785*0.995785)))/1.71099)+(0.620714*TMath::Power(1+((x/29.189)*(x/29.189)),-(506.895)))))/2.))/(TMath::TwoPi()*x*(0*exp(-(sqrt(x*x+0.139571*0.139571)-0.139571)/0.1)+116.441*pow(exp(-0.453438*x-0.157659*x*x)+x/0.569422,-6.02001)))))", + "223_pt": "(TMath::TwoPi()*x*(0*exp(-(sqrt(x*x+0.139571*0.139571)-0.139571)/0.1)+116.441*pow(exp(-0.453438*x-0.157659*x*x)+x/0.569422,-6.02001)))*(((x<0.25)*(1.5*(1-0.8*x)))*(0.324086/(1+exp(-(x-0.573304)/0.143352))+-0.106092*TMath::Gaus(x,0.857984,0.27756)+-0.35343*TMath::Gaus(x,-0.266188,-1.4987)+0.358613)+((x>=0.25)*1.2*(0.324086/(1+exp(-(x-0.573304)/0.143352))+-0.106092*TMath::Gaus(x,0.857984,0.27756)+-0.35343*TMath::Gaus(x,-0.266188,-1.4987)+0.358613)))", + "333_pt": "(TMath::TwoPi()*x*(0*exp(-(sqrt(x*x+0.139571*0.139571)-0.139571)/0.1)+116.441*pow(exp(-0.453438*x-0.157659*x*x)+x/0.569422,-6.02001)))*(1.2*(0.0822258/(1+exp(-(x-1.07925)/1.16509))+-0.551967*TMath::Gaus(x,0.203349,1.77693)+0.438271*TMath::Gaus(x,0.266864,2.0576)+0.0913634))" + }, + "5TeV_7080_wRatio_pi0corr_ratiosdown": { + "histoMtScaleFactor": { + "223": 0.62, + "331": 0.32 + }, + "111_pt": "(TMath::TwoPi()*x*(0*exp(-(sqrt(x*x+0.139571*0.139571)-0.139571)/0.1)+116.441*pow(exp(-0.453438*x-0.157659*x*x)+x/0.569422,-6.02001)))/(7.18342e-01+(9.86860e-01-7.18342e-01)*(1-exp(-x/3.07386e-01)))", + "221_pt": "((TMath::TwoPi()*x*(0*exp(-(sqrt(x*x+0.139571*0.139571)-0.139571)/0.1)+116.441*pow(exp(-0.453438*x-0.157659*x*x)+x/0.569422,-6.02001)))/(7.18342e-01+(9.86860e-01-7.18342e-01)*(1-exp(-x/3.07386e-01))))*(((x<0.4)*(0.4*(1+2.5*x)))*(((TMath::TwoPi()*x*(0*exp(-(sqrt(x*x+0.139571*0.139571)-0.139571)/0.1)+116.441*pow(exp(-0.453438*x-0.157659*x*x)+x/0.569422,-6.02001)))*((0.509043/(1+exp(-(x-0.37759)/0.335237))+-0.159762*TMath::Gaus(x,0.948373,1.33321)+-0.0429426*TMath::Gaus(x,2.4898,2.67569)+0.0428236+((0.550454*exp((((0.995785*x)-sqrt((x*x)+(0.5478530000*0.5478530000)))/sqrt(1-(0.995785*0.995785)))/1.71099))+(0.0106936*(0.620714*TMath::Power(1+((x/29.189)*(x/29.189)),-(506.895)))))/(exp((((0.995785*x)-sqrt((x*x)+(0.1349770000*0.1349770000)))/sqrt(1-(0.995785*0.995785)))/1.71099)+(0.620714*TMath::Power(1+((x/29.189)*(x/29.189)),-(506.895)))))/2.))/(TMath::TwoPi()*x*(0*exp(-(sqrt(x*x+0.139571*0.139571)-0.139571)/0.1)+116.441*pow(exp(-0.453438*x-0.157659*x*x)+x/0.569422,-6.02001))))+(x>=0.4)*0.8*(((TMath::TwoPi()*x*(0*exp(-(sqrt(x*x+0.139571*0.139571)-0.139571)/0.1)+116.441*pow(exp(-0.453438*x-0.157659*x*x)+x/0.569422,-6.02001)))*((0.509043/(1+exp(-(x-0.37759)/0.335237))+-0.159762*TMath::Gaus(x,0.948373,1.33321)+-0.0429426*TMath::Gaus(x,2.4898,2.67569)+0.0428236+((0.550454*exp((((0.995785*x)-sqrt((x*x)+(0.5478530000*0.5478530000)))/sqrt(1-(0.995785*0.995785)))/1.71099))+(0.0106936*(0.620714*TMath::Power(1+((x/29.189)*(x/29.189)),-(506.895)))))/(exp((((0.995785*x)-sqrt((x*x)+(0.1349770000*0.1349770000)))/sqrt(1-(0.995785*0.995785)))/1.71099)+(0.620714*TMath::Power(1+((x/29.189)*(x/29.189)),-(506.895)))))/2.))/(TMath::TwoPi()*x*(0*exp(-(sqrt(x*x+0.139571*0.139571)-0.139571)/0.1)+116.441*pow(exp(-0.453438*x-0.157659*x*x)+x/0.569422,-6.02001)))))", + "113_pt": "(TMath::TwoPi()*x*(0*exp(-(sqrt(x*x+0.139571*0.139571)-0.139571)/0.1)+116.441*pow(exp(-0.453438*x-0.157659*x*x)+x/0.569422,-6.02001)))*((x>1.951)*(0.451114/(1+exp(-(x-0.707439)/0.374928))+-0.307087*TMath::Gaus(x,-0.577264,1.60957)+-0.20694*TMath::Gaus(x,-2.50098,4.31777)+0.337195)+(x<=1.951)*((((0.52988/(1+exp(-((x-0.303965)/0.287856))))+(-0.281848*TMath::Gaus(x,0.497102,0.688973)))+(-0.249068*TMath::Gaus(x,1.09157,1.16378)))+0.253347))", + "333_pt": "(TMath::TwoPi()*x*(0*exp(-(sqrt(x*x+0.139571*0.139571)-0.139571)/0.1)+116.441*pow(exp(-0.453438*x-0.157659*x*x)+x/0.569422,-6.02001)))*(0.8*(0.0822258/(1+exp(-(x-1.07925)/1.16509))+-0.551967*TMath::Gaus(x,0.203349,1.77693)+0.438271*TMath::Gaus(x,0.266864,2.0576)+0.0913634))" + }, + "5TeV_8090_wRatio_pi0corr": { + "histoMtScaleFactor": { + "113": 0.84, + "331": 0.4 + }, + "111_pt": "(TMath::TwoPi()*x*(0*exp(-(sqrt(x*x+0.139571*0.139571)-0.139571)/0.1)+44.8976*pow(exp(-0.491415*x-0.0563088*x*x)+x/0.585056,-6.11751)))/(7.18342e-01+(9.86860e-01-7.18342e-01)*(1-exp(-x/3.07386e-01)))", + "221_pt": "((TMath::TwoPi()*x*(0*exp(-(sqrt(x*x+0.139571*0.139571)-0.139571)/0.1)+44.8976*pow(exp(-0.491415*x-0.0563088*x*x)+x/0.585056,-6.11751)))/(7.18342e-01+(9.86860e-01-7.18342e-01)*(1-exp(-x/3.07386e-01))))*(((TMath::TwoPi()*x*(0*exp(-(sqrt(x*x+0.139571*0.139571)-0.139571)/0.1)+44.8976*pow(exp(-0.491415*x-0.0563088*x*x)+x/0.585056,-6.11751)))*((0.401729/(1+exp(-(x-0.329328)/0.283064))+-0.165522*TMath::Gaus(x,0.572808,1.12455)+-0.098106*TMath::Gaus(x,1.55187,2.85629)+0.154946+((0.550454*exp((((0.995785*x)-sqrt((x*x)+(0.5478530000*0.5478530000)))/sqrt(1-(0.995785*0.995785)))/1.71099))+(0.0106936*(0.620714*TMath::Power(1+((x/29.189)*(x/29.189)),-(506.895)))))/(exp((((0.995785*x)-sqrt((x*x)+(0.1349770000*0.1349770000)))/sqrt(1-(0.995785*0.995785)))/1.71099)+(0.620714*TMath::Power(1+((x/29.189)*(x/29.189)),-(506.895)))))/2.))/(TMath::TwoPi()*x*(0*exp(-(sqrt(x*x+0.139571*0.139571)-0.139571)/0.1)+44.8976*pow(exp(-0.491415*x-0.0563088*x*x)+x/0.585056,-6.11751))))", + "223_pt": "(TMath::TwoPi()*x*(0*exp(-(sqrt(x*x+0.139571*0.139571)-0.139571)/0.1)+44.8976*pow(exp(-0.491415*x-0.0563088*x*x)+x/0.585056,-6.11751)))*(0.324086/(1+exp(-(x-0.573304)/0.143352))+-0.106092*TMath::Gaus(x,0.857984,0.27756)+-0.35343*TMath::Gaus(x,-0.266188,-1.4987)+0.358613)", + "333_pt": "(TMath::TwoPi()*x*(0*exp(-(sqrt(x*x+0.139571*0.139571)-0.139571)/0.1)+44.8976*pow(exp(-0.491415*x-0.0563088*x*x)+x/0.585056,-6.11751)))*(0.105659/(1+exp(-(x-0.781147)/3.13076))+-0.564081*TMath::Gaus(x,-0.134319,1.22474)+0.426234*TMath::Gaus(x,-0.173703,1.17147)+0.093734)" + }, + "5TeV_8090_wRatio_pi0corrup": { + "histoMtScaleFactor": { + "113": 0.84, + "331": 0.4 + }, + "111_pt": "(TMath::TwoPi()*x*(0*exp(-(sqrt(x*x+0.139571*0.139571)-0.139571)/0.1)+44.8976*pow(exp(-0.491415*x-0.0563088*x*x)+x/0.585056,-6.11751)))/(7.18342e-01*0.95+(9.86860e-01-7.18342e-01*0.95)*(1-exp(-x/3.07386e-01)))", + "221_pt": "((TMath::TwoPi()*x*(0*exp(-(sqrt(x*x+0.139571*0.139571)-0.139571)/0.1)+44.8976*pow(exp(-0.491415*x-0.0563088*x*x)+x/0.585056,-6.11751)))/(7.18342e-01*0.95+(9.86860e-01-7.18342e-01*0.95)*(1-exp(-x/3.07386e-01))))*(((TMath::TwoPi()*x*(0*exp(-(sqrt(x*x+0.139571*0.139571)-0.139571)/0.1)+44.8976*pow(exp(-0.491415*x-0.0563088*x*x)+x/0.585056,-6.11751)))*((0.401729/(1+exp(-(x-0.329328)/0.283064))+-0.165522*TMath::Gaus(x,0.572808,1.12455)+-0.098106*TMath::Gaus(x,1.55187,2.85629)+0.154946+((0.550454*exp((((0.995785*x)-sqrt((x*x)+(0.5478530000*0.5478530000)))/sqrt(1-(0.995785*0.995785)))/1.71099))+(0.0106936*(0.620714*TMath::Power(1+((x/29.189)*(x/29.189)),-(506.895)))))/(exp((((0.995785*x)-sqrt((x*x)+(0.1349770000*0.1349770000)))/sqrt(1-(0.995785*0.995785)))/1.71099)+(0.620714*TMath::Power(1+((x/29.189)*(x/29.189)),-(506.895)))))/2.))/(TMath::TwoPi()*x*(0*exp(-(sqrt(x*x+0.139571*0.139571)-0.139571)/0.1)+44.8976*pow(exp(-0.491415*x-0.0563088*x*x)+x/0.585056,-6.11751))))", + "223_pt": "(TMath::TwoPi()*x*(0*exp(-(sqrt(x*x+0.139571*0.139571)-0.139571)/0.1)+44.8976*pow(exp(-0.491415*x-0.0563088*x*x)+x/0.585056,-6.11751)))*(0.324086/(1+exp(-(x-0.573304)/0.143352))+-0.106092*TMath::Gaus(x,0.857984,0.27756)+-0.35343*TMath::Gaus(x,-0.266188,-1.4987)+0.358613)", + "333_pt": "(TMath::TwoPi()*x*(0*exp(-(sqrt(x*x+0.139571*0.139571)-0.139571)/0.1)+44.8976*pow(exp(-0.491415*x-0.0563088*x*x)+x/0.585056,-6.11751)))*(0.105659/(1+exp(-(x-0.781147)/3.13076))+-0.564081*TMath::Gaus(x,-0.134319,1.22474)+0.426234*TMath::Gaus(x,-0.173703,1.17147)+0.093734)" + }, + "5TeV_8090_wRatio_pi0corrdown": { + "histoMtScaleFactor": { + "113": 0.84, + "331": 0.4 + }, + "111_pt": "(TMath::TwoPi()*x*(0*exp(-(sqrt(x*x+0.139571*0.139571)-0.139571)/0.1)+44.8976*pow(exp(-0.491415*x-0.0563088*x*x)+x/0.585056,-6.11751)))/(7.18342e-01*1.05+(9.86860e-01-7.18342e-01*1.05)*(1-exp(-x/3.07386e-01)))", + "221_pt": "((TMath::TwoPi()*x*(0*exp(-(sqrt(x*x+0.139571*0.139571)-0.139571)/0.1)+44.8976*pow(exp(-0.491415*x-0.0563088*x*x)+x/0.585056,-6.11751)))/(7.18342e-01*1.05+(9.86860e-01-7.18342e-01*1.05)*(1-exp(-x/3.07386e-01))))*(((TMath::TwoPi()*x*(0*exp(-(sqrt(x*x+0.139571*0.139571)-0.139571)/0.1)+44.8976*pow(exp(-0.491415*x-0.0563088*x*x)+x/0.585056,-6.11751)))*((0.401729/(1+exp(-(x-0.329328)/0.283064))+-0.165522*TMath::Gaus(x,0.572808,1.12455)+-0.098106*TMath::Gaus(x,1.55187,2.85629)+0.154946+((0.550454*exp((((0.995785*x)-sqrt((x*x)+(0.5478530000*0.5478530000)))/sqrt(1-(0.995785*0.995785)))/1.71099))+(0.0106936*(0.620714*TMath::Power(1+((x/29.189)*(x/29.189)),-(506.895)))))/(exp((((0.995785*x)-sqrt((x*x)+(0.1349770000*0.1349770000)))/sqrt(1-(0.995785*0.995785)))/1.71099)+(0.620714*TMath::Power(1+((x/29.189)*(x/29.189)),-(506.895)))))/2.))/(TMath::TwoPi()*x*(0*exp(-(sqrt(x*x+0.139571*0.139571)-0.139571)/0.1)+44.8976*pow(exp(-0.491415*x-0.0563088*x*x)+x/0.585056,-6.11751))))", + "223_pt": "(TMath::TwoPi()*x*(0*exp(-(sqrt(x*x+0.139571*0.139571)-0.139571)/0.1)+44.8976*pow(exp(-0.491415*x-0.0563088*x*x)+x/0.585056,-6.11751)))*(0.324086/(1+exp(-(x-0.573304)/0.143352))+-0.106092*TMath::Gaus(x,0.857984,0.27756)+-0.35343*TMath::Gaus(x,-0.266188,-1.4987)+0.358613)", + "333_pt": "(TMath::TwoPi()*x*(0*exp(-(sqrt(x*x+0.139571*0.139571)-0.139571)/0.1)+44.8976*pow(exp(-0.491415*x-0.0563088*x*x)+x/0.585056,-6.11751)))*(0.105659/(1+exp(-(x-0.781147)/3.13076))+-0.564081*TMath::Gaus(x,-0.134319,1.22474)+0.426234*TMath::Gaus(x,-0.173703,1.17147)+0.093734)" + }, + "5TeV_8090_wRatio_pi0corr_up": { + "histoMtScaleFactor": { + "113": 0.84, + "331": 0.4 + }, + "111_pt": "(TMath::TwoPi()*x*(0*exp(-(sqrt(x*x+0.139571*0.139571)-0.139571)/0.1)+48.3871*pow(exp(-0.489465*x-0.105892*x*x)+x/0.566265,-6.04512)))/(7.18342e-01+(9.86860e-01-7.18342e-01)*(1-exp(-x/3.07386e-01)))", + "221_pt": "((TMath::TwoPi()*x*(0*exp(-(sqrt(x*x+0.139571*0.139571)-0.139571)/0.1)+48.3871*pow(exp(-0.489465*x-0.105892*x*x)+x/0.566265,-6.04512)))/(7.18342e-01+(9.86860e-01-7.18342e-01)*(1-exp(-x/3.07386e-01))))*(((TMath::TwoPi()*x*(0*exp(-(sqrt(x*x+0.139571*0.139571)-0.139571)/0.1)+48.3871*pow(exp(-0.489465*x-0.105892*x*x)+x/0.566265,-6.04512)))*((0.401729/(1+exp(-(x-0.329328)/0.283064))+-0.165522*TMath::Gaus(x,0.572808,1.12455)+-0.098106*TMath::Gaus(x,1.55187,2.85629)+0.154946+((0.550454*exp((((0.995785*x)-sqrt((x*x)+(0.5478530000*0.5478530000)))/sqrt(1-(0.995785*0.995785)))/1.71099))+(0.0106936*(0.620714*TMath::Power(1+((x/29.189)*(x/29.189)),-(506.895)))))/(exp((((0.995785*x)-sqrt((x*x)+(0.1349770000*0.1349770000)))/sqrt(1-(0.995785*0.995785)))/1.71099)+(0.620714*TMath::Power(1+((x/29.189)*(x/29.189)),-(506.895)))))/2.))/(TMath::TwoPi()*x*(0*exp(-(sqrt(x*x+0.139571*0.139571)-0.139571)/0.1)+48.3871*pow(exp(-0.489465*x-0.105892*x*x)+x/0.566265,-6.04512))))", + "223_pt": "(TMath::TwoPi()*x*(0*exp(-(sqrt(x*x+0.139571*0.139571)-0.139571)/0.1)+48.3871*pow(exp(-0.489465*x-0.105892*x*x)+x/0.566265,-6.04512)))*(0.324086/(1+exp(-(x-0.573304)/0.143352))+-0.106092*TMath::Gaus(x,0.857984,0.27756)+-0.35343*TMath::Gaus(x,-0.266188,-1.4987)+0.358613)", + "333_pt": "(TMath::TwoPi()*x*(0*exp(-(sqrt(x*x+0.139571*0.139571)-0.139571)/0.1)+48.3871*pow(exp(-0.489465*x-0.105892*x*x)+x/0.566265,-6.04512)))*(0.105659/(1+exp(-(x-0.781147)/3.13076))+-0.564081*TMath::Gaus(x,-0.134319,1.22474)+0.426234*TMath::Gaus(x,-0.173703,1.17147)+0.093734)" + }, + "5TeV_8090_wRatio_pi0corr_down": { + "histoMtScaleFactor": { + "113": 0.84, + "331": 0.4 + }, + "111_pt": "(TMath::TwoPi()*x*(0*exp(-(sqrt(x*x+0.139571*0.139571)-0.139571)/0.1)+41.8184*pow(exp(-0.45903*x-0.00764471*x*x)+x/0.618416,-6.24444)))/(7.18342e-01+(9.86860e-01-7.18342e-01)*(1-exp(-x/3.07386e-01)))", + "221_pt": "((TMath::TwoPi()*x*(0*exp(-(sqrt(x*x+0.139571*0.139571)-0.139571)/0.1)+41.8184*pow(exp(-0.45903*x-0.00764471*x*x)+x/0.618416,-6.24444)))/(7.18342e-01+(9.86860e-01-7.18342e-01)*(1-exp(-x/3.07386e-01))))*(((TMath::TwoPi()*x*(0*exp(-(sqrt(x*x+0.139571*0.139571)-0.139571)/0.1)+41.8184*pow(exp(-0.45903*x-0.00764471*x*x)+x/0.618416,-6.24444)))*((0.401729/(1+exp(-(x-0.329328)/0.283064))+-0.165522*TMath::Gaus(x,0.572808,1.12455)+-0.098106*TMath::Gaus(x,1.55187,2.85629)+0.154946+((0.550454*exp((((0.995785*x)-sqrt((x*x)+(0.5478530000*0.5478530000)))/sqrt(1-(0.995785*0.995785)))/1.71099))+(0.0106936*(0.620714*TMath::Power(1+((x/29.189)*(x/29.189)),-(506.895)))))/(exp((((0.995785*x)-sqrt((x*x)+(0.1349770000*0.1349770000)))/sqrt(1-(0.995785*0.995785)))/1.71099)+(0.620714*TMath::Power(1+((x/29.189)*(x/29.189)),-(506.895)))))/2.))/(TMath::TwoPi()*x*(0*exp(-(sqrt(x*x+0.139571*0.139571)-0.139571)/0.1)+41.8184*pow(exp(-0.45903*x-0.00764471*x*x)+x/0.618416,-6.24444))))", + "223_pt": "(TMath::TwoPi()*x*(0*exp(-(sqrt(x*x+0.139571*0.139571)-0.139571)/0.1)+41.8184*pow(exp(-0.45903*x-0.00764471*x*x)+x/0.618416,-6.24444)))*(0.324086/(1+exp(-(x-0.573304)/0.143352))+-0.106092*TMath::Gaus(x,0.857984,0.27756)+-0.35343*TMath::Gaus(x,-0.266188,-1.4987)+0.358613)", + "333_pt": "(TMath::TwoPi()*x*(0*exp(-(sqrt(x*x+0.139571*0.139571)-0.139571)/0.1)+41.8184*pow(exp(-0.45903*x-0.00764471*x*x)+x/0.618416,-6.24444)))*(0.105659/(1+exp(-(x-0.781147)/3.13076))+-0.564081*TMath::Gaus(x,-0.134319,1.22474)+0.426234*TMath::Gaus(x,-0.173703,1.17147)+0.093734)" + }, + "5TeV_8090_wRatio_pi0corr_ratiosup": { + "histoMtScaleFactor": { + "113": 1.01, + "331": 0.48 + }, + "111_pt": "(TMath::TwoPi()*x*(0*exp(-(sqrt(x*x+0.139571*0.139571)-0.139571)/0.1)+44.8976*pow(exp(-0.491415*x-0.0563088*x*x)+x/0.585056,-6.11751)))/(7.18342e-01+(9.86860e-01-7.18342e-01)*(1-exp(-x/3.07386e-01)))", + "221_pt": "((TMath::TwoPi()*x*(0*exp(-(sqrt(x*x+0.139571*0.139571)-0.139571)/0.1)+44.8976*pow(exp(-0.491415*x-0.0563088*x*x)+x/0.585056,-6.11751)))/(7.18342e-01+(9.86860e-01-7.18342e-01)*(1-exp(-x/3.07386e-01))))*(((x<0.25)*(1.5*(1-0.8*x)))*(((TMath::TwoPi()*x*(0*exp(-(sqrt(x*x+0.139571*0.139571)-0.139571)/0.1)+44.8976*pow(exp(-0.491415*x-0.0563088*x*x)+x/0.585056,-6.11751)))*((0.401729/(1+exp(-(x-0.329328)/0.283064))+-0.165522*TMath::Gaus(x,0.572808,1.12455)+-0.098106*TMath::Gaus(x,1.55187,2.85629)+0.154946+((0.550454*exp((((0.995785*x)-sqrt((x*x)+(0.5478530000*0.5478530000)))/sqrt(1-(0.995785*0.995785)))/1.71099))+(0.0106936*(0.620714*TMath::Power(1+((x/29.189)*(x/29.189)),-(506.895)))))/(exp((((0.995785*x)-sqrt((x*x)+(0.1349770000*0.1349770000)))/sqrt(1-(0.995785*0.995785)))/1.71099)+(0.620714*TMath::Power(1+((x/29.189)*(x/29.189)),-(506.895)))))/2.))/(TMath::TwoPi()*x*(0*exp(-(sqrt(x*x+0.139571*0.139571)-0.139571)/0.1)+44.8976*pow(exp(-0.491415*x-0.0563088*x*x)+x/0.585056,-6.11751))))+(x>=0.25)*1.2*(((TMath::TwoPi()*x*(0*exp(-(sqrt(x*x+0.139571*0.139571)-0.139571)/0.1)+44.8976*pow(exp(-0.491415*x-0.0563088*x*x)+x/0.585056,-6.11751)))*((0.401729/(1+exp(-(x-0.329328)/0.283064))+-0.165522*TMath::Gaus(x,0.572808,1.12455)+-0.098106*TMath::Gaus(x,1.55187,2.85629)+0.154946+((0.550454*exp((((0.995785*x)-sqrt((x*x)+(0.5478530000*0.5478530000)))/sqrt(1-(0.995785*0.995785)))/1.71099))+(0.0106936*(0.620714*TMath::Power(1+((x/29.189)*(x/29.189)),-(506.895)))))/(exp((((0.995785*x)-sqrt((x*x)+(0.1349770000*0.1349770000)))/sqrt(1-(0.995785*0.995785)))/1.71099)+(0.620714*TMath::Power(1+((x/29.189)*(x/29.189)),-(506.895)))))/2.))/(TMath::TwoPi()*x*(0*exp(-(sqrt(x*x+0.139571*0.139571)-0.139571)/0.1)+44.8976*pow(exp(-0.491415*x-0.0563088*x*x)+x/0.585056,-6.11751)))))", + "223_pt": "(TMath::TwoPi()*x*(0*exp(-(sqrt(x*x+0.139571*0.139571)-0.139571)/0.1)+44.8976*pow(exp(-0.491415*x-0.0563088*x*x)+x/0.585056,-6.11751)))*(((x<0.25)*(1.5*(1-0.8*x)))*(0.324086/(1+exp(-(x-0.573304)/0.143352))+-0.106092*TMath::Gaus(x,0.857984,0.27756)+-0.35343*TMath::Gaus(x,-0.266188,-1.4987)+0.358613)+((x>=0.25)*1.2*(0.324086/(1+exp(-(x-0.573304)/0.143352))+-0.106092*TMath::Gaus(x,0.857984,0.27756)+-0.35343*TMath::Gaus(x,-0.266188,-1.4987)+0.358613)))", + "333_pt": "(TMath::TwoPi()*x*(0*exp(-(sqrt(x*x+0.139571*0.139571)-0.139571)/0.1)+44.8976*pow(exp(-0.491415*x-0.0563088*x*x)+x/0.585056,-6.11751)))*(1.2*(0.105659/(1+exp(-(x-0.781147)/3.13076))+-0.564081*TMath::Gaus(x,-0.134319,1.22474)+0.426234*TMath::Gaus(x,-0.173703,1.17147)+0.093734))" + }, + "5TeV_8090_wRatio_pi0corr_ratiosdown": { + "histoMtScaleFactor": { + "223": 0.62, + "331": 0.32 + }, + "111_pt": "(TMath::TwoPi()*x*(0*exp(-(sqrt(x*x+0.139571*0.139571)-0.139571)/0.1)+44.8976*pow(exp(-0.491415*x-0.0563088*x*x)+x/0.585056,-6.11751)))/(7.18342e-01+(9.86860e-01-7.18342e-01)*(1-exp(-x/3.07386e-01)))", + "221_pt": "((TMath::TwoPi()*x*(0*exp(-(sqrt(x*x+0.139571*0.139571)-0.139571)/0.1)+44.8976*pow(exp(-0.491415*x-0.0563088*x*x)+x/0.585056,-6.11751)))/(7.18342e-01+(9.86860e-01-7.18342e-01)*(1-exp(-x/3.07386e-01))))*(((x<0.4)*(0.4*(1+2.5*x)))*(((TMath::TwoPi()*x*(0*exp(-(sqrt(x*x+0.139571*0.139571)-0.139571)/0.1)+44.8976*pow(exp(-0.491415*x-0.0563088*x*x)+x/0.585056,-6.11751)))*((0.401729/(1+exp(-(x-0.329328)/0.283064))+-0.165522*TMath::Gaus(x,0.572808,1.12455)+-0.098106*TMath::Gaus(x,1.55187,2.85629)+0.154946+((0.550454*exp((((0.995785*x)-sqrt((x*x)+(0.5478530000*0.5478530000)))/sqrt(1-(0.995785*0.995785)))/1.71099))+(0.0106936*(0.620714*TMath::Power(1+((x/29.189)*(x/29.189)),-(506.895)))))/(exp((((0.995785*x)-sqrt((x*x)+(0.1349770000*0.1349770000)))/sqrt(1-(0.995785*0.995785)))/1.71099)+(0.620714*TMath::Power(1+((x/29.189)*(x/29.189)),-(506.895)))))/2.))/(TMath::TwoPi()*x*(0*exp(-(sqrt(x*x+0.139571*0.139571)-0.139571)/0.1)+44.8976*pow(exp(-0.491415*x-0.0563088*x*x)+x/0.585056,-6.11751))))+(x>=0.4)*0.8*(((TMath::TwoPi()*x*(0*exp(-(sqrt(x*x+0.139571*0.139571)-0.139571)/0.1)+44.8976*pow(exp(-0.491415*x-0.0563088*x*x)+x/0.585056,-6.11751)))*((0.401729/(1+exp(-(x-0.329328)/0.283064))+-0.165522*TMath::Gaus(x,0.572808,1.12455)+-0.098106*TMath::Gaus(x,1.55187,2.85629)+0.154946+((0.550454*exp((((0.995785*x)-sqrt((x*x)+(0.5478530000*0.5478530000)))/sqrt(1-(0.995785*0.995785)))/1.71099))+(0.0106936*(0.620714*TMath::Power(1+((x/29.189)*(x/29.189)),-(506.895)))))/(exp((((0.995785*x)-sqrt((x*x)+(0.1349770000*0.1349770000)))/sqrt(1-(0.995785*0.995785)))/1.71099)+(0.620714*TMath::Power(1+((x/29.189)*(x/29.189)),-(506.895)))))/2.))/(TMath::TwoPi()*x*(0*exp(-(sqrt(x*x+0.139571*0.139571)-0.139571)/0.1)+44.8976*pow(exp(-0.491415*x-0.0563088*x*x)+x/0.585056,-6.11751)))))", + "113_pt": "(TMath::TwoPi()*x*(0*exp(-(sqrt(x*x+0.139571*0.139571)-0.139571)/0.1)+44.8976*pow(exp(-0.491415*x-0.0563088*x*x)+x/0.585056,-6.11751)))*((x>1.951)*(0.451114/(1+exp(-(x-0.707439)/0.374928))+-0.307087*TMath::Gaus(x,-0.577264,1.60957)+-0.20694*TMath::Gaus(x,-2.50098,4.31777)+0.337195)+(x<=1.951)*((((0.52988/(1+exp(-((x-0.303965)/0.287856))))+(-0.281848*TMath::Gaus(x,0.497102,0.688973)))+(-0.249068*TMath::Gaus(x,1.09157,1.16378)))+0.253347))", + "333_pt": "(TMath::TwoPi()*x*(0*exp(-(sqrt(x*x+0.139571*0.139571)-0.139571)/0.1)+44.8976*pow(exp(-0.491415*x-0.0563088*x*x)+x/0.585056,-6.11751)))*(0.8*(0.105659/(1+exp(-(x-0.781147)/3.13076))+-0.564081*TMath::Gaus(x,-0.134319,1.22474)+0.426234*TMath::Gaus(x,-0.173703,1.17147)+0.093734))" + } +} diff --git a/MC/config/PWGEM/parametrizations/pp136TeV_run3.json b/MC/config/PWGEM/parametrizations/pp136TeV_run3.json new file mode 100755 index 000000000..974cd8545 --- /dev/null +++ b/MC/config/PWGEM/parametrizations/pp136TeV_run3.json @@ -0,0 +1,41 @@ +{ + "13TeV_MB_default": { + "histoMtScaleFactor": { + "113": 0.87, + "223": 0.572, + "331": 0.4 + }, + "221_pt": "((0.52015*1.)+(43.159*(-0.011541*TMath::Power(1+((x/1.11668)*(x/1.11668)),-(0.696078)))))/(1.+(-0.011541*TMath::Power(1+((x/1.11668)*(x/1.11668)),-(0.696078)))) * (x*(55.4505*TMath::Exp(-(TMath::Sqrt(x*x+0.134977*0.134977)-0.134977)/0.14849)+2.93224*TMath::Power(1+(x*x)/(0.64965*0.64965*2.97448),-2.97448)))", + "111_pt": "( x*(55.4505*TMath::Exp(-(TMath::Sqrt(x*x+0.134977*0.134977)-0.134977)/0.14849)+2.93224*TMath::Power(1+(x*x)/(0.64965*0.64965*2.97448),-2.97448)) )", + "333_pt": "(x*0.162735*TMath::Power(TMath::Exp(-0.455874*x-TMath::Abs(-0.0589095)*x*x)+x/1.30284,-5.7907))", + "443_pt": "x*3.76783e-05/TMath::Power((1+TMath::Power(x/4.06472,2.0)),3.03429)", + "321_pt": "1.2778632*x*7.70776*TMath::Power(TMath::Exp(-0.618249*x-TMath::Abs(3.16962e-09)*x*x)+x/1.02821,-5.47764)", + "2212_pt": "1.2778632*x*1.4891*TMath::Power(TMath::Exp(-0.4799*x-TMath::Abs(0.0225614)*x*x)+x/1.6315,-6.82731)" + }, + "13TeV_MB_etadown": { + "histoMtScaleFactor": { + "113": 0.87, + "223": 0.572, + "331": 0.4 + }, + "221_pt": "(1+(-0.012*x+0.2))*(((0.512943*1.)+(50.7191*(-0.00955168*TMath::Power(1+((x/1.27138)*(x/1.27138)),-(0.806776)))))/(1.+(-0.00955168*TMath::Power(1+((x/1.27138)*(x/1.27138)),-(0.806776))))) * (x*(55.4505*TMath::Exp(-(TMath::Sqrt(x*x+0.134977*0.134977)-0.134977)/0.14849)+2.93224*TMath::Power(1+(x*x)/(0.64965*0.64965*2.97448),-2.97448)))", + "111_pt": "( x*(55.4505*TMath::Exp(-(TMath::Sqrt(x*x+0.134977*0.134977)-0.134977)/0.14849)+2.93224*TMath::Power(1+(x*x)/(0.64965*0.64965*2.97448),-2.97448)) )", + "333_pt": "(x*0.162735*TMath::Power(TMath::Exp(-0.455874*x-TMath::Abs(-0.0589095)*x*x)+x/1.30284,-5.7907))", + "443_pt": "x*3.76783e-05/TMath::Power((1+TMath::Power(x/4.06472,2.0)),3.03429)", + "321_pt": "1.2778632*x*7.70776*TMath::Power(TMath::Exp(-0.618249*x-TMath::Abs(3.16962e-09)*x*x)+x/1.02821,-5.47764)", + "2212_pt": "1.2778632*x*1.4891*TMath::Power(TMath::Exp(-0.4799*x-TMath::Abs(0.0225614)*x*x)+x/1.6315,-6.82731)" + }, + "13TeV_MB_etaup": { + "histoMtScaleFactor": { + "113": 0.87, + "223": 0.572, + "331": 0.4 + }, + "221_pt": "(1-(-0.012*x+0.2))*(((0.539777*1.)+(44.4999*(-0.0119051*TMath::Power(1+((x/0.935105)*(x/0.935105)),-(0.559079)))))/(1.+(-0.0119051*TMath::Power(1+((x/0.935105)*(x/0.935105)),-(0.559079))))) * (x*(55.4505*TMath::Exp(-(TMath::Sqrt(x*x+0.134977*0.134977)-0.134977)/0.14849)+2.93224*TMath::Power(1+(x*x)/(0.64965*0.64965*2.97448),-2.97448)))", + "111_pt": "( x*(55.4505*TMath::Exp(-(TMath::Sqrt(x*x+0.134977*0.134977)-0.134977)/0.14849)+2.93224*TMath::Power(1+(x*x)/(0.64965*0.64965*2.97448),-2.97448)) )", + "333_pt": "(x*0.162735*TMath::Power(TMath::Exp(-0.455874*x-TMath::Abs(-0.0589095)*x*x)+x/1.30284,-5.7907))", + "443_pt": "x*3.76783e-05/TMath::Power((1+TMath::Power(x/4.06472,2.0)),3.03429)", + "321_pt": "1.2778632*x*7.70776*TMath::Power(TMath::Exp(-0.618249*x-TMath::Abs(3.16962e-09)*x*x)+x/1.02821,-5.47764)", + "2212_pt": "1.2778632*x*1.4891*TMath::Power(TMath::Exp(-0.4799*x-TMath::Abs(0.0225614)*x*x)+x/1.6315,-6.82731)" + } +} \ No newline at end of file diff --git a/MC/config/PWGEM/pythia8/decayer/force_dummy.cfg b/MC/config/PWGEM/pythia8/decayer/force_dummy.cfg new file mode 100644 index 000000000..e69de29bb diff --git a/MC/config/PWGEM/pythia8/decayer/force_semileptonic.cfg b/MC/config/PWGEM/pythia8/decayer/force_semileptonic.cfg new file mode 100644 index 000000000..0951a2341 --- /dev/null +++ b/MC/config/PWGEM/pythia8/decayer/force_semileptonic.cfg @@ -0,0 +1,77 @@ +### semileptonic decays for charm +### D+ +411:oneChannel = 1 0.087 0 -311 -11 12 +411:addChannel = 1 0.040 0 -321 211 -11 12 +411:addChannel = 1 0.037 0 -313 -11 12 +### D0 +421:oneChannel = 1 0.035 0 -321 -11 12 +421:addChannel = 1 0.022 0 -323 -11 12 +421:addChannel = 1 0.016 0 -321 111 -11 12 +421:addChannel = 1 0.014 0 -311 -211 -11 12 +### Ds +431:oneChannel = 1 0.025 0 333 -11 12 +431:addChannel = 1 0.027 0 221 -11 12 +### Lambdac +4122:oneChannel = 1 0.036 0 3122 -11 12 +### chi_{c}^{+} +4232:oneChannel = 1 0.07 0 3322 -11 12 +### chi_{c}^{0} +4132:oneChannel = 1 0.014 0 3312 -11 12 +### Omega_{c} +4332:oneChannel = 1 0.01224 0 3334 -11 12 + +### semileptonic decays for beauty +### B0 +511:oneChannel = 1 0.0207000 0 12 -11 -411 +511:addChannel = 1 0.0570000 0 12 -11 -413 +511:addChannel = 1 0.0023000 0 12 -11 -415 +511:addChannel = 1 0.0001330 0 12 -11 -211 +511:addChannel = 1 0.0002690 0 12 -11 -213 +511:addChannel = 1 0.0045000 0 12 -11 -10411 +511:addChannel = 1 0.0052000 0 12 -11 -10413 +511:addChannel = 1 0.0083000 0 12 -11 -20413 + +### B+ +521:oneChannel = 1 0.0000720 0 12 -11 111 +521:addChannel = 1 0.0001450 0 12 -11 113 +521:addChannel = 1 0.0000840 0 12 -11 221 +521:addChannel = 1 0.0001450 0 12 -11 223 +521:addChannel = 1 0.0000840 0 12 -11 331 +521:addChannel = 1 0.0224000 0 12 -11 -421 +521:addChannel = 1 0.0617000 0 12 -11 -423 +521:addChannel = 1 0.0030000 0 12 -11 -425 +521:addChannel = 1 0.0049000 0 12 -11 -10421 +521:addChannel = 1 0.0056000 0 12 -11 -10423 +521:addChannel = 1 0.0090000 0 12 -11 -20423 + +### Bs +531:oneChannel = 1 0.0002000 0 12 -11 -321 +531:addChannel = 1 0.0003000 0 12 -11 -323 +531:addChannel = 1 0.0210000 0 12 -11 -431 +531:addChannel = 1 0.0490000 0 12 -11 -433 +531:addChannel = 1 0.0070000 0 12 -11 -435 +531:addChannel = 1 0.0003000 0 12 -11 -10323 +531:addChannel = 1 0.0040000 0 12 -11 -10431 +531:addChannel = 1 0.0070000 0 12 -11 -10433 +531:addChannel = 1 0.0002000 0 12 -11 -20323 +531:addChannel = 1 0.0040000 0 12 -11 -20433 + +### Lambdab +5122:oneChannel = 1 0.0546000 0 -12 11 4122 +5122:addChannel = 1 0.0096000 0 -12 11 4124 +5122:addChannel = 1 0.0128000 0 -12 11 14122 + +### Chi_{b}^{-} +5132:oneChannel = 1 0.1080010 0 -12 11 4 3101 +5132:addChannel = 1 0.0020000 0 -12 11 2 3101 +### Chi_{b}^{0} +5232:oneChannel = 1 0.1080010 0 -12 11 4 3201 +5232:addChannel = 1 0.0020000 0 -12 11 2 3201 +### Omega_{b}^{-} +5332:oneChannel = 1 0.1080010 1 -12 11 4 3303 +5332:oneChannel = 1 0.0020000 1 -12 11 2 3303 + +# Correct OmegaC decay length (wrong in PYTHIA8 decay table) (mm/c) +4332:tau0 = 0.08000000000 +# Correct Lb decay length (wrong in PYTHIA8 decay table) +5122:tau0 = 4.41000e-01 \ No newline at end of file diff --git a/MC/config/PWGEM/pythia8/generator/configPythia_ForcedDalitz.cfg b/MC/config/PWGEM/pythia8/generator/configPythia_ForcedDalitz.cfg new file mode 100644 index 000000000..fca369b49 --- /dev/null +++ b/MC/config/PWGEM/pythia8/generator/configPythia_ForcedDalitz.cfg @@ -0,0 +1,20 @@ +ProcessLevel:all on + +### beams +Beams:idA 2212 # proton +Beams:idB 2212 # proton +Beams:eCM 13600. # GeV + +### processes +SoftQCD:inelastic on # all inelastic processes + +ParticleDecays:limitTau0 on +ParticleDecays:tau0Max 10 + + +#decay eta -> e+ e- gamma, BR = 100% +221:oneChannel = 1 1 0 22 11 -11 + +#decay pi0 -> e+ e- gamma BR = 10% +111:oneChannel = 1 0.9 0 22 22 +111:addChannel = 1 0.1 0 22 11 -11 diff --git a/MC/config/PWGEM/pythia8/generator/pythia8_DY.cfg b/MC/config/PWGEM/pythia8/generator/pythia8_DY.cfg new file mode 100644 index 000000000..d839106eb --- /dev/null +++ b/MC/config/PWGEM/pythia8/generator/pythia8_DY.cfg @@ -0,0 +1,16 @@ +### beams +Beams:idA 2212 # proton +Beams:idB 2212 # proton +Beams:eCM 13600. # GeV #user can change eCM from command line. + +### processes +WeakSingleBoson:ffbar2gmZ on # ffbar -> Z/gamma* +PhaseSpace:mHatMin 0.5 +PhaseSpace:mHatMax 15 +23:mMin 0.5 +TimeShower:mMaxGamma 0.5 +23:onMode off # switch off all Z0 decay channels. # User must switch back on Z0 going to l+ l- in C or ini. gamma* is tread as 23, too. + +### decays +ParticleDecays:limitTau0 on +ParticleDecays:tau0Max 10. diff --git a/MC/config/PWGEM/pythia8/generator/pythia8_OO_536_VM2ll.cfg b/MC/config/PWGEM/pythia8/generator/pythia8_OO_536_VM2ll.cfg new file mode 100644 index 000000000..596a85beb --- /dev/null +++ b/MC/config/PWGEM/pythia8/generator/pythia8_OO_536_VM2ll.cfg @@ -0,0 +1,21 @@ +### OO beams +Beams:idA = 1000080160 +Beams:idB = 1000080160 +Beams:eCM = 5360.0 ### energy + +Beams:frameType = 1 +ParticleDecays:limitTau0 = on +ParticleDecays:tau0Max = 10. ### match alice: 1cm/c = 10.0mm/c + +### Save some CPU at init of jobs +### To avoid refitting, add the following lines to your configuration file: +HeavyIon:SigFitNGen = 0 +HeavyIon:SigFitDefPar = 2.15,18.42,0.33 + +Random:setSeed = on + +# change omega, phi meson's BR below +223:oneChannel = 1 0.5 0 -11 11 +223:addChannel = 1 0.5 0 -13 13 +333:oneChannel = 1 0.5 0 -11 11 +333:addChannel = 1 0.5 0 -13 13 diff --git a/MC/config/PWGEM/pythia8/generator/pythia8_OO_536_bbbar.cfg b/MC/config/PWGEM/pythia8/generator/pythia8_OO_536_bbbar.cfg new file mode 100644 index 000000000..47d52bfbd --- /dev/null +++ b/MC/config/PWGEM/pythia8/generator/pythia8_OO_536_bbbar.cfg @@ -0,0 +1,22 @@ +### beams +Beams:idA = 1000080160 +Beams:idB = 1000080160 +Beams:eCM = 5360.0 +Beams:frameType = 1 + +### Save some CPU at init of jobs +### To avoid refitting, add the following lines to your configuration file: +HeavyIon:SigFitNGen = 0 +HeavyIon:SigFitDefPar = 2.15,18.42,0.33 +### processes +HardQCD:hardbbbar on # scatterings g-g / q-qbar -> b-bbar + +### decays +ParticleDecays:limitTau0 on +ParticleDecays:tau0Max 10. + + +# Correct OmegaC decay length (wrong in PYTHIA8 decay table) (mm/c) +4332:tau0 = 0.08000000000 +# Correct Lb decay length (wrong in PYTHIA8 decay table) +5122:tau0 = 4.41000e-01 diff --git a/MC/config/PWGEM/pythia8/generator/pythia8_OO_536_ccbar.cfg b/MC/config/PWGEM/pythia8/generator/pythia8_OO_536_ccbar.cfg new file mode 100644 index 000000000..07d252517 --- /dev/null +++ b/MC/config/PWGEM/pythia8/generator/pythia8_OO_536_ccbar.cfg @@ -0,0 +1,45 @@ +### beams +Beams:idA = 1000080160 +Beams:idB = 1000080160 +Beams:eCM = 5360.0 +Beams:frameType = 1 + +### Save some CPU at init of jobs +### To avoid refitting, add the following lines to your configuration file: +HeavyIon:SigFitNGen = 0 +HeavyIon:SigFitDefPar = 2.15,18.42,0.33 + +### processes +# HardQCD:hardccbar on # ccbar production +SoftQCD:inelastic = on + +### decays +ParticleDecays:limitTau0 on +ParticleDecays:tau0Max 10. + + +### only semileptonic decays +### D+ +411:oneChannel = 1 0.087 0 -311 -11 12 +411:addChannel = 1 0.040 0 -321 211 -11 12 +411:addChannel = 1 0.037 0 -313 -11 12 +### D0 +421:oneChannel = 1 0.035 0 -321 -11 12 +421:addChannel = 1 0.022 0 -323 -11 12 +421:addChannel = 1 0.016 0 -321 111 -11 12 +### Ds +431:oneChannel = 1 0.025 0 333 -11 12 +431:addChannel = 1 0.027 0 221 -11 12 +### Lambdac +4122:oneChannel = 1 0.036 0 3122 -11 12 +### chi_{c}^{+} +4232:oneChannel = 1 0.07 0 3322 -11 12 +### chi_{c}^{0} +4132:oneChannel = 1 0.014 0 3312 -11 12 +### Omega_{c} +4332:oneChannel = 1 0.01224 0 3334 -11 12 + +# Correct OmegaC decay length (wrong in PYTHIA8 decay table) (mm/c) +4332:tau0 = 0.08000000000 +# Correct Lb decay length (wrong in PYTHIA8 decay table) +5122:tau0 = 4.41000e-01 \ No newline at end of file diff --git a/MC/config/PWGEM/pythia8/generator/pythia8_PbPb_5360_VM2ll.cfg b/MC/config/PWGEM/pythia8/generator/pythia8_PbPb_5360_VM2ll.cfg new file mode 100644 index 000000000..d356956f7 --- /dev/null +++ b/MC/config/PWGEM/pythia8/generator/pythia8_PbPb_5360_VM2ll.cfg @@ -0,0 +1,23 @@ +### Specify beams +Beams:idA = 1000822080 +Beams:idB = 1000822080 +Beams:eCM = 5360.0 ### energy + +Beams:frameType = 1 +ParticleDecays:limitTau0 = on +ParticleDecays:tau0Max = 10. ### match alice: 1cm/c = 10.0mm/c + +### Initialize the Angantyr model to fit the total and semi-includive +### cross sections in Pythia within some tolerance. +HeavyIon:SigFitErr = 0.02,0.02,0.1,0.05,0.05,0.0,0.1,0.0 + +### These parameters are typicall suitable for sqrt(S_NN)=5TeV +HeavyIon:SigFitDefPar = 17.24,2.15,0.33,0.0,0.0,0.0,0.0,0.0 + +Random:setSeed = on + +# change omega, phi meson's BR below +223:oneChannel = 1 0.5 0 -11 11 +223:addChannel = 1 0.5 0 -13 13 +333:oneChannel = 1 0.5 0 -11 11 +333:addChannel = 1 0.5 0 -13 13 diff --git a/MC/config/PWGEM/pythia8/generator/pythia8_bbbar_OO_536_forceddecayscharmbeauty.cfg b/MC/config/PWGEM/pythia8/generator/pythia8_bbbar_OO_536_forceddecayscharmbeauty.cfg new file mode 100644 index 000000000..4305eb7dc --- /dev/null +++ b/MC/config/PWGEM/pythia8/generator/pythia8_bbbar_OO_536_forceddecayscharmbeauty.cfg @@ -0,0 +1,101 @@ +### beams +Beams:idA = 1000080160 +Beams:idB = 1000080160 +Beams:eCM = 5360.0 +Beams:frameType = 1 + +### Save some CPU at init of jobs +### To avoid refitting, add the following lines to your configuration file: +HeavyIon:SigFitNGen = 0 +HeavyIon:SigFitDefPar = 2.15,18.42,0.33 +### processes +HardQCD:hardbbbar on # scatterings g-g / q-qbar -> b-bbar + +### decays +ParticleDecays:limitTau0 on +ParticleDecays:tau0Max 10. + + +# Correct OmegaC decay length (wrong in PYTHIA8 decay table) (mm/c) +4332:tau0 = 0.08000000000 +# Correct Lb decay length (wrong in PYTHIA8 decay table) +5122:tau0 = 4.41000e-01 + +### only semileptonic decays for charm +### D+ +411:oneChannel = 1 0.087 0 -311 -11 12 +411:addChannel = 1 0.040 0 -321 211 -11 12 +411:addChannel = 1 0.037 0 -313 -11 12 +### D0 +421:oneChannel = 1 0.035 0 -321 -11 12 +421:addChannel = 1 0.022 0 -323 -11 12 +421:addChannel = 1 0.016 0 -321 111 -11 12 +421:addChannel = 1 0.014 0 -311 -211 -11 12 +### Ds +431:oneChannel = 1 0.025 0 333 -11 12 +431:addChannel = 1 0.027 0 221 -11 12 +### Lambdac +4122:oneChannel = 1 0.036 0 3122 -11 12 +### chi_{c}^{+} +4232:oneChannel = 1 0.07 0 3322 -11 12 +### chi_{c}^{0} +4132:oneChannel = 1 0.014 0 3312 -11 12 +### Omega_{c} +4332:oneChannel = 1 0.01224 0 3334 -11 12 + +### only semileptonic decays for beauty +### B0 +511:oneChannel = 1 0.0207000 0 12 -11 -411 +511:addChannel = 1 0.0570000 0 12 -11 -413 +511:addChannel = 1 0.0023000 0 12 -11 -415 +511:addChannel = 1 0.0001330 0 12 -11 -211 +511:addChannel = 1 0.0002690 0 12 -11 -213 +511:addChannel = 1 0.0045000 0 12 -11 -10411 +511:addChannel = 1 0.0052000 0 12 -11 -10413 +511:addChannel = 1 0.0083000 0 12 -11 -20413 + +### B+ +521:oneChannel = 1 0.0000720 0 12 -11 111 +521:addChannel = 1 0.0001450 0 12 -11 113 +521:addChannel = 1 0.0000840 0 12 -11 221 +521:addChannel = 1 0.0001450 0 12 -11 223 +521:addChannel = 1 0.0000840 0 12 -11 331 +521:addChannel = 1 0.0224000 0 12 -11 -421 +521:addChannel = 1 0.0617000 0 12 -11 -423 +521:addChannel = 1 0.0030000 0 12 -11 -425 +521:addChannel = 1 0.0049000 0 12 -11 -10421 +521:addChannel = 1 0.0056000 0 12 -11 -10423 +521:addChannel = 1 0.0090000 0 12 -11 -20423 + +### Bs +531:oneChannel = 1 0.0002000 0 12 -11 -321 +531:addChannel = 1 0.0003000 0 12 -11 -323 +531:addChannel = 1 0.0210000 0 12 -11 -431 +531:addChannel = 1 0.0490000 0 12 -11 -433 +531:addChannel = 1 0.0070000 0 12 -11 -435 +531:addChannel = 1 0.0003000 0 12 -11 -10323 +531:addChannel = 1 0.0040000 0 12 -11 -10431 +531:addChannel = 1 0.0070000 0 12 -11 -10433 +531:addChannel = 1 0.0002000 0 12 -11 -20323 +531:addChannel = 1 0.0040000 0 12 -11 -20433 + +### Lambdab +5122:oneChannel = 1 0.0546000 0 -12 11 4122 +5122:addChannel = 1 0.0096000 0 -12 11 4124 +5122:addChannel = 1 0.0128000 0 -12 11 14122 + +### Chi_{b}^{-} +5132:oneChannel = 1 0.1080010 0 -12 11 4 3101 +5132:addChannel = 1 0.0020000 0 -12 11 2 3101 +### Chi_{b}^{0} +5232:oneChannel = 1 0.1080010 0 -12 11 4 3201 +5232:addChannel = 1 0.0020000 0 -12 11 2 3201 +### Omega_{b}^{-} +5332:oneChannel = 1 0.1080010 1 -12 11 4 3303 +5332:oneChannel = 1 0.0020000 1 -12 11 2 3303 + + +# Correct OmegaC decay length (wrong in PYTHIA8 decay table) (mm/c) +4332:tau0 = 0.08000000000 +# Correct Lb decay length (wrong in PYTHIA8 decay table) +5122:tau0 = 4.41000e-01 diff --git a/MC/config/PWGEM/pythia8/generator/pythia8_hf_cocktail_pp13.cfg b/MC/config/PWGEM/pythia8/generator/pythia8_hf_cocktail_pp13.cfg new file mode 100644 index 000000000..f7884e068 --- /dev/null +++ b/MC/config/PWGEM/pythia8/generator/pythia8_hf_cocktail_pp13.cfg @@ -0,0 +1,30 @@ +### beams +Beams:idA 2212 # proton +Beams:idB 2212 # proton +Beams:eCM 13000. # GeV + +### processes +SoftQCD:inelastic on + +### decays +ParticleDecays:limitTau0 on +ParticleDecays:tau0Max 10. + +### switch on color reconnection in mode 2 (https://arxiv.org/pdf/1505.01681.pdf) +Tune:pp = 14 +ColourReconnection:mode = 1 +ColourReconnection:allowDoubleJunRem = off +ColourReconnection:m0 = 0.3 +ColourReconnection:allowJunctions = on +ColourReconnection:junctionCorrection = 1.20 +ColourReconnection:timeDilationMode = 2 +ColourReconnection:timeDilationPar = 0.18 +StringPT:sigma = 0.335 +StringZ:aLund = 0.36 +StringZ:bLund = 0.56 +StringFlav:probQQtoQ = 0.078 +StringFlav:ProbStoUD = 0.2 +StringFlav:probQQ1toQQ0join = 0.0275,0.0275,0.0275,0.0275 +MultiPartonInteractions:pT0Ref = 2.15 +BeamRemnants:remnantMode = 1 +BeamRemnants:saturation =5 \ No newline at end of file diff --git a/MC/config/PWGEM/pythia8/generator/pythia8_hf_cocktail_pp502.cfg b/MC/config/PWGEM/pythia8/generator/pythia8_hf_cocktail_pp502.cfg new file mode 100644 index 000000000..83d28efba --- /dev/null +++ b/MC/config/PWGEM/pythia8/generator/pythia8_hf_cocktail_pp502.cfg @@ -0,0 +1,30 @@ +### beams +Beams:idA 2212 # proton +Beams:idB 2212 # proton +Beams:eCM 5200. # GeV + +### processes +SoftQCD:inelastic on + +### decays +ParticleDecays:limitTau0 on +ParticleDecays:tau0Max 10. + +### switch on color reconnection in mode 2 (https://arxiv.org/pdf/1505.01681.pdf) +Tune:pp = 14 +ColourReconnection:mode = 1 +ColourReconnection:allowDoubleJunRem = off +ColourReconnection:m0 = 0.3 +ColourReconnection:allowJunctions = on +ColourReconnection:junctionCorrection = 1.20 +ColourReconnection:timeDilationMode = 2 +ColourReconnection:timeDilationPar = 0.18 +StringPT:sigma = 0.335 +StringZ:aLund = 0.36 +StringZ:bLund = 0.56 +StringFlav:probQQtoQ = 0.078 +StringFlav:ProbStoUD = 0.2 +StringFlav:probQQ1toQQ0join = 0.0275,0.0275,0.0275,0.0275 +MultiPartonInteractions:pT0Ref = 2.15 +BeamRemnants:remnantMode = 1 +BeamRemnants:saturation =5 \ No newline at end of file diff --git a/MC/config/PWGEM/pythia8/generator/pythia8_hf_cocktail_pp536.cfg b/MC/config/PWGEM/pythia8/generator/pythia8_hf_cocktail_pp536.cfg new file mode 100644 index 000000000..ccaa31ce8 --- /dev/null +++ b/MC/config/PWGEM/pythia8/generator/pythia8_hf_cocktail_pp536.cfg @@ -0,0 +1,30 @@ +### beams +Beams:idA 2212 # proton +Beams:idB 2212 # proton +Beams:eCM 5360. # GeV + +### processes +SoftQCD:inelastic on + +### decays +ParticleDecays:limitTau0 on +ParticleDecays:tau0Max 10. + +### switch on color reconnection in mode 2 (https://arxiv.org/pdf/1505.01681.pdf) +Tune:pp = 14 +ColourReconnection:mode = 1 +ColourReconnection:allowDoubleJunRem = off +ColourReconnection:m0 = 0.3 +ColourReconnection:allowJunctions = on +ColourReconnection:junctionCorrection = 1.20 +ColourReconnection:timeDilationMode = 2 +ColourReconnection:timeDilationPar = 0.18 +StringPT:sigma = 0.335 +StringZ:aLund = 0.36 +StringZ:bLund = 0.56 +StringFlav:probQQtoQ = 0.078 +StringFlav:ProbStoUD = 0.2 +StringFlav:probQQ1toQQ0join = 0.0275,0.0275,0.0275,0.0275 +MultiPartonInteractions:pT0Ref = 2.15 +BeamRemnants:remnantMode = 1 +BeamRemnants:saturation =5 \ No newline at end of file diff --git a/MC/config/PWGEM/pythia8/generator/pythia8_pp_13600_VM2ll.cfg b/MC/config/PWGEM/pythia8/generator/pythia8_pp_13600_VM2ll.cfg new file mode 100644 index 000000000..b8a0c3923 --- /dev/null +++ b/MC/config/PWGEM/pythia8/generator/pythia8_pp_13600_VM2ll.cfg @@ -0,0 +1,23 @@ +### Specify beams +Beams:idA = 2212 +Beams:idB = 2212 +Beams:eCM = 13600. ### energy + +Beams:frameType = 1 +ParticleDecays:limitTau0 = on +ParticleDecays:tau0Max = 10. ### match alice: 1cm/c = 10.0mm/c + +### processes +SoftQCD:inelastic = on # all inelastic processes + +# default: do nothing, Monash 2013 will do its thing +Tune:pp = 14 + +Random:setSeed = on + +# change eta, omega, phi meson's BR below +221:oneChannel = 1 0.5 0 -13 13 +223:oneChannel = 1 0.5 0 -11 11 +223:addChannel = 1 0.5 0 -13 13 +333:oneChannel = 1 0.5 0 -11 11 +333:addChannel = 1 0.5 0 -13 13 diff --git a/MC/config/PWGEM/pythia8/generator/pythia8_pp_5360_MB_gapevent.cfg b/MC/config/PWGEM/pythia8/generator/pythia8_pp_5360_MB_gapevent.cfg new file mode 100644 index 000000000..b3fdfdd99 --- /dev/null +++ b/MC/config/PWGEM/pythia8/generator/pythia8_pp_5360_MB_gapevent.cfg @@ -0,0 +1,15 @@ +### beams +Beams:idA 2212 # proton +Beams:idB 2212 # proton +Beams:eCM 5360 # GeV + +### processes +SoftQCD:inelastic on # all inelastic processes + +### per default it is Monash anyway +Tune:pp = 14 + +### decays +ParticleDecays:limitTau0 on +ParticleDecays:tau0Max 10. + diff --git a/MC/config/PWGEM/pythia8/generator/pythia8_pp_5360_VM2ee.cfg b/MC/config/PWGEM/pythia8/generator/pythia8_pp_5360_VM2ee.cfg new file mode 100644 index 000000000..b767c9ea3 --- /dev/null +++ b/MC/config/PWGEM/pythia8/generator/pythia8_pp_5360_VM2ee.cfg @@ -0,0 +1,37 @@ +### Specify beams +Beams:idA = 2212 +Beams:idB = 2212 +Beams:eCM = 5360. ### energy + +Beams:frameType = 1 +ParticleDecays:limitTau0 = on +ParticleDecays:tau0Max = 10. ### match alice: 1cm/c = 10.0mm/c + +### processes +SoftQCD:inelastic = on # all inelastic processes + +# default: do nothing, Monash 2013 will do its thing +Tune:pp = 14 + +Random:setSeed = on + +# don't modify pion's PR as charged multiplicity is drived by them. + +# eta +221:oneChannel = 1 1.0 0 -11 11 22 + +# eta' +331:oneChannel = 1 0.294 0 -11 11 111 +331:addChannel = 1 0.706 0 -11 11 223 + +# rho +113:oneChannel = 1 1.0 0 -11 11 + +# omega +223:oneChannel = 1 0.088 0 -11 11 +223:addChannel = 1 0.912 0 -11 11 111 + +# phi +333:oneChannel = 1 0.710 0 -11 11 +333:addChannel = 1 0.032 0 -11 11 111 +333:addChannel = 1 0.258 0 -11 11 221 diff --git a/MC/config/PWGEM/pythia8/generator/pythia8_pp_5360_VM2ll.cfg b/MC/config/PWGEM/pythia8/generator/pythia8_pp_5360_VM2ll.cfg new file mode 100644 index 000000000..6d9191759 --- /dev/null +++ b/MC/config/PWGEM/pythia8/generator/pythia8_pp_5360_VM2ll.cfg @@ -0,0 +1,23 @@ +### Specify beams +Beams:idA = 2212 +Beams:idB = 2212 +Beams:eCM = 5360. ### energy + +Beams:frameType = 1 +ParticleDecays:limitTau0 = on +ParticleDecays:tau0Max = 10. ### match alice: 1cm/c = 10.0mm/c + +### processes +SoftQCD:inelastic = on # all inelastic processes + +# default: do nothing, Monash 2013 will do its thing +Tune:pp = 14 + +Random:setSeed = on + +# change eta, omega, phi meson's BR below +221:oneChannel = 1 0.5 0 -13 13 +223:oneChannel = 1 0.5 0 -11 11 +223:addChannel = 1 0.5 0 -13 13 +333:oneChannel = 1 0.5 0 -11 11 +333:addChannel = 1 0.5 0 -13 13 diff --git a/MC/config/PWGEM/pythia8/generator/pythia8_pp_5360_bbbar.cfg b/MC/config/PWGEM/pythia8/generator/pythia8_pp_5360_bbbar.cfg new file mode 100644 index 000000000..3e1df36b7 --- /dev/null +++ b/MC/config/PWGEM/pythia8/generator/pythia8_pp_5360_bbbar.cfg @@ -0,0 +1,36 @@ +### beams +Beams:idA 2212 # proton +Beams:idB 2212 # proton +Beams:eCM 5360 # GeV + +### processes +#HardQCD:hardccbar on # scatterings g-g / q-qbar -> c-cbar +HardQCD:hardbbbar on # scatterings g-g / q-qbar -> b-bbar + +### decays +ParticleDecays:limitTau0 on +ParticleDecays:tau0Max 10. + +### switch on color reconnection in mode 2 (https://arxiv.org/pdf/1505.01681.pdf) +Tune:pp = 14 +ColourReconnection:mode = 1 +ColourReconnection:allowDoubleJunRem = off +ColourReconnection:m0 = 0.3 +ColourReconnection:allowJunctions = on +ColourReconnection:junctionCorrection = 1.20 +ColourReconnection:timeDilationMode = 2 +ColourReconnection:timeDilationPar = 0.18 +StringPT:sigma = 0.335 +StringZ:aLund = 0.36 +StringZ:bLund = 0.56 +StringFlav:probQQtoQ = 0.078 +StringFlav:ProbStoUD = 0.2 +StringFlav:probQQ1toQQ0join = 0.0275,0.0275,0.0275,0.0275 +MultiPartonInteractions:pT0Ref = 2.15 +BeamRemnants:remnantMode = 1 +BeamRemnants:saturation =5 + +# Correct OmegaC decay length (wrong in PYTHIA8 decay table) (mm/c) +4332:tau0 = 0.08000000000 +# Correct Lb decay length (wrong in PYTHIA8 decay table) +5122:tau0 = 4.41000e-01 diff --git a/MC/config/PWGEM/pythia8/generator/pythia8_pp_5360_bbbar_forceddecayscharmbeauty.cfg b/MC/config/PWGEM/pythia8/generator/pythia8_pp_5360_bbbar_forceddecayscharmbeauty.cfg new file mode 100644 index 000000000..2cc3486fe --- /dev/null +++ b/MC/config/PWGEM/pythia8/generator/pythia8_pp_5360_bbbar_forceddecayscharmbeauty.cfg @@ -0,0 +1,110 @@ +### beams +Beams:idA 2212 # proton +Beams:idB 2212 # proton +Beams:eCM 5360 # GeV + +### processes +#HardQCD:hardccbar on # scatterings g-g / q-qbar -> c-cbar +HardQCD:hardbbbar on # scatterings g-g / q-qbar -> b-bbar + +### decays +ParticleDecays:limitTau0 on +ParticleDecays:tau0Max 10. + +### switch on color reconnection in mode 2 (https://arxiv.org/pdf/1505.01681.pdf) +Tune:pp = 14 +ColourReconnection:mode = 1 +ColourReconnection:allowDoubleJunRem = off +ColourReconnection:m0 = 0.3 +ColourReconnection:allowJunctions = on +ColourReconnection:junctionCorrection = 1.20 +ColourReconnection:timeDilationMode = 2 +ColourReconnection:timeDilationPar = 0.18 +StringPT:sigma = 0.335 +StringZ:aLund = 0.36 +StringZ:bLund = 0.56 +StringFlav:probQQtoQ = 0.078 +StringFlav:ProbStoUD = 0.2 +StringFlav:probQQ1toQQ0join = 0.0275,0.0275,0.0275,0.0275 +MultiPartonInteractions:pT0Ref = 2.15 +BeamRemnants:remnantMode = 1 +BeamRemnants:saturation =5 + +### only semileptonic decays for charm +### D+ +411:oneChannel = 1 0.087 0 -311 -11 12 +411:addChannel = 1 0.040 0 -321 211 -11 12 +411:addChannel = 1 0.037 0 -313 -11 12 +### D0 +421:oneChannel = 1 0.035 0 -321 -11 12 +421:addChannel = 1 0.022 0 -323 -11 12 +421:addChannel = 1 0.016 0 -321 111 -11 12 +421:addChannel = 1 0.014 0 -311 -211 -11 12 +### Ds +431:oneChannel = 1 0.025 0 333 -11 12 +431:addChannel = 1 0.027 0 221 -11 12 +### Lambdac +4122:oneChannel = 1 0.036 0 3122 -11 12 +### chi_{c}^{+} +4232:oneChannel = 1 0.07 0 3322 -11 12 +### chi_{c}^{0} +4132:oneChannel = 1 0.014 0 3312 -11 12 +### Omega_{c} +4332:oneChannel = 1 0.01224 0 3334 -11 12 + +### only semileptonic decays for beauty +### B0 +511:oneChannel = 1 0.0207000 0 12 -11 -411 +511:addChannel = 1 0.0570000 0 12 -11 -413 +511:addChannel = 1 0.0023000 0 12 -11 -415 +511:addChannel = 1 0.0001330 0 12 -11 -211 +511:addChannel = 1 0.0002690 0 12 -11 -213 +511:addChannel = 1 0.0045000 0 12 -11 -10411 +511:addChannel = 1 0.0052000 0 12 -11 -10413 +511:addChannel = 1 0.0083000 0 12 -11 -20413 + +### B+ +521:oneChannel = 1 0.0000720 0 12 -11 111 +521:addChannel = 1 0.0001450 0 12 -11 113 +521:addChannel = 1 0.0000840 0 12 -11 221 +521:addChannel = 1 0.0001450 0 12 -11 223 +521:addChannel = 1 0.0000840 0 12 -11 331 +521:addChannel = 1 0.0224000 0 12 -11 -421 +521:addChannel = 1 0.0617000 0 12 -11 -423 +521:addChannel = 1 0.0030000 0 12 -11 -425 +521:addChannel = 1 0.0049000 0 12 -11 -10421 +521:addChannel = 1 0.0056000 0 12 -11 -10423 +521:addChannel = 1 0.0090000 0 12 -11 -20423 + +### Bs +531:oneChannel = 1 0.0002000 0 12 -11 -321 +531:addChannel = 1 0.0003000 0 12 -11 -323 +531:addChannel = 1 0.0210000 0 12 -11 -431 +531:addChannel = 1 0.0490000 0 12 -11 -433 +531:addChannel = 1 0.0070000 0 12 -11 -435 +531:addChannel = 1 0.0003000 0 12 -11 -10323 +531:addChannel = 1 0.0040000 0 12 -11 -10431 +531:addChannel = 1 0.0070000 0 12 -11 -10433 +531:addChannel = 1 0.0002000 0 12 -11 -20323 +531:addChannel = 1 0.0040000 0 12 -11 -20433 + +### Lambdab +5122:oneChannel = 1 0.0546000 0 -12 11 4122 +5122:addChannel = 1 0.0096000 0 -12 11 4124 +5122:addChannel = 1 0.0128000 0 -12 11 14122 + +### Chi_{b}^{-} +5132:oneChannel = 1 0.1080010 0 -12 11 4 3101 +5132:addChannel = 1 0.0020000 0 -12 11 2 3101 +### Chi_{b}^{0} +5232:oneChannel = 1 0.1080010 0 -12 11 4 3201 +5232:addChannel = 1 0.0020000 0 -12 11 2 3201 +### Omega_{b}^{-} +5332:oneChannel = 1 0.1080010 1 -12 11 4 3303 +5332:oneChannel = 1 0.0020000 1 -12 11 2 3303 + + +# Correct OmegaC decay length (wrong in PYTHIA8 decay table) (mm/c) +4332:tau0 = 0.08000000000 +# Correct Lb decay length (wrong in PYTHIA8 decay table) +5122:tau0 = 4.41000e-01 diff --git a/MC/config/PWGEM/pythia8/generator/pythia8_pp_5360_cr2_forceddecayscharm.cfg b/MC/config/PWGEM/pythia8/generator/pythia8_pp_5360_cr2_forceddecayscharm.cfg new file mode 100644 index 000000000..7f5a2bcab --- /dev/null +++ b/MC/config/PWGEM/pythia8/generator/pythia8_pp_5360_cr2_forceddecayscharm.cfg @@ -0,0 +1,63 @@ +### main + +Main:timesAllowErrors 2000 +#allow more errors in the pythia. + + +### beams +Beams:idA 2212 # proton +Beams:idB 2212 # proton +Beams:eCM 5360 # GeV + +### processes +# HardQCD:hardccbar on # ccbar production +SoftQCD:inelastic = on + +### decays +ParticleDecays:limitTau0 on +ParticleDecays:tau0Max 10. + +### switch on color reconnection in mode 2 (https://arxiv.org/pdf/1505.01681.pdf) +Tune:pp = 14 +ColourReconnection:mode = 1 +ColourReconnection:allowDoubleJunRem = off +ColourReconnection:m0 = 0.3 +ColourReconnection:allowJunctions = on +ColourReconnection:junctionCorrection = 1.20 +ColourReconnection:timeDilationMode = 2 +ColourReconnection:timeDilationPar = 0.18 +StringPT:sigma = 0.335 +StringZ:aLund = 0.36 +StringZ:bLund = 0.56 +StringFlav:probQQtoQ = 0.078 +StringFlav:ProbStoUD = 0.2 +StringFlav:probQQ1toQQ0join = 0.0275,0.0275,0.0275,0.0275 +MultiPartonInteractions:pT0Ref = 2.15 +BeamRemnants:remnantMode = 1 +BeamRemnants:saturation =5 + + ### only semileptonic decays +### D+ +411:oneChannel = 1 0.087 0 -311 -11 12 +411:addChannel = 1 0.040 0 -321 211 -11 12 +411:addChannel = 1 0.037 0 -313 -11 12 +### D0 +421:oneChannel = 1 0.035 0 -321 -11 12 +421:addChannel = 1 0.022 0 -323 -11 12 +421:addChannel = 1 0.016 0 -321 111 -11 12 +### Ds +431:oneChannel = 1 0.025 0 333 -11 12 +431:addChannel = 1 0.027 0 221 -11 12 +### Lambdac +4122:oneChannel = 1 0.036 0 3122 -11 12 +### chi_{c}^{+} +4232:oneChannel = 1 0.07 0 3322 -11 12 +### chi_{c}^{0} +4132:oneChannel = 1 0.014 0 3312 -11 12 +### Omega_{c} +4332:oneChannel = 1 0.01224 0 3334 -11 12 + +# Correct OmegaC decay length (wrong in PYTHIA8 decay table) (mm/c) +4332:tau0 = 0.08000000000 +# Correct Lb decay length (wrong in PYTHIA8 decay table) +5122:tau0 = 4.41000e-01 diff --git a/MC/config/PWGGAJE/external/generator/generator_pythia8_gaptrigger_hook.C b/MC/config/PWGGAJE/external/generator/generator_pythia8_gaptrigger_hook.C new file mode 100644 index 000000000..bfcd55f45 --- /dev/null +++ b/MC/config/PWGGAJE/external/generator/generator_pythia8_gaptrigger_hook.C @@ -0,0 +1,279 @@ +R__ADD_INCLUDE_PATH($O2DPG_MC_CONFIG_ROOT) +///#include "FairGenerator.h" +//#include "Generators/GeneratorPythia8.h" +#include "Pythia8/Pythia.h" +#include "MC/config/PWGGAJE/hooks/prompt_gamma_hook.C" +//#include "TRandom.h" +//#include +// +//#include +//#include + +// Prompt-photon custom event generator +// that alternates between 2 gun generators. This is the non-triggered version, without hooks, and would work with any PYTHIA cfg +// set up to inject MB events alongside prompt-photon events +// in 'MB-gap' mode. +// The number of MB events injected, and the PYTHIA config +// for each event type is defined by the user in the .ini +// generator file (e.g. GeneratorJE_gapgen5_hook.ini) +// +// Author: Adrian Fereydon Nassirpour (adrian.fereydon.nassirpour@cern.ch), based on code from Jaime Norman (jaime.norman@cern.ch) + +namespace o2 +{ +namespace eventgen +{ + +using namespace Pythia8; + + +/// A very simple gap generator alternating between 2 different particle guns +class GeneratorPythia8GapGenJEMB : public o2::eventgen::GeneratorPythia8 +{ +public: + /// default constructor + GeneratorPythia8GapGenJEMB(int inputTriggerRatio = 5,std::string pathMB = "",std::string pathSignal = "") { + + mGeneratedEvents = 0; + mInverseTriggerRatio = inputTriggerRatio; + + auto seed = (gRandom->TRandom::GetSeed() % 900000000); + + cout << "Initalizing extra PYTHIA object used to generate min-bias events..." << endl; + TString pathconfigMB = gSystem->ExpandPathName(TString(pathMB)); + pythiaObjectMinimumBias.readFile(pathconfigMB.Data()); + pythiaObjectMinimumBias.readString("Random:setSeed on"); + pythiaObjectMinimumBias.readString("Random:seed " + std::to_string(seed)); + pythiaObjectMinimumBias.init(); + cout << "Initalization complete" << endl; + cout << "Initalizing extra PYTHIA object used to generate signal events..." << endl; + TString pathconfigSignal = gSystem->ExpandPathName(TString(pathSignal)); + pythiaObjectSignal.readFile(pathconfigSignal.Data()); + pythiaObjectSignal.readString("Random:setSeed on"); + pythiaObjectSignal.readString("Random:seed " + std::to_string(seed)); + // Here we could loada hook, but we want to run MB for this production + // Pythia8::UserHooks *hook = pythia8_userhooks_promptgamma(); + // pythiaObjectSignal.setUserHooksPtr(std::shared_ptr(hook)); + pythiaObjectSignal.init(); + cout << "Initalization complete" << endl; + // Add Sub generators + addSubGenerator(0, "MB generator"); + addSubGenerator(1, "jet-jet generator"); + } + + + /// Destructor + ~GeneratorPythia8GapGenJEMB() = default; + + void setUsedSeed(unsigned int seed) + { + mUsedSeed = seed; + }; + unsigned int getUsedSeed() const + { + return mUsedSeed; + }; + + bool generateEvent() override + { + + // Simple straightforward check to alternate generators + mPythia.event.reset(); + + if (mGeneratedEvents % mInverseTriggerRatio == 0) { + LOG(info) << "Event " << mGeneratedEvents << ", generate signal event"; + // Generate event of interest + Bool_t mGenerationOK = kFALSE; + while (!mGenerationOK) { + mGenerationOK = pythiaObjectSignal.next(); + } + mPythia.event = pythiaObjectSignal.event; + setEventHeaderProperties(pythiaObjectSignal); + LOG(info) << "--- Print info properties custom..."; + printEventHeaderProperties(pythiaObjectSignal); + notifySubGenerator(1); + } + else { + LOG(info) << "Event " << mGeneratedEvents << ", generate mb event"; + // Generate minimum-bias event + Bool_t mGenerationOK = kFALSE; + while (!mGenerationOK) { + mGenerationOK = pythiaObjectMinimumBias.next(); + } + mPythia.event = pythiaObjectMinimumBias.event; + setEventHeaderProperties(pythiaObjectMinimumBias); + LOG(info) << "--- Print info properties custom..."; + printEventHeaderProperties(pythiaObjectMinimumBias); + notifySubGenerator(0); + } + mGeneratedEvents++; + return true; + } + + // for testing + void printEventHeaderProperties (Pythia8::Pythia &pythiaObject) { + LOG(info) << "Info name = " << pythiaObject.info.name(); + LOG(info) << "Info code = " << pythiaObject.info.code(); + LOG(info) << "Info weight = " << pythiaObject.info.weight(); + LOG(info) << "Info id1pdf = " << pythiaObject.info.id1pdf(); + LOG(info) << "Info id2pdf = " << pythiaObject.info.id2pdf(); + + LOG(info) << "Info x1pdf = " << pythiaObject.info.x1pdf(); + LOG(info) << "Info x2pdf = " << pythiaObject.info.x2pdf(); + LOG(info) << "Info QFac = " << pythiaObject.info.QFac(); + LOG(info) << "Info pdf1 = " << pythiaObject.info.pdf1(); + LOG(info) << "Info pdf2 = " << pythiaObject.info.pdf2(); + + // Set cross section + LOG(info) << "Info sigmaGen = " << pythiaObject.info.sigmaGen(); + LOG(info) << "Info sigmaErr = " << pythiaObject.info.sigmaErr(); + + // Set event scale and nMPI + LOG(info) << "Info QRen = " << pythiaObject.info.QRen(); + LOG(info) << "Info nMPI = " << pythiaObject.info.nMPI(); + + // Set accepted and attempted values + LOG(info) << "Info accepted = " << pythiaObject.info.nAccepted(); + LOG(info) << "Info attempted = " << pythiaObject.info.nTried(); + + // Set weights (overrides cross-section for each weight) + size_t iw = 0; + auto xsecErr = pythiaObject.info.weightContainerPtr->getTotalXsecErr(); + for (auto w : pythiaObject.info.weightContainerPtr->getTotalXsec()) { + std::string post = (iw == 0 ? "" : "_" + std::to_string(iw)); + LOG(info) << "Info weight by index = " << pythiaObject.info.weightValueByIndex(iw); + iw++; + } + + } + + // in order to save the event weight we need to override the following function + // from the inherited o2::eventgen::GeneratorPythia8 class. The event header properties + // are created as members of this class, and are set using the active event generator + // (MB or jet-jet), then propagated to the event header + void updateHeader(o2::dataformats::MCEventHeader* eventHeader) override { + /** update header **/ + using Key = o2::dataformats::MCInfoKeys; + + eventHeader->putInfo(Key::generator, "pythia8"); + eventHeader->putInfo(Key::generatorVersion, PYTHIA_VERSION_INTEGER); + eventHeader->putInfo(Key::processName, name); + eventHeader->putInfo(Key::processCode, code); + eventHeader->putInfo(Key::weight, weight); + + // Set PDF information + eventHeader->putInfo(Key::pdfParton1Id, id1pdf); + eventHeader->putInfo(Key::pdfParton2Id, id2pdf); + eventHeader->putInfo(Key::pdfX1, x1pdf); + eventHeader->putInfo(Key::pdfX2, x2pdf); + eventHeader->putInfo(Key::pdfScale, QFac); + eventHeader->putInfo(Key::pdfXF1, pdf1); + eventHeader->putInfo(Key::pdfXF2, pdf2); + + // Set cross section + eventHeader->putInfo(Key::xSection, sigmaGen * 1e9); + eventHeader->putInfo(Key::xSectionError, sigmaErr * 1e9); + + // Set event scale and nMPI + eventHeader->putInfo(Key::eventScale, QRen); + eventHeader->putInfo(Key::mpi, nMPI); + + // Set accepted and attempted events + eventHeader->putInfo(Key::acceptedEvents, accepted); + eventHeader->putInfo(Key::attemptedEvents, attempted); + + LOG(info) << "--- updated header weight = " << weight; + + // The following is also set in the base class updateHeader function + // but as far as I can tell, there is no Xsec weight in the default + // header so this is not copied over for now + + //size_t iw = 0; + //auto xsecErr = info.weightContainerPtr->getTotalXsecErr(); + //for (auto w : info.weightContainerPtr->getTotalXsec()) { + // std::string post = (iw == 0 ? "" : "_" + std::to_string(iw)); + // eventHeader->putInfo(Key::weight + post, info.weightValueByIndex(iw)); + // eventHeader->putInfo(Key::xSection + post, w * 1e9); + // eventHeader->putInfo(Key::xSectionError + post, xsecErr[iw] * 1e9); + // iw++; + //} + } + + void setEventHeaderProperties (Pythia8::Pythia &pythiaObject) { + + auto& info = pythiaObject.info; + + name = info.name(); + code = info.code(); + weight = info.weight(); + // Set PDF information + id1pdf = info.id1pdf(); + id2pdf = info.id2pdf(); + x1pdf = info.x1pdf(); + x2pdf = info.x2pdf(); + QFac = info.QFac(); + pdf1 = info.pdf1(); + pdf2 = info.pdf2(); + // Set cross section + sigmaGen = info.sigmaGen(); + sigmaErr = info.sigmaErr(); + // Set event scale and nMPI + QRen = info.QRen(); + nMPI = info.nMPI(); + // Set accepted and attempted events + accepted = info.nAccepted(); + attempted = info.nTried(); + } + +private: + // Interface to override import particles + Pythia8::Event mOutputEvent; + + // Properties of selection + unsigned int mUsedSeed; + + // Control gap-triggering + unsigned long long mGeneratedEvents; + int mInverseTriggerRatio; + + // Handling generators + Pythia8::Pythia pythiaObjectMinimumBias; + Pythia8::Pythia pythiaObjectSignal; + + // header info - needed to save event properties + std::string name; + int code; + float weight; + // PDF information + int id1pdf; + int id2pdf; + float x1pdf; + float x2pdf; + float QFac; + float pdf1; + float pdf2; + // cross section + float sigmaGen; + float sigmaErr; + // event scale and nMPI + float QRen; + int nMPI; + // accepted and attempted events + int accepted; + int attempted; +}; + +} // namespace eventgen +} // namespace o2 + +/** generator instance and settings **/ + +FairGenerator* getGeneratorPythia8GapGenJEMB(int inputTriggerRatio = 5, std::string pathMB = "",std::string pathSignal = "") { + auto myGen = new o2::eventgen::GeneratorPythia8GapGenJEMB(inputTriggerRatio, pathMB, pathSignal); + auto seed = (gRandom->TRandom::GetSeed() % 900000000); + myGen->setUsedSeed(seed); + myGen->readString("Random:setSeed on"); + myGen->readString("Random:seed " + std::to_string(seed)); + myGen->readString("HardQCD:all = on"); + return myGen; +} diff --git a/MC/config/PWGGAJE/external/generator/generator_pythia8_gaptrigger_jets_hook.C b/MC/config/PWGGAJE/external/generator/generator_pythia8_gaptrigger_jets_hook.C index 33ac86d92..c3db3294c 100644 --- a/MC/config/PWGGAJE/external/generator/generator_pythia8_gaptrigger_jets_hook.C +++ b/MC/config/PWGGAJE/external/generator/generator_pythia8_gaptrigger_jets_hook.C @@ -130,11 +130,14 @@ public: LOG(info) << "Info sigmaGen = " << pythiaObject.info.sigmaGen(); LOG(info) << "Info sigmaErr = " << pythiaObject.info.sigmaErr(); - // Set event scale and nMPI LOG(info) << "Info QRen = " << pythiaObject.info.QRen(); LOG(info) << "Info nMPI = " << pythiaObject.info.nMPI(); + // Set accepted and attempted values + LOG(info) << "Info accepted = " << pythiaObject.info.nAccepted(); + LOG(info) << "Info attempted = " << pythiaObject.info.nTried(); + // Set weights (overrides cross-section for each weight) size_t iw = 0; auto xsecErr = pythiaObject.info.weightContainerPtr->getTotalXsecErr(); @@ -176,6 +179,11 @@ public: // Set event scale and nMPI eventHeader->putInfo(Key::eventScale, QRen); eventHeader->putInfo(Key::mpi, nMPI); + + // Set accepted and attempted events + eventHeader->putInfo(Key::acceptedEvents, accepted); + eventHeader->putInfo(Key::attemptedEvents, attempted); + LOG(info) << "--- updated header weight = " << weight; // The following is also set in the base class updateHeader function @@ -214,6 +222,9 @@ public: // Set event scale and nMPI QRen = info.QRen(); nMPI = info.nMPI(); + // Set accepted and attempted events + accepted = info.nAccepted(); + attempted = info.nTried(); } private: @@ -249,7 +260,9 @@ private: // event scale and nMPI float QRen; int nMPI; - + // accepted and attempted events + int accepted; + int attempted; }; } // namespace eventgen diff --git a/MC/config/PWGGAJE/external/generator/generator_pythia8_gaptrigger_promptphotons_hook.C b/MC/config/PWGGAJE/external/generator/generator_pythia8_gaptrigger_promptphotons_hook.C new file mode 100644 index 000000000..b138fccb3 --- /dev/null +++ b/MC/config/PWGGAJE/external/generator/generator_pythia8_gaptrigger_promptphotons_hook.C @@ -0,0 +1,279 @@ +R__ADD_INCLUDE_PATH($O2DPG_MC_CONFIG_ROOT) +///#include "FairGenerator.h" +//#include "Generators/GeneratorPythia8.h" +#include "Pythia8/Pythia.h" +#include "MC/config/PWGGAJE/hooks/prompt_gamma_hook.C" +//#include "TRandom.h" +//#include +// +//#include +//#include + +// Prompt-photon custom event generator +// that alternates between 2 gun generators. +// set up to inject MB events alongside prompt-photon events +// in 'MB-gap' mode. +// The number of MB events injected, and the PYTHIA config +// for each event type is defined by the user in the .ini +// generator file (e.g. GeneratorJE_gapgen5_hook.ini) +// +// Author: Adrian Fereydon Nassirpour (adrian.fereydon.nassirpour@cern.ch), based on code from Jaime Norman (jaime.norman@cern.ch) + +namespace o2 +{ +namespace eventgen +{ + +using namespace Pythia8; + + +/// A very simple gap generator alternating between 2 different particle guns +class GeneratorPythia8GapGenJEPhoton : public o2::eventgen::GeneratorPythia8 +{ +public: + /// default constructor + GeneratorPythia8GapGenJEPhoton(int inputTriggerRatio = 5,std::string pathMB = "",std::string pathSignal = "") { + + mGeneratedEvents = 0; + mInverseTriggerRatio = inputTriggerRatio; + + auto seed = (gRandom->TRandom::GetSeed() % 900000000); + + cout << "Initalizing extra PYTHIA object used to generate min-bias events..." << endl; + TString pathconfigMB = gSystem->ExpandPathName(TString(pathMB)); + pythiaObjectMinimumBias.readFile(pathconfigMB.Data()); + pythiaObjectMinimumBias.readString("Random:setSeed on"); + pythiaObjectMinimumBias.readString("Random:seed " + std::to_string(seed)); + pythiaObjectMinimumBias.init(); + cout << "Initalization complete" << endl; + cout << "Initalizing extra PYTHIA object used to generate signal events..." << endl; + TString pathconfigSignal = gSystem->ExpandPathName(TString(pathSignal)); + pythiaObjectSignal.readFile(pathconfigSignal.Data()); + pythiaObjectSignal.readString("Random:setSeed on"); + pythiaObjectSignal.readString("Random:seed " + std::to_string(seed)); + // load jet hook to ensure at least one prompt photon is within detector acceptance + Pythia8::UserHooks *hook = pythia8_userhooks_promptgamma(); + pythiaObjectSignal.setUserHooksPtr(std::shared_ptr(hook)); + pythiaObjectSignal.init(); + cout << "Initalization complete" << endl; + // Add Sub generators + addSubGenerator(0, "MB generator"); + addSubGenerator(1, "jet-jet generator"); + } + + + /// Destructor + ~GeneratorPythia8GapGenJEPhoton() = default; + + void setUsedSeed(unsigned int seed) + { + mUsedSeed = seed; + }; + unsigned int getUsedSeed() const + { + return mUsedSeed; + }; + + bool generateEvent() override + { + + // Simple straightforward check to alternate generators + mPythia.event.reset(); + + if (mGeneratedEvents % mInverseTriggerRatio == 0) { + LOG(info) << "Event " << mGeneratedEvents << ", generate signal event"; + // Generate event of interest + Bool_t mGenerationOK = kFALSE; + while (!mGenerationOK) { + mGenerationOK = pythiaObjectSignal.next(); + } + mPythia.event = pythiaObjectSignal.event; + setEventHeaderProperties(pythiaObjectSignal); + LOG(info) << "--- Print info properties custom..."; + printEventHeaderProperties(pythiaObjectSignal); + notifySubGenerator(1); + } + else { + LOG(info) << "Event " << mGeneratedEvents << ", generate mb event"; + // Generate minimum-bias event + Bool_t mGenerationOK = kFALSE; + while (!mGenerationOK) { + mGenerationOK = pythiaObjectMinimumBias.next(); + } + mPythia.event = pythiaObjectMinimumBias.event; + setEventHeaderProperties(pythiaObjectMinimumBias); + LOG(info) << "--- Print info properties custom..."; + printEventHeaderProperties(pythiaObjectMinimumBias); + notifySubGenerator(0); + } + mGeneratedEvents++; + return true; + } + + // for testing + void printEventHeaderProperties (Pythia8::Pythia &pythiaObject) { + LOG(info) << "Info name = " << pythiaObject.info.name(); + LOG(info) << "Info code = " << pythiaObject.info.code(); + LOG(info) << "Info weight = " << pythiaObject.info.weight(); + LOG(info) << "Info id1pdf = " << pythiaObject.info.id1pdf(); + LOG(info) << "Info id2pdf = " << pythiaObject.info.id2pdf(); + + LOG(info) << "Info x1pdf = " << pythiaObject.info.x1pdf(); + LOG(info) << "Info x2pdf = " << pythiaObject.info.x2pdf(); + LOG(info) << "Info QFac = " << pythiaObject.info.QFac(); + LOG(info) << "Info pdf1 = " << pythiaObject.info.pdf1(); + LOG(info) << "Info pdf2 = " << pythiaObject.info.pdf2(); + + // Set cross section + LOG(info) << "Info sigmaGen = " << pythiaObject.info.sigmaGen(); + LOG(info) << "Info sigmaErr = " << pythiaObject.info.sigmaErr(); + + // Set event scale and nMPI + LOG(info) << "Info QRen = " << pythiaObject.info.QRen(); + LOG(info) << "Info nMPI = " << pythiaObject.info.nMPI(); + + // Set accepted and attempted values + LOG(info) << "Info accepted = " << pythiaObject.info.nAccepted(); + LOG(info) << "Info attempted = " << pythiaObject.info.nTried(); + + // Set weights (overrides cross-section for each weight) + size_t iw = 0; + auto xsecErr = pythiaObject.info.weightContainerPtr->getTotalXsecErr(); + for (auto w : pythiaObject.info.weightContainerPtr->getTotalXsec()) { + std::string post = (iw == 0 ? "" : "_" + std::to_string(iw)); + LOG(info) << "Info weight by index = " << pythiaObject.info.weightValueByIndex(iw); + iw++; + } + + } + + // in order to save the event weight we need to override the following function + // from the inherited o2::eventgen::GeneratorPythia8 class. The event header properties + // are created as members of this class, and are set using the active event generator + // (MB or jet-jet), then propagated to the event header + void updateHeader(o2::dataformats::MCEventHeader* eventHeader) override { + /** update header **/ + using Key = o2::dataformats::MCInfoKeys; + + eventHeader->putInfo(Key::generator, "pythia8"); + eventHeader->putInfo(Key::generatorVersion, PYTHIA_VERSION_INTEGER); + eventHeader->putInfo(Key::processName, name); + eventHeader->putInfo(Key::processCode, code); + eventHeader->putInfo(Key::weight, weight); + + // Set PDF information + eventHeader->putInfo(Key::pdfParton1Id, id1pdf); + eventHeader->putInfo(Key::pdfParton2Id, id2pdf); + eventHeader->putInfo(Key::pdfX1, x1pdf); + eventHeader->putInfo(Key::pdfX2, x2pdf); + eventHeader->putInfo(Key::pdfScale, QFac); + eventHeader->putInfo(Key::pdfXF1, pdf1); + eventHeader->putInfo(Key::pdfXF2, pdf2); + + // Set cross section + eventHeader->putInfo(Key::xSection, sigmaGen * 1e9); + eventHeader->putInfo(Key::xSectionError, sigmaErr * 1e9); + + // Set event scale and nMPI + eventHeader->putInfo(Key::eventScale, QRen); + eventHeader->putInfo(Key::mpi, nMPI); + + // Set accepted and attempted events + eventHeader->putInfo(Key::acceptedEvents, accepted); + eventHeader->putInfo(Key::attemptedEvents, attempted); + + LOG(info) << "--- updated header weight = " << weight; + + // The following is also set in the base class updateHeader function + // but as far as I can tell, there is no Xsec weight in the default + // header so this is not copied over for now + + //size_t iw = 0; + //auto xsecErr = info.weightContainerPtr->getTotalXsecErr(); + //for (auto w : info.weightContainerPtr->getTotalXsec()) { + // std::string post = (iw == 0 ? "" : "_" + std::to_string(iw)); + // eventHeader->putInfo(Key::weight + post, info.weightValueByIndex(iw)); + // eventHeader->putInfo(Key::xSection + post, w * 1e9); + // eventHeader->putInfo(Key::xSectionError + post, xsecErr[iw] * 1e9); + // iw++; + //} + } + + void setEventHeaderProperties (Pythia8::Pythia &pythiaObject) { + + auto& info = pythiaObject.info; + + name = info.name(); + code = info.code(); + weight = info.weight(); + // Set PDF information + id1pdf = info.id1pdf(); + id2pdf = info.id2pdf(); + x1pdf = info.x1pdf(); + x2pdf = info.x2pdf(); + QFac = info.QFac(); + pdf1 = info.pdf1(); + pdf2 = info.pdf2(); + // Set cross section + sigmaGen = info.sigmaGen(); + sigmaErr = info.sigmaErr(); + // Set event scale and nMPI + QRen = info.QRen(); + nMPI = info.nMPI(); + // Set accepted and attempted events + accepted = info.nAccepted(); + attempted = info.nTried(); + } + +private: + // Interface to override import particles + Pythia8::Event mOutputEvent; + + // Properties of selection + unsigned int mUsedSeed; + + // Control gap-triggering + unsigned long long mGeneratedEvents; + int mInverseTriggerRatio; + + // Handling generators + Pythia8::Pythia pythiaObjectMinimumBias; + Pythia8::Pythia pythiaObjectSignal; + + // header info - needed to save event properties + std::string name; + int code; + float weight; + // PDF information + int id1pdf; + int id2pdf; + float x1pdf; + float x2pdf; + float QFac; + float pdf1; + float pdf2; + // cross section + float sigmaGen; + float sigmaErr; + // event scale and nMPI + float QRen; + int nMPI; + // accepted and attempted events + int accepted; + int attempted; +}; + +} // namespace eventgen +} // namespace o2 + +/** generator instance and settings **/ + +FairGenerator* getGeneratorPythia8GapGenJEPhoton(int inputTriggerRatio = 5, std::string pathMB = "",std::string pathSignal = "") { + auto myGen = new o2::eventgen::GeneratorPythia8GapGenJEPhoton(inputTriggerRatio, pathMB, pathSignal); + auto seed = (gRandom->TRandom::GetSeed() % 900000000); + myGen->setUsedSeed(seed); + myGen->readString("Random:setSeed on"); + myGen->readString("Random:seed " + std::to_string(seed)); + myGen->readString("HardQCD:all = on"); + return myGen; +} diff --git a/MC/config/PWGGAJE/external/generator/generator_pythia8_powheg.C b/MC/config/PWGGAJE/external/generator/generator_pythia8_powheg.C index 6ca884dda..5c3afd206 100644 --- a/MC/config/PWGGAJE/external/generator/generator_pythia8_powheg.C +++ b/MC/config/PWGGAJE/external/generator/generator_pythia8_powheg.C @@ -4,6 +4,7 @@ R__ADD_INCLUDE_PATH($O2DPG_MC_CONFIG_ROOT) #include "Pythia8/Pythia.h" #include "Generators/GeneratorPythia8Param.h" #include "CommonUtils/FileSystemUtils.h" +#include // Pythia8 generator with POWHEG // // Author: Marco Giacalone (marco.giacalone@cern.ch) @@ -13,7 +14,7 @@ R__ADD_INCLUDE_PATH($O2DPG_MC_CONFIG_ROOT) generator/generator_pythia8_powheg.C;GeneratorExternal.funcName=\ getGeneratorJEPythia8POWHEG(\"powheg.input\",\"${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGGAJE/pythia8/generator/pythia8_powheg.cfg\")" // or with iniFile -// o2-sim -g external --noGeant -n 2 -j 8 --configFile $O2DPG_MC_CONFIG_ROOT/MC/config/PWGGAJE/ini/GeneratorPythia8POWHEG.ini +// o2-sim -g external --noGeant -n 2 -j 8 --configFile $O2DPG_MC_CONFIG_ROOT/MC/config/PWGGAJE/ini/GeneratorPythia8POWHEG_beauty.ini namespace o2 { @@ -22,10 +23,11 @@ namespace eventgen using namespace Pythia8; -// Pythia8 generator using POWHEG data that are generated during the initialization -// of the external generator. The POWHEG configuration file is copied to the current -// directory with the right name and the POWHEG events are generated using the executable -// specified via the type parameter, namely: +// Pythia8 generator using POWHEG data that are generated partially during the initialization +// of the external generator and then during the generateEvent when mNMaxPerJob is reached. The first time +// all the configuration files are created so that the other jobs can be run much faster (and in parallel in the future) +// The POWHEG configuration file is copied to the current directory with the right name and the POWHEG events are generated +// using the executable specified via the type parameter, namely: // 0: pwhg_main_hvq // 1: pwhg_main_W // 2: pwhg_main_Z @@ -35,7 +37,7 @@ class GeneratorJEPythia8POWHEG : public o2::eventgen::GeneratorPythia8 { public: /// default constructor - GeneratorJEPythia8POWHEG(std::string confpath = "pwgpath", short int type = 0) + GeneratorJEPythia8POWHEG(std::string confpath = "pwgpath", short int type = 0, int maxEventsPerJob = 50) { // Assign events to generate with POWHEG unsigned int nPowhegEvents = getTotalNEvents(); @@ -43,23 +45,58 @@ public: LOG(fatal) << "Number of events not set or set to 0."; exit(1); } - // Check on nEvents to generate with POWHEG - // due to integer limit hardcoded in the generator - if (nPowhegEvents > std::numeric_limits::max()) { - LOG(fatal) << "Number of events for POWHEG exceeds the maximum allowed value"; + // POWHEG has an integer limit hardcoded for the nEvents, but + // with the multiple jobs setup this is not an issue (an error will automatically be thrown) + mNMaxPerJob = maxEventsPerJob; + if (mNMaxPerJob < 1) { + LOG(fatal) << "Number of events per job are set to 0 or lower."; exit(1); } + mNFiles = nPowhegEvents / mNMaxPerJob; + if (nPowhegEvents % mNMaxPerJob != 0) + { + mNFiles++; + } + gRandom->SetSeed(0); + if(!confMaker(confpath)) + { + LOG(fatal) << "Failed to edit POWHEG configuration file"; + exit(1); + } + mPowhegConf = confpath; + // Get POWHEG executable to use + if (type >= mPowhegGen.size()) { + LOG(warn) << "Available POWHEG generators are:"; + for (int k = 0; k < mPowhegGen.size(); k++) + { + LOG(warn) << "\t" << k << ": " << mPowhegGen[k]; + } + LOG(fatal) << "POWHEG generator type " << type << " not found"; + exit(1); + } else { + LOG(info) << "Running POWHEG using the " << mPowhegGen[type] << " executable"; + // Generate the POWHEG events + mExePOW = mPowhegGen[type] + " &"; + system(mExePOW.c_str()); + } + }; + + Bool_t confMaker(std::string confpath = "pwgpath", bool parallel = false) + { // Check if file exist and is not empty if (std::filesystem::exists(confpath) && std::filesystem::file_size(confpath) > 0) { // Copy the file to the current directory ifstream src(confpath); ofstream dst("powheg.input"); - gRandom->SetSeed(0); int seed = gRandom->Integer(900000000); bool isseed = false; bool isnumevts = false; + if (mCurrFile == mNFiles - 1 && getTotalNEvents() % mNMaxPerJob != 0) { + mNMaxPerJob = getTotalNEvents() % mNMaxPerJob; + } std::string line; - while (std::getline(src, line)) { + while (std::getline(src, line)) + { if (line.find("iseed") != std::string::npos) { // Set the seed to the random number @@ -69,42 +106,129 @@ public: if (line.find("numevts") != std::string::npos) { // Set the number of events to the number of events defined in the configuration - line = "numevts " + std::to_string(nPowhegEvents); + line = "numevts " + std::to_string(mNMaxPerJob); // replace it in the file isnumevts = true; } dst << line << std::endl; } - if (!isseed) { + if (!isseed) + { dst << "iseed " << seed << std::endl; } - if (!isnumevts) { - dst << "numevts " << nPowhegEvents << std::endl; + if (!isnumevts) + { + dst << "numevts " << mNMaxPerJob << std::endl; + } + if (parallel) + { + dst << "manyseeds 1" << std::endl; // Enables the usage of pwgseeds.dat file to set the seed in parallel mode + dst << "parallelstage 4" << std::endl; // Allows event generation based on pre-generated POWHEG configuration files (needed for certain configurations) } src.close(); dst.close(); } else { LOG(fatal) << "POWHEG configuration file not found or empty" << std::endl; - exit(1); + return false; } - // Get POWHEG executable to use - if (type >= mPowhegGen.size()) { - LOG(warn) << "Available POWHEG generators are:"; - for (int k = 0; k < mPowhegGen.size(); k++) - { - LOG(warn) << "\t" << k << ": " << mPowhegGen[k]; + return true; + } + + Bool_t startPOW() + { + if(mCurrFile == 1) { + if (!confMaker(mPowhegConf, true)) { + LOG(fatal) << "Failed to edit POWHEG configuration with parallelisation"; + return false; } - LOG(fatal) << "POWHEG generator type " << type << " not found"; - exit(1); + } + LOG(info) << "Starting POWHEG job " << mCurrFile+1 << " of " << mNFiles; + system(("echo " + std::to_string(mCurrFile - 1) + " | " + mExePOW).c_str()); + return true; + } + + Bool_t checkEOF() { + // Check if the POWHEG generation is done + int result = system(("grep -q /LesHouchesEvents " + mLHEFoutput).c_str()); + if (result == 0) + { + return true; } else { - LOG(info) << "Running POWHEG using the " << mPowhegGen[type] << " executable"; - // Generate the POWHEG events - system(mPowhegGen[type].c_str()); + return false; + } + } + + Bool_t POWchecker() { + // Check if the POWHEG events file exists + LOG(info) << "Waiting for " << mLHEFoutput << " to exist"; + while (!std::filesystem::exists(mLHEFoutput.c_str())) + { + std::this_thread::sleep_for(std::chrono::milliseconds(100)); + } + LOG(info) << "POWHEG events file for job " << mCurrFile << " found"; + while (!checkEOF()) + { + std::this_thread::sleep_for(std::chrono::milliseconds(100)); + } + LOG(info) << "POWHEG events ready"; + return true; + } + + // Check for the POWHEG events file existance + Bool_t Init() override + { + // Check if the POWHEG events file exists + if(POWchecker()) { + return GeneratorPythia8::Init(); + } else { + return false; + } + }; + + // Set Generator ReadEvent to wait for the POWHEG events + Bool_t generateEvent() override + { + /** Reinitialise when EOF is reached **/ + if (mPythia.info.atEndOfFile()) + { + if(mCurrFile == 0) + { + mPythia.readString("Beams:newLHEFsameInit = on"); + // Create pwgseeds.dat file with a random seed for each line + std::ofstream seedfile("pwgseeds.dat"); + for (int i = 0; i < mNFiles - 1; i++) + { + seedfile << gRandom->Integer(900000000) << std::endl; + } + seedfile.close(); + } + mCurrFile++; + mLHEFoutput = Form("pwgevents-%04d.lhe", mCurrFile - 1); + mPythia.readString(Form("Beams:LHEF = %s", mLHEFoutput.c_str())); + if(!startPOW()) + { + return false; + } + if (POWchecker()) { + // If Pythia fails to initialize, exit with error. + if (!mPythia.init()) + { + LOG(fatal) << "Failed to init \'Pythia8\': init returned with error"; + return false; + } + } } + return GeneratorPythia8::generateEvent(); }; private: const std::vector mPowhegGen = {"pwhg_main_hvq", "pwhg_main_W", "pwhg_main_Z", "pwhg_main_dijet", "pwhg_main_directphoton"}; // POWHEG executables + short int mNFiles = 1; + short int mCurrFile = 0; + std::string mExePOW = ""; + std::string mPowhegConf = ""; + std::string mLHEFoutput = "pwgevents.lhe"; + int mNMaxPerJob = 50; }; } // namespace eventgen @@ -112,13 +236,13 @@ private: /** generator instance and settings **/ -FairGenerator *getGeneratorJEPythia8POWHEG(std::string powhegconf = "pwgpath", std::string pythia8conf = "", short int type = 0) +FairGenerator *getGeneratorJEPythia8POWHEG(std::string powhegconf = "pwgpath", std::string pythia8conf = "", short int type = 0, int maxEventsPerJob = 1e4) { using namespace o2::eventgen; // Expand paths for the POWHEG configuration file powhegconf = o2::utils::expandShellVarsInFileName(powhegconf); LOG(info) << "Using POWHEG configuration file: " << powhegconf; - auto myGen = new GeneratorJEPythia8POWHEG(powhegconf, type); + auto myGen = new GeneratorJEPythia8POWHEG(powhegconf, type, maxEventsPerJob); if(GeneratorPythia8Param::Instance().config.empty() && pythia8conf.empty()) { LOG(fatal) << "No configuration provided for Pythia8"; } @@ -131,4 +255,4 @@ FairGenerator *getGeneratorJEPythia8POWHEG(std::string powhegconf = "pwgpath", s myGen->setConfig(pythia8conf); } return myGen; -} \ No newline at end of file +} diff --git a/MC/config/PWGGAJE/external/generator/parametrisedJetModel/generator_pythia8_box_parametrisedModel_pythia6Fragmentation.C b/MC/config/PWGGAJE/external/generator/parametrisedJetModel/generator_pythia8_box_parametrisedModel_pythia6Fragmentation.C new file mode 100644 index 000000000..e07298280 --- /dev/null +++ b/MC/config/PWGGAJE/external/generator/parametrisedJetModel/generator_pythia8_box_parametrisedModel_pythia6Fragmentation.C @@ -0,0 +1,397 @@ +#if !defined(__CLING__) || defined(__ROOTCLING__) + +#include "FairGenerator.h" +#include "FairPrimaryGenerator.h" +#include "Generators/GeneratorPythia8.h" +#include "TDatabasePDG.h" +#include "TF1.h" +#include "TGrid.h" +#include "TMath.h" +#include "TParticlePDG.h" +#include "TRandom3.h" +#include +#endif + +#include "Pythia8/Pythia.h" +#include +#include + +R__LOAD_LIBRARY(libpythia6) +R__LOAD_LIBRARY(libGeneratorParam) +#include "TPythia6.h" + +using namespace Pythia8; + +// #include "SimulationDataFormat/ParticleStatus.h" +// #include "SimulationDataFormat/MCEventHeader.h" + +// Input to simulation: +// inputFilePathName file is expected to be a json file with the structure like so: +// { +// "simLog": false, +// "sglGenRAA": 1, +// "sglGenTAA": 1, +// "sglCutoffSteepNess": 15, +// "sglCutoffAbscissa": 10, +// "fallSpecterSlopeLog": 10.833274, +// "fallSpecterAffinePowerConstantTerm": -5.476804, +// "fallSpecterAffinePowerSlope": 0.001110, +// "bkgAveragePt": 0.670, +// "collTotalMultWithBkg": 2000 +// } +// can be uploaded to grid using for example: alien.py cp +// file:/local/path/parametrisedModel_PbPb_5p36TeV_cent0010.json +// alien:/path/on/alien/parametrisedModel_PbPb_5p36TeV_cent0010.json + +class GeneratorParametrisedJetModel : public o2::eventgen::GeneratorPythia8 { +public: + /// constructor + GeneratorParametrisedJetModel(std::string inputSimParametersPath, std::string inputSimParametersFileName, bool generateUE = true) : mInputSimParametersPath{inputSimParametersPath}, mInputSimParametersFileName{inputSimParametersFileName}, mGenerateUE{generateUE} { + + std::string inputFilePathName = "alien://" + inputSimParametersPath + inputSimParametersFileName; + if (!gGrid) { + TGrid::Connect("alien://"); + if (!gGrid) { + LOG(fatal) << "AliEn connection failed, check token."; + exit(1); + } + } + // fetch and copy the .json file to the sim work directory + std::string outputPath = "./"; + TString aliencp = Form("alien_cp alien://%s%s file:%s%s", inputSimParametersPath.c_str(), + inputSimParametersFileName.c_str(), outputPath.c_str(), + inputSimParametersFileName.c_str()); // an internal operation in ROOT that discards the + // JSON file directly (smaller than 300 bytes and if + // a bit bigger it would discard the file because it + // understands it's not a ROOT file), thus one + // cannot use TFile::Cp() + if (gSystem->Exec(aliencp.Data()) != 0) { + cout << "Error: Sim parameters .json file " << inputFilePathName << " does not exist!" << endl; + exit(1); + } + // open the file + std::FILE *fjson = std::fopen(inputSimParametersFileName.c_str(), "r"); + if (!fjson) { + cout << "Could not open sim parameters file " << inputFilePathName << endl; + exit(1); + } + + // create streamer + char readBuffer[65536]; + rapidjson::FileReadStream jsonStream(fjson, readBuffer, sizeof(readBuffer)); + + // parse the json file + rapidjson::Document jsonDocument; + jsonDocument.ParseStream(jsonStream); + + // is it a proper json document? + if (jsonDocument.HasParseError()) { + cout << "Check the sim parameters file! There is a problem with the format!" << endl; + exit(1); + } + + // are the parameter names as expected? + for (const std::string ¶meterName : mConfigurableSimParameterNames) { + if (!jsonDocument.HasMember(parameterName.c_str())) { + cout << "Check the sim parameters file! Item " << parameterName << " is missing!" << endl; + exit(1); + } + } + + // write log of simulation? + std::string writeLog("simLog"); + if (!jsonDocument.HasMember(writeLog.c_str())) { + cout << "Check the sim parameters file! Item " << writeLog.c_str() << " is missing!" << endl; + exit(1); + } + mDebug = jsonDocument[writeLog.c_str()].GetBool(); + + // get parameters for sim + mSglGenRAA = jsonDocument[mConfigurableSimParameterNames.at(0).c_str()].GetDouble(); + mSglGenTAA = jsonDocument[mConfigurableSimParameterNames.at(1).c_str()].GetDouble(); + mSglCutoffSteepNess = jsonDocument[mConfigurableSimParameterNames.at(2).c_str()].GetDouble(); + mSglCutoffAbscissa = jsonDocument[mConfigurableSimParameterNames.at(3).c_str()].GetDouble(); + mFallSpecterSlopeLog = jsonDocument[mConfigurableSimParameterNames.at(4).c_str()].GetDouble(); + mFallSpecterAffinePowerConstantTerm = jsonDocument[mConfigurableSimParameterNames.at(5).c_str()].GetDouble(); + mFallSpecterAffinePowerSlope = jsonDocument[mConfigurableSimParameterNames.at(6).c_str()].GetDouble(); + mBkgAveragePt = jsonDocument[mConfigurableSimParameterNames.at(7).c_str()].GetDouble(); + mCollTotalMultWithBkg = jsonDocument[mConfigurableSimParameterNames.at(8).c_str()].GetDouble(); + + // clean up + std::fclose(fjson); + + cout << "param retrieved: mSglGenRAA = " << mSglGenRAA << endl; + cout << "param retrieved: mSglGenTAA = " << mSglGenTAA << endl; + cout << "param retrieved: mSglCutoffSteepNess = " << mSglCutoffSteepNess << endl; + cout << "param retrieved: mSglCutoffAbscissa = " << mSglCutoffAbscissa << endl; + cout << "param retrieved: mFallSpecterSlopeLog = " << mFallSpecterSlopeLog << endl; + cout << "param retrieved: mFallSpecterAffinePowerConstantTerm = " << mFallSpecterAffinePowerConstantTerm << endl; + cout << "param retrieved: mFallSpecterAffinePowerSlope = " << mFallSpecterAffinePowerSlope << endl; + cout << "param retrieved: mBkgAveragePt = " << mBkgAveragePt << endl; + cout << "param retrieved: mCollTotalMultWithBkg = " << mCollTotalMultWithBkg << endl; + + // thermal background function + mBoltzmannPDF = new TF1("f1", "[0]*[0]*x*exp(-[0]*x)", mBkgGenPtMin, mPtInfinity); + mBoltzmannPDF->SetParameter(0, 2. / mBkgAveragePt); + + // jet signal function + // this thesis says that the jet distrib used to sample parton pt is + // actually full jet -> solves neutral particle fragments issue (better than + // scaling) https://drupal.star.bnl.gov/STAR/files/phd_thesis_rusnak.pdf for + // the fragments radiating outside of the jet radius issue: instead of using + // this PYTHIA distrib directly as the truth distrib in unfolding closure, + // instead we do the same sim+jet reco, but without the bkg; so need to have + // the option to run with and without UE bkg probably should use biggest + // Radius one can find with good stats for the pp PYTHIA + mJetYieldFit = new TF1("f2", "[0]*[1]*exp(-exp(-[2]*(x-[3]))) * exp([4])*pow(x, [5]+[6]*x)", 0, mPtInfinity); // RAA * TAA * sigmoid(cutoff at [2]) * fit to fulljetSpectrum in pp PYTHIA + mJetYieldFit->SetParameter(0, mSglGenRAA); // rAA (single value for all pt) + mJetYieldFit->SetParameter(1, mSglGenTAA); // + mJetYieldFit->SetParameter(2, mSglCutoffSteepNess); // steepness for the cutoff shape; higher is + // steeper, but looks more and more like a + // Heavyside step function as it gets to 50 or 100 + mJetYieldFit->SetParameter(3, mSglCutoffAbscissa); // cutoffpoint of hard population, in GeV/c + mJetYieldFit->SetParameter(4, mFallSpecterSlopeLog); // falling spectrum ln() of proportionality factor + mJetYieldFit->SetParameter(5, mFallSpecterAffinePowerConstantTerm); // falling spectrum affine power: constant term + mJetYieldFit->SetParameter(6, mFallSpecterAffinePowerSlope); // falling spectrum affine power: proportionality factor + // values from full jet spectra fit of R=0.6 jets in + // https://journals.aps.org/prc/abstract/10.1103/PhysRevC.101.034911; + // hepdata link: https://www.hepdata.net/record/ins1755387 done using TF1* + // fitFullJetSpectrum = new TF1(fname, "exp([0]) * pow(x, [1] + [2]*x)", + // fitMin, fitMax); fit, parameters first initialised by fitting + // log(fullSpectrum) with log(fitFullJetSpectrum tf1); + + mNJetsAverage = mJetYieldFit->Integral(mSglCutoffAbscissa, mPtInfinity); // careful, this script assumes the mJetYieldFit is the + // pt-differential yield, integrated over eta + + mPythia.init(); // Initialize + } + + /// Destructor + ~GeneratorParametrisedJetModel() = default; + + Bool_t generateEvent() override { + if (mDebug) { + cout << "##########################################################################################################" << endl; + cout << "###################################### Beginning of generateEvent() ######################################" << endl; + cout << "##########################################################################################################" << endl; + } + + mPythia.event.reset(); + + /////////////////////////////////////////////// + ////////////////// Jet signal ///////////////// + /////////////////////////////////////////////// + + int nJets = gRandom->Poisson(mNJetsAverage); + + if (mDebug) { + cout << "####################### creating partons signal #######################" << endl; + cout << "signal: count " << nJets << " for mNJetsAverage = " << mNJetsAverage << "" << endl; + } + + TClonesArray *genParticlesArray = new TClonesArray("TParticle", 1000); + + int particleCountCurrent = 1; // counts the system fake particle pdg 90 + for (int iJet{0}; iJet < nJets; ++iJet) { + genParticlesArray->Delete(); + + const bool isQuark = gRandom->Uniform(0, 1) > 1. / 3 ? true : false; // ratio quarks:gluons = 2:1 + const int pdgQuark = gRandom->Uniform(0, 1) > 1. / 2 ? mPdgQuarkU : mPdgQuarkD; // half and half for u and d quarks + const int pdgJet = (int)isQuark * pdgQuark + (1 - (int)isQuark) * mPdgGluon; + const double sglMass = TDatabasePDG::Instance()->GetParticle(pdgJet)->Mass(); + const double sglPt = mJetYieldFit->GetRandom(mSglCutoffAbscissa, mPtInfinity); + const double sglEta = gRandom->Uniform(mGenMinEta, mGenMaxEta); + const double sglPhi = gRandom->Uniform(0, o2::constants::math::TwoPI); + const double sglPx{sglPt * std::cos(sglPhi)}; + const double sglPy{sglPt * std::sin(sglPhi)}; + const double sglPz{sglPt * std::sinh(sglEta)}; + const double sglEt{std::hypot(std::hypot(sglPt, sglPz), sglMass)}; + + Particle myJet; + myJet.id(pdgJet); + myJet.status(23); + myJet.px(sglPx); + myJet.py(sglPy); + myJet.pz(sglPz); + myJet.e(sglEt); + myJet.m(sglMass); + myJet.xProd(0); + myJet.yProd(0); + myJet.zProd(0); + int jetCol = 101 + 2 * iJet; // each jet gets a different colour and acolour value, + // so that the pythia knows they're distinct colour + // lines, i.e. different strings + int jetACol = 101 + 2 * iJet + 1; + + if (mDebug) { + cout << "-- || jet parton #" << iJet + << ", index=" << mPythia.event.back().index() + 1 + << ": isQuark = " << isQuark << ", pdg = " << pdgJet + << ", pt = " << sglPt << ", mass = " << sglMass << endl; + } + + auto pythia6Event = TPythia6::Instance(); + + int lineNumber = 0; // line number seems to be index of particle in array; set to 0 in + // PM code? but doc says it runs Pyexec() right after; iJet doesn't + // work for ijet=1+; set to 0 and it seems to work + double sglTheta = 2.0 * std::atan(std::exp(-1 * sglEta)); + pythia6Event->Py1ent(lineNumber, pdgJet, sglEt, sglTheta, sglPhi); + + int final = pythia6Event->ImportParticles(genParticlesArray, "Final"); // only saves final state particles; "All" would instead give all the particles + int nConstituents = genParticlesArray->GetEntries(); + + mPythia.event.append(myJet); + for (int iParticle = 0; iParticle < nConstituents; ++iParticle) { + TParticle *tParticle = (TParticle *)genParticlesArray->At(iParticle); + + Particle pythiaParticle; + pythiaParticle.id(tParticle->GetPdgCode()); + pythiaParticle.status(tParticle->GetStatusCode()); // in pythia6 all the particles that are not + // the initial partons have status code 1; + // this is because apparently pythia6 does + // not decay them automatically yet; they + // are by no means all stable particles; but + // we do not care for this study + pythiaParticle.px(tParticle->Px()); + pythiaParticle.py(tParticle->Py()); + pythiaParticle.pz(tParticle->Pz()); + pythiaParticle.e(tParticle->Energy()); + pythiaParticle.m(tParticle->GetMass()); + pythiaParticle.xProd(tParticle->Vx()); + pythiaParticle.yProd(tParticle->Vy()); + pythiaParticle.zProd(tParticle->Vz()); + pythiaParticle.mother1(particleCountCurrent); // particleCountCurrent is the offset to account for existing IDs of constituents of previous jets. + // Not saving the actual mother ID because ImportParticles(genParticlesArray, "Final") only saves the final + // particles, and the mother id still refer to particles not saved in + // genParticlesArray a priori the mother-daughter links aren't needed + // for the closure test this will be used for; keeping the initial + // parton as mother for now + + mPythia.event.append(pythiaParticle); + } + particleCountCurrent += nConstituents + 1; // +1 is for the jet parton itself, which is not in the final state + } + delete genParticlesArray; + + if (mDebug) { + mPythia.event.list(); + } + + /////////////////////////////////////////////// + // Underlying Event (UE): thermal background // + /////////////////////////////////////////////// + + if (mGenerateUE) { + int nHardParticles = mPythia.event.size() - 1; // number of particles after hadronisation of jet partons and pruning, -1 because of system particle with pdg id 90 + int sign = 1; + if (mDebug) { + cout << "####################### Adding Thermal Background #######################" << endl; + } + for (int iBkg{0}; iBkg < mCollTotalMultWithBkg - nHardParticles; ++iBkg) { + const double bkgPt = mBoltzmannPDF->GetRandom(mBkgGenPtMin, mPtInfinity); + const double bkgEta = gRandom->Uniform(mGenMinEta, mGenMaxEta); + const double bkgPhi = gRandom->Uniform(0, o2::constants::math::TwoPI); + const double bkgPx{bkgPt * std::cos(bkgPhi)}; + const double bkgPy{bkgPt * std::sin(bkgPhi)}; + const double bkgPz{bkgPt * std::sinh(bkgEta)}; + const double bkgEt{std::hypot(std::hypot(bkgPt, bkgPz), mBkgMass)}; + sign *= gRandom->Uniform(0, 1) > 0.5 ? 1 : -1; + + Particle myParticle; + myParticle.id(sign * + mPdgPion); // let's make them pions until further notice + myParticle.status(201); // 201+ free to use by anybody; using 201 to know if's from background + // https://pythia.org/latest-manual/ParticleProperties.html; + myParticle.px(bkgPx); + myParticle.py(bkgPy); + myParticle.pz(bkgPz); + myParticle.e(bkgEt); + myParticle.m(mBkgMass); + myParticle.xProd(0); + myParticle.yProd(0); + myParticle.zProd(0); + + if (iBkg % 100 == 0 && mDebug) { + cout << "------- ||||| bkg particle " << iBkg << ": pt = " << bkgPt << endl; + } + + mPythia.event.append(myParticle); + } + } + + if (mDebug) { + cout << "##########################################################################################################" << endl; + cout << "######################################## End of generateEvent() ##########################################" << endl; + cout << "##########################################################################################################" << endl; + } + return true; + } + + //__________________________________________________________________ + +private: + bool mDebug = false; // setting to true will display particle lists + std::string mInputSimParametersPath, mInputSimParametersFileName; // input path and file name of .json used to read simulation parameters + + //////////////////////////////////////////////// + ///////// Common signal and background parameters //////// + //////////////////////////////////////////////// + + const double mPtInfinity = 300; // maximum pt (in GeV/c) for generated particles, and upper pT limit for integral and TF1 purposes; too high and GetRandom struggles + const double mGenMinEta = -1.; /// minimum pseudorapidity for generated particles + const double mGenMaxEta = +1.; /// maximum pseudorapidity for generated particles + int mCollTotalMultWithBkg; /// total multiplicity of the collision + bool mGenerateUE = false; /// boolean to request (or not) embedding of the jet signal inside underlying event modelled by a thermal background + const std::vector mConfigurableSimParameterNames = { + "sglGenRAA", + "sglGenTAA", + "sglCutoffSteepNess", + "sglCutoffAbscissa", + "fallSpecterSlopeLog", + "fallSpecterAffinePowerConstantTerm", + "fallSpecterAffinePowerSlope", + "bkgAveragePt", + "collTotalMultWithBkg"}; + + ///////////////////////////////////////////// + /////// Thermal background parameters /////// + ///////////////////////////////////////////// + + // bkg fit + TF1 *mBoltzmannPDF; /// TF1 to store pdf function from which pt is drawn + double mBkgAveragePt; + const double mBkgGenPtMin = 0; /// minimum pt (in GeV/c) for generated particles + const double mBkgMass = 0; /// particle mass [GeV/c^2] + + // bkg pdg code + const int mPdgPion = 211; /// particle pdg code of pion check that is not + /// defined somewhere already + + ///////////////////////////////////// + /////// Jet signal parameters /////// + ///////////////////////////////////// + + // signal fit + double mSglGenRAA; + double mSglGenTAA; + double mSglCutoffSteepNess; /// steepness for the cutoff shape; higher is steeper, but looks more and more like a Heavyside step function as it gets to 50 or 100 + double mSglCutoffAbscissa; /// minimum pt (in GeV/c) for jet signal distribution; it's a smooth cutoff + double mFallSpecterSlopeLog; + double mFallSpecterAffinePowerConstantTerm; + double mFallSpecterAffinePowerSlope; + TF1 *mJetYieldFit; /// TF1 to store pdf function from which pt is drawn + double mNJetsAverage; /// average number of jets in a collision + + // signal pdg codes + const int mPdgQuarkU = 1; /// particle pdg code of quark u + const int mPdgQuarkD = 2; /// particle pdg code of quark d + const int mPdgGluon = 21; /// particle pdg code of gluon +}; + +///___________________________________________________________ +FairGenerator *generateParametrisedJetModel(std::string inputSimParametersPath, + std::string inputSimParametersFileName, + bool generateUE = true) { + return new GeneratorParametrisedJetModel(inputSimParametersPath, inputSimParametersFileName, generateUE); +} \ No newline at end of file diff --git a/MC/config/PWGGAJE/external/powheg/powheg_jetjet_13600.input b/MC/config/PWGGAJE/external/powheg/powheg_jetjet_13600.input new file mode 100755 index 000000000..c51aebbe8 --- /dev/null +++ b/MC/config/PWGGAJE/external/powheg/powheg_jetjet_13600.input @@ -0,0 +1,90 @@ +numevts 10 ! number of events to be generated +ih1 1 ! hadron 1 (1 for protons, -1 for antiprotons) +ih2 1 ! hadron 2 (1 for protons, -1 for antiprotons) +ebeam1 6800d0 ! energy of beam 1 +ebeam2 6800d0 ! energy of beam 2 + +bornktmin 1d0 ! (default 0d0) Generation cut: minimum kt in underlying Born +bornsuppfact 120d0 ! (default 0d0) Mass parameter for Born suppression factor. + ! If < 0 suppfact = 1. + + +! To be set only if using internal (mlm) pdfs +! 131 cteq6m +! ndns1 131 ! pdf set for hadron 1 (mlm numbering) +! ndns2 131 ! pdf set for hadron 2 (mlm numbering) + +! To be set only if using LHA pdfs +! 10050 cteq6m +! 10550 cteq66 +! 13100 CT14nlo +! 14400 CT18nlo +lhans1 14400 ! pdf set for hadron 1 (LHA numbering) +lhans2 14400 ! pdf set for hadron 2 (LHA numbering) + +! To be set only if using different pdf sets for the two incoming hadrons +# QCDLambda5 0.25 ! for not equal pdf sets + +#renscfact 1d0 ! (default 1d0) ren scale factor: muren = muref * renscfact +#facscfact 1d0 ! (default 1d0) fac scale factor: mufact = muref * facscfact + +! Parameters to allow or not the use of stored data +use-old-grid 1 ! If 1 use old grid if file pwggrids.dat is present (<> 1 regenerate) +use-old-ubound 1 ! If 1 use norm of upper bounding function stored + ! in pwgubound.dat, if present; <> 1 regenerate + +! A typical call uses 1/1400 seconds (1400 calls per second) +ncall1 20000 ! No. calls for the construction of the importance sampling grid +itmx1 5 ! No. iterations for grid: total 100000 calls ~ 70 seconds +ncall2 20000 ! No. calls for the computation of the upper bounding + ! envelope for the generation of radiation +itmx2 5 ! No. iterations for the above + +! Notice: the total number of calls is ncall2*itmx2*foldcsi*foldy*foldphi +! these folding numbers yield a negative fraction of 0.5% with bornktmin=10 GeV. +! With these settings: ncall2*itmx2*foldcsi*foldy*foldphi=5M, 60 minutes +foldcsi 5 ! No. folds on csi integration +foldy 5 ! No. folds on y integration +foldphi 2 ! No. folds on phi integration + +nubound 500000 ! No. calls to set up the upper bounding norms for radiation. + ! This is performed using only the Born cross section (fast) + +! OPTIONAL PARAMETERS + +withnegweights 0 ! (default 0). If 1 use negative weights. +#bornonly 1 ! (default 0). If 1 compute underlying Born using LO + ! cross section only. + +#ptsqmin 0.8 ! (default 0.8 GeV) minimum pt for generation of radiation +#charmthr 1.5 ! (default 1.5 GeV) charm treshold for gluon splitting +#bottomthr 5.0 ! (default 5.0 GeV) bottom treshold for gluon splitting +#testplots 1 ! (default 0, do not) do NLO and PWHG distributions +#charmthrpdf 1.5 ! (default 1.5 GeV) pdf charm treshold +#bottomthrpdf 5.0 ! (default 5.0 GeV) pdf bottom treshold + +#xupbound 2d0 ! increase upper bound for radiation generation + +#iseed 5421 ! Start the random number generator with seed iseed +#rand1 0 ! skipping rand2*100000000+rand1 numbers (see RM48 +#rand2 0 ! short writeup in CERNLIB). +#manyseeds 1 ! Used to perform multiple runs with different random + ! seeds in the same directory. + ! If set to 1, the program asks for an integer j; + ! The file pwgseeds.dat at line j is read, and the + ! integer at line j is used to initialize the random + ! sequence for the generation of the event. + ! The event file is called pwgevents-'j'.lhe + +doublefsr 1 ! Default 0; if 1 use new mechanism to generate regions + ! such that the emitted harder than the + ! emitter in FSR is suppressed. If doublefsr=0 this is + ! only the case for emitted gluons (old behaviour). If + ! 1 it is also applied to emitted quarks. + ! If set, it strongly reduces spikes on showered output. + + + +par_diexp 4 ! default is 2. With 4 there is a stronger separation +par_dijexp 4 ! of regions, it may help to reduce spikes when generating +par_2gsupp 4 ! weighted events. diff --git a/MC/config/PWGGAJE/external/powheg/powheg_jetjet_13600_mini.input b/MC/config/PWGGAJE/external/powheg/powheg_jetjet_13600_mini.input new file mode 100755 index 000000000..e151c10d9 --- /dev/null +++ b/MC/config/PWGGAJE/external/powheg/powheg_jetjet_13600_mini.input @@ -0,0 +1,90 @@ +numevts 10 ! number of events to be generated +ih1 1 ! hadron 1 (1 for protons, -1 for antiprotons) +ih2 1 ! hadron 2 (1 for protons, -1 for antiprotons) +ebeam1 6800d0 ! energy of beam 1 +ebeam2 6800d0 ! energy of beam 2 + +bornktmin 10d0 ! (default 0d0) Generation cut: minimum kt in underlying Born +bornsuppfact 120d0 ! (default 0d0) Mass parameter for Born suppression factor. + ! If < 0 suppfact = 1. + + +! To be set only if using internal (mlm) pdfs +! 131 cteq6m +! ndns1 131 ! pdf set for hadron 1 (mlm numbering) +! ndns2 131 ! pdf set for hadron 2 (mlm numbering) + +! To be set only if using LHA pdfs +! 10050 cteq6m +! 10550 cteq66 +! 13100 CT14nlo +! 14400 CT18nlo +lhans1 14400 ! pdf set for hadron 1 (LHA numbering) +lhans2 14400 ! pdf set for hadron 2 (LHA numbering) + +! To be set only if using different pdf sets for the two incoming hadrons +# QCDLambda5 0.25 ! for not equal pdf sets + +#renscfact 1d0 ! (default 1d0) ren scale factor: muren = muref * renscfact +#facscfact 1d0 ! (default 1d0) fac scale factor: mufact = muref * facscfact + +! Parameters to allow or not the use of stored data +use-old-grid 1 ! If 1 use old grid if file pwggrids.dat is present (<> 1 regenerate) +use-old-ubound 1 ! If 1 use norm of upper bounding function stored + ! in pwgubound.dat, if present; <> 1 regenerate + +! A typical call uses 1/1400 seconds (1400 calls per second) +ncall1 20000 ! No. calls for the construction of the importance sampling grid +itmx1 5 ! No. iterations for grid: total 100000 calls ~ 70 seconds +ncall2 10000 ! No. calls for the computation of the upper bounding + ! envelope for the generation of radiation +itmx2 3 ! No. iterations for the above + +! Notice: the total number of calls is ncall2*itmx2*foldcsi*foldy*foldphi +! these folding numbers yield a negative fraction of 0.5% with bornktmin=10 GeV. +! With these settings: ncall2*itmx2*foldcsi*foldy*foldphi=5M, 60 minutes +foldcsi 2 ! No. folds on csi integration +foldy 2 ! No. folds on y integration +foldphi 1 ! No. folds on phi integration + +nubound 100000 ! No. calls to set up the upper bounding norms for radiation. + ! This is performed using only the Born cross section (fast) + +! OPTIONAL PARAMETERS + +withnegweights 0 ! (default 0). If 1 use negative weights. +#bornonly 1 ! (default 0). If 1 compute underlying Born using LO + ! cross section only. + +#ptsqmin 0.8 ! (default 0.8 GeV) minimum pt for generation of radiation +#charmthr 1.5 ! (default 1.5 GeV) charm treshold for gluon splitting +#bottomthr 5.0 ! (default 5.0 GeV) bottom treshold for gluon splitting +#testplots 1 ! (default 0, do not) do NLO and PWHG distributions +#charmthrpdf 1.5 ! (default 1.5 GeV) pdf charm treshold +#bottomthrpdf 5.0 ! (default 5.0 GeV) pdf bottom treshold + +#xupbound 2d0 ! increase upper bound for radiation generation + +#iseed 5421 ! Start the random number generator with seed iseed +#rand1 0 ! skipping rand2*100000000+rand1 numbers (see RM48 +#rand2 0 ! short writeup in CERNLIB). +#manyseeds 1 ! Used to perform multiple runs with different random + ! seeds in the same directory. + ! If set to 1, the program asks for an integer j; + ! The file pwgseeds.dat at line j is read, and the + ! integer at line j is used to initialize the random + ! sequence for the generation of the event. + ! The event file is called pwgevents-'j'.lhe + +doublefsr 1 ! Default 0; if 1 use new mechanism to generate regions + ! such that the emitted harder than the + ! emitter in FSR is suppressed. If doublefsr=0 this is + ! only the case for emitted gluons (old behaviour). If + ! 1 it is also applied to emitted quarks. + ! If set, it strongly reduces spikes on showered output. + + + +par_diexp 4 ! default is 2. With 4 there is a stronger separation +par_dijexp 4 ! of regions, it may help to reduce spikes when generating +par_2gsupp 4 ! weighted events. diff --git a/MC/config/PWGGAJE/ini/GeneratorJE_gapgen5_hook.ini b/MC/config/PWGGAJE/ini/GeneratorJE_gapgen2_hook_pp13600GeV.ini similarity index 81% rename from MC/config/PWGGAJE/ini/GeneratorJE_gapgen5_hook.ini rename to MC/config/PWGGAJE/ini/GeneratorJE_gapgen2_hook_pp13600GeV.ini index 947b04251..ff17ff484 100644 --- a/MC/config/PWGGAJE/ini/GeneratorJE_gapgen5_hook.ini +++ b/MC/config/PWGGAJE/ini/GeneratorJE_gapgen2_hook_pp13600GeV.ini @@ -1,8 +1,8 @@ -### jet-jet production with MB Gap 5 +### jet-jet production with MB Gap 2 ### The external generator derives from GeneratorPythia8. [GeneratorExternal] fileName = ${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGGAJE/external/generator/generator_pythia8_gaptrigger_jets_hook.C -funcName = getGeneratorPythia8GapGenJE(5,"${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGGAJE/pythia8/generator/pythia8_minbias.cfg","${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGGAJE/pythia8/generator/pythia8_jet.cfg") +funcName = getGeneratorPythia8GapGenJE(2,"${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGGAJE/pythia8/generator/pythia8_minbias.cfg","${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGGAJE/pythia8/generator/pythia8_jet.cfg") [GeneratorPythia8] config=${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGGAJE/pythia8/generator/pythia8_jet.cfg diff --git a/MC/config/PWGGAJE/ini/GeneratorJE_gapgen3_hook_pp5360GeV.ini b/MC/config/PWGGAJE/ini/GeneratorJE_gapgen3_hook_pp5360GeV.ini new file mode 100644 index 000000000..c708379a8 --- /dev/null +++ b/MC/config/PWGGAJE/ini/GeneratorJE_gapgen3_hook_pp5360GeV.ini @@ -0,0 +1,9 @@ +### jet-jet production with MB Gap 3 for pp anchored to Pb-Pb periods +### The external generator derives from GeneratorPythia8. +[GeneratorExternal] +fileName = ${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGGAJE/external/generator/generator_pythia8_gaptrigger_jets_hook.C +funcName = getGeneratorPythia8GapGenJE(3,"${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGGAJE/pythia8/generator/pythia8_minbias_pp5360GeV.cfg","${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGGAJE/pythia8/generator/pythia8_jet_pp5360GeV.cfg") + +[GeneratorPythia8] +config=${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGGAJE/pythia8/generator/pythia8_jet_pp5360GeV.cfg +includePartonEvent=true diff --git a/MC/config/PWGGAJE/ini/GeneratorPythia8Box_parametrisedModel_pythia6Fragmentation_PbPb_cent0010_noBkg.ini b/MC/config/PWGGAJE/ini/GeneratorPythia8Box_parametrisedModel_pythia6Fragmentation_PbPb_cent0010_noBkg.ini new file mode 100644 index 000000000..1fdc88fb9 --- /dev/null +++ b/MC/config/PWGGAJE/ini/GeneratorPythia8Box_parametrisedModel_pythia6Fragmentation_PbPb_cent0010_noBkg.ini @@ -0,0 +1,7 @@ +### bkg production using pythia8 box generator, to embed jet-jet production into +[GeneratorExternal] +fileName = ${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGGAJE/external/generator/parametrisedJetModel/generator_pythia8_box_parametrisedModel_pythia6Fragmentation.C +funcName = generateParametrisedJetModel("/alice/cern.ch/user/a/alandou/Analysis/PWGJE/simSettings/combinatorialBkgClosure/", "parametrisedModel_PbPb_5p36TeV_cent0010.json", false) + +[GeneratorPythia8] +config=${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGGAJE/pythia8/generator/pythia8box_parametrisedModel.cfg \ No newline at end of file diff --git a/MC/config/PWGGAJE/ini/GeneratorPythia8Box_parametrisedModel_pythia6Fragmentation_PbPb_cent0010_withBkg.ini b/MC/config/PWGGAJE/ini/GeneratorPythia8Box_parametrisedModel_pythia6Fragmentation_PbPb_cent0010_withBkg.ini new file mode 100644 index 000000000..57227ffe1 --- /dev/null +++ b/MC/config/PWGGAJE/ini/GeneratorPythia8Box_parametrisedModel_pythia6Fragmentation_PbPb_cent0010_withBkg.ini @@ -0,0 +1,7 @@ +### bkg production using pythia8 box generator, to embed jet-jet production into +[GeneratorExternal] +fileName = ${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGGAJE/external/generator/parametrisedJetModel/generator_pythia8_box_parametrisedModel_pythia6Fragmentation.C +funcName = generateParametrisedJetModel("/alice/cern.ch/user/a/alandou/Analysis/PWGJE/simSettings/combinatorialBkgClosure/", "parametrisedModel_PbPb_5p36TeV_cent0010.json", true) + +[GeneratorPythia8] +config=${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGGAJE/pythia8/generator/pythia8box_parametrisedModel.cfg \ No newline at end of file diff --git a/MC/config/PWGGAJE/ini/GeneratorPythia8Box_parametrisedModel_pythia6Fragmentation_PbPb_cent5080_noBkg.ini b/MC/config/PWGGAJE/ini/GeneratorPythia8Box_parametrisedModel_pythia6Fragmentation_PbPb_cent5080_noBkg.ini new file mode 100644 index 000000000..b51c7ded5 --- /dev/null +++ b/MC/config/PWGGAJE/ini/GeneratorPythia8Box_parametrisedModel_pythia6Fragmentation_PbPb_cent5080_noBkg.ini @@ -0,0 +1,7 @@ +### bkg production using pythia8 box generator, to embed jet-jet production into +[GeneratorExternal] +fileName = ${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGGAJE/external/generator/parametrisedJetModel/generator_pythia8_box_parametrisedModel_pythia6Fragmentation.C +funcName = generateParametrisedJetModel("/alice/cern.ch/user/a/alandou/Analysis/PWGJE/simSettings/combinatorialBkgClosure/", "parametrisedModel_PbPb_5p36TeV_cent5080.json", false) + +[GeneratorPythia8] +config=${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGGAJE/pythia8/generator/pythia8box_parametrisedModel.cfg \ No newline at end of file diff --git a/MC/config/PWGGAJE/ini/GeneratorPythia8Box_parametrisedModel_pythia6Fragmentation_PbPb_cent5080_withBkg.ini b/MC/config/PWGGAJE/ini/GeneratorPythia8Box_parametrisedModel_pythia6Fragmentation_PbPb_cent5080_withBkg.ini new file mode 100644 index 000000000..654469b4d --- /dev/null +++ b/MC/config/PWGGAJE/ini/GeneratorPythia8Box_parametrisedModel_pythia6Fragmentation_PbPb_cent5080_withBkg.ini @@ -0,0 +1,7 @@ +### bkg production using pythia8 box generator, to embed jet-jet production into +[GeneratorExternal] +fileName = ${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGGAJE/external/generator/parametrisedJetModel/generator_pythia8_box_parametrisedModel_pythia6Fragmentation.C +funcName = generateParametrisedJetModel("/alice/cern.ch/user/a/alandou/Analysis/PWGJE/simSettings/combinatorialBkgClosure/", "parametrisedModel_PbPb_5p36TeV_cent5080.json", true) + +[GeneratorPythia8] +config=${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGGAJE/pythia8/generator/pythia8box_parametrisedModel.cfg \ No newline at end of file diff --git a/MC/config/PWGGAJE/ini/GeneratorPythia8POWHEG.ini b/MC/config/PWGGAJE/ini/GeneratorPythia8POWHEG_beauty.ini similarity index 94% rename from MC/config/PWGGAJE/ini/GeneratorPythia8POWHEG.ini rename to MC/config/PWGGAJE/ini/GeneratorPythia8POWHEG_beauty.ini index 45b8a0bcb..c557aa172 100644 --- a/MC/config/PWGGAJE/ini/GeneratorPythia8POWHEG.ini +++ b/MC/config/PWGGAJE/ini/GeneratorPythia8POWHEG_beauty.ini @@ -1,5 +1,6 @@ ### The external generator derives from GeneratorPythia8. ## The generator allows to run Pythia8 with POWHEG +#---> GeneratorPythia8POWHEG [GeneratorExternal] fileName=${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGGAJE/external/generator/generator_pythia8_powheg.C funcName=getGeneratorJEPythia8POWHEG("${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGGAJE/external/powheg/powheg_beauty_default.input") diff --git a/MC/config/PWGGAJE/ini/GeneratorPythia8POWHEG_beauty_F05.ini b/MC/config/PWGGAJE/ini/GeneratorPythia8POWHEG_beauty_F05.ini new file mode 100644 index 000000000..4be1cf530 --- /dev/null +++ b/MC/config/PWGGAJE/ini/GeneratorPythia8POWHEG_beauty_F05.ini @@ -0,0 +1,9 @@ +### The external generator derives from GeneratorPythia8. +## The generator allows to run Pythia8 with POWHEG +#---> GeneratorPythia8POWHEG +[GeneratorExternal] +fileName=${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGGAJE/external/generator/generator_pythia8_powheg.C +funcName=getGeneratorJEPythia8POWHEG("${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGGAJE/external/powheg/powheg_beauty_F05.input") + +[GeneratorPythia8] +config=${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGGAJE/pythia8/generator/pythia8_powheg.cfg diff --git a/MC/config/PWGGAJE/ini/GeneratorPythia8POWHEG_beauty_F05_R05.ini b/MC/config/PWGGAJE/ini/GeneratorPythia8POWHEG_beauty_F05_R05.ini new file mode 100644 index 000000000..24aa494c7 --- /dev/null +++ b/MC/config/PWGGAJE/ini/GeneratorPythia8POWHEG_beauty_F05_R05.ini @@ -0,0 +1,9 @@ +### The external generator derives from GeneratorPythia8. +## The generator allows to run Pythia8 with POWHEG +#---> GeneratorPythia8POWHEG +[GeneratorExternal] +fileName=${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGGAJE/external/generator/generator_pythia8_powheg.C +funcName=getGeneratorJEPythia8POWHEG("${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGGAJE/external/powheg/powheg_beauty_F05_R05.input") + +[GeneratorPythia8] +config=${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGGAJE/pythia8/generator/pythia8_powheg.cfg diff --git a/MC/config/PWGGAJE/ini/GeneratorPythia8POWHEG_beauty_F2.ini b/MC/config/PWGGAJE/ini/GeneratorPythia8POWHEG_beauty_F2.ini new file mode 100644 index 000000000..effba39eb --- /dev/null +++ b/MC/config/PWGGAJE/ini/GeneratorPythia8POWHEG_beauty_F2.ini @@ -0,0 +1,9 @@ +### The external generator derives from GeneratorPythia8. +## The generator allows to run Pythia8 with POWHEG +#---> GeneratorPythia8POWHEG +[GeneratorExternal] +fileName=${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGGAJE/external/generator/generator_pythia8_powheg.C +funcName=getGeneratorJEPythia8POWHEG("${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGGAJE/external/powheg/powheg_beauty_F2.input") + +[GeneratorPythia8] +config=${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGGAJE/pythia8/generator/pythia8_powheg.cfg diff --git a/MC/config/PWGGAJE/ini/GeneratorPythia8POWHEG_beauty_F2_R2.ini b/MC/config/PWGGAJE/ini/GeneratorPythia8POWHEG_beauty_F2_R2.ini new file mode 100644 index 000000000..04457b78c --- /dev/null +++ b/MC/config/PWGGAJE/ini/GeneratorPythia8POWHEG_beauty_F2_R2.ini @@ -0,0 +1,9 @@ +### The external generator derives from GeneratorPythia8. +## The generator allows to run Pythia8 with POWHEG +#---> GeneratorPythia8POWHEG +[GeneratorExternal] +fileName=${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGGAJE/external/generator/generator_pythia8_powheg.C +funcName=getGeneratorJEPythia8POWHEG("${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGGAJE/external/powheg/powheg_beauty_F2_R2.input") + +[GeneratorPythia8] +config=${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGGAJE/pythia8/generator/pythia8_powheg.cfg diff --git a/MC/config/PWGGAJE/ini/GeneratorPythia8POWHEG_beauty_MHigh.ini b/MC/config/PWGGAJE/ini/GeneratorPythia8POWHEG_beauty_MHigh.ini new file mode 100644 index 000000000..1a89f3b9c --- /dev/null +++ b/MC/config/PWGGAJE/ini/GeneratorPythia8POWHEG_beauty_MHigh.ini @@ -0,0 +1,9 @@ +### The external generator derives from GeneratorPythia8. +## The generator allows to run Pythia8 with POWHEG +#---> GeneratorPythia8POWHEG +[GeneratorExternal] +fileName=${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGGAJE/external/generator/generator_pythia8_powheg.C +funcName=getGeneratorJEPythia8POWHEG("${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGGAJE/external/powheg/powheg_beauty_MHigh.input") + +[GeneratorPythia8] +config=${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGGAJE/pythia8/generator/pythia8_powheg.cfg diff --git a/MC/config/PWGGAJE/ini/GeneratorPythia8POWHEG_beauty_MLow.ini b/MC/config/PWGGAJE/ini/GeneratorPythia8POWHEG_beauty_MLow.ini new file mode 100644 index 000000000..647e0b6a6 --- /dev/null +++ b/MC/config/PWGGAJE/ini/GeneratorPythia8POWHEG_beauty_MLow.ini @@ -0,0 +1,9 @@ +### The external generator derives from GeneratorPythia8. +## The generator allows to run Pythia8 with POWHEG +#---> GeneratorPythia8POWHEG +[GeneratorExternal] +fileName=${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGGAJE/external/generator/generator_pythia8_powheg.C +funcName=getGeneratorJEPythia8POWHEG("${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGGAJE/external/powheg/powheg_beauty_MLow.input") + +[GeneratorPythia8] +config=${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGGAJE/pythia8/generator/pythia8_powheg.cfg diff --git a/MC/config/PWGGAJE/ini/GeneratorPythia8POWHEG_beauty_R05.ini b/MC/config/PWGGAJE/ini/GeneratorPythia8POWHEG_beauty_R05.ini new file mode 100644 index 000000000..e940aa088 --- /dev/null +++ b/MC/config/PWGGAJE/ini/GeneratorPythia8POWHEG_beauty_R05.ini @@ -0,0 +1,9 @@ +### The external generator derives from GeneratorPythia8. +## The generator allows to run Pythia8 with POWHEG +#---> GeneratorPythia8POWHEG +[GeneratorExternal] +fileName=${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGGAJE/external/generator/generator_pythia8_powheg.C +funcName=getGeneratorJEPythia8POWHEG("${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGGAJE/external/powheg/powheg_beauty_R05.input") + +[GeneratorPythia8] +config=${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGGAJE/pythia8/generator/pythia8_powheg.cfg diff --git a/MC/config/PWGGAJE/ini/GeneratorPythia8POWHEG_beauty_R2.ini b/MC/config/PWGGAJE/ini/GeneratorPythia8POWHEG_beauty_R2.ini new file mode 100644 index 000000000..e846873b5 --- /dev/null +++ b/MC/config/PWGGAJE/ini/GeneratorPythia8POWHEG_beauty_R2.ini @@ -0,0 +1,9 @@ +### The external generator derives from GeneratorPythia8. +## The generator allows to run Pythia8 with POWHEG +#---> GeneratorPythia8POWHEG +[GeneratorExternal] +fileName=${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGGAJE/external/generator/generator_pythia8_powheg.C +funcName=getGeneratorJEPythia8POWHEG("${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGGAJE/external/powheg/powheg_beauty_R2.input") + +[GeneratorPythia8] +config=${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGGAJE/pythia8/generator/pythia8_powheg.cfg diff --git a/MC/config/PWGGAJE/ini/GeneratorPythia8POWHEG_charm.ini b/MC/config/PWGGAJE/ini/GeneratorPythia8POWHEG_charm.ini new file mode 100644 index 000000000..df8a6a1da --- /dev/null +++ b/MC/config/PWGGAJE/ini/GeneratorPythia8POWHEG_charm.ini @@ -0,0 +1,9 @@ +### The external generator derives from GeneratorPythia8. +## The generator allows to run Pythia8 with POWHEG +#---> GeneratorPythia8POWHEG +[GeneratorExternal] +fileName=${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGGAJE/external/generator/generator_pythia8_powheg.C +funcName=getGeneratorJEPythia8POWHEG("${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGGAJE/external/powheg/powheg_charm_default.input") + +[GeneratorPythia8] +config=${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGGAJE/pythia8/generator/pythia8_powheg.cfg diff --git a/MC/config/PWGGAJE/ini/GeneratorPythia8POWHEG_charm_F05.ini b/MC/config/PWGGAJE/ini/GeneratorPythia8POWHEG_charm_F05.ini new file mode 100644 index 000000000..34bc652e3 --- /dev/null +++ b/MC/config/PWGGAJE/ini/GeneratorPythia8POWHEG_charm_F05.ini @@ -0,0 +1,9 @@ +### The external generator derives from GeneratorPythia8. +## The generator allows to run Pythia8 with POWHEG +#---> GeneratorPythia8POWHEG +[GeneratorExternal] +fileName=${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGGAJE/external/generator/generator_pythia8_powheg.C +funcName=getGeneratorJEPythia8POWHEG("${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGGAJE/external/powheg/powheg_charm_F05.input") + +[GeneratorPythia8] +config=${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGGAJE/pythia8/generator/pythia8_powheg.cfg diff --git a/MC/config/PWGGAJE/ini/GeneratorPythia8POWHEG_charm_F05_R05.ini b/MC/config/PWGGAJE/ini/GeneratorPythia8POWHEG_charm_F05_R05.ini new file mode 100644 index 000000000..e4ab0f479 --- /dev/null +++ b/MC/config/PWGGAJE/ini/GeneratorPythia8POWHEG_charm_F05_R05.ini @@ -0,0 +1,9 @@ +### The external generator derives from GeneratorPythia8. +## The generator allows to run Pythia8 with POWHEG +#---> GeneratorPythia8POWHEG +[GeneratorExternal] +fileName=${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGGAJE/external/generator/generator_pythia8_powheg.C +funcName=getGeneratorJEPythia8POWHEG("${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGGAJE/external/powheg/powheg_charm_F05_R05.input") + +[GeneratorPythia8] +config=${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGGAJE/pythia8/generator/pythia8_powheg.cfg diff --git a/MC/config/PWGGAJE/ini/GeneratorPythia8POWHEG_charm_F2.ini b/MC/config/PWGGAJE/ini/GeneratorPythia8POWHEG_charm_F2.ini new file mode 100644 index 000000000..36aa6b6c2 --- /dev/null +++ b/MC/config/PWGGAJE/ini/GeneratorPythia8POWHEG_charm_F2.ini @@ -0,0 +1,9 @@ +### The external generator derives from GeneratorPythia8. +## The generator allows to run Pythia8 with POWHEG +#---> GeneratorPythia8POWHEG +[GeneratorExternal] +fileName=${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGGAJE/external/generator/generator_pythia8_powheg.C +funcName=getGeneratorJEPythia8POWHEG("${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGGAJE/external/powheg/powheg_charm_F2.input") + +[GeneratorPythia8] +config=${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGGAJE/pythia8/generator/pythia8_powheg.cfg diff --git a/MC/config/PWGGAJE/ini/GeneratorPythia8POWHEG_charm_F2_R2.ini b/MC/config/PWGGAJE/ini/GeneratorPythia8POWHEG_charm_F2_R2.ini new file mode 100644 index 000000000..37d417322 --- /dev/null +++ b/MC/config/PWGGAJE/ini/GeneratorPythia8POWHEG_charm_F2_R2.ini @@ -0,0 +1,9 @@ +### The external generator derives from GeneratorPythia8. +## The generator allows to run Pythia8 with POWHEG +#---> GeneratorPythia8POWHEG +[GeneratorExternal] +fileName=${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGGAJE/external/generator/generator_pythia8_powheg.C +funcName=getGeneratorJEPythia8POWHEG("${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGGAJE/external/powheg/powheg_charm_F2_R2.input") + +[GeneratorPythia8] +config=${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGGAJE/pythia8/generator/pythia8_powheg.cfg diff --git a/MC/config/PWGGAJE/ini/GeneratorPythia8POWHEG_charm_MHigh.ini b/MC/config/PWGGAJE/ini/GeneratorPythia8POWHEG_charm_MHigh.ini new file mode 100644 index 000000000..73f83de02 --- /dev/null +++ b/MC/config/PWGGAJE/ini/GeneratorPythia8POWHEG_charm_MHigh.ini @@ -0,0 +1,9 @@ +### The external generator derives from GeneratorPythia8. +## The generator allows to run Pythia8 with POWHEG +#---> GeneratorPythia8POWHEG +[GeneratorExternal] +fileName=${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGGAJE/external/generator/generator_pythia8_powheg.C +funcName=getGeneratorJEPythia8POWHEG("${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGGAJE/external/powheg/powheg_charm_MHigh.input") + +[GeneratorPythia8] +config=${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGGAJE/pythia8/generator/pythia8_powheg.cfg diff --git a/MC/config/PWGGAJE/ini/GeneratorPythia8POWHEG_charm_MLow.ini b/MC/config/PWGGAJE/ini/GeneratorPythia8POWHEG_charm_MLow.ini new file mode 100644 index 000000000..ed7c5c7b7 --- /dev/null +++ b/MC/config/PWGGAJE/ini/GeneratorPythia8POWHEG_charm_MLow.ini @@ -0,0 +1,9 @@ +### The external generator derives from GeneratorPythia8. +## The generator allows to run Pythia8 with POWHEG +#---> GeneratorPythia8POWHEG +[GeneratorExternal] +fileName=${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGGAJE/external/generator/generator_pythia8_powheg.C +funcName=getGeneratorJEPythia8POWHEG("${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGGAJE/external/powheg/powheg_charm_MLow.input") + +[GeneratorPythia8] +config=${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGGAJE/pythia8/generator/pythia8_powheg.cfg diff --git a/MC/config/PWGGAJE/ini/GeneratorPythia8POWHEG_charm_R05.ini b/MC/config/PWGGAJE/ini/GeneratorPythia8POWHEG_charm_R05.ini new file mode 100644 index 000000000..61680cab2 --- /dev/null +++ b/MC/config/PWGGAJE/ini/GeneratorPythia8POWHEG_charm_R05.ini @@ -0,0 +1,9 @@ +### The external generator derives from GeneratorPythia8. +## The generator allows to run Pythia8 with POWHEG +#---> GeneratorPythia8POWHEG +[GeneratorExternal] +fileName=${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGGAJE/external/generator/generator_pythia8_powheg.C +funcName=getGeneratorJEPythia8POWHEG("${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGGAJE/external/powheg/powheg_charm_R05.input") + +[GeneratorPythia8] +config=${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGGAJE/pythia8/generator/pythia8_powheg.cfg diff --git a/MC/config/PWGGAJE/ini/GeneratorPythia8POWHEG_charm_R2.ini b/MC/config/PWGGAJE/ini/GeneratorPythia8POWHEG_charm_R2.ini new file mode 100644 index 000000000..e8185c68d --- /dev/null +++ b/MC/config/PWGGAJE/ini/GeneratorPythia8POWHEG_charm_R2.ini @@ -0,0 +1,9 @@ +### The external generator derives from GeneratorPythia8. +## The generator allows to run Pythia8 with POWHEG +#---> GeneratorPythia8POWHEG +[GeneratorExternal] +fileName=${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGGAJE/external/generator/generator_pythia8_powheg.C +funcName=getGeneratorJEPythia8POWHEG("${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGGAJE/external/powheg/powheg_charm_R2.input") + +[GeneratorPythia8] +config=${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGGAJE/pythia8/generator/pythia8_powheg.cfg diff --git a/MC/config/PWGGAJE/ini/GeneratorPythia8POWHEG_jetjet_13600.ini b/MC/config/PWGGAJE/ini/GeneratorPythia8POWHEG_jetjet_13600.ini new file mode 100644 index 000000000..201e7a734 --- /dev/null +++ b/MC/config/PWGGAJE/ini/GeneratorPythia8POWHEG_jetjet_13600.ini @@ -0,0 +1,10 @@ +### The external generator derives from GeneratorPythia8. +## The generator allows to run Pythia8 with POWHEG +## The option '3' which is given to getGeneratorJEPythia8POWHEG selects the pwhg_main_dijet process +#---> GeneratorPythia8POWHEG +[GeneratorExternal] +fileName=${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGGAJE/external/generator/generator_pythia8_powheg.C +funcName=getGeneratorJEPythia8POWHEG("${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGGAJE/external/powheg/powheg_jetjet_13600.input","",3) + +[GeneratorPythia8] +config=${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGGAJE/pythia8/generator/pythia8_powheg.cfg diff --git a/MC/config/PWGGAJE/ini/GeneratorPythia8POWHEG_jetjet_13600_mini.ini b/MC/config/PWGGAJE/ini/GeneratorPythia8POWHEG_jetjet_13600_mini.ini new file mode 100644 index 000000000..7cedd849e --- /dev/null +++ b/MC/config/PWGGAJE/ini/GeneratorPythia8POWHEG_jetjet_13600_mini.ini @@ -0,0 +1,11 @@ +### The external generator derives from GeneratorPythia8. +## The generator allows to run Pythia8 with POWHEG +## The option '3' which is given to getGeneratorJEPythia8POWHEG selects the pwhg_main_dijet process +## This is a less computing intensive alternative to the original GeneratorPythia8POWHEG_jetjet_13600.ini. It keeps the event generation close to 5 minutes +#---> GeneratorPythia8POWHEG +[GeneratorExternal] +fileName=${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGGAJE/external/generator/generator_pythia8_powheg.C +funcName=getGeneratorJEPythia8POWHEG("${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGGAJE/external/powheg/powheg_jetjet_13600_mini.input","",3) + +[GeneratorPythia8] +config=${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGGAJE/pythia8/generator/pythia8_powheg.cfg diff --git a/MC/config/PWGGAJE/ini/hook_prompt_gamma_gap.ini b/MC/config/PWGGAJE/ini/hook_prompt_gamma_gap.ini new file mode 100644 index 000000000..7747e0ed5 --- /dev/null +++ b/MC/config/PWGGAJE/ini/hook_prompt_gamma_gap.ini @@ -0,0 +1,7 @@ +[GeneratorExternal] +fileName = ${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGGAJE/external/generator/generator_pythia8_gaptrigger_promptphotons_hook.C +funcName = getGeneratorPythia8GapGenJEPhoton(2,"${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGGAJE/pythia8/generator/pythia8_minbias.cfg","${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGGAJE/pythia8/generator/pythia8_promptphoton.cfg") + +[GeneratorPythia8] +config=${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGGAJE/pythia8/generator/pythia8_promptphoton.cfg +includePartonEvent=true diff --git a/MC/config/PWGGAJE/ini/prompt_gamma_gap.ini b/MC/config/PWGGAJE/ini/prompt_gamma_gap.ini new file mode 100644 index 000000000..dc69687f3 --- /dev/null +++ b/MC/config/PWGGAJE/ini/prompt_gamma_gap.ini @@ -0,0 +1,7 @@ +[GeneratorExternal] +fileName = ${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGGAJE/external/generator/generator_pythia8_gaptrigger_hook.C +funcName = getGeneratorPythia8GapGenJEMB(2,"${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGGAJE/pythia8/generator/pythia8_minbias.cfg","${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGGAJE/pythia8/generator/pythia8_promptphoton.cfg") + +[GeneratorPythia8] +config=${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGGAJE/pythia8/generator/pythia8_promptphoton.cfg +includePartonEvent=true \ No newline at end of file diff --git a/MC/config/PWGGAJE/ini/tests/GeneratorJE_gapgen5_hook.C b/MC/config/PWGGAJE/ini/tests/GeneratorJE_gapgen2_hook_pp13600GeV.C similarity index 97% rename from MC/config/PWGGAJE/ini/tests/GeneratorJE_gapgen5_hook.C rename to MC/config/PWGGAJE/ini/tests/GeneratorJE_gapgen2_hook_pp13600GeV.C index 5ac7f5173..3364b9f6d 100644 --- a/MC/config/PWGGAJE/ini/tests/GeneratorJE_gapgen5_hook.C +++ b/MC/config/PWGGAJE/ini/tests/GeneratorJE_gapgen2_hook_pp13600GeV.C @@ -1,7 +1,7 @@ int External() { std::string path{"o2sim_Kine.root"}; - float ratioTrigger = 1./5; // one event triggered out of 5 + float ratioTrigger = 1./2; // one event triggered out of 2 TFile file(path.c_str(), "READ"); diff --git a/MC/config/PWGGAJE/ini/tests/GeneratorJE_gapgen3_hook_pp5360GeV.C b/MC/config/PWGGAJE/ini/tests/GeneratorJE_gapgen3_hook_pp5360GeV.C new file mode 100644 index 000000000..db42706cb --- /dev/null +++ b/MC/config/PWGGAJE/ini/tests/GeneratorJE_gapgen3_hook_pp5360GeV.C @@ -0,0 +1,71 @@ +int External() { + std::string path{"o2sim_Kine.root"}; + + float ratioTrigger = 1./3; // one event triggered out of 3 + + + TFile file(path.c_str(), "READ"); + if (file.IsZombie()) { + std::cerr << "Cannot open ROOT file " << path << "\n"; + return 1; + } + + auto tree = (TTree *)file.Get("o2sim"); + std::vector *tracks{}; + tree->SetBranchAddress("MCTrack", &tracks); + o2::dataformats::MCEventHeader *eventHeader = nullptr; + tree->SetBranchAddress("MCEventHeader.", &eventHeader); + + int nEventsMB{}, nEventsJetJet{}; + float sumWeightsMB{}, sumWeightsJetJet{}; + int sumTracks{}; + auto nEvents = tree->GetEntries(); + + for (int i = 0; i < nEvents; i++) { + tree->GetEntry(i); + + // check subgenerator information and event weights + if (eventHeader->hasInfo(o2::mcgenid::GeneratorProperty::SUBGENERATORID)) { + bool isValid = false; + int subGeneratorId = eventHeader->getInfo(o2::mcgenid::GeneratorProperty::SUBGENERATORID, isValid); + if (eventHeader->hasInfo(o2::dataformats::MCInfoKeys::weight)) { + float weight = eventHeader->getInfo(o2::dataformats::MCInfoKeys::weight,isValid); + if (subGeneratorId == 0) { + nEventsMB++; + sumWeightsMB += weight; + } + else if (subGeneratorId == 1) { + nEventsJetJet++; + sumWeightsJetJet += weight; + } + } + } + sumTracks += tracks->size(); + } + + std::cout << "--------------------------------\n"; + std::cout << "# Events: " << nEvents << "\n"; + std::cout << "# MB events: " << nEventsMB << "\n"; + std::cout << " sum of weights for MB events: " << sumWeightsMB << "\n"; + std::cout << "# Jet-jet events " << nEventsJetJet << "\n"; + std::cout << " sum of weights jet-jet events: " << sumWeightsJetJet << "\n"; + std::cout << "# tracks summed over all events (jet-jet + MB): " << sumTracks << "\n"; + + if (nEventsMB < nEvents * (1 - ratioTrigger) * 0.95 || nEventsMB > nEvents * (1 - ratioTrigger) * 1.05) { // we put some tolerance since the number of generated events is small + std::cerr << "Number of generated MB events different than expected\n"; + return 1; + } + if (nEventsJetJet < nEvents * ratioTrigger * 0.95 || nEventsJetJet > nEvents * ratioTrigger * 1.05) { + std::cerr << "Number of jet-jet generated events different than expected\n"; + return 1; + } + if(nEventsMB < sumWeightsMB * 0.95 || nEventsMB > sumWeightsMB * 1.05) { + std::cerr << "Weights of MB events do not = 1 as expected\n"; + return 1; + } + if(sumTracks < 1) { + std::cerr << "No tracks in simulated events\n"; + return 1; + } + return 0; +} diff --git a/MC/config/PWGGAJE/ini/tests/GeneratorPythia8Box_parametrisedModel_pythia6Fragmentation_PbPb_cent0010_noBkg.C b/MC/config/PWGGAJE/ini/tests/GeneratorPythia8Box_parametrisedModel_pythia6Fragmentation_PbPb_cent0010_noBkg.C new file mode 100644 index 000000000..fddd963ae --- /dev/null +++ b/MC/config/PWGGAJE/ini/tests/GeneratorPythia8Box_parametrisedModel_pythia6Fragmentation_PbPb_cent0010_noBkg.C @@ -0,0 +1,34 @@ +int External() { + std::string path{"o2sim_Kine.root"}; + + TFile file(path.c_str(), "READ"); + if (file.IsZombie()) { + std::cerr << "Cannot open ROOT file " << path << "\n"; + return 1; + } + + auto tree = (TTree *)file.Get("o2sim"); + std::vector *tracks{}; + tree->SetBranchAddress("MCTrack", &tracks); + o2::dataformats::MCEventHeader *eventHeader = nullptr; + tree->SetBranchAddress("MCEventHeader.", &eventHeader); + + int sumTracks{}; + auto nEvents = tree->GetEntries(); + + for (int i = 0; i < nEvents; i++) { + tree->GetEntry(i); + sumTracks += tracks->size(); + } + + std::cout << "--------------------------------\n"; + std::cout << "# Events: " << nEvents << "\n"; + std::cout << "# tracks summed over all events (jet-jet + MB): " << sumTracks + << "\n"; + + if (sumTracks < 1) { + std::cerr << "No tracks in simulated events\n"; + return 1; + } + return 0; +} \ No newline at end of file diff --git a/MC/config/PWGGAJE/ini/tests/GeneratorPythia8Box_parametrisedModel_pythia6Fragmentation_PbPb_cent0010_withBkg.C b/MC/config/PWGGAJE/ini/tests/GeneratorPythia8Box_parametrisedModel_pythia6Fragmentation_PbPb_cent0010_withBkg.C new file mode 100644 index 000000000..fddd963ae --- /dev/null +++ b/MC/config/PWGGAJE/ini/tests/GeneratorPythia8Box_parametrisedModel_pythia6Fragmentation_PbPb_cent0010_withBkg.C @@ -0,0 +1,34 @@ +int External() { + std::string path{"o2sim_Kine.root"}; + + TFile file(path.c_str(), "READ"); + if (file.IsZombie()) { + std::cerr << "Cannot open ROOT file " << path << "\n"; + return 1; + } + + auto tree = (TTree *)file.Get("o2sim"); + std::vector *tracks{}; + tree->SetBranchAddress("MCTrack", &tracks); + o2::dataformats::MCEventHeader *eventHeader = nullptr; + tree->SetBranchAddress("MCEventHeader.", &eventHeader); + + int sumTracks{}; + auto nEvents = tree->GetEntries(); + + for (int i = 0; i < nEvents; i++) { + tree->GetEntry(i); + sumTracks += tracks->size(); + } + + std::cout << "--------------------------------\n"; + std::cout << "# Events: " << nEvents << "\n"; + std::cout << "# tracks summed over all events (jet-jet + MB): " << sumTracks + << "\n"; + + if (sumTracks < 1) { + std::cerr << "No tracks in simulated events\n"; + return 1; + } + return 0; +} \ No newline at end of file diff --git a/MC/config/PWGGAJE/ini/tests/GeneratorPythia8Box_parametrisedModel_pythia6Fragmentation_PbPb_cent5080_noBkg.C b/MC/config/PWGGAJE/ini/tests/GeneratorPythia8Box_parametrisedModel_pythia6Fragmentation_PbPb_cent5080_noBkg.C new file mode 100644 index 000000000..fddd963ae --- /dev/null +++ b/MC/config/PWGGAJE/ini/tests/GeneratorPythia8Box_parametrisedModel_pythia6Fragmentation_PbPb_cent5080_noBkg.C @@ -0,0 +1,34 @@ +int External() { + std::string path{"o2sim_Kine.root"}; + + TFile file(path.c_str(), "READ"); + if (file.IsZombie()) { + std::cerr << "Cannot open ROOT file " << path << "\n"; + return 1; + } + + auto tree = (TTree *)file.Get("o2sim"); + std::vector *tracks{}; + tree->SetBranchAddress("MCTrack", &tracks); + o2::dataformats::MCEventHeader *eventHeader = nullptr; + tree->SetBranchAddress("MCEventHeader.", &eventHeader); + + int sumTracks{}; + auto nEvents = tree->GetEntries(); + + for (int i = 0; i < nEvents; i++) { + tree->GetEntry(i); + sumTracks += tracks->size(); + } + + std::cout << "--------------------------------\n"; + std::cout << "# Events: " << nEvents << "\n"; + std::cout << "# tracks summed over all events (jet-jet + MB): " << sumTracks + << "\n"; + + if (sumTracks < 1) { + std::cerr << "No tracks in simulated events\n"; + return 1; + } + return 0; +} \ No newline at end of file diff --git a/MC/config/PWGGAJE/ini/tests/GeneratorPythia8Box_parametrisedModel_pythia6Fragmentation_PbPb_cent5080_withBkg.C b/MC/config/PWGGAJE/ini/tests/GeneratorPythia8Box_parametrisedModel_pythia6Fragmentation_PbPb_cent5080_withBkg.C new file mode 100644 index 000000000..fddd963ae --- /dev/null +++ b/MC/config/PWGGAJE/ini/tests/GeneratorPythia8Box_parametrisedModel_pythia6Fragmentation_PbPb_cent5080_withBkg.C @@ -0,0 +1,34 @@ +int External() { + std::string path{"o2sim_Kine.root"}; + + TFile file(path.c_str(), "READ"); + if (file.IsZombie()) { + std::cerr << "Cannot open ROOT file " << path << "\n"; + return 1; + } + + auto tree = (TTree *)file.Get("o2sim"); + std::vector *tracks{}; + tree->SetBranchAddress("MCTrack", &tracks); + o2::dataformats::MCEventHeader *eventHeader = nullptr; + tree->SetBranchAddress("MCEventHeader.", &eventHeader); + + int sumTracks{}; + auto nEvents = tree->GetEntries(); + + for (int i = 0; i < nEvents; i++) { + tree->GetEntry(i); + sumTracks += tracks->size(); + } + + std::cout << "--------------------------------\n"; + std::cout << "# Events: " << nEvents << "\n"; + std::cout << "# tracks summed over all events (jet-jet + MB): " << sumTracks + << "\n"; + + if (sumTracks < 1) { + std::cerr << "No tracks in simulated events\n"; + return 1; + } + return 0; +} \ No newline at end of file diff --git a/MC/config/PWGGAJE/ini/tests/hook_prompt_gamma_gap.C b/MC/config/PWGGAJE/ini/tests/hook_prompt_gamma_gap.C new file mode 100644 index 000000000..69cd83f86 --- /dev/null +++ b/MC/config/PWGGAJE/ini/tests/hook_prompt_gamma_gap.C @@ -0,0 +1,71 @@ +int External() { + std::string path{"o2sim_Kine.root"}; + + float ratioTrigger = 1./2; // one event triggered out of 5 + + + TFile file(path.c_str(), "READ"); + if (file.IsZombie()) { + std::cerr << "Cannot open ROOT file " << path << "\n"; + return 1; + } + + auto tree = (TTree *)file.Get("o2sim"); + std::vector *tracks{}; + tree->SetBranchAddress("MCTrack", &tracks); + o2::dataformats::MCEventHeader *eventHeader = nullptr; + tree->SetBranchAddress("MCEventHeader.", &eventHeader); + + int nEventsMB{}, nEventsJetJet{}; + float sumWeightsMB{}, sumWeightsJetJet{}; + int sumTracks{}; + auto nEvents = tree->GetEntries(); + + for (int i = 0; i < nEvents; i++) { + tree->GetEntry(i); + + // check subgenerator information and event weights + if (eventHeader->hasInfo(o2::mcgenid::GeneratorProperty::SUBGENERATORID)) { + bool isValid = false; + int subGeneratorId = eventHeader->getInfo(o2::mcgenid::GeneratorProperty::SUBGENERATORID, isValid); + if (eventHeader->hasInfo(o2::dataformats::MCInfoKeys::weight)) { + float weight = eventHeader->getInfo(o2::dataformats::MCInfoKeys::weight,isValid); + if (subGeneratorId == 0) { + nEventsMB++; + sumWeightsMB += weight; + } + else if (subGeneratorId == 1) { + nEventsJetJet++; + sumWeightsJetJet += weight; + } + } + } + sumTracks += tracks->size(); + } + + std::cout << "--------------------------------\n"; + std::cout << "# Events: " << nEvents << "\n"; + std::cout << "# MB events: " << nEventsMB << "\n"; + std::cout << " sum of weights for MB events: " << sumWeightsMB << "\n"; + std::cout << "# prompt_photon events " << nEventsJetJet << "\n"; + std::cout << " sum of weights prompt_photon events: " << sumWeightsJetJet << "\n"; + std::cout << "# tracks summed over all events (prompt_photon + MB): " << sumTracks << "\n"; + + if (nEventsMB < nEvents * (1 - ratioTrigger) * 0.95 || nEventsMB > nEvents * (1 - ratioTrigger) * 1.05) { // we put some tolerance since the number of generated events is small + std::cerr << "Number of generated MB events different than expected\n"; + return 1; + } + if (nEventsJetJet < nEvents * ratioTrigger * 0.95 || nEventsJetJet > nEvents * ratioTrigger * 1.05) { + std::cerr << "Number of prompt_photon generated events different than expected\n"; + return 1; + } + if(nEventsMB < sumWeightsMB * 0.95 || nEventsMB > sumWeightsMB * 1.05) { + std::cerr << "Weights of MB events do not = 1 as expected\n"; + return 1; + } + if(sumTracks < 1) { + std::cerr << "No tracks in simulated events\n"; + return 1; + } + return 0; +} diff --git a/MC/config/PWGGAJE/ini/tests/prompt_gamma_gap.C b/MC/config/PWGGAJE/ini/tests/prompt_gamma_gap.C new file mode 100644 index 000000000..6f32003fe --- /dev/null +++ b/MC/config/PWGGAJE/ini/tests/prompt_gamma_gap.C @@ -0,0 +1,71 @@ +int External() { + std::string path{"o2sim_Kine.root"}; + + float ratioTrigger = 1./2; // one event triggered out of 5 + + + TFile file(path.c_str(), "READ"); + if (file.IsZombie()) { + std::cerr << "Cannot open ROOT file " << path << "\n"; + return 1; + } + + auto tree = (TTree *)file.Get("o2sim"); + std::vector *tracks{}; + tree->SetBranchAddress("MCTrack", &tracks); + o2::dataformats::MCEventHeader *eventHeader = nullptr; + tree->SetBranchAddress("MCEventHeader.", &eventHeader); + + int nEventsMB{}, nEventsJetJet{}; + float sumWeightsMB{}, sumWeightsJetJet{}; + int sumTracks{}; + auto nEvents = tree->GetEntries(); + + for (int i = 0; i < nEvents; i++) { + tree->GetEntry(i); + + // check subgenerator information and event weights + if (eventHeader->hasInfo(o2::mcgenid::GeneratorProperty::SUBGENERATORID)) { + bool isValid = false; + int subGeneratorId = eventHeader->getInfo(o2::mcgenid::GeneratorProperty::SUBGENERATORID, isValid); + if (eventHeader->hasInfo(o2::dataformats::MCInfoKeys::weight)) { + float weight = eventHeader->getInfo(o2::dataformats::MCInfoKeys::weight,isValid); + if (subGeneratorId == 0) { + nEventsMB++; + sumWeightsMB += weight; + } + else if (subGeneratorId == 1) { + nEventsJetJet++; + sumWeightsJetJet += weight; + } + } + } + sumTracks += tracks->size(); + } + + std::cout << "--------------------------------\n"; + std::cout << "# Events: " << nEvents << "\n"; + std::cout << "# MB events: " << nEventsMB << "\n"; + std::cout << " sum of weights for MB events: " << sumWeightsMB << "\n"; + std::cout << "# Jet-jet events " << nEventsJetJet << "\n"; + std::cout << " sum of weights jet-jet events: " << sumWeightsJetJet << "\n"; + std::cout << "# tracks summed over all events (jet-jet + MB): " << sumTracks << "\n"; + + if (nEventsMB < nEvents * (1 - ratioTrigger) * 0.95 || nEventsMB > nEvents * (1 - ratioTrigger) * 1.05) { // we put some tolerance since the number of generated events is small + std::cerr << "Number of generated MB events different than expected\n"; + return 1; + } + if (nEventsJetJet < nEvents * ratioTrigger * 0.95 || nEventsJetJet > nEvents * ratioTrigger * 1.05) { + std::cerr << "Number of jet-jet generated events different than expected\n"; + return 1; + } + if(nEventsMB < sumWeightsMB * 0.95 || nEventsMB > sumWeightsMB * 1.05) { + std::cerr << "Weights of MB events do not = 1 as expected\n"; + return 1; + } + if(sumTracks < 1) { + std::cerr << "No tracks in simulated events\n"; + return 1; + } + return 0; +} diff --git a/MC/config/PWGGAJE/pythia8/generator/pythia8_promptphoton.cfg b/MC/config/PWGGAJE/pythia8/generator/pythia8_promptphoton.cfg new file mode 100644 index 000000000..ff0258880 --- /dev/null +++ b/MC/config/PWGGAJE/pythia8/generator/pythia8_promptphoton.cfg @@ -0,0 +1,21 @@ +# 2 -> 2 prompt photon production, oversampling by pThat^4 + +### beams +Beams:idA = 2212 # proton +Beams:idB = 2212 # proton +Beams:eCM = 13600. # GeV + +### processes +SoftQCD:inelastic = off +HardQCD:all = off +PromptPhoton:all = on + +### decays +ParticleDecays:limitTau0 = on +ParticleDecays:tau0Max = 10. + +### phase space cuts +PhaseSpace:pTHatMin = 5 +PhaseSpace:pTHatMax = 600 +PhaseSpace:bias2Selection = on +PhaseSpace:bias2SelectionPow = 4 \ No newline at end of file diff --git a/MC/config/PWGGAJE/pythia8/generator/pythia8box_parametrisedModel.cfg b/MC/config/PWGGAJE/pythia8/generator/pythia8box_parametrisedModel.cfg new file mode 100644 index 000000000..e80199deb --- /dev/null +++ b/MC/config/PWGGAJE/pythia8/generator/pythia8box_parametrisedModel.cfg @@ -0,0 +1,16 @@ +# ### processes + +ProcessLevel:all = off +HadronLevel:all = on +Check:event = off +# ColourReconnection:reconnect = off +# PartonLevel:MPI = off + +### processes +### SoftQCD:inelastic = on + +### decays +ParticleDecays:limitTau0 = on +ParticleDecays:tau0Max = 0. + +### decays: no need to change anything as particles produced by external generator generator_pythia8_bkgBoltzmann are pions, which do not decay by default with PYTHIA8 diff --git a/MC/config/PWGHF/external/generator/generator_pythia8_embed_charmnuclei.C b/MC/config/PWGHF/external/generator/generator_pythia8_embed_charmnuclei.C new file mode 100644 index 000000000..94c9c0b80 --- /dev/null +++ b/MC/config/PWGHF/external/generator/generator_pythia8_embed_charmnuclei.C @@ -0,0 +1,349 @@ +#include "FairGenerator.h" +#include "Generators/GeneratorPythia8.h" +#include "Pythia8/Pythia.h" +#include "TRandom.h" +#include "TF1.h" +#include "TMath.h" +#include +#include +#include +#include + +#include "Math/Vector3D.h" +#include "Math/Vector4D.h" + +R__ADD_INCLUDE_PATH($O2DPG_MC_CONFIG_ROOT) +#include "MC/config/common/external/generator/CoalescencePythia8.h" + +using namespace Pythia8; + +class GeneratorPythia8HFEmbedCharmNuclei : public o2::eventgen::GeneratorPythia8 +{ + public: + + /// constructor + GeneratorPythia8HFEmbedCharmNuclei(int pdgCode = 2010010020, float lifetime = 1.f, int nCharmNucleiPerEvent = 10, float yMin = -1.f, float yMax = 1.f, float ptMax = 25.f, bool trivialCoal = false, float coalMomentum = 0.2, float fracFromB = 0.f, unsigned int seed = 0u) + { + nNumberOfCharmNucleiPerEvent = nCharmNucleiPerEvent; + mRapidityMinCharmNuclei = yMin; + mRapidityMaxCharmNuclei = yMax; + mPtMaxCharmNuclei = ptMax; + mTrivialCoal = trivialCoal; + mCoalMomentum = coalMomentum; + mFractionFromBeauty = fracFromB; + mPdgCharmNucleus = pdgCode; + mSign = 1; + mUsedSeed = seed; + if (std::abs(mPdgCharmNucleus) == 2010010020) { + mMassCharmNucleus = 3.226f; + } else { + LOG(fatal) << "********** [GeneratorPythia8HFEmbedCharmNuclei] Only c-deuteron (pdg=2010010020) currently supported! Exit **********"; + } + mLifetimeCharmNucleus = lifetime; + mDecayDistr = new TF1("mDecayDistr", "TMath::Exp(-x * 1./[0])", 0., mLifetimeCharmNucleus * 100); + mDecayDistr->SetNpx(10000); + mDecayDistr->SetParameter(0, mLifetimeCharmNucleus); + mDecayDistrLb = new TF1("mDecayDistrLb", "TMath::Exp(-x * 1./[0])", 0., 44.f); + mDecayDistrLb->SetParameter(0, 0.440f); // lifetime of Lambda_b in mm/c + mDecayDistrLb->SetNpx(10000); + mPtDistrLb = new TF1("mPtDistrLb","[0]*x/TMath::Power((1+TMath::Power(x/[1],[3])),[2])",0.,100.); + mPtDistrLb->SetParameters(1000., 6.97355, 3.20721, 1.71678); + mPtDistrLb->SetNpx(10000); + + Print(); + + auto& param = o2::eventgen::GeneratorPythia8Param::Instance(); + LOG(info) << "Init \'GeneratorPythia8HFEmbedCharmNuclei\' with following parameters"; + LOG(info) << param; + if (param.config.empty()) { + LOG(fatal) << "Failed to init \'GeneratorPythia8\': problems with configuration file "; + } + std::string cfg = gSystem->ExpandPathName(param.config.c_str()); + LOG(info) << "GeneratorPythia8HFEmbedCharmNuclei Reading configuration from file: " << cfg; + if (!mPythiaGun.readFile(cfg, true)) { + LOG(fatal) << "Failed to init \'GeneratorPythia8\': problems with configuration file " << cfg; + } + + mPythiaGun.readString("Random:setSeed = on"); + mPythiaGun.readString("Random:seed = " + std::to_string(seed)); + + if (!mPythiaGun.init()) { + LOG(fatal) << "Failed to init \'GeneratorPythia8\': init returned with error"; + } + } + + /// Destructor + ~GeneratorPythia8HFEmbedCharmNuclei() = default; + + /// Print the input + void Print() + { + LOG(info) << "********** GeneratorPythia8HFEmbedCharmNuclei configuration dump **********"; + LOG(info) << Form("* PDG code of charm nuclei to be injected: %d", mPdgCharmNucleus); + LOG(info) << Form("* Mass of charm nuclei to be injected (GeV/c2): %f", mMassCharmNucleus); + LOG(info) << Form("* Lifetime of charm nuclei to be injected (mm): %f", mLifetimeCharmNucleus); + LOG(info) << Form("* Number of charm nuclei injected per event: %d", nNumberOfCharmNucleiPerEvent); + LOG(info) << Form("* Charmed nucleus rapidity: %f - %f", mRapidityMinCharmNuclei, mRapidityMaxCharmNuclei); + LOG(info) << Form("* Charmed nucleus pT max (prompt): %f", mPtMaxCharmNuclei); + LOG(info) << Form("* Trivial coalescence: %d", mTrivialCoal); + LOG(info) << Form("* Coalescence momentum: %f", mCoalMomentum); + LOG(info) << Form("* Fraction from beauty: %f", mFractionFromBeauty); + LOG(info) << "***********************************************************************"; + } + + void setHadronRapidity(float yMin, float yMax) + { + mRapidityMinCharmNuclei = yMin; + mRapidityMaxCharmNuclei = yMax; + }; + + void setUsedSeed(unsigned int seed) + { + mUsedSeed = seed; + }; + + unsigned int getUsedSeed() const + { + return mUsedSeed; + }; + + //__________________________________________________________________ + bool generateEvent() override + { + // we start from an empty event + mPythia.event.reset(); + + // we simulate c-deuteron decays + for (int iCharmNuclei{0}; iCharmNuclei 0) ? mSign = -1 : mSign = 1; + if (nNumberOfCharmNucleiPerEvent % 2 != 0 && iCharmNuclei == nNumberOfCharmNucleiPerEvent - 1) { + if (gRandom->Rndm() < 0.5) { + mSign = 1; + } + } + + int pdgToGen = mPdgCharmNucleus; + float massToGen = mMassCharmNucleus; + float lifetimeToGen = 0.f; + float minRapToGen = mRapidityMinCharmNuclei; + float maxRapToGen = mRapidityMaxCharmNuclei; + bool isFromB = gRandom->Rndm() < mFractionFromBeauty; + // we determine if it's prompt or non-prompt + if (isFromB) { + pdgToGen = 5122; // we generate a Lambda_b and we let it decay into the charmed nucleus, no other beauty hadrons are considered + massToGen = 5.61940f; // mass of Lambda_b (GeV/c2) + lifetimeToGen = mDecayDistrLb->GetRandom(); + minRapToGen *= 2; + maxRapToGen *= 2; + } else { + lifetimeToGen = mDecayDistr->GetRandom(); + } + + auto pt = (!isFromB) ? gRandom->Uniform(0., mPtMaxCharmNuclei) : mPtDistrLb->GetRandom(); + auto y = gRandom->Uniform(minRapToGen, maxRapToGen); + auto phi = gRandom->Uniform(0, TMath::TwoPi()); + auto px = pt * TMath::Cos(phi); + auto py = pt * TMath::Sin(phi); + auto mt = TMath::Sqrt(massToGen * massToGen + pt * pt); + auto pz = mt * TMath::SinH(y); + auto p = TMath::Sqrt(pt * pt + pz * pz); + auto e = TMath::Sqrt(massToGen * massToGen + p * p); + + Particle particle; + particle.id(mSign * pdgToGen); + particle.status(83); + particle.m(massToGen); + particle.px(px); + particle.py(py); + particle.pz(pz); + particle.e(e); + particle.xProd(0.f); + particle.yProd(0.f); + particle.zProd(0.f); + particle.tau(lifetimeToGen); + mPythiaGun.particleData.mayDecay(5122, true); // force decay + mPythiaGun.particleData.mayDecay(mPdgCharmNucleus, true); // force decay + + bool isCoalSuccess{false}; + int nTrials{0}; + while(!isCoalSuccess || nTrials > 1e4) { + mPythiaGun.event.reset(); + mPythiaGun.event.append(particle); + mPythiaGun.moreDecays(); + std::array dausToCoal = {-1, -1}; + std::vector pdgShortLivedResos = {313, 2224, 102134}; + std::map statusResoDecay = {{313, -85}, {2224, -86}, {102134, -87}}; // do not use 94, it is used by default for no resonances + std::map statusResoDecayFromB = {{313, -95}, {2224, -96}, {102134, -97}}; // do not use 94, it is used by default for no resonances + int whichReso{0}; + int idxCharmNucleus{-1}; + for (int iPart{0}; iPart= idxCharmNucleus) { + // we need to change the indices of the daughter particles to point to the charmed nucleus + auto dauList = part.daughterList(); + for (auto const& dau : dauList) { + mPythiaGun.event[dau].mother1(idxCharmNucleus); + } + mPythiaGun.event.remove(iPart, iPart, true); + whichReso=*resoIt; + } + } + if (whichReso > 0) { // we have to reset all the particles as daughters of the charm nucleus + std::vector idxDausCharmNucleus{}; + for (int iPart{0}; iPart newPartList{}; + std::vector idxToRemove{}; + for (int iPart{idxDausCharmNucleus[0]}; iPart updatedMothers{}; + for (int iPart{0}; iPart{1000010020}, mTrivialCoal, mCoalMomentum, dausToCoal[0], dausToCoal[1], 10.); + if (whichReso > 0) { + if (isFromB) { + mPythiaGun.event[idxCharmNucleus].status(statusResoDecayFromB[whichReso]); + } else { + mPythiaGun.event[idxCharmNucleus].status(statusResoDecay[whichReso]); + } + } + if (isCoalSuccess) { + restoreEnergyConservation(mPythiaGun.event, idxCharmNucleus); + int offset = mPythia.event.size(); // we need to rescale the indices of mothers and daughters, accounting for the particles that are already appended to the event + for (int iPart{0}; iPart 0) { + part.mother1(mother1 + offset - 1); + } + if (mother2 > 0) { + part.mother2(mother2 + offset - 1); + } + if (daughter1 > 0) { + part.daughter1(daughter1 + offset - 1); + } + if (daughter2 > 0) { + part.daughter2(daughter2 + offset - 1); + } + mPythia.event.append(part); + } + } + nTrials++; + } + } + + return true; + } + + +private: + + void restoreEnergyConservation(Pythia8::Event& event, int idxCharmNucleus, float targetMassTolerance = 1e-5) { + /// In the coalescence, the energy is not conserved, we rescale the momentum of the charmed nuclei daughters to restore it to avoid changes in the invariant mass of the charmed nucleus + + float scale = 1.f; + float invMass{0.f}; + while (abs(invMass - mMassCharmNucleus) > targetMassTolerance) { + ROOT::Math::PxPyPzMVector fourVecCharmNucleus; + for (int iDau{event[idxCharmNucleus].daughter1()}; iDau<=event[idxCharmNucleus].daughter2(); ++iDau) { + auto dau = event[iDau]; + fourVecCharmNucleus += ROOT::Math::PxPyPzMVector(dau.px() * scale, dau.py() * scale, dau.pz() * scale, dau.m()); + } + invMass = fourVecCharmNucleus.M(); + scale *= mMassCharmNucleus / invMass; + } + + for (int iDau{event[idxCharmNucleus].daughter1()}; iDau<=event[idxCharmNucleus].daughter2(); ++iDau) { + event[iDau].px(event[iDau].px() * scale); + event[iDau].py(event[iDau].py() * scale); + event[iDau].pz(event[iDau].pz() * scale); + } + event[idxCharmNucleus].px(event[idxCharmNucleus].px() * scale); + event[idxCharmNucleus].py(event[idxCharmNucleus].py() * scale); + event[idxCharmNucleus].pz(event[idxCharmNucleus].pz() * scale); + } + + // Properties of selection + float mMassCharmNucleus; /// mass of the charmed nucleus + int mPdgCharmNucleus; /// pdg code of the charmed nucleus + float mLifetimeCharmNucleus; /// lifetime of the charmed nucleus + int nNumberOfCharmNucleiPerEvent; /// number of charmed nuclei injected per event + float mRapidityMinCharmNuclei; /// rapidity min of the generated charmed nuclei + float mRapidityMaxCharmNuclei; /// rapidity max of the generated charmed nuclei + float mPtMaxCharmNuclei; /// pT max of the generated charmed nuclei + unsigned int mUsedSeed; /// seed + bool mTrivialCoal; /// if true, the coalescence is done without checking the distance in the phase space of the nucleons + float mCoalMomentum; /// coalescence momentum + Pythia8::Pythia mPythiaGun; /// Gun generator with decay support + TF1* mDecayDistr; /// Lifetime distribution + TF1* mDecayDistrLb; /// Lifetime distribution for Lb + TF1* mPtDistrLb; /// pt distribution for Lb (power-law fit to FONLL) + float mFractionFromBeauty; /// fraction of charmed nuclei coming from beauty hadrons + int mSign; /// sign of the charmed nuclei to be generated, if 0 they are generated with 50% of probability as particle or antiparticle +}; + + +///___________________________________________________________ +FairGenerator *GenerateHFEmbedCDeuteron(float lifetime = 1.f, int nCharmNucleiPerEvent = 10, float yMin = -1.f, float yMax = 1.f, float ptMax = 25.f, bool trivialCoal = false, float coalMomentum = 0.2f, float fracFromB = 0.25f) +{ + auto seed = (gRandom->TRandom::GetSeed() % 900000000); + auto myGen = new GeneratorPythia8HFEmbedCharmNuclei(2010010020, lifetime, nCharmNucleiPerEvent, yMin, yMax, ptMax, trivialCoal, coalMomentum, fracFromB, seed); + myGen->readString("Random:setSeed on"); + myGen->readString("Random:seed " + std::to_string(seed)); + return myGen; +} diff --git a/MC/config/PWGHF/external/generator/generator_pythia8_embed_hf.C b/MC/config/PWGHF/external/generator/generator_pythia8_embed_hf.C index 1fd07e182..7a28d631a 100644 --- a/MC/config/PWGHF/external/generator/generator_pythia8_embed_hf.C +++ b/MC/config/PWGHF/external/generator/generator_pythia8_embed_hf.C @@ -10,6 +10,7 @@ using namespace Pythia8; +#include namespace hf_generators { enum GenType : int { @@ -35,7 +36,13 @@ public: //} /// Destructor - ~GeneratorPythia8EmbedHF() = default; + ~GeneratorPythia8EmbedHF() { + // Clean up the internally created HF generator if any + if (mGeneratorEvHF) { + delete mGeneratorEvHF; + mGeneratorEvHF = nullptr; + } + } /// Init bool Init() override @@ -51,29 +58,30 @@ public: /// \param yHadronMin minimum hadron rapidity /// \param yHadronMax maximum hadron rapidity /// \param hadronPdgList list of PDG codes for hadrons to be used in trigger - void setupGeneratorEvHF(int genType, bool usePtHardBins, float yQuarkMin, float yQuarkMax, float yHadronMin, float yHadronMax, std::vector hadronPdgList = {}) { + /// \param quarkPdgList list of PDG codes for quarks to be enriched in the trigger + void setupGeneratorEvHF(int genType, bool usePtHardBins, float yQuarkMin, float yQuarkMax, float yHadronMin, float yHadronMax, std::vector quarkPdgList = {}, std::vector hadronPdgList = {}, std::vector> partPdgToReplaceList = {}, std::vector freqReplaceList = {}) { mGeneratorEvHF = nullptr; switch (genType) { case hf_generators::GapTriggeredCharm: LOG(info) << "********** [GeneratorPythia8EmbedHF] configuring GeneratorPythia8GapTriggeredCharm **********"; LOG(info) << "********** Default number of HF signal events to be merged (updated by notifyEmbedding): " << mNumSigEvs; - mGeneratorEvHF = dynamic_cast(GeneratorPythia8GapTriggeredCharm(/*no gap trigger*/1, yQuarkMin, yQuarkMax, yHadronMin, yHadronMax, hadronPdgList)); + mGeneratorEvHF = dynamic_cast(GeneratorPythia8GapTriggeredCharm(/*no gap trigger*/1, yQuarkMin, yQuarkMax, yHadronMin, yHadronMax, hadronPdgList, partPdgToReplaceList, freqReplaceList)); break; case hf_generators::GapTriggeredBeauty: LOG(info) << "********** [GeneratorPythia8EmbedHF] configuring GeneratorPythia8GapTriggeredBeauty **********"; LOG(info) << "********** Default number of HF signal events to be merged (updated by notifyEmbedding): " << mNumSigEvs; - mGeneratorEvHF = dynamic_cast(GeneratorPythia8GapTriggeredBeauty(/*no gap trigger*/1, yQuarkMin, yQuarkMax, yHadronMin, yHadronMax, hadronPdgList)); + mGeneratorEvHF = dynamic_cast(GeneratorPythia8GapTriggeredBeauty(/*no gap trigger*/1, yQuarkMin, yQuarkMax, yHadronMin, yHadronMax, hadronPdgList, partPdgToReplaceList, freqReplaceList)); break; case hf_generators::GapTriggeredCharmAndBeauty: LOG(info) << "********** [GeneratorPythia8EmbedHF] configuring GeneratorPythia8GapTriggeredCharmAndBeauty **********"; LOG(info) << "********** Default number of HF signal events to be merged (updated by notifyEmbedding): " << mNumSigEvs; - mGeneratorEvHF = dynamic_cast(GeneratorPythia8GapTriggeredCharmAndBeauty(/*no gap trigger*/1, yQuarkMin, yQuarkMax, yHadronMin, yHadronMax, hadronPdgList)); + mGeneratorEvHF = dynamic_cast(GeneratorPythia8GapTriggeredCharmAndBeauty(/*no gap trigger*/1, yQuarkMin, yQuarkMax, yHadronMin, yHadronMax, hadronPdgList, partPdgToReplaceList, freqReplaceList)); break; case hf_generators::GapHF: LOG(info) << "********** [GeneratorPythia8EmbedHF] configuring GeneratorPythia8GapHF **********"; LOG(info) << "********** Default number of HF signal events to be merged (updated by notifyEmbedding): " << mNumSigEvs; - mGeneratorEvHF = dynamic_cast(GeneratorPythia8GapHF(/*no gap trigger*/1, yQuarkMin, yQuarkMax, yHadronMin, yHadronMax, hadronPdgList)); + mGeneratorEvHF = dynamic_cast(GeneratorPythia8GapTriggeredBeauty(/*no gap trigger*/1, yQuarkMin, yQuarkMax, yHadronMin, yHadronMax, hadronPdgList, partPdgToReplaceList, freqReplaceList)); break; default: LOG(fatal) << "********** [GeneratorPythia8EmbedHF] bad configuration, fix it! **********"; @@ -111,7 +119,7 @@ public: LOG(info) << "[notifyEmbedding] ----- Collision impact parameter: " << x; /// number of events to be embedded in a background event - mNumSigEvs = std::max(1.,120.*(x<5.)+80.*(1.-x/20.)*(x>5.)*(x<11.)+240.*(1.-x/13.)*(x>11.)); + mNumSigEvs = static_cast(std::lround(5.0 + 0.886202881 * std::pow(std::max(0.0f, 17.5f - x), 1.7))); LOG(info) << "[notifyEmbedding] ----- generating " << mNumSigEvs << " signal events " << std::endl; }; @@ -380,34 +388,34 @@ private: }; // Charm enriched -FairGenerator * GeneratorPythia8EmbedHFCharm(bool usePtHardBins = false, float yQuarkMin = -1.5, float yQuarkMax = 1.5, float yHadronMin = -1.5, float yHadronMax = 1.5, std::vector hadronPdgList = {}) +FairGenerator * GeneratorPythia8EmbedHFCharm(bool usePtHardBins = false, float yQuarkMin = -1.5, float yQuarkMax = 1.5, float yHadronMin = -1.5, float yHadronMax = 1.5, std::vector quarkPdgList = {}, std::vector hadronPdgList = {}, std::vector> partPdgToReplaceList = {}, std::vector freqReplaceList = {}) { auto myGen = new GeneratorPythia8EmbedHF(); /// setup the internal generator for HF events - myGen->setupGeneratorEvHF(hf_generators::GapTriggeredCharm, usePtHardBins, yQuarkMin, yQuarkMax, yHadronMin, yHadronMax, hadronPdgList); + myGen->setupGeneratorEvHF(hf_generators::GapTriggeredCharm, usePtHardBins, yQuarkMin, yQuarkMax, yHadronMin, yHadronMax, quarkPdgList, hadronPdgList, partPdgToReplaceList, freqReplaceList); return myGen; } // Beauty enriched -FairGenerator * GeneratorPythia8EmbedHFBeauty(bool usePtHardBins = false, float yQuarkMin = -1.5, float yQuarkMax = 1.5, float yHadronMin = -1.5, float yHadronMax = 1.5, std::vector hadronPdgList = {}) +FairGenerator * GeneratorPythia8EmbedHFBeauty(bool usePtHardBins = false, float yQuarkMin = -1.5, float yQuarkMax = 1.5, float yHadronMin = -1.5, float yHadronMax = 1.5, std::vector quarkPdgList = {}, std::vector hadronPdgList = {}, std::vector> partPdgToReplaceList = {}, std::vector freqReplaceList = {}) { auto myGen = new GeneratorPythia8EmbedHF(); /// setup the internal generator for HF events - myGen->setupGeneratorEvHF(hf_generators::GapTriggeredBeauty, usePtHardBins, yQuarkMin, yQuarkMax, yHadronMin, yHadronMax, hadronPdgList); + myGen->setupGeneratorEvHF(hf_generators::GapTriggeredBeauty, usePtHardBins, yQuarkMin, yQuarkMax, yHadronMin, yHadronMax, quarkPdgList, hadronPdgList, partPdgToReplaceList, freqReplaceList); return myGen; } // Charm and beauty enriched (with same ratio) -FairGenerator * GeneratorPythia8EmbedHFCharmAndBeauty(bool usePtHardBins = false, float yQuarkMin = -1.5, float yQuarkMax = 1.5, float yHadronMin = -1.5, float yHadronMax = 1.5, std::vector hadronPdgList = {}) +FairGenerator * GeneratorPythia8EmbedHFCharmAndBeauty(bool usePtHardBins = false, float yQuarkMin = -1.5, float yQuarkMax = 1.5, float yHadronMin = -1.5, float yHadronMax = 1.5, std::vector quarkPdgList = {}, std::vector hadronPdgList = {}, std::vector> partPdgToReplaceList = {}, std::vector freqReplaceList = {}) { auto myGen = new GeneratorPythia8EmbedHF(); /// setup the internal generator for HF events - myGen->setupGeneratorEvHF(hf_generators::GapTriggeredCharmAndBeauty, usePtHardBins, yQuarkMin, yQuarkMax, yHadronMin, yHadronMax, hadronPdgList); + myGen->setupGeneratorEvHF(hf_generators::GapTriggeredCharmAndBeauty, usePtHardBins, yQuarkMin, yQuarkMax, yHadronMin, yHadronMax, quarkPdgList, hadronPdgList, partPdgToReplaceList, freqReplaceList); return myGen; } diff --git a/MC/config/PWGHF/external/generator/generator_pythia8_gaptriggered_hf.C b/MC/config/PWGHF/external/generator/generator_pythia8_gaptriggered_hf.C index 2f7ae4226..2b801b47f 100644 --- a/MC/config/PWGHF/external/generator/generator_pythia8_gaptriggered_hf.C +++ b/MC/config/PWGHF/external/generator/generator_pythia8_gaptriggered_hf.C @@ -1,7 +1,14 @@ +R__LOAD_LIBRARY(EvtGen) +R__ADD_INCLUDE_PATH($EVTGEN_ROOT/include) + #include "FairGenerator.h" #include "Generators/GeneratorPythia8.h" +#include "Generators/GeneratorPythia8Param.h" +#include "EvtGen/EvtGen.hh" #include "Pythia8/Pythia.h" +#include "Pythia8Plugins/EvtGen.h" #include "TRandom.h" +#include "TDatabasePDG.h" #include #include @@ -16,21 +23,54 @@ public: GeneratorPythia8GapTriggeredHF() = default; /// constructor - GeneratorPythia8GapTriggeredHF(int inputTriggerRatio = 5, std::vector quarkPdgList = {}, std::vector hadronPdgList = {}) + GeneratorPythia8GapTriggeredHF(int inputTriggerRatio = 5, std::vector quarkPdgList = {}, std::vector hadronPdgList = {}, std::vector> partPdgToReplaceList = {}, std::vector freqReplaceList = {}) { mGeneratedEvents = 0; mInverseTriggerRatio = inputTriggerRatio; mQuarkRapidityMin = -1.5; - mQuarkRapidityMax = -1.5; + mQuarkRapidityMax = 1.5; mHadRapidityMin = -1.5; - mHadRapidityMax = -1.5; + mHadRapidityMax = 1.5; mQuarkPdg = 0; mHadronPdg = 0; mQuarkPdgList = quarkPdgList; mHadronPdgList = hadronPdgList; + mPartPdgToReplaceList = partPdgToReplaceList; + mFreqReplaceList = freqReplaceList; + mEvtGen = nullptr; + mUseEvtGen = false; + mEvtGenDecTable = ""; + // Ds1*(2700), Ds1*(2860), Ds3*(2860), Xic(3055)+, Xic(3080)+, Xic(3055)0, Xic(3080)0, LambdaC(2625), LambdaC(2595), LambdaC(2860), LambdaC(2880), LambdaC(2940), ThetaC(3100) + mCustomPartPdgs = {30433, 40433, 437, 4315, 4316, 4325, 4326, 4124, 14122, 24124, 24126, 4125, 9422111}; + mCustomPartMasses[30433] = 2.714f; + mCustomPartMasses[40433] = 2.859f; + mCustomPartMasses[437] = 2.860f; + mCustomPartMasses[4315] = 3.0590f; + mCustomPartMasses[4316] = 3.0799f; + mCustomPartMasses[4325] = 3.0559f; + mCustomPartMasses[4326] = 3.0772f; + mCustomPartMasses[4124] = 2.62810f; + mCustomPartMasses[14122] = 2.59225f; + mCustomPartMasses[24124] = 2.8561f; + mCustomPartMasses[24126] = 2.8816; + mCustomPartMasses[4125] = 2.9396f; + mCustomPartMasses[9422111] = 3.099f; + mCustomPartWidths[30433] = 0.122f; + mCustomPartWidths[40433] = 0.160f; + mCustomPartWidths[437] = 0.053f; + mCustomPartWidths[4315] = 0.0064f; + mCustomPartWidths[4316] = 0.0056f; + mCustomPartWidths[4325] = 0.0078f; + mCustomPartWidths[4326] = 0.0036f; + mCustomPartWidths[4124] = 0.00052f; + mCustomPartWidths[14122] = 0.0026f; + mCustomPartWidths[24124] = 0.0676f; + mCustomPartWidths[24126] = 0.0056f; + mCustomPartWidths[4125] = 0.017f; + mCustomPartWidths[9422111] = 0.0000083f; Print(); - } + } /// Destructor ~GeneratorPythia8GapTriggeredHF() = default; @@ -54,6 +94,11 @@ public: { LOG(info)< {} (freq. {})", mPartPdgToReplaceList[iRepl].at(0), mPartPdgToReplaceList[iRepl].at(1), mFreqReplaceList[iRepl]); + } LOG(info)<<"***********************************************************************"; } @@ -62,6 +107,25 @@ public: addSubGenerator(0, "Minimum bias"); addSubGenerator(4, "Charm injected"); addSubGenerator(5, "Beauty injected"); + + std::vector pdgToReplace{}; + for (auto iRepl{0u}; iRepl 1.f) { + LOGP(fatal, "Replacing more than 100% of a particle!"); + } + pdgToReplace.push_back(mPartPdgToReplaceList[iRepl].at(0)); + } + + if (mUseEvtGen) { + mEvtGen = new Pythia8::EvtGenDecays(&mPythia, mEvtGenDecTable.data(), gSystem->ExpandPathName("$EVTGEN_ROOT/share/EvtGen/evt.pdl")); + } + return o2::eventgen::GeneratorPythia8::Init(); } @@ -83,6 +147,14 @@ public: { return mUsedSeed; }; + void setUseEvtGenDecayer(std::string evtGenDecTable = "") { + mUseEvtGen = true; + if (evtGenDecTable.empty()) { + mEvtGenDecTable = gSystem->ExpandPathName("$EVTGEN_ROOT/share/EvtGen/DECAY.DEC"); + } else { + mEvtGenDecTable = gSystem->ExpandPathName(evtGenDecTable.data()); + } + } protected: //__________________________________________________________________ @@ -115,7 +187,11 @@ protected: { if (GeneratorPythia8::generateEvent()) { - genOk = selectEvent(mPythia.event); + if (mUseEvtGen) { + mEvtGen->decay(); + checkConsistency(); + } + genOk = selectEvent(); } } notifySubGenerator(mQuarkPdg); @@ -127,6 +203,12 @@ protected: while (!genOk) { genOk = GeneratorPythia8::generateEvent(); + if (genOk) { + if (mUseEvtGen) { + mEvtGen->decay(); + checkConsistency(); + } + } } notifySubGenerator(0); } @@ -136,34 +218,36 @@ protected: return true; } - bool selectEvent(const Pythia8::Event &event) + bool selectEvent() { bool isGoodAtPartonLevel{mQuarkPdgList.size() == 0}; bool isGoodAtHadronLevel{mHadronPdgList.size() == 0}; + bool anyPartToReplace{mPartPdgToReplaceList.size() > 0}; - for (auto iPart{0}; iPart < event.size(); ++iPart) + for (auto iPart{0}; iPart < mPythia.event.size(); ++iPart) { + // search for Q-Qbar mother with at least one Q in rapidity window if (!isGoodAtPartonLevel) { - auto daughterList = event[iPart].daughterList(); + auto daughterList = mPythia.event[iPart].daughterList(); bool hasQ = false, hasQbar = false, atSelectedY = false; for (auto iDau : daughterList) { - if (event[iDau].id() == mQuarkPdg) + if (mPythia.event[iDau].id() == mQuarkPdg) { hasQ = true; - if ((event[iDau].y() > mQuarkRapidityMin) && (event[iDau].y() < mQuarkRapidityMax)) + if ((mPythia.event[iDau].y() > mQuarkRapidityMin) && (mPythia.event[iDau].y() < mQuarkRapidityMax)) { atSelectedY = true; } } - if (event[iDau].id() == -mQuarkPdg) + if (mPythia.event[iDau].id() == -mQuarkPdg) { hasQbar = true; - if ((event[iDau].y() > mQuarkRapidityMin) && (event[iDau].y() < mQuarkRapidityMax)) + if ((mPythia.event[iDau].y() > mQuarkRapidityMin) && (mPythia.event[iDau].y() < mQuarkRapidityMax)) { atSelectedY = true; } @@ -178,30 +262,144 @@ protected: // search for hadron in rapidity window if (!isGoodAtHadronLevel) { - int id = std::abs(event[iPart].id()); - float rap = event[iPart].y(); + int id = std::abs(mPythia.event[iPart].id()); + float rap = mPythia.event[iPart].y(); if (id == mHadronPdg && rap > mHadRapidityMin && rap < mHadRapidityMax) { isGoodAtHadronLevel = true; } } - // we send the trigger - if (isGoodAtPartonLevel && isGoodAtHadronLevel) + // if requested, we replace the particle + const double pseudoRndm = mPythia.event[iPart].pT() * 1000. - (int64_t)(mPythia.event[iPart].pT() * 1000); + for (auto iPartToReplace{0u}; iPartToReplace= 91 && statusMother <= 99) { + return false; + } + + auto mothers = mPythia.event[iPartToReplace].motherList(); + + int charge = mPythia.event[iPartToReplace].id() / std::abs(mPythia.event[iPartToReplace].id()); + float px = mPythia.event[iPartToReplace].px(); + float py = mPythia.event[iPartToReplace].py(); + float pz = mPythia.event[iPartToReplace].pz(); + float mass = 0.f; + + if (std::find(mCustomPartPdgs.begin(), mCustomPartPdgs.end(), pdgCodeNew) == mCustomPartPdgs.end()) { // not a custom particle + float width = TDatabasePDG::Instance()->GetParticle(pdgCodeNew)->Width(); + float massRest = TDatabasePDG::Instance()->GetParticle(pdgCodeNew)->Mass(); + if (width > 0.f) { + mass = gRandom->BreitWigner(massRest, width); + } else { + mass = massRest; + } + } else { + if (mCustomPartWidths[pdgCodeNew] > 0.f) { + mass = gRandom->BreitWigner(mCustomPartMasses[pdgCodeNew], mCustomPartWidths[pdgCodeNew]); + } else { + mass = mCustomPartMasses[pdgCodeNew]; + } + } + float energy = std::sqrt(px*px + py*py + pz*pz + mass*mass); + + // buffer daughter indices of mothers + std::vector> dauOfMothers{}; + for (auto const& mother: mothers) { + dauOfMothers.push_back(mPythia.event[mother].daughterList()); + } + + // we remove particle to replace and its daughters + mPythia.event[iPartToReplace].undoDecay(); + int status = std::abs(mPythia.event[iPartToReplace].status()); // we must get it here otherwise it is negative (already decayed) + if (status < 81 || status > 89) { + status = 81; + } + mPythia.event.remove(iPartToReplace, iPartToReplace, true); // we remove the original particle + + // we restore the daughter indices of the mothers after the removal + int newPartIdx{0}; + std::array newMothers = {0, 0}; + if (o2::eventgen::GeneratorPythia8Param::Instance().includePartonEvent) { // only necessary in case of parton event, otherwise we keep no mother + newMothers[0] = mothers.front(); + newMothers[1] = mothers.back(); + newPartIdx = mPythia.event.size(); + } + for (auto iMom{0u}; iMom dau1) { + mPythia.event[mothers[iMom]].daughter1(dau1); + mPythia.event[mothers[iMom]].daughter2(dau2 - 1); + } else if (dau1 == dau2) { + if (dau1 == 0) { + mPythia.event[mothers[iMom]].daughter1(0); + mPythia.event[mothers[iMom]].daughter2(0); + } else { // in this case we set it equal to the new particle + mPythia.event[mothers[iMom]].daughter1(newPartIdx); + mPythia.event[mothers[iMom]].daughter2(newPartIdx); + } + } else if (dau2 < dau1) { // in this case we set it equal to the new particle + if (dau2 == 0) { + mPythia.event[mothers[iMom]].daughter1(newPartIdx); + } else { + if (dau1 == iPartToReplace) { + mPythia.event[mothers[iMom]].daughter1(newPartIdx); + } else { + mPythia.event[mothers[iMom]].daughter2(newPartIdx); + } + } + } + } + + mPythia.event.append(charge * pdgCodeNew, status, newMothers[0], newMothers[1], 0, 0, 0, 0, px, py, pz, energy, mass); + mPythia.moreDecays(); // we need to decay the new particle + + return true; + } + + void checkConsistency() { + for (int iPart{1}; iPartGetParticle(abs(mPythia.event[iPart].id()))) { + // std::cout << "Particle code non known in TDatabasePDG " << mPythia.event[iPart].id() << " - set pdg = 89" << std::endl; + mPythia.event[iPart].id(89); + } + } + } + + private: // Interface to override import particles Pythia8::Event mOutputEvent; - // Properties of selection +// Properties of selection int mQuarkPdg; float mQuarkRapidityMin; float mQuarkRapidityMax; @@ -209,6 +407,11 @@ private: float mHadRapidityMin; float mHadRapidityMax; unsigned int mUsedSeed; + std::vector> mPartPdgToReplaceList; + std::vector mFreqReplaceList; + std::vector mCustomPartPdgs; + std::map mCustomPartMasses; + std::map mCustomPartWidths; // Control gap-triggering unsigned long long mGeneratedEvents; @@ -219,13 +422,19 @@ private: // Control alternate trigger on different hadrons std::vector mHadronPdgList = {}; + + // EVTGEN decayer from PYTHIA8 plugins + Pythia8::EvtGenDecays *mEvtGen; + bool mUseEvtGen; + std::string mEvtGenDecTable; + }; // Predefined generators: // Charm-enriched -FairGenerator *GeneratorPythia8GapTriggeredCharm(int inputTriggerRatio, float yQuarkMin = -1.5, float yQuarkMax = 1.5, float yHadronMin = -1.5, float yHadronMax = 1.5, std::vector hadronPdgList = {}) +FairGenerator *GeneratorPythia8GapTriggeredCharm(int inputTriggerRatio, float yQuarkMin = -1.5, float yQuarkMax = 1.5, float yHadronMin = -1.5, float yHadronMax = 1.5, std::vector hadronPdgList = {}, std::vector> partPdgToReplaceList = {}, std::vector freqReplaceList = {}) { - auto myGen = new GeneratorPythia8GapTriggeredHF(inputTriggerRatio, std::vector{4}, hadronPdgList); + auto myGen = new GeneratorPythia8GapTriggeredHF(inputTriggerRatio, std::vector{4}, hadronPdgList, partPdgToReplaceList, freqReplaceList); auto seed = (gRandom->TRandom::GetSeed() % 900000000); myGen->setUsedSeed(seed); myGen->readString("Random:setSeed on"); @@ -239,9 +448,9 @@ FairGenerator *GeneratorPythia8GapTriggeredCharm(int inputTriggerRatio, float yQ } // Beauty-enriched -FairGenerator *GeneratorPythia8GapTriggeredBeauty(int inputTriggerRatio, float yQuarkMin = -1.5, float yQuarkMax = 1.5, float yHadronMin = -1.5, float yHadronMax = 1.5, std::vector hadronPdgList = {}) +FairGenerator *GeneratorPythia8GapTriggeredBeauty(int inputTriggerRatio, float yQuarkMin = -1.5, float yQuarkMax = 1.5, float yHadronMin = -1.5, float yHadronMax = 1.5, std::vector hadronPdgList = {}, std::vector> partPdgToReplaceList = {}, std::vector freqReplaceList = {}) { - auto myGen = new GeneratorPythia8GapTriggeredHF(inputTriggerRatio, std::vector{5}, hadronPdgList); + auto myGen = new GeneratorPythia8GapTriggeredHF(inputTriggerRatio, std::vector{5}, hadronPdgList, partPdgToReplaceList, freqReplaceList); auto seed = (gRandom->TRandom::GetSeed() % 900000000); myGen->setUsedSeed(seed); myGen->readString("Random:setSeed on"); @@ -255,9 +464,9 @@ FairGenerator *GeneratorPythia8GapTriggeredBeauty(int inputTriggerRatio, float y } // Charm and beauty enriched (with same ratio) -FairGenerator *GeneratorPythia8GapTriggeredCharmAndBeauty(int inputTriggerRatio, float yQuarkMin = -1.5, float yQuarkMax = 1.5, float yHadronMin = -1.5, float yHadronMax = 1.5, std::vector hadronPdgList = {}) +FairGenerator *GeneratorPythia8GapTriggeredCharmAndBeauty(int inputTriggerRatio, float yQuarkMin = -1.5, float yQuarkMax = 1.5, float yHadronMin = -1.5, float yHadronMax = 1.5, std::vector hadronPdgList = {}, std::vector> partPdgToReplaceList = {}, std::vector freqReplaceList = {}) { - auto myGen = new GeneratorPythia8GapTriggeredHF(inputTriggerRatio, std::vector{4, 5}, hadronPdgList); + auto myGen = new GeneratorPythia8GapTriggeredHF(inputTriggerRatio, std::vector{4, 5}, hadronPdgList, partPdgToReplaceList, freqReplaceList); auto seed = (gRandom->TRandom::GetSeed() % 900000000); myGen->setUsedSeed(seed); myGen->readString("Random:setSeed on"); @@ -270,13 +479,13 @@ FairGenerator *GeneratorPythia8GapTriggeredCharmAndBeauty(int inputTriggerRatio, return myGen; } -FairGenerator *GeneratorPythia8GapHF(int inputTriggerRatio, float yQuarkMin = -1.5, float yQuarkMax = 1.5, float yHadronMin = -1.5, float yHadronMax = 1.5, std::vector quarkPdgList = {}, std::vector hadronPdgList = {}) +FairGenerator *GeneratorPythia8GapHF(int inputTriggerRatio, float yQuarkMin = -1.5, float yQuarkMax = 1.5, float yHadronMin = -1.5, float yHadronMax = 1.5, std::vector quarkPdgList = {}, std::vector hadronPdgList = {}, std::vector> partPdgToReplaceList = {}, std::vector freqReplaceList = {}) { if (hadronPdgList.size() == 0 && quarkPdgList.size() == 0) { LOG(fatal) << "GeneratorPythia8GapHF: At least one quark or hadron PDG code must be specified"; } - auto myGen = new GeneratorPythia8GapTriggeredHF(inputTriggerRatio, quarkPdgList, hadronPdgList); + auto myGen = new GeneratorPythia8GapTriggeredHF(inputTriggerRatio, quarkPdgList, hadronPdgList, partPdgToReplaceList, freqReplaceList); auto seed = (gRandom->TRandom::GetSeed() % 900000000); myGen->setUsedSeed(seed); myGen->readString("Random:setSeed on"); @@ -285,4 +494,21 @@ FairGenerator *GeneratorPythia8GapHF(int inputTriggerRatio, float yQuarkMin = -1 myGen->setHadronRapidity(yHadronMin, yHadronMax); return myGen; -} \ No newline at end of file +} + +// Beauty-enriched with EvtGen decayer +FairGenerator *GeneratorPythia8GapTriggeredBeautyWithEvtGen(int inputTriggerRatio, float yQuarkMin = -1.5, float yQuarkMax = 1.5, float yHadronMin = -1.5, float yHadronMax = 1.5, std::vector hadronPdgList = {}, std::vector> partPdgToReplaceList = {}, std::vector freqReplaceList = {}, std::string decayTable = "") +{ + auto myGen = new GeneratorPythia8GapTriggeredHF(inputTriggerRatio, std::vector{5}, hadronPdgList, partPdgToReplaceList, freqReplaceList); + auto seed = (gRandom->TRandom::GetSeed() % 900000000); + myGen->setUsedSeed(seed); + myGen->readString("Random:setSeed on"); + myGen->readString("Random:seed " + std::to_string(seed)); + myGen->setQuarkRapidity(yQuarkMin, yQuarkMax); + if (hadronPdgList.size() != 0) + { + myGen->setHadronRapidity(yHadronMin, yHadronMax); + } + myGen->setUseEvtGenDecayer(decayTable); + return myGen; +} diff --git a/MC/config/PWGHF/external/generator/generator_pythia8_hfhadron_to_nuclei.C b/MC/config/PWGHF/external/generator/generator_pythia8_hfhadron_to_nuclei.C new file mode 100644 index 000000000..a2aadef89 --- /dev/null +++ b/MC/config/PWGHF/external/generator/generator_pythia8_hfhadron_to_nuclei.C @@ -0,0 +1,202 @@ +#include "FairGenerator.h" +#include "Generators/GeneratorPythia8.h" +#include "Pythia8/Pythia.h" +#include "TRandom.h" +#include +#include +#include +#include + +R__ADD_INCLUDE_PATH($O2DPG_MC_CONFIG_ROOT) +#include "MC/config/common/external/generator/CoalescencePythia8.h" + +using namespace Pythia8; + +class GeneratorPythia8HFHadToNuclei : public o2::eventgen::GeneratorPythia8 +{ + public: + /// default constructor + GeneratorPythia8HFHadToNuclei() = default; + + /// constructor + GeneratorPythia8HFHadToNuclei(int inputTriggerRatio = 5, std::vector hfHadronPdgList = {}, std::vector nucleiPdgList = {}, bool trivialCoal = false, float coalMomentum = 0.4) + { + + mGeneratedEvents = 0; + mInverseTriggerRatio = inputTriggerRatio; + mHadRapidityMin = -1.5; + mHadRapidityMax = 1.5; + mHadronPdg = 0; + mHFHadronPdgList = hfHadronPdgList; + mNucleiPdgList = nucleiPdgList; + mTrivialCoal = trivialCoal; + mCoalMomentum = coalMomentum; + Print(); + } + + /// Destructor + ~GeneratorPythia8HFHadToNuclei() = default; + + /// Print the input + void Print() + { + LOG(info) << "********** GeneratorPythia8HFHadToNuclei configuration dump **********"; + LOG(info) << Form("* Trigger ratio: %d", mInverseTriggerRatio); + LOG(info) << Form("* Hadron rapidity: %f - %f", mHadRapidityMin, mHadRapidityMax); + LOG(info) << Form("* Hadron pdg list: "); + for (auto pdg : mHFHadronPdgList) { + LOG(info) << Form("* %d ", pdg); + } + LOG(info) << Form("* Trivial coalescence: %d", mTrivialCoal); + LOG(info) << Form("* Coalescence momentum: %f", mCoalMomentum); + LOG(info) << Form("* Nuclei pdg list: "); + for (auto pdg : mNucleiPdgList) { + LOG(info) << Form("* %d ", pdg); + } + LOG(info) << "***********************************************************************"; + } + + bool Init() override + { + addSubGenerator(0, "Minimum bias"); + addSubGenerator(1, "HF + Coalescence"); + return o2::eventgen::GeneratorPythia8::Init(); + } + + void setHadronRapidity(float yMin, float yMax) + { + mHadRapidityMin = yMin; + mHadRapidityMax = yMax; + }; + void setUsedSeed(unsigned int seed) + { + mUsedSeed = seed; + }; + unsigned int getUsedSeed() const + { + return mUsedSeed; + }; + + protected: + //__________________________________________________________________ + bool generateEvent() override + { + // Simple straightforward check to alternate generators + if (mGeneratedEvents % mInverseTriggerRatio == 0) { + int nInjectedEvents = mGeneratedEvents / mInverseTriggerRatio; + // Alternate hadrons if enabled (with the same ratio) + if (mHFHadronPdgList.size() >= 1) { + int iHadron = nInjectedEvents % mHFHadronPdgList.size(); + mHadronPdg = mHFHadronPdgList[iHadron]; + LOG(info) << "Selected hadron: " << mHFHadronPdgList[iHadron]; + } + + // Generate event of interest + bool genOk = false; + while (!genOk) { + if (GeneratorPythia8::generateEvent()) { + genOk = selectEvent(mPythia.event); + } + } + notifySubGenerator(1); + } else { + // Generate minimum-bias event + bool genOk = false; + while (!genOk) { + genOk = GeneratorPythia8::generateEvent(); + } + notifySubGenerator(0); + } + + mGeneratedEvents++; + + return true; + } + + bool selectEvent(Pythia8::Event& event) + { + for (auto iPart{0}; iPart < event.size(); ++iPart) { + // search for hadron in rapidity window + int id = std::abs(event[iPart].id()); + float rap = event[iPart].y(); + if (id == mHadronPdg && rap > mHadRapidityMin && rap < mHadRapidityMax) { + + int d1 = event[iPart].daughter1(); + int d2 = event[iPart].daughter2(); + + // Protection for invalid index of daughter 1 + if (d1 < 0 || d1 >= event.size()) { + LOG(info) << "Invalid daughter index 1! d1 = " << d1; + continue; + } + + // Protection for invalid index of daughter 2 + if (d2 < 0 || d2 >= event.size()) { + LOG(info) << "Invalid daughter index 2! d2 = " << d2; + continue; + } + + // Swap order + if (d1 > d2) { + std::swap(d1, d2); + } + + // No daughters + if (d1 == 0 && d2 == 0) { + LOG(info) << "No daughters (0,0). Skipping."; + continue; + } + + LOG(debug) << "-----------------------------------------------------"; + LOG(debug) << "Found hadron " << event[iPart].id() << " with rapidity " << rap << " and daughters " << d1 << " " << d2; + // print pdg code of daughters + LOG(debug) << "Daughters: "; + for (int iDau = d1; iDau <= d2; ++iDau) { + LOG(debug) << "Daughter " << iDau << ": " << event[iDau].id(); + } + bool isCoalDone = CoalescencePythia8(event, mNucleiPdgList, mTrivialCoal, mCoalMomentum, d1, d2); + if (isCoalDone) { + LOG(debug) << "Coalescence process found for hadron " << event[iPart].id() << " with daughters " << d1 << " " << d2; + LOG(debug) << "Check updated daughters: "; + for (int iDau = d1; iDau <= d2; ++iDau) { + LOG(debug) << "Daughter " << iDau << ": " << event[iDau].id(); + } + return true; + } + } + } + return false; + }; + + private: + // Interface to override import particles + Pythia8::Event mOutputEvent; + + // Properties of selection + int mHadronPdg; + float mHadRapidityMin; + float mHadRapidityMax; + unsigned int mUsedSeed; + + // Control gap-triggering + unsigned long long mGeneratedEvents; + int mInverseTriggerRatio; + + // Control alternate trigger on different hadrons + std::vector mHFHadronPdgList = {}; + std::vector mNucleiPdgList = {}; + + bool mTrivialCoal = false; /// if true, the coalescence is done without checking the distance in the phase space of the nucleons + float mCoalMomentum; /// coalescence momentum +}; + + +///___________________________________________________________ +FairGenerator *generateHFHadToNuclei(int input_trigger_ratio = 5, std::vector hf_hadron_pdg_list = {}, std::vector nuclei_pdg_list = {}, bool trivial_coal = false, float coal_momentum = 0.4) +{ + auto myGen = new GeneratorPythia8HFHadToNuclei(input_trigger_ratio, hf_hadron_pdg_list, nuclei_pdg_list, trivial_coal, coal_momentum); + auto seed = (gRandom->TRandom::GetSeed() % 900000000); + myGen->readString("Random:setSeed on"); + myGen->readString("Random:seed " + std::to_string(seed)); + return myGen; +} diff --git a/MC/config/PWGHF/external/generator/selectNonHfe.C b/MC/config/PWGHF/external/generator/selectNonHfe.C new file mode 100644 index 000000000..7c685c585 --- /dev/null +++ b/MC/config/PWGHF/external/generator/selectNonHfe.C @@ -0,0 +1,96 @@ +/// Select π⁰ and η within a given rapidity window for enhancement +/// pdgPartForAccCut: PDG of the particle to select (111=π⁰, 221=η) +/// minNb: minimum number of such particles per event for enhancement + +//// authors: Rashi Gupta (rashi.gupta@cern.ch) +/// authors: Ravindra Singh (ravindra.singh@cern.ch) + + +#if !defined(__CLING__) || defined(__ROOTCLING__) +#include "FairGenerator.h" +#include "FairPrimaryGenerator.h" +#include "Generators/GeneratorPythia8.h" +#include "TRandom3.h" +#include "TParticlePDG.h" +#include "TDatabasePDG.h" +#include "TMath.h" +#include +#include +#endif + +#include "Pythia8/Pythia.h" +using namespace Pythia8; + +class GeneratorPythia8Box : public o2::eventgen::GeneratorPythia8 +{ +public: + + GeneratorPythia8Box(std::vector pdgList, int nInject = 3, float ptMin = 0.1, float ptMax = 50.0, float etaMin = -0.8, float etaMax = 0.8) + : mPdgList(pdgList), nParticles(nInject), genMinPt(ptMin), genMaxPt(ptMax), genMinEta(etaMin), genMaxEta(etaMax) + { + } + + ~GeneratorPythia8Box() = default; + +Bool_t generateEvent() override +{ + bool hasElectron = false; + + while (!hasElectron) { + mPythia.event.reset(); + + for (int i{0}; i < nParticles; ++i) + { + int currentPdg = mPdgList[gRandom->Integer(mPdgList.size())]; + double mass = TDatabasePDG::Instance()->GetParticle(currentPdg)->Mass(); + + const double pt = gRandom->Uniform(genMinPt, genMaxPt); + const double eta = gRandom->Uniform(genMinEta, genMaxEta); + const double phi = gRandom->Uniform(0, TMath::TwoPi()); + + const double px{pt * std::cos(phi)}; + const double py{pt * std::sin(phi)}; + const double pz{pt * std::sinh(eta)}; + const double et{std::hypot(std::hypot(pt, pz), mass)}; + + + mPythia.event.append(currentPdg, 11, 0, 0, px, py, pz, et, mass); + } + + + if (!mPythia.next()) continue; + + + for (int i = 0; i < mPythia.event.size(); ++i) { + if (std::abs(mPythia.event[i].id()) == 11) { + + + double childPt = mPythia.event[i].pT(); + double childEta = mPythia.event[i].eta(); + + if (childPt > 0.1 && std::abs(childEta) < 1.2) { + hasElectron = true; // Mil gaya! + break; + } + } + } + + } + + return true; +} + +private: + std::vector mPdgList; + double genMinPt, genMaxPt; + double genMinEta, genMaxEta; + int nParticles; +}; + + +FairGenerator *generatePythia8Box(float ptMin = 0.1, float ptMax = 50.0) +{ + + std::vector pdgList = {111, 221}; + return new GeneratorPythia8Box(pdgList, 3, ptMin, ptMax, -0.8, 0.8); +} diff --git a/MC/config/PWGHF/hybrid/GeneratorHF_Non_Hfe.json b/MC/config/PWGHF/hybrid/GeneratorHF_Non_Hfe.json new file mode 100644 index 000000000..c729060bb --- /dev/null +++ b/MC/config/PWGHF/hybrid/GeneratorHF_Non_Hfe.json @@ -0,0 +1,40 @@ +{ + "generators": [ + { + "name": "pythia8", + "config": { + "config": "${O2DPG_MC_CONFIG_ROOT}/MC/config/common/pythia8/generator/pythia8_NonHfe.cfg" + }, + "triggers": { + "mode": "or", + "specs": [ + { + "macro": "${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGHF/trigger/selectNonHfe.C", + "function": "selectPionEtaWithinAcc(\"111;221\",-1.5,1.5,1)" + } + ] + } + }, + { + "name": "boxgen", + "config": { + "pdg": 111, + "prange[0]": 0.1, + "prange[1]": 50.0, + "eta[0]": -0.8, + "eta[1]": 0.8 + } + }, + { + "name": "boxgen", + "config": { + "pdg": 221, + "prange[0]": 0.1, + "prange[1]": 50.0, + "eta[0]": -0.8, + "eta[1]": 0.8 + } + } + ], + "fractions": [1, 1, 1] +} diff --git a/MC/config/PWGHF/ini/GeneratorHFOmegaCEmb.ini b/MC/config/PWGHF/ini/GeneratorHFOmegaCEmb.ini index df4ef98a1..1401a63ec 100644 --- a/MC/config/PWGHF/ini/GeneratorHFOmegaCEmb.ini +++ b/MC/config/PWGHF/ini/GeneratorHFOmegaCEmb.ini @@ -1,3 +1,4 @@ +#NEV_TEST> 10 [GeneratorExternal] fileName=${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGLF/pythia8/generator_pythia8_box.C funcName=generatePythia8Box(4332, 3) diff --git a/MC/config/PWGHF/ini/GeneratorHFOmegaCToXiPiEmb.ini b/MC/config/PWGHF/ini/GeneratorHFOmegaCToXiPiEmb.ini index 06695380b..a781b81be 100644 --- a/MC/config/PWGHF/ini/GeneratorHFOmegaCToXiPiEmb.ini +++ b/MC/config/PWGHF/ini/GeneratorHFOmegaCToXiPiEmb.ini @@ -1,3 +1,4 @@ +#NEV_TEST> 10 [GeneratorExternal] fileName=${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGLF/pythia8/generator_pythia8_box.C funcName=generatePythia8Box(4332, 3) diff --git a/MC/config/PWGHF/ini/GeneratorHFTrigger_BToDeuteron.ini b/MC/config/PWGHF/ini/GeneratorHFTrigger_BToDeuteron.ini new file mode 100644 index 000000000..95bf68b19 --- /dev/null +++ b/MC/config/PWGHF/ini/GeneratorHFTrigger_BToDeuteron.ini @@ -0,0 +1,8 @@ +#NEV_TEST> 10 +#O2DPG_TEST> ${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGHF/ini/tests/GeneratorHFTrigger_BToDeuteron.C +### The external generator derives from GeneratorPythia8. +[GeneratorExternal] +fileName=${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGHF/external/generator/generator_pythia8_hfhadron_to_nuclei.C +funcName=generateHFHadToNuclei(3, {521}, {1000010020}, true, 0.5) +[GeneratorPythia8] +config=${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGHF/pythia8/generator/pythia8_bminus_CRmode2.cfg diff --git a/MC/config/PWGHF/ini/GeneratorHFTrigger_Bforced.ini b/MC/config/PWGHF/ini/GeneratorHFTrigger_Bforced.ini index 108242b2a..282b34ea2 100755 --- a/MC/config/PWGHF/ini/GeneratorHFTrigger_Bforced.ini +++ b/MC/config/PWGHF/ini/GeneratorHFTrigger_Bforced.ini @@ -1,4 +1,4 @@ -### The external generator derives from GeneratorPythia8. +#NEV_TEST> 50 [GeneratorExternal] fileName=${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGHF/external/generator/generator_pythia8_gaptriggered_hf.C funcName=GeneratorPythia8GapTriggeredBeauty(3, -5, 5) diff --git a/MC/config/PWGHF/ini/GeneratorHFTrigger_LambdaBToDeuteron.ini b/MC/config/PWGHF/ini/GeneratorHFTrigger_LambdaBToDeuteron.ini new file mode 100644 index 000000000..fab061515 --- /dev/null +++ b/MC/config/PWGHF/ini/GeneratorHFTrigger_LambdaBToDeuteron.ini @@ -0,0 +1,7 @@ +#NEV_TEST> 10 +### The external generator derives from GeneratorPythia8. +[GeneratorExternal] +fileName=${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGHF/external/generator/generator_pythia8_hfhadron_to_nuclei.C +funcName=generateHFHadToNuclei(3, {5122}, {1000010020}, true, 0.5) +[GeneratorPythia8] +config=${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGHF/pythia8/generator/pythia8_lambdab_probQQtoQ.cfg diff --git a/MC/config/PWGHF/ini/GeneratorHFTrigger_LambdaBToNuclei.ini b/MC/config/PWGHF/ini/GeneratorHFTrigger_LambdaBToNuclei.ini new file mode 100644 index 000000000..5ef69c415 --- /dev/null +++ b/MC/config/PWGHF/ini/GeneratorHFTrigger_LambdaBToNuclei.ini @@ -0,0 +1,7 @@ +#NEV_TEST> 10 +[GeneratorExternal] +fileName=${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGHF/external/generator/generator_pythia8_hfhadron_to_nuclei.C +funcName=generateHFHadToNuclei(3, {5122}, {1000020030, 1000010030}, true, 0.5) + +[GeneratorPythia8] +config=${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGHF/pythia8/generator/pythia8_lambdab_with_decays_Mode2.cfg diff --git a/MC/config/PWGHF/ini/GeneratorHFTrigger_OmegaCToXiPi.ini b/MC/config/PWGHF/ini/GeneratorHFTrigger_OmegaCToXiPi.ini index bbe44e4f2..80c27b5ba 100644 --- a/MC/config/PWGHF/ini/GeneratorHFTrigger_OmegaCToXiPi.ini +++ b/MC/config/PWGHF/ini/GeneratorHFTrigger_OmegaCToXiPi.ini @@ -1,4 +1,4 @@ -### The external generator derives from GeneratorPythia8. +#NEV_TEST> 10 [GeneratorExternal] fileName=${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGHF/external/generator/generator_pythia8_gaptriggered_hf.C funcName=GeneratorPythia8GapTriggeredCharm(5,-1.5,1.5,-1.5,1.5,{4332}) diff --git a/MC/config/PWGHF/ini/GeneratorHFTrigger_XiCToXiPi.ini b/MC/config/PWGHF/ini/GeneratorHFTrigger_XiCToXiPi.ini index 5cce50121..5beb85b15 100644 --- a/MC/config/PWGHF/ini/GeneratorHFTrigger_XiCToXiPi.ini +++ b/MC/config/PWGHF/ini/GeneratorHFTrigger_XiCToXiPi.ini @@ -1,4 +1,4 @@ -### The external generator derives from GeneratorPythia8. +#NEV_TEST> 10 [GeneratorExternal] fileName=${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGHF/external/generator/generator_pythia8_gaptriggered_hf.C funcName=GeneratorPythia8GapTriggeredCharm(5,-1.5,1.5,-1.5,1.5,{4132}) diff --git a/MC/config/PWGHF/ini/GeneratorHFTrigger_Xi_Omega_C.ini b/MC/config/PWGHF/ini/GeneratorHFTrigger_Xi_Omega_C.ini index 650649e46..98035dc7a 100644 --- a/MC/config/PWGHF/ini/GeneratorHFTrigger_Xi_Omega_C.ini +++ b/MC/config/PWGHF/ini/GeneratorHFTrigger_Xi_Omega_C.ini @@ -1,4 +1,4 @@ -### The external generator derives from GeneratorPythia8. +#NEV_TEST> 10 [GeneratorExternal] fileName=${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGHF/external/generator/generator_pythia8_gaptriggered_hf.C funcName=GeneratorPythia8GapHF(5,-1.5,1.5,-1.5,1.5,{4,5}, {4132, 4332}) diff --git a/MC/config/PWGHF/ini/GeneratorHFTrigger_bbbar.ini b/MC/config/PWGHF/ini/GeneratorHFTrigger_bbbar.ini index fffbad370..c79c39e3c 100755 --- a/MC/config/PWGHF/ini/GeneratorHFTrigger_bbbar.ini +++ b/MC/config/PWGHF/ini/GeneratorHFTrigger_bbbar.ini @@ -1,4 +1,4 @@ -### The external generator derives from GeneratorPythia8. +#NEV_TEST> 20 [GeneratorExternal] fileName=${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGHF/external/generator/generator_pythia8_gaptriggered_hf.C funcName=GeneratorPythia8GapTriggeredBeauty(3, -5, 5) diff --git a/MC/config/PWGHF/ini/GeneratorHFTrigger_ccbar.ini b/MC/config/PWGHF/ini/GeneratorHFTrigger_ccbar.ini index 3becd0dfb..4dc2594a0 100755 --- a/MC/config/PWGHF/ini/GeneratorHFTrigger_ccbar.ini +++ b/MC/config/PWGHF/ini/GeneratorHFTrigger_ccbar.ini @@ -1,4 +1,4 @@ -### The external generator derives from GeneratorPythia8. +#NEV_TEST> 20 [GeneratorExternal] fileName=${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGHF/external/generator/generator_pythia8_gaptriggered_hf.C funcName=GeneratorPythia8GapTriggeredCharm(3, -5, 5) diff --git a/MC/config/PWGHF/ini/GeneratorHFXiCToXiPiEmb.ini b/MC/config/PWGHF/ini/GeneratorHFXiCToXiPiEmb.ini index 517923892..4a234ed08 100644 --- a/MC/config/PWGHF/ini/GeneratorHFXiCToXiPiEmb.ini +++ b/MC/config/PWGHF/ini/GeneratorHFXiCToXiPiEmb.ini @@ -1,3 +1,4 @@ +#NEV_TEST> 10 [GeneratorExternal] fileName=${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGLF/pythia8/generator_pythia8_box.C funcName=generatePythia8Box(4132, 3) diff --git a/MC/config/PWGHF/ini/GeneratorHF_CDeuteron_Injected.ini b/MC/config/PWGHF/ini/GeneratorHF_CDeuteron_Injected.ini new file mode 100644 index 000000000..2a574f340 --- /dev/null +++ b/MC/config/PWGHF/ini/GeneratorHF_CDeuteron_Injected.ini @@ -0,0 +1,10 @@ +#NEV_TEST> 100 +### The external generator derives from GeneratorPythia8. +[GeneratorExternal] +fileName=${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGHF/external/generator/generator_pythia8_embed_charmnuclei.C +funcName=GenerateHFEmbedCDeuteron(0.5, 10, -1., 1., 25., 0, 0.4, 0.25) + +### includePartonEvent is needed to keep the c-deuteron in the event record, even if there are no partons in the event +[GeneratorPythia8] +config=${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGHF/pythia8/generator/pythia8_cdeuteron_to_dkpi.cfg +includePartonEvent=true diff --git a/MC/config/PWGHF/ini/GeneratorHF_D2H_bbbar_B2JPsi_gap5_Mode2.ini b/MC/config/PWGHF/ini/GeneratorHF_D2H_bbbar_B2JPsi_gap5_Mode2.ini new file mode 100755 index 000000000..e2e4a5acd --- /dev/null +++ b/MC/config/PWGHF/ini/GeneratorHF_D2H_bbbar_B2JPsi_gap5_Mode2.ini @@ -0,0 +1,9 @@ +#NEV_TEST> 20 +### The external generator derives from GeneratorPythia8. +[GeneratorExternal] +fileName=${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGHF/external/generator/generator_pythia8_gaptriggered_hf.C +funcName=GeneratorPythia8GapTriggeredBeautyWithEvtGen(5, -1.5, 1.5, -1.5, 1.5, {}, {}, {}, "${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGHF/pythia8/decayer/EVTGEN_DECAY_B2JPSI.DEC") + +[GeneratorPythia8] +config=${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGHF/pythia8/generator/pythia8_Mode2_noforcedecays.cfg +includePartonEvent=false diff --git a/MC/config/PWGHF/ini/GeneratorHF_D2H_bbbar_Bforced_gap5_Mode2.ini b/MC/config/PWGHF/ini/GeneratorHF_D2H_bbbar_Bforced_gap5_Mode2.ini index de43066b4..52ddaf828 100755 --- a/MC/config/PWGHF/ini/GeneratorHF_D2H_bbbar_Bforced_gap5_Mode2.ini +++ b/MC/config/PWGHF/ini/GeneratorHF_D2H_bbbar_Bforced_gap5_Mode2.ini @@ -1,4 +1,4 @@ -### The external generator derives from GeneratorPythia8. +#NEV_TEST> 20 [GeneratorExternal] fileName=${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGHF/external/generator/generator_pythia8_gaptriggered_hf.C funcName=GeneratorPythia8GapTriggeredBeauty(5, -1.5, 1.5) diff --git a/MC/config/PWGHF/ini/GeneratorHF_D2H_bbbar_BtoDK_gap5_Mode2.ini b/MC/config/PWGHF/ini/GeneratorHF_D2H_bbbar_BtoDK_gap5_Mode2.ini new file mode 100755 index 000000000..25d30964c --- /dev/null +++ b/MC/config/PWGHF/ini/GeneratorHF_D2H_bbbar_BtoDK_gap5_Mode2.ini @@ -0,0 +1,8 @@ +#NEV_TEST> 20 +[GeneratorExternal] +fileName=${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGHF/external/generator/generator_pythia8_gaptriggered_hf.C +funcName=GeneratorPythia8GapTriggeredBeauty(5, -1.5, 1.5) + +[GeneratorPythia8] +config=${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGHF/pythia8/generator/pythia8_beautyhadronic_with_BtoDK_Mode2.cfg +includePartonEvent=true diff --git a/MC/config/PWGHF/ini/GeneratorHF_D2H_bbbar_Mode2_OmegaC.ini b/MC/config/PWGHF/ini/GeneratorHF_D2H_bbbar_Mode2_OmegaC.ini index 3868e83a1..fc956774f 100755 --- a/MC/config/PWGHF/ini/GeneratorHF_D2H_bbbar_Mode2_OmegaC.ini +++ b/MC/config/PWGHF/ini/GeneratorHF_D2H_bbbar_Mode2_OmegaC.ini @@ -1,3 +1,4 @@ +#NEV_TEST> 5 ### The external generator derives from GeneratorPythia8. [GeneratorExternal] fileName=${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGHF/external/generator/generator_pythia8_gaptriggered_hf.C @@ -5,4 +6,6 @@ funcName=GeneratorPythia8GapTriggeredBeauty(1, -1.5, 1.5, -1.5, 1.5, {4332}) [GeneratorPythia8] config=${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGHF/pythia8/generator/pythia8_charmhadronic_with_decays_Mode2.cfg +hooksFileName=${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGHF/pythia8/hooks/pythia8_userhooks_qqbar.C +hooksFuncName=pythia8_userhooks_bbbar(-1.5,1.5) includePartonEvent=true diff --git a/MC/config/PWGHF/ini/GeneratorHF_D2H_bbbar_Mode2_OmegaC_NoDecay.ini b/MC/config/PWGHF/ini/GeneratorHF_D2H_bbbar_Mode2_OmegaC_NoDecay.ini index 2661ee333..508b76dec 100644 --- a/MC/config/PWGHF/ini/GeneratorHF_D2H_bbbar_Mode2_OmegaC_NoDecay.ini +++ b/MC/config/PWGHF/ini/GeneratorHF_D2H_bbbar_Mode2_OmegaC_NoDecay.ini @@ -1,3 +1,4 @@ +#NEV_TEST> 5 ### The external generator derives from GeneratorPythia8. [GeneratorExternal] fileName=${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGHF/external/generator/generator_pythia8_gaptriggered_hf.C @@ -5,4 +6,6 @@ funcName=GeneratorPythia8GapTriggeredBeauty(1, -1.5, 1.5, -1.5, 1.5, {4332}) [GeneratorPythia8] config=${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGHF/pythia8/generator/pythia8_charmhadronic_OmegaC_NoDecay.cfg +hooksFileName=${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGHF/pythia8/hooks/pythia8_userhooks_qqbar.C +hooksFuncName=pythia8_userhooks_bbbar(-1.5,1.5) includePartonEvent=true diff --git a/MC/config/PWGHF/ini/GeneratorHF_D2H_bbbar_Mode2_OmegaC_NoDecay_pp_ref.ini b/MC/config/PWGHF/ini/GeneratorHF_D2H_bbbar_Mode2_OmegaC_NoDecay_pp_ref.ini new file mode 100644 index 000000000..5a9b792e5 --- /dev/null +++ b/MC/config/PWGHF/ini/GeneratorHF_D2H_bbbar_Mode2_OmegaC_NoDecay_pp_ref.ini @@ -0,0 +1,11 @@ +#NEV_TEST> 5 +### The external generator derives from GeneratorPythia8. +[GeneratorExternal] +fileName=${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGHF/external/generator/generator_pythia8_gaptriggered_hf.C +funcName=GeneratorPythia8GapTriggeredBeauty(1, -1.5, 1.5, -1.5, 1.5, {4332}) + +[GeneratorPythia8] +config=${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGHF/pythia8/generator/pythia8_charmhadronic_OmegaC_NoDecay_Mode2_pp_ref.cfg +hooksFileName=${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGHF/pythia8/hooks/pythia8_userhooks_qqbar.C +hooksFuncName=pythia8_userhooks_bbbar(-1.5,1.5) +includePartonEvent=true \ No newline at end of file diff --git a/MC/config/PWGHF/ini/GeneratorHF_D2H_bbbar_Mode2_XiC0_XiCplus.ini b/MC/config/PWGHF/ini/GeneratorHF_D2H_bbbar_Mode2_XiC0_XiCplus.ini index cb7dcb724..e16fbfb70 100755 --- a/MC/config/PWGHF/ini/GeneratorHF_D2H_bbbar_Mode2_XiC0_XiCplus.ini +++ b/MC/config/PWGHF/ini/GeneratorHF_D2H_bbbar_Mode2_XiC0_XiCplus.ini @@ -1,3 +1,4 @@ +#NEV_TEST> 10 ### The external generator derives from GeneratorPythia8. [GeneratorExternal] fileName=${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGHF/external/generator/generator_pythia8_gaptriggered_hf.C @@ -5,4 +6,6 @@ funcName=GeneratorPythia8GapTriggeredBeauty(1, -1.5, 1.5, -1.5, 1.5, {4132, 4232 [GeneratorPythia8] config=${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGHF/pythia8/generator/pythia8_charmhadronic_with_decays_Mode2.cfg +hooksFileName=${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGHF/pythia8/hooks/pythia8_userhooks_qqbar.C +hooksFuncName=pythia8_userhooks_bbbar(-1.5,1.5) includePartonEvent=true diff --git a/MC/config/PWGHF/ini/GeneratorHF_D2H_bbbar_Mode2_XiC_NoDecay.ini b/MC/config/PWGHF/ini/GeneratorHF_D2H_bbbar_Mode2_XiC_NoDecay.ini new file mode 100644 index 000000000..d1fd4223f --- /dev/null +++ b/MC/config/PWGHF/ini/GeneratorHF_D2H_bbbar_Mode2_XiC_NoDecay.ini @@ -0,0 +1,11 @@ +#NEV_TEST> 10 +### The external generator derives from GeneratorPythia8. +[GeneratorExternal] +fileName=${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGHF/external/generator/generator_pythia8_gaptriggered_hf.C +funcName=GeneratorPythia8GapTriggeredBeauty(1, -1.5, 1.5, -1.5, 1.5, {4132}) + +[GeneratorPythia8] +config=${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGHF/pythia8/generator/pythia8_charmhadronic_XiC_NoDecay.cfg +hooksFileName=${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGHF/pythia8/hooks/pythia8_userhooks_qqbar.C +hooksFuncName=pythia8_userhooks_bbbar(-1.5,1.5) +includePartonEvent=true diff --git a/MC/config/PWGHF/ini/GeneratorHF_D2H_bbbar_Mode2_XiC_NoDecay_pp_ref.ini b/MC/config/PWGHF/ini/GeneratorHF_D2H_bbbar_Mode2_XiC_NoDecay_pp_ref.ini new file mode 100644 index 000000000..cee03f3bc --- /dev/null +++ b/MC/config/PWGHF/ini/GeneratorHF_D2H_bbbar_Mode2_XiC_NoDecay_pp_ref.ini @@ -0,0 +1,11 @@ +#NEV_TEST> 10 +### The external generator derives from GeneratorPythia8. +[GeneratorExternal] +fileName=${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGHF/external/generator/generator_pythia8_gaptriggered_hf.C +funcName=GeneratorPythia8GapTriggeredBeauty(1, -1.5, 1.5, -1.5, 1.5, {4132}) + +[GeneratorPythia8] +config=${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGHF/pythia8/generator/pythia8_charmhadronic_XiC_NoDecay_Mode2_pp_ref.cfg +hooksFileName=${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGHF/pythia8/hooks/pythia8_userhooks_qqbar.C +hooksFuncName=pythia8_userhooks_bbbar(-1.5,1.5) +includePartonEvent=true \ No newline at end of file diff --git a/MC/config/PWGHF/ini/GeneratorHF_D2H_bbbar_Mode2_XiCplus_NoDecay.ini b/MC/config/PWGHF/ini/GeneratorHF_D2H_bbbar_Mode2_XiCplus_NoDecay.ini new file mode 100644 index 000000000..8bc123304 --- /dev/null +++ b/MC/config/PWGHF/ini/GeneratorHF_D2H_bbbar_Mode2_XiCplus_NoDecay.ini @@ -0,0 +1,11 @@ +#NEV_TEST> 10 +### The external generator derives from GeneratorPythia8. +[GeneratorExternal] +fileName=${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGHF/external/generator/generator_pythia8_gaptriggered_hf.C +funcName=GeneratorPythia8GapTriggeredBeauty(1, -1.5, 1.5, -1.5, 1.5, {4232}) + +[GeneratorPythia8] +config=${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGHF/pythia8/generator/pythia8_charmhadronic_XiCplus_NoDecay.cfg +hooksFileName=${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGHF/pythia8/hooks/pythia8_userhooks_qqbar.C +hooksFuncName=pythia8_userhooks_bbbar(-1.5,1.5) +includePartonEvent=true diff --git a/MC/config/PWGHF/ini/GeneratorHF_D2H_bbbar_Mode2_XiCplus_NoDecay_pp_ref.ini b/MC/config/PWGHF/ini/GeneratorHF_D2H_bbbar_Mode2_XiCplus_NoDecay_pp_ref.ini new file mode 100644 index 000000000..8b5935473 --- /dev/null +++ b/MC/config/PWGHF/ini/GeneratorHF_D2H_bbbar_Mode2_XiCplus_NoDecay_pp_ref.ini @@ -0,0 +1,11 @@ +#NEV_TEST> 10 +### The external generator derives from GeneratorPythia8. +[GeneratorExternal] +fileName=${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGHF/external/generator/generator_pythia8_gaptriggered_hf.C +funcName=GeneratorPythia8GapTriggeredBeauty(1, -1.5, 1.5, -1.5, 1.5, {4232}) + +[GeneratorPythia8] +config=${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGHF/pythia8/generator/pythia8_charmhadronic_XiCplus_NoDecay_Mode2_pp_ref.cfg +hooksFileName=${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGHF/pythia8/hooks/pythia8_userhooks_qqbar.C +hooksFuncName=pythia8_userhooks_bbbar(-1.5,1.5) +includePartonEvent=true \ No newline at end of file diff --git a/MC/config/PWGHF/ini/GeneratorHF_D2H_bbbar_gap5.ini b/MC/config/PWGHF/ini/GeneratorHF_D2H_bbbar_gap5.ini index 5e463ae0e..4b65f23e8 100755 --- a/MC/config/PWGHF/ini/GeneratorHF_D2H_bbbar_gap5.ini +++ b/MC/config/PWGHF/ini/GeneratorHF_D2H_bbbar_gap5.ini @@ -1,3 +1,4 @@ +#NEV_TEST> 20 ### The external generator derives from GeneratorPythia8. [GeneratorExternal] fileName=${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGHF/external/generator/generator_pythia8_gaptriggered_hf.C diff --git a/MC/config/PWGHF/ini/GeneratorHF_D2H_ccbar_Mode2_OmegaC.ini b/MC/config/PWGHF/ini/GeneratorHF_D2H_ccbar_Mode2_OmegaC.ini index 2c1b9c411..95c99d275 100755 --- a/MC/config/PWGHF/ini/GeneratorHF_D2H_ccbar_Mode2_OmegaC.ini +++ b/MC/config/PWGHF/ini/GeneratorHF_D2H_ccbar_Mode2_OmegaC.ini @@ -1,3 +1,4 @@ +#NEV_TEST> 10 ### The external generator derives from GeneratorPythia8. [GeneratorExternal] fileName=${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGHF/external/generator/generator_pythia8_gaptriggered_hf.C @@ -5,4 +6,6 @@ funcName=GeneratorPythia8GapTriggeredCharm(1, -1.5, 1.5, -1.5, 1.5, {4332}) [GeneratorPythia8] config=${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGHF/pythia8/generator/pythia8_charmhadronic_with_decays_Mode2.cfg +hooksFileName=${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGHF/pythia8/hooks/pythia8_userhooks_qqbar.C +hooksFuncName=pythia8_userhooks_ccbar(-1.5,1.5) includePartonEvent=true diff --git a/MC/config/PWGHF/ini/GeneratorHF_D2H_ccbar_Mode2_OmegaC_NoDecay.ini b/MC/config/PWGHF/ini/GeneratorHF_D2H_ccbar_Mode2_OmegaC_NoDecay.ini new file mode 100644 index 000000000..fedb78299 --- /dev/null +++ b/MC/config/PWGHF/ini/GeneratorHF_D2H_ccbar_Mode2_OmegaC_NoDecay.ini @@ -0,0 +1,11 @@ +#NEV_TEST> 10 +### The external generator derives from GeneratorPythia8. +[GeneratorExternal] +fileName=${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGHF/external/generator/generator_pythia8_gaptriggered_hf.C +funcName=GeneratorPythia8GapTriggeredCharm(1, -1.5, 1.5, -1.5, 1.5, {4332}) + +[GeneratorPythia8] +config=${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGHF/pythia8/generator/pythia8_charmhadronic_OmegaC_NoDecay.cfg +hooksFileName=${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGHF/pythia8/hooks/pythia8_userhooks_qqbar.C +hooksFuncName=pythia8_userhooks_ccbar(-1.5,1.5) +includePartonEvent=true diff --git a/MC/config/PWGHF/ini/GeneratorHF_D2H_ccbar_Mode2_OmegaC_NoDecay_pp_ref.ini b/MC/config/PWGHF/ini/GeneratorHF_D2H_ccbar_Mode2_OmegaC_NoDecay_pp_ref.ini new file mode 100644 index 000000000..68348cbbd --- /dev/null +++ b/MC/config/PWGHF/ini/GeneratorHF_D2H_ccbar_Mode2_OmegaC_NoDecay_pp_ref.ini @@ -0,0 +1,11 @@ +#NEV_TEST> 10 +### The external generator derives from GeneratorPythia8. +[GeneratorExternal] +fileName=${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGHF/external/generator/generator_pythia8_gaptriggered_hf.C +funcName=GeneratorPythia8GapTriggeredCharm(1, -1.5, 1.5, -1.5, 1.5, {4332}) + +[GeneratorPythia8] +config=${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGHF/pythia8/generator/pythia8_charmhadronic_OmegaC_NoDecay_Mode2_pp_ref.cfg +hooksFileName=${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGHF/pythia8/hooks/pythia8_userhooks_qqbar.C +hooksFuncName=pythia8_userhooks_ccbar(-1.5,1.5) +includePartonEvent=true \ No newline at end of file diff --git a/MC/config/PWGHF/ini/GeneratorHF_D2H_ccbar_Mode2_XiC0_XiCplus.ini b/MC/config/PWGHF/ini/GeneratorHF_D2H_ccbar_Mode2_XiC0_XiCplus.ini index 6505ea24b..5e301a4cf 100755 --- a/MC/config/PWGHF/ini/GeneratorHF_D2H_ccbar_Mode2_XiC0_XiCplus.ini +++ b/MC/config/PWGHF/ini/GeneratorHF_D2H_ccbar_Mode2_XiC0_XiCplus.ini @@ -1,3 +1,4 @@ +#NEV_TEST> 10 ### The external generator derives from GeneratorPythia8. [GeneratorExternal] fileName=${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGHF/external/generator/generator_pythia8_gaptriggered_hf.C @@ -5,4 +6,6 @@ funcName=GeneratorPythia8GapTriggeredCharm(1, -1.5, 1.5, -1.5, 1.5, {4132, 4232} [GeneratorPythia8] config=${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGHF/pythia8/generator/pythia8_charmhadronic_with_decays_Mode2.cfg +hooksFileName=${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGHF/pythia8/hooks/pythia8_userhooks_qqbar.C +hooksFuncName=pythia8_userhooks_ccbar(-1.5,1.5) includePartonEvent=true diff --git a/MC/config/PWGHF/ini/GeneratorHF_D2H_ccbar_Mode2_XiC_NoDecay.ini b/MC/config/PWGHF/ini/GeneratorHF_D2H_ccbar_Mode2_XiC_NoDecay.ini new file mode 100644 index 000000000..2b23edbf2 --- /dev/null +++ b/MC/config/PWGHF/ini/GeneratorHF_D2H_ccbar_Mode2_XiC_NoDecay.ini @@ -0,0 +1,11 @@ +#NEV_TEST> 10 +### The external generator derives from GeneratorPythia8. +[GeneratorExternal] +fileName=${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGHF/external/generator/generator_pythia8_gaptriggered_hf.C +funcName=GeneratorPythia8GapTriggeredCharm(1, -1.5, 1.5, -1.5, 1.5, {4132}) + +[GeneratorPythia8] +config=${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGHF/pythia8/generator/pythia8_charmhadronic_XiC_NoDecay.cfg +hooksFileName=${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGHF/pythia8/hooks/pythia8_userhooks_qqbar.C +hooksFuncName=pythia8_userhooks_ccbar(-1.5,1.5) +includePartonEvent=true diff --git a/MC/config/PWGHF/ini/GeneratorHF_D2H_ccbar_Mode2_XiC_NoDecay_pp_ref.ini b/MC/config/PWGHF/ini/GeneratorHF_D2H_ccbar_Mode2_XiC_NoDecay_pp_ref.ini new file mode 100644 index 000000000..650eb8a5f --- /dev/null +++ b/MC/config/PWGHF/ini/GeneratorHF_D2H_ccbar_Mode2_XiC_NoDecay_pp_ref.ini @@ -0,0 +1,11 @@ +#NEV_TEST> 10 +### The external generator derives from GeneratorPythia8. +[GeneratorExternal] +fileName=${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGHF/external/generator/generator_pythia8_gaptriggered_hf.C +funcName=GeneratorPythia8GapTriggeredCharm(1, -1.5, 1.5, -1.5, 1.5, {4132}) + +[GeneratorPythia8] +config=${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGHF/pythia8/generator/pythia8_charmhadronic_XiC_NoDecay_Mode2_pp_ref.cfg +hooksFileName=${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGHF/pythia8/hooks/pythia8_userhooks_qqbar.C +hooksFuncName=pythia8_userhooks_ccbar(-1.5,1.5) +includePartonEvent=true \ No newline at end of file diff --git a/MC/config/PWGHF/ini/GeneratorHF_D2H_ccbar_Mode2_XiCplus_NoDecay.ini b/MC/config/PWGHF/ini/GeneratorHF_D2H_ccbar_Mode2_XiCplus_NoDecay.ini new file mode 100644 index 000000000..c308bfeda --- /dev/null +++ b/MC/config/PWGHF/ini/GeneratorHF_D2H_ccbar_Mode2_XiCplus_NoDecay.ini @@ -0,0 +1,11 @@ +#NEV_TEST> 10 +### The external generator derives from GeneratorPythia8. +[GeneratorExternal] +fileName=${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGHF/external/generator/generator_pythia8_gaptriggered_hf.C +funcName=GeneratorPythia8GapTriggeredCharm(1, -1.5, 1.5, -1.5, 1.5, {4232}) + +[GeneratorPythia8] +config=${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGHF/pythia8/generator/pythia8_charmhadronic_XiCplus_NoDecay.cfg +hooksFileName=${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGHF/pythia8/hooks/pythia8_userhooks_qqbar.C +hooksFuncName=pythia8_userhooks_ccbar(-1.5,1.5) +includePartonEvent=true diff --git a/MC/config/PWGHF/ini/GeneratorHF_D2H_ccbar_Mode2_XiCplus_NoDecay_pp_ref.ini b/MC/config/PWGHF/ini/GeneratorHF_D2H_ccbar_Mode2_XiCplus_NoDecay_pp_ref.ini new file mode 100644 index 000000000..849c5f4fa --- /dev/null +++ b/MC/config/PWGHF/ini/GeneratorHF_D2H_ccbar_Mode2_XiCplus_NoDecay_pp_ref.ini @@ -0,0 +1,11 @@ +#NEV_TEST> 10 +### The external generator derives from GeneratorPythia8. +[GeneratorExternal] +fileName=${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGHF/external/generator/generator_pythia8_gaptriggered_hf.C +funcName=GeneratorPythia8GapTriggeredCharm(1, -1.5, 1.5, -1.5, 1.5, {4232}) + +[GeneratorPythia8] +config=${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGHF/pythia8/generator/pythia8_charmhadronic_XiCplus_NoDecay_Mode2_pp_ref.cfg +hooksFileName=${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGHF/pythia8/hooks/pythia8_userhooks_qqbar.C +hooksFuncName=pythia8_userhooks_ccbar(-1.5,1.5) +includePartonEvent=true \ No newline at end of file diff --git a/MC/config/PWGHF/ini/GeneratorHF_D2H_ccbar_and_bbbar_Mode2_ptHardBins.ini b/MC/config/PWGHF/ini/GeneratorHF_D2H_ccbar_and_bbbar_Mode2_ptHardBins.ini index 4f67c5b2e..ed7202eb2 100644 --- a/MC/config/PWGHF/ini/GeneratorHF_D2H_ccbar_and_bbbar_Mode2_ptHardBins.ini +++ b/MC/config/PWGHF/ini/GeneratorHF_D2H_ccbar_and_bbbar_Mode2_ptHardBins.ini @@ -1,3 +1,4 @@ +#NEV_TEST> 20 ### The external generator derives from GeneratorPythia8. [GeneratorExternal] fileName=${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGHF/external/generator/generator_pythia8_gaptriggered_hf.C diff --git a/MC/config/PWGHF/ini/GeneratorHF_D2H_ccbar_and_bbbar_PbPb.ini b/MC/config/PWGHF/ini/GeneratorHF_D2H_ccbar_and_bbbar_PbPb.ini index 5a7e99b3c..03b15ce2c 100644 --- a/MC/config/PWGHF/ini/GeneratorHF_D2H_ccbar_and_bbbar_PbPb.ini +++ b/MC/config/PWGHF/ini/GeneratorHF_D2H_ccbar_and_bbbar_PbPb.ini @@ -1,3 +1,4 @@ +#NEV_TEST> 10 ### The external generator derives from GeneratorPythia8. [GeneratorExternal] fileName=${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGHF/external/generator/generator_pythia8_embed_hf.C diff --git a/MC/config/PWGHF/ini/GeneratorHF_D2H_ccbar_and_bbbar_PbPb_corrBkg.ini b/MC/config/PWGHF/ini/GeneratorHF_D2H_ccbar_and_bbbar_PbPb_corrBkg.ini new file mode 100644 index 000000000..57715e41c --- /dev/null +++ b/MC/config/PWGHF/ini/GeneratorHF_D2H_ccbar_and_bbbar_PbPb_corrBkg.ini @@ -0,0 +1,9 @@ +#NEV_TEST> 10 +### The external generator derives from GeneratorPythia8. +[GeneratorExternal] +fileName=${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGHF/external/generator/generator_pythia8_embed_hf.C +funcName=GeneratorPythia8EmbedHFCharmAndBeauty() + +[GeneratorPythia8] +config=${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGHF/pythia8/generator/pythia8_charmhadronic_with_decays_Mode2_hardQCD_5TeV_CorrBkg.cfg +includePartonEvent=true diff --git a/MC/config/PWGHF/ini/GeneratorHF_D2H_ccbar_and_bbbar_PbPb_ptHardBins.ini b/MC/config/PWGHF/ini/GeneratorHF_D2H_ccbar_and_bbbar_PbPb_ptHardBins.ini index dc2cb28a0..2273c8205 100644 --- a/MC/config/PWGHF/ini/GeneratorHF_D2H_ccbar_and_bbbar_PbPb_ptHardBins.ini +++ b/MC/config/PWGHF/ini/GeneratorHF_D2H_ccbar_and_bbbar_PbPb_ptHardBins.ini @@ -1,3 +1,4 @@ +#NEV_TEST> 10 ### The external generator derives from GeneratorPythia8. [GeneratorExternal] fileName=${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGHF/external/generator/generator_pythia8_embed_hf.C diff --git a/MC/config/PWGHF/ini/GeneratorHF_D2H_ccbar_and_bbbar_PbPb_replaced.ini b/MC/config/PWGHF/ini/GeneratorHF_D2H_ccbar_and_bbbar_PbPb_replaced.ini new file mode 100644 index 000000000..e0cd149eb --- /dev/null +++ b/MC/config/PWGHF/ini/GeneratorHF_D2H_ccbar_and_bbbar_PbPb_replaced.ini @@ -0,0 +1,9 @@ +#NEV_TEST> 10 +### The external generator derives from GeneratorPythia8. +[GeneratorExternal] +fileName=${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGHF/external/generator/generator_pythia8_embed_hf.C +funcName=GeneratorPythia8EmbedHFCharmAndBeauty(false, -1.5, 1.5, -1.5, 1.5, std::vector{}, std::vector{}, std::vector>{{423,4132},{423,4232},{4212,4332}}, std::vector{0.5,0.5,1}) + +[GeneratorPythia8] +config=${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGHF/pythia8/generator/pythia8_charmhadronic_decays_Mode2_hardQCD_5TeV_XicOmegaC.cfg +includePartonEvent=true \ No newline at end of file diff --git a/MC/config/PWGHF/ini/GeneratorHF_D2H_ccbar_and_bbbar_gap2_QCDCR_OO.ini b/MC/config/PWGHF/ini/GeneratorHF_D2H_ccbar_and_bbbar_gap2_QCDCR_OO.ini new file mode 100755 index 000000000..854f810a1 --- /dev/null +++ b/MC/config/PWGHF/ini/GeneratorHF_D2H_ccbar_and_bbbar_gap2_QCDCR_OO.ini @@ -0,0 +1,9 @@ +#NEV_TEST> 16 +### The external generator derives from GeneratorPythia8. +[GeneratorExternal] +fileName=${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGHF/external/generator/generator_pythia8_gaptriggered_hf.C +funcName=GeneratorPythia8GapTriggeredCharmAndBeauty(2, -1.5, 1.5) + +[GeneratorPythia8] +config=${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGHF/pythia8/generator/pythia8_charmhadronic_with_decays_QCDCR_OO.cfg +includePartonEvent=true diff --git a/MC/config/PWGHF/ini/GeneratorHF_D2H_ccbar_and_bbbar_gap2_QCDCR_pO.ini b/MC/config/PWGHF/ini/GeneratorHF_D2H_ccbar_and_bbbar_gap2_QCDCR_pO.ini new file mode 100755 index 000000000..838a4a4f4 --- /dev/null +++ b/MC/config/PWGHF/ini/GeneratorHF_D2H_ccbar_and_bbbar_gap2_QCDCR_pO.ini @@ -0,0 +1,8 @@ +#NEV_TEST> 12 +[GeneratorExternal] +fileName=${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGHF/external/generator/generator_pythia8_gaptriggered_hf.C +funcName=GeneratorPythia8GapTriggeredCharmAndBeauty(2, -1.5, 1.5) + +[GeneratorPythia8] +config=${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGHF/pythia8/generator/pythia8_charmhadronic_with_decays_QCDCR_pO.cfg +includePartonEvent=true diff --git a/MC/config/PWGHF/ini/GeneratorHF_D2H_ccbar_and_bbbar_gap3.ini b/MC/config/PWGHF/ini/GeneratorHF_D2H_ccbar_and_bbbar_gap3.ini index 60a6ff4c5..f7fefbb20 100755 --- a/MC/config/PWGHF/ini/GeneratorHF_D2H_ccbar_and_bbbar_gap3.ini +++ b/MC/config/PWGHF/ini/GeneratorHF_D2H_ccbar_and_bbbar_gap3.ini @@ -1,3 +1,4 @@ +#NEV_TEST> 24 ### The external generator derives from GeneratorPythia8. [GeneratorExternal] fileName=${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGHF/external/generator/generator_pythia8_gaptriggered_hf.C diff --git a/MC/config/PWGHF/ini/GeneratorHF_D2H_ccbar_and_bbbar_gap3_Mode2.ini b/MC/config/PWGHF/ini/GeneratorHF_D2H_ccbar_and_bbbar_gap3_Mode2.ini index aab7d4b5f..8b0d2fb2f 100755 --- a/MC/config/PWGHF/ini/GeneratorHF_D2H_ccbar_and_bbbar_gap3_Mode2.ini +++ b/MC/config/PWGHF/ini/GeneratorHF_D2H_ccbar_and_bbbar_gap3_Mode2.ini @@ -1,3 +1,4 @@ +#NEV_TEST> 12 ### The external generator derives from GeneratorPythia8. [GeneratorExternal] fileName=${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGHF/external/generator/generator_pythia8_gaptriggered_hf.C diff --git a/MC/config/PWGHF/ini/GeneratorHF_D2H_ccbar_and_bbbar_gap3_Mode2_XiC.ini b/MC/config/PWGHF/ini/GeneratorHF_D2H_ccbar_and_bbbar_gap3_Mode2_XiC.ini index 0abfe5c4f..bfa5df7b9 100755 --- a/MC/config/PWGHF/ini/GeneratorHF_D2H_ccbar_and_bbbar_gap3_Mode2_XiC.ini +++ b/MC/config/PWGHF/ini/GeneratorHF_D2H_ccbar_and_bbbar_gap3_Mode2_XiC.ini @@ -1,3 +1,4 @@ +#NEV_TEST> 12 ### The external generator derives from GeneratorPythia8. [GeneratorExternal] fileName=${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGHF/external/generator/generator_pythia8_gaptriggered_hf.C diff --git a/MC/config/PWGHF/ini/GeneratorHF_D2H_ccbar_and_bbbar_gap5.ini b/MC/config/PWGHF/ini/GeneratorHF_D2H_ccbar_and_bbbar_gap5.ini index de97f7740..429f59170 100755 --- a/MC/config/PWGHF/ini/GeneratorHF_D2H_ccbar_and_bbbar_gap5.ini +++ b/MC/config/PWGHF/ini/GeneratorHF_D2H_ccbar_and_bbbar_gap5.ini @@ -1,3 +1,4 @@ +#NEV_TEST> 20 ### The external generator derives from GeneratorPythia8. [GeneratorExternal] fileName=${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGHF/external/generator/generator_pythia8_gaptriggered_hf.C diff --git a/MC/config/PWGHF/ini/GeneratorHF_D2H_ccbar_and_bbbar_gap5_DReso.ini b/MC/config/PWGHF/ini/GeneratorHF_D2H_ccbar_and_bbbar_gap5_DReso.ini index 84138c596..713b79c1c 100644 --- a/MC/config/PWGHF/ini/GeneratorHF_D2H_ccbar_and_bbbar_gap5_DReso.ini +++ b/MC/config/PWGHF/ini/GeneratorHF_D2H_ccbar_and_bbbar_gap5_DReso.ini @@ -1,3 +1,4 @@ +#NEV_TEST> 20 ### The external generator derives from GeneratorPythia8. [GeneratorExternal] fileName=${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGHF/external/generator/generator_pythia8_gaptriggered_hf.C diff --git a/MC/config/PWGHF/ini/GeneratorHF_D2H_ccbar_and_bbbar_gap5_DResoTrigger.ini b/MC/config/PWGHF/ini/GeneratorHF_D2H_ccbar_and_bbbar_gap5_DResoTrigger.ini new file mode 100644 index 000000000..4ec024367 --- /dev/null +++ b/MC/config/PWGHF/ini/GeneratorHF_D2H_ccbar_and_bbbar_gap5_DResoTrigger.ini @@ -0,0 +1,10 @@ +#NEV_TEST> 40 +### The external generator derives from GeneratorPythia8. +[GeneratorExternal] +fileName=${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGHF/external/generator/generator_pythia8_gaptriggered_hf.C +funcName=GeneratorPythia8GapTriggeredCharmAndBeauty(5, -1.5, 1.5, -1.5, 1.5, {10433, 435}, {{10433, 30433}, {10433, 437}, {435, 4325}, {435, 4326}, {425, 4315}, {425, 4316}}, {0.1, 0.1, 0.1, 0.1, 0.5, 0.5}) + +[GeneratorPythia8] +config=${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGHF/pythia8/generator/pythia8_charmhadronic_with_decays_DResoTrigger.cfg +includePartonEvent=false +### not needed for jet studies, hence no need to keep parton event diff --git a/MC/config/PWGHF/ini/GeneratorHF_D2H_ccbar_and_bbbar_gap5_LcResoTrigger.ini b/MC/config/PWGHF/ini/GeneratorHF_D2H_ccbar_and_bbbar_gap5_LcResoTrigger.ini new file mode 100644 index 000000000..cbd913e01 --- /dev/null +++ b/MC/config/PWGHF/ini/GeneratorHF_D2H_ccbar_and_bbbar_gap5_LcResoTrigger.ini @@ -0,0 +1,10 @@ +#NEV_TEST> 20 +### The external generator derives from GeneratorPythia8. +[GeneratorExternal] +fileName=${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGHF/external/generator/generator_pythia8_gaptriggered_hf.C +funcName=GeneratorPythia8GapTriggeredCharmAndBeauty(5, -1.5, 1.5, -1.5, 1.5, {24124, 24126, 4125, 9422111}, {{4122, 24124}, {4122, 24126}, {4122, 4125}, {4122, 9422111}}, {0.1, 0.1, 0.1, 0.1}) + +[GeneratorPythia8] +config=${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGHF/pythia8/generator/pythia8_charmhadronic_with_decays_LcResoTrigger.cfg +includePartonEvent=false +### not needed for jet studies, hence no need to keep parton event diff --git a/MC/config/PWGHF/ini/GeneratorHF_D2H_ccbar_and_bbbar_gap5_Mode2.ini b/MC/config/PWGHF/ini/GeneratorHF_D2H_ccbar_and_bbbar_gap5_Mode2.ini index f6ba8d251..2f4a41721 100755 --- a/MC/config/PWGHF/ini/GeneratorHF_D2H_ccbar_and_bbbar_gap5_Mode2.ini +++ b/MC/config/PWGHF/ini/GeneratorHF_D2H_ccbar_and_bbbar_gap5_Mode2.ini @@ -1,3 +1,4 @@ +#NEV_TEST> 20 ### The external generator derives from GeneratorPythia8. [GeneratorExternal] fileName=${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGHF/external/generator/generator_pythia8_gaptriggered_hf.C diff --git a/MC/config/PWGHF/ini/GeneratorHF_D2H_ccbar_and_bbbar_gap5_Mode2_CharmBaryons.ini b/MC/config/PWGHF/ini/GeneratorHF_D2H_ccbar_and_bbbar_gap5_Mode2_CharmBaryons.ini index 8f5bfbca4..20fd5ab60 100755 --- a/MC/config/PWGHF/ini/GeneratorHF_D2H_ccbar_and_bbbar_gap5_Mode2_CharmBaryons.ini +++ b/MC/config/PWGHF/ini/GeneratorHF_D2H_ccbar_and_bbbar_gap5_Mode2_CharmBaryons.ini @@ -1,3 +1,4 @@ +#NEV_TEST> 10 ### The external generator derives from GeneratorPythia8. [GeneratorExternal] fileName=${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGHF/external/generator/generator_pythia8_gaptriggered_hf.C diff --git a/MC/config/PWGHF/ini/GeneratorHF_D2H_ccbar_and_bbbar_gap5_Mode2_CharmBaryons_pp_ref.ini b/MC/config/PWGHF/ini/GeneratorHF_D2H_ccbar_and_bbbar_gap5_Mode2_CharmBaryons_pp_ref.ini index 9c6f81e7d..569fee4c5 100644 --- a/MC/config/PWGHF/ini/GeneratorHF_D2H_ccbar_and_bbbar_gap5_Mode2_CharmBaryons_pp_ref.ini +++ b/MC/config/PWGHF/ini/GeneratorHF_D2H_ccbar_and_bbbar_gap5_Mode2_CharmBaryons_pp_ref.ini @@ -1,3 +1,4 @@ +#NEV_TEST> 10 ### The external generator derives from GeneratorPythia8. [GeneratorExternal] fileName=${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGHF/external/generator/generator_pythia8_gaptriggered_hf.C diff --git a/MC/config/PWGHF/ini/GeneratorHF_D2H_ccbar_and_bbbar_gap5_Mode2_XiC.ini b/MC/config/PWGHF/ini/GeneratorHF_D2H_ccbar_and_bbbar_gap5_Mode2_XiC.ini index 5869198dc..ad1aa5422 100755 --- a/MC/config/PWGHF/ini/GeneratorHF_D2H_ccbar_and_bbbar_gap5_Mode2_XiC.ini +++ b/MC/config/PWGHF/ini/GeneratorHF_D2H_ccbar_and_bbbar_gap5_Mode2_XiC.ini @@ -1,3 +1,4 @@ +#NEV_TEST> 10 ### The external generator derives from GeneratorPythia8. [GeneratorExternal] fileName=${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGHF/external/generator/generator_pythia8_gaptriggered_hf.C diff --git a/MC/config/PWGHF/ini/GeneratorHF_D2H_ccbar_and_bbbar_gap5_Mode2_XiC_OmegaC.ini b/MC/config/PWGHF/ini/GeneratorHF_D2H_ccbar_and_bbbar_gap5_Mode2_XiC_OmegaC.ini index bae677ab5..4d2e31712 100755 --- a/MC/config/PWGHF/ini/GeneratorHF_D2H_ccbar_and_bbbar_gap5_Mode2_XiC_OmegaC.ini +++ b/MC/config/PWGHF/ini/GeneratorHF_D2H_ccbar_and_bbbar_gap5_Mode2_XiC_OmegaC.ini @@ -1,3 +1,4 @@ +#NEV_TEST> 10 ### The external generator derives from GeneratorPythia8. [GeneratorExternal] fileName=${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGHF/external/generator/generator_pythia8_gaptriggered_hf.C diff --git a/MC/config/PWGHF/ini/GeneratorHF_D2H_ccbar_and_bbbar_gap5_Mode2_corrBkg.ini b/MC/config/PWGHF/ini/GeneratorHF_D2H_ccbar_and_bbbar_gap5_Mode2_corrBkg.ini new file mode 100644 index 000000000..840f0d14b --- /dev/null +++ b/MC/config/PWGHF/ini/GeneratorHF_D2H_ccbar_and_bbbar_gap5_Mode2_corrBkg.ini @@ -0,0 +1,9 @@ +#NEV_TEST> 20 +### The external generator derives from GeneratorPythia8. +[GeneratorExternal] +fileName=${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGHF/external/generator/generator_pythia8_gaptriggered_hf.C +funcName=GeneratorPythia8GapTriggeredCharmAndBeauty(5, -1.5, 1.5) + +[GeneratorPythia8] +config=${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGHF/pythia8/generator/pythia8_charmhadronic_with_decays_Mode2_CorrBkg.cfg +includePartonEvent=true diff --git a/MC/config/PWGHF/ini/GeneratorHF_D2H_ccbar_and_bbbar_gap5_Mode2_corrBkgSigmaC.ini b/MC/config/PWGHF/ini/GeneratorHF_D2H_ccbar_and_bbbar_gap5_Mode2_corrBkgSigmaC.ini new file mode 100644 index 000000000..d484e6d0f --- /dev/null +++ b/MC/config/PWGHF/ini/GeneratorHF_D2H_ccbar_and_bbbar_gap5_Mode2_corrBkgSigmaC.ini @@ -0,0 +1,10 @@ +#NEV_TEST> 100 +### The external generator derives from GeneratorPythia8. +[GeneratorExternal] +fileName=${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGHF/external/generator/generator_pythia8_gaptriggered_hf.C +funcName=GeneratorPythia8GapTriggeredCharmAndBeauty(5, -1.5, 1.5, -1.5, 1.5, {413}, {{413, 14122}, {413, 4124}}, {0.5, 0.5}) + +[GeneratorPythia8] +config=${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGHF/pythia8/generator/pythia8_charmhadronic_with_decays_Mode2_CorrBkgSigmaC.cfg +includePartonEvent=false +### not needed for jet studies, hence no need to keep parton event \ No newline at end of file diff --git a/MC/config/PWGHF/ini/GeneratorHF_D2H_ccbar_and_bbbar_gap5_Mode2_pp_ref.ini b/MC/config/PWGHF/ini/GeneratorHF_D2H_ccbar_and_bbbar_gap5_Mode2_pp_ref.ini new file mode 100644 index 000000000..a25d587cc --- /dev/null +++ b/MC/config/PWGHF/ini/GeneratorHF_D2H_ccbar_and_bbbar_gap5_Mode2_pp_ref.ini @@ -0,0 +1,9 @@ +#NEV_TEST> 20 +### The external generator derives from GeneratorPythia8. +[GeneratorExternal] +fileName=${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGHF/external/generator/generator_pythia8_gaptriggered_hf.C +funcName=GeneratorPythia8GapTriggeredCharmAndBeauty(5, -1.5, 1.5) + +[GeneratorPythia8] +config=${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGHF/pythia8/generator/pythia8_charmhadronic_with_decays_Mode2_pp_ref.cfg +includePartonEvent=true diff --git a/MC/config/PWGHF/ini/GeneratorHF_D2H_ccbar_and_bbbar_gap8.ini b/MC/config/PWGHF/ini/GeneratorHF_D2H_ccbar_and_bbbar_gap8.ini index c2731d152..47b370b8c 100755 --- a/MC/config/PWGHF/ini/GeneratorHF_D2H_ccbar_and_bbbar_gap8.ini +++ b/MC/config/PWGHF/ini/GeneratorHF_D2H_ccbar_and_bbbar_gap8.ini @@ -1,3 +1,4 @@ +#NEV_TEST> 32 ### The external generator derives from GeneratorPythia8. [GeneratorExternal] fileName=${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGHF/external/generator/generator_pythia8_gaptriggered_hf.C diff --git a/MC/config/PWGHF/ini/GeneratorHF_D2H_ccbar_and_bbbar_gap8_Mode2_XiC.ini b/MC/config/PWGHF/ini/GeneratorHF_D2H_ccbar_and_bbbar_gap8_Mode2_XiC.ini index d4d5ca1c3..97795a224 100755 --- a/MC/config/PWGHF/ini/GeneratorHF_D2H_ccbar_and_bbbar_gap8_Mode2_XiC.ini +++ b/MC/config/PWGHF/ini/GeneratorHF_D2H_ccbar_and_bbbar_gap8_Mode2_XiC.ini @@ -1,3 +1,4 @@ +#NEV_TEST> 16 ### The external generator derives from GeneratorPythia8. [GeneratorExternal] fileName=${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGHF/external/generator/generator_pythia8_gaptriggered_hf.C diff --git a/MC/config/PWGHF/ini/GeneratorHF_D2H_ccbar_gap5.ini b/MC/config/PWGHF/ini/GeneratorHF_D2H_ccbar_gap5.ini index cfcfb073e..8c598e7e1 100755 --- a/MC/config/PWGHF/ini/GeneratorHF_D2H_ccbar_gap5.ini +++ b/MC/config/PWGHF/ini/GeneratorHF_D2H_ccbar_gap5.ini @@ -1,3 +1,4 @@ +#NEV_TEST> 20 ### The external generator derives from GeneratorPythia8. [GeneratorExternal] fileName=${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGHF/external/generator/generator_pythia8_gaptriggered_hf.C diff --git a/MC/config/PWGHF/ini/GeneratorHF_D2H_ccbar_Mode2_OmegaC_to_Omega.ini b/MC/config/PWGHF/ini/GeneratorHF_HFe_ccbar_and_bbar_gap5_Mode2.ini similarity index 70% rename from MC/config/PWGHF/ini/GeneratorHF_D2H_ccbar_Mode2_OmegaC_to_Omega.ini rename to MC/config/PWGHF/ini/GeneratorHF_HFe_ccbar_and_bbar_gap5_Mode2.ini index 7bdc17baf..564cb14f7 100644 --- a/MC/config/PWGHF/ini/GeneratorHF_D2H_ccbar_Mode2_OmegaC_to_Omega.ini +++ b/MC/config/PWGHF/ini/GeneratorHF_HFe_ccbar_and_bbar_gap5_Mode2.ini @@ -1,8 +1,9 @@ +#NEV_TEST> 20 ### The external generator derives from GeneratorPythia8. [GeneratorExternal] fileName=${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGHF/external/generator/generator_pythia8_gaptriggered_hf.C -funcName=GeneratorPythia8GapTriggeredCharm(1, -1.5, 1.5, -1.5, 1.5, {4332}) +funcName=GeneratorPythia8GapTriggeredCharmAndBeauty(5, -1.5, 1.5, -1.0, 1.0, {11}) [GeneratorPythia8] -config=${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGHF/pythia8/generator/pythia8_charmhadronic_Omegac_to_Omega.cfg +config=${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGHF/pythia8/generator/pythia8_HFe_Mode2.cfg includePartonEvent=true diff --git a/MC/config/PWGHF/ini/GeneratorHF_HFe_ccbar_and_bbar_gap5_Mode2_pp_ref.ini b/MC/config/PWGHF/ini/GeneratorHF_HFe_ccbar_and_bbar_gap5_Mode2_pp_ref.ini new file mode 100644 index 000000000..202b484b5 --- /dev/null +++ b/MC/config/PWGHF/ini/GeneratorHF_HFe_ccbar_and_bbar_gap5_Mode2_pp_ref.ini @@ -0,0 +1,9 @@ +#NEV_TEST> 20 +### The external generator derives from GeneratorPythia8. +[GeneratorExternal] +fileName=${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGHF/external/generator/generator_pythia8_gaptriggered_hf.C +funcName=GeneratorPythia8GapTriggeredCharmAndBeauty(5, -1.5, 1.5, -1.0, 1.0, {11}) + +[GeneratorPythia8] +config=${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGHF/pythia8/generator/pythia8_HFe_Mode2_pp_ref.cfg +includePartonEvent=true diff --git a/MC/config/PWGHF/ini/GeneratorHF_Non_Hfe.ini b/MC/config/PWGHF/ini/GeneratorHF_Non_Hfe.ini new file mode 100644 index 000000000..f5455e34d --- /dev/null +++ b/MC/config/PWGHF/ini/GeneratorHF_Non_Hfe.ini @@ -0,0 +1,7 @@ +#### This configuration uses the Box generator to trigger π⁰/η production within the specified rapidity window +[GeneratorExternal] +fileName=${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGHF/external/generator/selectNonHfe.C +funcName = generatePythia8Box(0.1, 50.0) +[GeneratorPythia8] +config=${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGHF/pythia8/generator/pythia8_NonHfe.cfg +includePartonEvent=true diff --git a/MC/config/PWGHF/ini/GeneratorHF_bbbar_fwd_gap4_natural_inel_Mode2.ini b/MC/config/PWGHF/ini/GeneratorHF_bbbar_fwd_gap4_natural_inel_Mode2.ini new file mode 100644 index 000000000..a2b849bc3 --- /dev/null +++ b/MC/config/PWGHF/ini/GeneratorHF_bbbar_fwd_gap4_natural_inel_Mode2.ini @@ -0,0 +1,9 @@ +#NEV_TEST> 20 +### The external generator derives from GeneratorPythia8. +[GeneratorExternal] +fileName=${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGHF/external/generator/generator_pythia8_gaptriggered_hf.C +funcName=GeneratorPythia8GapTriggeredBeauty(4, -4.3, -2.2) +[GeneratorPythia8] +config=${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGHF/pythia8/generator/pythia8_inel_Mode2.cfg +includePartonEvent=true + \ No newline at end of file diff --git a/MC/config/PWGHF/ini/GeneratorHF_bbbar_fwd_gap4_natural_inel_Mode2_muTrig.ini b/MC/config/PWGHF/ini/GeneratorHF_bbbar_fwd_gap4_natural_inel_Mode2_muTrig.ini new file mode 100644 index 000000000..b126fceed --- /dev/null +++ b/MC/config/PWGHF/ini/GeneratorHF_bbbar_fwd_gap4_natural_inel_Mode2_muTrig.ini @@ -0,0 +1,8 @@ +#NEV_TEST> 20 +### The external generator derives from GeneratorPythia8. +[GeneratorExternal] +fileName=${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGHF/external/generator/generator_pythia8_gaptriggered_hf.C +funcName=GeneratorPythia8GapTriggeredBeauty(4, -5, -1.5, -4.3, -2.2, {13}) +[GeneratorPythia8] +config=${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGHF/pythia8/generator/pythia8_inel_Mode2.cfg +includePartonEvent=true \ No newline at end of file diff --git a/MC/config/PWGHF/ini/GeneratorHF_mu_bbbar_gap3_Mode2_accSmall.ini b/MC/config/PWGHF/ini/GeneratorHF_mu_bbbar_gap3_Mode2_accSmall.ini new file mode 100644 index 000000000..73dd727e7 --- /dev/null +++ b/MC/config/PWGHF/ini/GeneratorHF_mu_bbbar_gap3_Mode2_accSmall.ini @@ -0,0 +1,8 @@ +#NEV_TEST> 24 +### The external generator derives from GeneratorPythia8. +[GeneratorExternal] +fileName=${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGHF/external/generator/generator_pythia8_gaptriggered_hf.C +funcName=GeneratorPythia8GapTriggeredBeauty(3, -4.3, -2.2) +[GeneratorPythia8] +config=${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGHF/pythia8/generator/pythia8_beauty_with_mudecays_Mode2.cfg +includePartonEvent=true diff --git a/MC/config/PWGHF/ini/GeneratorHF_mu_bbbar_gap5_Mode2_accInt_muTrig.ini b/MC/config/PWGHF/ini/GeneratorHF_mu_bbbar_gap5_Mode2_accInt_muTrig.ini index 8a0b4ffd3..582ed736b 100644 --- a/MC/config/PWGHF/ini/GeneratorHF_mu_bbbar_gap5_Mode2_accInt_muTrig.ini +++ b/MC/config/PWGHF/ini/GeneratorHF_mu_bbbar_gap5_Mode2_accInt_muTrig.ini @@ -1,3 +1,4 @@ +#NEV_TEST> 20 ### The external generator derives from GeneratorPythia8. [GeneratorExternal] fileName=${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGHF/external/generator/generator_pythia8_gaptriggered_hf.C diff --git a/MC/config/PWGHF/ini/GeneratorHF_mu_bbbar_gap5_Mode2_accLarge.ini b/MC/config/PWGHF/ini/GeneratorHF_mu_bbbar_gap5_Mode2_accLarge.ini index ad1d271eb..8db0ed60b 100644 --- a/MC/config/PWGHF/ini/GeneratorHF_mu_bbbar_gap5_Mode2_accLarge.ini +++ b/MC/config/PWGHF/ini/GeneratorHF_mu_bbbar_gap5_Mode2_accLarge.ini @@ -1,3 +1,4 @@ +#NEV_TEST> 20 ### The external generator derives from GeneratorPythia8. [GeneratorExternal] fileName=${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGHF/external/generator/generator_pythia8_gaptriggered_hf.C diff --git a/MC/config/PWGHF/ini/GeneratorHF_mu_bbbar_gap5_Mode2_accLarge_muTrig.ini b/MC/config/PWGHF/ini/GeneratorHF_mu_bbbar_gap5_Mode2_accLarge_muTrig.ini index 1c5368bf2..972c075b2 100644 --- a/MC/config/PWGHF/ini/GeneratorHF_mu_bbbar_gap5_Mode2_accLarge_muTrig.ini +++ b/MC/config/PWGHF/ini/GeneratorHF_mu_bbbar_gap5_Mode2_accLarge_muTrig.ini @@ -1,3 +1,4 @@ +#NEV_TEST> 20 ### The external generator derives from GeneratorPythia8. [GeneratorExternal] fileName=${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGHF/external/generator/generator_pythia8_gaptriggered_hf.C diff --git a/MC/config/PWGHF/ini/GeneratorHF_mu_bbbar_gap5_Mode2_accSmall.ini b/MC/config/PWGHF/ini/GeneratorHF_mu_bbbar_gap5_Mode2_accSmall.ini index e96f24a0c..923394b48 100644 --- a/MC/config/PWGHF/ini/GeneratorHF_mu_bbbar_gap5_Mode2_accSmall.ini +++ b/MC/config/PWGHF/ini/GeneratorHF_mu_bbbar_gap5_Mode2_accSmall.ini @@ -1,3 +1,4 @@ +#NEV_TEST> 20 ### The external generator derives from GeneratorPythia8. [GeneratorExternal] fileName=${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGHF/external/generator/generator_pythia8_gaptriggered_hf.C diff --git a/MC/config/PWGHF/ini/GeneratorHF_mu_ccbar_gap3_Mode2_accSmall.ini b/MC/config/PWGHF/ini/GeneratorHF_mu_ccbar_gap3_Mode2_accSmall.ini new file mode 100644 index 000000000..bc2c06c55 --- /dev/null +++ b/MC/config/PWGHF/ini/GeneratorHF_mu_ccbar_gap3_Mode2_accSmall.ini @@ -0,0 +1,8 @@ +#NEV_TEST> 24 +### The external generator derives from GeneratorPythia8. +[GeneratorExternal] +fileName=${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGHF/external/generator/generator_pythia8_gaptriggered_hf.C +funcName=GeneratorPythia8GapTriggeredCharm(3, -4.3, -2.2) +[GeneratorPythia8] +config=${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGHF/pythia8/generator/pythia8_charm_with_mudecays_Mode2.cfg +includePartonEvent=true diff --git a/MC/config/PWGHF/ini/GeneratorHF_mu_ccbar_gap5_Mode2_accInt_muTrig.ini b/MC/config/PWGHF/ini/GeneratorHF_mu_ccbar_gap5_Mode2_accInt_muTrig.ini index 8540f0838..149728000 100644 --- a/MC/config/PWGHF/ini/GeneratorHF_mu_ccbar_gap5_Mode2_accInt_muTrig.ini +++ b/MC/config/PWGHF/ini/GeneratorHF_mu_ccbar_gap5_Mode2_accInt_muTrig.ini @@ -1,3 +1,4 @@ +#NEV_TEST> 20 ### The external generator derives from GeneratorPythia8. [GeneratorExternal] fileName=${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGHF/external/generator/generator_pythia8_gaptriggered_hf.C diff --git a/MC/config/PWGHF/ini/GeneratorHF_mu_ccbar_gap5_Mode2_accLarge.ini b/MC/config/PWGHF/ini/GeneratorHF_mu_ccbar_gap5_Mode2_accLarge.ini index 7ca5f7c86..6c3904834 100644 --- a/MC/config/PWGHF/ini/GeneratorHF_mu_ccbar_gap5_Mode2_accLarge.ini +++ b/MC/config/PWGHF/ini/GeneratorHF_mu_ccbar_gap5_Mode2_accLarge.ini @@ -1,3 +1,4 @@ +#NEV_TEST> 20 ### The external generator derives from GeneratorPythia8. [GeneratorExternal] fileName=${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGHF/external/generator/generator_pythia8_gaptriggered_hf.C diff --git a/MC/config/PWGHF/ini/GeneratorHF_mu_ccbar_gap5_Mode2_accLarge_muTrig.ini b/MC/config/PWGHF/ini/GeneratorHF_mu_ccbar_gap5_Mode2_accLarge_muTrig.ini index 149812d38..970a08807 100644 --- a/MC/config/PWGHF/ini/GeneratorHF_mu_ccbar_gap5_Mode2_accLarge_muTrig.ini +++ b/MC/config/PWGHF/ini/GeneratorHF_mu_ccbar_gap5_Mode2_accLarge_muTrig.ini @@ -1,3 +1,4 @@ +#NEV_TEST> 20 ### The external generator derives from GeneratorPythia8. [GeneratorExternal] fileName=${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGHF/external/generator/generator_pythia8_gaptriggered_hf.C diff --git a/MC/config/PWGHF/ini/GeneratorHF_mu_ccbar_gap5_Mode2_accSmall.ini b/MC/config/PWGHF/ini/GeneratorHF_mu_ccbar_gap5_Mode2_accSmall.ini index c694e078f..43e1b79fa 100644 --- a/MC/config/PWGHF/ini/GeneratorHF_mu_ccbar_gap5_Mode2_accSmall.ini +++ b/MC/config/PWGHF/ini/GeneratorHF_mu_ccbar_gap5_Mode2_accSmall.ini @@ -1,3 +1,4 @@ +#NEV_TEST> 20 ### The external generator derives from GeneratorPythia8. [GeneratorExternal] fileName=${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGHF/external/generator/generator_pythia8_gaptriggered_hf.C diff --git a/MC/config/PWGHF/ini/tests/GeneratorHFTrigger_BToDeuteron.C b/MC/config/PWGHF/ini/tests/GeneratorHFTrigger_BToDeuteron.C new file mode 100644 index 000000000..bd56f98e6 --- /dev/null +++ b/MC/config/PWGHF/ini/tests/GeneratorHFTrigger_BToDeuteron.C @@ -0,0 +1,48 @@ +int External() +{ + std::string path{"o2sim_Kine.root"}; + std::vector checkPdgHadron{521}; + std::vector nucleiDauPdg{1000010020}; + + TFile file(path.c_str(), "READ"); + if (file.IsZombie()) + { + std::cerr << "Cannot open ROOT file " << path << "\n"; + return 1; + } + + auto tree = (TTree *)file.Get("o2sim"); + std::vector *tracks{}; + tree->SetBranchAddress("MCTrack", &tracks); + + int nSignals{}, nSignalGoodDecay{}; + auto nEvents = tree->GetEntries(); + + for (int i = 0; i < nEvents; i++) + { + tree->GetEntry(i); + for (auto &track : *tracks) + { + auto pdg = track.GetPdgCode(); + if (std::find(checkPdgHadron.begin(), checkPdgHadron.end(), std::abs(pdg)) != checkPdgHadron.end()) + { + if(std::abs(track.GetRapidity()) > 1.5) continue; + nSignals++; + for (int j{track.getFirstDaughterTrackId()}; j <= track.getLastDaughterTrackId(); ++j) + { + auto pdgDau = tracks->at(j).GetPdgCode(); + if (std::find(nucleiDauPdg.begin(), nucleiDauPdg.end(), std::abs(pdgDau)) != nucleiDauPdg.end()) + { + nSignalGoodDecay++; + } + } + } + } + } + std::cout << "--------------------------------\n"; + std::cout << "# Events: " << nEvents << "\n"; + std::cout << "# signal hadrons: " << nSignals << "\n"; + std::cout << "# signal hadrons decaying into nuclei: " << nSignalGoodDecay << "\n"; + + return 0; +} \ No newline at end of file diff --git a/MC/config/PWGHF/ini/tests/GeneratorHFTrigger_Bforced.C b/MC/config/PWGHF/ini/tests/GeneratorHFTrigger_Bforced.C index c3cb9bcfb..7f0eca77f 100644 --- a/MC/config/PWGHF/ini/tests/GeneratorHFTrigger_Bforced.C +++ b/MC/config/PWGHF/ini/tests/GeneratorHFTrigger_Bforced.C @@ -90,8 +90,9 @@ int External() return 1; } - float fracForcedDecays = float(nSignalGoodDecay) / nSignals; - if (fracForcedDecays < 0.75) // we put some tolerance (e.g. due to oscillations which might change the final state) + float fracForcedDecays = nSignals ? float(nSignalGoodDecay) / nSignals : 0.0f; + float uncFracForcedDecays = nSignals ? std::sqrt(fracForcedDecays * (1 - fracForcedDecays) / nSignals) : 1.0f; + if (1 - fracForcedDecays > 0.3 + uncFracForcedDecays) // we put some tolerance (e.g. due to oscillations which might change the final state) { std::cerr << "Fraction of signals decaying into the correct channel " << fracForcedDecays << " lower than expected\n"; return 1; diff --git a/MC/config/PWGHF/ini/tests/GeneratorHFTrigger_LambdaBToDeuteron.C b/MC/config/PWGHF/ini/tests/GeneratorHFTrigger_LambdaBToDeuteron.C new file mode 100644 index 000000000..3df607574 --- /dev/null +++ b/MC/config/PWGHF/ini/tests/GeneratorHFTrigger_LambdaBToDeuteron.C @@ -0,0 +1,57 @@ +int External() +{ + std::string path{"o2sim_Kine.root"}; + std::vector checkPdgHadron{5122}; // Lambda_b + std::vector nucleiDauPdg{1000010020}; // d, 3He, 3H + + TFile file(path.c_str(), "READ"); + if (file.IsZombie()) + { + std::cerr << "Cannot open ROOT file " << path << "\n"; + return 1; + } + + auto tree = (TTree *)file.Get("o2sim"); + std::vector *tracks{}; + tree->SetBranchAddress("MCTrack", &tracks); + + int nSignals{}, nSignalGoodDecay{}; + auto nEvents = tree->GetEntries(); + + for (int i = 0; i < nEvents; i++) + { + tree->GetEntry(i); + for (auto &track : *tracks) + { + auto pdg = track.GetPdgCode(); + if (std::find(checkPdgHadron.begin(), checkPdgHadron.end(), std::abs(pdg)) != checkPdgHadron.end()) // found signal + { + // count signal PDG + if(std::abs(track.GetRapidity()) > 1.5) continue; // skip if outside rapidity window + nSignals++; + for (int j{track.getFirstDaughterTrackId()}; j <= track.getLastDaughterTrackId(); ++j) + { + auto pdgDau = tracks->at(j).GetPdgCode(); + if (std::find(nucleiDauPdg.begin(), nucleiDauPdg.end(), std::abs(pdgDau)) != nucleiDauPdg.end()) + { + nSignalGoodDecay++; + } + } + } + } + } + std::cout << "--------------------------------\n"; + std::cout << "# Events: " << nEvents << "\n"; + std::cout <<"# signal hadrons: " << nSignals << "\n"; + std::cout <<"# signal hadrons decaying into nuclei: " << nSignalGoodDecay << "\n"; + + float fracForcedDecays = nSignals ? float(nSignalGoodDecay) / nSignals : 0.0f; + float uncFracForcedDecays = nSignals ? std::sqrt(fracForcedDecays * (1 - fracForcedDecays) / nSignals) : 1.0f; + if (1 - fracForcedDecays > 0.2 + uncFracForcedDecays) // we put some tolerance (lambdaB in MB events do not coalesce) + { + std::cerr << "Fraction of signals decaying into nuclei: " << fracForcedDecays << ", lower than expected\n"; + return 1; + } + + return 0; +} diff --git a/MC/config/PWGHF/ini/tests/GeneratorHFTrigger_LambdaBToNuclei.C b/MC/config/PWGHF/ini/tests/GeneratorHFTrigger_LambdaBToNuclei.C new file mode 100644 index 000000000..be1ef1b56 --- /dev/null +++ b/MC/config/PWGHF/ini/tests/GeneratorHFTrigger_LambdaBToNuclei.C @@ -0,0 +1,57 @@ +int External() +{ + std::string path{"o2sim_Kine.root"}; + std::vector checkPdgHadron{5122}; // Lambda_b + std::vector nucleiDauPdg{1000020030, 1000010030}; // 3He, 3H + + TFile file(path.c_str(), "READ"); + if (file.IsZombie()) + { + std::cerr << "Cannot open ROOT file " << path << "\n"; + return 1; + } + + auto tree = (TTree *)file.Get("o2sim"); + std::vector *tracks{}; + tree->SetBranchAddress("MCTrack", &tracks); + + int nSignals{}, nSignalGoodDecay{}; + auto nEvents = tree->GetEntries(); + + for (int i = 0; i < nEvents; i++) + { + tree->GetEntry(i); + for (auto &track : *tracks) + { + auto pdg = track.GetPdgCode(); + if (std::find(checkPdgHadron.begin(), checkPdgHadron.end(), std::abs(pdg)) != checkPdgHadron.end()) // found signal + { + // count signal PDG + if(std::abs(track.GetRapidity()) > 1.5) continue; // skip if outside rapidity window + nSignals++; + for (int j{track.getFirstDaughterTrackId()}; j <= track.getLastDaughterTrackId(); ++j) + { + auto pdgDau = tracks->at(j).GetPdgCode(); + if (std::find(nucleiDauPdg.begin(), nucleiDauPdg.end(), std::abs(pdgDau)) != nucleiDauPdg.end()) + { + nSignalGoodDecay++; + } + } + } + } + } + std::cout << "--------------------------------\n"; + std::cout << "# Events: " << nEvents << "\n"; + std::cout <<"# signal hadrons: " << nSignals << "\n"; + std::cout <<"# signal hadrons decaying into nuclei: " << nSignalGoodDecay << "\n"; + + float fracForcedDecays = nSignals ? float(nSignalGoodDecay) / nSignals : 0.0f; + float uncFracForcedDecays = nSignals ? std::sqrt(fracForcedDecays * (1 - fracForcedDecays) / nSignals) : 1.0f; + if (1 - fracForcedDecays > 0.2 + uncFracForcedDecays) // we put some tolerance (lambdaB in MB events do not coalesce) + { + std::cerr << "Fraction of signals decaying into nuclei: " << fracForcedDecays << ", lower than expected\n"; + return 1; + } + + return 0; +} diff --git a/MC/config/PWGHF/ini/tests/GeneratorHFTrigger_bbbar.C b/MC/config/PWGHF/ini/tests/GeneratorHFTrigger_bbbar.C index d67a9b48d..05a465e6d 100644 --- a/MC/config/PWGHF/ini/tests/GeneratorHFTrigger_bbbar.C +++ b/MC/config/PWGHF/ini/tests/GeneratorHFTrigger_bbbar.C @@ -82,8 +82,9 @@ int External() return 1; } - float fracForcedDecays = float(nSignalGoodDecay) / nSignals; - if (fracForcedDecays < 0.9) // we put some tolerance (e.g. due to oscillations which might change the final state) + float fracForcedDecays = nSignals ? float(nSignalGoodDecay) / nSignals : 0.0f; + float uncFracForcedDecays = nSignals ? std::sqrt(fracForcedDecays * (1 - fracForcedDecays) / nSignals) : 1.0f; + if (1 - fracForcedDecays > 0.15 + uncFracForcedDecays) // we put some tolerance (e.g. due to oscillations which might change the final state) { std::cerr << "Fraction of signals decaying into the correct channel " << fracForcedDecays << " lower than expected\n"; return 1; diff --git a/MC/config/PWGHF/ini/tests/GeneratorHFTrigger_ccbar.C b/MC/config/PWGHF/ini/tests/GeneratorHFTrigger_ccbar.C index ac58836b2..22863be41 100644 --- a/MC/config/PWGHF/ini/tests/GeneratorHFTrigger_ccbar.C +++ b/MC/config/PWGHF/ini/tests/GeneratorHFTrigger_ccbar.C @@ -82,8 +82,9 @@ int External() return 1; } - float fracForcedDecays = float(nSignalGoodDecay) / nSignals; - if (fracForcedDecays < 0.9) // we put some tolerance (e.g. due to oscillations which might change the final state) + float fracForcedDecays = nSignals ? float(nSignalGoodDecay) / nSignals : 0.0f; + float uncFracForcedDecays = nSignals ? std::sqrt(fracForcedDecays * (1 - fracForcedDecays) / nSignals) : 1.0f; + if (1 - fracForcedDecays > 0.15 + uncFracForcedDecays) // we put some tolerance (e.g. due to oscillations which might change the final state) { std::cerr << "Fraction of signals decaying into the correct channel " << fracForcedDecays << " lower than expected\n"; return 1; diff --git a/MC/config/PWGHF/ini/tests/GeneratorHF_CDeuteron_Injected.C b/MC/config/PWGHF/ini/tests/GeneratorHF_CDeuteron_Injected.C new file mode 100644 index 000000000..56d22c72a --- /dev/null +++ b/MC/config/PWGHF/ini/tests/GeneratorHF_CDeuteron_Injected.C @@ -0,0 +1,127 @@ +int External() { + std::string path{"o2sim_Kine.root"}; + + int pdgCDeuteron{2010010020}; + int checkNumberOfCDeuteronPerEvent{10}; + float checkLifetimeCDeuteron{0.05f}; + std::map>> checkDecays{ + {2010010020, {{-321, 211, 1000010020}}} // c-deuteron -> K- + pi+ + deuteron + }; + float checkFracCDeuteronFromBeauty{0.25}; + + TFile file(path.c_str(), "READ"); + if (file.IsZombie()) { + std::cerr << "Cannot open ROOT file " << path << "\n"; + return 1; + } + + auto tree = (TTree *)file.Get("o2sim"); + std::vector *tracks{}; + tree->SetBranchAddress("MCTrack", &tracks); + + int nCDeuteron{}, nCDeuteronGoodDecay{}, nCDeuteronFromBeauty{}; + std::array averageLifetimeCDeuteron{0.f, 0.f}; // prompt and non-prompt + float massCDeuteron = 3.226f; + auto nEvents = tree->GetEntries(); + + for (int i = 0; i < nEvents; i++) { + tree->GetEntry(i); + + for (auto &track : *tracks) { + auto pdg = track.GetPdgCode(); + auto absPdg = std::abs(pdg); + // std::cout << "Event " << i << ": found particle with PDG " << pdg << std::endl; + + if (absPdg == pdgCDeuteron) { // found signal + nCDeuteron++; // count signal PDG + + // std::cout << "Event " << i << ": found c-deuteron with PDG " << pdg << std::endl; + + std::vector pdgsDecay{}; + std::vector pdgsDecayAntiPart{}; + if (track.getFirstDaughterTrackId() >= 0 && track.getLastDaughterTrackId() >= 0) { + for (int j{track.getFirstDaughterTrackId()}; j <= track.getLastDaughterTrackId(); ++j) { + // std::cout << "Fetching daughter track with ID " << j << std::endl; + auto pdgDau = tracks->at(j).GetPdgCode(); + // std::cout << "PDG of daughter track " << j << ": " << pdgDau << std::endl; + pdgsDecay.push_back(pdgDau); + if (pdgDau != 333 && pdgDau != 111) { // phi and pi0 are antiparticles of themselves + pdgsDecayAntiPart.push_back(-pdgDau); + } else { + pdgsDecayAntiPart.push_back(pdgDau); + } + } + } + // std::cout << "Daughters fetched" << std::endl; + + auto mother = track.getMotherTrackId(); + bool isFromBeauty{false}; + if (mother >= 0 && std::abs(tracks->at(mother).GetPdgCode()) == 5122) { // check if c-deuteron comes from Lb + nCDeuteronFromBeauty++; + isFromBeauty = true; + } + + auto dauTrack = tracks->at(track.getFirstDaughterTrackId()); + float decayLength = std::sqrt((track.GetStartVertexCoordinatesX() - dauTrack.GetStartVertexCoordinatesX()) * (track.GetStartVertexCoordinatesX() - dauTrack.GetStartVertexCoordinatesX()) + (track.GetStartVertexCoordinatesY() - dauTrack.GetStartVertexCoordinatesY()) * (track.GetStartVertexCoordinatesY() - dauTrack.GetStartVertexCoordinatesY()) + (track.GetStartVertexCoordinatesZ() - dauTrack.GetStartVertexCoordinatesZ()) * (track.GetStartVertexCoordinatesZ() - dauTrack.GetStartVertexCoordinatesZ())); + if (!isFromBeauty) { + averageLifetimeCDeuteron[0] += decayLength * massCDeuteron / track.GetP(); + } else { + averageLifetimeCDeuteron[1] += decayLength * massCDeuteron / track.GetP(); + } + + std::sort(pdgsDecay.begin(), pdgsDecay.end()); + std::sort(pdgsDecayAntiPart.begin(), pdgsDecayAntiPart.end()); + + for (auto &decay : checkDecays[std::abs(pdg)]) { + if (pdgsDecay == decay || pdgsDecayAntiPart == decay) { + nCDeuteronGoodDecay++; + break; + } + } + // std::cout << "Daughters checked " << std::endl; + } + } + } + + averageLifetimeCDeuteron[0] /= nCDeuteron - nCDeuteronFromBeauty; + averageLifetimeCDeuteron[1] /= nCDeuteronFromBeauty; + + std::cout << "--------------------------------\n"; + std::cout << "# Events: " << nEvents << "\n"; + std::cout <<"# signal c-deuteron: " << nCDeuteron << "\n"; + std::cout <<"# signal c-deuteron decaying in the correct channel: " << nCDeuteronGoodDecay << "\n"; + std::cout <<"# signal c-deuteron from beauty: " << nCDeuteronFromBeauty << "\n"; + std::cout <<"Average lifetime of c-deuteron (prompt): " << averageLifetimeCDeuteron[0] << " (cm) \n"; + std::cout <<"Average lifetime of c-deuteron (non-prompt): " << averageLifetimeCDeuteron[1] << " (cm) \n"; + + float numberOfCDeuteronPerEvent = float(nCDeuteron) / nEvents; + float fracCDeuteronGoodDecay = float(nCDeuteronGoodDecay) / nCDeuteron; + float fracCDeuteronFromBeauty = float(nCDeuteronFromBeauty) / nCDeuteron; + + if (std::abs(numberOfCDeuteronPerEvent - checkNumberOfCDeuteronPerEvent) / numberOfCDeuteronPerEvent > 0.05) { // we put some tolerance since the number of generated events is small + std::cerr << "Number of C-deuterons per event " << numberOfCDeuteronPerEvent << " different than expected " << checkNumberOfCDeuteronPerEvent << "\n"; + return 1; + } + + if (fracCDeuteronGoodDecay < 0.95) { // we put some tolerance since the number of generated events is small + std::cerr << "Fraction of signals decaying into the correct channel " << fracCDeuteronGoodDecay << " lower than expected\n"; + return 1; + } + + if (std::abs(fracCDeuteronFromBeauty - checkFracCDeuteronFromBeauty) / checkFracCDeuteronFromBeauty > 0.10) { // we put some tolerance since the number of generated events is small + std::cerr << "Fraction of signals from beauty " << fracCDeuteronFromBeauty << " different than expected " << checkFracCDeuteronFromBeauty << "\n"; + return 1; + } + + if (std::abs(averageLifetimeCDeuteron[0] - checkLifetimeCDeuteron) / checkLifetimeCDeuteron > 0.10) { // we put some tolerance since the number of generated events is small + std::cerr << "Lifetime for prompt c-deuteron " << averageLifetimeCDeuteron[0] << " different than expected " << checkLifetimeCDeuteron << "\n"; + return 1; + } + + if (std::abs(averageLifetimeCDeuteron[1] - checkLifetimeCDeuteron) / checkLifetimeCDeuteron > 0.10) { // we put some tolerance since the number of generated events is small + std::cerr << "Lifetime for non-prompt c-deuteron " << averageLifetimeCDeuteron[1] << " different than expected " << checkLifetimeCDeuteron << "\n"; + return 1; + } + + return 0; +} diff --git a/MC/config/PWGHF/ini/tests/GeneratorHF_D2H_bbbar_B2JPsi_gap5_Mode2.C b/MC/config/PWGHF/ini/tests/GeneratorHF_D2H_bbbar_B2JPsi_gap5_Mode2.C new file mode 100644 index 000000000..e18dcadde --- /dev/null +++ b/MC/config/PWGHF/ini/tests/GeneratorHF_D2H_bbbar_B2JPsi_gap5_Mode2.C @@ -0,0 +1,113 @@ +int External() { + std::string path{"o2sim_Kine.root"}; + + int checkPdgQuark{5}; + float ratioTrigger = 1./5; // one event triggered out of 5 + + std::vector checkPdgHadron{443, 511, 521, 531, 5122}; + std::map>> checkHadronDecays{ // sorted pdg of daughters + {443, {{-11, 11}, {-13, 13}}}, // J/psi + {511, {{313, 443}}}, // B0 + {521, {{321, 443}}}, // B+ + {531, {{333, 443}}}, // Bs0 + {5122, {{321, 443, 2212}}} // Lb0 + }; + + TFile file(path.c_str(), "READ"); + if (file.IsZombie()) { + std::cerr << "Cannot open ROOT file " << path << "\n"; + return 1; + } + + auto tree = (TTree *)file.Get("o2sim"); + std::vector *tracks{}; + tree->SetBranchAddress("MCTrack", &tracks); + o2::dataformats::MCEventHeader *eventHeader = nullptr; + tree->SetBranchAddress("MCEventHeader.", &eventHeader); + + int nEventsMB{}, nEventsInj{}; + int nSignals{}, nSignalGoodDecay{}; + int nJPsiToEE{}, nJPsiToMuMu{}; + auto nEvents = tree->GetEntries(); + + for (int i = 0; i < nEvents; i++) { + tree->GetEntry(i); + + // check subgenerator information + if (eventHeader->hasInfo(o2::mcgenid::GeneratorProperty::SUBGENERATORID)) { + bool isValid = false; + int subGeneratorId = eventHeader->getInfo(o2::mcgenid::GeneratorProperty::SUBGENERATORID, isValid); + if (subGeneratorId == 0) { + nEventsMB++; + } else if (subGeneratorId == checkPdgQuark) { + nEventsInj++; + } + } + + for (auto &track : *tracks) { + auto pdg = track.GetPdgCode(); + if (std::find(checkPdgHadron.begin(), checkPdgHadron.end(), std::abs(pdg)) != checkPdgHadron.end()) { // found signal + nSignals++; // count signal PDG + + std::vector pdgsDecay{}; + std::vector pdgsDecayAntiPart{}; + for (int j{track.getFirstDaughterTrackId()}; j <= track.getLastDaughterTrackId(); ++j) { + auto pdgDau = tracks->at(j).GetPdgCode(); + if (pdg == 443 && pdgDau == 22) { + continue; + } + pdgsDecay.push_back(pdgDau); + if (pdgDau != 333) { // phi is antiparticle of itself + pdgsDecayAntiPart.push_back(-pdgDau); + } else { + pdgsDecayAntiPart.push_back(pdgDau); + } + } + + std::sort(pdgsDecay.begin(), pdgsDecay.end()); + std::sort(pdgsDecayAntiPart.begin(), pdgsDecayAntiPart.end()); + + for (auto &decay : checkHadronDecays[std::abs(pdg)]) { + if (pdgsDecay == decay || pdgsDecayAntiPart == decay) { + nSignalGoodDecay++; + if (pdg == 443) { + if (decay == std::vector{-11, 11}) { + nJPsiToEE++; + } else if (decay == std::vector{-13, 13}) { + nJPsiToMuMu++; + } + } + break; + } + } + } + } + } + + std::cout << "--------------------------------\n"; + std::cout << "# Events: " << nEvents << "\n"; + std::cout << "# MB events: " << nEventsMB << "\n"; + std::cout << Form("# events injected with %d quark pair: ", checkPdgQuark) << nEventsInj << "\n"; + std::cout <<"# signal hadrons: " << nSignals << "\n"; + std::cout <<"# signal hadrons decaying in the correct channel: " << nSignalGoodDecay << "\n"; + std::cout <<"# J/Psi decaying to e+e-: " << nJPsiToEE << "\n"; + std::cout <<"# J/Psi decaying to mu+mu-: " << nJPsiToMuMu << "\n"; + + if (nEventsMB < nEvents * (1 - ratioTrigger) * 0.95 || nEventsMB > nEvents * (1 - ratioTrigger) * 1.05) { // we put some tolerance since the number of generated events is small + std::cerr << "Number of generated MB events different than expected\n"; + return 1; + } + if (nEventsInj < nEvents * ratioTrigger * 0.95 || nEventsInj > nEvents * ratioTrigger * 1.05) { + std::cerr << "Number of generated events injected with " << checkPdgQuark << " different than expected\n"; + return 1; + } + + float fracForcedDecays = nSignals ? float(nSignalGoodDecay) / nSignals : 0.0f; + float uncFracForcedDecays = nSignals ? std::sqrt(fracForcedDecays * (1 - fracForcedDecays) / nSignals) : 1.0f; + if (1 - fracForcedDecays > 0.5 + uncFracForcedDecays) { // at least 50% in the main decay channels (we also have correlated backgrounds, mostly from other B decays) + std::cerr << "Fraction of signals decaying into the correct channel " << fracForcedDecays << " lower than expected\n"; + return 1; + } + + return 0; +} diff --git a/MC/config/PWGHF/ini/tests/GeneratorHF_D2H_bbbar_Bforced_gap5_Mode2.C b/MC/config/PWGHF/ini/tests/GeneratorHF_D2H_bbbar_Bforced_gap5_Mode2.C index b5264c370..629aa3ae1 100644 --- a/MC/config/PWGHF/ini/tests/GeneratorHF_D2H_bbbar_Bforced_gap5_Mode2.C +++ b/MC/config/PWGHF/ini/tests/GeneratorHF_D2H_bbbar_Bforced_gap5_Mode2.C @@ -105,8 +105,9 @@ int External() { return 1; } - float fracForcedDecays = float(nSignalGoodDecay) / nSignals; - if (fracForcedDecays < 0.85) { // we put some tolerance (e.g. due to oscillations which might change the final state) + float fracForcedDecays = nSignals ? float(nSignalGoodDecay) / nSignals : 0.0f; + float uncFracForcedDecays = nSignals ? std::sqrt(fracForcedDecays * (1 - fracForcedDecays) / nSignals) : 1.0f; + if (1 - fracForcedDecays > 0.3 + uncFracForcedDecays) { // we put some tolerance (e.g. due to oscillations which might change the final state) std::cerr << "Fraction of signals decaying into the correct channel " << fracForcedDecays << " lower than expected\n"; return 1; } diff --git a/MC/config/PWGHF/ini/tests/GeneratorHF_D2H_bbbar_BtoDK_gap5_Mode2.C b/MC/config/PWGHF/ini/tests/GeneratorHF_D2H_bbbar_BtoDK_gap5_Mode2.C new file mode 100644 index 000000000..07f70bfd7 --- /dev/null +++ b/MC/config/PWGHF/ini/tests/GeneratorHF_D2H_bbbar_BtoDK_gap5_Mode2.C @@ -0,0 +1,116 @@ +int External() { + std::string path{"o2sim_Kine.root"}; + + int checkPdgQuark{5}; + float ratioTrigger = 1./5; // one event triggered out of 5 + + std::vector checkPdgHadron{411, 421, 431, 4122, 4132, 4232, 4332, 511, 521, 531, 5122}; + std::map>> checkHadronDecays{ // sorted pdg of daughters + {411, {{-321, 211, 211}, {-313, 211}, {211, 311}, {211, 333}}}, // D+ + {421, {{-321, 211}, {-321, 111, 211}}}, // D0 + {431, {{211, 333}, {-313, 321}}}, // Ds+ + {4122, {{-313, 2212}, {-321, 2224}, {211, 102134}, {-321, 211, 2212}, {311, 2212}}}, // Lc+ + {4132, {{211, 3312}}}, // Xic0 + {4232, {{-313, 2212}, {-321, 3324}, {211, 211, 3312}, {-321, 211, 2212}}}, // Xic+ + {4332, {{211, 3334}}}, // Omegac+ + {511, {{-411, 211}, {-411, 321}}}, // B0 + {521, {{-421, 211}, {-421, 321}}}, // B+ + {531, {{-431, 211}, {-431, 321}}}, // Bs0 + {5122, {{4122, -211}, {4122, -321}}} // Lb0 + }; + + TFile file(path.c_str(), "READ"); + if (file.IsZombie()) { + std::cerr << "Cannot open ROOT file " << path << "\n"; + return 1; + } + + auto tree = (TTree *)file.Get("o2sim"); + std::vector *tracks{}; + tree->SetBranchAddress("MCTrack", &tracks); + o2::dataformats::MCEventHeader *eventHeader = nullptr; + tree->SetBranchAddress("MCEventHeader.", &eventHeader); + + int nEventsMB{}, nEventsInj{}; + int nQuarks{}, nSignals{}, nSignalGoodDecay{}; + auto nEvents = tree->GetEntries(); + + for (int i = 0; i < nEvents; i++) { + tree->GetEntry(i); + + // check subgenerator information + if (eventHeader->hasInfo(o2::mcgenid::GeneratorProperty::SUBGENERATORID)) { + bool isValid = false; + int subGeneratorId = eventHeader->getInfo(o2::mcgenid::GeneratorProperty::SUBGENERATORID, isValid); + if (subGeneratorId == 0) { + nEventsMB++; + } else if (subGeneratorId == checkPdgQuark) { + nEventsInj++; + } + } + + for (auto &track : *tracks) { + auto pdg = track.GetPdgCode(); + if (std::abs(pdg) == checkPdgQuark) { + nQuarks++; + continue; + } + if (std::find(checkPdgHadron.begin(), checkPdgHadron.end(), std::abs(pdg)) != checkPdgHadron.end()) { // found signal + nSignals++; // count signal PDG + + std::vector pdgsDecay{}; + std::vector pdgsDecayAntiPart{}; + for (int j{track.getFirstDaughterTrackId()}; j <= track.getLastDaughterTrackId(); ++j) { + auto pdgDau = tracks->at(j).GetPdgCode(); + pdgsDecay.push_back(pdgDau); + if (pdgDau != 333) { // phi is antiparticle of itself + pdgsDecayAntiPart.push_back(-pdgDau); + } else { + pdgsDecayAntiPart.push_back(pdgDau); + } + } + + std::sort(pdgsDecay.begin(), pdgsDecay.end()); + std::sort(pdgsDecayAntiPart.begin(), pdgsDecayAntiPart.end()); + + for (auto &decay : checkHadronDecays[std::abs(pdg)]) { + if (pdgsDecay == decay || pdgsDecayAntiPart == decay) { + nSignalGoodDecay++; + break; + } + } + } + } + } + + std::cout << "--------------------------------\n"; + std::cout << "# Events: " << nEvents << "\n"; + std::cout << "# MB events: " << nEventsMB << "\n"; + std::cout << Form("# events injected with %d quark pair: ", checkPdgQuark) << nEventsInj << "\n"; + std::cout << Form("# %d (anti)quarks: ", checkPdgQuark) << nQuarks << "\n"; + std::cout <<"# signal hadrons: " << nSignals << "\n"; + std::cout <<"# signal hadrons decaying in the correct channel: " << nSignalGoodDecay << "\n"; + + if (nEventsMB < nEvents * (1 - ratioTrigger) * 0.95 || nEventsMB > nEvents * (1 - ratioTrigger) * 1.05) { // we put some tolerance since the number of generated events is small + std::cerr << "Number of generated MB events different than expected\n"; + return 1; + } + if (nEventsInj < nEvents * ratioTrigger * 0.95 || nEventsInj > nEvents * ratioTrigger * 1.05) { + std::cerr << "Number of generated events injected with " << checkPdgQuark << " different than expected\n"; + return 1; + } + + if (nQuarks < nEvents * ratioTrigger) { // we expect anyway more because the same quark is repeated several time, after each gluon radiation + std::cerr << "Number of generated (anti)quarks " << checkPdgQuark << " lower than expected\n"; + return 1; + } + + float fracForcedDecays = nSignals ? float(nSignalGoodDecay) / nSignals : 0.0f; + float uncFracForcedDecays = nSignals ? std::sqrt(fracForcedDecays * (1 - fracForcedDecays) / nSignals) : 1.0f; + if (1 - fracForcedDecays > 0.15 + uncFracForcedDecays) { // we put some tolerance (e.g. due to oscillations which might change the final state) + std::cerr << "Fraction of signals decaying into the correct channel " << fracForcedDecays << " lower than expected\n"; + return 1; + } + + return 0; +} diff --git a/MC/config/PWGHF/ini/tests/GeneratorHF_D2H_bbbar_Mode2_OmegaC.C b/MC/config/PWGHF/ini/tests/GeneratorHF_D2H_bbbar_Mode2_OmegaC.C index e55bb2709..d4c8fdf56 100644 --- a/MC/config/PWGHF/ini/tests/GeneratorHF_D2H_bbbar_Mode2_OmegaC.C +++ b/MC/config/PWGHF/ini/tests/GeneratorHF_D2H_bbbar_Mode2_OmegaC.C @@ -95,8 +95,9 @@ int External() { return 1; } - float fracForcedDecays = float(nSignalGoodDecay) / nSignals; - if (fracForcedDecays < 0.9) { // we put some tolerance (e.g. due to oscillations which might change the final state) + float fracForcedDecays = nSignals ? float(nSignalGoodDecay) / nSignals : 0.0f; + float uncFracForcedDecays = nSignals ? std::sqrt(fracForcedDecays * (1 - fracForcedDecays) / nSignals) : 1.0f; + if (1 - fracForcedDecays > 0.15 + uncFracForcedDecays) { // we put some tolerance (e.g. due to oscillations which might change the final state) std::cerr << "Fraction of signals decaying into the correct channel " << fracForcedDecays << " lower than expected\n"; return 1; } diff --git a/MC/config/PWGHF/ini/tests/GeneratorHF_D2H_bbbar_Mode2_OmegaC_NoDecay.C b/MC/config/PWGHF/ini/tests/GeneratorHF_D2H_bbbar_Mode2_OmegaC_NoDecay.C index 73788a608..70fecc536 100644 --- a/MC/config/PWGHF/ini/tests/GeneratorHF_D2H_bbbar_Mode2_OmegaC_NoDecay.C +++ b/MC/config/PWGHF/ini/tests/GeneratorHF_D2H_bbbar_Mode2_OmegaC_NoDecay.C @@ -1,7 +1,7 @@ int External() { std::string path{"o2sim_Kine.root"}; - int checkPdgQuarkOne = 5; + int checkPdgQuark{5}; int checkPdgHadron{4332}; int checkHadronDecays{0}; diff --git a/MC/config/PWGHF/ini/tests/GeneratorHF_D2H_bbbar_Mode2_OmegaC_NoDecay_pp_ref.C b/MC/config/PWGHF/ini/tests/GeneratorHF_D2H_bbbar_Mode2_OmegaC_NoDecay_pp_ref.C new file mode 100644 index 000000000..70fecc536 --- /dev/null +++ b/MC/config/PWGHF/ini/tests/GeneratorHF_D2H_bbbar_Mode2_OmegaC_NoDecay_pp_ref.C @@ -0,0 +1,83 @@ +int External() { + std::string path{"o2sim_Kine.root"}; + + int checkPdgQuark{5}; + + int checkPdgHadron{4332}; + int checkHadronDecays{0}; + + TFile file(path.c_str(), "READ"); + if (file.IsZombie()) { + std::cerr << "Cannot open ROOT file " << path << "\n"; + return 1; + } + + auto tree = (TTree *)file.Get("o2sim"); + std::vector *tracks{}; + tree->SetBranchAddress("MCTrack", &tracks); + o2::dataformats::MCEventHeader *eventHeader = nullptr; + tree->SetBranchAddress("MCEventHeader.", &eventHeader); + + int nEventsInj{}; + int nQuarks{}, nSignals{}; + auto nEvents = tree->GetEntries(); + + for (int i = 0; i < nEvents; i++) { + tree->GetEntry(i); + + // check subgenerator information + if (eventHeader->hasInfo(o2::mcgenid::GeneratorProperty::SUBGENERATORID)) { + bool isValid = false; + int subGeneratorId = eventHeader->getInfo(o2::mcgenid::GeneratorProperty::SUBGENERATORID, isValid); + if (subGeneratorId == checkPdgQuark) { + nEventsInj++; + } + } + + for (auto &track : *tracks) { + auto pdg = track.GetPdgCode(); + if (std::abs(pdg) == checkPdgQuark) { + nQuarks++; + continue; + } + if (std::abs(pdg) == checkPdgHadron) { // found signal + nSignals++; // count signal PDG + + for (int j{track.getFirstDaughterTrackId()}; j <= track.getLastDaughterTrackId(); ++j) { + if (j >= 0) { + checkHadronDecays += 1; + } + } + } + } + } + + std::cout << "--------------------------------\n"; + std::cout << "# Events: " << nEvents << "\n"; + std::cout << Form("# events injected with %d quark pair: ", checkPdgQuark) << nEventsInj << "\n"; + std::cout << Form("# %d (anti)quarks: ", checkPdgQuark) << nQuarks << "\n"; + std::cout <<"# signal hadrons: " << nSignals << "\n"; + std::cout <<"# signal hadrons decaying : " << checkHadronDecays << "\n"; + + if (nEventsInj < nEvents) { + std::cerr << "Number of generated events with triggered events different than expected\n"; + return 1; + } + + if (nQuarks < nEvents) { // we expect anyway more because the same quark is repeated several time, after each gluon radiation + std::cerr << "Number of generated (anti)quarks " << checkPdgQuark << " lower than expected\n"; + return 1; + } + + if (nSignals < nEvents) { + std::cerr << "Number of generated signals lower than expected\n"; + return 1; + } + + if (checkHadronDecays > 0) { + std::cerr << "Decayed OmegaC, it should never decay\n"; + return 1; + } + + return 0; +} diff --git a/MC/config/PWGHF/ini/tests/GeneratorHF_D2H_bbbar_Mode2_XiC0_XiCplus.C b/MC/config/PWGHF/ini/tests/GeneratorHF_D2H_bbbar_Mode2_XiC0_XiCplus.C index 69d9a256c..27591c842 100644 --- a/MC/config/PWGHF/ini/tests/GeneratorHF_D2H_bbbar_Mode2_XiC0_XiCplus.C +++ b/MC/config/PWGHF/ini/tests/GeneratorHF_D2H_bbbar_Mode2_XiC0_XiCplus.C @@ -6,8 +6,17 @@ int External() { std::vector checkPdgHadron{4132, 4232}; std::map>> checkHadronDecays{ // sorted pdg of daughters - {4132, {{211, 3312}}}, // Xic0 - {4232, {{-313, 2212}, {-321, 3324}, {211, 211, 3312}, {-321, 211, 2212}}} // Xic+ + {4132, { + {3312, 211}, // Xic0 -> Xi-, pi+ + }}, + {4232, { + {2212, -321, 211}, // Xic+ -> p, K-, pi+ + {2212, -313}, // Xic+ -> p, Kbar^*(892)0 + {3312, 211, 211}, // Xic+ -> Xi-, pi+, pi+ + {2212, 333}, // Xic+ -> p, phi(1020)0 + {3222, -211, 211}, // Xic+ -> Sigma+, pi-, pi+ + {3324, 211}, // Xic+ -> Xi(1530)0, pi+ + }}, }; TFile file(path.c_str(), "READ"); @@ -65,6 +74,7 @@ int External() { std::sort(pdgsDecayAntiPart.begin(), pdgsDecayAntiPart.end()); for (auto &decay : checkHadronDecays[std::abs(pdg)]) { + std::sort(decay.begin(), decay.end()); if (pdgsDecay == decay || pdgsDecayAntiPart == decay) { nSignalGoodDecay++; break; @@ -96,8 +106,9 @@ int External() { return 1; } - float fracForcedDecays = float(nSignalGoodDecay) / nSignals; - if (fracForcedDecays < 0.9) { // we put some tolerance (e.g. due to oscillations which might change the final state) + float fracForcedDecays = nSignals ? float(nSignalGoodDecay) / nSignals : 0.0f; + float uncFracForcedDecays = nSignals ? std::sqrt(fracForcedDecays * (1 - fracForcedDecays) / nSignals) : 1.0f; + if (1 - fracForcedDecays > 0.15 + uncFracForcedDecays) { // we put some tolerance (e.g. due to oscillations which might change the final state) std::cerr << "Fraction of signals decaying into the correct channel " << fracForcedDecays << " lower than expected\n"; return 1; } diff --git a/MC/config/PWGHF/ini/tests/GeneratorHF_D2H_bbbar_Mode2_XiC_NoDecay.C b/MC/config/PWGHF/ini/tests/GeneratorHF_D2H_bbbar_Mode2_XiC_NoDecay.C new file mode 100644 index 000000000..5f406097e --- /dev/null +++ b/MC/config/PWGHF/ini/tests/GeneratorHF_D2H_bbbar_Mode2_XiC_NoDecay.C @@ -0,0 +1,83 @@ +int External() { + std::string path{"o2sim_Kine.root"}; + + int checkPdgQuark{5}; + + int checkPdgHadron{4132}; + int checkHadronDecays{0}; + + TFile file(path.c_str(), "READ"); + if (file.IsZombie()) { + std::cerr << "Cannot open ROOT file " << path << "\n"; + return 1; + } + + auto tree = (TTree *)file.Get("o2sim"); + std::vector *tracks{}; + tree->SetBranchAddress("MCTrack", &tracks); + o2::dataformats::MCEventHeader *eventHeader = nullptr; + tree->SetBranchAddress("MCEventHeader.", &eventHeader); + + int nEventsInj{}; + int nQuarks{}, nSignals{}; + auto nEvents = tree->GetEntries(); + + for (int i = 0; i < nEvents; i++) { + tree->GetEntry(i); + + // check subgenerator information + if (eventHeader->hasInfo(o2::mcgenid::GeneratorProperty::SUBGENERATORID)) { + bool isValid = false; + int subGeneratorId = eventHeader->getInfo(o2::mcgenid::GeneratorProperty::SUBGENERATORID, isValid); + if (subGeneratorId == checkPdgQuark) { + nEventsInj++; + } + } + + for (auto &track : *tracks) { + auto pdg = track.GetPdgCode(); + if (std::abs(pdg) == checkPdgQuark) { + nQuarks++; + continue; + } + if (std::abs(pdg) == checkPdgHadron) { // found signal + nSignals++; // count signal PDG + + for (int j{track.getFirstDaughterTrackId()}; j <= track.getLastDaughterTrackId(); ++j) { + if (j >= 0) { + checkHadronDecays += 1; + } + } + } + } + } + + std::cout << "--------------------------------\n"; + std::cout << "# Events: " << nEvents << "\n"; + std::cout << Form("# events injected with %d quark pair: ", checkPdgQuark) << nEventsInj << "\n"; + std::cout << Form("# %d (anti)quarks: ", checkPdgQuark) << nQuarks << "\n"; + std::cout <<"# signal hadrons: " << nSignals << "\n"; + std::cout <<"# signal hadrons decaying : " << checkHadronDecays << "\n"; + + if (nEventsInj < nEvents) { + std::cerr << "Number of generated events with triggered events different than expected\n"; + return 1; + } + + if (nQuarks < nEvents) { // we expect anyway more because the same quark is repeated several time, after each gluon radiation + std::cerr << "Number of generated (anti)quarks " << checkPdgQuark << " lower than expected\n"; + return 1; + } + + if (nSignals < nEvents) { + std::cerr << "Number of generated signals lower than expected\n"; + return 1; + } + + if (checkHadronDecays > 0) { + std::cerr << "Decayed XiC, it should never decay\n"; + return 1; + } + + return 0; +} diff --git a/MC/config/PWGHF/ini/tests/GeneratorHF_D2H_bbbar_Mode2_XiC_NoDecay_pp_ref.C b/MC/config/PWGHF/ini/tests/GeneratorHF_D2H_bbbar_Mode2_XiC_NoDecay_pp_ref.C new file mode 100644 index 000000000..5f406097e --- /dev/null +++ b/MC/config/PWGHF/ini/tests/GeneratorHF_D2H_bbbar_Mode2_XiC_NoDecay_pp_ref.C @@ -0,0 +1,83 @@ +int External() { + std::string path{"o2sim_Kine.root"}; + + int checkPdgQuark{5}; + + int checkPdgHadron{4132}; + int checkHadronDecays{0}; + + TFile file(path.c_str(), "READ"); + if (file.IsZombie()) { + std::cerr << "Cannot open ROOT file " << path << "\n"; + return 1; + } + + auto tree = (TTree *)file.Get("o2sim"); + std::vector *tracks{}; + tree->SetBranchAddress("MCTrack", &tracks); + o2::dataformats::MCEventHeader *eventHeader = nullptr; + tree->SetBranchAddress("MCEventHeader.", &eventHeader); + + int nEventsInj{}; + int nQuarks{}, nSignals{}; + auto nEvents = tree->GetEntries(); + + for (int i = 0; i < nEvents; i++) { + tree->GetEntry(i); + + // check subgenerator information + if (eventHeader->hasInfo(o2::mcgenid::GeneratorProperty::SUBGENERATORID)) { + bool isValid = false; + int subGeneratorId = eventHeader->getInfo(o2::mcgenid::GeneratorProperty::SUBGENERATORID, isValid); + if (subGeneratorId == checkPdgQuark) { + nEventsInj++; + } + } + + for (auto &track : *tracks) { + auto pdg = track.GetPdgCode(); + if (std::abs(pdg) == checkPdgQuark) { + nQuarks++; + continue; + } + if (std::abs(pdg) == checkPdgHadron) { // found signal + nSignals++; // count signal PDG + + for (int j{track.getFirstDaughterTrackId()}; j <= track.getLastDaughterTrackId(); ++j) { + if (j >= 0) { + checkHadronDecays += 1; + } + } + } + } + } + + std::cout << "--------------------------------\n"; + std::cout << "# Events: " << nEvents << "\n"; + std::cout << Form("# events injected with %d quark pair: ", checkPdgQuark) << nEventsInj << "\n"; + std::cout << Form("# %d (anti)quarks: ", checkPdgQuark) << nQuarks << "\n"; + std::cout <<"# signal hadrons: " << nSignals << "\n"; + std::cout <<"# signal hadrons decaying : " << checkHadronDecays << "\n"; + + if (nEventsInj < nEvents) { + std::cerr << "Number of generated events with triggered events different than expected\n"; + return 1; + } + + if (nQuarks < nEvents) { // we expect anyway more because the same quark is repeated several time, after each gluon radiation + std::cerr << "Number of generated (anti)quarks " << checkPdgQuark << " lower than expected\n"; + return 1; + } + + if (nSignals < nEvents) { + std::cerr << "Number of generated signals lower than expected\n"; + return 1; + } + + if (checkHadronDecays > 0) { + std::cerr << "Decayed XiC, it should never decay\n"; + return 1; + } + + return 0; +} diff --git a/MC/config/PWGHF/ini/tests/GeneratorHF_D2H_bbbar_Mode2_XiCplus_NoDecay.C b/MC/config/PWGHF/ini/tests/GeneratorHF_D2H_bbbar_Mode2_XiCplus_NoDecay.C new file mode 100644 index 000000000..3e245d287 --- /dev/null +++ b/MC/config/PWGHF/ini/tests/GeneratorHF_D2H_bbbar_Mode2_XiCplus_NoDecay.C @@ -0,0 +1,83 @@ +int External() { + std::string path{"o2sim_Kine.root"}; + + int checkPdgQuark = 5; + + int checkPdgHadron{4232}; + int checkHadronDecays{0}; + + TFile file(path.c_str(), "READ"); + if (file.IsZombie()) { + std::cerr << "Cannot open ROOT file " << path << "\n"; + return 1; + } + + auto tree = (TTree *)file.Get("o2sim"); + std::vector *tracks{}; + tree->SetBranchAddress("MCTrack", &tracks); + o2::dataformats::MCEventHeader *eventHeader = nullptr; + tree->SetBranchAddress("MCEventHeader.", &eventHeader); + + int nEventsInj{}; + int nQuarks{}, nSignals{}; + auto nEvents = tree->GetEntries(); + + for (int i = 0; i < nEvents; i++) { + tree->GetEntry(i); + + // check subgenerator information + if (eventHeader->hasInfo(o2::mcgenid::GeneratorProperty::SUBGENERATORID)) { + bool isValid = false; + int subGeneratorId = eventHeader->getInfo(o2::mcgenid::GeneratorProperty::SUBGENERATORID, isValid); + if (subGeneratorId == checkPdgQuark) { + nEventsInj++; + } + } + + for (auto &track : *tracks) { + auto pdg = track.GetPdgCode(); + if (std::abs(pdg) == checkPdgQuark) { + nQuarks++; + continue; + } + if (std::abs(pdg) == checkPdgHadron) { // found signal + nSignals++; // count signal PDG + + for (int j{track.getFirstDaughterTrackId()}; j <= track.getLastDaughterTrackId(); ++j) { + if (j >= 0) { + checkHadronDecays += 1; + } + } + } + } + } + + std::cout << "--------------------------------\n"; + std::cout << "# Events: " << nEvents << "\n"; + std::cout << Form("# events injected with %d quark pair: ", checkPdgQuark) << nEventsInj << "\n"; + std::cout << Form("# %d (anti)quarks: ", checkPdgQuark) << nQuarks << "\n"; + std::cout <<"# signal hadrons: " << nSignals << "\n"; + std::cout <<"# signal hadrons decaying : " << checkHadronDecays << "\n"; + + if (nEventsInj < nEvents) { + std::cerr << "Number of generated events with triggered events different than expected\n"; + return 1; + } + + if (nQuarks < nEvents) { // we expect anyway more because the same quark is repeated several time, after each gluon radiation + std::cerr << "Number of generated (anti)quarks " << checkPdgQuark << " lower than expected\n"; + return 1; + } + + if (nSignals < nEvents) { + std::cerr << "Number of generated signals lower than expected\n"; + return 1; + } + + if (checkHadronDecays > 0) { + std::cerr << "Decayed XiC, it should never decay\n"; + return 1; + } + + return 0; +} diff --git a/MC/config/PWGHF/ini/tests/GeneratorHF_D2H_bbbar_Mode2_XiCplus_NoDecay_pp_ref.C b/MC/config/PWGHF/ini/tests/GeneratorHF_D2H_bbbar_Mode2_XiCplus_NoDecay_pp_ref.C new file mode 100644 index 000000000..4ec473f52 --- /dev/null +++ b/MC/config/PWGHF/ini/tests/GeneratorHF_D2H_bbbar_Mode2_XiCplus_NoDecay_pp_ref.C @@ -0,0 +1,83 @@ +int External() { + std::string path{"o2sim_Kine.root"}; + + int checkPdgQuark{5}; + + int checkPdgHadron{4232}; + int checkHadronDecays{0}; + + TFile file(path.c_str(), "READ"); + if (file.IsZombie()) { + std::cerr << "Cannot open ROOT file " << path << "\n"; + return 1; + } + + auto tree = (TTree *)file.Get("o2sim"); + std::vector *tracks{}; + tree->SetBranchAddress("MCTrack", &tracks); + o2::dataformats::MCEventHeader *eventHeader = nullptr; + tree->SetBranchAddress("MCEventHeader.", &eventHeader); + + int nEventsInj{}; + int nQuarks{}, nSignals{}; + auto nEvents = tree->GetEntries(); + + for (int i = 0; i < nEvents; i++) { + tree->GetEntry(i); + + // check subgenerator information + if (eventHeader->hasInfo(o2::mcgenid::GeneratorProperty::SUBGENERATORID)) { + bool isValid = false; + int subGeneratorId = eventHeader->getInfo(o2::mcgenid::GeneratorProperty::SUBGENERATORID, isValid); + if (subGeneratorId == checkPdgQuark) { + nEventsInj++; + } + } + + for (auto &track : *tracks) { + auto pdg = track.GetPdgCode(); + if (std::abs(pdg) == checkPdgQuark) { + nQuarks++; + continue; + } + if (std::abs(pdg) == checkPdgHadron) { // found signal + nSignals++; // count signal PDG + + for (int j{track.getFirstDaughterTrackId()}; j <= track.getLastDaughterTrackId(); ++j) { + if (j >= 0) { + checkHadronDecays += 1; + } + } + } + } + } + + std::cout << "--------------------------------\n"; + std::cout << "# Events: " << nEvents << "\n"; + std::cout << Form("# events injected with %d quark pair: ", checkPdgQuark) << nEventsInj << "\n"; + std::cout << Form("# %d (anti)quarks: ", checkPdgQuark) << nQuarks << "\n"; + std::cout <<"# signal hadrons: " << nSignals << "\n"; + std::cout <<"# signal hadrons decaying : " << checkHadronDecays << "\n"; + + if (nEventsInj < nEvents) { + std::cerr << "Number of generated events with triggered events different than expected\n"; + return 1; + } + + if (nQuarks < nEvents) { // we expect anyway more because the same quark is repeated several time, after each gluon radiation + std::cerr << "Number of generated (anti)quarks " << checkPdgQuark << " lower than expected\n"; + return 1; + } + + if (nSignals < nEvents) { + std::cerr << "Number of generated signals lower than expected\n"; + return 1; + } + + if (checkHadronDecays > 0) { + std::cerr << "Decayed XiCplus, it should never decay\n"; + return 1; + } + + return 0; +} diff --git a/MC/config/PWGHF/ini/tests/GeneratorHF_D2H_bbbar_gap5.C b/MC/config/PWGHF/ini/tests/GeneratorHF_D2H_bbbar_gap5.C index 0dda90492..9d4e1574e 100644 --- a/MC/config/PWGHF/ini/tests/GeneratorHF_D2H_bbbar_gap5.C +++ b/MC/config/PWGHF/ini/tests/GeneratorHF_D2H_bbbar_gap5.C @@ -102,8 +102,9 @@ int External() return 1; } - float fracForcedDecays = float(nSignalGoodDecay) / nSignals; - if (fracForcedDecays < 0.9) { // we put some tolerance (e.g. due to oscillations which might change the final state) + float fracForcedDecays = nSignals ? float(nSignalGoodDecay) / nSignals : 0.0f; + float uncFracForcedDecays = nSignals ? std::sqrt(fracForcedDecays * (1 - fracForcedDecays) / nSignals) : 1.0f; + if (1 - fracForcedDecays > 0.15 + uncFracForcedDecays) { // we put some tolerance (e.g. due to oscillations which might change the final state) std::cerr << "Fraction of signals decaying into the correct channel " << fracForcedDecays << " lower than expected\n"; return 1; } diff --git a/MC/config/PWGHF/ini/tests/GeneratorHF_D2H_ccbar_Mode2_OmegaC.C b/MC/config/PWGHF/ini/tests/GeneratorHF_D2H_ccbar_Mode2_OmegaC.C index 081dfecae..5734e02da 100644 --- a/MC/config/PWGHF/ini/tests/GeneratorHF_D2H_ccbar_Mode2_OmegaC.C +++ b/MC/config/PWGHF/ini/tests/GeneratorHF_D2H_ccbar_Mode2_OmegaC.C @@ -95,8 +95,9 @@ int External() { return 1; } - float fracForcedDecays = float(nSignalGoodDecay) / nSignals; - if (fracForcedDecays < 0.9) { // we put some tolerance (e.g. due to oscillations which might change the final state) + float fracForcedDecays = nSignals ? float(nSignalGoodDecay) / nSignals : 0.0f; + float uncFracForcedDecays = nSignals ? std::sqrt(fracForcedDecays * (1 - fracForcedDecays) / nSignals) : 1.0f; + if (1 - fracForcedDecays > 0.15 + uncFracForcedDecays) { // we put some tolerance (e.g. due to oscillations which might change the final state) std::cerr << "Fraction of signals decaying into the correct channel " << fracForcedDecays << " lower than expected\n"; return 1; } diff --git a/MC/config/PWGHF/ini/tests/GeneratorHF_D2H_ccbar_Mode2_OmegaC_NoDecay.C b/MC/config/PWGHF/ini/tests/GeneratorHF_D2H_ccbar_Mode2_OmegaC_NoDecay.C new file mode 100644 index 000000000..58ef8cbf1 --- /dev/null +++ b/MC/config/PWGHF/ini/tests/GeneratorHF_D2H_ccbar_Mode2_OmegaC_NoDecay.C @@ -0,0 +1,83 @@ +int External() { + std::string path{"o2sim_Kine.root"}; + + int checkPdgQuark{4}; + + int checkPdgHadron{4332}; + int checkHadronDecays{0}; + + TFile file(path.c_str(), "READ"); + if (file.IsZombie()) { + std::cerr << "Cannot open ROOT file " << path << "\n"; + return 1; + } + + auto tree = (TTree *)file.Get("o2sim"); + std::vector *tracks{}; + tree->SetBranchAddress("MCTrack", &tracks); + o2::dataformats::MCEventHeader *eventHeader = nullptr; + tree->SetBranchAddress("MCEventHeader.", &eventHeader); + + int nEventsInj{}; + int nQuarks{}, nSignals{}; + auto nEvents = tree->GetEntries(); + + for (int i = 0; i < nEvents; i++) { + tree->GetEntry(i); + + // check subgenerator information + if (eventHeader->hasInfo(o2::mcgenid::GeneratorProperty::SUBGENERATORID)) { + bool isValid = false; + int subGeneratorId = eventHeader->getInfo(o2::mcgenid::GeneratorProperty::SUBGENERATORID, isValid); + if (subGeneratorId == checkPdgQuark) { + nEventsInj++; + } + } + + for (auto &track : *tracks) { + auto pdg = track.GetPdgCode(); + if (std::abs(pdg) == checkPdgQuark) { + nQuarks++; + continue; + } + if (std::abs(pdg) == checkPdgHadron) { // found signal + nSignals++; // count signal PDG + + for (int j{track.getFirstDaughterTrackId()}; j <= track.getLastDaughterTrackId(); ++j) { + if (j >= 0) { + checkHadronDecays += 1; + } + } + } + } + } + + std::cout << "--------------------------------\n"; + std::cout << "# Events: " << nEvents << "\n"; + std::cout << Form("# events injected with %d quark pair: ", checkPdgQuark) << nEventsInj << "\n"; + std::cout << Form("# %d (anti)quarks: ", checkPdgQuark) << nQuarks << "\n"; + std::cout <<"# signal hadrons: " << nSignals << "\n"; + std::cout <<"# signal hadrons decaying : " << checkHadronDecays << "\n"; + + if (nEventsInj < nEvents) { + std::cerr << "Number of generated events with triggered events different than expected\n"; + return 1; + } + + if (nQuarks < nEvents) { // we expect anyway more because the same quark is repeated several time, after each gluon radiation + std::cerr << "Number of generated (anti)quarks " << checkPdgQuark << " lower than expected\n"; + return 1; + } + + if (nSignals < nEvents) { + std::cerr << "Number of generated signals lower than expected\n"; + return 1; + } + + if (checkHadronDecays > 0) { + std::cerr << "Decayed OmegaC, it should never decay\n"; + return 1; + } + + return 0; +} diff --git a/MC/config/PWGHF/ini/tests/GeneratorHF_D2H_ccbar_Mode2_OmegaC_to_Omega.C b/MC/config/PWGHF/ini/tests/GeneratorHF_D2H_ccbar_Mode2_OmegaC_NoDecay_pp_ref.C similarity index 77% rename from MC/config/PWGHF/ini/tests/GeneratorHF_D2H_ccbar_Mode2_OmegaC_to_Omega.C rename to MC/config/PWGHF/ini/tests/GeneratorHF_D2H_ccbar_Mode2_OmegaC_NoDecay_pp_ref.C index 268a57174..81ea759b2 100644 --- a/MC/config/PWGHF/ini/tests/GeneratorHF_D2H_ccbar_Mode2_OmegaC_to_Omega.C +++ b/MC/config/PWGHF/ini/tests/GeneratorHF_D2H_ccbar_Mode2_OmegaC_NoDecay_pp_ref.C @@ -1,10 +1,10 @@ int External() { std::string path{"o2sim_Kine.root"}; - int checkPdgQuarkOne = 4; + int checkPdgQuark{4}; int checkPdgHadron{4332}; - int checkHadronDecays{3334}; + int checkHadronDecays{0}; TFile file(path.c_str(), "READ"); if (file.IsZombie()) { @@ -19,7 +19,7 @@ int External() { tree->SetBranchAddress("MCEventHeader.", &eventHeader); int nEventsInj{}; - int nQuarks{}, nSignals{}, nSignalGoodDecay{}; + int nQuarks{}, nSignals{}; auto nEvents = tree->GetEntries(); for (int i = 0; i < nEvents; i++) { @@ -44,10 +44,8 @@ int External() { nSignals++; // count signal PDG for (int j{track.getFirstDaughterTrackId()}; j <= track.getLastDaughterTrackId(); ++j) { - auto pdgDau = tracks->at(j).GetPdgCode(); - if (std::abs(pdgDau) == checkHadronDecays) { - nSignalGoodDecay; - break; + if (j >= 0) { + checkHadronDecays += 1; } } } @@ -59,7 +57,7 @@ int External() { std::cout << Form("# events injected with %d quark pair: ", checkPdgQuark) << nEventsInj << "\n"; std::cout << Form("# %d (anti)quarks: ", checkPdgQuark) << nQuarks << "\n"; std::cout <<"# signal hadrons: " << nSignals << "\n"; - std::cout <<"# signal hadrons decaying in the correct channel: " << nSignalGoodDecay << "\n"; + std::cout <<"# signal hadrons decaying : " << checkHadronDecays << "\n"; if (nEventsInj < nEvents) { std::cerr << "Number of generated events with triggered events different than expected\n"; @@ -76,11 +74,11 @@ int External() { return 1; } - float fracForcedDecays = float(nSignalGoodDecay) / nSignals; - if (fracForcedDecays < 0.9) { // we put some tolerance (it should not happen, but to be conservative) - std::cerr << "Fraction of signals decaying into the correct channel " << fracForcedDecays << " lower than expected\n"; + if (checkHadronDecays > 0) { + std::cerr << "Decayed OmegaC, it should never decay\n"; return 1; } return 0; } + diff --git a/MC/config/PWGHF/ini/tests/GeneratorHF_D2H_ccbar_Mode2_XiC0_XiCplus.C b/MC/config/PWGHF/ini/tests/GeneratorHF_D2H_ccbar_Mode2_XiC0_XiCplus.C index 9f999d474..17987c9a0 100644 --- a/MC/config/PWGHF/ini/tests/GeneratorHF_D2H_ccbar_Mode2_XiC0_XiCplus.C +++ b/MC/config/PWGHF/ini/tests/GeneratorHF_D2H_ccbar_Mode2_XiC0_XiCplus.C @@ -6,8 +6,17 @@ int External() { std::vector checkPdgHadron{4132, 4232}; std::map>> checkHadronDecays{ // sorted pdg of daughters - {4132, {{211, 3312}}}, // Xic0 - {4232, {{-313, 2212}, {-321, 3324}, {211, 211, 3312}, {-321, 211, 2212}}} // Xic+ + {4132, { + {3312, 211}, // Xic0 -> Xi-, pi+ + }}, + {4232, { + {2212, -321, 211}, // Xic+ -> p, K-, pi+ + {2212, -313}, // Xic+ -> p, Kbar^*(892)0 + {3312, 211, 211}, // Xic+ -> Xi-, pi+, pi+ + {2212, 333}, // Xic+ -> p, phi(1020)0 + {3222, -211, 211}, // Xic+ -> Sigma+, pi-, pi+ + {3324, 211}, // Xic+ -> Xi(1530)0, pi+ + }}, }; TFile file(path.c_str(), "READ"); @@ -65,6 +74,7 @@ int External() { std::sort(pdgsDecayAntiPart.begin(), pdgsDecayAntiPart.end()); for (auto &decay : checkHadronDecays[std::abs(pdg)]) { + std::sort(decay.begin(), decay.end()); if (pdgsDecay == decay || pdgsDecayAntiPart == decay) { nSignalGoodDecay++; break; @@ -96,8 +106,9 @@ int External() { return 1; } - float fracForcedDecays = float(nSignalGoodDecay) / nSignals; - if (fracForcedDecays < 0.9) { // we put some tolerance (e.g. due to oscillations which might change the final state) + float fracForcedDecays = nSignals ? float(nSignalGoodDecay) / nSignals : 0.0f; + float uncFracForcedDecays = nSignals ? std::sqrt(fracForcedDecays * (1 - fracForcedDecays) / nSignals) : 1.0f; + if (1 - fracForcedDecays > 0.15 + uncFracForcedDecays) { // we put some tolerance (e.g. due to oscillations which might change the final state) std::cerr << "Fraction of signals decaying into the correct channel " << fracForcedDecays << " lower than expected\n"; return 1; } diff --git a/MC/config/PWGHF/ini/tests/GeneratorHF_D2H_ccbar_Mode2_XiC_NoDecay.C b/MC/config/PWGHF/ini/tests/GeneratorHF_D2H_ccbar_Mode2_XiC_NoDecay.C new file mode 100644 index 000000000..b05f61cda --- /dev/null +++ b/MC/config/PWGHF/ini/tests/GeneratorHF_D2H_ccbar_Mode2_XiC_NoDecay.C @@ -0,0 +1,84 @@ +int External() { + std::string path{"o2sim_Kine.root"}; + + int checkPdgQuark{4}; + + int checkPdgHadron{4132}; + int checkHadronDecays{0}; + + TFile file(path.c_str(), "READ"); + if (file.IsZombie()) { + std::cerr << "Cannot open ROOT file " << path << "\n"; + return 1; + } + + auto tree = (TTree *)file.Get("o2sim"); + std::vector *tracks{}; + tree->SetBranchAddress("MCTrack", &tracks); + o2::dataformats::MCEventHeader *eventHeader = nullptr; + tree->SetBranchAddress("MCEventHeader.", &eventHeader); + + int nEventsInj{}; + int nQuarks{}, nSignals{}; + auto nEvents = tree->GetEntries(); + + for (int i = 0; i < nEvents; i++) { + tree->GetEntry(i); + + // check subgenerator information + if (eventHeader->hasInfo(o2::mcgenid::GeneratorProperty::SUBGENERATORID)) { + bool isValid = false; + int subGeneratorId = eventHeader->getInfo(o2::mcgenid::GeneratorProperty::SUBGENERATORID, isValid); + if (subGeneratorId == checkPdgQuark) { + nEventsInj++; + } + } + + for (auto &track : *tracks) { + auto pdg = track.GetPdgCode(); + if (std::abs(pdg) == checkPdgQuark) { + nQuarks++; + continue; + } + if (std::abs(pdg) == checkPdgHadron) { // found signal + nSignals++; // count signal PDG + + for (int j{track.getFirstDaughterTrackId()}; j <= track.getLastDaughterTrackId(); ++j) { + if (j >= 0) { + checkHadronDecays += 1; + } + } + } + } + } + + std::cout << "--------------------------------\n"; + std::cout << "# Events: " << nEvents << "\n"; + std::cout << Form("# events injected with %d quark pair: ", checkPdgQuark) << nEventsInj << "\n"; + std::cout << Form("# %d (anti)quarks: ", checkPdgQuark) << nQuarks << "\n"; + std::cout <<"# signal hadrons: " << nSignals << "\n"; + std::cout <<"# signal hadrons decaying : " << checkHadronDecays << "\n"; + + if (nEventsInj < nEvents) { + std::cerr << "Number of generated events with triggered events different than expected\n"; + return 1; + } + + if (nQuarks < nEvents) { // we expect anyway more because the same quark is repeated several time, after each gluon radiation + std::cerr << "Number of generated (anti)quarks " << checkPdgQuark << " lower than expected\n"; + return 1; + } + + if (nSignals < nEvents) { + std::cerr << "Number of generated signals lower than expected\n"; + return 1; + } + + if (checkHadronDecays > 0) { + std::cerr << "Decayed XiC, it should never decay\n"; + return 1; + } + + return 0; +} + diff --git a/MC/config/PWGHF/ini/tests/GeneratorHF_D2H_ccbar_Mode2_XiC_NoDecay_pp_ref.C b/MC/config/PWGHF/ini/tests/GeneratorHF_D2H_ccbar_Mode2_XiC_NoDecay_pp_ref.C new file mode 100644 index 000000000..b05f61cda --- /dev/null +++ b/MC/config/PWGHF/ini/tests/GeneratorHF_D2H_ccbar_Mode2_XiC_NoDecay_pp_ref.C @@ -0,0 +1,84 @@ +int External() { + std::string path{"o2sim_Kine.root"}; + + int checkPdgQuark{4}; + + int checkPdgHadron{4132}; + int checkHadronDecays{0}; + + TFile file(path.c_str(), "READ"); + if (file.IsZombie()) { + std::cerr << "Cannot open ROOT file " << path << "\n"; + return 1; + } + + auto tree = (TTree *)file.Get("o2sim"); + std::vector *tracks{}; + tree->SetBranchAddress("MCTrack", &tracks); + o2::dataformats::MCEventHeader *eventHeader = nullptr; + tree->SetBranchAddress("MCEventHeader.", &eventHeader); + + int nEventsInj{}; + int nQuarks{}, nSignals{}; + auto nEvents = tree->GetEntries(); + + for (int i = 0; i < nEvents; i++) { + tree->GetEntry(i); + + // check subgenerator information + if (eventHeader->hasInfo(o2::mcgenid::GeneratorProperty::SUBGENERATORID)) { + bool isValid = false; + int subGeneratorId = eventHeader->getInfo(o2::mcgenid::GeneratorProperty::SUBGENERATORID, isValid); + if (subGeneratorId == checkPdgQuark) { + nEventsInj++; + } + } + + for (auto &track : *tracks) { + auto pdg = track.GetPdgCode(); + if (std::abs(pdg) == checkPdgQuark) { + nQuarks++; + continue; + } + if (std::abs(pdg) == checkPdgHadron) { // found signal + nSignals++; // count signal PDG + + for (int j{track.getFirstDaughterTrackId()}; j <= track.getLastDaughterTrackId(); ++j) { + if (j >= 0) { + checkHadronDecays += 1; + } + } + } + } + } + + std::cout << "--------------------------------\n"; + std::cout << "# Events: " << nEvents << "\n"; + std::cout << Form("# events injected with %d quark pair: ", checkPdgQuark) << nEventsInj << "\n"; + std::cout << Form("# %d (anti)quarks: ", checkPdgQuark) << nQuarks << "\n"; + std::cout <<"# signal hadrons: " << nSignals << "\n"; + std::cout <<"# signal hadrons decaying : " << checkHadronDecays << "\n"; + + if (nEventsInj < nEvents) { + std::cerr << "Number of generated events with triggered events different than expected\n"; + return 1; + } + + if (nQuarks < nEvents) { // we expect anyway more because the same quark is repeated several time, after each gluon radiation + std::cerr << "Number of generated (anti)quarks " << checkPdgQuark << " lower than expected\n"; + return 1; + } + + if (nSignals < nEvents) { + std::cerr << "Number of generated signals lower than expected\n"; + return 1; + } + + if (checkHadronDecays > 0) { + std::cerr << "Decayed XiC, it should never decay\n"; + return 1; + } + + return 0; +} + diff --git a/MC/config/PWGHF/ini/tests/GeneratorHF_D2H_ccbar_Mode2_XiCplus_NoDecay.C b/MC/config/PWGHF/ini/tests/GeneratorHF_D2H_ccbar_Mode2_XiCplus_NoDecay.C new file mode 100644 index 000000000..a2b4d3499 --- /dev/null +++ b/MC/config/PWGHF/ini/tests/GeneratorHF_D2H_ccbar_Mode2_XiCplus_NoDecay.C @@ -0,0 +1,84 @@ +int External() { + std::string path{"o2sim_Kine.root"}; + + int checkPdgQuark = 4; + + int checkPdgHadron{4232}; + int checkHadronDecays{0}; + + TFile file(path.c_str(), "READ"); + if (file.IsZombie()) { + std::cerr << "Cannot open ROOT file " << path << "\n"; + return 1; + } + + auto tree = (TTree *)file.Get("o2sim"); + std::vector *tracks{}; + tree->SetBranchAddress("MCTrack", &tracks); + o2::dataformats::MCEventHeader *eventHeader = nullptr; + tree->SetBranchAddress("MCEventHeader.", &eventHeader); + + int nEventsInj{}; + int nQuarks{}, nSignals{}; + auto nEvents = tree->GetEntries(); + + for (int i = 0; i < nEvents; i++) { + tree->GetEntry(i); + + // check subgenerator information + if (eventHeader->hasInfo(o2::mcgenid::GeneratorProperty::SUBGENERATORID)) { + bool isValid = false; + int subGeneratorId = eventHeader->getInfo(o2::mcgenid::GeneratorProperty::SUBGENERATORID, isValid); + if (subGeneratorId == checkPdgQuark) { + nEventsInj++; + } + } + + for (auto &track : *tracks) { + auto pdg = track.GetPdgCode(); + if (std::abs(pdg) == checkPdgQuark) { + nQuarks++; + continue; + } + if (std::abs(pdg) == checkPdgHadron) { // found signal + nSignals++; // count signal PDG + + for (int j{track.getFirstDaughterTrackId()}; j <= track.getLastDaughterTrackId(); ++j) { + if (j >= 0) { + checkHadronDecays += 1; + } + } + } + } + } + + std::cout << "--------------------------------\n"; + std::cout << "# Events: " << nEvents << "\n"; + std::cout << Form("# events injected with %d quark pair: ", checkPdgQuark) << nEventsInj << "\n"; + std::cout << Form("# %d (anti)quarks: ", checkPdgQuark) << nQuarks << "\n"; + std::cout <<"# signal hadrons: " << nSignals << "\n"; + std::cout <<"# signal hadrons decaying : " << checkHadronDecays << "\n"; + + if (nEventsInj < nEvents) { + std::cerr << "Number of generated events with triggered events different than expected\n"; + return 1; + } + + if (nQuarks < nEvents) { // we expect anyway more because the same quark is repeated several time, after each gluon radiation + std::cerr << "Number of generated (anti)quarks " << checkPdgQuark << " lower than expected\n"; + return 1; + } + + if (nSignals < nEvents) { + std::cerr << "Number of generated signals lower than expected\n"; + return 1; + } + + if (checkHadronDecays > 0) { + std::cerr << "Decayed XiC, it should never decay\n"; + return 1; + } + + return 0; +} + diff --git a/MC/config/PWGHF/ini/tests/GeneratorHF_D2H_ccbar_Mode2_XiCplus_NoDecay_pp_ref.C b/MC/config/PWGHF/ini/tests/GeneratorHF_D2H_ccbar_Mode2_XiCplus_NoDecay_pp_ref.C new file mode 100644 index 000000000..f595aadd8 --- /dev/null +++ b/MC/config/PWGHF/ini/tests/GeneratorHF_D2H_ccbar_Mode2_XiCplus_NoDecay_pp_ref.C @@ -0,0 +1,84 @@ +int External() { + std::string path{"o2sim_Kine.root"}; + + int checkPdgQuark{4}; + + int checkPdgHadron{4232}; + int checkHadronDecays{0}; + + TFile file(path.c_str(), "READ"); + if (file.IsZombie()) { + std::cerr << "Cannot open ROOT file " << path << "\n"; + return 1; + } + + auto tree = (TTree *)file.Get("o2sim"); + std::vector *tracks{}; + tree->SetBranchAddress("MCTrack", &tracks); + o2::dataformats::MCEventHeader *eventHeader = nullptr; + tree->SetBranchAddress("MCEventHeader.", &eventHeader); + + int nEventsInj{}; + int nQuarks{}, nSignals{}; + auto nEvents = tree->GetEntries(); + + for (int i = 0; i < nEvents; i++) { + tree->GetEntry(i); + + // check subgenerator information + if (eventHeader->hasInfo(o2::mcgenid::GeneratorProperty::SUBGENERATORID)) { + bool isValid = false; + int subGeneratorId = eventHeader->getInfo(o2::mcgenid::GeneratorProperty::SUBGENERATORID, isValid); + if (subGeneratorId == checkPdgQuark) { + nEventsInj++; + } + } + + for (auto &track : *tracks) { + auto pdg = track.GetPdgCode(); + if (std::abs(pdg) == checkPdgQuark) { + nQuarks++; + continue; + } + if (std::abs(pdg) == checkPdgHadron) { // found signal + nSignals++; // count signal PDG + + for (int j{track.getFirstDaughterTrackId()}; j <= track.getLastDaughterTrackId(); ++j) { + if (j >= 0) { + checkHadronDecays += 1; + } + } + } + } + } + + std::cout << "--------------------------------\n"; + std::cout << "# Events: " << nEvents << "\n"; + std::cout << Form("# events injected with %d quark pair: ", checkPdgQuark) << nEventsInj << "\n"; + std::cout << Form("# %d (anti)quarks: ", checkPdgQuark) << nQuarks << "\n"; + std::cout <<"# signal hadrons: " << nSignals << "\n"; + std::cout <<"# signal hadrons decaying : " << checkHadronDecays << "\n"; + + if (nEventsInj < nEvents) { + std::cerr << "Number of generated events with triggered events different than expected\n"; + return 1; + } + + if (nQuarks < nEvents) { // we expect anyway more because the same quark is repeated several time, after each gluon radiation + std::cerr << "Number of generated (anti)quarks " << checkPdgQuark << " lower than expected\n"; + return 1; + } + + if (nSignals < nEvents) { + std::cerr << "Number of generated signals lower than expected\n"; + return 1; + } + + if (checkHadronDecays > 0) { + std::cerr << "Decayed XiCplus, it should never decay\n"; + return 1; + } + + return 0; +} + diff --git a/MC/config/PWGHF/ini/tests/GeneratorHF_D2H_ccbar_and_bbbar_Mode2_ptHardBins.C b/MC/config/PWGHF/ini/tests/GeneratorHF_D2H_ccbar_and_bbbar_Mode2_ptHardBins.C index 0177751d0..4a3fba732 100644 --- a/MC/config/PWGHF/ini/tests/GeneratorHF_D2H_ccbar_and_bbbar_Mode2_ptHardBins.C +++ b/MC/config/PWGHF/ini/tests/GeneratorHF_D2H_ccbar_and_bbbar_Mode2_ptHardBins.C @@ -68,7 +68,7 @@ int External() { for (int j{track.getFirstDaughterTrackId()}; j <= track.getLastDaughterTrackId(); ++j) { auto pdgDau = tracks->at(j).GetPdgCode(); pdgsDecay.push_back(pdgDau); - if (pdgDau != 333) { // phi is antiparticle of itself + if (pdgDau != 333 && pdgDau != 111) { // phi is antiparticle of itself pdgsDecayAntiPart.push_back(-pdgDau); } else { pdgsDecayAntiPart.push_back(pdgDau); @@ -123,13 +123,14 @@ int External() { return 1; } - float fracForcedDecays = float(nSignalGoodDecay) / nSignals; - if (fracForcedDecays < 0.9) { // we put some tolerance (e.g. due to oscillations which might change the final state) + float fracForcedDecays = nSignals ? float(nSignalGoodDecay) / nSignals : 0.0f; + float uncFracForcedDecays = nSignals ? std::sqrt(fracForcedDecays * (1 - fracForcedDecays) / nSignals) : 1.0f; + if (1 - fracForcedDecays > 0.15 + uncFracForcedDecays) { // we put some tolerance (e.g. due to oscillations which might change the final state) std::cerr << "Fraction of signals decaying into the correct channel " << fracForcedDecays << " lower than expected\n"; return 1; } - if (averagePt < 8.) { // by testing locally it should be around 8.5 GeV/c with pthard bin 20-200 (contrary to 2-2.5 GeV/c of SoftQCD) + if (averagePt < 6) { // by testing locally it should be around 8.5 GeV/c with pthard bin 20-200 (contrary to 2-2.5 GeV/c of SoftQCD) std::cerr << "Average pT of charmed hadrons " << averagePt << " lower than expected\n"; return 1; } diff --git a/MC/config/PWGHF/ini/tests/GeneratorHF_D2H_ccbar_and_bbbar_PbPb.C b/MC/config/PWGHF/ini/tests/GeneratorHF_D2H_ccbar_and_bbbar_PbPb.C index 497b80acd..0edd85513 100644 --- a/MC/config/PWGHF/ini/tests/GeneratorHF_D2H_ccbar_and_bbbar_PbPb.C +++ b/MC/config/PWGHF/ini/tests/GeneratorHF_D2H_ccbar_and_bbbar_PbPb.C @@ -8,13 +8,74 @@ int External() { std::vector checkPdgHadron{411, 421, 431, 4122, 4132, 4232, 4332}; std::map>> checkHadronDecays{ // sorted pdg of daughters - {411, {{-321, 211, 211}, {-313, 211}, {211, 311}, {211, 333}}}, // D+ - {421, {{-321, 211}, {-321, 111, 211}}}, // D0 - {431, {{211, 333}, {-313, 321}}}, // Ds+ - {4122, {{-313, 2212}, {-321, 2224}, {211, 102134}, {-321, 211, 2212}, {311, 2212}}}, // Lc+ - {4132, {{211, 3312}}}, // Xic0 - {4232, {{-313, 2212}, {-321, 3324}, {211, 211, 3312}, {-321, 211, 2212}}}, // Xic+ - {4332, {{211, 3334}}} // Omegac+ + {421, { + {-321, 211}, // D0 -> K-, pi+ + {-321, 211, 111}, // D0 -> K-, pi+, pi0 + {213, -321}, // D0 -> rho(770)+, K- + {-313, 111}, // D0 -> Kbar^*(892)0, pi0 + {-323, 211}, // D0 -> K^*(892)-, pi+ + {-211, 211}, // D0 -> pi-, pi+ + {213, -211}, // D0 -> rho(770)+, pi- + {-211, 211, 111}, // D0 -> pi-, pi+, pi0 + {-321, 321}, // D0 -> K-, K+ + }}, + + {411, { + {-321, 211, 211}, // D+ -> K-, pi+, pi+ + {-10311, 211}, // D+ -> Kbar0^*(1430)0, pi+ + {-313, 211}, // D+ -> Kbar^*(892)0, pi+ + {-321, 211, 211, 111}, // D+ -> K-, pi+, pi+, pi0 + {333, 211}, // D+ -> phi(1020)0, pi+ + {-313, 321}, // D+ -> Kbar^*(892)0, K+ + {-10311, 321}, // D+ -> Kbar0^*(1430)0, K+ + {-321, 321, 211}, // D+ -> K-, K+, pi+ + {113, 211}, // D+ -> rho(770)0, pi+ + {225, 211}, // D+ -> f2(1270)0, pi+ + {-211, 211, 211}, // D+ -> pi-, pi+, pi+ + }}, + + {431, { + {333, 211}, // Ds+ -> phi(1020)0, pi+ + {-313, 321}, // Ds+ -> Kbar^*(892)0, K+ + {333, 213}, // Ds+ -> phi(1020)0, rho(770)+ + {113, 211}, // Ds+ -> rho(770)0, pi+ + {225, 211}, // Ds+ -> f2(1270)0, pi+ + {-211, 211, 211}, // Ds+ -> pi-, pi+, pi+ + {313, 211}, // Ds+ -> K^*(892)0, pi+ + {10221, 321}, // Ds+ -> f0(1370)0, K+ + {113, 321}, // Ds+ -> rho(770)0, K+ + {-211, 321, 211}, // Ds+ -> pi-, K+, pi+ + {221, 211}, // Ds+ -> eta, pi+ + }}, + + {4122, { + {2212, -321, 211}, // Lambdac+ -> p, K-, pi+ + {2212, -313}, // Lambdac+ -> p, Kbar^*(892)0 + {2224, -321}, // Lambdac+ -> Delta(1232)++, K- + {102134, 211}, // Lambdac+ -> 102134, pi+ + {2212, 311}, // Lambdac+ -> p, K0 + {2212, -321, 211, 111}, // Lambdac+ -> p, K-, pi+, pi0 + {2212, -211, 211}, // Lambdac+ -> p, pi-, pi+ + {2212, 333}, // Lambdac+ -> p, phi(1020)0 + }}, + + {4232, { + {2212, -321, 211}, // Xic+ -> p, K-, pi+ + {2212, -313}, // Xic+ -> p, Kbar^*(892)0 + {3312, 211, 211}, // Xic+ -> Xi-, pi+, pi+ + {2212, 333}, // Xic+ -> p, phi(1020)0 + {3222, -211, 211}, // Xic+ -> Sigma+, pi-, pi+ + {3324, 211}, // Xic+ -> Xi(1530)0, pi+ + }}, + + {4132, { + {3312, 211}, // Xic0 -> Xi-, pi+ + }}, + + {4332, { + {3334, 211}, // Omegac0 -> Omega-, pi+ + {3312, 211}, // Omegac0 -> Xi-, pi+ + }}, }; TFile file(path.c_str(), "READ"); @@ -67,7 +128,7 @@ int External() { for (int j{track.getFirstDaughterTrackId()}; j <= track.getLastDaughterTrackId(); ++j) { auto pdgDau = tracks->at(j).GetPdgCode(); pdgsDecay.push_back(pdgDau); - if (pdgDau != 333) { // phi is antiparticle of itself + if (pdgDau != 333 && pdgDau != 111 && pdgDau != 221 && pdgDau != 113 && pdgDau != 225) { // phi is antiparticle of itself pdgsDecayAntiPart.push_back(-pdgDau); } else { pdgsDecayAntiPart.push_back(pdgDau); @@ -78,6 +139,7 @@ int External() { std::sort(pdgsDecayAntiPart.begin(), pdgsDecayAntiPart.end()); for (auto &decay : checkHadronDecays[std::abs(pdg)]) { + std::sort(decay.begin(), decay.end()); if (pdgsDecay == decay || pdgsDecayAntiPart == decay) { nSignalGoodDecay++; break; @@ -119,8 +181,9 @@ int External() { return 1; } - float fracForcedDecays = float(nSignalGoodDecay) / nSignals; - if (fracForcedDecays < 0.9) { // we put some tolerance (e.g. due to oscillations which might change the final state) + float fracForcedDecays = nSignals ? float(nSignalGoodDecay) / nSignals : 0.0f; + float uncFracForcedDecays = nSignals ? std::sqrt(fracForcedDecays * (1 - fracForcedDecays) / nSignals) : 1.0f; + if (1 - fracForcedDecays > 0.15 + uncFracForcedDecays) { // we put some tolerance (e.g. due to oscillations which might change the final state) std::cerr << "Fraction of signals decaying into the correct channel " << fracForcedDecays << " lower than expected\n"; return 1; } diff --git a/MC/config/PWGHF/ini/tests/GeneratorHF_D2H_ccbar_and_bbbar_PbPb_corrBkg.C b/MC/config/PWGHF/ini/tests/GeneratorHF_D2H_ccbar_and_bbbar_PbPb_corrBkg.C new file mode 100644 index 000000000..be57a1439 --- /dev/null +++ b/MC/config/PWGHF/ini/tests/GeneratorHF_D2H_ccbar_and_bbbar_PbPb_corrBkg.C @@ -0,0 +1,183 @@ +int External() { + std::string path{"o2sim_Kine.root"}; + //std::string path{"tf1/sgn_1_Kine.root"}; + + int checkPdgQuarkOne{4}; + int checkPdgQuarkTwo{5}; + float ratioTrigger = 1.; // one event triggered out of 1 + + std::vector checkPdgHadron{411, 421, 431, 4122, 4232}; + std::map>> checkHadronDecays{ // sorted pdg of daughters + {421, { + {-321, 211}, // D0 -> K-, pi+ + {-321, 211, 111}, // D0 -> K-, pi+, pi0 + {213, -321}, // D0 -> rho(770)+, K- + {-313, 111}, // D0 -> Kbar^*(892)0, pi0 + {-323, 211}, // D0 -> K^*(892)-, pi+ + {-211, 211}, // D0 -> pi-, pi+ + {213, -211}, // D0 -> rho(770)+, pi- + {-211, 211, 111}, // D0 -> pi-, pi+, pi0 + {-321, 321}, // D0 -> K-, K+ + }}, + + {411, { + {-321, 211, 211}, // D+ -> K-, pi+, pi+ + {-10311, 211}, // D+ -> Kbar0^*(1430)0, pi+ + {-313, 211}, // D+ -> Kbar^*(892)0, pi+ + {-321, 211, 211, 111}, // D+ -> K-, pi+, pi+, pi0 + {333, 211}, // D+ -> phi(1020)0, pi+ + {-313, 321}, // D+ -> Kbar^*(892)0, K+ + {-10311, 321}, // D+ -> Kbar0^*(1430)0, K+ + {-321, 321, 211}, // D+ -> K-, K+, pi+ + {113, 211}, // D+ -> rho(770)0, pi+ + {225, 211}, // D+ -> f2(1270)0, pi+ + {-211, 211, 211}, // D+ -> pi-, pi+, pi+ + }}, + + {431, { + {333, 211}, // Ds+ -> phi(1020)0, pi+ + {-313, 321}, // Ds+ -> Kbar^*(892)0, K+ + {333, 213}, // Ds+ -> phi(1020)0, rho(770)+ + {113, 211}, // Ds+ -> rho(770)0, pi+ + {225, 211}, // Ds+ -> f2(1270)0, pi+ + {-211, 211, 211}, // Ds+ -> pi-, pi+, pi+ + {313, 211}, // Ds+ -> K^*(892)0, pi+ + {10221, 321}, // Ds+ -> f0(1370)0, K+ + {113, 321}, // Ds+ -> rho(770)0, K+ + {-211, 321, 211}, // Ds+ -> pi-, K+, pi+ + {221, 211}, // Ds+ -> eta, pi+ + }}, + + {4122, { + {2212, -321, 211}, // Lambdac+ -> p, K-, pi+ + {2212, -313}, // Lambdac+ -> p, Kbar^*(892)0 + {2224, -321}, // Lambdac+ -> Delta(1232)++, K- + {102134, 211}, // Lambdac+ -> 102134, pi+ + {2212, 311}, // Lambdac+ -> p, K0 + {2212, -321, 211, 111}, // Lambdac+ -> p, K-, pi+, pi0 + {2212, -211, 211}, // Lambdac+ -> p, pi-, pi+ + {2212, 333}, // Lambdac+ -> p, phi(1020)0 + }}, + + {4232, { + {2212, -321, 211}, // Xic+ -> p, K-, pi+ + {2212, -313}, // Xic+ -> p, Kbar^*(892)0 + {3312, 211, 211}, // Xic+ -> Xi-, pi+, pi+ + {2212, 333}, // Xic+ -> p, phi(1020)0 + {3222, -211, 211}, // Xic+ -> Sigma+, pi-, pi+ + {3324, 211}, // Xic+ -> Xi(1530)0, pi+ + }}, + }; + + TFile file(path.c_str(), "READ"); + if (file.IsZombie()) { + std::cerr << "Cannot open ROOT file " << path << "\n"; + return 1; + } + + auto tree = (TTree *)file.Get("o2sim"); + std::vector *tracks{}; + tree->SetBranchAddress("MCTrack", &tracks); + o2::dataformats::MCEventHeader *eventHeader = nullptr; + tree->SetBranchAddress("MCEventHeader.", &eventHeader); + + int nEventsMB{}, nEventsInjOne{}, nEventsInjTwo{}; + int nQuarksOne{}, nQuarksTwo{}, nSignals{}, nSignalGoodDecay{}; + auto nEvents = tree->GetEntries(); + + for (int i = 0; i < nEvents; i++) { + tree->GetEntry(i); + + // check subgenerator information + //if (eventHeader->hasInfo(o2::mcgenid::GeneratorProperty::SUBGENERATORID)) { + // bool isValid = false; + // int subGeneratorId = eventHeader->getInfo(o2::mcgenid::GeneratorProperty::SUBGENERATORID, isValid); + // if (subGeneratorId == 0) { + // nEventsMB++; + // } else if (subGeneratorId == checkPdgQuarkOne) { + // nEventsInjOne++; + // } else if (subGeneratorId == checkPdgQuarkTwo) { + // nEventsInjTwo++; + // } + //} + + for (auto &track : *tracks) { + auto pdg = track.GetPdgCode(); + if (std::abs(pdg) == checkPdgQuarkOne) { + nQuarksOne++; + continue; + } + if (std::abs(pdg) == checkPdgQuarkTwo) { + nQuarksTwo++; + continue; + } + if (std::find(checkPdgHadron.begin(), checkPdgHadron.end(), std::abs(pdg)) != checkPdgHadron.end()) { // found signal + nSignals++; // count signal PDG + + std::vector pdgsDecay{}; + std::vector pdgsDecayAntiPart{}; + for (int j{track.getFirstDaughterTrackId()}; j <= track.getLastDaughterTrackId(); ++j) { + auto pdgDau = tracks->at(j).GetPdgCode(); + pdgsDecay.push_back(pdgDau); + if (pdgDau != 333 && pdgDau != 111 && pdgDau != 221 && pdgDau != 113 && pdgDau != 225) { // phi is antiparticle of itself + pdgsDecayAntiPart.push_back(-pdgDau); + } else { + pdgsDecayAntiPart.push_back(pdgDau); + } + } + + std::sort(pdgsDecay.begin(), pdgsDecay.end()); + std::sort(pdgsDecayAntiPart.begin(), pdgsDecayAntiPart.end()); + + for (auto &decay : checkHadronDecays[std::abs(pdg)]) { + std::sort(decay.begin(), decay.end()); + if (pdgsDecay == decay || pdgsDecayAntiPart == decay) { + nSignalGoodDecay++; + break; + } + } + } + } + } + + std::cout << "--------------------------------\n"; + std::cout << "# Events: " << nEvents << "\n"; + //std::cout << "# MB events: " << nEventsMB << "\n"; + //std::cout << Form("# events injected with %d quark pair: ", checkPdgQuarkOne) << nEventsInjOne << "\n"; + //std::cout << Form("# events injected with %d quark pair: ", checkPdgQuarkTwo) << nEventsInjTwo << "\n"; + std::cout << Form("# %d (anti)quarks: ", checkPdgQuarkOne) << nQuarksOne << "\n"; + std::cout << Form("# %d (anti)quarks: ", checkPdgQuarkTwo) << nQuarksTwo << "\n"; + std::cout <<"# signal hadrons: " << nSignals << "\n"; + std::cout <<"# signal hadrons decaying in the correct channel: " << nSignalGoodDecay << "\n"; + + //if (nEventsMB < nEvents * (1 - ratioTrigger) * 0.95 || nEventsMB > nEvents * (1 - ratioTrigger) * 1.05) { // we put some tolerance since the number of generated events is small + // std::cerr << "Number of generated MB events different than expected\n"; + // return 1; + //} + //if (nEventsInjOne < nEvents * ratioTrigger * 0.5 * 0.95 || nEventsInjOne > nEvents * ratioTrigger * 0.5 * 1.05) { + // std::cerr << "Number of generated events injected with " << checkPdgQuarkOne << " different than expected\n"; + // return 1; + //} + //if (nEventsInjTwo < nEvents * ratioTrigger * 0.5 * 0.95 || nEventsInjTwo > nEvents * ratioTrigger * 0.5 * 1.05) { + // std::cerr << "Number of generated events injected with " << checkPdgQuarkTwo << " different than expected\n"; + // return 1; + //} + + if (nQuarksOne < nEvents * ratioTrigger) { // we expect anyway more because the same quark is repeated several time, after each gluon radiation + std::cerr << "Number of generated (anti)quarks " << checkPdgQuarkOne << " lower than expected\n"; + return 1; + } + if (nQuarksTwo < nEvents * ratioTrigger) { // we expect anyway more because the same quark is repeated several time, after each gluon radiation + std::cerr << "Number of generated (anti)quarks " << checkPdgQuarkTwo << " lower than expected\n"; + return 1; + } + + float fracForcedDecays = nSignals ? float(nSignalGoodDecay) / nSignals : 0.0f; + float uncFracForcedDecays = nSignals ? std::sqrt(fracForcedDecays * (1 - fracForcedDecays) / nSignals) : 1.0f; + if (1 - fracForcedDecays > 0.15 + uncFracForcedDecays) { // we put some tolerance (e.g. due to oscillations which might change the final state) + std::cerr << "Fraction of signals decaying into the correct channel " << fracForcedDecays << " lower than expected\n"; + return 1; + } + + return 0; +} diff --git a/MC/config/PWGHF/ini/tests/GeneratorHF_D2H_ccbar_and_bbbar_PbPb_ptHardBins.C b/MC/config/PWGHF/ini/tests/GeneratorHF_D2H_ccbar_and_bbbar_PbPb_ptHardBins.C index 112cda1f4..0edd85513 100644 --- a/MC/config/PWGHF/ini/tests/GeneratorHF_D2H_ccbar_and_bbbar_PbPb_ptHardBins.C +++ b/MC/config/PWGHF/ini/tests/GeneratorHF_D2H_ccbar_and_bbbar_PbPb_ptHardBins.C @@ -5,17 +5,77 @@ int External() { int checkPdgQuarkOne{4}; int checkPdgQuarkTwo{5}; float ratioTrigger = 1.; // one event triggered out of 1 - float averagePt = 0.; std::vector checkPdgHadron{411, 421, 431, 4122, 4132, 4232, 4332}; std::map>> checkHadronDecays{ // sorted pdg of daughters - {411, {{-321, 211, 211}, {-313, 211}, {211, 311}, {211, 333}}}, // D+ - {421, {{-321, 211}, {-321, 111, 211}}}, // D0 - {431, {{211, 333}, {-313, 321}}}, // Ds+ - {4122, {{-313, 2212}, {-321, 2224}, {211, 102134}, {-321, 211, 2212}, {311, 2212}}}, // Lc+ - {4132, {{211, 3312}}}, // Xic0 - {4232, {{-313, 2212}, {-321, 3324}, {211, 211, 3312}, {-321, 211, 2212}}}, // Xic+ - {4332, {{211, 3334}}} // Omegac+ + {421, { + {-321, 211}, // D0 -> K-, pi+ + {-321, 211, 111}, // D0 -> K-, pi+, pi0 + {213, -321}, // D0 -> rho(770)+, K- + {-313, 111}, // D0 -> Kbar^*(892)0, pi0 + {-323, 211}, // D0 -> K^*(892)-, pi+ + {-211, 211}, // D0 -> pi-, pi+ + {213, -211}, // D0 -> rho(770)+, pi- + {-211, 211, 111}, // D0 -> pi-, pi+, pi0 + {-321, 321}, // D0 -> K-, K+ + }}, + + {411, { + {-321, 211, 211}, // D+ -> K-, pi+, pi+ + {-10311, 211}, // D+ -> Kbar0^*(1430)0, pi+ + {-313, 211}, // D+ -> Kbar^*(892)0, pi+ + {-321, 211, 211, 111}, // D+ -> K-, pi+, pi+, pi0 + {333, 211}, // D+ -> phi(1020)0, pi+ + {-313, 321}, // D+ -> Kbar^*(892)0, K+ + {-10311, 321}, // D+ -> Kbar0^*(1430)0, K+ + {-321, 321, 211}, // D+ -> K-, K+, pi+ + {113, 211}, // D+ -> rho(770)0, pi+ + {225, 211}, // D+ -> f2(1270)0, pi+ + {-211, 211, 211}, // D+ -> pi-, pi+, pi+ + }}, + + {431, { + {333, 211}, // Ds+ -> phi(1020)0, pi+ + {-313, 321}, // Ds+ -> Kbar^*(892)0, K+ + {333, 213}, // Ds+ -> phi(1020)0, rho(770)+ + {113, 211}, // Ds+ -> rho(770)0, pi+ + {225, 211}, // Ds+ -> f2(1270)0, pi+ + {-211, 211, 211}, // Ds+ -> pi-, pi+, pi+ + {313, 211}, // Ds+ -> K^*(892)0, pi+ + {10221, 321}, // Ds+ -> f0(1370)0, K+ + {113, 321}, // Ds+ -> rho(770)0, K+ + {-211, 321, 211}, // Ds+ -> pi-, K+, pi+ + {221, 211}, // Ds+ -> eta, pi+ + }}, + + {4122, { + {2212, -321, 211}, // Lambdac+ -> p, K-, pi+ + {2212, -313}, // Lambdac+ -> p, Kbar^*(892)0 + {2224, -321}, // Lambdac+ -> Delta(1232)++, K- + {102134, 211}, // Lambdac+ -> 102134, pi+ + {2212, 311}, // Lambdac+ -> p, K0 + {2212, -321, 211, 111}, // Lambdac+ -> p, K-, pi+, pi0 + {2212, -211, 211}, // Lambdac+ -> p, pi-, pi+ + {2212, 333}, // Lambdac+ -> p, phi(1020)0 + }}, + + {4232, { + {2212, -321, 211}, // Xic+ -> p, K-, pi+ + {2212, -313}, // Xic+ -> p, Kbar^*(892)0 + {3312, 211, 211}, // Xic+ -> Xi-, pi+, pi+ + {2212, 333}, // Xic+ -> p, phi(1020)0 + {3222, -211, 211}, // Xic+ -> Sigma+, pi-, pi+ + {3324, 211}, // Xic+ -> Xi(1530)0, pi+ + }}, + + {4132, { + {3312, 211}, // Xic0 -> Xi-, pi+ + }}, + + {4332, { + {3334, 211}, // Omegac0 -> Omega-, pi+ + {3312, 211}, // Omegac0 -> Xi-, pi+ + }}, }; TFile file(path.c_str(), "READ"); @@ -62,14 +122,13 @@ int External() { } if (std::find(checkPdgHadron.begin(), checkPdgHadron.end(), std::abs(pdg)) != checkPdgHadron.end()) { // found signal nSignals++; // count signal PDG - averagePt += track.GetPt(); std::vector pdgsDecay{}; std::vector pdgsDecayAntiPart{}; for (int j{track.getFirstDaughterTrackId()}; j <= track.getLastDaughterTrackId(); ++j) { auto pdgDau = tracks->at(j).GetPdgCode(); pdgsDecay.push_back(pdgDau); - if (pdgDau != 333) { // phi is antiparticle of itself + if (pdgDau != 333 && pdgDau != 111 && pdgDau != 221 && pdgDau != 113 && pdgDau != 225) { // phi is antiparticle of itself pdgsDecayAntiPart.push_back(-pdgDau); } else { pdgsDecayAntiPart.push_back(pdgDau); @@ -80,6 +139,7 @@ int External() { std::sort(pdgsDecayAntiPart.begin(), pdgsDecayAntiPart.end()); for (auto &decay : checkHadronDecays[std::abs(pdg)]) { + std::sort(decay.begin(), decay.end()); if (pdgsDecay == decay || pdgsDecayAntiPart == decay) { nSignalGoodDecay++; break; @@ -89,8 +149,6 @@ int External() { } } - averagePt /= nSignals; - std::cout << "--------------------------------\n"; std::cout << "# Events: " << nEvents << "\n"; //std::cout << "# MB events: " << nEventsMB << "\n"; @@ -100,7 +158,6 @@ int External() { std::cout << Form("# %d (anti)quarks: ", checkPdgQuarkTwo) << nQuarksTwo << "\n"; std::cout <<"# signal hadrons: " << nSignals << "\n"; std::cout <<"# signal hadrons decaying in the correct channel: " << nSignalGoodDecay << "\n"; - std::cout <<"average pT of signal hadrons: " << averagePt << "\n"; //if (nEventsMB < nEvents * (1 - ratioTrigger) * 0.95 || nEventsMB > nEvents * (1 - ratioTrigger) * 1.05) { // we put some tolerance since the number of generated events is small // std::cerr << "Number of generated MB events different than expected\n"; @@ -124,8 +181,9 @@ int External() { return 1; } - float fracForcedDecays = float(nSignalGoodDecay) / nSignals; - if (fracForcedDecays < 0.9) { // we put some tolerance (e.g. due to oscillations which might change the final state) + float fracForcedDecays = nSignals ? float(nSignalGoodDecay) / nSignals : 0.0f; + float uncFracForcedDecays = nSignals ? std::sqrt(fracForcedDecays * (1 - fracForcedDecays) / nSignals) : 1.0f; + if (1 - fracForcedDecays > 0.15 + uncFracForcedDecays) { // we put some tolerance (e.g. due to oscillations which might change the final state) std::cerr << "Fraction of signals decaying into the correct channel " << fracForcedDecays << " lower than expected\n"; return 1; } diff --git a/MC/config/PWGHF/ini/tests/GeneratorHF_D2H_ccbar_and_bbbar_PbPb_replaced.C b/MC/config/PWGHF/ini/tests/GeneratorHF_D2H_ccbar_and_bbbar_PbPb_replaced.C new file mode 100644 index 000000000..ac01f2afc --- /dev/null +++ b/MC/config/PWGHF/ini/tests/GeneratorHF_D2H_ccbar_and_bbbar_PbPb_replaced.C @@ -0,0 +1,210 @@ +int External() { + std::string path{"o2sim_Kine.root"}; + //std::string path{"tf1/sgn_Kine.root"}; + + // Particle replacement configuration: {original, replacement}, frequencies + std::array, 3> pdgReplParticles = { + std::array{423, 4132}, // D*0 -> Xic0 + std::array{423, 4232}, // D*0 -> Xic+ + std::array{4212, 4332} // Sigmac+ -> Omegac0 + }; + std::array, 3> pdgReplPartCounters = { + std::array{0, 0}, + std::array{0, 0}, + std::array{0, 0} + }; + std::array freqRepl = {0.5, 0.5, 1.0}; + std::map sumOrigReplacedParticles = {{423, 0}, {4212, 0}}; + + // Signal hadrons to check (only final charm baryons after replacement) + std::array checkPdgHadron{4122, 4132, 4232, 4332}; + + // Expected decay channels - will be sorted automatically + // Define both particle and antiparticle versions + std::map>> checkHadronDecaysRaw{ + // Λc+ decays (from cfg: 4122:addChannel + resonance decays) + {4122, { + {2212, 311}, {-2212, -311}, // p K0s + {2212, -321, 211}, {-2212, 321, -211}, // p K- π+ (non-resonant) + {2212, 313}, {-2212, -313}, // p K*0 (not decayed) + {2212, 321, 211}, {-2212, -321, -211}, // p K*0 -> p (K- π+) [K*0 decayed] + {2224, -321}, {-2224, 321}, // Delta++ K- (not decayed) + {2212, 211, -321}, {-2212, -211, 321}, // Delta++ K- -> (p π+) K- [Delta decayed] + {102134, 211}, {-102134, -211}, // Lambda(1520) π+ (not decayed) + {2212, 321, 211}, {-2212, -321, -211}, // Lambda(1520) π+ -> (p K-) π+ [Lambda* decayed] + {2212, -321, 211, 111}, {-2212, 321, -211, 111}, // p K- π+ π0 + {2212, -211, 211}, {-2212, 211, -211}, // p π- π+ (cfg line 61: 2212 -211 211) + {2212, 333}, {-2212, 333}, // p φ (not decayed) + {2212, 321, -321}, {-2212, -321, 321} // p φ -> p (K+ K-) [φ decayed] + }}, + // Ξc0 decays (from cfg: 4132:onIfMatch) + {4132, { + {3312, 211}, {-3312, -211}, // Ξ- π+ + {3334, 321}, {-3334, -321} // Ω- K+ + }}, + // Ξc+ decays (from cfg: 4232:onIfMatch + resonance decays) + {4232, { + {2212, -321, 211}, {-2212, 321, -211}, // p K- π+ + {2212, -313}, {-2212, 313}, // p K̄*0 (not decayed) + {2212, -321, 211}, {-2212, 321, -211}, // p K̄*0 -> p (K+ π-) [K*0 decayed] + {2212, 333}, {-2212, 333}, // p φ (not decayed) + {2212, 321, -321}, {-2212, -321, 321}, // p φ -> p (K+ K-) [φ decayed] + {3222, -211, 211}, {-3222, 211, -211}, // Σ+ π- π+ + {3324, 211}, {-3324, -211}, // Ξ*0 π+ + {3312, 211, 211}, {-3312, -211, -211} // Ξ- π+ π+ + }}, + // Ωc0 decays (from cfg: 4332:onIfMatch) + {4332, { + {3334, 211}, {-3334, -211}, // Ω- π+ + {3312, 211}, {-3312, -211}, // Ξ- π+ + {3334, 321}, {-3334, -321} // Ω- K+ + }} + }; + + // Sort all decay channels + std::map>> checkHadronDecays; + for (auto &[pdg, decays] : checkHadronDecaysRaw) { + for (auto decay : decays) { + std::sort(decay.begin(), decay.end()); + checkHadronDecays[pdg].push_back(decay); + } + } + + TFile file(path.c_str(), "READ"); + if (file.IsZombie()) + { + std::cerr << "Cannot open ROOT file " << path << "\n"; + return 1; + } + + auto tree = (TTree *)file.Get("o2sim"); + std::vector *tracks{}; + tree->SetBranchAddress("MCTrack", &tracks); + + int nSignals{}, nSignalGoodDecay{}; + std::map failedDecayCount{{4122, 0}, {4132, 0}, {4232, 0}, {4332, 0}}; + std::map>> unknownDecays; + auto nEvents = tree->GetEntries(); + + for (int i = 0; i < nEvents; i++) + { + tree->GetEntry(i); + for (auto &track : *tracks) + { + auto pdg = track.GetPdgCode(); + auto absPdg = std::abs(pdg); + + if (std::find(checkPdgHadron.begin(), checkPdgHadron.end(), absPdg) != checkPdgHadron.end()) + { + nSignals++; // count signal PDG + + // Count replacement particles (single-match per track) + int matchedIdx = -1; + bool matchedIsReplacement = false; + for (int iRepl{0}; iRepl < 3; ++iRepl) { + if (absPdg == pdgReplParticles[iRepl][0]) { + matchedIdx = iRepl; + matchedIsReplacement = false; + break; + } + if (absPdg == pdgReplParticles[iRepl][1]) { + matchedIdx = iRepl; + matchedIsReplacement = true; + break; + } + } + if (matchedIdx >= 0) { + if (matchedIsReplacement) { + pdgReplPartCounters[matchedIdx][1]++; + } else { + pdgReplPartCounters[matchedIdx][0]++; + } + // Count the original-particle population once for this matched group + sumOrigReplacedParticles[pdgReplParticles[matchedIdx][0]]++; + } + + // Collect decay products + std::vector pdgsDecay{}; + if (track.getFirstDaughterTrackId() >= 0 && track.getLastDaughterTrackId() >= 0) { + for (int j{track.getFirstDaughterTrackId()}; j <= track.getLastDaughterTrackId(); ++j) { + auto pdgDau = tracks->at(j).GetPdgCode(); + pdgsDecay.push_back(pdgDau); + } + } + + std::sort(pdgsDecay.begin(), pdgsDecay.end()); + + // Check if decay matches expected channels + bool foundMatch = false; + for (auto &decay : checkHadronDecays[absPdg]) { + if (pdgsDecay == decay) { + nSignalGoodDecay++; + foundMatch = true; + break; + } + } + + // Record failed decays for debugging + if (!foundMatch && pdgsDecay.size() > 0) { + failedDecayCount[absPdg]++; + unknownDecays[absPdg].insert(pdgsDecay); + } + } + } + } + + std::cout << "--------------------------------\n"; + std::cout << "# Events: " << nEvents << "\n"; + std::cout << "# signal charm baryons: " << nSignals << "\n"; + std::cout << "# signal charm baryons decaying in the correct channel: " << nSignalGoodDecay << "\n"; + + // Print failed decay statistics + std::cout << "\nFailed decay counts:\n"; + for (auto &[pdg, count] : failedDecayCount) { + if (count > 0) { + std::cout << "PDG " << pdg << ": " << count << " failed decays\n"; + std::cout << " Unknown decay channels (first 5):\n"; + int printed = 0; + for (auto &decay : unknownDecays[pdg]) { + if (printed++ >= 5) break; + std::cout << " ["; + for (size_t i = 0; i < decay.size(); ++i) { + std::cout << decay[i]; + if (i < decay.size()-1) std::cout << ", "; + } + std::cout << "]\n"; + } + } + } + std::cout << "\n"; + + std::cout << "# D*0 (original): " << pdgReplPartCounters[0][0] << "\n"; + std::cout << "# Xic0 (replaced from D*0): " << pdgReplPartCounters[0][1] << "\n"; + std::cout << "# Xic+ (replaced from D*0): " << pdgReplPartCounters[1][1] << "\n"; + std::cout << "# Sigmac+ (original): " << pdgReplPartCounters[2][0] << "\n"; + std::cout << "# Omegac0 (replaced from Sigmac+): " << pdgReplPartCounters[2][1] << "\n"; + + // Check forced decay fraction + float fracForcedDecays = nSignals ? float(nSignalGoodDecay) / nSignals : 0.0f; + float uncFracForcedDecays = nSignals ? std::sqrt(fracForcedDecays * (1 - fracForcedDecays) / nSignals) : 1.0f; + std::cout << "# fraction of signals decaying into the correct channel: " << fracForcedDecays + << " (" << fracForcedDecays * 100.0f << "%)\n"; + if (1 - fracForcedDecays > 0.15 + uncFracForcedDecays) { // 85% threshold with tolerance + std::cerr << "Fraction of signals decaying into the correct channel " << fracForcedDecays << " lower than expected\n"; + return 1; + } + + // Check particle replacement ratios (2-sigma statistical compatibility) + for (int iRepl{0}; iRepl<6; ++iRepl) { + float numPart = sumOrigReplacedParticles[pdgReplParticles[iRepl][0]]; + float fracMeas = numPart ? float(pdgReplPartCounters[iRepl][1]) / numPart : 0.0f; + float fracMeasUnc = fracMeas ? std::sqrt(pdgReplPartCounters[iRepl][1]) / numPart : 1.0f; + + if (std::abs(fracMeas - freqRepl[iRepl]) > fracMeasUnc) { + std::cerr << "Fraction of replaced " << pdgReplParticles[iRepl][0] << " into " << pdgReplParticles[iRepl][1] << " is " << fracMeas <<" (expected "<< freqRepl[iRepl] << ")\n"; + return 1; + } + } + + return 0; +} \ No newline at end of file diff --git a/MC/config/PWGHF/ini/tests/GeneratorHF_D2H_ccbar_and_bbbar_gap2_QCDCR_OO.C b/MC/config/PWGHF/ini/tests/GeneratorHF_D2H_ccbar_and_bbbar_gap2_QCDCR_OO.C new file mode 100644 index 000000000..07c5f8837 --- /dev/null +++ b/MC/config/PWGHF/ini/tests/GeneratorHF_D2H_ccbar_and_bbbar_gap2_QCDCR_OO.C @@ -0,0 +1,190 @@ +int External(std::string path = "o2sim_Kine.root") { + + int checkPdgQuarkOne{4}; + int checkPdgQuarkTwo{5}; + float ratioTrigger = 1./2; // one event triggered out of 2 + + std::vector checkPdgHadron{411, 421, 431, 4122, 4132, 4232, 4332}; + std::map>> checkHadronDecays{ // sorted pdg of daughters + {421, { + {-321, 211}, // D0 -> K-, pi+ + {-321, 211, 111}, // D0 -> K-, pi+, pi0 + {213, -321}, // D0 -> rho(770)+, K- + {-313, 111}, // D0 -> Kbar^*(892)0, pi0 + {-323, 211}, // D0 -> K^*(892)-, pi+ + {-211, 211}, // D0 -> pi-, pi+ + {213, -211}, // D0 -> rho(770)+, pi- + {-211, 211, 111}, // D0 -> pi-, pi+, pi0 + {-321, 321}, // D0 -> K-, K+ + }}, + + {411, { + {-321, 211, 211}, // D+ -> K-, pi+, pi+ + {-10311, 211}, // D+ -> Kbar0^*(1430)0, pi+ + {-313, 211}, // D+ -> Kbar^*(892)0, pi+ + {-321, 211, 211, 111}, // D+ -> K-, pi+, pi+, pi0 + {333, 211}, // D+ -> phi(1020)0, pi+ + {-313, 321}, // D+ -> Kbar^*(892)0, K+ + {-10311, 321}, // D+ -> Kbar0^*(1430)0, K+ + {-321, 321, 211}, // D+ -> K-, K+, pi+ + {113, 211}, // D+ -> rho(770)0, pi+ + {225, 211}, // D+ -> f2(1270)0, pi+ + {-211, 211, 211}, // D+ -> pi-, pi+, pi+ + }}, + + {431, { + {333, 211}, // Ds+ -> phi(1020)0, pi+ + {-313, 321}, // Ds+ -> Kbar^*(892)0, K+ + {333, 213}, // Ds+ -> phi(1020)0, rho(770)+ + {113, 211}, // Ds+ -> rho(770)0, pi+ + {225, 211}, // Ds+ -> f2(1270)0, pi+ + {-211, 211, 211}, // Ds+ -> pi-, pi+, pi+ + {313, 211}, // Ds+ -> K^*(892)0, pi+ + {10221, 321}, // Ds+ -> f0(1370)0, K+ + {113, 321}, // Ds+ -> rho(770)0, K+ + {-211, 321, 211}, // Ds+ -> pi-, K+, pi+ + {221, 211}, // Ds+ -> eta, pi+ + }}, + + {4122, { + {2212, -321, 211}, // Lambdac+ -> p, K-, pi+ + {2212, -313}, // Lambdac+ -> p, Kbar^*(892)0 + {2224, -321}, // Lambdac+ -> Delta(1232)++, K- + {102134, 211}, // Lambdac+ -> 102134, pi+ + {2212, 311}, // Lambdac+ -> p, K0 + {2212, -321, 211, 111}, // Lambdac+ -> p, K-, pi+, pi0 + {2212, -211, 211}, // Lambdac+ -> p, pi-, pi+ + {2212, 333}, // Lambdac+ -> p, phi(1020)0 + }}, + + {4232, { + {2212, -321, 211}, // Xic+ -> p, K-, pi+ + {2212, -313}, // Xic+ -> p, Kbar^*(892)0 + {3312, 211, 211}, // Xic+ -> Xi-, pi+, pi+ + {2212, 333}, // Xic+ -> p, phi(1020)0 + {3222, -211, 211}, // Xic+ -> Sigma+, pi-, pi+ + {3324, 211}, // Xic+ -> Xi(1530)0, pi+ + }}, + + {4132, { + {3312, 211}, // Xic0 -> Xi-, pi+ + }}, + + {4332, { + {3334, 211}, // Omegac0 -> Omega-, pi+ + {3312, 211}, // Omegac0 -> Xi-, pi+ + }}, + }; + + TFile file(path.c_str(), "READ"); + if (file.IsZombie()) { + std::cerr << "Cannot open ROOT file " << path << "\n"; + return 1; + } + + auto tree = (TTree *)file.Get("o2sim"); + std::vector *tracks{}; + tree->SetBranchAddress("MCTrack", &tracks); + o2::dataformats::MCEventHeader *eventHeader = nullptr; + tree->SetBranchAddress("MCEventHeader.", &eventHeader); + + int nEventsMB{}, nEventsInjOne{}, nEventsInjTwo{}; + int nQuarksOne{}, nQuarksTwo{}, nSignals{}, nSignalGoodDecay{}; + auto nEvents = tree->GetEntries(); + + for (int i = 0; i < nEvents; i++) { + tree->GetEntry(i); + + // check subgenerator information + if (eventHeader->hasInfo(o2::mcgenid::GeneratorProperty::SUBGENERATORID)) { + bool isValid = false; + int subGeneratorId = eventHeader->getInfo(o2::mcgenid::GeneratorProperty::SUBGENERATORID, isValid); + if (subGeneratorId == 0) { + nEventsMB++; + } else if (subGeneratorId == checkPdgQuarkOne) { + nEventsInjOne++; + } else if (subGeneratorId == checkPdgQuarkTwo) { + nEventsInjTwo++; + } + } + + for (auto &track : *tracks) { + auto pdg = track.GetPdgCode(); + if (std::abs(pdg) == checkPdgQuarkOne) { + nQuarksOne++; + continue; + } + if (std::abs(pdg) == checkPdgQuarkTwo) { + nQuarksTwo++; + continue; + } + if (std::find(checkPdgHadron.begin(), checkPdgHadron.end(), std::abs(pdg)) != checkPdgHadron.end()) { // found signal + nSignals++; // count signal PDG + + std::vector pdgsDecay{}; + std::vector pdgsDecayAntiPart{}; + for (int j{track.getFirstDaughterTrackId()}; j <= track.getLastDaughterTrackId(); ++j) { + auto pdgDau = tracks->at(j).GetPdgCode(); + pdgsDecay.push_back(pdgDau); + if (pdgDau != 333 && pdgDau != 111 && pdgDau != 221 && pdgDau != 113 && pdgDau != 225) { // phi is antiparticle of itself + pdgsDecayAntiPart.push_back(-pdgDau); + } else { + pdgsDecayAntiPart.push_back(pdgDau); + } + } + + std::sort(pdgsDecay.begin(), pdgsDecay.end()); + std::sort(pdgsDecayAntiPart.begin(), pdgsDecayAntiPart.end()); + + for (auto &decay : checkHadronDecays[std::abs(pdg)]) { + std::sort(decay.begin(), decay.end()); + if (pdgsDecay == decay || pdgsDecayAntiPart == decay) { + nSignalGoodDecay++; + break; + } + } + } + } + } + + std::cout << "--------------------------------\n"; + std::cout << "# Events: " << nEvents << "\n"; + std::cout << "# MB events: " << nEventsMB << "\n"; + std::cout << Form("# events injected with %d quark pair: ", checkPdgQuarkOne) << nEventsInjOne << "\n"; + std::cout << Form("# events injected with %d quark pair: ", checkPdgQuarkTwo) << nEventsInjTwo << "\n"; + std::cout << Form("# %d (anti)quarks: ", checkPdgQuarkOne) << nQuarksOne << "\n"; + std::cout << Form("# %d (anti)quarks: ", checkPdgQuarkTwo) << nQuarksTwo << "\n"; + std::cout <<"# signal hadrons: " << nSignals << "\n"; + std::cout <<"# signal hadrons decaying in the correct channel: " << nSignalGoodDecay << "\n"; + + if (nEventsMB < nEvents * (1 - ratioTrigger) * 0.95 || nEventsMB > nEvents * (1 - ratioTrigger) * 1.05) { // we put some tolerance since the number of generated events is small + std::cerr << "Number of generated MB events different than expected\n"; + return 1; + } + if (nEventsInjOne < nEvents * ratioTrigger * 0.5 * 0.95 || nEventsInjOne > nEvents * ratioTrigger * 0.5 * 1.05) { + std::cerr << "Number of generated events injected with " << checkPdgQuarkOne << " different than expected\n"; + return 1; + } + if (nEventsInjTwo < nEvents * ratioTrigger * 0.5 * 0.95 || nEventsInjTwo > nEvents * ratioTrigger * 0.5 * 1.05) { + std::cerr << "Number of generated events injected with " << checkPdgQuarkTwo << " different than expected\n"; + return 1; + } + + if (nQuarksOne < nEvents * ratioTrigger) { // we expect anyway more because the same quark is repeated several time, after each gluon radiation + std::cerr << "Number of generated (anti)quarks " << checkPdgQuarkOne << " lower than expected\n"; + return 1; + } + if (nQuarksTwo < nEvents * ratioTrigger) { // we expect anyway more because the same quark is repeated several time, after each gluon radiation + std::cerr << "Number of generated (anti)quarks " << checkPdgQuarkTwo << " lower than expected\n"; + return 1; + } + + float fracForcedDecays = nSignals ? float(nSignalGoodDecay) / nSignals : 0.0f; + float uncFracForcedDecays = nSignals ? std::sqrt(fracForcedDecays * (1 - fracForcedDecays) / nSignals) : 1.0f; + if (1 - fracForcedDecays > 0.15 + uncFracForcedDecays) { // we put some tolerance (e.g. due to oscillations which might change the final state) + std::cerr << "Fraction of signals decaying into the correct channel " << fracForcedDecays << " lower than expected\n"; + return 1; + } + + return 0; +} diff --git a/MC/config/PWGHF/ini/tests/GeneratorHF_D2H_ccbar_and_bbbar_gap2_QCDCR_pO.C b/MC/config/PWGHF/ini/tests/GeneratorHF_D2H_ccbar_and_bbbar_gap2_QCDCR_pO.C new file mode 100644 index 000000000..07c5f8837 --- /dev/null +++ b/MC/config/PWGHF/ini/tests/GeneratorHF_D2H_ccbar_and_bbbar_gap2_QCDCR_pO.C @@ -0,0 +1,190 @@ +int External(std::string path = "o2sim_Kine.root") { + + int checkPdgQuarkOne{4}; + int checkPdgQuarkTwo{5}; + float ratioTrigger = 1./2; // one event triggered out of 2 + + std::vector checkPdgHadron{411, 421, 431, 4122, 4132, 4232, 4332}; + std::map>> checkHadronDecays{ // sorted pdg of daughters + {421, { + {-321, 211}, // D0 -> K-, pi+ + {-321, 211, 111}, // D0 -> K-, pi+, pi0 + {213, -321}, // D0 -> rho(770)+, K- + {-313, 111}, // D0 -> Kbar^*(892)0, pi0 + {-323, 211}, // D0 -> K^*(892)-, pi+ + {-211, 211}, // D0 -> pi-, pi+ + {213, -211}, // D0 -> rho(770)+, pi- + {-211, 211, 111}, // D0 -> pi-, pi+, pi0 + {-321, 321}, // D0 -> K-, K+ + }}, + + {411, { + {-321, 211, 211}, // D+ -> K-, pi+, pi+ + {-10311, 211}, // D+ -> Kbar0^*(1430)0, pi+ + {-313, 211}, // D+ -> Kbar^*(892)0, pi+ + {-321, 211, 211, 111}, // D+ -> K-, pi+, pi+, pi0 + {333, 211}, // D+ -> phi(1020)0, pi+ + {-313, 321}, // D+ -> Kbar^*(892)0, K+ + {-10311, 321}, // D+ -> Kbar0^*(1430)0, K+ + {-321, 321, 211}, // D+ -> K-, K+, pi+ + {113, 211}, // D+ -> rho(770)0, pi+ + {225, 211}, // D+ -> f2(1270)0, pi+ + {-211, 211, 211}, // D+ -> pi-, pi+, pi+ + }}, + + {431, { + {333, 211}, // Ds+ -> phi(1020)0, pi+ + {-313, 321}, // Ds+ -> Kbar^*(892)0, K+ + {333, 213}, // Ds+ -> phi(1020)0, rho(770)+ + {113, 211}, // Ds+ -> rho(770)0, pi+ + {225, 211}, // Ds+ -> f2(1270)0, pi+ + {-211, 211, 211}, // Ds+ -> pi-, pi+, pi+ + {313, 211}, // Ds+ -> K^*(892)0, pi+ + {10221, 321}, // Ds+ -> f0(1370)0, K+ + {113, 321}, // Ds+ -> rho(770)0, K+ + {-211, 321, 211}, // Ds+ -> pi-, K+, pi+ + {221, 211}, // Ds+ -> eta, pi+ + }}, + + {4122, { + {2212, -321, 211}, // Lambdac+ -> p, K-, pi+ + {2212, -313}, // Lambdac+ -> p, Kbar^*(892)0 + {2224, -321}, // Lambdac+ -> Delta(1232)++, K- + {102134, 211}, // Lambdac+ -> 102134, pi+ + {2212, 311}, // Lambdac+ -> p, K0 + {2212, -321, 211, 111}, // Lambdac+ -> p, K-, pi+, pi0 + {2212, -211, 211}, // Lambdac+ -> p, pi-, pi+ + {2212, 333}, // Lambdac+ -> p, phi(1020)0 + }}, + + {4232, { + {2212, -321, 211}, // Xic+ -> p, K-, pi+ + {2212, -313}, // Xic+ -> p, Kbar^*(892)0 + {3312, 211, 211}, // Xic+ -> Xi-, pi+, pi+ + {2212, 333}, // Xic+ -> p, phi(1020)0 + {3222, -211, 211}, // Xic+ -> Sigma+, pi-, pi+ + {3324, 211}, // Xic+ -> Xi(1530)0, pi+ + }}, + + {4132, { + {3312, 211}, // Xic0 -> Xi-, pi+ + }}, + + {4332, { + {3334, 211}, // Omegac0 -> Omega-, pi+ + {3312, 211}, // Omegac0 -> Xi-, pi+ + }}, + }; + + TFile file(path.c_str(), "READ"); + if (file.IsZombie()) { + std::cerr << "Cannot open ROOT file " << path << "\n"; + return 1; + } + + auto tree = (TTree *)file.Get("o2sim"); + std::vector *tracks{}; + tree->SetBranchAddress("MCTrack", &tracks); + o2::dataformats::MCEventHeader *eventHeader = nullptr; + tree->SetBranchAddress("MCEventHeader.", &eventHeader); + + int nEventsMB{}, nEventsInjOne{}, nEventsInjTwo{}; + int nQuarksOne{}, nQuarksTwo{}, nSignals{}, nSignalGoodDecay{}; + auto nEvents = tree->GetEntries(); + + for (int i = 0; i < nEvents; i++) { + tree->GetEntry(i); + + // check subgenerator information + if (eventHeader->hasInfo(o2::mcgenid::GeneratorProperty::SUBGENERATORID)) { + bool isValid = false; + int subGeneratorId = eventHeader->getInfo(o2::mcgenid::GeneratorProperty::SUBGENERATORID, isValid); + if (subGeneratorId == 0) { + nEventsMB++; + } else if (subGeneratorId == checkPdgQuarkOne) { + nEventsInjOne++; + } else if (subGeneratorId == checkPdgQuarkTwo) { + nEventsInjTwo++; + } + } + + for (auto &track : *tracks) { + auto pdg = track.GetPdgCode(); + if (std::abs(pdg) == checkPdgQuarkOne) { + nQuarksOne++; + continue; + } + if (std::abs(pdg) == checkPdgQuarkTwo) { + nQuarksTwo++; + continue; + } + if (std::find(checkPdgHadron.begin(), checkPdgHadron.end(), std::abs(pdg)) != checkPdgHadron.end()) { // found signal + nSignals++; // count signal PDG + + std::vector pdgsDecay{}; + std::vector pdgsDecayAntiPart{}; + for (int j{track.getFirstDaughterTrackId()}; j <= track.getLastDaughterTrackId(); ++j) { + auto pdgDau = tracks->at(j).GetPdgCode(); + pdgsDecay.push_back(pdgDau); + if (pdgDau != 333 && pdgDau != 111 && pdgDau != 221 && pdgDau != 113 && pdgDau != 225) { // phi is antiparticle of itself + pdgsDecayAntiPart.push_back(-pdgDau); + } else { + pdgsDecayAntiPart.push_back(pdgDau); + } + } + + std::sort(pdgsDecay.begin(), pdgsDecay.end()); + std::sort(pdgsDecayAntiPart.begin(), pdgsDecayAntiPart.end()); + + for (auto &decay : checkHadronDecays[std::abs(pdg)]) { + std::sort(decay.begin(), decay.end()); + if (pdgsDecay == decay || pdgsDecayAntiPart == decay) { + nSignalGoodDecay++; + break; + } + } + } + } + } + + std::cout << "--------------------------------\n"; + std::cout << "# Events: " << nEvents << "\n"; + std::cout << "# MB events: " << nEventsMB << "\n"; + std::cout << Form("# events injected with %d quark pair: ", checkPdgQuarkOne) << nEventsInjOne << "\n"; + std::cout << Form("# events injected with %d quark pair: ", checkPdgQuarkTwo) << nEventsInjTwo << "\n"; + std::cout << Form("# %d (anti)quarks: ", checkPdgQuarkOne) << nQuarksOne << "\n"; + std::cout << Form("# %d (anti)quarks: ", checkPdgQuarkTwo) << nQuarksTwo << "\n"; + std::cout <<"# signal hadrons: " << nSignals << "\n"; + std::cout <<"# signal hadrons decaying in the correct channel: " << nSignalGoodDecay << "\n"; + + if (nEventsMB < nEvents * (1 - ratioTrigger) * 0.95 || nEventsMB > nEvents * (1 - ratioTrigger) * 1.05) { // we put some tolerance since the number of generated events is small + std::cerr << "Number of generated MB events different than expected\n"; + return 1; + } + if (nEventsInjOne < nEvents * ratioTrigger * 0.5 * 0.95 || nEventsInjOne > nEvents * ratioTrigger * 0.5 * 1.05) { + std::cerr << "Number of generated events injected with " << checkPdgQuarkOne << " different than expected\n"; + return 1; + } + if (nEventsInjTwo < nEvents * ratioTrigger * 0.5 * 0.95 || nEventsInjTwo > nEvents * ratioTrigger * 0.5 * 1.05) { + std::cerr << "Number of generated events injected with " << checkPdgQuarkTwo << " different than expected\n"; + return 1; + } + + if (nQuarksOne < nEvents * ratioTrigger) { // we expect anyway more because the same quark is repeated several time, after each gluon radiation + std::cerr << "Number of generated (anti)quarks " << checkPdgQuarkOne << " lower than expected\n"; + return 1; + } + if (nQuarksTwo < nEvents * ratioTrigger) { // we expect anyway more because the same quark is repeated several time, after each gluon radiation + std::cerr << "Number of generated (anti)quarks " << checkPdgQuarkTwo << " lower than expected\n"; + return 1; + } + + float fracForcedDecays = nSignals ? float(nSignalGoodDecay) / nSignals : 0.0f; + float uncFracForcedDecays = nSignals ? std::sqrt(fracForcedDecays * (1 - fracForcedDecays) / nSignals) : 1.0f; + if (1 - fracForcedDecays > 0.15 + uncFracForcedDecays) { // we put some tolerance (e.g. due to oscillations which might change the final state) + std::cerr << "Fraction of signals decaying into the correct channel " << fracForcedDecays << " lower than expected\n"; + return 1; + } + + return 0; +} diff --git a/MC/config/PWGHF/ini/tests/GeneratorHF_D2H_ccbar_and_bbbar_gap3.C b/MC/config/PWGHF/ini/tests/GeneratorHF_D2H_ccbar_and_bbbar_gap3.C index d29245b32..10f9b8ccb 100644 --- a/MC/config/PWGHF/ini/tests/GeneratorHF_D2H_ccbar_and_bbbar_gap3.C +++ b/MC/config/PWGHF/ini/tests/GeneratorHF_D2H_ccbar_and_bbbar_gap3.C @@ -118,8 +118,9 @@ int External() { return 1; } - float fracForcedDecays = float(nSignalGoodDecay) / nSignals; - if (fracForcedDecays < 0.9) { // we put some tolerance (e.g. due to oscillations which might change the final state) + float fracForcedDecays = nSignals ? float(nSignalGoodDecay) / nSignals : 0.0f; + float uncFracForcedDecays = nSignals ? std::sqrt(fracForcedDecays * (1 - fracForcedDecays) / nSignals) : 1.0f; + if (1 - fracForcedDecays > 0.15 + uncFracForcedDecays) { // we put some tolerance (e.g. due to oscillations which might change the final state) std::cerr << "Fraction of signals decaying into the correct channel " << fracForcedDecays << " lower than expected\n"; return 1; } diff --git a/MC/config/PWGHF/ini/tests/GeneratorHF_D2H_ccbar_and_bbbar_gap3_Mode2.C b/MC/config/PWGHF/ini/tests/GeneratorHF_D2H_ccbar_and_bbbar_gap3_Mode2.C index d29245b32..3d5a21e0b 100644 --- a/MC/config/PWGHF/ini/tests/GeneratorHF_D2H_ccbar_and_bbbar_gap3_Mode2.C +++ b/MC/config/PWGHF/ini/tests/GeneratorHF_D2H_ccbar_and_bbbar_gap3_Mode2.C @@ -7,13 +7,65 @@ int External() { std::vector checkPdgHadron{411, 421, 431, 4122, 4132, 4232, 4332}; std::map>> checkHadronDecays{ // sorted pdg of daughters - {411, {{-321, 211, 211}, {-313, 211}, {211, 311}, {211, 333}}}, // D+ - {421, {{-321, 211}, {-321, 111, 211}}}, // D0 - {431, {{211, 333}, {-313, 321}}}, // Ds+ - {4122, {{-313, 2212}, {-321, 2224}, {211, 102134}, {-321, 211, 2212}, {311, 2212}}}, // Lc+ - {4132, {{211, 3312}}}, // Xic0 - {4232, {{-313, 2212}, {-321, 3324}, {211, 211, 3312}, {-321, 211, 2212}}}, // Xic+ - {4332, {{211, 3334}}} // Omegac+ + {411, { + {-321, 211, 211}, // K- π+ π+ (non-resonant) + {-321, 111, 211, 211}, // K- π+ π+ π0 (non-resonant) + {-313, 321}, // K*0(892) K+ + {-10311, 321}, // K*0(1430) K+ + {211, 333}, // φ π+ + {-321, 211, 321}, // K- K+ π+ (non-resonant) + {113, 211}, // ρ0 π+ + {211, 225}, // f2(1270) π+ + {-211, 211, 211} // π- π+ π+ (non-resonant) + }}, + {421, { + {-321, 211}, // K- π+ (non-resonant) + {-321, 111, 211}, // K- π+ π0 + {-321, 213}, // ρ+ K- + {-313, 111}, // antiK*0(892) π0 + {-323, 211}, // K*-(892) π+ + {-211, 211}, // π- π+ + {-211, 213}, // ρ+ π- + {-211, 111, 211}, // π- π+ π0 + {-321, 321} // K- K+ + }}, + {431, { + {211, 333}, // φ π+ + {-313, 321}, // antiK*(892) K+ + {213, 333}, // φ ρ + {113, 211}, // ρ π+ + {211, 225}, // f2(1270) π+ + {-211, 211, 211}, // π- π+ π+ (s-wave) + {211, 313}, // K*(892)0 π+ + {321, 10221}, // f0(1370) K+ + {113, 321}, // ρ0 K+ + {-211, 211, 321}, // π- K+ π+ (non-resonant) + {211, 221} // η π+ + }}, + {4122, { + {-321, 211, 2212}, // p K- π+ (non-resonant) + {-313, 2212}, // p K*0(892) + {-321, 2224}, // Δ++ K- + {211, 102134}, // Λ(1520) π+ + {-321, 111, 211, 2212}, // p K- π+ π0 + {-211, 211, 2212}, // p π- π+ + {333, 2212} // p φ + }}, + {4232, { + {-321, 211, 2212}, // Xic+ -> p, K-, pi+ + {-313, 2212}, // Xic+ -> p, Kbar^*(892)0 + {211, 211, 3312}, // Xic+ -> Xi-, pi+, pi+ + {333, 2212}, // Xic+ -> p, phi(1020)0 + {-211, 211, 3222}, // Xic+ -> Sigma+, pi-, pi+ + {211, 3324} // Xic+ -> Xi(1530)0, pi+ + }}, + {4132, { + {211, 3312}, // Xic0 -> Xi-, pi+ + }}, + {4332, { + {211, 3334}, // Omegac0 -> Omega-, pi+ + {211, 3312} // Omegac0 -> Xi-, pi+ + }} }; TFile file(path.c_str(), "READ"); @@ -66,7 +118,7 @@ int External() { for (int j{track.getFirstDaughterTrackId()}; j <= track.getLastDaughterTrackId(); ++j) { auto pdgDau = tracks->at(j).GetPdgCode(); pdgsDecay.push_back(pdgDau); - if (pdgDau != 333) { // phi is antiparticle of itself + if (pdgDau != 333 && pdgDau != 111 && pdgDau != 221 && pdgDau != 113 && pdgDau != 225) { // phi is antiparticle of itself pdgsDecayAntiPart.push_back(-pdgDau); } else { pdgsDecayAntiPart.push_back(pdgDau); @@ -118,8 +170,9 @@ int External() { return 1; } - float fracForcedDecays = float(nSignalGoodDecay) / nSignals; - if (fracForcedDecays < 0.9) { // we put some tolerance (e.g. due to oscillations which might change the final state) + float fracForcedDecays = nSignals ? float(nSignalGoodDecay) / nSignals : 0.0f; + float uncFracForcedDecays = nSignals ? std::sqrt(fracForcedDecays * (1 - fracForcedDecays) / nSignals) : 1.0f; + if (1 - fracForcedDecays > 0.15 + uncFracForcedDecays) { // we put some tolerance (e.g. due to oscillations which might change the final state) std::cerr << "Fraction of signals decaying into the correct channel " << fracForcedDecays << " lower than expected\n"; return 1; } diff --git a/MC/config/PWGHF/ini/tests/GeneratorHF_D2H_ccbar_and_bbbar_gap3_Mode2_XiC.C b/MC/config/PWGHF/ini/tests/GeneratorHF_D2H_ccbar_and_bbbar_gap3_Mode2_XiC.C index c99426354..9d6cbac69 100644 --- a/MC/config/PWGHF/ini/tests/GeneratorHF_D2H_ccbar_and_bbbar_gap3_Mode2_XiC.C +++ b/MC/config/PWGHF/ini/tests/GeneratorHF_D2H_ccbar_and_bbbar_gap3_Mode2_XiC.C @@ -112,8 +112,9 @@ int External() { return 1; } - float fracForcedDecays = float(nSignalGoodDecay) / nSignals; - if (fracForcedDecays < 0.9) { // we put some tolerance (e.g. due to oscillations which might change the final state) + float fracForcedDecays = nSignals ? float(nSignalGoodDecay) / nSignals : 0.0f; + float uncFracForcedDecays = nSignals ? std::sqrt(fracForcedDecays * (1 - fracForcedDecays) / nSignals) : 1.0f; + if (1 - fracForcedDecays > 0.15 + uncFracForcedDecays) { // we put some tolerance (e.g. due to oscillations which might change the final state) std::cerr << "Fraction of signals decaying into the correct channel " << fracForcedDecays << " lower than expected\n"; return 1; } diff --git a/MC/config/PWGHF/ini/tests/GeneratorHF_D2H_ccbar_and_bbbar_gap5.C b/MC/config/PWGHF/ini/tests/GeneratorHF_D2H_ccbar_and_bbbar_gap5.C index e5c0bf08d..f36c8a02f 100644 --- a/MC/config/PWGHF/ini/tests/GeneratorHF_D2H_ccbar_and_bbbar_gap5.C +++ b/MC/config/PWGHF/ini/tests/GeneratorHF_D2H_ccbar_and_bbbar_gap5.C @@ -118,8 +118,9 @@ int External() { return 1; } - float fracForcedDecays = float(nSignalGoodDecay) / nSignals; - if (fracForcedDecays < 0.9) { // we put some tolerance (e.g. due to oscillations which might change the final state) + float fracForcedDecays = nSignals ? float(nSignalGoodDecay) / nSignals : 0.0f; + float uncFracForcedDecays = nSignals ? std::sqrt(fracForcedDecays * (1 - fracForcedDecays) / nSignals) : 1.0f; + if (1 - fracForcedDecays > 0.15 + uncFracForcedDecays) { // we put some tolerance (e.g. due to oscillations which might change the final state) std::cerr << "Fraction of signals decaying into the correct channel " << fracForcedDecays << " lower than expected\n"; return 1; } diff --git a/MC/config/PWGHF/ini/tests/GeneratorHF_D2H_ccbar_and_bbbar_gap5_DReso.C b/MC/config/PWGHF/ini/tests/GeneratorHF_D2H_ccbar_and_bbbar_gap5_DReso.C index 3c1cfd492..ed1021a5d 100644 --- a/MC/config/PWGHF/ini/tests/GeneratorHF_D2H_ccbar_and_bbbar_gap5_DReso.C +++ b/MC/config/PWGHF/ini/tests/GeneratorHF_D2H_ccbar_and_bbbar_gap5_DReso.C @@ -130,8 +130,9 @@ int External() { return 1; } - float fracForcedDecays = float(nSignalGoodDecay) / nSignals; - if (fracForcedDecays < 0.9) { // we put some tolerance (e.g. due to oscillations which might change the final state) + float fracForcedDecays = nSignals ? float(nSignalGoodDecay) / nSignals : 0.0f; + float uncFracForcedDecays = nSignals ? std::sqrt(fracForcedDecays * (1 - fracForcedDecays) / nSignals) : 1.0f; + if (1 - fracForcedDecays > 0.15 + uncFracForcedDecays) { // we put some tolerance (e.g. due to oscillations which might change the final state) std::cerr << "Fraction of signals decaying into the correct channel " << fracForcedDecays << " lower than expected\n"; return 1; } diff --git a/MC/config/PWGHF/ini/tests/GeneratorHF_D2H_ccbar_and_bbbar_gap5_DResoTrigger.C b/MC/config/PWGHF/ini/tests/GeneratorHF_D2H_ccbar_and_bbbar_gap5_DResoTrigger.C new file mode 100644 index 000000000..702c1ddad --- /dev/null +++ b/MC/config/PWGHF/ini/tests/GeneratorHF_D2H_ccbar_and_bbbar_gap5_DResoTrigger.C @@ -0,0 +1,146 @@ +int External() { + std::string path{"o2sim_Kine.root"}; + + int checkPdgQuarkOne{4}; + int checkPdgQuarkTwo{5}; + float ratioTrigger = 1./5.; // one event triggered out of 5 + std::array, 6> pdgReplParticles = {std::array{10433, 30433}, std::array{10433, 437}, std::array{435, 4325}, std::array{435, 4326}, std::array{425, 4315}, std::array{425, 4316}}; + std::array, 6> pdgReplPartCounters = {std::array{0, 0}, std::array{0, 0}, std::array{0, 0}, std::array{0, 0}, std::array{0, 0}, std::array{0, 0}}; + std::array freqRepl = {0.1, 0.1, 0.1, 0.1, 0.5, 0.5}; + std::map sumOrigReplacedParticles = {{10433, 0}, {435, 0}, {425, 0}}; + + std::array checkPdgHadron{411, 421, 10433, 30433, 435, 437, 4325, 4326, 4315, 4316, 531, 425}; + std::map>> checkHadronDecays{ // sorted pdg of daughters + {411, {{-321, 211, 211}, {-313, 211}, {211, 311}, {211, 333}}}, // D+ + {421, {{-321, 211}, {-321, 111, 211}}}, // D0 + {435, {{311, 413}, {311, 411}}}, // Ds2*(2573) + {10433, {{311, 413}}}, // Ds1(2536) + {30433, {{311, 413}}}, // Ds1*(2700) + {437, {{311, 413}}}, // Ds3*(2860) + {4325, {{411, 3122}}}, // Xic(3055)+ + {4326, {{411, 3122}}}, // Xic(3080)+ + {4315, {{421, 3122}}}, // Xic(3055)+ + {4316, {{421, 3122}}}, // Xic(3080)+ + {531, {{-435, -11, 12}, {-10433, -11, 12}, {-435, -13, 14}, {-10433, -13, 14}, {-435, -15, 16}, {-10433, -15, 16}, {-435, 211}}}, // Bs0 + {425, {{-211, 413}, {111, 423}, {-211, 411}, {111, 421}, {-211, 111, 413}, {-211, 211, 423}}} + }; + + TFile file(path.c_str(), "READ"); + if (file.IsZombie()) { + std::cerr << "Cannot open ROOT file " << path << "\n"; + return 1; + } + + auto tree = (TTree *)file.Get("o2sim"); + std::vector *tracks{}; + tree->SetBranchAddress("MCTrack", &tracks); + o2::dataformats::MCEventHeader *eventHeader = nullptr; + tree->SetBranchAddress("MCEventHeader.", &eventHeader); + + int nEventsMB{}, nEventsInjOne{}, nEventsInjTwo{}; + int nSignals{}, nSignalGoodDecay{}; + auto nEvents = tree->GetEntries(); + + for (int i = 0; i < nEvents; i++) { + tree->GetEntry(i); + + // check subgenerator information + int subGeneratorId{-1}; + if (eventHeader->hasInfo(o2::mcgenid::GeneratorProperty::SUBGENERATORID)) { + bool isValid = false; + subGeneratorId = eventHeader->getInfo(o2::mcgenid::GeneratorProperty::SUBGENERATORID, isValid); + if (subGeneratorId == 0) { + nEventsMB++; + } else if (subGeneratorId == checkPdgQuarkOne) { + nEventsInjOne++; + } else if (subGeneratorId == checkPdgQuarkTwo) { + nEventsInjTwo++; + } + } + + for (auto &track : *tracks) { + auto pdg = track.GetPdgCode(); + auto absPdg = std::abs(pdg); + if (std::find(checkPdgHadron.begin(), checkPdgHadron.end(), absPdg) != checkPdgHadron.end()) { // found signal + nSignals++; // count signal PDG + + if (subGeneratorId == checkPdgQuarkOne) { // replacement only for prompt + for (int iRepl{0}; iRepl<6; ++iRepl) { + if (absPdg == pdgReplParticles[iRepl][0]) { + pdgReplPartCounters[iRepl][0]++; + sumOrigReplacedParticles[pdgReplParticles[iRepl][0]]++; + } else if (absPdg == pdgReplParticles[iRepl][1]) { + pdgReplPartCounters[iRepl][1]++; + sumOrigReplacedParticles[pdgReplParticles[iRepl][0]]++; + } + } + } + + std::vector pdgsDecay{}; + std::vector pdgsDecayAntiPart{}; + if (track.getFirstDaughterTrackId() >= 0 && track.getLastDaughterTrackId() >= 0) { + for (int j{track.getFirstDaughterTrackId()}; j <= track.getLastDaughterTrackId(); ++j) { + auto pdgDau = tracks->at(j).GetPdgCode(); + pdgsDecay.push_back(pdgDau); + if (pdgDau != 333 && pdgDau != 111) { // phi and pi0 are antiparticles of themselves + pdgsDecayAntiPart.push_back(-pdgDau); + } else { + pdgsDecayAntiPart.push_back(pdgDau); + } + } + } + + std::sort(pdgsDecay.begin(), pdgsDecay.end()); + std::sort(pdgsDecayAntiPart.begin(), pdgsDecayAntiPart.end()); + + for (auto &decay : checkHadronDecays[std::abs(pdg)]) { + if (pdgsDecay == decay || pdgsDecayAntiPart == decay) { + nSignalGoodDecay++; + break; + } + } + } + } + } + + std::cout << "--------------------------------\n"; + std::cout << "# Events: " << nEvents << "\n"; + std::cout << "# MB events: " << nEventsMB << "\n"; + std::cout << Form("# events injected with %d quark pair: ", checkPdgQuarkOne) << nEventsInjOne << "\n"; + std::cout << Form("# events injected with %d quark pair: ", checkPdgQuarkTwo) << nEventsInjTwo << "\n"; + std::cout <<"# signal hadrons: " << nSignals << "\n"; + std::cout <<"# signal hadrons decaying in the correct channel: " << nSignalGoodDecay << "\n"; + + if (nEventsMB < nEvents * (1 - ratioTrigger) * 0.95 || nEventsMB > nEvents * (1 - ratioTrigger) * 1.05) { // we put some tolerance since the number of generated events is small + std::cerr << "Number of generated MB events different than expected\n"; + return 1; + } + if (nEventsInjOne < nEvents * ratioTrigger * 0.5 * 0.95 || nEventsInjOne > nEvents * ratioTrigger * 0.5 * 1.05) { + std::cerr << "Number of generated events injected with " << checkPdgQuarkOne << " different than expected\n"; + return 1; + } + if (nEventsInjTwo < nEvents * ratioTrigger * 0.5 * 0.95 || nEventsInjTwo > nEvents * ratioTrigger * 0.5 * 1.05) { + std::cerr << "Number of generated events injected with " << checkPdgQuarkTwo << " different than expected\n"; + return 1; + } + + float fracForcedDecays = nSignals ? float(nSignalGoodDecay) / nSignals : 0.0f; + float uncFracForcedDecays = nSignals ? std::sqrt(fracForcedDecays * (1 - fracForcedDecays) / nSignals) : 1.0f; + if (1 - fracForcedDecays > 0.15 + uncFracForcedDecays) { // we put some tolerance (e.g. due to oscillations which might change the final state) + std::cerr << "Fraction of signals decaying into the correct channel " << fracForcedDecays << " lower than expected\n"; + return 1; + } + + for (int iRepl{0}; iRepl<6; ++iRepl) { + float numPart = sumOrigReplacedParticles[pdgReplParticles[iRepl][0]]; + float fracMeas = numPart ? float(pdgReplPartCounters[iRepl][1]) / numPart : 0.0f; + float fracMeasUnc = (fracMeas && numPart != 1) ? std::sqrt(pdgReplPartCounters[iRepl][1]) / numPart : 1.0f; + + if (std::abs(fracMeas - freqRepl[iRepl]) > fracMeasUnc) { + std::cerr << "Fraction of replaced " << pdgReplParticles[iRepl][0] << " into " << pdgReplParticles[iRepl][1] << " is " << fracMeas <<" (expected "<< freqRepl[iRepl] << ")\n"; + return 1; + } + } + + return 0; +} diff --git a/MC/config/PWGHF/ini/tests/GeneratorHF_D2H_ccbar_and_bbbar_gap5_LcResoTrigger.C b/MC/config/PWGHF/ini/tests/GeneratorHF_D2H_ccbar_and_bbbar_gap5_LcResoTrigger.C new file mode 100644 index 000000000..a2c5fa546 --- /dev/null +++ b/MC/config/PWGHF/ini/tests/GeneratorHF_D2H_ccbar_and_bbbar_gap5_LcResoTrigger.C @@ -0,0 +1,131 @@ +int ExternalLc() { + std::string path{"o2sim_Kine.root"}; + + int checkPdgQuarkOne{4}; // c quark injection + int checkPdgQuarkTwo{5}; // b quark injection + float ratioTrigger = 1./5.; // one event triggered out of 5 + + // PDG replacements: Λc(4122) -> resonances + std::array, 4> pdgReplParticles = { + std::array{4122, 24124}, // Λc -> Λc(2860) + std::array{4122, 24126}, // Λc -> Λc(2880) + std::array{4122, 4125}, // Λc -> Λc(2940) + std::array{4122, 9422111} // Λc -> Tc(3100) + }; + + // Counters for replacements + std::array, 4> pdgReplPartCounters = { + std::array{0,0}, std::array{0,0}, std::array{0,0}, std::array{0,0} + }; + + std::array freqRepl = {0.2, 0.2, 0.2, 0.2}; + std::map sumOrigReplacedParticles = {{4122,0}}; + + // Hadrons to check + std::array checkPdgHadron{24124, 24126, 4125, 9422111, 5122}; + + // Correct decays + std::map>> checkHadronDecays{ + {24124, {{421, 2212}}}, + {24126, {{421, 2212}}}, + {4125, {{421, 2212}}}, + {9422111, {{413, 2212}}}, + {5122, {{421, 2212, -211}, {41221, -211}, {24124, -211}, {24126, -211}, {4125, -211}}} + }; + + TFile file(path.c_str(), "READ"); + if (file.IsZombie()) { std::cerr << "Cannot open ROOT file " << path << "\n"; return 1; } + + auto tree = (TTree*)file.Get("o2sim"); + std::vector* tracks{}; + tree->SetBranchAddress("MCTrack", &tracks); + o2::dataformats::MCEventHeader* eventHeader = nullptr; + tree->SetBranchAddress("MCEventHeader.", &eventHeader); + + int nEventsMB{}, nEventsInjOne{}, nEventsInjTwo{}; + int nSignals{}, nSignalGoodDecay{}; + auto nEvents = tree->GetEntries(); + + std::map signalHadronsPerType; + std::map signalGoodDecayPerType; + for (auto pdg : checkPdgHadron) { signalHadronsPerType[pdg] = 0; signalGoodDecayPerType[pdg] = 0; } + + for (int i=0; iGetEntry(i); + + int subGeneratorId{-1}; + if (eventHeader->hasInfo(o2::mcgenid::GeneratorProperty::SUBGENERATORID)) { + bool isValid=false; + subGeneratorId = eventHeader->getInfo(o2::mcgenid::GeneratorProperty::SUBGENERATORID, isValid); + if (subGeneratorId==0) nEventsMB++; + else if (subGeneratorId==checkPdgQuarkOne) nEventsInjOne++; + else if (subGeneratorId==checkPdgQuarkTwo) nEventsInjTwo++; + } + + for (auto& track : *tracks) { + int pdg = track.GetPdgCode(); + int absPdg = std::abs(pdg); + + if (std::find(checkPdgHadron.begin(), checkPdgHadron.end(), absPdg) != checkPdgHadron.end()) { + nSignals++; + signalHadronsPerType[absPdg]++; + + if (subGeneratorId==checkPdgQuarkOne) { + for (int iRepl=0; iRepl<3; ++iRepl) { + if (absPdg == pdgReplParticles[iRepl][0]) { pdgReplPartCounters[iRepl][0]++; sumOrigReplacedParticles[pdgReplParticles[iRepl][0]]++; } + else if (absPdg == pdgReplParticles[iRepl][1]) { pdgReplPartCounters[iRepl][1]++; sumOrigReplacedParticles[pdgReplParticles[iRepl][0]]++; } + } + } + + std::vector pdgsDecay; + std::vector pdgsDecayAnti; + if (track.getFirstDaughterTrackId()>=0) { + for (int j=track.getFirstDaughterTrackId(); j<=track.getLastDaughterTrackId(); ++j) { + int pdgDau = tracks->at(j).GetPdgCode(); + pdgsDecay.push_back(pdgDau); + pdgsDecayAnti.push_back((pdgDau==111||pdgDau==333)? pdgDau : -pdgDau); + } + } + + std::sort(pdgsDecay.begin(), pdgsDecay.end()); + std::sort(pdgsDecayAnti.begin(), pdgsDecayAnti.end()); + + bool matchedDecay = false; + for (auto& decay : checkHadronDecays[absPdg]) { + std::vector decayCopy = decay; + std::sort(decayCopy.begin(), decayCopy.end()); + if (pdgsDecay == decayCopy || pdgsDecayAnti == decayCopy) { + matchedDecay = true; + nSignalGoodDecay++; + signalGoodDecayPerType[absPdg]++; + break; + } + } + + // Print daughters + std::cout << "Particle " << absPdg << " daughters: "; + for (auto d : pdgsDecay) std::cout << d << " "; + if (matchedDecay) std::cout << "(matches expected decay)"; + else std::cout << "(does NOT match expected decay)"; + std::cout << "\n"; + } + } + } + + std::cout << "--------------------------------\n"; + std::cout << "# Events: " << nEvents << "\n"; + std::cout << "# MB events: " << nEventsMB << "\n"; + std::cout << "# events injected with " << checkPdgQuarkOne << ": " << nEventsInjOne << "\n"; + std::cout << "# events injected with " << checkPdgQuarkTwo << ": " << nEventsInjTwo << "\n"; + std::cout << "# signal hadrons: " << nSignals << "\n"; + std::cout << "# signal hadrons decaying in correct channels: " << nSignalGoodDecay << "\n"; + + for (auto& [pdg, count] : signalHadronsPerType) { + int good = signalGoodDecayPerType[pdg]; + float frac = count>0 ? float(good)/count : 0.; + std::cout << "Particle " << pdg << ": " << count << " signals, " << good << " good decays, fraction: " << frac << "\n"; + } + + // Optional: sanity checks... + return 0; +} diff --git a/MC/config/PWGHF/ini/tests/GeneratorHF_D2H_ccbar_and_bbbar_gap5_Mode2.C b/MC/config/PWGHF/ini/tests/GeneratorHF_D2H_ccbar_and_bbbar_gap5_Mode2.C index e5c0bf08d..3f348adb3 100644 --- a/MC/config/PWGHF/ini/tests/GeneratorHF_D2H_ccbar_and_bbbar_gap5_Mode2.C +++ b/MC/config/PWGHF/ini/tests/GeneratorHF_D2H_ccbar_and_bbbar_gap5_Mode2.C @@ -7,13 +7,74 @@ int External() { std::vector checkPdgHadron{411, 421, 431, 4122, 4132, 4232, 4332}; std::map>> checkHadronDecays{ // sorted pdg of daughters - {411, {{-321, 211, 211}, {-313, 211}, {211, 311}, {211, 333}}}, // D+ - {421, {{-321, 211}, {-321, 111, 211}}}, // D0 - {431, {{211, 333}, {-313, 321}}}, // Ds+ - {4122, {{-313, 2212}, {-321, 2224}, {211, 102134}, {-321, 211, 2212}, {311, 2212}}}, // Lc+ - {4132, {{211, 3312}}}, // Xic0 - {4232, {{-313, 2212}, {-321, 3324}, {211, 211, 3312}, {-321, 211, 2212}}}, // Xic+ - {4332, {{211, 3334}}} // Omegac+ + {421, { + {-321, 211}, // D0 -> K-, pi+ + {-321, 211, 111}, // D0 -> K-, pi+, pi0 + {213, -321}, // D0 -> rho(770)+, K- + {-313, 111}, // D0 -> Kbar^*(892)0, pi0 + {-323, 211}, // D0 -> K^*(892)-, pi+ + {-211, 211}, // D0 -> pi-, pi+ + {213, -211}, // D0 -> rho(770)+, pi- + {-211, 211, 111}, // D0 -> pi-, pi+, pi0 + {-321, 321}, // D0 -> K-, K+ + }}, + + {411, { + {-321, 211, 211}, // D+ -> K-, pi+, pi+ + {-10311, 211}, // D+ -> Kbar0^*(1430)0, pi+ + {-313, 211}, // D+ -> Kbar^*(892)0, pi+ + {-321, 211, 211, 111}, // D+ -> K-, pi+, pi+, pi0 + {333, 211}, // D+ -> phi(1020)0, pi+ + {-313, 321}, // D+ -> Kbar^*(892)0, K+ + {-10311, 321}, // D+ -> Kbar0^*(1430)0, K+ + {-321, 321, 211}, // D+ -> K-, K+, pi+ + {113, 211}, // D+ -> rho(770)0, pi+ + {225, 211}, // D+ -> f2(1270)0, pi+ + {-211, 211, 211}, // D+ -> pi-, pi+, pi+ + }}, + + {431, { + {333, 211}, // Ds+ -> phi(1020)0, pi+ + {-313, 321}, // Ds+ -> Kbar^*(892)0, K+ + {333, 213}, // Ds+ -> phi(1020)0, rho(770)+ + {113, 211}, // Ds+ -> rho(770)0, pi+ + {225, 211}, // Ds+ -> f2(1270)0, pi+ + {-211, 211, 211}, // Ds+ -> pi-, pi+, pi+ + {313, 211}, // Ds+ -> K^*(892)0, pi+ + {10221, 321}, // Ds+ -> f0(1370)0, K+ + {113, 321}, // Ds+ -> rho(770)0, K+ + {-211, 321, 211}, // Ds+ -> pi-, K+, pi+ + {221, 211}, // Ds+ -> eta, pi+ + }}, + + {4122, { + {2212, -321, 211}, // Lambdac+ -> p, K-, pi+ + {2212, -313}, // Lambdac+ -> p, Kbar^*(892)0 + {2224, -321}, // Lambdac+ -> Delta(1232)++, K- + {102134, 211}, // Lambdac+ -> 102134, pi+ + {2212, 311}, // Lambdac+ -> p, K0 + {2212, -321, 211, 111}, // Lambdac+ -> p, K-, pi+, pi0 + {2212, -211, 211}, // Lambdac+ -> p, pi-, pi+ + {2212, 333}, // Lambdac+ -> p, phi(1020)0 + }}, + + {4232, { + {2212, -321, 211}, // Xic+ -> p, K-, pi+ + {2212, -313}, // Xic+ -> p, Kbar^*(892)0 + {3312, 211, 211}, // Xic+ -> Xi-, pi+, pi+ + {2212, 333}, // Xic+ -> p, phi(1020)0 + {3222, -211, 211}, // Xic+ -> Sigma+, pi-, pi+ + {3324, 211}, // Xic+ -> Xi(1530)0, pi+ + }}, + + {4132, { + {3312, 211}, // Xic0 -> Xi-, pi+ + }}, + + {4332, { + {3334, 211}, // Omegac0 -> Omega-, pi+ + {3312, 211}, // Omegac0 -> Xi-, pi+ + }}, }; TFile file(path.c_str(), "READ"); @@ -66,7 +127,7 @@ int External() { for (int j{track.getFirstDaughterTrackId()}; j <= track.getLastDaughterTrackId(); ++j) { auto pdgDau = tracks->at(j).GetPdgCode(); pdgsDecay.push_back(pdgDau); - if (pdgDau != 333) { // phi is antiparticle of itself + if (pdgDau != 333 && pdgDau != 111 && pdgDau != 221 && pdgDau != 113 && pdgDau != 225) { // phi is antiparticle of itself pdgsDecayAntiPart.push_back(-pdgDau); } else { pdgsDecayAntiPart.push_back(pdgDau); @@ -77,6 +138,7 @@ int External() { std::sort(pdgsDecayAntiPart.begin(), pdgsDecayAntiPart.end()); for (auto &decay : checkHadronDecays[std::abs(pdg)]) { + std::sort(decay.begin(), decay.end()); if (pdgsDecay == decay || pdgsDecayAntiPart == decay) { nSignalGoodDecay++; break; @@ -118,8 +180,9 @@ int External() { return 1; } - float fracForcedDecays = float(nSignalGoodDecay) / nSignals; - if (fracForcedDecays < 0.9) { // we put some tolerance (e.g. due to oscillations which might change the final state) + float fracForcedDecays = nSignals ? float(nSignalGoodDecay) / nSignals : 0.0f; + float uncFracForcedDecays = nSignals ? std::sqrt(fracForcedDecays * (1 - fracForcedDecays) / nSignals) : 1.0f; + if (1 - fracForcedDecays > 0.15 + uncFracForcedDecays) { // we put some tolerance (e.g. due to oscillations which might change the final state) std::cerr << "Fraction of signals decaying into the correct channel " << fracForcedDecays << " lower than expected\n"; return 1; } diff --git a/MC/config/PWGHF/ini/tests/GeneratorHF_D2H_ccbar_and_bbbar_gap5_Mode2_CharmBaryons.C b/MC/config/PWGHF/ini/tests/GeneratorHF_D2H_ccbar_and_bbbar_gap5_Mode2_CharmBaryons.C index 46befa6ad..951f38df2 100644 --- a/MC/config/PWGHF/ini/tests/GeneratorHF_D2H_ccbar_and_bbbar_gap5_Mode2_CharmBaryons.C +++ b/MC/config/PWGHF/ini/tests/GeneratorHF_D2H_ccbar_and_bbbar_gap5_Mode2_CharmBaryons.C @@ -5,11 +5,25 @@ int External() { int checkPdgQuarkTwo{5}; float ratioTrigger = 1./5; // one event triggered out of 5 - std::vector checkPdgHadron{4132, 4332, 4232}; + std::vector checkPdgHadron{4132, 4232, 4332}; std::map>> checkHadronDecays{ // sorted pdg of daughters - {4132, {{211, 3312}}}, // Xic0 - {4332, {{211, 3334}, {211, 3312}}}, // Omegac0 - {4232, {{313, 2212}, {211, 321, 2212}, {211, 3324}, {211, 211, 3312}}} //Xic+ + {4232, { + {-321, 211, 2212}, // Xic+ -> p, K-, pi+ + {-313, 2212}, // Xic+ -> p, Kbar^*(892)0 + {211, 211, 3312}, // Xic+ -> Xi-, pi+, pi+ + {333, 2212}, // Xic+ -> p, phi(1020)0 + {-211, 211, 3222}, // Xic+ -> Sigma+, pi-, pi+ + {211, 3324}, // Xic+ -> Xi(1530)0, pi+ + }}, + + {4132, { + {211, 3312}, // Xic0 -> Xi-, pi+ + }}, + + {4332, { + {211, 3334}, // Omegac0 -> Omega-, pi+ + {211, 3312}, // Omegac0 -> Xi-, pi+ + }}, }; TFile file(path.c_str(), "READ"); @@ -114,8 +128,9 @@ int External() { return 1; } - float fracForcedDecays = float(nSignalGoodDecay) / nSignals; - if (fracForcedDecays < 0.9) { // we put some tolerance (e.g. due to oscillations which might change the final state) + float fracForcedDecays = nSignals ? float(nSignalGoodDecay) / nSignals : 0.0f; + float uncFracForcedDecays = nSignals ? std::sqrt(fracForcedDecays * (1 - fracForcedDecays) / nSignals) : 1.0f; + if (1 - fracForcedDecays > 0.15 + uncFracForcedDecays) { // we put some tolerance (e.g. due to oscillations which might change the final state) std::cerr << "Fraction of signals decaying into the correct channel " << fracForcedDecays << " lower than expected\n"; return 1; } diff --git a/MC/config/PWGHF/ini/tests/GeneratorHF_D2H_ccbar_and_bbbar_gap5_Mode2_CharmBaryons_pp_ref.C b/MC/config/PWGHF/ini/tests/GeneratorHF_D2H_ccbar_and_bbbar_gap5_Mode2_CharmBaryons_pp_ref.C new file mode 100644 index 000000000..ad9f15bfe --- /dev/null +++ b/MC/config/PWGHF/ini/tests/GeneratorHF_D2H_ccbar_and_bbbar_gap5_Mode2_CharmBaryons_pp_ref.C @@ -0,0 +1,190 @@ +int External() { + std::string path{"o2sim_Kine.root"}; + + int checkPdgQuarkOne{4}; + int checkPdgQuarkTwo{5}; + float ratioTrigger = 1./5; // one event triggered out of 5 + + std::vector checkPdgHadron{411, 421, 431, 4122, 4132, 4232, 4332}; + std::map>> checkHadronDecays{ // sorted pdg of daughters + {421, { + {-321, 211}, // D0 -> K-, pi+ + {-321, 211, 111}, // D0 -> K-, pi+, pi0 + {213, -321}, // D0 -> rho(770)+, K- + {-313, 111}, // D0 -> Kbar^*(892)0, pi0 + {-323, 211}, // D0 -> K^*(892)-, pi+ + {-211, 211}, // D0 -> pi-, pi+ + {213, -211}, // D0 -> rho(770)+, pi- + {-211, 211, 111}, // D0 -> pi-, pi+, pi0 + {-321, 321}, // D0 -> K-, K+ + }}, + + {411, { + {-321, 211, 211}, // D+ -> K-, pi+, pi+ + {-10311, 211}, // D+ -> Kbar0^*(1430)0, pi+ + {-313, 211}, // D+ -> Kbar^*(892)0, pi+ + {-321, 211, 211, 111}, // D+ -> K-, pi+, pi+, pi0 + {333, 211}, // D+ -> phi(1020)0, pi+ + {-313, 321}, // D+ -> Kbar^*(892)0, K+ + {-10311, 321}, // D+ -> Kbar0^*(1430)0, K+ + {-321, 321, 211}, // D+ -> K-, K+, pi+ + {113, 211}, // D+ -> rho(770)0, pi+ + {225, 211}, // D+ -> f2(1270)0, pi+ + {-211, 211, 211}, // D+ -> pi-, pi+, pi+ + }}, + + {431, { + {211, 333}, // Ds+ -> phi(1020)0, pi+ + {-313, 321}, // Ds+ -> Kbar^*(892)0, K+ + {333, 213}, // Ds+ -> phi(1020)0, rho(770)+ + {113, 211}, // Ds+ -> rho(770)0, pi+ + {225, 211}, // Ds+ -> f2(1270)0, pi+ + {-211, 211, 211}, // Ds+ -> pi-, pi+, pi+ + {313, 211}, // Ds+ -> K^*(892)0, pi+ + {10221, 321}, // Ds+ -> f0(1370)0, K+ + {113, 321}, // Ds+ -> rho(770)0, K+ + {-211, 321, 211}, // Ds+ -> pi-, K+, pi+ + {221, 211}, // Ds+ -> eta, pi+ + }}, + + {4122, { + {2212, -321, 211}, // Lambdac+ -> p, K-, pi+ + {2212, -313}, // Lambdac+ -> p, Kbar^*(892)0 + {2224, -321}, // Lambdac+ -> Delta(1232)++, K- + {102134, 211}, // Lambdac+ -> 102134, pi+ + {2212, 311}, // Lambdac+ -> p, K0 + {2212, -321, 211, 111}, // Lambdac+ -> p, K-, pi+, pi0 + {2212, -211, 211}, // Lambdac+ -> p, pi-, pi+ + {2212, 333}, // Lambdac+ -> p, phi(1020)0 + }}, + {4232, { + {2212, -321, 211}, // Xic+ -> p, K-, pi+ + {2212, -313}, // Xic+ -> p, Kbar^*(892)0 + {3312, 211, 211}, // Xic+ -> Xi-, pi+, pi+ + {2212, 333}, // Xic+ -> p, phi(1020)0 + {3222, -211, 211}, // Xic+ -> Sigma+, pi-, pi+ + {3324, 211}, // Xic+ -> Xi(1530)0, pi+ + }}, + + {4132, { + {3312, 211}, // Xic0 -> Xi-, pi+ + }}, + + {4332, { + {3334, 211}, // Omegac0 -> Omega-, pi+ + {3312, 211}, // Omegac0 -> Xi-, pi+ + }}, + }; + + TFile file(path.c_str(), "READ"); + if (file.IsZombie()) { + std::cerr << "Cannot open ROOT file " << path << "\n"; + return 1; + } + + auto tree = (TTree *)file.Get("o2sim"); + std::vector *tracks{}; + tree->SetBranchAddress("MCTrack", &tracks); + o2::dataformats::MCEventHeader *eventHeader = nullptr; + tree->SetBranchAddress("MCEventHeader.", &eventHeader); + + int nEventsMB{}, nEventsInjOne{}, nEventsInjTwo{}; + int nQuarksOne{}, nQuarksTwo{}, nSignals{}, nSignalGoodDecay{}; + auto nEvents = tree->GetEntries(); + + for (int i = 0; i < nEvents; i++) { + tree->GetEntry(i); + + // check subgenerator information + if (eventHeader->hasInfo(o2::mcgenid::GeneratorProperty::SUBGENERATORID)) { + bool isValid = false; + int subGeneratorId = eventHeader->getInfo(o2::mcgenid::GeneratorProperty::SUBGENERATORID, isValid); + if (subGeneratorId == 0) { + nEventsMB++; + } else if (subGeneratorId == checkPdgQuarkOne) { + nEventsInjOne++; + } else if (subGeneratorId == checkPdgQuarkTwo) { + nEventsInjTwo++; + } + } + + for (auto &track : *tracks) { + auto pdg = track.GetPdgCode(); + if (std::abs(pdg) == checkPdgQuarkOne) { + nQuarksOne++; + continue; + } + if (std::abs(pdg) == checkPdgQuarkTwo) { + nQuarksTwo++; + continue; + } + if (std::find(checkPdgHadron.begin(), checkPdgHadron.end(), std::abs(pdg)) != checkPdgHadron.end()) { // found signal + nSignals++; // count signal PDG + + std::vector pdgsDecay{}; + std::vector pdgsDecayAntiPart{}; + for (int j{track.getFirstDaughterTrackId()}; j <= track.getLastDaughterTrackId(); ++j) { + auto pdgDau = tracks->at(j).GetPdgCode(); + pdgsDecay.push_back(pdgDau); + if (pdgDau != 333 && pdgDau != 111 && pdgDau != 221 && pdgDau != 113 && pdgDau != 225) { // phi is antiparticle of itself + pdgsDecayAntiPart.push_back(-pdgDau); + } else { + pdgsDecayAntiPart.push_back(pdgDau); + } + } + + std::sort(pdgsDecay.begin(), pdgsDecay.end()); + std::sort(pdgsDecayAntiPart.begin(), pdgsDecayAntiPart.end()); + + for (auto &decay : checkHadronDecays[std::abs(pdg)]) { + std::sort(decay.begin(), decay.end()); + if (pdgsDecay == decay || pdgsDecayAntiPart == decay) { + nSignalGoodDecay++; + break; + } + } + } + } + } + + std::cout << "--------------------------------\n"; + std::cout << "# Events: " << nEvents << "\n"; + std::cout << "# MB events: " << nEventsMB << "\n"; + std::cout << Form("# events injected with %d quark pair: ", checkPdgQuarkOne) << nEventsInjOne << "\n"; + std::cout << Form("# events injected with %d quark pair: ", checkPdgQuarkTwo) << nEventsInjTwo << "\n"; + std::cout << Form("# %d (anti)quarks: ", checkPdgQuarkOne) << nQuarksOne << "\n"; + std::cout << Form("# %d (anti)quarks: ", checkPdgQuarkTwo) << nQuarksTwo << "\n"; + std::cout <<"# signal hadrons: " << nSignals << "\n"; + std::cout <<"# signal hadrons decaying in the correct channel: " << nSignalGoodDecay << "\n"; + + if (nEventsMB < nEvents * (1 - ratioTrigger) * 0.95 || nEventsMB > nEvents * (1 - ratioTrigger) * 1.05) { // we put some tolerance since the number of generated events is small + std::cerr << "Number of generated MB events different than expected\n"; + return 1; + } + if (nEventsInjOne < nEvents * ratioTrigger * 0.5 * 0.95 || nEventsInjOne > nEvents * ratioTrigger * 0.5 * 1.05) { + std::cerr << "Number of generated events injected with " << checkPdgQuarkOne << " different than expected\n"; + return 1; + } + if (nEventsInjTwo < nEvents * ratioTrigger * 0.5 * 0.95 || nEventsInjTwo > nEvents * ratioTrigger * 0.5 * 1.05) { + std::cerr << "Number of generated events injected with " << checkPdgQuarkTwo << " different than expected\n"; + return 1; + } + + if (nQuarksOne < nEvents * ratioTrigger) { // we expect anyway more because the same quark is repeated several time, after each gluon radiation + std::cerr << "Number of generated (anti)quarks " << checkPdgQuarkOne << " lower than expected\n"; + return 1; + } + if (nQuarksTwo < nEvents * ratioTrigger) { // we expect anyway more because the same quark is repeated several time, after each gluon radiation + std::cerr << "Number of generated (anti)quarks " << checkPdgQuarkTwo << " lower than expected\n"; + return 1; + } + + float fracForcedDecays = nSignals ? float(nSignalGoodDecay) / nSignals : 0.0f; + float uncFracForcedDecays = nSignals ? std::sqrt(fracForcedDecays * (1 - fracForcedDecays) / nSignals) : 1.0f; + if (1 - fracForcedDecays > 0.15 + uncFracForcedDecays) { // we put some tolerance (e.g. due to oscillations which might change the final state) + std::cerr << "Fraction of signals decaying into the correct channel " << fracForcedDecays << " lower than expected\n"; + return 1; + } + + return 0; +} diff --git a/MC/config/PWGHF/ini/tests/GeneratorHF_D2H_ccbar_and_bbbar_gap5_Mode2_XiC.C b/MC/config/PWGHF/ini/tests/GeneratorHF_D2H_ccbar_and_bbbar_gap5_Mode2_XiC.C index b9b398cfe..2c56754d6 100644 --- a/MC/config/PWGHF/ini/tests/GeneratorHF_D2H_ccbar_and_bbbar_gap5_Mode2_XiC.C +++ b/MC/config/PWGHF/ini/tests/GeneratorHF_D2H_ccbar_and_bbbar_gap5_Mode2_XiC.C @@ -112,8 +112,9 @@ int External() { return 1; } - float fracForcedDecays = float(nSignalGoodDecay) / nSignals; - if (fracForcedDecays < 0.9) { // we put some tolerance (e.g. due to oscillations which might change the final state) + float fracForcedDecays = nSignals ? float(nSignalGoodDecay) / nSignals : 0.0f; + float uncFracForcedDecays = nSignals ? std::sqrt(fracForcedDecays * (1 - fracForcedDecays) / nSignals) : 1.0f; + if (1 - fracForcedDecays > 0.15 + uncFracForcedDecays) { // we put some tolerance (e.g. due to oscillations which might change the final state) std::cerr << "Fraction of signals decaying into the correct channel " << fracForcedDecays << " lower than expected\n"; return 1; } diff --git a/MC/config/PWGHF/ini/tests/GeneratorHF_D2H_ccbar_and_bbbar_gap5_Mode2_XiC_OmegaC.C b/MC/config/PWGHF/ini/tests/GeneratorHF_D2H_ccbar_and_bbbar_gap5_Mode2_XiC_OmegaC.C index 909ba4ccb..ab13f5c41 100644 --- a/MC/config/PWGHF/ini/tests/GeneratorHF_D2H_ccbar_and_bbbar_gap5_Mode2_XiC_OmegaC.C +++ b/MC/config/PWGHF/ini/tests/GeneratorHF_D2H_ccbar_and_bbbar_gap5_Mode2_XiC_OmegaC.C @@ -113,8 +113,9 @@ int External() { return 1; } - float fracForcedDecays = float(nSignalGoodDecay) / nSignals; - if (fracForcedDecays < 0.9) { // we put some tolerance (e.g. due to oscillations which might change the final state) + float fracForcedDecays = nSignals ? float(nSignalGoodDecay) / nSignals : 0.0f; + float uncFracForcedDecays = nSignals ? std::sqrt(fracForcedDecays * (1 - fracForcedDecays) / nSignals) : 1.0f; + if (1 - fracForcedDecays > 0.15 + uncFracForcedDecays) { // we put some tolerance (e.g. due to oscillations which might change the final state) std::cerr << "Fraction of signals decaying into the correct channel " << fracForcedDecays << " lower than expected\n"; return 1; } diff --git a/MC/config/PWGHF/ini/tests/GeneratorHF_D2H_ccbar_and_bbbar_gap5_Mode2_corrBkg.C b/MC/config/PWGHF/ini/tests/GeneratorHF_D2H_ccbar_and_bbbar_gap5_Mode2_corrBkg.C new file mode 100644 index 000000000..0b40d30fd --- /dev/null +++ b/MC/config/PWGHF/ini/tests/GeneratorHF_D2H_ccbar_and_bbbar_gap5_Mode2_corrBkg.C @@ -0,0 +1,181 @@ +int External() { + std::string path{"o2sim_Kine.root"}; + + int checkPdgQuarkOne{4}; + int checkPdgQuarkTwo{5}; + float ratioTrigger = 1./5; // one event triggered out of 5 + + std::vector checkPdgHadron{411, 421, 431, 4122, 4132, 4232, 4332}; + std::map>> checkHadronDecays{ // sorted pdg of daughters + {411, { + {-321, 211, 211}, // K- π+ π+ (non-resonant) + {-321, 111, 211, 211}, // K- π+ π+ π0 (non-resonant) + {-313, 321}, // K*0(892) K+ + {-10311, 321}, // K*0(1430) K+ + {211, 333}, // φ π+ + {-321, 211, 321}, // K- K+ π+ (non-resonant) + {113, 211}, // ρ0 π+ + {211, 225}, // f2(1270) π+ + {-211, 211, 211} // π- π+ π+ (non-resonant) + }}, + {421, { + {-321, 211}, // K- π+ (non-resonant) + {-321, 111, 211}, // K- π+ π0 + {-321, 213}, // ρ+ K- + {-313, 111}, // antiK*0(892) π0 + {-323, 211}, // K*-(892) π+ + {-211, 211}, // π- π+ + {-211, 213}, // ρ+ π- + {-211, 111, 211}, // π- π+ π0 + {-321, 321} // K- K+ + }}, + {431, { + {211, 333}, // φ π+ + {-313, 321}, // antiK*(892) K+ + {213, 333}, // φ ρ + {113, 211}, // ρ π+ + {211, 225}, // f2(1270) π+ + {-211, 211, 211}, // π- π+ π+ (s-wave) + {211, 313}, // K*(892)0 π+ + {321, 10221}, // f0(1370) K+ + {113, 321}, // ρ0 K+ + {-211, 211, 321}, // π- K+ π+ (non-resonant) + {211, 221} // η π+ + }}, + {4122, { + {-321, 211, 2212}, // p K- π+ (non-resonant) + {-313, 2212}, // p K*0(892) + {-321, 2224}, // Δ++ K- + {211, 102134}, // Λ(1520) π+ + {-321, 111, 211, 2212}, // p K- π+ π0 + {-211, 211, 2212}, // p π- π+ + {333, 2212} // p φ + }}, + {4232, { + {-321, 211, 2212}, // Xic+ -> p, K-, pi+ + {-313, 2212}, // Xic+ -> p, Kbar^*(892)0 + {211, 211, 3312}, // Xic+ -> Xi-, pi+, pi+ + {333, 2212}, // Xic+ -> p, phi(1020)0 + {-211, 211, 3222}, // Xic+ -> Sigma+, pi-, pi+ + {211, 3324} // Xic+ -> Xi(1530)0, pi+ + }}, + {4132, { + {211, 3312}, // Xic0 -> Xi-, pi+ + }}, + {4332, { + {211, 3334}, // Omegac0 -> Omega-, pi+ + {211, 3312} // Omegac0 -> Xi-, pi+ + }} + }; + + TFile file(path.c_str(), "READ"); + if (file.IsZombie()) { + std::cerr << "Cannot open ROOT file " << path << "\n"; + return 1; + } + + auto tree = (TTree *)file.Get("o2sim"); + std::vector *tracks{}; + tree->SetBranchAddress("MCTrack", &tracks); + o2::dataformats::MCEventHeader *eventHeader = nullptr; + tree->SetBranchAddress("MCEventHeader.", &eventHeader); + + int nEventsMB{}, nEventsInjOne{}, nEventsInjTwo{}; + int nQuarksOne{}, nQuarksTwo{}, nSignals{}, nSignalGoodDecay{}; + auto nEvents = tree->GetEntries(); + + for (int i = 0; i < nEvents; i++) { + tree->GetEntry(i); + + // check subgenerator information + if (eventHeader->hasInfo(o2::mcgenid::GeneratorProperty::SUBGENERATORID)) { + bool isValid = false; + int subGeneratorId = eventHeader->getInfo(o2::mcgenid::GeneratorProperty::SUBGENERATORID, isValid); + if (subGeneratorId == 0) { + nEventsMB++; + } else if (subGeneratorId == checkPdgQuarkOne) { + nEventsInjOne++; + } else if (subGeneratorId == checkPdgQuarkTwo) { + nEventsInjTwo++; + } + } + + for (auto &track : *tracks) { + auto pdg = track.GetPdgCode(); + if (std::abs(pdg) == checkPdgQuarkOne) { + nQuarksOne++; + continue; + } + if (std::abs(pdg) == checkPdgQuarkTwo) { + nQuarksTwo++; + continue; + } + if (std::find(checkPdgHadron.begin(), checkPdgHadron.end(), std::abs(pdg)) != checkPdgHadron.end()) { // found signal + nSignals++; // count signal PDG + + std::vector pdgsDecay{}; + std::vector pdgsDecayAntiPart{}; + for (int j{track.getFirstDaughterTrackId()}; j <= track.getLastDaughterTrackId(); ++j) { + auto pdgDau = tracks->at(j).GetPdgCode(); + pdgsDecay.push_back(pdgDau); + if (pdgDau != 333 && pdgDau != 111 && pdgDau != 221 && pdgDau != 113 && pdgDau != 225) { // phi is antiparticle of itself + pdgsDecayAntiPart.push_back(-pdgDau); + } else { + pdgsDecayAntiPart.push_back(pdgDau); + } + } + + std::sort(pdgsDecay.begin(), pdgsDecay.end()); + std::sort(pdgsDecayAntiPart.begin(), pdgsDecayAntiPart.end()); + + for (auto &decay : checkHadronDecays[std::abs(pdg)]) { + if (pdgsDecay == decay || pdgsDecayAntiPart == decay) { + nSignalGoodDecay++; + break; + } + } + } + } + } + + std::cout << "--------------------------------\n"; + std::cout << "# Events: " << nEvents << "\n"; + std::cout << "# MB events: " << nEventsMB << "\n"; + std::cout << Form("# events injected with %d quark pair: ", checkPdgQuarkOne) << nEventsInjOne << "\n"; + std::cout << Form("# events injected with %d quark pair: ", checkPdgQuarkTwo) << nEventsInjTwo << "\n"; + std::cout << Form("# %d (anti)quarks: ", checkPdgQuarkOne) << nQuarksOne << "\n"; + std::cout << Form("# %d (anti)quarks: ", checkPdgQuarkTwo) << nQuarksTwo << "\n"; + std::cout <<"# signal hadrons: " << nSignals << "\n"; + std::cout <<"# signal hadrons decaying in the correct channel: " << nSignalGoodDecay << "\n"; + + if (nEventsMB < nEvents * (1 - ratioTrigger) * 0.95 || nEventsMB > nEvents * (1 - ratioTrigger) * 1.05) { // we put some tolerance since the number of generated events is small + std::cerr << "Number of generated MB events different than expected\n"; + return 1; + } + if (nEventsInjOne < nEvents * ratioTrigger * 0.5 * 0.95 || nEventsInjOne > nEvents * ratioTrigger * 0.5 * 1.05) { + std::cerr << "Number of generated events injected with " << checkPdgQuarkOne << " different than expected\n"; + return 1; + } + if (nEventsInjTwo < nEvents * ratioTrigger * 0.5 * 0.95 || nEventsInjTwo > nEvents * ratioTrigger * 0.5 * 1.05) { + std::cerr << "Number of generated events injected with " << checkPdgQuarkTwo << " different than expected\n"; + return 1; + } + + if (nQuarksOne < nEvents * ratioTrigger) { // we expect anyway more because the same quark is repeated several time, after each gluon radiation + std::cerr << "Number of generated (anti)quarks " << checkPdgQuarkOne << " lower than expected\n"; + return 1; + } + if (nQuarksTwo < nEvents * ratioTrigger) { // we expect anyway more because the same quark is repeated several time, after each gluon radiation + std::cerr << "Number of generated (anti)quarks " << checkPdgQuarkTwo << " lower than expected\n"; + return 1; + } + + float fracForcedDecays = nSignals ? float(nSignalGoodDecay) / nSignals : 0.0f; + float uncFracForcedDecays = nSignals ? std::sqrt(fracForcedDecays * (1 - fracForcedDecays) / nSignals) : 1.0f; + if (1 - fracForcedDecays > 0.15 + uncFracForcedDecays) { // we put some tolerance (e.g. due to oscillations which might change the final state) + std::cerr << "Fraction of signals decaying into the correct channel " << fracForcedDecays << " lower than expected\n"; + return 1; + } + + return 0; +} diff --git a/MC/config/PWGHF/ini/tests/GeneratorHF_D2H_ccbar_and_bbbar_gap5_Mode2_corrBkgSigmaC.C b/MC/config/PWGHF/ini/tests/GeneratorHF_D2H_ccbar_and_bbbar_gap5_Mode2_corrBkgSigmaC.C new file mode 100644 index 000000000..e6622a0fa --- /dev/null +++ b/MC/config/PWGHF/ini/tests/GeneratorHF_D2H_ccbar_and_bbbar_gap5_Mode2_corrBkgSigmaC.C @@ -0,0 +1,222 @@ +#include "TFile.h" +#include "TTree.h" + +#include +#include + +int External() { + std::string path{"o2sim_Kine.root"}; + + int checkPdgQuarkOne{4}; + int checkPdgQuarkTwo{5}; + float ratioTrigger = 1./5.; // one event triggered out of 5 + std::array, 2> pdgReplParticles = {std::array{413, 14122}, std::array{413, 4124}}; + std::array, 2> pdgReplPartCounters = {std::array{0, 0}, std::array{0, 0}}; + std::array freqRepl = {0.5, 0.5}; + std::map sumOrigReplacedParticles = {{413, 0}}; + + std::array checkPdgHadron{413, 14122, 4124}; + std::map>> checkHadronDecays{ // sorted (!) pdg of daughters + //{14122, {{4222, -211}, {4112, 211}, {4122, 211, -211}}}, // Lc(2595)+ + //{4124, {{4222, -211}, {4112, 211}, {4122, 211, -211}}} // Lc(2625)+ + {14122, {{-211, 4222}, {211, 4112}, {-211, 211, 4122}}}, // Lc(2595)+ + {4124, {{-211, 4222}, {211, 4112}, {-211, 211, 4122}}}, // Lc(2625)+ + {413, {{22, 411}, {111, 411}, {211, 421}}} // D*+ as in PYTHIA + }; + + TFile file(path.c_str(), "READ"); + if (file.IsZombie()) { + std::cerr << "Cannot open ROOT file " << path << "\n"; + return 1; + } + + auto tree = (TTree *)file.Get("o2sim"); + std::vector *tracks{}; + tree->SetBranchAddress("MCTrack", &tracks); + o2::dataformats::MCEventHeader *eventHeader = nullptr; + tree->SetBranchAddress("MCEventHeader.", &eventHeader); + + int nEventsMB{}, nEventsInjOne{}, nEventsInjTwo{}; + int nSignals{}, nSignalGoodDecay{}; + auto nEvents = tree->GetEntries(); + + for (int i = 0; i < nEvents; i++) { + + std::cout << std::endl; + + tree->GetEntry(i); + + // check subgenerator information + int subGeneratorId{-1}; + if (eventHeader->hasInfo(o2::mcgenid::GeneratorProperty::SUBGENERATORID)) { + bool isValid = false; + subGeneratorId = eventHeader->getInfo(o2::mcgenid::GeneratorProperty::SUBGENERATORID, isValid); + if (subGeneratorId == 0) { + nEventsMB++; + } else if (subGeneratorId == checkPdgQuarkOne) { + nEventsInjOne++; + } else if (subGeneratorId == checkPdgQuarkTwo) { + nEventsInjTwo++; + } + } + + for (auto &track : *tracks) { + auto pdg = track.GetPdgCode(); + auto absPdg = std::abs(pdg); + if (std::find(checkPdgHadron.begin(), checkPdgHadron.end(), absPdg) != checkPdgHadron.end()) { // found signal + nSignals++; // count signal PDG + std::cout << std::endl << "==> signal " << absPdg << " found!" << std::endl; + + if (subGeneratorId == checkPdgQuarkOne) { // replacement only for prompt ---> BUT ALSO NON-PROMPT D* SEEM TO BE REPLACED + for (int iRepl{0}; iRepl<2; ++iRepl) { + if (absPdg == pdgReplParticles[iRepl][0]) { + pdgReplPartCounters[iRepl][0]++; + sumOrigReplacedParticles[pdgReplParticles[iRepl][0]]++; + } else if (absPdg == pdgReplParticles[iRepl][1]) { + pdgReplPartCounters[iRepl][1]++; + sumOrigReplacedParticles[pdgReplParticles[iRepl][0]]++; + } + } + } + else if (subGeneratorId == checkPdgQuarkTwo && (absPdg == pdgReplParticles[0][1] || absPdg == pdgReplParticles[1][1])) { + std::cout << " NB: we have a " << absPdg << " also in event with quark " << checkPdgQuarkTwo << ", i.e in an event with c-cbar pair present, tagged with a b-bbar (e.g. double-parton scattering)" << std::endl; + std::cout << " ### mother indices: "; + int idFirstMother = track.getMotherTrackId(); + int idSecondMother = track.getSecondMotherTrackId(); + std::vector motherIds = {}; + for(int i=idFirstMother; i<=idSecondMother; i++) { + std::cout << i << " "; + motherIds.push_back(i); + } + std::cout << std::endl; + + /// To establish if the partonic event is switched on or not, check if the motherIds are all -1 for the current hadron + /// This is ok for Lc excited states deriving from the replacement of a prompt D*+ + /// Instead, Lc excited states coming from Lb decays (i.e. not coming from a D*+ replacement))have at least one mother that has idx !=-1 (*) + bool partonicEventOn = false; + bool motherIdsAllMinus1 = true; + for(int idx : motherIds) { + if(idx != -1) { + /// one mother id different from + motherIdsAllMinus1 = false; + break; + } + } + //if(motherIds != std::vector{-1, -1}) { + if(!motherIdsAllMinus1) { + std::cout << "The " << absPdg << " particle has mothers. This should mean that it comes directly from parton hadronization, and that the partonic event was kept in the MC production " << std::endl; + partonicEventOn = true; + } + + std::cout << " ### mother PDG codes: "; + std::vector motherPdgCodes = {}; + bool updateCounters = true; + if(partonicEventOn) { + for(int i=idFirstMother; i<=idSecondMother; i++) { + motherPdgCodes.push_back(tracks->at(i).GetPdgCode()); + std::cout << motherPdgCodes.back() << " "; + } + + /// check that among the mothers there is a c/cbar quark + /// This means that the charm hadron comes from the c-quark hadronization, where the c/cbar quark + /// comes from a c-cbar pair present in the current event, tagged with a b-bbar (e.g. double-parton scattering) + if(std::find(motherPdgCodes.begin(), motherPdgCodes.end(), 4) == motherPdgCodes.end() && std::find(motherPdgCodes.begin(), motherPdgCodes.end(), -4) == motherPdgCodes.end()) { + /// if we arrive here, it means that the hadron comes from the decay of a beauty hadron. + /// This can happen if and only if this is not a replaced one (i.e. native from Lambdab0 decay) + if (std::find(motherPdgCodes.begin(), motherPdgCodes.end(), 5122) == motherPdgCodes.end() && std::find(motherPdgCodes.begin(), motherPdgCodes.end(), -5122) == motherPdgCodes.end()) { + std::cerr << "The particle " << absPdg << " does not originate neither from a c/c-bar quark (replaced) nor from a Lambda_b0 decay. There is something wrong, aborting..." << std::endl; + return 1; + } + /// since this is a native Lc excited state from Lb0 decay, we must not update the replacement counters + updateCounters = false; + } + } + std::cout << std::endl; + + /// update the counters only if the Lc excited state comes from a replaced prompt D*+, i.e. not from a Lb0 decay + if (!updateCounters) continue; + + /// only if we arrive here it means that everything is ok, and we can safely update the counters for the final statistics + for (int iRepl{0}; iRepl<2; ++iRepl) { + if (absPdg == pdgReplParticles[iRepl][0]) { + pdgReplPartCounters[iRepl][0]++; + sumOrigReplacedParticles[pdgReplParticles[iRepl][0]]++; + } else if (absPdg == pdgReplParticles[iRepl][1]) { + pdgReplPartCounters[iRepl][1]++; + sumOrigReplacedParticles[pdgReplParticles[iRepl][0]]++; + } + } + } + + + std::vector pdgsDecay{}; + std::vector pdgsDecayAntiPart{}; + if (track.getFirstDaughterTrackId() >= 0 && track.getLastDaughterTrackId() >= 0) { + for (int j{track.getFirstDaughterTrackId()}; j <= track.getLastDaughterTrackId(); ++j) { + auto pdgDau = tracks->at(j).GetPdgCode(); + pdgsDecay.push_back(pdgDau); + std::cout << " -- daughter " << j << ": " << pdgDau << std::endl; + if (pdgDau != 333 && pdgDau != 111) { // phi and pi0 are antiparticles of themselves + pdgsDecayAntiPart.push_back(-pdgDau); + } else { + pdgsDecayAntiPart.push_back(pdgDau); + } + } + } + + std::sort(pdgsDecay.begin(), pdgsDecay.end()); + std::sort(pdgsDecayAntiPart.begin(), pdgsDecayAntiPart.end()); + + for (auto &decay : checkHadronDecays[std::abs(pdg)]) { + if (pdgsDecay == decay || pdgsDecayAntiPart == decay) { + nSignalGoodDecay++; + std::cout << " !!! GOOD DECAY FOUND !!!" << std::endl; + break; + } + } + } + } // end loop over tracks + } + + std::cout << "--------------------------------\n"; + std::cout << "# Events: " << nEvents << "\n"; + std::cout << "# MB events: " << nEventsMB << "\n"; + std::cout << Form("# events injected with %d quark pair: ", checkPdgQuarkOne) << nEventsInjOne << "\n"; + std::cout << Form("# events injected with %d quark pair: ", checkPdgQuarkTwo) << nEventsInjTwo << "\n"; + std::cout <<"# signal hadrons: " << nSignals << "\n"; + std::cout <<"# signal hadrons decaying in the correct channel: " << nSignalGoodDecay << "\n"; + + if (nEventsMB < nEvents * (1 - ratioTrigger) * 0.90 || nEventsMB > nEvents * (1 - ratioTrigger) * 1.10) { // we put some tolerance since the number of generated events is small + std::cerr << "Number of generated MB events different than expected\n"; + return 1; + } + if (nEventsInjOne < nEvents * ratioTrigger * 0.5 * 0.90 || nEventsInjOne > nEvents * ratioTrigger * 0.5 * 1.10) { + std::cerr << "Number of generated events injected with " << checkPdgQuarkOne << " different than expected\n"; + return 1; + } + if (nEventsInjTwo < nEvents * ratioTrigger * 0.5 * 0.90 || nEventsInjTwo > nEvents * ratioTrigger * 0.5 * 1.10) { + std::cerr << "Number of generated events injected with " << checkPdgQuarkTwo << " different than expected\n"; + return 1; + } + + float fracForcedDecays = nSignals ? float(nSignalGoodDecay) / nSignals : 0.0f; + float uncFracForcedDecays = nSignals ? std::sqrt(fracForcedDecays * (1 - fracForcedDecays) / nSignals) : 1.0f; + if (1 - fracForcedDecays > 0.5 + uncFracForcedDecays) { // we put some tolerance (e.g. due to oscillations which might change the final state) + std::cerr << "Fraction of signals decaying into the correct channel " << fracForcedDecays << " lower than expected\n"; + return 1; + } + + // Check particle replacement ratios + for (int iRepl{0}; iRepl < 3; ++iRepl) { + float numPart = sumOrigReplacedParticles[pdgReplParticles[iRepl][0]]; + float fracMeas = numPart ? float(pdgReplPartCounters[iRepl][1]) / numPart : 0.0f; + float fracMeasUnc = (fracMeas && numPart != 1) ? std::sqrt(pdgReplPartCounters[iRepl][1]) / numPart : 1.0f; + + if (std::abs(fracMeas - freqRepl[iRepl]) > fracMeasUnc) { + std::cerr << "Fraction of replaced " << pdgReplParticles[iRepl][0] << " into " << pdgReplParticles[iRepl][1] << " is " << fracMeas <<" (expected "<< freqRepl[iRepl] << ")\n"; + return 1; + } + } + + return 0; +} diff --git a/MC/config/PWGHF/ini/tests/GeneratorHF_D2H_ccbar_and_bbbar_gap5_Mode2_pp_ref.C b/MC/config/PWGHF/ini/tests/GeneratorHF_D2H_ccbar_and_bbbar_gap5_Mode2_pp_ref.C new file mode 100644 index 000000000..a6f9ed435 --- /dev/null +++ b/MC/config/PWGHF/ini/tests/GeneratorHF_D2H_ccbar_and_bbbar_gap5_Mode2_pp_ref.C @@ -0,0 +1,191 @@ +int External() { + std::string path{"o2sim_Kine.root"}; + + int checkPdgQuarkOne{4}; + int checkPdgQuarkTwo{5}; + float ratioTrigger = 1./5; // one event triggered out of 5 + + std::vector checkPdgHadron{411, 421, 431, 4122, 4132, 4232, 4332}; + std::map>> checkHadronDecays{ // sorted pdg of daughters + {421, { + {-321, 211}, // D0 -> K-, pi+ + {-321, 211, 111}, // D0 -> K-, pi+, pi0 + {213, -321}, // D0 -> rho(770)+, K- + {-313, 111}, // D0 -> Kbar^*(892)0, pi0 + {-323, 211}, // D0 -> K^*(892)-, pi+ + {-211, 211}, // D0 -> pi-, pi+ + {213, -211}, // D0 -> rho(770)+, pi- + {-211, 211, 111}, // D0 -> pi-, pi+, pi0 + {-321, 321}, // D0 -> K-, K+ + }}, + + {411, { + {-321, 211, 211}, // D+ -> K-, pi+, pi+ + {-10311, 211}, // D+ -> Kbar0^*(1430)0, pi+ + {-313, 211}, // D+ -> Kbar^*(892)0, pi+ + {-321, 211, 211, 111}, // D+ -> K-, pi+, pi+, pi0 + {333, 211}, // D+ -> phi(1020)0, pi+ + {-313, 321}, // D+ -> Kbar^*(892)0, K+ + {-10311, 321}, // D+ -> Kbar0^*(1430)0, K+ + {-321, 321, 211}, // D+ -> K-, K+, pi+ + {113, 211}, // D+ -> rho(770)0, pi+ + {225, 211}, // D+ -> f2(1270)0, pi+ + {-211, 211, 211}, // D+ -> pi-, pi+, pi+ + }}, + + {431, { + {211, 333}, // Ds+ -> phi(1020)0, pi+ + {-313, 321}, // Ds+ -> Kbar^*(892)0, K+ + {333, 213}, // Ds+ -> phi(1020)0, rho(770)+ + {113, 211}, // Ds+ -> rho(770)0, pi+ + {225, 211}, // Ds+ -> f2(1270)0, pi+ + {-211, 211, 211}, // Ds+ -> pi-, pi+, pi+ + {313, 211}, // Ds+ -> K^*(892)0, pi+ + {10221, 321}, // Ds+ -> f0(1370)0, K+ + {113, 321}, // Ds+ -> rho(770)0, K+ + {-211, 321, 211}, // Ds+ -> pi-, K+, pi+ + {221, 211}, // Ds+ -> eta, pi+ + }}, + + {4122, { + {2212, -321, 211}, // Lambdac+ -> p, K-, pi+ + {2212, -313}, // Lambdac+ -> p, Kbar^*(892)0 + {2224, -321}, // Lambdac+ -> Delta(1232)++, K- + {102134, 211}, // Lambdac+ -> 102134, pi+ + {2212, 311}, // Lambdac+ -> p, K0 + {2212, -321, 211, 111}, // Lambdac+ -> p, K-, pi+, pi0 + {2212, -211, 211}, // Lambdac+ -> p, pi-, pi+ + {2212, 333}, // Lambdac+ -> p, phi(1020)0 + }}, + + {4232, { + {2212, -321, 211}, // Xic+ -> p, K-, pi+ + {2212, -313}, // Xic+ -> p, Kbar^*(892)0 + {3312, 211, 211}, // Xic+ -> Xi-, pi+, pi+ + {2212, 333}, // Xic+ -> p, phi(1020)0 + {3222, -211, 211}, // Xic+ -> Sigma+, pi-, pi+ + {3324, 211}, // Xic+ -> Xi(1530)0, pi+ + }}, + + {4132, { + {3312, 211}, // Xic0 -> Xi-, pi+ + }}, + + {4332, { + {3334, 211}, // Omegac0 -> Omega-, pi+ + {3312, 211}, // Omegac0 -> Xi-, pi+ + }}, + }; + + TFile file(path.c_str(), "READ"); + if (file.IsZombie()) { + std::cerr << "Cannot open ROOT file " << path << "\n"; + return 1; + } + + auto tree = (TTree *)file.Get("o2sim"); + std::vector *tracks{}; + tree->SetBranchAddress("MCTrack", &tracks); + o2::dataformats::MCEventHeader *eventHeader = nullptr; + tree->SetBranchAddress("MCEventHeader.", &eventHeader); + + int nEventsMB{}, nEventsInjOne{}, nEventsInjTwo{}; + int nQuarksOne{}, nQuarksTwo{}, nSignals{}, nSignalGoodDecay{}; + auto nEvents = tree->GetEntries(); + + for (int i = 0; i < nEvents; i++) { + tree->GetEntry(i); + + // check subgenerator information + if (eventHeader->hasInfo(o2::mcgenid::GeneratorProperty::SUBGENERATORID)) { + bool isValid = false; + int subGeneratorId = eventHeader->getInfo(o2::mcgenid::GeneratorProperty::SUBGENERATORID, isValid); + if (subGeneratorId == 0) { + nEventsMB++; + } else if (subGeneratorId == checkPdgQuarkOne) { + nEventsInjOne++; + } else if (subGeneratorId == checkPdgQuarkTwo) { + nEventsInjTwo++; + } + } + + for (auto &track : *tracks) { + auto pdg = track.GetPdgCode(); + if (std::abs(pdg) == checkPdgQuarkOne) { + nQuarksOne++; + continue; + } + if (std::abs(pdg) == checkPdgQuarkTwo) { + nQuarksTwo++; + continue; + } + if (std::find(checkPdgHadron.begin(), checkPdgHadron.end(), std::abs(pdg)) != checkPdgHadron.end()) { // found signal + nSignals++; // count signal PDG + + std::vector pdgsDecay{}; + std::vector pdgsDecayAntiPart{}; + for (int j{track.getFirstDaughterTrackId()}; j <= track.getLastDaughterTrackId(); ++j) { + auto pdgDau = tracks->at(j).GetPdgCode(); + pdgsDecay.push_back(pdgDau); + if (pdgDau != 333 && pdgDau != 111 && pdgDau != 221 && pdgDau != 113 && pdgDau != 225) { // phi is antiparticle of itself + pdgsDecayAntiPart.push_back(-pdgDau); + } else { + pdgsDecayAntiPart.push_back(pdgDau); + } + } + + std::sort(pdgsDecay.begin(), pdgsDecay.end()); + std::sort(pdgsDecayAntiPart.begin(), pdgsDecayAntiPart.end()); + + for (auto &decay : checkHadronDecays[std::abs(pdg)]) { + std::sort(decay.begin(), decay.end()); + if (pdgsDecay == decay || pdgsDecayAntiPart == decay) { + nSignalGoodDecay++; + break; + } + } + } + } + } + + std::cout << "--------------------------------\n"; + std::cout << "# Events: " << nEvents << "\n"; + std::cout << "# MB events: " << nEventsMB << "\n"; + std::cout << Form("# events injected with %d quark pair: ", checkPdgQuarkOne) << nEventsInjOne << "\n"; + std::cout << Form("# events injected with %d quark pair: ", checkPdgQuarkTwo) << nEventsInjTwo << "\n"; + std::cout << Form("# %d (anti)quarks: ", checkPdgQuarkOne) << nQuarksOne << "\n"; + std::cout << Form("# %d (anti)quarks: ", checkPdgQuarkTwo) << nQuarksTwo << "\n"; + std::cout <<"# signal hadrons: " << nSignals << "\n"; + std::cout <<"# signal hadrons decaying in the correct channel: " << nSignalGoodDecay << "\n"; + + if (nEventsMB < nEvents * (1 - ratioTrigger) * 0.95 || nEventsMB > nEvents * (1 - ratioTrigger) * 1.05) { // we put some tolerance since the number of generated events is small + std::cerr << "Number of generated MB events different than expected\n"; + return 1; + } + if (nEventsInjOne < nEvents * ratioTrigger * 0.5 * 0.95 || nEventsInjOne > nEvents * ratioTrigger * 0.5 * 1.05) { + std::cerr << "Number of generated events injected with " << checkPdgQuarkOne << " different than expected\n"; + return 1; + } + if (nEventsInjTwo < nEvents * ratioTrigger * 0.5 * 0.95 || nEventsInjTwo > nEvents * ratioTrigger * 0.5 * 1.05) { + std::cerr << "Number of generated events injected with " << checkPdgQuarkTwo << " different than expected\n"; + return 1; + } + + if (nQuarksOne < nEvents * ratioTrigger) { // we expect anyway more because the same quark is repeated several time, after each gluon radiation + std::cerr << "Number of generated (anti)quarks " << checkPdgQuarkOne << " lower than expected\n"; + return 1; + } + if (nQuarksTwo < nEvents * ratioTrigger) { // we expect anyway more because the same quark is repeated several time, after each gluon radiation + std::cerr << "Number of generated (anti)quarks " << checkPdgQuarkTwo << " lower than expected\n"; + return 1; + } + + float fracForcedDecays = nSignals ? float(nSignalGoodDecay) / nSignals : 0.0f; + float uncFracForcedDecays = nSignals ? std::sqrt(fracForcedDecays * (1 - fracForcedDecays) / nSignals) : 1.0f; + if (1 - fracForcedDecays > 0.15 + uncFracForcedDecays) { // we put some tolerance (e.g. due to oscillations which might change the final state) + std::cerr << "Fraction of signals decaying into the correct channel " << fracForcedDecays << " lower than expected\n"; + return 1; + } + + return 0; +} diff --git a/MC/config/PWGHF/ini/tests/GeneratorHF_D2H_ccbar_and_bbbar_gap8.C b/MC/config/PWGHF/ini/tests/GeneratorHF_D2H_ccbar_and_bbbar_gap8.C index b6828e205..b4a723630 100644 --- a/MC/config/PWGHF/ini/tests/GeneratorHF_D2H_ccbar_and_bbbar_gap8.C +++ b/MC/config/PWGHF/ini/tests/GeneratorHF_D2H_ccbar_and_bbbar_gap8.C @@ -118,8 +118,9 @@ int External() { return 1; } - float fracForcedDecays = float(nSignalGoodDecay) / nSignals; - if (fracForcedDecays < 0.9) { // we put some tolerance (e.g. due to oscillations which might change the final state) + float fracForcedDecays = nSignals ? float(nSignalGoodDecay) / nSignals : 0.0f; + float uncFracForcedDecays = nSignals ? std::sqrt(fracForcedDecays * (1 - fracForcedDecays) / nSignals) : 1.0f; + if (1 - fracForcedDecays > 0.15 + uncFracForcedDecays) { // we put some tolerance (e.g. due to oscillations which might change the final state) std::cerr << "Fraction of signals decaying into the correct channel " << fracForcedDecays << " lower than expected\n"; return 1; } diff --git a/MC/config/PWGHF/ini/tests/GeneratorHF_D2H_ccbar_and_bbbar_gap8_Mode2_XiC.C b/MC/config/PWGHF/ini/tests/GeneratorHF_D2H_ccbar_and_bbbar_gap8_Mode2_XiC.C index 596639d12..4e143c055 100644 --- a/MC/config/PWGHF/ini/tests/GeneratorHF_D2H_ccbar_and_bbbar_gap8_Mode2_XiC.C +++ b/MC/config/PWGHF/ini/tests/GeneratorHF_D2H_ccbar_and_bbbar_gap8_Mode2_XiC.C @@ -112,8 +112,9 @@ int External() { return 1; } - float fracForcedDecays = float(nSignalGoodDecay) / nSignals; - if (fracForcedDecays < 0.9) { // we put some tolerance (e.g. due to oscillations which might change the final state) + float fracForcedDecays = nSignals ? float(nSignalGoodDecay) / nSignals : 0.0f; + float uncFracForcedDecays = nSignals ? std::sqrt(fracForcedDecays * (1 - fracForcedDecays) / nSignals) : 1.0f; + if (1 - fracForcedDecays > 0.15 + uncFracForcedDecays) { // we put some tolerance (e.g. due to oscillations which might change the final state) std::cerr << "Fraction of signals decaying into the correct channel " << fracForcedDecays << " lower than expected\n"; return 1; } diff --git a/MC/config/PWGHF/ini/tests/GeneratorHF_D2H_ccbar_gap5.C b/MC/config/PWGHF/ini/tests/GeneratorHF_D2H_ccbar_gap5.C index 99a039e6f..38cc604cc 100644 --- a/MC/config/PWGHF/ini/tests/GeneratorHF_D2H_ccbar_gap5.C +++ b/MC/config/PWGHF/ini/tests/GeneratorHF_D2H_ccbar_gap5.C @@ -101,8 +101,9 @@ int External() { return 1; } - float fracForcedDecays = float(nSignalGoodDecay) / nSignals; - if (fracForcedDecays < 0.9) { // we put some tolerance (e.g. due to oscillations which might change the final state) + float fracForcedDecays = nSignals ? float(nSignalGoodDecay) / nSignals : 0.0f; + float uncFracForcedDecays = nSignals ? std::sqrt(fracForcedDecays * (1 - fracForcedDecays) / nSignals) : 1.0f; + if (1 - fracForcedDecays > 0.15 + uncFracForcedDecays) { // we put some tolerance (e.g. due to oscillations which might change the final state) std::cerr << "Fraction of signals decaying into the correct channel " << fracForcedDecays << " lower than expected\n"; return 1; } diff --git a/MC/config/PWGHF/ini/tests/GeneratorHF_HFe_ccbar_and_bbar_gap5_Mode2.C b/MC/config/PWGHF/ini/tests/GeneratorHF_HFe_ccbar_and_bbar_gap5_Mode2.C new file mode 100644 index 000000000..fb9df800e --- /dev/null +++ b/MC/config/PWGHF/ini/tests/GeneratorHF_HFe_ccbar_and_bbar_gap5_Mode2.C @@ -0,0 +1,128 @@ +int External() { + std::string path{"o2sim_Kine.root"}; + + int checkPdgDecayElectron = 11; + int checkPdgQuarkOne = 4; + int checkPdgQuarkTwo = 5; + float ratioTrigger = 1. / 5; // one event triggered out of 5 + + TFile file(path.c_str(), "READ"); + if (file.IsZombie()) { + std::cerr << "Cannot open ROOT file" << path << "\n"; + return 1; + } + + auto tree = (TTree *)file.Get("o2sim"); + if (!tree) { + std::cerr << "Cannot find tree o2sim in file" << path << "\n"; + return 1; + } + + std::vector *tracks{}; + tree->SetBranchAddress("MCTrack", &tracks); + o2::dataformats::MCEventHeader *eventHeader = nullptr; + tree->SetBranchAddress("MCEventHeader.", &eventHeader); + + int nEventsMB{}, nEventsInjOne{}, nEventsInjTwo{}; + int nQuarksOne{}, nQuarksTwo{}; + int nElectrons{}; + auto nEvents = tree->GetEntries(); + + for (int i = 0; i < nEvents; i++) { + tree->GetEntry(i); + + // check subgenerator information + if (eventHeader->hasInfo(o2::mcgenid::GeneratorProperty::SUBGENERATORID)) { + bool isValid = false; + int subGeneratorId = eventHeader->getInfo( + o2::mcgenid::GeneratorProperty::SUBGENERATORID, isValid); + if (subGeneratorId == 0) { + nEventsMB++; + } else if (subGeneratorId == checkPdgQuarkOne) { + nEventsInjOne++; + } else if (subGeneratorId == checkPdgQuarkTwo) { + nEventsInjTwo++; + } + } // if event header + + int nelectronsev = 0; + + for (auto &track : *tracks) { + auto pdg = track.GetPdgCode(); + if (std::abs(pdg) == checkPdgQuarkOne) { + nQuarksOne++; + continue; + } + if (std::abs(pdg) == checkPdgQuarkTwo) { + nQuarksTwo++; + continue; + } + + auto y = track.GetRapidity(); + if (std::abs(pdg) == checkPdgDecayElectron) { + int igmother = track.getMotherTrackId(); + auto gmTrack = (*tracks)[igmother]; + int gmpdg = gmTrack.GetPdgCode(); + if (int(std::abs(gmpdg) / 100.) == 4 || + int(std::abs(gmpdg) / 1000.) == 4 || + int(std::abs(gmpdg) / 100.) == 5 || + int(std::abs(gmpdg) / 1000.) == 5) { + nElectrons++; + nelectronsev++; + } // gmpdg + } // pdgdecay + } // loop track + // std::cout << "#electrons per event: " << nelectronsev << "\n"; + } + + std::cout << "--------------------------------\n"; + std::cout << "# Events: " << nEvents << "\n"; + std::cout << "# MB events: " << nEventsMB << "\n"; + std::cout << Form("# events injected with %d quark pair: ", checkPdgQuarkOne) + << nEventsInjOne << "\n"; + std::cout << Form("# events injected with %d quark pair: ", checkPdgQuarkTwo) + << nEventsInjTwo << "\n"; + std::cout << Form("# %d (anti)quarks: ", checkPdgQuarkOne) << nQuarksOne + << "\n"; + std::cout << Form("# %d (anti)quarks: ", checkPdgQuarkTwo) << nQuarksTwo + << "\n"; + + if (nEventsMB < nEvents * (1 - ratioTrigger) * 0.95 || + nEventsMB > nEvents * (1 - ratioTrigger) * + 1.05) { // we put some tolerance since the number of + // generated events is small + std::cerr << "Number of generated MB events different than expected\n"; + return 1; + } + if (nEventsInjOne < nEvents * ratioTrigger * 0.5 * 0.95 || + nEventsInjOne > nEvents * ratioTrigger * 0.5 * 1.05) { + std::cerr << "Number of generated events injected with " << checkPdgQuarkOne + << " different than expected\n"; + return 1; + } + if (nEventsInjTwo < nEvents * ratioTrigger * 0.5 * 0.95 || + nEventsInjTwo > nEvents * ratioTrigger * 0.5 * 1.05) { + std::cerr << "Number of generated events injected with " << checkPdgQuarkTwo + << " different than expected\n"; + return 1; + } + if (nQuarksOne < + nEvents * + ratioTrigger) { // we expect anyway more because the same quark is + // repeated several time, after each gluon radiation + std::cerr << "Number of generated (anti)quarks " << checkPdgQuarkOne + << " lower than expected\n"; + return 1; + } + if (nQuarksTwo < + nEvents * + ratioTrigger) { // we expect anyway more because the same quark is + // repeated several time, after each gluon radiation + std::cerr << "Number of generated (anti)quarks " << checkPdgQuarkTwo + << " lower than expected\n"; + return 1; + } + std::cout << "#electrons: " << nElectrons << "\n"; + + return 0; +} // external diff --git a/MC/config/PWGHF/ini/tests/GeneratorHF_HFe_ccbar_and_bbar_gap5_Mode2_pp_ref.C b/MC/config/PWGHF/ini/tests/GeneratorHF_HFe_ccbar_and_bbar_gap5_Mode2_pp_ref.C new file mode 100644 index 000000000..fb9df800e --- /dev/null +++ b/MC/config/PWGHF/ini/tests/GeneratorHF_HFe_ccbar_and_bbar_gap5_Mode2_pp_ref.C @@ -0,0 +1,128 @@ +int External() { + std::string path{"o2sim_Kine.root"}; + + int checkPdgDecayElectron = 11; + int checkPdgQuarkOne = 4; + int checkPdgQuarkTwo = 5; + float ratioTrigger = 1. / 5; // one event triggered out of 5 + + TFile file(path.c_str(), "READ"); + if (file.IsZombie()) { + std::cerr << "Cannot open ROOT file" << path << "\n"; + return 1; + } + + auto tree = (TTree *)file.Get("o2sim"); + if (!tree) { + std::cerr << "Cannot find tree o2sim in file" << path << "\n"; + return 1; + } + + std::vector *tracks{}; + tree->SetBranchAddress("MCTrack", &tracks); + o2::dataformats::MCEventHeader *eventHeader = nullptr; + tree->SetBranchAddress("MCEventHeader.", &eventHeader); + + int nEventsMB{}, nEventsInjOne{}, nEventsInjTwo{}; + int nQuarksOne{}, nQuarksTwo{}; + int nElectrons{}; + auto nEvents = tree->GetEntries(); + + for (int i = 0; i < nEvents; i++) { + tree->GetEntry(i); + + // check subgenerator information + if (eventHeader->hasInfo(o2::mcgenid::GeneratorProperty::SUBGENERATORID)) { + bool isValid = false; + int subGeneratorId = eventHeader->getInfo( + o2::mcgenid::GeneratorProperty::SUBGENERATORID, isValid); + if (subGeneratorId == 0) { + nEventsMB++; + } else if (subGeneratorId == checkPdgQuarkOne) { + nEventsInjOne++; + } else if (subGeneratorId == checkPdgQuarkTwo) { + nEventsInjTwo++; + } + } // if event header + + int nelectronsev = 0; + + for (auto &track : *tracks) { + auto pdg = track.GetPdgCode(); + if (std::abs(pdg) == checkPdgQuarkOne) { + nQuarksOne++; + continue; + } + if (std::abs(pdg) == checkPdgQuarkTwo) { + nQuarksTwo++; + continue; + } + + auto y = track.GetRapidity(); + if (std::abs(pdg) == checkPdgDecayElectron) { + int igmother = track.getMotherTrackId(); + auto gmTrack = (*tracks)[igmother]; + int gmpdg = gmTrack.GetPdgCode(); + if (int(std::abs(gmpdg) / 100.) == 4 || + int(std::abs(gmpdg) / 1000.) == 4 || + int(std::abs(gmpdg) / 100.) == 5 || + int(std::abs(gmpdg) / 1000.) == 5) { + nElectrons++; + nelectronsev++; + } // gmpdg + } // pdgdecay + } // loop track + // std::cout << "#electrons per event: " << nelectronsev << "\n"; + } + + std::cout << "--------------------------------\n"; + std::cout << "# Events: " << nEvents << "\n"; + std::cout << "# MB events: " << nEventsMB << "\n"; + std::cout << Form("# events injected with %d quark pair: ", checkPdgQuarkOne) + << nEventsInjOne << "\n"; + std::cout << Form("# events injected with %d quark pair: ", checkPdgQuarkTwo) + << nEventsInjTwo << "\n"; + std::cout << Form("# %d (anti)quarks: ", checkPdgQuarkOne) << nQuarksOne + << "\n"; + std::cout << Form("# %d (anti)quarks: ", checkPdgQuarkTwo) << nQuarksTwo + << "\n"; + + if (nEventsMB < nEvents * (1 - ratioTrigger) * 0.95 || + nEventsMB > nEvents * (1 - ratioTrigger) * + 1.05) { // we put some tolerance since the number of + // generated events is small + std::cerr << "Number of generated MB events different than expected\n"; + return 1; + } + if (nEventsInjOne < nEvents * ratioTrigger * 0.5 * 0.95 || + nEventsInjOne > nEvents * ratioTrigger * 0.5 * 1.05) { + std::cerr << "Number of generated events injected with " << checkPdgQuarkOne + << " different than expected\n"; + return 1; + } + if (nEventsInjTwo < nEvents * ratioTrigger * 0.5 * 0.95 || + nEventsInjTwo > nEvents * ratioTrigger * 0.5 * 1.05) { + std::cerr << "Number of generated events injected with " << checkPdgQuarkTwo + << " different than expected\n"; + return 1; + } + if (nQuarksOne < + nEvents * + ratioTrigger) { // we expect anyway more because the same quark is + // repeated several time, after each gluon radiation + std::cerr << "Number of generated (anti)quarks " << checkPdgQuarkOne + << " lower than expected\n"; + return 1; + } + if (nQuarksTwo < + nEvents * + ratioTrigger) { // we expect anyway more because the same quark is + // repeated several time, after each gluon radiation + std::cerr << "Number of generated (anti)quarks " << checkPdgQuarkTwo + << " lower than expected\n"; + return 1; + } + std::cout << "#electrons: " << nElectrons << "\n"; + + return 0; +} // external diff --git a/MC/config/PWGHF/ini/tests/GeneratorHF_Non_Hfe.C b/MC/config/PWGHF/ini/tests/GeneratorHF_Non_Hfe.C new file mode 100644 index 000000000..fb2c280d9 --- /dev/null +++ b/MC/config/PWGHF/ini/tests/GeneratorHF_Non_Hfe.C @@ -0,0 +1,61 @@ +int External() { + std::string path{"o2sim_Kine.root"}; + + const int pdgPi0 = 111; + const int pdgEta = 221; + const double yMin = -1.5; + const double yMax = 1.5; + const int minNb = 1; + + TFile file(path.c_str(), "READ"); + if (file.IsZombie()) { + std::cerr << "Cannot open ROOT file " << path << "\n"; + return 1; + } + + auto tree = (TTree*)file.Get("o2sim"); + if (!tree) { + std::cerr << "Cannot find tree o2sim\n"; + return 1; + } + + std::vector* tracks{}; + tree->SetBranchAddress("MCTrack", &tracks); + + int nEvents = tree->GetEntries(); + int nAccepted = 0; + int totalPi0 = 0, totalEta = 0; + + for (int i = 0; i < nEvents; ++i) { + tree->GetEntry(i); + + int count = 0; + for (auto& track : *tracks) { + int pdg = std::abs(track.GetPdgCode()); + double y = track.GetRapidity(); + + if ((pdg == pdgPi0 || pdg == pdgEta) && y >= yMin && y <= yMax) { + count++; + if (pdg == pdgPi0) totalPi0++; + if (pdg == pdgEta) totalEta++; + } + } + + if (count < minNb) { + std::cerr << " Trigger violation in event " << i + << " (found " << count << " π0/η in rapidity window)\n"; + return 1; + } + + nAccepted++; + } + + std::cout << "--------------------------------------\n"; + std::cout << "Trigger test: π0/η within rapidity window\n"; + std::cout << "Events tested: " << nEvents << "\n"; + std::cout << "Events accepted: " << nAccepted << "\n"; + std::cout << "# π0: " << totalPi0 << ", # η: " << totalEta << "\n"; + std::cout << "Trigger test PASSED\n"; + + return 0; +} diff --git a/MC/config/PWGHF/ini/tests/GeneratorHF_bbbar_fwd_gap4_natural_inel_Mode2.C b/MC/config/PWGHF/ini/tests/GeneratorHF_bbbar_fwd_gap4_natural_inel_Mode2.C new file mode 100644 index 000000000..34072820e --- /dev/null +++ b/MC/config/PWGHF/ini/tests/GeneratorHF_bbbar_fwd_gap4_natural_inel_Mode2.C @@ -0,0 +1,103 @@ +int External() { + + int checkPdgDecayMuon = 13; + int checkPdgQuark = 5; + + float ratioTrigger = 1. / 4; // one event triggered out of 4 + + std::string path{"o2sim_Kine.root"}; + + TFile file(path.c_str(), "READ"); + if (file.IsZombie()) { + std::cerr << "Cannot open ROOT file" << path << "\n"; + return 1; + } + + auto tree = (TTree *)file.Get("o2sim"); + if (!tree) { + std::cerr << "Cannot find tree o2sim in file" << path << "\n"; + return 1; + } + + std::vector *tracks{}; + tree->SetBranchAddress("MCTrack", &tracks); + + o2::dataformats::MCEventHeader *eventHeader = nullptr; + tree->SetBranchAddress("MCEventHeader.", &eventHeader); + + int nEventsMB{}; + int nEventsInj{}; + int nQuarks{}; + int nMuons{}; + + int nMuonsInAcceptance{}; + + auto nEvents = tree->GetEntries(); + + for (int i = 0; i < nEvents; i++) { + tree->GetEntry(i); + // check subgenerator information + if (eventHeader->hasInfo(o2::mcgenid::GeneratorProperty::SUBGENERATORID)) { + bool isValid = false; + int subGeneratorId = eventHeader->getInfo( + o2::mcgenid::GeneratorProperty::SUBGENERATORID, isValid); + if (subGeneratorId == 0) { + nEventsMB++; + } else if (subGeneratorId == checkPdgQuark) { + nEventsInj++; + } + } // if event header + + int nmuonsev = 0; + int nmuonsevinacc = 0; + + for (auto &track : *tracks) { + auto pdg = track.GetPdgCode(); + if (std::abs(pdg) == checkPdgQuark) { + nQuarks++; + continue; + } // pdgquark + auto y = track.GetRapidity(); + if (std::abs(pdg) == checkPdgDecayMuon) { + int igmother = track.getMotherTrackId(); + auto gmTrack = (*tracks)[igmother]; + int gmpdg = gmTrack.GetPdgCode(); + if (int(std::abs(gmpdg) / 100.) == 5 || + int(std::abs(gmpdg) / 1000.) == 5) { + nMuons++; + nmuonsev++; + if (-4.3 < y && y < -2.2) { + nMuonsInAcceptance++; + nmuonsevinacc++; + } + } // gmpdg + + } // pdgdecay + + } // loop track + // std::cout << "#muons per event: " << nmuonsev << "\n"; + // std::cout << "#muons in acceptance per event: " << nmuonsev << "\n"; + } // events + + std::cout << "#events: " << nEvents << "\n"; + std::cout << "# MB events: " << nEventsMB << "\n"; + std::cout << Form("# events injected with %d quark pair: ", checkPdgQuark) + << nEventsInj << "\n"; + if (nEventsMB < nEvents * (1 - ratioTrigger) * 0.95 || + nEventsMB > nEvents * (1 - ratioTrigger) * + 1.05) { // we put some tolerance since the number of + // generated events is small + std::cerr << "Number of generated MB events different than expected\n"; + return 1; + } + if (nEventsInj < nEvents * ratioTrigger * 0.95 || + nEventsInj > nEvents * ratioTrigger * 1.05) { + std::cerr << "Number of generated events injected with " << checkPdgQuark + << " different than expected\n"; + return 1; + } + std::cout << "#muons: " << nMuons << "\n"; + std::cout << "#muons in acceptance: " << nMuonsInAcceptance << "\n"; + + return 0; +} // external diff --git a/MC/config/PWGHF/ini/tests/GeneratorHF_bbbar_fwd_gap4_natural_inel_Mode2_muTrig.C b/MC/config/PWGHF/ini/tests/GeneratorHF_bbbar_fwd_gap4_natural_inel_Mode2_muTrig.C new file mode 100644 index 000000000..34072820e --- /dev/null +++ b/MC/config/PWGHF/ini/tests/GeneratorHF_bbbar_fwd_gap4_natural_inel_Mode2_muTrig.C @@ -0,0 +1,103 @@ +int External() { + + int checkPdgDecayMuon = 13; + int checkPdgQuark = 5; + + float ratioTrigger = 1. / 4; // one event triggered out of 4 + + std::string path{"o2sim_Kine.root"}; + + TFile file(path.c_str(), "READ"); + if (file.IsZombie()) { + std::cerr << "Cannot open ROOT file" << path << "\n"; + return 1; + } + + auto tree = (TTree *)file.Get("o2sim"); + if (!tree) { + std::cerr << "Cannot find tree o2sim in file" << path << "\n"; + return 1; + } + + std::vector *tracks{}; + tree->SetBranchAddress("MCTrack", &tracks); + + o2::dataformats::MCEventHeader *eventHeader = nullptr; + tree->SetBranchAddress("MCEventHeader.", &eventHeader); + + int nEventsMB{}; + int nEventsInj{}; + int nQuarks{}; + int nMuons{}; + + int nMuonsInAcceptance{}; + + auto nEvents = tree->GetEntries(); + + for (int i = 0; i < nEvents; i++) { + tree->GetEntry(i); + // check subgenerator information + if (eventHeader->hasInfo(o2::mcgenid::GeneratorProperty::SUBGENERATORID)) { + bool isValid = false; + int subGeneratorId = eventHeader->getInfo( + o2::mcgenid::GeneratorProperty::SUBGENERATORID, isValid); + if (subGeneratorId == 0) { + nEventsMB++; + } else if (subGeneratorId == checkPdgQuark) { + nEventsInj++; + } + } // if event header + + int nmuonsev = 0; + int nmuonsevinacc = 0; + + for (auto &track : *tracks) { + auto pdg = track.GetPdgCode(); + if (std::abs(pdg) == checkPdgQuark) { + nQuarks++; + continue; + } // pdgquark + auto y = track.GetRapidity(); + if (std::abs(pdg) == checkPdgDecayMuon) { + int igmother = track.getMotherTrackId(); + auto gmTrack = (*tracks)[igmother]; + int gmpdg = gmTrack.GetPdgCode(); + if (int(std::abs(gmpdg) / 100.) == 5 || + int(std::abs(gmpdg) / 1000.) == 5) { + nMuons++; + nmuonsev++; + if (-4.3 < y && y < -2.2) { + nMuonsInAcceptance++; + nmuonsevinacc++; + } + } // gmpdg + + } // pdgdecay + + } // loop track + // std::cout << "#muons per event: " << nmuonsev << "\n"; + // std::cout << "#muons in acceptance per event: " << nmuonsev << "\n"; + } // events + + std::cout << "#events: " << nEvents << "\n"; + std::cout << "# MB events: " << nEventsMB << "\n"; + std::cout << Form("# events injected with %d quark pair: ", checkPdgQuark) + << nEventsInj << "\n"; + if (nEventsMB < nEvents * (1 - ratioTrigger) * 0.95 || + nEventsMB > nEvents * (1 - ratioTrigger) * + 1.05) { // we put some tolerance since the number of + // generated events is small + std::cerr << "Number of generated MB events different than expected\n"; + return 1; + } + if (nEventsInj < nEvents * ratioTrigger * 0.95 || + nEventsInj > nEvents * ratioTrigger * 1.05) { + std::cerr << "Number of generated events injected with " << checkPdgQuark + << " different than expected\n"; + return 1; + } + std::cout << "#muons: " << nMuons << "\n"; + std::cout << "#muons in acceptance: " << nMuonsInAcceptance << "\n"; + + return 0; +} // external diff --git a/MC/config/PWGHF/ini/tests/GeneratorHF_mu_bbbar_gap3_Mode2_accSmall.C b/MC/config/PWGHF/ini/tests/GeneratorHF_mu_bbbar_gap3_Mode2_accSmall.C new file mode 100644 index 000000000..b915d734e --- /dev/null +++ b/MC/config/PWGHF/ini/tests/GeneratorHF_mu_bbbar_gap3_Mode2_accSmall.C @@ -0,0 +1,103 @@ +int External() { + + int checkPdgDecayMuon = 13; + int checkPdgQuark = 5; + + float ratioTrigger = 1./3; // one event triggered out of 5 + + std::string path{"o2sim_Kine.root"}; + + TFile file(path.c_str(), "READ"); + if (file.IsZombie()) { + std::cerr << "Cannot open ROOT file" << path << "\n"; + return 1; + } + + auto tree = (TTree *)file.Get("o2sim"); + if (!tree) { + std::cerr << "Cannot find tree o2sim in file" << path << "\n"; + return 1; + } + + std::vector *tracks{}; + tree->SetBranchAddress("MCTrack", &tracks); + + o2::dataformats::MCEventHeader *eventHeader = nullptr; + tree->SetBranchAddress("MCEventHeader.", &eventHeader); + + int nEventsMB{}; + int nEventsInj{}; + int nQuarks{}; + int nMuons{}; + + int nMuonsInAcceptance{}; + + auto nEvents = tree->GetEntries(); + + for (int i = 0; i < nEvents; i++) { + tree->GetEntry(i); + // check subgenerator information + if (eventHeader->hasInfo(o2::mcgenid::GeneratorProperty::SUBGENERATORID)) { + bool isValid = false; + int subGeneratorId = eventHeader->getInfo( + o2::mcgenid::GeneratorProperty::SUBGENERATORID, isValid); + if (subGeneratorId == 0) { + nEventsMB++; + } else if (subGeneratorId == checkPdgQuark) { + nEventsInj++; + } + } // if event header + + int nmuonsev = 0; + int nmuonsevinacc = 0; + + for (auto &track : *tracks) { + auto pdg = track.GetPdgCode(); + if (std::abs(pdg) == checkPdgQuark) { + nQuarks++; + continue; + } // pdgquark + auto y = track.GetRapidity(); + if (std::abs(pdg) == checkPdgDecayMuon) { + int igmother = track.getMotherTrackId(); + auto gmTrack = (*tracks)[igmother]; + int gmpdg = gmTrack.GetPdgCode(); + if (int(std::abs(gmpdg) / 100.) == 5 || + int(std::abs(gmpdg) / 1000.) == 5) { + nMuons++; + nmuonsev++; + if (-4.3 < y && y < -2.2) { + nMuonsInAcceptance++; + nmuonsevinacc++; + } + } // gmpdg + + } // pdgdecay + + } // loop track + // std::cout << "#muons per event: " << nmuonsev << "\n"; + // std::cout << "#muons in acceptance per event: " << nmuonsev << "\n"; + } // events + + std::cout << "#events: " << nEvents << "\n"; + std::cout << "# MB events: " << nEventsMB << "\n"; + std::cout << Form("# events injected with %d quark pair: ", checkPdgQuark) + << nEventsInj << "\n"; + if (nEventsMB < nEvents * (1 - ratioTrigger) * 0.95 || + nEventsMB > nEvents * (1 - ratioTrigger) * + 1.05) { // we put some tolerance since the number of + // generated events is small + std::cerr << "Number of generated MB events different than expected\n"; + return 1; + } + if (nEventsInj < nEvents * ratioTrigger * 0.95 || + nEventsInj > nEvents * ratioTrigger * 1.05) { + std::cerr << "Number of generated events injected with " << checkPdgQuark + << " different than expected\n"; + return 1; + } + std::cout << "#muons: " << nMuons << "\n"; + std::cout << "#muons in acceptance: " << nMuonsInAcceptance << "\n"; + + return 0; +} // external diff --git a/MC/config/PWGHF/ini/tests/GeneratorHF_mu_ccbar_gap3_Mode2_accSmall.C b/MC/config/PWGHF/ini/tests/GeneratorHF_mu_ccbar_gap3_Mode2_accSmall.C new file mode 100644 index 000000000..262973fc2 --- /dev/null +++ b/MC/config/PWGHF/ini/tests/GeneratorHF_mu_ccbar_gap3_Mode2_accSmall.C @@ -0,0 +1,103 @@ +int External() { + + int checkPdgDecayMuon = 13; + int checkPdgQuark = 4; + + float ratioTrigger = 1./3; // one event triggered out of 5 + + std::string path{"o2sim_Kine.root"}; + + TFile file(path.c_str(), "READ"); + if (file.IsZombie()) { + std::cerr << "Cannot open ROOT file" << path << "\n"; + return 1; + } + + auto tree = (TTree *)file.Get("o2sim"); + if (!tree) { + std::cerr << "Cannot find tree o2sim in file" << path << "\n"; + return 1; + } + + std::vector *tracks{}; + tree->SetBranchAddress("MCTrack", &tracks); + + o2::dataformats::MCEventHeader *eventHeader = nullptr; + tree->SetBranchAddress("MCEventHeader.", &eventHeader); + + int nEventsMB{}; + int nEventsInj{}; + int nQuarks{}; + int nMuons{}; + + int nMuonsInAcceptance{}; + + auto nEvents = tree->GetEntries(); + + for (int i = 0; i < nEvents; i++) { + tree->GetEntry(i); + // check subgenerator information + if (eventHeader->hasInfo(o2::mcgenid::GeneratorProperty::SUBGENERATORID)) { + bool isValid = false; + int subGeneratorId = eventHeader->getInfo( + o2::mcgenid::GeneratorProperty::SUBGENERATORID, isValid); + if (subGeneratorId == 0) { + nEventsMB++; + } else if (subGeneratorId == checkPdgQuark) { + nEventsInj++; + } + } // if event header + + int nmuonsev = 0; + int nmuonsevinacc = 0; + + for (auto &track : *tracks) { + auto pdg = track.GetPdgCode(); + if (std::abs(pdg) == checkPdgQuark) { + nQuarks++; + continue; + } // pdgquark + auto y = track.GetRapidity(); + if (std::abs(pdg) == checkPdgDecayMuon) { + int igmother = track.getMotherTrackId(); + auto gmTrack = (*tracks)[igmother]; + int gmpdg = gmTrack.GetPdgCode(); + if (int(std::abs(gmpdg) / 100.) == 4 || + int(std::abs(gmpdg) / 1000.) == 4) { + nMuons++; + nmuonsev++; + if (-4.3 < y && y < -2.2) { + nMuonsInAcceptance++; + nmuonsevinacc++; + } + } // gmpdg + + } // pdgdecay + + } // loop track + // std::cout << "#muons per event: " << nmuonsev << "\n"; + // std::cout << "#muons in acceptance per event: " << nmuonsev << "\n"; + } // events + + std::cout << "#events: " << nEvents << "\n"; + std::cout << "# MB events: " << nEventsMB << "\n"; + std::cout << Form("# events injected with %d quark pair: ", checkPdgQuark) + << nEventsInj << "\n"; + if (nEventsMB < nEvents * (1 - ratioTrigger) * 0.95 || + nEventsMB > nEvents * (1 - ratioTrigger) * + 1.05) { // we put some tolerance since the number of + // generated events is small + std::cerr << "Number of generated MB events different than expected\n"; + return 1; + } + if (nEventsInj < nEvents * ratioTrigger * 0.95 || + nEventsInj > nEvents * ratioTrigger * 1.05) { + std::cerr << "Number of generated events injected with " << checkPdgQuark + << " different than expected\n"; + return 1; + } + std::cout << "#muons: " << nMuons << "\n"; + std::cout << "#muons in acceptance: " << nMuonsInAcceptance << "\n"; + + return 0; +} // external diff --git a/MC/config/PWGHF/ini/tests/GeneratorHF_mu_ccbar_gap5_Mode2_accInt_muTrig.C b/MC/config/PWGHF/ini/tests/GeneratorHF_mu_ccbar_gap5_Mode2_accInt_muTrig.C index 25c5338a3..1cf192133 100644 --- a/MC/config/PWGHF/ini/tests/GeneratorHF_mu_ccbar_gap5_Mode2_accInt_muTrig.C +++ b/MC/config/PWGHF/ini/tests/GeneratorHF_mu_ccbar_gap5_Mode2_accInt_muTrig.C @@ -62,8 +62,8 @@ int External() { int igmother = track.getMotherTrackId(); auto gmTrack = (*tracks)[igmother]; int gmpdg = gmTrack.GetPdgCode(); - if (int(std::abs(gmpdg) / 100.) == 5 || - int(std::abs(gmpdg) / 1000.) == 5) { + if (int(std::abs(gmpdg) / 100.) == 4 || + int(std::abs(gmpdg) / 1000.) == 4) { nMuons++; nmuonsev++; if (-4.3 < y && y < -2.2) { diff --git a/MC/config/PWGHF/ini/tests/GeneratorHF_mu_ccbar_gap5_Mode2_accLarge.C b/MC/config/PWGHF/ini/tests/GeneratorHF_mu_ccbar_gap5_Mode2_accLarge.C index 25c5338a3..1cf192133 100644 --- a/MC/config/PWGHF/ini/tests/GeneratorHF_mu_ccbar_gap5_Mode2_accLarge.C +++ b/MC/config/PWGHF/ini/tests/GeneratorHF_mu_ccbar_gap5_Mode2_accLarge.C @@ -62,8 +62,8 @@ int External() { int igmother = track.getMotherTrackId(); auto gmTrack = (*tracks)[igmother]; int gmpdg = gmTrack.GetPdgCode(); - if (int(std::abs(gmpdg) / 100.) == 5 || - int(std::abs(gmpdg) / 1000.) == 5) { + if (int(std::abs(gmpdg) / 100.) == 4 || + int(std::abs(gmpdg) / 1000.) == 4) { nMuons++; nmuonsev++; if (-4.3 < y && y < -2.2) { diff --git a/MC/config/PWGHF/ini/tests/GeneratorHF_mu_ccbar_gap5_Mode2_accLarge_muTrig.C b/MC/config/PWGHF/ini/tests/GeneratorHF_mu_ccbar_gap5_Mode2_accLarge_muTrig.C index 25c5338a3..d53003560 100644 --- a/MC/config/PWGHF/ini/tests/GeneratorHF_mu_ccbar_gap5_Mode2_accLarge_muTrig.C +++ b/MC/config/PWGHF/ini/tests/GeneratorHF_mu_ccbar_gap5_Mode2_accLarge_muTrig.C @@ -62,8 +62,8 @@ int External() { int igmother = track.getMotherTrackId(); auto gmTrack = (*tracks)[igmother]; int gmpdg = gmTrack.GetPdgCode(); - if (int(std::abs(gmpdg) / 100.) == 5 || - int(std::abs(gmpdg) / 1000.) == 5) { + if (int(std::abs(gmpdg) / 100.) == 4|| + int(std::abs(gmpdg) / 1000.) == 4) { nMuons++; nmuonsev++; if (-4.3 < y && y < -2.2) { diff --git a/MC/config/PWGHF/ini/tests/GeneratorHF_mu_ccbar_gap5_Mode2_accSmall.C b/MC/config/PWGHF/ini/tests/GeneratorHF_mu_ccbar_gap5_Mode2_accSmall.C index 25c5338a3..1cf192133 100644 --- a/MC/config/PWGHF/ini/tests/GeneratorHF_mu_ccbar_gap5_Mode2_accSmall.C +++ b/MC/config/PWGHF/ini/tests/GeneratorHF_mu_ccbar_gap5_Mode2_accSmall.C @@ -62,8 +62,8 @@ int External() { int igmother = track.getMotherTrackId(); auto gmTrack = (*tracks)[igmother]; int gmpdg = gmTrack.GetPdgCode(); - if (int(std::abs(gmpdg) / 100.) == 5 || - int(std::abs(gmpdg) / 1000.) == 5) { + if (int(std::abs(gmpdg) / 100.) == 4 || + int(std::abs(gmpdg) / 1000.) == 4) { nMuons++; nmuonsev++; if (-4.3 < y && y < -2.2) { diff --git a/MC/config/PWGHF/ini/trigger_hf.ini b/MC/config/PWGHF/ini/trigger_hf.ini deleted file mode 100644 index 0558581fe..000000000 --- a/MC/config/PWGHF/ini/trigger_hf.ini +++ /dev/null @@ -1,13 +0,0 @@ -[GeneratorPythia8] -config=pythia8.cfg - -[TriggerExternal] -fileName=${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGHF/trigger/trigger_ccbar.C -funcName=trigger_ccbar(-1.5,1.5) - -[DecayerPythia8] -config[0] = ${O2DPG_MC_CONFIG_ROOT}/MC/config/common/pythia8/decayer/base.cfg -config[1] = ${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGHF/pythia8/decayer/force_hadronic_D.cfg -config[2] = ${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGHF/pythia8/decayer/force_hadronic_D_use4bodies.cfg - -#/alice/O2DPG/MC/config/PWGHF/external/trigger diff --git a/MC/config/PWGHF/pythia8/decayer/EVTGEN_DECAY_B2JPSI.DEC b/MC/config/PWGHF/pythia8/decayer/EVTGEN_DECAY_B2JPSI.DEC new file mode 100644 index 000000000..3ced468f5 --- /dev/null +++ b/MC/config/PWGHF/pythia8/decayer/EVTGEN_DECAY_B2JPSI.DEC @@ -0,0 +1,4554 @@ + +######################################################################## +# Copyright 1998-2020 CERN for the benefit of the EvtGen authors # +# # +# This file is part of EvtGen. # +# # +# EvtGen is free software: you can redistribute it and/or modify # +# it under the terms of the GNU General Public License as published by # +# the Free Software Foundation, either version 3 of the License, or # +# (at your option) any later version. # +# # +# EvtGen is distributed in the hope that it will be useful, # +# but WITHOUT ANY WARRANTY; without even the implied warranty of # +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # +# GNU General Public License for more details. # +# # +# You should have received a copy of the GNU General Public License # +# along with EvtGen. If not, see . # +######################################################################## + +# Updated to PDG 2010 by Tomas Pilar - T.Pilar@warwick.ac.uk +# Updated Mixing Parameters Mark Whitehead May 2009 +# +Define qoverp_incohMix_B_s0 1.0 +Define dm_incohMix_B_s0 17.8e12 +Define qoverp_incohMix_B0 1.0 +Define dm_incohMix_B0 0.507e12 +# Old definition of dm still in some decay models +Define dm 0.507e12 +#Define dgamma 0 +#Define qoverp 1 +#Define phaseqoverp 0 +#Define values for B0s mixing +#Define dms 20.e12 +# DeltaGammas corresponds to DG/G = 10% +#Define dgammas 6.852e10 +# Activate incoherent Mixing +### TODO: find a way to give mixing parameters through decay file to EvtGen +#####yesIncoherentB0Mixing dm dgamma +#####yesIncoherentBsMixing dms dgammas +# define the values of the CKM angles (alpha=70, beta=40) +Define alpha 1.365 +Define beta 0.39 +Define gamma 1.387 +Define twoBetaPlusGamma 2.167 +Define betaPlusHalfGamma 1.0835 +Define minusGamma -1.387 +Define minusTwoBeta -0.78 + +# New definitions for psiKstar modes (Lange, July 26, 2000) +Define PKHplus 0.159 +Define PKHzero 0.775 +Define PKHminus 0.612 +Define PKphHplus 1.563 +Define PKphHzero 0.0 +Define PKphHminus 2.712 + +Define Aplus 0.490 +Define Azero 1.10 +Define Aminus 0.4 +# +Define phAplus 2.5 +Define phAzero 0.0 +Define phAminus -0.17 + +# +# These particle aliases are used in for CP violating decays +# in which the decay distributions depends on how the K* decayed. +# +# +Alias K*L K*0 +Alias K*S K*0 +Alias K*BL anti-K*0 +Alias K*BS anti-K*0 +Alias K*0T K*0 +Alias anti-K*0T anti-K*0 +Alias K*BR anti-K*0 +Alias K*0R K*0 +Alias anti-K_0*0N anti-K_0*0 +Alias K_0*0N K_0*0 +# +ChargeConj K*L K*BL +ChargeConj K*S K*BS +ChargeConj K*0T anti-K*0T +ChargeConj K_0*0N anti-K_0*0N +ChargeConj K*0R K*BR +#JetSet parameter modifications +#(Very important that there are no blank spaces in the parameter string!) +#Turn of B0-B0B mixing in JetSet: +#JetSetPar MSTJ(26)=0 +# control of L=1 mesons (in order: J1S0 J0S1 J1S1 J2S1) - commented out by NB/WP +#JetSetPar PARJ(14)=0.05 +#JetSetPar PARJ(15)=0.05 +#JetSetPar PARJ(16)=0.05 +#JetSetPar PARJ(17)=0.05 +#cut-off parameter used to stop fragmentation process (should not be changed) +#####JetSetPar PARJ(33)=0.3 SET NOW IN GAUSS + +# PR LHCb 10/01/2006 +# Turn on PHOTOS for all decays +yesPhotos +# +# +#Decay vpho +#1.000 PYCONT; +#Enddecay +# +# use new VSS_BMIX mixing decay model (DK,28-Oct-1999) +Decay Upsilon(4S) +0.515122645 B+ B- VSS; #[Reconstructed PDG2011] +0.483122645 B0 anti-B0 VSS_BMIX dm; #[Reconstructed PDG2011] +0.000015583 e+ e- PHOTOS VLL; #[Reconstructed PDG2011] +0.000015766 mu+ mu- PHOTOS VLL; #[Reconstructed PDG2011] +0.000015766 tau+ tau- PHOTOS VLL; #[Reconstructed PDG2011] +0.000084099 Upsilon(2S) pi+ pi- VVPIPI; #[Reconstructed PDG2011] +0.000044342 Upsilon(2S) pi0 pi0 VVPIPI; #[Reconstructed PDG2011] +0.000080123 Upsilon pi+ pi- VVPIPI; #[Reconstructed PDG2011] +0.000044342 Upsilon pi0 pi0 VVPIPI; #[Reconstructed PDG2011] +0.000194392 Upsilon eta PARTWAVE 0.0 0.0 1.0 0.0 0.0 0.0; #[Reconstructed PDG2011] +# BF ~ (2J+1)E^3_gamma; see PRL 94, 032001 +# V-> gamma S Partial wave (L,S)=(0,0) +0.000092625 gamma chi_b0(3P) HELAMP 1. 0. 1. 0.; #[Reconstructed PDG2011] +# V-> gamma V Partial wave (L,S)=(0,1) +0.000138938 gamma chi_b1(3P) HELAMP 1. 0. 1. 0. -1. 0. -1. 0.; #[Reconstructed PDG2011] +# V-> gamma T Partial wave (L,S)=(0,1) +0.000129084 gamma chi_b2(3P) HELAMP 2.4494897 0. 1.7320508 0. 1. 0. 1. 0. 1.7320508 0. 2.4494897 0.; #[Reconstructed PDG2011] +# V-> gamma S Partial wave (L,S)=(0,0) +0.000002956 gamma chi_b0(2P) HELAMP 1. 0. 1. 0.; #[Reconstructed PDG2011] +# V-> gamma V Partial wave (L,S)=(0,1) +0.000007883 gamma chi_b1(2P) HELAMP 1. 0. 1. 0. -1. 0. -1. 0.; #[Reconstructed PDG2011] +# V-> gamma T Partial wave (L,S)=(0,1) +0.000011825 gamma chi_b2(2P) HELAMP 2.4494897 0. 1.7320508 0. 1. 0. 1. 0. 1.7320508 0. 2.4494897 0.; #[Reconstructed PDG2011] +0.000837571 g g g PYTHIA 92; +0.000039415 gamma g g PYTHIA 92; +Enddecay +# +# +# +Decay anti-B0 +# Charmonium states - updated from Lange's recommendations (august 23,2000) +# Based on new BABAR results I'm making the following changes (Lange, March 13, 2001 +# J/psi K0 was 10, now 9 x 10^-4 +# J/psi pi0 was 2.5, now 2.0 x 10^-4 +# J/psi Kstar was 15, now 13 +# Fix chic1 KS CP eigenstate +# adding J/psi rho and omega - for lack of better thing will use the Kstar helicity amplitudes. +# Psi2sKs 30 ->31 +# chic1 Kstar: 12 ->6 +0.000891000 J/psi anti-K0 SVS; #[New mode added] #[Reconstructed PDG2011] +# +# B -> J/psi anti-K*0 BR increased by a factor of 10 +0.01330000 J/psi anti-K*0 SVV_HELAMP PKHminus PKphHminus PKHzero PKphHzero PKHplus PKphHplus; #[Reconstructed PDG2011] +0.000027000 J/psi rho0 SVV_HELAMP PKHminus PKphHminus PKHzero PKphHzero PKHplus PKphHplus; #[Reconstructed PDG2011] +0.000030 J/psi omega SVV_HELAMP PKHminus PKphHminus PKHzero PKphHzero PKHplus PKphHplus; +0.000000000 J/psi K- pi+ PHSP; #[Reconstructed PDG2011] +0.00035 J/psi K- pi+ pi0 PHSP; +0.001300000 J/psi anti-K_10 SVV_HELAMP 0.5 0.0 1.0 0.0 0.5 0.0; #[Reconstructed PDG2011] +0.0001 J/psi anti-K'_10 SVV_HELAMP 0.5 0.0 1.0 0.0 0.5 0.0; +0.0005 J/psi anti-K_2*0 PHSP; +# +# below multiplied by chi_c or psi(2S) BR to J/psi +0.00036963 psi(2S) anti-K*0 SVV_HELAMP PKHminus PKphHminus PKHzero PKphHzero PKHplus PKphHplus; #[Reconstructed PDG2011] +0.00024238 psi(2S) K- pi+ PHSP; +0.00006059 psi(2S) K- pi+ pi0 PHSP; +0.00024238 psi(2S) anti-K_10 PHSP; +# +0.00007637 chi_c1 anti-K*0 SVV_HELAMP PKHminus PKphHminus PKHzero PKphHzero PKHplus PKphHplus; #[Reconstructed PDG2011] +0.00013760 chi_c1 K- pi+ PHSP; +0.00006880 chi_c1 K- pi+ pi0 PHSP; +# +0.00000585 chi_c2 anti-K*0 PHSP; +0.000039 chi_c2 K- pi+ PHSP; +0.0000195 chi_c2 K- pi+ pi0 PHSP; +# +Enddecay +# +Decay B0 +# B -> cc= s +# B -> J/psi K*0 BR increased by a factor of 10 +0.01330000 J/psi K*0 SVV_HELAMP PKHplus PKphHplus PKHzero PKphHzero PKHminus PKphHminus; #[Reconstructed PDG2011] +0.000027000 J/psi rho0 SVV_HELAMP PKHplus PKphHplus PKHzero PKphHzero PKHminus PKphHminus; #[Reconstructed PDG2011] +0.00003 J/psi omega SVV_HELAMP PKHplus PKphHplus PKHzero PKphHzero PKHminus PKphHminus; +0.000000000 J/psi K+ pi- PHSP; #[Reconstructed PDG2011] +#rl0.00035 J/psi K+ pi- pi0 PHSP; +0.001300000 J/psi K_10 SVV_HELAMP 0.5 0.0 1.0 0.0 0.5 0.0; #[Reconstructed PDG2011] +0.0001 J/psi K'_10 SVV_HELAMP 0.5 0.0 1.0 0.0 0.5 0.0; +0.0005 J/psi K_2*0 PHSP; +# +# below multiplied by chi_c or psi(2S) BR to J/psi +0.00036963 psi(2S) K*0 SVV_HELAMP PKHplus PKphHplus PKHzero PKphHzero PKHminus PKphHminus; #[Reconstructed PDG2011] +0.00024238 psi(2S) K+ pi- PHSP; +0.00006059 psi(2S) K+ pi- pi0 PHSP; +0.00024238 psi(2S) K_10 PHSP; +# +0.00007637 chi_c1 K*0 SVV_HELAMP PKHplus PKphHplus PKHzero PKphHzero PKHminus PKphHminus; #[Reconstructed PDG2011] +0.00013760 chi_c1 K+ pi- PHSP; +0.00006880 chi_c1 K+ pi- pi0 PHSP; +# +0.00000585 chi_c2 K*0 PHSP; +0.000039 chi_c2 K+ pi- PHSP; +0.0000195 chi_c2 K+ pi- pi0 PHSP; +# +Enddecay +# +# +Decay B- +# B -> cc= s sum = 1.92% +# B -> J/psi K- increased by a factor of 10 +0.01014000 J/psi K- SVS; #[Reconstructed PDG2011] +0.001430000 J/psi K*- SVV_HELAMP PKHminus PKphHminus PKHzero PKphHzero PKHplus PKphHplus; #[Reconstructed PDG2011] +0.000049000 J/psi pi- SVS; #[Reconstructed PDG2011] +0.000050000 J/psi rho- SVV_HELAMP PKHminus PKphHminus PKHzero PKphHzero PKHplus PKphHplus; #[Reconstructed PDG2011] +0.0002 J/psi anti-K0 pi- PHSP; +0.0001 J/psi K- pi0 PHSP; +#rl0.0007 J/psi K- pi+ pi- PHSP; +#rl0.00035 J/psi K- pi0 pi0 PHSP; +#rl0.00035 J/psi anti-K0 pi- pi0 PHSP; +0.0001 J/psi K'_1- SVV_HELAMP 0.5 0.0 1.0 0.0 0.5 0.0; +0.0005 J/psi K_2*- PHSP; +0.001800000 J/psi K_1- SVV_HELAMP 0.5 0.0 1.0 0.0 0.5 0.0; #[Reconstructed PDG2011] +0.000052000 J/psi phi K- PHSP; #[Reconstructed PDG2011] +# +# below multiplied by chi_c or psi(2S) BR to J/psi +0.000391411 psi(2S) K- SVS; #[Reconstructed PDG2011] +0.000375658 psi(2S) K*- SVV_HELAMP PKHminus PKphHminus PKHzero PKphHzero PKHplus PKphHplus; #[Reconstructed PDG2011] +0.000121180 psi(2S) K- pi0 PHSP; +0.001151210 psi(2S) K- pi+ pi- PHSP; #[Reconstructed PDG2011] +0.000060590 psi(2S) K- pi0 pi0 PHSP; +0.000242360 psi(2S) K_1- PHSP; +# +0.00015824 chi_c1 K- SVS; #[Reconstructed PDG2011] +0.0001032 chi_c1 K*- SVV_HELAMP PKHminus PKphHminus PKHzero PKphHzero PKHplus PKphHplus; #[Reconstructed PDG2011] +0.0000688 chi_c1 K- pi0 PHSP; +0.0001376 chi_c1 K- pi+ pi- PHSP; +0.0000688 chi_c1 K- pi0 pi0 PHSP; +# +0.0000039 chi_c2 K- STS; +0.0000039 chi_c2 K*- PHSP; +0.0000195 chi_c2 K- pi0 PHSP; +0.000039 chi_c2 K- pi+ pi- PHSP; +0.0000195 chi_c2 K- pi0 pi0 PHSP; +Enddecay + +# +Decay B+ +# B -> cc= s sum = 1.92% +# +# B -> J/psi K+ BR increased by a factor of 10 +0.01014000 J/psi K+ SVS; #[Reconstructed PDG2011] +0.001430000 J/psi K*+ SVV_HELAMP PKHplus PKphHplus PKHzero PKphHzero PKHminus PKphHminus; #[Reconstructed PDG2011] +0.000049000 J/psi pi+ SVS; #[Reconstructed PDG2011] +0.000050000 J/psi rho+ SVV_HELAMP PKHplus PKphHplus PKHzero PKphHzero PKHminus PKphHminus; #[Reconstructed PDG2011] +0.0001 J/psi K+ pi0 PHSP; +#rl0.0007 J/psi K+ pi- pi+ PHSP; +#rl0.00035 J/psi K+ pi0 pi0 PHSP; +0.0001 J/psi K'_1+ SVV_HELAMP 0.5 0.0 1.0 0.0 0.5 0.0; +0.0005 J/psi K_2*+ PHSP; +0.001800000 J/psi K_1+ SVV_HELAMP 0.5 0.0 1.0 0.0 0.5 0.0; #[Reconstructed PDG2011] +0.000052000 J/psi phi K+ PHSP; #[Reconstructed PDG2011] +# +# below multiplied by chi_c or psi(2S) BR to J/psi +0.000391411 psi(2S) K+ SVS; #[Reconstructed PDG2011] +0.000375658 psi(2S) K*+ SVV_HELAMP PKHplus PKphHplus PKHzero PKphHzero PKHminus PKphHminus; #[Reconstructed PDG2011] +0.000121180 psi(2S) K+ pi0 PHSP; +0.001151210 psi(2S) K+ pi- pi+ PHSP; #[Reconstructed PDG2011] +0.000060590 psi(2S) K+ pi0 pi0 PHSP; +0.000242360 psi(2S) K_1+ PHSP; +# +0.00015824 chi_c1 K+ SVS; #[Reconstructed PDG2011] +0.0001032 chi_c1 K*+ SVV_HELAMP PKHplus PKphHplus PKHzero PKphHzero PKHminus PKphHminus; #[Reconstructed PDG2011] +0.0000688 chi_c1 K+ pi0 PHSP; +0.0001376 chi_c1 K+ pi- pi+ PHSP; +0.0000688 chi_c1 K+ pi0 pi0 PHSP; +# +0.0000039 chi_c2 K+ STS; +0.0000039 chi_c2 K*+ PHSP; +0.0000195 chi_c2 K+ pi0 PHSP; +0.000039 chi_c2 K+ pi- pi+ PHSP; +0.0000195 chi_c2 K+ pi0 pi0 PHSP; +Enddecay + +#----------------------------------------------------------------- +# B references: +# +# [B1]: http://www.slac.stanford.edu/BFROOT/www/Physics/Tools/generators/dec-update/2002/Breco-recommendations.html +# +#----------------------------------------------------------------- + + +# +# +# B* mesons +# +Decay B*+ +1.0000 B+ gamma VSP_PWAVE; +Enddecay +Decay B*- +1.0000 B- gamma VSP_PWAVE; +Enddecay +Decay B*0 +1.0000 B0 gamma VSP_PWAVE; +Enddecay +Decay anti-B*0 +1.0000 anti-B0 gamma VSP_PWAVE; +Enddecay +Decay B_s*0 +1.0000 B_s0 gamma VSP_PWAVE; +Enddecay +Decay anti-B_s*0 +1.0000 anti-B_s0 gamma VSP_PWAVE; +Enddecay +# +# B_s decays. +# +# +# To count up the BR for this decay: +# awk ' /^0./{ sum = sum + $1 ;print sum } ' junk.dec +# +# anti-B_s decays. +# ------------------------------------------------------- +# whb&fkw 3/28/01 Taken from fkw's QQ tables. +# most dubious part are the B to baryons. +# fkw 4/28/00 made the Bs parallel to the Bd as best as I could +# ------------------------------------------------------- +# +# Lange - Nov14 - NOT adjusted for D_s->phipi change +# +Decay anti-B_s0 +# +# fkw 4/28/00 Strategy for charmonium modes: +# Take Bd BR's, replace spectator, +# assume etaprime = 2/3 ss +# and eta = 1/3 ss +# +# Note: Just for kicks I gave the c\bar c decays a small piece that is +# self tagging. See if you can find it. This is already in +# the B0 decays in cleo's version of decay.dec . +# +# B --> (c c=) (s s=) +# 2.65% +# should be: psi = 0.80% CLNS 94/1315 but isn't quite right. +# B_s0 -> J/psi phi increased by a factor fo 10 and includes phi->KK +0.00064 J/psi eta' SVS; +0.00032 J/psi eta SVS; +0.006305 J/psi phi SVV_HELAMP 1.0 0.0 1.0 0.0 1.0 0.0; #[Reconstructed PDG2011] +0.00070 J/psi K- K+ PHSP; +0.00070 J/psi anti-K0 K+ pi- PHSP; +0.00070 J/psi K- K+ pi0 PHSP; +0.000035 J/psi anti-K*0 PHSP; +0.000107 J/psi K*0 anti-K*0 PHSP; +# LHCb PR 04/02/04 Add (cc) phi n pi(+/0) +0.00039 J/psi phi pi+ pi- PHSP; +0.00039 J/psi phi pi0 pi0 PHSP; +# LHCb PR add (cc) phi eta(') + npi see CDF QQ +0.0002 J/psi eta pi+ pi- PHSP; +0.0004 J/psi eta' pi+ pi- PHSP; +0.0002 J/psi pi+ pi- PHSP; +# psi' = 0.34% CLNS 94/1315 +# +0.000281767 psi(2S) eta' SVS; +0.000142398 psi(2S) eta SVS; +0.000201697 psi(2S) phi SVV_HELAMP 1.0 0.0 1.0 0.0 1.0 0.0; #[Reconstructed PDG2011] +0.000181785 psi(2S) K- K+ PHSP; +0.000181785 psi(2S) anti-K0 K+ pi- PHSP; +0.000181785 psi(2S) K- K+ pi0 PHSP; +0.000206023 psi(2S) phi pi+ pi- PHSP; +0.000206023 psi(2S) phi pi0 pi0 PHSP; +0.000121190 psi(2S) eta pi+ pi- PHSP; +0.000242381 psi(2S) eta' pi+ pi- PHSP; +0.000121190 psi(2S) pi+ pi- PHSP; +# +# chi_c1 = 0.37% CLNS 94/1315 +0.0002408 chi_c1 eta' SVS; +0.0001032 chi_c1 eta SVS; +0.0004816 chi_c1 phi SVV_HELAMP 1.0 0.0 1.0 0.0 1.0 0.0; +0.00008944 chi_c1 K- K+ PHSP; +0.00008944 chi_c1 anti-K0 K+ pi- PHSP; +0.00008944 chi_c1 K- K+ pi0 PHSP; +0.0001376 chi_c1 phi pi+ pi- PHSP; +0.0000344 chi_c1 eta pi+ pi- PHSP; +0.0000688 chi_c1 eta' pi+ pi- PHSP; +# +# +# chic2 = 0.25% CLNS 94/1315 +0.00009067 chi_c2 eta' STS; +0.00004583 chi_c2 eta STS; +#0.000195 chi_c2 phi STV; whb: model doesn't exist! +0.0000312 chi_c2 K- K+ PHSP; +0.0000312 chi_c2 anti-K0 K+ pi- PHSP; +0.0000312 chi_c2 K- K+ pi0 PHSP; +# +Enddecay +# +# B_s decays. +# ------------------------------------------------------- +# whb&fkw 3/28/01 Taken from fkw's QQ tables. +# most dubious part are the B to baryons. +# fkw 4/28/00 made the Bs parallel to the Bd as best as I could +# ------------------------------------------------------- +Decay B_s0 +# fkw 4/28/00 Strategy for charmonium modes: +# Take Bd BR's, replace spectator, +# assume etaprime = 2/3 ss +# and eta = 1/3 ss +# +# Note: Just for kicks I gave the c\bar c decays a small piece that is +# self tagging. See if you can find it. This is already in +# the B0 decays in cleo's version of decay.dec . +# +# B --> (c c=) (s s=) +# 2.65% +# should be: psi = 0.80% CLNS 94/1315 but isn't quite right. +# B_s0 -> J/psi phi increased by a factor of 10 and including phi->KK +0.00064 J/psi eta' SVS; +0.00032 J/psi eta SVS; +0.006305 J/psi phi SVV_HELAMP 1.0 0.0 1.0 0.0 1.0 0.0; #[Reconstructed PDG2011] +0.00070 J/psi K- K+ PHSP; +0.00070 J/psi K0 K- pi+ PHSP; +0.00070 J/psi K- K+ pi0 PHSP; +0.000035 J/psi K*0 PHSP; +0.000107 J/psi K*0 anti-K*0 PHSP; +# LHCb PR 04/02/04 Add (cc) phi n pi(+/0) +0.00039 J/psi phi pi+ pi- PHSP; +0.00039 J/psi phi pi0 pi0 PHSP; +# LHCb PR Add (cc) phi eta(') + npi like in CDF QQ +0.0002 J/psi eta pi+ pi- PHSP; +0.0002 J/psi eta pi0 pi0 PHSP; +0.0004 J/psi eta' pi+ pi- PHSP; +0.0004 J/psi eta' pi0 pi0 PHSP; +0.0002 J/psi pi+ pi- PHSP; +# psi' = 0.34% CLNS 94/1315 +# below multiplied by chi_c or psi(2S) BR to J/psi and phi BR to KK +0.000281767 psi(2S) eta' SVS; +0.000142398 psi(2S) eta SVS; +0.000201697 psi(2S) phi SVV_HELAMP 1.0 0.0 1.0 0.0 1.0 0.0; #[Reconstructed PDG2011] +0.000181785 psi(2S) K- K+ PHSP; +0.000181785 psi(2S) K0 K- pi+ PHSP; +0.000181785 psi(2S) K- K+ pi0 PHSP; +0.000206023 psi(2S) phi pi+ pi- PHSP; +0.000206023 psi(2S) phi pi0 pi0 PHSP; +0.000121190 psi(2S) eta pi+ pi- PHSP; +0.000242381 psi(2S) eta' pi+ pi- PHSP; +0.000121190 psi(2S) pi+ pi- PHSP; +# +# chic1 = 0.37% CLNS 94/1315 +0.0002408 chi_c1 eta' SVS; +0.0001032 chi_c1 eta SVS; +0.0004816 chi_c1 phi SVV_HELAMP 1.0 0.0 1.0 0.0 1.0 0.0; +0.00008944 chi_c1 K- K+ PHSP; +0.00008944 chi_c1 anti-K0 K+ pi- PHSP; +0.00008944 chi_c1 K- K+ pi0 PHSP; +0.0001376 chi_c1 phi pi+ pi- PHSP; +0.0000344 chi_c1 eta pi+ pi- PHSP; +0.0000688 chi_c1 eta' pi+ pi- PHSP; +# +# chic2 = 0.25% CLNS 94/1315 +0.00009067 chi_c2 eta' STS; +0.00004583 chi_c2 eta STS; +#0.000195 chi_c2 phi STV; whb: doesn't exist +0.0000312 chi_c2 K- K+ PHSP; +0.0000312 chi_c2 K0 K- pi+ PHSP; +0.0000312 chi_c2 K- K+ pi0 PHSP; +# +Enddecay + +# whb: QQ B_c included- Near end of File +#Decay B_c- +#CHANNEL 0 0.0700 TAU- NUTB +#CHANNEL 1 0.1100 NUEB E- *CC* +#CHANNEL 1 0.1100 NUMB MU- *CC* +#CHANNEL 1 0.0300 NUTB TAU- *CC* +#CHANNEL 0 0.3400 *DU* *CC* +#CHANNEL 0 0.0700 *SC* *CC* +#CHANNEL 0 0.2700 *SC* +#0.0700 tau- anti-nu_tau PHSP; +#0.1100 anti-nu_e e- *CC* Simpleleptonic; +#0.1100 anti-nu_mu mu- *CC* Simple leptonic; +#0.0300 anti-nu_tau tau- *CC* Simple leptonic; +#0.3400 *DU* *CC* PHSP; +#0.0700 *SC* *CC* PHSP; +#0.2700 *SC* PHSP; +#Enddecay +# +#Decay B_c+ +#CHANNEL 0 0.0700 TAU+ NUT +#CHANNEL 1 0.1100 NUE E+ *CC* +#CHANNEL 1 0.1100 NUM MU+ *CC* +#CHANNEL 1 0.0300 NUT TAU+ *CC* +#CHANNEL 0 0.3400 *UD* *CC* +#CHANNEL 0 0.0700 *CS* *CC* +#CHANNEL 0 0.2700 *CS* +#0.0700 tau+ nu_tau PHSP; +#0.1100 nu_e E+ *CC* Simple leptonic; +#0.1100 nu_mu mu+ *CC* Simple leptonic; +#0.0300 nu_tau tau+ *CC* Simple leptonic; +#0.3400 *UD* *CC* PHSP; +#0.0700 *CS* *CC* PHSP; +#0.2700 *CS* PHSP; +#Enddecay + +# +# Updated to PDG 2008 +# +Decay tau- +0.154002925 e- anti-nu_e nu_tau PHOTOS TAULNUNU; #[Reconstructed PDG2011] +0.170000000 mu- anti-nu_mu nu_tau PHOTOS TAULNUNU; #[Reconstructed PDG2011] +0.109100000 pi- nu_tau TAUSCALARNU; #[Reconstructed PDG2011] +0.006960000 K- nu_tau TAUSCALARNU; #[Reconstructed PDG2011] +0.255100000 pi- pi0 nu_tau TAUHADNU -0.108 0.775 0.149 1.364 0.400; #[Reconstructed PDG2011] +0.001124109 nu_tau gamma pi- pi0 PYTHIA 21; +0.079301562 pi0 pi0 pi- nu_tau TAUHADNU -0.108 0.775 0.149 1.364 0.400 1.23 0.4; #[Reconstructed PDG2011] +0.000385656 nu_tau K- pi0 pi0 PYTHIA 21; +0.008508640 nu_tau pi- pi0 pi0 pi0 PYTHIA 21; +0.000864699 nu_tau pi- pi0 pi0 pi0 pi0 PHSP; #[Reconstructed PDG2011] +#0.2515 rho- nu_tau TAUVECTORNU; +#0.1790 a_1- nu_tau TAUVECTORNU; +# Modes with K0s +# +0.000319939 nu_tau pi- anti-K0 PYTHIA 21; +0.001590000 nu_tau K- K0 PYTHIA 21; +0.001700000 nu_tau K0 pi- anti-K0 PYTHIA 21; +0.001590000 nu_tau K- pi0 K0 PYTHIA 21; +0.004000000 nu_tau pi- anti-K0 pi0 PYTHIA 21; +# 3 Charged Particles +# +0.093200000 pi- pi- pi+ nu_tau TAUHADNU -0.108 0.775 0.149 1.364 0.400 1.23 0.4; #[Reconstructed PDG2011] +0.046100000 nu_tau pi- pi+ pi- pi0 PYTHIA 21; +0.000501526 nu_tau pi- pi- pi+ pi0 pi0 PHSP; #[Reconstructed PDG2011] +0.000155646 nu_tau pi- pi- pi+ pi0 pi0 pi0 PHSP; #[Reconstructed PDG2011] +0.003420000 nu_tau K- pi+ pi- PYTHIA 21; +0.001360000 nu_tau K- pi+ pi- pi0 PYTHIA 21; +0.001400000 nu_tau K- pi- K+ PYTHIA 21; +0.000015800 nu_tau K- K+ K- PYTHIA 21; +# 5 Charged Particles +# +0.000700406 nu_tau pi- pi- pi- pi+ pi+ PHSP; #[Reconstructed PDG2011] +0.000129705 nu_tau pi- pi- pi- pi+ pi+ pi0 PHSP; #[Reconstructed PDG2011] +# Misc other modes +# +0.012000000 K*- nu_tau TAUVECTORNU; #[Reconstructed PDG2011] +0.001390000 nu_tau eta pi- pi0 PYTHIA 21; +0.003199387 nu_tau pi- omega pi0 PYTHIA 21; +0.000410000 nu_tau K- omega PYTHIA 21; +0.002200000 anti-K*0 pi- nu_tau PHSP; #[Reconstructed PDG2011] +0.002100000 K*0 K- nu_tau PHSP; #[Reconstructed PDG2011] +0.000034000 phi pi- nu_tau PHSP; #[Reconstructed PDG2011] +0.000037000 phi K- nu_tau PHSP; #[Reconstructed PDG2011] +0.003600000 mu- anti-nu_mu nu_tau gamma PHSP; #[New mode added] #[Reconstructed PDG2011] +0.017500000 e- anti-nu_e nu_tau gamma PHSP; #[New mode added] #[Reconstructed PDG2011] +0.004290000 K- pi0 nu_tau PHSP; #[New mode added] #[Reconstructed PDG2011] +0.002200000 anti-K0 rho- nu_tau PHSP; #[New mode added] #[Reconstructed PDG2011] +0.000260000 pi- anti-K0 pi0 pi0 nu_tau PHSP; #[New mode added] #[Reconstructed PDG2011] +0.000310000 pi- K0 anti-K0 pi0 nu_tau PHSP; #[New mode added] #[Reconstructed PDG2011] +0.000061000 K- K+ pi- pi0 nu_tau PHSP; #[New mode added] #[Reconstructed PDG2011] +0.000028000 e- e- e+ anti-nu_e nu_tau PHSP; #[New mode added] #[Reconstructed PDG2011] +0.004700000 K_1- nu_tau PHSP; #[New mode added] #[Reconstructed PDG2011] +0.001700000 K'_1- nu_tau PHSP; #[New mode added] #[Reconstructed PDG2011] +0.001500000 K'*- nu_tau PHSP; #[New mode added] #[Reconstructed PDG2011] +0.000150000 eta pi- pi0 pi0 nu_tau PHSP; #[New mode added] #[Reconstructed PDG2011] +0.000161000 eta K- nu_tau PHSP; #[New mode added] #[Reconstructed PDG2011] +0.000138000 eta K*- nu_tau PHSP; #[New mode added] #[Reconstructed PDG2011] +0.000048000 eta K- pi0 nu_tau PHSP; #[New mode added] #[Reconstructed PDG2011] +0.000093000 eta anti-K0 pi- nu_tau PHSP; #[New mode added] #[Reconstructed PDG2011] +0.000360000 f_1 pi- nu_tau PHSP; #[New mode added] #[Reconstructed PDG2011] +Enddecay +# +CDecay tau+ +# +# Vector Mesons Updated PDG 2008 +# +Decay D*+ +0.6770 D0 pi+ VSS; +0.3070 D+ pi0 VSS; +0.0160 D+ gamma VSP_PWAVE; +Enddecay +Decay D*- +0.6770 anti-D0 pi- VSS; +0.3070 D- pi0 VSS; +0.0160 D- gamma VSP_PWAVE; +Enddecay +Decay D*0 +0.619000000 D0 pi0 VSS; #[Reconstructed PDG2011] +0.381000000 D0 gamma VSP_PWAVE; #[Reconstructed PDG2011] +Enddecay +Decay anti-D*0 +0.6190 anti-D0 pi0 VSS; +0.3810 anti-D0 gamma VSP_PWAVE; +Enddecay +# +Decay D_s*+ +0.942000000 D_s+ gamma VSP_PWAVE; #[Reconstructed PDG2011] +0.058000000 D_s+ pi0 VSS; #[Reconstructed PDG2011] +Enddecay +Decay D_s*- +0.942000000 D_s- gamma VSP_PWAVE; #[Reconstructed PDG2011] +0.058000000 D_s- pi0 VSS; #[Reconstructed PDG2011] +Enddecay +# +# +# D+ Meson +# +Decay D+ +0.055200000 anti-K*0 e+ nu_e PHOTOS ISGW2; # PDG2014 +0.088300000 anti-K0 e+ nu_e PHOTOS ISGW2; # PDG2014 +0.002773020 anti-K_10 e+ nu_e PHOTOS ISGW2; # Keep same as in 2010 version +0.002927076 anti-K_2*0 e+ nu_e PHOTOS ISGW2; # Keep same as in 2010 version +0.004050000 pi0 e+ nu_e PHOTOS ISGW2; # PDG2014 +0.001140000 eta e+ nu_e PHOTOS ISGW2; # PDG2014 +0.000220000 eta' e+ nu_e PHOTOS ISGW2; # PDG2014 +0.002180000 rho0 e+ nu_e PHOTOS ISGW2; # PDG2014 +0.001820000 omega e+ nu_e PHOTOS ISGW2; # PDG2014 +0.003321725 K- pi+ e+ nu_e PHOTOS PHSP; # PDG2014 (subtracted K*)+tiny bit to have sum=1 +0.001200122 anti-K0 pi0 e+ nu_e PHOTOS PHSP; # Keep same as in 2010 version+tiny bit to have sum=1 +# +0.052800000 anti-K*0 mu+ nu_mu PHOTOS ISGW2; # PDG2014 +0.092000000 anti-K0 mu+ nu_mu PHOTOS ISGW2; # PDG2014 +0.002773020 anti-K_10 mu+ nu_mu PHOTOS ISGW2; # Keep same as in 2010 version +0.002927076 anti-K_2*0 mu+ nu_mu PHOTOS ISGW2; # Keep same as in 2010 version +0.004050000 pi0 mu+ nu_mu PHOTOS ISGW2; # Same as electron +0.001140000 eta mu+ nu_mu PHOTOS ISGW2; # Same as electron +0.002200000 eta' mu+ nu_mu PHOTOS ISGW2; # Same as electron +0.002400000 rho0 mu+ nu_mu PHOTOS ISGW2; # PDG2014 +0.001820000 omega mu+ nu_mu PHOTOS ISGW2; # Same as electron +0.002921725 K- pi+ mu+ nu_mu PHOTOS PHSP; # PDG2014 (subtracted K*)+tiny bit to have sum=1 +0.001200122 anti-K0 pi0 mu+ nu_mu PHOTOS PHSP; # Keep same as in 2010 version+tiny bit to have sum=1 +# +# +0.000382000 mu+ nu_mu PHOTOS SLN; #[Reconstructed PDG2011] +0.000770283 tau+ nu_tau SLN; #[Reconstructed PDG2011] +# +0.014900000 K_S0 pi+ PHSP; #[Reconstructed PDG2011] +0.014600000 K_L0 pi+ PHSP; #[Reconstructed PDG2011] +0.000000000 anti-K0 pi+ PHSP; #[Reconstructed PDG2011] +# +0.025950843 a_1+ K_S0 SVS; #[Reconstructed PDG2011] +0.025950843 a_1+ K_L0 SVS; #[Reconstructed PDG2011] +0.000000000 a_1+ anti-K0 SVS; #[Reconstructed PDG2011] +# +0.027090862 anti-K'_10 pi+ SVS; #[Reconstructed PDG2011] +#0.0115 anti-K_0*0N pi+ PHSP; +0.013387523 anti-K*0 rho+ SVV_HELAMP 1.0 0.0 1.0 0.0 1.0 0.0; #[Reconstructed PDG2011] +# +# the Dalitz mode below includes K*bar(892)0 pi+, +# K*bar(1430)0 pi+, and K*bar(1680)0 pi+ resonances. +0.094000000 K- pi+ pi+ D_DALITZ; #[Reconstructed PDG2011] +# the Dalitz mode below includes K0bar rho+, +# and K*bar(892)0 pi+ resonances +0.069900000 K_S0 pi+ pi0 D_DALITZ; # PDG2014 +0.069900000 K_L0 pi+ pi0 D_DALITZ; # Assume to be same as K_S0 pi+ pi0 +0.000000000 anti-K0 pi+ pi0 D_DALITZ; #[Reconstructed PDG2011] +#0.0100 anti-K0 eta pi+ PHSP; +# +0.001247859 K_S0 rho0 pi+ PHSP; #[Reconstructed PDG2011] +0.001247859 K_L0 rho0 pi+ PHSP; #[Reconstructed PDG2011] +0.000000000 anti-K0 rho0 pi+ PHSP; #[Reconstructed PDG2011] +# +0.003851416 anti-K0 omega pi+ PHSP; #[Reconstructed PDG2011] +0.007032686 K- rho+ pi+ PHSP; #[Reconstructed PDG2011] +0.009274210 K*- pi+ pi+ PHSP; #[Reconstructed PDG2011] +0.047187552 anti-K*0 pi0 pi+ PHSP; #[Reconstructed PDG2011] +#0.0100 anti-K*0 eta pi+ PHSP; +0.001101505 anti-K*0 rho0 pi+ PHSP; #[Reconstructed PDG2011] +0.003851416 anti-K*0 omega pi+ PHSP; #[Reconstructed PDG2011] +#0.0100 K*- rho+ pi+ PHSP; +# +0.008473116 K- pi+ pi+ pi0 PHSP; #[Reconstructed PDG2011] +# +#0.002472609 K_S0 pi+ pi+ pi- PHSP; #[Reconstructed PDG2011] +#0.002472609 K_L0 pi+ pi+ pi- PHSP; #[Reconstructed PDG2011] +0.031200000 K_S0 pi+ pi+ pi- PHSP; # PDG2014 (why it was much smaller?) +0.031200000 K_L0 pi+ pi+ pi- PHSP; # PDG2014 +0.000000000 anti-K0 pi+ pi+ pi- PHSP; #[Reconstructed PDG2011] +# +#0.0188 anti-K0 pi+ pi0 pi0 PHSP; +0.005700000 K- pi+ pi+ pi+ pi- PHSP; #[Reconstructed PDG2011] +0.003851416 K- pi+ pi+ pi0 pi0 PHSP; #[Reconstructed PDG2011] +0.006701464 anti-K0 pi+ pi+ pi- pi0 PHSP; #[Reconstructed PDG2011] +0.002695991 anti-K0 pi+ pi0 pi0 pi0 PHSP; #[Reconstructed PDG2011] +# +0.004600000 K_S0 K_S0 K+ PHSP; #[Reconstructed PDG2011] +0.003111944 K_L0 K_L0 K+ PHSP; #[Reconstructed PDG2011] +0.000000000 anti-K0 anti-K0 K+ PHSP; #[Reconstructed PDG2011] +# +0.004660214 phi pi+ SVS; #[Reconstructed PDG2011] +0.023000000 phi pi+ pi0 PHSP; #[Reconstructed PDG2011] +# +0.002860000 K_S0 K+ PHSP; #[Reconstructed PDG2011] +0.002195307 K_L0 K+ PHSP; #[Reconstructed PDG2011] +0.000000000 anti-K0 K+ PHSP; #[Reconstructed PDG2011] +# +0.002179902 anti-K*0 K+ SVS; #[Reconstructed PDG2011] +# +0.016000000 K*+ K_S0 SVS; #[Reconstructed PDG2011] +0.011145999 K*+ K_L0 SVS; #[Reconstructed PDG2011] +0.000000000 K*+ anti-K0 SVS; #[Reconstructed PDG2011] +# +#0.0180 anti-K*0 K*+ SVV_HELAMP 1.0 0.0 1.0 0.0 1.0 0.0; +0.002826940 K+ K- pi+ PHSP; #[Reconstructed PDG2011] +0.000770283 K+ anti-K0 pi0 PHSP; #[Reconstructed PDG2011] +0.000000000 anti-K0 K0 pi+ PHSP; #[Reconstructed PDG2011] +0.000770283 K*+ K- pi+ PHSP; #[Reconstructed PDG2011] +0.000770283 K+ K*- pi+ PHSP; #[Reconstructed PDG2011] +0.000770283 K*+ anti-K0 pi0 PHSP; #[Reconstructed PDG2011] +0.000770283 K+ anti-K*0 pi0 PHSP; #[Reconstructed PDG2011] +0.000770283 anti-K*0 K0 pi+ PHSP; #[Reconstructed PDG2011] +0.000770283 anti-K0 K*0 pi+ PHSP; #[Reconstructed PDG2011] +# +0.001260000 pi0 pi+ PHSP; #[Reconstructed PDG2011] +0.000830000 rho0 pi+ SVS; #[Reconstructed PDG2011] +0.002440000 pi+ pi+ pi- PHSP; #[Reconstructed PDG2011] +0.004700000 pi+ pi0 pi0 PHSP; #[Reconstructed PDG2011] +0.011600000 pi+ pi+ pi- pi0 PHSP; #[Reconstructed PDG2011] +0.003851416 pi+ pi0 pi0 pi0 PHSP; #[Reconstructed PDG2011] +0.003430000 eta pi+ PHSP; #[Reconstructed PDG2011] +0.004400000 eta' pi+ PHSP; #[Reconstructed PDG2011] +0.001380000 eta pi+ pi0 PHSP; #[Reconstructed PDG2011] +0.002310850 eta pi+ pi+ pi- PHSP; #[Reconstructed PDG2011] +0.001540566 eta pi+ pi0 pi0 PHSP; #[Reconstructed PDG2011] +#lange jul22,2002 +0.001660000 pi+ pi+ pi+ pi- pi- PHSP; #[Reconstructed PDG2011] +# +# March 2009 New Modes +0.009300000 anti-K*0 a_1+ PHSP; #[Reconstructed PDG2011] +0.010545178 K+ K- pi+ pi0 PHSP; #[Reconstructed PDG2011] +# +0.001740000 K+ K_S0 pi+ pi- PHSP; #[Reconstructed PDG2011] +0.001270967 K+ K_L0 pi+ pi- PHSP; #[Reconstructed PDG2011] +0.000000000 K+ anti-K0 pi+ pi- PHSP; #[Reconstructed PDG2011] +# +0.002380000 K_S0 K- pi+ pi+ PHSP; #[Reconstructed PDG2011] +0.001756246 K_L0 K- pi+ pi+ PHSP; #[Reconstructed PDG2011] +0.000000000 K0 K- pi+ pi+ PHSP; #[Reconstructed PDG2011] +# +0.000230000 K+ K- pi+ pi+ pi- PHSP; #[Reconstructed PDG2011] +# +0.000240000 K+ K- K_S0 pi+ PHSP; #[Reconstructed PDG2011] +0.000161759 K+ K- K_L0 pi+ PHSP; #[Reconstructed PDG2011] +0.000000000 K+ K- anti-K0 pi+ PHSP; #[Reconstructed PDG2011] +# Doubly Cabibbo suppressed modes +0.000237000 K+ pi0 PHSP; #[Reconstructed PDG2011] +0.000332000 K+ pi+ pi- PHSP; #[Reconstructed PDG2011] +0.000089000 K+ K+ K- PHSP; #[Reconstructed PDG2011] +0.001720000 K- rho0 pi+ pi+ PHSP; #[New mode added] #[Reconstructed PDG2011] +0.001600000 eta' pi+ pi0 PHSP; #[New mode added] #[Reconstructed PDG2011] +0.000210000 K+ rho0 PHSP; #[New mode added] #[Reconstructed PDG2011] +Enddecay +# +# +Decay D- +0.055200000 K*0 e- anti-nu_e PHOTOS ISGW2; # PDG2014 +0.088300000 K0 e- anti-nu_e PHOTOS ISGW2; # PDG2014 +0.002773020 K_10 e- anti-nu_e PHOTOS ISGW2; # Keep same as in 2010 version +0.002927076 K_2*0 e- anti-nu_e PHOTOS ISGW2; # Keep same as in 2010 version +0.004050000 pi0 e- anti-nu_e PHOTOS ISGW2; # PDG2014 +0.001140000 eta e- anti-nu_e PHOTOS ISGW2; # PDG2014 +0.000220000 eta' e- anti-nu_e PHOTOS ISGW2; # PDG2014 +0.002180000 rho0 e- anti-nu_e PHOTOS ISGW2; # PDG2014 +0.001820000 omega e- anti-nu_e PHOTOS ISGW2; # PDG2014 +0.003321725 K+ pi- e- anti-nu_e PHOTOS PHSP; # PDG2014 (subtracted K*)+tiny bit to have sum=1 +0.001200122 K0 pi0 e- anti-nu_e PHOTOS PHSP; # Keep same as in 2010 version+tiny bit to have sum=1 +# +0.052800000 K*0 mu- anti-nu_mu PHOTOS ISGW2; #[Reconstructed PDG2011] +0.092000000 K0 mu- anti-nu_mu PHOTOS ISGW2; #[Reconstructed PDG2011] +0.002773020 K_10 mu- anti-nu_mu PHOTOS ISGW2; #[Reconstructed PDG2011] +0.002927076 K_2*0 mu- anti-nu_mu PHOTOS ISGW2; #[Reconstructed PDG2011] +0.004050000 pi0 mu- anti-nu_mu PHOTOS ISGW2; #[Reconstructed PDG2011] +0.001140000 eta mu- anti-nu_mu PHOTOS ISGW2; #[Reconstructed PDG2011] +0.002200000 eta' mu- anti-nu_mu PHOTOS ISGW2; #[Reconstructed PDG2011] +0.002400000 rho0 mu- anti-nu_mu PHOTOS ISGW2; #[Reconstructed PDG2011] +0.001820000 omega mu- anti-nu_mu PHOTOS ISGW2; #[Reconstructed PDG2011] +0.002921725 K+ pi- mu- anti-nu_mu PHOTOS PHSP; #[Reconstructed PDG2011] +0.001200122 K0 pi0 mu- anti-nu_mu PHOTOS PHSP; #[Reconstructed PDG2011] +# +0.000382000 mu- anti-nu_mu PHOTOS SLN; #[Reconstructed PDG2011] +0.000770283 tau- anti-nu_tau SLN; #[Reconstructed PDG2011] +# +0.014900000 K_S0 pi- PHSP; #[Reconstructed PDG2011] +0.014600000 K_L0 pi- PHSP; #[Reconstructed PDG2011] +0.000000000 K0 pi- PHSP; #[Reconstructed PDG2011] +# +0.025950843 a_1- K_S0 SVS; #[Reconstructed PDG2011] +0.025950843 a_1- K_L0 SVS; #[Reconstructed PDG2011] +0.000000000 a_1- K0 SVS; #[Reconstructed PDG2011] +# +0.027090862 K'_10 pi- SVS; #[Reconstructed PDG2011] +#0.0115 K_0*0N pi- PHSP; +0.013387523 K*0 rho- SVV_HELAMP 1.0 0.0 1.0 0.0 1.0 0.0; #[Reconstructed PDG2011] +# +# the Dalitz mode below includes K*(892)0 pi-, K*(1430)0 pi-, and K*(1680)0 pi- resonances. +0.094000000 K+ pi- pi- D_DALITZ; #[Reconstructed PDG2011] +# the Dalitz mode below includes K0 rho-, and K*(892)0 pi- resonances. +0.069900000 K_S0 pi- pi0 D_DALITZ; # PDG2014 +0.069900000 K_L0 pi- pi0 D_DALITZ; # Assume to be same as K_S0 pi- pi0 +0.000000000 K0 pi- pi0 D_DALITZ; #[Reconstructed PDG2011] +# +#0.0100 K0 eta pi- PHSP; +0.001247859 K_S0 rho0 pi- PHSP; #[Reconstructed PDG2011] +0.001247859 K_L0 rho0 pi- PHSP; #[Reconstructed PDG2011] +0.000000000 K0 rho0 pi- PHSP; #[Reconstructed PDG2011] +# +0.003851416 K0 omega pi- PHSP; #[Reconstructed PDG2011] +0.007032686 K+ rho- pi- PHSP; #[Reconstructed PDG2011] +0.009274210 K*+ pi- pi- PHSP; #[Reconstructed PDG2011] +0.047187552 K*0 pi0 pi- PHSP; #[Reconstructed PDG2011] +#0.0100 K*0 eta pi- PHSP; +0.001101505 K*0 rho0 pi- PHSP; #[Reconstructed PDG2011] +0.003851416 K*0 omega pi- PHSP; #[Reconstructed PDG2011] +#0.0100 K*+ rho- pi- PHSP; +# +0.008473116 K+ pi- pi- pi0 PHSP; #[Reconstructed PDG2011] +# +0.031200000 K_S0 pi- pi- pi+ PHSP; # PDG2014 (why it was much smaller?) +0.031200000 K_L0 pi- pi- pi+ PHSP; # PDG2014 +0.000000000 K0 pi- pi- pi+ PHSP; #[Reconstructed PDG2011] +# +#0.0188 K0 pi- pi0 pi0 PHSP; +0.005700000 K+ pi- pi- pi- pi+ PHSP; #[Reconstructed PDG2011] +0.003851416 K+ pi- pi- pi0 pi0 PHSP; #[Reconstructed PDG2011] +0.006701464 K0 pi- pi- pi+ pi0 PHSP; #[Reconstructed PDG2011] +0.002695991 K0 pi- pi0 pi0 pi0 PHSP; #[Reconstructed PDG2011] +# +0.004600000 K_S0 K_S0 K- PHSP; #[Reconstructed PDG2011] +0.003111944 K_L0 K_L0 K- PHSP; #[Reconstructed PDG2011] +0.000000000 K0 K0 K- PHSP; #[Reconstructed PDG2011] +# +0.004660214 phi pi- SVS; #[Reconstructed PDG2011] +0.023000000 phi pi- pi0 PHSP; #[Reconstructed PDG2011] +# +0.002860000 K_S0 K- PHSP; #[Reconstructed PDG2011] +0.002195307 K_L0 K- PHSP; #[Reconstructed PDG2011] +0.000000000 K0 K- PHSP; #[Reconstructed PDG2011] +# +0.002179902 K*0 K- SVS; #[Reconstructed PDG2011] +# +0.016000000 K*- K_S0 SVS; #[Reconstructed PDG2011] +0.011145999 K*- K_L0 SVS; #[Reconstructed PDG2011] +0.000000000 K*- K0 SVS; #[Reconstructed PDG2011] +# +#0.0180 K*0 K*- SVV_HELAMP 1.0 0.0 1.0 0.0 1.0 0.0; +0.002826940 K- K+ pi- PHSP; #[Reconstructed PDG2011] +0.000770283 K- K0 pi0 PHSP; #[Reconstructed PDG2011] +0.000000000 anti-K0 K0 pi- PHSP; #[Reconstructed PDG2011] +0.000770283 K*- K+ pi- PHSP; #[Reconstructed PDG2011] +0.000770283 K- K*+ pi- PHSP; #[Reconstructed PDG2011] +0.000770283 K*- K0 pi0 PHSP; #[Reconstructed PDG2011] +0.000770283 K- K*0 pi0 PHSP; #[Reconstructed PDG2011] +0.000770283 K*0 anti-K0 pi- PHSP; #[Reconstructed PDG2011] +0.000770283 K0 anti-K*0 pi- PHSP; #[Reconstructed PDG2011] +# +0.001260000 pi0 pi- PHSP; #[Reconstructed PDG2011] +0.000830000 rho0 pi- SVS; #[Reconstructed PDG2011] +0.002440000 pi- pi+ pi- PHSP; #[Reconstructed PDG2011] +0.004700000 pi- pi0 pi0 PHSP; #[Reconstructed PDG2011] +0.011600000 pi- pi+ pi- pi0 PHSP; #[Reconstructed PDG2011] +0.003851416 pi- pi0 pi0 pi0 PHSP; #[Reconstructed PDG2011] +0.003430000 eta pi- PHSP; #[Reconstructed PDG2011] +0.004400000 eta' pi- PHSP; #[Reconstructed PDG2011] +0.001380000 eta pi- pi0 PHSP; #[Reconstructed PDG2011] +0.002310850 eta pi- pi+ pi- PHSP; #[Reconstructed PDG2011] +0.001540566 eta pi- pi0 pi0 PHSP; #[Reconstructed PDG2011] +#lange jul22,2002 +0.001660000 pi+ pi- pi+ pi- pi- PHSP; #[Reconstructed PDG2011] +# +# March 2009 New Modes +0.009300000 K*0 a_1- PHSP; #[Reconstructed PDG2011] +0.010545178 K+ K- pi- pi0 PHSP; #[Reconstructed PDG2011] +# +0.001740000 K- K_S0 pi+ pi- PHSP; #[Reconstructed PDG2011] +0.001270967 K- K_L0 pi+ pi- PHSP; #[Reconstructed PDG2011] +0.000000000 K- K0 pi+ pi- PHSP; #[Reconstructed PDG2011] +# +0.002380000 K_S0 K+ pi- pi- PHSP; #[Reconstructed PDG2011] +0.001756246 K_L0 K+ pi- pi- PHSP; #[Reconstructed PDG2011] +0.000000000 anti-K0 K+ pi- pi- PHSP; #[Reconstructed PDG2011] +# +0.000230000 K+ K- pi+ pi- pi- PHSP; #[Reconstructed PDG2011] +# +0.000240000 K+ K- K_S0 pi- PHSP; #[Reconstructed PDG2011] +0.000161759 K+ K- K_L0 pi- PHSP; #[Reconstructed PDG2011] +0.000000000 K+ K- K0 pi- PHSP; #[Reconstructed PDG2011] +# Doubly Cabibbo suppressed modes +0.000237000 K- pi0 PHSP; #[Reconstructed PDG2011] +0.000332000 K- pi+ pi- PHSP; #[Reconstructed PDG2011] +0.000089000 K- K+ K- PHSP; #[Reconstructed PDG2011] +0.001720000 K+ rho0 pi- pi- PHSP; #[New mode added] #[Reconstructed PDG2011] +0.001600000 eta' pi- pi0 PHSP; #[New mode added] #[Reconstructed PDG2011] +0.000210000 K- rho0 PHSP; #[New mode added] #[Reconstructed PDG2011] +Enddecay +# +Decay K*BR +1.0000 anti-K0 pi0 VSS; +Enddecay +# +# +Decay D0 +# updated according to suggestions by P. Roudeau, +# using PDG2004 measurements and imposing the equality +# of sl partial widths for D+ and D0. +# Include additional decay anti-K0 pi- e+ nu_e , K- pi0 e+ nu_e. +# +0.021600000 K*- e+ nu_e PHOTOS ISGW2; # PDG2014 +0.035500000 K- e+ nu_e PHOTOS ISGW2; # PDG2014 +0.000760000 K_1- e+ nu_e PHOTOS ISGW2; # PDG2014 +0.001100000 K_2*- e+ nu_e PHOTOS ISGW2; # Small decrease as this is unmeasured +0.002890000 pi- e+ nu_e PHOTOS ISGW2; # PDG2014 +0.001770000 rho- e+ nu_e PHOTOS ISGW2; # PDG2014 +0.001080000 anti-K0 pi- e+ nu_e PHOTOS PHSP; # PDG2014 subtracting K* (decreased due large uncertaity ) +0.000400000 K- pi0 e+ nu_e PHOTOS PHSP; # PDG2014 subtracting K* (decreased due large uncertaity ) +# +0.021000000 K*- mu+ nu_mu PHOTOS ISGW2; # 1.1 * PDG2014 +0.034700000 K- mu+ nu_mu PHOTOS ISGW2; # 1.05 * PDG2014 +0.000076000 K_1- mu+ nu_mu PHOTOS ISGW2; # PDG2014 for electron +0.001100000 K_2*- mu+ nu_mu PHOTOS ISGW2; # copy from electron +0.002370000 pi- mu+ nu_mu PHOTOS ISGW2; # PDG2014 +0.002015940 rho- mu+ nu_mu PHOTOS ISGW2; # PDG2014 for electron +0.001080000 anti-K0 pi- mu+ nu_mu PHOTOS PHSP; # copy electron +0.000400000 K- pi0 mu+ nu_mu PHOTOS PHSP; # copy electron +# +0.038900000 K- pi+ PHSP; #[Reconstructed PDG2011] +# +0.012200000 K_S0 pi0 PHSP; #[Reconstructed PDG2011] +0.010000000 K_L0 pi0 PHSP; #[Reconstructed PDG2011] +0.000000000 anti-K0 pi0 PHSP; #[Reconstructed PDG2011] +# +0.004290000 K_S0 eta PHSP; #[Reconstructed PDG2011] +0.003802795 K_L0 eta PHSP; #[Reconstructed PDG2011] +0.000000000 anti-K0 eta PHSP; #[Reconstructed PDG2011] +# +0.009300000 K_S0 eta' PHSP; #[Reconstructed PDG2011] +0.008980094 K_L0 eta' PHSP; #[Reconstructed PDG2011] +0.000000000 anti-K0 eta' PHSP; #[Reconstructed PDG2011] +# +0.011100000 omega K_S0 SVS; #[Reconstructed PDG2011] +0.010904400 omega K_L0 SVS; #[Reconstructed PDG2011] +0.000000000 omega anti-K0 SVS; #[Reconstructed PDG2011] +# +0.001603588 anti-K*0 eta SVS; #[Reconstructed PDG2011] +0.000916336 anti-K*0 eta' SVS; #[Reconstructed PDG2011] +0.078000000 a_1+ K- SVS; #[Reconstructed PDG2011] +0.067625607 K*- rho+ SVV_HELAMP 1.0 0.0 1.0 0.0 1.0 0.0; #[Reconstructed PDG2011] +0.015800000 anti-K*0 rho0 SVV_HELAMP 1.0 0.0 1.0 0.0 1.0 0.0; #[Reconstructed PDG2011] +0.011000000 anti-K*0 omega SVV_HELAMP 1.0 0.0 1.0 0.0 1.0 0.0; #[Reconstructed PDG2011] +# the Dalitz mode below includes K*bar(892)0 pi0, +# K*(892)- pi+, and K- rho(770)+ resonances +0.139000000 K- pi+ pi0 D_DALITZ; #[Reconstructed PDG2011] +0.006634274 K*BR pi0 SVS; #[Reconstructed PDG2011] +0.016000000 K_1- pi+ SVS; #[Reconstructed PDG2011] +0.006505987 anti-K_10 pi0 SVS; #[Reconstructed PDG2011] +# +# the Dalitz mode below includes K*(892)- pi+ and Kbar0 rho(770)0 resonances +# LHCb PR 09 Apr 2004 split into KS/KL +0.029400000 K_S0 pi+ pi- D_DALITZ; #[Reconstructed PDG2011] +0.027856619 K_L0 pi+ pi- D_DALITZ; #[Reconstructed PDG2011] +0.000000000 anti-K0 pi+ pi- D_DALITZ; #[Reconstructed PDG2011] +# +0.008300000 K_S0 pi0 pi0 PHSP; #[Reconstructed PDG2011] +0.004425904 K_L0 pi0 pi0 PHSP; #[Reconstructed PDG2011] +0.000000000 anti-K0 pi0 pi0 PHSP; #[Reconstructed PDG2011] +# +0.024000000 anti-K*0 pi+ pi- PHSP; #[Reconstructed PDG2011] +0.010629499 anti-K*0 pi0 pi0 PHSP; #[Reconstructed PDG2011] +0.009163361 K*- pi+ pi0 PHSP; #[Reconstructed PDG2011] +0.006231086 K- rho+ pi0 PHSP; #[Reconstructed PDG2011] +0.005305586 K- pi+ rho0 PHSP; #[Reconstructed PDG2011] +0.019000000 K- pi+ omega PHSP; #[Reconstructed PDG2011] +0.009163361 K- pi+ eta PHSP; #[Reconstructed PDG2011] +0.007500000 K- pi+ eta' PHSP; #[Reconstructed PDG2011] +0.013300000 K- pi+ pi+ pi- PHSP; #[Reconstructed PDG2011] +# +0.054000000 K_S0 pi+ pi- pi0 PHSP; #[Reconstructed PDG2011] +0.010079698 K_L0 pi+ pi- pi0 PHSP; #[Reconstructed PDG2011] +0.000000000 anti-K0 pi+ pi- pi0 PHSP; #[Reconstructed PDG2011] +# +# K- pi+ pi0 pi0 is (15 +/- 5)% in the PDG, but we decrease it to +# have everything add to 1 and get enough neutral kaons: +#0.02575 K- pi+ pi0 pi0 PHSP; +# +#0.0143 anti-K0 pi0 pi0 pi0 PHSP; +0.040316317 anti-K0 pi0 pi0 pi0 PHSP; # Add in to fill sum to 1. [MK June 2015] +0.000000000 K- pi+ pi+ pi- pi0 PHSP; #[Reconstructed PDG2011] +0.003482077 K- pi+ pi0 pi0 pi0 PHSP; #[Reconstructed PDG2011] +# +0.002800000 K_S0 pi+ pi- pi+ pi- PHSP; #[Reconstructed PDG2011] +0.002684865 K_L0 pi+ pi- pi+ pi- PHSP; #[Reconstructed PDG2011] +0.000000000 anti-K0 pi+ pi- pi+ pi- PHSP; #[Reconstructed PDG2011] +# +#0.0638 anti-K0 pi+ pi- pi0 pi0 PHSP; +#0.0192 anti-K0 pi+ pi- pi0 pi0 pi0 PHSP; +# +0.002034266 phi K_S0 SVS; #[Reconstructed PDG2011] +0.002034266 phi K_L0 SVS; #[Reconstructed PDG2011] +0.000000000 phi anti-K0 SVS; #[Reconstructed PDG2011] +# +0.004650000 K_S0 K+ K- PHSP; #[Reconstructed PDG2011] +0.002785662 K_L0 K+ K- PHSP; #[Reconstructed PDG2011] +0.000000000 anti-K0 K+ K- PHSP; #[Reconstructed PDG2011] +# +0.000950000 K_S0 K_S0 K_S0 PHSP; #[Reconstructed PDG2011] +0.003940000 K+ K- PHSP; #[Reconstructed PDG2011] +0.000190000 K_S0 K_S0 PHSP; #[Reconstructed PDG2011] +0.000366534 K_L0 K_L0 PHSP; #[Reconstructed PDG2011] +0.000366534 K*0 anti-K0 SVS; #[Reconstructed PDG2011] +# +0.000091634 anti-K*0 K_S0 SVS; #[Reconstructed PDG2011] +0.000091634 anti-K*0 K_L0 SVS; #[Reconstructed PDG2011] +0.000000000 anti-K*0 K0 SVS; #[Reconstructed PDG2011] +# +0.000485658 K*- K+ SVS; #[Reconstructed PDG2011] +0.001365341 K*+ K- SVS; #[Reconstructed PDG2011] +0.001282871 anti-K*0 K*0 SVV_HELAMP 1.0 0.0 1.0 0.0 1.0 0.0; #[Reconstructed PDG2011] +0.000714742 phi pi0 SVS; #[Reconstructed PDG2011] +0.001007970 phi pi+ pi- PHSP; #[Reconstructed PDG2011] +0.002430000 K+ K- pi+ pi- PHSP; #[Reconstructed PDG2011] +0.002749008 K+ K- pi0 pi0 PHSP; #[Reconstructed PDG2011] +# +0.001280000 K_S0 K_S0 pi+ pi- PHSP; #[Reconstructed PDG2011] +0.001255381 K_L0 K_L0 pi+ pi- PHSP; #[Reconstructed PDG2011] +0.000000000 anti-K0 K0 pi+ pi- PHSP; #[Reconstructed PDG2011] +# +0.001374504 anti-K0 K0 pi0 pi0 PHSP; #[Reconstructed PDG2011] +# +0.001397000 pi+ pi- PHSP; #[Reconstructed PDG2011] +0.000800000 pi0 pi0 PHSP; #[Reconstructed PDG2011] +0.000640000 eta pi0 PHSP; #[Reconstructed PDG2011] +0.000810000 eta' pi0 PHSP; #[Reconstructed PDG2011] +0.001670000 eta eta PHSP; #[Reconstructed PDG2011] +0.009800000 rho+ pi- SVS; #[Reconstructed PDG2011] +0.004970000 rho- pi+ SVS; #[Reconstructed PDG2011] +0.003730000 rho0 pi0 SVS; #[Reconstructed PDG2011] +0.001209564 pi+ pi- pi0 PHSP; #[Reconstructed PDG2011] +0.000091634 pi0 pi0 pi0 PHSP; #[Reconstructed PDG2011] +0.005620000 pi+ pi+ pi- pi- PHSP; #[Reconstructed PDG2011] +0.009360000 pi+ pi- pi0 pi0 PHSP; #[Reconstructed PDG2011] +0.001510000 pi+ pi- pi+ pi- pi0 PHSP; #[Reconstructed PDG2011] +0.005498017 pi+ pi- pi0 pi0 pi0 PHSP; #[Reconstructed PDG2011] +0.000420000 pi+ pi- pi+ pi- pi+ pi- PHSP; #[Reconstructed PDG2011] +# +# Doubly Cabibbo suppressed decays: +0.000137450 pi- K+ PHSP; #[Reconstructed PDG2011] +0.000128287 pi- K*+ PHSP; #[Reconstructed PDG2011] +0.000274901 pi- K+ pi0 PHSP; #[Reconstructed PDG2011] +0.000247411 K+ pi- pi+ pi- PHSP; #[Reconstructed PDG2011] +# PR LHCb - 19 Apr. 2004 Add D0 -> mu+ mu- +0.000000000 mu+ mu- PHSP; #[Reconstructed PDG2011] +# +# March 2009 New Modes +0.000140000 phi eta PHSP; #[Reconstructed PDG2011] +0.019000000 anti-K*0 pi+ pi- pi0 PHSP; #[Reconstructed PDG2011] +0.000220000 K- pi+ pi- pi+ pi- pi+ PHSP; #[Reconstructed PDG2011] +0.000641435 K+ K- pi0 PHSP; #[Reconstructed PDG2011] +0.003100000 K+ K- pi+ pi- pi0 PHSP; #[Reconstructed PDG2011] +0.000221000 K+ K- K- pi+ PHSP; #[Reconstructed PDG2011] +# +0.005600000 K_S0 eta pi0 PHSP; #[Reconstructed PDG2011] +0.003665345 K_L0 eta pi0 PHSP; #[Reconstructed PDG2011] +0.000000000 anti-K0 eta pi0 PHSP; #[Reconstructed PDG2011] +# +0.002600000 K_S0 K+ pi- PHSP; #[Reconstructed PDG2011] +0.002382474 K_L0 K+ pi- PHSP; #[Reconstructed PDG2011] +0.000000000 anti-K0 K+ pi- PHSP; #[Reconstructed PDG2011] +# +0.003500000 K_S0 K- pi+ PHSP; #[Reconstructed PDG2011] +0.003344627 K_L0 K- pi+ PHSP; #[Reconstructed PDG2011] +0.000000000 K0 K- pi+ PHSP; #[Reconstructed PDG2011] +# +0.000310000 K_S0 K_S0 K+ pi- PHSP; #[Reconstructed PDG2011] +0.000293228 K_L0 K_L0 K+ pi- PHSP; #[Reconstructed PDG2011] +0.000000000 anti-K0 K0 K+ pi- PHSP; #[Reconstructed PDG2011] +# +0.000310000 K_S0 K_S0 K- pi+ PHSP; #[Reconstructed PDG2011] +0.000293228 K_L0 K_L0 K- pi+ PHSP; #[Reconstructed PDG2011] +0.000000000 anti-K0 K0 K- pi+ PHSP; #[Reconstructed PDG2011] +0.000000000 K- pi+ pi- e+ nu_e PHSP; #[New mode added] #[Reconstructed PDG2011] +0.001820000 rho0 rho0 PHSP; #[New mode added] #[Reconstructed PDG2011] +0.001090000 eta pi+ pi- PHSP; #[New mode added] #[Reconstructed PDG2011] +0.001600000 omega pi+ pi- PHSP; #[New mode added] #[Reconstructed PDG2011] +0.000450000 eta' pi+ pi- PHSP; #[New mode added] #[Reconstructed PDG2011] +0.001260000 eta eta' PHSP; #[New mode added] #[Reconstructed PDG2011] +0.000027000 phi gamma PHSP; #[New mode added] #[Reconstructed PDG2011] +0.000328000 anti-K*0 gamma PHSP; #[New mode added] #[Reconstructed PDG2011] +Enddecay +# +# +Decay K*0R +1.0000 K0 pi0 VSS; +Enddecay +# +# +Decay anti-D0 +0.021600000 K*+ e- anti-nu_e PHOTOS ISGW2; # PDG2014 +0.035500000 K+ e- anti-nu_e PHOTOS ISGW2; # PDG2014 +0.000760000 K_1+ e- anti-nu_e PHOTOS ISGW2; # PDG2014 +0.001100000 K_2*+ e- anti-nu_e PHOTOS ISGW2; # Small decrease as this is unmeasured +0.002890000 pi+ e- anti-nu_e PHOTOS ISGW2; # PDG2014 +0.001770000 rho+ e- anti-nu_e PHOTOS ISGW2; # PDG2014 +0.001080000 K0 pi+ e- anti-nu_e PHOTOS PHSP; # PDG2014 subtracting K* (decreased due large uncertaity ) +0.000400000 K+ pi0 e- anti-nu_e PHOTOS PHSP; # PDG2014 subtracting K* (decreased due large uncertaity ) +# +0.021000000 K*+ mu- anti-nu_mu PHOTOS ISGW2; # 1.1 * PDG2014 +0.034700000 K+ mu- anti-nu_mu PHOTOS ISGW2; # 1.05 * PDG2014 +0.000076000 K_1+ mu- anti-nu_mu PHOTOS ISGW2; # PDG2014 for electron +0.001100000 K_2*+ mu- anti-nu_mu PHOTOS ISGW2; # copy from electron +0.002370000 pi+ mu- anti-nu_mu PHOTOS ISGW2; # PDG2014 +0.002015940 rho+ mu- anti-nu_mu PHOTOS ISGW2; # PDG2014 for electron +0.001080000 K0 pi+ mu- anti-nu_mu PHOTOS PHSP; # copy electron +0.000400000 K+ pi0 mu- anti-nu_mu PHOTOS PHSP; # copy electron +# +0.038900000 K+ pi- PHSP; #[Reconstructed PDG2011] +# +0.012200000 K_S0 pi0 PHSP; #[Reconstructed PDG2011] +0.010000000 K_L0 pi0 PHSP; #[Reconstructed PDG2011] +0.000000000 K0 pi0 PHSP; #[Reconstructed PDG2011] +# +0.004290000 K_S0 eta PHSP; #[Reconstructed PDG2011] +0.003818748 K_L0 eta PHSP; #[Reconstructed PDG2011] +0.000000000 K0 eta PHSP; #[Reconstructed PDG2011] +# +0.009300000 K_S0 eta' PHSP; #[Reconstructed PDG2011] +0.009017767 K_L0 eta' PHSP; #[Reconstructed PDG2011] +0.000000000 K0 eta' PHSP; #[Reconstructed PDG2011] +# +0.011100000 omega K_S0 SVS; #[Reconstructed PDG2011] +0.010950146 omega K_L0 SVS; #[Reconstructed PDG2011] +0.000000000 omega K0 SVS; #[Reconstructed PDG2011] +# +0.001610316 K*0 eta SVS; #[Reconstructed PDG2011] +0.000920180 K*0 eta' SVS; #[Reconstructed PDG2011] +0.078000000 a_1- K+ SVS; #[Reconstructed PDG2011] +0.067909308 K*+ rho- SVV_HELAMP 1.0 0.0 1.0 0.0 1.0 0.0; #[Reconstructed PDG2011] +0.015800000 K*0 rho0 SVV_HELAMP 1.0 0.0 1.0 0.0 1.0 0.0; #[Reconstructed PDG2011] +0.011000000 K*0 omega SVV_HELAMP 1.0 0.0 1.0 0.0 1.0 0.0; #[Reconstructed PDG2011] +# the Dalitz mode below includes K*(892)0 pi0, K*(892)+ pi-, and K+ rho(770)- resonances +0.139000000 K+ pi- pi0 D_DALITZ; #[Reconstructed PDG2011] +0.006662106 K*0R pi0 SVS; #[Reconstructed PDG2011] +0.016000000 K_1+ pi- SVS; #[Reconstructed PDG2011] +0.006533280 K_10 pi0 SVS; #[Reconstructed PDG2011] +# the Dalitz mode below includes K*(892)+ pi- and K0 rho(770)0 resonances +# LHCb PR 09 Apr 2004, split into KS/KL +0.000000000 K0 pi+ pi- D_DALITZ; #[Reconstructed PDG2011] +0.029400000 K_S0 pi+ pi- D_DALITZ; #[Reconstructed PDG2011] +0.027973482 K_L0 pi+ pi- D_DALITZ; #[Reconstructed PDG2011] +# +0.008300000 K_S0 pi0 pi0 PHSP; #[Reconstructed PDG2011] +0.004444471 K_L0 pi0 pi0 PHSP; #[Reconstructed PDG2011] +0.000000000 K0 pi0 pi0 PHSP; #[Reconstructed PDG2011] +# +0.024000000 K*0 pi+ pi- PHSP; #[Reconstructed PDG2011] +0.010674092 K*0 pi0 pi0 PHSP; #[Reconstructed PDG2011] +0.009201803 K*+ pi- pi0 PHSP; #[Reconstructed PDG2011] +0.006257226 K+ rho- pi0 PHSP; #[Reconstructed PDG2011] +0.005327844 K+ pi- rho0 PHSP; #[Reconstructed PDG2011] +0.019000000 K+ pi- omega PHSP; #[Reconstructed PDG2011] +0.009201803 K+ pi- eta PHSP; #[Reconstructed PDG2011] +0.007500000 K+ pi- eta' PHSP; #[Reconstructed PDG2011] +0.013300000 K+ pi- pi+ pi- PHSP; #[Reconstructed PDG2011] +# +0.054000000 K_S0 pi+ pi- pi0 PHSP; #[Reconstructed PDG2011] +0.010121984 K_L0 pi+ pi- pi0 PHSP; #[Reconstructed PDG2011] +0.000000000 K0 pi+ pi- pi0 PHSP; #[Reconstructed PDG2011] +# +# K+ pi- pi0 pi0 is (15 +/- 5)% in the PDG, but we decrease it to +# have everything add to 1 and get enough neutral kaons: +#0.02575 K+ pi- pi0 pi0 PHSP; +# +#0.0143 K0 pi0 pi0 pi0 PHSP; +0.040346268 K0 pi0 pi0 pi0 PHSP; +0.000000000 K+ pi- pi+ pi- pi0 PHSP; #[Reconstructed PDG2011] +0.003496685 K+ pi- pi0 pi0 pi0 PHSP; #[Reconstructed PDG2011] +# +0.002800000 K_S0 pi+ pi- pi+ pi- PHSP; #[Reconstructed PDG2011] +0.002696128 K_L0 pi+ pi- pi+ pi- PHSP; #[Reconstructed PDG2011] +0.000000000 K0 pi+ pi- pi+ pi- PHSP; #[Reconstructed PDG2011] +# +#0.0638 K0 pi- pi+ pi0 pi0 PHSP; +#0.0192 K0 pi- pi+ pi0 pi0 pi0 PHSP; +# +0.002042800 phi K_S0 SVS; #[Reconstructed PDG2011] +0.002042800 phi K_L0 SVS; #[Reconstructed PDG2011] +0.000000000 phi K0 SVS; #[Reconstructed PDG2011] +# +0.004650000 K_S0 K+ K- PHSP; #[Reconstructed PDG2011] +0.002797348 K_L0 K+ K- PHSP; #[Reconstructed PDG2011] +0.000000000 K0 K+ K- PHSP; #[Reconstructed PDG2011] +# +0.000950000 K_S0 K_S0 K_S0 PHSP; #[Reconstructed PDG2011] +0.003940000 K+ K- PHSP; #[Reconstructed PDG2011] +0.000190000 K_S0 K_S0 PHSP; #[Reconstructed PDG2011] +0.000368072 K_L0 K_L0 PHSP; #[Reconstructed PDG2011] +0.000368072 anti-K*0 K0 SVS; #[Reconstructed PDG2011] +# +0.000092018 K*0 K_S0 SVS; #[Reconstructed PDG2011] +0.000092018 K*0 K_L0 SVS; #[Reconstructed PDG2011] +0.000000000 K*0 anti-K0 SVS; #[Reconstructed PDG2011] +# +0.000487696 K*+ K- SVS; #[Reconstructed PDG2011] +0.001371069 K*- K+ SVS; #[Reconstructed PDG2011] +0.001288252 K*0 anti-K*0 SVV_HELAMP 1.0 0.0 1.0 0.0 1.0 0.0; #[Reconstructed PDG2011] +0.000717741 phi pi0 SVS; #[Reconstructed PDG2011] +0.001012198 phi pi+ pi- PHSP; #[Reconstructed PDG2011] +0.002430000 K+ K- pi+ pi- PHSP; #[Reconstructed PDG2011] +0.002760541 K+ K- pi0 pi0 PHSP; #[Reconstructed PDG2011] +# +0.001280000 K_S0 K_S0 pi+ pi- PHSP; #[Reconstructed PDG2011] +0.001260647 K_L0 K_L0 pi+ pi- PHSP; #[Reconstructed PDG2011] +0.000000000 anti-K0 K0 pi+ pi- PHSP; #[Reconstructed PDG2011] +# +0.001380270 anti-K0 K0 pi0 pi0 PHSP; #[Reconstructed PDG2011] +# +0.001397000 pi+ pi- PHSP; #[Reconstructed PDG2011] +0.000800000 pi0 pi0 PHSP; #[Reconstructed PDG2011] +0.000640000 eta pi0 PHSP; #[Reconstructed PDG2011] +0.000810000 eta' pi0 PHSP; #[Reconstructed PDG2011] +0.001670000 eta eta PHSP; #[Reconstructed PDG2011] +0.009128189 rho+ pi- SVS; #[Reconstructed PDG2011] +0.004637709 rho- pi+ SVS; #[Reconstructed PDG2011] +0.003730000 rho0 pi0 SVS; #[Reconstructed PDG2011] +0.001214638 pi+ pi- pi0 PHSP; #[Reconstructed PDG2011] +0.000092018 pi0 pi0 pi0 PHSP; #[Reconstructed PDG2011] +0.005620000 pi+ pi+ pi- pi- PHSP; #[Reconstructed PDG2011] +0.009360000 pi+ pi- pi0 pi0 PHSP; #[Reconstructed PDG2011] +0.001510000 pi+ pi- pi+ pi- pi0 PHSP; #[Reconstructed PDG2011] +0.005521082 pi+ pi- pi0 pi0 pi0 PHSP; #[Reconstructed PDG2011] +0.000420000 pi+ pi- pi+ pi- pi+ pi- PHSP; #[Reconstructed PDG2011] +# +# Doubly Cabibbo suppressed decays: +0.000138027 pi+ K- PHSP; #[Reconstructed PDG2011] +0.000128825 pi+ K*- PHSP; #[Reconstructed PDG2011] +0.000276054 pi+ K- pi0 PHSP; #[Reconstructed PDG2011] +0.000248449 K- pi+ pi+ pi- PHSP; #[Reconstructed PDG2011] +# PR LHCb - 19 Apr. 2004 Add anti-D0 -> mu+ mu- +0.000000000 mu- mu+ PHSP; #[Reconstructed PDG2011] +# +# March 2009 New Modes +0.000140000 phi eta PHSP; #[Reconstructed PDG2011] +0.019000000 K*0 pi+ pi- pi0 PHSP; #[Reconstructed PDG2011] +0.000220000 K+ pi- pi- pi+ pi- pi+ PHSP; #[Reconstructed PDG2011] +0.000644126 K+ K- pi0 PHSP; #[Reconstructed PDG2011] +0.003100000 K+ K- pi+ pi- pi0 PHSP; #[Reconstructed PDG2011] +0.000221000 K+ K+ K- pi- PHSP; #[Reconstructed PDG2011] +# +0.005600000 K_S0 eta pi0 PHSP; #[Reconstructed PDG2011] +0.003680721 K_L0 eta pi0 PHSP; #[Reconstructed PDG2011] +0.000000000 K0 eta pi0 PHSP; #[Reconstructed PDG2011] +# +0.002600000 K_S0 K- pi+ PHSP; #[Reconstructed PDG2011] +0.002392469 K_L0 K- pi+ PHSP; #[Reconstructed PDG2011] +0.000000000 K0 K- pi+ PHSP; #[Reconstructed PDG2011] +# +0.003500000 K_S0 K+ pi- PHSP; #[Reconstructed PDG2011] +0.003358658 K_L0 K+ pi- PHSP; #[Reconstructed PDG2011] +0.000000000 anti-K0 K+ pi- PHSP; #[Reconstructed PDG2011] +# +0.000310000 K_S0 K_S0 K+ pi- PHSP; #[Reconstructed PDG2011] +0.000294458 K_L0 K_L0 K+ pi- PHSP; #[Reconstructed PDG2011] +0.000000000 anti-K0 K0 K+ pi- PHSP; #[Reconstructed PDG2011] +# +0.000310000 K_S0 K_S0 K- pi+ PHSP; #[Reconstructed PDG2011] +0.000294458 K_L0 K_L0 K- pi+ PHSP; #[Reconstructed PDG2011] +0.000000000 anti-K0 K0 K- pi+ PHSP; #[Reconstructed PDG2011] +0.000000000 K+ pi- pi+ e- anti-nu_e PHSP; #[New mode added] #[Reconstructed PDG2011] +0.001820000 rho0 rho0 PHSP; #[New mode added] #[Reconstructed PDG2011] +0.001090000 eta pi- pi+ PHSP; #[New mode added] #[Reconstructed PDG2011] +0.001600000 omega pi- pi+ PHSP; #[New mode added] #[Reconstructed PDG2011] +0.000450000 eta' pi- pi+ PHSP; #[New mode added] #[Reconstructed PDG2011] +0.001260000 eta eta' PHSP; #[New mode added] #[Reconstructed PDG2011] +0.000027000 phi gamma PHSP; #[New mode added] #[Reconstructed PDG2011] +0.000328000 K*0 gamma PHSP; #[New mode added] #[Reconstructed PDG2011] +Enddecay +# +# Updated to PDG 2008 +Decay D_s+ +0.024900000 phi e+ nu_e PHOTOS ISGW2; #[Reconstructed PDG2011] +0.026700000 eta e+ nu_e PHOTOS ISGW2; #[Reconstructed PDG2011] +0.009900000 eta' e+ nu_e PHOTOS ISGW2; #[Reconstructed PDG2011] +0.002058115 anti-K0 e+ nu_e PHOTOS ISGW2; #[Reconstructed PDG2011] +0.000762265 anti-K*0 e+ nu_e PHOTOS ISGW2; #[Reconstructed PDG2011] +0.018309605 phi mu+ nu_mu PHOTOS ISGW2; #[Reconstructed PDG2011] +0.022845082 eta mu+ nu_mu PHOTOS ISGW2; #[Reconstructed PDG2011] +0.008186726 eta' mu+ nu_mu PHOTOS ISGW2; #[Reconstructed PDG2011] +0.002058115 anti-K0 mu+ nu_mu PHOTOS ISGW2; #[Reconstructed PDG2011] +0.000762265 anti-K*0 mu+ nu_mu PHOTOS ISGW2; #[Reconstructed PDG2011] +0.005800000 mu+ nu_mu PHOTOS SLN; #[Reconstructed PDG2011] +0.031100000 tau+ nu_tau SLN; #[Reconstructed PDG2011] +### Lange Nov14, 2004 - average cleo + babar (prelim) using stat error only.. +0.045000000 phi pi+ SVS; #[Reconstructed PDG2011] +0.015600000 eta pi+ PHSP; #[Reconstructed PDG2011] +0.038000000 eta' pi+ PHSP; #[Reconstructed PDG2011] +0.002300000 omega pi+ SVS; #[Reconstructed PDG2011] +0.000304906 rho+ pi0 SVS; #[Reconstructed PDG2011] +0.000076226 pi+ pi0 PHSP; #[Reconstructed PDG2011] +#? +0.000196200 rho0 pi+ SVS; # PDG 2014 +0.007852048 f_0 pi+ PHSP; # PDG 2014 +0.001753646 f_2 pi+ PHSP; # PDG 2014 +0.004754077 f'_0 pi+ PHSP; # PDG 2014 +0.005768112 f_0(1500) pi+ PHSP; # PDG 2014 +#0.000735750 rho(2S)0 pi+ PHSP; # PDG 2014 +0.000000000 pi+ pi- pi+ PHSP; # PDG 2014 (filled by exclusives) +0.084000000 phi rho+ SVV_HELAMP 1.0 0.0 1.0 0.0 1.0 0.0; #[Reconstructed PDG2011] +0.089000000 rho+ eta SVS; #[Reconstructed PDG2011] +0.124213286 rho+ eta' SVS; # Decrease compared to PDG 2014 to preserve unitarity after +# # fixing Ds --> 3pi, we also have too much of inclusive eta', +# #so pick this decay +0.006500000 pi+ pi0 pi0 PHSP; #[Reconstructed PDG2011] +0.007622650 phi pi+ pi0 PHSP; #[Reconstructed PDG2011] +0.011433975 eta pi+ pi0 PHSP; #[Reconstructed PDG2011] +0.011433975 eta' pi+ pi0 PHSP; #[Reconstructed PDG2011] +0.012100000 phi pi+ pi- pi+ PHSP; #[Reconstructed PDG2011] +0.003811325 phi pi+ pi0 pi0 PHSP; #[Reconstructed PDG2011] +0.003811325 eta pi+ pi- pi+ PHSP; #[Reconstructed PDG2011] +0.003811325 eta pi+ pi0 pi0 PHSP; #[Reconstructed PDG2011] +# +0.014900000 K_S0 K+ PHSP; #[Reconstructed PDG2011] +0.011472088 K_L0 K+ PHSP; #[Reconstructed PDG2011] +0.000000000 anti-K0 K+ PHSP; #[Reconstructed PDG2011] +# +0.030490600 anti-K*0 K+ SVS; #[Reconstructed PDG2011] +0.054000000 K*+ anti-K0 SVS; #[Reconstructed PDG2011] +0.072000000 anti-K*0 K*+ SVV_HELAMP 1.0 0.0 1.0 0.0 1.0 0.0; #[Reconstructed PDG2011] +0.002286795 anti-K0 K+ pi0 PHSP; #[Reconstructed PDG2011] +0.000914718 anti-K*0 K+ pi0 PHSP; #[Reconstructed PDG2011] +0.000914718 K*+ anti-K0 pi0 PHSP; #[Reconstructed PDG2011] +0.003049060 anti-K*0 K*+ pi0 PHSP; #[Reconstructed PDG2011] +0.003811325 K+ K- pi+ PHSP; #[Reconstructed PDG2011] +# +0.009600000 K_S0 K+ pi+ pi- PHSP; #[Reconstructed PDG2011] +0.007470197 K_L0 K+ pi+ pi- PHSP; #[Reconstructed PDG2011] +0.000000000 anti-K0 K+ pi+ pi- PHSP; #[Reconstructed PDG2011] +# +0.000762265 anti-K0 K+ pi0 pi0 PHSP; #[Reconstructed PDG2011] +0.000000000 K+ K- pi+ pi- pi+ PHSP; #[Reconstructed PDG2011] +0.000152453 phi K+ SVS; #[Reconstructed PDG2011] +0.001390000 eta K+ PHSP; #[Reconstructed PDG2011] +0.001600000 eta' K+ PHSP; #[Reconstructed PDG2011] +0.000152453 eta K+ pi0 PHSP; #[Reconstructed PDG2011] +0.000152453 eta K+ pi+ pi- PHSP; #[Reconstructed PDG2011] +0.000152453 eta' K+ pi0 PHSP; #[Reconstructed PDG2011] +0.000152453 eta' K+ pi+ pi- PHSP; #[Reconstructed PDG2011] +0.000490000 K+ K- K+ PHSP; #[Reconstructed PDG2011] +# +0.001200000 K_S0 pi+ PHSP; #[Reconstructed PDG2011] +0.000968077 K_L0 pi+ PHSP; #[Reconstructed PDG2011] +0.000000000 K0 pi+ PHSP; #[Reconstructed PDG2011] +# +0.001143397 rho+ K0 SVS; #[Reconstructed PDG2011] +0.002700000 rho0 K+ SVS; #[Reconstructed PDG2011] +0.010000000 K0 pi+ pi0 PHSP; #[Reconstructed PDG2011] +0.001905662 a_1+ K0 SVS; #[Reconstructed PDG2011] +0.006021893 K*0 pi+ SVS; #[Reconstructed PDG2011] +0.003811325 K*0 rho+ SVV_HELAMP 1.0 0.0 1.0 0.0 1.0 0.0; #[Reconstructed PDG2011] +0.003811325 K*0 pi+ pi0 PHSP; #[Reconstructed PDG2011] +# +# March 2009 New Modes +0.000820000 K+ pi0 PHSP; #[Reconstructed PDG2011] +0.004200000 K+ pi+ pi- PHSP; #[Reconstructed PDG2011] +0.008000000 pi+ pi+ pi+ pi- pi- PHSP; #[Reconstructed PDG2011] +0.049000000 pi+ pi+ pi+ pi- pi- pi0 PHSP; #[Reconstructed PDG2011] +0.001300000 p+ anti-n0 PHSP; #[Reconstructed PDG2011] +# +0.000840000 K_S0 K_S0 pi+ pi+ pi- PHSP; #[Reconstructed PDG2011] +0.000686038 K_L0 K_L0 pi+ pi+ pi- PHSP; #[Reconstructed PDG2011] +0.000000000 anti-K0 K0 pi+ pi+ pi- PHSP; #[Reconstructed PDG2011] +# +0.002900000 K_S0 pi+ pi+ pi- PHSP; #[Reconstructed PDG2011] +0.002424003 K_L0 pi+ pi+ pi- PHSP; #[Reconstructed PDG2011] +0.000000000 anti-K0 pi+ pi+ pi- PHSP; #[Reconstructed PDG2011] +# Doubly Cabibbo suppressed +0.000129000 K+ K+ pi- PHSP; #[Reconstructed PDG2011] +0.003700000 K0 e+ nu_e PHSP; #[New mode added] #[Reconstructed PDG2011] +0.001800000 K*0 e+ nu_e PHSP; #[New mode added] #[Reconstructed PDG2011] +0.000000000 K+ K- pi+ pi0 PHSP; #[New mode added] #[Reconstructed PDG2011] +0.028000000 omega pi+ pi0 PHSP; #[New mode added] #[Reconstructed PDG2011] +0.016000000 omega pi+ pi+ pi- PHSP; #[New mode added] #[Reconstructed PDG2011] +Enddecay +# +# Updated to PDG 2008 +Decay D_s- +0.024900000 phi e- anti-nu_e PHOTOS ISGW2; #[Reconstructed PDG2011] +0.026700000 eta e- anti-nu_e PHOTOS ISGW2; #[Reconstructed PDG2011] +0.009900000 eta' e- anti-nu_e PHOTOS ISGW2; #[Reconstructed PDG2011] +0.002058115 K0 e- anti-nu_e PHOTOS ISGW2; #[Reconstructed PDG2011] +0.000762265 K*0 e- anti-nu_e PHOTOS ISGW2; #[Reconstructed PDG2011] +0.018309605 phi mu- anti-nu_mu PHOTOS ISGW2; #[Reconstructed PDG2011] +0.022845082 eta mu- anti-nu_mu PHOTOS ISGW2; #[Reconstructed PDG2011] +0.008186726 eta' mu- anti-nu_mu PHOTOS ISGW2; #[Reconstructed PDG2011] +0.002058115 K0 mu- anti-nu_mu PHOTOS ISGW2; #[Reconstructed PDG2011] +0.000762265 K*0 mu- anti-nu_mu PHOTOS ISGW2; #[Reconstructed PDG2011] +0.005800000 mu- anti-nu_mu PHOTOS SLN; #[Reconstructed PDG2011] +0.031100000 tau- anti-nu_tau SLN; #[Reconstructed PDG2011] +0.045000000 phi pi- SVS; #[Reconstructed PDG2011] +0.015600000 eta pi- PHSP; #[Reconstructed PDG2011] +0.038000000 eta' pi- PHSP; #[Reconstructed PDG2011] +0.002300000 omega pi- SVS; #[Reconstructed PDG2011] +0.000304906 rho- pi0 SVS; #[Reconstructed PDG2011] +0.000076226 pi- pi0 PHSP; #[Reconstructed PDG2011] +0.000196200 rho0 pi- SVS; # PDG 2014 +0.007852048 f_0 pi- PHSP; # PDG 2014 +0.001753646 f_2 pi- PHSP; # PDG 2014 +0.004754077 f'_0 pi- PHSP; # PDG 2014 +0.005768112 f_0(1500) pi- PHSP; # PDG 2014 +#0.000735750 rho(2S)0 pi- PHSP; # PDG 2014 +0.000000000 pi- pi+ pi- PHSP; # PDG 2014 (filled by exclusives) +0.084000000 phi rho- SVV_HELAMP 1.0 0.0 1.0 0.0 1.0 0.0; #[Reconstructed PDG2011] +0.089000000 rho- eta SVS; #[Reconstructed PDG2011] +0.124213286 rho- eta' SVS; # Decrease compared to PDG 2014 to preserve unitarity after +0.006500000 pi- pi0 pi0 PHSP; #[Reconstructed PDG2011] +0.007622650 phi pi- pi0 PHSP; #[Reconstructed PDG2011] +0.011433975 eta pi- pi0 PHSP; #[Reconstructed PDG2011] +0.011433975 eta' pi- pi0 PHSP; #[Reconstructed PDG2011] +0.012100000 phi pi- pi- pi+ PHSP; #[Reconstructed PDG2011] +0.003811325 phi pi- pi0 pi0 PHSP; #[Reconstructed PDG2011] +0.003811325 eta pi- pi- pi+ PHSP; #[Reconstructed PDG2011] +0.003811325 eta pi- pi0 pi0 PHSP; #[Reconstructed PDG2011] +# +0.014900000 K_S0 K- PHSP; #[Reconstructed PDG2011] +0.011472088 K_L0 K- PHSP; #[Reconstructed PDG2011] +0.000000000 K0 K- PHSP; #[Reconstructed PDG2011] +# +0.030490600 K*0 K- SVS; #[Reconstructed PDG2011] +0.054000000 K*- K0 SVS; #[Reconstructed PDG2011] +0.072000000 K*0 K*- SVV_HELAMP 1.0 0.0 1.0 0.0 1.0 0.0; #[Reconstructed PDG2011] +0.002286795 K0 K- pi0 PHSP; #[Reconstructed PDG2011] +0.000914718 K*0 K- pi0 PHSP; #[Reconstructed PDG2011] +0.000914718 K*- K0 pi0 PHSP; #[Reconstructed PDG2011] +0.003049060 K*0 K*- pi0 PHSP; #[Reconstructed PDG2011] +0.003811325 K+ K- pi- PHSP; #[Reconstructed PDG2011] +# +0.009600000 K_S0 K- pi+ pi- PHSP; #[Reconstructed PDG2011] +0.007470197 K_L0 K- pi+ pi- PHSP; #[Reconstructed PDG2011] +0.000000000 K0 K- pi+ pi- PHSP; #[Reconstructed PDG2011] +# +0.000762265 K0 K- pi0 pi0 PHSP; #[Reconstructed PDG2011] +0.000000000 K- K+ pi- pi+ pi- PHSP; #[Reconstructed PDG2011] +0.000152453 phi K- SVS; #[Reconstructed PDG2011] +0.001390000 eta K- PHSP; #[Reconstructed PDG2011] +0.001600000 eta' K- PHSP; #[Reconstructed PDG2011] +0.000152453 eta K- pi0 PHSP; #[Reconstructed PDG2011] +0.000152453 eta K- pi+ pi- PHSP; #[Reconstructed PDG2011] +0.000152453 eta' K- pi0 PHSP; #[Reconstructed PDG2011] +0.000152453 eta' K- pi+ pi- PHSP; #[Reconstructed PDG2011] +0.000490000 K- K- K+ PHSP; #[Reconstructed PDG2011] +# +0.001200000 K_S0 pi- PHSP; #[Reconstructed PDG2011] +0.000968077 K_L0 pi- PHSP; #[Reconstructed PDG2011] +0.000000000 anti-K0 pi- PHSP; #[Reconstructed PDG2011] +# +0.001143397 rho- anti-K0 SVS; #[Reconstructed PDG2011] +0.002700000 rho0 K- SVS; #[Reconstructed PDG2011] +0.010000000 anti-K0 pi- pi0 PHSP; #[Reconstructed PDG2011] +0.001905662 a_1- anti-K0 SVS; #[Reconstructed PDG2011] +0.006021893 anti-K*0 pi- SVS; #[Reconstructed PDG2011] +0.003811325 anti-K*0 rho- SVV_HELAMP 1.0 0.0 1.0 0.0 1.0 0.0; #[Reconstructed PDG2011] +0.003811325 anti-K*0 pi- pi0 PHSP; #[Reconstructed PDG2011] +# +# March 2009 New Modes +0.000820000 K- pi0 PHSP; #[Reconstructed PDG2011] +0.004200000 K- pi+ pi- PHSP; #[Reconstructed PDG2011] +0.008000000 pi+ pi+ pi- pi- pi- PHSP; #[Reconstructed PDG2011] +0.049000000 pi+ pi+ pi- pi- pi- pi0 PHSP; #[Reconstructed PDG2011] +0.001300000 anti-p- n0 PHSP; #[Reconstructed PDG2011] +# +0.000840000 K_S0 K_S0 pi+ pi- pi- PHSP; #[Reconstructed PDG2011] +0.000686038 K_L0 K_L0 pi+ pi- pi- PHSP; #[Reconstructed PDG2011] +0.000000000 anti-K0 K0 pi+ pi- pi- PHSP; #[Reconstructed PDG2011] +# +0.002900000 K_S0 pi+ pi- pi- PHSP; #[Reconstructed PDG2011] +0.002424003 K_L0 pi+ pi- pi- PHSP; #[Reconstructed PDG2011] +0.000000000 K0 pi+ pi- pi- PHSP; #[Reconstructed PDG2011] +# Doubly Cabibbo suppressed +0.000129000 K- K- pi+ PHSP; #[Reconstructed PDG2011] +0.003700000 anti-K0 e- anti-nu_e PHSP; #[New mode added] #[Reconstructed PDG2011] +0.001800000 anti-K*0 e- anti-nu_e PHSP; #[New mode added] #[Reconstructed PDG2011] +0.000000000 K- K+ pi- pi0 PHSP; #[New mode added] #[Reconstructed PDG2011] +0.028000000 omega pi- pi0 PHSP; #[New mode added] #[Reconstructed PDG2011] +0.016000000 omega pi- pi- pi+ PHSP; #[New mode added] #[Reconstructed PDG2011] +Enddecay +# +# D** +# +Decay D_0*+ +0.3333 D+ pi0 PHSP; +0.6667 D0 pi+ PHSP; +Enddecay +Decay D_0*- +0.3333 D- pi0 PHSP; +0.6667 anti-D0 pi- PHSP; +Enddecay +Decay D_0*0 +0.3333 D0 pi0 PHSP; +0.6667 D+ pi- PHSP; +Enddecay +Decay anti-D_0*0 +0.3333 anti-D0 pi0 PHSP; +0.6667 D- pi+ PHSP; +Enddecay +# + +SetLineshapePW D_1+ D*+ pi0 2 +SetLineshapePW D_1+ D*0 pi+ 2 +SetLineshapePW D_1- D*- pi0 2 +SetLineshapePW D_1- anti-D*0 pi- 2 +SetLineshapePW D_10 D*0 pi0 2 +SetLineshapePW D_10 D*+ pi- 2 +SetLineshapePW anti-D_10 anti-D*0 pi0 2 +SetLineshapePW anti-D_10 D*- pi+ 2 + +Decay D_1+ +0.3333 D*+ pi0 VVS_PWAVE 0.0 0.0 0.0 0.0 1.0 0.0; +0.6667 D*0 pi+ VVS_PWAVE 0.0 0.0 0.0 0.0 1.0 0.0; +Enddecay +Decay D_1- +0.3333 D*- pi0 VVS_PWAVE 0.0 0.0 0.0 0.0 1.0 0.0; +0.6667 anti-D*0 pi- VVS_PWAVE 0.0 0.0 0.0 0.0 1.0 0.0; +Enddecay +Decay D_10 +0.3333 D*0 pi0 VVS_PWAVE 0.0 0.0 0.0 0.0 1.0 0.0; +0.6667 D*+ pi- VVS_PWAVE 0.0 0.0 0.0 0.0 1.0 0.0; +Enddecay +Decay anti-D_10 +0.3333 anti-D*0 pi0 VVS_PWAVE 0.0 0.0 0.0 0.0 1.0 0.0; +0.6667 D*- pi+ VVS_PWAVE 0.0 0.0 0.0 0.0 1.0 0.0; +Enddecay +# +Decay D'_1+ +0.3333 D*+ pi0 VVS_PWAVE 1.0 0.0 0.0 0.0 0.0 0.0; +0.6667 D*0 pi+ VVS_PWAVE 1.0 0.0 0.0 0.0 0.0 0.0; +Enddecay +Decay D'_1- +0.3333 D*- pi0 VVS_PWAVE 1.0 0.0 0.0 0.0 0.0 0.0; +0.6667 anti-D*0 pi- VVS_PWAVE 1.0 0.0 0.0 0.0 0.0 0.0; +Enddecay +Decay D'_10 +0.6667 D*+ pi- VVS_PWAVE 1.0 0.0 0.0 0.0 0.0 0.0; +0.3333 D*0 pi0 VVS_PWAVE 1.0 0.0 0.0 0.0 0.0 0.0; +Enddecay +Decay anti-D'_10 +0.3333 anti-D*0 pi0 VVS_PWAVE 1.0 0.0 0.0 0.0 0.0 0.0; +0.6667 D*- pi+ VVS_PWAVE 1.0 0.0 0.0 0.0 0.0 0.0; +Enddecay +# + +SetLineshapePW D_2*+ D*+ pi0 2 +SetLineshapePW D_2*+ D*0 pi+ 2 +SetLineshapePW D_2*- D*- pi0 2 +SetLineshapePW D_2*- anti-D*0 pi- 2 +SetLineshapePW D_2*0 D*0 pi0 2 +SetLineshapePW D_2*0 D*+ pi- 2 +SetLineshapePW anti-D_2*0 anti-D*0 pi0 2 +SetLineshapePW anti-D_2*0 D*- pi+ 2 + +Decay D_2*+ +0.1030 D*+ pi0 TVS_PWAVE 0.0 0.0 1.0 0.0 0.0 0.0; +0.2090 D*0 pi+ TVS_PWAVE 0.0 0.0 1.0 0.0 0.0 0.0; +0.2290 D+ pi0 TSS; +0.4590 D0 pi+ TSS; +Enddecay +Decay D_2*- +0.1030 D*- pi0 TVS_PWAVE 0.0 0.0 1.0 0.0 0.0 0.0; +0.2090 anti-D*0 pi- TVS_PWAVE 0.0 0.0 1.0 0.0 0.0 0.0; +0.2290 D- pi0 TSS; +0.4590 anti-D0 pi- TSS; +Enddecay +Decay D_2*0 +0.2090 D*+ pi- TVS_PWAVE 0.0 0.0 1.0 0.0 0.0 0.0; +0.1030 D*0 pi0 TVS_PWAVE 0.0 0.0 1.0 0.0 0.0 0.0; +0.2290 D0 pi0 TSS; +0.4590 D+ pi- TSS; +Enddecay +Decay anti-D_2*0 +0.1030 anti-D*0 pi0 TVS_PWAVE 0.0 0.0 1.0 0.0 0.0 0.0; +0.2090 D*- pi+ TVS_PWAVE 0.0 0.0 1.0 0.0 0.0 0.0; +0.2290 anti-D0 pi0 TSS; +0.4590 D- pi+ TSS; +Enddecay +# +# D_s ** +# +Decay D_s0*+ +# 0.5000 D+ K0 PHSP; +# 0.5000 D0 K+ PHSP; +1.000 D_s+ pi0 PHSP; +Enddecay +Decay D_s0*- +# 0.5000 D- anti-K0 PHSP; +# 0.5000 anti-D0 K- PHSP; +1.000 D_s- pi0 PHSP; +Enddecay +Decay D'_s1+ +0.5000 D*+ K0 VVS_PWAVE 0.0 0.0 0.0 0.0 1.0 0.0; +0.5000 D*0 K+ VVS_PWAVE 0.0 0.0 0.0 0.0 1.0 0.0; +0.0000 gamma D_s*+ PHSP; +0.0000 gamma D_s+ PHSP; +Enddecay +Decay D'_s1- +0.5000 D*- anti-K0 VVS_PWAVE 0.0 0.0 0.0 0.0 1.0 0.0; +0.5000 anti-D*0 K- VVS_PWAVE 0.0 0.0 0.0 0.0 1.0 0.0; +0.0000 gamma D_s*- PHSP; +0.0000 gamma D_s- PHSP; +Enddecay +Decay D_s1+ +0.80000 D_s*+ pi0 PARTWAVE 1.0 0.0 0.0 0.0 0.0 0.0; +0.20000 D_s+ gamma VSP_PWAVE; +Enddecay +Decay D_s1- +0.80000 D_s*- pi0 PARTWAVE 1.0 0.0 0.0 0.0 0.0 0.0; +0.20000 D_s- gamma VSP_PWAVE; +Enddecay +Decay D_s2*+ +0.0500 D*+ K0 TVS_PWAVE 0.0 0.0 1.0 0.0 0.0 0.0; +0.0500 D*0 K+ TVS_PWAVE 0.0 0.0 1.0 0.0 0.0 0.0; +0.4300 D+ K0 TSS; +0.4700 D0 K+ TSS; +Enddecay +Decay D_s2*- +0.0500 D*- anti-K0 TVS_PWAVE 0.0 0.0 1.0 0.0 0.0 0.0; +0.0500 anti-D*0 K- TVS_PWAVE 0.0 0.0 1.0 0.0 0.0 0.0; +0.4300 D- anti-K0 TSS; +0.4700 anti-D0 K- TSS; +Enddecay +# +# +# Charm Mesons: Radially Excited States +# +Decay D(2S)0 +0.6667 D*+ pi- SVS; +0.3333 D*0 pi0 SVS; +Enddecay +Decay anti-D(2S)0 +0.3333 anti-D*0 pi0 SVS; +0.6667 D*- pi+ SVS; +Enddecay +Decay D(2S)+ +0.3333 D*+ pi0 SVS; +0.6667 D*0 pi+ SVS; +Enddecay +Decay D(2S)- +0.3333 D*- pi0 SVS; +0.6667 anti-D*0 pi- SVS; +Enddecay +Decay D*(2S)0 +0.3333 D*+ pi- VVS_PWAVE 1.0 0.0 0.0 0.0 0.0 0.0; +0.1667 D*0 pi0 VVS_PWAVE 1.0 0.0 0.0 0.0 0.0 0.0; +0.1667 D0 pi0 VSS; +0.3333 D+ pi- VSS; +Enddecay +Decay anti-D*(2S)0 +0.1667 anti-D*0 pi0 VVS_PWAVE 1.0 0.0 0.0 0.0 0.0 0.0; +0.3333 D*- pi+ VVS_PWAVE 1.0 0.0 0.0 0.0 0.0 0.0; +0.1667 anti-D0 pi0 VSS; +0.3333 D- pi+ VSS; +Enddecay +Decay D*(2S)+ +0.1667 D*+ pi0 VVS_PWAVE 1.0 0.0 0.0 0.0 0.0 0.0; +0.3333 D*0 pi+ VVS_PWAVE 1.0 0.0 0.0 0.0 0.0 0.0; +0.1667 D+ pi0 VSS; +0.3333 D0 pi+ VSS; +Enddecay +Decay D*(2S)- +0.1667 D*- pi0 VVS_PWAVE 1.0 0.0 0.0 0.0 0.0 0.0; +0.3333 anti-D*0 pi- VVS_PWAVE 1.0 0.0 0.0 0.0 0.0 0.0; +0.1667 D- pi0 VSS; +0.3333 anti-D0 pi- VSS; +Enddecay +# +# +# Strange Mesons updated to PDG 2008 +# +# +Decay K_S0 +0.691086452 pi+ pi- PHSP; #[Reconstructed PDG2011] +0.305986452 pi0 pi0 PHSP; #[Reconstructed PDG2011] +0.000000201 pi+ pi- pi0 PHSP; #[New mode added] #[Reconstructed PDG2011] +0.001722185 pi+ pi- gamma PHSP; #[New mode added] #[Reconstructed PDG2011] +0.000042831 pi+ pi- e+ e- PHSP; #[New mode added] #[Reconstructed PDG2011] +0.000000025 pi0 gamma gamma PHSP; #[New mode added] #[Reconstructed PDG2011] +0.000002399 gamma gamma PHSP; #[New mode added] #[Reconstructed PDG2011] +0.000344328 pi+ e- anti-nu_e PHSP; #[New mode added] #[Reconstructed PDG2011] +0.000344328 pi- e+ nu_e PHSP; #[New mode added] #[Reconstructed PDG2011] +0.000235400 pi+ mu- anti-nu_mu PHSP; #[New mode added] #TP manually added 9/1/2011 according to pdg +0.000235400 pi- mu+ nu_mu PHSP; #[New mode added] #TP manually added 9/1/2011 according to pdg +Enddecay +# +# K_L0 is decayed in GEANT +# +Decay K0 +0.500 K_L0 PHSP; +0.500 K_S0 PHSP; +Enddecay +Decay anti-K0 +0.500 K_L0 PHSP; +0.500 K_S0 PHSP; +Enddecay +# +Decay K*0 +0.6657 K+ pi- VSS; +0.3323 K0 pi0 VSS; +0.0020 K0 gamma VSP_PWAVE; +Enddecay +# +Decay anti-K*0 +0.6657 K- pi+ VSS; +0.3323 anti-K0 pi0 VSS; +0.0020 anti-K0 gamma VSP_PWAVE; +Enddecay +# +Decay K*+ +0.6657 K0 pi+ VSS; +0.3323 K+ pi0 VSS; +0.0020 K+ gamma VSP_PWAVE; +Enddecay +# +Decay K*- +0.6657 anti-K0 pi- VSS; +0.3323 K- pi0 VSS; +0.0020 K- gamma VSP_PWAVE; +Enddecay +# +# The decays below are for particle aliases and used when +# generating CP violating decays that depends on the decay +# of the neutral K* +# +Decay K*L +1.0000 pi0 K_L0 VSS; +Enddecay +Decay K*S +1.0000 pi0 K_S0 VSS; +Enddecay +Decay K*BL +1.0000 pi0 K_L0 VSS; +Enddecay +Decay K*BS +1.0000 pi0 K_S0 VSS; +Enddecay +Decay K*0T +1.0000 pi- K+ VSS; +Enddecay +Decay anti-K*0T +1.0000 pi+ K- VSS; +Enddecay +# +# +Decay K_0*+ +0.6667 K0 pi+ PHSP; +0.3333 K+ pi0 PHSP; +Enddecay +# +Decay K_0*- +0.6667 anti-K0 pi- PHSP; +0.3333 K- pi0 PHSP; +Enddecay +# +Decay K_0*0 +0.6667 K+ pi- PHSP; +0.3333 K0 pi0 PHSP; +Enddecay +# +Decay K_0*0N +1.0000 K0 pi0 PHSP; +Enddecay +# +Decay anti-K_0*0 +0.6667 K- pi+ PHSP; +0.3333 anti-K0 pi0 PHSP; +Enddecay +# +Decay anti-K_0*0N +1.0000 anti-K0 pi0 PHSP; +Enddecay +# +Decay K_10 +0.2800 rho- K+ VVS_PWAVE 1.0 0.0 0.0 0.0 0.0 0.0; +0.1400 rho0 K0 VVS_PWAVE 1.0 0.0 0.0 0.0 0.0 0.0; +0.1067 K*+ pi- VVS_PWAVE 1.0 0.0 0.0 0.0 0.0 0.0; +0.0533 K*0 pi0 VVS_PWAVE 1.0 0.0 0.0 0.0 0.0 0.0; +#To large masses can cause infinit loops +0.1100 omega K0 VVS_PWAVE 1.0 0.0 0.0 0.0 0.0 0.0; +0.1444 K0 pi+ pi- PHSP; +0.1244 K+ pi- pi0 PHSP; +0.0412 K0 pi0 pi0 PHSP; +Enddecay +# +Decay anti-K_10 +0.2800 rho+ K- VVS_PWAVE 1.0 0.0 0.0 0.0 0.0 0.0; +0.1400 rho0 anti-K0 VVS_PWAVE 1.0 0.0 0.0 0.0 0.0 0.0; +0.1067 K*- pi+ VVS_PWAVE 1.0 0.0 0.0 0.0 0.0 0.0; +0.0533 anti-K*0 pi0 VVS_PWAVE 1.0 0.0 0.0 0.0 0.0 0.0; +#To large masses can cause infinit loops +0.1100 omega anti-K0 VVS_PWAVE 1.0 0.0 0.0 0.0 0.0 0.0; +0.1444 anti-K0 pi+ pi- PHSP; +0.1244 K- pi+ pi0 PHSP; +0.0412 anti-K0 pi0 pi0 PHSP; +Enddecay +# +Decay K_1+ +0.2800 rho+ K0 VVS_PWAVE 1.0 0.0 0.0 0.0 0.0 0.0; +0.1400 rho0 K+ VVS_PWAVE 1.0 0.0 0.0 0.0 0.0 0.0; +0.1067 K*0 pi+ VVS_PWAVE 1.0 0.0 0.0 0.0 0.0 0.0; +0.0533 K*+ pi0 VVS_PWAVE 1.0 0.0 0.0 0.0 0.0 0.0; +#To large masses can cause infinit loops +0.1100 omega K+ VVS_PWAVE 1.0 0.0 0.0 0.0 0.0 0.0; +0.1444 K+ pi+ pi- PHSP; +0.1244 K0 pi+ pi0 PHSP; +0.0412 K+ pi0 pi0 PHSP; +Enddecay +# +Decay K_1- +0.2800 rho- anti-K0 VVS_PWAVE 1.0 0.0 0.0 0.0 0.0 0.0; +0.1400 rho0 K- VVS_PWAVE 1.0 0.0 0.0 0.0 0.0 0.0; +0.1067 anti-K*0 pi- VVS_PWAVE 1.0 0.0 0.0 0.0 0.0 0.0; +0.0533 K*- pi0 VVS_PWAVE 1.0 0.0 0.0 0.0 0.0 0.0; +#To large masses can cause infinit loops +0.1100 omega K- VVS_PWAVE 1.0 0.0 0.0 0.0 0.0 0.0; +0.1444 K- pi+ pi- PHSP; +0.1244 anti-K0 pi- pi0 PHSP; +0.0412 K- pi0 pi0 PHSP; +Enddecay +# +Decay K'_1+ +0.6300 K*0 pi+ VVS_PWAVE 1.0 0.0 0.0 0.0 0.0 0.0; +0.3100 K*+ pi0 VVS_PWAVE 1.0 0.0 0.0 0.0 0.0 0.0; +0.0200 rho+ K0 VVS_PWAVE 1.0 0.0 0.0 0.0 0.0 0.0; +0.0100 rho0 K+ VVS_PWAVE 1.0 0.0 0.0 0.0 0.0 0.0; +0.0100 omega K+ VVS_PWAVE 1.0 0.0 0.0 0.0 0.0 0.0; +0.0133 K+ pi+ pi- PHSP; +0.0067 K+ pi0 pi0 PHSP; +Enddecay +# +Decay K'_1- +0.6300 anti-K*0 pi- VVS_PWAVE 1.0 0.0 0.0 0.0 0.0 0.0; +0.3100 K*- pi0 VVS_PWAVE 1.0 0.0 0.0 0.0 0.0 0.0; +0.0200 rho- anti-K0 VVS_PWAVE 1.0 0.0 0.0 0.0 0.0 0.0; +0.0100 rho0 K- VVS_PWAVE 1.0 0.0 0.0 0.0 0.0 0.0; +0.0100 omega K- VVS_PWAVE 1.0 0.0 0.0 0.0 0.0 0.0; +0.0133 K- pi+ pi- PHSP; +0.0067 K- pi0 pi0 PHSP; +Enddecay +# +Decay K'_10 +0.6300 K*+ pi- VVS_PWAVE 1.0 0.0 0.0 0.0 0.0 0.0; +0.3100 K*0 pi0 VVS_PWAVE 1.0 0.0 0.0 0.0 0.0 0.0; +0.0200 rho- K+ VVS_PWAVE 1.0 0.0 0.0 0.0 0.0 0.0; +0.0100 rho0 K0 VVS_PWAVE 1.0 0.0 0.0 0.0 0.0 0.0; +0.0100 omega K0 VVS_PWAVE 1.0 0.0 0.0 0.0 0.0 0.0; +0.0133 K0 pi+ pi- PHSP; +0.0067 K0 pi0 pi0 PHSP; +Enddecay +# +Decay anti-K'_10 +0.6300 K*- pi+ VVS_PWAVE 1.0 0.0 0.0 0.0 0.0 0.0; +0.3100 anti-K*0 pi0 VVS_PWAVE 1.0 0.0 0.0 0.0 0.0 0.0; +0.0200 rho+ K- VVS_PWAVE 1.0 0.0 0.0 0.0 0.0 0.0; +0.0100 rho0 anti-K0 VVS_PWAVE 1.0 0.0 0.0 0.0 0.0 0.0; +0.0100 omega anti-K0 VVS_PWAVE 1.0 0.0 0.0 0.0 0.0 0.0; +0.0133 anti-K0 pi+ pi- PHSP; +0.0067 anti-K0 pi0 pi0 PHSP; +Enddecay +# +Decay K_2*+ +0.3340 K0 pi+ TSS; +0.1670 K+ pi0 TSS; +0.1645 K*0 pi+ TVS_PWAVE 0.0 0.0 1.0 0.0 0.0 0.0; +0.0835 K*+ pi0 TVS_PWAVE 0.0 0.0 1.0 0.0 0.0 0.0; +0.0450 K*0 pi+ pi0 PHSP; +0.0450 K*+ pi+ pi- PHSP; +0.0450 K*+ pi0 pi0 PHSP; +0.0580 rho+ K0 TVS_PWAVE 0.0 0.0 1.0 0.0 0.0 0.0; +0.0290 rho0 K+ TVS_PWAVE 0.0 0.0 1.0 0.0 0.0 0.0; +0.0290 omega K+ TVS_PWAVE 0.0 0.0 1.0 0.0 0.0 0.0; +Enddecay +# +Decay K_2*- +0.3340 anti-K0 pi- TSS; +0.1670 K- pi0 TSS; +0.1645 anti-K*0 pi- TVS_PWAVE 0.0 0.0 1.0 0.0 0.0 0.0; +0.0835 K*- pi0 TVS_PWAVE 0.0 0.0 1.0 0.0 0.0 0.0; +0.0450 anti-K*0 pi- pi0 PHSP; +0.0450 K*- pi+ pi- PHSP; +0.0450 K*- pi0 pi0 PHSP; +0.0580 rho- K0 TVS_PWAVE 0.0 0.0 1.0 0.0 0.0 0.0; +0.0290 rho0 K- TVS_PWAVE 0.0 0.0 1.0 0.0 0.0 0.0; +0.0290 omega K- TVS_PWAVE 0.0 0.0 1.0 0.0 0.0 0.0; +Enddecay +# +Decay K_2*0 +0.3340 K+ pi- TSS; +0.1670 K0 pi0 TSS; +0.1645 K*+ pi- TVS_PWAVE 0.0 0.0 1.0 0.0 0.0 0.0; +0.0835 K*0 pi0 TVS_PWAVE 0.0 0.0 1.0 0.0 0.0 0.0; +0.0450 K*0 pi+ pi- PHSP; +0.0450 K*0 pi0 pi0 PHSP; +0.0450 K*+ pi- pi0 PHSP; +0.0580 rho- K+ TVS_PWAVE 0.0 0.0 1.0 0.0 0.0 0.0; +0.0290 rho0 K0 TVS_PWAVE 0.0 0.0 1.0 0.0 0.0 0.0; +0.0290 omega K0 TVS_PWAVE 0.0 0.0 1.0 0.0 0.0 0.0; +Enddecay +# +Decay anti-K_2*0 +0.3340 K- pi+ TSS; +0.1670 anti-K0 pi0 TSS; +0.1645 K*- pi+ TVS_PWAVE 0.0 0.0 1.0 0.0 0.0 0.0; +0.0835 anti-K*0 pi0 TVS_PWAVE 0.0 0.0 1.0 0.0 0.0 0.0; +0.0450 anti-K*0 pi+ pi- PHSP; +0.0450 anti-K*0 pi0 pi0 PHSP; +0.0450 K*- pi+ pi0 PHSP; +0.0580 rho+ K- TVS_PWAVE 0.0 0.0 1.0 0.0 0.0 0.0; +0.0290 rho0 anti-K0 TVS_PWAVE 0.0 0.0 1.0 0.0 0.0 0.0; +0.0290 omega anti-K0 TVS_PWAVE 0.0 0.0 1.0 0.0 0.0 0.0; +Enddecay + + + + +# Decay K*(1410) +Decay K'*0 +0.0467 K+ pi- VSS; +0.0233 K0 pi0 VSS; +0.5760 K*+ pi- VVS_PWAVE 1.0 0.0 0.0 0.0 0.0 0.0; +0.2880 K*0 pi0 VVS_PWAVE 1.0 0.0 0.0 0.0 0.0 0.0; +0.0440 rho- K+ VVS_PWAVE 1.0 0.0 0.0 0.0 0.0 0.0; +0.0220 rho0 K0 VVS_PWAVE 1.0 0.0 0.0 0.0 0.0 0.0; +Enddecay +# +Decay anti-K'*0 +0.0467 K- pi+ VSS; +0.0233 anti-K0 pi0 VSS; +0.5760 K*- pi+ VVS_PWAVE 1.0 0.0 0.0 0.0 0.0 0.0; +0.2880 anti-K*0 pi0 VVS_PWAVE 1.0 0.0 0.0 0.0 0.0 0.0; +0.0440 rho+ K- VVS_PWAVE 1.0 0.0 0.0 0.0 0.0 0.0; +0.0220 rho0 anti-K0 VVS_PWAVE 1.0 0.0 0.0 0.0 0.0 0.0; +Enddecay +# +Decay K'*+ +0.0467 K0 pi+ VSS; +0.0233 K+ pi0 VSS; +0.5760 K*0 pi+ VVS_PWAVE 1.0 0.0 0.0 0.0 0.0 0.0; +0.2880 K*+ pi0 VVS_PWAVE 1.0 0.0 0.0 0.0 0.0 0.0; +0.0440 rho+ K0 VVS_PWAVE 1.0 0.0 0.0 0.0 0.0 0.0; +0.0220 rho0 K+ VVS_PWAVE 1.0 0.0 0.0 0.0 0.0 0.0; +Enddecay +# +Decay K'*- +0.0467 anti-K0 pi- VSS; +0.0233 K- pi0 VSS; +0.5760 anti-K*0 pi- VVS_PWAVE 1.0 0.0 0.0 0.0 0.0 0.0; +0.2880 K*- pi0 VVS_PWAVE 1.0 0.0 0.0 0.0 0.0 0.0; +0.0440 rho- K0 VVS_PWAVE 1.0 0.0 0.0 0.0 0.0 0.0; +0.0220 rho0 K- VVS_PWAVE 1.0 0.0 0.0 0.0 0.0 0.0; +Enddecay +# + + +# Decay K*(1680) +Decay K''*0 +0.2580 K+ pi- VSS; +0.1290 K0 pi0 VSS; +0.2093 K*+ pi- VVS_PWAVE 1.0 0.0 0.0 0.0 0.0 0.0; +0.1047 K*0 pi0 VVS_PWAVE 1.0 0.0 0.0 0.0 0.0 0.0; +0.1993 rho- K+ VVS_PWAVE 1.0 0.0 0.0 0.0 0.0 0.0; +0.0997 rho0 K0 VVS_PWAVE 1.0 0.0 0.0 0.0 0.0 0.0; +Enddecay +# +Decay anti-K''*0 +0.2580 K- pi+ VSS; +0.1290 anti-K0 pi0 VSS; +0.2093 K*- pi+ VVS_PWAVE 1.0 0.0 0.0 0.0 0.0 0.0; +0.1047 anti-K*0 pi0 VVS_PWAVE 1.0 0.0 0.0 0.0 0.0 0.0; +0.1993 rho+ K- VVS_PWAVE 1.0 0.0 0.0 0.0 0.0 0.0; +0.0997 rho0 anti-K0 VVS_PWAVE 1.0 0.0 0.0 0.0 0.0 0.0; +Enddecay +# +Decay K''*+ +0.2580 K0 pi+ VSS; +0.1290 K+ pi0 VSS; +0.2093 K*0 pi+ VVS_PWAVE 1.0 0.0 0.0 0.0 0.0 0.0; +0.1047 K*+ pi0 VVS_PWAVE 1.0 0.0 0.0 0.0 0.0 0.0; +0.1993 rho+ K0 VVS_PWAVE 1.0 0.0 0.0 0.0 0.0 0.0; +0.0997 rho0 K+ VVS_PWAVE 1.0 0.0 0.0 0.0 0.0 0.0; +Enddecay +# +Decay K''*- +0.2580 anti-K0 pi- VSS; +0.1290 K- pi0 VSS; +0.2093 anti-K*0 pi- VVS_PWAVE 1.0 0.0 0.0 0.0 0.0 0.0; +0.1047 K*- pi0 VVS_PWAVE 1.0 0.0 0.0 0.0 0.0 0.0; +0.1993 rho- K0 VVS_PWAVE 1.0 0.0 0.0 0.0 0.0 0.0; +0.0997 rho0 K- VVS_PWAVE 1.0 0.0 0.0 0.0 0.0 0.0; +Enddecay + +Decay Xsd +1.00000 d anti-s PYTHIA 42; +Enddecay + +Decay anti-Xsd +1.00000 anti-d s PYTHIA 42; +Enddecay + +Decay Xsu +1.00000 u anti-s PYTHIA 42; +Enddecay + +Decay anti-Xsu +1.00000 anti-u s PYTHIA 42; +Enddecay + +# Xss decays can be uncommented when Jst74/lucomp.F recognizes Xss +Decay Xss +1.00000 s anti-s PYTHIA 42; +Enddecay + +Decay anti-Xss +1.00000 anti-s s PYTHIA 42; +Enddecay + +# +# Light Mesons Updated to PDG 2008 +# +Decay pi0 +0.988228297 gamma gamma PHSP; #[Reconstructed PDG2011] +0.011738247 e+ e- gamma PI0_DALITZ; #[Reconstructed PDG2011] +0.000033392 e+ e+ e- e- PHSP; #[New mode added] #[Reconstructed PDG2011] +0.000000065 e+ e- PHSP; #[New mode added] #[Reconstructed PDG2011] +Enddecay +# +Decay eta +0.393100000 gamma gamma PHSP; #[Reconstructed PDG2011] +0.325700000 pi0 pi0 pi0 PHSP; #[Reconstructed PDG2011] +0.227400000 pi- pi+ pi0 ETA_DALITZ; #[Reconstructed PDG2011] +0.046000000 gamma pi- pi+ PHSP; #[Reconstructed PDG2011] +0.007000000 gamma e+ e- PHSP; #[Reconstructed PDG2011] +0.000310000 gamma mu+ mu- PHSP; #[Reconstructed PDG2011] +0.000270000 gamma gamma pi0 PHSP; #[Reconstructed PDG2011] +0.000214200 pi+ pi- e+ e- PHSP; #[Reconstructed PDG2011] +0.000005800 mu+ mu- PHSP; #[New mode added] #[Reconstructed PDG2011] +Enddecay +# +Decay rho0 +1.000 pi+ pi- VSS; +Enddecay +Decay rho+ +1.000 pi+ pi0 VSS; +Enddecay +Decay rho- +1.000 pi- pi0 VSS; +Enddecay +# +Decay omega +0.892000000 pi- pi+ pi0 OMEGA_DALITZ; #[Reconstructed PDG2011] +0.082800000 pi0 gamma VSP_PWAVE; #[Reconstructed PDG2011] +0.015300000 pi- pi+ VSS; #[Reconstructed PDG2011] +0.000460000 eta gamma VSP_PWAVE; #[Reconstructed PDG2011] +0.000770000 pi0 e+ e- PHOTOS PHSP; #[Reconstructed PDG2011] +0.000130000 pi0 mu+ mu- PHOTOS PHSP; #[Reconstructed PDG2011] +0.00150 pi+ pi- gamma PHSP; +0.000066000 pi0 pi0 gamma PHSP; #[Reconstructed PDG2011] +0.00050 pi+ pi- pi+ pi- PHSP; +0.000072800 e+ e- PHSP; #[New mode added] #[Reconstructed PDG2011] +0.000090000 mu+ mu- PHSP; #[New mode added] #[Reconstructed PDG2011] +Enddecay +# +Decay eta' +0.432000000 pi+ pi- eta PHSP; #[Reconstructed PDG2011] +0.217000000 pi0 pi0 eta PHSP; #[Reconstructed PDG2011] +0.293511000 rho0 gamma SVP_HELAMP 1.0 0.0 1.0 0.0; #[Reconstructed PDG2011] +0.027500000 omega gamma SVP_HELAMP 1.0 0.0 1.0 0.0; #[Reconstructed PDG2011] +0.022200000 gamma gamma PHSP; #[Reconstructed PDG2011] +0.001680000 pi0 pi0 pi0 PHSP; #[Reconstructed PDG2011] +0.000109000 gamma mu- mu+ PHOTOS PHSP; #[Reconstructed PDG2011] +0.003600000 pi+ pi- pi0 PHSP; #[New mode added] #[Reconstructed PDG2011] +0.002400000 pi+ pi- e+ e- PHSP; #[New mode added] #[Reconstructed PDG2011] +Enddecay +# +Decay phi +0.489000000 K+ K- VSS; #[Reconstructed PDG2011] +Enddecay +# +Decay a_1+ +0.4920 rho0 pi+ VVS_PWAVE 1.0 0.0 0.0 0.0 0.0 0.0; +0.5080 rho+ pi0 VVS_PWAVE 1.0 0.0 0.0 0.0 0.0 0.0; +Enddecay +Decay a_10 +0.5000 rho- pi+ VVS_PWAVE 1.0 0.0 0.0 0.0 0.0 0.0; +0.5000 rho+ pi- VVS_PWAVE 1.0 0.0 0.0 0.0 0.0 0.0; +Enddecay +Decay a_1- +0.4920 rho0 pi- VVS_PWAVE 1.0 0.0 0.0 0.0 0.0 0.0; +0.5080 rho- pi0 VVS_PWAVE 1.0 0.0 0.0 0.0 0.0 0.0; +Enddecay +# +Decay a_2+ +0.3500 rho0 pi+ TVS_PWAVE 0.0 0.0 1.0 0.0 0.0 0.0; +0.3500 rho+ pi0 TVS_PWAVE 0.0 0.0 1.0 0.0 0.0 0.0; +0.1430 eta pi+ TSS; +0.1000 omega pi+ pi0 PHSP; +0.0490 anti-K0 K+ TSS; +0.0027 pi+ gamma PHSP; +0.0053 eta' pi+ TSS; +Enddecay +# +Decay a_2- +0.3500 rho0 pi- TVS_PWAVE 0.0 0.0 1.0 0.0 0.0 0.0; +0.3500 rho- pi0 TVS_PWAVE 0.0 0.0 1.0 0.0 0.0 0.0; +0.1430 eta pi- TSS; +0.1000 omega pi- pi0 PHSP; +0.0490 anti-K0 K- TSS; +0.0027 pi- gamma PHSP; +0.0053 eta' pi- TSS; +Enddecay +# +Decay a_20 +0.3500 rho+ pi- TVS_PWAVE 0.0 0.0 1.0 0.0 0.0 0.0; +0.3500 rho- pi+ TVS_PWAVE 0.0 0.0 1.0 0.0 0.0 0.0; +0.1430 eta pi0 TSS; +0.1000 omega pi+ pi- PHSP; +0.0245 K+ K- TSS; +0.01225 K_L0 K_L0 TSS; +0.01225 K_S0 K_S0 TSS; +0.0027 pi0 gamma PHSP; +0.0053 eta' pi0 TSS; +Enddecay +# +Decay b_1+ +0.9984 omega pi+ VVS_PWAVE 1.0 0.0 0.0 0.0 0.0 0.0; +0.0016 pi+ gamma VSP_PWAVE; +Enddecay +Decay b_1- +0.9984 omega pi- VVS_PWAVE 1.0 0.0 0.0 0.0 0.0 0.0; +0.0016 pi- gamma VSP_PWAVE; +Enddecay +Decay b_10 +0.9984 omega pi0 VVS_PWAVE 1.0 0.0 0.0 0.0 0.0 0.0; +0.0016 pi0 gamma VSP_PWAVE; +Enddecay +# +Decay a_00 +0.9000 eta pi0 PHSP; +0.0500 K+ K- PHSP; +0.0250 K_S0 K_S0 PHSP; +0.0250 K_L0 K_L0 PHSP; +Enddecay +Decay a_0+ +0.9000 eta pi+ PHSP; +0.1000 anti-K0 K+ PHSP; +Enddecay +Decay a_0- +0.9000 eta pi- PHSP; +0.1000 K0 K- PHSP; +Enddecay +# +Decay f_0 +0.6667 pi+ pi- PHSP; +0.3333 pi0 pi0 PHSP; +#0.1100 K+ K- PHSP; +#0.0550 K_S0 K_S0 PHSP; +#0.0550 K_L0 K_L0 PHSP; +Enddecay +# +# +# MK: Based on PDG 2014 without any attempt to really include everything. One +# thing, which is missing is KK mode, but data are scattered quite lot and +# I would also need to find place where to make space for it. For needs I +# have at this moment, this should be sufficient +#Decay f_0(1370) +#0.17333 pi+ pi- PHSP; +#0.08667 pi0 pi0 PHSP; +#0.26000 pi+ pi+ pi- pi- PHSP; +#0.32000 pi+ pi- pi0 pi0 PHSP; +#0.10667 rho+ rho- PHSP; +#0.05333 rho0 rho0 PHSP; +#Enddecay +Decay f'_0 +0.5200 pi+ pi- PHSP; +0.2600 pi0 pi0 PHSP; +0.0750 pi+ pi+ pi- pi- PHSP; +0.0750 pi+ pi- pi0 pi0 PHSP; +0.0350 K+ K- PHSP; +0.0175 K_S0 K_S0 PHSP; +0.0175 K_L0 K_L0 PHSP; +Enddecay +# +Decay f_1 +0.110000000 rho0 pi+ pi- PHSP; #[Reconstructed PDG2011] +0.043364159 rho0 pi0 pi0 PHSP; #[Reconstructed PDG2011] +0.043442860 rho+ pi- pi0 PHSP; #[Reconstructed PDG2011] +0.043442860 rho- pi+ pi0 PHSP; #[Reconstructed PDG2011] +0.094440999 a_00 pi0 VSS; #[Reconstructed PDG2011] +0.094440999 a_0+ pi- VSS; #[Reconstructed PDG2011] +0.094440999 a_0- pi+ VSS; #[Reconstructed PDG2011] +0.086570916 eta pi+ pi- PHSP; #[Reconstructed PDG2011] +0.043285458 eta pi0 pi0 PHSP; #[Reconstructed PDG2011] +0.020226114 K+ K- pi0 PHSP; #[Reconstructed PDG2011] +0.010152407 K0 anti-K0 pi0 PHSP; #[Reconstructed PDG2011] +0.020226114 anti-K0 K+ pi- PHSP; #[Reconstructed PDG2011] +0.020226114 K0 K- pi+ PHSP; #[Reconstructed PDG2011] +0.055000000 gamma rho0 PHSP; #[Reconstructed PDG2011] +0.220000000 pi0 pi0 pi+ pi- PHSP; #[New mode added] #[Reconstructed PDG2011] +0.000000000 pi+ pi+ pi- pi- PHSP; #[New mode added] #[Reconstructed PDG2011] +0.000740000 phi gamma PHSP; #[New mode added] #[Reconstructed PDG2011] +Enddecay +# +Decay f'_1 +0.2500 K+ K- pi0 PHSP; +0.2500 K0 anti-K0 pi0 PHSP; +0.2500 anti-K0 K+ pi- PHSP; +0.2500 K0 K- pi+ PHSP; +Enddecay +# +Decay f_2 +0.5650 pi+ pi- TSS; +0.2820 pi0 pi0 TSS; +0.028000000 pi+ pi- pi+ pi- PHSP; #[Reconstructed PDG2011] +0.071000000 pi+ pi- pi0 pi0 PHSP; #[Reconstructed PDG2011] +0.003000000 pi0 pi0 pi0 pi0 PHSP; #[Reconstructed PDG2011] +0.0230 K+ K- TSS; +0.0115 K_S0 K_S0 TSS; +0.0115 K_L0 K_L0 TSS; +0.004000000 eta eta TSS; #[Reconstructed PDG2011] +0.000016400 gamma gamma PHSP; #[New mode added] #[Reconstructed PDG2011] +Enddecay +# +Decay f_0(1500) +0.019000000 eta eta' PHSP; #[Reconstructed PDG2011] +0.051000000 eta eta PHSP; #[Reconstructed PDG2011] +0.1410 pi0 pi0 pi0 pi0 PHSP; +0.3540 pi+ pi- pi+ pi- PHSP; +0.2330 pi+ pi- PHSP; +0.1160 pi0 pi0 PHSP; +0.0430 K+ K- PHSP; +0.0215 K_S0 K_S0 PHSP; +0.0215 K_L0 K_L0 PHSP; +Enddecay +# +Decay f'_2 +0.443904021 K+ K- TSS; #[Reconstructed PDG2011] +0.221952010 K_S0 K_S0 TSS; #[Reconstructed PDG2011] +0.221952010 K_L0 K_L0 TSS; #[Reconstructed PDG2011] +0.104000000 eta eta TSS; #[Reconstructed PDG2011] +0.005493862 pi+ pi- TSS; #[Reconstructed PDG2011] +0.002696987 pi0 pi0 TSS; #[Reconstructed PDG2011] +0.000001110 gamma gamma PHSP; #[New mode added] #[Reconstructed PDG2011] +Enddecay +# +Decay h_1 +0.3333 rho+ pi- VVS_PWAVE 1.0 0.0 0.0 0.0 0.0 0.0; +0.3333 rho- pi+ VVS_PWAVE 1.0 0.0 0.0 0.0 0.0 0.0; +0.3334 rho0 pi0 VVS_PWAVE 1.0 0.0 0.0 0.0 0.0 0.0; +Enddecay +# +Decay h'_1 +0.2500 K*+ K- VVS_PWAVE 1.0 0.0 0.0 0.0 0.0 0.0; +0.2500 K*- K+ VVS_PWAVE 1.0 0.0 0.0 0.0 0.0 0.0; +0.2500 anti-K*0 K0 VVS_PWAVE 1.0 0.0 0.0 0.0 0.0 0.0; +0.2500 K*0 anti-K0 VVS_PWAVE 1.0 0.0 0.0 0.0 0.0 0.0; +Enddecay +# +Decay rho(2S)+ +0.4000 pi+ pi0 PHSP; +0.4000 pi+ pi+ pi- pi0 PHSP; +0.2000 pi+ pi0 pi0 pi0 PHSP; +Enddecay +Decay rho(2S)- +0.4000 pi- pi0 PHSP; +0.4000 pi- pi+ pi- pi0 PHSP; +0.2000 pi- pi0 pi0 pi0 PHSP; +Enddecay +Decay rho(2S)0 +0.4000 pi+ pi- PHSP; +0.3500 pi+ pi- pi+ pi- PHSP; +0.1500 pi+ pi- pi0 pi0 PHSP; +0.1000 pi0 pi0 pi0 pi0 PHSP; +Enddecay +Decay phi(1680) +0.08 pi+ pi- PHSP; +0.05 pi+ pi+ pi- pi- PHSP; +0.10 pi0 pi+ pi- PHSP; +0.10 pi0 pi+ pi+ pi- pi- PHSP; +0.12 pi0 pi0 pi+ pi- PHSP; +0.04 pi0 pi+ pi+ pi+ pi- pi- pi- PHSP; +0.14 pi0 pi0 pi+ pi+ pi- pi- PHSP; +0.05 pi0 pi0 pi0 pi+ pi- PHSP; +0.06 pi0 pi0 pi0 pi+ pi+ pi- pi- PHSP; +0.03 pi0 pi0 pi0 pi+ pi+ pi+ pi- pi- pi- PHSP; +0.03 pi0 pi0 pi0 pi0 pi+ pi+ pi- pi- PHSP; +0.04 K+ K- pi+ pi- PHSP; +0.02 K0 K- pi+ PHSP; +0.02 anti-K0 K+ pi- PHSP; +0.02 K0 K- pi+ pi+ pi- PHSP; +0.02 anti-K0 K+ pi- pi- pi+ PHSP; +0.02 K0 K- pi0 pi+ PHSP; +0.02 anti-K0 K+ pi0 pi- PHSP; +0.02 eta pi0 pi+ pi- PHSP; +0.01 eta rho- pi0 pi+ PHSP; +0.01 eta rho+ pi0 pi- PHSP; +Enddecay +Decay rho(3S)0 +0.08 pi+ pi- PHSP; +0.05 pi+ pi+ pi- pi- PHSP; +0.10 pi0 pi+ pi- PHSP; +0.10 pi0 pi+ pi+ pi- pi- PHSP; +0.12 pi0 pi0 pi+ pi- PHSP; +0.04 pi0 pi+ pi+ pi+ pi- pi- pi- PHSP; +0.14 pi0 pi0 pi+ pi+ pi- pi- PHSP; +0.05 pi0 pi0 pi0 pi+ pi- PHSP; +0.06 pi0 pi0 pi0 pi+ pi+ pi- pi- PHSP; +0.03 pi0 pi0 pi0 pi+ pi+ pi+ pi- pi- pi- PHSP; +0.03 pi0 pi0 pi0 pi0 pi+ pi+ pi- pi- PHSP; +0.04 K+ K- pi+ pi- PHSP; +0.02 K0 K- pi+ PHSP; +0.02 anti-K0 K+ pi- PHSP; +0.02 K0 K- pi+ pi+ pi- PHSP; +0.02 anti-K0 K+ pi- pi- pi+ PHSP; +0.02 K0 K- pi0 pi+ PHSP; +0.02 anti-K0 K+ pi0 pi- PHSP; +0.02 eta pi0 pi+ pi- PHSP; +0.01 eta rho- pi0 pi+ PHSP; +0.01 eta rho+ pi0 pi- PHSP; +Enddecay +Decay omega(1650) +0.08 pi+ pi- PHSP; +0.05 pi+ pi+ pi- pi- PHSP; +0.10 pi0 pi+ pi- PHSP; +0.10 pi0 pi+ pi+ pi- pi- PHSP; +0.12 pi0 pi0 pi+ pi- PHSP; +0.04 pi0 pi+ pi+ pi+ pi- pi- pi- PHSP; +0.14 pi0 pi0 pi+ pi+ pi- pi- PHSP; +0.05 pi0 pi0 pi0 pi+ pi- PHSP; +0.06 pi0 pi0 pi0 pi+ pi+ pi- pi- PHSP; +0.03 pi0 pi0 pi0 pi+ pi+ pi+ pi- pi- pi- PHSP; +0.03 pi0 pi0 pi0 pi0 pi+ pi+ pi- pi- PHSP; +0.04 K+ K- pi+ pi- PHSP; +0.02 K0 K- pi+ PHSP; +0.02 anti-K0 K+ pi- PHSP; +0.02 K0 K- pi+ pi+ pi- PHSP; +0.02 anti-K0 K+ pi- pi- pi+ PHSP; +0.02 K0 K- pi0 pi+ PHSP; +0.02 anti-K0 K+ pi0 pi- PHSP; +0.02 eta pi0 pi+ pi- PHSP; +0.01 eta rho- pi0 pi+ PHSP; +0.01 eta rho+ pi0 pi- PHSP; +Enddecay +#Decay rho(1900) +#0.08 pi+ pi- PHSP; +#0.05 pi+ pi+ pi- pi- PHSP; +#0.10 pi0 pi+ pi- PHSP; +#0.10 pi0 pi+ pi+ pi- pi- PHSP; +#0.12 pi0 pi0 pi+ pi- PHSP; +#0.04 pi0 pi+ pi+ pi+ pi- pi- pi- PHSP; +#0.14 pi0 pi0 pi+ pi+ pi- pi- PHSP; +#0.05 pi0 pi0 pi0 pi+ pi- PHSP; +#0.06 pi0 pi0 pi0 pi+ pi+ pi- pi- PHSP; +#0.03 pi0 pi0 pi0 pi+ pi+ pi+ pi- pi- pi- PHSP; +#0.03 pi0 pi0 pi0 pi0 pi+ pi+ pi- pi- PHSP; +#0.04 K+ K- pi+ pi- PHSP; +#0.02 K0 K- pi+ PHSP; +#0.02 anti-K0 K+ pi- PHSP; +#0.02 K0 K- pi+ pi+ pi- PHSP; +#0.02 anti-K0 K+ pi- pi- pi+ PHSP; +#0.02 K0 K- pi0 pi+ PHSP; +#0.02 anti-K0 K+ pi0 pi- PHSP; +#0.02 eta pi0 pi+ pi- PHSP; +#0.01 eta rho- pi0 pi+ PHSP; +#0.01 eta rho+ pi0 pi- PHSP; +#Enddecay +Decay omega(2S) +0.08 pi+ pi- PHSP; +0.05 pi+ pi+ pi- pi- PHSP; +0.10 pi0 pi+ pi- PHSP; +0.10 pi0 pi+ pi+ pi- pi- PHSP; +0.12 pi0 pi0 pi+ pi- PHSP; +0.04 pi0 pi+ pi+ pi+ pi- pi- pi- PHSP; +0.14 pi0 pi0 pi+ pi+ pi- pi- PHSP; +0.05 pi0 pi0 pi0 pi+ pi- PHSP; +0.06 pi0 pi0 pi0 pi+ pi+ pi- pi- PHSP; +0.03 pi0 pi0 pi0 pi+ pi+ pi+ pi- pi- pi- PHSP; +0.03 pi0 pi0 pi0 pi0 pi+ pi+ pi- pi- PHSP; +0.04 K+ K- pi+ pi- PHSP; +0.02 K0 K- pi+ PHSP; +0.02 anti-K0 K+ pi- PHSP; +0.02 K0 K- pi+ pi+ pi- PHSP; +0.02 anti-K0 K+ pi- pi- pi+ PHSP; +0.02 K0 K- pi0 pi+ PHSP; +0.02 anti-K0 K+ pi0 pi- PHSP; +0.02 eta pi0 pi+ pi- PHSP; +0.01 eta rho- pi0 pi+ PHSP; +0.01 eta rho+ pi0 pi- PHSP; +Enddecay +#Decay rho(2150) +#0.08 pi+ pi- PHSP; +#0.05 pi+ pi+ pi- pi- PHSP; +#0.10 pi0 pi+ pi- PHSP; +#0.10 pi0 pi+ pi+ pi- pi- PHSP; +#0.12 pi0 pi0 pi+ pi- PHSP; +#0.04 pi0 pi+ pi+ pi+ pi- pi- pi- PHSP; +#0.14 pi0 pi0 pi+ pi+ pi- pi- PHSP; +#0.05 pi0 pi0 pi0 pi+ pi- PHSP; +#0.06 pi0 pi0 pi0 pi+ pi+ pi- pi- PHSP; +#0.03 pi0 pi0 pi0 pi+ pi+ pi+ pi- pi- pi- PHSP; +#0.03 pi0 pi0 pi0 pi0 pi+ pi+ pi- pi- PHSP; +#0.04 K+ K- pi+ pi- PHSP; +#0.02 K0 K- pi+ PHSP; +#0.02 anti-K0 K+ pi- PHSP; +#0.02 K0 K- pi+ pi+ pi- PHSP; +#0.02 anti-K0 K+ pi- pi- pi+ PHSP; +#0.02 K0 K- pi0 pi+ PHSP; +#0.02 anti-K0 K+ pi0 pi- PHSP; +#0.02 eta pi0 pi+ pi- PHSP; +#0.01 eta rho- pi0 pi+ PHSP; +#0.01 eta rho+ pi0 pi- PHSP; +#Enddecay +#Decay omega(1960) +#0.08 pi+ pi- PHSP; +#0.05 pi+ pi+ pi- pi- PHSP; +#0.10 pi0 pi+ pi- PHSP; +#0.10 pi0 pi+ pi+ pi- pi- PHSP; +#0.12 pi0 pi0 pi+ pi- PHSP; +#0.04 pi0 pi+ pi+ pi+ pi- pi- pi- PHSP; +#0.14 pi0 pi0 pi+ pi+ pi- pi- PHSP; +#0.05 pi0 pi0 pi0 pi+ pi- PHSP; +#0.06 pi0 pi0 pi0 pi+ pi+ pi- pi- PHSP; +#0.03 pi0 pi0 pi0 pi+ pi+ pi+ pi- pi- pi- PHSP; +#0.03 pi0 pi0 pi0 pi0 pi+ pi+ pi- pi- PHSP; +#0.04 K+ K- pi+ pi- PHSP; +#0.02 K0 K- pi+ PHSP; +#0.02 anti-K0 K+ pi- PHSP; +#0.02 K0 K- pi+ pi+ pi- PHSP; +#0.02 anti-K0 K+ pi- pi- pi+ PHSP; +#0.02 K0 K- pi0 pi+ PHSP; +#0.02 anti-K0 K+ pi0 pi- PHSP; +#0.02 eta pi0 pi+ pi- PHSP; +#0.01 eta rho- pi0 pi+ PHSP; +#0.01 eta rho+ pi0 pi- PHSP; +#Enddecay +#Decay rho(1965) +#0.08 pi+ pi- PHSP; +#0.05 pi+ pi+ pi- pi- PHSP; +#0.10 pi0 pi+ pi- PHSP; +#0.10 pi0 pi+ pi+ pi- pi- PHSP; +#0.12 pi0 pi0 pi+ pi- PHSP; +#0.04 pi0 pi+ pi+ pi+ pi- pi- pi- PHSP; +#0.14 pi0 pi0 pi+ pi+ pi- pi- PHSP; +#0.05 pi0 pi0 pi0 pi+ pi- PHSP; +#0.06 pi0 pi0 pi0 pi+ pi+ pi- pi- PHSP; +#0.03 pi0 pi0 pi0 pi+ pi+ pi+ pi- pi- pi- PHSP; +#0.03 pi0 pi0 pi0 pi0 pi+ pi+ pi- pi- PHSP; +#0.04 K+ K- pi+ pi- PHSP; +#0.02 K0 K- pi+ PHSP; +#0.02 anti-K0 K+ pi- PHSP; +#0.02 K0 K- pi+ pi+ pi- PHSP; +#0.02 anti-K0 K+ pi- pi- pi+ PHSP; +#0.02 K0 K- pi0 pi+ PHSP; +#0.02 anti-K0 K+ pi0 pi- PHSP; +#0.02 eta pi0 pi+ pi- PHSP; +#0.01 eta rho- pi0 pi+ PHSP; +#0.01 eta rho+ pi0 pi- PHSP; +#Enddecay +# +# +# cc= mesons Updated to PDG 2008 +# +Decay eta_c +0.001300000 p+ anti-p- PHSP; #[Reconstructed PDG2011] +0.002700000 phi phi SVV_HELAMP 1.0 0.0 0.0 0.0 -1.0 0.0; #[Reconstructed PDG2011] +0.002900000 phi K+ K- PHSP; #[Reconstructed PDG2011] +0.0067 rho0 rho0 SVV_HELAMP 1.0 0.0 0.0 0.0 -1.0 0.0; +0.0133 rho+ rho- SVV_HELAMP 1.0 0.0 0.0 0.0 -1.0 0.0; +0.012000000 pi+ pi- pi+ pi- PHSP; #[Reconstructed PDG2011] +0.001600000 K+ K- K+ K- PHSP; #[Reconstructed PDG2011] +0.015000000 K+ K- pi+ pi- PHSP; #[Reconstructed PDG2011] +0.0327 eta pi+ pi- PHSP; +0.0163 eta pi0 pi0 PHSP; +0.0273 eta' pi+ pi- PHSP; +0.0137 eta' pi0 pi0 PHSP; +0.0117 pi0 K+ K- PHSP; +0.0233 K+ anti-K0 pi- PHSP; +0.0233 K- K0 pi+ PHSP; +0.0117 K0 anti-K0 pi0 PHSP; +0.0046 K*+ K*- SVV_HELAMP 1.0 0.0 0.0 0.0 -1.0 0.0; +0.0046 K*0 anti-K*0 SVV_HELAMP 1.0 0.0 0.0 0.0 -1.0 0.0 ; +0.01 K*0 K- pi+ PHSP; +0.01 anti-K*0 K+ pi- PHSP; +# +#March 2009 New Modes +0.01500 K*0 anti-K*0 pi+ pi- PHSP; +0.007100000 K+ K- pi+ pi- pi+ pi- PHSP; #[Reconstructed PDG2011] +0.015000000 pi+ pi- pi+ pi- pi+ pi- PHSP; #[Reconstructed PDG2011] +0.001040000 Lambda0 anti-Lambda0 PHSP; #[Reconstructed PDG2011] +0.007600000 f_2 f_2 PHSP; #[Reconstructed PDG2011] +0.027000000 f_2 f'_2 PHSP; #[Reconstructed PDG2011] +# +0.682497000 rndmflav anti-rndmflav PYTHIA 42; +0.000063000 gamma gamma PHSP; #[New mode added] #[Reconstructed PDG2011] +Enddecay +# +Decay eta_c(2S) + 0.019 K+ anti-K0 pi- PHSP; + 0.019 K- K0 pi+ PHSP; + 0.0095 pi0 K+ K- PHSP; + 0.0095 K0 anti-K0 pi0 PHSP; +0.943 rndmflav anti-rndmflav PYTHIA 42; +Enddecay +# +Decay J/psi +0.3 e+ e- PHOTOS VLL; #[Reconstructed PDG2011] +0.7 mu+ mu- PHOTOS VLL; #[Reconstructed PDG2011] +Enddecay +# +Decay psi(2S) +0.336000000 J/psi pi+ pi- VVPIPI; #[Reconstructed PDG2011] +0.177300000 J/psi pi0 pi0 VVPIPI; #[Reconstructed PDG2011] +0.032800000 J/psi eta PARTWAVE 0.0 0.0 1.0 0.0 0.0 0.0; #[Reconstructed PDG2011] +0.001300000 J/psi pi0 PARTWAVE 0.0 0.0 1.0 0.0 0.0 0.0; #[Reconstructed PDG2011] +# below we also account for chi_c -> JPsi BR +0.00111592 gamma chi_c0 PHSP; #[Reconstructed PDG2011] +0.03164800 gamma chi_c1 PHSP; #[Reconstructed PDG2011] +0.01704300 gamma chi_c2 PHSP; #[Reconstructed PDG2011] +Enddecay + +Decay psi(4040) +0.000010700 e+ e- PHOTOS VLL; #[Reconstructed PDG2011] +0.000014000 mu+ mu- PHOTOS VLL; #[Reconstructed PDG2011] +0.000005000 tau+ tau- VLL; #[Reconstructed PDG2011] +0.002099938 D0 anti-D0 VSS; #[Reconstructed PDG2011] +0.000899973 D+ D- VSS; #[Reconstructed PDG2011] +0.167895013 D*0 anti-D0 VVS_PWAVE 1.0 0.0 0.0 0.0 0.0 0.0; #[Reconstructed PDG2011] +0.167895013 anti-D*0 D0 VVS_PWAVE 1.0 0.0 0.0 0.0 0.0 0.0; #[Reconstructed PDG2011] +0.181494610 D*+ D- VVS_PWAVE 1.0 0.0 0.0 0.0 0.0 0.0; #[Reconstructed PDG2011] +0.181494610 D*- D+ VVS_PWAVE 1.0 0.0 0.0 0.0 0.0 0.0; #[Reconstructed PDG2011] +0.159695257 D*0 anti-D*0 PHSP; #[Reconstructed PDG2011] +0.098197084 D*+ D*- PHSP; #[Reconstructed PDG2011] +0.000000000 D0 anti-D0 pi0 PHSP; #[Reconstructed PDG2011] +0.000000000 D+ D- pi0 PHSP; #[Reconstructed PDG2011] +0.000000000 D0 D- pi+ PHSP; #[Reconstructed PDG2011] +0.000000000 anti-D0 D+ pi- PHSP; #[Reconstructed PDG2011] +0.000000000 D*+ D- pi0 PHSP; #[Reconstructed PDG2011] +0.000000000 D*- D+ pi0 PHSP; #[Reconstructed PDG2011] +0.000000000 D*+ anti-D0 pi- PHSP; #[Reconstructed PDG2011] +0.000000000 D*- D0 pi+ PHSP; #[Reconstructed PDG2011] +0.000000000 D+ anti-D*0 pi- PHSP; #[Reconstructed PDG2011] +0.000000000 D- D*0 pi+ PHSP; #[Reconstructed PDG2011] +0.040298803 D_s+ D_s- VSS; #[Reconstructed PDG2011] +Enddecay +# +Decay psi(4160) +0.000008100 e+ e- PHOTOS VLL; #[Reconstructed PDG2011] +0.000009999 mu+ mu- PHOTOS VLL; #[Reconstructed PDG2011] +0.000006000 tau+ tau- VLL; #[Reconstructed PDG2011] +0.039697852 D0 anti-D0 VSS; #[Reconstructed PDG2011] +0.038697906 D+ D- VSS; #[Reconstructed PDG2011] +0.051997187 D*0 anti-D0 VVS_PWAVE 1.0 0.0 0.0 0.0 0.0 0.0; #[Reconstructed PDG2011] +0.051997187 anti-D*0 D0 VVS_PWAVE 1.0 0.0 0.0 0.0 0.0 0.0; #[Reconstructed PDG2011] +0.051497214 D*+ D- VVS_PWAVE 1.0 0.0 0.0 0.0 0.0 0.0; #[Reconstructed PDG2011] +0.051497214 D*- D+ VVS_PWAVE 1.0 0.0 0.0 0.0 0.0 0.0; #[Reconstructed PDG2011] +0.298613845 D*0 anti-D*0 PHSP; #[Reconstructed PDG2011] +0.308183327 D*+ D*- PHSP; #[Reconstructed PDG2011] +0.000000000 D0 anti-D0 pi0 PHSP; #[Reconstructed PDG2011] +0.000000000 D+ D- pi0 PHSP; #[Reconstructed PDG2011] +0.000000000 D0 D- pi+ PHSP; #[Reconstructed PDG2011] +0.000000000 anti-D0 D+ pi- PHSP; #[Reconstructed PDG2011] +0.000000000 D*+ D- pi0 PHSP; #[Reconstructed PDG2011] +0.000000000 D*- D+ pi0 PHSP; #[Reconstructed PDG2011] +0.000000000 D*+ anti-D0 pi- PHSP; #[Reconstructed PDG2011] +0.000000000 D*- D0 pi+ PHSP; #[Reconstructed PDG2011] +0.000000000 D+ anti-D*0 pi- PHSP; #[Reconstructed PDG2011] +0.000000000 D- D*0 pi+ PHSP; #[Reconstructed PDG2011] +0.009999459 D_s+ D_s- VSS; #[Reconstructed PDG2011] +0.048897355 D_s*+ D_s- VVS_PWAVE 1.0 0.0 0.0 0.0 0.0 0.0; #[Reconstructed PDG2011] +0.048897355 D_s*- D_s+ VVS_PWAVE 1.0 0.0 0.0 0.0 0.0 0.0; #[Reconstructed PDG2011] +0.000000000 D_s+ D_s- pi0 PHSP; #[Reconstructed PDG2011] +Enddecay +# +Decay psi(4415) +0.000009400 e+ e- PHOTOS VLL; #[Reconstructed PDG2011] +0.000011000 mu+ mu- PHOTOS VLL; #[Reconstructed PDG2011] +0.000007000 tau+ tau- VLL; #[Reconstructed PDG2011] +0.024399331 D0 anti-D0 VSS; #[Reconstructed PDG2011] +0.021899400 D+ D- VSS; #[Reconstructed PDG2011] +0.031999123 D*0 anti-D0 VVS_PWAVE 1.0 0.0 0.0 0.0 0.0 0.0; #[Reconstructed PDG2011] +0.031999123 anti-D*0 D0 VVS_PWAVE 1.0 0.0 0.0 0.0 0.0 0.0; #[Reconstructed PDG2011] +0.034299060 D*+ D- VVS_PWAVE 1.0 0.0 0.0 0.0 0.0 0.0; #[Reconstructed PDG2011] +0.034299060 D*- D+ VVS_PWAVE 1.0 0.0 0.0 0.0 0.0 0.0; #[Reconstructed PDG2011] +0.345090544 D*0 anti-D*0 PHSP; #[Reconstructed PDG2011] +0.353890303 D*+ D*- PHSP; #[Reconstructed PDG2011] +0.000000000 D0 anti-D0 pi0 PHSP; #[Reconstructed PDG2011] +0.000000000 D+ D- pi0 PHSP; #[Reconstructed PDG2011] +0.000000000 D0 D- pi+ PHSP; #[Reconstructed PDG2011] +0.000000000 anti-D0 D+ pi- PHSP; #[Reconstructed PDG2011] +0.000000000 D*+ D- pi0 PHSP; #[Reconstructed PDG2011] +0.000000000 D*- D+ pi0 PHSP; #[Reconstructed PDG2011] +0.000000000 D*+ anti-D0 pi- PHSP; #[Reconstructed PDG2011] +0.000000000 D*- D0 pi+ PHSP; #[Reconstructed PDG2011] +0.000000000 D+ anti-D*0 pi- PHSP; #[Reconstructed PDG2011] +0.000000000 D- D*0 pi+ PHSP; #[Reconstructed PDG2011] +0.011799677 D_s+ D_s- VSS; #[Reconstructed PDG2011] +0.041998849 D_s*+ D_s- VVS_PWAVE 1.0 0.0 0.0 0.0 0.0 0.0; #[Reconstructed PDG2011] +0.041998849 D_s*- D_s+ VVS_PWAVE 1.0 0.0 0.0 0.0 0.0 0.0; #[Reconstructed PDG2011] +0.026299279 D_s*+ D_s*- PHSP; #[Reconstructed PDG2011] +0.000000000 D_s+ D_s- pi0 PHSP; #[Reconstructed PDG2011] +0.000000000 D_s*+ D_s- pi0 PHSP; #[Reconstructed PDG2011] +0.000000000 D_s+ D_s*- pi0 PHSP; #[Reconstructed PDG2011] +0.000000000 D_s+ D- anti-K0 PHSP; #[Reconstructed PDG2011] +0.000000000 D_s- D+ anti-K0 PHSP; #[Reconstructed PDG2011] +0.000000000 D0 D_s- K+ PHSP; #[Reconstructed PDG2011] +0.000000000 anti-D0 D_s+ K- PHSP; #[Reconstructed PDG2011] +Enddecay +# +Decay chi_c0 +0.011600000 gamma J/psi PHSP; #[Reconstructed PDG2011] +Enddecay +# +Decay chi_c1 +0.344000000 J/psi gamma VVP 1.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0; #[Reconstructed PDG2011] +Enddecay +# +Decay chi_c2 +0.195000000 gamma J/psi PHSP; #[Reconstructed PDG2011] +Enddecay +# +Decay psi(3770) +0.410000000 D+ D- VSS; #[Reconstructed PDG2011] +0.520000000 D0 anti-D0 VSS; #[Reconstructed PDG2011] +0.001930000 J/psi pi+ pi- PHSP; #[Reconstructed PDG2011] +0.000800000 J/psi pi0 pi0 PHSP; #[Reconstructed PDG2011] +0.0073 gamma chi_c0 PHSP; +0.0029 gamma chi_c1 PHSP; +0.055850300 rndmflav anti-rndmflav PYTHIA 42; +0.000900000 J/psi eta PHSP; #[New mode added] #[Reconstructed PDG2011] +0.000009700 e+ e- PHSP; #[New mode added] #[Reconstructed PDG2011] +0.000310000 phi eta PHSP; #[New mode added] #[Reconstructed PDG2011] +Enddecay +# +Decay X_1(3872) +1.000 rndmflav anti-rndmflav PYTHIA 42; +Enddecay +# +# +# bb= Mesons Updated to PDG 2008 +# +Decay eta_b +1.000 rndmflav anti-rndmflav PYTHIA 42; +Enddecay +# +Decay Upsilon +0.024800000 e+ e- PHOTOS VLL; #[Reconstructed PDG2011] +0.024800000 mu+ mu- PHOTOS VLL; #[Reconstructed PDG2011] +0.026000000 tau+ tau- VLL; #[Reconstructed PDG2011] +0.014959973 d anti-d PYTHIA 91; +0.044879919 u anti-u PYTHIA 91; +0.014959973 s anti-s PYTHIA 91; +0.044879919 c anti-c PYTHIA 91; +0.774328202 g g g PYTHIA 92; +0.028922614 gamma g g PYTHIA 92; +0.000063000 gamma pi+ pi- PHSP; #[New mode added] #[Reconstructed PDG2011] +0.000017000 gamma pi0 pi0 PHSP; #[New mode added] #[Reconstructed PDG2011] +0.000011400 gamma K+ K- PHSP; #[New mode added] #[Reconstructed PDG2011] +0.000290000 gamma pi+ pi- K+ K- PHSP; #[New mode added] #[Reconstructed PDG2011] +0.000250000 gamma pi+ pi+ pi- pi- PHSP; #[New mode added] #[Reconstructed PDG2011] +0.000250000 gamma pi+ pi+ pi+ pi- pi- pi- PHSP; #[New mode added] #[Reconstructed PDG2011] +0.000240000 gamma pi+ pi+ pi- pi- K+ K- PHSP; #[New mode added] #[Reconstructed PDG2011] +0.000150000 gamma pi+ pi- p+ anti-p- PHSP; #[New mode added] #[Reconstructed PDG2011] +0.000040000 gamma pi+ pi+ pi- pi- p+ anti-p- PHSP; #[New mode added] #[Reconstructed PDG2011] +0.000020000 gamma K+ K+ K- K- PHSP; #[New mode added] #[Reconstructed PDG2011] +0.000037000 gamma f'_2 PHSP; #[New mode added] #[Reconstructed PDG2011] +0.000101000 gamma f_2 PHSP; #[New mode added] #[Reconstructed PDG2011] +Enddecay +# +Decay Upsilon(2S) +0.019100000 e+ e- PHOTOS VLL; #[Reconstructed PDG2011] +0.019300000 mu+ mu- PHOTOS VLL; #[Reconstructed PDG2011] +0.020000000 tau+ tau- VLL; #[Reconstructed PDG2011] +0.181000000 Upsilon pi+ pi- PHSP; #[Reconstructed PDG2011] +0.086000000 Upsilon pi0 pi0 PHSP; #[Reconstructed PDG2011] +# V-> gamma S Partial wave (L,S)=(0,1) +0.038000000 gamma chi_b0 HELAMP 1. 0. +1. 0.; #[Reconstructed PDG2011] +# V-> gamma V Partial wave (L,S)=(0,1) +0.069000000 gamma chi_b1 HELAMP 1. 0. 1. 0. -1. 0. -1. 0.; #[Reconstructed PDG2011] +# V-> gamma T Partial wave (L,S)=(0,1) +0.071500000 gamma chi_b2 HELAMP 2.4494897 0. 1.7320508 0. 1. 0. 1. 0. 1.7320508 0. 2.4494897 0.; #[Reconstructed PDG2011] +0.00500 d anti-d PYTHIA 91; +0.02000 u anti-u PYTHIA 91; +0.00500 s anti-s PYTHIA 91; +0.02000 c anti-c PYTHIA 91; +0.42160 g g g PYTHIA 92; +0.01600 gamma g g PYTHIA 92; +0.000210000 Upsilon eta PHSP; #[New mode added] #[Reconstructed PDG2011] +0.000390000 gamma eta_b PHSP; #[New mode added] #[Reconstructed PDG2011] +Enddecay +# +Decay Upsilon(3S) +0.0181 e+ e- PHOTOS VLL; +0.021800000 mu+ mu- PHOTOS VLL; #[Reconstructed PDG2011] +0.022900000 tau+ tau- VLL; #[Reconstructed PDG2011] +0.044000000 Upsilon pi+ pi- PHSP; #[Reconstructed PDG2011] +0.022000000 Upsilon pi0 pi0 PHSP; #[Reconstructed PDG2011] +0.024500000 Upsilon(2S) pi+ pi- PHSP; #[Reconstructed PDG2011] +0.018500000 Upsilon(2S) pi0 pi0 PHSP; #[Reconstructed PDG2011] +0.050000000 Upsilon(2S) gamma gamma PHSP; #[Reconstructed PDG2011] +# V-> gamma S Partial wave (L,S)=(0,1) +0.059000000 gamma chi_b0(2P) HELAMP 1. 0. 1. 0.; #[Reconstructed PDG2011] +# V-> gamma V Partial wave (L,S)=(0,1) +0.126000000 gamma chi_b1(2P) HELAMP 1. 0. 1. 0. -1. 0. -1. 0.; #[Reconstructed PDG2011] +# V-> gamma T Partial wave (L,S)=(0,1) +0.131000000 gamma chi_b2(2P) HELAMP 2.4494897 0. 1.7320508 0. 1. 0. 1. 0. 1.7320508 0. 2.4494897 0.; #[Reconstructed PDG2011] +0.00700 d anti-d PYTHIA 91; +0.02800 u anti-u PYTHIA 91; +0.00700 s anti-s PYTHIA 91; +0.02800 c anti-c PYTHIA 91; +0.37780 g g g PYTHIA 92; +0.01000 gamma g g PYTHIA 92; +0.003000000 gamma chi_b0 PHSP; #[New mode added] #[Reconstructed PDG2011] +0.000510000 gamma eta_b PHSP; #[New mode added] #[Reconstructed PDG2011] +Enddecay +# + +Decay Upsilon(5S) +0.5 B+ B- PHSP; +0.481487200 g g g PYTHIA 92; +0.000002800 e+ e- PHSP; #[New mode added] #[Reconstructed PDG2011] +0.005300000 Upsilon pi+ pi- PHSP; #[New mode added] #[Reconstructed PDG2011] +0.007800000 Upsilon(2S) pi+ pi- PHSP; #[New mode added] #[Reconstructed PDG2011] +0.004800000 Upsilon(3S) pi+ pi- PHSP; #[New mode added] #[Reconstructed PDG2011] +0.000610000 Upsilon K+ K- PHSP; #[New mode added] #[Reconstructed PDG2011] +Enddecay + +Decay chi_b0 +# S-> gamma V Partial wave (L,S)=(0,0) +0.0500 gamma Upsilon HELAMP 1. 0. 1. 0.; +0.949650000 rndmflav anti-rndmflav PYTHIA 42; +0.000110000 pi+ pi+ pi- pi- K+ K- PHSP; #[New mode added] #[Reconstructed PDG2011] +0.000240000 pi+ pi+ pi+ pi- pi- pi- K+ K- PHSP; #[New mode added] #[Reconstructed PDG2011] +Enddecay +# +Decay chi_b1 +# V-> gamma V Partial wave (L,S)=(0,1) +0.350000000 gamma Upsilon HELAMP 1. 0. 1. 0. -1. 0. -1. 0.; #[Reconstructed PDG2011] +0.643080000 g g PYTHIA 91; +0.000200000 pi+ pi- K+ K- pi0 PHSP; #[New mode added] #[Reconstructed PDG2011] +0.000800000 pi+ pi+ pi- pi- pi0 pi0 PHSP; #[New mode added] #[Reconstructed PDG2011] +0.000150000 pi+ pi+ pi- pi- K+ K- PHSP; #[New mode added] #[Reconstructed PDG2011] +0.000350000 pi+ pi+ pi- pi- K+ K- pi0 PHSP; #[New mode added] #[Reconstructed PDG2011] +0.000860000 pi+ pi+ pi- pi- K+ K- pi0 pi0 PHSP; #[New mode added] #[Reconstructed PDG2011] +0.000190000 pi+ pi+ pi+ pi- pi- pi- PHSP; #[New mode added] #[Reconstructed PDG2011] +0.001700000 pi+ pi+ pi+ pi- pi- pi- pi0 pi0 PHSP; #[New mode added] #[Reconstructed PDG2011] +0.000260000 pi+ pi+ pi+ pi- pi- pi- K+ K- PHSP; #[New mode added] #[Reconstructed PDG2011] +0.000750000 pi+ pi+ pi+ pi- pi- pi- K+ K- pi0 PHSP; #[New mode added] #[Reconstructed PDG2011] +0.000260000 pi+ pi+ pi+ pi+ pi- pi- pi- pi- PHSP; #[New mode added] #[Reconstructed PDG2011] +0.001400000 pi+ pi+ pi+ pi+ pi- pi- pi- pi- pi0 pi0 PHSP; #[New mode added] #[Reconstructed PDG2011] +Enddecay +# +Decay chi_b2 +# T-> gamma V Partial wave (L,S)=(0,2) Use PHSP. +0.220000000 gamma Upsilon PHSP; #[Reconstructed PDG2011] +#0.2200 gamma Upsilon HELAMP 1. 0. 1.7320508 0. 2.4494897 0. +# 2.4494897 0. 1.7320508 0. 1. 0.; +0.775550000 g g PYTHIA 91; +0.000080000 pi+ pi- K+ K- pi0 PHSP; #[New mode added] #[Reconstructed PDG2011] +0.000350000 pi+ pi+ pi- pi- pi0 pi0 PHSP; #[New mode added] #[Reconstructed PDG2011] +0.000110000 pi+ pi+ pi- pi- K+ K- PHSP; #[New mode added] #[Reconstructed PDG2011] +0.000210000 pi+ pi+ pi- pi- K+ K- pi0 PHSP; #[New mode added] #[Reconstructed PDG2011] +0.000390000 pi+ pi+ pi- pi- K+ K- pi0 pi0 PHSP; #[New mode added] #[Reconstructed PDG2011] +0.000070000 pi+ pi+ pi+ pi- pi- pi- PHSP; #[New mode added] #[Reconstructed PDG2011] +0.001000000 pi+ pi+ pi+ pi- pi- pi- pi0 pi0 PHSP; #[New mode added] #[Reconstructed PDG2011] +0.000360000 pi+ pi+ pi+ pi- pi- pi- K+ K- pi0 PHSP; #[New mode added] #[Reconstructed PDG2011] +0.000080000 pi+ pi+ pi+ pi+ pi- pi- pi- pi- PHSP; #[New mode added] #[Reconstructed PDG2011] +0.001800000 pi+ pi+ pi+ pi+ pi- pi- pi- pi- pi0 pi0 PHSP; #[New mode added] #[Reconstructed PDG2011] +Enddecay +# +Decay chi_b0(2P) +# S-> gamma V Partial wave (L,S)=(0,0) +0.009000000 gamma Upsilon HELAMP 1. 0. 1. 0.; #[Reconstructed PDG2011] +0.046000000 gamma Upsilon(2S) HELAMP 1. 0. 1. 0.; #[Reconstructed PDG2011] +# S-> gamma V Partial wave (L,S)=(0,0) +0.00150 gamma Upsilon_1(1D) HELAMP 1. 0. 1. 0.; +0.94350 g g PYTHIA 91; +Enddecay +# +Decay chi_b1(2P) +# V-> gamma V Partial wave (L,S)=(0,1) +0.085000000 gamma Upsilon HELAMP 1. 0. 1. 0. -1. 0. -1. 0.; #[Reconstructed PDG2011] +0.210000000 gamma Upsilon(2S) HELAMP 1. 0. 1. 0. -1. 0. -1. 0.; #[Reconstructed PDG2011] +# V-> gamma V Partial wave (L,S)=(0,1) +0.0097 gamma Upsilon_1(1D) HELAMP 1. 0. 1. 0. -1. 0. -1. 0.; +# V-> gamma T Partial wave (L,S)=(0,1) +0.0236 gamma Upsilon_2(1D) HELAMP 2.4494897 0. 1.7320508 0. 1. 0. 1. 0. 1.7320508 0. 2.4494897 0.; +0.648650000 g g PYTHIA 91; +0.016300000 omega Upsilon PHSP; #[New mode added] #[Reconstructed PDG2011] +0.000310000 pi+ pi- K+ K- pi0 PHSP; #[New mode added] #[Reconstructed PDG2011] +0.000590000 pi+ pi+ pi- pi- pi0 pi0 PHSP; #[New mode added] #[Reconstructed PDG2011] +0.000100000 pi+ pi+ pi- pi- K+ K- PHSP; #[New mode added] #[Reconstructed PDG2011] +0.000550000 pi+ pi+ pi- pi- K+ K- pi0 PHSP; #[New mode added] #[Reconstructed PDG2011] +0.001000000 pi+ pi+ pi- pi- K+ K- pi0 pi0 PHSP; #[New mode added] #[Reconstructed PDG2011] +0.000120000 pi+ pi+ pi+ pi- pi- pi- PHSP; #[New mode added] #[Reconstructed PDG2011] +0.001200000 pi+ pi+ pi+ pi- pi- pi- pi0 pi0 PHSP; #[New mode added] #[Reconstructed PDG2011] +0.000200000 pi+ pi+ pi+ pi- pi- pi- K+ K- PHSP; #[New mode added] #[Reconstructed PDG2011] +0.000610000 pi+ pi+ pi+ pi- pi- pi- K+ K- pi0 PHSP; #[New mode added] #[Reconstructed PDG2011] +0.000170000 pi+ pi+ pi+ pi+ pi- pi- pi- pi- PHSP; #[New mode added] #[Reconstructed PDG2011] +0.001900000 pi+ pi+ pi+ pi+ pi- pi- pi- pi- pi0 pi0 PHSP; #[New mode added] #[Reconstructed PDG2011] +Enddecay +# +Decay chi_b2(2P) +# T-> gamma V Partial wave (L,S)=(0,2) Use PHSP. +0.071000000 gamma Upsilon PHSP; #[Reconstructed PDG2011] +#0.0710 gamma Upsilon HELAMP 1. 0. 1.7320508 0. 2.4494897 0. +# 2.4494897 0. 1.7320508 0. 1. 0.; +0.162000000 gamma Upsilon(2S) PHSP; #[Reconstructed PDG2011] +#0.1620 gamma Upsilon(2S) HELAMP 1. 0. 1.7320508 0. 2.4494897 0. +# 2.4494897 0. 1.7320508 0. 1. 0.; +# T-> gamma V Partial wave (L,S)=(0,2) Use PHSP. +0.00023 gamma Upsilon_1(1D) PHSP; +#0.00023 gamma Upsilon_1(1D) HELAMP 1. 0. 1.7320508 0. 2.4494897 0. +# 2.4494897 0. 1.7320508 0. 1. 0.; +# T -> gamma T Partial wave (L,S)=(0,2) +0.00290 gamma Upsilon_2(1D) PHSP; +#0.00290 gamma Upsilon_2(1D) HELAMP -1. 0. -1.2247449 0. +# -1.2247449 0. -1. 0. +# 1. 0. 1.2247449 0. +# 1.2247449 0. 1. 0.; +# spin 3 not yet in HELAMP. +0.01420 gamma Upsilon_3(1D) PYTHIA 0; +# T-> gamma 3 Partial wave (L,S)=(0,2) +#0.01420 gamma Upsilon_3(1D) HELAMP 3.8729833 0. 3.1622777 0. +# 2.4494897 0. 1.7320508. 0. 1. 0. +# 1. 0. 1.7320508 0. 2.4494897 0. +# 3.1622777 0. 3.8729833 0.; +0.734240000 g g PYTHIA 91; +0.011000000 omega Upsilon PHSP; #[New mode added] #[Reconstructed PDG2011] +0.000390000 pi+ pi+ pi- pi- pi0 pi0 PHSP; #[New mode added] #[Reconstructed PDG2011] +0.000090000 pi+ pi+ pi- pi- K+ K- PHSP; #[New mode added] #[Reconstructed PDG2011] +0.000240000 pi+ pi+ pi- pi- K+ K- pi0 PHSP; #[New mode added] #[Reconstructed PDG2011] +0.000470000 pi+ pi+ pi- pi- K+ K- pi0 pi0 PHSP; #[New mode added] #[Reconstructed PDG2011] +0.000090000 pi+ pi+ pi+ pi- pi- pi- PHSP; #[New mode added] #[Reconstructed PDG2011] +0.001200000 pi+ pi+ pi+ pi- pi- pi- pi0 pi0 PHSP; #[New mode added] #[Reconstructed PDG2011] +0.000140000 pi+ pi+ pi+ pi- pi- pi- K+ K- PHSP; #[New mode added] #[Reconstructed PDG2011] +0.000420000 pi+ pi+ pi+ pi- pi- pi- K+ K- pi0 PHSP; #[New mode added] #[Reconstructed PDG2011] +0.000090000 pi+ pi+ pi+ pi+ pi- pi- pi- pi- PHSP; #[New mode added] #[Reconstructed PDG2011] +0.001300000 pi+ pi+ pi+ pi+ pi- pi- pi- pi- pi0 pi0 PHSP; #[New mode added] #[Reconstructed PDG2011] +Enddecay +# +Decay h_b +1.00000 g g PYTHIA 91; +Enddecay + +Decay chi_b0(3P) +#see Kwong and Rosner, PRD 38,279 (1988) +# S-> gamma V Partial wave (L,S)=(0,0) +0.01700 gamma Upsilon(3S) HELAMP 1. 0. 1. 0.; +# S-> gamma V Partial wave (L,S)=(0,0) +0.00400 gamma Upsilon_1(2D) HELAMP 1. 0. 1. 0.; +0.97900 g g PYTHIA 91; +Enddecay + +Decay chi_b1(3P) +#see Kwong and Rosner, PRD 38,279 (1988) +# V-> gamma V Partial wave (L,S)=(0,1) +0.15000 gamma Upsilon(3S) HELAMP 1. 0. 1. 0. -1. 0. -1. 0.; +# V-> gamma T Partial wave (L,S)=(0,1) +0.03100 gamma Upsilon_2(2D) HELAMP 2.4494897 0. 1.7320508 0. 1. 0. 1. 0. 1.7320508 0. 2.4494897 0.; +# V-> gamma V Partial wave (L,S)=(0,1) +0.01300 gamma Upsilon_1(2D) HELAMP 1. 0. 1. 0. -1. 0. -1. 0.; +0.80600 g g PYTHIA 91; +Enddecay + +Decay chi_b2(3P) +#see Kwong and Rosner, PRD 38,279 (1988) +# T-> gamma V Partial wave (L,S)=(0,2) Use PHSP. +0.08700 gamma Upsilon(3S) PHSP; +0.00000 gamma Upsilon(2S) PHSP; +0.00000 gamma Upsilon PHSP; +#0.08700 gamma Upsilon(3S) HELAMP 1. 0. 1.7320508 0. 2.4494897 0. +# 2.4494897 0. 1.7320508 0. 1. 0.; +#0.00000 gamma Upsilon(2S) HELAMP 1. 0. 1.7320508 0. 2.4494897 0. +# 2.4494897 0. 1.7320508 0. 1. 0.; +#0.00000 gamma Upsilon HELAMP 1. 0. 1.7320508 0. 2.4494897 0. +# 2.4494897 0. 1.7320508 0. 1. 0.; +# spin 3 not yet in HELAMP +0.02200 Upsilon_3(2D) gamma PHSP; +# T -> gamma 3 Partial wave (L,S)=(0,2) +#0.02200 gamma Upsilon_3(2D) HELAMP 3.8729833 0. 3.1622777 0. +# 2.4494897 0. 1.7320508. 0. 1. 0. +# 1. 0. 1.7320508 0. 2.4494897 0. +# 3.1622777 0. 3.8729833 0.; +# T -> gamma T Partial wave (L,S)=(0,2) +0.00400 gamma Upsilon_2(2D) PHSP; +#0.00400 gamma Upsilon_2(2D) HELAMP -1. 0. -1.2247449 0. +# -1.2247449 0. -1. 0. +# 1. 0. 1.2247449 0. +# 1.2247449 0. 1. 0.; +# T-> gamma V Partial wave (L,S)=(0,2) +0.00040 gamma Upsilon_1(2D) PHSP; +#0.00040 gamma Upsilon_1(2D) HELAMP 1. 0. 1.7320508 0. 2.4494897 0. +# 2.4494897 0. 1.7320508 0. 1. 0.; +0.88660 g g PYTHIA 91; +Enddecay + +Decay Upsilon_1(1D) +#see Kwong and Rosner, PRD 38,279 (1988) +0.00140 Upsilon pi+ pi- PHSP; +0.00070 Upsilon pi0 pi0 PHSP; +# V-> gamma S Partial wave (L,S)=(0,1) +0.60200 gamma chi_b0 HELAMP 1. 0. +1. 0.; +# V-> gamma V Partial wave (L,S)=(0,1) +0.31800 gamma chi_b1 HELAMP 1. 0. 1. 0. -1. 0. -1. 0.; +# V-> gamma T Partial wave (L,S)=(0,1) +0.02600 gamma chi_b2 HELAMP 2.4494897 0. 1.7320508 0. 1. 0. 1. 0. 1.7320508 0. 2.4494897 0.; +0.05190 g g g PYTHIA 92; +Enddecay + +Decay Upsilon_2(1D) +#see Kwong and Rosner, PRD 38,279 (1988) +0.00140 Upsilon pi+ pi- PHSP; +0.00070 Upsilon pi0 pi0 PHSP; +# T-> gamma T Partial wave (L,S)=(0,2) +0.20300 gamma chi_b2 PHSP; +#0.20300 gamma chi_b2 HELAMP -1. 0. -1.2247449 0. +# -1.2247449 0. -1. 0. +# 1. 0. 1.2247449 0. +# 1.2247449 0. 1. 0.; +# T-> gamma V Partial wave (L,S)=(0,2) Use PHSP. +0.78500 gamma chi_b1 PHSP; +#0.78500 gamma chi_b1 HELAMP 1. 0. 1.7320508 0. 2.4494897 0. +# 2.4494897 0. 1.7320508 0. 1. 0.; +0.00990 g g g PYTHIA 92; +Enddecay + +Decay Upsilon_3(1D) +#see Kwong and Rosner, PRD 38,279 (1988) +0.00200 Upsilon pi+ pi- PHSP; +0.00100 Upsilon pi0 pi0 PHSP; +0.95400 chi_b2 gamma PHSP; +0.04300 g g g PYTHIA 92; +Enddecay + +Decay Upsilon_1(2D) +#see Kwong and Rosner, PRD 38,279 (1988) +0.00000 Upsilon pi+ pi- PHSP; +0.00000 Upsilon pi0 pi0 PHSP; +0.00000 Upsilon(2S) pi+ pi- PHSP; +0.00000 Upsilon(2S) pi0 pi0 PHSP; +# V-> gamma S Partial wave (L,S)=(0,1) +0.51000 gamma chi_b0(2P) HELAMP 1. 0. +1. 0.; +# V-> gamma V Partial wave (L,S)=(0,1) +0.26000 gamma chi_b1(2P) HELAMP 1. 0. 1. 0. -1. 0. -1. 0.; +# V-> gamma T Partial wave (L,S)=(0,1) +0.01400 gamma chi_b2(2P) HELAMP 2.4494897 0. 1.7320508 0. 1. 0. 1. 0. 1.7320508 0. 2.4494897 0.; +0.21600 g g g PYTHIA 92; +Enddecay + +Decay Upsilon_2(2D) +#see Kwong and Rosner, PRD 38,279 (1988) +0.00000 Upsilon pi+ pi- PHSP; +0.00000 Upsilon pi0 pi0 PHSP; +0.00000 Upsilon(2S) pi+ pi- PHSP; +0.00000 Upsilon(2S) pi0 pi0 PHSP; +# T-> gamma T Partial wave (L,S)=(0,2) +0.04000 gamma chi_b2(2P) PHSP; +#0.04000 gamma chi_b2(2P) HELAMP -1. 0. -1.2247449 0. +# -1.2247449 0. -1. 0. +# 1. 0. 1.2247449 0. +# 1.2247449 0. 1. 0.; +# T-> gamma V Partial wave (L,S)=(0,2) Use PHSP. +0.13000 gamma chi_b1(2P) PHSP; +#0.13000 gamma chi_b1(2P) HELAMP 1. 0. 1.7320508 0. 2.4494897 0. +# 2.4494897 0. 1.7320508 0. 1. 0.; +0.83000 g g g PYTHIA 92; +Enddecay + +Decay Upsilon_3(2D) +#see Kwong and Rosner, PRD 38,279 (1988) +0.00000 Upsilon pi+ pi- PHSP; +0.00000 Upsilon pi0 pi0 PHSP; +0.00000 Upsilon(2S) pi+ pi- PHSP; +0.00000 Upsilon(2S) pi0 pi0 PHSP; +0.72000 chi_b2(2P) gamma PHSP; +0.28000 g g g PYTHIA 92; +Enddecay + +Decay h_b(2P) +1.00000 g g PYTHIA 91; +Enddecay +Decay h_b(3P) +1.00000 g g PYTHIA 91; +Enddecay +Decay eta_b2(1D) +1.00000 g g PYTHIA 91; +Enddecay +Decay eta_b2(2D) +1.00000 g g PYTHIA 91; +Enddecay +# +# Charm Baryons +# +Decay Lambda_c+ +0.021000000 e+ nu_e Lambda0 PYTHIA 22; +0.00500 e+ nu_e Sigma0 PYTHIA 22; +0.00500 e+ nu_e Sigma*0 PYTHIA 22; +0.00300 e+ nu_e n0 PYTHIA 22; +0.00200 e+ nu_e Delta0 PYTHIA 22; +0.00600 e+ nu_e p+ pi- PYTHIA 22; +0.00600 e+ nu_e n0 pi0 PYTHIA 22; +0.020000000 mu+ nu_mu Lambda0 PYTHIA 22; +0.00500 mu+ nu_mu Sigma0 PYTHIA 22; +0.00500 mu+ nu_mu Sigma*0 PYTHIA 22; +0.00300 mu+ nu_mu n0 PYTHIA 22; +0.00200 mu+ nu_mu Delta0 PYTHIA 22; +0.00600 mu+ nu_mu p+ pi- PYTHIA 22; +0.00600 mu+ nu_mu n0 pi0 PYTHIA 22; +0.008600000 Delta++ K- PYTHIA 0; +0.02500 Delta++ K*- PYTHIA 0; +0.023000000 p+ anti-K0 PYTHIA 0; +0.016000000 p+ anti-K*0 PYTHIA 0; +0.00500 Delta+ anti-K0 PYTHIA 0; +0.00500 Delta+ anti-K*0 PYTHIA 0; +0.010700000 Lambda0 pi+ PYTHIA 0; +0.00500 Lambda0 rho+ PYTHIA 0; +0.010500000 Sigma0 pi+ PYTHIA 0; +0.00400 Sigma0 rho+ PYTHIA 0; +0.00400 Sigma*0 pi+ PYTHIA 0; +0.00400 Sigma*0 rho+ PYTHIA 0; +0.010000000 Sigma+ pi0 PYTHIA 0; +0.005500000 Sigma+ eta PYTHIA 0; +0.00200 Sigma+ eta' PYTHIA 0; +0.00400 Sigma+ rho0 PYTHIA 0; +0.027000000 Sigma+ omega PYTHIA 0; +0.00300 Sigma*+ pi0 PYTHIA 0; +0.008500000 Sigma*+ eta PYTHIA 0; +0.00300 Sigma*+ rho0 PYTHIA 0; +0.00300 Sigma*+ omega PYTHIA 0; +0.003900000 Xi0 K+ PYTHIA 0; +0.00200 Xi0 K*+ PYTHIA 0; +0.002600000 Xi*0 K+ PYTHIA 0; +0.00100 Delta++ pi- PYTHIA 0; +0.00100 Delta++ rho- PYTHIA 0; +0.00200 p+ pi0 PYTHIA 0; +0.00100 p+ eta PYTHIA 0; +0.00100 p+ eta' PYTHIA 0; +0.00200 p+ rho0 PYTHIA 0; +0.00200 p+ omega PYTHIA 0; +0.000820000 p+ phi PYTHIA 0; +0.002800000 p+ f_0 PYTHIA 0; +0.00100 Delta+ pi0 PYTHIA 0; +0.00100 Delta+ eta PYTHIA 0; +0.00100 Delta+ eta' PYTHIA 0; +0.00100 Delta+ rho0 PYTHIA 0; +0.00100 Delta+ omega PYTHIA 0; +0.00300 n0 pi+ PYTHIA 0; +0.00300 n0 rho+ PYTHIA 0; +0.00300 Delta0 pi+ PYTHIA 0; +0.00300 Delta0 rho+ PYTHIA 0; +0.00500 Lambda0 K+ PYTHIA 0; +0.00500 Lambda0 K*+ PYTHIA 0; +0.00200 Sigma0 K+ PYTHIA 0; +0.00200 Sigma0 K*+ PYTHIA 0; +0.00100 Sigma*0 K+ PYTHIA 0; +0.00100 Sigma*0 K*+ PYTHIA 0; +0.00200 Sigma+ K0 PYTHIA 0; +0.002800000 Sigma+ K*0 PYTHIA 0; +0.00100 Sigma*+ K0 PYTHIA 0; +0.00100 Sigma*+ K*0 PYTHIA 0; +0.064094509 u anti-d d su_0 PYTHIA 43; +0.028102977 u anti-d d su_1 PYTHIA 43; +0.017256214 u anti-s d su_0 PYTHIA 43; +0.017256214 u anti-d d ud_0 PYTHIA 43; +0.046838295 s uu_1 PYTHIA 43; +0.069024855 u su_0 PYTHIA 43; +0.069024855 u su_1 PYTHIA 43; +0.014791040 d uu_1 PYTHIA 43; +0.007395520 u ud_0 PYTHIA 43; +0.007395520 u ud_1 PYTHIA 43; +0.025400000 p+ K- pi+ PHSP; #[New mode added] #[Reconstructed PDG2011] +0.033000000 p+ anti-K0 pi0 PHSP; #[New mode added] #[Reconstructed PDG2011] +0.012000000 p+ anti-K0 eta PHSP; #[New mode added] #[Reconstructed PDG2011] +0.026000000 p+ anti-K0 pi+ pi- PHSP; #[New mode added] #[Reconstructed PDG2011] +0.023000000 p+ K- pi+ pi0 PHSP; #[New mode added] #[Reconstructed PDG2011] +0.011000000 p+ K*- pi+ PHSP; #[New mode added] #[Reconstructed PDG2011] +0.001100000 p+ K- pi+ pi+ pi- PHSP; #[New mode added] #[Reconstructed PDG2011] +0.008000000 p+ K- pi+ pi0 pi0 PHSP; #[New mode added] #[Reconstructed PDG2011] +0.000700000 p+ pi+ pi- PHSP; #[New mode added] #[Reconstructed PDG2011] +0.001800000 p+ pi+ pi+ pi- pi- PHSP; #[New mode added] #[Reconstructed PDG2011] +0.000000000 p+ K+ K- PHSP; #[New mode added] #[Reconstructed PDG2011] +0.036000000 Lambda0 pi+ pi0 PHSP; #[New mode added] #[Reconstructed PDG2011] +0.015000000 Lambda0 pi+ pi+ pi- PHSP; #[New mode added] #[Reconstructed PDG2011] +0.011000000 Lambda0 pi+ rho0 PHSP; #[New mode added] #[Reconstructed PDG2011] +0.000000000 Lambda0 pi+ pi+ pi- pi0 PHSP; #[New mode added] #[Reconstructed PDG2011] +0.009500000 Lambda0 pi+ eta PHSP; #[New mode added] #[Reconstructed PDG2011] +0.012000000 Lambda0 pi+ omega PHSP; #[New mode added] #[Reconstructed PDG2011] +0.004700000 Lambda0 K+ anti-K0 PHSP; #[New mode added] #[Reconstructed PDG2011] +0.036000000 Sigma+ pi+ pi- PHSP; #[New mode added] #[Reconstructed PDG2011] +0.017000000 Sigma- pi+ pi+ PHSP; #[New mode added] #[Reconstructed PDG2011] +0.018000000 Sigma0 pi+ pi0 PHSP; #[New mode added] #[Reconstructed PDG2011] +0.008300000 Sigma0 pi+ pi+ pi- PHSP; #[New mode added] #[Reconstructed PDG2011] +0.000000000 Sigma+ K+ K- PHSP; #[New mode added] #[Reconstructed PDG2011] +0.003100000 Sigma+ phi PHSP; #[New mode added] #[Reconstructed PDG2011] +0.002500000 Xi- K+ pi+ PHSP; #[New mode added] #[Reconstructed PDG2011] +0.000000000 Sigma+ K+ pi- PHSP; #[New mode added] #[Reconstructed PDG2011] +Enddecay +CDecay anti-Lambda_c- +# +Decay Xi_c0 +1.000 PYTHIA 42; +Enddecay +Decay anti-Xi_c0 +1.000 PYTHIA 42; +Enddecay +# +Decay c-hadron +0.08000 e+ nu_e s specflav PYTHIA 22; +0.08000 mu+ nu_mu s specflav PYTHIA 22; +0.76000 u anti-d s specflav PYTHIA 42; +0.08000 u anti-s s specflav PYTHIA 42; +Enddecay +CDecay anti-c-hadron +# +Decay Sigma_c0 +1.0000 Lambda_c+ pi- PHSP; +Enddecay +Decay anti-Sigma_c0 +1.0000 anti-Lambda_c- pi+ PHSP; +Enddecay +# +Decay Sigma_c+ +1.0000 Lambda_c+ pi0 PHSP; +Enddecay +Decay anti-Sigma_c- +1.0000 anti-Lambda_c- pi0 PHSP; +Enddecay +# +Decay Xi_c+ +0.079535513 PYTHIA 42; +0.079535513 Sigma*+ anti-K0 PHSP; #[New mode added] #[Reconstructed PDG2011] +0.025689971 Lambda0 K- pi+ pi+ PHSP; #[New mode added] #[Reconstructed PDG2011] +0.010339617 Sigma+ K- pi+ PHSP; #[New mode added] #[Reconstructed PDG2011] +0.064423765 Sigma+ anti-K*0 PHSP; #[New mode added] #[Reconstructed PDG2011] +0.023065299 Sigma0 K- pi+ pi+ PHSP; #[New mode added] #[Reconstructed PDG2011] +0.043744532 Xi0 pi+ PHSP; #[New mode added] #[Reconstructed PDG2011] +0.079535513 Xi- pi+ pi+ PHSP; #[New mode added] #[Reconstructed PDG2011] +0.186113099 Xi0 pi+ pi0 PHSP; #[New mode added] #[Reconstructed PDG2011] +0.138391792 Xi0 pi- pi+ pi+ PHSP; #[New mode added] #[Reconstructed PDG2011] +0.182931679 Xi0 e+ nu_e PHSP; #[New mode added] #[Reconstructed PDG2011] +0.005567486 Omega- K+ pi+ PHSP; #[New mode added] #[Reconstructed PDG2011] +0.007158196 p+ K- pi+ PHSP; #[New mode added] #[Reconstructed PDG2011] +0.009544262 p+ anti-K*0 PHSP; #[New mode added] #[Reconstructed PDG2011] +0.038177046 Sigma+ pi+ pi- PHSP; #[New mode added] #[Reconstructed PDG2011] +0.014316392 Sigma- pi+ pi+ PHSP; #[New mode added] #[Reconstructed PDG2011] +0.011930327 Sigma+ K+ K- PHSP; #[New mode added] #[Reconstructed PDG2011] +Enddecay +Decay anti-Xi_c- +0.079535513 PYTHIA 42; +0.079535513 anti-Sigma*- K0 PHSP; #[New mode added] #[Reconstructed PDG2011] +0.025689971 anti-Lambda0 K+ pi- pi- PHSP; #[New mode added] #[Reconstructed PDG2011] +0.010339617 anti-Sigma- K+ pi- PHSP; #[New mode added] #[Reconstructed PDG2011] +0.064423765 anti-Sigma- K*0 PHSP; #[New mode added] #[Reconstructed PDG2011] +0.023065299 anti-Sigma0 K+ pi- pi- PHSP; #[New mode added] #[Reconstructed PDG2011] +0.043744532 anti-Xi0 pi- PHSP; #[New mode added] #[Reconstructed PDG2011] +0.079535513 anti-Xi+ pi- pi- PHSP; #[New mode added] #[Reconstructed PDG2011] +0.186113099 anti-Xi0 pi- pi0 PHSP; #[New mode added] #[Reconstructed PDG2011] +0.138391792 anti-Xi0 pi+ pi- pi- PHSP; #[New mode added] #[Reconstructed PDG2011] +0.182931679 anti-Xi0 e- anti-nu_e PHSP; #[New mode added] #[Reconstructed PDG2011] +0.005567486 anti-Omega+ K- pi- PHSP; #[New mode added] #[Reconstructed PDG2011] +0.007158196 anti-p- K+ pi- PHSP; #[New mode added] #[Reconstructed PDG2011] +0.009544262 anti-p- K*0 PHSP; #[New mode added] #[Reconstructed PDG2011] +0.038177046 anti-Sigma- pi- pi+ PHSP; #[New mode added] #[Reconstructed PDG2011] +0.014316392 anti-Sigma+ pi- pi- PHSP; #[New mode added] #[Reconstructed PDG2011] +0.011930327 anti-Sigma- K- K+ PHSP; #[New mode added] #[Reconstructed PDG2011] +Enddecay +# +Decay Sigma_c++ +1.0000 Lambda_c+ pi+ PHSP; +Enddecay +Decay anti-Sigma_c-- +1.0000 anti-Lambda_c- pi- PHSP; +Enddecay +# +Decay Xi'_c+ +0.1000 Lambda0 K- pi+ pi+ PHSP; +0.0800 Sigma0 K- pi+ pi+ PHSP; +0.8200 gamma Xi_c+ PHSP; +Enddecay +Decay anti-Xi'_c- +0.1000 anti-Lambda0 K+ pi- pi- PHSP; +0.0800 anti-Sigma0 K+ pi- pi- PHSP; +0.8200 gamma anti-Xi_c- PHSP; +Enddecay +# +Decay Xi'_c0 +1.0000 gamma Xi_c0 PHSP; +Enddecay +Decay anti-Xi'_c0 +1.0000 gamma anti-Xi_c0 PHSP; +Enddecay +# +# Light Baryons +# Lambda0 updated Feb 2009 +Decay Lambda0 +0.638719992 p+ pi- PHSP; #[Reconstructed PDG2011] +0.357719992 n0 pi0 PHSP; #[Reconstructed PDG2011] +0.001741600 n0 gamma PHSP; #[Reconstructed PDG2011] +0.000832160 p+ pi- gamma PHSP; #[Reconstructed PDG2011] +0.000831216 p+ e- anti-nu_e PHOTOS PHSP; #[Reconstructed PDG2011] +0.000155040 p+ mu- anti-nu_mu PHOTOS PHSP; #[Reconstructed PDG2011] +Enddecay +# +Decay anti-Lambda0 +0.638719992 anti-p- pi+ PHSP; #[Reconstructed PDG2011] +0.357719992 anti-n0 pi0 PHSP; #[Reconstructed PDG2011] +0.001741600 anti-n0 gamma PHSP; #[Reconstructed PDG2011] +0.000832160 anti-p- pi+ gamma PHSP; #[Reconstructed PDG2011] +0.000831216 anti-p- e+ nu_e PHOTOS PHSP; #[Reconstructed PDG2011] +0.000155040 anti-p- mu+ nu_mu PHOTOS PHSP; #[Reconstructed PDG2011] +Enddecay +# +Decay Lambda(1405)0 +0.3333 Sigma+ pi- PHSP; +0.3333 Sigma- pi+ PHSP; +0.3333 Sigma0 pi0 PHSP; +Enddecay +# +Decay anti-Lambda(1405)0 +0.3333 anti-Sigma+ pi- PHSP; +0.3333 anti-Sigma- pi+ PHSP; +0.3333 anti-Sigma0 pi0 PHSP; +Enddecay +# +Decay Lambda(1520)0 +0.23 p+ K- PHSP; +0.23 n0 anti-K0 PHSP; +0.14 Sigma+ pi- PHSP; +0.14 Sigma- pi+ PHSP; +0.14 Sigma0 pi0 PHSP; +0.0333 Lambda0 pi0 pi0 PHSP; +0.0667 Lambda0 pi+ pi- PHSP; +0.003 Sigma+ pi- pi0 PHSP; +0.003 Sigma- pi+ pi0 PHSP; +0.001 Sigma0 pi0 pi0 PHSP; +0.002 Sigma0 pi+ pi- PHSP; +0.011 Lambda0 gamma PHSP; +Enddecay +# +Decay anti-Lambda(1520)0 +0.23 anti-p- K+ PHSP; +0.23 anti-n0 K0 PHSP; +0.14 anti-Sigma- pi+ PHSP; +0.14 anti-Sigma+ pi- PHSP; +0.14 anti-Sigma0 pi0 PHSP; +0.0333 anti-Lambda0 pi0 pi0 PHSP; +0.0667 anti-Lambda0 pi+ pi- PHSP; +0.003 anti-Sigma+ pi- pi0 PHSP; +0.003 anti-Sigma- pi+ pi0 PHSP; +0.001 anti-Sigma0 pi0 pi0 PHSP; +0.002 anti-Sigma0 pi+ pi- PHSP; +0.011 anti-Lambda0 gamma PHSP; +Enddecay +# +Decay Lambda(1600)0 +0.176 p+ K- PHSP; +0.176 n0 anti-K0 PHSP; +0.216 Sigma+ pi- PHSP; +0.216 Sigma- pi+ PHSP; +0.216 Sigma0 pi0 PHSP; +Enddecay +# +Decay anti-Lambda(1600)0 +0.176 anti-p- K+ PHSP; +0.176 anti-n0 K0 PHSP; +0.216 anti-Sigma+ pi- PHSP; +0.216 anti-Sigma- pi+ PHSP; +0.216 anti-Sigma0 pi0 PHSP; +Enddecay +# +Decay Lambda(1670)0 +0.10 p+ K- PHSP; +0.10 n0 anti-K0 PHSP; +0.16 Sigma+ pi- PHSP; +0.16 Sigma- pi+ PHSP; +0.16 Sigma0 pi0 PHSP; +0.32 Lambda0 eta PHSP; +Enddecay +# +Decay anti-Lambda(1670)0 +0.10 anti-p- K+ PHSP; +0.10 anti-n0 K0 PHSP; +0.16 anti-Sigma+ pi- PHSP; +0.16 anti-Sigma- pi+ PHSP; +0.16 anti-Sigma0 pi0 PHSP; +0.32 anti-Lambda0 eta PHSP; +Enddecay +# +Decay Lambda(1690)0 +0.125 p+ K- PHSP; +0.125 n0 anti-K0 PHSP; +0.10 Sigma+ pi- PHSP; +0.10 Sigma- pi+ PHSP; +0.10 Sigma0 pi0 PHSP; +0.0833 Lambda0 pi0 pi0 PHSP; +0.1667 Lambda0 pi+ pi- PHSP; +0.067 Sigma+ pi- pi0 PHSP; +0.067 Sigma- pi+ pi0 PHSP; +0.022 Sigma0 pi0 pi0 PHSP; +0.044 Sigma0 pi+ pi- PHSP; +Enddecay +# +Decay anti-Lambda(1690)0 +0.125 anti-p- K+ PHSP; +0.125 anti-n0 K0 PHSP; +0.10 anti-Sigma+ pi- PHSP; +0.10 anti-Sigma- pi+ PHSP; +0.10 anti-Sigma0 pi0 PHSP; +0.0833 anti-Lambda0 pi0 pi0 PHSP; +0.1667 anti-Lambda0 pi+ pi- PHSP; +0.067 anti-Sigma+ pi- pi0 PHSP; +0.067 anti-Sigma- pi+ pi0 PHSP; +0.022 anti-Sigma0 pi0 pi0 PHSP; +0.044 anti-Sigma0 pi+ pi- PHSP; +Enddecay +# +Decay Lambda(1800)0 +0.165 p+ K- PHSP; +0.165 n0 anti-K0 PHSP; +0.08 Sigma+ pi- PHSP; +0.08 Sigma- pi+ PHSP; +0.08 Sigma0 pi0 PHSP; +0.003 Sigma*+ pi- PHSP; +0.003 Sigma*- pi+ PHSP; +0.004 Sigma*0 pi0 PHSP; +0.21 p+ K*- PHSP; +0.21 n0 anti-K*0 PHSP; +Enddecay +# +Decay anti-Lambda(1800)0 +0.165 anti-p- K+ PHSP; +0.165 anti-n0 K0 PHSP; +0.08 anti-Sigma+ pi- PHSP; +0.08 anti-Sigma- pi+ PHSP; +0.08 anti-Sigma0 pi0 PHSP; +0.003 anti-Sigma*+ pi- PHSP; +0.003 anti-Sigma*- pi+ PHSP; +0.004 anti-Sigma*0 pi0 PHSP; +0.21 anti-p- K*+ PHSP; +0.21 anti-n0 K*0 PHSP; +Enddecay +# +Decay Lambda(1810)0 +0.165 p+ K- PHSP; +0.165 n0 anti-K0 PHSP; +0.08 Sigma+ pi- PHSP; +0.08 Sigma- pi+ PHSP; +0.08 Sigma0 pi0 PHSP; +0.003 Sigma*+ pi- PHSP; +0.003 Sigma*- pi+ PHSP; +0.004 Sigma*0 pi0 PHSP; +0.21 p+ K*- PHSP; +0.21 n0 anti-K*0 PHSP; +Enddecay +# +Decay anti-Lambda(1810)0 +0.165 anti-p- K+ PHSP; +0.165 anti-n0 K0 PHSP; +0.08 anti-Sigma+ pi- PHSP; +0.08 anti-Sigma- pi+ PHSP; +0.08 anti-Sigma0 pi0 PHSP; +0.003 anti-Sigma*+ pi- PHSP; +0.003 anti-Sigma*- pi+ PHSP; +0.004 anti-Sigma*0 pi0 PHSP; +0.21 anti-p- K*+ PHSP; +0.21 anti-n0 K*0 PHSP; +Enddecay +# +Decay Lambda(1820)0 +0.34 p+ K- PHSP; +0.34 n0 anti-K0 PHSP; +0.06 Sigma+ pi- PHSP; +0.06 Sigma- pi+ PHSP; +0.06 Sigma0 pi0 PHSP; +0.04 Sigma*+ pi- PHSP; +0.04 Sigma*- pi+ PHSP; +0.04 Sigma*0 pi0 PHSP; +0.01 Lambda0 eta PHSP; +0.003 Sigma+ pi- pi0 PHSP; +0.004 Sigma- pi+ pi0 PHSP; +0.001 Sigma0 pi0 pi0 PHSP; +0.002 Sigma0 pi+ pi- PHSP; +Enddecay +# +Decay anti-Lambda(1820)0 +0.34 anti-p- K+ PHSP; +0.34 anti-n0 K0 PHSP; +0.06 anti-Sigma+ pi- PHSP; +0.06 anti-Sigma- pi+ PHSP; +0.06 anti-Sigma0 pi0 PHSP; +0.04 anti-Sigma*+ pi- PHSP; +0.04 anti-Sigma*- pi+ PHSP; +0.04 anti-Sigma*0 pi0 PHSP; +0.01 anti-Lambda0 eta PHSP; +0.003 anti-Sigma+ pi- pi0 PHSP; +0.004 anti-Sigma- pi+ pi0 PHSP; +0.001 anti-Sigma0 pi0 pi0 PHSP; +0.002 anti-Sigma0 pi+ pi- PHSP; +Enddecay +# +Decay Lambda(1830)0 +0.05 p+ K- PHSP; +0.05 n0 anti-K0 PHSP; +0.24 Sigma+ pi- PHSP; +0.24 Sigma- pi+ PHSP; +0.24 Sigma0 pi0 PHSP; +0.06 Sigma*+ pi- PHSP; +0.06 Sigma*- pi+ PHSP; +0.06 Sigma*0 pi0 PHSP; +Enddecay +# +Decay anti-Lambda(1830)0 +0.05 anti-p- K+ PHSP; +0.05 anti-n0 K0 PHSP; +0.24 anti-Sigma+ pi- PHSP; +0.24 anti-Sigma- pi+ PHSP; +0.24 anti-Sigma0 pi0 PHSP; +0.06 anti-Sigma*+ pi- PHSP; +0.06 anti-Sigma*- pi+ PHSP; +0.06 anti-Sigma*0 pi0 PHSP; +Enddecay +# +# +Decay Sigma(1660)0 +0.07 p+ K- PHSP; +0.07 n0 anti-K0 PHSP; +0.16 Lambda0 pi0 PHSP; +0.35 Sigma+ pi- PHSP; +0.35 Sigma- pi+ PHSP; +Enddecay +# +Decay anti-Sigma(1660)0 +0.07 anti-p- K+ PHSP; +0.07 anti-n0 K0 PHSP; +0.16 anti-Lambda0 pi0 PHSP; +0.35 anti-Sigma+ pi- PHSP; +0.35 anti-Sigma- pi+ PHSP; +Enddecay +# +Decay Sigma(1670)0 +0.07 p+ K- PHSP; +0.07 n0 anti-K0 PHSP; +0.16 Lambda0 pi0 PHSP; +0.35 Sigma+ pi- PHSP; +0.35 Sigma- pi+ PHSP; +Enddecay +# +Decay anti-Sigma(1670)0 +0.07 anti-p- K+ PHSP; +0.07 anti-n0 K0 PHSP; +0.16 anti-Lambda0 pi0 PHSP; +0.35 anti-Sigma+ pi- PHSP; +0.35 anti-Sigma- pi+ PHSP; +Enddecay +# +Decay Sigma(1775)0 +0.215 p+ K- PHSP; +0.215 n0 anti-K0 PHSP; +0.20 Lambda0 pi0 PHSP; +0.02 Sigma+ pi- PHSP; +0.02 Sigma- pi+ PHSP; +0.055 Sigma*+ pi- PHSP; +0.055 Sigma*- pi+ PHSP; +0.22 Lambda(1520)0 pi0 PHSP; +Enddecay +# +Decay anti-Sigma(1775)0 +0.215 anti-p- K+ PHSP; +0.215 anti-n0 K0 PHSP; +0.20 anti-Lambda0 pi0 PHSP; +0.02 anti-Sigma+ pi- PHSP; +0.02 anti-Sigma- pi+ PHSP; +0.055 anti-Sigma*+ pi- PHSP; +0.055 anti-Sigma*- pi+ PHSP; +0.22 anti-Lambda(1520)0 pi0 PHSP; +Enddecay +Decay Sigma+ +0.515454300 p+ pi0 PHSP; #[Reconstructed PDG2011] +0.482854300 n0 pi+ PHSP; #[Reconstructed PDG2011] +0.001225905 p+ gamma PHSP; #[Reconstructed PDG2011] +0.000445905 n0 pi+ gamma PHSP; #[New mode added] #[Reconstructed PDG2011] +0.000019590 Lambda0 e+ nu_e PHSP; #[New mode added] #[Reconstructed PDG2011] +Enddecay +Decay anti-Sigma- +0.515454300 anti-p- pi0 PHSP; #[Reconstructed PDG2011] +0.482854300 anti-n0 pi- PHSP; #[Reconstructed PDG2011] +0.001225905 anti-p- gamma PHSP; #[Reconstructed PDG2011] +0.000445905 anti-n0 pi- gamma PHSP; #[New mode added] #[Reconstructed PDG2011] +0.000019590 anti-Lambda0 e- anti-nu_e PHSP; #[New mode added] #[Reconstructed PDG2011] +Enddecay +# +Decay Delta+ +0.6630 p+ pi0 PHSP; +0.3310 n0 pi+ PHSP; +0.0060 p+ gamma PHSP; +Enddecay +Decay anti-Delta- +0.6630 anti-p- pi0 PHSP; +0.3310 anti-n0 pi- PHSP; +0.0060 anti-p- gamma PHSP; +Enddecay +# +Decay Delta++ +1.0000 p+ pi+ PHSP; +Enddecay +Decay anti-Delta-- +1.0000 anti-p- pi- PHSP; +Enddecay +# +Decay Xi*0 +0.3330 Xi0 pi0 PHSP; +0.6670 Xi- pi+ PHSP; +Enddecay +Decay anti-Xi*0 +0.3330 anti-Xi0 pi0 PHSP; +0.6670 anti-Xi+ pi- PHSP; +Enddecay +# +Decay Delta0 +0.3310 p+ pi- PHSP; +0.6630 n0 pi0 PHSP; +0.0060 n0 gamma PHSP; +Enddecay +Decay anti-Delta0 +0.3310 anti-p- pi+ PHSP; +0.6630 anti-n0 pi0 PHSP; +0.0060 anti-n0 gamma PHSP; +Enddecay +# +Decay Delta- +1.0000 n0 pi- PHSP; +Enddecay +Decay anti-Delta+ +1.0000 anti-n0 pi+ PHSP; +Enddecay +# +Decay Sigma- +0.998015700 n0 pi- PHSP; #[Reconstructed PDG2011] +0.000460000 n0 pi- gamma PHSP; #[New mode added] #[Reconstructed PDG2011] +0.001017000 n0 e- anti-nu_e PHSP; #[New mode added] #[Reconstructed PDG2011] +0.000450000 n0 mu- anti-nu_mu PHSP; #[New mode added] #[Reconstructed PDG2011] +0.000057300 Lambda0 e- anti-nu_e PHSP; #[New mode added] #[Reconstructed PDG2011] +Enddecay +Decay anti-Sigma+ +0.998015700 anti-n0 pi+ PHSP; #[Reconstructed PDG2011] +0.000460000 anti-n0 pi+ gamma PHSP; #[New mode added] #[Reconstructed PDG2011] +0.001017000 anti-n0 e+ nu_e PHSP; #[New mode added] #[Reconstructed PDG2011] +0.000450000 anti-n0 mu+ nu_mu PHSP; #[New mode added] #[Reconstructed PDG2011] +0.000057300 anti-Lambda0 e+ nu_e PHSP; #[New mode added] #[Reconstructed PDG2011] +Enddecay +# +Decay Sigma0 +0.995024876 gamma Lambda0 PHSP; #[Reconstructed PDG2011] +0.004975124 Lambda0 e+ e- PHSP; #[New mode added] #[Reconstructed PDG2011] +Enddecay +Decay anti-Sigma0 +0.995024876 gamma anti-Lambda0 PHSP; #[Reconstructed PDG2011] +0.004975124 anti-Lambda0 e- e+ PHSP; #[New mode added] #[Reconstructed PDG2011] +Enddecay +# +Decay Sigma*- +0.8800 Lambda0 pi- PHSP; +0.0600 Sigma0 pi- PHSP; +0.0600 Sigma- pi0 PHSP; +Enddecay +Decay anti-Sigma*+ +0.8800 anti-Lambda0 pi+ PHSP; +0.0600 anti-Sigma0 pi+ PHSP; +0.0600 anti-Sigma+ pi0 PHSP; +Enddecay +# +Decay Sigma*+ +0.8800 Lambda0 pi+ PHSP; +0.0600 Sigma+ pi0 PHSP; +0.0600 Sigma0 pi+ PHSP; +Enddecay +Decay anti-Sigma*- +0.8800 anti-Lambda0 pi- PHSP; +0.0600 anti-Sigma- pi0 PHSP; +0.0600 anti-Sigma0 pi- PHSP; +Enddecay +# +Decay Sigma*0 +0.8800 Lambda0 pi0 PHSP; +0.0600 Sigma+ pi- PHSP; +0.0600 Sigma- pi+ PHSP; +Enddecay +Decay anti-Sigma*0 +0.8800 anti-Lambda0 pi0 PHSP; +0.0600 anti-Sigma- pi+ PHSP; +0.0600 anti-Sigma+ pi- PHSP; +Enddecay +# +Decay Xi0 +0.995242400 Lambda0 pi0 PHSP; #[Reconstructed PDG2011] +0.001162400 Lambda0 gamma PHSP; #[New mode added] #[Reconstructed PDG2011] +0.000007600 Lambda0 e+ e- PHSP; #[New mode added] #[Reconstructed PDG2011] +0.003330000 Sigma0 gamma PHSP; #[New mode added] #[Reconstructed PDG2011] +0.000253000 Sigma+ e- anti-nu_e PHSP; #[New mode added] #[Reconstructed PDG2011] +0.000004600 Sigma+ mu- anti-nu_mu PHSP; #[New mode added] #[Reconstructed PDG2011] +Enddecay +Decay anti-Xi0 +0.995242400 anti-Lambda0 pi0 PHSP; #[Reconstructed PDG2011] +0.001162400 anti-Lambda0 gamma PHSP; #[New mode added] #[Reconstructed PDG2011] +0.000007600 anti-Lambda0 e- e+ PHSP; #[New mode added] #[Reconstructed PDG2011] +0.003330000 anti-Sigma0 gamma PHSP; #[New mode added] #[Reconstructed PDG2011] +0.000253000 anti-Sigma- e+ nu_e PHSP; #[New mode added] #[Reconstructed PDG2011] +0.000004600 anti-Sigma- mu+ nu_mu PHSP; #[New mode added] #[Reconstructed PDG2011] +Enddecay +# +Decay Xi- +0.998870000 Lambda0 pi- PHSP; #[Reconstructed PDG2011] +0.000127000 Sigma- gamma PHSP; #[New mode added] #[Reconstructed PDG2011] +0.000563000 Lambda0 e- anti-nu_e PHSP; #[New mode added] #[Reconstructed PDG2011] +0.000350000 Lambda0 mu- anti-nu_mu PHSP; #[New mode added] #[Reconstructed PDG2011] +0.000087000 Sigma0 e- anti-nu_e PHSP; #[New mode added] #[Reconstructed PDG2011] +Enddecay +Decay anti-Xi+ +0.998870000 anti-Lambda0 pi+ PHSP; #[Reconstructed PDG2011] +0.000127000 anti-Sigma+ gamma PHSP; #[New mode added] #[Reconstructed PDG2011] +0.000563000 anti-Lambda0 e+ nu_e PHSP; #[New mode added] #[Reconstructed PDG2011] +0.000350000 anti-Lambda0 mu+ nu_mu PHSP; #[New mode added] #[Reconstructed PDG2011] +0.000087000 anti-Sigma0 e+ nu_e PHSP; #[New mode added] #[Reconstructed PDG2011] +Enddecay +# +Decay Xi*- +0.6670 Xi0 pi- PHSP; +0.3330 Xi- pi0 PHSP; +Enddecay +Decay anti-Xi*+ +0.6670 anti-Xi0 pi+ PHSP; +0.3330 anti-Xi+ pi0 PHSP; +Enddecay +# +Decay Omega- +0.675949296 Lambda0 K- PHSP; #[Reconstructed PDG2011] +0.233949296 Xi0 pi- PHSP; #[Reconstructed PDG2011] +0.084828169 Xi- pi0 PHSP; #[Reconstructed PDG2011] +0.000000000 Xi- pi+ pi- PHSP; #[New mode added] #[Reconstructed PDG2011] +0.000493521 Xi*0 pi- PHSP; #[New mode added] #[Reconstructed PDG2011] +0.004779718 Xi0 e- anti-nu_e PHSP; #[New mode added] #[Reconstructed PDG2011] +Enddecay +Decay anti-Omega+ +0.675949296 anti-Lambda0 K+ PHSP; #[Reconstructed PDG2011] +0.233949296 anti-Xi0 pi+ PHSP; #[Reconstructed PDG2011] +0.084828169 anti-Xi+ pi0 PHSP; #[Reconstructed PDG2011] +0.000000000 anti-Xi+ pi- pi+ PHSP; #[New mode added] #[Reconstructed PDG2011] +0.000493521 anti-Xi*0 pi+ PHSP; #[New mode added] #[Reconstructed PDG2011] +0.004779718 anti-Xi0 e+ nu_e PHSP; #[New mode added] #[Reconstructed PDG2011] +Enddecay +# +# +Decay Sigma_c*0 +1.0000 Lambda_c+ pi- PHSP; +Enddecay +CDecay anti-Sigma_c*0 +# +Decay Sigma_c*+ +1.0000 Lambda_c+ pi0 PHSP; +Enddecay +CDecay anti-Sigma_c*- +# +Decay Sigma_c*++ +1.0000 Lambda_c+ pi+ PHSP; +Enddecay +CDecay anti-Sigma_c*-- +# +Decay Xi_c*0 +0.5000 Xi_c0 pi0 PHSP; +0.5000 Xi_c0 gamma PHSP; +Enddecay +CDecay anti-Xi_c*0 +# +Decay Xi_c*+ +0.5000 Xi_c+ pi0 PHSP; +0.5000 Xi_c+ gamma PHSP; +Enddecay +CDecay anti-Xi_c*- +# +Decay Omega_c0 +1.00000 PYTHIA 42; +Enddecay +# +CDecay anti-Omega_c0 +# +Decay Omega_c*0 +1.0000 Omega_c0 gamma PHSP; +Enddecay +# +CDecay anti-Omega_c*0 +# +Decay Xu0 +# X_u^0 -> u anti-u +# +1.0 u anti-u PYTHIA 42; +Enddecay +Decay Xu+ +# X_u^+ -> u anti-d +# +1.0 u anti-d PYTHIA 42; +Enddecay +CDecay Xu- + +#lange - PYTHIA is making h_c mesons - better add a decay +# channel for them. +Decay h_c +0.01 J/psi pi0 PHSP; +0.5 eta_c gamma PHSP; +0.49 rndmflav anti-rndmflav PYTHIA 42; +Enddecay + +# 12/08/03 RJT Update b-baryon decays... +# chi_c or psi(2S) BR to J/psi are included below + +Decay Lambda_b0 +# add from PDG 2026 + 0.00032 J/psi p+ K- PHSP; + 0.000026 J/psi p+ pi- PHSP; + 0.000000454 psi(2S) p+ pi- PHSP; + 0.00000454 psi(2S) p+ K- PHSP; + 0.00000258 chi_c1 p+ K- PHSP; + 0.000000175 chi_c1 p+ pi- PHSP; + 0.00000156 chi_c2 p+ K- PHSP; + 0.0000000937 chi_c2 p+ pi- PHSP; +Enddecay + +Decay anti-Lambda_b0 +# add from PDG 2026; + 0.00032 J/psi anti-p- K+ PHSP; + 0.000026 J/psi anti-p- pi+ PHSP; + 0.000000454 psi(2S) anti-p- pi+ PHSP; + 0.00000454 psi(2S) anti-p- K+ PHSP; + 0.00000258 chi_c1 anti-p- K+ PHSP; + 0.000000175 chi_c1 anti-p- pi+ PHSP; + 0.00000156 chi_c2 anti-p- K+ PHSP; + 0.0000000937 chi_c2 anti-p- pi+ PHSP; +Enddecay + +Decay Xi_b- +# SemiLeptonic Decays + 0.05460 Xi_c0 e- anti-nu_e PHSP; + 0.05460 Xi_c0 mu- anti-nu_mu PHSP; + 0.02000 Xi_c0 tau- anti-nu_tau PHSP; +# Hadronic Decays with Xi_c0 + 0.00600 Xi_c0 pi- PHSP; + 0.02200 Xi_c0 pi- pi+ pi- PHSP; + 0.00055 Xi_c0 K- PHSP; + 0.02200 Xi_c0 D_s- PHSP; + 0.00047 Xi- J/psi PHSP; +# added by D.Litvintsev 12/8/03: + 0.00038 Xi- psi(2S) PHSP; + 0.00018 D0 Lambda0 pi- PHSP; + 0.00020 Sigma_c0 K- PHSP; + 0.00020 Omega_c0 K- PHSP; +# +# aaa 10/19/05 Do not if this is correct but filling out with inclusives +0.38757 d anti-u d cs_0 PYTHIA 43; +0.16995 d anti-u d cs_1 PYTHIA 43; +0.06335 s anti-u d cs_0 PYTHIA 43; +0.00568 d anti-u s cs_1 PYTHIA 43; +0.00797 d anti-u s cs_0 PYTHIA 43; +0.06148 s anti-c d cs_0 PYTHIA 43; +0.06918 d anti-u d cd_0 PYTHIA 43; +0.03999 s anti-c d cd_0 PYTHIA 43; +0.00865 d anti-u d su_0 PYTHIA 43; +0.00500 s anti-c d su_0 PYTHIA 43; +Enddecay + +Decay anti-Xi_b+ +# SemiLeptonic Decays + 0.05460 anti-Xi_c0 e+ nu_e PHSP; + 0.05460 anti-Xi_c0 mu+ nu_mu PHSP; + 0.02000 anti-Xi_c0 tau+ nu_tau PHSP; +# Hadronic Decays with anti-Xi_c0 + 0.00600 anti-Xi_c0 pi+ PHSP; + 0.02200 anti-Xi_c0 pi+ pi+ pi- PHSP; + 0.00055 anti-Xi_c0 K+ PHSP; + 0.02200 anti-Xi_c0 D_s+ PHSP; + 0.00047 anti-Xi+ J/psi PHSP; +# added by D.Litvintsev 12/8/03: + 0.00038 anti-Xi+ psi(2S) PHSP; + 0.00018 anti-D0 anti-Lambda0 pi+ PHSP; + 0.00020 anti-Sigma_c0 K+ PHSP; + 0.00020 anti-Omega_c0 K+ PHSP; +# aaa 10/19/05 Do not if this is correct but filling out with inclusives +0.38757 u anti-d anti-d anti-cs_0 PYTHIA 43; +0.16995 u anti-d anti-d anti-cs_1 PYTHIA 43; +0.06335 u anti-s anti-d anti-cs_0 PYTHIA 43; +0.00568 u anti-d anti-s anti-cs_1 PYTHIA 43; +0.00797 u anti-d anti-s anti-cs_0 PYTHIA 43; +0.06148 c anti-s anti-d anti-cs_0 PYTHIA 43; +0.06918 u anti-d anti-d anti-cd_0 PYTHIA 43; +0.03999 c anti-s anti-d anti-cd_0 PYTHIA 43; +0.00865 u anti-d anti-d anti-su_0 PYTHIA 43; +0.00500 c anti-s anti-d anti-su_0 PYTHIA 43; +Enddecay + +Decay Xi_b0 +# SemiLeptonic Decays + 0.05460 Xi_c+ e- anti-nu_e PHSP; + 0.05460 Xi_c+ mu- anti-nu_mu PHSP; + 0.02000 Xi_c+ tau- anti-nu_tau PHSP; +# Hadronic Decays with Xi_c+ + 0.00600 Xi_c+ pi- PHSP; + 0.02200 Xi_c+ pi- pi+ pi- PHSP; + 0.00055 Xi_c+ K- PHSP; + 0.02200 Xi_c+ D_s- PHSP; + 0.00047 Xi0 J/psi PHSP; +# added by D.Litvintsev 12/8/03: + 0.00020 D0 Lambda0 PHSP; + 0.00010 Lambda_c+ K- PHSP; + 0.00020 Sigma_c0 anti-K0 PHSP; + 0.00020 Omega_c0 K0 PHSP; +# +# Additional decays from hep-ph/9709372 scaled to the Lambda_c0 pi rate + 0.00020 Xi'_c+ pi- PHSP; + 0.00003 Xi_c0 pi0 PHSP; + 0.00015 Xi_c0 eta PHSP; + 0.00004 Xi_c0 eta' PHSP; + 0.00020 Xi'_c0 pi0 PHSP; + 0.00020 Xi'_c0 eta PHSP; + 0.00030 Xi'_c0 eta' PHSP; + 0.00040 Sigma_c+ K- PHSP; +# aaa 10/19/05 Do not if this is correct but filling out with inclusives +0.58591 d anti-u s cu_0 PYTHIA 43; +0.01363 s anti-u s cu_1 PYTHIA 43; +0.09539 s anti-u s cc_1 PYTHIA 43; +0.10900 s anti-u d cu_1 PYTHIA 43; +0.01363 d anti-u d uu_1 PYTHIA 43; +Enddecay + +Decay anti-Xi_b0 + 0.05460 anti-Xi_c- e+ nu_e PHSP; + 0.05460 anti-Xi_c- mu+ nu_mu PHSP; + 0.02000 anti-Xi_c- tau+ nu_tau PHSP; +# Hadronic Decays with anti-Xi_c- + 0.00600 anti-Xi_c- pi+ PHSP; + 0.02200 anti-Xi_c- pi+ pi+ pi- PHSP; + 0.00055 anti-Xi_c- K+ PHSP; + 0.02200 anti-Xi_c- D_s+ PHSP; + 0.00047 anti-Xi0 J/psi PHSP; +# added by D.Litvintsev 12/8/03: + 0.00020 anti-D0 anti-Lambda0 PHSP; + 0.00010 anti-Lambda_c- K+ PHSP; + 0.00020 anti-Sigma_c0 K0 PHSP; + 0.00020 anti-Omega_c0 anti-K0 PHSP; +# +# Additional decays from hep-ph/9709372 scaled to the Lambda_c0 pi rate + 0.00020 anti-Xi'_c- pi+ PHSP; + 0.00003 anti-Xi_c0 pi0 PHSP; + 0.00015 anti-Xi_c0 eta PHSP; + 0.00004 anti-Xi_c0 eta' PHSP; + 0.00020 anti-Xi'_c0 pi0 PHSP; + 0.00020 anti-Xi'_c0 eta PHSP; + 0.00030 anti-Xi'_c0 eta' PHSP; + 0.00040 anti-Sigma_c- K+ PHSP; +# aaa 10/19/05 Do not if this is correct but filling out with inclusives +0.58591 u anti-d anti-s anti-cu_0 PYTHIA 43; +0.01363 u anti-s anti-s anti-cu_1 PYTHIA 43; +0.09539 u anti-s anti-s anti-cc_1 PYTHIA 43; +0.10900 u anti-s anti-d anti-cu_1 PYTHIA 43; +0.01363 u anti-d anti-d anti-uu_1 PYTHIA 43; +Enddecay + +# added by D.Litvintsev 12/8/03: +Decay Omega_b- +# SemiLeptonic Decays + 0.05460 Omega_c0 e- anti-nu_e PHSP; + 0.05460 Omega_c0 mu- anti-nu_mu PHSP; + 0.02000 Omega_c0 tau- anti-nu_tau PHSP; +# Hadronic Decays with Xi_c+ + 0.00600 Omega_c0 pi- PHSP; + 0.02200 Omega_c0 pi- pi+ pi- PHSP; + 0.00055 Omega_c0 K- PHSP; + 0.02200 Omega_c0 D_s- PHSP; + 0.0011 D0 Xi- PHSP; +# + 0.00047 Omega- J/psi PHSP; + 0.00038 Omega- psi(2S) PHSP; +# aaa 10/19/05 Do not if this is correct but filling out with inclusives +0.68192 d anti-u s cs_0 PYTHIA 43; +0.10910 d anti-u d cs_0 PYTHIA 43; +0.02728 d anti-u s su_0 PYTHIA 43; +Enddecay + +Decay anti-Omega_b+ +# SemiLeptonic Decays + 0.05460 anti-Omega_c0 e+ nu_e PHSP; + 0.05460 anti-Omega_c0 mu+ nu_mu PHSP; + 0.02000 anti-Omega_c0 tau+ nu_tau PHSP; +# Hadronic Decays with Xi_c+ + 0.00600 anti-Omega_c0 pi+ PHSP; + 0.02200 anti-Omega_c0 pi+ pi+ pi- PHSP; + 0.00055 anti-Omega_c0 K+ PHSP; + 0.02200 anti-Omega_c0 D_s+ PHSP; + 0.0011 anti-D0 anti-Xi+ PHSP; +# + 0.00047 anti-Omega+ J/psi PHSP; + 0.00038 anti-Omega+ psi(2S) PHSP; +# aaa 10/19/05 Do not if this is correct but filling out with inclusives +0.68192 u anti-d anti-s anti-cs_0 PYTHIA 43; +0.10910 u anti-d anti-d anti-cs_0 PYTHIA 43; +0.02728 u anti-d anti-s anti-su_0 PYTHIA 43; +Enddecay + + +Decay Sigma_b+ + 1.00000 Lambda_b0 pi+ PHSP; +Enddecay +Decay anti-Sigma_b- + 1.00000 anti-Lambda_b0 pi- PHSP; +Enddecay + +Decay Sigma_b- + 1.00000 Lambda_b0 pi- PHSP; +Enddecay +Decay anti-Sigma_b+ + 1.00000 anti-Lambda_b0 pi+ PHSP; +Enddecay + +Decay Sigma_b0 + 1.00000 Lambda_b0 gamma PHOTOS PHSP; +Enddecay +Decay anti-Sigma_b0 + 1.00000 anti-Lambda_b0 gamma PHOTOS PHSP; +Enddecay + + +# +# B_c Mesons +# + +Decay B_c- +0.01600 tau- anti-nu_tau SLN; +# +# SemiLeptonic Decays +0.01900 J/psi e- anti-nu_e PHOTOS PHSP; +0.00094 psi(2S) e- anti-nu_e PHOTOS PHSP; +0.00750 eta_c e- anti-nu_e PHOTOS PHSP; +0.00020 eta_c(2S) e- anti-nu_e PHOTOS PHSP; +0.00004 anti-D0 e- anti-nu_e PHOTOS PHSP; +0.00018 anti-D*0 e- anti-nu_e PHOTOS PHSP; +0.04030 anti-B_s0 e- anti-nu_e PHOTOS PHSP; +0.05060 anti-B_s*0 e- anti-nu_e PHOTOS PHSP; +0.00340 anti-B0 e- anti-nu_e PHOTOS PHSP; +0.00580 anti-B*0 e- anti-nu_e PHOTOS PHSP; +# +0.01900 J/psi mu- anti-nu_mu PHOTOS PHSP; +0.00094 psi(2S) mu- anti-nu_mu PHOTOS PHSP; +0.00750 eta_c mu- anti-nu_mu PHOTOS PHSP; +0.00020 eta_c(2S) mu- anti-nu_mu PHOTOS PHSP; +0.00004 anti-D0 mu- anti-nu_mu PHOTOS PHSP; +0.00018 anti-D*0 mu- anti-nu_mu PHOTOS PHSP; +0.04030 anti-B_s0 mu- anti-nu_mu PHOTOS PHSP; +0.05060 anti-B_s*0 mu- anti-nu_mu PHOTOS PHSP; +0.00340 anti-B0 mu- anti-nu_mu PHOTOS PHSP; +0.00580 anti-B*0 mu- anti-nu_mu PHOTOS PHSP; +# +0.00480 J/psi tau- anti-nu_tau PHSP; +0.00008 psi(2S) tau- anti-nu_tau PHSP; +0.00230 eta_c tau- anti-nu_tau PHSP; +0.000016 eta_c(2S) tau- anti-nu_tau PHSP; +0.00002 anti-D0 tau- anti-nu_tau PHSP; +0.00008 anti-D*0 tau- anti-nu_tau PHSP; +# +# +# Hadronic Decays +0.00200 eta_c pi- PHSP; +0.00420 rho- eta_c SVS; +0.00013 eta_c K- PHSP; +0.00020 K*- eta_c SVS; +0.00130 J/psi pi- SVS; +0.00400 J/psi rho- SVV_HELAMP 1.0 0.0 1.0 0.0 1.0 0.0; +0.00011 J/psi K- SVS; +0.00022 J/psi K*- SVV_HELAMP 1.0 0.0 1.0 0.0 1.0 0.0; +# +0.000053 D- D0 PHSP; +0.000075 D*0 D- SVS; +0.000049 D*- D0 SVS; +0.00033 D*- D*0 SVV_HELAMP 1.0 0.0 1.0 0.0 1.0 0.0; +0.0000048 D_s- D0 PHSP; +0.0000071 D*0 D_s- SVS; +0.0000045 D_s*- D0 SVS; +0.000026 D_s*- D*0 SVV_HELAMP 1.0 0.0 1.0 0.0 1.0 0.0; +# +0.0000003 D- anti-D0 PHSP; +0.0000003 anti-D*0 D- SVS; +0.0000004 D*- anti-D0 SVS; +0.0000016 anti-D*0 D*- SVV_HELAMP 1.0 0.0 1.0 0.0 1.0 0.0; +0.0000066 D_s- anti-D0 PHSP; +0.0000063 anti-D*0 D_s- SVS; +0.0000085 D_s*- anti-D0 SVS; +0.0000404 D_s*- anti-D*0 SVV_HELAMP 1.0 0.0 1.0 0.0 1.0 0.0; +# +0.00280 eta_c D_s- PHSP; +0.00270 D_s*- eta_c SVS; +0.00015 eta_c D- PHSP; +0.00010 D*- eta_c SVS; +0.00170 J/psi D_s- SVS; +0.00670 J/psi D_s*- SVV_HELAMP 1.0 0.0 1.0 0.0 1.0 0.0; +0.00009 J/psi D- SVS; +0.00028 J/psi D*- SVV_HELAMP 1.0 0.0 1.0 0.0 1.0 0.0; +# +0.16400 anti-B_s0 pi- PHSP; +0.07200 rho- anti-B_s0 SVS; +0.01060 anti-B_s0 K- PHSP; +0.00000 K*- anti-B_s0 SVS; +0.06500 anti-B_s*0 pi- SVS; +0.20200 anti-B_s*0 rho- SVV_HELAMP 1.0 0.0 1.0 0.0 1.0 0.0; +0.00370 anti-B_s*0 K- SVS; +0.00000 anti-B_s*0 K*- SVV_HELAMP 1.0 0.0 1.0 0.0 1.0 0.0; +0.01060 anti-B0 pi- PHSP; +0.00960 rho- anti-B0 SVS; +0.00070 anti-B0 K- PHSP; +0.00015 K*- anti-B0 SVS; +0.00950 anti-B*0 pi- SVS; +0.02570 anti-B*0 rho- SVV_HELAMP 1.0 0.0 1.0 0.0 1.0 0.0; +0.00055 anti-B*0 K- SVS; +0.00058 anti-B*0 K*- SVV_HELAMP 1.0 0.0 1.0 0.0 1.0 0.0; +0.00037 B- pi0 PHSP; +0.00034 rho0 B- SVS; +0.01980 B- K0 PHSP; +0.00430 K*0 B- SVS; +0.00033 B*- pi0 SVS; +0.00090 B*- rho0 SVV_HELAMP 1.0 0.0 1.0 0.0 1.0 0.0; +0.01600 B*- K0 SVS; +0.01670 B*- K*0 SVV_HELAMP 1.0 0.0 1.0 0.0 1.0 0.0; +# PR LHCb 09 Apr 2004 Add B_c+ -> rho0 pi+ + 0.00002 rho0 pi- SVS; +0.06005 anti-c s PYTHIA 42; +# PR LHCb 27 Apr 2004 Add Pythia Modes +# +# ash 10/27/03 Do not if this is correct but filling out with unknown cs +#0.0200235 cs_0 anti-uu_0 PYTHIA 63; +#0.0400470 cs_1 anti-uu_1 PYTHIA 63; +# +Enddecay + +# 09/15/03 A. Sanchez: Using BR's from hep-ph/0308214 +# +# Total Br = 0.939865 + .06135 cs +Decay B_c+ +0.01600 tau+ nu_tau SLN; +# +# SemiLeptonic Decays +0.01900 J/psi e+ nu_e PHOTOS PHSP; +0.00094 psi(2S) e+ nu_e PHOTOS PHSP; +0.00750 eta_c e+ nu_e PHOTOS PHSP; +0.00020 eta_c(2S) e+ nu_e PHOTOS PHSP; +0.00004 D0 e+ nu_e PHOTOS PHSP; +0.00018 D*0 e+ nu_e PHOTOS PHSP; +0.04030 B_s0 e+ nu_e PHOTOS PHSP; +0.05060 B_s*0 e+ nu_e PHOTOS PHSP; +0.00340 B0 e+ nu_e PHOTOS PHSP; +0.00580 B*0 e+ nu_e PHOTOS PHSP; +# +0.01900 J/psi mu+ nu_mu PHOTOS PHSP; +0.00094 psi(2S) mu+ nu_mu PHOTOS PHSP; +0.00750 eta_c mu+ nu_mu PHOTOS PHSP; +0.00020 eta_c(2S) mu+ nu_mu PHOTOS PHSP; +0.00004 D0 mu+ nu_mu PHOTOS PHSP; +0.00018 D*0 mu+ nu_mu PHOTOS PHSP; +0.04030 B_s0 mu+ nu_mu PHOTOS PHSP; +0.05060 B_s*0 mu+ nu_mu PHOTOS PHSP; +0.00340 B0 mu+ nu_mu PHOTOS PHSP; +0.00580 B*0 mu+ nu_mu PHOTOS PHSP; +# +0.00480 J/psi tau+ nu_tau PHSP; +0.00008 psi(2S) tau+ nu_tau PHSP; +0.00230 eta_c tau+ nu_tau PHSP; +0.000016 eta_c(2S) tau+ nu_tau PHSP; +0.00002 D0 tau+ nu_tau PHSP; +0.00008 D*0 tau+ nu_tau PHSP; +# +# Hadronic Decays +0.00200 eta_c pi+ PHSP; +0.00420 rho+ eta_c SVS; +0.00013 eta_c K+ PHSP; +0.00020 K*+ eta_c SVS; +0.00130 J/psi pi+ SVS; +0.00400 J/psi rho+ SVV_HELAMP 1.0 0.0 1.0 0.0 1.0 0.0; +0.00011 J/psi K+ SVS; +0.00022 J/psi K*+ SVV_HELAMP 1.0 0.0 1.0 0.0 1.0 0.0; +# +0.000053 D+ anti-D0 PHSP; +0.000075 anti-D*0 D+ SVS; +0.000049 D*+ anti-D0 SVS; +0.00033 D*+ anti-D*0 SVV_HELAMP 1.0 0.0 1.0 0.0 1.0 0.0; +0.0000048 D_s+ anti-D0 PHSP; +0.0000071 anti-D*0 D_s+ SVS; +0.0000045 D_s*+ anti-D0 SVS; +0.000026 D_s*+ anti-D*0 SVV_HELAMP 1.0 0.0 1.0 0.0 1.0 0.0; +# +0.0000003 D+ D0 PHSP; +0.0000003 D*0 D+ SVS; +0.0000004 D*+ D0 SVS; +0.0000016 D*0 D*+ SVV_HELAMP 1.0 0.0 1.0 0.0 1.0 0.0; +0.0000066 D_s+ D0 PHSP; +0.0000063 D*0 D_s+ SVS; +0.0000085 D_s*+ D0 SVS; +0.0000404 D_s*+ D*0 SVV_HELAMP 1.0 0.0 1.0 0.0 1.0 0.0; +# +0.00280 eta_c D_s+ PHSP; +0.00270 D_s*+ eta_c SVS; +0.00015 eta_c D+ PHSP; +0.00010 D*+ eta_c SVS; +0.00170 J/psi D_s+ SVS; +0.00670 J/psi D_s*+ SVV_HELAMP 1.0 0.0 1.0 0.0 1.0 0.0; +0.00009 J/psi D+ SVS; +0.00028 J/psi D*+ SVV_HELAMP 1.0 0.0 1.0 0.0 1.0 0.0; +# +0.16400 B_s0 pi+ PHSP; +0.07200 rho+ B_s0 SVS; +0.01060 B_s0 K+ PHSP; +0.00000 K*+ B_s0 SVS; +0.06500 B_s*0 pi+ SVS; +0.20200 B_s*0 rho+ SVV_HELAMP 1.0 0.0 1.0 0.0 1.0 0.0; +0.00370 B_s*0 K+ SVS; +0.00000 B_s*0 K*+ SVV_HELAMP 1.0 0.0 1.0 0.0 1.0 0.0; +0.01060 B0 pi+ PHSP; +0.00960 rho+ B0 SVS; +0.00070 B0 K+ PHSP; +0.00015 K*+ B0 SVS; +0.00950 B*0 pi+ SVS; +0.02570 B*0 rho+ SVV_HELAMP 1.0 0.0 1.0 0.0 1.0 0.0; +0.00055 B*0 K+ SVS; +0.00058 B*0 K*+ SVV_HELAMP 1.0 0.0 1.0 0.0 1.0 0.0; +0.00037 B+ pi0 PHSP; +0.00034 rho0 B+ SVS; +0.01980 B+ anti-K0 PHSP; +0.00430 K*0 B+ SVS; +0.00033 B*+ pi0 SVS; +0.00090 B*+ rho0 SVV_HELAMP 1.0 0.0 1.0 0.0 1.0 0.0; +0.01600 B*+ anti-K0 SVS; +0.01670 B*+ K*0 SVV_HELAMP 1.0 0.0 1.0 0.0 1.0 0.0; +# PR LHCb 09 Apr 2004 Add B_c+ -> rho0 pi+ + 0.00002 rho0 pi+ SVS; +0.06005 c anti-s PYTHIA 42; +# PR LHCb 27 Apr 2004 Add Pythia Modes +# +# ash 10/27/03 Do not if this is correct but filling out with unknown cs +#0.0200235 anti-cs_0 uu_0 PYTHIA 63; +#0.0400470 anti-cs_1 uu_1 PYTHIA 63; +# +Enddecay + + +# Add excited Lambda_c decays (R.J. Tesarek 12/9/03) +# Just a guess for the last two BR [Lambda_c(2593)+]. +Decay Lambda_c(2593)+ +0.096585366 Sigma_c++ pi- PHSP; #[Reconstructed PDG2011] +0.096585366 Sigma_c0 pi+ PHSP; #[Reconstructed PDG2011] +0.190000000 Lambda_c+ pi+ pi- PHSP; #[Reconstructed PDG2011] +0.096585366 Sigma_c+ pi0 PHSP; #[Reconstructed PDG2011] +0.036219512 Lambda_c+ pi0 pi0 PHSP; #[Reconstructed PDG2011] +0.004024390 Lambda_c+ gamma PHSP; #[Reconstructed PDG2011] +0.240000000 Sigma_c*++ pi- PHSP; #[New mode added] #[Reconstructed PDG2011] +0.240000000 Sigma_c*0 pi+ PHSP; #[New mode added] #[Reconstructed PDG2011] +Enddecay +Decay anti-Lambda_c(2593)- +0.096585366 anti-Sigma_c-- pi+ PHSP; #[Reconstructed PDG2011] +0.096585366 anti-Sigma_c0 pi- PHSP; #[Reconstructed PDG2011] +0.190000000 anti-Lambda_c- pi- pi+ PHSP; #[Reconstructed PDG2011] +0.096585366 anti-Sigma_c- pi0 PHSP; #[Reconstructed PDG2011] +0.036219512 anti-Lambda_c- pi0 pi0 PHSP; #[Reconstructed PDG2011] +0.004024390 anti-Lambda_c- gamma PHSP; #[Reconstructed PDG2011] +0.240000000 anti-Sigma_c*-- pi+ PHSP; #[New mode added] #[Reconstructed PDG2011] +0.240000000 anti-Sigma_c*0 pi- PHSP; #[New mode added] #[Reconstructed PDG2011] +Enddecay +# +Decay Lambda_c(2625)+ +0.670000000 Lambda_c+ pi+ pi- PHSP; #[Reconstructed PDG2011] +0.320294118 Lambda_c+ pi0 PHSP; #[Reconstructed PDG2011] +0.009705882 Lambda_c+ gamma PHSP; #[Reconstructed PDG2011] +Enddecay +Decay anti-Lambda_c(2625)- +0.670000000 anti-Lambda_c- pi- pi+ PHSP; #[Reconstructed PDG2011] +0.320294118 anti-Lambda_c- pi0 PHSP; #[Reconstructed PDG2011] +0.009705882 anti-Lambda_c- gamma PHSP; #[Reconstructed PDG2011] +Enddecay + +# Add excited B hadrons (LHCb PR 10/03/04) +# Reference : Pythia 6.205 decay table +# PDG Id = 5312 +Decay Xi'_b- + 1.0000 Xi_b- gamma PHSP; +Enddecay +Decay anti-Xi'_b+ + 1.0000 anti-Xi_b+ gamma PHSP; +Enddecay +# PDG Id = 5322 +Decay Xi'_b0 + 1.0000 Xi_b0 gamma PHSP; +Enddecay +Decay anti-Xi'_b0 + 1.0000 anti-Xi_b0 gamma PHSP; +Enddecay +# PDG Id = 10521 +Decay B_0*+ + 0.6670 B0 pi+ PHSP; + 0.3330 B+ pi0 PHSP; +Enddecay +Decay B_0*- + 0.6670 anti-B0 pi- PHSP; + 0.3330 B- pi0 PHSP; +Enddecay +# PDG Id = 20523 Broad : S wave +Decay B'_1+ + 0.6670 B*0 pi+ VVS_PWAVE 1.0 0.0 0.0 0.0 0.0 0.0; + 0.3330 B*+ pi0 VVS_PWAVE 1.0 0.0 0.0 0.0 0.0 0.0; +Enddecay +Decay B'_1- + 0.6670 anti-B*0 pi- VVS_PWAVE 1.0 0.0 0.0 0.0 0.0 0.0; + 0.3330 B*- pi0 VVS_PWAVE 1.0 0.0 0.0 0.0 0.0 0.0; +Enddecay +# PDG Id = 10523 Narrow : D wave +Decay B_1+ + 0.6670 B*0 pi+ VVS_PWAVE 0.0 0.0 0.0 0.0 1.0 0.0; + 0.3330 B*+ pi0 VVS_PWAVE 0.0 0.0 0.0 0.0 1.0 0.0; +Enddecay +Decay B_1- + 0.6670 anti-B*0 pi- VVS_PWAVE 0.0 0.0 0.0 0.0 1.0 0.0; + 0.3330 B*- pi0 VVS_PWAVE 0.0 0.0 0.0 0.0 1.0 0.0; +Enddecay +# PDG Id = 525 Narrow : D wave +Decay B_2*+ + 0.3000 B0 pi+ TSS; + 0.1500 B+ pi0 TSS; + 0.1600 B*0 pi+ TVS_PWAVE 0.0 0.0 1.0 0.0 0.0 0.0; + 0.0800 B*+ pi0 TVS_PWAVE 0.0 0.0 1.0 0.0 0.0 0.0; + 0.1300 B*0 pi+ pi0 PHSP; + 0.0600 B*+ pi+ pi- PHSP; + 0.0800 B0 pi+ pi0 PHSP; + 0.0400 B+ pi+ pi- PHSP; +Enddecay +Decay B_2*- + 0.3000 anti-B0 pi- TSS; + 0.1500 B- pi0 TSS; + 0.1600 anti-B*0 pi- TVS_PWAVE 0.0 0.0 1.0 0.0 0.0 0.0; + 0.0800 B*- pi0 TVS_PWAVE 0.0 0.0 1.0 0.0 0.0 0.0; + 0.1300 anti-B*0 pi- pi0 PHSP; + 0.0600 B*- pi- pi+ PHSP; + 0.0800 anti-B0 pi- pi0 PHSP; + 0.0400 B- pi- pi+ PHSP; +Enddecay +# PDG Id = 10511 +Decay B_0*0 + 0.6670 B+ pi- PHSP; + 0.3330 B0 pi0 PHSP; +Enddecay +Decay anti-B_0*0 + 0.6670 B- pi+ PHSP; + 0.3330 anti-B0 pi0 PHSP; +Enddecay +# PDG Id = 20513 Broad : S wave +Decay B'_10 + 0.6670 B*+ pi- VVS_PWAVE 1.0 0.0 0.0 0.0 0.0 0.0; + 0.3330 B*0 pi0 VVS_PWAVE 1.0 0.0 0.0 0.0 0.0 0.0; +Enddecay +Decay anti-B'_10 + 0.6670 B*- pi+ VVS_PWAVE 1.0 0.0 0.0 0.0 0.0 0.0; + 0.3330 anti-B*0 pi0 VVS_PWAVE 1.0 0.0 0.0 0.0 0.0 0.0; +Enddecay +# PDG Id = 10513 Narrow : D wave +Decay B_10 + 0.6670 B*+ pi- VVS_PWAVE 0.0 0.0 0.0 0.0 1.0 0.0; + 0.3330 B*0 pi0 VVS_PWAVE 0.0 0.0 0.0 0.0 1.0 0.0; +Enddecay +Decay anti-B_10 + 0.6670 B*- pi+ VVS_PWAVE 0.0 0.0 0.0 0.0 1.0 0.0; + 0.3330 anti-B*0 pi0 VVS_PWAVE 0.0 0.0 0.0 0.0 1.0 0.0; +Enddecay +# PDG Id = 515 +Decay B_2*0 + 0.3000 B+ pi- TSS; + 0.1500 B0 pi0 TSS; + 0.1600 B*+ pi- TVS_PWAVE 0.0 0.0 1.0 0.0 0.0 0.0; + 0.0800 B*0 pi0 TVS_PWAVE 0.0 0.0 1.0 0.0 0.0 0.0; + 0.1300 B*+ pi- pi0 PHSP; + 0.0600 B*0 pi+ pi- PHSP; + 0.0800 B+ pi- pi0 PHSP; + 0.0400 B0 pi+ pi- PHSP; +Enddecay +Decay anti-B_2*0 + 0.3000 B- pi+ TSS; + 0.1500 anti-B0 pi0 TSS; + 0.1600 B*- pi+ TVS_PWAVE 0.0 0.0 1.0 0.0 0.0 0.0; + 0.0800 anti-B*0 pi0 TVS_PWAVE 0.0 0.0 1.0 0.0 0.0 0.0; + 0.1300 B*- pi+ pi0 PHSP; + 0.0600 anti-B*0 pi- pi+ PHSP; + 0.0800 B- pi+ pi0 PHSP; + 0.0400 anti-B0 pi- pi+ PHSP; +Enddecay +# PDG Id = 10531 +Decay B_s0*0 + 0.5000 B+ K- PHSP; + 0.5000 B0 anti-K0 PHSP; +Enddecay +Decay anti-B_s0*0 + 0.5000 B- K+ PHSP; + 0.5000 anti-B0 K0 PHSP; +Enddecay +# PDG Id = 20533 Broad : S wave +Decay B'_s10 + 0.5000 B*+ K- VVS_PWAVE 1.0 0.0 0.0 0.0 0.0 0.0; + 0.5000 B*0 anti-K0 VVS_PWAVE 1.0 0.0 0.0 0.0 0.0 0.0; +Enddecay +Decay anti-B'_s10 + 0.5000 B*- K+ VVS_PWAVE 1.0 0.0 0.0 0.0 0.0 0.0; + 0.5000 anti-B*0 K0 VVS_PWAVE 1.0 0.0 0.0 0.0 0.0 0.0; +Enddecay +# PDG Id = 10533 Narrow : D wave +Decay B_s10 + 0.5000 B*+ K- VVS_PWAVE 0.0 0.0 0.0 0.0 1.0 0.0; + 0.5000 B*0 anti-K0 VVS_PWAVE 0.0 0.0 0.0 0.0 1.0 0.0; +Enddecay +Decay anti-B_s10 + 0.5000 B*- K+ VVS_PWAVE 0.0 0.0 0.0 0.0 1.0 0.0; + 0.5000 anti-B*0 K0 VVS_PWAVE 0.0 0.0 0.0 0.0 1.0 0.0; +Enddecay +# PDG Id = 535 Narrow : D wave +Decay B_s2*0 + 0.3000 B+ K- TSS; + 0.3000 B0 anti-K0 TSS; + 0.2000 B*+ K- TVS_PWAVE 0.0 0.0 1.0 0.0 0.0 0.0; + 0.2000 B*0 anti-K0 TVS_PWAVE 0.0 0.0 1.0 0.0 0.0 0.0; +Enddecay +Decay anti-B_s2*0 + 0.3000 B- K+ TSS; + 0.3000 anti-B0 K0 TSS; + 0.2000 B*- K+ TVS_PWAVE 0.0 0.0 1.0 0.0 0.0 0.0; + 0.2000 anti-B*0 K0 TVS_PWAVE 0.0 0.0 1.0 0.0 0.0 0.0; +Enddecay +# PDG Id = 543 +Decay B_c*+ + 1.0000 B_c+ gamma VSP_PWAVE; +Enddecay +Decay B_c*- + 1.0000 B_c- gamma VSP_PWAVE; +Enddecay +# PDG Id = 545 Narrow : D wave +Decay B_c2*+ + 0.3000 B0 D+ TSS; + 0.3000 B+ D0 TSS; + 0.2000 B*0 D+ TVS_PWAVE 0.0 0.0 1.0 0.0 0.0 0.0; + 0.2000 B*+ D0 TVS_PWAVE 0.0 0.0 1.0 0.0 0.0 0.0; +Enddecay +Decay B_c2*- + 0.3000 anti-B0 D- TSS; + 0.3000 B- anti-D0 TSS; + 0.2000 anti-B*0 D- TVS_PWAVE 0.0 0.0 1.0 0.0 0.0 0.0; + 0.2000 B*- anti-D0 TVS_PWAVE 0.0 0.0 1.0 0.0 0.0 0.0; +Enddecay +# PDG Id = 5114 +Decay Sigma_b*- + 1.0000 Lambda_b0 pi- PHSP; +Enddecay +Decay anti-Sigma_b*+ + 1.0000 anti-Lambda_b0 pi+ PHSP; +Enddecay +# PDG Id = 5224 +Decay Sigma_b*+ + 1.0000 Lambda_b0 pi+ PHSP; +Enddecay +Decay anti-Sigma_b*- + 1.0000 anti-Lambda_b0 pi- PHSP; +Enddecay +# PDG Id = 5214 +Decay Sigma_b*0 + 1.0000 Lambda_b0 pi0 PHSP; +Enddecay +Decay anti-Sigma_b*0 + 1.0000 anti-Lambda_b0 pi0 PHSP; +Enddecay +# PDG Id = 5314 +Decay Xi_b*- + 1.0000 Xi_b- gamma PHSP; +Enddecay +Decay anti-Xi_b*+ + 1.0000 anti-Xi_b+ gamma PHSP; +Enddecay +# PDG Id = 5324 +Decay Xi_b*0 + 1.0000 Xi_b0 gamma PHSP; +Enddecay +Decay anti-Xi_b*0 + 1.0000 anti-Xi_b0 gamma PHSP; +Enddecay +# PDG Id = 5334 +Decay Omega_b*- + 1.0000 Omega_b- gamma PHSP; +Enddecay +Decay anti-Omega_b*+ + 1.0000 anti-Omega_b+ gamma PHSP; +Enddecay +# PDG Id = 10541 +Decay B_c0*+ + 0.5000 B0 D+ PHSP; + 0.5000 B+ D0 PHSP; +Enddecay +Decay B_c0*- + 0.5000 anti-B0 D- PHSP; + 0.5000 B- anti-D0 PHSP; +Enddecay +# PDG Id = 10543 Narrow : D wave +Decay B_c1+ + 0.5000 B*0 D+ VVS_PWAVE 0.0 0.0 0.0 0.0 1.0 0.0; + 0.5000 B*+ D0 VVS_PWAVE 0.0 0.0 0.0 0.0 1.0 0.0; +Enddecay +Decay B_c1- + 0.5000 anti-B*0 D- VVS_PWAVE 0.0 0.0 0.0 0.0 1.0 0.0; + 0.5000 B*- anti-D0 VVS_PWAVE 0.0 0.0 0.0 0.0 1.0 0.0; +Enddecay +# PDG Id = 20543 Broad : S wave +Decay B'_c1+ + 0.5000 B*0 D+ VVS_PWAVE 1.0 0.0 0.0 0.0 0.0 0.0; + 0.5000 B*+ D0 VVS_PWAVE 1.0 0.0 0.0 0.0 0.0 0.0; +Enddecay +Decay B'_c1- + 0.5000 anti-B*0 D- VVS_PWAVE 1.0 0.0 0.0 0.0 0.0 0.0; + 0.5000 B*- anti-D0 VVS_PWAVE 1.0 0.0 0.0 0.0 0.0 0.0; +Enddecay + +# Excited charmed Baryons LHCb PR 3-05-2006 +Decay Xi_cc*++ + 0.08 e+ nu_e Xi_c+ PHSP ; + 0.08 mu+ nu_mu Xi_c+ PHSP ; +0.51 u anti-d s cu_0 PYTHIA 42; +0.25 u anti-d s cu_1 PYTHIA 42; +0.05 u anti-s s cu_0 PYTHIA 42; +0.03 u anti-s s cu_1 PYTHIA 42; +Enddecay + +Decay anti-Xi_cc*-- + 0.08 e- anti-nu_e anti-Xi_c- PHSP; + 0.08 mu- anti-nu_mu anti-Xi_c- PHSP; +0.51 anti-u d anti-s anti-cu_0 PYTHIA 42; +0.25 anti-u d anti-s anti-cu_0 PYTHIA 42; +0.05 anti-u s anti-s anti-cu_1 PYTHIA 42; +0.03 anti-u s anti-s anti-cu_1 PYTHIA 42; +Enddecay + +Decay Xi_cc++ + 0.08 e+ nu_e Xi_c+ PHSP ; + 0.08 mu+ nu_mu Xi_c+ PHSP ; +0.51 u anti-d s cu_0 PYTHIA 42; +0.25 u anti-d s cu_1 PYTHIA 42; +0.05 u anti-s s cu_0 PYTHIA 42; +0.03 u anti-s s cu_1 PYTHIA 42; +Enddecay + +Decay anti-Xi_cc-- + 0.08 e- anti-nu_e anti-Xi_c- PHSP; + 0.08 mu- anti-nu_mu anti-Xi_c- PHSP; +0.51 anti-u d anti-s anti-cu_0 PYTHIA 42; +0.25 anti-u d anti-s anti-cu_0 PYTHIA 42; +0.05 anti-u s anti-s anti-cu_1 PYTHIA 42; +0.03 anti-u s anti-s anti-cu_1 PYTHIA 42; +Enddecay + +Decay Xi_cc*+ + 0.08 e+ nu_e Xi_c0 PHSP; + 0.08 mu+ nu_mu Xi_c0 PHSP; +0.51 u anti-d s cd_0 PYTHIA 42; +0.25 u anti-d s cd_1 PYTHIA 42; +0.05 u anti-s s cd_0 PYTHIA 42; +0.03 u anti-s s cd_1 PYTHIA 42; +Enddecay + +Decay anti-Xi_cc*- + 0.08 e- anti-nu_e anti-Xi_c0 PHSP; + 0.08 mu- anti-nu_mu anti-Xi_c0 PHSP; +0.51 anti-u d anti-s anti-cd_0 PYTHIA 42; +0.25 anti-u d anti-s anti-cd_1 PYTHIA 42; +0.05 anti-u s anti-s anti-cd_0 PYTHIA 42; +0.03 anti-u s anti-s anti-cd_1 PYTHIA 42; +Enddecay + +Decay Xi_cc+ + 0.08 e+ nu_e Xi_c0 PHSP; + 0.08 mu+ nu_mu Xi_c0 PHSP; +0.51 u anti-d s cd_0 PYTHIA 42; +0.25 u anti-d s cd_1 PYTHIA 42; +0.05 u anti-s s cd_0 PYTHIA 42; +0.03 u anti-s s cd_1 PYTHIA 42; +Enddecay + +Decay anti-Xi_cc- + 0.08 e- anti-nu_e anti-Xi_c0 PHSP; + 0.08 mu- anti-nu_mu anti-Xi_c0 PHSP; +0.51 anti-u d anti-s anti-cd_0 PYTHIA 42; +0.25 anti-u d anti-s anti-cd_1 PYTHIA 42; +0.05 anti-u s anti-s anti-cd_0 PYTHIA 42; +0.03 anti-u s anti-s anti-cd_1 PYTHIA 42; +Enddecay + +Decay Omega_cc+ + 0.08 e+ nu_e Omega_c0 PHSP; + 0.08 mu+ nu_mu Omega_c0 PHSP; +0.51 u anti-d s cs_0 PYTHIA 42; +0.25 u anti-d s cs_1 PYTHIA 42; +0.05 u anti-s s cs_0 PYTHIA 42; +0.03 u anti-s s cs_1 PYTHIA 42; +Enddecay + +Decay anti-Omega_cc- + 0.08 e- anti-nu_e anti-Omega_c0 PHSP; + 0.08 mu- anti-nu_mu anti-Omega_c0 PHSP; +0.51 anti-u d anti-s anti-cs_0 PYTHIA 42; +0.25 anti-u d anti-s anti-cs_1 PYTHIA 42; +0.05 anti-u s anti-s anti-cs_0 PYTHIA 42; +0.03 anti-u s anti-s anti-cs_1 PYTHIA 42; +Enddecay + +Decay Omega_cc*+ + 0.08 e+ nu_e Omega_c0 PHSP; + 0.08 mu+ nu_mu Omega_c0 PHSP; +0.51 u anti-d s cs_0 PYTHIA 42; +0.25 u anti-d s cs_1 PYTHIA 42; +0.05 u anti-s s cs_0 PYTHIA 42; +0.03 u anti-s s cs_1 PYTHIA 42; +Enddecay + +Decay anti-Omega_cc*- + 0.08 e- anti-nu_e anti-Omega_c0 PHSP; + 0.08 mu- anti-nu_mu anti-Omega_c0 PHSP; +0.51 anti-u d anti-s anti-cs_0 PYTHIA 42; +0.25 anti-u d anti-s anti-cs_1 PYTHIA 42; +0.05 anti-u s anti-s anti-cs_0 PYTHIA 42; +0.03 anti-u s anti-s anti-cs_1 PYTHIA 42; +Enddecay + +Decay K_L0 +#0.202464226 pi+ e- anti-nu_e PHSP; #[New mode added] #[Reconstructed PDG2011] +#0.202464226 pi- e+ nu_e PHSP; #[New mode added] #[Reconstructed PDG2011] +#0.135033299 pi+ mu- anti-nu_mu PHSP; #[New mode added] #[Reconstructed PDG2011] +#0.135033299 pi- mu+ nu_mu PHSP; #[New mode added] #[Reconstructed PDG2011] +#0.000025738 pi0 pi+ e- anti-nu_e PHSP; #[New mode added] #[Reconstructed PDG2011] +#0.000025738 pi0 pi- e+ nu_e PHSP; #[New mode added] #[Reconstructed PDG2011] +#0.000006205 pi+ e- anti-nu_e e+ e- PHSP; #[New mode added] #[Reconstructed PDG2011] +#0.000006205 pi- e+ nu_e e+ e- PHSP; #[New mode added] #[Reconstructed PDG2011] +#0.194795855 pi0 pi0 pi0 PHSP; #[New mode added] #[Reconstructed PDG2011] +#0.125231606 pi+ pi- pi0 PHSP; #[New mode added] #[Reconstructed PDG2011] +#0.001880711 pi+ e- anti-nu_e gamma PHSP; #[New mode added] #[Reconstructed PDG2011] +#0.001880711 pi- e+ nu_e gamma PHSP; #[New mode added] #[Reconstructed PDG2011] +#0.000277023 pi+ mu- anti-nu_mu gamma PHSP; #[New mode added] #[Reconstructed PDG2011] +#0.000277023 pi- mu+ nu_mu gamma PHSP; #[New mode added] #[Reconstructed PDG2011] +#0.000040995 pi+ pi- gamma PHSP; #[New mode added] #[Reconstructed PDG2011] +#0.000001262 pi0 gamma gamma PHSP; #[New mode added] #[Reconstructed PDG2011] +#0.000000016 pi0 gamma e+ e- PHSP; #[New mode added] #[Reconstructed PDG2011] +#0.000545653 gamma gamma PHSP; #[New mode added] #[Reconstructed PDG2011] +#0.000009265 e+ e- gamma PHSP; #[New mode added] #[Reconstructed PDG2011] +#0.000000355 mu+ mu- gamma PHSP; #[New mode added] #[Reconstructed PDG2011] +#0.000000584 e+ e- gamma gamma PHSP; #[New mode added] #[Reconstructed PDG2011] +#0.000000007 mu+ mu- gamma gamma PHSP; #[New mode added] #[Reconstructed PDG2011] +Enddecay + +End diff --git a/MC/config/PWGHF/pythia8/decayer/force_hadronic_Xic0_Omegac.cfg b/MC/config/PWGHF/pythia8/decayer/force_hadronic_Xic0_Omegac.cfg new file mode 100644 index 000000000..457b52847 --- /dev/null +++ b/MC/config/PWGHF/pythia8/decayer/force_hadronic_Xic0_Omegac.cfg @@ -0,0 +1,44 @@ +################################################### +### author: Tiantian Cheng (tiantian.cheng@cern.ch) +### last update: March 2025 +################################################### + +Init:showChangedParticleData = on + +4332:tau0 = 0.0803 # Omega_c0 +4132:tau0 = 0.0455 # Xi_c0 + +4332:onMode = off +4132:onMode = off + +# Omega_c0 (4332) +4332:oneChannel = 1 0.4 0 3334 211 # Omega- pi+ +4332:addChannel = 1 0.4 0 3312 211 # Xi- pi+ +4332:addChannel = 1 0.2 0 3312 321 # Xi- K+ + +# Xi_c0 (4132) +4132:oneChannel = 1 0.4 0 3312 211 # Xi- pi+ +4132:addChannel = 1 0.4 0 3334 321 # Omega- K+ +4132:addChannel = 1 0.2 0 3312 321 # Xi- K+ + +# Xi- -> Lambda pi- +3312:onMode = off +3312:onIfAll = 3122 -211 + +# Omega- -> Lambda K- +3334:onMode = off +3334:onIfAll = 3122 -321 + +# Lambda -> p pi- +3122:onMode = off +3122:onIfAll = 2212 -211 + +# Omega_c0 +4332:onIfMatch = 3334 211 +4332:onIfMatch = 3312 211 +4332:onIfMatch = 3334 321 +4332:onIfMatch = 3312 321 + +# Xi_c0 +4132:onIfMatch = 3312 211 +4132:onIfMatch = 3334 321 diff --git a/MC/config/PWGHF/pythia8/decayer/force_hadronic_charmbaryon.cfg b/MC/config/PWGHF/pythia8/decayer/force_hadronic_charmbaryon.cfg new file mode 100644 index 000000000..9e5e79e45 --- /dev/null +++ b/MC/config/PWGHF/pythia8/decayer/force_hadronic_charmbaryon.cfg @@ -0,0 +1,88 @@ +# Decay configuration taken from MC/config/PWGHF/pythia8/generator/pythia8_charmhadronic_with_decays_Mode2_pp_ref.cfg +Init:showChangedParticleData = on +4332:tau0 = 0.0803 # OmegaC +4132:tau0 = 0.0455 # Xic0 + +# switch off all decay channels +4232:onMode = off +4332:onMode = off +4132:onMode = off + +## Xic decays +### Ξc+ -> p K- π+ (35%) +4232:oneChannel = 1 0.17500 0 2212 -321 211 ### Ξc+ -> p K- π+ 6.18e-3 +4232:addChannel = 1 0.17500 0 2212 -313 ### Ξc+ -> p antiK*0(892) +### Ξc+ -> Ξ- π+ π+ (35%) (set the same as Ξc+ -> p K- π+) +4232:addChannel = 1 0.35000 0 3312 211 211 ### Ξc+ -> Ξ- π+ π+ 2.86% +### Ξc+ -> p φ (10%) +4232:addChannel = 1 0.10000 0 2212 333 ### Ξc+ -> p φ +### Ξc+ -> sigma+ π+ π- (10%) +4232:addChannel = 1 0.12500 0 3222 -211 211 ### Ξc+ -> sigma+ π- π+ 1.37% +### Ξc+ -> Ξ*0 π+ (10%) +4232:addChannel = 1 0.12500 0 3324 211 + +### Ξc+ -> p K- π+ +4232:onIfMatch = 2212 321 211 +### Ξc+ -> p antiK*0(892) +4232:onIfMatch = 2212 313 +### Ξc+ -> p φ +4232:onIfMatch = 2212 333 +### Ξc+ -> sigma+ π+ π- (10%) +4232:onIfMatch = 3222 211 211 +### Ξc+ -> Ξ*0 π+, Ξ*0 -> Ξ- π+ +4232:onIfMatch = 3324 211 +### Ξc+ -> Ξ- π+ π+ +4232:onIfMatch = 3312 211 211 + +## Xic0 decays +### add Xic0 decays absent in PYTHIA8 decay table +4132:oneChannel = 1 0.0143 0 3312 211 ### Xi_c()0 --> Xi- pi+ 0.01432524810113947 + +### Xic0 -> Xi- pi+ +4132:onIfMatch = 3312 211 +# Matching Exclusive Decay Channels: +# ------------------------------------------------------- +# Xi_c()0 --> Xi- pi+ 0.01432524810113947 +# -> PDG Codes: 3312, 211 +# Xi_c()0 --> Xi- pi+ pi+ pi- 0.04775082700379833 +# -> PDG Codes: 3312, 211, 211, -211 + +## OmegaC decays +### add custom OmegaC decays absent in PYTHIA8 decay table +4332:oneChannel = 1 0.5 0 3334 211 +4332:addChannel = 1 0.5 0 3312 211 + +### Omega_c -> Omega pi +4332:onIfMatch = 3334 211 +# Matching Exclusive Decay Channels: +# ------------------------------------------------------- +# Omega_c()0 --> Omega- pi+ None +# -> PDG Codes: 3334, 211 +# Omega_c()0 --> Omega- pi+ pi0 1.79939678284182 +# -> PDG Codes: 3334, 211, 111 +# Omega_c()0 --> Omega- pi- 2 pi+ 0.30954954954955 +# -> PDG Codes: 3334, -211, [2], 211 + +### Omega_c -> Xi pi +4332:onIfMatch = 3312 211 +# Matching Exclusive Decay Channels: +# ------------------------------------------------------- +# Omega_c()0 --> Xi- Kbar0 pi+ 2.12 +# -> PDG Codes: 3312, -311, 211 +# Omega_c()0 --> Xi- K- 2 pi+ 0.625932203389831 +# -> PDG Codes: 3312, -321, [2], 211 + +## Allow the decay of resonances in the decay chain +### K*0(892) -> K- π+ +313:onMode = off +313:onIfAll = 321 211 +### φ -> K+ K- +333:onMode = off +333:onIfAll = 321 321 +### for Xic0 -> pi Xi -> pi pi Lambda -> pi pi pi p +### and Omega_c -> pi Xi -> pi pi Lambda -> pi pi pi p +3312:onMode = off +3312:onIfAll = 3122 -211 +### for Omega_c -> pi Omega -> pi K Lambda -> pi K pi p +3334:onMode = off +3334:onIfAll = 3122 -321 diff --git a/MC/config/PWGHF/pythia8/decayer/geant4_externaldecayer_charmbaryon.in b/MC/config/PWGHF/pythia8/decayer/geant4_externaldecayer_charmbaryon.in new file mode 100644 index 000000000..46b4def18 --- /dev/null +++ b/MC/config/PWGHF/pythia8/decayer/geant4_externaldecayer_charmbaryon.in @@ -0,0 +1,68 @@ + +/control/verbose 2 +/mcVerbose/all 1 +/mcVerbose/geometryManager 1 +/mcVerbose/opGeometryManager 1 +/mcTracking/loopVerbose 1 +/mcVerbose/composedPhysicsList 2 +/mcVerbose/runAction 2 # For looping thresholds control +#/tracking/verbose 1 +#//control/cout/ignoreThreadsExcept 0 + +/mcPhysics/rangeCuts 0.001 mm +/mcRegions/setRangePrecision 5 +/mcTracking/skipNeutrino true +/mcDet/setIsMaxStepInLowDensityMaterials true +/mcDet/setMaxStepInLowDensityMaterials 10 m +/mcMagField/setConstDistance 1 mm +/mcDet/setIsZeroMagField true +/mcControl/useRootRandom true # couple G4 random seed to gRandom + +# optical + +/process/optical/verbose 0 +/process/optical/processActivation Scintillation 0 +/process/optical/processActivation OpWLS 0 +/process/optical/processActivation OpMieHG 0 +/process/optical/cerenkov/setTrackSecondariesFirst false +/mcMagField/stepperType NystromRK4 + +# PAI for TRD +# Geant4 VMC >= v3.2 +/mcPhysics/emModel/setEmModel PAI +/mcPhysics/emModel/setRegions TRD_Gas-mix +/mcPhysics/emModel/setParticles all +/mcPrimaryGenerator/skipUnknownParticles true # don't crash when seeing unknown ion etc. (issue warning) + +# +# Precise Msc for EMCAL +# +# Geant4 VMC >= v3.2 +/mcPhysics/emModel/setEmModel SpecialUrbanMsc +/mcPhysics/emModel/setRegions EMC_Lead$ EMC_Scintillator$ +/mcPhysics/emModel/setParticles e- e+ + +# combined transportation + Msc mode is currently broken for ALICE (Geant 10.2.0) +/process/em/transportationWithMsc Disabled + +# +# Adding extra lines for fixing tracking bias +# +/mcMagField/setDeltaIntersection 1.0e-05 mm +/mcMagField/setMinimumEpsilonStep 0.5e-05 +/mcMagField/setMaximumEpsilonStep 1.0e-05 +/mcMagField/printParameters + +# Change default parameters for killing looping particles +# +/mcPhysics/useHighLooperThresholds +/mcRun/setLooperThresholdImportantEnergy 100. MeV + +# Define media with the INCLXX physics list; here basically in all ITS media +#/mcVerbose/biasingConfigurationManager 3 +/mcPhysics/biasing/setModel inclxx +/mcPhysics/biasing/setRegions ITS_AIR$ ITS_WATER$ ITS_COPPER$ ITS_KAPTON(POLYCH2)$ ITS_GLUE_IBFPC$ ITS_CERAMIC$ ITS_K13D2U2k$ ITS_K13D2U120$ ITS_F6151B05M$ ITS_M60J3K$ ITS_M55J6K$ ITS_FGS003$ ITS_CarbonFleece$ ITS_PEEKCF30$ ITS_GLUE$ ITS_ALUMINUM$ ITS_INOX304$ ALPIDE_METALSTACK$ ALPIDE_SI$ +/mcPhysics/biasing/setParticles proton neutron pi+ pi- + +# external decayer +/mcPhysics/setExtDecayerSelection omega_c0 anti_omega_c0 xi_c0 anti_xi_c0 xi_c+ xi_c- diff --git a/MC/config/PWGHF/pythia8/decayer/geant4_externaldecayer_omegac_xic.in b/MC/config/PWGHF/pythia8/decayer/geant4_externaldecayer_omegac_xic.in new file mode 100644 index 000000000..40fea08d1 --- /dev/null +++ b/MC/config/PWGHF/pythia8/decayer/geant4_externaldecayer_omegac_xic.in @@ -0,0 +1,68 @@ + +/control/verbose 2 +/mcVerbose/all 1 +/mcVerbose/geometryManager 1 +/mcVerbose/opGeometryManager 1 +/mcTracking/loopVerbose 1 +/mcVerbose/composedPhysicsList 2 +/mcVerbose/runAction 2 # For looping thresholds control +#/tracking/verbose 1 +#//control/cout/ignoreThreadsExcept 0 + +/mcPhysics/rangeCuts 0.001 mm +/mcRegions/setRangePrecision 5 +/mcTracking/skipNeutrino true +/mcDet/setIsMaxStepInLowDensityMaterials true +/mcDet/setMaxStepInLowDensityMaterials 10 m +/mcMagField/setConstDistance 1 mm +/mcDet/setIsZeroMagField true +/mcControl/useRootRandom true # couple G4 random seed to gRandom + +# optical + +/process/optical/verbose 0 +/process/optical/processActivation Scintillation 0 +/process/optical/processActivation OpWLS 0 +/process/optical/processActivation OpMieHG 0 +/process/optical/cerenkov/setTrackSecondariesFirst false +/mcMagField/stepperType NystromRK4 + +# PAI for TRD +# Geant4 VMC >= v3.2 +/mcPhysics/emModel/setEmModel PAI +/mcPhysics/emModel/setRegions TRD_Gas-mix +/mcPhysics/emModel/setParticles all +/mcPrimaryGenerator/skipUnknownParticles true # don't crash when seeing unknown ion etc. (issue warning) + +# +# Precise Msc for EMCAL +# +# Geant4 VMC >= v3.2 +/mcPhysics/emModel/setEmModel SpecialUrbanMsc +/mcPhysics/emModel/setRegions EMC_Lead$ EMC_Scintillator$ +/mcPhysics/emModel/setParticles e- e+ + +# combined transportation + Msc mode is currently broken for ALICE (Geant 10.2.0) +/process/em/transportationWithMsc Disabled + +# +# Adding extra lines for fixing tracking bias +# +/mcMagField/setDeltaIntersection 1.0e-05 mm +/mcMagField/setMinimumEpsilonStep 0.5e-05 +/mcMagField/setMaximumEpsilonStep 1.0e-05 +/mcMagField/printParameters + +# Change default parameters for killing looping particles +# +/mcPhysics/useHighLooperThresholds +/mcRun/setLooperThresholdImportantEnergy 100. MeV + +# Define media with the INCLXX physics list; here basically in all ITS media +#/mcVerbose/biasingConfigurationManager 3 +/mcPhysics/biasing/setModel inclxx +/mcPhysics/biasing/setRegions ITS_AIR$ ITS_WATER$ ITS_COPPER$ ITS_KAPTON(POLYCH2)$ ITS_GLUE_IBFPC$ ITS_CERAMIC$ ITS_K13D2U2k$ ITS_K13D2U120$ ITS_F6151B05M$ ITS_M60J3K$ ITS_M55J6K$ ITS_FGS003$ ITS_CarbonFleece$ ITS_PEEKCF30$ ITS_GLUE$ ITS_ALUMINUM$ ITS_INOX304$ ALPIDE_METALSTACK$ ALPIDE_SI$ +/mcPhysics/biasing/setParticles proton neutron pi+ pi- + +# external decayer +/mcPhysics/setExtDecayerSelection omega_c0 anti_omega_c0 xi_c0 anti_xi_c0 diff --git a/MC/config/PWGHF/pythia8/generator/pythia8_HFe_Mode2.cfg b/MC/config/PWGHF/pythia8/generator/pythia8_HFe_Mode2.cfg new file mode 100644 index 000000000..4f4dcb7bf --- /dev/null +++ b/MC/config/PWGHF/pythia8/generator/pythia8_HFe_Mode2.cfg @@ -0,0 +1,97 @@ +### authors: Fabrizio Grosa (fabrizio.grosa@cern.ch) +### Grazia Luparello (Grazia.Luparello@cern.ch) +### Antonio Palasciano (antonio.palasciano@cern.ch) +### Jonghan Park (jonghan@cern.ch) +### electrons from heavy-flavour hadrons and from light neutral mesons +### last update: August 2025 + +### beams +Beams:idA 2212 # proton +Beams:idB 2212 # proton +Beams:eCM 13600. # GeV + +### processes +SoftQCD:inelastic on # all inelastic processes + +### decays +ParticleDecays:limitTau0 on +ParticleDecays:tau0Max 10. + +### switching on Pythia Mode2 +ColourReconnection:mode 1 +ColourReconnection:allowDoubleJunRem off +ColourReconnection:m0 0.3 +ColourReconnection:allowJunctions on +ColourReconnection:junctionCorrection 1.20 +ColourReconnection:timeDilationMode 2 +ColourReconnection:timeDilationPar 0.18 +StringPT:sigma 0.335 +StringZ:aLund 0.36 +StringZ:bLund 0.56 +StringFlav:probQQtoQ 0.078 +StringFlav:ProbStoUD 0.2 +StringFlav:probQQ1toQQ0join 0.0275,0.0275,0.0275,0.0275 +MultiPartonInteractions:pT0Ref 2.15 +BeamRemnants:remnantMode 1 +BeamRemnants:saturation 5 + +# Correct decay lengths (wrong in PYTHIA8 decay table) +# Lb +5122:tau0 = 0.4390 +# Xic0 +4132:tau0 = 0.0455 +# OmegaC +4332:tau0 = 0.0803 + + +### switch off all decay channels +111:onMode = off +221:onMode = off + +411:onMode = off +421:onMode = off +431:onMode = off +4122:onMode = off +4132:onMode = off +4232:onMode = off +4332:onMode = off + +511:onMode = off +521:onMode = off +531:onMode = off +5122:onMode = off +5132:onMode = off +5232:onMode = off +5332:onMode = off + +###Semimuonic decays of charm + +### D+/- -> e + X +411:onIfAny = 11 +### D0 -> e + X +421:onIfAny = 11 +### D_s -> e + X +431:onIfAny = 11 +### Lambda_c -> e + X +4122:onIfAny = 11 +### Xsi0_c -> e + X +4132:onIfAny = 11 +### Xsi+_c -> e + X +4232:onIfAny = 11 +### Omega_c -> e + X +4332:onIfAny = 11 + +### B0 -> e + X +511:onIfAny = 11 +### B+/- -> e + X +521:onIfAny = 11 +### B_s -> e + X +531:onIfAny = 11 +### Lambda_b -> e + X +5122:onIfAny = 11 +### Xsi_b -> e + X +5132:onIfAny = 11 +### Xsi0_b -> e + X +5232:onIfAny = 11 +### Omega_b -> e + X +5332:onIfAny = 11 diff --git a/MC/config/PWGHF/pythia8/generator/pythia8_HFe_Mode2_pp_ref.cfg b/MC/config/PWGHF/pythia8/generator/pythia8_HFe_Mode2_pp_ref.cfg new file mode 100644 index 000000000..c13834cd5 --- /dev/null +++ b/MC/config/PWGHF/pythia8/generator/pythia8_HFe_Mode2_pp_ref.cfg @@ -0,0 +1,97 @@ +### authors: Fabrizio Grosa (fabrizio.grosa@cern.ch) +### Grazia Luparello (Grazia.Luparello@cern.ch) +### Antonio Palasciano (antonio.palasciano@cern.ch) +### Jonghan Park (jonghan@cern.ch) +### electrons from heavy-flavour hadrons and from light neutral mesons +### last update: August 2025 + +### beams +Beams:idA 2212 # proton +Beams:idB 2212 # proton +Beams:eCM 5360. # GeV + +### processes +SoftQCD:inelastic on # all inelastic processes + +### decays +ParticleDecays:limitTau0 on +ParticleDecays:tau0Max 10. + +### switching on Pythia Mode2 +ColourReconnection:mode 1 +ColourReconnection:allowDoubleJunRem off +ColourReconnection:m0 0.3 +ColourReconnection:allowJunctions on +ColourReconnection:junctionCorrection 1.20 +ColourReconnection:timeDilationMode 2 +ColourReconnection:timeDilationPar 0.18 +StringPT:sigma 0.335 +StringZ:aLund 0.36 +StringZ:bLund 0.56 +StringFlav:probQQtoQ 0.078 +StringFlav:ProbStoUD 0.2 +StringFlav:probQQ1toQQ0join 0.0275,0.0275,0.0275,0.0275 +MultiPartonInteractions:pT0Ref 2.15 +BeamRemnants:remnantMode 1 +BeamRemnants:saturation 5 + +# Correct decay lengths (wrong in PYTHIA8 decay table) +# Lb +5122:tau0 = 0.4390 +# Xic0 +4132:tau0 = 0.0455 +# OmegaC +4332:tau0 = 0.0803 + + +### switch off all decay channels +111:onMode = off +221:onMode = off + +411:onMode = off +421:onMode = off +431:onMode = off +4122:onMode = off +4132:onMode = off +4232:onMode = off +4332:onMode = off + +511:onMode = off +521:onMode = off +531:onMode = off +5122:onMode = off +5132:onMode = off +5232:onMode = off +5332:onMode = off + +###Semimuonic decays of charm + +### D+/- -> e + X +411:onIfAny = 11 +### D0 -> e + X +421:onIfAny = 11 +### D_s -> e + X +431:onIfAny = 11 +### Lambda_c -> e + X +4122:onIfAny = 11 +### Xsi0_c -> e + X +4132:onIfAny = 11 +### Xsi+_c -> e + X +4232:onIfAny = 11 +### Omega_c -> e + X +4332:onIfAny = 11 + +### B0 -> e + X +511:onIfAny = 11 +### B+/- -> e + X +521:onIfAny = 11 +### B_s -> e + X +531:onIfAny = 11 +### Lambda_b -> e + X +5122:onIfAny = 11 +### Xsi_b -> e + X +5132:onIfAny = 11 +### Xsi0_b -> e + X +5232:onIfAny = 11 +### Omega_b -> e + X +5332:onIfAny = 11 diff --git a/MC/config/PWGHF/pythia8/generator/pythia8_Mode2_noforcedecays.cfg b/MC/config/PWGHF/pythia8/generator/pythia8_Mode2_noforcedecays.cfg new file mode 100644 index 000000000..8109ace4c --- /dev/null +++ b/MC/config/PWGHF/pythia8/generator/pythia8_Mode2_noforcedecays.cfg @@ -0,0 +1,39 @@ +### authors: Fabrizio Grosa (fabrizio.grosa@cern.ch) + +### beams +Beams:idA 2212 # proton +Beams:idB 2212 # proton +Beams:eCM 13600. # GeV + +### processes +SoftQCD:inelastic on # all inelastic processes + +### decays +ParticleDecays:limitTau0 on +ParticleDecays:tau0Max 10. + +### switching on Pythia Mode2 +ColourReconnection:mode 1 +ColourReconnection:allowDoubleJunRem off +ColourReconnection:m0 0.3 +ColourReconnection:allowJunctions on +ColourReconnection:junctionCorrection 1.20 +ColourReconnection:timeDilationMode 2 +ColourReconnection:timeDilationPar 0.18 +StringPT:sigma 0.335 +StringZ:aLund 0.36 +StringZ:bLund 0.56 +StringFlav:probQQtoQ 0.078 +StringFlav:ProbStoUD 0.2 +StringFlav:probQQ1toQQ0join 0.0275,0.0275,0.0275,0.0275 +MultiPartonInteractions:pT0Ref 2.15 +BeamRemnants:remnantMode 1 +BeamRemnants:saturation 5 + +# Correct decay lengths (wrong in PYTHIA8 decay table) +# Lb +5122:tau0 = 0.4390 +# Xic0 +4132:tau0 = 0.0455 +# OmegaC +4332:tau0 = 0.0803 diff --git a/MC/config/PWGHF/pythia8/generator/pythia8_NonHfe.cfg b/MC/config/PWGHF/pythia8/generator/pythia8_NonHfe.cfg new file mode 100644 index 000000000..3feaa6585 --- /dev/null +++ b/MC/config/PWGHF/pythia8/generator/pythia8_NonHfe.cfg @@ -0,0 +1,25 @@ +### authors: Rashi Gupta (rashi.gupta@cern.ch) +### authors: Ravindra Singh (ravindra.singh@cern.ch) +### electrons from pi0 and eta enhancement + +### beams +Beams:idA 2212 # proton +Beams:idB 2212 # proton +Beams:eCM 13600. # GeV + +### processes + +ProcessLevel:all = off + +### decays +ParticleDecays:limitTau0 on +ParticleDecays:tau0Max 10. +### processes + + +### switch off all decay channels +111:onMode = off +221:onMode = off + +111:onIfAny = 11 # pi0 -> e+ e- gamma +221:onIfAny = 11 # eta -> e+ e- gamma diff --git a/MC/config/PWGHF/pythia8/generator/pythia8_beautyhadronic_with_BtoDK_Mode2.cfg b/MC/config/PWGHF/pythia8/generator/pythia8_beautyhadronic_with_BtoDK_Mode2.cfg new file mode 100644 index 000000000..4150664af --- /dev/null +++ b/MC/config/PWGHF/pythia8/generator/pythia8_beautyhadronic_with_BtoDK_Mode2.cfg @@ -0,0 +1,183 @@ +### authors: Fabrizio Grosa (fabrizio.grosa@cern.ch) +### Cristina Terrevoli (cristina.terrevoli@cern.ch) +### Fabio Catalano (fabio.catalano@cern.ch) +### last update: November 2023 + +### beams +Beams:idA 2212 # proton +Beams:idB 2212 # proton +Beams:eCM 13600. # GeV + +### processes +SoftQCD:inelastic on # all inelastic processes + +### decays +ParticleDecays:limitTau0 on +ParticleDecays:tau0Max 10. + +### switching on Pythia Mode2 +ColourReconnection:mode 1 +ColourReconnection:allowDoubleJunRem off +ColourReconnection:m0 0.3 +ColourReconnection:allowJunctions on +ColourReconnection:junctionCorrection 1.20 +ColourReconnection:timeDilationMode 2 +ColourReconnection:timeDilationPar 0.18 +StringPT:sigma 0.335 +StringZ:aLund 0.36 +StringZ:bLund 0.56 +StringFlav:probQQtoQ 0.078 +StringFlav:ProbStoUD 0.2 +StringFlav:probQQ1toQQ0join 0.0275,0.0275,0.0275,0.0275 +MultiPartonInteractions:pT0Ref 2.15 +BeamRemnants:remnantMode 1 +BeamRemnants:saturation 5 + +# Correct decay lengths (wrong in PYTHIA8 decay table) +# Lb +5122:tau0 = 0.4390 +# Xic0 +4132:tau0 = 0.0455 +# OmegaC +4332:tau0 = 0.0803 + +### Force golden charm hadrons decay modes for D2H studies +### add D0 decays absent in PYTHIA8 decay table and set BRs from PDG for other +421:oneChannel = 1 0.0389 0 -321 211 +421:addChannel = 1 0.00389 0 -321 211 111 +### add D+ decays absent in PYTHIA8 decay table and set BRs from PDG for other +411:oneChannel = 1 0.0752 0 -321 211 211 +411:addChannel = 1 0.0104 0 -313 211 +411:addChannel = 1 0.0156 0 311 211 +411:addChannel = 1 0.0752 0 333 211 # to have the same amount of D+->KKpi and D+->Kpipi +## add Lc decays absent in PYTHIA8 decay table and set BRs from PDG for other +4122:oneChannel = 1 0.0196 100 2212 -313 +4122:addChannel = 1 0.0108 100 2224 -321 +4122:addChannel = 1 0.022 100 102134 211 +4122:addChannel = 1 0.035 0 2212 -321 211 +4122:addChannel = 1 0.0159 0 2212 311 +### add Xic+ decays absent in PYTHIA8 decay table +4232:addChannel = 1 0.2 0 2212 -313 +4232:addChannel = 1 0.2 0 2212 -321 211 +4232:addChannel = 1 0.2 0 3324 211 +4232:addChannel = 1 0.2 0 3312 211 211 +### add Xic0 decays absent in PYTHIA8 decay table +4132:addChannel = 1 0.0143 0 3312 211 +### add OmegaC decays absent in PYTHIA8 decay table +4332:addChannel = 1 0.5 0 3334 211 +4332:addChannel = 1 0.5 0 3312 211 + +### K* -> K pi +313:onMode = off +313:onIfAll = 321 211 +### for Ds -> Phi pi+ +333:onMode = off +333:onIfAll = 321 321 +### for D0 -> rho0 pi+ k- +113:onMode = off +113:onIfAll = 211 211 +### for Lambda_c -> Delta++ K- +2224:onMode = off +2224:onIfAll = 2212 211 +### for Lambda_c -> Lambda(1520) K- +102134:onMode = off +102134:onIfAll = 2212 321 +### for Xic0 -> pi Xi -> pi pi Lambda -> pi pi pi p +### and Omega_c -> pi Xi -> pi pi Lambda -> pi pi pi p +3312:onMode = off +3312:onIfAll = 3122 -211 +3122:onMode = off +3122:onIfAll = 2212 -211 +### for Omega_c -> pi Omega -> pi K Lambda -> pi K pi p +3334:onMode = off +3334:onIfAll = 3122 -321 + +### switch off all decay channels +411:onMode = off +421:onMode = off +431:onMode = off +4122:onMode = off +4232:onMode = off +4132:onMode = off +443:onMode = off +4332:onMode = off +511:onMode = off +521:onMode = off +531:onMode = off +5122:onMode = off + +### D0 -> K pi +421:onIfMatch = 321 211 +### D0 -> K pi pi0 +421:onIfMatch = 321 211 111 + +### D+/- -> K pi pi +411:onIfMatch = 321 211 211 +### D+/- -> K* pi +411:onIfMatch = 313 211 +### D+/- -> phi pi +411:onIfMatch = 333 211 + +### D_s -> K K* +431:onIfMatch = 321 313 +### D_s -> Phi pi +431:onIfMatch = 333 211 + +### Lambda_c -> p K* +4122:onIfMatch = 2212 313 +### Lambda_c -> Delta K +4122:onIfMatch = 2224 321 +### Lambda_c -> Lambda(1520) pi +4122:onIfMatch = 102134 211 +### Lambda_c -> p K pi +4122:onIfMatch = 2212 321 211 +### Lambda_c -> pK0s +4122:onIfMatch = 2212 311 + +### Xic+ -> pK*0 +4232:onIfMatch = 2212 313 +### Xic+ -> p K- pi+ +4232:onIfMatch = 2212 321 211 +### Xic+ -> Xi*0 pi+, Xi*->Xi- pi+ +4232:onIfMatch = 3324 211 +### Xic+ -> Xi- pi+ pi+ +4232:onIfMatch = 3312 211 211 + +### Xic0 -> Xi- pi+ +4132:onIfMatch = 3312 211 + +### Omega_c -> Omega pi +4332:onIfMatch = 3334 211 +### Omega_c -> Xi pi +4332:onIfMatch = 3312 211 + +### Force also golden beauty hadrons decay modes for D2H studies +### add B0 decays +511:oneChannel = 1 0.5 0 -411 211 +511:addChannel = 1 0.5 0 -411 321 +### add B+ decays +521:oneChannel = 1 0.5 0 -421 211 +521:addChannel = 1 0.5 0 -421 321 +### add Bs decays +531:oneChannel = 1 0.5 0 -431 211 +531:addChannel = 1 0.5 0 -431 321 +### add Lb decays +5122:oneChannel = 1 0.5 0 4122 -211 +5122:addChannel = 1 0.5 0 4122 -321 + +### B0 -> D pi +511:onIfMatch = 411 211 +### B0 -> D K +511:onIfMatch = 411 321 +### B+ -> D0 pi +521:onIfMatch = 421 211 +### B+ -> D0 K +521:onIfMatch = 421 321 +### Bs -> Ds pi +531:onIfMatch = 431 211 +### Bs -> Ds rho +531:onIfMatch = 431 321 +### Lb -> Lc pi +5122:onIfMatch = 4122 211 +### Lb -> Lc K +5122:onIfMatch = 4122 321 diff --git a/MC/config/PWGHF/pythia8/generator/pythia8_bminus_CRmode2.cfg b/MC/config/PWGHF/pythia8/generator/pythia8_bminus_CRmode2.cfg new file mode 100644 index 000000000..285f42a79 --- /dev/null +++ b/MC/config/PWGHF/pythia8/generator/pythia8_bminus_CRmode2.cfg @@ -0,0 +1,81 @@ +### beams +Beams:idA 2212 # proton +Beams:idB 2212 # proton +Beams:eCM 13600. # GeV + +### processes +SoftQCD:inelastic on # all inelastic processes + +### decays +ParticleDecays:limitTau0 on +ParticleDecays:tau0Max 10. + +### switching on Pythia Mode2 +ColourReconnection:mode 1 +ColourReconnection:allowDoubleJunRem off +ColourReconnection:m0 0.3 +ColourReconnection:allowJunctions on +ColourReconnection:junctionCorrection 1.20 +ColourReconnection:timeDilationMode 2 +ColourReconnection:timeDilationPar 0.18 +StringPT:sigma 0.335 +StringZ:aLund 0.36 +StringZ:bLund 0.56 +StringFlav:probQQtoQ 0.078 +StringFlav:ProbStoUD 0.2 +StringFlav:probQQ1toQQ0join 0.0275,0.0275,0.0275,0.0275 +MultiPartonInteractions:pT0Ref 2.15 +BeamRemnants:remnantMode 1 +BeamRemnants:saturation 5 +BeamRemnants:allowBeamJunction = off +BeamRemnants:beamJunction = off +ColourReconnection:allowDiquarkJunctionCR = off + +# Correct decay lengths +# B+ +521:tau0 = 0.4914 # PDG: 1.638 ps -> c*tau = 0.4914 mm + +## B+ (521) decay modes – at least 2 nucleons in the final states +521:onMode = off +521:oneChannel = 1 3e-07 0 -2112 -2112 111 2112 2212 +521:addChannel = 1 3e-07 0 -3122 -2212 213 2112 2212 +521:addChannel = 1 3e-07 0 -2212 -2112 111 323 2112 2212 +521:addChannel = 1 3e-07 0 -2212 -2112 -211 211 321 2112 2212 +521:addChannel = 1 2e-07 0 -3122 -2212 211 2112 2212 +521:addChannel = 1 2e-07 0 -3122 -2212 -211 111 111 211 211 221 2112 2212 +521:addChannel = 1 2e-07 0 -3122 -2112 111 2112 2212 +521:addChannel = 1 2e-07 0 -3122 -2112 -211 111 211 2112 2212 +521:addChannel = 1 2e-07 0 -2214 -2212 111 211 321 2112 2212 +521:addChannel = 1 2e-07 0 -2212 -2212 211 211 311 2112 2212 +521:addChannel = 1 2e-07 0 -2212 -2212 113 211 321 2112 2212 +521:addChannel = 1 2e-07 0 -2212 -2212 111 111 211 211 2112 2212 +521:addChannel = 1 2e-07 0 -2212 -2112 211 311 2112 2212 +521:addChannel = 1 2e-07 0 -2212 -2112 113 321 2112 2212 +521:addChannel = 1 2e-07 0 -2212 -2112 111 221 321 2112 2212 +521:addChannel = 1 2e-07 0 -2212 -2112 111 113 211 2112 2212 +521:addChannel = 1 2e-07 0 -2112 -2112 -211 211 311 2112 2212 +521:addChannel = 1 2e-07 0 -2212 -2112 -211 113 211 211 2112 2212 +521:addChannel = 1 2e-07 0 -2212 -2112 -211 111 211 211 2112 2212 +521:addChannel = 1 2e-07 0 -2112 -2112 221 223 2112 2212 +521:addChannel = 1 2e-07 0 -2112 -2112 111 221 2112 2212 +521:onIfMatch = -2112 -2112 111 2112 2212 +521:onIfMatch = -3122 -2212 213 2112 2212 +521:onIfMatch = -2212 -2112 111 323 2112 2212 +521:onIfMatch = -2212 -2112 -211 211 321 2112 2212 +521:onIfMatch = -3122 -2212 211 2112 2212 +521:onIfMatch = -3122 -2212 -211 111 111 211 211 221 2112 2212 +521:onIfMatch = -3122 -2112 111 2112 2212 +521:onIfMatch = -3122 -2112 -211 111 211 2112 2212 +521:onIfMatch = -2214 -2212 111 211 321 2112 2212 +521:onIfMatch = -2212 -2212 211 211 311 2112 2212 +521:onIfMatch = -2212 -2212 113 211 321 2112 2212 +521:onIfMatch = -2212 -2212 111 111 211 211 2112 2212 +521:onIfMatch = -2212 -2112 211 311 2112 2212 +521:onIfMatch = -2212 -2112 113 321 2112 2212 +521:onIfMatch = -2212 -2112 111 221 321 2112 2212 +521:onIfMatch = -2212 -2112 111 113 211 2112 2212 +521:onIfMatch = -2112 -2112 -211 211 311 2112 2212 +521:onIfMatch = -2212 -2112 -211 113 211 211 2112 2212 +521:onIfMatch = -2212 -2112 -211 111 211 211 2112 2212 +521:onIfMatch = -2112 -2112 221 223 2112 2212 +521:onIfMatch = -2112 -2112 111 221 2112 2212 diff --git a/MC/config/PWGHF/pythia8/generator/pythia8_cdeuteron_to_dkpi.cfg b/MC/config/PWGHF/pythia8/generator/pythia8_cdeuteron_to_dkpi.cfg new file mode 100644 index 000000000..788e56fe3 --- /dev/null +++ b/MC/config/PWGHF/pythia8/generator/pythia8_cdeuteron_to_dkpi.cfg @@ -0,0 +1,102 @@ +### author: Fabrizio Grosa (fabrizio.grosa@cern.ch) +### since: May 2026 + +### beams (not relevant) +Beams:idA 2212 # proton +Beams:idB 2212 # proton +Beams:eCM 13600. # GeV + +### processes +SoftQCD:inelastic on # all inelastic processes + +### decays +ParticleDecays:limitTau0 on +ParticleDecays:tau0Max 10. + +### add the c-deuteron +### id:all = name antiName spinType chargeType colType m0 mWidth mMin mMax tau0 +2010010020:all = CDeuteron AntiCDeuteron 1 3 0 3.226 0 3.226 3.226 0.5 +2010010020:mayDecay = on + +# same as Λc+ -> p K- π+ including resonances + a neutron +2010010020:oneChannel = 1 0.14400 0 2112 2212 -321 211 ### cd+ -> n p K- π+ (non-resonant) 3.5% +2010010020:addChannel = 1 0.08100 100 2112 2212 -313 ### cd+ -> n p K*0(892) 1.96% +2010010020:addChannel = 1 0.04500 100 2112 2224 -321 ### cd+ -> n Delta++ K- 1.08% +2010010020:addChannel = 1 0.09000 100 2112 102134 211 ### cd+ -> n Lambda(1520) K- 2.20e-3 + +### K*0(892) -> K- π+ +313:onMode = off +313:onIfAll = 321 211 +### for Λc -> Delta++ K- +2224:onMode = off +2224:onIfAll = 2212 211 +### for Λc -> Lambda(1520) K- +102134:onMode = off +102134:onIfAll = 2212 321 + +# Λb0 -> cd+ decays taken from PYTHIA +# NB: cd+ must always be the last daughter, not to screw up replacements in the generator +# 15% 2 body +5122:oneChannel = 1 0.15 0 2010010020 -2212 ### Λb0 -> cd+ anti-p +# 27% 3 body +5122:addChannel = 1 0.054 100 -2212 111 2010010020 ### Λb0 -> cd+ anti-p pi0 +5122:addChannel = 1 0.027 100 -2212 113 2010010020 ### Λb0 -> cd+ anti-p rho0 +5122:addChannel = 1 0.027 100 -2212 221 2010010020 ### Λb0 -> cd+ anti-p eta +5122:addChannel = 1 0.027 100 -2212 223 2010010020 ### Λb0 -> cd+ anti-p omega +5122:addChannel = 1 0.060 100 -2112 -211 2010010020 ### Λb0 -> cd+ anti-n0 pi- +5122:addChannel = 1 0.030 100 -2112 -213 2010010020 ### Λb0 -> cd+ anti-n0 rho- +5122:addChannel = 1 0.010 100 -2214 111 2010010020 ### Λb0 -> cd+ DeltaBar- pi0 +5122:addChannel = 1 0.005 100 -2214 113 2010010020 ### Λb0 -> cd+ DeltaBar- rho0 +5122:addChannel = 1 0.005 100 -2214 221 2010010020 ### Λb0 -> cd+ DeltaBar- eta +5122:addChannel = 1 0.005 100 -2214 223 2010010020 ### Λb0 -> cd+ DeltaBar- omega +5122:addChannel = 1 0.007 100 -2114 -211 2010010020 ### Λb0 -> cd+ DeltaBar0 pi- +5122:addChannel = 1 0.003 100 -2114 -213 2010010020 ### Λb0 -> cd+ DeltaBar0 rho- +5122:addChannel = 1 0.007 100 -2224 211 2010010020 ### Λb0 -> cd+ DeltaBar-- pi+ +5122:addChannel = 1 0.003 100 -2224 213 2010010020 ### Λb0 -> cd+ DeltaBar-- rho+ +5122:addChannel = 1 0.010 0 -3122 -321 2010010020 ### Λb0 -> cd+ Lambdabar0 K- +# 31% 4 body +5122:addChannel = 1 0.054 100 -2212 111 111 2010010020 ### Λb0 -> cd+ anti-p pi0 pi0 +5122:addChannel = 1 0.027 100 -2212 211 -211 2010010020 ### Λb0 -> cd+ anti-p pi+ pi- +5122:addChannel = 1 0.013 100 -2212 213 -211 2010010020 ### Λb0 -> cd+ anti-p rho+ pi- +5122:addChannel = 1 0.018 100 -2212 113 111 2010010020 ### Λb0 -> cd+ anti-p rho0 pi0 +5122:addChannel = 1 0.009 100 -2212 113 113 2010010020 ### Λb0 -> cd+ anti-p rho0 rho0 +5122:addChannel = 1 0.018 100 -2212 221 111 2010010020 ### Λb0 -> cd+ anti-p eta pi0 +5122:addChannel = 1 0.009 100 -2212 221 113 2010010020 ### Λb0 -> cd+ anti-p eta rho0 +5122:addChannel = 1 0.018 100 -2212 223 111 2010010020 ### Λb0 -> cd+ anti-p omega pi0 +5122:addChannel = 1 0.009 100 -2212 223 113 2010010020 ### Λb0 -> cd+ anti-p omega rho0 +5122:addChannel = 1 0.040 100 -2112 -211 111 2010010020 ### Λb0 -> cd+ anti-n0 pi- pi0 +5122:addChannel = 1 0.020 100 -2112 -211 113 2010010020 ### Λb0 -> cd+ anti-n0 pi- rho0 +5122:addChannel = 1 0.020 100 -2112 -213 111 2010010020 ### Λb0 -> cd+ anti-n0 rho- pi0 +5122:addChannel = 1 0.010 100 -2112 -213 113 2010010020 ### Λb0 -> cd+ anti-n0 rho- rho0 +5122:addChannel = 1 0.010 100 -2214 111 111 2010010020 ### Λb0 -> cd+ DeltaBar- pi0 pi0 +5122:addChannel = 1 0.005 100 -2214 113 111 2010010020 ### Λb0 -> cd+ DeltaBar- rho0 pi0 +5122:addChannel = 1 0.005 100 -2214 221 111 2010010020 ### Λb0 -> cd+ DeltaBar- eta pi0 +5122:addChannel = 1 0.005 100 -2214 223 111 2010010020 ### Λb0 -> cd+ DeltaBar- omega pi0 +5122:addChannel = 1 0.007 100 -2114 -211 111 2010010020 ### Λb0 -> cd+ DeltaBar0 pi- pi0 +5122:addChannel = 1 0.003 100 -2114 -213 111 2010010020 ### Λb0 -> cd+ DeltaBar0 rho- pi0 +5122:addChannel = 1 0.007 100 -2224 211 111 2010010020 ### Λb0 -> cd+ DeltaBar-- pi+ pi0 +5122:addChannel = 1 0.003 100 -2224 213 111 2010010020 ### Λb0 -> cd+ DeltaBar-- rho+ pi0 +5122:addChannel = 1 0.010 0 -3122 -321 111 2010010020 ### Λb0 -> cd+ Lambdabar0 K- pi0 +# 19% 5 body +5122:addChannel = 1 0.033 100 -2212 111 111 111 2010010020 ### Λb0 -> cd+ anti-p pi0 pi0 pi0 +5122:addChannel = 1 0.016 100 -2212 211 -211 111 2010010020 ### Λb0 -> cd+ anti-p pi+ pi- pi0 +5122:addChannel = 1 0.008 100 -2212 213 -211 111 2010010020 ### Λb0 -> cd+ anti-p rho+ pi- pi0 +5122:addChannel = 1 0.012 100 -2212 113 111 111 2010010020 ### Λb0 -> cd+ anti-p rho0 pi0 pi0 +5122:addChannel = 1 0.006 100 -2212 113 113 111 2010010020 ### Λb0 -> cd+ anti-p rho0 rho0 pi0 +5122:addChannel = 1 0.012 100 -2212 221 111 111 2010010020 ### Λb0 -> cd+ anti-p eta pi0 pi0 +5122:addChannel = 1 0.006 100 -2212 221 113 111 2010010020 ### Λb0 -> cd+ anti-p eta rho0 pi0 +5122:addChannel = 1 0.012 100 -2212 223 111 111 2010010020 ### Λb0 -> cd+ anti-p omega pi0 pi0 +5122:addChannel = 1 0.006 100 -2212 223 113 111 2010010020 ### Λb0 -> cd+ anti-p omega rho0 pi0 +5122:addChannel = 1 0.030 100 -2112 -211 111 111 2010010020 ### Λb0 -> cd+ anti-n0 pi- pi0 pi0 +5122:addChannel = 1 0.011 100 -2112 -211 113 111 2010010020 ### Λb0 -> cd+ anti-n0 pi- rho0 pi0 +5122:addChannel = 1 0.011 100 -2112 -213 111 111 2010010020 ### Λb0 -> cd+ anti-n0 rho- pi0 pi0 +5122:addChannel = 1 0.006 100 -2112 -213 113 111 2010010020 ### Λb0 -> cd+ anti-n0 rho- rho0 pi0 +5122:addChannel = 1 0.006 100 -2214 111 111 111 2010010020 ### Λb0 -> cd+ DeltaBar- pi0 pi0 pi0 +5122:addChannel = 1 0.002 100 -2214 113 111 111 2010010020 ### Λb0 -> cd+ DeltaBar- rho0 pi0 pi0 +5122:addChannel = 1 0.002 100 -2214 221 111 111 2010010020 ### Λb0 -> cd+ DeltaBar- eta pi0 pi0 +5122:addChannel = 1 0.002 100 -2214 223 111 111 2010010020 ### Λb0 -> cd+ DeltaBar- omega pi0 pi0 +5122:addChannel = 1 0.005 100 -2114 -211 111 111 2010010020 ### Λb0 -> cd+ DeltaBar0 pi- pi0 pi0 +5122:addChannel = 1 0.001 100 -2114 -213 111 111 2010010020 ### Λb0 -> cd+ DeltaBar0 rho- pi0 pi0 +5122:addChannel = 1 0.005 100 -2224 211 111 111 2010010020 ### Λb0 -> cd+ DeltaBar-- pi+ pi0 pi0 +5122:addChannel = 1 0.001 100 -2224 213 111 111 2010010020 ### Λb0 -> cd+ DeltaBar-- rho+ pi0 pi0 +5122:addChannel = 1 0.006 0 -3122 -321 111 111 2010010020 ### Λb0 -> cd+ Lambdabar0 K- pi0 pi0 diff --git a/MC/config/PWGHF/pythia8/generator/pythia8_charmhadronic_OmegaC_NoDecay_Mode2_pp_ref.cfg b/MC/config/PWGHF/pythia8/generator/pythia8_charmhadronic_OmegaC_NoDecay_Mode2_pp_ref.cfg new file mode 100644 index 000000000..60732359a --- /dev/null +++ b/MC/config/PWGHF/pythia8/generator/pythia8_charmhadronic_OmegaC_NoDecay_Mode2_pp_ref.cfg @@ -0,0 +1,43 @@ +### author: Tiantian Cheng (tiantian.cheng@cern.ch) +### last update: August 2025 + +### beams +Beams:idA 2212 # proton +Beams:idB 2212 # proton +Beams:eCM 5360. # GeV + +### processes +SoftQCD:inelastic on # all inelastic processes + +### decays +ParticleDecays:limitTau0 on +ParticleDecays:tau0Max 10. + +### switching on Pythia Mode2 +ColourReconnection:mode 1 +ColourReconnection:allowDoubleJunRem off +ColourReconnection:m0 0.3 +ColourReconnection:allowJunctions on +ColourReconnection:junctionCorrection 1.20 +ColourReconnection:timeDilationMode 2 +ColourReconnection:timeDilationPar 0.18 +StringPT:sigma 0.335 +StringZ:aLund 0.36 +StringZ:bLund 0.56 +StringFlav:probQQtoQ 0.078 +StringFlav:ProbStoUD 0.2 +StringFlav:probQQ1toQQ0join 0.0275,0.0275,0.0275,0.0275 +MultiPartonInteractions:pT0Ref 2.15 +BeamRemnants:remnantMode 1 +BeamRemnants:saturation 5 + +# Correct decay lengths (wrong in PYTHIA8 decay table) +# Lb +5122:tau0 = 0.4390 +# Xic0 +4132:tau0 = 0.0455 +# OmegaC +4332:tau0 = 0.0803 + +### switch off OmegaC decays +4332:onMode = off diff --git a/MC/config/PWGHF/pythia8/generator/pythia8_charmhadronic_XiC_NoDecay.cfg b/MC/config/PWGHF/pythia8/generator/pythia8_charmhadronic_XiC_NoDecay.cfg new file mode 100644 index 000000000..6ce71ed4f --- /dev/null +++ b/MC/config/PWGHF/pythia8/generator/pythia8_charmhadronic_XiC_NoDecay.cfg @@ -0,0 +1,42 @@ +### configuration for XiC + +### beams +Beams:idA 2212 # proton +Beams:idB 2212 # proton +Beams:eCM 13600. # GeV + +### processes +SoftQCD:inelastic on # all inelastic processes + +### decays +ParticleDecays:limitTau0 on +ParticleDecays:tau0Max 10. + +### switching on Pythia Mode2 +ColourReconnection:mode 1 +ColourReconnection:allowDoubleJunRem off +ColourReconnection:m0 0.3 +ColourReconnection:allowJunctions on +ColourReconnection:junctionCorrection 1.20 +ColourReconnection:timeDilationMode 2 +ColourReconnection:timeDilationPar 0.18 +StringPT:sigma 0.335 +StringZ:aLund 0.36 +StringZ:bLund 0.56 +StringFlav:probQQtoQ 0.078 +StringFlav:ProbStoUD 0.2 +StringFlav:probQQ1toQQ0join 0.0275,0.0275,0.0275,0.0275 +MultiPartonInteractions:pT0Ref 2.15 +BeamRemnants:remnantMode 1 +BeamRemnants:saturation 5 + +#Correct decay lengths(wrong in PYTHIA8 decay table) +#Lb +5122:tau0 = 0.4390 +#Xic0 +4132:tau0 = 0.0455 +#OmegaC +4332:tau0 = 0.0803 + +### switch off XiC0 decays +4132:onMode = off diff --git a/MC/config/PWGHF/pythia8/generator/pythia8_charmhadronic_XiC_NoDecay_Mode2_pp_ref.cfg b/MC/config/PWGHF/pythia8/generator/pythia8_charmhadronic_XiC_NoDecay_Mode2_pp_ref.cfg new file mode 100644 index 000000000..7ca299325 --- /dev/null +++ b/MC/config/PWGHF/pythia8/generator/pythia8_charmhadronic_XiC_NoDecay_Mode2_pp_ref.cfg @@ -0,0 +1,43 @@ +### author: Tiantian Cheng (tiantian.cheng@cern.ch) +### last update: August 2025 + +### beams +Beams:idA 2212 # proton +Beams:idB 2212 # proton +Beams:eCM 5360. # GeV + +### processes +SoftQCD:inelastic on # all inelastic processes + +### decays +ParticleDecays:limitTau0 on +ParticleDecays:tau0Max 10. + +### switching on Pythia Mode2 +ColourReconnection:mode 1 +ColourReconnection:allowDoubleJunRem off +ColourReconnection:m0 0.3 +ColourReconnection:allowJunctions on +ColourReconnection:junctionCorrection 1.20 +ColourReconnection:timeDilationMode 2 +ColourReconnection:timeDilationPar 0.18 +StringPT:sigma 0.335 +StringZ:aLund 0.36 +StringZ:bLund 0.56 +StringFlav:probQQtoQ 0.078 +StringFlav:ProbStoUD 0.2 +StringFlav:probQQ1toQQ0join 0.0275,0.0275,0.0275,0.0275 +MultiPartonInteractions:pT0Ref 2.15 +BeamRemnants:remnantMode 1 +BeamRemnants:saturation 5 + +# Correct decay lengths (wrong in PYTHIA8 decay table) +# Lb +5122:tau0 = 0.4390 +# Xic0 +4132:tau0 = 0.0455 +# OmegaC +4332:tau0 = 0.0803 + +### switch off Xic0 decays +4132:onMode = off diff --git a/MC/config/PWGHF/pythia8/generator/pythia8_charmhadronic_XiCplus_NoDecay.cfg b/MC/config/PWGHF/pythia8/generator/pythia8_charmhadronic_XiCplus_NoDecay.cfg new file mode 100644 index 000000000..51771aee8 --- /dev/null +++ b/MC/config/PWGHF/pythia8/generator/pythia8_charmhadronic_XiCplus_NoDecay.cfg @@ -0,0 +1,42 @@ +### configuration for XiC + +### beams +Beams:idA 2212 # proton +Beams:idB 2212 # proton +Beams:eCM 13600. # GeV + +### processes +SoftQCD:inelastic on # all inelastic processes + +### decays +ParticleDecays:limitTau0 on +ParticleDecays:tau0Max 10. + +### switching on Pythia Mode2 +ColourReconnection:mode 1 +ColourReconnection:allowDoubleJunRem off +ColourReconnection:m0 0.3 +ColourReconnection:allowJunctions on +ColourReconnection:junctionCorrection 1.20 +ColourReconnection:timeDilationMode 2 +ColourReconnection:timeDilationPar 0.18 +StringPT:sigma 0.335 +StringZ:aLund 0.36 +StringZ:bLund 0.56 +StringFlav:probQQtoQ 0.078 +StringFlav:ProbStoUD 0.2 +StringFlav:probQQ1toQQ0join 0.0275,0.0275,0.0275,0.0275 +MultiPartonInteractions:pT0Ref 2.15 +BeamRemnants:remnantMode 1 +BeamRemnants:saturation 5 + +#Correct decay lengths(wrong in PYTHIA8 decay table) +#Lb +5122:tau0 = 0.4390 +#Xic0 +4132:tau0 = 0.0455 +#OmegaC +4332:tau0 = 0.0803 + +### switch off XiC+ decays +4232:onMode = off diff --git a/MC/config/PWGHF/pythia8/generator/pythia8_charmhadronic_XiCplus_NoDecay_Mode2_pp_ref.cfg b/MC/config/PWGHF/pythia8/generator/pythia8_charmhadronic_XiCplus_NoDecay_Mode2_pp_ref.cfg new file mode 100644 index 000000000..34e80be24 --- /dev/null +++ b/MC/config/PWGHF/pythia8/generator/pythia8_charmhadronic_XiCplus_NoDecay_Mode2_pp_ref.cfg @@ -0,0 +1,43 @@ +### author: Tiantian Cheng (tiantian.cheng@cern.ch) +### last update: August 2025 + +### beams +Beams:idA 2212 # proton +Beams:idB 2212 # proton +Beams:eCM 5360. # GeV + +### processes +SoftQCD:inelastic on # all inelastic processes + +### decays +ParticleDecays:limitTau0 on +ParticleDecays:tau0Max 10. + +### switching on Pythia Mode2 +ColourReconnection:mode 1 +ColourReconnection:allowDoubleJunRem off +ColourReconnection:m0 0.3 +ColourReconnection:allowJunctions on +ColourReconnection:junctionCorrection 1.20 +ColourReconnection:timeDilationMode 2 +ColourReconnection:timeDilationPar 0.18 +StringPT:sigma 0.335 +StringZ:aLund 0.36 +StringZ:bLund 0.56 +StringFlav:probQQtoQ 0.078 +StringFlav:ProbStoUD 0.2 +StringFlav:probQQ1toQQ0join 0.0275,0.0275,0.0275,0.0275 +MultiPartonInteractions:pT0Ref 2.15 +BeamRemnants:remnantMode 1 +BeamRemnants:saturation 5 + +# Correct decay lengths (wrong in PYTHIA8 decay table) +# Lb +5122:tau0 = 0.4390 +# Xic0 +4132:tau0 = 0.0455 +# OmegaC +4332:tau0 = 0.0803 + +### switch off Xic+ decays +4232:onMode = off diff --git a/MC/config/PWGHF/pythia8/generator/pythia8_charmhadronic_decays_Mode2_hardQCD_5TeV_XicOmegaC.cfg b/MC/config/PWGHF/pythia8/generator/pythia8_charmhadronic_decays_Mode2_hardQCD_5TeV_XicOmegaC.cfg new file mode 100644 index 000000000..84ac21536 --- /dev/null +++ b/MC/config/PWGHF/pythia8/generator/pythia8_charmhadronic_decays_Mode2_hardQCD_5TeV_XicOmegaC.cfg @@ -0,0 +1,156 @@ +### authors: Fabrizio Grosa (fabrizio.grosa@cern.ch) +### Ruiqi Yin (ruiqi.yin@cern.ch) +### last update: October 2025 + +### beams +Beams:idA 2212 # proton +Beams:idB 2212 # proton +Beams:eCM 5360. # GeV + +### processes: c-cbar and b-bbar processes +HardQCD:hardccbar on +HardQCD:hardbbbar on +HardQCD:gg2ccbar on +HardQCD:qqbar2ccbar on +HardQCD:gg2bbbar on +HardQCD:qqbar2bbbar on + +### decays +ParticleDecays:limitTau0 on +ParticleDecays:tau0Max 10. + +### switching on Pythia Mode2 +ColourReconnection:mode 1 +ColourReconnection:allowDoubleJunRem off +ColourReconnection:m0 0.3 +ColourReconnection:allowJunctions on +ColourReconnection:junctionCorrection 1.20 +ColourReconnection:timeDilationMode 2 +ColourReconnection:timeDilationPar 0.18 +StringPT:sigma 0.335 +StringZ:aLund 0.36 +StringZ:bLund 0.56 +StringFlav:probQQtoQ 0.078 +StringFlav:ProbStoUD 0.2 +StringFlav:probQQ1toQQ0join 0.0275,0.0275,0.0275,0.0275 +MultiPartonInteractions:pT0Ref 2.15 +BeamRemnants:remnantMode 1 +BeamRemnants:saturation 5 + +# Correct decay lengths (wrong in PYTHIA8 decay table) +# Lb +5122:tau0 = 0.4390 +# Xic0 +4132:tau0 = 0.0455 +# OmegaC +4332:tau0 = 0.0803 + +### Force charm baryon decay modes (Ξc and Ωc) +### D mesons use default PYTHIA8 branching ratios + +## Λc decays (optional, can be kept for reference) +### Λc+ -> p K- π+ (36%) +4122:oneChannel = 1 0.14400 0 2212 -321 211 ### Λc+ -> p K- π+ (non-resonant) 3.5% +4122:addChannel = 1 0.08100 100 2212 -313 ### Λc+ -> p K*0(892) 1.96% +4122:addChannel = 1 0.04500 100 2224 -321 ### Λc+ -> Delta++ K- 1.08% +4122:addChannel = 1 0.09000 100 102134 211 ### Λc+ -> Lambda(1520) K- 2.20e-3 +### Λc+ -> p K0S (36%) +4122:addChannel = 1 0.36000 0 2212 311 ### Λc+ -> p K0S 1.59% +### Λc+ -> p K- π+ π0 (small, 3%) +4122:addChannel = 1 0.03000 0 2212 -321 211 111 ### Λc+ -> p K- π+ π0 (non-resonant) 4.6% +### Λc+ -> p π- π+ (12.50%) +4122:addChannel = 1 0.12500 0 2212 -211 211 ### Λc+ -> p π+ π+ 4.59% +### Λc+ -> p K- K+ (12.50%) +4122:addChannel = 1 0.12500 0 2212 333 ### Λc+ -> p phi 1.06% + +## Xic decays +### Ξc+ -> p K- π+ (35%) +4232:oneChannel = 1 0.17500 0 2212 -321 211 ### Ξc+ -> p K- π+ 6.18e-3 +4232:addChannel = 1 0.17500 0 2212 -313 ### Ξc+ -> p antiK*0(892) +### Ξc+ -> Ξ- π+ π+ (35%) (set the same as Ξc+ -> p K- π+) +4232:addChannel = 1 0.35000 0 3312 211 211 ### Ξc+ -> Ξ- π+ π+ 2.86% +### Ξc+ -> p φ (10%) +4232:addChannel = 1 0.10000 0 2212 333 ### Ξc+ -> p φ +### Ξc+ -> sigma+ π+ π- (10%) +4232:addChannel = 1 0.12500 0 3222 -211 211 ### Ξc+ -> sigma+ π- π+ 1.37% +### Ξc+ -> Ξ*0 π+ (10%) +4232:addChannel = 1 0.12500 0 3324 211 + +### add Xic0 decays absent in PYTHIA8 decay table +4132:oneChannel = 1 0.0143 0 3312 211 + +### add OmegaC decays absent in PYTHIA8 decay table +4332:oneChannel = 1 0.5 0 3334 211 +4332:addChannel = 1 0.5 0 3312 211 + +# Allow the decay of resonances in the decay chain (only for charm baryons) +### for Λc -> Delta++ K- +2224:onMode = off +2224:onIfAll = 2212 211 +### for Λc -> Lambda(1520) K- +102134:onMode = off +102134:onIfAll = 2212 321 +### for Λc -> p K*0(892) +313:onMode = off +313:onIfAll = 321 211 +### for Λc -> p phi +333:onMode = off +333:onIfAll = 321 321 +### for Xic0 -> pi Xi -> pi pi Lambda -> pi pi pi p +### and Omega_c -> pi Xi -> pi pi Lambda -> pi pi pi p +3312:onMode = off +3312:onIfAll = 3122 -211 +3122:onMode = off +3122:onIfAll = 2212 -211 +### for Omega_c -> pi Omega -> pi K Lambda -> pi K pi p +3334:onMode = off +3334:onIfAll = 3122 -321 + +# Switch off charm baryon decay channels (D mesons use PYTHIA8 defaults) +4122:onMode = off +4232:onMode = off +4132:onMode = off +4332:onMode = off + +# Allow the decay of charm baryons +### Λc -> pK0s +4122:onIfMatch = 2212 311 +### Λc -> p K- π+ π0 +4122:onIfMatch = 2212 321 211 +### Λc -> p K* +4122:onIfMatch = 2212 313 +### Λc -> Delta++ K +4122:onIfMatch = 2224 321 +### Λc -> Lambda(1520) π +4122:onIfMatch = 102134 211 +### Λc -> p K- π+ π0 +4122:onIfMatch = 2212 321 211 111 +### Λc -> p π π +4122:onIfMatch = 2212 211 211 +### Λc -> p K K +4122:onIfMatch = 2212 333 + +### Ξc+ -> p K- π+ +4232:onIfMatch = 2212 321 211 +### Ξc+ -> p antiK*0(892) +4232:onIfMatch = 2212 313 +### Ξc+ -> p φ +4232:onIfMatch = 2212 333 +### Ξc+ -> sigma- π+ π+ +4232:onIfMatch = 3222 211 211 +### Ξc+ -> Ξ*0 π+, Ξ*0 -> Ξ- π+ +4232:onIfMatch = 3324 211 +### Ξc+ -> Ξ- π+ π+ +4232:onIfMatch = 3312 211 211 + +### Xic0 -> Xi- pi+ +4132:onIfMatch = 3312 211 +### Xic0 -> Omega- Ka+ +4132:onIfMatch = 3334 321 + +### Omega_c -> Omega pi +4332:onIfMatch = 3334 211 +### Omega_c -> Xi pi +4332:onIfMatch = 3312 211 +### Omega_c -> Omega- Ka+ +4332:onIfMatch = 3334 321 \ No newline at end of file diff --git a/MC/config/PWGHF/pythia8/generator/pythia8_charmhadronic_with_decays_DResoTrigger.cfg b/MC/config/PWGHF/pythia8/generator/pythia8_charmhadronic_with_decays_DResoTrigger.cfg new file mode 100644 index 000000000..a6b132d94 --- /dev/null +++ b/MC/config/PWGHF/pythia8/generator/pythia8_charmhadronic_with_decays_DResoTrigger.cfg @@ -0,0 +1,159 @@ +### author: Stefano Politano, Luca Aglietta (stefano.politano@cern.ch, luca.aglietta@cern.ch) +### since: July 2024 + +### beams +Beams:idA 2212 # proton +Beams:idB 2212 # proton +Beams:eCM 13600. # GeV + +### processes +SoftQCD:inelastic on # all inelastic processes + +### decays +ParticleDecays:limitTau0 on +ParticleDecays:tau0Max 10. + +# parameters to boost resonances production +StringFlav:mesonCL1S0J1= 3 +StringFlav:mesonCL1S1J2= 5 + +### add resonances not present in PYTHIA +### id:all = name antiName spinType chargeType colType m0 mWidth mMin mMax tau0 +### Ds1*(2700) +30433:all = D*_s1(2700)+ D*_s1(2700)- 3 3 0 2.714 0.122 2.51 10. 0. +30433:mayDecay = on + +### Ds1*(2860) +40433:all = D*_s1(2860)+ D*_s1(2860)- 3 3 0 2.859 0.160 2.51 10. 0. +40433:mayDecay = on + +### Ds3*(2860) +437:all = D*_s3(2860)+ D*_s3(2860)- 7 3 0 2.860 0.053 2.51 10. 0. +437:mayDecay = on + +### Xic(3055)+ +4325:all = Xi_c(3055)+ Xi_cbar(3055)- 4 3 0 3.0559 0.0078 2.986 10. 0. +4325:mayDecay = on + +### Xic(3080)+ +4326:all = Xi_c(3080)+ Xi_cbar(3080)- 2 3 0 3.0772 0.0036 2.986 10. 0. +4326:mayDecay = on + +### Xic(3055)0 +4315:all = Xi_c(3055)0 Xi_cbar(3055)0 4 0 0 3.0590 0.0064 2.981 10. 0. +4315:mayDecay = on + +### Xic(3080)0 +4316:all = Xi_c(3080)0 Xi_cbar(3080)0 2 0 0 3.0799 0.0056 2.981 10. 0. +4316:mayDecay = on + +### turn off all charm resonances decays +10433:onMode = off # Ds1(2536) +435:onMode = off # Ds2*(2573) +30433:onMode = off # Ds1*(2700) +40433:onMode = off # Ds1*(2860) +437:onMode = off # Ds3*(2860) +4325:onMode = off # Xic(3055)+ +4326:onMode = off # Xic(3080)+ +4315:onMode = off # Xic(3055)0 +4316:onMode = off # Xic(3080)0 + +### turn off all beauty hadron decays +531:onMode = off +521:onMode = off + +### add Ds1(2536) +10433:oneChannel = 1 1 0 413 311 +10433:onIfMatch = 413 311 + +### add Ds2*(2573) +435:oneChannel = 1 0.1000000 0 413 311 +435:addChannel = 1 0.9000000 0 411 311 +435:onIfMatch = 413 311 +435:onIfMatch = 411 311 + +### add Ds1*(2700) +30433:oneChannel = 1 1 0 413 311 +30433:onIfMatch = 413 311 + +### add Ds1*(2860) +40433:oneChannel = 1 1 0 413 311 +40433:onIfMatch = 413 311 + +### add Ds3*(2860) +437:oneChannel = 1 1 0 413 311 +437:onIfMatch = 413 311 + +### add Xic(3055)+ +4325:oneChannel = 1 1 0 411 3122 +4325:onIfMatch = 411 3122 + +### add Xic(3080)+ +4326:oneChannel = 1 1 0 411 3122 +4326:onIfMatch = 411 3122 + +### add Xic(3055)0 +4315:oneChannel = 1 1 0 421 3122 +4315:onIfMatch = 421 3122 + +### add Xic(3080)0 +4316:oneChannel = 1 1 0 421 3122 +4316:onIfMatch = 421 3122 + +### add Bs0 +531:oneChannel = 1 0.0070000 0 12 -11 -435 +531:addChannel = 1 0.0070000 0 12 -11 -10433 +531:addChannel = 1 0.0070000 0 14 -13 -435 +531:addChannel = 1 0.0070000 0 14 -13 -10433 +531:addChannel = 1 0.0028000 0 16 -15 -435 +531:addChannel = 1 0.0028000 0 16 -15 -10433 +531:addChannel = 1 0.0013000 0 -435 211 + +531:onIfMatch = 12 11 435 +531:onIfMatch = 12 11 10433 +531:onIfMatch = 14 13 435 +531:onIfMatch = 14 13 10433 +531:onIfMatch = 16 15 435 +531:onIfMatch = 16 15 10433 +531:onIfMatch = 435 211 + +# Correct decay lengths (wrong in PYTHIA8 decay table) +# Lb +5122:tau0 = 0.4390 +# Xic0 +4132:tau0 = 0.0455 +# OmegaC +4332:tau0 = 0.0803 + +### Force golden charm hadrons decay modes for D2H studies +### add D+ decays absent in PYTHIA8 decay table and set BRs from PDG for other +411:oneChannel = 1 0.0752 0 -321 211 211 +411:addChannel = 1 0.0104 0 -313 211 +411:addChannel = 1 0.0156 0 311 211 +411:addChannel = 1 0.0752 0 333 211 # to have the same amount of D+->KKpi and D+->Kpipi +### set D0 BRs +421:oneChannel = 1 0.9 0 -321 211 +421:addChannel = 1 0.1 0 -321 211 111 + +### K* -> K pi +313:onMode = off +313:onIfAll = 321 211 +### for Ds -> Phi pi+ +333:onMode = off +333:onIfAll = 321 321 + +### switch off all decay channels +411:onMode = off +421:onMode = off + +### D0 -> K pi +421:onIfMatch = 321 211 +### D0 -> K pi pi0 +421:onIfMatch = 321 211 111 + +### D+/- -> K pi pi +411:onIfMatch = 321 211 211 +### D+/- -> K* pi +411:onIfMatch = 313 211 +### D+/- -> phi pi +411:onIfMatch = 333 211 diff --git a/MC/config/PWGHF/pythia8/generator/pythia8_charmhadronic_with_decays_LcResoTrigger.cfg b/MC/config/PWGHF/pythia8/generator/pythia8_charmhadronic_with_decays_LcResoTrigger.cfg new file mode 100644 index 000000000..274d4b22b --- /dev/null +++ b/MC/config/PWGHF/pythia8/generator/pythia8_charmhadronic_with_decays_LcResoTrigger.cfg @@ -0,0 +1,118 @@ +### author: Antonio Palasciano (antonio.palasciano@cern.ch) +### since: July 2024 + +### beams +Beams:idA 2212 # proton +Beams:idB 2212 # proton +Beams:eCM 13600. # GeV + +### processes +SoftQCD:inelastic on # all inelastic processes + +### switching on Pythia Mode2 +ColourReconnection:mode 1 +ColourReconnection:allowDoubleJunRem off +ColourReconnection:m0 0.3 +ColourReconnection:allowJunctions on +ColourReconnection:junctionCorrection 1.20 +ColourReconnection:timeDilationMode 2 +ColourReconnection:timeDilationPar 0.18 +StringPT:sigma 0.335 +StringZ:aLund 0.36 +StringZ:bLund 0.56 +StringFlav:probQQtoQ 0.078 +StringFlav:ProbStoUD 0.2 +StringFlav:probQQ1toQQ0join 0.0275,0.0275,0.0275,0.0275 +MultiPartonInteractions:pT0Ref 2.15 +BeamRemnants:remnantMode 1 +BeamRemnants:saturation 5 + +### decays +ParticleDecays:limitTau0 on +ParticleDecays:tau0Max 10. + +### add resonances not present in PYTHIA +### id:all = name antiName spinType chargeType colType m0 mWidth mMin mMax tau0 + +### LambdaC(2860) +24124:all = Lambda_c(2860)+ Lambda_c(2860)- 3 1 0 2.8561 0.0676 2.7 10. 0. +24124:mayDecay = on + +### LambdaC(2880) +24126:all = Lambda_c(2880)+ Lambda_c(2880)- 5 1 0 2.8816 0.0056 2.85 10. 0. +24126:mayDecay = on + +### LambdaC(2940) +4125:all = Lambda_c(2940)+ Lambda_c(2940)- 3 1 0 2.9396 0.020 2.9 10. 0. +4125:mayDecay = on + +### TC(3100) +9422111:all = Theta_c(3100) 3 0 0 3.099 0.0000083 2.95 10. 0. +9422111:mayDecay = on + +### turn off all charm resonances decays +# 24124:onMode = off # LambdaC(2860) +# 24126:onMode = off # LambdaC(2880) +# 4125:onMode = off # LambdaC(2940) +# 9422111:onMode = off # Theta_c(3100) + +### turn off all beauty hadron decays +531:onMode = off +521:onMode = off +5122:onMode = off + +### add LambdaC(2860) +24124:oneChannel = 1 1 0 421 2212 +24124:onIfMatch = 421 2212 + +### add LambdaC(2880) +24126:oneChannel = 1 1 0 421 2212 +24126:onIfMatch = 421 2212 + +### add LambdaC(2940) +4125:oneChannel = 1 1 0 421 2212 +4125:onIfMatch = 421 2212 + +### add ThetaC(3100) +9422111:oneChannel = 1 1 0 413 2212 +9422111:onIfMatch = 413 2212 + +### add Lb +5122:addChannel = 1 0.2 0 421 2212 -211 # Lb -> D0 p pi- non resonant +5122:addChannel = 1 0.4 0 24124 -211 # Lb -> LambdaC(2860)+ pi- +5122:addChannel = 1 0.25 0 24126 -211 # Lb -> LambdaC(2880)+ pi- +5122:addChannel = 1 0.15 0 4125 -211 # Lb -> LambdaC(2940)+ pi- + +5122:onIfMatch = 421 2212 -211 # D0 p pi- +5122:onIfMatch = 24124 -211 # LambdaC(2860)+ pi- +5122:onIfMatch = 24126 -211 # LambdaC(2880)+ pi- +5122:onIfMatch = 4125 -211 # LambdaC(2940)+ pi- + +# Correct decay lengths (wrong in PYTHIA8 decay table) +# Lb +5122:tau0 = 0.4390 +# Xic0 +4132:tau0 = 0.0455 +# OmegaC +4332:tau0 = 0.0803 + +### Force golden charm hadrons decay modes for D2H studies +### set D0 BRs +421:oneChannel = 1 0.9 0 -321 211 +421:addChannel = 1 0.1 0 -321 211 111 + +### K* -> K pi +313:onMode = off +313:onIfAll = 321 211 + +### switch off all decay channels +411:onMode = off +413:onMode = off +421:onMode = off + +### D0 -> K pi +421:onIfMatch = 321 211 +### D0 -> K pi pi0 +421:onIfMatch = 321 211 111 +### D*+0 -> D0 pi +413:onIfMatch = 421 211 diff --git a/MC/config/PWGHF/pythia8/generator/pythia8_charmhadronic_with_decays_Mode2.cfg b/MC/config/PWGHF/pythia8/generator/pythia8_charmhadronic_with_decays_Mode2.cfg index aebd1cc63..7c03e2d0f 100644 --- a/MC/config/PWGHF/pythia8/generator/pythia8_charmhadronic_with_decays_Mode2.cfg +++ b/MC/config/PWGHF/pythia8/generator/pythia8_charmhadronic_with_decays_Mode2.cfg @@ -42,44 +42,127 @@ BeamRemnants:saturation 5 4332:tau0 = 0.0803 ### Force golden charm hadrons decay modes for D2H studies -### add D0 decays absent in PYTHIA8 decay table and set BRs from PDG for other -421:oneChannel = 1 0.0389 0 -321 211 -421:addChannel = 1 0.00389 0 -321 211 111 -### add D+ decays absent in PYTHIA8 decay table and set BRs from PDG for other -411:oneChannel = 1 0.0752 0 -321 211 211 -411:addChannel = 1 0.0104 0 -313 211 -411:addChannel = 1 0.0156 0 311 211 -411:addChannel = 1 0.0752 0 333 211 # to have the same amount of D+->KKpi and D+->Kpipi -## add Lc decays absent in PYTHIA8 decay table and set BRs from PDG for other -4122:oneChannel = 1 0.0196 100 2212 -313 -4122:addChannel = 1 0.0108 100 2224 -321 -4122:addChannel = 1 0.022 100 102134 211 -4122:addChannel = 1 0.035 0 2212 -321 211 -4122:addChannel = 1 0.0159 0 2212 311 -### add Xic+ decays absent in PYTHIA8 decay table -4232:addChannel = 1 0.2 0 2212 -313 -4232:addChannel = 1 0.2 0 2212 -321 211 -4232:addChannel = 1 0.2 0 3324 211 -4232:addChannel = 1 0.2 0 3312 211 211 +# HF decays +### BR are set to yield 50% of signal in golden channel and uniform abundance of corr. bkg channels (weighted by BR from PDG) +### +### D0 decays +### D0 -> K- π+ (50%) +421:oneChannel = 1 0.50000 0 -321 211 ### D0 -> K- π+ 3.94% +### D0 -> K- π+ π0 (12.50%) +421:addChannel = 1 0.00625 0 -321 211 111 ### D0 -> K- π+ π0 (non-resonant) 1.15% (e.g. 115/(115+231+195+1120)*0.2) +421:addChannel = 1 0.08750 0 213 -321 ### D0 -> rho+ K- 11.2% +421:addChannel = 1 0.01250 0 -313 111 ### D0 -> antiK*0(892) π0 1.95% +421:addChannel = 1 0.01875 0 -323 211 ### D0 -> K*-(892) π+ 2.31% +### D0 -> π- π+ (12.50%) +421:addChannel = 1 0.12500 0 -211 211 ### D0 -> π- π+ (non-resonant) 1.0e-4 +### D0 -> π- π+ π0 (12.50%) +421:addChannel = 1 0.08750 0 213 -211 ### D0 -> rho+ π- 1.01% +421:addChannel = 1 0.03750 0 -211 211 111 ### D0 -> π- π+ π0 (non-resonant) 1.3e-4 +### D0 -> K- K+ (12.50%) +421:addChannel = 1 0.12500 0 -321 321 ### D0 -> K- K+ (non-resonant) 4.08e-3 + +### D+ decays +### D+ -> K- π+ π+ (50%) +411:oneChannel = 1 0.40189 0 -321 211 211 ### D+ -> K- π+ π+ 9.38% +411:addChannel = 1 0.05356 0 -10311 211 ### D+ -> antiK*0(1430) π+ 1.25% +411:addChannel = 1 0.04455 0 -313 211 ### D+ -> K*0(892) pi+ 1.04% +### D+ -> K- π+ π+ π0 (small, 3%) +411:addChannel = 1 0.03000 0 -321 211 211 111 ### D+ -> K- π+ π+ π0 6.25% +### D+ -> K- K+ π+ (36.00%, set 25% for D+ -> φ π+, 11% for the rest) +411:addChannel = 1 0.25000 0 333 211 ### D+ -> φ π+ 2.69e-3 !needed for signal +411:addChannel = 1 0.03929 0 -313 321 ### D+ -> K*0(892) K+ 2.49e-3 +411:addChannel = 1 0.02865 0 -10311 321 ### D+ -> antiK*0(1430) K+ 1.82e-3 +411:addChannel = 1 0.04206 0 -321 321 211 ### D+ -> K- K+ π+ (non-resonant) 2.68e-3 +### D+ -> π- π+ π+ (11.00%) +411:addChannel = 1 0.02911 0 113 211 ### D+ -> rho0 π+ 8.4e-4 +411:addChannel = 1 0.01618 0 225 211 ### D+ -> f2(1270) π+ 4.6e-4 +411:addChannel = 1 0.06471 0 -211 211 211 ### D+ -> π- π+ π+ (non-resonant) 1.0e-4 + +### Ds+ decays +### Ds+ -> K- K+ π+ (50%) +431:oneChannel = 1 0.50000 0 333 211 ### Ds+ -> φ(1020) π+ 2.21% +431:addChannel = 1 0.15000 0 -313 321 ### Ds+ -> antiK*(892) K+ 2.58% +### Ds+ -> K- K+ π+ π0 (small, 2%) +431:addChannel = 1 0.02000 0 333 213 ### Ds+ -> φ(1020) rho 5.50% +### Ds+ -> π- π+ π+ (11.00%) +431:addChannel = 1 0.00220 0 113 211 ### Ds+ -> rho π+ 1.1e-4 +431:addChannel = 1 0.00220 0 225 211 ### Ds+ -> f2(1270) π+ 1.4e-3 +431:addChannel = 1 0.10560 0 -211 211 211 ### Ds+ -> π- π+ π+ 9.12e-3 (s-wave) +### Ds+ -> π- K+ π+ (11.00%) +431:addChannel = 1 0.03080 0 313 211 ### Ds+ -> K*(892)0 π+ 1.67e-3 +431:addChannel = 1 0.02200 0 10221 321 ### Ds+ -> f0(1370) K+ 1.2e-3 +431:addChannel = 1 0.03960 0 113 321 ### Ds+ -> rho0 K+ 2.17e-3 +431:addChannel = 1 0.01760 0 -211 321 211 ### Ds+ -> π- K+ π+ (non-resonant) 1.16-3 +### Ds+ -> π+ π- π+ π0 (11.00%) +431:addChannel = 1 0.11000 0 221 211 ### Ds+ -> eta π+ -> π0 π+ π+ π- (affects D+ golden channel) + +## Λc decays +### Λc+ -> p K- π+ (36%) +4122:oneChannel = 1 0.14400 0 2212 -321 211 ### Λc+ -> p K- π+ (non-resonant) 3.5% +4122:addChannel = 1 0.08100 100 2212 -313 ### Λc+ -> p K*0(892) 1.96% +4122:addChannel = 1 0.04500 100 2224 -321 ### Λc+ -> Delta++ K- 1.08% +4122:addChannel = 1 0.09000 100 102134 211 ### Λc+ -> Lambda(1520) K- 2.20e-3 +### Λc+ -> p K0S (36%) +4122:addChannel = 1 0.36000 0 2212 311 ### Λc+ -> p K0S 1.59% +### Λc+ -> p K- π+ π0 (small, 3%) +4122:addChannel = 1 0.03000 0 2212 -321 211 111 ### Λc+ -> p K- π+ π0 (non-resonant) 4.6% +### Λc+ -> p π- π+ (12.50%) +4122:addChannel = 1 0.12500 0 2212 -211 211 ### Λc+ -> p π+ π+ 4.59% +### Λc+ -> p K- K+ (12.50%) +4122:addChannel = 1 0.12500 0 2212 333 ### Λc+ -> p phi 1.06% + +## Xic decays +### Ξc+ -> p K- π+ (35%) +4232:oneChannel = 1 0.17500 0 2212 -321 211 ### Ξc+ -> p K- π+ 6.18e-3 +4232:addChannel = 1 0.17500 0 2212 -313 ### Ξc+ -> p antiK*0(892) +### Ξc+ -> Ξ- π+ π+ (35%) (set the same as Ξc+ -> p K- π+) +4232:addChannel = 1 0.35000 0 3312 211 211 ### Ξc+ -> Ξ- π+ π+ 2.86% +### Ξc+ -> p φ (10%) +4232:addChannel = 1 0.10000 0 2212 333 ### Ξc+ -> p φ +### Ξc+ -> sigma+ π+ π- (10%) +4232:addChannel = 1 0.12500 0 3222 -211 211 ### Ξc+ -> sigma+ π- π+ 1.37% +### Ξc+ -> Ξ*0 π+ (10%) +4232:addChannel = 1 0.12500 0 3324 211 + ### add Xic0 decays absent in PYTHIA8 decay table -4132:addChannel = 1 0.0143 0 3312 211 +4132:oneChannel = 1 0.0143 0 3312 211 + ### add OmegaC decays absent in PYTHIA8 decay table -4332:addChannel = 1 0.5 0 3334 211 +4332:oneChannel = 1 0.5 0 3334 211 4332:addChannel = 1 0.5 0 3312 211 -### K* -> K pi +# Allow the decay of resonances in the decay chain +### K*0(892) -> K- π+ 313:onMode = off 313:onIfAll = 321 211 -### for Ds -> Phi pi+ +### K*(892)+ -> K- π0 +323:onMode = off +323:onIfAll = 321 111 +### K*(1430)0 -> K- π+ +10311:onMode = off +10311:onIfAll = 321 211 +### rho+ -> π+ π0 +213:onMode = off +213:onIfAll = 211 111 +### φ -> K+ K- 333:onMode = off 333:onIfAll = 321 321 -### for D0 -> rho0 pi+ k- +### rho0 -> π+ π- 113:onMode = off 113:onIfAll = 211 211 -### for Lambda_c -> Delta++ K- +### f2(1270) -> π+ π- +225:onMode = off +225:onIfAll = 211 211 +### f0(1370) -> π+ π- +10221:onMode = off +10221:onIfAll = 211 211 +### eta -> π+ π- +221:onMode = off +221:onIfAll = 111 211 211 +### for Λc -> Delta++ K- 2224:onMode = off 2224:onIfAll = 2212 211 -### for Lambda_c -> Lambda(1520) K- +### for Λc -> Lambda(1520) K- 102134:onMode = off 102134:onIfAll = 2212 321 ### for Xic0 -> pi Xi -> pi pi Lambda -> pi pi pi p @@ -92,7 +175,7 @@ BeamRemnants:saturation 5 3334:onMode = off 3334:onIfAll = 3122 -321 -### switch off all decay channels +# switch off all decay channels 411:onMode = off 421:onMode = off 431:onMode = off @@ -102,41 +185,100 @@ BeamRemnants:saturation 5 443:onMode = off 4332:onMode = off -### D0 -> K pi +# Allow the decay of HF +### D0 -> K π 421:onIfMatch = 321 211 -### D0 -> K pi pi0 +### D0 -> K π π0 421:onIfMatch = 321 211 111 +### D0 -> rho K +421:onIfMatch = 213 321 +### D0 -> antiK*0 π0 +421:onIfMatch = 313 111 +### D0 -> K*- π+ +421:onIfMatch = 323 211 +### D0 -> π π +421:onIfMatch = 211 211 +### D0 -> rho+ π- +421:onIfMatch = 213 -211 +### D0 -> π π π0 +421:onIfMatch = 211 211 111 +### D0 -> K K +421:onIfMatch = 321 321 -### D+/- -> K pi pi +### D+/- -> K π π 411:onIfMatch = 321 211 211 -### D+/- -> K* pi +### D+/- -> K π π +411:onIfMatch = 321 211 211 111 +### D+/- -> K* π 411:onIfMatch = 313 211 -### D+/- -> phi pi +### D+/- -> K* K +411:onIfMatch = 313 321 +### D+/- -> antiK* π +411:onIfMatch = 10311 211 +### D+/- -> antiK* K +411:onIfMatch = 10311 321 +### D+/- -> φ π 411:onIfMatch = 333 211 +### D+/- -> K K π +411:onIfMatch = 321 321 211 +### D+/- -> f2(1270) π +411:onIfMatch = 225 211 +### D+/- -> rho π +411:onIfMatch = 113 211 +### D+/- -> π π π +411:onIfMatch = 211 211 211 -### D_s -> K K* -431:onIfMatch = 321 313 -### D_s -> Phi pi +### Ds -> φ π 431:onIfMatch = 333 211 +### Ds -> K* K +431:onIfMatch = 313 321 +### Ds -> φ rho+ +431:onIfMatch = 333 213 +### Ds -> rho π +431:onIfMatch = 113 211 +### Ds -> f2 π +431:onIfMatch = 225 211 +### Ds -> π π π +431:onIfMatch = 211 211 211 +### Ds -> K*(892)0 π+ +431:onIfMatch = 313 211 +### Ds -> f0(1370) K+ +431:onIfMatch = 10221 321 +### Ds -> rho0 K+ +431:onIfMatch = 113 321 +### Ds -> K π π +431:onIfMatch = 321 211 211 +### Ds -> eta π+ +431:onIfMatch = 221 211 -### Lambda_c -> p K* +### Λc -> pK0s +4122:onIfMatch = 2212 311 +### Λc -> p K- π+ π0 +4122:onIfMatch = 2212 321 211 +### Λc -> p K* 4122:onIfMatch = 2212 313 -### Lambda_c -> Delta K +### Λc -> Delta++ K 4122:onIfMatch = 2224 321 -### Lambda_c -> Lambda(1520) pi +### Λc -> Lambda(1520) π 4122:onIfMatch = 102134 211 -### Lambda_c -> p K pi -4122:onIfMatch = 2212 321 211 -### Lambda_c -> pK0s -4122:onIfMatch = 2212 311 +### Λc -> p K- π+ π0 +4122:onIfMatch = 2212 321 211 111 +### Λc -> p π π +4122:onIfMatch = 2212 211 211 +### Λc -> p K K +4122:onIfMatch = 2212 333 -### Xic+ -> pK*0 -4232:onIfMatch = 2212 313 -### Xic+ -> p K- pi+ +### Ξc+ -> p K- π+ 4232:onIfMatch = 2212 321 211 -### Xic+ -> Xi*0 pi+, Xi*->Xi- pi+ +### Ξc+ -> p antiK*0(892) +4232:onIfMatch = 2212 313 +### Ξc+ -> p φ +4232:onIfMatch = 2212 333 +### Ξc+ -> sigma- π+ π+ +4232:onIfMatch = 3222 211 211 +### Ξc+ -> Ξ*0 π+, Ξ*0 -> Ξ- π+ 4232:onIfMatch = 3324 211 -### Xic+ -> Xi- pi+ pi+ +### Ξc+ -> Ξ- π+ π+ 4232:onIfMatch = 3312 211 211 ### Xic0 -> Xi- pi+ @@ -145,4 +287,4 @@ BeamRemnants:saturation 5 ### Omega_c -> Omega pi 4332:onIfMatch = 3334 211 ### Omega_c -> Xi pi -4332:onIfMatch = 3312 211 +4332:onIfMatch = 3312 211 \ No newline at end of file diff --git a/MC/config/PWGHF/pythia8/generator/pythia8_charmhadronic_with_decays_Mode2_CorrBkg.cfg b/MC/config/PWGHF/pythia8/generator/pythia8_charmhadronic_with_decays_Mode2_CorrBkg.cfg new file mode 100644 index 000000000..9dd73f0ab --- /dev/null +++ b/MC/config/PWGHF/pythia8/generator/pythia8_charmhadronic_with_decays_Mode2_CorrBkg.cfg @@ -0,0 +1,242 @@ +### authors: Stefano Politano (stefano.politano@cern.ch), Mattia Faggin (mattia.faggin@cern.ch), Fabrizio Grosa (fabrizio.grosa@cern.ch), Marcello Di Costanzo (marcello.di.costanzo@cern.ch) +### last update: April 2025 + +### beams +Beams:idA 2212 # proton +Beams:idB 2212 # proton +Beams:eCM 13600. # GeV + +### processes +SoftQCD:inelastic on # all inelastic processes + +### decays +ParticleDecays:limitTau0 on +ParticleDecays:tau0Max 10. + +### switching on Pythia Mode2 +ColourReconnection:mode 1 +ColourReconnection:allowDoubleJunRem off +ColourReconnection:m0 0.3 +ColourReconnection:allowJunctions on +ColourReconnection:junctionCorrection 1.20 +ColourReconnection:timeDilationMode 2 +ColourReconnection:timeDilationPar 0.18 +StringPT:sigma 0.335 +StringZ:aLund 0.36 +StringZ:bLund 0.56 +StringFlav:probQQtoQ 0.078 +StringFlav:ProbStoUD 0.2 +StringFlav:probQQ1toQQ0join 0.0275,0.0275,0.0275,0.0275 +MultiPartonInteractions:pT0Ref 2.15 +BeamRemnants:remnantMode 1 +BeamRemnants:saturation 5 + +# Correct decay lengths (wrong in PYTHIA8 decay table) +# Lb +5122:tau0 = 0.4390 +# Xic0 +4132:tau0 = 0.0455 +# OmegaC +4332:tau0 = 0.0803 + +### HF decays +### BR are set to yield 20% of signal in golden channel and uniform abundance of corr. bkg channels (weighted by BR from PDG) +### +### D0 decays +### D0 -> K- π+ (20%) +421:oneChannel = 1 0.20 0 -321 211 ### D0 -> K- π+ 3.94% +### D0 -> K- π+ π0 (20%) +421:addChannel = 1 0.01 0 -321 211 111 ### D0 -> K- π+ π0 (non-resonant) 1.15% (e.g. 115/(115+231+195+1120)*0.2) +421:addChannel = 1 0.14 0 213 -321 ### D0 -> rho+ K- 11.2% +421:addChannel = 1 0.02 0 -313 111 ### D0 -> antiK*0(892) π0 1.95% +421:addChannel = 1 0.03 0 -323 211 ### D0 -> K*-(892) π+ 2.31% +### D0 -> π- π+ (20%) +421:addChannel = 1 0.20 0 -211 211 ### D0 -> π- π+ (non-resonant) 1.0e-4 +### D0 -> π- π+ π0 (20%) +421:addChannel = 1 0.14 0 213 -211 ### D0 -> rho+ π- 1.01% +421:addChannel = 1 0.06 0 -211 211 111 ### D0 -> π- π+ π0 (non-resonant) 1.3e-4 +### D0 -> K- K+ (20%) +421:addChannel = 1 0.20 0 -321 321 ### D0 -> K- K+ (non-resonant) 4.08e-3 + +### D+ decays +### D+ -> K- π+ π+ (28%) +411:oneChannel = 1 0.28 0 -321 211 211 ### D+ -> K- π+ π+ 9.38% +### D+ -> K- π+ π+ π0 (small, 5%) +411:addChannel = 1 0.05 0 -321 211 211 111 ### D+ -> K- π+ π+ π0 6.25% +### D+ -> K- K+ π+ (33%) +411:addChannel = 1 0.085 0 -313 321 ### D+ -> K*0(892) K+ 2.49e-3 +411:addChannel = 1 0.062 0 -10311 321 ### D+ -> antiK*0(1430) K+ 1.82e-3 +411:addChannel = 1 0.092 0 333 211 ### D+ -> φ π+ 2.69e-3 +411:addChannel = 1 0.091 0 -321 321 211 ### D+ -> K- K+ π+ (non-resonant) 2.68e-3 +### D+ -> π- π+ π+ (34%) +411:addChannel = 1 0.09 0 113 211 ### D+ -> rho0 π+ 8.4e-4 +411:addChannel = 1 0.05 0 225 211 ### D+ -> f2(1270) π+ 4.6e-4 +411:addChannel = 1 0.20 0 -211 211 211 ### D+ -> π- π+ π+ (non-resonant) 1.0e-4 + +### Ds+ decays +### Ds+ -> K- K+ π+ (20%) +431:oneChannel = 1 0.100 0 333 211 ### Ds+ -> φ(1020) π+ 2.21% +431:addChannel = 1 0.100 0 -313 321 ### Ds+ -> antiK*(892) K+ 2.58% +### Ds+ -> K- K+ π+ π0 (small, 5%) +431:addChannel = 1 0.050 0 333 213 ### Ds+ -> φ(1020) rho 5.50% +### Ds+ -> π- π+ π+ (25%) +431:addChannel = 1 0.005 0 113 211 ### Ds+ -> rho π+ 1.1e-4 +431:addChannel = 1 0.005 0 225 211 ### Ds+ -> f2(1270) π+ 1.4e-3 +431:addChannel = 1 0.240 0 -211 211 211 ### Ds+ -> π- π+ π+ 9.12e-3 (s-wave) +### Ds+ -> π- K+ π+ (25%) +431:addChannel = 1 0.07 0 313 211 ### Ds+ -> K*(892)0 π+ 1.67e-3 +431:addChannel = 1 0.05 0 10221 321 ### Ds+ -> f0(1370) K+ 1.2e-3 +431:addChannel = 1 0.09 0 113 321 ### Ds+ -> rho0 K+ 2.17e-3 +431:addChannel = 1 0.04 0 -211 321 211 ### Ds+ -> π- K+ π+ (non-resonant) 1.16-3 +### Ds+ -> π+ π- π+ π0 (25%) +431:addChannel = 1 0.250 0 221 211 ### Ds+ -> eta π+ -> π0 π+ π+ π- (affects D+ golden channel) + +## Λc decays +### Λc+ -> p K- π+ (20%, BR set up to 20%) +4122:oneChannel = 1 0.080 0 2212 -321 211 ### Λc+ -> p K- π+ (non-resonant) 3.5% +4122:addChannel = 1 0.045 100 2212 -313 ### Λc+ -> p K*0(892) 1.96% +4122:addChannel = 1 0.025 100 2224 -321 ### Λc+ -> Delta++ K- 1.08% +4122:addChannel = 1 0.050 100 102134 211 ### Λc+ -> Lambda(1520) K- 2.20e-3 +### Λc+ -> p K- π+ π0 (small, 5%) +4122:addChannel = 1 0.050 0 2212 -321 211 111 ### Λc+ -> p K- π+ π0 (non-resonant) 4.6% +### Λc+ -> p π- π+ (25%) +4122:addChannel = 1 0.250 0 2212 -211 211 ### Λc+ -> p π+ π+ 4.59% +### Λc+ -> p K- K+ (25%) +4122:addChannel = 1 0.250 0 2212 333 ### Λc+ -> p phi 1.06% + +### Ξc+ decays (unfiormly distributed) +### Ξc+ -> p K- π+ (34%) +4232:oneChannel = 1 0.17 0 2212 -321 211 ### Ξc+ -> p K- π+ +4232:addChannel = 1 0.17 0 2212 -313 ### Ξc+ -> p antiK*0(892) +### Ξc+ -> p K- K+ (33%) +4232:addChannel = 1 0.33 0 2212 333 ### Ξc+ -> p φ +### Ξc+ -> sigma+ π+ π- (33%) +4232:addChannel = 1 0.33 0 3222 -211 211 ### Ξc+ -> sigma+ π- π+ + +# Allow the decay of resonances in the decay chain +### K*0(892) -> K- π+ +313:onMode = off +313:onIfAll = 321 211 +### K*(892)+ -> K- π0 +323:onMode = off +323:onIfAll = 321 111 +### K*(1430)0 -> K- π+ +10311:onMode = off +10311:onIfAll = 321 211 +### rho+ -> π+ π0 +213:onMode = off +213:onIfAll = 211 111 +### φ -> K+ K- +333:onMode = off +333:onIfAll = 321 321 +### rho0 -> π+ π- +113:onMode = off +113:onIfAll = 211 211 +### f2(1270) -> π+ π- +225:onMode = off +225:onIfAll = 211 211 +### f0(1370) -> π+ π- +10221:onMode = off +10221:onIfAll = 211 211 +### eta -> π+ π- +221:onMode = off +221:onIfAll = 111 211 211 +### for Λc -> Delta++ K- +2224:onMode = off +2224:onIfAll = 2212 211 +### for Λc -> Lambda(1520) K- +102134:onMode = off +102134:onIfAll = 2212 321 + +### Switch off all decay channels +411:onMode = off +421:onMode = off +431:onMode = off +4122:onMode = off +4232:onMode = off + +# Allow the decay of HF +### D0 -> K π +421:onIfMatch = 321 211 +### D0 -> K π π0 +421:onIfMatch = 321 211 111 +### D0 -> rho K +421:onIfMatch = 213 321 +### D0 -> antiK*0 π0 +421:onIfMatch = 313 111 +### D0 -> K*- π+ +421:onIfMatch = 323 211 +### D0 -> π π +421:onIfMatch = 211 211 +### D0 -> rho+ π- +421:onIfMatch = 213 -211 +### D0 -> π π π0 +421:onIfMatch = 211 211 111 +### D0 -> K K +421:onIfMatch = 321 321 + +### D+/- -> K π π +411:onIfMatch = 321 211 211 +### D+/- -> K π π +411:onIfMatch = 321 211 211 111 +### D+/- -> K* K +411:onIfMatch = 313 321 +### D+/- -> antiK* π +411:onIfMatch = 10311 321 +### D+/- -> φ π +411:onIfMatch = 333 211 +### D+/- -> K K π +411:onIfMatch = 321 321 211 +### D+/- -> f2(1270) π +411:onIfMatch = 225 211 +### D+/- -> rho π +411:onIfMatch = 113 211 +### D+/- -> π π π +411:onIfMatch = 211 211 211 + +### Ds -> φ π +431:onIfMatch = 333 211 +### Ds -> K* K +431:onIfMatch = 313 321 +### Ds -> φ rho+ +431:onIfMatch = 333 213 +### Ds -> rho π +431:onIfMatch = 113 211 +### Ds -> f2 π +431:onIfMatch = 225 211 +### Ds -> π π π +431:onIfMatch = 211 211 211 +### Ds -> K*(892)0 π+ +431:onIfMatch = 313 211 +### Ds -> f0(1370) K+ +431:onIfMatch = 10221 321 +### Ds -> rho0 K+ +431:onIfMatch = 113 321 +### Ds -> K π π +431:onIfMatch = 321 211 211 +### Ds -> eta π+ +431:onIfMatch = 221 211 + +### Λc -> p K π +4122:onIfMatch = 2212 321 211 +### Λc -> p K* +4122:onIfMatch = 2212 313 +### Λc -> Delta++ K +4122:onIfMatch = 2224 321 +### Λc -> Lambda(1520) π +4122:onIfMatch = 102134 211 +### Λc -> p K- π+ π0 +4122:onIfMatch = 2212 321 211 111 +### Λc -> p π π +4122:onIfMatch = 2212 211 211 +### Λc -> p K K +4122:onIfMatch = 2212 333 + +### Ξc+ -> p K- π+ +4232:onIfMatch = 2212 321 211 +### Ξc+ -> p antiK*0(892) +4232:onIfMatch = 2212 313 +### Ξc+ -> p φ +4232:onIfMatch = 2212 333 +### Ξc+ -> sigma- π+ π+ +4232:onIfMatch = 3222 211 211 \ No newline at end of file diff --git a/MC/config/PWGHF/pythia8/generator/pythia8_charmhadronic_with_decays_Mode2_CorrBkgSigmaC.cfg b/MC/config/PWGHF/pythia8/generator/pythia8_charmhadronic_with_decays_Mode2_CorrBkgSigmaC.cfg new file mode 100644 index 000000000..0d61dfe3b --- /dev/null +++ b/MC/config/PWGHF/pythia8/generator/pythia8_charmhadronic_with_decays_Mode2_CorrBkgSigmaC.cfg @@ -0,0 +1,84 @@ +### authors: Mattia Faggin (mattia.faggin@cern.ch) +### last update: July 2025 + +### beams +Beams:idA 2212 # proton +Beams:idB 2212 # proton +Beams:eCM 13600. # GeV + +### processes +SoftQCD:inelastic on # all inelastic processes + +### decays +ParticleDecays:limitTau0 on +ParticleDecays:tau0Max 10. + +### switching on Pythia Mode2 +ColourReconnection:mode 1 +ColourReconnection:allowDoubleJunRem off +ColourReconnection:m0 0.3 +ColourReconnection:allowJunctions on +ColourReconnection:junctionCorrection 1.20 +ColourReconnection:timeDilationMode 2 +ColourReconnection:timeDilationPar 0.18 +StringPT:sigma 0.335 +StringZ:aLund 0.36 +StringZ:bLund 0.56 +StringFlav:probQQtoQ 0.078 +StringFlav:ProbStoUD 0.2 +StringFlav:probQQ1toQQ0join 0.0275,0.0275,0.0275,0.0275 +MultiPartonInteractions:pT0Ref 2.15 +BeamRemnants:remnantMode 1 +BeamRemnants:saturation 5 + +# switch off charm-hadron decays +4122:onMode = off +14122:onMode = off ### Lambda_c(2595)+ already present in PYTHIA +4124:onMode = off ### Lambda_c(2625)+ already present in PYTHIA + +## Λc decays +### Λc+ -> p K- π+ +4122:oneChannel = 1 0.0350 0 2212 -321 211 ### Λc+ -> p K- π+ (non-resonant) 3.5% +4122:addChannel = 1 0.0196 100 2212 -313 ### Λc+ -> p K*0(892) 1.96% +4122:addChannel = 1 0.0108 100 2224 -321 ### Λc+ -> Delta++ K- 1.08% +4122:addChannel = 1 0.0022 100 102134 211 ### Λc+ -> Lambda(1520) K- 2.20e-3 +4122:onIfMatch = 2212 321 211 +4122:onIfMatch = 2212 313 +4122:onIfMatch = 2224 321 +4122:onIfMatch = 102134 211 +### Λc(2595)+ +14122:oneChannel = 1 0.24 0 4222 -211 ### Λc(2595)+ -> Σc(2455)++ π- (24%) +14122:addChannel = 1 0.24 0 4112 211 ### Λc(2595)+ -> Σc(2455)0 π+ (24%) +14122:addChannel = 1 0.18 0 4122 211 -211 ### Λc(2595)+ -> Λc+ π+ π- (18%) +14122:onIfMatch = 4222 211 ### Λc(2595)+ -> Σc(2455)++ π- +14122:onIfMatch = 4112 211 ### Λc(2595)+ -> Σc(2455)0 π+ +14122:onIfMatch = 4122 211 211 ### Λc(2595)+ -> Λc+ π+ π- +### Λc(2625)+ +4124:oneChannel = 1 0.24 0 4222 -211 ### Λc(2592)+ -> Σc(2455)++ π- (24%) +4124:addChannel = 1 0.24 0 4112 211 ### Λc(2592)+ -> Σc(2455)0 π+ (24%) +4124:addChannel = 1 0.18 0 4122 211 -211 ### Λc(2592)+ -> Λc+ π+ π- (18%) +4124:onIfMatch = 4222 211 ### Λc(2625)+ -> Σc(2455)++ π- +4124:onIfMatch = 4112 211 ### Λc(2625)+ -> Σc(2455)0 π+ +4124:onIfMatch = 4122 211 211 ### Λc(2625)+ -> Λc+ π+ π- + +# Correct decay lengths (wrong in PYTHIA8 decay table) +# Lb +5122:tau0 = 0.4390 +# Xic0 +4132:tau0 = 0.0455 +# OmegaC +4332:tau0 = 0.0803 + +# Correct Breit-Wigner width +4124:mWidth = 0.00052 # <0.52 MeV + +# Force the decay of resonances in the decay chain +### K*0(892) -> K- π+ +313:onMode = off +313:onIfAll = 321 211 +### for Λc -> Delta++ K- +2224:onMode = off +2224:onIfAll = 2212 211 +### for Λc -> Lambda(1520) K- +102134:onMode = off +102134:onIfAll = 2212 321 diff --git a/MC/config/PWGHF/pythia8/generator/pythia8_charmhadronic_with_decays_Mode2_hardQCD_5TeV.cfg b/MC/config/PWGHF/pythia8/generator/pythia8_charmhadronic_with_decays_Mode2_hardQCD_5TeV.cfg index cbce46503..81da1a4ba 100644 --- a/MC/config/PWGHF/pythia8/generator/pythia8_charmhadronic_with_decays_Mode2_hardQCD_5TeV.cfg +++ b/MC/config/PWGHF/pythia8/generator/pythia8_charmhadronic_with_decays_Mode2_hardQCD_5TeV.cfg @@ -46,44 +46,127 @@ BeamRemnants:saturation 5 4332:tau0 = 0.0803 ### Force golden charm hadrons decay modes for D2H studies -### add D0 decays absent in PYTHIA8 decay table and set BRs from PDG for other -421:oneChannel = 1 0.0389 0 -321 211 -421:addChannel = 1 0.00389 0 -321 211 111 -### add D+ decays absent in PYTHIA8 decay table and set BRs from PDG for other -411:oneChannel = 1 0.0752 0 -321 211 211 -411:addChannel = 1 0.0104 0 -313 211 -411:addChannel = 1 0.0156 0 311 211 -411:addChannel = 1 0.0752 0 333 211 # to have the same amount of D+->KKpi and D+->Kpipi -## add Lc decays absent in PYTHIA8 decay table and set BRs from PDG for other -4122:oneChannel = 1 0.0196 100 2212 -313 -4122:addChannel = 1 0.0108 100 2224 -321 -4122:addChannel = 1 0.022 100 102134 211 -4122:addChannel = 1 0.035 0 2212 -321 211 -4122:addChannel = 1 0.0159 0 2212 311 -### add Xic+ decays absent in PYTHIA8 decay table -4232:addChannel = 1 0.2 0 2212 -313 -4232:addChannel = 1 0.2 0 2212 -321 211 -4232:addChannel = 1 0.2 0 3324 211 -4232:addChannel = 1 0.2 0 3312 211 211 +# HF decays +### BR are set to yield 50% of signal in golden channel and uniform abundance of corr. bkg channels (weighted by BR from PDG) +### +### D0 decays +### D0 -> K- π+ (50%) +421:oneChannel = 1 0.50000 0 -321 211 ### D0 -> K- π+ 3.94% +### D0 -> K- π+ π0 (12.50%) +421:addChannel = 1 0.00625 0 -321 211 111 ### D0 -> K- π+ π0 (non-resonant) 1.15% (e.g. 115/(115+231+195+1120)*0.2) +421:addChannel = 1 0.08750 0 213 -321 ### D0 -> rho+ K- 11.2% +421:addChannel = 1 0.01250 0 -313 111 ### D0 -> antiK*0(892) π0 1.95% +421:addChannel = 1 0.01875 0 -323 211 ### D0 -> K*-(892) π+ 2.31% +### D0 -> π- π+ (12.50%) +421:addChannel = 1 0.12500 0 -211 211 ### D0 -> π- π+ (non-resonant) 1.0e-4 +### D0 -> π- π+ π0 (12.50%) +421:addChannel = 1 0.08750 0 213 -211 ### D0 -> rho+ π- 1.01% +421:addChannel = 1 0.03750 0 -211 211 111 ### D0 -> π- π+ π0 (non-resonant) 1.3e-4 +### D0 -> K- K+ (12.50%) +421:addChannel = 1 0.12500 0 -321 321 ### D0 -> K- K+ (non-resonant) 4.08e-3 + +### D+ decays +### D+ -> K- π+ π+ (50%) +411:oneChannel = 1 0.40189 0 -321 211 211 ### D+ -> K- π+ π+ 9.38% +411:addChannel = 1 0.05356 0 -10311 211 ### D+ -> antiK*0(1430) π+ 1.25% +411:addChannel = 1 0.04455 0 -313 211 ### D+ -> K*0(892) pi+ 1.04% +### D+ -> K- π+ π+ π0 (small, 3%) +411:addChannel = 1 0.03000 0 -321 211 211 111 ### D+ -> K- π+ π+ π0 6.25% +### D+ -> K- K+ π+ (36.00%, set 25% for D+ -> φ π+, 11% for the rest) +411:addChannel = 1 0.25000 0 333 211 ### D+ -> φ π+ 2.69e-3 !needed for signal +411:addChannel = 1 0.03929 0 -313 321 ### D+ -> K*0(892) K+ 2.49e-3 +411:addChannel = 1 0.02865 0 -10311 321 ### D+ -> antiK*0(1430) K+ 1.82e-3 +411:addChannel = 1 0.04206 0 -321 321 211 ### D+ -> K- K+ π+ (non-resonant) 2.68e-3 +### D+ -> π- π+ π+ (11.00%) +411:addChannel = 1 0.02911 0 113 211 ### D+ -> rho0 π+ 8.4e-4 +411:addChannel = 1 0.01618 0 225 211 ### D+ -> f2(1270) π+ 4.6e-4 +411:addChannel = 1 0.06471 0 -211 211 211 ### D+ -> π- π+ π+ (non-resonant) 1.0e-4 + +### Ds+ decays +### Ds+ -> K- K+ π+ (50%) +431:oneChannel = 1 0.50000 0 333 211 ### Ds+ -> φ(1020) π+ 2.21% +431:addChannel = 1 0.15000 0 -313 321 ### Ds+ -> antiK*(892) K+ 2.58% +### Ds+ -> K- K+ π+ π0 (small, 2%) +431:addChannel = 1 0.02000 0 333 213 ### Ds+ -> φ(1020) rho 5.50% +### Ds+ -> π- π+ π+ (11.00%) +431:addChannel = 1 0.00220 0 113 211 ### Ds+ -> rho π+ 1.1e-4 +431:addChannel = 1 0.00220 0 225 211 ### Ds+ -> f2(1270) π+ 1.4e-3 +431:addChannel = 1 0.10560 0 -211 211 211 ### Ds+ -> π- π+ π+ 9.12e-3 (s-wave) +### Ds+ -> π- K+ π+ (11.00%) +431:addChannel = 1 0.03080 0 313 211 ### Ds+ -> K*(892)0 π+ 1.67e-3 +431:addChannel = 1 0.02200 0 10221 321 ### Ds+ -> f0(1370) K+ 1.2e-3 +431:addChannel = 1 0.03960 0 113 321 ### Ds+ -> rho0 K+ 2.17e-3 +431:addChannel = 1 0.01760 0 -211 321 211 ### Ds+ -> π- K+ π+ (non-resonant) 1.16-3 +### Ds+ -> π+ π- π+ π0 (11.00%) +431:addChannel = 1 0.11000 0 221 211 ### Ds+ -> eta π+ -> π0 π+ π+ π- (affects D+ golden channel) + +## Λc decays +### Λc+ -> p K- π+ (36%) +4122:oneChannel = 1 0.14400 0 2212 -321 211 ### Λc+ -> p K- π+ (non-resonant) 3.5% +4122:addChannel = 1 0.08100 100 2212 -313 ### Λc+ -> p K*0(892) 1.96% +4122:addChannel = 1 0.04500 100 2224 -321 ### Λc+ -> Delta++ K- 1.08% +4122:addChannel = 1 0.09000 100 102134 211 ### Λc+ -> Lambda(1520) K- 2.20e-3 +### Λc+ -> p K0S (36%) +4122:addChannel = 1 0.36000 0 2212 311 ### Λc+ -> p K0S 1.59% +### Λc+ -> p K- π+ π0 (small, 3%) +4122:addChannel = 1 0.03000 0 2212 -321 211 111 ### Λc+ -> p K- π+ π0 (non-resonant) 4.6% +### Λc+ -> p π- π+ (12.50%) +4122:addChannel = 1 0.12500 0 2212 -211 211 ### Λc+ -> p π+ π+ 4.59% +### Λc+ -> p K- K+ (12.50%) +4122:addChannel = 1 0.12500 0 2212 333 ### Λc+ -> p phi 1.06% + +## Xic decays +### Ξc+ -> p K- π+ (35%) +4232:oneChannel = 1 0.17500 0 2212 -321 211 ### Ξc+ -> p K- π+ 6.18e-3 +4232:addChannel = 1 0.17500 0 2212 -313 ### Ξc+ -> p antiK*0(892) +### Ξc+ -> Ξ- π+ π+ (35%) (set the same as Ξc+ -> p K- π+) +4232:addChannel = 1 0.35000 0 3312 211 211 ### Ξc+ -> Ξ- π+ π+ 2.86% +### Ξc+ -> p φ (10%) +4232:addChannel = 1 0.10000 0 2212 333 ### Ξc+ -> p φ +### Ξc+ -> sigma+ π+ π- (10%) +4232:addChannel = 1 0.12500 0 3222 -211 211 ### Ξc+ -> sigma+ π- π+ 1.37% +### Ξc+ -> Ξ*0 π+ (10%) +4232:addChannel = 1 0.12500 0 3324 211 + ### add Xic0 decays absent in PYTHIA8 decay table -4132:addChannel = 1 0.0143 0 3312 211 +4132:oneChannel = 1 0.0143 0 3312 211 + ### add OmegaC decays absent in PYTHIA8 decay table -4332:addChannel = 1 0.5 0 3334 211 +4332:oneChannel = 1 0.5 0 3334 211 4332:addChannel = 1 0.5 0 3312 211 -### K* -> K pi +# Allow the decay of resonances in the decay chain +### K*0(892) -> K- π+ 313:onMode = off 313:onIfAll = 321 211 -### for Ds -> Phi pi+ +### K*(892)+ -> K- π0 +323:onMode = off +323:onIfAll = 321 111 +### K*(1430)0 -> K- π+ +10311:onMode = off +10311:onIfAll = 321 211 +### rho+ -> π+ π0 +213:onMode = off +213:onIfAll = 211 111 +### φ -> K+ K- 333:onMode = off 333:onIfAll = 321 321 -### for D0 -> rho0 pi+ k- +### rho0 -> π+ π- 113:onMode = off 113:onIfAll = 211 211 -### for Lambda_c -> Delta++ K- +### f2(1270) -> π+ π- +225:onMode = off +225:onIfAll = 211 211 +### f0(1370) -> π+ π- +10221:onMode = off +10221:onIfAll = 211 211 +### eta -> π+ π- +221:onMode = off +221:onIfAll = 111 211 211 +### for Λc -> Delta++ K- 2224:onMode = off 2224:onIfAll = 2212 211 -### for Lambda_c -> Lambda(1520) K- +### for Λc -> Lambda(1520) K- 102134:onMode = off 102134:onIfAll = 2212 321 ### for Xic0 -> pi Xi -> pi pi Lambda -> pi pi pi p @@ -96,7 +179,7 @@ BeamRemnants:saturation 5 3334:onMode = off 3334:onIfAll = 3122 -321 -### switch off all decay channels +# Switch off all decay channels 411:onMode = off 421:onMode = off 431:onMode = off @@ -106,41 +189,100 @@ BeamRemnants:saturation 5 443:onMode = off 4332:onMode = off -### D0 -> K pi +# Allow the decay of HF +### D0 -> K π 421:onIfMatch = 321 211 -### D0 -> K pi pi0 +### D0 -> K π π0 421:onIfMatch = 321 211 111 +### D0 -> rho K +421:onIfMatch = 213 321 +### D0 -> antiK*0 π0 +421:onIfMatch = 313 111 +### D0 -> K*- π+ +421:onIfMatch = 323 211 +### D0 -> π π +421:onIfMatch = 211 211 +### D0 -> rho+ π- +421:onIfMatch = 213 -211 +### D0 -> π π π0 +421:onIfMatch = 211 211 111 +### D0 -> K K +421:onIfMatch = 321 321 -### D+/- -> K pi pi +### D+/- -> K π π 411:onIfMatch = 321 211 211 -### D+/- -> K* pi +### D+/- -> K π π +411:onIfMatch = 321 211 211 111 +### D+/- -> K* π 411:onIfMatch = 313 211 -### D+/- -> phi pi +### D+/- -> K* K +411:onIfMatch = 313 321 +### D+/- -> antiK* π +411:onIfMatch = 10311 211 +### D+/- -> antiK* K +411:onIfMatch = 10311 321 +### D+/- -> φ π 411:onIfMatch = 333 211 +### D+/- -> K K π +411:onIfMatch = 321 321 211 +### D+/- -> f2(1270) π +411:onIfMatch = 225 211 +### D+/- -> rho π +411:onIfMatch = 113 211 +### D+/- -> π π π +411:onIfMatch = 211 211 211 -### D_s -> K K* -431:onIfMatch = 321 313 -### D_s -> Phi pi +### Ds -> φ π 431:onIfMatch = 333 211 +### Ds -> K* K +431:onIfMatch = 313 321 +### Ds -> φ rho+ +431:onIfMatch = 333 213 +### Ds -> rho π +431:onIfMatch = 113 211 +### Ds -> f2 π +431:onIfMatch = 225 211 +### Ds -> π π π +431:onIfMatch = 211 211 211 +### Ds -> K*(892)0 π+ +431:onIfMatch = 313 211 +### Ds -> f0(1370) K+ +431:onIfMatch = 10221 321 +### Ds -> rho0 K+ +431:onIfMatch = 113 321 +### Ds -> K π π +431:onIfMatch = 321 211 211 +### Ds -> eta π+ +431:onIfMatch = 221 211 -### Lambda_c -> p K* +### Λc -> pK0s +4122:onIfMatch = 2212 311 +### Λc -> p K- π+ π0 +4122:onIfMatch = 2212 321 211 +### Λc -> p K* 4122:onIfMatch = 2212 313 -### Lambda_c -> Delta K +### Λc -> Delta++ K 4122:onIfMatch = 2224 321 -### Lambda_c -> Lambda(1520) pi +### Λc -> Lambda(1520) π 4122:onIfMatch = 102134 211 -### Lambda_c -> p K pi -4122:onIfMatch = 2212 321 211 -### Lambda_c -> pK0s -4122:onIfMatch = 2212 311 +### Λc -> p K- π+ π0 +4122:onIfMatch = 2212 321 211 111 +### Λc -> p π π +4122:onIfMatch = 2212 211 211 +### Λc -> p K K +4122:onIfMatch = 2212 333 -### Xic+ -> pK*0 -4232:onIfMatch = 2212 313 -### Xic+ -> p K- pi+ +### Ξc+ -> p K- π+ 4232:onIfMatch = 2212 321 211 -### Xic+ -> Xi*0 pi+, Xi*->Xi- pi+ +### Ξc+ -> p antiK*0(892) +4232:onIfMatch = 2212 313 +### Ξc+ -> p φ +4232:onIfMatch = 2212 333 +### Ξc+ -> sigma- π+ π+ +4232:onIfMatch = 3222 211 211 +### Ξc+ -> Ξ*0 π+, Ξ*0 -> Ξ- π+ 4232:onIfMatch = 3324 211 -### Xic+ -> Xi- pi+ pi+ +### Ξc+ -> Ξ- π+ π+ 4232:onIfMatch = 3312 211 211 ### Xic0 -> Xi- pi+ @@ -149,4 +291,4 @@ BeamRemnants:saturation 5 ### Omega_c -> Omega pi 4332:onIfMatch = 3334 211 ### Omega_c -> Xi pi -4332:onIfMatch = 3312 211 +4332:onIfMatch = 3312 211 \ No newline at end of file diff --git a/MC/config/PWGHF/pythia8/generator/pythia8_charmhadronic_with_decays_Mode2_hardQCD_5TeV_CorrBkg.cfg b/MC/config/PWGHF/pythia8/generator/pythia8_charmhadronic_with_decays_Mode2_hardQCD_5TeV_CorrBkg.cfg new file mode 100644 index 000000000..7280c9338 --- /dev/null +++ b/MC/config/PWGHF/pythia8/generator/pythia8_charmhadronic_with_decays_Mode2_hardQCD_5TeV_CorrBkg.cfg @@ -0,0 +1,250 @@ +### authors: Fabrizio Grosa (fabrizio.grosa@cern.ch) +### Mattia Faggin (mattia.faggin@cern.ch) +### Stefano Politano (stefano.politano@cern.ch) +###50 Marcello Di Costanzo (marcello.di.costanzo@cern.ch) +### last update: June 2024 + +### beams +Beams:idA 2212 # proton +Beams:idB 2212 # proton +Beams:eCM 5360. # GeV + +### processes: c-cbar and b-bbar processes +HardQCD:hardccbar on +HardQCD:hardbbbar on +HardQCD:gg2ccbar on +HardQCD:qqbar2ccbar on +HardQCD:gg2bbbar on +HardQCD:qqbar2bbbar on + +### decays +ParticleDecays:limitTau0 on +ParticleDecays:tau0Max 10. + +### switching on Pythia Mode2 +ColourReconnection:mode 1 +ColourReconnection:allowDoubleJunRem off +ColourReconnection:m0 0.3 +ColourReconnection:allowJunctions on +ColourReconnection:junctionCorrection 1.20 +ColourReconnection:timeDilationMode 2 +ColourReconnection:timeDilationPar 0.18 +StringPT:sigma 0.335 +StringZ:aLund 0.36 +StringZ:bLund 0.56 +StringFlav:probQQtoQ 0.078 +StringFlav:ProbStoUD 0.2 +StringFlav:probQQ1toQQ0join 0.0275,0.0275,0.0275,0.0275 +MultiPartonInteractions:pT0Ref 2.15 +BeamRemnants:remnantMode 1 +BeamRemnants:saturation 5 + +# Correct decay lengths (wrong in PYTHIA8 decay table) +# Lb +5122:tau0 = 0.4390 +# Xic0 +4132:tau0 = 0.0455 +# OmegaC +4332:tau0 = 0.0803 + +### HF decays +### BR are set to yield 20% of signal in golden channel and uniform abundance of corr. bkg channels (weighted by BR from PDG) +### +### D0 decays +### D0 -> K- π+ (20%) +421:oneChannel = 1 0.20 0 -321 211 ### D0 -> K- π+ 3.94% +### D0 -> K- π+ π0 (20%) +421:addChannel = 1 0.01 0 -321 211 111 ### D0 -> K- π+ π0 (non-resonant) 1.15% (e.g. 115/(115+231+195+1120)*0.2) +421:addChannel = 1 0.14 0 213 -321 ### D0 -> rho+ K- 11.2% +421:addChannel = 1 0.02 0 -313 111 ### D0 -> antiK*0(892) π0 1.95% +421:addChannel = 1 0.03 0 -323 211 ### D0 -> K*-(892) π+ 2.31% +### D0 -> π- π+ (20%) +421:addChannel = 1 0.20 0 -211 211 ### D0 -> π- π+ (non-resonant) 1.0e-4 +### D0 -> π- π+ π0 (20%) +421:addChannel = 1 0.14 0 213 -211 ### D0 -> rho+ π- 1.01% +421:addChannel = 1 0.06 0 -211 211 111 ### D0 -> π- π+ π0 (non-resonant) 1.3e-4 +### D0 -> K- K+ (20%) +421:addChannel = 1 0.20 0 -321 321 ### D0 -> K- K+ (non-resonant) 4.08e-3 + +### D+ decays +### D+ -> K- π+ π+ (28%) +411:oneChannel = 1 0.28 0 -321 211 211 ### D+ -> K- π+ π+ 9.38% +### D+ -> K- π+ π+ π0 (small, 5%) +411:addChannel = 1 0.05 0 -321 211 211 111 ### D+ -> K- π+ π+ π0 6.25% +### D+ -> K- K+ π+ (33%) +411:addChannel = 1 0.085 0 -313 321 ### D+ -> K*0(892) K+ 2.49e-3 +411:addChannel = 1 0.062 0 -10311 321 ### D+ -> antiK*0(1430) K+ 1.82e-3 +411:addChannel = 1 0.092 0 333 211 ### D+ -> φ π+ 2.69e-3 +411:addChannel = 1 0.091 0 -321 321 211 ### D+ -> K- K+ π+ (non-resonant) 2.68e-3 +### D+ -> π- π+ π+ (34%) +411:addChannel = 1 0.09 0 113 211 ### D+ -> rho0 π+ 8.4e-4 +411:addChannel = 1 0.05 0 225 211 ### D+ -> f2(1270) π+ 4.6e-4 +411:addChannel = 1 0.20 0 -211 211 211 ### D+ -> π- π+ π+ (non-resonant) 1.0e-4 + +### Ds+ decays +### Ds+ -> K- K+ π+ (20%) +431:oneChannel = 1 0.100 0 333 211 ### Ds+ -> φ(1020) π+ 2.21% +431:addChannel = 1 0.100 0 -313 321 ### Ds+ -> antiK*(892) K+ 2.58% +### Ds+ -> K- K+ π+ π0 (small, 5%) +431:addChannel = 1 0.050 0 333 213 ### Ds+ -> φ(1020) rho 5.50% +### Ds+ -> π- π+ π+ (25%) +431:addChannel = 1 0.005 0 113 211 ### Ds+ -> rho π+ 1.1e-4 +431:addChannel = 1 0.005 0 225 211 ### Ds+ -> f2(1270) π+ 1.4e-3 +431:addChannel = 1 0.240 0 -211 211 211 ### Ds+ -> π- π+ π+ 9.12e-3 (s-wave) +### Ds+ -> π- K+ π+ (25%) +431:addChannel = 1 0.07 0 313 211 ### Ds+ -> K*(892)0 π+ 1.67e-3 +431:addChannel = 1 0.05 0 10221 321 ### Ds+ -> f0(1370) K+ 1.2e-3 +431:addChannel = 1 0.09 0 113 321 ### Ds+ -> rho0 K+ 2.17e-3 +431:addChannel = 1 0.04 0 -211 321 211 ### Ds+ -> π- K+ π+ (non-resonant) 1.16-3 +### Ds+ -> π+ π- π+ π0 (25%) +431:addChannel = 1 0.250 0 221 211 ### Ds+ -> eta π+ -> π0 π+ π+ π- (affects D+ golden channel) + +## Λc decays +### Λc+ -> p K- π+ (20%, BR set up to 20%) +4122:oneChannel = 1 0.080 0 2212 -321 211 ### Λc+ -> p K- π+ (non-resonant) 3.5% +4122:addChannel = 1 0.045 100 2212 -313 ### Λc+ -> p K*0(892) 1.96% +4122:addChannel = 1 0.025 100 2224 -321 ### Λc+ -> Delta++ K- 1.08% +4122:addChannel = 1 0.050 100 102134 211 ### Λc+ -> Lambda(1520) K- 2.20e-3 +### Λc+ -> p K- π+ π0 (small, 5%) +4122:addChannel = 1 0.050 0 2212 -321 211 111 ### Λc+ -> p K- π+ π0 (non-resonant) 4.6% +### Λc+ -> p π- π+ (25%) +4122:addChannel = 1 0.250 0 2212 -211 211 ### Λc+ -> p π+ π+ 4.59% +### Λc+ -> p K- K+ (25%) +4122:addChannel = 1 0.250 0 2212 333 ### Λc+ -> p phi 1.06% + +### Ξc+ decays (unfiormly distributed) +### Ξc+ -> p K- π+ (34%) +4232:oneChannel = 1 0.17 0 2212 -321 211 ### Ξc+ -> p K- π+ +4232:addChannel = 1 0.17 0 2212 -313 ### Ξc+ -> p antiK*0(892) +### Ξc+ -> p K- K+ (33%) +4232:addChannel = 1 0.33 0 2212 333 ### Ξc+ -> p φ +### Ξc+ -> sigma+ π+ π- (33%) +4232:addChannel = 1 0.33 0 3222 -211 211 ### Ξc+ -> sigma+ π- π+ + +# Allow the decay of resonances in the decay chain +### K*0(892) -> K- π+ +313:onMode = off +313:onIfAll = 321 211 +### K*(892)+ -> K- π0 +323:onMode = off +323:onIfAll = 321 111 +### K*(1430)0 -> K- π+ +10311:onMode = off +10311:onIfAll = 321 211 +### rho+ -> π+ π0 +213:onMode = off +213:onIfAll = 211 111 +### φ -> K+ K- +333:onMode = off +333:onIfAll = 321 321 +### rho0 -> π+ π- +113:onMode = off +113:onIfAll = 211 211 +### f2(1270) -> π+ π- +225:onMode = off +225:onIfAll = 211 211 +### f0(1370) -> π+ π- +10221:onMode = off +10221:onIfAll = 211 211 +### eta -> π+ π- +221:onMode = off +221:onIfAll = 111 211 211 +### for Λc -> Delta++ K- +2224:onMode = off +2224:onIfAll = 2212 211 +### for Λc -> Lambda(1520) K- +102134:onMode = off +102134:onIfAll = 2212 321 + +### Switch off all decay channels +411:onMode = off +421:onMode = off +431:onMode = off +4122:onMode = off +4232:onMode = off + +# Allow the decay of HF +### D0 -> K π +421:onIfMatch = 321 211 +### D0 -> K π π0 +421:onIfMatch = 321 211 111 +### D0 -> rho K +421:onIfMatch = 213 321 +### D0 -> antiK*0 π0 +421:onIfMatch = 313 111 +### D0 -> K*- π+ +421:onIfMatch = 323 211 +### D0 -> π π +421:onIfMatch = 211 211 +### D0 -> rho+ π- +421:onIfMatch = 213 -211 +### D0 -> π π π0 +421:onIfMatch = 211 211 111 +### D0 -> K K +421:onIfMatch = 321 321 + +### D+/- -> K π π +411:onIfMatch = 321 211 211 +### D+/- -> K π π +411:onIfMatch = 321 211 211 111 +### D+/- -> K* K +411:onIfMatch = 313 321 +### D+/- -> antiK* π +411:onIfMatch = 10311 321 +### D+/- -> φ π +411:onIfMatch = 333 211 +### D+/- -> K K π +411:onIfMatch = 321 321 211 +### D+/- -> f2(1270) π +411:onIfMatch = 225 211 +### D+/- -> rho π +411:onIfMatch = 113 211 +### D+/- -> π π π +411:onIfMatch = 211 211 211 + +### Ds -> φ π +431:onIfMatch = 333 211 +### Ds -> K* K +431:onIfMatch = 313 321 +### Ds -> φ rho+ +431:onIfMatch = 333 213 +### Ds -> rho π +431:onIfMatch = 113 211 +### Ds -> f2 π +431:onIfMatch = 225 211 +### Ds -> π π π +431:onIfMatch = 211 211 211 +### Ds -> K*(892)0 π+ +431:onIfMatch = 313 211 +### Ds -> f0(1370) K+ +431:onIfMatch = 10221 321 +### Ds -> rho0 K+ +431:onIfMatch = 113 321 +### Ds -> K π π +431:onIfMatch = 321 211 211 +### Ds -> eta π+ +431:onIfMatch = 221 211 + +### Λc -> p K π +4122:onIfMatch = 2212 321 211 +### Λc -> p K* +4122:onIfMatch = 2212 313 +### Λc -> Delta++ K +4122:onIfMatch = 2224 321 +### Λc -> Lambda(1520) π +4122:onIfMatch = 102134 211 +### Λc -> p K- π+ π0 +4122:onIfMatch = 2212 321 211 111 +### Λc -> p π π +4122:onIfMatch = 2212 211 211 +### Λc -> p K K +4122:onIfMatch = 2212 333 + +### Ξc+ -> p K- π+ +4232:onIfMatch = 2212 321 211 +### Ξc+ -> p antiK*0(892) +4232:onIfMatch = 2212 313 +### Ξc+ -> p φ +4232:onIfMatch = 2212 333 +### Ξc+ -> sigma- π+ π+ +4232:onIfMatch = 3222 211 211 \ No newline at end of file diff --git a/MC/config/PWGHF/pythia8/generator/pythia8_charmhadronic_with_decays_Mode2_pp_ref.cfg b/MC/config/PWGHF/pythia8/generator/pythia8_charmhadronic_with_decays_Mode2_pp_ref.cfg index 63ce139a5..16d19709f 100644 --- a/MC/config/PWGHF/pythia8/generator/pythia8_charmhadronic_with_decays_Mode2_pp_ref.cfg +++ b/MC/config/PWGHF/pythia8/generator/pythia8_charmhadronic_with_decays_Mode2_pp_ref.cfg @@ -42,44 +42,127 @@ BeamRemnants:saturation 5 4332:tau0 = 0.0803 ### Force golden charm hadrons decay modes for D2H studies -### add D0 decays absent in PYTHIA8 decay table and set BRs from PDG for other -421:oneChannel = 1 0.0389 0 -321 211 -421:addChannel = 1 0.00389 0 -321 211 111 -### add D+ decays absent in PYTHIA8 decay table and set BRs from PDG for other -411:oneChannel = 1 0.0752 0 -321 211 211 -411:addChannel = 1 0.0104 0 -313 211 -411:addChannel = 1 0.0156 0 311 211 -411:addChannel = 1 0.0752 0 333 211 # to have the same amount of D+->KKpi and D+->Kpipi -## add Lc decays absent in PYTHIA8 decay table and set BRs from PDG for other -4122:oneChannel = 1 0.0196 100 2212 -313 -4122:addChannel = 1 0.0108 100 2224 -321 -4122:addChannel = 1 0.022 100 102134 211 -4122:addChannel = 1 0.035 0 2212 -321 211 -4122:addChannel = 1 0.0159 0 2212 311 -### add Xic+ decays absent in PYTHIA8 decay table -4232:addChannel = 1 0.2 0 2212 -313 -4232:addChannel = 1 0.2 0 2212 -321 211 -4232:addChannel = 1 0.2 0 3324 211 -4232:addChannel = 1 0.2 0 3312 211 211 +# HF decays +### BR are set to yield 50% of signal in golden channel and uniform abundance of corr. bkg channels (weighted by BR from PDG) +### +### D0 decays +### D0 -> K- π+ (50%) +421:oneChannel = 1 0.50000 0 -321 211 ### D0 -> K- π+ 3.94% +### D0 -> K- π+ π0 (12.50%) +421:addChannel = 1 0.00625 0 -321 211 111 ### D0 -> K- π+ π0 (non-resonant) 1.15% (e.g. 115/(115+231+195+1120)*0.2) +421:addChannel = 1 0.08750 0 213 -321 ### D0 -> rho+ K- 11.2% +421:addChannel = 1 0.01250 0 -313 111 ### D0 -> antiK*0(892) π0 1.95% +421:addChannel = 1 0.01875 0 -323 211 ### D0 -> K*-(892) π+ 2.31% +### D0 -> π- π+ (12.50%) +421:addChannel = 1 0.12500 0 -211 211 ### D0 -> π- π+ (non-resonant) 1.0e-4 +### D0 -> π- π+ π0 (12.50%) +421:addChannel = 1 0.08750 0 213 -211 ### D0 -> rho+ π- 1.01% +421:addChannel = 1 0.03750 0 -211 211 111 ### D0 -> π- π+ π0 (non-resonant) 1.3e-4 +### D0 -> K- K+ (12.50%) +421:addChannel = 1 0.12500 0 -321 321 ### D0 -> K- K+ (non-resonant) 4.08e-3 + +### D+ decays +### D+ -> K- π+ π+ (50%) +411:oneChannel = 1 0.40189 0 -321 211 211 ### D+ -> K- π+ π+ 9.38% +411:addChannel = 1 0.05356 0 -10311 211 ### D+ -> antiK*0(1430) π+ 1.25% +411:addChannel = 1 0.04455 0 -313 211 ### D+ -> K*0(892) pi+ 1.04% +### D+ -> K- π+ π+ π0 (small, 3%) +411:addChannel = 1 0.03000 0 -321 211 211 111 ### D+ -> K- π+ π+ π0 6.25% +### D+ -> K- K+ π+ (36.00%, set 25% for D+ -> φ π+, 11% for the rest) +411:addChannel = 1 0.25000 0 333 211 ### D+ -> φ π+ 2.69e-3 !needed for signal +411:addChannel = 1 0.03929 0 -313 321 ### D+ -> K*0(892) K+ 2.49e-3 +411:addChannel = 1 0.02865 0 -10311 321 ### D+ -> antiK*0(1430) K+ 1.82e-3 +411:addChannel = 1 0.04206 0 -321 321 211 ### D+ -> K- K+ π+ (non-resonant) 2.68e-3 +### D+ -> π- π+ π+ (11.00%) +411:addChannel = 1 0.02911 0 113 211 ### D+ -> rho0 π+ 8.4e-4 +411:addChannel = 1 0.01618 0 225 211 ### D+ -> f2(1270) π+ 4.6e-4 +411:addChannel = 1 0.06471 0 -211 211 211 ### D+ -> π- π+ π+ (non-resonant) 1.0e-4 + +### Ds+ decays +### Ds+ -> K- K+ π+ (50%) +431:oneChannel = 1 0.50000 0 333 211 ### Ds+ -> φ(1020) π+ 2.21% +431:addChannel = 1 0.15000 0 -313 321 ### Ds+ -> antiK*(892) K+ 2.58% +### Ds+ -> K- K+ π+ π0 (small, 2%) +431:addChannel = 1 0.02000 0 333 213 ### Ds+ -> φ(1020) rho 5.50% +### Ds+ -> π- π+ π+ (11.00%) +431:addChannel = 1 0.00220 0 113 211 ### Ds+ -> rho π+ 1.1e-4 +431:addChannel = 1 0.00220 0 225 211 ### Ds+ -> f2(1270) π+ 1.4e-3 +431:addChannel = 1 0.10560 0 -211 211 211 ### Ds+ -> π- π+ π+ 9.12e-3 (s-wave) +### Ds+ -> π- K+ π+ (11.00%) +431:addChannel = 1 0.03080 0 313 211 ### Ds+ -> K*(892)0 π+ 1.67e-3 +431:addChannel = 1 0.02200 0 10221 321 ### Ds+ -> f0(1370) K+ 1.2e-3 +431:addChannel = 1 0.03960 0 113 321 ### Ds+ -> rho0 K+ 2.17e-3 +431:addChannel = 1 0.01760 0 -211 321 211 ### Ds+ -> π- K+ π+ (non-resonant) 1.16-3 +### Ds+ -> π+ π- π+ π0 (11.00%) +431:addChannel = 1 0.11000 0 221 211 ### Ds+ -> eta π+ -> π0 π+ π+ π- (affects D+ golden channel) + +## Λc decays +### Λc+ -> p K- π+ (36%) +4122:oneChannel = 1 0.14400 0 2212 -321 211 ### Λc+ -> p K- π+ (non-resonant) 3.5% +4122:addChannel = 1 0.08100 100 2212 -313 ### Λc+ -> p K*0(892) 1.96% +4122:addChannel = 1 0.04500 100 2224 -321 ### Λc+ -> Delta++ K- 1.08% +4122:addChannel = 1 0.09000 100 102134 211 ### Λc+ -> Lambda(1520) K- 2.20e-3 +### Λc+ -> p K0S (36%) +4122:addChannel = 1 0.36000 0 2212 311 ### Λc+ -> p K0S 1.59% +### Λc+ -> p K- π+ π0 (small, 3%) +4122:addChannel = 1 0.03000 0 2212 -321 211 111 ### Λc+ -> p K- π+ π0 (non-resonant) 4.6% +### Λc+ -> p π- π+ (12.50%) +4122:addChannel = 1 0.12500 0 2212 -211 211 ### Λc+ -> p π+ π+ 4.59% +### Λc+ -> p K- K+ (12.50%) +4122:addChannel = 1 0.12500 0 2212 333 ### Λc+ -> p phi 1.06% + +## Xic decays +### Ξc+ -> p K- π+ (35%) +4232:oneChannel = 1 0.17500 0 2212 -321 211 ### Ξc+ -> p K- π+ 6.18e-3 +4232:addChannel = 1 0.17500 0 2212 -313 ### Ξc+ -> p antiK*0(892) +### Ξc+ -> Ξ- π+ π+ (35%) (set the same as Ξc+ -> p K- π+) +4232:addChannel = 1 0.35000 0 3312 211 211 ### Ξc+ -> Ξ- π+ π+ 2.86% +### Ξc+ -> p φ (10%) +4232:addChannel = 1 0.10000 0 2212 333 ### Ξc+ -> p φ +### Ξc+ -> sigma+ π+ π- (10%) +4232:addChannel = 1 0.12500 0 3222 -211 211 ### Ξc+ -> sigma+ π- π+ 1.37% +### Ξc+ -> Ξ*0 π+ (10%) +4232:addChannel = 1 0.12500 0 3324 211 + ### add Xic0 decays absent in PYTHIA8 decay table -4132:addChannel = 1 0.0143 0 3312 211 +4132:oneChannel = 1 0.0143 0 3312 211 + ### add OmegaC decays absent in PYTHIA8 decay table -4332:addChannel = 1 0.5 0 3334 211 +4332:oneChannel = 1 0.5 0 3334 211 4332:addChannel = 1 0.5 0 3312 211 -### K* -> K pi +# Allow the decay of resonances in the decay chain +### K*0(892) -> K- π+ 313:onMode = off 313:onIfAll = 321 211 -### for Ds -> Phi pi+ +### K*(892)+ -> K- π0 +323:onMode = off +323:onIfAll = 321 111 +### K*(1430)0 -> K- π+ +10311:onMode = off +10311:onIfAll = 321 211 +### rho+ -> π+ π0 +213:onMode = off +213:onIfAll = 211 111 +### φ -> K+ K- 333:onMode = off 333:onIfAll = 321 321 -### for D0 -> rho0 pi+ k- +### rho0 -> π+ π- 113:onMode = off 113:onIfAll = 211 211 -### for Lambda_c -> Delta++ K- +### f2(1270) -> π+ π- +225:onMode = off +225:onIfAll = 211 211 +### f0(1370) -> π+ π- +10221:onMode = off +10221:onIfAll = 211 211 +### eta -> π+ π- +221:onMode = off +221:onIfAll = 111 211 211 +### for Λc -> Delta++ K- 2224:onMode = off 2224:onIfAll = 2212 211 -### for Lambda_c -> Lambda(1520) K- +### for Λc -> Lambda(1520) K- 102134:onMode = off 102134:onIfAll = 2212 321 ### for Xic0 -> pi Xi -> pi pi Lambda -> pi pi pi p @@ -92,7 +175,7 @@ BeamRemnants:saturation 5 3334:onMode = off 3334:onIfAll = 3122 -321 -### switch off all decay channels +# switch off all decay channels 411:onMode = off 421:onMode = off 431:onMode = off @@ -102,41 +185,100 @@ BeamRemnants:saturation 5 443:onMode = off 4332:onMode = off -### D0 -> K pi +# Allow the decay of HF +### D0 -> K π 421:onIfMatch = 321 211 -### D0 -> K pi pi0 +### D0 -> K π π0 421:onIfMatch = 321 211 111 +### D0 -> rho K +421:onIfMatch = 213 321 +### D0 -> antiK*0 π0 +421:onIfMatch = 313 111 +### D0 -> K*- π+ +421:onIfMatch = 323 211 +### D0 -> π π +421:onIfMatch = 211 211 +### D0 -> rho+ π- +421:onIfMatch = 213 -211 +### D0 -> π π π0 +421:onIfMatch = 211 211 111 +### D0 -> K K +421:onIfMatch = 321 321 -### D+/- -> K pi pi +### D+/- -> K π π 411:onIfMatch = 321 211 211 -### D+/- -> K* pi +### D+/- -> K π π +411:onIfMatch = 321 211 211 111 +### D+/- -> K* π 411:onIfMatch = 313 211 -### D+/- -> phi pi +### D+/- -> K* K +411:onIfMatch = 313 321 +### D+/- -> antiK* π +411:onIfMatch = 10311 211 +### D+/- -> antiK* K +411:onIfMatch = 10311 321 +### D+/- -> φ π 411:onIfMatch = 333 211 +### D+/- -> K K π +411:onIfMatch = 321 321 211 +### D+/- -> f2(1270) π +411:onIfMatch = 225 211 +### D+/- -> rho π +411:onIfMatch = 113 211 +### D+/- -> π π π +411:onIfMatch = 211 211 211 -### D_s -> K K* -431:onIfMatch = 321 313 -### D_s -> Phi pi +### Ds -> φ π 431:onIfMatch = 333 211 +### Ds -> K* K +431:onIfMatch = 313 321 +### Ds -> φ rho+ +431:onIfMatch = 333 213 +### Ds -> rho π +431:onIfMatch = 113 211 +### Ds -> f2 π +431:onIfMatch = 225 211 +### Ds -> π π π +431:onIfMatch = 211 211 211 +### Ds -> K*(892)0 π+ +431:onIfMatch = 313 211 +### Ds -> f0(1370) K+ +431:onIfMatch = 10221 321 +### Ds -> rho0 K+ +431:onIfMatch = 113 321 +### Ds -> K π π +431:onIfMatch = 321 211 211 +### Ds -> eta π+ +431:onIfMatch = 221 211 -### Lambda_c -> p K* +### Λc -> pK0s +4122:onIfMatch = 2212 311 +### Λc -> p K- π+ π0 +4122:onIfMatch = 2212 321 211 +### Λc -> p K* 4122:onIfMatch = 2212 313 -### Lambda_c -> Delta K +### Λc -> Delta++ K 4122:onIfMatch = 2224 321 -### Lambda_c -> Lambda(1520) pi +### Λc -> Lambda(1520) π 4122:onIfMatch = 102134 211 -### Lambda_c -> p K pi -4122:onIfMatch = 2212 321 211 -### Lambda_c -> pK0s -4122:onIfMatch = 2212 311 +### Λc -> p K- π+ π0 +4122:onIfMatch = 2212 321 211 111 +### Λc -> p π π +4122:onIfMatch = 2212 211 211 +### Λc -> p K K +4122:onIfMatch = 2212 333 -### Xic+ -> pK*0 -4232:onIfMatch = 2212 313 -### Xic+ -> p K- pi+ +### Ξc+ -> p K- π+ 4232:onIfMatch = 2212 321 211 -### Xic+ -> Xi*0 pi+, Xi*->Xi- pi+ +### Ξc+ -> p antiK*0(892) +4232:onIfMatch = 2212 313 +### Ξc+ -> p φ +4232:onIfMatch = 2212 333 +### Ξc+ -> sigma- π+ π+ +4232:onIfMatch = 3222 211 211 +### Ξc+ -> Ξ*0 π+, Ξ*0 -> Ξ- π+ 4232:onIfMatch = 3324 211 -### Xic+ -> Xi- pi+ pi+ +### Ξc+ -> Ξ- π+ π+ 4232:onIfMatch = 3312 211 211 ### Xic0 -> Xi- pi+ diff --git a/MC/config/PWGHF/pythia8/generator/pythia8_charmhadronic_with_decays_QCDCR_OO.cfg b/MC/config/PWGHF/pythia8/generator/pythia8_charmhadronic_with_decays_QCDCR_OO.cfg new file mode 100644 index 000000000..255cdfbd4 --- /dev/null +++ b/MC/config/PWGHF/pythia8/generator/pythia8_charmhadronic_with_decays_QCDCR_OO.cfg @@ -0,0 +1,299 @@ +# Pythia8 configuration file for charm hadronic production in OO collisions at 5.36 TeV + +### beams +Beams:idA 1000080160 # Oxygen +Beams:idB 1000080160 # Oxygen +Beams:eCM 5360. # GeV + +### processes +SoftQCD:inelastic on # all inelastic processes + +### decays +Beams:frameType 1 +ParticleDecays:limitTau0 on +ParticleDecays:tau0Max 10. + +### Save some CPU at init of jobs +### To avoid refitting, add the following lines to your configuration file: +HeavyIon:SigFitNGen 0 +HeavyIon:SigFitDefPar 2.15,18.42,0.33 + +Random:setSeed on + +### switching on QCD colour reconnection mode +StringPT:sigma = 0.335 +StringZ:aLund = 0.36 +StringZ:bLund = 0.56 +StringFlav:probQQtoQ = 0.078 +StringFlav:ProbStoUD = 0.2 +StringFlav:probQQ1toQQ0join = 0.0275,0.0275,0.0275,0.0275 +BeamRemnants:remnantMode = 1 +BeamRemnants:saturation = 5 +ColourReconnection:mode = 1 +ColourReconnection:allowDoubleJunRem = off +ColourReconnection:allowJunctions = on +ColourReconnection:timeDilationMode = 0 +ColourReconnection:reconnect = on +ColourReconnection:forceHadronLevelCR = off +MultiPartonInteractions:pT0Ref = 2.12 +ColourReconnection:m0 = 2.9 +ColourReconnection:junctionCorrection = 1.43 +HIMultipartonInteractions:pT0Ref = 2.12 +BeamRemnants:beamJunction = off +HIBeamRemnants:beamJunction = off + +# Correct decay lengths (wrong in PYTHIA8 decay table) +# Lb +5122:tau0 = 0.4390 +# Xic0 +4132:tau0 = 0.0455 +# OmegaC +4332:tau0 = 0.0803 + +### Force golden charm hadrons decay modes for D2H studies +# HF decays +### BR are set to yield 50% of signal in golden channel and uniform abundance of corr. bkg channels (weighted by BR from PDG) +### +### D0 decays +### D0 -> K- π+ (50%) +421:oneChannel = 1 0.50000 0 -321 211 ### D0 -> K- π+ 3.94% +### D0 -> K- π+ π0 (12.50%) +421:addChannel = 1 0.00625 0 -321 211 111 ### D0 -> K- π+ π0 (non-resonant) 1.15% (e.g. 115/(115+231+195+1120)*0.2) +421:addChannel = 1 0.08750 0 213 -321 ### D0 -> rho+ K- 11.2% +421:addChannel = 1 0.01250 0 -313 111 ### D0 -> antiK*0(892) π0 1.95% +421:addChannel = 1 0.01875 0 -323 211 ### D0 -> K*-(892) π+ 2.31% +### D0 -> π- π+ (12.50%) +421:addChannel = 1 0.12500 0 -211 211 ### D0 -> π- π+ (non-resonant) 1.0e-4 +### D0 -> π- π+ π0 (12.50%) +421:addChannel = 1 0.08750 0 213 -211 ### D0 -> rho+ π- 1.01% +421:addChannel = 1 0.03750 0 -211 211 111 ### D0 -> π- π+ π0 (non-resonant) 1.3e-4 +### D0 -> K- K+ (12.50%) +421:addChannel = 1 0.12500 0 -321 321 ### D0 -> K- K+ (non-resonant) 4.08e-3 + +### D+ decays +### D+ -> K- π+ π+ (50%) +411:oneChannel = 1 0.40189 0 -321 211 211 ### D+ -> K- π+ π+ 9.38% +411:addChannel = 1 0.05356 0 -10311 211 ### D+ -> antiK*0(1430) π+ 1.25% +411:addChannel = 1 0.04455 0 -313 211 ### D+ -> K*0(892) pi+ 1.04% +### D+ -> K- π+ π+ π0 (small, 3%) +411:addChannel = 1 0.03000 0 -321 211 211 111 ### D+ -> K- π+ π+ π0 6.25% +### D+ -> K- K+ π+ (36.00%, set 25% for D+ -> φ π+, 11% for the rest) +411:addChannel = 1 0.25000 0 333 211 ### D+ -> φ π+ 2.69e-3 !needed for signal +411:addChannel = 1 0.03929 0 -313 321 ### D+ -> K*0(892) K+ 2.49e-3 +411:addChannel = 1 0.02865 0 -10311 321 ### D+ -> antiK*0(1430) K+ 1.82e-3 +411:addChannel = 1 0.04206 0 -321 321 211 ### D+ -> K- K+ π+ (non-resonant) 2.68e-3 +### D+ -> π- π+ π+ (11.00%) +411:addChannel = 1 0.02911 0 113 211 ### D+ -> rho0 π+ 8.4e-4 +411:addChannel = 1 0.01618 0 225 211 ### D+ -> f2(1270) π+ 4.6e-4 +411:addChannel = 1 0.06471 0 -211 211 211 ### D+ -> π- π+ π+ (non-resonant) 1.0e-4 + +### Ds+ decays +### Ds+ -> K- K+ π+ (50%) +431:oneChannel = 1 0.50000 0 333 211 ### Ds+ -> φ(1020) π+ 2.21% +431:addChannel = 1 0.15000 0 -313 321 ### Ds+ -> antiK*(892) K+ 2.58% +### Ds+ -> K- K+ π+ π0 (small, 2%) +431:addChannel = 1 0.02000 0 333 213 ### Ds+ -> φ(1020) rho 5.50% +### Ds+ -> π- π+ π+ (11.00%) +431:addChannel = 1 0.00220 0 113 211 ### Ds+ -> rho π+ 1.1e-4 +431:addChannel = 1 0.00220 0 225 211 ### Ds+ -> f2(1270) π+ 1.4e-3 +431:addChannel = 1 0.10560 0 -211 211 211 ### Ds+ -> π- π+ π+ 9.12e-3 (s-wave) +### Ds+ -> π- K+ π+ (11.00%) +431:addChannel = 1 0.03080 0 313 211 ### Ds+ -> K*(892)0 π+ 1.67e-3 +431:addChannel = 1 0.02200 0 10221 321 ### Ds+ -> f0(1370) K+ 1.2e-3 +431:addChannel = 1 0.03960 0 113 321 ### Ds+ -> rho0 K+ 2.17e-3 +431:addChannel = 1 0.01760 0 -211 321 211 ### Ds+ -> π- K+ π+ (non-resonant) 1.16-3 +### Ds+ -> π+ π- π+ π0 (11.00%) +431:addChannel = 1 0.11000 0 221 211 ### Ds+ -> eta π+ -> π0 π+ π+ π- (affects D+ golden channel) + +## Λc decays +### Λc+ -> p K- π+ (36%) +4122:oneChannel = 1 0.14400 0 2212 -321 211 ### Λc+ -> p K- π+ (non-resonant) 3.5% +4122:addChannel = 1 0.08100 100 2212 -313 ### Λc+ -> p K*0(892) 1.96% +4122:addChannel = 1 0.04500 100 2224 -321 ### Λc+ -> Delta++ K- 1.08% +4122:addChannel = 1 0.09000 100 102134 211 ### Λc+ -> Lambda(1520) K- 2.20e-3 +### Λc+ -> p K0S (36%) +4122:addChannel = 1 0.36000 0 2212 311 ### Λc+ -> p K0S 1.59% +### Λc+ -> p K- π+ π0 (small, 3%) +4122:addChannel = 1 0.03000 0 2212 -321 211 111 ### Λc+ -> p K- π+ π0 (non-resonant) 4.6% +### Λc+ -> p π- π+ (12.50%) +4122:addChannel = 1 0.12500 0 2212 -211 211 ### Λc+ -> p π+ π+ 4.59% +### Λc+ -> p K- K+ (12.50%) +4122:addChannel = 1 0.12500 0 2212 333 ### Λc+ -> p phi 1.06% + +## Xic decays +### Ξc+ -> p K- π+ (35%) +4232:oneChannel = 1 0.17500 0 2212 -321 211 ### Ξc+ -> p K- π+ 6.18e-3 +4232:addChannel = 1 0.17500 0 2212 -313 ### Ξc+ -> p antiK*0(892) +### Ξc+ -> Ξ- π+ π+ (35%) (set the same as Ξc+ -> p K- π+) +4232:addChannel = 1 0.35000 0 3312 211 211 ### Ξc+ -> Ξ- π+ π+ 2.86% +### Ξc+ -> p φ (10%) +4232:addChannel = 1 0.10000 0 2212 333 ### Ξc+ -> p φ +### Ξc+ -> sigma+ π+ π- (10%) +4232:addChannel = 1 0.12500 0 3222 -211 211 ### Ξc+ -> sigma+ π- π+ 1.37% +### Ξc+ -> Ξ*0 π+ (10%) +4232:addChannel = 1 0.12500 0 3324 211 + +### add Xic0 decays absent in PYTHIA8 decay table +4132:oneChannel = 1 0.0143 0 3312 211 + +### add OmegaC decays absent in PYTHIA8 decay table +4332:oneChannel = 1 0.5 0 3334 211 +4332:addChannel = 1 0.5 0 3312 211 + +# Allow the decay of resonances in the decay chain +### K*0(892) -> K- π+ +313:onMode = off +313:onIfAll = 321 211 +### K*(892)+ -> K- π0 +323:onMode = off +323:onIfAll = 321 111 +### K*(1430)0 -> K- π+ +10311:onMode = off +10311:onIfAll = 321 211 +### rho+ -> π+ π0 +213:onMode = off +213:onIfAll = 211 111 +### φ -> K+ K- +333:onMode = off +333:onIfAll = 321 321 +### rho0 -> π+ π- +113:onMode = off +113:onIfAll = 211 211 +### f2(1270) -> π+ π- +225:onMode = off +225:onIfAll = 211 211 +### f0(1370) -> π+ π- +10221:onMode = off +10221:onIfAll = 211 211 +### eta -> π+ π- +221:onMode = off +221:onIfAll = 111 211 211 +### for Λc -> Delta++ K- +2224:onMode = off +2224:onIfAll = 2212 211 +### for Λc -> Lambda(1520) K- +102134:onMode = off +102134:onIfAll = 2212 321 +### for Xic0 -> pi Xi -> pi pi Lambda -> pi pi pi p +### and Omega_c -> pi Xi -> pi pi Lambda -> pi pi pi p +3312:onMode = off +3312:onIfAll = 3122 -211 +3122:onMode = off +3122:onIfAll = 2212 -211 +### for Omega_c -> pi Omega -> pi K Lambda -> pi K pi p +3334:onMode = off +3334:onIfAll = 3122 -321 + +# switch off all decay channels +411:onMode = off +421:onMode = off +431:onMode = off +4122:onMode = off +4232:onMode = off +4132:onMode = off +443:onMode = off +4332:onMode = off + +# Allow the decay of HF +### D0 -> K π +421:onIfMatch = 321 211 +### D0 -> K π π0 +421:onIfMatch = 321 211 111 +### D0 -> rho K +421:onIfMatch = 213 321 +### D0 -> antiK*0 π0 +421:onIfMatch = 313 111 +### D0 -> K*- π+ +421:onIfMatch = 323 211 +### D0 -> π π +421:onIfMatch = 211 211 +### D0 -> rho+ π- +421:onIfMatch = 213 -211 +### D0 -> π π π0 +421:onIfMatch = 211 211 111 +### D0 -> K K +421:onIfMatch = 321 321 + +### D+/- -> K π π +411:onIfMatch = 321 211 211 +### D+/- -> K π π +411:onIfMatch = 321 211 211 111 +### D+/- -> K* π +411:onIfMatch = 313 211 +### D+/- -> K* K +411:onIfMatch = 313 321 +### D+/- -> antiK* π +411:onIfMatch = 10311 211 +### D+/- -> antiK* K +411:onIfMatch = 10311 321 +### D+/- -> φ π +411:onIfMatch = 333 211 +### D+/- -> K K π +411:onIfMatch = 321 321 211 +### D+/- -> f2(1270) π +411:onIfMatch = 225 211 +### D+/- -> rho π +411:onIfMatch = 113 211 +### D+/- -> π π π +411:onIfMatch = 211 211 211 + +### Ds -> φ π +431:onIfMatch = 333 211 +### Ds -> K* K +431:onIfMatch = 313 321 +### Ds -> φ rho+ +431:onIfMatch = 333 213 +### Ds -> rho π +431:onIfMatch = 113 211 +### Ds -> f2 π +431:onIfMatch = 225 211 +### Ds -> π π π +431:onIfMatch = 211 211 211 +### Ds -> K*(892)0 π+ +431:onIfMatch = 313 211 +### Ds -> f0(1370) K+ +431:onIfMatch = 10221 321 +### Ds -> rho0 K+ +431:onIfMatch = 113 321 +### Ds -> K π π +431:onIfMatch = 321 211 211 +### Ds -> eta π+ +431:onIfMatch = 221 211 + +### Λc -> pK0s +4122:onIfMatch = 2212 311 +### Λc -> p K- π+ π0 +4122:onIfMatch = 2212 321 211 +### Λc -> p K* +4122:onIfMatch = 2212 313 +### Λc -> Delta++ K +4122:onIfMatch = 2224 321 +### Λc -> Lambda(1520) π +4122:onIfMatch = 102134 211 +### Λc -> p K- π+ π0 +4122:onIfMatch = 2212 321 211 111 +### Λc -> p π π +4122:onIfMatch = 2212 211 211 +### Λc -> p K K +4122:onIfMatch = 2212 333 + +### Ξc+ -> p K- π+ +4232:onIfMatch = 2212 321 211 +### Ξc+ -> p antiK*0(892) +4232:onIfMatch = 2212 313 +### Ξc+ -> p φ +4232:onIfMatch = 2212 333 +### Ξc+ -> sigma- π+ π+ +4232:onIfMatch = 3222 211 211 +### Ξc+ -> Ξ*0 π+, Ξ*0 -> Ξ- π+ +4232:onIfMatch = 3324 211 +### Ξc+ -> Ξ- π+ π+ +4232:onIfMatch = 3312 211 211 + +### Xic0 -> Xi- pi+ +4132:onIfMatch = 3312 211 + +### Omega_c -> Omega pi +4332:onIfMatch = 3334 211 +### Omega_c -> Xi pi +4332:onIfMatch = 3312 211 \ No newline at end of file diff --git a/MC/config/PWGHF/pythia8/generator/pythia8_charmhadronic_with_decays_QCDCR_pO.cfg b/MC/config/PWGHF/pythia8/generator/pythia8_charmhadronic_with_decays_QCDCR_pO.cfg new file mode 100644 index 000000000..89c1c5d9e --- /dev/null +++ b/MC/config/PWGHF/pythia8/generator/pythia8_charmhadronic_with_decays_QCDCR_pO.cfg @@ -0,0 +1,300 @@ +# Pythia8 configuration file for charm hadronic production in pO collisions at 9.62 TeV + +### beams +Beams:frameType 2 # back-to-back beams of different energies and particles +Beams:idA 2212 # proton +Beams:idB 1000080160 # Oxygen +Beams:eA 6800. # Energy of proton beam in GeV moving in the +z direction +Beams:eB 3400. # Energy in GeV per Oxygen nucleon (6.8 Z TeV) moving in the -z direction + +### processes +SoftQCD:inelastic on # all inelastic processes + +### decays +ParticleDecays:limitTau0 on +ParticleDecays:tau0Max 10. + +### Save some CPU at init of jobs +### To avoid refitting, add the following lines to your configuration file: +HeavyIon:SigFitNGen 0 +HeavyIon:SigFitDefPar 2.15,18.42,0.33 + +Random:setSeed on + +### switching on QCD colour reconnection mode +StringPT:sigma = 0.335 +StringZ:aLund = 0.36 +StringZ:bLund = 0.56 +StringFlav:probQQtoQ = 0.078 +StringFlav:ProbStoUD = 0.2 +StringFlav:probQQ1toQQ0join = 0.0275,0.0275,0.0275,0.0275 +BeamRemnants:remnantMode = 1 +BeamRemnants:saturation = 5 +ColourReconnection:mode = 1 +ColourReconnection:allowDoubleJunRem = off +ColourReconnection:allowJunctions = on +ColourReconnection:timeDilationMode = 0 +ColourReconnection:reconnect = on +ColourReconnection:forceHadronLevelCR = off +MultiPartonInteractions:pT0Ref = 2.12 +ColourReconnection:m0 = 2.9 +ColourReconnection:junctionCorrection = 1.43 +HIMultipartonInteractions:pT0Ref = 2.12 +BeamRemnants:beamJunction = off +HIBeamRemnants:beamJunction = off + +# Correct decay lengths (wrong in PYTHIA8 decay table) +# Lb +5122:tau0 = 0.4390 +# Xic0 +4132:tau0 = 0.0455 +# OmegaC +4332:tau0 = 0.0803 + +### Force golden charm hadrons decay modes for D2H studies +# HF decays +### BR are set to yield 50% of signal in golden channel and uniform abundance of corr. bkg channels (weighted by BR from PDG) +### +### D0 decays +### D0 -> K- π+ (50%) +421:oneChannel = 1 0.50000 0 -321 211 ### D0 -> K- π+ 3.94% +### D0 -> K- π+ π0 (12.50%) +421:addChannel = 1 0.00625 0 -321 211 111 ### D0 -> K- π+ π0 (non-resonant) 1.15% (e.g. 115/(115+231+195+1120)*0.2) +421:addChannel = 1 0.08750 0 213 -321 ### D0 -> rho+ K- 11.2% +421:addChannel = 1 0.01250 0 -313 111 ### D0 -> antiK*0(892) π0 1.95% +421:addChannel = 1 0.01875 0 -323 211 ### D0 -> K*-(892) π+ 2.31% +### D0 -> π- π+ (12.50%) +421:addChannel = 1 0.12500 0 -211 211 ### D0 -> π- π+ (non-resonant) 1.0e-4 +### D0 -> π- π+ π0 (12.50%) +421:addChannel = 1 0.08750 0 213 -211 ### D0 -> rho+ π- 1.01% +421:addChannel = 1 0.03750 0 -211 211 111 ### D0 -> π- π+ π0 (non-resonant) 1.3e-4 +### D0 -> K- K+ (12.50%) +421:addChannel = 1 0.12500 0 -321 321 ### D0 -> K- K+ (non-resonant) 4.08e-3 + +### D+ decays +### D+ -> K- π+ π+ (50%) +411:oneChannel = 1 0.40189 0 -321 211 211 ### D+ -> K- π+ π+ 9.38% +411:addChannel = 1 0.05356 0 -10311 211 ### D+ -> antiK*0(1430) π+ 1.25% +411:addChannel = 1 0.04455 0 -313 211 ### D+ -> K*0(892) pi+ 1.04% +### D+ -> K- π+ π+ π0 (small, 3%) +411:addChannel = 1 0.03000 0 -321 211 211 111 ### D+ -> K- π+ π+ π0 6.25% +### D+ -> K- K+ π+ (36.00%, set 25% for D+ -> φ π+, 11% for the rest) +411:addChannel = 1 0.25000 0 333 211 ### D+ -> φ π+ 2.69e-3 !needed for signal +411:addChannel = 1 0.03929 0 -313 321 ### D+ -> K*0(892) K+ 2.49e-3 +411:addChannel = 1 0.02865 0 -10311 321 ### D+ -> antiK*0(1430) K+ 1.82e-3 +411:addChannel = 1 0.04206 0 -321 321 211 ### D+ -> K- K+ π+ (non-resonant) 2.68e-3 +### D+ -> π- π+ π+ (11.00%) +411:addChannel = 1 0.02911 0 113 211 ### D+ -> rho0 π+ 8.4e-4 +411:addChannel = 1 0.01618 0 225 211 ### D+ -> f2(1270) π+ 4.6e-4 +411:addChannel = 1 0.06471 0 -211 211 211 ### D+ -> π- π+ π+ (non-resonant) 1.0e-4 + +### Ds+ decays +### Ds+ -> K- K+ π+ (50%) +431:oneChannel = 1 0.50000 0 333 211 ### Ds+ -> φ(1020) π+ 2.21% +431:addChannel = 1 0.15000 0 -313 321 ### Ds+ -> antiK*(892) K+ 2.58% +### Ds+ -> K- K+ π+ π0 (small, 2%) +431:addChannel = 1 0.02000 0 333 213 ### Ds+ -> φ(1020) rho 5.50% +### Ds+ -> π- π+ π+ (11.00%) +431:addChannel = 1 0.00220 0 113 211 ### Ds+ -> rho π+ 1.1e-4 +431:addChannel = 1 0.00220 0 225 211 ### Ds+ -> f2(1270) π+ 1.4e-3 +431:addChannel = 1 0.10560 0 -211 211 211 ### Ds+ -> π- π+ π+ 9.12e-3 (s-wave) +### Ds+ -> π- K+ π+ (11.00%) +431:addChannel = 1 0.03080 0 313 211 ### Ds+ -> K*(892)0 π+ 1.67e-3 +431:addChannel = 1 0.02200 0 10221 321 ### Ds+ -> f0(1370) K+ 1.2e-3 +431:addChannel = 1 0.03960 0 113 321 ### Ds+ -> rho0 K+ 2.17e-3 +431:addChannel = 1 0.01760 0 -211 321 211 ### Ds+ -> π- K+ π+ (non-resonant) 1.16-3 +### Ds+ -> π+ π- π+ π0 (11.00%) +431:addChannel = 1 0.11000 0 221 211 ### Ds+ -> eta π+ -> π0 π+ π+ π- (affects D+ golden channel) + +## Λc decays +### Λc+ -> p K- π+ (36%) +4122:oneChannel = 1 0.14400 0 2212 -321 211 ### Λc+ -> p K- π+ (non-resonant) 3.5% +4122:addChannel = 1 0.08100 100 2212 -313 ### Λc+ -> p K*0(892) 1.96% +4122:addChannel = 1 0.04500 100 2224 -321 ### Λc+ -> Delta++ K- 1.08% +4122:addChannel = 1 0.09000 100 102134 211 ### Λc+ -> Lambda(1520) K- 2.20e-3 +### Λc+ -> p K0S (36%) +4122:addChannel = 1 0.36000 0 2212 311 ### Λc+ -> p K0S 1.59% +### Λc+ -> p K- π+ π0 (small, 3%) +4122:addChannel = 1 0.03000 0 2212 -321 211 111 ### Λc+ -> p K- π+ π0 (non-resonant) 4.6% +### Λc+ -> p π- π+ (12.50%) +4122:addChannel = 1 0.12500 0 2212 -211 211 ### Λc+ -> p π+ π+ 4.59% +### Λc+ -> p K- K+ (12.50%) +4122:addChannel = 1 0.12500 0 2212 333 ### Λc+ -> p phi 1.06% + +## Xic decays +### Ξc+ -> p K- π+ (35%) +4232:oneChannel = 1 0.17500 0 2212 -321 211 ### Ξc+ -> p K- π+ 6.18e-3 +4232:addChannel = 1 0.17500 0 2212 -313 ### Ξc+ -> p antiK*0(892) +### Ξc+ -> Ξ- π+ π+ (35%) (set the same as Ξc+ -> p K- π+) +4232:addChannel = 1 0.35000 0 3312 211 211 ### Ξc+ -> Ξ- π+ π+ 2.86% +### Ξc+ -> p φ (10%) +4232:addChannel = 1 0.10000 0 2212 333 ### Ξc+ -> p φ +### Ξc+ -> sigma+ π+ π- (10%) +4232:addChannel = 1 0.12500 0 3222 -211 211 ### Ξc+ -> sigma+ π- π+ 1.37% +### Ξc+ -> Ξ*0 π+ (10%) +4232:addChannel = 1 0.12500 0 3324 211 + +### add Xic0 decays absent in PYTHIA8 decay table +4132:oneChannel = 1 0.0143 0 3312 211 + +### add OmegaC decays absent in PYTHIA8 decay table +4332:oneChannel = 1 0.5 0 3334 211 +4332:addChannel = 1 0.5 0 3312 211 + +# Allow the decay of resonances in the decay chain +### K*0(892) -> K- π+ +313:onMode = off +313:onIfAll = 321 211 +### K*(892)+ -> K- π0 +323:onMode = off +323:onIfAll = 321 111 +### K*(1430)0 -> K- π+ +10311:onMode = off +10311:onIfAll = 321 211 +### rho+ -> π+ π0 +213:onMode = off +213:onIfAll = 211 111 +### φ -> K+ K- +333:onMode = off +333:onIfAll = 321 321 +### rho0 -> π+ π- +113:onMode = off +113:onIfAll = 211 211 +### f2(1270) -> π+ π- +225:onMode = off +225:onIfAll = 211 211 +### f0(1370) -> π+ π- +10221:onMode = off +10221:onIfAll = 211 211 +### eta -> π+ π- +221:onMode = off +221:onIfAll = 111 211 211 +### for Λc -> Delta++ K- +2224:onMode = off +2224:onIfAll = 2212 211 +### for Λc -> Lambda(1520) K- +102134:onMode = off +102134:onIfAll = 2212 321 +### for Xic0 -> pi Xi -> pi pi Lambda -> pi pi pi p +### and Omega_c -> pi Xi -> pi pi Lambda -> pi pi pi p +3312:onMode = off +3312:onIfAll = 3122 -211 +3122:onMode = off +3122:onIfAll = 2212 -211 +### for Omega_c -> pi Omega -> pi K Lambda -> pi K pi p +3334:onMode = off +3334:onIfAll = 3122 -321 + +# switch off all decay channels +411:onMode = off +421:onMode = off +431:onMode = off +4122:onMode = off +4232:onMode = off +4132:onMode = off +443:onMode = off +4332:onMode = off + +# Allow the decay of HF +### D0 -> K π +421:onIfMatch = 321 211 +### D0 -> K π π0 +421:onIfMatch = 321 211 111 +### D0 -> rho K +421:onIfMatch = 213 321 +### D0 -> antiK*0 π0 +421:onIfMatch = 313 111 +### D0 -> K*- π+ +421:onIfMatch = 323 211 +### D0 -> π π +421:onIfMatch = 211 211 +### D0 -> rho+ π- +421:onIfMatch = 213 -211 +### D0 -> π π π0 +421:onIfMatch = 211 211 111 +### D0 -> K K +421:onIfMatch = 321 321 + +### D+/- -> K π π +411:onIfMatch = 321 211 211 +### D+/- -> K π π +411:onIfMatch = 321 211 211 111 +### D+/- -> K* π +411:onIfMatch = 313 211 +### D+/- -> K* K +411:onIfMatch = 313 321 +### D+/- -> antiK* π +411:onIfMatch = 10311 211 +### D+/- -> antiK* K +411:onIfMatch = 10311 321 +### D+/- -> φ π +411:onIfMatch = 333 211 +### D+/- -> K K π +411:onIfMatch = 321 321 211 +### D+/- -> f2(1270) π +411:onIfMatch = 225 211 +### D+/- -> rho π +411:onIfMatch = 113 211 +### D+/- -> π π π +411:onIfMatch = 211 211 211 + +### Ds -> φ π +431:onIfMatch = 333 211 +### Ds -> K* K +431:onIfMatch = 313 321 +### Ds -> φ rho+ +431:onIfMatch = 333 213 +### Ds -> rho π +431:onIfMatch = 113 211 +### Ds -> f2 π +431:onIfMatch = 225 211 +### Ds -> π π π +431:onIfMatch = 211 211 211 +### Ds -> K*(892)0 π+ +431:onIfMatch = 313 211 +### Ds -> f0(1370) K+ +431:onIfMatch = 10221 321 +### Ds -> rho0 K+ +431:onIfMatch = 113 321 +### Ds -> K π π +431:onIfMatch = 321 211 211 +### Ds -> eta π+ +431:onIfMatch = 221 211 + +### Λc -> pK0s +4122:onIfMatch = 2212 311 +### Λc -> p K- π+ π0 +4122:onIfMatch = 2212 321 211 +### Λc -> p K* +4122:onIfMatch = 2212 313 +### Λc -> Delta++ K +4122:onIfMatch = 2224 321 +### Λc -> Lambda(1520) π +4122:onIfMatch = 102134 211 +### Λc -> p K- π+ π0 +4122:onIfMatch = 2212 321 211 111 +### Λc -> p π π +4122:onIfMatch = 2212 211 211 +### Λc -> p K K +4122:onIfMatch = 2212 333 + +### Ξc+ -> p K- π+ +4232:onIfMatch = 2212 321 211 +### Ξc+ -> p antiK*0(892) +4232:onIfMatch = 2212 313 +### Ξc+ -> p φ +4232:onIfMatch = 2212 333 +### Ξc+ -> sigma- π+ π+ +4232:onIfMatch = 3222 211 211 +### Ξc+ -> Ξ*0 π+, Ξ*0 -> Ξ- π+ +4232:onIfMatch = 3324 211 +### Ξc+ -> Ξ- π+ π+ +4232:onIfMatch = 3312 211 211 + +### Xic0 -> Xi- pi+ +4132:onIfMatch = 3312 211 + +### Omega_c -> Omega pi +4332:onIfMatch = 3334 211 +### Omega_c -> Xi pi +4332:onIfMatch = 3312 211 \ No newline at end of file diff --git a/MC/config/PWGHF/pythia8/generator/pythia8_inel_Mode2.cfg b/MC/config/PWGHF/pythia8/generator/pythia8_inel_Mode2.cfg new file mode 100644 index 000000000..b022e3612 --- /dev/null +++ b/MC/config/PWGHF/pythia8/generator/pythia8_inel_Mode2.cfg @@ -0,0 +1,38 @@ +### beams +Beams:idA 2212 # proton +Beams:idB 2212 # proton +Beams:eCM 13600. # GeV + +### processes +SoftQCD:inelastic on # all inelastic processes + +### decays +ParticleDecays:limitTau0 on +ParticleDecays:tau0Max 10. + +### switching on Pythia Mode2 +ColourReconnection:mode 1 +ColourReconnection:allowDoubleJunRem off +ColourReconnection:m0 0.3 +ColourReconnection:allowJunctions on +ColourReconnection:junctionCorrection 1.20 +ColourReconnection:timeDilationMode 2 +ColourReconnection:timeDilationPar 0.18 +StringPT:sigma 0.335 +StringZ:aLund 0.36 +StringZ:bLund 0.56 +StringFlav:probQQtoQ 0.078 +StringFlav:ProbStoUD 0.2 +StringFlav:probQQ1toQQ0join 0.0275,0.0275,0.0275,0.0275 +MultiPartonInteractions:pT0Ref 2.15 +BeamRemnants:remnantMode 1 +BeamRemnants:saturation 5 + +# Correct decay lengths (wrong in PYTHIA8 decay table) +# Lb +5122:tau0 = 0.4390 +# Xic0 +4132:tau0 = 0.0455 +# OmegaC +4332:tau0 = 0.0803 + diff --git a/MC/config/PWGHF/pythia8/generator/pythia8_lambdab_probQQtoQ.cfg b/MC/config/PWGHF/pythia8/generator/pythia8_lambdab_probQQtoQ.cfg new file mode 100644 index 000000000..f59bc78da --- /dev/null +++ b/MC/config/PWGHF/pythia8/generator/pythia8_lambdab_probQQtoQ.cfg @@ -0,0 +1,71 @@ +### beams +Beams:idA 2212 # proton +Beams:idB 2212 # proton +Beams:eCM 13600. # GeV + +### processes +SoftQCD:inelastic on # all inelastic processes + +### decays +ParticleDecays:limitTau0 on +ParticleDecays:tau0Max 10. + +### switching on Pythia Mode2 +ColourReconnection:mode 1 +ColourReconnection:allowDoubleJunRem off +ColourReconnection:m0 0.3 +ColourReconnection:allowJunctions on +ColourReconnection:junctionCorrection 1.20 +ColourReconnection:timeDilationMode 2 +ColourReconnection:timeDilationPar 0.18 +StringPT:sigma 0.335 +StringZ:aLund 0.36 +StringZ:bLund 0.56 +StringFlav:probQQtoQ 0.078 +StringFlav:ProbStoUD 0.2 +StringFlav:probQQ1toQQ0join 0.0275,0.0275,0.0275,0.0275 +MultiPartonInteractions:pT0Ref 2.15 +BeamRemnants:remnantMode 1 +BeamRemnants:saturation 5 +BeamRemnants:allowBeamJunction = off +BeamRemnants:beamJunction = off +ColourReconnection:allowDiquarkJunctionCR = off + +# Correct decay lengths (wrong in PYTHIA8 decay table) +# Lb +5122:tau0 = 0.4390 +# Xic0 +4132:tau0 = 0.0455 +# OmegaC +4332:tau0 = 0.0803 + +## Lb decay modes +5122:onMode = off +5122:oneChannel = 1 9.03e-05 0 2212 2212 -2212 -2212 2112 +5122:addChannel = 1 0.00181 0 2212 2212 -2212 -2212 2112 111 +5122:addChannel = 1 0.0181 0 2212 2212 -2212 -2212 2112 111 111 +5122:addChannel = 1 0.0271 0 2212 2212 -2212 -2212 2112 211 -211 +5122:addChannel = 1 0.0181 0 2212 2212 -2212 -2212 2112 211 211 -211 -211 +5122:addChannel = 1 0.181 0 2212 2212 -2212 -2212 2112 211 -211 111 +5122:addChannel = 1 0.199 0 2212 2212 -2212 -2212 2112 211 -211 111 111 +5122:addChannel = 1 0.0271 0 2212 2212 -2212 -2212 2112 211 211 -211 -211 111 +5122:addChannel = 1 0.00452 0 2212 2212 -2212 -2212 2112 211 111 +5122:addChannel = 1 0.0361 0 2212 2212 2112 -2212 -2112 -211 111 +5122:addChannel = 1 0.0452 0 2212 2212 2112 -2212 -2112 -211 111 111 +5122:addChannel = 1 0.0542 0 2212 2212 2112 -2212 -2112 -211 -211 211 +5122:addChannel = 1 0.361 0 2212 2212 2112 -2212 -2112 -211 -211 211 111 +5122:addChannel = 1 0.0271 0 2212 2212 2112 -2212 -2112 -211 -211 211 111 111 +5122:onIfMatch = 2212 2212 2212 2212 2112 +5122:onIfMatch = 2212 2212 2212 2212 2112 111 +5122:onIfMatch = 2212 2212 2212 2212 2112 111 111 +5122:onIfMatch = 2212 2212 2212 2212 2112 211 211 +5122:onIfMatch = 2212 2212 2212 2212 2112 211 211 211 211 +5122:onIfMatch = 2212 2212 2212 2212 2112 211 211 111 +5122:onIfMatch = 2212 2212 2212 2212 2112 211 211 111 111 +5122:onIfMatch = 2212 2212 2212 2212 2112 211 211 211 211 111 +5122:onIfMatch = 2212 2212 2212 2212 2112 211 111 +5122:onIfMatch = 2212 2212 2112 2212 2112 211 111 +5122:onIfMatch = 2212 2212 2112 2212 2112 211 111 111 +5122:onIfMatch = 2212 2212 2112 2212 2112 211 211 211 +5122:onIfMatch = 2212 2212 2112 2212 2112 211 211 211 111 +5122:onIfMatch = 2212 2212 2112 2212 2112 211 211 211 111 111 diff --git a/MC/config/PWGHF/pythia8/generator/pythia8_lambdab_with_decays_Mode2.cfg b/MC/config/PWGHF/pythia8/generator/pythia8_lambdab_with_decays_Mode2.cfg new file mode 100644 index 000000000..8243c2fbe --- /dev/null +++ b/MC/config/PWGHF/pythia8/generator/pythia8_lambdab_with_decays_Mode2.cfg @@ -0,0 +1,73 @@ +### authors: Fabrizio Grosa (fabrizio.grosa@cern.ch) +### Cristina Terrevoli (cristina.terrevoli@cern.ch) +### Fabio Catalano (fabio.catalano@cern.ch) +### last update: November 2023 + +### beams +Beams:idA 2212 # proton +Beams:idB 2212 # proton +Beams:eCM 13600. # GeV + +### processes +SoftQCD:inelastic on # all inelastic processes + +### decays +ParticleDecays:limitTau0 on +ParticleDecays:tau0Max 10. + +### switching on Pythia Mode2 +ColourReconnection:mode 1 +ColourReconnection:allowDoubleJunRem off +ColourReconnection:m0 0.3 +ColourReconnection:allowJunctions on +ColourReconnection:junctionCorrection 1.20 +ColourReconnection:timeDilationMode 2 +ColourReconnection:timeDilationPar 0.18 +StringPT:sigma 0.335 +StringZ:aLund 0.36 +StringZ:bLund 0.56 +StringFlav:probQQtoQ 0.078 +StringFlav:ProbStoUD 0.2 +StringFlav:probQQ1toQQ0join 0.0275,0.0275,0.0275,0.0275 +MultiPartonInteractions:pT0Ref 2.15 +BeamRemnants:remnantMode 1 +BeamRemnants:saturation 5 + +# Correct decay lengths (wrong in PYTHIA8 decay table) +# Lb +5122:tau0 = 0.4390 +# Xic0 +4132:tau0 = 0.0455 +# OmegaC +4332:tau0 = 0.0803 + +## Lb decay modes +5122:onMode = off +5122:oneChannel = 1 9.03e-05 0 2212 2212 -2212 -2212 2112 +5122:addChannel = 1 0.00181 0 2212 2212 -2212 -2212 2112 111 +5122:addChannel = 1 0.0181 0 2212 2212 -2212 -2212 2112 111 111 +5122:addChannel = 1 0.0271 0 2212 2212 -2212 -2212 2112 211 -211 +5122:addChannel = 1 0.0181 0 2212 2212 -2212 -2212 2112 211 211 -211 -211 +5122:addChannel = 1 0.181 0 2212 2212 -2212 -2212 2112 211 -211 111 +5122:addChannel = 1 0.199 0 2212 2212 -2212 -2212 2112 211 -211 111 111 +5122:addChannel = 1 0.0271 0 2212 2212 -2212 -2212 2112 211 211 -211 -211 111 +5122:addChannel = 1 0.00452 0 2212 2212 -2212 -2212 2112 211 111 +5122:addChannel = 1 0.0361 0 2212 2212 2112 -2212 -2112 -211 111 +5122:addChannel = 1 0.0452 0 2212 2212 2112 -2212 -2112 -211 111 111 +5122:addChannel = 1 0.0542 0 2212 2212 2112 -2212 -2112 -211 -211 211 +5122:addChannel = 1 0.361 0 2212 2212 2112 -2212 -2112 -211 -211 211 111 +5122:addChannel = 1 0.0271 0 2212 2212 2112 -2212 -2112 -211 -211 211 111 111 +5122:onIfMatch = 2212 2212 2212 2212 2112 +5122:onIfMatch = 2212 2212 2212 2212 2112 111 +5122:onIfMatch = 2212 2212 2212 2212 2112 111 111 +5122:onIfMatch = 2212 2212 2212 2212 2112 211 211 +5122:onIfMatch = 2212 2212 2212 2212 2112 211 211 211 211 +5122:onIfMatch = 2212 2212 2212 2212 2112 211 211 111 +5122:onIfMatch = 2212 2212 2212 2212 2112 211 211 111 111 +5122:onIfMatch = 2212 2212 2212 2212 2112 211 211 211 211 111 +5122:onIfMatch = 2212 2212 2212 2212 2112 211 111 +5122:onIfMatch = 2212 2212 2112 2212 2112 211 111 +5122:onIfMatch = 2212 2212 2112 2212 2112 211 111 111 +5122:onIfMatch = 2212 2212 2112 2212 2112 211 211 211 +5122:onIfMatch = 2212 2212 2112 2212 2112 211 211 211 111 +5122:onIfMatch = 2212 2212 2112 2212 2112 211 211 211 111 111 \ No newline at end of file diff --git a/MC/config/PWGLF/epos/pp_536TeV_hydro_cascade.optns b/MC/config/PWGLF/epos/pp_536TeV_hydro_cascade.optns new file mode 100644 index 000000000..502cdc217 --- /dev/null +++ b/MC/config/PWGLF/epos/pp_536TeV_hydro_cascade.optns @@ -0,0 +1,32 @@ +!-------------------------------------------------------------------- +! proton-proton collisions at 5.36 TeV with hydro and hadronic cascade +!-------------------------------------------------------------------- + +!--------------------------------------- +! Define run +!--------------------------------------- + +application hadron !hadron-hadron, hadron-nucleus, or nucleus-nucleus +set laproj 1 !projectile atomic number +set maproj 1 !projectile mass number +set latarg 1 !target atomic number +set matarg 1 !target mass number +set ecms 5360 !sqrt(s)_pp +set istmax 25 !max status considered for storage + +ftime on !string formation time non-zero +!suppressed decays: +nodecays + 110 20 2130 -2130 2230 -2230 1130 -1130 1330 -1330 2330 -2330 3331 -3331 +end + +set ninicon 1 !number of initial conditions used for hydro evolution +core full !core/corona activated +hydro hlle !hydro activated +eos x3ff !eos activated (epos standard EoS) +hacas full !hadronic cascade activated (UrQMD) +set nfreeze 1 !number of freeze out events per hydro event +set modsho 1 !printout every modsho events +set centrality 0 !0=min bias +set ihepmc 2 !HepMC output enabled on stdout +set nfull 10 diff --git a/MC/config/PWGLF/ini/GeneratorDoubleLambdaTriggered.ini b/MC/config/PWGLF/ini/GeneratorDoubleLambdaTriggered.ini new file mode 100644 index 000000000..5051b84a9 --- /dev/null +++ b/MC/config/PWGLF/ini/GeneratorDoubleLambdaTriggered.ini @@ -0,0 +1,9 @@ +[GeneratorExternal] +fileName=${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGLF/pythia8/generator_pythia8_doubleLambdas.C +funcName=generateDoubleLambda(1, 0.6, 10, 0.8) + +[GeneratorPythia8] +config=${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGLF/pythia8/generator/pythia8_inel_ropes_136tev.cfg + +[DecayerPythia8] +config[0]=${O2DPG_MC_CONFIG_ROOT}/MC/config/common/pythia8/decayer/base.cfg diff --git a/MC/config/PWGLF/ini/GeneratorEPOS4_pp536TeV.ini b/MC/config/PWGLF/ini/GeneratorEPOS4_pp536TeV.ini new file mode 100644 index 000000000..5958fb64c --- /dev/null +++ b/MC/config/PWGLF/ini/GeneratorEPOS4_pp536TeV.ini @@ -0,0 +1,11 @@ +[GeneratorExternal] +fileName=${O2DPG_MC_CONFIG_ROOT}/MC/config/examples/epos4/generator_EPOS4.C +funcName=generateEPOS4("${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGLF/epos/pp_536TeV_hydro_cascade.optns", 2147483647) + +[GeneratorFileOrCmd] +cmd=${O2DPG_MC_CONFIG_ROOT}/MC/config/examples/epos4/epos.sh +bMaxSwitch=none + +# Set to version 2 if EPOS4.0.0 is used +[HepMC] +version=3 diff --git a/MC/config/PWGLF/ini/GeneratorLFCascadesInJets_pp536TeV.ini b/MC/config/PWGLF/ini/GeneratorLFCascadesInJets_pp536TeV.ini new file mode 100644 index 000000000..7f96b4461 --- /dev/null +++ b/MC/config/PWGLF/ini/GeneratorLFCascadesInJets_pp536TeV.ini @@ -0,0 +1,10 @@ +[GeneratorExternal] +fileName=${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGLF/pythia8/generator_pythia8_LF.C +# funcName=generateLFTriggered("${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGLF/pythia8/generator/strangeparticlelist.gun", 0) +funcName=generateLFTriggered("${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGLF/pythia8/generator/strangeparticlelist.gun", 4) + +[GeneratorPythia8] # if triggered then this will be used as the background event +config=${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGLF/pythia8/generator/pythia8_jet_ropes_536tev.cfg + +[DecayerPythia8] +config[0]=${O2DPG_MC_CONFIG_ROOT}/MC/config/common/pythia8/decayer/base.cfg diff --git a/MC/config/PWGLF/ini/GeneratorLFDeuteronOOGap.ini b/MC/config/PWGLF/ini/GeneratorLFDeuteronOOGap.ini new file mode 100644 index 000000000..5fd1a11dc --- /dev/null +++ b/MC/config/PWGLF/ini/GeneratorLFDeuteronOOGap.ini @@ -0,0 +1,6 @@ +[GeneratorExternal] +fileName=${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGLF/pythia8/generator_pythia8_longlived_gaptriggered.C +funcName=generateLongLivedGapTriggered({1000010020}, 1, 4, 0.4, 8.0) + +[GeneratorPythia8] +config=${O2DPG_MC_CONFIG_ROOT}/MC/config/common/pythia8/generator/pythia8_OO_536.cfg diff --git a/MC/config/PWGLF/ini/GeneratorLFHyperNucleiOOGap.ini b/MC/config/PWGLF/ini/GeneratorLFHyperNucleiOOGap.ini new file mode 100644 index 000000000..2c2477aab --- /dev/null +++ b/MC/config/PWGLF/ini/GeneratorLFHyperNucleiOOGap.ini @@ -0,0 +1,6 @@ +[GeneratorExternal] +fileName=${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGLF/pythia8/generator_pythia8_longlived_gaptriggered.C +funcName=generateLongLivedGapTriggered("${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGLF/pythia8/generator/hypernuclei_oo.gun", 1) + +[GeneratorPythia8] +config=${O2DPG_MC_CONFIG_ROOT}/MC/config/common/pythia8/generator/pythia8_OO_536.cfg \ No newline at end of file diff --git a/MC/config/PWGLF/ini/GeneratorLFHyperNucleiPbPbGapWithFlow.ini b/MC/config/PWGLF/ini/GeneratorLFHyperNucleiPbPbGapWithFlow.ini new file mode 100644 index 000000000..37d3320d3 --- /dev/null +++ b/MC/config/PWGLF/ini/GeneratorLFHyperNucleiPbPbGapWithFlow.ini @@ -0,0 +1,7 @@ +[GeneratorExternal] +fileName=${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGLF/pythia8/generator_pythia8_longlived_gaptriggered.C +funcName=generateLongLivedGapTriggered("${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGLF/pythia8/generator/hypernuclei_flow.gun", 1, 1, 1) + +[GeneratorPythia8] +config=${O2_ROOT}/share/Generators/egconfig/pythia8_hi.cfg + diff --git a/MC/config/PWGLF/ini/GeneratorLFHypertritonPbPbGap.ini b/MC/config/PWGLF/ini/GeneratorLFHypertritonPbPbGap.ini index b4159f513..a1d8f67e9 100644 --- a/MC/config/PWGLF/ini/GeneratorLFHypertritonPbPbGap.ini +++ b/MC/config/PWGLF/ini/GeneratorLFHypertritonPbPbGap.ini @@ -1,6 +1,6 @@ [GeneratorExternal] fileName=${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGLF/pythia8/generator_pythia8_longlived_gaptriggered.C -funcName=generateLongLivedGapTriggered({1010010030}, 5, 10) +funcName=generateLongLivedGapTriggered({1010010030}, 1, 20) [GeneratorPythia8] config=${O2_ROOT}/share/Generators/egconfig/pythia8_hi.cfg diff --git a/MC/config/PWGLF/ini/GeneratorLFNucleiPbPbInHMPIDAcceptance.ini b/MC/config/PWGLF/ini/GeneratorLFNucleiPbPbInHMPIDAcceptance.ini new file mode 100644 index 000000000..d0d246004 --- /dev/null +++ b/MC/config/PWGLF/ini/GeneratorLFNucleiPbPbInHMPIDAcceptance.ini @@ -0,0 +1,6 @@ +[GeneratorExternal] +fileName=${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGLF/pythia8/generator_pythia8_longlived.C +funcName=generateLongLived(1000010020,10,0.1,3.0,-0.6,0.6,-0.7,1.7,-1) + +[GeneratorPythia8] +config=${O2_ROOT}/share/Generators/egconfig/pythia8_hi.cfg diff --git a/MC/config/PWGLF/ini/GeneratorLFNucleippInHMPIDAcceptance.ini b/MC/config/PWGLF/ini/GeneratorLFNucleippInHMPIDAcceptance.ini new file mode 100644 index 000000000..fe7d7a39b --- /dev/null +++ b/MC/config/PWGLF/ini/GeneratorLFNucleippInHMPIDAcceptance.ini @@ -0,0 +1,6 @@ +[GeneratorExternal] +fileName=${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGLF/pythia8/generator_pythia8_longlived.C +funcName=generateLongLived(1000010020,10,0.1,3.0,-0.6,0.6,-0.7,1.7,-1) + +[GeneratorPythia8] +config=${O2_ROOT}/share/Generators/egconfig/pythia8_inel.cfg diff --git a/MC/config/PWGLF/ini/GeneratorLF_Resonances_PbPb5360_trigger.ini b/MC/config/PWGLF/ini/GeneratorLFSigmaPiResonances.ini similarity index 72% rename from MC/config/PWGLF/ini/GeneratorLF_Resonances_PbPb5360_trigger.ini rename to MC/config/PWGLF/ini/GeneratorLFSigmaPiResonances.ini index bffef0d39..e58e173c7 100644 --- a/MC/config/PWGLF/ini/GeneratorLF_Resonances_PbPb5360_trigger.ini +++ b/MC/config/PWGLF/ini/GeneratorLFSigmaPiResonances.ini @@ -1,9 +1,6 @@ [GeneratorExternal] fileName=${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGLF/pythia8/generator_pythia8_LF.C -funcName=generateLF("${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGLF/pythia8/generator/resonancelistgun_trig_pbpb.json", true, 4) - -[GeneratorPythia8] -config=${O2_ROOT}/share/Generators/egconfig/pythia8_hi.cfg +funcName=generateLF("${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGLF/pythia8/generator/sigmapi_resonances_gun.json", true, 4) [DecayerPythia8] # after for transport code! config[0]=${O2DPG_MC_CONFIG_ROOT}/MC/config/common/pythia8/decayer/base.cfg diff --git a/MC/config/PWGLF/ini/GeneratorLFStrangenessInJetsTriggered_gap4.ini b/MC/config/PWGLF/ini/GeneratorLFStrangenessInJetsTriggered_gap4.ini new file mode 100644 index 000000000..0e4746183 --- /dev/null +++ b/MC/config/PWGLF/ini/GeneratorLFStrangenessInJetsTriggered_gap4.ini @@ -0,0 +1,9 @@ +[GeneratorExternal] +fileName=${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGLF/pythia8/generator_pythia8_LF.C +funcName=generateLFTriggered("${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGLF/pythia8/generator/strangeparticlelist.gun", 4) + +[GeneratorPythia8] # if triggered then this will be used as the background event +config=${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGLF/pythia8/generator/pythia8_jet_ropes_136tev.cfg + +[DecayerPythia8] +config[0]=${O2DPG_MC_CONFIG_ROOT}/MC/config/common/pythia8/decayer/base.cfg diff --git a/MC/config/PWGLF/ini/GeneratorLFStrangenessTriggered_5360gev.ini b/MC/config/PWGLF/ini/GeneratorLFStrangenessTriggered_5360gev.ini new file mode 100644 index 000000000..09d05da74 --- /dev/null +++ b/MC/config/PWGLF/ini/GeneratorLFStrangenessTriggered_5360gev.ini @@ -0,0 +1,10 @@ +[GeneratorExternal] +fileName=${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGLF/pythia8/generator_pythia8_LF.C +# funcName=generateLFTriggered("${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGLF/pythia8/generator/strangeparticlelist.gun", 0) +funcName=generateLFTriggered("${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGLF/pythia8/generator/strangeparticlelist.gun", 4) + +[GeneratorPythia8] # if triggered then this will be used as the background event +config=${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGLF/pythia8/generator/pythia8_inel_pp536tev.cfg + +[DecayerPythia8] +config[0]=${O2DPG_MC_CONFIG_ROOT}/MC/config/common/pythia8/decayer/base.cfg diff --git a/MC/config/PWGLF/ini/GeneratorLF_Coalescence.ini b/MC/config/PWGLF/ini/GeneratorLF_Coalescence.ini index 94129d323..3d7c6c7c9 100644 --- a/MC/config/PWGLF/ini/GeneratorLF_Coalescence.ini +++ b/MC/config/PWGLF/ini/GeneratorLF_Coalescence.ini @@ -1,6 +1,7 @@ [GeneratorExternal] fileName = ${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGLF/pythia8/generator_pythia8_coalescence.C -funcName = generateCoalescence(1, 0.239) +funcName = generateCoalescence({1000010030, 1000020030, 1010010030}, 1, 0.239) [GeneratorPythia8] config=${O2_ROOT}/share/Generators/egconfig/pythia8_inel.cfg + diff --git a/MC/config/PWGLF/ini/GeneratorLF_Coalescence_pp536TeV.ini b/MC/config/PWGLF/ini/GeneratorLF_Coalescence_pp536TeV.ini new file mode 100644 index 000000000..2e8f1e3c5 --- /dev/null +++ b/MC/config/PWGLF/ini/GeneratorLF_Coalescence_pp536TeV.ini @@ -0,0 +1,7 @@ +[GeneratorExternal] +fileName = ${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGLF/pythia8/generator_pythia8_coalescence.C +funcName = generateCoalescence({1000010020, 1000010030, 1000020030}, 1, 0.239) + +[GeneratorPythia8] +config=${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGLF/pythia8/generator/pythia8_inel_pp536tev.cfg + diff --git a/MC/config/PWGLF/ini/GeneratorLF_ExoticResonances_pp1360.ini b/MC/config/PWGLF/ini/GeneratorLF_ExoticResonances_pp1360.ini index 55262cb83..abf18374a 100644 --- a/MC/config/PWGLF/ini/GeneratorLF_ExoticResonances_pp1360.ini +++ b/MC/config/PWGLF/ini/GeneratorLF_ExoticResonances_pp1360.ini @@ -1,10 +1,10 @@ [GeneratorExternal] -fileName=${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGLF/pythia8/generator_pythia8_LF.C -funcName=generateLF("${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGLF/pythia8/generator/exoticresonancegun.json", true, 4) +fileName=${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGLF/pythia8/generator_pythia8_LF_rapidity.C +funcName=generateLFRapidity("${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGLF/pythia8/generator/exoticresonancegun.json", true, 1, false, false, "${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGLF/pythia8/generator/pythia8_inel_136tev.cfg", "") -# [GeneratorPythia8] # if triggered then this will be used as the background event -# config=${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGLF/pythia8/generator/pythia8_inel_136tev.cfg +[GeneratorPythia8] # if triggered then this will be used as the background event +config=${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGLF/pythia8/generator/pythia8_inel_136tev.cfg [DecayerPythia8] # after for transport code! config[0]=${O2DPG_MC_CONFIG_ROOT}/MC/config/common/pythia8/decayer/base.cfg -config[1]=${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGLF/pythia8/generator/resonances.cfg \ No newline at end of file +config[1]=${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGLF/pythia8/generator/resonances.cfg diff --git a/MC/config/PWGLF/ini/GeneratorLF_Lambda1520_pp.ini b/MC/config/PWGLF/ini/GeneratorLF_Lambda1520_pp.ini new file mode 100644 index 000000000..5f2eb7dca --- /dev/null +++ b/MC/config/PWGLF/ini/GeneratorLF_Lambda1520_pp.ini @@ -0,0 +1,10 @@ +[GeneratorExternal] +fileName=${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGLF/pythia8/generator_pythia8_LF_rapidity.C +funcName=generateLFRapidity("${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGLF/pythia8/generator/lambda1520gun_inj.json", true, 1, false, false, "${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGLF/pythia8/generator/pythia8_inel_136tev.cfg", "") + +[GeneratorPythia8] +config=${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGLF/pythia8/generator/pythia8_inel_136tev.cfg + +[DecayerPythia8] +config[0]=${O2DPG_MC_CONFIG_ROOT}/MC/config/common/pythia8/decayer/base.cfg +config[1]=${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGLF/pythia8/generator/lambda1520.cfg diff --git a/MC/config/PWGLF/ini/GeneratorLF_ResonancesBaryonic_NeNe_injection.ini b/MC/config/PWGLF/ini/GeneratorLF_ResonancesBaryonic_NeNe_injection.ini new file mode 100644 index 000000000..2646765a9 --- /dev/null +++ b/MC/config/PWGLF/ini/GeneratorLF_ResonancesBaryonic_NeNe_injection.ini @@ -0,0 +1,10 @@ +[GeneratorExternal] +fileName=${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGLF/pythia8/generator_pythia8_LF_rapidity.C +funcName=generateLFRapidity("${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGLF/pythia8/generator/resonancelistgun_baryonic_inj.json", true, 4, false, false, "${O2DPG_MC_CONFIG_ROOT}/MC/config/common/pythia8/generator/pythia8_NeNe_536.cfg", "") + +[GeneratorPythia8] # if triggered then this will be used as the background event +config=${O2DPG_MC_CONFIG_ROOT}/MC/config/common/pythia8/generator/pythia8_NeNe_536.cfg + +[DecayerPythia8] # after for transport code! +config[0]=${O2DPG_MC_CONFIG_ROOT}/MC/config/common/pythia8/decayer/base.cfg +config[1]=${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGLF/pythia8/generator/resonances_baryonic.cfg diff --git a/MC/config/PWGLF/ini/GeneratorLF_ResonancesBaryonic_OO_injection.ini b/MC/config/PWGLF/ini/GeneratorLF_ResonancesBaryonic_OO_injection.ini new file mode 100644 index 000000000..ac4000cba --- /dev/null +++ b/MC/config/PWGLF/ini/GeneratorLF_ResonancesBaryonic_OO_injection.ini @@ -0,0 +1,10 @@ +[GeneratorExternal] +fileName=${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGLF/pythia8/generator_pythia8_LF_rapidity.C +funcName=generateLFRapidity("${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGLF/pythia8/generator/resonancelistgun_baryonic_inj.json", true, 4, false, false, "${O2DPG_MC_CONFIG_ROOT}/MC/config/common/pythia8/generator/pythia8_OO_536.cfg", "") + +[GeneratorPythia8] # if triggered then this will be used as the background event +config=${O2DPG_MC_CONFIG_ROOT}/MC/config/common/pythia8/generator/pythia8_OO_536.cfg + +[DecayerPythia8] # after for transport code! +config[0]=${O2DPG_MC_CONFIG_ROOT}/MC/config/common/pythia8/decayer/base.cfg +config[1]=${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGLF/pythia8/generator/resonances_baryonic.cfg diff --git a/MC/config/PWGLF/ini/GeneratorLF_ResonancesBaryonic_pO_injection.ini b/MC/config/PWGLF/ini/GeneratorLF_ResonancesBaryonic_pO_injection.ini new file mode 100644 index 000000000..b85a88051 --- /dev/null +++ b/MC/config/PWGLF/ini/GeneratorLF_ResonancesBaryonic_pO_injection.ini @@ -0,0 +1,10 @@ +[GeneratorExternal] +fileName=${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGLF/pythia8/generator_pythia8_LF_rapidity.C +funcName=generateLFRapidity("${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGLF/pythia8/generator/resonancelistgun_baryonic_inj.json", true, 4, false, false, "${O2DPG_MC_CONFIG_ROOT}/MC/config/common/pythia8/generator/pythia8_pO_961.cfg", "") + +[GeneratorPythia8] # if triggered then this will be used as the background event +config=${O2DPG_MC_CONFIG_ROOT}/MC/config/common/pythia8/generator/pythia8_pO_961.cfg + +[DecayerPythia8] # after for transport code! +config[0]=${O2DPG_MC_CONFIG_ROOT}/MC/config/common/pythia8/decayer/base.cfg +config[1]=${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGLF/pythia8/generator/resonances_baryonic.cfg diff --git a/MC/config/PWGLF/ini/GeneratorLF_ResonancesBaryonic_pp1360_injection.ini b/MC/config/PWGLF/ini/GeneratorLF_ResonancesBaryonic_pp1360_injection.ini new file mode 100644 index 000000000..7d9613efa --- /dev/null +++ b/MC/config/PWGLF/ini/GeneratorLF_ResonancesBaryonic_pp1360_injection.ini @@ -0,0 +1,10 @@ +[GeneratorExternal] +fileName=${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGLF/pythia8/generator_pythia8_LF_rapidity.C +funcName=generateLFRapidity("${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGLF/pythia8/generator/resonancelistgun_baryonic_inj.json", true, 4, false, false, "${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGLF/pythia8/generator/pythia8_inel_136tev.cfg", "") + +[GeneratorPythia8] # this will be used as the background event +config=${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGLF/pythia8/generator/pythia8_inel_136tev.cfg + +[DecayerPythia8] # after for transport code! +config[0]=${O2DPG_MC_CONFIG_ROOT}/MC/config/common/pythia8/decayer/base.cfg +config[1]=${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGLF/pythia8/generator/resonances_baryonic.cfg diff --git a/MC/config/PWGLF/ini/GeneratorLF_ResonancesBaryonic_pp1360_rapidityinjection.ini b/MC/config/PWGLF/ini/GeneratorLF_ResonancesBaryonic_pp1360_rapidityinjection.ini new file mode 100644 index 000000000..3b27a5608 --- /dev/null +++ b/MC/config/PWGLF/ini/GeneratorLF_ResonancesBaryonic_pp1360_rapidityinjection.ini @@ -0,0 +1,10 @@ +[GeneratorExternal] +fileName=${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGLF/pythia8/generator_pythia8_LF_rapidity.C +funcName=generateLFRapidity("${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGLF/pythia8/generator/resonancelistgun_baryonic_inj.json", true, 2, false, true, "${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGLF/pythia8/generator/pythia8_inel_136tev.cfg", "") + +[GeneratorPythia8] # this will be used as the background event +config=${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGLF/pythia8/generator/pythia8_inel_136tev.cfg + +[DecayerPythia8] # after for transport code! +config[0]=${O2DPG_MC_CONFIG_ROOT}/MC/config/common/pythia8/decayer/base.cfg +config[1]=${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGLF/pythia8/generator/resonances_baryonic.cfg diff --git a/MC/config/PWGLF/ini/GeneratorLF_Resonances_pp900_trigger.ini b/MC/config/PWGLF/ini/GeneratorLF_ResonancesBaryonic_pp5360_injection.ini similarity index 57% rename from MC/config/PWGLF/ini/GeneratorLF_Resonances_pp900_trigger.ini rename to MC/config/PWGLF/ini/GeneratorLF_ResonancesBaryonic_pp5360_injection.ini index 1f0328d6a..779dfcf51 100644 --- a/MC/config/PWGLF/ini/GeneratorLF_Resonances_pp900_trigger.ini +++ b/MC/config/PWGLF/ini/GeneratorLF_ResonancesBaryonic_pp5360_injection.ini @@ -1,10 +1,10 @@ [GeneratorExternal] -fileName=${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGLF/pythia8/generator_pythia8_LF.C -funcName=generateLF("${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGLF/pythia8/generator/resonancelistgun_trig.json", true, 4) +fileName=${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGLF/pythia8/generator_pythia8_LF_rapidity.C +funcName=generateLFRapidity("${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGLF/pythia8/generator/resonancelistgun_exoticAll.json", true, 2, false, true, "${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGLF/pythia8/generator/pythia8_inel_pp536tev.cfg", "") [GeneratorPythia8] # if triggered then this will be used as the background event -config=${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGLF/pythia8/generator/pythia8_inel_pp900gev.cfg +config=${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGLF/pythia8/generator/pythia8_inel_pp536tev.cfg [DecayerPythia8] # after for transport code! config[0]=${O2DPG_MC_CONFIG_ROOT}/MC/config/common/pythia8/decayer/base.cfg -config[1]=${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGLF/pythia8/generator/resonances.cfg \ No newline at end of file +config[1]=${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGLF/pythia8/generator/resonances.cfg diff --git a/MC/config/PWGLF/ini/GeneratorLF_Resonances_PbPb.ini b/MC/config/PWGLF/ini/GeneratorLF_Resonances_PbPb.ini index b66e66584..0c568d47c 100644 --- a/MC/config/PWGLF/ini/GeneratorLF_Resonances_PbPb.ini +++ b/MC/config/PWGLF/ini/GeneratorLF_Resonances_PbPb.ini @@ -1,10 +1,10 @@ [GeneratorExternal] -fileName=${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGLF/pythia8/generator_pythia8_LF.C -funcName=generateLF("${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGLF/pythia8/generator/resonancelistgun_pbpb.json", true, 4) +fileName=${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGLF/pythia8/generator_pythia8_LF_rapidity.C +funcName=generateLFRapidity("${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGLF/pythia8/generator/resonancelistgun_trig.json", true, 4, true, false, "${O2_ROOT}/share/Generators/egconfig/pythia8_hi.cfg", "${O2_ROOT}/share/Generators/egconfig/pythia8_hi.cfg") -# [GeneratorPythia8] -# config=${O2_ROOT}/share/Generators/egconfig/pythia8_hi.cfg +[GeneratorPythia8] +config=${O2_ROOT}/share/Generators/egconfig/pythia8_hi.cfg [DecayerPythia8] # after for transport code! config[0]=${O2DPG_MC_CONFIG_ROOT}/MC/config/common/pythia8/decayer/base.cfg -config[1]=${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGLF/pythia8/generator/resonances.cfg \ No newline at end of file +config[1]=${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGLF/pythia8/generator/resonances.cfg diff --git a/MC/config/PWGLF/ini/GeneratorLF_Resonances_PbPb5360_injection.ini b/MC/config/PWGLF/ini/GeneratorLF_Resonances_PbPb5360_injection.ini index 89faa5413..7bce5d0b5 100644 --- a/MC/config/PWGLF/ini/GeneratorLF_Resonances_PbPb5360_injection.ini +++ b/MC/config/PWGLF/ini/GeneratorLF_Resonances_PbPb5360_injection.ini @@ -1,10 +1,10 @@ [GeneratorExternal] -fileName=${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGLF/pythia8/generator_pythia8_LF.C -funcName=generateLF("${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGLF/pythia8/generator/resonancelistgun_inj_pbpb.json", true, 4) +fileName=${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGLF/pythia8/generator_pythia8_LF_rapidity.C +funcName=generateLFRapidity("${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGLF/pythia8/generator/resonancelistgun_inj_pbpb.json", true, 1, false, false, "${O2_ROOT}/share/Generators/egconfig/pythia8_hi.cfg", "") -# [GeneratorPythia8] -# config=${O2_ROOT}/share/Generators/egconfig/pythia8_hi.cfg +[GeneratorPythia8] +config=${O2_ROOT}/share/Generators/egconfig/pythia8_hi.cfg [DecayerPythia8] # after for transport code! config[0]=${O2DPG_MC_CONFIG_ROOT}/MC/config/common/pythia8/decayer/base.cfg -config[1]=${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGLF/pythia8/generator/resonances.cfg \ No newline at end of file +config[1]=${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGLF/pythia8/generator/resonances.cfg diff --git a/MC/config/PWGLF/ini/GeneratorLF_Resonances_PbPb_exotic.ini b/MC/config/PWGLF/ini/GeneratorLF_Resonances_PbPb_exotic.ini index e2e575af0..8c3471b4f 100644 --- a/MC/config/PWGLF/ini/GeneratorLF_Resonances_PbPb_exotic.ini +++ b/MC/config/PWGLF/ini/GeneratorLF_Resonances_PbPb_exotic.ini @@ -1,10 +1,10 @@ [GeneratorExternal] -fileName=${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGLF/pythia8/generator_pythia8_LF.C -funcName=generateLF("${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGLF/pythia8/generator/resonancelistgun_exotic_pbpb.json", true, 4) +fileName=${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGLF/pythia8/generator_pythia8_LF_rapidity.C +funcName=generateLFRapidity("${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGLF/pythia8/generator/resonancelistgun_exotic_pbpb.json", true, 4, false, false, "${O2_ROOT}/share/Generators/egconfig/pythia8_hi.cfg", "") -# [GeneratorPythia8] -# config=${O2_ROOT}/share/Generators/egconfig/pythia8_hi.cfg +[GeneratorPythia8] +config=${O2_ROOT}/share/Generators/egconfig/pythia8_hi.cfg [DecayerPythia8] # after for transport code! config[0]=${O2DPG_MC_CONFIG_ROOT}/MC/config/common/pythia8/decayer/base.cfg -config[1]=${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGLF/pythia8/generator/resonances.cfg \ No newline at end of file +config[1]=${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGLF/pythia8/generator/resonances.cfg diff --git a/MC/config/PWGLF/ini/GeneratorLF_Resonances_pp.ini b/MC/config/PWGLF/ini/GeneratorLF_Resonances_pp.ini index 8e91af28b..543c0d7b2 100644 --- a/MC/config/PWGLF/ini/GeneratorLF_Resonances_pp.ini +++ b/MC/config/PWGLF/ini/GeneratorLF_Resonances_pp.ini @@ -1,10 +1,10 @@ [GeneratorExternal] -fileName=${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGLF/pythia8/generator_pythia8_LF.C -funcName=generateLF("${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGLF/pythia8/generator/resonancelistgun.json", true, 4) +fileName=${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGLF/pythia8/generator_pythia8_LF_rapidity.C +funcName=generateLFRapidity("${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGLF/pythia8/generator/resonancelistgun_trig.json", true, 4, true, false, "${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGLF/pythia8/generator/pythia8_inel_136tev.cfg", "${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGLF/pythia8/generator/pythia8_inel_136tev.cfg") -# [GeneratorPythia8] # if triggered then this will be used as the background event -# config=${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGLF/pythia8/generator/pythia8_inel_136tev.cfg +[GeneratorPythia8] # if triggered then this will be used as the background event +config=${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGLF/pythia8/generator/pythia8_inel_136tev.cfg [DecayerPythia8] # after for transport code! config[0]=${O2DPG_MC_CONFIG_ROOT}/MC/config/common/pythia8/decayer/base.cfg -config[1]=${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGLF/pythia8/generator/resonances.cfg \ No newline at end of file +config[1]=${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGLF/pythia8/generator/resonances.cfg diff --git a/MC/config/PWGLF/ini/GeneratorLF_Resonances_pp1360.ini b/MC/config/PWGLF/ini/GeneratorLF_Resonances_pp1360.ini index 8e91af28b..543c0d7b2 100644 --- a/MC/config/PWGLF/ini/GeneratorLF_Resonances_pp1360.ini +++ b/MC/config/PWGLF/ini/GeneratorLF_Resonances_pp1360.ini @@ -1,10 +1,10 @@ [GeneratorExternal] -fileName=${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGLF/pythia8/generator_pythia8_LF.C -funcName=generateLF("${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGLF/pythia8/generator/resonancelistgun.json", true, 4) +fileName=${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGLF/pythia8/generator_pythia8_LF_rapidity.C +funcName=generateLFRapidity("${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGLF/pythia8/generator/resonancelistgun_trig.json", true, 4, true, false, "${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGLF/pythia8/generator/pythia8_inel_136tev.cfg", "${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGLF/pythia8/generator/pythia8_inel_136tev.cfg") -# [GeneratorPythia8] # if triggered then this will be used as the background event -# config=${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGLF/pythia8/generator/pythia8_inel_136tev.cfg +[GeneratorPythia8] # if triggered then this will be used as the background event +config=${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGLF/pythia8/generator/pythia8_inel_136tev.cfg [DecayerPythia8] # after for transport code! config[0]=${O2DPG_MC_CONFIG_ROOT}/MC/config/common/pythia8/decayer/base.cfg -config[1]=${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGLF/pythia8/generator/resonances.cfg \ No newline at end of file +config[1]=${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGLF/pythia8/generator/resonances.cfg diff --git a/MC/config/PWGLF/ini/GeneratorLF_Resonances_pp1360_injection.ini b/MC/config/PWGLF/ini/GeneratorLF_Resonances_pp1360_injection.ini index 9e3d43470..c8ad07a90 100644 --- a/MC/config/PWGLF/ini/GeneratorLF_Resonances_pp1360_injection.ini +++ b/MC/config/PWGLF/ini/GeneratorLF_Resonances_pp1360_injection.ini @@ -1,10 +1,10 @@ [GeneratorExternal] -fileName=${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGLF/pythia8/generator_pythia8_LF.C -funcName=generateLF("${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGLF/pythia8/generator/resonancelistgun_inj.json", true, 4) +fileName=${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGLF/pythia8/generator_pythia8_LF_rapidity.C +funcName=generateLFRapidity("${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGLF/pythia8/generator/resonancelistgun_inj.json", true, 1, false, false, "${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGLF/pythia8/generator/pythia8_inel_136tev.cfg", "") -# [GeneratorPythia8] # if triggered then this will be used as the background event -# config=${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGLF/pythia8/generator/pythia8_inel_136tev.cfg +[GeneratorPythia8] # if triggered then this will be used as the background event +config=${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGLF/pythia8/generator/pythia8_inel_136tev.cfg [DecayerPythia8] # after for transport code! config[0]=${O2DPG_MC_CONFIG_ROOT}/MC/config/common/pythia8/decayer/base.cfg -config[1]=${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGLF/pythia8/generator/resonances.cfg \ No newline at end of file +config[1]=${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGLF/pythia8/generator/resonances.cfg diff --git a/MC/config/PWGLF/ini/GeneratorLF_Resonances_pp900.ini b/MC/config/PWGLF/ini/GeneratorLF_Resonances_pp900.ini index d23569e2a..e1895740b 100644 --- a/MC/config/PWGLF/ini/GeneratorLF_Resonances_pp900.ini +++ b/MC/config/PWGLF/ini/GeneratorLF_Resonances_pp900.ini @@ -1,10 +1,10 @@ [GeneratorExternal] -fileName=${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGLF/pythia8/generator_pythia8_LF.C -funcName=generateLF("${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGLF/pythia8/generator/resonancelistgun.json", true, 4) +fileName=${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGLF/pythia8/generator_pythia8_LF_rapidity.C +funcName=generateLFRapidity("${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGLF/pythia8/generator/resonancelistgun_trig.json", true, 4, true, false, "${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGLF/pythia8/generator/pythia8_inel_pp900gev.cfg", "${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGLF/pythia8/generator/pythia8_inel_pp900gev.cfg") -# [GeneratorPythia8] # if triggered then this will be used as the background event -# config=${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGLF/pythia8/generator/pythia8_inel_pp900gev.cfg +[GeneratorPythia8] # if triggered then this will be used as the background event +config=${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGLF/pythia8/generator/pythia8_inel_pp900gev.cfg [DecayerPythia8] # after for transport code! config[0]=${O2DPG_MC_CONFIG_ROOT}/MC/config/common/pythia8/decayer/base.cfg -config[1]=${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGLF/pythia8/generator/resonances.cfg \ No newline at end of file +config[1]=${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGLF/pythia8/generator/resonances.cfg diff --git a/MC/config/PWGLF/ini/GeneratorLF_Resonances_pp900_injection.ini b/MC/config/PWGLF/ini/GeneratorLF_Resonances_pp900_injection.ini index 4ef0a59b6..d172f034f 100644 --- a/MC/config/PWGLF/ini/GeneratorLF_Resonances_pp900_injection.ini +++ b/MC/config/PWGLF/ini/GeneratorLF_Resonances_pp900_injection.ini @@ -1,10 +1,10 @@ [GeneratorExternal] -fileName=${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGLF/pythia8/generator_pythia8_LF.C -funcName=generateLF("${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGLF/pythia8/generator/resonancelistgun_inj.json", true, 4) +fileName=${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGLF/pythia8/generator_pythia8_LF_rapidity.C +funcName=generateLFRapidity("${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGLF/pythia8/generator/resonancelistgun_inj.json", true, 4, false, false, "${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGLF/pythia8/generator/pythia8_inel_pp900gev.cfg", "") -# [GeneratorPythia8] # if triggered then this will be used as the background event -# config=${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGLF/pythia8/generator/pythia8_inel_pp900gev.cfg +[GeneratorPythia8] # if triggered then this will be used as the background event +config=${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGLF/pythia8/generator/pythia8_inel_pp900gev.cfg [DecayerPythia8] # after for transport code! config[0]=${O2DPG_MC_CONFIG_ROOT}/MC/config/common/pythia8/decayer/base.cfg -config[1]=${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGLF/pythia8/generator/resonances.cfg \ No newline at end of file +config[1]=${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGLF/pythia8/generator/resonances.cfg diff --git a/MC/config/PWGLF/ini/GeneratorLF_Resonances_pp_exotic.ini b/MC/config/PWGLF/ini/GeneratorLF_Resonances_pp_exotic.ini index a49804cc8..e520191e7 100644 --- a/MC/config/PWGLF/ini/GeneratorLF_Resonances_pp_exotic.ini +++ b/MC/config/PWGLF/ini/GeneratorLF_Resonances_pp_exotic.ini @@ -1,10 +1,10 @@ [GeneratorExternal] -fileName=${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGLF/pythia8/generator_pythia8_LF.C -funcName=generateLF("${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGLF/pythia8/generator/resonancelistgun_exotic.json", true, 4) +fileName=${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGLF/pythia8/generator_pythia8_LF_rapidity.C +funcName=generateLFRapidity("${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGLF/pythia8/generator/gluelistgun.json", true, 2, false, true, "${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGLF/pythia8/generator/pythia8_inel_136tev.cfg", "") -# [GeneratorPythia8] # if triggered then this will be used as the background event -# config=${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGLF/pythia8/generator/pythia8_inel_136tev.cfg +[GeneratorPythia8] # if triggered then this will be used as the background event +config=${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGLF/pythia8/generator/pythia8_inel_136tev.cfg [DecayerPythia8] # after for transport code! config[0]=${O2DPG_MC_CONFIG_ROOT}/MC/config/common/pythia8/decayer/base.cfg -config[1]=${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGLF/pythia8/generator/resonances.cfg \ No newline at end of file +config[1]=${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGLF/pythia8/generator/resonances.cfg diff --git a/MC/config/PWGLF/ini/GeneratorLF_Resonances_pp1360_trigger.ini b/MC/config/PWGLF/ini/GeneratorLF_Resonances_pp_exoticAll.ini similarity index 61% rename from MC/config/PWGLF/ini/GeneratorLF_Resonances_pp1360_trigger.ini rename to MC/config/PWGLF/ini/GeneratorLF_Resonances_pp_exoticAll.ini index 0a4d58ca4..64d174b68 100644 --- a/MC/config/PWGLF/ini/GeneratorLF_Resonances_pp1360_trigger.ini +++ b/MC/config/PWGLF/ini/GeneratorLF_Resonances_pp_exoticAll.ini @@ -1,10 +1,10 @@ [GeneratorExternal] -fileName=${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGLF/pythia8/generator_pythia8_LF.C -funcName=generateLF("${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGLF/pythia8/generator/resonancelistgun_trig.json", true, 4) +fileName=${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGLF/pythia8/generator_pythia8_LF_rapidity.C +funcName=generateLFRapidity("${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGLF/pythia8/generator/resonancelistgun_exoticAll.json", true, 4, false, false, "${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGLF/pythia8/generator/pythia8_inel_136tev.cfg", "") [GeneratorPythia8] # if triggered then this will be used as the background event config=${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGLF/pythia8/generator/pythia8_inel_136tev.cfg [DecayerPythia8] # after for transport code! config[0]=${O2DPG_MC_CONFIG_ROOT}/MC/config/common/pythia8/decayer/base.cfg -config[1]=${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGLF/pythia8/generator/resonances.cfg \ No newline at end of file +config[1]=${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGLF/pythia8/generator/resonances.cfg diff --git a/MC/config/PWGLF/ini/GeneratorLF_Resonances_pp_exoticAll_gap2.ini b/MC/config/PWGLF/ini/GeneratorLF_Resonances_pp_exoticAll_gap2.ini new file mode 100644 index 000000000..e55c3195c --- /dev/null +++ b/MC/config/PWGLF/ini/GeneratorLF_Resonances_pp_exoticAll_gap2.ini @@ -0,0 +1,10 @@ +[GeneratorExternal] +fileName=${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGLF/pythia8/generator_pythia8_LF_rapidity.C +funcName=generateLFRapidity("${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGLF/pythia8/generator/resonancelistgun_exoticAll.json", true, 2, false, true, "${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGLF/pythia8/generator/pythia8_inel_136tev.cfg", "") + +[GeneratorPythia8] # this will be used as the background event +config=${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGLF/pythia8/generator/pythia8_inel_136tev.cfg + +[DecayerPythia8] # after for transport code! +config[0]=${O2DPG_MC_CONFIG_ROOT}/MC/config/common/pythia8/decayer/base.cfg +config[1]=${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGLF/pythia8/generator/resonances.cfg diff --git a/MC/config/PWGLF/ini/GeneratorLF_StrangenessInJets_gap4.ini b/MC/config/PWGLF/ini/GeneratorLF_StrangenessInJets_gap4.ini new file mode 100644 index 000000000..80b0235b8 --- /dev/null +++ b/MC/config/PWGLF/ini/GeneratorLF_StrangenessInJets_gap4.ini @@ -0,0 +1,6 @@ +[GeneratorExternal] +fileName = ${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGLF/pythia8/generator_pythia8_strangeness_in_jets.C +funcName = generateStrangenessInJets(10.0,0.4,4) + +[GeneratorPythia8] +config=${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGLF/pythia8/generator/pythia8_jet_ropes_136tev.cfg \ No newline at end of file diff --git a/MC/config/PWGLF/ini/GeneratorLF_Strangeness_OO5360_injection.ini b/MC/config/PWGLF/ini/GeneratorLF_Strangeness_OO5360_injection.ini new file mode 100644 index 000000000..33df39f1b --- /dev/null +++ b/MC/config/PWGLF/ini/GeneratorLF_Strangeness_OO5360_injection.ini @@ -0,0 +1,6 @@ +[GeneratorExternal] +fileName=${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGLF/pythia8/generator_pythia8_extraStrangeness.C +funcName=generator_extraStrangeness(5,30) + +[GeneratorPythia8] +config=${O2DPG_MC_CONFIG_ROOT}/MC/config/common/pythia8/generator/pythia8_OO_536.cfg diff --git a/MC/config/PWGLF/ini/GeneratorLF_Strangeness_OO5360_injection_omega100.ini b/MC/config/PWGLF/ini/GeneratorLF_Strangeness_OO5360_injection_omega100.ini new file mode 100644 index 000000000..326f7e6c8 --- /dev/null +++ b/MC/config/PWGLF/ini/GeneratorLF_Strangeness_OO5360_injection_omega100.ini @@ -0,0 +1,6 @@ +[GeneratorExternal] +fileName=${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGLF/pythia8/generator_pythia8_extraStrangeness.C +funcName=generator_extraStrangeness(10,100) + +[GeneratorPythia8] +config=${O2DPG_MC_CONFIG_ROOT}/MC/config/common/pythia8/generator/pythia8_OO_536.cfg diff --git a/MC/config/PWGLF/ini/GeneratorLF_Strangeness_OO5360_injection_omega30.ini b/MC/config/PWGLF/ini/GeneratorLF_Strangeness_OO5360_injection_omega30.ini new file mode 100644 index 000000000..ea7fa77a8 --- /dev/null +++ b/MC/config/PWGLF/ini/GeneratorLF_Strangeness_OO5360_injection_omega30.ini @@ -0,0 +1,6 @@ +[GeneratorExternal] +fileName=${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGLF/pythia8/generator_pythia8_extraStrangeness.C +funcName=generator_extraStrangeness(10,30) + +[GeneratorPythia8] +config=${O2DPG_MC_CONFIG_ROOT}/MC/config/common/pythia8/generator/pythia8_OO_536.cfg diff --git a/MC/config/PWGLF/ini/GeneratorLF_Strangeness_OO5360_injection_omega300.ini b/MC/config/PWGLF/ini/GeneratorLF_Strangeness_OO5360_injection_omega300.ini new file mode 100644 index 000000000..2d7273ab3 --- /dev/null +++ b/MC/config/PWGLF/ini/GeneratorLF_Strangeness_OO5360_injection_omega300.ini @@ -0,0 +1,6 @@ +[GeneratorExternal] +fileName=${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGLF/pythia8/generator_pythia8_extraStrangeness.C +funcName=generator_extraStrangeness(10,300) + +[GeneratorPythia8] +config=${O2DPG_MC_CONFIG_ROOT}/MC/config/common/pythia8/generator/pythia8_OO_536.cfg diff --git a/MC/config/PWGLF/ini/GeneratorLF_Strangeness_OO5360_injection_omega50.ini b/MC/config/PWGLF/ini/GeneratorLF_Strangeness_OO5360_injection_omega50.ini new file mode 100644 index 000000000..9b9b041ac --- /dev/null +++ b/MC/config/PWGLF/ini/GeneratorLF_Strangeness_OO5360_injection_omega50.ini @@ -0,0 +1,6 @@ +[GeneratorExternal] +fileName=${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGLF/pythia8/generator_pythia8_extraStrangeness.C +funcName=generator_extraStrangeness(10,50) + +[GeneratorPythia8] +config=${O2DPG_MC_CONFIG_ROOT}/MC/config/common/pythia8/generator/pythia8_OO_536.cfg diff --git a/MC/config/PWGLF/ini/GeneratorLF_Strangeness_OO5360_injection_omega500.ini b/MC/config/PWGLF/ini/GeneratorLF_Strangeness_OO5360_injection_omega500.ini new file mode 100644 index 000000000..d3b36a244 --- /dev/null +++ b/MC/config/PWGLF/ini/GeneratorLF_Strangeness_OO5360_injection_omega500.ini @@ -0,0 +1,6 @@ +[GeneratorExternal] +fileName=${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGLF/pythia8/generator_pythia8_extraStrangeness.C +funcName=generator_extraStrangeness(10,500) + +[GeneratorPythia8] +config=${O2DPG_MC_CONFIG_ROOT}/MC/config/common/pythia8/generator/pythia8_OO_536.cfg diff --git a/MC/config/PWGLF/ini/GeneratorLF_SyntheFlowOO.ini b/MC/config/PWGLF/ini/GeneratorLF_SyntheFlowOO.ini new file mode 100644 index 000000000..ee52a0a61 --- /dev/null +++ b/MC/config/PWGLF/ini/GeneratorLF_SyntheFlowOO.ini @@ -0,0 +1,6 @@ +[GeneratorExternal] +fileName=${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGLF/pythia8/generator_pythia8_syntheFlowOO.C +funcName=generator_syntheFlowOO() + +[GeneratorPythia8] +config=${O2DPG_MC_CONFIG_ROOT}/MC/config/common/pythia8/generator/pythia8_OO_536.cfg diff --git a/MC/config/PWGLF/ini/GeneratorLF_deuteron_wigner.ini b/MC/config/PWGLF/ini/GeneratorLF_deuteron_wigner.ini new file mode 100644 index 000000000..1f12b9d03 --- /dev/null +++ b/MC/config/PWGLF/ini/GeneratorLF_deuteron_wigner.ini @@ -0,0 +1,6 @@ +[GeneratorExternal] +fileName = ${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGLF/pythia8/generator_pythia8_deuteron_wigner.C +funcName = generateAntideuteronsWignerCoalescence(1.2) + +[GeneratorPythia8] +config=${O2_ROOT}/share/Generators/egconfig/pythia8_inel.cfg diff --git a/MC/config/PWGLF/ini/GeneratorLF_pp536_Ropes.ini b/MC/config/PWGLF/ini/GeneratorLF_pp536_Ropes.ini new file mode 100644 index 000000000..2bfa5df9f --- /dev/null +++ b/MC/config/PWGLF/ini/GeneratorLF_pp536_Ropes.ini @@ -0,0 +1,6 @@ +[GeneratorExternal] +fileName=${O2DPG_MC_CONFIG_ROOT}/MC/config/ALICE3/pythia8/generator_pythia8_ALICE3.C +funcName=generator_pythia8_ALICE3() + +[GeneratorPythia8] +config=${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGLF/pythia8/generator/pythia8_inel_ropes_536tev.cfg \ No newline at end of file diff --git a/MC/config/PWGLF/ini/GeneratorLF_pp536_wDeCoal.ini b/MC/config/PWGLF/ini/GeneratorLF_pp536_wDeCoal.ini new file mode 100644 index 000000000..126aa66ca --- /dev/null +++ b/MC/config/PWGLF/ini/GeneratorLF_pp536_wDeCoal.ini @@ -0,0 +1,6 @@ +[GeneratorExternal] +fileName=${O2DPG_MC_CONFIG_ROOT}/MC/config/ALICE3/pythia8/generator_pythia8_ALICE3.C +funcName=generator_pythia8_ALICE3() + +[GeneratorPythia8] +config=${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGLF/pythia8/generator/pythia8_inel_536tev_wDeCoal.cfg \ No newline at end of file diff --git a/MC/config/PWGLF/ini/GeneratorLF_pp536_wDeInel.ini b/MC/config/PWGLF/ini/GeneratorLF_pp536_wDeInel.ini new file mode 100644 index 000000000..10d233002 --- /dev/null +++ b/MC/config/PWGLF/ini/GeneratorLF_pp536_wDeInel.ini @@ -0,0 +1,6 @@ +[GeneratorExternal] +fileName=${O2DPG_MC_CONFIG_ROOT}/MC/config/ALICE3/pythia8/generator_pythia8_ALICE3.C +funcName=generator_pythia8_ALICE3() + +[GeneratorPythia8] +config=${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGLF/pythia8/generator/pythia8_inel_536tev_wDeInel.cfg \ No newline at end of file diff --git a/MC/config/PWGLF/ini/GeneratorSigmaProtonTriggered.ini b/MC/config/PWGLF/ini/GeneratorSigmaProtonTriggered.ini new file mode 100644 index 000000000..923a5947d --- /dev/null +++ b/MC/config/PWGLF/ini/GeneratorSigmaProtonTriggered.ini @@ -0,0 +1,5 @@ +[GeneratorExternal] +fileName=${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGLF/pythia8/generator_pythia8_sigma_hadron.C +funcName=generateSigmaHadron(2212, 2, 1, 10, 0.8) +[GeneratorPythia8] +config=${O2_ROOT}/share/Generators/egconfig/pythia8_inel.cfg \ No newline at end of file diff --git a/MC/config/PWGLF/ini/tests/GeneratorDoubleLambdaTriggered.C b/MC/config/PWGLF/ini/tests/GeneratorDoubleLambdaTriggered.C new file mode 100644 index 000000000..96fcd8bbd --- /dev/null +++ b/MC/config/PWGLF/ini/tests/GeneratorDoubleLambdaTriggered.C @@ -0,0 +1,25 @@ +int External() { + std::string path{"o2sim_Kine.root"}; + + TFile file(path.c_str(), "READ"); + if (file.IsZombie()) { + std::cerr << "Cannot open ROOT file " << path << "\n"; + return 1; + } + + auto tree = (TTree *)file.Get("o2sim"); + if (!tree) { + std::cerr << "Cannot find tree o2sim in file " << path << "\n"; + return 1; + } + std::vector *tracks{}; + tree->SetBranchAddress("MCTrack", &tracks); + + auto nLambda = tree->Scan("MCTrack.GetPdgCode()", "TMath::Abs(MCTrack.GetPdgCode()) == 3122"); + + if (nLambda == 0) { + std::cerr << "No event of interest\n"; + return 1; + } + return 0; +} diff --git a/MC/config/PWGLF/ini/tests/GeneratorEPOS4_pp536TeV.C b/MC/config/PWGLF/ini/tests/GeneratorEPOS4_pp536TeV.C new file mode 100644 index 000000000..5f9432f9e --- /dev/null +++ b/MC/config/PWGLF/ini/tests/GeneratorEPOS4_pp536TeV.C @@ -0,0 +1,64 @@ +int External() +{ + std::string path{"o2sim_Kine.root"}; + // Check that file exists, can be opened and has the correct tree + TFile file(path.c_str(), "READ"); + if (file.IsZombie()) + { + std::cerr << "Cannot open ROOT file " << path << "\n"; + return 1; + } + auto tree = (TTree *)file.Get("o2sim"); + if (!tree) + { + std::cerr << "Cannot find tree o2sim in file " << path << "\n"; + return 1; + } + std::vector *tracks{}; + tree->SetBranchAddress("MCTrack", &tracks); + + // Check if all events are filled + auto nEvents = tree->GetEntries(); + for (Long64_t i = 0; i < nEvents; ++i) + { + tree->GetEntry(i); + if (tracks->empty()) + { + std::cerr << "Empty entry found at event " << i << "\n"; + return 1; + } + } + // Check if there are 100 events, as simulated in the o2dpg-test + if (nEvents != 100) + { + std::cerr << "Expected 100 events, got " << nEvents << "\n"; + return 1; + } + // check if each event has two protons with 2680 GeV of energy + // exits if the particle is not a proton + for (int i = 0; i < nEvents; i++) + { + auto check = tree->GetEntry(i); + int count = 0; + for (int idxMCTrack = 0; idxMCTrack < tracks->size(); ++idxMCTrack) + { + auto track = tracks->at(idxMCTrack); + double energy = track.GetEnergy(); + // Check if track energy is approximately equal to 2680 GeV (a tolerance of 65 keV is considered, straight equality does not work due to floating point precision) + if (std::abs(energy - 2680) < 1e-4) + { + if (track.GetPdgCode() != 2212){ + std::cerr << "Found 2680 GeV particle with pdgID " << track.GetPdgCode() << "\n"; + return 1; + } + count++; + } + } + if (count < 2) + { + std::cerr << "Event " << i << " has less than 2 protons at 2680 GeV\n"; + return 1; + } + } + return 0; +} diff --git a/MC/config/PWGLF/ini/tests/GeneratorLFCascadesInJets_pp536TeV.C b/MC/config/PWGLF/ini/tests/GeneratorLFCascadesInJets_pp536TeV.C new file mode 100644 index 000000000..49ba5d4e2 --- /dev/null +++ b/MC/config/PWGLF/ini/tests/GeneratorLFCascadesInJets_pp536TeV.C @@ -0,0 +1,58 @@ +int External() +{ + std::string path{"o2sim_Kine.root"}; + int numberOfInjectedSignalsPerEvent{1}; + std::vector injectedPDGs = { + 3334, + -3334, + 3312, + -3312}; + + auto nInjection = injectedPDGs.size(); + + TFile file(path.c_str(), "READ"); + if (file.IsZombie()) { + std::cerr << "Cannot open ROOT file " << path << "\n"; + return 1; + } + + auto tree = (TTree*)file.Get("o2sim"); + if (!tree) { + std::cerr << "Cannot find tree o2sim in file " << path << "\n"; + return 1; + } + std::vector* tracks{}; + tree->SetBranchAddress("MCTrack", &tracks); + + std::vector nSignal; + for (int i = 0; i < nInjection; i++) { + nSignal.push_back(0); + } + + auto nEvents = tree->GetEntries(); + for (int i = 0; i < nEvents; i++) { + auto check = tree->GetEntry(i); + for (int idxMCTrack = 0; idxMCTrack < tracks->size(); ++idxMCTrack) { + auto track = tracks->at(idxMCTrack); + auto pdg = track.GetPdgCode(); + auto it = std::find(injectedPDGs.begin(), injectedPDGs.end(), pdg); + int index = std::distance(injectedPDGs.begin(), it); // index of injected PDG + if (it != injectedPDGs.end()) // found + { + // count signal PDG + nSignal[index]++; + } + } + } + std::cout << "--------------------------------\n"; + std::cout << "# Events: " << nEvents << "\n"; + for (int i = 0; i < nInjection; i++) { + std::cout << "# Injected nuclei \n"; + std::cout << injectedPDGs[i] << ": " << nSignal[i] << "\n"; + if (nSignal[i] == 0) { + std::cerr << "No generated: " << injectedPDGs[i] << "\n"; + return 1; // At least one of the injected particles should be generated + } + } + return 0; +} \ No newline at end of file diff --git a/MC/config/PWGLF/ini/tests/GeneratorLFDeuteronOOGap.C b/MC/config/PWGLF/ini/tests/GeneratorLFDeuteronOOGap.C new file mode 100644 index 000000000..6d270f811 --- /dev/null +++ b/MC/config/PWGLF/ini/tests/GeneratorLFDeuteronOOGap.C @@ -0,0 +1,53 @@ +int External() +{ + std::string path{"o2sim_Kine.root"}; + std::vector possiblePDGs = {1000010020, -1000010020}; + + int nPossiblePDGs = possiblePDGs.size(); + + TFile file(path.c_str(), "READ"); + if (file.IsZombie()) + { + std::cerr << "Cannot open ROOT file " << path << "\n"; + return 1; + } + + auto tree = (TTree *)file.Get("o2sim"); + if (!tree) + { + std::cerr << "Cannot find tree o2sim in file " << path << "\n"; + return 1; + } + std::vector *tracks{}; + tree->SetBranchAddress("MCTrack", &tracks); + + std::vector injectedPDGs; + + auto nEvents = tree->GetEntries(); + for (int i = 0; i < nEvents; i++) + { + auto check = tree->GetEntry(i); + for (int idxMCTrack = 0; idxMCTrack < tracks->size(); ++idxMCTrack) + { + auto track = tracks->at(idxMCTrack); + auto pdg = track.GetPdgCode(); + auto it = std::find(possiblePDGs.begin(), possiblePDGs.end(), pdg); + if (it != possiblePDGs.end() && track.isPrimary()) // found + { + injectedPDGs.push_back(pdg); + } + } + } + std::cout << "--------------------------------\n"; + std::cout << "# Events: " << nEvents << "\n"; + if(injectedPDGs.empty()){ + std::cerr << "No injected particles\n"; + return 1; // At least one of the injected particles should be generated + } + for (int i = 0; i < nPossiblePDGs; i++) + { + std::cout << "# Injected nuclei \n"; + std::cout << possiblePDGs[i] << ": " << std::count(injectedPDGs.begin(), injectedPDGs.end(), possiblePDGs[i]) << "\n"; + } + return 0; +} diff --git a/MC/config/PWGLF/ini/tests/GeneratorLFHyperNucleiOOGap.C b/MC/config/PWGLF/ini/tests/GeneratorLFHyperNucleiOOGap.C new file mode 100644 index 000000000..0f51674fb --- /dev/null +++ b/MC/config/PWGLF/ini/tests/GeneratorLFHyperNucleiOOGap.C @@ -0,0 +1,58 @@ +int External() +{ + std::string path{"o2sim_Kine.root"}; + std::vector possiblePDGs = {1000010020, -1000010020, + 1000010030, -1000010030, + 1000020030, -1000020030, + 1000020040, -1000020040, + 1010010030, -1010010030, + 1010010040, -1010010040}; + + int nPossiblePDGs = possiblePDGs.size(); + + TFile file(path.c_str(), "READ"); + if (file.IsZombie()) + { + std::cerr << "Cannot open ROOT file " << path << "\n"; + return 1; + } + + auto tree = (TTree *)file.Get("o2sim"); + if (!tree) + { + std::cerr << "Cannot find tree o2sim in file " << path << "\n"; + return 1; + } + std::vector *tracks{}; + tree->SetBranchAddress("MCTrack", &tracks); + + std::vector injectedPDGs; + + auto nEvents = tree->GetEntries(); + for (int i = 0; i < nEvents; i++) + { + auto check = tree->GetEntry(i); + for (int idxMCTrack = 0; idxMCTrack < tracks->size(); ++idxMCTrack) + { + auto track = tracks->at(idxMCTrack); + auto pdg = track.GetPdgCode(); + auto it = std::find(possiblePDGs.begin(), possiblePDGs.end(), pdg); + if (it != possiblePDGs.end() && track.isPrimary()) // found + { + injectedPDGs.push_back(pdg); + } + } + } + std::cout << "--------------------------------\n"; + std::cout << "# Events: " << nEvents << "\n"; + if(injectedPDGs.empty()){ + std::cerr << "No injected particles\n"; + return 1; // At least one of the injected particles should be generated + } + for (int i = 0; i < nPossiblePDGs; i++) + { + std::cout << "# Injected nuclei \n"; + std::cout << possiblePDGs[i] << ": " << std::count(injectedPDGs.begin(), injectedPDGs.end(), possiblePDGs[i]) << "\n"; + } + return 0; +} diff --git a/MC/config/PWGLF/ini/tests/GeneratorLFHyperNucleiPbPbGapWithFlow.C b/MC/config/PWGLF/ini/tests/GeneratorLFHyperNucleiPbPbGapWithFlow.C new file mode 100644 index 000000000..0f51674fb --- /dev/null +++ b/MC/config/PWGLF/ini/tests/GeneratorLFHyperNucleiPbPbGapWithFlow.C @@ -0,0 +1,58 @@ +int External() +{ + std::string path{"o2sim_Kine.root"}; + std::vector possiblePDGs = {1000010020, -1000010020, + 1000010030, -1000010030, + 1000020030, -1000020030, + 1000020040, -1000020040, + 1010010030, -1010010030, + 1010010040, -1010010040}; + + int nPossiblePDGs = possiblePDGs.size(); + + TFile file(path.c_str(), "READ"); + if (file.IsZombie()) + { + std::cerr << "Cannot open ROOT file " << path << "\n"; + return 1; + } + + auto tree = (TTree *)file.Get("o2sim"); + if (!tree) + { + std::cerr << "Cannot find tree o2sim in file " << path << "\n"; + return 1; + } + std::vector *tracks{}; + tree->SetBranchAddress("MCTrack", &tracks); + + std::vector injectedPDGs; + + auto nEvents = tree->GetEntries(); + for (int i = 0; i < nEvents; i++) + { + auto check = tree->GetEntry(i); + for (int idxMCTrack = 0; idxMCTrack < tracks->size(); ++idxMCTrack) + { + auto track = tracks->at(idxMCTrack); + auto pdg = track.GetPdgCode(); + auto it = std::find(possiblePDGs.begin(), possiblePDGs.end(), pdg); + if (it != possiblePDGs.end() && track.isPrimary()) // found + { + injectedPDGs.push_back(pdg); + } + } + } + std::cout << "--------------------------------\n"; + std::cout << "# Events: " << nEvents << "\n"; + if(injectedPDGs.empty()){ + std::cerr << "No injected particles\n"; + return 1; // At least one of the injected particles should be generated + } + for (int i = 0; i < nPossiblePDGs; i++) + { + std::cout << "# Injected nuclei \n"; + std::cout << possiblePDGs[i] << ": " << std::count(injectedPDGs.begin(), injectedPDGs.end(), possiblePDGs[i]) << "\n"; + } + return 0; +} diff --git a/MC/config/PWGLF/ini/tests/GeneratorLFNucleiPbPbInHMPIDAcceptance.C b/MC/config/PWGLF/ini/tests/GeneratorLFNucleiPbPbInHMPIDAcceptance.C new file mode 100644 index 000000000..6d270f811 --- /dev/null +++ b/MC/config/PWGLF/ini/tests/GeneratorLFNucleiPbPbInHMPIDAcceptance.C @@ -0,0 +1,53 @@ +int External() +{ + std::string path{"o2sim_Kine.root"}; + std::vector possiblePDGs = {1000010020, -1000010020}; + + int nPossiblePDGs = possiblePDGs.size(); + + TFile file(path.c_str(), "READ"); + if (file.IsZombie()) + { + std::cerr << "Cannot open ROOT file " << path << "\n"; + return 1; + } + + auto tree = (TTree *)file.Get("o2sim"); + if (!tree) + { + std::cerr << "Cannot find tree o2sim in file " << path << "\n"; + return 1; + } + std::vector *tracks{}; + tree->SetBranchAddress("MCTrack", &tracks); + + std::vector injectedPDGs; + + auto nEvents = tree->GetEntries(); + for (int i = 0; i < nEvents; i++) + { + auto check = tree->GetEntry(i); + for (int idxMCTrack = 0; idxMCTrack < tracks->size(); ++idxMCTrack) + { + auto track = tracks->at(idxMCTrack); + auto pdg = track.GetPdgCode(); + auto it = std::find(possiblePDGs.begin(), possiblePDGs.end(), pdg); + if (it != possiblePDGs.end() && track.isPrimary()) // found + { + injectedPDGs.push_back(pdg); + } + } + } + std::cout << "--------------------------------\n"; + std::cout << "# Events: " << nEvents << "\n"; + if(injectedPDGs.empty()){ + std::cerr << "No injected particles\n"; + return 1; // At least one of the injected particles should be generated + } + for (int i = 0; i < nPossiblePDGs; i++) + { + std::cout << "# Injected nuclei \n"; + std::cout << possiblePDGs[i] << ": " << std::count(injectedPDGs.begin(), injectedPDGs.end(), possiblePDGs[i]) << "\n"; + } + return 0; +} diff --git a/MC/config/PWGLF/ini/tests/GeneratorLFStrangenessInJetsTriggered_gap4.C b/MC/config/PWGLF/ini/tests/GeneratorLFStrangenessInJetsTriggered_gap4.C new file mode 100644 index 000000000..50b579161 --- /dev/null +++ b/MC/config/PWGLF/ini/tests/GeneratorLFStrangenessInJetsTriggered_gap4.C @@ -0,0 +1,58 @@ +int External() +{ + std::string path{"o2sim_Kine.root"}; + int numberOfInjectedSignalsPerEvent{1}; + std::vector injectedPDGs = { + 3334, + -3334, + 3312, + -3312}; + + auto nInjection = injectedPDGs.size(); + + TFile file(path.c_str(), "READ"); + if (file.IsZombie()) { + std::cerr << "Cannot open ROOT file " << path << "\n"; + return 1; + } + + auto tree = (TTree*)file.Get("o2sim"); + if (!tree) { + std::cerr << "Cannot find tree o2sim in file " << path << "\n"; + return 1; + } + std::vector* tracks{}; + tree->SetBranchAddress("MCTrack", &tracks); + + std::vector nSignal; + for (int i = 0; i < nInjection; i++) { + nSignal.push_back(0); + } + + auto nEvents = tree->GetEntries(); + for (int i = 0; i < nEvents; i++) { + auto check = tree->GetEntry(i); + for (int idxMCTrack = 0; idxMCTrack < tracks->size(); ++idxMCTrack) { + auto track = tracks->at(idxMCTrack); + auto pdg = track.GetPdgCode(); + auto it = std::find(injectedPDGs.begin(), injectedPDGs.end(), pdg); + int index = std::distance(injectedPDGs.begin(), it); // index of injected PDG + if (it != injectedPDGs.end()) // found + { + // count signal PDG + nSignal[index]++; + } + } + } + std::cout << "--------------------------------\n"; + std::cout << "# Events: " << nEvents << "\n"; + for (int i = 0; i < nInjection; i++) { + std::cout << "# Injected nuclei \n"; + std::cout << injectedPDGs[i] << ": " << nSignal[i] << "\n"; + if (nSignal[i] == 0) { + std::cerr << "No generated: " << injectedPDGs[i] << "\n"; + return 1; // At least one of the injected particles should be generated + } + } + return 0; +} diff --git a/MC/config/PWGLF/ini/tests/GeneratorLFStrangenessTriggered_5360gev.C b/MC/config/PWGLF/ini/tests/GeneratorLFStrangenessTriggered_5360gev.C new file mode 120000 index 000000000..363dcd11d --- /dev/null +++ b/MC/config/PWGLF/ini/tests/GeneratorLFStrangenessTriggered_5360gev.C @@ -0,0 +1 @@ +GeneratorLFStrangenessTriggered.C \ No newline at end of file diff --git a/MC/config/PWGLF/ini/tests/GeneratorLF_Coalescence_pp536TeV.C b/MC/config/PWGLF/ini/tests/GeneratorLF_Coalescence_pp536TeV.C new file mode 100644 index 000000000..ab7eeb695 --- /dev/null +++ b/MC/config/PWGLF/ini/tests/GeneratorLF_Coalescence_pp536TeV.C @@ -0,0 +1,28 @@ +int External() +{ + std::string path{"o2sim_Kine.root"}; + + TFile file(path.c_str(), "READ"); + if (file.IsZombie()) + { + std::cerr << "Cannot open ROOT file " << path << "\n"; + return 1; + } + + auto tree = (TTree *)file.Get("o2sim"); + if (!tree) + { + std::cerr << "Cannot find tree o2sim in file " << path << "\n"; + return 1; + } + std::vector *tracks{}; + tree->SetBranchAddress("MCTrack", &tracks); + + auto nEvents = tree->GetEntries(); + if (nEvents < 1) + { + std::cerr << "No events actually generated: not OK!"; + return 1; + } + return 0; +} diff --git a/MC/config/PWGLF/ini/tests/GeneratorLF_Resonances_pp1360_trigger.C b/MC/config/PWGLF/ini/tests/GeneratorLF_Lambda1520_pp.C similarity index 74% rename from MC/config/PWGLF/ini/tests/GeneratorLF_Resonances_pp1360_trigger.C rename to MC/config/PWGLF/ini/tests/GeneratorLF_Lambda1520_pp.C index b4d5c81f2..6b02def64 100644 --- a/MC/config/PWGLF/ini/tests/GeneratorLF_Resonances_pp1360_trigger.C +++ b/MC/config/PWGLF/ini/tests/GeneratorLF_Lambda1520_pp.C @@ -6,56 +6,12 @@ int External() int numberOfEventsProcessed{0}; int numberOfEventsProcessedWithoutInjection{0}; std::vector injectedPDGs = { - 323, // K*+- - -323, // K*bar+- - 9010221, // f_0(980) - 113, // rho(770)0 - 213, // rho(770)+ - -213, // rho(770)bar- - 3224, // Sigma(1385)+ - -3224, // Sigma(1385)bar- - 3114, // Sigma(1385)- - -3114, // Sigma(1385)bar+ - 3124, // Lambda(1520)0 - -3124, // Lambda(1520)0bar - 3324, // Xi(1530)0 - -3324, // Xi(1530)0bar - 10323, // K1(1270)+ - -10323, // K1(1270)-bar - 2224, // Delta(1232)+ - -2224, // Delta(1232)bar- - 2114, // Delta(1232)0 - -2114, // Delta(1232)0bar - 123314, // Xi(1820)- - -123314, // Xi(1820)+ - 123324, // Xi(1820)0 - -123324 // Xi(1820)0bar + 102134, // Lambda(1520)0 + -102134, // Lambda(1520)0bar }; std::vector> decayDaughters = { - {311, 211}, // K*+- - {-311, -211}, // K*bar+- - {211, -211}, // f_0(980) - {211, -211}, // rho(770)0 - {211, 111}, // rho(770)+ - {-211, 111}, // rho(770)bar- - {3122, 211}, // Sigma(1385)+ - {-3122, -211}, // Sigma(1385)bar- - {3122, -211}, // Sigma(1385)- - {-3122, 211}, // Sigma(1385)bar+ - {2212, -321}, // Lambda(1520)0 - {-2212, 321}, // Lambda(1520)0bar - {3312, 211}, // Xi(1530)0 - {-3312, -211}, // Xi(1530)0bar - {321, 211}, // K1(1270)+ - {-321, -211}, // K1(1270)-bar - {2212, 211}, // Delta(1232)+ - {-2212, -211}, // Delta(1232)bar- - {2212, -211}, // Delta(1232)- - {-2212, 211}, // Delta(1232)bar+ - {3122, -311}, // Xi(1820)- - {3122, 311}, // Xi(1820)+ - {3122, 310}, // Xi(1820)0 - {-3122, 310} // Xi(1820)0bar + {2212, -321}, // Lambda(1520)0 + {-2212, 321}, // Lambda(1520)0bar }; auto nInjection = injectedPDGs.size(); @@ -179,4 +135,4 @@ int External() return 0; } -void GeneratorLF_Resonances_pp1360_trigger() { External(); } +void GeneratorLF_Resonances_pp1360_injection() { External(); } diff --git a/MC/config/PWGLF/ini/tests/GeneratorLF_Resonances_PbPb5360_trigger.C b/MC/config/PWGLF/ini/tests/GeneratorLF_ResonancesBaryonic_NeNe_injection.C similarity index 69% rename from MC/config/PWGLF/ini/tests/GeneratorLF_Resonances_PbPb5360_trigger.C rename to MC/config/PWGLF/ini/tests/GeneratorLF_ResonancesBaryonic_NeNe_injection.C index b6057017a..63a9b6922 100644 --- a/MC/config/PWGLF/ini/tests/GeneratorLF_Resonances_PbPb5360_trigger.C +++ b/MC/config/PWGLF/ini/tests/GeneratorLF_ResonancesBaryonic_NeNe_injection.C @@ -6,56 +6,16 @@ int External() int numberOfEventsProcessed{0}; int numberOfEventsProcessedWithoutInjection{0}; std::vector injectedPDGs = { - 323, // K*+- - -323, // K*bar+- - 9010221, // f_0(980) - 113, // rho(770)0 - 213, // rho(770)+ - -213, // rho(770)bar- - 3224, // Sigma(1385)+ - -3224, // Sigma(1385)bar- - 3114, // Sigma(1385)- - -3114, // Sigma(1385)bar+ - 3124, // Lambda(1520)0 - -3124, // Lambda(1520)0bar - 3324, // Xi(1530)0 - -3324, // Xi(1530)0bar - 10323, // K1(1270)+ - -10323, // K1(1270)-bar - 2224, // Delta(1232)+ - -2224, // Delta(1232)bar- - 2114, // Delta(1232)0 - -2114, // Delta(1232)0bar - 123314, // Xi(1820)- - -123314, // Xi(1820)+ - 123324, // Xi(1820)0 - -123324 // Xi(1820)0bar + 102134, // Lambda(1520)0 + -102134, // Lambda(1520)0bar + 3324, // Xi(1530)0 + -3324 // Xi(1530)0bar }; std::vector> decayDaughters = { - {311, 211}, // K*+- - {-311, -211}, // K*bar+- - {211, -211}, // f_0(980) - {211, -211}, // rho(770)0 - {211, 111}, // rho(770)+ - {-211, 111}, // rho(770)bar- - {3122, 211}, // Sigma(1385)+ - {-3122, -211}, // Sigma(1385)bar- - {3122, -211}, // Sigma(1385)- - {-3122, 211}, // Sigma(1385)bar+ - {2212, -321}, // Lambda(1520)0 + {2212, -321}, // Lambda(1520)0 {-2212, 321}, // Lambda(1520)0bar - {3312, 211}, // Xi(1530)0 - {-3312, -211}, // Xi(1530)0bar - {321, 211}, // K1(1270)+ - {-321, -211}, // K1(1270)-bar - {2212, 211}, // Delta(1232)+ - {-2212, -211}, // Delta(1232)bar- - {2212, -211}, // Delta(1232)- - {-2212, 211}, // Delta(1232)bar+ - {3122, -311}, // Xi(1820)- - {3122, 311}, // Xi(1820)+ - {3122, 310}, // Xi(1820)0 - {-3122, 310} // Xi(1820)0bar + {3312, 211}, // Xi(1530)0 + {-3312, -211} // Xi(1530)0bar }; auto nInjection = injectedPDGs.size(); @@ -110,7 +70,7 @@ int External() { // count signal PDG nSignal[index]++; - if(track.getFirstDaughterTrackId() < 0) + if (track.getFirstDaughterTrackId() < 0) { nNotDecayed[index]++; continue; @@ -118,20 +78,21 @@ int External() for (int j{track.getFirstDaughterTrackId()}; j <= track.getLastDaughterTrackId(); ++j) { auto pdgDau = tracks->at(j).GetPdgCode(); - bool foundDau= false; + bool foundDau = false; // count decay PDGs for (int idxDaughter = 0; idxDaughter < decayDaughters[index].size(); ++idxDaughter) { if (pdgDau == decayDaughters[index][idxDaughter]) { nDecays[index][idxDaughter]++; - foundDau= true; + foundDau = true; hasInjection = true; break; } } - if (!foundDau) { - std::cerr << "Decay daughter not found: " << pdg << " -> " << pdgDau << "\n"; + if (!foundDau) + { + std::cerr << "Decay daughter not found: " << pdg << " -> " << pdgDau << "\n"; } } } @@ -147,7 +108,8 @@ int External() { std::cout << "# Mother \n"; std::cout << injectedPDGs[i] << " generated: " << nSignal[i] << ", " << nNotDecayed[i] << " did not decay\n"; - if (nSignal[i] == 0){ + if (nSignal[i] == 0) + { std::cerr << "No generated: " << injectedPDGs[i] << "\n"; // return 1; // At least one of the injected particles should be generated } @@ -167,14 +129,14 @@ int External() std::cout << "Number of events processed without injection: " << numberOfEventsProcessedWithoutInjection << "\n"; // injected event + numberOfGapEvents*gap events + injected event + numberOfGapEvents*gap events + ... // total fraction of the gap event: numberOfEventsProcessedWithoutInjection/numberOfEventsProcessed - float ratioOfNormalEvents = numberOfEventsProcessedWithoutInjection/numberOfEventsProcessed; + float ratioOfNormalEvents = numberOfEventsProcessedWithoutInjection / numberOfEventsProcessed; if (ratioOfNormalEvents > 0.75) { std::cout << "The number of injected event is loo low!!" << std::endl; return 1; } - + return 0; } -void GeneratorLF_Resonances_PbPb5360_trigger() { External(); } +void GeneratorLF_ResonancesBaryonic_NeNe_injection() { External(); } diff --git a/MC/config/PWGLF/ini/tests/GeneratorLF_ResonancesBaryonic_OO_injection.C b/MC/config/PWGLF/ini/tests/GeneratorLF_ResonancesBaryonic_OO_injection.C new file mode 100644 index 000000000..a47ce77ea --- /dev/null +++ b/MC/config/PWGLF/ini/tests/GeneratorLF_ResonancesBaryonic_OO_injection.C @@ -0,0 +1,142 @@ +int External() +{ + std::string path{"o2sim_Kine.root"}; + int numberOfInjectedSignalsPerEvent{1}; + int numberOfGapEvents{4}; + int numberOfEventsProcessed{0}; + int numberOfEventsProcessedWithoutInjection{0}; + std::vector injectedPDGs = { + 102134, // Lambda(1520)0 + -102134, // Lambda(1520)0bar + 3324, // Xi(1530)0 + -3324 // Xi(1530)0bar + }; + std::vector> decayDaughters = { + {2212, -321}, // Lambda(1520)0 + {-2212, 321}, // Lambda(1520)0bar + {3312, 211}, // Xi(1530)0 + {-3312, -211} // Xi(1530)0bar + }; + + auto nInjection = injectedPDGs.size(); + + TFile file(path.c_str(), "READ"); + if (file.IsZombie()) + { + std::cerr << "Cannot open ROOT file " << path << "\n"; + return 1; + } + + auto tree = (TTree *)file.Get("o2sim"); + if (!tree) + { + std::cerr << "Cannot find tree o2sim in file " << path << "\n"; + return 1; + } + std::vector *tracks{}; + tree->SetBranchAddress("MCTrack", &tracks); + + std::vector nSignal; + for (int i = 0; i < nInjection; i++) + { + nSignal.push_back(0); + } + std::vector> nDecays; + std::vector nNotDecayed; + for (int i = 0; i < nInjection; i++) + { + std::vector nDecay; + for (int j = 0; j < decayDaughters[i].size(); j++) + { + nDecay.push_back(0); + } + nDecays.push_back(nDecay); + nNotDecayed.push_back(0); + } + auto nEvents = tree->GetEntries(); + bool hasInjection = false; + for (int i = 0; i < nEvents; i++) + { + hasInjection = false; + numberOfEventsProcessed++; + auto check = tree->GetEntry(i); + for (int idxMCTrack = 0; idxMCTrack < tracks->size(); ++idxMCTrack) + { + auto track = tracks->at(idxMCTrack); + auto pdg = track.GetPdgCode(); + auto it = std::find(injectedPDGs.begin(), injectedPDGs.end(), pdg); + int index = std::distance(injectedPDGs.begin(), it); // index of injected PDG + if (it != injectedPDGs.end()) // found + { + // count signal PDG + nSignal[index]++; + if (track.getFirstDaughterTrackId() < 0) + { + nNotDecayed[index]++; + continue; + } + for (int j{track.getFirstDaughterTrackId()}; j <= track.getLastDaughterTrackId(); ++j) + { + auto pdgDau = tracks->at(j).GetPdgCode(); + bool foundDau = false; + // count decay PDGs + for (int idxDaughter = 0; idxDaughter < decayDaughters[index].size(); ++idxDaughter) + { + if (pdgDau == decayDaughters[index][idxDaughter]) + { + nDecays[index][idxDaughter]++; + foundDau = true; + hasInjection = true; + break; + } + } + if (!foundDau) + { + std::cerr << "Decay daughter not found: " << pdg << " -> " << pdgDau << "\n"; + } + } + } + } + if (!hasInjection) + { + numberOfEventsProcessedWithoutInjection++; + } + } + std::cout << "--------------------------------\n"; + std::cout << "# Events: " << nEvents << "\n"; + for (int i = 0; i < nInjection; i++) + { + std::cout << "# Mother \n"; + std::cout << injectedPDGs[i] << " generated: " << nSignal[i] << ", " << nNotDecayed[i] << " did not decay\n"; + if (nSignal[i] == 0) + { + std::cerr << "No generated: " << injectedPDGs[i] << "\n"; + // return 1; // At least one of the injected particles should be generated + } + for (int j = 0; j < decayDaughters[i].size(); j++) + { + std::cout << "# Daughter " << decayDaughters[i][j] << ": " << nDecays[i][j] << "\n"; + } + // if (nSignal[i] != nEvents * numberOfInjectedSignalsPerEvent) + // { + // std::cerr << "Number of generated: " << injectedPDGs[i] << ", lower than expected\n"; + // // return 1; // Don't need to return 1, since the number of generated particles is not the same for each event + // } + } + std::cout << "--------------------------------\n"; + std::cout << "Number of events processed: " << numberOfEventsProcessed << "\n"; + std::cout << "Number of input for the gap events: " << numberOfGapEvents << "\n"; + std::cout << "Number of events processed without injection: " << numberOfEventsProcessedWithoutInjection << "\n"; + // injected event + numberOfGapEvents*gap events + injected event + numberOfGapEvents*gap events + ... + // total fraction of the gap event: numberOfEventsProcessedWithoutInjection/numberOfEventsProcessed + float ratioOfNormalEvents = numberOfEventsProcessedWithoutInjection / numberOfEventsProcessed; + if (ratioOfNormalEvents > 0.75) + { + std::cout << "The number of injected event is loo low!!" << std::endl; + return 1; + } + + return 0; +} + +void GeneratorLF_ResonancesBaryonic_OO_injection() { External(); } diff --git a/MC/config/PWGLF/ini/tests/GeneratorLF_ResonancesBaryonic_pO_injection.C b/MC/config/PWGLF/ini/tests/GeneratorLF_ResonancesBaryonic_pO_injection.C new file mode 100644 index 000000000..38d05d522 --- /dev/null +++ b/MC/config/PWGLF/ini/tests/GeneratorLF_ResonancesBaryonic_pO_injection.C @@ -0,0 +1,142 @@ +int External() +{ + std::string path{"o2sim_Kine.root"}; + int numberOfInjectedSignalsPerEvent{1}; + int numberOfGapEvents{4}; + int numberOfEventsProcessed{0}; + int numberOfEventsProcessedWithoutInjection{0}; + std::vector injectedPDGs = { + 102134, // Lambda(1520)0 + -102134, // Lambda(1520)0bar + 3324, // Xi(1530)0 + -3324 // Xi(1530)0bar + }; + std::vector> decayDaughters = { + {2212, -321}, // Lambda(1520)0 + {-2212, 321}, // Lambda(1520)0bar + {3312, 211}, // Xi(1530)0 + {-3312, -211} // Xi(1530)0bar + }; + + auto nInjection = injectedPDGs.size(); + + TFile file(path.c_str(), "READ"); + if (file.IsZombie()) + { + std::cerr << "Cannot open ROOT file " << path << "\n"; + return 1; + } + + auto tree = (TTree *)file.Get("o2sim"); + if (!tree) + { + std::cerr << "Cannot find tree o2sim in file " << path << "\n"; + return 1; + } + std::vector *tracks{}; + tree->SetBranchAddress("MCTrack", &tracks); + + std::vector nSignal; + for (int i = 0; i < nInjection; i++) + { + nSignal.push_back(0); + } + std::vector> nDecays; + std::vector nNotDecayed; + for (int i = 0; i < nInjection; i++) + { + std::vector nDecay; + for (int j = 0; j < decayDaughters[i].size(); j++) + { + nDecay.push_back(0); + } + nDecays.push_back(nDecay); + nNotDecayed.push_back(0); + } + auto nEvents = tree->GetEntries(); + bool hasInjection = false; + for (int i = 0; i < nEvents; i++) + { + hasInjection = false; + numberOfEventsProcessed++; + auto check = tree->GetEntry(i); + for (int idxMCTrack = 0; idxMCTrack < tracks->size(); ++idxMCTrack) + { + auto track = tracks->at(idxMCTrack); + auto pdg = track.GetPdgCode(); + auto it = std::find(injectedPDGs.begin(), injectedPDGs.end(), pdg); + int index = std::distance(injectedPDGs.begin(), it); // index of injected PDG + if (it != injectedPDGs.end()) // found + { + // count signal PDG + nSignal[index]++; + if (track.getFirstDaughterTrackId() < 0) + { + nNotDecayed[index]++; + continue; + } + for (int j{track.getFirstDaughterTrackId()}; j <= track.getLastDaughterTrackId(); ++j) + { + auto pdgDau = tracks->at(j).GetPdgCode(); + bool foundDau = false; + // count decay PDGs + for (int idxDaughter = 0; idxDaughter < decayDaughters[index].size(); ++idxDaughter) + { + if (pdgDau == decayDaughters[index][idxDaughter]) + { + nDecays[index][idxDaughter]++; + foundDau = true; + hasInjection = true; + break; + } + } + if (!foundDau) + { + std::cerr << "Decay daughter not found: " << pdg << " -> " << pdgDau << "\n"; + } + } + } + } + if (!hasInjection) + { + numberOfEventsProcessedWithoutInjection++; + } + } + std::cout << "--------------------------------\n"; + std::cout << "# Events: " << nEvents << "\n"; + for (int i = 0; i < nInjection; i++) + { + std::cout << "# Mother \n"; + std::cout << injectedPDGs[i] << " generated: " << nSignal[i] << ", " << nNotDecayed[i] << " did not decay\n"; + if (nSignal[i] == 0) + { + std::cerr << "No generated: " << injectedPDGs[i] << "\n"; + // return 1; // At least one of the injected particles should be generated + } + for (int j = 0; j < decayDaughters[i].size(); j++) + { + std::cout << "# Daughter " << decayDaughters[i][j] << ": " << nDecays[i][j] << "\n"; + } + // if (nSignal[i] != nEvents * numberOfInjectedSignalsPerEvent) + // { + // std::cerr << "Number of generated: " << injectedPDGs[i] << ", lower than expected\n"; + // // return 1; // Don't need to return 1, since the number of generated particles is not the same for each event + // } + } + std::cout << "--------------------------------\n"; + std::cout << "Number of events processed: " << numberOfEventsProcessed << "\n"; + std::cout << "Number of input for the gap events: " << numberOfGapEvents << "\n"; + std::cout << "Number of events processed without injection: " << numberOfEventsProcessedWithoutInjection << "\n"; + // injected event + numberOfGapEvents*gap events + injected event + numberOfGapEvents*gap events + ... + // total fraction of the gap event: numberOfEventsProcessedWithoutInjection/numberOfEventsProcessed + float ratioOfNormalEvents = numberOfEventsProcessedWithoutInjection / numberOfEventsProcessed; + if (ratioOfNormalEvents > 0.75) + { + std::cout << "The number of injected event is loo low!!" << std::endl; + return 1; + } + + return 0; +} + +void GeneratorLF_ResonancesBaryonic_pO_injection() { External(); } diff --git a/MC/config/PWGLF/ini/tests/GeneratorLF_ResonancesBaryonic_pp1360_injection.C b/MC/config/PWGLF/ini/tests/GeneratorLF_ResonancesBaryonic_pp1360_injection.C new file mode 100644 index 000000000..27069c08f --- /dev/null +++ b/MC/config/PWGLF/ini/tests/GeneratorLF_ResonancesBaryonic_pp1360_injection.C @@ -0,0 +1,142 @@ +int External() +{ + std::string path{"o2sim_Kine.root"}; + int numberOfInjectedSignalsPerEvent{1}; + int numberOfGapEvents{4}; + int numberOfEventsProcessed{0}; + int numberOfEventsProcessedWithoutInjection{0}; + std::vector injectedPDGs = { + 102134, // Lambda(1520)0 + -102134, // Lambda(1520)0bar + 3324, // Xi(1530)0 + -3324 // Xi(1530)0bar + }; + std::vector> decayDaughters = { + {2212, -321}, // Lambda(1520)0 + {-2212, 321}, // Lambda(1520)0bar + {3312, 211}, // Xi(1530)0 + {-3312, -211} // Xi(1530)0bar + }; + + auto nInjection = injectedPDGs.size(); + + TFile file(path.c_str(), "READ"); + if (file.IsZombie()) + { + std::cerr << "Cannot open ROOT file " << path << "\n"; + return 1; + } + + auto tree = (TTree *)file.Get("o2sim"); + if (!tree) + { + std::cerr << "Cannot find tree o2sim in file " << path << "\n"; + return 1; + } + std::vector *tracks{}; + tree->SetBranchAddress("MCTrack", &tracks); + + std::vector nSignal; + for (int i = 0; i < nInjection; i++) + { + nSignal.push_back(0); + } + std::vector> nDecays; + std::vector nNotDecayed; + for (int i = 0; i < nInjection; i++) + { + std::vector nDecay; + for (int j = 0; j < decayDaughters[i].size(); j++) + { + nDecay.push_back(0); + } + nDecays.push_back(nDecay); + nNotDecayed.push_back(0); + } + auto nEvents = tree->GetEntries(); + bool hasInjection = false; + for (int i = 0; i < nEvents; i++) + { + hasInjection = false; + numberOfEventsProcessed++; + auto check = tree->GetEntry(i); + for (int idxMCTrack = 0; idxMCTrack < tracks->size(); ++idxMCTrack) + { + auto track = tracks->at(idxMCTrack); + auto pdg = track.GetPdgCode(); + auto it = std::find(injectedPDGs.begin(), injectedPDGs.end(), pdg); + int index = std::distance(injectedPDGs.begin(), it); // index of injected PDG + if (it != injectedPDGs.end()) // found + { + // count signal PDG + nSignal[index]++; + if (track.getFirstDaughterTrackId() < 0) + { + nNotDecayed[index]++; + continue; + } + for (int j{track.getFirstDaughterTrackId()}; j <= track.getLastDaughterTrackId(); ++j) + { + auto pdgDau = tracks->at(j).GetPdgCode(); + bool foundDau = false; + // count decay PDGs + for (int idxDaughter = 0; idxDaughter < decayDaughters[index].size(); ++idxDaughter) + { + if (pdgDau == decayDaughters[index][idxDaughter]) + { + nDecays[index][idxDaughter]++; + foundDau = true; + hasInjection = true; + break; + } + } + if (!foundDau) + { + std::cerr << "Decay daughter not found: " << pdg << " -> " << pdgDau << "\n"; + } + } + } + } + if (!hasInjection) + { + numberOfEventsProcessedWithoutInjection++; + } + } + std::cout << "--------------------------------\n"; + std::cout << "# Events: " << nEvents << "\n"; + for (int i = 0; i < nInjection; i++) + { + std::cout << "# Mother \n"; + std::cout << injectedPDGs[i] << " generated: " << nSignal[i] << ", " << nNotDecayed[i] << " did not decay\n"; + if (nSignal[i] == 0) + { + std::cerr << "No generated: " << injectedPDGs[i] << "\n"; + // return 1; // At least one of the injected particles should be generated + } + for (int j = 0; j < decayDaughters[i].size(); j++) + { + std::cout << "# Daughter " << decayDaughters[i][j] << ": " << nDecays[i][j] << "\n"; + } + // if (nSignal[i] != nEvents * numberOfInjectedSignalsPerEvent) + // { + // std::cerr << "Number of generated: " << injectedPDGs[i] << ", lower than expected\n"; + // // return 1; // Don't need to return 1, since the number of generated particles is not the same for each event + // } + } + std::cout << "--------------------------------\n"; + std::cout << "Number of events processed: " << numberOfEventsProcessed << "\n"; + std::cout << "Number of input for the gap events: " << numberOfGapEvents << "\n"; + std::cout << "Number of events processed without injection: " << numberOfEventsProcessedWithoutInjection << "\n"; + // injected event + numberOfGapEvents*gap events + injected event + numberOfGapEvents*gap events + ... + // total fraction of the gap event: numberOfEventsProcessedWithoutInjection/numberOfEventsProcessed + float ratioOfNormalEvents = numberOfEventsProcessedWithoutInjection / numberOfEventsProcessed; + if (ratioOfNormalEvents > 0.75) + { + std::cout << "The number of injected event is loo low!!" << std::endl; + return 1; + } + + return 0; +} + +void GeneratorLF_Resonances_pp1360_injection() { External(); } diff --git a/MC/config/PWGLF/ini/tests/GeneratorLF_ResonancesBaryonic_pp1360_rapidityinjection.C b/MC/config/PWGLF/ini/tests/GeneratorLF_ResonancesBaryonic_pp1360_rapidityinjection.C new file mode 100644 index 000000000..27069c08f --- /dev/null +++ b/MC/config/PWGLF/ini/tests/GeneratorLF_ResonancesBaryonic_pp1360_rapidityinjection.C @@ -0,0 +1,142 @@ +int External() +{ + std::string path{"o2sim_Kine.root"}; + int numberOfInjectedSignalsPerEvent{1}; + int numberOfGapEvents{4}; + int numberOfEventsProcessed{0}; + int numberOfEventsProcessedWithoutInjection{0}; + std::vector injectedPDGs = { + 102134, // Lambda(1520)0 + -102134, // Lambda(1520)0bar + 3324, // Xi(1530)0 + -3324 // Xi(1530)0bar + }; + std::vector> decayDaughters = { + {2212, -321}, // Lambda(1520)0 + {-2212, 321}, // Lambda(1520)0bar + {3312, 211}, // Xi(1530)0 + {-3312, -211} // Xi(1530)0bar + }; + + auto nInjection = injectedPDGs.size(); + + TFile file(path.c_str(), "READ"); + if (file.IsZombie()) + { + std::cerr << "Cannot open ROOT file " << path << "\n"; + return 1; + } + + auto tree = (TTree *)file.Get("o2sim"); + if (!tree) + { + std::cerr << "Cannot find tree o2sim in file " << path << "\n"; + return 1; + } + std::vector *tracks{}; + tree->SetBranchAddress("MCTrack", &tracks); + + std::vector nSignal; + for (int i = 0; i < nInjection; i++) + { + nSignal.push_back(0); + } + std::vector> nDecays; + std::vector nNotDecayed; + for (int i = 0; i < nInjection; i++) + { + std::vector nDecay; + for (int j = 0; j < decayDaughters[i].size(); j++) + { + nDecay.push_back(0); + } + nDecays.push_back(nDecay); + nNotDecayed.push_back(0); + } + auto nEvents = tree->GetEntries(); + bool hasInjection = false; + for (int i = 0; i < nEvents; i++) + { + hasInjection = false; + numberOfEventsProcessed++; + auto check = tree->GetEntry(i); + for (int idxMCTrack = 0; idxMCTrack < tracks->size(); ++idxMCTrack) + { + auto track = tracks->at(idxMCTrack); + auto pdg = track.GetPdgCode(); + auto it = std::find(injectedPDGs.begin(), injectedPDGs.end(), pdg); + int index = std::distance(injectedPDGs.begin(), it); // index of injected PDG + if (it != injectedPDGs.end()) // found + { + // count signal PDG + nSignal[index]++; + if (track.getFirstDaughterTrackId() < 0) + { + nNotDecayed[index]++; + continue; + } + for (int j{track.getFirstDaughterTrackId()}; j <= track.getLastDaughterTrackId(); ++j) + { + auto pdgDau = tracks->at(j).GetPdgCode(); + bool foundDau = false; + // count decay PDGs + for (int idxDaughter = 0; idxDaughter < decayDaughters[index].size(); ++idxDaughter) + { + if (pdgDau == decayDaughters[index][idxDaughter]) + { + nDecays[index][idxDaughter]++; + foundDau = true; + hasInjection = true; + break; + } + } + if (!foundDau) + { + std::cerr << "Decay daughter not found: " << pdg << " -> " << pdgDau << "\n"; + } + } + } + } + if (!hasInjection) + { + numberOfEventsProcessedWithoutInjection++; + } + } + std::cout << "--------------------------------\n"; + std::cout << "# Events: " << nEvents << "\n"; + for (int i = 0; i < nInjection; i++) + { + std::cout << "# Mother \n"; + std::cout << injectedPDGs[i] << " generated: " << nSignal[i] << ", " << nNotDecayed[i] << " did not decay\n"; + if (nSignal[i] == 0) + { + std::cerr << "No generated: " << injectedPDGs[i] << "\n"; + // return 1; // At least one of the injected particles should be generated + } + for (int j = 0; j < decayDaughters[i].size(); j++) + { + std::cout << "# Daughter " << decayDaughters[i][j] << ": " << nDecays[i][j] << "\n"; + } + // if (nSignal[i] != nEvents * numberOfInjectedSignalsPerEvent) + // { + // std::cerr << "Number of generated: " << injectedPDGs[i] << ", lower than expected\n"; + // // return 1; // Don't need to return 1, since the number of generated particles is not the same for each event + // } + } + std::cout << "--------------------------------\n"; + std::cout << "Number of events processed: " << numberOfEventsProcessed << "\n"; + std::cout << "Number of input for the gap events: " << numberOfGapEvents << "\n"; + std::cout << "Number of events processed without injection: " << numberOfEventsProcessedWithoutInjection << "\n"; + // injected event + numberOfGapEvents*gap events + injected event + numberOfGapEvents*gap events + ... + // total fraction of the gap event: numberOfEventsProcessedWithoutInjection/numberOfEventsProcessed + float ratioOfNormalEvents = numberOfEventsProcessedWithoutInjection / numberOfEventsProcessed; + if (ratioOfNormalEvents > 0.75) + { + std::cout << "The number of injected event is loo low!!" << std::endl; + return 1; + } + + return 0; +} + +void GeneratorLF_Resonances_pp1360_injection() { External(); } diff --git a/MC/config/PWGLF/ini/tests/GeneratorLF_ResonancesBaryonic_pp5360_injection.C b/MC/config/PWGLF/ini/tests/GeneratorLF_ResonancesBaryonic_pp5360_injection.C new file mode 100644 index 000000000..f73f13c3d --- /dev/null +++ b/MC/config/PWGLF/ini/tests/GeneratorLF_ResonancesBaryonic_pp5360_injection.C @@ -0,0 +1,142 @@ +int External() +{ + std::string path{"o2sim_Kine.root"}; + int numberOfInjectedSignalsPerEvent{1}; + int numberOfGapEvents{4}; + int numberOfEventsProcessed{0}; + int numberOfEventsProcessedWithoutInjection{0}; + std::vector injectedPDGs = { + 102134, // Lambda(1520)0 + -102134, // Lambda(1520)0bar + 3324, // Xi(1530)0 + -3324 // Xi(1530)0bar + }; + std::vector> decayDaughters = { + {2212, -321}, // Lambda(1520)0 + {-2212, 321}, // Lambda(1520)0bar + {3312, 211}, // Xi(1530)0 + {-3312, -211} // Xi(1530)0bar + }; + + auto nInjection = injectedPDGs.size(); + + TFile file(path.c_str(), "READ"); + if (file.IsZombie()) + { + std::cerr << "Cannot open ROOT file " << path << "\n"; + return 1; + } + + auto tree = (TTree *)file.Get("o2sim"); + if (!tree) + { + std::cerr << "Cannot find tree o2sim in file " << path << "\n"; + return 1; + } + std::vector *tracks{}; + tree->SetBranchAddress("MCTrack", &tracks); + + std::vector nSignal; + for (int i = 0; i < nInjection; i++) + { + nSignal.push_back(0); + } + std::vector> nDecays; + std::vector nNotDecayed; + for (int i = 0; i < nInjection; i++) + { + std::vector nDecay; + for (int j = 0; j < decayDaughters[i].size(); j++) + { + nDecay.push_back(0); + } + nDecays.push_back(nDecay); + nNotDecayed.push_back(0); + } + auto nEvents = tree->GetEntries(); + bool hasInjection = false; + for (int i = 0; i < nEvents; i++) + { + hasInjection = false; + numberOfEventsProcessed++; + auto check = tree->GetEntry(i); + for (int idxMCTrack = 0; idxMCTrack < tracks->size(); ++idxMCTrack) + { + auto track = tracks->at(idxMCTrack); + auto pdg = track.GetPdgCode(); + auto it = std::find(injectedPDGs.begin(), injectedPDGs.end(), pdg); + int index = std::distance(injectedPDGs.begin(), it); // index of injected PDG + if (it != injectedPDGs.end()) // found + { + // count signal PDG + nSignal[index]++; + if (track.getFirstDaughterTrackId() < 0) + { + nNotDecayed[index]++; + continue; + } + for (int j{track.getFirstDaughterTrackId()}; j <= track.getLastDaughterTrackId(); ++j) + { + auto pdgDau = tracks->at(j).GetPdgCode(); + bool foundDau = false; + // count decay PDGs + for (int idxDaughter = 0; idxDaughter < decayDaughters[index].size(); ++idxDaughter) + { + if (pdgDau == decayDaughters[index][idxDaughter]) + { + nDecays[index][idxDaughter]++; + foundDau = true; + hasInjection = true; + break; + } + } + if (!foundDau) + { + std::cerr << "Decay daughter not found: " << pdg << " -> " << pdgDau << "\n"; + } + } + } + } + if (!hasInjection) + { + numberOfEventsProcessedWithoutInjection++; + } + } + std::cout << "--------------------------------\n"; + std::cout << "# Events: " << nEvents << "\n"; + for (int i = 0; i < nInjection; i++) + { + std::cout << "# Mother \n"; + std::cout << injectedPDGs[i] << " generated: " << nSignal[i] << ", " << nNotDecayed[i] << " did not decay\n"; + if (nSignal[i] == 0) + { + std::cerr << "No generated: " << injectedPDGs[i] << "\n"; + // return 1; // At least one of the injected particles should be generated + } + for (int j = 0; j < decayDaughters[i].size(); j++) + { + std::cout << "# Daughter " << decayDaughters[i][j] << ": " << nDecays[i][j] << "\n"; + } + // if (nSignal[i] != nEvents * numberOfInjectedSignalsPerEvent) + // { + // std::cerr << "Number of generated: " << injectedPDGs[i] << ", lower than expected\n"; + // // return 1; // Don't need to return 1, since the number of generated particles is not the same for each event + // } + } + std::cout << "--------------------------------\n"; + std::cout << "Number of events processed: " << numberOfEventsProcessed << "\n"; + std::cout << "Number of input for the gap events: " << numberOfGapEvents << "\n"; + std::cout << "Number of events processed without injection: " << numberOfEventsProcessedWithoutInjection << "\n"; + // injected event + numberOfGapEvents*gap events + injected event + numberOfGapEvents*gap events + ... + // total fraction of the gap event: numberOfEventsProcessedWithoutInjection/numberOfEventsProcessed + float ratioOfNormalEvents = numberOfEventsProcessedWithoutInjection / numberOfEventsProcessed; + if (ratioOfNormalEvents > 0.75) + { + std::cout << "The number of injected event is loo low!!" << std::endl; + return 1; + } + + return 0; +} + +void GeneratorLF_ResonancesBaryonic_pp5360_injection() { External(); } diff --git a/MC/config/PWGLF/ini/tests/GeneratorLF_Resonances_pp_exotic.C b/MC/config/PWGLF/ini/tests/GeneratorLF_Resonances_pp_exotic.C index 61d739eab..5155fbebc 100644 --- a/MC/config/PWGLF/ini/tests/GeneratorLF_Resonances_pp_exotic.C +++ b/MC/config/PWGLF/ini/tests/GeneratorLF_Resonances_pp_exotic.C @@ -6,37 +6,20 @@ int External() int numberOfEventsProcessed{0}; int numberOfEventsProcessedWithoutInjection{0}; std::vector injectedPDGs = { - 9010221, // f_0(980) + 225, // f_2(1270) + 115, // a_2(1320) 10221, // f_0(1370) 9030221, // f_0(1500) - 10331, // f_0(1710) - 20223, // f_1(1285) - 20333, // f_1(1420) 335, // f_2(1525) - 115, // a_2(1230) - 10323, // K1(1270)+ - -10323, // K1(1270)-bar - 123314, // Xi(1820)- - -123314, // Xi(1820)+ - 123324, // Xi(1820)0 - -123324 // Xi(1820)0bar + 10331 // f_0(1710) }; std::vector> decayDaughters = { - {211, -211}, // f_0(980) - {310, 310}, // f_0(1370) - {310, 310}, // f_0(1500) - {310, 310}, // f_0(1710) - {310, -321, 211}, // f_1(1285) - {310, -321, 211}, // f_1(1420) - {310, 310}, // f_2(1525) - {310, 310}, // a_2(1230) - {321, 211}, // K1(1270)+ - {-321, -211}, // K1(1270)-bar - {2212, 211}, // Delta(1232)+ - {3122, -311}, // Xi(1820)- - {3122, 311}, // Xi(1820)+ - {3122, 310}, // Xi(1820)0 - {-3122, 310} // Xi(1820)0bar + {310, 310}, // f_2(1270) + {310, 310}, // a_2(1320) + {310, 310}, // f_0(1370) + {310, 310}, // f_0(1500) + {310, 310}, // f_2(1525) + {310, 310} // f_0(1710) }; auto nInjection = injectedPDGs.size(); diff --git a/MC/config/PWGLF/ini/tests/GeneratorLF_Resonances_pp900_trigger.C b/MC/config/PWGLF/ini/tests/GeneratorLF_Resonances_pp_exoticAll.C similarity index 80% rename from MC/config/PWGLF/ini/tests/GeneratorLF_Resonances_pp900_trigger.C rename to MC/config/PWGLF/ini/tests/GeneratorLF_Resonances_pp_exoticAll.C index 701d018ad..6fe8638d7 100644 --- a/MC/config/PWGLF/ini/tests/GeneratorLF_Resonances_pp900_trigger.C +++ b/MC/config/PWGLF/ini/tests/GeneratorLF_Resonances_pp_exoticAll.C @@ -6,44 +6,41 @@ int External() int numberOfEventsProcessed{0}; int numberOfEventsProcessedWithoutInjection{0}; std::vector injectedPDGs = { - 323, // K*+- - -323, // K*bar+- 9010221, // f_0(980) - 113, // rho(770)0 - 213, // rho(770)+ - -213, // rho(770)bar- - 3224, // Sigma(1385)+ - -3224, // Sigma(1385)bar- - 3114, // Sigma(1385)- - -3114, // Sigma(1385)bar+ - 3324, // Xi(1530)0 - -3324, // Xi(1530)0bar + 225, // f_2(1270) + 115, // a_2(1320) + 10221, // f_0(1370) + 9030221, // f_0(1500) + 335, // f_2(1525) + 10331, // f_0(1710) + 20223, // f_1(1285) + 20333, // f_1(1420) + 335, // f_2(1525) 10323, // K1(1270)+ -10323, // K1(1270)-bar - 2224, // Delta(1232)+ - -2224, // Delta(1232)bar- - 2114, // Delta(1232)0 - -2114 // Delta(1232)0bar + 123314, // Xi(1820)- + -123314, // Xi(1820)+ + 123324, // Xi(1820)0 + -123324 // Xi(1820)0bar }; std::vector> decayDaughters = { - {311, 211}, // K*+- - {-311, -211}, // K*bar+- - {211, -211}, // f_0(980) - {211, -211}, // rho(770)0 - {211, 111}, // rho(770)+ - {-211, 111}, // rho(770)bar- - {3122, 211}, // Sigma(1385)+ - {-3122, -211}, // Sigma(1385)bar- - {3122, -211}, // Sigma(1385)- - {-3122, 211}, // Sigma(1385)bar+ - {3312, 211}, // Xi(1530)0 - {-3312, -211}, // Xi(1530)0bar - {321, 211}, // K1(1270)+ - {-321, -211}, // K1(1270)-bar - {2212, 211}, // Delta(1232)+ - {-2212, -211}, // Delta(1232)bar- - {2212, -211}, // Delta(1232)- - {-2212, 211} // Delta(1232)bar+ + {211, -211}, // f_0(980) + {310, 310}, // f_2(1270) + {310, 310}, // a_2(1320) + {310, 310}, // f_0(1370) + {310, 310}, // f_0(1500) + {310, 310}, // f_2(1525) + {310, 310}, // f_0(1710) + {310, -321, 211}, // f_1(1285) + {310, -321, 211}, // f_1(1420) + {310, 310}, // f_2(1525) + {321, 211}, // K1(1270)+ + {-321, -211}, // K1(1270)-bar + {2212, 211}, // Delta(1232)+ + {3122, -311}, // Xi(1820)- + {3122, 311}, // Xi(1820)+ + {3122, 310}, // Xi(1820)0 + {-3122, 310} // Xi(1820)0bar }; auto nInjection = injectedPDGs.size(); @@ -167,4 +164,4 @@ int External() return 0; } -void GeneratorLF_Resonances_pp900_trigger() { External(); } +void GeneratorLF_Resonances_pp1360_injection() { External(); } diff --git a/MC/config/PWGLF/ini/tests/GeneratorLF_Resonances_pp_exoticAll_gap2.C b/MC/config/PWGLF/ini/tests/GeneratorLF_Resonances_pp_exoticAll_gap2.C new file mode 100644 index 000000000..74076d41c --- /dev/null +++ b/MC/config/PWGLF/ini/tests/GeneratorLF_Resonances_pp_exoticAll_gap2.C @@ -0,0 +1,154 @@ +int External() +{ + std::string path{"o2sim_Kine.root"}; + int numberOfInjectedSignalsPerEvent{1}; + int numberOfGapEvents{4}; + int numberOfEventsProcessed{0}; + int numberOfEventsProcessedWithoutInjection{0}; + std::vector injectedPDGs = { + 225, // f_2(1270) + 10221, // f_0(1370) + 9030221, // f_0(1500) + 10331, // f_0(1710) + 20223, // f_1(1285) + 20333, // f_1(1420) + 335, // f_2(1525) + 115, // a_2(1320) + 102134, // Lambda(1520)0 + -102134 // Lambda(1520)0bar + }; + std::vector> decayDaughters = { + {310, 310}, // f_2(1270) + {310, 310}, // f_0(1370) + {310, 310}, // f_0(1500) + {310, 310}, // f_0(1710) + {310, -321, 211}, // f_1(1285) + {310, -321, 211}, // f_1(1420) + {310, 310}, // f_2(1525) + {310, 310}, // a_2(1320) + {2212, -321}, // Lambda(1520)0 + {-2212, 321} // Lambda(1520)0bar + }; + + auto nInjection = injectedPDGs.size(); + + TFile file(path.c_str(), "READ"); + if (file.IsZombie()) + { + std::cerr << "Cannot open ROOT file " << path << "\n"; + return 1; + } + + auto tree = (TTree *)file.Get("o2sim"); + if (!tree) + { + std::cerr << "Cannot find tree o2sim in file " << path << "\n"; + return 1; + } + std::vector *tracks{}; + tree->SetBranchAddress("MCTrack", &tracks); + + std::vector nSignal; + for (int i = 0; i < nInjection; i++) + { + nSignal.push_back(0); + } + std::vector> nDecays; + std::vector nNotDecayed; + for (int i = 0; i < nInjection; i++) + { + std::vector nDecay; + for (int j = 0; j < decayDaughters[i].size(); j++) + { + nDecay.push_back(0); + } + nDecays.push_back(nDecay); + nNotDecayed.push_back(0); + } + auto nEvents = tree->GetEntries(); + bool hasInjection = false; + for (int i = 0; i < nEvents; i++) + { + hasInjection = false; + numberOfEventsProcessed++; + auto check = tree->GetEntry(i); + for (int idxMCTrack = 0; idxMCTrack < tracks->size(); ++idxMCTrack) + { + auto track = tracks->at(idxMCTrack); + auto pdg = track.GetPdgCode(); + auto it = std::find(injectedPDGs.begin(), injectedPDGs.end(), pdg); + int index = std::distance(injectedPDGs.begin(), it); // index of injected PDG + if (it != injectedPDGs.end()) // found + { + // count signal PDG + nSignal[index]++; + if (track.getFirstDaughterTrackId() < 0) + { + nNotDecayed[index]++; + continue; + } + for (int j{track.getFirstDaughterTrackId()}; j <= track.getLastDaughterTrackId(); ++j) + { + auto pdgDau = tracks->at(j).GetPdgCode(); + bool foundDau = false; + // count decay PDGs + for (int idxDaughter = 0; idxDaughter < decayDaughters[index].size(); ++idxDaughter) + { + if (pdgDau == decayDaughters[index][idxDaughter]) + { + nDecays[index][idxDaughter]++; + foundDau = true; + hasInjection = true; + break; + } + } + if (!foundDau) + { + std::cerr << "Decay daughter not found: " << pdg << " -> " << pdgDau << "\n"; + } + } + } + } + if (!hasInjection) + { + numberOfEventsProcessedWithoutInjection++; + } + } + std::cout << "--------------------------------\n"; + std::cout << "# Events: " << nEvents << "\n"; + for (int i = 0; i < nInjection; i++) + { + std::cout << "# Mother \n"; + std::cout << injectedPDGs[i] << " generated: " << nSignal[i] << ", " << nNotDecayed[i] << " did not decay\n"; + if (nSignal[i] == 0) + { + std::cerr << "No generated: " << injectedPDGs[i] << "\n"; + // return 1; // At least one of the injected particles should be generated + } + for (int j = 0; j < decayDaughters[i].size(); j++) + { + std::cout << "# Daughter " << decayDaughters[i][j] << ": " << nDecays[i][j] << "\n"; + } + // if (nSignal[i] != nEvents * numberOfInjectedSignalsPerEvent) + // { + // std::cerr << "Number of generated: " << injectedPDGs[i] << ", lower than expected\n"; + // // return 1; // Don't need to return 1, since the number of generated particles is not the same for each event + // } + } + std::cout << "--------------------------------\n"; + std::cout << "Number of events processed: " << numberOfEventsProcessed << "\n"; + std::cout << "Number of input for the gap events: " << numberOfGapEvents << "\n"; + std::cout << "Number of events processed without injection: " << numberOfEventsProcessedWithoutInjection << "\n"; + // injected event + numberOfGapEvents*gap events + injected event + numberOfGapEvents*gap events + ... + // total fraction of the gap event: numberOfEventsProcessedWithoutInjection/numberOfEventsProcessed + float ratioOfNormalEvents = numberOfEventsProcessedWithoutInjection / numberOfEventsProcessed; + if (ratioOfNormalEvents > 0.75) + { + std::cout << "The number of injected event is loo low!!" << std::endl; + return 1; + } + + return 0; +} + +void GeneratorLF_Resonances_pp1360_injection() { External(); } diff --git a/MC/config/PWGLF/ini/tests/GeneratorLF_StrangenessInJets_gap4.C b/MC/config/PWGLF/ini/tests/GeneratorLF_StrangenessInJets_gap4.C new file mode 100644 index 000000000..12f069f3c --- /dev/null +++ b/MC/config/PWGLF/ini/tests/GeneratorLF_StrangenessInJets_gap4.C @@ -0,0 +1,27 @@ +int External() { + std::string path{"o2sim_Kine.root"}; + + TFile file(path.c_str(), "READ"); + if (file.IsZombie()) { + std::cerr << "Cannot open ROOT file " << path << "\n"; + return 1; + } + + auto tree = (TTree *)file.Get("o2sim"); + if (!tree) { + std::cerr << "Cannot find tree o2sim in file " << path << "\n"; + return 1; + } + std::vector *tracks{}; + tree->SetBranchAddress("MCTrack", &tracks); + + auto nXi = tree->Scan("MCTrack.GetPdgCode()", "TMath::Abs(MCTrack.GetPdgCode()) == 3312"); + auto nOmega = tree->Scan("MCTrack.GetPdgCode()", "TMath::Abs(MCTrack.GetPdgCode()) == 3334"); + auto nStr = nXi+nOmega; + + if (nStr == 0) { + std::cerr << "No event of interest\n"; + return 1; + } + return 0; +} diff --git a/MC/config/PWGLF/ini/tests/GeneratorLF_Strangeness_OO5360_injection.C b/MC/config/PWGLF/ini/tests/GeneratorLF_Strangeness_OO5360_injection.C new file mode 100644 index 000000000..ab7eeb695 --- /dev/null +++ b/MC/config/PWGLF/ini/tests/GeneratorLF_Strangeness_OO5360_injection.C @@ -0,0 +1,28 @@ +int External() +{ + std::string path{"o2sim_Kine.root"}; + + TFile file(path.c_str(), "READ"); + if (file.IsZombie()) + { + std::cerr << "Cannot open ROOT file " << path << "\n"; + return 1; + } + + auto tree = (TTree *)file.Get("o2sim"); + if (!tree) + { + std::cerr << "Cannot find tree o2sim in file " << path << "\n"; + return 1; + } + std::vector *tracks{}; + tree->SetBranchAddress("MCTrack", &tracks); + + auto nEvents = tree->GetEntries(); + if (nEvents < 1) + { + std::cerr << "No events actually generated: not OK!"; + return 1; + } + return 0; +} diff --git a/MC/config/PWGLF/ini/tests/GeneratorLF_Strangeness_OO5360_injection_omega100.C b/MC/config/PWGLF/ini/tests/GeneratorLF_Strangeness_OO5360_injection_omega100.C new file mode 120000 index 000000000..fe732fe72 --- /dev/null +++ b/MC/config/PWGLF/ini/tests/GeneratorLF_Strangeness_OO5360_injection_omega100.C @@ -0,0 +1 @@ +GeneratorLF_SyntheFlow.C \ No newline at end of file diff --git a/MC/config/PWGLF/ini/tests/GeneratorLF_Strangeness_OO5360_injection_omega30.C b/MC/config/PWGLF/ini/tests/GeneratorLF_Strangeness_OO5360_injection_omega30.C new file mode 120000 index 000000000..fe732fe72 --- /dev/null +++ b/MC/config/PWGLF/ini/tests/GeneratorLF_Strangeness_OO5360_injection_omega30.C @@ -0,0 +1 @@ +GeneratorLF_SyntheFlow.C \ No newline at end of file diff --git a/MC/config/PWGLF/ini/tests/GeneratorLF_Strangeness_OO5360_injection_omega300.C b/MC/config/PWGLF/ini/tests/GeneratorLF_Strangeness_OO5360_injection_omega300.C new file mode 120000 index 000000000..fe732fe72 --- /dev/null +++ b/MC/config/PWGLF/ini/tests/GeneratorLF_Strangeness_OO5360_injection_omega300.C @@ -0,0 +1 @@ +GeneratorLF_SyntheFlow.C \ No newline at end of file diff --git a/MC/config/PWGLF/ini/tests/GeneratorLF_Strangeness_OO5360_injection_omega50.C b/MC/config/PWGLF/ini/tests/GeneratorLF_Strangeness_OO5360_injection_omega50.C new file mode 120000 index 000000000..fe732fe72 --- /dev/null +++ b/MC/config/PWGLF/ini/tests/GeneratorLF_Strangeness_OO5360_injection_omega50.C @@ -0,0 +1 @@ +GeneratorLF_SyntheFlow.C \ No newline at end of file diff --git a/MC/config/PWGLF/ini/tests/GeneratorLF_Strangeness_OO5360_injection_omega500.C b/MC/config/PWGLF/ini/tests/GeneratorLF_Strangeness_OO5360_injection_omega500.C new file mode 120000 index 000000000..fe732fe72 --- /dev/null +++ b/MC/config/PWGLF/ini/tests/GeneratorLF_Strangeness_OO5360_injection_omega500.C @@ -0,0 +1 @@ +GeneratorLF_SyntheFlow.C \ No newline at end of file diff --git a/MC/config/PWGLF/ini/tests/GeneratorLF_SyntheFlowOO.C b/MC/config/PWGLF/ini/tests/GeneratorLF_SyntheFlowOO.C new file mode 100644 index 000000000..ab7eeb695 --- /dev/null +++ b/MC/config/PWGLF/ini/tests/GeneratorLF_SyntheFlowOO.C @@ -0,0 +1,28 @@ +int External() +{ + std::string path{"o2sim_Kine.root"}; + + TFile file(path.c_str(), "READ"); + if (file.IsZombie()) + { + std::cerr << "Cannot open ROOT file " << path << "\n"; + return 1; + } + + auto tree = (TTree *)file.Get("o2sim"); + if (!tree) + { + std::cerr << "Cannot find tree o2sim in file " << path << "\n"; + return 1; + } + std::vector *tracks{}; + tree->SetBranchAddress("MCTrack", &tracks); + + auto nEvents = tree->GetEntries(); + if (nEvents < 1) + { + std::cerr << "No events actually generated: not OK!"; + return 1; + } + return 0; +} diff --git a/MC/config/PWGLF/ini/tests/GeneratorLF_deuteron_wigner.C b/MC/config/PWGLF/ini/tests/GeneratorLF_deuteron_wigner.C new file mode 100644 index 000000000..3cf153204 --- /dev/null +++ b/MC/config/PWGLF/ini/tests/GeneratorLF_deuteron_wigner.C @@ -0,0 +1,41 @@ + +int External() { + std::string path{"o2sim_Kine.root"}; + + TFile file(path.c_str(), "READ"); + if (file.IsZombie()) { + std::cerr << "Cannot open ROOT file " << path << "\n"; + return 1; + } + + auto tree = (TTree *)file.Get("o2sim"); + if (!tree) { + std::cerr << "Cannot find tree o2sim in file " << path << "\n"; + return 1; + } + + std::vector* tracks = nullptr; + tree->SetBranchAddress("MCTrack", &tracks); + + Long64_t nEntries = tree->GetEntries(); + int nSelected = 0; + + for (Long64_t i = 0; i < nEntries; ++i) { + tree->GetEntry(i); + for (const auto& track : *tracks) { + if (std::abs(track.GetPdgCode()) == 1000010020) { // Deuteron + ++nSelected; + break; // Found in this event + } + } + } + + if (nSelected == 0) { + std::cout << "No events with deuterons found.\n"; + } else { + std::cout << "Found " << nSelected << " events with deuterons\n"; + } + return 0; + +} + diff --git a/MC/config/PWGLF/ini/tests/GeneratorLF_pp536_Ropes.C b/MC/config/PWGLF/ini/tests/GeneratorLF_pp536_Ropes.C new file mode 100644 index 000000000..ab7eeb695 --- /dev/null +++ b/MC/config/PWGLF/ini/tests/GeneratorLF_pp536_Ropes.C @@ -0,0 +1,28 @@ +int External() +{ + std::string path{"o2sim_Kine.root"}; + + TFile file(path.c_str(), "READ"); + if (file.IsZombie()) + { + std::cerr << "Cannot open ROOT file " << path << "\n"; + return 1; + } + + auto tree = (TTree *)file.Get("o2sim"); + if (!tree) + { + std::cerr << "Cannot find tree o2sim in file " << path << "\n"; + return 1; + } + std::vector *tracks{}; + tree->SetBranchAddress("MCTrack", &tracks); + + auto nEvents = tree->GetEntries(); + if (nEvents < 1) + { + std::cerr << "No events actually generated: not OK!"; + return 1; + } + return 0; +} diff --git a/MC/config/PWGLF/ini/tests/GeneratorLF_pp536_wDeCoal.C b/MC/config/PWGLF/ini/tests/GeneratorLF_pp536_wDeCoal.C new file mode 100644 index 000000000..ab7eeb695 --- /dev/null +++ b/MC/config/PWGLF/ini/tests/GeneratorLF_pp536_wDeCoal.C @@ -0,0 +1,28 @@ +int External() +{ + std::string path{"o2sim_Kine.root"}; + + TFile file(path.c_str(), "READ"); + if (file.IsZombie()) + { + std::cerr << "Cannot open ROOT file " << path << "\n"; + return 1; + } + + auto tree = (TTree *)file.Get("o2sim"); + if (!tree) + { + std::cerr << "Cannot find tree o2sim in file " << path << "\n"; + return 1; + } + std::vector *tracks{}; + tree->SetBranchAddress("MCTrack", &tracks); + + auto nEvents = tree->GetEntries(); + if (nEvents < 1) + { + std::cerr << "No events actually generated: not OK!"; + return 1; + } + return 0; +} diff --git a/MC/config/PWGLF/ini/tests/GeneratorLF_pp536_wDeInel.C b/MC/config/PWGLF/ini/tests/GeneratorLF_pp536_wDeInel.C new file mode 100644 index 000000000..ab7eeb695 --- /dev/null +++ b/MC/config/PWGLF/ini/tests/GeneratorLF_pp536_wDeInel.C @@ -0,0 +1,28 @@ +int External() +{ + std::string path{"o2sim_Kine.root"}; + + TFile file(path.c_str(), "READ"); + if (file.IsZombie()) + { + std::cerr << "Cannot open ROOT file " << path << "\n"; + return 1; + } + + auto tree = (TTree *)file.Get("o2sim"); + if (!tree) + { + std::cerr << "Cannot find tree o2sim in file " << path << "\n"; + return 1; + } + std::vector *tracks{}; + tree->SetBranchAddress("MCTrack", &tracks); + + auto nEvents = tree->GetEntries(); + if (nEvents < 1) + { + std::cerr << "No events actually generated: not OK!"; + return 1; + } + return 0; +} diff --git a/MC/config/PWGLF/ini/tests/GeneratorSigmaProtonTriggered.C b/MC/config/PWGLF/ini/tests/GeneratorSigmaProtonTriggered.C new file mode 100644 index 000000000..91d47a9a6 --- /dev/null +++ b/MC/config/PWGLF/ini/tests/GeneratorSigmaProtonTriggered.C @@ -0,0 +1,49 @@ +int External() +{ + std::string path{"o2sim_Kine.root"}; + + TFile file(path.c_str(), "READ"); + if (file.IsZombie()) { + std::cerr << "Cannot open ROOT file " << path << "\n"; + return 1; + } + + auto tree = (TTree*)file.Get("o2sim"); + if (!tree) { + std::cerr << "Cannot find tree o2sim in file " << path << "\n"; + return 1; + } + + std::vector* tracks = nullptr; + tree->SetBranchAddress("MCTrack", &tracks); + + const auto nEvents = tree->GetEntries(); + + for (Long64_t iEv = 0; iEv < nEvents; ++iEv) { + tree->GetEntry(iEv); + + bool hasSigma = false; + bool hasProton = false; + + for (const auto& track : *tracks) { + const int pdg = track.GetPdgCode(); + const int absPdg = std::abs(pdg); + + if (absPdg == 3112 || absPdg == 3222) { + hasSigma = true; + } + + if (pdg == 2212) { + hasProton = true; + } + + if (hasSigma && hasProton) { + std::cout << "Found event of interest at entry " << iEv << "\n"; + return 0; + } + } + } + + std::cerr << "No Sigma-proton event of interest\n"; + return 1; +} \ No newline at end of file diff --git a/MC/config/PWGLF/pythia8/decayer/force_h3l_kink_decay.cfg b/MC/config/PWGLF/pythia8/decayer/force_h3l_kink_decay.cfg new file mode 100644 index 000000000..abc615984 --- /dev/null +++ b/MC/config/PWGLF/pythia8/decayer/force_h3l_kink_decay.cfg @@ -0,0 +1,20 @@ +Init:showChangedParticleData = on +1010010030:new = hypertriton anti_hypertriton 1 0 0 0 0 2.991 0.0 0.0 0.0 +1010010030:m0 = 2.991 +1010010030:mWidth = 0.0 +1010010030:tau0 = 78.0 # lifetime in mm (~2.6e-10 s) +1010010030:spinType = 1 +1010010030:chargeType = 3 # +1 e = 3 * (1/3 e) +1010010030:colType = 0 + +1000010030:new = triton anti_triton 1 0 0 0 0 2.80892 0.0 0.0 0.0 +1000010030:m0 = 2.80892 +1000010030:mWidth = 0.0 +1000010030:tau0 = 0.0 # effectively stable +1000010030:spinType = 1 +1000010030:chargeType = 3 # +1 e +1000010030:colType = 0 +1000010030:mayDecay = off + +1010010030:mayDecay = on +1010010030:oneChannel = 1 1.0 0 1000010030 111 diff --git a/MC/config/PWGLF/pythia8/decayer/force_lambda_charged_decay.cfg b/MC/config/PWGLF/pythia8/decayer/force_lambda_charged_decay.cfg new file mode 100644 index 000000000..2446b28c7 --- /dev/null +++ b/MC/config/PWGLF/pythia8/decayer/force_lambda_charged_decay.cfg @@ -0,0 +1,5 @@ +3122:mayDecay = on +3122:oneChannel = 1 1.0 0 2212 -211 + +-3122:mayDecay = on +-3122:oneChannel = 1 1.0 0 -2212 211 \ No newline at end of file diff --git a/MC/config/PWGLF/pythia8/decayer/g4_ext_decayer_h3l.in b/MC/config/PWGLF/pythia8/decayer/g4_ext_decayer_h3l.in new file mode 100644 index 000000000..8bbdf6ca3 --- /dev/null +++ b/MC/config/PWGLF/pythia8/decayer/g4_ext_decayer_h3l.in @@ -0,0 +1,68 @@ + +/control/verbose 2 +/mcVerbose/all 1 +/mcVerbose/geometryManager 1 +/mcVerbose/opGeometryManager 1 +/mcTracking/loopVerbose 1 +/mcVerbose/composedPhysicsList 2 +/mcVerbose/runAction 2 # For looping thresholds control +#/tracking/verbose 1 +#//control/cout/ignoreThreadsExcept 0 + +/mcPhysics/rangeCuts 0.001 mm +/mcRegions/setRangePrecision 5 +/mcTracking/skipNeutrino true +/mcDet/setIsMaxStepInLowDensityMaterials true +/mcDet/setMaxStepInLowDensityMaterials 10 m +/mcMagField/setConstDistance 1 mm +/mcDet/setIsZeroMagField true +/mcControl/useRootRandom true # couple G4 random seed to gRandom + +# optical + +/process/optical/verbose 0 +/process/optical/processActivation Scintillation 0 +/process/optical/processActivation OpWLS 0 +/process/optical/processActivation OpMieHG 0 +/process/optical/cerenkov/setTrackSecondariesFirst false +/mcMagField/stepperType NystromRK4 + +# PAI for TRD +# Geant4 VMC >= v3.2 +/mcPhysics/emModel/setEmModel PAI +/mcPhysics/emModel/setRegions TRD_Gas-mix +/mcPhysics/emModel/setParticles all +/mcPrimaryGenerator/skipUnknownParticles true # don't crash when seeing unknown ion etc. (issue warning) + +# +# Precise Msc for EMCAL +# +# Geant4 VMC >= v3.2 +/mcPhysics/emModel/setEmModel SpecialUrbanMsc +/mcPhysics/emModel/setRegions EMC_Lead$ EMC_Scintillator$ +/mcPhysics/emModel/setParticles e- e+ + +# combined transportation + Msc mode is currently broken for ALICE (Geant 10.2.0) +/process/em/transportationWithMsc Disabled + +# +# Adding extra lines for fixing tracking bias +# +/mcMagField/setDeltaIntersection 1.0e-05 mm +/mcMagField/setMinimumEpsilonStep 0.5e-05 +/mcMagField/setMaximumEpsilonStep 1.0e-05 +/mcMagField/printParameters + +# Change default parameters for killing looping particles +# +/mcPhysics/useHighLooperThresholds +/mcRun/setLooperThresholdImportantEnergy 100. MeV + +# Define media with the INCLXX physics list; here basically in all ITS media +#/mcVerbose/biasingConfigurationManager 3 +/mcPhysics/biasing/setModel inclxx +/mcPhysics/biasing/setRegions ITS_AIR$ ITS_WATER$ ITS_COPPER$ ITS_KAPTON(POLYCH2)$ ITS_GLUE_IBFPC$ ITS_CERAMIC$ ITS_K13D2U2k$ ITS_K13D2U120$ ITS_F6151B05M$ ITS_M60J3K$ ITS_M55J6K$ ITS_FGS003$ ITS_CarbonFleece$ ITS_PEEKCF30$ ITS_GLUE$ ITS_ALUMINUM$ ITS_INOX304$ ALPIDE_METALSTACK$ ALPIDE_SI$ +/mcPhysics/biasing/setParticles proton neutron pi+ pi- + +# external decayer +/mcPhysics/setExtDecayerSelection hypertriton anti_hypertriton \ No newline at end of file diff --git a/MC/config/PWGLF/pythia8/decayer/g4_ext_decayer_lambda.in b/MC/config/PWGLF/pythia8/decayer/g4_ext_decayer_lambda.in new file mode 100644 index 000000000..e843b1d9e --- /dev/null +++ b/MC/config/PWGLF/pythia8/decayer/g4_ext_decayer_lambda.in @@ -0,0 +1,68 @@ + +/control/verbose 2 +/mcVerbose/all 1 +/mcVerbose/geometryManager 1 +/mcVerbose/opGeometryManager 1 +/mcTracking/loopVerbose 1 +/mcVerbose/composedPhysicsList 2 +/mcVerbose/runAction 2 # For looping thresholds control +#/tracking/verbose 1 +#//control/cout/ignoreThreadsExcept 0 + +/mcPhysics/rangeCuts 0.001 mm +/mcRegions/setRangePrecision 5 +/mcTracking/skipNeutrino true +/mcDet/setIsMaxStepInLowDensityMaterials true +/mcDet/setMaxStepInLowDensityMaterials 10 m +/mcMagField/setConstDistance 1 mm +/mcDet/setIsZeroMagField true +/mcControl/useRootRandom true # couple G4 random seed to gRandom + +# optical + +/process/optical/verbose 0 +/process/optical/processActivation Scintillation 0 +/process/optical/processActivation OpWLS 0 +/process/optical/processActivation OpMieHG 0 +/process/optical/cerenkov/setTrackSecondariesFirst false +/mcMagField/stepperType NystromRK4 + +# PAI for TRD +# Geant4 VMC >= v3.2 +/mcPhysics/emModel/setEmModel PAI +/mcPhysics/emModel/setRegions TRD_Gas-mix +/mcPhysics/emModel/setParticles all +/mcPrimaryGenerator/skipUnknownParticles true # don't crash when seeing unknown ion etc. (issue warning) + +# +# Precise Msc for EMCAL +# +# Geant4 VMC >= v3.2 +/mcPhysics/emModel/setEmModel SpecialUrbanMsc +/mcPhysics/emModel/setRegions EMC_Lead$ EMC_Scintillator$ +/mcPhysics/emModel/setParticles e- e+ + +# combined transportation + Msc mode is currently broken for ALICE (Geant 10.2.0) +/process/em/transportationWithMsc Disabled + +# +# Adding extra lines for fixing tracking bias +# +/mcMagField/setDeltaIntersection 1.0e-05 mm +/mcMagField/setMinimumEpsilonStep 0.5e-05 +/mcMagField/setMaximumEpsilonStep 1.0e-05 +/mcMagField/printParameters + +# Change default parameters for killing looping particles +# +/mcPhysics/useHighLooperThresholds +/mcRun/setLooperThresholdImportantEnergy 100. MeV + +# Define media with the INCLXX physics list; here basically in all ITS media +#/mcVerbose/biasingConfigurationManager 3 +/mcPhysics/biasing/setModel inclxx +/mcPhysics/biasing/setRegions ITS_AIR$ ITS_WATER$ ITS_COPPER$ ITS_KAPTON(POLYCH2)$ ITS_GLUE_IBFPC$ ITS_CERAMIC$ ITS_K13D2U2k$ ITS_K13D2U120$ ITS_F6151B05M$ ITS_M60J3K$ ITS_M55J6K$ ITS_FGS003$ ITS_CarbonFleece$ ITS_PEEKCF30$ ITS_GLUE$ ITS_ALUMINUM$ ITS_INOX304$ ALPIDE_METALSTACK$ ALPIDE_SI$ +/mcPhysics/biasing/setParticles proton neutron pi+ pi- + +# external decayer +/mcPhysics/setExtDecayerSelection lambda anti_lambda \ No newline at end of file diff --git a/MC/config/PWGLF/pythia8/generator/exotic_nuclei_pp.gun b/MC/config/PWGLF/pythia8/generator/exotic_nuclei_pp.gun new file mode 100644 index 000000000..6174a13c4 --- /dev/null +++ b/MC/config/PWGLF/pythia8/generator/exotic_nuclei_pp.gun @@ -0,0 +1,5 @@ +# PDG N ptMin ptMax yMin yMax +225 10 0.2 10 -1 1 +115 10 0.2 10 -1 1 +335 10 0.2 10 -1 1 +10331 10 0.2 10 -1 1 diff --git a/MC/config/PWGLF/pythia8/generator/exoticresonancegun.json b/MC/config/PWGLF/pythia8/generator/exoticresonancegun.json index a2d964c1a..7043cd6d8 100644 --- a/MC/config/PWGLF/pythia8/generator/exoticresonancegun.json +++ b/MC/config/PWGLF/pythia8/generator/exoticresonancegun.json @@ -6,6 +6,8 @@ "ptMax": 20, "etaMin": -1.2, "etaMax": 1.2, + "rapidityMin": -1.2, + "rapidityMax": 1.2, "genDecayed": true }, "f_1(1420)" : { @@ -15,6 +17,8 @@ "ptMax": 20, "etaMin": -1.2, "etaMax": 1.2, + "rapidityMin": -1.2, + "rapidityMax": 1.2, "genDecayed": true }, "f_0(1500)" : { @@ -24,6 +28,8 @@ "ptMax": 20, "etaMin": -1.2, "etaMax": 1.2, + "rapidityMin": -1.2, + "rapidityMax": 1.2, "genDecayed": true }, "f_0(1710)" : { @@ -33,6 +39,8 @@ "ptMax": 20, "etaMin": -1.2, "etaMax": 1.2, + "rapidityMin": -1.2, + "rapidityMax": 1.2, "genDecayed": true }, "f_2(1525)" : { @@ -42,6 +50,8 @@ "ptMax": 20, "etaMin": -1.2, "etaMax": 1.2, + "rapidityMin": -1.2, + "rapidityMax": 1.2, "genDecayed": true }, "f_0(1370)" : { @@ -51,6 +61,8 @@ "ptMax": 20, "etaMin": -1.2, "etaMax": 1.2, + "rapidityMin": -1.2, + "rapidityMax": 1.2, "genDecayed": true } } diff --git a/MC/config/PWGLF/pythia8/generator/gluelistgun.json b/MC/config/PWGLF/pythia8/generator/gluelistgun.json new file mode 100644 index 000000000..00683e335 --- /dev/null +++ b/MC/config/PWGLF/pythia8/generator/gluelistgun.json @@ -0,0 +1,68 @@ +{ + "f_2(1270)": { + "pdg": 225, + "n": 3, + "ptMin": 0.0, + "ptMax": 30, + "etaMin": -1.0, + "etaMax": 1.0, + "rapidityMin": -1.0, + "rapidityMax": 1.0, + "genDecayed": true + }, + "f_0(1370)": { + "pdg": 10221, + "n": 3, + "ptMin": 0.0, + "ptMax": 30, + "etaMin": -1.0, + "etaMax": 1.0, + "rapidityMin": -1.0, + "rapidityMax": 1.0, + "genDecayed": true + }, + "f_0(1500)": { + "pdg": 9030221, + "n": 3, + "ptMin": 0.0, + "ptMax": 30, + "etaMin": -1.0, + "etaMax": 1.0, + "rapidityMin": -1.0, + "rapidityMax": 1.0, + "genDecayed": true + }, + "f_0(1710)": { + "pdg": 10331, + "n": 3, + "ptMin": 0.0, + "ptMax": 30, + "etaMin": -1.0, + "etaMax": 1.0, + "rapidityMin": -1.0, + "rapidityMax": 1.0, + "genDecayed": true + }, + "f_2(1525)": { + "pdg": 335, + "n": 3, + "ptMin": 0.0, + "ptMax": 30, + "etaMin": -1.0, + "etaMax": 1.0, + "rapidityMin": -1.0, + "rapidityMax": 1.0, + "genDecayed": true + }, + "a_2(1230)": { + "pdg": 115, + "n": 3, + "ptMin": 0.0, + "ptMax": 30, + "etaMin": -1.0, + "etaMax": 1.0, + "rapidityMin": -1.0, + "rapidityMax": 1.0, + "genDecayed": true + } +} \ No newline at end of file diff --git a/MC/config/PWGLF/pythia8/generator/hypernuclei_flow.gun b/MC/config/PWGLF/pythia8/generator/hypernuclei_flow.gun new file mode 100644 index 000000000..54455aff0 --- /dev/null +++ b/MC/config/PWGLF/pythia8/generator/hypernuclei_flow.gun @@ -0,0 +1,5 @@ +# PDG N ptMin ptMax yMin yMax +1000010020 20 0.2 10 -1 1 +1000020030 20 0.2 10 -1 1 +1000020040 20 0.2 10 -1 1 +1010010030 20 0.2 10 -1 1 diff --git a/MC/config/PWGLF/pythia8/generator/hypernuclei_oo.gun b/MC/config/PWGLF/pythia8/generator/hypernuclei_oo.gun new file mode 100644 index 000000000..66ba2dc0f --- /dev/null +++ b/MC/config/PWGLF/pythia8/generator/hypernuclei_oo.gun @@ -0,0 +1,10 @@ +# PDG N ptMin ptMax yMin yMax +1000010020 2 0.2 10 -1 1 +1000010030 2 0.2 10 -1 1 +1000020030 2 0.2 10 -1 1 +1000020040 2 0.2 10 -1 1 +1010010030 2 0.2 10 -1 1 +1010010040 2 0.2 10 -1 1 +1010020040 2 0.2 10 -1 1 +1010000030 1 0.2 10 -1 1 +1000030040 1 0.2 10 -1 1 \ No newline at end of file diff --git a/MC/config/PWGLF/pythia8/generator/hypernuclei_pbpb.gun b/MC/config/PWGLF/pythia8/generator/hypernuclei_pbpb.gun index 3b4a8d274..8bda8396e 100644 --- a/MC/config/PWGLF/pythia8/generator/hypernuclei_pbpb.gun +++ b/MC/config/PWGLF/pythia8/generator/hypernuclei_pbpb.gun @@ -6,3 +6,5 @@ 1010010030 20 0.2 10 -1 1 1010010040 20 0.2 10 -1 1 1010020040 20 0.2 10 -1 1 +1010000030 10 0.2 10 -1 1 +1000030040 10 0.2 10 -1 1 diff --git a/MC/config/PWGLF/pythia8/generator/lambda1520.cfg b/MC/config/PWGLF/pythia8/generator/lambda1520.cfg new file mode 100644 index 000000000..df201689b --- /dev/null +++ b/MC/config/PWGLF/pythia8/generator/lambda1520.cfg @@ -0,0 +1,10 @@ +### Define resonance +ProcessLevel:all = off # will not look for the 'process' + +# id::all = name antiName spinType chargeType colType m0 mWidth mMin mMax tau0 +102134:all = Lambda1520 Lambda1520bar 4 0 0 1.51950 0.01560 1.47 1.60 0 + +### add Resonance decays absent in PYTHIA8 decay table and set BRs from PDG for other +102134:oneChannel = 1 1.000 0 2212 -321 +102134:onMode = off +102134:onIfMatch = 2212 -321 diff --git a/MC/config/PWGLF/pythia8/generator/lambda1520gun_inj.json b/MC/config/PWGLF/pythia8/generator/lambda1520gun_inj.json new file mode 100644 index 000000000..f7e095729 --- /dev/null +++ b/MC/config/PWGLF/pythia8/generator/lambda1520gun_inj.json @@ -0,0 +1,24 @@ +{ + "Lambda(1520)0" : { + "pdg": 102134, + "n": 5, + "ptMin": 0.0, + "ptMax": 15, + "etaMin": -1.0, + "etaMax": 1.0, + "rapidityMin": -1.0, + "rapidityMax": 1.0, + "genDecayed": true + }, + "anti-Lambda(1520)0" : { + "pdg": -102134, + "n": 5, + "ptMin": 0.0, + "ptMax": 15, + "etaMin": -1.0, + "etaMax": 1.0, + "rapidityMin": -1.0, + "rapidityMax": 1.0, + "genDecayed": true + } +} diff --git a/MC/config/PWGLF/pythia8/generator/pythia8_inel_536tev_wDeCoal.cfg b/MC/config/PWGLF/pythia8/generator/pythia8_inel_536tev_wDeCoal.cfg new file mode 100644 index 000000000..6ad09b191 --- /dev/null +++ b/MC/config/PWGLF/pythia8/generator/pythia8_inel_536tev_wDeCoal.cfg @@ -0,0 +1,23 @@ +### Specify beams +Beams:idA = 2212 +Beams:idB = 2212 +Beams:eCM = 5360. ### energy + +Beams:frameType = 1 +ParticleDecays:limitTau0 = on +ParticleDecays:tau0Max = 10. ### match alice: 1cm/c = 10.0mm/c + +### processes +SoftQCD:inelastic = on # all inelastic processes + +# default: do nothing, Monash 2013 will do its thing +Tune:pp = 14 + +Random:setSeed = on + +# enable deuteron production by coalescence collisions +HadronLevel:DeuteronProduction = on +DeuteronProduction:channels = {2212 2112 > 22} +DeuteronProduction:models = {0} +DeuteronProduction:norm = 1 +DeuteronProduction:parms = {0.195 1} diff --git a/MC/config/PWGLF/pythia8/generator/pythia8_inel_536tev_wDeInel.cfg b/MC/config/PWGLF/pythia8/generator/pythia8_inel_536tev_wDeInel.cfg new file mode 100644 index 000000000..b1154ea4f --- /dev/null +++ b/MC/config/PWGLF/pythia8/generator/pythia8_inel_536tev_wDeInel.cfg @@ -0,0 +1,19 @@ +### Specify beams +Beams:idA = 2212 +Beams:idB = 2212 +Beams:eCM = 5360. ### energy + +Beams:frameType = 1 +ParticleDecays:limitTau0 = on +ParticleDecays:tau0Max = 10. ### match alice: 1cm/c = 10.0mm/c + +### processes +SoftQCD:inelastic = on # all inelastic processes + +# default: do nothing, Monash 2013 will do its thing +Tune:pp = 14 + +Random:setSeed = on + +# enable deuteron production by inelastic collisions +HadronLevel:DeuteronProduction = on diff --git a/MC/config/PWGLF/pythia8/generator/pythia8_inel_pp536tev.cfg b/MC/config/PWGLF/pythia8/generator/pythia8_inel_pp536tev.cfg new file mode 100644 index 000000000..6c22eb379 --- /dev/null +++ b/MC/config/PWGLF/pythia8/generator/pythia8_inel_pp536tev.cfg @@ -0,0 +1,18 @@ +### beams +Beams:idA = 2212 # proton +Beams:idB = 2212 # proton +Beams:eCM = 5360. # GeV + +### processes +SoftQCD:inelastic = on # all inelastic processes + +### decays +ParticleDecays:limitTau0 = on +ParticleDecays:tau0Max = 10. + +### phase space cuts +PhaseSpace:pTHatMin = 0.000000 +PhaseSpace:pTHatMax = -1.000000 + +Random:setSeed = on +Random:seed = 0 \ No newline at end of file diff --git a/MC/config/PWGLF/pythia8/generator/pythia8_inel_ropes_536tev.cfg b/MC/config/PWGLF/pythia8/generator/pythia8_inel_ropes_536tev.cfg new file mode 100644 index 000000000..9e4a73bcb --- /dev/null +++ b/MC/config/PWGLF/pythia8/generator/pythia8_inel_ropes_536tev.cfg @@ -0,0 +1,26 @@ +### beams +Beams:idA = 2212 # proton +Beams:idB = 2212 # proton +Beams:eCM = 5360. # GeV + +### processes +SoftQCD:inelastic = on # all inelastic processes + +### decays +ParticleDecays:limitTau0 = on +ParticleDecays:tau0Max = 10. + +### phase space cuts +PhaseSpace:pTHatMin = 0.000000 +PhaseSpace:pTHatMax = -1.000000 + +Random:setSeed = on +Random:seed = 0 + +Ropewalk:RopeHadronization = on +Ropewalk:doShoving = off +Ropewalk:doFlavour = on +Ropewalk:r0 = 0.5 +Ropewalk:m0 = 0.2 +Ropewalk:beta = 0.1 +PartonVertex:setVertex = on \ No newline at end of file diff --git a/MC/config/PWGLF/pythia8/generator/pythia8_jet_ropes_136tev.cfg b/MC/config/PWGLF/pythia8/generator/pythia8_jet_ropes_136tev.cfg new file mode 100644 index 000000000..c198e1db6 --- /dev/null +++ b/MC/config/PWGLF/pythia8/generator/pythia8_jet_ropes_136tev.cfg @@ -0,0 +1,29 @@ +### beams +Beams:idA = 2212 # proton +Beams:idB = 2212 # proton +Beams:eCM = 13600. # GeV + +### processes +SoftQCD:inelastic = off +HardQCD:all = on + +### decays +ParticleDecays:limitTau0 = on +ParticleDecays:tau0Max = 10. + +### phase space cuts +PhaseSpace:pTHatMin = 8 +PhaseSpace:pTHatMax = 600 +PhaseSpace:bias2Selection = on +PhaseSpace:bias2SelectionPow = 4 + +Random:setSeed = on +Random:seed = 0 + +Ropewalk:RopeHadronization = on +Ropewalk:doShoving = off +Ropewalk:doFlavour = on +Ropewalk:r0 = 0.5 +Ropewalk:m0 = 0.2 +Ropewalk:beta = 0.1 +PartonVertex:setVertex = on \ No newline at end of file diff --git a/MC/config/PWGLF/pythia8/generator/pythia8_jet_ropes_536tev.cfg b/MC/config/PWGLF/pythia8/generator/pythia8_jet_ropes_536tev.cfg new file mode 100644 index 000000000..eb7aa7a86 --- /dev/null +++ b/MC/config/PWGLF/pythia8/generator/pythia8_jet_ropes_536tev.cfg @@ -0,0 +1,29 @@ +### beams +Beams:idA = 2212 # proton +Beams:idB = 2212 # proton +Beams:eCM = 5360. # GeV + +### processes +SoftQCD:inelastic = off +HardQCD:all = on + +### decays +ParticleDecays:limitTau0 = on +ParticleDecays:tau0Max = 10. + +### phase space cuts +PhaseSpace:pTHatMin = 8 +PhaseSpace:pTHatMax = 600 +PhaseSpace:bias2Selection = on +PhaseSpace:bias2SelectionPow = 4 + +Random:setSeed = on +Random:seed = 0 + +Ropewalk:RopeHadronization = on +Ropewalk:doShoving = off +Ropewalk:doFlavour = on +Ropewalk:r0 = 0.5 +Ropewalk:m0 = 0.2 +Ropewalk:beta = 0.1 +PartonVertex:setVertex = on \ No newline at end of file diff --git a/MC/config/PWGLF/pythia8/generator/resonancelistgun.json b/MC/config/PWGLF/pythia8/generator/resonancelistgun.json index b8c248b16..8fa6a5b4f 100644 --- a/MC/config/PWGLF/pythia8/generator/resonancelistgun.json +++ b/MC/config/PWGLF/pythia8/generator/resonancelistgun.json @@ -6,6 +6,8 @@ "ptMax": 20, "etaMin": -1.2, "etaMax": 1.2, + "rapidityMin": -1.2, + "rapidityMax": 1.2, "genDecayed": true }, "K(892)-" : { @@ -15,6 +17,8 @@ "ptMax": 20, "etaMin": -1.2, "etaMax": 1.2, + "rapidityMin": -1.2, + "rapidityMax": 1.2, "genDecayed": true }, "f_0(980)" : { @@ -24,6 +28,8 @@ "ptMax": 20, "etaMin": -1.2, "etaMax": 1.2, + "rapidityMin": -1.2, + "rapidityMax": 1.2, "genDecayed": true }, "rho(770)0" : { @@ -33,6 +39,8 @@ "ptMax": 20, "etaMin": -1.2, "etaMax": 1.2, + "rapidityMin": -1.2, + "rapidityMax": 1.2, "genDecayed": true }, "rho(770)+" : { @@ -42,6 +50,8 @@ "ptMax": 20, "etaMin": -1.2, "etaMax": 1.2, + "rapidityMin": -1.2, + "rapidityMax": 1.2, "genDecayed": true }, "rho(770)-" : { @@ -51,6 +61,8 @@ "ptMax": 20, "etaMin": -1.2, "etaMax": 1.2, + "rapidityMin": -1.2, + "rapidityMax": 1.2, "genDecayed": true }, "Sigma(1385)-" : { @@ -60,6 +72,8 @@ "ptMax": 20, "etaMin": -1.2, "etaMax": 1.2, + "rapidityMin": -1.2, + "rapidityMax": 1.2, "genDecayed": true }, "anti-Sigma(1385)+" : { @@ -69,6 +83,8 @@ "ptMax": 20, "etaMin": -1.2, "etaMax": 1.2, + "rapidityMin": -1.2, + "rapidityMax": 1.2, "genDecayed": true }, "Sigma(1385)+" : { @@ -78,6 +94,8 @@ "ptMax": 20, "etaMin": -1.2, "etaMax": 1.2, + "rapidityMin": -1.2, + "rapidityMax": 1.2, "genDecayed": true }, "anti-Sigma(1385)-" : { @@ -87,6 +105,8 @@ "ptMax": 20, "etaMin": -1.2, "etaMax": 1.2, + "rapidityMin": -1.2, + "rapidityMax": 1.2, "genDecayed": true }, "Lambda(1520)0" : { @@ -96,6 +116,8 @@ "ptMax": 20, "etaMin": -1.2, "etaMax": 1.2, + "rapidityMin": -1.2, + "rapidityMax": 1.2, "genDecayed": true }, "anti-Lambda(1520)0" : { @@ -105,6 +127,8 @@ "ptMax": 20, "etaMin": -1.2, "etaMax": 1.2, + "rapidityMin": -1.2, + "rapidityMax": 1.2, "genDecayed": true }, "Xi(1530)0" : { @@ -114,6 +138,8 @@ "ptMax": 20, "etaMin": -1.2, "etaMax": 1.2, + "rapidityMin": -1.2, + "rapidityMax": 1.2, "genDecayed": true }, "anti-Xi(1530)0" : { @@ -123,6 +149,8 @@ "ptMax": 20, "etaMin": -1.2, "etaMax": 1.2, + "rapidityMin": -1.2, + "rapidityMax": 1.2, "genDecayed": true }, "K1(1270)+": { @@ -132,6 +160,8 @@ "ptMax": 20, "etaMin": -1.2, "etaMax": 1.2, + "rapidityMin": -1.2, + "rapidityMax": 1.2, "genDecayed": true }, "K1(1270)-": { @@ -141,6 +171,8 @@ "ptMax": 20, "etaMin": -1.2, "etaMax": 1.2, + "rapidityMin": -1.2, + "rapidityMax": 1.2, "genDecayed": true }, "Delta++" : { @@ -150,6 +182,8 @@ "ptMax": 20, "etaMin": -1.2, "etaMax": 1.2, + "rapidityMin": -1.2, + "rapidityMax": 1.2, "genDecayed": true }, "anti-Delta++" : { @@ -159,6 +193,8 @@ "ptMax": 20, "etaMin": -1.2, "etaMax": 1.2, + "rapidityMin": -1.2, + "rapidityMax": 1.2, "genDecayed": true }, "Delta0" : { @@ -168,6 +204,8 @@ "ptMax": 20, "etaMin": -1.2, "etaMax": 1.2, + "rapidityMin": -1.2, + "rapidityMax": 1.2, "genDecayed": true }, "anti-Delta0" : { @@ -177,6 +215,8 @@ "ptMax": 20, "etaMin": -1.2, "etaMax": 1.2, + "rapidityMin": -1.2, + "rapidityMax": 1.2, "genDecayed": true }, "Xi(1820)0" : { @@ -186,6 +226,8 @@ "ptMax": 20, "etaMin": -1.2, "etaMax": 1.2, + "rapidityMin": -1.2, + "rapidityMax": 1.2, "genDecayed": true }, "Anti-Xi(1820)0" : { @@ -195,6 +237,8 @@ "ptMax": 20, "etaMin": -1.2, "etaMax": 1.2, + "rapidityMin": -1.2, + "rapidityMax": 1.2, "genDecayed": true }, "Xi(1820)-" : { @@ -204,6 +248,8 @@ "ptMax": 20, "etaMin": -1.2, "etaMax": 1.2, + "rapidityMin": -1.2, + "rapidityMax": 1.2, "genDecayed": true }, "Xi(1820)+" : { @@ -213,6 +259,8 @@ "ptMax": 20, "etaMin": -1.2, "etaMax": 1.2, + "rapidityMin": -1.2, + "rapidityMax": 1.2, "genDecayed": true } } diff --git a/MC/config/PWGLF/pythia8/generator/resonancelistgun_baryonic_inj.json b/MC/config/PWGLF/pythia8/generator/resonancelistgun_baryonic_inj.json new file mode 100644 index 000000000..11a339251 --- /dev/null +++ b/MC/config/PWGLF/pythia8/generator/resonancelistgun_baryonic_inj.json @@ -0,0 +1,46 @@ +{ + "Lambda(1520)0" : { + "pdg": 102134, + "n": 3, + "ptMin": 0.0, + "ptMax": 15, + "etaMin": -1.0, + "etaMax": 1.0, + "rapidityMin": -1.0, + "rapidityMax": 1.0, + "genDecayed": true + }, + "anti-Lambda(1520)0" : { + "pdg": -102134, + "n": 3, + "ptMin": 0.0, + "ptMax": 15, + "etaMin": -1.0, + "etaMax": 1.0, + "rapidityMin": -1.0, + "rapidityMax": 1.0, + "genDecayed": true + }, + "Xi(1530)0" : { + "pdg": 3324, + "n": 3, + "ptMin": 0.0, + "ptMax": 15, + "etaMin": -1.0, + "etaMax": 1.0, + "rapidityMin": -1.0, + "rapidityMax": 1.0, + "genDecayed": true + }, + "anti-Xi(1530)0" : { + "pdg": -3324, + "n": 3, + "ptMin": 0.0, + "ptMax": 15, + "etaMin": -1.0, + "etaMax": 1.0, + "rapidityMin": -1.0, + "rapidityMax": 1.0, + "genDecayed": true + } +} diff --git a/MC/config/PWGLF/pythia8/generator/resonancelistgun_exotic.json b/MC/config/PWGLF/pythia8/generator/resonancelistgun_exotic.json deleted file mode 100644 index 1d1f07fcb..000000000 --- a/MC/config/PWGLF/pythia8/generator/resonancelistgun_exotic.json +++ /dev/null @@ -1,128 +0,0 @@ -{ - "f_0(980)" : { - "pdg": 9010221, - "n": 1, - "ptMin": 0.0, - "ptMax": 20, - "etaMin": -1.2, - "etaMax": 1.2, - "genDecayed": true - }, - "f_0(1370)" : { - "pdg": 10221, - "n": 1, - "ptMin": 0.0, - "ptMax": 20, - "etaMin": -1.2, - "etaMax": 1.2, - "genDecayed": true - }, - "f_0(1500)" : { - "pdg": 9030221, - "n": 1, - "ptMin": 0.0, - "ptMax": 20, - "etaMin": -1.2, - "etaMax": 1.2, - "genDecayed": true - }, - "f_0(1710)" : { - "pdg": 10331, - "n": 1, - "ptMin": 0.0, - "ptMax": 20, - "etaMin": -1.2, - "etaMax": 1.2, - "genDecayed": true - }, - "f_1(1285)" : { - "pdg": 20223, - "n": 1, - "ptMin": 0.0, - "ptMax": 20, - "etaMin": -1.2, - "etaMax": 1.2, - "genDecayed": true - }, - "f_1(1420)" : { - "pdg": 20333, - "n": 1, - "ptMin": 0.0, - "ptMax": 20, - "etaMin": -1.2, - "etaMax": 1.2, - "genDecayed": true - }, - "f_2(1525)" : { - "pdg": 335, - "n": 1, - "ptMin": 0.0, - "ptMax": 20, - "etaMin": -1.2, - "etaMax": 1.2, - "genDecayed": true - }, - "a_2(1230)" : { - "pdg": 115, - "n": 1, - "ptMin": 0.0, - "ptMax": 20, - "etaMin": -1.2, - "etaMax": 1.2, - "genDecayed": true - }, - "K1(1270)+": { - "pdg": 10323, - "n": 1, - "ptMin": 0.0, - "ptMax": 20, - "etaMin": -1.2, - "etaMax": 1.2, - "genDecayed": true - }, - "K1(1270)-": { - "pdg": -10323, - "n": 1, - "ptMin": 0.0, - "ptMax": 20, - "etaMin": -1.2, - "etaMax": 1.2, - "genDecayed": true - }, - "Xi(1820)0" : { - "pdg": 123314, - "n": 1, - "ptMin": 0.0, - "ptMax": 20, - "etaMin": -1.2, - "etaMax": 1.2, - "genDecayed": true - }, - "Anti-Xi(1820)0" : { - "pdg": -123314, - "n": 1, - "ptMin": 0.0, - "ptMax": 20, - "etaMin": -1.2, - "etaMax": 1.2, - "genDecayed": true - }, - "Xi(1820)-" : { - "pdg": 123324, - "n": 1, - "ptMin": 0.0, - "ptMax": 20, - "etaMin": -1.2, - "etaMax": 1.2, - "genDecayed": true - }, - "Xi(1820)+" : { - "pdg": -123324, - "n": 1, - "ptMin": 0.0, - "ptMax": 20, - "etaMin": -1.2, - "etaMax": 1.2, - "genDecayed": true - } -} diff --git a/MC/config/PWGLF/pythia8/generator/resonancelistgun_exoticAll.json b/MC/config/PWGLF/pythia8/generator/resonancelistgun_exoticAll.json new file mode 100644 index 000000000..800756307 --- /dev/null +++ b/MC/config/PWGLF/pythia8/generator/resonancelistgun_exoticAll.json @@ -0,0 +1,112 @@ +{ + "f_2(1270)": { + "pdg": 225, + "n": 3, + "ptMin": 0.0, + "ptMax": 15, + "etaMin": -1.0, + "etaMax": 1.0, + "rapidityMin": -1.0, + "rapidityMax": 1.0, + "genDecayed": true + }, + "f_0(1370)": { + "pdg": 10221, + "n": 3, + "ptMin": 0.0, + "ptMax": 15, + "etaMin": -1.0, + "etaMax": 1.0, + "rapidityMin": -1.0, + "rapidityMax": 1.0, + "genDecayed": true + }, + "f_0(1500)": { + "pdg": 9030221, + "n": 3, + "ptMin": 0.0, + "ptMax": 15, + "etaMin": -1.0, + "etaMax": 1.0, + "rapidityMin": -1.0, + "rapidityMax": 1.0, + "genDecayed": true + }, + "f_0(1710)": { + "pdg": 10331, + "n": 3, + "ptMin": 0.0, + "ptMax": 15, + "etaMin": -1.0, + "etaMax": 1.0, + "rapidityMin": -1.0, + "rapidityMax": 1.0, + "genDecayed": true + }, + "f_1(1285)": { + "pdg": 20223, + "n": 3, + "ptMin": 0.0, + "ptMax": 15, + "etaMin": -1.0, + "etaMax": 1.0, + "rapidityMin": -1.0, + "rapidityMax": 1.0, + "genDecayed": true + }, + "f_1(1420)": { + "pdg": 20333, + "n": 3, + "ptMin": 0.0, + "ptMax": 15, + "etaMin": -1.0, + "etaMax": 1.0, + "rapidityMin": -1.0, + "rapidityMax": 1.0, + "genDecayed": true + }, + "f_2(1525)": { + "pdg": 335, + "n": 3, + "ptMin": 0.0, + "ptMax": 15, + "etaMin": -1.0, + "etaMax": 1.0, + "rapidityMin": -1.0, + "rapidityMax": 1.0, + "genDecayed": true + }, + "a_2(1320)": { + "pdg": 115, + "n": 3, + "ptMin": 0.0, + "ptMax": 15, + "etaMin": -1.0, + "etaMax": 1.0, + "rapidityMin": -1.0, + "rapidityMax": 1.0, + "genDecayed": true + }, + "Lambda(1520)0" : { + "pdg": 102134, + "n": 3, + "ptMin": 0.0, + "ptMax": 15, + "etaMin": -1.0, + "etaMax": 1.0, + "rapidityMin": -1.0, + "rapidityMax": 1.0, + "genDecayed": true + }, + "anti-Lambda(1520)0" : { + "pdg": -102134, + "n": 3, + "ptMin": 0.0, + "ptMax": 15, + "etaMin": -1.0, + "etaMax": 1.0, + "rapidityMin": -1.0, + "rapidityMax": 1.0, + "genDecayed": true + } +} diff --git a/MC/config/PWGLF/pythia8/generator/resonancelistgun_exotic_pbpb.json b/MC/config/PWGLF/pythia8/generator/resonancelistgun_exotic_pbpb.json index 99b38064d..780b2969a 100644 --- a/MC/config/PWGLF/pythia8/generator/resonancelistgun_exotic_pbpb.json +++ b/MC/config/PWGLF/pythia8/generator/resonancelistgun_exotic_pbpb.json @@ -1,74 +1,101 @@ { - "f_0(980)" : { + "f_0(980)": { "pdg": 9010221, "n": 10, "ptMin": 0.0, "ptMax": 20, "etaMin": -1.2, "etaMax": 1.2, + "rapidityMin": -1.2, + "rapidityMax": 1.2, "genDecayed": true }, - "f_0(1370)" : { + "f_2(1270)": { + "pdg": 225, + "n": 1, + "ptMin": 0.0, + "ptMax": 20, + "etaMin": -1.2, + "etaMax": 1.2, + "rapidityMin": -1.2, + "rapidityMax": 1.2, + "genDecayed": true + }, + "f_0(1370)": { "pdg": 10221, "n": 10, "ptMin": 0.0, "ptMax": 20, "etaMin": -1.2, "etaMax": 1.2, + "rapidityMin": -1.2, + "rapidityMax": 1.2, "genDecayed": true }, - "f_0(1500)" : { + "f_0(1500)": { "pdg": 9030221, "n": 10, "ptMin": 0.0, "ptMax": 20, "etaMin": -1.2, "etaMax": 1.2, + "rapidityMin": -1.2, + "rapidityMax": 1.2, "genDecayed": true }, - "f_0(1710)" : { + "f_0(1710)": { "pdg": 10331, "n": 10, "ptMin": 0.0, "ptMax": 20, "etaMin": -1.2, "etaMax": 1.2, + "rapidityMin": -1.2, + "rapidityMax": 1.2, "genDecayed": true }, - "f_1(1285)" : { + "f_1(1285)": { "pdg": 20223, "n": 10, "ptMin": 0.0, "ptMax": 20, "etaMin": -1.2, "etaMax": 1.2, + "rapidityMin": -1.2, + "rapidityMax": 1.2, "genDecayed": true }, - "f_1(1420)" : { + "f_1(1420)": { "pdg": 20333, "n": 10, "ptMin": 0.0, "ptMax": 20, "etaMin": -1.2, "etaMax": 1.2, + "rapidityMin": -1.2, + "rapidityMax": 1.2, "genDecayed": true }, - "f_2(1525)" : { + "f_2(1525)": { "pdg": 335, "n": 10, "ptMin": 0.0, "ptMax": 20, "etaMin": -1.2, "etaMax": 1.2, + "rapidityMin": -1.2, + "rapidityMax": 1.2, "genDecayed": true }, - "a_2(1230)" : { + "a_2(1230)": { "pdg": 115, "n": 1, "ptMin": 0.0, "ptMax": 20, "etaMin": -1.2, "etaMax": 1.2, + "rapidityMin": -1.2, + "rapidityMax": 1.2, "genDecayed": true }, "K1(1270)+": { @@ -78,6 +105,8 @@ "ptMax": 20, "etaMin": -1.2, "etaMax": 1.2, + "rapidityMin": -1.2, + "rapidityMax": 1.2, "genDecayed": true }, "K1(1270)-": { @@ -87,42 +116,52 @@ "ptMax": 20, "etaMin": -1.2, "etaMax": 1.2, + "rapidityMin": -1.2, + "rapidityMax": 1.2, "genDecayed": true }, - "Xi(1820)0" : { + "Xi(1820)0": { "pdg": 123314, "n": 10, "ptMin": 0.0, "ptMax": 20, "etaMin": -1.2, "etaMax": 1.2, + "rapidityMin": -1.2, + "rapidityMax": 1.2, "genDecayed": true }, - "Anti-Xi(1820)0" : { + "Anti-Xi(1820)0": { "pdg": -123314, "n": 10, "ptMin": 0.0, "ptMax": 20, "etaMin": -1.2, "etaMax": 1.2, + "rapidityMin": -1.2, + "rapidityMax": 1.2, "genDecayed": true }, - "Xi(1820)-" : { + "Xi(1820)-": { "pdg": 123324, "n": 10, "ptMin": 0.0, "ptMax": 20, "etaMin": -1.2, "etaMax": 1.2, + "rapidityMin": -1.2, + "rapidityMax": 1.2, "genDecayed": true }, - "Xi(1820)+" : { + "Xi(1820)+": { "pdg": -123324, "n": 10, "ptMin": 0.0, "ptMax": 20, "etaMin": -1.2, "etaMax": 1.2, + "rapidityMin": -1.2, + "rapidityMax": 1.2, "genDecayed": true } -} +} \ No newline at end of file diff --git a/MC/config/PWGLF/pythia8/generator/resonancelistgun_inj.json b/MC/config/PWGLF/pythia8/generator/resonancelistgun_inj.json index e2ff3a233..c15acbf37 100644 --- a/MC/config/PWGLF/pythia8/generator/resonancelistgun_inj.json +++ b/MC/config/PWGLF/pythia8/generator/resonancelistgun_inj.json @@ -6,6 +6,8 @@ "ptMax": 20, "etaMin": -1.2, "etaMax": 1.2, + "rapidityMin": -1.2, + "rapidityMax": 1.2, "genDecayed": true }, "anti-Lambda(1520)0" : { @@ -15,6 +17,8 @@ "ptMax": 20, "etaMin": -1.2, "etaMax": 1.2, + "rapidityMin": -1.2, + "rapidityMax": 1.2, "genDecayed": true }, "f_0(980)" : { @@ -24,6 +28,8 @@ "ptMax": 20, "etaMin": -1.2, "etaMax": 1.2, + "rapidityMin": -1.2, + "rapidityMax": 1.2, "genDecayed": true }, "Xi(1820)0" : { @@ -33,6 +39,8 @@ "ptMax": 20, "etaMin": -1.2, "etaMax": 1.2, + "rapidityMin": -1.2, + "rapidityMax": 1.2, "genDecayed": true }, "Anti-Xi(1820)0" : { @@ -42,6 +50,8 @@ "ptMax": 20, "etaMin": -1.2, "etaMax": 1.2, + "rapidityMin": -1.2, + "rapidityMax": 1.2, "genDecayed": true }, "Xi(1820)-" : { @@ -51,6 +61,8 @@ "ptMax": 20, "etaMin": -1.2, "etaMax": 1.2, + "rapidityMin": -1.2, + "rapidityMax": 1.2, "genDecayed": true }, "Xi(1820)+" : { @@ -60,6 +72,8 @@ "ptMax": 20, "etaMin": -1.2, "etaMax": 1.2, + "rapidityMin": -1.2, + "rapidityMax": 1.2, "genDecayed": true } } diff --git a/MC/config/PWGLF/pythia8/generator/resonancelistgun_inj_pbpb.json b/MC/config/PWGLF/pythia8/generator/resonancelistgun_inj_pbpb.json index 1de68db2e..005c8ca76 100644 --- a/MC/config/PWGLF/pythia8/generator/resonancelistgun_inj_pbpb.json +++ b/MC/config/PWGLF/pythia8/generator/resonancelistgun_inj_pbpb.json @@ -6,6 +6,8 @@ "ptMax": 20, "etaMin": -1.2, "etaMax": 1.2, + "rapidityMin": -1.2, + "rapidityMax": 1.2, "genDecayed": true }, "anti-Lambda(1520)0" : { @@ -15,6 +17,8 @@ "ptMax": 20, "etaMin": -1.2, "etaMax": 1.2, + "rapidityMin": -1.2, + "rapidityMax": 1.2, "genDecayed": true }, "f_0(980)" : { @@ -24,6 +28,8 @@ "ptMax": 20, "etaMin": -1.2, "etaMax": 1.2, + "rapidityMin": -1.2, + "rapidityMax": 1.2, "genDecayed": true }, "Xi(1820)0" : { @@ -33,6 +39,8 @@ "ptMax": 20, "etaMin": -1.2, "etaMax": 1.2, + "rapidityMin": -1.2, + "rapidityMax": 1.2, "genDecayed": true }, "Anti-Xi(1820)0" : { @@ -42,6 +50,8 @@ "ptMax": 20, "etaMin": -1.2, "etaMax": 1.2, + "rapidityMin": -1.2, + "rapidityMax": 1.2, "genDecayed": true }, "Xi(1820)-" : { @@ -51,6 +61,8 @@ "ptMax": 20, "etaMin": -1.2, "etaMax": 1.2, + "rapidityMin": -1.2, + "rapidityMax": 1.2, "genDecayed": true }, "Xi(1820)+" : { @@ -60,6 +72,8 @@ "ptMax": 20, "etaMin": -1.2, "etaMax": 1.2, + "rapidityMin": -1.2, + "rapidityMax": 1.2, "genDecayed": true } } diff --git a/MC/config/PWGLF/pythia8/generator/resonancelistgun_pbpb.json b/MC/config/PWGLF/pythia8/generator/resonancelistgun_pbpb.json index 89413907a..d2f92f44d 100644 --- a/MC/config/PWGLF/pythia8/generator/resonancelistgun_pbpb.json +++ b/MC/config/PWGLF/pythia8/generator/resonancelistgun_pbpb.json @@ -6,6 +6,8 @@ "ptMax": 20, "etaMin": -1.2, "etaMax": 1.2, + "rapidityMin": -1.2, + "rapidityMax": 1.2, "genDecayed": true }, "K(892)-" : { @@ -15,6 +17,8 @@ "ptMax": 20, "etaMin": -1.2, "etaMax": 1.2, + "rapidityMin": -1.2, + "rapidityMax": 1.2, "genDecayed": true }, "f_0(980)" : { @@ -24,6 +28,8 @@ "ptMax": 20, "etaMin": -1.2, "etaMax": 1.2, + "rapidityMin": -1.2, + "rapidityMax": 1.2, "genDecayed": true }, "rho(770)0" : { @@ -33,6 +39,8 @@ "ptMax": 20, "etaMin": -1.2, "etaMax": 1.2, + "rapidityMin": -1.2, + "rapidityMax": 1.2, "genDecayed": true }, "rho(770)+" : { @@ -42,6 +50,8 @@ "ptMax": 20, "etaMin": -1.2, "etaMax": 1.2, + "rapidityMin": -1.2, + "rapidityMax": 1.2, "genDecayed": true }, "rho(770)-" : { @@ -51,6 +61,8 @@ "ptMax": 20, "etaMin": -1.2, "etaMax": 1.2, + "rapidityMin": -1.2, + "rapidityMax": 1.2, "genDecayed": true }, "Sigma(1385)-" : { @@ -60,6 +72,8 @@ "ptMax": 20, "etaMin": -1.2, "etaMax": 1.2, + "rapidityMin": -1.2, + "rapidityMax": 1.2, "genDecayed": true }, "anti-Sigma(1385)+" : { @@ -69,6 +83,8 @@ "ptMax": 20, "etaMin": -1.2, "etaMax": 1.2, + "rapidityMin": -1.2, + "rapidityMax": 1.2, "genDecayed": true }, "Sigma(1385)+" : { @@ -78,6 +94,8 @@ "ptMax": 20, "etaMin": -1.2, "etaMax": 1.2, + "rapidityMin": -1.2, + "rapidityMax": 1.2, "genDecayed": true }, "anti-Sigma(1385)-" : { @@ -87,6 +105,8 @@ "ptMax": 20, "etaMin": -1.2, "etaMax": 1.2, + "rapidityMin": -1.2, + "rapidityMax": 1.2, "genDecayed": true }, "Lambda(1520)0" : { @@ -96,6 +116,8 @@ "ptMax": 20, "etaMin": -1.2, "etaMax": 1.2, + "rapidityMin": -1.2, + "rapidityMax": 1.2, "genDecayed": true }, "anti-Lambda(1520)0" : { @@ -105,6 +127,8 @@ "ptMax": 20, "etaMin": -1.2, "etaMax": 1.2, + "rapidityMin": -1.2, + "rapidityMax": 1.2, "genDecayed": true }, "Xi(1530)0" : { @@ -114,6 +138,8 @@ "ptMax": 20, "etaMin": -1.2, "etaMax": 1.2, + "rapidityMin": -1.2, + "rapidityMax": 1.2, "genDecayed": true }, "anti-Xi(1530)0" : { @@ -123,6 +149,8 @@ "ptMax": 20, "etaMin": -1.2, "etaMax": 1.2, + "rapidityMin": -1.2, + "rapidityMax": 1.2, "genDecayed": true }, "K1(1270)+": { @@ -132,6 +160,8 @@ "ptMax": 20, "etaMin": -1.2, "etaMax": 1.2, + "rapidityMin": -1.2, + "rapidityMax": 1.2, "genDecayed": true }, "K1(1270)-": { @@ -141,6 +171,8 @@ "ptMax": 20, "etaMin": -1.2, "etaMax": 1.2, + "rapidityMin": -1.2, + "rapidityMax": 1.2, "genDecayed": true }, "Delta++" : { @@ -150,6 +182,8 @@ "ptMax": 20, "etaMin": -1.2, "etaMax": 1.2, + "rapidityMin": -1.2, + "rapidityMax": 1.2, "genDecayed": true }, "anti-Delta++" : { @@ -159,6 +193,8 @@ "ptMax": 20, "etaMin": -1.2, "etaMax": 1.2, + "rapidityMin": -1.2, + "rapidityMax": 1.2, "genDecayed": true }, "Delta0" : { @@ -168,6 +204,8 @@ "ptMax": 20, "etaMin": -1.2, "etaMax": 1.2, + "rapidityMin": -1.2, + "rapidityMax": 1.2, "genDecayed": true }, "anti-Delta0" : { @@ -177,6 +215,8 @@ "ptMax": 20, "etaMin": -1.2, "etaMax": 1.2, + "rapidityMin": -1.2, + "rapidityMax": 1.2, "genDecayed": true }, "Xi(1820)0" : { @@ -186,6 +226,8 @@ "ptMax": 20, "etaMin": -1.2, "etaMax": 1.2, + "rapidityMin": -1.2, + "rapidityMax": 1.2, "genDecayed": true }, "Anti-Xi(1820)0" : { @@ -195,6 +237,8 @@ "ptMax": 20, "etaMin": -1.2, "etaMax": 1.2, + "rapidityMin": -1.2, + "rapidityMax": 1.2, "genDecayed": true }, "Xi(1820)-" : { @@ -204,6 +248,8 @@ "ptMax": 20, "etaMin": -1.2, "etaMax": 1.2, + "rapidityMin": -1.2, + "rapidityMax": 1.2, "genDecayed": true }, "Xi(1820)+" : { @@ -213,6 +259,8 @@ "ptMax": 20, "etaMin": -1.2, "etaMax": 1.2, + "rapidityMin": -1.2, + "rapidityMax": 1.2, "genDecayed": true } } diff --git a/MC/config/PWGLF/pythia8/generator/resonancelistgun_trig.json b/MC/config/PWGLF/pythia8/generator/resonancelistgun_trig.json index b8e19d235..de1ad01e1 100644 --- a/MC/config/PWGLF/pythia8/generator/resonancelistgun_trig.json +++ b/MC/config/PWGLF/pythia8/generator/resonancelistgun_trig.json @@ -6,6 +6,8 @@ "ptMax": 20, "etaMin": -1.2, "etaMax": 1.2, + "rapidityMin": -1.2, + "rapidityMax": 1.2, "genDecayed": true }, "K(892)-" : { @@ -15,6 +17,8 @@ "ptMax": 20, "etaMin": -1.2, "etaMax": 1.2, + "rapidityMin": -1.2, + "rapidityMax": 1.2, "genDecayed": true }, "rho(770)0" : { @@ -24,6 +28,8 @@ "ptMax": 20, "etaMin": -1.2, "etaMax": 1.2, + "rapidityMin": -1.2, + "rapidityMax": 1.2, "genDecayed": true }, "rho(770)+" : { @@ -33,6 +39,8 @@ "ptMax": 20, "etaMin": -1.2, "etaMax": 1.2, + "rapidityMin": -1.2, + "rapidityMax": 1.2, "genDecayed": true }, "rho(770)-" : { @@ -42,6 +50,8 @@ "ptMax": 20, "etaMin": -1.2, "etaMax": 1.2, + "rapidityMin": -1.2, + "rapidityMax": 1.2, "genDecayed": true }, "Sigma(1385)-" : { @@ -51,6 +61,8 @@ "ptMax": 20, "etaMin": -1.2, "etaMax": 1.2, + "rapidityMin": -1.2, + "rapidityMax": 1.2, "genDecayed": true }, "anti-Sigma(1385)+" : { @@ -60,6 +72,8 @@ "ptMax": 20, "etaMin": -1.2, "etaMax": 1.2, + "rapidityMin": -1.2, + "rapidityMax": 1.2, "genDecayed": true }, "Sigma(1385)+" : { @@ -69,6 +83,8 @@ "ptMax": 20, "etaMin": -1.2, "etaMax": 1.2, + "rapidityMin": -1.2, + "rapidityMax": 1.2, "genDecayed": true }, "anti-Sigma(1385)-" : { @@ -78,6 +94,8 @@ "ptMax": 20, "etaMin": -1.2, "etaMax": 1.2, + "rapidityMin": -1.2, + "rapidityMax": 1.2, "genDecayed": true }, "Xi(1530)0" : { @@ -87,6 +105,8 @@ "ptMax": 20, "etaMin": -1.2, "etaMax": 1.2, + "rapidityMin": -1.2, + "rapidityMax": 1.2, "genDecayed": true }, "anti-Xi(1530)0" : { @@ -96,6 +116,8 @@ "ptMax": 20, "etaMin": -1.2, "etaMax": 1.2, + "rapidityMin": -1.2, + "rapidityMax": 1.2, "genDecayed": true }, "K1(1270)+": { @@ -105,6 +127,8 @@ "ptMax": 20, "etaMin": -1.2, "etaMax": 1.2, + "rapidityMin": -1.2, + "rapidityMax": 1.2, "genDecayed": true }, "K1(1270)-": { @@ -114,6 +138,8 @@ "ptMax": 20, "etaMin": -1.2, "etaMax": 1.2, + "rapidityMin": -1.2, + "rapidityMax": 1.2, "genDecayed": true }, "Delta++" : { @@ -123,6 +149,8 @@ "ptMax": 20, "etaMin": -1.2, "etaMax": 1.2, + "rapidityMin": -1.2, + "rapidityMax": 1.2, "genDecayed": true }, "anti-Delta++" : { @@ -132,6 +160,8 @@ "ptMax": 20, "etaMin": -1.2, "etaMax": 1.2, + "rapidityMin": -1.2, + "rapidityMax": 1.2, "genDecayed": true }, "Delta0" : { @@ -141,6 +171,8 @@ "ptMax": 20, "etaMin": -1.2, "etaMax": 1.2, + "rapidityMin": -1.2, + "rapidityMax": 1.2, "genDecayed": true }, "anti-Delta0" : { @@ -150,6 +182,8 @@ "ptMax": 20, "etaMin": -1.2, "etaMax": 1.2, + "rapidityMin": -1.2, + "rapidityMax": 1.2, "genDecayed": true } } diff --git a/MC/config/PWGLF/pythia8/generator/resonancelistgun_trig_pbpb.json b/MC/config/PWGLF/pythia8/generator/resonancelistgun_trig_pbpb.json index b778543df..f2c692e5a 100644 --- a/MC/config/PWGLF/pythia8/generator/resonancelistgun_trig_pbpb.json +++ b/MC/config/PWGLF/pythia8/generator/resonancelistgun_trig_pbpb.json @@ -6,6 +6,8 @@ "ptMax": 20, "etaMin": -1.2, "etaMax": 1.2, + "rapidityMin": -1.2, + "rapidityMax": 1.2, "genDecayed": true }, "K(892)-" : { @@ -15,6 +17,8 @@ "ptMax": 20, "etaMin": -1.2, "etaMax": 1.2, + "rapidityMin": -1.2, + "rapidityMax": 1.2, "genDecayed": true }, "rho(770)0" : { @@ -24,6 +28,8 @@ "ptMax": 20, "etaMin": -1.2, "etaMax": 1.2, + "rapidityMin": -1.2, + "rapidityMax": 1.2, "genDecayed": true }, "rho(770)+" : { @@ -33,6 +39,8 @@ "ptMax": 20, "etaMin": -1.2, "etaMax": 1.2, + "rapidityMin": -1.2, + "rapidityMax": 1.2, "genDecayed": true }, "rho(770)-" : { @@ -42,6 +50,8 @@ "ptMax": 20, "etaMin": -1.2, "etaMax": 1.2, + "rapidityMin": -1.2, + "rapidityMax": 1.2, "genDecayed": true }, "Sigma(1385)-" : { @@ -51,6 +61,8 @@ "ptMax": 20, "etaMin": -1.2, "etaMax": 1.2, + "rapidityMin": -1.2, + "rapidityMax": 1.2, "genDecayed": true }, "anti-Sigma(1385)+" : { @@ -60,6 +72,8 @@ "ptMax": 20, "etaMin": -1.2, "etaMax": 1.2, + "rapidityMin": -1.2, + "rapidityMax": 1.2, "genDecayed": true }, "Sigma(1385)+" : { @@ -69,6 +83,8 @@ "ptMax": 20, "etaMin": -1.2, "etaMax": 1.2, + "rapidityMin": -1.2, + "rapidityMax": 1.2, "genDecayed": true }, "anti-Sigma(1385)-" : { @@ -78,6 +94,8 @@ "ptMax": 20, "etaMin": -1.2, "etaMax": 1.2, + "rapidityMin": -1.2, + "rapidityMax": 1.2, "genDecayed": true }, "Xi(1530)0" : { @@ -87,6 +105,8 @@ "ptMax": 20, "etaMin": -1.2, "etaMax": 1.2, + "rapidityMin": -1.2, + "rapidityMax": 1.2, "genDecayed": true }, "anti-Xi(1530)0" : { @@ -96,6 +116,8 @@ "ptMax": 20, "etaMin": -1.2, "etaMax": 1.2, + "rapidityMin": -1.2, + "rapidityMax": 1.2, "genDecayed": true }, "K1(1270)+": { @@ -105,6 +127,8 @@ "ptMax": 20, "etaMin": -1.2, "etaMax": 1.2, + "rapidityMin": -1.2, + "rapidityMax": 1.2, "genDecayed": true }, "K1(1270)-": { @@ -114,6 +138,8 @@ "ptMax": 20, "etaMin": -1.2, "etaMax": 1.2, + "rapidityMin": -1.2, + "rapidityMax": 1.2, "genDecayed": true }, "Delta++" : { @@ -123,6 +149,8 @@ "ptMax": 20, "etaMin": -1.2, "etaMax": 1.2, + "rapidityMin": -1.2, + "rapidityMax": 1.2, "genDecayed": true }, "anti-Delta++" : { @@ -132,6 +160,8 @@ "ptMax": 20, "etaMin": -1.2, "etaMax": 1.2, + "rapidityMin": -1.2, + "rapidityMax": 1.2, "genDecayed": true }, "Delta0" : { @@ -141,6 +171,8 @@ "ptMax": 20, "etaMin": -1.2, "etaMax": 1.2, + "rapidityMin": -1.2, + "rapidityMax": 1.2, "genDecayed": true }, "anti-Delta0" : { @@ -150,6 +182,8 @@ "ptMax": 20, "etaMin": -1.2, "etaMax": 1.2, + "rapidityMin": -1.2, + "rapidityMax": 1.2, "genDecayed": true } } diff --git a/MC/config/PWGLF/pythia8/generator/resonances.cfg b/MC/config/PWGLF/pythia8/generator/resonances.cfg index 628ba85e2..d35eaba2e 100644 --- a/MC/config/PWGLF/pythia8/generator/resonances.cfg +++ b/MC/config/PWGLF/pythia8/generator/resonances.cfg @@ -1,31 +1,17 @@ ### Define resonance ProcessLevel:all = off # will not look for the 'process' +102132:all = Lambda1405 Lambda1405bar 4 0 0 1.40500 0.05000 1.30 1.50 0 +102132:oneChannel = 1 0.33333 5 3112 211 +102132:addChannel = 1 0.33333 5 3222 -211 +102132:addChannel = 1 0.33333 5 3212 111 + # id::all = name antiName spinType chargeType colType m0 mWidth mMin mMax tau0 +### Lambda1520 102134:all = Lambda1520 Lambda1520bar 4 0 0 1.51950 0.01560 1.47 1.60 0 - -### add Resonance decays absent in PYTHIA8 decay table and set BRs from PDG for other -102134:oneChannel = 1 0.229944 5 2212 -321 -102134:addChannel = 1 0.229944 5 2112 -311 -102134:addChannel = 1 0.143076 5 3222 -211 -102134:addChannel = 1 0.143076 5 3212 111 -102134:addChannel = 1 0.143076 5 3112 211 -102134:addChannel = 1 0.034066 4 3224 -211 -102134:addChannel = 1 0.034066 4 3214 111 -102134:addChannel = 1 0.034066 4 3114 211 -102134:addChannel = 1 0.008687 3 3122 22 - +102134:oneChannel = 1 1.000 0 2212 -321 102134:onMode = off - 102134:onIfMatch = 2212 -321 -102134:onIfMatch = 2112 -311 -102134:onIfMatch = 3222 -211 -102134:onIfMatch = 3212 111 -102134:onIfMatch = 3112 211 -102134:onIfMatch = 3224 -211 -102134:onIfMatch = 3214 111 -102134:onIfMatch = 3114 211 -102134:onIfMatch = 3122 22 ### Xi1820 123324:all = Xi1820 Xi1820bar 0 0 0 1.8234 0.0 0.0 0.0 0 @@ -54,22 +40,32 @@ ProcessLevel:all = off # will not look for the 'process' 20333:onIfMatch = 310 321 -211 ### glueball hunting -9030221:all = f_0(1500) f_0(1500) 3 0 0 1.50600 0.11200 1.40000 1.60000 0 +9030221:all = f_0(1500) f_0(1500) 0 0 0 1.50600 0.11200 1.40000 1.60000 0 9030221:oneChannel = 1 1.000 0 310 310 9030221:onMode = off 9030221:onIfMatch = 310 310 -10331:all = f_0(1710) f_0(1710) 3 0 0 1.72000 0.13500 1.10000 2.40000 0 +10331:all = f_0(1710) f_0(1710) 0 0 0 1.71000 0.15000 1.10000 2.40000 0 10331:oneChannel = 1 1.000 0 310 310 10331:onMode = off 10331:onIfMatch = 310 310 -335:all = f_2(1525) f_2(1525) 5 0 0 1.52500 0.07300 1.10000 2.00000 0 +335:all = f_2(1525) f_2(1525) 4 0 0 1.52500 0.08400 1.10000 2.00000 0 335:oneChannel = 1 1.000 0 310 310 335:onMode = off 335:onIfMatch = 310 310 -10221:all = f_0(1370) f_0(1370) 3 0 0 1.35000 0.20000 0.80000 2.00000 0 +10221:all = f_0(1370) f_0(1370) 0 0 0 1.35000 0.20000 0.80000 2.00000 0 10221:oneChannel = 1 1.000 0 310 310 10221:onMode = off 10221:onIfMatch = 310 310 + +225:all = f_2(1270) f_2(1270) 4 0 0 1.27500 0.1860 1.10000 1.50000 0 +225:oneChannel = 1 1.000 0 310 310 +225:onMode = off +225:onIfMatch = 310 310 + +115:all = a_2(1320) a_2(1320) 4 0 0 1.31820 0.10780 1.10000 1.50000 0 +115:oneChannel = 1 1.000 0 310 310 +115:onMode = off +115:onIfMatch = 310 310 diff --git a/MC/config/PWGLF/pythia8/generator/resonances_baryonic.cfg b/MC/config/PWGLF/pythia8/generator/resonances_baryonic.cfg new file mode 100644 index 000000000..e05459994 --- /dev/null +++ b/MC/config/PWGLF/pythia8/generator/resonances_baryonic.cfg @@ -0,0 +1,28 @@ +### Define resonance +ProcessLevel:all = off # will not look for the 'process' + +### Lambda1520 +# id::all = name antiName spinType chargeType colType m0 mWidth mMin mMax tau0 +102134:all = Lambda1520 Lambda1520bar 4 0 0 1.51950 0.01560 1.47 1.60 0 +102134:oneChannel = 1 1.000 0 2212 -321 +102134:onMode = off +102134:onIfMatch = 2212 -321 + +### Xi1530 +# id::all = name antiName spinType chargeType colType m0 mWidth mMin mMax tau0 +3324:all = Xi1530 Xi1530bar 4 0 0 1.53180 0.0091 1.50 1.59 0 +3324:oneChannel = 1 1.000 0 3312 211 +3324:onMode = off +3324:onIfMatch = 3312 211 + +### Xi1820 +123324:all = Xi1820 Xi1820bar 4 0 0 1.823 0.024 1.75 1.95 0 +123324:oneChannel = 1 1.000 0 3122 310 +123324:onMode = off +123324:onIfMatch = 3122 310 + +123314:all = Xi1820Minus Xi1820Plus 4 -3 0 1.823 0.024 1.75 1.95 0 +123314:oneChannel = 1 1.000 0 3122 -321 +123314:onMode = off +123314:onIfMatch = 3122 -321 + diff --git a/MC/config/PWGLF/pythia8/generator/sigmapi_resonances_gun.json b/MC/config/PWGLF/pythia8/generator/sigmapi_resonances_gun.json new file mode 100644 index 000000000..6d7e4b2b3 --- /dev/null +++ b/MC/config/PWGLF/pythia8/generator/sigmapi_resonances_gun.json @@ -0,0 +1,29 @@ +{ + "lambda(1405)" : { + "pdg": 102132, + "n": 2, + "ptMin": 0.0, + "ptMax": 10, + "etaMin": -1.2, + "etaMax": 1.2, + "genDecayed": true + }, + "lambda(1520)" : { + "pdg": 102134, + "n": 2, + "ptMin": 0.0, + "ptMax": 10, + "etaMin": -1.2, + "etaMax": 1.2, + "genDecayed": true + }, + "sigma(1385)" : { + "pdg": 3214, + "n": 2, + "ptMin": 0.0, + "ptMax": 10, + "etaMin": -1.2, + "etaMax": 1.2, + "genDecayed": true + } +} diff --git a/MC/config/PWGLF/pythia8/generator_pythia8_LF_rapidity.C b/MC/config/PWGLF/pythia8/generator_pythia8_LF_rapidity.C new file mode 100644 index 000000000..0a10286dd --- /dev/null +++ b/MC/config/PWGLF/pythia8/generator_pythia8_LF_rapidity.C @@ -0,0 +1,721 @@ +/// +/// \file generator_pythia8_LF_rapidity.C +/// \author Hirak Kumar Koley hirak.koley@cern.ch +/// \author Bong-Hwi Lim bong-hwi.lim@cern.ch +/// \author Based on generator_pythia8_LF.C by Nicolò Jacazio +/// \since 2025/08/18 +/// \brief Implementation of a gun generator for multiple particles using rapidity or pseudorapidity (default) instead of eta, built on generator_pythia8_longlived.C +/// Needs PDG, Number of injected, minimum and maximum pT, minimum and maximum y/eta. These can be provided in three ways, bundeling variables, particles or from input file +/// usage: +/// `o2-sim -g external --configKeyValues 'GeneratorExternal.fileName=generator_pythia8_LF_rapidity.C;GeneratorExternal.funcName=generateLFRapidity({1000010020, 1000010030}, {10, 10}, {0.5, 0.5}, {10, 10}, {-1.0, -1.0}, {1.0, 1.0})'` +/// Here PDG, Number injected, pT limits, y/eta limits are separated and matched by index +/// or: +/// `o2-sim -g external --configKeyValues 'GeneratorExternal.fileName=generator_pythia8_LF_rapidity.C;GeneratorExternal.funcName=generateLFRapidity({{1000010020, 10, 0.5, 10, -1.0, 1.0}, {1000010030, 10, 0.5, 10, -1.0, 1.0}})'` +/// Here PDG, Number injected, pT limits, y/eta limits are divided per particle +/// or: +/// `o2-sim -g external --configKeyValues 'GeneratorExternal.fileName=generator_pythia8_LF_rapidity.C;GeneratorExternal.funcName=generateLFRapidity("${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGLF/pythia8/generator/exotic_nuclei_pp.gun")'` +/// Here PDG, Number injected, pT limits, y/eta limits are provided via an intermediate configuration file +/// + +#if !defined(__CLING__) || defined(__ROOTCLING__) +#include "FairGenerator.h" + +#include "TDatabasePDG.h" +#include "TMath.h" +#include "TParticlePDG.h" +#include "TRandom3.h" + +#include "Generators/GeneratorPythia8.h" +#include "Pythia8/Pythia.h" +#if __has_include("SimulationDataFormat/MCGenStatus.h") +#include "SimulationDataFormat/MCGenStatus.h" +#else +#include "SimulationDataFormat/MCGenProperties.h" +#endif +#if __has_include("SimulationDataFormat/MCUtils.h") +#include "SimulationDataFormat/MCUtils.h" +#endif +#include "TSystem.h" + +#include "Generators/GeneratorPythia8Param.h" +#include "fairlogger/Logger.h" + +#include +#include +#endif +// DecayerPythia8Param needs to be included after the #endif to work with Cling +#include "Generators/DecayerPythia8Param.h" +#if defined(__CLING__) && !defined(__ROOTCLING__) +#if __has_include("SimulationDataFormat/MCGenStatus.h") +#include "SimulationDataFormat/MCGenStatus.h" +#elif __has_include("SimulationDataFormat/MCGenProperties.h") +#include "SimulationDataFormat/MCGenProperties.h" +#endif +#if __has_include("SimulationDataFormat/MCUtils.h") +#include "SimulationDataFormat/MCUtils.h" +#endif +#pragma cling load("libO2Generators") +#endif +// #include "Generators/GeneratorPythia8.h" +#include "generator_pythia8_longlived.C" + +#include + +using namespace Pythia8; +using namespace o2::mcgenstatus; + +class GeneratorPythia8LFRapidity : public o2::eventgen::GeneratorPythia8 +{ + public: + /// Parametric constructor + GeneratorPythia8LFRapidity(bool injOnePerEvent = true, + int gapBetweenInjection = 0, + bool useTrigger = false, + bool useRapidity = false, + std::string pythiaCfgMb = "${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGLF/pythia8/generator/pythia8_inel_136tev.cfg", + std::string pythiaCfgSignal = "${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGLF/pythia8/generator/pythia8_inel_136tev.cfg") : GeneratorPythia8{}, + mOneInjectionPerEvent{injOnePerEvent}, + mGapBetweenInjection{gapBetweenInjection}, + mUseTriggering{useTrigger}, + mUseRapidity{useRapidity} + { + LOG(info) << "GeneratorPythia8LFRapidity constructor"; + LOG(info) << "++ mOneInjectionPerEvent: " << mOneInjectionPerEvent; + LOG(info) << "++ mGapBetweenInjection: " << mGapBetweenInjection; + LOG(info) << "++ mUseTriggering: " << mUseTriggering; + LOG(info) << "++ mUseRapidity: " << mUseRapidity; + LOG(info) << "++ pythiaCfgMb: " << pythiaCfgMb; + LOG(info) << "++ pythiaCfgSignal: " << pythiaCfgSignal; + gRandom->SetSeed(0); + if (useTrigger) { + mPythia.readString("ProcessLevel:all off"); + if (pythiaCfgMb == "") { // If no configuration file is provided, use the one from the Pythia8Param + auto& param = o2::eventgen::GeneratorPythia8Param::Instance(); + LOG(info) << "Instance LFRapidity \'Pythia8\' generator with following parameters for MB event"; + LOG(info) << param; + pythiaCfgMb = param.config; + } + if (pythiaCfgSignal == "") { // If no configuration file is provided, use the one from the Pythia8Param + auto& param = o2::eventgen::GeneratorPythia8Param::Instance(); + LOG(info) << "Instance LFRapidity \'Pythia8\' generator with following parameters for signal event"; + LOG(info) << param; + pythiaCfgSignal = param.config; + } + pythiaCfgMb = gSystem->ExpandPathName(pythiaCfgMb.c_str()); + pythiaCfgSignal = gSystem->ExpandPathName(pythiaCfgSignal.c_str()); + LOG(info) << " ++ Using trigger, initializing Pythia8 for trigger"; + if (!pythiaObjectMinimumBias.readFile(pythiaCfgMb)) { + LOG(fatal) << "Could not pythiaObjectMinimumBias.readFile(\"" << pythiaCfgMb << "\")"; + } + pythiaObjectMinimumBias.readString("Random:setSeed = on"); + pythiaObjectMinimumBias.readString("Random:seed =" + std::to_string(gRandom->Integer(900000000 - 2) + 1)); + + // FIX: Init signal pythia object + if (!pythiaObjectSignal.readFile(pythiaCfgSignal)) { + LOG(fatal) << "Could not pythiaObjectSignal.readFile(\"" << pythiaCfgSignal << "\")"; + } + pythiaObjectSignal.readString("Random:setSeed = on"); + pythiaObjectSignal.readString("Random:seed =" + std::to_string(gRandom->Integer(900000000 - 2) + 1)); + pythiaObjectMinimumBias.particleData.addParticle(1000100200, "20Ne", 6, 30, 0, 19.992440); + mPythiaGun.particleData.addParticle(1000100200, "20Ne", 6, 30, 0, 19.992440); + if (!pythiaObjectMinimumBias.init()) { + LOG(fatal) << "Could not pythiaObjectMinimumBias.init() from " << pythiaCfgMb; + } + if (!pythiaObjectSignal.init()) { + LOG(fatal) << "Could not pythiaObjectSignal.init() from " << pythiaCfgSignal; + } + } else { // Using simple injection with internal decay (if needed). Fetching the parameters from the configuration file of the PythiaDecayer + + if (pythiaCfgMb == "") { // If no configuration file is provided, use the one from the Pythia8Param + auto& param = o2::eventgen::GeneratorPythia8Param::Instance(); + LOG(info) << "Instance LFRapidity \'Pythia8\' generator with following parameters for MB event"; + LOG(info) << param; + pythiaCfgMb = param.config; + } + // FIX: Fallback if still empty to default minbias + if (pythiaCfgMb == "") { + pythiaCfgMb = "${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGLF/pythia8/generator/pythia8_inel_136tev.cfg"; + } + pythiaCfgMb = gSystem->ExpandPathName(pythiaCfgMb.c_str()); + if (!pythiaObjectMinimumBias.readFile(pythiaCfgMb)) { + LOG(fatal) << "Could not pythiaObjectMinimumBias.readFile(\"" << pythiaCfgMb << "\")"; + } + pythiaObjectMinimumBias.readString("Random:setSeed = on"); + pythiaObjectMinimumBias.readString("Random:seed =" + std::to_string(gRandom->Integer(900000000 - 2) + 1)); + + pythiaObjectMinimumBias.particleData.addParticle(1000100200, "20Ne", 6, 30, 0, 19.992440); + mPythiaGun.particleData.addParticle(1000100200, "20Ne", 6, 30, 0, 19.992440); + if (!pythiaObjectMinimumBias.init()) { + LOG(fatal) << "Could not pythiaObjectMinimumBias.init() from " << pythiaCfgMb; + } + + /** switch off process level **/ + mPythiaGun.readString("ProcessLevel:all off"); + + auto& param = o2::eventgen::DecayerPythia8Param::Instance(); + LOG(info) << "Init \'GeneratorPythia8LFRapidity\' with following parameters"; + LOG(info) << param; + for (int i = 0; i < 8; ++i) { + if (param.config[i].empty()) { + continue; + } + std::string config = gSystem->ExpandPathName(param.config[i].c_str()); + LOG(info) << "GeneratorPythia8LFRapidity Reading configuration from file: " << config; + if (!mPythiaGun.readFile(config, true)) { + LOG(fatal) << "Failed to init \'DecayerPythia8\': problems with configuration file " + << config; + return; + } + } + + /** show changed particle data **/ + if (param.showChanged) { + mPythiaGun.readString(std::string("Init:showChangedParticleData on")); + } else { + mPythiaGun.readString(std::string("Init:showChangedParticleData off")); + } + + /** initialise **/ + if (!mPythiaGun.init()) { + LOG(fatal) << "Failed to init \'DecayerPythia8\': init returned with error"; + return; + } + if (pythiaCfgSignal != "") { + LOG(fatal) << "Cannot use simple injection and have a configuration file. pythiaCfgSignal= `" << pythiaCfgSignal << "` must be empty"; + } + } + } + + /// Destructor + ~GeneratorPythia8LFRapidity() = default; + + //__________________________________________________________________ + Bool_t generateEvent() override + { + if (!mUseTriggering) { // Injected mode: Embedding into MB + // 1. Generate Background (MB) + // LOG(info) << "Generating background event " << mEventCounter; + + bool lGenerationOK = false; + while (!lGenerationOK) { + lGenerationOK = pythiaObjectMinimumBias.next(); + } + mPythia.event = pythiaObjectMinimumBias.event; + + // 2. Determine if we inject specific particles (Gap logic) + bool doInjection = true; + if (mGapBetweenInjection > 0) { + if (mGapBetweenInjection == 1 && mEventCounter % 2 == 0) { + doInjection = false; + } else if (mEventCounter % mGapBetweenInjection != 0) { + doInjection = false; + } + } + + if (!doInjection) { + LOG(info) << "Skipping injection for event " << mEventCounter; + return true; + } + } + + LOG(info) << "generateEvent (Injection) " << mEventCounter; + + // For Triggered mode, we start clean. For Injected mode, we have MB in mPythia.event + if (mUseTriggering) { + mPythia.event.reset(); + } + + mConfigToUse = mOneInjectionPerEvent ? static_cast(gRandom->Uniform(0.f, getNGuns())) : -1; + LOG(info) << "Using configuration " << mConfigToUse << " out of " << getNGuns() << ", of which " << mGunConfigs.size() << " are transport decayed and " << mGunConfigsGenDecayed.size() << " are generator decayed"; + + bool injectedForThisEvent = false; + int nConfig = mGunConfigs.size(); // We start counting from the configurations of the transport decayed particles + for (const ConfigContainer& cfg : mGunConfigsGenDecayed) { + nConfig++; + if (mConfigToUse >= 0 && (nConfig - 1) != mConfigToUse) { + continue; + } + LOG(info) << "Using config container "; + cfg.print(); + if (mUseTriggering) { // Do the triggering + bool doSignal{mEventCounter % (mGapBetweenInjection + 1) == 0}; // Do signal or gap + + if (doSignal) { + LOG(info) << "Generating triggered signal event for particle"; + cfg.print(); + bool satisfiesTrigger = false; + int nTries = 0; + while (!satisfiesTrigger) { + if (!pythiaObjectSignal.next()) { + continue; + } + // Check if triggered condition satisfied + for (int j = 0; j < pythiaObjectSignal.event.size(); j++) { + const int& pypid = pythiaObjectSignal.event[j].id(); + const float& pyeta = mUseRapidity ? pythiaObjectSignal.event[j].y() : pythiaObjectSignal.event[j].eta(); + const float& pypt = pythiaObjectSignal.event[j].pT(); + if (pypid == cfg.mPdg && cfg.mMin < pyeta && pyeta < cfg.mMax && pypt > cfg.mPtMin && pypt < cfg.mPtMax) { + LOG(info) << "Found particle " << j << " " << pypid << " with " << (mUseRapidity ? "rapidity" : "eta") << " " << pyeta << " and pT " << pypt << " in event " << mEventCounter << " after " << nTries << " tries"; + satisfiesTrigger = true; + break; + } + } + nTries++; + } + mPythia.event = pythiaObjectSignal.event; + } else { + LOG(info) << "Generating background event " << mEventCounter; + // Generate minimum-bias event + bool lGenerationOK = false; + while (!lGenerationOK) { + lGenerationOK = pythiaObjectMinimumBias.next(); + } + mPythia.event = pythiaObjectMinimumBias.event; + } + continue; + } + + // Do the injection + // Use mPythiaGun for separate generation and decay + mPythiaGun.event.reset(); + for (int i{0}; i < cfg.mNInject; ++i) { + const double pt = gRandom->Uniform(cfg.mPtMin, cfg.mPtMax); + const double eta = gRandom->Uniform(cfg.mMin, cfg.mMax); + const double phi = gRandom->Uniform(0, TMath::TwoPi()); + const double px{pt * std::cos(phi)}; + const double py{pt * std::sin(phi)}; + + double pz = 0; + double et = 0; + + if (mUseRapidity) { + // Rapidty Case + const double mT = std::sqrt(cfg.mMass * cfg.mMass + pt * pt); + pz = mT * std::sinh(eta); + et = mT * std::cosh(eta); + } else { + // Eta Case + pz = pt * std::sinh(eta); + const double p = pt * std::cosh(eta); + et = std::sqrt(p * p + cfg.mMass * cfg.mMass); + } + + Particle particle; + particle.id(cfg.mPdg); + particle.status(11); + particle.m(cfg.mMass); + particle.px(px); + particle.py(py); + particle.pz(pz); + particle.e(et); + particle.xProd(0.f); + particle.yProd(0.f); + particle.zProd(0.f); + mPythiaGun.particleData.mayDecay(cfg.mPdg, true); // force decay + mPythiaGun.event.append(particle); + } + // Decay the gun particles + mPythiaGun.moreDecays(); + mPythiaGun.next(); + + // Merge mPythiaGun event into mPythia.event (MB) + int offset = mPythia.event.size(); + LOG(info) << "Merging " << mPythiaGun.event.size() - 1 << " injected particles into MB event of size " << offset; + + for (int i = 1; i < mPythiaGun.event.size(); ++i) { // Skip system particle 0 + Particle& p = mPythiaGun.event[i]; + // Adjust history indices + int mother1 = p.mother1(); + int mother2 = p.mother2(); + int daughter1 = p.daughter1(); + int daughter2 = p.daughter2(); + + if (mother1 > 0) + mother1 += offset - 1; + if (mother2 > 0) + mother2 += offset - 1; + if (daughter1 > 0) + daughter1 += offset - 1; + if (daughter2 > 0) + daughter2 += offset - 1; + + p.mothers(mother1, mother2); + p.daughters(daughter1, daughter2); + + mPythia.event.append(p); + } + + injectedForThisEvent = true; + } + + // For purely trivial injection (no generator decay needed in loop or just transport decay), we still might have injection flag + // But above loop covers generator decayed. + // What if we only have Transport Decay particles? (mGunConfigs) + // We treat them in importParticles usually. + // But if we are in embedding mode, we just need to ensure the MB event is there. + // The mGunConfigs are handled in importParticles. + + if (mVerbose) { + LOG(info) << "Eventlisting"; + mPythia.event.list(1); + mPythia.stat(); + } + return true; + } + + //__________________________________________________________________ + Bool_t importParticles() override + { + if (!mUseTriggering) { // If the triggering is used we handle the the gap when generating the signal + if (mGapBetweenInjection > 0) { + if (mGapBetweenInjection == 1 && mEventCounter % 2 == 0) { + LOG(info) << "Skipping importParticles event " << mEventCounter++; + return true; + } else if (mEventCounter % mGapBetweenInjection != 0) { + LOG(info) << "Skipping importParticles event " << mEventCounter++; + return true; + } + } + } + LOG(info) << "importParticles " << mEventCounter++; + GeneratorPythia8::importParticles(); + int nConfig = 0; + for (const ConfigContainer& cfg : mGunConfigs) { + nConfig++; + if (mConfigToUse >= 0 && (nConfig - 1) != mConfigToUse) { + continue; + } + LOGF(info, "Injecting %i particles with PDG %i, pT in [%f, %f], %s in [%f, %f]", cfg.mNInject, cfg.mPdg, cfg.mPtMin, cfg.mPtMax, (mUseRapidity ? "rapidity" : "eta"), cfg.mMin, cfg.mMax); + + for (int i{0}; i < cfg.mNInject; ++i) { + const double pt = gRandom->Uniform(cfg.mPtMin, cfg.mPtMax); + const double eta = gRandom->Uniform(cfg.mMin, cfg.mMax); + const double phi = gRandom->Uniform(0, TMath::TwoPi()); + const double px{pt * std::cos(phi)}; + const double py{pt * std::sin(phi)}; + double pz = 0; + double et = 0; + + if (mUseRapidity) { + const double mT = std::sqrt(cfg.mMass * cfg.mMass + pt * pt); + pz = mT * std::sinh(eta); + et = mT * std::cosh(eta); + } else { + pz = pt * std::sinh(eta); + const double p = pt * std::cosh(eta); + et = std::sqrt(p * p + cfg.mMass * cfg.mMass); + } + + // TParticle::TParticle(Int_t pdg, + // Int_t status, + // Int_t mother1, Int_t mother2, + // Int_t daughter1, Int_t daughter2, + // Double_t px, Double_t py, Double_t pz, Double_t etot, + // Double_t vx, Double_t vy, Double_t vz, Double_t time) + + mParticles.push_back(TParticle(cfg.mPdg, + MCGenStatusEncoding(1, 1).fullEncoding, + -1, -1, + -1, -1, + px, py, pz, et, + 0., 0., 0., 0.)); + // make sure status code is encoded properly. Transport flag will be set by default and we have nothing + // to do since all pushed particles should be tracked. + o2::mcutils::MCGenHelper::encodeParticleStatusAndTracking(mParticles.back()); + } + nConfig++; + } + if (mVerbose) { + LOG(info) << "Printing particles that are appended"; + int n = 0; + for (const auto& p : mParticles) { + LOG(info) << "Particle " << n++ << " is a " << p.GetPdgCode() << " with status " << p.GetStatusCode() << " and px = " << p.Py() << " py = " << p.Py() << " pz = " << p.Pz(); + } + } + return true; + } + + struct ConfigContainer { + ConfigContainer(int input_pdg = 0, int n = 1, + float ptMin = 1, float ptMax = 10, + float min = -1, float max = 1) : mPdg{input_pdg}, + mNInject{n}, + mPtMin{ptMin}, + mPtMax{ptMax}, + mMin{min}, + mMax{max} + { + // mMass = getMassFromPDG(mPdg); + mMass = GeneratorPythia8LongLivedGun::getMass(mPdg); + if (mMass <= 0) { + LOG(fatal) << "Could not find mass for mPdg " << mPdg; + } + LOGF(info, "ConfigContainer: mPdg = %i, mNInject = %i, mPtMin = %f, mPtMax = %f, mMin = %f, mMax = %f, mMass = %f", + mPdg, mNInject, mPtMin, mPtMax, mMin, mMax, mMass); + }; + + ConfigContainer(TObjArray* arr) : ConfigContainer(atoi(arr->At(0)->GetName()), + atoi(arr->At(1)->GetName()), + atof(arr->At(2)->GetName()), + atof(arr->At(3)->GetName()), + atof(arr->At(4)->GetName()), + atof(arr->At(5)->GetName())) + { + bool hasGenDecayed = false; + for (int i = 0; i < arr->GetEntries(); i++) { + const TString n = arr->At(i)->GetName(); + std::cout << n << std::endl; + if (n == "genDecayed") { + hasGenDecayed = true; + break; + } + } + if (hasGenDecayed) { + if (arr->GetEntries() != 7) { + LOG(fatal) << "Wrong number of entries in the configuration array, should be 7, is " << arr->GetEntries(); + } + } else { + if (arr->GetEntries() != 6) { + LOG(fatal) << "Wrong number of entries in the configuration array, should be 6, is " << arr->GetEntries(); + } + } + }; + ConfigContainer(TString line) : ConfigContainer(line.Tokenize(" ")) {}; + ConfigContainer(const nlohmann::json& jsonParams, bool useRapidity = false) : ConfigContainer(jsonParams["pdg"], + jsonParams["n"], + jsonParams["ptMin"], + jsonParams["ptMax"], + (useRapidity && jsonParams.contains("rapidityMin")) ? jsonParams["rapidityMin"] : (jsonParams.contains("min") ? jsonParams["min"] : jsonParams["etaMin"]), + (useRapidity && jsonParams.contains("rapidityMax")) ? jsonParams["rapidityMax"] : (jsonParams.contains("max") ? jsonParams["max"] : jsonParams["etaMax"])) {}; + + // Data Members + const int mPdg = 0; + const int mNInject = 1; + const float mPtMin = 1; + const float mPtMax = 10; + const float mMin = -1.f; + const float mMax = 1.f; + double mMass = 0.f; + + void print() const + { + LOGF(info, "int mPdg = %i", mPdg); + LOGF(info, "int mNInject = %i", mNInject); + LOGF(info, "float mPtMin = %f", mPtMin); + LOGF(info, "float mPtMax = %f", mPtMax); + LOGF(info, "float mMin = %f", mMin); + LOGF(info, "float mMax = %f", mMax); + LOGF(info, "double mMass = %f", mMass); + } + }; + + //__________________________________________________________________ + ConfigContainer addGun(int input_pdg, int nInject = 1, float ptMin = 1, float ptMax = 10, float min = 1, float max = 10) + { + if (mUseTriggering) { // If in trigger mode, every particle needs to be generated from pythia + return addGunGenDecayed(input_pdg, nInject, ptMin, ptMax, min, max); + } + ConfigContainer cfg{input_pdg, nInject, ptMin, ptMax, min, max}; + mGunConfigs.push_back(cfg); + return cfg; + } + + //__________________________________________________________________ + ConfigContainer addGun(ConfigContainer cfg) { return addGun(cfg.mPdg, cfg.mNInject, cfg.mPtMin, cfg.mPtMax, cfg.mMin, cfg.mMax); } + + //__________________________________________________________________ + ConfigContainer addGunGenDecayed(int input_pdg, int nInject = 1, float ptMin = 1, float ptMax = 10, float min = 1, float max = 10) + { + ConfigContainer cfg{input_pdg, nInject, ptMin, ptMax, min, max}; + mGunConfigsGenDecayed.push_back(cfg); + return cfg; + } + + //__________________________________________________________________ + ConfigContainer addGunGenDecayed(ConfigContainer cfg) { return addGunGenDecayed(cfg.mPdg, cfg.mNInject, cfg.mPtMin, cfg.mPtMax, cfg.mMin, cfg.mMax); } + + //__________________________________________________________________ + long int getNGuns() const { return mGunConfigs.size() + mGunConfigsGenDecayed.size(); } + + //__________________________________________________________________ + void print() + { + LOG(info) << "GeneratorPythia8LFRapidity configuration with " << getNGuns() << " guns:"; + LOG(info) << "Particles decayed by the transport:"; + int n = 0; + for (const auto& cfg : mGunConfigs) { + LOG(info) << n++ << "/" << mGunConfigs.size() << ":"; + cfg.print(); + } + n = 0; + LOG(info) << "Particles decayed by the generator:"; + for (const auto& cfg : mGunConfigsGenDecayed) { + LOG(info) << n++ << "/" << mGunConfigs.size() << ":"; + cfg.print(); + } + } + + void setVerbose(bool verbose = true) { mVerbose = verbose; } + + private: + // Configuration + const bool mOneInjectionPerEvent = true; // if true, only one injection per event is performed, i.e. if multiple PDG (including antiparticles) are requested to be injected only one will be done per event + const bool mUseTriggering = false; // if true, use triggering instead of injection + const int mGapBetweenInjection = 0; // Gap between two signal events. 0 means injection at every event + const bool mUseRapidity = false; // if true, use rapidity instead of eta + + // Running variables + int mConfigToUse = -1; // Index of the configuration to use + int mEventCounter = 0; // Event counter + bool mVerbose = true; // Verbosity flag + + std::vector mGunConfigs; // List of gun configurations to use + std::vector mGunConfigsGenDecayed; // List of gun configurations to use that will be decayed by the generator + Pythia8::Pythia pythiaObjectSignal; // Signal collision generator + Pythia8::Pythia pythiaObjectMinimumBias; // Minimum bias collision generator + Pythia8::Pythia mPythiaGun; // Gun generator with decay support +}; + +///___________________________________________________________ +/// Create generator via arrays of entries. By default injecting in every event and all particles +FairGenerator* generateLFRapidity(std::vector PDGs, std::vector nInject, std::vector ptMin, std::vector ptMax, std::vector min, std::vector max, bool useRapidity = false) +{ + const std::vector entries = {PDGs.size(), nInject.size(), ptMin.size(), ptMax.size(), min.size(), max.size()}; + if (!std::equal(entries.begin() + 1, entries.end(), entries.begin())) { + LOGF(fatal, "Not equal number of entries, check configuration"); + return nullptr; + } + GeneratorPythia8LFRapidity* multiGun = new GeneratorPythia8LFRapidity(false, 0, false, useRapidity, "", ""); + for (unsigned long i = 0; i < entries[0]; i++) { + multiGun->addGun(PDGs[i], nInject[i], ptMin[i], ptMax[i], min[i], max[i]); + } + return multiGun; +} + +///___________________________________________________________ +/// Create generator via an array of configurations +FairGenerator* generateLFRapidity(std::vector cfg, + std::vector cfgGenDecayed, + bool injectOnePDGPerEvent = true, + int gapBetweenInjection = 0, + bool useTrigger = false, + bool useRapidity = false, + std::string pythiaCfgMb = "", + std::string pythiaCfgSignal = "") +{ + GeneratorPythia8LFRapidity* multiGun = new GeneratorPythia8LFRapidity(injectOnePDGPerEvent, gapBetweenInjection, useTrigger, useRapidity, pythiaCfgMb, pythiaCfgSignal); + for (const auto& c : cfg) { + LOGF(info, "Adding gun %i", multiGun->getNGuns()); + c.print(); + multiGun->addGun(c); + } + for (const auto& c : cfgGenDecayed) { + LOGF(info, "Adding gun %i, particle will be decayed by the generator", multiGun->getNGuns()); + c.print(); + multiGun->addGunGenDecayed(c); + } + multiGun->print(); + return multiGun; +} + +///___________________________________________________________ +/// Create generator via input file +FairGenerator* generateLFRapidity(std::string configuration = "${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGLF/pythia8/generator/exotic_nuclei_pp.gun", + bool injectOnePDGPerEvent = true, + int gapBetweenInjection = 0, + bool useTrigger = false, + bool useRapidity = false, + std::string pythiaCfgMb = "", + std::string pythiaCfgSignal = "") +{ + configuration = gSystem->ExpandPathName(configuration.c_str()); + LOGF(info, "Using configuration file '%s'", configuration.c_str()); + std::ifstream inputFile(configuration.c_str(), ios::in); + std::vector cfgVec; + std::vector cfgVecGenDecayed; + if (!inputFile.is_open()) { + LOGF(fatal, "Can't open '%s' !", configuration.c_str()); + return nullptr; + } + if (TString(configuration.c_str()).EndsWith(".json")) { // read from JSON file + nlohmann::json paramfile = nlohmann::json::parse(inputFile); + std::cout << "paramfile " << paramfile << std::endl; + for (const auto& param : paramfile) { + std::cout << param << std::endl; + // cfgVecGenDecayed.push_back(GeneratorPythia8LFRapidity::ConfigContainer{paramfile[n].template get(), param}); + if (param["genDecayed"]) { + cfgVecGenDecayed.push_back(GeneratorPythia8LFRapidity::ConfigContainer{param, useRapidity}); + } else { + cfgVec.push_back(GeneratorPythia8LFRapidity::ConfigContainer{param, useRapidity}); + } + } + } else { + std::string l; + int n = 0; + while (getline(inputFile, l)) { + TString line = l; + line.Strip(TString::kBoth, ' '); + std::cout << n++ << " '" << line << "'" << endl; + if (line.IsNull() || line.IsWhitespace()) { + continue; + } + if (line.BeginsWith("#")) { + std::cout << "Skipping\n"; + continue; + } + if (line.Contains("genDecayed")) { + cfgVecGenDecayed.push_back(GeneratorPythia8LFRapidity::ConfigContainer{line}); + } else { + cfgVec.push_back(GeneratorPythia8LFRapidity::ConfigContainer{line}); + } + } + } + return generateLFRapidity(cfgVec, cfgVecGenDecayed, injectOnePDGPerEvent, gapBetweenInjection, useTrigger, useRapidity, pythiaCfgMb, pythiaCfgSignal); +} + +///___________________________________________________________ +/// Create generator via input file for the triggered mode +FairGenerator* generateLFRapidityTriggered(std::string configuration = "${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGLF/pythia8/generator/exotic_nuclei_pp.gun", + int gapBetweenInjection = 0, + bool useRapidity = false, + std::string pythiaCfgMb = "", + std::string pythiaCfgSignal = "") +{ + return generateLFRapidity(configuration, /*injectOnePDGPerEvent=*/true, gapBetweenInjection, /*useTrigger=*/true, useRapidity, pythiaCfgMb, pythiaCfgSignal); +} + +///___________________________________________________________ +void generator_pythia8_LF_rapidity(bool testInj = true, bool testTrg = false, bool useRapidity = false, const char* particleListFile = "cfg_rapidity.json") +{ + LOG(info) << "Compiled correctly!"; + if (!testInj && !testTrg) { + return; + } + // Injected mode + if (testInj) { + LOG(info) << "Testing the injected mode"; + auto* gen = static_cast(generateLFRapidity(particleListFile, true, 0, false, useRapidity)); + gen->setVerbose(); + gen->Print(); + gen->print(); + gen->Init(); + gen->generateEvent(); + gen->importParticles(); + } + + // Triggered mode + if (testTrg) { + LOG(info) << "Testing the triggered mode"; + GeneratorPythia8LFRapidity* gen = static_cast(generateLFRapidityTriggered(particleListFile, + /*gapBetweenInjection=*/0, + useRapidity, + /*pythiaCfgMb=*/"inel136tev.cfg", + /*pythiaCfgSignal=*/"inel136tev.cfg")); + gen->setVerbose(); + gen->Print(); + gen->print(); + gen->Init(); + gen->generateEvent(); + gen->importParticles(); + } +} diff --git a/MC/config/PWGLF/pythia8/generator_pythia8_coalescence.C b/MC/config/PWGLF/pythia8/generator_pythia8_coalescence.C index ec5d1c6e1..790710476 100644 --- a/MC/config/PWGLF/pythia8/generator_pythia8_coalescence.C +++ b/MC/config/PWGLF/pythia8/generator_pythia8_coalescence.C @@ -16,19 +16,21 @@ using namespace Pythia8; #endif +R__ADD_INCLUDE_PATH($O2DPG_MC_CONFIG_ROOT) +#include "MC/config/common/external/generator/CoalescencePythia8.h" /// First version of the simple coalescence generator based PYTHIA8 -/// TODO: extend to other nuclei (only He3 is implemented now) class GeneratorPythia8Coalescence : public o2::eventgen::GeneratorPythia8 { public: /// Constructor - GeneratorPythia8Coalescence(int input_trigger_ratio = 1, double coal_momentum = 0.4) + GeneratorPythia8Coalescence(std::vector pdgList, int input_trigger_ratio = 1, double coal_momentum = 0.4) : o2::eventgen::GeneratorPythia8() { fmt::printf(">> Coalescence generator %d\n", input_trigger_ratio); mInverseTriggerRatio = input_trigger_ratio; mCoalMomentum = coal_momentum; + mPdgList = pdgList; } /// Destructor ~GeneratorPythia8Coalescence() = default; @@ -47,13 +49,14 @@ protected: // Simple straightforward check to alternate generators if (mGeneratedEvents % mInverseTriggerRatio == 0) { + fmt::printf(">> Generating coalescence event %d\n", mGeneratedEvents); bool genOk = false; int localCounter{0}; while (!genOk) { if (GeneratorPythia8::generateEvent()) { - genOk = selectEvent(mPythia.event); + genOk = CoalescencePythia8(mPythia.event, mPdgList, mCoalMomentum); } localCounter++; } @@ -63,6 +66,7 @@ protected: } else { + fmt::printf(">> Generating minimum-bias event %d\n", mGeneratedEvents); // Generate minimum-bias event bool genOk = false; while (!genOk) @@ -71,106 +75,25 @@ protected: } notifySubGenerator(0); } - mGeneratedEvents++; - return true; } - bool selectEvent(Pythia8::Event &event) - { - std::vector protons[2], neutrons[2], lambdas[2]; - for (auto iPart{0}; iPart < event.size(); ++iPart) - { - if (std::abs(event[iPart].y()) > 1.) // skip particles with y > 1 - { - continue; - } - switch (std::abs(event[iPart].id())) - { - case 2212: - protons[event[iPart].id() > 0].push_back(iPart); - break; - case 2112: - neutrons[event[iPart].id() > 0].push_back(iPart); - break; - case 3122: - lambdas[event[iPart].id() > 0].push_back(iPart); - break; - default: - break; - } - } - const double coalescenceRadius{0.5 * 1.122462 * mCoalMomentum}; /// 1.122462 [2^(1/6)] from PRL 126, 101101 (2021), only for 3 body coalescence - - auto coalescence = [&](int iC, int pdgCode, float mass, int iD1, int iD2, int iD3) { - if (event[iD1].status() < 0 || event[iD2].status() < 0 || event[iD3].status() < 0) - { - return false; - } - auto p1 = event[iD1].p(); - auto p2 = event[iD2].p(); - auto p3 = event[iD3].p(); - auto p = p1 + p2 + p3; - p1.bstback(p); - p2.bstback(p); - p3.bstback(p); - - if (p1.pAbs() <= coalescenceRadius && p2.pAbs() <= coalescenceRadius && p3.pAbs() <= coalescenceRadius) - { - p.e(std::hypot(p.pAbs(), mass)); - /// In order to avoid the transport of the mother particles, but to still keep them in the stack, we set the status to negative and we mark the nucleus status as 94 (decay product) - event.append((iC * 2 - 1) * pdgCode, 94, 0, 0, 0, 0, 0, 0, p.px(), p.py(), p.pz(), p.e(), mass); - event[iD1].statusNeg(); - event[iD1].daughter1(event.size() - 1); - event[iD2].statusNeg(); - event[iD2].daughter1(event.size() - 1); - event[iD3].statusNeg(); - event[iD3].daughter1(event.size() - 1); - - fmt::printf(">> Adding a %i with p = %f, %f, %f, E = %f\n", (iC * 2 - 1) * pdgCode, p.px(), p.py(), p.pz(), p.e()); - - return true; - } - return false; - }; - - bool coalHappened = false; - for (int iC{0}; iC < 2; ++iC) - { - for (int iP{0}; iP < protons[iC].size(); ++iP) { - for (int iN{0}; iN < neutrons[iC].size(); ++iN) { - /// H3L loop - for (int iL{0}; iL < lambdas[iC].size(); ++iL) { - coalHappened |= coalescence(iC, 1010010030, 2.991134, protons[iC][iP], neutrons[iC][iN], lambdas[iC][iL]); - } - /// H3 loop - for (int iN2{iN + 1}; iN2 < neutrons[iC].size(); ++iN2) { - coalHappened |= coalescence(iC, 1000010030, 2.80892113298, protons[iC][iP], neutrons[iC][iN], neutrons[iC][iN2]); - } - /// He3 loop - for (int iP2{iP + 1}; iP2 < protons[iC].size(); ++iP2) { - coalHappened |= coalescence(iC, 1000020030, 2.808391, protons[iC][iP], protons[iC][iP2], neutrons[iC][iN]); - } - } - } - } - return coalHappened; - } private: - // Control gap-triggering - float mCoalMomentum = 0.4; + std::vector mPdgList; /// list of pdg codes to be generated + float mCoalMomentum = 0.4; /// coalescence momentum uint64_t mGeneratedEvents = 0; /// number of events generated so far int mInverseTriggerRatio = 1; /// injection gap }; ///___________________________________________________________ -FairGenerator *generateCoalescence(int input_trigger_ratio, double coal_momentum = 0.4) +FairGenerator *generateCoalescence(std::vector pdgList, int input_trigger_ratio, double coal_momentum = 0.4) { - auto myGen = new GeneratorPythia8Coalescence(input_trigger_ratio, coal_momentum); + auto myGen = new GeneratorPythia8Coalescence(pdgList, input_trigger_ratio, coal_momentum); auto seed = (gRandom->TRandom::GetSeed() % 900000000); myGen->readString("Random:setSeed on"); myGen->readString("Random:seed " + std::to_string(seed)); return myGen; } +///___________________________________________________________ \ No newline at end of file diff --git a/MC/config/PWGLF/pythia8/generator_pythia8_deuteron_wigner.C b/MC/config/PWGLF/pythia8/generator_pythia8_deuteron_wigner.C new file mode 100644 index 000000000..0efcdc1a0 --- /dev/null +++ b/MC/config/PWGLF/pythia8/generator_pythia8_deuteron_wigner.C @@ -0,0 +1,157 @@ +#if !defined(__CLING__) || defined(__ROOTCLING__) +#include "FairGenerator.h" +#include "FairPrimaryGenerator.h" +#include "Generators/GeneratorPythia8.h" +#include "Pythia8/Pythia.h" +#include "TDatabasePDG.h" +#include "TMath.h" +#include "TParticlePDG.h" +#include "TRandom3.h" +#include "TSystem.h" +#include "TH2D.h" +#include "TH1D.h" +#include "TFile.h" +#include "fairlogger/Logger.h" +#include "CCDB/BasicCCDBManager.h" +#include +#include +#include +#include +using namespace Pythia8; +#endif + +/// Event generator for proton-proton (pp) collisions using Pythia8. +/// (Anti)deuterons are formed via nucleon coalescence modeled using the Wigner density formalism. + +class GeneratorPythia8DeuteronWigner : public o2::eventgen::GeneratorPythia8 { +public: + GeneratorPythia8DeuteronWigner(double sourceRadius = 1.2) + : o2::eventgen::GeneratorPythia8(), mSourceRadius(sourceRadius) { + + // Connect to CCDB and retrieve coalescence probability two-dimensional table + o2::ccdb::CcdbApi ccdb_api; + ccdb_api.init("https://alice-ccdb.cern.ch"); + + mTwoDimCoalProbability = ccdb_api.retrieveFromTFileAny("Users/a/alcaliva/WignerCoalescence/ArgonneProbability/AddedSDWave"); + + if (!mTwoDimCoalProbability) { + LOG(fatal) << "Could not find coalescence probability table in input file!"; + } + } + + ~GeneratorPythia8DeuteronWigner() override = default; + + bool Init() override { + addSubGenerator(0, "Pythia8 events with (anti)deuterons formed via coalescence using the Wigner density formalism, provided the coalescence condition is fulfilled"); + return o2::eventgen::GeneratorPythia8::Init(); + } + +protected: + bool generateEvent() override { + + if (GeneratorPythia8::generateEvent() && EventHasDeuteron(mPythia.event)) { + LOG(debug) << ">> A Deuteron was formed!"; + } + + notifySubGenerator(0); + ++mGeneratedEvents; + return true; + } + + bool EventHasDeuteron(Pythia8::Event& event) { + + bool deuteronIsFormed = false; + const double md = 1.87561294257; // Deuteron mass [GeV] + + std::vector proton_ID, neutron_ID; + std::vector proton_status, neutron_status; + + for (int iPart = 0; iPart < event.size(); ++iPart) { + if (event[iPart].status() <= 0) { + continue; + } + + int absID = std::abs(event[iPart].id()); + if (absID == 2212) { + proton_ID.push_back(iPart); + proton_status.push_back(0); + } else if (absID == 2112) { + neutron_ID.push_back(iPart); + neutron_status.push_back(0); + } + } + + int radiusBin = mTwoDimCoalProbability->GetXaxis()->FindBin(mSourceRadius); + TH1D* prob_vs_q = mTwoDimCoalProbability->ProjectionY("prob_vs_q", radiusBin, radiusBin, "E"); + prob_vs_q->SetDirectory(nullptr); + + for (size_t ip = 0; ip < proton_ID.size(); ip++) { + if (proton_status[ip] < 0) continue; + + for (size_t in = 0; in < neutron_ID.size(); in++) { + if (neutron_status[in] < 0) continue; + + int protonID = proton_ID[ip]; + int neutronID = neutron_ID[in]; + int sign_p = event[protonID].id() / std::abs(event[protonID].id()); + int sign_n = event[neutronID].id() / std::abs(event[neutronID].id()); + if (sign_p != sign_n) continue; + + auto p1 = event[protonID].p(); + auto p2 = event[neutronID].p(); + auto p = p1 + p2; + p1.bstback(p); + p2.bstback(p); + + Vec4 deltaPVec = p1 - p2; + double deltaP = 0.5 * deltaPVec.pAbs(); + + int binQ = prob_vs_q->FindBin(deltaP); + + // Skip underflow and overflow bins + if (binQ < 1 || binQ > prob_vs_q->GetNbinsX()) { + continue; + } + double coalProb = prob_vs_q->GetBinContent(prob_vs_q->FindBin(deltaP)); + double rndCoalProb = gRandom->Uniform(0.0, 1.0); + double rndSpinIsospin = gRandom->Uniform(0.0, 1.0); + + if (rndCoalProb < coalProb && rndSpinIsospin < 3.0/8.0) { + double energy = std::hypot(p.pAbs(), md); + p.e(energy); + int deuteronPDG = sign_p * 1000010020; + + event.append(deuteronPDG, 121, 0, 0, 0, 0, 0, 0, p.px(), p.py(), p.pz(), p.e(), md); + + event[protonID].statusNeg(); + event[protonID].daughter1(event.size() - 1); + proton_status[ip] = -1; + + event[neutronID].statusNeg(); + event[neutronID].daughter1(event.size() - 1); + neutron_status[in] = -1; + + deuteronIsFormed = true; + } + } + } + + // free allocated memory + delete prob_vs_q; + return deuteronIsFormed; + } + +private: + double mSourceRadius = 1.2; + uint64_t mGeneratedEvents = 0; + TH2D* mTwoDimCoalProbability = nullptr; +}; + +///________________________________________________________________________________________________________ +FairGenerator* generateAntideuteronsWignerCoalescence(double sourceRadius = 1.2) { + auto myGenerator = new GeneratorPythia8DeuteronWigner(sourceRadius); + auto seed = gRandom->TRandom::GetSeed() % 900000000; + myGenerator->readString("Random:setSeed on"); + myGenerator->readString("Random:seed " + std::to_string(seed)); + return myGenerator; +} diff --git a/MC/config/PWGLF/pythia8/generator_pythia8_doubleLambdas.C b/MC/config/PWGLF/pythia8/generator_pythia8_doubleLambdas.C new file mode 100644 index 000000000..b03a57ef0 --- /dev/null +++ b/MC/config/PWGLF/pythia8/generator_pythia8_doubleLambdas.C @@ -0,0 +1,162 @@ +#if !defined(__CLING__) || defined(__ROOTCLING__) +#include "FairGenerator.h" +#include "FairPrimaryGenerator.h" +#include "Generators/GeneratorPythia8.h" +#include "Pythia8/Pythia.h" +#include "TDatabasePDG.h" +#include "TMath.h" +#include "TParticlePDG.h" +#include "TRandom3.h" +#include "TSystem.h" +#include "TVector2.h" +#include "fairlogger/Logger.h" +#include +#include +#include +#include +using namespace Pythia8; +#endif + +/// Event generator using Pythia ropes +/// One event of interest is triggered after n minimum-bias events. +/// Event of interest : an event that contains at least two generated (anti-)Lambdas + +class GeneratorPythia8DoubleLambda : public o2::eventgen::GeneratorPythia8 +{ +public: + /// Constructor + GeneratorPythia8DoubleLambda(int gapSize = 4, double minPt = 0.2, double maxPt = 10, double maxEta = 0.8) + : o2::eventgen::GeneratorPythia8(), + mGapSize(gapSize), + mMinPt(minPt), + mMaxPt(maxPt), + mMaxEta(maxEta) + { + fmt::printf( + ">> Pythia8 generator: two (anti-)Lambdas, gap = %d, minPtLambda = %f, maxPtLambda = %f, |etaLambda| < %f\n", gapSize, minPt, maxPt, maxEta); + } + /// Destructor + ~GeneratorPythia8DoubleLambda() = default; + + bool Init() override + { + addSubGenerator(0, "Pythia8 events with two (anti-)Lambdas"); + return o2::eventgen::GeneratorPythia8::Init(); + } + +protected: + /// Check if particle is physical primary or from HF decay + bool isLambdaPhysicalPrimaryOrFromHF(const Pythia8::Particle &p, const Pythia8::Event &event) + { + // Select only final-state particles + if (!p.isFinal()) + { + return false; + } + + // Walk up ancestry + int motherId = p.mother1(); + + while (motherId > 0) + { + + // Get mother + const auto &mother = event[motherId]; + const int absMotherPdg = std::abs(mother.id()); + + // Check if particle is from HF decay + if ((absMotherPdg / 100 == 4) || (absMotherPdg / 100 == 5) || (absMotherPdg / 1000 == 4) || (absMotherPdg / 1000 == 5)) + { + return true; + } + + // Reject non-physical primary hadrons + if (mother.isHadron() && mother.tau0() > 1.0) + { + return false; + } + motherId = mother.mother1(); + } + return true; + } + + bool generateEvent() override + { + fmt::printf(">> Generating event %d\n", mGeneratedEvents); + + bool genOk = false; + int localCounter{0}; + constexpr int kMaxTries{100000}; + + // Accept mGapSize events unconditionally, then one triggered event + if (mGeneratedEvents % (mGapSize + 1) < mGapSize) + { + genOk = GeneratorPythia8::generateEvent(); + fmt::printf(">> Gap-event (no strangeness check)\n"); + } + else + { + while (!genOk && localCounter < kMaxTries) + { + if (GeneratorPythia8::generateEvent()) + { + genOk = selectEvent(mPythia.event); + } + localCounter++; + } + if (!genOk) + { + fmt::printf("Failed to generate triggered event after %d tries\n", kMaxTries); + return false; + } + fmt::printf(">> Triggered event: event accepted after %d iterations (double (anti-)Lambdas)\n", localCounter); + } + + notifySubGenerator(0); + mGeneratedEvents++; + return true; + } + + bool selectEvent(Pythia8::Event &event) + { + + std::vector particleID; + int nLambda{0}; + + for (int i = 0; i < event.size(); i++) + { + const auto &p = event[i]; + if (std::abs(p.eta()) > mMaxEta || p.pT() < mMinPt || p.pT() > mMaxPt) + continue; + if (!isLambdaPhysicalPrimaryOrFromHF(p, event)) + continue; + + if (std::abs(p.id()) == 3122) + nLambda++; + + particleID.emplace_back(i); + } + if (nLambda < 2) + return false; + + return true; + } + +private: + int mGapSize{4}; + double mMinPt{0.2}; + double mMaxPt{10.0}; + double mMaxEta{0.8}; + uint64_t mGeneratedEvents{0}; +}; + +///___________________________________________________________ +FairGenerator *generateDoubleLambda(int gap = 4, double minPt = 0.2, double maxPt = 10, double maxEta = 0.8) +{ + + auto myGenerator = new GeneratorPythia8DoubleLambda(gap, minPt, maxPt, maxEta); + auto seed = (gRandom->TRandom::GetSeed() % 900000000); + myGenerator->readString("Random:setSeed on"); + myGenerator->readString("Random:seed " + std::to_string(seed)); + return myGenerator; +} diff --git a/MC/config/PWGLF/pythia8/generator_pythia8_extraStrangeness.C b/MC/config/PWGLF/pythia8/generator_pythia8_extraStrangeness.C index c7a57f956..f518c1d7b 100644 --- a/MC/config/PWGLF/pythia8/generator_pythia8_extraStrangeness.C +++ b/MC/config/PWGLF/pythia8/generator_pythia8_extraStrangeness.C @@ -10,13 +10,14 @@ #include "TDatabasePDG.h" #include +#include #include class GeneratorPythia8ExtraStrangeness : public o2::eventgen::GeneratorPythia8 { public: /// Constructor - GeneratorPythia8ExtraStrangeness() { + GeneratorPythia8ExtraStrangeness(double enhancementXi, double enhancementOmega) { genMinPt=0.0; genMaxPt=20.0; genminY=-1.0; @@ -35,8 +36,10 @@ public: xProd=0; yProd=0; zProd=0; - xProd=0.; yProd=0.; zProd=0.; - + + fEnhancementXi = enhancementXi; + fEnhancementOmega = enhancementOmega; + fLVHelper = std::make_unique(); fSpectrumXi = std::make_unique("fSpectrumXi", this, &GeneratorPythia8ExtraStrangeness::boltzPlusPower, 0., genMaxPt, 5, "GeneratorPythia8ExtraStrangeness", "boltzPlusPower"); @@ -60,7 +63,7 @@ public: Double_t mt = TMath::Sqrt(mass * mass + pt * pt); return TMath::ASinH(mt / pt * TMath::SinH(y)); } - + /// set 4-momentum void set4momentum(double input_px, double input_py, double input_pz){ px = input_px; @@ -206,7 +209,7 @@ Double_t boltzPlusPower(const Double_t *x, const Double_t *p) // Info in : created default TCanvas with name c1 //Adjust relative abundance of multi-strange particles by injecting some Double_t lExpectedXiToPion = TMath::Max(4.74929e-03 - 4.08255e-03*TMath::Exp(-nChargedParticlesAtMidRap/4.76660e+00) - 0.00211334,0.); - Double_t lExpectedXi = 5.0*nPionsAtMidRap*lExpectedXiToPion; // extra rich, factor 5 + Double_t lExpectedXi = fEnhancementXi*nPionsAtMidRap*lExpectedXiToPion; // extra rich, factor 5 Int_t lXiYield = gRandom->Poisson(3*lExpectedXi); //factor 3: fix the rapidity acceptance m = 1.32171; pdg = 3312; @@ -227,7 +230,7 @@ Double_t boltzPlusPower(const Double_t *x, const Double_t *p) // OMEGA ABUNDANCE FIX //Adjust relative abundance of multi-strange particles by injecting some Double_t lExpectedOmegaToPion = TMath::Max(8.55057e-04 - 7.38732e-04*TMath::Exp(-nChargedParticlesAtMidRap/2.40545e+01) - 6.56785e-05,0.); - Double_t lExpectedOmega = 5.0*nPionsAtMidRap*lExpectedOmegaToPion; // extra rich, factor 5 + Double_t lExpectedOmega = fEnhancementOmega*nPionsAtMidRap*lExpectedOmegaToPion; // extra rich, factor 30 (omega -> rarer -> smaller Nch bias -> ok to enrich more) Int_t lOmegaYield = gRandom->Poisson(3*lExpectedOmega); //factor 3: fix the rapidity acceptance m = 1.67245; pdg = 3334; @@ -270,16 +273,22 @@ private: double xProd; /// x-coordinate position production vertex [cm] double yProd; /// y-coordinate position production vertex [cm] double zProd; /// z-coordinate position production vertex [cm] - + + double fEnhancementXi; /// Enhancement factor for Xi + double fEnhancementOmega; /// Enhancement factor for Omega + std::unique_ptr fLVHelper; std::unique_ptr fSpectrumXi; std::unique_ptr fSpectrumOm; }; - FairGenerator *generator_extraStrangeness() + FairGenerator *generator_extraStrangeness(double enhancementXi = 5.0, double enhancementOmega = 30.0) { - auto generator = new GeneratorPythia8ExtraStrangeness(); - gRandom->SetSeed(0); + auto generator = new GeneratorPythia8ExtraStrangeness(enhancementXi,enhancementOmega); + //gRandom->SetSeed(0); + + // Initialize ROOT random number generator with a time-dependent seed to get different sequences each run + gRandom->SetSeed(static_cast(time(nullptr))); generator->readString("Random:setSeed = on"); generator->readString("Random:seed =" + std::to_string(gRandom->Integer(900000000 - 2) + 1)); return generator; diff --git a/MC/config/PWGLF/pythia8/generator_pythia8_longlived.C b/MC/config/PWGLF/pythia8/generator_pythia8_longlived.C index c72a42561..af071914b 100644 --- a/MC/config/PWGLF/pythia8/generator_pythia8_longlived.C +++ b/MC/config/PWGLF/pythia8/generator_pythia8_longlived.C @@ -16,7 +16,7 @@ class GeneratorPythia8LongLivedGun : public o2::eventgen::GeneratorPythia8 { public: /// constructor - GeneratorPythia8LongLivedGun(int input_pdg, int nInject = 1, float ptMin = 1, float ptMax = 10, int input_pdg2 = -1) : pdg{input_pdg}, nParticles{nInject}, genMinPt{ptMin}, genMaxPt{ptMax}, m{getMass(input_pdg)}, pdg2{input_pdg2} + GeneratorPythia8LongLivedGun(int input_pdg, int nInject = 1, float ptMin = 1, float ptMax = 10, float etaMin = -1.0, float etaMax = 1.0, float phiMin = 0.0, float phiMax = TMath::Pi(), int input_pdg2 = -1) : pdg{input_pdg}, nParticles{nInject}, genMinPt{ptMin}, genMaxPt{ptMax}, genMinEta{etaMin}, genMaxEta{etaMax}, genMinPhi{phiMin}, genMaxPhi{phiMax}, m{getMass(input_pdg)}, pdg2{input_pdg2} { } @@ -51,7 +51,7 @@ public: { const double pt = gRandom->Uniform(genMinPt, genMaxPt); const double eta = gRandom->Uniform(genMinEta, genMaxEta); - const double phi = gRandom->Uniform(0, TMath::TwoPi()); + const double phi = gRandom->Uniform(genMinPhi, genMaxPhi); const double px{pt * std::cos(phi)}; const double py{pt * std::sin(phi)}; const double pz{pt * std::sinh(eta)}; @@ -69,7 +69,7 @@ public: { const double pt = gRandom->Uniform(genMinPt, genMaxPt); const double eta = gRandom->Uniform(genMinEta, genMaxEta); - const double phi = gRandom->Uniform(0, TMath::TwoPi()); + const double phi = gRandom->Uniform(genMinPhi, genMaxPhi); const double px{pt * std::cos(phi)}; const double py{pt * std::sin(phi)}; const double pz{pt * std::sinh(eta)}; @@ -88,8 +88,10 @@ public: private: double genMinPt = 0.5; /// minimum 3-momentum for generated particles double genMaxPt = 12.; /// maximum 3-momentum for generated particles - double genMinEta = -1.; /// minimum pseudorapidity for generated particles - double genMaxEta = +1.; /// maximum pseudorapidity for generated particles + double genMinEta = -1.0; /// minimum pseudorapidity for generated particles + double genMaxEta = +1.0; /// maximum pseudorapidity for generated particles + double genMinPhi = 0.0; /// minimum pseudorapidity for generated particles + double genMaxPhi = TMath::Pi(); /// maximum pseudorapidity for generated particles double m = 0; /// particle mass [GeV/c^2] int pdg = 0; /// particle pdg code @@ -101,7 +103,8 @@ private: }; ///___________________________________________________________ -FairGenerator *generateLongLived(int pdg, int nInject, float ptMin = 1, float ptMax = 10, int pdg2 = -1) +FairGenerator *generateLongLived(int pdg, int nInject, float ptMin = 1, float ptMax = 10, float etaMin = -1.0, float etaMax = 1.0, float phiMin = 0.0, float phiMax = TMath::Pi(), int pdg2 = -1) { - return new GeneratorPythia8LongLivedGun(pdg, nInject, ptMin, ptMax, pdg2); + return new GeneratorPythia8LongLivedGun(pdg, nInject, ptMin, ptMax, etaMin, etaMax, phiMin, phiMax, pdg2); } + diff --git a/MC/config/PWGLF/pythia8/generator_pythia8_longlived_gaptriggered.C b/MC/config/PWGLF/pythia8/generator_pythia8_longlived_gaptriggered.C index ff67e41d9..b17a9fb19 100644 --- a/MC/config/PWGLF/pythia8/generator_pythia8_longlived_gaptriggered.C +++ b/MC/config/PWGLF/pythia8/generator_pythia8_longlived_gaptriggered.C @@ -1,10 +1,13 @@ -#if !defined(__CLING__) || defined(__ROOTCLING__) #include "Pythia8/Pythia.h" +#include "Pythia8/HeavyIons.h" // for event plane angle + +#if !defined(__CLING__) || defined(__ROOTCLING__) #include "FairGenerator.h" #include "FairPrimaryGenerator.h" #include "Generators/GeneratorPythia8.h" #include "fairlogger/Logger.h" +#include "CCDB/BasicCCDBManager.h" #include "TRandom3.h" #include "TParticlePDG.h" #include "TDatabasePDG.h" @@ -21,7 +24,7 @@ class GeneratorPythia8LongLivedGapTriggered : public o2::eventgen::GeneratorPyth { public: /// Constructor - GeneratorPythia8LongLivedGapTriggered(std::vector input_pdg, int input_trigger_ratio = 1, int n_injected = 1, float pt_min = 1, float pt_max = 10, float y_min = -1, float y_max = 1) + GeneratorPythia8LongLivedGapTriggered(std::vector input_pdg, int input_trigger_ratio = 1, int n_injected = 1, float pt_min = 1, float pt_max = 10, float y_min = -1, float y_max = 1, bool addSyntheticFlow = false) { mPdg = input_pdg; setNinjected(n_injected); @@ -31,10 +34,38 @@ public: mMass = getMass(input_pdg); mGeneratedEvents = 0; mAlternatingPDGsign = true; + mAddSyntheticFlow = addSyntheticFlow; + + if(mAddSyntheticFlow){ + lutGen = new o2::eventgen::FlowMapper(); + + // -------- CONFIGURE SYNTHETIC FLOW ------------ + // establish connection to ccdb + o2::ccdb::CcdbApi ccdb_api; + ccdb_api.init("https://alice-ccdb.cern.ch"); + + // config was placed at midpoint of run 544122, retrieve that + std::map metadataRCT, headers; + headers = ccdb_api.retrieveHeaders("RCT/Info/RunInformation/544122", metadataRCT, -1); + int64_t tsSOR = atol(headers["SOR"].c_str()); + int64_t tsEOR = atol(headers["EOR"].c_str()); + int64_t midRun = 0.5*tsSOR+0.5*tsEOR; + + map metadata; // can be empty + auto list = ccdb_api.retrieveFromTFileAny("Users/d/ddobrigk/syntheflow", metadata, midRun); + + TH1D *hv2vspT = (TH1D*) list->FindObject("hFlowVsPt_ins1116150_v1_Table_1"); + TH1D *heccvsb = (TH1D*) list->FindObject("hEccentricityVsB"); + + cout<<"Generating LUT for flow test"<CreateLUT(hv2vspT, heccvsb); + cout<<"Finished creating LUT!"<ExpandPathName(file_name.c_str()); std::ifstream config_file(expanded_file_name); @@ -65,6 +96,34 @@ public: mMass = getMass(mPdg); mGeneratedEvents = 0; mAlternatingPDGsign = true; + mAddSyntheticFlow = addSyntheticFlow; + + if(mAddSyntheticFlow){ + lutGen = new o2::eventgen::FlowMapper(); + + // -------- CONFIGURE SYNTHETIC FLOW ------------ + // establish connection to ccdb + o2::ccdb::CcdbApi ccdb_api; + ccdb_api.init("https://alice-ccdb.cern.ch"); + + // config was placed at midpoint of run 544122, retrieve that + std::map metadataRCT, headers; + headers = ccdb_api.retrieveHeaders("RCT/Info/RunInformation/544122", metadataRCT, -1); + int64_t tsSOR = atol(headers["SOR"].c_str()); + int64_t tsEOR = atol(headers["EOR"].c_str()); + int64_t midRun = 0.5*tsSOR+0.5*tsEOR; + + map metadata; // can be empty + auto list = ccdb_api.retrieveFromTFileAny("Users/d/ddobrigk/syntheflow", metadata, midRun); + + TH1D *hv2vspT = (TH1D*) list->FindObject("hFlowVsPt_ins1116150_v1_Table_1"); + TH1D *heccvsb = (TH1D*) list->FindObject("hEccentricityVsB"); + + cout<<"Generating LUT for flow test"<CreateLUT(hv2vspT, heccvsb); + cout<<"Finished creating LUT!"<phi(); + float impactParameter = mPythia.info.hiInfo->b(); + + for ( Long_t j=0; j < mPythia.event.size(); j++ ) { + float pyphi = mPythia.event[j].phi(); + float pypT = mPythia.event[j].pT(); + + // calculate delta with EP + float deltaPhiEP = pyphi - eventPlaneAngle; + float shift = 0.0; + while(deltaPhiEP<0.0){ + deltaPhiEP += 2*TMath::Pi(); + shift += 2*TMath::Pi(); + } + while(deltaPhiEP>2*TMath::Pi()){ + deltaPhiEP -= 2*TMath::Pi(); + shift -= 2*TMath::Pi(); + } + float newDeltaPhiEP = lutGen->MapPhi(deltaPhiEP, impactParameter, pypT); + float pyphiNew = newDeltaPhiEP - shift + eventPlaneAngle; + + if(pyphiNew>TMath::Pi()) + pyphiNew -= 2.0*TMath::Pi(); + if(pyphiNew<-TMath::Pi()) + pyphiNew += 2.0*TMath::Pi(); + mPythia.event[j].rot(0.0, pyphiNew-pyphi); + } + } + //+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + mGeneratedEvents++; return true; } @@ -169,18 +264,21 @@ private: std::vector mYmax; /// maximum rapidity for generated particles bool mAlternatingPDGsign = true; /// bool to randomize the PDG code of the core particle + bool mAddSyntheticFlow = false; /// switch to add synthetic flow (requires EP angle from PYTHIA) std::vector mNinjected; /// Number of injected particles // Control gap-triggering unsigned long long mGeneratedEvents; /// number of events generated so far int mInverseTriggerRatio; /// injection gap + + o2::eventgen::FlowMapper *lutGen; // for mapping phi angles }; ///___________________________________________________________ -FairGenerator *generateLongLivedGapTriggered(std::vector mPdg, int input_trigger_ratio, int n_injected = 1, float pt_min = 1, float pt_max = 10, float y_min = -1, float y_max = 1, bool alternate_sign = true) +FairGenerator *generateLongLivedGapTriggered(std::vector mPdg, int input_trigger_ratio, int n_injected = 1, float pt_min = 1, float pt_max = 10, float y_min = -1, float y_max = 1, bool alternate_sign = true, bool addSyntheticFlow = false) { - auto myGen = new GeneratorPythia8LongLivedGapTriggered(mPdg, input_trigger_ratio, n_injected, pt_min, pt_max, y_min, y_max); + auto myGen = new GeneratorPythia8LongLivedGapTriggered(mPdg, input_trigger_ratio, n_injected, pt_min, pt_max, y_min, y_max, addSyntheticFlow); myGen->setAlternatingPDGsign(alternate_sign); auto seed = (gRandom->TRandom::GetSeed() % 900000000); myGen->readString("Random:setSeed on"); @@ -189,9 +287,9 @@ FairGenerator *generateLongLivedGapTriggered(std::vector mPdg, int input_tr } ///___________________________________________________________ -FairGenerator *generateLongLivedGapTriggered(std::string config_file_name, int input_trigger_ratio, bool alternate_sign = true) +FairGenerator *generateLongLivedGapTriggered(std::string config_file_name, int input_trigger_ratio, bool alternate_sign = true, bool addSyntheticFlow = false) { - auto myGen = new GeneratorPythia8LongLivedGapTriggered(config_file_name, input_trigger_ratio); + auto myGen = new GeneratorPythia8LongLivedGapTriggered(config_file_name, input_trigger_ratio, addSyntheticFlow); myGen->setAlternatingPDGsign(alternate_sign); auto seed = (gRandom->TRandom::GetSeed() % 900000000); myGen->readString("Random:setSeed on"); diff --git a/MC/config/PWGLF/pythia8/generator_pythia8_sigma_hadron.C b/MC/config/PWGLF/pythia8/generator_pythia8_sigma_hadron.C new file mode 100644 index 000000000..296dd78fc --- /dev/null +++ b/MC/config/PWGLF/pythia8/generator_pythia8_sigma_hadron.C @@ -0,0 +1,197 @@ +#if !defined(__CLING__) || defined(__ROOTCLING__) +#include "FairGenerator.h" +#include "FairPrimaryGenerator.h" +#include "Generators/GeneratorPythia8.h" +#include "Pythia8/Pythia.h" +#include "TDatabasePDG.h" +#include "TMath.h" +#include "TParticlePDG.h" +#include "TRandom3.h" +#include "TSystem.h" +#include "TVector2.h" +#include "fairlogger/Logger.h" +#include +#include +#include +#include +using namespace Pythia8; +#endif + +/// Event of interest: +/// an event that contains at least one Sigma- or Sigma+ +/// paired with at least one hadron of a specific PDG code, +/// and the pair has k* < kStarMax + +class GeneratorPythia8SigmaHadron : public o2::eventgen::GeneratorPythia8 +{ +public: + /// Constructor + GeneratorPythia8SigmaHadron(int hadronPdg, int gapSize = 4, double minPt = 0.2, + double maxPt = 10, double maxEta = 0.8, double kStarMax = 1.0) + : o2::eventgen::GeneratorPythia8(), + mHadronPdg(hadronPdg), + mGapSize(gapSize), + mMinPt(minPt), + mMaxPt(maxPt), + mMaxEta(maxEta), + mKStarMax(kStarMax) + { + fmt::printf( + ">> Pythia8 generator: Sigma± + hadron(PDG=%d), gap = %d, minPt = %f, maxPt = %f, |eta| < %f, k* < %f\n", + hadronPdg, gapSize, minPt, maxPt, maxEta, kStarMax); + } + + ~GeneratorPythia8SigmaHadron() = default; + + bool Init() override + { + addSubGenerator(0, "Pythia8 events with Sigma± and a specific hadron"); + return o2::eventgen::GeneratorPythia8::Init(); + } + +protected: + /// Check whether particle descends from a Sigma+ or Sigma- + bool isFromSigmaDecay(const Pythia8::Particle& p, const Pythia8::Event& event) + { + int motherId = p.mother1(); + + while (motherId > 0) { + const auto& mother = event[motherId]; + const int absMotherPdg = std::abs(mother.id()); + + if (absMotherPdg == 3112 || absMotherPdg == 3222) { + return true; + } + + motherId = mother.mother1(); + } + + return false; + } + + /// k* of a pair from invariant masses and 4-momenta + /// k* = momentum of either particle in the pair rest frame + double computeKStar(const Pythia8::Particle& p1, const Pythia8::Particle& p2) const + { + const double e = p1.e() + p2.e(); + const double px = p1.px() + p2.px(); + const double py = p1.py() + p2.py(); + const double pz = p1.pz() + p2.pz(); + const double s = e * e - px * px - py * py - pz * pz; + if (s <= 0.) { + return 1.e9; + } + const double m1 = p1.m(); + const double m2 = p2.m(); + const double term1 = s - std::pow(m1 + m2, 2); + const double term2 = s - std::pow(m1 - m2, 2); + const double lambda = term1 * term2; + + if (lambda <= 0.) { + return 0.; + } + return 0.5 * std::sqrt(lambda / s); + } + + bool generateEvent() override + { + fmt::printf(">> Generating event %llu\n", mGeneratedEvents); + + bool genOk = false; + int localCounter{0}; + constexpr int kMaxTries{100000}; + + // Accept mGapSize events unconditionally, then one triggered event + if (mGeneratedEvents % (mGapSize + 1) < mGapSize) { + genOk = GeneratorPythia8::generateEvent(); + fmt::printf(">> Gap-event (no trigger check)\n"); + } else { + while (!genOk && localCounter < kMaxTries) { + if (GeneratorPythia8::generateEvent()) { + genOk = selectEvent(mPythia.event); + } + localCounter++; + } + + if (!genOk) { + fmt::printf("Failed to generate triggered event after %d tries\n", kMaxTries); + return false; + } + + fmt::printf(">> Triggered event: accepted after %d iterations (Sigma± + hadron PDG=%d, k* < %f)\n", + localCounter, mHadronPdg, mKStarMax); + } + + notifySubGenerator(0); + mGeneratedEvents++; + return true; + } + + bool selectEvent(Pythia8::Event& event) + { + std::vector sigmaIndices; + std::vector hadronIndices; + + for (int i = 0; i < event.size(); i++) { + const auto& p = event[i]; + + if (std::abs(p.eta()) > mMaxEta || p.pT() < mMinPt || p.pT() > mMaxPt) { + continue; + } + + const int pdg = p.id(); + const int absPdg = std::abs(pdg); + + // Sigma- or Sigma+ + if (absPdg == 3112 || absPdg == 3222) { + sigmaIndices.push_back(i); + } + + if (std::abs(pdg) == mHadronPdg && !isFromSigmaDecay(p, event)) { + hadronIndices.push_back(i); + } + } + if (sigmaIndices.empty() || hadronIndices.empty()) { + return false; + } + + for (const auto iSigma : sigmaIndices) { + for (const auto iHadron : hadronIndices) { + + if (iSigma == iHadron) { + continue; + } + + const auto& sigma = event[iSigma]; + const auto& hadron = event[iHadron]; + + const double kStar = computeKStar(sigma, hadron); + if (kStar < mKStarMax) { + return true; + } + } + } + + return false; + } + +private: + int mHadronPdg{211}; + int mGapSize{4}; + double mMinPt{0.2}; + double mMaxPt{10.0}; + double mMaxEta{0.8}; + double mKStarMax{1.0}; + uint64_t mGeneratedEvents{0}; +}; + +///___________________________________________________________ +FairGenerator* generateSigmaHadron(int hadronPdg, int gap = 4, double minPt = 0.2, + double maxPt = 10, double maxEta = 0.8, double kStarMax = 1.0) +{ + auto myGenerator = new GeneratorPythia8SigmaHadron(hadronPdg, gap, minPt, maxPt, maxEta, kStarMax); + auto seed = (gRandom->TRandom::GetSeed() % 900000000); + myGenerator->readString("Random:setSeed on"); + myGenerator->readString("Random:seed " + std::to_string(seed)); + return myGenerator; +} \ No newline at end of file diff --git a/MC/config/PWGLF/pythia8/generator_pythia8_strangeness_in_jets.C b/MC/config/PWGLF/pythia8/generator_pythia8_strangeness_in_jets.C new file mode 100644 index 000000000..8075d27cb --- /dev/null +++ b/MC/config/PWGLF/pythia8/generator_pythia8_strangeness_in_jets.C @@ -0,0 +1,192 @@ +#if !defined(__CLING__) || defined(__ROOTCLING__) +#include "FairGenerator.h" +#include "FairPrimaryGenerator.h" +#include "Generators/GeneratorPythia8.h" +#include "Pythia8/Pythia.h" +#include "TDatabasePDG.h" +#include "TMath.h" +#include "TParticlePDG.h" +#include "TRandom3.h" +#include "TSystem.h" +#include "TVector2.h" +#include "fairlogger/Logger.h" +#include +#include +#include +#include +using namespace Pythia8; +#endif + +/// Event generator using Pythia ropes for Ξ and Ω production in jets. +/// Jets are defined as particles within a cone around the highest-pT particle +/// (approximate jet axis) and include charged final-state particles that are +/// either physical primaries or from heavy-flavor decays. +/// Jets must be fully within the acceptance and have pT > 10 GeV. +/// One event of interest is generated after 4 minimum-bias events. + +class GeneratorPythia8StrangenessInJet : public o2::eventgen::GeneratorPythia8 { +public: + /// Constructor + GeneratorPythia8StrangenessInJet(double ptJetMin = 10.0, double Rjet = 0.4, int gapSize = 4) + : o2::eventgen::GeneratorPythia8(), + mptJetMin(ptJetMin), + mRjet(Rjet), + mGapSize(gapSize) + { + fmt::printf( + ">> Pythia8 generator: Xi/Omega inside jets with pt_{jet} > %.1f GeV, R_{jet} = %.1f, gap = %d\n", + ptJetMin, Rjet, gapSize); + } + /// Destructor + ~GeneratorPythia8StrangenessInJet() = default; + + bool Init() override { + addSubGenerator(0, "Pythia8 events with Xi/Omega inside jets"); + return o2::eventgen::GeneratorPythia8::Init(); + } + +protected: + /// Check if particle is physical primary or from HF decay + bool isPhysicalPrimaryOrFromHF(const Pythia8::Particle& p, const Pythia8::Event& event) + { + // Select only final-state particles + if (!p.isFinal()) { + return false; + } + + // Particle species selection + const int absPdg = std::abs(p.id()); + if (absPdg!=211 && absPdg!=321 && absPdg!= 2212 && absPdg!=1000010020 && absPdg!=11 && absPdg!=13) + return false; + + // Walk up ancestry + int motherId = p.mother1(); + + while (motherId > 0) { + + // Get mother + const auto& mother = event[motherId]; + const int absMotherPdg = std::abs(mother.id()); + + // Check if particle is from HF decay + if ((absMotherPdg / 100 == 4) || (absMotherPdg / 100 == 5) || (absMotherPdg / 1000 == 4) || (absMotherPdg / 1000 == 5)) { + return true; + } + + // Reject non-physical primary hadrons + if (mother.isHadron() && mother.tau0() > 1.0) { + return false; + } + motherId = mother.mother1(); + } + return true; + } + + // Compute delta phi + double getDeltaPhi(double a1, double a2) + { + double deltaPhi{0.0}; + double phi1 = TVector2::Phi_0_2pi(a1); + double phi2 = TVector2::Phi_0_2pi(a2); + double diff = std::fabs(phi1 - phi2); + + if (diff <= M_PI) + deltaPhi = diff; + if (diff > M_PI) + deltaPhi = 2.0 * M_PI - diff; + + return deltaPhi; + } + + bool generateEvent() override { + fmt::printf(">> Generating event %d\n", mGeneratedEvents); + + bool genOk = false; + int localCounter{0}; + constexpr int kMaxTries{100000}; + + // Accept mGapSize events unconditionally, then one triggered event + if (mGeneratedEvents % (mGapSize + 1) < mGapSize) { + genOk = GeneratorPythia8::generateEvent(); + fmt::printf(">> Gap-trigger accepted event (no strangeness check)\n"); + } else { + while (!genOk && localCounter < kMaxTries) { + if (GeneratorPythia8::generateEvent()) { + genOk = selectEvent(mPythia.event); + } + localCounter++; + } + if (!genOk) { + fmt::printf("Failed to generate triggered event after %d tries\n",kMaxTries); + return false; + } + fmt::printf(">> Event accepted after %d iterations (Xi/Omega in jet)\n", localCounter); + } + + notifySubGenerator(0); + mGeneratedEvents++; + return true; + } + + bool selectEvent(Pythia8::Event &event) { + + double etaJet{-999.0}, phiJet{-999.0}, ptMax{0.0}; + std::vector particleID; + bool containsXiOrOmega{false}; + + for (int i = 0; i < event.size(); i++) { + const auto& p = event[i]; + if (std::abs(p.id()) == 3312 || std::abs(p.id()) == 3334) + containsXiOrOmega = true; + + if (std::abs(p.eta()) > 0.8 || p.pT() < 0.1) continue; + if (!isPhysicalPrimaryOrFromHF(p, event)) continue; + particleID.emplace_back(i); + + if (p.pT() > ptMax) { + ptMax = p.pT(); + etaJet = p.eta(); + phiJet = p.phi(); + } + } + if (ptMax == 0.0) + return false; + if (std::abs(etaJet) + mRjet > 0.8) + return false; + if (!containsXiOrOmega) + return false; + + double ptJet{0.0}; + for (int i = 0 ; i < particleID.size() ; i++) { + int id = particleID[i]; + const auto& p = event[id]; + + double deltaEta = std::abs(p.eta() - etaJet); + double deltaPhi = getDeltaPhi(p.phi(),phiJet); + double deltaR = std::sqrt(deltaEta * deltaEta + deltaPhi * deltaPhi); + if (deltaR < mRjet) { + ptJet += p.pT(); + } + } + if (ptJet < mptJetMin) + return false; + + return true; + } + +private: + double mptJetMin{10.0}; + double mRjet{0.4}; + int mGapSize{4}; + uint64_t mGeneratedEvents{0}; +}; + +///___________________________________________________________ +FairGenerator *generateStrangenessInJets(double ptJet = 10.0, double rJet = 0.4, int gap = 4) { + + auto myGenerator = new GeneratorPythia8StrangenessInJet(ptJet,rJet,gap); + auto seed = (gRandom->TRandom::GetSeed() % 900000000); + myGenerator->readString("Random:setSeed on"); + myGenerator->readString("Random:seed " + std::to_string(seed)); + return myGenerator; +} diff --git a/MC/config/PWGLF/pythia8/generator_pythia8_syntheFlowOO.C b/MC/config/PWGLF/pythia8/generator_pythia8_syntheFlowOO.C new file mode 100644 index 000000000..09fac8287 --- /dev/null +++ b/MC/config/PWGLF/pythia8/generator_pythia8_syntheFlowOO.C @@ -0,0 +1,107 @@ + +#include "Pythia8/Pythia.h" +#include "Pythia8/HeavyIons.h" +#include "FairGenerator.h" +#include "FairPrimaryGenerator.h" +#include "Generators/GeneratorPythia8.h" +#include "TRandom3.h" +#include "TParticlePDG.h" +#include "TDatabasePDG.h" +#include "CCDB/BasicCCDBManager.h" +#include "TH1F.h" +#include "TH1D.h" + +#include +#include + +class GeneratorPythia8SyntheFlowOO : public o2::eventgen::GeneratorPythia8 +{ +public: + /// Constructor + GeneratorPythia8SyntheFlowOO() { + lutGen = new o2::eventgen::FlowMapper(); + + // -------- CONFIGURE SYNTHETIC FLOW ------------ + // establish connection to ccdb + o2::ccdb::CcdbApi ccdb_api; + ccdb_api.init("https://alice-ccdb.cern.ch"); + + // config was placed at midpoint of run 544122, retrieve that + std::map metadataRCT, headers; + headers = ccdb_api.retrieveHeaders("RCT/Info/RunInformation/544122", metadataRCT, -1); + int64_t tsSOR = atol(headers["SOR"].c_str()); + int64_t tsEOR = atol(headers["EOR"].c_str()); + int64_t midRun = 0.5*tsSOR+0.5*tsEOR; + + map metadata; // can be empty + auto list = ccdb_api.retrieveFromTFileAny("Users/d/ddobrigk/syntheflow", metadata, midRun); + + TH1D *hv2vspT = (TH1D*) list->FindObject("hFlowVsPt_ins1116150_v1_Table_1"); + TH1D *heccvsb = (TH1D*) list->FindObject("hEccentricityVsB"); + + cout<<"Generating LUT for flow test"<CreateLUT(hv2vspT, heccvsb); + cout<<"Finished creating LUT!"<phi(); + float impactParameter = mPythia.info.hiInfo->b(); + + for ( Long_t j=0; j < mPythia.event.size(); j++ ) { + float pyphi = mPythia.event[j].phi(); + float pypT = mPythia.event[j].pT(); + + // calculate delta with EP + float deltaPhiEP = pyphi - eventPlaneAngle; + float shift = 0.0; + while(deltaPhiEP<0.0){ + deltaPhiEP += 2*TMath::Pi(); + shift += 2*TMath::Pi(); + } + while(deltaPhiEP>2*TMath::Pi()){ + deltaPhiEP -= 2*TMath::Pi(); + shift -= 2*TMath::Pi(); + } + float newDeltaPhiEP = lutGen->MapPhi(deltaPhiEP, impactParameter, pypT); + float pyphiNew = newDeltaPhiEP - shift + eventPlaneAngle; + + if(pyphiNew>TMath::Pi()) + pyphiNew -= 2.0*TMath::Pi(); + if(pyphiNew<-TMath::Pi()) + pyphiNew += 2.0*TMath::Pi(); + mPythia.event[j].rot(0.0, pyphiNew-pyphi); + } + //+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + + return true; + } + +private: + o2::eventgen::FlowMapper *lutGen; // for mapping phi angles +}; + + FairGenerator *generator_syntheFlowOO() + { + auto generator = new GeneratorPythia8SyntheFlowOO(); + gRandom->SetSeed(0); + generator->readString("Random:setSeed = on"); + generator->readString("Random:seed =" + std::to_string(gRandom->Integer(900000000 - 2) + 1)); + return generator; + } diff --git a/MC/config/PWGUD/external/generator/DecayTablesEvtGen/OPENCHARM.DEC b/MC/config/PWGUD/external/generator/DecayTablesEvtGen/OPENCHARM.DEC index d35930c4a..c8e964d75 100644 --- a/MC/config/PWGUD/external/generator/DecayTablesEvtGen/OPENCHARM.DEC +++ b/MC/config/PWGUD/external/generator/DecayTablesEvtGen/OPENCHARM.DEC @@ -42,4 +42,12 @@ Decay phi 1.0 K+ K- VSS; #[Reconstructed PDG2011] Enddecay +Decay K*0 +1.0 K+ pi- VSS; +Enddecay + +Decay anti-K*0 +1.0 K- pi+ VSS; +Enddecay + End diff --git a/MC/config/PWGUD/external/generator/DecayTablesEvtGen/TAUTAU.EL3PI.DEC b/MC/config/PWGUD/external/generator/DecayTablesEvtGen/TAUTAU.6PI.DEC similarity index 58% rename from MC/config/PWGUD/external/generator/DecayTablesEvtGen/TAUTAU.EL3PI.DEC rename to MC/config/PWGUD/external/generator/DecayTablesEvtGen/TAUTAU.6PI.DEC index 86fed720d..bbe75c401 100644 --- a/MC/config/PWGUD/external/generator/DecayTablesEvtGen/TAUTAU.EL3PI.DEC +++ b/MC/config/PWGUD/external/generator/DecayTablesEvtGen/TAUTAU.6PI.DEC @@ -1,5 +1,5 @@ Decay tau- -1.0 e- anti-nu_e nu_tau PHOTOS TAULNUNU; #[Reconstructed PDG2011] +1.0 pi- pi- pi+ nu_tau TAUHADNU -0.108 0.775 0.149 1.364 0.400 1.23 0.4; #[Reconstructed PDG2011] Enddecay Decay tau+ 1.0 pi+ pi+ pi- anti-nu_tau TAUHADNU -0.108 0.775 0.149 1.364 0.400 1.23 0.4; #[Reconstructed PDG2011] diff --git a/MC/config/PWGUD/external/generator/DecayTablesEvtGen/TAUTAU.LN3PI.DEC b/MC/config/PWGUD/external/generator/DecayTablesEvtGen/TAUTAU.LN3PI.DEC new file mode 100644 index 000000000..b8c453c67 --- /dev/null +++ b/MC/config/PWGUD/external/generator/DecayTablesEvtGen/TAUTAU.LN3PI.DEC @@ -0,0 +1,9 @@ +Decay tau- +0.5 e- anti-nu_e nu_tau PHOTOS TAULNUNU; #[Reconstructed PDG2011] +0.5 mu- anti-nu_mu nu_tau PHOTOS TAULNUNU; #[Reconstructed PDG2011] +Enddecay +Decay tau+ +0.5 pi+ pi+ pi- anti-nu_tau TAUHADNU -0.108 0.775 0.149 1.364 0.400 1.23 0.4; #[Reconstructed PDG2011] +0.5 anti-nu_tau pi+ pi- pi+ pi0 PHSP; +Enddecay +End diff --git a/MC/config/PWGUD/external/generator/DecayTablesEvtGen/TAUTAU.LP3PI.DEC b/MC/config/PWGUD/external/generator/DecayTablesEvtGen/TAUTAU.LP3PI.DEC new file mode 100644 index 000000000..8b45742ad --- /dev/null +++ b/MC/config/PWGUD/external/generator/DecayTablesEvtGen/TAUTAU.LP3PI.DEC @@ -0,0 +1,9 @@ +Decay tau- +0.5 pi- pi- pi+ nu_tau TAUHADNU -0.108 0.775 0.149 1.364 0.400 1.23 0.4; #[Reconstructed PDG2011] +0.5 nu_tau pi- pi+ pi- pi0 PHSP; +Enddecay +Decay tau+ +0.5 e+ anti-nu_tau nu_e PHOTOS TAULNUNU; #[Reconstructed PDG2011] +0.5 mu+ anti-nu_tau nu_mu PHOTOS TAULNUNU; #[Reconstructed PDG2011] +Enddecay +End diff --git a/MC/config/PWGUD/external/generator/DecayTablesEvtGen/TAUTAU.PN3PI.DEC b/MC/config/PWGUD/external/generator/DecayTablesEvtGen/TAUTAU.PN3PI.DEC new file mode 100644 index 000000000..a23f6bd84 --- /dev/null +++ b/MC/config/PWGUD/external/generator/DecayTablesEvtGen/TAUTAU.PN3PI.DEC @@ -0,0 +1,9 @@ +Decay tau- +0.5 pi- nu_tau TAUSCALARNU; #[Reconstructed PDG2011] +0.5 pi- pi0 nu_tau TAUHADNU -0.108 0.775 0.149 1.364 0.400; #[Reconstructed PDG2011] +Enddecay +Decay tau+ +0.5 pi+ pi+ pi- anti-nu_tau TAUHADNU -0.108 0.775 0.149 1.364 0.400 1.23 0.4; #[Reconstructed PDG2011] +0.5 anti-nu_tau pi+ pi- pi+ pi0 PHSP; +Enddecay +End diff --git a/MC/config/PWGUD/external/generator/DecayTablesEvtGen/TAUTAU.PO3PI.DEC b/MC/config/PWGUD/external/generator/DecayTablesEvtGen/TAUTAU.PO3PI.DEC deleted file mode 100644 index b17413d5c..000000000 --- a/MC/config/PWGUD/external/generator/DecayTablesEvtGen/TAUTAU.PO3PI.DEC +++ /dev/null @@ -1,7 +0,0 @@ -Decay tau- -1.0 pi- pi- pi+ nu_tau TAUHADNU -0.108 0.775 0.149 1.364 0.400 1.23 0.4; #[Reconstructed PDG2011] -Enddecay -Decay tau+ -1.0 e+ anti-nu_tau nu_e PHOTOS TAULNUNU; #[Reconstructed PDG2011] -Enddecay -End diff --git a/MC/config/PWGUD/external/generator/DecayTablesEvtGen/TAUTAU.PP3PI.DEC b/MC/config/PWGUD/external/generator/DecayTablesEvtGen/TAUTAU.PP3PI.DEC new file mode 100644 index 000000000..76bc14f80 --- /dev/null +++ b/MC/config/PWGUD/external/generator/DecayTablesEvtGen/TAUTAU.PP3PI.DEC @@ -0,0 +1,9 @@ +Decay tau- +0.5 pi- pi- pi+ nu_tau TAUHADNU -0.108 0.775 0.149 1.364 0.400 1.23 0.4; #[Reconstructed PDG2011] +0.5 nu_tau pi- pi+ pi- pi0 PHSP; +Enddecay +Decay tau+ +0.5 pi+ anti-nu_tau TAUSCALARNU; #[Reconstructed PDG2011] +0.5 pi+ pi0 anti-nu_tau TAUHADNU -0.108 0.775 0.149 1.364 0.400; #[Reconstructed PDG2011] +Enddecay +End diff --git a/MC/config/PWGUD/external/generator/GeneratorStarlight.C b/MC/config/PWGUD/external/generator/GeneratorStarlight.C index 9c317ac81..be7e4d367 100644 --- a/MC/config/PWGUD/external/generator/GeneratorStarlight.C +++ b/MC/config/PWGUD/external/generator/GeneratorStarlight.C @@ -77,14 +77,14 @@ class GeneratorStarlight_class : public Generator bool Init() override { Generator::Init(); - + float beam1energy = TMath::Sqrt(Double_t(projZ)/projA*targA/targZ)*eCM/2; float beam2energy = TMath::Sqrt(Double_t(projA)/projZ*targZ/targA)*eCM/2; float gamma1 = beam1energy/0.938272; float gamma2 = beam2energy/0.938272; float rapMax = 4.1 + 0.5*(TMath::ACosH(gamma2)-TMath::ACosH(gamma1)); float dy = 0.01; - + const struct SLConfig { const char* name; int prod_mode; @@ -119,6 +119,7 @@ class GeneratorStarlight_class : public Generator {"kCohJpsiToEl", 2, 443011, 20, -1.0, -1.0, 443, 0 }, // {"kCohJpsiToElRad", 2, 443011, 20, -1.0, -1.0, 443, 1 }, // {"kCohJpsiToProton", 2, 4432212, 20, -1.0, -1.0, 443, 0 }, // + {"kCohJpsiToLLbar", 2, 4433122, 20, -1.0, -1.0, 443, 0 }, // {"kCohJpsi4Prong", 2, 443013, 20, -1.0, -1.0, 443, 1 }, // {"kCohJpsi6Prong", 2, 443013, 20, -1.0, -1.0, 443, 1 }, // {"kCohPsi2sToMu", 2, 444013, 20, -1.0, -1.0, 100443, 0 }, // @@ -150,8 +151,11 @@ class GeneratorStarlight_class : public Generator {"kIncohUpsilonToEl", 4, 553011, 20, -1.0, -1.0, 553, 0 }, // {"kDpmjetSingleA", 5, 113, 20, -1.0, -1.0, -1, 0 }, // {"kDpmjetSingleC", 5, 113, 20, -1.0, -1.0, -1, 0 }, // - {"kTauLowToEl3Pi", 1, 15, 990, 3.5, 20.0, -1, 1 }, // from 0.4 to 15 GeV - {"kTauLowToPo3Pi", 1, 15, 990, 3.5, 20.0, -1, 1 }, // from 0.4 to 15 GeV + {"kTauLowToL+3Pi", 1, 15, 990, 3.5, 20.0, -1, 1 }, // from 0.4 to 15 GeV + {"kTauLowToL-3Pi", 1, 15, 990, 3.5, 20.0, -1, 1 }, // from 0.4 to 15 GeV + {"kTauLowToPi+3Pi", 1, 15, 990, 3.5, 20.0, -1, 1 }, // from 0.4 to 15 GeV + {"kTauLowToPi-3Pi", 1, 15, 990, 3.5, 20.0, -1, 1 }, // from 0.4 to 15 GeV + {"kTauLowTo6Pi", 1, 15, 990, 3.5, 20.0, -1, 1 }, // from 0.4 to 15 GeV {"kTauLowToElMu", 1, 15, 990, 3.5, 20.0, -1, 1 }, // from 0.4 to 15 GeV {"kTauLowToElPiPi0", 1, 15, 990, 3.5, 20.0, -1, 1 }, // from 0.4 to 15 GeV {"kTauLowToPoPiPi0", 1, 15, 990, 3.5, 20.0, -1, 1 }, // from 0.4 to 15 GeV @@ -165,14 +169,14 @@ class GeneratorStarlight_class : public Generator break; } } - + if (idx == -1) { std::cout << "STARLIGHT process "<< mSelectedConfiguration <<" is not supported" << std::endl; return false; } - + mPdgMother = slConfig[idx].pdg_mother; - mDecayEvtGen = slConfig[idx].decay_EvtGen; + mDecayEvtGen = slConfig[idx].decay_EvtGen; unsigned int random_seed = generateRandomSeed(); @@ -210,6 +214,8 @@ class GeneratorStarlight_class : public Generator if(slConfig[idx].prod_mode == 5 || slConfig[idx].prod_mode == 6 || slConfig[idx].prod_mode == 7){ setParameter("MIN_GAMMA_ENERGY = 1000.0"); setParameter("MAX_GAMMA_ENERGY = 600000.0"); + setParameter("KEEP_PHI = 1"); + setParameter("KEEP_KSTAR = 1"); } TString extraPars(mExtraParams); @@ -220,18 +226,18 @@ class GeneratorStarlight_class : public Generator if (not mInputParameters.init()) { std::cout << "InitStarLight parameter initialization has failed" << std::endl; return false; - } - + } + mStarLight = new starlight; mStarLight->setInputParameters(&mInputParameters); mRandomGenerator.SetSeed(mInputParameters.randomSeed()); - mStarLight->setRandomGenerator(&mRandomGenerator); - return mStarLight->init(); - + mStarLight->setRandomGenerator(&mRandomGenerator); + return mStarLight->init(); + }; - - bool generateEvent() override { - + + bool generateEvent() override { + if (!mStarLight) { std::cout <<"GenerateEvent: StarLight class/object not properly constructed"<produceEvent(); // boost event to the experiment CM frame mEvent.boost(0.5*(TMath::ACosH(mInputParameters.beam1LorentzGamma()) - TMath::ACosH(mInputParameters.beam2LorentzGamma()))); - - return true; - + + return true; + }; // at importParticles we add particles to the output particle vector // according to the selected configuration bool importParticles() override - { + { int nVtx(0); float vtx(0), vty(0), vtz(0), vtt(0); const std::vector* slVtx; @@ -326,9 +332,19 @@ class GeneratorStarlight_class : public Generator //particle.Print(); mParticles.push_back(particle); o2::mcutils::MCGenHelper::encodeParticleStatusAndTracking(mParticles.back(), true); - } + } } - return true; + return true; + } + + //Store couple of event informations to the MC event header + void updateHeader(o2::dataformats::MCEventHeader* eventHeader)override + { + using Key = o2::dataformats::MCInfoKeys; + + eventHeader->putInfo(Key::generator, "STARlight"); + eventHeader->putInfo(Key::processName, mSelectedConfiguration); + eventHeader->putInfo("photonEnergy", getPhotonEnergy()); } protected: @@ -339,7 +355,7 @@ class GeneratorStarlight_class : public Generator int targZ=82; private: - starlight *mStarLight = 0x0; + starlight *mStarLight = 0x0; inputParameters mInputParameters; // simulation input information. randomGenerator mRandomGenerator; // STARLIGHT's own random generator upcXEvent mEvent; // object holding STARlight simulated event. @@ -349,12 +365,12 @@ class GeneratorStarlight_class : public Generator int mPdgMother = -1; bool mDecayEvtGen = 0; - + }; - + } // namespace eventgen } // namespace o2 - + FairGenerator* GeneratorStarlight(std::string configuration = "empty",float energyCM = 5020, int beam1Z = 82, int beam1A = 208, int beam2Z = 82, int beam2A = 208, std::string extrapars = "",std::string dpmjetconf = "") diff --git a/MC/config/PWGUD/external/generator/GeneratorStarlightToEvtGen.C b/MC/config/PWGUD/external/generator/GeneratorStarlightToEvtGen.C index 3bf3afaa6..9d59d3c44 100644 --- a/MC/config/PWGUD/external/generator/GeneratorStarlightToEvtGen.C +++ b/MC/config/PWGUD/external/generator/GeneratorStarlightToEvtGen.C @@ -18,7 +18,7 @@ FairGenerator* gen->AddPdg(-15,1); } else if(configuration.find("kDpmjet") != std::string::npos){ - gen->SetSizePdg(11); + gen->SetSizePdg(14); gen->AddPdg( 411,0); gen->AddPdg(-411,1); gen->AddPdg( 421,2); @@ -30,6 +30,9 @@ FairGenerator* gen->AddPdg( 4122,8); gen->AddPdg(-4122,9); gen->AddPdg( 333,10); + gen->AddPdg(-333,11); + gen->AddPdg( 313,12); + gen->AddPdg(-313,13); } else{ gen->SetPolarization(1); //Transversal @@ -38,21 +41,24 @@ FairGenerator* gen->AddPdg(100443,1); gen->AddPdg(223,2); } - + TString pathO2 = gSystem->ExpandPathName("$O2DPG_MC_CONFIG_ROOT/MC/config/PWGUD/external/generator/DecayTablesEvtGen"); if (configuration.find("Psi2sToMuPi") != std::string::npos) gen->SetDecayTable(Form("%s/PSI2S.MUMUPIPI.DEC",pathO2.Data())); else if (configuration.find("Psi2sToElPi") != std::string::npos) gen->SetDecayTable(Form("%s/PSI2S.EEPIPI.DEC",pathO2.Data())); else if (configuration.find("RhoPrime") != std::string::npos) gen->SetDecayTable(Form("%s/RHOPRIME.RHOPIPI.DEC",pathO2.Data())); else if (configuration.find("OmegaTo3Pi") != std::string::npos) gen->SetDecayTable(Form("%s/OMEGA.3PI.DEC",pathO2.Data())); else if (configuration.find("JpsiToElRad") != std::string::npos) gen->SetDecayTable(Form("%s/JPSI.EE.DEC",pathO2.Data())); - else if (configuration.find("ToEl3Pi") != std::string::npos) gen->SetDecayTable(Form("%s/TAUTAU.EL3PI.DEC",pathO2.Data())); - else if (configuration.find("ToPo3Pi") != std::string::npos) gen->SetDecayTable(Form("%s/TAUTAU.PO3PI.DEC",pathO2.Data())); + else if (configuration.find("ToL+3Pi") != std::string::npos) gen->SetDecayTable(Form("%s/TAUTAU.LP3PI.DEC",pathO2.Data())); + else if (configuration.find("ToL-3Pi") != std::string::npos) gen->SetDecayTable(Form("%s/TAUTAU.LN3PI.DEC",pathO2.Data())); + else if (configuration.find("ToPi+3Pi") != std::string::npos) gen->SetDecayTable(Form("%s/TAUTAU.LP3PI.DEC",pathO2.Data())); + else if (configuration.find("ToPi-3Pi") != std::string::npos) gen->SetDecayTable(Form("%s/TAUTAU.LN3PI.DEC",pathO2.Data())); + else if (configuration.find("To6Pi") != std::string::npos) gen->SetDecayTable(Form("%s/TAUTAU.6PI.DEC",pathO2.Data())); else if (configuration.find("ToElMu") != std::string::npos) gen->SetDecayTable(Form("%s/TAUTAU.ELMU.DEC",pathO2.Data())); else if (configuration.find("ToElPiPi0") != std::string::npos) gen->SetDecayTable(Form("%s/TAUTAU.ELPI.DEC",pathO2.Data())); else if (configuration.find("ToPoPiPi0") != std::string::npos) gen->SetDecayTable(Form("%s/TAUTAU.POPI.DEC",pathO2.Data())); else if (configuration.find("Jpsi4Prong") != std::string::npos) gen->SetDecayTable(Form("%s/JPSI.4PRONG.DEC",pathO2.Data())); else if (configuration.find("Jpsi6Prong") != std::string::npos) gen->SetDecayTable(Form("%s/JPSI.6PRONG.DEC",pathO2.Data())); else if (configuration.find("Dpmjet") != std::string::npos) gen->SetDecayTable(Form("%s/OPENCHARM.DEC",pathO2.Data())); - + return gen; } diff --git a/MC/config/PWGUD/external/generator/Generator_nOOn.C b/MC/config/PWGUD/external/generator/Generator_nOOn.C index dc19f9504..798c0d6b2 100644 --- a/MC/config/PWGUD/external/generator/Generator_nOOn.C +++ b/MC/config/PWGUD/external/generator/Generator_nOOn.C @@ -1,3 +1,4 @@ +R__ADD_INCLUDE_PATH($nOOn_ROOT/include) R__LOAD_LIBRARY(NeutronGenerator_cxx.so) #include "GeneratorStarlight.C" #include "NeutronGenerator.h" diff --git a/MC/config/PWGUD/ini/makeStarlightConfig.py b/MC/config/PWGUD/ini/makeStarlightConfig.py index 48feb7548..1655624c7 100755 --- a/MC/config/PWGUD/ini/makeStarlightConfig.py +++ b/MC/config/PWGUD/ini/makeStarlightConfig.py @@ -8,19 +8,19 @@ parser = argparse.ArgumentParser(description='Make Starlight configuration', formatter_class=argparse.ArgumentDefaultsHelpFormatter) -parser.add_argument('--collType',default='PbPb', choices=['PbPb', 'pPb', 'Pbp', 'pp', 'OO', 'pO', 'Op'], +parser.add_argument('--collType',default='PbPb', choices=['PbPb', 'pPb', 'Pbp', 'pp', 'OO', 'pO', 'Op', 'NeNe'], help='Colission system') - + parser.add_argument('--eCM', type=float, default='5360', help='Centre-of-mass energy') parser.add_argument('--rapidity', default='cent', choices=['cent_rap', 'muon_rap', 'cent_eta', 'muon_eta'], help='Rapidity to select') -parser.add_argument('--process',default=None, choices=['kTwoGammaToMuLow', 'kTwoGammaToElLow', 'kTwoGammaToMuMedium', 'kTwoGammaToElMedium', 'kTwoGammaToMuHigh', 'kTwoGammaToElHigh', 'kTwoGammaToRhoRho', 'kTwoGammaToF2', 'kCohRhoToPi', 'kCohRhoToElEl', 'kCohRhoToMuMu', 'kCohRhoToPiWithCont', 'kCohRhoToPiFlat', 'kCohPhiToKa', 'kDirectPhiToKaKa', 'kCohPhiToEl', 'kCohOmegaTo2Pi', 'kCohOmegaTo3Pi', 'kCohOmegaToPiPiPi', 'kCohRhoPrimeTo4Pi', 'kCohJpsiToMu', 'kCohJpsiToEl', 'kCohJpsiToElRad', 'kCohJpsiToProton', 'kCohJpsi4Prong', 'kCohJpsi6Prong', 'kCohPsi2sToMu','kCohPsi2sToEl', 'kCohPsi2sToMuPi', 'kCohPsi2sToElPi', 'kCohUpsilonToMu', 'kCohUpsilonToEl', 'kIncohRhoToPi', 'kIncohRhoToElEl', 'kIncohRhoToMuMu', 'kIncohRhoToPiWithCont', 'kIncohRhoToPiFlat', 'kIncohPhiToKa', 'kIncohOmegaTo2Pi', 'kIncohOmegaTo3Pi', 'kIncohOmegaToPiPiPi', 'kIncohRhoPrimeTo4Pi', 'kIncohJpsiToMu', 'kIncohJpsiToEl', 'kIncohJpsiToElRad', 'kIncohJpsiToProton', 'kIncohJpsiToLLbar', 'kIncohPsi2sToMu', 'kIncohPsi2sToEl', 'kIncohPsi2sToMuPi', 'kIncohPsi2sToElPi', 'kIncohUpsilonToMu', 'kIncohUpsilonToEl', 'kDpmjetSingleA', 'kDpmjetSingleA_Dzero', 'kDpmjetSingleA_Dcharged', 'kDpmjetSingleA_Dstar', 'kDpmjetSingleA_Phi', 'kDpmjetSingleA_Kstar', 'kDpmjetSingleC', 'kDpmjetSingleC_Dzero', 'kDpmjetSingleC_Dcharged', 'kDpmjetSingleC_Dstar', 'kDpmjetSingleC_Phi', 'kDpmjetSingleC_Kstar', 'kTauLowToEl3Pi', 'kTauLowToPo3Pi', 'kTauMediumToEl3Pi', 'kTauMediumToPo3Pi', 'kTauHighToEl3Pi', 'kTauHighToPo3Pi', 'kTauLowToElMu', 'kTauLowToElPiPi0', 'kTauLowToPoPiPi0'], +parser.add_argument('--process',default=None, choices=['kTwoGammaToMuLow', 'kTwoGammaToElLow', 'kTwoGammaToMuMedium', 'kTwoGammaToElMedium', 'kTwoGammaToMuHigh', 'kTwoGammaToElHigh', 'kTwoGammaToRhoRho', 'kTwoGammaToF2', 'kCohRhoToPi', 'kCohRhoToElEl', 'kCohRhoToMuMu', 'kCohRhoToPiWithCont', 'kCohRhoToPiFlat', 'kCohPhiToKa', 'kDirectPhiToKaKa', 'kCohPhiToEl', 'kCohOmegaTo2Pi', 'kCohOmegaTo3Pi', 'kCohOmegaToPiPiPi', 'kCohRhoPrimeTo4Pi', 'kCohJpsiToMu', 'kCohJpsiToEl', 'kCohJpsiToElRad', 'kCohJpsiToProton', 'kCohJpsiToLLbar', 'kCohJpsi4Prong', 'kCohJpsi6Prong', 'kCohPsi2sToMu','kCohPsi2sToEl', 'kCohPsi2sToMuPi', 'kCohPsi2sToElPi', 'kCohUpsilonToMu', 'kCohUpsilonToEl', 'kIncohRhoToPi', 'kIncohRhoToElEl', 'kIncohRhoToMuMu', 'kIncohRhoToPiWithCont', 'kIncohRhoToPiFlat', 'kIncohPhiToKa', 'kIncohOmegaTo2Pi', 'kIncohOmegaTo3Pi', 'kIncohOmegaToPiPiPi', 'kIncohRhoPrimeTo4Pi', 'kIncohJpsiToMu', 'kIncohJpsiToEl', 'kIncohJpsiToElRad', 'kIncohJpsiToProton', 'kIncohJpsiToLLbar', 'kIncohPsi2sToMu', 'kIncohPsi2sToEl', 'kIncohPsi2sToMuPi', 'kIncohPsi2sToElPi', 'kIncohUpsilonToMu', 'kIncohUpsilonToEl', 'kDpmjetSingleA', 'kDpmjetSingleA_Dzero', 'kDpmjetSingleA_Lc', 'kDpmjetSingleA_Dcharged', 'kDpmjetSingleA_Dstar', 'kDpmjetSingleA_Phi', 'kDpmjetSingleA_Kstar', 'kDpmjetSingleC', 'kDpmjetSingleC_Dzero', 'kDpmjetSingleC_Lc', 'kDpmjetSingleC_Dcharged', 'kDpmjetSingleC_Dstar', 'kDpmjetSingleC_Phi', 'kDpmjetSingleC_Kstar', 'kTauLowToL+3Pi', 'kTauLowToL-3Pi', 'kTauLowToPi+3Pi', 'kTauLowToPi-3Pi', 'kTauLowTo6Pi', 'kTauLowToElMu', 'kTauLowToElPiPi0', 'kTauLowToPoPiPi0'], help='Process to switch on') - - + + parser.add_argument('--output', default='GenStarlight.ini', help='Where to write the configuration') @@ -63,17 +63,22 @@ pZ = 8 pA = 16 tZ = 8 - tA = 16 + tA = 16 if 'pO' in args.collType: pZ = 1 pA = 1 tZ = 8 - tA = 16 + tA = 16 if 'Op' in args.collType: pZ = 8 pA = 16 tZ = 1 - tA = 1 + tA = 1 +if 'NeNe' in args.collType: + pZ = 10 + pA = 20 + tZ = 10 + tA = 20 ### open output file fout = open(args.output, 'w') @@ -90,7 +95,7 @@ else: fout.write('fileName = ${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGUD/external/generator/GeneratorStarlight.C \n') fout.write('funcName = GeneratorStarlight("%s", %f, %d, %d, %d, %d, "%s", "%s") \n' % (args.process.split('_')[0],args.eCM ,pZ,pA,tZ,tA,args.extraPars,args.dpmjetConf)) - + ###Trigger if not 'kDpmjet' in args.process: fout.write('[TriggerExternal] \n') @@ -122,6 +127,8 @@ fout.write('funcName = triggerPhi(-0.9,0.9) \n') if 'Kstar' in args.process: fout.write('funcName = triggerKstar(-0.9,0.9) \n') + if 'Lc' in args.process: + fout.write('funcName = triggerLc(-0.9,0.9) \n') ### close outout file fout.close() diff --git a/MC/config/PWGUD/trigger/triggerDpmjetParticle.C b/MC/config/PWGUD/trigger/triggerDpmjetParticle.C index 9d3a99c00..acc9cf258 100644 --- a/MC/config/PWGUD/trigger/triggerDpmjetParticle.C +++ b/MC/config/PWGUD/trigger/triggerDpmjetParticle.C @@ -14,7 +14,7 @@ o2::eventgen::Trigger triggerDzero(double rapidityMin = -1., double rapidityMax if ((particle.Y() > rapidityMin) && (particle.Y() < rapidityMax)) return kTRUE; } - return kFALSE; + return kFALSE; }; } @@ -45,10 +45,10 @@ o2::eventgen::Trigger triggerDstar(double rapidityMin = -1., double rapidityMax o2::eventgen::Trigger triggerPhi(double rapidityMin = -1., double rapidityMax = -1.) { return [rapidityMin, rapidityMax](const std::vector& particles) -> bool { - for (std::vector::size_type i = 0; i != (particles.size()-1); i++) { - if ((particles[i].GetPdgCode() == 321 && particles[i+1].GetPdgCode() == -321) || (particles[i].GetPdgCode() == -321 && particles[i+1].GetPdgCode() == 321)) - if ((particles[i].Eta() > rapidityMin) && (particles[i].Eta() < rapidityMax) && (particles[i+1].Eta() > rapidityMin) && (particles[i+1].Eta() < rapidityMax)) - return kTRUE; + for (const auto& particle : particles) { + if (TMath::Abs(particle.GetPdgCode()) == 333) + if ((particle.Y() > rapidityMin) && (particle.Y() < rapidityMax)) + return kTRUE; } return kFALSE; }; @@ -57,10 +57,22 @@ o2::eventgen::Trigger triggerPhi(double rapidityMin = -1., double rapidityMax = o2::eventgen::Trigger triggerKstar(double rapidityMin = -1., double rapidityMax = -1.) { return [rapidityMin, rapidityMax](const std::vector& particles) -> bool { - for (std::vector::size_type i = 0; i != (particles.size()-1); i++) { - if ((particles[i].GetPdgCode() == 321 && particles[i+1].GetPdgCode() == -211) || (particles[i].GetPdgCode() == -211 && particles[i+1].GetPdgCode() == 321)) - if ((particles[i].Eta() > rapidityMin) && (particles[i].Eta() < rapidityMax) && (particles[i+1].Eta() > rapidityMin) && (particles[i+1].Eta() < rapidityMax)) - return kTRUE; + for (const auto& particle : particles) { + if (TMath::Abs(particle.GetPdgCode()) == 313) + if ((particle.Y() > rapidityMin) && (particle.Y() < rapidityMax)) + return kTRUE; + } + return kFALSE; + }; +} + +o2::eventgen::Trigger triggerLc(double rapidityMin = -1., double rapidityMax = -1.) +{ + return [rapidityMin, rapidityMax](const std::vector& particles) -> bool { + for (const auto& particle : particles) { + if (TMath::Abs(particle.GetPdgCode()) == 4122) + if ((particle.Y() > rapidityMin) && (particle.Y() < rapidityMax)) + return kTRUE; } return kFALSE; }; diff --git a/MC/config/QC/json/ITSTPCmatchedTracks_direct_MC.json b/MC/config/QC/json/ITSTPCmatchedTracks_direct_MC.json index 5aba15f8a..8b80ff34f 100644 --- a/MC/config/QC/json/ITSTPCmatchedTracks_direct_MC.json +++ b/MC/config/QC/json/ITSTPCmatchedTracks_direct_MC.json @@ -41,7 +41,7 @@ "taskParameters": { "GID": "ITS-TPC,ITS", "verbose": "false", - "minPtITSCut": "0.f", + "minPtITSCut": "0.1f", "etaITSCut": "1e10f", "minNITSClustersCut": "0", "maxChi2PerClusterITS": "100000", @@ -50,8 +50,8 @@ "minNTPCClustersCut": "60", "minDCACut": "100.f", "minDCACutY": "10.f", - "minPtCut": "0.f", - "maxPtCut": "1e10f", + "minPtCut": "0.1f", + "maxPtCut": "20.f", "etaCut": "1e10f", "isMC": "true" }, diff --git a/MC/config/QC/json/fdd-recpoints.json b/MC/config/QC/json/fdd-recpoints.json new file mode 100644 index 000000000..8f61b6893 --- /dev/null +++ b/MC/config/QC/json/fdd-recpoints.json @@ -0,0 +1,38 @@ +{ + "qc": { + "config": { + "database": { + "implementation": "CCDB", + "host": "ccdb-test.cern.ch:8080", + "username": "not_applicable", + "password": "not_applicable", + "name": "not_applicable" + }, + "Activity": { + "provenance": "qc_mc", + "passName": "passMC", + "periodName": "SimChallenge" + }, + "monitoring": { + "url": "no-op://" + }, + "conditionDB": { + "url": "alice-ccdb.cern.ch" + } + }, + "tasks": { + "RecPoints": { + "active": "true", + "className": "o2::quality_control_modules::fdd::RecPointsQcTask", + "moduleName": "QcFDD", + "detectorName": "FDD", + "cycleDurationSeconds": "600", + "maxNumberCycles": "-1", + "dataSource": { + "type": "direct", + "query": "recpoints:FDD/RECPOINTS/0;channels:FDD/RECCHDATA/0" + } + } + } + } +} \ No newline at end of file diff --git a/MC/config/QC/json/ft0-reconstruction-config.json b/MC/config/QC/json/ft0-reconstruction-config.json index bebf3faf5..95b93f6f6 100644 --- a/MC/config/QC/json/ft0-reconstruction-config.json +++ b/MC/config/QC/json/ft0-reconstruction-config.json @@ -36,6 +36,16 @@ "dataSource": { "type": "direct", "query": "recpoints:FT0/RECPOINTS/0;channels:FT0/RECCHDATA/0" + }, + "grpGeomRequest" : { + "geomRequest": "None", + "askGRPECS": "false", + "askGRPLHCIF": "true", + "askGRPMagField": "false", + "askMatLUT": "false", + "askTime": "false", + "askOnceAllButField": "false", + "needPropagatorD": "false" } } } diff --git a/MC/config/QC/json/fv0-digits.json b/MC/config/QC/json/fv0-digits.json new file mode 100644 index 000000000..dbb559621 --- /dev/null +++ b/MC/config/QC/json/fv0-digits.json @@ -0,0 +1,51 @@ +{ + "qc": { + "config": { + "database": { + "implementation": "CCDB", + "host": "ccdb-test.cern.ch:8080", + "username": "not_applicable", + "password": "not_applicable", + "name": "not_applicable" + }, + "Activity": { + "provenance": "qc_mc", + "passName": "passMC", + "periodName": "SimChallenge" + }, + "monitoring": { + "url": "no-op://" + }, + "conditionDB": { + "url": "alice-ccdb.cern.ch" + } + }, + "tasks": { + "Digits": { + "active": "true", + "className": "o2::quality_control_modules::fv0::DigitQcTask", + "moduleName": "QcFV0", + "detectorName": "FV0", + "cycleDurationSeconds": "600", + "maxNumberCycles": "-1", + "dataSource": { + "type": "direct", + "query": "digits:FV0/DIGITSBC/0;channels:FV0/DIGITSCH/0" + }, + "taskParameters": { + "#ChannelIDs": "0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48", + "#ChannelIDsAmpVsTime": "0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48", + "trgModeInnerOuterThresholdVar": "Ampl", + "trgThresholdNChannels": "2", + "trgThresholdCharge": "8", + "trgThresholdChargeInner": "4", + "trgThresholdChargeOuter": "4", + "trgChargeLevelLow": "6", + "trgChargeLevelHigh": "4095", + "minGateTimeForRatioHistogram": "-192", + "maxGateTimeForRatioHistogram": "192" + } + } + } + } +} \ No newline at end of file diff --git a/MC/config/QC/json/hmp.json b/MC/config/QC/json/hmp.json new file mode 100644 index 000000000..2995fef64 --- /dev/null +++ b/MC/config/QC/json/hmp.json @@ -0,0 +1,57 @@ +{ + "qc":{ + "config":{ + "database":{ + "implementation":"CCDB", + "host":"ccdb-test.cern.ch:8080", + "username":"not_applicable", + "password":"not_applicable", + "name":"not_applicable" + }, + "Activity":{ + "number": "42", + "type": "2", + "provenance": "qc_mc", + "passName": "passMC", + "periodName": "SimChallenge" + }, + "monitoring":{ + "url":"infologger:///debug?qc" + }, + "consul":{ + "url":"http://consul-test.cern.ch:8500" + }, + "conditionDB":{ + "url":"ccdb-test.cern.ch:8080" + } + }, + "tasks": { + "HMPClusters":{ + "active":"true", + "taskName" : "Clusters", + "className":"o2::quality_control_modules::hmpid::HmpidTaskClusters", + "moduleName":"QcHMPID", + "detectorName":"HMP", + "cycleDurationSeconds":"60", + "maxNumberCycles":"-1", + "dataSource": { + "type":"direct", + "query":"intrecord:HMP/INTRECORDS1/0;clusters:HMP/CLUSTERS/0" + } + }, + "HMPMatches":{ + "active":"true", + "taskName" : "Matches", + "className":"o2::quality_control_modules::hmpid::HmpidTaskMatches", + "moduleName":"QcHMPID", + "detectorName":"HMP", + "cycleDurationSeconds":"60", + "maxNumberCycles":"-1", + "dataSource": { + "type":"direct", + "query":"matchHMP:HMP/MATCHES/0;hmpidcluster:HMP/CLUSTERS/0;hmpidtriggers:HMP/INTRECORDS1/0" + } + } + } + } +} diff --git a/MC/config/QC/json/mch-digits-task.json b/MC/config/QC/json/mch-digits-task.json new file mode 100644 index 000000000..aad04c70a --- /dev/null +++ b/MC/config/QC/json/mch-digits-task.json @@ -0,0 +1,58 @@ +{ + "qc": { + "config": { + "database": { + "implementation": "CCDB", + "host": "localhost:6464", + "username": "not_applicable", + "password": "not_applicable", + "name": "not_applicable", + "maxObjectSize": "12582912" + }, + "Activity": { + "number": "42", + "type": "2", + "provenance": "qc_mc", + "passName": "passMC", + "periodName": "SimChallenge" + }, + "monitoring": { + "url": "infologger:///debug?qc" + }, + "consul": { + "url": "" + }, + "conditionDB": { + "url": "" + } + }, + "tasks": { + "MCHDigits": { + "active": "true", + "taskName": "Digits", + "className": "o2::quality_control_modules::muonchambers::DigitsTask", + "moduleName": "QcMuonChambers", + "detectorName": "MCH", + "cycleDurationSeconds": "300", + "maxNumberCycles": "-1", + "dataSource": { + "type": "direct", + "query": "digits:MCH/DIGITS" + }, + "taskParameters": { + "Diagnostic": "false" + }, + "grpGeomRequest": { + "geomRequest": "None", + "askGRPECS": "true", + "askGRPLHCIF": "false", + "askGRPMagField": "false", + "askMatLUT": "false", + "askTime": "false", + "askOnceAllButField": "false", + "needPropagatorD": "false" + } + } + } + } +} diff --git a/MC/config/QC/json/mch-errors-task.json b/MC/config/QC/json/mch-errors-task.json new file mode 100644 index 000000000..154cb3c75 --- /dev/null +++ b/MC/config/QC/json/mch-errors-task.json @@ -0,0 +1,44 @@ +{ + "qc": { + "config": { + "database": { + "implementation": "CCDB", + "host": "http://ccdb-test.cern.ch:8080", + "username": "not_applicable", + "password": "not_applicable", + "name": "not_applicable" + }, + "Activity": { + "number": "42", + "type": "2", + "provenance": "qc_mc", + "passName": "passMC", + "periodName": "SimChallenge" + }, + "monitoring": { + "url": "infologger:///debug?qc" + }, + "consul": { + "url": "" + }, + "conditionDB": { + "url": "" + } + }, + "tasks": { + "MCHErrors": { + "active": "true", + "taskName": "Errors", + "className": "o2::quality_control_modules::muonchambers::ErrorTask", + "moduleName": "QcMuonChambers", + "detectorName": "MCH", + "cycleDurationSeconds": "600", + "maxNumberCycles": "-1", + "dataSource": { + "type": "direct", + "query": "errors:MCH/PROCERRORS/0" + } + } + } + } +} diff --git a/MC/config/QC/json/mch-reco-task.json b/MC/config/QC/json/mch-reco-task.json new file mode 100644 index 000000000..e6f2b719b --- /dev/null +++ b/MC/config/QC/json/mch-reco-task.json @@ -0,0 +1,74 @@ +{ + "qc": { + "config": { + "database": { + "implementation": "CCDB", + "host": "localhost:6464", + "username": "not_applicable", + "password": "not_applicable", + "name": "not_applicable" + }, + "Activity": { + "number": "42", + "type": "2", + "provenance": "qc_mc", + "passName": "passMC", + "periodName": "SimChallenge" + }, + "monitoring": { + "url": "infologger:///debug?qc" + }, + "consul": { + "url": "" + }, + "conditionDB": { + "url": "" + } + }, + "tasks": { + "Rofs": { + "active": "true", + "className": "o2::quality_control_modules::muonchambers::RofsTask", + "moduleName": "QcMuonChambers", + "detectorName": "MCH", + "cycleDurationSeconds": "300", + "maxNumberCycles": "-1", + "dataSource": { + "type": "direct", + "query": "digits:MCH/DIGITS;rofs:MCH/DIGITROFS" + }, + "taskParameters": { + "Diagnostic": "false" + } + }, + "MCHPreclusters": { + "active": "true", + "taskName": "Preclusters", + "className": "o2::quality_control_modules::muonchambers::PreclustersTask", + "moduleName": "QcMuonChambers", + "detectorName": "MCH", + "cycleDurationSeconds": "300", + "maxNumberCycles": "-1", + "dataSource": { + "type": "direct", + "query": "preclusters:MCH/PRECLUSTERS/0;preclusterdigits:MCH/PRECLUSTERDIGITS/0" + } + }, + "FRofs": { + "active": "true", + "className": "o2::quality_control_modules::muonchambers::RofsTask", + "moduleName": "QcMuonChambers", + "detectorName": "MCH", + "cycleDurationSeconds": "300", + "maxNumberCycles": "-1", + "dataSource": { + "type": "direct", + "query": "digits:MCH/F-DIGITS;rofs:MCH/TC-F-DIGITROFS" + }, + "taskParameters": { + "Diagnostic": "false" + } + } + } + } +} diff --git a/MC/config/QC/json/mch-tracks-task.json b/MC/config/QC/json/mch-tracks-task.json new file mode 100644 index 000000000..6b4d9fc64 --- /dev/null +++ b/MC/config/QC/json/mch-tracks-task.json @@ -0,0 +1,58 @@ +{ + "qc": { + "config": { + "database": { + "implementation": "CCDB", + "host": "localhost:6464", + "username": "not_applicable", + "password": "not_applicable", + "name": "not_applicable" + }, + "Activity": { + "number": "42", + "type": "2", + "provenance": "qc_mc", + "passName": "passMC", + "periodName": "SimChallenge" + }, + "monitoring": { + "url": "infologger:///debug?qc" + }, + "consul": { + "url": "" + }, + "conditionDB": { + "url": "https://alice-ccdb.cern.ch" + } + }, + "tasks": { + "MCHTracks": { + "active": "true", + "taskName": "Tracks", + "className": "o2::quality_control_modules::muon::TracksTask", + "moduleName": "QcMUONCommon", + "detectorName": "MCH", + "cycleDurationSeconds": "180", + "maxNumberCycles": "-1", + "dataSource": { + "type": "direct", + "query": "trackMCH:MCH/TRACKS;trackMCHROF:MCH/TRACKROFS;trackMCHTRACKCLUSTERS:MCH/TRACKCLUSTERS;mchtrackdigits:MCH/CLUSTERDIGITS" + }, + "taskParameters": { + "maxTracksPerTF": "600", + "GID": "MCH" + }, + "grpGeomRequest": { + "geomRequest": "Aligned", + "askGRPECS": "true", + "askGRPLHCIF": "false", + "askGRPMagField": "true", + "askMatLUT": "false", + "askTime": "false", + "askOnceAllButField": "true", + "needPropagatorD": "false" + } + } + } + } +} diff --git a/MC/config/QC/json/mchmid-tracks-task.json b/MC/config/QC/json/mchmid-tracks-task.json new file mode 100644 index 000000000..67c6e22f9 --- /dev/null +++ b/MC/config/QC/json/mchmid-tracks-task.json @@ -0,0 +1,59 @@ +{ + "qc": { + "config": { + "database": { + "implementation": "CCDB", + "host": "localhost:6464", + "username": "not_applicable", + "password": "not_applicable", + "name": "not_applicable" + }, + "Activity": { + "number": "42", + "type": "2", + "provenance": "qc_mc", + "passName": "passMC", + "periodName": "SimChallenge" + }, + "monitoring": { + "url": "infologger:///debug?qc" + }, + "consul": { + "url": "" + }, + "conditionDB": { + "url": "https://alice-ccdb.cern.ch" + } + }, + "tasks": { + "TaskMUONTracks": { + "active": "true", + "className": "o2::quality_control_modules::muon::TracksTask", + "moduleName": "QcMUONCommon", + "detectorName": "GLO", + "taskName": "MUONTracks", + "cycleDurationSeconds": "300", + "maxNumberCycles": "-1", + "dataSource": { + "type": "direct", + "query": "trackMCH:MCH/TRACKS;trackMCHROF:MCH/TRACKROFS;trackMCHTRACKCLUSTERS:MCH/TRACKCLUSTERS;mchtrackdigits:MCH/CLUSTERDIGITS;trackMID:MID/TRACKS/0;trackMIDROF:MID/TRACKROFS/0;trackMIDTRACKCLUSTERS:MID/TRACKCLUSTERS/0;trackClMIDROF:MID/TRCLUSROFS/0;matchMCHMID:GLO/MTC_MCHMID" + }, + "taskParameters": { + "maxTracksPerTF": "600", + "GID" : "MCH,MID,MCH-MID" + }, + "grpGeomRequest": { + "geomRequest": "Aligned", + "askGRPECS": "true", + "askGRPLHCIF": "false", + "askGRPMagField": "true", + "askMatLUT": "false", + "askTime": "false", + "askOnceAllButField": "false", + "needPropagatorD": "false" + }, + "location": "remote" + } + } + } +} diff --git a/MC/config/QC/json/mftmch-tracks-task.json b/MC/config/QC/json/mftmch-tracks-task.json new file mode 100644 index 000000000..d90420ea1 --- /dev/null +++ b/MC/config/QC/json/mftmch-tracks-task.json @@ -0,0 +1,59 @@ +{ + "qc": { + "config": { + "database": { + "implementation": "CCDB", + "host": "localhost:6464", + "username": "not_applicable", + "password": "not_applicable", + "name": "not_applicable" + }, + "Activity": { + "number": "42", + "type": "2", + "provenance": "qc_mc", + "passName": "passMC", + "periodName": "SimChallenge" + }, + "monitoring": { + "url": "infologger:///debug?qc" + }, + "consul": { + "url": "" + }, + "conditionDB": { + "url": "https://alice-ccdb.cern.ch" + } + }, + "tasks": { + "TaskMUONTracks": { + "active": "true", + "className": "o2::quality_control_modules::muon::TracksTask", + "moduleName": "QcMUONCommon", + "detectorName": "GLO", + "taskName": "MUONTracks", + "cycleDurationSeconds": "300", + "maxNumberCycles": "-1", + "dataSource": { + "type": "direct", + "query": "trackMCH:MCH/TRACKS;trackMCHROF:MCH/TRACKROFS;trackMCHTRACKCLUSTERS:MCH/TRACKCLUSTERS;mchtrackdigits:MCH/CLUSTERDIGITS;trackMFT:MFT/TRACKS;trackMFTROF:MFT/MFTTrackROF;trackMFTClIdx:MFT/TRACKCLSID;alpparMFT:MFT/ALPIDEPARAM/0?lifetime=condition&ccdb-path=MFT/Config/AlpideParam;fwdtracks:GLO/GLFWD" + }, + "taskParameters": { + "maxTracksPerTF": "600", + "GID" : "MCH,MFT,MFT-MCH" + }, + "grpGeomRequest": { + "geomRequest": "Aligned", + "askGRPECS": "true", + "askGRPLHCIF": "false", + "askGRPMagField": "true", + "askMatLUT": "false", + "askTime": "false", + "askOnceAllButField": "false", + "needPropagatorD": "false" + }, + "location": "remote" + } + } + } +} diff --git a/MC/config/QC/json/mftmchmid-tracks-task.json b/MC/config/QC/json/mftmchmid-tracks-task.json new file mode 100644 index 000000000..6f82b5038 --- /dev/null +++ b/MC/config/QC/json/mftmchmid-tracks-task.json @@ -0,0 +1,106 @@ +{ + "qc": { + "config": { + "database": { + "implementation": "CCDB", + "host": "localhost:6464", + "username": "not_applicable", + "password": "not_applicable", + "name": "not_applicable" + }, + "Activity": { + "number": "42", + "type": "2", + "provenance": "qc_mc", + "passName": "passMC", + "periodName": "SimChallenge" + }, + "monitoring": { + "url": "infologger:///debug?qc" + }, + "consul": { + "url": "" + }, + "conditionDB": { + "url": "https://alice-ccdb.cern.ch" + } + }, + "tasks": { + "TaskMUONTracks": { + "active": "true", + "className": "o2::quality_control_modules::muon::TracksTask", + "moduleName": "QcMUONCommon", + "detectorName": "GLO", + "taskName": "MUONTracks", + "cycleDurationSeconds": "300", + "maxNumberCycles": "-1", + "dataSource": { + "type": "direct", + "query": "trackMCH:MCH/TRACKS;trackMCHROF:MCH/TRACKROFS;trackMCHTRACKCLUSTERS:MCH/TRACKCLUSTERS;mchtrackdigits:MCH/CLUSTERDIGITS;trackMFT:MFT/TRACKS;trackMFTROF:MFT/MFTTrackROF;trackMFTClIdx:MFT/TRACKCLSID;alpparMFT:MFT/ALPIDEPARAM/0?lifetime=condition&ccdb-path=MFT/Config/AlpideParam;fwdtracks:GLO/GLFWD;trackMID:MID/TRACKS/0;trackMIDROF:MID/TRACKROFS/0;trackMIDTRACKCLUSTERS:MID/TRACKCLUSTERS/0;trackClMIDROF:MID/TRCLUSROFS/0;matchMCHMID:GLO/MTC_MCHMID" + }, + "taskParameters": { + "maxTracksPerTF": "600", + "cutRAbsMin": "17.6", + "cutRAbsMax": "89.5", + "cutEtaMin": "-4.0", + "cutEtaMax": "-2.5", + "cutPtMin": "0.5", + "nSigmaPDCA": "6", + "cutChi2Max": "1000", + "diMuonTimeCut": "100", + "fullHistos": "0", + "GID" : "MCH,MCH-MID" + }, + "grpGeomRequest": { + "geomRequest": "Aligned", + "askGRPECS": "true", + "askGRPLHCIF": "false", + "askGRPMagField": "true", + "askMatLUT": "false", + "askTime": "false", + "askOnceAllButField": "false", + "needPropagatorD": "false" + }, + "location": "remote" + }, + "TaskMUONTracksMFT": { + "active": "true", + "className": "o2::quality_control_modules::muon::TracksTask", + "moduleName": "QcMUONCommon", + "detectorName": "GLO", + "taskName": "MUONTracksMFT", + "cycleDurationSeconds": "300", + "maxNumberCycles": "-1", + "dataSource": { + "type": "direct", + "query": "trackMCH:MCH/TRACKS;trackMCHROF:MCH/TRACKROFS;trackMCHTRACKCLUSTERS:MCH/TRACKCLUSTERS;mchtrackdigits:MCH/CLUSTERDIGITS;trackMFT:MFT/TRACKS;trackMFTROF:MFT/MFTTrackROF;trackMFTClIdx:MFT/TRACKCLSID;alpparMFT:MFT/ALPIDEPARAM/0?lifetime=condition&ccdb-path=MFT/Config/AlpideParam;fwdtracks:GLO/GLFWD;trackMID:MID/TRACKS/0;trackMIDROF:MID/TRACKROFS/0;trackMIDTRACKCLUSTERS:MID/TRACKCLUSTERS/0;trackClMIDROF:MID/TRCLUSROFS/0;matchMCHMID:GLO/MTC_MCHMID" + }, + "taskParameters": { + "maxTracksPerTF": "600", + "cutRAbsMin": "26.5", + "cutRAbsMax": "89.5", + "cutEtaMin": "-3.3", + "cutEtaMax": "-2.5", + "cutPtMin": "0.5", + "nSigmaPDCA": "6", + "cutChi2Max": "1000", + "matchChi2MaxMFT": "45", + "diMuonTimeCut": "100", + "fullHistos": "0", + "GID" : "MCH,MFT-MCH,MCH-MID,MFT-MCH-MID" + }, + "grpGeomRequest": { + "geomRequest": "Aligned", + "askGRPECS": "true", + "askGRPLHCIF": "false", + "askGRPMagField": "true", + "askMatLUT": "false", + "askTime": "false", + "askOnceAllButField": "false", + "needPropagatorD": "false" + }, + "location": "remote" + } + } + } +} diff --git a/MC/config/QC/json/mid-task.json b/MC/config/QC/json/mid-task.json index 1f76d7ef2..6d5671bce 100644 --- a/MC/config/QC/json/mid-task.json +++ b/MC/config/QC/json/mid-task.json @@ -35,7 +35,7 @@ "cycleDurationSeconds": "60", "dataSource": { "type": "direct", - "query": "digits:MID/DATA;digits_rof:MID/DATAROF" + "query": "digits:MID/DATA/0;digits_rof:MID/DATAROF/0" } }, "MIDClusters": { @@ -47,7 +47,7 @@ "cycleDurationSeconds": "60", "dataSource": { "type": "direct", - "query": "clusters:MID/TRACKCLUSTERS;clusterrofs:MID/TRCLUSROFS" + "query": "clusters:MID/TRACKCLUSTERS/0;clusterrofs:MID/TRCLUSROFS/0" } }, "MIDTracks": { @@ -59,7 +59,7 @@ "cycleDurationSeconds": "60", "dataSource": { "type": "direct", - "query": "tracks:MID/TRACKS;trackrofs:MID/TRACKROFS" + "query": "tracks:MID/TRACKS/0;trackrofs:MID/TRACKROFS/0" } } }, diff --git a/MC/config/analysis_testing/json/analyses_config.json b/MC/config/analysis_testing/json/analyses_config.json index 2b1f0ae77..bc2998ce4 100644 --- a/MC/config/analysis_testing/json/analyses_config.json +++ b/MC/config/analysis_testing/json/analyses_config.json @@ -6,8 +6,8 @@ "expected_output": ["AnalysisResults.root"], "valid_mc": true, "valid_data": false, - "tasks": ["o2-analysis-timestamp", - "o2-analysis-track-propagation", + "tasks": ["o2-analysis-event-selection-service", + "o2-analysis-propagationservice", "o2-analysistutorial-mc-histograms"] }, { @@ -16,10 +16,9 @@ "expected_output": ["AnalysisResults.root"], "valid_mc": true, "valid_data": true, - "tasks": ["o2-analysis-timestamp", - "o2-analysis-track-propagation", + "tasks": ["o2-analysis-event-selection-service", + "o2-analysis-propagationservice", "o2-analysis-trackselection", - "o2-analysis-event-selection", "o2-analysis-qa-efficiency"] }, { @@ -28,10 +27,9 @@ "expected_output": ["AnalysisResults.root"], "valid_mc": true, "valid_data": true, - "tasks": ["o2-analysis-timestamp", - "o2-analysis-track-propagation", + "tasks": ["o2-analysis-event-selection-service", + "o2-analysis-propagationservice", "o2-analysis-trackselection", - "o2-analysis-event-selection", "o2-analysis-qa-event-track"] }, { @@ -40,18 +38,14 @@ "expected_output": ["AnalysisResults.root"], "valid_mc": true, "valid_data": true, - "tasks": ["o2-analysis-lf-lambdakzerobuilder", - "o2-analysis-track-propagation", - "o2-analysis-trackselection", - "o2-analysis-pid-tof-base", - "o2-analysis-pid-tof", - "o2-analysis-pid-tof-full", - "o2-analysis-pid-tpc-base", - "o2-analysis-pid-tpc", - "o2-analysis-event-selection", - "o2-analysis-timestamp", - "o2-analysis-multiplicity-table", - "o2-analysis-qa-k0s-tracking-efficiency", + "tasks": ["o2-analysis-trackselection", + "o2-analysis-pid-tof-merge", + "o2-analysis-lf-strangenesstofpid", + "o2-analysis-pid-tpc-service", + "o2-analysis-event-selection-service", + "o2-analysis-multcenttable", + "o2-analysis-ft0-corrected-table", + "o2-analysis-propagationservice", "o2-analysis-perf-k0s-resolution"] }, { @@ -61,21 +55,16 @@ "valid_mc": true, "valid_data": true, "tasks": ["o2-analysis-ft0-corrected-table", - "o2-analysis-timestamp", - "o2-analysis-track-propagation", + "o2-analysis-event-selection-service", + "o2-analysis-propagationservice", "o2-analysis-trackselection", - "o2-analysis-event-selection", - "o2-analysis-multiplicity-table", - "o2-analysis-pid-tof-base", - "o2-analysis-pid-tof", - "o2-analysis-pid-tof-full", + "o2-analysis-multcenttable", + "o2-analysis-pid-tof-merge", "o2-analysis-pid-tof-qa", "o2-analysis-pid-tof-qa-evtime", - "o2-analysis-pid-tof-beta", "o2-analysis-pid-tof-qa-beta", "o2-analysis-pid-tpc-qa", - "o2-analysis-pid-tpc-base", - "o2-analysis-pid-tpc"] + "o2-analysis-pid-tpc-service"] }, { "name": "PWGMMMFT", @@ -83,11 +72,11 @@ "expected_output": ["AnalysisResults.root"], "valid_mc": true, "valid_data": true, - "tasks": ["o2-analysis-timestamp", - "o2-analysis-track-propagation", + "tasks": ["o2-analysis-event-selection-service", + "o2-analysis-propagationservice", "o2-analysis-trackselection", - "o2-analysis-event-selection", - "o2-analysis-multiplicity-table", + "o2-analysis-multcenttable", + "o2-analysis-fwdtrack-to-collision-associator", "o2-analysis-mm-track-propagation", "o2-analysis-mm-dndeta-mft"] }, @@ -97,11 +86,23 @@ "expected_output": ["AnalysisResults.root"], "valid_mc": true, "valid_data": true, - "tasks": ["o2-analysis-timestamp", - "o2-analysis-track-propagation", - "o2-analysis-event-selection", + "tasks": ["o2-analysis-event-selection-service", + "o2-analysis-propagationservice", "o2-analysis-event-selection-qa"] }, + { + "name": "TimeDependentQA", + "enabled": true, + "expected_output": ["AnalysisResults.root"], + "valid_mc": true, + "valid_data": true, + "tasks": ["o2-analysis-event-selection-service", + "o2-analysis-propagationservice", + "o2-analysis-trackselection", + "o2-analysis-multcenttable", + "o2-analysis-ft0-corrected-table", + "o2-analysis-time-dependent-qa"] + }, { "name": "CheckDataModelMC", "enabled": true, @@ -116,7 +117,7 @@ "expected_output": ["AnalysisResults.root"], "valid_mc": true, "valid_data": false, - "tasks": ["o2-analysis-timestamp", + "tasks": ["o2-analysis-event-selection-service", "o2-analysis-mm-vertexing-fwd"] }, { @@ -125,10 +126,9 @@ "expected_output": ["AnalysisResults.root"], "valid_mc": true, "valid_data": false, - "tasks": ["o2-analysis-timestamp", - "o2-analysis-track-propagation", + "tasks": ["o2-analysis-event-selection-service", + "o2-analysis-propagationservice", "o2-analysis-trackselection", - "o2-analysis-event-selection", "o2-analysis-task-mc-simple-qc"] }, { @@ -142,12 +142,10 @@ "o2-analysis-je-emcal-correction-task", "o2-analysis-je-emc-clustermonitor", "o2-analysis-je-emc-tmmonitor", - "o2-analysis-timestamp", - "o2-analysis-track-propagation", + "o2-analysis-event-selection-service", + "o2-analysis-propagationservice", "o2-analysis-trackselection", - "o2-analysis-event-selection", - "o2-analysis-pid-tpc", - "o2-analysis-pid-tpc-base" + "o2-analysis-pid-tpc-service" ] }, { @@ -156,13 +154,32 @@ "expected_output": ["AnalysisResults.root"], "valid_mc": true, "valid_data": true, - "tasks": ["o2-analysis-timestamp", - "o2-analysis-track-propagation", + "tasks": ["o2-analysis-event-selection-service", + "o2-analysis-propagationservice", "o2-analysis-trackselection", - "o2-analysis-event-selection", - "o2-analysis-multiplicity-table", + "o2-analysis-multcenttable", "o2-analysis-ft0-corrected-table", "o2-analysis-ft0-qa"] + }, + { + "name": "HFDzeroQA", + "enabled": true, + "expected_output": ["AnalysisResults.root"], + "valid_mc": true, + "valid_data": true, + "tasks": ["o2-analysis-hf-task-d0", + "o2-analysis-hf-candidate-selector-d0", + "o2-analysis-hf-candidate-creator-2prong", + "o2-analysis-hf-track-index-skim-creator", + "o2-analysis-track-to-collision-associator", + "o2-analysis-hf-pid-creator", + "o2-analysis-trackselection", + "o2-analysis-multcenttable", + "o2-analysis-propagationservice", + "o2-analysis-event-selection-service", + "o2-analysis-pid-tpc-service", + "o2-analysis-pid-tof-merge", + "o2-analysis-ft0-corrected-table"] } ] } diff --git a/MC/config/analysis_testing/json/dpl/o2-analysis-centrality-table.json b/MC/config/analysis_testing/json/dpl/o2-analysis-centrality-table.json new file mode 100644 index 000000000..dd342777e --- /dev/null +++ b/MC/config/analysis_testing/json/dpl/o2-analysis-centrality-table.json @@ -0,0 +1,460 @@ +{ + "centrality-table": { + "processRun2": "false", + "processRun3": "true", + "processRun3Complete": "false", + "processRun3FT0": "false", + "embedINELgtZEROselection": "false", + "produceHistograms": "0", + "ccdbUrl": "http://alice-ccdb.cern.ch", + "ccdbPath": "Centrality/Estimators", + "genName": "", + "doNotCrashOnNull": "1", + "reconstructionPass": "", + "binsPercentile": { + "values": [ + 0, + 0, + 0.001, + 0.002, + 0.003, + 0.004, + 0.005, + 0.006, + 0.007, + 0.008, + 0.009, + 0.01, + 0.011, + 0.012, + 0.013, + 0.014, + 0.015, + 0.016, + 0.017, + 0.018, + 0.019, + 0.02, + 0.021, + 0.022, + 0.023, + 0.024, + 0.025, + 0.026, + 0.027, + 0.028, + 0.029, + 0.03, + 0.031, + 0.032, + 0.033, + 0.034, + 0.035, + 0.036, + 0.037, + 0.038, + 0.039, + 0.04, + 0.041, + 0.042, + 0.043, + 0.044, + 0.045, + 0.046, + 0.047, + 0.048, + 0.049, + 0.05, + 0.051, + 0.052, + 0.053, + 0.054, + 0.055, + 0.056, + 0.057, + 0.058, + 0.059, + 0.06, + 0.061, + 0.062, + 0.063, + 0.064, + 0.065, + 0.066, + 0.067, + 0.068, + 0.069, + 0.07, + 0.071, + 0.072, + 0.073, + 0.074, + 0.075, + 0.076, + 0.077, + 0.078, + 0.079, + 0.08, + 0.081, + 0.082, + 0.083, + 0.084, + 0.085, + 0.086, + 0.087, + 0.088, + 0.089, + 0.09, + 0.091, + 0.092, + 0.093, + 0.094, + 0.095, + 0.096, + 0.097, + 0.098, + 0.099, + 0.1, + 0.11, + 0.12, + 0.13, + 0.14, + 0.15, + 0.16, + 0.17, + 0.18, + 0.19, + 0.2, + 0.21, + 0.22, + 0.23, + 0.24, + 0.25, + 0.26, + 0.27, + 0.28, + 0.29, + 0.3, + 0.31, + 0.32, + 0.33, + 0.34, + 0.35, + 0.36, + 0.37, + 0.38, + 0.39, + 0.4, + 0.41, + 0.42, + 0.43, + 0.44, + 0.45, + 0.46, + 0.47, + 0.48, + 0.49, + 0.5, + 0.51, + 0.52, + 0.53, + 0.54, + 0.55, + 0.56, + 0.57, + 0.58, + 0.59, + 0.6, + 0.61, + 0.62, + 0.63, + 0.64, + 0.65, + 0.66, + 0.67, + 0.68, + 0.69, + 0.7, + 0.71, + 0.72, + 0.73, + 0.74, + 0.75, + 0.76, + 0.77, + 0.78, + 0.79, + 0.8, + 0.81, + 0.82, + 0.83, + 0.84, + 0.85, + 0.86, + 0.87, + 0.88, + 0.89, + 0.9, + 0.91, + 0.92, + 0.93, + 0.94, + 0.95, + 0.96, + 0.97, + 0.98, + 0.99, + 1, + 1.1, + 1.2, + 1.3, + 1.4, + 1.5, + 1.6, + 1.7, + 1.8, + 1.9, + 2, + 2.1, + 2.2, + 2.3, + 2.4, + 2.5, + 2.6, + 2.7, + 2.8, + 2.9, + 3, + 3.1, + 3.2, + 3.3, + 3.4, + 3.5, + 3.6, + 3.7, + 3.8, + 3.9, + 4, + 4.1, + 4.2, + 4.3, + 4.4, + 4.5, + 4.6, + 4.7, + 4.8, + 4.9, + 5, + 5.1, + 5.2, + 5.3, + 5.4, + 5.5, + 5.6, + 5.7, + 5.8, + 5.9, + 6, + 6.1, + 6.2, + 6.3, + 6.4, + 6.5, + 6.6, + 6.7, + 6.8, + 6.9, + 7, + 7.1, + 7.2, + 7.3, + 7.4, + 7.5, + 7.6, + 7.7, + 7.8, + 7.9, + 8, + 8.1, + 8.2, + 8.3, + 8.4, + 8.5, + 8.6, + 8.7, + 8.8, + 8.9, + 9, + 9.1, + 9.2, + 9.3, + 9.4, + 9.5, + 9.6, + 9.7, + 9.8, + 9.9, + 10, + 11, + 12, + 13, + 14, + 15, + 16, + 17, + 18, + 19, + 20, + 21, + 22, + 23, + 24, + 25, + 26, + 27, + 28, + 29, + 30, + 31, + 32, + 33, + 34, + 35, + 36, + 37, + 38, + 39, + 40, + 41, + 42, + 43, + 44, + 45, + 46, + 47, + 48, + 49, + 50, + 51, + 52, + 53, + 54, + 55, + 56, + 57, + 58, + 59, + 60, + 61, + 62, + 63, + 64, + 65, + 66, + 67, + 68, + 69, + 70, + 71, + 72, + 73, + 74, + 75, + 76, + 77, + 78, + 79, + 80, + 81, + 82, + 83, + 84, + 85, + 86, + 87, + 88, + 89, + 90, + 91, + 92, + 93, + 94, + 95, + 96, + 97, + 98, + 99, + 100 + ] + }, + "enabledTables": { + "labels_rows": [ + "CentRun2V0Ms", + "CentRun2V0As", + "CentRun2SPDTrks", + "CentRun2SPDClss", + "CentRun2CL0s", + "CentRun2CL1s", + "CentFV0As", + "CentFT0Ms", + "CentFT0As", + "CentFT0Cs", + "CentFT0CVariant1s", + "CentFDDMs", + "CentNTPVs", + "CentNGlobals", + "CentMFTs" + ], + "labels_cols": [ + "Enable" + ], + "values": [ + [ + -1 + ], + [ + -1 + ], + [ + -1 + ], + [ + -1 + ], + [ + -1 + ], + [ + -1 + ], + [ + -1 + ], + [ + -1 + ], + [ + -1 + ], + [ + -1 + ], + [ + -1 + ], + [ + -1 + ], + [ + -1 + ], + [ + -1 + ], + [ + -1 + ] + ] + } + } +} diff --git a/MC/config/analysis_testing/json/dpl/o2-analysis-event-selection-service.json b/MC/config/analysis_testing/json/dpl/o2-analysis-event-selection-service.json new file mode 100644 index 000000000..c17cdcb3c --- /dev/null +++ b/MC/config/analysis_testing/json/dpl/o2-analysis-event-selection-service.json @@ -0,0 +1,57 @@ +{ + "event-selection-service": { + "timestamp": { + "verbose": "0", + "fatalOnInvalidTimestamp": "0", + "rct-path": "RCT/Info/RunInformation", + "orbit-reset-path": "CTP/Calib/OrbitReset", + "isRun2MC": "-1" + }, + "bcselOpts": { + "amIneeded": "-1", + "triggerBcShift": "0", + "ITSROFrameStartBorderMargin": "-1", + "ITSROFrameEndBorderMargin": "-1", + "TimeFrameStartBorderMargin": "-1", + "TimeFrameEndBorderMargin": "-1", + "checkRunDurationLimits": "0", + "maxInactiveChipsPerLayer": { + "values": [ + "8", + "8", + "8", + "111", + "111", + "195", + "195" + ] + }, + "NumberOfOrbitsPerTF": "-1" + }, + "evselOpts": { + "amIneeded": "-1", + "muonSelection": "0", + "maxDiffZvtxFT0vsPV": "1", + "isMC": "-1", + "confSigmaBCforHighPtTracks": "4", + "TimeIntervalForOccupancyCalculationMin": "-40", + "TimeIntervalForOccupancyCalculationMax": "100", + "TimeRangeVetoOnCollStandard": "10", + "TimeRangeVetoOnCollNarrow": "2", + "FT0CamplPerCollCutVetoOnCollInTimeRange": "8000", + "FT0CamplPerCollCutVetoOnCollInROF": "5000", + "EpsilonVzDiffVetoInROF": "0.300000012", + "UseWeightsForOccupancyEstimator": "1", + "NumberOfOrbitsPerTF": "-1", + "TestAlternativeBcMatching": "0", + "TestModifyTimeVetoOnNearbyColl": "0", + "TestVetoOnTRDinPast": "0", + "TestVzDiffNsigma": "3", + "TestVzDiffMargin": "0.200000003" + }, + "lumiOpts": { + "amIneeded": "-1" + }, + "ccdburl": "http://alice-ccdb.cern.ch" + } +} \ No newline at end of file diff --git a/MC/config/analysis_testing/json/dpl/o2-analysis-ft0-corrected-table.json b/MC/config/analysis_testing/json/dpl/o2-analysis-ft0-corrected-table.json new file mode 100644 index 000000000..5fe5e456b --- /dev/null +++ b/MC/config/analysis_testing/json/dpl/o2-analysis-ft0-corrected-table.json @@ -0,0 +1,13 @@ +{ + "ft0-corrected-table": { + "resoFT0A": "20", + "resoFT0C": "20", + "addHistograms": "0", + "collisionSystem": "-2", + "ccdb-url": "http://alice-ccdb.cern.ch", + "ccdb-path-grplhcif": "GLO/Config/GRPLHCIF", + "ccdb-timestamp": "-1", + "processStandard": "1", + "processWithBypassFT0timeInMC": "0" + } +} \ No newline at end of file diff --git a/MC/config/analysis_testing/json/dpl/o2-analysis-fwdtrack-to-collision-associator.json b/MC/config/analysis_testing/json/dpl/o2-analysis-fwdtrack-to-collision-associator.json new file mode 100644 index 000000000..8273cfdf4 --- /dev/null +++ b/MC/config/analysis_testing/json/dpl/o2-analysis-fwdtrack-to-collision-associator.json @@ -0,0 +1,13 @@ +{ + "fwd-track-to-collision-association": { + "nSigmaForTimeCompat": "4", + "timeMargin": "0", + "includeUnassigned": "0", + "fillTableOfCollIdsPerTrack": "1", + "bcWindowForOneSigma": "115", + "processFwdAssocWithTime": "0", + "processFwdStandardAssoc": "0", + "processMFTAssocWithTime": "1", + "processMFTStandardAssoc": "0" + } +} \ No newline at end of file diff --git a/MC/config/analysis_testing/json/dpl/o2-analysis-hf-candidate-creator-2prong.json b/MC/config/analysis_testing/json/dpl/o2-analysis-hf-candidate-creator-2prong.json new file mode 100644 index 000000000..d45ab8eb0 --- /dev/null +++ b/MC/config/analysis_testing/json/dpl/o2-analysis-hf-candidate-creator-2prong.json @@ -0,0 +1,96 @@ +{ + "hf-candidate-creator-2prong": { + "constrainKfToPv": "false", + "propagateToPCA": "true", + "useAbsDCA": "false", + "useWeightedFinalPCA": "false", + "maxR": "200", + "maxDZIni": "4", + "minParamChange": "0.001", + "minRelChi2Change": "0.90000000000000002", + "fillHistograms": "true", + "isRun2": "false", + "ccdbUrl": "http:\/\/alice-ccdb.cern.ch", + "ccdbPathGrp": "GLO\/GRP\/GRP", + "ccdbPathGrpMag": "GLO\/Config\/GRPMagField", + "hfEvSel": { + "centralityMin": "-10", + "centralityMax": "110", + "useSel8Trigger": "true", + "triggerClass": "-1", + "useTvxTrigger": "false", + "useTimeFrameBorderCut": "false", + "useItsRofBorderCut": "false", + "useIsGoodZvtxFT0vsPV": "false", + "useNoSameBunchPileup": "true", + "useOccupancyCut": "false", + "occEstimator": "1", + "occupancyMin": "0", + "occupancyMax": "1000000", + "nPvContributorsMin": "0", + "chi2PvMax": "-1", + "zPvPosMin": "-10", + "zPvPosMax": "10", + "useNoCollInTimeRangeNarrow": "false", + "useNoCollInTimeRangeStandard": "false", + "useNoCollInRofStandard": "false", + "softwareTrigger": "", + "bcMarginForSoftwareTrigger": "100", + "ccdbPathSoftwareTrigger": "Users\/m\/mpuccio\/EventFiltering\/OTS\/", + "th2ConfigAxisCent": { + "values": [ + "100", + "0", + "100" + ] + }, + "th2ConfigAxisOccupancy": { + "values": [ + "24", + "0", + "24000" + ] + }, + "requireGoodRct": "true", + "rctLabel": "CBT_hadronPID", + "rctCheckZDC": "false", + "rctTreatLimitedAcceptanceAsBad": "false" + }, + "axisMass": { + "values": [ + "500", + "1.6", + "2.1" + ] + }, + "processPvRefitWithDCAFitterN": "false", + "processNoPvRefitWithDCAFitterN": "false", + "processPvRefitWithKFParticle": "false", + "processNoPvRefitWithKFParticle": "false", + "processPvRefitWithDCAFitterNCentFT0C": "false", + "processNoPvRefitWithDCAFitterNCentFT0C": "true", + "processPvRefitWithKFParticleCentFT0C": "false", + "processNoPvRefitWithKFParticleCentFT0C": "false", + "processPvRefitWithDCAFitterNCentFT0M": "false", + "processNoPvRefitWithDCAFitterNCentFT0M": "false", + "processPvRefitWithKFParticleCentFT0M": "false", + "processNoPvRefitWithKFParticleCentFT0M": "false", + "processPvRefitWithDCAFitterNUpc": "false", + "processNoPvRefitWithDCAFitterNUpc": "false", + "processPvRefitWithKFParticleUpc": "false", + "processNoPvRefitWithKFParticleUpc": "false", + "processCollisions": "false", + "processCollisionsCentFT0C": "true", + "processCollisionsCentFT0M": "false", + "processCollisionsUpc": "false" + }, + "hf-candidate-creator-2prong-expressions": { + "rejectBackground": "false", + "matchKinkedDecayTopology": "false", + "matchInteractionsWithMaterial": "false", + "matchCorrelatedBackground": "false", + "processMc": "false", + "processMcCentFT0C": "false", + "processMcCentFT0M": "false" + } +} diff --git a/MC/config/analysis_testing/json/dpl/o2-analysis-hf-candidate-selector-d0.json b/MC/config/analysis_testing/json/dpl/o2-analysis-hf-candidate-selector-d0.json new file mode 100644 index 000000000..008b1676c --- /dev/null +++ b/MC/config/analysis_testing/json/dpl/o2-analysis-hf-candidate-selector-d0.json @@ -0,0 +1,706 @@ +{ + "hf-candidate-selector-d0": { + "ptCandMin": "0", + "ptCandMax": "50", + "usePid": "true", + "ptPidTpcMin": "0.40000000000000002", + "ptPidTpcMax": "50", + "nSigmaTpcMax": "3", + "nSigmaTpcCombinedMax": "3", + "usePidTpcOnly": "false", + "ptPidTofMin": "0.40000000000000002", + "ptPidTofMax": "50", + "nSigmaTofMax": "3", + "nSigmaTofCombinedMax": "3", + "usePidTpcAndTof": "true", + "itsNClustersFoundMin": "0", + "itsChi2PerClusterMax": "1e+10", + "tpcNClustersFoundMin": "70", + "tpcNCrossedRowsMin": "80", + "tpcNCrossedRowsOverFindableClustersMin": "0.800000012", + "tpcChi2PerClusterMax": "1e+10", + "keepOnlySidebandCandidates": "false", + "distanceFromD0MassForSidebands": "0.14999999999999999", + "binsPt": { + "values": [ + "0", + "1", + "2", + "3", + "4", + "6", + "8", + "12", + "24", + "50", + "100" + ] + }, + "cuts": { + "labels_rows": [ + "pT bin 0", + "pT bin 1", + "pT bin 2", + "pT bin 3", + "pT bin 4", + "pT bin 5", + "pT bin 6", + "pT bin 7", + "pT bin 8", + "pT bin 9", + "pT bin 10", + "pT bin 11", + "pT bin 12", + "pT bin 13", + "pT bin 14", + "pT bin 15", + "pT bin 16", + "pT bin 17", + "pT bin 18", + "pT bin 19", + "pT bin 20", + "pT bin 21", + "pT bin 22", + "pT bin 23", + "pT bin 24" + ], + "labels_cols": [ + "m", + "DCA", + "cos theta*", + "pT K", + "pT Pi", + "d0K", + "d0pi", + "d0d0", + "cos pointing angle", + "cos pointing angle xy", + "min norm decay length XY", + "max decay length", + "max decay length XY", + "min decay length", + "norm dauImpPar XY" + ], + "values": [ + [ + "0.20000000000000001", + "0.040000000000000001", + "0.80000000000000004", + "0.5", + "0.5", + "1", + "1", + "1", + "0.97999999999999998", + "0.98499999999999999", + "0", + "10", + "10", + "0", + "0.10000000000000001" + ], + [ + "0.20000000000000001", + "0.040000000000000001", + "0.80000000000000004", + "0.5", + "0.5", + "1", + "1", + "1", + "0.98999999999999999", + "0.995", + "0", + "10", + "10", + "0", + "0.10000000000000001" + ], + [ + "0.20000000000000001", + "0.029999999999999999", + "0.80000000000000004", + "0.5", + "0.5", + "1", + "1", + "1", + "0.97999999999999998", + "0.98499999999999999", + "0", + "10", + "10", + "0", + "0.10000000000000001" + ], + [ + "0.20000000000000001", + "0.029999999999999999", + "0.80000000000000004", + "0.59999999999999998", + "0.59999999999999998", + "1", + "1", + "1", + "0.96999999999999997", + "0.97499999999999998", + "0", + "10", + "10", + "0", + "0.10000000000000001" + ], + [ + "0.20000000000000001", + "0.029999999999999999", + "0.80000000000000004", + "0.59999999999999998", + "0.59999999999999998", + "1", + "1", + "1", + "0.95999999999999996", + "0.96499999999999997", + "0", + "10", + "10", + "0", + "0.10000000000000001" + ], + [ + "0.20000000000000001", + "0.029999999999999999", + "0.80000000000000004", + "0.59999999999999998", + "0.59999999999999998", + "1", + "1", + "1", + "0.94999999999999996", + "0.95499999999999996", + "0", + "10", + "10", + "0", + "0.10000000000000001" + ], + [ + "0.20000000000000001", + "0.029999999999999999", + "0.80000000000000004", + "0.69999999999999996", + "0.69999999999999996", + "1", + "1", + "1", + "0.93999999999999995", + "0.94499999999999995", + "0", + "10", + "10", + "0", + "0.10000000000000001" + ], + [ + "0.20000000000000001", + "0.029999999999999999", + "0.80000000000000004", + "0.69999999999999996", + "0.69999999999999996", + "1", + "1", + "1", + "0.92000000000000004", + "0.92500000000000004", + "0", + "10", + "10", + "0", + "0.10000000000000001" + ], + [ + "0.20000000000000001", + "0.029999999999999999", + "0.80000000000000004", + "0.69999999999999996", + "0.69999999999999996", + "1", + "1", + "1", + "0.91000000000000003", + "0.91500000000000004", + "0", + "10", + "10", + "0", + "0.10000000000000001" + ], + [ + "0.20000000000000001", + "0.029999999999999999", + "0.80000000000000004", + "0.69999999999999996", + "0.69999999999999996", + "1", + "1", + "1", + "0.90000000000000002", + "0.90500000000000003", + "0", + "10", + "10", + "0", + "0.10000000000000001" + ], + [ + "0.20000000000000001", + "0.029999999999999999", + "1", + "0.40000000000000002", + "0.40000000000000002", + "1", + "1", + "1", + "0.90000000000000002", + "0.90000000000000002", + "0", + "10", + "10", + "0", + "0.10000000000000001" + ], + [ + "0.20000000000000001", + "0.029999999999999999", + "1", + "0.40000000000000002", + "0.40000000000000002", + "1", + "1", + "1", + "0.84999999999999998", + "0.84999999999999998", + "0", + "10", + "10", + "0", + "0.10000000000000001" + ], + [ + "0.20000000000000001", + "0.029999999999999999", + "1", + "0.40000000000000002", + "0.40000000000000002", + "1", + "1", + "1", + "0.84999999999999998", + "0.84999999999999998", + "0", + "10", + "10", + "0", + "0.10000000000000001" + ], + [ + "0.20000000000000001", + "0.035000000000000003", + "1", + "0.40000000000000002", + "0.40000000000000002", + "0.10000000000000001", + "0.10000000000000001", + "0", + "0.84999999999999998", + "0.84999999999999998", + "0", + "10", + "10", + "0", + "0.5" + ], + [ + "0.20000000000000001", + "0.029999999999999999", + "1", + "0.40000000000000002", + "0.40000000000000002", + "0.10000000000000001", + "0.10000000000000001", + "0", + "0.84999999999999998", + "0.84999999999999998", + "0", + "10", + "10", + "0", + "0.5" + ], + [ + "0.20000000000000001", + "0.029999999999999999", + "0.90000000000000002", + "0.40000000000000002", + "0.40000000000000002", + "0.10000000000000001", + "0.10000000000000001", + "0", + "0.84999999999999998", + "0.84999999999999998", + "0", + "10", + "10", + "0", + "0.5" + ], + [ + "0.20000000000000001", + "0.029999999999999999", + "0.90000000000000002", + "0.40000000000000002", + "0.40000000000000002", + "0.10000000000000001", + "0.10000000000000001", + "-5.0000000000000002e-05", + "0.84999999999999998", + "0.84999999999999998", + "0", + "10", + "10", + "0", + "0.5" + ], + [ + "0.20000000000000001", + "0.029999999999999999", + "0.90000000000000002", + "0.69999999999999996", + "0.69999999999999996", + "0.10000000000000001", + "0.10000000000000001", + "-5.0000000000000002e-05", + "0.84999999999999998", + "0.84999999999999998", + "0", + "10", + "10", + "0.059999999999999998", + "0.5" + ], + [ + "0.20000000000000001", + "0.029999999999999999", + "0.90000000000000002", + "0.69999999999999996", + "0.69999999999999996", + "0.10000000000000001", + "0.10000000000000001", + "-5.0000000000000002e-05", + "0.84999999999999998", + "0.84999999999999998", + "0", + "10", + "10", + "0.059999999999999998", + "0.5" + ], + [ + "0.20000000000000001", + "0.029999999999999999", + "1", + "0.69999999999999996", + "0.69999999999999996", + "0.10000000000000001", + "0.10000000000000001", + "0.0001", + "0.84999999999999998", + "0.84999999999999998", + "0", + "10", + "10", + "0.059999999999999998", + "0.5" + ], + [ + "0.40000000000000002", + "0.035000000000000003", + "1", + "0.69999999999999996", + "0.69999999999999996", + "0.10000000000000001", + "0.10000000000000001", + "0.0099999900000000003", + "0.84999999999999998", + "0.84999999999999998", + "0", + "10", + "10", + "0.059999999999999998", + "0.5" + ], + [ + "0.40000000000000002", + "0.035000000000000003", + "1", + "0.69999999999999996", + "0.69999999999999996", + "0.10000000000000001", + "0.10000000000000001", + "0.0099999900000000003", + "0.84999999999999998", + "0.84999999999999998", + "0", + "10", + "10", + "0.059999999999999998", + "0.5" + ], + [ + "0.40000000000000002", + "0.030000000000000002", + "1", + "0.69999999999999996", + "0.69999999999999996", + "0.10000000000000001", + "0.10000000000000001", + "0.0099999900000000003", + "0.84999999999999998", + "0.84999999999999998", + "0", + "10", + "10", + "0.059999999999999998", + "0.5" + ], + [ + "0.40000000000000002", + "0.030000000000000002", + "1", + "0.69999999999999996", + "0.69999999999999996", + "0.10000000000000001", + "0.10000000000000001", + "0.0099999900000000003", + "0.84999999999999998", + "0.84999999999999998", + "0", + "10", + "10", + "0.059999999999999998", + "0.5" + ], + [ + "0.40000000000000002", + "0.030000000000000002", + "1", + "0.59999999999999998", + "0.59999999999999998", + "0.10000000000000001", + "0.10000000000000001", + "0.0099999900000000003", + "0.84999999999999998", + "0.84999999999999998", + "0", + "10", + "10", + "0.059999999999999998", + "0.5" + ] + ] + }, + "applyMl": "true", + "binsPtMl": { + "values": [ + "0", + "1", + "2", + "3", + "4", + "6", + "8", + "12", + "24", + "50", + "100" + ] + }, + "cutDirMl": { + "values": [ + "0", + "1", + "1" + ] + }, + "cutsMl": { + "labels_rows": [ + "pT bin 0", + "pT bin 1", + "pT bin 2", + "pT bin 3", + "pT bin 4", + "pT bin 5", + "pT bin 6", + "pT bin 7", + "pT bin 8", + "pT bin 9", + "pT bin 10", + "pT bin 11" + ], + "labels_cols": [ + "score class 1", + "score class 2", + "score class 3" + ], + "values": [ + [ + "0.0025", + "0", + "0" + ], + [ + "0.005", + "0", + "0" + ], + [ + "0.006", + "0", + "0" + ], + [ + "0.008", + "0", + "0" + ], + [ + "0.01", + "0", + "0" + ], + [ + "0.1", + "0", + "0" + ], + [ + "0.2", + "0", + "0" + ], + [ + "0.4", + "0", + "0" + ], + [ + "1", + "0", + "0" + ], + [ + "1", + "0", + "0" + ], + [ + "1", + "0", + "0" + ], + [ + "1", + "0", + "0" + ] + ] + }, + "nClassesMl": "3", + "enableDebugMl": "true", + "namesInputFeatures": { + "values": [ + "impactParameterXY0", + "impactParameterXY1", + "chi2PCA", + "cpa", + "cpaXY", + "decayLengthXY", + "decayLength", + "impactParameterProduct", + "nSigTpcTofPiExpPi", + "nSigTpcTofKaExpKa", + "nSigTpcPiExpPi", + "nSigTpcKaExpPi", + "nSigTpcTofKaExpPi", + "nSigTpcPiExpKa", + "nSigTpcKaExpKa", + "nSigTpcTofPiExpKa" + ] + }, + "ccdbUrl": "http:\/\/alice-ccdb.cern.ch", + "modelPathsCCDB": { + "values": [ + "Users\/b\/bizhang\/BDT\/D0\/23_PbPb_020_new\/pt0_1", + "Users\/b\/bizhang\/BDT\/D0\/23_PbPb_020_new\/pt1_2", + "Users\/b\/bizhang\/BDT\/D0\/23_PbPb_020_new\/pt2_3", + "Users\/b\/bizhang\/BDT\/D0\/23_PbPb_020_new\/pt3_4", + "Users\/b\/bizhang\/BDT\/D0\/23_PbPb_020_new\/pt4_6", + "Users\/b\/bizhang\/BDT\/D0\/23_PbPb_020_new\/pt6_8", + "Users\/b\/bizhang\/BDT\/D0\/23_PbPb_020_new\/pt8_12", + "Users\/b\/bizhang\/BDT\/D0\/23_PbPb_020_new\/pt12_24", + "Users\/b\/bizhang\/BDT\/D0\/23_PbPb_020_new\/pt24_50", + "Users\/b\/bizhang\/BDT\/D0\/23_PbPb_020_new\/pt24_50" + ] + }, + "onnxFileNames": { + "values": [ + "ModelHandler_pT_0_1.onnx", + "ModelHandler_pT_1_2.onnx", + "ModelHandler_pT_2_3.onnx", + "ModelHandler_pT_3_4.onnx", + "ModelHandler_pT_4_6.onnx", + "ModelHandler_pT_6_8.onnx", + "ModelHandler_pT_8_12.onnx", + "ModelHandler_pT_12_24.onnx", + "ModelHandler_pT_24_50.onnx", + "ModelHandler_pT_24_50.onnx" + ] + }, + "timestampCCDB": "-1", + "loadModelsFromCCDB": "true", + "useTriggerMassCut": "false", + "hfTrigger2ProngCuts": { + "nSigmaMax": "2", + "ptDeltaMassMax": "10", + "ptMassCutMax": "9999", + "deltaMassPars": { + "labels_rows": "", + "labels_cols": [ + "constant", + "linear" + ], + "values": [ + [ + "-0.00249999994", + "9.99999975e-05" + ] + ] + }, + "sigmaPars": { + "labels_rows": "", + "labels_cols": [ + "constant", + "linear" + ], + "values": [ + [ + "0.0142400004", + "0.00178000005" + ] + ] + } + }, + "processWithDCAFitterN": "true", + "processWithKFParticle": "false" + } +} \ No newline at end of file diff --git a/MC/config/analysis_testing/json/dpl/o2-analysis-hf-pid-creator.json b/MC/config/analysis_testing/json/dpl/o2-analysis-hf-pid-creator.json new file mode 100644 index 000000000..dfb171a57 --- /dev/null +++ b/MC/config/analysis_testing/json/dpl/o2-analysis-hf-pid-creator.json @@ -0,0 +1,15 @@ +{ + "hf-pid-creator": { + "processDummy": "false", + "processFullEl": "false", + "processTinyEl": "false", + "processFullMu": "false", + "processTinyMu": "false", + "processFullPi": "true", + "processTinyPi": "false", + "processFullKa": "true", + "processTinyKa": "false", + "processFullPr": "false", + "processTinyPr": "false" + } +} \ No newline at end of file diff --git a/MC/config/analysis_testing/json/dpl/o2-analysis-hf-task-d0.json b/MC/config/analysis_testing/json/dpl/o2-analysis-hf-task-d0.json new file mode 100644 index 000000000..ae1a0be18 --- /dev/null +++ b/MC/config/analysis_testing/json/dpl/o2-analysis-hf-task-d0.json @@ -0,0 +1,161 @@ +{ + "hf-task-d0": { + "selectionFlagD0": "1", + "selectionFlagD0bar": "1", + "yCandGenMax": "0.5", + "yCandRecoMax": "0.80000000000000004", + "selectionFlagHf": "1", + "selectionTopol": "1", + "selectionCand": "1", + "selectionPid": "1", + "binsPt": { + "values": [ + "0", + "1", + "2", + "3", + "4", + "5", + "6", + "7", + "8", + "10", + "12", + "16", + "24", + "36", + "50" + ] + }, + "centEstimator": "2", + "occEstimator": "1", + "storeCentrality": "true", + "storeOccupancy": "true", + "storeTrackQuality": "false", + "applyMl": "true", + "thnConfigAxisBkgScore": { + "values": [ + "5000", + "0", + "0.5" + ] + }, + "thnConfigAxisNonPromptScore": { + "values": [ + "100", + "0", + "1" + ] + }, + "thnConfigAxisPromptScore": { + "values": [ + "100", + "0", + "1" + ] + }, + "thnConfigAxisMass": { + "values": [ + "120", + "1.5848", + "2.1848" + ] + }, + "thnConfigAxisPtB": { + "values": [ + "1000", + "0", + "100" + ] + }, + "thnConfigAxisPt": { + "values": [ + "500", + "0", + "50" + ] + }, + "thnConfigAxisY": { + "values": [ + "20", + "-1", + "1" + ] + }, + "thnConfigAxisOrigin": { + "values": [ + "3", + "-0.5", + "2.5" + ] + }, + "thnConfigAxisCandType": { + "values": [ + "6", + "-0.5", + "5.5" + ] + }, + "thnConfigAxisGenPtD": { + "values": [ + "500", + "0", + "50" + ] + }, + "thnConfigAxisGenPtB": { + "values": [ + "1000", + "0", + "100" + ] + }, + "thnConfigAxisNumPvContr": { + "values": [ + "800", + "-0.5", + "7999.5" + ] + }, + "thnConfigAxisCent": { + "values": [ + "110", + "0", + "110" + ] + }, + "thnConfigAxisOccupancy": { + "values": [ + "24", + "0", + "24000" + ] + }, + "thnConfigAxisMinItsNCls": { + "values": [ + "5", + "3", + "8" + ] + }, + "thnConfigAxisMinTpcNCrossedRows": { + "values": [ + "10", + "70", + "180" + ] + }, + "processDataWithDCAFitterN": "false", + "processDataWithDCAFitterNCent": "false", + "processDataWithKFParticle": "false", + "processDataWithDCAFitterNMl": "false", + "processDataWithDCAFitterNMlCent": "true", + "processDataWithKFParticleMl": "false", + "processMcWithDCAFitterN": "false", + "processMcWithDCAFitterNCent": "false", + "processMcWithKFParticle": "false", + "processMcWithDCAFitterNMl": "false", + "processMcWithDCAFitterNMlCent": "false", + "processMcWithKFParticleMl": "false" + } +} \ No newline at end of file diff --git a/MC/config/analysis_testing/json/dpl/o2-analysis-hf-track-index-skim-creator.json b/MC/config/analysis_testing/json/dpl/o2-analysis-hf-track-index-skim-creator.json new file mode 100644 index 000000000..3d941b71e --- /dev/null +++ b/MC/config/analysis_testing/json/dpl/o2-analysis-hf-track-index-skim-creator.json @@ -0,0 +1,895 @@ +{ + "hf-track-index-skim-creator-tag-sel-collisions": { + "fillHistograms": "true", + "triggerClassName": "", + "hfEvSel": { + "centralityMin": "-10", + "centralityMax": "110", + "useSel8Trigger": "true", + "triggerClass": "-1", + "useTvxTrigger": "false", + "useTimeFrameBorderCut": "false", + "useItsRofBorderCut": "false", + "useIsGoodZvtxFT0vsPV": "false", + "useNoSameBunchPileup": "false", + "useOccupancyCut": "false", + "occEstimator": "1", + "occupancyMin": "0", + "occupancyMax": "1000000", + "nPvContributorsMin": "0", + "chi2PvMax": "-1", + "zPvPosMin": "-10", + "zPvPosMax": "10", + "useNoCollInTimeRangeNarrow": "false", + "useNoCollInTimeRangeStandard": "false", + "useNoCollInRofStandard": "false", + "softwareTrigger": "", + "bcMarginForSoftwareTrigger": "100", + "ccdbPathSoftwareTrigger": "Users\/m\/mpuccio\/EventFiltering\/OTS\/Chunked\/", + "th2ConfigAxisCent": { + "values": [ + "100", + "0", + "100" + ] + }, + "th2ConfigAxisOccupancy": { + "values": [ + "14", + "0", + "14000" + ] + }, + "requireGoodRct": "false", + "rctLabel": "CBT_hadronPID", + "rctCheckZDC": "false", + "rctTreatLimitedAcceptanceAsBad": "false" + }, + "processTrigAndCentFT0ASel": "false", + "processTrigAndCentFT0CSel": "true", + "processTrigAndCentFT0MSel": "false", + "processTrigAndCentFV0ASel": "false", + "processTrigSel": "false", + "processNoTrigSel": "false", + "processUpcSel": "false" + }, + "hf-pid-creator": { + "processDummy": "false", + "processFullEl": "false", + "processTinyEl": "false", + "processFullMu": "false", + "processTinyMu": "false", + "processFullPi": "true", + "processTinyPi": "false", + "processFullKa": "true", + "processTinyKa": "false", + "processFullPr": "false", + "processTinyPr": "false" + }, + "hf-track-index-skim-creator-tag-sel-tracks": { + "isRun2": "false", + "doPvRefit": "false", + "fillHistograms": "true", + "debugPvRefit": "false", + "doCutQuality": "true", + "useIsGlobalTrack": "false", + "useIsGlobalTrackWoDCA": "true", + "tpcNClsFoundMin": "70", + "binsPtTrack": { + "values": [ + "0", + "0.5", + "1", + "1.5", + "2", + "3", + "1000" + ] + }, + "ptMinTrack2Prong": "0.40000000000000002", + "cutsTrack2Prong": { + "labels_rows": "", + "labels_cols": [ + "min_dcaxytoprimary", + "max_dcaxytoprimary", + "min_dcaztoprimary", + "max_dcaztoprimary" + ], + "values": [ + [ + "0.002", + "10", + "0", + "100" + ], + [ + "0.002", + "10", + "0", + "100" + ], + [ + "0.002", + "10", + "0", + "100" + ], + [ + "0.002", + "10", + "0", + "100" + ], + [ + "0", + "10", + "0", + "100" + ], + [ + "0", + "10", + "0", + "100" + ] + ] + }, + "etaMinTrack2Prong": "-0.80000000000000004", + "etaMaxTrack2Prong": "0.80000000000000004", + "ptMinTrack3Prong": "0.59999999999999998", + "cutsTrack3Prong": { + "labels_rows": "", + "labels_cols": [ + "min_dcaxytoprimary", + "max_dcaxytoprimary", + "min_dcaztoprimary", + "max_dcaztoprimary" + ], + "values": [ + [ + "0.0040000000000000001", + "10", + "0", + "100" + ], + [ + "0.0040000000000000001", + "10", + "0", + "100" + ], + [ + "0.0040000000000000001", + "10", + "0", + "100" + ], + [ + "0.0040000000000000001", + "10", + "0", + "100" + ], + [ + "0", + "10", + "0", + "100" + ], + [ + "0", + "10", + "0", + "100" + ] + ] + }, + "etaMinTrack3Prong": "-0.80000000000000004", + "etaMaxTrack3Prong": "0.80000000000000004", + "ptMinTrackBach": "0", + "cutsTrackBach": { + "labels_rows": "", + "labels_cols": [ + "min_dcaxytoprimary", + "max_dcaxytoprimary", + "min_dcaztoprimary", + "max_dcaztoprimary" + ], + "values": [ + [ + "0", + "10", + "0", + "100" + ], + [ + "0", + "10", + "0", + "100" + ], + [ + "0", + "10", + "0", + "100" + ], + [ + "0", + "10", + "0", + "100" + ], + [ + "0", + "10", + "0", + "100" + ], + [ + "0", + "10", + "0", + "100" + ] + ] + }, + "etaMinTrackBach": "-0.80000000000000004", + "etaMaxTrackBach": "0.80000000000000004", + "ptMinTrackBachLfCasc": "0.10000000000000001", + "cutsTrackBachLfCasc": { + "labels_rows": "", + "labels_cols": [ + "min_dcaxytoprimary", + "max_dcaxytoprimary", + "min_dcaztoprimary", + "max_dcaztoprimary" + ], + "values": [ + [ + "0", + "10", + "0", + "100" + ], + [ + "0", + "10", + "0", + "100" + ], + [ + "0", + "10", + "0", + "100" + ], + [ + "0", + "10", + "0", + "100" + ], + [ + "0", + "10", + "0", + "100" + ], + [ + "0", + "10", + "0", + "100" + ] + ] + }, + "etaMinTrackBachLfCasc": "-99999", + "etaMaxTrackBachLfCasc": "1.1000000000000001", + "useIsGlobalTrackForBachLfCasc": "false", + "useIsGlobalTrackWoDCAForBachLfCasc": "false", + "useIsQualityTrackITSForBachLfCasc": "true", + "ptMinSoftPionForDstar": "0.10000000000000001", + "etaMinSoftPionForDstar": "-0.80000000000000004", + "etaMaxSoftPionForDstar": "0.80000000000000004", + "cutsTrackDstar": { + "labels_rows": "", + "labels_cols": [ + "min_dcaxytoprimary", + "max_dcaxytoprimary", + "min_dcaztoprimary", + "max_dcaztoprimary" + ], + "values": [ + [ + "0", + "2", + "0", + "100" + ], + [ + "0", + "2", + "0", + "100" + ], + [ + "0", + "2", + "0", + "100" + ], + [ + "0", + "2", + "0", + "100" + ], + [ + "0", + "2", + "0", + "100" + ], + [ + "0", + "2", + "0", + "100" + ] + ] + }, + "useIsGlobalTrackForSoftPion": "false", + "useIsGlobalTrackWoDCAForSoftPion": "true", + "useIsQualityTrackITSForSoftPion": "false", + "selectionsPid": { + "labels_rows": [ + "ProtonInLcToPKPi", + "ProtonInXicToPKPi", + "ProtonInLcToPK0S", + "KaonIn3Prongs" + ], + "labels_cols": [ + "minPtTpc", + "maxPtTpc", + "nSigmaMaxTpc", + "minPtTof", + "maxPtTof", + "nSigmaMaxTof" + ], + "values": [ + [ + "0", + "1000", + "4", + "0", + "1000", + "5" + ], + [ + "0", + "1000", + "4", + "0", + "1000", + "5" + ], + [ + "0", + "1000", + "4", + "0", + "1000", + "5" + ], + [ + "0", + "1000", + "4", + "0", + "1000", + "5" + ] + ] + }, + "ccdbUrl": "http:\/\/alice-ccdb.cern.ch", + "ccdbPathLut": "GLO\/Param\/MatLUT", + "ccdbPathGrp": "GLO\/GRP\/GRP", + "ccdbPathGrpMag": "GLO\/Config\/GRPMagField", + "axisPvRefitDeltaX": { + "values": [ + "1000", + "-0.5", + "0.5" + ] + }, + "axisPvRefitDeltaY": { + "values": [ + "1000", + "-0.5", + "0.5" + ] + }, + "axisPvRefitDeltaZ": { + "values": [ + "1000", + "-0.5", + "0.5" + ] + }, + "processNoPid": "false", + "processProtonPidTpc": "true", + "processProtonPidTof": "false", + "processProtonPidTpcOrTof": "false", + "processProtonPidTpcAndTof": "false" + }, + "hf-track-index-skim-creator": { + "isRun2": "false", + "do3Prong": "true", + "doDstar": "true", + "debug": "false", + "debugPvRefit": "false", + "fillHistograms": "true", + "ptTolerance": "0.10000000000000001", + "minTwoTrackDecayLengthFor3Prongs": "0.01", + "maxTwoTrackChi2PcaFor3Prongs": "10000000000", + "propagateToPCA": "true", + "useAbsDCA": "false", + "useWeightedFinalPCA": "false", + "maxR": "200", + "maxDZIni": "4", + "minParamChange": "0.001", + "minRelChi2Change": "0.90000000000000002", + "ccdbUrl": "http:\/\/alice-ccdb.cern.ch", + "ccdbPathLut": "GLO\/Param\/MatLUT", + "ccdbPathGrp": "GLO\/GRP\/GRP", + "ccdbPathGrpMag": "GLO\/Config\/GRPMagField", + "binsPtD0ToPiK": { + "values": [ + "0", + "5", + "1000" + ] + }, + "cutsD0ToPiK": { + "labels_rows": "", + "labels_cols": [ + "massMin", + "massMax", + "cosp", + "d0d0" + ], + "values": [ + [ + "1.6499999999999999", + "2.1000000000000001", + "0.90000000000000002", + "0" + ], + [ + "1.6499999999999999", + "2.25", + "0.90000000000000002", + "0" + ] + ] + }, + "binsPtJpsiToEE": { + "values": [ + "0", + "5", + "1000" + ] + }, + "cutsJpsiToEE": { + "labels_rows": "", + "labels_cols": [ + "massMin", + "massMax", + "cosp", + "d0d0" + ], + "values": [ + [ + "0", + "0", + "2", + "0" + ], + [ + "0", + "0", + "2", + "0" + ] + ] + }, + "binsPtJpsiToMuMu": { + "values": [ + "0", + "5", + "1000" + ] + }, + "cutsJpsiToMuMu": { + "labels_rows": "", + "labels_cols": [ + "massMin", + "massMax", + "cosp", + "d0d0" + ], + "values": [ + [ + "0", + "0", + "2", + "0" + ], + [ + "0", + "0", + "2", + "0" + ] + ] + }, + "binsPtDplusToPiKPi": { + "values": [ + "1", + "5", + "1000" + ] + }, + "cutsDplusToPiKPi": { + "labels_rows": "", + "labels_cols": [ + "massMin", + "massMax", + "cosp", + "decL" + ], + "values": [ + [ + "1.7", + "2.0499999999999998", + "0.95999999999999996", + "0.050000000000000003" + ], + [ + "1.6499999999999999", + "2.2000000000000002", + "0.94999999999999996", + "0.050000000000000003" + ] + ] + }, + "binsPtDsToKKPi": { + "values": [ + "1", + "5", + "1000" + ] + }, + "cutsDsToKKPi": { + "labels_rows": "", + "labels_cols": [ + "massMin", + "massMax", + "cosp", + "decL", + "deltaMassKK" + ], + "values": [ + [ + "1.7", + "2.1499999999999999", + "0.93999999999999995", + "0.02", + "0.02" + ], + [ + "1.6499999999999999", + "2.25", + "0.92000000000000004", + "0.02", + "0.02" + ] + ] + }, + "binsPtLcToPKPi": { + "values": [ + "2", + "8", + "1000" + ] + }, + "cutsLcToPKPi": { + "labels_rows": "", + "labels_cols": [ + "massMin", + "massMax", + "cosp", + "decL" + ], + "values": [ + [ + "2.1000000000000001", + "2.5", + "0.92000000000000004", + "0.01" + ], + [ + "2", + "2.6000000000000001", + "0.90000000000000002", + "0.02" + ] + ] + }, + "binsPtXicToPKPi": { + "values": [ + "2", + "8", + "1000" + ] + }, + "cutsXicToPKPi": { + "labels_rows": "", + "labels_cols": [ + "massMin", + "massMax", + "cosp", + "decL" + ], + "values": [ + [ + "2.1000000000000001", + "2.6499999999999999", + "0.93999999999999995", + "0.02" + ], + [ + "2", + "2.7000000000000002", + "0.92000000000000004", + "0.02" + ] + ] + }, + "binsPtDstarToD0Pi": { + "values": [ + "2", + "5", + "1000" + ] + }, + "cutsDstarToD0Pi": { + "labels_rows": "", + "labels_cols": [ + "deltaMassMax", + "deltaMassD0" + ], + "values": [ + [ + "0.17000000000000001", + "0.070000000000000007" + ], + [ + "0.17000000000000001", + "0.10000000000000001" + ] + ] + }, + "applyProtonPidForLcToPKPi": "true", + "applyProtonPidForXicToPKPi": "true", + "applyKaonPidIn3Prongs": "true", + "applyMlForHfFilters": "false", + "mlModelPathCCDB": "EventFiltering\/PWGHF\/BDTSmeared", + "timestampCcdbForHfFilters": "1657032422771", + "loadMlModelsFromCCDB": "true", + "onnxFileNames": { + "labels_rows": [ + "D0", + "Dplus", + "Lc", + "Ds", + "Xic" + ], + "labels_cols": [ + "Model path" + ], + "values": [ + [ + "ModelHandler_onnx_D0ToKPi.onnx" + ], + [ + "ModelHandler_onnx_DplusToPiKPi.onnx" + ], + [ + "ModelHandler_onnx_LcToPKPi.onnx" + ], + [ + "ModelHandler_onnx_DsToKKPi.onnx" + ], + [ + "" + ] + ] + }, + "thresholdMlScoreD0ToKPi": { + "labels_rows": "", + "labels_cols": [ + "BDTbkg", + "BDTprompt", + "BDTnonprompt" + ], + "values": [ + [ + "0.10000000000000001", + "0.5", + "0.5" + ] + ] + }, + "thresholdMlScoreDplusToPiKPi": { + "labels_rows": "", + "labels_cols": [ + "BDTbkg", + "BDTprompt", + "BDTnonprompt" + ], + "values": [ + [ + "0.10000000000000001", + "0.5", + "0.5" + ] + ] + }, + "thresholdMlScoreDsToPiKK": { + "labels_rows": "", + "labels_cols": [ + "BDTbkg", + "BDTprompt", + "BDTnonprompt" + ], + "values": [ + [ + "0.10000000000000001", + "0.5", + "0.5" + ] + ] + }, + "thresholdMlScoreLcToPiKP": { + "labels_rows": "", + "labels_cols": [ + "BDTbkg", + "BDTprompt", + "BDTnonprompt" + ], + "values": [ + [ + "0.10000000000000001", + "0.5", + "0.5" + ] + ] + }, + "thresholdMlScoreXicToPiKP": { + "labels_rows": "", + "labels_cols": [ + "BDTbkg", + "BDTprompt", + "BDTnonprompt" + ], + "values": [ + [ + "0.10000000000000001", + "0.5", + "0.5" + ] + ] + }, + "axisPvRefitDeltaX": { + "values": [ + "1000", + "-0.5", + "0.5" + ] + }, + "axisPvRefitDeltaY": { + "values": [ + "1000", + "-0.5", + "0.5" + ] + }, + "axisPvRefitDeltaZ": { + "values": [ + "1000", + "-0.5", + "0.5" + ] + }, + "processNo2And3Prongs": "false", + "process2And3ProngsWithPvRefit": "false", + "process2And3ProngsNoPvRefit": "true", + "process2And3ProngsWithPvRefitWithPidForHfFiltersBdt": "false", + "process2And3ProngsNoPvRefitWithPidForHfFiltersBdt": "false" + }, + "hf-track-index-skim-creator-lf-cascades": { + "fillHistograms": "true", + "do3Prong": "true", + "rejDiffCollTrack": "true", + "ptTolerance": "0.10000000000000001", + "massXiPiMin": "2.1000000000000001", + "massXiPiMax": "3", + "massOmegaCharmBachelorMin": "2.3999999999999999", + "massOmegaCharmBachelorMax": "3", + "massXiPiPiMin": "2.1000000000000001", + "massXiPiPiMax": "2.7999999999999998", + "propagateToPCA": "true", + "useAbsDCA": "true", + "useWeightedFinalPCA": "true", + "maxR": "200", + "maxDZIni": "4", + "maxDXYIni": "4", + "minParamChange": "0.001", + "minRelChi2Change": "0.90000000000000002", + "maxChi2": "100", + "refitWithMatCorr": "true", + "ptMinOmegacZeroToOmegaPiLfCasc": "0", + "ptMinOmegaczeroToOmegaKaLfCasc": "0", + "ptMinXicZeroOmegacZeroToXiPiLfCasc": "0", + "ptMinXicplusLfCasc": "0", + "v0TransvRadius": "1", + "cascTransvRadius": "0.400000006", + "decayLengthXicMin": "-1", + "dcaBachToPv": "0.0500000007", + "dcaV0ToPv": "0.0500000007", + "v0CosPA": "0.94999999999999996", + "cascCosPA": "0.94999999999999996", + "xicCosPA": "0.94999999999999996", + "dcaV0Dau": "2", + "dcaCascDau": "1", + "dcaNegToPv": "0.0500000007", + "dcaPosToPv": "0.0500000007", + "v0MassWindow": "0.00800000038", + "cascadeMassWindow": "0.00999999978", + "isRun2": "false", + "ccdbUrl": "http:\/\/alice-ccdb.cern.ch", + "ccdbPathLut": "GLO\/Param\/MatLUT", + "ccdbPathGrp": "GLO\/GRP\/GRP", + "ccdbPathGrpMag": "GLO\/Config\/GRPMagField", + "processNoLfCascades": "true", + "processLfCascades": "false" + }, + "hf-track-index-skim-creator-cascades": { + "isRun2": "false", + "fillHistograms": "true", + "useDCAFitter": "true", + "propagateToPCA": "true", + "maxR": "200", + "maxDZIni": "4", + "minParamChange": "0.001", + "minRelChi2Change": "0.90000000000000002", + "useAbsDCA": "true", + "useWeightedFinalPCA": "true", + "etaMinV0Daugh": "-99999", + "etaMaxV0Daugh": "1.1000000000000001", + "ptMinV0Daugh": "0.050000000000000003", + "cpaV0Min": "0.995", + "cutInvMassV0": "0.050000000000000003", + "ptCascCandMin": "-1", + "cutInvMassCascLc": "1", + "applyProtonPid": "false", + "ccdbUrl": "http:\/\/alice-ccdb.cern.ch", + "ccdbPathLut": "GLO\/Param\/MatLUT", + "ccdbPathGrp": "GLO\/GRP\/GRP", + "ccdbPathGrpMag": "GLO\/Config\/GRPMagField", + "processNoCascades": "true", + "processCascades": "false" + } +} diff --git a/MC/config/analysis_testing/json/dpl/o2-analysis-lf-strangenesstofpid.json b/MC/config/analysis_testing/json/dpl/o2-analysis-lf-strangenesstofpid.json new file mode 100644 index 000000000..f168e5634 --- /dev/null +++ b/MC/config/analysis_testing/json/dpl/o2-analysis-lf-strangenesstofpid.json @@ -0,0 +1,166 @@ +{ + "strangenesstofpid": { + "calculationMethod": "0", + "calculateV0s": "-1", + "calculateCascades": "-1", + "calculateV0TOFPIDs": "-1", + "calculateV0TOFBetas": "-1", + "calculateV0TOFDebugs": "-1", + "calculateCascTOFPIDs": "-1", + "d_bz": "-999", + "tofPosition": "377.93399", + "doQA": "0", + "doNSigmas": "1", + "doQANSigma": "0", + "v0Calibration": { + "qaDCADau": "0.5", + "qaCosPA": "0.999000013", + "qaMassWindow": "0.00499999989", + "qaTPCNSigma": "5" + }, + "cascadeCalibration": { + "qaV0DCADau": "0.5", + "qaCascDCADau": "0.5", + "qaV0CosPA": "0.995000005", + "qaCascCosPA": "0.995000005", + "qaMassWindow": "0.00499999989", + "qaTPCNSigma": "5" + }, + "ccdb": { + "ccdb-url": "http://alice-ccdb.cern.ch", + "grpPath": "GLO/GRP/GRP", + "grpmagPath": "GLO/Config/GRPMagField", + "lutPath": "GLO/Param/MatLUT", + "nSigmaPath": "Users/d/ddobrigk/stratof", + "mVtxPath": "GLO/Calib/MeanVertex" + }, + "useCustomRunNumber": "1", + "manualRunNumber": "544122", + "axisPosition": { + "values": [ + "400", + "-400", + "400" + ] + }, + "axisEta": { + "values": [ + "20", + "-1", + "1" + ] + }, + "axisDeltaTime": { + "values": [ + "2000", + "-1000", + "1000" + ] + }, + "axisDeltaTimeVsPrimaryCalculation": { + "values": [ + "500", + "-500", + "500" + ] + }, + "axisTime": { + "values": [ + "400", + "10000", + "50000" + ] + }, + "axisNSigma": { + "values": [ + "200", + "-10", + "10" + ] + }, + "axisRatioMethods": { + "values": [ + "400", + "0.8999999761581421", + "1.899999976158142" + ] + }, + "axisSnp": { + "values": [ + "220", + "-1.100000023841858", + "1.100000023841858" + ] + }, + "axisP": { + "values": [ + "0", + "0", + "0.10000000149011612", + "0.20000000298023224", + "0.30000001192092896", + "0.4000000059604645", + "0.5", + "0.6000000238418579", + "0.699999988079071", + "0.800000011920929", + "0.8999999761581421", + "1", + "1.100000023841858", + "1.2000000476837158", + "1.2999999523162842", + "1.399999976158142", + "1.5", + "1.600000023841858", + "1.7000000476837158", + "1.7999999523162842", + "1.899999976158142", + "2", + "2.200000047683716", + "2.4000000953674316", + "2.5999999046325684", + "2.799999952316284", + "3", + "3.200000047683716", + "3.4000000953674316", + "3.5999999046325684", + "3.799999952316284", + "4", + "4.400000095367432", + "4.800000190734863", + "5.199999809265137", + "5.599999904632568", + "6", + "6.5", + "7", + "7.5", + "8", + "9", + "10", + "11", + "12", + "13", + "14", + "15", + "17", + "19", + "21", + "23", + "25", + "30", + "35", + "40", + "50" + ] + }, + "axisSmallP": { + "values": [ + "250", + "0", + "2.5" + ] + }, + "processStandardData": "1", + "processDerivedData": "0" + } +} \ No newline at end of file diff --git a/MC/config/analysis_testing/json/dpl/o2-analysis-mm-track-propagation.json b/MC/config/analysis_testing/json/dpl/o2-analysis-mm-track-propagation.json new file mode 100644 index 000000000..d8e6cce90 --- /dev/null +++ b/MC/config/analysis_testing/json/dpl/o2-analysis-mm-track-propagation.json @@ -0,0 +1,29 @@ +{ + "ambiguous-track-propagation": { + "ccdburl": "http://alice-ccdb.cern.ch", + "geoPath": "GLO/Config/GeometryAligned", + "grpmagPath": "GLO/Config/GRPMagField", + "mVtxPath": "GLO/Calib/MeanVertex", + "produceExtra": "0", + "produceHistos": "0", + "removeTrivialAssoc": "0", + "binsDCAxy": { + "values": [ + "200", + "-1", + "1" + ] + }, + "binsDCAz": { + "values": [ + "200", + "-1", + "1" + ] + }, + "processCentral": "0", + "processMFT": "0", + "processMFTReassoc": "1", + "processMFTReassoc3D": "0" + } +} \ No newline at end of file diff --git a/MC/config/analysis_testing/json/dpl/o2-analysis-multcenttable.json b/MC/config/analysis_testing/json/dpl/o2-analysis-multcenttable.json new file mode 100644 index 000000000..43a938bf2 --- /dev/null +++ b/MC/config/analysis_testing/json/dpl/o2-analysis-multcenttable.json @@ -0,0 +1,145 @@ +{ + "mult-cent-table": { + "generatorName": "", + "processRun3WithGlobalCounters": "0", + "processMFT": "0", + "processRun3": "1", + "processCentralityRun2": "0", + "processRun2": "0", + "processMonteCarlo2Mults": "0", + "enabledTables": { + "values": [ + [ + -1 + ], + [ + -1 + ], + [ + -1 + ], + [ + -1 + ], + [ + -1 + ], + [ + -1 + ], + [ + -1 + ], + [ + -1 + ], + [ + -1 + ], + [ + -1 + ], + [ + -1 + ], + [ + -1 + ], + [ + -1 + ], + [ + -1 + ], + [ + -1 + ], + [ + -1 + ], + [ + -1 + ], + [ + -1 + ], + [ + -1 + ], + [ + -1 + ], + [ + -1 + ], + [ + -1 + ], + [ + -1 + ], + [ + -1 + ], + [ + -1 + ], + [ + -1 + ], + [ + -1 + ], + [ + -1 + ], + [ + -1 + ], + [ + -1 + ], + [ + -1 + ], + [ + -1 + ], + [ + -1 + ], + [ + -1 + ], + [ + -1 + ], + [ + -1 + ], + [ + -1 + ], + [ + -1 + ], + [ + -1 + ] + ] + }, + "maxPtGlobalTrack": "1e+10", + "embedINELgtZEROselection": "0", + "minPtGlobalTrack": "0.15", + "autoConfigureProcess": "0", + "ccdbPathCentrality": "Centrality/Estimators", + "doVertexZeq": "1", + "ccdbPathVtxZ": "Centrality/Calibration", + "minNclsITSibGlobalTrack": "1", + "reconstructionPass": "", + "ccdburl": "http://alice-ccdb.cern.ch", + "processCentralityRun3": "1", + "minNclsITSGlobalTrack": "5", + "processMonteCarlo": "0" + } +} \ No newline at end of file diff --git a/MC/config/analysis_testing/json/dpl/o2-analysis-perf-k0s-resolution.json b/MC/config/analysis_testing/json/dpl/o2-analysis-perf-k0s-resolution.json index f7e949770..5bf02b5bd 100644 --- a/MC/config/analysis_testing/json/dpl/o2-analysis-perf-k0s-resolution.json +++ b/MC/config/analysis_testing/json/dpl/o2-analysis-perf-k0s-resolution.json @@ -30,12 +30,144 @@ 6.2831853 ] }, - "rapidity": "0.5", - "v0lifetime": "3", - "v0setting_cospa": "0.995", - "v0setting_dcanegtopv": "0.1", - "v0setting_dcapostopv": "0.1", - "v0setting_dcav0dau": "1", - "v0setting_radius": "0.9" + "relpTResBins": { + "values": [ + "200", + "0", + "0.5" + ] + }, + "centralityAxis": { + "values": [ + "0", + "0", + "5", + "10", + "20", + "30", + "40", + "50", + "60", + "70", + "80", + "90", + "100", + "101" + ] + }, + "occupancyAxis": { + "values": [ + "0", + "-1", + "0", + "250", + "500", + "750", + "1000", + "1500", + "2000", + "3000", + "4500", + "6000", + "8000", + "10000", + "50000" + ] + }, + "eventSelections": { + "requireSel8": "0", + "requireTriggerTVX": "1", + "rejectITSROFBorder": "1", + "rejectTFBorder": "1", + "requireIsVertexITSTPC": "0", + "requireIsGoodZvtxFT0VsPV": "0", + "requireIsVertexTOFmatched": "0", + "requireIsVertexTRDmatched": "0", + "rejectSameBunchPileup": "1", + "requireNoCollInTimeRangeStd": "0", + "requireNoCollInTimeRangeStrict": "0", + "requireNoCollInTimeRangeNarrow": "0", + "requireNoCollInROFStd": "0", + "requireNoCollInROFStrict": "0", + "requireINEL0": "0", + "requireINEL1": "0", + "maxZVtxPosition": "10", + "centralityEstimator": "0", + "useFT0CbasedOccupancy": "0", + "minOccupancy": "-1", + "maxOccupancy": "-1" + }, + "v0Selections": { + "v0TypeSelection": "1", + "rapidityCut": "0.5", + "daughterEtaCut": "0.800000012", + "v0cospa": "0.995000005", + "dcav0dau": "1", + "dcanegtopv": "0.100000001", + "dcapostopv": "0.100000001", + "v0radius": "1.20000005", + "v0radiusMax": "100000", + "lifetimecut": { + "labels_rows": "", + "labels_cols": [ + "lifetimecutLambda", + "lifetimecutK0S" + ], + "values": [ + [ + "30", + "20" + ] + ] + }, + "armPodCut": "5", + "minTPCrows": "70", + "minITSclusters": "-1", + "minTPCrowsOverFindableClusters": "-1", + "minTPCfoundOverFindableClusters": "-1", + "maxFractionTPCSharedClusters": "1e+09", + "maxITSchi2PerNcls": "1e+09", + "maxTPCchi2PerNcls": "1e+09", + "requirePosITSib": "0", + "requireNegITSib": "0", + "requirePosITSafterburner": "0", + "requireNegITSafterburner": "0", + "trdSelectionPos": "0", + "trdSelectionNeg": "0", + "tofSelectionPos": "0", + "tofSelectionNeg": "0", + "pidHypoPos": "-1", + "pidHypoNeg": "-1", + "tpcPidNsigmaCut": "1e+09", + "tofPidNsigmaCut": "1000000" + }, + "useMultidimHisto": "0", + "enableTPCPlot": "0", + "requireTrueK0s": "0", + "doTreatPiToMuon": "0", + "trackTuner": { + "debugInfo": "0", + "updateTrackDCAs": "0", + "updateTrackCovMat": "0", + "updateCurvature": "0", + "updateCurvatureIU": "0", + "updatePulls": "0", + "isInputFileFromCCDB": "0", + "pathInputFile": "", + "nameInputFile": "", + "pathFileQoverPt": "", + "nameFileQoverPt": "", + "usePvRefitCorrections": "0", + "qOverPtMC": "-1", + "qOverPtData": "-1", + "nPhiBins": "0" + }, + "useTrackTuner": "0", + "trackTunerParams": "debugInfo=0|updateTrackCovMat=0|updateCurvature=1|updatePulls=0|isInputFileFromCCDB=1|pathInputFile=Users/m/mfaggin/test/inputsTrackTuner/PbPb2022|nameInputFile=trackTuner_DataLHC22sPass5_McLHC22l1b2_run529397.root|usePvRefitCorrections=0|oneOverPtCurrent=1|oneOverPtUpgr=1.2", + "lutPath": "GLO/Param/MatLUTInner", + "ccdbUrl": "http://alice-ccdb.cern.ch", + "grpmagPath": "GLO/Config/GRPMagField", + "processData": "1", + "processMC": "0" } } diff --git a/MC/config/analysis_testing/json/dpl/o2-analysis-pid-tof-merge.json b/MC/config/analysis_testing/json/dpl/o2-analysis-pid-tof-merge.json new file mode 100644 index 000000000..f4a68dbee --- /dev/null +++ b/MC/config/analysis_testing/json/dpl/o2-analysis-pid-tof-merge.json @@ -0,0 +1,96 @@ +{ + "tof-pid-merge": { + "enableQaHistograms": "0", + "enableTOFParamsForBetaMass": "0", + "enableParticle": { + "labels_rows": [ + "El", + "Mu", + "Pi", + "Ka", + "Pr", + "De", + "Tr", + "He", + "Al" + ], + "labels_cols": [ + "Enable", + "EnableFull" + ], + "values": [ + [ + "-1", + "-1" + ], + [ + "-1", + "-1" + ], + [ + "-1", + "-1" + ], + [ + "-1", + "-1" + ], + [ + "-1", + "-1" + ], + [ + "-1", + "-1" + ], + [ + "-1", + "-1" + ], + [ + "-1", + "-1" + ], + [ + "-1", + "-1" + ] + ] + }, + "processRun3": "1", + "processRun2": "0", + "processRun2BetaM": "0", + "processRun3BetaM": "1" + }, + "tof-signal": { + "enableQaHistograms": "0", + "ccdb-url": "http://alice-ccdb.cern.ch", + "ccdb-path-grplhcif": "GLO/Config/GRPLHCIF", + "ccdb-timestamp": "-1", + "timeShiftCCDBPathPos": "Analysis/PID/TOFOffsetPos", + "timeShiftCCDBPathNeg": "Analysis/PID/TOFOffsetPos", + "timeShiftCCDBPathPosMC": "", + "timeShiftCCDBPathNegMC": "", + "paramFileName": "", + "parametrizationPath": "TOF/Calib/Params", + "reconstructionPass": "metadata", + "reconstructionPassDefault": "unanchored", + "fatalOnPassNotAvailable": "0", + "enableTimeDependentResponse": "1", + "collisionSystem": "-1", + "autoSetProcessFunctions": "1", + "processRun3": "1", + "processRun2": "0" + }, + "tof-event-time": { + "minMomentum": "0.5", + "maxMomentum": "2", + "maxEvTimeTOF": "100000", + "sel8TOFEvTime": "0", + "computeEvTimeWithTOF": "1", + "computeEvTimeWithFT0": "1", + "maxNtracksInSet": "10", + "processRun2": "0", + "processRun3": "1" + } +} \ No newline at end of file diff --git a/MC/config/analysis_testing/json/dpl/o2-analysis-pid-tpc-service.json b/MC/config/analysis_testing/json/dpl/o2-analysis-pid-tpc-service.json new file mode 100644 index 000000000..5069a4eb2 --- /dev/null +++ b/MC/config/analysis_testing/json/dpl/o2-analysis-pid-tpc-service.json @@ -0,0 +1,52 @@ +{ + "pid-tpc-service": { + "ccdburl": "http://alice-ccdb.cern.ch", + "pidTPC": { + "param-file": "", + "ccdbPath": "Analysis/PID/TPC/Response", + "recoPass": "", + "ccdb-timestamp": "0", + "useNetworkCorrection": "0", + "autofetchNetworks": "1", + "skipTPCOnly": "0", + "networkPathLocally": "network.onnx", + "networkPathCCDB": "Analysis/PID/TPC/ML", + "enableNetworkOptimizations": "1", + "networkSetNumThreads": "0", + "savedEdxsCorrected": "-1", + "useCorrecteddEdx": "0", + "pid-full-el": "-1", + "pid-full-mu": "-1", + "pid-full-pi": "-1", + "pid-full-ka": "-1", + "pid-full-pr": "-1", + "pid-full-de": "-1", + "pid-full-tr": "-1", + "pid-full-he": "-1", + "pid-full-al": "-1", + "pid-tiny-el": "-1", + "pid-tiny-mu": "-1", + "pid-tiny-pi": "-1", + "pid-tiny-ka": "-1", + "pid-tiny-pr": "-1", + "pid-tiny-de": "-1", + "pid-tiny-tr": "-1", + "pid-tiny-he": "-1", + "pid-tiny-al": "-1", + "enableTuneOnDataTable": "-1", + "useNetworkEl": "1", + "useNetworkMu": "0", + "useNetworkPi": "1", + "useNetworkKa": "1", + "useNetworkPr": "1", + "useNetworkDe": "0", + "useNetworkTr": "0", + "useNetworkHe": "0", + "useNetworkAl": "0", + "networkBetaGammaCutoff": "0.449999988" + }, + "processTracksIU": "1", + "processTracksIUWithTracksQA": "0", + "processTracksMCIU": "0" + } +} \ No newline at end of file diff --git a/MC/config/analysis_testing/json/dpl/o2-analysis-propagation-service.json b/MC/config/analysis_testing/json/dpl/o2-analysis-propagation-service.json new file mode 100644 index 000000000..05c23a7f0 --- /dev/null +++ b/MC/config/analysis_testing/json/dpl/o2-analysis-propagation-service.json @@ -0,0 +1,403 @@ +{ + "propagation-service": { + "ccdburl": "http://alice-ccdb.cern.ch", + "ccdb": { + "ccdb-url": "http://alice-ccdb.cern.ch", + "lutPath": "GLO/Param/MatLUTInner", + "grpmagPath": "GLO/Config/GRPMagField", + "mVtxPath": "GLO/Calib/MeanVertex" + }, + "enabledTables": { + "labels_rows": [ + "V0Indices", + "V0CoresBase", + "V0Covs", + "CascIndices", + "KFCascIndices", + "TraCascIndices", + "StoredCascCores", + "StoredKFCascCores", + "StoredTraCascCores", + "CascCovs", + "KFCascCovs", + "TraCascCovs", + "V0TrackXs", + "CascTrackXs", + "CascBBs", + "V0DauCovs", + "V0DauCovIUs", + "V0TraPosAtDCAs", + "V0TraPosAtIUs", + "V0Ivanovs", + "McV0Labels", + "V0MCCores", + "V0CoreMCLabels", + "V0MCCollRefs", + "McCascLabels", + "McKFCascLabels", + "McTraCascLabels", + "McCascBBTags", + "CascMCCores", + "CascCoreMCLabels", + "CascMCCollRefs", + "CascToTraRefs", + "CascToKFRefs", + "TraToCascRefs", + "KFToCascRefs", + "V0FoundTags", + "CascFoundTags" + ], + "labels_cols": [ + "enable" + ], + "values": [ + [ + "-1" + ], + [ + "-1" + ], + [ + "-1" + ], + [ + "-1" + ], + [ + "-1" + ], + [ + "-1" + ], + [ + "-1" + ], + [ + "-1" + ], + [ + "-1" + ], + [ + "-1" + ], + [ + "-1" + ], + [ + "-1" + ], + [ + "-1" + ], + [ + "-1" + ], + [ + "-1" + ], + [ + "-1" + ], + [ + "-1" + ], + [ + "-1" + ], + [ + "-1" + ], + [ + "-1" + ], + [ + "-1" + ], + [ + "-1" + ], + [ + "1" + ], + [ + "-1" + ], + [ + "-1" + ], + [ + "-1" + ], + [ + "-1" + ], + [ + "-1" + ], + [ + "1" + ], + [ + "1" + ], + [ + "1" + ], + [ + "-1" + ], + [ + "-1" + ], + [ + "-1" + ], + [ + "-1" + ], + [ + "-1" + ], + [ + "-1" + ] + ] + }, + "deduplicationAlgorithm": "1", + "useV0BufferForCascades": "0", + "mc_findableMode": "0", + "refitWithMaterialCorrection": "0", + "v0BuilderOpts": { + "generatePhotonCandidates": "0", + "moveTPCOnlyTracks": "1", + "minCrossedRows": "60", + "dcanegtopv": "0.0500000007", + "dcapostopv": "0.0500000007", + "v0cospa": "0.96999999999999997", + "dcav0dau": "1.5", + "v0radius": "0.899999976", + "maxDaughterEta": "0.800000012", + "mc_populateV0MCCoresSymmetric": "0", + "mc_populateV0MCCoresAsymmetric": "1", + "mc_treatPiToMuDecays": "1", + "mc_rapidityWindow": "0.5", + "mc_keepOnlyPhysicalPrimary": "1", + "mc_addGeneratedK0Short": "1", + "mc_addGeneratedLambda": "1", + "mc_addGeneratedAntiLambda": "1", + "mc_addGeneratedGamma": "0", + "mc_addGeneratedGammaMakeCollinear": "0", + "mc_findableDetachedV0": "0" + }, + "cascadeBuilderOpts": { + "useCascadeMomentumAtPrimVtx": "0", + "minCrossedRows": "60", + "dcabachtopv": "0.0500000007", + "cascradius": "0.899999976", + "casccospa": "0.970000029", + "dcacascdau": "1.5", + "lambdaMassWindow": "0.00999999978", + "maxDaughterEta": "0.800000012", + "kfTuneForOmega": "0", + "kfConstructMethod": "2", + "kfUseV0MassConstraint": "1", + "kfUseCascadeMassConstraint": "0", + "kfDoDCAFitterPreMinimV0": "1", + "kfDoDCAFitterPreMinimCasc": "1", + "mc_populateCascMCCoresSymmetric": "0", + "mc_populateCascMCCoresAsymmetric": "1", + "mc_addGeneratedXiMinus": "1", + "mc_addGeneratedXiPlus": "1", + "mc_addGeneratedOmegaMinus": "1", + "mc_addGeneratedOmegaPlus": "1", + "mc_treatPiToMuDecays": "1", + "mc_rapidityWindow": "0.5", + "mc_keepOnlyPhysicalPrimary": "1", + "mc_findableDetachedCascade": "0" + }, + "preSelectOpts": { + "preselectOnlyDesiredV0s": "0", + "preselectOnlyDesiredCascades": "0", + "lifetimeCut": { + "labels_rows": "", + "labels_cols": [ + "lifetimeCutK0S", + "lifetimeCutLambda", + "lifetimeCutXi", + "lifetimeCutOmega" + ], + "values": [ + [ + "20", + "60", + "40", + "20" + ] + ] + }, + "massCutPhoton": "0.300000012", + "massCutK0": { + "labels_rows": "", + "labels_cols": [ + "constant", + "linear", + "expoConstant", + "expoRelax" + ], + "values": [ + [ + "0.00281882007", + "0.00114057004", + "0.00172138005", + "0.500262022" + ] + ] + }, + "massCutLambda": { + "labels_rows": "", + "labels_cols": [ + "constant", + "linear", + "expoConstant", + "expoRelax" + ], + "values": [ + [ + "0.00117517996", + "0.000124098995", + "0.00547936978", + "0.308008999" + ] + ] + }, + "massCutXi": { + "labels_rows": "", + "labels_cols": [ + "constant", + "linear", + "expoConstant", + "expoRelax" + ], + "values": [ + [ + "0.00143209996", + "0.000203560994", + "0.00243186997", + "0.799668014" + ] + ] + }, + "massCutOm": { + "labels_rows": "", + "labels_cols": [ + "constant", + "linear", + "expoConstant", + "expoRelax" + ], + "values": [ + [ + "0.00143209996", + "0.000203560994", + "0.00243186997", + "0.799668014" + ] + ] + }, + "massWindownumberOfSigmas": "20", + "massWindowSafetyMargin": "0.00100000005", + "maxTPCpidNsigma": "5" + }, + "trackTuner": { + "debugInfo": "0", + "updateTrackDCAs": "0", + "updateTrackCovMat": "0", + "updateCurvature": "0", + "updateCurvatureIU": "0", + "updatePulls": "0", + "isInputFileFromCCDB": "0", + "pathInputFile": "", + "nameInputFile": "", + "pathFileQoverPt": "", + "nameFileQoverPt": "", + "usePvRefitCorrections": "0", + "qOverPtMC": "-1", + "qOverPtData": "-1", + "nPhiBins": "0" + }, + "trackPropagation": { + "minPropagationDistance": "5", + "useTrackTuner": "0", + "useTrkPid": "0", + "fillTrackTunerTable": "0", + "trackTunerConfigSource": "1", + "trackTunerParams": "debugInfo=0|updateTrackDCAs=1|updateTrackCovMat=1|updateCurvature=0|updateCurvatureIU=0|updatePulls=0|isInputFileFromCCDB=1|pathInputFile=Users\/m\/mfaggin\/test\/inputsTrackTuner\/PbPb2022|nameInputFile=trackTuner_DataLHC22sPass5_McLHC22l1b2_run529397.root|pathFileQoverPt=Users\/h\/hsharma\/qOverPtGraphs|nameFileQoverPt=D0sigma_Data_removal_itstps_MC_LHC22b1b.root|usePvRefitCorrections=0|qOverPtMC=-1.|qOverPtData=-1.", + "axisPtQA": { + "values": [ + "0", + "0", + "0.10000000149011612", + "0.20000000298023224", + "0.30000001192092896", + "0.4000000059604645", + "0.5", + "0.6000000238418579", + "0.699999988079071", + "0.800000011920929", + "0.8999999761581421", + "1", + "1.100000023841858", + "1.2000000476837158", + "1.2999999523162842", + "1.399999976158142", + "1.5", + "1.600000023841858", + "1.7000000476837158", + "1.7999999523162842", + "1.899999976158142", + "2", + "2.200000047683716", + "2.4000000953674316", + "2.5999999046325684", + "2.799999952316284", + "3", + "3.200000047683716", + "3.4000000953674316", + "3.5999999046325684", + "3.799999952316284", + "4", + "4.400000095367432", + "4.800000190734863", + "5.199999809265137", + "5.599999904632568", + "6", + "6.5", + "7", + "7.5", + "8", + "9", + "10", + "11", + "12", + "13", + "14", + "15", + "17", + "19", + "21", + "23", + "25", + "30", + "35", + "40", + "50" + ] + } + }, + "processRealData": "0", + "processMonteCarlo": "0", + "processRealDataWithPID": "1", + "processMonteCarloWithPID": "0" + } +} \ No newline at end of file diff --git a/MC/config/analysis_testing/json/dpl/o2-analysis-qa-event-track.json b/MC/config/analysis_testing/json/dpl/o2-analysis-qa-event-track.json index 07aacee70..0c4adc582 100644 --- a/MC/config/analysis_testing/json/dpl/o2-analysis-qa-event-track.json +++ b/MC/config/analysis_testing/json/dpl/o2-analysis-qa-event-track.json @@ -1,13 +1,138 @@ { "qa-event-track": { - "checkOnlyPVContributor": "true", - "overwriteAxisRangeForPbPb": "!OVERWRITEAXISRANGEFORPBPBVALUE!", - "processData": "!ANALYSIS_QC_is_data!", - "processDataIU": "false", - "processDataIUFiltered": "false", - "processMC": "!ANALYSIS_QC_is_mc!", - "processTableData": "false", - "processTableMC": "false", - "trackSelection": "1" - } + "maxEta": "2", + "checkOnlyPVContributor": "1", + "minPhi": "-1", + "binsPt": { + "values": [ + 0, + 0, + 0.1, + 0.2, + 0.3, + 0.4, + 0.5, + 0.6, + 0.7, + 0.8, + 0.9, + 1, + 1.1, + 1.2, + 1.3, + 1.4, + 1.5, + 2, + 5, + 10, + 20, + 50 + ] + }, + "minPt": "-10", + "selectPrim": "0", + "selectSec": "0", + "forceTRD": "0", + "processDataIU": "0", + "doDebug": "0", + "minTPCcrossedRows": "70", + "processTrackMatch": "!ANALYSIS_QC_is_data!", + "binsDeltaPt": { + "values": [ + 100, + -0.495, + 0.505 + ] + }, + "selectPID": "0", + "PartIdentifier": "2", + "forceNotTRD": "0", + "binsInvPt": { + "values": [ + 0, + 0, + 0.1, + 0.2, + 0.3, + 0.4, + 0.5, + 0.6, + 0.7, + 0.8, + 0.9, + 1, + 1.1, + 1.2, + 1.3, + 1.4, + 1.5, + 2, + 5, + 10, + 20, + 50 + ] + }, + "minEta": "-2", + "doExtraPIDqa": "0", + "tfCut": "1", + "processRun2ConvertedData": "0", + "addRunInfo": "1", + "maxPhi": "10", + "binsVertexPosZ": { + "values": [ + 100, + -20, + 20 + ] + }, + "selectGoodEvents": "1", + "maxPt": "1e+10", + "binsDeltaSigned1Pt": { + "values": [ + 100, + -0.495, + 0.505 + ] + }, + "binsSigned1Pt": { + "values": [ + 300, + -5, + 5 + ] + }, + "binsVertexNumContrib": { + "values": [ + 200, + 0, + 200 + ] + }, + "binsTrackMultiplicity": { + "values": [ + 1000, + 0, + 1000 + ] + }, + "checkFakeMatches": "0", + "overwriteAxisRangeForPbPb": "!OVERWRITEAXISRANGEFORPBPBVALUE!", + "activateChecksTRD": "0", + "binsVertexPosXY": { + "values": [ + 500, + -1, + 1 + ] + }, + "processData": "!ANALYSIS_QC_is_data!", + "trackSelection": "1", + "selectCharge": "0", + "checkPIDforTracking": "0", + "processRun2ConvertedMC": "0", + "isRun3": "1", + "processMC": "!ANALYSIS_QC_is_mc!", + "processDataIUFiltered": "0" + } } diff --git a/MC/config/analysis_testing/json/dpl/o2-analysis-time-dependent-qa.json b/MC/config/analysis_testing/json/dpl/o2-analysis-time-dependent-qa.json new file mode 100644 index 000000000..296243dd8 --- /dev/null +++ b/MC/config/analysis_testing/json/dpl/o2-analysis-time-dependent-qa.json @@ -0,0 +1,6 @@ +{ + "time-dependent-qa-task": { + "FlagCheckQoverPtHist": "0", + "FlagFillPhiVsTimeHist": "0" + } +} diff --git a/MC/config/analysis_testing/json/dpl/o2-analysis-track-to-collision-associator.json b/MC/config/analysis_testing/json/dpl/o2-analysis-track-to-collision-associator.json new file mode 100644 index 000000000..5a796328a --- /dev/null +++ b/MC/config/analysis_testing/json/dpl/o2-analysis-track-to-collision-associator.json @@ -0,0 +1,13 @@ +{ + "track-to-collision-association": { + "nSigmaForTimeCompat": "4", + "timeMargin": "500", + "setTrackSelections": "1", + "usePVAssociation": "true", + "includeUnassigned": "true", + "fillTableOfCollIdsPerTrack": "false", + "bcWindowForOneSigma": "60", + "processAssocWithTime": "true", + "processStandardAssoc": "false" + } +} diff --git a/MC/config/analysis_testing/json/dpl/o2-analysis-trackselection.json b/MC/config/analysis_testing/json/dpl/o2-analysis-trackselection.json index b8cc1b072..dc26e77f7 100644 --- a/MC/config/analysis_testing/json/dpl/o2-analysis-trackselection.json +++ b/MC/config/analysis_testing/json/dpl/o2-analysis-trackselection.json @@ -1,12 +1,14 @@ { "track-selection": { - "compatibilityIU": "false", - "etaMax": "0.8", - "etaMin": "-0.8", - "isRun3": "true", - "itsMatching": "1", + "isRun3": "1", + "produceTable": "-1", "produceFBextendedTable": "-1", + "compatibilityIU": "0", + "itsMatching": "1", + "dcaSetup": "0", + "ptMin": "0.100000001", "ptMax": "1e+10", - "ptMin": "0.1" + "etaMin": "-1", + "etaMax": "1" } -} +} \ No newline at end of file diff --git a/MC/config/analysis_testing/json/dpl/o2-analysistutorial-mc-histograms.json b/MC/config/analysis_testing/json/dpl/o2-analysistutorial-mc-histograms.json new file mode 100644 index 000000000..d60d3166b --- /dev/null +++ b/MC/config/analysis_testing/json/dpl/o2-analysistutorial-mc-histograms.json @@ -0,0 +1,11 @@ +{ + "access-mc-data": { + "reduce-output" : 2 + }, + "access-mc-truth": { + "reduce-output" : 2 + }, + "loop-over-mc-matched": { + "reduce-output" : 2 + } +} diff --git a/MC/config/common/TPCloopers/ScalerComptonParams.json b/MC/config/common/TPCloopers/ScalerComptonParams.json new file mode 100644 index 000000000..d8e654847 --- /dev/null +++ b/MC/config/common/TPCloopers/ScalerComptonParams.json @@ -0,0 +1,28 @@ +{ + "normal": { + "min": [ + -0.0108811147511005, + -0.0098758740350604, + -0.0103233363479375, + -260.0542297363281, + -259.80059814453125 + ], + "max": [ + 0.0108060473576188, + 0.0103057539090514, + 0.0106524610891938, + 260.0343933105469, + 259.62890625 + ] + }, + "outlier": { + "center": [ + -71.39387130737305, + 96791.23828125 + ], + "scale": [ + 265.9389114379883, + 230762.30981445312 + ] + } +} \ No newline at end of file diff --git a/MC/config/common/TPCloopers/ScalerPairParams.json b/MC/config/common/TPCloopers/ScalerPairParams.json new file mode 100644 index 000000000..61434bfa2 --- /dev/null +++ b/MC/config/common/TPCloopers/ScalerPairParams.json @@ -0,0 +1,34 @@ +{ + "normal": { + "min": [ + -0.0073022879660129, + -0.0077305701561272, + -0.0076750442385673, + -0.0082916170358657, + -0.0079681202769279, + -0.0077468422241508, + -255.6164093017578, + -252.9441680908203 + ], + "max": [ + 0.007688719779253, + 0.0077241472899913, + 0.0075828479602932, + 0.00813714787364, + 0.0083825681358575, + 0.0073839174583554, + 256.2904968261719, + 253.4925842285156 + ] + }, + "outlier": { + "center": [ + -79.66580963134766, + 141535.640625 + ], + "scale": [ + 250.8921127319336, + 222363.16015625 + ] + } +} \ No newline at end of file diff --git a/MC/config/common/TPCloopers/gaussian_params.csv b/MC/config/common/TPCloopers/gaussian_params.csv new file mode 100644 index 000000000..8e07c22dd --- /dev/null +++ b/MC/config/common/TPCloopers/gaussian_params.csv @@ -0,0 +1,4 @@ +9.611554230339172022e+01 +1.963570744941765867e+01 +4.300000000000000000e+01 +1.690000000000000000e+02 diff --git a/MC/config/common/TPCloopers/poisson_params.csv b/MC/config/common/TPCloopers/poisson_params.csv new file mode 100644 index 000000000..ef26bd973 --- /dev/null +++ b/MC/config/common/TPCloopers/poisson_params.csv @@ -0,0 +1,3 @@ +3.165383056343737511e+00 +1.000000000000000000e+00 +1.200000000000000000e+01 diff --git a/MC/config/common/external/generator/CoalescencePythia8.h b/MC/config/common/external/generator/CoalescencePythia8.h new file mode 100644 index 000000000..7e4abc53e --- /dev/null +++ b/MC/config/common/external/generator/CoalescencePythia8.h @@ -0,0 +1,182 @@ +// Copyright 2019-2020 CERN and copyright holders of ALICE O2. +// See https://alice-o2.web.cern.ch/copyright for details of the copyright holders. +// All rights not expressly granted are reserved. +// +// This software is distributed under the terms of the GNU General Public +// License v3 (GPL Version 3), copied verbatim in the file "COPYING". +// +// In applying this license CERN does not waive the privileges and immunities +// granted to it by virtue of its status as an Intergovernmental Organization +// or submit itself to any jurisdiction. + +#include "Pythia8/Pythia.h" +#include "fairlogger/Logger.h" +#include "TParticlePDG.h" +#include "TDatabasePDG.h" +#include "TSystem.h" +#include "TMath.h" +#include +#include +#include +#include +using namespace Pythia8; + +/// Coalescence afterburner for Pythia8 +/// Utility to compute naive coalescence afterburner as done in PRL 126, 101101 (2021) + +enum NucleiBits { + kDeuteron = 0, + kTriton = 1, + kHe3 = 2, + kHyperTriton = 3, + kHe4 = 4, +}; + +std::vector pdgList = {1000010020, 1000010030, 1000020030, 1010010030, 1000020040}; +std::vector massList = {1.875612, 2.80892113298, 2.808391, 2.991134, 3.727379}; + +bool doCoal(Pythia8::Event& event, int charge, int pdgCode, float mass, bool trivialCoal, double coalescenceRadius, bool nuclFromDecay, int iD1, int iD2, int iD3 = -1, int iD4 = -1) +{ + std::vector nucleonIDs = std::vector{iD1, iD2}; + // add A=3 and A=4 nuclei if enabled + if (iD3 > 0) { + nucleonIDs.push_back(iD3); + } + if (iD4 > 0) { + nucleonIDs.push_back(iD4); + } + Pythia8::Vec4 p; + for (auto nID : nucleonIDs) { + if (event[nID].status() < 0) { + // nucleon already used in coalescence + return false; + } + p += event[nID].p(); + } + bool isCoalescence = true; + for (auto nID : nucleonIDs) { + auto pN = event[nID].p(); + pN.bstback(p); + // trivial coal does not check the distance of the nucleons + if (pN.pAbs() > coalescenceRadius && !trivialCoal) { + isCoalescence = false; + break; + } + } + if (!isCoalescence) { + return false; + } + p.e(std::hypot(p.pAbs(), mass)); + + if (!nuclFromDecay) { + /// keep the original nucleons with negative status, store the mother with status 94 + event.append((charge * 2 - 1) * pdgCode, 94, 0, 0, 0, 0, 0, 0, p.px(), p.py(), p.pz(), p.e(), mass); + for (auto nID : nucleonIDs) { + event[nID].statusNeg(); + event[nID].daughter1(event.size() - 1); + } + } else { + // first nucleon will be replaced by the nucleus, the others will be removed + bool swap = true; + int nRemoved = 0; + for (auto iPart{0}; iPart < event.size(); ++iPart) { + for (auto nID : nucleonIDs) { + if (iPart == nID && swap) { + // replace the nucleon with the nucleus + LOG(debug) << "Replacing nucleon with index " << iPart << " and pdg code " << event[iPart].id() << " with nucleus with pdg code " << (charge * 2 - 1) * pdgCode; + event[iPart].id((charge * 2 - 1) * pdgCode); + event[iPart].status(94); + event[iPart].px(p.px()); + event[iPart].py(p.py()); + event[iPart].pz(p.pz()); + event[iPart].e(std::hypot(p.pAbs(), mass)); + event[iPart].m(mass); + swap = false; + } else if (iPart == nID - nRemoved && !swap) { + LOG(debug) << "Removing nucleon with index " << iPart << " and pdg code " << event[iPart].id(); + event.remove(iPart, iPart, true); + nRemoved++; + } + } + } + } + LOG(debug) << "Adding a " << (charge * 2 - 1) * pdgCode << " with p = " << p.px() << ", " << p.py() << ", " << p.pz() << ", E = " << p.e(); + return true; +} + +bool CoalescencePythia8(Pythia8::Event& event, std::vector inputPdgList = {}, bool trivialCoal = false, double coalMomentum = 0.4, int firstDauID = -1, int lastDauId = -1, float maxRapidity = 1.) +{ + const double coalescenceRadius{0.5 * 1.122462 * coalMomentum}; + // if coalescence from a heavy hadron, loop only between firstDauID and lastDauID + int loopStart = firstDauID > -1 ? firstDauID : 0; + int loopEnd = lastDauId > -1 ? lastDauId : event.size() - 1; + // fill the nuclear mask + uint8_t nuclearMask = 0; + for (auto nuclPdg : inputPdgList) { + if (nuclPdg == pdgList[NucleiBits::kDeuteron]) { + nuclearMask |= (1 << kDeuteron); + } else if (nuclPdg == pdgList[NucleiBits::kTriton]) { + nuclearMask |= (1 << kTriton); + } else if (nuclPdg == pdgList[NucleiBits::kHe3]) { + nuclearMask |= (1 << kHe3); + } else if (nuclPdg == pdgList[NucleiBits::kHyperTriton]) { + nuclearMask |= (1 << kHyperTriton); + } else if (nuclPdg == pdgList[NucleiBits::kHe4]) { + nuclearMask |= (1 << kHe4); + } else { + LOG(fatal) << "Unknown pdg code for coalescence generator: " << nuclPdg; + return false; + } + } + // fill nucleon pools + std::vector protons[2], neutrons[2], lambdas[2]; + for (auto iPart{loopStart}; iPart <= loopEnd; ++iPart) { + if (std::abs(event[iPart].y()) > maxRapidity) // skip particles with y > ymax + { + continue; + } + if (std::abs(event[iPart].id()) == 2212) { + protons[event[iPart].id() > 0].push_back(iPart); + } else if (std::abs(event[iPart].id()) == 2112) { + neutrons[event[iPart].id() > 0].push_back(iPart); + } else if (std::abs(event[iPart].id()) == 3122 && (nuclearMask & (1 << kHyperTriton))) { + lambdas[event[iPart].id() > 0].push_back(iPart); + } + } + // run coalescence + bool nuclFromDecay = firstDauID > -1; + bool coalHappened = false; + + for (int iC{0}; iC < 2; ++iC) { + for (int iP{0}; iP < protons[iC].size(); ++iP) { + for (int iN{0}; iN < neutrons[iC].size(); ++iN) { + if (nuclearMask & (1 << kDeuteron)) { + coalHappened |= doCoal(event, iC, pdgList[kDeuteron], massList[kDeuteron], trivialCoal, coalescenceRadius, nuclFromDecay, protons[iC][iP], neutrons[iC][iN]); + } + if (nuclearMask & (1 << kTriton)) { + for (int iN2{iN + 1}; iN2 < neutrons[iC].size(); ++iN2) { + coalHappened |= doCoal(event, iC, pdgList[kTriton], massList[kTriton], trivialCoal, coalescenceRadius, nuclFromDecay, protons[iC][iP], neutrons[iC][iN], neutrons[iC][iN2]); + } + } + if (nuclearMask & (1 << kHe3)) { + for (int iP2{iP + 1}; iP2 < protons[iC].size(); ++iP2) { + coalHappened |= doCoal(event, iC, pdgList[kHe3], massList[kHe3], trivialCoal, coalescenceRadius, nuclFromDecay, protons[iC][iP], protons[iC][iP2], neutrons[iC][iN]); + } + } + if (nuclearMask & (1 << kHyperTriton)) { + for (int iL{0}; iL < lambdas[iC].size(); ++iL) { + coalHappened |= doCoal(event, iC, pdgList[kHyperTriton], massList[kHyperTriton], trivialCoal, coalescenceRadius, nuclFromDecay, protons[iC][iP], neutrons[iC][iN], lambdas[iC][iL]); + } + } + if (nuclearMask & (1 << kHe4)) { + for (int iP2{iP + 1}; iP2 < protons[iC].size(); ++iP2) { + for (int iN2{iN + 1}; iN2 < neutrons[iC].size(); ++iN2) { + coalHappened |= doCoal(event, iC, pdgList[kHe4], massList[kHe4], trivialCoal, coalescenceRadius, nuclFromDecay, protons[iC][iP], protons[iC][iP2], neutrons[iC][iN], neutrons[iC][iN2]); + } + } + } + } + } + } + return coalHappened; +} diff --git a/MC/config/common/external/generator/QEDepem.C b/MC/config/common/external/generator/QEDepem.C index 4ed3cdcc4..f34cfe839 100644 --- a/MC/config/common/external/generator/QEDepem.C +++ b/MC/config/common/external/generator/QEDepem.C @@ -29,6 +29,8 @@ o2::eventgen::GeneratorTGenerator* QEDepem() genBg->SetPtRange(qedParam.ptMin, qedParam.ptMax); // Set pt limits (GeV) for e+-: 1MeV corresponds to max R=13.3mm at 5kGaus genBg->SetOrigin(diamond.position[0], diamond.position[1], diamond.position[2]); // vertex position in space genBg->SetSigma(diamond.width[0], diamond.width[1], diamond.width[2]); // vertex sigma + genBg->SetCMEnergy(qedParam.cmEnergy); // center of mass energy per nucleon pair in GeV + genBg->SetZ(qedParam.Z); // atomic number of the projectile/target (only symmetric systems are compatible for now) genBg->SetTimeOrigin(0.); // vertex position in time genBg->Init(); diff --git a/MC/config/common/external/generator/TPCLoopers.C b/MC/config/common/external/generator/TPCLoopers.C new file mode 100644 index 000000000..8253fe091 --- /dev/null +++ b/MC/config/common/external/generator/TPCLoopers.C @@ -0,0 +1,787 @@ +#include +#include +#include +#include +#include +#include "CCDB/CCDBTimeStampUtils.h" +#include "CCDB/CcdbApi.h" +#include "DetectorsRaw/HBFUtils.h" + +//** This external generator is now used for development purposes only. +//** Fast simulated TPC loopers are automatically integrated as detector effect in O2 +//** starting from the O2PDPSuite::MC-prod-2026-v3-1 official release (05/02/2026) +//** Previous cocktails configurations using this generator must not be used anymore for recent tags, +//** as they will increase the default TPC loopers contribution. +//** For support: Marco Giacalone . + +// Static Ort::Env instance for multiple onnx model loading +static Ort::Env global_env(ORT_LOGGING_LEVEL_WARNING, "GlobalEnv"); + +// This class is responsible for loading the scaler parameters from a JSON file +// and applying the inverse transformation to the generated data. +struct Scaler_debug +{ + std::vector normal_min; + std::vector normal_max; + std::vector outlier_center; + std::vector outlier_scale; + + void load(const std::string &filename) + { + std::ifstream file(filename); + if (!file.is_open()) + { + throw std::runtime_error("Error: Could not open scaler file!"); + } + + std::string json_str((std::istreambuf_iterator(file)), std::istreambuf_iterator()); + file.close(); + + rapidjson::Document doc; + doc.Parse(json_str.c_str()); + + if (doc.HasParseError()) + { + throw std::runtime_error("Error: JSON parsing failed!"); + } + + normal_min = jsonArrayToVector(doc["normal"]["min"]); + normal_max = jsonArrayToVector(doc["normal"]["max"]); + outlier_center = jsonArrayToVector(doc["outlier"]["center"]); + outlier_scale = jsonArrayToVector(doc["outlier"]["scale"]); + } + + std::vector inverse_transform(const std::vector &input) + { + std::vector output; + for (int i = 0; i < input.size(); ++i) + { + if (i < input.size() - 2) + output.push_back(input[i] * (normal_max[i] - normal_min[i]) + normal_min[i]); + else + output.push_back(input[i] * outlier_scale[i - (input.size() - 2)] + outlier_center[i - (input.size() - 2)]); + } + + return output; + } + +private: + std::vector jsonArrayToVector(const rapidjson::Value &jsonArray) + { + std::vector vec; + for (int i = 0; i < jsonArray.Size(); ++i) + { + vec.push_back(jsonArray[i].GetDouble()); + } + return vec; + } +}; + +// This class loads the ONNX model and generates samples using it. +class ONNXGenerator_debug +{ +public: + ONNXGenerator_debug(Ort::Env &shared_env, const std::string &model_path) + : env(shared_env), session(env, model_path.c_str(), Ort::SessionOptions{}) + { + // Create session options + Ort::SessionOptions session_options; + session = Ort::Session(env, model_path.c_str(), session_options); + } + + std::vector generate_sample() + { + Ort::AllocatorWithDefaultOptions allocator; + + // Generate a latent vector (z) + std::vector z(100); + for (auto &v : z) + v = rand_gen.Gaus(0.0, 1.0); + + // Prepare input tensor + std::vector input_shape = {1, 100}; + // Get memory information + Ort::MemoryInfo memory_info = Ort::MemoryInfo::CreateCpu(OrtArenaAllocator, OrtMemTypeDefault); + + // Create input tensor correctly + Ort::Value input_tensor = Ort::Value::CreateTensor( + memory_info, z.data(), z.size(), input_shape.data(), input_shape.size()); + // Run inference + const char *input_names[] = {"z"}; + const char *output_names[] = {"output"}; + auto output_tensors = session.Run(Ort::RunOptions{nullptr}, input_names, &input_tensor, 1, output_names, 1); + + // Extract output + float *output_data = output_tensors.front().GetTensorMutableData(); + // Get the size of the output tensor + auto output_tensor_info = output_tensors.front().GetTensorTypeAndShapeInfo(); + size_t output_data_size = output_tensor_info.GetElementCount(); // Total number of elements in the tensor + std::vector output; + for (int i = 0; i < output_data_size; ++i) + { + output.push_back(output_data[i]); + } + + return output; + } + +private: + Ort::Env &env; + Ort::Session session; + TRandom3 rand_gen; +}; + +namespace o2 +{ +namespace eventgen +{ + +class GenTPCLoopers_debug : public Generator +{ + public: + GenTPCLoopers_debug(std::string model_pairs = "tpcloopmodel.onnx", std::string model_compton = "tpcloopmodelcompton.onnx", + std::string poisson = "poisson.csv", std::string gauss = "gauss.csv", std::string scaler_pair = "scaler_pair.json", + std::string scaler_compton = "scaler_compton.json") + { + // Checking if the model files exist and are not empty + std::ifstream model_file[2]; + model_file[0].open(model_pairs); + model_file[1].open(model_compton); + if (!model_file[0].is_open() || model_file[0].peek() == std::ifstream::traits_type::eof()) + { + LOG(fatal) << "Error: Pairs model file is empty or does not exist!"; + exit(1); + } + if (!model_file[1].is_open() || model_file[1].peek() == std::ifstream::traits_type::eof()) + { + LOG(fatal) << "Error: Compton model file is empty or does not exist!"; + exit(1); + } + model_file[0].close(); + model_file[1].close(); + // Checking if the scaler files exist and are not empty + std::ifstream scaler_file[2]; + scaler_file[0].open(scaler_pair); + scaler_file[1].open(scaler_compton); + if (!scaler_file[0].is_open() || scaler_file[0].peek() == std::ifstream::traits_type::eof()) + { + LOG(fatal) << "Error: Pairs scaler file is empty or does not exist!"; + exit(1); + } + if (!scaler_file[1].is_open() || scaler_file[1].peek() == std::ifstream::traits_type::eof()) + { + LOG(fatal) << "Error: Compton scaler file is empty or does not exist!"; + exit(1); + } + scaler_file[0].close(); + scaler_file[1].close(); + // Checking if the poisson file exists and it's not empty + if (poisson != "") + { + std::ifstream poisson_file(poisson); + if (!poisson_file.is_open() || poisson_file.peek() == std::ifstream::traits_type::eof()) + { + LOG(fatal) << "Error: Poisson file is empty or does not exist!"; + exit(1); + } + else + { + poisson_file >> mPoisson[0] >> mPoisson[1] >> mPoisson[2]; + poisson_file.close(); + mPoissonSet = true; + } + } + // Checking if the gauss file exists and it's not empty + if (gauss != "") + { + std::ifstream gauss_file(gauss); + if (!gauss_file.is_open() || gauss_file.peek() == std::ifstream::traits_type::eof()) + { + LOG(fatal) << "Error: Gauss file is empty or does not exist!"; + exit(1); + } + else + { + gauss_file >> mGauss[0] >> mGauss[1] >> mGauss[2] >> mGauss[3]; + gauss_file.close(); + mGaussSet = true; + } + } + mONNX_pair = std::make_unique(global_env, model_pairs); + mScaler_pair = std::make_unique(); + mScaler_pair->load(scaler_pair); + mONNX_compton = std::make_unique(global_env, model_compton); + mScaler_compton = std::make_unique(); + mScaler_compton->load(scaler_compton); + Generator::setTimeUnit(1.0); + Generator::setPositionUnit(1.0); + } + + Bool_t generateEvent() override + { + // Clear the vector of pairs + mGenPairs.clear(); + // Clear the vector of compton electrons + mGenElectrons.clear(); + if (mFlatGas) + { + unsigned int nLoopers, nLoopersPairs, nLoopersCompton; + LOG(debug) << "mCurrentEvent is " << mCurrentEvent; + LOG(debug) << "Current event time: " << ((mCurrentEvent < mInteractionTimeRecords.size() - 1) ? std::to_string(mInteractionTimeRecords[mCurrentEvent + 1].bc2ns() - mInteractionTimeRecords[mCurrentEvent].bc2ns()) : std::to_string(mTimeEnd - mInteractionTimeRecords[mCurrentEvent].bc2ns())) << " ns"; + LOG(debug) << "Current time offset wrt BC: " << mInteractionTimeRecords[mCurrentEvent].getTimeOffsetWrtBC() << " ns"; + mTimeLimit = (mCurrentEvent < mInteractionTimeRecords.size() - 1) ? mInteractionTimeRecords[mCurrentEvent + 1].bc2ns() - mInteractionTimeRecords[mCurrentEvent].bc2ns() : mTimeEnd - mInteractionTimeRecords[mCurrentEvent].bc2ns(); + // With flat gas the number of loopers are adapted based on time interval widths + // The denominator is either the LHC orbit (if mFlatGasOrbit is true) or the mean interaction time record interval + nLoopers = mFlatGasOrbit ? (mFlatGasNumber * (mTimeLimit / o2::constants::lhc::LHCOrbitNS)) : (mFlatGasNumber * (mTimeLimit / mIntTimeRecMean)); + nLoopersPairs = static_cast(std::round(nLoopers * mLoopsFractionPairs)); + nLoopersCompton = nLoopers - nLoopersPairs; + SetNLoopers(nLoopersPairs, nLoopersCompton); + LOG(info) << "Flat gas loopers: " << nLoopers << " (pairs: " << nLoopersPairs << ", compton: " << nLoopersCompton << ")"; + generateEvent(mTimeLimit); + mCurrentEvent++; + } else { + // Set number of loopers if poissonian params are available + if (mPoissonSet) + { + mNLoopersPairs = static_cast(std::round(mMultiplier[0] * PoissonPairs())); + } + if (mGaussSet) + { + mNLoopersCompton = static_cast(std::round(mMultiplier[1] * GaussianElectrons())); + } + // Generate pairs + for (int i = 0; i < mNLoopersPairs; ++i) + { + std::vector pair = mONNX_pair->generate_sample(); + // Apply the inverse transformation using the scaler + std::vector transformed_pair = mScaler_pair->inverse_transform(pair); + mGenPairs.push_back(transformed_pair); + } + // Generate compton electrons + for (int i = 0; i < mNLoopersCompton; ++i) + { + std::vector electron = mONNX_compton->generate_sample(); + // Apply the inverse transformation using the scaler + std::vector transformed_electron = mScaler_compton->inverse_transform(electron); + mGenElectrons.push_back(transformed_electron); + } + } + return true; + } + + Bool_t generateEvent(double &time_limit) + { + LOG(info) << "Time constraint for loopers: " << time_limit << " ns"; + // Generate pairs + for (int i = 0; i < mNLoopersPairs; ++i) + { + std::vector pair = mONNX_pair->generate_sample(); + // Apply the inverse transformation using the scaler + std::vector transformed_pair = mScaler_pair->inverse_transform(pair); + transformed_pair[9] = gRandom->Uniform(0., time_limit); // Regenerate time, scaling is not needed because time_limit is already in nanoseconds + mGenPairs.push_back(transformed_pair); + } + // Generate compton electrons + for (int i = 0; i < mNLoopersCompton; ++i) + { + std::vector electron = mONNX_compton->generate_sample(); + // Apply the inverse transformation using the scaler + std::vector transformed_electron = mScaler_compton->inverse_transform(electron); + transformed_electron[6] = gRandom->Uniform(0., time_limit); // Regenerate time, scaling is not needed because time_limit is already in nanoseconds + mGenElectrons.push_back(transformed_electron); + } + LOG(info) << "Generated Particles with time limit"; + return true; + } + + Bool_t importParticles() override + { + // Get looper pairs from the event + for (auto &pair : mGenPairs) + { + double px_e, py_e, pz_e, px_p, py_p, pz_p; + double vx, vy, vz, time; + double e_etot, p_etot; + px_e = pair[0]; + py_e = pair[1]; + pz_e = pair[2]; + px_p = pair[3]; + py_p = pair[4]; + pz_p = pair[5]; + vx = pair[6]; + vy = pair[7]; + vz = pair[8]; + time = pair[9]; + e_etot = TMath::Sqrt(px_e * px_e + py_e * py_e + pz_e * pz_e + mMass_e * mMass_e); + p_etot = TMath::Sqrt(px_p * px_p + py_p * py_p + pz_p * pz_p + mMass_p * mMass_p); + // Push the electron + TParticle electron(11, 1, -1, -1, -1, -1, px_e, py_e, pz_e, e_etot, vx, vy, vz, time / 1e9); + electron.SetStatusCode(o2::mcgenstatus::MCGenStatusEncoding(electron.GetStatusCode(), 0).fullEncoding); + electron.SetBit(ParticleStatus::kToBeDone, // + o2::mcgenstatus::getHepMCStatusCode(electron.GetStatusCode()) == 1); + mParticles.push_back(electron); + // Push the positron + TParticle positron(-11, 1, -1, -1, -1, -1, px_p, py_p, pz_p, p_etot, vx, vy, vz, time / 1e9); + positron.SetStatusCode(o2::mcgenstatus::MCGenStatusEncoding(positron.GetStatusCode(), 0).fullEncoding); + positron.SetBit(ParticleStatus::kToBeDone, // + o2::mcgenstatus::getHepMCStatusCode(positron.GetStatusCode()) == 1); + mParticles.push_back(positron); + } + // Get compton electrons from the event + for (auto &compton : mGenElectrons) + { + double px, py, pz; + double vx, vy, vz, time; + double etot; + px = compton[0]; + py = compton[1]; + pz = compton[2]; + vx = compton[3]; + vy = compton[4]; + vz = compton[5]; + time = compton[6]; + etot = TMath::Sqrt(px * px + py * py + pz * pz + mMass_e * mMass_e); + // Push the electron + TParticle electron(11, 1, -1, -1, -1, -1, px, py, pz, etot, vx, vy, vz, time / 1e9); + electron.SetStatusCode(o2::mcgenstatus::MCGenStatusEncoding(electron.GetStatusCode(), 0).fullEncoding); + electron.SetBit(ParticleStatus::kToBeDone, // + o2::mcgenstatus::getHepMCStatusCode(electron.GetStatusCode()) == 1); + mParticles.push_back(electron); + } + + return true; + } + + unsigned int PoissonPairs() + { + unsigned int poissonValue; + do + { + // Generate a Poisson-distributed random number with mean mPoisson[0] + poissonValue = mRandGen.Poisson(mPoisson[0]); + } while (poissonValue < mPoisson[1] || poissonValue > mPoisson[2]); // Regenerate if out of range + + return poissonValue; + } + + unsigned int GaussianElectrons() + { + unsigned int gaussValue; + do + { + // Generate a Normal-distributed random number with mean mGass[0] and stddev mGauss[1] + gaussValue = mRandGen.Gaus(mGauss[0], mGauss[1]); + } while (gaussValue < mGauss[2] || gaussValue > mGauss[3]); // Regenerate if out of range + + return gaussValue; + } + + void SetNLoopers(unsigned int &nsig_pair, unsigned int &nsig_compton) + { + if(mPoissonSet) { + LOG(info) << "Poissonian parameters correctly loaded."; + } else { + mNLoopersPairs = nsig_pair; + } + if(mGaussSet) { + LOG(info) << "Gaussian parameters correctly loaded."; + } else { + mNLoopersCompton = nsig_compton; + } + } + + void SetMultiplier(std::array &mult) + { + // Multipliers will work only if the poissonian and gaussian parameters are set + // otherwise they will be ignored + if (mult[0] < 0 || mult[1] < 0) + { + LOG(fatal) << "Error: Multiplier values must be non-negative!"; + exit(1); + } else { + LOG(info) << "Multiplier values set to: Pair = " << mult[0] << ", Compton = " << mult[1]; + mMultiplier[0] = mult[0]; + mMultiplier[1] = mult[1]; + } + } + + void setFlatGas(Bool_t &flat, const Int_t &number = -1, const Int_t &nloopers_orbit = -1) + { + mFlatGas = flat; + if (mFlatGas) + { + if(nloopers_orbit > 0) + { + mFlatGasOrbit = true; + mFlatGasNumber = nloopers_orbit; + LOG(info) << "Flat gas loopers will be generated using orbit reference."; + } else { + mFlatGasOrbit = false; + if (number < 0) + { + LOG(warn) << "Warning: Number of loopers per event must be non-negative! Switching option off."; + mFlatGas = false; + mFlatGasNumber = -1; + } else { + mFlatGasNumber = number; + } + } + if (mFlatGas){ + // Check if mContextFile is already opened + if(!mContextFile) + { + mContextFile = std::filesystem::exists("collisioncontext.root") ? TFile::Open("collisioncontext.root") : nullptr; + } + if(!mCollisionContext) + { + mCollisionContext = mContextFile ? (o2::steer::DigitizationContext *)mContextFile->Get("DigitizationContext") : nullptr; + } + mInteractionTimeRecords = mCollisionContext ? mCollisionContext->getEventRecords() : std::vector{}; + if (mInteractionTimeRecords.empty()) + { + LOG(error) << "Error: No interaction time records found in the collision context!"; + exit(1); + } else { + LOG(info) << "Interaction Time records has " << mInteractionTimeRecords.size() << " entries."; + mCollisionContext->printCollisionSummary(); + } + for (int c = 0; c < mInteractionTimeRecords.size() - 1; c++) + { + mIntTimeRecMean += mInteractionTimeRecords[c + 1].bc2ns() - mInteractionTimeRecords[c].bc2ns(); + } + mIntTimeRecMean /= (mInteractionTimeRecords.size() - 1); // Average interaction time record used as reference + const auto &hbfUtils = o2::raw::HBFUtils::Instance(); + // Get the start time of the second orbit after the last interaction record + const auto &lastIR = mInteractionTimeRecords.back(); + o2::InteractionRecord finalOrbitIR(0, lastIR.orbit + 2); // Final orbit, BC = 0 + mTimeEnd = finalOrbitIR.bc2ns(); + LOG(debug) << "Final orbit start time: " << mTimeEnd << " ns while last interaction record time is " << mInteractionTimeRecords.back().bc2ns() << " ns"; + } + } else { + mFlatGasNumber = -1; + } + LOG(info) << "Flat gas loopers: " << (mFlatGas ? "ON" : "OFF") << ", Reference loopers number per " << (mFlatGasOrbit ? "orbit " : "event ") << mFlatGasNumber; + } + + void setFractionPairs(float &fractionPairs) + { + if (fractionPairs < 0 || fractionPairs > 1) + { + LOG(fatal) << "Error: Loops fraction for pairs must be in the range [0, 1]."; + exit(1); + } + mLoopsFractionPairs = fractionPairs; + LOG(info) << "Pairs fraction set to: " << mLoopsFractionPairs; + } + + void SetRate(const std::string &rateFile, const bool isPbPb = true, const int &intRate = 50000) + { + // Checking if the rate file exists and is not empty + TFile rate_file(rateFile.c_str(), "READ"); + if (!rate_file.IsOpen() || rate_file.IsZombie()) + { + LOG(fatal) << "Error: Rate file is empty or does not exist!"; + exit(1); + } + const char* fitName = isPbPb ? "fitPbPb" : "fitpp"; + auto fit = (TF1 *)rate_file.Get(fitName); + if (!fit) + { + LOG(fatal) << "Error: Could not find fit function '" << fitName << "' in rate file!"; + exit(1); + } + mInteractionRate = intRate; + if(mInteractionRate < 0) + { + mContextFile = std::filesystem::exists("collisioncontext.root") ? TFile::Open("collisioncontext.root") : nullptr; + if(!mContextFile || mContextFile->IsZombie()) + { + LOG(fatal) << "Error: Interaction rate not provided and collision context file not found!"; + exit(1); + } + mCollisionContext = (o2::steer::DigitizationContext *)mContextFile->Get("DigitizationContext"); + mInteractionRate = std::floor(mCollisionContext->getDigitizerInteractionRate()); + LOG(info) << "Interaction rate retrieved from collision context: " << mInteractionRate << " Hz"; + if (mInteractionRate < 0) + { + LOG(fatal) << "Error: Invalid interaction rate retrieved from collision context!"; + exit(1); + } + } + auto ref = static_cast(std::floor(fit->Eval(mInteractionRate / 1000.))); // fit expects rate in kHz + rate_file.Close(); + if (ref <= 0) + { + LOG(fatal) << "Computed flat gas number reference per orbit is <=0"; + exit(1); + } else { + LOG(info) << "Set flat gas number to " << ref << " loopers per orbit using " << fitName << " from " << mInteractionRate << " Hz interaction rate."; + auto flat = true; + setFlatGas(flat, -1, ref); + } + } + + void SetAdjust(const float &adjust = 0.f) + { + if (mFlatGas && mFlatGasOrbit && adjust >= -1.f && adjust != 0.f) + { + LOG(info) << "Adjusting flat gas number per orbit by " << adjust * 100.f << "%"; + mFlatGasNumber = static_cast(std::round(mFlatGasNumber * (1.f + adjust))); + LOG(info) << "New flat gas number per orbit: " << mFlatGasNumber; + } + } + + private: + std::unique_ptr mONNX_pair = nullptr; + std::unique_ptr mONNX_compton = nullptr; + std::unique_ptr mScaler_pair = nullptr; + std::unique_ptr mScaler_compton = nullptr; + double mPoisson[3] = {0.0, 0.0, 0.0}; // Mu, Min and Max of Poissonian + double mGauss[4] = {0.0, 0.0, 0.0, 0.0}; // Mean, Std, Min, Max + std::vector> mGenPairs; + std::vector> mGenElectrons; + unsigned int mNLoopersPairs = -1; + unsigned int mNLoopersCompton = -1; + std::array mMultiplier = {1., 1.}; + bool mPoissonSet = false; + bool mGaussSet = false; + // Random number generator + TRandom3 mRandGen; + // Masses of the electrons and positrons + TDatabasePDG *mPDG = TDatabasePDG::Instance(); + double mMass_e = mPDG->GetParticle(11)->Mass(); + double mMass_p = mPDG->GetParticle(-11)->Mass(); + int mCurrentEvent = 0; // Current event number, used for adaptive loopers + TFile *mContextFile = nullptr; // Input collision context file + o2::steer::DigitizationContext *mCollisionContext = nullptr; // Pointer to the digitization context + std::vector mInteractionTimeRecords; // Interaction time records from collision context + Bool_t mFlatGas = false; // Flag to indicate if flat gas loopers are used + Bool_t mFlatGasOrbit = false; // Flag to indicate if flat gas loopers are per orbit + Int_t mFlatGasNumber = -1; // Number of flat gas loopers per event + double mIntTimeRecMean = 1.0; // Average interaction time record used for the reference + double mTimeLimit = 0.0; // Time limit for the current event + double mTimeEnd = 0.0; // Time limit for the last event + float mLoopsFractionPairs = 0.08; // Fraction of loopers from Pairs + std::string mRateFile = ""; // File with clusters/rate information per orbit + int mInteractionRate = 38000; // Interaction rate in Hz +}; + +} // namespace eventgen +} // namespace o2 + +// ONNX model files can be local, on AliEn or in the ALICE CCDB. +// For local and alien files it is mandatory to provide the filenames, for the CCDB instead the +// path to the object in the CCDB is sufficient. The model files will be downloaded locally. +// Example of CCDB path: "ccdb://Users/n/name/test" +// Example of alien path: "alien:///alice/cern.ch/user/n/name/test/test.onnx" +FairGenerator * + Generator_TPCLoopers(std::string model_pairs = "tpcloopmodel.onnx", std::string model_compton = "tpcloopmodelcompton.onnx", + std::string poisson = "poisson.csv", std::string gauss = "gauss.csv", std::string scaler_pair = "scaler_pair.json", + std::string scaler_compton = "scaler_compton.json", std::array mult = {1., 1.}, unsigned int nloopers_pairs = 1, + unsigned int nloopers_compton = 1) +{ + // Expand all environment paths + model_pairs = gSystem->ExpandPathName(model_pairs.c_str()); + model_compton = gSystem->ExpandPathName(model_compton.c_str()); + poisson = gSystem->ExpandPathName(poisson.c_str()); + gauss = gSystem->ExpandPathName(gauss.c_str()); + scaler_pair = gSystem->ExpandPathName(scaler_pair.c_str()); + scaler_compton = gSystem->ExpandPathName(scaler_compton.c_str()); + const std::array models = {model_pairs, model_compton}; + const std::array local_names = {"WGANpair.onnx", "WGANcompton.onnx"}; + const std::array isAlien = {models[0].starts_with("alien://"), models[1].starts_with("alien://")}; + const std::array isCCDB = {models[0].starts_with("ccdb://"), models[1].starts_with("ccdb://")}; + if (std::any_of(isAlien.begin(), isAlien.end(), [](bool v) { return v; })) + { + if (!gGrid) { + TGrid::Connect("alien://"); + if (!gGrid) { + LOG(fatal) << "AliEn connection failed, check token."; + exit(1); + } + } + for (size_t i = 0; i < models.size(); ++i) + { + if (isAlien[i] && !TFile::Cp(models[i].c_str(), local_names[i].c_str())) + { + LOG(fatal) << "Error: Model file " << models[i] << " does not exist!"; + exit(1); + } + } + } + if (std::any_of(isCCDB.begin(), isCCDB.end(), [](bool v) { return v; })) + { + o2::ccdb::CcdbApi ccdb_api; + ccdb_api.init("http://alice-ccdb.cern.ch"); + for (size_t i = 0; i < models.size(); ++i) + { + if (isCCDB[i]) + { + auto model_path = models[i].substr(7); // Remove "ccdb://" + // Treat filename if provided in the CCDB path + auto extension = model_path.find(".onnx"); + if (extension != std::string::npos) + { + auto last_slash = model_path.find_last_of('/'); + model_path = model_path.substr(0, last_slash); + } + std::map filter; + if(!ccdb_api.retrieveBlob(model_path, "./" , filter, o2::ccdb::getCurrentTimestamp(), false, local_names[i].c_str())) + { + LOG(fatal) << "Error: issues in retrieving " << model_path << " from CCDB!"; + exit(1); + } + } + } + } + model_pairs = isAlien[0] || isCCDB[0] ? local_names[0] : model_pairs; + model_compton = isAlien[1] || isCCDB[1] ? local_names[1] : model_compton; + auto generator = new o2::eventgen::GenTPCLoopers_debug(model_pairs, model_compton, poisson, gauss, scaler_pair, scaler_compton); + generator->SetNLoopers(nloopers_pairs, nloopers_compton); + generator->SetMultiplier(mult); + return generator; +} + +// Generator with flat gas loopers. Number of loopers starts from a reference value and changes +// based on the BC time intervals in each event. +FairGenerator * +Generator_TPCLoopersFlat(std::string model_pairs = "tpcloopmodel.onnx", std::string model_compton = "tpcloopmodelcompton.onnx", + std::string scaler_pair = "scaler_pair.json", std::string scaler_compton = "scaler_compton.json", + bool flat_gas = true, const int loops_num = 500, float fraction_pairs = 0.08, const int nloopers_orbit = -1) +{ + // Expand all environment paths + model_pairs = gSystem->ExpandPathName(model_pairs.c_str()); + model_compton = gSystem->ExpandPathName(model_compton.c_str()); + scaler_pair = gSystem->ExpandPathName(scaler_pair.c_str()); + scaler_compton = gSystem->ExpandPathName(scaler_compton.c_str()); + const std::array models = {model_pairs, model_compton}; + const std::array local_names = {"WGANpair.onnx", "WGANcompton.onnx"}; + const std::array isAlien = {models[0].starts_with("alien://"), models[1].starts_with("alien://")}; + const std::array isCCDB = {models[0].starts_with("ccdb://"), models[1].starts_with("ccdb://")}; + if (std::any_of(isAlien.begin(), isAlien.end(), [](bool v) + { return v; })) + { + if (!gGrid) + { + TGrid::Connect("alien://"); + if (!gGrid) + { + LOG(fatal) << "AliEn connection failed, check token."; + exit(1); + } + } + for (size_t i = 0; i < models.size(); ++i) + { + if (isAlien[i] && !TFile::Cp(models[i].c_str(), local_names[i].c_str())) + { + LOG(fatal) << "Error: Model file " << models[i] << " does not exist!"; + exit(1); + } + } + } + if (std::any_of(isCCDB.begin(), isCCDB.end(), [](bool v) + { return v; })) + { + o2::ccdb::CcdbApi ccdb_api; + ccdb_api.init("http://alice-ccdb.cern.ch"); + for (size_t i = 0; i < models.size(); ++i) + { + if (isCCDB[i]) + { + auto model_path = models[i].substr(7); // Remove "ccdb://" + // Treat filename if provided in the CCDB path + auto extension = model_path.find(".onnx"); + if (extension != std::string::npos) + { + auto last_slash = model_path.find_last_of('/'); + model_path = model_path.substr(0, last_slash); + } + std::map filter; + if (!ccdb_api.retrieveBlob(model_path, "./", filter, o2::ccdb::getCurrentTimestamp(), false, local_names[i].c_str())) + { + LOG(fatal) << "Error: issues in retrieving " << model_path << " from CCDB!"; + exit(1); + } + } + } + } + model_pairs = isAlien[0] || isCCDB[0] ? local_names[0] : model_pairs; + model_compton = isAlien[1] || isCCDB[1] ? local_names[1] : model_compton; + auto generator = new o2::eventgen::GenTPCLoopers_debug(model_pairs, model_compton, "", "", scaler_pair, scaler_compton); + generator->setFractionPairs(fraction_pairs); + generator->setFlatGas(flat_gas, loops_num, nloopers_orbit); + return generator; +} + +// Generator with flat gas loopers. Reference number of loopers is provided per orbit via external file +FairGenerator * +Generator_TPCLoopersOrbitRef(std::string model_pairs = "tpcloopmodel.onnx", std::string model_compton = "tpcloopmodelcompton.onnx", + std::string scaler_pair = "scaler_pair.json", std::string scaler_compton = "scaler_compton.json", + std::string nclxrate = "nclxrate.root", bool isPbPb = true, const int intrate = -1, const float adjust = 0.f) +{ + // Expand all environment paths + model_pairs = gSystem->ExpandPathName(model_pairs.c_str()); + model_compton = gSystem->ExpandPathName(model_compton.c_str()); + scaler_pair = gSystem->ExpandPathName(scaler_pair.c_str()); + scaler_compton = gSystem->ExpandPathName(scaler_compton.c_str()); + nclxrate = gSystem->ExpandPathName(nclxrate.c_str()); + const std::array models = {model_pairs, model_compton, nclxrate}; + const std::array local_names = {"WGANpair.onnx", "WGANcompton.onnx", "nclxrate.root"}; + const std::array isAlien = {models[0].starts_with("alien://"), models[1].starts_with("alien://"), nclxrate.starts_with("alien://")}; + const std::array isCCDB = {models[0].starts_with("ccdb://"), models[1].starts_with("ccdb://"), nclxrate.starts_with("ccdb://")}; + if (std::any_of(isAlien.begin(), isAlien.end(), [](bool v) + { return v; })) + { + if (!gGrid) + { + TGrid::Connect("alien://"); + if (!gGrid) + { + LOG(fatal) << "AliEn connection failed, check token."; + exit(1); + } + } + for (size_t i = 0; i < models.size(); ++i) + { + if (isAlien[i] && !TFile::Cp(models[i].c_str(), local_names[i].c_str())) + { + LOG(fatal) << "Error: Model file " << models[i] << " does not exist!"; + exit(1); + } + } + } + if (std::any_of(isCCDB.begin(), isCCDB.end(), [](bool v) + { return v; })) + { + o2::ccdb::CcdbApi ccdb_api; + ccdb_api.init("http://alice-ccdb.cern.ch"); + for (size_t i = 0; i < models.size(); ++i) + { + if (isCCDB[i]) + { + auto model_path = models[i].substr(7); // Remove "ccdb://" + // Treat filename if provided in the CCDB path + auto extension = model_path.find(".onnx"); + if (extension != std::string::npos) + { + auto last_slash = model_path.find_last_of('/'); + model_path = model_path.substr(0, last_slash); + } + std::map filter; + if (!ccdb_api.retrieveBlob(model_path, "./", filter, o2::ccdb::getCurrentTimestamp(), false, local_names[i].c_str())) + { + LOG(fatal) << "Error: issues in retrieving " << model_path << " from CCDB!"; + exit(1); + } + } + } + } + model_pairs = isAlien[0] || isCCDB[0] ? local_names[0] : model_pairs; + model_compton = isAlien[1] || isCCDB[1] ? local_names[1] : model_compton; + nclxrate = isAlien[2] || isCCDB[2] ? local_names[2] : nclxrate; + auto generator = new o2::eventgen::GenTPCLoopers_debug(model_pairs, model_compton, "", "", scaler_pair, scaler_compton); + generator->SetRate(nclxrate, isPbPb, intrate); + // Adjust can be negative (-1 maximum) or positive to decrease or increase the number of loopers per orbit + generator->SetAdjust(adjust); + return generator; +} \ No newline at end of file diff --git a/MC/config/common/external/generator/perfConf.json b/MC/config/common/external/generator/perfConf.json new file mode 100644 index 000000000..c3bdfae0b --- /dev/null +++ b/MC/config/common/external/generator/perfConf.json @@ -0,0 +1,23 @@ +{ + "generators": [ + { + "cocktail": [ + { + "name": "pythia8pp", + "config": "" + }, + { + "name": "external", + "config": { + "fileName": "${O2DPG_MC_CONFIG_ROOT}/MC/config/common/external/generator/performanceGenerator.C", + "funcName": "Generator_Performance()", + "iniFile": "" + } + } + ] + } + ], + "fractions": [ + 1 + ] +} diff --git a/MC/config/common/external/generator/performanceGenerator.C b/MC/config/common/external/generator/performanceGenerator.C new file mode 100644 index 000000000..d592d6f25 --- /dev/null +++ b/MC/config/common/external/generator/performanceGenerator.C @@ -0,0 +1,397 @@ +// External generator requested in https://its.cern.ch/jira/browse/O2-6235 +// for multidimensional performance studies +// Example usage: +// o2-sim -j 8 -o test -n 100 --seed 612 -g hybrid --configKeyValues "GeneratorHybrid.configFile=${O2DPG_MC_CONFIG_ROOT}/MC/config/common/external/generator/perfConf.json" +namespace o2 +{ + namespace eventgen + { + + class GenPerf : public Generator + { + public: + GenPerf(float fraction = 0.03f, unsigned short int nsig = 100, unsigned short int tag = 1) + { + if (fraction == -1) { + LOG(info) << nsig << " Signal particles will be generated in each event"; + mNSig = nsig; + mFraction = -1.f; + } else if (fraction >= 0) { + LOG(info) << "Fraction based signal generation is enabled"; + LOG(info) << fraction << "*nUE tracks per event will be generated"; + mFraction = fraction; + } else { + LOG(fatal) << "Wrong fraction selected. Accepted values are:"; + LOG(fatal) << "\t -1 => fixed number of tracks per event"; + LOG(fatal) << ">=0 => fraction based signal generation over the number of UE tracks per event"; + exit(1); + } + initGenMap(); + if (genMap.find(tag) == genMap.end()) { + LOG(fatal) << "Wrong tag selected. Accepted values are:"; + for (const auto& [key, _] : genMap) { + LOG(fatal) << "\t" << key; + } + exit(1); + } else { + mTag = tag; + LOG(info) << "Generator with tag " << mTag << " is selected"; + } + LOG(info) << "Z0 decays are handled with Pythia8"; + mPythia = std::make_unique(); + // Turn off all event generation - we only want to decay our Z0 + mPythia->readString("ProcessLevel:all = off"); + // Disable standard event checks since we're manually building the event + mPythia->readString("Check:event = off"); + mPythia->init(); // Initialize + Generator::setTimeUnit(1.0); + Generator::setPositionUnit(1.0); + } + + Bool_t generateEvent() override + { + return kTRUE; + } + + Bool_t importParticles() override + { + mNUE = 0; + if ( mFraction != -1) { + // This line assumes that the current generator is run in a cocktail with another generator + // which is run before the current one in a sequential way + if (!mGenList) { + auto &hybridInstance = GeneratorHybrid::Instance(); + mGenList = &hybridInstance.getGenerators(); + } + if (!mGenList->empty()) { + mNUE = mGenList->front()->getParticles().size(); + LOG(debug) << "Number of tracks from UE is " << mNUE; + } + } + unsigned short nSig = (mFraction == -1) ? mNSig : std::lround(mFraction * mNUE); + LOG(debug) << "Generating additional " << nSig << " particles"; + for (int k = 0; k < nSig; k++){ + auto part = genMap[mTag](); + if(part.GetPdgCode() == 23) { + auto daughters = decayZ0(part); + for (auto &dau : daughters) + { + mParticles.push_back(dau); + } + } else { + mParticles.push_back(part); + } + } + return kTRUE; + } + + private: + float mFraction = 0.03f; // Fraction based generation + unsigned short int mNSig = 0; // Number of particles to generate + unsigned int mNUE = 0; // Number of tracks in the Underlying event + unsigned short int mTag = 1; // Tag to select the generation function + std::unique_ptr mPythia; // Pythia8 instance for particle decays not present in the physics list of Geant4 (like Z0) + const std::vector>* mGenList = nullptr; // Cached generators list + std::map> genMap; + UInt_t mGenID = 42; + + // This is performance test generator with uniform weighting for PDG + TParticle generateParticle0() + { + // 1. Get the singleton instances + TDatabasePDG *pdg = TDatabasePDG::Instance(); + // 2. Define the list of PDG codes + const int ncodes = 13; + const int pdgCodes[ncodes] = { + 310, // K0_s + 421, // D0 + 3122, // Lambda + -3122, // Anti-Lambda + 443, // J/psi + 13, // mu- + 22, // gamma + 23, // Z0 + 1, 2, 3, 4, 5 // Quarks: d, u, s, c, b (t-quark is 6, often excluded for kinematics) + }; + // 3. Randomly select and validate a PDG code + // TMath::Nint(gRandom->Rndm() * ncodes) selects an index from 0 to ncodes-1 safely. + int index = TMath::Nint(gRandom->Rndm() * (ncodes - 1)); + int pdgCode = pdgCodes[index]; + // Check if the particle exists and switch to antiparticle if needed + if (pdg->GetParticle(pdgCode) == nullptr) + { + if (pdg->GetParticle(-pdgCode) != nullptr) + { + pdgCode *= -1; // Use the negative code (antiparticle) + } + else + { + LOG(error) << "Error: PDG code " << pdgCode << " not found in TDatabasePDG. Using Muon (13)."; + pdgCode = 13; + } + } + // 4. Generate Kinematics (p_T, phi, eta) + float pt = 1 / (gRandom->Rndm()); // flat 1/pt distribution + float phi = gRandom->Rndm() * 2.0f * TMath::Pi(); + float eta = 3.0f * (gRandom->Rndm() - 0.5f); // eta from -1.5 to 1.5 + // Initial position (origin) + float xyz[3] = {0.0f, 0.0f, 0.0f}; + // if cosmic, you might want to randomize the vertex position + if (pdgCode == 13 || pdgCode == -13) + { + xyz[0] = (gRandom->Rndm() - 0.5) * 300.0f; // x from -100 to 100 cm + xyz[1] = (gRandom->Rndm() - 0.5) * 300.0f; // y from -100 to 100 cm + xyz[2] = 400; + pt = 1 / (gRandom->Rndm() + 0.01); + eta = gRandom->Gaus() * 0.2; + } + // + // Convert spherical coordinates (pt, phi, eta) to Cartesian (px, py, pz) + float pz = pt * TMath::SinH(eta); + float px = pt * TMath::Cos(phi); + float py = pt * TMath::Sin(phi); + // 5. Calculate Energy (E) from Mass (M) + TParticlePDG *particleInfo = pdg->GetParticle(pdgCode); + double mass = particleInfo ? particleInfo->Mass() : 0.1056; // Default to muon mass if lookup fails + double energy = TMath::Sqrt(px * px + py * py + pz * pz + mass * mass); + + // 6. Create and return the TParticle object by value + // TParticle(pdgCode, trackIndex, Mother, Daughter1, Daughter2, Px, Py, Pz, E, Vx, Vy, Vz, Time) + int status = -1; // Status code, -1 for undefined + // Set your custom performance generator ID (e.g., ID 42) + TParticle generatedParticle(pdgCode, status, -1, -1, -1, -1, px, py, pz, energy, xyz[0], xyz[1], xyz[2], 0.0); + generatedParticle.SetStatusCode(o2::mcgenstatus::MCGenStatusEncoding(generatedParticle.GetStatusCode(), 0).fullEncoding); + generatedParticle.SetUniqueID(mGenID); + if (pdgCode == 23) { + generatedParticle.SetBit(ParticleStatus::kToBeDone, false); // Force Z0 to be decayed by the transport + } else { + generatedParticle.SetBit(ParticleStatus::kToBeDone, // + o2::mcgenstatus::getHepMCStatusCode(generatedParticle.GetStatusCode()) == 1); + } + return generatedParticle; + } + + // Particle configuration for ALICE O2 performance testing + struct ParticleSpec + { + int pdgCode; + float fraction; // Relative probability for probe statistics + float pTScale; // Scales pt + }; + + // Optimized for rare probes (J/psi, D0, jets) with flat distributions + const std::vector g_particle_specs = { + // PDG | Fraction | pTScale + {22, 1.0f, 1.0f}, // Photon: High yield for PID/calo + {13, 1.f, 1.0f}, // Muon: Cosmic override applied + {-13, 1.f, 1.0f}, // Anti-muon + {23, 0.1f, 10.0f}, // Z0: Rare, + {310, 1.f, 1.0f}, // K0_s: Common hadron + {421, 0.2f, 1.5f}, // D0 + {443, 0.1f, 5.0f}, // J/psi: Boosted for candle + {3122, 0.5f, 1.0f}, // Lambda + {-3122, 0.5f, 1.0f}, // Anti-Lambda + {211, 1.0f, 1.0f}, // Pi+ + {-211, 1.0f, 1.0f}, // Pi-: + // + {21, 0.1f, 3.0f}, // Gluon: Jet proxy (status=11) + {1, 0.1f, 3.0f}, // d quark: Jet proxy + {-1, 0.1f, 3.0f}, // anti-d + {2, 0.1f, 3.0f}, // u quark: Jet proxy + {-2, 0.1f, 3.0f}, // anti-u + {3, 0.1f, 5.0f}, // s quark: Strange + {-3, 0.1f, 5.0f}, // anti-s + {4, 0.1f, 5.0f}, // c quark: Heavy flavor + {-4, 0.1f, 5.0f}, // anti-c + {5, 0.1f, 8.0f}, // b quark: Very hard + {-5, 0.1f, 8.0f} // anti-b + }; + + // pT bounds: Max pT ~5 TeV (ALICE Pb-Pb energy) + const float kMaxInvPt = 2.f; // Min pT = 0.5 GeV + const float kMinInvPt = 2e-4f; // Max pT = 5000 GeV (unscaled) + + // Check if particle is a parton (quark/gluon, status=11) + bool isParton(int& pdgCode) + { + int absCode = TMath::Abs(pdgCode); + return (absCode >= 1 && absCode <= 5) || absCode == 21; + } + + // Generator for flat distributions in pT, eta for calibration + TParticle generateParticle1() + { + TDatabasePDG *pdg = TDatabasePDG::Instance(); + // 1. Weighted Random Selection + static float totalWeight = 0.0f; + if (totalWeight == 0.0f) + { + totalWeight = std::accumulate(g_particle_specs.begin(), g_particle_specs.end(), 0.0f, + [](float sum, const ParticleSpec &spec) + { return sum + spec.fraction; }); + } + float randVal = gRandom->Rndm() * totalWeight; + float cumulativeWeight = 0.0f; + const ParticleSpec *selectedSpec = nullptr; + for (const auto &spec : g_particle_specs) + { + cumulativeWeight += spec.fraction; + if (randVal <= cumulativeWeight) + { + selectedSpec = &spec; + break; + } + } + if (!selectedSpec) + selectedSpec = &g_particle_specs.back(); + int pdgCode = selectedSpec->pdgCode; + float pTScale = selectedSpec->pTScale; + // 2. PDG Validation + if (!pdg->GetParticle(pdgCode)) + { + if (pdg->GetParticle(-pdgCode)) + pdgCode *= -1; + else + { + LOG(error) << "Error: PDG " << pdgCode << " not found. Using muon (13).\n"; + pdgCode = 13; + pTScale = 1.0f; + } + } + // 3. Status: 11 for partons (jets), 1 for final-state + int status = isParton(pdgCode) ? 11 : 1; + // 4. Kinematics (flat 1/pT, max ~5000 GeV / pTScale) + float inv_pt = gRandom->Rndm() * (kMaxInvPt - kMinInvPt) + kMinInvPt; + float pt = 1.0f / inv_pt; + float phi = gRandom->Rndm() * 2.0f * TMath::Pi(); + float eta = gRandom->Rndm() * 3.0f - 1.5f; // ALICE TPC: -1.5 to 1.5 + // Vertex: Delta (embedding handles smearing) + float xyz[3] = {0.0f, 0.0f, 0.0f}; + // 5. Cosmic Muon Override + if (TMath::Abs(pdgCode) == 13) + { + xyz[0] = (gRandom->Rndm() - 0.5f) * 300.0f; + xyz[1] = (gRandom->Rndm() - 0.5f) * 300.0f; + xyz[2] = 400.0f; + inv_pt = (gRandom->Rndm() + 0.01f) / pTScale; // Apply pTScale + pt = 1.0f / inv_pt; + eta = TMath::Max(-4.0, TMath::Min(4.0, gRandom->Gaus(0.0, 0.2))); + status = 1; + } + // 6. Momentum and Energy + float pz = pt * TMath::SinH(eta); + float px = pt * TMath::Cos(phi); + float py = pt * TMath::Sin(phi); + TParticlePDG *particleInfo = pdg->GetParticle(pdgCode); + double mass = particleInfo ? particleInfo->Mass() : 0.1056; + double energy = TMath::Sqrt(px * px + py * py + pz * pz + mass * mass); + // 7. TParticle Creation (quarks/gluons need fragmentation in O2) + TParticle generatedParticle(pdgCode, status, -1, -1, -1, -1, px, py, pz, energy, xyz[0], xyz[1], xyz[2], 0.0); + generatedParticle.SetStatusCode(o2::mcgenstatus::MCGenStatusEncoding(generatedParticle.GetStatusCode(), 0).fullEncoding); + generatedParticle.SetUniqueID(mGenID); + if (pdgCode == 23) { + generatedParticle.SetBit(ParticleStatus::kToBeDone, false); + // Z0 will follow another decay procedure + } else { + generatedParticle.SetBit(ParticleStatus::kToBeDone, // + o2::mcgenstatus::getHepMCStatusCode(generatedParticle.GetStatusCode()) == 1); + } + return generatedParticle; + } + + void initGenMap() + { + genMap[0] = [this]() + { return generateParticle0(); }; + genMap[1] = [this]() + { return generateParticle1(); }; + } + + std::vector decayZ0(TParticle &z0) + { + std::vector subparts; + auto &event = mPythia->event; + // Reset event record for new decay + event.reset(); + // Add the Z0 particle to the event record + // Arguments: id, status, mother1, mother2, daughter1, daughter2, + // col, acol, px, py, pz, e, m, scale, pol + // Status code: 91 = incoming particles (needed for proper decay handling) + int iZ0 = event.append(23, 91, 0, 0, 0, 0, 0, 0, + z0.Px(), z0.Py(), z0.Pz(), z0.Energy(), z0.GetMass()); + // Set production vertex + event[iZ0].vProd(z0.Vx(), z0.Vy(), z0.Vz(), 0.0); + // Forcing decay by calling hadron level function + if (!mPythia->forceHadronLevel()) + { + cout << "Warning: Z0 decay failed!" << endl; + } + for (int j = 0; j < event.size(); ++j) + { + const Pythia8::Particle &p = event[j]; + if (p.id() == 23) // PDG code for Z0 + { + // Push Z0 itself + subparts.push_back(TParticle(p.id(), p.status(), + -1, -1, -1, -1, + p.px(), p.py(), + p.pz(), p.e(), + z0.Vx(), z0.Vy(), z0.Vz(), 0.0)); + subparts.back().SetStatusCode(o2::mcgenstatus::MCGenStatusEncoding(p.status(), 0).fullEncoding); + subparts.back().SetUniqueID(mGenID); + subparts.back().SetBit(ParticleStatus::kToBeDone, false); + // Navigate through intermediate Z0s to find final decay products + int iZ0 = j; + while (event[iZ0].daughter1() != 0 && + event[event[iZ0].daughter1()].id() == 23) + { + iZ0 = event[iZ0].daughter1(); + } + // Recursively collect all final-state descendants + std::function collectAllDescendants = [&](int idx) + { + const Pythia8::Particle &particle = event[idx]; + subparts.push_back(TParticle(particle.id(), particle.status(), + -1, -1, -1, -1, + particle.px(), particle.py(), + particle.pz(), particle.e(), + p.xProd(), p.yProd(), p.zProd(), p.tProd())); + subparts.back().SetStatusCode(o2::mcgenstatus::MCGenStatusEncoding(particle.status(), 0).fullEncoding); + subparts.back().SetUniqueID(mGenID + 1); + subparts.back().SetBit(ParticleStatus::kToBeDone, + o2::mcgenstatus::getHepMCStatusCode(subparts.back().GetStatusCode()) == 1); + // Not final-state, recurse through daughters + if (!particle.isFinal()) + { + int d1 = particle.daughter1(); + int d2 = particle.daughter2(); + if (d1 > 0) + { + for (int k = d1; k <= d2; ++k) + { + collectAllDescendants(k); + } + } + } + }; + // Start collecting from the final Z0 + collectAllDescendants(iZ0); + break; // Found and processed the Z0 + } + } + return subparts; + } + }; + + } // namespace eventgen +} // namespace o2 + +// Performance test generator +// fraction == -1 enables the fixed number of signal particles per event (nsig) +// tag selects the generator type to be used +FairGenerator * +Generator_Performance(const float fraction = 0.03f, const unsigned short int nsig = 100, unsigned short int tag = 1) +{ + auto generator = new o2::eventgen::GenPerf(fraction, nsig, tag); + return generator; +} \ No newline at end of file diff --git a/MC/config/common/ini/GeneratorLoopersFlatFile.ini b/MC/config/common/ini/GeneratorLoopersFlatFile.ini new file mode 100644 index 000000000..4143989ab --- /dev/null +++ b/MC/config/common/ini/GeneratorLoopersFlatFile.ini @@ -0,0 +1,8 @@ +# TPC loopers injector using fit to calculate reference loopers number per orbit. File with fit function is pulled from the CCDB. +# Three additional parameters are available in the function: (isPbPb = true, intRate = -1, adjust = 0.) +# isPbPb and intRate must be set in case the collision system is not PbPb and the IR is not taken from collisioncontext, while adjust can be used to decrease/increase +# the number of loopers per orbit obtained from the reference (e.g. -0.1 reduces the loopers by 10%) +#---> GeneratorTPCloopers +[GeneratorExternal] +fileName = ${O2DPG_MC_CONFIG_ROOT}/MC/config/common/external/generator/TPCLoopers.C +funcName = Generator_TPCLoopersOrbitRef("ccdb://Users/m/mgiacalo/WGAN_ExtGenPair", "ccdb://Users/m/mgiacalo/WGAN_ExtGenCompton", "${O2DPG_MC_CONFIG_ROOT}/MC/config/common/TPCloopers/ScalerPairParams.json", "${O2DPG_MC_CONFIG_ROOT}/MC/config/common/TPCloopers/ScalerComptonParams.json","ccdb://Users/m/mgiacalo/ClustersTrackRatio") diff --git a/MC/config/common/ini/GeneratorLoopersFlatGas.ini b/MC/config/common/ini/GeneratorLoopersFlatGas.ini new file mode 100644 index 000000000..68c7648ae --- /dev/null +++ b/MC/config/common/ini/GeneratorLoopersFlatGas.ini @@ -0,0 +1,5 @@ +# TPC loopers injector +#---> GeneratorTPCloopers +[GeneratorExternal] +fileName = ${O2DPG_MC_CONFIG_ROOT}/MC/config/common/external/generator/TPCLoopers.C +funcName = Generator_TPCLoopersFlat("ccdb://Users/m/mgiacalo/WGAN_ExtGenPair", "ccdb://Users/m/mgiacalo/WGAN_ExtGenCompton", "${O2DPG_MC_CONFIG_ROOT}/MC/config/common/TPCloopers/ScalerPairParams.json", "${O2DPG_MC_CONFIG_ROOT}/MC/config/common/TPCloopers/ScalerComptonParams.json") \ No newline at end of file diff --git a/MC/config/common/ini/GeneratorPerformance.ini b/MC/config/common/ini/GeneratorPerformance.ini new file mode 100644 index 000000000..c4a4efb03 --- /dev/null +++ b/MC/config/common/ini/GeneratorPerformance.ini @@ -0,0 +1,4 @@ +# Performance generator test using hybrid configuration with Pythia8 +# underlying event generator +[GeneratorHybrid] +configFile = ${O2DPG_MC_CONFIG_ROOT}/MC/config/common/external/generator/perfConf.json diff --git a/MC/config/common/ini/GeneratorPerformanceFix.ini b/MC/config/common/ini/GeneratorPerformanceFix.ini new file mode 100644 index 000000000..7c0ce5f0d --- /dev/null +++ b/MC/config/common/ini/GeneratorPerformanceFix.ini @@ -0,0 +1,8 @@ +# Test performance generator for multidimensional studies using fixed number of signal particles per event +# Parameters are in order: fraction of signal particles, fixed number of signal particles per event, tag to select the generator type +# Setting fraction = -1 enables the fixed number of signal particles per event (nsig). +# An hybrid configuration JSON file is provided in ${O2DPG_MC_CONFIG_ROOT}/MC/config/common/external/generator/perfConf.json to run the generator +# in fraction based mode +[GeneratorExternal] +fileName = ${O2DPG_MC_CONFIG_ROOT}/MC/config/common/external/generator/performanceGenerator.C +funcName = Generator_Performance(-1, 100, 1) diff --git a/MC/config/common/ini/GeneratorTPCloopers.ini b/MC/config/common/ini/GeneratorTPCloopers.ini new file mode 100644 index 000000000..276a086c8 --- /dev/null +++ b/MC/config/common/ini/GeneratorTPCloopers.ini @@ -0,0 +1,4 @@ +# Example of tpc loopers generator with a poisson distribution of pairs and gaussian distribution of compton electrons +[GeneratorExternal] +fileName = ${O2DPG_MC_CONFIG_ROOT}/MC/config/common/external/generator/TPCLoopers.C +funcName = Generator_TPCLoopers("ccdb://Users/m/mgiacalo/WGAN_ExtGenPair", "ccdb://Users/m/mgiacalo/WGAN_ExtGenCompton", "${O2DPG_MC_CONFIG_ROOT}/MC/config/common/TPCloopers/poisson_params.csv", "${O2DPG_MC_CONFIG_ROOT}/MC/config/common/TPCloopers/gaussian_params.csv", "${O2DPG_MC_CONFIG_ROOT}/MC/config/common/TPCloopers/ScalerPairParams.json", "${O2DPG_MC_CONFIG_ROOT}/MC/config/common/TPCloopers/ScalerComptonParams.json") \ No newline at end of file diff --git a/MC/config/common/ini/GeneratorTPCloopers_fixNPairs.ini b/MC/config/common/ini/GeneratorTPCloopers_fixNPairs.ini new file mode 100644 index 000000000..4223ecf40 --- /dev/null +++ b/MC/config/common/ini/GeneratorTPCloopers_fixNPairs.ini @@ -0,0 +1,6 @@ +# Example of tpc loopers generator with a fixed number of pairs and compton electrons (10) +# Multiplier values are ignored in this case, but kept to 1 for consistency +#---> GeneratorTPCloopers +[GeneratorExternal] +fileName = ${O2DPG_MC_CONFIG_ROOT}/MC/config/common/external/generator/TPCLoopers.C +funcName = Generator_TPCLoopers("ccdb://Users/m/mgiacalo/WGAN_ExtGenPair", "ccdb://Users/m/mgiacalo/WGAN_ExtGenCompton", "", "", "${O2DPG_MC_CONFIG_ROOT}/MC/config/common/TPCloopers/ScalerPairParams.json", "${O2DPG_MC_CONFIG_ROOT}/MC/config/common/TPCloopers/ScalerComptonParams.json",{1.,1.}, 10,10) diff --git a/MC/config/common/ini/pythia8_NeNe_536.ini b/MC/config/common/ini/pythia8_NeNe_536.ini new file mode 100644 index 000000000..c279dd980 --- /dev/null +++ b/MC/config/common/ini/pythia8_NeNe_536.ini @@ -0,0 +1,9 @@ +[Diamond] +width[2]=6.0 + +[GeneratorExternal] +fileName=${O2DPG_MC_CONFIG_ROOT}/MC/config/ALICE3/pythia8/generator_pythia8_ALICE3.C +funcName=generator_pythia8_ALICE3() + +[GeneratorPythia8] +config=${O2DPG_MC_CONFIG_ROOT}/MC/config/common/pythia8/generator/pythia8_NeNe_536.cfg diff --git a/MC/config/common/ini/pythia8_OO_536.ini b/MC/config/common/ini/pythia8_OO_536.ini new file mode 100644 index 000000000..ade15add1 --- /dev/null +++ b/MC/config/common/ini/pythia8_OO_536.ini @@ -0,0 +1,9 @@ +[Diamond] +width[2]=6.0 + +[GeneratorExternal] +fileName=${O2DPG_MC_CONFIG_ROOT}/MC/config/ALICE3/pythia8/generator_pythia8_ALICE3.C +funcName=generator_pythia8_ALICE3() + +[GeneratorPythia8] +config=${O2DPG_MC_CONFIG_ROOT}/MC/config/common/pythia8/generator/pythia8_OO_536.cfg diff --git a/MC/config/common/ini/pythia8_OO_rescattering_536.ini b/MC/config/common/ini/pythia8_OO_rescattering_536.ini new file mode 100644 index 000000000..a0f2fc2e5 --- /dev/null +++ b/MC/config/common/ini/pythia8_OO_rescattering_536.ini @@ -0,0 +1,9 @@ +[Diamond] +width[2]=6.0 + +[GeneratorExternal] +fileName=${O2DPG_MC_CONFIG_ROOT}/MC/config/ALICE3/pythia8/generator_pythia8_ALICE3.C +funcName=generator_pythia8_ALICE3() + +[GeneratorPythia8] +config=${O2DPG_MC_CONFIG_ROOT}/MC/config/common/pythia8/generator/pythia8_OO_rescattering_536.cfg diff --git a/MC/config/common/ini/pythia8_PbPb_rescattering_536.ini b/MC/config/common/ini/pythia8_PbPb_rescattering_536.ini new file mode 100644 index 000000000..1ed1278ef --- /dev/null +++ b/MC/config/common/ini/pythia8_PbPb_rescattering_536.ini @@ -0,0 +1,10 @@ +#NEV_TEST> 1 +[Diamond] +width[2]=6.0 + +[GeneratorExternal] +fileName=${O2DPG_MC_CONFIG_ROOT}/MC/config/ALICE3/pythia8/generator_pythia8_ALICE3.C +funcName=generator_pythia8_ALICE3() + +[GeneratorPythia8] +config=${O2DPG_MC_CONFIG_ROOT}/MC/config/common/pythia8/generator/pythia8_PbPb_rescattering_536.cfg diff --git a/MC/config/common/ini/pythia8_inel_difftuned.ini b/MC/config/common/ini/pythia8_inel_difftuned.ini new file mode 100644 index 000000000..65ff9b972 --- /dev/null +++ b/MC/config/common/ini/pythia8_inel_difftuned.ini @@ -0,0 +1,2 @@ +[GeneratorPythia8] +config=${O2DPG_MC_CONFIG_ROOT}/MC/config/common/pythia8/generator/pythia8_inel_difftuned.cfg diff --git a/MC/config/common/ini/pythia8_pO_961.ini b/MC/config/common/ini/pythia8_pO_961.ini new file mode 100644 index 000000000..db8ccff48 --- /dev/null +++ b/MC/config/common/ini/pythia8_pO_961.ini @@ -0,0 +1,9 @@ +[Diamond] +width[2]=6.0 + +[GeneratorExternal] +fileName=${O2DPG_MC_CONFIG_ROOT}/MC/config/ALICE3/pythia8/generator_pythia8_ALICE3.C +funcName=generator_pythia8_ALICE3() + +[GeneratorPythia8] +config=${O2DPG_MC_CONFIG_ROOT}/MC/config/common/pythia8/generator/pythia8_pO_961.cfg diff --git a/MC/config/common/ini/tests/GeneratorPerformance.C b/MC/config/common/ini/tests/GeneratorPerformance.C new file mode 100644 index 000000000..c34ca7c5d --- /dev/null +++ b/MC/config/common/ini/tests/GeneratorPerformance.C @@ -0,0 +1,55 @@ +int Hybrid() +{ + std::string path{"o2sim_Kine.root"}; + TFile file(path.c_str(), "READ"); + if (file.IsZombie()) + { + std::cerr << "Cannot open ROOT file " << path << "\n"; + return 1; + } + auto tree = (TTree *)file.Get("o2sim"); + if (!tree) + { + std::cerr << "Cannot find tree 'o2sim' in file " << path << "\n"; + return 1; + } + // Get the MCTrack branch + std::vector *tracks{}; + tree->SetBranchAddress("MCTrack", &tracks); + // Check if processes with ID 42 are available + const int processID = 42; // Performance test particle custom process ID + int nEvents = tree->GetEntries(); + short int count_perf = 0; + bool flag = false; + for (int i = 0; i < nEvents; i++) + { + tree->GetEntry(i); + int nTracks = tracks->size(); + count_perf = 0; + for (auto &track : *tracks) + { + const auto &process = track.getProcess(); + if (process == processID) + { + flag = true; + // No need to continue checking other tracks in the event + break; + } + } + if (flag == true) + { + count_perf++; + flag = false; + } + } + if (count_perf == 0) + { + std::cerr << "No performance test particles found in the events\n"; + return 1; + } else if (count_perf > nEvents) { + std::cerr << "More performance test flagged events than generated events\n"; + return 1; + } + file.Close(); + return 0; +} \ No newline at end of file diff --git a/MC/config/common/ini/tests/GeneratorPerformanceFix.C b/MC/config/common/ini/tests/GeneratorPerformanceFix.C new file mode 100644 index 000000000..ffda1fb6e --- /dev/null +++ b/MC/config/common/ini/tests/GeneratorPerformanceFix.C @@ -0,0 +1,43 @@ +int External() { + std::string path{"o2sim_Kine.root"}; + TFile file(path.c_str(), "READ"); + if (file.IsZombie()) { + std::cerr << "Cannot open ROOT file " << path << "\n"; + return 1; + } + auto tree = (TTree *)file.Get("o2sim"); + if (!tree) { + std::cerr << "Cannot find tree 'o2sim' in file " << path << "\n"; + return 1; + } + // Get the MCTrack branch + std::vector *tracks{}; + tree->SetBranchAddress("MCTrack", &tracks); + // Check if processes with ID 42 are available + // And are 100 per event + const int processID = 42; // Performance test particle custom process ID + int nEvents = tree->GetEntries(); + short int count_perf = 0; + unsigned short int expSig = 100; // set by default in the ini file + for (int i = 0; i < nEvents; i++) { + tree->GetEntry(i); + int nTracks = tracks->size(); + count_perf = 0; + for (auto &track : *tracks) + { + const auto& process = track.getProcess(); + if (process == 42) + { + count_perf++; + } + } + if (count_perf != expSig) + { + std::cerr << "Event " << i << ": Expected " << expSig << " performance test particles, found " << count_perf << "\n"; + return 1; + } + } + + file.Close(); + return 0; +} \ No newline at end of file diff --git a/MC/config/common/ini/tests/GeneratorTPCloopers.C b/MC/config/common/ini/tests/GeneratorTPCloopers.C new file mode 100644 index 000000000..7413fd839 --- /dev/null +++ b/MC/config/common/ini/tests/GeneratorTPCloopers.C @@ -0,0 +1,42 @@ +int External() { + std::string path{"o2sim_Kine.root"}; + TFile file(path.c_str(), "READ"); + if (file.IsZombie()) { + std::cerr << "Cannot open ROOT file " << path << "\n"; + return 1; + } + auto tree = (TTree *)file.Get("o2sim"); + if (!tree) { + std::cerr << "Cannot find tree 'o2sim' in file " << path << "\n"; + return 1; + } + // Get the MCTrack branch + std::vector *tracks{}; + tree->SetBranchAddress("MCTrack", &tracks); + // Check if only pairs are contained in the simulation + int nEvents = tree->GetEntries(); + int count_e = 0; + int count_p = 0; + for (int i = 0; i < nEvents; i++) { + tree->GetEntry(i); + for (auto &track : *tracks) + { + auto pdg = track.GetPdgCode(); + if (pdg == 11) { + count_e++; + } else if (pdg == -11) { + count_p++; + } else { + std::cerr << "Found unexpected PDG code: " << pdg << "\n"; + return 1; + } + } + } + if (count_e < count_p) { + std::cerr << "Less electrons than positrons: " << count_e << " vs " << count_p << "\n"; + return 1; + } + file.Close(); + + return 0; +} \ No newline at end of file diff --git a/MC/config/common/ini/tests/pythia8_NeNe_536.C b/MC/config/common/ini/tests/pythia8_NeNe_536.C new file mode 100644 index 000000000..1c28040e2 --- /dev/null +++ b/MC/config/common/ini/tests/pythia8_NeNe_536.C @@ -0,0 +1,24 @@ +int External() { + std::string path{"o2sim_Kine.root"}; + + TFile file(path.c_str(), "READ"); + if (file.IsZombie()) { + std::cerr << "Cannot open ROOT file " << path << "\n"; + return 1; + } + + auto tree = (TTree *)file.Get("o2sim"); + if (!tree) { + std::cerr << "Cannot find tree o2sim in file " << path << "\n"; + return 1; + } + std::vector *tracks{}; + tree->SetBranchAddress("MCTrack", &tracks); + + auto nEvents = tree->GetEntries(); + if (nEvents == 0) { + std::cerr << "No event of interest\n"; + return 1; + } + return 0; +} diff --git a/MC/config/common/ini/tests/pythia8_OO_536.C b/MC/config/common/ini/tests/pythia8_OO_536.C new file mode 100644 index 000000000..1c28040e2 --- /dev/null +++ b/MC/config/common/ini/tests/pythia8_OO_536.C @@ -0,0 +1,24 @@ +int External() { + std::string path{"o2sim_Kine.root"}; + + TFile file(path.c_str(), "READ"); + if (file.IsZombie()) { + std::cerr << "Cannot open ROOT file " << path << "\n"; + return 1; + } + + auto tree = (TTree *)file.Get("o2sim"); + if (!tree) { + std::cerr << "Cannot find tree o2sim in file " << path << "\n"; + return 1; + } + std::vector *tracks{}; + tree->SetBranchAddress("MCTrack", &tracks); + + auto nEvents = tree->GetEntries(); + if (nEvents == 0) { + std::cerr << "No event of interest\n"; + return 1; + } + return 0; +} diff --git a/MC/config/common/ini/tests/pythia8_OO_rescattering_536.C b/MC/config/common/ini/tests/pythia8_OO_rescattering_536.C new file mode 100644 index 000000000..1c28040e2 --- /dev/null +++ b/MC/config/common/ini/tests/pythia8_OO_rescattering_536.C @@ -0,0 +1,24 @@ +int External() { + std::string path{"o2sim_Kine.root"}; + + TFile file(path.c_str(), "READ"); + if (file.IsZombie()) { + std::cerr << "Cannot open ROOT file " << path << "\n"; + return 1; + } + + auto tree = (TTree *)file.Get("o2sim"); + if (!tree) { + std::cerr << "Cannot find tree o2sim in file " << path << "\n"; + return 1; + } + std::vector *tracks{}; + tree->SetBranchAddress("MCTrack", &tracks); + + auto nEvents = tree->GetEntries(); + if (nEvents == 0) { + std::cerr << "No event of interest\n"; + return 1; + } + return 0; +} diff --git a/MC/config/common/ini/tests/pythia8_PbPb_rescattering_536.C b/MC/config/common/ini/tests/pythia8_PbPb_rescattering_536.C new file mode 100644 index 000000000..1c28040e2 --- /dev/null +++ b/MC/config/common/ini/tests/pythia8_PbPb_rescattering_536.C @@ -0,0 +1,24 @@ +int External() { + std::string path{"o2sim_Kine.root"}; + + TFile file(path.c_str(), "READ"); + if (file.IsZombie()) { + std::cerr << "Cannot open ROOT file " << path << "\n"; + return 1; + } + + auto tree = (TTree *)file.Get("o2sim"); + if (!tree) { + std::cerr << "Cannot find tree o2sim in file " << path << "\n"; + return 1; + } + std::vector *tracks{}; + tree->SetBranchAddress("MCTrack", &tracks); + + auto nEvents = tree->GetEntries(); + if (nEvents == 0) { + std::cerr << "No event of interest\n"; + return 1; + } + return 0; +} diff --git a/MC/config/common/ini/tests/pythia8_inel_difftuned.C b/MC/config/common/ini/tests/pythia8_inel_difftuned.C new file mode 100644 index 000000000..7ee7ea397 --- /dev/null +++ b/MC/config/common/ini/tests/pythia8_inel_difftuned.C @@ -0,0 +1,24 @@ +int pythia8() { + std::string path{"o2sim_Kine.root"}; + + TFile file(path.c_str(), "READ"); + if (file.IsZombie()) { + std::cerr << "Cannot open ROOT file " << path << "\n"; + return 1; + } + + auto tree = (TTree *)file.Get("o2sim"); + if (!tree) { + std::cerr << "Cannot find tree o2sim in file " << path << "\n"; + return 1; + } + std::vector *tracks{}; + tree->SetBranchAddress("MCTrack", &tracks); + + auto nEvents = tree->GetEntries(); + if (nEvents == 0) { + std::cerr << "No event of interest\n"; + return 1; + } + return 0; +} diff --git a/MC/config/common/ini/tests/pythia8_pO_961.C b/MC/config/common/ini/tests/pythia8_pO_961.C new file mode 100644 index 000000000..1c28040e2 --- /dev/null +++ b/MC/config/common/ini/tests/pythia8_pO_961.C @@ -0,0 +1,24 @@ +int External() { + std::string path{"o2sim_Kine.root"}; + + TFile file(path.c_str(), "READ"); + if (file.IsZombie()) { + std::cerr << "Cannot open ROOT file " << path << "\n"; + return 1; + } + + auto tree = (TTree *)file.Get("o2sim"); + if (!tree) { + std::cerr << "Cannot find tree o2sim in file " << path << "\n"; + return 1; + } + std::vector *tracks{}; + tree->SetBranchAddress("MCTrack", &tracks); + + auto nEvents = tree->GetEntries(); + if (nEvents == 0) { + std::cerr << "No event of interest\n"; + return 1; + } + return 0; +} diff --git a/MC/config/common/pythia8/generator/pythia8_NeNe_536.cfg b/MC/config/common/pythia8/generator/pythia8_NeNe_536.cfg new file mode 100644 index 000000000..6f514e6d6 --- /dev/null +++ b/MC/config/common/pythia8/generator/pythia8_NeNe_536.cfg @@ -0,0 +1,14 @@ +### NeNe beams +Beams:idA = 1000100200 # Neon +Beams:idB = 1000100200 # Neon +Beams:eCM = 5360.0 ### energy + +Beams:frameType = 1 +ParticleDecays:limitTau0 = on +ParticleDecays:tau0Max = 10. ### match alice: 1cm/c = 10.0mm/c + +### To avoid refitting, add the following lines to your configuration file: +HeavyIon:SigFitNGen = 0 +HeavyIon:SigFitDefPar = 2.15,18.42,0.33 + +Random:setSeed = on diff --git a/MC/config/common/pythia8/generator/pythia8_OO_536.cfg b/MC/config/common/pythia8/generator/pythia8_OO_536.cfg new file mode 100644 index 000000000..d587387b9 --- /dev/null +++ b/MC/config/common/pythia8/generator/pythia8_OO_536.cfg @@ -0,0 +1,15 @@ +### OO beams +Beams:idA = 1000080160 +Beams:idB = 1000080160 +Beams:eCM = 5360.0 ### energy + +Beams:frameType = 1 +ParticleDecays:limitTau0 = on +ParticleDecays:tau0Max = 10. ### match alice: 1cm/c = 10.0mm/c + +### Save some CPU at init of jobs +### To avoid refitting, add the following lines to your configuration file: +HeavyIon:SigFitNGen = 0 +HeavyIon:SigFitDefPar = 2.15,18.42,0.33 + +Random:setSeed = on diff --git a/MC/config/common/pythia8/generator/pythia8_OO_rescattering_536.cfg b/MC/config/common/pythia8/generator/pythia8_OO_rescattering_536.cfg new file mode 100644 index 000000000..cd0a11e50 --- /dev/null +++ b/MC/config/common/pythia8/generator/pythia8_OO_rescattering_536.cfg @@ -0,0 +1,22 @@ +### OO beams +Beams:idA = 1000080160 +Beams:idB = 1000080160 +Beams:eCM = 5360.0 ### energy + +Beams:frameType = 1 +ParticleDecays:limitTau0 = on +ParticleDecays:tau0Max = 10. ### match alice: 1cm/c = 10.0mm/c + +### Save some CPU at init of jobs +### To avoid refitting, add the following lines to your configuration file: +HeavyIon:SigFitNGen = 0 +HeavyIon:SigFitDefPar = 2.15,18.42,0.33 + +### enable hadronic rescattering +HadronLevel:Rescatter = on # default = off +Fragmentation:setVertices = on # default = off +PartonVertex:setVertex = on # default = off +Rescattering:nearestNeighbours = off # default = on (but "require a larger retuning effort") +Rescattering:inelastic = on # default = on + +Random:setSeed = on diff --git a/MC/config/common/pythia8/generator/pythia8_PbPb_rescattering_536.cfg b/MC/config/common/pythia8/generator/pythia8_PbPb_rescattering_536.cfg new file mode 100644 index 000000000..d4158bdcf --- /dev/null +++ b/MC/config/common/pythia8/generator/pythia8_PbPb_rescattering_536.cfg @@ -0,0 +1,24 @@ +### OO beams +Beams:idA 1000822080 # Pb +Beams:idB 1000822080 # Pb +Beams:eCM = 5360.0 ### energy + +Beams:frameType = 1 +ParticleDecays:limitTau0 = on +ParticleDecays:tau0Max = 10. ### match alice: 1cm/c = 10.0mm/c + +### Initialize the Angantyr model to fit the total and semi-includive +### cross sections in Pythia within some tolerance. +HeavyIon:SigFitErr = 0.02,0.02,0.1,0.05,0.05,0.0,0.1,0.0 + +### These parameters are typicall suitable for sqrt(S_NN)=5TeV +HeavyIon:SigFitDefPar = 17.24,2.15,0.33,0.0,0.0,0.0,0.0,0.0 + +### enable hadronic rescattering +HadronLevel:Rescatter = on # default = off +Fragmentation:setVertices = on # default = off +PartonVertex:setVertex = on # default = off +Rescattering:nearestNeighbours = off # default = on (but "require a larger retuning effort") +Rescattering:inelastic = on # default = on + +Random:setSeed = on diff --git a/MC/config/common/pythia8/generator/pythia8_inel_536.cfg b/MC/config/common/pythia8/generator/pythia8_inel_536.cfg new file mode 100644 index 000000000..d1fb9b68a --- /dev/null +++ b/MC/config/common/pythia8/generator/pythia8_inel_536.cfg @@ -0,0 +1,11 @@ +### beams +Beams:idA 2212 # proton +Beams:idB 2212 # proton +Beams:eCM 5360.0 # GeV + +### processes +SoftQCD:inelastic on # all inelastic processes + +### decays +ParticleDecays:limitTau0 on +ParticleDecays:tau0Max 10. diff --git a/MC/config/common/pythia8/generator/pythia8_inel_difftuned.cfg b/MC/config/common/pythia8/generator/pythia8_inel_difftuned.cfg new file mode 100644 index 000000000..22dcfbb7e --- /dev/null +++ b/MC/config/common/pythia8/generator/pythia8_inel_difftuned.cfg @@ -0,0 +1,25 @@ +### beams +Beams:idA 2212 # proton +Beams:idB 2212 # proton +Beams:eCM 13600. # GeV + +### processes +SoftQCD:inelastic on # all inelastic processes + +### decays +ParticleDecays:limitTau0 on +ParticleDecays:tau0Max 10. + +### adjust diffraction +### note that PYTHIA calculates the ND sigma via a +### 'remaining from total' formula: no need to put +### that in by hand + +SigmaTotal:mode 0 +SigmaDiffractive:mode 0 +SigmaTotal:sigmaTot 78.6 +SigmaTotal:sigmaEl 0.0 +SigmaTotal:sigmaXB 10.625 +SigmaTotal:sigmaAX 10.625 +SigmaTotal:sigmaXX 9.78 +SigmaTotal:sigmaAXB 0.0 diff --git a/MC/config/common/pythia8/generator/pythia8_pO_961.cfg b/MC/config/common/pythia8/generator/pythia8_pO_961.cfg new file mode 100644 index 000000000..235300c1d --- /dev/null +++ b/MC/config/common/pythia8/generator/pythia8_pO_961.cfg @@ -0,0 +1,15 @@ +### OO beams +Beams:frameType 2 # back-to-back beams of different energies and particles +Beams:idA 2212 # proton +Beams:idB 1000080160 # Oxygen +Beams:eA 6800. # Energy of proton beam in GeV moving in the +z direction +Beams:eB 3400. # Energy in GeV per Oxygen nucleon (6.8 Z TeV) moving in the -z direction + +ParticleDecays:limitTau0 = on +ParticleDecays:tau0Max = 10. ### match alice: 1cm/c = 10.0mm/c + +### To avoid refitting, add the following lines to your configuration file: +HeavyIon:SigFitNGen = 0 +HeavyIon:SigFitDefPar = 2.17,17.56,0.30 + +Random:setSeed = on diff --git a/MC/config/common/pythia8/utils/mkpy8cfg.py b/MC/config/common/pythia8/utils/mkpy8cfg.py index 460af1e99..ccea745cb 100755 --- a/MC/config/common/pythia8/utils/mkpy8cfg.py +++ b/MC/config/common/pythia8/utils/mkpy8cfg.py @@ -102,6 +102,9 @@ def derive_process(process_in, beam_type_a, beam_type_b): if args.eCM > 0: fout.write('Beams:eCM = %f \n' % (args.eCM)) elif args.eA > 0 and args.eB > 0: + # Reference frame to be set to 2 if the two back-to-back beams have different energies + if args.eA != args.eB: + fout.write('Beams:frameType = 2 \n') fout.write('Beams:eA = %f \n' % (args.eA)) fout.write('Beams:eB = %f \n' % (args.eB)) else: @@ -136,7 +139,7 @@ def derive_process(process_in, beam_type_a, beam_type_b): fout.write('\n') ### heavy ion settings (valid for Pb-Pb 5520 only) -if args.process == 'heavy_ion': +if args.process == 'heavy_ion' and (args.idA == 1000822080 and args.idB == 1000822080 and args.eCM == 5520.): fout.write('### heavy-ion settings (valid for Pb-Pb 5520 only) \n') fout.write('HeavyIon:SigFitNGen = 0 \n') fout.write('HeavyIon:SigFitDefPar = 13.88,1.84,0.22,0.0,0.0,0.0,0.0,0.0 \n') diff --git a/MC/config/examples/epos4/epos.sh b/MC/config/examples/epos4/epos.sh index c416e03f7..13a30b0d0 100755 --- a/MC/config/examples/epos4/epos.sh +++ b/MC/config/examples/epos4/epos.sh @@ -5,7 +5,33 @@ # in order not to print useless information on stdout (a z-*optns*.mtr file will be created) optns="example" -seed=$RANDOM +seed=$(od -An -N2 -tu2 /dev/urandom | tr -d ' ') +EPOS4="" + +if [ -z "$EPO4VSN" ]; then + echo "Error: EPO4VSN environment variable is not set" + exit 1 +fi + +if [ "$EPO4VSN" = "4.0.0" ]; then + EPOS4="$EPOS4_ROOT/epos4/scripts/epos" + export LIBDIR=$EPOS4_ROOT/epos4/bin +else + EPOS4="$EPOS4_ROOT/bin/epos" +fi + +# Check if the environment variable EPO4 is set (mandatory with o2dpg-sim-tests on CI machines) +# If not, set all the EPOS4 related variables, most likely they are unset as well. +if [ -z "${EPO4}" ]; then + export OPT=./ + export HTO=./ + export CHK=./ + if [ "$EPO4VSN" = "4.0.0" ]; then + export EPO4=$EPOS4_ROOT/epos4/ + else + export EPO4=$EPOS4_ROOT/ + fi +fi while test $# -gt 0 ; do case $1 in @@ -18,24 +44,26 @@ done if [ ! -f $optns.optns ]; then echo "Error: Options file $optns.optns not found" - exit 1 + exit 2 fi -if [ $seed -eq 0 ]; then - echo "Seed can't be 0, random number will be used" - seed=$RANDOM +if grep -Fq "set ihq 1" $optns.optns; then + if [ -z "$EPO4HQVSN" ]; then + # Error: EPOS4HQ version not found + exit 3 + else + # Running with EPOS4HQ + if [ -z "${EPO4HQ}" ]; then + export EPO4HQ=$EPOS4HQ_ROOT/ + fi + EPOS4="$EPO4HQ/bin/eposhq" + fi fi -# Check if the environment variable EPO4 is set (mandatory with o2dpg-sim-tests on CI machines) -# If not, set all the EPOS4 related variables, most likely they are unset as well. -if [ -z "${EPO4}" ]; then - export EPO4=$EPOS4_ROOT/epos4/ - export LIBDIR=$EPOS4_ROOT/epos4/bin - export EPO4VSN=4.0.0 - export OPT=./ - export HTO=./ - export CHK=./ +if [ $seed -eq 0 ]; then + # Seed can't be 0, random number will be used + seed=$(od -An -N2 -tu2 /dev/urandom | tr -d ' ') fi -# Or filters the stdout with only HepMC2 useful data -$EPOS4_ROOT/epos4/scripts/epos -hepstd -s $seed $optns | sed -n 's/^\(HepMC::\|[EAUWVP] \)/\1/p' +# OR filters the stdout with only HepMC useful data +$EPOS4 -hepstd -s $seed $optns | sed -n 's/^\(HepMC::\|[EAUWVP] \)/\1/p' \ No newline at end of file diff --git a/MC/config/examples/epos4/generator/NeNe_536TeV_EPOS4.optns b/MC/config/examples/epos4/generator/NeNe_536TeV_EPOS4.optns new file mode 100644 index 000000000..5c84f533d --- /dev/null +++ b/MC/config/examples/epos4/generator/NeNe_536TeV_EPOS4.optns @@ -0,0 +1,33 @@ +!-------------------------------------------------------------------- +! Neon-Neon collisions with hydro and hadronic cascade +!-------------------------------------------------------------------- + +!--------------------------------------- +! Define run +!--------------------------------------- + +application hadron !hadron-hadron, hadron-nucleus, or nucleus-nucleus +set laproj 10 !projectile atomic number +set maproj 20 !projectile mass number +set latarg 10 !target atomic number +set matarg 20 !target mass number +set ecms 5360 !sqrt(s)_pp +set istmax 25 !max status considered for storage + +ftime on !string formation time non-zero +!suppressed decays: +nodecays + 110 20 2130 -2130 2230 -2230 1130 -1130 1330 -1330 2330 -2330 3331 -3331 +end + +set ninicon 1 !number of initial conditions used for hydro evolution +core full !core/corona activated +hydro hlle !hydro activated +eos x3ff !eos activated (epos standard EoS) +hacas full !hadronic cascade activated (UrQMD) +set nfreeze 1 !number of freeze out events per hydro event +set modsho 1 !printout every modsho events +set centrality 0 !0=min bias +set ihepmc 2 !HepMC output enabled on stdout +fillTree4(C1) !C1 sets impact parameter as centrality variable +set nfull 10 diff --git a/MC/config/examples/epos4/generator/NeNe_536TeV_EPOS4HQ.optns b/MC/config/examples/epos4/generator/NeNe_536TeV_EPOS4HQ.optns new file mode 100644 index 000000000..294a581ac --- /dev/null +++ b/MC/config/examples/epos4/generator/NeNe_536TeV_EPOS4HQ.optns @@ -0,0 +1,34 @@ +!-------------------------------------------------------------------- +! Neon-Neon collisions with hydro and hadronic cascade +!-------------------------------------------------------------------- + +!--------------------------------------- +! Define run +!--------------------------------------- + +application hadron !hadron-hadron, hadron-nucleus, or nucleus-nucleus +set laproj 10 !projectile atomic number +set maproj 20 !projectile mass number +set latarg 10 !target atomic number +set matarg 20 !target mass number +set ecms 5360 !sqrt(s)_pp +set istmax 25 !max status considered for storage + +ftime on !string formation time non-zero +!suppressed decays: +nodecays + 110 20 2130 -2130 2230 -2230 1130 -1130 1330 -1330 2330 -2330 3331 -3331 +end + +set ninicon 1 !number of initial conditions used for hydro evolution +core full !core/corona activated +hydro hlle !hydro activated +eos x3ff !eos activated (epos standard EoS) +hacas full !hadronic cascade activated (UrQMD) +set nfreeze 1 !number of freeze out events per hydro event +set modsho 1 !printout every modsho events +set centrality 0 !0=min bias +set ihepmc 2 !HepMC output enabled on stdout +fillTree4(C1) !C1 sets impact parameter as centrality variable +set ihq 1 !Enables HQ +set nfull 10 diff --git a/MC/config/examples/epos4/generator/OO_536TeV_EPOS4.optns b/MC/config/examples/epos4/generator/OO_536TeV_EPOS4.optns new file mode 100644 index 000000000..eeaab8cd9 --- /dev/null +++ b/MC/config/examples/epos4/generator/OO_536TeV_EPOS4.optns @@ -0,0 +1,33 @@ +!-------------------------------------------------------------------- +! Oxygen-Oxygen collisions with hydro and hadronic cascade +!-------------------------------------------------------------------- + +!--------------------------------------- +! Define run +!--------------------------------------- + +application hadron !hadron-hadron, hadron-nucleus, or nucleus-nucleus +set laproj 8 !projectile atomic number +set maproj 16 !projectile mass number +set latarg 8 !target atomic number +set matarg 16 !target mass number +set ecms 5360 !sqrt(s)_pp +set istmax 25 !max status considered for storage + +ftime on !string formation time non-zero +!suppressed decays: +nodecays + 110 20 2130 -2130 2230 -2230 1130 -1130 1330 -1330 2330 -2330 3331 -3331 +end + +set ninicon 1 !number of initial conditions used for hydro evolution +core full !core/corona activated +hydro hlle !hydro activated +eos x3ff !eos activated (epos standard EoS) +hacas full !hadronic cascade activated (UrQMD) +set nfreeze 1 !number of freeze out events per hydro event +set modsho 1 !printout every modsho events +set centrality 0 !0=min bias +set ihepmc 2 !HepMC output enabled on stdout +fillTree4(C1) !C1 sets impact parameter as centrality variable +set nfull 10 diff --git a/MC/config/examples/epos4/generator/OO_536TeV_EPOS4HQ.optns b/MC/config/examples/epos4/generator/OO_536TeV_EPOS4HQ.optns new file mode 100644 index 000000000..ac4dacb34 --- /dev/null +++ b/MC/config/examples/epos4/generator/OO_536TeV_EPOS4HQ.optns @@ -0,0 +1,34 @@ +!-------------------------------------------------------------------- +! Oxygen-Oxygen collisions with hydro and hadronic cascade +!-------------------------------------------------------------------- + +!--------------------------------------- +! Define run +!--------------------------------------- + +application hadron !hadron-hadron, hadron-nucleus, or nucleus-nucleus +set laproj 8 !projectile atomic number +set maproj 16 !projectile mass number +set latarg 8 !target atomic number +set matarg 16 !target mass number +set ecms 5360 !sqrt(s)_pp +set istmax 25 !max status considered for storage + +ftime on !string formation time non-zero +!suppressed decays: +nodecays + 110 20 2130 -2130 2230 -2230 1130 -1130 1330 -1330 2330 -2330 3331 -3331 +end + +set ninicon 1 !number of initial conditions used for hydro evolution +core full !core/corona activated +hydro hlle !hydro activated +eos x3ff !eos activated (epos standard EoS) +hacas full !hadronic cascade activated (UrQMD) +set nfreeze 1 !number of freeze out events per hydro event +set modsho 1 !printout every modsho events +set centrality 0 !0=min bias +set ihepmc 2 !HepMC output enabled on stdout +fillTree4(C1) !C1 sets impact parameter as centrality variable +set ihq 1 !Enables HQ +set nfull 10 diff --git a/MC/config/examples/epos4/generator/example.optns b/MC/config/examples/epos4/generator/example.optns index 553ecafa8..015d51a06 100644 --- a/MC/config/examples/epos4/generator/example.optns +++ b/MC/config/examples/epos4/generator/example.optns @@ -1,5 +1,5 @@ !-------------------------------------------------------------------- -! proton-proton collision no hydro no hadronic cascade +! proton-proton collisions with hydro and hadronic cascade !-------------------------------------------------------------------- !--------------------------------------- @@ -11,7 +11,7 @@ set laproj 1 !projectile atomic number set maproj 1 !projectile mass number set latarg 1 !target atomic number set matarg 1 !target mass number -set ecms 13000 !sqrt(s)_pp +set ecms 13600 !sqrt(s)_pp set istmax 25 !max status considered for storage ftime on !string formation time non-zero diff --git a/MC/config/examples/epos4/generator/examplehq.optns b/MC/config/examples/epos4/generator/examplehq.optns new file mode 100755 index 000000000..40afb362a --- /dev/null +++ b/MC/config/examples/epos4/generator/examplehq.optns @@ -0,0 +1,33 @@ +!-------------------------------------------------------------------- +! proton-proton collisions with hydro and hadronic cascade +!-------------------------------------------------------------------- + +!--------------------------------------- +! Define run +!--------------------------------------- + +application hadron !hadron-hadron, hadron-nucleus, or nucleus-nucleus +set laproj 1 !projectile atomic number +set maproj 1 !projectile mass number +set latarg 1 !target atomic number +set matarg 1 !target mass number +set ecms 13600 !sqrt(s)_pp +set istmax 25 !max status considered for storage + +ftime on !string formation time non-zero +!suppressed decays: +nodecays + 110 20 2130 -2130 2230 -2230 1130 -1130 1330 -1330 2330 -2330 3331 -3331 +end + +set ninicon 1 !number of initial conditions used for hydro evolution +core full !core/corona activated +hydro hlle !hydro activated +eos x3ff !eos activated (epos standard EoS) +hacas full !hadronic cascade activated (UrQMD) +set nfreeze 1 !number of freeze out events per hydro event +set modsho 1 !printout every modsho events +set centrality 0 !0=min bias +set ihepmc 2 !HepMC output enabled on stdout +set nfull 10 !Total number of events to be generated +set ihq 1 !Enable EPOS4HQ diff --git a/MC/config/examples/epos4/generator/examplepbpb.optns b/MC/config/examples/epos4/generator/examplepbpb.optns new file mode 100644 index 000000000..49a41c350 --- /dev/null +++ b/MC/config/examples/epos4/generator/examplepbpb.optns @@ -0,0 +1,33 @@ +!-------------------------------------------------------------------- +! Lead-Lead collision with hydro and hadronic cascade +!-------------------------------------------------------------------- + +!--------------------------------------- +! Define run +!--------------------------------------- + +application hadron !hadron-hadron, hadron-nucleus, or nucleus-nucleus +set laproj 82 !projectile atomic number +set maproj 208 !projectile mass number +set latarg 82 !target atomic number +set matarg 208 !target mass number +set ecms 5360 !sqrt(s)_pp +set istmax 25 !max status considered for storage + +ftime on !string formation time non-zero +!suppressed decays: +nodecays + 110 20 2130 -2130 2230 -2230 1130 -1130 1330 -1330 2330 -2330 3331 -3331 +end + +set ninicon 1 !number of initial conditions used for hydro evolution +core full !core/corona activated +hydro hlle !hydro activated +eos x3ff !eos activated (epos standard EoS) +hacas full !hadronic cascade activated (UrQMD) +set nfreeze 1 !number of freeze out events per hydro event +set modsho 1 !printout every modsho events +set centrality 0 !0=min bias +set ihepmc 2 !HepMC output enabled on stdout +fillTree4(C1) !C1 sets impact parameter as centrality variable +set nfull 10 \ No newline at end of file diff --git a/MC/config/examples/epos4/generator/pp_136TeV_hydro_cascade.optns b/MC/config/examples/epos4/generator/pp_136TeV_hydro_cascade.optns new file mode 100644 index 000000000..1e4b8ea66 --- /dev/null +++ b/MC/config/examples/epos4/generator/pp_136TeV_hydro_cascade.optns @@ -0,0 +1,32 @@ +!-------------------------------------------------------------------- +! proton-proton collisions at 13.6 TeV with hydro and hadronic cascade +!-------------------------------------------------------------------- + +!--------------------------------------- +! Define run +!--------------------------------------- + +application hadron !hadron-hadron, hadron-nucleus, or nucleus-nucleus +set laproj 1 !projectile atomic number +set maproj 1 !projectile mass number +set latarg 1 !target atomic number +set matarg 1 !target mass number +set ecms 13600 !sqrt(s)_pp +set istmax 25 !max status considered for storage + +ftime on !string formation time non-zero +!suppressed decays: +nodecays + 110 20 2130 -2130 2230 -2230 1130 -1130 1330 -1330 2330 -2330 3331 -3331 +end + +set ninicon 1 !number of initial conditions used for hydro evolution +core full !core/corona activated +hydro hlle !hydro activated +eos x3ff !eos activated (epos standard EoS) +hacas full !hadronic cascade activated (UrQMD) +set nfreeze 10 !number of freeze out events per hydro event +set modsho 1 !printout every modsho events +set centrality 0 !0=min bias +set ihepmc 2 !HepMC output enabled on stdout +set nfull 10 diff --git a/MC/config/examples/epos4/generator/pp_136TeV_hydro_cascade_off.optns b/MC/config/examples/epos4/generator/pp_136TeV_hydro_cascade_off.optns new file mode 100644 index 000000000..e02b08b3f --- /dev/null +++ b/MC/config/examples/epos4/generator/pp_136TeV_hydro_cascade_off.optns @@ -0,0 +1,32 @@ +!-------------------------------------------------------------------- +! proton-proton collisions at 13.6 TeV with hydro and hadronic cascade switched off +!-------------------------------------------------------------------- + +!--------------------------------------- +! Define run +!--------------------------------------- + +application hadron !hadron-hadron, hadron-nucleus, or nucleus-nucleus +set laproj 1 !projectile atomic number +set maproj 1 !projectile mass number +set latarg 1 !target atomic number +set matarg 1 !target mass number +set ecms 13600 !sqrt(s)_pp +set istmax 25 !max status considered for storage + +ftime on !string formation time non-zero +!suppressed decays: +nodecays + 110 20 2130 -2130 2230 -2230 1130 -1130 1330 -1330 2330 -2330 3331 -3331 +end + +set ninicon 1 !number of initial conditions used for hydro evolution +core full !core/corona activated +hydro hlle !hydro activated +eos x3ff !eos activated (epos standard EoS) +hacas off !hadronic cascade activated (UrQMD) +set nfreeze 10 !number of freeze out events per hydro event +set modsho 1 !printout every modsho events +set centrality 0 !0=min bias +set ihepmc 2 !HepMC output enabled on stdout +set nfull 10 diff --git a/MC/config/examples/epos4/generator/pp_13TeV_hydro_cascade.optns b/MC/config/examples/epos4/generator/pp_13TeV_hydro_cascade.optns new file mode 100644 index 000000000..6081a0fa4 --- /dev/null +++ b/MC/config/examples/epos4/generator/pp_13TeV_hydro_cascade.optns @@ -0,0 +1,32 @@ +!-------------------------------------------------------------------- +! proton-proton collisions at 13 TeV with hydro and hadronic cascade +!-------------------------------------------------------------------- + +!--------------------------------------- +! Define run +!--------------------------------------- + +application hadron !hadron-hadron, hadron-nucleus, or nucleus-nucleus +set laproj 1 !projectile atomic number +set maproj 1 !projectile mass number +set latarg 1 !target atomic number +set matarg 1 !target mass number +set ecms 13000 !sqrt(s)_pp +set istmax 25 !max status considered for storage + +ftime on !string formation time non-zero +!suppressed decays: +nodecays + 110 20 2130 -2130 2230 -2230 1130 -1130 1330 -1330 2330 -2330 3331 -3331 +end + +set ninicon 1 !number of initial conditions used for hydro evolution +core full !core/corona activated +hydro hlle !hydro activated +eos x3ff !eos activated (epos standard EoS) +hacas full !hadronic cascade activated (UrQMD) +set nfreeze 1 !number of freeze out events per hydro event +set modsho 1 !printout every modsho events +set centrality 0 !0=min bias +set ihepmc 2 !HepMC output enabled on stdout +set nfull 10 diff --git a/MC/config/examples/epos4/generator_EPOS4.C b/MC/config/examples/epos4/generator_EPOS4.C index 6d08a7b19..987bed823 100644 --- a/MC/config/examples/epos4/generator_EPOS4.C +++ b/MC/config/examples/epos4/generator_EPOS4.C @@ -9,6 +9,37 @@ class GeneratorEPOS4 : public o2::eventgen::GeneratorHepMC GeneratorEPOS4() = default; ~GeneratorEPOS4() = default; + bool importParticles() override { + bool status = GeneratorHepMC::importParticles(); + if (!status) { + LOG(error) << "Failed to import particles from HepMC event!"; + return false; + } + // Skip transport of charmonia chi_0c and chi_1c (incompatible with default G4 physics list) + // These are not decayed by EPOS4 (no daughters) + if (!mEnChi) + { + for (int a = 0; a < mParticles.size(); ++a) { + if (mParticles[a].GetPdgCode() == 10441 || mParticles[a].GetPdgCode() == 20443) + { + LOG(debug) << "Setting charmonium state " << mParticles[a].GetPdgCode() << " with index " << a << " not to be transported"; + mParticles[a].SetBit(ParticleStatus::kToBeDone, false); + } + } + } + return true; + } + + void setChiFlag(bool &flag) { + mEnChi = flag; + if (!flag) { + LOG(info) << "Charmonium states chi_0c and chi_1c will not be transported."; + } + } + + private: + bool mEnChi = false; // Switch to enable chi_0c and chi_1c mesons + }; // Next function takes the optns file as argument and edits the maximum number of events to be generated. @@ -19,7 +50,7 @@ class GeneratorEPOS4 : public o2::eventgen::GeneratorHepMC // type for the nfull parameter. Might be changed in the future. // When running locally, or on the GRID (not in hyperloop), the default parameters provided in the .ini file of the // external generation can be overwritten using the confKeyValues option (or similar depending on the tool used). -FairGenerator* generateEPOS4(const std::string &name, const int& nEvents) +FairGenerator* generateEPOS4(const std::string &name, const int& nEvents, bool enableChi = false) { // check if the file exists auto filename = gSystem->ExpandPathName(name.c_str()); @@ -43,19 +74,28 @@ FairGenerator* generateEPOS4(const std::string &name, const int& nEvents) buffer << line << "\n"; } file.close(); + auto gen = new GeneratorEPOS4(); + // Set the chi flag + gen->setChiFlag(enableChi); + auto ¶m0 = o2::eventgen::GeneratorFileOrCmdParam::Instance(); + auto ¶m = o2::eventgen::GeneratorHepMCParam::Instance(); + auto &conf = o2::conf::SimConfig::Instance(); + // Randomise seed (useful for multiple instances of the generator) + int randomSeed = gRandom->Integer(conf.getStartSeed()); // Write the updated content back to a file in the current directory - std::ofstream outFile("cfg.optns"); + std::string optnsFileName(Form("cfg%d.optns", randomSeed)); + std::ofstream outFile(optnsFileName); outFile << buffer.str(); if (!found) { outFile << "set nfull " + std::to_string(nEvents); } outFile.close(); - auto gen = new GeneratorEPOS4(); - auto& param0 = o2::eventgen::GeneratorFileOrCmdParam::Instance(); - auto& param = o2::eventgen::GeneratorHepMCParam::Instance(); - auto& conf = o2::conf::SimConfig::Instance(); + optnsFileName = optnsFileName.substr(0, optnsFileName.find_last_of('.')); // remove the .optns extension // setup the HepMC generator to run with automatic FIFOs gen->setup(param0, param, conf); + // Replace seed and optns file + gen->setCmd(param0.cmd + " -i " + optnsFileName); + gen->setSeed(randomSeed); return gen; } diff --git a/MC/config/examples/herwig/LHC.in b/MC/config/examples/herwig/LHC.in new file mode 100644 index 000000000..cb1ecb4fb --- /dev/null +++ b/MC/config/examples/herwig/LHC.in @@ -0,0 +1,36 @@ +# -*- ThePEG-repository -*- + +################################################################################ +# This file contains our best tune to UE data from ATLAS at 7 TeV. More recent +# tunes and tunes for other centre-of-mass energies as well as more usage +# instructions can be obtained from this Herwig wiki page: +# http://projects.hepforge.org/herwig/trac/wiki/MB_UE_tunes +# The model for soft interactions and diffractions is explained in +# [S. Gieseke, P. Kirchgaesser, F. Loshaj, arXiv:1612.04701] +################################################################################ + +read snippets/PPCollider.in + +################################################## +# Technical parameters for this run +################################################## +cd /Herwig/Generators +################################################## +# LHC physics parameters (override defaults here) +################################################## +set EventGenerator:EventHandler:LuminosityFunction:Energy 13600.0 +# Minimum Bias +read snippets/MB.in + +# Recommended set of parameters for MB/UE runs +set /Herwig/Hadronization/ColourReconnector:ReconnectionProbability 0.5 +set /Herwig/UnderlyingEvent/MPIHandler:pTmin0 3.502683 +set /Herwig/UnderlyingEvent/MPIHandler:InvRadius 1.402055 +set /Herwig/UnderlyingEvent/MPIHandler:Power 0.416852 +set /Herwig/Partons/RemnantDecayer:ladderPower -0.08 +set /Herwig/Partons/RemnantDecayer:ladderNorm 0.95 + +################################################## +# Save run for later usage with 'Herwig run' +################################################## +saverun LHC EventGenerator \ No newline at end of file diff --git a/MC/config/examples/herwig/generator_Herwig.C b/MC/config/examples/herwig/generator_Herwig.C new file mode 100644 index 000000000..1c3da112c --- /dev/null +++ b/MC/config/examples/herwig/generator_Herwig.C @@ -0,0 +1,333 @@ +#define SKIP_HEPMC_CONVERSION 1 +#define HAVE_HEPMC3 1 + +// O2DPG and ROOT includes +#include "FairGenerator.h" +#include "FairPrimaryGenerator.h" +#include "fairlogger/Logger.h" +#include "TParticle.h" +#include "TLorentzVector.h" +#include +#include +#include + +// ThePEG +#include "ThePEG/Repository/EventGenerator.h" +#include "ThePEG/EventRecord/Event.h" +#include "ThePEG/EventRecord/Particle.h" +#include "ThePEG/EventRecord/Step.h" +#include "ThePEG/Config/ThePEG.h" +#include "ThePEG/PDT/ParticleData.h" +#include "ThePEG/Repository/Repository.h" + +// Herwig +#include "Herwig/API/HerwigAPI.h" +#include "Herwig/API/HerwigUI.h" + +// Subclass of HerwigUI to provide minimal implementation of the abstract class +class SimpleHerwigUI : public Herwig::HerwigUI +{ +public: + SimpleHerwigUI(const std::string &inFile, + Herwig::RunMode::Mode mode = Herwig::RunMode::READ, int seed = 0) + : m_inFile(inFile), m_mode(mode), + m_in(inFile), m_out(std::cout), m_err(std::cerr), mSeed(seed) + { + if (!m_in) + { + LOG(fatal) << "Cannot open Herwig input file: " << inFile; + exit(1); + } + std::string hDir = std::getenv("HERWIG_ROOT"); + if (!hDir.empty()) + { + Dirs.push_back(hDir + "/share/Herwig"); + } + } + + Herwig::RunMode::Mode runMode() const override { return m_mode; } + + std::string repository() const override { + std::string rpo = std::getenv("HERWIG_ROOT"); + rpo.append("/share/Herwig/HerwigDefaults.rpo"); + return rpo; + } + std::string inputfile() const override { return m_inFile; } + std::string setupfile() const override { return ""; } + + bool resume() const override { return false; } + bool tics() const override { return false; } + std::string tag() const override { return ""; } + std::string integrationList() const override { return ""; } + + const std::vector &prependReadDirectories() const override + { + return Dirs; + } + const std::vector &appendReadDirectories() const override + { + static std::vector empty; + return empty; + } + + long N() const override { return 1; } // number of events + int seed() const override { return mSeed; } + int jobs() const override { return 1; } + unsigned int jobSize() const override { return 1; } + unsigned int maxJobs() const override { return 1; } + + void quitWithHelp() const override { std::exit(1); } + void quit() const override { std::exit(1); } + + std::ostream &outStream() const override { return m_out; } + std::ostream &errStream() const override { return m_err; } + std::istream &inStream() const override { return m_in; } + +private: + std::string m_inFile; + Herwig::RunMode::Mode m_mode; + mutable std::ifstream m_in; + std::ostream &m_out; + std::ostream &m_err; + std::vector Dirs; + int mSeed = 0; +}; + +namespace o2 +{ +namespace eventgen +{ + +/// HERWIG7 event generator using ThePEG interface +/// Author: Marco Giacalone (marco.giacalone@cern.ch) +/// Based on the O2DPG external generator configurations +class GeneratorHerwig : public Generator +{ +public: + /// Default constructor + GeneratorHerwig(const std::string& configFile = "LHC.in", int seed = -1) + : mConfigFile(configFile) + , mEventGenerator(nullptr) + { + LOG(info) << "HERWIG7 Generator construction"; + LOG(info) << "Config file: " << mConfigFile; + std::string extension = mConfigFile.substr(mConfigFile.find_last_of(".")); + if( extension == ".in" ) { + mIsInputFile = true; + LOG(info) << "Using input file for configuration"; + } else if(extension == ".run") { + mIsInputFile = false; + LOG(info) << "Using run file for configuration"; + } else { + LOG(fatal) << "No file extension found in config file: " << mConfigFile; + exit(1); + } + if (seed < 0) + { + auto &conf = o2::conf::SimConfig::Instance(); + mSeed = gRandom->Integer(conf.getStartSeed()); + } else { + mSeed = seed; + } + LOG(info) << "Using seed: " << mSeed << " for HERWIG simulation"; + } + + /// Destructor + ~GeneratorHerwig() = default; + + /// Initialize the generator + Bool_t Init() override + { + LOG(info) << "Initializing HERWIG7 Generator"; + if (mIsInputFile) { + // Process .in file + return initFromInputFile(); + } else { + // Process .run file directly + return initFromRunFile(); + } + } + + /// Generate event + Bool_t generateEvent() override + { + if (!mEventGenerator) { + LOG(error) << "Event generator not initialized"; + return kFALSE; + } + // Clear previous event particles + hParticles.clear(); + + // Generate the event + mPEGEvent = mEventGenerator->shoot(); + + if (!mPEGEvent) + { + LOG(error) << "Failed to generate event"; + return kFALSE; + } + + // Convert ThePEG event to TParticle format + convertEvent(mPEGEvent); + LOG(debug) << "Herwig7 generated " << hParticles.size() << " particles"; + + return kTRUE; + } + + /// Import particles for transport + Bool_t importParticles() override + { + if (hParticles.empty()) { + LOG(warning) << "No particles to import"; + return kFALSE; + } + + // Add particles to the primary generator + for (const auto& particle : hParticles) { + mParticles.push_back(particle); + } + + return kTRUE; + } + +private: + std::string mConfigFile; ///< HERWIG config file (.in or .run) + Bool_t mIsInputFile = false; ///< True for .in files, false for .run files + ThePEG::EGPtr mEventGenerator; ///< ThePEG event generator + std::vector hParticles; ///< Generated Herwig particles + ThePEG::EventPtr mPEGEvent; ///< Pointer to Current event + int mSeed = 0; ///< Random seed for Herwig + + void printHerwigSearchPaths() + { + const auto &list = ThePEG::Repository::listReadDirs(); + + LOG(info) << "Append directories:\n"; + for (const auto &p : list) + LOG(info) << " " << p << "\n"; + } + + /// Initialize from .in file + Bool_t initFromInputFile() + { + LOG(info) << "Initializing from .in file: " << mConfigFile; + + using namespace ThePEG; + SimpleHerwigUI ui(mConfigFile, Herwig::RunMode::READ, mSeed); + Herwig::API::read(ui); + // For debugging, print the search paths + // printHerwigSearchPaths(); + // Currently the .run filename is set inside the .in file itself with + // the line "saverun LHC EventGenerator" or similar. We assume this is the same as + // the .in file name with .run extension, so change that string accordingly in your .in files. + std::string runFile = mConfigFile; + size_t pos = runFile.find_last_of('.'); + runFile.replace(pos, 4, ".run"); + pos = runFile.find_last_of('/'); + runFile = (pos != std::string::npos) ? runFile.substr(pos + 1) : runFile; + mConfigFile = runFile; + LOG(info) << "Generated run file: " << runFile; + auto res = initFromRunFile(); + if (!res) { + LOG(error) << "Failed to initialize from generated run file"; + return kFALSE; + } + return kTRUE; + } + + /// Initialize from .run file + Bool_t initFromRunFile() + { + LOG(info) << "Initializing from .run file: " << mConfigFile; + + using namespace ThePEG; + + if (!std::ifstream(mConfigFile)) + { + LOG(info) << "Run file does not exist: " << mConfigFile; + return kFALSE; + } + SimpleHerwigUI runui(mConfigFile, Herwig::RunMode::RUN, mSeed); + // Prepare the generator + mEventGenerator = Herwig::API::prepareRun(runui); + if (!mEventGenerator) + { + LOG(fatal) << "Error: prepareRun() returned null."; + return kFALSE; + } + + mEventGenerator->initialize(); + LOG(info) << "Herwig generator initialized successfully."; + return kTRUE; + } + + /// Convert ThePEG event to TParticle format + void convertEvent(ThePEG::EventPtr event) + { + if (!event) return; + + // Get all particles from the event + const ThePEG::tPVector& particles = event->getFinalState(); + + for (size_t i = 0; i < particles.size(); ++i) { + ThePEG::tPPtr particle = particles[i]; + if (!particle) continue; + + // Get particle properties + int pdgCode = particle->id(); + int status = getFinalStateStatus(particle); + + // Get 4-momentum + ThePEG::LorentzMomentum momentum = particle->momentum(); + double px = momentum.x() / ThePEG::GeV; // Convert to GeV + double py = momentum.y() / ThePEG::GeV; + double pz = momentum.z() / ThePEG::GeV; + double e = momentum.e() / ThePEG::GeV; + + // Get production vertex + const ThePEG::LorentzPoint &vertex = particle->vertex(); + double vx = vertex.x() / ThePEG::mm; // Convert to mm + double vy = vertex.y() / ThePEG::mm; + double vz = vertex.z() / ThePEG::mm; + double vt = vertex.t() / ThePEG::mm; // Convert to mm/c + + // Create TParticle + TParticle tparticle( + pdgCode, status, + -1, -1, -1, -1, // mother and daughter indices (to be set properly) + px, py, pz, e, + vx, vy, vz, vt + ); + tparticle.SetStatusCode(o2::mcgenstatus::MCGenStatusEncoding(tparticle.GetStatusCode(), 0).fullEncoding); + tparticle.SetBit(ParticleStatus::kToBeDone, // + o2::mcgenstatus::getHepMCStatusCode(tparticle.GetStatusCode()) == 1); + + hParticles.push_back(tparticle); + } + + LOG(debug) << "Converted " << hParticles.size() << " particles from HERWIG7 event"; + } + + /// Determine final state status for particle + int getFinalStateStatus(ThePEG::tPPtr particle) + { + // In HERWIG/ThePEG, check if particle is stable + if (particle->children().empty()) { + return 1; // Final state particle + } else { + return 2; // Intermediate particle + } + } +}; + +} // namespace eventgen +} // namespace o2 + +/// HERWIG7 generator from .in/.run file. If seed is -1, a random seed is chosen +/// based on the SimConfig starting seed. +FairGenerator* generateHerwig7(const std::string inputFile = "LHC.in", int seed = -1) +{ + auto filePath = gSystem->ExpandPathName(inputFile.c_str()); + auto generator = new o2::eventgen::GeneratorHerwig(filePath, seed); + return generator; +} \ No newline at end of file diff --git a/MC/config/examples/hybrid/example.json b/MC/config/examples/hybrid/example.json new file mode 100644 index 000000000..a43766ab7 --- /dev/null +++ b/MC/config/examples/hybrid/example.json @@ -0,0 +1,30 @@ +{ + "generators": [ + { + "name": "pythia8", + "config": { + "config": "${O2_ROOT}/share/Generators/egconfig/pythia8_inel.cfg", + "hooksFileName": "", + "hooksFuncName": "", + "includePartonEvent": false, + "particleFilter": "", + "verbose": 0 + } + }, + { + "name": "evtpool", + "config": { + "eventPoolPath" : "${O2DPG_MC_CONFIG_ROOT}/MC/config/examples/hybrid/examplemanifest.dat", + "skipNonTrackable" : true, + "roundRobin" : false, + "randomize" : true, + "rngseed" : 0, + "randomphi" : false + } + } + ], + "fractions": [ + 1, + 1 + ] +} diff --git a/MC/config/examples/hybrid/examplemanifest.dat b/MC/config/examples/hybrid/examplemanifest.dat new file mode 100755 index 000000000..5cbfda065 --- /dev/null +++ b/MC/config/examples/hybrid/examplemanifest.dat @@ -0,0 +1,10 @@ +alien:///alice/sim/2025/EP25i1_GeneratorHF_D2H_bbbar_Mode2_XiC_NoDecay/1/001/evtpool.root +alien:///alice/sim/2025/EP25i1_GeneratorHF_D2H_bbbar_Mode2_XiC_NoDecay/1/002/evtpool.root +alien:///alice/sim/2025/EP25i1_GeneratorHF_D2H_bbbar_Mode2_XiC_NoDecay/1/003/evtpool.root +alien:///alice/sim/2025/EP25i1_GeneratorHF_D2H_bbbar_Mode2_XiC_NoDecay/1/004/evtpool.root +alien:///alice/sim/2025/EP25i1_GeneratorHF_D2H_bbbar_Mode2_XiC_NoDecay/1/005/evtpool.root +alien:///alice/sim/2025/EP25i1_GeneratorHF_D2H_bbbar_Mode2_XiC_NoDecay/1/006/evtpool.root +alien:///alice/sim/2025/EP25i1_GeneratorHF_D2H_bbbar_Mode2_XiC_NoDecay/1/007/evtpool.root +alien:///alice/sim/2025/EP25i1_GeneratorHF_D2H_bbbar_Mode2_XiC_NoDecay/1/008/evtpool.root +alien:///alice/sim/2025/EP25i1_GeneratorHF_D2H_bbbar_Mode2_XiC_NoDecay/1/009/evtpool.root +alien:///alice/sim/2025/EP25i1_GeneratorHF_D2H_bbbar_Mode2_XiC_NoDecay/1/010/evtpool.root \ No newline at end of file diff --git a/MC/config/examples/hybrid/exampleparallel.json b/MC/config/examples/hybrid/exampleparallel.json new file mode 100644 index 000000000..77416d23d --- /dev/null +++ b/MC/config/examples/hybrid/exampleparallel.json @@ -0,0 +1,47 @@ +{ + "mode": "parallel", + "generators": [ + { + "name": "pythia8pp", + "config": "" + }, + { + "name": "pythia8pp", + "config": "" + }, + { + "name": "pythia8pp", + "config": "" + }, + { + "name": "pythia8pp", + "config": "" + }, + { + "name": "pythia8pp", + "config": "" + }, + { + "name": "pythia8pp", + "config": "" + }, + { + "name": "pythia8pp", + "config": "" + }, + { + "name": "pythia8pp", + "config": "" + } + ], + "fractions": [ + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1 + ] +} \ No newline at end of file diff --git a/MC/config/examples/ini/GeneratorEPOS4.ini b/MC/config/examples/ini/GeneratorEPOS4.ini index 33935cbe2..abfbb65dd 100644 --- a/MC/config/examples/ini/GeneratorEPOS4.ini +++ b/MC/config/examples/ini/GeneratorEPOS4.ini @@ -3,8 +3,9 @@ fileName=${O2DPG_MC_CONFIG_ROOT}/MC/config/examples/epos4/generator_EPOS4.C funcName=generateEPOS4("${O2DPG_MC_CONFIG_ROOT}/MC/config/examples/epos4/generator/example.optns", 2147483647) [GeneratorFileOrCmd] -cmd=${O2DPG_MC_CONFIG_ROOT}/MC/config/examples/epos4/epos.sh -i cfg +cmd=${O2DPG_MC_CONFIG_ROOT}/MC/config/examples/epos4/epos.sh bMaxSwitch=none +# Set to version 2 if EPOS4.0.0 is used [HepMC] -version=2 \ No newline at end of file +version=3 diff --git a/MC/config/examples/ini/GeneratorEPOS4HQ.ini b/MC/config/examples/ini/GeneratorEPOS4HQ.ini new file mode 100644 index 000000000..f5804d584 --- /dev/null +++ b/MC/config/examples/ini/GeneratorEPOS4HQ.ini @@ -0,0 +1,11 @@ +#---> GeneratorEPOS4 +[GeneratorExternal] +fileName=${O2DPG_MC_CONFIG_ROOT}/MC/config/examples/epos4/generator_EPOS4.C +funcName=generateEPOS4("${O2DPG_MC_CONFIG_ROOT}/MC/config/examples/epos4/generator/examplehq.optns", 2147483647) + +[GeneratorFileOrCmd] +cmd=${O2DPG_MC_CONFIG_ROOT}/MC/config/examples/epos4/epos.sh +bMaxSwitch=none + +[HepMC] +version=3 \ No newline at end of file diff --git a/MC/config/examples/ini/GeneratorEPOS4HQNeNe536TeV.ini b/MC/config/examples/ini/GeneratorEPOS4HQNeNe536TeV.ini new file mode 100644 index 000000000..b54fff7d5 --- /dev/null +++ b/MC/config/examples/ini/GeneratorEPOS4HQNeNe536TeV.ini @@ -0,0 +1,13 @@ +#NEV_TEST> 10 +#---> GeneratorEPOS4NeNe536TeV +[GeneratorExternal] +fileName=${O2DPG_MC_CONFIG_ROOT}/MC/config/examples/epos4/generator_EPOS4.C +funcName=generateEPOS4("${O2DPG_MC_CONFIG_ROOT}/MC/config/examples/epos4/generator/NeNe_536TeV_EPOS4HQ.optns", 2147483647) + +[GeneratorFileOrCmd] +cmd=${O2DPG_MC_CONFIG_ROOT}/MC/config/examples/epos4/epos.sh +bMaxSwitch=none + +# Set to version 2 if EPOS4.0.0 is used +[HepMC] +version=3 diff --git a/MC/config/examples/ini/GeneratorEPOS4HQOO536TeV.ini b/MC/config/examples/ini/GeneratorEPOS4HQOO536TeV.ini new file mode 100644 index 000000000..6f1407888 --- /dev/null +++ b/MC/config/examples/ini/GeneratorEPOS4HQOO536TeV.ini @@ -0,0 +1,13 @@ +#NEV_TEST> 1 +#---> GeneratorEPOS4OO536TeV +[GeneratorExternal] +fileName=${O2DPG_MC_CONFIG_ROOT}/MC/config/examples/epos4/generator_EPOS4.C +funcName=generateEPOS4("${O2DPG_MC_CONFIG_ROOT}/MC/config/examples/epos4/generator/OO_536TeV_EPOS4HQ.optns", 2147483647) + +[GeneratorFileOrCmd] +cmd=${O2DPG_MC_CONFIG_ROOT}/MC/config/examples/epos4/epos.sh +bMaxSwitch=none + +# Set to version 2 if EPOS4.0.0 is used +[HepMC] +version=3 diff --git a/MC/config/examples/ini/GeneratorEPOS4NeNe536TeV.ini b/MC/config/examples/ini/GeneratorEPOS4NeNe536TeV.ini new file mode 100644 index 000000000..3dc0901ad --- /dev/null +++ b/MC/config/examples/ini/GeneratorEPOS4NeNe536TeV.ini @@ -0,0 +1,12 @@ +#NEV_TEST> 10 +[GeneratorExternal] +fileName=${O2DPG_MC_CONFIG_ROOT}/MC/config/examples/epos4/generator_EPOS4.C +funcName=generateEPOS4("${O2DPG_MC_CONFIG_ROOT}/MC/config/examples/epos4/generator/NeNe_536TeV_EPOS4.optns", 2147483647) + +[GeneratorFileOrCmd] +cmd=${O2DPG_MC_CONFIG_ROOT}/MC/config/examples/epos4/epos.sh +bMaxSwitch=none + +# Set to version 2 if EPOS4.0.0 is used +[HepMC] +version=3 diff --git a/MC/config/examples/ini/GeneratorEPOS4OO536TeV.ini b/MC/config/examples/ini/GeneratorEPOS4OO536TeV.ini new file mode 100644 index 000000000..c05718ff0 --- /dev/null +++ b/MC/config/examples/ini/GeneratorEPOS4OO536TeV.ini @@ -0,0 +1,12 @@ +#NEV_TEST> 1 +[GeneratorExternal] +fileName=${O2DPG_MC_CONFIG_ROOT}/MC/config/examples/epos4/generator_EPOS4.C +funcName=generateEPOS4("${O2DPG_MC_CONFIG_ROOT}/MC/config/examples/epos4/generator/OO_536TeV_EPOS4.optns", 2147483647) + +[GeneratorFileOrCmd] +cmd=${O2DPG_MC_CONFIG_ROOT}/MC/config/examples/epos4/epos.sh +bMaxSwitch=none + +# Set to version 2 if EPOS4.0.0 is used +[HepMC] +version=3 diff --git a/MC/config/examples/ini/GeneratorEPOS4PbPb.ini b/MC/config/examples/ini/GeneratorEPOS4PbPb.ini new file mode 100644 index 000000000..6732c459c --- /dev/null +++ b/MC/config/examples/ini/GeneratorEPOS4PbPb.ini @@ -0,0 +1,12 @@ +#NEV_TEST> 1 +[GeneratorExternal] +fileName=${O2DPG_MC_CONFIG_ROOT}/MC/config/examples/epos4/generator_EPOS4.C +funcName=generateEPOS4("${O2DPG_MC_CONFIG_ROOT}/MC/config/examples/epos4/generator/examplepbpb.optns", 2147483647) + +[GeneratorFileOrCmd] +cmd=${O2DPG_MC_CONFIG_ROOT}/MC/config/examples/epos4/epos.sh +bMaxSwitch=none + +# Set to version 2 if EPOS4.0.0 is used +[HepMC] +version=3 diff --git a/MC/config/examples/ini/GeneratorEPOS4_pp136TeV.ini b/MC/config/examples/ini/GeneratorEPOS4_pp136TeV.ini new file mode 100644 index 000000000..96bf37247 --- /dev/null +++ b/MC/config/examples/ini/GeneratorEPOS4_pp136TeV.ini @@ -0,0 +1,12 @@ +#---> GeneratorEPOS4 +[GeneratorExternal] +fileName=${O2DPG_MC_CONFIG_ROOT}/MC/config/examples/epos4/generator_EPOS4.C +funcName=generateEPOS4("${O2DPG_MC_CONFIG_ROOT}/MC/config/examples/epos4/generator/pp_136TeV_hydro_cascade.optns", 214748364) + +[GeneratorFileOrCmd] +cmd=${O2DPG_MC_CONFIG_ROOT}/MC/config/examples/epos4/epos.sh +bMaxSwitch=none + +# Set to version 2 if EPOS4.0.0 is used +[HepMC] +version=3 diff --git a/MC/config/examples/ini/GeneratorEPOS4_pp136TeV_nohacas.ini b/MC/config/examples/ini/GeneratorEPOS4_pp136TeV_nohacas.ini new file mode 100644 index 000000000..f1efd0687 --- /dev/null +++ b/MC/config/examples/ini/GeneratorEPOS4_pp136TeV_nohacas.ini @@ -0,0 +1,12 @@ +#---> GeneratorEPOS4 +[GeneratorExternal] +fileName=${O2DPG_MC_CONFIG_ROOT}/MC/config/examples/epos4/generator_EPOS4.C +funcName=generateEPOS4("${O2DPG_MC_CONFIG_ROOT}/MC/config/examples/epos4/generator/pp_136TeV_hydro_cascade_off.optns", 214748364) + +[GeneratorFileOrCmd] +cmd=${O2DPG_MC_CONFIG_ROOT}/MC/config/examples/epos4/epos.sh +bMaxSwitch=none + +# Set to version 2 if EPOS4.0.0 is used +[HepMC] +version=3 diff --git a/MC/config/examples/ini/GeneratorEPOS4_pp13TeV.ini b/MC/config/examples/ini/GeneratorEPOS4_pp13TeV.ini new file mode 100644 index 000000000..3e5080bf1 --- /dev/null +++ b/MC/config/examples/ini/GeneratorEPOS4_pp13TeV.ini @@ -0,0 +1,11 @@ +[GeneratorExternal] +fileName=${O2DPG_MC_CONFIG_ROOT}/MC/config/examples/epos4/generator_EPOS4.C +funcName=generateEPOS4("${O2DPG_MC_CONFIG_ROOT}/MC/config/examples/epos4/generator/pp_13TeV_hydro_cascade.optns", 2147483647) + +[GeneratorFileOrCmd] +cmd=${O2DPG_MC_CONFIG_ROOT}/MC/config/examples/epos4/epos.sh +bMaxSwitch=none + +# Set to version 2 if EPOS4.0.0 is used +[HepMC] +version=3 diff --git a/MC/config/examples/ini/GeneratorExtToHybrid.ini b/MC/config/examples/ini/GeneratorExtToHybrid.ini new file mode 100644 index 000000000..62e0986b7 --- /dev/null +++ b/MC/config/examples/ini/GeneratorExtToHybrid.ini @@ -0,0 +1,3 @@ +[GeneratorHybrid] +configFile = ${O2DPG_MC_CONFIG_ROOT}/MC/config/examples/hybrid/example.json +switchExtToHybrid = true \ No newline at end of file diff --git a/MC/config/examples/ini/GeneratorExtToHybridParallel.ini b/MC/config/examples/ini/GeneratorExtToHybridParallel.ini new file mode 100644 index 000000000..7745d9095 --- /dev/null +++ b/MC/config/examples/ini/GeneratorExtToHybridParallel.ini @@ -0,0 +1,4 @@ +[GeneratorHybrid] +configFile = ${O2DPG_MC_CONFIG_ROOT}/MC/config/examples/hybrid/exampleparallel.json +switchExtToHybrid = true +num_workers = 8 diff --git a/MC/config/examples/ini/GeneratorHERWIG7.ini b/MC/config/examples/ini/GeneratorHERWIG7.ini new file mode 100644 index 000000000..af904d1e8 --- /dev/null +++ b/MC/config/examples/ini/GeneratorHERWIG7.ini @@ -0,0 +1,3 @@ +[GeneratorExternal] +fileName=${O2DPG_MC_CONFIG_ROOT}/MC/config/examples/herwig/generator_Herwig.C +funcName=generateHerwig7("${O2DPG_MC_CONFIG_ROOT}/MC/config/examples/herwig/LHC.in") diff --git a/MC/config/examples/ini/tests/GeneratorEPOS4NeNe536TeV.C b/MC/config/examples/ini/tests/GeneratorEPOS4NeNe536TeV.C new file mode 100644 index 000000000..994e64c42 --- /dev/null +++ b/MC/config/examples/ini/tests/GeneratorEPOS4NeNe536TeV.C @@ -0,0 +1,78 @@ +int External() +{ + std::string path{"o2sim_Kine.root"}; + + // Check that file exists, can be opened and has the correct tree + TFile file(path.c_str(), "READ"); + if (file.IsZombie()) + { + std::cerr << "Cannot open ROOT file " << path << "\n"; + return 1; + } + + auto tree = (TTree*)file.Get("o2sim"); + if (!tree) + { + std::cerr << "Cannot find tree o2sim in file " << path << "\n"; + return 1; + } + + std::vector* tracks{}; + tree->SetBranchAddress("MCTrack", &tracks); + + // Check if all events are filled + auto nEvents = tree->GetEntries(); + for (Long64_t i = 0; i < nEvents; ++i) + { + tree->GetEntry(i); + if (tracks->empty()) + { + std::cerr << "Empty entry found at event " << i << "\n"; + return 1; + } + } + + // Check if there is 1 event, as customarily set in the ini file + // Heavy-ion collisions with hydro and hadronic cascade are very slow to simulate + if (nEvents != 10) + { + std::cerr << "Expected 10 events, got " << nEvents << "\n"; + return 1; + } + + // ---- Neon-Neon parameters ---- + constexpr int kNeonPDG = 1000100200; // Ne-20 ion + constexpr double kEnucleon = 5360.; // GeV per nucleon + constexpr int kA = 20; // Neon mass number + constexpr double kNeonEnergy = kA * kEnucleon / 2.0; // beam energy in GeV + + // Check if each event has two neon ions at expected energy + for (int i = 0; i < nEvents; i++) + { + tree->GetEntry(i); + int count = 0; + + for (int idxMCTrack = 0; idxMCTrack < tracks->size(); ++idxMCTrack) + { + auto track = tracks->at(idxMCTrack); + double energy = track.GetEnergy(); + + // 50 MeV tolerance (floating point safety) + if (std::abs(energy - kNeonEnergy) < 5e-2 && + track.GetPdgCode() == kNeonPDG) + { + count++; + } + } + + if (count < 2) + { + std::cerr << "Event " << i + << " has less than 2 neon ions at " + << kNeonEnergy << " GeV\n"; + return 1; + } + } + + return 0; +} diff --git a/MC/config/examples/ini/tests/GeneratorEPOS4OO536TeV.C b/MC/config/examples/ini/tests/GeneratorEPOS4OO536TeV.C new file mode 100644 index 000000000..97798d7e2 --- /dev/null +++ b/MC/config/examples/ini/tests/GeneratorEPOS4OO536TeV.C @@ -0,0 +1,78 @@ +int External() +{ + std::string path{"o2sim_Kine.root"}; + + // Check that file exists, can be opened and has the correct tree + TFile file(path.c_str(), "READ"); + if (file.IsZombie()) + { + std::cerr << "Cannot open ROOT file " << path << "\n"; + return 1; + } + + auto tree = (TTree *)file.Get("o2sim"); + if (!tree) + { + std::cerr << "Cannot find tree o2sim in file " << path << "\n"; + return 1; + } + + std::vector *tracks{}; + tree->SetBranchAddress("MCTrack", &tracks); + + // Check if all events are filled + auto nEvents = tree->GetEntries(); + for (Long64_t i = 0; i < nEvents; ++i) + { + tree->GetEntry(i); + if (tracks->empty()) + { + std::cerr << "Empty entry found at event " << i << "\n"; + return 1; + } + } + + // Check if there is 1 event, as customly set in the ini file + // Heavy-ion collisions with hydro and hadronic cascade are very slow to simulate + if (nEvents != 1) + { + std::cerr << "Expected 1 event, got " << nEvents << "\n"; + return 1; + } + + // ---- Oxygen-Oxygen parameters ---- + constexpr int kOxygenPDG = 1000080160; // O-16 ion + constexpr double kEnucleon = 5360.; // GeV per nucleon + constexpr int kA = 16; // Oxygen mass number + constexpr double kOxygenEnergy = kA * kEnucleon / 2.0; // 85760 / 2 GeV + + // Check if each event has two oxygen ions at expected energy + for (int i = 0; i < nEvents; i++) + { + tree->GetEntry(i); + int count = 0; + + for (int idxMCTrack = 0; idxMCTrack < tracks->size(); ++idxMCTrack) + { + auto track = tracks->at(idxMCTrack); + double energy = track.GetEnergy(); + + // 50 MeV tolerance (floating point safety) + if (std::abs(energy - kOxygenEnergy) < 5e-2 && + track.GetPdgCode() == kOxygenPDG) + { + count++; + } + } + + if (count < 2) + { + std::cerr << "Event " << i + << " has less than 2 oxygen ions at " + << kOxygenEnergy << " GeV\n"; + return 1; + } + } + + return 0; +} diff --git a/MC/config/examples/ini/tests/GeneratorEPOS4PbPb.C b/MC/config/examples/ini/tests/GeneratorEPOS4PbPb.C new file mode 100644 index 000000000..3cc43d99c --- /dev/null +++ b/MC/config/examples/ini/tests/GeneratorEPOS4PbPb.C @@ -0,0 +1,60 @@ +int External() +{ + std::string path{"o2sim_Kine.root"}; + // Check that file exists, can be opened and has the correct tree + TFile file(path.c_str(), "READ"); + if (file.IsZombie()) + { + std::cerr << "Cannot open ROOT file " << path << "\n"; + return 1; + } + auto tree = (TTree *)file.Get("o2sim"); + if (!tree) + { + std::cerr << "Cannot find tree o2sim in file " << path << "\n"; + return 1; + } + std::vector *tracks{}; + tree->SetBranchAddress("MCTrack", &tracks); + + // Check if all events are filled + auto nEvents = tree->GetEntries(); + for (Long64_t i = 0; i < nEvents; ++i) + { + tree->GetEntry(i); + if (tracks->empty()) + { + std::cerr << "Empty entry found at event " << i << "\n"; + return 1; + } + } + // Check if there is 1 event, as customly set in the ini file + // Lead-Lead collisions with hydro and hadronic cascade are very slow to simulate + if (nEvents != 1) + { + std::cerr << "Expected 1 event, got " << nEvents << "\n"; + return 1; + } + // check if each event has two lead ions with 557440 (208*5360) GeV of energy + for (int i = 0; i < nEvents; i++) + { + auto check = tree->GetEntry(i); + int count = 0; + for (int idxMCTrack = 0; idxMCTrack < tracks->size(); ++idxMCTrack) + { + auto track = tracks->at(idxMCTrack); + double energy = track.GetEnergy(); + // Check if lead ion track energy is approximately equal to 557440 GeV (a tolerance of 50 MeV is considered, straight equality does not work due to floating point precision) + if (std::abs(energy - 557440) < 5e-2 && track.GetPdgCode() == 1000822080) + { + count++; + } + } + if (count < 2) + { + std::cerr << "Event " << i << " has less than 2 lead ions at 557440 GeV\n"; + return 1; + } + } + return 0; +} \ No newline at end of file diff --git a/MC/config/examples/ini/tests/GeneratorEPOS4_pp13TeV.C b/MC/config/examples/ini/tests/GeneratorEPOS4_pp13TeV.C new file mode 100644 index 000000000..eac9c321b --- /dev/null +++ b/MC/config/examples/ini/tests/GeneratorEPOS4_pp13TeV.C @@ -0,0 +1,64 @@ +int External() +{ + std::string path{"o2sim_Kine.root"}; + // Check that file exists, can be opened and has the correct tree + TFile file(path.c_str(), "READ"); + if (file.IsZombie()) + { + std::cerr << "Cannot open ROOT file " << path << "\n"; + return 1; + } + auto tree = (TTree *)file.Get("o2sim"); + if (!tree) + { + std::cerr << "Cannot find tree o2sim in file " << path << "\n"; + return 1; + } + std::vector *tracks{}; + tree->SetBranchAddress("MCTrack", &tracks); + + // Check if all events are filled + auto nEvents = tree->GetEntries(); + for (Long64_t i = 0; i < nEvents; ++i) + { + tree->GetEntry(i); + if (tracks->empty()) + { + std::cerr << "Empty entry found at event " << i << "\n"; + return 1; + } + } + // Check if there are 100 events, as simulated in the o2dpg-test + if (nEvents != 100) + { + std::cerr << "Expected 100 events, got " << nEvents << "\n"; + return 1; + } + // check if each event has two protons with 6500 GeV of energy + // exits if the particle is not a proton + for (int i = 0; i < nEvents; i++) + { + auto check = tree->GetEntry(i); + int count = 0; + for (int idxMCTrack = 0; idxMCTrack < tracks->size(); ++idxMCTrack) + { + auto track = tracks->at(idxMCTrack); + double energy = track.GetEnergy(); + // Check if track energy is approximately equal to 6500 GeV (a tolerance of 65 keV is considered, straight equality does not work due to floating point precision) + if (std::abs(energy - 6500) < 1e-4) + { + if (track.GetPdgCode() != 2212){ + std::cerr << "Found 6500 GeV particle with pdgID " << track.GetPdgCode() << "\n"; + return 1; + } + count++; + } + } + if (count < 2) + { + std::cerr << "Event " << i << " has less than 2 protons at 6500 GeV\n"; + return 1; + } + } + return 0; +} diff --git a/MC/config/examples/ini/tests/GeneratorExtToHybrid.C b/MC/config/examples/ini/tests/GeneratorExtToHybrid.C new file mode 100644 index 000000000..2694d57e4 --- /dev/null +++ b/MC/config/examples/ini/tests/GeneratorExtToHybrid.C @@ -0,0 +1,38 @@ +int Hybrid() +{ + std::string path{"o2sim_Kine.root"}; + // Check that file exists, can be opened and has the correct tree + TFile file(path.c_str(), "READ"); + if (file.IsZombie()) + { + std::cerr << "Cannot open ROOT file " << path << "\n"; + return 1; + } + auto tree = (TTree *)file.Get("o2sim"); + if (!tree) + { + std::cerr << "Cannot find tree o2sim in file " << path << "\n"; + return 1; + } + std::vector *tracks{}; + tree->SetBranchAddress("MCTrack", &tracks); + + // Check if all events are filled + auto nEvents = tree->GetEntries(); + for (Long64_t i = 0; i < nEvents; ++i) + { + tree->GetEntry(i); + if (tracks->empty()) + { + std::cerr << "Empty entry found at event " << i << "\n"; + return 1; + } + } + // Check if there are 100 events, as simulated in the o2dpg-test + if (nEvents != 100) + { + std::cerr << "Expected 100 events, got " << nEvents << "\n"; + return 1; + } + return 0; +} diff --git a/MC/config/examples/ini/tests/GeneratorExtToHybridParallel.C b/MC/config/examples/ini/tests/GeneratorExtToHybridParallel.C new file mode 100644 index 000000000..2694d57e4 --- /dev/null +++ b/MC/config/examples/ini/tests/GeneratorExtToHybridParallel.C @@ -0,0 +1,38 @@ +int Hybrid() +{ + std::string path{"o2sim_Kine.root"}; + // Check that file exists, can be opened and has the correct tree + TFile file(path.c_str(), "READ"); + if (file.IsZombie()) + { + std::cerr << "Cannot open ROOT file " << path << "\n"; + return 1; + } + auto tree = (TTree *)file.Get("o2sim"); + if (!tree) + { + std::cerr << "Cannot find tree o2sim in file " << path << "\n"; + return 1; + } + std::vector *tracks{}; + tree->SetBranchAddress("MCTrack", &tracks); + + // Check if all events are filled + auto nEvents = tree->GetEntries(); + for (Long64_t i = 0; i < nEvents; ++i) + { + tree->GetEntry(i); + if (tracks->empty()) + { + std::cerr << "Empty entry found at event " << i << "\n"; + return 1; + } + } + // Check if there are 100 events, as simulated in the o2dpg-test + if (nEvents != 100) + { + std::cerr << "Expected 100 events, got " << nEvents << "\n"; + return 1; + } + return 0; +} diff --git a/MC/config/examples/ini/tests/GeneratorHERWIG7.C b/MC/config/examples/ini/tests/GeneratorHERWIG7.C new file mode 100644 index 000000000..384dda574 --- /dev/null +++ b/MC/config/examples/ini/tests/GeneratorHERWIG7.C @@ -0,0 +1,38 @@ +int External() +{ + std::string path{"o2sim_Kine.root"}; + // Check that file exists, can be opened and has the correct tree + TFile file(path.c_str(), "READ"); + if (file.IsZombie()) + { + std::cerr << "Cannot open ROOT file " << path << "\n"; + return 1; + } + auto tree = (TTree *)file.Get("o2sim"); + if (!tree) + { + std::cerr << "Cannot find tree o2sim in file " << path << "\n"; + return 1; + } + std::vector *tracks{}; + tree->SetBranchAddress("MCTrack", &tracks); + + // Check if all events are filled + auto nEvents = tree->GetEntries(); + for (Long64_t i = 0; i < nEvents; ++i) + { + tree->GetEntry(i); + if (tracks->empty()) + { + std::cerr << "Empty entry found at event " << i << "\n"; + return 1; + } + } + // Check if there are 100 events, as simulated in the o2dpg-test + if (nEvents != 100) + { + std::cerr << "Expected 100 events, got " << nEvents << "\n"; + return 1; + } + return 0; +} \ No newline at end of file diff --git a/MC/prodinfo/README.md b/MC/prodinfo/README.md new file mode 100644 index 000000000..af99241b5 --- /dev/null +++ b/MC/prodinfo/README.md @@ -0,0 +1,9 @@ +This directory contains scripts and function to collect, define and upload +CCDB meta data objects for (official) MC productions. + +This meta data can be queried in other stages, such as analysis, for the purpose of further data processing. + +TODO: + +- include cycle number in data +- include software versions (2tag or not) \ No newline at end of file diff --git a/MC/prodinfo/bctvx_evselqa_harvester.py b/MC/prodinfo/bctvx_evselqa_harvester.py new file mode 100755 index 000000000..387abd293 --- /dev/null +++ b/MC/prodinfo/bctvx_evselqa_harvester.py @@ -0,0 +1,312 @@ +#!/usr/bin/env python3 +""" +PyROOT pipeline to: + - parse file paths like ./LHC25as/cpass0/568664/AnalysisResults.root + - choose highest-priority pass per run + - extract histogram event-selection-qa-task/hBcTVX + - hash histogram to prevent duplicates + - write upload ROOT file + - upload using o2-ccdb-upload (or optionally call o2::CcdbApi from C++) + + +Usage: + python3 upload_pipeline.py --file-list files.txt + OR + python3 upload_pipeline.py ./LHC25as/*/*/*/AnalysisResults.root +""" + +import os +import sys +import json +import argparse +import hashlib +import tempfile +import subprocess +from collections import defaultdict + +# PyROOT import +import ROOT +from ROOT import o2 # for O2 access + +# -------- user config ---------- +# priority: earlier in list -> higher priority +PASS_PRIORITY = ["apass6", "apass5", "apass4", "apass3", "apass2", "apass1", "cpass0"] + +# path inside AnalysisResults.root to histogram +HIST_PATH = "event-selection-qa-task/hBcTVX" + +# Local JSON file storing processed histogram hashes to avoid duplicates +PROCESSED_HASH_DB = "processed_hashes.json" + +def getRunInformation(runnumber): + runInfo = o2.parameters.AggregatedRunInfo.buildAggregatedRunInfo(o2.ccdb.BasicCCDBManager.instance(), runnumber) + return {"SOR" : runInfo.sor, + "EOR" : runInfo.eor} + + +def make_ccdb_upload_command(localfile, passname, runnumber, sor, eor, key="ccdb_object"): + l = [ + "o2-ccdb-upload", + "--host", "http://ccdb-test.cern.ch:8080", # <-- adapt to your CCDB server + "--path", "GLO/CALIB/EVSELQA/HBCTVX", # will be filled per-run + "--file", f"{localfile}", # will be replaced with filename + "-k", f"{key}", + "-m", f"run_number={runnumber};pass={passname}", # no extra quotes here (only needed on shell) + "--starttimestamp", f"{sor}", + "--endtimestamp", f"{eor}", + ] + return l # " ".join(l) + +# ------------------------------- +def load_processed_db(path): + if os.path.exists(path): + with open(path, "r") as f: + return json.load(f) + else: + return {"hashes": []} + + +def save_processed_db(path, db): + with open(path, "w") as f: + json.dump(db, f, indent=2) + + +def parse_path_meta(filepath): + """ + Find a pattern *////AnalysisResults.root anywhere in the path. + Returns {period, pass, run}. + + Example accepted paths: + ./LHC25as/cpass0/568664/AnalysisResults.root + /tmp/foo/2023/LHC23zzh/cpass0/544095/AnalysisResults.root + """ + p = os.path.normpath(filepath) + parts = p.split(os.sep) + + # Find the index of AnalysisResults.root + try: + idx = parts.index("AnalysisResults.root") + except ValueError: + # maybe something like analysisresults.root? Lowercase? + # Try case-insensitive fallback + idx = None + for i, comp in enumerate(parts): + if comp.lower() == "analysisresults.root": + idx = i + break + if idx is None: + raise ValueError(f"File does not contain AnalysisResults.root: {filepath}") + + # Need at least 3 dirs before it: period, pass, run + if idx < 3: + raise ValueError(f"Cannot extract period/pass/run from short path: {filepath}") + + run = parts[idx-1] + passname = parts[idx-2] + period = parts[idx-3] + + # Optional sanity checks + if not run.isdigit(): + raise ValueError(f"Run number is not numeric: '{run}' in path {filepath}") + + return {"period": period, "pass": passname, "run": run} + + +def pass_priority_rank(pass_name): + try: + return PASS_PRIORITY.index(pass_name) + except ValueError: + # unknown pass name -> low priority (append at end) + return len(PASS_PRIORITY) + + +def pick_best_pass_file(files_for_run): + """ + files_for_run: list of dicts with keys {pass, path, period} + returns the dict for the chosen file (highest priority) + """ + # sort by priority (lower index -> higher preference) + files_sorted = sorted(files_for_run, key=lambda x: pass_priority_rank(x["pass"])) + return files_sorted[0] if files_sorted else None + + +def histogram_hash(hist): + """ + Deterministic hash of a TH1* content: + - axis nbins, xmin, xmax + - bin contents + bin errors + Returns hex sha256 string. + """ + h = hist + nbins = h.GetNbinsX() + xmin = h.GetXaxis().GetXmin() + xmax = h.GetXaxis().GetXmax() + # collect values + m = hashlib.sha256() + m.update(f"{nbins}|{xmin}|{xmax}|{h.GetName()}|{h.GetTitle()}".encode("utf-8")) + for b in range(0, nbins + 2): # include under/overflow + c = float(h.GetBinContent(b)) + e = float(h.GetBinError(b)) + m.update(f"{b}:{c:.17g}:{e:.17g};".encode("utf-8")) + return m.hexdigest() + + +def extract_histogram_from_file(root_path, hist_path): + """ + Returns a clone of the TH1 found at hist_path or raises on error. + """ + f = ROOT.TFile.Open(root_path, "READ") + if not f or f.IsZombie(): + raise IOError(f"Cannot open file {root_path}") + obj = f.Get(hist_path) + if not obj: + f.Close() + raise KeyError(f"Histogram {hist_path} not found in {root_path}") + if not isinstance(obj, ROOT.TH1): + f.Close() + raise TypeError(f"Object at {hist_path} is not a TH1 (found {type(obj)}) in {root_path}") + # clone to decouple from file and then close file + clone = obj.Clone(obj.GetName()) + clone.SetDirectory(0) + f.Close() + return clone + + +def write_upload_root(hist, meta, outpath): + """ + Writes histogram and metadata (as a TObjString) into a new ROOT file for uploading. + meta: dict of metadata (period, pass, run, runinfo, hash) + """ + f = ROOT.TFile(outpath, "RECREATE") + f.cd() + # set name to include run for clarity + hist_copy = hist.Clone(hist.GetName()) + hist_copy.SetDirectory(f) + hist_copy.Write() + # write metadata as JSON inside TObjString + json_meta = json.dumps(meta) + sobj = ROOT.TObjString(json_meta) + sobj.Write("metadata") + f.Close() + + +def upload_ccdb_via_cli(upload_file, ccdb_path, passname, runnumber, sor, eor): + """ + Call o2-ccdb-upload CLI with CCDB_UPLOAD_CMD template. + Adjust template above for your environment if needed. + """ + cmd = make_ccdb_upload_command(upload_file, passname, runnumber, sor, eor, key="hBcTVX") + print("Running upload command:", " ".join(cmd)) + res = subprocess.run(cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE, text=True) + if res.returncode != 0: + # raise RuntimeError(f"o2-ccdb-upload failed: {res.returncode}\nstdout:{res.stdout}\nstderr:{res.stderr}") + print (f"o2-ccdb-upload failed: {res.returncode}\nstdout:{res.stdout}\nstderr:{res.stderr}") + return False + + print (f"o2-ccdb-upload succeeded: {res.returncode}\nstdout:{res.stdout}\nstderr:{res.stderr}") + return True + + +def main(argv): + parser = argparse.ArgumentParser(description="Extract histogram from AnalysisResults.root and upload to CCDB") + parser.add_argument("--file-list", help="Text file with one file path per line (or '-')", default=None) + parser.add_argument("paths", nargs="*", help="globs or paths to AnalysisResults.root files") + parser.add_argument("--skip-upload", action="store_true", help="Only create upload ROOT files, do not call o2-ccdb-upload") + parser.add_argument("--out-dir", default="ccdb_uploads", help="Where to put temporary upload ROOT files") + parser.add_argument("--processed-db", default=PROCESSED_HASH_DB, help="JSON file to keep processed-hashes") + parser.add_argument("--ccdb-base-path", default="/calibration/hBcTVX", help="Base path inside CCDB where to upload") + args = parser.parse_args(argv) + + # collect files + file_paths = [] + if args.file_list: + if args.file_list == "-": + lines = sys.stdin.read().splitlines() + else: + with open(args.file_list, "r") as f: + lines = [ln.strip() for ln in f if ln.strip()] + file_paths.extend(lines) + if args.paths: + # expand globs + import glob + for p in args.paths: + file_paths.extend(sorted(glob.glob(p))) + if not file_paths: + print("No files provided. Exiting.") + return 1 + + # build per-run grouping + runs = defaultdict(list) + for p in file_paths: + try: + meta = parse_path_meta(p) + except Exception as e: + print(f"Skipping {p}: cannot parse path: {e}") + continue + runs[meta["run"]].append({"path": p, "pass": meta["pass"], "period": meta["period"]}) + + # load processed DB + db = load_processed_db(args.processed_db) + processed_hashes = set(db.get("hashes", [])) + + os.makedirs(args.out_dir, exist_ok=True) + + for run, filelist in runs.items(): + selected = pick_best_pass_file(filelist) + if not selected: + print(f"No candidate for run {run}, skipping.") + continue + path = selected["path"] + period = selected["period"] + pass_name = selected["pass"] + print(f"Selected for run {run}: {path} (period={period}, pass={pass_name})") + + try: + hist = extract_histogram_from_file(path, HIST_PATH) + except Exception as e: + print(f"Failed to extract histogram from {path}: {e}") + continue + + # compute hash + hsh = histogram_hash(hist) + if hsh in processed_hashes: + print(f"Histogram hash {hsh} for run {run} already processed -> skipping upload.") + continue + + # get run information + runinfo = getRunInformation(int(run)) + + # prepare metadata + meta = { + "period": period, + "pass": pass_name, + "run": run, + "runinfo": runinfo, + "hist_name": hist.GetName(), + "hist_title": hist.GetTitle(), + "hash": hsh + } + + # write temporary upload file + out_fname = os.path.join(args.out_dir, f"upload_{period}_{pass_name}_{run}.root") + write_upload_root(hist, meta, out_fname) + print(f"Wrote upload file: {out_fname}") + + # perform upload + if not args.skip_upload: + # build ccdb path (customize to your conventions) + ccdb_path = os.path.join(args.ccdb_base_path, period, pass_name, run) + upload_ccdb_via_cli(out_fname, ccdb_path, pass_name, run, runinfo["SOR"], runinfo["EOR"]) + + # mark as processed (only after successful upload or skip-upload) + processed_hashes.add(hsh) + db["hashes"] = list(processed_hashes) + save_processed_db(args.processed_db, db) + print(f"Marked hash {hsh} as processed.") + + print("Done.") + return 0 + + +if __name__ == "__main__": + sys.exit(main(sys.argv[1:])) diff --git a/MC/prodinfo/mcprodinfo_ccdb_upload.py b/MC/prodinfo/mcprodinfo_ccdb_upload.py new file mode 100644 index 000000000..2de6cfd81 --- /dev/null +++ b/MC/prodinfo/mcprodinfo_ccdb_upload.py @@ -0,0 +1,160 @@ +import json +import os +import requests +import subprocess + +import dataclasses # to define the MCProdInfo data layout and convert it to dict +from dataclasses import dataclass, field, asdict, fields +from typing import Optional +import hashlib + +@dataclass(frozen=True) +class MCProdInfo: + """ + struct for MonteCarlo production info + """ + LPMProductionTag: str + Col: int + IntRate: float # only indicative of some interaction rate (could vary within the run) + RunNumber: int + OrbitsPerTF: int + # max_events_per_tf: Optional[int] = -1 + Comment: Optional[str] = None + McTag: Optional[str] = None # main software tag used + RecoTag: Optional[str] = None # RecoTag (if any) + Hash: Optional[str] = field(default=None) + + def __post_init__(self): + if self.Hash == None: + # Hash only the meaningful fields + data_to_hash = { + k: v for k, v in asdict(self).items() + if k != 'Hash' + } + hash_str = hashlib.sha256( + json.dumps(data_to_hash, sort_keys=True).encode() + ).hexdigest() + object.__setattr__(self, 'Hash', hash_str) + + +import re + +def extract_metadata_blocks_from_CCDB(text: str): + blocks = [] + # Split on 'Metadata:\n' and iterate over each block + sections = text.split('Metadata:\n') + for section in sections[1:]: # skip the first chunk (before any Metadata:) + metadata = {} + for line in section.splitlines(): + if not line.strip(): # stop at first blank line + break + match = re.match(r'\s*(\w+)\s*=\s*(.+)', line) + if match: + key, val = match.groups() + # Type conversion + if val == "None": + val = None + elif val.isdigit() or (val.startswith('-') and val[1:].isdigit()): + val = int(val) + else: + try: + val = float(val) + except ValueError: + val = val.strip() + metadata[key] = val + if metadata: + blocks.append(metadata) + return blocks + + + +def query_mcprodinfo(base_url, user, run_number, lpm_prod_tag, cert_dir="/tmp"): + """ + Queries MCProdInfo from CCDB. Returns object or None + """ + # check if the tokenfiles are there + key_path = os.environ.get("JALIEN_TOKEN_KEY") + cert_path = os.environ.get("JALIEN_TOKEN_CERT") + if key_path == None and cert_path == None: + uid = os.getuid() + cert_path = os.path.join(cert_dir, f"tokencert_{uid}.pem") + key_path = os.path.join(cert_dir, f"tokenkey_{uid}.pem") + + # Build full URL + user_path = 'Users/' + user[0] + '/' + user + start = run_number + stop = run_number + 1 + url = f"{base_url}/browse/{user_path}/MCProdInfo/{lpm_prod_tag}/{start}/{stop}" + + response = requests.get(url, cert=(cert_path, key_path), verify=False) + if response.status_code != 404: + meta = extract_metadata_blocks_from_CCDB(response.content.decode('utf-8')) + if (len(meta) > 0): + def filter_known_fields(cls, data: dict) -> dict: + valid_keys = {f.name for f in fields(cls)} + return {k: v for k, v in data.items() if k in valid_keys} + + clean_meta = filter_known_fields(MCProdInfo, meta[0]) + return MCProdInfo(**clean_meta) + + return None + + +def upload_mcprodinfo_meta(base_url, user, run_number, lpm_prod_tag, keys, cert_dir="/tmp"): + """ + Uploads an empty .dat file using client certificates. + + Parameters: + - base_url (str): The base HTTPS URL, e.g., "https://URL" + - user (str): The uploader --> Determines location "Users/f/foo_bar/MCProdInfo/..." + - keys (dict): Dictionary with meta information to upload, e.g., {"key1": "var1", "key2": "var2"} + - cert_dir (str): Directory where the .pem files are located (default: /tmp) + + Returns: + - Response object from the POST request + """ + # Create an empty file + empty_file = "empty.dat" + with open(empty_file, "w") as f: + f.write("0") + + # Construct user ID-specific cert and key paths + key_path = os.environ.get("JALIEN_TOKEN_KEY") + cert_path = os.environ.get("JALIEN_TOKEN_CERT") + if key_path == None and cert_path == None: + uid = os.getuid() + cert_path = os.path.join(cert_dir, f"tokencert_{uid}.pem") + key_path = os.path.join(cert_dir, f"tokenkey_{uid}.pem") + + # Build full URL + query = "/".join(f"{k}={v}" for k, v in keys.items()) + user_path = 'Users/' + user[0] + '/' + user + start = run_number + stop = run_number + 1 + url = f"{base_url}/{user_path}/MCProdInfo/{lpm_prod_tag}/{start}/{stop}/{query}" + + print (f"Full {url}") + + # Prepare request + with open(empty_file, 'rb') as f: + files = {'blob': f} + response = requests.post(url, files=files, cert=(cert_path, key_path), verify=False) + + # Optional: remove the temporary file + os.remove(empty_file) + + return response + +def publish_MCProdInfo(mc_prod_info, ccdb_url = "https://alice-ccdb.cern.ch", username = "aliprod", force_overwrite=False, include_meta_into_aod=False): + print("Publishing MCProdInfo") + + if mc_prod_info.LPMProductionTag == None or len(mc_prod_info.LPMProductionTag) == 0: + print ("No LPM production tag found; Not publishing") + return + + # see if this already has meta-data uploaded, otherwise do nothing + mc_prod_info_q = query_mcprodinfo(ccdb_url, username, mc_prod_info.RunNumber, mc_prod_info.LPMProductionTag) + if mc_prod_info_q == None or force_overwrite == True: + # could make this depend on hash values in future + upload_mcprodinfo_meta(ccdb_url, username, mc_prod_info.RunNumber, mc_prod_info.LPMProductionTag, dataclasses.asdict(mc_prod_info)) + diff --git a/MC/prodinfo/mcprodinfo_harvester.py b/MC/prodinfo/mcprodinfo_harvester.py new file mode 100755 index 000000000..426bdb767 --- /dev/null +++ b/MC/prodinfo/mcprodinfo_harvester.py @@ -0,0 +1,205 @@ +#!/usr/bin/env python3 + +# A python tool, that fills CCDB MCProdInfo by +# harvesting the data from production log files from the GRID. +# This is useful, when the information was not directly filled +# by the MC job itself. + +import json +import subprocess +import sys +from collections import defaultdict +from zipfile import ZipFile +import re +import os +import argparse + +from mcprodinfo_ccdb_upload import MCProdInfo, publish_MCProdInfo + + +def alien_find(path, pattern="*"): + cmd = ["alien.py", "find", path, pattern] + result = subprocess.run(cmd, capture_output=True, text=True, check=True) + return [line.strip() for line in result.stdout.splitlines() if line.strip()] + + +def alien_cp(alien_path, local_path): + cmd = ["alien.py", "cp", f"alien://{alien_path}", f"file://{local_path}"] + subprocess.run(cmd, stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL, check=True) + + +def parse_workflow_path(path, prod_tag): + parts = path.strip("/").split("/") + try: + idx = parts.index(prod_tag) + except ValueError: + return None + + after = parts[idx + 1 :] + if len(after) < 2: + return None + + if after[0].isdigit() and len(after[0]) == 1: + cycle = int(after[0]) + run_number = int(after[1]) + split = after[2] + else: + cycle = None + run_number = int(after[0]) + split = after[1] + + return cycle, run_number, split + + +def extract_from_zip(local_zip_path): + """Extract workflow.json and stdout from log_archive.zip.""" + wf_data = None + env_vars = {} + try: + with ZipFile(local_zip_path, "r") as zf: + # workflow.json + if "workflow.json" in zf.namelist(): + with zf.open("workflow.json") as wf_file: + wf_data = json.load(wf_file) + + # stdout (could be named stdout or stdout.log) + candidates = [n for n in zf.namelist() if n.startswith("stdout")] + if candidates: + with zf.open(candidates[0]) as so: + text = so.read().decode(errors="ignore") + for key in [ + "ALIEN_JDL_PACKAGES", + "ALIEN_JDL_O2DPG_ASYNC_RECO_TAG", + "ALIEN_MASTERJOB", + ]: + m = re.search(rf"{key}=(.*)", text) + if m: + env_vars[key] = m.group(1).strip() + except Exception as e: + print(f"⚠️ Failed to extract from {local_zip_path}: {e}") + return wf_data, env_vars + + +def build_info(prod_tag, run_number, wf_data, env_vars): + meta=wf_data.get("meta") + if meta != None: + int_rate = meta.get("interactionRate") + col_system = meta.get("col") + orbits_per_tf = meta.get("orbitsPerTF") + + return MCProdInfo( + LPMProductionTag=prod_tag, + Col=col_system, + IntRate=int_rate, + RunNumber=run_number, + OrbitsPerTF=orbits_per_tf, + McTag=env_vars.get("ALIEN_JDL_PACKAGES"), + RecoTag=env_vars.get("ALIEN_JDL_O2DPG_ASYNC_RECO_TAG") + ) + + +def pick_split(prod_tag, run_number, candidates, ascending=True): + """Pick the first valid split (min if ascending, max if not).""" + def split_key(entry): + _, split, _ = entry + try: + return int(split) + except ValueError: + return float("inf") + + candidates_sorted = sorted(candidates, key=split_key, reverse=not ascending) + + for cycle, split, zip_path in candidates_sorted: + print (f"Trying to analyse {zip_path}") + local_zip = f"/tmp/log_archive_{run_number}_{cycle or 0}_{split}.zip" + try: + alien_cp(zip_path, local_zip) + except subprocess.CalledProcessError: + continue + + wf_data, env_vars = extract_from_zip(local_zip) + + try: + os.remove(local_zip) # cleanup downloaded file + except OSError: + pass + + if wf_data: + info = build_info(prod_tag, run_number, wf_data, env_vars) + return info, cycle, split, zip_path + print (f"Failed") + + return None, None, None, None + + +def process_prod_tag(prod_tag, year="2025", ccdb_url=None, username=None, overwrite=False): + base_path = f"/alice/sim/{year}/{prod_tag}" + + workflow_files = alien_find(base_path, "workflow.json") + # exclude some unnecessary paths + workflow_files = [ + zf for zf in workflow_files + if "/AOD/" not in zf and "/QC/" not in zf and "/TimeseriesTPCmerging/" not in zf and "/Stage" not in zf + ] + # directories containing workflow.json + workflow_dirs = {os.path.dirname(wf) for wf in workflow_files} + print (f"Found {len(workflow_dirs)} workflow dirs") + + # Step 1: find all log_archive.zip files + print (f"Querying AliEn for all directories with zip files") + zip_files = alien_find(base_path, "log_archive.zip") + + # exclude some unnecessary paths + zip_files = [ + zf for zf in zip_files + if "/AOD/" not in zf and "/QC/" not in zf and "/TimeseriesTPCmerging/" not in zf and "/Stage" not in zf + ] + zip_files_dirs = {os.path.dirname(zf) for zf in zip_files} + print (f"Found {len(zip_files_dirs)} zip dirs") + + # keep only zips in dirs where workflow.json also exists + relevant_zips = [zf for zf in zip_files if os.path.dirname(zf) in workflow_dirs] + + # Step 2: group by run_number + runs = defaultdict(list) + for zf in relevant_zips: + parsed = parse_workflow_path(zf, prod_tag) + if parsed is None: + continue + cycle, run_number, split = parsed + runs[run_number].append((cycle, split, zf)) + + print(f"Found {len(runs)} run numbers") + + # Step 3: for each run_number, handle smallest and largest valid split + for run_number, candidates in sorted(runs.items()): + print (f"Analysing run {run_number}") + info_min, cycle_min, split_min, _ = pick_split(prod_tag, run_number, candidates, ascending=True) + info_max, cycle_max, split_max, _ = pick_split(prod_tag, run_number, candidates, ascending=False) + + # some consistency checks + if info_min and info_max: + if info_min.Col != info_max.Col: + print(f"❌ ColSystem mismatch for run {run_number}") + if info_min.OrbitsPerTF != info_max.OrbitsPerTF: + print(f"❌ OrbitsPerTF mismatch for run {run_number}") + + publish_MCProdInfo(info_min, username=username, ccdb_url=ccdb_url, force_overwrite=overwrite) + print (info_min) + + +def main(): + parser = argparse.ArgumentParser( + description="Harvest MC production metadata from AlienGRID and publish to CCDB" + ) + parser.add_argument("--prod_tag", required=True, help="Production tag (e.g. prod2025a)") + parser.add_argument("--ccdb", required=False, default="https://alice-ccdb.cern.ch", help="CCDB server URL") + parser.add_argument("--username", required=False, help="GRID username (needs appropriate AliEn token initialized)") + parser.add_argument("--year", default="2025", help="Production year (default: 2025)") + parser.add_argument("--overwrite", action="store_true", help="Overwrite existing entries") + args = parser.parse_args() + + process_prod_tag(args.prod_tag, year=args.year, ccdb_url=args.ccdb, username=args.username, overwrite=args.overwrite) + +if __name__ == "__main__": + main() diff --git a/MC/run/ANCHOR/anchor-dpl-options-blacklist.json b/MC/run/ANCHOR/anchor-dpl-options-blacklist.json new file mode 100644 index 000000000..f224be858 --- /dev/null +++ b/MC/run/ANCHOR/anchor-dpl-options-blacklist.json @@ -0,0 +1,46 @@ +{ + "__comment__" : "Options (per dpl workflow) *not* to be transfered from async-reco to MC workflows.", + "global": [ + "--pipeline", + "--disable-mc", + "--loop" + ], + "o2-aod-producer-workflow": [ + "--reco-pass", + "--aod-writer-maxfilesize" + ], + "o2-its-reco-workflow": [ + "--digits-from-upstream" + ], + "o2-tof-reco-workflow": [ + "--input-type", + "--output-type", + "--local-cmp" + ], + "o2-tof-matcher-workflow": [ + "--use-fit", + "--tof-lanes", + "--output-type", + "--enable-dia" + ], + "o2-mft-reco-workflow": [ + "--digits-from-upstream", + "--nThreads" + ], + "o2-emcal-cell-recalibrator-workflow": [ + "--redirect-led" + ], + "o2-phos-reco-workflow": [ + "--input-type", + "--output-type" + ], + "o2-trd-global-tracking" : [ + "--enable-ph" + ], + "o2-trd-tracklet-transformer" : [ + "--disable-irframe-reader" + ], + "o2-tpcits-match-workflow" : [ + "--nthreads" + ] +} \ No newline at end of file diff --git a/MC/run/ANCHOR/anchorMC.sh b/MC/run/ANCHOR/anchorMC.sh index b114ac8c4..9425f8dfb 100755 --- a/MC/run/ANCHOR/anchorMC.sh +++ b/MC/run/ANCHOR/anchorMC.sh @@ -45,22 +45,23 @@ print_help() echo echo "as well as:" echo "NTIMEFRAMES," - echo "NSIGEVENTS," echo "SPLITID," - echo "CYCLE," echo "PRODSPLIT." echo echo "Optional are:" echo "ALIEN_JDL_CPULIMIT or CPULIMIT, set the CPU limit of the workflow runner, default: 8," echo "NWORKERS, set the number of workers during detector transport, default: 8," echo "ALIEN_JDL_SIMENGINE or SIMENGINE, choose the transport engine, default: TGeant4," - echo "ALIEN_JDL_WORKFLOWDETECTORS, set detectors to be taken into account, default: ITS,TPC,TOF,FV0,FT0,FDD,MID,MFT,MCH,TRD,EMC,PHS,CPV,HMP,CTP," + echo "ALIEN_JDL_WORKFLOWDETECTORS, set detectors to be taken into account, default: not-used (take the ones from async-reco)" echo "ALIEN_JDL_ANCHOR_SIM_OPTIONS, additional options that are passed to the workflow creation, default: -gen pythia8," echo "ALIEN_JDL_ADDTIMESERIESINMC, run TPC time series. Default: 1, switch off by setting to 0," echo "ALIEN_JDL_MC_ORBITS_PER_TF=N, enforce some orbits per timeframe, instead of determining from CCDB" echo "ALIEN_JDL_RUN_TIME_SPAN_FILE=FILE, use a run-time-span file to exclude bad data-taking periods" echo "ALIEN_JDL_INVERT_IRFRAME_SELECTION, invertes the choice of ALIEN_JDL_RUN_TIME_SPAN_FILE" + echo "ALIEN_JDL_CCDB_CONDITION_NOT_AFTER, sets the condition_not_after timestamp for CCDB queries" echo "DISABLE_QC, set this to disable QC, e.g. to 1" + echo "CYCLE, to set a cycle number different than 0" + echo "NSIGEVENTS, to enforce a specific upper limit of events in a timeframe (not counting orbit-early) events" } # Prevent the script from being soured to omit unexpected surprises when exit is used @@ -102,7 +103,6 @@ alien-token-info >/dev/null 2>&1 # the only four where there is a real default for export ALIEN_JDL_CPULIMIT=${ALIEN_JDL_CPULIMIT:-${CPULIMIT:-8}} export ALIEN_JDL_SIMENGINE=${ALIEN_JDL_SIMENGINE:-${SIMENGINE:-TGeant4}} -export ALIEN_JDL_WORKFLOWDETECTORS=${ALIEN_JDL_WORKFLOWDETECTORS:-ITS,TPC,TOF,FV0,FT0,FDD,MID,MFT,MCH,TRD,EMC,PHS,CPV,HMP,CTP} # can be passed to contain additional options that will be passed to o2dpg_sim_workflow_anchored.py and eventually to o2dpg_sim_workflow.py export ALIEN_JDL_ANCHOR_SIM_OPTIONS=${ALIEN_JDL_ANCHOR_SIM_OPTIONS:--gen pythia8} # all others MUST be set by the user/on the outside @@ -119,12 +119,7 @@ export ALIEN_JDL_LPMANCHORYEAR=${ALIEN_JDL_LPMANCHORYEAR:-${ANCHORYEAR}} # decide whether to run TPC time series; on by default, switched off by setting to 0 export ALIEN_JDL_ADDTIMESERIESINMC=${ALIEN_JDL_ADDTIMESERIESINMC:-1} -# cache the production tag, will be set to a special anchor tag; reset later in fact -ALIEN_JDL_LPMPRODUCTIONTAG_KEEP=$ALIEN_JDL_LPMPRODUCTIONTAG -echo_info "Substituting ALIEN_JDL_LPMPRODUCTIONTAG=$ALIEN_JDL_LPMPRODUCTIONTAG with ALIEN_JDL_LPMANCHORPRODUCTION=$ALIEN_JDL_LPMANCHORPRODUCTION for simulating reco pass..." -ALIEN_JDL_LPMPRODUCTIONTAG=$ALIEN_JDL_LPMANCHORPRODUCTION - -# check variables that need to be set +# check for presence of essential variables that need to be set [ -z "${ALIEN_JDL_LPMANCHORPASSNAME}" ] && { echo_error "Set ALIEN_JDL_LPMANCHORPASSNAME or ANCHORPASSNAME" ; exit 1 ; } [ -z "${ALIEN_JDL_LPMRUNNUMBER}" ] && { echo_error "Set ALIEN_JDL_LPMRUNNUMBER or RUNNUMBER" ; exit 1 ; } [ -z "${ALIEN_JDL_LPMPRODUCTIONTYPE}" ] && { echo_error "Set ALIEN_JDL_LPMPRODUCTIONTYPE or PRODUCTIONTYPE" ; exit 1 ; } @@ -135,11 +130,40 @@ ALIEN_JDL_LPMPRODUCTIONTAG=$ALIEN_JDL_LPMANCHORPRODUCTION [ -z "${ALIEN_JDL_LPMANCHORYEAR}" ] && { echo_error "Set ALIEN_JDL_LPMANCHORYEAR or ANCHORYEAR" ; exit 1 ; } [ -z "${NTIMEFRAMES}" ] && { echo_error "Set NTIMEFRAMES" ; exit 1 ; } -[ -z "${NSIGEVENTS}" ] && { echo_error "Set NSIGEVENTS" ; exit 1 ; } [ -z "${SPLITID}" ] && { echo_error "Set SPLITID" ; exit 1 ; } -[ -z "${CYCLE}" ] && { echo_error "Set CYCLE" ; exit 1 ; } [ -z "${PRODSPLIT}" ] && { echo_error "Set PRODSPLIT" ; exit 1 ; } + +# cache the production tag, will be set to a special anchor tag; reset later in fact +ALIEN_JDL_LPMPRODUCTIONTAG_KEEP=$ALIEN_JDL_LPMPRODUCTIONTAG +echo_info "Substituting ALIEN_JDL_LPMPRODUCTIONTAG=$ALIEN_JDL_LPMPRODUCTIONTAG with ALIEN_JDL_LPMANCHORPRODUCTION=$ALIEN_JDL_LPMANCHORPRODUCTION for simulating reco pass..." +ALIEN_JDL_LPMPRODUCTIONTAG=$ALIEN_JDL_LPMANCHORPRODUCTION + +if [[ $ALIEN_JDL_ANCHOR_SIM_OPTIONS == *"--tpc-distortion-type 2"* ]]; then + export O2DPG_ENABLE_TPC_DISTORTIONS=ON + # set the SCALING SOURCE to CTP for MC unless explicitely given from outside + export ALIEN_JDL_TPCSCALINGSOURCE=${ALIEN_JDL_TPCSCALINGSOURCE:-"CTP"} +fi + + +# The number of signal events can be given, but should be useful only in +# certain expert modes. In the default case, the final event number is determined by the timeframe length. +if [ -z "${NSIGEVENTS}" ]; then + NSIGEVENTS=10000 # this is just some big number; In the simulation the event number is the minimum of this number and what fits into a single timeframe + # based on the interaction rate. The number is a reasonable upper limit related to ~5696 collisions that fit into 32 LHC orbits at 2MHz interaction rate. +fi + +if [ -z "${CYCLE}" ]; then + echo_info "No CYCLE number given ... defaulting to 0" + CYCLE=0 +fi + +# this generates an exact reproducer script for this job +# that can be used locally for debugging etc. +if [[ -n "${ALIEN_PROC_ID}" && -n "${JALIEN_WSPORT}" ]]; then + ${O2DPG_ROOT}/GRID/utils/getReproducerScript.sh ${ALIEN_PROC_ID} +fi + # also for this keep a real default NWORKERS=${NWORKERS:-8} # set a default seed if not given @@ -148,7 +172,7 @@ SEED=${ALIEN_PROC_ID:-${SEED:-1}} ONCVMFS=0 if [ "${ALIEN_JDL_O2DPG_OVERWRITE}" ]; then - echo "Setting O2DPG_ROOT to overwritten path" + echo "Setting O2DPG_ROOT to overwritten path ${ALIEN_JDL_O2DPG_OVERWRITE}" export O2DPG_ROOT=${ALIEN_JDL_O2DPG_OVERWRITE} fi @@ -174,11 +198,12 @@ fi #<----- START OF part that should run under a clean alternative software environment if this was given ------ if [ "${ALIEN_JDL_O2DPG_ASYNC_RECO_TAG}" ]; then if [ "${LOADEDMODULES}" ]; then + printenv > env_before_stashing.printenv echo "Stashing initial modules" module save initial_modules.list # we stash the current modules environment module list --no-pager module purge --no-pager - export > env_after_stashing.env + printenv > env_after_stashing.printenv echo "Modules after purge" module list --no-pager fi @@ -214,10 +239,6 @@ chmod u+x setenv_extra.sh echo_info "Setting up DPGRECO to ${DPGRECO}" -# settings that are MC-specific, modify setenv_extra.sh in-place -sed -i 's/GPU_global.dEdxUseFullGainMap=1;GPU_global.dEdxDisableResidualGainMap=1/GPU_global.dEdxSplineTopologyCorrFile=splines_for_dedx_V1_MC_iter0_PP.root;GPU_global.dEdxDisableTopologyPol=1;GPU_global.dEdxDisableGainMap=1;GPU_global.dEdxDisableResidualGainMap=1;GPU_global.dEdxDisableResidualGain=1/' setenv_extra.sh -### ??? - # take out line running the workflow (if we don't have data input) [ ${CTF_TEST_FILE} ] || sed -i '/WORKFLOWMODE=run/d' async_pass.sh @@ -232,23 +253,18 @@ RECO_RC=$? echo_info "async_pass.sh finished with ${RECO_RC}" if [[ "${RECO_RC}" != "0" ]] ; then - exit ${RECO_RC} + exit ${RECO_RC} fi - -ALIEN_JDL_LPMPRODUCTIONTAG=$ALIEN_JDL_LPMPRODUCTIONTAG_KEEP -echo_info "Setting back ALIEN_JDL_LPMPRODUCTIONTAG to $ALIEN_JDL_LPMPRODUCTIONTAG" - -# now create the local MC config file --> config-config.json -${O2DPG_ROOT}/UTILS/parse-async-WorkflowConfig.py -ASYNC_WF_RC=${?} - -# check if config reasonably created -if [[ "${ASYNC_WF_RC}" != "0" || `grep "o2-ctf-reader-workflow-options" config-json.json 2> /dev/null | wc -l` == "0" ]]; then - echo_error "Problem in anchor config creation. Exiting." +# check that workflowconfig.log was created correctly +if [[ ! -f workflowconfig.log ]]; then + echo "Workflowconfig.log file not found" exit 1 fi +export ALIEN_JDL_LPMPRODUCTIONTAG=$ALIEN_JDL_LPMPRODUCTIONTAG_KEEP +echo_info "Setting back ALIEN_JDL_LPMPRODUCTIONTAG to $ALIEN_JDL_LPMPRODUCTIONTAG" + # get rid of the temporary software environment if [ "${ALIEN_JDL_O2DPG_ASYNC_RECO_TAG}" ]; then module purge --no-pager @@ -256,23 +272,52 @@ if [ "${ALIEN_JDL_O2DPG_ASYNC_RECO_TAG}" ]; then echo "Restoring initial environment" module --no-pager restore initial_modules.list module saverm initial_modules.list - if [ "${ALIEN_JDL_O2DPG_OVERWRITE}" ]; then - echo "Setting back O2DPG_ROOT to overwritten path ${ALIEN_JDL_O2DPG_OVERWRITE}" - export O2DPG_ROOT=${ALIEN_JDL_O2DPG_OVERWRITE} - fi + + # Restore overwritten O2DPG variables set by modules but changed by user + # (in particular custom O2DPG_ROOT and O2DPG_MC_CONFIG_ROOT) + # We must avoid piping into a while loop (otherwise the internal export is executed in sub-shell) + printenv > env_after_restore.printenv + while read -r var; do + b=$(grep "^$var=" env_before_stashing.printenv | cut -d= -f2-) + a=$(grep "^$var=" env_after_restore.printenv | cut -d= -f2-) + [[ "$b" != "$a" ]] && export "$var=$b" && echo "Reapplied: $var to ${b}" + done < <( + comm -12 \ + <(grep '^O2DPG' env_before_stashing.printenv | cut -d= -f1 | sort) \ + <(grep '^O2DPG' env_after_restore.printenv | cut -d= -f1 | sort)) + fi #<----- END OF part that should run under a clean alternative software environment if this was given ------ +# now create the local MC config file --> config-json.json +# we create the new config output with blacklist functionality +ASYNC_CONFIG_BLACKLIST=${ASYNC_CONFIG_BLACKLIST:-${O2DPG_ROOT}/MC/run/ANCHOR/anchor-dpl-options-blacklist.json} +${O2DPG_ROOT}/MC/bin/o2dpg_dpl_config_tools.py workflowconfig.log ${ASYNC_CONFIG_BLACKLIST} config-json.json +ASYNC_WF_RC=${?} + +# check if config reasonably created +if [[ "${ASYNC_WF_RC}" != "0" || `grep "ConfigParams" config-json.json 2> /dev/null | wc -l` == "0" ]]; then + echo_error "Problem in anchor config creation. Exiting." + exit 1 +fi + # -- CREATE THE MC JOB DESCRIPTION ANCHORED TO RUN -- MODULES="--skipModules ZDC" -# Since this is used, set it explicitly -ALICEO2_CCDB_LOCALCACHE=${ALICEO2_CCDB_LOCALCACHE:-$(pwd)/ccdb} + +# publish MCPRODINFO for first few jobs of a production +# if external script exported PUBLISH_MCPRODINFO, it will be published anyways +if [ -z "$PUBLISH_MCPRODINFO" ] && [ "$SPLITID" -lt 20 ]; then + PUBLISH_MCPRODINFO_OPTION="--publish-mcprodinfo" + echo "Will publish MCProdInfo" +else + echo "Will not publish MCProdInfo" +fi # these arguments will be digested by o2dpg_sim_workflow_anchored.py baseargs="-tf ${NTIMEFRAMES} --split-id ${SPLITID} --prod-split ${PRODSPLIT} --cycle ${CYCLE} --run-number ${ALIEN_JDL_LPMRUNNUMBER} \ ${ALIEN_JDL_RUN_TIME_SPAN_FILE:+--run-time-span-file ${ALIEN_JDL_RUN_TIME_SPAN_FILE} ${ALIEN_JDL_INVERT_IRFRAME_SELECTION:+--invert-irframe-selection}} \ - ${ALIEN_JDL_MC_ORBITS_PER_TF:+--orbitsPerTF ${ALIEN_JDL_MC_ORBITS_PER_TF}}" + ${ALIEN_JDL_MC_ORBITS_PER_TF:+--orbitsPerTF ${ALIEN_JDL_MC_ORBITS_PER_TF}} ${PUBLISH_MCPRODINFO_OPTION}" # these arguments will be passed as well but only eventually be digested by o2dpg_sim_workflow.py which is called from o2dpg_sim_workflow_anchored.py remainingargs="-seed ${SEED} -ns ${NSIGEVENTS} --include-local-qc --pregenCollContext" @@ -282,7 +327,11 @@ remainingargs="${remainingargs} -productionTag ${ALIEN_JDL_LPMPRODUCTIONTAG:-ali # since the last passed argument wins, e.g. -productionTag cannot be overwritten by the user remainingargs="${ALIEN_JDL_ANCHOR_SIM_OPTIONS} ${remainingargs} --anchor-config config-json.json" # apply software tagging choice -remainingargs="${remainingargs} ${ALIEN_JDL_O2DPG_ASYNC_RECO_TAG:+--alternative-reco-software ${ALIEN_JDL_O2DPG_ASYNC_RECO_TAG}}" +# remainingargs="${remainingargs} ${ALIEN_JDL_O2DPG_ASYNC_RECO_TAG:+--alternative-reco-software ${ALIEN_JDL_O2DPG_ASYNC_RECO_TAG}}" +ALIEN_JDL_O2DPG_ASYNC_RECO_FROMSTAGE=${ALIEN_JDL_O2DPG_ASYNC_RECO_FROMSTAGE:-RECO} +remainingargs="${remainingargs} ${ALIEN_JDL_O2DPG_ASYNC_RECO_TAG:+--alternative-reco-software ${PWD}/env_async.env@${ALIEN_JDL_O2DPG_ASYNC_RECO_FROMSTAGE}}" +# potentially add CCDB timemachine timestamp +remainingargs="${remainingargs} ${ALIEN_JDL_CCDB_CONDITION_NOT_AFTER:+--condition-not-after ${ALIEN_JDL_CCDB_CONDITION_NOT_AFTER}}" echo_info "baseargs passed to o2dpg_sim_workflow_anchored.py: ${baseargs}" echo_info "remainingargs forwarded to o2dpg_sim_workflow.py: ${remainingargs}" @@ -299,6 +348,9 @@ fi TIMESTAMP=`grep "Determined timestamp to be" ${anchoringLogFile} | awk '//{print $6}'` echo_info "TIMESTAMP IS ${TIMESTAMP}" +if [ "${ONLY_WORKFLOW_CREATION}" ]; then + exit 0 +fi # check if this job is exluded because it falls inside a bad data-taking period ISEXCLUDED=$(grep "TIMESTAMP IS EXCLUDED IN RUN" ${anchoringLogFile}) @@ -309,53 +361,48 @@ if [ "${ISEXCLUDED}" ]; then exit 0 fi -# -- Create aligned geometry using ITS ideal alignment to avoid overlaps in geant -CCDBOBJECTS_IDEAL_MC="ITS/Calib/Align" -TIMESTAMP_IDEAL_MC=1 -${O2_ROOT}/bin/o2-ccdb-downloadccdbfile --host http://alice-ccdb.cern.ch/ -p ${CCDBOBJECTS_IDEAL_MC} -d ${ALICEO2_CCDB_LOCALCACHE} --timestamp ${TIMESTAMP_IDEAL_MC} -CCDB_RC="${?}" -if [ ! "${CCDB_RC}" == "0" ]; then - echo_error "Problem during CCDB prefetching of ${CCDBOBJECTS_IDEAL_MC}. Exiting." - exit ${CCDB_RC} -fi - -# TODO This can potentially be removed or if needed, should be taken over by o2dpg_sim_workflow_anchored.py and O2_dpg_workflow_runner.py -echo "run with echo in pipe" | ${O2_ROOT}/bin/o2-create-aligned-geometry-workflow --configKeyValues "HBFUtils.startTime=${TIMESTAMP}" --condition-remap=file://${ALICEO2_CCDB_LOCALCACHE}=ITS/Calib/Align -b --run -mkdir -p $ALICEO2_CCDB_LOCALCACHE/GLO/Config/GeometryAligned -ln -s -f $PWD/o2sim_geometry-aligned.root $ALICEO2_CCDB_LOCALCACHE/GLO/Config/GeometryAligned/snapshot.root -[[ -f $PWD/its_GeometryTGeo.root ]] && mkdir -p $ALICEO2_CCDB_LOCALCACHE/ITS/Config/Geometry && ln -s -f $PWD/its_GeometryTGeo.root $ALICEO2_CCDB_LOCALCACHE/ITS/Config/Geometry/snapshot.root -[[ -f $PWD/mft_GeometryTGeo.root ]] && mkdir -p $ALICEO2_CCDB_LOCALCACHE/MFT/Config/Geometry && ln -s -f $PWD/mft_GeometryTGeo.root $ALICEO2_CCDB_LOCALCACHE/MFT/Config/Geometry/snapshot.root - -# -- RUN THE MC WORKLOAD TO PRODUCE AOD -- +# -- RUN THE MC WORKLOAD TO PRODUCE TARGETS -- export FAIRMQ_IPC_PREFIX=./ echo_info "Ready to start main workflow" -${O2DPG_ROOT}/MC/bin/o2_dpg_workflow_runner.py -f workflow.json -tt ${ALIEN_JDL_O2DPGWORKFLOWTARGET:-aod} --cpu-limit ${ALIEN_JDL_CPULIMIT:-8} --dynamic-resources -MCRC=$? # <--- we'll report back this code -if [[ "${ALIEN_JDL_ADDTIMESERIESINMC}" != "0" ]]; then - # Default value is 1 so this is run by default. - echo_info "Running TPC time series" - ${O2DPG_ROOT}/MC/bin/o2_dpg_workflow_runner.py -f workflow.json -tt tpctimes +# Let us construct the workflow targets +targetString="" +if [ "${ALIEN_JDL_O2DPGWORKFLOWTARGET}" ]; then + # The user gave ${ALIEN_JDL_O2DPGWORKFLOWTARGET}. This is an expert mode not used in production. + # In this case, we will build just that. No QC, no TPC timeseries, ... + targetString=${ALIEN_JDL_O2DPGWORKFLOWTARGET} +else + targetString="'aodmerge.*'" + # Now add more targets depending on options + # -) The TPC timeseries targets + if [[ "${ALIEN_JDL_ADDTIMESERIESINMC}" == "1" ]]; then + targetString="${targetString} 'tpctimes.*'" + fi + # -) TPC residual calibration + if [ "${ALIEN_JDL_DOTPCRESIDUALEXTRACTION}" ]; then + targetString="${targetString} 'tpcresidmerge.*'" + fi + # -) QC tasks + if [[ -z "${DISABLE_QC}" && "${remainingargs}" == *"--include-local-qc"* ]]; then + targetString="${targetString} '^.*QC.*'" # QC tasks should have QC in the name + fi fi +echo_info "Workflow will run with target specification ${targetString}" -[[ ! -z "${DISABLE_QC}" ]] && echo_info "QC is disabled, skip it." +${O2DPG_ROOT}/MC/bin/o2_dpg_workflow_runner.py -f workflow.json -tt ${targetString} \ + --cpu-limit ${ALIEN_JDL_CPULIMIT:-8} --dynamic-resources \ + ${ALIEN_O2DPG_FILEGRAPH:+--remove-files-early ${ALIEN_O2DPG_FILEGRAPH}} \ + ${ALIEN_O2DPG_ADDITIONAL_WORKFLOW_RUNNER_ARGS} -if [[ -z "${DISABLE_QC}" && "${MCRC}" = "0" && "${remainingargs}" == *"--include-local-qc"* ]] ; then - # do QC tasks - echo_info "Doing QC" - ${O2DPG_ROOT}/MC/bin/o2_dpg_workflow_runner.py -f workflow.json --target-labels QC --cpu-limit ${ALIEN_JDL_CPULIMIT:-8} -k - # NOTE that with the -k|--keep-going option, the runner will try to keep on executing even if some tasks fail. - # That means, even if there is a failing QC task, the return code will be 0 - MCRC=$? -fi +MCRC=$? # <--- we'll report back this code # # full logs tar-ed for output, regardless the error code or validation - to catch also QC logs... # if [[ -n "$ALIEN_PROC_ID" ]]; then - find ./ \( -name "*.log*" -o -name "*mergerlog*" -o -name "*serverlog*" -o -name "*workerlog*" -o -name "pythia8.cfg" \) | tar -czvf debug_log_archive.tgz -T - + find ./ \( -name "*.log*" -o -name "*mergerlog*" -o -name "*serverlog*" -o -name "*workerlog*" -o -name "pythia8.cfg" -o -name "reproducer*.sh" \) | tar -czvf debug_log_archive.tgz -T - if [[ "$ALIEN_JDL_CREATE_TAR_IN_MC" == "1" ]]; then find ./ \( -name "*.log*" -o -name "*mergerlog*" -o -name "*serverlog*" -o -name "*workerlog*" -o -name "*.root" \) | tar -czvf debug_full_archive.tgz -T - fi diff --git a/MC/run/ANCHOR/anchorMC_DataEmbedding.sh b/MC/run/ANCHOR/anchorMC_DataEmbedding.sh new file mode 100755 index 000000000..80cb1daae --- /dev/null +++ b/MC/run/ANCHOR/anchorMC_DataEmbedding.sh @@ -0,0 +1,471 @@ +#!/bin/bash + +# add distortion maps +# https://alice.its.cern.ch/jira/browse/O2-3346?focusedCommentId=300982&page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel#comment-300982 +# +# export O2DPG_ENABLE_TPC_DISTORTIONS=ON +# SCFile=$PWD/distortions_5kG_lowIR.root # file needs to be downloaded +# export O2DPG_TPC_DIGIT_EXTRA=" --distortionType 2 --readSpaceCharge ${SCFile} " + +# +# procedure setting up and executing an anchored MC +# + +######################## +# helper functionality # +######################## + +echo_info() +{ + echo "INFO [anchorMC]: ${*}" +} + +echo_error() +{ + echo "ERROR [anchorMC]: ${*}" +} + +print_help() +{ + echo "Usage: ./anchorMC.sh" + echo + echo "This needs O2 and O2DPG loaded from alienv." + echo + echo "Make sure the following env variables are set:" + echo "ALIEN_JDL_LPMANCHORPASSNAME or ANCHORPASSNAME," + echo "ALIEN_JDL_MCANCHOR or MCANCHOR," + echo "ALIEN_JDL_LPMPASSNAME or PASSNAME," + echo "ALIEN_JDL_LPMRUNNUMBER or RUNNUMBER," + echo "ALIEN_JDL_LPMPRODUCTIONTYPE or PRODUCTIONTYPE," + echo "ALIEN_JDL_LPMINTERACTIONTYPE or INTERACTIONTYPE," + echo "ALIEN_JDL_LPMPRODUCTIONTAG or PRODUCTIONTAG," + echo "ALIEN_JDL_LPMANCHORRUN or ANCHORRUN," + echo "ALIEN_JDL_LPMANCHORPRODUCTION or ANCHORPRODUCTION," + echo "ALIEN_JDL_LPMANCHORYEAR or ANCHORYEAR," + echo + echo "as well as:" + echo "NTIMEFRAMES," + echo "SPLITID," + echo "PRODSPLIT." + echo + echo "Optional are:" + echo "ALIEN_JDL_CPULIMIT or CPULIMIT, set the CPU limit of the workflow runner, default: 8," + echo "NWORKERS, set the number of workers during detector transport, default: 8," + echo "ALIEN_JDL_SIMENGINE or SIMENGINE, choose the transport engine, default: TGeant4," + echo "ALIEN_JDL_WORKFLOWDETECTORS, set detectors to be taken into account, default: not-used (take the ones from async-reco)" + echo "ALIEN_JDL_ANCHOR_SIM_OPTIONS, additional options that are passed to the workflow creation, default: -gen pythia8," + echo "ALIEN_JDL_ADDTIMESERIESINMC, run TPC time series. Default: 1, switch off by setting to 0," + echo "ALIEN_JDL_MC_ORBITS_PER_TF=N, enforce some orbits per timeframe, instead of determining from CCDB" + echo "ALIEN_JDL_RUN_TIME_SPAN_FILE=FILE, use a run-time-span file to exclude bad data-taking periods" + echo "ALIEN_JDL_INVERT_IRFRAME_SELECTION, invertes the choice of ALIEN_JDL_RUN_TIME_SPAN_FILE" + echo "ALIEN_JDL_CCDB_CONDITION_NOT_AFTER, sets the condition_not_after timestamp for CCDB queries" + echo "DISABLE_QC, set this to disable QC, e.g. to 1" + echo "CYCLE, to set a cycle number different than 0" + echo "NSIGEVENTS, to enforce a specific upper limit of events in a timeframe (not counting orbit-early) events" +} + +# Prevent the script from being soured to omit unexpected surprises when exit is used +SCRIPT_NAME="$(basename "$(test -L "$0" && readlink "$0" || echo "$0")")" +if [ "${SCRIPT_NAME}" != "$(basename ${BASH_SOURCE[0]})" ] ; then + echo_error "This script cannot not be sourced" >&2 + return 1 +fi + +while [ "$1" != "" ] ; do + case $1 in + --help|-h ) shift + print_help + exit 0 + ;; + * ) echo "Unknown argument ${1}" + exit 1 + ;; + esac +done + +# make sure O2DPG + O2 is loaded +[ ! "${O2DPG_ROOT}" ] && echo_error "This needs O2DPG loaded" && exit 1 +[ ! "${O2_ROOT}" ] && echo_error "This needs O2 loaded" && exit 1 + +# check if jq is there +which jq >/dev/null 2>&1 +[ "${?}" != "0" ] && { echo_error "jq is not found. Install or load via alienv." ; exit 1 ; } + +alien-token-info >/dev/null 2>&1 +[ "${?}" != "0" ] && { echo_error "No GRID token found, required to run." ; exit 1 ; } + +################################################################# +# Set all required variables to identify an anchored production # +################################################################# + +# Allow for both "ALIEN_JDL_LPM" as well as "KEY" + +# the only four where there is a real default for +export ALIEN_JDL_CPULIMIT=${ALIEN_JDL_CPULIMIT:-${CPULIMIT:-8}} +export ALIEN_JDL_SIMENGINE=${ALIEN_JDL_SIMENGINE:-${SIMENGINE:-TGeant4}} +# can be passed to contain additional options that will be passed to o2dpg_sim_workflow_anchored.py and eventually to o2dpg_sim_workflow.py +export ALIEN_JDL_ANCHOR_SIM_OPTIONS=${ALIEN_JDL_ANCHOR_SIM_OPTIONS:--gen pythia8} +# all others MUST be set by the user/on the outside +export ALIEN_JDL_LPMANCHORPASSNAME=${ALIEN_JDL_LPMANCHORPASSNAME:-${ANCHORPASSNAME}} +# LPMPASSNAME is used in O2 and O2DPG scripts, however on the other hand, ALIEN_JDL_LPMANCHORPASSNAME is the one that is set in JDL templates; so use ALIEN_JDL_LPMANCHORPASSNAME and set ALIEN_JDL_LPMPASSNAME +export ALIEN_JDL_LPMPASSNAME=${ALIEN_JDL_LPMANCHORPASSNAME} +export ALIEN_JDL_LPMRUNNUMBER=${ALIEN_JDL_LPMRUNNUMBER:-${RUNNUMBER}} +export ALIEN_JDL_LPMPRODUCTIONTYPE=${ALIEN_JDL_LPMPRODUCTIONTYPE:-${PRODUCTIONTYPE}} +export ALIEN_JDL_LPMINTERACTIONTYPE=${ALIEN_JDL_LPMINTERACTIONTYPE:-${INTERACTIONTYPE}} +export ALIEN_JDL_LPMPRODUCTIONTAG=${ALIEN_JDL_LPMPRODUCTIONTAG:-${PRODUCTIONTAG}} +export ALIEN_JDL_LPMANCHORRUN=${ALIEN_JDL_LPMANCHORRUN:-${ANCHORRUN}} +export ALIEN_JDL_LPMANCHORPRODUCTION=${ALIEN_JDL_LPMANCHORPRODUCTION:-${ANCHORPRODUCTION}} +export ALIEN_JDL_LPMANCHORYEAR=${ALIEN_JDL_LPMANCHORYEAR:-${ANCHORYEAR}} +# decide whether to run TPC time series; on by default, switched off by setting to 0 +export ALIEN_JDL_ADDTIMESERIESINMC=${ALIEN_JDL_ADDTIMESERIESINMC:-1} + +# check for presence of essential variables that need to be set +[ -z "${ALIEN_JDL_LPMANCHORPASSNAME}" ] && { echo_error "Set ALIEN_JDL_LPMANCHORPASSNAME or ANCHORPASSNAME" ; exit 1 ; } +[ -z "${ALIEN_JDL_LPMRUNNUMBER}" ] && { echo_error "Set ALIEN_JDL_LPMRUNNUMBER or RUNNUMBER" ; exit 1 ; } +[ -z "${ALIEN_JDL_LPMPRODUCTIONTYPE}" ] && { echo_error "Set ALIEN_JDL_LPMPRODUCTIONTYPE or PRODUCTIONTYPE" ; exit 1 ; } +[ -z "${ALIEN_JDL_LPMINTERACTIONTYPE}" ] && { echo_error "Set ALIEN_JDL_LPMINTERACTIONTYPE or INTERACTIONTYPE" ; exit 1 ; } +[ -z "${ALIEN_JDL_LPMPRODUCTIONTAG}" ] && { echo_error "Set ALIEN_JDL_LPMPRODUCTIONTAG or PRODUCTIONTAG" ; exit 1 ; } +[ -z "${ALIEN_JDL_LPMANCHORRUN}" ] && { echo_error "Set ALIEN_JDL_LPMANCHORRUN or ANCHORRUN" ; exit 1 ; } +[ -z "${ALIEN_JDL_LPMANCHORPRODUCTION}" ] && { echo_error "Set ALIEN_JDL_LPMANCHORPRODUCTION or ANCHORPRODUCTION" ; exit 1 ; } +[ -z "${ALIEN_JDL_LPMANCHORYEAR}" ] && { echo_error "Set ALIEN_JDL_LPMANCHORYEAR or ANCHORYEAR" ; exit 1 ; } + +[ -z "${NTIMEFRAMES}" ] && { echo_error "Set NTIMEFRAMES" ; exit 1 ; } +[ -z "${SPLITID}" ] && { echo_error "Set SPLITID" ; exit 1 ; } +[ -z "${PRODSPLIT}" ] && { echo_error "Set PRODSPLIT" ; exit 1 ; } + + +# cache the production tag, will be set to a special anchor tag; reset later in fact +ALIEN_JDL_LPMPRODUCTIONTAG_KEEP=$ALIEN_JDL_LPMPRODUCTIONTAG +echo_info "Substituting ALIEN_JDL_LPMPRODUCTIONTAG=$ALIEN_JDL_LPMPRODUCTIONTAG with ALIEN_JDL_LPMANCHORPRODUCTION=$ALIEN_JDL_LPMANCHORPRODUCTION for simulating reco pass..." +ALIEN_JDL_LPMPRODUCTIONTAG=$ALIEN_JDL_LPMANCHORPRODUCTION + +if [[ $ALIEN_JDL_ANCHOR_SIM_OPTIONS == *"--tpc-distortion-type 2"* ]]; then + export O2DPG_ENABLE_TPC_DISTORTIONS=ON + # set the SCALING SOURCE to CTP for MC unless explicitely given from outside + export ALIEN_JDL_TPCSCALINGSOURCE=${ALIEN_JDL_TPCSCALINGSOURCE:-"CTP"} +fi + + +# The number of signal events can be given, but should be useful only in +# certain expert modes. In the default case, the final event number is determined by the timeframe length. +if [ -z "${NSIGEVENTS}" ]; then + NSIGEVENTS=10000 # this is just some big number; In the simulation the event number is the minimum of this number and what fits into a single timeframe + # based on the interaction rate. The number is a reasonable upper limit related to ~5696 collisions that fit into 32 LHC orbits at 2MHz interaction rate. +fi + +if [ -z "${CYCLE}" ]; then + echo_info "No CYCLE number given ... defaulting to 0" + CYCLE=0 +fi + +# this generates an exact reproducer script for this job +# that can be used locally for debugging etc. +if [[ -n "${ALIEN_PROC_ID}" && -n "${JALIEN_WSPORT}" ]]; then + ${O2DPG_ROOT}/GRID/utils/getReproducerScript.sh ${ALIEN_PROC_ID} +fi + +# also for this keep a real default +NWORKERS=${NWORKERS:-8} +# set a default seed if not given +SEED=${ALIEN_PROC_ID:-${SEED:-1}} + +ONCVMFS=0 + +if [ "${ALIEN_JDL_O2DPG_OVERWRITE}" ]; then + echo "Setting O2DPG_ROOT to overwritten path ${ALIEN_JDL_O2DPG_OVERWRITE}" + export O2DPG_ROOT=${ALIEN_JDL_O2DPG_OVERWRITE} +fi + +export > env_base.env + +if ! declare -F module > /dev/null; then + module() { + eval "$(/usr/bin/modulecmd bash "$@")"; + } + export -f module +fi + +[[ "${BASEDIR}" == /cvmfs/* ]] && ONCVMFS=1 +if [ ! "${MODULEPATH}" ]; then + export MODULEPATH=${BASEDIR}/../Modules/modulefiles + if [ "${ONCVMFS}" == "1" ]; then + PLATFORM=$(echo "${BASEDIR}" | sed -E 's|.*/([^/]+)/Packages|\1|') + export MODULEPATH=${MODULEPATH}:${BASEDIR}/../../etc/toolchain/modulefiles/${PLATFORM} + fi + echo "Determined Modulepath to be ${MODULEPATH}" +fi + +#<----- START OF part that should run under a clean alternative software environment if this was given ------ +if [ "${ALIEN_JDL_O2DPG_ASYNC_RECO_TAG}" ]; then + if [ "${LOADEDMODULES}" ]; then + printenv > env_before_stashing.printenv + echo "Stashing initial modules" + module save initial_modules.list # we stash the current modules environment + module list --no-pager + module purge --no-pager + printenv > env_after_stashing.printenv + echo "Modules after purge" + module list --no-pager + fi + echo_info "Using tag ${ALIEN_JDL_O2DPG_ASYNC_RECO_TAG} to setup anchored MC" + /cvmfs/alice.cern.ch/bin/alienv printenv "${ALIEN_JDL_O2DPG_ASYNC_RECO_TAG}" &> async_environment.env + source async_environment.env + export > env_async.env +fi + +# default async_pass.sh script +DPGRECO=$O2DPG_ROOT/DATA/production/configurations/asyncReco/async_pass.sh +# default destenv_extra.sh script +DPGSETENV=$O2DPG_ROOT/DATA/production/configurations/asyncReco/setenv_extra.sh + +# a specific async_pass.sh script is in the current directory, assume that one should be used +if [[ -f async_pass.sh ]]; then + # the default is executable, however, this may not be, so make it so + chmod +x async_pass.sh + DPGRECO=./async_pass.sh +else + cp -v $DPGRECO . +fi + +# if there is no setenv_extra.sh in this directory (so no special version is "shipped" with this rpodcution), copy the default one +if [[ ! -f setenv_extra.sh ]] ; then + cp ${DPGSETENV} . + echo_info "Use default setenv_extra.sh from ${DPGSETENV}." +else + echo_info "setenv_extra.sh was found in the current working directory, use it." +fi + +chmod u+x setenv_extra.sh + +echo_info "Setting up DPGRECO to ${DPGRECO}" + +# take out line running the workflow (if we don't have data input) +[ ${CTF_TEST_FILE} ] || sed -i '/WORKFLOWMODE=run/d' async_pass.sh + +# create workflow ---> creates the file that can be parsed +export IGNORE_EXISTING_SHMFILES=1 +touch list.list + +# run the async_pass.sh and store output to log file for later inspection and extraction of information +./async_pass.sh ${CTF_TEST_FILE:-""} 2&> async_pass_log.log +RECO_RC=$? + +echo_info "async_pass.sh finished with ${RECO_RC}" + +if [[ "${RECO_RC}" != "0" ]] ; then + exit ${RECO_RC} +fi + +# check that workflowconfig.log was created correctly +if [[ ! -f workflowconfig.log ]]; then + echo "Workflowconfig.log file not found" + exit 1 +fi + +export ALIEN_JDL_LPMPRODUCTIONTAG=$ALIEN_JDL_LPMPRODUCTIONTAG_KEEP +echo_info "Setting back ALIEN_JDL_LPMPRODUCTIONTAG to $ALIEN_JDL_LPMPRODUCTIONTAG" + +# get rid of the temporary software environment +if [ "${ALIEN_JDL_O2DPG_ASYNC_RECO_TAG}" ]; then + module purge --no-pager + # restore the initial software environment + echo "Restoring initial environment" + module --no-pager restore initial_modules.list + module saverm initial_modules.list + + # Restore overwritten O2DPG variables set by modules but changed by user + # (in particular custom O2DPG_ROOT and O2DPG_MC_CONFIG_ROOT) + printenv > env_after_restore.printenv + comm -12 <(grep '^O2DPG' env_before_stashing.printenv | cut -d= -f1 | sort) \ + <(grep '^O2DPG' env_after_restore.printenv | cut -d= -f1 | sort) | + while read -r var; do + b=$(grep "^$var=" env_before_stashing.printenv | cut -d= -f2-) + a=$(grep "^$var=" env_after_restore.printenv | cut -d= -f2-) + [[ "$b" != "$a" ]] && export "$var=$b" && echo "Reapplied: $var to ${b}" + done +fi +#<----- END OF part that should run under a clean alternative software environment if this was given ------ + +# now create the local MC config file --> config-json.json +# we create the new config output with blacklist functionality +ASYNC_CONFIG_BLACKLIST=${ASYNC_CONFIG_BLACKLIST:-${O2DPG_ROOT}/MC/run/ANCHOR/anchor-dpl-options-blacklist.json} +${O2DPG_ROOT}/MC/bin/o2dpg_dpl_config_tools.py workflowconfig.log ${ASYNC_CONFIG_BLACKLIST} config-json.json +ASYNC_WF_RC=${?} + +# check if config reasonably created +if [[ "${ASYNC_WF_RC}" != "0" || `grep "ConfigParams" config-json.json 2> /dev/null | wc -l` == "0" ]]; then + echo_error "Problem in anchor config creation. Exiting." + exit 1 +fi + +# -- CREATE THE MC JOB DESCRIPTION ANCHORED TO RUN -- + +MODULES="--skipModules ZDC" + +# publish MCPRODINFO for first few jobs of a production +# if external script exported PUBLISH_MCPRODINFO, it will be published anyways +if [ -z "$PUBLISH_MCPRODINFO" ] && [ "$SPLITID" -lt 20 ]; then + PUBLISH_MCPRODINFO_OPTION="--publish-mcprodinfo" + echo "Will publish MCProdInfo" +else + echo "Will not publish MCProdInfo" +fi +PUBLISH_MCPRODINFO_OPTION="" + +# let's take the input data AO2D from a JDL variable +AOD_DATA_FILE=${ALIEN_JDL_MC_DATA_EMBEDDING_AO2D} +if [ "${ALIEN_JDL_MC_DATA_EMBEDDING_AO2D}" ]; then + NTIMEFRAMES=1 + NWORKERS=1 # these embedding jobs process only light pp type signals ... the parallelism will come via parallel workflows +fi + +# call the python script to extract all collision contexts +python3 ${O2DPG_ROOT}/MC/utils/o2dpg_data_embedding_utils.py --aod-file ${AOD_DATA_FILE} --run-number ${ALIEN_JDL_LPMRUNNUMBER} --limit ${DATA_EMBEDDING_LIMIT:-8} + +parallel_job_count=0 +failed_count=0 +for external_context in collission_context_*.root; do + echo "Embedding into ${external_context}" + # extract timeframe from name + anchoring_tf="${external_context#collission_context_}" # remove prefix 'collision_context_' + anchoring_tf="${anchoring_tf%.root}" # remove suffix '.root' + # now we have a string with DF_FOLDERNAME:TIMEFRAMEID + + df_folder="${anchoring_tf%%:*}" + anchoring_tf="${anchoring_tf##*:}" + + echo "Treating timeframe ${anchoring_tf} coming from folder ${df_folder}" + + # we do it in a separate workspace + workspace="TF_${anchoring_tf}" + mkdir "${workspace}"; cd "${workspace}" + # fetch the apass reco anchoring config + cp ../*.json . + + # we need to adjust the SEED for each job + JOBSEED=$SEED + [ "$JOBSEED" != "-1" ] && let JOBSEED=JOBSEED+anchoring_tf + echo "TF ${anchoring_tf} got seed ${JOBSEED}" + + # these arguments will be digested by o2dpg_sim_workflow_anchored.py + anchoringArgs="--split-id ${SPLITID} --prod-split ${PRODSPLIT} --cycle ${CYCLE}" + if [ "${ALIEN_JDL_MC_DATA_EMBEDDING_AO2D}" ]; then + anchoringArgs="--timeframeID ${anchoring_tf}" + fi + baseargs="-tf ${NTIMEFRAMES} ${anchoringArgs} --run-number ${ALIEN_JDL_LPMRUNNUMBER} \ + ${ALIEN_JDL_RUN_TIME_SPAN_FILE:+--run-time-span-file ${ALIEN_JDL_RUN_TIME_SPAN_FILE} ${ALIEN_JDL_INVERT_IRFRAME_SELECTION:+--invert-irframe-selection}} \ + ${ALIEN_JDL_MC_ORBITS_PER_TF:+--orbitsPerTF ${ALIEN_JDL_MC_ORBITS_PER_TF}} ${PUBLISH_MCPRODINFO_OPTION}" + + # these arguments will be passed as well but only eventually be digested by o2dpg_sim_workflow.py which is called from o2dpg_sim_workflow_anchored.py + remainingargs="-seed ${JOBSEED} -ns ${NSIGEVENTS} --include-local-qc --pregenCollContext" + remainingargs="${remainingargs} -e ${ALIEN_JDL_SIMENGINE} -j ${NWORKERS}" + remainingargs="${remainingargs} -productionTag ${ALIEN_JDL_LPMPRODUCTIONTAG:-alibi_anchorTest_tmp}" + # prepend(!) ALIEN_JDL_ANCHOR_SIM_OPTIONS + # since the last passed argument wins, e.g. -productionTag cannot be overwritten by the user + remainingargs="${ALIEN_JDL_ANCHOR_SIM_OPTIONS} ${remainingargs} --anchor-config config-json.json" + # apply software tagging choice + # remainingargs="${remainingargs} ${ALIEN_JDL_O2DPG_ASYNC_RECO_TAG:+--alternative-reco-software ${ALIEN_JDL_O2DPG_ASYNC_RECO_TAG}}" + ALIEN_JDL_O2DPG_ASYNC_RECO_FROMSTAGE=${ALIEN_JDL_O2DPG_ASYNC_RECO_FROMSTAGE:-RECO} + remainingargs="${remainingargs} ${ALIEN_JDL_O2DPG_ASYNC_RECO_TAG:+--alternative-reco-software ${PWD}/env_async.env@${ALIEN_JDL_O2DPG_ASYNC_RECO_FROMSTAGE}}" + # potentially add CCDB timemachine timestamp + remainingargs="${remainingargs} ${ALIEN_JDL_CCDB_CONDITION_NOT_AFTER:+--condition-not-after ${ALIEN_JDL_CCDB_CONDITION_NOT_AFTER}}" + # add external collision context injection + if [ "${ALIEN_JDL_MC_DATA_EMBEDDING_AO2D}" ]; then + remainingargs="${remainingargs} --data-anchoring ${PWD}/../${external_context} --aod-output-folder ${df_folder##*_} --aod-parent-file ${ALIEN_JDL_MC_DATA_EMBEDDING_AO2D}" + fi + + echo_info "baseargs passed to o2dpg_sim_workflow_anchored.py: ${baseargs}" + echo_info "remainingargs forwarded to o2dpg_sim_workflow.py: ${remainingargs}" + + anchoringLogFile=timestampsampling_${ALIEN_JDL_LPMRUNNUMBER}.log + # query CCDB has changed, w/o "_" + ${O2DPG_ROOT}/MC/bin/o2dpg_sim_workflow_anchored.py ${baseargs} -- ${remainingargs} &> ${anchoringLogFile} + WF_RC="${?}" + if [ "${WF_RC}" != "0" ] ; then + echo_error "Problem during anchor timestamp sampling and workflow creation. Exiting." + exit ${WF_RC} + fi + + TIMESTAMP=`grep "Determined timestamp to be" ${anchoringLogFile} | awk '//{print $6}'` + echo_info "TIMESTAMP IS ${TIMESTAMP}" + + if [ "${ONLY_WORKFLOW_CREATION}" ]; then + continue # or exit + fi + + # check if this job is exluded because it falls inside a bad data-taking period + ISEXCLUDED=$(grep "TIMESTAMP IS EXCLUDED IN RUN" ${anchoringLogFile}) + if [ "${ISEXCLUDED}" ]; then + # we can quit here; there is nothing to do + # (apart from maybe creating a fake empty AO2D.root file or the like) + echo "Timestamp is excluded from run. Nothing to do here" + continue # or exit 0 + fi + + # -- RUN THE MC WORKLOAD TO PRODUCE TARGETS -- + + export FAIRMQ_IPC_PREFIX=./ + echo_info "Ready to start main workflow" + + # Let us construct the workflow targets + targetString="" + if [ "${ALIEN_JDL_O2DPGWORKFLOWTARGET}" ]; then + # The user gave ${ALIEN_JDL_O2DPGWORKFLOWTARGET}. This is an expert mode not used in production. + # In this case, we will build just that. No QC, no TPC timeseries, ... + targetString=${ALIEN_JDL_O2DPGWORKFLOWTARGET} + else + targetString="'aodmerge.*'" + # Now add more targets depending on options + # -) The TPC timeseries targets + if [[ "${ALIEN_JDL_ADDTIMESERIESINMC}" == "1" ]]; then + targetString="${targetString} 'tpctimes.*'" + fi + # -) TPC residual calibration + if [ "${ALIEN_JDL_DOTPCRESIDUALSEXTRACTION}" ]; then + targetString="${targetString} 'tpcresidmerge.*'" + fi + # -) QC tasks + if [[ -z "${DISABLE_QC}" && "${remainingargs}" == *"--include-local-qc"* ]]; then + targetString="${targetString} '^.*QC.*'" # QC tasks should have QC in the name + fi + fi + echo_info "Workflow will run with target specification ${targetString}" + + ${O2DPG_ROOT}/MC/bin/o2_dpg_workflow_runner.py -f workflow.json -tt ${targetString} -j 1 \ + --cpu-limit ${ALIEN_JDL_CPULIMIT:-8} --dynamic-resources \ + ${ALIEN_O2DPG_FILEGRAPH:+--remove-files-early ${ALIEN_O2DPG_FILEGRAPH}} \ + ${ALIEN_O2DPG_ADDITIONAL_WORKFLOW_RUNNER_ARGS} &> pipeline_log & + + ((parallel_job_count++)) + # If limit reached, wait for one job to finish + if ((parallel_job_count >= 8)); then + if ! wait -n; then + ((failed_count++)) + fi + ((parallel_job_count--)) + fi + + cd .. +done # done outer loop +while ((parallel_job_count > 0)); do + if ! wait -n; then + ((failed_count++)) + fi + ((parallel_job_count--)) +done + +if [ "${ALIEN_JDL_MC_DATA_EMBEDDING_AO2D}" ]; then + # produce the final merged AO2D + find ./ -maxdepth 2 -mindepth 2 -name "AO2D.root" > aod_inputs.txt + o2-aod-merger --input aod_inputs.txt --output AO2D.root --merge-by-name # --merge-by-name restricts merging to folders of same name +fi + +# +# full logs tar-ed for output, regardless the error code or validation - to catch also QC logs... +# +if [[ -n "$ALIEN_PROC_ID" ]]; then + find ./ \( -name "*.log*" -o -name "*mergerlog*" -o -name "*serverlog*" -o -name "*workerlog*" -o -name "pythia8.cfg" -o -name "reproducer*.sh" \) | tar -czvf debug_log_archive.tgz -T - + if [[ "$ALIEN_JDL_CREATE_TAR_IN_MC" == "1" ]]; then + find ./ \( -name "*.log*" -o -name "*mergerlog*" -o -name "*serverlog*" -o -name "*workerlog*" -o -name "*.root" \) | tar -czvf debug_full_archive.tgz -T - + fi +fi diff --git a/MC/run/ANCHOR/tests/ML_clusterizer/run.sh b/MC/run/ANCHOR/tests/ML_clusterizer/run.sh new file mode 100755 index 000000000..9f800d868 --- /dev/null +++ b/MC/run/ANCHOR/tests/ML_clusterizer/run.sh @@ -0,0 +1,68 @@ +#!/bin/bash + +#JDL_OUTPUT=*.txt@disk=1,AO2D*.root@disk=2,*.log@disk=1,*stat*@disk=1,*.json@disk=1,debug*tgz@disk=2,tf*/coll*.root +#JDL_ERROROUTPUT=*.txt@disk=1,AO2D*.root@disk=2,*.log@disk=1,*.json@disk=1,debug*tgz@disk=2 +#JDL_PACKAGE=O2PDPSuite::daily-20251215-0000-1 + +# +# An **EXAMPLE** showing injection of GPU_proc_nn config_keys into the workflow creation, so +# that TPC clusterizer runs with ML kernel. +# + +# example anchoring +export ALIEN_JDL_LPMANCHORPASSNAME=apass4 +export ALIEN_JDL_MCANCHOR=apass4 +export ALIEN_JDL_CPULIMIT=8 +export ALIEN_JDL_LPMRUNNUMBER=544124 +export ALIEN_JDL_LPMPRODUCTIONTYPE=MC +export ALIEN_JDL_LPMINTERACTIONTYPE=PbPb +export ALIEN_JDL_LPMPRODUCTIONTAG=MLClusterTest +export ALIEN_JDL_LPMANCHORRUN=544124 +export ALIEN_JDL_LPMANCHORPRODUCTION=LHC23zz +export ALIEN_JDL_LPMANCHORYEAR=2023 + +export NTIMEFRAMES=1 +export PRODSPLIT=${ALIEN_O2DPG_GRIDSUBMIT_PRODSPLIT:-100} +export SPLITID=${ALIEN_O2DPG_GRIDSUBMIT_SUBJOBID:-50} +export CYCLE=0 + +# this file modifies few config key values for GPU_proc_nn for application in TPC clusterization +LOCAL_CONFIG="customize_ml_clusterizing.json" +cat > ${LOCAL_CONFIG} < ${INPUT_FILE_STRIPPED} + +# Read the header line and convert it into variable names +IFS=',' read -r -a headers < "$INPUT_FILE_STRIPPED" + +# Replace placeholders in the header (e.g., %{VAR} → VAR) +for i in "${!headers[@]}"; do + headers[$i]=$(echo "${headers[$i]}" | sed -E 's/#?%\{//;s/\}//g') +done + +TOPWORKDIR="" + +# Read and process each subsequent line +{ + read # Skip the header line + + count=1 # Counter for output files + datestring=$(date +"%Y%m%d_%H%M%S") + while IFS=',' read -r -a values; do + # Assign each value to its corresponding variable + for i in "${!headers[@]}"; do + declare "${headers[$i]}"="${values[$i]}" + done + + PRODUCTION_TAG="2tagtest_${datestring}_${count}" + # Example: Print assigned variables + echo "SOFTWARETAG_SIM: $SOFTWARETAG_SIM" + echo "SOFTWARETAG_ASYNC: $SOFTWARETAG_ASYNC" + echo "PASSNAME: $PASSNAME" + echo "COL_SYSTEM: $COL_SYSTEM" + echo "RUN_NUMBER: $RUN_NUMBER" + echo "INTERACTIONTYPE: $INTERACTIONTYPE" + echo "PRODUCTION_TAG: $PRODUCTION_TAG" + echo "ANCHOR_PRODUCTION: $ANCHOR_PRODUCTION" + echo "ANCHORYEAR: $ANCHORYEAR" + echo "SIM_OPTIONS: $SIM_OPTIONS" + echo "--------------------------------" + + if [ "${DAILYTAGTOTEST}" ]; then + SOFTWARETAG_SIM=${DAILYTAGTOTEST} + fi + + OUTPUT_FILE_FINAL="${WORKING_DIR}/${OUTPUT_FILE}_case${count}.sh" + + # create final test script with these values + cp "$TEMPLATE_FILE" "${OUTPUT_FILE_FINAL}" + for var in "${headers[@]}"; do + sed -i "s|%{$var}|${!var}|g" "$OUTPUT_FILE_FINAL" + done + # put the require spec + sed -i "s/%{JDL_REQUIREMENT}/${REQUIRE_STRING}/g" "$OUTPUT_FILE_FINAL" + + # inject custom repo if available + if [ "${O2DPG_CUSTOM_REPO}" ]; then + sed -i "s|%{O2DPG_CUSTOM_REPO}|${O2DPG_CUSTOM_REPO}|g" "$OUTPUT_FILE_FINAL" + else + sed -i "/%{O2DPG_CUSTOM_REPO}/d" "$OUTPUT_FILE_FINAL" + fi + + TOPWORKDIR=2tag_release_testing_${BUILD_TAG:-${SOFTWARETAG_SIM}} + + # we submit the test to the GRID (with some multiplicity) + # ${WORKING_DIR}/submit_case${count}_${SOFTWARETAG_ASYNC//::/-} + echo "${O2DPG_ROOT}/GRID/utils/grid_submit.sh --prodsplit ${PRODSPLIT:-4} --singularity --ttl ${TTL:-3600} --script ${OUTPUT_FILE_FINAL} \ + --jobname "anchorTest_${count}" --wait-any --topworkdir ${TOPWORKDIR}" > ${WORKING_DIR}/submit_case${count}.sh + # TODO: optional local execution with --local option + + ((count++)) # Increment counter for next row + done +} < "${INPUT_FILE_STRIPPED}" #Redirect file input here to avoid subshell issues + +cd ${WORKING_DIR} + +# now we submit all the jobs in the background and wait for them to return +declare -A logfiles +declare -A urls +for s in submit*.sh; do + echo "submitting ${s}" + export GRID_SUBMIT_WORKDIR="${WORKING_DIR}/${s}_workdir" + ( + bash ${s} &> log_${s} + echo "Job ${s} returned" + ) & + logfiles["$s"]="log_${s}" +done + +# Next stage is to wait until all jobs are actually running on +# AliEn +waitcounter=0 +maxwait=100 +while (( ${#logfiles[@]} > 0 && waitcounter < maxwait )); do + for script in "${!logfiles[@]}"; do + logfile=${logfiles["$script"]} + if grep -q "https://alimonitor.cern.ch/agent/jobs/details.jsp?pid=" "$logfile" 2>/dev/null; then + # Extract URL: strip ANSI codes, find URL, take first match + url=$(sed 's/\x1B\[[0-9;]*[a-zA-Z]//g' "$logfile" \ + | grep -o 'https://alimonitor.cern.ch/agent/jobs/details.jsp?pid=[0-9]*' \ + | head -n1) + + echo "Job ${script} has AliEn job URL: ${url}" + urls["$script"]=${url} + unset logfiles["$script"] + fi + done + sleep 1 + ((waitcounter++)) +done + +# wait for all (GRID) jobs to return +echo "Waiting for jobs to return/finish" +wait + +# verify / validate the output produced from these jobs +# The test is successfull if at least one subjob from each test +# produced the AO2D output. +echo "-- Jobs done ... validating --" + +FINAL_SUCCESS=0 +for s in submit*.sh; do + # find output path + TEST_OUTPUT_PATH="${WORKING_DIR}/${s}_workdir" # $(grep "Local working directory is" log_${s} | awk '//{print $5}') + + # get the Output path on JAlien from the JDL + ALIEN_OUTPUT_FOLDER=$(grep 'OutputDir' ${TEST_OUTPUT_PATH}/*.jdl | cut -d'"' -f2 | sed 's|/[^/]*#.*#.*$||') + + # see if there is an AO2D.root and a workflow.json in one of the jobs in that folder + AODS_FOUND=$(alien.py find ${ALIEN_OUTPUT_FOLDER} AO2D.root) + WORKFLOWS_FOUND=$(alien.py find ${ALIEN_OUTPUT_FOLDER} workflow.json) + + if [[ -z ${WORKFLOWS_FOUND} || -z ${AODS_FOUND} ]]; then + echo "❌ Missing files for case $s: Check here for logs ${urls[${s}]}" + FINAL_SUCCESS=1 # mark as failure + # also upload log file to AliEn for later inspection + alien.py cp file:./log_${s} alien:~/${TOPWORKDIR} + else + echo "✅ Files found in $s" + fi +done + +if [[ ${FINAL_SUCCESS} -eq 0 ]]; then + echo "✅ All submissions have required files." +else + echo "❌ Some submissions are missing required files." +fi + +#TODO: echo "-- Cleaning up ... " +cd .. + +exit ${FINAL_SUCCESS} diff --git a/MC/run/HEPscore/hep-score.sh b/MC/run/HEPscore/hep-score.sh index f7671c94f..f25df2c4f 100755 --- a/MC/run/HEPscore/hep-score.sh +++ b/MC/run/HEPscore/hep-score.sh @@ -8,8 +8,6 @@ [ ! "${O2DPG_ROOT}" ] && echo "Error: This needs O2DPG loaded" && exit 1 [ ! "${O2_ROOT}" ] && echo "Error: This needs O2 loaded" && exit 1 -# ----------- LOAD UTILITY FUNCTIONS -------------------------- -. ${O2_ROOT}/share/scripts/jobutils.sh # ----------- START ACTUAL JOB ----------------------------- NSIGEVENTS=${NSIGEVENTS:-5} diff --git a/MC/run/PWGDQ/runBeautyToJpsi_fwdy_PbPb.sh b/MC/run/PWGDQ/runBeautyToJpsi_fwdy_PbPb.sh index 3eaa90881..e15940a53 100644 --- a/MC/run/PWGDQ/runBeautyToJpsi_fwdy_PbPb.sh +++ b/MC/run/PWGDQ/runBeautyToJpsi_fwdy_PbPb.sh @@ -5,8 +5,6 @@ [ ! "${O2_ROOT}" ] && echo "Error: This needs O2 loaded" && exit 1 -# ----------- LOAD UTILITY FUNCTIONS -------------------------- -. ${O2_ROOT}/share/scripts/jobutils.sh RNDSEED=${RNDSEED:-0} NSIGEVENTS=${NSIGEVENTS:-1} @@ -14,7 +12,7 @@ NBKGEVENTS=${NBKGEVENTS:-1} NWORKERS=${NWORKERS:-8} NTIMEFRAMES=${NTIMEFRAMES:-1} -${O2DPG_ROOT}/MC/bin/o2dpg_sim_workflow.py -eCM 5020 -gen external -j ${NWORKERS} -ns ${NSIGEVENTS} -tf ${NTIMEFRAMES} -e TGeant4 -mod "--skipModules ZDC" \ +${O2DPG_ROOT}/MC/bin/o2dpg_sim_workflow.py -eCM 5020 -gen external -j ${NWORKERS} -ns ${NSIGEVENTS} -tf ${NTIMEFRAMES} -e TGeant4 \ -trigger "external" -ini $O2DPG_ROOT/MC/config/PWGDQ/ini/GeneratorHF_bbbar_fwdy.ini -interactionRate 500000 \ -genBkg pythia8 -procBkg "heavy_ion" -colBkg PbPb --embedding -nb ${NBKGEVENTS} --mft-assessment-full --fwdmatching-assessment-full --fwdmatching-save-trainingdata diff --git a/MC/run/PWGDQ/runBeautyToJpsi_fwdy_pp.sh b/MC/run/PWGDQ/runBeautyToJpsi_fwdy_pp.sh index 76f886fec..2becd0cc5 100755 --- a/MC/run/PWGDQ/runBeautyToJpsi_fwdy_pp.sh +++ b/MC/run/PWGDQ/runBeautyToJpsi_fwdy_pp.sh @@ -5,8 +5,6 @@ [ ! "${O2_ROOT}" ] && echo "Error: This needs O2 loaded" && exit 1 -# ----------- LOAD UTILITY FUNCTIONS -------------------------- -. ${O2_ROOT}/share/scripts/jobutils.sh RNDSEED=${RNDSEED:-0} NSIGEVENTS=${NSIGEVENTS:-1} @@ -14,7 +12,7 @@ NBKGEVENTS=${NBKGEVENTS:-1} NWORKERS=${NWORKERS:-8} NTIMEFRAMES=${NTIMEFRAMES:-1} -${O2DPG_ROOT}/MC/bin/o2dpg_sim_workflow.py -eCM 13600 -gen external -j ${NWORKERS} -ns ${NSIGEVENTS} -tf ${NTIMEFRAMES} -e TGeant4 -mod "--skipModules ZDC" \ +${O2DPG_ROOT}/MC/bin/o2dpg_sim_workflow.py -eCM 13600 -gen external -j ${NWORKERS} -ns ${NSIGEVENTS} -tf ${NTIMEFRAMES} -e TGeant4 \ -trigger "external" -ini $O2DPG_ROOT/MC/config/PWGDQ/ini/GeneratorHF_bbbar_fwdy.ini -interactionRate 500000 \ -genBkg pythia8 -procBkg inel -colBkg pp --embedding -nb ${NBKGEVENTS} --fwdmatching-4-param --fwdmatching-cut-4-param diff --git a/MC/run/PWGDQ/runBeautyToJpsi_midy_pp.sh b/MC/run/PWGDQ/runBeautyToJpsi_midy_pp.sh index f8ef40880..4d44a6853 100755 --- a/MC/run/PWGDQ/runBeautyToJpsi_midy_pp.sh +++ b/MC/run/PWGDQ/runBeautyToJpsi_midy_pp.sh @@ -5,8 +5,6 @@ [ ! "${O2_ROOT}" ] && echo "Error: This needs O2 loaded" && exit 1 -# ----------- LOAD UTILITY FUNCTIONS -------------------------- -. ${O2_ROOT}/share/scripts/jobutils.sh RNDSEED=${RNDSEED:-0} NSIGEVENTS=${NSIGEVENTS:-1} @@ -14,7 +12,7 @@ NBKGEVENTS=${NBKGEVENTS:-1} NWORKERS=${NWORKERS:-8} NTIMEFRAMES=${NTIMEFRAMES:-1} -${O2DPG_ROOT}/MC/bin/o2dpg_sim_workflow.py -eCM 900 -gen external -j ${NWORKERS} -ns ${NSIGEVENTS} -tf ${NTIMEFRAMES} -e TGeant4 -mod "--skipModules ZDC" \ +${O2DPG_ROOT}/MC/bin/o2dpg_sim_workflow.py -eCM 900 -gen external -j ${NWORKERS} -ns ${NSIGEVENTS} -tf ${NTIMEFRAMES} -e TGeant4 \ -trigger "external" -ini $O2DPG_ROOT/MC/config/PWGDQ/ini/GeneratorHF_bbbar_midy.ini -interactionRate 500000 \ -genBkg pythia8 -procBkg inel -colBkg pp --embedding -nb ${NBKGEVENTS} diff --git a/MC/run/PWGDQ/runBeautyToMuons_fwd_pp.sh b/MC/run/PWGDQ/runBeautyToMuons_fwd_pp.sh index b4fbe123a..cd5209ab2 100644 --- a/MC/run/PWGDQ/runBeautyToMuons_fwd_pp.sh +++ b/MC/run/PWGDQ/runBeautyToMuons_fwd_pp.sh @@ -8,8 +8,6 @@ export ALICEO2_CCDB_LOCALCACHE=$PWD/.ccdb -# ----------- LOAD UTILITY FUNCTIONS -------------------------- -. ${O2_ROOT}/share/scripts/jobutils.sh RNDSEED=${RNDSEED:-0} NSIGEVENTS=${NSIGEVENTS:-1} @@ -18,7 +16,7 @@ NWORKERS=${NWORKERS:-8} NTIMEFRAMES=${NTIMEFRAMES:-1} -${O2DPG_ROOT}/MC/bin/o2dpg_sim_workflow.py -eCM 13600 -gen external -j ${NWORKERS} -ns ${NSIGEVENTS} -tf ${NTIMEFRAMES} -e TGeant4 -mod "MCH MFT MID ITS" \ +${O2DPG_ROOT}/MC/bin/o2dpg_sim_workflow.py -eCM 13600 -gen external -j ${NWORKERS} -ns ${NSIGEVENTS} -tf ${NTIMEFRAMES} -e TGeant4 \ -trigger "external" -ini $O2DPG_ROOT/MC/config/PWGDQ/ini/GeneratorHF_bbbarToMuonsSemileptonic_fwdy.ini \ -genBkg pythia8 -procBkg cdiff -colBkg pp --embedding -nb ${NBKGEVENTS} \ -confKeyBkg "Diamond.width[2]=6" -interactionRate 2000 --mft-assessment-full --fwdmatching-assessment-full diff --git a/MC/run/PWGDQ/runBeautyToMuons_noForce_fwd_pp.sh b/MC/run/PWGDQ/runBeautyToMuons_noForce_fwd_pp.sh index ded2c646b..69f363b23 100644 --- a/MC/run/PWGDQ/runBeautyToMuons_noForce_fwd_pp.sh +++ b/MC/run/PWGDQ/runBeautyToMuons_noForce_fwd_pp.sh @@ -8,8 +8,6 @@ export ALICEO2_CCDB_LOCALCACHE=$PWD/.ccdb -# ----------- LOAD UTILITY FUNCTIONS -------------------------- -. ${O2_ROOT}/share/scripts/jobutils.sh RNDSEED=${RNDSEED:-0} NSIGEVENTS=${NSIGEVENTS:-1} @@ -18,7 +16,7 @@ NWORKERS=${NWORKERS:-8} NTIMEFRAMES=${NTIMEFRAMES:-1} -${O2DPG_ROOT}/MC/bin/o2dpg_sim_workflow.py -eCM 13600 -gen external -j ${NWORKERS} -ns ${NSIGEVENTS} -tf ${NTIMEFRAMES} -e TGeant4 -mod "MCH MFT MID ITS" \ +${O2DPG_ROOT}/MC/bin/o2dpg_sim_workflow.py -eCM 13600 -gen external -j ${NWORKERS} -ns ${NSIGEVENTS} -tf ${NTIMEFRAMES} -e TGeant4 \ -trigger "external" -ini $O2DPG_ROOT/MC/config/PWGDQ/ini/GeneratorHF_bbbarToDDbarToMuons_fwdy.ini \ -genBkg pythia8 -procBkg cdiff -colBkg pp --embedding -nb ${NBKGEVENTS} \ -confKeyBkg "Diamond.width[2]=6" -interactionRate 2000 --mft-assessment-full --fwdmatching-assessment-full diff --git a/MC/run/PWGDQ/runBeautyToPsiAndJpsi_fwdy_pp_triggerGap.sh b/MC/run/PWGDQ/runBeautyToPsiAndJpsi_fwdy_pp_triggerGap.sh index 8a344f66d..a1d2f9f57 100755 --- a/MC/run/PWGDQ/runBeautyToPsiAndJpsi_fwdy_pp_triggerGap.sh +++ b/MC/run/PWGDQ/runBeautyToPsiAndJpsi_fwdy_pp_triggerGap.sh @@ -5,8 +5,6 @@ [ ! "${O2_ROOT}" ] && echo "Error: This needs O2 loaded" && exit 1 -# ----------- LOAD UTILITY FUNCTIONS -------------------------- -. ${O2_ROOT}/share/scripts/jobutils.sh RNDSEED=${RNDSEED:-0} NSIGEVENTS=${NSIGEVENTS:-1} @@ -14,7 +12,7 @@ NBKGEVENTS=${NBKGEVENTS:-1} NWORKERS=${NWORKERS:-8} NTIMEFRAMES=${NTIMEFRAMES:-1} -${O2DPG_ROOT}/MC/bin/o2dpg_sim_workflow.py -eCM 13600 -gen external -j ${NWORKERS} -ns ${NSIGEVENTS} -tf ${NTIMEFRAMES} -e TGeant4 -mod "--skipModules ZDC" \ +${O2DPG_ROOT}/MC/bin/o2dpg_sim_workflow.py -eCM 13600 -gen external -j ${NWORKERS} -ns ${NSIGEVENTS} -tf ${NTIMEFRAMES} -e TGeant4 \ -ini $O2DPG_ROOT/MC/config/PWGDQ/ini/GeneratorHF_bbbar_PsiAndJpsi_fwdy_triggerGap.ini --mft-assessment-full --fwdmatching-assessment-full -interactionRate 500000 # run workflow diff --git a/MC/run/PWGDQ/runBeautyToPsiAndJpsi_midy_pp_triggerGap.sh b/MC/run/PWGDQ/runBeautyToPsiAndJpsi_midy_pp_triggerGap.sh index d9387ea7f..0dad5b4a5 100755 --- a/MC/run/PWGDQ/runBeautyToPsiAndJpsi_midy_pp_triggerGap.sh +++ b/MC/run/PWGDQ/runBeautyToPsiAndJpsi_midy_pp_triggerGap.sh @@ -5,8 +5,6 @@ [ ! "${O2_ROOT}" ] && echo "Error: This needs O2 loaded" && exit 1 -# ----------- LOAD UTILITY FUNCTIONS -------------------------- -. ${O2_ROOT}/share/scripts/jobutils.sh RNDSEED=${RNDSEED:-0} NSIGEVENTS=${NSIGEVENTS:-1} @@ -14,7 +12,7 @@ NBKGEVENTS=${NBKGEVENTS:-1} NWORKERS=${NWORKERS:-8} NTIMEFRAMES=${NTIMEFRAMES:-1} -${O2DPG_ROOT}/MC/bin/o2dpg_sim_workflow.py -eCM 13600 -gen external -j ${NWORKERS} -ns ${NSIGEVENTS} -tf ${NTIMEFRAMES} -e TGeant4 -mod "--skipModules ZDC" \ +${O2DPG_ROOT}/MC/bin/o2dpg_sim_workflow.py -eCM 13600 -gen external -j ${NWORKERS} -ns ${NSIGEVENTS} -tf ${NTIMEFRAMES} -e TGeant4 \ -ini $O2DPG_ROOT/MC/config/PWGDQ/ini/GeneratorHF_bbbar_PsiAndJpsi_midy_triggerGap.ini -interactionRate 500000 # run workflow diff --git a/MC/run/PWGDQ/runBeautyToPsi_fwdy_PbPb.sh b/MC/run/PWGDQ/runBeautyToPsi_fwdy_PbPb.sh index febbd98ac..38dd22686 100755 --- a/MC/run/PWGDQ/runBeautyToPsi_fwdy_PbPb.sh +++ b/MC/run/PWGDQ/runBeautyToPsi_fwdy_PbPb.sh @@ -5,8 +5,6 @@ [ ! "${O2_ROOT}" ] && echo "Error: This needs O2 loaded" && exit 1 -# ----------- LOAD UTILITY FUNCTIONS -------------------------- -. ${O2_ROOT}/share/scripts/jobutils.sh RNDSEED=${RNDSEED:-0} NSIGEVENTS=${NSIGEVENTS:-2} @@ -14,7 +12,7 @@ NBKGEVENTS=${NBKGEVENTS:-2} NWORKERS=${NWORKERS:-4} NTIMEFRAMES=${NTIMEFRAMES:-1} -${O2DPG_ROOT}/MC/bin/o2dpg_sim_workflow.py -eCM 5020 -gen external -j ${NWORKERS} -ns ${NSIGEVENTS} -tf ${NTIMEFRAMES} -e TGeant4 -mod "--skipModules ZDC" \ +${O2DPG_ROOT}/MC/bin/o2dpg_sim_workflow.py -eCM 5020 -gen external -j ${NWORKERS} -ns ${NSIGEVENTS} -tf ${NTIMEFRAMES} -e TGeant4 \ -trigger "external" -ini $O2DPG_ROOT/MC/config/PWGDQ/ini/GeneratorHF_bbbar_Psi2S_fwdy.ini -interactionRate 500000 \ -genBkg pythia8 -procBkg "heavy_ion" -colBkg PbPb --embedding -nb ${NBKGEVENTS} --mft-assessment-full --fwdmatching-assessment-full diff --git a/MC/run/PWGDQ/runBeautyToPsi_fwdy_pp.sh b/MC/run/PWGDQ/runBeautyToPsi_fwdy_pp.sh index 02b9bd27d..9bd9b125a 100755 --- a/MC/run/PWGDQ/runBeautyToPsi_fwdy_pp.sh +++ b/MC/run/PWGDQ/runBeautyToPsi_fwdy_pp.sh @@ -5,8 +5,6 @@ [ ! "${O2_ROOT}" ] && echo "Error: This needs O2 loaded" && exit 1 -# ----------- LOAD UTILITY FUNCTIONS -------------------------- -. ${O2_ROOT}/share/scripts/jobutils.sh RNDSEED=${RNDSEED:-0} NSIGEVENTS=${NSIGEVENTS:-1} @@ -14,7 +12,7 @@ NBKGEVENTS=${NBKGEVENTS:-1} NWORKERS=${NWORKERS:-8} NTIMEFRAMES=${NTIMEFRAMES:-1} -${O2DPG_ROOT}/MC/bin/o2dpg_sim_workflow.py -eCM 900 -gen external -j ${NWORKERS} -ns ${NSIGEVENTS} -tf ${NTIMEFRAMES} -e TGeant4 -mod "--skipModules ZDC" \ +${O2DPG_ROOT}/MC/bin/o2dpg_sim_workflow.py -eCM 900 -gen external -j ${NWORKERS} -ns ${NSIGEVENTS} -tf ${NTIMEFRAMES} -e TGeant4 \ -trigger "external" -ini $O2DPG_ROOT/MC/config/PWGDQ/ini/GeneratorHF_bbbar_Psi2S_fwdy.ini -interactionRate 500000 \ -genBkg pythia8 -procBkg inel -colBkg pp --embedding -nb ${NBKGEVENTS} diff --git a/MC/run/PWGDQ/runBeautyToPsi_midy_pp.sh b/MC/run/PWGDQ/runBeautyToPsi_midy_pp.sh index 941db0167..58e9cb74e 100755 --- a/MC/run/PWGDQ/runBeautyToPsi_midy_pp.sh +++ b/MC/run/PWGDQ/runBeautyToPsi_midy_pp.sh @@ -5,8 +5,6 @@ [ ! "${O2_ROOT}" ] && echo "Error: This needs O2 loaded" && exit 1 -# ----------- LOAD UTILITY FUNCTIONS -------------------------- -. ${O2_ROOT}/share/scripts/jobutils.sh RNDSEED=${RNDSEED:-0} NSIGEVENTS=${NSIGEVENTS:-1} @@ -14,7 +12,7 @@ NBKGEVENTS=${NBKGEVENTS:-1} NWORKERS=${NWORKERS:-8} NTIMEFRAMES=${NTIMEFRAMES:-1} -${O2DPG_ROOT}/MC/bin/o2dpg_sim_workflow.py -eCM 900 -gen external -j ${NWORKERS} -ns ${NSIGEVENTS} -tf ${NTIMEFRAMES} -e TGeant4 -mod "--skipModules ZDC" \ +${O2DPG_ROOT}/MC/bin/o2dpg_sim_workflow.py -eCM 900 -gen external -j ${NWORKERS} -ns ${NSIGEVENTS} -tf ${NTIMEFRAMES} -e TGeant4 \ -trigger "external" -ini $O2DPG_ROOT/MC/config/PWGDQ/ini/GeneratorHF_bbbar_Psi2S_midy.ini \ -genBkg pythia8 -procBkg inel -colBkg pp --embedding -nb ${NBKGEVENTS} -interactionRate 500000 diff --git a/MC/run/PWGDQ/runBplusToJpsi_midy_pp.sh b/MC/run/PWGDQ/runBplusToJpsi_midy_pp.sh index c559a75ac..5c43fda51 100755 --- a/MC/run/PWGDQ/runBplusToJpsi_midy_pp.sh +++ b/MC/run/PWGDQ/runBplusToJpsi_midy_pp.sh @@ -5,8 +5,6 @@ [ ! "${O2_ROOT}" ] && echo "Error: This needs O2 loaded" && exit 1 -# ----------- LOAD UTILITY FUNCTIONS -------------------------- -. ${O2_ROOT}/share/scripts/jobutils.sh RNDSEED=${RNDSEED:-0} NSIGEVENTS=${NSIGEVENTS:-1} @@ -14,7 +12,7 @@ NBKGEVENTS=${NBKGEVENTS:-1} NWORKERS=${NWORKERS:-8} NTIMEFRAMES=${NTIMEFRAMES:-1} -${O2DPG_ROOT}/MC/bin/o2dpg_sim_workflow.py -eCM 13600 -gen external -j ${NWORKERS} -ns ${NSIGEVENTS} -tf ${NTIMEFRAMES} -e TGeant4 -mod "--skipModules ZDC" \ +${O2DPG_ROOT}/MC/bin/o2dpg_sim_workflow.py -eCM 13600 -gen external -j ${NWORKERS} -ns ${NSIGEVENTS} -tf ${NTIMEFRAMES} -e TGeant4 \ -trigger "external" -ini $O2DPG_ROOT/MC/config/PWGDQ/ini/GeneratorHF_bbbarToBplus_midy.ini -interactionRate 500000 \ -genBkg pythia8 -procBkg inel -colBkg pp --embedding -nb ${NBKGEVENTS} diff --git a/MC/run/PWGDQ/runBplusToJpsi_midy_pp_triggerGap.sh b/MC/run/PWGDQ/runBplusToJpsi_midy_pp_triggerGap.sh index 449e67216..46aed6068 100755 --- a/MC/run/PWGDQ/runBplusToJpsi_midy_pp_triggerGap.sh +++ b/MC/run/PWGDQ/runBplusToJpsi_midy_pp_triggerGap.sh @@ -5,8 +5,6 @@ [ ! "${O2_ROOT}" ] && echo "Error: This needs O2 loaded" && exit 1 -# ----------- LOAD UTILITY FUNCTIONS -------------------------- -. ${O2_ROOT}/share/scripts/jobutils.sh RNDSEED=${RNDSEED:-0} NSIGEVENTS=${NSIGEVENTS:-1} @@ -14,7 +12,7 @@ NBKGEVENTS=${NBKGEVENTS:-1} NWORKERS=${NWORKERS:-8} NTIMEFRAMES=${NTIMEFRAMES:-1} -${O2DPG_ROOT}/MC/bin/o2dpg_sim_workflow.py -eCM 13600 -gen external -j ${NWORKERS} -ns ${NSIGEVENTS} -tf ${NTIMEFRAMES} -e TGeant4 -mod "--skipModules ZDC" \ +${O2DPG_ROOT}/MC/bin/o2dpg_sim_workflow.py -eCM 13600 -gen external -j ${NWORKERS} -ns ${NSIGEVENTS} -tf ${NTIMEFRAMES} -e TGeant4 \ -ini $O2DPG_ROOT/MC/config/PWGDQ/ini/GeneratorHF_bbbarToBplus_midy_triggerGap.ini -interactionRate 500000 # run workflow diff --git a/MC/run/PWGDQ/runCharmToMuons_fwd_pp.sh b/MC/run/PWGDQ/runCharmToMuons_fwd_pp.sh index 565a01aca..58cf706e3 100644 --- a/MC/run/PWGDQ/runCharmToMuons_fwd_pp.sh +++ b/MC/run/PWGDQ/runCharmToMuons_fwd_pp.sh @@ -8,8 +8,6 @@ export ALICEO2_CCDB_LOCALCACHE=$PWD/.ccdb -# ----------- LOAD UTILITY FUNCTIONS -------------------------- -. ${O2_ROOT}/share/scripts/jobutils.sh RNDSEED=${RNDSEED:-0} NSIGEVENTS=${NSIGEVENTS:-1} @@ -18,7 +16,7 @@ NWORKERS=${NWORKERS:-8} NTIMEFRAMES=${NTIMEFRAMES:-1} -${O2DPG_ROOT}/MC/bin/o2dpg_sim_workflow.py -eCM 13600 -gen external -j ${NWORKERS} -ns ${NSIGEVENTS} -tf ${NTIMEFRAMES} -e TGeant4 -mod "MCH MFT MID ITS" \ +${O2DPG_ROOT}/MC/bin/o2dpg_sim_workflow.py -eCM 13600 -gen external -j ${NWORKERS} -ns ${NSIGEVENTS} -tf ${NTIMEFRAMES} -e TGeant4 \ -trigger "external" -ini $O2DPG_ROOT/MC/config/PWGDQ/ini/GeneratorHF_ccbarToMuonsSemileptonic_fwdy.ini \ -genBkg pythia8 -procBkg cdiff -colBkg pp --embedding -nb ${NBKGEVENTS} \ -confKeyBkg "Diamond.width[2]=6" -interactionRate 2000 --mft-assessment-full --fwdmatching-assessment-full diff --git a/MC/run/PWGDQ/runFwdMuBoxGen_PbPb.sh b/MC/run/PWGDQ/runFwdMuBoxGen_PbPb.sh index 0e5e257a9..3163b3770 100755 --- a/MC/run/PWGDQ/runFwdMuBoxGen_PbPb.sh +++ b/MC/run/PWGDQ/runFwdMuBoxGen_PbPb.sh @@ -6,8 +6,6 @@ [ ! "${O2_ROOT}" ] && echo "Error: This needs O2 loaded" && exit 1 -# ----------- LOAD UTILITY FUNCTIONS -------------------------- -. ${O2_ROOT}/share/scripts/jobutils.sh RNDSEED=${RNDSEED:-0} NSIGEVENTS=${NSIGEVENTS:-1} diff --git a/MC/run/PWGDQ/runFwdMuBoxGen_pp.sh b/MC/run/PWGDQ/runFwdMuBoxGen_pp.sh index 4284a5a0c..396530969 100755 --- a/MC/run/PWGDQ/runFwdMuBoxGen_pp.sh +++ b/MC/run/PWGDQ/runFwdMuBoxGen_pp.sh @@ -6,8 +6,6 @@ [ ! "${O2_ROOT}" ] && echo "Error: This needs O2 loaded" && exit 1 -# ----------- LOAD UTILITY FUNCTIONS -------------------------- -. ${O2_ROOT}/share/scripts/jobutils.sh RNDSEED=${RNDSEED:-0} NSIGEVENTS=${NSIGEVENTS:-1} @@ -16,7 +14,7 @@ NWORKERS=${NWORKERS:-8} NTIMEFRAMES=${NTIMEFRAMES:-1} NBOXMUONS=${NBOXMUONS:-2} -${O2DPG_ROOT}/MC/bin/o2dpg_sim_workflow.py -eCM 13600 -gen external -j ${NWORKERS} -ns ${NSIGEVENTS} -tf ${NTIMEFRAMES} -e TGeant4 -mod "--skipModules ZDC" \ +${O2DPG_ROOT}/MC/bin/o2dpg_sim_workflow.py -eCM 13600 -gen external -j ${NWORKERS} -ns ${NSIGEVENTS} -tf ${NTIMEFRAMES} -e TGeant4 \ -confKey "GeneratorExternal.fileName=${O2DPG_ROOT}/MC/config/PWGDQ/external/generator/GeneratorBoxFwd.C;GeneratorExternal.funcName=fwdMuBoxGen()" -interactionRate 500000 \ -genBkg pythia8 -procBkg inel -colBkg pp --embedding -nb ${NBKGEVENTS} --mft-assessment-full --fwdmatching-assessment-full --fwdmatching-save-trainingdata diff --git a/MC/run/PWGDQ/runPromptCharmonia_fwdy_PbPb.sh b/MC/run/PWGDQ/runPromptCharmonia_fwdy_PbPb.sh index 82d0b10fd..e8d2462d3 100755 --- a/MC/run/PWGDQ/runPromptCharmonia_fwdy_PbPb.sh +++ b/MC/run/PWGDQ/runPromptCharmonia_fwdy_PbPb.sh @@ -5,8 +5,6 @@ [ ! "${O2_ROOT}" ] && echo "Error: This needs O2 loaded" && exit 1 -# ----------- LOAD UTILITY FUNCTIONS -------------------------- -. ${O2_ROOT}/share/scripts/jobutils.sh RNDSEED=${RNDSEED:-0} NSIGEVENTS=${NSIGEVENTS:-1} @@ -14,7 +12,7 @@ NBKGEVENTS=${NBKGEVENTS:-1} NWORKERS=${NWORKERS:-8} NTIMEFRAMES=${NTIMEFRAMES:-1} -${O2DPG_ROOT}/MC/bin/o2dpg_sim_workflow.py -eCM 5020 -gen external -j ${NWORKERS} -ns ${NSIGEVENTS} -tf ${NTIMEFRAMES} -e TGeant4 -mod "--skipModules ZDC" \ +${O2DPG_ROOT}/MC/bin/o2dpg_sim_workflow.py -eCM 5020 -gen external -j ${NWORKERS} -ns ${NSIGEVENTS} -tf ${NTIMEFRAMES} -e TGeant4 \ -confKey "GeneratorExternal.fileName=${O2DPG_ROOT}/MC/config/PWGDQ/external/generator/GeneratorCocktailPromptCharmoniaToMuonEvtGen_PbPb5TeV.C;GeneratorExternal.funcName=GeneratorCocktailPromptCharmoniaToMuonEvtGen_PbPb5TeV()" \ -genBkg pythia8 -procBkg "heavy_ion" -colBkg PbPb --embedding -nb ${NBKGEVENTS} --mft-assessment-full --fwdmatching-assessment-full --fwdmatching-save-trainingdata -interactionRate 500000 diff --git a/MC/run/PWGDQ/runPromptCharmonia_fwdy_pp.sh b/MC/run/PWGDQ/runPromptCharmonia_fwdy_pp.sh index 24f2c1fb5..7dbe40c4c 100755 --- a/MC/run/PWGDQ/runPromptCharmonia_fwdy_pp.sh +++ b/MC/run/PWGDQ/runPromptCharmonia_fwdy_pp.sh @@ -5,8 +5,6 @@ [ ! "${O2_ROOT}" ] && echo "Error: This needs O2 loaded" && exit 1 -# ----------- LOAD UTILITY FUNCTIONS -------------------------- -. ${O2_ROOT}/share/scripts/jobutils.sh RNDSEED=${RNDSEED:-0} NSIGEVENTS=${NSIGEVENTS:-1} @@ -15,7 +13,7 @@ NWORKERS=${NWORKERS:-8} NTIMEFRAMES=${NTIMEFRAMES:-1} TARGETTASK=${TARGETTASK:+-tt ${TARGETTASK}} -${O2DPG_ROOT}/MC/bin/o2dpg_sim_workflow.py -eCM 13600 -gen external -j ${NWORKERS} -ns ${NSIGEVENTS} -tf ${NTIMEFRAMES} -e TGeant4 -mod "--skipModules ZDC" \ +${O2DPG_ROOT}/MC/bin/o2dpg_sim_workflow.py -eCM 13600 -gen external -j ${NWORKERS} -ns ${NSIGEVENTS} -tf ${NTIMEFRAMES} -e TGeant4 \ -confKey "GeneratorExternal.fileName=${O2DPG_ROOT}/MC/config/PWGDQ/external/generator/GeneratorParamPromptJpsiToMuonEvtGen_pp13TeV.C;GeneratorExternal.funcName=GeneratorParamPromptJpsiToMuonEvtGen_pp13TeV()" \ -genBkg pythia8 -procBkg inel -colBkg pp --embedding -nb ${NBKGEVENTS} --fwdmatching-4-param --fwdmatching-cut-4-param -interactionRate 500000 diff --git a/MC/run/PWGDQ/runPromptCharmonia_fwdy_pp_assessment.sh b/MC/run/PWGDQ/runPromptCharmonia_fwdy_pp_assessment.sh index 348863a2f..7b6d2f294 100755 --- a/MC/run/PWGDQ/runPromptCharmonia_fwdy_pp_assessment.sh +++ b/MC/run/PWGDQ/runPromptCharmonia_fwdy_pp_assessment.sh @@ -5,8 +5,6 @@ [ ! "${O2_ROOT}" ] && echo "Error: This needs O2 loaded" && exit 1 -# ----------- LOAD UTILITY FUNCTIONS -------------------------- -. ${O2_ROOT}/share/scripts/jobutils.sh RNDSEED=${RNDSEED:-0} NSIGEVENTS=${NSIGEVENTS:-1} @@ -14,7 +12,7 @@ NBKGEVENTS=${NBKGEVENTS:-1} NWORKERS=${NWORKERS:-8} NTIMEFRAMES=${NTIMEFRAMES:-1} -${O2DPG_ROOT}/MC/bin/o2dpg_sim_workflow.py -eCM 900 -gen external -j ${NWORKERS} -ns ${NSIGEVENTS} -tf ${NTIMEFRAMES} -e TGeant4 -mod "--skipModules ZDC" \ +${O2DPG_ROOT}/MC/bin/o2dpg_sim_workflow.py -eCM 900 -gen external -j ${NWORKERS} -ns ${NSIGEVENTS} -tf ${NTIMEFRAMES} -e TGeant4 \ -confKey "GeneratorExternal.fileName=${O2DPG_ROOT}/MC/config/PWGDQ/external/generator/GeneratorCocktailPromptCharmoniaToMuonEvtGen_pp13TeV.C;GeneratorExternal.funcName=GeneratorCocktailPromptCharmoniaToMuonEvtGen_pp13TeV()" \ -genBkg pythia8 -procBkg inel -colBkg pp --embedding -nb ${NBKGEVENTS} --mft-assessment-full --fwdmatching-assessment-full -interactionRate 500000 diff --git a/MC/run/PWGDQ/runPromptCharmonia_fwdy_pp_assessment_triggerGap.sh b/MC/run/PWGDQ/runPromptCharmonia_fwdy_pp_assessment_triggerGap.sh index 5da085250..fb1a8ca90 100755 --- a/MC/run/PWGDQ/runPromptCharmonia_fwdy_pp_assessment_triggerGap.sh +++ b/MC/run/PWGDQ/runPromptCharmonia_fwdy_pp_assessment_triggerGap.sh @@ -5,8 +5,6 @@ [ ! "${O2_ROOT}" ] && echo "Error: This needs O2 loaded" && exit 1 -# ----------- LOAD UTILITY FUNCTIONS -------------------------- -. ${O2_ROOT}/share/scripts/jobutils.sh RNDSEED=${RNDSEED:-0} NSIGEVENTS=${NSIGEVENTS:-1} @@ -14,7 +12,7 @@ NBKGEVENTS=${NBKGEVENTS:-1} NWORKERS=${NWORKERS:-8} NTIMEFRAMES=${NTIMEFRAMES:-1} -${O2DPG_ROOT}/MC/bin/o2dpg_sim_workflow.py -eCM 13600 -gen external -j ${NWORKERS} -ns ${NSIGEVENTS} -tf ${NTIMEFRAMES} -e TGeant4 -mod "--skipModules ZDC" \ +${O2DPG_ROOT}/MC/bin/o2dpg_sim_workflow.py -eCM 13600 -gen external -j ${NWORKERS} -ns ${NSIGEVENTS} -tf ${NTIMEFRAMES} -e TGeant4 \ -ini $O2DPG_ROOT/MC/config/PWGDQ/ini/Generator_InjectedPromptCharmoniaFwdy_TriggerGap.ini --mft-assessment-full --fwdmatching-assessment-full -interactionRate 500000 # run workflow diff --git a/MC/run/PWGDQ/runPromptCharmonia_midy_pp.sh b/MC/run/PWGDQ/runPromptCharmonia_midy_pp.sh index 5a1a503ad..e2e9ec057 100755 --- a/MC/run/PWGDQ/runPromptCharmonia_midy_pp.sh +++ b/MC/run/PWGDQ/runPromptCharmonia_midy_pp.sh @@ -5,8 +5,6 @@ [ ! "${O2_ROOT}" ] && echo "Error: This needs O2 loaded" && exit 1 -# ----------- LOAD UTILITY FUNCTIONS -------------------------- -. ${O2_ROOT}/share/scripts/jobutils.sh RNDSEED=${RNDSEED:-0} NSIGEVENTS=${NSIGEVENTS:-1} @@ -14,7 +12,7 @@ NBKGEVENTS=${NBKGEVENTS:-1} NWORKERS=${NWORKERS:-8} NTIMEFRAMES=${NTIMEFRAMES:-1} -${O2DPG_ROOT}/MC/bin/o2dpg_sim_workflow.py -eCM 900 -gen external -j ${NWORKERS} -ns ${NSIGEVENTS} -tf ${NTIMEFRAMES} -e TGeant4 -mod "--skipModules ZDC" \ +${O2DPG_ROOT}/MC/bin/o2dpg_sim_workflow.py -eCM 900 -gen external -j ${NWORKERS} -ns ${NSIGEVENTS} -tf ${NTIMEFRAMES} -e TGeant4 \ -confKey "GeneratorExternal.fileName=${O2DPG_ROOT}/MC/config/PWGDQ/external/generator/GeneratorCocktailPromptCharmoniaToElectronEvtGen_pp13TeV.C;GeneratorExternal.funcName=GeneratorCocktailPromptCharmoniaToElectronEvtGen_pp13TeV()" \ -genBkg pythia8 -procBkg inel -colBkg pp --embedding -nb ${NBKGEVENTS} -interactionRate 500000 diff --git a/MC/run/PWGDQ/runPromptCharmonia_midy_pp_triggerGap.sh b/MC/run/PWGDQ/runPromptCharmonia_midy_pp_triggerGap.sh index 401d6ced2..ed549861a 100755 --- a/MC/run/PWGDQ/runPromptCharmonia_midy_pp_triggerGap.sh +++ b/MC/run/PWGDQ/runPromptCharmonia_midy_pp_triggerGap.sh @@ -5,8 +5,6 @@ [ ! "${O2_ROOT}" ] && echo "Error: This needs O2 loaded" && exit 1 -# ----------- LOAD UTILITY FUNCTIONS -------------------------- -. ${O2_ROOT}/share/scripts/jobutils.sh RNDSEED=${RNDSEED:-0} NSIGEVENTS=${NSIGEVENTS:-1} @@ -14,7 +12,7 @@ NBKGEVENTS=${NBKGEVENTS:-1} NWORKERS=${NWORKERS:-8} NTIMEFRAMES=${NTIMEFRAMES:-1} -${O2DPG_ROOT}/MC/bin/o2dpg_sim_workflow.py -eCM 13600 -interactionRate 500000 -gen external -j ${NWORKERS} -ns ${NSIGEVENTS} -tf ${NTIMEFRAMES} -e TGeant4 -mod "--skipModules ZDC" \ +${O2DPG_ROOT}/MC/bin/o2dpg_sim_workflow.py -eCM 13600 -interactionRate 500000 -gen external -j ${NWORKERS} -ns ${NSIGEVENTS} -tf ${NTIMEFRAMES} -e TGeant4 \ -ini $O2DPG_ROOT/MC/config/PWGDQ/ini/Generator_InjectedPromptCharmoniaMidy_TriggerGap.ini # run workflow diff --git a/MC/run/PWGDQ/runPromptJpsi_fwdy_pp_assessment_triggerGap.sh b/MC/run/PWGDQ/runPromptJpsi_fwdy_pp_assessment_triggerGap.sh index a784b4737..3634d30d2 100755 --- a/MC/run/PWGDQ/runPromptJpsi_fwdy_pp_assessment_triggerGap.sh +++ b/MC/run/PWGDQ/runPromptJpsi_fwdy_pp_assessment_triggerGap.sh @@ -5,8 +5,6 @@ [ ! "${O2_ROOT}" ] && echo "Error: This needs O2 loaded" && exit 1 -# ----------- LOAD UTILITY FUNCTIONS -------------------------- -. ${O2_ROOT}/share/scripts/jobutils.sh RNDSEED=${RNDSEED:-0} NSIGEVENTS=${NSIGEVENTS:-1} @@ -14,7 +12,7 @@ NBKGEVENTS=${NBKGEVENTS:-1} NWORKERS=${NWORKERS:-8} NTIMEFRAMES=${NTIMEFRAMES:-1} -${O2DPG_ROOT}/MC/bin/o2dpg_sim_workflow.py -eCM 13600 -gen external -j ${NWORKERS} -ns ${NSIGEVENTS} -tf ${NTIMEFRAMES} -e TGeant4 -mod "--skipModules ZDC" \ +${O2DPG_ROOT}/MC/bin/o2dpg_sim_workflow.py -eCM 13600 -gen external -j ${NWORKERS} -ns ${NSIGEVENTS} -tf ${NTIMEFRAMES} -e TGeant4 \ -ini $O2DPG_ROOT/MC/config/PWGDQ/ini/Generator_InjectedPromptJpsiFwdy_TriggerGap.ini --mft-assessment-full --fwdmatching-assessment-full -interactionRate 500000 # run workflow diff --git a/MC/run/PWGDQ/runPromptJpsi_midy_pp.sh b/MC/run/PWGDQ/runPromptJpsi_midy_pp.sh index 2398cd456..203aa4048 100755 --- a/MC/run/PWGDQ/runPromptJpsi_midy_pp.sh +++ b/MC/run/PWGDQ/runPromptJpsi_midy_pp.sh @@ -5,8 +5,6 @@ [ ! "${O2_ROOT}" ] && echo "Error: This needs O2 loaded" && exit 1 -# ----------- LOAD UTILITY FUNCTIONS -------------------------- -. ${O2_ROOT}/share/scripts/jobutils.sh RNDSEED=${RNDSEED:-0} NSIGEVENTS=${NSIGEVENTS:-1} @@ -14,7 +12,7 @@ NBKGEVENTS=${NBKGEVENTS:-1} NWORKERS=${NWORKERS:-8} NTIMEFRAMES=${NTIMEFRAMES:-1} -${O2DPG_ROOT}/MC/bin/o2dpg_sim_workflow.py -eCM 900 -gen external -j ${NWORKERS} -ns ${NSIGEVENTS} -tf ${NTIMEFRAMES} -e TGeant4 -mod "--skipModules ZDC" \ +${O2DPG_ROOT}/MC/bin/o2dpg_sim_workflow.py -eCM 900 -gen external -j ${NWORKERS} -ns ${NSIGEVENTS} -tf ${NTIMEFRAMES} -e TGeant4 \ -confKey "GeneratorExternal.fileName=${O2DPG_ROOT}/MC/config/PWGDQ/external/generator/GeneratorParamPromptJpsiToElectronEvtGen_pp13TeV.C;GeneratorExternal.funcName=GeneratorParamPromptJpsiToElectronEvtGen_pp13TeV()" \ -genBkg pythia8 -procBkg inel -colBkg pp --embedding -nb ${NBKGEVENTS} -interactionRate 500000 diff --git a/MC/run/PWGDQ/runPromptPsi2S_fwdy_pp_assessment_triggerGap.sh b/MC/run/PWGDQ/runPromptPsi2S_fwdy_pp_assessment_triggerGap.sh index 5baa5f223..caf085726 100755 --- a/MC/run/PWGDQ/runPromptPsi2S_fwdy_pp_assessment_triggerGap.sh +++ b/MC/run/PWGDQ/runPromptPsi2S_fwdy_pp_assessment_triggerGap.sh @@ -5,8 +5,6 @@ [ ! "${O2_ROOT}" ] && echo "Error: This needs O2 loaded" && exit 1 -# ----------- LOAD UTILITY FUNCTIONS -------------------------- -. ${O2_ROOT}/share/scripts/jobutils.sh RNDSEED=${RNDSEED:-0} NSIGEVENTS=${NSIGEVENTS:-1} @@ -14,7 +12,7 @@ NBKGEVENTS=${NBKGEVENTS:-1} NWORKERS=${NWORKERS:-8} NTIMEFRAMES=${NTIMEFRAMES:-1} -${O2DPG_ROOT}/MC/bin/o2dpg_sim_workflow.py -eCM 13600 -gen external -j ${NWORKERS} -ns ${NSIGEVENTS} -tf ${NTIMEFRAMES} -e TGeant4 -mod "--skipModules ZDC" \ +${O2DPG_ROOT}/MC/bin/o2dpg_sim_workflow.py -eCM 13600 -gen external -j ${NWORKERS} -ns ${NSIGEVENTS} -tf ${NTIMEFRAMES} -e TGeant4 \ -ini $O2DPG_ROOT/MC/config/PWGDQ/ini/Generator_InjectedPromptPsi2SFwdy_TriggerGap.ini --mft-assessment-full --fwdmatching-assessment-full -interactionRate 500000 # run workflow diff --git a/MC/run/PWGDQ/run_pp_JpsiHFcorr_ccbar_gaptrigger.sh b/MC/run/PWGDQ/run_pp_JpsiHFcorr_ccbar_gaptrigger.sh index 215a49e12..b18ba13cd 100755 --- a/MC/run/PWGDQ/run_pp_JpsiHFcorr_ccbar_gaptrigger.sh +++ b/MC/run/PWGDQ/run_pp_JpsiHFcorr_ccbar_gaptrigger.sh @@ -8,8 +8,6 @@ [ ! "${O2DPG_ROOT}" ] && echo "Error: This needs O2DPG loaded" && exit 1 [ ! "${O2_ROOT}" ] && echo "Error: This needs O2 loaded" && exit 1 -# ----------- LOAD UTILITY FUNCTIONS -------------------------- -. ${O2_ROOT}/share/scripts/jobutils.sh # ----------- START ACTUAL JOB ----------------------------- @@ -22,7 +20,7 @@ NTIMEFRAMES=${NTIMEFRAMES:-1} # create workflow #ccbar filter -${O2DPG_ROOT}/MC/bin/o2dpg_sim_workflow.py -eCM 13600 -col pp -gen external -j ${NWORKERS} -ns ${NSIGEVENTS} -tf ${NTIMEFRAMES} -interactionRate 500000 -confKey "Diamond.width[2]=6." -e ${SIMENGINE} ${SEED} -mod "--skipModules ZDC" \ +${O2DPG_ROOT}/MC/bin/o2dpg_sim_workflow.py -eCM 13600 -col pp -gen external -j ${NWORKERS} -ns ${NSIGEVENTS} -tf ${NTIMEFRAMES} -interactionRate 500000 -confKey "Diamond.width[2]=6." -e ${SIMENGINE} ${SEED} \ -ini $O2DPG_ROOT/MC/config/PWGDQ/ini/GeneratorJPsiHFCorr_ccbar.ini \ # run workflow diff --git a/MC/run/PWGEM/runAnchoredDYee_OO_5360_Gap2.sh b/MC/run/PWGEM/runAnchoredDYee_OO_5360_Gap2.sh new file mode 100644 index 000000000..9b36bcf51 --- /dev/null +++ b/MC/run/PWGEM/runAnchoredDYee_OO_5360_Gap2.sh @@ -0,0 +1,52 @@ +#!/bin/bash + +# +# Steering script for HF enhanced dielectron MC anchored to LHC25ae +# + +# example anchoring + +export ALIEN_JDL_LPMANCHORPASSNAME=apass2 +export ALIEN_JDL_MCANCHOR=apass2 +export ALIEN_JDL_CPULIMIT=8 +export ALIEN_JDL_LPMRUNNUMBER=564356 +export ALIEN_JDL_LPMPRODUCTIONTYPE=MC +export ALIEN_JDL_LPMINTERACTIONTYPE=pp +export ALIEN_JDL_LPMPRODUCTIONTAG=LHC26a2 +export ALIEN_JDL_LPMANCHORRUN=564356 +export ALIEN_JDL_LPMANCHORPRODUCTION=LHC25ae +export ALIEN_JDL_LPMANCHORYEAR=2025 +export ALIEN_JDL_OUTPUT=*.dat@disk=1,*.txt@disk=1,*.root@disk=2 + +export NTIMEFRAMES=1 +export NSIGEVENTS=20 +export SPLITID=100 +export PRODSPLIT=153 +export CYCLE=0 + +# on the GRID, this is set and used as seed; when set, it takes precedence over SEED +#export ALIEN_PROC_ID=2963436952 +export SEED=0 + +# for pp and 50 events per TF, we launch only 4 workers. +export NWORKERS=2 + +# define the generator via ini file +# use 30/70 sampling for different generators +# No forced beauty decays as we have observed biases + +# generate random number +RNDSIG=$(($RANDOM % 100)) + +CONFIGNAME="GeneratorDYee_GapTriggered_Gap2_OO5360GeV.ini" + +export ALIEN_JDL_ANCHOR_SIM_OPTIONS="-gen external -ini $O2DPG_ROOT/MC/config/PWGEM/ini/$CONFIGNAME" + +# run the central anchor steering script; this includes +# * derive timestamp +# * derive interaction rate +# * extract and prepare configurations (which detectors are contained in the run etc.) +# * run the simulation (and QC) +# To disable QC, uncomment the following line +#export DISABLE_QC=1 +${O2DPG_ROOT}/MC/run/ANCHOR/anchorMC.sh diff --git a/MC/run/PWGEM/runAnchoredDYee_OO_5360_Gap5.sh b/MC/run/PWGEM/runAnchoredDYee_OO_5360_Gap5.sh new file mode 100644 index 000000000..8767cae2d --- /dev/null +++ b/MC/run/PWGEM/runAnchoredDYee_OO_5360_Gap5.sh @@ -0,0 +1,52 @@ +#!/bin/bash + +# +# Steering script for HF enhanced dielectron MC anchored to LHC25ae +# + +# example anchoring + +export ALIEN_JDL_LPMANCHORPASSNAME=apass2 +export ALIEN_JDL_MCANCHOR=apass2 +export ALIEN_JDL_CPULIMIT=8 +export ALIEN_JDL_LPMRUNNUMBER=564356 +export ALIEN_JDL_LPMPRODUCTIONTYPE=MC +export ALIEN_JDL_LPMINTERACTIONTYPE=pp +export ALIEN_JDL_LPMPRODUCTIONTAG=LHC26a2 +export ALIEN_JDL_LPMANCHORRUN=564356 +export ALIEN_JDL_LPMANCHORPRODUCTION=LHC25ae +export ALIEN_JDL_LPMANCHORYEAR=2025 +export ALIEN_JDL_OUTPUT=*.dat@disk=1,*.txt@disk=1,*.root@disk=2 + +export NTIMEFRAMES=1 +export NSIGEVENTS=20 +export SPLITID=100 +export PRODSPLIT=153 +export CYCLE=0 + +# on the GRID, this is set and used as seed; when set, it takes precedence over SEED +#export ALIEN_PROC_ID=2963436952 +export SEED=0 + +# for pp and 50 events per TF, we launch only 4 workers. +export NWORKERS=2 + +# define the generator via ini file +# use 30/70 sampling for different generators +# No forced beauty decays as we have observed biases + +# generate random number +RNDSIG=$(($RANDOM % 100)) + +CONFIGNAME="GeneratorDYee_GapTriggered_Gap5_OO5360GeV.ini" + +export ALIEN_JDL_ANCHOR_SIM_OPTIONS="-gen external -ini $O2DPG_ROOT/MC/config/PWGEM/ini/$CONFIGNAME" + +# run the central anchor steering script; this includes +# * derive timestamp +# * derive interaction rate +# * extract and prepare configurations (which detectors are contained in the run etc.) +# * run the simulation (and QC) +# To disable QC, uncomment the following line +#export DISABLE_QC=1 +${O2DPG_ROOT}/MC/run/ANCHOR/anchorMC.sh diff --git a/MC/run/PWGEM/runAnchoredDYee_pp_13600_Gap5.sh b/MC/run/PWGEM/runAnchoredDYee_pp_13600_Gap5.sh new file mode 100644 index 000000000..77450c320 --- /dev/null +++ b/MC/run/PWGEM/runAnchoredDYee_pp_13600_Gap5.sh @@ -0,0 +1,50 @@ +#!/bin/bash + +# +# Steering script for HF enhanced dielectron MC anchored to LHC24ap,aq apass1 +# + +# example anchoring +# taken from https://its.cern.ch/jira/browse/O2-5670 +export ALIEN_JDL_LPMANCHORPASSNAME=apass1 +export ALIEN_JDL_MCANCHOR=apass1 +export ALIEN_JDL_CPULIMIT=8 +export ALIEN_JDL_LPMRUNNUMBER=559348 +export ALIEN_JDL_LPMPRODUCTIONTYPE=MC +export ALIEN_JDL_LPMINTERACTIONTYPE=pp +export ALIEN_JDL_LPMPRODUCTIONTAG=LHC24a6 +export ALIEN_JDL_LPMANCHORRUN=559348 +export ALIEN_JDL_LPMANCHORPRODUCTION=LHC26ac +export ALIEN_JDL_LPMANCHORYEAR=2026 +export ALIEN_JDL_OUTPUT=*.dat@disk=1,*.txt@disk=1,*.root@disk=2 + +export NTIMEFRAMES=1 +export NSIGEVENTS=20 +export SPLITID=100 +export PRODSPLIT=153 +export CYCLE=0 + +# on the GRID, this is set and used as seed; when set, it takes precedence over SEED +#export ALIEN_PROC_ID=2963436952 +export SEED=0 + +# for pp and 50 events per TF, we launch only 4 workers. +export NWORKERS=2 + +# define the generator via ini file +# use 20/40/40 sampling for different generators +# generate random number +#RNDSIG=$(($RANDOM % 100)) + +CONFIGNAME="GeneratorDYee_GapTriggered_Gap5_pp13600GeV.ini" + +export ALIEN_JDL_ANCHOR_SIM_OPTIONS="-gen external -ini $O2DPG_ROOT/MC/config/PWGEM/ini/$CONFIGNAME" + +# run the central anchor steering script; this includes +# * derive timestamp +# * derive interaction rate +# * extract and prepare configurations (which detectors are contained in the run etc.) +# * run the simulation (and QC) +# To disable QC, uncomment the following line +#export DISABLE_QC=1 +${O2DPG_ROOT}/MC/run/ANCHOR/anchorMC.sh diff --git a/MC/run/PWGEM/runAnchoredDYee_pp_5360_Gap5.sh b/MC/run/PWGEM/runAnchoredDYee_pp_5360_Gap5.sh new file mode 100644 index 000000000..6d703d179 --- /dev/null +++ b/MC/run/PWGEM/runAnchoredDYee_pp_5360_Gap5.sh @@ -0,0 +1,50 @@ +#!/bin/bash + +# +# Steering script for HF enhanced dielectron MC anchored to LHC24ap,aq apass1 +# + +# example anchoring +# taken from https://its.cern.ch/jira/browse/O2-5670 +export ALIEN_JDL_LPMANCHORPASSNAME=apass1 +export ALIEN_JDL_MCANCHOR=apass1 +export ALIEN_JDL_CPULIMIT=8 +export ALIEN_JDL_LPMRUNNUMBER=559348 +export ALIEN_JDL_LPMPRODUCTIONTYPE=MC +export ALIEN_JDL_LPMINTERACTIONTYPE=pp +export ALIEN_JDL_LPMPRODUCTIONTAG=LHC24a6 +export ALIEN_JDL_LPMANCHORRUN=559348 +export ALIEN_JDL_LPMANCHORPRODUCTION=LHC24ap +export ALIEN_JDL_LPMANCHORYEAR=2024 +export ALIEN_JDL_OUTPUT=*.dat@disk=1,*.txt@disk=1,*.root@disk=2 + +export NTIMEFRAMES=1 +export NSIGEVENTS=20 +export SPLITID=100 +export PRODSPLIT=153 +export CYCLE=0 + +# on the GRID, this is set and used as seed; when set, it takes precedence over SEED +#export ALIEN_PROC_ID=2963436952 +export SEED=0 + +# for pp and 50 events per TF, we launch only 4 workers. +export NWORKERS=2 + +# define the generator via ini file +# use 20/40/40 sampling for different generators +# generate random number +#RNDSIG=$(($RANDOM % 100)) + +CONFIGNAME="GeneratorDYee_GapTriggered_Gap5_pp5360GeV.ini" + +export ALIEN_JDL_ANCHOR_SIM_OPTIONS="-gen external -ini $O2DPG_ROOT/MC/config/PWGEM/ini/$CONFIGNAME" + +# run the central anchor steering script; this includes +# * derive timestamp +# * derive interaction rate +# * extract and prepare configurations (which detectors are contained in the run etc.) +# * run the simulation (and QC) +# To disable QC, uncomment the following line +#export DISABLE_QC=1 +${O2DPG_ROOT}/MC/run/ANCHOR/anchorMC.sh diff --git a/MC/run/PWGEM/runAnchoredHFGapToDielectrons_pp_5360_Gap5.sh b/MC/run/PWGEM/runAnchoredHFGapToDielectrons_pp_5360_Gap5.sh new file mode 100644 index 000000000..019a53415 --- /dev/null +++ b/MC/run/PWGEM/runAnchoredHFGapToDielectrons_pp_5360_Gap5.sh @@ -0,0 +1,57 @@ +#!/bin/bash + +# +# Steering script for HF enhanced dielectron MC anchored to LHC24ap,aq apass1 +# + +# example anchoring +# taken from https://its.cern.ch/jira/browse/O2-5670 +export ALIEN_JDL_LPMANCHORPASSNAME=apass1 +export ALIEN_JDL_MCANCHOR=apass1 +export ALIEN_JDL_CPULIMIT=8 +export ALIEN_JDL_LPMRUNNUMBER=559348 +export ALIEN_JDL_LPMPRODUCTIONTYPE=MC +export ALIEN_JDL_LPMINTERACTIONTYPE=pp +export ALIEN_JDL_LPMPRODUCTIONTAG=LHC24a6 +export ALIEN_JDL_LPMANCHORRUN=559348 +export ALIEN_JDL_LPMANCHORPRODUCTION=LHC24ap +export ALIEN_JDL_LPMANCHORYEAR=2024 +export ALIEN_JDL_OUTPUT=*.dat@disk=1,*.txt@disk=1,*.root@disk=2 + +export NTIMEFRAMES=1 +export NSIGEVENTS=20 +export SPLITID=100 +export PRODSPLIT=153 +export CYCLE=0 + +# on the GRID, this is set and used as seed; when set, it takes precedence over SEED +#export ALIEN_PROC_ID=2963436952 +export SEED=0 + +# for pp and 50 events per TF, we launch only 4 workers. +export NWORKERS=2 + +# define the generator via ini file +# use 20/40/40 sampling for different generators +# generate random number +RNDSIG=$(($RANDOM % 100)) + + +if [[ $RNDSIG -ge 0 && $RNDSIG -lt 20 ]]; +then + CONFIGNAME="GeneratorHFGapTriggered_Charm_Gap5_pp5360GeV.ini" +elif [[ $RNDSIG -ge 20 && $RNDSIG -lt 100 ]]; +then + CONFIGNAME="GeneratorHFGapTriggered_BeautyNoForcedDecay_Gap5_pp5360GeV.ini" +fi + +export ALIEN_JDL_ANCHOR_SIM_OPTIONS="-gen external -ini $O2DPG_ROOT/MC/config/PWGEM/ini/$CONFIGNAME" + +# run the central anchor steering script; this includes +# * derive timestamp +# * derive interaction rate +# * extract and prepare configurations (which detectors are contained in the run etc.) +# * run the simulation (and QC) +# To disable QC, uncomment the following line +#export DISABLE_QC=1 +${O2DPG_ROOT}/MC/run/ANCHOR/anchorMC.sh diff --git a/MC/run/PWGEM/runAnchoredHFGapToDielectrons_pp_Gap5.sh b/MC/run/PWGEM/runAnchoredHFGapToDielectrons_pp_Gap5.sh index 7547dcb0c..a3726aab3 100644 --- a/MC/run/PWGEM/runAnchoredHFGapToDielectrons_pp_Gap5.sh +++ b/MC/run/PWGEM/runAnchoredHFGapToDielectrons_pp_Gap5.sh @@ -37,13 +37,10 @@ export NWORKERS=2 RNDSIG=$(($RANDOM % 100)) -if [[ $RNDSIG -ge 0 && $RNDSIG -lt 30 ]]; +if [[ $RNDSIG -ge 0 && $RNDSIG -lt 20 ]]; then CONFIGNAME="GeneratorHFGapTriggered_Charm_Gap5.ini" -elif [[ $RNDSIG -ge 30 && $RNDSIG -lt 50 ]]; -then - CONFIGNAME="GeneratorHFGapTriggered_BeautyForcedDecay_Gap5.ini" -elif [[ $RNDSIG -ge 50 && $RNDSIG -lt 100 ]]; +elif [[ $RNDSIG -ge 20 && $RNDSIG -lt 100 ]]; then CONFIGNAME="GeneratorHFGapTriggered_BeautyNoForcedDecay_Gap5.ini" fi diff --git a/MC/run/PWGEM/runHFFullToDielectrons_pp.sh b/MC/run/PWGEM/runHFFullToDielectrons_pp.sh index 6393f9791..e17ba6516 100644 --- a/MC/run/PWGEM/runHFFullToDielectrons_pp.sh +++ b/MC/run/PWGEM/runHFFullToDielectrons_pp.sh @@ -8,8 +8,6 @@ export ALICEO2_CCDB_LOCALCACHE=$PWD/.ccdb -# ----------- LOAD UTILITY FUNCTIONS -------------------------- -. ${O2_ROOT}/share/scripts/jobutils.sh RNDSEED=${RNDSEED:-0} NSIGEVENTS=${NSIGEVENTS:-1} @@ -36,7 +34,7 @@ fi -${O2DPG_ROOT}/MC/bin/o2dpg_sim_workflow.py -eCM 13600 -col pp -gen external -j ${NWORKERS} -ns ${NSIGEVENTS} -tf ${NTIMEFRAMES} -e TGeant4 -mod "--skipModules ZDC" \ +${O2DPG_ROOT}/MC/bin/o2dpg_sim_workflow.py -eCM 13600 -col pp -gen external -j ${NWORKERS} -ns ${NSIGEVENTS} -tf ${NTIMEFRAMES} -e TGeant4 \ ${SEED} \ -trigger "external" -ini $O2DPG_ROOT/MC/config/PWGEM/ini/$CONFIGNAME \ -confKeyBkg "Diamond.width[2]=6" -interactionRate ${INTRATE} diff --git a/MC/run/PWGEM/runHFGapToDielectrons_pp.sh b/MC/run/PWGEM/runHFGapToDielectrons_pp.sh index bc884b56a..9cf1b5556 100644 --- a/MC/run/PWGEM/runHFGapToDielectrons_pp.sh +++ b/MC/run/PWGEM/runHFGapToDielectrons_pp.sh @@ -8,8 +8,6 @@ export ALICEO2_CCDB_LOCALCACHE=$PWD/.ccdb -# ----------- LOAD UTILITY FUNCTIONS -------------------------- -. ${O2_ROOT}/share/scripts/jobutils.sh RNDSEED=${RNDSEED:-0} NSIGEVENTS=${NSIGEVENTS:-1} @@ -37,7 +35,7 @@ fi -${O2DPG_ROOT}/MC/bin/o2dpg_sim_workflow.py -eCM 13600 -col pp -gen external -j ${NWORKERS} -ns ${NSIGEVENTS} -tf ${NTIMEFRAMES} -e TGeant4 -mod "--skipModules ZDC" \ +${O2DPG_ROOT}/MC/bin/o2dpg_sim_workflow.py -eCM 13600 -col pp -gen external -j ${NWORKERS} -ns ${NSIGEVENTS} -tf ${NTIMEFRAMES} -e TGeant4 \ ${SEED} \ -ini $O2DPG_ROOT/MC/config/PWGEM/ini/$CONFIGNAME \ -confKeyBkg "Diamond.width[2]=6" -interactionRate ${INTRATE} diff --git a/MC/run/PWGEM/runHFToDielectrons_PbPb.sh b/MC/run/PWGEM/runHFToDielectrons_PbPb.sh new file mode 100644 index 000000000..4193f6751 --- /dev/null +++ b/MC/run/PWGEM/runHFToDielectrons_PbPb.sh @@ -0,0 +1,51 @@ +#!/usr/bin/env bash + +RNDSEED=${RNDSEED:-0} +NWORKERS=${NWORKERS:-8} + + +export ALIEN_JDL_LPMPRODUCTIONTYPE=MC +export ALIEN_JDL_CPULIMIT=20 +export ALIEN_JDL_LPMANCHORPASSNAME=apass4 +export ALIEN_JDL_MCANCHOR=apass4 +export ALIEN_JDL_COLLISIONSYSTEM=PbPb +export ALIEN_JDL_LPMPASSNAME=apass4 +export ALIEN_JDL_LPMRUNNUMBER=544474 +export ALIEN_JDL_LPMANCHORRUN=544474 + +export ALIEN_JDL_LPMINTERACTIONTYPE=PbPb +export ALIEN_JDL_LPMPRODUCTIONTAG="TestProd17032026" +export ALIEN_JDL_LPMANCHORPRODUCTION="LHC26ac" +export ALIEN_JDL_LPMANCHORYEAR=2023 + +export ALIEN_JDL_O2DPGWORKFLOWTARGET="aod" + +export PRODSPLIT=${ALIEN_O2DPG_GRIDSUBMIT_PRODSPLIT:-10} +export SPLITID=${ALIEN_O2DPG_GRIDSUBMIT_SUBJOBID:-10} +export CYCLE=0 +export NTIMEFRAMES=8 +export NSIGEVENTS=20 +export NBKGEVENTS=10 + +# define the generator via ini file +# use 20/80 sampling for different generators +# generate random number +RNDSIG=$(($RANDOM % 100)) + + +if [[ $RNDSIG -ge 0 && $RNDSIG -lt 20 ]]; +then + CONFIGNAME="GeneratorHF_Charm_PbPb_electron.ini" +elif [[ $RNDSIG -ge 20 && $RNDSIG -lt 100 ]]; +then + CONFIGNAME="GeneratorHF_BeautyNoForcedDecay_PbPb_electron.ini" +fi + + +# generator and other sim configuration; parallel world for ITS +SIM_OPTIONS="-eCM 5360 -gen external -j ${NWORKERS} -tf ${NTIMEFRAMES} -e TGeant4 -seed 0 -ini ${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGEM/ini/$CONFIGNAME -genBkg pythia8 -procBkg \"heavy_ion\" -colBkg PbPb --embedding -nb $NBKGEVENTS" + +export ALIEN_JDL_ANCHOR_SIM_OPTIONS="${SIM_OPTIONS}" + +${O2DPG_ROOT}/MC/run/ANCHOR/anchorMC.sh + diff --git a/MC/run/PWGEM/runHFToDielectrons_pp.sh b/MC/run/PWGEM/runHFToDielectrons_pp.sh index 7f2ac8a38..ab41fe0ac 100644 --- a/MC/run/PWGEM/runHFToDielectrons_pp.sh +++ b/MC/run/PWGEM/runHFToDielectrons_pp.sh @@ -8,8 +8,6 @@ export ALICEO2_CCDB_LOCALCACHE=$PWD/.ccdb -# ----------- LOAD UTILITY FUNCTIONS -------------------------- -. ${O2_ROOT}/share/scripts/jobutils.sh RNDSEED=${RNDSEED:-0} NSIGEVENTS=${NSIGEVENTS:-1} @@ -35,7 +33,7 @@ fi -${O2DPG_ROOT}/MC/bin/o2dpg_sim_workflow.py -eCM 13600 -gen external -j ${NWORKERS} -ns ${NSIGEVENTS} -tf ${NTIMEFRAMES} -e TGeant4 -mod "--skipModules ZDC" \ +${O2DPG_ROOT}/MC/bin/o2dpg_sim_workflow.py -eCM 13600 -gen external -j ${NWORKERS} -ns ${NSIGEVENTS} -tf ${NTIMEFRAMES} -e TGeant4 \ -trigger "external" -ini $O2DPG_ROOT/MC/config/PWGEM/ini/$CONFIGNAME \ -genBkg pythia8 -procBkg cdiff -colBkg pp --embedding -nb ${NBKGEVENTS} \ -confKeyBkg "Diamond.width[2]=6" -interactionRate 500000 diff --git a/MC/run/PWGEM/runHfToDielectrons_OO_Gap2.sh b/MC/run/PWGEM/runHfToDielectrons_OO_Gap2.sh new file mode 100644 index 000000000..8026630ff --- /dev/null +++ b/MC/run/PWGEM/runHfToDielectrons_OO_Gap2.sh @@ -0,0 +1,59 @@ +#!/bin/bash + +# +# Steering script for HF enhanced dielectron MC anchored to LHC25ae +# + +# example anchoring + +export ALIEN_JDL_LPMANCHORPASSNAME=apass2 +export ALIEN_JDL_MCANCHOR=apass2 +export ALIEN_JDL_CPULIMIT=8 +export ALIEN_JDL_LPMRUNNUMBER=564356 +export ALIEN_JDL_LPMPRODUCTIONTYPE=MC +export ALIEN_JDL_LPMINTERACTIONTYPE=pp +export ALIEN_JDL_LPMPRODUCTIONTAG=LHC26a2 +export ALIEN_JDL_LPMANCHORRUN=564356 +export ALIEN_JDL_LPMANCHORPRODUCTION=LHC25ae +export ALIEN_JDL_LPMANCHORYEAR=2025 +export ALIEN_JDL_OUTPUT=*.dat@disk=1,*.txt@disk=1,*.root@disk=2 + +export NTIMEFRAMES=1 +export NSIGEVENTS=20 +export SPLITID=100 +export PRODSPLIT=153 +export CYCLE=0 + +# on the GRID, this is set and used as seed; when set, it takes precedence over SEED +#export ALIEN_PROC_ID=2963436952 +export SEED=0 + +# for pp and 50 events per TF, we launch only 4 workers. +export NWORKERS=2 + +# define the generator via ini file +# use 30/70 sampling for different generators +# No forced beauty decays as we have observed biases + +# generate random number +RNDSIG=$(($RANDOM % 100)) + + +if [[ $RNDSIG -ge 0 && $RNDSIG -lt 30 ]]; +then + CONFIGNAME="GeneratorHFGapTriggered_Charm_Gap2_OO_electron.ini" +elif [[ $RNDSIG -ge 30 && $RNDSIG -lt 100 ]]; +then + CONFIGNAME="GeneratorHFGapTriggered_BeautyNoForcedDecay_Gap2_OO_electron.ini" +fi + +export ALIEN_JDL_ANCHOR_SIM_OPTIONS="-gen external -ini $O2DPG_ROOT/MC/config/PWGEM/ini/$CONFIGNAME" + +# run the central anchor steering script; this includes +# * derive timestamp +# * derive interaction rate +# * extract and prepare configurations (which detectors are contained in the run etc.) +# * run the simulation (and QC) +# To disable QC, uncomment the following line +#export DISABLE_QC=1 +${O2DPG_ROOT}/MC/run/ANCHOR/anchorMC.sh diff --git a/MC/run/PWGEM/runPythia8GapTriggeredLFee_pp.sh b/MC/run/PWGEM/runPythia8GapTriggeredLFee_pp.sh index 281dcccf3..8b34e2b78 100644 --- a/MC/run/PWGEM/runPythia8GapTriggeredLFee_pp.sh +++ b/MC/run/PWGEM/runPythia8GapTriggeredLFee_pp.sh @@ -8,8 +8,6 @@ export ALICEO2_CCDB_LOCALCACHE=$PWD/.ccdb -# ----------- LOAD UTILITY FUNCTIONS -------------------------- -. ${O2_ROOT}/share/scripts/jobutils.sh NSIGEVENTS=${NSIGEVENTS:-10} NWORKERS=${NWORKERS:-8} @@ -20,7 +18,7 @@ NP=${NP:-1} CONFIGNAME="Generator_GapTriggered_LFee_all_np${NP}_gap${GAP}.ini" -${O2DPG_ROOT}/MC/bin/o2dpg_sim_workflow.py -eCM 13600 -col pp -gen external -j ${NWORKERS} -ns ${NSIGEVENTS} -tf ${NTIMEFRAMES} -e TGeant4 -mod "--skipModules ZDC" \ +${O2DPG_ROOT}/MC/bin/o2dpg_sim_workflow.py -eCM 13600 -col pp -gen external -j ${NWORKERS} -ns ${NSIGEVENTS} -tf ${NTIMEFRAMES} -e TGeant4 \ -ini $O2DPG_ROOT/MC/config/PWGEM/ini/$CONFIGNAME \ -confKeyBkg "Diamond.width[2]=6" -interactionRate ${INTRATE} diff --git a/MC/run/PWGEM/runPythia8GapTriggeredLFgamma_pp.sh b/MC/run/PWGEM/runPythia8GapTriggeredLFgamma_pp.sh index 7d23cd4e9..76a456f2f 100644 --- a/MC/run/PWGEM/runPythia8GapTriggeredLFgamma_pp.sh +++ b/MC/run/PWGEM/runPythia8GapTriggeredLFgamma_pp.sh @@ -8,8 +8,6 @@ export ALICEO2_CCDB_LOCALCACHE=$PWD/.ccdb -# ----------- LOAD UTILITY FUNCTIONS -------------------------- -. ${O2_ROOT}/share/scripts/jobutils.sh NSIGEVENTS=${NSIGEVENTS:-10} NWORKERS=${NWORKERS:-8} @@ -20,7 +18,7 @@ NP=${NP:-1} CONFIGNAME="Generator_GapTriggered_LFgamma_np${NP}_gap${GAP}.ini" -${O2DPG_ROOT}/MC/bin/o2dpg_sim_workflow.py -eCM 13600 -col pp -gen external -j ${NWORKERS} -ns ${NSIGEVENTS} -tf ${NTIMEFRAMES} -e TGeant4 -mod "--skipModules ZDC" \ +${O2DPG_ROOT}/MC/bin/o2dpg_sim_workflow.py -eCM 13600 -col pp -gen external -j ${NWORKERS} -ns ${NSIGEVENTS} -tf ${NTIMEFRAMES} -e TGeant4 \ -ini $O2DPG_ROOT/MC/config/PWGEM/ini/$CONFIGNAME \ -confKeyBkg "Diamond.width[2]=6" -interactionRate ${INTRATE} diff --git a/MC/run/PWGEM/runPythia8GapTriggeredLFmumu_pp.sh b/MC/run/PWGEM/runPythia8GapTriggeredLFmumu_pp.sh index 4cfb459a8..85642a50c 100644 --- a/MC/run/PWGEM/runPythia8GapTriggeredLFmumu_pp.sh +++ b/MC/run/PWGEM/runPythia8GapTriggeredLFmumu_pp.sh @@ -8,8 +8,6 @@ #export ALICEO2_CCDB_LOCALCACHE=$PWD/.ccdb -# ----------- LOAD UTILITY FUNCTIONS -------------------------- -#. ${O2_ROOT}/share/scripts/jobutils.sh #NSIGEVENTS=${NSIGEVENTS:-10} #NWORKERS=${NWORKERS:-8} @@ -18,7 +16,7 @@ #CONFIGNAME="Generator_GapTriggered_LFmumu_np1_gap5.ini" -#${O2DPG_ROOT}/MC/bin/o2dpg_sim_workflow.py -eCM 13600 -col pp -gen external -j ${NWORKERS} -ns ${NSIGEVENTS} -tf ${NTIMEFRAMES} -e TGeant4 -mod "--skipModules ZDC" \ +#${O2DPG_ROOT}/MC/bin/o2dpg_sim_workflow.py -eCM 13600 -col pp -gen external -j ${NWORKERS} -ns ${NSIGEVENTS} -tf ${NTIMEFRAMES} -e TGeant4 \ #-ini $O2DPG_ROOT/MC/config/PWGEM/ini/$CONFIGNAME \ #-confKeyBkg "Diamond.width[2]=6" -interactionRate ${INTRATE} @@ -35,8 +33,6 @@ export ALICEO2_CCDB_LOCALCACHE=$PWD/.ccdb -# ----------- LOAD UTILITY FUNCTIONS -------------------------- -. ${O2_ROOT}/share/scripts/jobutils.sh NSIGEVENTS=${NSIGEVENTS:-10} NWORKERS=${NWORKERS:-8} @@ -45,7 +41,7 @@ INTRATE=${INTRATE:-500000} CONFIGNAME="Generator_GapTriggered_LFmumu.ini" -${O2DPG_ROOT}/MC/bin/o2dpg_sim_workflow.py -eCM 13600 -col pp -gen external -j ${NWORKERS} -ns ${NSIGEVENTS} -tf ${NTIMEFRAMES} -e TGeant4 -mod "--skipModules ZDC" \ +${O2DPG_ROOT}/MC/bin/o2dpg_sim_workflow.py -eCM 13600 -col pp -gen external -j ${NWORKERS} -ns ${NSIGEVENTS} -tf ${NTIMEFRAMES} -e TGeant4 \ -ini $O2DPG_ROOT/MC/config/PWGEM/ini/$CONFIGNAME \ -confKeyBkg "Diamond.width[2]=6" -interactionRate ${INTRATE} diff --git a/MC/run/PWGGAJE/run_decaygammajets.sh b/MC/run/PWGGAJE/run_decaygammajets.sh index 81283e219..039b6ac5b 100755 --- a/MC/run/PWGGAJE/run_decaygammajets.sh +++ b/MC/run/PWGGAJE/run_decaygammajets.sh @@ -9,8 +9,6 @@ #set -x -# ----------- LOAD UTILITY FUNCTIONS -------------------------- -. ${O2_ROOT}/share/scripts/jobutils.sh # ----------- START ACTUAL JOB ----------------------------- @@ -79,7 +77,7 @@ echo 'Detector acceptance option ' $PARTICLE_ACCEPTANCE ${O2DPG_ROOT}/MC/bin/o2dpg_sim_workflow.py -eCM ${CONFIG_ENERGY} -col pp -gen pythia8 -proc "jets" \ -ptHatMin ${PTHATMIN} -ptHatMax ${PTHATMAX} \ -tf ${NTIMEFRAMES} -ns ${NSIGEVENTS} -e ${SIMENGINE} \ - -j ${NWORKERS} -mod "--skipModules ZDC" \ + -j ${NWORKERS} \ -weightPow ${WEIGHTPOW} \ -trigger "external" -ini "\$O2DPG_ROOT/MC/config/PWGGAJE/ini/trigger_decay_gamma.ini" diff --git a/MC/run/PWGGAJE/run_dirgamma.sh b/MC/run/PWGGAJE/run_dirgamma.sh index 30403128c..daca947f2 100755 --- a/MC/run/PWGGAJE/run_dirgamma.sh +++ b/MC/run/PWGGAJE/run_dirgamma.sh @@ -9,8 +9,6 @@ #set -x -# ----------- LOAD UTILITY FUNCTIONS -------------------------- -. ${O2_ROOT}/share/scripts/jobutils.sh # ----------- START ACTUAL JOB ----------------------------- @@ -63,7 +61,7 @@ echo 'Parton PDG option ' $CONFIG_OUTPARTON_PDG ${O2DPG_ROOT}/MC/bin/o2dpg_sim_workflow.py -eCM ${CONFIG_ENERGY} -col pp -gen pythia8 -proc "dirgamma" \ -ptHatMin ${PTHATMIN} -ptHatMax ${PTHATMAX} \ -tf ${NTIMEFRAMES} -ns ${NSIGEVENTS} -e ${SIMENGINE} \ - -j ${NWORKERS} -mod "--skipModules ZDC" \ + -j ${NWORKERS} \ -weightPow ${WEIGHTPOW} \ -trigger "external" -ini "\$O2DPG_ROOT/MC/config/PWGGAJE/ini/trigger_prompt_gamma.ini" diff --git a/MC/run/PWGGAJE/run_dirgamma_embedding.sh b/MC/run/PWGGAJE/run_dirgamma_embedding.sh index 938bbe979..c867a3759 100755 --- a/MC/run/PWGGAJE/run_dirgamma_embedding.sh +++ b/MC/run/PWGGAJE/run_dirgamma_embedding.sh @@ -6,8 +6,6 @@ #set -x -# ----------- LOAD UTILITY FUNCTIONS -------------------------- -. ${O2_ROOT}/share/scripts/jobutils.sh # ----------- START ACTUAL JOB ----------------------------- @@ -61,7 +59,7 @@ ${O2DPG_ROOT}/MC/bin/o2dpg_sim_workflow.py -eCM ${CONFIG_ENERGY} -col pp -gen pythia8 -proc "dirgamma" \ -ptHatMin ${PTHATMIN} -ptHatMax ${PTHATMAX} \ -tf ${NTIMEFRAMES} -ns ${NSIGEVENTS} -e ${SIMENGINE} \ - -j ${NWORKERS} -mod "--skipModules ZDC" \ + -j ${NWORKERS} \ -weightPow ${WEIGHTPOW} \ -trigger "external" -ini "\$O2DPG_ROOT/MC/config/PWGGAJE/ini/trigger_prompt_gamma.ini" diff --git a/MC/run/PWGGAJE/run_dirgamma_hook.sh b/MC/run/PWGGAJE/run_dirgamma_hook.sh index af2d98b13..8b108f4d7 100755 --- a/MC/run/PWGGAJE/run_dirgamma_hook.sh +++ b/MC/run/PWGGAJE/run_dirgamma_hook.sh @@ -9,8 +9,6 @@ #set -x -# ----------- LOAD UTILITY FUNCTIONS -------------------------- -. ${O2_ROOT}/share/scripts/jobutils.sh # ----------- START ACTUAL JOB ----------------------------- @@ -63,7 +61,7 @@ echo 'Parton PDG option ' $CONFIG_OUTPARTON_PDG ${O2DPG_ROOT}/MC/bin/o2dpg_sim_workflow.py -eCM ${CONFIG_ENERGY} -col pp -gen pythia8 -proc "dirgamma" \ -ptHatMin ${PTHATMIN} -ptHatMax ${PTHATMAX} \ -tf ${NTIMEFRAMES} -ns ${NSIGEVENTS} -e ${SIMENGINE} \ - -j ${NWORKERS} -mod "--skipModules ZDC" \ + -j ${NWORKERS} \ -weightPow ${WEIGHTPOW} \ -ini "\$O2DPG_ROOT/MC/config/PWGGAJE/ini/hook_prompt_gamma.ini" diff --git a/MC/run/PWGGAJE/run_dirgamma_hook_embedding.sh b/MC/run/PWGGAJE/run_dirgamma_hook_embedding.sh index 60e8d5371..8d6a37b83 100755 --- a/MC/run/PWGGAJE/run_dirgamma_hook_embedding.sh +++ b/MC/run/PWGGAJE/run_dirgamma_hook_embedding.sh @@ -10,8 +10,6 @@ #set -x -# ----------- LOAD UTILITY FUNCTIONS -------------------------- -. ${O2_ROOT}/share/scripts/jobutils.sh # ----------- START ACTUAL JOB ----------------------------- @@ -67,7 +65,7 @@ ${O2DPG_ROOT}/MC/bin/o2dpg_sim_workflow.py -eCM ${CONFIG_ENERGY} -col pp -gen pythia8 -proc "dirgamma" \ -ptHatMin ${PTHATMIN} -ptHatMax ${PTHATMAX} \ -tf ${NTIMEFRAMES} -ns ${NSIGEVENTS} -e ${SIMENGINE} \ - -j ${NWORKERS} -mod "--skipModules ZDC" \ + -j ${NWORKERS} \ -weightPow ${WEIGHTPOW} \ -ini "\$O2DPG_ROOT/MC/config/PWGGAJE/ini/hook_prompt_gamma.ini" diff --git a/MC/run/PWGGAJE/run_jets.sh b/MC/run/PWGGAJE/run_jets.sh index a15530f3b..9e31cbcd0 100755 --- a/MC/run/PWGGAJE/run_jets.sh +++ b/MC/run/PWGGAJE/run_jets.sh @@ -5,8 +5,6 @@ #set -x -# ----------- LOAD UTILITY FUNCTIONS -------------------------- -. ${O2_ROOT}/share/scripts/jobutils.sh # ----------- START ACTUAL JOB ----------------------------- @@ -42,7 +40,7 @@ fi ${O2DPG_ROOT}/MC/bin/o2dpg_sim_workflow.py -eCM ${CONFIG_ENERGY} -col pp -gen pythia8 -proc "jets" \ -ptHatMin ${PTHATMIN} -ptHatMax ${PTHATMAX} \ -tf ${NTIMEFRAMES} -ns ${NSIGEVENTS} -e ${SIMENGINE} \ - -j ${NWORKERS} -mod "--skipModules ZDC" \ + -j ${NWORKERS} \ -weightPow ${WEIGHTPOW} -interactionRate 500000 # run workflow diff --git a/MC/run/PWGGAJE/run_jets_HF_bbbar.sh b/MC/run/PWGGAJE/run_jets_HF_bbbar.sh index be00d7fe9..d9749d300 100644 --- a/MC/run/PWGGAJE/run_jets_HF_bbbar.sh +++ b/MC/run/PWGGAJE/run_jets_HF_bbbar.sh @@ -7,8 +7,6 @@ [ ! "${O2DPG_ROOT}" ] && echo "Error: This needs O2DPG loaded" && exit 1 [ ! "${O2_ROOT}" ] && echo "Error: This needs O2 loaded" && exit 1 -# ----------- LOAD UTILITY FUNCTIONS -------------------------- -. ${O2_ROOT}/share/scripts/jobutils.sh # ----------- START ACTUAL JOB ----------------------------- @@ -47,7 +45,7 @@ fi ${O2DPG_ROOT}/MC/bin/o2dpg_sim_workflow.py -eCM ${CONFIG_ENERGY} -col pp -gen external -proc "jets" \ -ptHatMin ${PTHATMIN} -ptHatMax ${PTHATMAX} \ -tf ${NTIMEFRAMES} -ns ${NSIGEVENTS} -e ${SIMENGINE} \ - -j ${NWORKERS} -mod "--skipModules ZDC" \ + -j ${NWORKERS} \ -interactionRate 500000 -confKey "Diamond.width[2]=6." ${SEED} \ -ini $O2DPG_ROOT/MC/config/PWGHF/ini/GeneratorHFTrigger_bbbar.ini \ -weightPow ${WEIGHTPOW} diff --git a/MC/run/PWGGAJE/run_jets_HF_ccbar.sh b/MC/run/PWGGAJE/run_jets_HF_ccbar.sh index 9b155ba2b..22aece831 100644 --- a/MC/run/PWGGAJE/run_jets_HF_ccbar.sh +++ b/MC/run/PWGGAJE/run_jets_HF_ccbar.sh @@ -7,8 +7,6 @@ [ ! "${O2DPG_ROOT}" ] && echo "Error: This needs O2DPG loaded" && exit 1 [ ! "${O2_ROOT}" ] && echo "Error: This needs O2 loaded" && exit 1 -# ----------- LOAD UTILITY FUNCTIONS -------------------------- -. ${O2_ROOT}/share/scripts/jobutils.sh # ----------- START ACTUAL JOB ----------------------------- @@ -26,7 +24,7 @@ SIMENGINE=${SIMENGINE:-TGeant4} #ccbar filter and bias2SelectionPow and PtHat settings are in the ini file given below ${O2DPG_ROOT}/MC/bin/o2dpg_sim_workflow.py -eCM ${CONFIG_ENERGY} -col pp -gen external -proc "jets" \ -tf ${NTIMEFRAMES} -ns ${NSIGEVENTS} -e ${SIMENGINE} \ - -j ${NWORKERS} -mod "--skipModules ZDC" \ + -j ${NWORKERS} \ -interactionRate 500000 -confKey "Diamond.width[2]=6." ${SEED} \ -ini $O2DPG_ROOT/MC/config/PWGGAJE/ini/GeneratorHFJETrigger_ccbar.ini diff --git a/MC/run/PWGGAJE/run_jets_embedding.sh b/MC/run/PWGGAJE/run_jets_embedding.sh index 103f986b2..d58ed2aca 100755 --- a/MC/run/PWGGAJE/run_jets_embedding.sh +++ b/MC/run/PWGGAJE/run_jets_embedding.sh @@ -7,8 +7,6 @@ #set -x -# ----------- LOAD UTILITY FUNCTIONS -------------------------- -. ${O2_ROOT}/share/scripts/jobutils.sh # ----------- START ACTUAL JOB ----------------------------- @@ -47,7 +45,7 @@ ${O2DPG_ROOT}/MC/bin/o2dpg_sim_workflow.py -eCM ${CONFIG_ENERGY} \ -col pp -gen pythia8 -proc "jets" \ -ptHatMin ${PTHATMIN} -ptHatMax ${PTHATMAX} \ -tf ${NTIMEFRAMES} -ns ${NSIGEVENTS} -e ${SIMENGINE} \ - -j ${NWORKERS} -mod "--skipModules ZDC" \ + -j ${NWORKERS} \ -weightPow ${WEIGHTPOW} -interactionRate 500000 # run workflow ${O2DPG_ROOT}/MC/bin/o2_dpg_workflow_runner.py -f workflow.json diff --git a/MC/run/PWGGAJE/run_jets_hook.sh b/MC/run/PWGGAJE/run_jets_hook.sh index 45fc8eab2..66a557813 100755 --- a/MC/run/PWGGAJE/run_jets_hook.sh +++ b/MC/run/PWGGAJE/run_jets_hook.sh @@ -5,8 +5,6 @@ #set -x -# ----------- LOAD UTILITY FUNCTIONS -------------------------- -. ${O2_ROOT}/share/scripts/jobutils.sh # ----------- START ACTUAL JOB ----------------------------- @@ -59,7 +57,7 @@ echo 'Parton PDG option ' $CONFIG_OUTPARTON_PDG ${O2DPG_ROOT}/MC/bin/o2dpg_sim_workflow.py -eCM ${CONFIG_ENERGY} -col pp -gen pythia8 -proc "jets" \ -ptHatMin ${PTHATMIN} -ptHatMax ${PTHATMAX} \ -tf ${NTIMEFRAMES} -ns ${NSIGEVENTS} -e ${SIMENGINE} \ - -j ${NWORKERS} -mod "--skipModules ZDC" \ + -j ${NWORKERS} \ -ini "\$O2DPG_ROOT/MC/config/PWGGAJE/ini/hook_jets.ini" \ -weightPow ${WEIGHTPOW} # run workflow diff --git a/MC/run/PWGHF/analysis_benchmark.sh b/MC/run/PWGHF/analysis_benchmark.sh index 9f57cdb57..172a85f3d 100755 --- a/MC/run/PWGHF/analysis_benchmark.sh +++ b/MC/run/PWGHF/analysis_benchmark.sh @@ -10,8 +10,6 @@ [ ! "${O2DPG_ROOT}" ] && echo "Error: This needs O2DPG loaded" && exit 1 [ ! "${O2_ROOT}" ] && echo "Error: This needs O2 loaded" && exit 1 -# ----------- LOAD UTILITY FUNCTIONS -------------------------- -. ${O2_ROOT}/share/scripts/jobutils.sh # ----------- START ACTUAL JOB ----------------------------- diff --git a/MC/run/PWGHF/run_OmegaCInjected.sh b/MC/run/PWGHF/run_OmegaCInjected.sh index 29c354952..924f4b3e7 100755 --- a/MC/run/PWGHF/run_OmegaCInjected.sh +++ b/MC/run/PWGHF/run_OmegaCInjected.sh @@ -8,8 +8,6 @@ [ ! "${O2DPG_ROOT}" ] && echo "Error: This needs O2DPG loaded" && exit 1 [ ! "${O2_ROOT}" ] && echo "Error: This needs O2 loaded" && exit 1 -# ----------- LOAD UTILITY FUNCTIONS -------------------------- -. ${O2_ROOT}/share/scripts/jobutils.sh # ----------- START ACTUAL JOB ----------------------------- @@ -27,7 +25,7 @@ SYSTEM=${SYSTEM:-pp} ENERGY=${ENERGY:-13600} [[ ${SPLITID} != "" ]] && SEED="-seed ${SPLITID}" || SEED="" -${O2DPG_ROOT}/MC/bin/o2dpg_sim_workflow.py -e ${SIMENGINE} ${SEED} -eCM 13600 -col pp -colBkg pp -gen external -genBkg pythia8 -procBkg inel -j ${NWORKERS} -ns ${NSIGEVENTS} -nb ${NBKGEVENTS} -tf ${NTIMEFRAMES} -interactionRate 500000 -confKey "Diamond.width[2]=6." -mod "--skipModules ZDC" \ +${O2DPG_ROOT}/MC/bin/o2dpg_sim_workflow.py -e ${SIMENGINE} ${SEED} -eCM 13600 -col pp -colBkg pp -gen external -genBkg pythia8 -procBkg inel -j ${NWORKERS} -ns ${NSIGEVENTS} -nb ${NBKGEVENTS} -tf ${NTIMEFRAMES} -interactionRate 500000 -confKey "Diamond.width[2]=6." \ --embedding -ini $O2DPG_ROOT/MC/config/PWGHF/ini/GeneratorHFOmegaCEmb.ini diff --git a/MC/run/PWGHF/run_OmegaCToXiPiInjected.sh b/MC/run/PWGHF/run_OmegaCToXiPiInjected.sh index 14a73e330..0584ebe13 100755 --- a/MC/run/PWGHF/run_OmegaCToXiPiInjected.sh +++ b/MC/run/PWGHF/run_OmegaCToXiPiInjected.sh @@ -8,8 +8,6 @@ [ ! "${O2DPG_ROOT}" ] && echo "Error: This needs O2DPG loaded" && exit 1 [ ! "${O2_ROOT}" ] && echo "Error: This needs O2 loaded" && exit 1 -# ----------- LOAD UTILITY FUNCTIONS -------------------------- -. ${O2_ROOT}/share/scripts/jobutils.sh # ----------- START ACTUAL JOB ----------------------------- @@ -27,7 +25,7 @@ SYSTEM=${SYSTEM:-pp} ENERGY=${ENERGY:-13600} [[ ${SPLITID} != "" ]] && SEED="-seed ${SPLITID}" || SEED="" -${O2DPG_ROOT}/MC/bin/o2dpg_sim_workflow.py -e ${SIMENGINE} ${SEED} -eCM 13600 -col pp -colBkg pp -gen external -genBkg pythia8 -procBkg inel -j ${NWORKERS} -ns ${NSIGEVENTS} -nb ${NBKGEVENTS} -tf ${NTIMEFRAMES} -interactionRate 500000 -confKey "Diamond.width[2]=6." -mod "--skipModules ZDC" \ +${O2DPG_ROOT}/MC/bin/o2dpg_sim_workflow.py -e ${SIMENGINE} ${SEED} -eCM 13600 -col pp -colBkg pp -gen external -genBkg pythia8 -procBkg inel -j ${NWORKERS} -ns ${NSIGEVENTS} -nb ${NBKGEVENTS} -tf ${NTIMEFRAMES} -interactionRate 500000 -confKey "Diamond.width[2]=6." \ --embedding -ini $O2DPG_ROOT/MC/config/PWGHF/ini/GeneratorHFOmegaCToXiPiEmb.ini diff --git a/MC/run/PWGHF/run_XiCToXiPiInjected.sh b/MC/run/PWGHF/run_XiCToXiPiInjected.sh index 34b2aad89..112eb49a6 100755 --- a/MC/run/PWGHF/run_XiCToXiPiInjected.sh +++ b/MC/run/PWGHF/run_XiCToXiPiInjected.sh @@ -8,8 +8,6 @@ [ ! "${O2DPG_ROOT}" ] && echo "Error: This needs O2DPG loaded" && exit 1 [ ! "${O2_ROOT}" ] && echo "Error: This needs O2 loaded" && exit 1 -# ----------- LOAD UTILITY FUNCTIONS -------------------------- -. ${O2_ROOT}/share/scripts/jobutils.sh # ----------- START ACTUAL JOB ----------------------------- @@ -27,7 +25,7 @@ SYSTEM=${SYSTEM:-pp} ENERGY=${ENERGY:-13600} [[ ${SPLITID} != "" ]] && SEED="-seed ${SPLITID}" || SEED="" -${O2DPG_ROOT}/MC/bin/o2dpg_sim_workflow.py -e ${SIMENGINE} ${SEED} -eCM 13600 -col pp -colBkg pp -gen external -genBkg pythia8 -procBkg inel -j ${NWORKERS} -ns ${NSIGEVENTS} -nb ${NBKGEVENTS} -tf ${NTIMEFRAMES} -interactionRate 500000 -confKey "Diamond.width[2]=6." -mod "--skipModules ZDC" \ +${O2DPG_ROOT}/MC/bin/o2dpg_sim_workflow.py -e ${SIMENGINE} ${SEED} -eCM 13600 -col pp -colBkg pp -gen external -genBkg pythia8 -procBkg inel -j ${NWORKERS} -ns ${NSIGEVENTS} -nb ${NBKGEVENTS} -tf ${NTIMEFRAMES} -interactionRate 500000 -confKey "Diamond.width[2]=6." \ --embedding -ini $O2DPG_ROOT/MC/config/PWGHF/ini/GeneratorHFXiCToXiPiEmb.ini diff --git a/MC/run/PWGHF/run_pp_HFtriggers_Bforced_gaptrigger.sh b/MC/run/PWGHF/run_pp_HFtriggers_Bforced_gaptrigger.sh index 517c79352..ccec3bbb9 100755 --- a/MC/run/PWGHF/run_pp_HFtriggers_Bforced_gaptrigger.sh +++ b/MC/run/PWGHF/run_pp_HFtriggers_Bforced_gaptrigger.sh @@ -8,8 +8,6 @@ [ ! "${O2DPG_ROOT}" ] && echo "Error: This needs O2DPG loaded" && exit 1 [ ! "${O2_ROOT}" ] && echo "Error: This needs O2 loaded" && exit 1 -# ----------- LOAD UTILITY FUNCTIONS -------------------------- -. ${O2_ROOT}/share/scripts/jobutils.sh # ----------- START ACTUAL JOB ----------------------------- @@ -23,7 +21,7 @@ NTIMEFRAMES=${NTIMEFRAMES:-1} # create workflow #ccbar filter -${O2DPG_ROOT}/MC/bin/o2dpg_sim_workflow.py -eCM 13600 -col pp -gen external -j ${NWORKERS} -ns ${NSIGEVENTS} -tf ${NTIMEFRAMES} -interactionRate 500000 -confKey "Diamond.width[2]=6.;" -e ${SIMENGINE} ${SEED} -mod "--skipModules ZDC" \ +${O2DPG_ROOT}/MC/bin/o2dpg_sim_workflow.py -eCM 13600 -col pp -gen external -j ${NWORKERS} -ns ${NSIGEVENTS} -tf ${NTIMEFRAMES} -interactionRate 500000 -confKey "Diamond.width[2]=6.;" -e ${SIMENGINE} ${SEED} \ -ini $O2DPG_ROOT/MC/config/PWGHF/ini/GeneratorHFTrigger_Bforced.ini \ # run workflow diff --git a/MC/run/PWGHF/run_pp_HFtriggers_bbbar_gaptrigger.sh b/MC/run/PWGHF/run_pp_HFtriggers_bbbar_gaptrigger.sh index b85a5376e..d5c2973d4 100755 --- a/MC/run/PWGHF/run_pp_HFtriggers_bbbar_gaptrigger.sh +++ b/MC/run/PWGHF/run_pp_HFtriggers_bbbar_gaptrigger.sh @@ -8,8 +8,6 @@ [ ! "${O2DPG_ROOT}" ] && echo "Error: This needs O2DPG loaded" && exit 1 [ ! "${O2_ROOT}" ] && echo "Error: This needs O2 loaded" && exit 1 -# ----------- LOAD UTILITY FUNCTIONS -------------------------- -. ${O2_ROOT}/share/scripts/jobutils.sh # ----------- START ACTUAL JOB ----------------------------- @@ -22,7 +20,7 @@ NTIMEFRAMES=${NTIMEFRAMES:-1} # create workflow #ccbar filter -${O2DPG_ROOT}/MC/bin/o2dpg_sim_workflow.py -eCM 13600 -col pp -gen external -j ${NWORKERS} -ns ${NSIGEVENTS} -tf ${NTIMEFRAMES} -interactionRate 500000 -confKey "Diamond.width[2]=6.;" -e ${SIMENGINE} ${SEED} -mod "--skipModules ZDC" \ +${O2DPG_ROOT}/MC/bin/o2dpg_sim_workflow.py -eCM 13600 -col pp -gen external -j ${NWORKERS} -ns ${NSIGEVENTS} -tf ${NTIMEFRAMES} -interactionRate 500000 -confKey "Diamond.width[2]=6.;" -e ${SIMENGINE} ${SEED} \ -ini $O2DPG_ROOT/MC/config/PWGHF/ini/GeneratorHFTrigger_bbbar.ini \ # run workflow diff --git a/MC/run/PWGHF/run_pp_HFtriggers_ccbar_gaptrigger.sh b/MC/run/PWGHF/run_pp_HFtriggers_ccbar_gaptrigger.sh index 77446c9a1..c84fa121d 100755 --- a/MC/run/PWGHF/run_pp_HFtriggers_ccbar_gaptrigger.sh +++ b/MC/run/PWGHF/run_pp_HFtriggers_ccbar_gaptrigger.sh @@ -8,8 +8,6 @@ [ ! "${O2DPG_ROOT}" ] && echo "Error: This needs O2DPG loaded" && exit 1 [ ! "${O2_ROOT}" ] && echo "Error: This needs O2 loaded" && exit 1 -# ----------- LOAD UTILITY FUNCTIONS -------------------------- -. ${O2_ROOT}/share/scripts/jobutils.sh # ----------- START ACTUAL JOB ----------------------------- @@ -22,7 +20,7 @@ NTIMEFRAMES=${NTIMEFRAMES:-1} # create workflow #ccbar filter -${O2DPG_ROOT}/MC/bin/o2dpg_sim_workflow.py -eCM 13600 -col pp -gen external -j ${NWORKERS} -ns ${NSIGEVENTS} -tf ${NTIMEFRAMES} -interactionRate 500000 -confKey "Diamond.width[2]=6." -e ${SIMENGINE} ${SEED} -mod "--skipModules ZDC" \ +${O2DPG_ROOT}/MC/bin/o2dpg_sim_workflow.py -eCM 13600 -col pp -gen external -j ${NWORKERS} -ns ${NSIGEVENTS} -tf ${NTIMEFRAMES} -interactionRate 500000 -confKey "Diamond.width[2]=6." -e ${SIMENGINE} ${SEED} \ -ini $O2DPG_ROOT/MC/config/PWGHF/ini/GeneratorHFTrigger_ccbar.ini \ # run workflow diff --git a/MC/run/PWGHF/run_pp_HFtriggers_ccbar_userhook_replaceBkg.sh b/MC/run/PWGHF/run_pp_HFtriggers_ccbar_userhook_replaceBkg.sh index d03bd8845..9a2e71c96 100755 --- a/MC/run/PWGHF/run_pp_HFtriggers_ccbar_userhook_replaceBkg.sh +++ b/MC/run/PWGHF/run_pp_HFtriggers_ccbar_userhook_replaceBkg.sh @@ -8,8 +8,6 @@ [ ! "${O2DPG_ROOT}" ] && echo "Error: This needs O2DPG loaded" && exit 1 [ ! "${O2_ROOT}" ] && echo "Error: This needs O2 loaded" && exit 1 -# ----------- LOAD UTILITY FUNCTIONS -------------------------- -. ${O2_ROOT}/share/scripts/jobutils.sh # ----------- START ACTUAL JOB ----------------------------- @@ -24,7 +22,7 @@ NBKGEVENTS=$(($NSIGEVENTS * $NBKGEVENTSPERSIGNALEVENT)) # create workflow #ccbar filter -${O2DPG_ROOT}/MC/bin/o2dpg_sim_workflow.py -e ${SIMENGINE} ${SEED} -eCM 13600 -col pp -colBkg pp -gen pythia8 -genBkg pythia8 -procBkg "" -j ${NWORKERS} -ns ${NSIGEVENTS} -nb ${NBKGEVENTS} -tf ${NTIMEFRAMES} -interactionRate 500000 -confKey "Diamond.width[2]=6." -mod "--skipModules ZDC" \ +${O2DPG_ROOT}/MC/bin/o2dpg_sim_workflow.py -e ${SIMENGINE} ${SEED} -eCM 13600 -col pp -colBkg pp -gen pythia8 -genBkg pythia8 -procBkg "" -j ${NWORKERS} -ns ${NSIGEVENTS} -nb ${NBKGEVENTS} -tf ${NTIMEFRAMES} -interactionRate 500000 -confKey "Diamond.width[2]=6." \ --embedding --embeddPattern r0:e${NBKGEVENTSPERSIGNALEVENT} -ini $O2DPG_ROOT/MC/config/PWGHF/ini/GeneratorHFTrigger_ccbar.ini -iniBkg $O2DPG_ROOT/MC/config/PWGHF/ini/GeneratorHFTrigger_bkg.ini \ # run workflow diff --git a/MC/run/PWGHF/run_pp_HFtriggers_omegactoxipi_gaptrigger.sh b/MC/run/PWGHF/run_pp_HFtriggers_omegactoxipi_gaptrigger.sh index 95db5efc7..44c50816f 100644 --- a/MC/run/PWGHF/run_pp_HFtriggers_omegactoxipi_gaptrigger.sh +++ b/MC/run/PWGHF/run_pp_HFtriggers_omegactoxipi_gaptrigger.sh @@ -8,8 +8,6 @@ [ ! "${O2DPG_ROOT}" ] && echo "Error: This needs O2DPG loaded" && exit 1 [ ! "${O2_ROOT}" ] && echo "Error: This needs O2 loaded" && exit 1 -# ----------- LOAD UTILITY FUNCTIONS -------------------------- -. ${O2_ROOT}/share/scripts/jobutils.sh # ----------- START ACTUAL JOB ----------------------------- @@ -23,7 +21,7 @@ NTIMEFRAMES=${NTIMEFRAMES:-1} # create workflow #ccbar filter -${O2DPG_ROOT}/MC/bin/o2dpg_sim_workflow.py -eCM 13600 -col pp -gen external -j ${NWORKERS} -ns ${NSIGEVENTS} -tf ${NTIMEFRAMES} -interactionRate 500000 -confKey "Diamond.width[2]=6." -e ${SIMENGINE} ${SEED} -mod "--skipModules ZDC" \ +${O2DPG_ROOT}/MC/bin/o2dpg_sim_workflow.py -eCM 13600 -col pp -gen external -j ${NWORKERS} -ns ${NSIGEVENTS} -tf ${NTIMEFRAMES} -interactionRate 500000 -confKey "Diamond.width[2]=6." -e ${SIMENGINE} ${SEED} \ -ini $O2DPG_ROOT/MC/config/PWGHF/ini/GeneratorHFTrigger_OmegaCToXiPi.ini \ # run workflow diff --git a/MC/run/PWGHF/run_pp_HFtriggers_xi_omega_c_gaptrigger.sh b/MC/run/PWGHF/run_pp_HFtriggers_xi_omega_c_gaptrigger.sh index 9ecb4d3d8..71cee05dd 100755 --- a/MC/run/PWGHF/run_pp_HFtriggers_xi_omega_c_gaptrigger.sh +++ b/MC/run/PWGHF/run_pp_HFtriggers_xi_omega_c_gaptrigger.sh @@ -8,8 +8,6 @@ [ ! "${O2DPG_ROOT}" ] && echo "Error: This needs O2DPG loaded" && exit 1 [ ! "${O2_ROOT}" ] && echo "Error: This needs O2 loaded" && exit 1 -# ----------- LOAD UTILITY FUNCTIONS -------------------------- -. ${O2_ROOT}/share/scripts/jobutils.sh # ----------- START ACTUAL JOB ----------------------------- @@ -23,7 +21,7 @@ NTIMEFRAMES=${NTIMEFRAMES:-1} # create workflow #ccbar filter -${O2DPG_ROOT}/MC/bin/o2dpg_sim_workflow.py -eCM 13600 -col pp -gen external -j ${NWORKERS} -ns ${NSIGEVENTS} -tf ${NTIMEFRAMES} -interactionRate 500000 -confKey "Diamond.width[2]=6." -e ${SIMENGINE} ${SEED} -mod "--skipModules ZDC" \ +${O2DPG_ROOT}/MC/bin/o2dpg_sim_workflow.py -eCM 13600 -col pp -gen external -j ${NWORKERS} -ns ${NSIGEVENTS} -tf ${NTIMEFRAMES} -interactionRate 500000 -confKey "Diamond.width[2]=6." -e ${SIMENGINE} ${SEED} \ -ini $O2DPG_ROOT/MC/config/PWGHF/ini/GeneratorHFTrigger_Xi_Omega_C.ini \ # run workflow diff --git a/MC/run/PWGHF/run_pp_HFtriggers_xictoxipi_gaptrigger.sh b/MC/run/PWGHF/run_pp_HFtriggers_xictoxipi_gaptrigger.sh index e3558c441..b51b22859 100644 --- a/MC/run/PWGHF/run_pp_HFtriggers_xictoxipi_gaptrigger.sh +++ b/MC/run/PWGHF/run_pp_HFtriggers_xictoxipi_gaptrigger.sh @@ -8,8 +8,6 @@ [ ! "${O2DPG_ROOT}" ] && echo "Error: This needs O2DPG loaded" && exit 1 [ ! "${O2_ROOT}" ] && echo "Error: This needs O2 loaded" && exit 1 -# ----------- LOAD UTILITY FUNCTIONS -------------------------- -. ${O2_ROOT}/share/scripts/jobutils.sh # ----------- START ACTUAL JOB ----------------------------- @@ -23,7 +21,7 @@ NTIMEFRAMES=${NTIMEFRAMES:-1} # create workflow #ccbar filter -${O2DPG_ROOT}/MC/bin/o2dpg_sim_workflow.py -eCM 13600 -col pp -gen external -j ${NWORKERS} -ns ${NSIGEVENTS} -tf ${NTIMEFRAMES} -interactionRate 500000 -confKey "Diamond.width[2]=6." -e ${SIMENGINE} ${SEED} -mod "--skipModules ZDC" \ +${O2DPG_ROOT}/MC/bin/o2dpg_sim_workflow.py -eCM 13600 -col pp -gen external -j ${NWORKERS} -ns ${NSIGEVENTS} -tf ${NTIMEFRAMES} -interactionRate 500000 -confKey "Diamond.width[2]=6." -e ${SIMENGINE} ${SEED} \ -ini $O2DPG_ROOT/MC/config/PWGHF/ini/GeneratorHFTrigger_XiCToXiPi.ini \ # run workflow diff --git a/MC/run/PWGHF/run_pp_PWGHF_testbeam_ccbar_trigger.sh b/MC/run/PWGHF/run_pp_PWGHF_testbeam_ccbar_trigger.sh index 160b8f2c6..c6f01aad3 100644 --- a/MC/run/PWGHF/run_pp_PWGHF_testbeam_ccbar_trigger.sh +++ b/MC/run/PWGHF/run_pp_PWGHF_testbeam_ccbar_trigger.sh @@ -8,8 +8,6 @@ [ ! "${O2DPG_ROOT}" ] && echo "Error: This needs O2DPG loaded" && exit 1 [ ! "${O2_ROOT}" ] && echo "Error: This needs O2 loaded" && exit 1 -# ----------- LOAD UTILITY FUNCTIONS -------------------------- -. ${O2_ROOT}/share/scripts/jobutils.sh # ----------- START ACTUAL JOB ----------------------------- diff --git a/MC/run/PWGHF/run_pp_testbeam_LcTrigger.sh b/MC/run/PWGHF/run_pp_testbeam_LcTrigger.sh index 19a818173..77a506c72 100644 --- a/MC/run/PWGHF/run_pp_testbeam_LcTrigger.sh +++ b/MC/run/PWGHF/run_pp_testbeam_LcTrigger.sh @@ -8,8 +8,6 @@ [ ! "${O2DPG_ROOT}" ] && echo "Error: This needs O2DPG loaded" && exit 1 [ ! "${O2_ROOT}" ] && echo "Error: This needs O2 loaded" && exit 1 -# ----------- LOAD UTILITY FUNCTIONS -------------------------- -#. ${O2_ROOT}/share/scripts/jobutils.sh # ----------- START ACTUAL JOB ----------------------------- diff --git a/MC/run/PWGHF/run_pp_testbeam_ccbarfilter.sh b/MC/run/PWGHF/run_pp_testbeam_ccbarfilter.sh index be6e0272a..1267296bb 100644 --- a/MC/run/PWGHF/run_pp_testbeam_ccbarfilter.sh +++ b/MC/run/PWGHF/run_pp_testbeam_ccbarfilter.sh @@ -8,8 +8,6 @@ [ ! "${O2DPG_ROOT}" ] && echo "Error: This needs O2DPG loaded" && exit 1 [ ! "${O2_ROOT}" ] && echo "Error: This needs O2 loaded" && exit 1 -# ----------- LOAD UTILITY FUNCTIONS -------------------------- -#. ${O2_ROOT}/share/scripts/jobutils.sh # ----------- START ACTUAL JOB ----------------------------- @@ -23,7 +21,7 @@ NTIMEFRAMES=${NTIMEFRAMES:-1} # create workflow #ccbar filter -${O2DPG_ROOT}/MC/bin/o2dpg_sim_workflow.py -eCM 900 -col pp -gen pythia8 -proc "inel" -j ${NWORKERS} -ns ${NSIGEVENTS} -tf ${NTIMEFRAMES} -interactionRate 10000 -confKey "Diamond.width[2]=6." -e TGeant4 -mod "--skipModules ZDC" \ +${O2DPG_ROOT}/MC/bin/o2dpg_sim_workflow.py -eCM 900 -col pp -gen pythia8 -proc "inel" -j ${NWORKERS} -ns ${NSIGEVENTS} -tf ${NTIMEFRAMES} -interactionRate 10000 -confKey "Diamond.width[2]=6." -e TGeant4 \ -ini $O2DPG_ROOT/MC/config/PWGHF/ini/GeneratorHF_ccbar.ini \ # run workflow diff --git a/MC/run/PWGLF/runLFInjector.sh b/MC/run/PWGLF/runLFInjector.sh index db7ace628..16a62602e 100755 --- a/MC/run/PWGLF/runLFInjector.sh +++ b/MC/run/PWGLF/runLFInjector.sh @@ -6,7 +6,6 @@ # The following variables can be set from the outside: # - NWORKERS: number of workers to use (default 8) -# - MODULES: modules to be run (default "--skipModules ZDC") # - SIMENGINE: simulation engine (default TGeant4) # - NSIGEVENTS: number of signal events (default 1) # - NBKGEVENTS: number of background events (default 1) @@ -36,13 +35,10 @@ echo "CFGINIFILE = $1" export IGNORE_VALIDITYCHECK_OF_CCDB_LOCALCACHE=1 #export ALICEO2_CCDB_LOCALCACHE=.ccdb -# ----------- LOAD UTILITY FUNCTIONS -------------------------- -. ${O2_ROOT}/share/scripts/jobutils.sh # ----------- START ACTUAL JOB ------------------------------- NWORKERS=${NWORKERS:-8} -MODULES=${MODULES:---skipModules ZDC} SIMENGINE=${SIMENGINE:-TGeant4} NSIGEVENTS=${NSIGEVENTS:-1} NBKGEVENTS=${NBKGEVENTS:-1} @@ -65,9 +61,9 @@ echo "ENERGY = $ENERGY" echo "CFGINIFILE = $CFGINIFILE" # create workflow -${O2DPG_ROOT}/MC/bin/o2dpg_sim_workflow.py -eCM ${ENERGY} -col ${SYSTEM} -gen external -j ${NWORKERS} -ns ${NSIGEVENTS} -tf ${NTIMEFRAMES} -interactionRate ${INTRATE} -confKey "Diamond.width[2]=6." -e ${SIMENGINE} ${SEED} -mod "${MODULES}" \ +${O2DPG_ROOT}/MC/bin/o2dpg_sim_workflow.py -eCM ${ENERGY} -col ${SYSTEM} -gen external -j ${NWORKERS} -ns ${NSIGEVENTS} -tf ${NTIMEFRAMES} -interactionRate ${INTRATE} -confKey "Diamond.width[2]=6." -e ${SIMENGINE} ${SEED} \ -ini ${CFGINIFILE} # run workflow O2_SIM_WORKFLOW_RUNNER=${O2_SIM_WORKFLOW_RUNNER:-"${O2DPG_ROOT}/MC/bin/o2_dpg_workflow_runner.py"} -$O2_SIM_WORKFLOW_RUNNER -f workflow.json -tt aod --cpu-limit $NWORKERS \ No newline at end of file +$O2_SIM_WORKFLOW_RUNNER -f workflow.json -tt aod --cpu-limit $NWORKERS diff --git a/MC/run/PWGLF/run_Coalescence_pp.sh b/MC/run/PWGLF/run_Coalescence_pp.sh index e9eee33db..c01ac6ac6 100755 --- a/MC/run/PWGLF/run_Coalescence_pp.sh +++ b/MC/run/PWGLF/run_Coalescence_pp.sh @@ -8,8 +8,6 @@ [ ! "${O2DPG_ROOT}" ] && echo "Error: This needs O2DPG loaded" && exit 1 [ ! "${O2_ROOT}" ] && echo "Error: This needs O2 loaded" && exit 1 -# ----------- LOAD UTILITY FUNCTIONS -------------------------- -. ${O2_ROOT}/share/scripts/jobutils.sh # ----------- START ACTUAL JOB ----------------------------- @@ -24,7 +22,7 @@ ENERGY=${ENERGY:-13600} [[ ${SPLITID} != "" ]] && SEED="-seed ${SPLITID}" || SEED="" # create workflow -${O2DPG_ROOT}/MC/bin/o2dpg_sim_workflow.py -eCM ${ENERGY} -col ${SYSTEM} -gen external -j ${NWORKERS} -ns ${NSIGEVENTS} -tf ${NTIMEFRAMES} -interactionRate ${INTRATE} -confKey "Diamond.width[0]=0.005;Diamond.width[1]=0.005;Diamond.width[2]=6." -e ${SIMENGINE} ${SEED} -mod "--skipModules ZDC" \ +${O2DPG_ROOT}/MC/bin/o2dpg_sim_workflow.py -eCM ${ENERGY} -col ${SYSTEM} -gen external -j ${NWORKERS} -ns ${NSIGEVENTS} -tf ${NTIMEFRAMES} -interactionRate ${INTRATE} -confKey "Diamond.width[0]=0.005;Diamond.width[1]=0.005;Diamond.width[2]=6." -e ${SIMENGINE} ${SEED} \ -ini $O2DPG_ROOT/MC/config/PWGLF/ini/GeneratorLF_Coalescence.ini # run workflow diff --git a/MC/run/PWGLF/run_DeTrHeInjected.sh b/MC/run/PWGLF/run_DeTrHeInjected.sh index 439b505bc..409c84808 100755 --- a/MC/run/PWGLF/run_DeTrHeInjected.sh +++ b/MC/run/PWGLF/run_DeTrHeInjected.sh @@ -12,8 +12,6 @@ export IGNORE_VALIDITYCHECK_OF_CCDB_LOCALCACHE=1 #export ALICEO2_CCDB_LOCALCACHE=.ccdb -# ----------- LOAD UTILITY FUNCTIONS -------------------------- -. ${O2_ROOT}/share/scripts/jobutils.sh # ----------- START ACTUAL JOB ----------------------------- diff --git a/MC/run/PWGLF/run_DeTrHeInjected_PbPb.sh b/MC/run/PWGLF/run_DeTrHeInjected_PbPb.sh index cb93c5d78..06bacbc23 100755 --- a/MC/run/PWGLF/run_DeTrHeInjected_PbPb.sh +++ b/MC/run/PWGLF/run_DeTrHeInjected_PbPb.sh @@ -12,8 +12,6 @@ export IGNORE_VALIDITYCHECK_OF_CCDB_LOCALCACHE=1 #export ALICEO2_CCDB_LOCALCACHE=.ccdb -# ----------- LOAD UTILITY FUNCTIONS -------------------------- -. ${O2_ROOT}/share/scripts/jobutils.sh # ----------- START ACTUAL JOB ----------------------------- diff --git a/MC/run/PWGLF/run_DoubleLambdaTriggered.sh b/MC/run/PWGLF/run_DoubleLambdaTriggered.sh new file mode 100755 index 000000000..c7e2ae418 --- /dev/null +++ b/MC/run/PWGLF/run_DoubleLambdaTriggered.sh @@ -0,0 +1,41 @@ +#!/bin/bash + +# make sure O2DPG + O2 is loaded +[ ! "${O2DPG_ROOT}" ] && echo "Error: This needs O2DPG loaded" && exit 1 +[ ! "${O2_ROOT}" ] && echo "Error: This needs O2 loaded" && exit 1 + +# ----------- CONFIGURE -------------------------- +export IGNORE_VALIDITYCHECK_OF_CCDB_LOCALCACHE=1 +#export ALICEO2_CCDB_LOCALCACHE=.ccdb + + +# ----------- START ACTUAL JOB ----------------------------- + +NWORKERS=${NWORKERS:-8} +SIMENGINE=${SIMENGINE:-TGeant4} +NSIGEVENTS=${NSIGEVENTS:-100} +NTIMEFRAMES=${NTIMEFRAMES:-1} +INTRATE=${INTRATE:-50000} +SYSTEM=${SYSTEM:-pp} +ENERGY=${ENERGY:-13600} +CFGINIFILE=${CFGINIFILE:-"${O2DPG_ROOT}/MC/config/PWGLF/ini/GeneratorDoubleLambdaTriggered.ini"} +SEED="-seed 1995" +#[[ ${SPLITID} != "" ]] && SEED="-seed ${SPLITID}" || SEED="" + +echo "NWORKERS = $NWORKERS" + +# create workflow +O2_SIM_WORKFLOW=${O2_SIM_WORKFLOW:-"${O2DPG_ROOT}/MC/bin/o2dpg_sim_workflow.py"} +CFGDECAY="${O2DPG_ROOT}/MC/config/PWGLF/pythia8/decayer/force_lambda_charged_decay.cfg" +G4CFG="${O2DPG_ROOT}/MC/config/PWGLF/pythia8/decayer/g4_ext_decayer_lambda.in" +$O2_SIM_WORKFLOW -eCM ${ENERGY} -col ${SYSTEM} -gen external \ + -j ${NWORKERS} \ + -ns ${NSIGEVENTS} -tf ${NTIMEFRAMES} -interactionRate ${INTRATE} \ + -confKey "Diamond.width[0]=0.1;Diamond.width[1]=0.1;Diamond.width[2]=6.;;DecayerPythia8.config[1]=${CFGDECAY};DecayerPythia8.showChanged=1;G4.configMacroFile=${G4CFG}" \ + ${SEED} \ + -e ${SIMENGINE} \ + -ini $CFGINIFILE + +# run workflow +O2_SIM_WORKFLOW_RUNNER=${O2_SIM_WORKFLOW_RUNNER:-"${O2DPG_ROOT}/MC/bin/o2_dpg_workflow_runner.py"} +$O2_SIM_WORKFLOW_RUNNER -f workflow.json -tt aod --cpu-limit $NWORKERS diff --git a/MC/run/PWGLF/run_GeneratorLF_antid_and_highpt.sh b/MC/run/PWGLF/run_GeneratorLF_antid_and_highpt.sh index ce8c90be3..49f7ca958 100644 --- a/MC/run/PWGLF/run_GeneratorLF_antid_and_highpt.sh +++ b/MC/run/PWGLF/run_GeneratorLF_antid_and_highpt.sh @@ -5,8 +5,6 @@ [ ! "${O2DPG_ROOT}" ] && echo "Error: This needs O2DPG loaded" && exit 1 [ ! "${O2_ROOT}" ] && echo "Error: This needs O2 loaded" && exit 1 -# ----------- LOAD UTILITY FUNCTIONS -------------------------- -. ${O2_ROOT}/share/scripts/jobutils.sh # ----------- START ACTUAL JOB ----------------------------- @@ -21,7 +19,7 @@ ENERGY=${ENERGY:-13600} [[ ${SPLITID} != "" ]] && SEED="-seed ${SPLITID}" || SEED="" # create workflow -${O2DPG_ROOT}/MC/bin/o2dpg_sim_workflow.py -eCM ${ENERGY} -col ${SYSTEM} -gen external -j ${NWORKERS} -ns ${NSIGEVENTS} -tf ${NTIMEFRAMES} -interactionRate ${INTRATE} -confKey "Diamond.width[0]=0.005;Diamond.width[1]=0.005;Diamond.width[2]=6." -e ${SIMENGINE} ${SEED} -mod "--skipModules ZDC" \ +${O2DPG_ROOT}/MC/bin/o2dpg_sim_workflow.py -eCM ${ENERGY} -col ${SYSTEM} -gen external -j ${NWORKERS} -ns ${NSIGEVENTS} -tf ${NTIMEFRAMES} -interactionRate ${INTRATE} -confKey "Diamond.width[0]=0.005;Diamond.width[1]=0.005;Diamond.width[2]=6." -e ${SIMENGINE} ${SEED} \ -ini $O2DPG_ROOT/MC/config/PWGLF/ini/GeneratorLF_antid_and_highpt.ini # run workflow diff --git a/MC/run/PWGLF/run_GeneratorLF_highpt.sh b/MC/run/PWGLF/run_GeneratorLF_highpt.sh index e4d4efe2c..817cd3303 100644 --- a/MC/run/PWGLF/run_GeneratorLF_highpt.sh +++ b/MC/run/PWGLF/run_GeneratorLF_highpt.sh @@ -5,8 +5,6 @@ [ ! "${O2DPG_ROOT}" ] && echo "Error: This needs O2DPG loaded" && exit 1 [ ! "${O2_ROOT}" ] && echo "Error: This needs O2 loaded" && exit 1 -# ----------- LOAD UTILITY FUNCTIONS -------------------------- -. ${O2_ROOT}/share/scripts/jobutils.sh # ----------- START ACTUAL JOB ----------------------------- @@ -21,7 +19,7 @@ ENERGY=${ENERGY:-13600} [[ ${SPLITID} != "" ]] && SEED="-seed ${SPLITID}" || SEED="" # create workflow -${O2DPG_ROOT}/MC/bin/o2dpg_sim_workflow.py -eCM ${ENERGY} -col ${SYSTEM} -gen external -j ${NWORKERS} -ns ${NSIGEVENTS} -tf ${NTIMEFRAMES} -interactionRate ${INTRATE} -confKey "Diamond.width[0]=0.005;Diamond.width[1]=0.005;Diamond.width[2]=6." -e ${SIMENGINE} ${SEED} -mod "--skipModules ZDC" \ +${O2DPG_ROOT}/MC/bin/o2dpg_sim_workflow.py -eCM ${ENERGY} -col ${SYSTEM} -gen external -j ${NWORKERS} -ns ${NSIGEVENTS} -tf ${NTIMEFRAMES} -interactionRate ${INTRATE} -confKey "Diamond.width[0]=0.005;Diamond.width[1]=0.005;Diamond.width[2]=6." -e ${SIMENGINE} ${SEED} \ -ini $O2DPG_ROOT/MC/config/PWGLF/ini/GeneratorLF_HighPt.ini # run workflow diff --git a/MC/run/PWGLF/run_GeneratorLF_highpt_strangeness.sh b/MC/run/PWGLF/run_GeneratorLF_highpt_strangeness.sh index 217fa83fe..ebf598e24 100644 --- a/MC/run/PWGLF/run_GeneratorLF_highpt_strangeness.sh +++ b/MC/run/PWGLF/run_GeneratorLF_highpt_strangeness.sh @@ -5,8 +5,6 @@ [ ! "${O2DPG_ROOT}" ] && echo "Error: This needs O2DPG loaded" && exit 1 [ ! "${O2_ROOT}" ] && echo "Error: This needs O2 loaded" && exit 1 -# ----------- LOAD UTILITY FUNCTIONS -------------------------- -. ${O2_ROOT}/share/scripts/jobutils.sh # ----------- START ACTUAL JOB ----------------------------- @@ -21,7 +19,7 @@ ENERGY=${ENERGY:-13600} [[ ${SPLITID} != "" ]] && SEED="-seed ${SPLITID}" || SEED="" # create workflow -${O2DPG_ROOT}/MC/bin/o2dpg_sim_workflow.py -eCM ${ENERGY} -col ${SYSTEM} -gen external -j ${NWORKERS} -ns ${NSIGEVENTS} -tf ${NTIMEFRAMES} -interactionRate ${INTRATE} -confKey "Diamond.width[0]=0.005;Diamond.width[1]=0.005;Diamond.width[2]=6." -e ${SIMENGINE} ${SEED} -mod "--skipModules ZDC" \ +${O2DPG_ROOT}/MC/bin/o2dpg_sim_workflow.py -eCM ${ENERGY} -col ${SYSTEM} -gen external -j ${NWORKERS} -ns ${NSIGEVENTS} -tf ${NTIMEFRAMES} -interactionRate ${INTRATE} -confKey "Diamond.width[0]=0.005;Diamond.width[1]=0.005;Diamond.width[2]=6." -e ${SIMENGINE} ${SEED} \ -ini $O2DPG_ROOT/MC/config/PWGLF/ini/GeneratorLF_highpt_strangeness.ini # run workflow diff --git a/MC/run/PWGLF/run_HyperInjectedGap.sh b/MC/run/PWGLF/run_HyperInjectedGap.sh index a973ac443..2b408891a 100644 --- a/MC/run/PWGLF/run_HyperInjectedGap.sh +++ b/MC/run/PWGLF/run_HyperInjectedGap.sh @@ -8,8 +8,6 @@ [ ! "${O2DPG_ROOT}" ] && echo "Error: This needs O2DPG loaded" && exit 1 [ ! "${O2_ROOT}" ] && echo "Error: This needs O2 loaded" && exit 1 -# ----------- LOAD UTILITY FUNCTIONS -------------------------- -. ${O2_ROOT}/share/scripts/jobutils.sh # ----------- START ACTUAL JOB ----------------------------- @@ -25,7 +23,7 @@ ENERGY=${ENERGY:-13600} [[ ${SPLITID} != "" ]] && SEED="-seed ${SPLITID}" || SEED="" # create workflow -${O2DPG_ROOT}/MC/bin/o2dpg_sim_workflow.py -eCM ${ENERGY} -col ${SYSTEM} -gen external -j ${NWORKERS} -ns ${NSIGEVENTS} -tf ${NTIMEFRAMES} -interactionRate ${INTRATE} -confKey "Diamond.width[0]=0.1;Diamond.width[1]=0.1;Diamond.width[2]=6." -e ${SIMENGINE} ${SEED} -mod "--skipModules ZDC" \ +${O2DPG_ROOT}/MC/bin/o2dpg_sim_workflow.py -eCM ${ENERGY} -col ${SYSTEM} -gen external -j ${NWORKERS} -ns ${NSIGEVENTS} -tf ${NTIMEFRAMES} -interactionRate ${INTRATE} -confKey "Diamond.width[0]=0.1;Diamond.width[1]=0.1;Diamond.width[2]=6." -e ${SIMENGINE} ${SEED} \ -ini ${O2DPG_ROOT}/MC/config/PWGLF/ini/GeneratorLFHyper${SYSTEM}Gap.ini # run workflow diff --git a/MC/run/PWGLF/run_HyperNucleiInjectedGap.sh b/MC/run/PWGLF/run_HyperNucleiInjectedGap.sh index cbf094547..d53659f9a 100644 --- a/MC/run/PWGLF/run_HyperNucleiInjectedGap.sh +++ b/MC/run/PWGLF/run_HyperNucleiInjectedGap.sh @@ -8,8 +8,6 @@ [ ! "${O2DPG_ROOT}" ] && echo "Error: This needs O2DPG loaded" && exit 1 [ ! "${O2_ROOT}" ] && echo "Error: This needs O2 loaded" && exit 1 -# ----------- LOAD UTILITY FUNCTIONS -------------------------- -. ${O2_ROOT}/share/scripts/jobutils.sh # ----------- START ACTUAL JOB ----------------------------- @@ -25,7 +23,7 @@ ENERGY=${ENERGY:-13600} [[ ${SPLITID} != "" ]] && SEED="-seed ${SPLITID}" || SEED="" # create workflow -${O2DPG_ROOT}/MC/bin/o2dpg_sim_workflow.py -eCM ${ENERGY} -col ${SYSTEM} -gen external -j ${NWORKERS} -ns ${NSIGEVENTS} -tf ${NTIMEFRAMES} -interactionRate ${INTRATE} -confKey "Diamond.width[0]=0.1;Diamond.width[1]=0.1;Diamond.width[2]=6." -e ${SIMENGINE} ${SEED} -mod "--skipModules ZDC" \ +${O2DPG_ROOT}/MC/bin/o2dpg_sim_workflow.py -eCM ${ENERGY} -col ${SYSTEM} -gen external -j ${NWORKERS} -ns ${NSIGEVENTS} -tf ${NTIMEFRAMES} -interactionRate ${INTRATE} -confKey "Diamond.width[0]=0.1;Diamond.width[1]=0.1;Diamond.width[2]=6." -e ${SIMENGINE} ${SEED} \ -ini ${O2DPG_ROOT}/MC/config/PWGLF/ini/GeneratorLFHyperNuclei${SYSTEM}Gap.ini # run workflow diff --git a/MC/run/PWGLF/run_HyperNucleiInjectedGapWithFlow.sh b/MC/run/PWGLF/run_HyperNucleiInjectedGapWithFlow.sh new file mode 100755 index 000000000..249c103f1 --- /dev/null +++ b/MC/run/PWGLF/run_HyperNucleiInjectedGapWithFlow.sh @@ -0,0 +1,33 @@ +#!/bin/bash + +# make sure O2DPG + O2 is loaded +[ ! "${O2DPG_ROOT}" ] && echo "Error: This needs O2DPG loaded" && exit 1 +[ ! "${O2_ROOT}" ] && echo "Error: This needs O2 loaded" && exit 1 + +# ----------- CONFIGURE -------------------------- +export IGNORE_VALIDITYCHECK_OF_CCDB_LOCALCACHE=1 +#export ALICEO2_CCDB_LOCALCACHE=.ccdb + + +# ----------- START ACTUAL JOB ----------------------------- + +NWORKERS=${NWORKERS:-8} +SIMENGINE=${SIMENGINE:-TGeant4} +NSIGEVENTS=${NSIGEVENTS:-1} +NTIMEFRAMES=${NTIMEFRAMES:-1} +INTRATE=${INTRATE:-50000} +SYSTEM=${SYSTEM:-PbPb} +ENERGY=${ENERGY:-5360} +CFGINIFILE=${CFGINIFILE:-"${O2DPG_ROOT}/MC/config/PWGLF/ini/GeneratorLFHyperNucleiPbPbGapWithFlow.ini"} + +[[ ${SPLITID} != "" ]] && SEED="-seed ${SPLITID}" || SEED="-seed 0" + +echo "NWORKERS = $NWORKERS" + +# create workflow +O2_SIM_WORKFLOW=${O2_SIM_WORKFLOW:-"${O2DPG_ROOT}/MC/bin/o2dpg_sim_workflow.py"} +$O2_SIM_WORKFLOW -eCM ${ENERGY} -col ${SYSTEM} -gen external -j ${NWORKERS} -ns ${NSIGEVENTS} -tf ${NTIMEFRAMES} -interactionRate ${INTRATE} -confKey "Diamond.width[0]=0.1;Diamond.width[1]=0.1;Diamond.width[2]=6." -e ${SIMENGINE} ${SEED} -ini $CFGINIFILE + +# run workflow +O2_SIM_WORKFLOW_RUNNER=${O2_SIM_WORKFLOW_RUNNER:-"${O2DPG_ROOT}/MC/bin/o2_dpg_workflow_runner.py"} +$O2_SIM_WORKFLOW_RUNNER -f workflow.json -tt aod --cpu-limit $NWORKERS diff --git a/MC/run/PWGLF/run_HypertritonInjected.sh b/MC/run/PWGLF/run_HypertritonInjected.sh index 145f60615..27ed61b17 100644 --- a/MC/run/PWGLF/run_HypertritonInjected.sh +++ b/MC/run/PWGLF/run_HypertritonInjected.sh @@ -8,8 +8,6 @@ [ ! "${O2DPG_ROOT}" ] && echo "Error: This needs O2DPG loaded" && exit 1 [ ! "${O2_ROOT}" ] && echo "Error: This needs O2 loaded" && exit 1 -# ----------- LOAD UTILITY FUNCTIONS -------------------------- -. ${O2_ROOT}/share/scripts/jobutils.sh # ----------- START ACTUAL JOB ----------------------------- @@ -25,7 +23,7 @@ ENERGY=${ENERGY:-5520} [[ ${SPLITID} != "" ]] && SEED="-seed ${SPLITID}" || SEED="" # create workflow -${O2DPG_ROOT}/MC/bin/o2dpg_sim_workflow.py -eCM ${ENERGY} -col ${SYSTEM} -gen external -j ${NWORKERS} -ns ${NSIGEVENTS} -tf ${NTIMEFRAMES} -interactionRate ${INTRATE} -confKey "Diamond.width[0]=0.1;Diamond.width[1]=0.1;Diamond.width[2]=6." -e ${SIMENGINE} ${SEED} -mod "--skipModules ZDC" \ +${O2DPG_ROOT}/MC/bin/o2dpg_sim_workflow.py -eCM ${ENERGY} -col ${SYSTEM} -gen external -j ${NWORKERS} -ns ${NSIGEVENTS} -tf ${NTIMEFRAMES} -interactionRate ${INTRATE} -confKey "Diamond.width[0]=0.1;Diamond.width[1]=0.1;Diamond.width[2]=6." -e ${SIMENGINE} ${SEED} \ -ini ${O2DPG_ROOT}/MC/config/PWGLF/ini/GeneratorLFHypertriton${SYSTEM}.ini # run workflow diff --git a/MC/run/PWGLF/run_HypertritonInjectedGap.sh b/MC/run/PWGLF/run_HypertritonInjectedGap.sh index 6be9e7ea1..2802e2186 100644 --- a/MC/run/PWGLF/run_HypertritonInjectedGap.sh +++ b/MC/run/PWGLF/run_HypertritonInjectedGap.sh @@ -8,8 +8,6 @@ [ ! "${O2DPG_ROOT}" ] && echo "Error: This needs O2DPG loaded" && exit 1 [ ! "${O2_ROOT}" ] && echo "Error: This needs O2 loaded" && exit 1 -# ----------- LOAD UTILITY FUNCTIONS -------------------------- -. ${O2_ROOT}/share/scripts/jobutils.sh # ----------- START ACTUAL JOB ----------------------------- @@ -25,7 +23,7 @@ ENERGY=${ENERGY:-13600} [[ ${SPLITID} != "" ]] && SEED="-seed ${SPLITID}" || SEED="" # create workflow -${O2DPG_ROOT}/MC/bin/o2dpg_sim_workflow.py -eCM ${ENERGY} -col ${SYSTEM} -gen external -j ${NWORKERS} -ns ${NSIGEVENTS} -tf ${NTIMEFRAMES} -interactionRate ${INTRATE} -confKey "Diamond.width[0]=0.1;Diamond.width[1]=0.1;Diamond.width[2]=6." -e ${SIMENGINE} ${SEED} -mod "--skipModules ZDC" \ +${O2DPG_ROOT}/MC/bin/o2dpg_sim_workflow.py -eCM ${ENERGY} -col ${SYSTEM} -gen external -j ${NWORKERS} -ns ${NSIGEVENTS} -tf ${NTIMEFRAMES} -interactionRate ${INTRATE} -confKey "Diamond.width[0]=0.1;Diamond.width[1]=0.1;Diamond.width[2]=6." -e ${SIMENGINE} ${SEED} \ -ini ${O2DPG_ROOT}/MC/config/PWGLF/ini/GeneratorLFHypertriton${SYSTEM}Gap.ini # run workflow diff --git a/MC/run/PWGLF/run_NucleiFwdInjectedGap.sh b/MC/run/PWGLF/run_NucleiFwdInjectedGap.sh index e83d1aed2..faef33201 100755 --- a/MC/run/PWGLF/run_NucleiFwdInjectedGap.sh +++ b/MC/run/PWGLF/run_NucleiFwdInjectedGap.sh @@ -8,8 +8,6 @@ [ ! "${O2DPG_ROOT}" ] && echo "Error: This needs O2DPG loaded" && exit 1 [ ! "${O2_ROOT}" ] && echo "Error: This needs O2 loaded" && exit 1 -# ----------- LOAD UTILITY FUNCTIONS -------------------------- -. ${O2_ROOT}/share/scripts/jobutils.sh # ----------- START ACTUAL JOB ----------------------------- @@ -25,7 +23,7 @@ ENERGY=${ENERGY:-13600} [[ ${SPLITID} != "" ]] && SEED="-seed ${SPLITID}" || SEED="" # create workflow -${O2DPG_ROOT}/MC/bin/o2dpg_sim_workflow.py -eCM ${ENERGY} -col ${SYSTEM} -gen external -j ${NWORKERS} -ns ${NSIGEVENTS} -tf ${NTIMEFRAMES} -interactionRate ${INTRATE} -confKey "Diamond.width[0]=0.1;Diamond.width[1]=0.1;Diamond.width[2]=6." -e ${SIMENGINE} ${SEED} -mod "--skipModules ZDC" \ +${O2DPG_ROOT}/MC/bin/o2dpg_sim_workflow.py -eCM ${ENERGY} -col ${SYSTEM} -gen external -j ${NWORKERS} -ns ${NSIGEVENTS} -tf ${NTIMEFRAMES} -interactionRate ${INTRATE} -confKey "Diamond.width[0]=0.1;Diamond.width[1]=0.1;Diamond.width[2]=6." -e ${SIMENGINE} ${SEED} \ -ini ${O2DPG_ROOT}/MC/config/PWGLF/ini/GeneratorLFNucleiFwd${SYSTEM}Gap.ini # run workflow diff --git a/MC/run/PWGLF/run_OmegaInjected.sh b/MC/run/PWGLF/run_OmegaInjected.sh index 004e5dbc3..7c97201dc 100755 --- a/MC/run/PWGLF/run_OmegaInjected.sh +++ b/MC/run/PWGLF/run_OmegaInjected.sh @@ -8,8 +8,6 @@ [ ! "${O2DPG_ROOT}" ] && echo "Error: This needs O2DPG loaded" && exit 1 [ ! "${O2_ROOT}" ] && echo "Error: This needs O2 loaded" && exit 1 -# ----------- LOAD UTILITY FUNCTIONS -------------------------- -. ${O2_ROOT}/share/scripts/jobutils.sh # ----------- START ACTUAL JOB ----------------------------- @@ -27,7 +25,7 @@ SYSTEM=${SYSTEM:-pp} ENERGY=${ENERGY:-13600} [[ ${SPLITID} != "" ]] && SEED="-seed ${SPLITID}" || SEED="" -${O2DPG_ROOT}/MC/bin/o2dpg_sim_workflow.py -e ${SIMENGINE} ${SEED} -eCM 13600 -col pp -colBkg pp -gen external -genBkg pythia8 -procBkg inel -j ${NWORKERS} -ns ${NSIGEVENTS} -nb ${NBKGEVENTS} -tf ${NTIMEFRAMES} -interactionRate 500000 -confKey "Diamond.width[2]=6." -mod "--skipModules ZDC" \ +${O2DPG_ROOT}/MC/bin/o2dpg_sim_workflow.py -e ${SIMENGINE} ${SEED} -eCM 13600 -col pp -colBkg pp -gen external -genBkg pythia8 -procBkg inel -j ${NWORKERS} -ns ${NSIGEVENTS} -nb ${NBKGEVENTS} -tf ${NTIMEFRAMES} -interactionRate 500000 -confKey "Diamond.width[2]=6." \ --embedding -ini $O2DPG_ROOT/MC/config/PWGLF/ini/GeneratorLFOmegaEmb.ini diff --git a/MC/run/PWGLF/run_SigmaProtonTriggered.sh b/MC/run/PWGLF/run_SigmaProtonTriggered.sh new file mode 100644 index 000000000..6d3d01f50 --- /dev/null +++ b/MC/run/PWGLF/run_SigmaProtonTriggered.sh @@ -0,0 +1,36 @@ +#!/bin/bash + +# make sure O2DPG + O2 is loaded +[ ! "${O2DPG_ROOT}" ] && echo "Error: This needs O2DPG loaded" && exit 1 +[ ! "${O2_ROOT}" ] && echo "Error: This needs O2 loaded" && exit 1 + +# ----------- CONFIGURE -------------------------- +export IGNORE_VALIDITYCHECK_OF_CCDB_LOCALCACHE=1 +#export ALICEO2_CCDB_LOCALCACHE=.ccdb + + +# ----------- START ACTUAL JOB ----------------------------- + +NWORKERS=${NWORKERS:-8} +SIMENGINE=${SIMENGINE:-TGeant4} +NSIGEVENTS=${NSIGEVENTS:-100} +NTIMEFRAMES=${NTIMEFRAMES:-1} +INTRATE=${INTRATE:-500000} +SYSTEM=${SYSTEM:-pp} +ENERGY=${ENERGY:-13600} +CFGINIFILE=${CFGINIFILE:-"${O2DPG_ROOT}/MC/config/PWGLF/ini/GeneratorSigmaProtonTriggered.ini"} +SEED="-seed 1995" + +# create workflow +O2_SIM_WORKFLOW=${O2_SIM_WORKFLOW:-"${O2DPG_ROOT}/MC/bin/o2dpg_sim_workflow.py"} +$O2_SIM_WORKFLOW -eCM ${ENERGY} -col ${SYSTEM} -gen external \ + -j ${NWORKERS} \ + -ns ${NSIGEVENTS} -tf ${NTIMEFRAMES} -interactionRate ${INTRATE} \ + -confKey "Diamond.width[0]=0.1;Diamond.width[1]=0.1;Diamond.width[2]=6.;" \ + ${SEED} \ + -e ${SIMENGINE} \ + -ini $CFGINIFILE + +# run workflow +O2_SIM_WORKFLOW_RUNNER=${O2_SIM_WORKFLOW_RUNNER:-"${O2DPG_ROOT}/MC/bin/o2_dpg_workflow_runner.py"} +$O2_SIM_WORKFLOW_RUNNER -f workflow.json -tt aod --cpu-limit $NWORKERS diff --git a/MC/run/PWGLF/run_StrangenessInjected.sh b/MC/run/PWGLF/run_StrangenessInjected.sh index 9c07c9271..afdc3c6af 100755 --- a/MC/run/PWGLF/run_StrangenessInjected.sh +++ b/MC/run/PWGLF/run_StrangenessInjected.sh @@ -12,8 +12,6 @@ export IGNORE_VALIDITYCHECK_OF_CCDB_LOCALCACHE=1 #export ALICEO2_CCDB_LOCALCACHE=.ccdb -# ----------- LOAD UTILITY FUNCTIONS -------------------------- -. ${O2_ROOT}/share/scripts/jobutils.sh # ----------- START ACTUAL JOB ----------------------------- diff --git a/MC/run/PWGLF/run_StrangenessInjected_PbPb.sh b/MC/run/PWGLF/run_StrangenessInjected_PbPb.sh index b1e8fd544..b850cf662 100755 --- a/MC/run/PWGLF/run_StrangenessInjected_PbPb.sh +++ b/MC/run/PWGLF/run_StrangenessInjected_PbPb.sh @@ -12,8 +12,6 @@ export IGNORE_VALIDITYCHECK_OF_CCDB_LOCALCACHE=1 #export ALICEO2_CCDB_LOCALCACHE=.ccdb -# ----------- LOAD UTILITY FUNCTIONS -------------------------- -. ${O2_ROOT}/share/scripts/jobutils.sh # ----------- START ACTUAL JOB ----------------------------- diff --git a/MC/run/PWGLF/run_StrangenessTriggered.sh b/MC/run/PWGLF/run_StrangenessTriggered.sh index 412edf995..83b8e98e8 100755 --- a/MC/run/PWGLF/run_StrangenessTriggered.sh +++ b/MC/run/PWGLF/run_StrangenessTriggered.sh @@ -12,8 +12,6 @@ export IGNORE_VALIDITYCHECK_OF_CCDB_LOCALCACHE=1 #export ALICEO2_CCDB_LOCALCACHE=.ccdb -# ----------- LOAD UTILITY FUNCTIONS -------------------------- -. ${O2_ROOT}/share/scripts/jobutils.sh # ----------- START ACTUAL JOB ----------------------------- diff --git a/MC/run/PWGLF/run_StrangenessTriggered_pp900gev.sh b/MC/run/PWGLF/run_StrangenessTriggered_pp900gev.sh index dc0262c0e..09e93cde9 100755 --- a/MC/run/PWGLF/run_StrangenessTriggered_pp900gev.sh +++ b/MC/run/PWGLF/run_StrangenessTriggered_pp900gev.sh @@ -12,8 +12,6 @@ export IGNORE_VALIDITYCHECK_OF_CCDB_LOCALCACHE=1 #export ALICEO2_CCDB_LOCALCACHE=.ccdb -# ----------- LOAD UTILITY FUNCTIONS -------------------------- -. ${O2_ROOT}/share/scripts/jobutils.sh # ----------- START ACTUAL JOB ----------------------------- diff --git a/MC/run/PWGLF/run_SyntheticFlowXi_PbPb.sh b/MC/run/PWGLF/run_SyntheticFlowXi_PbPb.sh index 088d145af..aa5526b4f 100755 --- a/MC/run/PWGLF/run_SyntheticFlowXi_PbPb.sh +++ b/MC/run/PWGLF/run_SyntheticFlowXi_PbPb.sh @@ -12,8 +12,6 @@ export IGNORE_VALIDITYCHECK_OF_CCDB_LOCALCACHE=1 #export ALICEO2_CCDB_LOCALCACHE=.ccdb -# ----------- LOAD UTILITY FUNCTIONS -------------------------- -. ${O2_ROOT}/share/scripts/jobutils.sh # ----------- START ACTUAL JOB ----------------------------- diff --git a/MC/run/PWGLF/run_SyntheticFlow_OO.sh b/MC/run/PWGLF/run_SyntheticFlow_OO.sh new file mode 100644 index 000000000..4b6c2fef2 --- /dev/null +++ b/MC/run/PWGLF/run_SyntheticFlow_OO.sh @@ -0,0 +1,42 @@ +#!/bin/bash + +# +# A example workflow MC->RECO->AOD for a simple pp min bias +# production, targetting test beam conditions. + +# make sure O2DPG + O2 is loaded +[ ! "${O2DPG_ROOT}" ] && echo "Error: This needs O2DPG loaded" && exit 1 +[ ! "${O2_ROOT}" ] && echo "Error: This needs O2 loaded" && exit 1 + +# ----------- CONFIGURE -------------------------- +export IGNORE_VALIDITYCHECK_OF_CCDB_LOCALCACHE=1 +#export ALICEO2_CCDB_LOCALCACHE=.ccdb + + +# ----------- START ACTUAL JOB ----------------------------- + +NWORKERS=${NWORKERS:-8} +SIMENGINE=${SIMENGINE:-TGeant4} +NSIGEVENTS=${NSIGEVENTS:-1} +NTIMEFRAMES=${NTIMEFRAMES:-1} +INTRATE=${INTRATE:-50000} +SYSTEM=${SYSTEM:-OO} +ENERGY=${ENERGY:-5360} +CFGINIFILE=${CFGINIFILE:-"${O2DPG_ROOT}/MC/config/PWGLF/ini/GeneratorLF_SyntheFlowOO.ini"} +[[ ${SPLITID} != "" ]] && SEED="-seed ${SPLITID}" || SEED="" + +echo "NWORKERS = $NWORKERS" + +# create workflow +O2_SIM_WORKFLOW=${O2_SIM_WORKFLOW:-"${O2DPG_ROOT}/MC/bin/o2dpg_sim_workflow.py"} +$O2_SIM_WORKFLOW -eCM ${ENERGY} -col ${SYSTEM} -gen external \ + -j ${NWORKERS} \ + -ns ${NSIGEVENTS} -tf ${NTIMEFRAMES} -interactionRate ${INTRATE} \ + -confKey "Diamond.width[2]=6." \ + ${SEED} \ + -e ${SIMENGINE} \ + -ini $CFGINIFILE + +# run workflow +O2_SIM_WORKFLOW_RUNNER=${O2_SIM_WORKFLOW_RUNNER:-"${O2DPG_ROOT}/MC/bin/o2_dpg_workflow_runner.py"} +$O2_SIM_WORKFLOW_RUNNER -f workflow.json -tt aod --cpu-limit $NWORKERS diff --git a/MC/run/PWGLF/run_SyntheticFlow_PbPb.sh b/MC/run/PWGLF/run_SyntheticFlow_PbPb.sh index e102226d4..f6907eb42 100755 --- a/MC/run/PWGLF/run_SyntheticFlow_PbPb.sh +++ b/MC/run/PWGLF/run_SyntheticFlow_PbPb.sh @@ -12,8 +12,6 @@ export IGNORE_VALIDITYCHECK_OF_CCDB_LOCALCACHE=1 #export ALICEO2_CCDB_LOCALCACHE=.ccdb -# ----------- LOAD UTILITY FUNCTIONS -------------------------- -. ${O2_ROOT}/share/scripts/jobutils.sh # ----------- START ACTUAL JOB ----------------------------- diff --git a/MC/run/PWGLF/run_XSectionVariation.sh b/MC/run/PWGLF/run_XSectionVariation.sh index 027f6d0a0..96fb19571 100644 --- a/MC/run/PWGLF/run_XSectionVariation.sh +++ b/MC/run/PWGLF/run_XSectionVariation.sh @@ -8,8 +8,6 @@ [ ! "${O2DPG_ROOT}" ] && echo "Error: This needs O2DPG loaded" && exit 1 [ ! "${O2_ROOT}" ] && echo "Error: This needs O2 loaded" && exit 1 -# ----------- LOAD UTILITY FUNCTIONS -------------------------- -. ${O2_ROOT}/share/scripts/jobutils.sh # ----------- START ACTUAL JOB ----------------------------- @@ -25,7 +23,7 @@ ENERGY=${ENERGY:-13600} [[ ${SPLITID} != "" ]] && SEED="-seed ${SPLITID}" || SEED="" # create workflow -${O2DPG_ROOT}/MC/bin/o2dpg_sim_workflow.py -eCM ${ENERGY} -col ${SYSTEM} -gen external -j ${NWORKERS} -ns ${NSIGEVENTS} -tf ${NTIMEFRAMES} -interactionRate ${INTRATE} -confKey "Diamond.width[0]=0.1;Diamond.width[1]=0.1;Diamond.width[2]=6." -e ${SIMENGINE} ${SEED} -mod "--skipModules ZDC" \ +${O2DPG_ROOT}/MC/bin/o2dpg_sim_workflow.py -eCM ${ENERGY} -col ${SYSTEM} -gen external -j ${NWORKERS} -ns ${NSIGEVENTS} -tf ${NTIMEFRAMES} -interactionRate ${INTRATE} -confKey "Diamond.width[0]=0.1;Diamond.width[1]=0.1;Diamond.width[2]=6." -e ${SIMENGINE} ${SEED} \ -ini ${O2DPG_ROOT}/MC/config/PWGLF/ini/GeneratorLFHyperNuclei${SYSTEM}Gap.ini # run workflow diff --git a/MC/run/PWGUD/runDiffEvents.sh b/MC/run/PWGUD/runDiffEvents.sh index 9d4bd065d..632742730 100755 --- a/MC/run/PWGUD/runDiffEvents.sh +++ b/MC/run/PWGUD/runDiffEvents.sh @@ -26,7 +26,6 @@ DVX=0.01 DVY=0.01 DVZ=6.00 -MODULES="--skipModules ZDC" # create workflow ${O2DPG_ROOT}/MC/bin/o2dpg_sim_workflow.py \ @@ -37,7 +36,6 @@ ${O2DPG_ROOT}/MC/bin/o2dpg_sim_workflow.py \ -ns ${NSIGPTF} \ -tf ${NTIMEFRAMES} \ -e TGeant4 \ - -mod "${MODULES}" \ -interactionRate ${SIGINTRATE} \ -confKey "HepMC.fileName="${FHEPMC}";HepMC.version=3;Diamond.width[0]="${DVX}";Diamond.width[1]="${DVY}";Diamond.width[2]="${DVZ}"" diff --git a/MC/run/PWGUD/runPythiaAndDiffEvents.sh b/MC/run/PWGUD/runPythiaAndDiffEvents.sh index 57928cee7..6484cbb8c 100755 --- a/MC/run/PWGUD/runPythiaAndDiffEvents.sh +++ b/MC/run/PWGUD/runPythiaAndDiffEvents.sh @@ -27,8 +27,6 @@ DVX=0.01 DVY=0.01 DVZ=6.00 -MODULES="--skipModules ZDC" - # create workflow SIGINTRATE=`echo "${BKGINTRATE}*${NSIGPTF}/${NBKGPTF}" | bc` NBKG=`echo "${NBKGPTF}*${NTIMEFRAMES}" | bc` @@ -38,7 +36,6 @@ ${O2DPG_ROOT}/MC/bin/o2dpg_sim_workflow.py \ -eCM ${ECM} \ -j ${NWORKERS} \ -e TGeant4 \ - -mod "${MODULES}" \ -tf ${NTIMEFRAMES} \ -interactionRate ${BKGINTRATE} \ -gen hepmc \ diff --git a/MC/run/common/run_PbPb_trigger_multiplicity_stableparticles_inFIT.sh b/MC/run/common/run_PbPb_trigger_multiplicity_stableparticles_inFIT.sh index 3f20e10eb..3d4d56cb5 100644 --- a/MC/run/common/run_PbPb_trigger_multiplicity_stableparticles_inFIT.sh +++ b/MC/run/common/run_PbPb_trigger_multiplicity_stableparticles_inFIT.sh @@ -5,8 +5,6 @@ [ ! "${O2_ROOT}" ] && echo "Error: This needs O2 loaded" && exit 1 -# ----------- LOAD UTILITY FUNCTIONS -------------------------- -. ${O2_ROOT}/share/scripts/jobutils.sh RNDSEED=${RNDSEED:-0} NEVENTS=${NEVENTS:-2} diff --git a/MC/run/examples/O2DPG_pp_minbias.sh b/MC/run/examples/O2DPG_pp_minbias.sh index f9b2a99c7..9643a2be3 100755 --- a/MC/run/examples/O2DPG_pp_minbias.sh +++ b/MC/run/examples/O2DPG_pp_minbias.sh @@ -9,8 +9,6 @@ [ ! "${O2DPG_ROOT}" ] && echo "Error: This needs O2DPG loaded" && exit 1 [ ! "${O2_ROOT}" ] && echo "Error: This needs O2 loaded" && exit 1 -# ----------- LOAD UTILITY FUNCTIONS -------------------------- -. ${O2_ROOT}/share/scripts/jobutils.sh # ----------- START ACTUAL JOB ----------------------------- @@ -38,7 +36,7 @@ MEMLIMIT=${MEMLIMIT:+--mem-limit ${MEMLIMIT}} CPULIMIT=${CPULIMIT:+--cpu-limit ${CPULIMIT}} # create workflow -${O2DPG_ROOT}/MC/bin/o2dpg_sim_workflow.py -eCM 13600 -col pp -gen pythia8 -proc inel -tf ${NTFS} \ +${O2DPG_ROOT}/MC/bin/o2dpg_sim_workflow.py -eCM 13600 -seed 12345 -col pp -gen pythia8 -proc inel -tf ${NTFS} \ -ns ${NEVENTS} -e ${SIMENGINE} -run 301000 \ -j ${NWORKERS} -interactionRate ${INTRATE} \ --include-qc --include-analysis diff --git a/MC/utils/AODBcRewriter.C b/MC/utils/AODBcRewriter.C new file mode 100644 index 000000000..16c7451ef --- /dev/null +++ b/MC/utils/AODBcRewriter.C @@ -0,0 +1,1566 @@ +// AODBcRewriter.C +// +// Usage: +// root -l -b -q 'AODBcRewriter.C("AO2D.root","AO2D_rewritten.root")' +// +// ----------------------------------------------------------------------------- +// PURPOSE +// ----------------------------------------------------------------------------- +// After merging two AO2D files the BC table (O2bc_*) can contain: +// (a) Non-monotonic fGlobalBC values — violating a framework requirement. +// (b) Duplicate fGlobalBC values — one logical BC spread across many rows. +// (c) Duplicate MCCollisions — the same MC event repeated because it +// appeared in both source files before merging. +// +// This tool fixes all three problems in one pass per DF_ directory: +// +// Stage 0 — Sort & deduplicate the BC table. Build BC permutation map: +// bcPerm[oldBCrow] = newBCrow. +// +// Stage 1 — Process every table that carries fIndexBCs / fIndexBC. +// Remap the index via bcPerm, sort rows by the new index, and +// record a permutation map for each such table so that tables +// paste-joined to it can follow. +// Special sub-case: O2mccollision_* is deduplicated here — +// rows whose (fIndexBCs, generator-level event ID) key has already +// been seen are dropped, and a FULL permutation map is produced +// (mcCollPerm[oldRow] = newRow, -1 = dropped). +// +// Stage 2 — Process every table that carries fIndexMcCollisions. +// Remap via mcCollPerm, sort, record mcCollXxxPerm if needed. +// +// Paste-join tables — tables that have NO index column but are implicitly +// joined row-for-row with another table (e.g. O2mccollisionlabel +// is paste-joined with O2collision). They must be reordered +// identically to their parent. The known paste-join relationships +// are listed in kPasteJoins below and are applied after the +// relevant stage has established the parent permutation. +// +// Unrelated tables — tables with no dependency on BCs or MCCollisions are +// copied verbatim. +// +// ----------------------------------------------------------------------------- +// DATA MODEL DEPENDENCY GRAPH (relevant subset) +// ----------------------------------------------------------------------------- +// +// BCs (O2bc_*) [Stage 0] +// │ fIndexBCs +// ├─► Collisions (O2collision_*) [Stage 1] +// │ │ paste-join ► McCollisionLabels (O2mccollisionlabel_*) +// │ │ fIndexCollisions (in tracks etc. — tracked by collPerm) +// │ └─► Tracks (O2track_*, O2trackiu_*, ...) [Stage 1] +// │ paste-join ► McTrackLabels (O2mctracklabel_*) +// │ +// └─► MCCollisions (O2mccollision_*) [Stage 1, deduplicated] +// │ fIndexMcCollisions +// ├─► HepMCXSections (O2hepmcxsection_*) [Stage 2] +// ├─► HepMCPdfInfos (O2hepmcpdfinfo_*) [Stage 2] +// └─► HepMCHeavyIons (O2hepmcheavyion_*) [Stage 2] +// +// All other tables (detector hits, ZDC, FT0, FV0, FDD, …) that carry +// fIndexBCs are handled generically in Stage 1 without special-casing. +// +// ----------------------------------------------------------------------------- + +#ifndef __CLING__ +#include "RVersion.h" +#include "TBranch.h" +#include "TDirectory.h" +#include "TFile.h" +#include "TKey.h" +#include "TLeaf.h" +#include "TMap.h" +#include "TROOT.h" +#include "TString.h" +#include "TTree.h" +#include "TGrid.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#endif + +// ============================================================================ +// SECTION 1 — Types and small helpers +// ============================================================================ + +// A permutation map: permMap[oldRow] = newRow, -1 means "row was dropped". +using PermMap = std::vector; + +// Convenience: build an identity permutation of length n. +static PermMap identityPerm(Long64_t n) { + PermMap p(n); + std::iota(p.begin(), p.end(), 0); + return p; +} + +// Names of tables that begin with these prefixes are BC tables or flag tables +// and are handled specially in Stage 0. +static bool isBCTable(const char *name) { + return TString(name).BeginsWith("O2bc"); +} + +static bool isDF(const char *name) { + return TString(name).BeginsWith("DF_"); +} + +// Return the name of the BC index branch if present, else nullptr. +static const char *bcIndexBranch(TTree *t) { + if (!t) return nullptr; + if (t->GetBranch("fIndexBCs")) return "fIndexBCs"; + if (t->GetBranch("fIndexBC")) return "fIndexBC"; + return nullptr; +} + +// Return the name of the MCCollision index branch if present, else nullptr. +static const char *mcCollIndexBranch(TTree *t) { + if (!t) return nullptr; + if (t->GetBranch("fIndexMcCollisions")) return "fIndexMcCollisions"; + return nullptr; +} + +// Return the name of the Collision index branch if present, else nullptr. +static const char *collIndexBranch(TTree *t) { + if (!t) return nullptr; + if (t->GetBranch("fIndexCollisions")) return "fIndexCollisions"; + return nullptr; +} + +// ---------------------------------------------------------------------------- +// Paste-join relationships (authoritative; derived from AnalysisDataModel.h +// comments such as "Table joined to the collision table containing the MC +// index" and from the SOA EXTENDED_TABLE declarations for cov / extra tables). +// +// A paste-joined CHILD has NO row of its own — its row N corresponds to row N +// of its PARENT. If the parent is reordered or has rows dropped, the child +// must follow row-for-row to preserve the 1:1 alignment. Any index columns +// the child carries (e.g. fIndexMcCollisions in O2mccollisionlabel) are then +// remapped *value-wise* via the appropriate parent stage's permutation, but +// rows are NEVER added or dropped on the child's own initiative. +// +// Matching uses TString::BeginsWith on the child name; parent matching uses +// allPerms keys (so versioned names like O2collision_001 resolve via prefix). +// When several parent candidates are listed for the same child, the first one +// found in allPerms wins (this lets us prefer O2track_iu over O2track). +static const std::vector> kPasteJoins = { + // { paste-joined child prefix, parent prefix } + { "O2bcflag", "O2bc" }, // BCFlags joinable with BCs + { "O2mccollisionlabel", "O2collision" }, // McCollisionLabels -> Collisions + { "O2mctracklabel", "O2track_iu" }, // McTrackLabels -> Tracks (prefer _iu) + { "O2mctracklabel", "O2track" }, + { "O2mcfwdtracklabel", "O2fwdtrack" }, // McFwdTrackLabels -> FwdTracks + { "O2mcmfttracklabel", "O2mfttrack" }, // McMFTTrackLabels -> MFTTracks + { "O2mccalolabel", "O2calo" }, // McCaloLabels -> Calos + { "O2trackcov_iu", "O2track_iu" }, // TracksCovIU -> TracksIU (cov) + { "O2trackextra", "O2track_iu" }, // TracksExtra -> TracksIU + { "O2fwdtrackcov", "O2fwdtrack" }, // FwdTracksCov -> FwdTracks + // Note: O2mfttrackcov has its own fIndexMFTTracks column — it is NOT + // paste-joined and must NOT be listed here. +}; + +// True if the given tree name matches any registered paste-join child prefix. +static bool isPasteJoinChild(const std::string &tname) { + for (auto &kv : kPasteJoins) + if (TString(tname.c_str()).BeginsWith(kv.first.c_str())) return true; + return false; +} + +// ============================================================================ +// SECTION 2 — Generic ROOT branch I/O helpers +// ============================================================================ +// +// AO2D branches store plain scalar values (Int_t, ULong64_t, Float_t, …) or +// variable-length arrays (VLAs). We need to read and write them generically +// without knowing the concrete type at compile time. The trick is to allocate +// a raw byte buffer of the right size, set the branch address to it, and use +// the ScalarTag enum to know how to interpret it when we need to (e.g. for +// index remapping). + +enum class ScalarTag { + kInt, kUInt, kShort, kUShort, kLong64, kULong64, + kFloat, kDouble, kChar, kUChar, kBool, kUnknown +}; + +static ScalarTag tagOf(TLeaf *leaf) { + if (!leaf) return ScalarTag::kUnknown; + TString t = leaf->GetTypeName(); + if (t == "Int_t") return ScalarTag::kInt; + if (t == "UInt_t") return ScalarTag::kUInt; + if (t == "Short_t") return ScalarTag::kShort; + if (t == "UShort_t") return ScalarTag::kUShort; + if (t == "Long64_t") return ScalarTag::kLong64; + if (t == "ULong64_t") return ScalarTag::kULong64; + if (t == "Float_t") return ScalarTag::kFloat; + if (t == "Double_t") return ScalarTag::kDouble; + if (t == "Char_t") return ScalarTag::kChar; + if (t == "UChar_t") return ScalarTag::kUChar; + if (t == "Bool_t") return ScalarTag::kBool; + return ScalarTag::kUnknown; +} + +static size_t byteSize(ScalarTag t) { + switch (t) { + case ScalarTag::kInt: return sizeof(Int_t); + case ScalarTag::kUInt: return sizeof(UInt_t); + case ScalarTag::kShort: return sizeof(Short_t); + case ScalarTag::kUShort: return sizeof(UShort_t); + case ScalarTag::kLong64: return sizeof(Long64_t); + case ScalarTag::kULong64: return sizeof(ULong64_t); + case ScalarTag::kFloat: return sizeof(Float_t); + case ScalarTag::kDouble: return sizeof(Double_t); + case ScalarTag::kChar: return sizeof(Char_t); + case ScalarTag::kUChar: return sizeof(UChar_t); + case ScalarTag::kBool: return sizeof(Bool_t); + default: return 0; + } +} + +// Read an integer value from a raw buffer regardless of its stored type. +// Used to extract index values (fIndexBCs etc.) from their buffers. +static Long64_t readAsInt(const void *buf, ScalarTag tag) { + switch (tag) { + case ScalarTag::kInt: return *static_cast(buf); + case ScalarTag::kUInt: return *static_cast(buf); + case ScalarTag::kShort: return *static_cast(buf); + case ScalarTag::kUShort: return *static_cast(buf); + case ScalarTag::kLong64: return *static_cast(buf); + case ScalarTag::kULong64: return (Long64_t)*static_cast(buf); + default: return -1; + } +} + +// Write an integer value into a raw buffer. +static void writeAsInt(void *buf, ScalarTag tag, Long64_t val) { + switch (tag) { + case ScalarTag::kInt: *static_cast(buf) = (Int_t)val; break; + case ScalarTag::kUInt: *static_cast(buf) = (UInt_t)val; break; + case ScalarTag::kShort: *static_cast(buf) = (Short_t)val; break; + case ScalarTag::kUShort: *static_cast(buf) = (UShort_t)val; break; + case ScalarTag::kLong64: *static_cast(buf) = (Long64_t)val; break; + default: break; + } +} + +// Remap a single Int_t index value through a PermMap. Returns -1 for any +// out-of-range or already-invalid (negative) value. +static Int_t remapIdx(Int_t val, const PermMap &perm) { + if (val < 0 || (size_t)val >= perm.size()) return -1; + return perm[(size_t)val]; +} + +// A description of one branch in a tree: its name, scalar type tag, byte +// size, and whether it is a VLA (variable-length array). For VLAs we also +// keep the name of the count branch and the maximum observed element count +// (needed for buffer sizing). +struct BranchDesc { + std::string name; + ScalarTag tag = ScalarTag::kUnknown; + size_t elemSize = 0; // byte size of one element + int nElems = 1; // >1 for fixed-size arrays (e.g. fIndexSlice_Daughters[2]) + bool isVLA = false; + std::string countBranchName; // only for VLAs + Long64_t maxElems = 1; // only for VLAs +}; + +// Scan all branches of a tree and return their descriptors. Count branches +// for VLAs are represented only once (as the count side of the data branch) +// and are marked so they don't also appear as standalone entries. +static std::vector describeBranches(TTree *tree) { + std::vector result; + std::unordered_set countBranchNames; + + // First pass: identify all count branches for VLAs + for (auto *obj : *tree->GetListOfBranches()) { + TBranch *br = static_cast(obj); + TLeaf *leaf = static_cast(br->GetListOfLeaves()->At(0)); + if (!leaf) continue; + if (TLeaf *cnt = leaf->GetLeafCount()) + countBranchNames.insert(cnt->GetBranch()->GetName()); + } + + // Second pass: build descriptors + for (auto *obj : *tree->GetListOfBranches()) { + TBranch *br = static_cast(obj); + std::string bname = br->GetName(); + TLeaf *leaf = static_cast(br->GetListOfLeaves()->At(0)); + if (!leaf) { std::cerr << " [warn] branch without leaf: " << bname << "\n"; continue; } + + BranchDesc d; + d.name = bname; + d.tag = tagOf(leaf); + + if (TLeaf *cnt = leaf->GetLeafCount()) { + // This is a VLA data branch + d.isVLA = true; + d.countBranchName = cnt->GetBranch()->GetName(); + d.tag = tagOf(leaf); + d.elemSize = byteSize(d.tag); + + // Pre-scan to find the maximum array length (needed for buffer) + TBranch *cntBr = cnt->GetBranch(); + ScalarTag cntTag = tagOf(cnt); + size_t cntSz = byteSize(cntTag); + if (cntSz == 0) { std::cerr << " [warn] VLA count branch has unknown type: " << bname << "\n"; continue; } + std::vector cntBuf(cntSz, 0); + cntBr->SetAddress(cntBuf.data()); + Long64_t maxLen = 1; + for (Long64_t i = 0; i < tree->GetEntries(); ++i) { + cntBr->GetEntry(i); + Long64_t v = readAsInt(cntBuf.data(), cntTag); + if (v > maxLen) maxLen = v; + } + d.maxElems = maxLen; + + } else if (countBranchNames.count(bname)) { + // This is a count branch — skip it here; handled together with its VLA + continue; + } else { + // Plain scalar or fixed-size array branch (e.g. fIndexSlice_Daughters[2]) + d.isVLA = false; + d.elemSize = byteSize(d.tag); + d.nElems = leaf->GetLen(); // 1 for scalars, >1 for fixed arrays + if (d.elemSize == 0) { + std::cerr << " [warn] branch " << bname << " has unknown type " + << leaf->GetTypeName() << " — will be skipped\n"; + continue; + } + } + result.push_back(std::move(d)); + } + return result; +} + +// ============================================================================ +// SECTION 3 — Table rewriting engine +// ============================================================================ +// +// rewriteTable() is the single generic function that handles any table. +// It takes: +// - src : the source TTree +// - dirOut : directory to write the output TTree into +// - rowOrder : which source rows to include and in what order +// (a vector of source row indices, possibly a subset) +// - indexBranch : name of the index branch to remap, or "" if none +// - parentPerm : PermMap for remapping that index (may be empty) +// - extraRemaps : additional index columns to remap in-place via their own +// PermMaps (used for intra-table and cross-table indices +// that are not the primary sort key, e.g. mother/daughter +// indices in O2mcparticle or fIndexMcParticles in labels) +// +// It returns the permutation of source rows implied by rowOrder, expressed +// as a PermMap: perm[srcRow] = outputRow, -1 if the row was dropped. + +// Describes one extra index column to remap independently of the sort key. +struct ExtraRemap { + std::string branchName; // branch whose integer values to remap + const PermMap *perm; // remapping table: newVal = (*perm)[oldVal] +}; + +static PermMap rewriteTable(TTree *src, TDirectory *dirOut, + const std::vector &rowOrder, + const std::string &indexBranch, + const PermMap &parentPerm, + const std::vector &extraRemaps = {}) { + + Long64_t nSrc = src->GetEntries(); + + // Build the inverse permutation (srcRow → outRow) from rowOrder + PermMap srcToOut(nSrc, -1); + for (Long64_t outRow = 0; outRow < (Long64_t)rowOrder.size(); ++outRow) + srcToOut[rowOrder[outRow]] = (Int_t)outRow; + + // Describe all branches + auto descs = describeBranches(src); + + // Allocate raw buffers: for each branch one buffer (for VLAs: data buffer + // sized maxElems * elemSize, plus a separate count buffer). + // We use a std::vector per branch (automatically memory-safe). + struct BranchIO { + BranchDesc desc; + std::vector dataBuf; // scalar: elemSize bytes; VLA: maxElems*elemSize bytes + std::vector countBuf; // VLA only + ScalarTag countTag = ScalarTag::kUnknown; + TBranch *inBr = nullptr; + TBranch *inCntBr = nullptr; + }; + std::vector ios; + ios.reserve(descs.size()); + + for (auto &d : descs) { + BranchIO io; + io.desc = d; + if (!d.isVLA) { + // Allocate for all elements (nElems>1 for fixed arrays like fIndexSlice_Daughters[2]) + io.dataBuf.assign(d.nElems * d.elemSize, 0); + } else { + io.dataBuf.assign(d.maxElems * d.elemSize, 0); + TBranch *cntBr = src->GetBranch(d.countBranchName.c_str()); + TLeaf *cntLeaf = cntBr ? static_cast(cntBr->GetListOfLeaves()->At(0)) : nullptr; + io.countTag = cntLeaf ? tagOf(cntLeaf) : ScalarTag::kUnknown; + io.countBuf.assign(byteSize(io.countTag), 0); + io.inCntBr = cntBr; + } + io.inBr = src->GetBranch(d.name.c_str()); + ios.push_back(std::move(io)); + } + + // Set input branch addresses + for (auto &io : ios) { + if (io.inBr) io.inBr->SetAddress(io.dataBuf.data()); + if (io.inCntBr) io.inCntBr->SetAddress(io.countBuf.data()); + } + + // Create output tree and set output branch addresses. + // We clone the tree structure (no entries) and reset addresses. + dirOut->cd(); + TTree *out = src->CloneTree(0, "fast"); + + // Find the index branch (if any) — we will update its value on the fly + ScalarTag idxTag = ScalarTag::kUnknown; + std::vector newIdxBuf; + TBranch *outIdxBr = nullptr; + if (!indexBranch.empty()) { + TBranch *inIdxBr = src->GetBranch(indexBranch.c_str()); + TLeaf *idxLeaf = inIdxBr ? static_cast(inIdxBr->GetListOfLeaves()->At(0)) : nullptr; + idxTag = idxLeaf ? tagOf(idxLeaf) : ScalarTag::kUnknown; + if (idxTag != ScalarTag::kUnknown) { + newIdxBuf.assign(byteSize(idxTag), 0); + outIdxBr = out->GetBranch(indexBranch.c_str()); + if (outIdxBr) outIdxBr->SetAddress(newIdxBuf.data()); + } + } + + // Set all other output branch addresses to the same data buffers as input + for (auto &io : ios) { + if (io.desc.name == indexBranch) continue; // handled separately above + TBranch *outBr = out->GetBranch(io.desc.name.c_str()); + if (!outBr) { std::cerr << " [warn] no output branch for " << io.desc.name << "\n"; continue; } + outBr->SetAddress(io.dataBuf.data()); + if (io.desc.isVLA) { + TBranch *outCntBr = out->GetBranch(io.desc.countBranchName.c_str()); + if (outCntBr) outCntBr->SetAddress(io.countBuf.data()); + } + } + + // Fill the output tree row by row in the requested order + Long64_t nRemapped = 0; + for (Long64_t srcRow : rowOrder) { + src->GetEntry(srcRow); + + // Remap the index branch if required + if (outIdxBr && idxTag != ScalarTag::kUnknown && !parentPerm.empty()) { + // Read old index from the input branch's buffer (one of the ios entries) + Long64_t oldIdx = -1; + for (auto &io : ios) { + if (io.desc.name == indexBranch) { oldIdx = readAsInt(io.dataBuf.data(), idxTag); break; } + } + Long64_t newIdx = -1; + if (oldIdx >= 0 && oldIdx < (Long64_t)parentPerm.size()) + newIdx = parentPerm[oldIdx]; + writeAsInt(newIdxBuf.data(), idxTag, newIdx >= 0 ? newIdx : -1); + if (newIdx != oldIdx) ++nRemapped; + } + + // Apply extra in-place index remaps (e.g. intra-table mother/daughter + // indices in O2mcparticle, or fIndexMcParticles in label tables). + // The output branch shares the same buffer, so modifying dataBuf here + // is read by out->Fill() below. + for (auto &er : extraRemaps) { + for (auto &io : ios) { + if (io.desc.name != er.branchName) continue; + if (io.desc.isVLA) { + // VLA: remap each element according to count + Long64_t cnt = readAsInt(io.countBuf.data(), io.countTag); + auto *p = reinterpret_cast(io.dataBuf.data()); + for (Long64_t j = 0; j < cnt; ++j) + p[j] = remapIdx(p[j], *er.perm); + } else { + // Scalar or fixed-size array: remap all nElems integers + auto *p = reinterpret_cast(io.dataBuf.data()); + for (int j = 0; j < io.desc.nElems; ++j) + p[j] = remapIdx(p[j], *er.perm); + } + break; + } + } + + out->Fill(); + } + + std::cout << " wrote " << out->GetEntries() << " / " << nSrc + << " rows; " << nRemapped << " index values remapped\n"; + out->Write(); + return srcToOut; +} + +// ============================================================================ +// SECTION 4 — Stage 0: BC table sort + deduplication +// ============================================================================ +// +// Reads fGlobalBC from the BC tree, sorts rows, drops exact-duplicate BC +// values, and writes the compacted table. Returns bcPerm[oldRow] = newRow. +// +// IMPORTANT (history — do not "optimize" this back): +// A previous revision replaced this sort with an order-preserving in-place +// dedup that std::abort()ed unless the input BC table was already globalBC- +// sorted. That directly contradicts this tool's PURPOSE (a) at the top of the +// file — repairing *non-monotonic* fGlobalBC in MERGED AO2Ds — so it aborted on +// exactly the files it exists to fix ("doesn't run to completion"). We sort +// unconditionally instead. +// +// Sorting BCs does imply a reorder cascade: collisions are sorted by their +// remapped fIndexBCs in Stage 1, and the collision-grouped track tables must +// then be re-grouped to follow the new collision order in Stage 1b. That +// cascade is real and unavoidable for non-monotonic input; it is handled +// explicitly and completely by those stages. This is the correct fix — keep +// it. An "assert already sorted" shortcut here is a known dead end. + +struct BCStage0Result { + PermMap bcPerm; // bcPerm[oldRow] = newRow in sorted/deduped BC table + Long64_t nUnique = 0; +}; + +static BCStage0Result stage0_sortBCs(TTree *treeBCs, TDirectory *dirOut) { + BCStage0Result res; + Long64_t n = treeBCs->GetEntries(); + if (n == 0) return res; + + TBranch *brGBC = treeBCs->GetBranch("fGlobalBC"); + if (!brGBC) { std::cerr << "ERROR: O2bc_* tree has no fGlobalBC branch!\n"; return res; } + + ULong64_t gbc = 0; + brGBC->SetAddress(&gbc); + std::vector gbcs(n); + for (Long64_t i = 0; i < n; ++i) { treeBCs->GetEntry(i); gbcs[i] = gbc; } + + // Sort row indices by fGlobalBC (stable, so equal-globalBC rows keep their + // input order before being collapsed below). + std::vector order(n); + std::iota(order.begin(), order.end(), 0); + std::stable_sort(order.begin(), order.end(), + [&](Long64_t a, Long64_t b){ return gbcs[a] < gbcs[b]; }); + + // Build the deduplicated row list and the permutation: rows sharing a + // globalBC collapse onto one output row. + res.bcPerm.assign(n, -1); + std::vector rowOrder; // source rows to keep, in output order + ULong64_t prev = 0; + Int_t newRow = -1; + for (Long64_t srcRow : order) { + if (newRow < 0 || gbcs[srcRow] != prev) { + ++newRow; + prev = gbcs[srcRow]; + rowOrder.push_back(srcRow); + } + // All rows with the same globalBC map to the same new row (deduplication) + res.bcPerm[srcRow] = newRow; + } + res.nUnique = rowOrder.size(); + + std::cout << " BC stage: " << n << " rows -> " << res.nUnique << " unique (sorted)\n"; + + // Write the BC table (no index remapping needed for the table itself) + rewriteTable(treeBCs, dirOut, rowOrder, /*indexBranch=*/"", /*parentPerm=*/{}); + + return res; +} + +// ============================================================================ +// SECTION 5 — Stage 0b: BC flags table (follows BC row order exactly) +// ============================================================================ + +static void stage0_copyBCFlags(TTree *treeFlags, TDirectory *dirOut, + const PermMap &bcPerm) { + if (!treeFlags) return; + Long64_t nSrc = treeFlags->GetEntries(); + + // Build rowOrder: for each unique output BC row, pick the first source row + // that mapped to it + std::vector rowOrder; + std::map first; // newBCrow -> first srcRow + for (Long64_t i = 0; i < (Long64_t)bcPerm.size(); ++i) + if (bcPerm[i] >= 0) first.emplace(bcPerm[i], i); // emplace keeps first + rowOrder.reserve(first.size()); + for (auto &kv : first) rowOrder.push_back(kv.second); + + rewriteTable(treeFlags, dirOut, rowOrder, /*indexBranch=*/"", /*parentPerm=*/{}); +} + +// ============================================================================ +// SECTION 6 — Stage 1: Tables indexed by BCs (generic + MCCollisions special) +// ============================================================================ +// +// Returns a map: treeName -> PermMap, containing the row permutation for +// every table processed at this stage. Callers use this for paste-joined +// tables and for Stage 2. + +// Key used to detect duplicate MCCollisions. +// +// Two MCCollision rows are considered identical when BOTH of the following hold: +// 1. They map to the same BC row after remapping (same globalBC). +// 2. They carry the same fEventWeight value. +// +// fEventWeight is a float written by the generator for every event and is +// unique enough (in combination with the BC) to distinguish distinct events +// from the same generator that happen to land in the same BC. +// +// IMPORTANT: if fEventWeight is absent from the tree we do NOT deduplicate at +// all, because we have no reliable way to distinguish distinct events that share +// the same BC. Deduplicating on BC alone would incorrectly merge different MC +// events that were placed in the same bunch crossing. +struct MCCollKey { + Long64_t newBCrow; + Float_t weight; + bool operator==(const MCCollKey &o) const { + return newBCrow == o.newBCrow && weight == o.weight; + } +}; +struct MCCollKeyHash { + size_t operator()(const MCCollKey &k) const { + size_t h1 = std::hash{}(k.newBCrow); + // Bit-cast float to uint32 for hashing — avoids UB and NaN weirdness + uint32_t wbits; + std::memcpy(&wbits, &k.weight, sizeof(wbits)); + return h1 ^ (size_t(wbits) << 32) ^ size_t(wbits); + } +}; + +static std::unordered_map +stage1_BCindexedTables(TDirectory *dirIn, TDirectory *dirOut, + const PermMap &bcPerm) { + std::unordered_map tablePerms; + + TIter it(dirIn->GetListOfKeys()); + while (TKey *key = static_cast(it())) { + if (TString(key->GetClassName()) != "TTree") continue; + std::unique_ptr obj(key->ReadObj()); + TTree *src = dynamic_cast(obj.get()); + if (!src) continue; + + std::string tname = src->GetName(); + if (isBCTable(tname.c_str())) continue; // handled in stage 0 + + const char *idxBr = bcIndexBranch(src); + if (!idxBr) continue; // not BC-indexed — handled elsewhere + + std::cout << " Stage1 [BC-indexed]: " << tname << "\n"; + + Long64_t nSrc = src->GetEntries(); + + // Read all index values to build the sort order + TBranch *inIdxBr = src->GetBranch(idxBr); + TLeaf *idxLeaf = static_cast(inIdxBr->GetListOfLeaves()->At(0)); + ScalarTag idxTag = tagOf(idxLeaf); + size_t idxSz = byteSize(idxTag); + std::vector idxBuf(idxSz, 0); + inIdxBr->SetAddress(idxBuf.data()); + + // For MCCollision deduplication: also read fEventWeight if available. + // If absent, deduplication is disabled -- see MCCollKey comment for why. + bool isMCColl = TString(tname.c_str()).BeginsWith("O2mccollision"); + TBranch *wBr = isMCColl ? src->GetBranch("fEventWeight") : nullptr; + Float_t wVal = 0.f; + if (wBr) wBr->SetAddress(&wVal); + bool canDedup = isMCColl && (wBr != nullptr); + if (isMCColl && !canDedup) + std::cout << " MCCollision: fEventWeight absent -- deduplication disabled\n"; + + // Build (newBCrow, srcRow) pairs + struct SortEntry { Long64_t newBC; Long64_t srcRow; }; + std::vector entries; + entries.reserve(nSrc); + + std::unordered_set seenMCColl; + std::vector keep(nSrc, true); + + for (Long64_t i = 0; i < nSrc; ++i) { + inIdxBr->GetEntry(i); + if (wBr) wBr->GetEntry(i); + Long64_t oldBC = readAsInt(idxBuf.data(), idxTag); + Long64_t newBC = (oldBC >= 0 && oldBC < (Long64_t)bcPerm.size()) + ? bcPerm[oldBC] : -1; + + if (canDedup) { + // Deduplication: drop rows with a (newBC, weight) pair seen before. + // First occurrence in source row order is kept. + MCCollKey k{newBC, wVal}; + if (!seenMCColl.insert(k).second) { + keep[i] = false; + } + } + entries.push_back({newBC, i}); + } + + // Stable-sort by newBC (invalid = -1 sink to end) + std::stable_sort(entries.begin(), entries.end(), + [](const SortEntry &a, const SortEntry &b){ + if (a.newBC < 0 && b.newBC >= 0) return false; + if (a.newBC >= 0 && b.newBC < 0) return true; + return a.newBC < b.newBC; + }); + + // Build rowOrder, respecting the keep[] mask for MCCollisions + std::vector rowOrder; + rowOrder.reserve(nSrc); + for (auto &e : entries) { + if (keep[e.srcRow]) rowOrder.push_back(e.srcRow); + } + + if (isMCColl) { + Long64_t dropped = nSrc - (Long64_t)rowOrder.size(); + std::cout << " MCCollision dedup: dropped " << dropped + << " duplicate rows (" << rowOrder.size() << " kept)\n"; + } + + PermMap perm = rewriteTable(src, dirOut, rowOrder, idxBr, bcPerm); + tablePerms[tname] = std::move(perm); + } + return tablePerms; +} + +// ============================================================================ +// SECTION 7 — Stage 2: Tables indexed by MCCollisions +// ============================================================================ + +static std::unordered_map +stage2_MCCollIndexedTables(TDirectory *dirIn, TDirectory *dirOut, + const PermMap &mcCollPerm) { + std::unordered_map tablePerms; + + TIter it(dirIn->GetListOfKeys()); + while (TKey *key = static_cast(it())) { + if (TString(key->GetClassName()) != "TTree") continue; + std::unique_ptr obj(key->ReadObj()); + TTree *src = dynamic_cast(obj.get()); + if (!src) continue; + + std::string tname = src->GetName(); + if (isBCTable(tname.c_str())) continue; + if (bcIndexBranch(src)) continue; // already handled in stage 1 + + const char *idxBr = mcCollIndexBranch(src); + if (!idxBr) continue; + + // A paste-join child (e.g. O2mccollisionlabel) MUST follow its parent's + // row order and never drop rows on its own. Defer it to + // processPasteJoinTables, which will remap any of its own index columns + // (fIndexMcCollisions, ...) value-wise without touching the row count. + if (isPasteJoinChild(tname)) { + std::cout << " Stage2: deferring paste-join child " << tname + << " to paste-join handler\n"; + continue; + } + + std::cout << " Stage2 [MCColl-indexed]: " << tname << "\n"; + + Long64_t nSrc = src->GetEntries(); + TBranch *inIdxBr = src->GetBranch(idxBr); + TLeaf *idxLeaf = static_cast(inIdxBr->GetListOfLeaves()->At(0)); + ScalarTag idxTag = tagOf(idxLeaf); + size_t idxSz = byteSize(idxTag); + std::vector idxBuf(idxSz, 0); + inIdxBr->SetAddress(idxBuf.data()); + + struct SortEntry { Long64_t newMCColl; Long64_t srcRow; }; + std::vector entries; + entries.reserve(nSrc); + + for (Long64_t i = 0; i < nSrc; ++i) { + inIdxBr->GetEntry(i); + Long64_t oldIdx = readAsInt(idxBuf.data(), idxTag); + Long64_t newIdx = (oldIdx >= 0 && oldIdx < (Long64_t)mcCollPerm.size()) + ? mcCollPerm[oldIdx] : -1; + entries.push_back({newIdx, i}); + } + + // Drop rows whose MCCollision parent was dropped (newIdx == -1 due to dedup) + // and sort the rest + std::stable_sort(entries.begin(), entries.end(), + [](const SortEntry &a, const SortEntry &b){ + if (a.newMCColl < 0 && b.newMCColl >= 0) return false; + if (a.newMCColl >= 0 && b.newMCColl < 0) return true; + return a.newMCColl < b.newMCColl; + }); + + std::vector rowOrder; + rowOrder.reserve(nSrc); + Long64_t dropped = 0; + for (auto &e : entries) { + if (e.newMCColl >= 0) rowOrder.push_back(e.srcRow); + else ++dropped; + } + if (dropped) + std::cout << " dropped " << dropped + << " rows whose MCCollision parent was deduplicated\n"; + + // For O2mcparticle: compute the self-permutation (old row -> new row) from + // the row order BEFORE calling rewriteTable, then pass it as extra remaps + // so that intra-table mother/daughter indices are updated in the same pass. + // The stable sort above preserves within-collision particle order, which + // keeps fIndexSlice_Daughters contiguous — so remapping [first,last] via + // selfPerm is correct. + std::vector extraRemaps; + PermMap selfPerm; + if (TString(tname.c_str()).BeginsWith("O2mcparticle")) { + selfPerm.assign(nSrc, -1); + for (Long64_t outRow = 0; outRow < (Long64_t)rowOrder.size(); ++outRow) + selfPerm[rowOrder[outRow]] = (Int_t)outRow; + extraRemaps.push_back({"fIndexArray_Mothers", &selfPerm}); + extraRemaps.push_back({"fIndexSlice_Daughters", &selfPerm}); + std::cout << " O2mcparticle: will remap intra-table mother/daughter indices\n"; + } + + PermMap perm = rewriteTable(src, dirOut, rowOrder, idxBr, mcCollPerm, extraRemaps); + tablePerms[tname] = std::move(perm); + } + return tablePerms; +} + +// ============================================================================ +// SECTION 8 — Paste-join table handling +// ============================================================================ +// +// A paste-joined CHILD has no row of its own — its row N corresponds to row N +// of its PARENT table. When the parent is reordered, the child must follow +// row-for-row to preserve the 1:1 alignment. Paste-join children may still +// carry their own index columns; those values are remapped in-place via the +// appropriate parent-stage permutation. +// +// The list of paste-join pairs is in kPasteJoins (Section 1). +// +// Index columns we know how to remap in a child: +// fIndexMcCollisions -> via mcCollPerm +// fIndexCollisions -> via collPerm +// fIndexMcParticles -> via mcParticlePerm +// fIndexArrayMcParticles -> via mcParticlePerm (VLA) +// +// When the named parent is not in allPerms (e.g. tracks aren't reordered in +// this build), the child is processed with identity row order so the +// value-wise remaps still apply but the row order is unchanged. + +// Build the row order from a PermMap (srcRow -> outRow), inverted. +static std::vector rowOrderFromPerm(const PermMap &perm) { + // perm[srcRow] = outRow (or -1 if dropped) + // We need: outRow -> srcRow, i.e. a sorted list of (outRow, srcRow) pairs + std::vector> pairs; + pairs.reserve(perm.size()); + for (Long64_t srcRow = 0; srcRow < (Long64_t)perm.size(); ++srcRow) + if (perm[srcRow] >= 0) pairs.push_back({perm[srcRow], srcRow}); + std::sort(pairs.begin(), pairs.end()); + std::vector order; + order.reserve(pairs.size()); + for (auto &p : pairs) order.push_back(p.second); + return order; +} + +// Locate a permutation in allPerms whose key begins with a given prefix. +// Returns nullptr if none found. +static const PermMap *findPermByPrefix( + const std::unordered_map &allPerms, + const char *prefix, + std::string *foundName = nullptr) { + for (auto &[name, perm] : allPerms) { + if (TString(name.c_str()).BeginsWith(prefix)) { + if (foundName) *foundName = name; + return &perm; + } + } + return nullptr; +} + +// ============================================================================ +// SECTION 9b — Stage 1b: Collision-grouped track tables +// ============================================================================ +// +// The primary track tables (O2track_iu, O2mfttrack_*, O2fwdtrack) are GROUPED +// by collision. O2's slicing cache (ArrowTableSlicingCache::validateOrder) +// requires every fIndexCollisions group — including the "-1" ambiguous group — +// to be a single contiguous run; otherwise it aborts with +// "Table ... index fIndexCollisions has a group with index -1 that is split". +// +// When several MC sub-timeframes are merged into one DF_ folder (data-embedding +// anchoring, which stores MC timeframes under the same DF_ as the parent data +// file), each sub-frame contributes its own [collision-grouped][-1 ambiguous] +// block. Concatenating them splits the -1 group into N runs, so the table is +// no longer sliceable. Stage 1 only reorders BC-indexed tables, and tracks are +// otherwise written in input row order, so the split survives into the output. +// +// This stage re-establishes the grouping: it reorders each collision-grouped +// track table by its remapped fIndexCollisions (stable, with -1 sinking to the +// end so the ambiguous group is one contiguous run — matching the Stage 1 +// convention) and publishes the resulting row permutation. Downstream: +// * paste-join children (O2trackextra, O2trackcov_iu, O2mctracklabel, ...) +// follow the published parent permutation; +// * every fIndexTracks* / fIndexMFTTracks / fIndexFwdTracks reference is +// remapped through it in processPasteJoinTables. +static bool isCollGroupedTrackTable(const std::string &tname) { + static const char *kPrefixes[] = {"O2track_iu", "O2track", + "O2mfttrack", "O2fwdtrack"}; + for (auto *p : kPrefixes) + if (TString(tname.c_str()).BeginsWith(p)) return true; + return false; +} + +static void stage1b_reorderTrackTables( + TDirectory *dirIn, TDirectory *dirOut, + std::unordered_map &allPerms, + std::unordered_set &written) { + + const PermMap *collPermP = findPermByPrefix(allPerms, "O2collision_"); + if (!collPermP) return; // no collisions present — nothing to regroup against + + TIter it(dirIn->GetListOfKeys()); + while (TKey *key = static_cast(it())) { + if (TString(key->GetClassName()) != "TTree") continue; + std::unique_ptr obj(key->ReadObj()); + TTree *src = dynamic_cast(obj.get()); + if (!src) continue; + + std::string tname = src->GetName(); + if (written.count(tname)) continue; // BC-indexed tracks etc. already done + if (!isCollGroupedTrackTable(tname)) continue; + if (isPasteJoinChild(tname)) continue; // children follow their parent below + if (!src->GetBranch("fIndexCollisions")) continue; + + std::cout << " Stage1b [coll-grouped]: " << tname << "\n"; + + Long64_t nSrc = src->GetEntries(); + TBranch *inIdxBr = src->GetBranch("fIndexCollisions"); + TLeaf *idxLeaf = static_cast(inIdxBr->GetListOfLeaves()->At(0)); + ScalarTag idxTag = tagOf(idxLeaf); + std::vector idxBuf(byteSize(idxTag), 0); + inIdxBr->SetAddress(idxBuf.data()); + + struct SortEntry { Long64_t newColl; Long64_t srcRow; }; + std::vector entries; + entries.reserve(nSrc); + for (Long64_t i = 0; i < nSrc; ++i) { + inIdxBr->GetEntry(i); + Long64_t oldColl = readAsInt(idxBuf.data(), idxTag); + Long64_t newColl = (oldColl >= 0 && oldColl < (Long64_t)collPermP->size()) + ? (*collPermP)[oldColl] : -1; + entries.push_back({newColl, i}); + } + // Stable-sort by remapped collision; the ambiguous group (-1) sinks to the + // end as a single contiguous run. Stable keeps the within-collision order. + std::stable_sort(entries.begin(), entries.end(), + [](const SortEntry &a, const SortEntry &b){ + if (a.newColl < 0 && b.newColl >= 0) return false; + if (a.newColl >= 0 && b.newColl < 0) return true; + return a.newColl < b.newColl; + }); + std::vector rowOrder; + rowOrder.reserve(nSrc); + for (auto &e : entries) rowOrder.push_back(e.srcRow); + + // Reorder rows and remap fIndexCollisions values through collPerm. + PermMap perm = rewriteTable(src, dirOut, rowOrder, "fIndexCollisions", *collPermP); + allPerms[tname] = std::move(perm); + written.insert(tname); + } +} + +static void processPasteJoinTables( + TDirectory *dirIn, TDirectory *dirOut, + const std::unordered_map &allPerms, + const std::unordered_set &alreadyWritten, + const PermMap *bcPermP = nullptr) { + + // Pre-locate the parent permutations that paste-join children may want to + // apply to their own index columns. Any of these may legitimately be null + // (e.g. mcParticlePerm absent if there is no O2mcparticle in this DF). + const PermMap *mcParticlePerm = findPermByPrefix(allPerms, "O2mcparticle"); + const PermMap *mcCollPermP = findPermByPrefix(allPerms, "O2mccollision_"); + const PermMap *collPermP = findPermByPrefix(allPerms, "O2collision_"); + // Track tables reordered in Stage 1b: every reference into them must be + // remapped through their permutation (null if the table is absent / wasn't + // reordered, in which case no remap is needed). + const PermMap *trkPerm = findPermByPrefix(allPerms, "O2track_iu"); + const PermMap *mftPerm = findPermByPrefix(allPerms, "O2mfttrack"); + const PermMap *fwdPerm = findPermByPrefix(allPerms, "O2fwdtrack"); + // bcPermP is passed in from processDF (the BC table is the only stage + // whose permutation isn't already published in allPerms). + + TIter it(dirIn->GetListOfKeys()); + while (TKey *key = static_cast(it())) { + if (TString(key->GetClassName()) != "TTree") continue; + std::unique_ptr obj(key->ReadObj()); + TTree *src = dynamic_cast(obj.get()); + if (!src) continue; + + std::string tname = src->GetName(); + if (alreadyWritten.count(tname)) continue; + if (isBCTable(tname.c_str())) continue; + // Stage-1 BC-indexed and Stage-2 MCColl-indexed non-paste-join tables are + // already in alreadyWritten. A paste-join child carrying its own MCColl + // index (e.g. O2mccollisionlabel) was deferred from stage2 and lands here. + if (bcIndexBranch(src)) continue; + if (mcCollIndexBranch(src) && !isPasteJoinChild(tname)) continue; + + // Build value-wise extra remaps for any index column this table carries + // that points into a table whose row order may have changed. + std::vector extraRemaps; + if (mcParticlePerm) { + if (src->GetBranch("fIndexMcParticles")) + extraRemaps.push_back({"fIndexMcParticles", mcParticlePerm}); + if (src->GetBranch("fIndexArrayMcParticles")) + extraRemaps.push_back({"fIndexArrayMcParticles", mcParticlePerm}); + } + if (mcCollPermP && src->GetBranch("fIndexMcCollisions")) + extraRemaps.push_back({"fIndexMcCollisions", mcCollPermP}); + if (collPermP && src->GetBranch("fIndexCollisions")) + extraRemaps.push_back({"fIndexCollisions", collPermP}); + if (bcPermP) { + // BC-pointing indices that weren't already remapped in Stage 1. + // Stage-1 BC-indexed tables (with fIndexBCs / fIndexBC) are in + // alreadyWritten by now, so this only fires for tables that escaped + // Stage 1 — chiefly the O2ambiguous* family, which carries the SOA + // SLICE_INDEX_COLUMN(BC, bc) stored on disk as fIndexSliceBCs[2]/I. + // After BC dedup the slice endpoints would otherwise point past the + // compacted BC table; remapping through bcPerm fixes this. + if (src->GetBranch("fIndexSliceBCs")) + extraRemaps.push_back({"fIndexSliceBCs", bcPermP}); + if (src->GetBranch("fIndexBCs")) + extraRemaps.push_back({"fIndexBCs", bcPermP}); + if (src->GetBranch("fIndexBC")) + extraRemaps.push_back({"fIndexBC", bcPermP}); + } + + // Track-pointing indices: the track tables may have been reordered in + // Stage 1b, so every reference into them must be remapped through the + // corresponding permutation. (No-op when the perm is null / absent.) + auto addTrkRemap = [&](const char *br, const PermMap *pm) { + if (pm && src->GetBranch(br)) extraRemaps.push_back({br, pm}); + }; + addTrkRemap("fIndexTracks", trkPerm); + addTrkRemap("fIndexTracks_0", trkPerm); + addTrkRemap("fIndexTracks_1", trkPerm); + addTrkRemap("fIndexTracks_2", trkPerm); + addTrkRemap("fIndexTracks_Pos", trkPerm); + addTrkRemap("fIndexTracks_Neg", trkPerm); + addTrkRemap("fIndexTracks_ITS", trkPerm); + addTrkRemap("fIndexMFTTracks", mftPerm); + addTrkRemap("fIndexFwdTracks", fwdPerm); + addTrkRemap("fIndexFwdTracks_MatchMCHTrack", fwdPerm); + + // Find a paste-join parent for this table (kPasteJoins lookup). + const PermMap *parentPerm = nullptr; + std::string parentName; + for (auto &[pastePrefix, parentPrefix] : kPasteJoins) { + if (!TString(tname.c_str()).BeginsWith(pastePrefix.c_str())) continue; + parentPerm = findPermByPrefix(allPerms, parentPrefix.c_str(), &parentName); + if (parentPerm) break; + } + + if (parentPerm) { + std::cout << " Paste-join: " << tname << " follows " << parentName << "\n"; + auto rowOrder = rowOrderFromPerm(*parentPerm); + if ((Long64_t)rowOrder.size() != src->GetEntries()) { + std::cerr << " [warn] paste-join size mismatch: " << tname + << " has " << src->GetEntries() << " rows but parent perm covers " + << rowOrder.size() << " — cloning as-is\n"; + dirOut->cd(); + TTree *c = src->CloneTree(-1, "fast"); + c->SetDirectory(dirOut); + c->Write(); + } else { + rewriteTable(src, dirOut, rowOrder, "", {}, extraRemaps); + } + } else if (!extraRemaps.empty() || isPasteJoinChild(tname)) { + // Parent wasn't reordered (or not present in this DF) — keep row order + // identical but still apply value-wise index remaps and follow the + // paste-join 1:1 invariant by going through the identity row order. + std::cout << " Identity-order remap: " << tname << "\n"; + Long64_t n = src->GetEntries(); + std::vector identity(n); + std::iota(identity.begin(), identity.end(), 0LL); + rewriteTable(src, dirOut, identity, "", {}, extraRemaps); + } else { + // No paste-join and no index remapping needed — fast clone + std::cout << " Copy (no dependency): " << tname << "\n"; + dirOut->cd(); + TTree *c = src->CloneTree(-1, "fast"); + c->SetDirectory(dirOut); + c->Write(); + } + } +} + +// ============================================================================ +// SECTION 9 — Non-tree object copying (TMap metadata etc.) +// ============================================================================ + +static void copyNonTreeObjects(TDirectory *dirIn, TDirectory *dirOut) { + TIter it(dirIn->GetListOfKeys()); + while (TKey *key = static_cast(it())) { + if (TString(key->GetClassName()) == "TTree") continue; + std::unique_ptr obj(key->ReadObj()); + dirOut->cd(); + if (obj->IsA()->InheritsFrom(TMap::Class())) + dirOut->WriteTObject(obj.get(), key->GetName(), "Overwrite"); + else + obj->Write(key->GetName(), TObject::kOverwrite); + } +} + +// ============================================================================ +// SECTION 10 — Per-DF directory driver +// ============================================================================ + +static void processDF(TDirectory *dirIn, TDirectory *dirOut) { + std::cout << "========================================\n"; + std::cout << "Processing " << dirIn->GetName() << "\n"; + + // ---- Find BC tree and optional flags tree ---- + TTree *treeBCs = nullptr; + TTree *treeFlags = nullptr; + { + TIter it(dirIn->GetListOfKeys()); + while (TKey *key = static_cast(it())) { + if (TString(key->GetClassName()) != "TTree") continue; + TTree *t = static_cast(dirIn->Get(key->GetName())); + if (!t) continue; + TString tname = t->GetName(); + if (tname.BeginsWith("O2bc_")) { treeBCs = t; } + if (tname.BeginsWith("O2bcflag")){ treeFlags = t; } + } + } + + if (!treeBCs) { + // No BC table — deep-copy everything unchanged + std::cout << " No BC table found — copying directory verbatim\n"; + TIter it(dirIn->GetListOfKeys()); + while (TKey *key = static_cast(it())) { + std::unique_ptr obj(key->ReadObj()); + dirOut->cd(); + if (obj->InheritsFrom(TTree::Class())) { + TTree *c = static_cast(obj.get())->CloneTree(-1, "fast"); + c->SetDirectory(dirOut); c->Write(); + } else if (obj->IsA()->InheritsFrom(TMap::Class())) { + dirOut->WriteTObject(obj.get(), key->GetName(), "Overwrite"); + } else { + obj->Write(key->GetName(), TObject::kOverwrite); + } + } + return; + } + + // ---- Stage 0: sort & deduplicate BCs ---- + std::cout << "-- Stage 0: BCs --\n"; + dirOut->cd(); + BCStage0Result s0 = stage0_sortBCs(treeBCs, dirOut); + if (treeFlags) stage0_copyBCFlags(treeFlags, dirOut, s0.bcPerm); + + // Track which tree names have been written so we don't double-write + std::unordered_set written; + written.insert(treeBCs->GetName()); + if (treeFlags) written.insert(treeFlags->GetName()); + + // ---- Stage 1: BC-indexed tables (including MCCollisions dedup) ---- + std::cout << "-- Stage 1: BC-indexed tables --\n"; + auto stage1Perms = stage1_BCindexedTables(dirIn, dirOut, s0.bcPerm); + for (auto &kv : stage1Perms) written.insert(kv.first); + + // ---- Stage 2: MCCollision-indexed tables ---- + // Find the MCCollision permutation from stage 1 + std::cout << "-- Stage 2: MCCollision-indexed tables --\n"; + PermMap mcCollPerm; + for (auto &[tname, perm] : stage1Perms) { + if (TString(tname.c_str()).BeginsWith("O2mccollision")) { + mcCollPerm = perm; + break; + } + } + if (!mcCollPerm.empty()) { + auto stage2Perms = stage2_MCCollIndexedTables(dirIn, dirOut, mcCollPerm); + for (auto &kv : stage2Perms) { + written.insert(kv.first); + stage1Perms[kv.first] = kv.second; // merge into allPerms for paste-join lookup + } + } else { + std::cout << " (no MCCollision table found — skipping stage 2)\n"; + } + + // ---- Stage 1b: regroup collision-grouped track tables ---- + // Must run after Stage 1 (needs the collision permutation) and before the + // paste-join stage (so children follow the new track order and fIndexTracks* + // references are remapped). Publishes track permutations into stage1Perms. + std::cout << "-- Stage 1b: collision-grouped track tables --\n"; + stage1b_reorderTrackTables(dirIn, dirOut, stage1Perms, written); + + // ---- Paste-join tables + unrelated tables ---- + std::cout << "-- Paste-join and unrelated tables --\n"; + processPasteJoinTables(dirIn, dirOut, stage1Perms, written, &s0.bcPerm); + + // ---- Non-tree objects (TMap metadata) ---- + copyNonTreeObjects(dirIn, dirOut); + + std::cout << "Done: " << dirIn->GetName() << "\n"; +} + +// ============================================================================ +// SECTION 11 — Post-write validation +// ============================================================================ +// +// AODBcRewriterValidate() opens a rewritten AO2D and checks key invariants: +// 1. BC table is strictly monotonic in fGlobalBC. +// 2. MC particle intra-table daughter/mother indices are in range and point +// to particles belonging to the same MC collision. +// 3. Every paste-joined child table has the same row count as its parent +// (e.g. O2mccollisionlabel matches O2collision). +// 4. Every fIndex* value across the DF is in range w.r.t. its referent +// table (value -1 is always permitted as the "no link" sentinel). +// +// Returns true if all checks pass. Prints [FAIL] lines for each violation. + +// Map from fIndex* branch name to the table-name prefix it refers to. The +// match on the referent side uses TString::BeginsWith so versioned suffixes +// (O2collision_001, O2bc_001, ...) are handled. Branches not in this list +// are skipped by the range check (this includes O2mcparticle's intra-table +// fIndexArray_Mothers / fIndexSlice_Daughters, which are checked separately +// with stricter semantics in the MC-particle block). +static const std::vector> kIndexBranchToTable = { + { "fIndexBCs", "O2bc_" }, + { "fIndexBC", "O2bc_" }, + { "fIndexSliceBCs", "O2bc_" }, + { "fIndexCollisions", "O2collision_" }, + { "fIndexCollision", "O2collision_" }, + { "fIndexMcCollisions", "O2mccollision_" }, + { "fIndexMcParticles", "O2mcparticle" }, + { "fIndexArrayMcParticles", "O2mcparticle" }, + { "fIndexTracks", "O2track_iu" }, + { "fIndexTracks_0", "O2track_iu" }, + { "fIndexTracks_1", "O2track_iu" }, + { "fIndexTracks_2", "O2track_iu" }, + { "fIndexTracks_Pos", "O2track_iu" }, + { "fIndexTracks_Neg", "O2track_iu" }, + { "fIndexTracks_ITS", "O2track_iu" }, + { "fIndexFwdTracks", "O2fwdtrack" }, + { "fIndexFwdTracks_MatchMCHTrack", "O2fwdtrack" }, + { "fIndexMFTTracks", "O2mfttrack" }, + { "fIndexV0s", "O2v0_" }, + { "fIndexCascades", "O2cascade_" }, + { "fIndexDecay3Bodys", "O2decay3body" }, +}; + +// Find a tree in d whose name begins with the given prefix. Returns the +// number of entries, or -1 if not found. +static Long64_t treeEntriesByPrefix(TDirectory *d, const char *prefix) { + TIter it(d->GetListOfKeys()); + TKey *k; + while ((k = (TKey*)it())) { + if (!TString(k->GetName()).BeginsWith(prefix)) continue; + TObject *obj = d->Get(k->GetName()); + if (!obj || !obj->InheritsFrom(TTree::Class())) continue; + return ((TTree*)obj)->GetEntries(); + } + return -1; +} + +// Generic in-range check for every fIndex* branch listed above. Reads the +// branch's leaf (scalar, fixed-array, or VLA), iterates all entries, and +// counts how many values are outside [-1, nReferent). +static Long64_t checkIndexRange(TTree *t, const char *branchName, + Long64_t nReferent) { + TBranch *br = t->GetBranch(branchName); + if (!br) return 0; + TLeaf *leaf = (TLeaf*)br->GetListOfLeaves()->At(0); + if (!leaf) return 0; + if (TString(leaf->GetTypeName()) != "Int_t") return 0; // only Int_t indices + + TLeaf *cntLeaf = leaf->GetLeafCount(); // VLA? + int fixedN = leaf->GetLen(); // 1 for scalar, >1 for fixed array + + // Allocate worst-case buffer. For a VLA we need a prescan to size it. + Long64_t maxLen = fixedN; + if (cntLeaf) { + // simple prescan + Int_t cnt = 0; + TBranch *cntBr = cntLeaf->GetBranch(); + cntBr->SetAddress(&cnt); + for (Long64_t i = 0; i < t->GetEntries(); ++i) { + cntBr->GetEntry(i); + if (cnt > maxLen) maxLen = cnt; + } + } + std::vector buf(std::max(1, maxLen), 0); + Int_t cnt = fixedN; + TBranch *cntBr = cntLeaf ? cntLeaf->GetBranch() : nullptr; + br->SetAddress(buf.data()); + if (cntBr) cntBr->SetAddress(&cnt); + + Long64_t bad = 0; + for (Long64_t i = 0; i < t->GetEntries(); ++i) { + br->GetEntry(i); + if (cntBr) cntBr->GetEntry(i); + int n = cntBr ? (int)cnt : fixedN; + for (int j = 0; j < n; ++j) { + Int_t v = buf[j]; + if (v < -1) { ++bad; continue; } + if (v >= (Int_t)nReferent) { ++bad; continue; } + } + } + br->ResetAddress(); + if (cntBr) cntBr->ResetAddress(); + return bad; +} + +// Verify the collision-grouping invariant that O2's ArrowTableSlicingCache +// (validateOrder) enforces on the consumer side: in a table grouped by +// fIndexCollisions, every distinct index value — including the -1 "ambiguous" +// group — must occupy a single contiguous run of rows. A split group is +// exactly the failure that crashed event-selection downstream +// ("Table ... index fIndexCollisions has a group with index -1 that is split +// by N"). This is the post-write counterpart to Stage 1b's regrouping. +// Returns the number of groups found split into >1 run (0 = OK). +static Long64_t checkCollisionGroupContiguity(TTree *t) { + TBranch *br = t->GetBranch("fIndexCollisions"); + if (!br) return 0; + TLeaf *leaf = (TLeaf*)br->GetListOfLeaves()->At(0); + if (!leaf || TString(leaf->GetTypeName()) != "Int_t") return 0; + if (leaf->GetLen() != 1 || leaf->GetLeafCount()) return 0; // scalar only + + Int_t idx = 0; + br->SetAddress(&idx); + std::unordered_set closed; // groups whose run has already ended + Int_t cur = 0; bool have = false; + Long64_t split = 0; + for (Long64_t i = 0; i < t->GetEntries(); ++i) { + br->GetEntry(i); + if (have && idx == cur) continue; // current run continues + if (have) closed.insert(cur); // previous run just ended + if (closed.count(idx)) ++split; // re-opening a group seen earlier + cur = idx; have = true; + } + br->ResetAddress(); + return split; +} + +static bool validateDF(TDirectory *d) { + bool ok = true; + + // ---- discover key trees ---- + TIter it(d->GetListOfKeys()); + TKey *k; + TTree *bcTree = nullptr; + TTree *mcpTree = nullptr; + while ((k = (TKey*)it())) { + TObject *obj = d->Get(k->GetName()); + if (!obj || !obj->InheritsFrom(TTree::Class())) continue; + TTree *t = (TTree*)obj; + TString tn = t->GetName(); + if (tn.BeginsWith("O2bc_")) bcTree = t; + if (tn.BeginsWith("O2mcparticle")) mcpTree = t; + } + + if (bcTree) { + ULong64_t gbc = 0, prev = 0; + bcTree->SetBranchAddress("fGlobalBC", &gbc); + Long64_t nBC = bcTree->GetEntries(); + Long64_t nBad = 0; + for (Long64_t i = 0; i < nBC; ++i) { + bcTree->GetEntry(i); + if (i > 0 && gbc <= prev) ++nBad; + prev = gbc; + } + if (nBad > 0) { + std::cerr << " [FAIL] " << bcTree->GetName() + << ": " << nBad << " non-monotonic BC entries\n"; + ok = false; + } + } + + // ---- MC particle intra-table indices ---- + if (mcpTree) { + Long64_t nMcp = mcpTree->GetEntries(); + Int_t daughters[2] = {-1,-1}, mcCollIdx = -1, motherSize = 0, mothers[200] = {}; + mcpTree->SetBranchStatus("*", 0); + mcpTree->SetBranchStatus("fIndexSlice_Daughters", 1); + mcpTree->SetBranchStatus("fIndexMcCollisions", 1); + mcpTree->SetBranchStatus("fIndexArray_Mothers_size",1); + mcpTree->SetBranchStatus("fIndexArray_Mothers", 1); + mcpTree->SetBranchAddress("fIndexSlice_Daughters", daughters); + mcpTree->SetBranchAddress("fIndexMcCollisions", &mcCollIdx); + mcpTree->SetBranchAddress("fIndexArray_Mothers_size",&motherSize); + mcpTree->SetBranchAddress("fIndexArray_Mothers", mothers); + + // Pre-load MC collision index for cross-collision check + std::vector allMcColl(nMcp); + for (Long64_t i = 0; i < nMcp; ++i) { mcpTree->GetEntry(i); allMcColl[i] = mcCollIdx; } + + Long64_t badSlice = 0, badMother = 0, badXcoll = 0; + for (Long64_t i = 0; i < nMcp; ++i) { + mcpTree->GetEntry(i); + if (daughters[0] >= 0) { + if (daughters[0] >= nMcp || daughters[1] >= nMcp || daughters[0] > daughters[1]) + ++badSlice; + else for (Int_t d2 = daughters[0]; d2 <= daughters[1]; ++d2) + if (allMcColl[d2] != mcCollIdx) ++badXcoll; + } + for (int m = 0; m < std::min(motherSize, 200); ++m) { + if (mothers[m] >= 0) { + if (mothers[m] >= nMcp) ++badMother; + else if (allMcColl[mothers[m]] != mcCollIdx) ++badXcoll; + } + } + } + if (badSlice || badMother || badXcoll) { + std::cerr << " [FAIL] " << mcpTree->GetName() + << ": bad_slice=" << badSlice + << " bad_mother=" << badMother + << " cross_coll=" << badXcoll << "\n"; + ok = false; + } + mcpTree->SetBranchStatus("*", 1); + } + + // ---- Paste-join row-count parity ---- + // For every (child, parent) pair in kPasteJoins, if both are present in the + // DF their row counts must be identical. This catches the class of bugs + // where a child was sorted/dropped on its own index (e.g. a previous + // version dropped O2mccollisionlabel rows on MC-collision dedup while + // leaving O2collision_001 intact, producing an off-by-N mismatch). + for (auto &[childPrefix, parentPrefix] : kPasteJoins) { + Long64_t nChild = treeEntriesByPrefix(d, childPrefix.c_str()); + Long64_t nParent = treeEntriesByPrefix(d, parentPrefix.c_str()); + if (nChild < 0 || nParent < 0) continue; // pair not both present + if (nChild != nParent) { + std::cerr << " [FAIL] paste-join size mismatch: " << childPrefix << "*" + << " has " << nChild << " rows but parent " << parentPrefix << "*" + << " has " << nParent << "\n"; + ok = false; + } + } + + // ---- Generic fIndex* range check ---- + // For each table in the DF, scan all fIndex* branches and confirm every + // value lies in [-1, nReferent). This catches stale pointers across + // tables (cross-table index drift) which a per-DF-tree-only check misses. + TIter it2(d->GetListOfKeys()); + TKey *k2; + while ((k2 = (TKey*)it2())) { + TObject *obj = d->Get(k2->GetName()); + if (!obj || !obj->InheritsFrom(TTree::Class())) continue; + TTree *t = (TTree*)obj; + for (auto &[branchName, referentPrefix] : kIndexBranchToTable) { + if (!t->GetBranch(branchName.c_str())) continue; + Long64_t nRef = treeEntriesByPrefix(d, referentPrefix.c_str()); + if (nRef < 0) continue; // referent not in this DF; skip silently + Long64_t bad = checkIndexRange(t, branchName.c_str(), nRef); + if (bad > 0) { + std::cerr << " [FAIL] " << t->GetName() << "." << branchName + << ": " << bad << " value(s) out of range [-1, " << nRef << ")\n"; + ok = false; + } + } + } + + // ---- Collision-group contiguity (slicing invariant) ---- + // O2's slicing cache requires each fIndexCollisions group (incl. -1) to be a + // single contiguous run. This is the exact invariant whose violation crashed + // event-selection; it is what Stage 1b re-establishes. Check every + // collision-grouped track table (paste-join children follow their parent's + // row order, so checking the parent suffices). + TIter it3(d->GetListOfKeys()); + TKey *k3; + while ((k3 = (TKey*)it3())) { + TObject *obj = d->Get(k3->GetName()); + if (!obj || !obj->InheritsFrom(TTree::Class())) continue; + TTree *t = (TTree*)obj; + if (!isCollGroupedTrackTable(t->GetName())) continue; + if (isPasteJoinChild(t->GetName())) continue; + Long64_t split = checkCollisionGroupContiguity(t); + if (split > 0) { + std::cerr << " [FAIL] " << t->GetName() + << ": fIndexCollisions has " << split + << " group(s) split into non-contiguous runs (slicing will abort)\n"; + ok = false; + } + } + + return ok; +} + +bool AODBcRewriterValidate(const char *fname = "AO2D_rewritten.root") { + std::cout << "Validating " << fname << "\n"; + std::unique_ptr f(TFile::Open(fname, "READ")); + if (!f || f->IsZombie()) { std::cerr << "Cannot open " << fname << "\n"; return false; } + + bool allOk = true; + int nDF = 0; + TIter top(f->GetListOfKeys()); + TKey *k; + while ((k = (TKey*)top())) { + if (!TString(k->GetName()).BeginsWith("DF_")) continue; + TDirectory *d = (TDirectory*)f->Get(k->GetName()); + bool dfOk = validateDF(d); + if (!dfOk) std::cerr << " -> FAILED in " << k->GetName() << "\n"; + allOk = allOk && dfOk; + ++nDF; + } + f->Close(); + if (allOk) + std::cout << "VALIDATION PASSED (" << nDF << " DFs checked)\n"; + else + std::cout << "VALIDATION FAILED — see [FAIL] lines above\n"; + return allOk; +} + +// ============================================================================ +// SECTION 12 — Top-level entry point +// ============================================================================ + +void AODBcRewriter(const char *inFileName = "AO2D.root", + const char *outFileName = "AO2D_rewritten.root") { + + std::cout << "AODBcRewriter: input=" << inFileName + << " output=" << outFileName << "\n"; + if (TString(inFileName).BeginsWith("alien:")) { + TGrid::Connect("alien"); + } + std::unique_ptr fin(TFile::Open(inFileName, "READ")); + if (!fin || fin->IsZombie()) { std::cerr << "ERROR: cannot open " << inFileName << "\n"; return; } + + int algo = fin->GetCompressionAlgorithm(); + int lvl = fin->GetCompressionLevel(); + +#if ROOT_VERSION_CODE >= ROOT_VERSION(6, 30, 0) + std::unique_ptr fout(TFile::Open(outFileName, "RECREATE", "", lvl)); +#else + std::unique_ptr fout(TFile::Open(outFileName, "RECREATE")); +#endif + if (!fout || fout->IsZombie()) { std::cerr << "ERROR: cannot create " << outFileName << "\n"; return; } + fout->SetCompressionAlgorithm(algo); + fout->SetCompressionLevel(lvl); + + TIter top(fin->GetListOfKeys()); + while (TKey *key = static_cast(top())) { + TString name = key->GetName(); + std::unique_ptr obj(key->ReadObj()); + + if (obj->InheritsFrom(TDirectory::Class()) && isDF(name)) { + TDirectory *din = static_cast(obj.get()); + TDirectory *dout = fout->mkdir(name); + processDF(din, dout); + } else { + // Top-level non-DF objects (metadata TMaps etc.) + fout->cd(); + if (obj->IsA()->InheritsFrom(TMap::Class())) + fout->WriteTObject(obj.get(), name, "Overwrite"); + else + obj->Write(name, TObject::kOverwrite); + } + } + + fout->Write("", TObject::kOverwrite); + fout->Close(); + fin->Close(); + std::cout << "All done. Output: " << outFileName << "\n"; +} diff --git a/MC/utils/AOD_check_globalBC_monotonic.C b/MC/utils/AOD_check_globalBC_monotonic.C new file mode 100644 index 000000000..b92472d5e --- /dev/null +++ b/MC/utils/AOD_check_globalBC_monotonic.C @@ -0,0 +1,141 @@ +// Scans all DF_* folders for O2bc_001 TTrees and checks that the +// fGlobalBC branch (ULong64_t) is monotonically non-decreasing. + +#ifndef __CLING__ +#include "TBranch.h" +#include "TDirectory.h" +#include "TFile.h" +#include "TKey.h" +#include "TLeaf.h" +#include "TTree.h" +#include +#include +#include +#endif + +struct BCReport { + bool hasBranch = false; + bool monotonic = true; + Long64_t entries = 0; + Long64_t firstViolationEntry = -1; + Long64_t nViolations = 0; + ULong64_t maxBackwardJump = 0; + std::vector>> samples; +}; + +static BCReport checkO2bcTree(TTree *t) { + BCReport r; + if (!t) + return r; + + TBranch *br = t->GetBranch("fGlobalBC"); + if (!br) + return r; + r.hasBranch = true; + + ULong64_t buf = 0; + br->SetAddress(&buf); + + r.entries = t->GetEntries(); + if (r.entries <= 1) + return r; + + bool havePrev = false; + ULong64_t prevVal = 0; + + for (Long64_t i = 0; i < r.entries; ++i) { + t->GetEntry(i); + ULong64_t v = buf; + + if (!havePrev) { + prevVal = v; + havePrev = true; + continue; + } + + if (v < prevVal) { + if (r.firstViolationEntry < 0) + r.firstViolationEntry = i; + ++r.nViolations; + r.monotonic = false; + ULong64_t jump = prevVal - v; + if (jump > r.maxBackwardJump) + r.maxBackwardJump = jump; + if (r.samples.size() < 5) + r.samples.push_back({i, {prevVal, v}}); + } + + prevVal = v; + } + + return r; +} + +void AOD_check_globalBC_monotonic(const char *inFileName = "AO2D.root") { + std::string inFileStr(inFileName); + if (inFileStr.find("alien:") != std::string::npos) { + TGrid::Connect("alien"); + } + + std::cout << "Opening file: " << inFileName << std::endl; + TFile *f = TFile::Open(inFileName, "READ"); + if (!f || f->IsZombie()) { + std::cerr << "ERROR: cannot open input file.\n"; + return; + } + + Long64_t totalTrees = 0; + Long64_t totalWithBranch = 0; + Long64_t totalViolations = 0; + + TIter topKeys(f->GetListOfKeys()); + while (TKey *k = (TKey *)topKeys()) { + TObject *obj = k->ReadObj(); + if (!obj->InheritsFrom(TDirectory::Class())) + continue; + + TDirectory *dir = (TDirectory *)obj; + TString dname = dir->GetName(); + if (!dname.BeginsWith("DF_")) + continue; + + TTree *t = (TTree *)dir->Get("O2bc_001"); + if (!t) + continue; + ++totalTrees; + + BCReport r = checkO2bcTree(t); + + if (!r.hasBranch) { + std::cout << "[skip] " << dir->GetName() + << "/O2bc_001 has no fGlobalBC\n"; + continue; + } + ++totalWithBranch; + + if (r.monotonic) { + std::cout << "[ OK ] " << dir->GetName() << "/O2bc_001 — " << r.entries + << " entries, monotonic\n"; + } else { + ++totalViolations; + std::cout << "[BAD] " << dir->GetName() << "/O2bc_001 — " << r.entries + << " entries, first violation at entry " + << r.firstViolationEntry + << ", total violations: " << r.nViolations + << ", max backward jump: " << r.maxBackwardJump << "\n"; + + for (auto &s : r.samples) { + std::cout << " entry " << s.first << ": " << s.second.first + << " -> " << s.second.second << "\n"; + } + } + } + + std::cout << "\n==================== SUMMARY ====================\n"; + std::cout << "O2bc_001 trees checked: " << totalTrees << "\n"; + std::cout << "With fGlobalBC branch: " << totalWithBranch << "\n"; + std::cout << "Trees NOT monotonic: " << totalViolations << "\n"; + std::cout << "=================================================\n"; + + f->Close(); +} diff --git a/MC/utils/AOD_detect_unsorted_fIndexBCs.C b/MC/utils/AOD_detect_unsorted_fIndexBCs.C new file mode 100644 index 000000000..13571ac85 --- /dev/null +++ b/MC/utils/AOD_detect_unsorted_fIndexBCs.C @@ -0,0 +1,260 @@ +// Scans DF_* folders, finds trees with an Int-like "fIndexBCs" branch, +// and reports those where fIndexBCs is not monotonically non-decreasing. +// Negative values (e.g. -1) are ignored for the monotonicity check. + +#ifndef __CLING__ +#include "TBranch.h" +#include "TDirectory.h" +#include "TFile.h" +#include "TKey.h" +#include "TLeaf.h" +#include "TString.h" +#include "TTree.h" +#include +#include +#include +#include +#include +#endif + +struct MonotonicReport { + bool hasBranch = false; // tree has fIndexBCs + bool monotonic = true; // true if non-decreasing + Long64_t entries = 0; + Long64_t firstViolationEntry = -1; // entry index of first backward step + Long64_t nViolations = 0; // count of backward steps + Long64_t maxBackwardJump = 0; // biggest (prevValid - curr) observed + std::vector>> + samples; // (entry, (prev, curr)) +}; + +/// Try to bind a branch named "fIndexBCs" with an integral buffer. +/// Supports common integer POD types (Int_t, UInt_t, Long64_t, ULong64_t). +/// Returns: pointer to bound buffer as int64_t-compatible view (value is +/// copied), and sets branch address appropriately. +class FIndexBinder { +public: + TBranch *br = nullptr; + std::string type; + // One of these will be used based on the branch's leaf type: + Int_t buf_i = 0; + UInt_t buf_ui = 0; + Long64_t buf_l = 0; + ULong64_t buf_ul = 0; + + // which is active + enum Kind { KNone, KInt, KUInt, KLong64, KULong64 } kind = KNone; + + bool bind(TTree *t, const char *name = "fIndexBCs") { + br = t->GetBranch(name); + if (!br) + return false; + if (br->GetListOfLeaves()->GetEntries() <= 0) + return false; + TLeaf *leaf = (TLeaf *)br->GetListOfLeaves()->At(0); + type = leaf->GetTypeName(); + + if (type == "Int_t") { + kind = KInt; + br->SetAddress(&buf_i); + } else if (type == "UInt_t") { + kind = KUInt; + br->SetAddress(&buf_ui); + } else if (type == "Long64_t") { + kind = KLong64; + br->SetAddress(&buf_l); + } else if (type == "ULong64_t") { + kind = KULong64; + br->SetAddress(&buf_ul); + } else { + // not an integer POD we handle + kind = KNone; + br = nullptr; + return false; + } + return true; + } + + // Read the current value as signed 64-bit (for comparisons). + // For unsigned, cast safely to signed domain if within range; otherwise + // clamp. + Long64_t valueAsI64() const { + switch (kind) { + case KInt: + return (Long64_t)buf_i; + case KUInt: + return (buf_ui <= (UInt_t)std::numeric_limits::max() + ? (Long64_t)buf_ui + : (Long64_t)std::numeric_limits::max()); + case KLong64: + return buf_l; + case KULong64: + return (buf_ul <= (ULong64_t)std::numeric_limits::max() + ? (Long64_t)buf_ul + : (Long64_t)std::numeric_limits::max()); + default: + return 0; + } + } +}; + +static MonotonicReport checkTreeMonotonic(TTree *t, bool verbose = false) { + MonotonicReport r; + if (!t) + return r; + + // Speed up: only read the target branch + t->SetBranchStatus("*", 0); + if (t->GetBranch("fIndexBCs")) + t->SetBranchStatus("fIndexBCs", 1); + + FIndexBinder binder; + if (!binder.bind(t, "fIndexBCs")) { + r.hasBranch = false; + // Re-enable all for safety if user continues using the tree later + t->SetBranchStatus("*", 1); + return r; + } + r.hasBranch = true; + + r.entries = t->GetEntries(); + if (r.entries <= 1) { + r.monotonic = true; + t->SetBranchStatus("*", 1); + return r; + } + + bool havePrev = false; + Long64_t prevValid = 0; + + for (Long64_t i = 0; i < r.entries; ++i) { + t->GetEntry(i); + Long64_t v = binder.valueAsI64(); + + // Ignore negatives (e.g. -1 sentinel values) + if (v < 0) + continue; + + if (!havePrev) { + prevValid = v; + havePrev = true; + continue; + } + + if (v < prevValid) { + // backward step + if (r.firstViolationEntry < 0) + r.firstViolationEntry = i; + ++r.nViolations; + r.monotonic = false; + Long64_t jump = prevValid - v; + if (jump > r.maxBackwardJump) + r.maxBackwardJump = jump; + if (r.samples.size() < 5) + r.samples.push_back({i, {prevValid, v}}); + // Do not update prevValid here; we keep comparing to last valid + // non-decreasing reference + continue; + } + + // normal non-decreasing step + prevValid = v; + } + + // Restore statuses + t->SetBranchStatus("*", 1); + return r; +} + +void AOD_detect_unsorted_fIndexBCs(const char *inFileName = "AO2D.root", + bool verbosePerTree = false) { + std::cout << "Opening file: " << inFileName << std::endl; + TFile *f = TFile::Open(inFileName, "READ"); + if (!f || f->IsZombie()) { + std::cerr << "ERROR: cannot open input file.\n"; + return; + } + + Long64_t totalTreesChecked = 0; + Long64_t totalWithBranch = 0; + Long64_t totalViolations = 0; + + std::cout << "Scanning top-level for DF_* folders...\n"; + + // Iterate top-level keys + TIter kIt(f->GetListOfKeys()); + while (TKey *k = (TKey *)kIt()) { + TString kname = k->GetName(); + TObject *obj = k->ReadObj(); + + if (!obj->InheritsFrom(TDirectory::Class()) || !kname.BeginsWith("DF_")) { + continue; + } + + auto *dir = (TDirectory *)obj; + std::cout << "\n====================================================\n"; + std::cout << "DF folder: " << dir->GetName() << "\n"; + + // Iterate all keys in this DF directory + TIter dIt(dir->GetListOfKeys()); + while (TKey *dk = (TKey *)dIt()) { + TObject *tobj = dir->Get(dk->GetName()); + if (!tobj->InheritsFrom(TTree::Class())) { + continue; // only trees are relevant + } + + TTree *t = (TTree *)tobj; + ++totalTreesChecked; + + // Only consider trees that *have* fIndexBCs + if (!t->GetBranch("fIndexBCs")) { + if (verbosePerTree) { + std::cout << " [skip] " << t->GetName() << " (no fIndexBCs)\n"; + } + continue; + } + ++totalWithBranch; + + MonotonicReport r = checkTreeMonotonic(t, verbosePerTree); + + if (!r.hasBranch) { + // Shouldn't happen due to prior check, but keep robust + if (verbosePerTree) { + std::cout << " [skip] " << t->GetName() + << " (failed to bind branch)\n"; + } + continue; + } + + if (r.monotonic) { + if (verbosePerTree) { + std::cout << " [ OK ] " << t->GetName() + << " — entries: " << r.entries << " (non-decreasing)\n"; + } + } else { + ++totalViolations; + std::cout << " [BAD] " << t->GetName() << " — entries: " << r.entries + << ", first violation at entry " << r.firstViolationEntry + << ", total backward steps: " << r.nViolations + << ", max backward jump: " << r.maxBackwardJump << "\n"; + + // Print a few examples of (prev, curr) causing violation + if (!r.samples.empty()) { + std::cout << " sample backward steps (entry: prev -> curr):\n"; + for (auto &s : r.samples) { + std::cout << " " << s.first << ": " << s.second.first + << " -> " << s.second.second << "\n"; + } + } + } + } + } + + std::cout << "\n==================== SUMMARY ====================\n"; + std::cout << "Trees visited: " << totalTreesChecked << "\n"; + std::cout << "Trees with fIndexBCs: " << totalWithBranch << "\n"; + std::cout << "Trees NOT monotonic: " << totalViolations << "\n"; + std::cout << "=================================================\n"; + + f->Close(); +} diff --git a/MC/utils/CLAUDE.md b/MC/utils/CLAUDE.md new file mode 100644 index 000000000..56968ed16 --- /dev/null +++ b/MC/utils/CLAUDE.md @@ -0,0 +1,372 @@ +# CLAUDE.md — AODBcRewriter Development Handoff + +## Current work state (handoff — 2026-06-09) + +**Branch:** `fix/aodbcrewriter-track-regroup` · **Last commit:** `8bb9d30b3c` +(committed, not yet pushed/validated). + +### The bug being fixed: tracks' `-1` collision group split + +Downstream O2 analysis (`o2-analysis-event-selection`) was crashing with: + +``` +[FATAL] Table Tracks_IU index fIndexCollisions has a group with index -1 + that is split by 776 +``` + +O2's `ArrowTableSlicingCache::validateOrder` requires every `fIndexCollisions` +group in a track table — **including the `-1` "ambiguous" group** — to be one +contiguous run of rows. Two commits broke this: + +- **`b11cd3de`** added a value-wise remap of tracks' `fIndexCollisions` via + `collPerm` but left the track **rows in input order**. Since Stage 1 reorders + `O2collision` (sort by remapped `fIndexBCs`), the remapped values no longer + formed contiguous groups → the split. (b11cd3de made the *values* correct at + the cost of the *grouping*; the complete fix needs **both** — reorder rows + *and* remap values.) +- **`28b44ef`** (a colleague's attempt) then replaced the Stage 0 BC **sort** + with an order-preserving dedup that `std::abort()`s unless the input BC table + is already `globalBC`-sorted. That contradicts PURPOSE (a) — repairing + *non-monotonic* BCs in merged files — so it aborted on exactly the files the + tool exists to fix ("doesn't run to completion"). + +### What the current fix does + +1. **Reverted only the Stage 0 change** of `28b44ef`: restored `stage0_sortBCs` + (sort + dedup) and removed the abort. Non-monotonic merged BCs are repaired + again, as intended. +2. **Kept `28b44ef`'s Stage 1b** (`stage1b_reorderTrackTables`, Section 9b) and + the `fIndexTracks*` / `fIndexMFTTracks` / `fIndexFwdTracks` remaps in + `processPasteJoinTables`. This regroup-tracks-by-remapped-`fIndexCollisions` + mechanism is the *correct* fix for the split; it only ever failed because the + aborting Stage 0 stopped it from running. Rewriting it from scratch was + judged higher-risk than keeping the reviewed logic. +3. **Added validator check** `checkCollisionGroupContiguity` (Section 11): + mirrors O2's slicing invariant — flags any `fIndexCollisions` group split + into >1 run. Runs over every collision-grouped track table. + +**Design note / cascade:** sorting BCs is unavoidable for non-monotonic input +and forces a reorder cascade **BC (Stage 0) → collisions (Stage 1) → tracks +(Stage 1b)**, propagated to paste-join children and all track references. Do +**not** re-introduce an "assert already sorted / order-preserving" Stage 0 — it +is a known dead end (see the history note in the Section 4 code comment). + +### Not done yet / next steps for whoever picks this up + +- **UNVALIDATED on real data.** Parses cleanly in cling (`.L AODBcRewriter.C`), + but has *not* been run on a real merged AO2D, nor through the analysis task + that crashed. The macro is interpreter-only; `.L AODBcRewriter.C+` (ACLiC) + fails on missing std includes — pre-existing, not a regression. + Test sequence: `AODBcRewriter("AO2D.root","out.root")` → + `AODBcRewriterValidate("out.root")` (expect no `[FAIL]`) → then the **real** + `o2-analysis-event-selection` on `out.root` (ground truth). +- **Known fragility (whack-a-mole):** the `fIndexTracks*` reference remap is a + hardcoded enumeration in `processPasteJoinTables` and the validator's + `kIndexBranchToTable`. A missed reference into a reordered track table = silent + corruption. Longer term, *derive* index→referent relationships from the AO2D + column-name conventions instead of enumerating. +- **Biggest gap:** there is no executable analysis-level CI for this tool, so + regressions are only found in production with delay. Building a reproducer + (merged AO2D that triggers the split/abort) + a CI check that runs the real + task is the agreed top priority after this fix lands. + +--- + +## What this tool does + +`AODBcRewriter.C` is a ROOT macro that fixes structural integrity problems in +ALICE Run3 AO2D files after merging. AO2D files are ROOT files containing +`DF_*` subdirectories, each holding a set of TTrees that form a relational +schema (similar to a database). After merging two AO2D files with `hadd` or +similar tools, three problems can arise: + +1. **Non-monotonic `fGlobalBC`** in the BC table — the framework requires + strictly increasing values. +2. **Duplicate `fGlobalBC` entries** — the same bunch crossing represented by + multiple rows. +3. **Duplicate MCCollision entries** — the same MC event appearing twice + because it was present in both source files before merging. + +Run with: +```bash +root -l -b -q 'AODBcRewriter.C("AO2D.root","AO2D_rewritten.root")' +``` + +--- + +## AO2D data model (relevant subset) + +The tables form a dependency graph. Every stage of the tool processes one +level of this graph and produces a **PermMap** (`vector`, +`permMap[oldRow] = newRow`, -1 = row dropped) which the next stage consumes. + +``` +BCs (O2bc_*) [Stage 0] + │ fIndexBCs / fIndexBC + ├─► Collisions (O2collision_*) [Stage 1] + │ │ paste-join ──► McCollisionLabels (O2mccollisionlabel_*) + │ └─► Tracks (O2track_*, O2trackiu_*, ...) [Stage 1] + │ paste-join ─► McTrackLabels (O2mctracklabel_*) + │ paste-join ─► McFwdTrackLabels, McMFTTrackLabels + │ + └─► MCCollisions (O2mccollision_*) [Stage 1, deduped] + │ fIndexMcCollisions + ├─► HepMCXSections (O2hepmcxsection_*) [Stage 2] + ├─► HepMCPdfInfos (O2hepmcpdfinfo_*) [Stage 2] + └─► HepMCHeavyIons (O2hepmcheavyion_*) [Stage 2] +``` + +**Index joins** (`fIndexBCs`, `fIndexCollisions`, `fIndexMcCollisions`) are +explicit integer columns pointing to a row in another table by position. + +**Paste joins** are implicit: table row N of a paste-joined table corresponds +to row N of its parent table. These tables have *no index column*. They must +be reordered to match their parent whenever the parent is reordered. + +The known paste-join relationships are hardcoded in `kPasteJoins` (Section 1). +The list is authoritative — derived from `AnalysisDataModel.h` comments +("Table joined to the collision table containing the MC index", etc.) and +from the SOA `EXTENDED_TABLE` declarations for cov / extra tables: +``` +O2bcflag → parent: O2bc_* (BCFlags joinable with BCs) +O2mccollisionlabel → parent: O2collision_* (McCollisionLabels) +O2mctracklabel → parent: O2track_iu (or O2track) +O2mcfwdtracklabel → parent: O2fwdtrack +O2mcmfttracklabel → parent: O2mfttrack +O2mccalolabel → parent: O2calo (McCaloLabels) +O2trackcov_iu → parent: O2track_iu (TracksCovIU extension) +O2trackextra → parent: O2track_iu (TracksExtra extension) +O2fwdtrackcov → parent: O2fwdtrack (FwdTracksCov extension) +``` +NOT in this list (despite the suffix): `O2mfttrackcov` carries its own +`fIndexMFTTracks` and is **index-linked**, not paste-joined. + +A child may carry its own index columns (e.g. `O2mccollisionlabel` carries +`fIndexMcCollisions`). Those values are remapped *value-wise* through the +appropriate parent-stage permutation, but the child's row count and row +order strictly follow its paste-join parent. + +--- + +## Code structure (11 sections) + +| Section | Function(s) | Purpose | +|---------|-------------|---------| +| 1 | `PermMap`, `isBCTable`, `bcIndexBranch`, `mcCollIndexBranch`, `collIndexBranch`, `kPasteJoins`, `isPasteJoinChild` | Core types, name-probe helpers, and the authoritative paste-join list | +| 2 | `ScalarTag`, `tagOf`, `byteSize`, `readAsInt`, `writeAsInt`, `BranchDesc`, `describeBranches` | Generic ROOT branch I/O over raw byte buffers | +| 3 | `rewriteTable` | **Central engine**: writes any table in a given row order, remapping one nominated index column via a PermMap | +| 4 | `BCStage0Result`, `stage0_sortBCs` | Sort + deduplicate the BC table; produce `bcPerm` | +| 5 | `stage0_copyBCFlags` | Copy BC flags table following BC row selection | +| 6 | `MCCollKey`, `MCCollKeyHash`, `stage1_BCindexedTables` | Process all BC-indexed tables; deduplicate MCCollisions | +| 7 | `stage2_MCCollIndexedTables` | Process all MCCollision-indexed tables; drop rows whose parent was deduped | +| 9b | `isCollGroupedTrackTable`, `stage1b_reorderTrackTables` | **Stage 1b**: regroup collision-grouped track tables (`O2track_iu`, `O2mfttrack`, `O2fwdtrack`) by remapped `fIndexCollisions` (`-1` sinks to a contiguous tail); publish track perms so children/references follow. Restores the O2 slicing invariant after the BC→collision reorder cascade | +| 8 | `rowOrderFromPerm`, `findPermByPrefix`, `processPasteJoinTables` | Reorder paste-joined tables to follow their parent (1:1 row count guaranteed); remap any of their own index columns value-wise (incl. `fIndexTracks*` via the Stage 1b track perms); copy unrelated tables verbatim | +| 9 | `copyNonTreeObjects` | Copy TMap metadata and other non-TTree objects | +| 10 | `processDF` | Orchestrates all stages for one `DF_*` directory | +| 11 | `AODBcRewriter` | Top-level entry: opens files, iterates `DF_*` dirs, preserves compression | + +### `rewriteTable` — the central engine + +```cpp +PermMap rewriteTable(TTree *src, TDirectory *dirOut, + const vector &rowOrder, + const string &indexBranch, + const PermMap &parentPerm); +``` + +- `rowOrder`: which source rows to emit and in what sequence (may be a subset + for deduplication, or reordered for sorting) +- `indexBranch`: name of the one index column to remap (e.g. `"fIndexBCs"`), + or `""` for none +- `parentPerm`: the PermMap from the parent stage used to translate the old + index value to a new one +- Returns `srcToOut` PermMap: `srcToOut[srcRow] = outRow`, -1 if dropped + +The function handles both scalar branches and VLA (variable-length array) +branches generically. For VLAs it pre-scans the count branch to find the +maximum array length and allocates buffers accordingly. Input and output +branches share the same raw byte buffers; ROOT handles the VLA count +implicitly through the shared count buffer. + +--- + +## MCCollision deduplication + +Implemented in `stage1_BCindexedTables` when the current table begins with +`O2mccollision`. + +**Key**: `MCCollKey { Long64_t newBCrow; Float_t weight; }` using `fEventWeight`. + +**Important constraint**: deduplication is only enabled when `fEventWeight` is +present in the tree. If it is absent, all rows are kept (only reordered). This +is intentional: deduplicating on `newBCrow` alone would incorrectly collapse +distinct MC events that happen to share the same bunch crossing. + +When a MCCollision row is dropped (PermMap entry = -1), Stage 2 propagates +the drop: any `O2hepmcxsection_*` / `O2hepmcpdfinfo_*` / `O2hepmcheavyion_*` +row whose `fIndexMcCollisions` pointed to a dropped row is also dropped. + +--- + +## Known gaps / TODO items + +These were identified during the refactor but not yet implemented: + +### 1. `fIndexCollisions` inside `O2mccollision` is not remapped + +`O2mccollision` has both `fIndexBCs` (handled) and `fIndexCollisions` (linking +back to the reconstructed `O2collision` row). After Stage 1 reorders +`O2collision`, this second index in `O2mccollision` becomes stale. + +**Fix**: After `stage1_BCindexedTables` runs, find `collPerm` (the PermMap for +`O2collision_*`) in `stage1Perms`, then apply a second `rewriteTable` pass on +`O2mccollision_*` to remap `fIndexCollisions` via `collPerm`. The +`ExtraRemap` mechanism in `rewriteTable` already supports this pattern. + +### 2. Deduplication key could be strengthened + +The current `(newBCrow, fEventWeight)` key is a good heuristic. A more robust +key would additionally include `fImpactParameter` and/or `fGeneratorsID` if +those branches are present. Consider making the key construction a small +helper function that probes which fields are available and builds the strongest +possible key. + +### 3. `O2mccollision` has two potential parents for paste-join lookup + +In `processDF`, the MCColl PermMap is extracted by scanning `stage1Perms` for +a name beginning with `"O2mccollision"`. If the DF contains both +`O2mccollision_000` and `O2mccollision_001` (schema version coexistence), +only the first found is used. Add a warning and handle this explicitly if it +becomes relevant. + +### 4. Paste-join size-mismatch fallback is silent-ish + +When a paste-joined table has a different row count from its parent (schema +drift), the tool falls back to `CloneTree(-1, "fast")` and prints a warning. +This produces a structurally inconsistent output. Consider making this a hard +error, or implement a best-effort row-count reconciliation. + +### ~~5. No validation pass~~ (RESOLVED) + +`AODBcRewriterValidate(fname)` (Section 11) now validates BC monotonicity, +MC-particle intra-table index integrity, paste-join row-count parity, and +generic `fIndex*` range against the referent table. Call it after rewriting +to confirm output correctness. + +### ~~6. fIndexArray_Mothers / fIndexSlice_Daughters not remapped~~ (RESOLVED) + +This was the root cause of the O2Physics FATAL +`MC particle N has daughter with index M > MC particle table size`. +After Stage 2 reorders `O2mcparticle`, the intra-table mother/daughter indices +now get remapped via `ExtraRemap` in the same pass (Section 7). + +`fIndexMcParticles` in label tables (`O2mctracklabel`, `O2mcfwdtracklabel`, +`O2mcmfttracklabel`, `O2mccalolabel`) is also now remapped via the MC-particle +permutation in `processPasteJoinTables` (Section 8). + +### ~~8. fIndexSliceBCs in O2ambiguous* not remapped after BC dedup~~ (RESOLVED) + +`fIndexSliceBCs` is a SOA `SLICE_INDEX_COLUMN(BC, bc)` (header line 1029), +stored on disk as a fixed `[2]/I` `{first, last}` pair pointing into the BC +table. It appears in `O2ambiguoustrack`, `O2ambiguousmfttr`, +`O2ambiguousfwdtr` — none of which carry `fIndexBCs` and therefore none +were processed by Stage 1. After BC dedup the slice endpoints would then +point past the compacted table. + +**Fix**: `processPasteJoinTables` now also accepts the BC permutation +(passed explicitly from `processDF`) and applies it value-wise to any +`fIndexSliceBCs` / `fIndexBCs` / `fIndexBC` column it finds. Validated +against `example_AOD/AO2D_pre.root`: pre-fix the rewritten output had 7 +and 19 out-of-range slice endpoints in DF_3594457012003; post-fix the +validator reports zero. + +### ~~7. Paste-join row-count drift on MC-collision dedup~~ (RESOLVED) + +`O2mccollisionlabel` is paste-joined to `O2collision_*` (row N ↔ row N) but +also carries `fIndexMcCollisions`. The previous code routed it through Stage +2 (because of the MC-collision index), which sorted it by new MC-collision +position and *dropped* rows whose MC collision had been deduplicated. That +left `O2mccollisionlabel` shorter than `O2collision_*` by N rows — leading +to downstream "O2collision_001 is one larger than O2mccollisionlabel" crashes. + +**Fix**: `kPasteJoins` was extended to cover every joined pair from +`AnalysisDataModel.h`. Paste-join children are now *deferred* from Stage 2 +to `processPasteJoinTables`, where they take the parent's row order and have +their own index columns remapped value-wise. Rows that lose their MC label +on dedup now correctly produce `fIndexMcCollisions == -1`, and the row count +matches the parent collision table. + +The new validator catches the regression class as +`[FAIL] paste-join size mismatch: O2mccollisionlabel* has N rows but parent + O2collision* has M`. + +### ~~9. Tracks' `-1` collision group split after BC/collision reorder~~ (RESOLVED — pending validation) + +See the **Current work state** section at the top for the full story. In short: +after Stage 1 reorders `O2collision`, the collision-grouped track tables must be +**reordered** (not just have their `fIndexCollisions` values remapped) so each +group — including the `-1` ambiguous group — stays one contiguous run, as O2's +`ArrowTableSlicingCache::validateOrder` requires. + +**Fix:** Stage 1b (`stage1b_reorderTrackTables`, Section 9b) stable-sorts each +track table by remapped `fIndexCollisions` (`-1` to a contiguous tail), publishes +the track perm, and `processPasteJoinTables` follows it for paste-join children +and remaps every `fIndexTracks*` reference. New validator check +`checkCollisionGroupContiguity` flags split groups as +`[FAIL] ... fIndexCollisions has N group(s) split into non-contiguous runs`. + +**Status:** committed on `fix/aodbcrewriter-track-regroup` (`8bb9d30b3c`), parses +in cling, **not yet run on a real merged AO2D or the failing analysis task.** + +--- + +## Testing checklist + +When testing a new AO2D: + +1. Run `AODBcRewriterValidate("AO2D_rewritten.root")` (Section 11). + It checks BC monotonicity, MC-particle intra-table integrity, paste-join + row-count parity for every pair in `kPasteJoins`, and `fIndex*` value + ranges against the referent table. Failures appear as `[FAIL] ...` lines. +2. Check stdout from the rewrite run itself for any `[warn]` lines — these + indicate branches or tables that fell through to a fallback path. +3. If deduplication ran, verify the dropped count is as expected by comparing + the input DF MCCollision count vs. output. + +A standalone minimal validation script (kept here for reference; in practice +just call `AODBcRewriterValidate`): +```cpp +// validate.C +void validate(const char *fname) { + TFile *f = TFile::Open(fname); + TIter top(f->GetListOfKeys()); + while (TKey *k = (TKey*)top()) { + if (!TString(k->GetName()).BeginsWith("DF_")) continue; + TDirectory *d = (TDirectory*)f->Get(k->GetName()); + // check BC monotonicity + TTree *bc = (TTree*)d->Get("O2bc_001"); // adjust suffix + if (bc) { + ULong64_t gbc, prev = 0; bool ok = true; + bc->SetBranchAddress("fGlobalBC", &gbc); + for (Long64_t i = 0; i < bc->GetEntries(); ++i) { + bc->GetEntry(i); + if (i > 0 && gbc <= prev) { printf("BC non-monotonic at row %lld\n", i); ok=false; } + prev = gbc; + } + if (ok) printf("%s: BCs OK (%lld entries)\n", k->GetName(), bc->GetEntries()); + } + } +} +``` + +--- + +## Data model reference + +Full table schema: https://aliceo2group.github.io/analysis-framework/docs/datamodel/ao2dTables.html + +Source definitions: `AliceO2/Framework/Core/include/Framework/AnalysisDataModel.h` + +The upstream PR this work improves upon: https://github.com/AliceO2Group/O2DPG/pull/2317 + +Target file location in O2DPG: `MC/utils/AODBcRewriter.C` \ No newline at end of file diff --git a/MC/utils/metrics/README.md b/MC/utils/metrics/README.md new file mode 100644 index 000000000..38043aade --- /dev/null +++ b/MC/utils/metrics/README.md @@ -0,0 +1,3 @@ +Set of scripts and utilities for the creation and processing +of workflow metrics (CPU, memory, walltime) for tasks executed +in o2dpg_workflow_runner.py and derived from its pipeline_metric*.log monitoring. \ No newline at end of file diff --git a/MC/utils/metrics/metrics_harvester.py b/MC/utils/metrics/metrics_harvester.py new file mode 100644 index 000000000..30585ed26 --- /dev/null +++ b/MC/utils/metrics/metrics_harvester.py @@ -0,0 +1,224 @@ +#!/usr/bin/env python3 + +# A python tool, that calculates mean O2DPG workflow metrics by +# harvesting from data from pipeline_metric files from the GRID (for a given lpm production tag). + +import json +import subprocess +from collections import defaultdict +import re +import os +import argparse +import random +from pathlib import Path +import sys +import time +from concurrent.futures import ThreadPoolExecutor, ProcessPoolExecutor, as_completed + +# add the parent directory of the current file to sys.path to find the o2dpg_sim_metric +sys.path.append(os.path.abspath(os.path.join(os.path.dirname(__file__), '..'))) +from o2dpg_sim_metrics import json_stat_impl + +def alien_find(path, pattern="*", logging=False): + cmd = ["alien.py", "find", path, pattern] + if logging: + print (f"Performing {cmd}") + result = subprocess.run(cmd, capture_output=True, text=True, check=True) + return [line.strip() for line in result.stdout.splitlines() if line.strip()] + + +def alien_cp(alien_path, local_path, parent=None, fatal=False, logging=False): + cmd = ["alien.py", "cp"] + if parent != None: + cmd = cmd + ["-parent", f"{parent}"] + cmd = cmd + [f"alien://{alien_path}", f"file://{local_path}"] + if logging: + print (f"Performing {cmd}") + try: + subprocess.run(cmd, stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL, check=True) + except subprocess.CalledProcessError as e: + pass + +def alien_cp_inputfile(inputfile, logging=False): + cmd = ["alien.py", "cp", "-input", f"{inputfile}"] + if logging: + print (f"Performing {cmd}") + subprocess.run(cmd, stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL, check=True) + +def parse_workflow_path(path, prod_tag): + parts = path.strip("/").split("/") + try: + idx = parts.index(prod_tag) + except ValueError: + return None + + after = parts[idx + 1 :] + if len(after) < 2: + return None + + if after[0].isdigit() and len(after[0]) == 1: + cycle = int(after[0]) + run_number = int(after[1]) + split = after[2] + else: + cycle = None + run_number = int(after[0]) + split = after[1] + + return cycle, run_number, split + + +def calculate_statistics(selecteddirs, prod_tag, run_number, batchcopy = False): + """ + downloads the metrics files and calculates aggregates statistics + """ + targetdir = f"/tmp/o2dpg_metrics_harvester/{prod_tag}/{run_number}" + if not os.path.exists(targetdir): + os.makedirs(targetdir) + + start=time.time() + # determine target dir based on tag and run_number + if batchcopy == True: + # make an inputfile + inputfile = f"{targetdir}/cp_input.list" + with open(inputfile,'w') as f: + for dir in selecteddirs: + path = Path(dir) + # Get the last 1 components --> mimics -parent which does not work with inputlists + last_N = Path(*path.parts[-1:]) + f.write(f"{dir}/pipeline_metr* file:{targetdir}/{last_N}\n") + + # copy with the input-file + alien_cp_inputfile(inputfile, logging=True) + + else: + for dir in selecteddirs: + # avoid copy if we can ! + # we need to keep 2-top level dirs + alien_cp(f"{dir}/pipeline_metr*", targetdir, parent=1) + + end=time.time() + print(f"Copy took {end-start:.4f} seconds") + + # construct the list of all inputfiles + input_files = [str(p) for p in Path(targetdir).rglob('pipeline_metr*')] + print(input_files) + + # calculate the stats with all the files in targetdir + outputfilename=f"{targetdir}/merged_metrics.json" + meta_info = {"prod-tag" : prod_tag, "run-number" : run_number} + json_stat_impl(input_files, outputfilename, meta_info) + +import os +from concurrent.futures import ThreadPoolExecutor, ProcessPoolExecutor + +def treat_parallel(func, data, use_threads=False, max_workers=None): + """ + Apply `func` to each element of `data` in parallel. + + Parameters + ---------- + func : callable + The function to apply to each element. + data : iterable + The data to process. + use_threads : bool, default=False + If True, use threads (good for I/O-bound tasks). + If False, use processes (good for CPU-bound tasks). + max_workers : int, optional + Number of workers to use. Defaults to number of CPUs for processes. + + Returns + ------- + list + The results in the same order as `data`. + """ + if max_workers is None: + max_workers = os.cpu_count() if not use_threads else min(32, os.cpu_count() * 5) + + Executor = ThreadPoolExecutor if use_threads else ProcessPoolExecutor + + # --- Use map to preserve order --- + with Executor(max_workers=max_workers) as executor: + results = list(executor.map(func, data)) + + return results + +def treat_one_run(data_element): + """ + The final worker function to execute for each run. + Expects it's input parameters in a list to work well with Thread/ProcessExecutor and treat_parallel above. + + data_element should be a tuple, where + index 0 --> the run_number + index 1 --> a list of tuples(cycle, split, directory) + index 2 --> production tag + index 3 --> sample_size + """ + run_number, candidates = data_element[0], data_element[1] + prod_tag = data_element[2] + sample_size = data_element[3] + universe = [ w[2] for w in candidates ] + selected_dirs = random.sample(universe, min(len(universe), sample_size)) + print (f"For {run_number} selected {selected_dirs}") + calculate_statistics(selected_dirs, prod_tag, run_number, batchcopy=True) + + +def process_prod_tag(prod_tag, year="2025", ccdb_url=None, username=None, overwrite=False, samplesize=20): + base_path = f"/alice/sim/{year}/{prod_tag}" + + pipelinemetric_files = alien_find(base_path, "pipeline_metric*") + + # exclude some unnecessary paths + pipelinemetric_files = [ + zf for zf in pipelinemetric_files + if "/AOD/" not in zf and "/QC/" not in zf and "/TimeseriesTPCmerging/" not in zf and "/Stage" not in zf + ] + print (f"Found {len(pipelinemetric_files)} pipeline metric files") + + # directories containing workflow.json + workflow_dirs = {os.path.dirname(wf) for wf in pipelinemetric_files} + print (f"Found {len(workflow_dirs)} workflow dirs") + + # Step 2: group by run_number + runs = defaultdict(list) + for dir in workflow_dirs: + parsed = parse_workflow_path(dir, prod_tag) + if parsed is None: + continue + cycle, run_number, split = parsed + runs[run_number].append((cycle, split, dir)) + print(f"Found {len(runs)} run numbers") + + # Step 3: for each run_number, pick samplesize files for the final calculation + # for run_number, candidates in sorted(runs.items()): + # universe = [ w[2] for w in candidates ] + # selected_dirs = random.sample(universe, min(len(universe), samplesize)) + # print (f"For {run_number} selected {selected_dirs}") + + # # calculate merged statistics from the sample + # calculate_statistics(selected_dirs, prod_tag, run_number, batchcopy=False) + + data = [ (d[0], d[1], prod_tag, samplesize) for d in sorted(runs.items()) ] + do_parallel = True + if do_parallel == True: + treat_parallel(treat_one_run, data, use_threads=False, max_workers=8) + else: + for data_element in data: + treat_one_run(data_element) + +def main(): + parser = argparse.ArgumentParser( + description="Harvest MC metrics from AlienGRID; aggregate; and publish to CCDB" + ) + parser.add_argument("--prod_tag", required=True, help="Production tag (e.g. prod2025a)") + parser.add_argument("--ccdb", required=False, default="https://alice-ccdb.cern.ch", help="CCDB server URL") + parser.add_argument("--username", required=False, help="GRID username (needs appropriate AliEn token initialized)") + parser.add_argument("--year", default="2025", help="Production year (default: 2025)") + parser.add_argument("--overwrite", action="store_true", help="Overwrite existing entries") + args = parser.parse_args() + + process_prod_tag(args.prod_tag, year=args.year, ccdb_url=args.ccdb, username=args.username, overwrite=args.overwrite) + +if __name__ == "__main__": + main() diff --git a/MC/utils/metrics/server.py b/MC/utils/metrics/server.py new file mode 100644 index 000000000..6c768c961 --- /dev/null +++ b/MC/utils/metrics/server.py @@ -0,0 +1,92 @@ + +# A simple HTTPS server with an endpoint on which +# callers can inject O2DPG_workflow_runner stat json metrics. +# The service is supposed to run as aggregator of these individual metrics +# and to provide high-quality merged statistics on resource estimates. These +# estimates can then be used to improve the scheduling of o2dpg_workflow_runner workflows. + +from fastapi import FastAPI +from pydantic import BaseModel +from asyncio import Queue, create_task +import asyncio, json, time +import aiofiles +from fastapi import Request + +import sys, os + +# add the parent directory of the current file to sys.path to find the o2dpg_sim_metric +sys.path.append(os.path.abspath(os.path.join(os.path.dirname(__file__), '..'))) +from o2dpg_sim_metrics import merge_stats_into + +app = FastAPI() +queue = Queue() +agg = {} # {(metric_name): {"sum": 0.0, "count": 0}} +flush_interval = 5 # seconds +outfile = "metrics.json" + +# Global state +agg_by_tag = {} # { production_tag: cached_result } + + +@app.post("/metric") +async def receive_metric(request : Request): + # just enqueue, return quickly + payload = await request.json() + await queue.put(payload) + return {"status": "ok"} + +def init_cache(): + """ + Initializes the cache of results from files + """ + pass + +def flush_to_disc(tag): + """ + flushes result for tag to disc + """ + metrics = agg_by_tag.get(tag, {}) + filename = f"aggr_metrics_tag_{tag}.json" + with open(filename, 'w') as f: + json.dump(metrics, f) + +async def worker(): + """ + Function performing the metrics aggregation + """ + while True: + payload = await queue.get() + + # Extract production-tag from metadata + meta = payload.get("meta-data", {}) + tag = meta.get("production-tag", "default") + + print (f"Worker is treating payload for tag {tag}") + + current = agg_by_tag.get(tag, {}) # fetch existing aggregate + updated = merge_stats_into([payload, current], None, meta) # merge new payload with cached + agg_by_tag[tag] = updated # store back in cache + + flush_to_disc(tag) + + queue.task_done() + + +async def flusher(): + while True: + await asyncio.sleep(flush_interval) + snapshot = { + k: (v["sum"] / v["count"]) if v["count"] else 0 + for k, v in agg.items() + } + async with aiofiles.open(outfile, "w") as f: + await f.write(json.dumps(snapshot, indent=2)) + print(f"Flushed {len(snapshot)} metrics at {time.ctime()}") + + +@app.on_event("startup") +async def startup(): + # start multiple workers for parallelism + for _ in range(8): # one per CPU core + create_task(worker()) + # create_task(flusher()) diff --git a/MC/utils/metrics/top_metrics.sh b/MC/utils/metrics/top_metrics.sh new file mode 100644 index 000000000..5f9e748ae --- /dev/null +++ b/MC/utils/metrics/top_metrics.sh @@ -0,0 +1,31 @@ +#!/usr/bin/env bash + +# a simple top-N metrics query for a couple of examples using jq +# assumes JSON produced by o2dpg_sim_metrics.py + +# top CPU-time consumers +jq 'to_entries + | map(select(.value.cpu?.mean != null and .value.lifetime?.mean != null)) + | sort_by(-(.value.cpu.mean * .value.lifetime.mean)) + | .[:5] + | map({name: .key, + cpu_mean: .value.cpu.mean, + lifetime_mean: .value.lifetime.mean, + product: (.value.cpu.mean * .value.lifetime.mean)})' merged_metrics.json + +# top mem consumers + + +# top cpu consumers +jq 'to_entries + | map(select(.value.cpu?.mean != null)) + | sort_by(-.value.cpu.mean) + | .[:5] + | map({name: .key, cpu_mean: .value.cpu.mean})' + +# top walltime consumers +jq 'to_entries + | map(select(.value.lifetime?.mean != null)) + | sort_by(-.value.lifetime.mean) + | .[:5] + | map({name: .key, lifetime_mean: .value.lifetime.mean})' \ No newline at end of file diff --git a/MC/utils/o2dpg_data_embedding_utils.py b/MC/utils/o2dpg_data_embedding_utils.py new file mode 100644 index 000000000..b152d991e --- /dev/null +++ b/MC/utils/o2dpg_data_embedding_utils.py @@ -0,0 +1,344 @@ +# Set of python modules/util functions for the MC-to-DATA embedding +# Mostly concerning extraction of MC collision context from existing data AO2D.root + +import warnings +warnings.filterwarnings( + "ignore", + message="pandas.Int64Index is deprecated", + category=FutureWarning, +) + +import ROOT +import uproot +import pandas as pd +import re +from ROOT import o2 # for CCDB +import argparse +import sys + +class lhc_constants: + LHCMaxBunches = 3564 # max N bunches + LHCRFFreq = 400.789e6 # LHC RF frequency in Hz + LHCBunchSpacingNS = 10 * 1.e9 / LHCRFFreq # bunch spacing in ns (10 RFbuckets) + LHCOrbitNS = LHCMaxBunches * LHCBunchSpacingNS # orbit duration in ns + LHCRevFreq = 1.e9 / LHCOrbitNS # revolution frequency + LHCBunchSpacingMUS = LHCBunchSpacingNS * 1e-3 # bunch spacing in \mus (10 RFbuckets) + LHCOrbitMUS = LHCOrbitNS * 1e-3 + +def thin_AO2D_file(input_file): + """ + A function to thin an existing AO2D file by just keeping a single DF_ folder + """ + + # Open the input ROOT file + infile = ROOT.TFile.Open(input_file, "READ") + + # Find the first TDirectory starting with "DF_" + df_dir = None + dir_name = "" + for key in infile.GetListOfKeys(): + name = key.GetName() + if name.startswith("DF_"): + # Access the TDirectory + df_dir = infile.Get(name) + dir_name = name + break + + if not df_dir: + raise RuntimeError("No TDirectory starting with 'DF_' found.") + + # Open the output file (create if not exist) + output_file = "AO2D_reduced_" + str(dir_name) + ".root" + outfile = ROOT.TFile.Open(output_file, "RECREATE") + + # Create the same directory structure in the output file + df_dir_copy = outfile.mkdir(dir_name) + + # Move to the newly created directory + df_dir_copy.cd() + + # Loop over the keys (trees) inside the "DF_" directory and copy them + for key in df_dir.GetListOfKeys(): + obj = df_dir.Get(key.GetName()) + if isinstance(obj, ROOT.TTree): # Check if it's a TTree + # Clone the tree and write it to the corresponding directory in the output file + obj.CloneTree(-1).Write(key.GetName(), ROOT.TObject.kOverwrite) # Copy the tree + + # Now handle the metaData;1 key (TMap) in the top-level directory + meta_data = infile.Get("metaData") + if meta_data: + if isinstance(meta_data, ROOT.TMap): + copied_meta_data = meta_data.Clone() + outfile.cd() # Make sure we're at the top-level in the output file + outfile.WriteObject(meta_data, "metaData") + + # Iterate over the map + iter = meta_data.MakeIterator() + entry = iter.Next() + while entry: + key = entry + value = meta_data.GetValue(key) + + # Convert TObjString to Python string + key_str = key.GetName() + value_str = value.GetName() if value else "None" + print(f"{key_str}: {value_str}") + entry = iter.Next() + + # Close the files + outfile.Close() + infile.Close() + + print(f"Copied all trees from TDirectory '{dir_name}' to '{output_file}'.") + + +def retrieve_Aggregated_RunInfos(run_number): + """ + Retrieves the aggregated runinfo object ... augmented with the number of timeframes + """ + runInfo = o2.parameters.AggregatedRunInfo.buildAggregatedRunInfo(o2.ccdb.BasicCCDBManager.instance(), run_number) + detList = o2.detectors.DetID.getNames(runInfo.grpECS.getDetsReadOut()) + assert (run_number == runInfo.runNumber) + assert (run_number == runInfo.grpECS.getRun()) + + run_info = {"SOR" : runInfo.sor, + "EOR" : runInfo.eor, + "FirstOrbit" : runInfo.orbitSOR, + "LastOrbit" : runInfo.orbitEOR, + "OrbitReset" : runInfo.orbitReset, + "OrbitsPerTF" : int(runInfo.orbitsPerTF), + "detList" : detList} + + # update num of timeframes + # figure out how many timeframes fit into this run range + # take the number of orbits per timeframe and multiply by orbit duration to calculate how many timeframes fit into this run + time_length_inmus = 1000 * (run_info["EOR"] - run_info["SOR"]) + ntimeframes = time_length_inmus / (run_info["OrbitsPerTF"] * lhc_constants.LHCOrbitMUS) + run_info["ntimeframes"] = ntimeframes + + return run_info + + +def get_bc_with_timestamps(bc_data, run_info): + """ + bc_data is a pandas df containing the AO2D basic bunch crossing data. + Returns the bc table with additional information on timeframeID etc. + """ + + # add a new column to the bc table dynamically + # this is the time in mu s + bc_data["timestamp"] = run_info["OrbitReset"] + (bc_data["fGlobalBC"] * lhc_constants.LHCBunchSpacingMUS).astype("int64") + bc_data["timeframeID"] = ((bc_data["fGlobalBC"] - (run_info["FirstOrbit"] * lhc_constants.LHCMaxBunches)) / (lhc_constants.LHCMaxBunches * run_info["OrbitsPerTF"])).astype("int64") + bc_data["orbit"] = (bc_data["fGlobalBC"] // lhc_constants.LHCMaxBunches).astype("int64") + bc_data["bc_within_orbit"] = (bc_data["fGlobalBC"] % lhc_constants.LHCMaxBunches).astype("int64") + return bc_data + + +def get_timeframe_structure(filepath, run_info, max_folders=1, include_dataframe = False, folder_filter=None): + """ + run_info: The aggregated run_info object for this run + """ + def find_tree_key(keys, pattern): + for key in keys: + key_clean = key + if re.search(pattern, key_clean, re.IGNORECASE): + return key_clean + return None + + file = uproot.open(filepath) + raw_keys = file.keys() + + folders = { k.split("/")[0] : 1 for k in raw_keys if "O2bc_001" in k } + folders = [ k for k in folders.keys() ] + folders = folders[:max_folders] + + print ("have ", len(raw_keys), f" in file {filepath}") + + merged = {} # data containers per file + for folder in folders: + if folder_filter != None and folder != folder_filter: + continue + #print (f"Looking into {folder}") + + # Find correct table names using regex + bc_key = find_tree_key(raw_keys, f"^{folder}/O2bc_001") + bc_data = file[bc_key].arrays(library="pd") + + # collision data + coll_key = find_tree_key(raw_keys, f"^{folder}/O2coll.*_001") + coll_data = file[coll_key].arrays(library="pd") + + # extend the data + bc_data = get_bc_with_timestamps(bc_data, run_info) + + # do the splice with collision data + bc_data_coll = bc_data.iloc[coll_data["fIndexBCs"]].reset_index(drop=True) + # this is the combined table containing collision data associated to bc and time information + combined = pd.concat([bc_data_coll, coll_data], axis = 1) + + # do the actual timeframe structure calculation; we only take collisions with a trigger decision attached + triggered = combined[combined["fTriggerMask"] != 0] + timeframe_structure = triggered.groupby('timeframeID').apply( + lambda g: list(zip(g['fGlobalBC'], g['fPosX'], g['fPosY'], g['fPosZ'], g['orbit'], g['bc_within_orbit'], g['fCollisionTime'])) + ).reset_index(name='position_vectors') + + folderkey = folder + '@' + filepath + merged[folderkey] = timeframe_structure # data per folder + if include_dataframe: + merged["data"] = combined + + # annotate which timeframes are available here and from which file + return merged + + +def fetch_bccoll_to_localFile(alien_file, local_filename): + """ + A function to remotely talk to a ROOT file ... and fetching only + BC and collision tables for minimal network transfer. Creates a ROOT file locally + of name local_filename. + + Returns True if success, otherwise False + """ + + # make sure we have a TGrid connection + # Connect to AliEn grid + if not ROOT.gGrid: + ROOT.TGrid.Connect("alien://") + + if not ROOT.gGrid: + print (f"Not TGrid object found ... aborting") + return False + + # Open the remote file via AliEn + infile = ROOT.TFile.Open(alien_file, "READ") + if not infile or infile.IsZombie(): + raise RuntimeError(f"Failed to open {alien_file}") + return False + + # Output local file + outfile = ROOT.TFile.Open(local_filename, "RECREATE") + + # List of trees to copy + trees_to_copy = ["O2bc_001", "O2collision_001"] + + # Loop over top-level keys to find DF_ folders + for key in infile.GetListOfKeys(): + obj = key.ReadObj() + if obj.InheritsFrom("TDirectory") and key.GetName().startswith("DF_"): + df_name = key.GetName() + df_dir = infile.Get(df_name) + + # Create corresponding folder in output file + out_df_dir = outfile.mkdir(df_name) + out_df_dir.cd() + + # Copy only specified trees if they exist + for tree_name in trees_to_copy: + if df_dir.GetListOfKeys().FindObject(tree_name): + tree = df_dir.Get(tree_name) + cloned_tree = tree.CloneTree(-1) # copy all entries + cloned_tree.Write(tree_name) + + outfile.cd() # go back to top-level for next DF_ + + # Close files + outfile.Close() + infile.Close() + return True + + +def convert_to_digicontext(aod_timeframe, df_folder, timeframeID=-1): + """ + converts AOD collision information from AO2D to collision context + which can be used for MC + """ + # we create the digitization context object + digicontext=o2.steer.DigitizationContext() + + # we can fill this container + parts = digicontext.getEventParts() + # we can fill this container + records = digicontext.getEventRecords() + # copy over information + maxParts = 1 + + entry = 0 + vertices = ROOT.std.vector("o2::math_utils::Point3D")() + vertices.resize(len(aod_timeframe)) + + colindex = 0 + for colindex, col in enumerate(aod_timeframe): + # we make an event interaction record + pvector = ROOT.std.vector("o2::steer::EventPart")() + pvector.push_back(o2.steer.EventPart(0, colindex)) + parts.push_back(pvector) + + orbit = col[4] + bc_within_orbit = col[5] + interaction_rec = o2.InteractionRecord(bc_within_orbit, orbit) + col_time_relative_to_bc = col[6] # in NS + time_interaction_rec = o2.InteractionTimeRecord(interaction_rec, col_time_relative_to_bc) + records.push_back(time_interaction_rec) + vertices[colindex].SetX(col[1]) + vertices[colindex].SetY(col[2]) + vertices[colindex].SetZ(col[3]) + + digicontext.setInteractionVertices(vertices) + digicontext.setNCollisions(vertices.size()) + digicontext.setMaxNumberParts(maxParts) + + # set the bunch filling ---> NEED to fetch it from CCDB + # digicontext.setBunchFilling(bunchFillings[0]); + + # TODO: set the interaction rate (for TPC loopers) + # digicontext.mDigitizerInteractionRate = ... + + prefixes = ROOT.std.vector("std::string")(); + prefixes.push_back("sgn") + + digicontext.setSimPrefixes(prefixes); + digicontext.printCollisionSummary(); + digicontext.saveToFile(f"collission_context_{df_folder}:{timeframeID}.root") + + +def process_data_AO2D(file_name, run_number, upper_limit = -1): + """ + Creates all the collision contexts + """ + timeframe_data = [] + + local_filename = "local.root" + fetch_bccoll_to_localFile(file_name, local_filename) + + # fetch run_info object + run_info = retrieve_Aggregated_RunInfos(run_number) + merged = get_timeframe_structure(local_filename, run_info, max_folders=1000) + print ("Got " + str(len(merged)) + " datasets") + timeframe_data.append(merged) + + counter = 0 + for d in timeframe_data: + for key in d: + result = d[key] + for index, row in result.iterrows(): + if upper_limit >= 0 and counter >= upper_limit: + break + tf = row['timeframeID'] + cols = row['position_vectors'] + df = key.split('@')[0] # this is the DF folder name + convert_to_digicontext(cols, df, tf) + counter = counter + 1 + + +def main(): + parser = argparse.ArgumentParser(description='Extracts collision contexts from reconstructed AO2D') + + parser.add_argument("--run-number", type=int, help="Run number to anchor to", required=True) + parser.add_argument("--aod-file", type=str, help="Data AO2D file (can be on AliEn)", required=True) + parser.add_argument("--limit", type=int, default=-1, help="Upper limit of timeframes to be extracted (-1 is no limit)") + args = parser.parse_args() + + process_data_AO2D(args.aod_file, args.run_number, args.limit) + +if __name__ == "__main__": + sys.exit(main()) diff --git a/MC/utils/o2dpg_sim_metrics.py b/MC/utils/o2dpg_sim_metrics.py index 25dbb00df..cb90fec09 100755 --- a/MC/utils/o2dpg_sim_metrics.py +++ b/MC/utils/o2dpg_sim_metrics.py @@ -12,6 +12,7 @@ import matplotlib import json import numpy as np +import math import pandas as pd ############################################################################ @@ -744,6 +745,108 @@ def extract_resources(pipelines): # Collect all metrics we got, here we want to have the median from all the iterations return [Resources(p) for p in pipelines] +def merge_stats(elementary, running): + """ + Merge an incoming elementary JSON into a running stats structure. + Also maintains running std using Welford's method. + + Each metric stores: + mean, std, M2, min, max, count + """ + if not elementary: + return running + + n_new_total = int(elementary.get("count", 1)) + running["count"] = running.get("count", 0) + n_new_total + + for name, metrics in elementary.items(): + if name == "count": + continue + + if name not in running: + running[name] = {"count": 0} + + # existing count for this name + n_old_name = running[name].get("count", 0) + + for metric, vals in metrics.items(): + if not isinstance(vals, dict): + continue + + if metric not in running[name]: + running[name][metric] = { + "min": vals.get("min"), + "max": vals.get("max"), + "mean": vals.get("mean"), + "std": 0.0, + "M2": 0.0, + "count": n_new_total + } + continue + + rmetric = running[name][metric] + n_old = rmetric.get("count", 0) + n_new = n_new_total + + # update min / max + e_min = vals.get("min") + e_max = vals.get("max") + if e_min is not None: + rmetric["min"] = e_min if rmetric["min"] is None else min(rmetric["min"], e_min) + if e_max is not None: + rmetric["max"] = e_max if rmetric["max"] is None else max(rmetric["max"], e_max) + + # combine means & M2 + mean_a = rmetric.get("mean") + mean_b = vals.get("mean") + + # If either mean is missing, use the one that exists + if mean_a is None and mean_b is None: + # Nothing to do + continue + elif mean_a is None: + rmetric["mean"] = mean_b + rmetric["M2"] = 0.0 + rmetric["count"] = n_new + elif mean_b is None: + # keep existing stats + rmetric["mean"] = mean_a + rmetric["M2"] = rmetric.get("M2", 0.0) + rmetric["count"] = n_old + else: + # both defined → do weighted merge + delta = mean_b - mean_a + new_count = n_old + n_new + new_mean = mean_a + delta * (n_new / new_count) + new_M2 = rmetric.get("M2", 0.0) + 0.0 + (delta**2) * (n_old * n_new / new_count) + + rmetric["mean"] = new_mean + rmetric["M2"] = new_M2 + rmetric["count"] = new_count + + # update std from M2 + c = rmetric["count"] + rmetric["std"] = math.sqrt(rmetric["M2"] / c) if c > 1 else 0.0 + + running[name]["count"] = n_old_name + n_new_total + + # round mean and std for readability + for name, metrics in running.items(): + if name == "count": + continue + for metric, vals in metrics.items(): + if not isinstance(vals, dict): + continue + if "mean" in vals: + vals["mean"] = r3(vals["mean"]) + if "std" in vals: + vals["std"] = r3(vals["std"]) + if "min" in vals: + vals["min"] = r3(vals["min"]) + if "max" in vals: + vals["max"] = r3(vals["max"]) + + return running def print_statistics(resource_object): """ @@ -773,7 +876,119 @@ def print_statistics(resource_object): print ("Mean-CPU (cores): ", mean_cpu) print ("Max-CPU (cores): ", max_cpu) print ("CPU-efficiency: ", mean_cpu / meta["cpu_limit"]) - print ("---> ") + + #(c) Top N memory consumers by name + top_n = 5 + top_mem = ( + dframe.groupby('name')['pss'] + .max() # peak PSS for each component + .sort_values(ascending=False) # sort by memory usage + .head(top_n) + ) + print(f"\nTop-{top_n} memory consumers (by peak PSS):") + for comp, mem in top_mem.items(): + print(f" {comp:<20s} {mem:10.2f} MB") + + #(d) max disc consumption + if 'disc' in dframe: + print ("\nMax-DISC usage (MB): ", dframe['disc'].max()) + print ("Mean-DISC usage (MB): ", dframe['disc'].mean()) + print ("---> ") + +def r3(x): + """Round to 3 decimals, return None for None/NaN.""" + if x is None: + return None + try: + xf = float(x) + except Exception: + return None + if math.isnan(xf): + return None + return round(xf, 3) + +def produce_json_stat(resource_object): + print ("<--- Producing resource json from file ", resource_object.pipeline_file) + dframe = resource_object.df + meta = resource_object.meta + + # also write json summary; This is a file that can be used + # to adjust the resource estimates in o2dpg_workflow_runner.py + # + resource_json = {} + # group by 'name' and compute all needed stats for each metric + stats = ( + dframe + .groupby('name') + .agg({ + 'pss': ['min', 'max', 'mean'], + 'uss': ['min', 'max', 'mean'], + 'cpu': ['min', 'max', 'mean'] + }) + ) + + # turn the multi-level columns into flat names + stats.columns = [f"{col[0]}_{col[1]}" for col in stats.columns] + stats = stats.reset_index() + + # ----- compute lifetime ~ walltime per (timeframe, name) ----- + # ------------------------------------------------ + # Filter out unrealistic timeframes (nice == 19) because it's not the realistic runtime + df_nice_filtered = dframe[dframe['nice'] != 19].copy() + + # the calculates of mean runtime should be averaged over timeframes + lifetime_per_tf = ( + df_nice_filtered + .groupby(['timeframe', 'name'])['iter'] + .agg(lambda x: x.max() - x.min() + 1) # +1 to include both ends + .reset_index(name='lifetime') + ) + + # now average over timeframes for each name + mean_lifetime = ( + lifetime_per_tf + .groupby('name')['lifetime'] + .mean() + ) + max_lifetime = ( + lifetime_per_tf + .groupby('name')['lifetime'] + .max() + ) + min_lifetime = ( + lifetime_per_tf + .groupby('name')['lifetime'] + .max() + ) + + resource_json["count"] = 1 # basic sample size + + # convert to nested dictionary + for _, row in stats.iterrows(): + name = row['name'] + resource_json[name] = { + 'pss': { + 'min': r3(row['pss_min']), + 'max': r3(row['pss_max']), + 'mean': r3(row['pss_mean']) + }, + 'uss': { + 'min': r3(row['uss_min']), + 'max': r3(row['uss_max']), + 'mean': r3(row['uss_mean']) + }, + 'cpu': { + 'min': r3(row['cpu_min']), + 'max': r3(row['cpu_max']), + 'mean': r3(row['cpu_mean']) + }, + 'lifetime': { + 'min' : r3(float(min_lifetime.get(name, np.nan))), + 'max' : r3(float(max_lifetime.get(name, np.nan))), + 'mean' : r3(float(mean_lifetime.get(name, np.nan))) + } + } + return resource_json def stat(args): """ @@ -785,6 +1000,54 @@ def stat(args): print_statistics(res) +def merge_stats_into(list_of_json_stats, outputfile, metadata): + running = {} + # read all the inputs + for inp_json in list_of_json_stats: + # we may have to strip the meta-data section first of all + running = merge_stats(inp_json, running) + + # attach meta-data + running["meta-data"] = metadata + + # now write out the result into the output file + if running and outputfile != None: + with open(outputfile, 'w') as f: + json.dump(running, f) + + return running + + +def build_meta_header(arg): + meta = {} + if type(arg) == str: + if arg != "": + meta = json.loads(arg) + elif type(arg) == dict: + meta = deepcopy(arg) + else: + print ("Unsupported Meta input type") + return meta + +def json_stat_impl(pipelines, output, header_data): + resources = extract_resources(pipelines) + all_stats = [produce_json_stat(res) for res in resources] + + merge_stats_into(all_stats, output, build_meta_header(header_data)) + + +def json_stat(args): + json_stat_impl(args.pipelines, args.output, args.header_data) + +def merge_json_stats(args): + all_stats = [] + for inp in args.inputs: + # load the json as a dict + with open(inp,'r') as f: + all_stats.append(json.load(f)) + + merge_stats_into(all_stats, args.output, build_meta_header(args.header_data)) + def history(args): """ Entrypoint for history @@ -1032,7 +1295,19 @@ def main(): stat_parser.set_defaults(func=stat) stat_parser.add_argument("-p", "--pipelines", nargs="*", help="pipeline_metric files from o2_dpg_workflow_runner", required=True) - plot_parser = sub_parsers.add_parser("history", help="Plot (multiple) metrcis from extracted metrics JSON file(s)") + json_stat_parser = sub_parsers.add_parser("json-stat", help="Produce basic json stat (compatible with o2dog_workflow_runner injection)") + json_stat_parser.set_defaults(func=json_stat) + json_stat_parser.add_argument("-p", "--pipelines", nargs="*", help="Pipeline_metric files from o2_dpg_workflow_runner; Merges information", required=True) + json_stat_parser.add_argument("-o", "--output", type=str, help="Output json filename", required=True) + json_stat_parser.add_argument("-hd", "--header-data", type=str, default='', help="Some meta-data headers to be included in the JSON") + + merge_stat_parser = sub_parsers.add_parser("merge-json-stats", help="Merge information from json-stats into an aggregated stat") + merge_stat_parser.set_defaults(func=merge_json_stats) + merge_stat_parser.add_argument("-i", "--inputs", nargs="*", help="List of incoming/input json stat files", required=True) + merge_stat_parser.add_argument("-o", "--output", type=str, help="Output json filename", required=True) + merge_stat_parser.add_argument("-hd", "--header-data", type=str, default="", help="Some meta-data headers to be included in the JSON") + + plot_parser = sub_parsers.add_parser("history", help="Plot (multiple) metrics from extracted metrics JSON file(s)") plot_parser.set_defaults(func=history) plot_parser.add_argument("-p", "--pipelines", nargs="*", help="pipeline_metric files from o2_dpg_workflow_runner", required=True) plot_parser.add_argument("--output", help="output directory", default="resource_history") diff --git a/UTILS/FileIOGraph/analyse_FileIO.py b/UTILS/FileIOGraph/analyse_FileIO.py index 5ad4523f9..f2e35c736 100755 --- a/UTILS/FileIOGraph/analyse_FileIO.py +++ b/UTILS/FileIOGraph/analyse_FileIO.py @@ -22,7 +22,7 @@ # the run-number of data taking or default if unanchored parser.add_argument('--actionFile', type=str, help="O2DPG pipeline runner action file") parser.add_argument('--monitorFile', type=str, help="monitoring file provided by fanotify tool. See O2DPG/UTILS/FileIOGraph.") -parser.add_argument('--basedir', type=str, help="O2DPG workflow dir") +parser.add_argument('--basedir', default="/", type=str, help="O2DPG workflow dir") parser.add_argument('--file-filters', nargs='+', default=[r'.*'], help="Filters (regular expressions) to select files (default all = '.*')") parser.add_argument('--graphviz', type=str, help="Produce a graphviz plot") parser.add_argument('-o','--output', type=str, help="Output JSON report") @@ -60,7 +60,8 @@ file_written_task = {} file_consumed_task = {} -pattern = re.compile(args.basedir + r'([^,]+),((?:read|write)),(.*)') +pattern = re.compile(r'"?([^"]+)"?,((?:read|write)),(.*)') +basedir_pattern = re.compile("^" + args.basedir) # neglecting some framework file names file_exclude_filter = re.compile(r'(.*)\.log(.*)|(ccdb/log)|(.*)dpl-config\.json') @@ -76,6 +77,13 @@ mode = match.group(2) pids = match.group(3).split(";") + # see if matches the workdir + if not basedir_pattern.match(file_name): + continue + + # remove basedir from file_name + file_name = file_name.replace(args.basedir + '/', "./", 1) + # implement file name filter if file_exclude_filter.match(file_name): continue diff --git a/UTILS/FileIOGraph/monitor_fileaccess.cpp b/UTILS/FileIOGraph/monitor_fileaccess.cpp index 50567e593..9c7519c6b 100644 --- a/UTILS/FileIOGraph/monitor_fileaccess.cpp +++ b/UTILS/FileIOGraph/monitor_fileaccess.cpp @@ -64,7 +64,7 @@ std::string getcmd(pid_t pid) fclose(file); for (int byte = 0; byte < bytesRead; ++byte) { if (buffer[byte] == '\0') { - buffer[byte] == '@'; + buffer[byte] = '@'; } } return std::string(buffer); @@ -98,7 +98,7 @@ int main(int argc, char** argv) { int fan; char buf[4096]; - char fdpath[32]; + char fdpath[64]; char path[PATH_MAX + 1]; ssize_t buflen, linklen; struct fanotify_event_metadata* metadata; @@ -114,11 +114,11 @@ int main(int argc, char** argv) auto MAX_MOTHER_PID_ENV = getenv("MAXMOTHERPID"); int max_mother_pid = 1; // everything if (MAX_MOTHER_PID_ENV != nullptr) { - std::cerr << "found env variablen"; + std::cerr << "found env variable MAX_MOTHER_PID_ENV"; max_mother_pid = std::atoi(MAX_MOTHER_PID_ENV); std::cerr << "Setting topmost mother process to " << max_mother_pid << "\n"; } else { - std::cerr << "No environment given\n"; + std::cerr << "No environment given. Monitoring globally.\n"; } auto thispid = getpid(); @@ -174,10 +174,10 @@ int main(int argc, char** argv) } if (metadata->mask & FAN_CLOSE_WRITE) { - printf("%s,write,%s\n", path, parentspid->c_str()); + printf("\"%s\",write,%s\n", path, parentspid->c_str()); } if (metadata->mask & FAN_CLOSE_NOWRITE) { - printf("%s,read,%s\n", path, parentspid->c_str()); + printf("\"%s\",read,%s\n", path, parentspid->c_str()); } } diff --git a/UTILS/FileIOGraph/monitor_fileaccess_v2.cpp b/UTILS/FileIOGraph/monitor_fileaccess_v2.cpp new file mode 100644 index 000000000..2f3750bc6 --- /dev/null +++ b/UTILS/FileIOGraph/monitor_fileaccess_v2.cpp @@ -0,0 +1,219 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define CHK(expr, errcode) \ + if ((expr) == errcode) \ + { \ + perror(#expr); \ + exit(EXIT_FAILURE); \ + } + +#define MAXBUF (BUFSIZ * 2) + +int getppid_safe(int pid) +{ + int ppid = 0; + char buf[MAXBUF]; + char procname[64]; // big enough for /proc//status + FILE *fp; + + snprintf(procname, sizeof(procname), "/proc/%d/status", pid); + fp = fopen(procname, "r"); + if (fp != NULL) + { + size_t ret = fread(buf, sizeof(char), MAXBUF - 1, fp); + if (ret > 0) + buf[ret] = '\0'; + fclose(fp); + } + char *ppid_loc = strstr(buf, "\nPPid:"); + if (ppid_loc) + { + if (sscanf(ppid_loc, "\nPPid:%d", &ppid) != 1) + return 0; + return ppid; + } + return 0; +} + +std::string getcmd(pid_t pid) +{ + if (pid == 0 || pid == 1) + return std::string(""); + + char path[64]; + snprintf(path, sizeof(path), "/proc/%d/cmdline", pid); + + FILE *file = fopen(path, "r"); + if (file) + { + char buffer[1024]; // max 1k command line + size_t bytesRead = fread(buffer, 1, sizeof(buffer), file); + fclose(file); + for (size_t i = 0; i < bytesRead; ++i) + { + if (buffer[i] == '\0') + buffer[i] = '@'; + } + return std::string(buffer, bytesRead); + } + return std::string(""); +} + +std::unordered_map good_pid_cache; +std::unordered_map pid_to_parents; +std::unordered_map pid_to_command; + +bool is_good_pid(int pid, int maxparent) +{ + auto iter = good_pid_cache.find(pid); + if (iter != good_pid_cache.end()) + return iter->second; + + if (pid == maxparent) + return good_pid_cache[pid] = true; + if (pid == 0) + return good_pid_cache[pid] = false; + + return good_pid_cache[pid] = is_good_pid(getppid_safe(pid), maxparent); +} + +std::string build_parent_chain(int pid, int maxparent) +{ + auto iter = pid_to_parents.find(pid); + if (iter != pid_to_parents.end()) + return iter->second; + + std::stringstream str; + int current = pid; + str << current; + while (current != maxparent && current != 0) + { + if (pid_to_command.find(current) == pid_to_command.end()) + { + std::string cmd = getcmd(current); + pid_to_command[current] = cmd; + fprintf(stdout, "pid-to-command:%i:%s\n", current, cmd.c_str()); + } + int next = getppid_safe(current); + current = next; + str << ";" << current; + } + pid_to_parents[pid] = str.str(); + return str.str(); +} + +int main(int argc, char **argv) +{ + int fan; + char buf[8192]; + char fdpath[64]; + char path[PATH_MAX + 1]; + ssize_t buflen, linklen; + struct fanotify_event_metadata *metadata; + + // init fanotify + + // with this we can observe specific root directories + auto ROOT_PATH_ENV = getenv("FILEACCESS_MON_ROOTPATH"); + std::string root_path = "/"; + if (ROOT_PATH_ENV) { + root_path = std::string(ROOT_PATH_ENV); + std::cerr << "Observing file access below " << root_path << "\n"; + } + + CHK(fan = fanotify_init(FAN_CLASS_NOTIF, O_RDONLY), -1); + CHK(fanotify_mark(fan, FAN_MARK_ADD | FAN_MARK_MOUNT, + FAN_CLOSE_WRITE | FAN_CLOSE_NOWRITE | FAN_EVENT_ON_CHILD, + AT_FDCWD, root_path.c_str()), + -1); + + // read env for filtering + auto MAX_MOTHER_PID_ENV = getenv("MAXMOTHERPID"); + int max_mother_pid = 1; // default: allow everything + if (MAX_MOTHER_PID_ENV != nullptr) + { + max_mother_pid = std::atoi(MAX_MOTHER_PID_ENV); + std::cerr << "Setting topmost mother process to " << max_mother_pid << "\n"; + } + else + { + std::cerr << "No MAXMOTHERPID environment given\n"; + } + + auto thispid = getpid(); + + struct pollfd fds[1]; + fds[0].fd = fan; + fds[0].events = POLLIN; + + for (;;) + { + int pollres = poll(fds, 1, -1); // wait indefinitely + if (pollres == -1) + { + perror("poll"); + continue; + } + + if (fds[0].revents & POLLIN) + { + buflen = read(fan, buf, sizeof(buf)); + if (buflen == -1) + { + perror("read"); + continue; + } + metadata = (struct fanotify_event_metadata *)&buf; + while (FAN_EVENT_OK(metadata, buflen)) + { + if (metadata->mask & FAN_Q_OVERFLOW) + { + fprintf(stderr, "Queue overflow!\n"); + continue; + } + snprintf(fdpath, sizeof(fdpath), "/proc/self/fd/%d", metadata->fd); + linklen = readlink(fdpath, path, sizeof(path) - 1); + if (linklen >= 0) + { + path[linklen] = '\0'; + int pid = metadata->pid; + + bool record = true; + record = record && pid != thispid; + record = record && (metadata->mask & (FAN_CLOSE_WRITE | FAN_CLOSE_NOWRITE)); + record = record && is_good_pid(pid, max_mother_pid); + + if (record) + { + std::string parent_chain = build_parent_chain(pid, max_mother_pid); + + if (metadata->mask & FAN_CLOSE_WRITE) + { + printf("\"%s\",write,%s\n", path, parent_chain.c_str()); + fflush(stdout); + } + if (metadata->mask & FAN_CLOSE_NOWRITE) + { + printf("\"%s\",read,%s\n", path, parent_chain.c_str()); + fflush(stdout); + } + } + } + close(metadata->fd); + metadata = FAN_EVENT_NEXT(metadata, buflen); + } + } + } +} diff --git a/UTILS/Parsers/READMEtreeFastCache.md b/UTILS/Parsers/READMEtreeFastCache.md new file mode 100644 index 000000000..19296ef11 --- /dev/null +++ b/UTILS/Parsers/READMEtreeFastCache.md @@ -0,0 +1,126 @@ +# 📦 ROOT Tree Fast Cache System + +This repository contains ROOT macros for fast lookup and interpolation of values from TTrees, using: + +- `treeFastCache1D.C`: 1D cache with nearest-neighbor lookup +- `treeFastCacheND.C`: ND cache with exact match in N–1 dimensions and nearest-neighbor in 1 dimension + +They are designed for interactive analysis with `TTree::Draw`, e.g., QA plots, calibration overlays, or smoothed time series. + +--- + +## 🔹 `treeFastCache1D.C` + +### ✅ Features + +- Register 1D lookup maps from TTrees +- Nearest-neighbor lookup from `std::map` +- Can register by ID or string name +- Fast evaluation inside `TTree::Draw` +- Alias integration for interactive sessions + +### 🧪 Example + +```cpp +TTree* tree = ...; +int mapID = registerMap1DByName("dcar_vs_time", "time", "dcar_value", tree, "subentry==127"); + +tree->SetAlias("dcar_smooth", ("getNearest1D(time," + std::to_string(mapID) + ")").c_str()); +tree->Draw("dcar_value:dcar_smooth", "indexType==1", "colz", 10000); +``` + +--- + +## 🔸 `treeFastCacheND.C` + +### ✅ Features + +- ND caching with: + - **Exact match** in N–1 dimensions + - **Nearest-neighbor** lookup in 1 dimension (e.g. `time`) +- Uses full `double` precision for all keys +- Alias support for `TTree::Draw` +- Registration by name with hashed map ID +- Variadic interface for direct use + +### 🧪 Example: Time Series + +```cpp +TTree* tree = ...; +int mapID = registerMapND("dcar_vs_time", tree, {"subentry"}, "time", "mTSITSTPC.mDCAr_A_NTracks_median", "1"); +setNearestNDAlias(tree, "dcar_smooth", "dcar_vs_time", "time", {"subentry"}); + +tree->Draw("mTSITSTPC.mDCAr_A_NTracks_median:dcar_smooth", "indexType==1", "colz", 10000); +``` + +### 🖊️ Parameters for `registerMapND` +```cpp +int registerMapND( + const std::string& name, // Unique name of the map + TTree* tree, // Source TTree + const std::vector& exactDims, // Exact-match coordinate names + const std::string& nearestDim, // Nearest-match dimension (e.g. time) + const std::string& valueVar, // Variable to interpolate + const std::string& selection // TTree selection +); +``` + +### 🖊️ Parameters for `setNearestNDAlias` +```cpp +void setNearestNDAlias( + TTree* tree, // Target tree + const std::string& aliasName, // Alias to create + const std::string& mapName, // Name used in registration + const std::string& nearestCoordExpr, // Nearest-match expression + const std::vector& exactCoordExprs // Exact match expressions +); +``` + +### ⚡️ Alternative: Direct expression +```cpp +tree->Draw("val:getNearestND(time,mapID,subentry)", ...); +``` + +--- + +## 📊 Internal Storage + +### 1D: +```cpp +std::map> registeredMaps; +std::map nameToMapID; +``` + +### ND: +```cpp +std::map, std::map>> ndCaches; +std::map ndNameToID; +``` + +--- + +## 📌 Best Practices + +- Use aliases to simplify `TTree::Draw` expressions +- Use double precision for stability in nearest search +- Store maps by string name to simplify re-registration +- Prefer `setNearestNDAlias()` over manual `getNearestND(...)` for readability + +--- + +## 📤 Future Ideas + +- Optional interpolation (linear, spline) +- Graceful handling of unmatched keys +- Caching diagnostics and summary statistics +- C++ class wrapper for lifecycle + reusability + +--- + +## 📜 License + +Intended for use in internal physics analyses. No warranty implied. + +--- + +For more details, see comments and examples inside `treeFastCache1D.C` and `treeFastCacheND.C`. diff --git a/UTILS/Parsers/treeFastCache.C b/UTILS/Parsers/treeFastCache.C new file mode 100644 index 000000000..624a9f02f --- /dev/null +++ b/UTILS/Parsers/treeFastCache.C @@ -0,0 +1,258 @@ +/* +.L $O2DPG/UTILS/Parsers/treeFastCache.C +*/ + +/* + treeFastCache.C + Simple caching system for fast lookup of 1D values from a TTree, using nearest-neighbor interpolation. + This utility allows registration of (X, Y) pairs from a TTree into a std::map, + indexed by a user-defined mapID or map name. The lookup function `getNearest1D(x, mapID)` + retrieves the Y value for the X closest to the query. + Features: + - Register maps via string name or numeric ID + - Query nearest-neighbor value for any X + - Graceful error handling and range checking + - Base for future ND extension +*/ + +#include +#include +#include +#include +#include +#include +#include + +using namespace std; + +// Map: mapID -> map +std::map> registeredMaps; +std::map nameToMapID; + +/// Hash a string to create a deterministic mapID +int hashMapName(const std::string& name) { + std::hash hasher; + return static_cast(hasher(name)); +} + +/// Register a 1D lookup map from TTree (X -> Y) +/// @param valX Name of the X-axis variable (lookup key) +/// @param valY Name of the Y-axis variable (value to retrieve) +/// @param tree Pointer to TTree to extract data from +/// @param selection Selection string (TTree::Draw-compatible) +/// @param mapID Integer ID to associate with this map +void registerMap1D(const std::string& valX, const std::string& valY, TTree* tree, const std::string& selection, int mapID) { + if (!tree) { + std::cerr << "[registerMap1D] Null TTree pointer." << std::endl; + return; + } + + int entries = tree->Draw((valY + ":" + valX).c_str(), selection.c_str(), "goff"); + if (entries <= 0) { + std::cerr << "[registerMap1D] No entries matched for mapID=" << mapID << std::endl; + return; + } + + if (!tree->GetV1() || !tree->GetV2()) { + std::cerr << "[registerMap1D] Internal Draw buffer pointers are null." << std::endl; + return; + } + + std::map newMap; + for (int i = 0; i < entries; ++i) { + if (i >= tree->GetSelectedRows()) { + std::cerr << "[registerMap1D] Index out of range at i=" << i << std::endl; + break; + } + double x = tree->GetV2()[i]; // valX + float y = tree->GetV1()[i]; // valY + newMap[x] = y; + } + + registeredMaps[mapID] = std::move(newMap); + std::cout << "[registerMap1D] Registered map " << mapID << " with " << entries << " entries." << std::endl; +} + +/// Register by name; returns mapID computed from name +int registerMap1DByName(const std::string& mapName, const std::string& valX, const std::string& valY, TTree* tree, const std::string& selection) { + int mapID = hashMapName(mapName); + nameToMapID[mapName] = mapID; + registerMap1D(valX, valY, tree, selection, mapID); + return mapID; +} + +/// Get the nearest Y for a given X from the map registered with mapID +/// @param x Query value along X axis +/// @param mapID Map identifier used in registration +/// @return Y value corresponding to nearest X in the map +float getNearest1D(float x, int mapID) { + const auto itMap = registeredMaps.find(mapID); + if (itMap == registeredMaps.end()) { + std::cerr << "[getNearest1D] Map ID " << mapID << " not found." << std::endl; + return NAN; + } + + const auto& map = itMap->second; + if (map.empty()) { + std::cerr << "[getNearest1D] Map ID " << mapID << " is empty." << std::endl; + return NAN; + } + + auto it = map.lower_bound(x); + if (it == map.begin()) return it->second; + if (it == map.end()) return std::prev(it)->second; + + auto prev = std::prev(it); + return (std::abs(prev->first - x) < std::abs(it->first - x)) ? prev->second : it->second; +} + +/// Convenience version: lookup by name +float getNearest1DByName(float x, const std::string& mapName) { + auto it = nameToMapID.find(mapName); + if (it == nameToMapID.end()) { + std::cerr << "[getNearest1DByName] Map name \"" << mapName << "\" not found." << std::endl; + return NAN; + } + return getNearest1D(x, it->second); +} + +/// Example usage +void example1D() { + TFile *f = TFile::Open("timeSeries10000_apass5.root"); + TTree * tree0=(TTree*)f->Get("timeSeries"); + // Fill tree here or load from file + int mapID = registerMap1DByName("dcar_vs_time", "time", "mTSITSTPC.mDCAr_A_NTracks_median", tree0, "subentry==127"); + tree0->SetAlias("mDCAr_A_NTracks_median_All" ,("getNearest1D(time, " + std::to_string(mapID) + ")").data()); + tree0->Draw("mTSITSTPC.mDCAr_A_NTracks_median:mDCAr_A_NTracks_median_All","indexType==1","",10000); +} +/* ------------------------------------------------------------------ + Statistics extension (non‑breaking) ------------------------------- + Added without changing previous API. + + New options: + • Enum‑based interface for better ROOT compatibility + enum StatKind { kMean=0, kMedian=1, kStd=2 }; + float getStat(double x,int mapID,StatKind kind,double dx); + + • Convenience thin wrappers for ROOT aliases + getMean1D , getMedian1D , getStd1D + + • cacheStat unchanged (uses strings internally) + + ------------------------------------------------------------------*/ + +#include +#include +#include + +// --- enum for faster numeric calls -------------------------------- +enum StatKind { kMean=0, kMedian=1, kStd=2 }; + +// Cache: stat → mapID → dx → (x → value) +static std::map>> cacheMean; +static std::map>> cacheMedian; +static std::map>> cacheStd; + +static float _mean(const std::vector& v){ return v.empty()?NAN:std::accumulate(v.begin(),v.end(),0.0f)/v.size(); } +static float _median(std::vector v){ if(v.empty()) return NAN; size_t n=v.size()/2; std::nth_element(v.begin(),v.begin()+n,v.end()); return v[n]; } +static float _std(const std::vector& v){ if(v.size()<2) return NAN; float m=_mean(v); double s2=0; for(float e:v){ double d=e-m; s2+=d*d;} return std::sqrt(s2/(v.size()-1)); } + +//-------------------------------------------------------------------- +static float _computeStat(double x,int mapID,double dx,StatKind k){ + const auto itM=registeredMaps.find(mapID); + if(itM==registeredMaps.end()||itM->second.empty()) return NAN; + const auto &mp=itM->second; + std::vector buf; + for(auto it=mp.lower_bound(x-dx); it!=mp.end()&&it->first<=x+dx; ++it) buf.push_back(it->second); + if(buf.empty()) return NAN; + switch(k){ + case kMean: return _mean(buf); + case kMedian: return _median(buf); + case kStd: return _std(buf); + } + return NAN; +} + +//-------------------------------------------------------------------- +/** + * @brief Return a local statistic (mean / median / std) around a query point. + * + * This version is preferred inside **TTree::Draw** because it uses an enum + * instead of a string literal. + * + * @param x Center of the window (same coordinate used in the cache) + * @param mapID ID returned by registerMap1D / registerMap1DByName + * @param kind kMean (0), kMedian (1) or kStd (2) + * @param dx Half‑window size: the statistic is computed from all points + * with X in [x − dx, x + dx] + * + * Internally the first request builds (and caches) a map x → stat(x) + * for the given (mapID, dx, kind). Subsequent calls are O(log N). + */ +// Fast numeric interface (enum) ------------------------------------ +float getStat(double x,int mapID,StatKind kind,double dx){ + auto *pcache = (kind==kMean? &cacheMean : (kind==kMedian? &cacheMedian : &cacheStd)); + auto &byMap = (*pcache)[mapID]; + auto &byDx = byMap[dx]; + if(byDx.empty()){ + // build lazily for this dx + const auto itM=registeredMaps.find(mapID); + if(itM==registeredMaps.end()) return NAN; + for(const auto &kv: itM->second){ double cx=kv.first; byDx[cx]=_computeStat(cx,mapID,dx,kind);} } + const auto &statMap = byDx; + auto it=statMap.lower_bound(x); + if(it==statMap.begin()) return it->second; + if(it==statMap.end()) return std::prev(it)->second; + auto prev=std::prev(it); + return (fabs(prev->first-x)first-x)?prev->second:it->second); +} + +// String interface kept for backward compat. +float getStat(double x,int mapID,const char* st,double dx){ + std::string s(st); + if(s=="mean") return getStat(x,mapID,kMean ,dx); + if(s=="median") return getStat(x,mapID,kMedian,dx); + if(s=="std"||s=="sigma") return getStat(x,mapID,kStd,dx); + std::cerr<<"[getStat] Unknown statType="<(kind),dx); +} + +//-------------------------------------------------------------------- +// Pre‑cache requested stats (by enum) ------------------------------- (by enum) ------------------------------- +bool cacheStat(int mapID,const std::vector& stats,double dx){ + for(const std::string &s:stats){ + if(s=="mean") getStat(0,mapID,kMean ,dx); // lazy build + else if(s=="median") getStat(0,mapID,kMedian,dx); + else if(s=="std"||s=="sigma") getStat(0,mapID,kStd,dx); + } + return true; +} + +//-------------------------------------------------------------------- +/// Example: statistics with enum wrappers +void exampleStat1D(){ + TFile *f=TFile::Open("timeSeries10000_apass5.root"); + TTree *t=(TTree*)f->Get("timeSeries"); + int id = registerMap1DByName("dcar_time_stat","time","mTSITSTPC.mDCAr_A_NTracks_median",t,"subentry==127"); + + // Pre‑cache mean & std for ±200 window + cacheStat(id,{"mean","std"},200); + + // Use integer selector (0 = mean, 2 = std). This avoids any ROOT + // overload ambiguity and works in TTree::Draw directly. + t->SetAlias("dcar_mean", Form("getStat(time,%d,0,200)", id)); // 0 → kMean + t->SetAlias("dcar_sigma", Form("getStat(time,%d,2,200)", id)); // 2 → kStd + + t->Draw("mTSITSTPC.mDCAr_A_NTracks_median:dcar_mean","indexType==1","colz",10000); + t->Draw("getStat(time,591487517, 0 ,10000+0):getStat(time,591487517, 1 ,10000+0)","indexType==1","colz",100000); +} \ No newline at end of file diff --git a/UTILS/Parsers/treeFastCacheND.C b/UTILS/Parsers/treeFastCacheND.C new file mode 100644 index 000000000..541022746 --- /dev/null +++ b/UTILS/Parsers/treeFastCacheND.C @@ -0,0 +1,221 @@ +/* +.L $O2DPG/UTILS/Parsers/treeFastCacheND.C +*/ +/* + treeFastCacheND.C + + Multi-dimensional cache system for ROOT TTree lookup with mixed matching modes: + - Exact match in N-1 dimensions + - Nearest-neighbor in one dimension (typically time) + + This system complements treeFastCache1D by enabling efficient access to structured ND data. + + Features: + - Caches values based on N-dimensional keys using a combination of exact and nearest lookups + - Provides ROOT-friendly interface usable within TTree::Draw + - Uses full double precision for both exact and nearest match coordinates + - Works interactively with aliases and supports variadic access + + Author: ChatGPT for Marian +*/ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +using namespace std; + +/// Generic ND key support +typedef std::map NearestMap; ///< 1D interpolation map (e.g., time → value) +typedef std::vector ExactKey; ///< Exact match dimensions (e.g., subentry, CRU, etc.) + +/// Container of ND maps: outer map = mapID → {ExactKey → NearestMap} +std::map> ndCaches; +std::map ndNameToID; ///< Map from user-defined name to hash-based mapID + +/// Deterministically hash a name to a map ID +int hashMapNameND(const std::string& name) { + std::hash hasher; + return static_cast(hasher(name)); +} + +/// Register an ND lookup map from a TTree +/** + * @param name Unique name to identify the map + * @param tree Source TTree + * @param exactDims List of column names for exact-match dimensions + * @param nearestDim Name of nearest-search dimension (e.g., "time") + * @param valueVar Name of value column + * @param selection TTree::Draw-compatible selection expression + * @return mapID (generated from name) + */ +int registerMapND(const std::string& name, + TTree* tree, + const std::vector& exactDims, + const std::string& nearestDim, + const std::string& valueVar, + const std::string& selection) { + if (!tree) throw std::invalid_argument("[registerMapND] Null TTree."); + int mapID = hashMapNameND(name); + ndNameToID[name] = mapID; + + std::string expr = valueVar + ":" + nearestDim; + for (const auto& dim : exactDims) expr += ":" + dim; + int entries = tree->Draw(expr.c_str(), selection.c_str(), "goff"); + if (entries>=tree->GetEstimate()){ + tree->SetEstimate(entries*2); + entries = tree->Draw(expr.c_str(), selection.c_str(), "goff"); + } + if (entries <= 0) { + std::cerr << "[registerMapND] No entries selected." << std::endl; + return mapID; + } + + int dimCount = 2 + exactDims.size(); + std::vector buffers(dimCount); + for (int i = 0; i < dimCount; ++i) { + buffers[i] = tree->GetVal(i); + if (!buffers[i]) throw std::runtime_error("[registerMapND] Missing Draw buffer at " + std::to_string(i)); + } + + std::map newMap; + for (int i = 0; i < entries; ++i) { + double val = buffers[0][i]; + double near = buffers[1][i]; + ExactKey key; + for (size_t j = 0; j < exactDims.size(); ++j) key.push_back(buffers[2 + j][i]); + newMap[key][near] = val; + } + ndCaches[mapID] = std::move(newMap); + std::cout << "[registerMapND] Registered ND map '" << name << "' with ID=" << mapID << " and " << entries << " entries." << std::endl; + return mapID; +} + +/// Query map using exact + nearest key +/** + * @param query Value for nearest-match dimension + * @param mapID ID of registered map + * @param exactKey Vector of exact-match dimensions (must match registration) + * @return Interpolated value or NaN if no match + */ +double getNearestND(double query, int mapID, const ExactKey& exactKey) { + const auto& map = ndCaches[mapID]; + auto itOuter = map.find(exactKey); + if (itOuter == map.end()) return NAN; + + const auto& innerMap = itOuter->second; + if (innerMap.empty()) return NAN; + + auto it = innerMap.lower_bound(query); + if (it == innerMap.begin()) return it->second; + if (it == innerMap.end()) return std::prev(it)->second; + + auto prev = std::prev(it); + return (std::abs(prev->first - query) < std::abs(it->first - query)) ? prev->second : it->second; +} + +/// Variadic interface to getNearestND for use with TTree::Draw +/** + * @tparam Dims Arbitrary number of scalar dimensions (int or float/double) + * @param query Nearest dimension (e.g., time) + * @param mapID Map ID registered via registerMapND + * @param dims... Dimensions to match exactly + */ +template +double getNearestND(double query, int mapID, Dims... dims) { + ExactKey exactKey{static_cast(dims)...}; + return getNearestND(query, mapID, exactKey); +} + +/// Lookup using map name +/** + * @param query Nearest-dimension value (e.g., time) + * @param exactKey Exact-dimension vector + * @param mapName Map name from registration + */ +double getNearestNDByName(double query, const ExactKey& exactKey, const std::string& mapName) { + auto itID = ndNameToID.find(mapName); + if (itID == ndNameToID.end()) return NAN; + return getNearestND(query, itID->second, exactKey); +} + +/// Register alias in tree for use in interactive Draw +/** + * @param tree TTree pointer + * @param aliasName Alias to create + * @param mapName Name of registered ND map + * @param nearestCoordExpr Expression for nearest dimension (e.g., "time") + * @param exactCoordExprs Expressions for exact dimensions (e.g., {"subentry"}) + */ +void setNearestNDAlias(TTree* tree, const std::string& aliasName, const std::string& mapName, const std::string& nearestCoordExpr, const std::vector& exactCoordExprs) { + auto it = ndNameToID.find(mapName); + if (it == ndNameToID.end()) { + std::cerr << "[setNearestNDAlias] Map not found: " << mapName << std::endl; + return; + } + int mapID = it->second; + + std::string expr = "getNearestND(" + nearestCoordExpr + "," + std::to_string(mapID); + for (const auto& ex : exactCoordExprs) expr += "," + ex; + expr += ")"; + tree->SetAlias(aliasName.c_str(), expr.c_str()); +} + +/// Example usage for ND map creation - for very High voltage queries for distertion calibration +void exampleND() { + TTree* tree = new TTree("tree", "demo"); + int mapID = registerMapND("test_map", tree, {"CRU", "iTF"}, "time", "val", "subentry==127"); + setNearestNDAlias(tree, "val_interp", "test_map", "time", {"CRU", "iTF"}); + tree->Draw("val:val_interp", "val!=0", "colz"); +} + +/// Example usage for time series ND lookup +void exampleTimeSeries() { + TFile *f = TFile::Open("timeSeries10000_apass5.root"); + TTree *tree = (TTree*)f->Get("timeSeries"); + int mapID = registerMapND("dcar_vs_time", tree, {"subentry"}, "time", "mTSITSTPC.mDCAr_A_NTracks_median", "1"); + setNearestNDAlias(tree, "mDCAr_A_NTracks_median_interp", "dcar_vs_time", "time", {"subentry"}); + tree->Draw("mTSITSTPC.mDCAr_A_NTracks_median:mDCAr_A_NTracks_median_interp", "indexType==1", "", 10000); +} + +/// Example usage for time series ND lookup +void test_exampleTimeSeries() { + TFile *f5 = TFile::Open("timeSeries10000_LHC23zzx_apass5.root"); + TTree *tree5 = (TTree*)f5->Get("timeSeries"); + TFile *f4 = TFile::Open("timeSeries10000_LHC23zz_combo_apass4.root"); + TTree *tree4 = (TTree*)f4->Get("timeSeries"); + int mapID5A = registerMapND("mDCAr_A_Median_median5", tree5, {"subentry"}, "time", "mTSITSTPC.mDCAr_A_Median_median", "1"); + int mapID5C = registerMapND("mDCAr_C_Median_median5", tree5, {"subentry"}, "time", "mTSITSTPC.mDCAr_C_Median_median", "1"); + int mapID4A = registerMapND("mDCAr_A_Median_median4", tree4, {"subentry"}, "time", "mTSITSTPC.mDCAr_A_Median_median", "1"); + int mapID4C = registerMapND("mDCAr_C_Median_median4", tree4, {"subentry"}, "time", "mTSITSTPC.mDCAr_C_Median_median", "1"); + // + setNearestNDAlias(tree5, "mDCAr_A_Median_median_interp5", "mDCAr_A_Median_median5", "time", {"subentry"}); + setNearestNDAlias(tree5, "mDCAr_C_Median_median_interp5", "mDCAr_C_Median_median5", "time", {"subentry"}); + setNearestNDAlias(tree4, "mDCAr_C_Median_median_interp5", "mDCAr_A_Median_median5", "time", {"subentry"}); + // + setNearestNDAlias(tree5, "mDCAr_A_Median_median_interp4", "mDCAr_A_Median_median4", "time", {"subentry"}); + setNearestNDAlias(tree4, "mDCAr_A_Median_median_interp4", "mDCAr_A_Median_median4", "time", {"subentry"}); + + tree5->Draw("mTSITSTPC.mDCAr_A_Median_median:mDCAr_A_Median_median_interp4", "indexType==1", "", 10000); + // make unit test -RMS should be 0 + int val5=tree5->Draw("mTSITSTPC.mDCAr_A_Median_median==mDCAr_A_Median_median_interp5", "indexType==1", ""); + float rms5=tree5->GetHistogram()->GetRMS(); + float mean5=tree5->GetHistogram()->GetMean(); + //make unit test like output rms5==0, mean5==1 + int va4l=tree4->Draw("mTSITSTPC.mDCAr_A_Median_median==mDCAr_A_Median_median_interp4", "indexType==1", ""); + float rms4=tree4->GetHistogram()->GetRMS(); + float mean4=tree4->GetHistogram()->GetMean(); + //make unit test like output rms5==0, mean5==1 + if ( std::abs(rms4) < 1e-5 && std::abs(mean4 - 1.0) < 1e-5) { + std::cout << "[UnitTest] OK - Interpolation match for apass4 is exact." << std::endl; + } else { + std::cerr << "[UnitTest] ERROR - Interpolation mismatch for apass4. RMS=" << rms4 << ", Mean=" << mean4 << std::endl; + } +} + diff --git a/UTILS/Parsers/workflowToJSON.sh b/UTILS/Parsers/workflowToJSON.sh index 1b0f530cb..1b6163a58 100644 --- a/UTILS/Parsers/workflowToJSON.sh +++ b/UTILS/Parsers/workflowToJSON.sh @@ -1,4 +1,5 @@ # Source path for the script +# source $O2DPG/UTILS/Parsers/workflowToJSON.sh # source $NOTES/JIRA/ATO-648/workflowToJSON.sh # Description: @@ -110,6 +111,73 @@ jq -Rn ' ]' "$log_file" } + +# makeDiffWorkflow alien:///alice/data/2023/LHC23zzk/544515/apass5/1140/o2_ctf_run00544515_orbit0221337280_tf0000047516_epn242/workflowconfig.log alien:///alice/data/2023/LHC23zzk/544515/apass4/1140/o2_ctf_run00544515_orbit0221337280_tf0000047516_epn242/workflowconfig.log 1 gpu +makeDiffWorkflow() { + # Make diff of workflowConfig.log JSONs. + # Usage: + # makeDiffWorkflow + # file0: path or alien:// to first workflowconfig.log + # file1: path or alien:// to second workflowconfig.log + # diffType: 0 = unified diff, 1 = side-by-side (default: 1) + # filter: string to match command, e.g. gpu (default: gpu) + # Notes: + # Creates workflow0.json and workflow1.json from parsed input. + # Uses makeParse and jq for filtering and diffing. + # Supports Alien paths via alien.py cat. + + if [[ -z "$1" || -z "$2" ]]; then + cat <<'HELP_USAGE' | helpCat0 bash +makeDiffWorkflow: Compare two O2 workflowconfig logs (local or Alien). +Usage: + makeDiffWorkflow +Parameters: + file0 – path to first workflowconfig.log or alien:// path + file1 – path to second workflowconfig.log or alien:// path + diffType – (optional) 0 = unified diff, 1 = side-by-side diff (default: 1) + filter – (optional) command string filter, e.g. "gpu", "hlt" (default: gpu) +Example: + makeDiffWorkflow alien:///path/to/file0.log ./file1.log 1 gpu + makeDiffWorkflow alien:///alice/data/2023/LHC23zzk/544515/apass5/1140/o2_ctf_run00544515_orbit0221337280_tf0000047516_epn242/workflowconfig.log alien:///alice/data/2023/LHC23zzk/544515/apass4/1140/o2_ctf_run00544515_orbit0221337280_tf0000047516_epn242/workflowconfig.log 1 gpu + +HELP_USAGE + return + fi + file0="$1" + file1="$2" + diffType="${3:-1}" + filter="${4:-o2-gpu}" + # Download from alien if needed + if [[ "$file0" == alien://* ]]; then + echo "Fetching $file0 from Alien..." + alien.py cat "$file0" > "${TMPDIR:-/tmp}/workflow0.log" + file0="${TMPDIR:-/tmp}/workflow0.log" + fi + if [[ "$file1" == alien://* ]]; then + echo "Fetching $file1 from Alien..." + alien.py cat "$file1" > "${TMPDIR:-/tmp}/workflow1.log" + file1="${TMPDIR:-/tmp}/workflow1.log" + fi + + makeParse "$file0" > workflow0.json + makeParse "$file1" > workflow1.json + + # Apply filter to both JSON files + jq ".[] | select(.command | test(\"^${filter}\"))" workflow0.json | jq --sort-keys . > workflow0.filtered.json + jq ".[] | select(.command | test(\"^${filter}\"))" workflow1.json | jq --sort-keys . > workflow1.filtered.json + + echo "Comparing workflow commands filtered by '^o2-${filter}'..." + + if [[ "$diffType" -eq 1 ]]; then + diff --side-by-side --left-column --color=always workflow0.filtered.json workflow1.filtered.json | less -R + else + diff --color=always workflow0.filtered.json workflow1.filtered.json | less -R + fi +} + + + + makeDiffExample(){ cat < #include #include +#include +#include + +bool gWarningDetected = false; // Global flag to track the warning + +void MyErrorHandler(int level, Bool_t abort, const char *location, const char *msg) { + if (strstr(msg, "repair") != nullptr) { + gWarningDetected = true; + } + DefaultErrorHandler(level, abort, location, msg); // Call ROOT’s default handler +} int checkCorruptedAO2Ds(TString infileName = "/alice/sim/2024/LHC24h2/535545/AOD/005/AO2D.root", bool fromAlien = true) { + + SetErrorHandler(MyErrorHandler); if (fromAlien) { TGrid::Connect("alien://"); @@ -21,7 +34,7 @@ int checkCorruptedAO2Ds(TString infileName = "/alice/sim/2024/LHC24h2/535545/AOD // all VLA branches in the AO2Ds.root std::map> branchesToCheck = { - {"O2mcparticle_001", std::vector{"fIndexArray_Mothers"}}, + {"O2mcparticle_001", std::vector{"fIndexArray_Mothers", "fVx", "fIndexMcCollisions"}}, {"O2ft0", std::vector{"fAmplitudeA", "fChannelA", "fAmplitudeC", "fChannelC"}}, {"O2fv0a", std::vector{"fAmplitude", "fChannel"}}, {"O2mccalolabel_001", std::vector{"fIndexArrayMcParticles", "fAmplitudeA"}}, @@ -42,6 +55,10 @@ int checkCorruptedAO2Ds(TString infileName = "/alice/sim/2024/LHC24h2/535545/AOD std::cout << "Found corrupted file! DF: " << dirKey->GetName() << " Tree:" << pair.first.data() << " Branch:" << branchName.data() << std::endl; return -1; } + if (gWarningDetected) { + std::cout << "Found file in need of repair! DF: " << dirKey->GetName() << " Tree:" << pair.first.data() << " Branch:" << branchName.data() << std::endl; + return -2; + } } } } @@ -49,4 +66,4 @@ int checkCorruptedAO2Ds(TString infileName = "/alice/sim/2024/LHC24h2/535545/AOD } return 0; -} \ No newline at end of file +} diff --git a/UTILS/delete_CCDBObject.sh b/UTILS/delete_CCDBObject.sh new file mode 100755 index 000000000..91ec03f48 --- /dev/null +++ b/UTILS/delete_CCDBObject.sh @@ -0,0 +1,9 @@ +OBJECT=${1} +# object is of the form PATH/VALIDITY/ID +# Users/s/swenzel/MCProdInfo/LHC24d1c_minus50/529663/55ceab78-485e-11f0-8e6c-c0a80209250c + +curl -X DELETE --cert /tmp/tokencert_$(id -u).pem \ + --key /tmp/tokenkey_$(id -u).pem \ + -v -k \ + "http://ccdb-test.cern.ch:8080/${OBJECT}" + diff --git a/UTILS/delete_CCDBPath_recursively.sh b/UTILS/delete_CCDBPath_recursively.sh new file mode 100755 index 000000000..c17add57a --- /dev/null +++ b/UTILS/delete_CCDBPath_recursively.sh @@ -0,0 +1,17 @@ +# Step 1 we browse the complete MCProd (or whatever) subfolder + +P=$1 + +BROWSE_RESULT=$(curl --cert /tmp/tokencert_$(id -u).pem \ + --key /tmp/tokenkey_$(id -u).pem \ + -v -k \ + "http://ccdb-test.cern.ch:8080/browse/${P}/*" | awk -F': ' ' +/^ID:/ {id=$2} +/^Path:/ {path=$2} +/^Validity:/ {split($2, a, " -"); validity=a[1]; print path "/" validity "/" id} +') + +for path in ${BROWSE_RESULT}; do + echo "Will,Would delete ${path}" + ./delete_CCDBObject.sh ${path} +done diff --git a/UTILS/findCorruptedAO2Ds.sh b/UTILS/findCorruptedAO2Ds.sh index fd4ebfccb..af8e8ddb3 100755 --- a/UTILS/findCorruptedAO2Ds.sh +++ b/UTILS/findCorruptedAO2Ds.sh @@ -2,9 +2,10 @@ # Simple script to find corrupted AO2Ds using the checkCorruptedAO2Ds.C macro -PRODUCTION=LHC24h2 +PRODUCTION=LHC24f3c RUN=* # use * for all runs -NJOBS=90 +NJOBS=20 +PRODUCTIONCYCLE=0 OUTPUTFILE=corrupted_files_$PRODUCTION.txt if [ -e "$OUTPUTFILE" ]; then @@ -12,10 +13,10 @@ if [ -e "$OUTPUTFILE" ]; then fi # find all files in alien -if [ "$variable" == "*" ]; then - alien_find alien:///alice/sim/2024/${PRODUCTION} 5*/AOD/*/AO2D.root > files_to_check.txt +if [ "$RUN" == "*" ]; then + alien_find alien:///alice/sim/2024/${PRODUCTION}/${PRODUCTIONCYCLE}/5*/AOD/*/AO2D.root > files_to_check.txt else - alien_find alien:///alice/sim/2024/${PRODUCTION} ${RUN}/AOD/*/AO2D.root > files_to_check.txt + alien_find alien:///alice/sim/2024/${PRODUCTION}/${PRODUCTIONCYCLE}/${RUN}/AOD/*/AO2D.root > files_to_check.txt fi mapfile -t FILESTOCHECK < files_to_check.txt @@ -23,7 +24,7 @@ mapfile -t FILESTOCHECK < files_to_check.txt process_file() { IFS='/' read -a num <<< "$1" INPUT=$1 - echo '.x checkCorruptedAO2Ds.C("'${INPUT}'", true)' | root -l -b > log_${num[5]}_${num[7]} + echo '.x checkCorruptedAO2Ds.C("'${INPUT}'", true)' | root -l -b > log_${num[6]}_${num[8]} echo '.q' } export -f process_file @@ -33,12 +34,15 @@ parallel -j $NJOBS process_file ::: "${FILESTOCHECK[@]}" # create list of corrupted files touch $OUTPUTFILE ERRORSTR="Found corrupted file!" +REPAIRSTR="Found file in need of repair!" for FILE in "${FILESTOCHECK[@]}"; do IFS='/' read -a num <<< "$FILE" - if grep -q "$ERRORSTR" log_${num[5]}_${num[7]}; then - echo $FILE >> $OUTPUTFILE + if grep -q "$ERRORSTR" log_${num[6]}_${num[8]}; then + echo $FILE " is corrupted!" >> $OUTPUTFILE + elif grep -q "$REPAIRSTR" log_${num[6]}_${num[8]}; then + echo $FILE " is broken!" >> $OUTPUTFILE fi done rm files_to_check.txt -rm log* \ No newline at end of file +rm log_* diff --git a/UTILS/rawTF2raw/README.md b/UTILS/rawTF2raw/README.md new file mode 100644 index 000000000..4ed14be48 --- /dev/null +++ b/UTILS/rawTF2raw/README.md @@ -0,0 +1,40 @@ + The script `generate_rawtf_indices.sh` provides functions to extract a list of consecutive TFs form a list of `*rawtf*.tf` files and create the corresponding `*.raw` files, e.g. for REPLAY datasets at P2. + +Input parameters for sourcing the script: +- param1: list with input `*rawtf*.tf` files; expected file name (for extraction of period and run number): rawtflist__.txt, e.g. rawtflist_LHC25ab_563041.txt +- param2: directory to store output `*.raw` files +- param3: number of TFs to store as `*.raw` files +- param4: tfCounter id of first TF to process, e.g. at least 3500 to skip ITS ROF rate ramp up +- param5: number of input Blocks to be expected per TF to select only TFs with all inputs / detectors present + - if number of inputs is irrelevant, it can be set to 0 to be ignored + +Available functions by sourcing the script: +- `check_tfs_per_file` + - print the average number of TFs per file from a small subset of rawtf files from the input file list +- `sort_tfs` + - sort the TFs from the input file list in continuous order and save the corresponding timeslice ids in the order they appear in the input file list + - if nBlocks (parameter 5) is not 0, then there is an additional check on the number of requested inputs defined by nBlocks + - outputs: + - tf-reader_*.log: full log output from o2-raw-tf-reader-workflow which is used to grep for the timeslice and tfCounter ids + - tfids_*.txt: list with timeslice and tfCounter ids, sorted by tfCounter + - timeslices_*.txt: sorted list of \$nTFs timeslice indices to be used for raw data creation +- `create_raw_files` + - use sorted list of timeslice ids created with sort_tfs as input to create *.raw files for those timeslices + - the final command (for reference) and the full log output is written to \$outputDir.log + +Example usage: +``` +# source functions and set input / output parameters +# in this case: process 125 TFs, start at tfCounter id 3500, check `*rawtf*.tf` files for number of inputs and only use TFs with (in this case) 14 inputs to ensure all detectors from this run are present +source $O2DPG_ROOT/UTILS/rawTF2raw/generate_rawtf_indices.sh rawtflist_LHC25ab_563041.txt 2025-05-19-pp-750khz-replay-LHC25ab-563041 125 3500 14 + +# create input list of timeslice IDs to be processed for `*.raw` file creation (`timeslices_*.txt`) +# timeslice IDs from this list correspond to \$nTFs consecutive tfCounter ids +# intermediate outputs from o2-raw-tf-reader-workflow and the sorted list of all tfCounter ids will also be stored (`reader_*.log` and `tfids_*.txt`) +sort_tfs + +# create `*.raw` files for timeslices in `timeslices_*.txt` created in the previous step +create_raw_files +``` + + diff --git a/UTILS/rawTF2raw/generate_rawtf_indices.sh b/UTILS/rawTF2raw/generate_rawtf_indices.sh new file mode 100644 index 000000000..49a32e4e5 --- /dev/null +++ b/UTILS/rawTF2raw/generate_rawtf_indices.sh @@ -0,0 +1,98 @@ +#!/bin/bash + +# source $O2DPG_ROOT/UTILS/rawTF2raw/generate_rawtf_indices.sh + +print_help() { + cat < ${tfreader_log} + if [ "0$nBlocks" -eq "00" ]; then + grep 'tf-reader.*Done processing' ${tfreader_log} | sed 's/,//g' | awk '{print $5,$6,$7,$9}' | sort -t ':' -k 3 -h >${tfs_sorted} + else + grep 'tf-reader' ${tfreader_log} | grep -v -e 'Executing sh' -e 'Resuming reading' -e 'Processing file' | grep "Block:${nBlocks}" -A 6 | grep 'Done processing' | sed 's/,//g' | awk '{print $5,$6,$7,$9}' | sort -t ':' -k 3 -h >${tfs_sorted} + fi + firstTFtmp=${firstTF} + while true; do + firstLine=$(grep -nr "tfCounter:${firstTFtmp} " ${tfs_sorted} | awk -F ':' '{print $1}') + [[ ! -z ${firstLine} ]] && break + firstTFtmp=$((firstTFtmp+1)) + done + tail -n +${firstLine} ${tfs_sorted} | head -n ${nTFs} | awk '{print $1}' | sort -V | sed -z -e 's/timeslice://g ; s/\n/,/g ; s/,$//g' >${timeslices_sorted} +} + +# creation of raw data +create_raw_files() { + mkdir -p ${outputDir} + echo "LID=\"$(cat ${timeslices_sorted})\"" | tee ${outputDir}.log + LID=$(cat ${timeslices_sorted}) + echo "o2-raw-tf-reader-workflow --raw-only-det all --shm-segment-size 16000000000 --input-data ${rawtfFileList} --select-tf-ids " '$LID' " | o2-raw-data-dump-workflow --tof-input-uncompressed --shm-segment-size 16000000000 --fatal-on-deadbeef --output-directory ${outputDir} --dump-verbosity 1 --run | tee -a ${outputDir}.log" | tee -a ${outputDir}.log + o2-raw-tf-reader-workflow --raw-only-det all --shm-segment-size 16000000000 --input-data ${rawtfFileList} --select-tf-ids "$LID" | o2-raw-data-dump-workflow --tof-input-uncompressed --shm-segment-size 16000000000 --fatal-on-deadbeef --output-directory ${outputDir} --dump-verbosity 1 --run | tee -a ${outputDir}.log +} diff --git a/test/README.md b/test/README.md index 3c2a90d47..7109e4e70 100644 --- a/test/README.md +++ b/test/README.md @@ -24,9 +24,9 @@ Whenever an `ini` file is detedcted to be tested, a test macro is required to be ```bash .C ``` -Note, that `run_tests.sh` will automatically detect all generators used in an `ini`. For at least one generator defined in the `ini` file there must be a test. Each test is defined as a function in the `.C` macro. Assuming you want to test `External` and `Pythia8` generator, the macro should look like +Note, that `run_tests.sh` will automatically detect all generators used in an `ini`. For at least one generator defined in the `ini` file there must be a test. Each test is defined as a function in the `.C` macro. Assuming you want to test `External`, `Pythia8` and `Hybrid` generators, the macro should look like ```cpp -int Pythia8() +int pythia8() { // do your test return ret; @@ -37,6 +37,12 @@ int External() // do your test return ret; } + +int Hybrid() +{ + // do your test + return ret; +} ``` The return type must be an integer, `0` in case of success and `!=0` in case of failure. diff --git a/test/run_generator_tests.sh b/test/run_generator_tests.sh index 9024d4aed..e02f1080d 100755 --- a/test/run_generator_tests.sh +++ b/test/run_generator_tests.sh @@ -1,10 +1,27 @@ #!/bin/bash +###################################### +# Add Herwig, GSL, ThePEG and nlohmann_json packages to root include path and library path if not already present +###################################### + +# ROOT_INCLUDE_PATH +[[ -n "$THEPEG_ROOT" && ":$ROOT_INCLUDE_PATH:" != *":$THEPEG_ROOT/include:"* ]] && ROOT_INCLUDE_PATH="$THEPEG_ROOT/include:$ROOT_INCLUDE_PATH" +[[ -n "$HERWIG_ROOT" && ":$ROOT_INCLUDE_PATH:" != *":$HERWIG_ROOT/include:"* ]] && ROOT_INCLUDE_PATH="$HERWIG_ROOT/include:$ROOT_INCLUDE_PATH" +[[ -n "$GSL_ROOT" && ":$ROOT_INCLUDE_PATH:" != *":$GSL_ROOT/include:"* ]] && ROOT_INCLUDE_PATH="$GSL_ROOT/include:$ROOT_INCLUDE_PATH" +[[ -n "$NLOHMANN_JSON_ROOT" && ":$ROOT_INCLUDE_PATH:" != *":$NLOHMANN_JSON_ROOT/include:"* ]] && ROOT_INCLUDE_PATH="$NLOHMANN_JSON_ROOT/include:$ROOT_INCLUDE_PATH" + +# LD_LIBRARY_PATH +[[ -n "$THEPEG_ROOT" && ":$LD_LIBRARY_PATH:" != *":$THEPEG_ROOT/lib/ThePEG:"* ]] && LD_LIBRARY_PATH="$THEPEG_ROOT/lib/ThePEG:$LD_LIBRARY_PATH" +[[ -n "$HERWIG_ROOT" && ":$LD_LIBRARY_PATH:" != *":$HERWIG_ROOT/lib/Herwig:"* ]] && LD_LIBRARY_PATH="$HERWIG_ROOT/lib/Herwig:$LD_LIBRARY_PATH" +[[ -n "$GSL_ROOT" && ":$LD_LIBRARY_PATH:" != *":$GSL_ROOT/lib:"* ]] && LD_LIBRARY_PATH="$GSL_ROOT/lib:$LD_LIBRARY_PATH" + +export ROOT_INCLUDE_PATH LD_LIBRARY_PATH + ###################################### # Entrypoint for O2DPG related tests # ###################################### -CHECK_GENERATORS="Pythia8 External" +CHECK_GENERATORS="Pythia8 External Hybrid" # The test parent dir to be cretaed in current directory TEST_PARENT_DIR="o2dpg_tests/generators" @@ -29,24 +46,24 @@ TEST_COUNTER=1 # whether or not to delete everything except logs (default is to delete) KEEP_ONLY_LOGS=1 +# Number of workers for parallel test runs +JOBS=${JOBS:-8} +echo "Running tests with up to ${JOBS} parallel jobs" # Prepare some colored output SRED="\033[0;31m" SGREEN="\033[0;32m" SEND="\033[0m" - echo_green() { echo -e "${SGREEN}${*}${SEND}" } - echo_red() { echo -e "${SRED}${*}${SEND}" } - # Prevent the script from being soured to omit unexpected surprises when exit is used SCRIPT_NAME="$(basename "$(test -L "$0" && readlink "$0" || echo "$0")")" if [ "${SCRIPT_NAME}" != "$(basename ${BASH_SOURCE[0]})" ] ; then @@ -54,19 +71,36 @@ if [ "${SCRIPT_NAME}" != "$(basename ${BASH_SOURCE[0]})" ] ; then return 1 fi - ################################## # Core and utility functionality # ################################## - get_test_script_path_for_ini() { local ini_path=${1} local test_script=$(basename ${ini_path}) - echo $(dirname ${ini_path})/tests/${test_script%.ini}.C + local path_to_test_script=$(dirname ${ini_path})/tests/${test_script%.ini}.C + if [[ ! -f ${path_to_test_script} ]] ; then + # Check if test redirection is applied inside the ini_path file using the #---> syntax + local redirection=$(grep "#--->" ${ini_path}) + if [[ "${redirection}" != "" ]] ; then + test_script=$(echo ${redirection} | awk '{print $2}') + path_to_test_script=$(dirname ${ini_path})/tests/${test_script}.C + fi + fi + echo ${path_to_test_script} } +get_nevents_from_ini() +{ + # function to force the number of events to be simulated from the ini file (default = 100) + # Syntax: #NEV_TEST> 10 (space between #NEV_TEST> and the number is mandatory) + # To be used only if external generator takes too long to run causing timeouts in CI + local ini_path=${1} + local nev=$(grep "#NEV_TEST>" ${ini_path} | tail -n 1 | awk '{print $2}' | tr -d ' ') + [[ "${nev}" == "" ]] && nev=100 + echo ${nev} +} exec_test() { @@ -75,17 +109,30 @@ exec_test() local ini_path=${1} local generator=${2} # for now one of "Pythia8" or "External", at this point we know that settings for the generator are defined in this ini local generator_lower=$(echo "${generator}" | tr '[:upper:]' '[:lower:]') + local test_id=${3} # DPL session ID # TODO Potentially, one could run an external generator that derives from GeneratorPythia8 and so could probably use configuration for TriggerPythia8 - local trigger=${3:+-t ${generator_lower}} + local trigger=${4:+-t ${generator_lower}} + local trigger_dpl=${4:+--trigger ${generator_lower}} local RET=0 # this is how our test script is expected to be called local test_script=$(get_test_script_path_for_ini ${ini_path}) + # get the number of events to be simulated from the ini file + local nev=$(get_nevents_from_ini ${ini_path}) # prepare the header of the log files echo "### Testing ${ini_path} with generator ${generator} ###" > ${LOG_FILE_KINE} echo "### Testing ${ini_path} with generator ${generator} ###" > ${LOG_FILE_GENERIC_KINE} echo "### Testing ${ini_path} with generator ${generator} ###" > ${LOG_FILE_SIM} + echo "### Testing DPL-eventgen ###" >> ${LOG_FILE_SIM} + # run the event generation using the dpl-eventgen executable. + # This is a basic running test, however it's important because the system running on Hyperloop + # is largely used for MCGEN productions and is currently tested only locally. + # Using unique session labels to prevent channel binding conflicts in parallel execution + o2-sim-dpl-eventgen --session test_${test_id} --generator ${generator_lower} ${trigger_dpl} --nEvents ${nev} --configFile ${ini_path} --configKeyValues "GeneratorPythia8.includePartonEvent=true" -b >> ${LOG_FILE_SIM} 2>&1 + RET=${?} + [[ "${RET}" != "0" ]] && { remove_artifacts ; return ${RET} ; } # run the simulation, fail if not successful - o2-sim -g ${generator_lower} ${trigger} --noGeant -n 100 -j 4 --configFile ${ini_path} --configKeyValues "GeneratorPythia8.includePartonEvent=true" >> ${LOG_FILE_SIM} 2>&1 + echo "### Testing base o2-sim executable ###" >> ${LOG_FILE_SIM} + o2-sim -g ${generator_lower} ${trigger} --noGeant -n ${nev} -j 1 --configFile ${ini_path} --configKeyValues "GeneratorPythia8.includePartonEvent=true" >> ${LOG_FILE_SIM} 2>&1 RET=${?} [[ "${RET}" != "0" ]] && { remove_artifacts ; return ${RET} ; } @@ -104,6 +151,13 @@ exec_test() return ${RET} } +wait_for_slot() +{ + # Wait until the number of background jobs is within the limit + while (( $(jobs -r | wc -l) >= JOBS )) ; do + sleep 0.1 + done +} check_generators() { @@ -120,40 +174,53 @@ check_generators() # check if this generator is mentioned in the INI file and only then test it if [[ "$(grep ${g} ${ini_path})" != "" ]] ; then local look_for=$(grep " ${g}.*\(\)" ${test_script}) + # For Pythia8 the function in the test script is lowercase for compatibility purposes + if [[ "${g}" == "Pythia8" ]]; then + look_for=$(grep " pythia8.*\(\)" ${test_script}) + fi local has_trigger="$(grep Trigger${g} ${ini_path})" [[ -z "${look_for}" ]] && continue - echo -n "Test ${TEST_COUNTER}: ${ini_path} with generator ${g}" tested_any=1 # prepare the test directory local test_dir=${TEST_COUNTER}_$(basename ${ini})_${g}_dir rm -rf ${test_dir} 2> /dev/null mkdir ${test_dir} - pushd ${test_dir} > /dev/null - # one single test - exec_test ${ini_path} ${g} ${has_trigger} - RET=${?} - popd > /dev/null - if [[ "${RET}" != "0" ]] ; then - echo_red " -> FAILED" - ret_this=${RET} - else - echo_green " -> PASSED" - fi + local test_num=${TEST_COUNTER} ((TEST_COUNTER++)) + + # Wait for an available slot before starting a new test + wait_for_slot + + echo "Test ${test_num}: ${ini_path} with generator ${g} - STARTED" + # Run test in background + ( + cd ${test_dir} + exec_test ${ini_path} ${g} ${test_num} ${has_trigger} + exit $? + ) & + local pid=$! + + # Store test information in global arrays + test_pids+=(${pid}) + test_numbers+=(${test_num}) + test_generators+=(${g}) + test_ini_paths+=("${ini_path}") fi done [[ -z "${tested_any}" ]] && { echo_red "No test scenario was found for any generator. There must be at least one generator to be tested." ; ret_this=1 ; } return ${ret_this} } - add_ini_files_from_macros() { # given a list of macros, collect all INI files which contain at least one of them local macro_files=$@ for mf in ${macro_files} ; do - # if any, strip the leading O2DPG_ROOT path to only grep for the relative trailing path - mf=${mf##${O2DPG_ROOT}/} + # Strip anything before MC/config/, if any, to get the macro relative path + if [[ "${mf}" == *"MC/config"* ]] ; then + mf=${mf#*MC/config/} + mf="MC/config/${mf}" + fi local other_ini_files=$(grep -r -l ${mf} | grep ".ini$") # so this macro is not included in any of the INI file, # maybe it is included by another macro which is then included in an INI file @@ -166,7 +233,6 @@ add_ini_files_from_macros() done } - get_root_includes() { # check if some R__ADD_INCLUDE_PATH is used in the including macro and check the included file against that @@ -186,7 +252,6 @@ get_root_includes() echo ${full_includes} } - find_including_macros() { # figure out the macros that INCLUDE macros that have changed, so that in turn we can check @@ -233,7 +298,6 @@ find_including_macros() echo ${including_macros} } - add_ini_files_from_tests() { # Collect also those INI files for which the test has been changed @@ -252,7 +316,6 @@ add_ini_files_from_tests() done } - collect_ini_files() { # Collect all INI files which have changed @@ -286,7 +349,6 @@ collect_ini_files() add_ini_files_from_tests ${macros} } - get_git_repo_directory() { local repo= @@ -331,11 +393,11 @@ print_usage() # whether or not to exit after first test has failed fail_immediately= -[[ "${1}" == "--fail_immediately" ]] && fail_immediately=1 +[[ "${1}" == "--fail-immediately" ]] && fail_immediately=1 while [ "$1" != "" ] ; do case $1 in - --fail_immediately ) shift + --fail-immediately ) shift fail_immediately=1 ;; --keep-artifacts ) shift @@ -419,6 +481,12 @@ pushd ${TEST_PARENT_DIR} > /dev/null # global return code to be returned at the end ret_global=0 +# Global arrays to track all test jobs (across all INI files) +declare -a test_pids +declare -a test_numbers +declare -a test_generators +declare -a test_ini_paths + # check each of the INI files for ini in ${ini_files_full_paths} ; do @@ -445,6 +513,50 @@ for ini in ${ini_files_full_paths} ; do [[ "${fail_immediately}" == "1" ]] && break fi done + +# Wait for all test jobs to complete and collect results +total_tests=${#test_pids[@]} +completed=0 +while (( completed < total_tests )) ; do + # Wait for any background job to complete + wait -n + RET=$? + + # Find which job completed by checking which PID no longer exists + for idx in "${!test_pids[@]}" ; do + pid="${test_pids[$idx]}" + if ! kill -0 ${pid} 2>/dev/null ; then + # This job has completed, get its actual exit status + wait ${pid} 2>/dev/null + RET=$? + + test_num="${test_numbers[$idx]}" + generator="${test_generators[$idx]}" + ini_path="${test_ini_paths[$idx]}" + + if [[ "${RET}" != "0" ]] ; then + echo_red "Test ${test_num}: ${ini_path} with generator ${generator} -> FAILED" + ret_global=${RET} + if [[ "${fail_immediately}" == "1" ]] ; then + # Kill remaining background jobs + for remaining_pid in "${test_pids[@]}" ; do + kill ${remaining_pid} 2>/dev/null + done + completed=${total_tests} + break + fi + else + echo_green "Test ${test_num}: ${ini_path} with generator ${generator} -> PASSED" + fi + + # Remove this job from tracking + unset test_pids[$idx] + ((completed++)) + break + fi + done +done + # return to where we came from popd > /dev/null