From a1a7b411f1f054152cfb3e50623227ef10c718dc Mon Sep 17 00:00:00 2001 From: "J.A. de Jong - Redu-Sone B.V., ASCEE V.O.F" Date: Tue, 16 May 2023 12:12:36 +0200 Subject: [PATCH] Updates and bugfixes on fromnpy in Measurement --- src/lasp/lasp_measurement.py | 62 ++++++++++++++++++++++++++---------- 1 file changed, 46 insertions(+), 16 deletions(-) diff --git a/src/lasp/lasp_measurement.py b/src/lasp/lasp_measurement.py index cbe0d91..9f05a3b 100644 --- a/src/lasp/lasp_measurement.py +++ b/src/lasp/lasp_measurement.py @@ -1,5 +1,6 @@ #!/usr/bin/env python3 # -*- coding: utf-8 -*- +from __future__ import annotations """! Author: J.A. de Jong - ASCEE @@ -113,7 +114,7 @@ class IterRawData: nblocks = fa.shape[0] blocksize = fa.shape[1] self.blocksize = blocksize - nchannels = fa.shape[2] + # nchannels = fa.shape[2] self.channels = channels self.istart = kwargs.pop('istart', 0) @@ -143,7 +144,7 @@ class IterRawData: """Return the next block.""" fa = self.fa - nblocks_to_return = self.lastblock-self.firstblock+1 + # nblocks_to_return = self.lastblock-self.firstblock+1 block = self.firstblock + self.i @@ -162,7 +163,7 @@ class IterRawData: # print(f'block: {block}, starto: {start_offset}, stopo {stop_offset}') self.i += 1 - return self.fa[block, start_offset:stop_offset, :][:, self.channels] + return fa[block, start_offset:stop_offset, :][:, self.channels] class IterData(IterRawData): @@ -771,23 +772,32 @@ class Measurement: samplerate, sensitivity, mfn, - timestamp=None): - """Converts a numpy array to a LASP Measurement file, opens the - associated Measurement object and returns it. The measurement file will - have the same file name as the txt file, except with h5 extension. + timestamp=None, + qtys: List[SIQtys] = None, + channelNames: List[str] = None, + force=False) -> Measurement: + """ + Creates a LASP measurement file from input numpy array data. + Opens the associated Measurement object and returns it. Args: data: Numpy array, first column is sample, second is channel. Can - also be specified with a single column for single-channel data + also be specified with a single column for single-channel data. + samplerate: Sampling frequency in [Hz] - sensitivity: 1D array of channel sensitivities [Pa^-1] - mfn: Filepath where measurement file is stored. + + sensitivity: 1D array of channel sensitivities in [U^-1], where U is + the recorded unit. + + mfn: Filepath of the file where the data is stored. + timestamp: If given, a custom timestamp for the measurement - (integer containing seconds since epoch). If not given, the - timestamp is obtained from the last modification time. - delimiter: Column delimiter - firstcoltime: If true, the first column is the treated as the - sample time. + (integer containing seconds since epoch). + + qtys: If a list of physical quantity data is given here + + channelNames: Name of the channels + force: If True, overwrites existing files with specified `mfn` name. """ @@ -801,24 +811,44 @@ class Measurement: if data.ndim != 2: data = data[:, np.newaxis] + try: len(sensitivity) except: raise ValueError('Sensitivity should be given as array-like data type') sensitivity = np.asarray(sensitivity) - nchannels = data.shape[1] if nchannels != sensitivity.shape[0]: raise ValueError( f'Invalid sensitivity length given. Should be: {nchannels}') + if channelNames is not None: + if len(channelNames) != nchannels: + raise RuntimeError("Illegal length of channelNames list given") + + if qtys is None: + qtys = [SIQtys.AP]*nchannels + else: + if len(qtys) != nchannels: + raise RuntimeError("Illegal length of qtys list given") + + qtyvals = [qty.value for qty in qtys] + with h5.File(mfn, 'w') as hf: hf.attrs['samplerate'] = samplerate hf.attrs['sensitivity'] = sensitivity hf.attrs['time'] = timestamp hf.attrs['blocksize'] = 1 hf.attrs['nchannels'] = nchannels + + # Add physical quantity indices + hf.attrs['qtys_enum_idx'] = [qtyval.toInt() for qtyval in qtyvals] + + # Add channel names in case given + if channelNames is not None: + hf.attrs['channelNames'] = channelNames + ad = hf.create_dataset('audio', (1, data.shape[0], data.shape[1]), dtype=data.dtype, maxshape=(1, data.shape[0], data.shape[1]),