class StimuliSurfaceH5(H5File): def __init__(self, path): super(StimuliSurfaceH5, self).__init__(path) self.spatial = Scalar(Attr(str), self, name='spatial') self.temporal = Scalar(Attr(str), self, name='temporal') self.surface = Reference(StimuliSurface.surface, self) self.focal_points_surface = DataSet( StimuliSurface.focal_points_surface, self) self.focal_points_triangles = DataSet( StimuliSurface.focal_points_triangles, self) def store(self, datatype, scalars_only=False): self.surface.store(datatype.surface) self.focal_points_surface.store(datatype.focal_points_surface) self.focal_points_triangles.store(datatype.focal_points_triangles) self.spatial.store(datatype.spatial.to_json(datatype.spatial)) self.temporal.store(datatype.temporal.to_json(datatype.temporal)) def load_into(self, datatype): datatype.gid = self.gid.load() datatype.surface = self.surface.load() datatype.focal_points_triangles = self.focal_points_triangles.load() datatype.focal_points_surface = self.focal_points_surface.load() spatial_eq = self.spatial.load() spatial_eq = datatype.spatial.from_json(spatial_eq) datatype.spatial = spatial_eq temporal_eq = self.temporal.load() temporal_eq = datatype.temporal.from_json(temporal_eq) datatype.temporal = temporal_eq
class TimeSeriesSEEGH5(TimeSeriesSensorsH5): def __init__(self, path): super(TimeSeriesSEEGH5, self).__init__(path) self.sensors = Reference(TimeSeriesSEEG.sensors, self) self.labels_order = Json(TimeSeriesSEEG.labels_ordering, self) def store_references(self, ts): self.sensors.store(ts.sensors.gid)
class TimeSeriesVolumeH5(TimeSeriesH5): def __init__(self, path): super(TimeSeriesVolumeH5, self).__init__(path) self.volume = Reference(TimeSeriesVolume.volume, self) self.labels_ordering = Json(TimeSeriesVolume.labels_ordering, self) def store_references(self, ts): self.volume.store(ts.volume.gid) def get_volume_view(self, from_idx, to_idx, x_plane, y_plane, z_plane, **kwargs): """ Retrieve 3 slices through the Volume TS, at the given X, y and Z coordinates, and in time [from_idx .. to_idx]. :param from_idx: int This will be the limit on the first dimension (time) :param to_idx: int Also limit on the first Dimension (time) :param x_plane: int coordinate :param y_plane: int coordinate :param z_plane: int coordinate :return: An array of 3 Matrices 2D, each containing the values to display in planes xy, yz and xy. """ overall_shape = self.data.shape from_idx, to_idx, time = preprocess_time_parameters(from_idx, to_idx, overall_shape[0]) x_plane, y_plane, z_plane = preprocess_space_parameters(x_plane, y_plane, z_plane, overall_shape[1], overall_shape[2], overall_shape[3]) slices = slice(from_idx, to_idx), slice(overall_shape[1]), slice(overall_shape[2]), slice(z_plane, z_plane + 1) slicex = self.read_data_slice(slices)[:, :, :, 0].tolist() slices = slice(from_idx, to_idx), slice(x_plane, x_plane + 1), slice(overall_shape[2]), slice(overall_shape[3]) slicey = self.read_data_slice(slices)[:, 0, :, :][..., ::-1].tolist() slices = slice(from_idx, to_idx), slice(overall_shape[1]), slice(y_plane, y_plane + 1), slice(overall_shape[3]) slicez = self.read_data_slice(slices)[:, :, 0, :][..., ::-1].tolist() return [slicex, slicey, slicez] def get_voxel_time_series(self, x, y, z, **kwargs): """ Retrieve for a given voxel (x,y,z) the entire timeline. :param x: int coordinate :param y: int coordinate :param z: int coordinate :return: A complex dictionary with information about current voxel. The main part will be a vector with all the values over time from the x,y,z coordinates. """ overall_shape = self.data.shape x, y, z = preprocess_space_parameters(x, y, z, overall_shape[1], overall_shape[2], overall_shape[3]) slices = prepare_time_slice(overall_shape[0]), slice(x, x + 1), slice(y, y + 1), slice(z, z + 1) result = postprocess_voxel_ts(self, slices) return result
class ProjectionH5(MonitorH5): def __init__(self, path): super(ProjectionH5, self).__init__(path) self.region_mapping = Reference(Projection.region_mapping, self) self.obnoise = Reference(Projection.obsnoise, self) def store(self, datatype, scalars_only=False, store_references=False): # type: (Projection, bool, bool) -> None super(ProjectionH5, self).store(datatype, scalars_only, store_references) self.region_mapping.store(datatype.region_mapping.gid)
class StimuliRegionH5(H5File): def __init__(self, path): super(StimuliRegionH5, self).__init__(path) self.spatial = EquationScalar(StimuliRegion.spatial, self) self.temporal = EquationScalar(StimuliRegion.temporal, self) self.connectivity = Reference(StimuliRegion.connectivity, self) self.weight = DataSet(StimuliRegion.weight, self) def store(self, datatype, scalars_only=False): super(StimuliRegionH5, self).store(datatype, scalars_only) self.connectivity.store(datatype.connectivity)
class MEGH5(ProjectionH5): def __init__(self, path): super(MEGH5, self).__init__(path) self.projection = Reference(MEG.projection, self) self.sensors = Reference(MEG.sensors, self) def store(self, datatype, scalars_only=False, store_references=False): # type: (Projection, bool, bool) -> None super(MEGH5, self).store(datatype, scalars_only, store_references) self.projection.store(datatype.projection.gid) self.sensors.store(datatype.sensors.gid)
class TimeSeriesSurfaceH5(TimeSeriesH5): SELECTION_LIMIT = 100 def __init__(self, path): super(TimeSeriesSurfaceH5, self).__init__(path) self.surface = Reference(TimeSeriesSurface.surface, self) self.labels_ordering = Json(TimeSeriesSurface.labels_ordering, self) def store_references(self, ts): self.surface.store(ts.surface) def get_space_labels(self): """ Return only the first `SELECTION_LIMIT` vertices/channels """ return ['signal-%d' % i for i in range(min(self.data.shape[2], self.SELECTION_LIMIT))]
class IntegratorStochasticH5(IntegratorH5): def __init__(self, path): super(IntegratorStochasticH5, self).__init__(path) self.noise = Reference(IntegratorStochastic.noise, self) def store(self, datatype, scalars_only=False, store_references=False): # type: (IntegratorStochastic) -> None super(IntegratorStochasticH5, self).store(datatype, scalars_only, store_references) noise_gid = self.store_config_as_reference(datatype.noise) self.noise.store(noise_gid) def load_into(self, datatype): # type: (IntegratorStochastic) -> None super(IntegratorStochasticH5, self).load_into(datatype) datatype.noise = self.load_from_reference(self.noise.load())
class BurstConfigurationH5(H5File): def __init__(self, path): super(BurstConfigurationH5, self).__init__(path) self.name = Scalar(Attr(str), self, name='name') self.status = Scalar(Attr(str), self, name='status') self.error_message = Scalar(Attr(str, required=False), self, name='error_message') self.start_time = Scalar(Attr(str), self, name='start_time') self.finish_time = Scalar(Attr(str, required=False), self, name='finish_time') self.simulator = Reference(Attr(uuid.UUID), self, name='simulator') self.range1 = Scalar(Attr(str, required=False), self, name='range1') self.range2 = Scalar(Attr(str, required=False), self, name='range2') def store(self, burst_config, scalars_only=False, store_references=True): # type (BurstConfiguration, bool, bool) -> None self.gid.store(uuid.UUID(burst_config.gid)) self.name.store(burst_config.name) self.status.store(burst_config.status) self.error_message.store(burst_config.error_message or 'None') self.start_time.store(date2string(burst_config.start_time)) self.finish_time.store(date2string(burst_config.finish_time)) self.simulator.store(uuid.UUID(burst_config.simulator_gid)) self.range1.store(burst_config.range1) self.range2.store(burst_config.range2) def load_into(self, burst_config): # type (BurstConfiguration) -> None burst_config.gid = self.gid.load().hex burst_config.name = self.name.load() burst_config.status = self.status.load() burst_config.error_message = self.error_message.load() burst_config.start_time = string2date(self.start_time.load()) finish_time = self.finish_time.load() if finish_time and finish_time != 'None': burst_config.finish_time = string2date(finish_time) burst_config.simulator_gid = self.simulator.load().hex try: burst_config.range1 = self.range1.load() except MissingDataSetException: burst_config.range1 = None try: burst_config.range2 = self.range2.load() except MissingDataSetException: burst_config.range2 = None
class MultiplicativeH5(NoiseH5): def __init__(self, path): super(MultiplicativeH5, self).__init__(path) self.nsig = DataSet(Multiplicative.nsig, self) self.b = Reference(Multiplicative.b, self) def store(self, datatype, scalars_only=False, store_references=False): # type: (Multiplicative) -> None super(MultiplicativeH5, self).store(datatype, scalars_only, store_references) equation_gid = self.store_config_as_reference(datatype.b) self.b.store(equation_gid) def load_into(self, datatype): # type: (Multiplicative) -> None super(MultiplicativeH5, self).load_into(datatype) datatype.b = self.load_from_reference(self.b.load())
class SimulatorH5(SimulatorConfigurationH5): def __init__(self, path): super(SimulatorH5, self).__init__(path) self.connectivity = Reference(Simulator.connectivity, self) self.conduction_speed = Scalar(Simulator.conduction_speed, self) self.coupling = Reference(Simulator.coupling, self) self.surface = Reference(Simulator.surface, self) self.stimulus = Reference(Simulator.stimulus, self) self.model = Reference(Simulator.model, self) self.integrator = Reference(Simulator.integrator, self) self.initial_conditions = DataSet(Simulator.initial_conditions, self) self.monitors = Json(Simulator.monitors, self) self.simulation_length = Scalar(Simulator.simulation_length, self) self.simulation_state = Reference(Attr(field_type=uuid.UUID), self, name='simulation_state') def store(self, datatype, scalars_only=False, store_references=False): # type: (Simulator) -> None # TODO: handle store conn here # self.connectivity.store(conn_gid) self.conduction_speed.store(datatype.conduction_speed) self.initial_conditions.store(datatype.initial_conditions) self.simulation_length.store(datatype.simulation_length) integrator_gid = self.store_config_as_reference(datatype.integrator) self.integrator.store(integrator_gid) coupling_gid = self.store_config_as_reference(datatype.coupling) self.coupling.store(coupling_gid) model_gid = self.store_config_as_reference(datatype.model) self.model.store(model_gid) # TODO: handle multiple monitors monitor_gid = self.store_config_as_reference(datatype.monitors[0]) self.monitors.store([monitor_gid.hex]) if datatype.surface: cortex_gid = self.store_config_as_reference(datatype.surface) self.surface.store(cortex_gid) self.type.store(self.get_full_class_name(type(datatype))) def load_into(self, datatype): # type: (Simulator) -> None datatype.conduction_speed = self.conduction_speed.load() datatype.initial_conditions = self.initial_conditions.load() datatype.simulation_length = self.simulation_length.load() datatype.integrator = self.load_from_reference(self.integrator.load()) datatype.coupling = self.load_from_reference(self.coupling.load()) datatype.model = self.load_from_reference(self.model.load()) # TODO: handle multiple monitors datatype.monitors = [self.load_from_reference(self.monitors.load()[0])] if self.surface.load(): datatype.surface = self.load_from_reference(self.surface.load())
class TimeSeriesRegionH5(TimeSeriesH5): def __init__(self, path): super(TimeSeriesRegionH5, self).__init__(path) self.connectivity = Reference(TimeSeriesRegion.connectivity, self) self.region_mapping_volume = Reference( TimeSeriesRegion.region_mapping_volume, self) self.region_mapping = Reference(TimeSeriesRegion.region_mapping, self) self.labels_ordering = Json(TimeSeriesRegion.labels_ordering, self) @staticmethod def out_of_range(min_value): return round(min_value) - 1 def get_measure_points_selection_gid(self): """ :return: the associated connectivity gid """ connectivity_gid = self.connectivity.load() if connectivity_gid is None: return '' return connectivity_gid.hex def store_references(self, ts): self.connectivity.store(ts.connectivity.gid) if ts.region_mapping_volume is not None: self.region_mapping_volume.store(ts.region_mapping_volume.gid) if ts.region_mapping is not None: self.region_mapping.store(ts.region_mapping.gid)
class LocalConnectivityH5(H5File): def __init__(self, path): super(LocalConnectivityH5, self).__init__(path) self.surface = Reference(LocalConnectivity.surface, self) # this multidataset accessor works but something is off about it # this would be clearer # self.matrix, self.matrixindices, self.matrixindptr self.matrix = SparseMatrix(LocalConnectivity.matrix, self) # equation is an inlined reference # should this be a special equation scalar field? # or this? # this is clear about the structure, but obviously breaks the default store/load # self.equation_equation = Scalar(Equation.equation, self) # self.equation_parameters = Scalar(Equation.parameters, self) self.equation = Scalar(Attr(str), self, name='equation') self.cutoff = Scalar(LocalConnectivity.cutoff, self) # equations are such a special case that we will have to implement custom load store def store(self, datatype, scalars_only=False): self.surface.store(datatype.surface) self.matrix.store(datatype.matrix) self.cutoff.store(datatype.cutoff) self.equation.store(datatype.equation.to_json(datatype.equation)) def load_into(self, datatype): datatype.gid = self.gid.load() datatype.matrix = self.matrix.load() datatype.cutoff = self.cutoff.load() eq = self.equation.load() eq = datatype.equation.from_json(eq) datatype.equation = eq def get_min_max_values(self): metadata = self.matrix.get_metadata() return metadata.min, metadata.max
class StimuliRegionH5(H5File): def __init__(self, path): super(StimuliRegionH5, self).__init__(path) self.spatial = Scalar(Attr(str), self, name='spatial') self.temporal = Scalar(Attr(str), self, name='temporal') self.connectivity = Reference(StimuliRegion.connectivity, self) self.weight = DataSet(StimuliRegion.weight, self) def store(self, datatype, scalars_only=False): self.connectivity.store(datatype.connectivity) self.weight.store(datatype.weight) self.spatial.store(datatype.spatial.to_json(datatype.spatial)) self.temporal.store(datatype.temporal.to_json(datatype.temporal)) def load_into(self, datatype): datatype.gid = self.gid.load() datatype.connectivity = self.connectivity.load() datatype.weight = self.weight.load() spatial_eq = self.spatial.load() spatial_eq = datatype.spatial.from_json(spatial_eq) datatype.spatial = spatial_eq temporal_eq = self.temporal.load() temporal_eq = datatype.temporal.from_json(temporal_eq) datatype.temporal = temporal_eq
class SimulatorH5(SimulatorConfigurationH5): def __init__(self, path): super(SimulatorH5, self).__init__(path) self.connectivity = Reference(Simulator.connectivity, self) self.conduction_speed = Scalar(Simulator.conduction_speed, self) self.coupling = Reference(Simulator.coupling, self) self.surface = Reference(Simulator.surface, self) self.stimulus = Reference(Simulator.stimulus, self) self.model = Reference(Simulator.model, self) self.integrator = Reference(Simulator.integrator, self) self.initial_conditions = DataSet(Simulator.initial_conditions, self) self.monitors = Json(Simulator.monitors, self) self.simulation_length = Scalar(Simulator.simulation_length, self) self.simulation_state = Reference(Attr(field_type=uuid.UUID), self, name='simulation_state') def store(self, datatype, scalars_only=False, store_references=False): # type: (Simulator, bool, bool) -> None self.gid.store(datatype.gid) self.connectivity.store(datatype.connectivity) self.conduction_speed.store(datatype.conduction_speed) self.initial_conditions.store(datatype.initial_conditions) self.simulation_length.store(datatype.simulation_length) integrator_gid = self.store_config_as_reference(datatype.integrator) self.integrator.store(integrator_gid) coupling_gid = self.store_config_as_reference(datatype.coupling) self.coupling.store(coupling_gid) model_gid = self.store_config_as_reference(datatype.model) self.model.store(model_gid) monitor_gids = [] for monitor in datatype.monitors: monitor_gid = self.store_config_as_reference(monitor).hex monitor_gids.append(monitor_gid) self.monitors.store(monitor_gids) if datatype.surface: cortex_gid = self.store_config_as_reference(datatype.surface) self.surface.store(cortex_gid) if datatype.stimulus: self.stimulus.store(datatype.stimulus) self.type.store(self.get_full_class_name(type(datatype))) def load_into(self, datatype): # type: (Simulator) -> None datatype.conduction_speed = self.conduction_speed.load() datatype.initial_conditions = self.initial_conditions.load() datatype.simulation_length = self.simulation_length.load() datatype.integrator = self.load_from_reference(self.integrator.load()) datatype.coupling = self.load_from_reference(self.coupling.load()) datatype.model = self.load_from_reference(self.model.load()) monitors = [] for monitor in self.monitors.load(): monitors.append(self.load_from_reference(monitor)) datatype.monitors = monitors if self.surface.load(): datatype.surface = self.load_from_reference(self.surface.load())