Skip to content
Snippets Groups Projects
Commit 5fac61da authored by Wuttke, Joachim's avatar Wuttke, Joachim
Browse files

p2d now via g5 p

parent a9c5e135
No related branches found
No related tags found
No related merge requests found
......@@ -361,7 +361,6 @@ bool frida_command(string cmd)
"Allow iterative refinement for curve plotting",
SPloWin::instance()->current()->refine);
} else if (cmd == "gp" || cmd == "gf" || cmd == "gfa") {
const string ps_outdir = CNode::eval("psdir")->to_s();
const string ps_head = CNode::eval("pshead")->to_s();
const string ps_cont = CNode::eval("pscont")->to_s();
const string ps_dict = (cmd == "gp") ? CNode::eval("psdict")->to_s() : "";
......@@ -384,7 +383,7 @@ bool frida_command(string cmd)
}
if (fname != "")
SPloWin::instance()->current()->write_postscript(
mode, triv::wordexp_unique(fname), ps_outdir, ps_head, ps_cont, ps_dict);
mode, triv::wordexp_unique(fname), ps_head, ps_cont, ps_dict);
} else if (cmd == "gw") {
SPloWin::instance()->display_list();
} else if (sscanf(cmd.c_str(), "g%i", &i) == 1) {
......@@ -645,9 +644,6 @@ 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);
......
......@@ -58,6 +58,17 @@ int SFSel::nJ_max() const
return ret;
}
//! Return the one and only D file in the current selection.
const COld* SFSel::theOneD() const
{
vector<int> ksel = selD();
if (ksel.size()==0)
throw "No data file selected";
else if (ksel.size()>1)
throw "More than one data file selected";
return dynamic_cast<const COld*>(SMem::instance()->mem_get(ksel[0]));
}
//**************************************************************************************************
//* Write to online file selection
//**************************************************************************************************
......
......@@ -31,6 +31,7 @@ public:
vector<int> selC() const;
COlo* sel_first() const;
int nJ_max() const;
const COld* theOneD() const;
// Modify file selection:
void sel_delete();
......
......@@ -8,29 +8,43 @@
//! \brief NPlot: plot data and curves.
#include <algorithm>
#include <boost/format.hpp>
#include "defs.hpp"
#include "../plot/dualplot.hpp"
#include "../trivia/vector_ops.hpp"
#include "../trivia/file_ops.hpp" // TODO rm file creation from plot2D
#include "../plot/dualplot.hpp"
#include "config.hpp"
#include "curve.hpp"
#include "fsel.hpp"
#include "jsel.hpp"
#include "loop.hpp"
#include "expr.hpp"
#include "mem.hpp"
#include "obj.hpp"
#include "olf.hpp"
#include "plot.hpp"
#include "slice.hpp"
using boost::format;
namespace {
void determine_Xrange(CPlot* plot, vector<int>& JSel);
void determine_Yrange(CPlot* plot, vector<int>& JSel);
int plot_data(CPlot* plot, const COld* fd, int k, int j, int pstyle);
int plot_curve_convolved(CPlot* plot, const COlc* fc, int k, int j, int cstyle);
int plot_curve_to_grid(CPlot* plot, const COlc* fc, int k, int j, int cstyle);
int plot_curve_equidist(CPlot* plot, const COlc* fc, int k, int j, int cstyle);
int plot_curve_refine(CPlot* plot, const COlc* fc, int k, int j, int cstyle);
void plot1D(class CPlot* plot, bool add, const string& mode);
void plot2D(class CPlot* plot);
//**************************************************************************************************
//* Subroutines: determine data ranges
//**************************************************************************************************
//! Loop over selected data files to determine x range.
void determine_Xrange(CPlot* plot, vector<int>& JSel)
......@@ -114,7 +128,6 @@ void determine_Yrange(CPlot* plot, vector<int>& JSel)
//* Subroutines: plot one scan
//**************************************************************************************************
//! Plot slice j of data file fd; return number of points plotted.
int plot_data(CPlot* plot, const COld* fd, int k, int j, int pstyle)
......@@ -395,14 +408,13 @@ int plot_curve_refine(CPlot* plot, const COlc* fc, int k, int j, int cstyle)
return npts;
}
//**************************************************************************************************
//* Plot routine is accessible from the main menu
//* plot1D
//**************************************************************************************************
//! Plot set of spectra, or add to open plot.
void NPlot::plot(class CPlot* plot, bool add, const string& mode)
void plot1D(class CPlot* plot, bool add, const string& mode)
{
FileIterator fiter(SFSel::instance()->sel());
......@@ -438,7 +450,7 @@ void NPlot::plot(class CPlot* plot, bool add, const string& mode)
CCoord yCo = SFSel::instance()->sel_first()->yco;
// draw new frame:
plot->start_frame("Frida version " VERSION, xCo.str_ps(), yCo.str_ps());
plot->start_frame1D("Frida version " VERSION, xCo.str_ps(), yCo.str_ps());
}
// plot:
......@@ -491,3 +503,77 @@ void NPlot::plot(class CPlot* plot, bool add, const string& mode)
}
plot->show_specs();
}
//**************************************************************************************************
//* plot2D
//**************************************************************************************************
//! Plot all spectra as 2D color plot
void plot2D(class CPlot* plot)
{ // EMBEDDED DIALOG
const COld* fd = SFSel::instance()->theOneD();
size_t m = fd->nJ();
if (m<2)
throw "2d plot requires at least 2 slices";
// determine bin limits
vector<double> zval = fd->zvec(0)->to_rvec();
vector<double> zlim = triv::histogram_limits(zval);
vector<double> xlim = triv::histogram_limits(fd->VS(0)->x);
double xinf = xlim.front();
double xsup = xlim.back();
double yinf, ysup;
triv::getMinMax(fd->VS(0)->y, yinf, ysup);
for (size_t j=1; j<m; ++j) {
xlim = triv::histogram_limits(fd->VS(j)->x);
xinf = std::min(xinf, xlim.front());
xsup = std::max(xsup, xlim.back());
double yyinf, yysup;
triv::getMinMax(fd->VS(j)->y, yyinf, yysup);
yinf = std::min(yinf, yyinf);
ysup = std::max(ysup, yysup);
}
plot->X.set_limits(xinf, xsup);
plot->Z.set_limits(zlim.front(), zlim.back());
plot->Y.set_limits(yinf, ysup);
// plot
plot->start_frame2D(
"Frida version " VERSION, fd->xco.str_ps(), fd->ZCo[0].str_ps(), fd->yco.str_ps());
for (size_t j=0; j<m; ++j) {
const CSpec* s = fd->VS(j);
vector<double> xlim = triv::histogram_limits(s->x);
for (size_t i=0; i<s->size(); ++i)
plot->ps_line(
str(format("%13.7g wx %13.7g wx %13.7g wy %13.7g wy %13.7g wh t2d\n")
% xlim[i] % xlim[i+1] % zlim[j] % zlim[j+1] % s->y[i] ) );
plot->ps_line("\n");
}
// doclines
plot->doc_TxLine(fd->name);
for (int i = 0; i < fd->lDoc.size(); i++)
plot->doc_TxLine(" " + fd->lDoc[i]);
// plot -> file
const string ps_head = CNode::eval("pshead")->to_s();
const string ps_cont = CNode::eval("pscont")->to_s();
const string ps_dict = CNode::eval("psdict")->to_s();
static string fname = "~/P.ps";
plot->write_postscript(
"create", triv::wordexp_unique(fname), ps_head, ps_cont, ps_dict);
}
} // anonymous namespace
//**************************************************************************************************
//* Main plot routine accessible from the main menu
//**************************************************************************************************
void NPlot::plot(class CPlot* plot, bool add, const string& mode)
{
if (plot->p2D) {
if (add)
throw "Cannot 'add' to 2D plot";
::plot2D(plot);
} else
::plot1D(plot, add, mode);
}
......@@ -10,11 +10,11 @@
#ifndef PLOT_H
#define PLOT_H
//! Plot data and curves.
namespace NPlot
{
void plot(class CPlot* plot, bool add, const string& mode = "ask");
}
#endif // PLOT_H
......@@ -104,57 +104,3 @@ 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);
// determine and print bin limits
vector<double> zval = f->zvec(0)->to_rvec();
vector<double> zlim = triv::histogram_limits(zval);
vector<double> xlim = triv::histogram_limits(f->VS(0)->x);
double xinf = xlim.front();
double xsup = xlim.back();
double yinf, ysup;
triv::getMinMax(f->VS(0)->y, yinf, ysup);
for (size_t j=1; j<m; ++j) {
xlim = triv::histogram_limits(f->VS(j)->x);
xinf = std::min(xinf, xlim.front());
xsup = std::max(xsup, xlim.back());
double yyinf, yysup;
triv::getMinMax(f->VS(j)->y, yyinf, yysup);
yinf = std::min(yinf, yyinf);
ysup = std::max(ysup, yysup);
}
ofs << ( format("0 %13.7g %13.7g xSetCoord\n") % xinf % xsup );
ofs << ( format("0 %13.7g %13.7g ySetCoord\n") % zlim.front() % zlim.back() );
ofs << ( format("0 %13.7g %13.7g hSetCoord\n") % yinf % ysup );
// print bins
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 wy %13.7g wy %13.7g wh t2d\n")
% xlim[i] % xlim[i+1] % zlim[j] % zlim[j+1] % s->y[i] );
ofs << "\n";
}
ofs.close();
}
}
......@@ -20,7 +20,6 @@ namespace NSpecial
{
void FourierCosine();
void Test();
void export_p2d(bool allow_overwrite);
template <typename T> complex<T> pssc(T z)
{
......
......@@ -99,12 +99,21 @@ void CPlot::set_aux(const string& cmd)
}
//! Plot coordinate frame (axes, ticks, labels).
//! Clear 1D plot canvas, and plot coordinate frame (axes, ticks, labels).
void CPlot::start_frame(const string& caller, const string& xlabel, const string& ylabel)
void CPlot::start_frame1D(const string& caller, const string& xlabel, const string& ylabel)
{
gnuPlotter->start_frame(X, Y);
ps_Plotter->start_frame(caller, X, Y, xlabel, ylabel);
ps_Plotter->start_frame1D(caller, X, Y, xlabel, ylabel);
}
//! Clear 2D plot canvas, and plot coordinate frame (axes, ticks, labels).
void CPlot::start_frame2D(
const string& caller, const string& xlabel, const string& zlabel, const string& ylabel)
{
ps_Plotter->start_frame2D(caller, X, Y, Z, xlabel, ylabel, zlabel);
}
......@@ -123,6 +132,12 @@ void CPlot::add_spec(
style_no, xp, yp, dyp, zentries, xco, yco, info);
}
//! Plot one bin of 2D plot.
void CPlot::ps_line(const string& line)
{
ps_Plotter->main_line(line);
}
void CPlot::show_specs()
{
gnuPlotter->show_specs();
......@@ -155,10 +170,11 @@ void CPlot::doc_CvTxLine(const string& line, int num)
//! Write buffered plot to postscript file.
void CPlot::write_postscript(
const string& mode, const string& fname, const string& ps_outdir,
const string& mode, const string& fname,
const string& ps_head, const string& ps_cont, const string& ps_dict)
{
ps_Plotter->write_postscript(mode, fname, ps_outdir, ps_head, ps_cont, ps_dict);
ps_Plotter->copy_header(mode, fname, ps_head, ps_cont, ps_dict);
ps_Plotter->write_data(fname);
}
//! Info line to characterize this plot window.
......
......@@ -34,19 +34,23 @@ public:
bool refine; //!< Refine curve plot when appropriate?
void gp_write(const std::string& in);
void start_frame(const std::string& caller,
const std::string& xlabel, const std::string& ylabel);
void start_frame1D(
const std::string& caller, const std::string& xlabel, const std::string& ylabel);
void start_frame2D(
const std::string& caller, const std::string& xlabel, const std::string& zlabel,
const std::string& ylabel);
void add_spec(
bool as_line, bool new_slice, int style_no, const std::vector<double>& xp,
const std::vector<double>& yp, const std::vector<double>& dyp,
const std::vector<std::string>& zentries, const std::string& xco, const std::string& yco,
const std::string& info);
void ps_line(const std::string& line);
void show_specs();
void doc_TxLine(const std::string& line);
void doc_PtTxLine(const std::string& line, int num);
void doc_CvTxLine(const std::string& line, int num);
void write_postscript(
const std::string& mode, const std::string& fname, const std::string& ps_outdir,
const std::string& mode, const std::string& fname,
const std::string& ps_head, const std::string& ps_cont, const std::string& ps_dict);
void set_aux(const std::string& cmd);
std::string info() const;
......
......@@ -24,8 +24,11 @@ using boost::format;
namespace {
string ps_ticktack(
const vector<double>& Tacks, const int ntpt, const double* ticklim, const CAxis* A);
string ps_frame(
const CAxis* X, const CAxis* Y, const string& xlabel, const string& ylabel);
string ps_coord(const CAxis* A, const char a);
string ps_axis(const CAxis* A, const string& label, const char a);
string ps_horiz();
string ps_verti();
string ps_colorscale();
string ps_slice_header(
bool as_line, int slice_no, int style_no, const vector<string>& zentries,
const string& xco, const string& yco);
......@@ -36,16 +39,41 @@ namespace {
const string& fname, const string& doc_lines);
}
void CPS_Plotter::start_frame(
void CPS_Plotter::start_frame1D(
const string& caller, const CAxis& _X, const CAxis& _Y,
const string& xlabel, const string& ylabel)
{
p2D = false;
X = &_X;
Y = &_Y;
ps_snum = 0;
ps_Doc = "";
ps_accu = "\n%% output created by " + caller + "\n\n";
ps_accu += ps_frame(X, Y, xlabel, ylabel);
ps_accu += ps_coord(X, 'x');
ps_accu += ps_coord(Y, 'y');
ps_accu += ps_axis(X, xlabel, 'x') + ps_horiz();
ps_accu += ps_axis(Y, ylabel, 'y') + ps_verti();
ps_accu += "plotbefore\n\n";
}
void CPS_Plotter::start_frame2D(
const std::string& caller, const CAxis& _X, const CAxis& _Z, const CAxis& _Y,
const std::string& xlabel, const std::string& zlabel, const std::string& ylabel)
{
p2D = true;
X = &_X;
Z = &_Z;
Y = &_Y;
ps_snum = 0;
ps_Doc = "";
ps_accu = "\n%% output created by " + caller + "\n\n";
ps_accu += ps_coord(X, 'x');
ps_accu += ps_coord(Z, 'y');
ps_accu += ps_coord(Y, 'h');
ps_accu += ps_axis(X, xlabel, 'x') + ps_horiz();
ps_accu += ps_axis(Z, zlabel, 'y') + ps_verti();
ps_accu += ps_axis(Y, ylabel, 'h') + ps_colorscale();
ps_accu += "plotbefore\n\n";
}
void CPS_Plotter::add_spec(
......@@ -64,13 +92,18 @@ void CPS_Plotter::add_spec(
ps_accu += ps_data_block(X, Y, xp, yp, dyp);
}
void CPS_Plotter::main_line(const string& line)
{
ps_accu += line + "\n";
}
void CPS_Plotter::doc_line(const string& line)
{
ps_Doc += line + "\n";
}
void CPS_Plotter::write_postscript(
const string& mode, const string& fname, const string& ps_outdir,
void CPS_Plotter::copy_header(
const string& mode, const string& fname,
const string& ps_head, const string& ps_cont, const string& ps_dict)
{
// copy headers to output file
......@@ -90,7 +123,10 @@ void CPS_Plotter::write_postscript(
cmd = "cat " + ps_dict + " " + ps_head + " > " + fname;
}
triv::system(cmd);
}
void CPS_Plotter::write_data(const string& fname)
{
// append specific output to output file:
if (!triv::file_exists(fname))
throw "BUG: after copying headers, graphic output file " + fname + " still doesn't exist";
......@@ -137,42 +173,48 @@ namespace {
return ret;
}
string ps_frame(
const CAxis* X, const CAxis* Y, const string& xlabel, const string& ylabel)
string ps_coord(const CAxis* A, const char a)
{
string ret;
ret += str(format("%1i %g %g xSetCoord\n") % X->logflag % X->inf % X->sup);
ret += str(format("%1i %g %g ySetCoord\n") % Y->logflag % Y->inf % Y->sup);
return str(format("%1i %g %g %cSetCoord\n") % A->logflag % A->inf % A->sup % a);
}
string ps_axis(const CAxis* A, const string& label, const char a)
{
string ret;
int ntpt;
double ticklim[2];
vector<double> Tacks;
ret += "\n";
ret += "/xPlotFrame {\n";
if (X->logflag && X->inf <= 0)
throw "BUG: x log incompatible with limits " + X->str();
X->calc_ticks(Tacks, &ntpt, ticklim);
ret += ps_ticktack(Tacks, ntpt, ticklim, X);
ret += " {(" + xlabel + ")}\n";
ret +=
ret += "/" + string(1,a) + "PlotFrame {\n";
if (A->logflag && A->inf <= 0)
throw "BUG: log incompatible with limits " + A->str();
A->calc_ticks(Tacks, &ntpt, ticklim);
ret += ps_ticktack(Tacks, ntpt, ticklim, A);
ret += " {(" + label + ")}\n";
return ret;
}
string ps_horiz()
{
return
" 0 10 0 0 0 90 OneAxx Axx Tic Tac xNumL %% low x axis\n"
" 0 10 0 10 0 270 OneAxx Axx Tic Tac %% top x axis\n"
" xCL\n"
"} def\n\n";
}
ret += "/yPlotFrame {\n";
if (Y->logflag && Y->inf <= 0)
throw "BUG: y log incompatible with limits " + Y->str();
Y->calc_ticks(Tacks, &ntpt, ticklim);
ret += ps_ticktack(Tacks, ntpt, ticklim, Y);
ret += " {(" + ylabel + ")}\n";
ret +=
string ps_verti()
{
return
" 0 10 0 0 90 0 OneAxx Axx Tic Tac yNumL %% left y axis\n"
" 0 10 10 0 90 180 OneAxx Axx Tic Tac %% right y axis\n"
" yCL\n"
"} def\n\n"
"plotbefore\n\n";
return ret;
"} def\n\n";
}
string ps_colorscale()
{
return "%TODO colorscale\n";
}
string ps_slice_header(
......
......@@ -17,20 +17,28 @@ public:
CPS_Plotter() {}
CPS_Plotter(CPS_Plotter const&) = delete;
CPS_Plotter& operator=(CPS_Plotter const&) = delete;
void start_frame(const std::string& caller, const CAxis& _X, const CAxis& _Y,
void start_frame1D(
const std::string& caller, const CAxis& _X, const CAxis& _Y,
const std::string& xlabel, const std::string& ylabel);
void start_frame2D(
const std::string& caller, const CAxis& _X, const CAxis& _Z, const CAxis& _Y,
const std::string& xlabel, const std::string& zlabel, const std::string& ylabel);
void add_spec(
bool as_line, bool new_slice, int style_no,
const std::vector<double>& xp, const std::vector<double>& yp,
const std::vector<double>& dyp, const std::vector<std::string>& zentries,
const std::string& xco, const std::string& yco, const std::string& info);
void main_line(const std::string& line);
void doc_line(const std::string& line);
void write_postscript(
const std::string& mode, const std::string& fname, const std::string& ps_outdir,
void copy_header(
const std::string& mode, const std::string& fname,
const std::string& ps_head, const std::string& ps_cont, const std::string& ps_dict);
void write_data(const std::string& fname);
private:
bool p2D;
const CAxis* X;
const CAxis* Y;
const CAxis* Z;
int ps_snum; //!< Slice number in Postscript file.
std::string ps_accu; //!< Main Postscript cache.
std::string ps_Doc; //!< Special Postscript cache for doc lines ?.
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment