2Contains class implementations to get file content of ODiSI generated data.
3Depending on the file extension the according file reader will be called.
4The FileHandler reads all data including metadata, tare, x-axis and strain.
6\author Anett Kielreiter
11from datetime
import datetime
12from collections.abc
import Generator
14from .
import filereader
19 File handler class to get measurement data from sensors.
20 Currently raw data and exported TSV files from
21 ODiSI 6100 series interrogators by Luna Inc LunaInnovations2020
22 are supported, see \cite LunaInnovations2020.
24 def __init__(self, filename: str, chunk_size: int = 1000):
26 Provides the handler for parsing measuring data files.
27 Different types of files are supported (atm *.dat and *.tsv )
28 \param filename Path to file to get measurement data.
29 \param chunk_size \copybrief chunk_size For more, see \ref chunk_size.
46 ext = os.path.splitext(filename)[1].lower()
52 raise ValueError(
"No valid file format")
58 Close the handle to the file and reset all function variables.
60 if self.
reader is not None:
71 start_time: datetime =
None,
72 end_time: datetime =
None,
74 ) -> tuple[list, dict]:
76 Reads all measurement files and returns the strain values, x_axis,
77 tare and timestamps filtered by given parameters.
78 The values are read in blocks to avoid memory issues.
79 The values will be split to gages/segments,
80 if segments_gages are given.
81 \param channel Selected channel of the file, defines the sensor.
82 \param start_time Read measurements from given timestamp.
83 \param end_time Read measurements till given timestamp.
84 \param segments_gages String or list of strings of gages/segments.
85 \return List of available timestamps.
86 \return Data of measurement (strain, xaxis, tare) as dict.
87 If no segment/gage selected, the dict contains ['All'] key.
91 if channel
is not None:
92 sensor = next((x
for x
in self.
sensors if x.channel == channel),
None)
97 if segments_gages
is not None and isinstance(segments_gages, str):
98 segments_gages = [segments_gages]
106 if segments_gages
is not None:
108 segments_gages, strain)
110 if 'All' not in meas_dict:
111 meas_dict[
'All'] = {}
112 if meas_dict[
'All'].get(
'x_axis',
None)
is None:
113 meas_dict[
'All'][
'strain'] = strain
114 meas_dict[
'All'][
'x_axis'] = sensor.x_axis
115 meas_dict[
'All'][
'tare'] = sensor.tare
117 meas_dict[
'All'][
'strain'].extend(strain)
118 timestamps.extend(times)
120 return timestamps, meas_dict
124 Generator to iterate over all .dat files of current measurement.
125 Reads all values of the file and separate it to the channels.
126 \return Dict with all measurement data (timestamps, strain) by channel.
128 if not self.
reader.measurement_files:
131 for dat_file
in self.
reader.measurement_files:
132 data_dict = self.
reader.read_dat_file(dat_file)
137 chunk_size: int =
None,
139 start_time: datetime =
None,
140 end_time: datetime =
None
141 ) -> Generator[list, list]:
143 Generator to iterate over the whole file
144 and yields data with size of chunk.
145 Returns lists of timestamps and strain values.
146 \param chunk_size Maximum number of lines to read in lists, see \ref chunk_size.
147 \param channel Selected channel of the file, defines the sensor.
148 \param start_time Read measurements from given timestamp.
149 \param end_time Read measurements till given timestamp.
150 \return List of available timestamps.
151 \return Strain data as list.
155 chunk_size = self.
chunk_size if chunk_size
is None else chunk_size
157 channel = self.
sensors[0].channel
160 for entry
in self.
reader.read_next_measurement(start_time=start_time,
163 timestamps.append(entry[0])
164 strain.append(entry[1])
166 if len(timestamps) >= chunk_size:
167 yield timestamps, strain
170 if len(timestamps) > 0:
171 yield timestamps, strain
176 chunk_size: int =
None,
178 start_time: datetime =
None,
179 end_time: datetime =
None
180 ) -> Generator[list, dict]:
182 Generator to iterate over a dictionary with all strain data,
183 x-axis and tare for the given segment or gage names of chunk_size.
184 Separately from it, it returns the timestamps of file.
185 \param segments_gages String or list of gage/segment name(s).
186 \param chunk_size Number of lines to be read in one chunk as int.
187 \param channel Selected channel of the file, defines the sensor.
188 \param start_time Read measurements from given timestamp.
189 \param end_time Read measurements till given timestamp.
190 \return timestamps List of available timestamps.
191 \return meas_dict Dict with all measurement data of segment/gage.
193 chunk_size = self.
chunk_size if chunk_size
is None else chunk_size
194 if channel
is not None:
195 sensor = next((x
for x
in self.
sensors if x.channel == channel),
201 if isinstance(segments_gages, str):
202 segments_gages = [segments_gages]
210 segments_gages, strain)
211 yield timestamps, meas_dict
221 Fill the meas_dict dictionary with all strain data, x-axis and tare
222 for the given segment or gage names.
223 \param meas_dict Dict with all measurement data of segment/gage.
224 \param sensor Sensor object with axis, tare, etc.
225 \param segments_gages String or list of gage/segment name(s).
226 \param strain Strain values as list of arrays.
228 for name
in segments_gages:
229 if name
not in meas_dict:
234 if meas_dict[name].get(
'x_axis',
None)
is None:
235 meas_dict[name][
'strain'] = ([i[start:end]
for i
in strain])
236 meas_dict[name][
'x_axis'] = sensor.x_axis[start:end]
237 meas_dict[name][
'tare'] = sensor.tare[start:end]
239 meas_dict[name][
'strain'].extend(
240 ([i[start:end]
for i
in strain]))
246 ) -> tuple[int, int]:
248 Get start and end index of gage/segment.
249 \param name Name of the segment/gage.
250 \param sensor Sensor object with axis, tare, etc.
251 \return start Start index of segment or index of gage.
252 \return end End index of segment or index+1 if gage.
254 if name
in sensor.gages:
255 target = sensor.gages
256 elif name
in sensor.segments:
257 target = sensor.segments
260 start = target[name][
'index']
262 if name
in sensor.segments:
263 end = start + target[name][
'length']
File handler class to get measurement data from sensors.
sensors
List of SensorInfo object available in file, contains all sensor specific infos (incl.
__init__(self, str filename, int chunk_size=1000)
Provides the handler for parsing measuring data files.
Generator[list, dict] yield_gages_segments_in_chunks(self, segments_gages, int chunk_size=None, int channel=None, datetime start_time=None, datetime end_time=None)
Generator to iterate over a dictionary with all strain data, x-axis and tare for the given segment or...
chunk_size
Size of chunks when reading multiple readings at once.
metadata
Dictionary, which stores metadata for each file imported.
tuple[list, dict] get_measurements(self, int channel=None, datetime start_time=None, datetime end_time=None, segments_gages=None)
_split_to_gages_segments(self, dict meas_dict, filereader.SensorInfo sensor, segments_gages, list strain)
Fill the meas_dict dictionary with all strain data, x-axis and tare for the given segment or gage nam...
Generator[list, list] yield_measurements_in_chunks(self, int chunk_size=None, int channel=None, datetime start_time=None, datetime end_time=None)
Generator to iterate over the whole file and yields data with size of chunk.
tuple[int, int] _get_range_of_segment_gage(self, str name, filereader.SensorInfo sensor)
Get start and end index of gage/segment.
Generator[dict] yield_dat_file_values(self)
Generator to iterate over all .dat files of current measurement.
close_file(self)
Close the handle to the file and reset all function variables.
reader
Holds the file reader for selected file.
File reader class for the .dat measurement files recorded by the ODiSI 6100 series interrogators by L...
Class to hold sensor specific data (name, serial number, ...).
File reader class for the .tsv measurement files exported by the ODiSI 6100 series interrogators by L...