musrfit 1.10.0
PMsr2Data.cpp
Go to the documentation of this file.
1/***************************************************************************
2
3 PMsr2Data.cpp
4
5 Author: Bastian M. Wojek / Andreas Suter
6 e-mail: andreas.suter@psi.ch
7
8***************************************************************************/
9
10/***************************************************************************
11 * Copyright (C) 2009-2026 by Bastian M. Wojek / 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// note: msr2data is on purpose implemented in a way that shows string handling can be done solely
31// using std::string, boost and related standard C++ features
32// This implies, however, occasionally strange constructs when interoperating with PMusr-classes
33// which mostly rely on ROOT's TString.
34
35#include <cctype>
36#include <sstream>
37#include <fstream>
38#include <iomanip>
39#include <algorithm>
40#include <limits>
41#include <memory>
42
43#include <boost/algorithm/string/trim.hpp> // for stripping leading whitespace in std::string
44#include <boost/algorithm/string/case_conv.hpp> // for to_lower() in std::string
45#include <boost/algorithm/string/split.hpp> // split strings at certain characters
46using namespace boost::algorithm;
47
48#include <boost/lexical_cast.hpp> // for atoi-replacement
49
50#include "PMsr2Data.h"
51
52//-------------------------------------------------------------
53// Constructor
54//-------------------------------------------------------------
74{
75 fRunVector.clear();
77 fSaxParser = nullptr;
78 fStartupHandler = nullptr;
79 fDataHandler = nullptr;
80 fMsrHandler = nullptr;
81}
82
83//-------------------------------------------------------------
84// Destructor
85//-------------------------------------------------------------
94{
95 fRunVector.clear();
97 fIndVar.clear();
98}
99
100//-------------------------------------------------------------
101// DetermineRunNumberDigits
102//-------------------------------------------------------------
131int PMsr2Data::DetermineRunNumberDigits(unsigned int runNo, bool normalMode) const
132{
133 std::ostringstream strInfile;
134 strInfile << runNo << fFileExtension << ".msr";
135 std::unique_ptr<std::ifstream> in = std::make_unique<std::ifstream>(strInfile.str().c_str());
136 if (!in->is_open()) {
137 if (!normalMode && (runNo == *fRunVectorIter)) {
138 std::string fileNameCopy(strInfile.str());
139 strInfile.clear();
140 strInfile.str("");
141 strInfile << runNo << "+global" << fFileExtension << ".msr";
142 in.reset(new std::ifstream(strInfile.str().c_str()));
143 if (!in->is_open()) {
144 std::cerr << std::endl << ">> msr2data: **ERROR** Neither the file " << fileNameCopy << " nor the file " << strInfile.str() << " can be opened! Please check!";
145 std::cerr << std::endl;
146 return -1;
147 }
148 } else if (runNo == *fRunVectorIter) { // the first run of the runlist was given - if it did not exist, try the rest of the runlist
149 if (++fRunVectorIter != fRunVector.end()) {
151 } else {
152 std::cerr << std::endl << ">> msr2data: **ERROR** None of the given msr-files can be opened! Please check!";
153 std::cerr << std::endl;
154 return -1;
155 }
156 } else {
157 std::cerr << std::endl << ">> msr2data: **ERROR** The given template " << strInfile.str() << " cannot be opened! Please check!";
158 std::cerr << std::endl;
159 return -1;
160 }
161 }
162
163 std::ostringstream tempRunNumber;
164 tempRunNumber.fill('0');
165 tempRunNumber.setf(std::ios::internal, std::ios::adjustfield);
166 tempRunNumber.width(fRunNumberDigits);
167 tempRunNumber << runNo;
168
169 fRunNumberDigits = tempRunNumber.str().length();
170
171 std::string line, firstOnLine;
172 std::istringstream strLine;
173
174 while (getline(*in, line)) {
175 strLine.clear();
176 strLine.str(line);
177 strLine >> firstOnLine;
178 if (!to_lower_copy(firstOnLine).compare("run")) {
179 // for path-names with spaces
180 std::string::size_type loc{0};
181 while (!strLine.eof()) {
182 firstOnLine.clear();
183 strLine >> firstOnLine;
184 loc = firstOnLine.rfind(tempRunNumber.str());
185 if ( loc != std::string::npos ) {
186 while ( loc > 0 ) {
187 if (isdigit(firstOnLine.at(--loc))) {
189 } else {
190 break;
191 }
192 }
193 in->close();
194 fRunVectorIter = fRunVector.begin(); // set back the runlist-iterator which might have changed during the search for the correct file
195 return 0;
196 }
197 }
198 std::cerr << std::endl << ">> msr2data: **ERROR** The first processed run file number does not match the \"file index\"!";
199 std::cerr << std::endl << ">> msr2data: **ERROR** The number of digits to be used for formatting the run numbers cannot be determined!";
200 std::cerr << std::endl << ">> msr2data: **ERROR** Please check the first msr-file that should be processed;";
201 std::cerr << std::endl << ">> msr2data: **ERROR** this is either some template or the first existing file from the run list.";
202 std::cerr << std::endl;
203 in->close();
204 return -2;
205 }
206 }
207 std::cerr << std::endl << ">> msr2data: **ERROR** Please check the first msr-file that should be processed;";
208 std::cerr << std::endl << ">> msr2data: **ERROR** this is either some template or the first file from the run list.";
209 std::cerr << std::endl << ">> msr2data: **ERROR** Obviously it contains no RUN block...";
210 std::cerr << std::endl;
211 in->close();
212
213 return -3;
214}
215
216//-------------------------------------------------------------
217// CheckRunNumbersInRange
218//-------------------------------------------------------------
239{
240 // since 2023, we encounter in LEM run numbers > 9999, hence this check has been loosened
241 // by replacing static_cast<int>(fRunNumberDigits)) by static_cast<int>(fRunNumberDigits+1)).
242 double max(pow(static_cast<double>(10), static_cast<int>(fRunNumberDigits+1)) - 1.0);
243 unsigned int max_UInt;
244 max > static_cast<double>(std::numeric_limits<unsigned int>::max()) ? max_UInt = std::numeric_limits<unsigned int>::max()
245 : max_UInt = static_cast<unsigned int>(max);
246 for (std::vector<unsigned int>::const_iterator iter(fRunVector.begin()); iter != fRunVector.end(); ++iter) {
247 if (*iter > max_UInt) {
248 return -1;
249 }
250 }
251 return 0;
252}
253
254//-------------------------------------------------------------
255// GetPresentRun
256//-------------------------------------------------------------
267unsigned int PMsr2Data::GetPresentRun() const
268{
269 if (fRunVectorIter != fRunVector.end())
270 return *fRunVectorIter;
271 else
272 return 0;
273}
274
275//-------------------------------------------------------------
276// SetRunNumbers (single run)
277//-------------------------------------------------------------
290int PMsr2Data::SetRunNumbers(unsigned int runNo)
291{
292 if (runNo < 1)
293 return 1;
294
295 fRunVector.clear();
296 fRunVector.push_back(runNo);
297 fRunVectorIter = fRunVector.begin();
298
299 return 0;
300}
301
302//-------------------------------------------------------------
303// SetRunNumbers (range)
304//-------------------------------------------------------------
321int PMsr2Data::SetRunNumbers(unsigned int runNoStart, unsigned int runNoEnd)
322{
323 if ((runNoStart < 1) || (runNoEnd < 1))
324 return 1;
325
326 fRunVector.clear();
327 if (runNoStart <= runNoEnd) {
328 for (unsigned int i(runNoStart); i<=runNoEnd; ++i)
329 fRunVector.push_back(i);
330 } else {
331 for (unsigned int i(runNoStart); i>=runNoEnd; --i)
332 fRunVector.push_back(i);
333 }
334 fRunVectorIter = fRunVector.begin();
335
336 return 0;
337}
338
339//-------------------------------------------------------------
340// SetRunNumbers (explicit vector)
341//-------------------------------------------------------------
355int PMsr2Data::SetRunNumbers(const std::vector<unsigned int> &runListVector)
356{
357 if (runListVector.empty())
358 return -1;
359
360 for (std::vector<unsigned int>::const_iterator iter(runListVector.begin()); iter!=runListVector.end(); ++iter) {
361 if (*iter < 1)
362 return 1;
363 }
364
365 fRunVector = runListVector;
366 fRunVectorIter = fRunVector.begin();
367
368 return 0;
369}
370
371//-------------------------------------------------------------
372// SetRunNumbers (from file)
373//-------------------------------------------------------------
400int PMsr2Data::SetRunNumbers(const std::string &runListFile)
401{
402 fRunVector.clear();
403
404 std::ifstream in(runListFile.c_str());
405 if (!in) {
406 std::cerr << std::endl << ">> msr2data: **ERROR** The runlist file " << runListFile << " cannot be opened! Please check!";
407 std::cerr << std::endl;
408 return -1;
409 }
410
411 std::string line, indvar;
412 std::istringstream strLine;
413 std::vector<std::string> splitVec;
414 unsigned int cntr(0);
415 unsigned int runNo;
416
417 while (getline(in, line)) {
418 trim(line);
419 if (line.empty())
420 continue;
421 else if (line.at(0) == '#')
422 continue;
423 else
424 ++cntr;
425
426 split( splitVec, line, is_any_of("#") ); // split the string if any comments appear on the line
427
428 if (cntr == 1) { // Read in the names of the independent variables in the runlist file
429 strLine.clear();
430 strLine.str(splitVec[0]);
431 strLine >> indvar; // "RUN"
432 if (to_lower_copy(indvar).compare("run")) {
433 std::cerr << std::endl << ">> msr2data: **ERROR** The format of the runlist file " << runListFile << " is not correct! Please check!";
434 std::cerr << std::endl;
435 }
436 while (strLine >> indvar)
437 fIndVar.push_back(indvar);
438 }
439
440 if (cntr > 1) {
441 strLine.clear();
442 strLine.str(splitVec[0]);
443 strLine >> runNo;
444 if (runNo < 1)
445 return 1;
446 fRunVector.push_back(runNo);
447 }
448
449 splitVec.clear();
450 }
451
452 in.close();
453 fRunVectorIter = fRunVector.begin();
454 fRunListFile = true;
455 fRunListFileStream = std::make_unique<std::ifstream>(runListFile.c_str());
456
457 return 0;
458}
459
460//-------------------------------------------------------------
461// ParseXmlStartupFile
462//-------------------------------------------------------------
483{
484 int status;
485 fSaxParser = std::make_unique<TSAXParser>();
486 fStartupHandler = std::make_unique<PStartupHandler>();
487 std::string startup_path_name(fStartupHandler->GetStartupFilePath().Data());
488 fSaxParser->ConnectToHandler("PStartupHandler", fStartupHandler.get());
489 //status = fSaxParser->ParseFile(startup_path_name.c_str());
490 // parsing the file as above seems to lead to problems in certain environments;
491 // use the parseXmlFile function instead (see PStartupHandler.cpp for the definition)
493 // check for parse errors
494 if (status) { // error
495 std::cerr << std::endl << ">> msr2data: **WARNING** Reading/parsing musrfit_startup.xml failed." << std::endl;
496 }
497 return status;
498}
499
500//-------------------------------------------------------------
501// ReadMsrFile
502//-------------------------------------------------------------
517int PMsr2Data::ReadMsrFile(const std::string &infile) const
518{
519 int status;
520 fMsrHandler = std::make_unique<PMsrHandler>(infile.c_str());
521 status = fMsrHandler->ReadMsrFile();
522 if (status != PMUSR_SUCCESS) {
523 switch (status) {
525 std::cerr << std::endl << ">> msr2data: **ERROR** Could not find " << infile << std::endl;
526 break;
528 std::cerr << std::endl << ">> msr2data: **SYNTAX ERROR** in file " << infile << ", full stop here." << std::endl;
529 break;
530 default:
531 std::cerr << std::endl << ">> msr2data: **UNKOWN ERROR** when trying to read the msr-file" << std::endl;
532 break;
533 }
534 }
535 return status;
536}
537
538//-------------------------------------------------------------
539// GetSingleRunMsrFile
540//-------------------------------------------------------------
557{
558 std::ostringstream singleMsrInFile;
559 singleMsrInFile << *fRunVectorIter << "-OneRunFit" << fFileExtension << ".msr";
560 PMsrHandler *singleRunMsrFile = new PMsrHandler(singleMsrInFile.str().c_str());
561
562 int status = singleRunMsrFile->ReadMsrFile();
563 if (status != PMUSR_SUCCESS) {
564 switch (status) {
566 std::cerr << std::endl << ">> msr2data: **ERROR** Could not find " << singleMsrInFile.str() << std::endl;
567 break;
569 std::cerr << std::endl << ">> msr2data: **SYNTAX ERROR** in file " << singleMsrInFile.str() << ", full stop here." << std::endl;
570 break;
571 default:
572 std::cerr << std::endl << ">> msr2data: **UNKOWN ERROR** when trying to read the msr-file" << std::endl;
573 break;
574 }
575 return nullptr;
576 }
577
578 return singleRunMsrFile;
579}
580
581//-------------------------------------------------------------
582// ReadRunDataFile
583//-------------------------------------------------------------
600{
601 if (fStartupHandler)
602 fDataHandler = std::make_unique<PRunDataHandler>(fMsrHandler.get(), fStartupHandler->GetDataPathList());
603 else
604 fDataHandler = std::make_unique<PRunDataHandler>(fMsrHandler.get());
605
606 fDataHandler->ReadData();
607
608 bool success = fDataHandler->IsAllDataAvailable();
609 if (!success) {
610 std::cerr << std::endl << ">> msr2data: **WARNING** Could not read all data files, will continue without the data file information..." << std::endl;
611 return 1;
612 }
613
614 return 0;
615}
616
617//-------------------------------------------------------------
628bool PMsr2Data::PrepareNewInputFile(unsigned int tempRun, bool calledFromGlobalMode) const
629{
630 if (fRunVectorIter == fRunVector.end())
631 return false;
632
633 if (*fRunVectorIter == tempRun)
634 return true;
635
636 std::string globalTag("");
637 if (calledFromGlobalMode)
638 globalTag = "-OneRunFit";
639
640 std::ostringstream strInfile;
641 strInfile << tempRun << globalTag << fFileExtension << ".msr";
642
643 std::ifstream in(strInfile.str().c_str());
644 if (!in) {
645 std::cerr << std::endl << ">> msr2data: **ERROR** The template msr-file " << strInfile.str() << " cannot be opened! Please check!";
646 std::cerr << std::endl;
647 return false;
648 }
649 std::ostringstream strOutfile;
650 strOutfile << *fRunVectorIter << globalTag << fFileExtension << ".msr";
651 std::ofstream out(strOutfile.str().c_str());
652 if (!out) {
653 std::cerr << std::endl << ">> msr2data: **ERROR** The new msr file " << strOutfile.str() << " cannot be opened! Please check!";
654 std::cerr << std::endl;
655 return false;
656 }
657
658 std::ostringstream tempRunNumber;
659 tempRunNumber.fill('0');
660 tempRunNumber.setf(std::ios::internal, std::ios::adjustfield);
661 tempRunNumber.width(fRunNumberDigits);
662 tempRunNumber << tempRun;
663
664 std::ostringstream newRunNumber;
665 newRunNumber.fill('0');
666 newRunNumber.setf(std::ios::internal, std::ios::adjustfield);
667 newRunNumber.width(fRunNumberDigits);
668 newRunNumber << *fRunVectorIter;
669
670 std::cout << std::endl << ">> msr2data: **INFO** Generating new input msr file " << strOutfile.str() << std::endl;
671
672 std::string line, firstOnLine;
673 std::istringstream strLine;
674 unsigned int emptyLineCounter(0);
675
676 // write the run number in the TITLE line of the msr-file (is overwritten later by musrfit if called with the -t option)
677 getline(in, line);
678 out << *fRunVectorIter << std::endl;
679
680 while (getline(in, line)) {
681 if (line.empty()) {
682 if (++emptyLineCounter < 3) // allow only two successive empty lines in the input files (just for convenience)
683 out << std::endl;
684 continue;
685 } else
686 emptyLineCounter = 0;
687
688 if (!line.compare("SET BATCH") || !line.compare("END RETURN"))
689 continue;
690
691 strLine.clear();
692 strLine.str(line);
693 strLine >> firstOnLine;
694 if (!to_lower_copy(firstOnLine).compare("run")) {
695 // needed for path-fln with spaces
696 std::string::size_type loc;
697 std::string sstr{""};
698 firstOnLine.clear();
699 while (!strLine.eof()) {
700 strLine >> sstr;
701 if (firstOnLine.empty())
702 firstOnLine = sstr;
703 else
704 firstOnLine += " " + sstr;
705 loc = firstOnLine.rfind(tempRunNumber.str());
706 if ( loc != std::string::npos ) {
707 firstOnLine.replace(loc, fRunNumberDigits, newRunNumber.str());
708 break;
709 }
710 }
711 if (strLine.eof()) {
712 std::cerr << std::endl << ">> msr2data: **WARNING** The template run file number does not match the \"file index\"";
713 std::cerr << std::endl << ">> msr2data: **WARNING** Unexpected things will happen... (for sure)";
714 std::cerr << std::endl;
715 }
716 out << "RUN " << firstOnLine;
717 while (strLine >> firstOnLine)
718 out << " " << firstOnLine;
719 out << std::endl;
720 } else if (!to_lower_copy(firstOnLine).compare("chisq") || !to_lower_copy(firstOnLine).compare("maxlh")) {
721 out << "*** FIT DID NOT CONVERGE ***" << std::endl;
722 break;
723 } else {
724 out << line << std::endl;
725 }
726 }
727 in.close();
728 out.close();
729 return true;
730}
731
732
733//-------------------------------------------------------------
747{
748 if (par1.fIsGlobal) {
749 if (par2.fIsGlobal && (par2.fNo > par1.fNo))
750 return true;
751 else if (par2.fIsGlobal && (par2.fNo < par1.fNo))
752 return false;
753 else
754 return true;
755 }
756 else if (par2.fIsGlobal)
757 return false;
758 else if (par2.fNo > par1.fNo)
759 return true;
760 else
761 return false;
762}
763
764//-------------------------------------------------------------
779bool PMsr2Data::PrepareGlobalInputFile(unsigned int tempRun, const std::string &msrOutFile, unsigned int globalPlus) const
780{
781 const TString alpha("alpha"), beta("beta"), norm("norm"), bkgfit("bkgfit"), lifetime("lifetime");
782
783 std::ostringstream strInfile;
784 strInfile << tempRun << fFileExtension << ".msr";
785
786 // read template msr-file
787 int status(ReadMsrFile(strInfile.str()));
788 if (status != PMUSR_SUCCESS)
789 return false;
790
791 // define two heavily used variables
792 PMsrParamList *msrParamList(fMsrHandler->GetMsrParamList());
793 PMsrRunList *msrRunList(fMsrHandler->GetMsrRunList());
794
795 // check how many RUN blocks are in the template msr-file
796 fNumTempRunBlocks = msrRunList->size();
797
798 // check that the RUN block run numbers match the template run number
799 std::ostringstream tempRunNumber;
800 tempRunNumber.fill('0');
801 tempRunNumber.setf(std::ios::internal, std::ios::adjustfield);
802 tempRunNumber.width(fRunNumberDigits);
803 tempRunNumber << tempRun;
804
805 std::string tempRunName;
806 for (unsigned int i(0); i < fNumTempRunBlocks; ++i) {
807 tempRunName = msrRunList->at(i).GetRunName()->Data();
808 std::string::size_type loc = tempRunName.rfind(tempRunNumber.str());
809 if ( loc == std::string::npos ) {
810 std::cerr << std::endl << ">> msr2data: **ERROR** A template run file number does not match the \"file index\"";
811 std::cerr << std::endl << ">> msr2data: **ERROR** Please check the template file!";
812 std::cerr << std::endl;
813 return false;
814 }
815 }
816
817 std::cout << std::endl << ">> msr2data: **INFO** Generating new global input msr file " << msrOutFile << std::endl;
818
819 // set some title for the msr-file
820 std::ostringstream titleStream;
821 titleStream << "Global msr file for the runs: ";
822 while (fRunVectorIter != fRunVector.end()) {
823 titleStream << *fRunVectorIter << " ";
825 }
826 fRunVectorIter = fRunVector.begin();
827 fMsrHandler->SetMsrTitle(TString(titleStream.str()));
828 titleStream.clear();
829 titleStream.str("");
830
831 // search parameter list for run-specific parameters - the rest is assumed to be global
832 std::string tempParamName;
833 for (unsigned int i(0); i < msrParamList->size(); ++i) {
834 tempParamName = msrParamList->at(i).fName.Data();
835 std::string::size_type loc = tempParamName.rfind(tempRunNumber.str());
836 if ((tempParamName.length() > fRunNumberDigits) && (loc == tempParamName.length() - fRunNumberDigits)) {
837 msrParamList->at(i).fIsGlobal = false;
839 } else {
840 msrParamList->at(i).fIsGlobal = true;
842 }
843 }
844
845 // there should be at least one run specific parameter, otherwise the GLOBAL option doesn't make sense
846 if (fNumSpecParam == 0) {
847 std::cout << ">> msr2data: **ERROR** found NO run specific parameter, hence the GLOBAL option doesn't make sense." << std::endl;
848 std::cout << ">> msr2data: Could it be, that your run specific labling is < 4 digits? Please check your msr-Input-File." << std::endl;
849 return false;
850 }
851
852
853 // check if parameters have been sorted correctly from the beginning
854 bool wasSorted(true);
855 for (unsigned int i(0); i < fNumGlobalParam; ++i) {
856 if(!msrParamList->at(i).fIsGlobal) {
857 wasSorted = false;
858 break;
859 }
860 }
861
862 int tempPar;
863 std::vector<int> *tempMap;
864 PMsrLines *tempLines;
865 std::vector<std::string> tempVec;
866 std::string line, tempString;
867
868 if (!wasSorted) {
869 // Sort the parameters: global ones first, then run-specific
870 sort(msrParamList->begin(), msrParamList->end(), compare_parameters);
871
872 // Change the parameter numbers in all blocks according to the new order
873
874 // THEORY block
875 tempLines = fMsrHandler->GetMsrTheory();
876 bool mapExists(false);
877 for (unsigned int i(0); i < tempLines->size(); ++i) {
878 line = (*tempLines)[i].fLine.Data();
879 split( tempVec, line, is_any_of(" \t"), token_compress_on ); // split the theory line at spaces
880 for (unsigned int j(1); j < tempVec.size(); ++j) {
881 try {
882 tempPar = boost::lexical_cast<unsigned int>(tempVec[j]);
883 // go through the whole parameter list and look for the correct parameter - this is stupid, however, I do not know what else to do
884 for (unsigned int k(0); k < msrParamList->size(); ++k) {
885 if (tempPar == msrParamList->at(k).fNo) {
886 if (msrParamList->at(k).fIsGlobal) {
887 tempVec[j] = boost::lexical_cast<std::string>(k + 1);
888 } else {
889 std::cerr << std::endl << ">> msr2data: **WARNING** The parameter " << msrParamList->at(k).fName.Data() \
890 << " is recognized as run specific!";
891 std::cerr << std::endl << ">> msr2data: **WARNING** Still it appears directly (un-mapped) in the template THEORY block.";
892 std::cerr << std::endl << ">> msr2data: **WARNING** The THEORY block entry will be substituted by a mapped parameter.";
893 std::cerr << std::endl << ">> msr2data: **WARNING** In case, this is not what has been intended, please review the new msr-file!";
894 std::cerr << std::endl;
895
896 unsigned int l(0);
897 tempMap = msrRunList->at(0).GetMap();
898 while (l < tempMap->size()) {
899 if ((*tempMap)[l] == tempPar) {
900 mapExists = true;
901 for (unsigned int m(1); m < fNumTempRunBlocks; ++m) {
902 if (msrRunList->at(m).GetMap()->at(l) != tempPar) {
903 mapExists = false;
904 break;
905 }
906 }
907 }
908 if (mapExists) {
909 break;
910 } else {
911 ++l;
912 }
913 }
914
915 if (mapExists) {
916 tempVec[j] = "map";
917 tempVec[j].append(boost::lexical_cast<std::string>(l + 1));
918 mapExists = false;
919 } else { // look for the first not used map entry
920 for (l = 0; l < tempMap->size(); ++l) {
921 if (!(*tempMap)[l]) {
922 break;
923 }
924 }
925 for (unsigned int m(0); m < fNumTempRunBlocks; ++m) {
926 msrRunList->at(m).SetMap(tempPar, l);
927 }
928 tempVec[j] = "map";
929 tempVec[j].append(boost::lexical_cast<std::string>(l + 1));
930 }
931 }
932 break;
933 }
934 }
935 }
936 catch(boost::bad_lexical_cast &) {
937 // in case the cast does not work: do nothing - this means the entry is not a simple parameter
938 }
939 }
940 // replace the old theory line by the new one
941 (*tempLines)[i].fLine.Clear();
942 for (unsigned int j(0); j < tempVec.size(); ++j) {
943 (*tempLines)[i].fLine += TString(tempVec[j]) + TString(" ");
944 }
945 tempVec.clear();
946 }
947
948 // FUNCTIONS block
949 std::string::size_type pos(0);
950 tempLines = fMsrHandler->GetMsrFunctions();
951 for (unsigned int i(0); i < tempLines->size(); ++i) {
952 line = (*tempLines)[i].fLine.Data();
953 split( tempVec, line, is_any_of(" ()+-*/=\t,") ); // split the function line at spaces and some characters that might be juxtaposed to the parameters
954 for (unsigned int j(1); j < tempVec.size(); ++j) {
955 if (!tempVec[j].substr(0,3).compare("par")) {
956 try {
957 tempPar = boost::lexical_cast<unsigned int>(tempVec[j].substr(3));
958 // go through the whole parameter list and look for the correct parameter - this is stupid, however, I do not know what else to do
959 for (unsigned int k(0); k < msrParamList->size(); ++k) {
960 if (tempPar == msrParamList->at(k).fNo) {
961 if (msrParamList->at(k).fIsGlobal) {
962 pos = line.find(tempVec[j], pos);
963 if ( pos != std::string::npos ) {
964 tempString = "par";
965 tempString.append(boost::lexical_cast<std::string>(k + 1));
966 line.replace(pos, tempVec[j].length(), tempString);
967 } else {
968 std::cerr << std::endl << ">> msr2data: **ERROR** A previously identified parameter in the FUNCTIONS block is not found any more!";
969 std::cerr << std::endl << ">> msr2data: **ERROR** This should not happen! Please report a bug!";
970 std::cerr << std::endl;
971 }
972 } else {
973 std::cerr << std::endl << ">> msr2data: **WARNING** The parameter " << msrParamList->at(k).fName.Data() \
974 << " is recognized as run specific!";
975 std::cerr << std::endl << ">> msr2data: **WARNING** Still it appears directly (un-mapped) in the template FUNCTIONS block.";
976 std::cerr << std::endl << ">> msr2data: **WARNING** The FUNCTIONS block entry will be substituted by a mapped parameter.";
977 std::cerr << std::endl << ">> msr2data: **WARNING** In case, this is not what has been intended, please review the new msr-file!";
978 std::cerr << std::endl;
979
980 unsigned int l(0);
981 tempMap = msrRunList->at(0).GetMap();
982 while (l < tempMap->size()) {
983 if ((*tempMap)[l] == tempPar) {
984 mapExists = true;
985 for (unsigned int m(1); m < fNumTempRunBlocks; ++m) {
986 if (msrRunList->at(m).GetMap()->at(l) != tempPar) {
987 mapExists = false;
988 break;
989 }
990 }
991 }
992 if (mapExists) {
993 break;
994 } else {
995 ++l;
996 }
997 }
998
999 if (!mapExists) {
1000 for (l = 0; l < tempMap->size(); ++l) {
1001 if (!(*tempMap)[l]) {
1002 break;
1003 }
1004 }
1005 for (unsigned int m(0); m < fNumTempRunBlocks; ++m) {
1006 msrRunList->at(m).SetMap(tempPar, l);
1007 }
1008 }
1009 pos = line.find(tempVec[j], pos);
1010 if ( pos != std::string::npos ) {
1011 tempString = "map";
1012 tempString.append(boost::lexical_cast<std::string>(l + 1));
1013 line.replace(pos, tempVec[j].length(), tempString);
1014 } else {
1015 std::cerr << std::endl << ">> msr2data: **ERROR** A previously identified parameter in the FUNCTIONS block is not found any more!";
1016 std::cerr << std::endl << ">> msr2data: **ERROR** This should not happen! Please report a bug!";
1017 std::cerr << std::endl;
1018 }
1019 mapExists = false;
1020 }
1021 break;
1022 }
1023 }
1024 }
1025 catch(boost::bad_lexical_cast &) {
1026 std::cerr << std::endl << ">> msr2data: **ERROR** Something is wrong with the parameters used in the FUNCTIONS block!";
1027 std::cerr << std::endl << ">> msr2data: **ERROR** Please report a bug - function parsing should have failed earlier!";
1028 std::cerr << std::endl;
1029 return false;
1030 }
1031 }
1032 ++pos;
1033 }
1034 // replace the old function line by the new one
1035 (*tempLines)[i].fLine = TString(line);
1036 tempVec.clear();
1037 pos = 0;
1038 }
1039
1040 // RUN blocks
1041 // substitute the old parameter numbers by the new ones
1042
1043 unsigned int l(0);
1044
1045 // look in the following order through the RUN-blocks: norm, bkg-fit, alpha, beta, lifetime, maps
1046 for (unsigned int i(0); i < fNumTempRunBlocks; ++i) {
1047 tempPar = msrRunList->at(i).GetNormParamNo();
1048 if (tempPar > 0) {
1049 // go through the whole parameter list and look for the correct parameter - this is stupid, however, I do not know what else to do
1050 for (l = 0; l < msrParamList->size(); ++l) {
1051 if (tempPar == msrParamList->at(l).fNo) {
1052 msrRunList->at(i).SetNormParamNo(l + 1);
1053 break;
1054 }
1055 }
1056 if (l > msrParamList->size()) {
1057 std::cerr << std::endl << ">> msr2data: **ERROR** The norm parameter specified in RUN block " << i + 1 << " does not exist!";
1058 std::cerr << std::endl << ">> msr2data: **ERROR** Please report a bug - file checks should have failed earlier!";
1059 std::cerr << std::endl;
1060 return false;
1061 }
1062 }
1063 tempPar = msrRunList->at(i).GetBkgFitParamNo();
1064 if (tempPar > 0) {
1065 // go through the whole parameter list and look for the correct parameter - this is stupid, however, I do not know what else to do
1066 for (l = 0; l < msrParamList->size(); ++l) {
1067 if (tempPar == msrParamList->at(l).fNo) {
1068 msrRunList->at(i).SetBkgFitParamNo(l + 1);
1069 break;
1070 }
1071 }
1072 if (l > msrParamList->size()) {
1073 std::cerr << std::endl << ">> msr2data: **ERROR** The backgr.fit parameter specified in RUN block " << i + 1 << " does not exist!";
1074 std::cerr << std::endl << ">> msr2data: **ERROR** Please report a bug - file checks should have failed earlier!";
1075 std::cerr << std::endl;
1076 return false;
1077 }
1078 }
1079 tempPar = msrRunList->at(i).GetAlphaParamNo();
1080 if (tempPar > 0) {
1081 // go through the whole parameter list and look for the correct parameter - this is stupid, however, I do not know what else to do
1082 for (l = 0; l < msrParamList->size(); ++l) {
1083 if (tempPar == msrParamList->at(l).fNo) {
1084 msrRunList->at(i).SetAlphaParamNo(l + 1);
1085 break;
1086 }
1087 }
1088 if (l > msrParamList->size()) {
1089 std::cerr << std::endl << ">> msr2data: **ERROR** The alpha parameter specified in RUN block " << i + 1 << " does not exist!";
1090 std::cerr << std::endl << ">> msr2data: **ERROR** Please report a bug - file checks should have failed earlier!";
1091 std::cerr << std::endl;
1092 return false;
1093 }
1094 }
1095 tempPar = msrRunList->at(i).GetBetaParamNo();
1096 if (tempPar > 0) {
1097 // go through the whole parameter list and look for the correct parameter - this is stupid, however, I do not know what else to do
1098 for (l = 0; l < msrParamList->size(); ++l) {
1099 if (tempPar == msrParamList->at(l).fNo) {
1100 msrRunList->at(i).SetBetaParamNo(l + 1);
1101 break;
1102 }
1103 }
1104 if (l > msrParamList->size()) {
1105 std::cerr << std::endl << ">> msr2data: **ERROR** The beta parameter specified in RUN block " << i + 1 << " does not exist!";
1106 std::cerr << std::endl << ">> msr2data: **ERROR** Please report a bug - file checks should have failed earlier!";
1107 std::cerr << std::endl;
1108 return false;
1109 }
1110 }
1111 tempPar = msrRunList->at(i).GetLifetimeParamNo();
1112 if (tempPar > 0) {
1113 // go through the whole parameter list and look for the correct parameter - this is stupid, however, I do not know what else to do
1114 for (l = 0; l < msrParamList->size(); ++l) {
1115 if (tempPar == msrParamList->at(l).fNo) {
1116 msrRunList->at(i).SetLifetimeParamNo(l + 1);
1117 break;
1118 }
1119 }
1120 if (l > msrParamList->size()) {
1121 std::cerr << std::endl << ">> msr2data: **ERROR** The lifetime parameter specified in RUN block " << i + 1 << " does not exist!";
1122 std::cerr << std::endl << ">> msr2data: **ERROR** Please report a bug - file checks should have failed earlier!";
1123 std::cerr << std::endl;
1124 return false;
1125 }
1126 }
1127 tempMap = msrRunList->at(i).GetMap();
1128 for (unsigned int j(0); j < tempMap->size(); ++j) {
1129 tempPar = (*tempMap)[j];
1130 if (tempPar > 0) {
1131 // go through the whole parameter list and look for the correct parameter - this is stupid, however, I do not know what else to do
1132 for (l = 0; l < msrParamList->size(); ++l) {
1133 if (tempPar == msrParamList->at(l).fNo) {
1134 msrRunList->at(i).SetMap(l + 1, j);
1135 break;
1136 }
1137 }
1138 }
1139 }
1140 tempMap = nullptr;
1141 }
1142
1143 // FOURIER block - in case a parameter is used for the phase
1144 if (fMsrHandler->GetMsrFourierList()->fPhaseParamNo.size() > 0) {
1145 // go through the whole parameter list ...
1146 for (unsigned int k(0); k < msrParamList->size(); ++k) {
1147 if (tempPar == msrParamList->at(k).fNo) {
1148 fMsrHandler->GetMsrFourierList()->fPhaseParamNo.push_back(k + 1);
1149 break;
1150 }
1151 }
1152 }
1153
1154 // PLOT block - in case a parameter is used for the RRFphase
1155 for (unsigned int i(0); i < fMsrHandler->GetMsrPlotList()->size(); ++i) {
1156 tempPar = fMsrHandler->GetMsrPlotList()->at(i).fRRFPhaseParamNo;
1157 if (tempPar > 0) {
1158 // go through the whole parameter list ...
1159 for (unsigned int k(0); k < msrParamList->size(); ++k) {
1160 if (tempPar == msrParamList->at(k).fNo) {
1161 fMsrHandler->GetMsrPlotList()->at(i).fRRFPhaseParamNo = k + 1;
1162 break;
1163 }
1164 }
1165 }
1166 }
1167
1168 // finally fix the PARAMETER block after the reorganization
1169 for (l = 0; l < msrParamList->size(); ++l) {
1170 msrParamList->at(l).fNo = l + 1;
1171 }
1172 } else { // if the parameters were sorted just check the THEORY and FUNCTIONS blocks for run specific parameters
1173 bool lineChanged(false), mapExists(false);
1174 // THEORY block
1175 tempLines = fMsrHandler->GetMsrTheory();
1176 for (unsigned int i(0); i < tempLines->size(); ++i) {
1177 line = (*tempLines)[i].fLine.Data();
1178 split( tempVec, line, is_any_of(" \t"), token_compress_on ); // split the theory line at spaces
1179
1180 for (unsigned int j(1); j < tempVec.size(); ++j) {
1181 try {
1182 tempPar = boost::lexical_cast<unsigned int>(tempVec[j]);
1183 if (!msrParamList->at(tempPar - 1).fIsGlobal) {
1184 std::cerr << std::endl << ">> msr2data: **WARNING** The parameter " << msrParamList->at(tempPar - 1).fName.Data() \
1185 << " is recognized as run specific!";
1186 std::cerr << std::endl << ">> msr2data: **WARNING** Still it appears directly (un-mapped) in the template THEORY block.";
1187 std::cerr << std::endl << ">> msr2data: **WARNING** The THEORY block entry will be substituted by a mapped parameter.";
1188 std::cerr << std::endl << ">> msr2data: **WARNING** In case, this is not what has been intended, please review the new msr-file!";
1189 std::cerr << std::endl;
1190
1191 unsigned int l(0);
1192 tempMap = msrRunList->at(0).GetMap();
1193 while (l < tempMap->size()) {
1194 if ((*tempMap)[l] == tempPar) {
1195 mapExists = true;
1196 for (unsigned int m(1); m < fNumTempRunBlocks; ++m) {
1197 if (msrRunList->at(m).GetMap()->at(l) != tempPar) {
1198 mapExists = false;
1199 break;
1200 }
1201 }
1202 }
1203 if (mapExists) {
1204 break;
1205 } else {
1206 ++l;
1207 }
1208 }
1209
1210 if (mapExists) {
1211 tempVec[j] = "map";
1212 tempVec[j].append(boost::lexical_cast<std::string>(l + 1));
1213 lineChanged = true;
1214 mapExists = false;
1215 } else {
1216 for (l = 0; l < tempMap->size(); ++l) {
1217 if (!(*tempMap)[l]) {
1218 break;
1219 }
1220 }
1221 for (unsigned int m(0); m < fNumTempRunBlocks; ++m) {
1222 msrRunList->at(m).SetMap(tempPar, l);
1223 }
1224 tempVec[j] = "map";
1225 tempVec[j].append(boost::lexical_cast<std::string>(l + 1));
1226 lineChanged = true;
1227 }
1228 }
1229 }
1230 catch(boost::bad_lexical_cast &) {
1231 // in case the cast does not work: do nothing - this means the entry is not a simple parameter
1232 }
1233 }
1234 // replace the old theory line by the new one
1235 if (lineChanged) {
1236 (*tempLines)[i].fLine.Clear();
1237 for (unsigned int j(0); j < tempVec.size(); ++j) {
1238 (*tempLines)[i].fLine += TString(tempVec[j]) + TString(" ");
1239 }
1240 lineChanged = false;
1241 }
1242 tempVec.clear();
1243 }
1244
1245 // FUNCTIONS block
1246 tempLines = fMsrHandler->GetMsrFunctions();
1247 std::string::size_type pos(0);
1248 for (unsigned int i(0); i < tempLines->size(); ++i) {
1249 line = (*tempLines)[i].fLine.Data();
1250 split( tempVec, line, is_any_of(" ()+-*/=\t,") ); // split the function line at spaces and some characters that might be juxtaposed to the parameters
1251 for (unsigned int j(1); j < tempVec.size(); ++j) {
1252 if (!tempVec[j].substr(0,3).compare("par")) {
1253 try {
1254 tempPar = boost::lexical_cast<unsigned int>(tempVec[j].substr(3));
1255
1256 if (!msrParamList->at(tempPar - 1).fIsGlobal) {
1257
1258 std::cerr << std::endl << ">> msr2data: **WARNING** The parameter " << msrParamList->at(tempPar - 1).fName.Data() \
1259 << " is recognized as run specific!";
1260 std::cerr << std::endl << ">> msr2data: **WARNING** Still it appears directly (un-mapped) in the template FUNCTIONS block.";
1261 std::cerr << std::endl << ">> msr2data: **WARNING** The FUNCTIONS block entry will be substituted by a mapped parameter.";
1262 std::cerr << std::endl << ">> msr2data: **WARNING** In case, this is not what has been intended, please review the new msr-file!";
1263 std::cerr << std::endl;
1264
1265 unsigned int l(0);
1266 tempMap = msrRunList->at(0).GetMap();
1267 while (l < tempMap->size()) {
1268 if ((*tempMap)[l] == tempPar) {
1269 mapExists = true;
1270 for (unsigned int m(1); m < fNumTempRunBlocks; ++m) {
1271 if (msrRunList->at(m).GetMap()->at(l) != tempPar) {
1272 mapExists = false;
1273 break;
1274 }
1275 }
1276 }
1277 if (mapExists) {
1278 break;
1279 } else {
1280 ++l;
1281 }
1282 }
1283
1284 if (!mapExists) {
1285 for (l = 0; l < tempMap->size(); ++l) {
1286 if (!(*tempMap)[l]) {
1287 break;
1288 }
1289 }
1290 for (unsigned int m(0); m < fNumTempRunBlocks; ++m) {
1291 msrRunList->at(m).SetMap(tempPar, l);
1292 }
1293 }
1294 pos = line.find(tempVec[j], pos);
1295 if ( pos != std::string::npos ) {
1296 tempString = "map";
1297 tempString.append(boost::lexical_cast<std::string>(l + 1));
1298 line.replace(pos, tempVec[j].length(), tempString);
1299 } else {
1300 std::cerr << std::endl << ">> msr2data: **ERROR** A previously identified parameter in the FUNCTIONS block is not found any more!";
1301 std::cerr << std::endl << ">> msr2data: **ERROR** This should not happen! Please report a bug!";
1302 std::cerr << std::endl;
1303 }
1304 mapExists = false;
1305 lineChanged = true;
1306 }
1307 }
1308
1309 catch(boost::bad_lexical_cast &) {
1310 std::cerr << std::endl << ">> msr2data: **ERROR** Something is wrong with the parameters used in the FUNCTIONS block!";
1311 std::cerr << std::endl << ">> msr2data: **ERROR** Please report a bug - function parsing should have failed earlier!";
1312 std::cerr << std::endl;
1313 return false;
1314 }
1315 }
1316 ++pos;
1317 }
1318 // replace the old function line by the new one
1319 if (lineChanged) {
1320 (*tempLines)[i].fLine = TString(line);
1321 lineChanged = false;
1322 }
1323 tempVec.clear();
1324 pos = 0;
1325 }
1326 }
1327
1328 // go once more trough the template RUN blocks and look for common parameters
1329 // look in the following order through the RUN-blocks: norm, bkg-fit, alpha, beta, lifetime, maps
1330 for (unsigned int i(0); i < fNumTempRunBlocks; ++i) {
1331 tempPar = msrRunList->at(i).GetNormParamNo();
1332 if ((tempPar > 0) && (tempPar < MSR_PARAM_FUN_OFFSET)) { // if the norm-parameter is given by a function we do not have to care about it here!
1333 if (msrParamList->at(tempPar-1).fIsGlobal) { // norm of RUN block i is global
1334 msrRunList->at(i).SetParGlobal(norm, 1);
1335 } else {
1336 msrRunList->at(i).SetParGlobal(norm, 0);
1337 }
1338 }
1339 tempPar = msrRunList->at(i).GetBkgFitParamNo();
1340 if (tempPar > 0) {
1341 if (msrParamList->at(tempPar-1).fIsGlobal) { // bkg-fit of RUN block i is global
1342 msrRunList->at(i).SetParGlobal(bkgfit, 1);
1343 } else {
1344 msrRunList->at(i).SetParGlobal(bkgfit, 0);
1345 }
1346 }
1347 tempPar = msrRunList->at(i).GetAlphaParamNo();
1348 if (tempPar > 0) {
1349 if (msrParamList->at(tempPar-1).fIsGlobal) { // alpha of RUN block i is global
1350 msrRunList->at(i).SetParGlobal(alpha, 1);
1351 } else {
1352 msrRunList->at(i).SetParGlobal(alpha, 0);
1353 }
1354 }
1355 tempPar = msrRunList->at(i).GetBetaParamNo();
1356 if (tempPar > 0) {
1357 if (msrParamList->at(tempPar-1).fIsGlobal) { // beta of RUN block i is global
1358 msrRunList->at(i).SetParGlobal(beta, 1);
1359 } else {
1360 msrRunList->at(i).SetParGlobal(beta, 0);
1361 }
1362 }
1363 tempPar = msrRunList->at(i).GetLifetimeParamNo();
1364 if (tempPar > 0) {
1365 if (msrParamList->at(tempPar-1).fIsGlobal) { // lifetime of RUN block i is global
1366 msrRunList->at(i).SetParGlobal(lifetime, 1);
1367 } else {
1368 msrRunList->at(i).SetParGlobal(lifetime, 0);
1369 }
1370 }
1371 tempMap = msrRunList->at(i).GetMap();
1372 for (unsigned int j(0); j < tempMap->size(); ++j) {
1373 tempPar = (*tempMap)[j];
1374 if (tempPar > 0) {
1375 if (msrParamList->at(tempPar-1).fIsGlobal) { // map j of RUN block i is global
1376 msrRunList->at(i).SetMapGlobal(j, 1);
1377 } else {
1378 msrRunList->at(i).SetMapGlobal(j, 0);
1379 }
1380 }
1381 }
1382 tempMap = nullptr;
1383 }
1384
1385 // if the global+ option is specified, generate new single run msr-files and fit them
1386 // to obtain better starting parameter values for the global file
1387
1388 if (globalPlus) {
1389 // for the first file (or if the !-option is given), prepare a sorted input from the internal data-structure
1390 // if chain-fitting is used, the successive files are copied from the first
1391 unsigned int oldTempRun(0);
1392 bool firstrun(true);
1393 bool success(true);
1394
1395 while(fRunVectorIter != fRunVector.end()) {
1396 if (firstrun || (globalPlus == 1))
1397 success = PrepareNewSortedInputFile(tempRun);
1398 else
1399 success = PrepareNewInputFile(oldTempRun, true);
1400 if (firstrun)
1401 firstrun = false;
1402 oldTempRun = *fRunVectorIter;
1403
1404 if (!success) {
1405 std::cout << std::endl << ">> msr2data: **ERROR** Input file generation has not been successful! Quitting..." << std::endl;
1406 return false;
1407 }
1408
1409 // and do the fitting
1410 // check if MUSRFITPATH is set, if not issue a warning
1411 std::string path("");
1412 bool pathSet(false);
1413 char *pathPtr(getenv("MUSRFITPATH"));
1414 if (pathPtr) {
1415 path = boost::lexical_cast<std::string>(pathPtr);
1416 if (!path.empty()) {
1417 pathSet = true;
1418 path.append("/");
1419 }
1420 }
1421 if (!pathSet) {
1422 std::cerr << std::endl << ">> msr2data: **WARNING** The MUSRFITPATH environment variable is not set!";
1423 std::cerr << std::endl << ">> msr2data: **WARNING** Please set it or at least ensure that musrfit can be found on the PATH!" << std::endl;
1424 }
1425 std::ostringstream oss;
1426 oss << path << "musrfit" << " " << *fRunVectorIter << "-OneRunFit" << fFileExtension << ".msr";
1427 std::cout << std::endl << ">> msr2data: **INFO** Calling " << oss.str() << std::endl;
1428 if (system(oss.str().c_str()) == -1) {
1429 std::cerr << std::endl << "**ERROR** system call: " << oss.str().c_str() << " failed." << std::endl;
1430 }
1431
1433 }
1434 // set back the iterator to the first run
1435 fRunVectorIter = fRunVector.begin();
1436
1437 std::cout << std::endl << ">> msr2data: **INFO** Continuing with the generation of the global input msr file " << msrOutFile << std::endl;
1438 }
1439
1440
1441 // now go through the specified runs and add run-specific parameters and RUN blocks
1442
1443 PMsrHandler *singleRunMsrFile;
1444 singleRunMsrFile = nullptr;
1445
1446 std::map<UInt_t, TString> commentsP, commentsR;
1447 TString tempTstr;
1448 std::ostringstream newRunNumber;
1449 newRunNumber.fill('0');
1450 newRunNumber.setf(std::ios::internal, std::ios::adjustfield);
1451 newRunNumber.width(fRunNumberDigits);
1452 newRunNumber << *fRunVectorIter;
1453
1454 //std::cout << "Number of run specific parameters: " << fNumSpecParam << std::endl;
1455
1456 if (newRunNumber.str().compare(tempRunNumber.str())) { // first run number does not match the template run number
1457 // in global+ mode, read in the single run msr-file of the corresponding run
1458 if (globalPlus) {
1459 singleRunMsrFile = GetSingleRunMsrFile();
1460 if (singleRunMsrFile == nullptr)
1461 return false;
1462 }
1463
1464 // substitute the template run-numbers in the parameter names
1465 for (unsigned int l(fNumGlobalParam); l < msrParamList->size(); ++l) {
1466 tempParamName = msrParamList->at(l).fName.Data();
1467 std::string::size_type loc = tempParamName.rfind(tempRunNumber.str());
1468 if ( loc != std::string::npos ) {
1469 tempParamName.replace(loc, fRunNumberDigits, newRunNumber.str());
1470 msrParamList->at(l).fName = tempParamName;
1471 if (globalPlus && singleRunMsrFile) {
1472 fMsrHandler->SetMsrParamValue(l, singleRunMsrFile->GetMsrParamList()->at(l).fValue);
1473 fMsrHandler->SetMsrParamStep(l, singleRunMsrFile->GetMsrParamList()->at(l).fStep);
1474 }
1475 } else {
1476 std::cerr << std::endl << ">> msr2data: **ERROR** The indices of the run specific parameters do not match the template run number!";
1477 std::cerr << std::endl << ">> msr2data: **ERROR** This should not happen! Please report a bug!";
1478 std::cerr << std::endl;
1479 }
1480 }
1481 if (singleRunMsrFile) {
1482 delete singleRunMsrFile;
1483 singleRunMsrFile = nullptr;
1484 }
1485
1486 // substitute the template run-numbers in the RUN names
1487 for (unsigned int i(0); i < fNumTempRunBlocks; ++i) {
1488 tempRunName = msrRunList->at(i).GetRunName()->Data();
1489 std::string::size_type loc = tempRunName.rfind(tempRunNumber.str());
1490 if ( loc != std::string::npos ) {
1491 tempRunName.replace(loc, fRunNumberDigits, newRunNumber.str());
1492 tempTstr = TString(tempRunName);
1493 msrRunList->at(i).SetRunName(tempTstr, 0);
1494 } else {
1495 std::cerr << std::endl << ">> msr2data: **ERROR** A template run file number does not match the \"file index\"";
1496 std::cerr << std::endl << ">> msr2data: **ERROR** Please check the template file!";
1497 std::cerr << std::endl;
1498 return false;
1499 }
1500 }
1501 }
1502
1503 std::ostringstream tempStrStr;
1504
1505 // comments for the output-file
1506 if (fNumGlobalParam) {
1507 commentsP[1] = TString("Common parameters for all runs");
1508 }
1509 if (fNumSpecParam) {
1510 tempStrStr.str("");
1511 tempStrStr << "Specific parameters for run " << *fRunVectorIter;
1512 tempTstr = tempStrStr.str();
1513 commentsP[fNumGlobalParam + 1] = tempTstr;
1514 }
1515 if (fNumTempRunBlocks) {
1516 tempStrStr.str("");
1517 tempStrStr << "RUN blocks for run " << *fRunVectorIter;
1518 tempTstr = tempStrStr.str();
1519 commentsR[1] = tempTstr;
1520 }
1521
1523
1524 UInt_t runcounter(0);
1525 std::map<TString, Int_t> *runParGlobal(nullptr);
1526 std::map<TString, Int_t>::iterator iter;
1527 PIntVector *runMapGlobal(nullptr);
1528
1529 while (fRunVectorIter != fRunVector.end()) {
1530 tempRunNumber.str(newRunNumber.str());
1531 newRunNumber.str("");
1532 newRunNumber.clear();
1533 newRunNumber.fill('0');
1534 newRunNumber.setf(std::ios::internal, std::ios::adjustfield);
1535 newRunNumber.width(fRunNumberDigits);
1536 newRunNumber << *fRunVectorIter;
1537
1538 // in global+ mode, read in the single run msr-file
1539 if (globalPlus) {
1540 singleRunMsrFile = GetSingleRunMsrFile();
1541 if (singleRunMsrFile == nullptr)
1542 return false;
1543 }
1544
1545 // add parameters for each run
1546 for (unsigned int l(0); l < fNumSpecParam; ++l) {
1547 msrParamList->push_back(msrParamList->at(fNumGlobalParam + runcounter*fNumSpecParam + l));
1548 tempParamName = msrParamList->back().fName.Data();
1549 std::string::size_type loc = tempParamName.rfind(tempRunNumber.str());
1550 if ( loc != std::string::npos ) {
1551 tempParamName.replace(loc, fRunNumberDigits, newRunNumber.str());
1552 msrParamList->back().fName = tempParamName;
1553 msrParamList->back().fNo += fNumSpecParam;
1554 if (globalPlus && singleRunMsrFile) {
1555 fMsrHandler->SetMsrParamValue(msrParamList->size() - 1, singleRunMsrFile->GetMsrParamList()->at(fNumGlobalParam + l).fValue);
1556 fMsrHandler->SetMsrParamStep(msrParamList->size() - 1, singleRunMsrFile->GetMsrParamList()->at(fNumGlobalParam + l).fStep);
1557 }
1558 } else {
1559 std::cerr << std::endl << ">> msr2data: **ERROR** Something went wrong when appending new parameters!";
1560 std::cerr << std::endl << ">> msr2data: **ERROR** This should not happen! Please report a bug!";
1561 std::cerr << std::endl;
1562 }
1563 }
1564 if (singleRunMsrFile) {
1565 delete singleRunMsrFile;
1566 singleRunMsrFile = nullptr;
1567 }
1568
1569 // add RUN blocks for each run
1570 for (unsigned int i(0); i < fNumTempRunBlocks; ++i) {
1571 msrRunList->push_back(msrRunList->at(runcounter*fNumTempRunBlocks + i));
1572 tempRunName = msrRunList->back().GetRunName()->Data();
1573 std::string::size_type loc = tempRunName.rfind(tempRunNumber.str());
1574 if ( loc != std::string::npos ) {
1575 tempRunName.replace(loc, fRunNumberDigits, newRunNumber.str());
1576 tempTstr = TString(tempRunName);
1577 msrRunList->back().SetRunName(tempTstr, 0);
1578 } else {
1579 std::cerr << std::endl << ">> msr2data: **ERROR** Something went wrong when appending new RUN blocks!";
1580 std::cerr << std::endl << ">> msr2data: **ERROR** This should not happen! Please report a bug!";
1581 std::cerr << std::endl;
1582 return false;
1583 }
1584 // change run specific parameter numbers in the new RUN block
1585 runParGlobal = msrRunList->back().GetParGlobal();
1586 iter = runParGlobal->find(norm);
1587 if (iter != runParGlobal->end()) {
1588 if (!iter->second)
1589 msrRunList->back().SetNormParamNo(msrRunList->back().GetNormParamNo() + fNumSpecParam);
1590 }
1591 iter = runParGlobal->find(bkgfit);
1592 if (iter != runParGlobal->end()) {
1593 if (!iter->second)
1594 msrRunList->back().SetBkgFitParamNo(msrRunList->back().GetBkgFitParamNo() + fNumSpecParam);
1595 }
1596 iter = runParGlobal->find(alpha);
1597 if (iter != runParGlobal->end()) {
1598 if (!iter->second)
1599 msrRunList->back().SetAlphaParamNo(msrRunList->back().GetAlphaParamNo() + fNumSpecParam);
1600 }
1601 iter = runParGlobal->find(beta);
1602 if (iter != runParGlobal->end()) {
1603 if (!iter->second)
1604 msrRunList->back().SetBetaParamNo(msrRunList->back().GetBetaParamNo() + fNumSpecParam);
1605 }
1606 iter = runParGlobal->find(lifetime);
1607 if (iter != runParGlobal->end()) {
1608 if (!iter->second)
1609 msrRunList->back().SetLifetimeParamNo(msrRunList->back().GetLifetimeParamNo() + fNumSpecParam);
1610 }
1611 runMapGlobal = msrRunList->back().GetMapGlobal();
1612 for (unsigned int l(0); l < runMapGlobal->size(); ++l) {
1613 if (!(*runMapGlobal)[l])
1614 msrRunList->back().SetMap(msrRunList->back().GetMap()->at(l) + fNumSpecParam, l);
1615 }
1616 }
1617
1618 ++runcounter;
1619
1620 // comments for the output-file
1621 if (fNumSpecParam) {
1622 tempStrStr.str("");
1623 tempStrStr << "Specific parameters for run " << *fRunVectorIter;
1624 tempTstr = tempStrStr.str();
1625 commentsP[fNumGlobalParam + runcounter*fNumSpecParam + 1] = tempTstr;
1626 }
1627 if (fNumTempRunBlocks) {
1628 tempStrStr.str("");
1629 tempStrStr << "RUN blocks for run " << *fRunVectorIter;
1630 tempTstr = tempStrStr.str();
1631 commentsR[runcounter*fNumTempRunBlocks + 1] = tempTstr;
1632 }
1633
1635 }
1636
1637 // set the convergence flag to false because no fit has been performed using the newly generated file
1638 fMsrHandler->GetMsrStatistic()->fValid = false;
1639
1640 // write the global msr-file
1641 status = fMsrHandler->WriteMsrFile(msrOutFile.c_str(), &commentsP, nullptr, nullptr, &commentsR);
1642
1643 if (status != PMUSR_SUCCESS) {
1644 std::cerr << std::endl << ">> msr2data: **ERROR** Writing the new msr-file has not been successful!";
1645 std::cerr << std::endl;
1646 return false;
1647 }
1648
1649 // set back the run-iterator to the start
1650 fRunVectorIter = fRunVector.begin();
1651
1652 msrParamList = nullptr;
1653 msrRunList = nullptr;
1654
1655 return true;
1656}
1657
1658//-------------------------------------------------------------
1669bool PMsr2Data::PrepareNewSortedInputFile(unsigned int tempRun) const
1670{
1671
1672 PMsrParamList *msrParamList(fMsrHandler->GetMsrParamList());
1673 PMsrRunList *msrRunList(fMsrHandler->GetMsrRunList());
1674
1675 // make a copy of the msr-file-data to be able to restore it after the operations (parameter name and run number changes)
1676 PMsrParamList paramListCopy(*msrParamList);
1677 PMsrRunList runListCopy(*msrRunList);
1678 TString titleCopy(*(fMsrHandler->GetMsrTitle()));
1679
1680 std::ostringstream tempRunNumber;
1681 tempRunNumber.fill('0');
1682 tempRunNumber.setf(std::ios::internal, std::ios::adjustfield);
1683 tempRunNumber.width(fRunNumberDigits);
1684 tempRunNumber << tempRun;
1685
1686 std::ostringstream newRunNumber;
1687 newRunNumber.fill('0');
1688 newRunNumber.setf(std::ios::internal, std::ios::adjustfield);
1689 newRunNumber.width(fRunNumberDigits);
1690 newRunNumber << *fRunVectorIter;
1691
1692 std::string tempParamName, tempRunName;
1693 TString tempTstr;
1694
1695 std::ostringstream msrOutFile;
1696 msrOutFile << *fRunVectorIter << "-OneRunFit" << fFileExtension << ".msr";
1697 std::cout << std::endl << ">> msr2data: **INFO** Generating new input msr file " << msrOutFile.str() << std::endl;
1698
1699 tempTstr = TString(newRunNumber.str());
1700 fMsrHandler->SetMsrTitle(tempTstr);
1701
1702 // remove the template run-numbers in the parameter names
1703 for (unsigned int l(fNumGlobalParam); l < msrParamList->size(); ++l) {
1704 tempParamName = msrParamList->at(l).fName.Data();
1705 std::string::size_type loc = tempParamName.rfind(tempRunNumber.str());
1706 if ( loc != std::string::npos ) {
1707 tempParamName.erase(loc);
1708 msrParamList->at(l).fName = tempParamName;
1709 } else {
1710 std::cerr << std::endl << ">> msr2data: **ERROR** The indices of the run specific parameters do not match the template run number!";
1711 std::cerr << std::endl << ">> msr2data: **ERROR** This should not happen! Please report a bug!";
1712 std::cerr << std::endl;
1713 }
1714 }
1715
1716 if (newRunNumber.str().compare(tempRunNumber.str())) { // first run number does not match the template run number
1717 // substitute the template run-numbers in the RUN names
1718 for (unsigned int i(0); i < fNumTempRunBlocks; ++i) {
1719 tempRunName = msrRunList->at(i).GetRunName()->Data();
1720 std::string::size_type loc = tempRunName.rfind(tempRunNumber.str());
1721 if ( loc != std::string::npos ) {
1722 tempRunName.replace(loc, fRunNumberDigits, newRunNumber.str());
1723 tempTstr = TString(tempRunName);
1724 msrRunList->at(i).SetRunName(tempTstr, 0);
1725 } else {
1726 std::cerr << std::endl << ">> msr2data: **ERROR** A template run file number does not match the \"file index\"";
1727 std::cerr << std::endl << ">> msr2data: **ERROR** Please check the template file!";
1728 std::cerr << std::endl;
1729 return false;
1730 }
1731 }
1732 }
1733
1734 // set the convergence flag to false because no fit has been performed using the newly generated file
1735 fMsrHandler->GetMsrStatistic()->fValid = false;
1736
1737 // write the msr-file
1738 int status = fMsrHandler->WriteMsrFile(msrOutFile.str().c_str());
1739
1740 // restore original msr-file-data
1741 *msrParamList = paramListCopy;
1742 *msrRunList = runListCopy;
1743 fMsrHandler->SetMsrTitle(titleCopy);
1744
1745 paramListCopy.clear();
1746 runListCopy.clear();
1747 titleCopy.Clear();
1748
1749 if (status != PMUSR_SUCCESS) {
1750 std::cerr << std::endl << ">> msr2data: **ERROR** Writing the new msr file has not been successful!";
1751 std::cerr << std::endl;
1752 return false;
1753 }
1754
1755 return true;
1756
1757}
1758
1759//-------------------------------------------------------------
1775int PMsr2Data::WriteOutput(const std::string &outfile, const std::vector<unsigned int>& paramList, bool db,
1776 unsigned int withHeader, bool global, unsigned int counter) const
1777{
1778 // make sure that the parameter number of the parameter list stays within proper bounds
1779 for (unsigned int i=0; i<paramList.size(); i++) {
1780 if (paramList[i] > fMsrHandler->GetMsrParamList()->size()) {
1781 std::cerr << "msr2data: **ERROR** found parameter " << paramList[i] << " which is out of bound (>" << fMsrHandler->GetMsrParamList()->size() << ")." << std::endl;
1782 return -1;
1783 }
1784 }
1785
1786 if (!to_lower_copy(outfile).compare("none")) {
1788 return PMUSR_SUCCESS;
1789 }
1790
1791 std::ostringstream curRunNumber;
1792 curRunNumber.fill('0');
1793 curRunNumber.setf(std::ios::internal, std::ios::adjustfield);
1794 curRunNumber.width(fRunNumberDigits);
1795 curRunNumber << *fRunVectorIter;
1796
1797 std::string msrTitle(fMsrHandler->GetMsrTitle()->Data());
1798 std::string msrFileName(fMsrHandler->GetFileName().Data());
1799 unsigned int msrNoOfParams(fMsrHandler->GetNoOfParams());
1800 PMsrParamList *msrParamList(fMsrHandler->GetMsrParamList());
1801 PMsrRunList *msrRunList(fMsrHandler->GetMsrRunList());
1802
1803 if (global && (fRunVectorIter == fRunVector.begin())) {
1804 // since the DB-ASCII-output is in principle independent of the original msr-file-generation
1805 // the number of global and run specific parameters as well as the number of RUN blocks per run number have to be determined again
1806 // in case no msr-file has been created before.
1807 std::ostringstream tempRunNumber;
1808 std::string tempName;
1809 if (!fNumGlobalParam && !fNumSpecParam && !fNumTempRunBlocks) { // if not all parameters are zero they have been determined before
1810 tempRunNumber.fill('0');
1811 tempRunNumber.setf(std::ios::internal, std::ios::adjustfield);
1812 tempRunNumber.width(fRunNumberDigits);
1813 tempRunNumber << fRunVector.front();
1814
1815 // search parameter list for run-specific parameters
1816 for (unsigned int i(0); i < msrParamList->size(); ++i) {
1817 tempName = msrParamList->at(i).fName.Data();
1818 std::string::size_type loc = tempName.rfind(tempRunNumber.str());
1819 if ((tempName.length() > fRunNumberDigits) && (loc == tempName.length() - fRunNumberDigits)) {
1820 if (!fNumSpecParam) {
1821 fNumGlobalParam = i;
1822 }
1823 ++fNumSpecParam;
1824 }
1825 }
1826 if (!fNumSpecParam) {
1827 fNumGlobalParam = msrParamList->size();
1828 }
1829
1830 // look through the RUN blocks and count them
1831 for (unsigned int i(0); i < msrRunList->size(); ++i) {
1832 tempName = msrRunList->at(i).GetRunName()->Data();
1833 std::string::size_type loc = tempName.rfind(tempRunNumber.str());
1834 if ( loc != std::string::npos ) {
1836 }
1837 }
1838// std::cerr << std::endl << ">> msr2data: **WARNING** At the moment the full integrity of the global msr file cannot be checked!";
1839// std::cerr << std::endl << ">> msr2data: **WARNING** It should therefore be checked carefully that the run order is consistent";
1840// std::cerr << std::endl << ">> msr2data: **WARNING** in the specified run list, the parameters and the RUN blocks in the msr file!";
1841// std::cerr << std::endl << ">> msr2data: **WARNING** A simple check for the first specified run yields:";
1842// std::cerr << std::endl << ">> msr2data: **WARNING** Number of global parameters: " << fNumGlobalParam;
1843// std::cerr << std::endl << ">> msr2data: **WARNING** Number of run specific parameters: " << fNumSpecParam;
1844// std::cerr << std::endl << ">> msr2data: **WARNING** Number of RUN blocks per run number: " << fNumTempRunBlocks;
1845// std::cerr << std::endl;
1846 }
1847 // Two more simple consistency checks
1848 bool okP(true), okR(true);
1849 if ((msrParamList->size() - fNumGlobalParam)%fNumSpecParam) {
1850 okP = false;
1851 } else if ((msrParamList->size() - fNumGlobalParam)/fNumSpecParam != fRunVector.size()) {
1852 okP = false;
1853 }
1854
1855 if (!okP) {
1856 std::cerr << std::endl << ">> msr2data: **ERROR** The number of parameters or their grouping is not consistent with the specified run list!";
1857 std::cerr << std::endl << ">> msr2data: **ERROR** Please check carefully the integrity of the msr file!";
1858 std::cerr << std::endl << ">> msr2data: **ERROR** No output will be written!";
1859 std::cerr << std::endl;
1860 return -1;
1861 }
1862
1863 if (msrRunList->size()%fNumTempRunBlocks) {
1864 okR = false;
1865 } else if (msrRunList->size()/fNumTempRunBlocks != fRunVector.size()) {
1866 okR = false;
1867 }
1868
1869 if (!okR) {
1870 std::cerr << std::endl << ">> msr2data: **ERROR** The number of RUN blocks or their grouping is not consistent with the specified run list!";
1871 std::cerr << std::endl << ">> msr2data: **ERROR** Please check carefully the integrity of the msr file!";
1872 std::cerr << std::endl << ">> msr2data: **ERROR** No output will be written!";
1873 std::cerr << std::endl;
1874 return -1;
1875 }
1876
1877 // With all the gathered information look once more through the FITPARAMETER and RUN blocks and check them for the correct run numbers
1878 for (unsigned int a(0); a < fRunVector.size(); ++a) {
1879 tempRunNumber.clear();
1880 tempRunNumber.str("");
1881 tempRunNumber.fill('0');
1882 tempRunNumber.setf(std::ios::internal, std::ios::adjustfield);
1883 tempRunNumber.width(fRunNumberDigits);
1884 tempRunNumber << fRunVector[a];
1885
1886 for (unsigned int i(0); i < fNumSpecParam; ++i) {
1887 tempName = msrParamList->at(fNumGlobalParam + a*fNumSpecParam + i).fName.Data();
1888 std::string::size_type loc = tempName.rfind(tempRunNumber.str());
1889 if (!(tempName.length() > fRunNumberDigits) || !(loc == tempName.length() - fRunNumberDigits)) {
1890 okP = false;
1891 break;
1892 }
1893 }
1894 if (!okP) {
1895 break;
1896 }
1897 }
1898
1899 if (!okP) {
1900 std::cerr << std::endl << ">> msr2data: **ERROR** The run specific parameter names are not consistent with the specified run list!";
1901 std::cerr << std::endl << ">> msr2data: **ERROR** Please check carefully the integrity of the msr file and the run list!";
1902 std::cerr << std::endl << ">> msr2data: **ERROR** No output will be written!";
1903 std::cerr << std::endl;
1904 return -1;
1905 }
1906
1907 for (unsigned int a(0); a < fRunVector.size(); ++a) {
1908 tempRunNumber.clear();
1909 tempRunNumber.str("");
1910 tempRunNumber.fill('0');
1911 tempRunNumber.setf(std::ios::internal, std::ios::adjustfield);
1912 tempRunNumber.width(fRunNumberDigits);
1913 tempRunNumber << fRunVector[a];
1914
1915 for (unsigned int i(0); i < fNumTempRunBlocks; ++i) {
1916 tempName = msrRunList->at(a*fNumTempRunBlocks + i).GetRunName()->Data();
1917 std::string::size_type loc = tempName.rfind(tempRunNumber.str());
1918 if (loc == std::string::npos) {
1919 okR = false;
1920 break;
1921 }
1922 }
1923 if (!okR) {
1924 break;
1925 }
1926 }
1927
1928 if (!okR) {
1929 std::cerr << std::endl << ">> msr2data: **ERROR** The run names in the RUN blocks are not consistent with the specified run list!";
1930 std::cerr << std::endl << ">> msr2data: **ERROR** Please check carefully the integrity of the msr file and the run list!";
1931 std::cerr << std::endl << ">> msr2data: **ERROR** No output will be written!";
1932 std::cerr << std::endl;
1933 return -1;
1934 }
1935 }
1936
1937 std::vector<std::string> dataParamNames;
1938 std::vector<std::string> dataParamLabels;
1939 std::vector<double> dataParam, dataParamErr;
1940
1941 if (fDataHandler) {
1942 PRawRunData *rawRunData;
1943 if (global) {
1944 rawRunData = fDataHandler->GetRunData((*msrRunList)[fNumTempRunBlocks*counter].GetRunName()->Data());
1945 } else {
1946 rawRunData = fDataHandler->GetRunData((*msrRunList)[0].GetRunName()->Data());
1947 }
1948
1949 if (rawRunData == nullptr)
1950 return -1;
1951
1952 switch (rawRunData->GetNoOfTemperatures()) {
1953 case 1:
1954 dataParamNames.push_back("dataT");
1955 dataParamLabels.push_back("T (K)");
1956 dataParam.push_back(rawRunData->GetTemperature(0));
1957 dataParamErr.push_back(rawRunData->GetTempError(0));
1958 break;
1959 default:
1960 std::ostringstream oss;
1961 for (unsigned int i(0); i<rawRunData->GetNoOfTemperatures(); i++) {
1962 oss << "dataT" << i;
1963 dataParamNames.push_back(oss.str());
1964 oss.str("");
1965 oss << "T" << i << " (K)";
1966 dataParamLabels.push_back(oss.str());
1967 oss.str("");
1968 dataParam.push_back(rawRunData->GetTemperature(i));
1969 dataParamErr.push_back(rawRunData->GetTempError(i));
1970 }
1971 break;
1972 }
1973
1974 double value;
1975 value = rawRunData->GetField();
1976 if (value != PMUSR_UNDEFINED) {
1977 dataParamNames.push_back("dataB");
1978 dataParamLabels.push_back("B (G)");
1979 dataParam.push_back(value);
1980 }
1981
1982 value = rawRunData->GetEnergy();
1983 if (value != PMUSR_UNDEFINED) {
1984 dataParamNames.push_back("dataE");
1985 dataParamLabels.push_back("Implantation Energy (keV)");
1986 dataParam.push_back(value);
1987 }
1988
1989 value = rawRunData->GetTransport();
1990 if (value != PMUSR_UNDEFINED) {
1991 dataParamNames.push_back("dataTr");
1992 dataParamLabels.push_back("Transport (kV)");
1993 dataParam.push_back(value);
1994 }
1995
1996 PDoubleVector ra(rawRunData->GetRingAnode());
1997 if (ra.size() > 1) {
1998 if ((ra[0] != PMUSR_UNDEFINED) && (ra[1] != PMUSR_UNDEFINED)) {
1999 dataParamNames.push_back("dataRALRAR");
2000 dataParamLabels.push_back("RAL-RAR (kV)");
2001 dataParam.push_back(ra[0]-ra[1]);
2002 }
2003 }
2004 if (ra.size() == 4) {
2005 if ((ra[2] != PMUSR_UNDEFINED) && (ra[3] != PMUSR_UNDEFINED)) {
2006 dataParamNames.push_back("dataRATRAB");
2007 dataParamLabels.push_back("RAT-RAB (kV)");
2008 dataParam.push_back(ra[2]-ra[3]);
2009 }
2010 }
2011
2012 value = rawRunData->GetMuonSpinAngle();
2013 if (value != PMUSR_UNDEFINED) {
2014 dataParamNames.push_back("dataSpinRot");
2015 dataParamLabels.push_back("Spin Rotation Angle (degree)");
2016 dataParam.push_back(value);
2017 }
2018
2019 rawRunData = nullptr;
2020 }
2021
2022// get the independent variable values from the runlist file if needed
2023 PDoubleVector indVarValues;
2024
2025 if (fRunListFile) {
2026 std::string line;
2027 std::vector<std::string> splitVec;
2028 unsigned int runNo;
2029 double val;
2030 std::istringstream strLine;
2031
2032 while (getline(*fRunListFileStream, line)) {
2033 trim(line);
2034 if (line.empty())
2035 continue;
2036 else if (line.at(0) == '#' || !to_lower_copy(line.substr(0,3)).compare("run"))
2037 continue;
2038 else {
2039 split( splitVec, line, is_any_of("#") ); // split the string if any comments appear on the line
2040 strLine.clear();
2041 strLine.str(splitVec[0]);
2042 strLine >> runNo;
2043 if (runNo != *fRunVectorIter) {
2044 std::cerr << std::endl << ">> msr2data: **ERROR** The run number in the runlist file does not match the one which should be processed...";
2045 std::cerr << std::endl << ">> msr2data: **ERROR** Something is very strange... Please report this bug!";
2046 std::cerr << std::endl;
2047 fRunVectorIter = fRunVector.end();
2048 return -1;
2049 }
2050 while (strLine >> val) {
2051 indVarValues.push_back(val);
2052 }
2053 if (indVarValues.size() != fIndVar.size()) {
2054 std::cerr << std::endl << ">> msr2data: **ERROR** The number of data entries in the runlist file for the run number " << runNo;
2055 std::cerr << std::endl << ">> msr2data: **ERROR** does not match the number of labels given in the RUN-line! Please check the file!";
2056 std::cerr << std::endl;
2057 fRunVectorIter = fRunVector.end();
2058 return -1;
2059 }
2060 break;
2061 }
2062 }
2063 }
2064
2065// The RUNLIST file stream and the run vector iterator might get out of synchronization, if the following check is placed before the above block...
2066 PMsrStatisticStructure *msrStatistic(fMsrHandler->GetMsrStatistic());
2067 if (!msrStatistic->fValid) { // in the GLOBAL mode this has already been checked before -> check should be negative anyway
2068 std::cerr << std::endl << ">> msr2data: **WARNING** The fit of run " << *fRunVectorIter << " has not converged!";
2069 std::cerr << std::endl << ">> msr2data: **WARNING** Its parameter data have not been appended to the output file " << outfile;
2070 std::cerr << std::endl;
2072
2073// clean up some vectors
2074 dataParamNames.clear();
2075 dataParamLabels.clear();
2076 dataParam.clear();
2077 dataParamErr.clear();
2078 indVarValues.clear();
2079
2080 return -2;
2081 }
2082
2083// open the DB or dat file and write the data
2084 std::fstream outFile;
2085 outFile.open(outfile.c_str(), std::ios::in | std::ios::out | std::ios::ate);
2086 if (outFile.is_open()) {
2087 if (((withHeader == 0) || (withHeader == 1)) && !fHeaderWritten) {
2088 // Header should (not) be written explicitly, start writing at the end of the file
2089 // This also ensures the backward compatibility to the old "noheader" option
2090 outFile.seekp(0, std::ios::end);
2091 } else {
2092 if (!fHeaderWritten) { // File already present: assume header is present already and find the last written block
2093 fHeaderWritten = true;
2094 }
2095 int size(outFile.tellg());
2096 std::string s;
2097
2098 for (int i(1); i<=size; ++i) { // find the last non-empty line
2099 outFile.seekg(-i, std::ios::end);
2100 getline(outFile, s);
2101 trim(s); // remove whitespace
2102 if (s.empty()) { // trim cuts off also characters like '\n', therefore this should work also with M$-DOS linebreaks
2103 if (i == size) {
2104 outFile.seekp(0);
2105 fHeaderWritten = false; // if the file contained only empty lines, default to writing the header
2106 break;
2107 } else {
2108 continue;
2109 }
2110 } else {
2111 outFile.seekp(0, std::ios::cur);
2112 break;
2113 }
2114 }
2115 }
2116 } else {
2117 outFile.open(outfile.c_str(), std::ios::out);
2118 if (!outFile.is_open()) {
2119 std::cerr << std::endl << ">> msr2data: **ERROR** The output file " << outfile << " cannot be opened! Please check!";
2120 std::cerr << std::endl;
2121 fRunVectorIter = fRunVector.end();
2122 return -1;
2123 }
2124 }
2125
2126 if (db) {
2127
2128 if (withHeader && !fHeaderWritten) {
2129 std::cout << std::endl << ">> msr2data: **INFO** Write a new DB file header to " << outfile << std::endl;
2130
2131 outFile << "TITLE" << std::endl;
2132 outFile << ">>>Put your title here<<<" << std::endl << std::endl;
2133 outFile << "Abstract" << std::endl;
2134 outFile << ">>>Put your abstract here<<<" << std::endl << std::endl;
2135 outFile << "LABELS" << std::endl;
2136
2137 if (fDataHandler) {
2138 for (unsigned int i(0); i < dataParamLabels.size(); ++i) {
2139 outFile << dataParamLabels[i] << std::endl;
2140 }
2141 }
2142
2143 if (fRunListFile) {
2144 for (unsigned int i(0); i < fIndVar.size(); ++i) {
2145 outFile << fIndVar[i] << std::endl;
2146 }
2147 }
2148
2149 // in the GLOBAL mode write only global parameters and those which belong to the actual run - in the NORMAL mode write all parameters
2150 if (global) {
2151 std::string tempName;
2152 for (unsigned int i(0); i < fNumGlobalParam; ++i) {
2153 if (InParameterList(i, paramList))
2154 outFile << (*msrParamList)[i].fName.Data() << std::endl;
2155 }
2156 for (unsigned int i(0); i < fNumSpecParam; ++i) {
2157 if (InParameterList(fNumGlobalParam + fNumSpecParam*counter + i, paramList)) {
2158 tempName = (*msrParamList)[fNumGlobalParam + fNumSpecParam*counter + i].fName.Data();
2159 std::string::size_type loc = tempName.rfind(curRunNumber.str());
2160 if (loc == tempName.length() - fRunNumberDigits) {
2161 outFile << tempName.substr(0, loc) << std::endl;
2162 } else {
2163 std::cerr << std::endl << ">> msr2data: **ERROR** The run index of some parameter does not match the run number being processed!";
2164 std::cerr << std::endl << ">> msr2data: **ERROR** The output will be flawed!";
2165 std::cerr << std::endl;
2166 }
2167 }
2168 }
2169 } else {
2170 for (unsigned int i(0); i < msrNoOfParams; ++i) {
2171 if (InParameterList(i, paramList))
2172 outFile << (*msrParamList)[i].fName.Data() << std::endl;
2173 }
2174 }
2175
2176 if (msrStatistic->fChisq)
2177 outFile << "CHISQ" << std::endl;
2178 else
2179 outFile << "maxLH" << std::endl;
2180
2181 outFile << "NDF" << std::endl;
2182
2183 if (msrStatistic->fChisq)
2184 outFile << "CHISQred" << std::endl;
2185 else
2186 outFile << "maxLHred" << std::endl;
2187
2188 outFile << "RUN" << std::endl;
2189
2190 outFile << std::endl << "Data";
2191
2192 if (fDataHandler) {
2193 for (unsigned int i(0); i < dataParamNames.size(); ++i) {
2194 outFile << " " << dataParamNames[i];
2195 }
2196 }
2197
2198 if (fRunListFile) {
2199 for (unsigned int i(0); i < fIndVar.size(); ++i) {
2200 outFile << " " << fIndVar[i];
2201 }
2202 }
2203
2204 // in the GLOBAL mode write only global parameters and those which belong to the actual run - in the NORMAL mode write all parameters
2205 if (global) {
2206 std::string tempName;
2207 for (unsigned int i(0); i < fNumGlobalParam; ++i) {
2208 if (InParameterList(i, paramList))
2209 outFile << " " << (*msrParamList)[i].fName.Data();
2210 }
2211 for (unsigned int i(0); i < fNumSpecParam; ++i) {
2212 if (InParameterList(i, paramList)) {
2213 tempName = (*msrParamList)[fNumGlobalParam + fNumSpecParam*counter + i].fName.Data();
2214 std::string::size_type loc = tempName.rfind(curRunNumber.str());
2215 if (loc == tempName.length() - fRunNumberDigits) {
2216 outFile << " " << tempName.substr(0, loc);
2217 } else {
2218 std::cerr << std::endl << ">> msr2data: **ERROR** The run index of some parameter does not match the run number being processed!";
2219 std::cerr << std::endl << ">> msr2data: **ERROR** The output will be flawed!";
2220 std::cerr << std::endl;
2221 }
2222 }
2223 }
2224 } else {
2225 for (unsigned int i(0); i < msrNoOfParams; ++i) {
2226 if (InParameterList(i, paramList))
2227 outFile << " " << (*msrParamList)[i].fName.Data();
2228 }
2229 }
2230
2231 if (msrStatistic->fChisq)
2232 outFile << " " << "CHISQ";
2233 else
2234 outFile << " " << "maxLH";
2235
2236 outFile << " " << "NDF";
2237
2238 if (msrStatistic->fChisq)
2239 outFile << " " << "CHISQred";
2240 else
2241 outFile << " " << "maxLHred";
2242
2243 outFile << " " << "RUN" << std::endl;
2244
2245 outFile << "\\-e" << std::endl;
2246
2247 fHeaderWritten = true;
2248 }
2249
2250 if (fDataHandler) {
2251 for (unsigned int i(0); i < dataParam.size(); ++i) {
2252 if (i < dataParamErr.size())
2253 outFile << dataParamNames[i] << " = " << dataParam[i] << ", " \
2254 << dataParamErr[i] << ", " << dataParamErr[i] << ",\\" << std::endl;
2255 else
2256 outFile << dataParamNames[i] << " = " << dataParam[i] << ", 0, 0,\\" << std::endl;
2257 }
2258 }
2259
2260 if (fRunListFile) {
2261 for (unsigned int i(0); i < indVarValues.size(); ++i) {
2262 outFile << fIndVar[i] << " = " << indVarValues[i] << ", 0, 0,\\" << std::endl;
2263 }
2264 }
2265
2266 // in the GLOBAL mode write only global parameters and those which belong to the actual run - in the NORMAL mode write all parameters
2267 if (global) {
2268 std::string tempName;
2269 unsigned int idx;
2270 for (unsigned int i(0); i < fNumGlobalParam; ++i) {
2271 if (InParameterList(i, paramList)) {
2272 outFile << (*msrParamList)[i].fName.Data() << " = ";
2273 if ((*msrParamList)[i].fPosErrorPresent) {
2274 WriteValue(outFile, (*msrParamList)[i].fValue, (*msrParamList)[i].fPosError, outFile.width(), db);
2275 outFile << ", ";
2276 } else {
2277 outFile << (*msrParamList)[i].fValue << ", ";
2278 }
2279
2280 if ((*msrParamList)[i].fPosErrorPresent)
2281 outFile << (*msrParamList)[i].fPosError << ", ";
2282 else
2283 outFile << fabs((*msrParamList)[i].fStep) << ", ";
2284 outFile << fabs((*msrParamList)[i].fStep) << ",\\" << std::endl;
2285 }
2286 }
2287 for (unsigned int i(0); i < fNumSpecParam; ++i) {
2288 idx = fNumGlobalParam + fNumSpecParam*counter + i;
2289 if (InParameterList(idx, paramList)) {
2290 tempName = (*msrParamList)[idx].fName.Data();
2291 std::string::size_type loc = tempName.rfind(curRunNumber.str());
2292 if (loc == tempName.length() - fRunNumberDigits) {
2293 outFile << tempName.substr(0, loc) << " = ";
2294 if ((*msrParamList)[idx].fPosErrorPresent) {
2295 WriteValue(outFile, (*msrParamList)[idx].fValue, (*msrParamList)[idx].fPosError, outFile.width(), db);
2296 outFile << ", ";
2297 } else {
2298 outFile << (*msrParamList)[idx].fValue << ", ";
2299 }
2300 if ((*msrParamList)[idx].fPosErrorPresent) {
2301 WriteValue(outFile, (*msrParamList)[idx].fPosError, (*msrParamList)[idx].fPosError, outFile.width(), db);
2302 outFile << ", ";
2303 } else {
2304 WriteValue(outFile, (*msrParamList)[idx].fStep, (*msrParamList)[idx].fStep, outFile.width(), db);
2305 outFile << ", ";
2306 }
2307 WriteValue(outFile, (*msrParamList)[idx].fStep, (*msrParamList)[idx].fStep, outFile.width(), db);
2308 outFile << ",\\" << std::endl;
2309 }
2310 }
2311 }
2312 } else {
2313 for (unsigned int i(0); i < msrNoOfParams; ++i) {
2314 if (InParameterList(i, paramList)) {
2315 outFile << (*msrParamList)[i].fName.Data() << " = ";
2316 if ((*msrParamList)[i].fPosErrorPresent) {
2317 WriteValue(outFile, (*msrParamList)[i].fValue, (*msrParamList)[i].fPosError, outFile.width(), db);
2318 outFile << ", ";
2319 } else {
2320 WriteValue(outFile, (*msrParamList)[i].fValue, fabs((*msrParamList)[i].fStep), outFile.width(), db);
2321 outFile << ", ";
2322 }
2323 if ((*msrParamList)[i].fPosErrorPresent) {
2324 WriteValue(outFile, (*msrParamList)[i].fPosError, (*msrParamList)[i].fPosError, outFile.width(), db);
2325 outFile << ", ";
2326 } else {
2327 WriteValue(outFile, (*msrParamList)[i].fStep, (*msrParamList)[i].fStep, outFile.width(), db);
2328 outFile << ", ";
2329 }
2330 WriteValue(outFile, (*msrParamList)[i].fStep, (*msrParamList)[i].fStep, outFile.width(), db);
2331 outFile << ",\\" << std::endl;
2332 }
2333 }
2334 }
2335
2336 if (msrStatistic->fChisq)
2337 outFile << "CHISQ = " << msrStatistic->fMin << ", 0, 0,\\" << std::endl;
2338 else
2339 outFile << "maxLH = " << msrStatistic->fMin << ", 0, 0,\\" << std::endl;
2340
2341 outFile << "NDF = " << msrStatistic->fNdf << ", 0, 0,\\" << std::endl;
2342
2343 if (msrStatistic->fChisq)
2344 outFile << "CHISQred = " << msrStatistic->fMin/msrStatistic->fNdf << ", 0, 0,\\" << std::endl;
2345 else
2346 outFile << "maxLHred = " << msrStatistic->fMin/msrStatistic->fNdf << ", 0, 0,\\" << std::endl;
2347
2348 outFile << *fRunVectorIter << ",,, " << msrTitle << std::endl;
2349
2350 } else { // no DB file but ASCII file with data columns
2351
2352 unsigned int length(0), maxlength(12);
2353 for (unsigned int i(0); i < dataParamNames.size(); ++i) {
2354 length = dataParamNames[i].length();
2355 if (length > maxlength)
2356 maxlength = length;
2357 }
2358 for (unsigned int i(0); i < fIndVar.size(); ++i) {
2359 length = fIndVar[i].length();
2360 if (length > maxlength)
2361 maxlength = length;
2362 }
2363 // in the GLOBAL mode write only global parameters and those which belong to the actual run - in the NORMAL mode write all parameters
2364 std::string s;
2365 if (global) {
2366 for (unsigned int i(0); i < fNumGlobalParam; ++i) {
2367 if (InParameterList(i, paramList)) {
2368 s = (*msrParamList)[i].fName.Data();
2369 length = s.length();
2370 if (length > maxlength)
2371 maxlength = length;
2372 }
2373 }
2374 unsigned int idx;
2375 for (unsigned int i(0); i < fNumSpecParam; ++i) {
2376 idx = fNumGlobalParam + fNumSpecParam*counter + i;
2377 if (InParameterList(idx, paramList)) {
2378 s = (*msrParamList)[idx].fName.Data();
2379 std::string::size_type loc = s.rfind(curRunNumber.str());
2380 if (loc == s.length() - fRunNumberDigits) {
2381 length = s.length() - fRunNumberDigits;
2382 if (length > maxlength)
2383 maxlength = length;
2384 } else {
2385 std::cerr << std::endl << ">> msr2data: **ERROR** The run index of some parameter does not match the run number being processed!";
2386 std::cerr << std::endl << ">> msr2data: **ERROR** The output will be flawed!";
2387 std::cerr << std::endl;
2388 }
2389 }
2390 }
2391 } else {
2392 for (unsigned int i(0); i < msrNoOfParams; ++i) {
2393 if (InParameterList(i, paramList)) {
2394 s = (*msrParamList)[i].fName.Data();
2395 length = s.length();
2396 if (length > maxlength)
2397 maxlength = length;
2398 }
2399 }
2400 }
2401 if (maxlength < 13)
2402 maxlength = 13; // will use a minimum field width of 13 which corresponds to: -1.23456e-07 + ' '
2403 else
2404 maxlength += 1; // maximum length of parameter names + ' '
2405
2406 if (withHeader && !fHeaderWritten) {
2407 std::cout << std::endl << ">> msr2data: **INFO** Write a new simple-ASCII file header to " << outfile << std::endl;
2408
2409 if (fDataHandler) {
2410 for (unsigned int i(0); i < dataParamNames.size(); ++i) {
2411 s = dataParamNames[i];
2412 if (i < dataParamErr.size()) {
2413 outFile << std::setw(maxlength) << std::left << s << std::setw(maxlength + 3) << std::left << s + "Err";
2414 } else
2415 outFile << std::setw(maxlength) << std::left << s;
2416 }
2417 }
2418
2419 if (fRunListFile) {
2420 for (unsigned int i(0); i < fIndVar.size(); ++i) {
2421 outFile << std::setw(maxlength) << std::left << fIndVar[i];
2422 }
2423 }
2424
2425 // in the GLOBAL mode write only global parameters and those which belong to the actual run - in the NORMAL mode write all parameters
2426 if (global) {
2427 for (unsigned int i(0); i < fNumGlobalParam; ++i) {
2428 if (InParameterList(i, paramList)) {
2429 s = (*msrParamList)[i].fName.Data();
2430 outFile << std::setw(maxlength) << std::left << s \
2431 << std::setw(maxlength + 6) << std::left << s + "PosErr" \
2432 << std::setw(maxlength + 6) << std::left << s + "NegErr";
2433 }
2434 }
2435 unsigned int idx;
2436 for (unsigned int i(0); i < fNumSpecParam; ++i) {
2437 idx = fNumGlobalParam + fNumSpecParam*counter + i;
2438 if (InParameterList(idx, paramList)) {
2439 s = (*msrParamList)[idx].fName.Data();
2440 std::string::size_type loc = s.rfind(curRunNumber.str());
2441 if (loc == s.length() - fRunNumberDigits) {
2442 s = s.substr(0, loc);
2443 outFile << std::setw(maxlength) << std::left << s \
2444 << std::setw(maxlength + 6) << std::left << s + "PosErr" \
2445 << std::setw(maxlength + 6) << std::left << s + "NegErr";
2446 } else {
2447 std::cerr << std::endl << ">> msr2data: **ERROR** The run index of some parameter does not match the run number being processed!";
2448 std::cerr << std::endl << ">> msr2data: **ERROR** The output will be flawed!";
2449 std::cerr << std::endl;
2450 }
2451 }
2452 }
2453 } else {
2454 for (unsigned int i(0); i < msrNoOfParams; ++i) {
2455 if (InParameterList(i, paramList)) {
2456 s = (*msrParamList)[i].fName.Data();
2457 outFile << std::setw(maxlength) << std::left << s \
2458 << std::setw(maxlength + 6) << std::left << s + "PosErr" \
2459 << std::setw(maxlength + 6) << std::left << s + "NegErr";
2460 }
2461 }
2462 }
2463 s.clear();
2464
2465 if (msrStatistic->fChisq)
2466 outFile << std::setw(maxlength) << std::left << "CHISQ";
2467 else
2468 outFile << std::setw(maxlength) << std::left << "maxLH";
2469
2470 outFile << std::setw(maxlength) << std::left << "NDF";
2471
2472 if (msrStatistic->fChisq)
2473 outFile << std::setw(maxlength) << std::left << "CHISQred";
2474 else
2475 outFile << std::setw(maxlength) << std::left << "maxLHred";
2476
2477 outFile << std::setw(maxlength) << std::left << "RUN" << std::endl;
2478
2479 fHeaderWritten = true;
2480 }
2481
2482 if (fDataHandler) {
2483 for (unsigned int i(0); i < dataParam.size(); ++i) {
2484 if (i < dataParamErr.size()) {
2485 WriteValue(outFile, dataParam[i], maxlength);
2486 WriteValue(outFile, dataParamErr[i], maxlength + 3);
2487 } else {
2488 WriteValue(outFile, dataParam[i], maxlength);
2489 }
2490 }
2491 }
2492
2493 if (fRunListFile) {
2494 for (unsigned int i(0); i < indVarValues.size(); ++i) {
2495 WriteValue(outFile, indVarValues[i], maxlength);
2496 }
2497 }
2498
2499 // in the GLOBAL mode write only global parameters and those which belong to the actual run - in the NORMAL mode write all parameters
2500 if (global) {
2501 for (unsigned int i(0); i < fNumGlobalParam; ++i) {
2502 if (InParameterList(i, paramList)) {
2503 if ((*msrParamList)[i].fPosErrorPresent)
2504 WriteValue(outFile, (*msrParamList)[i].fValue, (*msrParamList)[i].fPosError, maxlength, db);
2505 else
2506 WriteValue(outFile, (*msrParamList)[i].fValue, maxlength);
2507
2508 if ((*msrParamList)[i].fPosErrorPresent)
2509 WriteValue(outFile, (*msrParamList)[i].fPosError, (*msrParamList)[i].fPosError, maxlength, db);
2510 else
2511 WriteValue(outFile, fabs((*msrParamList)[i].fStep), (*msrParamList)[i].fStep, maxlength, db);
2512
2513 WriteValue(outFile, fabs((*msrParamList)[i].fStep), (*msrParamList)[i].fStep, maxlength, db);
2514 }
2515 }
2516 unsigned int idx;
2517 for (unsigned int i(0); i < fNumSpecParam; ++i) {
2518 idx = fNumGlobalParam + fNumSpecParam*counter + i;
2519 if (InParameterList(idx, paramList)) {
2520 if ((*msrParamList)[idx].fPosErrorPresent)
2521 WriteValue(outFile, (*msrParamList)[idx].fValue, (*msrParamList)[idx].fPosError, maxlength, db);
2522 else
2523 WriteValue(outFile, (*msrParamList)[idx].fValue, maxlength);
2524
2525 if ((*msrParamList)[idx].fPosErrorPresent)
2526 WriteValue(outFile, (*msrParamList)[idx].fPosError, (*msrParamList)[idx].fPosError, maxlength, db);
2527 else
2528 WriteValue(outFile, (*msrParamList)[idx].fStep, (*msrParamList)[idx].fStep, maxlength, db);
2529
2530 WriteValue(outFile, (*msrParamList)[idx].fStep, (*msrParamList)[idx].fStep, maxlength, db);
2531 }
2532 }
2533 } else {
2534 for (unsigned int i(0); i < msrNoOfParams; ++i) {
2535 if (InParameterList(i, paramList)) {
2536 if ((*msrParamList)[i].fPosErrorPresent)
2537 WriteValue(outFile, (*msrParamList)[i].fValue, (*msrParamList)[i].fPosError, maxlength, db);
2538 else
2539 WriteValue(outFile, (*msrParamList)[i].fValue, fabs((*msrParamList)[i].fStep), maxlength, db);
2540
2541 if ((*msrParamList)[i].fPosErrorPresent)
2542 WriteValue(outFile, (*msrParamList)[i].fPosError, (*msrParamList)[i].fPosError, maxlength, db);
2543 else
2544 WriteValue(outFile, fabs((*msrParamList)[i].fStep), fabs((*msrParamList)[i].fStep), maxlength, db);
2545
2546 WriteValue(outFile, fabs((*msrParamList)[i].fStep), fabs((*msrParamList)[i].fStep), maxlength, db);
2547 }
2548 }
2549 }
2550
2551 WriteValue(outFile, msrStatistic->fMin, maxlength);
2552
2553 WriteValue(outFile, msrStatistic->fNdf, maxlength);
2554
2555 WriteValue(outFile, msrStatistic->fMin/msrStatistic->fNdf, maxlength);
2556
2557 WriteValue(outFile, *fRunVectorIter, maxlength);
2558 outFile << std::endl;
2559
2560 }
2561
2562 if (global) {
2563 std::cout << std::endl << ">> msr2data: **INFO** Parameter data of run " << *fRunVectorIter << " of file " << msrFileName \
2564 << " have been appended to " << outfile << std::endl;
2565 } else {
2566 std::cout << std::endl << ">> msr2data: **INFO** Parameter data of file " << msrFileName << " have been appended to " << outfile << std::endl;
2567 }
2568
2570
2571 outFile.close();
2572
2573 if (!global || (fRunVectorIter == fRunVector.end())) {
2574 fDataHandler.reset();
2575 }
2576
2577 msrParamList = nullptr;
2578 msrRunList = nullptr;
2579
2580// clean up some vectors
2581 dataParamNames.clear();
2582 dataParamLabels.clear();
2583 dataParam.clear();
2584 dataParamErr.clear();
2585 indVarValues.clear();
2586
2587 return PMUSR_SUCCESS;
2588
2589}
2590
2591//-------------------------------------------------------------
2592// WriteValue (single value)
2593//-------------------------------------------------------------
2609void PMsr2Data::WriteValue(std::fstream &outFile, const double &value, const unsigned int &width) const
2610{
2611 if ((fabs(value) >= 1.0e6) || ((fabs(value) < 1.0e-4) && (fabs(value) > 0.0)))
2612 outFile << std::scientific << std::setprecision(width - 8);
2613 else
2614 outFile.unsetf(std::ios::floatfield);
2615 outFile << std::setw(width) << std::left << value;
2616}
2617
2618//-------------------------------------------------------------
2619// WriteValue (value with error)
2620//-------------------------------------------------------------
2645void PMsr2Data::WriteValue(std::fstream &outFile, const double &value, const double &errValue, const unsigned int &width, const bool &db) const
2646{
2647 Int_t previous_prec = outFile.precision();
2648 Int_t prec = GetFirstSignificantDigit(errValue);
2649
2650 // for iostream also the number of digit before the decimal points are needed
2651 if (fabs(value) > 0.0)
2652 prec += static_cast<int>(log10(fabs(value)));
2653
2654 if ((fabs(value) >= 1.0e6) || ((fabs(value) < 1.0e-4) && (fabs(value) > 0)))
2655 outFile << std::scientific;
2656 else
2657 outFile.unsetf(std::ios::floatfield);
2658
2659 outFile.precision(prec);
2660 outFile << std::setw(width) << std::left << value;
2661 outFile.precision(previous_prec);
2662
2663 // make sure there is at least one space before the next number starts
2664 if (!db) {
2665 outFile << " ";
2666 }
2667}
2668
2669//-------------------------------------------------------------
2670// GetFirstSignificantDigit
2671//-------------------------------------------------------------
2692int PMsr2Data::GetFirstSignificantDigit(const double &value) const
2693{
2694 int prec=6;
2695
2696 int i=0;
2697 bool done = false;
2698 double dval = value;
2699 do {
2700 if (fabs(dval) >= 1.0)
2701 done = true;
2702 i++;
2703 dval *= 10.0;
2704 } while ((i<20) && !done);
2705
2706 if (i<20)
2707 prec = i;
2708
2709 return prec+1;
2710}
2711
2712//-------------------------------------------------------------
2713// InParameterList
2714//-------------------------------------------------------------
2733bool PMsr2Data::InParameterList(const unsigned int &paramValue, const std::vector<unsigned int> &paramList) const
2734{
2735 // if paramList.size() == 0, i.e. use ALL parameters
2736 if (paramList.size() == 0)
2737 return true;
2738
2739 for (unsigned int i=0; i<paramList.size(); i++) {
2740 if (paramValue+1 == paramList[i])
2741 return true;
2742 }
2743
2744 return false;
2745}
2746
2747//-------------------------------------------------------------------------------------------------------
2748// end
2749//-------------------------------------------------------------------------------------------------------
bool compare_parameters(const PMsrParamStructure &par1, const PMsrParamStructure &par2)
#define PMUSR_SUCCESS
Successful operation completion.
Definition PMusr.h:53
std::vector< PMsrRunBlock > PMsrRunList
Definition PMusr.h:1245
#define PMUSR_UNDEFINED
Definition PMusr.h:172
#define PMUSR_MSR_FILE_NOT_FOUND
MSR file could not be found at specified path.
Definition PMusr.h:59
#define MSR_PARAM_FUN_OFFSET
Offset added to function indices for parameter parsing.
Definition PMusr.h:260
std::vector< PMsrLineStructure > PMsrLines
Definition PMusr.h:989
#define PMUSR_MSR_SYNTAX_ERROR
Syntax error detected in MSR file content.
Definition PMusr.h:63
std::vector< Int_t > PIntVector
Definition PMusr.h:367
std::vector< PMsrParamStructure > PMsrParamList
Definition PMusr.h:1022
std::vector< Double_t > PDoubleVector
Definition PMusr.h:385
const char * startup_path_name
return status
int parseXmlFile(TSAXParser *, const char *)
Replacement function for TSAXParser::ParseFile().
PMsr2Data(const std::string &fileExtension)
Constructor that initializes the msr2data handler.
Definition PMsr2Data.cpp:73
unsigned int fNumSpecParam
Number of spectrum-specific parameters.
Definition PMsr2Data.h:311
int ReadMsrFile(const std::string &msrFileName) const
Reads and parses an msr-file.
std::unique_ptr< std::ifstream > fRunListFileStream
Stream for reading run list file.
Definition PMsr2Data.h:305
bool PrepareGlobalInputFile(unsigned int templateNumber, const std::string &globalOutputFile, unsigned int runListSize) const
Generates an msr-file for global (multi-run) fitting.
PMsrHandler * GetSingleRunMsrFile() const
Retrieves msr-file handler for a single run.
int WriteOutput(const std::string &outputFileName, const std::vector< unsigned int > &parameters, bool dbFormat, unsigned int precision, bool global=false, unsigned int counter=0) const
Writes extracted parameters to output file.
bool PrepareNewInputFile(unsigned int templateNumber, bool sorted) const
Generates a new msr-file from a template.
int CheckRunNumbersInRange() const
Validates that all run numbers are within acceptable ranges.
unsigned int fNumTempRunBlocks
Number of temporary run blocks.
Definition PMsr2Data.h:312
std::vector< unsignedint >::const_iterator fRunVectorIter
Iterator for current position in run vector.
Definition PMsr2Data.h:302
int ReadRunDataFile()
Reads the run data file for the current run.
std::unique_ptr< PMsrHandler > fMsrHandler
Handler for msr-file parsing and generation.
Definition PMsr2Data.h:309
std::unique_ptr< TSAXParser > fSaxParser
XML SAX parser for startup file.
Definition PMsr2Data.h:306
std::string fFileExtension
File extension for data files (e.g., "bin", "root")
Definition PMsr2Data.h:300
int GetFirstSignificantDigit(const double &value) const
Determines the first significant digit position of a value.
unsigned int fNumGlobalParam
Number of global parameters in fit.
Definition PMsr2Data.h:310
std::unique_ptr< PStartupHandler > fStartupHandler
Handler for XML startup file configuration.
Definition PMsr2Data.h:307
int SetRunNumbers(unsigned int runNumber)
Sets a single run number for processing.
void WriteValue(std::fstream &outFile, const double &value, const unsigned int &width) const
Writes a single numeric value to output stream.
bool fHeaderWritten
Flag tracking if output header has been written.
Definition PMsr2Data.h:314
int ParseXmlStartupFile()
Parses the XML startup file for configuration.
unsigned int fRunNumberDigits
Number of digits for run number formatting.
Definition PMsr2Data.h:313
~PMsr2Data()
Destructor that cleans up resources.
Definition PMsr2Data.cpp:93
bool PrepareNewSortedInputFile(unsigned int templateNumber) const
Generates a sorted msr-file from a template.
std::vector< std::string > fIndVar
Independent variables for output.
Definition PMsr2Data.h:304
std::vector< unsigned int > fRunVector
Vector of run numbers to process.
Definition PMsr2Data.h:301
unsigned int GetPresentRun() const
Gets the current run number being processed.
int DetermineRunNumberDigits(unsigned int maxRunNumber, bool templateFile) const
Determines the number of digits needed for run number formatting.
bool fRunListFile
Flag indicating if run list is from a file.
Definition PMsr2Data.h:303
bool InParameterList(const unsigned int &paramValue, const std::vector< unsigned int > &paramList) const
Checks if a parameter is in the output parameter list.
std::unique_ptr< PRunDataHandler > fDataHandler
Handler for run data files.
Definition PMsr2Data.h:308
MSR file parser and manager for the musrfit framework.
virtual PMsrParamList * GetMsrParamList()
Returns pointer to fit parameter list.
virtual Int_t ReadMsrFile()
Reads and parses the MSR file.
virtual const Double_t GetTransport()
Definition PMusr.h:865
virtual const Double_t GetMuonSpinAngle()
Definition PMusr.h:843
virtual const PDoubleVector GetRingAnode()
Definition PMusr.h:866
virtual const Double_t GetTempError(const UInt_t idx)
Definition PMusr.cpp:671
virtual const UInt_t GetNoOfTemperatures()
Definition PMusr.h:860
virtual const Double_t GetField()
Definition PMusr.h:859
virtual const Double_t GetEnergy()
Definition PMusr.h:864
virtual const PDoublePairVector * GetTemperature() const
Definition PMusr.h:861
Int_t fNo
Parameter number (1, 2, 3, ...)
Definition PMusr.h:1005
Bool_t fIsGlobal
True if parameter is global (for msr2data global mode)
Definition PMusr.h:1015
UInt_t fNdf
number of degrees of freedom
Definition PMusr.h:1333
Double_t fMin
chisq or max. likelihood
Definition PMusr.h:1331
Bool_t fChisq
flag telling if min = chi2 or min = max.likelihood
Definition PMusr.h:1330
Bool_t fValid
flag showing if the statistics block is valid, i.e. a fit took place which converged
Definition PMusr.h:1327