Warning, /physics_benchmarks/Snakefile is written in an unsupported language. File is not indexed.
0001 configfile: "snakemake.yml"
0002
0003 import functools
0004 import os
0005 import subprocess
0006 from snakemake.logging import logger
0007
0008
0009 ## The detector install prefix is the single source of truth: the geometry XML
0010 ## directory, the geometry library and thisepic.sh are all derived from it.
0011 ## DETECTOR_PATH is published back into the configuration so that rules can
0012 ## refer to it as config["DETECTOR_PATH"] rather than reaching for a
0013 ## module-level name, and so that a detector with a non-standard layout can
0014 ## still be pointed at directly with --config DETECTOR_PATH=...
0015 DETECTOR_PREFIX = config["DETECTOR_PREFIX"]
0016 config.setdefault("DETECTOR_PATH", f"{DETECTOR_PREFIX}/share/{config['DETECTOR']}")
0017
0018 ## ROOT mirrors the absolute source path underneath its build directory, so
0019 ## ROOT_BUILD_DIR has to be absolute for the declared outputs to match where
0020 ## ACLiC actually writes. An empty value means build in-tree.
0021 ROOT_BUILD_DIR = config.get("ROOT_BUILD_DIR") or None
0022
0023 if ROOT_BUILD_DIR is not None:
0024 ROOT_BUILD_DIR = os.path.abspath(ROOT_BUILD_DIR)
0025 ROOT_BUILD_DIR_PREFIX = f"{ROOT_BUILD_DIR}/{os.getcwd().lstrip('/')}/"
0026 else:
0027 ROOT_BUILD_DIR_PREFIX = ""
0028
0029
0030 ## Every shell: block gets the detector environment and ROOT settings from the
0031 ## configuration, so the pipeline does not depend on the CI job having set them
0032 ## up. Five things to keep in mind when editing this:
0033 ## - No stray curly braces: shell.prefix() runs its argument through
0034 ## snakemake's own format(), which would interpret them as format fields.
0035 ## That rules out ${VAR:-} style defaults, hence the ordering below.
0036 ## - "set -euo pipefail" comes last, not first. Snakemake normally prepends it
0037 ## to every shell: block, but only while no shell.prefix() is set, so we have
0038 ## to reinstate it ourselves or silently lose it. It has to come *after* the
0039 ## environment setup: thisepic.sh reads $LD_LIBRARY_PATH unguarded and the
0040 ## ROOT_INCLUDE_PATH append reads its own previous value, both of which abort
0041 ## under "set -u" when unset. The rule body still runs fully strict.
0042 ## - thisepic.sh takes the detector configuration as $1. That relies on
0043 ## "source" rather than POSIX ".", which does not give the sourced script
0044 ## its own positional parameters; snakemake runs shell: blocks under bash
0045 ## (it calls shell.executable("bash") on import), so this is fine.
0046 ## - DETECTOR_PATH is re-exported afterwards, because thisepic.sh sets it from
0047 ## its own install tree, which would otherwise disagree with
0048 ## config["DETECTOR_PATH"] for the rules that read $DETECTOR_PATH in a
0049 ## shell: block.
0050 ## - ";" and not "&&", so that the environment setup does not abort a rule
0051 ## where thisepic.sh is absent (e.g. the lager image used by dvmp:generate).
0052 shell.prefix(
0053 f"source {DETECTOR_PREFIX}/bin/thisepic.sh {config['DETECTOR_CONFIG']}; "
0054 f"export DETECTOR_PATH={config['DETECTOR_PATH']}; "
0055 f"export ROOT_MAX_THREADS={config['BENCHMARK_N_THREADS']}; "
0056 f"export ROOT_INCLUDE_PATH={os.path.abspath(workflow.basedir)}/include:$ROOT_INCLUDE_PATH; "
0057 + (f"export ROOT_BUILD_DIR={ROOT_BUILD_DIR}; " if ROOT_BUILD_DIR else "")
0058 + "set -euo pipefail; "
0059 )
0060
0061
0062 @functools.cache
0063 def get_spack_package_hash(package_name):
0064 import json
0065 try:
0066 ver_info = json.loads(subprocess.check_output(["spack", "find", "--json", package_name]))
0067 return ver_info[0]["hash"]
0068 except FileNotFoundError as e:
0069 logger.warning("Spack is not installed")
0070 return ""
0071 except subprocess.CalledProcessError as e:
0072 print(e)
0073 return ""
0074
0075
0076 @functools.cache
0077 def find_epic_libraries():
0078 import ctypes.util
0079 # if library is not found (not avaliable) we return an empty list to let DAG still evaluate
0080 libs = []
0081 lib = ctypes.util.find_library("epic")
0082 if lib is not None:
0083 libs.append(f"{DETECTOR_PREFIX}/lib/{lib}")
0084 return libs
0085
0086
0087 rule compile_analysis:
0088 input:
0089 "{path}/{filename}.cxx",
0090 output:
0091 ROOT_BUILD_DIR_PREFIX + "{path}/{filename}_cxx.d",
0092 ROOT_BUILD_DIR_PREFIX + "{path}/{filename}_cxx.so",
0093 ROOT_BUILD_DIR_PREFIX + "{path}/{filename}_cxx_ACLiC_dict_rdict.pcm",
0094 shell:
0095 """
0096 root -l -b -q -e '.L {input}+'
0097 """
0098
0099
0100 rule fetch_epic:
0101 output:
0102 filepath="EPIC/{PATH}"
0103 cache: True
0104 shell: """
0105 xrdcp root://dtn-eic.jlab.org//volatile/eic/{output.filepath} {output.filepath}
0106 """
0107
0108
0109 rule warmup_run:
0110 output:
0111 "warmup/{DETECTOR_CONFIG}.edm4hep.rnt.root",
0112 message: "Ensuring that calibrations/fieldmaps are available for {wildcards.DETECTOR_CONFIG}"
0113 shell: """
0114 ddsim \
0115 --runType batch \
0116 --numberOfEvents 1 \
0117 --compactFile "$DETECTOR_PATH/{wildcards.DETECTOR_CONFIG}.xml" \
0118 --outputConfig.useRNTuple true \
0119 --outputFile "{output}" \
0120 --enableGun
0121 """
0122
0123 include: "benchmarks/Exclusive-Diffraction-Tagging/demp/Snakefile"
0124 include: "benchmarks/Exclusive-Diffraction-Tagging/diffractive_vm/Snakefile"
0125 include: "benchmarks/Exclusive-Diffraction-Tagging/dvmp/Snakefile"
0126 include: "benchmarks/Exclusive-Diffraction-Tagging/semi_coherent/Snakefile"
0127 include: "benchmarks/Jets-HF/jets/Snakefile"
0128 include: "benchmarks/Inclusive/dis/Snakefile"