Skip to content

Commit 7a2ac6e

Browse files
dweindldilpath
andauthored
Add support for pathlib.Path (#93)
Add support for pathlib.Path for reading PEtab tables and other files Closes #82 Co-authored-by: Dilan Pathirana <[email protected]>
1 parent 4f6b841 commit 7a2ac6e

File tree

13 files changed

+114
-95
lines changed

13 files changed

+114
-95
lines changed

petab/conditions.py

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,20 @@
11
"""Functions operating on the PEtab condition table"""
22

3-
from typing import Iterable, Optional, List, Union
3+
from pathlib import Path
4+
from typing import Iterable, List, Optional, Union
45

56
import numpy as np
67
import pandas as pd
78

8-
from . import lint, core
9+
from . import core, lint
910
from .C import *
1011

1112
__all__ = ['get_condition_df', 'write_condition_df', 'create_condition_df',
1213
'get_parametric_overrides']
1314

1415

1516
def get_condition_df(
16-
condition_file: Union[str, pd.DataFrame, None]
17+
condition_file: Union[str, pd.DataFrame, Path, None]
1718
) -> pd.DataFrame:
1819
"""Read the provided condition file into a ``pandas.Dataframe``
1920
@@ -25,7 +26,7 @@ def get_condition_df(
2526
if condition_file is None:
2627
return condition_file
2728

28-
if isinstance(condition_file, str):
29+
if isinstance(condition_file, (str, Path)):
2930
condition_file = pd.read_csv(condition_file, sep='\t',
3031
float_precision='round_trip')
3132

@@ -44,7 +45,7 @@ def get_condition_df(
4445
return condition_file
4546

4647

47-
def write_condition_df(df: pd.DataFrame, filename: str) -> None:
48+
def write_condition_df(df: pd.DataFrame, filename: Union[str, Path]) -> None:
4849
"""Write PEtab condition table
4950
5051
Arguments:

petab/core.py

Lines changed: 10 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
"""PEtab core functions (or functions that don't fit anywhere else)"""
2-
2+
from pathlib import Path
33
import logging
44
import os
55
import re
@@ -43,7 +43,7 @@ def write_simulation_df(df: pd.DataFrame, filename: str) -> None:
4343
df.to_csv(filename, sep='\t', index=False)
4444

4545

46-
def get_visualization_df(visualization_file: str) -> pd.DataFrame:
46+
def get_visualization_df(visualization_file: Union[str, Path]) -> pd.DataFrame:
4747
"""Read PEtab visualization table
4848
4949
Arguments:
@@ -62,7 +62,9 @@ def get_visualization_df(visualization_file: str) -> pd.DataFrame:
6262
return vis_spec
6363

6464

65-
def write_visualization_df(df: pd.DataFrame, filename: str) -> None:
65+
def write_visualization_df(
66+
df: pd.DataFrame, filename: Union[str, Path]
67+
) -> None:
6668
"""Write PEtab visualization table
6769
6870
Arguments:
@@ -241,8 +243,8 @@ def is_empty(val) -> bool:
241243

242244

243245
def create_combine_archive(
244-
yaml_file: str,
245-
filename: str,
246+
yaml_file: Union[str, Path],
247+
filename: Union[str, Path],
246248
family_name: Optional[str] = None,
247249
given_name: Optional[str] = None,
248250
email: Optional[str] = None,
@@ -260,7 +262,7 @@ def create_combine_archive(
260262
organization: Organization of archive creator
261263
"""
262264

263-
path_prefix = os.path.dirname(yaml_file)
265+
path_prefix = os.path.dirname(str(yaml_file))
264266
yaml_config = yaml.load_yaml(yaml_file)
265267

266268
# function-level import, because module-level import interfered with
@@ -285,7 +287,7 @@ def _add_file_metadata(location: str, description: str = ""):
285287

286288
# Add PEtab files and metadata
287289
archive.addFile(
288-
yaml_file,
290+
str(yaml_file),
289291
os.path.basename(yaml_file),
290292
libcombine.KnownFormats.lookupFormat("yaml"),
291293
True
@@ -353,7 +355,7 @@ def _add_file_metadata(location: str, description: str = ""):
353355
description.addCreator(creator)
354356

355357
archive.addMetadata(".", description)
356-
archive.writeToFile(filename)
358+
archive.writeToFile(str(filename))
357359

358360

359361
def unique_preserve_order(seq: Sequence) -> List:

petab/measurements.py

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,16 @@
11
"""Functions operating on the PEtab measurement table"""
22
# noqa: F405
33

4-
54
import itertools
65
import numbers
7-
from typing import List, Union, Dict
6+
from pathlib import Path
7+
from typing import Dict, List, Union
88
from warnings import warn
99

1010
import numpy as np
1111
import pandas as pd
1212

13-
from . import (lint, core, observables)
13+
from . import (core, lint, observables)
1414
from .C import * # noqa: F403
1515

1616
__all__ = ['assert_overrides_match_parameter_count',
@@ -26,7 +26,7 @@
2626

2727

2828
def get_measurement_df(
29-
measurement_file: Union[None, str, pd.DataFrame]
29+
measurement_file: Union[None, str, Path, pd.DataFrame]
3030
) -> pd.DataFrame:
3131
"""
3232
Read the provided measurement file into a ``pandas.Dataframe``.
@@ -40,7 +40,7 @@ def get_measurement_df(
4040
if measurement_file is None:
4141
return measurement_file
4242

43-
if isinstance(measurement_file, str):
43+
if isinstance(measurement_file, (str, Path)):
4444
measurement_file = pd.read_csv(measurement_file, sep='\t',
4545
float_precision='round_trip')
4646

@@ -50,7 +50,7 @@ def get_measurement_df(
5050
return measurement_file
5151

5252

53-
def write_measurement_df(df: pd.DataFrame, filename: str) -> None:
53+
def write_measurement_df(df: pd.DataFrame, filename: Union[str, Path]) -> None:
5454
"""Write PEtab measurement table
5555
5656
Arguments:

petab/observables.py

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,15 @@
11
"""Functions for working with the PEtab observables table"""
22

3+
import re
34
from collections import OrderedDict
4-
from typing import Union, List
5+
from pathlib import Path
6+
from typing import List, Union
57

68
import libsbml
79
import pandas as pd
8-
import re
910
import sympy as sp
1011

11-
from . import lint, core
12+
from . import core, lint
1213
from .C import * # noqa: F403
1314

1415
__all__ = ['create_observable_df',
@@ -20,7 +21,7 @@
2021

2122

2223
def get_observable_df(
23-
observable_file: Union[str, pd.DataFrame, None]
24+
observable_file: Union[str, pd.DataFrame, Path, None]
2425
) -> pd.DataFrame:
2526
"""
2627
Read the provided observable file into a ``pandas.Dataframe``.
@@ -34,7 +35,7 @@ def get_observable_df(
3435
if observable_file is None:
3536
return observable_file
3637

37-
if isinstance(observable_file, str):
38+
if isinstance(observable_file, (str, Path)):
3839
observable_file = pd.read_csv(observable_file, sep='\t',
3940
float_precision='round_trip')
4041

@@ -53,7 +54,7 @@ def get_observable_df(
5354
return observable_file
5455

5556

56-
def write_observable_df(df: pd.DataFrame, filename: str) -> None:
57+
def write_observable_df(df: pd.DataFrame, filename: Union[str, Path]) -> None:
5758
"""Write PEtab observable table
5859
5960
Arguments:

petab/parameters.py

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,15 @@
11
"""Functions operating on the PEtab parameter table"""
22

33
import numbers
4-
import pandas as pd
5-
import numpy as np
64
from collections import OrderedDict
7-
from typing import Iterable, Set, List, Tuple, Dict, Union
5+
from pathlib import Path
6+
from typing import Dict, Iterable, List, Set, Tuple, Union
87

98
import libsbml
9+
import numpy as np
10+
import pandas as pd
1011

11-
from . import lint, core, measurements, conditions, observables
12+
from . import conditions, core, lint, measurements, observables
1213
from .C import * # noqa: F403
1314

1415
__all__ = ['create_parameter_df',
@@ -27,7 +28,7 @@
2728

2829

2930
def get_parameter_df(
30-
parameter_file: Union[str, List[str], pd.DataFrame, None]
31+
parameter_file: Union[str, Path, List[str], pd.DataFrame, None]
3132
) -> pd.DataFrame:
3233
"""
3334
Read the provided parameter file into a ``pandas.Dataframe``.
@@ -46,7 +47,7 @@ def get_parameter_df(
4647
if isinstance(parameter_file, pd.DataFrame):
4748
parameter_df = parameter_file
4849

49-
if isinstance(parameter_file, str):
50+
if isinstance(parameter_file, (str, Path)):
5051
parameter_df = pd.read_csv(parameter_file, sep='\t',
5152
float_precision='round_trip')
5253

@@ -82,7 +83,7 @@ def get_parameter_df(
8283
return parameter_df
8384

8485

85-
def write_parameter_df(df: pd.DataFrame, filename: str) -> None:
86+
def write_parameter_df(df: pd.DataFrame, filename: Union[str, Path]) -> None:
8687
"""Write PEtab parameter table
8788
8889
Arguments:

petab/problem.py

Lines changed: 8 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,7 @@
11
"""PEtab Problem class"""
22

33
import os
4-
# Renamed to `Path_` to avoid unknown error during Sphinx doc build
5-
from pathlib import Path as Path_
4+
from pathlib import Path
65
import tempfile
76
from typing import Dict, Iterable, List, Optional, Union
87
from warnings import warn
@@ -237,7 +236,7 @@ def from_folder(folder: str, model_name: str = None) -> 'Problem':
237236
)
238237

239238
@staticmethod
240-
def from_combine(filename: str) -> 'Problem':
239+
def from_combine(filename: Union[Path, str]) -> 'Problem':
241240
"""Read PEtab COMBINE archive (http://co.mbine.org/documents/archive).
242241
243242
See also :py:func:`petab.create_combine_archive`.
@@ -258,7 +257,7 @@ def from_combine(filename: str) -> 'Problem':
258257
"(python-libcombine) must be installed.")
259258

260259
archive = libcombine.CombineArchive()
261-
if archive.initializeFromArchive(filename) is None:
260+
if archive.initializeFromArchive(str(filename)) is None:
262261
print(f"Invalid Combine Archive: {filename}")
263262
return None
264263

@@ -273,7 +272,7 @@ def from_combine(filename: str) -> 'Problem':
273272

274273
def to_files_generic(
275274
self,
276-
prefix_path: Union[str, Path_],
275+
prefix_path: Union[str, Path],
277276
) -> None:
278277
"""Save a PEtab problem to generic file names.
279278
@@ -292,7 +291,7 @@ def to_files_generic(
292291
Returns:
293292
The path to the PEtab problem YAML file.
294293
"""
295-
prefix_path = Path_(prefix_path)
294+
prefix_path = Path(prefix_path)
296295

297296
# Generate generic filenames for data tables in the PEtab problem that
298297
# contain data.
@@ -326,7 +325,7 @@ def to_files(self,
326325
visualization_file: Optional[str] = None,
327326
observable_file: Optional[str] = None,
328327
yaml_file: Optional[str] = None,
329-
prefix_path: Optional[Union[str, Path_]] = None,
328+
prefix_path: Optional[Union[str, Path]] = None,
330329
relative_paths: bool = True,) -> None:
331330
"""
332331
Write PEtab tables to files for this problem
@@ -359,9 +358,9 @@ def to_files(self,
359358
If a destination was provided for a non-existing entity.
360359
"""
361360
if prefix_path is not None:
362-
prefix_path = Path_(prefix_path)
361+
prefix_path = Path(prefix_path)
363362

364-
def add_prefix(path0: Union[None, str, Path_]) -> str:
363+
def add_prefix(path0: Union[None, str, Path]) -> str:
365364
if path0 is None:
366365
return path0
367366
return str(prefix_path / path0)

petab/sbml.py

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,12 @@
11
"""Functions for interacting with SBML models"""
2-
from warnings import warn
32
import logging
4-
from pandas.io.common import get_handle, is_url, is_file_like
53
import re
6-
from typing import Dict, Any, List, Union, Tuple
4+
from pathlib import Path
5+
from typing import Any, Dict, List, Tuple, Union
6+
from warnings import warn
7+
78
import libsbml
9+
from pandas.io.common import get_handle, is_file_like, is_url
810

911
logger = logging.getLogger(__name__)
1012
__all__ = ['add_global_parameter',
@@ -413,15 +415,18 @@ def get_model_parameters(sbml_model: libsbml.Model, with_values=False
413415
if sbml_model.getAssignmentRuleByVariable(p.getId()) is None}
414416

415417

416-
def write_sbml(sbml_doc: libsbml.SBMLDocument, filename: str) -> None:
418+
def write_sbml(
419+
sbml_doc: libsbml.SBMLDocument,
420+
filename: Union[Path, str]
421+
) -> None:
417422
"""Write PEtab visualization table
418423
419424
Arguments:
420425
sbml_doc: SBML document containing the SBML model
421426
filename: Destination file name
422427
"""
423428
sbml_writer = libsbml.SBMLWriter()
424-
ret = sbml_writer.writeSBMLToFile(sbml_doc, filename)
429+
ret = sbml_writer.writeSBMLToFile(sbml_doc, str(filename))
425430
if not ret:
426431
raise RuntimeError(f"libSBML reported error {ret} when trying to "
427432
f"create SBML file {filename}.")

0 commit comments

Comments
 (0)