58#include <QInputDialog>
63#include <QProcessEnvironment>
64#include <QRegularExpression>
72#define PMUPP_POSNEGERR 1
118 SetParam(name, param, posErr, negErr);
188 if (idx < (
unsigned int)
fParam.size())
208 if (idx < (
unsigned int)
fRun.size())
253 QStringList &arg, QString &workDir, QString &errorMsg)
261 int pos0=-1, pos1=-1;
262 QString flnCurrent(
""), extCurrent(
""), runStr(
"");
265 pos0 = fln[0].lastIndexOf(
"/");
266 workDir = fln[0].left(pos0);
268 for (
int i=0; i<fln.count(); i++) {
270 tok = fln[i].split(
"/");
271 flnCurrent = tok[tok.size()-1];
274 pos0 = flnCurrent.indexOf(
"_");
276 errorMsg =
"msr-file name has a structure which cannot be handled.\n\
277 It should be <run><extension>, where <run> is the run number\n\
278 and <extension> needs to start with a '_'.";
281 pos1 = flnCurrent.lastIndexOf(
".");
282 if ((pos1 == -1) || (pos1 < pos0)) {
283 errorMsg =
"msr-file name has a structure which cannot be handled.\n\
284 It should be <run><extension>.msr, where <run> is the run number\n\
285 and <extension> needs to start with a '_'.";
290 runStr = flnCurrent.left(pos0);
293 errorMsg = QString(
"Found run number string '%1' which is not a number.").arg(runStr);
300 ext = flnCurrent.mid(pos0, pos1-pos0);
302 extCurrent = flnCurrent.mid(pos0, pos1-pos0);
305 if ((i>0) && (ext != extCurrent)) {
306 errorMsg =
"Currently mixed msr-file extensions cannot be handled.";
312 for (
int i=0; i<run.size(); i++)
317 arg << collectionName;
350 QString collName(
"");
353 if (fln[0].endsWith(
".msr")) {
355 collName = QInputDialog::getText(0,
"Get Collection Name",
"Please enter a collection name",
356 QLineEdit::Normal,
"coll007", &ok);
357 if (!ok || collName.isEmpty())
365 QString workDir(
"./");
371 fProc = std::make_unique<QProcess>(
this);
372 connect(
fProc.get(), SIGNAL( readyReadStandardOutput() ),
this, SLOT(
readFromStdOut() ) );
373 connect(
fProc.get(), SIGNAL( readyReadStandardError() ),
this, SLOT(
readFromStdErr() ) );
374 connect(
fProc.get(), SIGNAL( finished(
int, QProcess::ExitStatus) ),
this, SLOT(
processDone(
int, QProcess::ExitStatus) ) );
376 QProcessEnvironment env = QProcessEnvironment::systemEnvironment();
377#if defined(Q_OS_DARWIN)
378 env.insert(
"DYLD_LIBRARY_PATH", env.value(
"ROOTSYS") +
"/lib:/usr/local/lib:" + env.value(
"DYLD_LIBRARY_PATH"));
380 env.insert(
"LD_LIBRARY_PATH", env.value(
"ROOTSYS") +
"/lib:" + env.value(
"LD_LIBRARY_PATH"));
382 cmd = env.value(
"MUSRFITPATH") + QString(
"/msr2data");
383 if (!QFile::exists(cmd)) {
385 cmd = env.value(
"ROOTSYS") + QString(
"/bin/msr2data");
386 if (!QFile::exists(cmd)) {
387 errorMsg =
"cannot find msr2data need here.";
391 QString pathName = workDir + QString(
"/") + collName;
392 if (QFile::exists(pathName))
393 QFile::remove(pathName);
394 fProc->setProcessEnvironment(env);
395 fProc->setWorkingDirectory(workDir);
396 fProc->start(cmd, arg);
397 if (!
fProc->waitForFinished()) {
398 errorMsg = QString(tr(
"Could not execute the output command: ")+cmd[0]);
403 collection =
ReadDbFile(pathName, valid, errorMsg);
405 std::cerr << std::endl;
406 std::cerr <<
"----" << std::endl;
407 std::cerr <<
"**ERROR** read db-file failure (" << pathName.toLatin1().data() <<
"." << std::endl;
408 std::cerr <<
"----" << std::endl;
411 collName.remove(
".db");
416 for (
int i=0; i<fln.size(); i++) {
417 if (fln[i].endsWith(
".db")) {
418 collection =
ReadDbFile(fln[i], valid, errorMsg);
422 if (!fln[i].startsWith(
"/")) {
423 if (fln[i].startsWith(
"..")) {
424 int idx = fln[i].lastIndexOf(
"/");
426 errorMsg = QString(
"found '%1' which shouldn't be possible!").arg(fln[i]);
427 std::cerr << std::endl;
428 std::cerr <<
"----" << std::endl;
429 std::cerr <<
"**ERROR** " << errorMsg.toLatin1().data() << std::endl;
430 std::cerr <<
"----" << std::endl;
433 QString relPath = fln[i].left(idx);
434 QString fileName = fln[i].right(fln[i].length()-idx-1);
436 collection.
SetPathName(dir.absolutePath()+
"/" +fileName);
438 QDir dir(QDir::currentPath());
444 int pos = fln[i].lastIndexOf(
"/");
449 collName = fln[i].right(fln[i].length()-pos-1);
452 }
else if (fln[i].endsWith(
".dat") || fln[i].endsWith(
".txt")) {
459 errorMsg = QString(
"unkown file type for ")+fln[i];
460 std::cerr << std::endl;
461 std::cerr <<
"*********" << std::endl;
462 std::cerr <<
"**ERROR** " << errorMsg.toLatin1().data() << std::endl;
463 std::cerr <<
"*********" << std::endl;
504 if (!file.open(QIODevice::ReadOnly | QIODevice::Text)) {
505 errorMsg = QString(
"couldn't open ") + fln;
506 std::cerr << std::endl;
507 std::cerr <<
"----" << std::endl;
508 std::cerr <<
"**ERROR** " << errorMsg.toLatin1().data() << std::endl;
509 std::cerr <<
"----" << std::endl;
514 QTextStream in(&file);
516 QStringList token, subTok;
517 bool done =
false, param_found =
false, ok;
522 while (!in.atEnd() && !done) {
523 line = in.readLine();
525 if (line.startsWith(
"\\-e")) {
527 line = in.readLine();
529 if (param_found && !line.isEmpty()) {
532 token = line.split(
",", Qt::SkipEmptyParts);
533 if (token.size()==0) {
534 errorMsg = fln + QString(
". No parameter tokens.");
535 std::cerr << std::endl;
536 std::cerr <<
"----" << std::endl;
537 std::cerr <<
"**ERROR** in " << errorMsg.toLatin1().data() << std::endl;
538 std::cerr <<
"----" << std::endl;
543 ival = token[0].toInt(&ok);
551 for (
int i=1; i<token.size(); i++)
553 title = title.trimmed();
558 errorMsg = fln + QString(
".\n");
560 errorMsg += QString(
" current run (#%1) has %2 params.\n").arg(run.
GetNumber()).arg(run.
GetNoOfParam());
561 errorMsg += QString(
" Inspect your db-file!");
562 std::cerr << std::endl;
563 std::cerr <<
"----" << std::endl;
564 std::cerr <<
"**ERROR** in " << errorMsg.toLatin1().data() << std::endl;
565 std::cerr <<
"----" << std::endl;
574 if (token.size() != 4) {
575 std::cerr << std::endl;
576 std::cerr <<
"----" << std::endl;
577 std::cerr <<
"**ERROR** in" << fln.toLatin1().data() <<
". # parameter tokens != 4." << std::endl;
578 std::cerr <<
"----" << std::endl;
583 subTok = token[0].split(
"=");
584 if (subTok.size() != 2) {
585 std::cerr << std::endl;
586 std::cerr <<
"----" << std::endl;
587 std::cerr <<
"**ERROR** in" << fln.toLatin1().data() <<
". parameter name=value token missing." << std::endl;
588 std::cerr <<
"----" << std::endl;
593 QString paramName = subTok[0].trimmed();
596 dval = subTok[1].toDouble(&ok);
600 std::cerr << std::endl;
601 std::cerr <<
"----" << std::endl;
602 std::cerr <<
"**ERROR** in" << fln.toLatin1().data() <<
". parameter name=value token missing or wrong?!" << std::endl;
603 std::cerr <<
"----" << std::endl;
609 dval = token[1].toDouble(&ok);
613 std::cerr << std::endl;
614 std::cerr <<
"----" << std::endl;
615 std::cerr <<
"**ERROR** in" << fln.toLatin1().data() <<
". parameter pos. error not a number?!" << std::endl;
616 std::cerr <<
"----" << std::endl;
622 dval = token[2].toDouble(&ok);
626 std::cerr << std::endl;
627 std::cerr <<
"----" << std::endl;
628 std::cerr <<
"**ERROR** in" << fln.toLatin1().data() <<
". parameter neg. error not a number?!" << std::endl;
629 std::cerr <<
"----" << std::endl;
639 std::cerr << std::endl;
640 std::cerr <<
"----" << std::endl;
641 std::cerr <<
"**ERROR** in" << fln.toLatin1().data() <<
". No parameter found." << std::endl;
642 std::cerr <<
"----" << std::endl;
686 if (!file.open(QIODevice::ReadOnly | QIODevice::Text)) {
687 errorMsg = QString(
"couldn't open ")+fln;
688 std::cerr << std::endl;
689 std::cerr <<
"----" << std::endl;
690 std::cerr <<
"**ERROR** " << errorMsg.toLatin1().data() << std::endl;
691 std::cerr <<
"----" << std::endl;
696 QTextStream in(&file);
699 bool done =
false, ok;
705 line = in.readLine();
706 token = line.split(QRegularExpression(
"\\s+"), Qt::SkipEmptyParts);
708 QVector<QString> headerInfo;
709 QVector<int> headerCode;
711 for (
int i=0; i<token.size(); i++) {
712 headerInfo.push_back(token[i]);
713 if (token[i].contains(
"PosErr"))
715 else if (token[i].contains(
"NegErr"))
717 else if (token[i].contains(
"Err"))
719 else if (token[i].contains(
"RUN"))
723 headerCode.push_back(code);
728 while (!in.atEnd() && !done) {
729 line = in.readLine();
734 token = line.split(QRegularExpression(
"\\s+"), Qt::SkipEmptyParts);
736 if (token.size() != headerInfo.size()) {
737 errorMsg = QString(
"size mismatch between header and parameter int line: %1 (header=%2 / param=%3)").arg(lineNo).arg(headerInfo.size()).arg(token.size());
738 std::cerr << std::endl;
739 std::cerr <<
"----" << std::endl;
740 std::cerr <<
"**ERROR** " << errorMsg.toLatin1().data() << std::endl;
741 std::cerr <<
"----" << std::endl;
746 for (
int i=0; i<token.size(); i++) {
747 dval = token[i].toDouble(&ok);
749 errorMsg = QString(
"unrecognized token ('%1') in line %2 (line number: %3)").arg(token[i].toLatin1().data()).arg(line.toLatin1().data()).arg(lineNo);
750 std::cerr << std::endl;
751 std::cerr <<
"----" << std::endl;
752 std::cerr <<
"**ERROR** " << errorMsg.toLatin1().data() << std::endl;
753 std::cerr <<
"----" << std::endl;
762 if (i+1 < token.size()) {
794 run.
SetName(QString(
"%1").arg((
int)dval));
797 QString collName(
"");
798 int pos = fln.lastIndexOf(
"/");
802 collName = fln.right(fln.length()-pos-1);
940 QString name = QString(
"??");
970 QVector<double> data;
997 for (
int i=0; i<
fCollection[idx].GetNoOfRuns(); i++) {
998 data.push_back(
fCollection[idx].GetRun(i).GetParam(idx1).GetValue());
1024 QVector<double> data;
1051 for (
int i=0; i<
fCollection[idx].GetNoOfRuns(); i++) {
1079 QVector<double> data;
1106 for (
int i=0; i<
fCollection[idx].GetNoOfRuns(); i++) {
1171 std::cout <<
"debug> +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-" << std::endl;
1172 std::cout <<
"debug> collection name: " <<
fCollection[i].GetName().toLatin1().data() << std::endl;
1173 std::cout <<
"debug> +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-" << std::endl;
1174 for (
int j=0; j<
fCollection[i].GetNoOfRuns(); j++) {
1175 std::cout <<
"debug> ----------------------------------" << std::endl;
1177 std::cout <<
"debug>> run number: " << run.
GetNumber() << std::endl;
1178 std::cout <<
"debug>> run name : " << run.
GetName().toLatin1().data() << std::endl;
1179 std::cout <<
"debug>> ---------------------------------" << std::endl;
1182 std::cout <<
"debug>>> " << param.
GetName().toLatin1().data() <<
": " << param.
GetValue() <<
" -+ " << param.
GetNegErr() <<
" / " << param.
GetPosErr() << std::endl;
1198 qInfo() <<
fProc->readAllStandardOutput();
1211 qInfo() <<
fProc->readAllStandardError();
1227 qInfo() <<
"in processDone()";
1228 if ((exitStatus == QProcess::CrashExit) && (exitCode != 0)) {
1229 qInfo() <<
"**ERROR** processDone: exitCode = " << exitCode << Qt::endl;
Core data structures and handler classes for mupp parameter management.
#define MUPP_UNDEF
Undefined value constant used to indicate missing or invalid data.
void readFromStdOut()
Slot to handle standard output from msr2data process.
bool analyzeFileList(const QStringList &fln, QString &collectionName, QStringList &arg, QString &workDir, QString &errorMsg)
Analyzes a list of msr-files to prepare arguments for msr2data.
PmuppCollection GetCollection(const int idx, bool &valid)
Retrieves a collection by index (by value).
void ReplaceCollection(PmuppCollection coll, int idx)
Replaces a collection at the specified index.
std::unique_ptr< QProcess > fProc
process handle for invoking msr2data when msr files need conversion
PmuppCollection ReadDbFile(const QString fln, bool &valid, QString &errorMsg)
Reads and parses a db-format parameter file.
void Dump()
Dumps all collection data to stdout for debugging.
int GetCollectionIndex(const QString name)
PParamDataHandler::GetCollectionIndex. Get the collection index of a given collection name.
void newData()
Signal emitted when new data has been successfully loaded.
QVector< double > GetPosErr(QString collName, QString paramName)
Retrieves all positive errors for a specific parameter across all runs.
QString GetCollectionName(const int idx)
PParamDataHandler::GetCollectionName.
QVector< double > GetValues(QString collName, QString paramName)
Retrieves all values for a specific parameter across all runs.
QVector< PmuppCollection > fCollection
vector containing all loaded collections
QVector< double > GetNegErr(QString collName, QString paramName)
Retrieves all negative errors for a specific parameter across all runs.
void RemoveCollection(QString name)
Removes a collection from the handler by name.
bool ReadParamFile(const QStringList fln, QString &errorMsg)
Reads parameter file(s) and loads them into collections.
void NewCollection(const QString name)
Creates and adds an empty collection with the specified name.
void processDone(int, QProcess::ExitStatus)
Slot to handle completion of msr2data process.
void readFromStdErr()
Slot to handle standard error from msr2data process.
PmuppCollection ReadColumnParamFile(const QString fln, bool &valid, QString &errorMsg)
Reads and parses a column-based parameter file (dat/txt format).
Represents a collection of related experimental runs.
void SetPathName(QString pathName)
Sets the full path name of the collection file.
void SetName(QString name)
Sets the collection name.
PmuppRun GetRun(unsigned int idx)
Retrieves a run from a collection by index.
void AddRun(PmuppRun run)
Adds a run to this collection.
int GetNoOfRuns()
Gets the number of runs in this collection.
QVector< PmuppRun > fRun
vector of all runs in this collection
Represents a single fit parameter with its value and uncertainties.
double GetNegErr()
Gets the negative error of the parameter.
void SetPosErr(double dval)
Sets the positive error of the parameter.
PmuppParam()
Default constructor for PmuppParam.
double fNegErr
negative (lower) error of the parameter
void SetName(QString name)
Sets the parameter name.
void SetParam(QString name, double param, double posErr)
Sets parameter with symmetric errors.
double GetPosErr()
Gets the positive error of the parameter.
double fValue
central value of the parameter
void SetValue(double dval)
Sets the parameter value.
void ResetParam()
Resets the parameter to undefined state.
double GetValue()
Gets the parameter value.
void SetNegErr(double dval)
Sets the negative error of the parameter.
QString fName
parameter name (e.g., "alpha", "lambda", "phase")
double fPosErr
positive (upper) error of the parameter
QString GetName()
Gets the parameter name.
Represents all fit parameters from a single experimental run.
void Clear()
Clears all run data and resets to initial state.
void SetName(QString name)
Sets the run name/title.
int GetNumber()
Gets the run number.
PmuppParam GetParam(unsigned int idx)
Retrieves a parameter from a run by index.
void SetNumber(int ival)
Sets the run number.
void AddParam(PmuppParam param)
Adds a parameter to this run.
QVector< PmuppParam > fParam
vector of all fit parameters for this run
QString GetName()
Gets the run name/title.
int GetNoOfParam()
Gets the number of parameters in this run.