mirror of
https://github.com/aportelli/LatAnalyze.git
synced 2025-04-10 19:20:44 +01:00
first implementation of the plotting module
This commit is contained in:
parent
c62555aa09
commit
db61c7ea90
@ -37,16 +37,16 @@ using namespace Latan;
|
|||||||
using namespace Exceptions;
|
using namespace Exceptions;
|
||||||
|
|
||||||
// logic errors
|
// logic errors
|
||||||
CONST_EXC(Logic, logic_error(ERR_PREF+msg+ERR_SUFF))
|
CONST_EXC(Logic, logic_error(ERR_PREF + msg + ERR_SUFF))
|
||||||
CONST_EXC(Definition, Logic("definition error: "+msg,loc))
|
CONST_EXC(Definition, Logic("definition error: " + msg, loc))
|
||||||
CONST_EXC(Implementation, Logic("implementation error: "+msg,loc))
|
CONST_EXC(Implementation, Logic("implementation error: " + msg, loc))
|
||||||
CONST_EXC(Range, Logic("range error: "+msg,loc))
|
CONST_EXC(Range, Logic("range error: " + msg, loc))
|
||||||
CONST_EXC(Size, Logic("size error: "+msg,loc))
|
CONST_EXC(Size, Logic("size error: " + msg, loc))
|
||||||
// runtime errors
|
// runtime errors
|
||||||
CONST_EXC(Runtime, runtime_error(ERR_PREF+msg+ERR_SUFF))
|
CONST_EXC(Runtime, runtime_error(ERR_PREF + msg + ERR_SUFF))
|
||||||
CONST_EXC(Compilation, Runtime("compilation error: "+msg,loc))
|
CONST_EXC(Compilation, Runtime("compilation error: " + msg, loc))
|
||||||
CONST_EXC(Io, Runtime("IO error: "+msg,loc))
|
CONST_EXC(Io, Runtime("IO error: " + msg, loc))
|
||||||
CONST_EXC(Parsing, Runtime(msg,loc))
|
CONST_EXC(Parsing, Runtime(msg, loc))
|
||||||
CONST_EXC(Program, Runtime(msg,loc))
|
CONST_EXC(Program, Runtime(msg, loc))
|
||||||
CONST_EXC(Syntax, Runtime("syntax error: "+msg,loc))
|
CONST_EXC(Syntax, Runtime("syntax error: " + msg, loc))
|
||||||
|
CONST_EXC(System, Runtime("system error: " + msg, loc))
|
||||||
|
@ -25,9 +25,9 @@
|
|||||||
#include <latan/Global.hpp>
|
#include <latan/Global.hpp>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#define SRC_LOC strFrom<const char*>(__FUNCTION__) + " at "\
|
#define SRC_LOC strFrom(__FUNCTION__) + " at " + strFrom(__FILE__) + ":"\
|
||||||
+ strFrom<const char*>(__FILE__) + ":" + strFrom<int>(__LINE__)
|
+ strFrom(__LINE__)
|
||||||
#define LATAN_ERROR(exc,msg) throw(Exceptions::exc(msg,SRC_LOC))
|
#define LATAN_ERROR(exc,msg) throw(Exceptions::exc(msg, SRC_LOC))
|
||||||
|
|
||||||
#define DECL_EXC(name, base) \
|
#define DECL_EXC(name, base) \
|
||||||
class name: public base\
|
class name: public base\
|
||||||
@ -53,6 +53,7 @@ namespace Exceptions
|
|||||||
DECL_EXC(Parsing, Runtime);
|
DECL_EXC(Parsing, Runtime);
|
||||||
DECL_EXC(Program, Runtime);
|
DECL_EXC(Program, Runtime);
|
||||||
DECL_EXC(Syntax, Runtime);
|
DECL_EXC(Syntax, Runtime);
|
||||||
|
DECL_EXC(System, Runtime);
|
||||||
}
|
}
|
||||||
|
|
||||||
END_NAMESPACE
|
END_NAMESPACE
|
||||||
|
@ -38,6 +38,7 @@ liblatan_la_SOURCES = \
|
|||||||
MathInterpreter.cpp \
|
MathInterpreter.cpp \
|
||||||
MathParser.ypp \
|
MathParser.ypp \
|
||||||
MathLexer.lpp \
|
MathLexer.lpp \
|
||||||
|
Plot.cpp \
|
||||||
Sample.cpp \
|
Sample.cpp \
|
||||||
../config.h
|
../config.h
|
||||||
liblatan_ladir = $(pkgincludedir)
|
liblatan_ladir = $(pkgincludedir)
|
||||||
@ -50,6 +51,8 @@ liblatan_la_HEADERS = \
|
|||||||
Mat.hpp \
|
Mat.hpp \
|
||||||
Math.hpp \
|
Math.hpp \
|
||||||
MathInterpreter.hpp \
|
MathInterpreter.hpp \
|
||||||
|
ParserState.hpp \
|
||||||
|
Plot.hpp \
|
||||||
Sample.hpp
|
Sample.hpp
|
||||||
liblatan_la_CFLAGS = $(COM_CFLAGS)
|
liblatan_la_CFLAGS = $(COM_CFLAGS)
|
||||||
liblatan_la_CXXFLAGS = $(COM_CXXFLAGS)
|
liblatan_la_CXXFLAGS = $(COM_CXXFLAGS)
|
||||||
|
247
latan/Plot.cpp
Normal file
247
latan/Plot.cpp
Normal file
@ -0,0 +1,247 @@
|
|||||||
|
/*
|
||||||
|
* Plot.cpp, part of LatAnalyze 3
|
||||||
|
*
|
||||||
|
* Copyright (C) 2013 - 2014 Antonin Portelli
|
||||||
|
*
|
||||||
|
* LatAnalyze 3 is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* LatAnalyze 3 is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with LatAnalyze 3. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#define _POSIX_C_SOURCE 199209L
|
||||||
|
|
||||||
|
#include <latan/Plot.hpp>
|
||||||
|
#include <latan/includes.hpp>
|
||||||
|
|
||||||
|
using namespace std;
|
||||||
|
using namespace Latan;
|
||||||
|
|
||||||
|
/******************************************************************************
|
||||||
|
* PlotCommand implementation *
|
||||||
|
******************************************************************************/
|
||||||
|
// constructors ////////////////////////////////////////////////////////////////
|
||||||
|
PlotCommand::PlotCommand(void)
|
||||||
|
{}
|
||||||
|
|
||||||
|
PlotCommand::PlotCommand(const string &command)
|
||||||
|
: command_(command)
|
||||||
|
{}
|
||||||
|
|
||||||
|
// destructor //////////////////////////////////////////////////////////////////
|
||||||
|
PlotCommand::~PlotCommand(void)
|
||||||
|
{}
|
||||||
|
|
||||||
|
// access //////////////////////////////////////////////////////////////////////
|
||||||
|
const std::string & PlotCommand::getCommand(void) const
|
||||||
|
{
|
||||||
|
return command_;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/******************************************************************************
|
||||||
|
* Plot implementation *
|
||||||
|
******************************************************************************/
|
||||||
|
// constructor /////////////////////////////////////////////////////////////////
|
||||||
|
Plot::Plot(void)
|
||||||
|
: gnuplotBin_(GNUPLOT_BIN)
|
||||||
|
, gnuplotArgs_(GNUPLOT_ARGS)
|
||||||
|
, gnuplotPath_("")
|
||||||
|
, terminal_("")
|
||||||
|
, title_("")
|
||||||
|
{
|
||||||
|
scaleMode_[Axis::x] = 0;
|
||||||
|
scaleMode_[Axis::y] = 0;
|
||||||
|
scale_[Axis::x].min = 0.0;
|
||||||
|
scale_[Axis::x].max = 0.0;
|
||||||
|
scale_[Axis::y].min = 0.0;
|
||||||
|
scale_[Axis::y].max = 0.0;
|
||||||
|
label_[Axis::x] = "";
|
||||||
|
label_[Axis::y] = "";
|
||||||
|
}
|
||||||
|
|
||||||
|
// destructor //////////////////////////////////////////////////////////////////
|
||||||
|
Plot::~Plot(void)
|
||||||
|
{
|
||||||
|
while (!tmpFileName_.empty())
|
||||||
|
{
|
||||||
|
if (remove(tmpFileName_.top().c_str()))
|
||||||
|
{
|
||||||
|
LATAN_ERROR(System, "impossible to remove temporary file '" +
|
||||||
|
tmpFileName_.top() + "'");
|
||||||
|
}
|
||||||
|
tmpFileName_.pop();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// plot objects ////////////////////////////////////////////////////////////////
|
||||||
|
Plot & Plot::operator<<(const PlotCommand &command)
|
||||||
|
{
|
||||||
|
plotCommand_.push_back(command.getCommand());
|
||||||
|
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
// find gnuplot ////////////////////////////////////////////////////////////////
|
||||||
|
#define PATH_MAX_SIZE 4096
|
||||||
|
|
||||||
|
void Plot::getProgramPath(void)
|
||||||
|
{
|
||||||
|
int i, j, lg;
|
||||||
|
char *path;
|
||||||
|
static char buf[PATH_MAX_SIZE];
|
||||||
|
|
||||||
|
/* Trivial case: try in CWD */
|
||||||
|
sprintf(buf,"./%s", gnuplotBin_.c_str()) ;
|
||||||
|
if (access(buf, X_OK) == 0)
|
||||||
|
{
|
||||||
|
sprintf(buf,".");
|
||||||
|
gnuplotPath_ = buf;
|
||||||
|
}
|
||||||
|
/* Try out in all paths given in the PATH variable */
|
||||||
|
else
|
||||||
|
{
|
||||||
|
buf[0] = 0;
|
||||||
|
path = getenv("PATH") ;
|
||||||
|
if (path)
|
||||||
|
{
|
||||||
|
for (i=0;path[i];)
|
||||||
|
{
|
||||||
|
for (j=i;(path[j])&&(path[j]!=':');j++);
|
||||||
|
lg = j - i;
|
||||||
|
strncpy(buf,path + i,(size_t)(lg));
|
||||||
|
if (lg == 0)
|
||||||
|
{
|
||||||
|
buf[lg++] = '.';
|
||||||
|
}
|
||||||
|
buf[lg++] = '/';
|
||||||
|
strcpy(buf + lg, gnuplotBin_.c_str());
|
||||||
|
if (access(buf, X_OK) == 0)
|
||||||
|
{
|
||||||
|
/* Found it! */
|
||||||
|
break ;
|
||||||
|
}
|
||||||
|
buf[0] = 0;
|
||||||
|
i = j;
|
||||||
|
if (path[i] == ':') i++ ;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
LATAN_ERROR(System, "PATH variable not set");
|
||||||
|
}
|
||||||
|
/* If the buffer is still empty, the command was not found */
|
||||||
|
if (buf[0] == 0)
|
||||||
|
{
|
||||||
|
LATAN_ERROR(System, "cannot find gnuplot in $PATH");
|
||||||
|
}
|
||||||
|
/* Otherwise truncate the command name to yield path only */
|
||||||
|
lg = (int)(strlen(buf) - 1);
|
||||||
|
while (buf[lg]!='/')
|
||||||
|
{
|
||||||
|
buf[lg] = 0;
|
||||||
|
lg--;
|
||||||
|
}
|
||||||
|
buf[lg] = 0;
|
||||||
|
gnuplotPath_ = buf;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// plot parsing and output /////////////////////////////////////////////////////
|
||||||
|
void Plot::display(void)
|
||||||
|
{
|
||||||
|
std::string command;
|
||||||
|
FILE *gnuplotPipe;
|
||||||
|
|
||||||
|
if (!getenv("DISPLAY"))
|
||||||
|
{
|
||||||
|
LATAN_ERROR(System, "cannot find DISPLAY variable: is it set ?");
|
||||||
|
}
|
||||||
|
getProgramPath();
|
||||||
|
command = gnuplotPath_ + "/" + gnuplotBin_ + " " + gnuplotArgs_;
|
||||||
|
gnuplotPipe = popen(command.c_str(), "w");
|
||||||
|
if (!gnuplotPipe)
|
||||||
|
{
|
||||||
|
LATAN_ERROR(System, "error starting gnuplot (command was '" + command
|
||||||
|
+ "')");
|
||||||
|
}
|
||||||
|
commandBuffer_.str("");
|
||||||
|
commandBuffer_ << *this;
|
||||||
|
fprintf(gnuplotPipe, "%s", commandBuffer_.str().c_str());
|
||||||
|
if (pclose(gnuplotPipe) == -1)
|
||||||
|
{
|
||||||
|
LATAN_ERROR(System, "problem closing communication to gnuplot");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ostream & Latan::operator<<(ostream &out, const Plot &plot)
|
||||||
|
{
|
||||||
|
std::string begin, end;
|
||||||
|
|
||||||
|
if (!plot.terminal_.empty())
|
||||||
|
{
|
||||||
|
out << "set term " << plot.terminal_ << endl;
|
||||||
|
}
|
||||||
|
if (!plot.output_.empty())
|
||||||
|
{
|
||||||
|
out << "set output '" << plot.terminal_ << "'" << endl;
|
||||||
|
}
|
||||||
|
if (plot.scaleMode_[Plot::Axis::x] & Plot::Scale::manual)
|
||||||
|
{
|
||||||
|
out << "xMin = " << plot.scale_[Plot::Axis::x].min << endl;
|
||||||
|
out << "xMax = " << plot.scale_[Plot::Axis::x].max << endl;
|
||||||
|
}
|
||||||
|
if (plot.scaleMode_[Plot::Axis::y] & Plot::Scale::manual)
|
||||||
|
{
|
||||||
|
out << "yMin = " << plot.scale_[Plot::Axis::y].min << endl;
|
||||||
|
out << "yMax = " << plot.scale_[Plot::Axis::y].max << endl;
|
||||||
|
}
|
||||||
|
if (!plot.title_.empty())
|
||||||
|
{
|
||||||
|
out << "set title '" << plot.title_ << "'" << endl;
|
||||||
|
}
|
||||||
|
if (plot.scaleMode_[Plot::Axis::x] & Plot::Scale::manual)
|
||||||
|
{
|
||||||
|
out << "set xrange [xMin:xMax]" << endl;
|
||||||
|
}
|
||||||
|
if (plot.scaleMode_[Plot::Axis::y] & Plot::Scale::manual)
|
||||||
|
{
|
||||||
|
out << "set yrange [yMin:yMax]" << endl;
|
||||||
|
}
|
||||||
|
if (plot.scaleMode_[Plot::Axis::x] & Plot::Scale::log)
|
||||||
|
{
|
||||||
|
out << "set log x" << endl;
|
||||||
|
}
|
||||||
|
if (plot.scaleMode_[Plot::Axis::y] & Plot::Scale::log)
|
||||||
|
{
|
||||||
|
out << "set log y" << endl;
|
||||||
|
}
|
||||||
|
if (!plot.label_[Plot::Axis::x].empty())
|
||||||
|
{
|
||||||
|
out << "set xlabel '" << plot.label_[Plot::Axis::x] << "'" << endl;
|
||||||
|
}
|
||||||
|
if (!plot.label_[Plot::Axis::y].empty())
|
||||||
|
{
|
||||||
|
out << "set ylabel '" << plot.label_[Plot::Axis::y] << "'" << endl;
|
||||||
|
}
|
||||||
|
for (unsigned int i = 0; i < plot.headCommand_.size(); ++i)
|
||||||
|
{
|
||||||
|
out << plot.headCommand_[i] << endl;
|
||||||
|
}
|
||||||
|
for (unsigned int i = 0; i < plot.plotCommand_.size(); ++i)
|
||||||
|
{
|
||||||
|
begin = (i == 0) ? "plot " : " ";
|
||||||
|
end = (i == plot.plotCommand_.size() - 1) ? "" : ",\\";
|
||||||
|
out << begin << plot.plotCommand_[i] << end << endl;
|
||||||
|
}
|
||||||
|
|
||||||
|
return out;
|
||||||
|
}
|
120
latan/Plot.hpp
Normal file
120
latan/Plot.hpp
Normal file
@ -0,0 +1,120 @@
|
|||||||
|
/*
|
||||||
|
* Plot.hpp, part of LatAnalyze 3
|
||||||
|
*
|
||||||
|
* Copyright (C) 2013 - 2014 Antonin Portelli
|
||||||
|
*
|
||||||
|
* LatAnalyze 3 is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* LatAnalyze 3 is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with LatAnalyze 3. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef Latan_Plot_hpp_
|
||||||
|
#define Latan_Plot_hpp_
|
||||||
|
|
||||||
|
#include <sstream>
|
||||||
|
#include <stack>
|
||||||
|
#include <vector>
|
||||||
|
#include <latan/Global.hpp>
|
||||||
|
|
||||||
|
// gnuplot default parameters
|
||||||
|
#ifndef GNUPLOT_BIN
|
||||||
|
#define GNUPLOT_BIN "gnuplot"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef GNUPLOT_ARGS
|
||||||
|
#define GNUPLOT_ARGS "-p"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
BEGIN_NAMESPACE
|
||||||
|
|
||||||
|
/******************************************************************************
|
||||||
|
* Plot commands *
|
||||||
|
******************************************************************************/
|
||||||
|
class PlotCommand
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
// constructors/destructor
|
||||||
|
PlotCommand(void);
|
||||||
|
PlotCommand(const std::string &command);
|
||||||
|
virtual ~PlotCommand(void);
|
||||||
|
// access
|
||||||
|
virtual const std::string & getCommand(void) const;
|
||||||
|
protected:
|
||||||
|
std::string command_;
|
||||||
|
};
|
||||||
|
|
||||||
|
/******************************************************************************
|
||||||
|
* Plot class *
|
||||||
|
******************************************************************************/
|
||||||
|
|
||||||
|
class Plot
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
class Scale
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
enum
|
||||||
|
{
|
||||||
|
reset = 0,
|
||||||
|
manual = 1 << 0,
|
||||||
|
log = 1 << 1
|
||||||
|
};
|
||||||
|
};
|
||||||
|
private:
|
||||||
|
struct Range
|
||||||
|
{
|
||||||
|
double min, max;
|
||||||
|
};
|
||||||
|
class Axis
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
enum
|
||||||
|
{
|
||||||
|
x = 0,
|
||||||
|
y = 1
|
||||||
|
};
|
||||||
|
};
|
||||||
|
public:
|
||||||
|
// constructor/destructor
|
||||||
|
Plot(void);
|
||||||
|
virtual ~Plot(void);
|
||||||
|
// plot objects
|
||||||
|
Plot & operator<<(const PlotCommand &command);
|
||||||
|
// plot parsing and output
|
||||||
|
void display(void);
|
||||||
|
friend std::ostream & operator<<(std::ostream &out, const Plot &plot);
|
||||||
|
private:
|
||||||
|
// find gnuplot
|
||||||
|
void getProgramPath(void);
|
||||||
|
private:
|
||||||
|
// gnuplot execution parameters
|
||||||
|
std::string gnuplotBin_;
|
||||||
|
std::string gnuplotArgs_;
|
||||||
|
std::string gnuplotPath_;
|
||||||
|
// string buffer for commands
|
||||||
|
std::ostringstream commandBuffer_;
|
||||||
|
// stack of created temporary files
|
||||||
|
std::stack<std::string> tmpFileName_;
|
||||||
|
// plot content
|
||||||
|
std::string terminal_;
|
||||||
|
std::string output_;
|
||||||
|
std::string title_;
|
||||||
|
unsigned int scaleMode_[2];
|
||||||
|
Range scale_[2];
|
||||||
|
std::string label_[2];
|
||||||
|
std::vector<std::string> headCommand_;
|
||||||
|
std::vector<std::string> plotCommand_;
|
||||||
|
};
|
||||||
|
|
||||||
|
END_NAMESPACE
|
||||||
|
|
||||||
|
#endif // Latan_Plot_hpp_
|
@ -26,6 +26,10 @@
|
|||||||
#include <sstream>
|
#include <sstream>
|
||||||
#include <cmath>
|
#include <cmath>
|
||||||
#include <cstdarg>
|
#include <cstdarg>
|
||||||
|
#include <cstdio>
|
||||||
|
#include <cstdlib>
|
||||||
|
#include <sys/stat.h>
|
||||||
|
#include <unistd.h>
|
||||||
#include "../config.h"
|
#include "../config.h"
|
||||||
|
|
||||||
#endif // Latan_includes_hpp_
|
#endif // Latan_includes_hpp_
|
||||||
|
Loading…
x
Reference in New Issue
Block a user