PyAntiGen 1.0.9__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (55) hide show
  1. framework/AntimonyGen.py +48 -0
  2. framework/RxnDict_to_antimony.py +594 -0
  3. framework/TelluriumGen.py +16 -0
  4. framework/__init__.py +0 -0
  5. framework/antimony_utils.py +294 -0
  6. framework/cli.py +229 -0
  7. framework/data_interpolation.py +340 -0
  8. framework/isotopomer_tools.py +41 -0
  9. framework/model_generation.py +46 -0
  10. framework/models.py +189 -0
  11. framework/module_base.py +42 -0
  12. framework/pyantigen.py +51 -0
  13. framework/rate_laws.py +101 -0
  14. framework/reaction_creation.py +43 -0
  15. framework/template/Example/AntiGen_paths.py +23 -0
  16. framework/template/Example/Engine/Anchor_cache.py +193 -0
  17. framework/template/Example/Engine/Deadline.py +535 -0
  18. framework/template/Example/Engine/Evaluator.py +1176 -0
  19. framework/template/Example/Engine/Event_times.py +491 -0
  20. framework/template/Example/Engine/Fast_profile.py +701 -0
  21. framework/template/Example/Engine/Fit_cache.py +329 -0
  22. framework/template/Example/Engine/Identifiability.py +698 -0
  23. framework/template/Example/Engine/Model_optimize.py +1483 -0
  24. framework/template/Example/Engine/Model_simulate.py +124 -0
  25. framework/template/Example/Engine/Nuisance_sensitivity.py +298 -0
  26. framework/template/Example/Engine/Optimize.py +6862 -0
  27. framework/template/Example/Engine/Petab_export.py +398 -0
  28. framework/template/Example/Engine/Preequil_cache.py +361 -0
  29. framework/template/Example/Engine/Profile_checkpoint.py +399 -0
  30. framework/template/Example/Engine/Results.py +395 -0
  31. framework/template/Example/Engine/Sensitivity_analysis.py +320 -0
  32. framework/template/Example/Engine/Simulate.py +617 -0
  33. framework/template/Example/Flipflop_reference.py +401 -0
  34. framework/template/Example/Model_generate.py +37 -0
  35. framework/template/Example/Model_run.py +261 -0
  36. framework/template/Example/Modules/Data.py +63 -0
  37. framework/template/Example/Modules/Events.py +14 -0
  38. framework/template/Example/Modules/Experiment.py +194 -0
  39. framework/template/Example/Modules/Loss_config.py +61 -0
  40. framework/template/Example/Modules/Observed_species.py +3 -0
  41. framework/template/Example/Modules/Optimizer_settings.py +258 -0
  42. framework/template/Example/Modules/Plots.py +89 -0
  43. framework/template/Example/Modules/Solver_settings.py +16 -0
  44. framework/template/Example/Modules/Update_opt_parameters.py +24 -0
  45. framework/template/Example/Modules/Update_parameters.py +49 -0
  46. framework/template/data/ADneg.csv +27 -0
  47. framework/template/data/ADpos.csv +27 -0
  48. framework/template/data/Flipflop.csv +29 -0
  49. framework/template/data/make_flipflop_data.py +174 -0
  50. pyantigen-1.0.9.dist-info/METADATA +129 -0
  51. pyantigen-1.0.9.dist-info/RECORD +55 -0
  52. pyantigen-1.0.9.dist-info/WHEEL +5 -0
  53. pyantigen-1.0.9.dist-info/entry_points.txt +2 -0
  54. pyantigen-1.0.9.dist-info/licenses/LICENSE +21 -0
  55. pyantigen-1.0.9.dist-info/top_level.txt +1 -0
