|
27 | 27 | "ValidationTask", |
28 | 28 | "CheckModel", |
29 | 29 | "CheckProblemConfig", |
| 30 | + "CheckMeasuredObservablesDefined", |
| 31 | + "CheckOverridesMatchPlaceholders", |
| 32 | + "CheckMeasuredExperimentsDefined", |
| 33 | + "CheckMeasurementModelId", |
30 | 34 | "CheckPosLogMeasurements", |
31 | 35 | "CheckValidConditionTargets", |
32 | 36 | "CheckUniquePrimaryKeys", |
@@ -769,8 +773,39 @@ def run(self, problem: Problem) -> ValidationIssue | None: |
769 | 773 | return None |
770 | 774 |
|
771 | 775 |
|
772 | | -# TODO: check that Measurements model IDs match the available ones |
773 | | -# https://github.com/PEtab-dev/libpetab-python/issues/392 |
| 776 | +class CheckMeasurementModelId(ValidationTask): |
| 777 | + """Validate model IDs of measurements.""" |
| 778 | + |
| 779 | + def run(self, problem: Problem) -> ValidationIssue | None: |
| 780 | + messages = [] |
| 781 | + available_models = {m.model_id for m in problem.models} |
| 782 | + |
| 783 | + for measurement in problem.measurements: |
| 784 | + if not measurement.model_id: |
| 785 | + if len(available_models) < 2: |
| 786 | + # If there is only one model, it is not required to specify |
| 787 | + # the model ID in the measurement table. |
| 788 | + continue |
| 789 | + |
| 790 | + messages.append( |
| 791 | + f"Measurement `{measurement}' does not have a model ID, " |
| 792 | + "but there are multiple models available. " |
| 793 | + "Please specify the model ID in the measurement table." |
| 794 | + ) |
| 795 | + continue |
| 796 | + |
| 797 | + if measurement.model_id not in available_models: |
| 798 | + messages.append( |
| 799 | + f"Measurement `{measurement}' has model ID " |
| 800 | + f"`{measurement.model_id}' which does not match " |
| 801 | + "any of the available models: " |
| 802 | + f"{available_models}." |
| 803 | + ) |
| 804 | + |
| 805 | + if messages: |
| 806 | + return ValidationError("\n".join(messages)) |
| 807 | + |
| 808 | + return None |
774 | 809 |
|
775 | 810 |
|
776 | 811 | def get_valid_parameters_for_parameter_table( |
@@ -1011,6 +1046,7 @@ def get_placeholders( |
1011 | 1046 | CheckProblemConfig(), |
1012 | 1047 | CheckModel(), |
1013 | 1048 | CheckUniquePrimaryKeys(), |
| 1049 | + CheckMeasurementModelId(), |
1014 | 1050 | CheckMeasuredObservablesDefined(), |
1015 | 1051 | CheckPosLogMeasurements(), |
1016 | 1052 | CheckOverridesMatchPlaceholders(), |
|
0 commit comments