Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2026-08-12 08:24:58

0001 """Test ePIC stack/workflow configuration."""
0002 
0003 import yaml
0004 
0005 from aid2e.utilities.epic_utils.epic_stack_config import (
0006     EpicLayerConfig,
0007     EpicJobDefinition,
0008     EpicStageDefinition,
0009     EpicBranchDefinition,
0010     EpicWorkflowDefinition,
0011     EpicWorkflowsConfiguration,
0012 )
0013 from aid2e.utilities.workflows.dag_executor import DAGExecutor
0014 
0015 def _sample_epic_workflow_payload() -> dict:
0016     """Build ePIC workflow configuration."""
0017     return {
0018        "workflows": [
0019            {
0020                "name": "imaging_optimization",
0021                "description": "Optimize the number of AstroPix layers in the BIC",
0022                "stack_type": "epic",
0023                "branches": [
0024                    {
0025                        "name": "photon_phi_resolution",
0026                        "description": "Calculate phi resolution for single photons",
0027                        "stages": [
0028                            {
0029                                "name": "geo",
0030                                "description": "Check for overlaps in modified geomtry",
0031                                "jobs" : [
0032                                    {
0033                                        "name": "geo_job",
0034                                        "layers": [
0035                                            {
0036                                                "layer": "geo",
0037                                                "inputs": [
0038                                                    "{{geometry_dir}}/install/share/epic/epic.xml"
0039                                                ],
0040                                                "outputs": [
0041                                                    "{{execution_dir}}/geo.overlaps.txt"
0042                                                ]
0043                                            }
0044                                        ],
0045                                        "payload": {
0046                                            "evaluator_type": "stack",
0047                                            "stack_type": "epic",
0048                                            "job_id": "geo"
0049                                        }
0050                                    }
0051                                ]
0052                            },
0053                            {
0054                                "name": "sim",
0055                                "description": "Simulate single photons",
0056                                "jobs": [
0057                                    {
0058                                        "name": "sim_job",
0059                                        "layers": [
0060                                            {
0061                                                "layer": "sim",
0062                                                "inputs": [
0063                                                    "inputs/central_photons.py"
0064                                                ],
0065                                                "outputs": [
0066                                                    "{{execution_dir}}/central_photons.edm4hep.root"
0067                                                ]
0068                                            }
0069                                        ],
0070                                        "payload": {
0071                                            "evaluator_type": "stack",
0072                                            "stack_type": "epic",
0073                                            "job_id": "sim"
0074                                        }
0075                                    }
0076                                ]
0077                            },
0078                            {
0079                                "name": "rec_and_ana",
0080                                "description": "Run reconstruction and analysis",
0081                                "jobs": [
0082                                    {
0083                                        "name": "rec_ana_job",
0084                                        "layers": [
0085                                            {
0086                                                "layer": "rec",
0087                                                "inputs": [
0088                                                    "{{outputs[sim:sim_job:sim]}}/central_photons.edm4hep.root"
0089                                                ],
0090                                                "outputs": [
0091                                                    "{{execution_dir}}/central_photons.edm4eic.root"
0092                                                ],
0093                                                "arguments": [
0094                                                    "-Pnthreads=8",
0095                                                    "-Peicrecon:LogLevel=debug"
0096                                                ]
0097                                            },
0098                                            {
0099                                                "layer": "ana",
0100                                                "inputs": [
0101                                                    "{{outputs[rec_and_ana:rec_ana_job:rec]}}/central_photons.edm4eic.root"
0102                                                ],
0103                                                "outputs": [
0104                                                    "{{execution_dir}}/central_photons.hist.root"
0105                                                ],
0106                                                "arguments": [
0107                                                    "-c phi",
0108                                                    "-s 22"
0109                                                ],
0110                                                "command": "scripts/bic_angular_reso.py",
0111                                                "rule": "python {{command}} -i {{inputs}} -o {{outputs}} {{arguments}}"
0112                                            }
0113                                        ],
0114                                        "payload": {
0115                                            "evaluator_type": "stack",
0116                                            "stack_type": "epic",
0117                                            "job_id": "rec_ana"
0118                                        }
0119                                    }
0120                                ]
0121                            }
0122                        ]
0123                    }
0124                ]
0125            }
0126        ]
0127    }
0128 
0129 def test_epic_workflows_validation(tmp_path):
0130     """Validate workflow model."""
0131     config_path = tmp_path / "epic_workflow.config"
0132     config_path.write_text(yaml.safe_dump(_sample_epic_workflow_payload()))
0133 
0134     payload = None
0135     with open(config_path, 'r') as data:
0136         payload = yaml.safe_load(data)
0137     assert payload is not None
0138 
0139     config = EpicWorkflowsConfiguration(**payload)
0140     assert 1 == len(config.workflows)
0141     assert 1 == len(config.workflows[0].branches)
0142     assert 3 == len(config.workflows[0].branches[0].stages)
0143     assert 1 == len(config.workflows[0].branches[0].stages[0].jobs)
0144     assert 1 == len(config.workflows[0].branches[0].stages[1].jobs)
0145     assert 1 == len(config.workflows[0].branches[0].stages[2].jobs)
0146     assert 1 == len(config.workflows[0].branches[0].stages[0].jobs[0].layers)
0147     assert 1 == len(config.workflows[0].branches[0].stages[1].jobs[0].layers)
0148     assert 2 == len(config.workflows[0].branches[0].stages[2].jobs[0].layers)
0149 
0150     # confirm that classes are resolved correctly
0151     assert isinstance(config, EpicWorkflowsConfiguration)
0152     assert isinstance(config.workflows[0], EpicWorkflowDefinition)
0153     assert isinstance(config.workflows[0].branches[0], EpicBranchDefinition)
0154     assert isinstance(config.workflows[0].branches[0].stages[0], EpicStageDefinition)
0155     assert isinstance(config.workflows[0].branches[0].stages[0].jobs[0], EpicJobDefinition)
0156     assert isinstance(config.workflows[0].branches[0].stages[0].jobs[0].layers[0], EpicLayerConfig)
0157 
0158     # check that select info is set correctly
0159     assert "epic" == config.workflows[0].stack_type
0160     assert "photon_phi_resolution" == config.workflows[0].branches[0].name
0161     assert "geo" == config.workflows[0].branches[0].stages[0].name
0162     assert "epic" == config.workflows[0].branches[0].stages[1].jobs[0].payload["stack_type"]
0163     assert "rec" == config.workflows[0].branches[0].stages[2].jobs[0].layers[0].layer
0164     assert "-s 22" == config.workflows[0].branches[0].stages[2].jobs[0].layers[1].arguments[1]
0165 
0166 def test_epic_executor_from_config(tmp_path):
0167     """Create DAGExecutor from epic workflow."""
0168     config_path = tmp_path / "epic_workflow.config"
0169     config_path.write_text(yaml.safe_dump(_sample_epic_workflow_payload()))
0170 
0171     payload = None
0172     with open(config_path, 'r') as data:
0173         payload = yaml.safe_load(data)
0174     assert payload is not None
0175 
0176     config = payload["workflows"][0]
0177     workflow = EpicWorkflowDefinition(**config)
0178     executor = DAGExecutor(workflow, base_output_dir=tmp_path)
0179     assert executor is not None
0180     assert "photon_phi_resolution" == executor.workflow.branches[0].name