musrfit 1.12.1
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//-------------------------------------------------------------
780bool PMsr2Data::PrepareGlobalInputFile(unsigned int tempRun, const std::string &msrOutFile, unsigned int globalPlus, const std::string &musrfitOptions) const
781{
782 const TString alpha("alpha"), beta("beta"), norm("norm"), bkgfit("bkgfit"), lifetime("lifetime");
783
784 std::ostringstream strInfile;
785 strInfile << tempRun << fFileExtension << ".msr";
786
787 // read template msr-file
788 int status(ReadMsrFile(strInfile.str()));
789 if (status != PMUSR_SUCCESS)
790 return false;
791
792 // define two heavily used variables
793 PMsrParamList *msrParamList(fMsrHandler->GetMsrParamList());
794 PMsrRunList *msrRunList(fMsrHandler->GetMsrRunList());
795
796 // check how many RUN blocks are in the template msr-file
797 fNumTempRunBlocks = msrRunList->size();
798
799 // check that the RUN block run numbers match the template run number
800 std::ostringstream tempRunNumber;
801 tempRunNumber.fill('0');
802 tempRunNumber.setf(std::ios::internal, std::ios::adjustfield);
803 tempRunNumber.width(fRunNumberDigits);
804 tempRunNumber << tempRun;
805
806 std::string tempRunName;
807 for (unsigned int i(0); i < fNumTempRunBlocks; ++i) {
808 tempRunName = msrRunList->at(i).GetRunName()->Data();
809 std::string::size_type loc = tempRunName.rfind(tempRunNumber.str());
810 if ( loc == std::string::npos ) {
811 std::cerr << std::endl << ">> msr2data: **ERROR** A template run file number does not match the \"file index\"";
812 std::cerr << std::endl << ">> msr2data: **ERROR** Please check the template file!";
813 std::cerr << std::endl;
814 return false;
815 }
816 }
817
818 std::cout << std::endl << ">> msr2data: **INFO** Generating new global input msr file " << msrOutFile << std::endl;
819
820 // set some title for the msr-file
821 std::ostringstream titleStream;
822 titleStream << "Global msr file for the runs: ";
823 while (fRunVectorIter != fRunVector.end()) {
824 titleStream << *fRunVectorIter << " ";
826 }
827 fRunVectorIter = fRunVector.begin();
828 fMsrHandler->SetMsrTitle(TString(titleStream.str()));
829 titleStream.clear();
830 titleStream.str("");
831
832 // search parameter list for run-specific parameters - the rest is assumed to be global
833 std::string tempParamName;
834 for (unsigned int i(0); i < msrParamList->size(); ++i) {
835 tempParamName = msrParamList->at(i).fName.Data();
836 std::string::size_type loc = tempParamName.rfind(tempRunNumber.str());
837 if ((tempParamName.length() > fRunNumberDigits) && (loc == tempParamName.length() - fRunNumberDigits)) {
838 msrParamList->at(i).fIsGlobal = false;
840 } else {
841 msrParamList->at(i).fIsGlobal = true;
843 }
844 }
845
846 // there should be at least one run specific parameter, otherwise the GLOBAL option doesn't make sense
847 if (fNumSpecParam == 0) {
848 std::cout << ">> msr2data: **ERROR** found NO run specific parameter, hence the GLOBAL option doesn't make sense." << std::endl;
849 std::cout << ">> msr2data: Could it be, that your run specific labling is < 4 digits? Please check your msr-Input-File." << std::endl;
850 return false;
851 }
852
853
854 // check if parameters have been sorted correctly from the beginning
855 bool wasSorted(true);
856 for (unsigned int i(0); i < fNumGlobalParam; ++i) {
857 if(!msrParamList->at(i).fIsGlobal) {
858 wasSorted = false;
859 break;
860 }
861 }
862
863 int tempPar;
864 std::vector<int> *tempMap;
865 PMsrLines *tempLines;
866 std::vector<std::string> tempVec;
867 std::string line, tempString;
868
869 if (!wasSorted) {
870 // Sort the parameters: global ones first, then run-specific
871 sort(msrParamList->begin(), msrParamList->end(), compare_parameters);
872
873 // Change the parameter numbers in all blocks according to the new order
874
875 // THEORY block
876 tempLines = fMsrHandler->GetMsrTheory();
877 bool mapExists(false);
878 for (unsigned int i(0); i < tempLines->size(); ++i) {
879 line = (*tempLines)[i].fLine.Data();
880 split( tempVec, line, is_any_of(" \t"), token_compress_on ); // split the theory line at spaces
881 for (unsigned int j(1); j < tempVec.size(); ++j) {
882 try {
883 tempPar = boost::lexical_cast<unsigned int>(tempVec[j]);
884 // go through the whole parameter list and look for the correct parameter - this is stupid, however, I do not know what else to do
885 for (unsigned int k(0); k < msrParamList->size(); ++k) {
886 if (tempPar == msrParamList->at(k).fNo) {
887 if (msrParamList->at(k).fIsGlobal) {
888 tempVec[j] = boost::lexical_cast<std::string>(k + 1);
889 } else {
890 std::cerr << std::endl << ">> msr2data: **WARNING** The parameter " << msrParamList->at(k).fName.Data() \
891 << " is recognized as run specific!";
892 std::cerr << std::endl << ">> msr2data: **WARNING** Still it appears directly (un-mapped) in the template THEORY block.";
893 std::cerr << std::endl << ">> msr2data: **WARNING** The THEORY block entry will be substituted by a mapped parameter.";
894 std::cerr << std::endl << ">> msr2data: **WARNING** In case, this is not what has been intended, please review the new msr-file!";
895 std::cerr << std::endl;
896
897 unsigned int l(0);
898 tempMap = msrRunList->at(0).GetMap();
899 while (l < tempMap->size()) {
900 if ((*tempMap)[l] == tempPar) {
901 mapExists = true;
902 for (unsigned int m(1); m < fNumTempRunBlocks; ++m) {
903 if (msrRunList->at(m).GetMap()->at(l) != tempPar) {
904 mapExists = false;
905 break;
906 }
907 }
908 }
909 if (mapExists) {
910 break;
911 } else {
912 ++l;
913 }
914 }
915
916 if (mapExists) {
917 tempVec[j] = "map";
918 tempVec[j].append(boost::lexical_cast<std::string>(l + 1));
919 mapExists = false;
920 } else { // look for the first not used map entry
921 for (l = 0; l < tempMap->size(); ++l) {
922 if (!(*tempMap)[l]) {
923 break;
924 }
925 }
926 for (unsigned int m(0); m < fNumTempRunBlocks; ++m) {
927 msrRunList->at(m).SetMap(tempPar, l);
928 }
929 tempVec[j] = "map";
930 tempVec[j].append(boost::lexical_cast<std::string>(l + 1));
931 }
932 }
933 break;
934 }
935 }
936 }
937 catch(boost::bad_lexical_cast &) {
938 // in case the cast does not work: do nothing - this means the entry is not a simple parameter
939 }
940 }
941 // replace the old theory line by the new one
942 (*tempLines)[i].fLine.Clear();
943 for (unsigned int j(0); j < tempVec.size(); ++j) {
944 (*tempLines)[i].fLine += TString(tempVec[j]) + TString(" ");
945 }
946 tempVec.clear();
947 }
948
949 // FUNCTIONS block
950 std::string::size_type pos(0);
951 tempLines = fMsrHandler->GetMsrFunctions();
952 for (unsigned int i(0); i < tempLines->size(); ++i) {
953 line = (*tempLines)[i].fLine.Data();
954 split( tempVec, line, is_any_of(" ()+-*/=\t,") ); // split the function line at spaces and some characters that might be juxtaposed to the parameters
955 for (unsigned int j(1); j < tempVec.size(); ++j) {
956 if (!tempVec[j].substr(0,3).compare("par")) {
957 try {
958 tempPar = boost::lexical_cast<unsigned int>(tempVec[j].substr(3));
959 // go through the whole parameter list and look for the correct parameter - this is stupid, however, I do not know what else to do
960 for (unsigned int k(0); k < msrParamList->size(); ++k) {
961 if (tempPar == msrParamList->at(k).fNo) {
962 if (msrParamList->at(k).fIsGlobal) {
963 pos = line.find(tempVec[j], pos);
964 if ( pos != std::string::npos ) {
965 tempString = "par";
966 tempString.append(boost::lexical_cast<std::string>(k + 1));
967 line.replace(pos, tempVec[j].length(), tempString);
968 } else {
969 std::cerr << std::endl << ">> msr2data: **ERROR** A previously identified parameter in the FUNCTIONS block is not found any more!";
970 std::cerr << std::endl << ">> msr2data: **ERROR** This should not happen! Please report a bug!";
971 std::cerr << std::endl;
972 }
973 } else {
974 std::cerr << std::endl << ">> msr2data: **WARNING** The parameter " << msrParamList->at(k).fName.Data() \
975 << " is recognized as run specific!";
976 std::cerr << std::endl << ">> msr2data: **WARNING** Still it appears directly (un-mapped) in the template FUNCTIONS block.";
977 std::cerr << std::endl << ">> msr2data: **WARNING** The FUNCTIONS block entry will be substituted by a mapped parameter.";
978 std::cerr << std::endl << ">> msr2data: **WARNING** In case, this is not what has been intended, please review the new msr-file!";
979 std::cerr << std::endl;
980
981 unsigned int l(0);
982 tempMap = msrRunList->at(0).GetMap();
983 while (l < tempMap->size()) {
984 if ((*tempMap)[l] == tempPar) {
985 mapExists = true;
986 for (unsigned int m(1); m < fNumTempRunBlocks; ++m) {
987 if (msrRunList->at(m).GetMap()->at(l) != tempPar) {
988 mapExists = false;
989 break;
990 }
991 }
992 }
993 if (mapExists) {
994 break;
995 } else {
996 ++l;
997 }
998 }
999
1000 if (!mapExists) {
1001 for (l = 0; l < tempMap->size(); ++l) {
1002 if (!(*tempMap)[l]) {
1003 break;
1004 }
1005 }
1006 for (unsigned int m(0); m < fNumTempRunBlocks; ++m) {
1007 msrRunList->at(m).SetMap(tempPar, l);
1008 }
1009 }
1010 pos = line.find(tempVec[j], pos);
1011 if ( pos != std::string::npos ) {
1012 tempString = "map";
1013 tempString.append(boost::lexical_cast<std::string>(l + 1));
1014 line.replace(pos, tempVec[j].length(), tempString);
1015 } else {
1016 std::cerr << std::endl << ">> msr2data: **ERROR** A previously identified parameter in the FUNCTIONS block is not found any more!";
1017 std::cerr << std::endl << ">> msr2data: **ERROR** This should not happen! Please report a bug!";
1018 std::cerr << std::endl;
1019 }
1020 mapExists = false;
1021 }
1022 break;
1023 }
1024 }
1025 }
1026 catch(boost::bad_lexical_cast &) {
1027 std::cerr << std::endl << ">> msr2data: **ERROR** Something is wrong with the parameters used in the FUNCTIONS block!";
1028 std::cerr << std::endl << ">> msr2data: **ERROR** Please report a bug - function parsing should have failed earlier!";
1029 std::cerr << std::endl;
1030 return false;
1031 }
1032 }
1033 ++pos;
1034 }
1035 // replace the old function line by the new one
1036 (*tempLines)[i].fLine = TString(line);
1037 tempVec.clear();
1038 pos = 0;
1039 }
1040
1041 // RUN blocks
1042 // substitute the old parameter numbers by the new ones
1043
1044 unsigned int l(0);
1045
1046 // look in the following order through the RUN-blocks: norm, bkg-fit, alpha, beta, lifetime, maps
1047 for (unsigned int i(0); i < fNumTempRunBlocks; ++i) {
1048 tempPar = msrRunList->at(i).GetNormParamNo();
1049 if (tempPar > 0) {
1050 // go through the whole parameter list and look for the correct parameter - this is stupid, however, I do not know what else to do
1051 for (l = 0; l < msrParamList->size(); ++l) {
1052 if (tempPar == msrParamList->at(l).fNo) {
1053 msrRunList->at(i).SetNormParamNo(l + 1);
1054 break;
1055 }
1056 }
1057 if (l > msrParamList->size()) {
1058 std::cerr << std::endl << ">> msr2data: **ERROR** The norm parameter specified in RUN block " << i + 1 << " does not exist!";
1059 std::cerr << std::endl << ">> msr2data: **ERROR** Please report a bug - file checks should have failed earlier!";
1060 std::cerr << std::endl;
1061 return false;
1062 }
1063 }
1064 tempPar = msrRunList->at(i).GetBkgFitParamNo();
1065 if (tempPar > 0) {
1066 // go through the whole parameter list and look for the correct parameter - this is stupid, however, I do not know what else to do
1067 for (l = 0; l < msrParamList->size(); ++l) {
1068 if (tempPar == msrParamList->at(l).fNo) {
1069 msrRunList->at(i).SetBkgFitParamNo(l + 1);
1070 break;
1071 }
1072 }
1073 if (l > msrParamList->size()) {
1074 std::cerr << std::endl << ">> msr2data: **ERROR** The backgr.fit parameter specified in RUN block " << i + 1 << " does not exist!";
1075 std::cerr << std::endl << ">> msr2data: **ERROR** Please report a bug - file checks should have failed earlier!";
1076 std::cerr << std::endl;
1077 return false;
1078 }
1079 }
1080 tempPar = msrRunList->at(i).GetAlphaParamNo();
1081 if (tempPar > 0) {
1082 // go through the whole parameter list and look for the correct parameter - this is stupid, however, I do not know what else to do
1083 for (l = 0; l < msrParamList->size(); ++l) {
1084 if (tempPar == msrParamList->at(l).fNo) {
1085 msrRunList->at(i).SetAlphaParamNo(l + 1);
1086 break;
1087 }
1088 }
1089 if (l > msrParamList->size()) {
1090 std::cerr << std::endl << ">> msr2data: **ERROR** The alpha parameter specified in RUN block " << i + 1 << " does not exist!";
1091 std::cerr << std::endl << ">> msr2data: **ERROR** Please report a bug - file checks should have failed earlier!";
1092 std::cerr << std::endl;
1093 return false;
1094 }
1095 }
1096 tempPar = msrRunList->at(i).GetBetaParamNo();
1097 if (tempPar > 0) {
1098 // go through the whole parameter list and look for the correct parameter - this is stupid, however, I do not know what else to do
1099 for (l = 0; l < msrParamList->size(); ++l) {
1100 if (tempPar == msrParamList->at(l).fNo) {
1101 msrRunList->at(i).SetBetaParamNo(l + 1);
1102 break;
1103 }
1104 }
1105 if (l > msrParamList->size()) {
1106 std::cerr << std::endl << ">> msr2data: **ERROR** The beta parameter specified in RUN block " << i + 1 << " does not exist!";
1107 std::cerr << std::endl << ">> msr2data: **ERROR** Please report a bug - file checks should have failed earlier!";
1108 std::cerr << std::endl;
1109 return false;
1110 }
1111 }
1112 tempPar = msrRunList->at(i).GetLifetimeParamNo();
1113 if (tempPar > 0) {
1114 // go through the whole parameter list and look for the correct parameter - this is stupid, however, I do not know what else to do
1115 for (l = 0; l < msrParamList->size(); ++l) {
1116 if (tempPar == msrParamList->at(l).fNo) {
1117 msrRunList->at(i).SetLifetimeParamNo(l + 1);
1118 break;
1119 }
1120 }
1121 if (l > msrParamList->size()) {
1122 std::cerr << std::endl << ">> msr2data: **ERROR** The lifetime parameter specified in RUN block " << i + 1 << " does not exist!";
1123 std::cerr << std::endl << ">> msr2data: **ERROR** Please report a bug - file checks should have failed earlier!";
1124 std::cerr << std::endl;
1125 return false;
1126 }
1127 }
1128 tempMap = msrRunList->at(i).GetMap();
1129 for (unsigned int j(0); j < tempMap->size(); ++j) {
1130 tempPar = (*tempMap)[j];
1131 if (tempPar > 0) {
1132 // go through the whole parameter list and look for the correct parameter - this is stupid, however, I do not know what else to do
1133 for (l = 0; l < msrParamList->size(); ++l) {
1134 if (tempPar == msrParamList->at(l).fNo) {
1135 msrRunList->at(i).SetMap(l + 1, j);
1136 break;
1137 }
1138 }
1139 }
1140 }
1141 tempMap = nullptr;
1142 }
1143
1144 // FOURIER block - in case a parameter is used for the phase
1145 if (fMsrHandler->GetMsrFourierList()->fPhaseParamNo.size() > 0) {
1146 // go through the whole parameter list ...
1147 for (unsigned int k(0); k < msrParamList->size(); ++k) {
1148 if (tempPar == msrParamList->at(k).fNo) {
1149 fMsrHandler->GetMsrFourierList()->fPhaseParamNo.push_back(k + 1);
1150 break;
1151 }
1152 }
1153 }
1154
1155 // PLOT block - in case a parameter is used for the RRFphase
1156 for (unsigned int i(0); i < fMsrHandler->GetMsrPlotList()->size(); ++i) {
1157 tempPar = fMsrHandler->GetMsrPlotList()->at(i).fRRFPhaseParamNo;
1158 if (tempPar > 0) {
1159 // go through the whole parameter list ...
1160 for (unsigned int k(0); k < msrParamList->size(); ++k) {
1161 if (tempPar == msrParamList->at(k).fNo) {
1162 fMsrHandler->GetMsrPlotList()->at(i).fRRFPhaseParamNo = k + 1;
1163 break;
1164 }
1165 }
1166 }
1167 }
1168
1169 // finally fix the PARAMETER block after the reorganization
1170 for (l = 0; l < msrParamList->size(); ++l) {
1171 msrParamList->at(l).fNo = l + 1;
1172 }
1173 } else { // if the parameters were sorted just check the THEORY and FUNCTIONS blocks for run specific parameters
1174 bool lineChanged(false), mapExists(false);
1175 // THEORY block
1176 tempLines = fMsrHandler->GetMsrTheory();
1177 for (unsigned int i(0); i < tempLines->size(); ++i) {
1178 line = (*tempLines)[i].fLine.Data();
1179 split( tempVec, line, is_any_of(" \t"), token_compress_on ); // split the theory line at spaces
1180
1181 for (unsigned int j(1); j < tempVec.size(); ++j) {
1182 try {
1183 tempPar = boost::lexical_cast<unsigned int>(tempVec[j]);
1184 if (!msrParamList->at(tempPar - 1).fIsGlobal) {
1185 std::cerr << std::endl << ">> msr2data: **WARNING** The parameter " << msrParamList->at(tempPar - 1).fName.Data() \
1186 << " is recognized as run specific!";
1187 std::cerr << std::endl << ">> msr2data: **WARNING** Still it appears directly (un-mapped) in the template THEORY block.";
1188 std::cerr << std::endl << ">> msr2data: **WARNING** The THEORY block entry will be substituted by a mapped parameter.";
1189 std::cerr << std::endl << ">> msr2data: **WARNING** In case, this is not what has been intended, please review the new msr-file!";
1190 std::cerr << std::endl;
1191
1192 unsigned int l(0);
1193 tempMap = msrRunList->at(0).GetMap();
1194 while (l < tempMap->size()) {
1195 if ((*tempMap)[l] == tempPar) {
1196 mapExists = true;
1197 for (unsigned int m(1); m < fNumTempRunBlocks; ++m) {
1198 if (msrRunList->at(m).GetMap()->at(l) != tempPar) {
1199 mapExists = false;
1200 break;
1201 }
1202 }
1203 }
1204 if (mapExists) {
1205 break;
1206 } else {
1207 ++l;
1208 }
1209 }
1210
1211 if (mapExists) {
1212 tempVec[j] = "map";
1213 tempVec[j].append(boost::lexical_cast<std::string>(l + 1));
1214 lineChanged = true;
1215 mapExists = false;
1216 } else {
1217 for (l = 0; l < tempMap->size(); ++l) {
1218 if (!(*tempMap)[l]) {
1219 break;
1220 }
1221 }
1222 for (unsigned int m(0); m < fNumTempRunBlocks; ++m) {
1223 msrRunList->at(m).SetMap(tempPar, l);
1224 }
1225 tempVec[j] = "map";
1226 tempVec[j].append(boost::lexical_cast<std::string>(l + 1));
1227 lineChanged = true;
1228 }
1229 }
1230 }
1231 catch(boost::bad_lexical_cast &) {
1232 // in case the cast does not work: do nothing - this means the entry is not a simple parameter
1233 }
1234 }
1235 // replace the old theory line by the new one
1236 if (lineChanged) {
1237 (*tempLines)[i].fLine.Clear();
1238 for (unsigned int j(0); j < tempVec.size(); ++j) {
1239 (*tempLines)[i].fLine += TString(tempVec[j]) + TString(" ");
1240 }
1241 lineChanged = false;
1242 }
1243 tempVec.clear();
1244 }
1245
1246 // FUNCTIONS block
1247 tempLines = fMsrHandler->GetMsrFunctions();
1248 std::string::size_type pos(0);
1249 for (unsigned int i(0); i < tempLines->size(); ++i) {
1250 line = (*tempLines)[i].fLine.Data();
1251 split( tempVec, line, is_any_of(" ()+-*/=\t,") ); // split the function line at spaces and some characters that might be juxtaposed to the parameters
1252 for (unsigned int j(1); j < tempVec.size(); ++j) {
1253 if (!tempVec[j].substr(0,3).compare("par")) {
1254 try {
1255 tempPar = boost::lexical_cast<unsigned int>(tempVec[j].substr(3));
1256
1257 if (!msrParamList->at(tempPar - 1).fIsGlobal) {
1258
1259 std::cerr << std::endl << ">> msr2data: **WARNING** The parameter " << msrParamList->at(tempPar - 1).fName.Data() \
1260 << " is recognized as run specific!";
1261 std::cerr << std::endl << ">> msr2data: **WARNING** Still it appears directly (un-mapped) in the template FUNCTIONS block.";
1262 std::cerr << std::endl << ">> msr2data: **WARNING** The FUNCTIONS block entry will be substituted by a mapped parameter.";
1263 std::cerr << std::endl << ">> msr2data: **WARNING** In case, this is not what has been intended, please review the new msr-file!";
1264 std::cerr << std::endl;
1265
1266 unsigned int l(0);
1267 tempMap = msrRunList->at(0).GetMap();
1268 while (l < tempMap->size()) {
1269 if ((*tempMap)[l] == tempPar) {
1270 mapExists = true;
1271 for (unsigned int m(1); m < fNumTempRunBlocks; ++m) {
1272 if (msrRunList->at(m).GetMap()->at(l) != tempPar) {
1273 mapExists = false;
1274 break;
1275 }
1276 }
1277 }
1278 if (mapExists) {
1279 break;
1280 } else {
1281 ++l;
1282 }
1283 }
1284
1285 if (!mapExists) {
1286 for (l = 0; l < tempMap->size(); ++l) {
1287 if (!(*tempMap)[l]) {
1288 break;
1289 }
1290 }
1291 for (unsigned int m(0); m < fNumTempRunBlocks; ++m) {
1292 msrRunList->at(m).SetMap(tempPar, l);
1293 }
1294 }
1295 pos = line.find(tempVec[j], pos);
1296 if ( pos != std::string::npos ) {
1297 tempString = "map";
1298 tempString.append(boost::lexical_cast<std::string>(l + 1));
1299 line.replace(pos, tempVec[j].length(), tempString);
1300 } else {
1301 std::cerr << std::endl << ">> msr2data: **ERROR** A previously identified parameter in the FUNCTIONS block is not found any more!";
1302 std::cerr << std::endl << ">> msr2data: **ERROR** This should not happen! Please report a bug!";
1303 std::cerr << std::endl;
1304 }
1305 mapExists = false;
1306 lineChanged = true;
1307 }
1308 }
1309
1310 catch(boost::bad_lexical_cast &) {
1311 std::cerr << std::endl << ">> msr2data: **ERROR** Something is wrong with the parameters used in the FUNCTIONS block!";
1312 std::cerr << std::endl << ">> msr2data: **ERROR** Please report a bug - function parsing should have failed earlier!";
1313 std::cerr << std::endl;
1314 return false;
1315 }
1316 }
1317 ++pos;
1318 }
1319 // replace the old function line by the new one
1320 if (lineChanged) {
1321 (*tempLines)[i].fLine = TString(line);
1322 lineChanged = false;
1323 }
1324 tempVec.clear();
1325 pos = 0;
1326 }
1327 }
1328
1329 // go once more trough the template RUN blocks and look for common parameters
1330 // look in the following order through the RUN-blocks: norm, bkg-fit, alpha, beta, lifetime, maps
1331 for (unsigned int i(0); i < fNumTempRunBlocks; ++i) {
1332 tempPar = msrRunList->at(i).GetNormParamNo();
1333 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!
1334 if (msrParamList->at(tempPar-1).fIsGlobal) { // norm of RUN block i is global
1335 msrRunList->at(i).SetParGlobal(norm, 1);
1336 } else {
1337 msrRunList->at(i).SetParGlobal(norm, 0);
1338 }
1339 }
1340 tempPar = msrRunList->at(i).GetBkgFitParamNo();
1341 if (tempPar > 0) {
1342 if (msrParamList->at(tempPar-1).fIsGlobal) { // bkg-fit of RUN block i is global
1343 msrRunList->at(i).SetParGlobal(bkgfit, 1);
1344 } else {
1345 msrRunList->at(i).SetParGlobal(bkgfit, 0);
1346 }
1347 }
1348 tempPar = msrRunList->at(i).GetAlphaParamNo();
1349 if ((tempPar > 0) && (tempPar < MSR_PARAM_FUN_OFFSET)) { // if alpha is given by a function we do not have to care about it here!
1350 if (msrParamList->at(tempPar-1).fIsGlobal) { // alpha of RUN block i is global
1351 msrRunList->at(i).SetParGlobal(alpha, 1);
1352 } else {
1353 msrRunList->at(i).SetParGlobal(alpha, 0);
1354 }
1355 }
1356 tempPar = msrRunList->at(i).GetBetaParamNo();
1357 if ((tempPar > 0) && (tempPar < MSR_PARAM_FUN_OFFSET)) { // if beta is given by a function we do not have to care about it here!
1358 if (msrParamList->at(tempPar-1).fIsGlobal) { // beta of RUN block i is global
1359 msrRunList->at(i).SetParGlobal(beta, 1);
1360 } else {
1361 msrRunList->at(i).SetParGlobal(beta, 0);
1362 }
1363 }
1364 tempPar = msrRunList->at(i).GetLifetimeParamNo();
1365 if (tempPar > 0) {
1366 if (msrParamList->at(tempPar-1).fIsGlobal) { // lifetime of RUN block i is global
1367 msrRunList->at(i).SetParGlobal(lifetime, 1);
1368 } else {
1369 msrRunList->at(i).SetParGlobal(lifetime, 0);
1370 }
1371 }
1372 tempMap = msrRunList->at(i).GetMap();
1373 for (unsigned int j(0); j < tempMap->size(); ++j) {
1374 tempPar = (*tempMap)[j];
1375 if (tempPar > 0) {
1376 if (msrParamList->at(tempPar-1).fIsGlobal) { // map j of RUN block i is global
1377 msrRunList->at(i).SetMapGlobal(j, 1);
1378 } else {
1379 msrRunList->at(i).SetMapGlobal(j, 0);
1380 }
1381 }
1382 }
1383 tempMap = nullptr;
1384 }
1385
1386 // if the global+ option is specified, generate new single run msr-files and fit them
1387 // to obtain better starting parameter values for the global file
1388
1389 if (globalPlus) {
1390 // for the first file (or if the !-option is given), prepare a sorted input from the internal data-structure
1391 // if chain-fitting is used, the successive files are copied from the first
1392 unsigned int oldTempRun(0);
1393 bool firstrun(true);
1394 bool success(true);
1395
1396 while(fRunVectorIter != fRunVector.end()) {
1397 if (firstrun || (globalPlus == 1))
1398 success = PrepareNewSortedInputFile(tempRun);
1399 else
1400 success = PrepareNewInputFile(oldTempRun, true);
1401 if (firstrun)
1402 firstrun = false;
1403 oldTempRun = *fRunVectorIter;
1404
1405 if (!success) {
1406 std::cout << std::endl << ">> msr2data: **ERROR** Input file generation has not been successful! Quitting..." << std::endl;
1407 return false;
1408 }
1409
1410 // and do the fitting
1411 // check if MUSRFITPATH is set, if not issue a warning
1412 std::string path("");
1413 bool pathSet(false);
1414 char *pathPtr(getenv("MUSRFITPATH"));
1415 if (pathPtr) {
1416 path = boost::lexical_cast<std::string>(pathPtr);
1417 if (!path.empty()) {
1418 pathSet = true;
1419 path.append("/");
1420 }
1421 }
1422 if (!pathSet) {
1423 std::cerr << std::endl << ">> msr2data: **WARNING** The MUSRFITPATH environment variable is not set!";
1424 std::cerr << std::endl << ">> msr2data: **WARNING** Please set it or at least ensure that musrfit can be found on the PATH!" << std::endl;
1425 }
1426 std::ostringstream oss;
1427 oss << path << "musrfit" << " " << *fRunVectorIter << "-OneRunFit" << fFileExtension << ".msr" << " " << musrfitOptions;
1428 std::cout << std::endl << ">> msr2data: **INFO** Calling " << oss.str() << std::endl;
1429 if (system(oss.str().c_str()) == -1) {
1430 std::cerr << std::endl << "**ERROR** system call: " << oss.str().c_str() << " failed." << std::endl;
1431 }
1432
1434 }
1435 // set back the iterator to the first run
1436 fRunVectorIter = fRunVector.begin();
1437
1438 std::cout << std::endl << ">> msr2data: **INFO** Continuing with the generation of the global input msr file " << msrOutFile << std::endl;
1439 }
1440
1441
1442 // now go through the specified runs and add run-specific parameters and RUN blocks
1443
1444 PMsrHandler *singleRunMsrFile;
1445 singleRunMsrFile = nullptr;
1446
1447 std::map<UInt_t, TString> commentsP, commentsR;
1448 TString tempTstr;
1449 std::ostringstream newRunNumber;
1450 newRunNumber.fill('0');
1451 newRunNumber.setf(std::ios::internal, std::ios::adjustfield);
1452 newRunNumber.width(fRunNumberDigits);
1453 newRunNumber << *fRunVectorIter;
1454
1455 //std::cout << "Number of run specific parameters: " << fNumSpecParam << std::endl;
1456
1457 // in global+ mode, read in the single-run msr-file of the first run and use its
1458 // fitted values/steps as starting values for the run-specific parameters -
1459 // also when the first run coincides with the template run
1460 if (globalPlus) {
1461 singleRunMsrFile = GetSingleRunMsrFile();
1462 if (singleRunMsrFile == nullptr)
1463 return false;
1464 for (unsigned int l(fNumGlobalParam); l < msrParamList->size(); ++l) {
1465 fMsrHandler->SetMsrParamValue(l, singleRunMsrFile->GetMsrParamList()->at(l).fValue);
1466 fMsrHandler->SetMsrParamStep(l, singleRunMsrFile->GetMsrParamList()->at(l).fStep);
1467 }
1468 delete singleRunMsrFile;
1469 singleRunMsrFile = nullptr;
1470 }
1471
1472 if (newRunNumber.str().compare(tempRunNumber.str())) { // first run number does not match the template run number
1473 // substitute the template run-numbers in the parameter names
1474 for (unsigned int l(fNumGlobalParam); l < msrParamList->size(); ++l) {
1475 tempParamName = msrParamList->at(l).fName.Data();
1476 std::string::size_type loc = tempParamName.rfind(tempRunNumber.str());
1477 if ( loc != std::string::npos ) {
1478 tempParamName.replace(loc, fRunNumberDigits, newRunNumber.str());
1479 msrParamList->at(l).fName = tempParamName;
1480 } else {
1481 std::cerr << std::endl << ">> msr2data: **ERROR** The indices of the run specific parameters do not match the template run number!";
1482 std::cerr << std::endl << ">> msr2data: **ERROR** This should not happen! Please report a bug!";
1483 std::cerr << std::endl;
1484 }
1485 }
1486
1487 // substitute the template run-numbers in the RUN names
1488 for (unsigned int i(0); i < fNumTempRunBlocks; ++i) {
1489 tempRunName = msrRunList->at(i).GetRunName()->Data();
1490 std::string::size_type loc = tempRunName.rfind(tempRunNumber.str());
1491 if ( loc != std::string::npos ) {
1492 tempRunName.replace(loc, fRunNumberDigits, newRunNumber.str());
1493 tempTstr = TString(tempRunName);
1494 msrRunList->at(i).SetRunName(tempTstr, 0);
1495 } else {
1496 std::cerr << std::endl << ">> msr2data: **ERROR** A template run file number does not match the \"file index\"";
1497 std::cerr << std::endl << ">> msr2data: **ERROR** Please check the template file!";
1498 std::cerr << std::endl;
1499 return false;
1500 }
1501 }
1502 }
1503
1504 std::ostringstream tempStrStr;
1505
1506 // comments for the output-file
1507 if (fNumGlobalParam) {
1508 commentsP[1] = TString("Common parameters for all runs");
1509 }
1510 if (fNumSpecParam) {
1511 tempStrStr.str("");
1512 tempStrStr << "Specific parameters for run " << *fRunVectorIter;
1513 tempTstr = tempStrStr.str();
1514 commentsP[fNumGlobalParam + 1] = tempTstr;
1515 }
1516 if (fNumTempRunBlocks) {
1517 tempStrStr.str("");
1518 tempStrStr << "RUN blocks for run " << *fRunVectorIter;
1519 tempTstr = tempStrStr.str();
1520 commentsR[1] = tempTstr;
1521 }
1522
1524
1525 UInt_t runcounter(0);
1526 std::map<TString, Int_t> *runParGlobal(nullptr);
1527 std::map<TString, Int_t>::iterator iter;
1528 PIntVector *runMapGlobal(nullptr);
1529
1530 while (fRunVectorIter != fRunVector.end()) {
1531 tempRunNumber.str(newRunNumber.str());
1532 newRunNumber.str("");
1533 newRunNumber.clear();
1534 newRunNumber.fill('0');
1535 newRunNumber.setf(std::ios::internal, std::ios::adjustfield);
1536 newRunNumber.width(fRunNumberDigits);
1537 newRunNumber << *fRunVectorIter;
1538
1539 // in global+ mode, read in the single run msr-file
1540 if (globalPlus) {
1541 singleRunMsrFile = GetSingleRunMsrFile();
1542 if (singleRunMsrFile == nullptr)
1543 return false;
1544 }
1545
1546 // add parameters for each run
1547 for (unsigned int l(0); l < fNumSpecParam; ++l) {
1548 msrParamList->push_back(msrParamList->at(fNumGlobalParam + runcounter*fNumSpecParam + l));
1549 tempParamName = msrParamList->back().fName.Data();
1550 std::string::size_type loc = tempParamName.rfind(tempRunNumber.str());
1551 if ( loc != std::string::npos ) {
1552 tempParamName.replace(loc, fRunNumberDigits, newRunNumber.str());
1553 msrParamList->back().fName = tempParamName;
1554 msrParamList->back().fNo += fNumSpecParam;
1555 if (globalPlus && singleRunMsrFile) {
1556 fMsrHandler->SetMsrParamValue(msrParamList->size() - 1, singleRunMsrFile->GetMsrParamList()->at(fNumGlobalParam + l).fValue);
1557 fMsrHandler->SetMsrParamStep(msrParamList->size() - 1, singleRunMsrFile->GetMsrParamList()->at(fNumGlobalParam + l).fStep);
1558 }
1559 } else {
1560 std::cerr << std::endl << ">> msr2data: **ERROR** Something went wrong when appending new parameters!";
1561 std::cerr << std::endl << ">> msr2data: **ERROR** This should not happen! Please report a bug!";
1562 std::cerr << std::endl;
1563 }
1564 }
1565 if (singleRunMsrFile) {
1566 delete singleRunMsrFile;
1567 singleRunMsrFile = nullptr;
1568 }
1569
1570 // add RUN blocks for each run
1571 for (unsigned int i(0); i < fNumTempRunBlocks; ++i) {
1572 msrRunList->push_back(msrRunList->at(runcounter*fNumTempRunBlocks + i));
1573 tempRunName = msrRunList->back().GetRunName()->Data();
1574 std::string::size_type loc = tempRunName.rfind(tempRunNumber.str());
1575 if ( loc != std::string::npos ) {
1576 tempRunName.replace(loc, fRunNumberDigits, newRunNumber.str());
1577 tempTstr = TString(tempRunName);
1578 msrRunList->back().SetRunName(tempTstr, 0);
1579 } else {
1580 std::cerr << std::endl << ">> msr2data: **ERROR** Something went wrong when appending new RUN blocks!";
1581 std::cerr << std::endl << ">> msr2data: **ERROR** This should not happen! Please report a bug!";
1582 std::cerr << std::endl;
1583 return false;
1584 }
1585 // change run specific parameter numbers in the new RUN block
1586 runParGlobal = msrRunList->back().GetParGlobal();
1587 iter = runParGlobal->find(norm);
1588 if (iter != runParGlobal->end()) {
1589 if (!iter->second)
1590 msrRunList->back().SetNormParamNo(msrRunList->back().GetNormParamNo() + fNumSpecParam);
1591 }
1592 iter = runParGlobal->find(bkgfit);
1593 if (iter != runParGlobal->end()) {
1594 if (!iter->second)
1595 msrRunList->back().SetBkgFitParamNo(msrRunList->back().GetBkgFitParamNo() + fNumSpecParam);
1596 }
1597 iter = runParGlobal->find(alpha);
1598 if (iter != runParGlobal->end()) {
1599 if (!iter->second)
1600 msrRunList->back().SetAlphaParamNo(msrRunList->back().GetAlphaParamNo() + fNumSpecParam);
1601 }
1602 iter = runParGlobal->find(beta);
1603 if (iter != runParGlobal->end()) {
1604 if (!iter->second)
1605 msrRunList->back().SetBetaParamNo(msrRunList->back().GetBetaParamNo() + fNumSpecParam);
1606 }
1607 iter = runParGlobal->find(lifetime);
1608 if (iter != runParGlobal->end()) {
1609 if (!iter->second)
1610 msrRunList->back().SetLifetimeParamNo(msrRunList->back().GetLifetimeParamNo() + fNumSpecParam);
1611 }
1612 runMapGlobal = msrRunList->back().GetMapGlobal();
1613 for (unsigned int l(0); l < runMapGlobal->size(); ++l) {
1614 if (!(*runMapGlobal)[l])
1615 msrRunList->back().SetMap(msrRunList->back().GetMap()->at(l) + fNumSpecParam, l);
1616 }
1617 }
1618
1619 ++runcounter;
1620
1621 // comments for the output-file
1622 if (fNumSpecParam) {
1623 tempStrStr.str("");
1624 tempStrStr << "Specific parameters for run " << *fRunVectorIter;
1625 tempTstr = tempStrStr.str();
1626 commentsP[fNumGlobalParam + runcounter*fNumSpecParam + 1] = tempTstr;
1627 }
1628 if (fNumTempRunBlocks) {
1629 tempStrStr.str("");
1630 tempStrStr << "RUN blocks for run " << *fRunVectorIter;
1631 tempTstr = tempStrStr.str();
1632 commentsR[runcounter*fNumTempRunBlocks + 1] = tempTstr;
1633 }
1634
1636 }
1637
1638 // set the convergence flag to false because no fit has been performed using the newly generated file
1639 fMsrHandler->GetMsrStatistic()->fValid = false;
1640
1641 // write the global msr-file
1642 status = fMsrHandler->WriteMsrFile(msrOutFile.c_str(), &commentsP, nullptr, nullptr, &commentsR);
1643
1644 if (status != PMUSR_SUCCESS) {
1645 std::cerr << std::endl << ">> msr2data: **ERROR** Writing the new msr-file has not been successful!";
1646 std::cerr << std::endl;
1647 return false;
1648 }
1649
1650 // set back the run-iterator to the start
1651 fRunVectorIter = fRunVector.begin();
1652
1653 msrParamList = nullptr;
1654 msrRunList = nullptr;
1655
1656 return true;
1657}
1658
1659//-------------------------------------------------------------
1670bool PMsr2Data::PrepareNewSortedInputFile(unsigned int tempRun) const
1671{
1672
1673 PMsrParamList *msrParamList(fMsrHandler->GetMsrParamList());
1674 PMsrRunList *msrRunList(fMsrHandler->GetMsrRunList());
1675
1676 // make a copy of the msr-file-data to be able to restore it after the operations (parameter name and run number changes)
1677 PMsrParamList paramListCopy(*msrParamList);
1678 PMsrRunList runListCopy(*msrRunList);
1679 TString titleCopy(*(fMsrHandler->GetMsrTitle()));
1680
1681 std::ostringstream tempRunNumber;
1682 tempRunNumber.fill('0');
1683 tempRunNumber.setf(std::ios::internal, std::ios::adjustfield);
1684 tempRunNumber.width(fRunNumberDigits);
1685 tempRunNumber << tempRun;
1686
1687 std::ostringstream newRunNumber;
1688 newRunNumber.fill('0');
1689 newRunNumber.setf(std::ios::internal, std::ios::adjustfield);
1690 newRunNumber.width(fRunNumberDigits);
1691 newRunNumber << *fRunVectorIter;
1692
1693 std::string tempParamName, tempRunName;
1694 TString tempTstr;
1695
1696 std::ostringstream msrOutFile;
1697 msrOutFile << *fRunVectorIter << "-OneRunFit" << fFileExtension << ".msr";
1698 std::cout << std::endl << ">> msr2data: **INFO** Generating new input msr file " << msrOutFile.str() << std::endl;
1699
1700 tempTstr = TString(newRunNumber.str());
1701 fMsrHandler->SetMsrTitle(tempTstr);
1702
1703 // remove the template run-numbers in the parameter names
1704 for (unsigned int l(fNumGlobalParam); l < msrParamList->size(); ++l) {
1705 tempParamName = msrParamList->at(l).fName.Data();
1706 std::string::size_type loc = tempParamName.rfind(tempRunNumber.str());
1707 if ( loc != std::string::npos ) {
1708 msrParamList->at(l).fName = StripRunNumberSuffix(tempParamName, tempRunNumber.str());
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 << StripRunNumberSuffix(tempName, curRunNumber.str()) << 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 << " " << StripRunNumberSuffix(tempName, curRunNumber.str());
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 << StripRunNumberSuffix(tempName, curRunNumber.str()) << " = ";
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 = StripRunNumberSuffix(s, curRunNumber.str()).length();
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 = StripRunNumberSuffix(s, curRunNumber.str());
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//-------------------------------------------------------------
2758std::string PMsr2Data::StripRunNumberSuffix(const std::string &name, const std::string &runNumberStr) const
2759{
2760 if ((name.length() < runNumberStr.length()) ||
2761 (name.compare(name.length() - runNumberStr.length(), runNumberStr.length(), runNumberStr)))
2762 return name;
2763
2764 std::string::size_type loc(name.length() - runNumberStr.length());
2765 if ((loc > 0) && (name[loc-1] == '_'))
2766 --loc;
2767
2768 return name.substr(0, loc);
2769}
2770
2771//-------------------------------------------------------------------------------------------------------
2772// end
2773//-------------------------------------------------------------------------------------------------------
bool compare_parameters(const PMsrParamStructure &par1, const PMsrParamStructure &par2)
#define PMUSR_SUCCESS
Successful operation completion.
Definition PMusr.h:58
std::vector< PMsrRunBlock > PMsrRunList
Definition PMusr.h:1263
#define PMUSR_UNDEFINED
Definition PMusr.h:177
#define PMUSR_MSR_FILE_NOT_FOUND
MSR file could not be found at specified path.
Definition PMusr.h:64
#define MSR_PARAM_FUN_OFFSET
Offset added to function indices for parameter parsing.
Definition PMusr.h:265
std::vector< PMsrLineStructure > PMsrLines
Definition PMusr.h:1007
#define PMUSR_MSR_SYNTAX_ERROR
Syntax error detected in MSR file content.
Definition PMusr.h:68
std::vector< Int_t > PIntVector
Definition PMusr.h:381
std::vector< PMsrParamStructure > PMsrParamList
Definition PMusr.h:1040
std::vector< Double_t > PDoubleVector
Definition PMusr.h:399
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:326
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:320
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:327
std::vector< unsignedint >::const_iterator fRunVectorIter
Iterator for current position in run vector.
Definition PMsr2Data.h:317
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:324
std::string StripRunNumberSuffix(const std::string &name, const std::string &runNumberStr) const
Strips the trailing run-number suffix (and an optional preceding separator such as '_') from a run-sp...
std::unique_ptr< TSAXParser > fSaxParser
XML SAX parser for startup file.
Definition PMsr2Data.h:321
std::string fFileExtension
File extension for data files (e.g., "bin", "root").
Definition PMsr2Data.h:315
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:325
std::unique_ptr< PStartupHandler > fStartupHandler
Handler for XML startup file configuration.
Definition PMsr2Data.h:322
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:329
int ParseXmlStartupFile()
Parses the XML startup file for configuration.
unsigned int fRunNumberDigits
Number of digits for run number formatting.
Definition PMsr2Data.h:328
~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:319
std::vector< unsigned int > fRunVector
Vector of run numbers to process.
Definition PMsr2Data.h:316
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:318
bool PrepareGlobalInputFile(unsigned int templateNumber, const std::string &globalOutputFile, unsigned int runListSize, const std::string &musrfitOptions="") const
Generates an msr-file for global (multi-run) fitting.
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:323
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:879
virtual const Double_t GetMuonSpinAngle()
Definition PMusr.h:857
virtual const PDoubleVector GetRingAnode()
Definition PMusr.h:880
virtual const Double_t GetTempError(const UInt_t idx)
Definition PMusr.cpp:671
virtual const UInt_t GetNoOfTemperatures()
Definition PMusr.h:874
virtual const Double_t GetField()
Definition PMusr.h:873
virtual const Double_t GetEnergy()
Definition PMusr.h:878
virtual const PDoublePairVector * GetTemperature() const
Definition PMusr.h:875
Int_t fNo
Parameter number (1, 2, 3, ...).
Definition PMusr.h:1023
Bool_t fIsGlobal
True if parameter is global (for msr2data global mode).
Definition PMusr.h:1033
UInt_t fNdf
number of degrees of freedom
Definition PMusr.h:1351
Double_t fMin
chisq or max. likelihood
Definition PMusr.h:1349
Bool_t fChisq
flag telling if min = chi2 or min = max.likelihood
Definition PMusr.h:1348
Bool_t fValid
flag showing if the statistics block is valid, i.e. a fit took place which converged
Definition PMusr.h:1345