Skip to content

Commit

Permalink
Add support for pathlib.Path (#93)
Browse files Browse the repository at this point in the history
Add support for pathlib.Path for reading PEtab tables and other files

Closes #82

Co-authored-by: Dilan Pathirana <59329744+dilpath@users.noreply.github.com>
  • Loading branch information
dweindl and dilpath authored Nov 29, 2021
1 parent 4f6b841 commit 7a2ac6e
Show file tree
Hide file tree
Showing 13 changed files with 114 additions and 95 deletions.
11 changes: 6 additions & 5 deletions petab/conditions.py
Original file line number Diff line number Diff line change
@@ -1,19 +1,20 @@
"""Functions operating on the PEtab condition table"""

from typing import Iterable, Optional, List, Union
from pathlib import Path
from typing import Iterable, List, Optional, Union

import numpy as np
import pandas as pd

from . import lint, core
from . import core, lint
from .C import *

__all__ = ['get_condition_df', 'write_condition_df', 'create_condition_df',
'get_parametric_overrides']


def get_condition_df(
condition_file: Union[str, pd.DataFrame, None]
condition_file: Union[str, pd.DataFrame, Path, None]
) -> pd.DataFrame:
"""Read the provided condition file into a ``pandas.Dataframe``
Expand All @@ -25,7 +26,7 @@ def get_condition_df(
if condition_file is None:
return condition_file

if isinstance(condition_file, str):
if isinstance(condition_file, (str, Path)):
condition_file = pd.read_csv(condition_file, sep='\t',
float_precision='round_trip')

Expand All @@ -44,7 +45,7 @@ def get_condition_df(
return condition_file


def write_condition_df(df: pd.DataFrame, filename: str) -> None:
def write_condition_df(df: pd.DataFrame, filename: Union[str, Path]) -> None:
"""Write PEtab condition table
Arguments:
Expand Down
18 changes: 10 additions & 8 deletions petab/core.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
"""PEtab core functions (or functions that don't fit anywhere else)"""

from pathlib import Path
import logging
import os
import re
Expand Down Expand Up @@ -43,7 +43,7 @@ def write_simulation_df(df: pd.DataFrame, filename: str) -> None:
df.to_csv(filename, sep='\t', index=False)


def get_visualization_df(visualization_file: str) -> pd.DataFrame:
def get_visualization_df(visualization_file: Union[str, Path]) -> pd.DataFrame:
"""Read PEtab visualization table
Arguments:
Expand All @@ -62,7 +62,9 @@ def get_visualization_df(visualization_file: str) -> pd.DataFrame:
return vis_spec


def write_visualization_df(df: pd.DataFrame, filename: str) -> None:
def write_visualization_df(
df: pd.DataFrame, filename: Union[str, Path]
) -> None:
"""Write PEtab visualization table
Arguments:
Expand Down Expand Up @@ -241,8 +243,8 @@ def is_empty(val) -> bool:


def create_combine_archive(
yaml_file: str,
filename: str,
yaml_file: Union[str, Path],
filename: Union[str, Path],
family_name: Optional[str] = None,
given_name: Optional[str] = None,
email: Optional[str] = None,
Expand All @@ -260,7 +262,7 @@ def create_combine_archive(
organization: Organization of archive creator
"""

path_prefix = os.path.dirname(yaml_file)
path_prefix = os.path.dirname(str(yaml_file))
yaml_config = yaml.load_yaml(yaml_file)

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

# Add PEtab files and metadata
archive.addFile(
yaml_file,
str(yaml_file),
os.path.basename(yaml_file),
libcombine.KnownFormats.lookupFormat("yaml"),
True
Expand Down Expand Up @@ -353,7 +355,7 @@ def _add_file_metadata(location: str, description: str = ""):
description.addCreator(creator)

archive.addMetadata(".", description)
archive.writeToFile(filename)
archive.writeToFile(str(filename))


def unique_preserve_order(seq: Sequence) -> List:
Expand Down
12 changes: 6 additions & 6 deletions petab/measurements.py
Original file line number Diff line number Diff line change
@@ -1,16 +1,16 @@
"""Functions operating on the PEtab measurement table"""
# noqa: F405


import itertools
import numbers
from typing import List, Union, Dict
from pathlib import Path
from typing import Dict, List, Union
from warnings import warn

import numpy as np
import pandas as pd

from . import (lint, core, observables)
from . import (core, lint, observables)
from .C import * # noqa: F403

__all__ = ['assert_overrides_match_parameter_count',
Expand All @@ -26,7 +26,7 @@


def get_measurement_df(
measurement_file: Union[None, str, pd.DataFrame]
measurement_file: Union[None, str, Path, pd.DataFrame]
) -> pd.DataFrame:
"""
Read the provided measurement file into a ``pandas.Dataframe``.
Expand All @@ -40,7 +40,7 @@ def get_measurement_df(
if measurement_file is None:
return measurement_file

if isinstance(measurement_file, str):
if isinstance(measurement_file, (str, Path)):
measurement_file = pd.read_csv(measurement_file, sep='\t',
float_precision='round_trip')

Expand All @@ -50,7 +50,7 @@ def get_measurement_df(
return measurement_file


def write_measurement_df(df: pd.DataFrame, filename: str) -> None:
def write_measurement_df(df: pd.DataFrame, filename: Union[str, Path]) -> None:
"""Write PEtab measurement table
Arguments:
Expand Down
13 changes: 7 additions & 6 deletions petab/observables.py
Original file line number Diff line number Diff line change
@@ -1,14 +1,15 @@
"""Functions for working with the PEtab observables table"""

import re
from collections import OrderedDict
from typing import Union, List
from pathlib import Path
from typing import List, Union

import libsbml
import pandas as pd
import re
import sympy as sp

from . import lint, core
from . import core, lint
from .C import * # noqa: F403

__all__ = ['create_observable_df',
Expand All @@ -20,7 +21,7 @@


def get_observable_df(
observable_file: Union[str, pd.DataFrame, None]
observable_file: Union[str, pd.DataFrame, Path, None]
) -> pd.DataFrame:
"""
Read the provided observable file into a ``pandas.Dataframe``.
Expand All @@ -34,7 +35,7 @@ def get_observable_df(
if observable_file is None:
return observable_file

if isinstance(observable_file, str):
if isinstance(observable_file, (str, Path)):
observable_file = pd.read_csv(observable_file, sep='\t',
float_precision='round_trip')

Expand All @@ -53,7 +54,7 @@ def get_observable_df(
return observable_file


def write_observable_df(df: pd.DataFrame, filename: str) -> None:
def write_observable_df(df: pd.DataFrame, filename: Union[str, Path]) -> None:
"""Write PEtab observable table
Arguments:
Expand Down
15 changes: 8 additions & 7 deletions petab/parameters.py
Original file line number Diff line number Diff line change
@@ -1,14 +1,15 @@
"""Functions operating on the PEtab parameter table"""

import numbers
import pandas as pd
import numpy as np
from collections import OrderedDict
from typing import Iterable, Set, List, Tuple, Dict, Union
from pathlib import Path
from typing import Dict, Iterable, List, Set, Tuple, Union

import libsbml
import numpy as np
import pandas as pd

from . import lint, core, measurements, conditions, observables
from . import conditions, core, lint, measurements, observables
from .C import * # noqa: F403

__all__ = ['create_parameter_df',
Expand All @@ -27,7 +28,7 @@


def get_parameter_df(
parameter_file: Union[str, List[str], pd.DataFrame, None]
parameter_file: Union[str, Path, List[str], pd.DataFrame, None]
) -> pd.DataFrame:
"""
Read the provided parameter file into a ``pandas.Dataframe``.
Expand All @@ -46,7 +47,7 @@ def get_parameter_df(
if isinstance(parameter_file, pd.DataFrame):
parameter_df = parameter_file

if isinstance(parameter_file, str):
if isinstance(parameter_file, (str, Path)):
parameter_df = pd.read_csv(parameter_file, sep='\t',
float_precision='round_trip')

Expand Down Expand Up @@ -82,7 +83,7 @@ def get_parameter_df(
return parameter_df


def write_parameter_df(df: pd.DataFrame, filename: str) -> None:
def write_parameter_df(df: pd.DataFrame, filename: Union[str, Path]) -> None:
"""Write PEtab parameter table
Arguments:
Expand Down
17 changes: 8 additions & 9 deletions petab/problem.py
Original file line number Diff line number Diff line change
@@ -1,8 +1,7 @@
"""PEtab Problem class"""

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

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

archive = libcombine.CombineArchive()
if archive.initializeFromArchive(filename) is None:
if archive.initializeFromArchive(str(filename)) is None:
print(f"Invalid Combine Archive: {filename}")
return None

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

def to_files_generic(
self,
prefix_path: Union[str, Path_],
prefix_path: Union[str, Path],
) -> None:
"""Save a PEtab problem to generic file names.
Expand All @@ -292,7 +291,7 @@ def to_files_generic(
Returns:
The path to the PEtab problem YAML file.
"""
prefix_path = Path_(prefix_path)
prefix_path = Path(prefix_path)

# Generate generic filenames for data tables in the PEtab problem that
# contain data.
Expand Down Expand Up @@ -326,7 +325,7 @@ def to_files(self,
visualization_file: Optional[str] = None,
observable_file: Optional[str] = None,
yaml_file: Optional[str] = None,
prefix_path: Optional[Union[str, Path_]] = None,
prefix_path: Optional[Union[str, Path]] = None,
relative_paths: bool = True,) -> None:
"""
Write PEtab tables to files for this problem
Expand Down Expand Up @@ -359,9 +358,9 @@ def to_files(self,
If a destination was provided for a non-existing entity.
"""
if prefix_path is not None:
prefix_path = Path_(prefix_path)
prefix_path = Path(prefix_path)

def add_prefix(path0: Union[None, str, Path_]) -> str:
def add_prefix(path0: Union[None, str, Path]) -> str:
if path0 is None:
return path0
return str(prefix_path / path0)
Expand Down
15 changes: 10 additions & 5 deletions petab/sbml.py
Original file line number Diff line number Diff line change
@@ -1,10 +1,12 @@
"""Functions for interacting with SBML models"""
from warnings import warn
import logging
from pandas.io.common import get_handle, is_url, is_file_like
import re
from typing import Dict, Any, List, Union, Tuple
from pathlib import Path
from typing import Any, Dict, List, Tuple, Union
from warnings import warn

import libsbml
from pandas.io.common import get_handle, is_file_like, is_url

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


def write_sbml(sbml_doc: libsbml.SBMLDocument, filename: str) -> None:
def write_sbml(
sbml_doc: libsbml.SBMLDocument,
filename: Union[Path, str]
) -> None:
"""Write PEtab visualization table
Arguments:
sbml_doc: SBML document containing the SBML model
filename: Destination file name
"""
sbml_writer = libsbml.SBMLWriter()
ret = sbml_writer.writeSBMLToFile(sbml_doc, filename)
ret = sbml_writer.writeSBMLToFile(sbml_doc, str(filename))
if not ret:
raise RuntimeError(f"libSBML reported error {ret} when trying to "
f"create SBML file {filename}.")
Expand Down
Loading

0 comments on commit 7a2ac6e

Please sign in to comment.