scripts.step_5_visualize_noise_and_kinetics

step_5_visualize_noise_and_kinetics.py

Generates plots
  1. Noise vs mean plots (BFP / mCherry) – empirical time-series
  2. Hill K vs n
  3. Up vs down half-times
  4. Repression vs derepression delays
  5. Hierarchical noise summary (per plasmid / channel / experiment)
  6. Noise vs kinetic parameters (design-guided view)
  7. Time series summaries (mean ± SE) per plasmid
  8. Goodness-of-fit between empirical and hierarchical noise

Requires input CSV files in "parameters/" directory: - Hill_parameters.csv - half_times_upregulation.csv - half_times_downregulation.csv - delays_repression.csv - delays_derepression.csv - single_cell_noise_timeseries.csv - single_cell_noise_hierarchical.csv

compute_ts_summary

compute_ts_summary(noise_ts)

Aggregate single-cell time series to per-(plasmid, time) means and SEs.

Source code in scripts/step_5_visualize_noise_and_kinetics.py
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
def compute_ts_summary(noise_ts: pd.DataFrame) -> pd.DataFrame:
    """
    Aggregate single-cell time series to per-(plasmid, time) means and SEs.
    """

    def agg(group):
        mean_BFP = group["mean_BFP"].mean()
        mean_mC = group["mean_mCherry"].mean()
        se_BFP = np.sqrt((group["var_BFP"] / group["n_cells"]).mean())
        se_mC = np.sqrt((group["var_mCherry"] / group["n_cells"]).mean())
        return pd.Series(
            {
                "mean_BFP": mean_BFP,
                "se_BFP": se_BFP,
                "mean_mCherry": mean_mC,
                "se_mCherry": se_mC,
            }
        )

    summary = (
        noise_ts
        .groupby(["plasmid", "time"], as_index=False)
        .apply(agg, include_groups=False)
    )
    return summary

ensure_outdir

ensure_outdir(path)

Ensure output directory exists.

Parameters:
  • path (Path) –

    Path to the output directory.

Source code in scripts/step_5_visualize_noise_and_kinetics.py
42
43
44
45
46
47
48
49
50
def ensure_outdir(path: Path) -> None:
    """
    Ensure output directory exists.

    Args:
        path (Path): Path to the output directory.
    """

    path.mkdir(parents=True, exist_ok=True)

load_tables

load_tables()

Load all required CSV tables into a dictionary of DataFrames.

  1. Hill parameters
  2. Half-times upregulation
  3. Half-times downregulation
  4. Alpha values
  5. Delays derepression
  6. Delays repression
  7. Single-cell noise time series
  8. Single-cell noise hierarchical
Returns:
  • dict( Dict[str, DataFrame] ) –

    Dictionary of DataFrames keyed by table name.

Source code in scripts/step_5_visualize_noise_and_kinetics.py
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
def load_tables() -> Dict[str, pd.DataFrame]:
    """
    Load all required CSV tables into a dictionary of DataFrames.

    1. Hill parameters
    2. Half-times upregulation
    3. Half-times downregulation
    4. Alpha values
    5. Delays derepression
    6. Delays repression
    7. Single-cell noise time series
    8. Single-cell noise hierarchical

    Returns:
        dict: Dictionary of DataFrames keyed by table name.
    """
    hill = pd.read_csv(PARAM_PATH / "Hill_parameters.csv")  # plasmid, K, n
    up = pd.read_csv(PARAM_PATH / "half_times_upregulation.csv")  # plasmid, halftime, se
    down = pd.read_csv(PARAM_PATH / "half_times_downregulation.csv")  # plasmid, halftime, se
    alpha = pd.read_csv(PARAM_PATH / "alphamcherry.csv")  # alpha
    delays_de = pd.read_csv(PARAM_PATH / "delays_derepression.csv")  # plasmid, d_rev
    delays_rep = pd.read_csv(PARAM_PATH / "delays_repression.csv")  # plasmid, d_rev
    design = pd.read_csv(PARAM_PATH / "design_space_scan_repression.csv")  # not used here
    noise_ts = pd.read_csv(PARAM_PATH / "single_cell_noise_timeseries.csv")
    noise_hier = pd.read_csv(PARAM_PATH / "single_cell_noise_hierarchical.csv")
    return {
        "hill": hill,
        "up": up,
        "down": down,
        "alpha": alpha,
        "delays_de": delays_de,
        "delays_rep": delays_rep,
        "design": design,
        "noise_ts": noise_ts,
        "noise_hier_raw": noise_hier,
    }

make_noise_hier_long

make_noise_hier_long(noise_hier_raw)

Build a long-format table with explicit 'channel' from the wide single_cell_noise_hierarchical.csv.

Parameters:
  • noise_hier_raw (DataFrame) –

    Raw hierarchical noise DataFrame.

Returns:
  • DataFrame

    pd.DataFrame: Long-format hierarchical noise DataFrame.

Source code in scripts/step_5_visualize_noise_and_kinetics.py
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
def make_noise_hier_long(noise_hier_raw: pd.DataFrame) -> pd.DataFrame:
    """
    Build a long-format table with explicit 'channel' from the wide
    single_cell_noise_hierarchical.csv.

    Args:
        noise_hier_raw (pd.DataFrame): Raw hierarchical noise DataFrame.

    Returns:
        pd.DataFrame: Long-format hierarchical noise DataFrame.
    """
    records = []
    for _, row in noise_hier_raw.iterrows():
        for channel, prefix in [("BFP", "BFP"), ("mCherry", "mCherry")]:
            records.append(
                {
                    "plasmid": row["plasmid"],
                    "exp": row["exp"],
                    "n_groups": row["n_groups"],
                    "channel": channel,
                    "cv2": row[f"cv2_{prefix}"],
                    "cv2_se": row[f"cv2_{prefix}_se"],
                    "cv2_ci_low": row[f"cv2_{prefix}_ci_low"],
                    "cv2_ci_high": row[f"cv2_{prefix}_ci_high"],
                    "mean": row[f"mean_{prefix}"],
                    "mean_se": row[f"mean_{prefix}_se"],
                    "mean_ci_low": row[f"mean_{prefix}_ci_low"],
                    "mean_ci_high": row[f"mean_{prefix}_ci_high"],
                }
            )
    df_long = pd.DataFrame(records)
    return df_long