diff --git a/src/musredit_qt5/mupp/PmuppScript.cpp b/src/musredit_qt5/mupp/PmuppScript.cpp index 829637c8..9305b9a6 100644 --- a/src/musredit_qt5/mupp/PmuppScript.cpp +++ b/src/musredit_qt5/mupp/PmuppScript.cpp @@ -113,7 +113,7 @@ int PmuppScript::executeScript() } else if (cmd.startsWith("var")) { status = var_cmd(cmd); } else if (cmd.startsWith("col")) { - std::cout << "debug> will eventually handle linking of a variable to a collection ..." << std::endl; + // nothing to be done here, since var handles it internally } else { std::cerr << "**ERROR** found unkown script command '" << cmd.toLatin1().constData() << "'." << std::endl << std::endl; status = -2; @@ -300,14 +300,32 @@ int PmuppScript::addX(const QString str) // clean up plot info first fPlotInfo.clear(); - // make sure that label is found in ALL collections + // make sure that label is found in ALL collections, or in variables + // first check collections + bool foundInColl(true), foundInVar(true); + QString collName(""); for (int i=0; iGetNoOfCollections(); i++) { coll = fParamDataHandler->GetCollection(i); if (!foundLabel(coll, label)) { // label not found + foundInColl = false; + collName = coll->GetName(); + break; +/* //as35 std::cerr << std::endl << "**ERROR** couldn't find '" << label.toLatin1().constData() << "' in collection '" << coll->GetName().toLatin1().constData() << "'" << std::endl << std::endl; return -4; +*/ //as35 } } + // second check variables + if (!foundVariable(label)) { // label not found + foundInVar = false; + } + // make sure label(s) have been found + if (!foundInColl && !foundInVar) { // not all labels found, neither in collection nor variables. + std::cerr << std::endl << "**ERROR** couldn't find '" << label.toLatin1().constData() << "' in collection '" << collName.toLatin1().constData() << "'," << std::endl; + std::cerr << " nor is it a defined variable" << std::endl << std::endl; + return -4; + } // resize fPlotInfo to the number of selections fPlotInfo.resize(fParamDataHandler->GetNoOfCollections()); @@ -318,15 +336,32 @@ int PmuppScript::addX(const QString str) fPlotInfo[i].xLabel = label; } } else { // a specific selection - // check that label is found in the selected collection + // check that label is found in the selected collection, or in variables coll = fParamDataHandler->GetCollection(fSelected); if (coll == 0) { std::cerr << std::endl << "**ERROR** in addX: selected collection couldn't be found ..." << std::endl << std::endl; return -3; } + // first check collection + bool foundInColl(true), foundInVar(true); + QString collName(""); if (!foundLabel(coll, label)) { // label not found + foundInColl = false; + collName = coll->GetName(); +/* //as35 std::cerr << std::endl << "**ERROR** couldn't find '" << label.toLatin1().constData() << "' in collection '" << coll->GetName().toLatin1().constData() << "'" << std::endl << std::endl; return -4; +*/ //as35 + } + // second check variables + if (!foundVariable(label)) { // label not found + foundInVar = false; + } + // make sure label(s) have been found + if (!foundInColl && !foundInVar) { // not all labels found, neither in collection nor variables. + std::cerr << std::endl << "**ERROR** couldn't find '" << label.toLatin1().constData() << "' in collection '" << collName.toLatin1().constData() << "'," << std::endl; + std::cerr << " nor is it a defined variable" << std::endl << std::endl; + return -4; } // feed plot entry @@ -362,16 +397,40 @@ int PmuppScript::addY(const QString str) std::cerr << std::endl << "**ERROR** in addY. addY called without previous 'select' command." << std::endl << std::endl; return -2; } else if (fSelected == -1) { // i.e. select ALL - // make sure that label(s) is/are found in ALL collections + // make sure that label(s) is/are found in ALL collections, or in variables + // first check collections + bool foundInColl(true), foundInVar(true); + int idx = -1; + QString collName(""); for (int i=0; iGetNoOfCollections(); i++) { coll = fParamDataHandler->GetCollection(i); for (int j=0; jGetName(); + idx = j; + break; +/* //as35 std::cerr << std::endl << "**ERROR** couldn't find '" << label[j].toLatin1().constData() << "' in collection '" << coll->GetName().toLatin1().constData() << "'" << std::endl << std::endl; return -4; +*/ //as35 } } } + // second check variables + for (int i=0; iGetCollection(fSelected); if (coll == 0) { std::cerr << std::endl << "**ERROR** in addY: selected collection couldn't be found ..." << std::endl << std::endl; return -3; } + // first check specific collection + bool foundInColl(true), foundInVar(true); + int idx = -1; + QString collName(""); for (int i=0; iGetName(); + idx = i; + break; +/* //as35 std::cerr << std::endl << "**ERROR** couldn't find '" << label[i].toLatin1().constData() << "' in collection '" << coll->GetName().toLatin1().constData() << "'" << std::endl << std::endl; return -4; +*/ //as35 } } + // second check variables + for (int i=0; iGetCollectionName(i); xx = fParamDataHandler->GetValues(collName, fPlotInfo[i].xLabel); + if (xx.size() == 0) { // it is a variable + int idx = getVarIndex(fPlotInfo[i].xLabel); + if (idx == -1) { + std::cerr << std::endl; + std::cerr << "**ERROR** Couldn't get x-label '" << fPlotInfo[i].xLabel.toLatin1().data() << "'." << std::endl; + std::cerr << " This should never happens." << std::endl; + return -3; + } + xx = QVector::fromStdVector(fVarHandler[idx].getValues()); + } // get x-axis min/max minMax(xx, x_min, x_max); if (count==0) { @@ -533,6 +627,18 @@ int PmuppScript::macro(const QString str, const QString plotFln) yy = fParamDataHandler->GetValues(collName, fPlotInfo[i].yLabel[j]); yyPosErr = fParamDataHandler->GetPosErr(collName, fPlotInfo[i].yLabel[j]); yyNegErr = fParamDataHandler->GetNegErr(collName, fPlotInfo[i].yLabel[j]); + if (yy.size() == 0) { // it's a variable + int idx = getVarIndex(fPlotInfo[i].yLabel[j]); + if (idx == -1) { + std::cerr << std::endl; + std::cerr << "**ERROR** Couldn't get y-label '" << fPlotInfo[i].yLabel[j].toLatin1().data() << "'." << std::endl; + std::cerr << " This should never happens." << std::endl; + return -3; + } + yy = QVector::fromStdVector(fVarHandler[idx].getValues()); + yyPosErr = QVector::fromStdVector(fVarHandler[idx].getErrors()); + yyNegErr = QVector::fromStdVector(fVarHandler[idx].getErrors()); + } // get y-axis min/max minMax(yy, y_min, y_max); if (count==0) { @@ -684,7 +790,7 @@ int PmuppScript::var_cmd(const QString str) if (idx == -1) // var not linked to collection, ignore it return 0; - // check for the related error variable if present + // check if the related error variable is present QString varErr = QString("%1%2").arg(tok[1]).arg("Err"); QString varErrCmd(""); for (int i=0; iGetCollection(idx), parse_str); + PVarHandler varHandler(fParamDataHandler->GetCollection(idx), parse_str, tok[1].toLatin1().data()); + if (!varHandler.isValid()) + return 1; fVarHandler.push_back(varHandler); return 0; @@ -725,6 +833,44 @@ bool PmuppScript::foundLabel(PmuppCollection *coll, const QString label) return result; } +//-------------------------------------------------------------------------- +/** + * @brief PmuppScript::foundVariable + * @param var + * @return + */ +bool PmuppScript::foundVariable(const QString var) +{ + bool result = false; + for (int i=0; i fVarHandler; bool foundLabel(PmuppCollection *coll, const QString label); + bool foundVariable(const QString var); + int getVarIndex(const QString var); void minMax(QVector dvec, double &min, double &max); QString getNicerLabel(const QString label); diff --git a/src/musredit_qt5/mupp/examples/sigmaSC-vs-temp.txt b/src/musredit_qt5/mupp/examples/sigmaSC-vs-temp.txt index 5d565e40..f19ef5ad 100644 --- a/src/musredit_qt5/mupp/examples/sigmaSC-vs-temp.txt +++ b/src/musredit_qt5/mupp/examples/sigmaSC-vs-temp.txt @@ -5,22 +5,21 @@ loadPath ./ load YBCO-40nm-FC-E3p8keV-B10mT-Tscan.db # collection 0 load YBCO-40nm-FC-E3p8keV-B150mT-Tscan.db # collection 1 -# define the variables (on this level the parsing will be done) # B=10mT -var quatsch var SigmaSC_10 = pow(abs(pow($Sigma,2.0)-pow(0.11,2.0)), 0.5) # 0.11 (1/us) is the nuclear contribution (T>Tc) var SigmaSC_10Err = pow(pow($Sigma*$SigmaErr,2.0)+pow(0.11*0.0025,2.0), 0.5)/$SigmaSC_10 # B=150mT var SigmaSC_150 = pow(abs(pow($Sigma,2.0)-pow(0.075,2.0)), 0.5) # 0.075 (1/us) is the nuclear contribution (T>Tc) var SigmaSC_150Err = pow(pow($Sigma*$SigmaErr,2.0)+pow(0.075*0.0025,2.0), 0.5)/$SigmaSC_150 -# link variables to collection (on this level the semantic checks will be done) col 0 : SigmaSC_10 # error variable SigmaSC_10Err doesn't need to be given, it is automatically linked to SigmaSC_10 col 1 : SigmaSC_150 +norm + select 0 x dataT -y SigmaSC_10 # (on this level the evaluation will be done) +y SigmaSC_10 select 1 x dataT diff --git a/src/musredit_qt5/mupp/var/include/PVarHandler.h b/src/musredit_qt5/mupp/var/include/PVarHandler.h index 02277ec4..94beac1a 100644 --- a/src/musredit_qt5/mupp/var/include/PVarHandler.h +++ b/src/musredit_qt5/mupp/var/include/PVarHandler.h @@ -36,24 +36,32 @@ #include #include "Pmupp.h" -#include +#include "PAst.hpp" +#include "PProgram.hpp" class PVarHandler { public: - PVarHandler(PmuppCollection *coll, std::string parse_str); + PVarHandler(PmuppCollection *coll, std::string parse_str, std::string var_name); bool isValid() { return fIsValid; } + QString getVarName() { return QString(fVarName.c_str()); } std::vector getValues(); std::vector getErrors(); private: PmuppCollection *fColl; ///< collection need for parsing and evaluation std::string fParseStr; ///< the variable input to be parsed + std::string fVarName; ///< variable name + mupp::prog::PVarHandler fVar; ///< values of the evaluation bool fIsValid; mupp::ast::statement_list fAst; ///< the AST void injectPredefVariables(); + + std::string getVarName(int idx); + std::vector getData(int idx); + std::vector getDataErr(int idx); }; #endif //_PVARHANDLER_H_ diff --git a/src/musredit_qt5/mupp/var/src/CMakeLists.txt b/src/musredit_qt5/mupp/var/src/CMakeLists.txt index ed93922e..90abf78f 100644 --- a/src/musredit_qt5/mupp/var/src/CMakeLists.txt +++ b/src/musredit_qt5/mupp/var/src/CMakeLists.txt @@ -1,4 +1,7 @@ target_sources(mupp PRIVATE ${CMAKE_CURRENT_LIST_DIR}/PVarHandler.cpp + ${CMAKE_CURRENT_LIST_DIR}/PExpression.cpp + ${CMAKE_CURRENT_LIST_DIR}/PProgram.cpp + ${CMAKE_CURRENT_LIST_DIR}/PStatement.cpp ) diff --git a/src/musredit_qt5/mupp/var/src/PVarHandler.cpp b/src/musredit_qt5/mupp/var/src/PVarHandler.cpp index 62e134df..afe9d3a3 100644 --- a/src/musredit_qt5/mupp/var/src/PVarHandler.cpp +++ b/src/musredit_qt5/mupp/var/src/PVarHandler.cpp @@ -31,22 +31,54 @@ #include "PVarHandler.h" -/* #include "PSkipper.hpp" #include "PErrorHandler.hpp" #include "PStatement.hpp" -#include "PAstDump.hpp" #include "PProgram.hpp" -*/ //-------------------------------------------------------------------------- /** * @brief PVarHandler::PVarHandler */ -PVarHandler::PVarHandler(PmuppCollection *coll, std::string parse_str) : - fColl(coll), fParseStr(parse_str), fIsValid(false) +PVarHandler::PVarHandler(PmuppCollection *coll, std::string parse_str, std::string var_name) : + fColl(coll), fParseStr(parse_str), fVarName(var_name), fIsValid(false) { injectPredefVariables(); + + typedef std::string::const_iterator iterator_type; + iterator_type iter = fParseStr.begin(); + iterator_type end = fParseStr.end(); + + mupp::PErrorHandler error_handler(iter, end); // the error handler + mupp::parser::PStatement parser(error_handler); // the parser + mupp::prog::PProgram prog(error_handler); // our compiler, and exec + mupp::parser::PSkipper skipper; // the skipper parser + + // perform the parsing + bool success = phrase_parse(iter, end, parser, skipper, fAst); + if (success && iter == end) { + if (prog(fAst)) { // semantic analysis + std::vector data, dataErr; + for (unsigned int i=0; iGetRun(0).GetNoOfParam(); i++) { + data = getData(i); + dataErr = getDataErr(i); + prog.add_predef_var_values(getVarName(i), data, dataErr); + } + mupp::prog::PProgEval eval(prog.getVars()); // setup evaluation stage + eval(fAst); // evaluate stuff + + // keep data + bool ok; + fVar = eval.getVar(fVarName, ok); + if (!ok) { + std::cerr << "**ERROR** evalution failed..." << std::endl; + fIsValid = false; + } + } + fIsValid = true; + } else { + std::cerr << "**ERROR** parsing failed..." << std::endl; + } } //-------------------------------------------------------------------------- @@ -56,9 +88,11 @@ PVarHandler::PVarHandler(PmuppCollection *coll, std::string parse_str) : */ std::vector PVarHandler::getValues() { - std::vector result; + std::vector data; + if (fIsValid) + data = fVar.GetValue(); - return result; + return data; } //-------------------------------------------------------------------------- @@ -68,9 +102,11 @@ std::vector PVarHandler::getValues() */ std::vector PVarHandler::getErrors() { - std::vector result; + std::vector data; + if (fIsValid) + data = fVar.GetError(); - return result; + return data; } //-------------------------------------------------------------------------- @@ -83,8 +119,9 @@ void PVarHandler::injectPredefVariables() mupp::ast::variable_declaration var; std::string varName, errVarName; - for (int i=0; iGetNoOfRuns(); i++) { - varName = fColl->GetRun(i).GetName().toLatin1().data(); + PmuppRun run = fColl->GetRun(0); + for (int i=0; i= fColl->GetRun(0).GetNoOfParam()) + return name; + + return fColl->GetRun(0).GetParam(idx).GetName().toLatin1().data(); +} + +//-------------------------------------------------------------------------- +/** + * @brief PVarHandler::getData + * @param idx + * @return + */ +std::vector PVarHandler::getData(int idx) +{ + std::vector data; + + // make sure idx is in range + if (idx >= fColl->GetRun(0).GetNoOfParam()) + return data; + + double dval; + for (int i=0; iGetNoOfRuns(); i++) { + dval = fColl->GetRun(i).GetParam(idx).GetValue(); + data.push_back(dval); + } + + return data; +} + +//-------------------------------------------------------------------------- +/** + * @brief PVarHandler::getDataErr + * @param idx + * @return + */ +std::vector PVarHandler::getDataErr(int idx) +{ + std::vector err; + + // make sure idx is in range + if (idx >= fColl->GetRun(0).GetNoOfParam()) + return err; + + double dvalPos, dvalNeg; + for (int i=0; iGetNoOfRuns(); i++) { + dvalPos = fColl->GetRun(i).GetParam(idx).GetPosErr(); + dvalNeg = fColl->GetRun(i).GetParam(idx).GetNegErr(); + dvalPos = sqrt(fabs(dvalPos*dvalNeg)); // geometric mean of pos/neg error + err.push_back(dvalPos); + } + + return err; +}