PyAntiGen 1.0.10__tar.gz → 1.0.11__tar.gz

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 (74) hide show
  1. pyantigen-1.0.11/.github/workflows/publish.yml +29 -0
  2. pyantigen-1.0.11/.gitignore +28 -0
  3. pyantigen-1.0.11/.vscode/launch.json +21 -0
  4. {pyantigen-1.0.10 → pyantigen-1.0.11}/PKG-INFO +1 -1
  5. {pyantigen-1.0.10 → pyantigen-1.0.11}/PyAntiGen.egg-info/PKG-INFO +1 -1
  6. {pyantigen-1.0.10 → pyantigen-1.0.11}/PyAntiGen.egg-info/SOURCES.txt +10 -0
  7. pyantigen-1.0.11/PyAntiGen.egg-info/scm_file_list.json +125 -0
  8. pyantigen-1.0.11/PyAntiGen.egg-info/scm_version.json +8 -0
  9. pyantigen-1.0.11/framework/.agents/skills/module_generation/SKILL.md +109 -0
  10. pyantigen-1.0.11/framework/.agents/skills/ode_conversion_antimony/SKILL.md +34 -0
  11. pyantigen-1.0.11/framework/.agents/skills/ode_extraction_pipeline/SKILL.md +41 -0
  12. pyantigen-1.0.11/framework/.gitignore +2 -0
  13. pyantigen-1.0.11/framework/__init__.py +20 -0
  14. pyantigen-1.0.11/framework/_version.py +24 -0
  15. pyantigen-1.0.11/pyproject.toml +57 -0
  16. {pyantigen-1.0.10 → pyantigen-1.0.11}/setup.py +3 -1
  17. pyantigen-1.0.10/framework/__init__.py +0 -0
  18. pyantigen-1.0.10/pyproject.toml +0 -39
  19. {pyantigen-1.0.10 → pyantigen-1.0.11}/LICENSE +0 -0
  20. {pyantigen-1.0.10 → pyantigen-1.0.11}/MANIFEST.in +0 -0
  21. {pyantigen-1.0.10 → pyantigen-1.0.11}/PyAntiGen.egg-info/dependency_links.txt +0 -0
  22. {pyantigen-1.0.10 → pyantigen-1.0.11}/PyAntiGen.egg-info/entry_points.txt +0 -0
  23. {pyantigen-1.0.10 → pyantigen-1.0.11}/PyAntiGen.egg-info/requires.txt +0 -0
  24. {pyantigen-1.0.10 → pyantigen-1.0.11}/PyAntiGen.egg-info/top_level.txt +0 -0
  25. {pyantigen-1.0.10 → pyantigen-1.0.11}/README.md +0 -0
  26. {pyantigen-1.0.10 → pyantigen-1.0.11}/framework/AntimonyGen.py +0 -0
  27. {pyantigen-1.0.10 → pyantigen-1.0.11}/framework/RxnDict_to_antimony.py +0 -0
  28. {pyantigen-1.0.10 → pyantigen-1.0.11}/framework/TelluriumGen.py +0 -0
  29. {pyantigen-1.0.10 → pyantigen-1.0.11}/framework/antimony_utils.py +0 -0
  30. {pyantigen-1.0.10 → pyantigen-1.0.11}/framework/cli.py +0 -0
  31. {pyantigen-1.0.10 → pyantigen-1.0.11}/framework/data_interpolation.py +0 -0
  32. {pyantigen-1.0.10 → pyantigen-1.0.11}/framework/isotopomer_tools.py +0 -0
  33. {pyantigen-1.0.10 → pyantigen-1.0.11}/framework/model_generation.py +0 -0
  34. {pyantigen-1.0.10 → pyantigen-1.0.11}/framework/models.py +0 -0
  35. {pyantigen-1.0.10 → pyantigen-1.0.11}/framework/module_base.py +0 -0
  36. {pyantigen-1.0.10 → pyantigen-1.0.11}/framework/pyantigen.py +0 -0
  37. {pyantigen-1.0.10 → pyantigen-1.0.11}/framework/rate_laws.py +0 -0
  38. {pyantigen-1.0.10 → pyantigen-1.0.11}/framework/reaction_creation.py +0 -0
  39. {pyantigen-1.0.10 → pyantigen-1.0.11}/framework/template/Example/AntiGen_paths.py +0 -0
  40. {pyantigen-1.0.10 → pyantigen-1.0.11}/framework/template/Example/Engine/Anchor_cache.py +0 -0
  41. {pyantigen-1.0.10 → pyantigen-1.0.11}/framework/template/Example/Engine/Deadline.py +0 -0
  42. {pyantigen-1.0.10 → pyantigen-1.0.11}/framework/template/Example/Engine/Evaluator.py +0 -0
  43. {pyantigen-1.0.10 → pyantigen-1.0.11}/framework/template/Example/Engine/Event_times.py +0 -0
  44. {pyantigen-1.0.10 → pyantigen-1.0.11}/framework/template/Example/Engine/Fast_profile.py +0 -0
  45. {pyantigen-1.0.10 → pyantigen-1.0.11}/framework/template/Example/Engine/Fit_cache.py +0 -0
  46. {pyantigen-1.0.10 → pyantigen-1.0.11}/framework/template/Example/Engine/Identifiability.py +0 -0
  47. {pyantigen-1.0.10 → pyantigen-1.0.11}/framework/template/Example/Engine/Model_optimize.py +0 -0
  48. {pyantigen-1.0.10 → pyantigen-1.0.11}/framework/template/Example/Engine/Model_simulate.py +0 -0
  49. {pyantigen-1.0.10 → pyantigen-1.0.11}/framework/template/Example/Engine/Nuisance_sensitivity.py +0 -0
  50. {pyantigen-1.0.10 → pyantigen-1.0.11}/framework/template/Example/Engine/Optimize.py +0 -0
  51. {pyantigen-1.0.10 → pyantigen-1.0.11}/framework/template/Example/Engine/Petab_export.py +0 -0
  52. {pyantigen-1.0.10 → pyantigen-1.0.11}/framework/template/Example/Engine/Preequil_cache.py +0 -0
  53. {pyantigen-1.0.10 → pyantigen-1.0.11}/framework/template/Example/Engine/Profile_checkpoint.py +0 -0
  54. {pyantigen-1.0.10 → pyantigen-1.0.11}/framework/template/Example/Engine/Results.py +0 -0
  55. {pyantigen-1.0.10 → pyantigen-1.0.11}/framework/template/Example/Engine/Sensitivity_analysis.py +0 -0
  56. {pyantigen-1.0.10 → pyantigen-1.0.11}/framework/template/Example/Engine/Simulate.py +0 -0
  57. {pyantigen-1.0.10 → pyantigen-1.0.11}/framework/template/Example/Flipflop_reference.py +0 -0
  58. {pyantigen-1.0.10 → pyantigen-1.0.11}/framework/template/Example/Model_generate.py +0 -0
  59. {pyantigen-1.0.10 → pyantigen-1.0.11}/framework/template/Example/Model_run.py +0 -0
  60. {pyantigen-1.0.10 → pyantigen-1.0.11}/framework/template/Example/Modules/Data.py +0 -0
  61. {pyantigen-1.0.10 → pyantigen-1.0.11}/framework/template/Example/Modules/Events.py +0 -0
  62. {pyantigen-1.0.10 → pyantigen-1.0.11}/framework/template/Example/Modules/Experiment.py +0 -0
  63. {pyantigen-1.0.10 → pyantigen-1.0.11}/framework/template/Example/Modules/Loss_config.py +0 -0
  64. {pyantigen-1.0.10 → pyantigen-1.0.11}/framework/template/Example/Modules/Observed_species.py +0 -0
  65. {pyantigen-1.0.10 → pyantigen-1.0.11}/framework/template/Example/Modules/Optimizer_settings.py +0 -0
  66. {pyantigen-1.0.10 → pyantigen-1.0.11}/framework/template/Example/Modules/Plots.py +0 -0
  67. {pyantigen-1.0.10 → pyantigen-1.0.11}/framework/template/Example/Modules/Solver_settings.py +0 -0
  68. {pyantigen-1.0.10 → pyantigen-1.0.11}/framework/template/Example/Modules/Update_opt_parameters.py +0 -0
  69. {pyantigen-1.0.10 → pyantigen-1.0.11}/framework/template/Example/Modules/Update_parameters.py +0 -0
  70. {pyantigen-1.0.10 → pyantigen-1.0.11}/framework/template/data/ADneg.csv +0 -0
  71. {pyantigen-1.0.10 → pyantigen-1.0.11}/framework/template/data/ADpos.csv +0 -0
  72. {pyantigen-1.0.10 → pyantigen-1.0.11}/framework/template/data/Flipflop.csv +0 -0
  73. {pyantigen-1.0.10 → pyantigen-1.0.11}/framework/template/data/make_flipflop_data.py +0 -0
  74. {pyantigen-1.0.10 → pyantigen-1.0.11}/setup.cfg +0 -0
