#pragma once #include "BFileW.h" #include "actiondep.h" #include "ncfuncs.h" #include using michlib::BFileW; ADD_ACTION(TSC, tsc, ReadPSupported || ReadSupported); template MString ActionTSC::DoAction(const CLArgs& args, D& ds) { auto [reg, regerr] = GetRegion(args); if(regerr.Exist()) return regerr; auto resop = ds.Open(args); if(resop.Exist()) return "Can't open source: " + resop; michlib_internal::ParameterListEx pars; pars.UsePrefix(""); pars.SetParameter("source", args.at("source")); auto [tindexes, err] = GetTIndexes(ds, args, pars); if(err.Exist()) return err; if(!args.contains("var")) return "Variable not specified"; MString vname = args.at("var"); if(!ds.CheckVar(vname)) return "Variable " + vname + " not exists in this dataset"; pars.SetParameter("variable", vname); std::unique_ptr sourcepars; if constexpr(ParametersSupported) { if constexpr(ParametersRequiredRegion) { auto [p, err] = ds.Parameters(pars, args, reg); if(err.Exist()) return err; sourcepars.reset(p); } else { auto [p, err] = ds.Parameters(pars, args); if(err.Exist()) return err; sourcepars.reset(p); } } auto p = sourcepars.get(); auto data = Read(ds, vname, p, tindexes); if(!data) return "Can't read data"; if(!data.Unit().Exist()) michlib::errmessage("Unknown measurement unit!"); MString outfmt = args.contains("format") ? args.at("format") : "bin"; if(outfmt == "bin") { BFileW fw; MString name = args.contains("out") ? args.at("out") : "out.bin"; fw.Create(name, 3); fw.SetColumnName(1, "Longitude"); fw.SetColumnName(2, "Latitude"); fw.SetColumnName(3, vname + ", " + (data.Unit().Exist() ? data.Unit() : "unknown")); fw.SetParameters(pars); for(size_t i = 0; i < data.N(); i++) { fw.Write(data.Lon(i)); fw.Write(data.Lat(i)); fw.Write(data.IsFill(i) ? NAN : data(i)); } fw.Finalize(); fw.Close(); return ""; } if(outfmt == "nc" || outfmt == "netcdf") { MString name = args.contains("out") ? args.at("out") : "out.nc"; int ret; int ncid, dimid, dimidxy[2]; int lonid, latid, vid; MString text; auto fill = std::numeric_limits::max(); float fval; int compress = 3; if(args.contains("compress")) compress = args.at("compress").ToInt(); ret = nc_create(name.Buf(), NC_CLOBBER | NC_NETCDF4, &ncid); if(ret != NC_NOERR) return "Can't create netcdf file: " + name; ret = nc_put_att_text(ncid, NC_GLOBAL, "history", args.at("_cmdline").Len() + 1, args.at("_cmdline").Buf()); if(ret != NC_NOERR) return "Can't write history attribute in the netcdf file"; if constexpr(ReadIs2DGeoRectArray) { ret = nc_def_dim(ncid, "longitude", data.Nx(), &dimidxy[0]); if(ret != NC_NOERR) return "Can't create x-dimension in the netcdf file"; ret = nc_def_dim(ncid, "latitude", data.Ny(), &dimidxy[1]); if(ret != NC_NOERR) return "Can't create y-dimension in the netcdf file"; ret = nc_def_var(ncid, "longitude", NC_FLOAT, 1, &dimidxy[0], &lonid); if(ret != NC_NOERR) return "Can't create longitude variable in the netcdf file"; ret = nc_def_var(ncid, "latitude", NC_FLOAT, 1, &dimidxy[1], &latid); if(ret != NC_NOERR) return "Can't create latitude variable in the netcdf file"; ret = nc_def_var(ncid, vname.Buf(), NC_FLOAT, 2, dimidxy, &vid); if(ret != NC_NOERR) return "Can't create " + vname + " variable in the netcdf file"; } else { ret = nc_def_dim(ncid, "i", data.N(), &dimid); if(ret != NC_NOERR) return "Can't create dimension in the netcdf file"; ret = nc_def_var(ncid, "longitude", NC_FLOAT, 1, &dimid, &lonid); if(ret != NC_NOERR) return "Can't create longitude variable in the netcdf file"; ret = nc_def_var(ncid, "latitude", NC_FLOAT, 1, &dimid, &latid); if(ret != NC_NOERR) return "Can't create latitude variable in the netcdf file"; ret = nc_def_var(ncid, vname.Buf(), NC_FLOAT, 1, &dimid, &vid); if(ret != NC_NOERR) return "Can't create " + vname + " variable in the netcdf file"; } ret = nc_def_var_deflate(ncid, lonid, 1, 1, compress); if(ret != NC_NOERR) return "Can't set deflate parameters for longitude variable in the netcdf file"; ret = nc_def_var_deflate(ncid, latid, 1, 1, compress); if(ret != NC_NOERR) return "Can't set deflate parameters for latitude variable in the netcdf file"; ret = nc_def_var_deflate(ncid, vid, 1, 1, compress); if(ret != NC_NOERR) return "Can't set deflate parameters for " + vname + " variable in the netcdf file"; text = "longitude"; ret = nc_put_att_text(ncid, lonid, "standard_name", text.Len() + 1, text.Buf()); if(ret != NC_NOERR) return "Can't write standard_name attribute of longitude variable in the netcdf file"; text = "latitude"; ret = nc_put_att_text(ncid, latid, "standard_name", text.Len() + 1, text.Buf()); if(ret != NC_NOERR) return "Can't write standard_name attribute of latitude variable in the netcdf file"; text = NCFuncs::Name2StName(vname); if(text.Exist()) { ret = nc_put_att_text(ncid, vid, "standard_name", text.Len() + 1, text.Buf()); if(ret != NC_NOERR) return "Can't write standard_name attribute of " + vname + " variable in the netcdf file"; } else { text = NCFuncs::Name2LongName(vname); ret = nc_put_att_text(ncid, vid, "long_name", text.Len() + 1, text.Buf()); if(ret != NC_NOERR) return "Can't write long_name attribute of " + vname + " variable in the netcdf file"; } ret = nc_put_att_float(ncid, vid, "_FillValue", NC_FLOAT, 1, &fill); if(ret != NC_NOERR) return "Can't write _FillValue attribute of " + vname + " variable in the netcdf file"; ret = nc_enddef(ncid); if(ret != NC_NOERR) return "Can't finish definition of the netcdf file"; if constexpr(ReadIs2DGeoRectArray) { size_t i[2]; for(i[0] = 0; i[0] < data.Nx(); i[0]++) { fval = data.Ix2Lon(i[0]); ret = nc_put_var1_float(ncid, lonid, &i[0], &fval); if(ret != NC_NOERR) return "Can't write longitude variable in the netcdf file: " + MString(i[0]); } for(i[1] = 0; i[1] < data.Ny(); i[1]++) { fval = data.Iy2Lat(i[1]); ret = nc_put_var1_float(ncid, latid, &i[1], &fval); if(ret != NC_NOERR) return "Can't write latitude variable in the netcdf file: " + MString(i[1]); } for(i[0] = 0; i[0] < data.Nx(); i[0]++) for(i[1] = 0; i[1] < data.Ny(); i[1]++) { fval = data.IsFill(i[0], i[1]) ? fill : data(i[0], i[1]); ret = nc_put_var1_float(ncid, vid, i, &fval); if(ret != NC_NOERR) return "Can't write " + vname + " variable in the netcdf file: " + MString(i[0]) + ", " + i[1]; } } else { for(size_t i = 0; i < data.N(); i++) { fval = data.Lon(i); ret = nc_put_var1_float(ncid, lonid, &i, &fval); if(ret != NC_NOERR) return "Can't write longitude variable in the netcdf file: " + MString(i); fval = data.Lat(i); ret = nc_put_var1_float(ncid, latid, &i, &fval); if(ret != NC_NOERR) return "Can't write latitude variable in the netcdf file: " + MString(i); fval = data.IsFill(i) ? fill : data(i); ret = nc_put_var1_float(ncid, vid, &i, &fval); if(ret != NC_NOERR) return "Can't write " + vname + " variable in the netcdf file: " + MString(i); } } ret = nc_close(ncid); if(ret != NC_NOERR) return "Can't close netcdf file"; return ""; } return "Unknown format: " + outfmt; };