/*************************************************************************** PMsrHandler.cpp Author: Andreas Suter e-mail: andreas.suter@psi.ch ***************************************************************************/ /*************************************************************************** * Copyright (C) 2007-2014 by Andreas Suter * * andreas.suter@psi.ch * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program; if not, write to the * * Free Software Foundation, Inc., * * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * ***************************************************************************/ #include #include #include #include using namespace std; #include #include #include #include #include "PMusr.h" #include "PMsrHandler.h" //-------------------------------------------------------------------------- // Constructor //-------------------------------------------------------------------------- /** *

Constructor * * \param fileName name of a msr-file. */ PMsrHandler::PMsrHandler(const Char_t *fileName, PStartupOptions *startupOptions, const Bool_t fourierOnly) : fFourierOnly(fourierOnly), fStartupOptions(startupOptions), fFileName(fileName) { // init variables fMsrBlockCounter = 0; fTitle = ""; fCopyStatisticsBlock = false; fStatistic.fValid = false; fStatistic.fChisq = true; fStatistic.fMin = -1.0; fStatistic.fNdf = 0; fStatistic.fMinExpected = 0.0; fStatistic.fMinExpectedPerHisto.clear(); fStatistic.fNdfPerHisto.clear(); fFuncHandler = 0; // check if the file name given is a path-file-name, and if yes, split it into path and file name. if (fFileName.Contains("/")) { Int_t idx = -1; while (fFileName.Index("/", idx+1) != -1) { idx = fFileName.Index("/", idx+1); } fMsrFileDirectoryPath = fFileName; fMsrFileDirectoryPath.Remove(idx+1); } else { fMsrFileDirectoryPath = "./"; } } //-------------------------------------------------------------------------- // Destructor //-------------------------------------------------------------------------- /** *

Destructor */ PMsrHandler::~PMsrHandler() { fParam.clear(); fTheory.clear(); fFunctions.clear(); fRuns.clear(); fCommands.clear(); fPlots.clear(); fStatistic.fStatLines.clear(); fStatistic.fMinExpectedPerHisto.clear(); fStatistic.fNdfPerHisto.clear(); fParamInUse.clear(); if (fFuncHandler) { delete fFuncHandler; fFuncHandler = 0; } } //-------------------------------------------------------------------------- // ReadMsrFile (public) //-------------------------------------------------------------------------- /** *

Reads and parses a msr-file. * *

return: * - PMUSR_SUCCESS if everything is OK * - line number if an error in the MSR file was encountered which cannot be handled. */ Int_t PMsrHandler::ReadMsrFile() { ifstream f; string str; TString line; Int_t line_no = 0; Int_t result = PMUSR_SUCCESS; PMsrLineStructure current; PMsrLines fit_parameter; PMsrLines theory; PMsrLines functions; PMsrLines global; PMsrLines run; PMsrLines commands; PMsrLines fourier; PMsrLines plot; PMsrLines statistic; // init stuff InitFourierParameterStructure(fFourier); // open msr-file f.open(fFileName.Data(), iostream::in); if (!f.is_open()) { return PMUSR_MSR_FILE_NOT_FOUND; } fMsrBlockCounter = -1; // no msr block // read msr-file while (!f.eof()) { // read a line getline(f, str); line = str.c_str(); line_no++; current.fLineNo = line_no; current.fLine = line; if (line.BeginsWith("#") || line.IsWhitespace()) { // if the line is a comment/empty go to the next one continue; } if (!line.IsWhitespace()) { // if not an empty line, handle it // check for a msr block if (line_no == 1) { // title fTitle = line; } else if (line.BeginsWith("FITPARAMETER")) { // FITPARAMETER block tag fMsrBlockCounter = MSR_TAG_FITPARAMETER; } else if (line.BeginsWith("THEORY")) { // THEORY block tag fMsrBlockCounter = MSR_TAG_THEORY; theory.push_back(current); } else if (line.BeginsWith("FUNCTIONS")) { // FUNCTIONS block tag fMsrBlockCounter = MSR_TAG_FUNCTIONS; functions.push_back(current); } else if (line.BeginsWith("GLOBAL")) { // GLOBAL block tag fMsrBlockCounter = MSR_TAG_GLOBAL; global.push_back(current); } else if (line.BeginsWith("RUN")) { // RUN block tag fMsrBlockCounter = MSR_TAG_RUN; run.push_back(current); } else if (line.BeginsWith("COMMANDS")) { // COMMANDS block tag fMsrBlockCounter = MSR_TAG_COMMANDS; commands.push_back(current); } else if (line.BeginsWith("FOURIER")) { // FOURIER block tag fMsrBlockCounter = MSR_TAG_FOURIER; fourier.push_back(current); } else if (line.BeginsWith("PLOT")) { // PLOT block tag fMsrBlockCounter = MSR_TAG_PLOT; plot.push_back(current); } else if (line.BeginsWith("STATISTIC")) { // STATISTIC block tag fMsrBlockCounter = MSR_TAG_STATISTIC; statistic.push_back(current); } else { // the read line is some real stuff switch (fMsrBlockCounter) { case MSR_TAG_FITPARAMETER: // FITPARAMETER block fit_parameter.push_back(current); break; case MSR_TAG_THEORY: // THEORY block theory.push_back(current); break; case MSR_TAG_FUNCTIONS: // FUNCTIONS block functions.push_back(current); break; case MSR_TAG_GLOBAL: // GLOBAL block global.push_back(current); break; case MSR_TAG_RUN: // RUN block run.push_back(current); break; case MSR_TAG_COMMANDS: // COMMANDS block commands.push_back(current); break; case MSR_TAG_FOURIER: // FOURIER block fourier.push_back(current); break; case MSR_TAG_PLOT: // PLOT block plot.push_back(current); break; case MSR_TAG_STATISTIC: // STATISTIC block statistic.push_back(current); break; default: break; } } } } // close msr-file f.close(); // execute handler of the various blocks if (!HandleFitParameterEntry(fit_parameter)) result = PMUSR_MSR_SYNTAX_ERROR; if (result == PMUSR_SUCCESS) if (!HandleTheoryEntry(theory)) result = PMUSR_MSR_SYNTAX_ERROR; if (result == PMUSR_SUCCESS) if (!HandleFunctionsEntry(functions)) result = PMUSR_MSR_SYNTAX_ERROR; if (result == PMUSR_SUCCESS) if (!HandleGlobalEntry(global)) result = PMUSR_MSR_SYNTAX_ERROR; if (result == PMUSR_SUCCESS) if (!HandleRunEntry(run)) result = PMUSR_MSR_SYNTAX_ERROR; if (result == PMUSR_SUCCESS) if (!HandleCommandsEntry(commands)) result = PMUSR_MSR_SYNTAX_ERROR; if (result == PMUSR_SUCCESS) if (!HandleFourierEntry(fourier)) result = PMUSR_MSR_SYNTAX_ERROR; if (result == PMUSR_SUCCESS) if (!HandlePlotEntry(plot)) result = PMUSR_MSR_SYNTAX_ERROR; if (result == PMUSR_SUCCESS) if (!HandleStatisticEntry(statistic)) result = PMUSR_MSR_SYNTAX_ERROR; // check if chisq or max.log likelihood fStatistic.fChisq = true; for (UInt_t i=0; i> PMsrHandler::ReadMsrFile: **SEVERE ERROR** parameter name " << fParam[parX].fName.Data() << " is identical for parameter no " << fParam[parX].fNo << " and " << fParam[parY].fNo << "!"; cerr << endl << ">> Needs to be fixed first!"; cerr << endl; result = PMUSR_MSR_SYNTAX_ERROR; } } // check that if maps are present in the theory- and/or function-block, // that there are really present in the run block if ((result == PMUSR_SUCCESS) && !fFourierOnly) if (!CheckMaps()) result = PMUSR_MSR_SYNTAX_ERROR; // check that if functions are present in the theory- and/or run-block, that they // are really present in the function block if (result == PMUSR_SUCCESS) if (!CheckFuncs()) result = PMUSR_MSR_SYNTAX_ERROR; // check that if histogram grouping is present that it makes any sense if (result == PMUSR_SUCCESS) if (!CheckHistoGrouping()) result = PMUSR_MSR_SYNTAX_ERROR; // check that if addrun is present that the given parameter make any sense if (result == PMUSR_SUCCESS) if (!CheckAddRunParameters()) result = PMUSR_MSR_SYNTAX_ERROR; if (result == PMUSR_SUCCESS) { CheckMaxLikelihood(); // check if the user wants to use max likelihood with asymmetry/non-muSR fit (which is not implemented) CheckLegacyLifetimecorrection(); // check if lifetimecorrection is found in RUN blocks, if yes transfer it to PLOT blocks } // clean up fit_parameter.clear(); theory.clear(); functions.clear(); global.clear(); run.clear(); commands.clear(); fourier.clear(); plot.clear(); statistic.clear(); return result; } //-------------------------------------------------------------------------- // WriteMsrLogFile (public) //-------------------------------------------------------------------------- /** *

Writes a mlog-file. * *

return: * - PMUSR_SUCCESS everything is OK * - PMUSR_MSR_LOG_FILE_WRITE_ERROR msr-/mlog-file couldn't be opened * - PMUSR_MSR_SYNTAX_ERROR a syntax error has been encountered * * \param messages if true some additional messages concerning the statistic block are written. * When using musrt0, messages will be set to false. */ Int_t PMsrHandler::WriteMsrLogFile(const Bool_t messages) { const UInt_t prec = 6; // default output precision for float/doubles UInt_t neededPrec = 0; UInt_t neededWidth = 9; Int_t tag, lineNo = 0, number; Int_t runNo = -1, addRunNo = 0; Int_t plotNo = -1; string line; TString logFileName, str, sstr, *pstr; TObjArray *tokens = 0; TObjString *ostr = 0; Bool_t found = false; Bool_t statisticBlockFound = false; Bool_t partialStatisticBlockFound = true; PBoolVector t0TagMissing; // needed for proper musrt0 handling for (UInt_t i=0; i addt0TagMissing; // needed for proper musrt0 handling PBoolVector bvec; for (UInt_t i=0; iGetEntries() == 0) { // not a parameter line fout << str.Data() << endl; } else { ostr = dynamic_cast(tokens->At(0)); sstr = ostr->GetString(); if (sstr.IsDigit()) { // parameter number = sstr.Atoi(); number--; // make sure number makes sense assert ((number >= 0) && (number < (Int_t)fParam.size())); // parameter no fout.width(9); fout << right << fParam[number].fNo; fout << " "; // parameter name fout.width(11); fout << left << fParam[number].fName.Data(); fout << " "; // value of the parameter if (fParam[number].fStep == 0.0) // if fixed parameter take all significant digits neededPrec = LastSignificant(fParam[number].fValue); else // step/neg.error given hence they will limited the output precission of the value neededPrec = NeededPrecision(fParam[number].fStep)+1; if ((fParam[number].fStep != 0.0) && fParam[number].fPosErrorPresent && (NeededPrecision(fParam[number].fPosError)+1 > neededPrec)) neededPrec = NeededPrecision(fParam[number].fPosError)+1; if (neededPrec < 6) neededWidth = 9; else neededWidth = neededPrec + 3; fout.width(neededWidth); fout.setf(ios::fixed, ios::floatfield); fout.precision(neededPrec); fout << left << fParam[number].fValue; fout << " "; // value of step/error/neg.error fout.width(11); fout.setf(ios::fixed); if (fParam[number].fStep == 0.0) neededPrec = 0; fout.precision(neededPrec); fout << left << fParam[number].fStep; fout << " "; fout.width(11); fout.setf(ios::fixed); fout.precision(neededPrec); if ((fParam[number].fNoOfParams == 5) || (fParam[number].fNoOfParams == 7)) // pos. error given if (fParam[number].fPosErrorPresent && (fParam[number].fStep != 0)) // pos error is a number fout << left << fParam[number].fPosError; else // pos error is a none fout << left << "none"; else // no pos. error fout << left << "none"; fout << " "; fout.unsetf(ios::floatfield); // boundaries if (fParam[number].fNoOfParams > 5) { fout.width(7); fout.precision(prec); if (fParam[number].fLowerBoundaryPresent) fout << left << fParam[number].fLowerBoundary; else fout << left << "none"; fout << " "; fout.width(7); fout.precision(prec); if (fParam[number].fUpperBoundaryPresent) fout << left << fParam[number].fUpperBoundary; else fout << left << "none"; fout << " "; } fout << endl; } else { // not a parameter, hence just copy it fout << str.Data() << endl; } // clean up tokens delete tokens; } break; case MSR_TAG_THEORY: found = false; for (UInt_t i=0; iGetFuncString(idx); sstr.ToLower(); fout << sstr.Data() << endl; } } else { fout << str.Data() << endl; } break; case MSR_TAG_GLOBAL: sstr = str; if (sstr.BeginsWith("fittype")) { fout.width(16); switch (fGlobal.GetFitType()) { case MSR_FITTYPE_SINGLE_HISTO: fout << left << "fittype" << MSR_FITTYPE_SINGLE_HISTO << " (single histogram fit)" << endl; break; case MSR_FITTYPE_ASYM: fout << left << "fittype" << MSR_FITTYPE_ASYM << " (asymmetry fit)" << endl ; break; case MSR_FITTYPE_MU_MINUS: fout << left << "fittype" << MSR_FITTYPE_MU_MINUS << " (mu minus fit)" << endl ; break; case MSR_FITTYPE_NON_MUSR: fout << left << "fittype" << MSR_FITTYPE_NON_MUSR << " (non muSR fit)" << endl ; break; default: break; } } else if (sstr.BeginsWith("data")) { fout.width(16); fout << left << "data"; for (UInt_t j=0; j<4; j++) { if (fGlobal.GetDataRange(j) > 0) { fout.width(8); fout << left << fGlobal.GetDataRange(j); } } fout << endl; } else if (sstr.BeginsWith("t0")) { fout.width(16); fout << left << "t0"; for (UInt_t j=0; j 0) fout << "+" << fGlobal.GetFitRangeOffset(0); fout << " lgb"; if (fGlobal.GetFitRangeOffset(1) > 0) fout << "-" << fGlobal.GetFitRangeOffset(1); neededPrec = LastSignificant(fGlobal.GetFitRange(0)); if (LastSignificant(fGlobal.GetFitRange(1)) > neededPrec) neededPrec = LastSignificant(fGlobal.GetFitRange(1)); fout.precision(neededPrec); fout << " # in time: " << fGlobal.GetFitRange(0) << ".." << fGlobal.GetFitRange(1) << " (usec)"; } else { // fit range given in time for (UInt_t j=0; j<2; j++) { if (fGlobal.GetFitRange(j) == -1) break; neededWidth = 7; neededPrec = LastSignificant(fGlobal.GetFitRange(j)); fout.width(neededWidth); fout.precision(neededPrec); fout << left << fixed << fGlobal.GetFitRange(j); if (j==0) fout << " "; } } fout << endl; } else if (sstr.BeginsWith("packing")) { fout.width(16); fout << left << "packing"; fout << fGlobal.GetPacking() << endl; } else { fout << str.Data() << endl; } break; case MSR_TAG_RUN: sstr = str; sstr.Remove(TString::kLeading, ' '); if (sstr.BeginsWith("RUN")) { addRunNo = 0; // reset counter fout << "RUN " << fRuns[runNo].GetRunName()->Data() << " "; pstr = fRuns[runNo].GetBeamline(); if (pstr == 0) { cerr << endl << ">> PMsrHandler::WriteMsrLogFile: **ERROR** Couldn't obtain beamline data." << endl; assert(0); } pstr->ToUpper(); fout << pstr->Data() << " "; pstr = fRuns[runNo].GetInstitute(); if (pstr == 0) { cerr << endl << ">> PMsrHandler::WriteMsrLogFile: **ERROR** Couldn't obtain institute data." << endl; assert(0); } pstr->ToUpper(); fout << pstr->Data() << " "; pstr = fRuns[runNo].GetFileFormat(); if (pstr == 0) { cerr << endl << ">> PMsrHandler::WriteMsrLogFile: **ERROR** Couldn't obtain file format data." << endl; assert(0); } pstr->ToUpper(); fout << pstr->Data() << " (name beamline institute data-file-format)" << endl; } else if (sstr.BeginsWith("ADDRUN")) { addRunNo++; fout << "ADDRUN " << fRuns[runNo].GetRunName(addRunNo)->Data() << " "; pstr = fRuns[runNo].GetBeamline(addRunNo); if (pstr == 0) { cerr << endl << ">> PMsrHandler::WriteMsrLogFile: **ERROR** Couldn't obtain beamline data (addrun)." << endl; assert(0); } pstr->ToUpper(); fout << pstr->Data() << " "; pstr = fRuns[runNo].GetInstitute(addRunNo); if (pstr == 0) { cerr << endl << ">> PMsrHandler::WriteMsrLogFile: **ERROR** Couldn't obtain institute data (addrun)." << endl; assert(0); } pstr->ToUpper(); fout << pstr->Data() << " "; pstr = fRuns[runNo].GetFileFormat(addRunNo); if (pstr == 0) { cerr << endl << ">> PMsrHandler::WriteMsrLogFile: **ERROR** Couldn't obtain file format data (addrun)." << endl; assert(0); } pstr->ToUpper(); fout << pstr->Data() << " (name beamline institute data-file-format)" << endl; } else if (sstr.BeginsWith("fittype")) { fout.width(16); switch (fRuns[runNo].GetFitType()) { case MSR_FITTYPE_SINGLE_HISTO: fout << left << "fittype" << MSR_FITTYPE_SINGLE_HISTO << " (single histogram fit)" << endl; break; case MSR_FITTYPE_ASYM: fout << left << "fittype" << MSR_FITTYPE_ASYM << " (asymmetry fit)" << endl ; break; case MSR_FITTYPE_MU_MINUS: fout << left << "fittype" << MSR_FITTYPE_MU_MINUS << " (mu minus fit)" << endl ; break; case MSR_FITTYPE_NON_MUSR: fout << left << "fittype" << MSR_FITTYPE_NON_MUSR << " (non muSR fit)" << endl ; break; default: break; } } else if (sstr.BeginsWith("alpha ")) { fout.width(16); fout << left << "alpha"; fout << fRuns[runNo].GetAlphaParamNo() << endl; } else if (sstr.BeginsWith("beta ")) { fout.width(16); fout << left << "beta"; fout << fRuns[runNo].GetBetaParamNo() << endl; } else if (sstr.BeginsWith("norm")) { fout.width(16); fout << left << "norm"; // check if norm is give as a function if (fRuns[runNo].GetNormParamNo() >= MSR_PARAM_FUN_OFFSET) fout << "fun" << fRuns[runNo].GetNormParamNo()-MSR_PARAM_FUN_OFFSET; else fout << fRuns[runNo].GetNormParamNo(); fout << endl; } else if (sstr.BeginsWith("backgr.fit")) { fout.width(16); fout << left << "backgr.fit"; fout << fRuns[runNo].GetBkgFitParamNo() << endl; } else if (sstr.BeginsWith("lifetime ")) { fout.width(16); fout << left << "lifetime"; fout << fRuns[runNo].GetLifetimeParamNo() << endl; } else if (sstr.BeginsWith("lifetimecorrection")) { /* obsolate, hence do nothing here if ((fRuns[runNo].IsLifetimeCorrected()) && ((fRuns[runNo].GetFitType() == MSR_FITTYPE_SINGLE_HISTO) || (fGlobal.GetFitType() == MSR_FITTYPE_SINGLE_HISTO))) { fout << "lifetimecorrection" << endl; } */ } else if (sstr.BeginsWith("map")) { fout << "map "; for (UInt_t j=0; jsize(); j++) { fout.width(5); fout << right << fRuns[runNo].GetMap(j); } // if there are less maps then 10 fill with zeros if (fRuns[runNo].GetMap()->size() < 10) { for (UInt_t j=fRuns[runNo].GetMap()->size(); j<10; j++) fout << " 0"; } fout << endl; } else if (sstr.BeginsWith("forward")) { if (fRuns[runNo].GetForwardHistoNoSize() == 0) { cerr << endl << ">> PMsrHandler::WriteMsrLogFile: **WARNING** 'forward' tag without any data found!"; cerr << endl << ">> Something is VERY fishy, please check your msr-file carfully." << endl; } else { TString result(""); PIntVector forward; for (UInt_t i=0; i> PMsrHandler::WriteMsrLogFile: **WARNING** 'backward' tag without any data found!"; cerr << endl << ">> Something is VERY fishy, please check your msr-file carfully." << endl; } else { TString result(""); PIntVector backward; for (UInt_t i=0; i 0) { fout.width(8); fout << left << fRuns[runNo].GetBkgRange(j); } } if (fRuns[runNo].GetBkgEstimated(0) != PMUSR_UNDEFINED) { Int_t precision=4; if ((Int_t)log10(fRuns[runNo].GetBkgEstimated(0))+1 >= 4) precision = 2; fout << " # estimated bkg: "; fout << fixed; fout.precision(precision); fout << fRuns[runNo].GetBkgEstimated(0); if (fRuns[runNo].GetBkgEstimated(1) != PMUSR_UNDEFINED) { fout << " / "; fout << fixed; fout.precision(precision); fout << fRuns[runNo].GetBkgEstimated(1); } } fout << endl; } else if (sstr.BeginsWith("data")) { dataTagMissing[runNo] = false; fout.width(16); fout << left << "data"; for (UInt_t j=0; j<4; j++) { if (fRuns[runNo].GetDataRange(j) > 0) { fout.width(8); fout << left << fRuns[runNo].GetDataRange(j); } } fout << endl; } else if (sstr.BeginsWith("t0")) { t0TagMissing[runNo] = false; fout.width(16); fout << left << "t0"; for (UInt_t j=0; j> PMsrHandler::WriteMsrLogFile: **WARNING** 'addt0' tag without any data found!"; cerr << endl << ">> Something is VERY fishy, please check your msr-file carfully." << endl; } else { fout.width(16); fout << left << "addt0"; for (Int_t j=0; jIsWhitespace()) { // labels fout.width(16); fout << left << "xy-data"; fout.width(8); fout << left << fixed << fRuns[runNo].GetXDataLabel()->Data(); fout << " "; fout.width(8); fout << left << fixed << fRuns[runNo].GetYDataLabel()->Data(); fout << endl; } } else if (sstr.BeginsWith("fit")) { // check if missing t0/addt0/background/data tag are present eventhough the values are present, if so write these data values // if ISIS data, do not do anything if (t0TagMissing[runNo] && fRuns[runNo].GetInstitute()->CompareTo("isis", TString::kIgnoreCase)) { if (fRuns[runNo].GetT0BinSize() > 0) { fout.width(16); fout << left << "t0"; for (UInt_t j=0; jCompareTo("isis", TString::kIgnoreCase)) { if (fRuns[runNo].GetAddT0BinSize(i) > 0) { fout.width(16); fout << left << "addt0"; for (Int_t j=0; j= 0) { fout.width(16); fout << left << "background"; for (UInt_t j=0; j<4; j++) { if (fRuns[runNo].GetBkgRange(j) > 0) { fout.width(8); fout << left << fRuns[runNo].GetBkgRange(j); } } fout << endl; } } if (dataTagMissing[runNo]) { if (fRuns[runNo].GetDataRange(0) >= 0) { fout.width(16); fout << left << "data"; for (UInt_t j=0; j<4; j++) { if (fRuns[runNo].GetDataRange(j) > 0) { fout.width(8); fout << left << fRuns[runNo].GetDataRange(j); } } fout << endl; } } // write fit range line fout.width(16); fout << left << "fit"; if (fRuns[runNo].IsFitRangeInBin()) { // fit range given in bins fout << "fgb"; if (fRuns[runNo].GetFitRangeOffset(0) > 0) fout << "+" << fRuns[runNo].GetFitRangeOffset(0); fout << " lgb"; if (fRuns[runNo].GetFitRangeOffset(1) > 0) fout << "-" << fRuns[runNo].GetFitRangeOffset(1); neededPrec = LastSignificant(fRuns[runNo].GetFitRange(0)); if (LastSignificant(fRuns[runNo].GetFitRange(1)) > neededPrec) neededPrec = LastSignificant(fRuns[runNo].GetFitRange(1)); fout.precision(neededPrec); fout << " # in time: " << fRuns[runNo].GetFitRange(0) << ".." << fRuns[runNo].GetFitRange(1) << " (usec)"; } else { // fit range given in time for (UInt_t j=0; j<2; j++) { if (fRuns[runNo].GetFitRange(j) == -1) break; neededWidth = 7; neededPrec = LastSignificant(fRuns[runNo].GetFitRange(j)); fout.width(neededWidth); fout.precision(neededPrec); fout << left << fixed << fRuns[runNo].GetFitRange(j); if (j==0) fout << " "; } } fout << endl; } else if (sstr.BeginsWith("packing")) { fout.width(16); fout << left << "packing"; fout << fRuns[runNo].GetPacking() << endl; } else { fout << str.Data() << endl; } break; case MSR_TAG_COMMANDS: fout << str.Data() << endl; break; case MSR_TAG_FOURIER: sstr = str; sstr.Remove(TString::kLeading, ' '); if (sstr.BeginsWith("units")) { fout << "units "; if (fFourier.fUnits == FOURIER_UNIT_GAUSS) { fout << "Gauss"; } else if (fFourier.fUnits == FOURIER_UNIT_TESLA) { fout << "Tesla"; } else if (fFourier.fUnits == FOURIER_UNIT_FREQ) { fout << "MHz "; } else if (fFourier.fUnits == FOURIER_UNIT_CYCLES) { fout << "Mc/s"; } fout << " # units either 'Gauss', 'Tesla', 'MHz', or 'Mc/s'"; fout << endl; } else if (sstr.BeginsWith("fourier_power")) { fout << "fourier_power " << fFourier.fFourierPower << endl; } else if (sstr.BeginsWith("dc-corrected")) { fout << "dc-corrected "; if (fFourier.fDCCorrected == true) fout << "true" << endl; else fout << "false" << endl; } else if (sstr.BeginsWith("apodization")) { fout << "apodization "; if (fFourier.fApodization == FOURIER_APOD_NONE) { fout << "NONE "; } else if (fFourier.fApodization == FOURIER_APOD_WEAK) { fout << "WEAK "; } else if (fFourier.fApodization == FOURIER_APOD_MEDIUM) { fout << "MEDIUM"; } else if (fFourier.fApodization == FOURIER_APOD_STRONG) { fout << "STRONG"; } fout << " # NONE, WEAK, MEDIUM, STRONG"; fout << endl; } else if (sstr.BeginsWith("plot")) { fout << "plot "; if (fFourier.fPlotTag == FOURIER_PLOT_REAL) { fout << "REAL "; } else if (fFourier.fPlotTag == FOURIER_PLOT_IMAG) { fout << "IMAG "; } else if (fFourier.fPlotTag == FOURIER_PLOT_REAL_AND_IMAG) { fout << "REAL_AND_IMAG"; } else if (fFourier.fPlotTag == FOURIER_PLOT_POWER) { fout << "POWER"; } else if (fFourier.fPlotTag == FOURIER_PLOT_PHASE) { fout << "PHASE"; } fout << " # REAL, IMAG, REAL_AND_IMAG, POWER, PHASE"; fout << endl; } else if (sstr.BeginsWith("phase")) { if (fFourier.fPhaseParamNo > 0) { fout << "phase par" << fFourier.fPhaseParamNo << endl; } else { if (fFourier.fPhase != -999.0) { fout << "phase " << fFourier.fPhase << endl; } } } else if (sstr.BeginsWith("range_for_phase_correction")) { fout << "range_for_phase_correction " << fFourier.fRangeForPhaseCorrection[0] << " " << fFourier.fRangeForPhaseCorrection[1] << endl; } else if (sstr.BeginsWith("range ")) { fout << "range " << fFourier.fPlotRange[0] << " " << fFourier.fPlotRange[1] << endl; } else { fout << str.Data() << endl; } break; case MSR_TAG_PLOT: sstr = str; sstr.Remove(TString::kLeading, ' '); if (sstr.BeginsWith("PLOT")) { switch (fPlots[plotNo].fPlotType) { case MSR_PLOT_SINGLE_HISTO: fout << "PLOT " << fPlots[plotNo].fPlotType << " (single histo plot)" << endl; break; case MSR_PLOT_ASYM: fout << "PLOT " << fPlots[plotNo].fPlotType << " (asymmetry plot)" << endl; break; case MSR_PLOT_MU_MINUS: fout << "PLOT " << fPlots[plotNo].fPlotType << " (mu minus plot)" << endl; break; case MSR_PLOT_NON_MUSR: fout << "PLOT " << fPlots[plotNo].fPlotType << " (non muSR plot)" << endl; break; default: break; } if (fPlots[plotNo].fLifeTimeCorrection) { fout << "lifetimecorrection" << endl; } } else if (sstr.BeginsWith("lifetimecorrection")) { // do nothing, since it is already handled in the lines above. // The reason why this handled that oddly is due to legacy issues // of this flag, i.e. transfer from RUN -> PLOT } else if (sstr.BeginsWith("runs")) { fout << "runs "; fout.precision(0); for (UInt_t j=0; j 0) { fout << " "; neededPrec = LastSignificant(fPlots[plotNo].fYmin[0]); fout.precision(neededPrec); fout << fPlots[plotNo].fYmin[0] << " "; neededPrec = LastSignificant(fPlots[plotNo].fYmax[0]); fout.precision(neededPrec); fout << fPlots[plotNo].fYmax[0]; } fout << endl; } else { fout << str.Data() << endl; } break; case MSR_TAG_STATISTIC: statisticBlockFound = true; sstr = str; sstr.Remove(TString::kLeading, ' '); if (sstr.BeginsWith("STATISTIC")) { TDatime dt; fout << "STATISTIC --- " << dt.AsSQLString() << endl; } else if (sstr.BeginsWith("chisq") || sstr.BeginsWith("maxLH")) { partialStatisticBlockFound = false; if (fStatistic.fValid) { // valid fit result if (fStatistic.fChisq) { str.Form(" chisq = %.1lf, NDF = %d, chisq/NDF = %lf", fStatistic.fMin, fStatistic.fNdf, fStatistic.fMin / fStatistic.fNdf); fout << str.Data() << endl; if (messages) cout << endl << str.Data() << endl; // check if expected chisq needs to be written if (fStatistic.fMinExpected != 0.0) { str.Form(" expected chisq = %.1lf, NDF = %d, expected chisq/NDF = %lf", fStatistic.fMinExpected, fStatistic.fNdf, fStatistic.fMinExpected/fStatistic.fNdf); if (fStartupOptions) { if (fStartupOptions->writeExpectedChisq) fout << str.Data() << endl; } if (messages) cout << endl << str.Data() << endl; for (UInt_t i=0; i 0) { str.Form(" run block %d: (NDF/red.chisq/red.chisq_e) = (%d/%lf/%lf)", i+1, fStatistic.fNdfPerHisto[i], fStatistic.fMinPerHisto[i]/fStatistic.fNdfPerHisto[i], fStatistic.fMinExpectedPerHisto[i]/fStatistic.fNdfPerHisto[i]); if (fStartupOptions) { if (fStartupOptions->writeExpectedChisq) fout << str.Data() << endl; } if (messages) cout << str.Data() << endl; } } } else if (fStatistic.fNdfPerHisto.size() > 1) { // check if per run chisq needs to be written for (UInt_t i=0; iwriteExpectedChisq) fout << str.Data() << endl; } if (messages) cout << str.Data() << endl; } } } else { // maxLH str.Form(" maxLH = %.1lf, NDF = %d, maxLH/NDF = %lf", fStatistic.fMin, fStatistic.fNdf, fStatistic.fMin / fStatistic.fNdf); fout << str.Data() << endl; if (messages) cout << endl << str.Data() << endl; } } else { fout << "*** FIT DID NOT CONVERGE ***" << endl; if (messages) cout << endl << "*** FIT DID NOT CONVERGE ***" << endl; } } else if (sstr.BeginsWith("*** FIT DID NOT CONVERGE ***")) { partialStatisticBlockFound = false; if (fStatistic.fValid) { // valid fit result if (fStatistic.fChisq) { // chisq str.Form(" chisq = %.1lf, NDF = %d, chisq/NDF = %lf", fStatistic.fMin, fStatistic.fNdf, fStatistic.fMin / fStatistic.fNdf); fout << str.Data() << endl; if (messages) cout << endl << str.Data() << endl; // check if expected chisq needs to be written if (fStatistic.fMinExpected != 0.0) { str.Form(" expected chisq = %.1lf, NDF = %d, expected chisq/NDF = %lf", fStatistic.fMinExpected, fStatistic.fNdf, fStatistic.fMinExpected/fStatistic.fNdf); if (fStartupOptions) { if (fStartupOptions->writeExpectedChisq) fout << str.Data() << endl; } if (messages) cout << str.Data() << endl; for (UInt_t i=0; i 0) { str.Form(" run block %d: (NDF/red.chisq/red.chisq_e) = (%d/%lf/%lf)", i+1, fStatistic.fNdfPerHisto[i], fStatistic.fMinPerHisto[i]/fStatistic.fNdfPerHisto[i], fStatistic.fMinExpectedPerHisto[i]/fStatistic.fNdfPerHisto[i]); if (fStartupOptions) { if (fStartupOptions->writeExpectedChisq) fout << str.Data() << endl; } if (messages) cout << str.Data() << endl; } } } else if (fStatistic.fNdfPerHisto.size() > 1) { // check if per run chisq needs to be written for (UInt_t i=0; iwriteExpectedChisq) fout << str.Data() << endl; } if (messages) cout << str.Data() << endl; } } } else { // max. log. liklihood str.Form(" maxLH = %.1lf, NDF = %d, maxLH/NDF = %lf", fStatistic.fMin, fStatistic.fNdf, fStatistic.fMin / fStatistic.fNdf); fout << str.Data() << endl; if (messages) cout << endl << str.Data() << endl; } } else { fout << "*** FIT DID NOT CONVERGE ***" << endl; if (messages) cout << endl << "*** FIT DID NOT CONVERGE ***" << endl; } } else { if (str.Length() > 0) { sstr = str; sstr.Remove(TString::kLeading, ' '); if (!sstr.BeginsWith("expected chisq") && !sstr.BeginsWith("run block")) fout << str.Data() << endl; } else { // only write endl if not eof is reached. This is preventing growing msr-files, i.e. more and more empty lines at the end of the file if (!fin.eof()) fout << endl; } } break; default: break; } } // there was no statistic block present in the msr-input-file if (!statisticBlockFound) { partialStatisticBlockFound = false; cerr << endl << ">> PMsrHandler::WriteMsrLogFile: **WARNING** no STATISTIC block present, will write a default one" << endl; fout << "###############################################################" << endl; TDatime dt; fout << "STATISTIC --- " << dt.AsSQLString() << endl; if (fStatistic.fValid) { // valid fit result if (fStatistic.fChisq) { str.Form(" chisq = %.1lf, NDF = %d, chisq/NDF = %lf", fStatistic.fMin, fStatistic.fNdf, fStatistic.fMin / fStatistic.fNdf); fout << str.Data() << endl; if (messages) cout << endl << str.Data() << endl; // check if expected chisq needs to be written if (fStatistic.fMinExpected != 0.0) { str.Form(" expected chisq = %.1lf, NDF = %d, expected chisq/NDF = %lf", fStatistic.fMinExpected, fStatistic.fNdf, fStatistic.fMinExpected/fStatistic.fNdf); if (fStartupOptions) { if (fStartupOptions->writeExpectedChisq) fout << str.Data() << endl; } if (messages) cout << str.Data() << endl; for (UInt_t i=0; i 0) { str.Form(" run block %d: (NDF/red.chisq/red.chisq_e) = (%d/%lf/%lf)", i+1, fStatistic.fNdfPerHisto[i], fStatistic.fMinPerHisto[i]/fStatistic.fNdfPerHisto[i], fStatistic.fMinExpectedPerHisto[i]/fStatistic.fNdfPerHisto[i]); if (fStartupOptions) { if (fStartupOptions->writeExpectedChisq) fout << str.Data() << endl; } if (messages) cout << str.Data() << endl; } } } else if (fStatistic.fNdfPerHisto.size() > 1) { // check if per run chisq needs to be written for (UInt_t i=0; iwriteExpectedChisq) fout << str.Data() << endl; } if (messages) cout << str.Data() << endl; } } } else { // maxLH str.Form(" maxLH = %.1lf, NDF = %d, maxLH/NDF = %lf", fStatistic.fMin, fStatistic.fNdf, fStatistic.fMin / fStatistic.fNdf); fout << str.Data() << endl; if (messages) cout << endl << str.Data() << endl; // check if per run block maxLH needs to be written } } else { fout << "*** FIT DID NOT CONVERGE ***" << endl; if (messages) cout << endl << "*** FIT DID NOT CONVERGE ***" << endl; } } // there was only a partial statistic block present in the msr-input-file if (partialStatisticBlockFound) { cerr << endl << ">> PMsrHandler::WriteMsrLogFile: **WARNING** garbage STATISTIC block present in the msr-input file."; cerr << endl << ">> ** WILL ADD SOME SENSIBLE STUFF, BUT YOU HAVE TO CHECK IT SINCE I AM **NOT** REMOVING THE GARBAGE! **" << endl; TDatime dt; fout << "STATISTIC --- " << dt.AsSQLString() << endl; if (fStatistic.fValid) { // valid fit result if (fStatistic.fChisq) { // chisq str.Form(" chisq = %.1lf, NDF = %d, chisq/NDF = %lf", fStatistic.fMin, fStatistic.fNdf, fStatistic.fMin / fStatistic.fNdf); fout << str.Data() << endl; if (messages) cout << endl << str.Data() << endl; // check if expected chisq needs to be written if (fStatistic.fMinExpected != 0.0) { str.Form(" expected chisq = %.1lf, NDF = %d, expected chisq/NDF = %lf", fStatistic.fMinExpected, fStatistic.fNdf, fStatistic.fMinExpected/fStatistic.fNdf); if (fStartupOptions) { if (fStartupOptions->writeExpectedChisq) fout << str.Data() << endl; } if (messages) cout << str.Data() << endl; for (UInt_t i=0; i 0) { str.Form(" run block %d: (NDF/red.chisq/red.chisq_e) =(%d/%lf/%lf)", i+1, fStatistic.fNdfPerHisto[i], fStatistic.fMinExpectedPerHisto[i]/fStatistic.fNdfPerHisto[i], fStatistic.fMinExpectedPerHisto[i]/fStatistic.fNdfPerHisto[i]); if (fStartupOptions) { if (fStartupOptions->writeExpectedChisq) fout << str.Data() << endl; } if (messages) cout << str.Data() << endl; } } } else if (fStatistic.fNdfPerHisto.size() > 1) { // check if per run chisq needs to be written for (UInt_t i=0; iwriteExpectedChisq) fout << str.Data() << endl; } if (messages) cout << str.Data() << endl; } } } else { // max. log. liklihood str.Form(" maxLH = %.1lf, NDF = %d, maxLH/NDF = %lf", fStatistic.fMin, fStatistic.fNdf, fStatistic.fMin / fStatistic.fNdf); fout << str.Data() << endl; if (messages) cout << endl << str.Data() << endl; } } else { fout << "*** FIT DID NOT CONVERGE (4) ***" << endl; if (messages) cout << endl << "*** FIT DID NOT CONVERGE ***" << endl; } } // close files fout.close(); fin.close(); // clean up t0TagMissing.clear(); backgroundTagMissing.clear(); dataTagMissing.clear(); return PMUSR_SUCCESS; } //-------------------------------------------------------------------------- // WriteMsrFile (public) //-------------------------------------------------------------------------- /** *

Writes a msr-file from the internal data structures * *

return: * - PMUSR_SUCCESS everything is OK * - PMUSR_MSR_FILE_WRITE_ERROR msr output file couldn't be opened * * \param filename The name of the output file. */ Int_t PMsrHandler::WriteMsrFile(const Char_t *filename, map *commentsPAR, \ map *commentsTHE, \ map *commentsFUN, \ map *commentsRUN) { const UInt_t prec = 6; // output precision for float/doubles const TString hline = "###############################################################"; UInt_t i = 0; map::iterator iter; TString str, *pstr; // open output file for writing ofstream fout(filename); if (!fout) { return PMUSR_MSR_FILE_WRITE_ERROR; } // write TITLE fout << fTitle.Data() << endl; fout << hline.Data() << endl; // write FITPARAMETER block fout << "FITPARAMETER" << endl; fout << "# No Name Value Step Pos_Error Boundaries" << endl; for (i = 0; i < fParam.size(); ++i) { if (commentsPAR) { iter = commentsPAR->find(i+1); if (iter != commentsPAR->end()) { fout << endl; fout << "# " << iter->second.Data() << endl; fout << endl; commentsPAR->erase(iter); } } // parameter no fout.width(9); fout << right << fParam[i].fNo; fout << " "; // parameter name fout.width(11); fout << left << fParam[i].fName.Data(); fout << " "; // value of the parameter fout.width(9); fout.precision(prec); fout << left << fParam[i].fValue; fout << " "; // value of step/error/neg.error fout.width(11); fout.precision(prec); fout << left << fParam[i].fStep; fout << " "; fout.width(11); fout.precision(prec); if ((fParam[i].fNoOfParams == 5) || (fParam[i].fNoOfParams == 7)) // pos. error given if (fParam[i].fPosErrorPresent && (fParam[i].fStep != 0)) // pos error is a number fout << left << fParam[i].fPosError; else // pos error is a none fout << left << "none"; else // no pos. error fout << left << "none"; fout << " "; // boundaries if (fParam[i].fNoOfParams > 5) { fout.width(7); fout.precision(prec); if (fParam[i].fLowerBoundaryPresent) fout << left << fParam[i].fLowerBoundary; else fout << left << "none"; fout << " "; fout.width(7); fout.precision(prec); if (fParam[i].fUpperBoundaryPresent) fout << left << fParam[i].fUpperBoundary; else fout << left << "none"; fout << " "; } fout << endl; } if (commentsPAR && !commentsPAR->empty()) { fout << endl; for(iter = commentsPAR->begin(); iter != commentsPAR->end(); ++iter) { fout << "# " << iter->second.Data() << endl; } commentsPAR->clear(); } fout << endl; fout << hline.Data() << endl; // write THEORY block fout << "THEORY" << endl; for (i = 1; i < fTheory.size(); ++i) { if (commentsTHE) { iter = commentsTHE->find(i); if (iter != commentsTHE->end()) { fout << endl; fout << "# " << iter->second.Data() << endl; fout << endl; commentsTHE->erase(iter); } } fout << fTheory[i].fLine.Data() << endl; } if (commentsTHE && !commentsTHE->empty()) { fout << endl; for(iter = commentsTHE->begin(); iter != commentsTHE->end(); ++iter) { fout << "# " << iter->second.Data() << endl; } commentsTHE->clear(); } fout << endl; fout << hline.Data() << endl; // write FUNCTIONS block // or comment it if there is none in the data structures if (fFunctions.size() < 2) fout << "# "; fout << "FUNCTIONS" << endl; for (i = 1; i < fFunctions.size(); ++i) { if (commentsFUN) { iter = commentsFUN->find(i); if (iter != commentsFUN->end()) { fout << endl; fout << "# " << iter->second.Data() << endl; fout << endl; commentsFUN->erase(iter); } } fout << fFunctions[i].fLine.Data() << endl; } if (commentsFUN && !commentsFUN->empty()) { fout << endl; for(iter = commentsFUN->begin(); iter != commentsFUN->end(); ++iter) { fout << "# " << iter->second.Data() << endl; } commentsFUN->clear(); } fout << endl; fout << hline.Data() << endl; // write GLOBAL block if (fGlobal.IsPresent()) { // not sure that anything needs to be done here ... } // write RUN blocks for (i = 0; i < fRuns.size(); ++i) { if (commentsRUN) { iter = commentsRUN->find(i + 1); if (iter != commentsRUN->end()) { if (!i) fout << endl; fout << "# " << iter->second.Data() << endl; fout << endl; commentsRUN->erase(iter); } } fout << "RUN " << fRuns[i].GetRunName()->Data() << " "; pstr = fRuns[i].GetBeamline(); if (pstr == 0) { cerr << endl << ">> PMsrHandler::WriteMsrFile: **ERROR** Couldn't obtain beamline data." << endl; assert(0); } pstr->ToUpper(); fout << pstr->Data() << " "; pstr = fRuns[i].GetInstitute(); if (pstr == 0) { cerr << endl << ">> PMsrHandler::WriteMsrFile: **ERROR** Couldn't obtain institute data." << endl; assert(0); } pstr->ToUpper(); fout << pstr->Data() << " "; pstr = fRuns[i].GetFileFormat(); if (pstr == 0) { cerr << endl << ">> PMsrHandler::WriteMsrFile: **ERROR** Couldn't obtain file format data." << endl; assert(0); } pstr->ToUpper(); fout << pstr->Data() << " (name beamline institute data-file-format)" << endl; // ADDRUN for (UInt_t j = 1; j < fRuns[i].GetRunNameSize(); ++j) { fout << "ADDRUN " << fRuns[i].GetRunName(j)->Data() << " "; pstr = fRuns[i].GetBeamline(j); if (pstr == 0) { cerr << endl << ">> PMsrHandler::WriteMsrFile: **ERROR** Couldn't obtain beamline data (addrun)." << endl; assert(0); } pstr->ToUpper(); fout << pstr->Data() << " "; pstr = fRuns[i].GetInstitute(j); if (pstr == 0) { cerr << endl << ">> PMsrHandler::WriteMsrFile: **ERROR** Couldn't obtain institute data (addrun)." << endl; assert(0); } pstr->ToUpper(); fout << pstr->Data() << " "; pstr = fRuns[i].GetFileFormat(j); if (pstr == 0) { cerr << endl << ">> PMsrHandler::WriteMsrFile: **ERROR** Couldn't obtain file format data (addrun)." << endl; assert(0); } pstr->ToUpper(); fout << pstr->Data() << " (name beamline institute data-file-format)" << endl; } // fittype fout.width(16); switch (fRuns[i].GetFitType()) { case MSR_FITTYPE_SINGLE_HISTO: fout << left << "fittype" << MSR_FITTYPE_SINGLE_HISTO << " (single histogram fit)" << endl; break; case MSR_FITTYPE_ASYM: fout << left << "fittype" << MSR_FITTYPE_ASYM << " (asymmetry fit)" << endl ; break; case MSR_FITTYPE_MU_MINUS: fout << left << "fittype" << MSR_FITTYPE_MU_MINUS << " (mu minus fit)" << endl ; break; case MSR_FITTYPE_NON_MUSR: fout << left << "fittype" << MSR_FITTYPE_NON_MUSR << " (non muSR fit)" << endl ; break; default: break; } // alpha if (fRuns[i].GetAlphaParamNo() != -1) { fout.width(16); fout << left << "alpha"; fout << fRuns[i].GetAlphaParamNo() << endl; } // beta if (fRuns[i].GetBetaParamNo() != -1) { fout.width(16); fout << left << "beta"; fout << fRuns[i].GetBetaParamNo() << endl; } // norm if (fRuns[i].GetNormParamNo() != -1) { fout.width(16); fout << left << "norm"; // check if norm is give as a function if (fRuns[i].GetNormParamNo() >= MSR_PARAM_FUN_OFFSET) fout << "fun" << fRuns[i].GetNormParamNo()-MSR_PARAM_FUN_OFFSET; else fout << fRuns[i].GetNormParamNo(); fout << endl; } // backgr.fit if (fRuns[i].GetBkgFitParamNo() != -1) { fout.width(16); fout << left << "backgr.fit"; fout << fRuns[i].GetBkgFitParamNo() << endl; } // lifetime if (fRuns[i].GetLifetimeParamNo() != -1) { fout.width(16); fout << left << "lifetime"; fout << fRuns[i].GetLifetimeParamNo() << endl; } // lifetimecorrection if ((fRuns[i].IsLifetimeCorrected()) && (fRuns[i].GetFitType() == MSR_FITTYPE_SINGLE_HISTO)) { fout << "lifetimecorrection" << endl; } // map fout << "map "; for (UInt_t j=0; jsize(); ++j) { fout.width(5); fout << right << fRuns[i].GetMap(j); } // if there are less maps then 10 fill with zeros if (fRuns[i].GetMap()->size() < 10) { for (UInt_t j=fRuns[i].GetMap()->size(); j<10; ++j) fout << " 0"; } fout << endl; // forward if (fRuns[i].GetForwardHistoNoSize() == 0) { cerr << endl << ">> PMsrHandler::WriteMsrFile: **WARNING** No 'forward' data found!"; cerr << endl << ">> Something is VERY fishy, please check your msr-file carfully." << endl; } else { fout.width(16); fout << left << "forward"; for (UInt_t j=0; j 0) { fout.width(16); fout << left << "backward"; for (UInt_t j=0; j 0) { fout.width(8); fout << left << fRuns[i].GetBkgRange(j); } } fout << endl; } // data if ((fRuns[i].GetDataRange(0) != -1) || (fRuns[i].GetDataRange(1) != -1) || (fRuns[i].GetDataRange(2) != -1) || (fRuns[i].GetDataRange(3) != -1)) { fout.width(16); fout << left << "data"; for (UInt_t j=0; j<4; ++j) { if (fRuns[i].GetDataRange(j) > 0) { fout.width(8); fout << left << fRuns[i].GetDataRange(j); } } fout << endl; } // t0 if (fRuns[i].GetT0BinSize() > 0) { fout.width(16); fout << left << "t0"; for (UInt_t j=0; j 0) { fout.width(16); fout << left << "addt0"; for (Int_t k=0; kIsWhitespace()) { // labels fout.width(16); fout << left << "xy-data"; fout.width(8); fout << left << fixed << fRuns[i].GetXDataLabel()->Data(); fout << " "; fout.width(8); fout << left << fixed << fRuns[i].GetYDataLabel()->Data(); fout << endl; } // fit fout.width(16); fout << left << "fit"; if (fRuns[i].IsFitRangeInBin()) { // fit range given in bins fout << "fgb"; if (fRuns[i].GetFitRangeOffset(0) > 0) fout << "+" << fRuns[i].GetFitRangeOffset(0); fout << " lgb"; if (fRuns[i].GetFitRangeOffset(1) > 0) fout << "-" << fRuns[i].GetFitRangeOffset(1); } else { // fit range given in time for (UInt_t j=0; j<2; j++) { if (fRuns[i].GetFitRange(j) == -1) break; UInt_t neededWidth = 7; UInt_t neededPrec = LastSignificant(fRuns[i].GetFitRange(j)); fout.width(neededWidth); fout.precision(neededPrec); fout << left << fixed << fRuns[i].GetFitRange(j); if (j==0) fout << " "; } } fout << endl; // packing fout.width(16); fout << left << "packing"; fout << fRuns[i].GetPacking() << endl; fout << endl; } if (commentsRUN && !commentsRUN->empty()) { for(iter = commentsRUN->begin(); iter != commentsRUN->end(); ++iter) { fout << "# " << iter->second.Data() << endl; } fout << endl; commentsRUN->clear(); } fout << hline.Data() << endl; // write COMMANDS block fout << "COMMANDS" << endl; for (i = 0; i < fCommands.size(); ++i) { if (fCommands[i].fLine.BeginsWith("SET BATCH") || fCommands[i].fLine.BeginsWith("END RETURN")) continue; else fout << fCommands[i].fLine.Data() << endl; } fout << endl; fout << hline.Data() << endl; // write FOURIER block if (fFourier.fFourierBlockPresent) { fout << "FOURIER" << endl; // units if (fFourier.fUnits) { fout << "units "; if (fFourier.fUnits == FOURIER_UNIT_GAUSS) { fout << "Gauss"; } else if (fFourier.fUnits == FOURIER_UNIT_TESLA) { fout << "Tesla"; } else if (fFourier.fUnits == FOURIER_UNIT_FREQ) { fout << "MHz "; } else if (fFourier.fUnits == FOURIER_UNIT_CYCLES) { fout << "Mc/s"; } fout << " # units either 'Gauss', 'Tesla', 'MHz', or 'Mc/s'"; fout << endl; } // fourier_power if (fFourier.fFourierPower != -1) { fout << "fourier_power " << fFourier.fFourierPower << endl; } // apodization if (fFourier.fApodization) { fout << "apodization "; if (fFourier.fApodization == FOURIER_APOD_NONE) { fout << "NONE "; } else if (fFourier.fApodization == FOURIER_APOD_WEAK) { fout << "WEAK "; } else if (fFourier.fApodization == FOURIER_APOD_MEDIUM) { fout << "MEDIUM"; } else if (fFourier.fApodization == FOURIER_APOD_STRONG) { fout << "STRONG"; } fout << " # NONE, WEAK, MEDIUM, STRONG"; fout << endl; } // plot if (fFourier.fPlotTag) { fout << "plot "; if (fFourier.fPlotTag == FOURIER_PLOT_REAL) { fout << "REAL "; } else if (fFourier.fPlotTag == FOURIER_PLOT_IMAG) { fout << "IMAG "; } else if (fFourier.fPlotTag == FOURIER_PLOT_REAL_AND_IMAG) { fout << "REAL_AND_IMAG"; } else if (fFourier.fPlotTag == FOURIER_PLOT_POWER) { fout << "POWER"; } else if (fFourier.fPlotTag == FOURIER_PLOT_PHASE) { fout << "PHASE"; } fout << " # REAL, IMAG, REAL_AND_IMAG, POWER, PHASE"; fout << endl; } // phase if (fFourier.fPhaseParamNo > 0) { fout << "phase par" << fFourier.fPhaseParamNo << endl; } else if (fFourier.fPhase != -999.0) { fout << "phase " << fFourier.fPhase << endl; } // range_for_phase_correction if ((fFourier.fRangeForPhaseCorrection[0] != -1.0) || (fFourier.fRangeForPhaseCorrection[1] != -1.0)) { fout << "range_for_phase_correction " << fFourier.fRangeForPhaseCorrection[0] << " " << fFourier.fRangeForPhaseCorrection[1] << endl; } // range if ((fFourier.fPlotRange[0] != -1.0) || (fFourier.fPlotRange[1] != -1.0)) { fout << "range " << fFourier.fPlotRange[0] << " " << fFourier.fPlotRange[1] << endl; } // // phase_increment -- not used in msr-files at the moment (can only be set through the xml-file) // if (fFourier.fPhaseIncrement) { // fout << "phase_increment " << fFourier.fPhaseIncrement << endl; // } fout << endl; fout << hline.Data() << endl; } // write PLOT blocks for (i = 0; i < fPlots.size(); ++i) { switch (fPlots[i].fPlotType) { case MSR_PLOT_SINGLE_HISTO: fout << "PLOT " << fPlots[i].fPlotType << " (single histo plot)" << endl; break; case MSR_PLOT_ASYM: fout << "PLOT " << fPlots[i].fPlotType << " (asymmetry plot)" << endl; break; case MSR_PLOT_MU_MINUS: fout << "PLOT " << fPlots[i].fPlotType << " (mu minus plot)" << endl; break; case MSR_PLOT_NON_MUSR: fout << "PLOT " << fPlots[i].fPlotType << " (non muSR plot)" << endl; break; default: break; } // runs fout << "runs "; fout.precision(0); for (UInt_t j=0; j 1) && (fPlots[i].fTmax.size() > 1)) { fout << "sub_ranges "; fout.precision(2); for (UInt_t j=0; j < fPlots[i].fTmin.size(); ++j) { fout << " " << fPlots[i].fTmin[j] << " " << fPlots[i].fTmax[j]; } } if (!fPlots[i].fYmin.empty() && !fPlots[i].fYmax.empty()) { fout << " " << fPlots[i].fYmin[0] << " " << fPlots[i].fYmax[0]; } fout << endl; // use_fit_ranges if (fPlots[i].fUseFitRanges) { if (!fPlots[i].fYmin.empty() && !fPlots[i].fYmax.empty()) fout << "use_fit_ranges " << fPlots[i].fYmin[0] << " " << fPlots[i].fYmax[0] << endl; else fout << "use_fit_ranges" << endl; } // view_packing if (fPlots[i].fViewPacking != -1) { fout << "view_packing " << fPlots[i].fViewPacking << endl; } // logx if (fPlots[i].fLogX) { fout << "logx" << endl; } // logy if (fPlots[i].fLogY) { fout << "logy" << endl; } // rrf_packing if (fPlots[i].fRRFPacking) { fout << "rrf_packing " << fPlots[i].fRRFPacking << endl; } // rrf_freq if (fPlots[i].fRRFFreq) { fout << "rrf_freq " << fPlots[i].fRRFFreq << " "; switch (fPlots[i].fRRFUnit) { case RRF_UNIT_kHz: fout << "kHz"; break; case RRF_UNIT_MHz: fout << "MHz"; break; case RRF_UNIT_Mcs: fout << "Mc/s"; break; case RRF_UNIT_G: fout << "G"; break; case RRF_UNIT_T: fout << "T"; break; default: break; } fout << endl; } // rrf_phase if (fPlots[i].fRRFPhaseParamNo > 0) { fout << "rrf_phase par" << fPlots[i].fRRFPhaseParamNo << endl; } else if (fPlots[i].fRRFPhase) { fout << "rrf_phase " << fPlots[i].fRRFPhase << endl; } fout << endl; } if (!fPlots.empty()) { fout << hline.Data() << endl; } // write STATISTIC block TDatime dt; fout << "STATISTIC --- " << dt.AsSQLString() << endl; if (fStatistic.fValid) { // valid fit result if (fStatistic.fChisq) { // chisq str = " chisq = "; str += fStatistic.fMin; str += ", NDF = "; str += fStatistic.fNdf; str += ", chisq/NDF = "; str += fStatistic.fMin / fStatistic.fNdf; fout << str.Data() << endl; } else { // max. log. liklihood str = " maxLH = "; str += fStatistic.fMin; str += ", NDF = "; str += fStatistic.fNdf; str += ", maxLH/NDF = "; str += fStatistic.fMin / fStatistic.fNdf; fout << str.Data() << endl; } } else { fout << "*** FIT DID NOT CONVERGE ***" << endl; } // close file fout.close(); str.Clear(); pstr = 0; return PMUSR_SUCCESS; } //-------------------------------------------------------------------------- // SetMsrParamValue (public) //-------------------------------------------------------------------------- /** *

Sets the fit parameter value at position idx. * *

return: * - true if idx is within range * - false if idx is larger than the fit parameter vector. * * \param idx index of the fit parameter value. * \param value fit parameter value to be set. */ Bool_t PMsrHandler::SetMsrParamValue(UInt_t idx, Double_t value) { if (idx >= fParam.size()) { cerr << endl << ">> PMsrHandler::SetMsrParamValue(): **ERROR** idx = " << idx << " is >= than the number of fit parameters " << fParam.size(); cerr << endl; return false; } fParam[idx].fValue = value; return true; } //-------------------------------------------------------------------------- // SetMsrParamStep (public) //-------------------------------------------------------------------------- /** *

Sets the fit parameter step value (initial step size for minuit2) at positon idx. * After a successful fit, the negative error will be writen. * *

return: * - true if idx is within range * - false if idx is larger than the fit parameter vector. * * \param idx index fo the fit parameter step value * \param value fit parameter step value to be set. */ Bool_t PMsrHandler::SetMsrParamStep(UInt_t idx, Double_t value) { if (idx >= fParam.size()) { cerr << endl << ">> PMsrHandler::SetMsrParamValue(): **ERROR** idx = " << idx << " is larger than the number of parameters " << fParam.size(); cerr << endl; return false; } fParam[idx].fStep = value; return true; } //-------------------------------------------------------------------------- // SetMsrParamPosErrorPresent (public) //-------------------------------------------------------------------------- /** *

Sets the flag whether the fit parameter positive error value is persent. This at positon idx. * *

return: * - true if idx is within range * - false if idx is larger than the fit parameter vector. * * \param idx index fo the fit parameter positive error value * \param value fit parameter positive error value present. */ Bool_t PMsrHandler::SetMsrParamPosErrorPresent(UInt_t idx, Bool_t value) { if (idx >= fParam.size()) { cerr << endl << ">> PMsrHandler::SetMsrParamPosErrorPresent(): **ERROR** idx = " << idx << " is larger than the number of parameters " << fParam.size(); cerr << endl; return false; } fParam[idx].fPosErrorPresent = value; return true; } //-------------------------------------------------------------------------- // SetMsrParamPosError (public) //-------------------------------------------------------------------------- /** *

Sets the fit parameter positive error value at positon idx. * *

return: * - true if idx is within range * - false if idx is larger than the fit parameter vector. * * \param idx index fo the fit parameter positive error value * \param value fit parameter positive error value to be set. */ Bool_t PMsrHandler::SetMsrParamPosError(UInt_t idx, Double_t value) { if (idx >= fParam.size()) { cerr << endl << ">> PMsrHandler::SetMsrParamPosError(): **ERROR** idx = " << idx << " is larger than the number of parameters " << fParam.size(); cerr << endl; return false; } fParam[idx].fPosErrorPresent = true; fParam[idx].fPosError = value; return true; } //-------------------------------------------------------------------------- // SetMsrT0Entry (public) //-------------------------------------------------------------------------- /** *

Sets the t0 entries for a given runNo and a given histogram index idx. * * \param runNo msr-file run number * \param idx msr-file histogram index * \param bin t0 bin value */ void PMsrHandler::SetMsrT0Entry(UInt_t runNo, UInt_t idx, Double_t bin) { if (runNo >= fRuns.size()) { // error cerr << endl << ">> PMsrHandler::SetMsrT0Entry: **ERROR** runNo = " << runNo << ", is out of valid range 0.." << fRuns.size(); cerr << endl; return; } if (idx >= fRuns[runNo].GetT0BinSize()) { // error cerr << endl << ">> PMsrHandler::SetMsrT0Entry: **WARNING** idx = " << idx << ", is out of valid range 0.." << fRuns[runNo].GetT0BinSize(); cerr << endl << ">> Will add it anyway."; cerr << endl; } fRuns[runNo].SetT0Bin(bin, idx); } //-------------------------------------------------------------------------- // SetMsrAddT0Entry (public) //-------------------------------------------------------------------------- /** *

Sets a t0 value for an addrun entry. * * \param runNo msr-file run number * \param addRunIdx msr-file addrun index, e.g. if 2 addruns are present addRunIdx can take the values 0 or 1. * \param histoIdx msr-file histogram index for an addrun. * \param bin t0 bin value. */ void PMsrHandler::SetMsrAddT0Entry(UInt_t runNo, UInt_t addRunIdx, UInt_t histoIdx, Double_t bin) { if (runNo >= fRuns.size()) { // error cerr << endl << ">> PMsrHandler::SetMsrAddT0Entry: **ERROR** runNo = " << runNo << ", is out of valid range 0.." << fRuns.size(); cerr << endl; return; } if (addRunIdx >= fRuns[runNo].GetAddT0BinEntries()) { // error cerr << endl << ">> PMsrHandler::SetMsrAddT0Entry: **WARNING** addRunIdx = " << addRunIdx << ", is out of valid range 0.." << fRuns[runNo].GetAddT0BinEntries(); cerr << endl << ">> Will add it anyway."; cerr << endl; } if (static_cast(histoIdx) > fRuns[runNo].GetAddT0BinSize(addRunIdx)) { // error cerr << endl << ">> PMsrHandler::SetMsrAddT0Entry: **WARNING** histoIdx = " << histoIdx << ", is out of valid range 0.." << fRuns[runNo].GetAddT0BinSize(addRunIdx); cerr << endl << ">> Will add it anyway."; cerr << endl; } fRuns[runNo].SetAddT0Bin(bin, addRunIdx, histoIdx); } //-------------------------------------------------------------------------- // SetMsrDataRangeEntry (public) //-------------------------------------------------------------------------- /** *

Sets the data range entries for a given runNo and a given histogram index idx. * * \param runNo msr-file run number * \param idx 0=start bin index, 1=end bin index * \param bin data range bin value */ void PMsrHandler::SetMsrDataRangeEntry(UInt_t runNo, UInt_t idx, Int_t bin) { if (runNo >= fRuns.size()) { // error cerr << endl << ">> PMsrHandler::SetMsrDataRangeEntry: **ERROR** runNo = " << runNo << ", is out of valid range 0.." << fRuns.size(); cerr << endl; return; } fRuns[runNo].SetDataRange(bin, idx); } //-------------------------------------------------------------------------- // SetMsrBkgRangeEntry (public) //-------------------------------------------------------------------------- /** *

Sets the background range entries for a given runNo and a given histogram index idx. * * \param runNo msr-file run number * \param idx 0=start bin index, 1=end bin index * \param bin background range bin value */ void PMsrHandler::SetMsrBkgRangeEntry(UInt_t runNo, UInt_t idx, Int_t bin) { if (runNo >= fRuns.size()) { // error cerr << endl << ">> PMsrHandler::SetMsrBkgRangeEntry: **ERROR** runNo = " << runNo << ", is out of valid range 0.." << fRuns.size(); cerr << endl; return; } fRuns[runNo].SetBkgRange(bin, idx); } //-------------------------------------------------------------------------- // ParameterInUse (public) //-------------------------------------------------------------------------- /** *

Needed for the following purpose: if minuit is minimizing, it varies * all the parameters of the parameter list (if not fixed), even if a particular * parameter is NOT used at all. This is stupid! Hence one has to check * if the parameter is used at all and if not, it has to be fixed. * *

return: * - 0 if the parameter is not used. * - a value > 0 if the parameter is used. * * \param paramNo parameter number */ Int_t PMsrHandler::ParameterInUse(UInt_t paramNo) { // check that paramNo is within acceptable range if ((paramNo < 0) || (paramNo >= fParam.size())) return -1; return fParamInUse[paramNo]; } //-------------------------------------------------------------------------- // HandleFitParameterEntry (private) //-------------------------------------------------------------------------- /** *

The routine analyze a parameter line and, if the possible parameter list * is OK (what this means see below), it adds the parameter to the parameter list. * *

Possible cases: * \code * No Name Value Step/Neg_Error Pos_Error Boundary_Low Boundary_High * x x x x x x x -> 7 Parameters, e.g. after a MINOS fit * x x x x x -> 5 Parameters, e.g. after a MINOS fit * without boundaries * x x x x -> 4 Parameters, e.g. after MIGRAD fit * without boundaries, or * when starting * \endcode * * return: * - true is fit parameter lines are OK. * - false otherwise * * \param lines is a list of lines containing the fitparameter block */ Bool_t PMsrHandler::HandleFitParameterEntry(PMsrLines &lines) { // If msr-file is used for musrFT only, nothing needs to be done here. if (fFourierOnly) return true; PMsrParamStructure param; Bool_t error = false; PMsrLines::iterator iter; TObjArray *tokens = 0; TObjString *ostr = 0; TString str; // fill param structure iter = lines.begin(); while ((iter != lines.end()) && !error) { // init param structure param.fNoOfParams = -1; param.fNo = -1; param.fName = TString(""); param.fValue = 0.0; param.fStep = 0.0; param.fPosErrorPresent = false; param.fPosError = 0.0; param.fLowerBoundaryPresent = false; param.fLowerBoundary = 0.0; param.fUpperBoundaryPresent = false; param.fUpperBoundary = 0.0; tokens = iter->fLine.Tokenize(" \t"); if (!tokens) { cerr << endl << ">> PMsrHandler::HandleFitParameterEntry: **SEVERE ERROR** Couldn't tokenize Parameters in line " << iter->fLineNo; cerr << endl << endl; return false; } // handle various input possiblities if ((tokens->GetEntries() < 4) || (tokens->GetEntries() > 7) || (tokens->GetEntries() == 6)) { error = true; } else { // handle the first 4 parameter since they are always the same // parameter number ostr = dynamic_cast(tokens->At(0)); str = ostr->GetString(); if (str.IsDigit()) param.fNo = str.Atoi(); else error = true; // parameter name ostr = dynamic_cast(tokens->At(1)); str = ostr->GetString(); param.fName = str; // parameter value ostr = dynamic_cast(tokens->At(2)); str = ostr->GetString(); if (str.IsFloat()) param.fValue = (Double_t)str.Atof(); else error = true; // parameter value ostr = dynamic_cast(tokens->At(3)); str = ostr->GetString(); if (str.IsFloat()) param.fStep = (Double_t)str.Atof(); else error = true; // 4 values, i.e. No Name Value Step if (tokens->GetEntries() == 4) { param.fNoOfParams = 4; } // 5 values, i.e. No Name Value Neg_Error Pos_Error if (tokens->GetEntries() == 5) { param.fNoOfParams = 5; // positive error ostr = dynamic_cast(tokens->At(4)); str = ostr->GetString(); if (str.IsFloat()) { param.fPosErrorPresent = true; param.fPosError = (Double_t)str.Atof(); } else { str.ToLower(); if (!str.CompareTo("none", TString::kIgnoreCase)) param.fPosErrorPresent = false; else error = true; } } // 7 values, i.e. No Name Value Neg_Error Pos_Error Lower_Boundary Upper_Boundary if (tokens->GetEntries() == 7) { param.fNoOfParams = 7; // positive error ostr = dynamic_cast(tokens->At(4)); str = ostr->GetString(); if (str.IsFloat()) { param.fPosErrorPresent = true; param.fPosError = (Double_t)str.Atof(); } else { str.ToLower(); if (!str.CompareTo("none", TString::kIgnoreCase)) param.fPosErrorPresent = false; else error = true; } // lower boundary ostr = dynamic_cast(tokens->At(5)); str = ostr->GetString(); // check if lower boundary is "none", i.e. upper boundary limited only if (!str.CompareTo("none", TString::kIgnoreCase)) { // none param.fLowerBoundaryPresent = false; } else { // assuming that the lower boundary is a number if (str.IsFloat()) { param.fLowerBoundary = (Double_t)str.Atof(); param.fLowerBoundaryPresent = true; } else { error = true; } } // upper boundary ostr = dynamic_cast(tokens->At(6)); str = ostr->GetString(); // check if upper boundary is "none", i.e. lower boundary limited only if (!str.CompareTo("none", TString::kIgnoreCase)) { // none param.fUpperBoundaryPresent = false; } else { // assuming a number if (str.IsFloat()) { param.fUpperBoundary = (Double_t)str.Atof(); param.fUpperBoundaryPresent = true; } else { error = true; } } // check for lower-/upper-boundaries = none/none if (!param.fLowerBoundaryPresent && !param.fUpperBoundaryPresent) param.fNoOfParams = 5; // since there are no real boundaries present } } // check if enough elements found if (error) { cerr << endl; cerr << endl << ">> PMsrHandler::HandleFitParameterEntry: **ERROR** in line " << iter->fLineNo << ":"; cerr << endl << ">> " << iter->fLine.Data(); cerr << endl << ">> A Fit Parameter line needs to have the following form: "; cerr << endl; cerr << endl << ">> No Name Value Step/Error [Lower_Boundary Upper_Boundary]"; cerr << endl; cerr << endl << ">> or"; cerr << endl; cerr << endl << ">> No Name Value Step/Neg_Error Pos_Error [Lower_Boundary Upper_Boundary]"; cerr << endl; cerr << endl << ">> No: the parameter number (an Int_t)"; cerr << endl << ">> Name: the name of the parameter (less than 256 character)"; cerr << endl << ">> Value: the starting value of the parameter (a Double_t)"; cerr << endl << ">> Step/Error,"; cerr << endl << ">> Step/Neg_Error: the starting step value in a fit (a Double_t), or"; cerr << endl << ">> the symmetric error (MIGRAD, SIMPLEX), or"; cerr << endl << ">> the negative error (MINOS)"; cerr << endl << ">> Pos_Error: the positive error (MINOS), (a Double_t or \"none\")"; cerr << endl << ">> Lower_Boundary: the lower boundary allowed for the fit parameter (a Double_t or \"none\")"; cerr << endl << ">> Upper_Boundary: the upper boundary allowed for the fit parameter (a Double_t or \"none\")"; cerr << endl; } else { // everything is OK, therefore add the parameter to the parameter list fParam.push_back(param); } // clean up if (tokens) { delete tokens; tokens = 0; } iter++; } // check if all parameters have subsequent numbers. for (UInt_t i=0; i> PMsrHandler::HandleFitParameterEntry: **ERROR**"; cerr << endl << ">> Sorry, you are assuming to much from this program, it cannot"; cerr << endl << ">> handle none subsequent numbered parameters yet or in the near future."; cerr << endl << ">> Found parameter " << fParam[i].fName.Data() << ", with"; cerr << endl << ">> parameter number " << fParam[i].fNo << ", at paramter position " << i+1 << "."; cerr << endl << ">> This needs to be fixed first."; cerr << endl; break; } } return !error; } //-------------------------------------------------------------------------- // HandleTheoryEntry (private) //-------------------------------------------------------------------------- /** *

Just stores the THEORY block lines. * * return: * - true always * * \param lines is a list of lines containing the theory block */ Bool_t PMsrHandler::HandleTheoryEntry(PMsrLines &lines) { // If msr-file is used for musrFT only, nothing needs to be done here. if (fFourierOnly) return true; // store the theory lines fTheory = lines; return true; } //-------------------------------------------------------------------------- // HandleFunctionsEntry (private) //-------------------------------------------------------------------------- /** *

Parses the FUNCTIONS block of the msr-file. * * return: * - true if the parsing was successful. * - false otherwise * * \param lines is a list of lines containing the functions block */ Bool_t PMsrHandler::HandleFunctionsEntry(PMsrLines &lines) { // If msr-file is used for musrFT only, nothing needs to be done here. if (fFourierOnly) return true; // store the functions lines fFunctions = lines; // create function handler fFuncHandler = new PFunctionHandler(fFunctions); if (fFuncHandler == 0) { cerr << endl << ">> PMsrHandler::HandleFunctionsEntry: **ERROR** Couldn't invoke PFunctionHandler." << endl; return false; } // do the parsing if (!fFuncHandler->DoParse()) { return false; } // check if an empty FUNCTIONS block is present if ((fFuncHandler->GetNoOfFuncs() == 0) && !lines.empty()) { cerr << endl << ">> PMsrHandler::HandleFunctionsEntry: **WARNING** empty FUNCTIONS block found!"; cerr << endl; } return true; } //-------------------------------------------------------------------------- // HandleGlobalEntry (private) //-------------------------------------------------------------------------- /** *

Parses the GLOBAL block of the msr-file. * * return: * - true if successful * - false otherwise * * \param lines is a list of lines containing the run blocks */ Bool_t PMsrHandler::HandleGlobalEntry(PMsrLines &lines) { PMsrLines::iterator iter; PMsrGlobalBlock global; Bool_t error = false; TString str; TObjArray *tokens = 0; TObjString *ostr = 0; Int_t ival; Double_t dval; UInt_t addT0Counter = 0; // since this routine is called, a GLOBAL block is present global.SetGlobalPresent(true); iter = lines.begin(); while ((iter != lines.end()) && !error) { // remove potential comment at the end of lines str = iter->fLine; Ssiz_t idx = str.Index("#"); if (idx != -1) str.Remove(idx); // tokenize line tokens = str.Tokenize(" \t"); if (!tokens) { cerr << endl << ">> PMsrHandler::HandleGlobalEntry: **SEVERE ERROR** Couldn't tokenize line " << iter->fLineNo; cerr << endl << endl; return false; } if (iter->fLine.BeginsWith("fittype", TString::kIgnoreCase)) { // fittype if (tokens->GetEntries() < 2) { error = true; } else { ostr = dynamic_cast(tokens->At(1)); str = ostr->GetString(); if (str.IsDigit()) { Int_t fittype = str.Atoi(); if ((fittype == MSR_FITTYPE_SINGLE_HISTO) || (fittype == MSR_FITTYPE_ASYM) || (fittype == MSR_FITTYPE_MU_MINUS) || (fittype == MSR_FITTYPE_NON_MUSR)) { global.SetFitType(fittype); } else { error = true; } } else { error = true; } } } else if (iter->fLine.BeginsWith("data", TString::kIgnoreCase)) { // data if (tokens->GetEntries() < 3) { error = true; } else { for (Int_t i=1; iGetEntries(); i++) { ostr = dynamic_cast(tokens->At(i)); str = ostr->GetString(); if (str.IsDigit()) { ival = str.Atoi(); if (ival >= 0) { global.SetDataRange(ival, i-1); } else { error = true; } } else { error = true; } } } } else if (iter->fLine.BeginsWith("t0", TString::kIgnoreCase)) { // t0 if (tokens->GetEntries() < 2) { error = true; } else { for (Int_t i=1; iGetEntries(); i++) { ostr = dynamic_cast(tokens->At(i)); str = ostr->GetString(); if (str.IsFloat()) { dval = str.Atof(); if (dval >= 0.0) global.SetT0Bin(dval); else error = true; } else { error = true; } } } } else if (iter->fLine.BeginsWith("addt0", TString::kIgnoreCase)) { // addt0 if (tokens->GetEntries() < 2) { error = true; } else { for (Int_t i=1; iGetEntries(); i++) { ostr = dynamic_cast(tokens->At(i)); str = ostr->GetString(); if (str.IsFloat()) { dval = str.Atof(); if (dval >= 0.0) global.SetAddT0Bin(dval, addT0Counter, i-1); else error = true; } else { error = true; } } } addT0Counter++; } else if (iter->fLine.BeginsWith("fit", TString::kIgnoreCase)) { // fit range if (tokens->GetEntries() < 3) { error = true; } else { // fit given in time, i.e. fit , where , are given as doubles if (iter->fLine.Contains("fgb", TString::kIgnoreCase)) { // fit given in bins, i.e. fit fgb+n0 lgb-n1 // check 1st entry, i.e. fgb[+n0] ostr = dynamic_cast(tokens->At(1)); str = ostr->GetString(); Ssiz_t idx = str.First("+"); TString numStr = str; if (idx > -1) { // '+' present hence extract n0 numStr.Remove(0,idx+1); if (numStr.IsFloat()) { global.SetFitRangeOffset(numStr.Atoi(), 0); } else { error = true; } } else { // n0 == 0 global.SetFitRangeOffset(0, 0); } // check 2nd entry, i.e. lgb[-n1] ostr = dynamic_cast(tokens->At(2)); str = ostr->GetString(); idx = str.First("-"); numStr = str; if (idx > -1) { // '-' present hence extract n1 numStr.Remove(0,idx+1); if (numStr.IsFloat()) { global.SetFitRangeOffset(numStr.Atoi(), 1); } else { error = true; } } else { // n0 == 0 global.SetFitRangeOffset(0, 0); } if (!error) global.SetFitRangeInBins(true); } else { // fit given in time, i.e. fit , where , are given as doubles for (Int_t i=1; i<3; i++) { ostr = dynamic_cast(tokens->At(i)); str = ostr->GetString(); if (str.IsFloat()) global.SetFitRange(str.Atof(), i-1); else error = true; } } } } else if (iter->fLine.BeginsWith("packing", TString::kIgnoreCase)) { // packing if (tokens->GetEntries() < 2) { error = true; } else { ostr = dynamic_cast(tokens->At(1)); str = ostr->GetString(); if (str.IsDigit()) { ival = str.Atoi(); if (ival >= 0) { global.SetPacking(ival); } else { error = true; } } else { error = true; } } } // clean up if (tokens) { delete tokens; tokens = 0; } ++iter; } if (error) { --iter; cerr << endl << ">> PMsrHandler::HandleGlobalEntry: **ERROR** in line " << iter->fLineNo << ":"; cerr << endl << ">> '" << iter->fLine.Data() << "'"; cerr << endl << ">> GLOBAL block syntax is too complex to print it here. Please check the manual."; } else { // save global fGlobal = global; } return !error; } //-------------------------------------------------------------------------- // HandleRunEntry (private) //-------------------------------------------------------------------------- /** *

Parses the RUN blocks of the msr-file. * * return: * - true if successful * - false otherwise * * \param lines is a list of lines containing the run blocks */ Bool_t PMsrHandler::HandleRunEntry(PMsrLines &lines) { PMsrLines::iterator iter; PMsrRunBlock param; Bool_t first = true; // first run line tag Bool_t error = false; Bool_t runLinePresent = false; TString str; TObjArray *tokens = 0; TObjString *ostr = 0; UInt_t addT0Counter = 0; Int_t ival; Double_t dval; iter = lines.begin(); while ((iter != lines.end()) && !error) { // remove potential comment at the end of lines str = iter->fLine; Ssiz_t idx = str.Index("#"); if (idx != -1) str.Remove(idx); // tokenize line tokens = str.Tokenize(" \t"); if (!tokens) { cerr << endl << ">> PMsrHandler::HandleRunEntry: **SEVERE ERROR** Couldn't tokenize Parameters in line " << iter->fLineNo; cerr << endl << endl; return false; } // RUN line ---------------------------------------------- if (iter->fLine.BeginsWith("run", TString::kIgnoreCase)) { runLinePresent = true; // this is needed to make sure that a run line is present before and ADDRUN is following if (!first) { // not the first run in the list fRuns.push_back(param); param.CleanUp(); } else { first = false; } // get run name, beamline, institute, and file-format if (tokens->GetEntries() < 5) { error = true; } else { // run name ostr = dynamic_cast(tokens->At(1)); str = ostr->GetString(); param.SetRunName(str); // beamline ostr = dynamic_cast(tokens->At(2)); str = ostr->GetString(); param.SetBeamline(str); // institute ostr = dynamic_cast(tokens->At(3)); str = ostr->GetString(); param.SetInstitute(str); // data file format ostr = dynamic_cast(tokens->At(4)); str = ostr->GetString(); param.SetFileFormat(str); } addT0Counter = 0; // reset counter } // ADDRUN line --------------------------------------------- if (iter->fLine.BeginsWith("addrun", TString::kIgnoreCase)) { if (!runLinePresent) { cerr << endl << ">> PMsrHandler::HandleRunEntry: **ERROR** Found ADDRUN without prior RUN, or"; cerr << endl << ">> ADDRUN lines intercepted by other stuff. All this is not allowed!"; cerr << endl << ">> error in line " << iter->fLineNo; cerr << endl; error = true; continue; } // get run name, beamline, institute, and file-format if (tokens->GetEntries() < 5) { error = true; } else { // run name ostr = dynamic_cast(tokens->At(1)); str = ostr->GetString(); param.SetRunName(str); // beamline ostr = dynamic_cast(tokens->At(2)); str = ostr->GetString(); param.SetBeamline(str); // institute ostr = dynamic_cast(tokens->At(3)); str = ostr->GetString(); param.SetInstitute(str); // data file format ostr = dynamic_cast(tokens->At(4)); str = ostr->GetString(); param.SetFileFormat(str); } } // fittype ------------------------------------------------- if (iter->fLine.BeginsWith("fittype", TString::kIgnoreCase)) { runLinePresent = false; // this is needed to make sure that a run line is present before and ADDRUN is following if (tokens->GetEntries() < 2) { error = true; } else { ostr = dynamic_cast(tokens->At(1)); str = ostr->GetString(); if (str.IsDigit()) { Int_t fittype = str.Atoi(); if ((fittype == MSR_FITTYPE_SINGLE_HISTO) || (fittype == MSR_FITTYPE_ASYM) || (fittype == MSR_FITTYPE_MU_MINUS) || (fittype == MSR_FITTYPE_NON_MUSR)) { param.SetFitType(fittype); } else { error = true; } } else { error = true; } } } // alpha ------------------------------------------------- if (iter->fLine.BeginsWith("alpha", TString::kIgnoreCase)) { runLinePresent = false; // this is needed to make sure that a run line is present before and ADDRUN is following if (tokens->GetEntries() < 2) { error = true; } else { ostr = dynamic_cast(tokens->At(1)); str = ostr->GetString(); if (str.IsDigit()) { ival = str.Atoi(); if (ival > 0) param.SetAlphaParamNo(ival); else error = true; } else { error = true; } } } // beta ------------------------------------------------- if (iter->fLine.BeginsWith("beta", TString::kIgnoreCase)) { runLinePresent = false; // this is needed to make sure that a run line is present before and ADDRUN is following if (tokens->GetEntries() < 2) { error = true; } else { ostr = dynamic_cast(tokens->At(1)); str = ostr->GetString(); if (str.IsDigit()) { ival = str.Atoi(); if (ival > 0) param.SetBetaParamNo(ival); else error = true; } else { error = true; } } } // norm ------------------------------------------------- if (iter->fLine.BeginsWith("norm", TString::kIgnoreCase)) { runLinePresent = false; // this is needed to make sure that a run line is present before and ADDRUN is following if (tokens->GetEntries() < 2) { error = true; } else { ostr = dynamic_cast(tokens->At(1)); str = ostr->GetString(); if (str.IsDigit()) { param.SetNormParamNo(str.Atoi()); } else if (str.Contains("fun")) { Int_t no; if (FilterNumber(str, "fun", MSR_PARAM_FUN_OFFSET, no)) param.SetNormParamNo(no); else error = true; } else { error = true; } } } // backgr.fit -------------------------------------------- if (iter->fLine.BeginsWith("backgr.fit", TString::kIgnoreCase)) { runLinePresent = false; // this is needed to make sure that a run line is present before and ADDRUN is following if (tokens->GetEntries() < 2) { error = true; } else { ostr = dynamic_cast(tokens->At(1)); str = ostr->GetString(); if (str.IsDigit()) { ival = str.Atoi(); if (ival > 0) param.SetBkgFitParamNo(ival); else error = true; } else { error = true; } } } // lifetime ------------------------------------------------ if (iter->fLine.BeginsWith("lifetime ", TString::kIgnoreCase)) { runLinePresent = false; // this is needed to make sure that a run line is present before and ADDRUN is following if (tokens->GetEntries() < 2) { error = true; } else { ostr = dynamic_cast(tokens->At(1)); str = ostr->GetString(); if (str.IsDigit()) { ival = str.Atoi(); if (ival > 0) param.SetLifetimeParamNo(ival); else error = true; } else { error = true; } } } // lifetimecorrection --------------------------------------- if (iter->fLine.BeginsWith("lifetimecorrection", TString::kIgnoreCase)) { runLinePresent = false; // this is needed to make sure that a run line is present before and ADDRUN is following param.SetLifetimeCorrection(true); } // map ------------------------------------------------------ if (iter->fLine.BeginsWith("map", TString::kIgnoreCase)) { runLinePresent = false; // this is needed to make sure that a run line is present before and ADDRUN is following for (Int_t i=1; iGetEntries(); i++) { ostr = dynamic_cast(tokens->At(i)); str = ostr->GetString(); if (str.IsDigit()) { ival = str.Atoi(); if (ival >= 0) param.SetMap(ival); else error = true; } else { error = true; } } // check map entries, i.e. if the map values are within parameter bounds if (!fFourierOnly) { for (UInt_t i=0; isize(); i++) { if ((param.GetMap(i) < 0) || (param.GetMap(i) > (Int_t) fParam.size())) { cerr << endl << ">> PMsrHandler::HandleRunEntry: **SEVERE ERROR** map value " << param.GetMap(i) << " in line " << iter->fLineNo << " is out of range!"; error = true; break; } } } } // forward ------------------------------------------------ if (iter->fLine.BeginsWith("forward", TString::kIgnoreCase)) { runLinePresent = false; // this is needed to make sure that a run line is present before and ADDRUN is following if (tokens->GetEntries() < 2) { error = true; } else { PIntVector group; str = iter->fLine; if (ParseDetectorGrouping(str, group)) { for (UInt_t i=0; ifLine.BeginsWith("backward", TString::kIgnoreCase)) { runLinePresent = false; // this is needed to make sure that a run line is present before and ADDRUN is following if (tokens->GetEntries() < 2) { error = true; } else { PIntVector group; str = iter->fLine; if (ParseDetectorGrouping(str, group)) { for (UInt_t i=0; ifLine.BeginsWith("backgr.fix", TString::kIgnoreCase)) { runLinePresent = false; // this is needed to make sure that a run line is present before and ADDRUN is following if (tokens->GetEntries() < 2) { error = true; } else { for (Int_t i=1; iGetEntries(); i++) { ostr = dynamic_cast(tokens->At(i)); str = ostr->GetString(); if (str.IsFloat()) param.SetBkgFix(str.Atof(), i-1); else error = true; } } } // background --------------------------------------------- if (iter->fLine.BeginsWith("background", TString::kIgnoreCase)) { runLinePresent = false; // this is needed to make sure that a run line is present before and ADDRUN is following if ((tokens->GetEntries() < 3) || (tokens->GetEntries() % 2 != 1)) { // odd number (>=3) of entries needed error = true; } else { for (Int_t i=1; iGetEntries(); i++) { ostr = dynamic_cast(tokens->At(i)); str = ostr->GetString(); if (str.IsDigit()) { ival = str.Atoi(); if (ival > 0) param.SetBkgRange(ival, i-1); else error = true; } else { error = true; } } } } // data -------------------------------------------------- if (iter->fLine.BeginsWith("data", TString::kIgnoreCase)) { runLinePresent = false; // this is needed to make sure that a run line is present before and ADDRUN is following if ((tokens->GetEntries() < 3) || (tokens->GetEntries() % 2 != 1)) { // odd number (>=3) of entries needed error = true; } else { for (Int_t i=1; iGetEntries(); i++) { ostr = dynamic_cast(tokens->At(i)); str = ostr->GetString(); if (str.IsDigit()) { ival = str.Atoi(); if (ival > 0) param.SetDataRange(ival, i-1); else error = true; } else { error = true; } } } } // t0 ----------------------------------------------------- if (iter->fLine.BeginsWith("t0", TString::kIgnoreCase)) { runLinePresent = false; // this is needed to make sure that a run line is present before and ADDRUN is following if (tokens->GetEntries() < 2) { error = true; } else { for (Int_t i=1; iGetEntries(); i++) { ostr = dynamic_cast(tokens->At(i)); str = ostr->GetString(); if (str.IsFloat()) { dval = str.Atof(); if (dval >= 0.0) param.SetT0Bin(dval); else error = true; } else { error = true; } } } } // addt0 ----------------------------------------------------- if (iter->fLine.BeginsWith("addt0", TString::kIgnoreCase)) { runLinePresent = false; // this is needed to make sure that a run line is present before and ADDRUN is following if (tokens->GetEntries() < 2) { error = true; } else { for (Int_t i=1; iGetEntries(); i++) { ostr = dynamic_cast(tokens->At(i)); str = ostr->GetString(); if (str.IsFloat()) { dval = str.Atof(); if (dval >= 0.0) param.SetAddT0Bin(dval, addT0Counter, i-1); else error = true; } else { error = true; } } } addT0Counter++; } // fit ----------------------------------------------------- if (iter->fLine.BeginsWith("fit ", TString::kIgnoreCase)) { runLinePresent = false; // this is needed to make sure that a run line is present before and ADDRUN is following if (tokens->GetEntries() < 3) { error = true; } else { if (iter->fLine.Contains("fgb", TString::kIgnoreCase)) { // fit given in bins, i.e. fit fgb+n0 lgb-n1 // check 1st entry, i.e. fgb[+n0] ostr = dynamic_cast(tokens->At(1)); str = ostr->GetString(); Ssiz_t idx = str.First("+"); TString numStr = str; if (idx > -1) { // '+' present hence extract n0 numStr.Remove(0,idx+1); if (numStr.IsFloat()) { param.SetFitRangeOffset(numStr.Atoi(), 0); } else { error = true; } } else { // n0 == 0 param.SetFitRangeOffset(0, 0); } // check 2nd entry, i.e. lgb[-n1] ostr = dynamic_cast(tokens->At(2)); str = ostr->GetString(); idx = str.First("-"); numStr = str; if (idx > -1) { // '-' present hence extract n1 numStr.Remove(0,idx+1); if (numStr.IsFloat()) { param.SetFitRangeOffset(numStr.Atoi(), 1); } else { error = true; } } else { // n0 == 0 param.SetFitRangeOffset(0, 0); } if (!error) param.SetFitRangeInBins(true); } else { // fit given in time, i.e. fit , where , are given as doubles for (Int_t i=1; i<3; i++) { ostr = dynamic_cast(tokens->At(i)); str = ostr->GetString(); if (str.IsFloat()) param.SetFitRange(str.Atof(), i-1); else error = true; } } } } // packing -------------------------------------------------- if (iter->fLine.BeginsWith("packing", TString::kIgnoreCase)) { runLinePresent = false; // this is needed to make sure that a run line is present before and ADDRUN is following if (tokens->GetEntries() != 2) { error = true; } else { ostr = dynamic_cast(tokens->At(1)); str = ostr->GetString(); if (str.IsDigit()) { ival = str.Atoi(); if (ival > 0) param.SetPacking(ival); else error = true; } else { error = true; } } } // xy-data ----------------------------------------------- if (iter->fLine.BeginsWith("xy-data", TString::kIgnoreCase)) { runLinePresent = false; // this is needed to make sure that a run line is present before and ADDRUN is following if (tokens->GetEntries() != 3) { // xy-data x-label y-label error = true; } else { ostr = dynamic_cast(tokens->At(1)); str = ostr->GetString(); if (str.IsDigit()) { // xy-data indices given param.SetXDataIndex(str.Atoi()); // x-index ostr = dynamic_cast(tokens->At(2)); str = ostr->GetString(); if (str.IsDigit()) { ival = str.Atoi(); if (ival > 0) param.SetYDataIndex(ival); // y-index else error = true; } else { error = true; } } else { // xy-data labels given param.SetXDataLabel(str); // x-label ostr = dynamic_cast(tokens->At(2)); str = ostr->GetString(); param.SetYDataLabel(str); // y-label } } } // clean up if (tokens) { delete tokens; tokens = 0; } ++iter; } if (error) { --iter; cerr << endl << ">> PMsrHandler::HandleRunEntry: **ERROR** in line " << iter->fLineNo << ":"; cerr << endl << ">> " << iter->fLine.Data(); cerr << endl << ">> RUN block syntax is too complex to print it here. Please check the manual."; } else { // save last run found fRuns.push_back(param); param.CleanUp(); } return !error; } //-------------------------------------------------------------------------- // FilterNumber (private) //-------------------------------------------------------------------------- /** *

Used to filter numbers from a string of the structure strX, where * X is a number. The filter string is used to define the offset to X. * It is used to filter strings like: map1 or fun4. At the moment only * the filter strings 'map', 'fun', and 'par' are supported. * * return: * - true if successful * - false otherwise * * \param str input string * \param filter filter string * \param offset it is used to offset to found number, e.g. strX -> no = X+offset * \param no filtered number */ Bool_t PMsrHandler::FilterNumber(TString str, const Char_t *filter, Int_t offset, Int_t &no) { Int_t found, no_found=-1; // copy str to an ordinary c-like string Char_t *cstr, filterStr[32]; cstr = new Char_t[str.Sizeof()]; strncpy(cstr, str.Data(), str.Sizeof()); sprintf(filterStr, "%s%%d", filter); // get number if present found = sscanf(cstr, filterStr, &no_found); if (found == 1) if (no_found < 1000) no = no_found + offset; // clean up if (cstr) { delete [] cstr; cstr = 0; } if ((no_found < 0) || (no_found > 1000)) return false; else return true; } //-------------------------------------------------------------------------- // HandleCommandsEntry (private) //-------------------------------------------------------------------------- /** *

Just copies the COMMAND block lines. * * return: * - true * * \param lines is a list of lines containing the command block */ Bool_t PMsrHandler::HandleCommandsEntry(PMsrLines &lines) { // If msr-file is used for musrFT only, nothing needs to be done here. if (fFourierOnly) return true; PMsrLines::iterator iter; if (lines.empty()) { cerr << endl << ">> PMsrHandler::HandleCommandsEntry(): **WARNING**: There is no COMMAND block! Do you really want this?"; cerr << endl; } for (iter = lines.begin(); iter != lines.end(); ++iter) { if (!iter->fLine.BeginsWith("COMMANDS")) fCommands.push_back(*iter); } return true; } //-------------------------------------------------------------------------- // InitFourierParameterStructure (private) //-------------------------------------------------------------------------- /** *

Initializes the Fourier parameter structure. * * \param fourier fourier parameters */ void PMsrHandler::InitFourierParameterStructure(PMsrFourierStructure &fourier) { fourier.fFourierBlockPresent = false; // fourier block present fourier.fUnits = FOURIER_UNIT_NOT_GIVEN; // fourier untis, default: NOT GIVEN fourier.fFourierPower = -1; // zero padding, default: -1 = NOT GIVEN fourier.fDCCorrected = false; // dc-corrected FFT, default: false fourier.fApodization = FOURIER_APOD_NOT_GIVEN; // apodization, default: NOT GIVEN fourier.fPlotTag = FOURIER_PLOT_NOT_GIVEN; // initial plot tag, default: NOT GIVEN fourier.fPhaseParamNo = 0; // initial parameter no = 0 means not a parameter fourier.fPhase = -999.0; // fourier phase: -999 = NOT GIVEN for (UInt_t i=0; i<2; i++) { fourier.fRangeForPhaseCorrection[i] = -1.0; // frequency range for phase correction, default: {-1, -1} = NOT GIVEN fourier.fPlotRange[i] = -1.0; // fourier plot range, default: {-1, -1} = NOT GIVEN } } //-------------------------------------------------------------------------- // HandleFourierEntry (private) //-------------------------------------------------------------------------- /** *

Parses the Fourier block of a msr-file. * * return: * - true if successful * - false otherwise * * \param lines is a list of lines containing the fourier parameter block */ Bool_t PMsrHandler::HandleFourierEntry(PMsrLines &lines) { Bool_t error = false; if (lines.empty()) // no fourier block present return true; PMsrFourierStructure fourier; InitFourierParameterStructure(fourier); fourier.fFourierBlockPresent = true; PMsrLines::iterator iter; TObjArray *tokens = 0; TObjString *ostr = 0; TString str; Int_t ival; iter = lines.begin(); while ((iter != lines.end()) && !error) { // tokenize line tokens = iter->fLine.Tokenize(" \t"); if (!tokens) { cerr << endl << ">> PMsrHandler::HandleFourierEntry: **SEVERE ERROR** Couldn't tokenize Parameters in line " << iter->fLineNo; cerr << endl << endl; return false; } if (iter->fLine.BeginsWith("units", TString::kIgnoreCase)) { // units if (tokens->GetEntries() < 2) { // units are missing error = true; continue; } else { ostr = dynamic_cast(tokens->At(1)); str = ostr->GetString(); if (!str.CompareTo("gauss", TString::kIgnoreCase)) { fourier.fUnits = FOURIER_UNIT_GAUSS; } else if (!str.CompareTo("tesla", TString::kIgnoreCase)) { fourier.fUnits = FOURIER_UNIT_TESLA; } else if (!str.CompareTo("mhz", TString::kIgnoreCase)) { fourier.fUnits = FOURIER_UNIT_FREQ; } else if (!str.CompareTo("mc/s", TString::kIgnoreCase)) { fourier.fUnits = FOURIER_UNIT_CYCLES; } else { error = true; continue; } } } else if (iter->fLine.BeginsWith("fourier_power", TString::kIgnoreCase)) { // fourier power (zero padding) if (tokens->GetEntries() < 2) { // fourier power exponent is missing error = true; continue; } else { ostr = dynamic_cast(tokens->At(1)); str = ostr->GetString(); if (str.IsDigit()) { ival = str.Atoi(); if ((ival >= 0) && (ival <= 20)) { fourier.fFourierPower = ival; } else { // fourier power out of range error = true; continue; } } else { // fourier power not a number error = true; continue; } } } else if (iter->fLine.BeginsWith("dc-corrected", TString::kIgnoreCase)) { // dc-corrected if (tokens->GetEntries() < 2) { // dc-corrected tag is missing error = true; continue; } else { ostr = dynamic_cast(tokens->At(1)); str = ostr->GetString(); if (!str.CompareTo("true", TString::kIgnoreCase) || !str.CompareTo("1")) { fourier.fDCCorrected = true; } else if (!str.CompareTo("false", TString::kIgnoreCase) || !str.CompareTo("0")) { fourier.fDCCorrected = false; } else { // unrecognized dc-corrected tag error = true; continue; } } } else if (iter->fLine.BeginsWith("apodization", TString::kIgnoreCase)) { // apodization if (tokens->GetEntries() < 2) { // apodization tag is missing error = true; continue; } else { ostr = dynamic_cast(tokens->At(1)); str = ostr->GetString(); if (!str.CompareTo("none", TString::kIgnoreCase)) { fourier.fApodization = FOURIER_APOD_NONE; } else if (!str.CompareTo("weak", TString::kIgnoreCase)) { fourier.fApodization = FOURIER_APOD_WEAK; } else if (!str.CompareTo("medium", TString::kIgnoreCase)) { fourier.fApodization = FOURIER_APOD_MEDIUM; } else if (!str.CompareTo("strong", TString::kIgnoreCase)) { fourier.fApodization = FOURIER_APOD_STRONG; } else { // unrecognized apodization tag error = true; continue; } } } else if (iter->fLine.BeginsWith("plot", TString::kIgnoreCase)) { // plot tag if (tokens->GetEntries() < 2) { // plot tag is missing error = true; continue; } else { ostr = dynamic_cast(tokens->At(1)); str = ostr->GetString(); if (!str.CompareTo("real", TString::kIgnoreCase)) { fourier.fPlotTag = FOURIER_PLOT_REAL; } else if (!str.CompareTo("imag", TString::kIgnoreCase)) { fourier.fPlotTag = FOURIER_PLOT_IMAG; } else if (!str.CompareTo("real_and_imag", TString::kIgnoreCase)) { fourier.fPlotTag = FOURIER_PLOT_REAL_AND_IMAG; } else if (!str.CompareTo("power", TString::kIgnoreCase)) { fourier.fPlotTag = FOURIER_PLOT_POWER; } else if (!str.CompareTo("phase", TString::kIgnoreCase)) { fourier.fPlotTag = FOURIER_PLOT_PHASE; } else { // unrecognized plot tag error = true; continue; } } } else if (iter->fLine.BeginsWith("phase", TString::kIgnoreCase)) { // phase if (tokens->GetEntries() < 2) { // phase value is missing error = true; continue; } else { ostr = dynamic_cast(tokens->At(1)); str = ostr->GetString(); if (str.BeginsWith("par", TString::kIgnoreCase)) { // parameter value if (fFourierOnly) { cerr << endl << ">> PMsrHandler::HandleFourierEntry: **WARNING** Found phase parameter for Fourier only."; cerr << endl << ">> This is currently not supported. Will set the phase to 0." << endl; fourier.fPhase = 0.0; } else { Int_t no = 0; if (FilterNumber(str, "par", 0, no)) { // check that the parameter is in range if ((Int_t)fParam.size() < no) { error = true; continue; } // keep the parameter number fourier.fPhaseParamNo = no; // get parameter value fourier.fPhase = fParam[no-1].fValue; } else { error = true; continue; } } } else if (str.IsFloat()) { // phase value fourier.fPhase = str.Atof(); } else { error = true; continue; } } } else if (iter->fLine.BeginsWith("range_for_phase_correction", TString::kIgnoreCase)) { if (tokens->GetEntries() < 3) { // range values are missing error = true; continue; } else { for (UInt_t i=0; i<2; i++) { ostr = dynamic_cast(tokens->At(i+1)); str = ostr->GetString(); if (str.IsFloat()) { fourier.fRangeForPhaseCorrection[i] = str.Atof(); } else { error = true; continue; } } } } else if (iter->fLine.BeginsWith("range", TString::kIgnoreCase)) { // fourier plot range if (tokens->GetEntries() < 3) { // plot range values are missing error = true; continue; } else { for (UInt_t i=0; i<2; i++) { ostr = dynamic_cast(tokens->At(i+1)); str = ostr->GetString(); if (str.IsFloat()) { fourier.fPlotRange[i] = str.Atof(); } else { error = true; continue; } } } } else if (!iter->fLine.BeginsWith("fourier", TString::kIgnoreCase) && !iter->fLine.BeginsWith("#") && !iter->fLine.IsWhitespace() && (iter->fLine.Length() != 0)) { // make error = true; continue; } // clean up if (tokens) { delete tokens; tokens = 0; } ++iter; } // clean up after error if (tokens) { delete tokens; tokens = 0; } if (error) { cerr << endl << ">> PMsrHandler::HandleFourierEntry: **ERROR** in line " << iter->fLineNo << ":"; cerr << endl; cerr << endl << ">> " << iter->fLine.Data(); cerr << endl; cerr << endl << ">> FOURIER block syntax, parameters in [] are optinal:"; cerr << endl; cerr << endl << ">> FOURIER"; cerr << endl << ">> [units Gauss | MHz | Mc/s]"; cerr << endl << ">> [fourier_power n # n is a number such that zero padding up to 2^n will be used]"; cerr << endl << ">> n=0 means no zero padding"; cerr << endl << ">> 0 <= n <= 20 are allowed values"; cerr << endl << ">> [dc-corrected true | false]"; cerr << endl << ">> [apodization none | weak | medium | strong]"; cerr << endl << ">> [plot real | imag | real_and_imag | power | phase]"; cerr << endl << ">> [phase value]"; cerr << endl << ">> [range_for_phase_correction min max]"; cerr << endl << ">> [range min max]"; cerr << endl; } else { // save last run found fFourier = fourier; } return !error; } //-------------------------------------------------------------------------- // HandlePlotEntry (private) //-------------------------------------------------------------------------- /** *

Parses the PLOT block of a msr-file. * * return: * - true if successful * - false otherwise * * \param lines is a list of lines containing the plot block */ Bool_t PMsrHandler::HandlePlotEntry(PMsrLines &lines) { Bool_t error = false; PMsrPlotStructure param; PMsrLines::iterator iter1; PMsrLines::iterator iter2; TObjArray *tokens = 0; TObjString *ostr = 0; TString str; if (lines.empty()) { cerr << endl << ">> PMsrHandler::HandlePlotEntry(): **WARNING**: There is no PLOT block! Do you really want this?"; cerr << endl; } iter1 = lines.begin(); while ((iter1 != lines.end()) && !error) { // initialize param structure param.fPlotType = -1; param.fLifeTimeCorrection = false; param.fUseFitRanges = false; // i.e. if not overwritten use the range info of the plot block param.fLogX = false; // i.e. if not overwritten use linear x-axis param.fLogY = false; // i.e. if not overwritten use linear y-axis param.fViewPacking = -1; // i.e. if not overwritten use the packing of the run blocks param.fRuns.clear(); param.fTmin.clear(); param.fTmax.clear(); param.fYmin.clear(); param.fYmax.clear(); param.fRRFPacking = 0; // i.e. if not overwritten it will not be a valid RRF param.fRRFFreq = 0.0; // i.e. no RRF whished param.fRRFUnit = RRF_UNIT_MHz; param.fRRFPhaseParamNo = 0; // initial parameter no = 0 means not a parameter param.fRRFPhase = 0.0; // find next plot if any is present iter2 = iter1; ++iter2; for ( ; iter2 != lines.end(); ++iter2) { if (iter2->fLine.Contains("PLOT")) break; } // handle a single PLOT block while ((iter1 != iter2) && !error) { if (iter1->fLine.Contains("PLOT")) { // handle plot header tokens = iter1->fLine.Tokenize(" \t"); if (!tokens) { cerr << endl << ">> PMsrHandler::HandlePlotEntry: **SEVERE ERROR** Couldn't tokenize PLOT in line " << iter1->fLineNo; cerr << endl << endl; return false; } if (tokens->GetEntries() < 2) { // plot type missing error = true; } else { ostr = dynamic_cast(tokens->At(1)); str = ostr->GetString(); if (str.IsDigit()) param.fPlotType = str.Atoi(); else error = true; } // clean up if (tokens) { delete tokens; tokens = 0; } } else if (iter1->fLine.Contains("lifetimecorrection", TString::kIgnoreCase)) { param.fLifeTimeCorrection = true; } else if (iter1->fLine.Contains("runs", TString::kIgnoreCase)) { // handle plot runs TComplex run; switch (param.fPlotType) { case -1: error = true; break; case MSR_PLOT_SINGLE_HISTO: // like: runs 1 5 13 case MSR_PLOT_ASYM: case MSR_PLOT_NON_MUSR: case MSR_PLOT_MU_MINUS: tokens = iter1->fLine.Tokenize(" \t"); if (!tokens) { cerr << endl << ">> PMsrHandler::HandlePlotEntry: **SEVERE ERROR** Couldn't tokenize PLOT in line " << iter1->fLineNo; cerr << endl << endl; return false; } if (tokens->GetEntries() < 2) { // runs missing error = true; } else { for (Int_t i=1; iGetEntries(); i++) { ostr = dynamic_cast(tokens->At(i)); str = ostr->GetString(); if (str.IsDigit()) { run = TComplex(str.Atoi(),-1.0); param.fRuns.push_back(run); } else { error = true; } } } // clean up if (tokens) { delete tokens; tokens = 0; } break; default: error = true; break; } } else if (iter1->fLine.Contains("range ", TString::kIgnoreCase)) { // handle plot range // remove previous entries param.fTmin.clear(); param.fTmax.clear(); param.fYmin.clear(); param.fYmax.clear(); tokens = iter1->fLine.Tokenize(" \t"); if (!tokens) { cerr << endl << ">> PMsrHandler::HandlePlotEntry: **SEVERE ERROR** Couldn't tokenize PLOT in line " << iter1->fLineNo; cerr << endl << endl; return false; } if ((tokens->GetEntries() != 3) && (tokens->GetEntries() != 5)) { error = true; } else { // handle t_min ostr = dynamic_cast(tokens->At(1)); str = ostr->GetString(); if (str.IsFloat()) param.fTmin.push_back((Double_t)str.Atof()); else error = true; // handle t_max ostr = dynamic_cast(tokens->At(2)); str = ostr->GetString(); if (str.IsFloat()) param.fTmax.push_back((Double_t)str.Atof()); else error = true; if (tokens->GetEntries() == 5) { // y-axis interval given as well // handle y_min ostr = dynamic_cast(tokens->At(3)); str = ostr->GetString(); if (str.IsFloat()) param.fYmin.push_back((Double_t)str.Atof()); else error = true; // handle y_max ostr = dynamic_cast(tokens->At(4)); str = ostr->GetString(); if (str.IsFloat()) param.fYmax.push_back((Double_t)str.Atof()); else error = true; } } // clean up if (tokens) { delete tokens; tokens = 0; } } else if (iter1->fLine.Contains("sub_ranges", TString::kIgnoreCase)) { // remove previous entries param.fTmin.clear(); param.fTmax.clear(); param.fYmin.clear(); param.fYmax.clear(); tokens = iter1->fLine.Tokenize(" \t"); if (!tokens) { cerr << endl << ">> PMsrHandler::HandlePlotEntry: **SEVERE ERROR** Couldn't tokenize PLOT in line " << iter1->fLineNo; cerr << endl << endl; return false; } if ((tokens->GetEntries() != (Int_t)(2*param.fRuns.size() + 1)) && (tokens->GetEntries() != (Int_t)(2*param.fRuns.size() + 3))) { error = true; } else { // get all the times for (UInt_t i=0; i(tokens->At(2*i+1)); str = ostr->GetString(); if (str.IsFloat()) param.fTmin.push_back((Double_t)str.Atof()); else error = true; // handle t_max ostr = dynamic_cast(tokens->At(2*i+2)); str = ostr->GetString(); if (str.IsFloat()) param.fTmax.push_back((Double_t)str.Atof()); else error = true; } // get y-range if present if (tokens->GetEntries() == (Int_t)(2*param.fRuns.size() + 3)) { // handle y_min ostr = dynamic_cast(tokens->At(2*param.fRuns.size()+1)); str = ostr->GetString(); if (str.IsFloat()) param.fYmin.push_back((Double_t)str.Atof()); else error = true; // handle y_max ostr = dynamic_cast(tokens->At(2*param.fRuns.size()+2)); str = ostr->GetString(); if (str.IsFloat()) param.fYmax.push_back((Double_t)str.Atof()); else error = true; } } // clean up if (tokens) { delete tokens; tokens = 0; } } else if (iter1->fLine.Contains("use_fit_ranges", TString::kIgnoreCase)) { param.fUseFitRanges = true; // check if y-ranges are given tokens = iter1->fLine.Tokenize(" \t"); if (!tokens) { cerr << endl << ">> PMsrHandler::HandlePlotEntry: **SEVERE ERROR** Couldn't tokenize PLOT in line " << iter1->fLineNo; cerr << endl << endl; return false; } if (tokens->GetEntries() == 3) { // i.e. use_fit_ranges ymin ymax // handle y_min ostr = dynamic_cast(tokens->At(1)); str = ostr->GetString(); if (str.IsFloat()) param.fYmin.push_back((Double_t)str.Atof()); else error = true; // handle y_max ostr = dynamic_cast(tokens->At(2)); str = ostr->GetString(); if (str.IsFloat()) param.fYmax.push_back((Double_t)str.Atof()); else error = true; } if ((tokens->GetEntries() != 1) && (tokens->GetEntries() != 3)) { cerr << endl << ">> PMsrHandler::HandlePlotEntry: **WARNING** use_fit_ranges with undefined additional parameters in line " << iter1->fLineNo; cerr << endl << ">> Will ignore this PLOT block command line, sorry."; cerr << endl << ">> Proper syntax: use_fit_ranges [ymin ymax]"; cerr << endl << ">> Found: '" << iter1->fLine.Data() << "'" << endl; } // clean up if (tokens) { delete tokens; tokens = 0; } } else if (iter1->fLine.Contains("logx", TString::kIgnoreCase)) { param.fLogX = true; } else if (iter1->fLine.Contains("logy", TString::kIgnoreCase)) { param.fLogY = true; } else if (iter1->fLine.Contains("view_packing", TString::kIgnoreCase)) { tokens = iter1->fLine.Tokenize(" \t"); if (!tokens) { cerr << endl << ">> PMsrHandler::HandlePlotEntry: **SEVERE ERROR** Couldn't tokenize view_packing in line " << iter1->fLineNo; cerr << endl << endl; return false; } if (tokens->GetEntries() != 2) { error = true; } else { ostr = dynamic_cast(tokens->At(1)); str = ostr->GetString(); if (str.IsDigit()) { Int_t val = str.Atoi(); if (val > 0) param.fViewPacking = val; else error = true; } else { error = true; } } // clean up if (tokens) { delete tokens; tokens = 0; } } else if (iter1->fLine.Contains("rrf_freq", TString::kIgnoreCase)) { // expected entry: rrf_freq value unit // allowed units: kHz, MHz, Mc/s, G, T tokens = iter1->fLine.Tokenize(" \t"); if (!tokens) { cerr << endl << ">> PMsrHandler::HandlePlotEntry: **SEVERE ERROR** Couldn't tokenize rrf_freq in line " << iter1->fLineNo; cerr << endl << endl; return false; } if (tokens->GetEntries() != 3) { error = true; } else { // get rrf frequency ostr = dynamic_cast(tokens->At(1)); str = ostr->GetString(); if (str.IsFloat()) { param.fRRFFreq = str.Atof(); } else { error = true; } // get unit ostr = dynamic_cast(tokens->At(2)); str = ostr->GetString(); if (str.Contains("kHz", TString::kIgnoreCase)) param.fRRFUnit = RRF_UNIT_kHz; else if (str.Contains("MHz", TString::kIgnoreCase)) param.fRRFUnit = RRF_UNIT_MHz; else if (str.Contains("Mc/s", TString::kIgnoreCase)) param.fRRFUnit = RRF_UNIT_Mcs; else if (str.Contains("G", TString::kIgnoreCase)) param.fRRFUnit = RRF_UNIT_G; else if (str.Contains("T", TString::kIgnoreCase)) param.fRRFUnit = RRF_UNIT_T; else error = true; } // clean up if (tokens) { delete tokens; tokens = 0; } } else if (iter1->fLine.Contains("rrf_phase", TString::kIgnoreCase)) { // expected entry: rrf_phase value. value given in units of degree. or // rrf_phase parX. where X is the parameter number, e.g. par3 tokens = iter1->fLine.Tokenize(" \t"); if (!tokens) { cerr << endl << ">> PMsrHandler::HandlePlotEntry: **SEVERE ERROR** Couldn't tokenize rrf_phase in line " << iter1->fLineNo; cerr << endl << endl; return false; } if (tokens->GetEntries() != 2) { error = true; } else { // get rrf phase ostr = dynamic_cast(tokens->At(1)); str = ostr->GetString(); if (str.IsFloat()) { param.fRRFPhase = str.Atof(); } else { if (str.BeginsWith("par", TString::kIgnoreCase)) { // parameter value Int_t no = 0; if (FilterNumber(str, "par", 0, no)) { // check that the parameter is in range if ((Int_t)fParam.size() < no) { error = true; } else { // keep the parameter number in case parX was used param.fRRFPhaseParamNo = no; // get parameter value param.fRRFPhase = fParam[no-1].fValue; } } } else { error = true; } } } // clean up if (tokens) { delete tokens; tokens = 0; } } else if (iter1->fLine.Contains("rrf_packing", TString::kIgnoreCase)) { // expected entry: rrf_phase value. value given in units of degree tokens = iter1->fLine.Tokenize(" \t"); if (!tokens) { cerr << endl << ">> PMsrHandler::HandlePlotEntry: **SEVERE ERROR** Couldn't tokenize rrf_packing in line " << iter1->fLineNo; cerr << endl << endl; return false; } if (tokens->GetEntries() != 2) { error = true; } else { // get rrf packing ostr = dynamic_cast(tokens->At(1)); str = ostr->GetString(); if (str.IsDigit()) { param.fRRFPacking = str.Atoi(); } else { error = true; } } // clean up if (tokens) { delete tokens; tokens = 0; } } else { error = true; } ++iter1; } // analyze if the plot block is valid Double_t keep; if (!error) { if (param.fRuns.empty()) { // there was no run tag error = true; } else { // everything ok if ((param.fTmin.size() > 0) || (param.fTmax.size() > 0)) { // if range is given, check that it is ordered properly for (UInt_t i=0; i param.fTmax[i]) { keep = param.fTmin[i]; param.fTmin[i] = param.fTmax[i]; param.fTmax[i] = keep; } } } if ((param.fYmin.size() > 0) || (param.fYmax.size() > 0)) { // if range is given, check that it is ordered properly for (UInt_t i=0; i param.fYmax[i]) { keep = param.fYmin[i]; param.fYmin[i] = param.fYmax[i]; param.fYmax[i] = keep; } } } // check RRF entries if (param.fRRFFreq != 0.0) { if (param.fRRFPacking == 0) { cerr << endl << ">> PMsrHandler::HandlePlotEntry(): **ERROR** found RRF frequency but no required RRF packing."; cerr << endl << ">> Will ignore the RRF option."; cerr << endl; param.fRRFFreq = 0.0; } } // check if runs listed in the plot block indeed to exist for (UInt_t i=0; i static_cast(fRuns.size())) { cerr << endl << ">> PMsrHandler::HandlePlotEntry(): **WARNING** found plot run number " << param.fRuns[i] << "."; cerr << endl << ">> There are only " << fRuns.size() << " runs present, will ignore this run."; cerr << endl; param.fRuns.erase(param.fRuns.begin()+i); i--; } if (param.fRuns[i] == 0) { cerr << endl << ">> PMsrHandler::HandlePlotEntry(): **WARNING** found plot run number 0."; cerr << endl << ">> Pot number needs to be > 0. Will ignore this entry."; cerr << endl; param.fRuns.erase(param.fRuns.begin()+i); i--; } } if (param.fRuns.size() > 0) { fPlots.push_back(param); } else { cerr << endl << ">> PMsrHandler::HandlePlotEntry: **ERROR** no valid PLOT block entries, will ignore the entire PLOT block."; cerr << endl; } } } if (fPlots.size() == 0) { error = true; cerr << endl << ">> PMsrHandler::HandlePlotEntry: **ERROR** no valid PLOT block at all present. Fix this first!"; cerr << endl; } if (error) { // print error message --iter1; cerr << endl << ">> PMsrHandler::HandlePlotEntry: **ERROR** in line " << iter1->fLineNo << ": " << iter1->fLine.Data(); cerr << endl << ">> A PLOT block needs to have the following structure:"; cerr << endl; cerr << endl << ">> PLOT "; cerr << endl << ">> runs "; cerr << endl << ">> [range tmin tmax [ymin ymax]]"; cerr << endl << ">> [sub_ranges tmin1 tmax1 tmin2 tmax2 ... tminN tmaxN [ymin ymax]"; cerr << endl << ">> [logx | logy]"; cerr << endl << ">> [use_fit_ranges [ymin ymax]]"; cerr << endl << ">> [view_packing n]"; cerr << endl; cerr << endl << ">> where is: 0=single histo asym,"; cerr << endl << ">> 2=forward-backward asym,"; cerr << endl << ">> 4=mu minus single histo,"; cerr << endl << ">> 8=non muSR."; cerr << endl << ">> is the list of runs, e.g. runs 1 3"; cerr << endl << ">> range is optional"; cerr << endl << ">> sub_ranges (if present) will plot the N given runs each on its own sub-range"; cerr << endl << ">> logx, logy (if present) will present the x-, y-axis in log-scale"; cerr << endl << ">> use_fit_ranges (if present) will plot each run on its fit-range"; cerr << endl << ">> view_packing n (if present) will bin all data by n (> 0) rather than the binning of the fit"; cerr << endl; } param.fRuns.clear(); } return !error; } //-------------------------------------------------------------------------- // HandleStatisticEntry (private) //-------------------------------------------------------------------------- /** *

Handles the STATISTIC block of a msr-file. * * return: * - true if successful * - false otherwise * * \param lines is a list of lines containing the statistic block */ Bool_t PMsrHandler::HandleStatisticEntry(PMsrLines &lines) { // If msr-file is used for musrFT only, nothing needs to be done here. if (fFourierOnly) return true; if (lines.empty()) { cerr << endl << ">> PMsrHandler::HandleStatisticEntry: **WARNING** There is no STATISTIC block! Do you really want this?"; cerr << endl; fStatistic.fValid = false; return true; } Char_t str[128]; Char_t date[128]; Char_t time[128]; Int_t status; Double_t dval; UInt_t ival; TString tstr; for (UInt_t i=0; i 0) { if (!tstr.BeginsWith("#") && !tstr.BeginsWith("STATISTIC") && !tstr.BeginsWith("chisq") && !tstr.BeginsWith("maxLH") && !tstr.BeginsWith("*** FIT DID NOT CONVERGE ***") && !tstr.BeginsWith("expected chisq") && !tstr.BeginsWith("run block")) { cerr << endl << ">> PMsrHandler::HandleStatisticEntry: **SYNTAX ERROR** in line " << lines[i].fLineNo; cerr << endl << ">> '" << lines[i].fLine.Data() << "'"; cerr << endl << ">> not a valid STATISTIC block line"; cerr << endl << ">> If you do not understand this, just remove the STATISTIC block, musrfit will recreate after fitting"; cerr << endl << endl; return false; } } // filter date and chisq etc from strings // extract date and time if (lines[i].fLine.Contains("STATISTIC")) { status = sscanf(lines[i].fLine.Data(), "STATISTIC --- %s%s", date, time); if (status == 2) { fStatistic.fDate = TString(date)+TString(", ")+TString(time); } else { fStatistic.fDate = TString("????-??-??, ??:??:??"); } } // extract chisq if (lines[i].fLine.Contains("chisq =")) { if (lines[i].fLine.Contains("expected")) { // expected chisq strncpy(str, lines[i].fLine.Data(), sizeof(str)); status = sscanf(str+lines[i].fLine.Index("chisq = ")+8, "%lf", &dval); if (status == 1) { fStatistic.fMinExpected = dval; } else { fStatistic.fMinExpected = -1.0; } } else { // chisq fStatistic.fValid = true; strncpy(str, lines[i].fLine.Data(), sizeof(str)); status = sscanf(str+lines[i].fLine.Index("chisq = ")+8, "%lf", &dval); if (status == 1) { fStatistic.fMin = dval; } else { fStatistic.fMin = -1.0; } } } // extract maxLH if (lines[i].fLine.Contains("maxLH =")) { fStatistic.fValid = true; strncpy(str, lines[i].fLine.Data(), sizeof(str)); status = sscanf(str+lines[i].fLine.Index("maxLH = ")+8, "%lf", &dval); if (status == 1) { fStatistic.fMin = dval; } else { fStatistic.fMin = -1.0; } } // extract NDF if (lines[i].fLine.Contains(", NDF =")) { strncpy(str, lines[i].fLine.Data(), sizeof(str)); status = sscanf(str+lines[i].fLine.Index(", NDF = ")+8, "%u", &ival); if (status == 1) { fStatistic.fNdf = ival; } else { fStatistic.fNdf = 0; } } // keep string fStatistic.fStatLines.push_back(lines[i]); } return true; } //-------------------------------------------------------------------------- // GetNoOfFitParameters (public) //-------------------------------------------------------------------------- /** *

Calculate the number of fit parameters. * * \param idx run block index */ UInt_t PMsrHandler::GetNoOfFitParameters(UInt_t idx) { UInt_t noOfFitParameters = 0; PUIntVector paramVector; PUIntVector funVector; PUIntVector mapVector; TObjArray *tokens = 0; TObjString *ostr = 0; TString str; UInt_t k, dval; Int_t status, pos; // check that idx is valid if (idx >= fRuns.size()) { cerr << endl << ">> PMsrHandler::GetNoOfFitParameters() **ERROR** idx=" << idx << ", out of range fRuns.size()=" << fRuns.size(); cerr << endl; return 0; } // get N0 parameter, possible parameter number or function (single histo fit) if (fRuns[idx].GetNormParamNo() != -1) { if (fRuns[idx].GetNormParamNo() < MSR_PARAM_FUN_OFFSET) // parameter paramVector.push_back(fRuns[idx].GetNormParamNo()); else // function funVector.push_back(fRuns[idx].GetNormParamNo() - MSR_PARAM_FUN_OFFSET); } // get background parameter, for the case the background is fitted (single histo fit) if (fRuns[idx].GetBkgFitParamNo() != -1) paramVector.push_back(fRuns[idx].GetBkgFitParamNo()); // get alpha parameter if present (asymmetry fit) if (fRuns[idx].GetAlphaParamNo() != -1) paramVector.push_back(fRuns[idx].GetAlphaParamNo()); // get beta parameter if present (asymmetry fit) if (fRuns[idx].GetBetaParamNo() != -1) paramVector.push_back(fRuns[idx].GetBetaParamNo()); // go through the theory block and collect parameters // possible entries: number -> parameter, fun -> function, map -> maps for (UInt_t i=0; i= 0) str.Resize(pos); // tokenize tokens = str.Tokenize(" \t"); if (!tokens) { mapVector.clear(); funVector.clear(); paramVector.clear(); return 0; } for (Int_t j=0; jGetEntries(); j++) { ostr = dynamic_cast(tokens->At(j)); str = ostr->GetString(); // check for parameter number if (str.IsDigit()) { dval = str.Atoi(); paramVector.push_back(dval); } // check for map if (str.Contains("map")) { status = sscanf(str.Data(), "map%d", &dval); if (status == 1) { mapVector.push_back(dval); } } // check for function if (str.Contains("fun")) { status = sscanf(str.Data(), "fun%d", &dval); if (status == 1) { funVector.push_back(dval); } } } delete tokens; tokens = 0; } // go through the function block and collect parameters for (UInt_t i=0; i> PMsrHandler::GetNoOfFitParameters() **ERROR** couldn't find fun" << funVector[i]; cerr << endl << endl; // clean up mapVector.clear(); funVector.clear(); paramVector.clear(); return 0; } // remove potential comments str = fFunctions[k].fLine; pos = str.Index('#'); if (pos >= 0) str.Resize(pos); // tokenize tokens = str.Tokenize(" \t"); if (!tokens) { mapVector.clear(); funVector.clear(); paramVector.clear(); return 0; } // filter out parameters and maps for (Int_t j=0; jGetEntries(); j++) { ostr = dynamic_cast(tokens->At(j)); str = ostr->GetString(); // check for parameter if (str.BeginsWith("par")) { status = sscanf(str.Data(), "par%d", &dval); if (status == 1) paramVector.push_back(dval); } // check for map if (str.BeginsWith("map")) { status = sscanf(str.Data(), "map%d", &dval); if (status == 1) mapVector.push_back(dval); } } } // go through the map and collect parameters for (UInt_t i=0; iFills the fParamInUse vector. An element of the vector will be 0 if the fit parameter * is not used at all, otherwise it will be > 0. * * \param theory msr-file THEROY block lines * \param funcs msr-file FUNCTIONS block lines * \param run msr-file RUN blocks lines */ void PMsrHandler::FillParameterInUse(PMsrLines &theory, PMsrLines &funcs, PMsrLines &run) { PIntVector map; PIntVector fun; PMsrLines::iterator iter; TObjArray *tokens = 0; TObjString *ostr = 0; TString str; Int_t ival, funNo; // create and initialize fParamInUse vector for (UInt_t i=0; ifLine; if (str.First('#') != -1) str.Resize(str.First('#')); // everything to lower case str.ToLower(); // tokenize string tokens = str.Tokenize(" \t"); if (!tokens) continue; // filter param no, map no, and fun no for (Int_t i=0; iGetEntries(); i++) { ostr = dynamic_cast(tokens->At(i)); str = ostr->GetString(); if (str.IsDigit()) { // parameter number ival = str.Atoi(); if ((ival > 0) && (ival < (Int_t)fParam.size()+1)) { fParamInUse[ival-1]++; } } else if (str.Contains("map")) { // map if (FilterNumber(str, "map", MSR_PARAM_MAP_OFFSET, ival)) map.push_back(ival-MSR_PARAM_MAP_OFFSET); } else if (str.Contains("fun")) { // fun if (FilterNumber(str, "fun", MSR_PARAM_FUN_OFFSET, ival)) fun.push_back(ival-MSR_PARAM_FUN_OFFSET); } } // delete tokens if (tokens) { delete tokens; tokens = 0; } } // go through all the function lines: 1st time ----------------------------- for (iter = funcs.begin(); iter != funcs.end(); ++iter) { // remove potential comments str = iter->fLine; if (str.First('#') != -1) str.Resize(str.First('#')); // everything to lower case str.ToLower(); tokens = str.Tokenize(" /t"); if (!tokens) continue; // filter fun number ostr = dynamic_cast(tokens->At(0)); str = ostr->GetString(); if (!FilterNumber(str, "fun", MSR_PARAM_FUN_OFFSET, funNo)) continue; funNo -= MSR_PARAM_FUN_OFFSET; // check if fun number is used, and if yes, filter parameter numbers and maps TString sstr; for (UInt_t i=0; ifLine; Char_t sval[128]; while (sstr.Index("par") != -1) { memset(sval, 0, sizeof(sval)); sstr = &sstr[sstr.Index("par")+3]; // trunc sstr for (Int_t j=0; jfLine; while (sstr.Index("map") != -1) { memset(sval, 0, sizeof(sval)); sstr = &sstr[sstr.Index("map")+3]; // trunc sstr for (Int_t j=0; j 0) { UInt_t pos; for (pos=0; posfLine; if (str.First('#') != -1) str.Resize(str.First('#')); // everything to lower case str.ToLower(); // handle everything but the maps if (str.Contains("alpha") || str.Contains("beta") || str.Contains("alpha2") || str.Contains("beta2") || str.Contains("norm") || str.Contains("backgr.fit") || str.Contains("lifetime ")) { // tokenize string tokens = str.Tokenize(" \t"); if (!tokens) continue; if (tokens->GetEntries()<2) continue; ostr = dynamic_cast(tokens->At(1)); // parameter number or function str = ostr->GetString(); // check if parameter number if (str.IsDigit()) { ival = str.Atoi(); fParamInUse[ival-1]++; } // check if fun if (str.Contains("fun")) { if (FilterNumber(str, "fun", MSR_PARAM_FUN_OFFSET, ival)) { fun.push_back(ival-MSR_PARAM_FUN_OFFSET); } } // delete tokens if (tokens) { delete tokens; tokens = 0; } } // handle the maps if (str.Contains("map")) { // tokenize string tokens = str.Tokenize(" \t"); if (!tokens) continue; // get the parameter number via map for (UInt_t i=0; iGetEntries()) { ostr = dynamic_cast(tokens->At(map[i])); str = ostr->GetString(); if (str.IsDigit()) { ival = str.Atoi(); if (ival > 0) { fParamInUse[ival-1]++; // this is OK since map is ranging from 1 .. } } } } // delete tokens if (tokens) { delete tokens; tokens = 0; } } } // go through all the function lines: 2nd time ----------------------------- for (iter = funcs.begin(); iter != funcs.end(); ++iter) { // remove potential comments str = iter->fLine; if (str.First('#') != -1) str.Resize(str.First('#')); // everything to lower case str.ToLower(); tokens = str.Tokenize(" /t"); if (!tokens) continue; // filter fun number ostr = dynamic_cast(tokens->At(0)); str = ostr->GetString(); if (!FilterNumber(str, "fun", MSR_PARAM_FUN_OFFSET, funNo)) continue; funNo -= MSR_PARAM_FUN_OFFSET; // check if fun number is used, and if yes, filter parameter numbers and maps TString sstr; for (UInt_t i=0; ifLine; Char_t sval[128]; while (sstr.Index("par") != -1) { memset(sval, 0, sizeof(sval)); sstr = &sstr[sstr.Index("par")+3]; // trunc sstr for (Int_t j=0; jfLine; while (sstr.Index("map") != -1) { memset(sval, 0, sizeof(sval)); sstr = &sstr[sstr.Index("map")+3]; // trunc sstr for (Int_t j=0; j 0) { UInt_t pos; for (pos=0; posfLine; if (str.First('#') != -1) str.Resize(str.First('#')); // everything to lower case str.ToLower(); // handle the maps if (str.Contains("map")) { // tokenize string tokens = str.Tokenize(" \t"); if (!tokens) continue; // get the parameter number via map for (UInt_t i=0; iGetEntries()) { ostr = dynamic_cast(tokens->At(map[i])); str = ostr->GetString(); if (str.IsDigit()) { ival = str.Atoi(); if (ival > 0) { fParamInUse[ival-1]++; // this is OK since map is ranging from 1 .. } } } } // delete tokens if (tokens) { delete tokens; tokens = 0; } } } // if unused parameters are present, set the step value to 0.0 for (UInt_t i=0; i> **WARNING** : Parameter No " << i+1 << " is not used at all, will fix it" << endl; fParam[i].fStep = 0.0; } } } // clean up map.clear(); fun.clear(); } //-------------------------------------------------------------------------- // CheckRunBlockIntegrity (public) //-------------------------------------------------------------------------- /** *

Checks the consistency of each RUN block, i.e. are the necessary parameters * set and present, etc. * * return: * - true if the RUN blocks fulfill the minimal requirements. * - false otherwise */ Bool_t PMsrHandler::CheckRunBlockIntegrity() { // go through all the present RUN blocks Int_t fitType = 0; for (UInt_t i=0; i> PMsrHandler::CheckRunBlockIntegrity(): **ERROR** fittype is neither defined in RUN block number " << i+1 << ", nor in the GLOBAL block." << endl; return false; } } // check for the different fittypes differently switch (fitType) { case PRUN_SINGLE_HISTO: // check of norm is present if ((fRuns[i].GetNormParamNo() == -1) && !fFourierOnly) { cerr << endl << ">> PMsrHandler::CheckRunBlockIntegrity(): **ERROR** in RUN block number " << i+1; cerr << endl << ">> Norm parameter number not defined. Necessary for single histogram fits." << endl; return false; } if (!fFourierOnly) { // next check NOT needed for Fourier only // check if norm parameter is given that it is either a valid function of a fit parameter present if (fRuns[i].GetNormParamNo() < MSR_PARAM_FUN_OFFSET) { // parameter number // check that norm parameter number is not larger than the number of parameters if (fRuns[i].GetNormParamNo() > static_cast(fParam.size())) { cerr << endl << ">> PMsrHandler::CheckRunBlockIntegrity(): **ERROR** in RUN block number " << i+1; cerr << endl << ">> Norm parameter number " << fRuns[i].GetNormParamNo() << " is larger than the number of fit parameters (" << fParam.size() << ")."; cerr << endl << ">> Consider to check the manual ;-)" << endl; return false; } } else { // function norm if (fRuns[i].GetNormParamNo()-MSR_PARAM_FUN_OFFSET > GetNoOfFuncs()) { cerr << endl << ">> PMsrHandler::CheckRunBlockIntegrity(): **ERROR** in RUN block number " << i+1; cerr << endl << ">> Norm parameter function number " << fRuns[i].GetNormParamNo()-MSR_PARAM_FUN_OFFSET << " is larger than the number of functions (" << GetNoOfFuncs() << ")."; cerr << endl << ">> Consider to check the manual ;-)" << endl; return false; } } } // check that there is a forward parameter number if (fRuns[i].GetForwardHistoNo() == -1) { cerr << endl << ">> PMsrHandler::CheckRunBlockIntegrity(): **ERROR** in RUN block number " << i+1; cerr << endl << ">> forward parameter number not defined. Necessary for single histogram fits." << endl; return false; } if ((fRuns[i].GetNormParamNo() > static_cast(fParam.size())) && !fFourierOnly) { // check if forward histogram number is a function if (fRuns[i].GetNormParamNo() - MSR_PARAM_FUN_OFFSET > static_cast(fParam.size())) { cerr << endl << ">> PMsrHandler::CheckRunBlockIntegrity(): **ERROR** in RUN block number " << i+1; cerr << endl << ">> forward histogram number " << fRuns[i].GetNormParamNo() << " is larger than the number of fit parameters (" << fParam.size() << ")."; cerr << endl << ">> Consider to check the manual ;-)" << endl; return false; } } // check fit range if (!fRuns[i].IsFitRangeInBin() && !fFourierOnly) { // fit range given as times in usec (RUN block) if ((fRuns[i].GetFitRange(0) == PMUSR_UNDEFINED) || (fRuns[i].GetFitRange(1) == PMUSR_UNDEFINED)) { // check fit range in RUN block if (!fGlobal.IsFitRangeInBin()) { // fit range given as times in usec (GLOBAL block) if ((fGlobal.GetFitRange(0) == PMUSR_UNDEFINED) || (fGlobal.GetFitRange(1) == PMUSR_UNDEFINED)) { // check fit range in GLOBAL block cerr << endl << "PMsrHandler::CheckRunBlockIntegrity(): **ERROR** in RUN block number " << i+1; cerr << endl << " Fit range is not defined. Necessary for single histogram fits." << endl; return false; } } } } // check number of T0's provided if ((fRuns[i].GetT0BinSize() > fRuns[i].GetForwardHistoNoSize()) && (fGlobal.GetT0BinSize() > fRuns[i].GetForwardHistoNoSize())) { cerr << endl << ">> PMsrHandler::CheckRunBlockIntegrity(): **ERROR** in RUN block number " << i+1; cerr << endl << ">> Found " << fRuns[i].GetT0BinSize() << " T0 entries. Expecting only " << fRuns[i].GetForwardHistoNoSize() << ". Needs to be fixed." << endl; cerr << endl << ">> In GLOBAL block: " << fGlobal.GetT0BinSize() << " T0 entries. Expecting only " << fRuns[i].GetForwardHistoNoSize() << ". Needs to be fixed." << endl; return false; } // check packing if ((fRuns[i].GetPacking() == -1) && (fGlobal.GetPacking() == -1)) { cerr << endl << ">> PMsrHandler::CheckRunBlockIntegrity(): **WARNING** in RUN block number " << i+1; cerr << endl << ">> Packing is neither defined here, nor in the GLOBAL block, will set it to 1." << endl; fRuns[i].SetPacking(1); } break; case PRUN_ASYMMETRY: // check alpha if ((fRuns[i].GetAlphaParamNo() == -1) && !fFourierOnly) { cerr << endl << ">> PMsrHandler::CheckRunBlockIntegrity(): **ERROR** in RUN block number " << i+1; cerr << endl << ">> alpha parameter number missing which is needed for an asymmetry fit."; cerr << endl << ">> Consider to check the manual ;-)" << endl; return false; } // check that there is a forward parameter number if (fRuns[i].GetForwardHistoNo() == -1) { cerr << endl << ">> PMsrHandler::CheckRunBlockIntegrity(): **ERROR** in RUN block number " << i+1; cerr << endl << ">> forward histogram number not defined. Necessary for asymmetry fits." << endl; return false; } // check that there is a backward parameter number if (fRuns[i].GetBackwardHistoNo() == -1) { cerr << endl << ">> PMsrHandler::CheckRunBlockIntegrity(): **ERROR** in RUN block number " << i+1; cerr << endl << ">> backward histogram number not defined. Necessary for asymmetry fits." << endl; return false; } // check fit range if (!fRuns[i].IsFitRangeInBin()) { // fit range given as times in usec if ((fRuns[i].GetFitRange(0) == PMUSR_UNDEFINED) || (fRuns[i].GetFitRange(1) == PMUSR_UNDEFINED)) { if ((fGlobal.GetFitRange(0) == PMUSR_UNDEFINED) || (fGlobal.GetFitRange(1) == PMUSR_UNDEFINED)) { cerr << endl << ">> PMsrHandler::CheckRunBlockIntegrity(): **ERROR** in RUN block number " << i+1; cerr << endl << ">> Fit range is not defined, also NOT present in the GLOBAL block. Necessary for asymmetry fits." << endl; return false; } } } // check number of T0's provided if ((fRuns[i].GetT0BinSize() > 2*fRuns[i].GetForwardHistoNoSize()) && (fGlobal.GetT0BinSize() > 2*fRuns[i].GetForwardHistoNoSize())) { cerr << endl << ">> PMsrHandler::CheckRunBlockIntegrity(): **ERROR** in RUN block number " << i+1; cerr << endl << ">> Found " << fRuns[i].GetT0BinSize() << " T0 entries. Expecting only " << 2*fRuns[i].GetForwardHistoNoSize() << " in forward. Needs to be fixed." << endl; cerr << endl << ">> In GLOBAL block: " << fGlobal.GetT0BinSize() << " T0 entries. Expecting only " << 2*fRuns[i].GetForwardHistoNoSize() << ". Needs to be fixed." << endl; return false; } if ((fRuns[i].GetT0BinSize() > 2*fRuns[i].GetBackwardHistoNoSize()) && (fGlobal.GetT0BinSize() > 2*fRuns[i].GetBackwardHistoNoSize())) { cerr << endl << ">> PMsrHandler::CheckRunBlockIntegrity(): **ERROR** in RUN block number " << i+1; cerr << endl << ">> Found " << fRuns[i].GetT0BinSize() << " T0 entries. Expecting only " << 2*fRuns[i].GetBackwardHistoNoSize() << " in backward. Needs to be fixed." << endl; cerr << endl << ">> In GLOBAL block: " << fGlobal.GetT0BinSize() << " T0 entries. Expecting only " << 2*fRuns[i].GetBackwardHistoNoSize() << ". Needs to be fixed." << endl; return false; } // check packing if ((fRuns[i].GetPacking() == -1) && (fGlobal.GetPacking() == -1)) { cerr << endl << ">> PMsrHandler::CheckRunBlockIntegrity(): **WARNING** in RUN block number " << i+1; cerr << endl << ">> Packing is neither defined here, nor in the GLOBAL block, will set it to 1." << endl; fRuns[i].SetPacking(1); } break; case PRUN_MU_MINUS: // needs eventually to be implemented break; case PRUN_NON_MUSR: // check xy-data if ((fRuns[i].GetXDataIndex() == -1) && (fRuns[i].GetXDataLabel()->Length() == 0)) { cerr << endl << ">> PMsrHandler::CheckRunBlockIntegrity(): **ERROR** in RUN block number " << i+1; cerr << endl << ">> xy-data is missing. Necessary for non muSR fits." << endl; return false; } // check fit range if ((fRuns[i].GetFitRange(0) == PMUSR_UNDEFINED) || (fRuns[i].GetFitRange(1) == PMUSR_UNDEFINED)) { if ((fGlobal.GetFitRange(0) == PMUSR_UNDEFINED) || (fGlobal.GetFitRange(1) == PMUSR_UNDEFINED)) { cerr << endl << ">> PMsrHandler::CheckRunBlockIntegrity(): **ERROR** in RUN block number " << i+1; cerr << endl << ">> Fit range is not defined, neither in the RUN block, nor in the GLOBAL block."; cerr << endl << ">> Necessary for non muSR fits." << endl; return false; } } // check packing if (fRuns[i].GetPacking() == -1) { if (fGlobal.GetPacking() == -1) { cerr << endl << ">> PMsrHandler::CheckRunBlockIntegrity(): **WARNING** in RUN block number " << i+1; cerr << endl << ">> Packing is not defined, will set it to 1." << endl; fRuns[i].SetPacking(1); } } break; default: cerr << endl << ">> PMsrHandler::CheckRunBlockIntegrity(): **ERROR** fittype " << fitType << " undefined." << endl; return false; break; } } return true; } //-------------------------------------------------------------------------- // CheckUniquenessOfParamNames (public) //-------------------------------------------------------------------------- /** *

Checks if all the fit parameters are unique. If not parX, parY will show * the first occurence of equal fit parameter names. * * return: * - true if the fit parameter names are unique. * - false otherwise * * \param parX index of the 1st fit parameter name for which there is a counter part. * \param parY index of the counter part fit parameter name. */ Bool_t PMsrHandler::CheckUniquenessOfParamNames(UInt_t &parX, UInt_t &parY) { Bool_t unique = true; for (UInt_t i=0; iChecks if map entries found in the theory- or function-block are also * present in the run-block. * * return: * - true if maps or OK * - false otherwise */ Bool_t PMsrHandler::CheckMaps() { Bool_t result = true; PIntVector mapVec; PIntVector mapBlock; PIntVector mapLineNo; TObjArray *tokens = 0; TObjString *ostr = 0; TString str; Int_t no; // check if map is present in the theory-block for (UInt_t i=0; iGetEntries(); j++) { ostr = dynamic_cast(tokens->At(j)); str = ostr->GetString(); if (str.Contains("map", TString::kIgnoreCase)) { if (FilterNumber(str, "map", MSR_PARAM_MAP_OFFSET, no)) { mapVec.push_back(no); mapBlock.push_back(0); // 0 = theory-block mapLineNo.push_back(fTheory[i].fLineNo); } } } // clean up tokens if (tokens) { delete tokens; tokens = 0; } } } // check if map is present in the function-block for (UInt_t i=0; iGetEntries(); j++) { ostr = dynamic_cast(tokens->At(j)); str = ostr->GetString(); if (str.Contains("map", TString::kIgnoreCase)) { if (FilterNumber(str, "map", MSR_PARAM_MAP_OFFSET, no)) { mapVec.push_back(no); mapBlock.push_back(1); // 1 = theory-block mapLineNo.push_back(fTheory[i].fLineNo); } } } // clean up tokens if (tokens) { delete tokens; tokens = 0; } } } // check if present maps are found in the run-block Bool_t found; for (UInt_t i=0; isize()) && (mapVec[i]-MSR_PARAM_MAP_OFFSET-1 >= 0)) { // map value smaller than run-block map length if (fRuns[j].GetMap(mapVec[i]-MSR_PARAM_MAP_OFFSET-1) != 0) { // map value in the run-block != 0 found = true; break; } } } if (!found) { // map not found result = false; cerr << endl << ">> PMsrHandler::CheckMaps: **ERROR** map" << mapVec[i]-MSR_PARAM_MAP_OFFSET << " found in the "; if (mapBlock[i] == 0) cerr << "theory-block "; else cerr << "functions-block "; cerr << "in line " << mapLineNo[i] << " is not present in the run-block!"; cerr << endl; if (mapVec[i]-MSR_PARAM_MAP_OFFSET == 0) { cerr << endl << ">> by the way: map must be > 0 ..."; cerr << endl; } } } // clean up mapVec.clear(); mapBlock.clear(); mapLineNo.clear(); return result; } //-------------------------------------------------------------------------- // CheckFuncs (public) //-------------------------------------------------------------------------- /** *

Checks if fun entries found in the theory- and run-block are also * present in the functions-block. * * return: * - true if fun entries or present in the FUNCTIONS block * - false otherwise */ Bool_t PMsrHandler::CheckFuncs() { Bool_t result = true; if (fFourierOnly) return result; PIntVector funVec; PIntVector funBlock; PIntVector funLineBlockNo; TObjArray *tokens = 0; TObjString *ostr = 0; TString str; Int_t no; // check if func is present in the theory-block for (UInt_t i=0; iGetEntries(); j++) { ostr = dynamic_cast(tokens->At(j)); str = ostr->GetString(); if (str.Contains("fun", TString::kIgnoreCase)) { if (FilterNumber(str, "fun", MSR_PARAM_FUN_OFFSET, no)) { funVec.push_back(no); funBlock.push_back(0); // 0 = theory-block funLineBlockNo.push_back(fTheory[i].fLineNo); } } } // clean up tokens if (tokens) { delete tokens; tokens = 0; } } } // check if func is present in the run-block for (UInt_t i=0; i= MSR_PARAM_FUN_OFFSET) { // function found funVec.push_back(fRuns[i].GetNormParamNo()); funBlock.push_back(1); // 1 = run-block funLineBlockNo.push_back(i+1); } } // check if present funcs are found in the functions-block Bool_t found; for (UInt_t i=0; i> PMsrHandler::CheckFuncs: **ERROR** fun" << funVec[i]-MSR_PARAM_FUN_OFFSET << " found in the "; if (funBlock[i] == 0) cerr << "theory-block in line " << funLineBlockNo[i] << " is not present in the functions-block!"; else cerr << "run-block No " << funLineBlockNo[i] << " (norm) is not present in the functions-block!"; cerr << endl; } } // clean up funVec.clear(); funBlock.clear(); funLineBlockNo.clear(); return result; } //-------------------------------------------------------------------------- // CheckHistoGrouping (public) //-------------------------------------------------------------------------- /** *

Checks if histogram grouping makes any sense. * * return: * - true if histogram grouping seems OK * - false otherwise */ Bool_t PMsrHandler::CheckHistoGrouping() { Bool_t result = true; for (UInt_t i=0; i> PMsrHandler::CheckHistoGrouping: **ERROR** # of forward histos != # of backward histos."; cerr << endl << ">> Run #" << i+1; cerr << endl; result = false; break; } } // check grouping entries are not identical, e.g. forward 1 1 2 if (fRuns[i].GetForwardHistoNoSize() > 1) { for (UInt_t j=0; j> PMsrHandler::CheckHistoGrouping: **WARNING** grouping identical histograms!!"; cerr << endl << ">> run no " << i+1 << ", forward histo " << j+1 << " == forward histo " << k+1 << "."; cerr << endl << ">> this really doesn't make any sense, but you are the boss."; cerr << endl; } } } } if (fRuns[i].GetBackwardHistoNoSize() > 1) { for (UInt_t j=0; j> PMsrHandler::CheckHistoGrouping: **WARNING** grouping identical histograms!!"; cerr << endl << ">> run no " << i+1 << ", backward histo " << j+1 << " == backward histo " << k+1 << "."; cerr << endl << ">> this really doesn't make any sense, but you are the boss."; cerr << endl; } } } } } return result; } //-------------------------------------------------------------------------- // CheckAddRunParameters (public) //-------------------------------------------------------------------------- /** *

In case addrun is present check that if addt0's are given there are as many addt0's than addrun's. * * return: * - true if either no addt0 present, or # of addrun's == # of addt0's. * - false otherwise */ Bool_t PMsrHandler::CheckAddRunParameters() { Bool_t result = true; for (UInt_t i=0; i 1) { // check concerning the addt0 tags if (fRuns[i].GetAddT0BinEntries() != 0) { if (fRuns[i].GetAddT0BinEntries() != fRuns[i].GetRunNameSize()-1) { cerr << endl << ">> PMsrHandler::CheckAddRunParameters: **ERROR** # of addt0 != # of addruns."; cerr << endl << ">> Run #" << i+1; cerr << endl; result = false; break; } } } } return result; } //-------------------------------------------------------------------------- // CheckMaxLikelihood (public) //-------------------------------------------------------------------------- /** *

If log max likelihood is requested, make sure that all run blocks are of single histogram type. * If this is not the case, fall back to chisq, since for asymmetry/non-muSR fit, log max likelihood * is not defined. */ void PMsrHandler::CheckMaxLikelihood() { if (!fStatistic.fChisq) { for (UInt_t i=0; i> PMsrHandler::CheckMaxLikelihood: **WARNING**: Maximum Log Likelihood Fit is only implemented"; cerr << endl << ">> for Single Histogram Fit. Will fall back to Chi Square Fit."; cerr << endl << endl; fStatistic.fChisq = true; break; } } } } //-------------------------------------------------------------------------- // GetGroupingString (public) //-------------------------------------------------------------------------- /** *

returns the forward/backward grouping string. * * \param runNo msr-file run block number * \param detector tag telling which set to be used. Possible are: 'forward' and 'backward' * \param groupingStr compressed grouping information. */ void PMsrHandler::GetGroupingString(Int_t runNo, TString detector, TString &groupingStr) { PIntVector grouping; if (!detector.CompareTo("forward", TString::kIgnoreCase)) { for (UInt_t i=0; ireturns if N0 shall be estimated */ Bool_t PMsrHandler::EstimateN0() { if (fStartupOptions == 0) return true; return fStartupOptions->estimateN0; } //-------------------------------------------------------------------------- // GetAlphaEstimateN0 (public) //-------------------------------------------------------------------------- /** *

returns alpha to estimate N0 */ Double_t PMsrHandler::GetAlphaEstimateN0() { if (fStartupOptions == 0) return 0.0; return fStartupOptions->alphaEstimateN0; } //-------------------------------------------------------------------------- // NeededPrecision (private) //-------------------------------------------------------------------------- /** *

Calculates the needed precision of Double_t values for WriteMsrLogFile and WriteMsrFile of the fit range. * If a precision of > precLimit decimal places is needed, a warning is placed and a value of precLimit is returned. * * \param dval value for which the precision has to be estimated * \param precLimit precision limit * * return: needed precision */ UInt_t PMsrHandler::NeededPrecision(Double_t dval, UInt_t precLimit) { UInt_t prec=0; if (dval == 0.0) return prec; for (UInt_t i=0; i> PMsrHandler::NeededPrecision(): **WARNING** precision limit of " << precLimit << ", requested."; } return prec; } //-------------------------------------------------------------------------- // LastSignifiant (private) //-------------------------------------------------------------------------- /** *

Gets the last significant digit down to precLimit. * * \param dval value for which the last signigicant digit shall be found * \param precLimit precision limit * * return: last significant digit down to precLimit */ UInt_t PMsrHandler::LastSignificant(Double_t dval, UInt_t precLimit) { UInt_t lastSignificant = 2; UInt_t decimalPoint = 0; char str[128]; sprintf(str, "%lf", dval); // find decimal point for (UInt_t i=0; i=0; i--) { if (str[i] != '0') { if ((i-decimalPoint) < precLimit) lastSignificant = i-decimalPoint; else lastSignificant = precLimit; break; } } return lastSignificant; } //-------------------------------------------------------------------------- // ParseDetectorGrouping (private) //-------------------------------------------------------------------------- /** *

* * \param str forward/backward string to be decoded * \param group decoded detector grouping vector * * return: true if parsing was successful, false otherwise. */ Bool_t PMsrHandler::ParseDetectorGrouping(TString str, PIntVector &group) { TObjArray *tok=0, *tok1=0; TObjString *ostr=0; Int_t first=0, last=0; // change cn - cm to cn-cm. Will *NOT* handle cn - cm etc str = str.ReplaceAll(" - ", "-"); group.clear(); tok = str.Tokenize(" \t"); // check that there are indeed enough tokens if (tok->GetEntries() < 2) { delete tok; return false; } for (Int_t i=1; iGetEntries(); i++) { ostr = dynamic_cast(tok->At(i)); if (ostr->GetString().Contains("-")) { // hopefully a cn-cm token tok1 = ostr->GetString().Tokenize("-"); if (tok1->GetEntries() == 2) { ostr = dynamic_cast(tok1->At(0)); if (ostr->GetString().IsDigit()) { first = ostr->GetString().Atoi(); } else { if (tok) delete tok; if (tok1) delete tok1; return false; } ostr = dynamic_cast(tok1->At(1)); if (ostr->GetString().IsDigit()) { last = ostr->GetString().Atoi(); } else { if (tok) delete tok; if (tok1) delete tok1; return false; } if (last < first) { if (tok) delete tok; return false; } for (Int_t i=first; i<=last; i++) group.push_back(i); } else { if (tok) delete tok; if (tok1) delete tok1; return false; } } else { // hopefully a number if (ostr->GetString().IsDigit()) { group.push_back(ostr->GetString().Atoi()); } else { if (tok) delete tok; return false; } } } // clean up if (tok) delete tok; if (tok1) delete tok1; return true; } //-------------------------------------------------------------------------- // MakeDetectorGroupingString (private) //-------------------------------------------------------------------------- /** *

encodes the detector grouping vector. * * \param str 'forward' or 'backward' * \param group detector grouping vector to be encoded * \param result encoded detector grouping string * \param includeDetector if true, the detector information is included */ void PMsrHandler::MakeDetectorGroupingString(TString str, PIntVector &group, TString &result, Bool_t includeDetector) { if (includeDetector) { result = str + TString(" "); if (str == TString("forward")) result += " "; } else { str = ""; } UInt_t i=0, j=0; do { j = i; while (group[j]+1 == group[j+1]) { j++; if (j == group.size()-1) break; } if (j >= i+2) { result += group[i]; result += "-"; result += group[j]; i = j+1; } else { result += group[i]; i++; } result += " "; } while (iChecks for lifetimecorrection flags in the RUN-blocks and if present, * transfer it to the PLOT-blocks. This is needed since originally the lifetimecorrection * was (miss)placed in the RUN-blocks rather than in the PLOT-blocks where it * most naturally would have been expected. */ void PMsrHandler::CheckLegacyLifetimecorrection() { UInt_t idx=0; for (UInt_t i=0; i