musredit 1.0.0
Loading...
Searching...
No Matches
PAdmin.cpp
Go to the documentation of this file.
1/****************************************************************************
2
3 PAdmin.cpp
4
5 Author: Andreas Suter
6 e-mail: andreas.suter@psi.ch
7
8*****************************************************************************/
9
10/***************************************************************************
11 * Copyright (C) 2010-2026 by Andreas Suter *
12 * andreas.suter@psi.ch *
13 * *
14 * This program is free software; you can redistribute it and/or modify *
15 * it under the terms of the GNU General Public License as published by *
16 * the Free Software Foundation; either version 2 of the License, or *
17 * (at your option) any later version. *
18 * *
19 * This program is distributed in the hope that it will be useful, *
20 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
21 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
22 * GNU General Public License for more details. *
23 * *
24 * You should have received a copy of the GNU General Public License *
25 * along with this program; if not, write to the *
26 * Free Software Foundation, Inc., *
27 * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
28 ***************************************************************************/
29
45
46#include <cstdlib>
47#include <iostream>
48
49#include <QMessageBox>
50#include <QString>
51#include <QStringView>
52#include <QLatin1String>
53#include <QFile>
54#include <QTextStream>
55#include <QVector>
56#include <QDir>
57#include <QProcessEnvironment>
58#include <QSysInfo>
59#include <QIODevice>
60
61#include "musrfit-info.h"
62#include "PAdmin.h"
63
64//--------------------------------------------------------------------------
65// implementation of PAdminXMLParser class
66//--------------------------------------------------------------------------
81PAdminXMLParser::PAdminXMLParser(const QString& fln, PAdmin *admin) : fAdmin(admin)
82{
83 fValid = false;
85 fFunc = false;
86
87 QFile file(fln);
88 if (!file.open(QFile::ReadOnly | QFile::Text) || (file.size()==0)) {
89 // warning and create default
90 QMessageBox::StandardButton ret = QMessageBox::warning(nullptr, "WARNING", "The musredit_startup.xml is corrupted. Create a default one?", QMessageBox::Yes | QMessageBox::No);
91 if (ret == QMessageBox::Yes) {
92 fAdmin->createMusreditStartupFile();
93 }
94 }
95
96 fValid = parse(&file);
97}
98
99//--------------------------------------------------------------------------
112bool PAdminXMLParser::parse(QIODevice *device)
113{
114 fXml.setDevice(device);
115
116 bool expectChars = false;
117 while (!fXml.atEnd()) {
118 fXml.readNext();
119 if (fXml.isStartDocument()) {
121 } else if (fXml.isStartElement()) {
122 startElement();
123 expectChars = true;
124 } else if (fXml.isCharacters() && expectChars) {
125 characters();
126 } else if (fXml.isEndElement()) {
127 endElement();
128 expectChars = false;
129 } else if (fXml.isEndDocument()) {
130 endDocument();
131 }
132 }
133 if (fXml.hasError()) {
134 QString msg;
135 msg = QString("%1 Line %2, column %3").arg(fXml.errorString()).arg(fXml.lineNumber()).arg(fXml.columnNumber());
136 QMessageBox::critical(nullptr, "ERROR", msg, QMessageBox::Ok, QMessageBox::NoButton);
137 return false;
138 }
139
140 return true;
141}
142
143//--------------------------------------------------------------------------
154{
155 // nothing to be done here for now
156 return true;
157}
158
159//--------------------------------------------------------------------------
172{
173 QString qName = fXml.name().toString();
174
175 if (qName == "timeout") {
177 } else if (qName == "font_name") {
179 } else if (qName == "font_size") {
181 } else if (qName == "exec_path") {
183 } else if (qName == "default_save_path") {
185 } else if (qName == "title_from_data_file") {
187 } else if (qName == "musrview_show_fourier") {
189 } else if (qName == "musrview_show_avg") {
191 } else if (qName == "musrview_show_one_to_one") {
193 } else if (qName == "enable_musrt0") {
195 } else if (qName == "ignore_theme_auto_detection") {
197 } else if (qName == "dark_theme_icons_menu") {
199 } else if (qName == "dark_theme_icons_toolbar") {
201 } else if (qName == "edit_w") {
203 } else if (qName == "edit_h") {
205 } else if (qName == "keep_minuit2_output") {
207 } else if (qName == "dump_ascii") {
209 } else if (qName == "dump_root") {
211 } else if (qName == "estimate_n0") {
213 } else if (qName == "yaml_out") {
215 } else if (qName == "use_no_of_threads") {
217 } else if (qName == "chisq_per_run_block") {
219 } else if (qName == "path_file_name") {
221 } else if (qName == "beamline") {
223 } else if (qName == "institute") {
225 } else if (qName == "file_format") {
227 } else if (qName == "lifetime_correction") {
229 } else if (qName == "musr_web_main") {
231 } else if (qName == "musr_web_title") {
233 } else if (qName == "musr_web_parameters") {
235 } else if (qName == "musr_web_theory") {
237 } else if (qName == "musr_web_functions") {
239 } else if (qName == "musr_web_run") {
241 } else if (qName == "musr_web_command") {
243 } else if (qName == "musr_web_fourier") {
245 } else if (qName == "musr_web_plot") {
247 } else if (qName == "musr_web_statistic") {
249 } else if (qName == "musr_web_msr2data") {
251 } else if (qName == "musr_web_musrFT") {
253 } else if (qName == "chain_fit") {
255 } else if (qName == "write_data_header") {
257 } else if (qName == "ignore_data_header_info") {
259 } else if (qName == "keep_minuit2_output") {
261 } else if (qName == "write_column_data") {
263 } else if (qName == "recreate_data_file") {
265 } else if (qName == "open_file_after_fitting") {
267 } else if (qName == "create_msr_file_only") {
269 } else if (qName == "fit_only") {
271 } else if (qName == "global") {
273 } else if (qName == "global_plus") {
275 } else if (qName == "func_pixmap_path") {
277 } else if (qName == "func") {
278 fKeyWord = eFunc;
279 fFunc = true;
280 // init theory item
281 fTheoryItem.name = "";
282 fTheoryItem.comment = "";
283 fTheoryItem.label = "";
284 fTheoryItem.pixmapName = "";
285 fTheoryItem.pixmap = QPixmap();
286 fTheoryItem.params = -1;
287 } else if (qName == "name") {
289 } else if (qName == "comment") {
291 } else if (qName == "label") {
293 } else if (qName == "pixmap") {
295 } else if (qName == "params") {
297 }
298
299 return true;
300}
301
302//--------------------------------------------------------------------------
313{
315
316 QString qName = fXml.name().toString();
317
318 if (qName == "func") {
319 fFunc = false;
320 fAdmin->addTheoryItem(fTheoryItem);
321 }
322
323 return true;
324}
325
326//--------------------------------------------------------------------------
341{
342 QString str = fXml.text().toString();
343 if (str.isEmpty())
344 return true;
345
346 QString help;
347 bool flag, ok;
348 int ival;
349
350 switch (fKeyWord) {
351 case eTimeout:
352 ival = QString(str.toLatin1()).trimmed().toInt(&ok);
353 if (ok)
354 fAdmin->setTimeout(ival);
355 break;
356 case eFontName:
357 fAdmin->setFontName(QString(str.toLatin1()).trimmed());
358 break;
359 case eFontSize:
360 ival = QString(str.toLatin1()).trimmed().toInt(&ok);
361 if (ok)
362 fAdmin->setFontSize(ival);
363 break;
364 case eExecPath:
365 fAdmin->setExecPath(QString(str.toLatin1()).trimmed());
366 break;
367 case eDefaultSavePath:
368 fAdmin->setDefaultSavePath(QString(str.toLatin1()).trimmed());
369 break;
371 if (str == "y")
372 flag = true;
373 else
374 flag = false;
375 fAdmin->setTitleFromDataFileFlag(flag);
376 break;
378 if (str == "y")
379 flag = true;
380 else
381 flag = false;
382 fAdmin->setMusrviewShowFourierFlag(flag);
383 break;
384 case eMusrviewShowAvg:
385 if (str == "y")
386 flag = true;
387 else
388 flag = false;
389 fAdmin->setMusrviewShowAvgFlag(flag);
390 break;
392 if (str == "y")
393 flag = true;
394 else
395 flag = false;
396 fAdmin->setMusrviewShowOneToOneFlag(flag);
397 break;
398 case eEnableMusrT0:
399 if (str == "y")
400 flag = true;
401 else
402 flag = false;
403 fAdmin->setEnableMusrT0Flag(flag);
404 break;
406 if (str == "y")
407 flag = true;
408 else
409 flag = false;
410 fAdmin->setIgnoreThemeAutoDetection(flag);
411 break;
413 if (str == "y")
414 flag = true;
415 else
416 flag = false;
417 fAdmin->setDarkThemeIconsMenuFlag(flag);
418 break;
420 if (str == "y")
421 flag = true;
422 else
423 flag = false;
424 fAdmin->setDarkThemeIconsToolbarFlag(flag);
425 break;
426 case eEditW:
427 ival = QString(str.toLatin1()).trimmed().toInt(&ok);
428 if (ok)
429 fAdmin->setEditWidth(ival);
430 break;
431 case eEditH:
432 ival = QString(str.toLatin1()).trimmed().toInt(&ok);
433 if (ok)
434 fAdmin->setEditHeight(ival);
435 break;
437 if (str == "y")
438 flag = true;
439 else
440 flag = false;
441 fAdmin->fMsr2DataParam.keepMinuit2Output = flag;
442 fAdmin->setKeepMinuit2OutputFlag(flag);
443 break;
444 case eDumpAscii:
445 if (str == "y")
446 flag = true;
447 else
448 flag = false;
449 fAdmin->setDumpAsciiFlag(flag);
450 break;
451 case eDumpRoot:
452 if (str == "y")
453 flag = true;
454 else
455 flag = false;
456 fAdmin->setDumpRootFlag(flag);
457 break;
458 case eEstimateN0:
459 if (str == "y")
460 flag = true;
461 else
462 flag = false;
463 fAdmin->fMsr2DataParam.estimateN0 = flag;
464 fAdmin->setEstimateN0Flag(flag);
465 break;
466 case eYamlOut:
467 if (str == "y")
468 flag = true;
469 else
470 flag = false;
471 fAdmin->fMsr2DataParam.yamlOut = flag;
472 fAdmin->setYamlOutFlag(flag);
473 break;
475 ival = QString(str.toLatin1()).trimmed().toInt(&ok);
476 if (ok)
477 fAdmin->setNoOfThreadsToBeUsed(ival);
478 break;
480 if (str == "y")
481 flag = true;
482 else
483 flag = false;
484 fAdmin->fMsr2DataParam.perRunBlockChisq = flag;
485 fAdmin->setChisqPerRunBlockFlag(flag);
486 break;
487 case eRecentFile:
488 fAdmin->addRecentFile(QString(str.toLatin1()).trimmed());
489 break;
490 case eBeamline:
491 fAdmin->setBeamline(QString(str.toLatin1()).trimmed());
492 break;
493 case eInstitute:
494 fAdmin->setInstitute(QString(str.toLatin1()).trimmed());
495 break;
496 case eFileFormat:
497 fAdmin->setFileFormat(QString(str.toLatin1()).trimmed());
498 break;
500 if (str == "y")
501 flag = true;
502 else
503 flag = false;
504 fAdmin->setLifetimeCorrectionFlag(flag);
505 break;
506 case eHelpMain:
507 fAdmin->setHelpUrl("main", str);
508 break;
509 case eHelpTitle:
510 fAdmin->setHelpUrl("title", str);
511 break;
512 case eHelpParameters:
513 fAdmin->setHelpUrl("parameters", str);
514 break;
515 case eHelpTheory:
516 fAdmin->setHelpUrl("theory", str);
517 break;
518 case eHelpFunctions:
519 fAdmin->setHelpUrl("functions", str);
520 break;
521 case eHelpRun:
522 fAdmin->setHelpUrl("run", str);
523 break;
524 case eHelpCommand:
525 fAdmin->setHelpUrl("command", str);
526 break;
527 case eHelpFourier:
528 fAdmin->setHelpUrl("fourier", str);
529 break;
530 case eHelpPlot:
531 fAdmin->setHelpUrl("plot", str);
532 break;
533 case eHelpStatistic:
534 fAdmin->setHelpUrl("statistic", str);
535 break;
536 case eHelpMsr2Data:
537 fAdmin->setHelpUrl("msr2data", str);
538 break;
539 case eHelpMusrFT:
540 fAdmin->setHelpUrl("musrFT", str);
541 break;
542 case eChainFit:
543 if (str == "y")
544 flag = true;
545 else
546 flag = false;
547 fAdmin->fMsr2DataParam.chainFit = flag;
548 break;
549 case eWriteDataHeader:
550 if (str == "y")
551 flag = true;
552 else
553 flag = false;
554 fAdmin->fMsr2DataParam.writeDbHeader = flag;
555 break;
557 if (str == "y")
558 flag = true;
559 else
560 flag = false;
561 fAdmin->fMsr2DataParam.ignoreDataHeaderInfo = flag;
562 break;
563 case eWriteColumnData:
564 if (str == "y")
565 flag = true;
566 else
567 flag = false;
568 fAdmin->fMsr2DataParam.writeColumnData = flag;
569 break;
571 if (str == "y")
572 flag = true;
573 else
574 flag = false;
575 fAdmin->fMsr2DataParam.recreateDbFile = flag;
576 break;
578 if (str == "y")
579 flag = true;
580 else
581 flag = false;
582 fAdmin->fMsr2DataParam.openFilesAfterFitting = flag;
583 break;
585 if (str == "y")
586 flag = true;
587 else
588 flag = false;
589 fAdmin->fMsr2DataParam.createMsrFileOnly = flag;
590 break;
591 case eFitOnly:
592 if (str == "y")
593 flag = true;
594 else
595 flag = false;
596 fAdmin->fMsr2DataParam.fitOnly = flag;
597 break;
598 case eGlobal:
599 if (str == "y")
600 flag = true;
601 else
602 flag = false;
603 fAdmin->fMsr2DataParam.global = flag;
604 break;
605 case eGlobalPlus:
606 if (str == "y")
607 flag = true;
608 else
609 flag = false;
610 fAdmin->fMsr2DataParam.globalPlus = flag;
611 break;
613 fAdmin->setTheoFuncPixmapPath(QString(str.toLatin1()).trimmed());
614 break;
615 default:
616 break;
617 }
618
619 if (fFunc) {
620 bool ok;
621 switch (fKeyWord) {
622 case eFuncName:
623 fTheoryItem.name = QString(str.toLatin1()).trimmed();
624 break;
625 case eFuncComment:
626 fTheoryItem.comment = QString(str.toLatin1()).trimmed();
627 break;
628 case eFuncLabel:
629 fTheoryItem.label = QString(str.toLatin1()).trimmed();
630 break;
631 case eFuncPixmap:
632 fTheoryItem.pixmapName = QString(str.toLatin1()).trimmed();
633 break;
634 case eFuncParams:
635 fTheoryItem.params = str.toInt(&ok);
636 if (!ok)
637 return false;
638 break;
639 default:
640 break;
641 }
642 }
643
644 return true;
645}
646
647//--------------------------------------------------------------------------
660{
661 // check if all necessary items are found
662 QString str;
663
664 if (fAdmin->getExecPath().indexOf('$') >= 0) {
665 str = expandPath(fAdmin->getExecPath());
666 if (!str.isEmpty())
667 fAdmin->setExecPath(str);
668 }
669
670 if (fAdmin->getDefaultSavePath().indexOf('$') >= 0) {
671 str = expandPath(fAdmin->getDefaultSavePath());
672 if (!str.isEmpty())
673 fAdmin->setDefaultSavePath(str);
674 }
675
676 if (fAdmin->getTheoFuncPixmapPath().indexOf('$') >=0) {
677 str = expandPath(fAdmin->getTheoFuncPixmapPath());
678 if (!str.isEmpty())
679 fAdmin->setTheoFuncPixmapPath(str);
680 }
681
682 //as35 dump admin - only for debugging
683 //as35 dump();
684
685 return true;
686}
687
688//--------------------------------------------------------------------------
701{
702 std::cout << "debug> +++++++++++++++++++++++" << std::endl;
703 std::cout << "debug> general:" << std::endl;
704 std::cout << "debug> exec_path : " << fAdmin->getExecPath().toLatin1().data() << std::endl;
705 std::cout << "debug> default_save_path : " << fAdmin->getDefaultSavePath().toLatin1().data() << std::endl;
706 std::cout << "debug> timeout : " << fAdmin->getTimeout() << std::endl;
707 std::cout << "debug> keep_minuit2_output : " << fAdmin->getKeepMinuit2OutputFlag() << std::endl;
708 std::cout << "debug> dump_ascii : " << fAdmin->getDumpAsciiFlag() << std::endl;
709 std::cout << "debug> dump_root : " << fAdmin->getDumpRootFlag() << std::endl;
710 std::cout << "debug> title_from_data_file : " << fAdmin->getTitleFromDataFileFlag() << std::endl;
711 std::cout << "debug> chisq_per_run_block : " << fAdmin->getChisqPerRunBlockFlag() << std::endl;
712 std::cout << "debug> estimate_n0 : " << fAdmin->getEstimateN0Flag() << std::endl;
713 std::cout << "debug> yaml_out : " << fAdmin->getYamlOutFlag() << std::endl;
714 std::cout << "debug> musrview_show_fourier : " << fAdmin->getMusrviewShowFourierFlag() << std::endl;
715 std::cout << "debug> musrview_show_avg : " << fAdmin->getMusrviewShowAvgFlag() << std::endl;
716 std::cout << "debug> enable_musrt0 : " << fAdmin->getEnableMusrT0Flag() << std::endl;
717 std::cout << "debug> ignore_theme_auto_detection : " << fAdmin->getIgnoreThemeAutoDetection() << std::endl;
718 std::cout << "debug> dark_theme_icons_menu : " << fAdmin->getDarkThemeIconsMenuFlag() << std::endl;
719 std::cout << "debug> dark_theme_icons_toolbar : " << fAdmin->getDarkThemeIconsToolbarFlag() << std::endl;
720 std::cout << "debug> edit_w : " << fAdmin->getEditWidth() << std::endl;
721 std::cout << "debug> edit_h : " << fAdmin->getEditHeight() << std::endl;
722 std::cout << "debug> +++++++++++++++++++++++" << std::endl;
723 std::cout << "debug> recent_files:" << std::endl;
724 for (int i=0; i<fAdmin->getNumRecentFiles(); i++) {
725 std::cout << "debug> recent_file " << i << ":" << fAdmin->getRecentFile(i).toLatin1().data() << std::endl;
726 }
727 std::cout << "debug> +++++++++++++++++++++++" << std::endl;
728 std::cout << "debug> help_section:" << std::endl;
729 std::cout << "debug> musr_web_main : " << fAdmin->getHelpUrl("main").toLatin1().data() << std::endl;
730 std::cout << "debug> musr_web_title : " << fAdmin->getHelpUrl("title").toLatin1().data() << std::endl;
731 std::cout << "debug> musr_web_parameters : " << fAdmin->getHelpUrl("parameters").toLatin1().data() << std::endl;
732 std::cout << "debug> musr_web_theory : " << fAdmin->getHelpUrl("theory").toLatin1().data() << std::endl;
733 std::cout << "debug> musr_web_functions : " << fAdmin->getHelpUrl("functions").toLatin1().data() << std::endl;
734 std::cout << "debug> musr_web_run : " << fAdmin->getHelpUrl("run").toLatin1().data() << std::endl;
735 std::cout << "debug> musr_web_command : " << fAdmin->getHelpUrl("command").toLatin1().data() << std::endl;
736 std::cout << "debug> musr_web_fourier : " << fAdmin->getHelpUrl("fourier").toLatin1().data() << std::endl;
737 std::cout << "debug> musr_web_plot : " << fAdmin->getHelpUrl("plot").toLatin1().data() << std::endl;
738 std::cout << "debug> musr_web_statistic : " << fAdmin->getHelpUrl("statistic").toLatin1().data() << std::endl;
739 std::cout << "debug> musr_web_msr2data : " << fAdmin->getHelpUrl("msr2data").toLatin1().data() << std::endl;
740 std::cout << "debug> musr_web_musrFT : " << fAdmin->getHelpUrl("musrFT").toLatin1().data() << std::endl;
741 std::cout << "debug> +++++++++++++++++++++++" << std::endl;
742 std::cout << "debug> font_section:" << std::endl;
743 std::cout << "debug> font_name : " << fAdmin->getFontName().toLatin1().data() << std::endl;
744 std::cout << "debug> font_size : " << fAdmin->getFontSize() << std::endl;
745 std::cout << "debug> +++++++++++++++++++++++" << std::endl;
746 std::cout << "debug> msr_file_defaults:" << std::endl;
747 std::cout << "debug> beamline : " << fAdmin->getBeamline().toLatin1().data() << std::endl;
748 std::cout << "debug> institute : " << fAdmin->getInstitute().toLatin1().data() << std::endl;
749 std::cout << "debug> file_format : " << fAdmin->getFileFormat().toLatin1().data() << std::endl;
750 std::cout << "debug> lifetime_correction : " << fAdmin->getLifetimeCorrectionFlag() << std::endl;
751 std::cout << "debug> +++++++++++++++++++++++" << std::endl;
752 std::cout << "debug> msr2data_defaults:" << std::endl;
753 std::cout << "debug> chain_fit : " << fAdmin->getMsr2DataParam().chainFit << std::endl;
754 std::cout << "debug> write_data_header : " << fAdmin->getMsr2DataParam().writeDbHeader << std::endl;
755 std::cout << "debug> ignore_data_header_info : " << fAdmin->getMsr2DataParam().ignoreDataHeaderInfo << std::endl;
756 std::cout << "debug> keep_minuit2_output : " << fAdmin->getMsr2DataParam().keepMinuit2Output << std::endl;
757 std::cout << "debug> write_column_data : " << fAdmin->getMsr2DataParam().writeColumnData << std::endl;
758 std::cout << "debug> recreate_data_file : " << fAdmin->getMsr2DataParam().recreateDbFile << std::endl;
759 std::cout << "debug> open_file_after_fitting : " << fAdmin->getMsr2DataParam().openFilesAfterFitting << std::endl;
760 std::cout << "debug> create_msr_file_only : " << fAdmin->getMsr2DataParam().createMsrFileOnly << std::endl;
761 std::cout << "debug> fit_only : " << fAdmin->getMsr2DataParam().fitOnly << std::endl;
762 std::cout << "debug> global : " << fAdmin->getMsr2DataParam().global << std::endl;
763 std::cout << "debug> global_plus : " << fAdmin->getMsr2DataParam().globalPlus << std::endl;
764 std::cout << "debug> +++++++++++++++++++++++" << std::endl;
765 std::cout << "debug> theory_functions:" << std::endl;
766 std::cout << "debug> func_pixmap_path : " << fAdmin->getTheoFuncPixmapPath().toLatin1().data() << std::endl;
767 std::cout << "debug> #theory : " << fAdmin->getTheoryCounts() << std::endl;
768 PTheory *theo;
769 for (unsigned int i=0; i<fAdmin->getTheoryCounts(); i++) {
770 theo = fAdmin->getTheoryItem(i);
771 std::cout << "debug> -------" << std::endl;
772 std::cout << "debug> name : " << theo->name.toLatin1().data() << std::endl;
773 std::cout << "debug> comment : " << theo->comment.toLatin1().data() << std::endl;
774 std::cout << "debug> label : " << theo->label.toLatin1().data() << std::endl;
775 std::cout << "debug> pixmapName : " << theo->pixmapName.toLatin1().data() << std::endl;
776 std::cout << "debug> params : " << theo->params << std::endl;
777 }
778}
779
780//--------------------------------------------------------------------------
795QString PAdminXMLParser::expandPath(const QString &str)
796{
797 QString token;
798 QString path;
799 QString msg;
800 QString newStr="";
801
802 QProcessEnvironment procEnv = QProcessEnvironment::systemEnvironment();
803
804 QStringList list = str.split("/");
805
806 for ( QStringList::Iterator it = list.begin(); it != list.end(); ++it ) {
807 token = *it;
808 if (token.contains("$")) {
809 token.remove('$');
810 if (!procEnv.contains(token)) {
811 msg = QString("Couldn't find '%1'. Some things might not work properly").arg(token);
812 QMessageBox::warning(nullptr, "WARNING", msg, QMessageBox::Ok, QMessageBox::NoButton);
813 newStr = "";
814 break;
815 }
816 path = procEnv.value(token, "");
817 if (path.isEmpty()) {
818 msg = QString("Couldn't expand '%1'. Some things might not work properly").arg(token);
819 QMessageBox::warning(nullptr, "WARNING", msg, QMessageBox::Ok, QMessageBox::NoButton);
820 newStr = "";
821 break;
822 }
823 newStr += path;
824 } else {
825 newStr += "/" + token;
826 }
827 }
828
829 return newStr;
830}
831
832//--------------------------------------------------------------------------
833// implementation of PAdmin class
834//--------------------------------------------------------------------------
852PAdmin::PAdmin() : QObject()
853{
854 fMsr2DataParam.runList = QString("");
855 fMsr2DataParam.runListFileName = QString("");
856 fMsr2DataParam.msrFileExtension = QString("");
857 fMsr2DataParam.templateRunNo = -1;
858 fMsr2DataParam.dbOutputFileName = QString("");
859 fMsr2DataParam.writeDbHeader = true;
860 fMsr2DataParam.ignoreDataHeaderInfo = false;
861 fMsr2DataParam.keepMinuit2Output = false;
862 fMsr2DataParam.estimateN0 = fEstimateN0;
863 fMsr2DataParam.yamlOut = false;
864 fMsr2DataParam.writeColumnData = false;
865 fMsr2DataParam.recreateDbFile = false;
866 fMsr2DataParam.chainFit = true;
867 fMsr2DataParam.openFilesAfterFitting = true;
868 fMsr2DataParam.perRunBlockChisq = fChisqPreRunBlock;
869 fMsr2DataParam.titleFromDataFile = true;
870 fMsr2DataParam.createMsrFileOnly = false;
871 fMsr2DataParam.fitOnly = false;
872 fMsr2DataParam.global = false;
873 fMsr2DataParam.globalPlus = false;
874
875 // XML Parser part
876 // 1st: check local directory
877 QString path = QDir::currentPath();
878 QString fln = QString("musredit_startup.xml");
879 QString pathFln = path + fln;
880 QProcessEnvironment procEnv = QProcessEnvironment::systemEnvironment();
881 if (!QFile::exists(pathFln)) {
882 // 2nd: check $HOME/.musrfit/musredit/musredit_startup.xml
883 path = QDir::homePath();
884 pathFln = path + "/.musrfit/musredit/" + fln;
885 if (!QFile::exists(pathFln)) {
886 // 3rd: check $MUSRFITPATH/musredit_startup.xml
887 path = procEnv.value("MUSRFITPATH", "");
888 pathFln = path + "/" + fln;
889 if (!QFile::exists(pathFln)) {
890 // 4th: check $ROOTSYS/bin/musredit_startup.xml
891 path = procEnv.value("ROOTSYS", "");
892 pathFln = path + "/bin/" + fln;
893 if (!QFile::exists(pathFln)) {
894 // 5th: not found anywhere hence create it
895 path = procEnv.value("HOME", "");
896 pathFln = path + "/.musrfit/musredit/" + fln;
898 }
899 }
900 }
901 }
902 fPrefPathName = pathFln;
903
905
906 // make sure that musrfit, musrview, etc are found under the fExecPath provided
907 QString str = fExecPath + "/musrfit";
908 QFileInfo info(str);
909 if (info.exists()) {
910 if (!info.isExecutable())
911 QMessageBox::critical(nullptr, "ERROR", "musrfit found but not recognized as executable.\nPlease check!");
912 } else {
913 QMessageBox::critical(nullptr, "ERROR", "musrfit not found.\nHave you set the necessary system variables properly?\nPlease check the manual.\nBefore you can use musrfit, this needs to be fixed.");
914 }
915
916 // check if system variables are set properly
917 bool sysVarMissing = false;
918 QString msg("Missing System Variables:\n");
919 path = procEnv.value("ROOTSYS", "");
920 if (path.isEmpty()) {
921 msg += "> ROOTSYS\n";
922 sysVarMissing = true;
923 }
924 path = procEnv.value("MUSRFITPATH", "");
925 if (path.isEmpty()) {
926 msg += "> MUSRFITPATH\n";
927 sysVarMissing = true;
928 }
929 if (sysVarMissing) {
930 msg += "Please set this/these system variables.";
931 QMessageBox::warning(nullptr, "WARNING", msg);
932 }
933}
934
935//--------------------------------------------------------------------------
959QString PAdmin::getHelpUrl(QString tag)
960{
961 return fHelpUrl[tag];
962}
963
964//--------------------------------------------------------------------------
978PTheory* PAdmin::getTheoryItem(const unsigned int idx)
979{
980 if (idx > (unsigned int)fTheory.size())
981 return 0;
982 else
983 return &fTheory[idx];
984}
985
986//--------------------------------------------------------------------------
1001{
1002 if (idx >= fRecentFile.size())
1003 return QString("");
1004
1005 return fRecentFile[idx];
1006}
1007
1008//--------------------------------------------------------------------------
1020void PAdmin::setHelpUrl(const QString tag, const QString url)
1021{
1022 fHelpUrl[tag] = url;
1023}
1024
1025//--------------------------------------------------------------------------
1039int PAdmin::loadPrefs(QString fln)
1040{
1041 if (QFile::exists(fln)) { // administration file present
1042 PAdminXMLParser handler(fln, this);
1043 if (!handler.isValid()) {
1044 QMessageBox::critical(nullptr, "ERROR",
1045 "Error parsing musredit_startup.xml settings file.\nProbably a few things will not work porperly.\nPlease fix this first.",
1046 QMessageBox::Ok, QMessageBox::NoButton);
1047 return 0;
1048 }
1049 } else {
1050 QMessageBox::critical(nullptr, "ERROR",
1051 "Couldn't find the musredit_startup.xml settings file.\nProbably a few things will not work porperly.\nPlease fix this first.",
1052 QMessageBox::Ok, QMessageBox::NoButton);
1053 return 0;
1054 }
1055 return 1;
1056}
1057
1058//--------------------------------------------------------------------------
1076int PAdmin::savePrefs(QString pref_fln)
1077{
1078 // check if musredit_startup.xml is present in the current directory, and if yes, use this file to
1079 // save the recent file names otherwise use the "master" musredit_startup.xml
1080 QString fln = QString("./musredit_startup.xml");
1081 if (!QFile::exists(fln))
1082 fln = fPrefPathName;
1083
1084 if (QFile::exists(fln)) { // administration file present
1085 QVector<QString> data;
1086 QFile file(fln);
1087 if (!file.open(QIODevice::ReadOnly | QIODevice::Text)) {
1088 std::cerr << std::endl << ">> PAdmin::savePrefs: **ERROR** Cannot open " << fln.toLatin1().data() << " for reading." << std::endl;
1089 return 1;
1090 }
1091 QTextStream fin(&file);
1092 while (!fin.atEnd()) {
1093 data.push_back(fin.readLine());
1094 }
1095 file.close();
1096
1097 // replace all the prefs
1098 for (int i=0; i<data.size(); i++) {
1099 if (data[i].contains("<timeout>") && data[i].contains("</timeout>")) {
1100 data[i] = " <timeout>" + QString("%1").arg(fTimeout) + "</timeout>";
1101 }
1102 if (data[i].contains("<keep_minuit2_output>") && data[i].contains("</keep_minuit2_output>")) {
1104 data[i] = " <keep_minuit2_output>y</keep_minuit2_output>";
1105 else
1106 data[i] = " <keep_minuit2_output>n</keep_minuit2_output>";
1107 }
1108 if (data[i].contains("<dump_ascii>") && data[i].contains("</dump_ascii>")) {
1109 if (fDumpAscii)
1110 data[i] = " <dump_ascii>y</dump_ascii>";
1111 else
1112 data[i] = " <dump_ascii>n</dump_ascii>";
1113 }
1114 if (data[i].contains("<dump_root>") && data[i].contains("</dump_root>")) {
1115 if (fDumpRoot)
1116 data[i] = " <dump_root>y</dump_root>";
1117 else
1118 data[i] = " <dump_root>n</dump_root>";
1119 }
1120 if (data[i].contains("<title_from_data_file>") && data[i].contains("</title_from_data_file>")) {
1122 data[i] = " <title_from_data_file>y</title_from_data_file>";
1123 else
1124 data[i] = " <title_from_data_file>n</title_from_data_file>";
1125 }
1126 if (data[i].contains("<chisq_per_run_block>") && data[i].contains("</chisq_per_run_block>")) {
1128 data[i] = " <chisq_per_run_block>y</chisq_per_run_block>";
1129 else
1130 data[i] = " <chisq_per_run_block>n</chisq_per_run_block>";
1131 }
1132 if (data[i].contains("<estimate_n0>") && data[i].contains("</estimate_n0>")) {
1133 if (fEstimateN0)
1134 data[i] = " <estimate_n0>y</estimate_n0>";
1135 else
1136 data[i] = " <estimate_n0>n</estimate_n0>";
1137 }
1138 if (data[i].contains("<yaml_out>") && data[i].contains("</yaml_out>")) {
1139 if (fYamlOut)
1140 data[i] = " <yaml_out>y</yaml_out>";
1141 else
1142 data[i] = " <yaml_out>n</yaml_out>";
1143 }
1144 if (data[i].contains("<use_no_of_threads>") && data[i].contains("</use_no_of_threads>")) {
1145 data[i] = " <use_no_of_threads>" + QString("%1").arg(fNoOfThreadsToBeUsed) + "</use_no_of_threads>";
1146 }
1147 if (data[i].contains("<musrview_show_fourier>") && data[i].contains("</musrview_show_fourier>")) {
1149 data[i] = " <musrview_show_fourier>y</musrview_show_fourier>";
1150 else
1151 data[i] = " <musrview_show_fourier>n</musrview_show_fourier>";
1152 }
1153 if (data[i].contains("<musrview_show_avg>") && data[i].contains("</musrview_show_avg>")) {
1154 if (fMusrviewShowAvg)
1155 data[i] = " <musrview_show_avg>y</musrview_show_avg>";
1156 else
1157 data[i] = " <musrview_show_avg>n</musrview_show_avg>";
1158 }
1159 if (data[i].contains("<enable_musrt0>") && data[i].contains("</enable_musrt0>")) {
1160 if (fEnableMusrT0)
1161 data[i] = " <enable_musrt0>y</enable_musrt0>";
1162 else
1163 data[i] = " <enable_musrt0>n</enable_musrt0>";
1164 }
1165 if (data[i].contains("<ignore_theme_auto_detection>")) {
1167 data[i] = " <ignore_theme_auto_detection>y</ignore_theme_auto_detection>";
1168 else
1169 data[i] = " <ignore_theme_auto_detection>n</ignore_theme_auto_detection>";
1170 }
1171 if (data[i].contains("<dark_theme_icons_menu>") && data[i].contains("</dark_theme_icons_menu>")) {
1173 data[i] = " <dark_theme_icons_menu>y</dark_theme_icons_menu>";
1174 else
1175 data[i] = " <dark_theme_icons_menu>n</dark_theme_icons_menu>";
1176 }
1177 if (data[i].contains("<dark_theme_icons_toolbar>") && data[i].contains("</dark_theme_icons_toolbar>")) {
1179 data[i] = " <dark_theme_icons_toolbar>y</dark_theme_icons_toolbar>";
1180 else
1181 data[i] = " <dark_theme_icons_toolbar>n</dark_theme_icons_toolbar>";
1182 }
1183 if (data[i].contains("<font_name>") && data[i].contains("</font_name>")) {
1184 data[i] = QString(" <font_name>%1</font_name>").arg(fFontName);
1185 }
1186 if (data[i].contains("<font_size>") && data[i].contains("</font_size>")) {
1187 data[i] = QString(" <font_size>%1</font_size>").arg(fFontSize);
1188 }
1189 }
1190
1191 // write prefs
1192 file.setFileName(pref_fln);
1193 if (!file.open(QIODevice::WriteOnly | QIODevice::Text)) {
1194 std::cerr << std::endl << ">> PAdmin::savePrefs: **ERROR** Cannot open " << pref_fln.toLatin1().data() << " for writing." << std::endl;
1195 return 0;
1196 }
1197 fin.setDevice(&file);
1198 for (int i=0; i<data.size(); i++) {
1199 fin << data[i] << Qt::endl;
1200 }
1201 file.close();
1202 } else {
1203 QString msg("Failed to write musredit_startup.xml. Neither a local nor a global copy found.");
1204 QMessageBox::warning(nullptr, "WARNING", msg, QMessageBox::Ok, QMessageBox::NoButton);
1205 }
1206
1207 return 1;
1208}
1209
1210//--------------------------------------------------------------------------
1223void PAdmin::addRecentFile(const QString str)
1224{
1225 // check if file name is not already present
1226 for (int i=0; i<fRecentFile.size(); i++) {
1227 if (str == fRecentFile[i])
1228 return;
1229 }
1230
1231 fRecentFile.push_front(str);
1232 if (fRecentFile.size() > MAX_RECENT_FILES)
1234}
1235
1236//--------------------------------------------------------------------------
1251{
1252 // check if musredit_startup.xml is present in the current directory, and if yes, use this file to
1253 // save the recent file names otherwise use the "master" musredit_startup.xml
1254
1255 QString str("");
1256 QString fln = QString("./musredit_startup.xml");
1257 if (!QFile::exists(fln))
1258 fln = fPrefPathName;
1259
1260 if (QFile::exists(fln)) { // administration file present
1261 QVector<QString> data;
1262 QFile file(fln);
1263 if (!file.open(QIODevice::ReadOnly | QIODevice::Text)) {
1264 std::cerr << std::endl << ">> PAdmin::saveRecentFile: **ERROR** Cannot open " << fln.toLatin1().data() << " for reading." << std::endl;
1265 return;
1266 }
1267 QTextStream fin(&file);
1268 while (!fin.atEnd()) {
1269 data.push_back(fin.readLine());
1270 }
1271 file.close();
1272
1273 // remove <path_file_name> from data
1274 for (QVector<QString>::iterator it = data.begin(); it != data.end(); ++it) {
1275 if (it->contains("<path_file_name>")) {
1276 it = data.erase(it);
1277 --it;
1278 }
1279 }
1280
1281 // add recent files
1282 int i;
1283 for (i=0; i<data.size(); i++) {
1284 if (data[i].contains("<recent_files>"))
1285 break;
1286 }
1287
1288 if (i == data.size()) {
1289 std::cerr << std::endl << ">> PAdmin::saveRecentFile: **ERROR** " << fln.toLatin1().data() << " seems to be corrupt." << std::endl;
1290 return;
1291 }
1292 i++;
1293 for (int j=fRecentFile.size()-1; j>=0; j--) {
1294 str = " <path_file_name>" + fRecentFile[j] + "</path_file_name>";
1295 data.insert(i++, str);
1296 }
1297
1298 if (!file.open(QIODevice::WriteOnly | QIODevice::Text)) {
1299 std::cerr << std::endl << ">> PAdmin::saveRecentFile: **ERROR** Cannot open " << fln.toLatin1().data() << " for reading." << std::endl;
1300 return;
1301 }
1302 fin.setDevice(&file);
1303 for (int i=0; i<data.size(); i++) {
1304 fin << data[i] << Qt::endl;
1305 }
1306 file.close();
1307 } else {
1308 QString msg("Failed to write musredit_startup.xml. Neither a local nor a global copy found.");
1309 QMessageBox::warning(nullptr, "WARNING", msg, QMessageBox::Ok, QMessageBox::NoButton);
1310 }
1311}
1312
1313//--------------------------------------------------------------------------
1329{
1330 // get $HOME
1331 QProcessEnvironment procEnv = QProcessEnvironment::systemEnvironment();
1332 QString pathName = procEnv.value("HOME", "");
1333 pathName += "/.musrfit/musredit";
1334
1335 // check if the directory $HOME/.musrfit/musredit exists if not create it
1336 QDir dir(pathName);
1337 if (!dir.exists()) {
1338 // directory $HOME/.musrfit/musredit does not exist hence create it
1339 dir.mkpath(pathName);
1340 }
1341
1342 // create default musredit_startup.xml file in $HOME/.musrfit/musredit
1343 pathName += "/musredit_startup.xml";
1344
1345 // get the default musredit_startup.xml.in from the internal resources
1346 QFile fres(":/musredit_startup.xml.in");
1347 if (!fres.exists()) {
1348 QString msg = QString("Neither couldn't find nor create musredit_startup.xml. Things are likely not to work.");
1349 QMessageBox::critical(nullptr, "ERROR", msg);
1350 return;
1351 }
1352
1353 if (!fres.open(QIODevice::ReadOnly | QIODevice::Text)) {
1354 QString msg = QString("Couldn't open internal resource file musredit_startup.xml.in. Things are likely not to work.");
1355 QMessageBox::critical(nullptr, "ERROR", msg);
1356 return;
1357 }
1358 // text stream for fres
1359 QTextStream fin(&fres);
1360
1361 // musredit_startup.xml default file
1362 QFile file(pathName);
1363
1364 if (!file.open(QIODevice::WriteOnly | QIODevice::Text))
1365 return;
1366
1367 // text stream for file
1368 QTextStream fout(&file);
1369
1370 QString line;
1371 while (!fin.atEnd()) {
1372 line = fin.readLine();
1373 line.replace("@prefix@", MUSRFIT_PREFIX);
1374 line.replace("@DOCDIR@", MUSRFIT_DOC_DIR);
1375 if (line.contains("<font_name>")) { // defaults: linux: Monospace, macOS: Courier New
1376 if (QSysInfo::productType().contains("osx")) {
1377 line.replace("Monospace", "Courier New");
1378 }
1379 }
1380 if (line.contains("<font_size>")) { // defaults: linux: 12, macOS: 16
1381 if (QSysInfo::productType().contains("osx")) {
1382 line.replace("12", "16");
1383 }
1384 }
1385 fout << line << Qt::endl;
1386 }
1387
1388 file.close();
1389 fres.close();
1390}
1391
1392//--------------------------------------------------------------------------
1393// END
1394//--------------------------------------------------------------------------
Administration and configuration management for musredit.
PTheory fTheoryItem
Temporary storage for theory function data during parsing.
Definition PAdmin.h:172
bool startDocument()
Handler called at the beginning of XML document parsing.
Definition PAdmin.cpp:153
bool parse(QIODevice *device)
Parse the XML configuration file.
Definition PAdmin.cpp:112
bool fValid
Flag indicating whether XML parsing completed successfully.
Definition PAdmin.h:169
void dump()
Dump all configuration values to stdout for debugging.
Definition PAdmin.cpp:700
virtual bool isValid()
Check if the XML file was parsed successfully.
Definition PAdmin.h:136
PAdminXMLParser(const QString &fln, PAdmin *)
Constructs an XML parser for the musredit configuration file.
Definition PAdmin.cpp:81
bool endDocument()
Handler called at the end of XML document parsing.
Definition PAdmin.cpp:659
PAdmin * fAdmin
Pointer to the PAdmin object being populated with configuration data.
Definition PAdmin.h:173
bool startElement()
Handler called when an XML start element is encountered.
Definition PAdmin.cpp:171
QString expandPath(const QString &)
Expand environment variables in a path string.
Definition PAdmin.cpp:795
bool endElement()
Handler called when an XML end element is encountered.
Definition PAdmin.cpp:312
QXmlStreamReader fXml
Qt XML stream reader for parsing the configuration file.
Definition PAdmin.h:168
bool fFunc
Flag indicating parser is inside a <func> element block.
Definition PAdmin.h:171
@ eMusrviewShowFourier
Definition PAdmin.h:147
@ eTheoFuncPixmapPath
Definition PAdmin.h:151
@ eMusrviewShowOneToOne
Definition PAdmin.h:147
@ eIgnoreThemeAutoDetection
Definition PAdmin.h:148
@ eIgnoreDataHeaderInfo
Definition PAdmin.h:154
@ eOpenFileAfterFitting
Definition PAdmin.h:155
@ eNoOfTreadsToBeUsed
Definition PAdmin.h:146
@ eDarkThemeIconsMenu
Definition PAdmin.h:148
@ eDarkThemeIconsToolbar
Definition PAdmin.h:148
@ eLifetimeCorrection
Definition PAdmin.h:150
EAdminKeyWords fKeyWord
Current XML element being processed.
Definition PAdmin.h:170
bool characters()
Handler for XML character data (element content).
Definition PAdmin.cpp:340
Central administration class for musredit configuration management.
Definition PAdmin.h:209
QString getHelpUrl(QString tag)
Get the help URL for a specific documentation section.
Definition PAdmin.cpp:959
bool fDumpRoot
If true, musrfit creates ROOT dump files (for debugging).
Definition PAdmin.h:356
bool fChisqPreRunBlock
If true, write per-run-block chi-square values to msr-file.
Definition PAdmin.h:358
QVector< PTheory > fTheory
Collection of theory functions available in the Theory menu.
Definition PAdmin.h:392
PAdmin()
Constructs the PAdmin object and loads configuration.
Definition PAdmin.cpp:852
QString fFontName
Editor font family name (default: Monospace on Linux, Courier New on macOS).
Definition PAdmin.h:314
bool fEstimateN0
If true, estimate N0 parameter for single histogram fits.
Definition PAdmin.h:359
friend class PAdminXMLParser
Allow XML parser to access protected setters.
Definition PAdmin.h:307
int fFontSize
Editor font size in points (default: 11 on Linux, 16 on macOS).
Definition PAdmin.h:315
PTheory * getTheoryItem(const unsigned int idx)
Get a theory function definition by index.
Definition PAdmin.cpp:978
PMsr2DataParam fMsr2DataParam
Default parameter values for msr2data tool integration.
Definition PAdmin.h:378
int loadPrefs(QString fln)
Load configuration from an XML file.
Definition PAdmin.cpp:1039
void saveRecentFiles()
Save recent file list to configuration file.
Definition PAdmin.cpp:1250
bool fDarkThemeIconsToolbar
If true, use dark theme icons in the toolbar.
Definition PAdmin.h:345
bool fDarkThemeIconsMenu
If true, use dark theme icons in application menus.
Definition PAdmin.h:344
bool fTitleFromDataFile
If true, extract msr-file title from the data file header.
Definition PAdmin.h:357
bool fIgnoreThemeAutoDetection
If true, ignore OS theme detection and use manual icon settings.
Definition PAdmin.h:343
bool fEnableMusrT0
If true, musrT0 tool is enabled in musredit (default: yes).
Definition PAdmin.h:342
int savePrefs(QString pref_fln)
Save current configuration to an XML file.
Definition PAdmin.cpp:1076
bool fMusrviewShowAvg
If true, musrview shows run-averaged data; if false, shows individual runs.
Definition PAdmin.h:340
bool fMusrviewShowFourier
If true, musrview shows Fourier transform at startup instead of time-domain data.
Definition PAdmin.h:339
bool fKeepMinuit2Output
If true, preserve MINUIT2.OUTPUT and MINUIT2.root files after fitting.
Definition PAdmin.h:354
int fTimeout
Timeout for musrfit processes in seconds (default: 1 hour).
Definition PAdmin.h:313
void addRecentFile(const QString str)
Add a file to the recent files list.
Definition PAdmin.cpp:1223
QString getRecentFile(int idx)
Get a recent file path by index.
Definition PAdmin.cpp:1000
int fNoOfThreadsToBeUsed
number of threads to be used
Definition PAdmin.h:361
bool fYamlOut
If true, write MINUIT2 output additionally as <msr-file>.yaml.
Definition PAdmin.h:360
void createMusreditStartupFile()
Create default musredit_startup.xml in user's home directory.
Definition PAdmin.cpp:1328
QVector< QString > fRecentFile
Ring buffer of recently opened file paths (max MAX_RECENT_FILES entries).
Definition PAdmin.h:332
QString fExecPath
Directory containing musrfit executables (musrfit, musrview, etc.).
Definition PAdmin.h:323
void setHelpUrl(const QString tag, const QString url)
Set the help URL for a documentation section.
Definition PAdmin.cpp:1020
QString fPrefPathName
Full path to the active musredit_startup.xml configuration file.
Definition PAdmin.h:322
bool fDumpAscii
If true, musrfit creates ASCII dump files (for debugging).
Definition PAdmin.h:355
QMap< QString, QString > fHelpUrl
Maps section tags (e.g., "theory", "parameters") to help URLs.
Definition PAdmin.h:385
#define MAX_RECENT_FILES
Maximum number of recently opened files to track.
Definition musredit.h:55
Structure holding information about a musrfit theory function.
Definition PAdmin.h:90
QString name
Internal function name used in msr files (e.g., "asymmetry", "simplExpo").
Definition PAdmin.h:91
QString comment
Human-readable description of the theory function.
Definition PAdmin.h:92
QString label
Short label for GUI menus and buttons.
Definition PAdmin.h:93
int params
Number of parameters required by this theory function.
Definition PAdmin.h:96
QString pixmapName
Filename of the pixmap image showing the mathematical formula.
Definition PAdmin.h:94