diff --git a/pub/lib/commands.cpp b/pub/lib/commands.cpp index c29c2ef0de8553ffd9720f7f0573478575bf32b5..2e9c15ca77fd3214c5d8d61acc3932681d335e3b 100644 --- a/pub/lib/commands.cpp +++ b/pub/lib/commands.cpp @@ -639,6 +639,9 @@ bool frida_command(string cmd) } else if (cmd == "_t") { NSpecial::Test(); + } else if (cmd == "p2d") { // new after 2.3.6b, undocumented + NSpecial::export_p2d(SMem::instance()->overwrite); + } else if (cmd == "qui" || cmd == "quit") { exit(0); diff --git a/pub/lib/file_out.cpp b/pub/lib/file_out.cpp index ecc0a6c1907f6f7c9c0d2961da4a6db9816ab6e0..74d74cecf748b11ad1b122496f1e9480dda2df5b 100644 --- a/pub/lib/file_out.cpp +++ b/pub/lib/file_out.cpp @@ -13,6 +13,7 @@ #include <yaml-cpp/yaml.h> #include "../readplus/ask.hpp" +#include "../trivia/file_ops.hpp" #include "../trivia/yaml_out.hpp" #include "file_out.hpp" @@ -47,13 +48,8 @@ void NFileOut::save(string fmt, bool allow_overwrite) // document file save f->log_action("fs " + outfnam + " # " + triv::time2strg(time(0))); // prevent unintended overwriting - if (!allow_overwrite) { - FILE* file; - if ((file = fopen(outfnam.c_str(), "r"))) { - fclose(file); - throw "file " + outfnam + " exists, use fso to overwrite"; - } - } + if (!allow_overwrite && triv::file_exists(outfnam)) + throw "file " + outfnam + " exists, use command modifier '!' to overwrite"; // save file if (fmt == "yda") { std::ofstream ofs; diff --git a/pub/lib/obj.cpp b/pub/lib/obj.cpp index 8849ff28ec9274a04deaf2086e5b1415a7d4bfa6..8ede1c5f3f634f15792d11692a74281974badfd2 100644 --- a/pub/lib/obj.cpp +++ b/pub/lib/obj.cpp @@ -158,6 +158,14 @@ string CObjVecObj::to_s(int maxlen, int minlen, int prec) const return ret; } +vector<double> CObjVecObj::to_rvec() const +{ + vector<double> ret(size()); + for (int i = 0; i < v.size(); ++i) + ret[i] = v[i]->to_r(); + return ret; +} + //************************************************************************************************** // CObjVecInt //************************************************************************************************** diff --git a/pub/lib/obj.hpp b/pub/lib/obj.hpp index 9a8e6f1abcb29067dbdb3947326e58cd602365b3..63eb78f2208cae3d167dae855a55780f51b9f9e3 100644 --- a/pub/lib/obj.hpp +++ b/pub/lib/obj.hpp @@ -153,6 +153,7 @@ public: inline string result_info() const { return to_s(); } inline RObj to_obj(int i) const { return v[i]; } string to_s(int maxlen = 12, int minlen = 1, int prec = 6) const; + vector<double> to_rvec() const; RObj to_vecnum() const; }; diff --git a/pub/lib/olf.cpp b/pub/lib/olf.cpp index 91d4aab2538262633e13451c086cc3202de2d303..fbff309b4efb3db1c3cc95925a64a17b20955474 100644 --- a/pub/lib/olf.cpp +++ b/pub/lib/olf.cpp @@ -102,6 +102,14 @@ void COlo::check_integrity() const RObj COlo::z(int j, int iz) const { return V[j]->z[iz]; } +//! Return vector of iz-th z-variables. + +RObjVecObj COlo::zvec(int iz) const { + PObjVecObj ret(new CObjVecObj(nJ())); + for (size_t j=0; j<nJ(); ++j) + ret->v[j] = V[j]->z[iz]; + return ret; +} //************************************************************************************************** //* COld/COlc (member functions that are similar for both classes) diff --git a/pub/lib/olf.hpp b/pub/lib/olf.hpp index a311cc29c3c9c113eaf93fd909df150ed66556b7..493d0acca7d002b393d0a29a041dc9d6557025e3 100644 --- a/pub/lib/olf.hpp +++ b/pub/lib/olf.hpp @@ -47,6 +47,7 @@ public: int nJ() const { return V.size(); } int nZ() const { return ZCo.size(); } RObj z(int j, int iz) const; + RObjVecObj zvec(int iz) const; virtual PSlice copy_slice(int j) const = 0; virtual POlo new_POlo() const = 0; virtual CCoord coord(const CGenus& genus) const = 0; diff --git a/pub/lib/special.cpp b/pub/lib/special.cpp index cf8eba150c371b191203fbd038e3c0f6e71ebde9..70b3708453079ff12757131bdd43cbad27df79ef 100644 --- a/pub/lib/special.cpp +++ b/pub/lib/special.cpp @@ -9,10 +9,14 @@ #include "defs.hpp" - +#include <fstream> +#include <vector> #include <fftw3.h> +#include <boost/format.hpp> - +#include "../trivia/file_ops.hpp" +#include "../trivia/vector_ops.hpp" +#include "../readplus/ask.hpp" #include "fsel.hpp" #include "loop.hpp" #include "mem.hpp" @@ -21,6 +25,9 @@ #include "slice.hpp" #include "special.hpp" +using boost::format; +using std::vector; + namespace NSpecial { void q_eval(double* par, int m_dat, double* fvec, void* data, int* info); @@ -97,3 +104,38 @@ void NSpecial::Test() } SMem::instance()->mem_store(move(fout)); } + +//! Experimental 2d plot + +void NSpecial::export_p2d(bool allow_overwrite) +{ // EMBEDDED_DIALOG + string outfnam; + FileIterator fiter(SFSel::instance()->selD()); + while (COld* f = fiter.nextD()) { + size_t m = f->nJ(); + if (m<2) + throw "2d plot requires at least 2 slices"; + // query output file name + outfnam = wask("Export to (.p2d)", f->name); + if (outfnam == "") + return; + f->name = outfnam; + outfnam += ".p2d"; + // document file save + if (!allow_overwrite && triv::file_exists(outfnam)) + throw "file " + outfnam + " exists, use flag ! to overwrite"; + std::ofstream ofs; + ofs.open(outfnam, std::ofstream::out); + vector<double> zval = f->zvec(0)->to_rvec(); + vector<double> zlim = triv::histogram_limits(zval); + for (size_t j=0; j<m; ++j) { + const CSpec* s = f->VS(j); + vector<double> xlim = triv::histogram_limits(s->x); + for (size_t i=0; i<s->size(); ++i) + ofs << ( format("%13.7g wx %13.7g wx %13.7g wz %13.7g wz %13.7g wy p2d\n") + % xlim[i] % xlim[i+1] % zlim[j] % zlim[j+1] % s->y[i] ); + ofs << "\n"; + } + ofs.close(); + } +} diff --git a/pub/lib/special.hpp b/pub/lib/special.hpp index 192da96e96e61e33c10b400f7ed7f1e9b12195c7..1bd69fe62126dbd21227779260d71c16befc7779 100644 --- a/pub/lib/special.hpp +++ b/pub/lib/special.hpp @@ -20,6 +20,7 @@ namespace NSpecial { void FourierCosine(); void Test(); +void export_p2d(bool allow_overwrite); template <typename T> complex<T> pssc(T z) {