-
Notifications
You must be signed in to change notification settings - Fork 1
/
TimeSeries.py
145 lines (113 loc) · 4.94 KB
/
TimeSeries.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
import numpy,pylab
import ctypes as C
from Header import Header
from SigPyProcUtils import File,Buffer
lib = C.CDLL("libSigPyProc.so")
class TimeSeries(Header):
"""Class to handle time series data.
Parameters
----------
\tparentInfo -- Dictionary containing header info or 32bit .tim file
\tmallocBuffer -- SigPyProcUtils.Buffer instance containing time series
Methods
-------
\tfold -- Fold a time series
\trFFt -- Perform forward real to complex 1-d DFT (uses fftw3)
\trunningMean -- Remove any inherent baseline in the data
\ttoPrestoFormat -- Write time series into presto compatible format (with inf file)
"""
def __init__(self,parentInfo,mallocBuffer=None):
"""Construct time series object from buffer or file.
Args:
parentInfo -- may be a file name or a dict instance containing
header information
mallocBuffer -- a SigPyProcUtils Buffer instance.
If parentInfo is a file, this argument
is ignored
"""
Header.__init__(self,parentInfo)
if isinstance(parentInfo,dict) and not mallocBuffer == None:
self.timBuffer = mallocBuffer
elif isinstance(parentInfo,str) and mallocBuffer == None:
self._readTim()
def _readTim(self):
"""Read time series from .tim file.
Currently only works with 32-bit time series.
Creates class attribute timBuffer.
"""
f = File(self.file,"r")
f.seek(self.hdrlen)
self.timBuffer = Buffer(self.info["nsamples"],C.c_float)
f.cread(self.timBuffer)
def fold(self,period,nbins=50,nints=1):
"""Fold time series into phase bins and subintegrations.
Args:
period -- period in seconds to fold with
nbins -- number of phase bins in output
nsubs -- number of subintegrations in output
Returns: FoldedData instance
"""
foldBuffer = Buffer(nbins*nints,C.c_double)
countBuffer = Buffer(nbins*nints,C.c_int)
lib.foldTim(self.timBuffer.Cbuffer,foldBuffer.Cbuffer,
countBuffer.Cbuffer,C.c_double(self.info["tsamp"]),
C.c_double(period),self.info["nsamples"],nbins,nints)
parentInfo = self.info.copy()
return FoldedData(parentInfo,foldBuffer,countBuffer,
period,self.info.get("refdm",0),
nbins,nints,1)
def rFFT(self):
"""Perform 1D real to complex forward FFT using fftw3.
Returns: SpectraFromBuffer instance
"""
if self.info["nsamples"]%2 ==0:
fftsize = self.info["nsamples"]
else:
fftsize = self.info["nsamples"]-1
fftBuffer = Buffer(fftsize+2,C.c_float)
lib.rfft(self.timBuffer.Cbuffer,fftBuffer.Cbuffer,fftsize)
return SpectraFromBuffer(self.info.copy(),fftBuffer)
def runningMean(self,window=10001):
"""Filter time series by a running mean.
Args:
window -- width in bins of running mean filter
"""
newTimBuffer = Buffer(self.info["nsamples"],C.c_float)
lib.runningMean(self.timBuffer.Cbuffer,newTimBuffer.Cbuffer,self.info["nsamples"],window)
return TimeSeries(self.info.copy(),newTimBuffer)
def downsample(self,factor):
newLen = self.info["nsamples"]//factor
newTimBuffer = Buffer(newLen,C.c_float)
lib.downsampleTim(self.timBuffer.Cbuffer,newTimBuffer.Cbuffer,factor,newLen)
self.modify_header('tsamp',self.info['tsamp']*factor)
parentInfo = self.info.copy()
self.reset_header()
return TimeSeries(parentInfo,newTimBuffer)
def toPrestoFormat(self,basename):
"""Write time series in presto .dat format.
"""
self.make_inf(outfile="%s.inf"%(basename))
datfile = File("%s.dat"%(basename),"w+")
self.timBuffer.Ndarray.tofile(datfile)
class MultiTimeSeries:
def __init__(self,files=None):
self.tims = {}
self.lags = {}
if isinstance(files,list):
for filename in files:
self.tims[filename] = TimeSeries(filename)
def append(self,TimeSeriesInst):
self.tims[TimeSeriesInst.info["filename"]] = TimeSeriesInst
def findLags(self,window=200):
keys = self.tims.keys()
reference = self.tims[keys[0]]
self.lags[keys[0]] = 0
for key in keys[1:]:
corr = numpy.correlate(reference.timBuffer.Cbuffer[window:-window],
self.tims[key].timBuffer.Cbuffer,mode="valid")
self.lags[key] = corr.argmax()-window
minlag = min(self.lags.values())
for key in keys:
self.lags[key] += abs(minlag)
from FoldedData import FoldedData
from Spectra import SpectraFromBuffer