From 945691fb3732ba8ca1d2b018943b6e8f074bda06 Mon Sep 17 00:00:00 2001 From: Michael Uleysky Date: Fri, 14 Apr 2023 14:36:42 +1000 Subject: [PATCH] Added source AVISO --- include/AVISO.h | 52 +++++++++++++++++++++++++++++++++++++++++++ include/layereddata.h | 10 +++++++-- include/odm.h | 10 ++++++++- src/layereddata.cpp | 13 ++++++----- src/odm.cpp | 19 +++++++++------- 5 files changed, 88 insertions(+), 16 deletions(-) create mode 100644 include/AVISO.h diff --git a/include/AVISO.h b/include/AVISO.h new file mode 100644 index 0000000..69e7ff0 --- /dev/null +++ b/include/AVISO.h @@ -0,0 +1,52 @@ +#pragma once +#include "layereddata.h" + +class AVISOData: public LayeredData +{ + enum Type + { + TYPE_UNKNOWN, + TYPE_DT, + TYPE_NRT, + TYPE_EDT, + TYPE_ENRT + }; + + Type type = TYPE_UNKNOWN; + + MString DataTitle() const + { + switch(type) + { + case(TYPE_DT): return "AVISO Delayed time velocity field"; + case(TYPE_NRT): return "AVISO Near-real time velocity field"; + case(TYPE_EDT): return "AVISO+Eckman Delayed time velocity field"; + case(TYPE_ENRT): return "AVISO+Eckman Near-real time velocity field"; + default: return "No title"; + } + } + + public: + AVISOData() = default; + + // TODO: RetVal + MString Open(const CLArgs& args) + { + MString dataset = args.contains("dataset") ? args.at("dataset") : "DT"; + + GPL.UsePrefix("AVISO"); + if(dataset == "DT") + type = TYPE_DT; + else if(dataset == "NRT") + type = TYPE_NRT; + else if(dataset == "EckmanDT") + type = TYPE_EDT; + else if(dataset == "EckmanNRT") + type = TYPE_ENRT; + else + return "Unknown dataset: " + dataset; + + SetTitle(DataTitle()); + return LayeredData::Open(dataset); + } +}; diff --git a/include/layereddata.h b/include/layereddata.h index 99458ae..8610fce 100644 --- a/include/layereddata.h +++ b/include/layereddata.h @@ -41,6 +41,7 @@ class LayeredData if(!time) return "Can't read times"; MDateTime refdate; + time_t step = 0; { auto units = nc.Attribute("time", "units"); if(!units) return "Can't read refdate"; @@ -48,7 +49,12 @@ class LayeredData MString rstr; auto words = michlib::Split_on_words(units); auto ci = words.begin(); - if(ci != words.end()) ci++; // skip "hours" + if(ci != words.end()) + { + if(*ci == "hours") step = 3600; + if(*ci == "days") step = 3600 * 24; + ci++; + } if(ci != words.end()) ci++; // skip "since" if(ci != words.end()) rstr = *ci; // Day if(ci != words.end()) ci++; @@ -57,7 +63,7 @@ class LayeredData } times.resize(time.DimLen(0)); - for(size_t i = 0; i < times.size(); i++) times[i] = refdate + static_cast(time(i)) * 3600; + for(size_t i = 0; i < times.size(); i++) times[i] = refdate + static_cast(time(i)) * step; return ""; } diff --git a/include/odm.h b/include/odm.h index f7c7a41..247f9f3 100644 --- a/include/odm.h +++ b/include/odm.h @@ -1,4 +1,5 @@ #pragma once +#include "AVISO.h" #include "BFileW.h" #include "HYCOM.h" #include "NEMO.h" @@ -10,7 +11,7 @@ using michlib::errmessage; using michlib::GPL; using michlib::message; -using DataVariants = std::variant; +using DataVariants = std::variant; template concept InfoSupported = requires(T t) { @@ -146,6 +147,13 @@ class Data: public DataVariants if(res.Exist()) return "Can't open source " + src + ":\n" + res; *this = Data(std::move(data)); } + else if(src == "AVISO") + { + AVISOData data; + auto res = data.Open(args); + if(res.Exist()) return "Can't open source " + src + ":\n" + res; + *this = Data(std::move(data)); + } else if(src == "HYCOM") { HYCOMData data; diff --git a/src/layereddata.cpp b/src/layereddata.cpp index 02d0e91..93878a5 100644 --- a/src/layereddata.cpp +++ b/src/layereddata.cpp @@ -112,13 +112,16 @@ MString LayeredData::Open(const MString& dataset) } auto rdepths = nc[0]->VR("depth"); - if(!rdepths) + if(rdepths) { - nc.clear(); - return "Can't read depths"; + depths.resize(rdepths.DimLen(0)); + for(size_t i = 0; i < depths.size(); i++) depths[i] = rdepths(i); + } + else // Surface only data + { + depths.resize(1); + depths[0]=0; } - depths.resize(rdepths.DimLen(0)); - for(size_t i = 0; i < depths.size(); i++) depths[i] = rdepths(i); auto lons = nc[0]->VR(lonname); auto lats = nc[0]->VR(latname); diff --git a/src/odm.cpp b/src/odm.cpp index 62dbfa7..fddc996 100644 --- a/src/odm.cpp +++ b/src/odm.cpp @@ -6,27 +6,31 @@ inline void Usage(const MString& arg0) message("Keys are:"); message(" action. What the program should do. May be: info, tsc, uv. Default: tsc."); message(" Keys for action=info. Print some information about dataset."); - message(" source. Required. May be: NEMO, HYCOM"); + message(" source. Required. May be: NEMO, HYCOM, AVISO"); message(" Keys for source=NEMO"); message(" dataset. Can be DT, NRT or NRT6. Default: DT"); message(" Keys for source=HYCOM"); message(" dataset. Can be Forecast, Hindcast or Reanalysis. Default: Forecast"); + message(" Keys for source=AVISO"); + message(" dataset. Can be DT, NRT, EckmanDT or EckmanNRT. Default: DT"); message(" Keys for action=tsc. Get temperature, salinity, chlorofill from dataset."); - message(" source. Required. May be: NEMO, HYCOM"); - message(" var. Required. May be: temp, ptemp, pdens, sal, chl, mld, ssh or w."); + message(" source. Required. May be: NEMO, HYCOM, AVISO"); + message(" var. Required. May be: U, U2, u, v, temp, ptemp, pdens, sal, chl, mld, ssh or w."); message(" time. Time moment or regular expression. If present, timeb and timee must be absent"); message(" timeb, timee. Time interval. If present, time must be absent"); + message(" lonb, lone, latb, late. Required. Region of interest"); message(" out. Output file. Default: out.bin"); message(" Keys for source=NEMO"); message(" dataset. Can be DT, NRT or NRT6. Default: DT"); message(" layer and/or depth. Layer or depth of NEMO dataset. If depth is specified, layer is ignored. Both ignored, if var=mld or var=ssh. Default: layer=0"); - message(" lonb, lone, latb, late. Required. Region of interest"); message(" Keys for source=HYCOM"); message(" dataset. Can be Forecast, Hindcast or Reanalysis. Default: Forecast"); message(" layer and/or depth. Layer or depth of HYCOM dataset. If depth is specified, layer is ignored. Both ignored, if var=mld or var=ssh. Default: layer=0"); - message(" lonb, lone, latb, late. Required. Region of interest"); + message(" Keys for source=AVISO"); + message(" dataset. Can be DT, NRT, EckmanDT or EckmanNRT. Default: DT"); + message(" layer and/or depth. Layer or depth of AVISO dataset. If depth is specified, layer is ignored. Both ignored for datasets DT and NRT. Default: layer=0"); message(" Keys for action=uv. Get velocity field and its derivatives."); - message(" source. Required. May be: NEMO, HYCOM"); + message(" source. Required. May be: NEMO, HYCOM, AVISO"); message(" time. Time moment or regular expression. If present, timeb and timee must be absent"); message(" timeb, timee. Time interval. If present, time must be absent"); message(" out. Output file for components of velocity field, divergency, rotor and Okubo-Weiss parameter. If absent, this data not calculated."); @@ -34,8 +38,7 @@ inline void Usage(const MString& arg0) message(" shiftx, shifty. Shift of the sparsed grid. Used only if velout parameter is present. Default: 0"); message(" skipx, skipy. How many poinst skipped in the sparsed grid. Used only if velout parameter is present. Default: 1, output each point"); message(" stpout. Output file for stationary points. If absent, this data not calculated."); - message(" Keys for source=NEMO. See section action=tsc."); - message(" Keys for source=HYCOM. See section action=tsc."); + message(" Keys for specific sources see in the section action=tsc."); } int main(int argc, char** argv)