@@ -0,0 +1,29 @@
1
+ name: Publish to PyPI
2
+
3
+ on:
4
+ push:
5
+ tags:
6
+ - "v*" # triggers on any tag like v0.1.0, v1.2.3
7
+
8
+ jobs:
9
+ build-and-publish:
10
+ runs-on: ubuntu-latest
11
+ environment: pypi # matches the environment name from Step 1
12
+ permissions:
13
+ id-token: write # required for trusted publishing
14
+
15
+ steps:
16
+ - uses: actions/checkout@v4
17
+
18
+ - uses: actions/setup-python@v5
19
+ with:
20
+ python-version: "3.11"
21
+
22
+ - name: Install build
23
+ run: pip install build
24
+
25
+ - name: Build package
26
+ run: python -m build
27
+
28
+ - name: Publish to PyPI
29
+ uses: pypa/gh-action-pypi-publish@release/v1
@@ -0,0 +1,28 @@
1
+ __pycache__/
2
+ *.py[cod]
3
+ *$py.class
4
+ *.so
5
+ .Python
6
+ env/
7
+ build/
8
+ develop-eggs/
9
+ dist/
10
+ downloads/
11
+ eggs/
12
+ .eggs/
13
+ lib/
14
+ lib64/
15
+ parts/
16
+ sdist/
17
+ var/
18
+ wheels/
19
+ *.egg-info/
20
+ .installed.cfg
21
+ *.egg
22
+ .env
23
+ .venv
24
+ venv/
25
+ ENV/
26
+
27
+ # Written at build time by setuptools-scm (see [tool.setuptools_scm])
28
+ framework/_version.py
@@ -0,0 +1,21 @@
1
+ {
2
+ "version": "0.2.0",
3
+ "configurations": [
4
+ {
5
+ "name": "Python: Current File (project root cwd)",
6
+ "type": "debugpy",
7
+ "request": "launch",
8
+ "program": "${file}",
9
+ "console": "integratedTerminal",
10
+ "cwd": "${workspaceFolder}"
11
+ },
12
+ {
13
+ "name": "Python: Current File (script dir cwd)",
14
+ "type": "debugpy",
15
+ "request": "launch",
16
+ "program": "${file}",
17
+ "console": "integratedTerminal",
18
+ "cwd": "${fileDirname}"
19
+ }
20
+ ]
21
+ }
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: PyAntiGen
3
- Version: 1.0.10
3
+ Version: 1.0.11
4
4
  Summary: Short one-line description of what PyAntiGen does
