From ebcd1925097e4a4ecf259824a71104db1060119b Mon Sep 17 00:00:00 2001 From: "Bastian M. Wojek" Date: Sat, 22 Jan 2011 01:17:22 +0000 Subject: [PATCH] Added a minor extension to the global mode of msr2data which allows the generation of a global msr-file including the results of single-run fits for run-specific parameters. This might help to get overall better starting parameters for a global fit. For a few more details and an example, see the documentation. Any testing is very welcome. --- ChangeLog | 4 +- src/classes/PMsr2Data.cpp | 274 +++++++++++++++++++++++++++++++++++--- src/include/PMsr2Data.h | 9 +- src/msr2data.cpp | 45 +++++-- 4 files changed, 297 insertions(+), 35 deletions(-) diff --git a/ChangeLog b/ChangeLog index cae078e8..1bf8c76c 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,15 +1,17 @@ #--------------------------------------------------------------------- # ChangeLog -# AS, 2010/11/11 +# AS, 2011/01/22 # $Id$ #--------------------------------------------------------------------- changes since 0.8.0 =================================== +NEW extended global mode in msr2data NEW any2many: an attempt to write the universial musr-data-file converter. Just started, needs still some work. NEW musrt0: added the possibility to show the t0 saved in the data file 's'. Furthermore added the option --getT0FromPromptPeak, -g with : will, in non-interactive mode estimate the t0's from the prompt peak and write it into the msr-file (MUSR-133). +FIXED a bug in the determination of the length of the run numbers in msr2data FIXED 2 little annoying problems: (i) now it is possible to zoom down to the single bin in musrview. (ii) when switching between data- and difference-view, the x-range doesn't change anymore. FIXED musrt0 crash for histogram number out of range (MUSR-157) diff --git a/src/classes/PMsr2Data.cpp b/src/classes/PMsr2Data.cpp index 31f199b8..92fc89ab 100644 --- a/src/classes/PMsr2Data.cpp +++ b/src/classes/PMsr2Data.cpp @@ -130,17 +130,31 @@ PMsr2Data::~PMsr2Data() * - -3 if the msr-file does not contain a RUN block * * \param runNo run number of an existing msr-file + * \param normalMode false for global mode * */ -int PMsr2Data::DetermineRunNumberDigits(unsigned int runNo) const +int PMsr2Data::DetermineRunNumberDigits(unsigned int runNo, bool normalMode) const { ostringstream strInfile; strInfile << runNo << fFileExtension << ".msr"; - ifstream in(strInfile.str().c_str()); - if (!in) { - cerr << endl << ">> msr2data: **ERROR** The msr-file " << strInfile.str() << " cannot be opened! Please check!"; - cerr << endl; - return -1; + ifstream *in = new ifstream(strInfile.str().c_str()); + if (!in->is_open()) { + if (!normalMode && (runNo == *fRunVectorIter)) { + string fileNameCopy(strInfile.str()); + strInfile.clear(); + strInfile.str(""); + strInfile << runNo << "+global" << fFileExtension << ".msr"; + in = new ifstream(strInfile.str().c_str()); + if (!in->is_open()) { + cerr << endl << ">> msr2data: **ERROR** Neither the file " << fileNameCopy << " nor the file " << strInfile.str() << " cannot be opened! Please check!"; + cerr << endl; + return -1; + } + } else { + cerr << endl << ">> msr2data: **ERROR** The file " << strInfile.str() << " cannot be opened! Please check!"; + cerr << endl; + return -1; + } } ostringstream tempRunNumber; @@ -152,7 +166,7 @@ int PMsr2Data::DetermineRunNumberDigits(unsigned int runNo) const string line, firstOnLine; istringstream strLine; - while (getline(in, line)) { + while (getline(*in, line)) { strLine.clear(); strLine.str(line); strLine >> firstOnLine; @@ -165,7 +179,9 @@ int PMsr2Data::DetermineRunNumberDigits(unsigned int runNo) const if(isdigit(line.at(loc))) { ++fRunNumberDigits; } else { - in.close(); + in->close(); + delete in; + in = 0; //cout << endl << "Number of digits: " << fRunNumberDigits << endl; return 0; } @@ -176,7 +192,9 @@ int PMsr2Data::DetermineRunNumberDigits(unsigned int runNo) const cerr << endl << ">> msr2data: **ERROR** Please check the first msr-file that should be processed;"; cerr << endl << ">> msr2data: **ERROR** this is either some template or the first file from the run list."; cerr << endl; - in.close(); + in->close(); + delete in; + in = 0; return -2; } } @@ -185,6 +203,9 @@ int PMsr2Data::DetermineRunNumberDigits(unsigned int runNo) const cerr << endl << ">> msr2data: **ERROR** this is either some template or the first file from the run list."; cerr << endl << ">> msr2data: **ERROR** Obviously it contains no RUN block..."; cerr << endl; + in->close(); + delete in; + in = 0; return -3; } @@ -280,7 +301,7 @@ int PMsr2Data::SetRunNumbers(unsigned int runNoStart, unsigned int runNoEnd) //------------------------------------------------------------- /** - *

