#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 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(v.Name(), "long_name"); newlnames.push_back(lname ? lname.Get() : ""); } if(newvnames.size() == 0) return "No variables found"; { auto his = newnc.A("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("history"); if(his) out += "Creator: " + his.Get() + "\n"; return out; } std::vector TSCDATAData::ReadLons() const { std::vector out; auto lons = nc.V("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::ReadLats() const { std::vector out; auto lats = nc.V("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::ReadVar(const MString& name) const { std::vector 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(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(name, "_FillValue"); return fill ? fill.Get() : 0.0; }