def __init__(self, model_name="vep_sde", model_config=ModelConfiguration(), parameters=[ XModes.X0MODE.value, "sigma_" + XModes.X0MODE.value, "tau1", "K", "x1_init", "z_init", "dX1t", "dZt", "sigma", "epsilon", "scale", "offset" ], xmode=XModes.X0MODE.value, priors_mode=PriorsModes.NONINFORMATIVE.value, sigma_x=None, sigma_x_scale=3, MC_direction_split=0.5, sigma_init=SIGMA_INIT_DEF, tau1=TAU1_DEF, tau0=TAU0_DEF, epsilon=EPSILON_DEF, sigma=SIGMA_DEF, scale=SCALE_SIGNAL_DEF, offset=OFFSET_SIGNAL_DEF, sde_mode=SDE_MODES.NONCENTERED.value, observation_model=OBSERVATION_MODELS.SEEG_LOGPOWER.value, number_of_signals=0, active_regions=[]): super(SDEProbabilisticModelBuilder, self).__init__(model_name, model_config, parameters, xmode, priors_mode, sigma_x, sigma_x_scale, MC_direction_split, sigma_init, tau1, tau0, epsilon, scale, offset, observation_model, number_of_signals, active_regions) self.sigma_init = sigma_init self.sde_mode = sde_mode self.sigma = sigma
def __init__(self, name='vep_ode', number_of_regions=0, target_data_type=TARGET_DATA_TYPE.EMPIRICAL.value, xmode=XModes.X0MODE.value, priors_mode=PriorsModes.NONINFORMATIVE.value, parameters={}, ground_truth={}, model_config=ModelConfiguration(), observation_model=OBSERVATION_MODELS.SEEG_LOGPOWER.value, sigma_x=SIGMA_X0_DEF, sigma_init=SIGMA_INIT_DEF, sigma=SIGMA_DEF, tau1=TAU1_DEF, tau0=TAU0_DEF, scale=SCALE_SIGNAL_DEF, offset=OFFSET_SIGNAL_DEF, epsilon=EPSILON_DEF, number_of_target_data=0, time_length=0, dt=DT_DEF, active_regions=[], sde_mode=SDE_MODES.NONCENTERED.value): super(SDEProbabilisticModel, self).__init__(name, number_of_regions, target_data_type, xmode, priors_mode, parameters, ground_truth, model_config, observation_model, sigma_x, sigma_init, tau1, tau0, scale, offset, epsilon, number_of_target_data, time_length, dt, active_regions) self.sigma = sigma self.sde_mode = sde_mode
def configure_model_from_equilibrium(self, x1EQ, zEQ, connectivity_matrix): # x1EQ, zEQ = self._ensure_equilibrum(x1EQ, zEQ) # We don't this by default anymore x0, Ceq, x0_values, e_values = self._compute_params_after_equilibration( x1EQ, zEQ, connectivity_matrix) model_configuration = ModelConfiguration( self.yc, self.Iext1, self.Iext2, self.K, self.a, self.b, self.d, self.slope, self.s, self.gamma, x1EQ, zEQ, Ceq, x0, x0_values, e_values, self.zmode, connectivity_matrix) return model_configuration
def _configure_model_from_equilibrium(self, x1eq, zeq, model_connectivity): # x1eq, zeq = self._ensure_equilibrum(x1eq, zeq) # We don't this by default anymore x0, Ceq, x0_values, e_values = self._compute_params_after_equilibration( x1eq, zeq, model_connectivity) return ModelConfiguration(self.yc, self.Iext1, self.Iext2, self.K, self.a, self.b, self.d, self.slope, self.s, self.gamma, self.tau1, self.tau0, x1eq, zeq, Ceq, x0, x0_values, e_values, self.zmode, model_connectivity)
def test_write_model_configuration(self): test_file = os.path.join(self.config.out.FOLDER_TEMP, "TestModelConfiguration.h5") dummy_mc = ModelConfiguration(x1eq=numpy.array([2.0, 3.0, 1.0]), zmode=None, zeq=numpy.array([3.0, 2.0, 1.0]), Ceq=numpy.array([1.0, 2.0, 3.0]), model_connectivity=self.dummy_connectivity.normalized_weights) assert not os.path.exists(test_file) self.writer.write_model_configuration(dummy_mc, test_file) assert os.path.exists(test_file)
def __init__(self, model_name="vep", model_config=ModelConfiguration(), parameters=[XModes.X0MODE.value], xmode=XModes.X0MODE.value, priors_mode=PriorsModes.NONINFORMATIVE.value): self.name = model_name self.model_config = model_config self.xmode = xmode self.parameters = parameters self.priors_mode = priors_mode
def test_read_model_configuration(self): test_file = os.path.join(self.config.out.FOLDER_TEMP, "TestModelConfiguration.h5") dummy_mc = ModelConfiguration(x1EQ=numpy.array([2.0, 3.0, 1.0]), zmode=None, zEQ=numpy.array([3.0, 2.0, 1.0]), model_connectivity=numpy.array( [[1.0, 2.0, 3.0], [1.0, 2.0, 3.0], [2.0, 2.0, 2.0]]), Ceq=numpy.array([1.0, 2.0, 3.0])) self.writer.write_model_configuration(dummy_mc, test_file) mc = self.reader.read_model_configuration(test_file) assert numpy.array_equal(dummy_mc.x1EQ, mc.x1EQ) assert numpy.array_equal(dummy_mc.zEQ, mc.zEQ) assert numpy.array_equal(dummy_mc.Ceq, mc.Ceq) assert numpy.array_equal(dummy_mc.model_connectivity, mc.model_connectivity)
def __init__(self, name='vep_ode', number_of_regions=0, target_data_type=TARGET_DATA_TYPE.EMPIRICAL.value, xmode=XModes.X0MODE.value, priors_mode=PriorsModes.NONINFORMATIVE.value, parameters={}, ground_truth={}, model_config=ModelConfiguration(), observation_model=OBSERVATION_MODELS.SEEG_LOGPOWER.value, sigma_x=SIGMA_X0_DEF, sigma_init=SIGMA_INIT_DEF, tau1=TAU1_DEF, tau0=TAU0_DEF, scale=SCALE_SIGNAL_DEF, offset=OFFSET_SIGNAL_DEF, epsilon=EPSILON_DEF, number_of_target_data=0, time_length=0, dt=DT_DEF, active_regions=[]): super(ODEProbabilisticModel, self).__init__(name, number_of_regions, target_data_type, xmode, priors_mode, parameters, ground_truth, model_config, sigma_x) if np.all(np.in1d(active_regions, range(self.number_of_regions))): self.active_regions = np.unique(active_regions).tolist() else: raise_value_error("Active regions indices:\n" + str(active_regions) + "\nbeyond number of regions (" + str(self.number_of_regions) + ")!") if observation_model in [_.value for _ in OBSERVATION_MODELS]: self.observation_model = observation_model else: raise_value_error("Statistical model's observation model " + str(observation_model) + " is not one of the valid ones: " + str([_.value for _ in OBSERVATION_MODELS]) + "!") self.sigma_init = sigma_init self.tau1 = tau1 self.tau0 = tau0 self.scale = scale self.offset = offset self.epsilon = epsilon self.number_of_target_data = number_of_target_data self.time_length = time_length self.dt = dt
def build_model_from_model_config_dict(self, model_config_dict): if not isinstance(model_config_dict, dict): model_config_dict = model_config_dict.__dict__ model_configuration = ModelConfiguration() for attr, value in model_configuration.__dict__.iteritems(): value = model_config_dict.get(attr, None) if value is None: warning( attr + " not found in the input model configuraiton dictionary!" + "\nLeaving default " + attr + ": " + str(getattr(model_configuration, attr))) if value is not None: setattr(model_configuration, attr, value) return model_configuration
def test_write_model_inversion_service(self): test_file = os.path.join(self.config.out.FOLDER_TEMP, "TestModelInversionService.h5") dummy_model_inversion_service = ModelInversionService( ModelConfiguration( model_connectivity=self.dummy_connectivity.normalized_weights, x1EQ=X1_EQ_CR_DEF), dynamical_model="Epileptor", sig_eq=(-4.0 / 3.0 - -5.0 / 3.0) / 10.0) assert not os.path.exists(test_file) self.writer.write_model_inversion_service( dummy_model_inversion_service, test_file) assert os.path.exists(test_file)
def __init__(self, name='vep', number_of_regions=0, target_data_type=TARGET_DATA_TYPE.EMPIRICAL.value, xmode=XModes.X0MODE.value, priors_mode=PriorsModes.NONINFORMATIVE.value, parameters={}, ground_truth={}, model_config=ModelConfiguration(), sigma_x=SIGMA_X0_DEF, MC_direction_split=0.5): self.name = name self.number_of_regions = number_of_regions self.xmode = xmode self.priors_mode = priors_mode self.sigma_x = sigma_x self.parameters = parameters self.model_config = model_config self.MC_direction_split = MC_direction_split self.ground_truth = ground_truth self.target_data_type = target_data_type
def __init__(self, model_name="vep", model_config=ModelConfiguration(), parameters=[ XModes.X0MODE.value, "sigma_" + XModes.X0MODE.value, "K" ], xmode=XModes.X0MODE.value, priors_mode=PriorsModes.NONINFORMATIVE.value, sigma_x=None, sigma_x_scale=3, MC_direction_split=0.5): super(ProbabilisticModelBuilder, self).__init__(model_name, model_config, parameters, xmode, priors_mode) if sigma_x is None: if self.xmode == XModes.X0MODE.value: self.sigma_x = SIGMA_X0_DEF else: self.sigma_x = SIGMA_EQ_DEF else: self.sigma_x = sigma_x self.sigma_x_scale = sigma_x_scale self.MC_direction_split = MC_direction_split
def __init__(self, model_name="vep_ode", model_config=ModelConfiguration(), parameters=[ XModes.X0MODE.value, "sigma_" + XModes.X0MODE.value, "tau1", "K", "x1_init", "z_init", "epsilon", "scale", "offset" ], xmode=XModes.X0MODE.value, priors_mode=PriorsModes.NONINFORMATIVE.value, sigma_x=None, sigma_x_scale=3, MC_direction_split=0.5, sigma_init=SIGMA_INIT_DEF, tau1=TAU1_DEF, tau0=TAU0_DEF, epsilon=EPSILON_DEF, scale=SCALE_SIGNAL_DEF, offset=OFFSET_SIGNAL_DEF, observation_model=OBSERVATION_MODELS.SEEG_LOGPOWER.value, number_of_signals=0, active_regions=[]): super(ODEProbabilisticModelBuilder, self).__init__(model_name, model_config, parameters, xmode, priors_mode, sigma_x, sigma_x_scale, MC_direction_split) self.sigma_init = sigma_init self.tau1 = tau1 self.tau0 = tau0 self.epsilon = epsilon self.scale = scale self.offset = offset self.observation_model = observation_model self.number_of_signals = number_of_signals self.time_length = self.compute_seizure_length() self.dt = self.compute_dt() self.active_regions = active_regions
def read_model_configuration(self, path): """ :param path: Path towards a ModelConfiguration H5 file :return: ModelConfiguration object """ self.logger.info("Starting to read ModelConfiguration from: %s" % path) h5_file = h5py.File(path, 'r', libver='latest') if h5_file.attrs["EPI_Subtype"] != "ModelConfiguration": self.logger.warning("This file does not seem to hold a ModelConfiguration") model_configuration = ModelConfiguration() for dataset in h5_file.keys(): model_configuration.set_attribute(dataset, h5_file["/" + dataset][()]) for attr in h5_file.attrs.keys(): model_configuration.set_attribute(attr, h5_file.attrs[attr]) h5_file.close() return model_configuration
class ProbabilisticModelBuilderBase(object): __metaclass__ = ABCMeta logger = initialize_logger(__name__) name = "vep" model_config = ModelConfiguration() parameters = [XModes.X0MODE.value] xmode = XModes.X0MODE.value priors_mode = PriorsModes.NONINFORMATIVE.value def __init__(self, model_name="vep", model_config=ModelConfiguration(), parameters=[XModes.X0MODE.value], xmode=XModes.X0MODE.value, priors_mode=PriorsModes.NONINFORMATIVE.value): self.name = model_name self.model_config = model_config self.xmode = xmode self.parameters = parameters self.priors_mode = priors_mode def __repr__(self, d=OrderedDict()): return formal_repr(self, self._repr(d)) def __str__(self): return self.__repr__() @property def number_of_regions(self): return self.model_config.number_of_regions @property def number_of_parameters(self): return len(self.parameters) def _repr(self, d=OrderedDict()): for ikey, (key, val) in enumerate(self.__dict__.iteritems()): d.update({str(ikey) + ". " + key: val}) return d def set_attributes(self, attributes_names, attribute_values): for attribute_name, attribute_value in zip( ensure_list(attributes_names), ensure_list(attribute_values)): setattr(self, attribute_name, attribute_value) return self def _set_attributes_from_dict(self, attributes_dict): if not isinstance(attributes_dict, dict): attributes_dict = attributes_dict.__dict__ for attr, value in attributes_dict.iteritems(): if not attr in [ "model_config", "parameters", "number_of_regions", "number_of_parameters" ]: value = attributes_dict.get(attr, None) if value is None: warning(attr + " not found in input dictionary!" + "\nLeaving as it is: " + attr + " = " + str(getattr(self, attr))) if value is not None: setattr(self, attr, value) return attributes_dict @abstractmethod def generate_parameters(self): pass @abstractmethod def generate_model(self): pass
class ProbabilisticModelBuilder(ProbabilisticModelBuilderBase): parameters = [XModes.X0MODE.value, "sigma_" + XModes.X0MODE.value, "K"] sigma_x = SIGMA_X0_DEF sigma_x_scale = 3 MC_direction_split = 0.5 model_config = ModelConfiguration() def __init__(self, model_name="vep", model_config=ModelConfiguration(), parameters=[ XModes.X0MODE.value, "sigma_" + XModes.X0MODE.value, "K" ], xmode=XModes.X0MODE.value, priors_mode=PriorsModes.NONINFORMATIVE.value, sigma_x=None, sigma_x_scale=3, MC_direction_split=0.5): super(ProbabilisticModelBuilder, self).__init__(model_name, model_config, parameters, xmode, priors_mode) if sigma_x is None: if self.xmode == XModes.X0MODE.value: self.sigma_x = SIGMA_X0_DEF else: self.sigma_x = SIGMA_EQ_DEF else: self.sigma_x = sigma_x self.sigma_x_scale = sigma_x_scale self.MC_direction_split = MC_direction_split def _repr(self, d=OrderedDict()): d.update(super(ProbabilisticModelBuilder, self)._repr(d)) nKeys = len(d) for ikey, (key, val) in enumerate(self.__dict__.iteritems()): d.update({str(nKeys + ikey) + ". " + key: str(val)}) return d def get_SC(self, model_connectivity): # Set symmetric connectivity to be in the interval [MC_MAX / MAX_MIN_RATIO, MC_MAX], # where self.MC_MAX corresponds to the 95th percentile of model_connectivity p95 = np.percentile(model_connectivity.flatten(), 95) SC = np.array(model_connectivity) if p95 != MC_MAX: SC = SC / p95 SC[SC > MC_MAX] = 1.0 mc_def_min = MC_MAX / MC_MAX_MIN_RATIO SC[SC < mc_def_min] = mc_def_min diag_ind = range(self.number_of_regions) SC[diag_ind, diag_ind] = 0.0 return SC def get_MC_prior(self, model_connectivity): MC_def = self.get_SC(model_connectivity) inds = np.triu_indices(self.number_of_regions, 1) MC_def[inds] = MC_def[inds] * self.MC_direction_split MC_def = MC_def.T MC_def[inds] = MC_def[inds] * (1.0 - self.MC_direction_split) MC_def = MC_def.T MC_def[MC_def < 0.001] = 0.001 return MC_def def generate_parameters(self): parameters = OrderedDict() self.logger.info("Generating model parameters by " + self.__class__.__name__ + "...") # Generative model: # Epileptor stability: self.logger.info("..." + self.xmode + "...") if self.priors_mode == PriorsModes.INFORMATIVE.value: xprior = getattr(self.model_config, self.xmode) sigma_x = None else: xprior = x_def[self.xmode]["def"] * np.ones( (self.number_of_regions, )) sigma_x = self.sigma_x x_param_name = self.xmode parameters.update({ self.xmode: generate_negative_lognormal_parameter( x_param_name, xprior, x_def[self.xmode]["min"], x_def[self.xmode]["max"], sigma=sigma_x, sigma_scale=self.sigma_x_scale, p_shape=(self.number_of_regions, ), use="scipy") }) # Update sigma_x value and name self.sigma_x = parameters[self.xmode].std sigma_x_name = "sigma_" + self.xmode if sigma_x in self.parameters: self.logger.info("..." + sigma_x + "...") parameters.update({ sigma_x: generate_lognormal_parameter(sigma_x_name, self.sigma_x, 0.0, 10 * self.sigma_x, sigma_scale=self.sigma_x, p_shape=(), use="scipy") }) # Coupling if "MC" in self.parameters: self.logger.info("...MC...") parameters.update({ "MC": generate_lognormal_parameter( "MC", self.get_MC_prior(self.model_config.model_connectivity), MC_MIN, MC_MAX, sigma=None, sigma_scale=MC_SCALE, p_shape=(), use="scipy") }) if "K" in self.parameters: self.logger.info("...K...") parameters.update({ "K": generate_lognormal_parameter("K", self.model_config.K, K_MIN, K_MAX, sigma=None, sigma_scale=K_SCALE, p_shape=(), use="scipy") }) return parameters def generate_model(self, target_data_type=TARGET_DATA_TYPE.SYNTHETIC.value, ground_truth={}): tic = time.time() self.logger.info("Generating model by " + self.__class__.__name__ + "...") parameters = self.generate_parameters() model = ProbabilisticModel(self.name, self.number_of_regions, target_data_type, self.xmode, self.priors_mode, parameters, ground_truth, self.model_config, self.sigma_x, self.MC_direction_split) self.logger.info(self.__class__.__name__ + " took " + str(time.time() - tic) + ' sec for model generation') return model
class ProbabilisticModel(object): name = "vep" target_data_type = TARGET_DATA_TYPE.EMPIRICAL.value parameters = {} model_config = ModelConfiguration() xmode = XModes.X0MODE.value priors_mode = PriorsModes.NONINFORMATIVE.value sigma_x = SIGMA_X0_DEF MC_direction_split = 0.5 ground_truth = {} @property def number_of_parameters(self): return len(self.parameters) def __init__(self, name='vep', number_of_regions=0, target_data_type=TARGET_DATA_TYPE.EMPIRICAL.value, xmode=XModes.X0MODE.value, priors_mode=PriorsModes.NONINFORMATIVE.value, parameters={}, ground_truth={}, model_config=ModelConfiguration(), sigma_x=SIGMA_X0_DEF, MC_direction_split=0.5): self.name = name self.number_of_regions = number_of_regions self.xmode = xmode self.priors_mode = priors_mode self.sigma_x = sigma_x self.parameters = parameters self.model_config = model_config self.MC_direction_split = MC_direction_split self.ground_truth = ground_truth self.target_data_type = target_data_type def _repr(self, d=OrderedDict()): for ikey, (key, val) in enumerate(self.__dict__.iteritems()): d.update({key: val}) return d def __repr__(self, d=OrderedDict()): return formal_repr(self, self._repr(d)) def __str__(self): return self.__repr__() @property def number_of_total_parameters(self): nparams = 0 for p in self.parameters.values(): nparams += np.maximum(1, np.prod(p.p_shape)) return nparams def get_parameter(self, parameter_name): parameter = self.parameters.get(parameter_name, None) if parameter is None: warning("Ground truth value for parameter " + parameter_name + " was not found!") return parameter def get_truth(self, parameter_name): if self.target_data_type == TARGET_DATA_TYPE.SYNTHETIC.value: truth = self.ground_truth.get(parameter_name, np.nan) if truth is np.nan: truth = getattr(self.model_config, parameter_name, np.nan) # TODO: find a more general solution here... if truth is np.nan and parameter_name == "MC" or parameter_name == "FC": truth = self.model_config.model_connectivity if truth is np.nan: # TODO: decide if it is a good idea to return this kind of modeler's "truth"... truth = getattr(self, parameter_name, np.nan) if truth is np.nan: warning("Ground truth value for parameter " + parameter_name + " was not found!") return truth return np.nan # Prior is either a parameter or the ground truth def get_prior(self, parameter_name): parameter = self.get_parameter(parameter_name) if parameter is None: # TODO: decide if it is a good idea to return this kind of modeler's fixed "prior"... return getattr(self, parameter_name, np.nan), None else: return parameter.mean, parameter def get_prior_pdf(self, parameter_name): mean_or_truth, parameter = self.get_prior(parameter_name) if isinstance(parameter, (ProbabilisticParameterBase, TransformedProbabilisticParameterBase)): return parameter.scipy_method("pdf") else: warning("No parameter " + parameter_name + " was found!\nReturning true value instead of pdf!") return mean_or_truth