def test_get_loss(self, extended_simulator, t, metric, handle_CVodeError): # Create some measurement objects from predictions, i.e. create some artifical data predicitions = extended_simulator.simulate(t=t) measurements = [ Measurement(name=_prediction.name, timepoints=_prediction.timepoints, values=_prediction.values, errors=np.ones_like(_prediction.values)) for _prediction in predicitions ] extended_simulator._get_loss(metric=metric, measurements=measurements) # Loss will be nan in case no relevant measurements are provided, i.e. measurements for states that are not defined assert np.isnan( extended_simulator._get_loss(metric=metric, measurements=[ Measurement(name='y1000', timepoints=[100, 200], values=[1, 2], errors=[10, 20]), ])) # Get loss for other parameters, as a minimizer would do several times _params = extended_simulator.get_all_parameters() different_params = {_p: _params[_p] * 0.95 for _p in _params} extended_simulator._get_loss_for_minimzer( metric=metric, guess_dict=different_params, measurements=measurements, handle_CVodeError=handle_CVodeError, verbosity_CVodeError=False, )
class StaticHelpers(): data_single = [Measurement(name='y0', timepoints=[1, 2, 3], values=[10, 10 ,10], errors=[0.1, 0.2, 0.3])] data_multi = [ Measurement(name='y0', timepoints=[1, 2, 3], values=[10, 10 ,10], errors=[0.1, 0.2, 0.3], replicate_id='1st'), Measurement(name='y0', timepoints=[1, 5, 10], values=[10, 10 ,10], errors=[0.1, 0.2, 0.3], replicate_id='2nd'), ] many_time_series_1 = [ [TimeSeries(name='T1', timepoints=[1, 2, 3, 4], values=[10, 10, 10, 10], replicate_id='1st')], [TimeSeries(name='T1', timepoints=[1, 2, 3], values=[10, 10, 10], replicate_id='1st')], ] unknowns = ['y00', 'y10'] bounds = [(-100, 100), (-100, 100)]
class StaticDatatypes(): timeseries = TimeSeries( name=StaticHelpers.name, timepoints=StaticHelpers.timepoints, values=StaticHelpers.values, replicate_id=StaticHelpers.replicate_id ) modelstate = ModelState( name=StaticHelpers.name, timepoints=StaticHelpers.timepoints, values=StaticHelpers.values, replicate_id=StaticHelpers.replicate_id ) measurement_wo_errs = Measurement( name=StaticHelpers.name, timepoints=StaticHelpers.timepoints, values=StaticHelpers.values, replicate_id=StaticHelpers.replicate_id ) measurement_w_errs = Measurement( name=StaticHelpers.name, timepoints=StaticHelpers.timepoints, values=StaticHelpers.values, errors=StaticHelpers.errors, replicate_id=StaticHelpers.replicate_id ) observation = Observation( name=StaticHelpers.name, timepoints=StaticHelpers.timepoints, values=StaticHelpers.values, observed_state=StaticHelpers.state, replicate_id=StaticHelpers.replicate_id ) sensitivity = Sensitivity( timepoints=StaticHelpers.timepoints, values=StaticHelpers.values, response=StaticHelpers.state, parameter=StaticHelpers.parameter, replicate_id=StaticHelpers.replicate_id )
class StaticHelpers(): data_single = [ Measurement(name='y0', timepoints=[1, 2, 3], values=[10, 20, 30], errors=[0.1, 0.2, 0.3]) ] data_multi = [ Measurement(name='y0', timepoints=[1, 2, 3], values=[10, 20, 30], errors=[0.1, 0.2, 0.3], replicate_id='1st') ] unknowns = ['y00', 'y10'] bounds = [(-100, 100), (-100, 100)]
class StaticData(): measurements_wo_errors = Measurement(name='M1', timepoints=[1, 2, 3], values=[10, 20, 30], replicate_id='1st') measurements_w_errors = Measurement(name='M2', timepoints=[2, 3, 4], values=[20, 30, 40], errors=[1 / 20, 1 / 30, 1 / 40], replicate_id='1st') time_series_1 = TimeSeries(name='TS1', timepoints=[1, 2], values=[10, 20], replicate_id='1st') time_series_2 = TimeSeries(name='TS2', timepoints=[2, 3], values=[20, 30], replicate_id='2nd')
def test_with_model_enforcing_CVodeError(self): name = 'model06' modelclass = ModelLibrary.modelclasses[name] model_parameters = ModelLibrary.model_parameters[name] initial_values = ModelLibrary.initial_values[name] extended_simulator = ExtendedSimulator( bioprocess_model_class=modelclass, model_parameters=model_parameters, initial_values=initial_values) # The chosen model will create an integration error for rate = 0. A RuntimeWarning is tehrefore raised before the CVodeError is raised with pytest.warns(RuntimeWarning): with pytest.raises(CVodeError): extended_simulator.simulate(t=24, parameters={'rate0': 0}) with pytest.warns(RuntimeWarning): with pytest.raises(CVodeError): extended_simulator._get_loss_for_minimzer( metric='negLL', guess_dict={'rate0': 0}, measurements=[ Measurement(name='y0', timepoints=[1, 2, 3], values=[10, 20, 30]), ], handle_CVodeError=False, verbosity_CVodeError=False, ) # For toxic parameters causing integration errors, CVodeError handling results in inf loss with pytest.warns(RuntimeWarning): assert np.isinf( extended_simulator._get_loss_for_minimzer( metric='negLL', guess_dict={'rate0': 0}, measurements=[ Measurement(name='y0', timepoints=[1, 2, 3], values=[10, 20, 30]), ], handle_CVodeError=True, verbosity_CVodeError=True, ))
def test_init_datatypes(self, values, errors, info, replicate_id): """ To test typical instantiations of datatypes. """ # Standard instatiations TimeSeries(name=StaticHelpers.name, timepoints=StaticHelpers.timepoints, values=values, info=info, replicate_id=replicate_id) ModelState(name=StaticHelpers.name, timepoints=StaticHelpers.timepoints, values=values, info=info, replicate_id=replicate_id) Measurement(name=StaticHelpers.name, timepoints=StaticHelpers.timepoints, values=values, errors=errors, info=info, replicate_id=replicate_id) Observation(name=StaticHelpers.name, timepoints=StaticHelpers.timepoints, values=values, observed_state='y1', replicate_id=replicate_id) Sensitivity(timepoints=StaticHelpers.timepoints, values=values, response='y1', parameter='p1', replicate_id=replicate_id) Sensitivity(timepoints=StaticHelpers.timepoints, values=values, response='y1', parameter='p1', h=1e-8, replicate_id=replicate_id) # Must provide timepoints with pytest.raises(ValueError): TimeSeries(name=StaticHelpers.name, timepoints=None, values=values) # Must provide values with pytest.raises(ValueError): TimeSeries(name=StaticHelpers.name, timepoints=StaticHelpers.timepoints, values=None) # Measurements can be created with error_models Measurement( name=StaticHelpers.name, timepoints=StaticHelpers.timepoints, values=values, error_model=StaticErrorModelHelpers.constant_error_model, error_model_parameters=StaticErrorModelHelpers.constant_error_model_parameters, ) # Must provide a subclass of rvs.continous as p.d.f. with pytest.raises(ValueError): Measurement(name=StaticHelpers.name, timepoints=StaticHelpers.timepoints, values=values, error_distribution=scipy.stats.bernoulli) # Error values must be >0 with pytest.raises(ValueError): Measurement(name=StaticHelpers.name, timepoints=StaticHelpers.timepoints, values=values, errors=[0]*len(StaticHelpers.values)) with pytest.raises(ValueError): Measurement(name=StaticHelpers.name, timepoints=StaticHelpers.timepoints, values=values, errors=[-1]*len(StaticHelpers.values))
def test_init_datatypes_masking_non_numeric(self, input_vector, masked_vector): """ Non-numeric values implicitly define a mask, which is in turn applied to all vectors of the corresponding datatypes. """ _timeseries = TimeSeries(name=StaticHelpers.name, timepoints=input_vector, values=StaticHelpers.values) assert all(_timeseries.timepoints) == all(masked_vector) assert _timeseries.length == len(masked_vector) _timeseries = TimeSeries(name=StaticHelpers.name, timepoints=StaticHelpers.timepoints, values=input_vector) assert all(_timeseries.timepoints) == all(masked_vector) assert _timeseries.length == len(masked_vector) _measurement = Measurement(name=StaticHelpers.name, timepoints=StaticHelpers.timepoints, values=StaticHelpers.values, errors=input_vector) assert all(_measurement.timepoints) == all(masked_vector) assert _measurement.length == len(masked_vector)
def test_update_error_models_parameters(self, error_model, error_model_parameters): """ Updates error_models for existing Measurement objects """ # create measurement first measurement = Measurement(name=StaticHelpers.name, timepoints=StaticHelpers.timepoints, values=StaticHelpers.values) # To use a different (new) error_model, it must be passed with its corresponding error_model_parameters measurement.update_error_model(error_model=error_model, error_model_parameters=error_model_parameters) # Parameter values can be updated, as long as all parameters are present in the new dictionary measurement.error_model_parameters = {_p : error_model_parameters[_p]*1.5 for _p in error_model_parameters} # Incase the error model is applied, a warning can be given for overwriting the error vector with pytest.warns(UserWarning): measurement.apply_error_model(report_level=1) # Setting new parameter values won't work with pytest.raises(KeyError): measurement.error_model_parameters = {'bad_parameter' : 1000}
def test_extended_simulator_with_observations(self): # Get building blocks for BioprocessModel name = 'model01' modelclass = ModelLibrary.modelclasses[name] initial_values = ModelLibrary.initial_values[name] model_parameters = ModelLibrary.model_parameters[name] # Get building blocks for ObservationFunctions obsfun_name = 'obsfun01' obsfun = ObservationFunctionLibrary.observation_functions[obsfun_name] obsfun_parameters = ObservationFunctionLibrary.observation_function_parameters[ obsfun_name] observed_state = ObservationFunctionLibrary.observed_states[ obsfun_name] obsfuns_params = [(obsfun, { **obsfun_parameters, 'observed_state': observed_state })] # Set new values for parameters, using an extended simulator extended_simulator = ExtendedSimulator( bioprocess_model_class=modelclass, model_parameters=model_parameters, initial_values=initial_values, observation_functions_parameters=obsfuns_params, ) params = extended_simulator.get_all_parameters() extended_simulator.set_parameters( {_p: params[_p] * 1.05 for _p in params}) # Get some prediction to be used as artifical data predicitions = extended_simulator.simulate(t=24) measurements = [ Measurement(name=_prediction.name, timepoints=_prediction.timepoints, values=_prediction.values, errors=np.ones_like(_prediction.values)) for _prediction in predicitions ] extended_simulator._get_loss(metric='negLL', measurements=measurements)
def test_other_distributions(self): # Create a Measurement object having an error t-distribution measurement_t = Measurement( name=StaticHelpers.name, timepoints=StaticHelpers.timepoints, values=StaticHelpers.values, errors=StaticHelpers.values, error_distribution=scipy.stats.t, distribution_kwargs={'df' : 1}, replicate_id='1st' ) # Get rvs values for, e.g. MC sampling measurement_t._get_random_samples_values() loss_1 = measurement_t.get_loss(metric='negLL', predictions=[StaticDatatypes.modelstate]) assert not np.isnan(loss_1) loss_2 = measurement_t.get_loss(metric='negLL', predictions=[StaticDatatypes.modelstate], distribution_kwargs={'df' : 100}) assert not np.isnan(loss_2) # Does not work in case there are no errors with pytest.raises(AttributeError): StaticDatatypes.measurement_wo_errs._get_random_samples_values()