Skip to content

Commit

Permalink
Unit dictionary is now pseudo-private
Browse files Browse the repository at this point in the history
This is done to remove it from the REST API since it is not part of the actual request body
  • Loading branch information
JR-1991 committed Apr 7, 2022
1 parent d3a9fcf commit df3627d
Show file tree
Hide file tree
Showing 18 changed files with 52 additions and 55 deletions.
2 changes: 1 addition & 1 deletion pyenzyme/enzymeml/core/abstract_classes.py
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ def unitdef(self):
if not self.unit:
return None

return self._enzmldoc.unit_dict[self._unit_id]
return self._enzmldoc._unit_dict[self._unit_id]


class AbstractSpeciesFactory(ABC):
Expand Down
5 changes: 2 additions & 3 deletions pyenzyme/enzymeml/core/enzymemlbase.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,6 @@ def json(self, indent: int = 2, **kwargs):
exclude_none=True,
exclude={
"log": ...,
"unit_dict": ...,
"file_dict": ...,
"protein_dict": {"Protein": {"__all__": {"_unit_id"}}},
},
Expand Down Expand Up @@ -57,7 +56,7 @@ def __setattr__(self, name, value):

# Create a new UnitDef and get the ID
new_unit_id = self._enzmldoc._convertToUnitDef(value)
value = self._enzmldoc.unit_dict[new_unit_id]._get_unit_name()
value = self._enzmldoc._unit_dict[new_unit_id]._get_unit_name()

# Set the unit ID to the object
attr_name = f"_{name}_id"
Expand All @@ -69,7 +68,7 @@ def __setattr__(self, name, value):
# Whenever a new ID is assigned, make sure the names are compliant with our standards
if "unit_id" in name and hasattr(self, "_enzmldoc"):
if self._enzmldoc:
unit_name = self._enzmldoc.unit_dict[value]._get_unit_name()
unit_name = self._enzmldoc._unit_dict[value]._get_unit_name()
attr_name = name.replace("_id", "")[1::]
super().__setattr__(attr_name, unit_name)

Expand Down
39 changes: 19 additions & 20 deletions pyenzyme/enzymeml/core/enzymemldocument.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
import seaborn as sns
import plotly.express as px

from pydantic import Field, validator, validate_arguments
from pydantic import Field, PrivateAttr, validator, validate_arguments
from typing import Dict, List, Tuple, TYPE_CHECKING, Optional, Union
from dataclasses import dataclass
from io import StringIO
Expand Down Expand Up @@ -134,12 +134,6 @@ class EnzymeMLDocument(EnzymeMLBase):
description="Dictionary mapping from reaction IDs to reaction describing objects.",
)

unit_dict: Dict[str, UnitDef] = Field(
alias="units",
default_factory=dict,
description="Dictionary mapping from unit IDs to unit describing objects.",
)

measurement_dict: Dict[str, Measurement] = Field(
alias="measurements",
default_factory=dict,
Expand All @@ -162,6 +156,9 @@ class EnzymeMLDocument(EnzymeMLBase):
default="",
)

# * Private attributes
_unit_dict: Dict[str, UnitDef] = PrivateAttr(default_factory=dict)

# ! Validators
@validator("log")
def start_logger(cls, logs: str, values: dict):
Expand Down Expand Up @@ -648,7 +645,7 @@ def _generateID(prefix: str, dictionary: dict) -> str:

return prefix + str(0)

