diff --git a/dolfyn/io/nortek.py b/dolfyn/io/nortek.py index 7e94db4a..a6420a29 100644 --- a/dolfyn/io/nortek.py +++ b/dolfyn/io/nortek.py @@ -163,8 +163,12 @@ class _NortekReader(): '0x10': 'read_vec_data', '0x11': 'read_vec_sysdata', '0x12': 'read_vec_hdr', - '0x71': 'read_microstrain', '0x20': 'read_awac_profile', + '0x30': 'read_awac_waves', + '0x31': 'read_awac_waves_hdr', + '0x36': 'read_awac_waves', + '0x42': 'read_awac_AST', + '0x71': 'read_microstrain', } def __init__(self, fname, endian=None, debug=False, @@ -1021,7 +1025,136 @@ def sci_awac_profile(self,): self.data['coords']['range'] = r self.data['attrs']['cell_size'] = cs self.data['attrs']['blank_dist'] = bd +<<<<<<< HEAD + +======= + + + def read_awac_waves_hdr(self,): + # ID: '0x31' + c = self.c + if self.debug: + print('Reading vector header data (0x31) ping #{} @ {}...' + .format(self.c, self.pos)) + hdrnow = {} + dat = self.data + ds = dat['sys'] + dv = dat['data_vars'] + if 'time' not in dat['coords']: + self._init_data(nortek_defs.awac_hdrdata) #!!! Write this + byts = self.read(56) + # The first two are size, the next 6 are time. + tmp = unpack(self.endian + '8xHB8H5B4H38x', byts) #!!! check format + dat['coords']['time'][c] = self.rd_time(byts[2:8]) + hdrnow['NRecords'] = tmp[0] + hdrnow['Blanking'] = tmp[1] # counts + ds['batt'][c] = tmp[2] #voltage (0.1 V) + dv['c_sound'][c] = tmp[3] # c (0.1 m/s) + dv['heading'][c] = tmp[4] # (0.1 deg) + dv['pitch'][c] = tmp[5] # (0.1 deg) + dv['roll'][c] = tmp[6] # (0.1 deg) + dv['P_min'][c] = tmp[7] # min pressure previous profile (0.001 dbar) + dv['P_max'][c] = tmp[8] # min pressure previous profile (0.001 dbar) + dv['temp'][c] = tmp[9] # (0.01 deg C) + hdrnow['CellSize'] = tmp[10] # (counts of T3) + hdrnow['Noise1'] = tmp[11] # noise amplitude beam 1 (counts) + hdrnow['Noise2'] = tmp[12] + hdrnow['Noise3'] = tmp[13] + hdrnow['Noise4'] = tmp[14] + hdrnow['ProcMagn1'] = tmp[15] # processing magnitude beam 1 + hdrnow['ProcMagn2'] = tmp[16] + hdrnow['ProcMagn3'] = tmp[17] + hdrnow['ProcMagn4'] = tmp[18] + hdrnow['Spare1'] = byts[42:].decode('utf-8') + self.checksum(byts) + if 'data_header' not in self.config: + self.config['data_header'] = hdrnow + else: + if not isinstance(self.config['data_header'], list): + self.config['data_header'] = [self.config['data_header']] + self.config['data_header'] += [hdrnow] + + + def read_awac_waves(self,): + """Read awac wave and suv data + """ + # IDs: 0x30 & 0x36 + c = self.c + dat = self.data + if self.debug: + print('Reading awac wave data (0x30) ping #{} @ {}...' + .format(self.c, self.pos)) + + if 'Dist1' not in dat['data_vars']: + self._init_data(nortek_defs.wave_data) #!!! Write this + self._dtypes += ['wave_data'] + byts = self.read(20) + # The first two are size + ds = dat['sys'] + dv = dat['data_vars'] + (dv['pressure'][c], # (0.001 dbar) + dv['dist1'][c], # distance 1 to surface, vertical beam (mm) + ds['AnaIn'][c], # analog input 1 + dv['vel'][0, c], # velocity beam 1 (mm/s) East for SUV + dv['vel'][1, c], # North for SUV + dv['vel'][2, c], # Up for SUV + dv['vel'][3, c], # distance 1 to surface, vertical beam (mm) or vel 4 for non-AST + dv['amp'][0, c], # amplitude beam 1 (counts) + dv['amp'][1, c], + dv['amp'][2, c], + # AST quality (counts) or amplitude beam 4 for non-AST + dv['amp'][3, c]) = unpack(self.endian + '3H4h4B', byts) #!!! check format + self.checksum(byts) + self.c += 1 + + + def read_awac_AST(self,): + """Read awac "stage" data - acoustic surface tracking (AST) data + """ + # ID: 0x42 + c = self.c + dat = self.data + if self.debug: + print('Reading awac stage data (0x42) ping #{} @ {}...' + .format(self.c, self.pos)) + + nbins = self.config['NBins'] + if 'AST1' not in dat['data_vars']: + self._init_data(nortek_defs.AST_data) #!!! Write this + self._dtypes += ['AST_data'] + + ds = dat['sys'] + dv = dat['data_vars'] + # There is a 'fill' byte at the end, if nbins is odd. + byts = self.read(30 + nbins + np.mod(nbins, 2)) + tmp = unpack(self.endian + 'x3Bx2HB2Hx3h2xB', byts) #!!! check format + # The first two are size + ds['Spare1'] = byts[0:2].decode('utf-8') # AST dist 1 duplicate + dv['amp'][0, c] = tmp[1] # amplitude beam 1 (counts) + dv['amp'][1, c] = tmp[2] + dv['amp'][2, c] = tmp[3] + ds['Spare2'] = byts[7:9].decode('utf-8') # AST quality duplicate + dv['pressure'][c] = tmp[5] # (0.001 dbar) + dv['AST'][0, c] = tmp[6] # AST1 (mm) + dv['AST_Q'][c] = tmp[7] # AST quality (counts) + dv['c_sound'][c] = tmp[8] # c (0.1 m/s) + dv['AST'][1, c] = tmp[9] # AST2 (mm) + ds['Spare3'] = byts[18:20].decode('utf-8') + dv['vel'][0, c] = tmp[11] # velocity beam 1 (mm/s) East for SUV + dv['vel'][1, c] = tmp[12] # North for SUV + dv['vel'][2, c] = tmp[13] # Up for SUV + ds['Spare4'] = byts[26:28].decode('utf-8') # AST dist 2 duplicate + ds['Spare5'] = byts[28].decode('utf-8') + dv['amp_b4'][0, c] = tmp[16] # amplitude cell 1 (counts) + # amplitude cells 2 through nbins - starts at byte 30 + tmp = unpack(self.endian + str(nbins) + 'B', byts[30:30+nbins-1]) + dv['amp_b4'][1:nbins-1, c] = tmp + + self.checksum(byts) + self.c += 1 + +>>>>>>> 383567050d2939192a53ae41a26d5d6b4adf8a15 def dat2sci(self,): for nm in self._dtypes: getattr(self, 'sci_' + nm)() diff --git a/dolfyn/io/nortek_defs.py b/dolfyn/io/nortek_defs.py index 2695af2a..74b40e5e 100644 --- a/dolfyn/io/nortek_defs.py +++ b/dolfyn/io/nortek_defs.py @@ -338,3 +338,148 @@ def sci_func(self, data): standard_name='signal_intensity_from_multibeam_acoustic_doppler_velocity_sensor_in_sea_water', ), } + +waves_hdrdata = { + 'time': _VarAtts(dims=[], + dtype=np.float64, + group='coords', + units='', + ), + 'batt': _VarAtts(dims=[], + dtype=np.uint16, + group='sys', + factor=0.1, + units='V', + ), + 'c_sound': _VarAtts(dims=[], + dtype=np.float32, + group='data_vars', + default_val=nan, + factor=0.1, + units='m/s', + ), + 'heading': _VarAtts(dims=[], + dtype=np.float32, + group='data_vars', + default_val=nan, + factor=0.1, + units='deg', + ), + 'pitch': _VarAtts(dims=[], + dtype=np.float32, + group='data_vars', + default_val=nan, + factor=0.1, + units='deg', + ), + 'roll': _VarAtts(dims=[], + dtype=np.float32, + group='data_vars', + default_val=nan, + factor=0.1, + units='deg', + ), + 'P_min': _VarAtts(dims=[], + dtype=np.float32, + group='data_vars', + default_val=nan, + factor=0.001, + units='dbar', + ), + 'P_max': _VarAtts(dims=[], + dtype=np.float32, + group='data_vars', + default_val=nan, + factor=0.001, + units='dbar', + ), + 'temp': _VarAtts(dims=[], + dtype=np.float32, + group='data_vars', + default_val=nan, + factor=0.01, + units='deg C', + ), +} + +waves_data = { + 'pressure': _VarAtts(dims=[], + dtype=np.float32, + group='data_vars', + default_val=nan, + factor=0.001, + units='dBar', + ), + 'dist1': _VarAtts(dims=[], + dtype=np.uint16, + group='data_vars', + factor=0.001, + units='m', + ), + 'AnaIn1': _VarAtts(dims=[], + dtype=np.float32, + group='sys', + default_val=nan, + units='n/a', + ), + 'vel': _VarAtts(dims=[4, 'n'], # how to change this for different # of beams? + dtype=np.float32, + group='data_vars', + default_val=nan, + factor=0.001, + units='m/s', + ), + 'amp': _VarAtts(dims=[4, 'n'], + dtype=np.uint8, + group='data_vars', + units='counts', + ), +} + +AST_data = { + 'amp': _VarAtts(dims=[3, 'n'], + dtype=np.uint8, + group='data_vars', + units='counts', + ), + 'amp_b4': _VarAtts(dims=[1, 'nbins', 'n'], + dtype=np.uint8, + group='data_vars', + units='counts', + ), + 'pressure': _VarAtts(dims=[], + dtype=np.float32, + group='data_vars', + default_val=nan, + factor=0.001, + units='dBar', + ), + 'AST': _VarAtts(dims=[2, 'n'], + dtype=np.float32, + group='data_vars', + default_val=nan, + factor=0.001, + units='m', + ), + 'AST_Q': _VarAtts(dims=[], + dtype=np.float32, + group='data_vars', + default_val=nan, + factor=0.001, + units='m', + ), + 'c_sound': _VarAtts(dims=[], + dtype=np.float32, + group='data_vars', + default_val=nan, + factor=0.1, + units='m/s', + ), + 'vel': _VarAtts(dims=[3, 'n'], + dtype=np.float32, + group='data_vars', + default_val=nan, + factor=0.001, + units='m/s', + ), +} \ No newline at end of file