#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(v.Name(), "standard_name"); auto axis = nc.A(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& vars) { auto head = nc.Header(); for(const auto& v: head.Variables()) { auto ret = nc.A(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"); if(vars.contains("ssh")) vars.emplace("ugeo"); if(vars.contains("ssh")) vars.emplace("vgeo"); } std::tuple 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 == "seconds") step = 1; if(*ci == "minutes") step = 60; 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"; if(stname == "mass_concentration_of_chlorophyll_a_in_sea_water") return "chl"; if(stname == "mole_concentration_of_nitrate_in_sea_water") return "NO3"; if(stname == "net_primary_production_of_biomass_expressed_as_carbon_per_unit_volume_in_sea_water") return "prprod"; if(stname == "mole_concentration_of_phytoplankton_expressed_as_carbon_in_sea_water") return "Cchl"; if(stname == "mole_concentration_of_phosphate_in_sea_water") return "PO4"; if(stname == "mole_concentration_of_silicate_in_sea_water") return "Si"; return ""; } MString NCFuncs::Name2StName(const MString& name) { if(name == "ptemp") return "sea_water_potential_temperature"; if(name == "temp") return "sea_water_temperature"; if(name == "sal") return "sea_water_salinity"; if(name == "mld") return "ocean_mixed_layer_thickness_defined_by_sigma_theta"; if(name == "ssh") return "sea_surface_height_above_geoid"; if(name == "u") return "eastward_sea_water_velocity"; if(name == "v") return "northward_sea_water_velocity"; if(name == "w") return "upward_sea_water_velocity"; if(name == "chl") return "mass_concentration_of_chlorophyll_a_in_sea_water"; if(name == "NO3") return "mole_concentration_of_nitrate_in_sea_water"; if(name == "prprod") return "net_primary_production_of_biomass_expressed_as_carbon_per_unit_volume_in_sea_water"; if(name == "Cchl") return "mole_concentration_of_phytoplankton_expressed_as_carbon_in_sea_water"; if(name == "PO4") return "mole_concentration_of_phosphate_in_sea_water"; if(name == "Si") return "mole_concentration_of_silicate_in_sea_water"; return ""; } MString NCFuncs::Name2LongName(const MString& name) { if(name == "ptemp") return "Potential temperature"; if(name == "temp") return "Temperature"; if(name == "sal") return "Salinity"; if(name == "mld") return "Mixed layer depth"; if(name == "ssh") return "Sea surface height"; if(name == "u") return "X-velocity"; if(name == "v") return "Y-velocity"; if(name == "w") return "Z-velocity"; if(name == "ugeo") return "Geostrophic eastward velocity from ssh"; if(name == "vgeo") return "Geostrophic northward velocity from ssh"; if(name == "chl") return "Concentration of chlorophyll"; if(name == "NO3") return "Concentration of nitrates"; if(name == "prprod") return "Primary production"; if(name == "Cchl") return "Concentration of chlorophyll carbon"; if(name == "PO4") return "Concentration of phosphates"; if(name == "Si") return "Concentration of silicates"; if(name == "U") return "Module of horizontal velocity"; if(name == "U2") return "Squared horizontal velocity"; return ""; } bool NCFuncs::HaveVar(const NCFileA& nc, const MString& vname) { auto head = nc.Header(); for(const auto& v: head.Variables()) { auto stname = nc.A(v.Name(), "standard_name"); if(!stname) continue; if(StName2Name(stname) == vname) return true; } return false; }