AJMR-Python-Baird/Mustique/adcptool/data.py

215 lines
7.6 KiB
Python

import adcptool.adcpimport #@UnusedImport (actually used in the eval() parts)
import adcptool.outliers #@UnusedImport
class DataClass():
'''
a class to store and manage all the ADCP data in this tool.
automatic retrieval and updating included.
'''
def __init__(self, parent=0):
# method register (pretty unpythonic)
self.methreg = dict(
rawprofile='adcptool.adcpimport.RawProfileObj(self.cfg["rawprofile"])',
cellmatrix='adcptool.outliers.get_cell_matrix(self.rawprofile)',
valuematrix='adcptool.outliers.get_valuematrix_from_cellmatrix(self.cellmatrix, self.cfg["valuematrix"], 1)',
goodvaluematrix='adcptool.outliers.get_valuematrix_from_cellmatrix(self.cellmatrix, self.cfg["valuematrix"], 2)',
relatdev='adcptool.outliers.get_relative_deviation_simple(self.valuematrix, self.goodvaluematrix, self.cfg["relatdev"])',
outliermatrix='adcptool.outliers.get_outliers(self.relatdev, self.goodvaluematrix, self.cfg["outliermatrix"])'
)
self.depencies = {
'rawprofile':[],
'cellmatrix':['rawprofile'],
'valuematrix':['cellmatrix'],
'goodvaluematrix':['cellmatrix'],
'relatdev':['valuematrix', 'goodvaluematrix'],
'outliermatrix':['relatdev']
}
#
# populate dicts from methreg
self.data = dict(list(zip(list(self.methreg.keys()), [None] * len(self.methreg)))) # hold the actual data
self.cfg = dict(list(zip(list(self.methreg.keys()), [None] * len(self.methreg)))) # stores the public cfg
self.cfg_saved = dict(list(zip(list(self.methreg.keys()), [None] * len(self.methreg)))) # store private cfg (the one that has been used for creating data)
self.testa = dict(list(zip(list(self.methreg.keys()), [None] * len(self.methreg)))) # store private cfg (the one that has been used for creating data)
self.testb = dict(list(zip(list(self.methreg.keys()), [None] * len(self.methreg)))) # store private cfg (the one that has been used for creating data)
def __getattr__(self, m):
'''
this is called to retrieve an arbitrary attribute.
they have to be named like in the self.methreg in order to work
'''
# print '-----------------------------------'
# print('a:{}, b:{}'.format(self.testa['rawprofile'], self.testb['rawprofile']))
# self.testa['rawprofile'] = 'foobar'
# print '-----------------------------------'
# print('a:{}, b:{}'.format(self.testa['rawprofile'], self.testb['rawprofile']))
# print('DBG: DataClass(): {} * requested.'.format(m))
# print('DBG: DataClass(): OLD config:')
# self.print_cfg( self.cfg_saved[m])
# print('DBG: DataClass(): NEW config:')
# self.print_cfg( self.cfg[m])
# print '-----------------------------------'
if self.data[m] == None or self.cfg[m] != self.cfg_saved[m] or self.depcheck(m):
# if needed: create the data (again)
# print('DBG: DataClass(): {} + updating.'.format(m))
if type(self.cfg[m]) == type(dict()):
self.cfg_saved[m] = self.cfg[m].copy()
else:
self.cfg_saved[m] = self.cfg[m]
self.data[m] = eval(self.methreg[m])
# print m, type(self.data[m]), type(self.cfg[m]), type(self.cfg_saved[m])
return self.data[m]
def print_cfg(self, x):
'''
a debug function that prints out the config dictionary nicely
'''
print(x)
def depcheck(self, m):
'''
somehow make the dependency chekcing
'''
for dep in self.depencies[m]:
# print('depcheck: {}:{}'.format(m, dep))
if self.cfg[dep] != self.cfg_saved[dep]:
# print('depcheck: {}:{}: cfg has changed'.format(m, dep))
return True
else:
return self.depcheck(dep)
def get_guicfg(tk):
'''
return an empty dictionary that contains the structure
that hold the Tk/Variables. unfortunately this is not the
same structure as the "real data structure" which is based
on the method names in DataClass()
'''
guicfg = dict(
inputfile = tk.StringVar(),
outliers = dict(
enabled=tk.BooleanVar(),
radius_h=tk.IntVar(),
radius_v=tk.IntVar(),
limit=tk.StringVar()
)
)
return guicfg
def gui2cfg(guicfg, cfg, module=False):
'''
read field variables from the GUI and write it into cfg. depending on module,
it either writes all or only the specified module
'''
# if module:
# for key in guicfg[module].keys():
# if not hasattr(guicfg[module][key], 'get'):
# cfg[key] = guicfg[module][key]
# else:
# cfg[key] = guicfg[module][key].get()
cfg['rawprofile'] = guicfg['inputfile'].get()
cfg['relatdev']['radius_h'] = int(guicfg['outliers']['radius_h'].get())
cfg['relatdev']['radius_v'] = int(guicfg['outliers']['radius_v'].get())
cfg['relatdev']['enabled'] = bool(guicfg['outliers']['enabled'].get())
cfg['outliermatrix']['limit'] = float(guicfg['outliers']['limit'].get())
cfg['outliermatrix']['enabled'] = bool(guicfg['outliers']['enabled'].get())
return cfg
def cfg2gui(guicfg, cfg, module=False):
'''
write the data from the cfg dictionary to the GUI variables.
'''
# if module:
# for key in guicfg:
# print('module: {}, key: {}, value:{}'.format(module, key, cfg[module][key]))
# guicfg[module][key].set(cfg[module][key])
#ugly but works
guicfg['inputfile'].set(cfg['rawprofile'])
guicfg['outliers']['radius_h'].set(cfg['relatdev']['radius_h'])
guicfg['outliers']['radius_v'].set(cfg['relatdev']['radius_v'])
guicfg['outliers']['enabled'].set(cfg['relatdev']['enabled'])
guicfg['outliers']['limit'].set(cfg['outliermatrix']['limit'])
guicfg['outliers']['enabled'].set(cfg['outliermatrix']['enabled'])
return guicfg
def get_default_cfg():
'''
return a default config that can be used as suggestion to the user
and also provides settings that cannot be changed in the GUI
'''
cfg = dict(
rawprofile = '../testfiles/demodata.txt',
valuematrix = '.velocity_comp.v',
relatdev = dict(radius_h=5, radius_v=0, enabled=1),
outliermatrix = dict(limit=2.5, enabled=1),
goodvaluematrix = None,
cellmatrix = None,
outfolder = '../testfiles/'
)
return cfg
# -----------------------------------------------------------------------------
if __name__ == '__main__':
dc = DataClass()
dc.cfg = get_default_cfg()
print(dc.cfg)
rd = dc.relatdev
ol = dc.outliermatrix
print(dc.cfg_saved, '\n', dc.cfg)
print('#### updating #######################################################')
dc.cfg['relatdev']['radius_h'] = 7
print(dc.cfg_saved, '\n', dc.cfg)
ol = dc.relatdev