|
|
@ -18,6 +18,10 @@ MString LayeredData::Info() const |
|
|
|
if(StName2Name(ret).Exist()) vars.emplace(StName2Name(ret)); |
|
|
|
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"); |
|
|
|
|
|
|
|
|
|
|
|
MString svars; |
|
|
|
MString svars; |
|
|
|
{ |
|
|
|
{ |
|
|
|
bool first = true; |
|
|
|
bool first = true; |
|
|
@ -136,7 +140,14 @@ std::pair<const BaseParameters*, MString> LayeredData::Parameters(michlib_intern |
|
|
|
|
|
|
|
|
|
|
|
if(!args.contains("var")) return {nullptr, "Variable not specified"}; |
|
|
|
if(!args.contains("var")) return {nullptr, "Variable not specified"}; |
|
|
|
ppar->varname = args.at("var"); |
|
|
|
ppar->varname = args.at("var"); |
|
|
|
if(!HaveVar(ppar->varname)) return {nullptr, "Variable " + ppar->varname + " not exists in this dataset"}; |
|
|
|
if(!HaveVar(ppar->varname)) |
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
bool varexist = false; |
|
|
|
|
|
|
|
if(ppar->varname == "temp" && HaveVar("ptemp") && HaveVar("sal")) varexist = true; |
|
|
|
|
|
|
|
if(ppar->varname == "ptemp" && HaveVar("temp") && HaveVar("sal")) varexist = true; |
|
|
|
|
|
|
|
if(ppar->varname == "pdens" && (HaveVar("ptemp") || HaveVar("temp")) && HaveVar("sal")) varexist = true; |
|
|
|
|
|
|
|
if(!varexist) return {nullptr, "Variable " + ppar->varname + " not exists in this dataset"}; |
|
|
|
|
|
|
|
} |
|
|
|
if(args.contains("layer")) ppar->layer = args.at("layer").ToInteger<size_t>(); |
|
|
|
if(args.contains("layer")) ppar->layer = args.at("layer").ToInteger<size_t>(); |
|
|
|
if(!args.contains("depth") && ppar->layer >= NDepths()) return {nullptr, MString("Layer ") + ppar->layer + " is too deep!"}; |
|
|
|
if(!args.contains("depth") && ppar->layer >= NDepths()) return {nullptr, MString("Layer ") + ppar->layer + " is too deep!"}; |
|
|
|
real depth = args.contains("depth") ? args.at("depth").ToReal() : Depth(ppar->layer); |
|
|
|
real depth = args.contains("depth") ? args.at("depth").ToReal() : Depth(ppar->layer); |
|
|
@ -192,7 +203,87 @@ LayeredData::Data LayeredData::Read(const BaseParameters* ip, size_t i) const |
|
|
|
|
|
|
|
|
|
|
|
auto p = dynamic_cast<const struct Parameters*>(ip); |
|
|
|
auto p = dynamic_cast<const struct Parameters*>(ip); |
|
|
|
auto [name, id, tid] = VarNameLoc(p->varname, times[i]); |
|
|
|
auto [name, id, tid] = VarNameLoc(p->varname, times[i]); |
|
|
|
auto head = nc[id]->Header(); |
|
|
|
if(!name.Exist()) // Conversion read
|
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
// ptemp from temp and sal
|
|
|
|
|
|
|
|
if(p->varname == "ptemp") |
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
struct Parameters params = *p; |
|
|
|
|
|
|
|
params.varname = "temp"; |
|
|
|
|
|
|
|
auto temp = Read(¶ms, i); |
|
|
|
|
|
|
|
params.varname = "sal"; |
|
|
|
|
|
|
|
auto sal = Read(¶ms, i); |
|
|
|
|
|
|
|
if(!(temp && sal)) return Data(); |
|
|
|
|
|
|
|
auto out = temp; |
|
|
|
|
|
|
|
for(size_t ind = 0; ind < out.N(); ind++) |
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
if(out.Lon(ind) != temp.Lon(ind) || out.Lon(ind) != sal.Lon(ind) || out.Lat(ind) != temp.Lat(ind) || out.Lat(ind) != sal.Lat(ind)) |
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
michlib::errmessage("Internal error"); |
|
|
|
|
|
|
|
exit(1); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
if(temp.IsFill(ind) || sal.IsFill(ind)) |
|
|
|
|
|
|
|
out.V(ind) = out.Fillval(); |
|
|
|
|
|
|
|
else |
|
|
|
|
|
|
|
out.V(ind) = Temp2PTemp(temp.V(ind), sal.V(ind), Depth(p->layer), out.Lon(ind), out.Lat(ind)); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
return out; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
// temp from ptemp and sal
|
|
|
|
|
|
|
|
if(p->varname == "temp") |
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
struct Parameters params = *p; |
|
|
|
|
|
|
|
params.varname = "ptemp"; |
|
|
|
|
|
|
|
auto temp = Read(¶ms, i); |
|
|
|
|
|
|
|
params.varname = "sal"; |
|
|
|
|
|
|
|
auto sal = Read(¶ms, i); |
|
|
|
|
|
|
|
if(!(temp && sal)) return Data(); |
|
|
|
|
|
|
|
auto out = temp; |
|
|
|
|
|
|
|
for(size_t ind = 0; ind < out.N(); ind++) |
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
if(out.Lon(ind) != temp.Lon(ind) || out.Lon(ind) != sal.Lon(ind) || out.Lat(ind) != temp.Lat(ind) || out.Lat(ind) != sal.Lat(ind)) |
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
michlib::errmessage("Internal error"); |
|
|
|
|
|
|
|
exit(1); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
if(temp.IsFill(ind) || sal.IsFill(ind)) |
|
|
|
|
|
|
|
out.V(ind) = out.Fillval(); |
|
|
|
|
|
|
|
else |
|
|
|
|
|
|
|
out.V(ind) = PTemp2Temp(temp.V(ind), sal.V(ind), Depth(p->layer), out.Lon(ind), out.Lat(ind)); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
return out; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
// pdens from temp and sal
|
|
|
|
|
|
|
|
if(p->varname == "pdens") |
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
struct Parameters params = *p; |
|
|
|
|
|
|
|
bool tempispot = HaveVar("ptemp"); |
|
|
|
|
|
|
|
params.varname = tempispot ? "ptemp" : "temp"; |
|
|
|
|
|
|
|
auto temp = Read(¶ms, i); |
|
|
|
|
|
|
|
params.varname = "sal"; |
|
|
|
|
|
|
|
auto sal = Read(¶ms, i); |
|
|
|
|
|
|
|
if(!(temp && sal)) return Data(); |
|
|
|
|
|
|
|
auto out = temp; |
|
|
|
|
|
|
|
for(size_t ind = 0; ind < out.N(); ind++) |
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
if(out.Lon(ind) != temp.Lon(ind) || out.Lon(ind) != sal.Lon(ind) || out.Lat(ind) != temp.Lat(ind) || out.Lat(ind) != sal.Lat(ind)) |
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
michlib::errmessage("Internal error"); |
|
|
|
|
|
|
|
exit(1); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
if(temp.IsFill(ind) || sal.IsFill(ind)) |
|
|
|
|
|
|
|
out.V(ind) = out.Fillval(); |
|
|
|
|
|
|
|
else |
|
|
|
|
|
|
|
out.V(ind) = tempispot ? PTemp2PDens(temp.V(ind), sal.V(ind), Depth(p->layer), out.Lon(ind), out.Lat(ind)) |
|
|
|
|
|
|
|
: Temp2PDens(temp.V(ind), sal.V(ind), Depth(p->layer), out.Lon(ind), out.Lat(ind)); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
return out; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
return Data(); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// Direct read
|
|
|
|
|
|
|
|
auto head = nc[id]->Header(); |
|
|
|
for(const auto& v: head.Variables()) |
|
|
|
for(const auto& v: head.Variables()) |
|
|
|
if(v.Name() == name) |
|
|
|
if(v.Name() == name) |
|
|
|
{ |
|
|
|
{ |
|
|
|