-
Notifications
You must be signed in to change notification settings - Fork 7
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
Functions for adding conditions/observables/parameter to Problem #328
Conversation
Codecov ReportAttention: Patch coverage is
Additional details and impacted files@@ Coverage Diff @@
## develop #328 +/- ##
===========================================
- Coverage 74.86% 74.26% -0.60%
===========================================
Files 52 52
Lines 4921 5048 +127
Branches 847 888 +41
===========================================
+ Hits 3684 3749 +65
- Misses 928 962 +34
- Partials 309 337 +28 ☔ View full report in Codecov by Sentry. |
4d5e790
to
dc20a0c
Compare
dc20a0c
to
78e32c0
Compare
Will simplify writing test cases and interactively assembling petab problems. To be extended. Related to PEtab-dev#220.
78e32c0
to
6b9bff5
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think the new code here might already be handled by the old code, so I left a comment to discuss that suggestion.
@@ -1005,3 +1006,177 @@ def n_priors(self) -> int: | |||
return 0 | |||
|
|||
return self.parameter_df[OBJECTIVE_PRIOR_PARAMETERS].notna().sum() | |||
|
|||
def add_condition(self, id_: str, name: str = None, **kwargs): |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
To match column headers/C.py
? Not exactly the same due to underscores... but we could decide whether to go for consistent or context-specific IDs everywhere.
def add_condition(self, id_: str, name: str = None, **kwargs): | |
def add_condition(self, condition_id: str, condition_name: str = None, **kwargs): |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Alternative: change all of these add_*
methods to take **kwargs
that are used to create a pd.Series
, which is then validated and concatenated. get_*_df
can be used to set the index. Then no table-specific code, and no need to redefine column names here?
if not isinstance(kwarg, str) and isinstance(kwarg, list): kwarg = PARAMETER_SEPARATOR.join(map(str, kwarg))
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah, I was struggling with what would be preferable. In add_condition
, it feels redundant to prefix everything with condition_
. Then again, it might be considered confusing if the arguments don't match the table columns. For me, the former felt more important. Also with regards to potentially introducing a proper object model, I think we'd want things to be more pythonic and less petaby.
I don't think the kwargs-solution would be very convenient. That would mean, you'd have write add_observable(**{petab.OBSERVABLE_ID:"foo", petab.SIMULATION_CONDITION_ID: "bar"})
, I think then I rather directly go back to constructing dataframes.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'll leave it as is for. As discussed elsewhere, the v2 API is likely to change drastically overall where these points will be addressed.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Alright, fine for v1, we can revisit v2 in case we change the column names there
id_: str, | ||
formula: str | float | int, | ||
noise_formula: str | float | int = None, | ||
noise_distribution: str = None, | ||
transform: str = None, | ||
name: str = None, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
As above
id_: str, | |
formula: str | float | int, | |
noise_formula: str | float | int = None, | |
noise_distribution: str = None, | |
transform: str = None, | |
name: str = None, | |
observable_id: str, | |
observable_formula: str | float | int, | |
noise_formula: str | float | int = None, | |
noise_distribution: str = None, | |
transform: str = None, | |
observable_name: str = None, |
petab/v1/problem.py
Outdated
tmp_df = pd.DataFrame(record).set_index([OBSERVABLE_ID]) | ||
if self.observable_df is None: | ||
self.observable_df = tmp_df | ||
else: | ||
self.observable_df = pd.concat([self.observable_df, tmp_df]) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
pd.concat
docs:
Any None objects will be dropped silently unless they are all None in which case a ValueError will be raised.
tmp_df = pd.DataFrame(record).set_index([OBSERVABLE_ID]) | |
if self.observable_df is None: | |
self.observable_df = tmp_df | |
else: | |
self.observable_df = pd.concat([self.observable_df, tmp_df]) | |
tmp_df = pd.DataFrame(record).set_index([OBSERVABLE_ID]) | |
self.observable_df = pd.concat([self.observable_df, tmp_df]) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There is still some unnecessary things happening in pandas before this not-None object is returned. Then again, these functions here aren't so much about efficiency. I will think about it, thanks for the suggestion.
petab/v2/petab1to2.py
Outdated
if src == dest: | ||
return |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is this to skip computation or avoid an error? If the latter, then src
/dest
could be relative, so Path.resolve()
should be used first.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It's the latter. Agreed, resolve would be preferable. I didn't use it, because src/dest could be URLs. But on second thought, shutil.copy
would break on those anyways...
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
done
47534b1
to
b9fc128
Compare
b9fc128
to
34ebde1
Compare
Add functions for adding individual conditions/observables/parameter/measurements to Problem. This will simplify writing test cases and interactively assembling petab problems.
petab.v2.Problem.add_*
will be added / updated to the new format separately.Related to #220.