diff --git a/TODO b/TODO index c182f37446056e3b2c68c566bfb72dec1515da64..d714d45cb420c84cd871d52ade65ad3144ebcd70 100644 --- a/TODO +++ b/TODO @@ -23,7 +23,6 @@ WISHLIST JWu - convolution with fits ? splines ? CHECK - gd: commandos -> gnuplot (für Fanni) - convolutand must not be defined over full energy range -- private ini file to overwrite generic one - mfj remove redundant doc lines - dp output for #spec>1 is obfuscated @@ -32,6 +31,9 @@ CHECK - gd: commandos -> gnuplot (für Fanni) - private ini file - additional settings: graph mode +- distinguish opr-functions (for modifications, with error propagation) and + and fit functions (allowing for ad-hoc additions) + SEBASTIAN = erledigt = diff --git a/pub/src/edif.cpp b/pub/src/edif.cpp index b92e385dd37079fc299d378c9d9e994c787c265b..3f4a2253f43a15b0c4d9791b46b7a7ddcbe2b513 100644 --- a/pub/src/edif.cpp +++ b/pub/src/edif.cpp @@ -368,8 +368,8 @@ void NEdif::EditCoord( string which ) NOlm::SelAssert(); NOlm::IterateO fiter; - CRef cref( which ); - if ( !cref.defined() ) { + CVariable cvar( which ); + if ( !cvar.defined() ) { printf( "! invalid coordinate %s\n", which.c_str() ); return; } @@ -380,20 +380,20 @@ void NEdif::EditCoord( string which ) while( fin = fiter() ) { POlo fout = fin; - if ( cref.var==CRef::_X ) { + if ( cvar.typ==CVariable::_X ) { old_co = fin->xco; fout->xco = new_co; - } else if ( cref.var==CRef::_Y ) { + } else if ( cvar.typ==CVariable::_Y ) { old_co = fin->yco; fout->yco = new_co; - } else if ( cref.var==CRef::_Z ) { - if( cref.num >= fin->nZ() ){ + } else if ( cvar.typ==CVariable::_Z ) { + if( cvar.num >= fin->nZ() ){ printf( "! not all files in selection have %s, use oz+\n", which.c_str() ); return; } - old_co = fin->ZCo[cref.num]; - fout->ZCo[cref.num] = new_co; + old_co = fin->ZCo[cvar.num]; + fout->ZCo[cvar.num] = new_co; } fout->lDoc.push_back( "ec"+string(which)+" "+new_co.str()+ " # old: " + old_co.str() ); diff --git a/pub/src/expr.cpp b/pub/src/expr.cpp index 0de1884bb2d0b142e8af34a091483f6d99f4efaf..f0454ff7965e75c35b2a52a0e4d0ba8199daf17d 100644 --- a/pub/src/expr.cpp +++ b/pub/src/expr.cpp @@ -81,13 +81,14 @@ string CContext::info() const return ret; } + //***************************************************************************// -//* class CRef *// -//* (references, typically used as endpoints of CTree's) *// +//* class CVariable *// //***************************************************************************// +//! Variables may be unnumbered (x,y,i,j,k,f,...) or numbered (z0,p0,...). -CRef::CRef( string s, PTree _tk, PTree _tj, PTree _ti ) +CVariable::CVariable( string s ) // 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. @@ -95,55 +96,103 @@ CRef::CRef( string s, PTree _tk, PTree _tj, PTree _ti ) num = 0; int isub; char c; - int nsub = sscanf(s.c_str(), "%c%d", &c, &isub); - if (s.substr(0,2)=="fm" && sscanf(s.substr(2).c_str(), "%d", &isub)==1 ) { - var = _FM; // fit metric + int nsub = sscanf( s.c_str(), "%c%d", &c, &isub ); + if ( s.substr(0,2)=="fm" && sscanf(s.substr(2).c_str(), "%d", &isub)==1 ) { + typ = _FM; // fit metric num = isub; - } else if (nsub==2 && c=='p') { - var = _FP; // fit parameter + } else if ( nsub==2 && c=='p' ) { + typ = _FP; // fit parameter num = isub; - } else if (s.substr(0,2)=="z+") { - var = _Z; // new z value + } else if ( s.substr(0,2)=="z+" ) { + typ = _Z; // new z value num = -1; - } else if (nsub==2 && c=='z') { - var = _Z; // z value + } else if ( nsub==2 && c=='z' ) { + typ = _Z; // z value num = isub; - } else if (s.substr(0,2)=="nj") { - var = _NJ; // number of spectra in file - } else if (s.substr(0,2)=="ni") { - var = _NI; // number of points in spectrum - } else if (nsub==1 && c=='x') { - var = _X; // x value - } else if (nsub==1 && c=='y') { - var = _Y; // y value - } else if (nsub==1 && c=='f') { - var = _FC; // fit curve - } else if (nsub==1 && c=='k') { - var = _K; // internal file index - } else if (nsub==1 && c=='j') { - var = _J; // index of current spectrum - } else if (nsub==1 && c=='i') { - var = _I; // index of current point + } else if ( s.substr(0,2)=="nj" ) { + typ = _NJ; // number of spectra in file + } else if ( s.substr(0,2)=="ni" ) { + typ = _NI; // number of points in spectrum + } else if ( nsub==1 && c=='x' ) { + typ = _X; // x value + } else if ( nsub==1 && c=='y' ) { + typ = _Y; // y value + } else if ( nsub==1 && c=='f' ) { + typ = _FC; // fit curve + } else if ( nsub==1 && c=='k' ) { + typ = _K; // internal file index + } else if ( nsub==1 && c=='j' ) { + typ = _J; // index of current spectrum + } else if ( nsub==1 && c=='i' ) { + typ = _I; // index of current point } else { - var = _NOREF; + typ = _NOREF; } - // newly constructed CRef takes over responsability to destroy CTree's - tk = _tk; - tj = _tj; - ti = _ti; - if (isindex() && indexed()) - throw string( "invalid cross reference: index cannot be indexed" ); +} + + +//! Convert to text. + +string CVariable::var_info() const +{ + string ret; + switch (typ) { + case _X: + ret = "x"; break; + case _Y: + ret = "y"; break; + case _FC: + ret = "f"; break; + case _Z: + ret = "z"; break; + case _FP: + ret = "p"; break; + case _FM: + ret = "fm"; break; + case _K: + ret = "k"; break; + case _J: + ret = "j"; break; + case _I: + ret = "i"; break; + case _NJ: + ret = "nj"; break; + case _NI: + ret = "ni"; break; + default: + throw string( "BUG: no info available for unexpected variable typ" ); + } + if ( numbered() ) + ret += strg(num); + return ret; +} + + +//***************************************************************************// +//* class CRef *// +//* (references, typically used as endpoints of CTree's) *// +//***************************************************************************// + + +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. + : CVariable( s ), tk( _tk ), tj ( _tj ), ti (_ti ) +{ + if (isindex() && ( ti || tj || tk ) ) + throw string( "BUG: invalid cross reference: index cannot be indexed" ); } void CRef::ref_val( CTOut *ret, const CContext *ctx ) const { // Plain index reference ? if ( isindex() ) { - if ( var == _K ) + if ( typ == _K ) ret->set_u( ctx->k ); - else if ( var == _J ) + else if ( typ == _J ) ret->set_u( ctx->j ); - else if ( var == _I ) { + else if ( typ == _I ) { if ( ctx->dim_1() ) { if ( ctx->i==-1 ) throw string ( "index i not defined in present context" ); @@ -153,9 +202,9 @@ void CRef::ref_val( CTOut *ret, const CContext *ctx ) const for ( uint i=0; i<ctx->nv; ++i ) ret->vd[i] = i; } else - throw string( "BUG ref_val(i) unforeseen reqDim" ); + throw string( "BUG: ref_val(i) unforeseen reqDim" ); } else - throw string( "BUG ref_val(index)" ); + throw string( "BUG: ref_val(index)" ); return; } @@ -185,16 +234,16 @@ void CRef::ref_val( CTOut *ret, const CContext *ctx ) const if ( j>=f->nJ() ) throw string( "ref_val: invalid spectrum index j=" + strg(j) ); } else if ( tj ) - throw string( "ref_val: j=" + ref_info() + + throw string( "ref_val: j=" + var_info() + " provided though operarion is not specwise" ); // check i: if ( !pointwise() && ti ) - throw string( "ref_val: i=" + ref_info() + + throw string( "ref_val: i=" + var_info() + " provided though operarion is not pointwise" ); // Reference for any file type ? - if ( var==CRef::_NJ ) { + if ( typ==CRef::_NJ ) { ret->set_u( f->nJ() ); return; } @@ -203,7 +252,7 @@ void CRef::ref_val( CTOut *ret, const CContext *ctx ) const POld fd = P2D( f ); POlc fc = P2C( f ); if ( fd ) { - if ( var == _X || var == _Y ) { + if ( typ == _X || typ == _Y ) { // cout << "CTX " << ctx->info() << "\n"; if ( ctx->dim_1() ) { // get point index i: @@ -218,9 +267,9 @@ void CRef::ref_val( CTOut *ret, const CContext *ctx ) const } if( i>= fd->VS(j)->size() ) throw string( "i out of range" ); - if ( var == _X ) + if ( typ == _X ) ret->set_d( fd->VS(j)->x[i] ); - else if ( var == _Y ) + else if ( typ == _Y ) ret->set_d( fd->VS(j)->y[i] ); } else if ( ctx->dim_vi() ) { ret->preset_vd( ctx->nv ); @@ -233,62 +282,62 @@ void CRef::ref_val( CTOut *ret, const CContext *ctx ) const ti->tree_uival( &i, &myctx ); if( i >= fd->VS(j)->size() ) throw string( "i out of range" ); - if ( var == _X ) + if ( typ == _X ) ret->vd[ii] = fd->VS(j)->x[i]; - else if ( var == _Y ) + else if ( typ == _Y ) ret->vd[ii] = fd->VS(j)->y[i]; } } else { if ( ctx->nv != fd->VS(j)->size() ) - throw "ref_val " + ref_info() + ": requested vec(" + + throw "ref_val " + var_info() + ": requested vec(" + strg(ctx->nv) + "), found vec(" + strg( fd->VS(j)->size() ); - if ( var == _X ) + if ( typ == _X ) ret->vd = fd->VS(j)->x; - else if ( var == _Y ) + else if ( typ == _Y ) ret->vd = fd->VS(j)->y; } } - } else if ( var == _Z ) { + } else if ( typ == _Z ) { if ( num>= fd->nZ() ) - throw( "invalid z ref(" + ref_info() + ") in data file" ); + throw( "invalid z ref(" + var_info() + ") in data file" ); ret->set_d( fd->VS(j)->z[num] ); - } else if ( var == _NI ) { + } else if ( typ == _NI ) { ret->set_d( fd->VS(j)->size() ); } else - throw( "invalid ref(" + ref_info() + ") in data file" ); + throw( "invalid ref(" + var_info() + ") in data file" ); } else if ( fc ) { - if ( var == _FP ) { + if ( typ == _FP ) { if ( num>= fc->nPar() ) - throw( "invalid p ref(" + ref_info() + ") in curve file" ); + throw( "invalid p ref(" + var_info() + ") in curve file" ); ret->set_d( fc->VC(j)->P[num] ); - } else if ( var == _FM ) { + } else if ( typ == _FM ) { if ( num>= CCurve::mQuality ) - throw( "invalid fm ref(" + ref_info() + ") in curve file" ); + throw( "invalid fm ref(" + var_info() + ") in curve file" ); ret->set_d( fc->VC(j)->Quality[num] ); - } else if ( var == _Z ) { + } else if ( typ == _Z ) { if ( num>= fc->nZ() ) - throw( "invalid z ref(" + ref_info() + ") in curve file" ); + throw( "invalid z ref(" + var_info() + ") in curve file" ); ret->set_d( fc->VC(j)->z[num] ); - } else if ( var == _FC ) { + } else if ( typ == _FC ) { ret->set_cr( fc, k, j ); } else - throw( "invalid ref(" + ref_info() + ") in curve file" ); + throw( "invalid ref(" + var_info() + ") in curve file" ); } else - throw string( "BUG ref->eval unexpected else" ); + throw string( "BUG: ref->eval unexpected else" ); } void CRef::coord( CCoord *ret, uint k_in ) const { if (isindex()) { - if ( var == _K ) + if ( typ == _K ) *ret = CCoord("k",""); - else if ( var == _J ) + else if ( typ == _J ) *ret = CCoord("j",""); - else if ( var == _I ) + else if ( typ == _I ) *ret = CCoord("i",""); else - throw string( "BUG coord(index)" ); + throw string( "BUG: coord(index)" ); return; } @@ -313,73 +362,40 @@ void CRef::coord( CCoord *ret, uint k_in ) const POlc fc = P2C( f ); if ( fd ) { if (!indatafile()) - throw( "coord: ref " + ref_info() + + throw( "coord: ref " + var_info() + " not allowed in data file " + strg(k) ); - if ( var == _X ) + if ( typ == _X ) *ret = fd->xco; - else if ( var == _Y ) + else if ( typ == _Y ) *ret = fd->yco; - else if ( var == _Z ) { + else if ( typ == _Z ) { if (num>=fd->ZCo.size()) throw( "coord: " + strg(num) + " undefined" ); *ret = fd->ZCo[num]; - } else if ( var == _NJ ) + } else if ( typ == _NJ ) *ret = CCoord("#spectra", ""); - else if ( var == _NI ) + else if ( typ == _NI ) *ret = CCoord("#points", ""); else - throw( "coord: data:ref(" + ref_info() + ") nyi" ); + throw( "coord: data:ref(" + var_info() + ") nyi" ); } else if ( fc ) { if (!incurvefile()) - throw( "coord: ref " + ref_info() + + throw( "coord: ref " + var_info() + " not allowed in curve file " + strg(k) ); - if ( var == _FP ) + if ( typ == _FP ) *ret = fc->PCo[num]; - else if ( var == _FM ) + else if ( typ == _FM ) *ret = CCoord("fqi_"+strg(num), ""); // fit quality indicator - else if ( var == _Z ) + else if ( typ == _Z ) *ret = fc->ZCo[num]; - else if ( var == _FC ) + else if ( typ == _FC ) *ret = CCoord(fc->expr,""); - else if ( var == _NJ ) + else if ( typ == _NJ ) *ret = CCoord("#spectra", ""); else - throw( "coord: curv:ref " + ref_info() + " nyi" ); + throw( "coord: curv:ref " + var_info() + " nyi" ); } else - throw string( "BUG ref->coord unexpected else" ); -} - -string CRef::ref_info(void) const -{ - string s; - switch (var) { - case _X: - s = "x"; break; - case _Y: - s = "y"; break; - case _FC: - s = "f"; break; - case _Z: - s = "z"; break; - case _FP: - s = "p"; break; - case _FM: - s = "fm"; break; - case _K: - s = "k"; break; - case _J: - s = "j"; break; - case _I: - s = "i"; break; - case _NJ: - s = "nj"; break; - case _NI: - s = "ni"; break; - default: - s = "?"; break; - } - if (numbered()) s += strg(num); - return s; + throw string( "BUG: ref->coord unexpected else" ); } @@ -951,9 +967,9 @@ string CTree::tree_info() const else if ( typ == _VAL ) return "val[" + strg(val) + "]"; else if ( typ == _REF ) - return "ref[" + ref->ref_info() + "]"; + return "ref[" + ref->var_info() + "]"; else if ( typ == _FRF ) - return "frf[" + ref->ref_info() + "]"; + return "frf[" + ref->var_info() + "]"; else if ( typ == _FARG ) return "farg"; else @@ -978,7 +994,7 @@ void CTree::npar_exec( uint *np ) const else if ( typ == _VAL || typ == _FARG || typ == _FRF ) ; // do nothing ( leave preset value 0 ? ) else if ( typ == _REF ) { - if ( ref->var==CRef::_FP ) { + if ( ref->typ==CRef::_FP ) { if (ref->numbered()) *np = max (*np, ref->num+1); else diff --git a/pub/src/expr.h b/pub/src/expr.h index 8cee07c1c8d240f69ba95dbbe499392c0c5eb7df..8ddd6688afc58716576c94732209d8f101115701 100644 --- a/pub/src/expr.h +++ b/pub/src/expr.h @@ -73,54 +73,60 @@ class CTOut { }; -//! References to data points, indices, ...; used as endpoints of CTree's. +//! Type of reference. -class CRef { +class CVariable { public: - enum TVar { _NOREF=0, + enum TTyp { _NOREF=0, _X, _Y, _Z, // data _FC, _FP, _FM, // "fit curve", function par's, fit metrics _K, _J, _I, // indices for file, spectrum, point _NJ, _NI // number of spectra in file, points in spectrum }; - TVar var; + TTyp typ; uint num; - PTree tk; - PTree tj; - PTree ti; - CRef( const string s="", - PTree _tk=PTree(), PTree _tj=PTree(), PTree _ti=PTree()); + CVariable( const string s="" ); bool defined() const { - return var!=_NOREF; }; + return typ!=_NOREF; }; bool isindex() const { - return var==_K || var==_J || var==_I; }; + return typ==_K || typ==_J || typ==_I; }; bool issize() const { - return var==_NJ || var==_NI; }; + return typ==_NJ || typ==_NI; }; bool pointwise() const { - return var==_X || var==_Y || var==_I; }; + return typ==_X || typ==_Y || typ==_I; }; bool specwise() const { - return pointwise() || var==_Z || var==_FP || var==_FM || var==_J || - var==_NI || var==_FC; }; + return pointwise() || typ==_Z || typ==_FP || typ==_FM || typ==_J || + typ==_NI || typ==_FC; }; bool unspecific() const { return isindex() || issize(); }; bool indatafile() const { - return unspecific() || var==_X || var==_Y || var==_Z; }; + return unspecific() || typ==_X || typ==_Y || typ==_Z; }; bool incurvefile() const { return (unspecific() && !pointwise()) - || var==_FC || var==_FP || var==_FM || var==_Z ; }; + || typ==_FC || typ==_FP || typ==_FM || typ==_Z ; }; bool numbered() const { - return var==_FP || var==_FM || var==_Z; }; + return typ==_FP || typ==_FM || typ==_Z; }; bool assignable() const { return defined() && !unspecific(); }; - bool indexed() const { - return ti || tj || tk; }; + + string var_info() const; +}; + +//! References to data points, indices, ...; used as endpoints of CTree's. + +class CRef: public CVariable { + public: + PTree tk; + PTree tj; + PTree ti; + + CRef( const string s="", + PTree _tk=PTree(), PTree _tj=PTree(), PTree _ti=PTree()); void ref_val( CTOut* ret, const CContext *ctx ) const; void coord( CCoord *ret, uint k ) const; - string ref_info() const; - const char* ref_cstr() const { return ref_info().c_str(); }; }; @@ -170,8 +176,6 @@ class CTree { void coord( CCoord *ret, uint k=(uint)-1 ) const; uint npar() const; string tree_info() const; - const char* tree_cstr() const { - return tree_info().c_str(); }; void tree_val( CTOut *ret, const CContext *ctx ) const; static uint setConvK( uint k ); diff --git a/pub/src/opr.cpp b/pub/src/opr.cpp index 1b34d939f19016f85ae9815920738835f79954a5..5e53b23e9eb7a5a1f8f09e1d9f75e5c85b2dbf63 100644 --- a/pub/src/opr.cpp +++ b/pub/src/opr.cpp @@ -151,7 +151,7 @@ void NOperate::Pointwise( string llabel ) { NOlm::SelAssert(); - CRef lref(llabel); + CVariable lref(llabel); if ( !lref.defined() ) throw "invalid left-hand side " + llabel; @@ -169,26 +169,26 @@ void NOperate::Pointwise( string llabel ) POlo fout( fin->new_olo() ); - if( lref.var!=CRef::_FP ) - fout->lDoc.push_back( "o" + lref.ref_info() + " " + expr); + if( lref.typ!=CVariable::_FP ) + fout->lDoc.push_back( "o" + lref.var_info() + " " + expr); if ( lref.pointwise() && !fd ) throw string( "no pointwise operation on curve" ); CCoord co; T->coord( &co, k ); - if ( lref.var==CRef::_X ) { + if ( lref.typ==CVariable::_X ) { fout->xco = co; - } else if ( lref.var==CRef::_Y ) { + } else if ( lref.typ==CVariable::_Y ) { fout->yco = co; - } else if ( lref.var==CRef::_Z ) { + } else if ( lref.typ==CVariable::_Z ) { if( lref.num==-1 ) fout->ZCo.push_back( co ); else if( lref.num>= fin->ZCo.size() ) throw string( "no such z coordinate to operate on" ); else fout->ZCo[lref.num] = co; - } else if ( lref.var==CRef::_FP ) { + } else if ( lref.typ==CVariable::_FP ) { if( !fc ) continue; // just ignore op operations on data files if( lref.num>=fc->nPar() ) @@ -205,18 +205,18 @@ void NOperate::Pointwise( string llabel ) PSpec eout( new CSpec( *(fd->VS(j)) ) ); vector<double> vout( fd->nPts(j) ); T->tree_vec_val( &vout, k, j ); - if (lref.var==CRef::_X) + if (lref.typ==CVariable::_X) (P2D(fout))->VS(j)->x = vout; else (P2D(fout))->VS(j)->y = vout; - } else if (lref.var==CRef::_Z) { + } else if (lref.typ==CVariable::_Z) { double dout; T->tree_point_val( &dout, k, j ); if ( lref.num==-1 ) fout->V[j]->z.push_back( dout ); else fout->V[j]->z[lref.num] = dout; - } else if (lref.var==CRef::_FP) { + } else if (lref.typ==CVariable::_FP) { double dout; T->tree_point_val( &dout, k, j ); (P2C(fout))->VC(j)->P[lref.num] = dout;