Rigorous.CurrentStateUtils#
Rigorous.CurrentStateUtils.py
- class JobInfo(id, iterations, best_fv, timestamp)#
Bases:
tupleMetadata for a single rigorous optimization job.
Attributes: id, iterations, best_fv, timestamp.
Create new instance of JobInfo(id, iterations, best_fv, timestamp)
- best_fv#
Alias for field number 2
- id#
Alias for field number 0
- iterations#
Alias for field number 1
- timestamp#
Alias for field number 3
- class JobConvergence(id, evals, fvs, best_fv, best_sv, timestamps)#
Bases:
tuplePer-job convergence detail with full fv trajectory.
Attributes: id, evals (list of eval counts), fvs (list of fv values), best_fv, best_sv, timestamps (list of datetimes).
Create new instance of JobConvergence(id, evals, fvs, best_fv, best_sv, timestamps)
- best_fv#
Alias for field number 3
- best_sv#
Alias for field number 4
- evals#
Alias for field number 1
- fvs#
Alias for field number 2
- id#
Alias for field number 0
- timestamps#
Alias for field number 5
- class ConvergenceInfo(jobs, best_fv, best_sv, best_job_id, spread, trend, n_jobs)#
Bases:
tupleSummary of convergence across all jobs.
Attributes: jobs (list of JobConvergence), best_fv, best_sv, best_job_id, spread, trend (‘improving’/’worsening’/’stable’), n_jobs.
Create new instance of ConvergenceInfo(jobs, best_fv, best_sv, best_job_id, spread, trend, n_jobs)
- best_fv#
Alias for field number 1
- best_job_id#
Alias for field number 3
- best_sv#
Alias for field number 2
- jobs#
Alias for field number 0
- n_jobs#
Alias for field number 6
- spread#
Alias for field number 4
- trend#
Alias for field number 5
- fv_to_sv(fv)#
Convert objective function value (fv) to Score Value (SV, 0-100 scale).
The raw optimizer objective fv is negative and nonlinear, making it hard to interpret. SV maps it to a human-readable 0-100 quality scale via:
SV = -200 / (1 + exp(-1.5 * fv)) + 100
- Quality thresholds:
SV >= 80 : Good (green in plot_convergence) SV 60-80 : Fair (orange) SV < 60 : Poor (red)
- Reference points:
fv = -3 -> SV ~= 98 fv = -1 -> SV ~= 64 fv = 0 -> SV = 0
Can also be applied to individual score values (not just the total fv) to identify which objectives are bottlenecks.
- construct_decomposition_from_results(run_info, **kwargs)#
- load_rigorous_result(decomp, analysis_folder, jobid=None, rgcurve=None, debug=False)#
Load a rigorous optimization result from disk without launching a subprocess.
This is the static result viewer: it reads the saved parameter vector from a completed job’s
callback.txtand reconstructs theDecompositionusing a lightweight (for_split_only) optimizer that only knows how to split parameters.- Parameters:
decomp (Decomposition) – The initial (quick) decomposition that was used as the starting point for rigorous optimization. Provides
ssd,num_components, model type, and baseline information.analysis_folder (str) – Path to the analysis folder used during optimization (same value passed to
optimize_rigorously(analysis_folder=...)).jobid (str, optional) – Specific job id to load (subfolder name under
optimized/jobs/). IfNone, loads the latest (last sorted) job.rgcurve (RgCurve, optional) – Pre-computed Rg curve. When provided, skips the expensive per-frame Guinier fitting that
ssd.xr.compute_rgcurve()would perform.debug (bool, optional) – If True, reload modules from disk.
- Returns:
A new Decomposition built from the optimized parameters.
- Return type:
Examples
After re-running cells 1-4 to restore
corrected,decomp,rgcurve:from molass.Rigorous.CurrentStateUtils import load_rigorous_result result = load_rigorous_result(decomp, "temp_analysis_scaffolded") result.plot_components(rgcurve=rgcurve)
- list_rigorous_jobs(analysis_folder)#
List completed rigorous optimization jobs on disk.
Scans the
analysis_folder/optimized/jobs/directory and returns metadata for each job that has acallback.txtfile.- Parameters:
analysis_folder (str) – The same
analysis_folderpassed tooptimize_rigorously().- Returns:
Each entry is a
JobInfo(id, iterations, best_fv, timestamp)namedtuple. The list is sorted by job id.- Return type:
Examples
jobs = decomp.list_rigorous_jobs("temp_analysis_scaffolded") for job in jobs: print(f"Job {job.id}: {job.iterations} iters, best fv={job.best_fv:.4f}")
- has_rigorous_results(analysis_folder)#
Check whether any rigorous optimization results are available.
This is a lightweight filesystem check — it does not parse results. Use this to poll readiness before calling
load_rigorous_result()orlist_rigorous_jobs().- Parameters:
analysis_folder (str) – The same
analysis_folderpassed tooptimize_rigorously().- Returns:
Trueif at least one job has written acallback.txtfile.- Return type:
Examples
if decomp.has_rigorous_results("temp_analysis"): result = decomp.load_rigorous_result("temp_analysis")
- wait_for_rigorous_results(analysis_folder, timeout=600, poll_interval=5)#
Block until rigorous optimization results become available.
Polls the filesystem at regular intervals until at least one job has a parseable
callback.txtfile, or the timeout is reached.Note: this checks
list_rigorous_jobs()(not just file existence) to avoid a race condition where the file is created but not yet written.- Parameters:
- Returns:
Trueif results appeared before timeout,Falseif timed out.- Return type:
Examples
decomp.optimize_rigorously(analysis_folder="temp", ...) if Decomposition.wait_for_rigorous_results("temp"): result = decomp.load_rigorous_result("temp") else: print("Timed out waiting for results.")
- parse_sv_history(analysis_folder)#
Parse all
callback.txtfiles and return the SV best-so-far trajectory.This is the pure data-extraction layer shared by
check_progress()andRunInfo.sv_history. No printing, no file writes.
- parse_sv_history_per_job(analysis_folder)#
Parse
callback.txtfiles and return per-job SV best-so-far trajectories.Like
parse_sv_history()but preserves job boundaries. Each job’s SV sequence starts fresh from its own first accepted evaluation but inherits the global running minimum from all preceding jobs.- Parameters:
analysis_folder (str) – Root folder for optimizer output (contains
optimized/jobs/).- Returns:
Mapping from job id (e.g.
'000','001') to the list of global best-SV-so-far values recorded within that job. Jobs with no accepted evaluations are omitted. Empty dict if no evaluations are recorded yet.- Return type:
Examples
per_job = parse_sv_history_per_job(run_info.analysis_folder) for job_id, svs in per_job.items(): print(f"job {job_id}: {len(svs)} evals, best SV = {svs[-1]:.1f}")
- check_progress(run_info_or_folder, label=None, write_snapshot=False)#
Read callback.txt(s) from all jobs and report best SV so far.
Re-runnable at any time while the optimizer is running or after it completes. Accepts either a
RunInfoobject or a plain folder path string, so it works even when the caller holds an olderRunInfoinstance from a previous session.- Parameters:
run_info_or_folder (RunInfo or str) – A
RunInfoobject (uses itsanalysis_folderattribute) or a plainanalysis_folderpath string.label (str, optional) – Display label prefix. Defaults to the basename of the analysis folder.
write_snapshot (bool, optional) –
If
True, write a compact JSON file to<analysis_folder>/optimized/progress_snapshot.jsonin addition to printing. The file can be read back later — even from a new AI session — viaRunInfo.load_progress_snapshot()orjson.load(open(...)):_run_sub.check_progress(write_snapshot=True) snap = _run_sub.load_progress_snapshot() # dict
Default
False(print-only, no side effects).
- Returns:
Progress data dict when there are evaluations to report;
Noneotherwise. Keys:label,n_evals,best_fv,best_sv,sv_best_so_far(full list),timestamp(ISO 8601 UTC).- Return type:
dict or None
Examples
# Via the RunInfo method (requires current class): _run_sub.check_progress(label="subprocess") # Persist for later AI-session retrieval: snap = _run_sub.check_progress(write_snapshot=True) # Via the standalone function (works with any RunInfo or a folder path): from molass.Rigorous import check_progress check_progress(_run_sub, label="subprocess") check_progress("/path/to/analysis_folder") # plain string also accepted
- read_convergence_data(analysis_folder)#
Read convergence data from all completed rigorous optimization jobs.
- Parameters:
analysis_folder (str) – The same
analysis_folderpassed tooptimize_rigorously().- Returns:
Summary with per-job trajectories and cross-job diagnostics. Key fields for programmatic assessment:
best_fv— global best objective valuespread— difference between worst and best job’s best_fvtrend—'improving','worsening', or'stable'jobs— list ofJobConvergencewith full fv trajectories
- Return type:
Examples
info = Decomposition.plot_convergence("temp_analysis") print(f"Best fv: {info.best_fv:.4f}, spread: {info.spread:.6f}") print(f"Trend: {info.trend}")
- plot_convergence(analysis_folder, ax=None, title=None)#
Plot convergence across rigorous optimization jobs.
Left subplot: best fv per job (cross-job trend). Right subplot: fv trajectory within each job (overlaid).
- Parameters:
- Returns:
The convergence data (same as
read_convergence_data()), so the caller can inspect values programmatically.- Return type:
Examples
info = Decomposition.plot_convergence("temp_analysis") print(f"Best: {info.best_fv:.4f}, trend: {info.trend}")