Example #1
0
 def test_none_complex_attribute(self):
     """
     Test that traited attributes are returned None, 
     when no value is assigned as default to them.
     """
     serie = time_series.TimeSeriesRegion()
     self.assertTrue(serie.connectivity is None)
Example #2
0
 def test_timeseriesregion(self):
     data = numpy.random.random((10, 10))
     dt = time_series.TimeSeriesRegion(data=data)
     assert dt.data.shape ==  (10, 10)
     assert dt.labels_ordering ==  ['Time', 'State Variable', 'Region', 'Mode']
     assert dt.sample_period ==  1.0
     assert dt.sample_rate ==  0.0
     assert dt.start_time ==  0.0
     assert dt.time.shape ==  (0,)
Example #3
0
 def test_timeseriesregion(self):
     data = numpy.random.random((10, 10))
     dt = time_series.TimeSeriesRegion(data=data)
     self.assertEqual(dt.data.shape, (10, 10))
     self.assertEqual(dt.labels_ordering, ['Time', 'State Variable', 'Region', 'Mode'])
     self.assertEqual(dt.sample_period, 1.0)
     self.assertEqual(dt.sample_rate, 0.0)
     self.assertEqual(dt.start_time, 0.0)
     self.assertEqual(dt.time.shape, (0,))
Example #4
0
            self.time[self.time_view],
            offset + self.data[self.time_view, 0, :, 0])

        self.hereiam[0].remove()
        self.hereiam = self.whereami_ax.plot(self.time_view,
                                             numpy.zeros(
                                                 (len(self.time_view), )),
                                             'b-',
                                             linewidth=4)

        pylab.draw()

if __name__ == "__main__":
    # Do some stuff that tests or makes use of this module...
    LOG.info("Testing %s module..." % __file__)
    try:
        data = numpy.load("../demos/demo_data_region_16s_2048Hz.npy")  #
    except IOError:
        LOG.error(
            "Can't load demo data. Run demos/generate_region_demo_data.py")
        raise

    period = 0.00048828125  #NOTE: Providing period in s
    tsr = time_series_datatypes.TimeSeriesRegion()
    tsr.data = data
    tsr.sample_period = period

    tsi = TimeSeriesInteractive(time_series=tsr)
    tsi.configure()
    tsi.show()
Example #5
0
    def evaluate(self):
        """
        Calculate simulated BOLD signal
        """
        cls_attr_name = self.__class__.__name__ + ".time_series"
        # self.time_series.trait["data"].log_debug(owner=cls_attr_name)

        # NOTE: Just using the first state variable, although in the Bold monitor
        #      input is the sum over the state-variables. Only time-series
        #      from basic monitors should be used as inputs.

        neural_activity, t_int = self.input_transformation(
            self.time_series, self.neural_input_transformation)
        input_shape = neural_activity.shape
        result_shape = self.result_shape(input_shape)
        self.log.debug("Result shape will be: %s" % str(result_shape))

        if self.dt is None:
            self.dt = self.time_series.sample_period / 1000.  # (s) integration time step
            msg = "Integration time step size for the balloon model is %s seconds" % str(
                self.dt)
            self.log.debug(msg)

        # NOTE: Avoid upsampling ...
        if self.dt < (self.time_series.sample_period / 1000.):
            msg = "Integration time step shouldn't be smaller than the sampling period of the input signal."
            self.log.error(msg)

        balloon_nvar = 4

        # NOTE: hard coded initial conditions
        state = numpy.zeros((input_shape[0], balloon_nvar, input_shape[2],
                             input_shape[3]))  # s
        state[0, 1, :] = 1.  # f
        state[0, 2, :] = 1.  # v
        state[0, 3, :] = 1.  # q

        # BOLD model coefficients
        k = self.compute_derived_parameters()
        k1, k2, k3 = k[0], k[1], k[2]

        # prepare integrator
        self.integrator.dt = self.dt
        self.integrator.configure()
        self.log.debug("Integration time step size will be: %s seconds" %
                       str(self.integrator.dt))

        scheme = self.integrator.scheme

        # NOTE: the following variables are not used in this integration but
        # required due to the way integrators scheme has been defined.

        local_coupling = 0.0
        stimulus = 0.0

        # Do some checks:
        if numpy.isnan(neural_activity).any():
            self.log.warning("NaNs detected in the neural activity!!")

        # normalise the time-series.
        neural_activity = neural_activity - neural_activity.mean(
            axis=0)[numpy.newaxis, :]

        # solve equations
        for step in range(1, t_int.shape[0]):
            state[step, :] = scheme(state[step - 1, :], self.balloon_dfun,
                                    neural_activity[step, :], local_coupling,
                                    stimulus)
            if numpy.isnan(state[step, :]).any():
                self.log.warning("NaNs detected...")

        # NOTE: just for the sake of clarity, define the variables used in the BOLD model
        s = state[:, 0, :]
        f = state[:, 1, :]
        v = state[:, 2, :]
        q = state[:, 3, :]

        # import pdb; pdb.set_trace()

        # BOLD models
        if self.bold_model == "nonlinear":
            """
            Non-linear BOLD model equations.
            Page 391. Eq. (13) top in [Stephan2007]_
            """
            y_bold = numpy.array(self.V0 * (k1 * (1. - q) + k2 *
                                            (1. - q / v) + k3 * (1. - v)))
            y_b = y_bold[:, numpy.newaxis, :, :]
            self.log.debug("Max value: %s" % str(y_b.max()))

        else:
            """
            Linear BOLD model equations.
            Page 391. Eq. (13) bottom in [Stephan2007]_ 
            """
            y_bold = numpy.array(self.V0 * ((k1 + k2) * (1. - q) + (k3 - k2) *
                                            (1. - v)))
            y_b = y_bold[:, numpy.newaxis, :, :]

        sample_period = 1. / self.dt

        bold_signal = time_series.TimeSeriesRegion(data=y_b,
                                                   time=t_int,
                                                   sample_period=sample_period,
                                                   sample_period_unit='s')

        return bold_signal
