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