def validate(self, yaml_path: str) -> Tuple[Dict, bool]:
def validateDocument(self, yaml_path: str) -> Tuple[Dict, bool]:
"""Validates an EnzymeML based on a given YAML file.
The YAML file should be compliant with PyEnzymes template found on Github
Expand Down Expand Up @@ -729,7 +726,7 @@ def generate_lines(dictionary: dict) -> None:

if units:
fin_string.append(">>> Units")
generate_lines(self.unit_dict)
generate_lines(self._unit_dict)

fin_string.append(">>> Reactants")
generate_lines(self.reactant_dict)
Expand Down Expand Up @@ -931,7 +928,7 @@ def addGlobalParameter(

if param.unit:
param._unit_id = self._convertToUnitDef(param.unit)
param.unit = self.unit_dict[param._unit_id]._get_unit_name()
param.unit = self._unit_dict[param._unit_id]._get_unit_name()

# Assign the current EnzymeMLDocument
param._enzmldoc = self
Expand Down Expand Up @@ -1094,12 +1091,12 @@ def _addSpecies(
if species.unit and use_parser:
unit_id = self._convertToUnitDef(species.unit)
species._unit_id = unit_id
species.unit = self.unit_dict[species._unit_id]._get_unit_name()
species.unit = self._unit_dict[species._unit_id]._get_unit_name()

elif species.unit and use_parser is False:
species._unit_id = species.unit
species.unit = self.getUnitString(species._unit_id)
species.unit = self.unit_dict[species._unit_id]._get_unit_name()
species.unit = self._unit_dict[species._unit_id]._get_unit_name()

# Log creation of the object
log_object(logger, species)
Expand Down Expand Up @@ -1261,7 +1258,9 @@ def _convert_kinetic_model_units(
for parameter in parameters:
if parameter.unit:
parameter._unit_id = enzmldoc._convertToUnitDef(parameter.unit)
parameter.unit = enzmldoc.unit_dict[parameter._unit_id]._get_unit_name()
parameter.unit = enzmldoc._unit_dict[
parameter._unit_id
]._get_unit_name()
parameter._enzmldoc = enzmldoc

def addReactions(self, reactions: List[EnzymeReaction]):
Expand Down Expand Up @@ -1360,7 +1359,7 @@ def _convertMeasurementUnits(self, measurement: Measurement) -> None:
)

# Set correct string
measurement.global_time_unit = self.unit_dict[
measurement.global_time_unit = self._unit_dict[
measurement._global_time_unit_id
]._get_unit_name()

Expand All @@ -1371,7 +1370,7 @@ def _convertMeasurementUnits(self, measurement: Measurement) -> None:
)

# Set correct string
measurement.temperature_unit = self.unit_dict[
measurement.temperature_unit = self._unit_dict[
measurement._temperature_unit_id
]._get_unit_name()

Expand Down Expand Up @@ -1489,7 +1488,7 @@ def _convertToUnitDef(self, unit: Optional[str]) -> str:

if unit is None:
raise TypeError("No unit given.")
elif unit in self.unit_dict.keys():
elif unit in self._unit_dict.keys():
return unit

return UnitCreator().getUnit(unit, self)
Expand Down Expand Up @@ -1517,7 +1516,7 @@ def getUnitString(self, unit_id: Optional[str]) -> str:
raise TypeError("No unit given.")

try:
return self.unit_dict[unit_id].name
return self._unit_dict[unit_id].name
except KeyError:
raise SpeciesNotFoundError(species_id=unit_id, enzymeml_part="Units")

Expand All @@ -1536,7 +1535,7 @@ def getUnitDef(self, id: str) -> UnitDef:

return self._getSpecies(
id=id,
dictionary=self.unit_dict,
dictionary=self._unit_dict,
element_type="Units",
)

Expand Down Expand Up @@ -1669,7 +1668,7 @@ def getAny(self, id: str) -> AbstractSpecies:
"""

