199 lines
5.3 KiB
Python
199 lines
5.3 KiB
Python
import sys
|
|
sys.dont_write_bytecode = True
|
|
import datetime
|
|
|
|
from adcptool.vector import Vector
|
|
|
|
|
|
#
|
|
# some 'constant' values that might be needed
|
|
bad_velocity = -32768
|
|
bad_discharge = 2147483647
|
|
bad_latlong = 30000
|
|
|
|
#
|
|
# handy functions
|
|
|
|
def line_as_list(f):
|
|
''' returns a list from the next line of the given file object '''
|
|
return f.pop(0).rstrip('\n').split()
|
|
|
|
|
|
def readnextline(f):
|
|
|
|
pass
|
|
|
|
|
|
|
|
def print_type(o):
|
|
print(type(o).__name__)
|
|
|
|
|
|
|
|
|
|
class RawProfileObj:
|
|
'''holds general data and all the ensembles'''
|
|
|
|
def __init__(self, filename):
|
|
self.ensembles = []
|
|
|
|
# python 3.x vs 2.x
|
|
try:
|
|
self.f = open(filename,'rt', encoding='latin-1').read().split('\n')
|
|
except TypeError:
|
|
self.f = open(filename,'rt').read().split('\n')
|
|
|
|
|
|
#
|
|
# general header stuff
|
|
|
|
# read something to get warm with python
|
|
self.note1 = self.f.pop(0)
|
|
self.note2 = self.f.pop(0)
|
|
|
|
l = line_as_list(self.f)
|
|
self.depth_cell_length = float(l[0])
|
|
self.number_of_depth_cells = l[3]
|
|
|
|
|
|
#
|
|
# add the ensembles
|
|
i = 0
|
|
while True:
|
|
#print('adding ensemble no',i)
|
|
self.ensembles.append(EnsembleObj(self.f, self.note1))
|
|
self.f = self.ensembles[i].f
|
|
|
|
if len(self.f) <= 1:
|
|
del self.f
|
|
break;
|
|
i += 1
|
|
|
|
|
|
def __getstate__(self):
|
|
# Copy the object's state from self.__dict__ which contains
|
|
# all our instance attributes. Always use the dict.copy()
|
|
# method to avoid modifying the original state.
|
|
state = self.__dict__.copy()
|
|
# Remove the unpickabel entries.
|
|
#del state['f']
|
|
return state
|
|
|
|
|
|
class EnsembleObj:
|
|
'''
|
|
holds an ensemble (set of different measurements on the same
|
|
(river surface) position
|
|
'''
|
|
def __init__(self, f, note1):
|
|
|
|
self.f = f
|
|
self.cells = []
|
|
|
|
#
|
|
# ensemble header stuff
|
|
|
|
|
|
firstline = self.f.pop(0)
|
|
|
|
# test if this line is actually what we want
|
|
if firstline == note1 or len(firstline) == 0:
|
|
exit('error: it looks like there are multiple transsects (profiles) in one ASCII file! (or there is an empty line in it which should never happen)')
|
|
|
|
else:
|
|
l = firstline.rstrip('\n').split()
|
|
|
|
time = [int(i) for i in l[0:7]]
|
|
|
|
time[0] += 2000 # in the source, they start counting in year 2000
|
|
time[6] *= 10000 # 1/100 seconds to microseconds
|
|
|
|
# compile time to python time format
|
|
self.ens_time = datetime.datetime(time[0], time[1], time[2], time[3], time[4], time[5], time[6])
|
|
|
|
self.ens_number = int(l[7])
|
|
self.corrected_heading = float(l[12])
|
|
|
|
# line "2"
|
|
l = line_as_list(self.f)
|
|
|
|
self.depth_reading = [float(i) for i in l[8:12]]
|
|
|
|
# line "3"
|
|
l = line_as_list(self.f)
|
|
self.total_elapsed_distance = float(l[0])
|
|
self.total_elapsed_time = float(l[1])
|
|
self.total_distance_traveled_north = float(l[2])
|
|
self.total_distance_traveled_east = float(l[3])
|
|
self.total_distance_made_good = float(l[4])
|
|
|
|
|
|
# skip line "4"
|
|
l = line_as_list(self.f)
|
|
self.lat = float(l[0])
|
|
self.lon = float(l[1])
|
|
|
|
# skip line "5"
|
|
l = line_as_list(self.f)
|
|
|
|
|
|
# line "6"
|
|
l = line_as_list(self.f)
|
|
|
|
self.measurement_units = l[1] # the units only apply to the velocity apparently
|
|
self.number_of_cells = int(l[0])
|
|
self.number_of_good_cells = 0
|
|
|
|
|
|
|
|
#
|
|
# add the bins/cells
|
|
|
|
for i in range(self.number_of_cells):
|
|
i = len(self.cells)
|
|
|
|
self.cells.append(CellObj(self.f))
|
|
self.f = self.cells[i].f
|
|
|
|
|
|
if self.cells[i].cell_is_good:
|
|
self.number_of_good_cells += 1
|
|
else:
|
|
# remove broken cells again
|
|
self.cells.pop()
|
|
|
|
|
|
def __getstate__(self):
|
|
# Copy the object's state from self.__dict__ which contains
|
|
# all our instance attributes. Always use the dict.copy()
|
|
# method to avoid modifying the original state.
|
|
state = self.__dict__.copy()
|
|
# Remove the unpicklable entries.
|
|
#del state['f']
|
|
return state
|
|
|
|
|
|
class CellObj:
|
|
''' holds the actual measured data '''
|
|
def __init__(self, f):
|
|
self.f = f
|
|
l = line_as_list(self.f)
|
|
|
|
if float(l[1]) != -32768:
|
|
self.cell_is_good = True
|
|
self.depth = float(l[0])
|
|
self.velocity_magn = float(l[1])
|
|
self.velocity_dir = float(l[2])
|
|
self.velocity_comp = Vector([float(i) for i in l[3:6]])
|
|
self.velocity_error = float(l[6])
|
|
self.percent_good = float(l[11])
|
|
else:
|
|
self.cell_is_good = False
|
|
|
|
def __getstate__(self):
|
|
# allows the class to be pickled
|
|
state = self.__dict__.copy()
|
|
# Remove the unpicklable entries.
|
|
#del state['f']
|
|
return state
|
|
|