Skip to content

Commit 76520f6

Browse files
committed
implement dqt reader
1 parent 2c5ff7c commit 76520f6

5 files changed

Lines changed: 15701 additions & 18421 deletions

File tree

circStudio/io/agd/agd.py

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,6 @@
33
import os
44
import sqlite3
55
import warnings
6-
76
from ..base import Raw
87

98

circStudio/io/awd/awd.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -164,7 +164,7 @@ def __init__(
164164
period=period,
165165
frequency=pd.Timedelta(freq),
166166
activity=data.loc[:, 'Activity'],
167-
light=data.loc[:, 'Light'].to_frame(name='whitelight') if 'Light' in data.columns else None
167+
light=data.loc[:, 'Light'].to_frame(name='light') if 'Light' in data.columns else None
168168
)
169169

170170
@property

circStudio/io/dqt/__init__.py

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
from .dqt import DQT
2+
from .dqt import read_dqt
3+
4+
5+
__all__ = ["DQT", "read_dqt"]

circStudio/io/dqt/dqt.py

Lines changed: 171 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,171 @@
1+
import pandas as pd
2+
import os
3+
import warnings
4+
from ..base import Raw
5+
6+
7+
class DQT(Raw):
8+
r"""Raw object from .csv file recorded by Daqtometers (Daqtix, Germany)
9+
10+
Parameters
11+
----------
12+
input_fname: str
13+
Path to the Daqtometer file.
14+
header_size: int, optional
15+
Header size (i.e. number of lines) of the raw data file.
16+
Default is 15.
17+
start_time: datetime-like, optional
18+
Read data from this time.
19+
Default is None.
20+
period: str, optional
21+
Length of the read data.
22+
Cf. #timeseries-offset-aliases in
23+
<https://pandas.pydata.org/pandas-docs/stable/timeseries.html>.
24+
Default is None (i.e all the data).
25+
"""
26+
27+
def __init__(
28+
self,
29+
input_fname,
30+
header_size=15,
31+
start_time=None,
32+
period=None
33+
):
34+
35+
# get absolute file path
36+
input_fname = os.path.abspath(input_fname)
37+
38+
# extract header and data size
39+
with open(input_fname) as f:
40+
header = [next(f) for x in range(header_size)]
41+
42+
# extract information from the header
43+
freq = self._extract_dqt_freq(header)
44+
45+
if freq > self._extract_dqt_sample_freq(header):
46+
warnings.warn(
47+
"The store rate of the DQT data is greater than the sampling "
48+
"rate.\nData are thus aggregated with the following settigs:\n"
49+
" - Binning mode: {}".format(
50+
self._extract_dqt_bin_mode(header)
51+
),
52+
UserWarning
53+
)
54+
55+
data = pd.read_csv(
56+
input_fname,
57+
delimiter=',',
58+
skiprows=(header_size-1),
59+
header=None,
60+
names=['activity', 'light'],
61+
index_col=0,
62+
parse_dates=[0],
63+
infer_datetime_format=True,
64+
dtype=float,
65+
na_values='x'
66+
).asfreq(freq)
67+
68+
# Convert activity from string to float
69+
data['activity'] = data['activity'].astype(float)
70+
71+
if start_time is not None:
72+
start_time = pd.to_datetime(start_time)
73+
else:
74+
start_time = data.index[0]
75+
76+
if period is not None:
77+
period = pd.Timedelta(period)
78+
stop_time = start_time+period
79+
else:
80+
stop_time = data.index[-1]
81+
period = stop_time - start_time
82+
83+
data = data[start_time:stop_time]
84+
85+
# Light
86+
if 'light' in data.columns:
87+
index_light = data.loc[:, 'light']
88+
else:
89+
index_light = None
90+
91+
# call __init__ function of the base class
92+
super().__init__(
93+
df=data,
94+
fpath=input_fname,
95+
start_time=start_time,
96+
period=period,
97+
frequency=freq,
98+
activity=data['activity'],
99+
light=index_light.to_frame(name='light') if index_light is not None else None
100+
)
101+
102+
@property
103+
def white_light(self):
104+
r"""Value of the light intensity (lux)."""
105+
if self.light is None:
106+
return None
107+
else:
108+
return self.light.get_channel('whitelight')
109+
110+
@classmethod
111+
def _match_string(cls, header, match):
112+
matchings = [s for s in header if match in s]
113+
if len(matchings) == 0:
114+
print('No match found for the string: {}.'.format(match))
115+
return None
116+
if len(matchings) > 1:
117+
print('Found multiple matchings for the string: {}'.format(match))
118+
else:
119+
return matchings[0]
120+
121+
@classmethod
122+
def _extract_dqt_freq(cls, header):
123+
freqstr = cls._match_string(header=header, match='Store rate')
124+
return pd.Timedelta(int(freqstr.split(',')[1]), unit='s')
125+
126+
@classmethod
127+
def _extract_dqt_sample_freq(cls, header):
128+
freqstr = cls._match_string(header=header, match='Sample rate')
129+
return pd.Timedelta(int(freqstr.split(',')[1])/0.1, unit='s')
130+
131+
@classmethod
132+
def _extract_dqt_bin_mode(cls, header):
133+
modestr = cls._match_string(header=header, match='Binning mode')
134+
return modestr.split(',')[1]
135+
136+
137+
def read_dqt(
138+
input_fname,
139+
header_size=15,
140+
start_time=None,
141+
period=None
142+
):
143+
r"""Raw object from .csv file recorded by Daqtometers (Daqtix, Germany)
144+
145+
Parameters
146+
----------
147+
input_fname: str
148+
Path to the DQT file.
149+
header_size: int
150+
Header size (i.e. number of lines) of the raw data file. Default is 15.
151+
start_time: datetime-like, optional
152+
Read data from this time.
153+
Default is None.
154+
period: str, optional
155+
Length of the read data.
156+
Cf. #timeseries-offset-aliases in
157+
<https://pandas.pydata.org/pandas-docs/stable/timeseries.html>.
158+
Default is None (i.e all the data).
159+
160+
Returns
161+
-------
162+
raw : Instance of RawDQT
163+
An object containing raw DQT data
164+
"""
165+
166+
return DQT(
167+
input_fname=input_fname,
168+
header_size=header_size,
169+
start_time=start_time,
170+
period=period
171+
)

0 commit comments

Comments
 (0)