You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
148 lines
4.6 KiB
148 lines
4.6 KiB
#define MICHLIB_NOSOURCE |
|
#include "ncfuncs.h" |
|
|
|
NCFuncs::CoordNames NCFuncs::GetDNames(const NCFileA& nc) |
|
{ |
|
CoordNames out; |
|
auto head = nc.Header(); |
|
for(const auto& dim: head.Dimensions()) |
|
{ |
|
if(dim.Name() == "lon" || dim.Name() == "longitude") |
|
{ |
|
out.lonname = dim.Name(); |
|
out.nx = dim.Len(); |
|
} |
|
if(dim.Name() == "lat" || dim.Name() == "latitude") |
|
{ |
|
out.latname = dim.Name(); |
|
out.ny = dim.Len(); |
|
} |
|
if(dim.Name() == "depth") |
|
{ |
|
out.depthname = dim.Name(); |
|
out.nz = dim.Len(); |
|
} |
|
if(dim.Name() == "time") |
|
{ |
|
out.timename = dim.Name(); |
|
out.nt = dim.Len(); |
|
} |
|
} |
|
return out; |
|
} |
|
|
|
NCFuncs::CoordNames NCFuncs::GetCNames(const NCFileA& nc) |
|
{ |
|
CoordNames out; |
|
auto head = nc.Header(); |
|
for(const auto& v: head.Variables()) // Try to define coordinates by attribute standard_name or attribute axis |
|
{ |
|
auto stname = nc.A<MString>(v.Name(), "standard_name"); |
|
auto axis = nc.A<MString>(v.Name(), "axis"); |
|
bool islon = false, islat = false, isdepth = false, istime = false; |
|
if(!(stname || axis)) continue; |
|
if(stname && stname.Get() == "longitude") islon = true; |
|
if(stname && stname.Get() == "latitude") islat = true; |
|
if(stname && stname.Get() == "depth") isdepth = true; |
|
if(stname && stname.Get() == "time") istime = true; |
|
|
|
if(!out.lonname.Exist() && axis && axis.Get() == "X") islon = true; |
|
if(!out.latname.Exist() && axis && axis.Get() == "Y") islat = true; |
|
if(!out.depthname.Exist() && axis && axis.Get() == "Z") isdepth = true; |
|
if(!out.timename.Exist() && axis && axis.Get() == "T") istime = true; |
|
|
|
if(islon) out.lonname = v.Name(); |
|
if(islat) out.latname = v.Name(); |
|
if(isdepth) out.depthname = v.Name(); |
|
if(istime) out.timename = v.Name(); |
|
|
|
if(islon) out.nx = v.Dimensions().size(); |
|
if(islat) out.ny = v.Dimensions().size(); |
|
if(isdepth) out.nz = v.Dimensions().size(); |
|
if(istime) out.nt = v.Dimensions().size(); |
|
} |
|
return out; |
|
} |
|
|
|
void NCFuncs::GetVars(const NCFileA& nc, std::set<MString>& vars) |
|
{ |
|
auto head = nc.Header(); |
|
for(const auto& v: head.Variables()) |
|
{ |
|
auto ret = nc.A<MString>(v.Name(), "standard_name"); |
|
if(!ret) continue; |
|
if(StName2Name(ret).Exist()) vars.emplace(StName2Name(ret)); |
|
} |
|
if((vars.contains("ptemp") || vars.contains("temp")) && vars.contains("sal")) vars.emplace("pdens"); |
|
if(vars.contains("ptemp") && vars.contains("sal")) vars.emplace("temp"); |
|
if(vars.contains("temp") && vars.contains("sal")) vars.emplace("ptemp"); |
|
|
|
if(vars.contains("u") && vars.contains("v")) vars.emplace("U"); |
|
if(vars.contains("u") && vars.contains("v")) vars.emplace("U2"); |
|
} |
|
|
|
std::tuple<MDateTime, time_t, bool> NCFuncs::Refdate(const MString& refdate) |
|
{ |
|
MDateTime out; |
|
time_t step = 0; |
|
|
|
MString rstr; |
|
auto words = michlib::Split_on_words(refdate); |
|
auto ci = words.begin(); |
|
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++; |
|
if(ci != words.end()) rstr += " " + *ci; // Hours |
|
bool success = out.FromString(rstr); |
|
return {out, step, success}; |
|
} |
|
|
|
MString NCFuncs::StName2Name(const MString& stname) |
|
{ |
|
if(stname == "sea_water_potential_temperature") return "ptemp"; |
|
if(stname == "sea_water_temperature") return "temp"; |
|
if(stname == "sea_water_salinity") return "sal"; |
|
if(stname == "ocean_mixed_layer_thickness_defined_by_sigma_theta") return "mld"; |
|
if(stname == "sea_surface_height_above_geoid") return "ssh"; |
|
if(stname == "sea_surface_elevation") return "ssh"; |
|
if(stname == "eastward_sea_water_velocity") return "u"; |
|
if(stname == "northward_sea_water_velocity") return "v"; |
|
if(stname == "surface_geostrophic_eastward_sea_water_velocity") return "u"; |
|
if(stname == "surface_geostrophic_northward_sea_water_velocity") return "v"; |
|
if(stname == "upward_sea_water_velocity") return "w"; |
|
return ""; |
|
} |
|
|
|
bool NCFuncs::HaveVar(const NCFileA& nc, const MString& vname) |
|
{ |
|
auto head = nc.Header(); |
|
for(const auto& v: head.Variables()) |
|
{ |
|
auto stname = nc.A<MString>(v.Name(), "standard_name"); |
|
if(!stname) continue; |
|
if(StName2Name(stname) == vname) return true; |
|
} |
|
return false; |
|
} |
|
|
|
/* |
|
template<class HV> bool NCFuncs::CheckVar(const MString& vname, HV hv) |
|
{ |
|
if(!hv(vname)) |
|
{ |
|
bool varexist = false; |
|
if(vname == "temp" && hv("ptemp") && hv("sal")) varexist = true; |
|
if(vname == "ptemp" && hv("temp") && hv("sal")) varexist = true; |
|
if(vname == "pdens" && (hv("ptemp") || hv("temp")) && hv("sal")) varexist = true; |
|
if((vname == "U" || vname == "U2") && hv("u") && hv("v")) varexist = true; |
|
if(!varexist) return false; |
|
} |
|
return true; |
|
} |
|
*/
|
|
|