/*************************************************************************** PMsrHandler.cpp Author: Andreas Suter e-mail: andreas.suter@psi.ch $Id$ ***************************************************************************/ /*************************************************************************** * Copyright (C) 2007-2010 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) : fFileName(fileName) { // init variables fMsrBlockCounter = 0; fTitle = ""; fCopyStatisticsBlock = false; fStatistic.fValid = false; fStatistic.fChisq = true; fStatistic.fMin = -1.0; fStatistic.fNdf = 0; 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(); 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 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("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_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 (!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; // fill parameter-in-use vector if (result == PMUSR_SUCCESS) FillParameterInUse(theory, functions, run); // check that each run fulfills the minimum requirements if (result == PMUSR_SUCCESS) if (!CheckRunBlockIntegrity()) result = PMUSR_MSR_SYNTAX_ERROR; // check that parameter names are unique if (result == PMUSR_SUCCESS) { UInt_t parX, parY; if (!CheckUniquenessOfParamNames(parX, parY)) { cerr << endl << ">> 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) 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; // clean up fit_parameter.clear(); theory.clear(); functions.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; // output precision for float/doubles 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 fout.width(9); fout.precision(prec); fout << left << fParam[number].fValue; fout << " "; // value of step/error/neg.error fout.width(11); fout.precision(prec); fout << left << fParam[number].fStep; fout << " "; fout.width(11); fout.precision(prec); 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 << " "; // 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(number-1); sstr.ToLower(); fout << sstr.Data() << endl; } } else { fout << str.Data() << endl; } break; case MSR_TAG_RUN: sstr = str; sstr.Remove(TString::kLeading, ' '); if (sstr.BeginsWith("RUN")) { 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")) { addRunNo = 0; 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")) { if ((fRuns[runNo].IsLifetimeCorrected()) && (fRuns[runNo].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 { fout.width(16); fout << left << "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 { fout.width(16); fout << left << "backward"; for (UInt_t i=0; i 0) { fout.width(8); fout << left << fRuns[runNo].GetBkgRange(j); } } 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 (t0TagMissing[runNo]) { if (fRuns[runNo].GetT0Size() > 0) { fout.width(16); fout << left << "t0"; for (UInt_t j=0; j 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<2; j++) { 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<2; j++) { fout.width(8); fout << left << fRuns[runNo].GetDataRange(j); } fout << endl; } } // write fit range line fout.width(16); fout << left << "fit"; for (UInt_t j=0; j<2; j++) { if (fRuns[runNo].GetFitRange(j) == -1) break; fout.width(8); fout.precision(2); fout << left << fixed << fRuns[runNo].GetFitRange(j); } 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_FIELD) { fout << "Gauss"; } else if (fFourier.fUnits == FOURIER_UNIT_FREQ) { fout << "MHz "; } else if (fFourier.fUnits == FOURIER_UNIT_CYCLES) { fout << "Mc/s"; } fout << " # units either 'Gauss', 'MHz', or 'Mc/s'"; fout << endl; } else if (sstr.BeginsWith("fourier_power")) { fout << "fourier_power " << fFourier.fFourierPower << 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; } } else if (sstr.BeginsWith("runs")) { fout << "runs "; fout.precision(0); for (UInt_t j=0; j 0) { fout << " " << fPlots[plotNo].fYmin[0] << " " << 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")) { partialStatisticBlockFound = false; if (fStatistic.fValid) { // valid fit result str = " chisq = "; str += fStatistic.fMin; str += ", NDF = "; str += fStatistic.fNdf; str += ", chisq/NDF = "; str += 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("maxLH")) { partialStatisticBlockFound = false; if (fStatistic.fValid) { // valid fit result str = " maxLH = "; str += fStatistic.fMin; str += ", NDF = "; str += fStatistic.fNdf; str += ", maxLH/NDF = "; str += 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 = " chisq = "; str += fStatistic.fMin; str += ", NDF = "; str += fStatistic.fNdf; str += ", chisq/NDF = "; str += fStatistic.fMin / fStatistic.fNdf; fout << str.Data() << endl; if (messages) cout << endl << 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; 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) 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) { // chisq str = " chisq = "; str += fStatistic.fMin; str += ", NDF = "; str += fStatistic.fNdf; str += ", chisq/NDF = "; str += fStatistic.fMin / fStatistic.fNdf; fout << str.Data() << endl; if (messages) cout << endl << 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; if (messages) cout << endl << str.Data() << endl; } } 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 = " chisq = "; str += fStatistic.fMin; str += ", NDF = "; str += fStatistic.fNdf; str += ", chisq/NDF = "; str += fStatistic.fMin / fStatistic.fNdf; fout << str.Data() << endl; if (messages) cout << endl << 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; if (messages) cout << endl << str.Data() << endl; } } else { fout << "*** FIT DID NOT CONVERGE ***" << 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 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 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].GetT0Size() > 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"; for (UInt_t j=0; j<2; j++) { if (fRuns[i].GetFitRange(j) == -1) break; fout.width(8); fout.precision(2); fout << left << fixed << fRuns[i].GetFitRange(j); } 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_FIELD) { fout << "Gauss"; } else if (fFourier.fUnits == FOURIER_UNIT_FREQ) { fout << "MHz "; } else if (fFourier.fUnits == FOURIER_UNIT_CYCLES) { fout << "Mc/s"; } fout << " # units either 'Gauss', '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) { 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, Int_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].GetT0Size()) { // error cerr << endl << ">> PMsrHandler::SetMsrT0Entry: **WARNING** idx = " << idx << ", is out of valid range 0.." << fRuns[runNo].GetT0Size(); cerr << endl << ">> Will add it anyway."; cerr << endl; } fRuns[runNo].SetT0(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, Int_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].GetAddT0Entries()) { // error cerr << endl << ">> PMsrHandler::SetMsrAddT0Entry: **WARNING** addRunIdx = " << addRunIdx << ", is out of valid range 0.." << fRuns[runNo].GetAddT0Entries(); cerr << endl << ">> Will add it anyway."; cerr << endl; } if (static_cast(histoIdx) > fRuns[runNo].GetAddT0Size(addRunIdx)) { // error cerr << endl << ">> PMsrHandler::SetMsrAddT0Entry: **WARNING** histoIdx = " << histoIdx << ", is out of valid range 0.." << fRuns[runNo].GetAddT0Size(addRunIdx); cerr << endl << ">> Will add it anyway."; cerr << endl; } fRuns[runNo].SetAddT0(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) { 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) { // 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) { // 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: **ERROR** empty FUNCTIONS block are not supported!"; cerr << endl << ">> If you want to keep it, just comment the whole block ;-)"; cerr << endl; return false; } return true; } //-------------------------------------------------------------------------- // 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; iter = lines.begin(); while ((iter != lines.end()) && !error) { // tokenize line tokens = iter->fLine.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 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 { 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.SetForwardHistoNo(ival); else error = true; } else { error = true; } } } } // backward ----------------------------------------------- if (iter->fLine.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 { 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.SetBackwardHistoNo(ival); else error = true; } else { error = true; } } } } // backgr.fix ---------------------------------------------- if (iter->fLine.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.IsDigit()) { ival = str.Atoi(); if (ival > 0) param.SetT0(ival); 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.IsDigit()) { ival = str.Atoi(); if (ival > 0) param.SetAddT0(ival, 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 { 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) { PMsrLines::iterator iter; if (lines.empty()) { cerr << endl << "**WARNING**: There is no COMMANDS 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.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) { //cout << endl << ">> in PMsrHandler::HandleFourierEntry ..."; Bool_t error = false; if (lines.empty()) // no fourier block present return true; //cout << endl << ">> in PMsrHandler::HandleFourierEntry, Fourier block present ..."; 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::HandleRunEntry: **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_FIELD; } 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("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 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 << "[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; TObjArray *tokens2 = 0; TObjString *ostr = 0; TString str; TString str2; if (lines.empty()) { cerr << endl << "**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.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.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("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: 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; case MSR_PLOT_MU_MINUS: // like: runs 1,1 1,2 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)); // something like 1,2 str = ostr->GetString(); tokens2 = str.Tokenize(","); if (!tokens2) { error = true; } else { ostr = dynamic_cast(tokens2->At(0)); // real part str = ostr->GetString(); ostr = dynamic_cast(tokens2->At(1)); // imag part str2 = ostr->GetString(); if (str.IsDigit() && str2.IsDigit()) { run = TComplex(str.Atoi(),str2.Atoi()); param.fRuns.push_back(run); } else { error = true; } } if (tokens2) { delete tokens2; tokens2 = 0; } } } // 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; } 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]"; 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 singhle histo (not implemented yet),"; 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 (lines.empty()) { cerr << endl << ">> PMsrHandler::HandleStatisticEntry: **WARNING** There is no STATISTIC block! Do you really want this?"; cerr << endl; fStatistic.fValid = false; return true; } // check if chisq or max.log likelihood fStatistic.fChisq = true; 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 ***")) { 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 =")) { 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; } //-------------------------------------------------------------------------- // FillParameterInUse (private) //-------------------------------------------------------------------------- /** *

Fills 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; iChecks 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 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].GetForwardHistoNo() > 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].GetFitRange(0) == PMUSR_UNDEFINED) || (fRuns[i].GetFitRange(1) == PMUSR_UNDEFINED)) { 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 packing if (fRuns[i].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; case PRUN_ASYMMETRY: // check alpha if (fRuns[i].GetAlphaParamNo() == -1) { 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 single histogram 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 single histogram fits." << endl; return false; } // check fit range if ((fRuns[i].GetFitRange(0) == PMUSR_UNDEFINED) || (fRuns[i].GetFitRange(1) == PMUSR_UNDEFINED)) { 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 packing if (fRuns[i].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; 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)) { 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 packing if (fRuns[i].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 (private) //-------------------------------------------------------------------------- /** *

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 (private) //-------------------------------------------------------------------------- /** *

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; 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 (private) //-------------------------------------------------------------------------- /** *

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 (private) //-------------------------------------------------------------------------- /** *

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].GetAddT0Entries() != 0) { if (fRuns[i].GetAddT0Entries() != 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; } // end ---------------------------------------------------------------------