Source code for pycif.plugins.simulators.gausscost.dump

from __future__ import annotations

from logging import warning

import pandas as pd

try:
    import cPickle as pickle
except ImportError:
    import pickle


[docs] def write_cost(self, run_id, j_b, j_o, zcost): """Append one cost-function record to ``cost.txt`` and ``cost.csv``. Args: self (Plugin): simulator plugin instance (provides ``cost_file`` and ``cost_file_csv`` path attributes). run_id (int): minimiser iteration identifier. j_b (float): background cost term :math:`J_b`. j_o (float): observation cost term :math:`J_o`. zcost (float): total cost :math:`J = J_b + J_o`. """ now = pd.Timestamp.now().isoformat() # Legacy txt file with open(self.cost_file, "a") as f: f.write(f"{run_id},{j_b},{j_o},{zcost},{now}\n") # csv file if self.cost_file_csv.exists(): df = pd.read_csv(self.cost_file_csv, index_col="run_id") else: df = pd.DataFrame(columns=["j_b", "j_o", "zcost", "time"]) df.index.name = "run_id" df.loc[run_id, "j_b"] = j_b df.loc[run_id, "j_o"] = j_o df.loc[run_id, "zcost"] = zcost df.loc[run_id, "time"] = now df.to_csv(self.cost_file_csv)
[docs] def write_gradcost(self, run_id, znorm_grad_b, znorm_grad_o, znorm_grad): """Append one gradient-norm record to ``gradcost.txt`` and ``gradcost.csv``. Args: self (Plugin): simulator plugin instance (provides ``gradcost_file`` and ``gradcost_file_csv`` path attributes). run_id (int): minimiser iteration identifier. znorm_grad_b (float): norm of the background gradient :math:`\|\nabla J_b\|`. znorm_grad_o (float): norm of the observation gradient :math:`\|\nabla J_o\|`. znorm_grad (float): norm of the total gradient :math:`\|\nabla J\|`. """ now = pd.Timestamp.now().isoformat() # Legacy txt file with open(self.gradcost_file, "a") as f: f.write(f"{run_id},{znorm_grad_b},{znorm_grad_o},{znorm_grad},{now}\n") # csv file if self.gradcost_file_csv.exists(): df = pd.read_csv(self.gradcost_file_csv, index_col="run_id") else: df = pd.DataFrame( columns=["znorm_grad_b", "znorm_grad_o", "znorm_grad", "time"] ) df.index.name = "run_id" df.loc[run_id, "znorm_grad_b"] = znorm_grad_b df.loc[run_id, "znorm_grad_o"] = znorm_grad_o df.loc[run_id, "znorm_grad"] = znorm_grad df.loc[run_id, "time"] = now df.to_csv(self.gradcost_file_csv)
[docs] def dump_cost( self, run_id: int, j_b: float, j_o: float, zgrad_b: float, zgrad_o: float, ) -> None: """Pickle the cost-function components and gradient vectors for restart. Saves ``(j_b, j_o, zgrad_b, zgrad_o)`` to ``$workdir/simulator/cost_grad.NNNN.pickle`` so that a restarted inversion can skip recomputing the forward and adjoint runs. Args: self (Plugin): simulator plugin instance (provides ``simulator_dir``). run_id (int): minimiser iteration identifier; used to name the file. j_b (float): background cost :math:`J_b`. j_o (float): observation cost :math:`J_o`. zgrad_b (np.ndarray): background gradient component. zgrad_o (np.ndarray): observation gradient component. """ cost_file = self.simulator_dir / f"cost_grad.{run_id:04d}.pickle" with open(cost_file, "wb") as f: pickle.dump((j_b, j_o, zgrad_b, zgrad_o), f)
[docs] def load_cost( self, run_id: int, ) -> tuple[float, float, float, float] | tuple[None, None, None, None]: """Reload the cost-function components and gradient vectors from a pickle file. Looks for ``cost_grad.NNNN.pickle`` (zero-padded) first, then falls back to the legacy non-padded name. Returns four ``None`` values when the file does not exist or cannot be read. Args: self (Plugin): simulator plugin instance (provides ``simulator_dir``). run_id (int): minimiser iteration identifier. Returns: tuple: ``(j_b, j_o, zgrad_b, zgrad_o)`` if the file exists and is readable; ``(None, None, None, None)`` otherwise. """ cost_file = self.simulator_dir / f"cost_grad.{run_id:04d}.pickle" legacy_cost_file = self.simulator_dir / f"cost_grad.{run_id}.pickle" path = cost_file if cost_file.exists() else legacy_cost_file if path.exists(): with open(path, "rb") as f: try: j_b, j_o, zgrad_b, zgrad_o = pickle.load(f) except EOFError: warning(f"Could not load cost function from '{path}'") return None, None, None, None return j_b, j_o, zgrad_b, zgrad_o else: return None, None, None, None