|
| 1 | +#!/bin/sh |
| 2 | + |
| 3 | +# Copyright 2019-2020 CERN and copyright holders of ALICE O2. |
| 4 | +# See https://alice-o2.web.cern.ch/copyright for details of the copyright holders. |
| 5 | +# All rights not expressly granted are reserved. |
| 6 | +# |
| 7 | +# This software is distributed under the terms of the GNU General Public |
| 8 | +# License v3 (GPL Version 3), copied verbatim in the file "COPYING". |
| 9 | +# |
| 10 | +# In applying this license CERN does not waive the privileges and immunities |
| 11 | +# granted to it by virtue of its status as an Intergovernmental Organization |
| 12 | +# or submit itself to any jurisdiction. |
| 13 | + |
| 14 | +# \file 00_prepare.sh |
| 15 | +# \brief Prepare the local ALICE 3 Geant4 fluence-study inputs and RD50 NIEL weights. |
| 16 | +# \author Nicola Nicassio (nicola.nicassio@cern.ch) |
| 17 | +# \author Rocco Liotino (rocco.liotino@cern.ch) |
| 18 | + |
| 19 | +# Portable preparation step for the ALICE 3 Geant4 fluence study. |
| 20 | +# |
| 21 | +# Supported: |
| 22 | +# ./00_prepare.sh |
| 23 | +# sh 00_prepare.sh |
| 24 | +# source 00_prepare.sh # bash/zsh/ksh |
| 25 | +# |
| 26 | +# POSIX dot syntax also works where the shell exposes the sourced filename, |
| 27 | +# or when FLUENCE_SCRIPT_PATH is set explicitly. |
| 28 | +# |
| 29 | +# The main body runs in a subshell so sourcing does not alter the caller's |
| 30 | +# shell options or current working directory. |
| 31 | + |
| 32 | +fluence_script_path() |
| 33 | +{ |
| 34 | + if [ -n "${FLUENCE_SCRIPT_PATH:-}" ]; then |
| 35 | + printf '%s\n' "$FLUENCE_SCRIPT_PATH" |
| 36 | + return 0 |
| 37 | + fi |
| 38 | + |
| 39 | + if [ -n "${BASH_VERSION:-}" ]; then |
| 40 | + eval 'printf "%s\n" "${BASH_SOURCE[0]}"' |
| 41 | + return 0 |
| 42 | + fi |
| 43 | + |
| 44 | + if [ -n "${ZSH_VERSION:-}" ]; then |
| 45 | + eval 'printf "%s\n" "${(%):-%x}"' |
| 46 | + return 0 |
| 47 | + fi |
| 48 | + |
| 49 | + if [ -n "${KSH_VERSION:-}" ]; then |
| 50 | + _fluence_ksh_path=$(eval 'printf "%s" "${.sh.file}"' 2>/dev/null || true) |
| 51 | + if [ -n "$_fluence_ksh_path" ]; then |
| 52 | + printf '%s\n' "$_fluence_ksh_path" |
| 53 | + return 0 |
| 54 | + fi |
| 55 | + fi |
| 56 | + |
| 57 | + case "$0" in |
| 58 | + sh|-sh|*/sh|dash|-dash|*/dash|ash|-ash|*/ash|ksh|-ksh|*/ksh) |
| 59 | + ;; |
| 60 | + *) |
| 61 | + case "$0" in |
| 62 | + */*) |
| 63 | + printf '%s\n' "$0" |
| 64 | + return 0 |
| 65 | + ;; |
| 66 | + *) |
| 67 | + _fluence_resolved=$(command -v "$0" 2>/dev/null || true) |
| 68 | + if [ -n "$_fluence_resolved" ] && [ -f "$_fluence_resolved" ]; then |
| 69 | + printf '%s\n' "$_fluence_resolved" |
| 70 | + return 0 |
| 71 | + fi |
| 72 | + ;; |
| 73 | + esac |
| 74 | + ;; |
| 75 | + esac |
| 76 | + |
| 77 | + return 1 |
| 78 | +} |
| 79 | + |
| 80 | +fluence_script_dir() |
| 81 | +{ |
| 82 | + _fluence_path=$(fluence_script_path) || return 1 |
| 83 | + CDPATH= cd "$(dirname "$_fluence_path")" 2>/dev/null && pwd -P |
| 84 | +} |
| 85 | + |
| 86 | +fluence_00_prepare_main() ( |
| 87 | +set -eu |
| 88 | + |
| 89 | +HERE=$(fluence_script_dir) || { |
| 90 | + echo "ERROR: cannot determine the directory containing this script." >&2 |
| 91 | + echo "Automatic sourced-file discovery is supported in bash, zsh and ksh93." >&2 |
| 92 | + echo "For another shell, either execute the script or set:" >&2 |
| 93 | + echo " FLUENCE_SCRIPT_PATH=/full/path/to/this/script.sh" >&2 |
| 94 | + exit 1 |
| 95 | +} |
| 96 | + |
| 97 | +BASE_DIR=${BASE_DIR:-$HERE} |
| 98 | +SIM_DIR=${SIM_DIR:-$BASE_DIR/Simulation_files} |
| 99 | + |
| 100 | +FIELD_MACRO=${FIELD_MACRO:-$BASE_DIR/ALICE3Field.C} |
| 101 | +SCORING_MACRO=${SCORING_MACRO:-$BASE_DIR/scoring_g4_alice3.in} |
| 102 | +G4CONFIG_BUILDER=${G4CONFIG_BUILDER:-$BASE_DIR/02_make_g4config.sh} |
| 103 | + |
| 104 | +# Permanent RD50 files kept beside the code. |
| 105 | +RD50_ROOT=${RD50_ROOT:-$BASE_DIR/rd50_niel.root} |
| 106 | +RD50_CSV=${RD50_CSV:-$BASE_DIR/rd50_niel.csv} |
| 107 | + |
| 108 | +# Leave empty if the O2/O2Physics environment is already loaded. |
| 109 | +# If supplied, this setup file itself must be compatible with POSIX "sh". |
| 110 | +O2_SETUP_SCRIPT=${O2_SETUP_SCRIPT:-} |
| 111 | + |
| 112 | +echo |
| 113 | +echo "============================================================" |
| 114 | +echo " ALICE3 LOCAL SIMULATION — PREPARE" |
| 115 | +echo "============================================================" |
| 116 | + |
| 117 | +if [ -n "$O2_SETUP_SCRIPT" ]; then |
| 118 | + if [ ! -r "$O2_SETUP_SCRIPT" ]; then |
| 119 | + echo "ERROR: cannot read O2 setup script: $O2_SETUP_SCRIPT" >&2 |
| 120 | + exit 1 |
| 121 | + fi |
| 122 | + . "$O2_SETUP_SCRIPT" |
| 123 | +fi |
| 124 | + |
| 125 | +for f in "$FIELD_MACRO" "$SCORING_MACRO" "$G4CONFIG_BUILDER"; do |
| 126 | + if [ ! -r "$f" ]; then |
| 127 | + echo "ERROR: missing mandatory file: $f" >&2 |
| 128 | + exit 2 |
| 129 | + fi |
| 130 | +done |
| 131 | + |
| 132 | +if ! command -v o2-sim-serial-run5 >/dev/null 2>&1; then |
| 133 | + echo "ERROR: o2-sim-serial-run5 is not in PATH." >&2 |
| 134 | + echo "Load the O2 or O2Physics environment first." >&2 |
| 135 | + exit 3 |
| 136 | +fi |
| 137 | + |
| 138 | +if [ -z "${O2_ROOT:-}" ]; then |
| 139 | + echo "ERROR: O2_ROOT is not set. Load O2 or O2Physics first." >&2 |
| 140 | + exit 4 |
| 141 | +fi |
| 142 | + |
| 143 | +O2_RD50_ROOT=$O2_ROOT/share/Detectors/gconfig/data/rd50_niel.root |
| 144 | + |
| 145 | +if [ ! -r "$O2_RD50_ROOT" ]; then |
| 146 | + echo "ERROR: cannot find $O2_RD50_ROOT" >&2 |
| 147 | + exit 5 |
| 148 | +fi |
| 149 | + |
| 150 | +echo "Refreshing RD50 ROOT from O2:" |
| 151 | +echo " $O2_RD50_ROOT" |
| 152 | +echo "-> $RD50_ROOT" |
| 153 | +cp -f "$O2_RD50_ROOT" "$RD50_ROOT" |
| 154 | + |
| 155 | +if ! command -v python3 >/dev/null 2>&1; then |
| 156 | + echo "ERROR: python3 is not available." >&2 |
| 157 | + exit 6 |
| 158 | +fi |
| 159 | + |
| 160 | +RD50_CSV_TMP=$RD50_CSV.tmp |
| 161 | +rm -f "$RD50_CSV_TMP" |
| 162 | + |
| 163 | +echo |
| 164 | +echo "Regenerating $RD50_CSV from $RD50_ROOT" |
| 165 | + |
| 166 | +python3 - "$RD50_ROOT" "$RD50_CSV_TMP" <<'PY' |
| 167 | +import sys |
| 168 | +import ROOT |
| 169 | +
|
| 170 | +input_file, output_file = sys.argv[1], sys.argv[2] |
| 171 | +
|
| 172 | +f = ROOT.TFile.Open(input_file, "READ") |
| 173 | +if not f or f.IsZombie(): |
| 174 | + raise RuntimeError(f"Cannot open {input_file}") |
| 175 | +
|
| 176 | +mandatory = [ |
| 177 | + (2112, "neutronDW"), |
| 178 | + (2212, "protonDW"), |
| 179 | + (211, "pionDW"), |
| 180 | +] |
| 181 | +
|
| 182 | +optional = [ |
| 183 | + (11, "electronDW"), |
| 184 | +] |
| 185 | +
|
| 186 | +graphs = [] |
| 187 | +
|
| 188 | +for pdg, name in mandatory: |
| 189 | + g = f.Get(name) |
| 190 | + if not g: |
| 191 | + raise RuntimeError( |
| 192 | + f"Mandatory graph '{name}' not found in {input_file}" |
| 193 | + ) |
| 194 | + graphs.append((pdg, name, g)) |
| 195 | +
|
| 196 | +for pdg, name in optional: |
| 197 | + g = f.Get(name) |
| 198 | + if g: |
| 199 | + graphs.append((pdg, name, g)) |
| 200 | + else: |
| 201 | + print(f"WARNING: optional graph '{name}' is absent.") |
| 202 | +
|
| 203 | +with open(output_file, "w") as out: |
| 204 | + out.write("# pdg,ekin[MeV],weight\n") |
| 205 | +
|
| 206 | + for pdg, name, g in graphs: |
| 207 | + print(f"Writing {name}: PDG {pdg}, {g.GetN()} points") |
| 208 | +
|
| 209 | + for i in range(g.GetN()): |
| 210 | + x = float(g.GetPointX(i)) |
| 211 | + y = float(g.GetPointY(i)) |
| 212 | + out.write(f"{pdg},{x:.12e},{y:.12e}\n") |
| 213 | +
|
| 214 | +f.Close() |
| 215 | +print(f"Wrote {output_file}") |
| 216 | +PY |
| 217 | + |
| 218 | +if [ ! -s "$RD50_CSV_TMP" ]; then |
| 219 | + echo "ERROR: RD50 CSV generation failed." >&2 |
| 220 | + rm -f "$RD50_CSV_TMP" |
| 221 | + exit 7 |
| 222 | +fi |
| 223 | + |
| 224 | +mv -f "$RD50_CSV_TMP" "$RD50_CSV" |
| 225 | + |
| 226 | +if [ ! -s "$RD50_ROOT" ] || [ ! -s "$RD50_CSV" ]; then |
| 227 | + echo "ERROR: RD50 preparation failed." >&2 |
| 228 | + exit 8 |
| 229 | +fi |
| 230 | + |
| 231 | +mkdir -p "$SIM_DIR" |
| 232 | + |
| 233 | +echo |
| 234 | +echo "Preparation OK." |
| 235 | +ls -l "$RD50_ROOT" "$RD50_CSV" |
| 236 | +echo |
| 237 | +echo "Authentication/token files are not touched or checked." |
| 238 | +) |
| 239 | + |
| 240 | +fluence_00_prepare_main "$@" |
0 commit comments