From 1839717f298cabff1191f8ea17d055dc12349349 Mon Sep 17 00:00:00 2001
From: "Joachim Wuttke (office)" <j.wuttke@fz-juelich.de>
Date: Mon, 3 May 2010 17:19:39 +0200
Subject: [PATCH] reorganize to reduce .h dependencies: - use "class" keyword -
 move constructor to .cpp - move calculator from expr.cpp to its own calc.cpp
 - regroup CSpec and CCurve with CZentry in zentry.h

---
 old/src-fragm/func-intp.cpp |  35 +++++++++
 pub/src/Makefile.am         |   4 +-
 pub/src/Makefile.in         |  18 ++---
 pub/src/calc.cpp            |  66 +++++++++++++++++
 pub/src/calc.h              |   3 +
 pub/src/curve.cpp           |   5 +-
 pub/src/curve.h             |   4 -
 pub/src/edif.cpp            |   7 +-
 pub/src/expr.cpp            | 144 +++++++++++++++++++++++-------------
 pub/src/expr.h              | 108 ++++++---------------------
 pub/src/frida2.cpp          |   4 +-
 pub/src/func.cpp            |  45 ++---------
 pub/src/func.h              |   2 -
 pub/src/manip.cpp           |   5 +-
 pub/src/olm.h               |   5 +-
 pub/src/opr.cpp             |   4 +-
 pub/src/plot.cpp            |   3 +-
 pub/src/spec.cpp            | 115 ----------------------------
 pub/src/spec.h              |   2 -
 pub/src/xax_lex.lpp         |  15 ++--
 pub/src/xax_yacc.ypp        |   2 +-
 pub/src/zentry.cpp          | 109 ++++++++++++++++++++++++++-
 pub/src/zentry.h            |  11 ++-
 23 files changed, 376 insertions(+), 340 deletions(-)
 create mode 100644 old/src-fragm/func-intp.cpp
 create mode 100644 pub/src/calc.cpp
 create mode 100644 pub/src/calc.h
 delete mode 100644 pub/src/spec.cpp
 delete mode 100644 pub/src/spec.h

diff --git a/old/src-fragm/func-intp.cpp b/old/src-fragm/func-intp.cpp
new file mode 100644
index 00000000..755a166a
--- /dev/null
+++ b/old/src-fragm/func-intp.cpp
@@ -0,0 +1,35 @@
+extern double func_data_intp_lin( double v, double dk, double dj );
+
+//**************************************************************************//
+//*   Functions based on data files                                        *//
+//**************************************************************************//
+
+//! linear interpolation in data from spectrum k,j.
+
+double func_data_intp_lin( double v, double dk, double dj )
+{
+    uint k = lrint( dk );
+    uint j = lrint( dj );
+    if( k>=NOlm::MOM.size() )
+        throw string( "intp: invalid k" );
+    POld fd = P2D( NOlm::MOM[k] );
+    if( !fd )
+        throw "f" + strg(k) + " is no data file";
+    if( j>=fd->nJ() )
+        throw string( "intp: invalid j" );
+    const PSpec s = fd->VS(j);
+    // we assume that s->x is sorted
+    uint ilow = 0, ihig = s->size()-1;
+    if( v < s->x[ilow] || v > s->x[ihig] )
+        return 0;
+    while( ihig-ilow > 1 ){
+        uint imid = (ilow+ihig)/2;
+        if( v < s->x[imid] )
+            ihig = imid;
+        else
+            ilow = imid;
+    }
+    return s->y[ilow] +
+        (v-s->x[ilow])/(s->x[ihig]-s->x[ilow])*(s->y[ihig]-s->y[ilow]);
+}
+
diff --git a/pub/src/Makefile.am b/pub/src/Makefile.am
index 8b078f64..82db67b4 100644
--- a/pub/src/Makefile.am
+++ b/pub/src/Makefile.am
@@ -30,6 +30,8 @@ PROBLEM = -Waddress \
 
 bin_PROGRAMS = frida
 frida_SOURCES = \
+calc.cpp \
+calc.h \
 coord.cpp \
 coord.h \
 curve.cpp \
@@ -65,8 +67,6 @@ rng.cpp \
 rng.h \
 rssm.cpp \
 rssm.h \
-spec.cpp \
-spec.h \
 special2.cpp \
 special.h \
 xax_lex.h \
diff --git a/pub/src/Makefile.in b/pub/src/Makefile.in
index b348fd6e..fe250a7c 100644
--- a/pub/src/Makefile.in
+++ b/pub/src/Makefile.in
@@ -51,12 +51,12 @@ CONFIG_CLEAN_FILES =
 CONFIG_CLEAN_VPATH_FILES =
 am__installdirs = "$(DESTDIR)$(bindir)"
 PROGRAMS = $(bin_PROGRAMS)
-am_frida_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) plot.$(OBJEXT) rng.$(OBJEXT) \
-	rssm.$(OBJEXT) spec.$(OBJEXT) special2.$(OBJEXT) \
+am_frida_OBJECTS = calc.$(OBJEXT) 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) plot.$(OBJEXT) \
+	rng.$(OBJEXT) rssm.$(OBJEXT) special2.$(OBJEXT) \
 	xax_lex.$(OBJEXT) xax_yacc.$(OBJEXT) zentry.$(OBJEXT)
 frida_OBJECTS = $(am_frida_OBJECTS)
 frida_LDADD = $(LDADD)