5
5
  Author: Open Source Contributor
6
6
  Author-email: Don <you@example.com>
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: PyAntiGen
3
- Version: 1.0.10
3
+ Version: 1.0.11
4
4
  Summary: Short one-line description of what PyAntiGen does
5
5
  Author: Open Source Contributor
6
6
  Author-email: Don <you@example.com>
@@ -1,18 +1,25 @@
1
+ .gitignore
1
2
  LICENSE
2
3
  MANIFEST.in
3
4
  README.md
4
5
  pyproject.toml
5
6
  setup.py
7
+ .github/workflows/publish.yml
8
+ .vscode/launch.json
6
9
  PyAntiGen.egg-info/PKG-INFO
7
10
  PyAntiGen.egg-info/SOURCES.txt
8
11
  PyAntiGen.egg-info/dependency_links.txt
9
12
  PyAntiGen.egg-info/entry_points.txt
10
13
  PyAntiGen.egg-info/requires.txt
14
+ PyAntiGen.egg-info/scm_file_list.json
15
+ PyAntiGen.egg-info/scm_version.json
11
16
  PyAntiGen.egg-info/top_level.txt
17
+ framework/.gitignore
12
18
  framework/AntimonyGen.py
13
19
  framework/RxnDict_to_antimony.py
14
20
  framework/TelluriumGen.py
15
21
  framework/__init__.py
22
+ framework/_version.py
16
23
  framework/antimony_utils.py
17
24
  framework/cli.py
18
25
  framework/data_interpolation.py
@@ -23,6 +30,9 @@ framework/module_base.py
23
30
  framework/pyantigen.py
24
31
  framework/rate_laws.py
25
32
  framework/reaction_creation.py
33
+ framework/.agents/skills/module_generation/SKILL.md
34
+ framework/.agents/skills/ode_conversion_antimony/SKILL.md
35
+ framework/.agents/skills/ode_extraction_pipeline/SKILL.md
26
36
  framework/template/Example/AntiGen_paths.py
27
37
  framework/template/Example/Flipflop_reference.py
28
38
  framework/template/Example/Model_generate.py
