Skip to content

Can't subtract scalar from TimeSeries with unit

On python 2.6 and astropy 1.0.4 the spectrum/transfer_function.py example fails due to a problem detrending by subtracting the mean:

>>> execfile("spectrum/transfer_function.py")
/home/duncan.macleod/.local/lib/python2.6/site-packages/matplotlib/__init__.py:872: UserWarning: axes.color_cycle is deprecated and replaced with axes.prop_cycle; please use the latter.
  warnings.warn(self.msg_depr % (key, alt_key))
Attempting to access data from frames...
Determined best frametype as 'L1_R'
Reading data from L1_R frames... Done
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "spectrum/transfer_function.py", line 55, in <module>
    gndfft = gnd.average_fft(100, 50, window='hamming')
  File "/mnt/home2/duncan.macleod/.local/lib/python2.6/site-packages/gwpy-0.1b3.dev-py2.6.egg/gwpy/timeseries/timeseries.py", line 218, in average_fft
    stepseries -= stepseries.value.mean()
  File "/mnt/home2/duncan.macleod/.local/lib/python2.6/site-packages/gwpy-0.1b3.dev-py2.6.egg/gwpy/data/array.py", line 145, in __array_prepare__
    return super(Array, self).__array_prepare__(obj, context=context)
  File "/home/duncan.macleod/.local/lib/python2.6/site-packages/astropy/units/quantity.py", line 317, in __array_prepare__
    .format(function.__name__))
astropy.units.core.UnitsError: Can only apply 'subtract' function to dimensionless quantities when other argument is not a quantity (unless the latter is all zero/infinity/nan)

The following patch is likely to fix the problem by doing everything in one go with a minor dtype change:

diff --git a/gwpy/timeseries/timeseries.py b/gwpy/timeseries/timeseries.py
index fd22760..2213014 100644
--- a/gwpy/timeseries/timeseries.py
+++ b/gwpy/timeseries/timeseries.py
@@ -197,6 +197,7 @@ class TimeSeries(TimeSeriesBase):
                 raise ValueError('window must be 1-D')
             elif win.shape[0] != nfft:
                 raise ValueError('Window is the wrong size.')
+        win = win.astype(self.dtype)
         scaling = 1. / numpy.absolute(win).mean()

         if nfft % 2:
@@ -213,11 +214,7 @@ class TimeSeries(TimeSeriesBase):
             idx_end = idx + nfft
             if idx_end > self.size:
                 continue
-            stepseries = self[idx:idx_end]
-            # detrend
-            stepseries -= stepseries.value.mean()
-            # window
-            stepseries *= win.astype(stepseries.dtype)
+            stepseries = self[idx:idx_end].detrend() * win
             # calculated FFT, weight, and stack
             fft_ = stepseries.fft(nfft=nfft) * scaling
             ffts.value[i, :] = fft_.value