Skip to content

v2: Don't merge tables when creating Problem #405

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

Merged
merged 2 commits into from
Jul 21, 2025

Conversation

dweindl
Copy link
Member

@dweindl dweindl commented Jul 21, 2025

PEtab allows spreading conditions/observables/measurements/... across multiple tables. So far, the different tables of a certain type are merged when creating a Problem. This is convenient for simulation, but pretty inconvenient when loading/modifying/saving the problem, where one usually wants to maintain the old structure.

This replaces Problem.${type}_table: ${type}Table by Problem.${type}_tables: list[${type}Table] table and introduces a Problem.${type} property that combines them on demand.

Closes #404.

PEtab allows spreading conditions/observables/measurements/... across multiple tables. So far, the different tables of a certain type are merged when creating a `Problem`. This is convenient for simulation, but pretty inconvenient when loading/modifying/saving the problem, where one usually wants to maintain the old structure.

This replaces `Problem.${type}_table: ${type}Table` by `Problem.${type}_tables: list[${type}Table]` table and introduces a `Problem.${type}` property that combines them on demand.

Closes PEtab-dev#404.
@dweindl dweindl self-assigned this Jul 21, 2025
@codecov-commenter
Copy link

codecov-commenter commented Jul 21, 2025

Codecov Report

Attention: Patch coverage is 60.13514% with 59 lines in your changes missing coverage. Please review.

Project coverage is 73.86%. Comparing base (153f2bd) to head (7bc254d).

Files with missing lines Patch % Lines
petab/v2/problem.py 52.42% 40 Missing and 9 partials ⚠️
petab/v2/lint.py 73.68% 8 Missing and 2 partials ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##             main     #405      +/-   ##
==========================================
- Coverage   74.18%   73.86%   -0.32%     
==========================================
  Files          62       62              
  Lines        6794     6835      +41     
  Branches     1184     1199      +15     
==========================================
+ Hits         5040     5049       +9     
- Misses       1306     1328      +22     
- Partials      448      458      +10     

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

@dweindl dweindl marked this pull request as ready for review July 21, 2025 07:58
@dweindl dweindl requested a review from a team as a code owner July 21, 2025 07:58
Copy link
Member

@dilpath dilpath left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Overall looks good 👍

I am not sure about the naming of e.g. problem.conditions. Since it's read-only, a getter method, e.g. problem.get_conditions() seems more appropriate, so users are less likely to make the mistake of trying to set condition values with the output from problem.conditions. This might be a problem for older users especially, who are used to a single table.


@property
def experiment_df(self) -> pd.DataFrame | None:
"""Experiment table as DataFrame."""
return self.experiment_table.to_df() if self.experiment_table else None
experiments = self.experiments
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Use self.experiments directly?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That requires building the list twice. Can be changed to an assignment expression, though.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ah, nevermind then!

Comment on lines +931 to +932
If there are more than one condition tables, the condition
is added to the last one.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Doc mapping table?

Comment on lines 953 to 955
if not self.mapping_tables:
self.mapping_tables.append(core.MappingTable(mappings=[]))
self.mapping_tables[-1].mappings.append(
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As self.add_mapping? But model_id is required there.

@dweindl
Copy link
Member Author

dweindl commented Jul 21, 2025

I am not sure about the naming of e.g. problem.conditions. Since it's read-only, a getter method, e.g. problem.get_conditions() seems more appropriate, so users are less likely to make the mistake of trying to set condition values with the output from problem.conditions. This might be a problem for older users especially, who are used to a single table.

I find that unnecessarily verbose. I think, Python users should not be too surprised about any read-only properties. Any decent IDE with static type-checking will flag such a mistake.

@dilpath
Copy link
Member

dilpath commented Jul 21, 2025

Python users should not be too surprised about any read-only properties. Any decent IDE with static type-checking will flag such a mistake.

A user might take the dataframe and start editing it without realizing that it doesn't edit the actual problem. e.g. problem.condition_df.loc[...] = 2 doesn't cause an issue? Or is this also flagged by the static type checker? Old code by users might have this kind of thing already, which might make migration confusing.

@dweindl
Copy link
Member Author

dweindl commented Jul 21, 2025

A user might take the dataframe and start editing it without realizing that it doesn't edit the actual problem. e.g. problem.conditions.loc[...] = 2 doesn't cause an issue? Or is this also flagged by the static type checker?

Do you mean Problem.conditions -> list[Condition] or Problem.condition_df -> pandas.DataFrame?

I'd be fine with removing the latter completely...

@dilpath
Copy link
Member

dilpath commented Jul 21, 2025

Do you mean Problem.conditions -> list[Condition] or Problem.condition_df -> pandas.DataFrame?

I'd be fine with removing the latter completely...

Sorry, makes sense now, I edited my last comment. Yes, Problem.condition_df would be confusing for old users IMO. The new Problem.conditions can be used to edit individual conditions so is intuitive like that 👍

@dweindl dweindl merged commit fb36efa into PEtab-dev:main Jul 21, 2025
6 checks passed
@dweindl dweindl deleted the feature_separate_tables branch July 21, 2025 14:09
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

v2: Don't merge tables when creating Problem
3 participants