@@ -246,6 +246,8 @@ PROBLEM = -Waddress \
 	-Wtype-limits
 
 frida_SOURCES = \
+calc.cpp \
+calc.h \
 coord.cpp \
 coord.h \
 curve.cpp \
@@ -281,8 +283,6 @@ rng.cpp \
 rng.h \
 rssm.cpp \
 rssm.h \
-spec.cpp \
-spec.h \
 special2.cpp \
 special.h \
 xax_lex.h \
@@ -385,6 +385,7 @@ mostlyclean-compile:
 distclean-compile:
 	-rm -f *.tab.c
 
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/calc.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/coord.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/curve.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dualplot.Po@am__quote@
@@ -403,7 +404,6 @@ distclean-compile:
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/plot.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@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/special2.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/xax_lex.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/xax_yacc.Po@am__quote@
diff --git a/pub/src/calc.cpp b/pub/src/calc.cpp
new file mode 100644
index 00000000..cb7a8375
--- /dev/null
+++ b/pub/src/calc.cpp
@@ -0,0 +1,66 @@
+//**************************************************************************//
+//* FRIDA: fast reliable interactive data analysis                         *//
+//* calc.cpp: the command-line pocket calculator                           *//
+//* (C) Joachim Wuttke 1990-, v2(C++) 2001-                                *//
+//* http://frida.sourceforge.net                                           *//
+//**************************************************************************//
+
+#include <math.h>
+#include <iostream>
+#include <stdlib.h> // for boost/shared_ptr
+#include <stdio.h>
+
+#include <ask_simple_value.h> // for calculator
+#include <readln.h>
+
+#include "mystd.h"
+#include "olm.h"
+#include "expr.h"
+#include "calc.h"
+
+#include "xax_yacc.h"
+#include "xax_lex.h"
+
+void NCalc::Calculator() 
+{
+    string s;
+    PTree T;
+    double v;
+
+    if ( NRead::stack_empty() ) {
+        // interactive calculator
+        while (1) {
+            s = sask("calc> ");
+            if (s[0]=='q')
+                return;
+            if (s[0]=='h' || s[0]=='?') {
+                printf( "enter valid arithmetic expression, or q to quit\n");
+                continue;
+            }
+            try {
+                user_xaxparse( s.c_str(), &T );
+                T->tree_point_val( &v );
+                printf("%.12g\n", v);
+            } catch( string& s ) {
+                cerr << s << endl;
+            }
+        }
+    } else {
+        // evaluate one expression, with respect to given file selection
+        s = NRead::readln("");
+        user_xaxparse( s.c_str(), &T );
+        NOlm::IterateO fiter;
+        if( fiter.size()==0 ) {
+            T->tree_point_val( &v, -1 );
+            printf("%.12g\n", v);
+        } else {
+            while ( (fiter()) ) {
+                uint k = fiter.k();
+                T->tree_point_val( &v, k );
+                if ( fiter.size()>1 )
+                    printf( "f%d: ", k );
+                printf("%.12g\n", v);
+            }
+        }
+    }
+}
diff --git a/pub/src/calc.h b/pub/src/calc.h
new file mode 100644
index 00000000..3fa3db02
--- /dev/null
+++ b/pub/src/calc.h
@@ -0,0 +1,3 @@
+namespace NCalc {
+    void Calculator();
+};
diff --git a/pub/src/curve.cpp b/pub/src/curve.cpp
index 6e6df0fd..3691cce5 100644
--- a/pub/src/curve.cpp
+++ b/pub/src/curve.cpp
@@ -20,7 +20,8 @@ using namespace std;
 using boost::format;
 
 #include "mystd.h"
-#include "olm.h" // includes also curve.h
+#include "olm.h"
+#include "curve.h"
 #include "expr.h"
 #include "xax_lex.h"
 
@@ -505,7 +506,7 @@ void NCurveFile::SetFitTuningPars( string which )
                 "(1) coefficient of determination\n"
                 "(2) mean deviation\n" );
         int ret = iask( "Option", NFitTune::mFitMetric );
-        if( ret<1 || ret> N_FIT_METRICS )
+        if( ret<1 || ret>CCurve::mQuality )
             throw string( "invalid option" );
         NFitTune::mFitMetric = ret;
     } else if ( which=="t" )
