PEtab SBML import fails when setting an event-assigned parameter via the condition table
Closed this issue · 0 comments
dweindl commented
PEtab SBML import fails when setting the initial value of an event-assigned parameter via the condition table.
Fails in a rather cryptic manner:
AttributeError Traceback (most recent call last)
File python3.11/site-packages/sympy/core/numbers.py:1175, in Float.__new__(cls, num, dps, precision)
1174 try:
-> 1175 _mpf_ = num._as_mpf_val(precision)
1176 except (NotImplementedError, AttributeError):
AttributeError: 'Add' object has no attribute '_as_mpf_val'
During handling of the above exception, another exception occurred:
TypeError Traceback (most recent call last)
File python3.11/site-packages/amici/petab_import.py:356, in import_petab_problem(petab_problem, model_output_dir, model_name, force_compile, non_estimated_parameters_as_constants, **kwargs)
349 import_model_pysb(
350 petab_problem,
351 model_name=model_name,
352 model_output_dir=model_output_dir,
353 **kwargs,
354 )
355 else:
--> 356 import_model_sbml(
357 petab_problem=petab_problem,
358 model_name=model_name,
359 model_output_dir=model_output_dir,
360 non_estimated_parameters_as_constants=non_estimated_parameters_as_constants,
361 **kwargs,
362 )
364 # import model
365 model_module = amici.import_model_module(model_name, model_output_dir)
File python3.11/site-packages/amici/logging.py:209, in log_execution_time.<locals>.decorator_timer.<locals>.wrapper_timer(*args, **kwargs)
206 level_length = len("DEBUG")
208 tstart = time.perf_counter()
--> 209 rval = func(*args, **kwargs)
210 tend = time.perf_counter()
211 spacers = " " * max(
212 59
213 - len(description)
(...)
217 0,
218 )
File python3.11/site-packages/amici/petab_import.py:746, in import_model_sbml(sbml_model, condition_table, observable_table, measurement_table, petab_problem, model_name, model_output_dir, verbose, allow_reinit_fixpar_initcond, validate, non_estimated_parameters_as_constants, output_parameter_defaults, discard_sbml_annotations, **kwargs)
740 logger.info(
741 "Variable parameters: "
742 + str(len(sbml_model.getListOfParameters()) - len(fixed_parameters))
743 )
745 # Create Python module from SBML model
--> 746 sbml_importer.sbml2amici(
747 model_name=model_name,
748 output_dir=model_output_dir,
749 observables=observables,
750 constant_parameters=fixed_parameters,
751 sigmas=sigmas,
752 allow_reinit_fixpar_initcond=allow_reinit_fixpar_initcond,
753 noise_distributions=noise_distrs,
754 verbose=verbose,
755 **kwargs,
756 )
758 if kwargs.get(
759 "compile", amici._get_default_argument(sbml_importer.sbml2amici, "compile")
760 ):
761 # check that the model extension was compiled successfully
762 model_module = amici.import_model_module(model_name, model_output_dir)
File python3.11/site-packages/amici/sbml_import.py:391, in SbmlImporter.sbml2amici(self, model_name, output_dir, observables, event_observables, constant_parameters, sigmas, event_sigmas, noise_distributions, event_noise_distributions, verbose, assume_pow_positivity, compiler, allow_reinit_fixpar_initcond, compile, compute_conservation_laws, simplify, cache_simplify, log_as_log10, generate_sensitivity_code)
285 """
286 Generate and compile AMICI C++ files for the model provided to the
287 constructor.
(...)
387 not be generated
388 """
389 set_log_level(logger, verbose)
--> 391 ode_model = self._build_ode_model(
392 observables=observables,
393 event_observables=event_observables,
394 constant_parameters=constant_parameters,
395 sigmas=sigmas,
396 event_sigmas=event_sigmas,
397 noise_distributions=noise_distributions,
398 event_noise_distributions=event_noise_distributions,
399 verbose=verbose,
400 compute_conservation_laws=compute_conservation_laws,
401 simplify=simplify,
402 cache_simplify=cache_simplify,
403 log_as_log10=log_as_log10,
404 )
406 exporter = DEExporter(
407 ode_model,
408 model_name=model_name,
(...)
414 generate_sensitivity_code=generate_sensitivity_code,
415 )
416 exporter.generate_model_code()
File python3.11/site-packages/amici/sbml_import.py:463, in SbmlImporter._build_ode_model(self, observables, event_observables, constant_parameters, sigmas, event_sigmas, noise_distributions, event_noise_distributions, verbose, compute_conservation_laws, simplify, cache_simplify, log_as_log10)
459 self._reset_symbols()
460 self.sbml_parser_settings.setParseLog(
461 sbml.L3P_PARSE_LOG_AS_LOG10 if log_as_log10 else sbml.L3P_PARSE_LOG_AS_LN
462 )
--> 463 self._process_sbml(constant_parameters)
465 if (
466 self.symbols.get(SymbolId.EVENT, False)
467 or any(
(...)
471 or self.flux_vector.has(sp.Heaviside, sp.Piecewise)
472 ):
473 if compute_conservation_laws:
File python3.11/site-packages/amici/logging.py:209, in log_execution_time.<locals>.decorator_timer.<locals>.wrapper_timer(*args, **kwargs)
206 level_length = len("DEBUG")
208 tstart = time.perf_counter()
--> 209 rval = func(*args, **kwargs)
210 tend = time.perf_counter()
211 spacers = " " * max(
212 59
213 - len(description)
(...)
217 0,
218 )
File python3.11/site-packages/amici/sbml_import.py:512, in SbmlImporter._process_sbml(self, constant_parameters)
510 self._process_parameters(constant_parameters)
511 self._process_compartments()
--> 512 self._process_species()
513 self._process_reactions()
514 self._process_rules()
File python3.11/site-packages/amici/logging.py:209, in log_execution_time.<locals>.decorator_timer.<locals>.wrapper_timer(*args, **kwargs)
206 level_length = len("DEBUG")
208 tstart = time.perf_counter()
--> 209 rval = func(*args, **kwargs)
210 tend = time.perf_counter()
211 spacers = " " * max(
212 59
213 - len(description)
(...)
217 0,
218 )
File python3.11/site-packages/amici/sbml_import.py:782, in SbmlImporter._process_species(self)
770 continue
771 self.symbols[SymbolId.SPECIES][_get_identifier_symbol(s)] = {
772 "name": s.getName() if s.isSetName() else s.getId(),
773 "compartment": _get_species_compartment_symbol(s),
(...)
779 "index": len(self.symbols[SymbolId.SPECIES]),
780 }
--> 782 self._convert_event_assignment_parameter_targets_to_species()
783 self._process_species_initial()
784 self._process_rate_rules()
File python3.11/site-packages/amici/sbml_import.py:1306, in SbmlImporter._convert_event_assignment_parameter_targets_to_species(self)
1298 parameter_def = {
1299 "name": par.getName() if par.isSetName() else par.getId(),
1300 "value": par.getValue() if ia_init is None else ia_init,
1301 }
1302 # Fixed parameters are added as species such that they can be
1303 # targets of events.
1304 self.symbols[SymbolId.SPECIES][parameter_target] = {
1305 "name": parameter_def["name"],
-> 1306 "init": sp.Float(parameter_def["value"]),
1307 # 'compartment': None, # can ignore for amounts
1308 "constant": False,
1309 "amount": True,
1310 # 'conversion_factor': 1.0, # can be ignored
1311 "index": len(self.symbols[SymbolId.SPECIES]),
1312 "dt": sp.Float(0),
1313 }
File python3.11/site-packages/sympy/core/numbers.py:1177, in Float.__new__(cls, num, dps, precision)
1175 _mpf_ = num._as_mpf_val(precision)
1176 except (NotImplementedError, AttributeError):
-> 1177 _mpf_ = mpmath.mpf(num, prec=precision)._mpf_
1179 return cls._new(_mpf_, precision, zero=False)
File python3.11/site-packages/mpmath/ctx_mp_python.py:79, in _mpf.__new__(cls, val, **kwargs)
77 else:
78 v = new(cls)
---> 79 v._mpf_ = mpf_pos(cls.mpf_convert_arg(val, prec, rounding), prec, rounding)
80 return v
File python3.11/site-packages/mpmath/ctx_mp_python.py:98, in _mpf.mpf_convert_arg(cls, x, prec, rounding)
96 return a
97 raise ValueError("can only create mpf from zero-width interval")
---> 98 raise TypeError("cannot create mpf from " + repr(x))
TypeError: cannot create mpf from initial_eventAssignedParameter_preeq*preequilibration_indicator + initial_eventAssignedParameter_sim*(1 - preequilibration_indicator)
Plain SBML import (without PEtab) works. The problem is
- the current way of handling initial values for use with preequilibration (even though in this example, no preequilibration was used)
in combination with -> 1306 "init": sp.Float(parameter_def["value"]),
, which does not handle expressions properly (which isn't necessary for regular SBML import)