Example #6
0
    def launch(self, model, model_parameters, integrator, integrator_parameters, connectivity,
               monitors, monitors_parameters=None, surface=None, surface_parameters=None, stimulus=None,
               coupling=None, coupling_parameters=None, initial_conditions=None,
               conduction_speed=None, simulation_length=0, simulation_state=None):
        """
        Called from the GUI to launch a simulation.
          *: string class name of chosen model, etc...
          *_parameters: dictionary of parameters for chosen model, etc...
          connectivity: tvb.datatypes.connectivity.Connectivity object.
          surface: tvb.datatypes.surfaces.CorticalSurface: or None.
          stimulus: tvb.datatypes.patters.* object
        """
        result_datatypes = dict()
        start_time = self.algorithm.current_step * self.algorithm.integrator.dt
        m_ind = -1
        for m_name in monitors:
            m_ind += 1
            sample_period = self.algorithm.monitors[m_ind].period
            # Create the required output for each monitor that was submitted
            if (m_name in self.RESULTS_MAP[time_series.TimeSeriesEEG]
                    and hasattr(self.algorithm.monitors[m_ind], 'sensors')):
                result_datatypes[m_name] = time_series.TimeSeriesEEG(storage_path=self.storage_path,
                                                                     sensors=self.algorithm.monitors[m_ind].sensors,
                                                                     sample_period=sample_period,
                                                                     title=' ' + m_name, start_time=start_time, )

            elif (m_name in self.RESULTS_MAP[time_series.TimeSeriesMEG]
                  and hasattr(self.algorithm.monitors[m_ind], 'sensors')):
                result_datatypes[m_name] = time_series.TimeSeriesMEG(storage_path=self.storage_path,
                                                                     sensors=self.algorithm.monitors[m_ind].sensors,
                                                                     sample_period=sample_period,
                                                                     title=' ' + m_name, start_time=start_time)

            elif m_name in self.RESULTS_MAP[time_series.TimeSeries]:
                result_datatypes[m_name] = time_series.TimeSeries(storage_path=self.storage_path,
                                                                  sample_period=sample_period,
                                                                  title=' ' + m_name, start_time=start_time)

            elif surface is None:
                ## We do not have a surface selected from UI, or regions only result.
                result_datatypes[m_name] = time_series.TimeSeriesRegion(storage_path=self.storage_path,
                                                                        connectivity=connectivity,
                                                                        sample_period=sample_period,
                                                                        title='Regions ' + m_name,
                                                                        start_time=start_time)

            else:
                result_datatypes[m_name] = time_series.TimeSeriesSurface(storage_path=self.storage_path,
                                                                         surface=surface, sample_period=sample_period,
                                                                         title='Surface ' + m_name,
                                                                         start_time=start_time)
            # Now check if the monitor will return results for each state variable, in which case store
            # the labels for these state variables.
            if m_name in self.HAVE_STATE_VARIABLES:
                selected_state_vars = [self.algorithm.model.state_variables[idx]
                                       for idx in self.algorithm.monitors[m_ind].voi]
                state_variable_dimension_name = result_datatypes[m_name].labels_ordering[1]
                result_datatypes[m_name].labels_dimensions[state_variable_dimension_name] = selected_state_vars
        
        #### Create Simulator State entity and persist it in DB. H5 file will be empty now.
        if not self._is_group_launch():
            simulation_state = SimulationState(storage_path=self.storage_path)
            self._capture_operation_results([simulation_state])

        ### Run simulation
        self.log.debug("%s: Starting simulation..." % str(self))
        for result in self.algorithm(simulation_length=simulation_length):
            for j, monitor in enumerate(monitors):
                if result[j] is not None:
                    result_datatypes[monitor].write_time_slice([result[j][0]])
                    result_datatypes[monitor].write_data_slice([result[j][1]])

        self.log.debug("%s: Completed simulation, starting to store simulation state " % str(self))
        ### Populate H5 file for simulator state. This step could also be done while running sim, in background.
        if not self._is_group_launch():
            simulation_state.populate_from(self.algorithm)
            self._capture_operation_results([simulation_state])

        self.log.debug("%s: Simulation state persisted, returning results " % str(self))
        final_results = []
        for result in result_datatypes.values():
            result.close_file()
            final_results.append(result)
        self.log.info("%s: Adapter simulation finished!!" % str(self))
        return final_results
