From a4de122efcdb24ffeaa5155fe29b3b0179a643a7 Mon Sep 17 00:00:00 2001 From: "Joachim Wuttke (laptop)" <j.wuttke@fz-juelich.de> Date: Fri, 26 Mar 2010 10:04:46 +0100 Subject: [PATCH] cleanup (edif.cpp partly -> plot.cpp; plotaux.cpp merged ->dualplot.cpp) --- pub/src/Makefile.am | 6 +- pub/src/Makefile.in | 5 +- pub/src/coord.cpp | 2 +- pub/src/dualplot.cpp | 238 ++++++++++++++-------- pub/src/dualplot.h | 13 +- pub/src/edif.cpp | 442 +---------------------------------------- pub/src/edif.h | 34 ++-- pub/src/frida2.cpp | 35 ++-- pub/src/manip.cpp | 1 - pub/src/mystd.cpp | 8 - pub/src/mystd.h | 5 - pub/src/plot.cpp | 463 +++++++++++++++++++++++++++++++++++++++++++ pub/src/plot.h | 3 + pub/src/plotaux.cpp | 138 ------------- pub/src/plotaux.h | 6 - pub/src/rssm.cpp | 1 + 16 files changed, 666 insertions(+), 734 deletions(-) create mode 100644 pub/src/plot.cpp create mode 100644 pub/src/plot.h delete mode 100644 pub/src/plotaux.cpp delete mode 100644 pub/src/plotaux.h diff --git a/pub/src/Makefile.am b/pub/src/Makefile.am index 5efbad83..8fce6fea 100644 --- a/pub/src/Makefile.am +++ b/pub/src/Makefile.am @@ -44,8 +44,8 @@ olm.cpp \ olm.h \ opr.cpp \ opr.h \ -plotaux.cpp \ -plotaux.h \ +plot.cpp \ +plot.h \ rng.cpp \ rng.h \ rssm.cpp \ @@ -57,7 +57,7 @@ special.h \ xax_lex.h \ xax_lex.lpp \ xax_yacc.ypp -AM_LDFLAGS = -lboost_regex -lread-plus -llmmin -lkww -lyaml-cpp +AM_LDFLAGS = -lboost_regex -lread-plus -llmmin -lkww -lyaml-cpp # frida2_LDADD $(BOOST_REGEX_LIB) # -lyaml-cpp diff --git a/pub/src/Makefile.in b/pub/src/Makefile.in index ffdfcf5c..08957b30 100644 --- a/pub/src/Makefile.in +++ b/pub/src/Makefile.in @@ -57,7 +57,7 @@ am_frida2_OBJECTS = coord.$(OBJEXT) curve.$(OBJEXT) dualplot.$(OBJEXT) \ edif.$(OBJEXT) expr.$(OBJEXT) file_in.$(OBJEXT) \ file_out.$(OBJEXT) frida2.$(OBJEXT) func.$(OBJEXT) \ index.$(OBJEXT) list.$(OBJEXT) manip.$(OBJEXT) mystd.$(OBJEXT) \ - olm.$(OBJEXT) opr.$(OBJEXT) plotaux.$(OBJEXT) rng.$(OBJEXT) \ + olm.$(OBJEXT) opr.$(OBJEXT) rng.$(OBJEXT) \ rssm.$(OBJEXT) spec.$(OBJEXT) special2.$(OBJEXT) \ xax_lex.$(OBJEXT) xax_yacc.$(OBJEXT) frida2_OBJECTS = $(am_frida2_OBJECTS) @@ -266,8 +266,6 @@ olm.cpp \ olm.h \ opr.cpp \ opr.h \ -plotaux.cpp \ -plotaux.h \ rng.cpp \ rng.h \ rssm.cpp \ @@ -389,7 +387,6 @@ distclean-compile: @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/mystd.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/olm.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/opr.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/plotaux.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/rng.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/rssm.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/spec.Po@am__quote@ diff --git a/pub/src/coord.cpp b/pub/src/coord.cpp index c3552c5b..270867b3 100644 --- a/pub/src/coord.cpp +++ b/pub/src/coord.cpp @@ -45,7 +45,7 @@ char CoordDecode( const string& resp, CCoord *rval ) } if (np!=0) return 'h'; - for (i=j; i>0 && strchr(" \t",resp[i-1]); i--); + for (i=j; i>0 && strchr(" \t",resp[i-1]); i--) ; if (i==0) return 'h'; *rval = CCoord( resp.substr(0,i), resp.substr(j+1, n-j-2) ); diff --git a/pub/src/dualplot.cpp b/pub/src/dualplot.cpp index 3af4d865..8b17548c 100644 --- a/pub/src/dualplot.cpp +++ b/pub/src/dualplot.cpp @@ -9,17 +9,10 @@ #include <string.h> #include <iostream> #include <math.h> -#include <sys/types.h> -#include <sys/stat.h> -#include <unistd.h> #include <fcntl.h> #include <boost/format.hpp> #include "mystd.h" -#include "plotaux.h" -#include "coord.h" -#include <ask_simple_value.h> -#include <ask_and_callback.h> #include "dualplot.h" using boost::format; @@ -73,6 +66,17 @@ void CAxis::set_from_string( string in ) throw string( "invalid lower bound, expecting real number" ); if ( !mystd::any2dbl(s2,&sup) ) throw string( "invalid upper bound, expecting real number" ); + // check new range + if ( logflag && inf<=0 && inf!=-INFINITY ) { + setAuto(); + throw string( "log scale requires range above 0" ); + } + if (!logflag && ( ( inf!=-INFINITY && inf<-3e38 ) || + ( sup!=+INFINITY && sup>+3e38 ) ) ) { + setAuto(); + throw string( "lin scale exceeds typical PS implementation range " + "(abs<3e38)" ); + } } //! Replace limits by rounded values. @@ -182,31 +186,6 @@ string CAxis::str() const return strg(inf) + " " + strg(sup); } -//! Query and check range. - -void CAxis::Ask( string quest ) -{ - string def, in; - // query input - def = str(); - in = sask( quest, def ); - if (in==def) - return; - if (in!="") - set_from_string( in ); - // check new range - if (logflag && inf<=0 && inf!=-INFINITY) { - setAuto(); - throw string( "log scale requires range above 0" ); - } - if (!logflag && ( ( inf!=-INFINITY && inf<-3e38 ) || - ( sup!=+INFINITY && sup>+3e38 ) ) ) { - setAuto(); - throw string( "lin scale exceeds typical PS implementation range " - "(abs<3e38)" ); - } -} - //! Describe range, for use in table of plot frames. string CAxis::info() const @@ -225,6 +204,128 @@ double CAxis::pc( double v ) const return CPLOT_PSMAX * value2plotcoord( v ); } +void CAxis::calc_ticks( int *ntack, double **tack, int *ntpt, double *ticklim) + const +{ + int ir, nt, i; + double r, rd, rdr, d, vsub, vsup, tack0, tackn, dtack; + + if ( inf >= sup ) + throw "PROGRAM ERROR/ Ticks/ Bad Limits: " + + strg(inf) + ", " + strg(sup); + + if (!logflag) { + r = log10(sup - inf); + ir = (int) ((r<0) ? r-1 : r); + rd = r - ir; // fractional part of r + rdr = pow(10., rd); + if (rdr > 9.99999) { + dtack = 2.5 * pow(10., ir); // spacing between tacks + *ntpt = 5; // ticks per tack + } else if (rdr > 5.00001) { + dtack = 2 * pow(10., ir); + *ntpt = 4; + } else if (rdr > 2.500005) { + dtack = 1 * pow(10., ir); + *ntpt = 5; + } else if (rdr > 1.600003) { + dtack = .5 * pow(10., ir); + *ntpt = 5; + } else if (rdr > 1.250002) { + dtack = .4 * pow(10., ir); + *ntpt = 4; + } else { + dtack = .25 * pow(10., ir); + *ntpt = 5; + } + d = inf / dtack; + tack0 = dtack * (int) (d<=0?d-1:d); + d = sup / dtack; + tackn = dtack * ((int) (d<0?d-1:d) + 1); + vsub = inf - (sup-inf)*1.e-4; + vsup = sup + (sup-inf)*1.e-4; + nt = (int) ((tackn-tack0) / dtack) + 3; // allocate enough + *tack = (double*) malloc(sizeof(double)*nt); + *ntack = 0; + for (i=0; i<nt; i++) { + d = tack0 + i*dtack; + if (vsub<=d && d<=vsup) + (*tack)[(*ntack)++] = d; + } + + ticklim[0] = tack0; + ticklim[1] = (*tack)[(*ntack)-1] + dtack; + + } else { // log scale + + static double eins = 1.0000009999999999; + double rlgmin, rlgmax, rlgrel, d1, d2, r0; + int minexp, maxexp, incr; + + if (inf <= 0) + throw string( "PROGRAM ERROR/ Ticks/ negative log argument" ); + + rlgmin = log10(inf); + rlgmax = log10(sup); + rlgrel = rlgmax - rlgmin; + if (rlgrel > 40) + throw string( "Excessive log range" ); + + minexp = (rlgmin>0 ? + (int) (rlgmin+1e-6) : + ((int) (rlgmin-1e-6) -1)); + maxexp = (rlgmax>0 ? + (int) (rlgmax+1e-6) : + ((int) (rlgmax-1e-6) -1)); + + incr = (int) (rlgrel / 7 + 1); // #decades per tack + if (incr==2) incr = 1; // preferences: 10^1, 10^3, 10^6 etc. + if (incr>3) incr = 3 * (incr % 3); + + if (incr > 1) { + minexp -= minexp % incr; + maxexp -= maxexp % incr; + } + + /* - Set large ticks array : */ + static int mt=30; + *tack = (double*) malloc(sizeof(double)*mt); + + *ntack = 0; + d1 = inf / eins; + d2 = sup * eins; + for ( i = minexp; incr < 0 ? i >= maxexp : i <= maxexp; i += incr ) { + r0 = pow(10., i); + if (d1<=r0 && r0<=d2) { + if(*ntack>=mt) + throw string( "PROG ERR too many tacks" ); + (*tack)[(*ntack)++] = r0; + } + } + + if (*ntack >= 1) { + ticklim[0] = (*tack)[0] / pow(10., incr); + ticklim[1] = (*tack)[(*ntack)-1] * pow(10., incr); + } else { + // untested. just to allow plots when no tacks in window + ticklim[0] = pow( 10., minexp ); + ticklim[1] = pow( 10., maxexp+1 ); + } + + /** determine # ticks / tack **/ + if (incr==1 && rlgrel<=7) { + *ntpt = 9; + } else if (incr==1 && rlgrel<=7) { + *ntpt = 3; // 1-2-5-10 - Schritte + } else if (incr==1) { + *ntpt = 1; + } else { + *ntpt = -incr; + // means incr ticks per tack + // means 1 tick per decade + } + } +} //**************************************************************************// //* CPlot *// @@ -241,22 +342,18 @@ CPlot::CPlot( uint _iPlot, bool _logx, bool _logy ) : string fn_fifo = string("/tmp/gnuplot-") + getenv( "LOGNAME" ); mystd::system( "rm -f "+fn_fifo ); - if (mkfifo( fn_fifo.c_str(), 0666 )) { - printf("SEVERE SYSTEM ERROR cannot make fifo %s" - " - will not be able to print\n", fn_fifo.c_str() ); - return; - } + if (mkfifo( fn_fifo.c_str(), 0666 )) + throw "SEVERE SYSTEM ERROR cannot make fifo " + fn_fifo + + ": will not be able to print"; mystd::system( "gnuplot -title " + strg(iPlot) + " -noraise" + " < " + fn_fifo + " &" ); // we use open instead of fopen or ofstream, // because we need non-blocking mode. - if (!(gp_fifo = open(fn_fifo.c_str(), O_WRONLY))) { - printf("SEVERE SYSTEM ERROR cannot open gp_fifo" - " - will not be able to print\n"); - return; - } + if (!(gp_fifo = open(fn_fifo.c_str(), O_WRONLY))) + throw "SEVERE SYSTEM ERROR cannot open fifo " + fn_fifo + + ": will not be able to print"; fcntl(gp_fifo,F_SETFL,O_NONBLOCK); gp_write( string("set terminal x11") ); @@ -286,9 +383,7 @@ void CPlot::clearFrame() void CPlot::setAux( string cmd ) { - if ( cmd=="gnp" ) - maxpoints = iask("Max # points in plot", maxpoints); - else if ( cmd=="gxl" ) { + if ( cmd=="gxl" ) { X.setLog( !X.logflag ); printf( "set x %s\n", X.logflag ? "log" : "lin" ); } else if ( cmd=="gxl+" ) @@ -322,7 +417,7 @@ void CPlot::setAux( string cmd ) //! Plot coordinate frame (axes, ticks, labels). -void CPlot::plotFrame() +void CPlot::plotFrame( string xlabel, string ylabel ) { gp_write( "set nologscale" ); string whichlog=""; @@ -348,11 +443,10 @@ void CPlot::plotFrame() ps_accu.push_back( "\n/xPlotFrame {" ); if ( X.logflag && X.inf<= 0 ) throw "BUG: x log incompatible with limits " + X.str(); - plotaux::calc_ticks( X.logflag, X.inf, X.sup, - &ntack, &tack, &ntpt, ticklim ); + X.calc_ticks( &ntack, &tack, &ntpt, ticklim ); ps_ticktack(ntack, tack, ntpt, ticklim, &X); free(tack); - snprintf( outlin, CPLOT_LINSIZ-4, " {(%s", X.C.ps_str().c_str() ); + snprintf( outlin, CPLOT_LINSIZ-4, " {(%s", xlabel.c_str() ); strncat( outlin, ")}\n", CPLOT_LINSIZ ); ps_accu.push_back( outlin ); ps_accu.push_back( " 0 10 0 0 0 90 " @@ -365,11 +459,10 @@ void CPlot::plotFrame() ps_accu.push_back( "\n/yPlotFrame {" ); if ( Y.logflag && Y.inf<= 0 ) throw "BUG: y log incompatible with limits " + Y.str(); - plotaux::calc_ticks( Y.logflag, Y.inf, Y.sup, - &ntack, &tack, &ntpt, ticklim ); + Y.calc_ticks( &ntack, &tack, &ntpt, ticklim ); ps_ticktack(ntack, tack, ntpt, ticklim, &Y); free(tack); - snprintf( outlin, CPLOT_LINSIZ, " {(%s", Y.C.ps_str().c_str() ); + snprintf( outlin, CPLOT_LINSIZ, " {(%s", ylabel.c_str() ); strncat( outlin, ")}\n", CPLOT_LINSIZ ); ps_accu.push_back( outlin ); ps_accu.push_back( " 0 10 0 0 90 0 " @@ -481,16 +574,8 @@ void CPlot::plotDoclines( const vector<string>& lDoc ) //! Write buffered plot to postscript file. -void CPlot::writePostscript( bool full_outfile ) +void CPlot::writePostscript( string ps_outdir, string ps_head, string ps_dict ) { - string ps_outdir, ps_head, ps_dict; - - // read configuration parameters: - ps_outdir = NRead::wofmac( "\\psdir" ); - ps_head = NRead::wofmac( "\\pshead" ); - if ( full_outfile ) - ps_dict = NRead::wofmac( "\\psdict" ); - // construct output file name: FILE *pssav; string flong, cmd, outf; @@ -498,7 +583,7 @@ void CPlot::writePostscript( bool full_outfile ) if (ps_fnum>=999) throw string( "graph file number overflow" ); outf = ps_outdir + str( format( "l%d." ) % ++ps_fnum ) + - ( full_outfile ? "ps" : "psa" ); + ( ps_dict=="" ? "psa" : "ps" ); if (!(pssav = mystd::glob_fopen(outf.c_str(), "", "", "r"))) break; // legal exit fclose(pssav); @@ -506,22 +591,20 @@ void CPlot::writePostscript( bool full_outfile ) cout << "save plot in " << outf << "\n"; // copy headers to output file: - cmd = string("cat ") + ( full_outfile ? ps_dict : "" ) + " " + - ps_head + " > " + outf + "\n"; + cmd = string("cat ") + + ps_dict + " " + // ps_dict may be "" + ps_head + " > " + + outf + "\n"; mystd::system( cmd ); // a redundant check of existence of the outfile: - if (!(pssav = mystd::glob_fopen(outf.c_str(), "", "", "r", &flong))) { + if (!(pssav = mystd::glob_fopen(outf.c_str(), "", "", "r", &flong))) throw "have not created file " + outf; - return; - } fclose(pssav); // append specific output to output file: - if (!(pssav = fopen(flong.c_str(), "a+"))) { - printf ("cannot write (append) to file %s\n", flong.c_str()); - return; - } + if (!(pssav = fopen(flong.c_str(), "a+"))) + throw "cannot write (append) to file " + flong; for( uint i=0; i<ps_accu.size(); ++i ){ // fprintf does not work here because output line may contain "%" fwrite( ps_accu[i].c_str(), 1, ps_accu[i].size(), pssav ); @@ -541,19 +624,6 @@ void CPlot::writePostscript( bool full_outfile ) fclose(pssav); } -//! Endless loop: query for gnuplot commands. - -void CPlot::feedGnuplot() -{ - string cmd; - cout << "entering mygnuplot - to leave, type q\n"; - while(1) { - cmd = sask("mygnuplot> "); - if (cmd.substr(0,1)=="q") return; - gp_write(cmd); - } -} - //! Info line to characterize this plot window. string CPlot::info() const diff --git a/pub/src/dualplot.h b/pub/src/dualplot.h index 6654c636..339a18c4 100644 --- a/pub/src/dualplot.h +++ b/pub/src/dualplot.h @@ -1,8 +1,7 @@ class CAxis { public: double inf, sup; - CCoord C; - bool logflag; // 'log' is reserved for math.h + bool logflag; bool force; CAxis( bool _log ) : @@ -24,9 +23,10 @@ class CAxis { double value2plotcoord( double v ) const; double plotcoord2value( double c ) const; double inf_pos() const; + void calc_ticks( int *ntack, double **tack, int *ntpt, double *ticklim ) + const; }; - #define CPLOT_PSMAX 10 #define CPLOT_LINSIZ 80 @@ -39,7 +39,7 @@ class CPlot { CPlot( uint _iPlot, bool _logx, bool _logy ); void clearFrame(); - void plotFrame(); + void plotFrame( string xlabel, string ylabel ); void addSpec( bool as_line, int style_no, const vector<double>& xp, const vector<double>& yp, const vector<double>& dyp, @@ -47,12 +47,11 @@ class CPlot { string xco, string yco, string info ); void showSpecs(); void plotDoclines( const vector<string>& lDoc ); - void writePostscript( bool full_outfile ); + void writePostscript( string ps_outdir, string ps_head, string ps_dict ); void setAux( string cmd ); - void feedGnuplot(); string info() const; -private: // can we move this to the .cpp file ? +private: int gp_fifo; void gp_write( string ); int gp_fno; diff --git a/pub/src/edif.cpp b/pub/src/edif.cpp index 080d0333..8c418c42 100644 --- a/pub/src/edif.cpp +++ b/pub/src/edif.cpp @@ -1,6 +1,6 @@ //**************************************************************************// //* FRIDA: fast reliable interactive data analysis *// -//* edif.cpp: edit on-line files (text_edit, dir, make, plot, ...) *// +//* edif.cpp: edit on-line files (text_edit, dir, make, ...) *// //* (C) Joachim Wuttke 1990-, v2(C++) 2001- *// //* http://frida.sourceforge.net *// //**************************************************************************// @@ -10,13 +10,10 @@ #include <iostream> #include <algorithm> -using namespace std; - #include "mystd.h" #include "olm.h" #include "expr.h" #include <ask_simple_value.h> -#include "dualplot.h" #include "edif.h" #include "index.h" @@ -263,7 +260,6 @@ user_choice: } else if (choice=="" || choice=="q") { return; } else if (Choice.parse(choice, 0, AllR.size())) { - cout << mystd::BEL; goto user_choice; } @@ -312,7 +308,6 @@ user_choice: CParam(AllR[ii], val)); } } else { - cout << mystd::BEL; goto action_on_par; } // action on rpar } // list of rpars @@ -950,438 +945,3 @@ void NEdif::MakeGrid(void) NOlm::SelNew(); NOlm::OloAdd(&olf); } - -//**************************************************************************// -//* Plotting *// -//**************************************************************************// - - - -double NEdif::FindAngleCos(double x1,double y1, //point 1 - double x2,double y2, //point 2 - double x3,double y3 )//point 3 -// Li Huang mar10 -{ - /* - (1) ________(2) - \)cos - \ - \(3) - - (x1,y1), (x2,y2) - (x2,y2) and (x3,y3) - a = x2 - x1, b = y2 - y1 - c = x3 - x2, d = y3 - y2. - The so called dot product yields the equation - Cosine( Theta ) = ( (a x c) + (b x d) )/(Sqrt(a^2 + b^2) x Sqrt(c^2 + d^2) ) = Z. - */ - double a,b,c,d,cos; - a = x2 - x1; - b = y2 - y1; - c = x3 - x2; - d = y3 - y2; - cos = ( (a * c) + (b * d) )/(sqrt(a*a + b*b) * sqrt(c*c + d*d) ); - return cos; -} - -//! The next point to be plotted is returned as *xt, *yt. - -void NEdif::FindNextPoint( const COlc *fc, - double xtm, double ytm, double dx, - double* xt, double* yt, uint k, uint j ) -// Li Huang mar10 -{ - uint i = 0; - double cos123 = 0; - double cos234 = 0; - double x1 = xtm; - double y1 = ytm; - double x2 = *xt; - double y2 = *yt; - double x3,y3; - double x4,y4; - /* - /)o1__ (3) - (2)_____________ - / \)o2 - / \ - (1)/ \(4) - - (xt,yt)__________(xt+dx,yt+dx) - / \ - / \ - (xtm,ytm)/ \(xt+2*dx,yt+2*dx) - - o1 < 1/4 degree && o2 < 1/4 degree - cos(1/4 degree) = 0.99999 - */ - do{ - x3 = x2 + dx; - y3 = fc->T->tree_curve_val_sca( x3, k, j ); - x4 = x3 + dx; - y4 = fc->T->tree_curve_val_sca( x4, k, j ); - cos123 = FindAngleCos(x1,y1,x2,y2,x3,y3); - cos234 = FindAngleCos(x2,y2,x3,y3,x4,y4); - dx = dx/2; - i++; - }while ( ( cos123 < 0.99999 || cos234 < 0.99999 ) && i <= 7); - *xt = x3; - *yt = y3; -} - -void NEdif::InterY(double xtm,double ytm,double xt,double yt, - double* xtt,double *ytt,double border) -{ - *ytt = border; - *xtt = (*ytt-ytm)*(xt-xtm)/(yt-ytm)+xtm; -} - - -//! Plot spectrum. - -void NEdif::Plot( CPlot *plot, bool add ) -{ - static CList JSel; - CEle *e; - uint k, j; - const COld *fd; - const COlc *fc; - CSpec S; - vector<double> novec; - static int pstyle = 0, cstyle = 0; - static string jSel = ""; - NOlm::JSelAsk( "Plot which spectra", &jSel, &JSel ); - - if (!add) { - - pstyle = 0; - cstyle = 0; - - // determine x-range ? - - double inf, sup; - if (!plot->X.finite()) { - NOlm::IterateD fiter; - const vector<double> *vx; - bool first = true; - while((fd=fiter())) { - JSel.evaluate( 0, fd->nSpec()-1 ); - for( uint iv=0; iv<JSel.size(); ++iv ) { - vx = &( fd->VS[JSel.V[iv]].x ); - for( uint i=0; i<vx->size(); ++i ){ - if( plot->X.logflag && (*vx)[i]<=0 ) - continue; - if( first ){ - inf = (*vx)[i]; - sup = (*vx)[i]; - first = false; - } else { - if( (*vx)[i]<inf ) inf = (*vx)[i]; - if( (*vx)[i]>sup ) sup = (*vx)[i]; - } - } - } - } - if( first ) - throw string( "x range is empty" ); - plot->X.setRoundedLimits( "x", inf, sup ); - } - - // determine y-range ? - if (!plot->Y.finite()) { - bool first=true; - NOlm::IterateEle eiter; - int npts = 100; - const CSpec *s; - while( (e=eiter()) ){ - k = eiter.SelNo(); - fc = e->C(); - if( fc && fc->kconv!=-1 ) - continue; - fd = e->D(); - JSel.evaluate( 0, e->nSpec()-1 ); - for( uint iv=0; iv<JSel.size(); ++iv ){ - uint j = JSel.V[iv]; - if( fd ){ - s = &(fd->VS[j]); - } else { - S.x.resize( npts ); - for ( uint i=0; i<npts; i++ ) - S.x[i] = plot->X.plotcoord2value( i/(npts-1.0) ); - fc->T->tree_curve_val_vec( &(S.y), S.x, k, j ); - s = &S; - } - for (uint i=0; i<s->size(); i++) { - if( !plot->X.contains( s->x[i] ) ) - continue; - if( plot->Y.logflag && s->y[i]<=0 ) - continue; - if (first) { - inf=s->y[i], sup=s->y[i]; - first = false; - } else { - if (s->y[i]<inf) inf=s->y[i]; - if (s->y[i]>sup) sup=s->y[i]; - } - } - } - } - if( first ) - throw string( "y range is empty" ); - plot->Y.setRoundedLimits( "y", inf, sup ); - } - - // build label: (zur Zeit nur vom ersten File; definiere +=) - plot->X.C = NOlm::MOM[*(NOlm::FSel.V.begin())].P()->xco; - plot->Y.C = NOlm::MOM[*(NOlm::FSel.V.begin())].P()->yco; - - // draw new frame: - plot->clearFrame(); - plot->plotFrame(); - } - - // plot data: - NOlm::IterateEle eiter; - while( (e=eiter()) ){ - k = eiter.SelNo(); - fc = e->C(); - fd = e->D(); - JSel.evaluate( 0, e->nSpec()-1 ); - for ( uint iv=0; iv<JSel.size(); ++iv){ - j = JSel.V[iv]; - // cout << "DEBUG edif plot k="<<k<<", j="<<j<<"\n"; - if ( fd ) { - // plot data - const CSpec *s; - s = &( fd->VS[j] ); - uint n=s->x.size(); - if ( n!=s->y.size() ) - throw string( "BUG: plot: x.size<>y.size" ); - // Filter: x,y -> xp,yp if inside frame - uint np=0, nxl=0, nxh=0, nyl=0, nyh=0; - vector<double> xp, yp, dyp; - for ( uint i=0; i<n; i++ ) { - double x = s->x[i]; - if( !plot->X.contains(x) ) { - if ( x<=plot->X.inf ){ - x = plot->X.inf; - nxl++; - } - if ( x>=plot->X.sup ){ - x = plot->X.sup; - nxh++; - } - if ( !plot->X.force ) - continue; - } - double y = s->y[i]; - if( !plot->Y.contains(y) ) { - if ( y<=plot->Y.inf ){ - y = plot->Y.inf; - nyl++; - } - if ( y>=plot->Y.sup ){ - y = plot->Y.sup; - nyh++; - } - if ( !plot->Y.force ) - continue; - } - if( np==plot->maxpoints && np<n ) { - printf("reached maxpoints at %g\n", s->x[i]); - } - xp.push_back( x ); - yp.push_back( y ); - if( s->dy.size() ) - dyp.push_back( s->dy[i] ); - np = xp.size(); - if( np > plot->maxpoints ) // continue in large steps - i += plot->maxpoints; - } - if ( np==0 ) { - printf( "file %u spec %u:" - " all %u points outside plot range:\n", - k, j, n ); - if( nxl ) - printf( " %u points < xmin\n", nxl ); - if( nxh ) - printf( " %u points > xmax\n", nxh ); - if( nyl ) - printf( " %u points < ymin\n", nyl ); - if( nyh ) - printf( " %u points > ymax\n", nyh ); - continue; - } else { - plot->addSpec( false, pstyle++, - xp, yp, dyp, *(e->Z(j)), - e->P()->xco.str(), e->P()->yco.str(), - "data file " + strg(k) + " spectrum "+strg(j) ); - } - } else if ( fc && fc->kconv!=-1 ) { - // plot curve, but only at x points of convolutand - uint kconv = fc->kconv; - uint jconv = CTree::setConvJ( k, j, kconv ); - COld *fconv = NOlm::MOM[kconv].D(); - if ( !fconv ) - throw string( "convolutand is not a data file" ); - vector<double> xp, yp; - for( uint i=0; i<fconv->VS[jconv].size(); ++i ){ - double x = fconv->VS[jconv].x[i]; - if( plot->X.contains( x ) ) - xp.push_back( x ); - } - fc->T->tree_curve_val_vec( &yp, xp, k, j ); - vector<double> xo, yo; - for( uint i=0; i<xp.size(); ++i ){ - if( !( plot->X.contains( xp[i] ) && - plot->Y.contains( yp[i] ) ) ) - continue; - xo.push_back( xp[i] ); - yo.push_back( yp[i] ); - } - if( xo.size()==0 ){ - cout << "curve k="<<strg(k)<<", j="<<strg(j)<<" is empty\n"; - return; - } - plot->addSpec( true, cstyle++, xo, yo, novec, *(e->Z(j)), - e->P()->xco.str(), e->P()->yco.str(), - "curve file "+strg(k)+" spectrum "+strg(j) ); - } else if ( fc && false ) { - // PRESENTLY UNUSED - // plot ordinary curve - // straight vectorial version, for rapid plotting - int npts = 297; - vector<double> xc(npts), yc, xp, yp; - for( uint i=0; i<npts; ++i ) - xc[i] = plot->X.plotcoord2value( i/(npts-1.0) ); - fc->T->tree_curve_val_vec( &yc, xc, k, j ); - for( uint i=0; i<npts; ++i ) { - if( plot->X.contains(xc[i]) && plot->Y.contains(yc[i]) ) { - xp.push_back( xc[i] ); - yp.push_back( yc[i] ); - } - } - plot->addSpec( true, cstyle++, xp, yp, novec, *(e->Z(j)), - e->P()->xco.str(), e->P()->yco.str(), - "curve file "+strg(k)+" spectrum "+strg(j) ); - } else if ( fc ) { - // plot ordinary curve, taking care: - // - stop/start line when leaving/reentering the frame (done) - // - interpolate when crossing the horizontal border (done) - // - interpolate at discontinuities (done) - //iamhere - uint npts = 97; - double dx = plot->X.plotcoord2value( 1/(npts-1.0) ) - - plot->X.plotcoord2value( 0/(npts-1.0) ); - vector< vector<double> > xpv, ypv; - vector<double> xp, yp; - bool plotfirst = true; - bool plotlast = false; - bool plotend = false; - bool started = false; - bool ended = false; - double xt, yt; //current point (i) - double xtm,ytm;// point (i - 1) - double xtmo,ytmo;// back up of (i - 1) - while ( (!plotend) ) { - if( xpv.size()>180 ) - throw string( "curve oscillates too fast for " - "interpolating plot mode" ); - if ( !plotlast ) { - if ( plotfirst ){ - xt = plot->X.plotcoord2value( 0.0 ); - yt = fc->T->tree_curve_val_sca( xt, k, j ); - } else { - FindNextPoint( fc, xtmo, ytmo, dx, - &xt, &yt, k, j ); - } - } - if ( plot->X.contains(xt) ){// if xt <= X.sup - if ( plot->Y.contains(yt) ) { //if in - if ( plotfirst ) { //a new curve starts - //with the first point as the starting point - xp.push_back( xt ); - yp.push_back( yt ); - plotfirst = false; - started = true; - } - else if ( !started ) { //a new curve starts - //i.e. the case: out -> in - double xtt,ytt; - double border = ytm > plot->Y.sup ? - plot->Y.sup : plot->Y.inf; - //using the previous point and current point to - //interpolate the intersection point - InterY(xtm,ytm,xt,yt,&xtt,&ytt,border); - xp.push_back( xtt ); - yp.push_back( ytt ); - xp.push_back( xt ); - yp.push_back( yt ); - started = true; - } - else if ( started ) { //continues a started curve - //i.e. the case in -> in - xp.push_back( xt ); - yp.push_back( yt ); - } - } - else if ( started ) { - // a curve ends - //i.e. the case: in -> in -> out - double xtt,ytt; - double border = yt > plot->Y.sup ? - plot->Y.sup : plot->Y.inf; - //using the previous point and current point to - //interpolate the intersection point - InterY(xtm,ytm,xt,yt,&xtt,&ytt,border); - xp.push_back( xtt ); - yp.push_back( ytt ); - started = false; - ended = true; - } - else if ( plotfirst ) { //a new curve starts - //with the first point is not inside the plotting - plotfirst = false; - } - if ( xt == plot->X.sup ) { - ended = true; - plotlast = true; - plotend = true; - } - } else if ( ( xt > plot->X.sup ) && !plotlast ){ - xt = plot->X.sup; - plotlast = true; - } else - throw string( "PROGRAM ERROR plot in fc: no ending" ); - - xtmo = xtm; - ytmo = ytm; - xtm = xt; - ytm = yt; - if ( ended ){ - xpv.push_back(xp); - ypv.push_back(yp); - xp.clear(); - yp.clear(); - ended = false; - } - } // end loop over points - - for ( uint ipv=0; ipv<xpv.size();++ipv) { - if(!xpv[ipv].empty()){ - plot->addSpec( true, cstyle, xpv[ipv], ypv[ipv], - novec, *(e->Z(j)), - e->P()->xco.str(), e->P()->yco.str(), - "curve file "+strg(k)+" spectrum "+strg(j) ); - } - } - cstyle++; - } else - throw string( "PROGRAM ERROR plot invalid *e" ); - } - plot->plotDoclines( e->P()->lDoc ); - if( fc ) - plot->plotDoclines( fc->pInfo() ); - } - plot->showSpecs(); -} diff --git a/pub/src/edif.h b/pub/src/edif.h index a6c65fde..b045f22c 100644 --- a/pub/src/edif.h +++ b/pub/src/edif.h @@ -1,24 +1,14 @@ namespace NEdif { - void Dir(); - void DirZ(); - void ListZ(); - void DirNumpar(); - void EditNumpar(); - void DirCoord(); - void EditFNam(); - void EditCoord( string which ); - void EditDoc(); - void ReadIn(); - void ReadTab( string qualif ); - void MakeGrid(); - void Plot( CPlot *plot, bool add ); -/* auxiliary for plotting: */ - double FindAngleCos(double x0,double y0, - double x1,double y1, - double x2,double y2 ); - void FindNextPoint( const COlc *fc, - double xtm, double ytm, double dx, - double* xt, double* yt, uint k, uint j ); - void InterY(double xtm,double ytm,double xt,double yt, - double* xtt,double *ytt,double border); + void Dir(); + void DirZ(); + void ListZ(); + void DirNumpar(); + void EditNumpar(); + void DirCoord(); + void EditFNam(); + void EditCoord( string which ); + void EditDoc(); + void ReadIn(); + void ReadTab( string qualif ); + void MakeGrid(); }; diff --git a/pub/src/frida2.cpp b/pub/src/frida2.cpp index 3475cf19..442374e6 100644 --- a/pub/src/frida2.cpp +++ b/pub/src/frida2.cpp @@ -19,6 +19,7 @@ #include "dualplot.h" #include "opr.h" #include "edif.h" +#include "plot.h" #include "file_in.h" #include "file_out.h" #include "rssm.h" @@ -283,16 +284,17 @@ int main() " gf plot to short .psX file\n" " gw list of plot windows\n" " g<n> switch to plot window <n>\n" - " gd dialog (within gnuplot)\n" " p plot\n" " pp plot with new autoranges\n" " a add to plot\n" ; } else if (cmd == "gx") { - Plots[iPlot]->X.Ask("Set x range"); + string range = sask( "Set x range" ); + Plots[iPlot]->X.set_from_string( range ); } else if (cmd == "gy") { - Plots[iPlot]->Y.Ask("Set y range"); + string range = sask( "Set y range" ); + Plots[iPlot]->Y.set_from_string( range ); } else if (cmd == "ga") { Plots[iPlot]->X.setAuto(); Plots[iPlot]->Y.setAuto(); @@ -301,15 +303,20 @@ int main() } else if (cmd == "gya") { Plots[iPlot]->Y.setAuto(); } else if (cmd.substr(0,2) == "gx" || - cmd.substr(0,2) == "gy" || - cmd == "gnp" ) { + cmd.substr(0,2) == "gy" ) { Plots[iPlot]->setAux( cmd ); - } else if (cmd == "gp") { - Plots[iPlot]->writePostscript( true ); - } else if (cmd == "gf") { - Plots[iPlot]->writePostscript( false ); - } else if (cmd == "gd") { // graph dialog - Plots[iPlot]->feedGnuplot(); + } else if ( cmd=="gnp" ) { + Plots[iPlot]->maxpoints = + iask( "Max # points in plot", Plots[iPlot]->maxpoints ); + } else if (cmd == "gp" || cmd == "gf" ) { + string ps_outdir = NRead::wofmac( "\\psdir" ); + string ps_head = NRead::wofmac( "\\pshead" ); + string ps_dict; + if ( cmd=="gp" ) + ps_dict = NRead::wofmac( "\\psdict" ); + else + ps_dict = ""; + Plots[iPlot]->writePostscript( ps_outdir, ps_head, ps_dict ); } else if (cmd == "gw") { for( uint i=0; i<nPlot; ++i ){ printf( " %c %1i %s\n", i==iPlot ? '*' : ' ', i, @@ -324,13 +331,13 @@ int main() } else throw string( "invalid graphic window number" ); } else if (cmd == "p") { - NEdif::Plot( Plots[iPlot], 0); + NPlot::Plot( Plots[iPlot], 0); } else if (cmd == "pp") { Plots[iPlot]->X.setAuto(); Plots[iPlot]->Y.setAuto(); - NEdif::Plot( Plots[iPlot], 0 ); + NPlot::Plot( Plots[iPlot], 0 ); } else if (cmd == "a") { - NEdif::Plot( Plots[iPlot], 1 ); + NPlot::Plot( Plots[iPlot], 1 ); } else if (cmd == "m") { diff --git a/pub/src/manip.cpp b/pub/src/manip.cpp index 72caa1ae..c4bdd286 100644 --- a/pub/src/manip.cpp +++ b/pub/src/manip.cpp @@ -18,7 +18,6 @@ #include "expr.h" #include <ask_simple_value.h> #include "manip.h" -#include "dualplot.h" // wg. edif.h #include "edif.h" // wg. ListZ() #include "xax_lex.h" #include "index.h" diff --git a/pub/src/mystd.cpp b/pub/src/mystd.cpp index c988eedf..8eee689e 100644 --- a/pub/src/mystd.cpp +++ b/pub/src/mystd.cpp @@ -24,14 +24,6 @@ namespace mystd_aux { }; -//**************************************************************************// -//* constants *// -//**************************************************************************// - -const char mystd::BEL = 0x7; -const double mystd::PI = 3.1415926535897931; - - //**************************************************************************// //* convert to string *// //**************************************************************************// diff --git a/pub/src/mystd.h b/pub/src/mystd.h index 1439e600..da352ac0 100644 --- a/pub/src/mystd.h +++ b/pub/src/mystd.h @@ -1,5 +1,4 @@ #include <string> -#include <fstream> #include <vector> #define SQR(a) ((a)*(a)) @@ -22,10 +21,6 @@ string yaml( const string ); namespace mystd { - //! constants - extern const double PI; - extern const char BEL; - //! convert from string bool str2vec( string inp, vector<double> *V, uint nmax=0, bool force=true ); bool any2dbl( const string& inp, double *val ); diff --git a/pub/src/plot.cpp b/pub/src/plot.cpp new file mode 100644 index 00000000..39540bfa --- /dev/null +++ b/pub/src/plot.cpp @@ -0,0 +1,463 @@ +//**************************************************************************// +//* FRIDA: fast reliable interactive data analysis *// +//* plot.cpp: plot on-line files *// +//* (C) Joachim Wuttke 1990-, v2(C++) 2001- *// +//* http://frida.sourceforge.net *// +//**************************************************************************// + +#include <stdlib.h> +#include <math.h> +#include <iostream> +#include <algorithm> + +#include "mystd.h" +#include "olm.h" +#include <ask_simple_value.h> +#include "dualplot.h" +#include "plot.h" + +#include <boost/format.hpp> +using boost::format; + +namespace NPlot { +/* auxiliary routines */ + double FindAngleCos( double x0,double y0, + double x1,double y1, + double x2,double y2 ); + void FindNextPoint( const COlc *fc, + double xtm, double ytm, double dx, + double* xt, double* yt, uint k, uint j ); + void InterY( double xtm,double ytm,double xt,double yt, + double* xtt,double *ytt,double border); +}; + +double NPlot::FindAngleCos(double x1,double y1, //point 1 + double x2,double y2, //point 2 + double x3,double y3 )//point 3 +// Li Huang mar10 +{ + /* + (1) ________(2) + \)cos + \ + \(3) + + (x1,y1), (x2,y2) + (x2,y2) and (x3,y3) + a = x2 - x1, b = y2 - y1 + c = x3 - x2, d = y3 - y2. + The so called dot product yields the equation + Cosine( Theta ) = ( (a x c) + (b x d) )/(Sqrt(a^2 + b^2) x Sqrt(c^2 + d^2) ) = Z. + */ + double a,b,c,d,cos; + a = x2 - x1; + b = y2 - y1; + c = x3 - x2; + d = y3 - y2; + cos = ( (a * c) + (b * d) )/(sqrt(a*a + b*b) * sqrt(c*c + d*d) ); + return cos; +} + +//! The next point to be plotted is returned as *xt, *yt. + +void NPlot::FindNextPoint( const COlc *fc, + double xtm, double ytm, double dx, + double* xt, double* yt, uint k, uint j ) +// Li Huang mar10 +{ + uint i = 0; + double cos123 = 0; + double cos234 = 0; + double x1 = xtm; + double y1 = ytm; + double x2 = *xt; + double y2 = *yt; + double x3,y3; + double x4,y4; + /* + /)o1__ (3) + (2)_____________ + / \)o2 + / \ + (1)/ \(4) + + (xt,yt)__________(xt+dx,yt+dx) + / \ + / \ + (xtm,ytm)/ \(xt+2*dx,yt+2*dx) + + o1 < 1/4 degree && o2 < 1/4 degree + cos(1/4 degree) = 0.99999 + */ + do{ + x3 = x2 + dx; + y3 = fc->T->tree_curve_val_sca( x3, k, j ); + x4 = x3 + dx; + y4 = fc->T->tree_curve_val_sca( x4, k, j ); + cos123 = FindAngleCos(x1,y1,x2,y2,x3,y3); + cos234 = FindAngleCos(x2,y2,x3,y3,x4,y4); + dx = dx/2; + i++; + }while ( ( cos123 < 0.99999 || cos234 < 0.99999 ) && i <= 7); + *xt = x3; + *yt = y3; +} + +void NPlot::InterY(double xtm,double ytm,double xt,double yt, + double* xtt,double *ytt,double border) +{ + *ytt = border; + *xtt = (*ytt-ytm)*(xt-xtm)/(yt-ytm)+xtm; +} + + +//! Plot spectrum. + +void NPlot::Plot( class CPlot *plot, bool add ) +{ + static CList JSel; + CEle *e; + uint k, j; + const COld *fd; + const COlc *fc; + CSpec S; + vector<double> novec; + static int pstyle = 0, cstyle = 0; + static string jSel = ""; + NOlm::JSelAsk( "Plot which spectra", &jSel, &JSel ); + + if (!add) { + + pstyle = 0; + cstyle = 0; + + // determine x-range ? + + double inf, sup; + if (!plot->X.finite()) { + NOlm::IterateD fiter; + const vector<double> *vx; + bool first = true; + while((fd=fiter())) { + JSel.evaluate( 0, fd->nSpec()-1 ); + for( uint iv=0; iv<JSel.size(); ++iv ) { + vx = &( fd->VS[JSel.V[iv]].x ); + for( uint i=0; i<vx->size(); ++i ){ + if( plot->X.logflag && (*vx)[i]<=0 ) + continue; + if( first ){ + inf = (*vx)[i]; + sup = (*vx)[i]; + first = false; + } else { + if( (*vx)[i]<inf ) inf = (*vx)[i]; + if( (*vx)[i]>sup ) sup = (*vx)[i]; + } + } + } + } + if( first ) + throw string( "x range is empty" ); + plot->X.setRoundedLimits( "x", inf, sup ); + } + + // determine y-range ? + if (!plot->Y.finite()) { + bool first=true; + NOlm::IterateEle eiter; + int npts = 100; + const CSpec *s; + while( (e=eiter()) ){ + k = eiter.SelNo(); + fc = e->C(); + if( fc && fc->kconv!=-1 ) + continue; + fd = e->D(); + JSel.evaluate( 0, e->nSpec()-1 ); + for( uint iv=0; iv<JSel.size(); ++iv ){ + uint j = JSel.V[iv]; + if( fd ){ + s = &(fd->VS[j]); + } else { + S.x.resize( npts ); + for ( uint i=0; i<npts; i++ ) + S.x[i] = plot->X.plotcoord2value( i/(npts-1.0) ); + fc->T->tree_curve_val_vec( &(S.y), S.x, k, j ); + s = &S; + } + for (uint i=0; i<s->size(); i++) { + if( !plot->X.contains( s->x[i] ) ) + continue; + if( plot->Y.logflag && s->y[i]<=0 ) + continue; + if (first) { + inf=s->y[i], sup=s->y[i]; + first = false; + } else { + if (s->y[i]<inf) inf=s->y[i]; + if (s->y[i]>sup) sup=s->y[i]; + } + } + } + } + if( first ) + throw string( "y range is empty" ); + plot->Y.setRoundedLimits( "y", inf, sup ); + } + + // build label: (zur Zeit nur vom ersten File; definiere +=) + CCoord xCo = NOlm::MOM[*(NOlm::FSel.V.begin())].P()->xco; + CCoord yCo = NOlm::MOM[*(NOlm::FSel.V.begin())].P()->yco; + + // draw new frame: + plot->clearFrame(); + plot->plotFrame( xCo.ps_str(), yCo.ps_str() ); + } + + // plot data: + NOlm::IterateEle eiter; + while( (e=eiter()) ){ + k = eiter.SelNo(); + fc = e->C(); + fd = e->D(); + JSel.evaluate( 0, e->nSpec()-1 ); + for ( uint iv=0; iv<JSel.size(); ++iv){ + j = JSel.V[iv]; + // cout << "DEBUG edif plot k="<<k<<", j="<<j<<"\n"; + if ( fd ) { + // plot data + const CSpec *s; + s = &( fd->VS[j] ); + uint n=s->x.size(); + if ( n!=s->y.size() ) + throw string( "BUG: plot: x.size<>y.size" ); + // Filter: x,y -> xp,yp if inside frame + uint np=0, nxl=0, nxh=0, nyl=0, nyh=0; + vector<double> xp, yp, dyp; + for ( uint i=0; i<n; i++ ) { + double x = s->x[i]; + if( !plot->X.contains(x) ) { + if ( x<=plot->X.inf ){ + x = plot->X.inf; + nxl++; + } + if ( x>=plot->X.sup ){ + x = plot->X.sup; + nxh++; + } + if ( !plot->X.force ) + continue; + } + double y = s->y[i]; + if( !plot->Y.contains(y) ) { + if ( y<=plot->Y.inf ){ + y = plot->Y.inf; + nyl++; + } + if ( y>=plot->Y.sup ){ + y = plot->Y.sup; + nyh++; + } + if ( !plot->Y.force ) + continue; + } + if( np==plot->maxpoints && np<n ) { + printf("reached maxpoints at %g\n", s->x[i]); + } + xp.push_back( x ); + yp.push_back( y ); + if( s->dy.size() ) + dyp.push_back( s->dy[i] ); + np = xp.size(); + if( np > plot->maxpoints ) // continue in large steps + i += plot->maxpoints; + } + if ( np==0 ) { + printf( "file %u spec %u:" + " all %u points outside plot range:\n", + k, j, n ); + if( nxl ) + printf( " %u points < xmin\n", nxl ); + if( nxh ) + printf( " %u points > xmax\n", nxh ); + if( nyl ) + printf( " %u points < ymin\n", nyl ); + if( nyh ) + printf( " %u points > ymax\n", nyh ); + continue; + } else { + plot->addSpec( false, pstyle++, + xp, yp, dyp, *(e->Z(j)), + e->P()->xco.str(), e->P()->yco.str(), + "data file " + strg(k) + + " spectrum "+strg(j) ); + } + } else if ( fc && fc->kconv!=-1 ) { + // plot curve, but only at x points of convolutand + uint kconv = fc->kconv; + uint jconv = CTree::setConvJ( k, j, kconv ); + COld *fconv = NOlm::MOM[kconv].D(); + if ( !fconv ) + throw string( "convolutand is not a data file" ); + vector<double> xp, yp; + for( uint i=0; i<fconv->VS[jconv].size(); ++i ){ + double x = fconv->VS[jconv].x[i]; + if( plot->X.contains( x ) ) + xp.push_back( x ); + } + fc->T->tree_curve_val_vec( &yp, xp, k, j ); + vector<double> xo, yo; + for( uint i=0; i<xp.size(); ++i ){ + if( !( plot->X.contains( xp[i] ) && + plot->Y.contains( yp[i] ) ) ) + continue; + xo.push_back( xp[i] ); + yo.push_back( yp[i] ); + } + if( xo.size()==0 ){ + cout << "curve k="<<strg(k)<<", j="<<strg(j)<<" is empty\n"; + return; + } + plot->addSpec( true, cstyle++, xo, yo, novec, *(e->Z(j)), + e->P()->xco.str(), e->P()->yco.str(), + "curve file "+strg(k)+" spectrum "+strg(j) ); + } else if ( fc && false ) { + // PRESENTLY UNUSED + // plot ordinary curve + // straight vectorial version, for rapid plotting + int npts = 297; + vector<double> xc(npts), yc, xp, yp; + for( uint i=0; i<npts; ++i ) + xc[i] = plot->X.plotcoord2value( i/(npts-1.0) ); + fc->T->tree_curve_val_vec( &yc, xc, k, j ); + for( uint i=0; i<npts; ++i ) { + if( plot->X.contains(xc[i]) && plot->Y.contains(yc[i]) ) { + xp.push_back( xc[i] ); + yp.push_back( yc[i] ); + } + } + plot->addSpec( true, cstyle++, xp, yp, novec, *(e->Z(j)), + e->P()->xco.str(), e->P()->yco.str(), + "curve file "+strg(k)+" spectrum "+strg(j) ); + } else if ( fc ) { + // plot ordinary curve, taking care: + // - stop/start line when leaving/reentering the frame (done) + // - interpolate when crossing the horizontal border (done) + // - interpolate at discontinuities (done) + //iamhere + uint npts = 97; + double dx = plot->X.plotcoord2value( 1/(npts-1.0) ) - + plot->X.plotcoord2value( 0/(npts-1.0) ); + vector< vector<double> > xpv, ypv; + vector<double> xp, yp; + bool plotfirst = true; + bool plotlast = false; + bool plotend = false; + bool started = false; + bool ended = false; + double xt, yt; //current point (i) + double xtm,ytm;// point (i - 1) + double xtmo,ytmo;// back up of (i - 1) + while ( (!plotend) ) { + if( xpv.size()>180 ) + throw string( "curve oscillates too fast for " + "interpolating plot mode" ); + if ( !plotlast ) { + if ( plotfirst ){ + xt = plot->X.plotcoord2value( 0.0 ); + yt = fc->T->tree_curve_val_sca( xt, k, j ); + } else { + FindNextPoint( fc, xtmo, ytmo, dx, + &xt, &yt, k, j ); + } + } + if ( plot->X.contains(xt) ){// if xt <= X.sup + if ( plot->Y.contains(yt) ) { //if in + if ( plotfirst ) { //a new curve starts + //with the first point as the starting point + xp.push_back( xt ); + yp.push_back( yt ); + plotfirst = false; + started = true; + } + else if ( !started ) { //a new curve starts + //i.e. the case: out -> in + double xtt,ytt; + double border = ytm > plot->Y.sup ? + plot->Y.sup : plot->Y.inf; + //using the previous point and current point to + //interpolate the intersection point + InterY(xtm,ytm,xt,yt,&xtt,&ytt,border); + xp.push_back( xtt ); + yp.push_back( ytt ); + xp.push_back( xt ); + yp.push_back( yt ); + started = true; + } + else if ( started ) { //continues a started curve + //i.e. the case in -> in + xp.push_back( xt ); + yp.push_back( yt ); + } + } + else if ( started ) { + // a curve ends + //i.e. the case: in -> in -> out + double xtt,ytt; + double border = yt > plot->Y.sup ? + plot->Y.sup : plot->Y.inf; + //using the previous point and current point to + //interpolate the intersection point + InterY(xtm,ytm,xt,yt,&xtt,&ytt,border); + xp.push_back( xtt ); + yp.push_back( ytt ); + started = false; + ended = true; + } + else if ( plotfirst ) { //a new curve starts + //with the first point is not inside the plotting + plotfirst = false; + } + if ( xt == plot->X.sup ) { + ended = true; + plotlast = true; + plotend = true; + } + } else if ( ( xt > plot->X.sup ) && !plotlast ){ + xt = plot->X.sup; + plotlast = true; + } else + throw string( "PROGRAM ERROR plot in fc: no ending" ); + + xtmo = xtm; + ytmo = ytm; + xtm = xt; + ytm = yt; + if ( ended ){ + xpv.push_back(xp); + ypv.push_back(yp); + xp.clear(); + yp.clear(); + ended = false; + } + } // end loop over points + + for ( uint ipv=0; ipv<xpv.size();++ipv) { + if(!xpv[ipv].empty()){ + plot->addSpec( true, cstyle, xpv[ipv], ypv[ipv], + novec, *(e->Z(j)), + e->P()->xco.str(), e->P()->yco.str(), + "curve file "+strg(k)+ + " spectrum "+strg(j) ); + } + } + cstyle++; + } else + throw string( "PROGRAM ERROR plot invalid *e" ); + } + plot->plotDoclines( e->P()->lDoc ); + if( fc ) + plot->plotDoclines( fc->pInfo() ); + } + plot->showSpecs(); +} diff --git a/pub/src/plot.h b/pub/src/plot.h new file mode 100644 index 00000000..b6d9e924 --- /dev/null +++ b/pub/src/plot.h @@ -0,0 +1,3 @@ +namespace NPlot { + void Plot( class CPlot *plot, bool add ); +}; diff --git a/pub/src/plotaux.cpp b/pub/src/plotaux.cpp deleted file mode 100644 index 8e2e8b4a..00000000 --- a/pub/src/plotaux.cpp +++ /dev/null @@ -1,138 +0,0 @@ -//**************************************************************************// -//* FRIDA: fast reliable interactive data analysis *// -//* plotaux.cpp: ticks and tacks *// -//* (C) Joachim Wuttke 1990-, v2(C++) 2001- *// -//* http://frida.sourceforge.net *// -//**************************************************************************// - -#include <string> -#include <stdlib.h> -#include <stdio.h> // for debug -#include <math.h> -using namespace std; - -#include "plotaux.h" -#include "mystd.h" - -void plotaux::calc_ticks(int logscale, double vmin, double vmax, - int *ntack, double **tack, int *ntpt, double *ticklim) -{ - int ir, nt, i; - double r, rd, rdr, d, vsub, vsup, tack0, tackn, dtack; - - if (vmin >= vmax) - throw "PROGRAM ERROR/ Ticks/ Bad Limits: " + - strg(vmin) + ", " + strg(vmax); - - if (!logscale) { - r = log10(vmax - vmin); - ir = (int) ((r<0) ? r-1 : r); - rd = r - ir; // fractional part of r - rdr = pow(10., rd); - if (rdr > 9.99999) { - dtack = 2.5 * pow(10., ir); // spacing between tacks - *ntpt = 5; // ticks per tack - } else if (rdr > 5.00001) { - dtack = 2 * pow(10., ir); - *ntpt = 4; - } else if (rdr > 2.500005) { - dtack = 1 * pow(10., ir); - *ntpt = 5; - } else if (rdr > 1.600003) { - dtack = .5 * pow(10., ir); - *ntpt = 5; - } else if (rdr > 1.250002) { - dtack = .4 * pow(10., ir); - *ntpt = 4; - } else { - dtack = .25 * pow(10., ir); - *ntpt = 5; - } - d = vmin / dtack; - tack0 = dtack * (int) (d<=0?d-1:d); - d = vmax / dtack; - tackn = dtack * ((int) (d<0?d-1:d) + 1); - vsub = vmin - (vmax-vmin)*1.e-4; - vsup = vmax + (vmax-vmin)*1.e-4; - nt = (int) ((tackn-tack0) / dtack) + 3; // allocate enough - *tack = (double*) malloc(sizeof(double)*nt); - *ntack = 0; - for (i=0; i<nt; i++) { - d = tack0 + i*dtack; - if (vsub<=d && d<=vsup) - (*tack)[(*ntack)++] = d; - } - - ticklim[0] = tack0; - ticklim[1] = (*tack)[(*ntack)-1] + dtack; - - } else { // log scale - - static double eins = 1.0000009999999999; - double rlgmin, rlgmax, rlgrel, d1, d2, r0; - int minexp, maxexp, incr; - - if (vmin <= 0) - throw string( "PROGRAM ERROR/ Ticks/ negative log argument" ); - - rlgmin = log10(vmin); - rlgmax = log10(vmax); - rlgrel = rlgmax - rlgmin; - if (rlgrel > 40) - throw string( "Excessive log range" ); - - minexp = (rlgmin>0 ? - (int) (rlgmin+1e-6) : - ((int) (rlgmin-1e-6) -1)); - maxexp = (rlgmax>0 ? - (int) (rlgmax+1e-6) : - ((int) (rlgmax-1e-6) -1)); - - incr = (int) (rlgrel / 7 + 1); // #decades per tack - if (incr==2) incr = 1; // preferences: 10^1, 10^3, 10^6 etc. - if (incr>3) incr = 3 * (incr % 3); - - if (incr > 1) { - minexp -= minexp % incr; - maxexp -= maxexp % incr; - } - - /* - Set large ticks array : */ - static int mt=30; - *tack = (double*) malloc(sizeof(double)*mt); - - *ntack = 0; - d1 = vmin / eins; - d2 = vmax * eins; - for ( i = minexp; incr < 0 ? i >= maxexp : i <= maxexp; i += incr ) { - r0 = pow(10., i); - if (d1<=r0 && r0<=d2) { - if(*ntack>=mt) - throw string( "PROG ERR too many tacks" ); - (*tack)[(*ntack)++] = r0; - } - } - - if (*ntack >= 1) { - ticklim[0] = (*tack)[0] / pow(10., incr); - ticklim[1] = (*tack)[(*ntack)-1] * pow(10., incr); - } else { - // untested. just to allow plots when no tacks in window - ticklim[0] = pow( 10., minexp ); - ticklim[1] = pow( 10., maxexp+1 ); - } - - /** determine # ticks / tack **/ - if (incr==1 && rlgrel<=7) { - *ntpt = 9; - } else if (incr==1 && rlgrel<=7) { - *ntpt = 3; // 1-2-5-10 - Schritte - } else if (incr==1) { - *ntpt = 1; - } else { - *ntpt = -incr; - // means incr ticks per tack - // means 1 tick per decade - } - } -} diff --git a/pub/src/plotaux.h b/pub/src/plotaux.h deleted file mode 100644 index a66a336e..00000000 --- a/pub/src/plotaux.h +++ /dev/null @@ -1,6 +0,0 @@ -// This is plotaux.h. For details, see plotaux.cpp - -namespace plotaux { - void calc_ticks(int logscale, double vmin, double vmax, - int *ntack, double **tack, int *ntpt, double *ticklim); -} diff --git a/pub/src/rssm.cpp b/pub/src/rssm.cpp index a714101a..376080de 100644 --- a/pub/src/rssm.cpp +++ b/pub/src/rssm.cpp @@ -9,6 +9,7 @@ #include <stdio.h> #include <time.h> #include <iostream> +#include <fstream> #include "mystd.h" #include "olm.h" -- GitLab