Skip to content

Commit 1369f14

Browse files
authored
Merge pull request #17 from codegithubka/Sary
prompt doc update
2 parents da4bb43 + 4c82f73 commit 1369f14

3 files changed

Lines changed: 479 additions & 31 deletions

File tree

docs/sary_prompts.md

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -941,3 +941,15 @@ Examples:
941941
if __name__ == "__main__":
942942
main()
943943

944+
(Phase 1 and 1.5) (Criticality)
945+
Statistical Test For Power Law using power law package
946+
Bifurcation
947+
Cluster size distribution
948+
949+
(Phase 2): (Self orgaization)
950+
Box plots (x axis-inital death rate, y axis - final or converged death rate)
951+
952+
(Phase 3): (Finite Size)
953+
log log plots of cluster size disstribution with cutoff (because of grid size)
954+
955+
(Phase 4): Sensitivity

scripts/analysis.py

Lines changed: 83 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -125,16 +125,19 @@ def load_sensitivity_results(results_dir: Path) -> List[Dict]:
125125
return json.load(f)
126126

127127

128-
def load_bifurcation_results(results_dir: Path) -> Tuple[np.ndarray, np.ndarray]:
128+
def load_bifurcation_results(results_dir: Path) -> Tuple[np.ndarray, np.ndarray, np.ndarray]:
129129
"""
130130
Load bifurcation analysis results.
131131
132132
Returns
133133
-------
134134
sweep_params : np.ndarray
135135
1D array of control parameter values (prey death rates).
136-
results : np.ndarray
137-
2D array of shape (n_sweep, n_replicates) with population counts
136+
prey_results : np.ndarray
137+
2D array of shape (n_sweep, n_replicates) with prey population counts
138+
at equilibrium.
139+
predator_results : np.ndarray
140+
2D array of shape (n_sweep, n_replicates) with predator population counts
138141
at equilibrium.
139142
"""
140143
npz_file = results_dir / "bifurcation_results.npz"
@@ -143,12 +146,27 @@ def load_bifurcation_results(results_dir: Path) -> Tuple[np.ndarray, np.ndarray]
143146
if npz_file.exists():
144147
logging.info(f"Loading bifurcation results from {npz_file}")
145148
data = np.load(npz_file)
146-
return data['sweep_params'], data['results']
149+
# Handle both old format (single 'results') and new format (prey/predator)
150+
if 'prey_results' in data:
151+
return data['sweep_params'], data['prey_results'], data['predator_results']
152+
else:
153+
# Old format - only prey results, create empty predator array
154+
prey_results = data['results']
155+
predator_results = np.full_like(prey_results, np.nan)
156+
return data['sweep_params'], prey_results, predator_results
147157
elif json_file.exists():
148158
logging.info(f"Loading bifurcation results from {json_file}")
149159
with open(json_file, 'r') as f:
150160
data = json.load(f)
151-
return np.array(data['sweep_params']), np.array(data['results'])
161+
# Handle both old and new format
162+
if 'prey_results' in data:
163+
return (np.array(data['sweep_params']),
164+
np.array(data['prey_results']),
165+
np.array(data['predator_results']))
166+
else:
167+
prey_results = np.array(data['results'])
168+
predator_results = np.full_like(prey_results, np.nan)
169+
return np.array(data['sweep_params']), prey_results, predator_results
152170
else:
153171
raise FileNotFoundError(f"Bifurcation results not found in {results_dir}")
154172

@@ -575,12 +593,14 @@ def plot_fss_analysis(fss_results: List[Dict], output_dir: Path, dpi: int = 150)
575593
logging.info(f"Saved {output_file}")
576594

577595

