123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814 |
- # -*- coding: utf-8 -*-
- """
- This module allows to convert standard data representations
- (e.g., a spike train stored as Neo SpikeTrain object)
- into other representations useful to perform calculations on the data.
- An example is the representation of a spike train as a sequence of 0-1 values
- (binned spike train).
- :copyright: Copyright 2014-2016 by the Elephant team, see AUTHORS.txt.
- :license: BSD, see LICENSE.txt for details.
- """
- from __future__ import division, print_function
- import neo
- import scipy
- import scipy.sparse as sps
- import numpy as np
- import quantities as pq
- def binarize(spiketrain, sampling_rate=None, t_start=None, t_stop=None,
- return_times=None):
- """
- Return an array indicating if spikes occured at individual time points.
- The array contains boolean values identifying whether one or more spikes
- happened in the corresponding time bin. Time bins start at `t_start`
- and end at `t_stop`, spaced in `1/sampling_rate` intervals.
- Accepts either a Neo SpikeTrain, a Quantity array, or a plain NumPy array.
- Returns a boolean array with each element being the presence or absence of
- a spike in that time bin. The number of spikes in a time bin is not
- considered.
- Optionally also returns an array of time points corresponding to the
- elements of the boolean array. The units of this array will be the same as
- the units of the SpikeTrain, if any.
- Parameters
- ----------
- spiketrain : Neo SpikeTrain or Quantity array or NumPy array
- The spike times. Does not have to be sorted.
- sampling_rate : float or Quantity scalar, optional
- The sampling rate to use for the time points.
- If not specified, retrieved from the `sampling_rate`
- attribute of `spiketrain`.
- t_start : float or Quantity scalar, optional
- The start time to use for the time points.
- If not specified, retrieved from the `t_start`
- attribute of `spiketrain`. If that is not present, default to
- `0`. Any value from `spiketrain` below this value is
- ignored.
- t_stop : float or Quantity scalar, optional
- The start time to use for the time points.
- If not specified, retrieved from the `t_stop`
- attribute of `spiketrain`. If that is not present, default to
- the maximum value of `sspiketrain`. Any value from
- `spiketrain` above this value is ignored.
- return_times : bool
- If True, also return the corresponding time points.
- Returns
- -------
- values : NumPy array of bools
- A ``True`` value at a particular index indicates the presence of
- one or more spikes at the corresponding time point.
- times : NumPy array or Quantity array, optional
- The time points. This will have the same units as `spiketrain`.
- If `spiketrain` has no units, this will be an NumPy array.
- Notes
- -----
- Spike times are placed in the bin of the closest time point, going to the
- higher bin if exactly between two bins.
- So in the case where the bins are `5.5` and `6.5`, with the spike time
- being `6.0`, the spike will be placed in the `6.5` bin.
- The upper edge of the last bin, equal to `t_stop`, is inclusive. That is,
- a spike time exactly equal to `t_stop` will be included.
- If `spiketrain` is a Quantity or Neo SpikeTrain and
- `t_start`, `t_stop` or `sampling_rate` is not, then the arguments that
- are not quantities will be assumed to have the same units as `spiketrain`.
- Raises
- ------
- TypeError
- If `spiketrain` is a NumPy array and `t_start`, `t_stop`, or
- `sampling_rate` is a Quantity..
- ValueError
- `t_start` and `t_stop` can be inferred from `spiketrain` if
- not explicitly defined and not an attribute of `spiketrain`.
- `sampling_rate` cannot, so an exception is raised if it is not
- explicitly defined and not present as an attribute of `spiketrain`.
- """
- # get the values from spiketrain if they are not specified.
- if sampling_rate is None:
- sampling_rate = getattr(spiketrain, 'sampling_rate', None)
- if sampling_rate is None:
- raise ValueError('sampling_rate must either be explicitly defined '
- 'or must be an attribute of spiketrain')
- if t_start is None:
- t_start = getattr(spiketrain, 't_start', 0)
- if t_stop is None:
- t_stop = getattr(spiketrain, 't_stop', np.max(spiketrain))
- # we don't actually want the sampling rate, we want the sampling period
- sampling_period = 1. / sampling_rate
- # figure out what units, if any, we are dealing with
- if hasattr(spiketrain, 'units'):
- units = spiketrain.units
- spiketrain = spiketrain.magnitude
- else:
- units = None
- # convert everything to the same units, then get the magnitude
- if hasattr(sampling_period, 'units'):
- if units is None:
- raise TypeError('sampling_period cannot be a Quantity if '
- 'spiketrain is not a quantity')
- sampling_period = sampling_period.rescale(units).magnitude
- if hasattr(t_start, 'units'):
- if units is None:
- raise TypeError('t_start cannot be a Quantity if '
- 'spiketrain is not a quantity')
- t_start = t_start.rescale(units).magnitude
- if hasattr(t_stop, 'units'):
- if units is None:
- raise TypeError('t_stop cannot be a Quantity if '
- 'spiketrain is not a quantity')
- t_stop = t_stop.rescale(units).magnitude
- # figure out the bin edges
- edges = np.arange(t_start - sampling_period / 2, t_stop + sampling_period * 3 / 2,
- sampling_period)
- # we don't want to count any spikes before t_start or after t_stop
- if edges[-2] > t_stop:
- edges = edges[:-1]
- if edges[1] < t_start:
- edges = edges[1:]
- edges[0] = t_start
- edges[-1] = t_stop
- # this is where we actually get the binarized spike train
- res = np.histogram(spiketrain, edges)[0].astype('bool')
- # figure out what to output
- if not return_times:
- return res
- elif units is None:
- return res, np.arange(t_start, t_stop + sampling_period, sampling_period)
- else:
- return res, pq.Quantity(np.arange(t_start, t_stop + sampling_period,
- sampling_period), units=units)
- ###########################################################################
- #
- # Methods to calculate parameters, t_start, t_stop, bin size,
- # number of bins
- #
- ###########################################################################
- def _calc_tstart(num_bins, binsize, t_stop):
- """
- Calculates the start point from given parameter.
- Calculates the start point :attr:`t_start` from the three parameter
- :attr:`t_stop`, :attr:`num_bins` and :attr`binsize`.
- Parameters
- ----------
- num_bins: int
- Number of bins
- binsize: quantities.Quantity
- Size of Bins
- t_stop: quantities.Quantity
- Stop time
- Returns
- -------
- t_start : quantities.Quantity
- Starting point calculated from given parameter.
- """
- if num_bins is not None and binsize is not None and t_stop is not None:
- return t_stop.rescale(binsize.units) - num_bins * binsize
- def _calc_tstop(num_bins, binsize, t_start):
- """
- Calculates the stop point from given parameter.
- Calculates the stop point :attr:`t_stop` from the three parameter
- :attr:`t_start`, :attr:`num_bins` and :attr`binsize`.
- Parameters
- ----------
- num_bins: int
- Number of bins
- binsize: quantities.Quantity
- Size of bins
- t_start: quantities.Quantity
- Start time
- Returns
- -------
- t_stop : quantities.Quantity
- Stoping point calculated from given parameter.
- """
- if num_bins is not None and binsize is not None and t_start is not None:
- return t_start.rescale(binsize.units) + num_bins * binsize
- def _calc_num_bins(binsize, t_start, t_stop):
- """
- Calculates the number of bins from given parameter.
- Calculates the number of bins :attr:`num_bins` from the three parameter
- :attr:`t_start`, :attr:`t_stop` and :attr`binsize`.
- Parameters
- ----------
- binsize: quantities.Quantity
- Size of Bins
- t_start : quantities.Quantity
- Start time
- t_stop: quantities.Quantity
- Stop time
- Returns
- -------
- num_bins : int
- Number of bins calculated from given parameter.
- Raises
- ------
- ValueError :
- Raised when :attr:`t_stop` is smaller than :attr:`t_start`".
- """
- if binsize is not None and t_start is not None and t_stop is not None:
- if t_stop < t_start:
- raise ValueError("t_stop (%s) is smaller than t_start (%s)"
- % (t_stop, t_start))
- return int(((t_stop - t_start).rescale(
- binsize.units) / binsize).magnitude)
- def _calc_binsize(num_bins, t_start, t_stop):
- """
- Calculates the stop point from given parameter.
- Calculates the size of bins :attr:`binsize` from the three parameter
- :attr:`num_bins`, :attr:`t_start` and :attr`t_stop`.
- Parameters
- ----------
- num_bins: int
- Number of bins
- t_start: quantities.Quantity
- Start time
- t_stop
- Stop time
- Returns
- -------
- binsize : quantities.Quantity
- Size of bins calculated from given parameter.
- Raises
- ------
- ValueError :
- Raised when :attr:`t_stop` is smaller than :attr:`t_start`".
- """
- if num_bins is not None and t_start is not None and t_stop is not None:
- if t_stop < t_start:
- raise ValueError("t_stop (%s) is smaller than t_start (%s)"
- % (t_stop, t_start))
- return (t_stop - t_start) / num_bins
- def _get_start_stop_from_input(spiketrains):
- """
- Returns the start :attr:`t_start`and stop :attr:`t_stop` point
- from given input.
- If one neo.SpikeTrain objects is given the start :attr:`t_stop `and stop
- :attr:`t_stop` of the spike train is returned.
- Otherwise the aligned times are returned, which are the maximal start point
- and minimal stop point.
- Parameters
- ----------
- spiketrains: neo.SpikeTrain object, list or array of neo.core.SpikeTrain
- objects
- List of neo.core SpikeTrain objects to extract `t_start` and
- `t_stop` from.
- Returns
- -------
- start : quantities.Quantity
- Start point extracted from input :attr:`spiketrains`
- stop : quantities.Quantity
- Stop point extracted from input :attr:`spiketrains`
- """
- if isinstance(spiketrains, neo.SpikeTrain):
- return spiketrains.t_start, spiketrains.t_stop
- else:
- start = max([elem.t_start for elem in spiketrains])
- stop = min([elem.t_stop for elem in spiketrains])
- return start, stop
- class BinnedSpikeTrain(object):
- """
- Class which calculates a binned spike train and provides methods to
- transform the binned spike train to a boolean matrix or a matrix with
- counted time points.
- A binned spike train represents the occurrence of spikes in a certain time
- frame.
- I.e., a time series like [0.5, 0.7, 1.2, 3.1, 4.3, 5.5, 6.7] is
- represented as [0, 0, 1, 3, 4, 5, 6]. The outcome is dependent on given
- parameter such as size of bins, number of bins, start and stop points.
- A boolean matrix represents the binned spike train in a binary (True/False)
- manner.
- Its rows represent the number of spike trains
- and the columns represent the binned index position of a spike in a
- spike train.
- The calculated matrix columns contains **Trues**, which indicate
- a spike.
- A matrix with counted time points is calculated the same way, but its
- columns contain the number of spikes that occurred in the spike train(s).
- It counts the occurrence of the timing of a spike in its respective
- spike train.
- Parameters
- ----------
- spiketrains : List of `neo.SpikeTrain` or a `neo.SpikeTrain` object
- Spiketrain(s)to be binned.
- binsize : quantities.Quantity
- Width of each time bin.
- Default is `None`
- num_bins : int
- Number of bins of the binned spike train.
- Default is `None`
- t_start : quantities.Quantity
- Time of the first bin (left extreme; included).
- Default is `None`
- t_stop : quantities.Quantity
- Stopping time of the last bin (right extreme; excluded).
- Default is `None`
- See also
- --------
- _convert_to_binned
- spike_indices
- to_bool_array
- to_array
- Notes
- -----
- There are four cases the given parameters must fulfill.
- Each parameter must be a combination of following order or it will raise
- a value error:
- * t_start, num_bins, binsize
- * t_start, num_bins, t_stop
- * t_start, bin_size, t_stop
- * t_stop, num_bins, binsize
- It is possible to give the SpikeTrain objects and one parameter
- (:attr:`num_bins` or :attr:`binsize`). The start and stop time will be
- calculated from given SpikeTrain objects (max start and min stop point).
- Missing parameter will also be calculated automatically.
- All parameters will be checked for consistency. A corresponding error will
- be raised, if one of the four parameters does not match the consistency
- requirements.
- """
- def __init__(self, spiketrains, binsize=None, num_bins=None, t_start=None,
- t_stop=None):
- """
- Defines a binned spike train class
- """
- # Converting spiketrains to a list, if spiketrains is one
- # SpikeTrain object
- if isinstance(spiketrains, neo.SpikeTrain):
- spiketrains = [spiketrains]
- # Check that spiketrains is a list of neo Spike trains.
- if not all([type(elem) == neo.core.SpikeTrain for elem in spiketrains]):
- raise TypeError(
- "All elements of the input list must be neo.core.SpikeTrain "
- "objects ")
- # Link to input
- self.lst_input = spiketrains
- # Set given parameter
- self.t_start = t_start
- self.t_stop = t_stop
- self.num_bins = num_bins
- self.binsize = binsize
- self.matrix_columns = num_bins
- self.matrix_rows = len(spiketrains)
- # Empty matrix for storage, time points matrix
- self._mat_u = None
- # Check all parameter, set also missing values
- self._calc_start_stop(spiketrains)
- self._check_init_params(binsize, num_bins, self.t_start, self.t_stop)
- self._check_consistency(spiketrains, self.binsize, self.num_bins,
- self.t_start, self.t_stop)
- # Variables to store the sparse matrix
- self._sparse_mat_u = None
- # Now create sparse matrix
- self._convert_to_binned(spiketrains)
- # =========================================================================
- # There are four cases the given parameters must fulfill
- # Each parameter must be a combination of following order or it will raise
- # a value error:
- # t_start, num_bins, binsize
- # t_start, num_bins, t_stop
- # t_start, bin_size, t_stop
- # t_stop, num_bins, binsize
- # ==========================================================================
- def _check_init_params(self, binsize, num_bins, t_start, t_stop):
- """
- Checks given parameter.
- Calculates also missing parameter.
- Parameters
- ----------
- binsize : quantity.Quantity
- Size of Bins
- num_bins : int
- Number of Bins
- t_start: quantity.Quantity
- Start time of the spike
- t_stop: quantity.Quantity
- Stop time of the spike
- Raises
- ------
- ValueError :
- If all parameters are `None`, a ValueError is raised.
- TypeError:
- If type of :attr:`num_bins` is not an Integer.
- """
- # Check if num_bins is an integer (special case)
- if num_bins is not None:
- if not isinstance(num_bins, int):
- raise TypeError("num_bins is not an integer!")
- # Check if all parameters can be calculated, otherwise raise ValueError
- if t_start is None:
- self.t_start = _calc_tstart(num_bins, binsize, t_stop)
- elif t_stop is None:
- self.t_stop = _calc_tstop(num_bins, binsize, t_start)
- elif num_bins is None:
- self.num_bins = _calc_num_bins(binsize, t_start, t_stop)
- if self.matrix_columns is None:
- self.matrix_columns = self.num_bins
- elif binsize is None:
- self.binsize = _calc_binsize(num_bins, t_start, t_stop)
- def _calc_start_stop(self, spiketrains):
- """
- Calculates start, stop from given spike trains.
- The start and stop points are calculated from given spike trains, only
- if they are not calculable from given parameter or the number of
- parameters is less than three.
- """
- if self._count_params() is False:
- start, stop = _get_start_stop_from_input(spiketrains)
- if self.t_start is None:
- self.t_start = start
- if self.t_stop is None:
- self.t_stop = stop
- def _count_params(self):
- """
- Counts up if one parameter is not `None` and returns **True** if the
- count is greater or equal `3`.
- The calculation of the binned matrix is only possible if there are at
- least three parameter (fourth parameter will be calculated out of
- them).
- This method checks if the necessary parameter are not `None` and
- returns **True** if the count is greater or equal to `3`.
- Returns
- -------
- bool :
- True, if the count is greater or equal to `3`.
- False, otherwise.
- """
- return sum(x is not None for x in
- [self.t_start, self.t_stop, self.binsize,
- self.num_bins]) >= 3
- def _check_consistency(self, spiketrains, binsize, num_bins, t_start,
- t_stop):
- """
- Checks the given parameters for consistency
- Raises
- ------
- ValueError :
- A ValueError is raised if an inconsistency regarding the parameter
- appears.
- AttributeError :
- An AttributeError is raised if there is an insufficient number of
- parameters.
- """
- if self._count_params() is False:
- raise AttributeError("Too less parameter given. Please provide "
- "at least one of the parameter which are "
- "None.\n"
- "t_start: %s, t_stop: %s, binsize: %s, "
- "numb_bins: %s" % (
- self.t_start,
- self.t_stop,
- self.binsize,
- self.num_bins))
- t_starts = [elem.t_start for elem in spiketrains]
- t_stops = [elem.t_stop for elem in spiketrains]
- max_tstart = max(t_starts)
- min_tstop = min(t_stops)
- if max_tstart >= min_tstop:
- raise ValueError(
- "Starting time of each spike train must be smaller than each "
- "stopping time")
- elif t_start < max_tstart or t_start > min_tstop:
- raise ValueError(
- 'some spike trains are not defined in the time given '
- 'by t_start')
- elif num_bins != int((
- (t_stop - t_start).rescale(binsize.units) / binsize).magnitude):
- raise ValueError(
- "Inconsistent arguments t_start (%s), " % t_start +
- "t_stop (%s), binsize (%d) " % (t_stop, binsize) +
- "and num_bins (%d)" % num_bins)
- elif not (t_start < t_stop <= min_tstop):
- raise ValueError(
- 'too many / too large time bins. Some spike trains are '
- 'not defined in the ending time')
- elif num_bins - int(num_bins) != 0 or num_bins < 0:
- raise TypeError(
- "Number of bins (num_bins) is not an integer or < 0: " + str(
- num_bins))
- @property
- def bin_edges(self):
- """
- Returns all time edges with :attr:`num_bins` bins as a quantity array.
- The borders of all time steps between start and stop [start, stop]
- with:attr:`num_bins` bins are regarded as edges.
- The border of the last bin is included.
- Returns
- -------
- bin_edges : quantities.Quantity array
- All edges in interval [start, stop] with :attr:`num_bins` bins
- are returned as a quantity array.
- """
- return pq.Quantity(np.linspace(self.t_start.magnitude,
- self.t_stop.magnitude,
- self.num_bins + 1, endpoint=True),
- units=self.binsize.units)
- @property
- def bin_centers(self):
- """
- Returns each center time point of all bins between start and stop
- points.
- The center of each bin of all time steps between start and stop
- (start, stop).
- Returns
- -------
- bin_edges : quantities.Quantity array
- All center edges in interval (start, stop) are returned as
- a quantity array.
- """
- return self.bin_edges[:-1] + self.binsize / 2
- def to_sparse_array(self):
- """
- Getter for sparse matrix with time points.
- Returns
- -------
- matrix: scipy.sparse.csr_matrix
- Sparse matrix, counted version.
- See also
- --------
- scipy.sparse.csr_matrix
- to_array
- """
- return self._sparse_mat_u
- def to_sparse_bool_array(self):
- """
- Getter for **boolean** version of the sparse matrix, calculated from
- sparse matrix with counted time points.
- Returns
- -------
- matrix: scipy.sparse.csr_matrix
- Sparse matrix, binary, boolean version.
- See also
- --------
- scipy.sparse.csr_matrix
- to_bool_array
- """
- # Return sparse Matrix as a copy
- tmp_mat = self._sparse_mat_u.copy()
- tmp_mat[tmp_mat.nonzero()] = 1
- return tmp_mat.astype(bool)
- @property
- def spike_indices(self):
- """
- A list of lists for each spike train (i.e., rows of the binned matrix),
- that in turn contains for each spike the index into the binned matrix
- where this spike enters.
- In contrast to `to_sparse_array().nonzero()`, this function will report
- two spikes falling in the same bin as two entries.
- Examples
- --------
- >>> import elephant.conversion as conv
- >>> import neo as n
- >>> import quantities as pq
- >>> st = n.SpikeTrain([0.5, 0.7, 1.2, 3.1, 4.3, 5.5, 6.7] * pq.s, t_stop=10.0 * pq.s)
- >>> x = conv.BinnedSpikeTrain(st, num_bins=10, binsize=1 * pq.s, t_start=0 * pq.s)
- >>> print(x.spike_indices)
- [[0, 0, 1, 3, 4, 5, 6]]
- >>> print(x.to_sparse_array().nonzero()[1])
- [0 1 3 4 5 6]
- """
- spike_idx = []
- for row in self._sparse_mat_u:
- l = []
- # Extract each non-zeros column index and how often it exists,
- # i.e., how many spikes fall in this column
- for col, count in zip(row.nonzero()[1], row.data):
- # Append the column index for each spike
- l.extend([col] * count)
- spike_idx.append(l)
- return spike_idx
- def to_bool_array(self):
- """
- Returns a dense matrix (`scipy.sparse.csr_matrix`), which rows
- represent the number of spike trains and the columns represent the
- binned index position of a spike in a spike train.
- The matrix columns contain **True**, which indicate a spike and
- **False** for non spike.
- Returns
- -------
- bool matrix : numpy.ndarray
- Returns a dense matrix representation of the sparse matrix,
- with **True** indicating a spike and **False*** for
- non spike.
- The **Trues** in the columns represent the index
- position of the spike in the spike train and rows represent the
- number of spike trains.
- Examples
- --------
- >>> import elephant.conversion as conv
- >>> import neo as n
- >>> import quantities as pq
- >>> a = n.SpikeTrain([0.5, 0.7, 1.2, 3.1, 4.3, 5.5, 6.7] * pq.s, t_stop=10.0 * pq.s)
- >>> x = conv.BinnedSpikeTrain(a, num_bins=10, binsize=1 * pq.s, t_start=0 * pq.s)
- >>> print(x.to_bool_array())
- [[ True True False True True True True False False False]]
- See also
- --------
- scipy.sparse.csr_matrix
- scipy.sparse.csr_matrix.toarray
- """
- return abs(scipy.sign(self.to_array())).astype(bool)
- def to_array(self, store_array=False):
- """
- Returns a dense matrix, calculated from the sparse matrix with counted
- time points, which rows represents the number of spike trains and the
- columns represents the binned index position of a spike in a
- spike train.
- The matrix columns contain the number of spikes that
- occurred in the spike train(s).
- If the **boolean** :attr:`store_array` is set to **True** the matrix
- will be stored in memory.
- Returns
- -------
- matrix : numpy.ndarray
- Matrix with spike times. Columns represent the index position of
- the binned spike and rows represent the number of spike trains.
- Examples
- --------
- >>> import elephant.conversion as conv
- >>> import neo as n
- >>> a = n.SpikeTrain([0.5, 0.7, 1.2, 3.1, 4.3, 5.5, 6.7] * pq.s, t_stop=10.0 * pq.s)
- >>> x = conv.BinnedSpikeTrain(a, num_bins=10, binsize=1 * pq.s, t_start=0 * pq.s)
- >>> print(x.to_array())
- [[2 1 0 1 1 1 1 0 0 0]]
- See also
- --------
- scipy.sparse.csr_matrix
- scipy.sparse.csr_matrix.toarray
- """
- if self._mat_u is not None:
- return self._mat_u
- if store_array:
- self._store_array()
- return self._mat_u
- # Matrix on demand
- else:
- return self._sparse_mat_u.toarray()
- def _store_array(self):
- """
- Stores the matrix with counted time points in memory.
- """
- if self._mat_u is None:
- self._mat_u = self.to_sparse_array().toarray()
- def remove_stored_array(self):
- """
- Removes the matrix with counted time points from memory.
- """
- if self._mat_u is not None:
- del self._mat_u
- self._mat_u = None
- def _convert_to_binned(self, spiketrains):
- """
- Converts neo.core.SpikeTrain objects to a sparse matrix
- (`scipy.sparse.csr_matrix`), which contains the binned times.
- Parameters
- ----------
- spiketrains : neo.SpikeTrain object or list of SpikeTrain objects
- The binned time array :attr:`spike_indices` is calculated from a
- SpikeTrain object or from a list of SpikeTrain objects.
- """
- from distutils.version import StrictVersion
- # column
- filled = []
- # row
- indices = []
- # data
- counts = []
- # to be downwards compatible compare numpy versions, if the used
- # version is smaller than v1.9 use different functions
- smaller_version = StrictVersion(np.__version__) < '1.9.0'
- for idx, elem in enumerate(spiketrains):
- ev = elem.view(pq.Quantity)
- scale = np.array(((ev - self.t_start).rescale(
- self.binsize.units) / self.binsize).magnitude, dtype=int)
- l = np.logical_and(ev >= self.t_start.rescale(self.binsize.units),
- ev <= self.t_stop.rescale(self.binsize.units))
- filled_tmp = scale[l]
- filled_tmp = filled_tmp[filled_tmp < self.num_bins]
- if smaller_version:
- f = np.unique(filled_tmp)
- c = np.bincount(f.searchsorted(filled_tmp))
- else:
- f, c = np.unique(filled_tmp, return_counts=True)
- filled.extend(f)
- counts.extend(c)
- indices.extend([idx] * len(f))
- csr_matrix = sps.csr_matrix((counts, (indices, filled)),
- shape=(self.matrix_rows,
- self.matrix_columns),
- dtype=int)
- self._sparse_mat_u = csr_matrix
|