musrfit 1.10.0
PStartupHandler.cpp
Go to the documentation of this file.
1/***************************************************************************
2
3 PStartupHandler.cpp
4
5 Author: Andreas Suter
6 e-mail: andreas.suter@psi.ch
7
8***************************************************************************/
9
10/***************************************************************************
11 * Copyright (C) 2007-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
30#include <sys/types.h>
31#include <sys/stat.h>
32
33#include <cstdlib>
34#include <iostream>
35#include <fstream>
36
37#include <TObjArray.h>
38#include <TObjString.h>
39#include <TColor.h>
40#include <TList.h>
41#include <TXMLAttr.h>
42
43#include "PStartupHandler.h"
44
46
47//--------------------------------------------------------------------------
48// This function is a replacement for the ParseFile method of TSAXParser.
49// It is needed because in certain environments ParseFile does not work but ParseBuffer does.
50//--------------------------------------------------------------------------
83int parseXmlFile(TSAXParser *saxParser, const char *startup_path_name)
84{
85 int status;
86 std::fstream xmlFile;
87 unsigned int xmlSize = 0;
88 char *xmlBuffer = nullptr;
89
90 xmlFile.open(startup_path_name, std::ios::in | std::ios::ate); // open file for reading and go to the end of the file
91 if (xmlFile.is_open()) { // check if file has been opened successfully
92 xmlSize = xmlFile.tellg(); // get the position within the stream == size of the file (since we are at the end)
93 xmlFile.seekg(0, std::ios::beg); // go back to the beginning of the stream
94 xmlBuffer = new char[xmlSize]; // allocate buffer memory for the whole XML file
95 xmlFile.read(xmlBuffer, xmlSize); // read in the whole XML file into the buffer
96 xmlFile.close(); // close the XML file
97 }
98 if (!xmlBuffer) { // file has not been read into the buffer
99 status = 1;
100 } else {
101 status = saxParser->ParseBuffer(xmlBuffer, xmlSize); // parse buffer
102 delete[] xmlBuffer; // free the buffer memory
103 xmlBuffer = nullptr;
104 }
105
106 return status;
107}
108
109//--------------------------------------------------------------------------
110// Constructor
111//--------------------------------------------------------------------------
148PStartupHandler::PStartupHandler(bool reset_startup_file)
149{
150 fStartupFileFound = false;
151 fStartupFilePath = "";
152
153 // get default path (for the moment only linux like)
154 Char_t *pmusrpath=nullptr;
155 Char_t *home=nullptr;
156 Char_t musrpath[128];
157 Char_t startup_path_name[128];
158
159 strncpy(musrpath, "", sizeof(musrpath));
160
161 // check if the startup file is found in the current directory
162 strcpy(startup_path_name, "./musrfit_startup.xml");
164 fStartupFileFound = true;
166 }
167 if (!fStartupFileFound) { // startup file not found in the current directory
168 // check if the startup file is found under $HOME/.musrfit
169 home = getenv("HOME");
170 if (home != nullptr) {
171 snprintf(startup_path_name, sizeof(startup_path_name), "%s/.musrfit/musrfit_startup.xml", home);
174 fStartupFileFound = true;
175 }
176 }
177 }
178 if (!fStartupFileFound) { // startup file not found in $HOME/.musrfit
179 // check if the MUSRFITPATH system variable is set
180 pmusrpath = getenv("MUSRFITPATH");
181 if (pmusrpath != nullptr) {
182 snprintf(startup_path_name, sizeof(startup_path_name), "%s/musrfit_startup.xml", pmusrpath);
185 fStartupFileFound = true;
186 }
187 }
188 }
189 if (!fStartupFileFound) { // MUSRFITPATH not set or empty, will try $ROOTSYS/bin
190 home = getenv("ROOTSYS");
191 if (home != nullptr) {
192 snprintf(musrpath, sizeof(musrpath), "%s/bin", home);
193 std::cerr << std::endl << "**WARNING** MUSRFITPATH environment variable not set will try " << musrpath << std::endl;
194 snprintf(startup_path_name, sizeof(startup_path_name), "%s/musrfit_startup.xml", musrpath);
197 fStartupFileFound = true;
198 }
199 }
200 }
201
202 // musrfit_startup.xml found. Check if it should be rewritten
203 if (fStartupFileFound && reset_startup_file) {
204 std::cout << std::endl;
205 std::cout << ">> Will only reset the file: '" << fStartupFilePath.Data() << "'."<< std::endl;
206 std::cout << std::endl;
207 if (!WriteDefaultStartupFile(reset_startup_file)) {
208 std::cerr << std::endl << "**ERROR** couldn't re-write " << fStartupFilePath.Data() << "." << std::endl;
209 return;
210 }
211 }
212
213 // if musrfit_startup.xml is still not found, will create a default one
214 if (!fStartupFileFound) {
215 std::cout << std::endl << "**INFO** no musrfit_startup.xml file found, will write a default one." << std::endl;
217 std::cerr << std::endl << "**ERROR** couldn't write default musrfit_startup.xml." << std::endl;
218 } else {
219 home = getenv("HOME");
220 if (home != nullptr) {
221 snprintf(startup_path_name, sizeof(startup_path_name), "%s/.musrfit/musrfit_startup.xml", home);
224 fStartupFileFound = true;
225 }
226 }
227 }
228 }
229}
230
231//--------------------------------------------------------------------------
232// Destructor
233//--------------------------------------------------------------------------
247{
248 // clean up
249 fDataPathList.clear();
250 fMarkerList.clear();
251 fColorList.clear();
252 fRunNameTemplate.clear();
253}
254
255//--------------------------------------------------------------------------
256// OnStartDocument
257//--------------------------------------------------------------------------
280{
281 fKey = eEmpty;
282
283 // init fourier default variables
284 fFourierDefaults.fFourierBlockPresent = false;
286 fFourierDefaults.fFourierPower = 0;
287 fFourierDefaults.fApodization = FOURIER_APOD_NONE;
289 fFourierDefaults.fRangeForPhaseCorrection[0] = -1.0;
290 fFourierDefaults.fRangeForPhaseCorrection[1] = -1.0;
291 fFourierDefaults.fPlotRange[0] = -1.0;
292 fFourierDefaults.fPlotRange[1] = -1.0;
293 fFourierDefaults.fPhaseIncrement = 1.0;
294}
295
296//--------------------------------------------------------------------------
297// OnEndDocument
298//--------------------------------------------------------------------------
312{
313 // check if anything was set, and if not set some default stuff
314 CheckLists();
315}
316
317//--------------------------------------------------------------------------
318// OnStartElement
319//--------------------------------------------------------------------------
349void PStartupHandler::OnStartElement(const Char_t *str, const TList *attributes)
350{
351 if (!strcmp(str, "data_path")) {
352 fKey = eDataPath;
353 } else if (!strcmp(str, "run_name_template")) {
355 TXMLAttr *attr;
356 TIter next(attributes);
357 while ((attr = (TXMLAttr*) next())) {
358 if (!strcmp(attr->GetName(), "inst")) {
359 fCurrentInstrumentName = attr->GetValue();
360 }
361 }
362 } else if (!strcmp(str, "marker")) {
363 fKey = eMarker;
364 } else if (!strcmp(str, "color")) {
365 fKey = eColor;
366 } else if (!strcmp(str, "units")) {
367 fKey = eUnits;
368 } else if (!strcmp(str, "fourier_power")) {
370 } else if (!strcmp(str, "apodization")) {
372 } else if (!strcmp(str, "plot")) {
373 fKey = ePlot;
374 } else if (!strcmp(str, "phase")) {
375 fKey = ePhase;
376 } else if (!strcmp(str, "phase_increment")) {
378 }
379}
380
381//--------------------------------------------------------------------------
382// OnEndElement
383//--------------------------------------------------------------------------
395void PStartupHandler::OnEndElement(const Char_t *str)
396{
397 fKey = eEmpty;
398}
399
400//--------------------------------------------------------------------------
401// OnCharacters
402//--------------------------------------------------------------------------
452void PStartupHandler::OnCharacters(const Char_t *str)
453{
454 TObjArray *tokens;
455 TObjString *ostr;
456 TString tstr;
457 Int_t color, r, g, b, ival;
458
459 PRunNameTemplate tmpl;
460 switch (fKey) {
461 case eDataPath:
462 // check that str is a valid path
463 // add str to the path list
464 fDataPathList.push_back(str);
465 break;
466 case eRunNameTemplate:
468 tmpl.runNameTemplate = str;
469 fRunNameTemplate.push_back(tmpl);
471 break;
472 case eMarker:
473 // check that str is a number
474 tstr = TString(str);
475 if (tstr.IsDigit()) {
476 // add converted str to the marker list
477 fMarkerList.push_back(tstr.Atoi());
478 } else {
479 std::cerr << std::endl << "PStartupHandler **WARNING** '" << str << "' is not a number, will ignore it";
480 std::cerr << std::endl;
481 }
482 break;
483 case eColor:
484 // check that str is a rbg code
485 tstr = TString(str);
486 tokens = tstr.Tokenize(",");
487 // check that there any tokens
488 if (!tokens) {
489 std::cerr << std::endl << "PStartupHandler **WARNING** '" << str << "' is not a rbg code, will ignore it";
490 std::cerr << std::endl;
491 return;
492 }
493 // check there is the right number of tokens
494 if (tokens->GetEntries() != 3) {
495 std::cerr << std::endl << "PStartupHandler **WARNING** '" << str << "' is not a rbg code, will ignore it";
496 std::cerr << std::endl;
497 return;
498 }
499 // get r
500 ostr = dynamic_cast<TObjString*>(tokens->At(0));
501 tstr = ostr->GetString();
502 if (tstr.IsDigit()) {
503 r = tstr.Atoi();
504 } else {
505 std::cerr << std::endl << "PStartupHandler **WARNING** r within the rgb code is not a number, will ignore it";
506 std::cerr << std::endl;
507 return;
508 }
509 // get g
510 ostr = dynamic_cast<TObjString*>(tokens->At(1));
511 tstr = ostr->GetString();
512 if (tstr.IsDigit()) {
513 g = tstr.Atoi();
514 } else {
515 std::cerr << std::endl << "PStartupHandler **WARNING** g within the rgb code is not a number, will ignore it";
516 std::cerr << std::endl;
517 return;
518 }
519 // get b
520 ostr = dynamic_cast<TObjString*>(tokens->At(2));
521 tstr = ostr->GetString();
522 if (tstr.IsDigit()) {
523 b = tstr.Atoi();
524 } else {
525 std::cerr << std::endl << "PStartupHandler **WARNING** b within the rgb code is not a number, will ignore it";
526 std::cerr << std::endl;
527 return;
528 }
529 // clean up tokens
530 if (tokens) {
531 delete tokens;
532 tokens = nullptr;
533 }
534 // generate the ROOT color code based on str
535 color = TColor::GetColor(r,g,b);
536 // add the color code to the color list
537 fColorList.push_back(color);
538 break;
539 case eUnits:
540 tstr = TString(str);
541 if (!tstr.CompareTo("gauss", TString::kIgnoreCase)) {
543 } else if (!tstr.CompareTo("tesla", TString::kIgnoreCase)) {
545 } else if (!tstr.CompareTo("mhz", TString::kIgnoreCase)) {
547 } else if (!tstr.CompareTo("mc/s", TString::kIgnoreCase)) {
549 } else {
550 std::cerr << std::endl << "PStartupHandler **WARNING** '" << str << "' is not a valid unit, will ignore it.";
551 std::cerr << std::endl;
552 }
553 break;
554 case eFourierPower:
555 tstr = TString(str);
556 if (tstr.IsDigit()) {
557 ival = tstr.Atoi();
558 if ((ival >= 0) && (ival <= 20)) {
559 fFourierDefaults.fFourierPower = ival;
560 } else {
561 std::cerr << std::endl << "PStartupHandler **WARNING** fourier power '" << str << "' is not a valid number (0..20), will ignore it.";
562 std::cerr << std::endl;
563 }
564 } else {
565 std::cerr << std::endl << "PStartupHandler **WARNING** fourier power '" << str << "' is not a valid number (0..20), will ignore it.";
566 std::cerr << std::endl;
567 }
568 break;
569 case eApodization:
570 tstr = TString(str);
571 if (!tstr.CompareTo("none", TString::kIgnoreCase)) {
572 fFourierDefaults.fApodization = FOURIER_APOD_NONE;
573 } else if (!tstr.CompareTo("weak", TString::kIgnoreCase)) {
574 fFourierDefaults.fApodization = FOURIER_APOD_WEAK;
575 } else if (!tstr.CompareTo("medium", TString::kIgnoreCase)) {
577 } else if (!tstr.CompareTo("strong", TString::kIgnoreCase)) {
579 } else {
580 std::cerr << std::endl << "PStartupHandler **WARNING** '" << str << "' is not a valid apodization, will ignore it.";
581 std::cerr << std::endl;
582 }
583 break;
584 case ePlot:
585 tstr = TString(str);
586 if (!tstr.CompareTo("real", TString::kIgnoreCase)) {
588 } else if (!tstr.CompareTo("imag", TString::kIgnoreCase)) {
590 } else if (!tstr.CompareTo("real_and_imag", TString::kIgnoreCase)) {
592 } else if (!tstr.CompareTo("power", TString::kIgnoreCase)) {
594 } else if (!tstr.CompareTo("phase", TString::kIgnoreCase)) {
596 } else {
597 std::cerr << std::endl << "PStartupHandler **WARNING** '" << str << "' is not a valid plot option, will ignore it.";
598 std::cerr << std::endl;
599 }
600 break;
601 case ePhase:
602 tstr = TString(str);
603 if (tstr.IsFloat()) {
604 fFourierDefaults.fPhase.push_back(tstr.Atof());
605 } else {
606 std::cerr << std::endl << "PStartupHandler **WARNING** '" << str << "' is not a valid phase, will ignore it.";
607 std::cerr << std::endl;
608 }
609 break;
610 case ePhaseIncrement:
611 tstr = TString(str);
612 if (tstr.IsFloat()) {
613 fFourierDefaults.fPhaseIncrement = tstr.Atof();
614 } else {
615 std::cerr << std::endl << "PStartupHandler **WARNING** '" << str << "' is not a valid phase increment, will ignore it.";
616 std::cerr << std::endl;
617 }
618 break;
619 default:
620 break;
621 }
622}
623
624//--------------------------------------------------------------------------
625// OnComment
626//--------------------------------------------------------------------------
637void PStartupHandler::OnComment(const Char_t *str)
638{
639 // nothing to be done for now
640}
641
642//--------------------------------------------------------------------------
643// OnWarning
644//--------------------------------------------------------------------------
658void PStartupHandler::OnWarning(const Char_t *str)
659{
660 std::cerr << std::endl << "PStartupHandler **WARNING** " << str;
661 std::cerr << std::endl;
662}
663
664//--------------------------------------------------------------------------
665// OnError
666//--------------------------------------------------------------------------
681void PStartupHandler::OnError(const Char_t *str)
682{
683 std::cerr << std::endl << "PStartupHandler **ERROR** " << str;
684 std::cerr << std::endl;
685}
686
687//--------------------------------------------------------------------------
688// OnFatalError
689//--------------------------------------------------------------------------
705void PStartupHandler::OnFatalError(const Char_t *str)
706{
707 std::cerr << std::endl << "PStartupHandler **FATAL ERROR** " << str;
708 std::cerr << std::endl;
709}
710
711//--------------------------------------------------------------------------
712// OnCdataBlock
713//--------------------------------------------------------------------------
727void PStartupHandler::OnCdataBlock(const Char_t *str, Int_t len)
728{
729 // nothing to be done for now
730}
731
732//--------------------------------------------------------------------------
733// CheckLists
734//--------------------------------------------------------------------------
766{
767 // check if anything was set, and if not set some default stuff
768
769 // check if any data path is given
770 if (fDataPathList.size() == 0) {
771 fDataPathList.push_back(TString("/mnt/data/nemu/his"));
772 fDataPathList.push_back(TString("/psi.ch/group/lmu/public/data/lem/his/"));
773 fDataPathList.push_back(TString("/psi.ch/group/lmu/public/data/alc/his/"));
774 fDataPathList.push_back(TString("/psi.ch/group/lmu/public/data/dolly/his/"));
775 fDataPathList.push_back(TString("/psi.ch/group/lmu/public/data/flame/his/"));
776 fDataPathList.push_back(TString("/psi.ch/group/lmu/public/data/gpd/his/"));
777 fDataPathList.push_back(TString("/psi.ch/group/lmu/public/data/gps/his/"));
778 fDataPathList.push_back(TString("/psi.ch/group/lmu/public/data/hal/his/"));
779 fDataPathList.push_back(TString("/psi.ch/group/lmu/public/data/ltf/his/"));
780 fDataPathList.push_back(TString("/psi.ch/group/lmu/public/data/misc/his/"));
781 fDataPathList.push_back(TString("/psi.ch/group/lmu/public/data/vms/his/"));
782 }
783
784 // check if any markers are given
785 if (fMarkerList.size() == 0) {
786 fMarkerList.push_back(24); // open circle
787 fMarkerList.push_back(25); // open square
788 fMarkerList.push_back(26); // open triangle
789 fMarkerList.push_back(27); // open diamond
790 fMarkerList.push_back(28); // open cross
791 fMarkerList.push_back(29); // full star
792 fMarkerList.push_back(30); // open star
793 fMarkerList.push_back(20); // full circle
794 fMarkerList.push_back(21); // full square
795 fMarkerList.push_back(22); // full triangle
796 fMarkerList.push_back(23); // full down triangle
797 fMarkerList.push_back(2); // thin cross
798 fMarkerList.push_back(3); // thin star
799 fMarkerList.push_back(5); // thin cross 45° rotated
800 }
801
802 // check if any colors are given
803 if (fColorList.size() == 0) {
804 fColorList.push_back(TColor::GetColor(0, 0, 0)); // kBlack
805 fColorList.push_back(TColor::GetColor(255, 0, 0)); // kRed
806 fColorList.push_back(TColor::GetColor(0, 255, 0)); // kGreen
807 fColorList.push_back(TColor::GetColor(0, 0, 255)); // kBlue
808 fColorList.push_back(TColor::GetColor(255, 0, 255)); // kMagneta
809 fColorList.push_back(TColor::GetColor(0, 255, 255)); // kCyan
810 fColorList.push_back(TColor::GetColor(156, 0, 255)); // kViolette-3
811 fColorList.push_back(TColor::GetColor(99, 101, 49)); // kYellow-1
812 fColorList.push_back(TColor::GetColor(49, 101, 49)); // kGreen-1
813 fColorList.push_back(TColor::GetColor(156, 48, 0)); // kOrange-4
814 }
815}
816
817//--------------------------------------------------------------------------
818// StartupFileExists
819//--------------------------------------------------------------------------
835{
836 Bool_t result = false;
837
838 std::ifstream ifile(fln);
839
840 if (ifile.fail()) {
841 result = false;
842 } else {
843 result = true;
844 ifile.close();
845 }
846
847 return result;
848}
849
850//--------------------------------------------------------------------------
851// WriteDefaultStartupFile
852//--------------------------------------------------------------------------
899Bool_t PStartupHandler::WriteDefaultStartupFile(bool reset_startup_file)
900{
901 Char_t startup_path_name[256];
902 if (reset_startup_file) { // reset the found
903 snprintf(startup_path_name, sizeof(startup_path_name), "%s", fStartupFilePath.Data());
904 } else { // no musrfit_startup.xml found, hence write default under $HOME/.musrfit
905 // get home
906 Char_t *home = nullptr;
907 home = getenv("HOME");
908 if (home == nullptr) {
909 std::cerr << std::endl << "**ERROR** couldn't obtain $HOME." << std::endl;
910 return false;
911 }
912
913 // first check that $HOME/.musrfit exists and if NOT create it
914 struct stat info;
915
916 snprintf(startup_path_name, sizeof(startup_path_name), "%s/.musrfit", home);
917 if (!stat(startup_path_name, &info)) {
918 if (!(info.st_mode & S_IFDIR))
919 return false;
920 } else {
921 if (mkdir(startup_path_name, 0777)) {
922 std::cerr << std::endl << "**ERROR** couldn't create '" << startup_path_name << "'" << std::endl;
923 return false;
924 }
925 }
926
927 // set path-name for musrfit_startup.xml
928 snprintf(startup_path_name, sizeof(startup_path_name), "%s/.musrfit/musrfit_startup.xml", home);
929 }
930
931 std::ofstream fout(startup_path_name, std::ofstream::out);
932 if (!fout.is_open()) {
933 std::cerr << std::endl << "**ERROR** couldn't open '" << startup_path_name << "' for writing." << std::endl;
934 return false;
935 }
936
937 // write default musrfit_startup.xml
938 fout << "<?xml version=\"1.0\" encoding=\"UTF-8\"?>" << std::endl;
939 fout << "<musrfit xmlns=\"https://lmu.pages.psi.ch/musrfit-docu/\">" << std::endl;
940 fout << " <comment>" << std::endl;
941 fout << " Defines default settings for the musrfit package" << std::endl;
942 fout << " </comment>" << std::endl;
943 fout << " <data_path>/psi.ch/group/lmu/public/data/lem/his</data_path>" << std::endl;
944 fout << " <data_path>/psi.ch/group/lmu/public/data/alc/his</data_path>" << std::endl;
945 fout << " <data_path>/psi.ch/group/lmu/public/data/dolly/his</data_path>" << std::endl;
946 fout << " <data_path>/psi.ch/group/lmu/public/data/flame/his</data_path>" << std::endl;
947 fout << " <data_path>/psi.ch/group/lmu/public/data/gpd/his</data_path>" << std::endl;
948 fout << " <data_path>/psi.ch/group/lmu/public/data/gps/his</data_path>" << std::endl;
949 fout << " <data_path>/psi.ch/group/lmu/public/data/hal/his</data_path>" << std::endl;
950 fout << " <data_path>/psi.ch/group/lmu/public/data/ltf/his</data_path>" << std::endl;
951 fout << " <data_path>/psi.ch/group/lmu/public/data/misc/his</data_path>" << std::endl;
952 fout << " <data_path>/psi.ch/group/lmu/public/data/vms/his</data_path>" << std::endl;
953 fout << " <!-- MISC/PSI 1985 - 1990 -->" << std::endl;
954 fout << " <run_name_template inst=\"misc\">d%yyyy%/deltat_misc_%rrrr%.bin</run_name_template>" << std::endl;
955 fout << " <!-- ALC TD/PSI -->" << std::endl;
956 fout << " <run_name_template inst=\"alc\">d%yyyy%/deltat_zh_chem_%rrrr%.bin</run_name_template>" << std:: endl;
957 fout << " <run_name_template inst=\"alc\">d%yyyy%/deltat_tdc_alc_%rrrr%.bin</run_name_template>" << std::endl;
958 fout << " <run_name_template inst=\"alc\">d%yyyy%/tdc/deltat_tdc_alc_%rrrr%.bin</run_name_template>" << std::endl;
959 fout << " <!-- VMS/PSI -->" << std::endl;
960 fout << " <run_name_template inst=\"vms\">d%yyyy%/tdc/root/deltat_tdc_vms_%yyyy%_%rrrr%.root</run_name_template>" << std::endl;
961 fout << " <!-- Dolly/PSI -->" << std::endl;
962 fout << " <run_name_template inst=\"dolly\">d%yyyy%/tdc/root/deltat_tdc_dolly_%yyyy%_%rrrr%.root</run_name_template>" << std::endl;
963 fout << " <run_name_template inst=\"dolly\">d%yyyy%/pie1/deltat_flc_%rrrr%.bin</run_name_template>" << std::endl;
964 fout << " <run_name_template inst=\"dolly\">d%yyyy%/pie3/deltat_flc_%rrrr%.bin</run_name_template>" << std::endl;
965 fout << " <run_name_template inst=\"dolly\">d%yyyy%/deltat_flc_%rrrr%.bin</run_name_template>" << std::endl;
966 fout << " <run_name_template inst=\"dolly\">d%yyyy%/deltat_pta_dolly_%rrrr%.bin</run_name_template>" << std::endl;
967 fout << " <run_name_template inst=\"dolly\">d%yyyy%/pta/deltat_pta_dolly_%rrrr%.bin</run_name_template>" << std::endl;
968 fout << " <run_name_template inst=\"dolly\">d%yyyy%/tdc/deltat_tdc_dolly_%rrrr%.bin</run_name_template>" << std::endl;
969 fout << " <run_name_template inst=\"dolly\">d%yyyy%/tdc/mdu/deltat_tdc_dolly_%rrrr%.mdu</run_name_template>" << std::endl;
970 fout << " <!-- Flame/PSI -->" << std::endl;
971 fout << " <run_name_template inst=\"flame\">d%yyyy%/tdc/root/deltat_tdc_flame_%yyyy%_%rrrr%.root</run_name_template>" << std::endl;
972 fout << " <run_name_template inst=\"flame\">d%yyyy%/tdc/deltat_tdc_flame_%rrrr%.bin</run_name_template>" << std::endl;
973 fout << " <run_name_template inst=\"flame\">d%yyyy%/tdc/mdu/deltat_tdc_flame_%yyyy%_%rrrr%.mdu</run_name_template>" << std::endl;
974 fout << " <!-- GPD/PSI -->" << std::endl;
975 fout << " <run_name_template inst=\"gpd\">d%yyyy%/tdc/root/deltat_tdc_gpd_%yyyy%_%rrrr%.root</run_name_template>" << std::endl;
976 fout << " <run_name_template inst=\"gpd\">d%yyyy%/deltat_mue1_%rrrr%.bin</run_name_template>" << std::endl;
977 fout << " <run_name_template inst=\"gpd\">d%yyyy%/deltat_fq_si_%rrrr%.bin</run_name_template>" << std::endl;
978 fout << " <run_name_template inst=\"gpd\">d%yyyy%/deltat_strobo_%rrrr%.bin</run_name_template>" << std::endl;
979 fout << " <run_name_template inst=\"gpd\">d%yyyy%/deltat_hp_ni_ht_%rrrr%.bin</run_name_template>" << std::endl;
980 fout << " <run_name_template inst=\"gpd\">d%yyyy%/deltat_hp_ni_%rrrr%.bin</run_name_template>" << std::endl;
981 fout << " <run_name_template inst=\"gpd\">d%yyyy%/deltat_ccr2_%rrrr%.bin</run_name_template>" << std::endl;
982 fout << " <run_name_template inst=\"gpd\">d%yyyy%/deltat_gpd_%rrrr%.bin</run_name_template>" << std::endl;
983 fout << " <run_name_template inst=\"gpd\">d%yyyy%/deltat_janis_%rrrr%.bin</run_name_template>" << std::endl;
984 fout << " <run_name_template inst=\"gpd\">d%yyyy%/deltat_janis_gpd_%rrrr%.bin</run_name_template>" << std::endl;
985 fout << " <run_name_template inst=\"gpd\">d%yyyy%/deltat_pta_gpd_%rrrr%.bin</run_name_template>" << std::endl;
986 fout << " <run_name_template inst=\"gpd\">d%yyyy%/pta/deltat_pta_gpd_%rrrr%.bin</run_name_template>" << std::endl;
987 fout << " <run_name_template inst=\"gpd\">d%yyyy%/tdc/deltat_tdc_gpd_%rrrr%.bin</run_name_template>" << std::endl;
988 fout << " <run_name_template inst=\"gpd\">d%yyyy%/tdc/mdu/deltat_tdc_gpd_%rrrr%.mdu</run_name_template>" << std::endl;
989 fout << " <!-- GPS/PSI -->" << std::endl;
990 fout << " <run_name_template inst=\"gps\">d%yyyy%/tdc/root/deltat_tdc_gps_%yyyy%_%rrrr%.root</run_name_template>" << std::endl;
991 fout << " <run_name_template inst=\"gps\">d%yyyy%/deltat_ccr_%rrrr%.bin</run_name_template>" << std::endl;
992 fout << " <run_name_template inst=\"gps\">d%yyyy%/deltat_he3_%rrrr%.bin</run_name_template>" << std::endl;
993 fout << " <run_name_template inst=\"gps\">d%yyyy%/deltat_stutt_%rrrr%.bin</run_name_template>" << std::endl;
994 fout << " <run_name_template inst=\"gps\">d%yyyy%/deltat_ltf_%rrrr%.bin</run_name_template>" << std::endl;
995 fout << " <run_name_template inst=\"gps\">d%yyyy%/deltat_flc_%rrrr%.bin</run_name_template>" << std::endl;
996 fout << " <run_name_template inst=\"gps\">d%yyyy%/deltat_flc2_%rrrr%.bin</run_name_template>" << std::endl;
997 fout << " <run_name_template inst=\"gps\">d%yyyy%/deltat_oven_%rrrr%.bin</run_name_template>" << std::endl;
998 fout << " <run_name_template inst=\"gps\">d%yyyy%/deltat_oven2_%rrrr%.bin</run_name_template>" << std::endl;
999 fout << " <run_name_template inst=\"gps\">d%yyyy%/deltat_pta_gps_%rrrr%.bin</run_name_template>" << std::endl;
1000 fout << " <run_name_template inst=\"gps\">d%yyyy%/tdc/deltat_tdc_gps_%rrrr%.bin</run_name_template>" << std::endl;
1001 fout << " <run_name_template inst=\"gps\">d%yyyy%/tdc/mdu/deltat_tdc_gps_%yyyy%_%rrrr%.mdu</run_name_template>" << std::endl;
1002 fout << " <!-- HAL-9500/PSI == HIFI/PSI -->" << std::endl;
1003 fout << " <run_name_template inst=\"hifi\">d%yyyy%/tdc/root/deltat_tdc_hifi_%yyyy%_%rrrr%.root</run_name_template>" << std::endl;
1004 fout << " <run_name_template inst=\"hifi\">d%yyyy%/tdc/deltat_hifi_%rrrr%.bin</run_name_template>" << std::endl;
1005 fout << " <run_name_template inst=\"hifi\">d%yyyy%/tdc/tdc_hifi_%yyyy%_%rrrrr%.mdu</run_name_template>" << std::endl;
1006 fout << " <run_name_template inst=\"hifi\">d%yyyy%/tdc/root/deltat_tdc_hifi_%yyyy%_%rrrr%.mdu</run_name_template>" << std::endl;
1007 fout << " <!-- LTF/PSI -->" << std::endl;
1008 fout << " <run_name_template inst=\"ltf\">d%yyyy%/deltat_ltf_%rrrr%.bin</run_name_template>" << std::endl;
1009 fout << " <run_name_template inst=\"ltf\">d%yyyy%/deltat_ltf2_%rrrr%.bin</run_name_template>" << std::endl;
1010 fout << " <run_name_template inst=\"ltf\">d%yyyy%/deltat_pta_ltf_%rrrr%.bin</run_name_template>" << std::endl;
1011 fout << " <run_name_template inst=\"ltf\">d%yyyy%/pta/deltat_pta_ltf_%rrrr%.bin</run_name_template>" << std::endl;
1012 fout << " <run_name_template inst=\"ltf\">d%yyyy%/tdc/deltat_tdc_ltf_%rrrr%.bin</run_name_template>" << std::endl;
1013 fout << " <!-- LEM/PSI -->" << std::endl;
1014 fout << " <run_name_template inst=\"lem\">%yyyy%/lem%yy%_his_%rrrr%.root</run_name_template>" << std::endl;
1015 fout << " <run_name_template inst=\"lem\">d%yyyy%/tdc/lem%yy%_his_%rrrr%.root</run_name_template>" << std::endl;
1016 fout << " <run_name_template inst=\"lem\">%yyyy%/lem%yy%_his_%rrrrr%.root</run_name_template>" << std::endl;
1017 fout << " <run_name_template inst=\"lem\">d%yyyy%/tdc/lem%yy%_his_%rrrrr%.root</run_name_template>" << std::endl;
1018 fout << " <fourier_settings>" << std::endl;
1019 fout << " <units>Gauss</units>" << std::endl;
1020 fout << " <fourier_power>0</fourier_power>" << std::endl;
1021 fout << " <apodization>none</apodization>" << std::endl;
1022 fout << " <plot>real_and_imag</plot>" << std::endl;
1023 fout << " <phase>0.0</phase>" << std::endl;
1024 fout << " <phase_increment>1.0</phase_increment>" << std::endl;
1025 fout << " </fourier_settings>" << std::endl;
1026 fout << " <root_settings>" << std::endl;
1027 fout << " <marker_list>" << std::endl;
1028 fout << " <!-- Root marker numbers -->" << std::endl;
1029 fout << " <marker>24</marker> <!-- open circle -->" << std::endl;
1030 fout << " <marker>25</marker> <!-- open square -->" << std::endl;
1031 fout << " <marker>26</marker> <!-- open triangle -->" << std::endl;
1032 fout << " <marker>27</marker> <!-- open diamond -->" << std::endl;
1033 fout << " <marker>28</marker> <!-- open cross -->" << std::endl;
1034 fout << " <marker>29</marker> <!-- full star -->" << std::endl;
1035 fout << " <marker>30</marker> <!-- open star -->" << std::endl;
1036 fout << " <marker>20</marker> <!-- full circle -->" << std::endl;
1037 fout << " <marker>21</marker> <!-- full square -->" << std::endl;
1038 fout << " <marker>22</marker> <!-- full triangle -->" << std::endl;
1039 fout << " <marker>23</marker> <!-- full triangle down -->" << std::endl;
1040 fout << " <marker>2</marker> <!-- thin cross -->" << std::endl;
1041 fout << " <marker>3</marker> <!-- thin star -->" << std::endl;
1042 fout << " <marker>5</marker> <!-- thin x -->" << std::endl;
1043 fout << " </marker_list>" << std::endl;
1044 fout << " <color_list>" << std::endl;
1045 fout << " <!-- Color as RGB coded string -->" << std::endl;
1046 fout << " <color>0,0,0</color> <!-- kBlack -->" << std::endl;
1047 fout << " <color>255,0,0</color> <!-- kRed -->" << std::endl;
1048 fout << " <color>0,153,0</color> <!-- kGreen+2 -->" << std::endl;
1049 fout << " <color>0,0,255</color> <!-- kBlue -->" << std::endl;
1050 fout << " <color>255,0,255</color> <!-- kMagenta -->" << std::endl;
1051 fout << " <color>0,255,255</color> <!-- kCyan -->" << std::endl;
1052 fout << " <color>153,0,255</color> <!-- kViolet-3 -->" << std::endl;
1053 fout << " <color>102,102,51</color> <!-- kYellow-1 -->" << std::endl;
1054 fout << " <color>51,102,51</color> <!-- kGreen-1 -->" << std::endl;
1055 fout << " <color>153,0,0</color> <!-- kRed+2 -->" << std::endl;
1056 fout << " </color_list>" << std::endl;
1057 fout << " </root_settings>" << std::endl;
1058 fout << "</musrfit>" << std::endl;
1059
1060 fout.close();
1061
1062 return true;
1063}
1064
1065// -------------------------------------------------------------------------
1066// end
1067// -------------------------------------------------------------------------
1068
#define FOURIER_UNIT_FREQ
Frequency in MHz.
Definition PMusr.h:276
#define FOURIER_PLOT_REAL_AND_IMAG
Plot both real and imaginary components (default)
Definition PMusr.h:314
#define FOURIER_UNIT_GAUSS
Magnetic field in Gauss (G)
Definition PMusr.h:272
#define FOURIER_PLOT_POWER
Plot power spectrum |F(ω)|²
Definition PMusr.h:316
#define FOURIER_PLOT_REAL
Plot real component only.
Definition PMusr.h:310
#define FOURIER_APOD_WEAK
Weak apodization (gentle windowing)
Definition PMusr.h:294
#define FOURIER_APOD_NONE
No apodization (rectangular window)
Definition PMusr.h:292
#define FOURIER_UNIT_CYCLES
Angular frequency in Mc/s (Mega-cycles per second)
Definition PMusr.h:278
#define FOURIER_APOD_STRONG
Strong apodization (heavy windowing for best frequency resolution)
Definition PMusr.h:298
#define FOURIER_PLOT_IMAG
Plot imaginary component only.
Definition PMusr.h:312
#define FOURIER_APOD_MEDIUM
Medium apodization (moderate windowing)
Definition PMusr.h:296
#define FOURIER_PLOT_PHASE
Plot phase spectrum arg(F(ω))
Definition PMusr.h:318
#define FOURIER_UNIT_TESLA
Magnetic field in Tesla (T)
Definition PMusr.h:274
const char * startup_path_name
ClassImpQ(PStartupHandler) int parseXmlFile(TSAXParser *saxParser
Replacement for TSAXParser::ParseFile() that uses buffer-based parsing.
char * xmlBuffer
std::fstream xmlFile
if(xmlFile.is_open())
return status
unsigned int xmlSize
int parseXmlFile(TSAXParser *, const char *)
Replacement function for TSAXParser::ParseFile().
Handles the musrfit XML startup configuration file (musrfit_startup.xml).
PRunNameTemplateList fRunNameTemplate
List of instrument-specific run name patterns.
PStartupHandler(bool reset_startup_file=false)
Constructor that locates and parses the musrfit startup configuration file.
virtual void CheckLists()
Validates configuration lists and fills missing entries with defaults.
virtual void OnComment(const Char_t *)
SAX callback: Called when XML comment is found (unused).
PIntVector fColorList
List of ROOT TColor codes (from RGB) for plotting.
PStringVector fDataPathList
List of directories to search for data files.
Bool_t fStartupFileFound
True if musrfit_startup.xml was located.
virtual void OnWarning(const Char_t *)
SAX callback: Called when XML parser issues a warning.
virtual void OnError(const Char_t *)
SAX callback: Called when XML parser encounters an error.
virtual void OnFatalError(const Char_t *)
SAX callback: Called when XML parser encounters a fatal error.
EKeyWords fKey
Current XML element type (SAX parser state)
TString fStartupFilePath
Full path to located startup file (empty if not found)
@ eApodization
Inside <apodization> element (none/weak/medium/strong)
@ eFourierPower
Inside <fourier_power> element (0-20)
@ eEmpty
No active element (between elements or unknown)
@ eMarker
Inside <marker> element (ROOT marker code)
@ ePhaseIncrement
Inside <phase_increment> element (degrees per step)
@ eUnits
Inside <units> element (Gauss/Tesla/MHz/Mc/s)
@ ePhase
Inside <phase> element (degrees)
@ ePlot
Inside <plot> element (real/imag/real_and_imag/power/phase)
@ eColor
Inside <color> element (RGB comma-separated)
@ eRunNameTemplate
Inside <run_name_template> element.
@ eDataPath
Inside <data_path> element.
TString fCurrentInstrumentName
Instrument name from run_name_template inst attribute.
virtual void OnEndElement(const Char_t *)
SAX callback: Called when an XML end element is encountered.
virtual void OnCharacters(const Char_t *)
SAX callback: Called with element text content.
PIntVector fMarkerList
List of ROOT TMarker style codes for plotting.
virtual ~PStartupHandler()
Destructor releasing allocated resources.
virtual void OnEndDocument()
SAX callback: Called when XML document parsing ends. Triggers CheckLists() to ensure all required set...
Bool_t WriteDefaultStartupFile(bool reset_startup_file=false)
Creates or overwrites a startup file with default configuration.
virtual void OnCdataBlock(const Char_t *, Int_t)
SAX callback: Called for CDATA blocks (unused).
PMsrFourierStructure fFourierDefaults
Fourier transform default settings structure.
virtual void OnStartElement(const Char_t *, const TList *)
SAX callback: Called when an XML start element is encountered.
virtual void OnStartDocument()
SAX callback: Called when XML document parsing begins. Initializes all configuration variables to def...
Bool_t StartupFileExists(Char_t *fln)
Checks if a file exists at the specified path.
TString runNameTemplate
File path template with placeholders (r=run, y=year)
Definition PMusr.h:1447
TString instrument
Instrument identifier (e.g., "GPS", "LEM", "DOLLY")
Definition PMusr.h:1446