def launch(self, view_model): # type: (FooDataImporterModel) -> TimeSeriesIndex array_data = numpy.loadtxt(view_model.array_data) ts = TimeSeries(data=array_data) ts.configure() ts_index = TimeSeriesIndex() ts_index.fill_from_has_traits(ts) ts_h5_path = h5.path_for(self.storage_path, TimeSeriesH5, ts_index.gid) with TimeSeriesH5(ts_h5_path) as ts_h5: ts_h5.store(ts, scalars_only=True) ts_h5.store_generic_attributes(GenericAttributes()) ts_h5.write_data_slice(array_data) return ts_index
class Timeseries(object): logger = initialize_logger(__name__) ts_type = "" _tvb = None # labels_dimensions = {"space": numpy.array([]), "variables": numpy.array([])} def __init__(self, input=numpy.array([[], []]), **kwargs): if isinstance(input, (Timeseries, TimeSeries)): if isinstance(input, Timeseries): self._tvb = deepcopy(input._tvb) self.ts_type = str(input.ts_type) elif isinstance(input, TimeSeries): self._tvb = deepcopy(input) if isinstance(input, TimeSeriesRegion): self.ts_type = "Region" if isinstance(input, TimeSeriesSEEG): self.ts_type = "SEEG" elif isinstance(input, TimeSeriesEEG): self.ts_type = "EEG" elif isinstance(input, TimeSeriesMEG): self.ts_type = "MEG" elif isinstance(input, TimeSeriesEEG): self.ts_type = "EEG" elif isinstance(input, TimeSeriesVolume): self.ts_type = "Volume" elif isinstance(input, TimeSeriesSurface): self.ts_type = "Surface" else: self.ts_type = "" warning( "Input TimeSeries %s is not one of the known TVB TimeSeries classes!" % str(input)) for attr, value in kwargs.items(): try: setattr(self, attr, value) except: setattr(self._tvb, attr, value) elif isinstance(input, numpy.ndarray): input = prepare_4D(input, self.logger) time = kwargs.pop("time", None) if time is not None: start_time = float( kwargs.pop("start_time", kwargs.pop("start_time", time[0]))) sample_period = float( kwargs.pop( "sample_period", kwargs.pop("sample_period", numpy.mean(numpy.diff(time))))) kwargs.update({ "start_time": start_time, "sample_period": sample_period }) # Initialize self.ts_type = kwargs.pop("ts_type", "Region") labels_ordering = kwargs.get("labels_ordering", None) # Get input sensors if any input_sensors = None if isinstance(kwargs.get("sensors", None), (TVBSensors, Sensors)): if isinstance(kwargs["sensors"], Sensors): input_sensors = kwargs["sensors"]._tvb self.ts_type = "%s sensor" % input_sensors.sensors_type kwargs.update({"sensors": input_sensors}) else: input_sensors = kwargs["sensors"] # Create Timeseries if isinstance(input_sensors, TVBSensors) or \ self.ts_type in ["SEEG sensor", "Internal sensor", "EEG sensor", "MEG sensor"]: # ...for Sensor Timeseries if labels_ordering is None: labels_ordering = LABELS_ORDERING labels_ordering[2] = "%s sensor" % self.ts_type kwargs.update({"labels_ordering": labels_ordering}) if isinstance(input_sensors, TVBSensorsInternal) or isequal_string(self.ts_type, "Internal sensor")\ or isequal_string(self.ts_type, "SEEG sensor"): self._tvb = TimeSeriesSEEG(data=input, **kwargs) self.ts_type = "SEEG sensor" elif isinstance(input_sensors, TVBSensorsEEG) or isequal_string( self.ts_type, "EEG sensor"): self._tvb = TimeSeriesEEG(data=input, **kwargs) self.ts_type = "EEG sensor" elif isinstance(input_sensors, TVBSensorsMEG) or isequal_string( self.ts_type, "MEG sensor"): self._tvb = TimeSeriesMEG(data=input, **kwargs) self.ts_type = "MEG sensor" else: raise_value_error( "Not recognizing sensors of type %s:\n%s" % (self.ts_type, str(input_sensors))) else: input_surface = kwargs.pop("surface", None) if isinstance( input_surface, (Surface, TVBSurface)) or self.ts_type == "Surface": self.ts_type = "Surface" if isinstance(input_surface, Surface): kwargs.update({"surface": input_surface._tvb}) else: kwargs.update({"surface": input_surface}) if labels_ordering is None: labels_ordering = LABELS_ORDERING labels_ordering[2] = "Vertex" kwargs.update({"labels_ordering": labels_ordering}) self._tvb = TimeSeriesSurface(data=input, **kwargs) elif isequal_string(self.ts_type, "Region"): if labels_ordering is None: labels_ordering = LABELS_ORDERING labels_ordering[2] = "Region" kwargs.update({"labels_ordering": labels_ordering}) self._tvb = TimeSeriesRegion(data=input, **kwargs) # , **kwargs elif isequal_string(self.ts_type, "Volume"): if labels_ordering is None: labels_ordering = ["Time", "X", "Y", "Z"] kwargs.update({"labels_ordering": labels_ordering}) self._tvb = TimeSeriesVolume(data=input, **kwargs) else: self._tvb = TimeSeries(data=input, **kwargs) if not numpy.all([ dim_label in self._tvb.labels_dimensions.keys() for dim_label in self._tvb.labels_ordering ]): warning( "Lack of correspondance between timeseries labels_ordering %s\n" "and labels_dimensions!: %s" % (self._tvb.labels_ordering, self._tvb.labels_dimensions.keys())) self._tvb.configure() self.configure_time() self.configure_sample_rate() if len(self.title) == 0: self._tvb.title = "%s Time Series" % self.ts_type def duplicate(self, **kwargs): return self.__class__(self, **kwargs) def _get_indices_from_labels(self, labels, dim): dim_label = self.labels_ordering[dim] return labels_to_indices(self.labels_dimensions[dim_label], labels, dim_label, self.logger) def _get_indices_of_variables(self, sv_labels): return self._get_indices_from_labels(sv_labels, 0) def _get_indices_of_labels(self, list_of_labels): return self._get_indices_from_labels(list_of_labels, 2) def _get_indices_of_samples(self, list_of_labels): return self._get_indices_from_labels(list_of_labels, 3) def _get_time_for_index(self, time_index): return self._tvb.start_time + time_index * self._tvb.sample_period def _get_index_for_time(self, time_unit): return int( (time_unit - self._tvb.start_time) / self._tvb.sample_period) def _check_indices(self, list_of_index, dim): for index in list_of_index: if index < 0 or index > self._tvb.data.shape[dim]: self.logger.error( "Some of the given indices are out of region range: [0, %s]", self._tvb.data.shape[dim]) raise IndexError def get_subset_by_index(self, list_of_indices, dim, **kwargs): assert dim in [0, 1, 2, 3] list_of_indices = ensure_list(list_of_indices) self._check_indices(list_of_indices, dim) slice_tuple = [slice(None), slice(None), slice(None), slice(None)] slice_tuple[dim] = list_of_indices data = self._tvb.data[tuple(slice_tuple)] dim_label = self.labels_ordering[dim] if len(self.labels_dimensions[dim_label]): labels_dimensions = deepcopy(self.labels_dimensions) labels_dimensions[dim_label] = numpy.array( labels_dimensions[dim_label])[list_of_indices] else: labels_dimensions = self.labels_dimensions if data.ndim == 3: data = numpy.expand_dims(data, 1) return self.duplicate(data=data, labels_dimensions=labels_dimensions, **kwargs) def get_subset_by_label(self, list_of_labels, dim, **kwargs): assert dim in [0, 1, 2, 3] list_of_labels = ensure_list(list_of_labels) dim_label = self.labels_ordering[dim] list_of_indices = labels_to_indices(self.labels_dimensions[dim_label], list_of_labels, dim_label, self.logger) return self.get_subset_by_index(list_of_indices, dim, **kwargs) def get_subset(self, list_of_indices_or_labels, dim, **kwargs): assert dim in [0, 1, 2, 3] list_of_indices_or_labels = ensure_list(list_of_indices_or_labels) if numpy.all([ is_integer(ind_or_lbl) for ind_or_lbl in list_of_indices_or_labels ]): return self.get_subset_by_index(list_of_indices_or_labels, dim, **kwargs) else: if dim == 0: if not numpy.all([ is_numeric(ind_or_lbl) for ind_or_lbl in list_of_indices_or_labels ]): raise_value_error( "Input consists neither of integer indices nor of points in time (floats)!: %s" % list_of_indices_or_labels) time_indices = [ self._get_index_for_time(time) for time in list_of_indices_or_labels ] return self.get_subset_by_index(time_indices, 0, **kwargs) else: if not numpy.all([ isinstance(ind_or_lbl, string_types) for ind_or_lbl in list_of_indices_or_labels ]): raise_value_error( "Input consists neither of integer indices nor of label strings!: %s" % list_of_indices_or_labels) return self.get_subset_by_label(list_of_indices_or_labels, dim, **kwargs) def get_times_by_index(self, list_of_times_indices, **kwargs): return self.get_subset_by_index(list_of_times_indices, 0, **kwargs) def get_times(self, list_of_times, **kwargs): return self.get_subset(list_of_times, 0, **kwargs) def get_variables_by_index(self, list_of_indices, **kwargs): return self.get_subset_by_index(list_of_indices, 1, **kwargs) def get_variables_by_label(self, list_of_labels, **kwargs): return self.get_subset_by_label(list_of_labels, 1, **kwargs) def get_variables(self, list_of_labels_or_inds, **kwargs): return self.get_subset(list_of_labels_or_inds, 1, **kwargs) def get_subspace_by_index(self, list_of_indices, **kwargs): return self.get_subset_by_index(list_of_indices, 2, **kwargs) def get_subspace_by_labels(self, list_of_labels): return self.get_subset_by_label(list_of_labels, 2, **kwargs) def get_subspace(self, list_of_labels_or_inds, **kwargs): return self.get_subset(list_of_labels_or_inds, 2, **kwargs) def get_samples_by_index(self, list_of_indices, **kwargs): return self.get_subset_by_index(list_of_indices, 2, **kwargs) def get_samples_by_labels(self, list_of_labels): return self.get_subset_by_label(list_of_labels, 2, **kwargs) def get_samples(self, list_of_labels_or_inds, **kwargs): return self.get_subset(list_of_labels_or_inds, 2, **kwargs) def __getattr__(self, attr_name): if self.labels_ordering[1] in self._tvb.labels_dimensions.keys(): if attr_name in self.variables_labels: return self.get_variables_by_label(attr_name) if (self.labels_ordering[2] in self._tvb.labels_dimensions.keys()): if attr_name in self.space_labels: return self.get_subspace_by_labels(attr_name) if (self.labels_ordering[3] in self._tvb.labels_dimensions.keys()): if attr_name in self.samples_labels: return self.get_samples_by_labels(attr_name) try: return getattr(self._tvb, attr_name) except: # Hack to avoid stupid error messages when searching for __ attributes in numpy.array() call... # TODO: something better? Maybe not needed if we never do something like numpy.array(timeseries) if attr_name.find("__") < 0: self.logger.error( "Attribute %s is not defined for this instance! You can use the following labels: " "%s = %s and %s = %s" % (attr_name, TimeseriesDimensions.VARIABLES.value, self.variables_labels, TimeseriesDimensions.SPACE.value, self.space_labels)) raise AttributeError def _get_index_for_slice_label(self, slice_label, slice_idx): if slice_idx == 1: return self._get_indices_of_labels([slice_label])[0] if slice_idx == 2: return self._get_indices_of_variables(slice_label) def _check_for_string_slice_indices(self, current_slice, slice_idx): slice_label1 = current_slice.start slice_label2 = current_slice.stop if isinstance(slice_label1, string_types): slice_label1 = self._get_index_for_slice_label( slice_label1, slice_idx) if isinstance(slice_label2, string_types): slice_label2 = self._get_index_for_slice_label( slice_label2, slice_idx) return slice(slice_label1, slice_label2, current_slice.step) def _get_string_slice_index(self, current_slice_string, slice_idx): return self._get_index_for_slice_label(current_slice_string, slice_idx) def __getitem__(self, slice_tuple): slice_list = [] for idx, current_slice in enumerate(slice_tuple): if isinstance(current_slice, slice): slice_list.append( self._check_for_string_slice_indices(current_slice, idx)) else: if isinstance(current_slice, string_types): slice_list.append( self._get_string_slice_index(current_slice, idx)) else: slice_list.append(current_slice) return self._tvb.data[tuple(slice_list)] @property def title(self): return self._tvb.title @property def data(self): return self._tvb.data @property def shape(self): return self._tvb.data.shape @property def time(self): return self._tvb.time @property def time_length(self): return self._tvb.length_1d @property def number_of_variables(self): return self._tvb.length_2d @property def number_of_labels(self): return self._tvb.length_3d @property def number_of_samples(self): return self._tvb.length_4d @property def start_time(self): return self._tvb.start_time @property def sample_period(self): return self._tvb.sample_period @property def end_time(self): return self.start_time + (self.time_length - 1) * self.sample_period @property def duration(self): return self.end_time - self.start_time def configure_time(self): self._tvb.time = numpy.arange(self.start_time, self.end_time + self.sample_period, self.sample_period) return self @property def time_unit(self): return self._tvb.sample_period_unit @property def sample_period_unit(self): return self._tvb.sample_period_unit @property def sample_rate(self): return self._tvb.sample_rate def configure_sampling_frequency(self): if len(self._tvb.sample_period_unit ) > 0 and self._tvb.sample_period_unit[0] == "m": self._tvb.sample_rate = 1000.0 / self._tvb.sample_period else: self._tvb.sample_rate = 1.0 / self._tvb.sample_period return self def configure_sample_rate(self): return self.configure_sampling_frequency() @property def labels_dimensions(self): return self._tvb.labels_dimensions @property def labels_ordering(self): return self._tvb.labels_ordering @property def space_labels(self): try: return numpy.array(self._tvb.get_space_labels()) except: return numpy.array( self._tvb.labels_dimensions.get(self.labels_ordering[2], [])) @property def variables_labels(self): return numpy.array( self._tvb.labels_dimensions.get(self.labels_ordering[1], [])) @property def samples_labels(self): return numpy.array( self._tvb.labels_dimensions.get(self.labels_ordering[3], [])) @property def nr_dimensions(self): return self._tvb.nr_dimensions @property def number_of_dimensions(self): return self._tvb.nr_dimensions @property def sensors(self): return self._tvb.sensors @property def connectivity(self): return self._tvb.connectivity @property def region_mapping_volume(self): return self._tvb.region_mapping_volume @property def region_mapping(self): return self._tvb.region_mapping @property def surface(self): return self._tvb.surface @property def volume(self): return self._tvb.volume @property def squeezed(self): return numpy.squeeze(self._tvb.data) def get_time_window(self, index_start, index_end, **kwargs): if index_start < 0 or index_end > self._tvb.data.shape[0]: self.logger.error( "The time indices are outside time series interval: [%s, %s]" % (0, self._tvb.data.shape[0])) raise IndexError subtime_data = self._tvb.data[index_start:index_end, :, :, :] if subtime_data.ndim == 3: subtime_data = numpy.expand_dims(subtime_data, 0) return self.duplicate(data=subtime_data, start_time=self._get_time_for_index(index_start), **kwargs) def get_time_window_by_units(self, unit_start, unit_end, **kwargs): end_time = self.end_time if unit_start < self._tvb.start_time or unit_end > end_time: self.logger.error( "The time units are outside time series interval: [%s, %s]" % (self._tvb.start_time, end_time)) raise ValueError index_start = self._get_index_for_time(unit_start) index_end = self._get_index_for_time(unit_end) return self.get_time_window(index_start, index_end) def decimate_time(self, new_sample_period, **kwargs): if new_sample_period % self.sample_period != 0: self.logger.error( "Cannot decimate time if new time step is not a multiple of the old time step" ) raise ValueError index_step = int(new_sample_period / self._tvb.sample_period) time_data = self._tvb.data[::index_step, :, :, :] return self.duplicate(data=time_data, sample_period=new_sample_period, **kwargs) def get_sample_window(self, index_start, index_end, **kwargs): subsample_data = self._tvb.data[:, :, :, index_start:index_end] if subsample_data.ndim == 3: subsample_data = numpy.expand_dims(subsample_data, 3) return self.duplicate(data=subsample_data, **kwargs) def get_source(self): if self.labels_ordering[1] not in self._tvb.labels_dimensions.keys(): self.logger.error( "No state variables are defined for this instance!") raise ValueError if PossibleVariables.SOURCE.value in self.variables_labels: return self.get_variables_by_label(PossibleVariables.SOURCE.value) def get_bipolar(self, **kwargs): bipolar_labels, bipolar_inds = monopolar_to_bipolar(self.space_labels) data = self._tvb.data[:, :, bipolar_inds[0]] - self._tvb.data[:, :, bipolar_inds[1]] bipolar_labels_dimensions = deepcopy(self._tvb.labels_dimensions) bipolar_labels_dimensions[self.labels_ordering[2]] = list( bipolar_labels) return self.duplicate(data=data, labels_dimensions=bipolar_labels_dimensions, **kwargs) def set_data(self, data): self._tvb.data = data return self def configure(self): self._tvb.configure() self.configure_time() self.configure_sampling_frequency() self.configure_sample_rate() return self