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.
 
 
 

129 lines
3.6 KiB

#define MICHLIB_NOSOURCE
#include "TSCDATA.h"
MString TSCDATAData::Open(const CLArgs& args)
{
if(!args.contains("dataset")) return "path to data not specified";
MString dataset = args.at("dataset");
michlib::NCFileA newnc;
std::vector<MString> newvnames, newlnames;
MString newhistory;
newnc.Reset(dataset);
if(!newnc) return "Can't open file " + dataset;
auto head = newnc.Header();
if(head.Dimensions().size() != 2) return "Unsupported number of dimensions";
if((head.Dimensions()[0].Name() != "longitude" || head.Dimensions()[1].Name() != "latitude") &&
(head.Dimensions()[1].Name() != "longitude" || head.Dimensions()[0].Name() != "latitude"))
return "Unsupported dimensions names";
if(head.Dimensions()[0].Name() == "longitude")
{
nx = head.Dimensions()[0].Len();
ny = head.Dimensions()[1].Len();
}
else
{
ny = head.Dimensions()[0].Len();
nx = head.Dimensions()[1].Len();
}
{
bool lonfound = false, latfound = false;
for(const auto& v: head.Variables())
if(v.Dimensions().size() == 1 && v.Type().Id() == NC_FLOAT)
{
lonfound = lonfound || (v.Dimensions()[0].Name() == "longitude" && v.Name() == "longitude");
latfound = latfound || (v.Dimensions()[0].Name() == "latitude" && v.Name() == "latitude");
}
if(!lonfound) return "Longitude not found";
if(!latfound) return "Latitude not found";
}
for(const auto& v: head.Variables())
{
if(v.Dimensions().size() != 2) continue;
if(v.Type().Id() != NC_FLOAT) continue;
if((v.Dimensions()[0].Name() != "longitude" || v.Dimensions()[1].Name() != "latitude") && (v.Dimensions()[1].Name() != "longitude" || v.Dimensions()[0].Name() != "latitude"))
continue;
newvnames.push_back(v.Name());
auto lname = newnc.A<MString>(v.Name(), "long_name");
newlnames.push_back(lname ? lname.Get() : "");
}
if(newvnames.size() == 0) return "No variables found";
{
auto his = newnc.A<MString>("history");
if(his) newhistory = his;
}
history = std::move(newhistory);
vnames = std::move(newvnames);
lnames = std::move(newlnames);
nc = std::move(newnc);
return "";
}
MString TSCDATAData::Info() const
{
if(!nc) return "";
MString out;
out += MString("Dimensions: ") + nx + " X " + ny + "\n";
out += MString("Variables: ");
for(size_t i = 0; i < vnames.size(); i++) out += ((i == 0) ? "" : ", ") + vnames[i];
out += "\n";
auto his = nc.A<MString>("history");
if(his) out += "Creator: " + his.Get() + "\n";
return out;
}
std::vector<TSCDATAData::DataType> TSCDATAData::ReadLons() const
{
std::vector<DataType> out;
auto lons = nc.V<DataType>("longitude");
if(lons)
{
out.resize(lons.DimLen(0));
for(size_t i = 0; i < out.size(); i++) out[i] = lons(i);
}
return out;
}
std::vector<TSCDATAData::DataType> TSCDATAData::ReadLats() const
{
std::vector<DataType> out;
auto lats = nc.V<DataType>("latitude");
if(lats)
{
out.resize(lats.DimLen(0));
for(size_t i = 0; i < out.size(); i++) out[i] = lats(i);
}
return out;
}
std::vector<TSCDATAData::DataType> TSCDATAData::ReadVar(const MString& name) const
{
std::vector<DataType> out;
bool havevar = false;
for(size_t i = 0; i < vnames.size(); i++) havevar = havevar || (vnames[i] == name);
if(!havevar) return out;
auto var = nc.V<DataType>(name, "latitude", "longitude");
if(var)
{
out.resize(nx * ny);
for(size_t iy = 0; iy < ny; iy++)
for(size_t ix = 0; ix < nx; ix++) out[iy * nx + ix] = var(iy, ix);
}
return out;
}
TSCDATAData::DataType TSCDATAData::FillVal(const MString& name) const
{
auto fill = nc.A<DataType>(name, "_FillValue");
return fill ? fill.Get() : 0.0;
}