diff --git a/pub/src/curve.h b/pub/src/curve.h
index c2e17bae..8ada77f1 100644
--- a/pub/src/curve.h
+++ b/pub/src/curve.h
@@ -1,7 +1,3 @@
-#include "zentry.h"
-
-#define N_FIT_METRICS 3
-
 //! NCurFil holds operations on curve files
 
 namespace NCurveFile {
diff --git a/pub/src/edif.cpp b/pub/src/edif.cpp
index a0ffade4..49b98c34 100644
--- a/pub/src/edif.cpp
+++ b/pub/src/edif.cpp
@@ -10,15 +10,16 @@
 #include <math.h>
 #include <iostream>
 #include <algorithm>
+#include <boost/format.hpp>
+
+#include <ask_simple_value.h>
 
 #include "mystd.h"
 #include "olm.h"
-#include "expr.h"
-#include <ask_simple_value.h>
+#include "expr.h" // only for EditCoord
 #include "edif.h"
 #include "index.h"
 
-#include <boost/format.hpp>
 using boost::format;
 
 namespace NEdif {
diff --git a/pub/src/expr.cpp b/pub/src/expr.cpp
index fbbba960..f1c702da 100644
--- a/pub/src/expr.cpp
+++ b/pub/src/expr.cpp
@@ -15,6 +15,7 @@
 
 #include "mystd.h"
 #include "olm.h" // for cross-references
+#include "func.h"
 #include "expr.h"
 
 #include "xax_yacc.h"
@@ -85,8 +86,7 @@ string CContext::info() const
 //***************************************************************************//
 
 
-CRef::CRef( string s, 
-	    PTree _tk, PTree _tj, PTree _ti )
+CRef::CRef( string s, PTree _tk, PTree _tj, PTree _ti )
     // NOTE: As long as this constructor is called by the parser and not
     // by the lexical analyzer, string s may contain more than just the
     // parameter name. Everything after the parameter name must be ignored.
@@ -262,7 +262,7 @@ void CRef::ref_val( CTOut *ret, const CContext *ctx ) const
                 throw( "invalid p ref(" + ref_info() + ") in curve file" );
             ret->set_d( fc->VC(j)->P[num] );
         } else if ( var == _FM ) {
-            if ( num>= N_FIT_METRICS )
+            if ( num>= CCurve::mQuality )
                 throw( "invalid fm ref(" + ref_info() + ") in curve file" );
             ret->set_d( fc->VC(j)->Quality[num] );
         } else if ( var == _Z ) {
@@ -386,6 +386,93 @@ string CRef::ref_info(void) const
 //* class CTree                                                             *//
 //***************************************************************************//
 
+//! Constructors.
+
+CTree::CTree()
+    : typ(_NOTREE), fun(0), has_farg(false) {}
+
+CTree::CTree( double v_in )
+    : typ(_VAL), val(v_in), fun(0), has_farg(false) {}
+
+CTree::CTree( const class CFunc *f_in, PTree a0 )
+    : typ(_OP), fun(f_in), narg(1)
+{
+    arg[0] = a0;
+    has_farg = a0->has_farg;
+    if ( fun->narg!=1 )
+        throw string( "BUG: CTree(1) with conflicting #arg" );
+}
+
+CTree::CTree( const class CFunc *f_in, PTree a0, PTree a1 )
+    : typ(_OP), fun(f_in), narg(2)
+{
+    arg[0] = a0; arg[1] = a1;
+    has_farg = a0->has_farg || a1->has_farg;
+    if ( fun->narg!=2 )
+        throw string( "BUG: CTree(2) with conflicting #arg" );
+}
+
+CTree::CTree( const class CFunc *f_in, PTree a0, PTree a1, PTree a2 )
+    : typ(_OP), fun(f_in), narg(3)
+{
+    arg[0] = a0; arg[1] = a1; arg[2] = a2;
+    has_farg = a0->has_farg || a1->has_farg || a2->has_farg;
+    if ( fun->narg!=3 )
+        throw string( "BUG: CTree(3) with conflicting #arg" );
+}
+
+CTree::CTree( PRef& _ref )
+    : typ(_REF), fun(0), ref(_ref), has_farg(false) {};
+
+CTree::CTree( PRef& _ref, PTree a0 )
+    : typ(_FRF), fun(0), ref(_ref)
+{
+    arg[0] = a0;
+    has_farg = a0->has_farg;
+}
+
+CTree::CTree( char which )
+{
+    if        ( which=='t' ) { // function argument
+        typ = _FARG;
+        has_farg = true;
+    } else if ( which=='d' ) { // Dirac delta function centered at 0
+        typ = _DIRAC;
+        has_farg = true; // function argument is implicit !
+        arg[0] = PTree( new CTree( 0.0 ) );
+        narg = 1;
+    } else
+        throw string( "invalid tree type in char-constructor" );
+}
+
+CTree::CTree( char which, const PTree& a0 )
+{
+    if ( which=='d' ) { // Dirac delta function centered at a0
+        typ = _DIRAC;
+        if( a0->has_farg )
+            throw string( "shift of Dirac delta must not contain t" );
+        arg[0] = a0;
+        narg = 1;
+        has_farg = true; // function argument is implicit !
+    } else
+        throw string( "invalid tree type in char-constructor" );
+}
+
+CTree::CTree( char which, const PTree& a0, const PTree& a1 )
+{
+    if ( which=='c' ) { // convolution
+        typ = _CONV;
+        has_farg = a0->has_farg;
+        arg[0] = a0;
+        arg[1] = a1;
+        narg = 2;
+    } else
+        throw string( "invalid tree type in char-constructor" );
+}
+
+
+//! Convolution context.
+
 typedef struct {
     PSpec sv;
     uint nv;
@@ -764,7 +851,7 @@ void CTree::tree_curve_val_vec(
 
 //! Dito, scalar, not optimized
 
-double CTree::tree_curve_val_sca( const double fargs, uint k, uint j ) const
+double CTree::tree_curve_val_sca( double fargs, uint k, uint j ) const
 {
     vector<double> in(1), out(1);
     in[0] = fargs;
@@ -899,52 +986,3 @@ void CTree::npar_exec( uint *np ) const
     } else
         throw string( "BUG: npar(UNDEF)" );
 }
-
-
-//***************************************************************************//
-//* direct access from main program                                         *//
-//***************************************************************************//
-
-void NCalc::Calculator() 
-{
-    string s;
-    PTree T;
-    double v;
-
-    if ( NRead::stack_empty() ) {
-        // interactive calculator
-        while (1) {
-            s = sask("calc> ");
-            if (s[0]=='q')
-                return;
-            if (s[0]=='h' || s[0]=='?') {
-                printf( "enter valid arithmetic expression, or q to quit\n");
-                continue;
-            }
-            try {
-                user_xaxparse( s.c_str(), &T );
-                T->tree_point_val( &v );
-                printf("%.12g\n", v);
-            } catch( string& s ) {
-                cerr << s << endl;
-            }
-        }
-    } else {
-        // evaluate one expression, with respect to given file selection
-        s = NRead::readln("");
-        user_xaxparse( s.c_str(), &T );
-        NOlm::IterateO fiter;
-        if( fiter.size()==0 ) {
-            T->tree_point_val( &v, -1 );
-            printf("%.12g\n", v);
-        } else {
-            while ( (fiter()) ) {
-                uint k = fiter.k();
-                T->tree_point_val( &v, k );
-                if ( fiter.size()>1 )
-                    printf( "f%d: ", k );
-                printf("%.12g\n", v);
-            }
-        }
-    }
-}
diff --git a/pub/src/expr.h b/pub/src/expr.h
index a3cd1049..8cee07c1 100644
--- a/pub/src/expr.h
+++ b/pub/src/expr.h
@@ -1,3 +1,5 @@
+#include <boost/shared_ptr.hpp>
+
 #define PTree boost::shared_ptr<class CTree>
 #define PRef  boost::shared_ptr<class CRef>
 
@@ -17,13 +19,12 @@ class CContext {
     TReqDim reqDim;
 
     // Explicit constructors:
-    void request_scalar(  const uint _k, const uint _j=-1, const uint _i=-1 ) {
+    void request_scalar(  uint _k, uint _j=-1, uint _i=-1 ) {
         k = _k; j = _j; i = _i; reqDim = _1; /* fargs=0 */ };
-    void request_vector_of_farg( const uint _k, const uint _j,
+    void request_vector_of_farg( uint _k, uint _j,
                                  const vector<double> *_fargs ) {
         k = _k; j = _j; fargs = _fargs; reqDim = _VT; }
-    void request_vector_of_indx( const uint _k, const uint _j,
-                                 const uint _nv ) {
+    void request_vector_of_indx( uint _k, uint _j, uint _nv ) {
         k = _k; j = _j; nv = _nv; reqDim = _VI; }
 
     bool dim_1()  const { return reqDim==_1;  };
@@ -36,7 +37,7 @@ class CContext {
 //! Curve reference with evaluation context.
 
 typedef struct {
-    POlc fc;
+    boost::shared_ptr<class COlc> fc;
     uint j, k;
 } CurveRef;
 
@@ -51,16 +52,16 @@ class CTOut {
     double d;
     vector<double> vd;
     CurveRef cr;
-    void set_u( const int u_ ) { typ = _OI; d = u_; };
-    void set_d( const double d_ ) { typ = _OD; d = d_; };
-    void preset_vd( const int n ) { typ = _OVD; vd.resize(n); };
+    void set_u( int u_ ) { typ = _OI; d = u_; };
+    void set_d( double d_ ) { typ = _OD; d = d_; };
+    void preset_vd( int n ) { typ = _OVD; vd.resize(n); };
     void set_vd( const vector<double>& vd_ ) { typ = _OVD; vd = vd_; };
-    void set_cr( POlc fc_, const uint k_, const uint j_ ) {
+    void set_cr( boost::shared_ptr<class COlc> fc_, uint k_, uint j_ ) {
         typ = _OF; cr.fc = fc_; cr.k = k_; cr.j = j_; };
     bool is_scalar() const { return typ==_OI || typ==_OD; };
     bool is_vector() const { return typ==_OVD; };
     bool is_curveref() const { return typ==_OF; };
-    double to_d( const int i ) const { return is_scalar() ? d : vd[i]; }
+    double to_d( int i ) const { return is_scalar() ? d : vd[i]; }
     void to_vd( vector<double> *vd_out ) const {
         if( is_scalar() ) {
             vd_out->resize( 1 );
@@ -138,7 +139,7 @@ class CTree {
     };
     TreeTyp typ;
     double val;
-    const CFunc* fun;
+    const class CFunc* fun;
     static const uint maxarg=3;
     PTree arg[maxarg];
     uint narg;
@@ -147,72 +148,16 @@ class CTree {
  public:
     bool has_farg;
 
-    CTree()
-        : typ(_NOTREE), fun(0), has_farg(false) {};
-    CTree( double v_in )
-        : typ(_VAL), val(v_in), fun(0), has_farg(false) {};
-    CTree( const CFunc *f_in, PTree a0 )
-        : typ(_OP), fun(f_in), narg(1) {
-        arg[0] = a0;
-        has_farg = a0->has_farg;
-        if ( fun->narg!=1 )
-            throw string( "PROG ERR: CTree(1) with conflicting #arg" );
-    };
-    CTree( const CFunc *f_in, PTree a0, PTree a1 )
-        : typ(_OP), fun(f_in), narg(2) {
-        arg[0] = a0; arg[1] = a1;
-        has_farg = a0->has_farg || a1->has_farg;
-        if ( fun->narg!=2 )
-            throw string( "PROG ERR: CTree(2) with conflicting #arg" );
-    };
-    CTree( const CFunc *f_in, PTree a0, PTree a1, PTree a2 )
-        : typ(_OP), fun(f_in), narg(3) {
-        arg[0] = a0; arg[1] = a1; arg[2] = a2;
-        has_farg = a0->has_farg || a1->has_farg || a2->has_farg;
-        if ( fun->narg!=3 )
-            throw string( "PROG ERR: CTree(3) with conflicting #arg" );
-    };
-    CTree( PRef& _ref )
-        : typ(_REF), fun(0), ref(_ref), has_farg(false) {};
-    CTree( PRef& _ref, PTree a0 )
-        : typ(_FRF), fun(0), ref(_ref) {
-        arg[0] = a0;
-        has_farg = a0->has_farg;
-    };
-    CTree( const char which ){
-        if        ( which=='t' ) { // function argument
-            typ = _FARG;
-            has_farg = true;
-        } else if ( which=='d' ) { // Dirac delta function centered at 0
-            typ = _DIRAC;
-            has_farg = true; // function argument is implicit !
-            arg[0] = PTree( new CTree( 0.0 ) );
-            narg = 1;
-        } else
-            throw string( "invalid tree type in char-constructor" );
-    };
-    CTree( const char which, const PTree& a0 ){
-        if ( which=='d' ) { // Dirac delta function centered at a0
-            typ = _DIRAC;
-            if( a0->has_farg )
-                throw string( "shift of Dirac delta must not contain t" );
-            arg[0] = a0;
-            narg = 1;
-            has_farg = true; // function argument is implicit !
-        } else
-            throw string( "invalid tree type in char-constructor" );
-    };
-
-    CTree( const char which, const PTree& a0, const PTree& a1 ){
-        if ( which=='c' ) { // convolution
-            typ = _CONV;
-            has_farg = a0->has_farg;
-            arg[0] = a0;
-            arg[1] = a1;
-            narg = 2;
-        } else
-            throw string( "invalid tree type in char-constructor" );
-    };
+    CTree();
+    CTree( double v_in );
+    CTree( const class CFunc *f_in, PTree a0 );
+    CTree( const class CFunc *f_in, PTree a0, PTree a1 );
+    CTree( const class CFunc *f_in, PTree a0, PTree a1, PTree a2 );
+    CTree( PRef& _ref );
+    CTree( PRef& _ref, PTree a0 );
+    CTree( char which );
+    CTree( char which, const PTree& a0 );
+    CTree( char which, const PTree& a0, const PTree& a1 );
 
     void tree_point_val( double *ret, uint k=(uint)-1,
                          uint j=(uint)-1, uint i=(uint)-1 ) const;
@@ -221,7 +166,7 @@ class CTree {
     void tree_uival( uint *ret, const CContext *ctx ) const;
     void tree_curve_val_vec( vector<double> *ret, const vector<double>& farg,
                              uint k, uint j ) const;
-    double tree_curve_val_sca( const double farg, uint k, uint j ) const;
+    double tree_curve_val_sca( double farg, uint k, uint j ) const;
     void coord( CCoord *ret, uint k=(uint)-1 ) const;
     uint npar() const;
     string tree_info() const;
@@ -234,10 +179,3 @@ class CTree {
  private:
     void npar_exec( uint *np ) const;
 };
-
-
-//! Direct access from main loop.
-
-namespace NCalc {
-    void Calculator();
-};
diff --git a/pub/src/frida2.cpp b/pub/src/frida2.cpp
index 41c3004c..eac4c73d 100644
--- a/pub/src/frida2.cpp
+++ b/pub/src/frida2.cpp
@@ -16,15 +16,17 @@
 
 #include "mystd.h"
 #include "olm.h"
-#include "expr.h" // for NCalc
+#include "calc.h"
 #include "dualplot.h"
 #include "opr.h"
 #include "edif.h"
+#include "func.h" // for initialization
 #include "plot.h"
 #include "file_in.h"
 #include "file_out.h"
 #include "rssm.h"
 #include "manip.h"
+#include "curve.h"
 #include "special.h"
 #include "rng.h"
 
diff --git a/pub/src/func.cpp b/pub/src/func.cpp
index 93559abd..5062c90a 100644
--- a/pub/src/func.cpp
+++ b/pub/src/func.cpp
@@ -9,14 +9,15 @@
 #include <iostream>
 #include <map>
 #include <gsl/gsl_sf.h>
+#include <kww.h>
+#include <ask_simple_value.h> //for find
 
 #include "mystd.h"
-#include <kww.h>
 #include "rng.h"
-#include "olm.h" // for func_data_, comes with many includes
-#include <ask_simple_value.h> //for find
+#include "func.h"
+#include "coord.h"
 
-double twopi = 8*atan(1.);
+const double twopi = 8*atan(1.);
 
 //**************************************************************************//
 //*   Functions of one argument                                            *//
@@ -175,39 +176,6 @@ double func_cauchy2 (double x, double p, double w) {
     return w==0 ? 0 : 2*w/twopi*(1.0/(SQR(x-p)+SQR(w))+1.0/(SQR(x+p)+SQR(w)));
 }
 
-//**************************************************************************//
-//*   Functions based on data files                                        *//
-//**************************************************************************//
-
-//! linear interpolation in data from spectrum k,j.
-
-double func_data_intp_lin( double v, double dk, double dj )
-{
-    uint k = lrint( dk );
-    uint j = lrint( dj );
-    if( k>=NOlm::MOM.size() )
-        throw string( "intp: invalid k" );
-    POld fd = P2D( NOlm::MOM[k] );
-    if( !fd )
-        throw "f" + strg(k) + " is no data file";
-    if( j>=fd->nJ() )
-        throw string( "intp: invalid j" );
-    const PSpec s = fd->VS(j);
-    // we assume that s->x is sorted
-    uint ilow = 0, ihig = s->size()-1;
-    if( v < s->x[ilow] || v > s->x[ihig] )
-        return 0;
-    while( ihig-ilow > 1 ){
-        uint imid = (ilow+ihig)/2;
-        if( v < s->x[imid] )
-            ihig = imid;
-        else
-            ilow = imid;
-    }
-    return s->y[ilow] +
-        (v-s->x[ilow])/(s->x[ihig]-s->x[ilow])*(s->y[ihig]-s->y[ilow]);
-}
-
 //**************************************************************************//
 //*   Function registration and retrieval                                  *//
 //**************************************************************************//
@@ -303,9 +271,6 @@ void NFunctions::Register(void) {
 
     fmap.insert(make_pair(string("q4w"),  CFunc("ran",  func_q4w)));
     fmap.insert(make_pair(string("cauchy2"),  CFunc("cauchy2",  func_cauchy2)));
-
-// f (data)
-    fmap.insert(make_pair(string("intp"), CFunc("intp",func_data_intp_lin)));
 }
 
 CFunc* NFunctions::find(string s)
diff --git a/pub/src/func.h b/pub/src/func.h
index a0cb7ddd..1584f58b 100644
--- a/pub/src/func.h
+++ b/pub/src/func.h
@@ -104,5 +104,3 @@ extern double func_condass(double,double,double); // conditional assignement
 extern double func_q4w(double,double,double);
 
 extern double func_cauchy2(double,double,double);
-
-extern double func_data_intp_lin( double v, double dk, double dj );
diff --git a/pub/src/manip.cpp b/pub/src/manip.cpp
index 4be00234..2d0f8007 100644
--- a/pub/src/manip.cpp
+++ b/pub/src/manip.cpp
@@ -13,10 +13,11 @@
 #include <boost/format.hpp>
 #include <gsl/gsl_sort.h>
 
+#include <ask_simple_value.h>
+
 #include "mystd.h"
 #include "olm.h"
-#include "expr.h"
-#include <ask_simple_value.h>
+#include "expr.h" // for sort, symmetrize
 #include "manip.h"
 #include "xax_lex.h"
 #include "index.h"
diff --git a/pub/src/olm.h b/pub/src/olm.h
index 4cb1559a..2756a65a 100644
--- a/pub/src/olm.h
+++ b/pub/src/olm.h
@@ -2,10 +2,7 @@
 
 #include "list.h"
 #include "coord.h"
-#include "spec.h"
-#include "curve.h"
-#include "func.h"
-
+#include "zentry.h"
 
 //! Online object: virtual base class for COld, COlc.
 
diff --git a/pub/src/opr.cpp b/pub/src/opr.cpp
index 87867910..792388bc 100644
--- a/pub/src/opr.cpp
+++ b/pub/src/opr.cpp
@@ -10,13 +10,15 @@
 #include <stdio.h>
 #include <iostream>
 #include <boost/format.hpp>
+
+#include <ask_simple_value.h>
+
 using boost::format;
 using namespace std;
 
 #include "mystd.h"
 #include "olm.h"
 #include "expr.h"
-#include <ask_simple_value.h>
 #include "opr.h"
 #include "xax_lex.h"
 
diff --git a/pub/src/plot.cpp b/pub/src/plot.cpp
index 701e3bc7..97c8e512 100644
--- a/pub/src/plot.cpp
+++ b/pub/src/plot.cpp
@@ -10,10 +10,11 @@
 #include <iostream>
 #include <algorithm>
 
+#include <ask_simple_value.h>
+
 #include "mystd.h"
 #include "olm.h"
 #include "expr.h"
-#include <ask_simple_value.h>
 #include "dualplot.h"
 #include "plot.h"
 
diff --git a/pub/src/spec.cpp b/pub/src/spec.cpp
deleted file mode 100644
index 0e69e337..00000000
--- a/pub/src/spec.cpp
+++ /dev/null
@@ -1,115 +0,0 @@
-//**************************************************************************//
-//* FRIDA: fast reliable interactive data analysis                         *//
-//* spec.cpp: each online data file contains at least one spectrum         *//
-//* (C) Joachim Wuttke 1990-, v2(C++) 2001-                                *//
-//* http://frida.sourceforge.net                                           *//
-//**************************************************************************//
-
-#include <stdlib.h>
-#include <stdio.h>
-#include <string.h>
-#include <math.h>
-#include <iostream>
-#include <boost/shared_ptr.hpp>
-
-#include "mystd.h"
-#include "spec.h"
-
-//**************************************************************************//
-//*  Construct or modify                                                   *//
-//**************************************************************************//
-
-//! Append given data point.
-
-void CSpec::push_xy( double _x, double _y )
-{
-    x.push_back(_x);
-    y.push_back(_y);
-}
-
-//! Append given data point, with error.
-
-void CSpec::push_xyd( double _x, double _y, double _dy )
-{
-    if( y.size()!=dy.size() )
-        throw string( "cannot push_xyd since y and dy have different size" );
-    x.push_back(_x);
-    y.push_back(_y);
-    dy.push_back(_dy);
-}
-
-//! Remove data points according to given indices.
-
-void CSpec::remove( uint begin, uint end )
-{
-    x.erase( x.begin()+begin, x.begin()+end );
-    y.erase( y.begin()+begin, y.begin()+end );
-    if( dy.size() )
-        dy.erase( dy.begin()+begin, dy.begin()+end );
-}
-
-//! Reset to initial state.
-
-void CSpec::clear()
-{
-    x.clear();
-    y.clear();
-    dy.clear();
-    z.clear();
-    dz.clear();
-}
-
-
-void CSpec::resize( uint n, bool with_dy )
-{
-    x.resize( n );
-    y.resize( n );
-    if( with_dy ) dy.resize( n );
-}
-
-//**************************************************************************//
-//*  Extract data                                                          *//
-//**************************************************************************//
-
-//! Return number of data points.
-
-uint CSpec::size() const
-{
-    if ( x.size()!=y.size() )
-        throw "BUG detected by spec::size: #x [" + 
-                  strg(x.size()) + "] <> #y [" + strg(y.size()) + "]\n";
-    if ( dy.size()!=y.size() && dy.size()!=0 )
-        throw "BUG detected by spec::size: #y [" + 
-                  strg(y.size()) + "] <> #dy [" + strg(dy.size()) + "]\n";
-    return y.size();
-}
-
-//! For each xx[i], set yy[i] by interpolating in this.x -> this.y.
-
-void CSpec::intpol( const vector<double>& xx, vector<double>& yy ) const
-{
-    uint n = size();
-    uint nn = xx.size();
-    yy.resize( nn );
-
-    uint ii = 0;
-    while( xx[ii]<x[0] ){
-        if( ii>=nn )
-            return;
-        yy[ii] = 0;
-        ++ii;
-    }
-    uint i = 0;
-    while ( i<n-1 && xx[ii]<x[n-1] ) {
-        while ( xx[ii]>x[i+1] && i<n-1 )
-            ++i;
-        if( i>=n-1 )
-            break;
-        if( ii>=nn )
-            return;
-        yy[ii] = y[i] + (xx[ii]-x[i])/(x[i+1]-x[i])*(y[i+1]-y[i]);
-        ++ii;
-    }
-    for( ; ii<nn; ++ii )
-        yy[ii] = 0;
-}
diff --git a/pub/src/spec.h b/pub/src/spec.h
deleted file mode 100644
index 0cbd06d3..00000000
--- a/pub/src/spec.h
+++ /dev/null
@@ -1,2 +0,0 @@
-#include "zentry.h"
-
diff --git a/pub/src/xax_lex.lpp b/pub/src/xax_lex.lpp
index d5678de8..c84608df 100644
--- a/pub/src/xax_lex.lpp
+++ b/pub/src/xax_lex.lpp
@@ -15,16 +15,15 @@ using namespace std;
 #include <math.h>
 #include <string>
 #include <vector>
-#include "olm.h"
-#include "expr.h"
+#include "func.h"
 #include "xax_yacc.h"
 
 // xaxtype must also be declared in xax.y
 struct xaxtype {
-    double  v;
-    void*   p; // for strings and functions
-    PTree   t;
-    PRef    r;
+    double                         v;
+    void*                          p; // for strings and functions
+    boost::shared_ptr<class CTree> t;
+    boost::shared_ptr<class CRef>  r;
 };
 #define YYSTYPE xaxtype
 
@@ -62,12 +61,12 @@ f {
 
 pi {
 	// printf( "lex: pi\n" );
-	xaxlval->v = acos(-1.);
+	xaxlval->v = M_PI;
 	return NUM; }
 
 e {
 	// printf( "lex: e\n" );
-	xaxlval->v = exp(1.);
+	xaxlval->v = M_E;
 	return NUM; }
 
 "=="  { return BOP_EQ; }
diff --git a/pub/src/xax_yacc.ypp b/pub/src/xax_yacc.ypp
index 038ecb97..c3356c5f 100644
--- a/pub/src/xax_yacc.ypp
+++ b/pub/src/xax_yacc.ypp
@@ -13,7 +13,7 @@ using namespace std;
 #include <stdlib.h>
 #include <string>
 #include <vector> // for expr.h
-#include "olm.h"
+#include "func.h"
 #include "expr.h"
 
 // xaxtype must also be declared in xax.l
diff --git a/pub/src/zentry.cpp b/pub/src/zentry.cpp
index bafb9e5f..4e96c281 100644
--- a/pub/src/zentry.cpp
+++ b/pub/src/zentry.cpp
@@ -1,3 +1,15 @@
+//**************************************************************************//
+//* FRIDA: fast reliable interactive data analysis                         *//
+//* zentry.cpp: z-dependent entries (spec or curve)                        *//
+//* (C) Joachim Wuttke 1990-, v2(C++) 2001-                                *//
+//* http://frida.sourceforge.net                                           *//
+//**************************************************************************//
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <math.h>
+#include <iostream>
 #include <vector>
 #include <boost/shared_ptr.hpp>
 
@@ -41,11 +53,106 @@ bool CompareZ( const PZentry& E1, const PZentry& E2 )
 //*  class CSpec                                                           *//
 //**************************************************************************//
 
+//! Append given data point.
+
+void CSpec::push_xy( double _x, double _y )
+{
+    x.push_back(_x);
+    y.push_back(_y);
+}
+
+//! Append given data point, with error.
+
+void CSpec::push_xyd( double _x, double _y, double _dy )
+{
+    if( y.size()!=dy.size() )
+        throw string( "cannot push_xyd since y and dy have different size" );
+    x.push_back(_x);
+    y.push_back(_y);
+    dy.push_back(_dy);
+}
+
+//! Remove data points according to given indices.
+
+void CSpec::remove( uint from, uint to )
+{
+    x.erase( x.begin()+from, x.begin()+to );
+    y.erase( y.begin()+from, y.begin()+to );
+    if( dy.size() )
+        dy.erase( dy.begin()+from, dy.begin()+to );
+}
+
+//! Reset to initial state.
+
+void CSpec::clear()
+{
+    x.clear();
+    y.clear();
+    dy.clear();
+    z.clear();
+    dz.clear();
+}
+
+
+//! Resize x,y,dy.
+
+void CSpec::resize( uint n, bool with_dy )
+{
+    x.resize( n );
+    y.resize( n );
+    if( with_dy ) dy.resize( n );
+}
+
+
+//! Return number of data points.
+
+uint CSpec::size() const
+{
+    if ( x.size()!=y.size() )
+        throw "BUG detected by spec::size: #x [" + 
+                  strg(x.size()) + "] <> #y [" + strg(y.size()) + "]\n";
+    if ( dy.size()!=y.size() && dy.size()!=0 )
+        throw "BUG detected by spec::size: #y [" + 
+                  strg(y.size()) + "] <> #dy [" + strg(dy.size()) + "]\n";
+    return y.size();
+}
+
+
+//! For each xx[i], set yy[i] by interpolating in this.x -> this.y.
+
+void CSpec::intpol( const vector<double>& xx, vector<double>& yy ) const
+{
+    uint n = size();
+    uint nn = xx.size();
+    yy.resize( nn );
+
+    uint ii = 0;
+    while( xx[ii]<x[0] ){
+        if( ii>=nn )
+            return;
+        yy[ii] = 0;
+        ++ii;
+    }
+    uint i = 0;
+    while ( i<n-1 && xx[ii]<x[n-1] ) {
+        while ( xx[ii]>x[i+1] && i<n-1 )
+            ++i;
+        if( i>=n-1 )
+            break;
+        if( ii>=nn )
+            return;
+        yy[ii] = y[i] + (xx[ii]-x[i])/(x[i+1]-x[i])*(y[i+1]-y[i]);
+        ++ii;
+    }
+    for( ; ii<nn; ++ii )
+        yy[ii] = 0;
+}
+
+
 //**************************************************************************//
 //*  class CCurve                                                          *//
 //**************************************************************************//
 
-
 //! Initialize curve. Used when creating or loading a curve file.
 
 void CCurve::clear(void)
diff --git a/pub/src/zentry.h b/pub/src/zentry.h
index 3d0b8c8f..8421718b 100644
--- a/pub/src/zentry.h
+++ b/pub/src/zentry.h
@@ -14,15 +14,13 @@ class CZentry {
 };
 
 
-bool CompareZ( const PZentry& E1, const PZentry& E2 );
-
-
 //! curve: parameters and fit outcome.
 
 class CCurve: public CZentry {
  public:
+    static const int mQuality = 3;
     vector<double> P;
-    double Quality[N_FIT_METRICS];
+    double Quality[mQuality];
     
     void clear( void );
 };
@@ -56,4 +54,9 @@ typedef boost::shared_ptr<CCurve> PCurve;
 typedef boost::shared_ptr<CSpec> PSpec;
 
 
+//! at global scope, for use in sorting.
+
+bool CompareZ( const PZentry& E1, const PZentry& E2 );
+
+
 #endif
-- 
GitLab