class FcdCalculator(core.Type):
    """
    The present class will do the following actions:

    - Compute the the fcd of the timeseries; the fcd is calculated in the following way:
        the time series is divided in time window of fixed length and with an overlapping of fixed length.
        The data-points within each window, centered at time ti, are used to calculate FC(ti) as Pearson correlation.
        The ij element of the FCD matrix is calculated as the Pearson correlation between FC(ti) and FC(tj) -in a vector
    - Apply to the fcd the spectral embedding algorithm in order to calculate epochs of stability of the fcd
        (length of time during which FC matrix are high correlated).

    The algorithm can produce 2 kind of results:

    - case 1: the algorithm is able to identify the epochs of stability
        -- fcs calculated over the epochs of stability (excluded the first one = artifact, due to initial conditions)
        -- 3 eigenvectors, associated to the 3 largest eigenvalues, of the fcs are extracted
    - case 2: the algorithm is not able to identify the epochs of stability
        -- fc over the all time series is calculated
        -- 3 first eigenvectors, associated to the 3 largest eigenvalues, of the fcs are extracted

    :return
        - fcd matrix whose values are between -1 and 1, inclusive.
        - in case 1: fcd matrix segmented i.e. fcd whose values are between -1 and 1.1, inclusive.
            (Value=1.1 for time not belonging to epochs of stability identified with spectral embedding algorithm)
            in case 2: fcd matrix segmented identical to the fcd matrix not segmented
        - dictionary containing the eigenvectors.
        - dictionary containing the eigenvalues
        - connectivity associated to the TimeSeriesRegions

    """

    time_series = time_series.TimeSeriesRegion(
        label="Time Series",
        required=True,
        doc="""The time-series for which the fcd matrices are calculated.""")

    sw = types_basic.Float(
        label="Sliding window length (ms)",
        default=120000,
        doc="""Length of the time window used to divided the time series.
        FCD matrix is calculated in the following way: the time series is divided in time window of fixed length and
        with an overlapping of fixed length. The datapoints within each window, centered at time ti, are used to
        calculate FC(ti) as Pearson correlation. The ij element of the FCD matrix is calculated as the Pearson
        Correlation between FC(ti) and FC(tj) arranged in a vector.""")

    sp = types_basic.Float(
        label="Spanning between two consecutive sliding window (ms)",
        default=2000,
        doc=
        """Spanning= (time windows length)-(overlapping between two consecutive time window). FCD matrix is
        calculated in the following way: the time series is divided in time window of fixed length and with an
        overlapping of fixed length. The datapoints within each window, centered at time ti, are used to calculate
        FC(ti) as Pearson Correlation. The ij element of the FCD matrix is calculated as the Pearson correlation
        between FC(ti) and FC(tj) arranged in a vector""")

    def evaluate(self):
        cls_attr_name = self.__class__.__name__ + ".time_series"
        self.time_series.trait["data"].log_debug(owner=cls_attr_name)

        # Pass sp and sw in the right time reference (means considering the sample period)
        sp = float(self.sp) / self.time_series.sample_period
        sw = float(self.sw) / self.time_series.sample_period

        input_shape = self.time_series.read_data_shape()
        result_shape = self.result_shape(input_shape)

        fcd = np.zeros(result_shape)
        fc_stream = {
        }  # dict where the fc calculated over the sliding window will be stored
        start = -sp  # in order to well initialize the first starting point of the FC stream
        for mode in range(result_shape[3]):
            for var in range(result_shape[2]):
                for nfcd in range(result_shape[0]):
                    start += sp
                    current_slice = tuple([
                        slice(int(start),
                              int(start + sw) + 1),
                        slice(var, var + 1),
                        slice(input_shape[2]),
                        slice(mode, mode + 1)
                    ])
                    data = self.time_series.read_data_slice(
                        current_slice).squeeze()
                    fc = np.corrcoef(data.T)
                    # the triangular part of the fc is organized as a vector, excluding the diagonal (always ones)
                    triangular = np.triu_indices(len(fc), 1)
                    fc_stream[nfcd] = fc[triangular]
                for i in range(result_shape[0]):
                    j = i
                    while j < result_shape[0]:
                        fci = fc_stream[i]
                        fcj = fc_stream[j]
                        fcd[i, j, var, mode] = np.corrcoef(fci, fcj)[0, 1]
                        fcd[j, i, var, mode] = fcd[i, j, var, mode]
                        j += 1

        util.log_debug_array(LOG, fcd, "FCD")

        num_eig = 3  # number of the eigenvector that will be extracted

        eigvect_dict = {
        }  # holds eigenvectors of the fcs calculated over the epochs, key1=mode, key2=var, key3=numb ep
        eigval_dict = {
        }  # holds eigenvalues of the fcs calculated over the epochs, key1=mode, key2=var, key3=numb ep
        for mode in range(result_shape[3]):
            eigvect_dict[mode] = {}
            eigval_dict[mode] = {}
            for var in range(result_shape[2]):
                eigvect_dict[mode][var] = {}
                eigval_dict[mode][var] = {}
                fcd_matrix = fcd[:, :, var, mode]
                [xir, xir_cutoff] = spectral_embedding(fcd_matrix)
                epochs_extremes = epochs_interval(xir, xir_cutoff, sp, sw)
                fcd_segmented = fcd.copy()
                if epochs_extremes.shape[0] <= 1:
                    # means that there are no more than 1 epochs of stability, thus the eigenvectors of
                    # the FC calculated over the entire TimeSeries will be calculated
                    epochs_extremes = np.zeros((2, 2), dtype=float)
                    epochs_extremes[1, 1] = input_shape[
                        0]  # [0,0] set in order to skip the first epoch
                else:
                    # means that more than 1 epochs of stability is identified thus fcd_segmented is calculated
                    fcd_segmented[xir > xir_cutoff, :, var, mode] = 1.1
                    fcd_segmented[:, xir > xir_cutoff, var, mode] = 1.1

                for ep in range(1, epochs_extremes.shape[0]):
                    eigvect_dict[mode][var][ep] = []
                    eigval_dict[mode][var][ep] = []
                    current_slice = tuple([
                        slice(int(epochs_extremes[ep][0]),
                              int(epochs_extremes[ep][1]) + 1),
                        slice(var, var + 1),
                        slice(input_shape[2]),
                        slice(mode, mode + 1)
                    ])
                    data = self.time_series.read_data_slice(
                        current_slice).squeeze()
                    fc = np.corrcoef(
                        data.T)  # calculate fc over the epoch of stability
                    eigval_matrix, eigvect_matrix = linalg.eig(fc)
                    eigval_matrix = np.real(eigval_matrix)
                    eigvect_matrix = np.real(eigvect_matrix)
                    eigval_matrix = eigval_matrix / np.sum(
                        np.abs(eigval_matrix)
                    )  # normalize eigenvalues to [0 and 1)
                    for en in range(num_eig):
                        index = np.argmax(eigval_matrix)
                        eigvect_dict[mode][var][ep].append(
                            abs(eigvect_matrix[:, index]))
                        eigval_dict[mode][var][ep].append(eigval_matrix[index])
                        eigval_matrix[index] = 0

        return [
            fcd, fcd_segmented, eigvect_dict, eigval_dict,
            self.time_series.connectivity
        ]

    def result_shape(self, input_shape):
        """Returns the shape of the fcd"""
        sp = float(self.sp) / self.time_series.sample_period
        sw = float(self.sw) / self.time_series.sample_period
        fcd_points = int((input_shape[0] - sw) / sp)
        result_shape = (fcd_points, fcd_points, input_shape[1], input_shape[3])
        return result_shape

    def result_size(self, input_shape):
        """
        Returns the storage size in Bytes of the main result of .
        """
        result_size = np.sum(map(
            np.prod, self.result_shape(input_shape))) * 8.0  # Bytes
        return result_size

    def extended_result_size(self, input_shape):
        """
        Returns the storage size in Bytes of the extended result of the ....
        That is, it includes storage of the evaluated ... attributes
        such as ..., etc.
        """
        extend_size = self.result_size(
            input_shape)  # Currently no derived attributes.
        return extend_size