@@ -368,47 +368,61 @@ def run(self, scenario: "Scenario") -> None:
368368
369369 # INFO-level outcome summary for workflow users
370370 try :
371- stats = None
371+ from ngraph .monte_carlo .results import DemandPlacementResults
372+
373+ dpr = DemandPlacementResults (
374+ raw_results = results .raw_results ,
375+ iterations = results .iterations ,
376+ baseline = results .baseline ,
377+ failure_patterns = results .failure_patterns ,
378+ metadata = results .metadata ,
379+ )
380+
381+ # Compute per-iteration success rates and summary statistics
382+ dist_df = dpr .success_rate_distribution ()
383+ stats = dpr .summary_statistics () if not dist_df .empty else {}
384+
385+ # Also compute an overall demand-level mean from envelopes for validation
372386 try :
373- from ngraph .monte_carlo .results import DemandPlacementResults
374-
375- dpr = DemandPlacementResults (
376- raw_results = results .raw_results ,
377- iterations = results .iterations ,
378- baseline = results .baseline ,
379- failure_patterns = results .failure_patterns ,
380- metadata = results .metadata ,
387+ envelope_means = [
388+ float (env .get ("mean" , 0.0 )) for env in envelopes .values ()
389+ ]
390+ overall_envelope_mean = (
391+ sum (envelope_means ) / len (envelope_means ) if envelope_means else 0.0
381392 )
382- stats = dpr .summary_statistics ()
383393 except Exception :
384- # Fallback: compute mean from overall_placement_ratio if present
385- ratios = [
386- float (r .get ("overall_placement_ratio" , 0.0 ))
387- for r in results .raw_results .get ("results" , [])
388- if isinstance (r , dict )
389- ]
390- if ratios :
391- import statistics
394+ overall_envelope_mean = 0.0
392395
393- stats = {
394- "mean" : float (statistics .mean (ratios )),
395- "min" : float (min (ratios )),
396- "max" : float (max (ratios )),
397- }
396+ # Add a concise per-step summary object to the results store
397+ scenario .results .put (
398+ self .name ,
399+ "placement_summary" ,
400+ {
401+ "iterations" : int (results .metadata .get ("iterations" , 0 )),
402+ "parallelism" : int (
403+ results .metadata .get (
404+ "parallelism" , self ._resolve_parallelism (self .parallelism )
405+ )
406+ ),
407+ "baseline" : bool (results .metadata .get ("baseline" , False )),
408+ "alpha" : float (step_metadata .get ("alpha" , 1.0 )),
409+ "alpha_source" : step_metadata .get ("alpha_source" , None ),
410+ "demand_count" : len (envelopes ),
411+ "success_rate_stats" : stats or {},
412+ "overall_envelope_mean" : float (overall_envelope_mean ),
413+ },
414+ )
398415
416+ # Prepare INFO log with consistent fields
399417 meta = results .metadata or {}
400418 iterations = int (meta .get ("iterations" , self .iterations ))
401419 workers = int (
402420 meta .get ("parallelism" , self ._resolve_parallelism (self .parallelism ))
403421 )
404- # Alpha transparency: print effective alpha and its source (explicit or MSD:<step>)
405422 try :
406423 alpha_value = float (step_metadata .get ("alpha" )) # type: ignore[arg-type]
407424 except Exception :
408- try :
409- alpha_value = float (effective_alpha )
410- except Exception :
411- alpha_value = 1.0
425+ alpha_value = float (effective_alpha ) if effective_alpha else 1.0
412426 alpha_source = (
413427 step_metadata .get ("alpha_source" )
414428 if isinstance (step_metadata , dict )
@@ -419,21 +433,30 @@ def run(self, scenario: "Scenario") -> None:
419433 if alpha_source
420434 else ("explicit" if not isinstance (self .alpha , str ) else "auto" )
421435 )
436+
437+ mean_v = float (stats .get ("mean" , 0.0 )) if stats else 0.0
438+ p50_v = float (stats .get ("p50" , 0.0 )) if stats else 0.0
439+ p95_v = float (stats .get ("p95" , 0.0 )) if stats else 0.0
440+ min_v = float (stats .get ("min" , 0.0 )) if stats else 0.0
441+ max_v = float (stats .get ("max" , 0.0 )) if stats else 0.0
442+
422443 logger .info (
423- "Placement summary: name=%s alpha=%.6g source=%s demands=%d iters=%d workers=%d ratio_mean =%.3f p50=%.3f p95=%.3f min=%.3f max=%.3f " ,
444+ "Placement summary: name=%s alpha=%.6g source=%s demands=%d iters=%d workers=%d iter_mean =%.4f p50=%.4f p95=%.4f min=%.4f max=%.4f env_mean=%.4f " ,
424445 self .name ,
425446 alpha_value ,
426447 alpha_source_str ,
427448 len (envelopes ),
428449 iterations ,
429450 workers ,
430- float (stats .get ("mean" , 0.0 )) if stats else 0.0 ,
431- float (stats .get ("p50" , 0.0 )) if stats else 0.0 ,
432- float (stats .get ("p95" , 0.0 )) if stats else 0.0 ,
433- float (stats .get ("min" , 0.0 )) if stats else 0.0 ,
434- float (stats .get ("max" , 0.0 )) if stats else 0.0 ,
451+ mean_v ,
452+ p50_v ,
453+ p95_v ,
454+ min_v ,
455+ max_v ,
456+ overall_envelope_mean ,
435457 )
436458 except Exception :
459+ # Logging must not raise
437460 pass
438461
439462 logger .info (
0 commit comments