Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion doc/source/api_reference.rst
Original file line number Diff line number Diff line change
Expand Up @@ -6,4 +6,4 @@ API Reference
.. testsetup:: *

from neo import SpikeTrain
import quantities as pq
from neo import units as un
2 changes: 1 addition & 1 deletion doc/source/core.rst
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,7 @@ cut across the simple container hierarchy.
NumPy compatibility
===================

Neo data objects inherit from :py:class:`Quantity`, which in turn inherits from NumPy
Neo data objects inherit from :py:class:`Quantity` (by using units module), which in turn inherits from NumPy
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

revert - we should not import Quantity via the units module

:py:class:`ndarray`. This means that a Neo :py:class:`AnalogSignal` is also a :py:class:`Quantity`
and an array, giving you access to all of the methods available for those objects.

Expand Down
5 changes: 3 additions & 2 deletions doc/source/images/generate_diagram.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,8 @@
from datetime import datetime

import numpy as np
import quantities as pq
from neo import units as un

from matplotlib import pyplot
from matplotlib.patches import Rectangle, ArrowStyle, FancyArrowPatch
from matplotlib.font_manager import FontProperties
Expand Down Expand Up @@ -173,7 +174,7 @@ def generate_diagram(filename, rect_pos, rect_width, figsize):
else:
t1 = attrname

if attrtype == pq.Quantity:
if attrtype == un.Quantity:
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Use the units module only for importing units, not for the quantities.Quantity class. This should still be pq.Quantity

if attr[2] == 0:
t2 = 'Quantity scalar'
else:
Expand Down
7 changes: 4 additions & 3 deletions examples/generated_data.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,11 @@
from __future__ import division # Use same division in Python 2 and 3

import numpy as np
import quantities as pq

from matplotlib import pyplot as plt

import neo
from neo import units as un


