71#include <QApplication>
80#include <QListWidgetItem>
81#include <QInputDialog>
86#include <QProcessEnvironment>
93#include "mupp_version.h"
95#include "git-revision.h"
161 for (
int i=0; i<
fYlabel.size(); i++) {
210 int idx =
fXlabel.lastIndexOf(
"-)");
213 str.remove(idx, str.length()-idx);
223 idx = str.toInt(&ok);
257 int iidx =
fXlabel.lastIndexOf(
"-)");
260 str.remove(iidx, str.length()-iidx);
270 iidx = str.toInt(&ok);
296 int length = errMsg.length();
298 fErrMsg =
new QPlainTextEdit(errMsg);
299 fOK =
new QPushButton(
"Done",
this);
303 QVBoxLayout *layout =
new QVBoxLayout;
305 layout->addWidget(
fOK);
307 connect(
fOK, SIGNAL( clicked() ),
this, SLOT( accept() ));
310 int noBreaks = errMsg.count(
'\n');
311 int width = 20*length / noBreaks;
316 setMinimumWidth(width);
345 QDateTime dt = QDateTime::currentDateTime();
346 fDatime = dt.toSecsSinceEpoch();
362 bool dataAtStartup =
false;
363 if (fln.size() > 0) {
364 if (fln[0].contains(
".msr")) {
366 QString collName = QString(
"collName0");
369 QString errorMsg(
"");
371 QMessageBox::critical(
this,
"ERROR", errorMsg);
373 dataAtStartup =
true;
379 QString iconName(
"");
381 iconName = QString(
":/icons/mupp-dark.svg");
383 iconName = QString(
":/icons/mupp-plain.svg");
384 setWindowIcon( QIcon( QPixmap(iconName) ) );
395 fBoxLayout_Main = std::make_unique<QBoxLayout>(QBoxLayout::TopToBottom);
398 fBoxLayout_Top = std::make_unique<QBoxLayout>(QBoxLayout::LeftToRight);
403 fColLabel = std::make_unique<QLabel>(
this);
404 fColLabel->setText(
"Collection -> Parameter");
411 fColList = std::make_unique<QListWidget>(
this);
412 fColList->setSelectionMode(QAbstractItemView::ExtendedSelection);
414 fParamList = std::make_unique<QListWidget>(
this);
416 fParamList->setSelectionMode(QAbstractItemView::SingleSelection);
432 fViewX = std::make_unique<QListWidget>(
this);
434 fViewX->viewport()->setAcceptDrops(
true);
435 fViewX->setDropIndicatorShown(
true);
437 fAddX = std::make_unique<QPushButton>(
"add X",
this);
438 fRemoveX = std::make_unique<QPushButton>(
"remove X",
this);
442 fViewY = std::make_unique<QListWidget>(
this);
444 fViewY->viewport()->setAcceptDrops(
true);
445 fViewY->setDropIndicatorShown(
true);
447 fAddY = std::make_unique<QPushButton>(
"add Y",
this);
448 fRemoveY = std::make_unique<QPushButton>(
"remove Y",
this);
451 fAddDitto = std::make_unique<QPushButton>(
"Add Ditto",
this);
452 fPlot = std::make_unique<QPushButton>(
"Plot",
this);
474 fCmdLine = std::make_unique<QLineEdit>(
this);
478 fExitButton = std::make_unique<QPushButton>(
"E&xit",
this);
480 QVBoxLayout *cmdLayout =
new QVBoxLayout;
481 QLabel *cmdLabel =
new QLabel(
"History:");
482 cmdLayout->addWidget(cmdLabel);
484 cmdLayout->addWidget(
fCmdLine.get());
486 fBoxLayout_Cmd = std::make_unique<QBoxLayout>(QBoxLayout::LeftToRight);
492 fCmdSplitter = std::make_unique<QSplitter>(Qt::Vertical,
this);
493 QWidget *topWidget =
new QWidget(
this);
495 QWidget *cmdWidget =
new QWidget(
this);
505 connect(
fAddX.get(), SIGNAL( pressed() ),
this, SLOT(
addX() ));
506 connect(
fAddY.get(), SIGNAL( pressed() ),
this, SLOT(
addY() ));
510 connect(
fPlot.get(), SIGNAL( pressed()),
this, SLOT(
plot()) );
515 connect(
fColList.get(), SIGNAL( itemDoubleClicked(QListWidgetItem*) ),
this, SLOT(
editCollName(QListWidgetItem*) ));
517 connect(
fViewX.get(), SIGNAL( currentRowChanged(
int) ),
this, SLOT(
refreshY() ));
518 connect(
fViewX.get(), SIGNAL( itemChanged(QListWidgetItem*) ),
this, SLOT(
dropOnViewX(QListWidgetItem*) ));
519 connect(
fViewY.get(), SIGNAL( itemChanged(QListWidgetItem*) ),
this, SLOT(
dropOnViewY(QListWidgetItem*) ));
531 if (fln.size() == 0) {
557 if (
fMuppPlot->state() != QProcess::NotRunning) {
567 key = ftok(QCoreApplication::applicationFilePath().toLatin1().data(), 1);
574 msqid = msgget(key, flags | S_IRUSR | S_IWUSR);
576 if (msgctl(msqid, IPC_RMID, NULL) == -1) {
577 std::cerr <<
"**ERROR** couldn't removed the message queue (msqid=" << msqid <<
", " << std::strerror(errno) <<
")." << std::endl << std::endl;
583 QProcessEnvironment env = QProcessEnvironment::systemEnvironment();
585 QString pathName = QString(
"%1/.musrfit/mupp/_mupp_%2.dat").arg(env.value(
"HOME")).arg(
fDatime);
586 QFile::remove(pathName);
587 pathName = QString(
"%1/.musrfit/mupp/_mupp_ftok_%2.dat").arg(env.value(
"HOME")).arg(
fMuppInstance);
588 QFile::remove(pathName);
613 QToolBar *tb =
new QToolBar(
this );
614 tb->setWindowTitle(
"File Actions" );
617 QMenu *menu =
new QMenu( tr(
"F&ile" ),
this );
618 menuBar()->addMenu( menu );
622 QString iconName(
"");
624 iconName = QString(
":/icons/document-open-dark.svg");
626 iconName = QString(
":/icons/document-open-plain.svg");
627 a =
new QAction( QIcon( QPixmap(iconName) ), tr(
"&Open..." ),
this );
628 a->setShortcut( tr(
"Ctrl+O") );
629 a->setStatusTip( tr(
"Open a musrfit parameter file.") );
630 connect( a, SIGNAL( triggered() ),
this, SLOT(
fileOpen() ) );
633 iconName = QString(
":/icons/document-open-plain.svg");
634 a =
new QAction( QIcon( QPixmap(iconName) ), tr(
"&New..." ),
this );
635 connect( a, SIGNAL( triggered() ),
this, SLOT(
fileOpen() ) );
648 a =
new QAction( tr(
"E&xit" ),
this );
649 a->setShortcut( tr(
"Ctrl+Q") );
650 a->setStatusTip( tr(
"Exit Program") );
651 connect( a, SIGNAL( triggered() ),
this, SLOT(
fileExit() ) );
661 QMenu *menu =
new QMenu( tr(
"&Tools" ),
this );
662 menuBar()->addMenu( menu );
666 a =
new QAction(tr(
"Plot ..." ),
this );
667 a->setStatusTip( tr(
"Plot x/y parameters") );
668 connect( a, SIGNAL( triggered() ),
this, SLOT(
plot() ) );
671 a =
new QAction(tr(
"Create ROOT Macro ..." ),
this );
672 a->setStatusTip( tr(
"Creates a ROOT Macro with the given x/y parameters") );
673 connect( a, SIGNAL( triggered() ),
this, SLOT(
createMacro() ) );
676 menu->addSeparator();
678 a =
new QAction(tr(
"Dump Collections ..." ),
this );
679 a->setStatusTip( tr(
"Dump all collections") );
683 a =
new QAction(tr(
"Dump XY ..." ),
this );
684 a->setStatusTip( tr(
"Dump XY parameter list") );
685 connect( a, SIGNAL( triggered() ),
this, SLOT(
toolDumpXY() ) );
688 menu->addSeparator();
690 a =
new QAction(tr(
"Add Variable" ),
this );
691 a->setStatusTip( tr(
"Calls a dialog which allows to add variables which are expressions of db/dat vars.") );
692 connect( a, SIGNAL( triggered() ),
this, SLOT(
addVar() ));
695 menu->addSeparator();
710 QMenu *menu =
new QMenu( tr(
"&Help" ),
this );
711 menuBar()->addMenu( menu );
721 a =
new QAction( tr(
"Cmd's" ),
this );
722 a->setStatusTip( tr(
"Lists the command line commands" ) );
723 connect( a, SIGNAL( triggered() ),
this, SLOT(
helpCmds() ));
726 a =
new QAction( tr(
"Author(s) ..." ),
this );
727 a->setStatusTip( tr(
"About the Author(s)") );
728 connect( a, SIGNAL( triggered() ),
this, SLOT(
helpAbout() ));
731 a =
new QAction( tr(
"About Qt..." ),
this );
732 a->setStatusTip( tr(
"Help About Qt") );
733 connect( a, SIGNAL( triggered() ),
this, SLOT(
helpAboutQt() ));
743 QStringList list = QFileDialog::getOpenFileNames(
745 "muSR Parameter Files",
747 "dat-files (*.dat);; db-Files (*.db);; All Params (*.msr *.db *.dat);; Msr-Files (*.msr);; All (*)");
749 if (list.count() == 0)
752 bool msrPresent =
false;
753 bool dbPresent =
false;
754 for (
int i=0; i<list.count(); i++) {
755 if (list[i].endsWith(
".msr"))
757 else if (list[i].endsWith(
".db") || list[i].endsWith(
".dat"))
760 QMessageBox::critical(
this,
"ERROR", QString(
"Found file with unkown extension:\n%1\nWill not do anything here.").arg(list[i]));
765 if (msrPresent && dbPresent) {
766 QMessageBox::critical(
this,
"ERROR",
"Currently mixed reading of msr and db/dat is not supported.");
770 QString errorMsg(
"");
772 QMessageBox::critical(
this,
"ERROR", errorMsg);
777 if (msrPresent || dbPresent) {
778 for (
int i=0; i<list.size(); i++) {
779 fAdmin->addRecentFile(list[i]);
791 QAction *action = qobject_cast<QAction *>(sender());
795 fln << action->text();
796 QString errorMsg(
"");
798 QMessageBox::critical(
this,
"ERROR", errorMsg);
822 QMessageBox::warning(
this,
"dump collections",
"no collections present");
832 if (
fXY.size() > 0) {
833 for (
int i=0; i<
fXY.size(); i++) {
834 qInfo() <<
"<-><-><-><-><-><-><-><-><-><->";
835 qInfo() << i <<
": collection tag: " <<
fXY[i].getCollectionTag();
836 qInfo() <<
" x-param: " <<
fXY[i].getXlabel();
837 for (
int j=0; j<
fXY[i].getYlabelSize(); j++)
838 qInfo() <<
" y-param: " <<
fXY[i].getYlabel(j);
841 QMessageBox::warning(
this,
"dump XY",
"no XY list present yet");
861 QMessageBox::information(
this,
"cmd help",
"<b>help:</b> this help.<br>"\
862 "<b>add var</b>: allows to add a variable which is formula of collection vars.<br>"\
863 "<b>ditto</b>: addX/Y for the new selection as for the previous ones.<br>"\
864 "<b>dump collections:</b> dumps all currently loaded collections.<br>"\
865 "<b>dump XY:</b> dumps X/Y tree.<br>"\
866 "<b>exit/quit:</b> close mupp.<br>"\
867 "<b>load:</b> calls the open file dialog.<br>"\
868 "<b>norm <flag>:</b> normalize plots to maximum if <flag> is true<br>"\
869 "<b>macro <fln>:</b> saves the X/Y data as a ROOT macro (*.C).<br>"\
870 "<b>path <macroPath>:</b> sets the path to the place where the macros will be saved.<br>"\
871 "<b>plot:</b> plot the X/Y data.<br>"\
872 "<b>refresh:</b> refresh the currently selected collection.<br>"\
873 "<b>select <nn>:</b> select collection in GUI.<br>"\
874 " <nn> is either the collection name or the row number.<br>"\
875 "<b>x <param_name> / y <param_name>:</b> add the parameter to the select axis.<br>"\
876 "<b>rmx <param_name> / rmy <param_name>:</b> remove the parameter of the select axis.<br>"\
877 "<b>flush:</b> flush the history buffer.");
887 QMessageBox::information(
this,
"about", QString(
"mupp: created by Andreas Suter.\nVersion: %1\nBranch: %2\nHash: %3").arg(MUPP_VERSION).arg(GIT_BRANCH).arg(GIT_CURRENT_SHA1));
889 QMessageBox::information(
this,
"about", QString(
"mupp: created by Andreas Suter.\nVersion: %1").arg(MUPP_VERSION));
899 QMessageBox::aboutQt(
this);
914 if (e->type() == QEvent::KeyPress) {
915 QKeyEvent *k =
static_cast<QKeyEvent*
>(e);
917 if (key == Qt::Key_Up) {
922 }
else if (key == Qt::Key_Down) {
929 }
else if (key == Qt::Key_Return) {
948 return QMainWindow::eventFilter(o, e);
964 QString str = QIcon::themeName();
967 if (
fAdmin->getDarkThemeIconsMenuFlag()) {
970 if (
fAdmin->getDarkThemeIconsToolbarFlag()) {
976 if (str.contains(
"dark", Qt::CaseInsensitive)) {
978 if (str.contains(
"ubuntu", Qt::CaseInsensitive) ||
979 str.contains(
"xfce", Qt::CaseInsensitive)) {
993 for (
int i=0; i<
fAdmin->getNumRecentFiles(); i++) {
1006 QProcessEnvironment procEnv = QProcessEnvironment::systemEnvironment();
1007 QString home = procEnv.value(
"HOME",
"");
1011 QString pathName = home +
"/.musrfit/mupp/mupp_history.txt";
1013 QFile file(pathName);
1014 if (!file.open(QIODevice::ReadOnly | QIODevice::Text)) {
1015 std::cerr << std::endl;
1016 std::cerr <<
"***********" << std::endl;
1017 std::cerr <<
"**WARNING** readCmdHistory(): couldn't open mupp_history.txt for reading ..." << std::endl;;
1018 std::cerr <<
"***********" << std::endl;
1022 QTextStream fin(&file);
1026 while (!fin.atEnd()) {
1027 line = fin.readLine();
1028 if (line.startsWith(
"%") || line.isEmpty())
1040 QProcessEnvironment procEnv = QProcessEnvironment::systemEnvironment();
1041 QString home = procEnv.value(
"HOME",
"");
1045 QString pathName = home +
"/.musrfit/mupp/";
1047 if (!dir.exists()) {
1049 dir.mkpath(pathName);
1051 pathName +=
"mupp_history.txt";
1053 QFile file(pathName);
1054 if (!file.open(QIODevice::WriteOnly | QIODevice::Text))
1057 QTextStream fout(&file);
1060 QDateTime dt = QDateTime::currentDateTime();
1061 fout <<
"% mupp history file" << Qt::endl;
1062 fout <<
"% " << dt.toString(
"HH:mm:ss - yy/MM/dd") << Qt::endl;
1068 fout <<
"% end mupp history file" << Qt::endl;
1079 QListWidgetItem *item =
fColList->currentItem();
1082 QString label = item->text();
1084 QString pathName(
"");
1089 QDir dir(QDir::currentPath());
1099 if (pathName.endsWith(
".db")) {
1100 QString errorMsg(
"");
1103 QMessageBox::critical(
this,
"ERROR - REFRESH",
1104 QString(
"Couldn't refresh %1\nFile corrupted?!\n").arg(
fParamDataHandler->GetCollection(collIdx)->GetName())+
1108 }
else if (pathName.endsWith(
".dat")) {
1109 QString errorMsg(
"");
1112 QMessageBox::critical(
this,
"ERROR - REFRESH",
1113 QString(
"Couldn't refresh %1\nFile corrupted?!\n").arg(
fParamDataHandler->GetCollection(collIdx)->GetName())+
1118 QMessageBox::critical(
this,
"ERROR - REFRESH",
1119 QString(
"Couldn't refresh %1").arg(
fParamDataHandler->GetCollection(collIdx)->GetName()));
1123 QString collName = pathName;
1124 int pos = collName.lastIndexOf(
"/");
1125 collName.remove(0, pos+1);
1144 QListWidgetItem *item =
fColList->currentItem();
1148 QString collName = item->text();
1173 fColList->setCurrentRow(idx, QItemSelectionModel::Select);
1189 QString paramName(
"");
1190 if (!param.isEmpty()) {
1192 if (
fParamList->findItems(param, Qt::MatchCaseSensitive).empty()) {
1193 QMessageBox::critical(
this,
"ERROR", QString(
"Parameter X '%1' not found").arg(param));
1199 QListWidgetItem *item =
fParamList->currentItem();
1202 paramName = item->text();
1205 QString xLabel = QString(
"%1 (-%2-)").arg(paramName).arg(idx);
1208 for (
int i=0; i<
fViewX->count(); i++) {
1209 if (
fViewX->item(i)->text() == xLabel)
1222 fXY.push_back(xyItem);
1232 QString paramName(
"");
1233 if (!param.isEmpty()) {
1235 if (
fParamList->findItems(param, Qt::MatchCaseSensitive).empty()) {
1236 QMessageBox::critical(
this,
"ERROR", QString(
"Parameter Y '%1' not found").arg(param));
1242 QListWidgetItem *item =
fParamList->currentItem();
1245 paramName = item->text();
1248 QString yLabel = QString(
"%1 (-%2-)").arg(paramName).arg(idx);
1251 if (
fViewX->count() == 0) {
1252 QMessageBox::warning(
this,
"WARNING",
"It is compulsory to have at least one x-parameter set\nbefore trying to add a y-parameter.");
1260 if (
fXY[idx].getCollectionTag() !=
fColList->currentRow()) {
1261 QMessageBox::warning(
this,
"WARNING",
"x/y parameters need to originate from the same collection.");
1266 for (
int i=0; i<
fViewY->count(); i++) {
1267 if (
fViewY->item(i)->text() == yLabel)
1279 fXY[idx].addYlabel(yLabel);
1289 QListWidgetItem *item =
fViewX->currentItem();
1294 if (!param.isEmpty()) {
1296 param = QString(
"%1 (-%2-)").arg(param).arg(idx);
1306 fViewX->removeItemWidget(item);
1317 QListWidgetItem *item =
fViewY->currentItem();
1322 QString xLabel =
fViewX->currentItem()->text();
1323 QString yLabel = item->text();
1324 if (!param.isEmpty()) {
1330 fXY[idx].removeYlabel(yLabel);
1332 fViewY->removeItemWidget(item);
1344 if (
fXY.size() == 0) {
1345 QMessageBox::critical(
this,
"ERROR",
"No x/y items present.\nTherefore nothing to be done.");
1350 QMessageBox::critical(
this,
"ERROR",
"Multiple unequal sets of x/y items present.\nDo not know how to handle.");
1355 QList<QListWidgetItem*> items =
fColList->selectedItems();
1356 if (items.count() == 0) {
1364 for (
int i=0; i<items.count(); i++) {
1381 for (
int i=0; i<items.count(); i++) {
1386 fXY.push_back(muXY);
1404 QVector<PCollInfo> collection_list;
1412 for (
int j=0; j<
fParamDataHandler->GetCollection(i)->GetRun(0).GetNoOfParam(); j++) {
1415 collection_list.push_back(collInfo);
1421 connect(
fVarDlg.get(), SIGNAL(check_request(QString,QVector<int>)),
this, SLOT(
check(QString,QVector<int>)));
1422 connect(
fVarDlg.get(), SIGNAL(add_request(QString,QVector<int>)),
this, SLOT(
add(QString,QVector<int>)));
1438 std::vector<PmuppCollection*> allColl;
1443 for (
int i=0; i<idx.size(); i++) {
1445 std::string(), allColl);
1453 if (count == idx.size()) {
1454 QMessageBox::information(
this,
"INFO",
"Parsing successful.");
1474 std::vector<PmuppCollection*> allColl;
1479 for (
int i=0; i<idx.size(); i++) {
1481 for (
int j=0; j<varNames.count(); j++) {
1483 varStr.toLatin1().data(),
1484 varNames[j].toLatin1().data(),
1521 QString mupp_err = QString(
"%1/.musrfit/mupp/mupp_err.log").arg(QString(qgetenv(
"HOME")));
1522 QFile fin(mupp_err);
1524 if (fin.open(QIODevice::ReadOnly | QIODevice::Text)) {
1525 QTextStream in(&fin);
1526 while (!in.atEnd()) {
1527 errStr += in.readLine();
1532 QFile::remove(mupp_err);
1534 if (errStr.isEmpty())
1535 errStr =
"unknown error - should never happen.";
1536 QString msg = QString(
"Parse error(s):\n");
1550 QStringList varNames;
1556 int pyIdx = parseStr.indexOf(
"<python>");
1558 parseStr = parseStr.left(pyIdx);
1560 while (idxS != -1) {
1561 idxS = parseStr.indexOf(
"var", idxS);
1563 idxE = parseStr.indexOf(
"=", idxS);
1564 str = parseStr.mid(idxS+4, idxE-idxS-4).trimmed();
1565 if (!str.endsWith(
"Err"))
1586 QVector<double> values;
1592 if (values.size() == 0) {
1599 std::vector<double> vec =
fVarHandler[i].getValues();
1600 values = QVector<double>(vec.begin(), vec.end());
1605 if (values.size() > 0)
1624 QVector<double> values;
1630 if (values.size() == 0) {
1636 std::vector<double> vec =
fVarHandler[i].getErrors();
1637 values = QVector<double>(vec.begin(), vec.end());
1642 if (values.size() > 0)
1661 QVector<double> values;
1667 if (values.size() == 0) {
1673 std::vector<double> vec =
fVarHandler[i].getErrors();
1674 values = QVector<double>(vec.begin(), vec.end());
1679 if (values.size() > 0)
1694 bool result =
false;
1697 for (
int i=0; i<
fXY.size(); i++) {
1705 }
else if (tag ==
kYaxis) {
1706 for (
int i=0; i<
fXY.size(); i++) {
1707 for (
int j=0; j<
fXY[i].getYlabelSize(); j++) {
1732 str1 =
fXY[0].getXlabel();
1733 idx = str1.lastIndexOf(
" (-");
1734 str1.remove(idx, str1.length()-idx);
1735 for (
int i=1; i<
fXY.size(); i++) {
1736 str2 =
fXY[i].getXlabel();
1737 idx = str2.lastIndexOf(
" (-");
1738 str2.remove(idx, str2.length()-idx);
1744 for (
int i=1; i<
fXY.size(); i++) {
1745 if (
fXY[0].getYlabelSize() !=
fXY[i].getYlabelSize())
1750 for (
int j=0; j<
fXY[0].getYlabelSize(); j++) {
1751 str1 =
fXY[0].getYlabel(j);
1752 idx = str1.lastIndexOf(
" (-");
1753 str1.remove(idx, str1.length()-idx);
1754 for (
int i=1; i<
fXY.size(); i++) {
1755 str2 =
fXY[i].getYlabel(j);
1756 idx = str2.lastIndexOf(
" (-");
1757 str2.remove(idx, str2.length()-idx);
1775 QString str = QString(
"(-%1-)").arg(idx);
1777 for (
int i=0; i<
fXY.size(); i++) {
1778 if (
fXY[i].getXlabel().contains(str))
1795 int pos = label.lastIndexOf(
" (-");
1796 label.truncate(pos);
1797 QString str = QString(
" (-%1-)").arg(idx);
1804 int pos = label.lastIndexOf(
" (-");
1805 label.truncate(pos);
1823 for (
int i=0; i<
fXY.size(); i++) {
1824 if (
fXY[i].getXlabel() == label) {
1843 if (item->text().contains(
"(-"))
1847 QString xLabel = QString(
"%1 (-%2-)").arg(item->text()).arg(idx);
1850 for (
int i=0; i<
fViewX->count(); i++) {
1851 if (
fViewX->item(i)->text() == xLabel) {
1852 fViewX->removeItemWidget(item);
1858 fViewX->setCurrentItem(item);
1859 fViewX->currentItem()->setText(xLabel);
1866 fXY.push_back(xyItem);
1879 if (item->text().contains(
"(-"))
1883 if (
fViewX->count() == 0) {
1884 fViewY->removeItemWidget(item);
1886 QMessageBox::warning(
this,
"WARNING",
"It is compulsory to have at least one x-parameter set\nbefore trying to add a y-parameter.");
1891 QString yLabel = QString(
"%1 (-%2-)").arg(item->text()).arg(idx);
1894 for (
int i=0; i<
fViewY->count(); i++) {
1895 if (
fViewY->item(i)->text() == yLabel) {
1896 fViewY->removeItemWidget(item);
1902 fViewY->setCurrentItem(item);
1903 fViewY->currentItem()->setText(yLabel);
1910 fXY[idx].addYlabel(yLabel);
1923 QListWidgetItem *item =
fViewX->currentItem();
1927 QString xLabel = item->text();
1932 for (
int i=0; i<
fXY[idx].getYlabelSize(); i++)
1942 QVector<PmuppMarker> marker =
fAdmin->getMarkers();
1943 QVector<PmuppColor> color =
fAdmin->getColors();
1945 if (
fXY.size() == 0) {
1946 QMessageBox::information(
this,
"createMacro",
"No parameter list present.");
1961 if (!file.open(QIODevice::WriteOnly | QIODevice::Text)) {
1962 QMessageBox::critical(
this,
"ERROR",
"Couldn't open macro file for writting.");
1966 QTextStream fout(&file);
1968 fout <<
"// " <<
fMacroName.toLatin1().data() << Qt::endl;
1969 fout <<
"// " << QDateTime::currentDateTime().toString(
"yy/MM/dd - HH:mm:ss") << Qt::endl;
1970 fout <<
"// " << Qt::endl;
1971 fout <<
"{" << Qt::endl;
1972 fout <<
" gROOT->Reset();" << Qt::endl;
1974 fout <<
" gStyle->SetOptTitle(0);" << Qt::endl;
1975 fout <<
" gStyle->SetOptDate(0);" << Qt::endl;
1976 fout <<
" gStyle->SetPadColor(TColor::GetColor(255,255,255)); // pad bkg to white" << Qt::endl;
1977 fout <<
" gStyle->SetCanvasColor(TColor::GetColor(255,255,255)); // canvas bkg to white" << Qt::endl;
1979 fout <<
" Int_t nn=0, i=0;" << Qt::endl;
1980 fout <<
" Double_t xx[512];" << Qt::endl;
1981 fout <<
" Double_t xxPosErr[512];" << Qt::endl;
1982 fout <<
" Double_t xxNegErr[512];" << Qt::endl;
1983 fout <<
" Double_t yy[512];" << Qt::endl;
1984 fout <<
" Double_t yyPosErr[512];" << Qt::endl;
1985 fout <<
" Double_t yyNegErr[512];" << Qt::endl;
1988 int collTag = -1, pos;
1989 QString collName(
"");
1990 QString xLabel(
""), yLabel(
"");
1992 QVector<double> xx, xxPosErr, xxNegErr, yy, yyPosErr, yyNegErr;
1993 double xMin=1.0e10, xMax=-1.0e10, yMin=1.0e10, yMax=-1.0e10;
1995 for (
int i=0; i<
fXY.size(); i++) {
1996 collTag =
fXY[i].getCollectionTag();
1997 collName =
fColList->item(collTag)->text();
1999 xLabel =
fXY[i].getXlabel();
2000 pos = xLabel.indexOf(
" (-");
2001 xLabel.remove(pos, xLabel.length()-pos);
2005 QString msg = QString(
"Couldn't get x-axis data from '%1', coll: '%2'").arg(xLabel).arg(collName);
2006 QMessageBox::critical(
this,
"ERROR", msg);
2009 xxPosErr =
getPosErr(collName, xLabel, ok);
2011 xxPosErr = QVector<double>(xx.size(), 0.0);
2012 xxNegErr =
getNegErr(collName, xLabel, ok);
2014 xxNegErr = QVector<double>(xx.size(), 0.0);
2017 if ((xLabel ==
"dataT") || (xLabel ==
"dataE"))
2020 for (
int j=0; j<
fXY[i].getYlabelSize(); j++) {
2022 yLabel =
fXY[i].getYlabel(j);
2023 pos = yLabel.indexOf(
" (-");
2024 yLabel.remove(pos, yLabel.length()-pos);
2028 QString msg = QString(
"Couldn't get y-axis data from '%1', coll: '%2'").arg(yLabel).arg(collName);
2029 QMessageBox::critical(
this,
"ERROR", msg);
2032 yyPosErr =
getPosErr(collName, yLabel, ok);
2034 QString msg = QString(
"Couldn't get y-axis pos. error data from '%1', coll: '%2'").arg(yLabel).arg(collName);
2035 QMessageBox::critical(
this,
"ERROR", msg);
2038 yyNegErr =
getNegErr(collName, yLabel, ok);
2040 QString msg = QString(
"Couldn't get y-axis neg. error data from '%1', coll: '%2'").arg(yLabel).arg(collName);
2041 QMessageBox::critical(
this,
"ERROR", msg);
2048 snprintf(gLabel,
sizeof(gLabel),
"g_%d_%d", i, j);
2049 fout <<
" nn = " << xx.size() <<
";" << Qt::endl;
2051 fout <<
" // xx" << Qt::endl;
2052 for (
int k=0; k<xx.size(); k++) {
2053 fout <<
" xx[" << k <<
"]=" << xx[k] <<
";" << Qt::endl;
2055 fout <<
" // xxPosErr" << Qt::endl;
2056 for (
int k=0; k<xx.size(); k++) {
2057 fout <<
" xxPosErr[" << k <<
"]=" << xxPosErr[k] <<
";" << Qt::endl;
2059 fout <<
" // xxNegErr" << Qt::endl;
2060 for (
int k=0; k<xx.size(); k++) {
2061 fout <<
" xxNegErr[" << k <<
"]=" << fabs(xxNegErr[k]) <<
";" << Qt::endl;
2063 fout <<
" // yy" << Qt::endl;
2064 for (
int k=0; k<xx.size(); k++) {
2065 fout <<
" yy[" << k <<
"]=" << yy[k] <<
";" << Qt::endl;
2067 fout <<
" // yyPosErr" << Qt::endl;
2068 for (
int k=0; k<xx.size(); k++) {
2069 fout <<
" yyPosErr[" << k <<
"]=" << yyPosErr[k] <<
";" << Qt::endl;
2071 fout <<
" // yyNegErr" << Qt::endl;
2072 for (
int k=0; k<xx.size(); k++) {
2073 fout <<
" yyNegErr[" << k <<
"]=" << fabs(yyNegErr[k]) <<
";" << Qt::endl;
2076 fout <<
" TGraphAsymmErrors *" << gLabel <<
" = new TGraphAsymmErrors(nn, xx, yy, xxNegErr, xxPosErr, yyNegErr, yyPosErr);" << Qt::endl;
2080 fout <<
" //***************" << Qt::endl;
2081 fout <<
" // plotting " << Qt::endl;
2082 fout <<
" //***************" << Qt::endl;
2083 fout <<
" TCanvas *c1 = new TCanvas(\"c1\", \"" <<
fMacroName.toLatin1().data() <<
"\", 10, 10, 600, 700);" << Qt::endl;
2087 for (
int i=0; i<
fXY.size(); i++) {
2088 xLabel =
fXY[i].getXlabel();
2089 pos = xLabel.indexOf(
" (-");
2090 xLabel.remove(pos, xLabel.length()-pos);
2092 for (
int j=0; j<
fXY[i].getYlabelSize(); j++) {
2093 idx = i*
fXY[i].getYlabelSize()+j;
2094 markerObj = marker[idx];
2095 yLabel =
fXY[i].getYlabel(j);
2096 pos = yLabel.indexOf(
" (-");
2097 yLabel.remove(pos, yLabel.length()-pos);
2099 snprintf(gLabel,
sizeof(gLabel),
"g_%d_%d", i, j);
2100 if ((i==0) && (j==0)) {
2101 if (idx < marker.size()) {
2102 fout <<
" " << gLabel <<
"->SetMarkerStyle(" << markerObj.
getMarker() <<
");" << Qt::endl;
2103 fout <<
" " << gLabel <<
"->SetMarkerSize(" << markerObj.
getMarkerSize() <<
");" << Qt::endl;
2105 fout <<
" " << gLabel <<
"->SetMarkerStyle(20); // bullet" << Qt::endl;
2106 fout <<
" " << gLabel <<
"->SetMarkerSize(1.5);" << Qt::endl;
2108 if (idx < color.size()) {
2109 color[idx].getRGB(r, g, b);
2110 fout <<
" " << gLabel <<
"->SetMarkerColor(TColor::GetColor(" << r <<
"," << g <<
"," << b <<
"));" << Qt::endl;
2111 fout <<
" " << gLabel <<
"->SetLineColor(TColor::GetColor(" << r <<
"," << g <<
"," << b <<
"));" << Qt::endl;
2113 fout <<
" " << gLabel <<
"->SetMarkerColor(kBlue);" << Qt::endl;
2114 fout <<
" " << gLabel <<
"->SetLineColor(kBlue);" << Qt::endl;
2116 fout <<
" " << gLabel <<
"->SetFillColor(kWhite);" << Qt::endl;
2117 fout <<
" " << gLabel <<
"->GetXaxis()->SetTitle(\"" << xLabel.toLatin1().data() <<
"\");" << Qt::endl;
2118 fout <<
" " << gLabel <<
"->GetXaxis()->SetTitleSize(0.05);" << Qt::endl;
2119 fout <<
" " << gLabel <<
"->GetXaxis()->SetRangeUser(" << 0.95*xMin <<
", " << 1.05*xMax <<
");" << Qt::endl;
2120 fout <<
" " << gLabel <<
"->GetYaxis()->SetTitle(\"" << yLabel.toLatin1().data() <<
"\");" << Qt::endl;
2121 fout <<
" " << gLabel <<
"->GetYaxis()->SetTitleSize(0.05);" << Qt::endl;
2122 fout <<
" " << gLabel <<
"->GetYaxis()->SetTitleOffset(1.30);" << Qt::endl;
2123 fout <<
" " << gLabel <<
"->GetYaxis()->SetRangeUser(" << 0.95*yMin <<
", " << 1.05*yMax <<
");" << Qt::endl;
2124 fout <<
" " << gLabel <<
"->GetXaxis()->SetDecimals(kTRUE);" << Qt::endl;
2125 fout <<
" " << gLabel <<
"->Draw(\"AP\");" << Qt::endl;
2127 if (idx < marker.size()) {
2128 fout <<
" " << gLabel <<
"->SetMarkerStyle(" << markerObj.
getMarker() <<
");" << Qt::endl;
2129 fout <<
" " << gLabel <<
"->SetMarkerSize(" << markerObj.
getMarkerSize() <<
");" << Qt::endl;
2131 fout <<
" " << gLabel <<
"->SetMarkerStyle(" << 21+j <<
");" << Qt::endl;
2132 fout <<
" " << gLabel <<
"->SetMarkerSize(1.5);" << Qt::endl;
2134 if (idx < color.size()) {
2135 color[idx].getRGB(r, g, b);
2136 fout <<
" " << gLabel <<
"->SetMarkerColor(TColor::GetColor(" << r <<
"," << g <<
"," << b <<
"));" << Qt::endl;
2137 fout <<
" " << gLabel <<
"->SetLineColor(TColor::GetColor(" << r <<
"," << g <<
"," << b <<
"));" << Qt::endl;
2139 fout <<
" " << gLabel <<
"->SetMarkerColor(kBlue);" << Qt::endl;
2140 fout <<
" " << gLabel <<
"->SetLineColor(kBlue);" << Qt::endl;
2142 fout <<
" " << gLabel <<
"->SetFillColor(kWhite);" << Qt::endl;
2143 fout <<
" " << gLabel <<
"->Draw(\"Psame\");" << Qt::endl;
2147 fout <<
"}" << Qt::endl;
2161 if (
fXY.size() == 0) {
2162 QMessageBox::information(
this,
"PLOT",
"No parameter list present.");
2168 QProcessEnvironment env = QProcessEnvironment::systemEnvironment();
2169 QString pathName = QString(
"%1/.musrfit/mupp/_mupp_%2.dat").arg(env.value(
"HOME")).arg(
fDatime);
2171 int collTag = -1, pos;
2172 QString collName(
"");
2173 QString xLabel(
""), yLabel(
"");
2174 QVector<double> xx, xxPosErr, xxNegErr, yy, yyPosErr, yyNegErr;
2175 QVector< QVector<double> > yyy, yyyPosErr, yyyNegErr;
2178 QFile file(pathName);
2179 if (!file.open(QIODevice::WriteOnly | QIODevice::Text)) {
2180 QMessageBox::critical(
this,
"ERROR",
"Couldn't write necessary temporary file!");
2183 QTextStream fout(&file);
2185 fout <<
"% path file name: " << pathName << Qt::endl;
2186 fout <<
"% creation time : " << QDateTime::currentDateTime().toString(
"yyyy.MM.dd - hh:mm:ss") << Qt::endl;
2187 fout <<
"%" << Qt::endl;
2188 for (
int i=0; i<
fXY.size(); i++) {
2190 collTag =
fXY[i].getCollectionTag();
2191 collName =
fColList->item(collTag)->text();
2193 fout <<
"% ---------" << Qt::endl;
2194 fout <<
"% collName = " << collName << Qt::endl;
2195 fout <<
"% start ---" << Qt::endl;
2198 xLabel =
fXY[i].getXlabel();
2199 pos = xLabel.indexOf(
" (-");
2200 xLabel.remove(pos, xLabel.length()-pos);
2204 QString msg = QString(
"Couldn't get x-axis data from '%1', coll: '%2'").arg(xLabel).arg(collName);
2205 QMessageBox::critical(
this,
"ERROR", msg);
2208 xxPosErr =
getPosErr(collName, xLabel, ok);
2210 xxPosErr = QVector<double>(xx.size(), 0.0);
2211 xxNegErr =
getNegErr(collName, xLabel, ok);
2213 xxNegErr = QVector<double>(xx.size(), 0.0);
2216 fout <<
"xLabel: " << xLabel <<
", ";
2217 for (
int j=0; j<
fXY[i].getYlabelSize()-1; j++) {
2219 yLabel =
fXY[i].getYlabel(j);
2220 pos = yLabel.indexOf(
" (-");
2221 yLabel.remove(pos, yLabel.length()-pos);
2225 QString msg = QString(
"Couldn't get y-axis data from '%1', coll: '%2'").arg(yLabel).arg(collName);
2226 QMessageBox::critical(
this,
"ERROR", msg);
2230 yyPosErr =
getPosErr(collName, yLabel, ok);
2232 QString msg = QString(
"Couldn't get y-axis pos. error data from '%1', coll: '%2'").arg(yLabel).arg(collName);
2233 QMessageBox::critical(
this,
"ERROR", msg);
2236 yyyPosErr.push_back(yyPosErr);
2237 yyNegErr =
getNegErr(collName, yLabel, ok);
2239 QString msg = QString(
"Couldn't get y-axis neg. error data from '%1', coll: '%2'").arg(yLabel).arg(collName);
2240 QMessageBox::critical(
this,
"ERROR", msg);
2243 yyyNegErr.push_back(yyNegErr);
2245 fout <<
"yLabel: " << yLabel <<
", ";
2248 int idx=
fXY[i].getYlabelSize()-1;
2249 yLabel =
fXY[i].getYlabel(idx);
2250 pos = yLabel.indexOf(
" (-");
2251 yLabel.remove(pos, yLabel.length()-pos);
2255 QString msg = QString(
"Couldn't get y-axis data from '%1', coll: '%2'").arg(yLabel).arg(collName);
2256 QMessageBox::critical(
this,
"ERROR", msg);
2260 yyPosErr =
getPosErr(collName, yLabel, ok);
2262 QString msg = QString(
"Couldn't get y-axis pos. error data from '%1', coll: '%2'").arg(yLabel).arg(collName);
2263 QMessageBox::critical(
this,
"ERROR", msg);
2266 yyyPosErr.push_back(yyPosErr);
2267 yyNegErr =
getNegErr(collName, yLabel, ok);
2269 QString msg = QString(
"Couldn't get y-axis neg. error data from '%1', coll: '%2'").arg(yLabel).arg(collName);
2270 QMessageBox::critical(
this,
"ERROR", msg);
2273 yyyNegErr.push_back(yyNegErr);
2276 fout <<
"yLabel: " << yLabel << Qt::endl;
2281 for (
int k=0; k<yyy.size(); k++) {
2283 for (
int j=0; j<xx.size(); j++) {
2284 if (yyy[k][j] > max)
2287 for (
int j=0; j<xx.size(); j++) {
2289 yyyPosErr[k][j] /= max;
2290 yyyNegErr[k][j] /= max;
2296 for (
int j=0; j<xx.size(); j++) {
2297 fout << xx[j] <<
", " << xxPosErr[j] <<
", " << xxNegErr[j] <<
", ";
2298 for (
int k=0; k<yyy.size()-1; k++) {
2299 fout << yyy[k][j] <<
", " << yyyPosErr[k][j] <<
", " << yyyNegErr[k][j] <<
", ";
2302 fout << yyy[idx][j] <<
", " << yyyPosErr[idx][j] <<
", " << yyyNegErr[idx][j];
2306 fout <<
"% end -----" << Qt::endl;
2325 QString tmpPathName = QString(
"%1/.musrfit/mupp/_mupp_ftok_%2.dat").arg(env.value(
"HOME")).arg(
fMuppInstance);
2326 file.setFileName(tmpPathName);
2327 if (!file.open(QIODevice::WriteOnly | QIODevice::Text)) {
2328 QMessageBox::critical(
this,
"ERROR",
"Couldn't write necessary temporary file!");
2331 fout.setDevice(&file);
2332 fout << QCoreApplication::applicationFilePath().toLatin1().data() << Qt::endl;
2335 key = ftok(QCoreApplication::applicationFilePath().toLatin1().data(),
fMuppInstance);
2337 QMessageBox::critical(
this,
"ERROR", QString(
"Couldn't obtain necessary key to install the IPC message queue (%1).").arg(std::strerror(errno)));
2345 msqid = msgget(key, flags | S_IRUSR | S_IWUSR);
2347 QMessageBox::critical(
this,
"ERROR", QString(
"Couldn't open the IPC message queue (%1).").arg(std::strerror(errno)));
2355 if (msgsnd(msqid, &msg, strlen(msg.
mtext)+1, flags) == -1) {
2356 QMessageBox::critical(
this,
"ERROR", QString(
"Couldn't send the IPC message (%1).").arg(std::strerror(errno)));
2365 if (
fMuppPlot->state() == QProcess::NotRunning) {
2377 QProcessEnvironment env = QProcessEnvironment::systemEnvironment();
2378 QString cmd = QString(
"%1/bin/mupp_plot").arg(MUPP_PREFIX);
2379#if defined(Q_OS_DARWIN)
2380 cmd = QString(
"/Applications/mupp.app/Contents/MacOS/mupp_plot");
2382 QString workDir = QString(
"./");
2388 fMuppPlot = std::make_unique<QProcess>(
this);
2390 QMessageBox::critical(
this,
"ERROR",
"Couldn't invoke QProcess for mupp_plot!");
2395#if defined(Q_OS_DARWIN)
2396 env.insert(
"DYLD_LIBRARY_PATH", env.value(
"ROOTSYS") +
"/lib:/usr/local/lib:" + env.value(
"DYLD_LIBRARY_PATH"));
2398 env.insert(
"LD_LIBRARY_PATH", env.value(
"ROOTSYS") +
"/lib:" + env.value(
"LD_LIBRARY_PATH"));
2401 fMuppPlot->setWorkingDirectory(workDir);
2405 QString msg(tr(
"Could not execute the output command: ")+cmd);
2406 QMessageBox::critical(
this, tr(
"FATAL ERROR"), msg, QMessageBox::Close );
2421 cmd = cmd.trimmed();
2422 cmd = cmd.remove(
"$ ");
2423 cmd = cmd.trimmed();
2425 if (!cmd.compare(
"exit", Qt::CaseInsensitive) || !cmd.compare(
"quit", Qt::CaseInsensitive)) {
2427 }
else if (!cmd.compare(
"load", Qt::CaseInsensitive) || !cmd.compare(
"open", Qt::CaseInsensitive)) {
2429 }
else if (!cmd.compare(
"dump collections", Qt::CaseInsensitive)) {
2431 }
else if (!cmd.compare(
"dump XY", Qt::CaseInsensitive)) {
2433 }
else if (!cmd.compare(
"refresh", Qt::CaseInsensitive)) {
2435 }
else if (!cmd.compare(
"plot", Qt::CaseInsensitive)) {
2437 }
else if (cmd.startsWith(
"macro")) {
2438 QStringList tok = cmd.split(
" ", Qt::SkipEmptyParts);
2439 if (tok.size() != 2) {
2440 QMessageBox::critical(
this,
"ERROR", QString(
"wrong macro cmd: %1.\nPlease check the help.").arg(cmd));
2445 }
else if (cmd.startsWith(
"path")) {
2446 QMessageBox::information(
this ,
"INFO",
"set's eventually the path for the macros to be saved.");
2448 QStringList tok = cmd.split(
" ", Qt::SkipEmptyParts);
2449 if (tok.size() != 2) {
2450 QMessageBox::critical(
this,
"ERROR", QString(
"wrong path cmd: %1.\nPlease check the help.").arg(cmd));
2457 if (envVar.startsWith(
"$")) {
2459 int pos = envVar.indexOf(
"/");
2462 QProcessEnvironment env = QProcessEnvironment::systemEnvironment();
2463 QString fullPath = env.value(envVar);
2464 if (fullPath.isEmpty()) {
2466 QMessageBox::critical(
this,
"ERROR", QString(
"Environment variable '%1' not present. Typo?!").arg(envVar.prepend(
"$")));
2469 fMacroPath.replace(envVar.prepend(
"$"), fullPath);
2471 }
else if (cmd.startsWith(
"select") || cmd.startsWith(
"sc")) {
2473 }
else if (cmd.startsWith(
"x")) {
2474 QStringList tok = cmd.split(
" ", Qt::SkipEmptyParts);
2478 QMessageBox::critical(
this,
"ERROR", QString(
"Found command 'x' without variable."));
2479 }
else if (cmd.startsWith(
"y")) {
2480 QStringList tok = cmd.split(
" ", Qt::SkipEmptyParts);
2484 QMessageBox::critical(
this,
"ERROR", QString(
"Found command 'y' without variable."));
2485 }
else if (cmd.startsWith(
"ditto")) {
2487 }
else if (cmd.startsWith(
"rmx")) {
2488 QStringList tok = cmd.split(
" ", Qt::SkipEmptyParts);
2492 QMessageBox::critical(
this,
"ERROR", QString(
"Found command 'rmx' without variable."));
2493 }
else if (cmd.startsWith(
"rmy")) {
2494 QStringList tok = cmd.split(
" ", Qt::SkipEmptyParts);
2498 QMessageBox::critical(
this,
"ERROR", QString(
"Found command 'rmy' without variable."));
2499 }
else if (cmd.startsWith(
"norm")) {
2500 QStringList tok = cmd.split(
" ", Qt::SkipEmptyParts);
2501 if (tok.size() != 2) {
2502 QMessageBox::critical(
this,
"ERROR",
"found wrong norm cmd, will ignore it.");
2505 if (!tok[1].trimmed().compare(
"true", Qt::CaseInsensitive)) {
2507 }
else if (!tok[1].trimmed().compare(
"false", Qt::CaseInsensitive)) {
2510 QMessageBox::critical(
this,
"ERROR",
"found wrong norm cmd, will ignore it.");
2513 }
else if (cmd.startsWith(
"add var")) {
2515 }
else if (cmd.startsWith(
"flush")) {
2520 }
else if (cmd.startsWith(
"help")) {
2562 QListWidgetItem *item =
fColList->item(currentRow);
2584 if (
fVarHandler[i].getCollName() == item->text()) {
2598 for (
int i=0; i<
fXY.size(); i++) {
2600 if (
fXY[i].getCollectionTag() == idx) {
2610 for (
int i=0; i<
fXY.size(); i++) {
2611 oldIdx =
fXY[i].getCollectionTag();
2614 fXY[i].setCollectionTag(oldIdx-1);
2616 str =
fXY[i].getXlabel();
2617 pos = str.indexOf(
"(");
2618 str.remove(pos, str.length()-pos);
2619 str += QString(
"(-%1-)").arg(oldIdx-1);
2620 fXY[i].setXlabel(str);
2622 for (
int j=0; j<
fXY[i].getYlabelSize(); j++) {
2623 str =
fXY[i].getYlabel(j);
2624 pos = str.indexOf(
"(");
2625 str.remove(pos, str.length()-pos);
2626 str += QString(
"(-%1-)").arg(oldIdx-1);
2627 fXY[i].setYlabel(j, str);
2642 for (
int i=0; i<
fXY.size(); i++) {
2646 fViewX->setCurrentRow(0);
2657 for (
int i=0; i<
fColList->count(); i++)
2671 QString oldName = item->text();
2672 QString newName = QInputDialog::getText(
this,
"Change Collection Name",
"Collection Name",
2673 QLineEdit::Normal, oldName, &ok);
2674 if (ok && !newName.isEmpty()) {
2675 item->setText(newName);
2690 for (
int i=0; i<data.size(); i++) {
2707 QString result(label);
2709 if (label ==
"dataT") {
2710 result = QString(
"T (K)");
2711 }
else if (label ==
"dataB") {
2712 result = QString(
"B (G)");
2713 }
else if (label ==
"dataE") {
2714 result =QString(
"E (keV)");
2715 }
else if (!label.compare(
"sigma", Qt::CaseInsensitive)) {
2717 result = QString(
"#sigma/max(#sigma)");
2719 result = QString(
"#sigma (1/#mus)");
2721 }
else if (!label.compare(
"lambda", Qt::CaseInsensitive)) {
2723 result = QString(
"#lambda/max(#lambda)");
2725 result = QString(
"#lambda (1/#mus)");
2727 }
else if (!label.compare(
"alpha_LR", Qt::CaseInsensitive)) {
2729 result = QString(
"#alpha_{LR}/max(#alpha_{LR})");
2731 result = QString(
"#alpha_{LR}");
2733 }
else if (!label.compare(
"alpha_TB", Qt::CaseInsensitive)) {
2735 result = QString(
"#alpha_{TB}/max(#alpha_{TB})");
2737 result = QString(
"#alpha_{TB}");
2741 result = QString(
"Normalized ");
2760 if (cmd.contains(
"select")) {
2761 str.remove(
"select");
2762 str = str.trimmed();
2763 }
else if (cmd.contains(
"sc")) {
2764 pos = cmd.indexOf(
"sc");
2765 str.remove(0, pos+2);
2766 str = str.trimmed();
2771 ival = str.toInt(&ok);
2773 if (ival < fColList->count())
2776 QMessageBox::critical(
this,
"ERROR",
2777 QString(
"Found Row Selection %1 which is > #Selections=%2").arg(ival).arg(
fColList->count()));
2779 for (
int i=0; i<
fColList->count(); i++) {
2780 if (
fColList->item(i)->text() == str) {
2800 QProcessEnvironment env = QProcessEnvironment::systemEnvironment();
2803 for (i=0; i<256; i++) {
2804 fln = QString(
"%1/.musrfit/mupp/_mupp_ftok_%2.dat").arg(env.value(
"HOME")).arg(i);
2805 if (!QFile::exists(fln))
Main GUI interface for the mupp (MusrFit Parameter Plotter) application.
Central manager class for loading and accessing parameter collections.
Dialog for displaying variable parsing error messages.
PVarErrorDialog(QString errMsg)
Constructor that creates and displays the error dialog.
QPushButton * fOK
button to close the dialog
QPlainTextEdit * fErrMsg
text widget displaying the error message
The PVarHandler class handles variable parsing, evaluation, and data management.
QString getVarName()
Gets the variable name.
bool isValid()
Checks if the parsing and evaluation were successful.
QString getCollName()
Gets the collection name.
Main administration class for mupp configuration management.
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.
QString GetName()
Gets the collection name.
bool fDarkThemeIconsMenu
flag for dark theme menu icons
void getTheme()
Detects system theme (light/dark) and configures icons accordingly.
void addVar()
Opens dialog to add/manage variable definitions.
void remove()
Removes the selected collection from the list.
std::unique_ptr< QBoxLayout > fBoxLayout_Top
top horizontal layout (left->right)
std::unique_ptr< QListWidget > fColList
list widget displaying data collections
uint fMuppInstance
unique instance identifier for this mupp session
std::unique_ptr< QProcess > fMuppPlot
external process for ROOT-based plotting
void plot()
Generates and displays the plot using current configuration.
uint getFirstAvailableMuppInstance()
Finds the first available mupp instance number for IPC.
void writeCmdHistory()
Writes command history to disk before exit.
void check(QString varStr, QVector< int > idx)
Checks variable expressions for validity.
std::unique_ptr< QAction > fNormalizeAction
action for normalize toggle
virtual ~PmuppGui()
Destructor. Cleans up resources and saves command history.
std::unique_ptr< QBoxLayout > fBoxLayout_Main
main vertical layout (top->bottom)
int getXlabelIndex(QString label)
Gets the index of an X-axis label in the XY list.
std::unique_ptr< PVarDialog > fVarDlg
variable definition dialog
void addX(QString param="")
Adds a parameter to the X-axis.
bool allXYEqual()
Checks if all X-Y configurations are identical.
void add(QString varStr, QVector< int > idx)
Adds a validated variable expression.
std::unique_ptr< QPlainTextEdit > fCmdLineHistory
text area displaying command history
std::unique_ptr< QLabel > fXaxisLabel
label for X-axis selection area
std::unique_ptr< QPushButton > fAddX
button to add parameter to X-axis
void helpCmds()
Shows help dialog with available commands.
std::unique_ptr< QListWidget > fViewY
list widget showing current Y-axis parameters
void selectCollection(QString cmd)
Selects a collection based on command string.
void helpAboutQt()
Shows Qt framework information dialog.
void toolDumpCollections()
Dumps collection information for debugging purposes.
void refresh()
Refreshes the collection list from data handler.
void getMinMax(QVector< double > &data, double &min, double &max)
Finds minimum and maximum values in a data vector.
std::unique_ptr< QPushButton > fRemoveY
button to remove Y-axis parameter
void removeY(QString param="")
Removes a parameter from the Y-axis.
void createMacro()
Creates a ROOT macro file from current plot configuration.
void updateXYListGui()
Updates the X-Y axis list widgets in the GUI.
void editCollName(QListWidgetItem *item)
Handles editing of collection name via double-click.
bool fDarkThemeIconsToolbar
flag for dark theme toolbar icons
void setupToolActions()
Sets up Tools menu actions (Dump, Variables, Normalize).
std::unique_ptr< QWidget > fCentralWidget
central widget containing all GUI elements
PParamDataHandler * fParamDataHandler
handler for parameter data collections
void handleCmds()
Processes commands entered in the command line.
std::unique_ptr< QLineEdit > fCmdLine
line edit for command input
std::unique_ptr< QPushButton > fPlot
button to generate and display plot
QVector< double > getPosErr(QString collName, QString paramName, bool &ok)
Gets positive error values for a parameter.
std::unique_ptr< QSplitter > fColParamSplitter
splitter between collection and parameter lists
void fileExit()
Exits the application after cleanup.
EAxis
Enumeration for axis type identification.
@ kXaxis
X-axis (independent variable)
bool fNormalize
flag indicating normalization mode
QStringList getVarNames(QString parseStr)
Extracts variable names from a parse string.
void refreshY()
Refreshes the Y-axis list after variable changes.
QVector< double > getNegErr(QString collName, QString paramName, bool &ok)
Gets negative error values for a parameter.
void startMuppPlot()
Starts the external ROOT plotting process.
std::unique_ptr< QPushButton > fRemoveX
button to remove X-axis parameter
bool indexAlreadyPresent(int idx)
Checks if an index is already present in XY list.
void removeX(QString param="")
Removes a parameter from the X-axis.
void dropOnViewY(QListWidgetItem *item)
Handles drag-and-drop onto Y-axis view.
std::unique_ptr< QListWidget > fParamList
list widget displaying parameters in selected collection
void fileOpen()
Opens a file dialog to select parameter data files to load.
void setupHelpActions()
Sets up Help menu actions (Commands, About).
std::unique_ptr< QLabel > fYaxisLabel
label for Y-axis selection area
QString substituteDefaultLabels(QString label)
Substitutes default parameter labels with descriptive names.
QAction * fRecentFilesAction[MAX_RECENT_FILES]
array of the recent file actions
bool isNewCollection(PmuppCollection &coll)
Checks if a collection is new (not already in the list).
void fillRecentFiles()
Populates the recent files menu from configuration.
void fileOpenRecent()
Opens a recently used parameter file.
std::unique_ptr< QListWidget > fViewX
list widget showing current X-axis parameter
void addDitto()
Copies X-axis parameter to Y-axis (ditto function).
void dropOnViewX(QListWidgetItem *item)
Handles drag-and-drop onto X-axis view.
void replaceIndex(PmuppXY &data, const int idx)
Replaces an index in the XY data structure.
PmuppGui(QStringList fln)
Constructor. Creates the main GUI window.
std::unique_ptr< QPushButton > fAddDitto
button to copy X-axis parameter to Y-axis
bool fIgnoreThemeAutoDetection
flag to override automatic theme detection
QMenu * fRecentFilesMenu
recent file menu
void updateParamList(int currentRow)
Updates the parameter list based on selected collection.
void handleNewData()
Handles newly loaded data by updating GUI components.
QVector< QString > fCmdHistory
command history buffer for navigation
QString fMacroPath
directory path for ROOT macro generation
void aboutToQuit()
Slot called when application is about to quit. Saves state.
std::unique_ptr< QGridLayout > fGridLayout_Right
right grid layout (2 columns, 6 rows)
QString fMacroName
name of the generated ROOT macro file
void updateXYList(int idx)
Updates the X-Y axis configuration for a specific index.
void updateCollectionList()
Updates the collection list widget from data handler.
QVector< PmuppXY > fXY
vector of X-Y axis configurations
void setupFileActions()
Sets up File menu actions (Open, Recent Files, Exit).
void readCmdHistory()
Reads command history from disk at startup.
std::unique_ptr< QPushButton > fRefreshCollection
button to refresh collection list
std::unique_ptr< QLabel > fColLabel
label for collection/parameter section
std::unique_ptr< QPushButton > fAddY
button to add parameter to Y-axis
std::unique_ptr< QSplitter > fCmdSplitter
splitter between history and command input
PmuppAdmin * fAdmin
administration object managing configuration
std::unique_ptr< QBoxLayout > fBoxLayout_Cmd
command area horizontal layout (left->right)
void helpAbout()
Shows about dialog with application information.
QVector< double > getValues(QString collName, QString paramName, bool &ok)
Gets parameter values from a collection.
void parseErrMsgDlg()
Displays a dialog with variable parsing error messages.
QVector< PVarHandler > fVarHandler
vector of variable handlers
std::unique_ptr< QPushButton > fExitButton
button to exit application
bool findValue(PmuppRun &run, EAxis tag)
Finds parameter value in a run structure.
std::unique_ptr< QGridLayout > fGridLayout_Left
left grid layout (2 columns, 3 rows)
qint64 fDatime
timestamp for IPC message queue identification
void toolDumpXY()
Dumps X-Y axis information for debugging purposes.
void normalize()
Toggles normalization mode for plot data.
bool eventFilter(QObject *o, QEvent *e)
Event filter for handling keyboard and mouse events.
void addY(QString param="")
Adds a parameter to the Y-axis.
std::unique_ptr< QPushButton > fRemoveCollection
button to remove selected collection
Represents a plot marker style and size.
void getMarker(int &marker, double &size)
Gets both marker code and size.
double getMarkerSize()
Gets the marker size multiplier.
QString GetName()
Gets the parameter name.
Represents all fit parameters from a single experimental run.
PmuppParam GetParam(unsigned int idx)
Retrieves a parameter from a run by index.
int GetNoOfParam()
Gets the number of parameters in this run.
Data structure for X-Y axis label associations.
void setCollectionTag(int tag)
Sets the collection tag (identifier).
int getXlabelIdx()
Extracts the parameter index from the X-axis label.
QString fXlabel
X-axis parameter label.
void setYlabel(int idx, QString str)
Sets the Y-axis label at a specific index.
int getYlabelIdx(int idx)
Extracts the parameter index from a Y-axis label.
void removeYlabel(int idx)
Removes a Y-axis label by index.
void init()
Initializes the object to default state.
QString getYlabel(int idx)
Gets a Y-axis label by index.
QString getXlabel()
Gets the X-axis label.
void setXlabel(QString str)
Sets the X-axis label.
int fCollectionTag
identifier for the associated data collection
int getYlabelSize()
Gets the number of Y-axis labels.
QVector< QString > fYlabel
vector of Y-axis parameter labels
#define PMUPP_MAX_MTEXT
Maximum size of the message text buffer.
#define MAX_RECENT_FILES
Maximum number of recent files to be tracked.
The PCollInfo struct holds collection information.
QStringList fVarName
variable names of the given collection
QString fCollName
collection name (may include path)
Message buffer structure for inter-process communication.
char mtext[PMUPP_MAX_MTEXT]
message body containing the actual message data
long mtype
message type identifier for message routing