Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

add compare.py which contains functions for comparing. #1206

Open
wants to merge 39 commits into
base: devel
Choose a base branch
from
Open
Changes from 1 commit
Commits
Show all changes
39 commits
Select commit Hold shift + click to select a range
3f3305c
add compare.py which contains functions for comparing.
Apr 25, 2022
3580819
fix typing and imports
Apr 25, 2022
101551d
fix .gitignore to ignore sonarlint
May 3, 2022
7419721
revised compare.py and the comparing functions
May 3, 2022
670877d
added typing and docstrings
May 3, 2022
4112af2
initial tests for compare.py
May 3, 2022
6c91335
tidying of compare.py
May 7, 2022
3f0d530
tidying of compare.py
May 9, 2022
edc4305
fixed some reaction comparison tests
May 10, 2022
2f835a6
fix: resolve E501 for mat.py
synchon May 1, 2022
7ab716e
fix: resolve F401 for cobrapy_repository.py
synchon May 1, 2022
48e433d
fix: resolve B008 and B014 for load.py
synchon May 1, 2022
0f90469
refactor: resolve D100, D103 and add type annotations and docstrings …
synchon May 1, 2022
7106669
refactor: resolve D100, add type annotations, docstrings and upgrade …
synchon May 2, 2022
0502729
refactor: resolve D100, D041 and add type annotations, docstrings for…
synchon May 2, 2022
deff161
refactor: resolve D100, F841 and add type annotations, docstrings for…
synchon May 2, 2022
aa1778e
refactor: resolve D100, D103 and add type annotations, docstrings for…
synchon May 2, 2022
8bc63e5
refactor: resolve D401, F841 and add type annotations and docstrings …
synchon May 3, 2022
434bd48
fix: docstrings fixes for test_annotation.py and test_annotation_form…
synchon May 3, 2022
015690e
chore: improve file opening for test_load.py
synchon May 3, 2022
547b2f8
chore: improve file opening for test_annotation.py
synchon May 3, 2022
3b206c1
chore: improve pytest exception handling for test_load.py
synchon May 4, 2022
2d61932
chore: add changes in next-release.md
synchon May 4, 2022
ddcd502
refactor: proper use of package import for loading resources in cobra…
synchon May 4, 2022
4d7ff97
refactor: group default repositories for load.py
synchon May 4, 2022
5a0313e
refactor: use pathlib.Path.open() for loading model in test_laod.py
synchon May 4, 2022
e98d19c
refactor: rename cobra/data/init.py to cobra/data/__init__.py
synchon May 4, 2022
cb32e2e
chore: remove unnecessary boilerplate code for singleton.py
synchon May 4, 2022
3c2362c
chore: resolve F401 for species.py
synchon May 4, 2022
e17425f
refactor: resolve F401, D103 and add type annotations, docstrings for…
synchon May 5, 2022
fb7c34d
refactor: resolve flake8 issue and add type annotations and upgrade c…
synchon May 5, 2022
3326064
refactor: remove try...except block for pytest import in conftest.py
synchon May 5, 2022
7bd0c61
refactor: remove LegacySolution class from codebase
synchon May 6, 2022
95acae6
refactor: resolve flake8 issues and add type annotations, docstrings …
synchon May 6, 2022
0a26462
refactor: resolve flake8 issues and type annotations, docstrings for …
synchon May 6, 2022
8fe367a
refactor: add further type annotations and correct f-string formattin…
synchon May 6, 2022
d55dddf
added some gene comparison tests
May 10, 2022
21eba62
black
May 10, 2022
4b92ed9
black again
May 11, 2022
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
added typing and docstrings
  • Loading branch information
uri.akavia committed May 3, 2022
commit 670877d77c38c0a85e0e83fb593abfda000fc0a2
75 changes: 56 additions & 19 deletions src/cobra/util/compare.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
"""Comparing models, reactions, metabolites, genes and groups."""

from typing import TYPE_CHECKING, Dict, Optional, Tuple, TypeVar
from typing import TYPE_CHECKING, Dict, Optional, Tuple, TypeVar, Callable

from cobra import DictList