Initialization of the internal list of runs using a explicitly specified run numbers + *

Initialization of the internal list of runs using explicitly specified run numbers * *

return: * - -1 if the vector is empty @@ -294,7 +315,7 @@ int PMsr2Data::SetRunNumbers(const vector &runListVector) if (runListVector.empty()) return -1; - for (vector::const_iterator iter(runListVector.begin()); iter!=runListVector.end(); iter++) { + for (vector::const_iterator iter(runListVector.begin()); iter!=runListVector.end(); ++iter) { if (*iter < 1) return 1; } @@ -340,7 +361,7 @@ int PMsr2Data::SetRunNumbers(const string &runListFile) else if (line.at(0) == '#') continue; else - cntr++; + ++cntr; split( splitVec, line, is_any_of("#") ); // split the string if any comments appear on the line @@ -409,7 +430,7 @@ int PMsr2Data::ParseXmlStartupFile() //------------------------------------------------------------- /** - *

Read in a msr-file + *

Read in a msr-file into the default structure * *

return: * - PMUSR_SUCCESS if everything is OK @@ -438,6 +459,39 @@ int PMsr2Data::ReadMsrFile(const string &infile) const return status; } +//------------------------------------------------------------- +/** + *

Read in the single run msr-file corresponding to the position in the run-vector + * into a secondary msr-handler different from the class member + * + *

return: + * - pointer to the secondary msr-handler or 0 in case of an error + * + */ +PMsrHandler* PMsr2Data::GetSingleRunMsrFile() const +{ + ostringstream singleMsrInFile; + singleMsrInFile << *fRunVectorIter << "-OneRunFit" << fFileExtension << ".msr"; + PMsrHandler *singleRunMsrFile = new PMsrHandler(singleMsrInFile.str().c_str()); + + int status = singleRunMsrFile->ReadMsrFile(); + if (status != PMUSR_SUCCESS) { + switch (status) { + case PMUSR_MSR_FILE_NOT_FOUND: + cerr << endl << ">> msr2data: **ERROR** Could not find " << singleMsrInFile.str() << endl; + break; + case PMUSR_MSR_SYNTAX_ERROR: + cerr << endl << ">> msr2data: **SYNTAX ERROR** in file " << singleMsrInFile.str() << ", full stop here." << endl; + break; + default: + cerr << endl << ">> msr2data: **UNKOWN ERROR** when trying to read the msr-file" << endl; + break; + } + return 0; + } + return singleRunMsrFile; +} + //------------------------------------------------------------- /** *

