Back to home page

EIC code displayed by LXR

 
 

    


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"