@@ -0,0 +1,125 @@
1
+ {
2
+ "files": [
3
+ ".github/workflows/publish.yml",
4
+ ".gitignore",
5
+ ".vscode/launch.json",
6
+ "LICENSE",
7
+ "MANIFEST.in",
8
+ "README.md",
9
+ "framework/.agents/skills/module_generation/SKILL.md",
10
+ "framework/.agents/skills/ode_conversion_antimony/SKILL.md",
11
+ "framework/.agents/skills/ode_extraction_pipeline/SKILL.md",
12
+ "framework/.gitignore",
13
+ "framework/AntimonyGen.py",
14
+ "framework/RxnDict_to_antimony.py",
15
+ "framework/TelluriumGen.py",
16
+ "framework/__init__.py",
17
+ "framework/antimony_utils.py",
18
+ "framework/cli.py",
19
+ "framework/data_interpolation.py",
20
+ "framework/isotopomer_tools.py",
21
+ "framework/model_generation.py",
22
+ "framework/models.py",
23
+ "framework/module_base.py",
24
+ "framework/pyantigen.py",
25
+ "framework/rate_laws.py",
26
+ "framework/reaction_creation.py",
27
+ "framework/template/Example/AntiGen_paths.py",
28
+ "framework/template/Example/Engine/Anchor_cache.py",
29
+ "framework/template/Example/Engine/Deadline.py",
30
+ "framework/template/Example/Engine/Evaluator.py",
31
+ "framework/template/Example/Engine/Event_times.py",
32
+ "framework/template/Example/Engine/Fast_profile.py",
33
+ "framework/template/Example/Engine/Fit_cache.py",
34
+ "framework/template/Example/Engine/Identifiability.py",
35
+ "framework/template/Example/Engine/Model_optimize.py",
36
+ "framework/template/Example/Engine/Model_simulate.py",
37
+ "framework/template/Example/Engine/Nuisance_sensitivity.py",
38
+ "framework/template/Example/Engine/Optimize.py",
39
+ "framework/template/Example/Engine/Petab_export.py",
40
+ "framework/template/Example/Engine/Preequil_cache.py",
41
+ "framework/template/Example/Engine/Profile_checkpoint.py",
42
+ "framework/template/Example/Engine/Results.py",
43
+ "framework/template/Example/Engine/Sensitivity_analysis.py",
44
+ "framework/template/Example/Engine/Simulate.py",
45
+ "framework/template/Example/Flipflop_reference.py",
46
+ "framework/template/Example/Model_generate.py",
47
+ "framework/template/Example/Model_run.py",
48
+ "framework/template/Example/Modules/Data.py",
49
+ "framework/template/Example/Modules/Events.py",
50
+ "framework/template/Example/Modules/Experiment.py",
51
+ "framework/template/Example/Modules/Loss_config.py",
52
+ "framework/template/Example/Modules/Observed_species.py",
53
+ "framework/template/Example/Modules/Optimizer_settings.py",
54
+ "framework/template/Example/Modules/Plots.py",
55
+ "framework/template/Example/Modules/Solver_settings.py",
56
+ "framework/template/Example/Modules/Update_opt_parameters.py",
57
+ "framework/template/Example/Modules/Update_parameters.py",
58
+ "framework/template/data/ADneg.csv",
59
+ "framework/template/data/ADpos.csv",
60
+ "framework/template/data/Flipflop.csv",
61
+ "framework/template/data/make_flipflop_data.py",
62
+ "pyproject.toml",
63
+ "setup.py",
64
+ "tests/README.md",
65
+ "tests/__init__.py",
66
+ "tests/conftest.py",
67
+ "tests/silk_fixtures/antimony_models/Antimony_Bloomingdale_2021_1a_all_reactions.txt",
68
+ "tests/silk_fixtures/antimony_models/Antimony_Bloomingdale_2021_1a_rules.txt",
69
+ "tests/silk_fixtures/antimony_models/Antimony_Elbert_2022_1a_all_reactions.txt",
70
+ "tests/silk_fixtures/antimony_models/Antimony_Elbert_2022_1a_rules.txt",
71
+ "tests/silk_fixtures/antimony_models/Bloomingdale_2021_1a/Bloomingdale_2021_1a_reactions.txt",
72
+ "tests/silk_fixtures/antimony_models/Bloomingdale_2021_1a/Bloomingdale_2021_1a_rules.txt",
73
+ "tests/silk_fixtures/antimony_models/Elbert_2022_1a/Elbert_2022_1a_reactions.txt",
74
+ "tests/silk_fixtures/antimony_models/Elbert_2022_1a/Elbert_2022_1a_rules.txt",
75
+ "tests/silk_fixtures/generated/Bloomingdale_2021_1a/Bloomingdale_2021_1a_InitialConditions.csv",
76
+ "tests/silk_fixtures/generated/Bloomingdale_2021_1a/Bloomingdale_2021_1a_events.txt",
77
+ "tests/silk_fixtures/generated/Bloomingdale_2021_1a/Bloomingdale_2021_1a_manual.txt",
78
+ "tests/silk_fixtures/generated/Bloomingdale_2021_1a/Bloomingdale_2021_1a_parameters.csv",
79
+ "tests/silk_fixtures/generated/Bloomingdale_2021_1a/Bloomingdale_2021_1a_reaction_dict.txt",
80
+ "tests/silk_fixtures/generated/Bloomingdale_2021_1a/Bloomingdale_2021_1a_reactions.txt",
81
+ "tests/silk_fixtures/generated/Bloomingdale_2021_1a/Bloomingdale_2021_1a_rules.txt",
82
+ "tests/silk_fixtures/generated/Bloomingdale_2021_1a/Bloomingdale_2021_1a_unique_compartments.txt",
83
+ "tests/silk_fixtures/generated/Bloomingdale_2021_1a/Bloomingdale_2021_1a_unique_parameters.txt",
84
+ "tests/silk_fixtures/generated/Bloomingdale_2021_1a/Bloomingdale_2021_1a_unique_species.txt",
85
+ "tests/silk_fixtures/generated/Bloomingdale_2021_1a/conversion_errors_Bloomingdale_2021_1a.log",
86
+ "tests/silk_fixtures/generated/Bloomingdale_2021_1a_all_reactions.txt",
87
+ "tests/silk_fixtures/generated/Bloomingdale_2021_1a_rules.txt",
88
+ "tests/silk_fixtures/generated/Elbert_2022_1a/Elbert_2022_1a_InitialConditions.csv",
89
+ "tests/silk_fixtures/generated/Elbert_2022_1a/Elbert_2022_1a_events.txt",
90
+ "tests/silk_fixtures/generated/Elbert_2022_1a/Elbert_2022_1a_manual.txt",
91
+ "tests/silk_fixtures/generated/Elbert_2022_1a/Elbert_2022_1a_parameters.csv",
92
+ "tests/silk_fixtures/generated/Elbert_2022_1a/Elbert_2022_1a_reaction_dict.txt",
93
+ "tests/silk_fixtures/generated/Elbert_2022_1a/Elbert_2022_1a_reactions.txt",
94
+ "tests/silk_fixtures/generated/Elbert_2022_1a/Elbert_2022_1a_rules.txt",
95
+ "tests/silk_fixtures/generated/Elbert_2022_1a/Elbert_2022_1a_unique_compartments.txt",
96
+ "tests/silk_fixtures/generated/Elbert_2022_1a/Elbert_2022_1a_unique_parameters.txt",
97
+ "tests/silk_fixtures/generated/Elbert_2022_1a/Elbert_2022_1a_unique_species.txt",
98
+ "tests/silk_fixtures/generated/Elbert_2022_1a/conversion_errors_Elbert_2022_1a.log",
99
+ "tests/silk_fixtures/generated/Elbert_2022_1a_all_reactions.txt",
100
+ "tests/silk_fixtures/generated/Elbert_2022_1a_rules.txt",
101
+ "tests/silk_fixtures/generated/conversion_errors_Bloomingdale_2021_1a.log",
102
+ "tests/silk_fixtures/generated/conversion_errors_Elbert_2022_1a.log",
103
+ "tests/silk_fixtures/generated/unique_compartments_Bloomingdale_2021_1a.txt",
104
+ "tests/silk_fixtures/generated/unique_compartments_Elbert_2022_1a.txt",
105
+ "tests/silk_fixtures/generated/unique_parameters_Bloomingdale_2021_1a.txt",
106
+ "tests/silk_fixtures/generated/unique_parameters_Elbert_2022_1a.txt",
107
+ "tests/silk_fixtures/generated/unique_species_Bloomingdale_2021_1a.txt",
108
+ "tests/silk_fixtures/generated/unique_species_Elbert_2022_1a.txt",
109
+ "tests/silk_fixtures/modules/Abeta/APP_reactions_elbert_1a.py",
110
+ "tests/silk_fixtures/modules/Abeta/Abeta_production_clearance_elbert_1a.py",
111
+ "tests/silk_fixtures/modules/Abeta/__init__.py",
112
+ "tests/silk_fixtures/modules/Antibody/__init__.py",
113
+ "tests/silk_fixtures/modules/Tissue_Flows/FCRn_flows_bloomingdale_1a.py",
114
+ "tests/silk_fixtures/modules/Tissue_Flows/Tissue_flows_bloomingdale_1a.py",
115
+ "tests/silk_fixtures/modules/Tissue_Flows/__init__.py",
116
+ "tests/silk_fixtures/modules/Tissue_Flows/cns_flows_bloomingdale_1a.py",
117
+ "tests/silk_fixtures/modules/Tissue_Flows/cns_flows_elbert_1a.py",
118
+ "tests/silk_fixtures/modules/Tissue_Rxns/Tissue_rxns_bloomingdale_1a.py",
119
+ "tests/silk_fixtures/modules/Tissue_Rxns/__init__.py",
120
+ "tests/silk_fixtures/modules/__init__.py",
121
+ "tests/silk_fixtures/scripts/Bloomingdale_2021_1a.py",
122
+ "tests/silk_fixtures/scripts/Elbert_2022_1a.py",
123
+ "tests/test_silk_all_reactions.py"
124
+ ]
125
+ }
@@ -0,0 +1,8 @@
1
+ {
2
+ "tag": "1.0.11",
3
+ "distance": 0,
4
+ "node": "gdaaaf88e980484296f77d2009b3a9f07ccafa816",
5
+ "dirty": false,
6
+ "branch": "HEAD",
7
+ "node_date": "2026-09-08"
8
+ }
@@ -0,0 +1,109 @@
1
+ ---
2
+ name: Generate PyAntiGen Modules
3
+ description: Guidelines and rules for generating new PyAntiGen modules
4
+ ---
5
+
6
+ # Generate PyAntiGen Modules
7
+
8
+ When asked to generate new reactions or modules for a new project in the PyAntiGen framework, follow these guidelines carefully. The generated modules will typically be placed in the `modules/` folder of the repository.
9
+
10
+ ## 1. File and Class Structure
11
+ - The module must be implemented as a Python class that inherits from `PyAntiGenModule`.
12
+ - Import the base class at the top of the file:
13
+ ```python
14
+ from framework.module_base import PyAntiGenModule
15
+ ```
16
+ - The class must implement a `build(self)` method.
17
+
18
+ ## 2. Handling Species and Isotopes
19
+ - Modules should retrieve their configured `Species` and `No_Isotope_SpeciesList` from `self.config`:
20
+ ```python
21
+ Species = self.config.get('Species')
22
+ No_Isotope_SpeciesList = self.config.get('No_Isotope_SpeciesList', [])
23
+ ```
24
+ - Determine the correct list of isotopes to iterate over. If the species is in `No_Isotope_SpeciesList`, it should only use the empty string `''` for its isotope label. Otherwise, use `self.model.isotopes`.
25
+ ```python
26
+ Isotopes = [''] if Species in No_Isotope_SpeciesList else self.model.isotopes
27
+ ```
28
+
29
+ ## 3. Formatting Isotope Strings
30
+ - Inside the loop over isotopes, build an `Isotope_str` to inject into reactant/product names:
31
+ ```python
32
+ for Isotope in Isotopes:
33
+ Isotope_str = f"_{Isotope}_" if Isotope else "_"
34
+ ```
35
+ - If the `Isotope` is `''` (natural abundance/unlabeled), `Isotope_str` will simply be `"_"` (e.g., resulting in `AB40_BrainISF`).
36
+ - If the `Isotope` is labeled (e.g., `'13C6Leu'`), `Isotope_str` will be `"_13C6Leu_"` (e.g., resulting in `AB40_13C6Leu_BrainISF`).
37
+
38
+ ## 4. Compartment Naming Convention
39
+ - **CRITICAL**: Compartment names **must be CamelCase (or PascalCase) and must not contain any underscores**.
40
+ - ✅ **Valid Examples**: `BrainISF`, `TissueVascular`, `SAS`, `BrainVascular`, `Endosomal`.
41
+ - ❌ **Invalid Examples**: `Brain_ISF`, `Tissue_Vascular`.
42
+
43
+ ## 5. Adding Reactions
44
+ - Use the `self.add_reaction()` method to append reactions to the model.
45
+ - **Single Species Format**: Reactants and Products must use the format `[{Species}{Isotope_str}{Compartment}]`.
46
+ - **CRITICAL - Multiple Species Array Syntax**: When a reaction has multiple reactants or products (e.g., binding of A and B), you **MUST** format the species as a comma-separated list enclosed in a single pair of brackets, like `f"[{Species1}, {Species2}]"`. Do **not** use string addition like `f"{Species1} + {Species2}"`.
47
+ - **CRITICAL - Variable Definitions**: Do not wrap your Python variables defining species names in brackets natively (e.g., use `APP = f"APP_{Comp}"` instead of `APP = f"[APP_{Comp}]"`). Supply the brackets only when passing to `add_reaction`.
48
+ - Ensure that the generated Reaction Names are descriptive and ideally incorporate the rule/flow type, the species, the isotope string, and the compartment(s).
49
+
50
+ ### Reaction Addition Example
51
+ ```python
52
+ Reaction_name = f"FlowWithinTissue_{Species}{Isotope_str}{Comp1}_{Comp2}"
53
+ Reactants = f"[{Species}{Isotope_str}{Comp1}]"
54
+ Products = f"[{Species}{Isotope_str}{Comp2}]"
55
+ Rate_type = "UDF" # Unidirectional Flow
56
+ # CRITICAL: Use parameter names (symbols), NOT hardcoded numerical values.
57
+ Rate_eqtn_prototype = "(1-RC_BBB) * Q_BrainISF"
58
+
59
+ self.add_reaction(Reaction_name, Reactants, Products, Rate_type, Rate_eqtn_prototype)
60
+ ```
61
+
62
+ ## 6. Parameter Names vs. Hardcoded Values
63
+ - **CRITICAL**: Always use **parameter names (symbols)** in your `Rate_eqtn_prototype` instead of hardcoding numerical values.
64
+ - For instance, if a clearance rate is 4.81e-5, define the equation using the parameter symbol (e.g., `\"kclearAPP\"`) rather than the number `\"4.81e-5\"`.
65
+ - This allows external scripts to parse the parameter names and values, enabling easy parameter sweeps and increasing flexibility without changing the Antimony generation code.
66
+
67
+
68
+ ## 7. Rate Types and Equation Prototypes
69
+ When adding reactions, the `Rate_type` must be carefully specified along with a properly formatted `Rate_eqtn_prototype` that corresponds to the correct units.
70
+ - **UDF (Unidirectional Flow)**: `Rate_eqtn_prototype` must have units of **[volume/time]**. Example: `\"(1-RC_BBB) * Q_BrainISF\"`.
71
+ - **BDF (Bidirectional Flow)**: Requires two rate prototypes (usually provided as an array or specific format parsed by your module) with units of **[volume/time]**.
72
+ - **MA (Mass Action)**: `Rate_eqtn_prototype` has units of **[concentration]^n/time**.
73
+ - **RMA (Reversible Mass Action)**: Requires two rate prototypes.
74
+ - **custom**: Requires providing the entire rate term with units of **[amount/time]**, where species names in the equation are treated as concentrations.
75
+
76
+ ## 8. Complete Module Example
77
+
78
+ ```python
79
+ from framework.module_base import PyAntiGenModule
80
+
81
+ class Example_FlowsModule(PyAntiGenModule):
82
+ \"\"\"
83
+ Example module for compartmental flow reactions.
84
+ \"\"\"
85
+ def build(self):
86
+ Species = self.config.get('Species')
87
+ No_Isotope_SpeciesList = self.config.get('No_Isotope_SpeciesList', [])
88
+
89
+ Isotopes = [''] if Species in No_Isotope_SpeciesList else self.model.isotopes
90
+
91
+ flow_rates = {
92
+ ('TissueVascular', 'BrainISF'): "(1-RC_BBB) * Q_BrainISF",
93
+ }
94
+
95
+ for Isotope in Isotopes:
96
+ Isotope_str = f"_{Isotope}_" if Isotope else "_"
97
+ for Comp1, Comp2 in flow_rates.keys():
98
+ Reaction_name = f"ExampleFlow_{Species}{Isotope_str}{Comp1}_{Comp2}"
99
+ Reactants = f"[{Species}{Isotope_str}{Comp1}]"
100
+ Products = f"[{Species}{Isotope_str}{Comp2}]"
101
+ Rate_type = "UDF"
102
+ Rate_eqtn_prototype = flow_rates[(Comp1, Comp2)]
103
+
104
+ self.add_reaction(Reaction_name, Reactants, Products, Rate_type, Rate_eqtn_prototype)
105
+ ```
106
+
107
+ ## 9. Reusing and Naming Modules
108
+ - **Preserve Existing Modules**: When creating a new module based on logic from an existing one, do not modify or overwrite the existing module. Leave existing code completely intact.
109
+ - **Naming Convention**: Create a new file and a new class. The new module's file name and class name should incorporate the new project's name (e.g., `CNS_Flows_<NewProjectName>Module` in `cns_flows_<newprojectname>.py`) to clearly distinguish it from prior versions and prevent accidental regression.
@@ -0,0 +1,34 @@
1
+ ---
2
+ name: Convert ODEs to Antimony
3
+ description: Guidelines for converting plain text ODEs into Antimony reactions using the PyAntiGen module framework.
4
+ ---
5
+
6
+ # Convert ODEs to Antimony
7
+ When asked to convert a system of Ordinary Differential Equations (ODEs) into Antimony format and subsequently generate a PyAntiGen module, you must follow a structured pipeline to prevent errors related to compartmental modeling, dimensional inconsistency, and raw text typos.
8
+
9
+ ## Step 1: Intermediate Reaction Extraction
10
+ Before writing any Antimony code or Python code, extract the reactions mathematically implied by the ODEs and write them sequentially as an intermediate step.
11
+ - **MathML AST Evaluation**: Many DOCX files use Word's built-in MathML (`<m:oMath>`). *Do not* naively flatten `<m:t>` text nodes! Parameters like `k_M2G` are represented as an `<m:sSub>` structure containing a base `<m:e>` and a `<m:sub>`. You must construct a recursive AST parser that evaluates tags like `sSub`, `sSup`, `f` (fractions), and `r` (text runs) separately to retain the mathematical logic! (e.g. Concatenating `sSub` base and sub fields creates unified subscript variables like `kM2G`).
12
+ - **Implied Multiplication**: Identify implied mathematical multiplication by checking if variable/parameter boundaries (e.g. `kclearAPP` followed by `APPplasma`) are explicitly adjacent in the evaluated MathML syntax blocks without an explicit operator symbol. Insert a strict `*` operator between adjacent alphanumeric strings during AST evaluation.
13
+ - Ensure you output a table format similar to the `Lin2022.docx` format.
14
+ - Structure: `Reactants -> Products | Rate expression`
15
+ - *Example*:
16
+ ```text
17
+ APPplasma + BACEplasma -> APP_BACEplasma | konPP * APPplasma * BACEplasma
18
+ ```
19
+
20
+ ## Step 2: Biological and Dimensional Error Checking
21
+ Perform a thorough inspection of the generated reaction table and the original ODEs. Compile a list of potential errors before proceeding:
22
+ 1. **Amount vs. Concentration (Dimensional Consistency)**: Check species prefixes. Species prefixed with `m` are often amounts, while others are concentrations. A binding term between an amount and a concentration directly alters both without scaling, which usually indicates a missing volume division in the concentration's ODE (e.g. `Amount * Concentration` does not yield a pure Rate of Concentration Change).
23
+ 2. **Volume Differences in Transport**: Transport between compartments (e.g., Plasma and CSF) for species measured in *concentrations* must include a volume ratio (e.g. `(V_csf / V_plasma) * k * [Species]`). If the raw ODEs omit these volume mappings but the variables are concentrations, report this error. (If the species are purely amounts, the symmetry holds without volume factors).
24
+ 3. **Typos in Raw Text**: Missing multiplication operators (e.g., `kcleaveBACEplasma` instead of `kcleave * BACEplasma`), cross-compartment typos (e.g., `Aoligcsf` used in a `bisf` equation), or injected pseudocode (e.g., `kinfusion if t<=2 h`).
25
+ 4. **Stoichiometry**: Validate that oligomerization or cleavage processes correctly balance mass.
26
+
27
+ Provide a `potential_errors.txt` (or similar summary) outlining these inconsistencies.
28
+
29
+ ## Step 3: Generate the PyAntiGen Module
30
+ Once errors are identified or corrected (if instructed), proceed to write the PyAntiGen Python module adhering to the "Generate PyAntiGen Modules" skill:
31
+ - Implement the `build(self)` method and use `self.add_reaction`.
32
+ - Adjust `Rate_eqtn_prototype` to include any requested compartment volume divisions.
33
+ - Wrap species names in brackets for array representations in PyAntiGen (e.g. `f"[{Species1}, {Species2}]"`).
34
+ - Ensure parameter symbols (not hardcoded values) are used for rate constants and volume factors.
@@ -0,0 +1,41 @@
1
+ ---
2
+ description: Pipeline for extracting ODEs from Office MathML in Word documents and formatting them into structured Reaction Tables
3
+ ---
4
+
5
+ # ODE Extraction Pipeline from Word MathML
6
+
7
+ This skill documents the automated pipeline designed to extract algebraic ordinary differential equations encoded as Office MathML (`<m:oMath>`) inside Microsoft Word (`.docx`) files, transform them into machine-readable text, and translate those ODE expressions into structured Reaction Tables suitable for validation against Antimony models.
8
+
9
+ ## Pipeline Steps
10
+
11
+ ### 1. Extract Equations from Word OMML
12
+ **Execution:** `python scripts/extract_omml_proper.py <input.docx>`
13
+ - Parses the Word archive to extract `word/document.xml`.
14
+ - Recursively evaluates MathML nodes (`m:sSub`, `m:f`, `m:sSup`, etc.).
15
+ - Binds subscripts natively to their bases (e.g., `<m:e>k</m:e>` and `<m:sub>13</m:sub>` -> `k13`).
16
+ - Intelligently injects standard `*` characters between implicitly multiplied, adjacent alphanumeric parameter strings.
17
+ - **Output:** `[filename]_extracted_omml.txt`
18
+
19
+ ### 2. Tabulate as Reactions
20
+ **Execution:** `python scripts/build_reaction_table_starred.py <input_extracted.txt> [output_table_txt]`
21
+ - Identifies mathematical derivatives, isolating the target accumulated variable (e.g., `d(Species)/dt`).
22
+ - Splits right-hand side algebraic expressions using sign boundaries while logically handling nested parentheses.
23
+ - Groups separated terms having the exact same mathematical rate back together, grouping separated productions and consumptions into a single physical reaction.
24
+ - **Format:** `Reactants -> Products | Rate equation`
25
+ - **Output:** `[filename]_reactions_table.txt`
26
+
27
+ ### 3. Normalize Nomenclature
28
+ **Execution:** `python scripts/map_species_names.py <input_table.txt> [output_mapped.txt] [dictionary_source.py]`
29
+ - Bypasses manual string-matching by importing a trusted dictionary (e.g., `name_map` from `scripts/compare_all_species.py`).
30
+ - Operates on word boundaries (`\b(key)\b`) inside the reaction table text to cleanly replace source nomenclatures into precise Antimony model equivalents.
31
+ - **Output:** `[filename]_reactions_table_mapped.txt`
32
+
33
+ ### 4. Verify and Match
34
+ **Execution:** `python scripts/match_reactions.py` *(requires paths inside script or via CLI to be matched to target system)*
35
+ - Ingests the normalized `reactions_table_mapped.txt`.
36
+ - Parses a compiled target hand-written Python Antimony model file.
37
+ - Calculates Jaccard similarity and exact intersections to match documented equations perfectly to implemented lines of code.
38
+ - Generates a human-auditable markdown report displaying isolated errors or undocumented mechanics.
39
+
40
+ ## Instructions for AI Agent
41
+ When an end-user provides a new Word Document describing mathematical equations to be translated into Antimony or to be verified against an existing codebase, run exactly steps 1 and 2 to obtain the base tabular equations. Only run step 3 if a valid dictionary exists to map the species properly. Finally, evaluate fidelity using step 4.
@@ -0,0 +1,2 @@
1
+ *.pyc
2
+ __pycache__/
@@ -0,0 +1,20 @@
1
+ """PyAntiGen: a declarative framework for building compartmental Antimony models."""
2
+
3
+ # Single source of truth for the version is the git tag, via setuptools-scm.
4
+ # _version.py is written at build time and ships inside the wheel; it is absent
5
+ # in a plain source checkout, so fall back to the installed distribution
6
+ # metadata, and finally to a clearly-invalid marker.
7
+ try:
8
+ from ._version import __version__
9
+ except ImportError: # pragma: no cover - depends on how the package was obtained
10
+ try:
11
+ from importlib.metadata import PackageNotFoundError, version as _version
12
+
13
+ try:
14
+ __version__ = _version("pyantigen")
15
+ except PackageNotFoundError:
16
+ __version__ = "0+unknown"
17
+ except ImportError:
18
+ __version__ = "0+unknown"
19
+
20
+ __all__ = ["__version__"]
@@ -0,0 +1,24 @@
1
+ # file generated by vcs-versioning
2
+ # don't change, don't track in version control
3
+ from __future__ import annotations
4
+
5
+ __all__ = [
6
+ "__version__",
7
+ "__version_tuple__",
8
+ "version",
9
+ "version_tuple",
10
+ "__commit_id__",
11
+ "commit_id",
12
+ ]
13
+
14
+ version: str
15
+ __version__: str
16
+ __version_tuple__: tuple[int | str, ...]
17
+ version_tuple: tuple[int | str, ...]
18
+ commit_id: str | None
19
+ __commit_id__: str | None
20
+
21
+ __version__ = version = '1.0.11'
22
+ __version_tuple__ = version_tuple = (1, 0, 11)
23
+
24
+ __commit_id__ = commit_id = 'gdaaaf88e9'
@@ -0,0 +1,57 @@
1
+ [build-system]
2
+ requires = ["setuptools>=68", "setuptools-scm>=8", "wheel"]
3
+ build-backend = "setuptools.build_meta"
4
+
5
+ [project]
6
+ name = "PyAntiGen"
7
+ # Version comes from the git tag via setuptools-scm; see [tool.setuptools_scm]
8
+ # below. Do not add a literal "version" here -- declaring both is a build error.
9
+ dynamic = ["version"]
10
+ description = "Short one-line description of what PyAntiGen does"
11
+ readme = "README.md"
12
+ license = { text = "MIT" } # adjust if needed
13
+ requires-python = ">=3.9"
14
+ authors = [
15
+ { name = "Don", email = "you@example.com" }
16
+ ]
17
+ keywords = ["alzheimer", "immunology", "simulation"] # tailor to your project
18
+ classifiers = [
19
+ "Programming Language :: Python :: 3",
20
+ "License :: OSI Approved :: MIT License",
21
+ "Operating System :: OS Independent",
22
+ ]
23
+ dependencies = [
24
+ "tellurium",
25
+ "scipy",
26
+ "numpy",
27
+ "pandas",
28
+ "numdifftools",
29
+ "openpyxl",
30
+ "matplotlib",
31
+ "pypesto",
32
+ ]
33
+
34
+ [project.urls]
35
+ Homepage = "https://github.com/you/PyAntiGen"
36
+
37
+ [project.scripts]
38
+ pyantigen-create = "framework.cli:create_project"
39
+
40
+ [tool.setuptools.packages.find]
41
+ include = ["framework*"]
42
+
43
+ # Version is derived from the latest git tag (v1.0.10 -> 1.0.10; the leading "v"
44
+ # is stripped automatically). Releasing is therefore: commit, tag, build.
45
+ #
46
+ # - On a clean checkout sitting exactly on a tag, the version IS that tag.
47
+ # - On any other commit, or a dirty tree, you get a development version such
48
+ # as 1.0.11.dev2+g1a2b3c4.d20260908. That carries a PEP 440 local segment,
49
+ # which PyPI refuses to accept -- deliberately. It means an untagged or
50
+ # uncommitted release fails at upload instead of shipping a wrong number.
51
+ # - Building from an export with no .git falls back to the version below,
52
+ # which is likewise unpublishable on purpose.
53
+ #
54
+ # CI must fetch full history and tags; a default shallow clone sees no tags.
55
+ [tool.setuptools_scm]
56
+ version_file = "framework/_version.py"
57
+ fallback_version = "0.0.0+unknown"
@@ -2,7 +2,9 @@ from setuptools import setup, find_packages
2
2
 