Read in a run data-file @@ -471,8 +525,9 @@ bool PMsr2Data::ReadRunDataFile() * - false otherwise * * \param tempRun template run number + * \param calledFromGlobalMode tag specifying if the routine is called as part of the global msr-file generation */ -bool PMsr2Data::PrepareNewInputFile(unsigned int tempRun) const +bool PMsr2Data::PrepareNewInputFile(unsigned int tempRun, bool calledFromGlobalMode) const { if (fRunVectorIter == fRunVector.end()) return false; @@ -480,8 +535,13 @@ bool PMsr2Data::PrepareNewInputFile(unsigned int tempRun) const if (*fRunVectorIter == tempRun) return true; + string globalTag(""); + if (calledFromGlobalMode) + globalTag = "-OneRunFit"; + ostringstream strInfile; - strInfile << tempRun << fFileExtension << ".msr"; + strInfile << tempRun << globalTag << fFileExtension << ".msr"; + ifstream in(strInfile.str().c_str()); if (!in) { cerr << endl << ">> msr2data: **ERROR** The template msr-file " << strInfile.str() << " cannot be opened! Please check!"; @@ -489,7 +549,7 @@ bool PMsr2Data::PrepareNewInputFile(unsigned int tempRun) const return false; } ostringstream strOutfile; - strOutfile << *fRunVectorIter << fFileExtension << ".msr"; + strOutfile << *fRunVectorIter << globalTag << fFileExtension << ".msr"; ofstream out(strOutfile.str().c_str()); if (!out) { cerr << endl << ">> msr2data: **ERROR** The new msr file " << strOutfile.str() << " cannot be opened! Please check!"; @@ -598,8 +658,12 @@ bool compare_parameters(const PMsrParamStructure &par1, const PMsrParamStructure * * \param tempRun template run number * \param msrOutFile name of the global msr-file to be written + * \param globalPlus tag of the global mode to be used: + * - 0: simple global mode with the same template starting parameters for each run + * - 1: global mode including single run fits and data extraction for the global msr-file (same template for all runs) + * - 2: global mode including single run fits and data extraction for the global msr-file (successive template generation) */ -bool PMsr2Data::PrepareGlobalInputFile(unsigned int tempRun, const string &msrOutFile) const +bool PMsr2Data::PrepareGlobalInputFile(unsigned int tempRun, const string &msrOutFile, unsigned int globalPlus) const { const TString alpha("alpha"), beta("beta"), norm("norm"), bkgfit("bkgfit"), lifetime("lifetime"); @@ -1189,8 +1253,61 @@ bool PMsr2Data::PrepareGlobalInputFile(unsigned int tempRun, const string &msrOu tempMap = 0; } + // if the global+ option is specified, generate new single run msr-files and fit them + // to obtain better starting parameter values for the global file + + if (globalPlus) { + // for the first file, prepare a sorted input from the internal data-structure + // if chain-fitting is used, the successive files are copied from the first + unsigned int oldTempRun(0); + bool firstrun(true); + bool success(true); + + while(fRunVectorIter != fRunVector.end()) { + if (firstrun || (globalPlus == 1)) + success = PrepareNewSortedInputFile(tempRun); + else + success = PrepareNewInputFile(oldTempRun, true); + if (firstrun) + firstrun = false; + oldTempRun = *fRunVectorIter; + + if (!success) { + cout << endl << ">> msr2data: **ERROR** Input file generation has not been successful! Quitting..." << endl; + return false; + } + + // and do the fitting + // check if MUSRFITPATH is set, if not issue a warning + string path; + try { + path = boost::lexical_cast(getenv("MUSRFITPATH")); + path.append("/"); + } + catch(boost::bad_lexical_cast &) { + cerr << endl << ">> msr2data: **WARNING** The MUSRFITPATH environment variable is not set!"; + cerr << endl << ">> msr2data: **WARNING** Please set it or at least ensure that musrfit can be found on the PATH!" << endl; + path = ""; + } + ostringstream oss; + oss << path << "musrfit" << " " << *fRunVectorIter << "-OneRunFit" << fFileExtension << ".msr"; + cout << endl << ">> msr2data: **INFO** Calling " << oss.str() << endl; + system(oss.str().c_str()); + + ++fRunVectorIter; + } + // set back the iterator to the first run + fRunVectorIter = fRunVector.begin(); + + cout << endl << ">> msr2data: **INFO** Continuing with the generation of the global input msr file " << msrOutFile << endl; + } + + // now go through the specified runs and add run-specific parameters and RUN blocks + PMsrHandler *singleRunMsrFile; + singleRunMsrFile = 0; + map commentsP, commentsR; TString tempTstr; ostringstream newRunNumber; @@ -1202,6 +1319,10 @@ bool PMsr2Data::PrepareGlobalInputFile(unsigned int tempRun, const string &msrOu //cout << "Number of run specific parameters: " << fNumSpecParam << endl; if (newRunNumber.str().compare(tempRunNumber.str())) { // first run number does not match the template run number + // in global+ mode, read in the single run msr-file + if (globalPlus) + singleRunMsrFile = GetSingleRunMsrFile(); + // substitute the template run-numbers in the parameter names for (unsigned int l(fNumGlobalParam); l < msrParamList->size(); ++l) { tempParamName = msrParamList->at(l).fName.Data(); @@ -1209,12 +1330,21 @@ bool PMsr2Data::PrepareGlobalInputFile(unsigned int tempRun, const string &msrOu if ( loc != string::npos ) { tempParamName.replace(loc, fRunNumberDigits, newRunNumber.str()); msrParamList->at(l).fName = tempParamName; + if (globalPlus && singleRunMsrFile) { + fMsrHandler->SetMsrParamValue(l, singleRunMsrFile->GetMsrParamList()->at(l).fValue); + fMsrHandler->SetMsrParamStep(l, singleRunMsrFile->GetMsrParamList()->at(l).fStep); + } } else { cerr << endl << ">> msr2data: **ERROR** The indices of the run specific parameters do not match the template run number!"; cerr << endl << ">> msr2data: **ERROR** This should not happen! Please report a bug!"; cerr << endl; } } + if (singleRunMsrFile) { + delete singleRunMsrFile; + singleRunMsrFile = 0; + } + // substitute the template run-numbers in the RUN names for (unsigned int i(0); i < fNumTempRunBlocks; ++i) { tempRunName = msrRunList->at(i).GetRunName()->Data(); @@ -1267,6 +1397,10 @@ bool PMsr2Data::PrepareGlobalInputFile(unsigned int tempRun, const string &msrOu newRunNumber.width(fRunNumberDigits); newRunNumber << *fRunVectorIter; + // in global+ mode, read in the single run msr-file + if (globalPlus) + singleRunMsrFile = GetSingleRunMsrFile(); + // add parameters for each run for (unsigned int l(0); l < fNumSpecParam; ++l) { msrParamList->push_back(msrParamList->at(fNumGlobalParam + runcounter*fNumSpecParam + l)); @@ -1276,12 +1410,20 @@ bool PMsr2Data::PrepareGlobalInputFile(unsigned int tempRun, const string &msrOu tempParamName.replace(loc, fRunNumberDigits, newRunNumber.str()); msrParamList->back().fName = tempParamName; msrParamList->back().fNo += fNumSpecParam; + if (globalPlus && singleRunMsrFile) { + fMsrHandler->SetMsrParamValue(msrParamList->size() - 1, singleRunMsrFile->GetMsrParamList()->at(fNumGlobalParam + l).fValue); + fMsrHandler->SetMsrParamStep(msrParamList->size() - 1, singleRunMsrFile->GetMsrParamList()->at(fNumGlobalParam + l).fStep); + } } else { cerr << endl << ">> msr2data: **ERROR** Something went wrong when appending new parameters!"; cerr << endl << ">> msr2data: **ERROR** This should not happen! Please report a bug!"; cerr << endl; } } + if (singleRunMsrFile) { + delete singleRunMsrFile; + singleRunMsrFile = 0; + } // add RUN blocks for each run for (unsigned int i(0); i < fNumTempRunBlocks; ++i) { @@ -1369,6 +1511,104 @@ bool PMsr2Data::PrepareGlobalInputFile(unsigned int tempRun, const string &msrOu return true; } +//------------------------------------------------------------- +/** + *

Generate a new msr-file for a single run in which the parameters are sorted for a global fit + * An internal sorted msr-file data structure has to be present. + * + *

return: + * - true if everything is OK + * - false otherwise + * + * \param tempRun template run number + */ +bool PMsr2Data::PrepareNewSortedInputFile(unsigned int tempRun) const +{ + + PMsrParamList *msrParamList(fMsrHandler->GetMsrParamList()); + PMsrRunList *msrRunList(fMsrHandler->GetMsrRunList()); + + // make a copy of the msr-file-data to be able to restore it after the operations (parameter name and run number changes) + PMsrParamList paramListCopy(*msrParamList); + PMsrRunList runListCopy(*msrRunList); + TString titleCopy(*(fMsrHandler->GetMsrTitle())); + + ostringstream tempRunNumber; + tempRunNumber.fill('0'); + tempRunNumber.setf(ios::internal, ios::adjustfield); + tempRunNumber.width(fRunNumberDigits); + tempRunNumber << tempRun; + + ostringstream newRunNumber; + newRunNumber.fill('0'); + newRunNumber.setf(ios::internal, ios::adjustfield); + newRunNumber.width(fRunNumberDigits); + newRunNumber << *fRunVectorIter; + + string tempParamName, tempRunName; + TString tempTstr; + + ostringstream msrOutFile; + msrOutFile << *fRunVectorIter << "-OneRunFit" << fFileExtension << ".msr"; + cout << endl << ">> msr2data: **INFO** Generating new input msr file " << msrOutFile.str() << endl; + + tempTstr = TString(newRunNumber.str()); + fMsrHandler->SetMsrTitle(tempTstr); + + // remove the template run-numbers in the parameter names + for (unsigned int l(fNumGlobalParam); l < msrParamList->size(); ++l) { + tempParamName = msrParamList->at(l).fName.Data(); + string::size_type loc = tempParamName.rfind(tempRunNumber.str()); + if ( loc != string::npos ) { + tempParamName.erase(loc); + msrParamList->at(l).fName = tempParamName; + } else { + cerr << endl << ">> msr2data: **ERROR** The indices of the run specific parameters do not match the template run number!"; + cerr << endl << ">> msr2data: **ERROR** This should not happen! Please report a bug!"; + cerr << endl; + } + } + + if (newRunNumber.str().compare(tempRunNumber.str())) { // first run number does not match the template run number + // substitute the template run-numbers in the RUN names + for (unsigned int i(0); i < fNumTempRunBlocks; ++i) { + tempRunName = msrRunList->at(i).GetRunName()->Data(); + string::size_type loc = tempRunName.rfind(tempRunNumber.str()); + if ( loc != string::npos ) { + tempRunName.replace(loc, fRunNumberDigits, newRunNumber.str()); + tempTstr = TString(tempRunName); + msrRunList->at(i).SetRunName(tempTstr, 0); + } else { + cerr << endl << ">> msr2data: **ERROR** A template run file number does not match the \"file index\""; + cerr << endl << ">> msr2data: **ERROR** Please check the template file!"; + cerr << endl; + return false; + } + } + } + + // write the msr-file + int status = fMsrHandler->WriteMsrFile(msrOutFile.str().c_str()); + + // restore original msr-file-data + *msrParamList = paramListCopy; + *msrRunList = runListCopy; + fMsrHandler->SetMsrTitle(titleCopy); + + paramListCopy.clear(); + runListCopy.clear(); + titleCopy.Clear(); + + if (status != PMUSR_SUCCESS) { + cerr << endl << ">> msr2data: **ERROR** Writing the new msr-file has not been successful!"; + cerr << endl; + return false; + } + + return true; + +} + //------------------------------------------------------------- /** *

Append fit parameters of a msr-file to the DB or ASCII file diff --git a/src/include/PMsr2Data.h b/src/include/PMsr2Data.h index 4cc12bdb..993cf8a3 100644 --- a/src/include/PMsr2Data.h +++ b/src/include/PMsr2Data.h @@ -63,19 +63,22 @@ class PMsr2Data int SetRunNumbers(const vector&); // explicit run list specified using [ ] unsigned int GetPresentRun() const; - int DetermineRunNumberDigits(unsigned int) const; + int DetermineRunNumberDigits(unsigned int, bool) const; int CheckRunNumbersInRange() const; int ParseXmlStartupFile(); int ReadMsrFile(const string&) const; bool ReadRunDataFile(); - bool PrepareNewInputFile(unsigned int) const; // template - bool PrepareGlobalInputFile(unsigned int, const string&) const; // generate msr-input file for a global fit + bool PrepareNewInputFile(unsigned int, bool) const; // template + bool PrepareGlobalInputFile(unsigned int, const string&, unsigned int) const; // generate msr-input file for a global fit int WriteOutput(const string&, bool, bool, bool global = false, unsigned int counter = 0) const; private: + bool PrepareNewSortedInputFile(unsigned int) const; // template + PMsrHandler* GetSingleRunMsrFile() const; + string fFileExtension; vector fRunVector; mutable vector::const_iterator fRunVectorIter; diff --git a/src/msr2data.cpp b/src/msr2data.cpp index 1ee98387..a2044218 100644 --- a/src/msr2data.cpp +++ b/src/msr2data.cpp @@ -77,13 +77,13 @@ bool isNumber(const string &s) */ void msr2data_syntax() { - cout << endl << "usage 1: msr2data [-o] [data] [noheader] [nosummary] [global]"; + cout << endl << "usage 1: msr2data [-o] [data] [noheader] [nosummary] [global[+[!]]]"; cout << endl << " [fit [-k] [-t] | fit-