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

Clean up governing_method and method in CandidateSpaces #73

Merged
merged 5 commits into from
Jan 3, 2024
Merged
Changes from 1 commit
Commits
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
44 changes: 22 additions & 22 deletions petab_select/candidate_space.py
Original file line number Diff line number Diff line change
Expand Up @@ -69,10 +69,6 @@ class CandidateSpace(abc.ABC):
An example of a difference is in the bidirectional method, where ``governing_method``
stores the bidirectional method, whereas `method` may also store the forward or
backward methods.
retry_model_space_search_if_no_models:
Whether a search with a candidate space should be repeated upon failure.
Useful for the :class:`BidirectionalCandidateSpace`, which switches directions
upon failure.
summary_tsv:
A string or :class:`pathlib.Path`. A summary of the model selection progress
will be written to this file.
Expand All @@ -85,8 +81,6 @@ class CandidateSpace(abc.ABC):
"""

governing_method: Method = None
method: Method = None
retry_model_space_search_if_no_models: bool = False

def __init__(
self,
Expand All @@ -96,14 +90,12 @@ def __init__(
limit: TYPE_LIMIT = np.inf,
summary_tsv: TYPE_PATH = None,
previous_predecessor_model: Optional[Model] = None,
method: Method = None,
):
self.limit = LimitHandler(
current=self.n_accepted,
limit=limit,
)
# Each candidate class specifies this as a class attribute.
if self.governing_method is None:
self.governing_method = self.method
self.reset(predecessor_model=predecessor_model, exclusions=exclusions)

self.summary_tsv = summary_tsv
Expand All @@ -115,6 +107,10 @@ def __init__(
if self.previous_predecessor_model is None:
self.previous_predecessor_model = self.predecessor_model

self.method = method
if self.method is None:
self.method = self.governing_method
dilpath marked this conversation as resolved.
Show resolved Hide resolved

def write_summary_tsv(self, row):
if self.summary_tsv is None:
return
Expand Down Expand Up @@ -500,7 +496,7 @@ class ForwardCandidateSpace(CandidateSpace):
Defaults to no maximum (``None``).
"""

method = Method.FORWARD
governing_method = Method.FORWARD
direction = 1

def __init__(
Expand Down Expand Up @@ -565,7 +561,7 @@ def _consider_method(self, model) -> bool:
class BackwardCandidateSpace(ForwardCandidateSpace):
"""The backward method class."""

method = Method.BACKWARD
governing_method = Method.BACKWARD
direction = -1


Expand Down Expand Up @@ -604,7 +600,7 @@ class FamosCandidateSpace(CandidateSpace):
be applied after one lateral move.
"""

method = Method.FAMOS
governing_method = Method.FAMOS
default_method_scheme = {
(Method.BACKWARD, Method.FORWARD): Method.LATERAL,
(Method.FORWARD, Method.BACKWARD): Method.LATERAL,
Expand Down Expand Up @@ -722,9 +718,12 @@ def __init__(
self.initial_method
]

super().__init__(*args, predecessor_model=predecessor_model, **kwargs)

self.governing_method = Method.FAMOS
super().__init__(
*args,
predecessor_model=predecessor_model,
method=self.method,
**kwargs,
)

self.n_reattempts = n_reattempts

Expand Down Expand Up @@ -1176,7 +1175,7 @@ def wrapper():
class LateralCandidateSpace(CandidateSpace):
"""Find models with the same number of estimated parameters."""

method = Method.LATERAL
governing_method = Method.LATERAL

def __init__(
self,
Expand Down Expand Up @@ -1233,7 +1232,7 @@ def _consider_method(self, model):
class BruteForceCandidateSpace(CandidateSpace):
"""The brute-force method class."""

method = Method.BRUTE_FORCE
governing_method = Method.BRUTE_FORCE

def __init__(self, *args, **kwargs):
# if args or kwargs:
Expand All @@ -1259,21 +1258,22 @@ def _consider_method(self, model):


def method_to_candidate_space_class(method: Method) -> Type[CandidateSpace]:
"""Instantiate a candidate space given its method name.
"""Get a candidate space class, given its method name.

Args:
method:
The name of the method corresponding to one of the implemented candidate
spaces.
The name of the method corresponding to one of the implemented
candidate spaces.

Returns:
The candidate space.
"""
for candidate_space_class in candidate_space_classes:
if candidate_space_class.method == method:
if candidate_space_class.governing_method == method:
return candidate_space_class
raise NotImplementedError(
f'The provided method name {method} does not correspond to an implemented candidate space.'
f'The provided method `{method}` does not correspond to an implemented '
'candidate space.'
)


Expand Down
Loading