File size: 3,657 Bytes
f5b7025
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
import gradio as gr
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt

# --- QUICK VIEW CALLBACK (new, lightweight) ---
def run_quick_view(file, turn_col, mag_col, rolling_window):
    if file is None:
        return None, "Upload a CSV first."

    df = pd.read_csv(file.name)
    if df.empty:
        return None, "CSV is empty."

    # Resolve turn axis
    use_turn = (turn_col not in [None, "None"] and turn_col in df.columns and pd.api.types.is_numeric_dtype(df[turn_col]))
    if use_turn:
        d = df.sort_values(turn_col).reset_index(drop=True)
        x = d[turn_col].to_numpy()
    else:
        d = df.reset_index(drop=True)
        x = np.arange(len(d)) + 1  # friendlier 1-based index

    # Validate magnitude
    if mag_col not in d.columns or not pd.api.types.is_numeric_dtype(d[mag_col]):
        return None, f"'{mag_col}' is not a numeric magnitude column."

    y = d[mag_col].astype(float).to_numpy()

    w = int(rolling_window)
    w = max(3, min(w, len(d)))
    roll = pd.Series(y).rolling(w, min_periods=max(3, w // 3)).mean().to_numpy()

    fig = plt.figure(figsize=(8, 4.5))
    ax = fig.add_subplot(111)
    ax.scatter(x, y, s=8, alpha=0.6, label="Turns")
    ax.plot(x, roll, label=f"Rolling mean (w={w})")
    ax.set_title(f"Quick View — {mag_col}")
    ax.set_xlabel(turn_col if use_turn else "Turn (row order)")
    ax.set_ylabel("Magnitude")
    ax.legend()
    fig.tight_layout()

    msg = "Quick View: response magnitude over time. Use Advanced tabs for stability bands + perturbations."
    return fig, msg

# --- UPLOAD CALLBACK ---
def on_upload_all(file):
    if file is None:
        # Ensure 'None' is always a possible choice for value=None updates
        return (
            gr.Dropdown.update(choices=[None], value=None),
            gr.Dropdown.update(choices=[None], value=None),
            gr.Dropdown.update(choices=[None], value=None),
            gr.Dropdown.update(choices=[None], value=None),
            gr.Dropdown.update(choices=["None"], value="None"),
            "Please upload a CSV file.",
            pd.DataFrame(),
        )

    try:
        df = pd.read_csv(file.name)
        if df.empty:
            return (
                gr.Dropdown.update(choices=[None], value=None),
                gr.Dropdown.update(choices=[None], value=None),
                gr.Dropdown.update(choices=[None], value=None),
                gr.Dropdown.update(choices=[None], value=None),
                gr.Dropdown.update(choices=["None"], value="None"),
                "CSV is empty.",
                pd.DataFrame(),
            )

        columns = list(df.columns)
        numeric_cols = [col for col in columns if pd.api.types.is_numeric_dtype(df[col])]

        # Ensure 'None' is a selectable option for optional columns where value is None
        dropdown_choices_for_none_value = [None] + columns
        dropdown_choices_for_numeric_none_value = [None] + numeric_cols
        dropdown_choices_for_string_none_value = ["None"] + columns

        # Set default mag_col to the first numeric column if available
        default_mag_col = numeric_cols[0] if numeric_cols else None

        return (
            gr.Dropdown.update(choices=dropdown_choices_for_none_value, value=None),
            gr.Dropdown.update(choices=dropdown_choices_for_none_value, value=None),
            gr.Dropdown.update(choices=dropdown_choices_for_numeric_none_value, value=default_mag_col),
            gr.Dropdown.update(choices=dropdown_choices_for_numeric_none_value, value=None),
            gr.Dropdown.update(choices=dropdown_choices_for_string_none_value, value="None"),
            f