if TYPE_CHECKING:
@@ -55,8 +57,8 @@ def compare_state(
Returns
-------
Tuple - bool, Dict
A tuple of a boolean (are the two objects different or not) and a dictionary
specifying how they differed.
A tuple of a boolean (are the two objects equivalent or different) and
a dictionary specifying how they differed.
"""
_is_equivalent = True
if ignore_keys is None:
@@ -89,8 +91,8 @@ def compare_reaction_state(
Returns
-------
Tuple - bool, Dict
A tuple of a boolean (are the two objects different or not) and a dictionary
specifying how they differed.
A tuple of a boolean (are the two objects equivalent or different) and a
dictionary specifying how they differed.
"""
_is_equivalent = True
state1 = rxn1.__getstate__()
@@ -123,8 +125,8 @@ def compare_group_state(
Returns
-------
Tuple - bool, Dict
A tuple of a boolean (are the two objects different or not) and a dictionary
specifying how they differed.
A tuple of a boolean (are the two objects equivalent or different) and a
dictionary specifying how they differed.
"""
_is_equivalent = True
state1 = group1.__getstate__()
@@ -138,24 +140,58 @@ def compare_group_state(


def compare_dictlists(
ignore_keys, dictlist_model1, dict_list_model2, comparison_function=None
dictlist1: DictList,
dictlist2: DictList,
ignore_keys: Optional[set] = None,
comparison_function: Optional[Callable] = None,
):
"""Compare dictlist of objects. Useful for comparing models.

Will check whether there are objects in dictlist1 that aren't present in dictlist2,
and vice versa.
Objects that appear in both dictlists will be compared using the comparison
function, which allows different functions for reaction or group. The default is
None, which will result in simple compare_state() used as the comparison function.

Parameters
----------
ignore_keys: set, optional
What keys should be ignored. Defualt None.
dictlist1: cobra.DictList
The first dictlist to compare
dictlist2: cobra.DictList
comparison_function: Callable
A function to use for comparing the objects in the dictlists.

Returns
-------
Tuple: bool, Dict, List
A tuple of a boolean (are the two dictlists equivalent or different) and a
dictionary specifying how they differed. It also returns a list of ids that
were present in both dictlists, but different.

See Also
--------
compare_state()
compare_reaction_state()
compare_group_state()
"""
if comparison_function is None:
comparison_function = compare_state
_is_equivalent = True
comparison = {}
diff_objs = []
ids_model1 = set(dictlist_model1.list_attr("id"))
ids_model2 = set(dict_list_model2.list_attr("id"))
ids_model1 = set(dictlist1.list_attr("id"))
ids_model2 = set(dictlist2.list_attr("id"))
if ids_model1 - ids_model2:
comparison["added"] = ids_model1 - ids_model2
_is_equivalent = False
if ids_model2 - ids_model1:
comparison["removed"] = ids_model2 - ids_model1
_is_equivalent = False
for _id in dictlist_model1.intersection(dict_list_model2):
obj1 = dictlist_model1.get_by_id(_id)
obj2 = dict_list_model2.get_by_id(_id)
for _id in dictlist1.intersection(dictlist2):
obj1 = dictlist1.get_by_id(_id)
obj2 = dictlist2.get_by_id(_id)
_eq, _comparison = comparison_function(obj1, obj2, ignore_keys=ignore_keys)
if not _eq:
_is_equivalent = False
@@ -186,12 +222,13 @@ def compare_model_state(
Other Model to compare.
ignore_notes: bool, optional
Whether or not to ignore the notes field in the model. Default True.
ignore_keys
ignore_keys: set, optional
What keys should be ignored. Defualt None.

Returns
-------
Tuple - bool, Dict
A tuple of a boolean (are the two models different or not)
A tuple of a boolean (are the two models equivalent or different)
and a dictionary specifying how they differed. The dictionary contains
different_x as a list and x for metabolites, reactions, genes, groups.
The differenet_x specifies which comparisons were not equivalent, while the
@@ -223,33 +260,33 @@ def compare_model_state(
_eq, model_comparison = compare_state(model1, model2, do_not_compare_models)
_is_equivalent = _eq
_eq, comp_result, different_ids = compare_dictlists(
ignore_keys, model1.metabolites, model2.metabolites
model1.metabolites, model2.metabolites, ignore_keys
)
model_comparison["metabolites"] = comp_result
model_comparison["different_mets"] = different_ids
_is_equivalent &= _eq

_eq, comp_result, different_ids = compare_dictlists(
ignore_keys,
model1.reactions,
model2.reactions,
ignore_keys,
comparison_function=compare_reaction_state,
)
model_comparison["reactions"] = comp_result
model_comparison["different_reactions"] = different_ids
_is_equivalent &= _eq

_eq, comp_result, different_ids = compare_dictlists(
ignore_keys, model1.genes, model2.genes
model1.genes, model2.genes, ignore_keys
)
model_comparison["genes"] = comp_result
model_comparison["different_genes"] = different_ids
_is_equivalent &= _eq

_eq, comp_result, different_ids = compare_dictlists(
ignore_keys,
model1.groups,
model2.groups,
ignore_keys,
comparison_function=compare_group_state,
)
model_comparison["genes"] = comp_result