# ascii.py # write hdr and data in ascii files import os import logging import tools import numpy as np from datetime import datetime def writeHeaderProfile(hdrFile, cfg, device, fe, r): f = open(hdrFile, 'w') # first line, header ex: # PIRATA-FR30 THALASSA IRD SBE911+ 09P-1263 BOURLES print("{} {} {} {} {} {}".format(cfg['cruise']['CYCLEMESURE'], cfg['cruise']['PLATEFORME'], cfg['cruise']['INSTITUTE'], cfg[device]['typeInstrument'], cfg[device]['instrumentNumber'], cfg['cruise']['PI'])) f.write("{} {} {} {} {} {}\n".format(cfg['cruise']['CYCLEMESURE'], cfg['cruise']['PLATEFORME'], cfg['cruise']['INSTITUTE'], cfg[device]['typeInstrument'], cfg[device]['instrumentNumber'], cfg['cruise']['PI'])) # write next lines, start and end profile ex: # 00001 18/02/2020 19:04:19 18/02/2020 22:41:07 11°28.85 N 023°00.59 W 4063 5083 fr30001 # add PROFILE and END_PROFILE_TIME, BATH for i in range(fe.n): for k in fe.variables_1D: if k == 'TIME': t = tools.julian2format(fe['TIME'][i]) print(f"{t} ", end='') f.write(f"{t} ") #query = self.db.query('SELECT end_date_time FROM station') # need to cast <class 'numpy.int32'> to int query = fe.db.select('station', ['end_date_time', 'filename'], station = int(fe['PROFILE'][i])) for idx, item in enumerate(query): dt = item['end_date_time'] if dt == None: pass else: print(f"{dt} ", end='') f.write(f"{dt} ") filename = item['filename'] elif k == 'LATITUDE': lat = tools.Dec2dmc(fe['LATITUDE'][i],'N') print(f"{lat} ", end='') f.write(f"{lat} ") elif k == 'LONGITUDE': lon = tools.Dec2dmc(fe['LONGITUDE'][i],'W') print(f"{lon} ", end='') f.write(f"{lon} ") else: fmt = fe.roscop[k]['format'] if np.isnan(fe[k][i]): # a revoir !!! #print(k, type(fe[k][i])) print(' 1e+36 ', end='') f.write(' 1e+36 ') else: print(f"{fmt} " % (fe[k][i]), end='') f.write(f"{fmt} " % (fe[k][i])) # get max value for each profile, DEPTH or PRES is the first value => keys[0] col = f"MAX({fe.keys[0]})" query = fe.db.query( f"SELECT {col} FROM data WHERE station_id = {i+1}") for idx, item in enumerate(query): dt = item[col] if dt == None: print(' 1e+36 ', end='') f.write(' 1e+36 ') else: print("%6.1f " % (item[col]), end='') f.write("%6.1f " % (item[col])) print(f" {filename}", end = '\n') f.write(f" {filename}\n") f.close() def writeDataProfile(dataFile, cfg, device, fe, r): f = open(dataFile, 'w') # write header, first line f.write("{} {} {} {} {} {}\n".format(cfg['cruise']['CYCLEMESURE'], cfg['cruise']['PLATEFORME'], cfg['cruise']['INSTITUTE'], cfg[device]['typeInstrument'], cfg[device]['instrumentNumber'], cfg['cruise']['PI'])) # write header, second line with physical parameter liste, fill with N/A if necessary f.write("PROFILE ") for k in fe.keys: f.write(f" {k} ") for r in range(len(fe.keys),len(fe.variables_1D)+1): f.write(' N/A ') f.write("\n") # write station or profile header for i in range(fe.n): # write header (pres or depth = -1) for k in fe.variables_1D: fmt = fe.roscop[k]['format'] if k == 'PROFILE' or k == 'PRFL': f.write(f"{fmt} -1 " % (fe[k][i])) elif k == 'TIME': # save date in EPIC format (numeric) in profile header f.write(f" {fmt} {'%s'}" % (fe[k][i] - fe.julian_from_year, tools.julian2format(fe[k][i], "%Y%m%d%H%M%S"))) else: if np.isnan(fe[k][i]): #print(k, type(fe[k][i])) f.write(' 1e+36 ') else: f.write(f" {fmt} " % (fe[k][i])) # fill last header columns with 1e+36 if for r in range(len(fe.variables_1D)+1, len(fe.keys)): f.write(' 1e+36 ') f.write("\n") # for each valid line in array (not _fillvalue) for m in range(fe.m): # don't print line if data is _fillValue if fe[fe.keys[0]][i][m] != fe.roscop[fe.keys[0]]['_FillValue']: fmt = fe.roscop['PROFILE']['format'] f.write(f"{fmt} " % (fe['PROFILE'][i])) # add value for each parameter, use format from roscop for k in fe.keys: fmt = fe.roscop[k]['format'] f.write(f" {fmt} " % (fe[k][i][m])) for r in range(len(fe.keys),len(fe.variables_1D)+1): f.write(' 1e+36 ') f.write("\n") f.close() def writeProfile(cfg, device, fe, r): if not os.path.exists(cfg['global']['ASCII']): os.makedirs(cfg['global']['ASCII']) fileName = "{}/{}.{}".format(cfg['global']['ASCII'], cfg['cruise']['CYCLEMESURE'], device.lower()) writeHeaderProfile(fileName, cfg, device.lower(), fe, r, ) print('writing header file: {}'.format(fileName), end='', flush=True) print(' done...') fileName = "{}/{}_{}".format(cfg['global']['ASCII'], cfg['cruise']['CYCLEMESURE'], device.lower()) print('writing data file: {}'.format(fileName), end='', flush=True) writeDataProfile(fileName, cfg, device.lower(), fe, r) print(' done...') def writeDecimalDataTrajectory(dataFile, cfg, device, fe, r): f = open(dataFile, 'w') # write header, first line f.write("{} {} {} ".format(cfg['cruise']['CYCLEMESURE'], cfg['cruise']['PLATEFORME'], cfg['cruise']['INSTITUTE'])) if 'typeInstrument' in cfg[device]: f.write(f"{cfg[device]['typeInstrument']}") if 'instrumentNumber' in cfg[device]: f.write(f"{cfg[device]['instrumentNumber']}") if 'PI' in cfg['cruise']: f.write(f"{cfg['cruise']['PI']}") f.write("\n") # write header, second line with physical parameter liste, fill with N/A if necessary for k in fe.keys: f.write(f" {k} ") f.write("\n") # write data for n in range(fe.n): for k in fe.keys: fmt = fe.roscop[k]['format'] if '_FillValue' in fe.roscop[k] and fe[k][n] == fe.roscop[k]['_FillValue']: f.write(' 1e+36 ') else: f.write(f" {fmt} " % (fe[k][n])) f.write("\n") f.close() def writeHumanDataTrajectory(dataFile, cfg, device, fe, r): f = open(dataFile, 'w') # write header, first line f.write("{} {} {} ".format(cfg['cruise']['CYCLEMESURE'], cfg['cruise']['PLATEFORME'], cfg['cruise']['INSTITUTE'])) if 'typeInstrument' in cfg[device]: f.write(f"{cfg[device]['typeInstrument']}") if 'instrumentNumber' in cfg[device]: f.write(f"{cfg[device]['instrumentNumber']}") if 'PI' in cfg['cruise']: f.write(f"{cfg['cruise']['PI']}") f.write("\n") # write header, second line with physical parameter liste, fill with N/A if necessary for k in fe.keys: if k == 'DAYD': f.write(" DATE TIME ") continue f.write(f" {k} ") f.write("\n") # write data for n in range(fe.n): for k in fe.keys: if k == 'LATITUDE': f.write(f" {tools.Dec2dmc(fe[k][n],'N')} ") continue if k == 'LONGITUDE': f.write(f" {tools.Dec2dmc(fe[k][n],'E')} ") continue if k == 'DAYD': # use the format given in devide trajectory toml config file dt = tools.julian2format(fe[k][n]) f.write(f" {dt} ") continue fmt = fe.roscop[k]['format'] if '_FillValue' in fe.roscop[k] and fe[k][n] == fe.roscop[k]['_FillValue']: f.write(' 1e+36 ') else: f.write(f" {fmt} " % (fe[k][n])) f.write("\n") f.close() def writeTrajectory(cfg, device, fe, r): if not os.path.exists(cfg['global']['ASCII']): os.makedirs(cfg['global']['ASCII']) # write ascii file with human read time and position fileName = "{}/{}.{}".format(cfg['global']['ASCII'], cfg['cruise']['CYCLEMESURE'], device.lower()) print('writing file: {}'.format(fileName), end='', flush=True) writeHumanDataTrajectory(fileName, cfg, device.lower(), fe, r, ) print(' done...') # write ascii file with decimal time and position fileName = "{}/{}_{}".format(cfg['global']['ASCII'], cfg['cruise']['CYCLEMESURE'], device.lower()) print('writing file: {}'.format(fileName), end='', flush=True) writeDecimalDataTrajectory(fileName, cfg, device.lower(), fe, r) print(' done...')