578-
def plot_bifurcation_diagram(sweep_params: np.ndarray, results: np.ndarray,
596+
def plot_bifurcation_diagram(sweep_params: np.ndarray,
597+
prey_results: np.ndarray,
598+
predator_results: np.ndarray,
579599
output_dir: Path, dpi: int = 150,
580600
control_label: str = "Prey Death Rate",
581601
population_label: str = "Population at Equilibrium"):
582602
"""
583-
Generate a stochastic bifurcation diagram.
603+
Generate a stochastic bifurcation diagram for both prey and predator.
584604
585605
Shows the distribution of equilibrium population counts as a function of
586606
a control parameter (e.g., prey death rate), with scatter points for each
@@ -591,10 +611,13 @@ def plot_bifurcation_diagram(sweep_params: np.ndarray, results: np.ndarray,
591611
sweep_params : np.ndarray
592612
1D array of control parameter values (e.g., prey death rates).
593613
Shape: (n_sweep,)
594-
results : np.ndarray
595-
2D array of population counts at equilibrium.
614+
prey_results : np.ndarray
615+
2D array of prey population counts at equilibrium.
596616
Shape: (n_sweep, n_replicates) where rows correspond to sweep_params
597617
and columns are replicate simulation runs.
618+
predator_results : np.ndarray
619+
2D array of predator population counts at equilibrium.
620+
Shape: (n_sweep, n_replicates).
598621
output_dir : Path
599622
Directory to save the output figure.
600623
dpi : int
@@ -604,36 +627,64 @@ def plot_bifurcation_diagram(sweep_params: np.ndarray, results: np.ndarray,
604627
population_label : str
605628
Label for y-axis (population count).
606629
"""
607-
n_sweep, n_replicates = results.shape
630+
n_sweep, n_replicates = prey_results.shape
631+
has_predator_data = not np.all(np.isnan(predator_results))
608632

609-
fig, ax = plt.subplots(figsize=(12, 7))
633+
fig, ax = plt.subplots(figsize=(14, 8))
610634

611635
# Scatter all individual replicates with transparency
636+
# Prey - green tones
612637
for i, param in enumerate(sweep_params):
613638
ax.scatter(
614639
np.full(n_replicates, param),
615-
results[i, :],
616-
alpha=0.3, s=15, c='steelblue', edgecolors='none'
640+
prey_results[i, :],
641+
alpha=0.3, s=15, c='forestgreen', edgecolors='none'
617642
)
618643

619-
# Compute summary statistics
620-
means = np.mean(results, axis=1)
621-
medians = np.median(results, axis=1)
622-
q25 = np.percentile(results, 25, axis=1)
623-
q75 = np.percentile(results, 75, axis=1)
624-
625-
# Plot median line and IQR envelope
626-
ax.fill_between(sweep_params, q25, q75, alpha=0.25, color='coral',
627-
label='IQR (25th-75th percentile)')
628-
ax.plot(sweep_params, medians, 'o-', color='darkred', linewidth=2,
629-
markersize=5, label='Median')
630-
ax.plot(sweep_params, means, 's--', color='black', linewidth=1.5,
631-
markersize=4, alpha=0.7, label='Mean')
644+
# Predator - red tones (if data available)
645+
if has_predator_data:
646+
for i, param in enumerate(sweep_params):
647+
ax.scatter(
648+
np.full(n_replicates, param),
649+
predator_results[i, :],
650+
alpha=0.3, s=15, c='crimson', edgecolors='none'
651+
)
652+
653+
# Compute summary statistics for prey
654+
prey_means = np.mean(prey_results, axis=1)
655+
prey_medians = np.median(prey_results, axis=1)
656+
prey_q25 = np.percentile(prey_results, 25, axis=1)
657+
prey_q75 = np.percentile(prey_results, 75, axis=1)
658+
659+
# Plot prey median line and IQR envelope
660+
ax.fill_between(sweep_params, prey_q25, prey_q75, alpha=0.2, color='green',
661+
label='Prey IQR')
662+
ax.plot(sweep_params, prey_medians, 'o-', color='darkgreen', linewidth=2,
663+
markersize=5, label='Prey Median')
664+
ax.plot(sweep_params, prey_means, 's--', color='forestgreen', linewidth=1.5,
665+
markersize=4, alpha=0.7, label='Prey Mean')
666+
667+
# Compute and plot predator statistics if available
668+
if has_predator_data:
669+
pred_means = np.mean(predator_results, axis=1)
670+
pred_medians = np.median(predator_results, axis=1)
671+
pred_q25 = np.percentile(predator_results, 25, axis=1)
672+
pred_q75 = np.percentile(predator_results, 75, axis=1)
673+
674+
ax.fill_between(sweep_params, pred_q25, pred_q75, alpha=0.2, color='red',
675+
label='Predator IQR')
676+
ax.plot(sweep_params, pred_medians, 'o-', color='darkred', linewidth=2,
677+
markersize=5, label='Predator Median')
678+
ax.plot(sweep_params, pred_means, 's--', color='crimson', linewidth=1.5,
679+
markersize=4, alpha=0.7, label='Predator Mean')
632680

633681
ax.set_xlabel(control_label)
634682
ax.set_ylabel(population_label)
635-
ax.set_title(f"Stochastic Bifurcation Diagram\n({n_replicates} replicates per parameter value)")
636-
ax.legend(loc='best')
683+
title = f"Stochastic Bifurcation Diagram\n({n_replicates} replicates per parameter value)"
684+
if has_predator_data:
685+
title = f"Prey-Predator {title}"
686+
ax.set_title(title)
687+
ax.legend(loc='best', ncol=2)
637688
ax.grid(True, alpha=0.3)
638689

639690
# Add rug plot at bottom showing parameter sampling density
@@ -887,10 +938,11 @@ def main():
887938
# Bifurcation diagram
888939
if plot_all or args.bifurcation_only:
889940
try:
890-
sweep_params, bifurc_results = load_bifurcation_results(results_dir)
941+
sweep_params, prey_results, predator_results = load_bifurcation_results(results_dir)
891942
logging.info(f"Loaded bifurcation results: {len(sweep_params)} sweep values, "
892-
f"{bifurc_results.shape[1]} replicates each")
893-
plot_bifurcation_diagram(sweep_params, bifurc_results, output_dir, args.dpi)
943+
f"{prey_results.shape[1]} replicates each")
944+
plot_bifurcation_diagram(sweep_params, prey_results, predator_results,
945+
output_dir, args.dpi)
894946
except FileNotFoundError as e:
895947
logging.warning(f"Bifurcation results not found: {e}")
896948

0 commit comments

Comments
 (0)