Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2026-04-27 07:28:14

0001 """
0002 ePIC software stack definitions. Define concrete classes inheriting
0003 from abstract base StackLayer and ExperimentStack from the workflows
0004 module.
0005 """
0006 
0007 from dataclasses import dataclass, field
0008 from typing import List
0009 
0010 from aid2e.utilities.workflows.experimental_stack import (
0011     AnaLayer,
0012     ExperimentStack,
0013     StackLayer
0014 )
0015 
0016 
0017 class EpicGeoLayer(StackLayer):
0018     """Geometry layer of ePIC stack"""
0019     name = "geo"
0020     command = "checkOverlaps"
0021     rule = '{command} {arguments} {inputs} {outputs}'
0022 
0023     def _make_input_arg(self, inputs: List[str]) -> str:
0024         """
0025         Formats inputs for ePIC-specific geometry
0026         layer. There should be exactly one input,
0027         the geometry configuration file to run
0028         overlap check on.
0029         """
0030         if len(inputs) != 1:
0031             raise ValueError(f"EpicGeoLayer takes one input, got {len(inputs)}")
0032         return inputs[0]
0033 
0034     def _make_output_arg(self, outputs: List[str]) -> str:
0035         """
0036         Formats outputs for ePIC-specific geometry
0037         layer. There should be exactly one output,
0038         the log file to store the results of the
0039         check.
0040 
0041         Also adds shell code to check for overlaps/
0042         extrusions and exit if any found.
0043         """
0044         if len(outputs) != 1:
0045             raise ValueError(f"EpicGeoLayer takes one output, got {len(outputs)}")
0046         output = outputs[0]
0047 
0048         # get output and check, exit if there were any overlaps
0049         checks = [
0050           f' >& {output}',
0051           f'grep -F "Number of illegal overlaps/extrusions : " {output} | while IFS= read -r line; do',
0052           '  lastChar="${line: -1}"',
0053           '  if [[ $lastChar =~ ^[0-9]$ ]]; then',
0054           '    if (( lastChar > 0 )); then',
0055           '      exit 9',
0056           '    fi',
0057           '  fi',
0058           'done'
0059         ]
0060         return '\n'.join(checks)
0061 
0062 
0063 class EpicSimLayer(StackLayer):
0064     """Simulation layer of ePIC stack"""
0065     name = "sim"
0066     command = "npsim"
0067     rule = '{command} {arguments} {inputs} {outputs}'
0068 
0069     def _make_input_arg(self, inputs: List[str]) -> str:
0070         """
0071         Formats inputs for ePIC-specific simulation
0072         layer. Applies appropriate CLI option based
0073         on file extension of input.
0074         """
0075         formatted_inputs = list()
0076         for in_file in inputs:
0077             if in_file.endswith(".py"):
0078                 formatted_inputs.append(f"--steeringFile {in_file}")
0079             if in_file.endswith(".hepmc3.root") or in_file.endswith(".hepmc"):
0080                 formatted_inputs.append(f"-I {in_file}")
0081             if in_file.endswith(".mac"):
0082                 formatted_inputs.append(f"--macroFile {in_file}")
0083         return ' '.join(formatted_inputs)
0084 
0085     def _make_output_arg(self, outputs: List[str]) -> str:
0086         """
0087         Formats outputs for ePIC-specific simulation
0088         layer.
0089         """
0090         out_arg = ' '.join(outputs)
0091         return f"--outputFile {out_arg}"
0092 
0093 
0094 class EpicRecLayer(StackLayer):
0095     """Reconstruction layer of ePIC stack"""
0096     name = "rec"
0097     command = "eicrecon"
0098     rule = '{command} {arguments} {outputs} {inputs}'
0099 
0100     def _make_input_arg(self, inputs: List[str]) -> str:
0101         """
0102         Formats inputs for ePIC-specific reconstruction
0103         layer.
0104         """
0105         in_arg = ' '.join(inputs)
0106         return in_arg
0107 
0108     def _make_output_arg(self, outputs: List[str]) -> str:
0109         """
0110         Formats outputs for ePIC-specific reconstruction
0111         layer.
0112         """
0113         formatted_outputs = list()
0114         for out_file in outputs:
0115             formatted_outputs.append(f"-Ppodio:output_file={out_file}")
0116         return ' '.join(formatted_outputs)
0117 
0118 
0119 class EpicAnaLayer(AnaLayer):
0120     """Analysis layer of ePIC stack"""
0121     pass
0122 
0123 
0124 @dataclass
0125 class EpicStack(ExperimentStack):
0126     """The ePIC software stack"""
0127     geo: EpicGeoLayer = field(default_factory = EpicGeoLayer)
0128     sim: EpicSimLayer = field(default_factory = EpicSimLayer)
0129     rec: EpicRecLayer = field(default_factory = EpicRecLayer)
0130     ana: EpicAnaLayer = field(default_factory = EpicAnaLayer)