diff --git a/src/classes/PTheory.cpp b/src/classes/PTheory.cpp index 4af3271e..4da5ea27 100644 --- a/src/classes/PTheory.cpp +++ b/src/classes/PTheory.cpp @@ -37,6 +37,7 @@ using namespace std; #include #include #include +#include #include #include @@ -91,6 +92,7 @@ PTheory::PTheory(PMsrHandler *msrInfo, unsigned int runNo, const bool hasParent) fAdd = 0; fMul = 0; fStaticKTLFFunc = 0; + fUserFcnClassName = TString(""); static unsigned int lineNo = 1; // lineNo static unsigned int depth = 0; // needed to handle '+' properly @@ -163,7 +165,7 @@ PTheory::PTheory(PMsrHandler *msrInfo, unsigned int runNo, const bool hasParent) } // line is a valid function, hence analyze parameters - if ((unsigned int)(tokens->GetEntries()-1) != fNoOfParam) { + if (((unsigned int)(tokens->GetEntries()-1) != fNoOfParam) && (idx != THEORY_USER_FCN)) { cout << endl << "**ERROR**: PTheory(): Theory line '" << line->fLine.Data() << "'"; cout << " in line no " << line->fLineNo; cout << " expecting " << fgTheoDataBase[idx].fNoOfParam << ", but found " << tokens->GetEntries()-1; @@ -179,6 +181,12 @@ PTheory::PTheory(PMsrHandler *msrInfo, unsigned int runNo, const bool hasParent) ostr = dynamic_cast(tokens->At(i)); str = ostr->GetString(); + // if userFcn, the first entry is the function name and needs to be handled specially + if ((fType == THEORY_USER_FCN) && (i == 1)) { + fUserFcnClassName = str; + continue; + } + // check if str is map if (str.Contains("map")) { status = sscanf(str.Data(), "map%u", &value); @@ -246,6 +254,15 @@ PTheory::PTheory(PMsrHandler *msrInfo, unsigned int runNo, const bool hasParent) MakeCleanAndTidyTheoryBlock(fullTheoryBlock); } + // check if user function, if so, check if it is reachable (root) + if (!fUserFcnClassName.IsWhitespace()) { + cout << endl << ">> user function class name: " << fUserFcnClassName.Data() << endl; + if (!TClass::GetDict(fUserFcnClassName.Data())) { + cout << endl << "**ERROR**: PTheory: user function class '" << fUserFcnClassName.Data() << "' not found. See line no " << line->fLineNo; + fValid = false; + } + } + // clean up if (tokens) { delete tokens; @@ -385,6 +402,10 @@ double PTheory::Func(register double t, const vector& paramValues, const return SkewedGauss(t, paramValues, funcValues) * fMul->Func(t, paramValues, funcValues) + fAdd->Func(t, paramValues, funcValues); break; + case THEORY_USER_FCN: + return UserFcn(t, paramValues, funcValues) * fMul->Func(t, paramValues, funcValues) + + fAdd->Func(t, paramValues, funcValues); + break; default: cout << endl << "**PANIC ERROR**: PTheory::Func: You never should have reached this line?!?! (" << fType << ")"; cout << endl; @@ -440,6 +461,9 @@ double PTheory::Func(register double t, const vector& paramValues, const case THEORY_SKEWED_GAUSS: return SkewedGauss(t, paramValues, funcValues) * fMul->Func(t, paramValues, funcValues); break; + case THEORY_USER_FCN: + return UserFcn(t, paramValues, funcValues) * fMul->Func(t, paramValues, funcValues); + break; default: cout << endl << "**PANIC ERROR**: PTheory::Func: You never should have reached this line?!?! (" << fType << ")"; cout << endl; @@ -497,6 +521,9 @@ double PTheory::Func(register double t, const vector& paramValues, const case THEORY_SKEWED_GAUSS: return SkewedGauss(t, paramValues, funcValues) + fAdd->Func(t, paramValues, funcValues); break; + case THEORY_USER_FCN: + return UserFcn(t, paramValues, funcValues) + fAdd->Func(t, paramValues, funcValues); + break; default: cout << endl << "**PANIC ERROR**: PTheory::Func: You never should have reached this line?!?! (" << fType << ")"; cout << endl; @@ -552,6 +579,9 @@ double PTheory::Func(register double t, const vector& paramValues, const case THEORY_SKEWED_GAUSS: return SkewedGauss(t, paramValues, funcValues); break; + case THEORY_USER_FCN: + return UserFcn(t, paramValues, funcValues); + break; default: cout << endl << "**PANIC ERROR**: PTheory::Func: You never should have reached this line?!?! (" << fType << ")"; cout << endl; @@ -1085,3 +1115,26 @@ double PTheory::SkewedGauss(register double t, const vector& paramValues return skg; } + +//-------------------------------------------------------------------------- +/** + *

+ * + * \param t time in \f$(\mu\mathrm{s})\f$ + * \param paramValues + */ +double PTheory::UserFcn(register double t, const vector& paramValues, const vector& funcValues) const +{ + static bool first = true; + +if (first) { + first = false; + cout << endl << ">> UserFcn: fParamNo.size()=" << fParamNo.size(); + for (unsigned int i=0; i> " << i << ": " << fParamNo[i]+1; + } + cout << endl; +} + + return 0.0; +} diff --git a/src/include/PTheory.h b/src/include/PTheory.h index 70bc8d52..8c950b56 100644 --- a/src/include/PTheory.h +++ b/src/include/PTheory.h @@ -67,7 +67,7 @@ #define THEORY_BESSEL 13 #define THEORY_INTERNAL_BESSEL 14 #define THEORY_SKEWED_GAUSS 15 -#define THEORY_USER 16 +#define THEORY_USER_FCN 16 // function parameter tags, i.e. how many parameters has a specific function #define THEORY_PARAM_ASYMMETRY 1 // asymetry @@ -88,7 +88,7 @@ #define THEORY_PARAM_SKEWED_GAUSS 4 // phase, frequency, rate minus, rate plus // number of available user functions -#define THEORY_MAX 16 +#define THEORY_MAX 17 // deg -> rad factor #define DEG_TO_RAD 0.0174532925199432955 @@ -162,7 +162,10 @@ static PTheoDataBase fgTheoDataBase[THEORY_MAX] = { "internBsl", "ib", "(phase frequency Trate Lrate)"}, {THEORY_SKEWED_GAUSS, THEORY_PARAM_SKEWED_GAUSS, false, - "skewedGss", "skg", "(phase frequency rate_m rate_p)"}}; + "skewedGss", "skg", "(phase frequency rate_m rate_p)"}, + + {THEORY_USER_FCN, 0, false, + "userFcn", "u", ""}}; //-------------------------------------------------------------------------------------- /** @@ -197,6 +200,7 @@ class PTheory virtual double Bessel(register double t, const vector& paramValues, const vector& funcValues) const; virtual double InternalBessel(register double t, const vector& paramValues, const vector& funcValues) const; virtual double SkewedGauss(register double t, const vector& paramValues, const vector& funcValues) const; + virtual double UserFcn(register double t, const vector& paramValues, const vector& funcValues) const; // variables bool fValid; @@ -210,6 +214,8 @@ class PTheory // TString fUserFunPreParsed; TF1 *fStaticKTLFFunc; + TString fUserFcnClassName; ///< name of the user function class for within root + PMsrHandler *fMsrInfo; };