Skip to content

Commit 058bf1a

Browse files
authored
Merge pull request #211 from PEtab-dev/0.2.2
Release 0.2.2
2 parents ed44446 + ef072dd commit 058bf1a

File tree

10 files changed

+107
-39
lines changed

10 files changed

+107
-39
lines changed

.github/workflows/deploy.yml

Lines changed: 12 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,11 @@ on:
77
jobs:
88
deploy:
99
runs-on: ubuntu-latest
10+
environment:
11+
name: pypi
12+
url: https://pypi.org/p/sbmlmath
13+
permissions:
14+
id-token: write
1015

1116
steps:
1217
- name: Check out repository
@@ -15,14 +20,12 @@ jobs:
1520
uses: actions/setup-python@v4
1621
with:
1722
python-version: 3.11
18-
- name: Install dependencies
23+
24+
- name: Install dependencies / build sdist
1925
run: |
2026
python -m pip install --upgrade pip
21-
pip install setuptools wheel twine
22-
- name: Build and publish
23-
env:
24-
TWINE_USERNAME: ${{ secrets.PYPI_USERNAME }}
25-
TWINE_PASSWORD: ${{ secrets.PYPI_PASSWORD }}
26-
run: |
27-
python setup.py sdist bdist_wheel
28-
twine upload dist/*
27+
pip install setuptools wheel build
28+
python -m build -s
29+
30+
- name: Publish a Python distribution to PyPI
31+
uses: pypa/gh-action-pypi-publish@release/v1

CHANGELOG.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,11 @@
22

33
## 0.2 series
44

5+
### 0.2.2
6+
7+
* Fixed IndexError with numpy 1.25.0 by @dweindl in https://github.com/PEtab-dev/libpetab-python/pull/209
8+
* Made `SbmlModel.from_file(..., model_id)` optional by @dilpath in https://github.com/PEtab-dev/libpetab-python/pull/207
9+
510
### 0.2.1
611

712
Fixes:

petab/models/sbml_model.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -59,7 +59,7 @@ def __setstate__(self, state):
5959
self.__dict__.update(state)
6060

6161
@staticmethod
62-
def from_file(filepath_or_buffer, model_id: str):
62+
def from_file(filepath_or_buffer, model_id: str = None):
6363
sbml_reader, sbml_document, sbml_model = get_sbml_model(
6464
filepath_or_buffer)
6565
return SbmlModel(

petab/version.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,2 @@
11
"""PEtab library version"""
2-
__version__ = '0.2.1'
2+
__version__ = '0.2.2'

petab/visualize/plotter.py

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -116,6 +116,8 @@ def generate_lineplot(
116116
if plotTypeData == REPLICATE:
117117
replicates = np.stack(
118118
measurements_to_plot.data_to_plot.repl.values)
119+
if replicates.ndim == 1:
120+
replicates = np.expand_dims(replicates, axis=1)
119121

120122
# plot first replicate
121123
p = ax.plot(
@@ -544,6 +546,8 @@ def _line_plot_at_t_inf(
544546
p = None
545547
if plotTypeData == REPLICATE:
546548
replicates = measurements_data_to_plot_inf.repl
549+
if replicates.ndim == 0:
550+
replicates = np.expand_dims(replicates, axis=0)
547551

548552
# plot first replicate
549553
p = ax_inf.plot(
@@ -587,6 +591,8 @@ def _line_plot_at_t_inf(
587591

588592
if plotTypeData == REPLICATE:
589593
replicates = simulations_data_to_plot_inf.repl
594+
if replicates.ndim == 0:
595+
replicates = np.expand_dims(replicates, axis=0)
590596

591597
# plot first replicate
592598
p = ax_inf.plot(

pytest.ini

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
11
[pytest]
22
filterwarnings =
3+
error
34
ignore:.*inspect.getargspec\(\) is deprecated.*:DeprecationWarning

tests/test_deprecated.py

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -23,8 +23,11 @@ def test_problem_with_sbml_model():
2323
parameter_df=parameter_df,
2424
)
2525

26-
_, condition_model = petab.get_model_for_condition(
27-
petab_problem, "condition_1")
26+
with pytest.warns(UserWarning,
27+
match="An SBML rule was removed to set the component "
28+
"species_2 to a constant value."):
29+
_, condition_model = petab.get_model_for_condition(
30+
petab_problem, "condition_1")
2831

2932
check_model(condition_model)
3033

tests/test_model_pysb.py

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,19 @@
11
"""Test related to petab.models.model_pysb"""
22
import pysb
3+
import pytest
4+
35
from petab.models.pysb_model import PySBModel, parse_species_name, \
46
pattern_from_string
57

68

9+
@pytest.fixture(scope="function")
10+
def uses_pysb():
11+
"""Cleanup PySB auto-exported symbols before and after test"""
12+
pysb.SelfExporter.cleanup()
13+
yield ()
14+
pysb.SelfExporter.cleanup()
15+
16+
717
def test_parse_species_name():
818
assert parse_species_name("cyclin(Y='U', b=None)") \
919
== [("cyclin", None, {'Y': 'U', 'b': None})]
@@ -32,7 +42,7 @@ def test_parse_species_name():
3242
# TODO: MultiState
3343

3444

35-
def test_pysb_model():
45+
def test_pysb_model(uses_pysb):
3646
model = pysb.Model()
3747
pysb.Compartment("c1")
3848
pysb.Monomer("A")
@@ -58,7 +68,7 @@ def test_pysb_model():
5868
assert petab_model.is_state_variable("A(s='a')") is False
5969

6070

61-
def test_pattern_parsing():
71+
def test_pattern_parsing(uses_pysb):
6272
model = pysb.Model()
6373
c1 = pysb.Compartment("c1")
6474
A = pysb.Monomer("A")

tests/test_sbml.py

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,8 @@
1-
import sys
21
import os
2+
import sys
33

44
import pandas as pd
5+
import pytest
56

67
sys.path.append(os.getcwd())
78
import petab # noqa: E402
@@ -88,7 +89,12 @@ def test_get_condition_specific_models():
8889
)
8990

9091
# create SBML model for condition with parameters updated from problem
91-
_, condition_model = petab.get_model_for_condition(
92-
petab_problem, "condition_1")
92+
with pytest.warns(
93+
UserWarning,
94+
match="An SBML rule was removed to set the "
95+
"component species_2 to a constant value."
96+
):
97+
_, condition_model = petab.get_model_for_condition(
98+
petab_problem, "condition_1")
9399

94100
check_model(condition_model)

tests/test_visualization.py

Lines changed: 55 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,13 @@
1919
EXAMPLE_DIR = Path(__file__).parents[1] / "doc" / "example"
2020

2121

22+
@pytest.fixture(scope="function")
23+
def close_fig():
24+
"""Close all open matplotlib figures"""
25+
yield
26+
plt.close('all')
27+
28+
2229
@pytest.fixture
2330
def data_file_Fujita():
2431
return EXAMPLE_DIR / "example_Fujita" / "Fujita_measurementData.tsv"
@@ -88,6 +95,7 @@ def visu_file_Fujita_minimal():
8895
/ "Fujita_visuSpec_mandatory.tsv"
8996

9097

98+
@pytest.mark.filterwarnings("ignore:Visualization table is empty")
9199
@pytest.fixture
92100
def visu_file_Fujita_empty():
93101
return EXAMPLE_DIR / "example_Fujita" / "visuSpecs" \
@@ -137,7 +145,8 @@ def simulation_file_Isensee():
137145
def test_visualization_with_vis_and_sim(data_file_Isensee,
138146
condition_file_Isensee,
139147
vis_spec_file_Isensee,
140-
simulation_file_Isensee):
148+
simulation_file_Isensee,
149+
close_fig):
141150
validate_visualization_df(
142151
petab.Problem(
143152
condition_df=petab.get_condition_df(condition_file_Isensee),
@@ -151,7 +160,8 @@ def test_visualization_with_vis_and_sim(data_file_Isensee,
151160
def test_visualization_replicates(data_file_Isensee,
152161
condition_file_Isensee,
153162
vis_spec_file_Isensee_replicates,
154-
simulation_file_Isensee):
163+
simulation_file_Isensee,
164+
close_fig):
155165
plot_with_vis_spec(vis_spec_file_Isensee_replicates,
156166
condition_file_Isensee,
157167
data_file_Isensee, simulation_file_Isensee)
@@ -160,15 +170,17 @@ def test_visualization_replicates(data_file_Isensee,
160170
def test_visualization_scatterplot(data_file_Isensee,
161171
condition_file_Isensee,
162172
vis_spec_file_Isensee_scatterplot,
163-
simulation_file_Isensee):
173+
simulation_file_Isensee,
174+
close_fig):
164175
plot_with_vis_spec(vis_spec_file_Isensee_scatterplot,
165176
condition_file_Isensee,
166177
data_file_Isensee, simulation_file_Isensee)
167178

168179

169180
def test_visualization_small_visu_file_w_datasetid(data_file_Fujita,
170181
condition_file_Fujita,
171-
visu_file_Fujita_small):
182+
visu_file_Fujita_small,
183+
close_fig):
172184
"""
173185
Test: visualization specification file only with few columns in
174186
particular datasetId
@@ -181,7 +193,8 @@ def test_visualization_small_visu_file_w_datasetid(data_file_Fujita,
181193
def test_visualization_small_visu_file_wo_datasetid(
182194
data_file_Fujita,
183195
condition_file_Fujita,
184-
visu_file_Fujita_wo_dsid_wo_yvalues):
196+
visu_file_Fujita_wo_dsid_wo_yvalues,
197+
close_fig):
185198
"""
186199
Test: visualization specification file only with few columns in
187200
particular no datasetId column
@@ -194,7 +207,8 @@ def test_visualization_small_visu_file_wo_datasetid(
194207
def test_visualization_all_obs_with_diff_settings(
195208
data_file_Fujita,
196209
condition_file_Fujita,
197-
visu_file_Fujita_all_obs_with_diff_settings):
210+
visu_file_Fujita_all_obs_with_diff_settings,
211+
close_fig):
198212
"""
199213
Test: visualization specification file only with few columns. In
200214
particular, no datasetId column and no yValues column, but more than one
@@ -207,7 +221,8 @@ def test_visualization_all_obs_with_diff_settings(
207221

208222
def test_visualization_minimal_visu_file(data_file_Fujita,
209223
condition_file_Fujita,
210-
visu_file_Fujita_minimal):
224+
visu_file_Fujita_minimal,
225+
close_fig):
211226
"""
212227
Test: visualization specification file only with mandatory column plotId
213228
(optional columns are optional)
@@ -218,18 +233,21 @@ def test_visualization_minimal_visu_file(data_file_Fujita,
218233

219234
def test_visualization_empty_visu_file(data_file_Fujita,
220235
condition_file_Fujita,
221-
visu_file_Fujita_empty):
236+
visu_file_Fujita_empty,
237+
close_fig):
222238
"""
223239
Test: Empty visualization specification file should default to routine
224240
for no file at all
225241
"""
226-
plot_with_vis_spec(visu_file_Fujita_empty, condition_file_Fujita,
227-
data_file_Fujita)
242+
with pytest.warns(UserWarning, match="Visualization table is empty."):
243+
plot_with_vis_spec(visu_file_Fujita_empty, condition_file_Fujita,
244+
data_file_Fujita)
228245

229246

230247
def test_visualization_minimal_data_file(data_file_Fujita_minimal,
231248
condition_file_Fujita,
232-
visu_file_Fujita_wo_dsid_wo_yvalues):
249+
visu_file_Fujita_wo_dsid_wo_yvalues,
250+
close_fig):
233251
"""
234252
Test visualization, with the case: data file only with mandatory columns
235253
(optional columns are optional)
@@ -240,7 +258,8 @@ def test_visualization_minimal_data_file(data_file_Fujita_minimal,
240258

241259
def test_visualization_with_dataset_list(data_file_Isensee,
242260
condition_file_Isensee,
243-
simulation_file_Isensee):
261+
simulation_file_Isensee,
262+
close_fig):
244263
datasets = [['JI09_150302_Drg345_343_CycNuc__4_ABnOH_and_ctrl',
245264
'JI09_150302_Drg345_343_CycNuc__4_ABnOH_and_Fsk'],
246265
['JI09_160201_Drg453-452_CycNuc__ctrl',
@@ -257,7 +276,8 @@ def test_visualization_with_dataset_list(data_file_Isensee,
257276

258277
def test_visualization_without_datasets(data_file_Fujita,
259278
condition_file_Fujita,
260-
simu_file_Fujita):
279+
simu_file_Fujita,
280+
close_fig):
261281

262282
sim_cond_id_list = [['model1_data1'], ['model1_data2', 'model1_data3'],
263283
['model1_data4', 'model1_data5'], ['model1_data6']]
@@ -284,7 +304,8 @@ def test_visualization_without_datasets(data_file_Fujita,
284304

285305

286306
def test_visualization_only_simulations(condition_file_Fujita,
287-
simu_file_Fujita):
307+
simu_file_Fujita,
308+
close_fig):
288309

289310
sim_cond_id_list = [['model1_data1'], ['model1_data2', 'model1_data3'],
290311
['model1_data4', 'model1_data5'], ['model1_data6']]
@@ -300,7 +321,9 @@ def test_visualization_only_simulations(condition_file_Fujita,
300321
plotted_noise=PROVIDED)
301322

302323

303-
def test_simple_visualization(data_file_Fujita, condition_file_Fujita):
324+
def test_simple_visualization(
325+
data_file_Fujita, condition_file_Fujita, close_fig
326+
):
304327
plot_without_vis_spec(condition_file_Fujita,
305328
measurements_df=data_file_Fujita)
306329
plot_without_vis_spec(condition_file_Fujita,
@@ -311,7 +334,8 @@ def test_simple_visualization(data_file_Fujita, condition_file_Fujita):
311334
def test_visualization_with__t_inf(data_file_Fujita_t_inf,
312335
simu_file_Fujita_t_inf,
313336
condition_file_Fujita,
314-
visu_file_Fujita_replicates):
337+
visu_file_Fujita_replicates,
338+
close_fig):
315339
# plot only measurements
316340
plot_without_vis_spec(condition_file_Fujita,
317341
measurements_df=data_file_Fujita_t_inf)
@@ -333,7 +357,8 @@ def test_visualization_with__t_inf(data_file_Fujita_t_inf,
333357

334358

335359
def test_save_plots_to_file(data_file_Isensee, condition_file_Isensee,
336-
vis_spec_file_Isensee, simulation_file_Isensee):
360+
vis_spec_file_Isensee, simulation_file_Isensee,
361+
close_fig):
337362
with TemporaryDirectory() as temp_dir:
338363
plot_with_vis_spec(vis_spec_file_Isensee, condition_file_Isensee,
339364
data_file_Isensee, simulation_file_Isensee,
@@ -349,7 +374,11 @@ def test_save_visu_file(data_file_Isensee,
349374
data_file_Isensee)
350375
figure, _ = vis_spec_parser.parse_from_id_list()
351376

352-
figure.save_to_tsv(path.join(temp_dir, "visuSpec.tsv"))
377+
with pytest.warns(
378+
UserWarning,
379+
match="please check that datasetId column corresponds to"
380+
):
381+
figure.save_to_tsv(path.join(temp_dir, "visuSpec.tsv"))
353382

354383
datasets = [['JI09_150302_Drg345_343_CycNuc__4_ABnOH_and_ctrl',
355384
'JI09_150302_Drg345_343_CycNuc__4_ABnOH_and_Fsk'],
@@ -361,16 +390,20 @@ def test_save_visu_file(data_file_Isensee,
361390
data_file_Isensee)
362391
figure, _ = vis_spec_parser.parse_from_id_list(datasets,
363392
group_by='dataset')
364-
figure.save_to_tsv(path.join(temp_dir, "visuSpec1.tsv"))
393+
with pytest.warns(
394+
UserWarning,
395+
match="please check that datasetId column corresponds to"
396+
):
397+
figure.save_to_tsv(path.join(temp_dir, "visuSpec1.tsv"))
365398

366399

367-
def test_residuals_plot(simu_file_Fujita):
400+
def test_residuals_plot(simu_file_Fujita, close_fig):
368401
fujita_yaml = EXAMPLE_DIR / "example_Fujita" / "Fujita.yaml"
369402
fujita_petab_problem = petab.Problem.from_yaml(fujita_yaml)
370403
plot_residuals_vs_simulation(fujita_petab_problem, simu_file_Fujita)
371404

372405

373-
def test_goodness_of_fit_plot(simu_file_Fujita):
406+
def test_goodness_of_fit_plot(simu_file_Fujita, close_fig):
374407
fujita_yaml = EXAMPLE_DIR / "example_Fujita" / "Fujita.yaml"
375408
fujita_petab_problem = petab.Problem.from_yaml(fujita_yaml)
376409
plot_goodness_of_fit(fujita_petab_problem, simu_file_Fujita)
@@ -389,6 +422,7 @@ def test_cli():
389422
subprocess.run(args, check=True)
390423

391424

425+
@pytest.mark.filterwarnings("ignore:Visualization table is empty")
392426
@pytest.mark.parametrize(
393427
"vis_file",
394428
(

0 commit comments

Comments
 (0)