Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-07-01 08:59:04

0001 #!/bin/bash
0002 # This script sets up the environment for EIC simulations using EPIC and EICrecon.
0003 # It installs the necessary software, compiles custom configurations, and generates job submission scripts.
0004 # It also handles the simulation and analysis of events based on user-defined parameters.
0005 
0006 # example of usage in BASH(!) shell  - not native .csh shell:
0007 # MOMENTUM=0.5 ./submit.sh
0008 
0009 # The workflow includes:
0010 # 1. Setting up the eic-shell
0011 # 2. Compiling EPIC+EICrecon in your directory if not already done.
0012 # 3. Generating a main simulation script = job with ddsim + eicrecon + run root macro.
0013 # 4. Generating a job submission script for HTCondor and submitting it.
0014 
0015 #================================================================
0016 #   CONFIGURATION
0017 #================================================================
0018 
0019 # simulation parameters
0020 DEFAULT_MOMENTUM=1          # 1 GeV
0021 DEFAULT_PHI=45              # 45 degrees
0022 DEFAULT_THETA=170           # 170 degrees
0023 DEFAULT_PARTICLE=neutron    # "neutron" or "proton"
0024 DEFAULT_NUMBER_OF_EVENTS=10 # 10 events per job
0025 DEFAULT_JOBS=10             # 10 job
0026 
0027 # simulation parameters - can be set via command line or environment variables
0028 MOMENTUM=${MOMENTUM:-$DEFAULT_MOMENTUM}
0029 PHI=${PHI:-$DEFAULT_PHI}
0030 THETA=${THETA:-$DEFAULT_THETA}
0031 PARTICLE=${PARTICLE:-$DEFAULT_PARTICLE}
0032 NUMBER_OF_EVENTS=${NUMBER_OF_EVENTS:-$DEFAULT_NUMBER_OF_EVENTS}
0033 JOBS=${JOBS:-$DEFAULT_JOBS}
0034 
0035 #================================================================
0036 DETECTOR_CONFIG="epic_backward_hcal_only.xml" # or some other e.g. "epic_backward_hcal_only.xml"
0037 #  make unique dir name for whole configuration
0038 SIM_CONFIG="${PARTICLE}_p${MOMENTUM}gev_phi${PHI}_theta${THETA}_${NUMBER_OF_EVENTS}events"
0039 
0040 # output directories
0041 output_dir="/gpfs02/eic/${USER}/output/${SIM_CONFIG}"
0042 my_epic_dir="/gpfs02/eic/${USER}/epic"
0043 my_eicrecon_dir="/gpfs02/eic/${USER}/EICrecon"
0044 current_dir="$(pwd)"
0045 
0046 #================================================================
0047 #   UTILITY FUNCTIONS
0048 #================================================================
0049 set -euo pipefail # Exit on error, undefined variables, and pipe failures
0050 log() {
0051     echo "[$(date '+%Y-%m-%d %H:%M:%S')] $*"
0052 }
0053 error() {
0054     echo "[$(date '+%Y-%m-%d %H:%M:%S')] ERROR: $*" >&2
0055     echo "  Context: Function ${FUNCNAME[1]}, Line ${BASH_LINENO[0]}" >&2
0056 }
0057 display_configuration() {
0058     cat <<EOF
0059 ===  SIMULATION CONFIGURATION ===
0060 
0061 Simulation Parameters:
0062   - Particle: ${PARTICLE}
0063   - Momentum: ${MOMENTUM} GeV
0064   - Phi: ${PHI}°, Theta: ${THETA0065   - Events per Job: ${NUMBER_OF_EVENTS}
0066   - Number of Jobs: ${JOBS}
0067 
0068 Output Directory: ${output_dir}
0069 ===================================
0070 EOF
0071 }
0072 #=================================================================
0073 # 1. Setting up the eic-shell
0074 # Setup EIC shell environment
0075 # Globals:
0076 #   EICSHELL - Path to eic-shell executable
0077 #   USER - Current username
0078 # Returns:
0079 #   0 on success, 1 on failure
0080 #================================================================
0081 setup_eicshell() {
0082     export EICSHELL="/eic/u/${USER}/eic/eic-shell"
0083     if [[ ! -f "$EICSHELL" ]]; then
0084         log "Installing eic-shell..."
0085         mkdir -p "$HOME/eic"
0086         cd "$HOME/eic"
0087         if ! curl -L https://github.com/eic/eic-shell/raw/main/install.sh | bash; then
0088             error "Failed to install eic-shell"
0089             exit 1
0090         fi
0091         cd "$current_dir"
0092     fi
0093 }
0094 #=================================================================
0095 
0096 #=================================================================
0097 # 2. Compiling EPIC in your directory if not already done.
0098 #=================================================================
0099 
0100 setup_epic() {
0101     log "Checking EPIC setup..."
0102     # Check if EPIC is already properly installed
0103     if [[ -d "$my_epic_dir" ]] && [[ -f "$my_epic_dir/install/bin/thisepic.sh" ]]; then
0104         log "EPIC already installed at $my_epic_dir"
0105         return 0
0106     fi
0107 
0108     log "Setting up EPIC..."
0109 
0110     # Create parent directory if it doesn't exist
0111     local parent_dir="$(dirname "$my_epic_dir")"
0112     mkdir -p "$parent_dir"
0113 
0114     # Remove any incomplete installation
0115     if [[ -d "$my_epic_dir" ]]; then
0116         log "Removing incomplete EPIC installation..."
0117         rm -rf "$my_epic_dir"
0118     fi
0119 
0120     # Clone EPIC
0121     cd "$parent_dir"
0122     log "Cloning EPIC repository..."
0123     if ! git clone https://github.com/eic/epic.git "$(basename "$my_epic_dir")"; then
0124         error "Failed to clone EPIC repository"
0125         exit 1
0126     fi
0127 
0128     cd "$my_epic_dir"
0129     # Build EPIC
0130 
0131     cat <<EOF | $EICSHELL
0132     echo "Configuring EPIC build..."
0133 
0134     # Run CMake configure step with ccache launcher support
0135     echo " Building and installing EPIC (this may take several minutes)..."
0136     if ! cmake -B build -S . \
0137         -DCMAKE_INSTALL_PREFIX=install; then
0138         echo "CMake configuration failed."
0139         exit 1
0140     fi
0141     if ! cmake --build build -j$(nproc) -- install; then
0142         exit 1
0143     fi
0144 EOF
0145     # Verify installation
0146     if [[ ! -f "$my_epic_dir/install/bin/thisepic.sh" ]]; then
0147         error "EPIC installation incomplete - missing thisepic.sh"
0148         exit 1
0149     fi
0150 
0151     cd "$current_dir"
0152     log "EPIC setup completed successfully"
0153 
0154 }
0155 
0156 #================================================================
0157 #   3. Compiling EICrecon in your directory if not already done.
0158 #================================================================
0159 
0160 setup_eicrecon() {
0161     log "Checking EICrecon setup..."
0162     # First, ensure EPIC is properly installed
0163     if [[ ! -f "$my_epic_dir/install/bin/thisepic.sh" ]]; then
0164         log "Expected EPIC installation at: $my_epic_dir/install/bin/thisepic.sh"
0165         error "EPIC installation not found. Please set up EPIC first."
0166         exit 1
0167     fi
0168     # Check if EICrecon is already properly installed
0169     if [[ -d "$my_eicrecon_dir" ]] && [[ -f "$my_eicrecon_dir/install/bin/eicrecon-this.sh" ]]; then
0170         log "EICrecon already installed at $my_eicrecon_dir"
0171         return 0
0172     fi
0173 
0174     log "Setting up EICrecon..."
0175 
0176     # Create parent directory if it doesn't exist
0177     local parent_dir="$(dirname "$my_eicrecon_dir")"
0178     mkdir -p "$parent_dir"
0179 
0180     # Remove any incomplete installation
0181     if [[ -d "$my_eicrecon_dir" ]]; then
0182         log "Removing incomplete EICrecon installation..."
0183         rm -rf "$my_eicrecon_dir"
0184     fi
0185 
0186     # Clone EICrecon
0187     cd "$parent_dir"
0188     log "Cloning EICrecon repository..."
0189     if ! git clone https://github.com/eic/EICrecon.git "$(basename "$my_eicrecon_dir")"; then
0190         error "Failed to clone EICrecon repository"
0191         exit 1
0192     fi
0193 
0194     # Build EICrecon
0195     cd "$my_eicrecon_dir"
0196 
0197     log "Configuring EICrecon build..."
0198     cat <<EOF | $EICSHELL
0199     source "$my_epic_dir/install/bin/thisepic.sh"
0200     if ! cmake -B build -S . -DCMAKE_INSTALL_PREFIX=install; then
0201         exit 1
0202     fi
0203     echo "Building and installing EICrecon (this may take several minutes)..."
0204     if ! cmake --build build -j$(nproc) -- install; then
0205         exit 1
0206     fi
0207     echo "Installing EICrecon..."
0208     if ! cmake --install build; then
0209         exit 1
0210     fi
0211 EOF
0212     # Verify installation
0213     if [[ ! -f "$my_eicrecon_dir/install/bin/eicrecon-this.sh" ]]; then
0214         error "EICrecon installation incomplete - missing eicrecon-this.sh"
0215         exit 1
0216     fi
0217 
0218     cd "$current_dir"
0219     log "EICrecon setup completed successfully"
0220 }
0221 #=================================================================
0222 
0223 #================================================================
0224 #   MAIN SCRIPT GENERATION
0225 #================================================================
0226 
0227 generate_main_script() {
0228     log "Generating main simulation script..."
0229 
0230     cat >my_generated_script.sh <<'EOF'
0231 #!/bin/bash
0232 cd OUTPUT_DIR_PLACEHOLDER
0233 # Parse arguments
0234 if [[ $# -ne 7 ]]; then
0235     echo "Usage: $0 <Cluster> <Process> <Momentum> <Phi> <Theta> <Particle> <NumberOfEvents>"
0236     echo "current values: $CLUSTER $PROCESS $GUN_MOMENTUM $GUN_PHI $GUN_THETA $PARTICLE $NUMBER_OF_EVENTS"
0237     exit 1
0238 fi
0239 export CLUSTER="$1"
0240 export PROCESS="$2"
0241 export GUN_MOMENTUM="$3"
0242 export GUN_PHI="$4"
0243 export GUN_THETA="$5"
0244 export PARTICLE="$6"
0245 export NUMBER_OF_EVENTS="$7"
0246 
0247 # Set up file names
0248 export FILENAME="${PARTICLE}_${NUMBER_OF_EVENTS}events_p${GUN_MOMENTUM}gev_phi${GUN_PHI}_theta${GUN_THETA}_job${CLUSTER}_${PROCESS}"
0249 export DDSIM_FILE="sim_${FILENAME}.edm4hep.root"
0250 export EICRECON_FILE="eicrecon_${FILENAME}.edm4eic.root"
0251 
0252 # Calculate angle ranges (small ranges for single-angle shooting)
0253 export GUN_THETA_MIN=$(echo "$GUN_THETA - 0.0001" | bc -l)
0254 export GUN_THETA_MAX=$(echo "$GUN_THETA + 0.0001" | bc -l)
0255 export GUN_PHI_MIN=$(echo "$GUN_PHI - 0.0001" | bc -l)
0256 export GUN_PHI_MAX=$(echo "$GUN_PHI + 0.0001" | bc -l)
0257 export GUN_MOMENTUM_MIN=$(echo "$GUN_MOMENTUM - 0.00001" | bc -l)
0258 export GUN_MOMENTUM_MAX=$(echo "$GUN_MOMENTUM + 0.00001" | bc -l)
0259 
0260 cat << 'EOFINNER' | EICSHELL_PLACEHOLDER
0261     # Source environment
0262     if [[ -f "MY_EPIC_DIR_PLACEHOLDER/install/bin/thisepic.sh" ]]; then
0263         source "MY_EPIC_DIR_PLACEHOLDER/install/bin/thisepic.sh" epic
0264     else
0265         error "EPIC installation not found"
0266         exit 1
0267     fi
0268 
0269     if ! ddsim \
0270             --compactFile "$DETECTOR_PATH/DETECTOR_CONFIG_PLACEHOLDER" \
0271             --numberOfEvents "$NUMBER_OF_EVENTS" \
0272             --random.seed "$(date +%N)" \
0273             --enableGun \
0274             --gun.particle "$PARTICLE" \
0275             --gun.thetaMin "${GUN_THETA_MIN}*degree" \
0276             --gun.thetaMax "${GUN_THETA_MAX}*degree" \
0277             --gun.phiMin "${GUN_PHI_MIN}*degree" \
0278             --gun.phiMax "${GUN_PHI_MAX}*degree" \
0279             --gun.distribution uniform \
0280             --gun.momentumMin "${GUN_MOMENTUM_MIN}*GeV" \
0281             --gun.momentumMax "${GUN_MOMENTUM_MAX}*GeV" \
0282             --outputFile "$DDSIM_FILE"; then
0283             echo "DDSIM simulation failed"
0284             exit 1
0285     fi
0286 
0287     # Source EICrecon
0288     if [[ -f "MY_EICRECON_DIR_PLACEHOLDER/install/bin/eicrecon-this.sh" ]]; then
0289         source "MY_EICRECON_DIR_PLACEHOLDER/install/bin/eicrecon-this.sh" epic
0290     else
0291         echo "EICrecon installation not found"
0292         exit 1
0293     fi
0294     # Run EICrecon if needed
0295     echo "Running EICrecon..."
0296     if ! eicrecon "$DDSIM_FILE" \
0297             -Ppodio:output_file="$EICRECON_FILE"
0298             -Ppodio:output_collections="MCParticles"; then
0299         echo "EICrecon failed"
0300         exit 1
0301     fi
0302     # Run analysis
0303     echo "Running ROOT analysis..."
0304     analysis_script="CURRENT_DIR_PLACEHOLDER/example_macro.C"
0305     if [[ ! -f "$analysis_script" ]]; then
0306         echo "Analysis script not found: $analysis_script"
0307         exit 1
0308     fi
0309     output_file="ana_${FILENAME}.root"
0310     if ! root -l -b -q "${analysis_script}(\\\"${EICRECON_FILE}\\\", \\\"${output_file}\\\")"; then
0311         echo "ROOT analysis failed"
0312         exit 1
0313     fi
0314     echo "Job completed successfully"
0315 EOFINNER
0316 EOF
0317     # Replace placeholders with actual values
0318     sed -i "s|OUTPUT_DIR_PLACEHOLDER|$output_dir|g" my_generated_script.sh
0319     sed -i "s|MY_EPIC_DIR_PLACEHOLDER|$my_epic_dir|g" my_generated_script.sh
0320     sed -i "s|MY_EICRECON_DIR_PLACEHOLDER|$my_eicrecon_dir|g" my_generated_script.sh
0321     sed -i "s|CURRENT_DIR_PLACEHOLDER|$current_dir|g" my_generated_script.sh
0322     sed -i "s|EICSHELL_PLACEHOLDER|$EICSHELL|g" my_generated_script.sh
0323     sed -i "s|DETECTOR_CONFIG_PLACEHOLDER|$DETECTOR_CONFIG|g" my_generated_script.sh
0324 
0325     chmod +x my_generated_script.sh
0326 
0327     log "Main simulation script generated successfully"
0328 }
0329 
0330 #================================================================
0331 #   JOB SUBMISSION SCRIPT
0332 #================================================================
0333 generate_job_script() {
0334     local temp_job="$current_dir/generated.job"
0335     # Remove existing job file if it exists
0336     if [[ -f "$temp_job" ]]; then
0337         rm -f "$temp_job"
0338     fi
0339     cat >"$temp_job" <<EOF
0340 Universe                = vanilla
0341 GetEnv                  = False
0342 Requirements            = (CPU_Speed >= 1)
0343 Rank                    = CPU_Speed
0344 Initialdir              = $current_dir
0345 Arguments               = \$(Cluster) \$(Process) $MOMENTUM $PHI $THETA $PARTICLE $NUMBER_OF_EVENTS
0346 Executable              = my_generated_script.sh
0347 Error                   = $output_dir/log/error\$(Cluster)_\$(Process).err
0348 Output                  = $output_dir/log/out\$(Cluster)_\$(Process).out
0349 Log                     = $output_dir/log/log\$(Cluster)_\$(Process).log
0350 Queue $JOBS
0351 EOF
0352     if [[ ! -f "$temp_job" ]]; then
0353         return 1
0354     fi
0355     # Only echo the filename - no log messages
0356     echo "$temp_job"
0357 }
0358 
0359 #================================================================
0360 #   MAIN EXECUTION
0361 #================================================================
0362 main() {
0363     log "=== Starting EPIC Simulation ==="
0364     #================================================================
0365     display_configuration
0366 
0367     # Setup phase
0368     log "Setting up eic-shell..."
0369     setup_eicshell
0370     setup_epic
0371     setup_eicrecon
0372 
0373     # Create output directories
0374     mkdir -p "$output_dir/log"
0375     rm -f $output_dir/log/*.*
0376     log "Output directory created: $output_dir"
0377 
0378     generate_main_script
0379 
0380     log "Generating HTCondor job submission script..."
0381     local job_file=$(generate_job_script)
0382 
0383     if [[ -z "$job_file" ]] || [[ ! -f "$job_file" ]]; then
0384         error "Failed to create job submission file"
0385         exit 1
0386     fi
0387     log "Job submission file created: $job_file"
0388 
0389     log "Submitting job..."
0390     if condor_submit "$job_file"; then
0391         log "Job submitted successfully! Output files will be saved in $output_dir"
0392     else
0393         error "Job submission failed"
0394         exit 1
0395     fi
0396     # wait for the jobs to finish
0397     #log "Waiting for jobs to finish..."
0398     # ./condor_control.sh
0399     log "=== EPIC Simulation Completed ==="
0400     #  now one can merge the output files into one
0401     # hadd -f -j -k "${output_dir}/merged_ana.root" "${output_dir}/ana*.root"
0402 }
0403 # Run main function
0404 main "$@"