@@ -992,6 +992,40 @@ def run(self, problem: Problem) -> ValidationIssue | None:
992992 return None
993993
994994
995+ class CheckHybridizationTable (ValidationTask ):
996+ """Validate the SciML hybridization table."""
997+
998+ def run (self , problem : Problem ) -> ValidationIssue | None :
999+ messages = []
1000+
1001+ condition_targets = {
1002+ c .target_id for ct in problem .conditions for c in ct .changes
1003+ }
1004+ nn_input_ids = {
1005+ inp .input_id for nn in problem .neural_networks for inp in nn .inputs
1006+ }
1007+ hyb_target_ids = {hyb .target_id for hyb in problem .hybridizations }
1008+ hyb_target_vals = {hyb .target_value for hyb in problem .hybridizations }
1009+
1010+ # Hybridization targets are not also targets in the condition table
1011+ if culprits := (hyb_target_ids & condition_targets ):
1012+ messages .append (
1013+ f"Hybridization target ids `{ culprits } ` are also "
1014+ "target ids in the condition table."
1015+ )
1016+ # NN inputs are not used as target values
1017+ if culprits := (hyb_target_vals & nn_input_ids ):
1018+ messages .append (
1019+ "The following neural net inputs were used as target values "
1020+ f"in the Hybridization tbale: `{ culprits } `. Please simplify."
1021+ )
1022+
1023+ if messages :
1024+ return ValidationError ("\n " .join (messages ))
1025+
1026+ return None
1027+
1028+
9951029def get_valid_parameters_for_parameter_table (
9961030 problem : Problem ,
9971031) -> set [str ]:
@@ -1192,3 +1226,13 @@ def get_placeholders(
11921226 CheckInitialChangeSymbols (),
11931227 CheckMappingTable (),
11941228]
1229+
1230+ #: Validation tasks that should be run PEtab SciML problems
1231+ sciml_validation_tasks = [
1232+ CheckHybridizationTable (),
1233+ ] + list (
1234+ set (default_validation_tasks )
1235+ - {
1236+ CheckAllParametersPresentInParameterTable (),
1237+ }
1238+ )
0 commit comments