def generate_block(n_segments=3, n_channels=8, n_units=3,
Expand Down Expand Up @@ -48,7 +49,7 @@ def generate_block(n_segments=3, n_channels=8, n_units=3,
sig = np.random.randn(data_samples)
sig[feature_pos:feature_pos + feature_samples] += wave

signal = neo.AnalogSignal(sig * pq.mV, sampling_rate=1 * pq.kHz)
signal = neo.AnalogSignal(sig * un.mV, sampling_rate=1 * un.kHz)
seg.analogsignals.append(signal)
rc.analogsignals.append(signal)

Expand All @@ -59,7 +60,7 @@ def generate_block(n_segments=3, n_channels=8, n_units=3,
feature_spikes = np.random.rand(5) * feature_len + feature_time
spikes = np.hstack([random_spikes, feature_spikes])

train = neo.SpikeTrain(spikes * pq.s, 1 * pq.s)
train = neo.SpikeTrain(spikes * un.s, 1 * un.s)
seg.spiketrains.append(train)
u.spiketrains.append(train)

Expand Down
8 changes: 5 additions & 3 deletions examples/simple_plot_with_matplotlib.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,12 @@
import urllib

import numpy as np
import quantities as pq

from matplotlib import pyplot

import neo
from neo import units as un


url = 'https://portal.g-node.org/neo/'
# distantfile = url + 'neuroexplorer/File_neuroexplorer_2.nex'
Expand All @@ -33,8 +35,8 @@
ax1 = fig.add_subplot(2, 1, 1)
ax2 = fig.add_subplot(2, 1, 2)
ax1.set_title(seg.file_origin)
mint = 0 * pq.s
maxt = np.inf * pq.s
mint = 0 * un.s
maxt = np.inf * un.s
for i, asig in enumerate(seg.analogsignals):
times = asig.times.rescale('s').magnitude
asig = asig.rescale('mV').magnitude
Expand Down
39 changes: 20 additions & 19 deletions neo/core/analogsignal.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,11 +22,12 @@
import logging

import numpy as np
import quantities as pq

from neo.core.baseneo import BaseNeo, MergeError, merge_annotations
from neo.core.channelindex import ChannelIndex

from neo import units as un

logger = logging.getLogger("Neo")


Expand All @@ -49,7 +50,7 @@ def _get_sampling_rate(sampling_rate, sampling_period):


def _new_AnalogSignalArray(cls, signal, units=None, dtype=None, copy=True,
t_start=0*pq.s, sampling_rate=None,
t_start=0*un.s, sampling_rate=None,
sampling_period=None, name=None, file_origin=None,
description=None,
annotations=None):
Expand All @@ -64,7 +65,7 @@ def _new_AnalogSignalArray(cls, signal, units=None, dtype=None, copy=True,
**annotations)


class AnalogSignal(BaseNeo, pq.Quantity):
class AnalogSignal(BaseNeo, un.Quantity):
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

should stay as pq.Quantity

'''
Array of one or more continuous analog signals.

Expand All @@ -79,10 +80,10 @@ class AnalogSignal(BaseNeo, pq.Quantity):
*Usage*::

>>> from neo.core import AnalogSignal
>>> import quantities as pq

>>>
>>> sigarr = AnalogSignal([[1, 2, 3], [4, 5, 6]], units='V',
... sampling_rate=1*pq.Hz)
... sampling_rate=1*un.Hz)
>>>
>>> sigarr
<AnalogSignal(array([[1, 2, 3],
Expand Down Expand Up @@ -148,13 +149,13 @@ class AnalogSignal(BaseNeo, pq.Quantity):

_single_parent_objects = ('Segment', 'ChannelIndex')
_quantity_attr = 'signal'
_necessary_attrs = (('signal', pq.Quantity, 2),
('sampling_rate', pq.Quantity, 0),
('t_start', pq.Quantity, 0))
_necessary_attrs = (('signal', un.Quantity, 2),
('sampling_rate', un.Quantity, 0),
('t_start', un.Quantity, 0))
_recommended_attrs = BaseNeo._recommended_attrs

def __new__(cls, signal, units=None, dtype=None, copy=True,
t_start=0 * pq.s, sampling_rate=None, sampling_period=None,
t_start=0 * un.s, sampling_rate=None, sampling_period=None,
name=None, file_origin=None, description=None,
**annotations):
'''
Expand All @@ -168,12 +169,12 @@ def __new__(cls, signal, units=None, dtype=None, copy=True,
if units is None:
if not hasattr(signal, "units"):
raise ValueError("Units must be specified")
elif isinstance(signal, pq.Quantity):
elif isinstance(signal, un.Quantity):
# could improve this test, what if units is a string?
if units != signal.units:
signal = signal.rescale(units)

obj = pq.Quantity(signal, units=units, dtype=dtype, copy=copy).view(cls)
obj = un.Quantity(signal, units=units, dtype=dtype, copy=copy).view(cls)

if obj.ndim == 1:
obj.shape = (-1, 1)
Expand All @@ -189,7 +190,7 @@ def __new__(cls, signal, units=None, dtype=None, copy=True,
return obj

def __init__(self, signal, units=None, dtype=None, copy=True,
t_start=0 * pq.s, sampling_rate=None, sampling_period=None,
t_start=0 * un.s, sampling_rate=None, sampling_period=None,
name=None, file_origin=None, description=None,
**annotations):
'''
Expand Down Expand Up @@ -235,7 +236,7 @@ def __array_finalize__(self, obj):
copied over here.
'''
super(AnalogSignal, self).__array_finalize__(obj)
self._t_start = getattr(obj, '_t_start', 0 * pq.s)
self._t_start = getattr(obj, '_t_start', 0 * un.s)
self._sampling_rate = getattr(obj, '_sampling_rate', None)

# The additional arguments
Expand Down Expand Up @@ -281,11 +282,11 @@ def __getitem__(self, i):
'''
obj = super(AnalogSignal, self).__getitem__(i)
if isinstance(i, int): # a single point in time across all channels
obj = pq.Quantity(obj.magnitude, units=obj.units)
obj = un.Quantity(obj.magnitude, units=obj.units)
elif isinstance(i, tuple):
j, k = i
if isinstance(j, int): # extract a quantity array
obj = pq.Quantity(obj.magnitude, units=obj.units)
obj = un.Quantity(obj.magnitude, units=obj.units)
else:
if isinstance(j, slice):
if j.start:
Expand Down Expand Up @@ -413,15 +414,15 @@ def rescale(self, units):
Return a copy of the AnalogSignal converted to the specified
units
'''
to_dims = pq.quantity.validate_dimensionality(units)
to_dims = un.quantity.validate_dimensionality(units)
if self.dimensionality == to_dims:
to_u = self.units
signal = np.array(self)
else:
to_u = pq.Quantity(1.0, to_dims)
from_u = pq.Quantity(1.0, self.dimensionality)
to_u = un.Quantity(1.0, to_dims)
from_u = un.Quantity(1.0, self.dimensionality)
try:
cf = pq.quantity.get_conversion_factor(from_u, to_u)
cf = un.quantity.get_conversion_factor(from_u, to_u)
except AssertionError:
raise ValueError('Unable to convert between units of "%s" \
and "%s"' % (from_u._dimensionality,
Expand Down
2 changes: 1 addition & 1 deletion neo/core/block.py
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ class Block(Container):

>>> from neo.core import (Block, Segment, ChannelIndex,
... AnalogSignal)
>>> from quantities import nA, kHz
>>> from neo.units import nA, kHz
>>> import numpy as np
>>>
>>> # create a Block with 3 Segment and 2 ChannelIndex objects
Expand Down
6 changes: 3 additions & 3 deletions neo/core/channelindex.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
from __future__ import absolute_import, division, print_function

import numpy as np
import quantities as pq
from neo import units as un

from neo.core.container import Container

Expand All @@ -32,7 +32,7 @@ class ChannelIndex(Container):

>>> from neo.core import (Block, Segment, ChannelIndex,
... AnalogSignal)
>>> from quantities import nA, kHz
>>> from neo.units import nA, kHz
>>> import numpy as np
>>>
>>> # create a Block with 3 Segment and 2 ChannelIndex objects
Expand Down Expand Up @@ -120,7 +120,7 @@ class ChannelIndex(Container):
_necessary_attrs = (('index', np.ndarray, 1, np.dtype('i')),)
_recommended_attrs = ((('channel_names', np.ndarray, 1, np.dtype('S')),
('channel_ids', np.ndarray, 1, np.dtype('i')),
('coordinates', pq.Quantity, 2)) +
('coordinates', un.Quantity, 2)) +
Container._recommended_attrs)

def __init__(self, index, channel_names=None, channel_ids=None,
Expand Down
24 changes: 13 additions & 11 deletions neo/core/epoch.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,10 +12,12 @@
import sys

import numpy as np
import quantities as pq


from neo.core.baseneo import BaseNeo, merge_annotations

from neo import units as un

PY_VER = sys.version_info[0]

def _new_epoch(cls, times=None, durations=None, labels=None, units=None,
Expand All @@ -27,14 +29,14 @@ def _new_epoch(cls, times=None, durations=None, labels=None, units=None,
return Epoch( times=times, durations=durations, labels=labels, units=units, name=name, file_origin=file_origin,
description=description, **annotations)

class Epoch(BaseNeo, pq.Quantity):
class Epoch(BaseNeo, un.Quantity):
'''
Array of epochs.

*Usage*::

>>> from neo.core import Epoch
>>> from quantities import s, ms
>>> from neo.units import s, ms
>>> import numpy as np
>>>
>>> epc = Epoch(times=np.arange(0, 30, 10)*s,
Expand Down Expand Up @@ -67,16 +69,16 @@ class Epoch(BaseNeo, pq.Quantity):

_single_parent_objects = ('Segment',)
_quantity_attr = 'times'
_necessary_attrs = (('times', pq.Quantity, 1),
('durations', pq.Quantity, 1),
_necessary_attrs = (('times', un.Quantity, 1),
('durations', un.Quantity, 1),
('labels', np.ndarray, 1, np.dtype('S')))

def __new__(cls, times=None, durations=None, labels=None, units=None,
name=None, description=None, file_origin=None, **annotations):
if times is None:
times = np.array([]) * pq.s
times = np.array([]) * un.s
if durations is None:
durations = np.array([]) * pq.s
durations = np.array([]) * un.s
if labels is None:
labels = np.array([], dtype='S')
if units is None:
Expand All @@ -90,16 +92,16 @@ def __new__(cls, times=None, durations=None, labels=None, units=None,
if hasattr(units, 'dimensionality'):
dim = units.dimensionality
else:
dim = pq.quantity.validate_dimensionality(units)
dim = un.quantity.validate_dimensionality(units)
# check to make sure the units are time
# this approach is much faster than comparing the
# reference dimensionality
if (len(dim) != 1 or list(dim.values())[0] != 1 or
not isinstance(list(dim.keys())[0], pq.UnitTime)):
not isinstance(list(dim.keys())[0], un.UnitTime)):
ValueError("Unit %s has dimensions %s, not [time]" %
(units, dim.simplified))

obj = pq.Quantity.__new__(cls, times, units=dim)
obj = un.Quantity.__new__(cls, times, units=dim)
obj.durations = durations
obj.labels = labels
obj.segment = None
Expand Down Expand Up @@ -147,7 +149,7 @@ def __repr__(self):

@property
def times(self):
return pq.Quantity(self)
return un.Quantity(self)

def merge(self, other):
'''
Expand Down
Loading