@@ -0,0 +1,174 @@
1
+ """
2
+ Generate the synthetic Flipflop dataset (Flipflop.csv) used by Example4/Example5.
3
+
4
+ The model is the two-step chain A -> B -> C (rates k_A_to_B, k_B_to_C) dosed by
5
+ an event (A = dose at t = delay), observed through the scaled output
6
+ predicted_B = SF * B_Comp1 / V_Comp1 on a log10 scale. Because
7
+
8
+ B(tau) = dose * k1 * (exp(-k1 tau) - exp(-k2 tau)) / (k2 - k1)
9
+
10
+ swapping (k1, k2) -> (k2, k1) rescales B by k2/k1, and a fitted SF absorbs that
11
+ rescaling exactly: (k1, k2, SF) and (k2, k1, SF*k1/k2) produce *identical*
12
+ predicted_B trajectories. That is the classic pharmacokinetic "flip-flop"
13
+ ambiguity, and it makes the likelihood exactly bimodal in these parameters.
14
+
15
+ To turn the exact symmetry into a *known, finite* likelihood gap between the
16
+ two modes, the Early treatment also carries a handful of very noisy direct
17
+ observations of predicted_A = A_Comp1 / V_Comp1 (A depends only on k1, so it
18
+ breaks the swap). sigma_logA is tuned so the swapped mode sits near the 95%
19
+ chi-square threshold (dNLL = 1.9207): high enough to make the true confidence
20
+ region interesting, low enough that a mis-scaled dNLL moves it across the
21
+ threshold and visibly changes the reported CI.
22
+
23
+ The seed is fixed so the committed Flipflop.csv is reproducible. After writing
24
+ the CSV the script refits both modes with scipy against the closed-form model
25
+ (no RoadRunner involved) and prints the *realized* swap-mode dNLL gap under the
26
+ same frozen-sigma convention the framework's diagnostics use, so the expected
27
+ gap is recorded next to the data it belongs to.
28
+ """
29
+ import argparse
30
+
31
+ import numpy as np
32
+ import pandas as pd
33
+
34
+ # Ground truth
35
+ K1_TRUE, K2_TRUE, SF_TRUE = 0.35, 0.07, 1.6
36
+ SIGMA_LOGB = 0.05 # dex, noise on log10(SF*B)
37
+ SIGMA_LOGA = 0.75 # dex, noise on log10(A); tuned to put the swap mode near dNLL ~ 2
38
+ N_B_REPS = 3
39
+
40
+ TREATMENTS = {
41
+ "Early": {"dose": 10.0, "delay": 5.0,
42
+ "t_B": np.arange(6.0, 48.1, 3.0), "t_A": np.array([6.0, 9.0, 12.0, 15.0])},
43
+ "Late": {"dose": 5.0, "delay": 10.0,
44
+ "t_B": np.arange(12.0, 48.1, 3.0), "t_A": np.array([])},
45
+ }
46
+
47
+ FLOOR = 1e-12 # same floor the loss-config expressions use
48
+
49
+
50
+ def chain_A(t, dose, delay, k1):
51
+ tau = np.maximum(np.asarray(t, dtype=float) - delay, 0.0)
52
+ return np.where(tau > 0, dose * np.exp(-k1 * tau), 0.0)
53
+
54
+
55
+ def chain_B(t, dose, delay, k1, k2):
56
+ tau = np.maximum(np.asarray(t, dtype=float) - delay, 0.0)
57
+ if abs(k1 - k2) < 1e-10:
58
+ core = dose * k1 * tau * np.exp(-k1 * tau)
59
+ else:
60
+ core = dose * k1 * (np.exp(-k1 * tau) - np.exp(-k2 * tau)) / (k2 - k1)
61
+ return np.where(tau > 0, core, 0.0)
62
+
63
+
64
+ def log10f(x):
65
+ return np.log10(np.maximum(x, FLOOR))
66
+
67
+
68
+ def generate(seed):
69
+ rng = np.random.default_rng(seed)
70
+ rows = []
71
+ for name, tr in TREATMENTS.items():
72
+ logB_true = log10f(SF_TRUE * chain_B(tr["t_B"], tr["dose"], tr["delay"], K1_TRUE, K2_TRUE))
73
+ logB_reps = logB_true[:, None] + rng.normal(0.0, SIGMA_LOGB, size=(len(logB_true), N_B_REPS))
74
+ logA = {}
75
+ if len(tr["t_A"]):
76
+ logA_true = log10f(chain_A(tr["t_A"], tr["dose"], tr["delay"], K1_TRUE))
77
+ for t, v in zip(tr["t_A"], logA_true + rng.normal(0.0, SIGMA_LOGA, size=len(tr["t_A"]))):
78
+ logA[t] = v
79
+ for i, t in enumerate(tr["t_B"]):
80
+ rows.append({
81
+ "Treatment": name, "time": t,
82
+ "logB1": logB_reps[i, 0], "logB2": logB_reps[i, 1], "logB3": logB_reps[i, 2],
83
+ "logA": logA.get(t, np.nan),
84
+ })
85
+ return pd.DataFrame(rows)
86
+
87
+
88
+ # --- realized-gap check (framework NLL convention, closed-form model) --------
89
+
90
+ def _stack_data(df):
91
+ """Return per-treatment stacked logB data and Early logA data."""
92
+ out = {}
93
+ for name, tr in TREATMENTS.items():
94
+ sub = df[df["Treatment"] == name]
95
+ t = np.concatenate([sub["time"].to_numpy()] * N_B_REPS)
96
+ y = np.concatenate([sub[f"logB{i+1}"].to_numpy() for i in range(N_B_REPS)])
97
+ out[name] = (t, y)
98
+ early = df[(df["Treatment"] == "Early") & df["logA"].notna()]
99
+ out["Early_A"] = (early["time"].to_numpy(), early["logA"].to_numpy())
100
+ return out
101
+
102
+
103
+ def _ssr_terms(p, data):
104
+ """Per-observable (SSR, n) at parameters p = (k1, k2, SF)."""
105
+ k1, k2, sf = p
106
+ terms = {}
107
+ for name, tr in TREATMENTS.items():
108
+ t, y = data[name]
109
+ pred = log10f(sf * chain_B(t, tr["dose"], tr["delay"], k1, k2))
110
+ terms[name] = (float(np.sum((y - pred) ** 2)), len(y))
111
+ t, y = data["Early_A"]
112
+ pred = log10f(chain_A(t, TREATMENTS["Early"]["dose"], TREATMENTS["Early"]["delay"], k1))
113
+ terms["Early_A"] = (float(np.sum((y - pred) ** 2)), len(y))
114
+ return terms
115
+
116
+
117
+ def _weighted_nll(p, data, sigmas):
118
+ terms = _ssr_terms(p, data)
119
+ return sum(ssr / (2.0 * sigmas[k] ** 2) for k, (ssr, n) in terms.items())
120
+
121
+
122
+ def frozen_sigmas_at(p, data, k_params=3):
123
+ """Framework convention: sigma = sqrt(SSR / max(1, n - k/n_observables)),
124
+ where n_observables counts observables in the same loss config (Early has
125
+ logB+logA -> 2, Late has logB -> 1)."""
126
+ terms = _ssr_terms(p, data)
127
+ n_obs_cfg = {"Early": 2, "Early_A": 2, "Late": 1}
128
+ return {k: max(np.sqrt(ssr / max(1, n - k_params / n_obs_cfg[k])), 1e-6)
129
+ for k, (ssr, n) in terms.items()}
130
+
131
+
132
+ def fit_mode(x0, data, sigmas):
133
+ from scipy.optimize import minimize
134
+ obj = lambda q: _weighted_nll(10.0 ** q, data, sigmas)
135
+ res = minimize(obj, np.log10(x0), method="Nelder-Mead",
136
+ options={"maxiter": 4000, "xatol": 1e-10, "fatol": 1e-12})
137
+ return 10.0 ** res.x, res.fun
138
+
139
+
140
+ def report_gap(df):
141
+ data = _stack_data(df)
142
+ # crude sigmas for a first fit, then freeze at the global optimum and refit
143
+ sigmas = {"Early": SIGMA_LOGB, "Late": SIGMA_LOGB, "Early_A": SIGMA_LOGA}
144
+ p_true, _ = fit_mode([K1_TRUE, K2_TRUE, SF_TRUE], data, sigmas)
145
+ sigmas = frozen_sigmas_at(p_true, data)
146
+ p_true, nll_true = fit_mode(p_true, data, sigmas)
147
+ p_swap0 = [p_true[1], p_true[0], p_true[2] * p_true[0] / p_true[1]]
148
+ p_swap, nll_swap = fit_mode(p_swap0, data, sigmas)
149
+ print(f" global mode : k1={p_true[0]:.4f} k2={p_true[1]:.4f} SF={p_true[2]:.4f}")
150
+ print(f" swapped mode: k1={p_swap[0]:.4f} k2={p_swap[1]:.4f} SF={p_swap[2]:.4f}")
151
+ print(f" frozen sigmas: " + ", ".join(f"{k}={v:.4f}" for k, v in sigmas.items()))
152
+ print(f" realized swap-mode dNLL gap = {nll_swap - nll_true:.4f}"
153
+ f" (95% threshold = 1.9207)")
154
+ return nll_swap - nll_true
155
+
156
+
157
+ if __name__ == "__main__":
158
+ ap = argparse.ArgumentParser()
159
+ ap.add_argument("--seed", type=int, default=5)
160
+ ap.add_argument("--out", type=str, default="Flipflop.csv")
161
+ ap.add_argument("--scan", type=int, default=0,
162
+ help="scan seeds 0..N-1 and report each realized gap instead of writing")
163
+ args = ap.parse_args()
164
+
165
+ if args.scan:
166
+ for s in range(args.scan):
167
+ df = generate(s)
168
+ print(f"seed {s}:")
169
+ report_gap(df)
170
+ else:
171
+ df = generate(args.seed)
172
+ df.to_csv(args.out, index=False, float_format="%.6g")
173
+ print(f"Wrote {args.out} (seed={args.seed})")
174
+ report_gap(df)
@@ -0,0 +1,129 @@
1
+ Metadata-Version: 2.4
2
+ Name: PyAntiGen
3
+ Version: 1.0.9
4
+ Summary: Short one-line description of what PyAntiGen does
5
+ Author: Open Source Contributor
6
+ Author-email: Don <you@example.com>
7
+ License: MIT
8
+ Project-URL: Homepage, https://github.com/you/PyAntiGen
9
+ Keywords: alzheimer,immunology,simulation
10
+ Classifier: Programming Language :: Python :: 3
11
+ Classifier: License :: OSI Approved :: MIT License
12
+ Classifier: Operating System :: OS Independent
13
+ Requires-Python: >=3.9
14
+ Description-Content-Type: text/markdown
15
+ License-File: LICENSE
16
+ Requires-Dist: tellurium
17
+ Requires-Dist: scipy
18
+ Requires-Dist: numpy
19
+ Requires-Dist: pandas
20
+ Requires-Dist: numdifftools
21
+ Requires-Dist: openpyxl
22
+ Requires-Dist: matplotlib
23
+ Requires-Dist: pypesto
24
+ Dynamic: author
25
+ Dynamic: license-file
26
+
27
+ # PyAntiGen
28
+
29
+ PyAntiGen is a declarative, object-oriented framework for generating compartmental biological models in Antimony format. It is designed to abstract away the repetitive boilerplate of defining reactions and compartments manually, allowing researchers to build complex, scalable models using clean Python syntax.
30
+
31
+ ## Features
32
+
33
+ - **Object-Oriented Modules:** Encapsulate tissues, flows, synthesis, and excretion into reusable Python classes.
34
+ - **Dynamic Registration:** Automatically binds reactions, compartments, and species to the global model state when a module is instantiated.
35
+ - **Project Scaffolding:** Includes a CLI command to instantly spin up new modeling projects with all necessary directories.
36
+ - **Isotope Tracking:** Natively supports tracking labeled isotopes and generating corresponding parallel reactions.
37
+
38
+ ## Installation
39
+ You can install PyAntiGen into your Python environment with:
40
+ ```bash
41
+ pip install pyantigen
42
+ ```
43
+
44
+ You can also install PyAntiGen globally into your preferred Python environment by cloning this repository and running pip:
45
+
46
+ ```bash
47
+ git clone https://github.com/elbert5770/PyAntiGen.git
48
+ cd PyAntiGen
49
+ pip install -e .
50
+ ```
51
+
52
+ ## Quick Start: Creating a New Model
53
+
54
+ Because PyAntiGen is installed as a system-level Python package, you don't need a copy of the framework files in your working directory.
55
+
56
+ To start a brand new modeling workspace, just open a terminal and navigate to a folder where you want your project to live (be careful not to build within the PyAntiGen folder itself) and run:
57
+
58
+ ```bash
59
+ pyantigen-create MyNewModel
60
+ ```
61
+
62
+ This will automatically scaffold the following project directory:
63
+ ```text
64
+ MyNewModel/
65
+ ├── .agents/
66
+ │ └── skills/ (agent skills, e.g. module generation, ODE conversion)
67
+ ├── Projects/
68
+ │ ├── Example/ (full example: generate, run + Modules/, Engine/)
69
+ │ │ ├── Model_generate.py
70
+ │ │ ├── Model_run.py
71
+ │ │ └── Modules/ (Data, AntimonyGen, Plots, Simulate, Optimize, Experiment, Events)
72
+ │ └── MyNewModel/ (same structure, Modules/ pre-populated from Example)
73
+ │ ├── Model_generate.py
74
+ │ ├── Model_run.py
75
+ │ └── Modules/ (Data, AntimonyGen, Plots, Simulate, Optimize, Experiment, Events)
76
+ ├── antimony_modules/
77
+ │ └── __init__.py (plus Basic/ for the example)
78
+ ├── data/ (Example experiment CSVs copied for the example)
79
+ ├── antimony_models/
80
+ │ └── Example/ (Example_parameters.csv, Example_InitialConditions.csv, etc.)
81
+ ├── generated/
82
+ │ └── Example/ (reaction dict, rules, etc. after generate)
83
+ ├── results/
84
+ │ └── Example/ (plots from Model_run.py)
85
+ ├── SBML_models/
86
+ └── pyantigen_settings.json (e.g. archive_with_timestamp: false)
87
+ ```
88
+
89
+ Every project folder under `Projects/` has a script called `Model_generate.py` that is run to generate the model. `MODEL_NAME` is derived automatically from the enclosing folder name (see `AntiGen_paths.py`), so being in the right project folder is all that's needed to generate/run the correct project. From `MyNewModel/Projects/Example/` run:
90
+
91
+ ```bash
92
+ python Model_generate.py
93
+ ```
94
+
95
+ This generates the model from the specified files in 'antimony_modules' and writes outputs to `antimony_models/Example/` and `generated/Example/`. This is entirely optional as Model_run.py also calls the constructor functions in `Model_generate.py`.
96
+
97
+ To run a simulation or optimization, you may edit the parameters in `antimony_models/Example/Example_parameters.csv`, derived parameters in `antimony_models/Example/Example_manual.txt`, and initial conditions in `antimony_models/Example/Example_InitialConditions.csv`.
98
+
99
+ Then, run `Model_run.py` to simulate the Example in Tellurium/RoadRunner:
100
+
101
+ ```bash
102
+ python Model_run.py --simulate Example
103
+ ```
104
+
105
+ To run optimization examples use the --optimize flag:
106
+
107
+ ```bash
108
+ python Model_run.py --optimize Example1
109
+ python Model_run.py --optimize Example2
110
+ python Model_run.py --optimize Example3
111
+ python Model_run.py --optimize Example4
112
+ python Model_run.py --optimize Example5
113
+ ```
114
+
115
+ Each example prints a banner explaining what it demonstrates before the run and a "what to look for" summary after it. All output lands in `results/Example/`, prefixed with the example and group names so runs never overwrite each other — e.g. `Example_Example2_ADpos_profile_likelihood.png`, `Example_Example4_Flipflop_optimization_results.csv`.
116
+
117
+ Examples 1–3 demonstrate structural identifiability: Example1/2 split the fit so each sub-problem is well-posed, while Example3 deliberately fits two exactly confounded parameters (`SF`/`V_Comp1`) jointly and shows how profile likelihood flags the ridge that likelihood slices and Sobol indices miss.
118
+
119
+ Examples 4–5 go further and test the *accuracy* of the profile likelihood ΔNLL itself, on a genuinely multimodal problem with a log10 objective. The chain A → B → C observed through `SF*B_Comp1/V_Comp1` has the classic pharmacokinetic "flip-flop" ambiguity — swapping the two rate constants and rescaling `SF` reproduces the data exactly — so the likelihood has two modes separated by a known ΔNLL gap (~2.4 at the NLL optimum, set by a few deliberately noisy observations of A and printed by `data/make_flipflop_data.py`). Example4 starts in the correct basin. Accurate profiles must (a) dip below zero by a known amount (~−2.1), because the fitting objective's per-observable averaging places the fit away from the inference NLL optimum that ΔNLL is anchored to, and (b) show the second mode at ~+0.8 — below the 95% threshold, so the correct confidence set is a union of two disjoint intervals; a walker that stops at the first threshold crossing never finds it, and a first-crossing CI extractor cannot represent it. Example5 starts in the wrong basin: sigmas are frozen at the wrong mode (inflating σ for the A data and deflating every ΔNLL), and the profile must dip to ~−0.98 at the true mode. `Projects/Example/Flipflop_reference.py` recomputes the exact reference profiles from the closed-form solution with scipy (independent of RoadRunner and of the framework's loss code), replicating the pipeline's conventions — fit objective for the anchor, MLE-frozen sigmas, summed NLL — and its `--compare results/Example/<run>.json` mode scores the framework's stored profile traces against the reference automatically.
120
+
121
+ Your own model lives under `Projects/MyNewModel/`. Modify the code for your model in `Projects/MyNewModel/Modules/`, `Projects/MyNewModel/Model_generate.py`, and `Projects/MyNewModel/Model_run.py`. Your problem will also require new modules in `antimony_modules/` to define the model.
122
+
123
+
124
+ ### Running from an IDE (Cursor / VS Code)
125
+
126
+ The **Play** button uses whichever Python interpreter is currently selected. If your environment (conda/venv) isn’t loaded, the run may fail with import or path errors.
127
+
128
+ 1. **Select the correct interpreter**: `Ctrl+Shift+P` (or `Cmd+Shift+P` on macOS) → **Python: Select Interpreter** → choose the environment where you ran `pip install -e .` (e.g. your conda or venv).
129
+ 2. **Run from project root**: Open the *project* folder (e.g. `MyNewModel`) as the workspace. Use **Run and Debug** (or Play on `Projects/Example/Model_run.py`); the project root is resolved from the script location so `antimony_models/Example/`, `generated/Example/`, and `results/Example/` resolve correctly.
@@ -0,0 +1,55 @@
1
+ framework/AntimonyGen.py,sha256=UhPnQ762yAJXAciXU9u5Vju8sTdJSrP-EzRkWu_XvAY,1404
2
+ framework/RxnDict_to_antimony.py,sha256=zStKjg14UBBbi5D4xGjZEPkMXH2igomD1ViEhtW40uw,25208
3
+ framework/TelluriumGen.py,sha256=zyjT9nDE8wgswp9y-uTs1LgiTuRA1FQv5RBu_TXPE00,618
4
+ framework/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
5
+ framework/antimony_utils.py,sha256=WT67cxgKSFwxpfwB0bfqYtnsB_SG84ynu6HKIDa2c0k,12341
6
+ framework/cli.py,sha256=YiDGBwT5aAlwmW-hKyA9gfixKrlT_pT3rmSNw_Diq2g,11123
7
+ framework/data_interpolation.py,sha256=nWMYNlJJJgze5qGQj4y1eXelcujrZsy3Dc7_bwEx55A,11982
8
+ framework/isotopomer_tools.py,sha256=7LTiO3mg-Nt0m-pRXmprnoyTyANff_4QUOadbZxHWQ4,1233
9
+ framework/model_generation.py,sha256=34mReS6angE7zcOHA3flz2dXKmutE59C-ryv2hk6YVA,2248
10
+ framework/models.py,sha256=CAwEGZYVPzgR4BX1IjAqcNHDAT9n4_tqjQSJl9bEN-I,7075
11
+ framework/module_base.py,sha256=xlNzbSTMIrgOkNNhQyxyneOCDuia-_ezgPR7qHCKJbc,1260
12
+ framework/pyantigen.py,sha256=PBdOlPsHAHNhE69n6BeN3-nLovqs_Fs0Bw8ajEuKbos,1621
13
+ framework/rate_laws.py,sha256=VVw06MPBgA8H5EaY7xRlW3UntF_90its_U0u-HS5frk,3629
14
+ framework/reaction_creation.py,sha256=n8qb6Dzr2BfBxGmkaEkSkmBlQTHI-1Li-r2kqFBxqE8,1169
15
+ framework/template/Example/AntiGen_paths.py,sha256=BbB-B0Pn0iHjLT67iLWi9U4WEoSkmQpNdflNPzr2mvQ,734
16
+ framework/template/Example/Flipflop_reference.py,sha256=aIYs_eM-0gOoYGInS-pHkeGcewGN7T3gHDO0ufRfqMI,16818
17
+ framework/template/Example/Model_generate.py,sha256=kddZCM1vClC49h3vPvz9hzJtxPWBJTN8aBgy4cnfMbs,1164
18
+ framework/template/Example/Model_run.py,sha256=MxAEIBb37O4KNdu_jZXvup-8Eey2XmIOU2R-gHggCDU,12651
19
+ framework/template/Example/Engine/Anchor_cache.py,sha256=NRxp9m-Kozw7gazG72riG5kaXV1nI0fA-tkr3G9UxIo,7220
20
+ framework/template/Example/Engine/Deadline.py,sha256=21SP1tgj_62DbheVdd2dedtqfEkVrG5H4wLQ0AP9EyE,22259
21
+ framework/template/Example/Engine/Evaluator.py,sha256=5aRnZYVmLKSIYKhAgQFnL57Yx3vrWcj2wZK4qKTfZYo,53221
22
+ framework/template/Example/Engine/Event_times.py,sha256=cd4OJthHWPYHYHr6TEXp7b2_r8EyucAW3u-ls_hTfGQ,19043
23
+ framework/template/Example/Engine/Fast_profile.py,sha256=pOyn-xumPqiEkAtjQYQLXyOfb9NdNNeG4TxfebMZGJ8,31644
24
+ framework/template/Example/Engine/Fit_cache.py,sha256=GWr8y2QsaWdibwdmJ6gLLwvk7L9tNfoaCLPSJYiC_KU,12913
25
+ framework/template/Example/Engine/Identifiability.py,sha256=x9zIhOhM3iqYyJNTevFtxyk4t8Jxpq9NW621ear0Z0g,32070
26
+ framework/template/Example/Engine/Model_optimize.py,sha256=IZtWPEATGMDz_WfBtLLtoGx7Q3_oiIFo-BrpxbSPiDw,69146
27
+ framework/template/Example/Engine/Model_simulate.py,sha256=2cFFePfDwUnTyl04qUM3UR_VQ6YZFrksKLiT_J2V3OE,4293
28
+ framework/template/Example/Engine/Nuisance_sensitivity.py,sha256=qUUmXo8DffgJKAFwTOaiZ-b5qaqkgCyEcnlawqMCBoM,11928
29
+ framework/template/Example/Engine/Optimize.py,sha256=wJmVP_LdNbGOaRL_v0hoWMGcLsX2GOcJZMyXF0FIwN4,313888
30
+ framework/template/Example/Engine/Petab_export.py,sha256=hKAq3USiZdUN-OskkYuhkEgPmDL-uV-Tliz3tPGDmrM,14188
31
+ framework/template/Example/Engine/Preequil_cache.py,sha256=LBVV_tw_B7P_jtnfWW_1X6jX0b3Q7Sg6qjhBeO0cP2M,15895
32
+ framework/template/Example/Engine/Profile_checkpoint.py,sha256=hfO5YCrbao8JOZoCtX1yhcm5PA2tZlp9TArM9AOA9iU,16490
33
+ framework/template/Example/Engine/Results.py,sha256=-QFcDTGCTXF5519c3Fjdqr6MEWAfCqIKSpr8FMphaDA,18832
34
+ framework/template/Example/Engine/Sensitivity_analysis.py,sha256=DqRsjCsIQD9v3GIlW8DR66zvZDg5UHHlbB_q39tMeuQ,12162
35
+ framework/template/Example/Engine/Simulate.py,sha256=EkcsH7pFVta2vAjH3sW1UsrPsM9AmdQftt8xg9m2Hrw,27385
36
+ framework/template/Example/Modules/Data.py,sha256=R24iiJhA2Nt2R4BS1aPZ6I3Pd0x3wNj6T1hP-3Bq3Go,2250
37
+ framework/template/Example/Modules/Events.py,sha256=1ZDpVUToMn1LOH1MVDfY3QwGPKiGvKUJK7YbWjN0w9w,325
38
+ framework/template/Example/Modules/Experiment.py,sha256=g87HshbsMFgM0BdGHi0rbzEASYb6Jdqcz_9Vgi5hBTs,8033
39
+ framework/template/Example/Modules/Loss_config.py,sha256=FTeTZMQeIG6YW0MxaFH0V7LRKxvNtVcy7WbHc398glU,2474
40
+ framework/template/Example/Modules/Observed_species.py,sha256=J44Ts9SuCd7IGhC6n3pdumMgBTV6I9PTtQ6diGUxP7A,215
41
+ framework/template/Example/Modules/Optimizer_settings.py,sha256=xGKhmx7Z8yuTilzdR3xqGtRuRqloG7HPVLjwWOKm5jU,12383
42
+ framework/template/Example/Modules/Plots.py,sha256=Ys9ZLq48XYybZQ_ZYo10lsS8GC77lfcdZi6cN6rx78c,3835
43
+ framework/template/Example/Modules/Solver_settings.py,sha256=RLTyhvqBhRZfCYigdastmnVInoHmUd0dWZ4CS6JsaEA,614
44
+ framework/template/Example/Modules/Update_opt_parameters.py,sha256=GVWKtLqDzAuEyexKh1tMxRK4fxbvk_E_LP29Nd0Taw8,1066
45
+ framework/template/Example/Modules/Update_parameters.py,sha256=g0cvFMwcax0nR02Q-nFRokoF-lqZc07GU-rA1fGWbwE,1961
46
+ framework/template/data/ADneg.csv,sha256=0AFLqSMQzdiP0CnKivcSLhAPGvSTBHHvURYNwjximIc,1649
47
+ framework/template/data/ADpos.csv,sha256=yomwM-351rqRGRG5HRWXVvH7YjCL02htibz1GhUr3F8,1627
48
+ framework/template/data/Flipflop.csv,sha256=Iz9dHh078n9cKMQGTkaO7ujXotL8-yekSIHaMALIgtQ,1097
49
+ framework/template/data/make_flipflop_data.py,sha256=K48EmCgS4N05l2nUXypNXuCS_mJ5P7VTopaxXrO4wd4,7152
50
+ pyantigen-1.0.9.dist-info/licenses/LICENSE,sha256=m8qNO2yS4hZm11HQeYNQ6AM05qIWl3D3cpofjwTPfzY,1070
51
+ pyantigen-1.0.9.dist-info/METADATA,sha256=jE6KYWDEQ2mBWSOOHHZTf7EFyWJ5P_eoGCJeS7zvbv8,8253
52
+ pyantigen-1.0.9.dist-info/WHEEL,sha256=YVMoNqKzERt-wjUZwJ33xBGAwnFl-4cqbYkTtWa4itE,91
53
+ pyantigen-1.0.9.dist-info/entry_points.txt,sha256=zZGw0nx5OM7k3G9oAdoDbz4S9k8OzuYU72IONHqONZw,66
54
+ pyantigen-1.0.9.dist-info/top_level.txt,sha256=hzpv2xEeSkKTVweFn8I8XnG5zJJOIOTB38-_zgJJSUw,10
55
+ pyantigen-1.0.9.dist-info/RECORD,,
@@ -0,0 +1,5 @@
1
+ Wheel-Version: 1.0
2
+ Generator: setuptools (84.0.0)
3
+ Root-Is-Purelib: true
4
+ Tag: py3-none-any
5
+
@@ -0,0 +1,2 @@
1
+ [console_scripts]
2
+ pyantigen-create = framework.cli:create_project
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 UW Elbert Lab
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
@@ -0,0 +1 @@
1
+ framework