#pragma once #include "actions.h" template struct DoAction_ { static MString DoAction(const CLArgs& args, D& data); }; template MString DoAction_::DoAction(const CLArgs& args, D& ds) { michlib_internal::ParameterListEx pars; pars.UsePrefix(""); pars.SetParameter("source", args.at("source")); auto [tindexes, err] = GetTIndexes(ds, args, pars); if(err.Exist()) return err; std::unique_ptr sourcepars; if constexpr(ParametersSupported) { auto [p, err] = ds.Parameters(pars, args); if(err.Exist()) return err; sourcepars.reset(p); } auto p = sourcepars.get(); auto data = ReadUV(ds, p, tindexes); if(!data) return "Can't read data"; // Main file MString name = args.contains("out") ? args.at("out") : ""; if(name.Exist()) { BFileW fw; fw.Create(name, 9); fw.SetColumnName(1, "Longitude"); fw.SetColumnName(2, "Latitude"); fw.SetColumnName(3, "u, cm/s"); fw.SetColumnName(4, "v, cm/s"); fw.SetColumnName(5, "Div, (cm/s)/km"); fw.SetColumnName(6, "Rot, (cm/s)/km"); fw.SetColumnName(7, "Okubo-Weiss parameter, (cm^2/s^2)/km^2"); fw.SetColumnName(8, "Kinetic energy, cm^2/s^2"); fw.SetColumnName(9, "Eddy kinetic energy, cm^2/s^2"); 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.U(i) == data.Fillval() ? NAN : data.U(i)); fw.Write(data.V(i) == data.Fillval() ? NAN : data.V(i)); fw.Write(data.Div(i) == data.Fillval() ? NAN : data.Div(i)); fw.Write(data.Rot(i) == data.Fillval() ? NAN : data.Rot(i)); fw.Write(data.OW(i) == data.Fillval() ? NAN : data.OW(i)); fw.Write(data.U2(i) == data.Fillval() ? NAN : data.U2(i)); fw.Write((data.U(i) == data.Fillval() || data.V(i) == data.Fillval()) ? NAN : (data.U2(i) - (data.U(i) * data.U(i) + data.V(i) * data.V(i)))); } fw.Finalize(); fw.Close(); } // Filtered vectors file name = args.contains("velout") ? args.at("velout") : ""; if(name.Exist()) { size_t shiftx = args.contains("shiftx") ? args.at("shiftx").ToInteger() : 0; size_t shifty = args.contains("shifty") ? args.at("shifty").ToInteger() : 0; size_t skipx = args.contains("skipx") ? args.at("skipx").ToInteger() : 1; size_t skipy = args.contains("skipy") ? args.at("skipy").ToInteger() : 1; BFileW vel; vel.Create(name, 4); vel.SetColumnName(1, "Longitude"); vel.SetColumnName(2, "Latitude"); vel.SetColumnName(3, "u, cm/s"); vel.SetColumnName(4, "v, cm/s"); for(size_t ix = shiftx; ix < data.Nx(); ix += skipx) for(size_t iy = shifty; iy < data.Ny(); iy += skipy) { vel.Write(data.Lon(ix, iy)); vel.Write(data.Lat(ix, iy)); vel.Write(data.U(ix, iy) == data.Fillval() ? NAN : data.U(ix, iy)); vel.Write(data.V(ix, iy) == data.Fillval() ? NAN : data.V(ix, iy)); } vel.Finalize(); vel.Close(); } // Stationary points name = args.contains("stpout") ? args.at("stpout") : ""; if(name.Exist()) { BFileW stp; stp.Create(name, 3); stp.SetColumnName(1, "Longitude"); stp.SetColumnName(2, "Latitude"); stp.SetColumnName(3, "Stability (0 - saddle, 1 - st. anticicl. focus, 2 - st. knot, 3 - unst. anticicl. focus, 4 - unst. knot, 5 - st. cicl. focus, 6 - unst. cicl. focus)"); for(size_t ix = 0; ix < data.Nx() - 1; ix++) for(size_t iy = 0; iy < data.Ny() - 1; iy++) { auto points = data.StablePoints(ix, iy); for(size_t i = 0; i < points.size(); i++) { stp.Write(points[i].x); stp.Write(points[i].y); stp.Write(michlib::int_cast(points[i].type)); } } stp.Finalize(); stp.Close(); } return ""; };