diff --git a/MonteCarloMarginalizeCode/Code/RIFT/integrators/multivariate_truncnorm.py b/MonteCarloMarginalizeCode/Code/RIFT/integrators/multivariate_truncnorm.py index f94f7d83..f248a40e 100644 --- a/MonteCarloMarginalizeCode/Code/RIFT/integrators/multivariate_truncnorm.py +++ b/MonteCarloMarginalizeCode/Code/RIFT/integrators/multivariate_truncnorm.py @@ -44,8 +44,8 @@ def _get_new_bounds(bounds, q): index += 1 new_bounds = np.empty((d, 2)) for dim in range(d): - new_bounds[dim][0] = min(new_points[:,[dim]]) - new_bounds[dim][1] = max(new_points[:,[dim]]) + new_bounds[dim][0] = min(new_points[:, dim]) + new_bounds[dim][1] = max(new_points[:, dim]) return new_bounds diff --git a/MonteCarloMarginalizeCode/Code/RIFT/simulation_manager/PBSManager.py b/MonteCarloMarginalizeCode/Code/RIFT/simulation_manager/PBSManager.py new file mode 100644 index 00000000..c60fdf35 --- /dev/null +++ b/MonteCarloMarginalizeCode/Code/RIFT/simulation_manager/PBSManager.py @@ -0,0 +1,136 @@ +import sys, os +import subprocess +import re +import logging +import RIFT.simulation_manager.BaseManager as bm + +logger = logging.getLogger(__name__) + +def default_pbs_build_job(tag='job_tag_default_pbs', exe=None, arg_str=None, sim_path=None, pbs_args=None, array_range=None, **kwargs): + """ + Builds a PBS submit script. + pbs_args: dict of PBS options, e.g., {'queue': 'workq', 'walltime': '01:00:00', 'nodes': '1:ppn=1'} + array_range: PBS array job specification, e.g., '1-10' or '1-10:2' (step size) + """ + if pbs_args is None: + pbs_args = {} + + # Standard PBS headers + script_lines = ["#!/bin/bash", "#PBS -N " + tag] + + # Add array job directive if specified + if array_range: + script_lines.append(f"#PBS -J {array_range}") + + # Add custom PBS arguments + if 'queue' in pbs_args: + script_lines.append(f"#PBS -q {pbs_args['queue']}") + if 'walltime' in pbs_args: + script_lines.append(f"#PBS -l walltime={pbs_args['walltime']}") + if 'nodes' in pbs_args: + script_lines.append(f"#PBS -l {pbs_args['nodes']}") + if 'mem' in pbs_args: + script_lines.append(f"#PBS -l mem={pbs_args['mem']}") + + script_lines.append("") # newline + script_lines.append(f"cd $PBS_O_WORKDIR") + script_lines.append(f"{exe} {arg_str}") + + script_content = "\n".join(script_lines) + return script_content, tag + ".pbs_sub" + +class SimulationArchiveOnLocalDiskIntegratedPBSQueue(bm.SimulationArchiveOnLocalDiskExternalQueue): + """ + Simulation archive whose entries are queued and run via PBS/Larus. + """ + def __init__(self, **kwargs): + self._internal_build_submit = default_pbs_build_job + self._internal_exe = 'echo' + self._internal_job_id = None + self._internal_simulations_have_sub_directories = True + super().__init__(**kwargs) + + if not os.path.exists(self.base_location + "/logs"): + os.mkdir(self.base_location + "/logs") + if not os.path.exists(self.base_location + "/pbs_submit_files/"): + os.mkdir(self.base_location + "/pbs_submit_files/") + + def generate_simulation(self, sim_params, **kwargs): + return self.register_simulation(sim_params, **kwargs) + + def build_single_job(self, tag=None, **kwargs): + """Builds and writes a single PBS submit script.""" + build_args = {} + build_args.update(kwargs) + + script_content, script_name = self._internal_build_submit(tag=tag, **build_args) + + full_path = os.path.join(self.base_location, "pbs_submit_files", script_name) + with open(full_path, 'w') as f: + f.write(script_content) + + self._internal_job_id = script_name # Temporary reference + return full_path + + def build_array_job(self, tag=None, array_range='1-10', **kwargs): + """ + Builds and writes a PBS array job submit script. + array_range: PBS array job specification, e.g., '1-10' or '1-10:2' + """ + build_args = dict(kwargs) + build_args['array_range'] = array_range + + script_content, script_name = self._internal_build_submit(tag=tag, **build_args) + + full_path = os.path.join(self.base_location, "pbs_submit_files", script_name) + with open(full_path, 'w') as f: + f.write(script_content) + + self._internal_job_id = script_name + return full_path + + def submit_job(self, script_path): + """Submits a PBS script via qsub and captures the job ID.""" + try: + result = subprocess.run(['qsub', script_path], + capture_output=True, text=True, check=True) + # qsub usually returns the job ID directly to stdout + job_id = result.stdout.strip() + logger.info(" PBS job submitted successfully: %s ", job_id) + return job_id + except subprocess.CalledProcessError as e: + logger.error(" Failed to submit PBS job %s: %s ", script_path, e.stderr) + return None + except FileNotFoundError: + logger.error(" qsub not found on PATH ") + return None + + def refresh_status_from_pbs(self, job_id): + """ + Checks the status of a PBS job using qstat. + Returns 'running' if job is in queue/running, 'complete' if gone (and output exists). + """ + try: + # qstat -f provides full details; -n for numeric IDs + result = subprocess.run(['qstat', '-n', job_id], + capture_output=True, text=True) + + if result.returncode == 0: + # Job is still in the system + return 'running' + else: + # Job is no longer in qstat; check if output exists via _internal_check_complete + return 'complete' + except Exception as exc: + logger.warning(" refresh_status_from_pbs failed for %s: %s ", job_id, exc) + return None + +if __name__ == "__main__": + # Simple smoke test + archive = SimulationArchiveOnLocalDiskIntegratedPBSQueue(name="pbs_test", base_location="pbs_test_dir") + archive.generator = lambda k: k*2 + archive.generate_simulation(0.5) + + # Test build + path = archive.build_single_job(tag="smoke_test", exe="echo", arg_str="hello world") + print(f"PBS script built at: {path}") diff --git a/MonteCarloMarginalizeCode/Code/RIFT/simulation_manager/__init__.py b/MonteCarloMarginalizeCode/Code/RIFT/simulation_manager/__init__.py index 1e441769..96ea9002 100644 --- a/MonteCarloMarginalizeCode/Code/RIFT/simulation_manager/__init__.py +++ b/MonteCarloMarginalizeCode/Code/RIFT/simulation_manager/__init__.py @@ -1 +1 @@ -__all__ = ['BaseManager', 'CondorManager', 'SlurmManager'] +__all__ = ['BaseManager', 'CondorManager', 'PBSManager', 'SlurmManager'] diff --git a/MonteCarloMarginalizeCode/Code/bin/cepp_basic_htcondor b/MonteCarloMarginalizeCode/Code/bin/cepp_basic_htcondor index 330d1c24..4b955a0b 100755 --- a/MonteCarloMarginalizeCode/Code/bin/cepp_basic_htcondor +++ b/MonteCarloMarginalizeCode/Code/bin/cepp_basic_htcondor @@ -1,6 +1,6 @@ #! /usr/bin/env python import htcondor2 as htcondor -from htcondor2.dags import DAG, Node +from htcondor2.dags import DAG # # GOAL # Simple pipeline: just ILE+fitting iteration jobs diff --git a/docs/source/api_reference/asimov/asimov_production.rst b/docs/source/api_reference/asimov/asimov_production.rst index 788eb1ea..03bef40b 100644 --- a/docs/source/api_reference/asimov/asimov_production.rst +++ b/docs/source/api_reference/asimov/asimov_production.rst @@ -114,7 +114,6 @@ Apply the base infrastructure configuration. These define the cluster, accountin - Base Singularity image 2. **cbcflow/testing.yaml**: cbcflow configuration - - Workflow manager settings 3. **production-pe-priors.yaml**: Prior distributions - Default prior settings for mass, spin, etc. @@ -122,7 +121,7 @@ Apply the base infrastructure configuration. These define the cluster, accountin Stage 4: cbcflow Integration ^^^^^^^^^^^^^^^^^^^^^^^^^^^ -cbcflow manages the overall workflow for production PE. It coordinates multiple pipelines and handles result aggregation: +cbcflow provides metadata about identified event candidates and internal understanding of them, recording state about previous investigations: .. code-block:: bash @@ -135,10 +134,10 @@ cbcflow manages the overall workflow for production PE. It coordinates multiple **What cbcflow does:** -- Coordinates data retrieval (graceDB) -- Manages multiple PE pipelines -- Handles result merging and aggregation -- Generates summary pages +`cbcflow documentation `_ provides: + +- **Metadata for superevents**, stored in a standardized format. +- **A Python API** for interacting with that metadata. Stage 5: Output Configuration ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -193,12 +192,12 @@ Define a function to add events. This is the core of the multi-event pattern: **What each blueprint provides:** -- **o4b-production.yaml**: Data retrieval from graceDB -- **standard.yaml**: PE configurator settings -- **standard-settings.yaml**: Bayeswave PSD settings -- **analysis_rift_SEOBNRv5PHM.yaml**: RIFT with SEOBNRv5PHM waveform -- **analysis_rift_NRSur7dq4.yaml**: RIFT with NRSur7dq4 waveform -- **bilby analyses**: Bilby with various waveforms (for cross-validation) +* `o4b-production.yaml `_: This blueprint provides analyses to retrieve calibration and the online PE results (needed to set priors) +* `pe-configurator/standard.yaml `_: PE configurator settings needed to set the priors +* `bayeswave-psd/standard-settings.yaml `_: Bayeswave PSD settings +* `analysis_rift_SEOBNRv5PHM.yaml`: RIFT with SEOBNRv5PHM waveform +* `analysis_rift_NRSur7dq4.yaml`: RIFT with NRSur7dq4 waveform +* `bilby analyses`: Bilby with various waveforms (for cross-validation) Stage 8: Event Loop ^^^^^^^^^^^^^^^^^^ diff --git a/docs/source/api_reference/asimov/asimov_simple.rst b/docs/source/api_reference/asimov/asimov_simple.rst index 61b3114b..395eb961 100644 --- a/docs/source/api_reference/asimov/asimov_simple.rst +++ b/docs/source/api_reference/asimov/asimov_simple.rst @@ -138,7 +138,7 @@ Label to Argument Mapping (rift.ini) The authoritative ``rift.ini`` template is located at: -`MonteCarloMarginalizeCode/Code/RIFT/asimov/rift.ini `_ in this repository. +`MonteCarloMarginalizeCode/Code/RIFT/asimov/rift.ini `_ in this repository. .. _asimov-rift-example: diff --git a/docs/source/api_reference/calmarg.rst b/docs/source/api_reference/calmarg.rst new file mode 100644 index 00000000..6289a9aa --- /dev/null +++ b/docs/source/api_reference/calmarg.rst @@ -0,0 +1,19 @@ +Calibration Marginalization API Reference +=========================================== + +This module provides tools for performing calibration marginalization in RIFT, allowing for the estimation of parameters while accounting for uncertainty in the calibration. + +.. automodule:: RIFT.calmarg + :members: + :undoc-members: + :show-inheritance: + +.. automodule:: RIFT.calmarg.generate_realizations + :members: + :undoc-members: + :show-inheritance: + +.. automodule:: RIFT.calmarg.rift_source + :members: + :undoc-members: + :show-inheritance: diff --git a/docs/source/api_reference/calmarg/index.rst b/docs/source/api_reference/calmarg/index.rst index 6df454f2..edb274ae 100644 --- a/docs/source/api_reference/calmarg/index.rst +++ b/docs/source/api_reference/calmarg/index.rst @@ -1,7 +1 @@ -Calibration Marginalization -=========================== - -.. automodule:: RIFT.calmarg - :members: - :undoc-members: - :show-inheritance: \ No newline at end of file +.. include:: ../calmarg.rst diff --git a/docs/source/api_reference/index.rst b/docs/source/api_reference/index.rst index 788abbdf..f6a68c61 100644 --- a/docs/source/api_reference/index.rst +++ b/docs/source/api_reference/index.rst @@ -14,7 +14,7 @@ Core RIFT Modules plot_utilities/index simulation_manager/index asimov/index - calmarg/index + calmarg misc/index lalsimutils diff --git a/docs/source/api_reference/physics/EOBTidalExternal.rst b/docs/source/api_reference/physics/EOBTidalExternal.rst new file mode 100644 index 00000000..71d656a7 --- /dev/null +++ b/docs/source/api_reference/physics/EOBTidalExternal.rst @@ -0,0 +1,7 @@ +EOBTidalExternal API Reference +============================== + +.. automodule:: RIFT.physics.EOBTidalExternal + :members: + :undoc-members: + :show-inheritance: diff --git a/docs/source/api_reference/physics/EOBTidalExternalC.rst b/docs/source/api_reference/physics/EOBTidalExternalC.rst new file mode 100644 index 00000000..0147c72f --- /dev/null +++ b/docs/source/api_reference/physics/EOBTidalExternalC.rst @@ -0,0 +1,7 @@ +EOBTidalExternalC API Reference +================================ + +.. automodule:: RIFT.physics.EOBTidalExternalC + :members: + :undoc-members: + :show-inheritance: diff --git a/docs/source/api_reference/physics/EOSManager.rst b/docs/source/api_reference/physics/EOSManager.rst new file mode 100644 index 00000000..fc8036af --- /dev/null +++ b/docs/source/api_reference/physics/EOSManager.rst @@ -0,0 +1,7 @@ +EOSManager API Reference +========================== + +.. automodule:: RIFT.physics.EOSManager + :members: + :undoc-members: + :show-inheritance: diff --git a/docs/source/api_reference/physics/MonotonicSpline.rst b/docs/source/api_reference/physics/MonotonicSpline.rst new file mode 100644 index 00000000..4efdd95c --- /dev/null +++ b/docs/source/api_reference/physics/MonotonicSpline.rst @@ -0,0 +1,7 @@ +MonotonicSpline API Reference +=============================== + +.. automodule:: RIFT.physics.MonotonicSpline + :members: + :undoc-members: + :show-inheritance: diff --git a/docs/source/api_reference/physics/PrecessingFisherMatrix.rst b/docs/source/api_reference/physics/PrecessingFisherMatrix.rst new file mode 100644 index 00000000..bf548dc7 --- /dev/null +++ b/docs/source/api_reference/physics/PrecessingFisherMatrix.rst @@ -0,0 +1,7 @@ +PrecessingFisherMatrix API Reference +====================================== + +.. automodule:: RIFT.physics.PrecessingFisherMatrix + :members: + :undoc-members: + :show-inheritance: diff --git a/docs/source/api_reference/physics/ROMWaveformManager.rst b/docs/source/api_reference/physics/ROMWaveformManager.rst new file mode 100644 index 00000000..df3a4901 --- /dev/null +++ b/docs/source/api_reference/physics/ROMWaveformManager.rst @@ -0,0 +1,7 @@ +ROMWaveformManager API Reference +================================== + +.. automodule:: RIFT.physics.ROMWaveformManager + :members: + :undoc-members: + :show-inheritance: diff --git a/docs/source/api_reference/physics/effectiveFisher.rst b/docs/source/api_reference/physics/effectiveFisher.rst new file mode 100644 index 00000000..c2c0db61 --- /dev/null +++ b/docs/source/api_reference/physics/effectiveFisher.rst @@ -0,0 +1,7 @@ +Effective Fisher API Reference +================================ + +.. automodule:: RIFT.physics.effectiveFisher + :members: + :undoc-members: + :show-inheritance: diff --git a/docs/source/api_reference/physics/index.rst b/docs/source/api_reference/physics/index.rst index 561b17f2..bb724104 100644 --- a/docs/source/api_reference/physics/index.rst +++ b/docs/source/api_reference/physics/index.rst @@ -1,7 +1,14 @@ -Physics Utilities -================== +Physics API Reference +===================== -.. automodule:: RIFT.physics - :members: - :undoc-members: - :show-inheritance: \ No newline at end of file +.. toctree:: + :maxdepth: 1 + + EOBTidalExternal + EOBTidalExternalC + EOSManager + GWSignal + MonotonicSpline + PrecessingFisherMatrix + ROMWaveformManager + effectiveFisher \ No newline at end of file