3
3
  setup(
4
4
  name='pyantigen',
5
- version='1.0.10',
5
+ # No version here. It is declared dynamic in pyproject.toml and supplied by
6
+ # setuptools-scm from the git tag; setting it in both places is a build
7
+ # error. This file now only carries package_data, which pyproject does not.
6
8
  description='A declarative framework for building compartmental Antimony models',
7
9
  author='Open Source Contributor',
8
10
  packages=find_packages(include=['framework*']),
File without changes
@@ -1,39 +0,0 @@
1
- [build-system]
2
- requires = ["setuptools>=68", "wheel"]
3
- build-backend = "setuptools.build_meta"
4
-
5
- [project]
6
- name = "PyAntiGen"
7
- version = "1.0.10"
8
- description = "Short one-line description of what PyAntiGen does"
9
- readme = "README.md"
10
- license = { text = "MIT" } # adjust if needed
11
- requires-python = ">=3.9"
12
- authors = [
13
- { name = "Don", email = "you@example.com" }
14
- ]
15
- keywords = ["alzheimer", "immunology", "simulation"] # tailor to your project
16
- classifiers = [
17
- "Programming Language :: Python :: 3",
18
- "License :: OSI Approved :: MIT License",
19
- "Operating System :: OS Independent",
20
- ]
21
- dependencies = [
22
- "tellurium",
23
- "scipy",
24
- "numpy",
25
- "pandas",
26
- "numdifftools",
27
- "openpyxl",
28
- "matplotlib",
29
- "pypesto",
30
- ]
31
-
32
- [project.urls]
33
- Homepage = "https://github.com/you/PyAntiGen"
34
-
35
- [project.scripts]
36
- pyantigen-create = "framework.cli:create_project"
37
-
38
- [tool.setuptools.packages.find]
39
- include = ["framework*"]
File without changes
File without changes
File without changes
File without changes
File without changes