41
41
# X is the long axis
42
42
# Y is the across-the-device axis
43
43
# Z is across the thickness of the device
44
- import numpy as np
45
- import argparse
46
- import sys
44
+
45
+ from Row import Row
47
46
from tkinter import filedialog
48
- import tkinter as tk
47
+ import argparse
49
48
import csv
50
- from Row import Row
49
+ import matplotlib .dates as mdate
50
+ import matplotlib .pyplot as plt
51
+ import numpy as np
51
52
import os
53
+ import sys
54
+ import tkinter as tk
52
55
53
56
class Processor :
54
57
@@ -57,22 +60,61 @@ def makeOutFile(self, filename, threshold):
57
60
path , file = os .path .split (filename )
58
61
name , ext = os .path .splitext (file )
59
62
newName = "wearing_" + str (threshold ) + "_" + name ;
60
-
63
+
61
64
newPlotName = newName + ".pdf"
62
65
newName = newName + ".csv"
63
-
64
- plotFilePath = os .path .join (path , newName )
65
- dataFilePath = os .path .join (path , newPlotName )
66
+
67
+ plotFilePath = os .path .join (path , newPlotName )
68
+ dataFilePath = os .path .join (path , newName )
66
69
print ("Plot file is" , plotFilePath )
67
70
print ("Output file is" , dataFilePath )
68
71
return [plotFilePath , dataFilePath ]
69
72
70
73
def _plot (self , plotFilename ,
74
+ threshold ,
75
+ epochTimestamps ,
71
76
maxAccPerSecond ,
72
77
aboveThresholdValues ,
73
- movementDetected ):
74
- pass
75
-
78
+ inUse ):
79
+ """ Generate the plot """
80
+
81
+ # Index 0 of data is epoch time
82
+ seconds = mdate .epoch2num (epochTimestamps )
83
+ print (seconds )
84
+ dateFormat = "%H:%M"
85
+ dateFormatter = mdate .DateFormatter (dateFormat )
86
+ locator = mdate .HourLocator (interval = 6 )
87
+ locator .MAXTICKS = 5000
88
+
89
+ fig , axis = plt .subplots (3 )
90
+
91
+ for index in range (3 ):
92
+ axis [index ].grid (True )
93
+ axis [index ].xaxis .set_major_locator (locator )
94
+ axis [index ].xaxis .set_minor_locator (mdate .HourLocator ())
95
+ axis [index ].xaxis .set_major_formatter (dateFormatter )
96
+ axis [index ].set_xlabel ("Time" )
97
+
98
+ axis [0 ].set_title (f"Threshold for total acc = { threshold } g" )
99
+ axis [0 ].set_ylabel ("Acceleration (g)" )
100
+ axis [0 ].plot (seconds , maxAccPerSecond , label = "max total acc" )
101
+
102
+ axis [1 ].set_yticks ([0 ,1 ])
103
+ axis [1 ].set_yticklabels (["false" ,"true" ])
104
+ axis [1 ].set_ylabel ("Above threshold" )
105
+ axis [1 ].plot (seconds , aboveThresholdValues , label = "above threshold" )
106
+
107
+ axis [2 ].set_yticks ([0 ,1 ])
108
+ axis [2 ].set_yticklabels (["false" ,"true" ])
109
+ axis [2 ].set_ylabel ("Above threshold" )
110
+ axis [2 ].plot (seconds , inUse , label = "in use" )
111
+
112
+ plt .legend ()
113
+ plt .savefig (plotFilename )
114
+ plt .draw ()
115
+ plt .close ()
116
+
117
+
76
118
def __call__ (self , filename , threshold ):
77
119
""" Process the file """
78
120
# Count number of seconds in the file
@@ -88,11 +130,13 @@ def __call__(self, filename, threshold):
88
130
elif firstEpoch is None :
89
131
firstEpoch = row .getEpoch ()
90
132
line = self .fh .readline ().strip ()
91
-
133
+
92
134
lastEpoch = row .getEpoch ()
93
135
secondsInFile = int (lastEpoch ) - int (firstEpoch ) + 1
94
- print (f"File contains { secondsInFile } seconds worth of data" )
95
-
136
+ days = round (secondsInFile / 86400 , 1 )
137
+ print (f"File contains { days } days ({ secondsInFile } seconds) worth of data" )
138
+
139
+ epochTimestamps = np .zeros (secondsInFile )
96
140
maxAccPerSecond = np .zeros (secondsInFile )
97
141
firstSecondEpoch = int (firstEpoch )
98
142
@@ -106,12 +150,13 @@ def __call__(self, filename, threshold):
106
150
pass
107
151
else :
108
152
second = int (row .getEpoch ()) - firstSecondEpoch
153
+ epochTimestamps [second ] = int (row .getEpoch ())
109
154
totalAcc = row .getTotAcc ()
110
155
if totalAcc > maxAccPerSecond [second ]:
111
156
maxAccPerSecond [second ] = totalAcc
112
157
line = self .fh .readline ().strip ()
113
158
print (f"Max per second accelerations extracted" )
114
- aboveThresholdValues = maxAccPerSecond
159
+ aboveThresholdValues = np . copy ( maxAccPerSecond )
115
160
# Now scan through looking for movement above a threshold
116
161
for second in range (len (aboveThresholdValues )):
117
162
if aboveThresholdValues [second ] < threshold :
@@ -120,54 +165,57 @@ def __call__(self, filename, threshold):
120
165
print (f"Determining periods of movement" )
121
166
# Scan through the above threshold values to set +/-5 minutes to
122
167
# 1 when there is an above threshold value
123
- movementDetected = np .zeros (secondsInFile )
168
+ inUse = np .zeros (secondsInFile )
124
169
for second in range (len (aboveThresholdValues )):
125
170
if aboveThresholdValues [second ] > 0 :
126
171
# Set the previous 5 * 60 values, less one, to 1
127
172
backIndex = second - ((4 * 60 ) + 59 )
128
173
for index in range (backIndex , second ):
129
- movementDetected [index ] = 1
174
+ inUse [index ] = 1
130
175
# Set the next 5 * 60 values to 1
131
176
for index in range (second , second + (5 * 60 )):
132
177
aboveThresholdValues [second ] = 1
133
178
134
179
plotFilename , outputFilename = self .makeOutFile (filename , threshold )
135
180
self ._plot (plotFilename ,
181
+ threshold ,
182
+ epochTimestamps ,
136
183
maxAccPerSecond ,
137
184
aboveThresholdValues ,
138
- movementDetected )
139
-
185
+ inUse )
186
+
140
187
# Output this as a data file
141
188
outfile = open (outputFilename , "w" )
142
189
with outfile :
143
190
writer = csv .writer (outfile )
144
191
for second in range (len (aboveThresholdValues )):
145
192
writer .writerow ([int (firstEpoch ) + second ,
146
193
second ,
147
- maxAccPerSecond [second ],
194
+ round ( maxAccPerSecond [second ], 6 ) ,
148
195
aboveThresholdValues [second ],
149
- movementDetected [second ]])
196
+ inUse [second ]])
197
+
150
198
return [plotFilename , outputFilename ]
151
-
199
+
152
200
def main ():
153
201
""" Command line entry point
154
202
"""
155
203
parser = argparse .ArgumentParser (description =
156
204
"Descriptive statistics for accelerometer file" )
157
205
parser .add_argument ("filename" , help = "Input filename" )
158
- parser .add_argument ("threshold" , help = "Threshold" ,
159
- type = float , default = "0. 1" )
206
+ parser .add_argument ("threshold" , help = "Threshold" , nargs = "?" ,
207
+ type = float , default = "1" )
160
208
args = parser .parse_args ()
161
209
filePath = args .filename
162
210
name , extension = os .path .splitext (filePath )
163
211
164
212
if extension == ".CWA" :
165
213
print ("You need the .csv, not the .CWA" , file = stderr )
166
214
os .exit (0 )
167
-
215
+
168
216
processor = Processor ()
169
217
plotfile , datafile = processor (args .filename , args .threshold )
170
-
218
+
171
219
if __name__ == "__main__" :
172
220
main ()
173
221
0 commit comments