Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2026-11-09 09:29:53

0001 """dRICH example workflow payloads and objective calculations."""
0002 
0003 from pathlib import Path
0004 
0005 import numpy as np
0006 
0007 
0008 # Trial paths and filenames
0009 
0010 
0011 def sim_reco_files(sim_dir, npart, trial_tag, point, particle):
0012     """Return simulation and reconstruction file paths for one scan point."""
0013     tag = (
0014         f"{npart}_{trial_tag}_{particle}_p_{point['p']}_"
0015         f"eta_{point['eta_min']}_{point['eta_max']}"
0016     )
0017     return Path(sim_dir) / f"scan_{tag}.root", Path(sim_dir) / f"recon_scan_{tag}.root"
0018 
0019 
0020 def analysis_result_file(results_dir, npart, trial_tag, point):
0021     """Return the analysis text output for one scan point."""
0022     return (
0023         Path(results_dir)
0024         / f"recon_scan_{npart}_{trial_tag}_p_{point['p']}_"
0025         f"eta_{point['eta_min']}_{point['eta_max']}.txt"
0026     )
0027 
0028 
0029 def _trial_context(problem_config, workflow_context):
0030     """Return inputs from the shared workflow context."""
0031     if problem_config is None:
0032         raise ValueError("dRICH payloads require problem_config")
0033     if problem_config.evaluation_config is None:
0034         raise ValueError("dRICH payloads require problem.evaluation_config")
0035 
0036     eval_config = problem_config.evaluation_config
0037     trial_index = workflow_context.get("trial_index")
0038     if trial_index is None:
0039         raise ValueError("dRICH payloads require trial_index")
0040     output_dir = Path(workflow_context["output_dir"])
0041     paths = {
0042         "results_dir": output_dir / "ana",
0043         "sim_dir": output_dir / "sim_rec",
0044     }
0045     return eval_config, trial_index, paths
0046 
0047 
0048 # Objective aggregation
0049 
0050 
0051 def aggregate_objectives(*, problem_config, workflow_context, **_):
0052     """Return objectives for a framework objective-plan step."""
0053     eval_config, trial_index, paths = _trial_context(
0054         problem_config,
0055         workflow_context,
0056     )
0057     particle_count = eval_config["npart"]
0058     scan_points = eval_config["scan_points"]
0059     results = np.array(
0060         [
0061             np.loadtxt(
0062                 analysis_result_file(
0063                     paths["results_dir"],
0064                     particle_count,
0065                     str(trial_index),
0066                     point,
0067                 )
0068             )
0069             for point in scan_points
0070         ]
0071     )
0072     momenta = np.array([point["p"] for point in scan_points])
0073     metric_values = (
0074         ("piKsep_etalow", results[momenta == 15, 2], results[momenta == 15, 3]),
0075         ("piKsep_etahigh", results[momenta == 45, 2], results[momenta == 45, 3]),
0076         ("acceptance", results[1:, 0], results[1:, 1]),
0077     )
0078     metrics = {}
0079     for name, values, errors in metric_values:
0080         metrics[name] = float(np.mean(values))
0081         metrics[f"{name}_err"] = float(np.linalg.norm(errors) / len(errors))
0082 
0083     if any(np.isnan(value) for value in metrics.values()):
0084         raise RuntimeError(f"NaN objective for trial {trial_index}")
0085 
0086     return metrics
0087 
0088 
0089 # Workflow payloads
0090 
0091 
0092 def sim_rec_payloads(*, problem_config, workflow_context, **_):
0093     """Return payload records for simulation/reconstruction jobs."""
0094     eval_config, trial_index, paths = _trial_context(
0095         problem_config,
0096         workflow_context,
0097     )
0098     trial_tag = str(trial_index)
0099     particle_count = eval_config["npart"]
0100     records = []
0101     for point in eval_config["scan_points"]:
0102         for particle in eval_config["particles"]:
0103             sim_file, reco_file = sim_reco_files(
0104                 paths["sim_dir"],
0105                 particle_count,
0106                 trial_tag,
0107                 point,
0108                 particle,
0109             )
0110             records.append(
0111                 {
0112                     "npart": particle_count,
0113                     "particle": particle,
0114                     "p": point["p"],
0115                     "eta_min": point["eta_min"],
0116                     "eta_max": point["eta_max"],
0117                     "sim_file": str(sim_file),
0118                     "reco_file": str(reco_file),
0119                 }
0120             )
0121     return records
0122 
0123 
0124 def ana_payloads(*, problem_config, workflow_context, **_):
0125     """Return payload records for analysis jobs."""
0126     eval_config, trial_index, paths = _trial_context(
0127         problem_config,
0128         workflow_context,
0129     )
0130     trial_tag = str(trial_index)
0131     particle_count = eval_config["npart"]
0132 
0133     records = []
0134     for point in eval_config["scan_points"]:
0135         records.append(
0136             {
0137                 "radiator": point["radiator"],
0138                 "bootstrap_samples": eval_config["bootstrap_samples"],
0139                 "nbootstraps": eval_config["nbootstraps"],
0140                 "ana_inputs": " ".join(
0141                     str(
0142                         sim_reco_files(
0143                             paths["sim_dir"],
0144                             particle_count,
0145                             trial_tag,
0146                             point,
0147                             particle,
0148                         )[1]
0149                     )
0150                     for particle in eval_config["particles"]
0151                 ),
0152                 "analysis_output": str(
0153                     analysis_result_file(
0154                         paths["results_dir"],
0155                         particle_count,
0156                         trial_tag,
0157                         point,
0158                     )
0159                 ),
0160             }
0161         )
0162     return records