all_dicts = {
**self.unit_dict,
**self._unit_dict,
**self.vessel_dict,
**self.reactant_dict,
**self.protein_dict,
Expand Down Expand Up @@ -1829,7 +1828,7 @@ def getMeasurementDict(self):

@deprecated_getter("unit_dict")
def getUnitDict(self):
return self.unit_dict
return self._unit_dict

@deprecated_getter("file_dict")
def getFileDict(self):
Expand Down
2 changes: 1 addition & 1 deletion pyenzyme/enzymeml/core/enzymereaction.py
Original file line number Diff line number Diff line change
Expand Up @@ -688,7 +688,7 @@ def unitdef(self):
if not self._enzmldoc:
return None

return self._enzmldoc.unit_dict[self._temperature_unit_id]
return self._enzmldoc._unit_dict[self._temperature_unit_id]

def getTemperature(self) -> float:
raise NotImplementedError("Temperature is now part of measurements.")
Expand Down
2 changes: 1 addition & 1 deletion pyenzyme/enzymeml/core/measurement.py
Original file line number Diff line number Diff line change
Expand Up @@ -396,7 +396,7 @@ def temperature_unitdef(self):
if not self._enzmldoc:
return None

return self._enzmldoc.unit_dict[self._temperature_unit_id]
return self._enzmldoc._unit_dict[self._temperature_unit_id]

@validate_arguments
def getReactant(self, reactant_id: str) -> MeasurementData:
Expand Down
6 changes: 3 additions & 3 deletions pyenzyme/enzymeml/core/measurementData.py
Original file line number Diff line number Diff line change
Expand Up @@ -86,7 +86,7 @@ def unifyUnits(self, kind: str, scale: int, enzmldoc) -> Optional[str]:
unit_id = None

# Transform initial concentration
unitdef: UnitDef = enzmldoc.unit_dict[self._unit_id].copy()
unitdef: UnitDef = enzmldoc._unit_dict[self._unit_id].copy()
transform_value, new_unit_name, unit_id = self._getTransformation(
unitdef, kind, scale, enzmldoc
)
Expand Down Expand Up @@ -134,7 +134,7 @@ def _rescaleReplicateUnits(
"""

data_unit_id = replicate._data_unit_id
unitdef: UnitDef = enzmldoc.unit_dict[data_unit_id].copy()
unitdef: UnitDef = enzmldoc._unit_dict[data_unit_id].copy()

# Calculate the scale to transform the unit
transform_value, new_unit_name, unit_id = self._getTransformation(
Expand Down Expand Up @@ -172,7 +172,7 @@ def unitdef(self):
if not self._enzmldoc:
return None

return self._enzmldoc.unit_dict[self._unit_id]
return self._enzmldoc._unit_dict[self._unit_id]

@deprecated_getter("reactant_id")
def getReactantID(self) -> Optional[str]:
Expand Down
4 changes: 2 additions & 2 deletions pyenzyme/enzymeml/core/replicate.py
Original file line number Diff line number Diff line change
Expand Up @@ -109,15 +109,15 @@ def data_unitdef(self):
if not self._enzmldoc:
return None

return self._enzmldoc.unit_dict[self._data_unit_id]
return self._enzmldoc._unit_dict[self._data_unit_id]

def time_unitdef(self):
"""Returns the appropriate unitdef if an enzmldoc is given"""

if not self._enzmldoc:
return None

return self._enzmldoc.unit_dict[self._time_unit_id]
return self._enzmldoc._unit_dict[self._time_unit_id]

@deprecated_getter("measurement_id")
def getMeasurement(self):
Expand Down
2 changes: 1 addition & 1 deletion pyenzyme/enzymeml/core/vessel.py
Original file line number Diff line number Diff line change
Expand Up @@ -83,7 +83,7 @@ def unitdef(self):
if not self._enzmldoc:
return None

return self._enzmldoc.unit_dict[self._unit_id]
return self._enzmldoc._unit_dict[self._unit_id]

@deprecated_getter("name")
def getName(self):
Expand Down
2 changes: 1 addition & 1 deletion pyenzyme/enzymeml/models/kineticmodel.py
Original file line number Diff line number Diff line change
Expand Up @@ -89,7 +89,7 @@ def unitdef(self):
if not self._enzmldoc:
return None

return self._enzmldoc.unit_dict[self._unit_id]
return self._enzmldoc._unit_dict[self._unit_id]


@static_check_init_args
Expand Down
8 changes: 4 additions & 4 deletions pyenzyme/enzymeml/tools/enzymemlreader.py
Original file line number Diff line number Diff line change
Expand Up @@ -147,7 +147,7 @@ def readFromFile(self, path: str) -> EnzymeMLDocument:

# Fetch units
unitDict = self._getUnits(model)
self.enzmldoc.unit_dict = unitDict
self.enzmldoc._unit_dict = unitDict

# Fetch Vessel
vessel = self._getVessel(model, self.enzmldoc)
Expand Down Expand Up @@ -728,8 +728,8 @@ def _getData(
species_id=reactant_id,
data_type=data_type,
measurement_id=measurement_id,
data_unit=enzmldoc.unit_dict[data_unit_id].name,
time_unit=enzmldoc.unit_dict[time_unit_id].name,
data_unit=enzmldoc._unit_dict[data_unit_id].name,
time_unit=enzmldoc._unit_dict[time_unit_id].name,
data=data,
time=time,
is_calculated=is_calculated,
Expand Down Expand Up @@ -879,7 +879,7 @@ def _parse_init_conc_element(element: ET.Element, enzmldoc):

# Convert the unit ID to the corresponding SI string
unit_id = element.attrib["unit"]
unit = enzmldoc.unit_dict[unit_id].name
unit = enzmldoc._unit_dict[unit_id].name

reactant_id = None
protein_id = None
Expand Down
2 changes: 1 addition & 1 deletion pyenzyme/enzymeml/tools/enzymemlwriter.py
Original file line number Diff line number Diff line change
Expand Up @@ -153,7 +153,7 @@ def convertEnzymeMLToSBML(self, model: libsbml.Model, enzmldoc):
self._addReactants(model, enzmldoc.reactant_dict)
self._addGlobalParameters(model, enzmldoc.global_parameters)
self._addReactions(model, enzmldoc.reaction_dict)
self._addUnits(model, enzmldoc.unit_dict)
self._addUnits(model, enzmldoc._unit_dict)

def _createArchive(self, enzmldoc, listofPaths, name: str = None):

Expand Down
7 changes: 3 additions & 4 deletions pyenzyme/enzymeml/tools/unitcreator.py
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ def getUnit(self, unit_string, enzmldoc) -> str:
)

# Generate ID
id = enzmldoc._generateID(prefix="u", dictionary=enzmldoc.unit_dict)
id = enzmldoc._generateID(prefix="u", dictionary=enzmldoc._unit_dict)

# Call unit parser to identify units
parser = UnitParser()
Expand Down Expand Up @@ -101,13 +101,13 @@ def getUnit(self, unit_string, enzmldoc) -> str:
if self.__checkFootprints(enzmldoc, unitdef.getFootprint()) != "NEW":
return self.__checkFootprints(enzmldoc, unitdef.getFootprint())

enzmldoc.unit_dict[unitdef.id] = unitdef
enzmldoc._unit_dict[unitdef.id] = unitdef

return unitdef.id

def __checkFootprints(self, enzmldoc, footprint):

for unit_id, unitdef in enzmldoc.unit_dict.items():
for unit_id, unitdef in enzmldoc._unit_dict.items():
if DeepDiff(unitdef.getFootprint(), footprint) == {}:
return unit_id

Expand Down Expand Up @@ -198,7 +198,6 @@ def __Dimensionless(self, unitdef, prefix=None, exponent=1):

def __getPrefix(self, prefix):


if prefix == "f":
return -15
elif prefix == "p":
Expand Down
6 changes: 3 additions & 3 deletions tests/enzymeml/core/test_enzymemldocument.py
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ def test_content(self):
assert not enzmldoc.complex_dict
assert not enzmldoc.reactant_dict
assert not enzmldoc.reaction_dict
assert not enzmldoc.unit_dict
assert not enzmldoc._unit_dict
assert not enzmldoc.file_dict
assert not enzmldoc.global_parameters

Expand All @@ -60,7 +60,7 @@ def test_defaults(self):
assert not enzmldoc.complex_dict
assert not enzmldoc.reactant_dict
assert not enzmldoc.reaction_dict
assert not enzmldoc.unit_dict
assert not enzmldoc._unit_dict
assert not enzmldoc.file_dict
assert not enzmldoc.global_parameters

Expand Down Expand Up @@ -228,7 +228,7 @@ def test_unit_attribute_change(self, enzmldoc):
def check_consistency(unit, unit_id, kind):
# Helper function
assert (
enzmldoc.unit_dict[unit_id].name == unit
enzmldoc._unit_dict[unit_id].name == unit
), f"Unit change for {kind} inconsistent"

# Test unit change vessel
Expand Down
2 changes: 1 addition & 1 deletion tests/enzymeml/core/test_enzymereaction.py
Original file line number Diff line number Diff line change
Expand Up @@ -347,7 +347,7 @@ def test_set_model(self, enzmldoc, correct_model, faulty_model):
assert parameter.name == "x"
assert parameter.value == 10.0
assert parameter.unit == "mmole / l"
assert enzmldoc.unit_dict[parameter._unit_id].name == "mmole / l"
assert enzmldoc._unit_dict[parameter._unit_id].name == "mmole / l"

# Faulty case
with pytest.raises(SpeciesNotFoundError):
Expand Down
4 changes: 2 additions & 2 deletions tests/enzymeml/core/test_measurement.py
Original file line number Diff line number Diff line change
Expand Up @@ -201,15 +201,15 @@ def test_unit_unification(self, enzmldoc):

assert replicate.data == [1000.0, 1000.0, 1000.0, 1000.0]
assert replicate.time == [1.0, 2.0, 3.0, 4.0]
assert enzmldoc.unit_dict[nu_unit_id].name == "umole / l"
assert enzmldoc._unit_dict[nu_unit_id].name == "umole / l"

# Check for proteins
replicate = measurement.species_dict["proteins"]["p0"].replicates[0]
nu_unit_id = replicate._data_unit_id

assert replicate.data == [1000.0, 1000.0, 1000.0, 1000.0]
assert replicate.time == [1.0, 2.0, 3.0, 4.0]
assert enzmldoc.unit_dict[nu_unit_id].name == "umole / l"
assert enzmldoc._unit_dict[nu_unit_id].name == "umole / l"

# Test for not supported unit kinds
with pytest.raises(ValueError):
Expand Down
2 changes: 1 addition & 1 deletion tests/enzymeml/core/test_measurement_data.py
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@ def test_unify_units(self, enzmldoc):

assert replicate.data == [1000.0, 1000.0, 1000.0, 1000.0]
assert replicate.data_unit == "umole / l"
assert enzmldoc.unit_dict[replicate._data_unit_id].name == "umole / l"
assert enzmldoc._unit_dict[replicate._data_unit_id].name == "umole / l"

assert data.init_conc == 10000.0
assert data.unit == "umole / l"
Expand Down

0 comments on commit df3627d

Please sign in to comment.