Source code for ocmw.dataproc.processModelData

# -*- coding: utf-8 -*-
"""
Tools for post-processing Open Telemac-Mascaret model data extract to OCMW format.

Chris Old
IES, School of Engineering, University of Edinburgh
Sep 2023

"""

# ----------------------------------------------------------------------------
#   IMPORTS
# ----------------------------------------------------------------------------

# Standard Python Dependencies
import os
# Non-Standard Python Dependencies
import numpy as np
# Local Module Dependencies
from ocmw.core.fileTools import getListOfFiles, generateGlobalAttributes
from ocmw.core.flowChar import preprocess_ts
from .ocmw_extract import ocmwExtn
from .ocmw_extract import load_ocmw_file, save_ocmw_file
from .ocmw_extract import extract_ts_at_hub
from .ocmw_extract import extract_model_ts_at_surface
from .ocmw_extract import extract_depthavg_ts
from .ocmw_extract import extract_rotav_ts_at_hub
# Other Dependencies


# ----------------------------------------------------------------------------
#   GLOBAL VARIABLES
# ----------------------------------------------------------------------------


# ----------------------------------------------------------------------------
#   CLASS DEFINITIONS
# ----------------------------------------------------------------------------


# ----------------------------------------------------------------------------
#   FUNCTION DEFINITIONS
# ----------------------------------------------------------------------------
[docs] def locDataExists(datapath,filename): """ Determine whether a data file exists Parameters ---------- datapath : str Full path to the data file. filename : str Name of data file. Returns ------- dataExists : bool Flag indicating file existence. """ dataExists = False if os.path.isdir(datapath): if os.path.isfile(datapath+'/'+filename): dataExists = True return dataExists
[docs] def hub_height_data(modelpath,filename,datasrc,dataset,tec,outfile): """ Extract TEC hub-height data from a timeseries of model profiles extracted at a specific location. """ datapath = modelpath+'/EXTRACT' if locDataExists(datapath,filename): analpath = modelpath+'/ANALYSIS' if not os.path.isdir(analpath): os.mkdir(analpath) ofprts = outfile.split('.') hab = tec.bottomMounted zhub = tec.hubHeight rdia = tec.rotorDiam Cp = tec.Cp if hab: rstr = '_hab_' else: rstr = '_dbs_' model_ts = extract_ts_at_hub(datapath,filename,dataset,datasrc,zhub,hab=hab) ofile = ofprts[0]+rstr+str(np.int32(np.ceil(zhub))).zfill(2)+'m_TS.'+ofprts[1] save_ocmw_file(analpath,ofile,model_ts) model_data = preprocess_ts(model_ts,tec=tec) ofile = ofprts[0]+rstr+str(np.int32(np.ceil(zhub))).zfill(2)+'m_PP.'+ofprts[1] save_ocmw_file(analpath,ofile,model_data) pwra_data = extract_rotav_ts_at_hub(datapath,filename,dataset,datasrc,model_data,rdia,zhub,hab=True,pwra=True,Cp=Cp) ofile = ofprts[0]+rstr+str(np.int32(np.ceil(zhub))).zfill(2)+'m_PWRA.'+ofprts[1] save_ocmw_file(analpath,ofile,pwra_data) else: print('Warning: Location data not avialble in '+modelpath) model_ts = None model_data = None pwra_data = None return model_ts, model_data, pwra_data
[docs] def hab_data(modelpath,filename,datasrc,dataset,z,outfile): """ Extract data at a specified height-above-bed from a timeseries of model profiles extracted at a specific location. """ datapath = modelpath+'/EXTRACT' if locDataExists(datapath,filename): analpath = modelpath+'/ANALYSIS' if not os.path.isdir(analpath): os.mkdir(analpath) ofprts = outfile.split('.') rstr = '_hab_' model_ts = extract_ts_at_hub(datapath,filename,dataset,datasrc,z,hab=True) ofile = ofprts[0]+rstr+str(np.int32(np.ceil(z))).zfill(2)+'m_TS.'+ofprts[1] save_ocmw_file(analpath,ofile,model_ts) model_data = preprocess_ts(model_ts) ofile = ofprts[0]+rstr+str(np.int32(np.ceil(z))).zfill(2)+'m_PP.'+ofprts[1] save_ocmw_file(analpath,ofile,model_data) else: print('Warning: Location data not avialble in '+modelpath) model_ts = None model_data = None return model_ts, model_data
[docs] def dbs_data(modelpath,filename,datasrc,dataset,d,outfile): """ Extract data at a specified depth-below-surface from a timeseries of model profiles extracted at a specific location. """ datapath = modelpath+'/EXTRACT' if locDataExists(datapath,filename): analpath = modelpath+'/ANALYSIS' if not os.path.isdir(analpath): os.mkdir(analpath) ofprts = outfile.split('.') rstr = '_hab_' model_ts = extract_ts_at_hub(datapath,filename,dataset,datasrc,d,hab=False) ofile = ofprts[0]+rstr+str(np.int32(np.ceil(d))).zfill(2)+'m_TS.'+ofprts[1] save_ocmw_file(analpath,ofile,model_ts) model_data = preprocess_ts(model_ts) ofile = ofprts[0]+rstr+str(np.int32(np.ceil(d))).zfill(2)+'m_PP.'+ofprts[1] save_ocmw_file(analpath,ofile,model_data) else: print('Warning: Location data not avialble in '+modelpath) model_ts = None model_data = None return model_ts, model_data
[docs] def dav_data(modelpath,filename,datasrc,dataset,outfile): """ Extract depth-averaged data from a timeseries of model profiles extracted at a specific location. """ datapath = modelpath+'/EXTRACT' if locDataExists(datapath,filename): analpath = modelpath+'/ANALYSIS' if not os.path.isdir(analpath): os.mkdir(analpath) ofprts = outfile.split('.') rstr = '_hab_' model_ts = extract_depthavg_ts(datapath,filename,dataset,datasrc) d = model_ts['zLoc'] ofile = ofprts[0]+rstr+str(np.int32(np.ceil(d))).zfill(2)+'m_TS.'+ofprts[1] save_ocmw_file(analpath,ofile,model_ts) model_data = preprocess_ts(model_ts) ofile = ofprts[0]+rstr+str(np.int32(np.ceil(d))).zfill(2)+'m_PP.'+ofprts[1] save_ocmw_file(analpath,ofile,model_data) else: print('Warning: Location data not avialble in '+modelpath) model_ts = None model_data = None return model_ts, model_data
[docs] def srf_data(modelpath,filename,datasrc,dataset,outfile): """ Extract data at the sea surface from a timeseries of model profiles extracted at a specific location. """ datapath = modelpath+'/EXTRACT' if locDataExists(datapath,filename): analpath = modelpath+'/ANALYSIS' if not os.path.isdir(analpath): os.mkdir(analpath) ofprts = outfile.split('.') rstr = '_hab_' model_ts = extract_model_ts_at_surface(datapath,filename,dataset,datasrc) d = model_ts['zLoc'] ofile = ofprts[0]+rstr+str(np.int32(np.ceil(d))).zfill(2)+'m_TS.'+ofprts[1] save_ocmw_file(analpath,ofile,model_ts) model_data = preprocess_ts(model_ts) ofile = ofprts[0]+rstr+str(np.int32(np.ceil(d))).zfill(2)+'m_PP.'+ofprts[1] save_ocmw_file(analpath,ofile,model_data) else: print('Warning: Location data not avialble in '+modelpath) model_ts = None model_data = None return model_ts, model_data
[docs] def merge_model_daily_files(datapath,srchstr,outfile): """ Merge daily model extract data into single a file for post-processing. """ files = getListOfFiles(datapath,srchstr+'*'+ocmwExtn) mrgdata = {} for i,f in enumerate(files): d = load_ocmw_file(datapath,f) if i == 0: titleStr = 'Merged location data - '+datapath.split('/')[-2]+' model' mrgdata['globalAttributes'] = generateGlobalAttributes(titleStr) mrgdata['dataLoc'] = d['dataLoc'] mrgdata['crs'] = d['crs'] mrgdata['meshElem'] = d['meshElem'] mrgdata['timeUnits'] = d['timeUnits'] mrgdata['epoch'] = d['epoch'] times = d['times'] depth = d['depth'] height = d['height'] depAvg_U = d['depAvg_U'] depAvg_V = d['depAvg_V'] if 'z' in d.keys(): if d['vel_east'].shape[0] != times.shape[0]: z = d['z'].transpose() vel_east = d['vel_east'].transpose() vel_north = d['vel_north'].transpose() vel_up = d['vel_up'].transpose() else: z = d['z'] vel_east = d['vel_east'] vel_north = d['vel_north'] vel_up = d['vel_up'] else: times = np.hstack([times,d['times']]) depth = np.hstack([depth,d['depth']]) height = np.hstack([height,d['height']]) depAvg_U = np.hstack([depAvg_U,d['depAvg_U']]) depAvg_V = np.hstack([depAvg_V,d['depAvg_V']]) if 'z' in d.keys(): if d['vel_east'].shape[0] != times.shape[0]: z = np.vstack([z,d['z'].transpose()]) vel_east = np.vstack([vel_east,d['vel_east'].transpose()]) vel_north = np.vstack([vel_north,d['vel_north'].transpose()]) vel_up = np.vstack([vel_up,d['vel_up'].transpose()]) else: z = np.vstack([z,d['z']]) vel_east = np.vstack([vel_east,d['vel_east']]) vel_north = np.vstack([vel_north,d['vel_north']]) vel_up = np.vstack([vel_up,d['vel_up']]) v,indx = np.unique(times,return_index=True) mrgdata['times'] = times[indx] mrgdata['depth'] = depth[indx] mrgdata['height'] = height[indx] mrgdata['depAvg_U'] = depAvg_U[indx] mrgdata['depAvg_V'] = depAvg_V[indx] if 'z' in d.keys(): mrgdata['z'] = z[indx,:] mrgdata['vel_east'] = vel_east[indx,:] mrgdata['vel_north'] = vel_north[indx,:] mrgdata['vel_up'] = vel_up save_ocmw_file(datapath,outfile,mrgdata) return mrgdata
[docs] def merge_model_daily_poly_files(datapath,srchstr,outfile): """ Merge daily model data extracted from within a polygon into a single file for post-processing. """ files = getListOfFiles(datapath,srchstr+'*'+ocmwExtn) mrgdata = {} for i,f in enumerate(files): d = load_ocmw_file(datapath,f) if i == 0: titleStr = 'Merged location data - '+datapath.split('/')[-2]+' model' mrgdata['globalAttributes'] = generateGlobalAttributes(titleStr) if 'dataLoc' in d.keys(): mrgdata['dataLoc'] = d['dataLoc'] if 'nodesLoc' in d.keys(): mrgdata['dataLoc'] = d['nodesLoc'] if 'crs' in d.keys(): mrgdata['crs'] = d['crs'] else: mrgdata['crs'] = 'EPSG:32630' if 'nodes' in d.keys(): mrgdata['meshNode'] = d['nodes'] mrgdata['timeUnits'] = d['timeUnits'] mrgdata['epoch'] = d['epoch'] times = d['times'] depth = d['depth'] height = d['height'] depAvg_U = d['depAvg_U'] depAvg_V = d['depAvg_V'] if 'z' in d.keys(): z = d['z'] vel_east = d['vel_east'] vel_north = d['vel_north'] vel_up = d['vel_up'] else: times = np.hstack([times,d['times']]) depth = np.concatenate([depth,d['depth']],axis=1) height = np.concatenate([height,d['height']],axis=1) depAvg_U = np.concatenate([depAvg_U,d['depAvg_U']],axis=1) depAvg_V = np.concatenate([depAvg_V,d['depAvg_V']],axis=1) if 'z' in d.keys(): z = np.concatenate([z,d['z']],axis=1) vel_east = np.concatenate([vel_east,d['vel_east']],axis=1) vel_north = np.concatenate([vel_north,d['vel_north']],axis=1) vel_up = np.concatenate([vel_up,d['vel_up']],axis=1) v,indx = np.unique(times,return_index=True) mrgdata['times'] = times[indx] mrgdata['depth'] = depth[:,indx] mrgdata['height'] = height[:,indx] mrgdata['depAvg_U'] = depAvg_U[:,indx] mrgdata['depAvg_V'] = depAvg_V[:,indx] if 'z' in d.keys(): mrgdata['z'] = z[:,indx,:] mrgdata['vel_east'] = vel_east[:,indx,:] mrgdata['vel_north'] = vel_north[:,indx,:] mrgdata['vel_up'] = vel_up[:,indx,:] save_ocmw_file(datapath,outfile,mrgdata) return mrgdata
# ---------------------------------------------------------------------------- # MAIN PROCESS # ---------------------------------------------------------------------------- #-------------------------------------------------------------------------- # INTERFACE #--------------------------------------------------------------------------