newly added. Not for productive used yetsvn diff | grep Index:

This commit is contained in:
nemu
2008-01-08 08:31:58 +00:00
commit c6cc508aaf
85 changed files with 14397 additions and 0 deletions

31
src/classes/BUILD Normal file
View File

@ -0,0 +1,31 @@
*************************************************************
Build instructions for the shared library libPMusr.so
Andreas Suter, 2008/01/08
$Id$
*************************************************************
At the moment a lot of the build stuff has to be done manually.
I will eventually migrate to cmake and than it will be much more
automatically.
Required packages:
* ROOT >= 5.16 : needed for read/write some data files, plotting, ...
* Minuit2 >= 5.08 : needed for fitting
* Spirit >= 1.8.5 : needed for parsing (this is part of the boost lib, and
hence installed on most linux machines). The boost libs
are platform independent and hence it should be easy in
the future to migrate also to Windows and Mac OS
Build instructions:
make -f Makefile.PMusr
than as root
make -f Makefile.PMusr install

138
src/classes/Makefile.PMusr Normal file
View File

@ -0,0 +1,138 @@
#---------------------------------------------------
# Makefile.PMusr
#
# Author: Andreas Suter
# e-mail: andreas.suter@psi.ch
#
# $Id$
#
# Comment: If it doesn't work, try
# make --warning-undefined-variables -f Makefile.PMusr
# it might be that OSTYPE is not set properly, i.e.
# OSTYPE being a variable (set), instead of a enviornment
# variable (printenv). If so, try
# export OSTYPE=linux-gnu
# are whatever makes sense on your system.
#---------------------------------------------------
#---------------------------------------------------
# get compilation and library flags from root-config
ROOTCFLAGS = $(shell $(ROOTSYS)/bin/root-config --cflags)
ROOTLIBS = $(shell $(ROOTSYS)/bin/root-config --libs)
ROOTGLIBS = $(shell $(ROOTSYS)/bin/root-config --glibs)
#---------------------------------------------------
# depending on the architecture, choose the compiler,
# linker, and the flags to use
#
ifeq ($(OSTYPE),linux)
OS = LINUX
endif
ifeq ($(OSTYPE),linux-gnu)
OS = LINUX
endif
ifeq ($(OSTYPE),darwin)
OS = DARWIN
endif
# -- Linux
ifeq ($(OS),LINUX)
CXX = g++
CXXFLAGS = -g -Wall -fPIC
PMUSRPATH = ../include
MNPATH = /usr/local/include
INCLUDES = -I $(PMUSRPATH) -I $(MNPATH)
LD = g++
LDFLAGS = -g
SOFLAGS = -O -shared
endif
# -- Darwin
ifeq ($(OS),DARWIN)
CXX = g++
CXXFLAGS = -g -Wall -fPIC
INCLUDES = -I../include
LD = g++
LDFLAGS = -g
SOFLAGS = -dynamic
endif
# the output from the root-config script:
CXXFLAGS += $(ROOTCFLAGS)
LDFLAGS +=
# the ROOT libraries (G = graphic)
LIBS = $(ROOTLIBS) -lXMLParser
GLIBS = $(ROOTGLIBS) -lXMLParser
# PSI libs
PSILIBS = -lTLemRunHeader
# Minuit2 lib
MNLIB = -L/usr/local/lib -lMinuit2Base
# some definitions: headers, sources, objects,...
HEADERS =
HEADERS += PStartupHandler.h
HEADERS += PMsrHandler.h
HEADERS += PRunDataHandler.h
HEADERS += PFunctionHandler.h
HEADERS += PFunctionGrammar.h
HEADERS += PFunction.h
HEADERS += PRunBase.h
HEADERS += PRunSingleHisto.h
HEADERS += PRunAsymmetry.h
HEADERS += PRunRRF.h
HEADERS += PRunNonMusr.h
HEADERS += PRunListCollection.h
HEADERS += PTheory.h
HEADERS += PFitterFcn.h
HEADERS += PFitter.h
OBJS =
OBJS += PStartupHandler.o
OBJS += PMsrHandler.o
OBJS += PRunDataHandler.o
OBJS += PFunctionHandler.o
OBJS += PFunction.o
OBJS += PRunBase.o
OBJS += PRunSingleHisto.o
OBJS += PRunAsymmetry.o
OBJS += PRunRRF.o
OBJS += PRunNonMusr.o
OBJS += PRunListCollection.o
OBJS += PTheory.o
OBJS += PFitterFcn.o
OBJS += PFitter.o
SHLIB = libPMusr.so
# make the shared lib:
#
all: $(SHLIB)
$(SHLIB): $(OBJS)
@echo "---> Building shared library $(SHLIB) ..."
/bin/rm -f $(SHLIB)
$(LD) $(OBJS) $(SOFLAGS) -o $(SHLIB) $(GLIBS) $(PSILIBS) $(MNLIB)
@echo "done"
# clean up: remove all object file (and core files)
# semicolon needed to tell make there is no source
# for this target!
#
clean:; @rm -f $(OBJS) *Dict* core*
@echo "---> removing $(OBJS)"
#
$(OBJS): %.o: %.cpp
$(CXX) $(INCLUDES) $(CXXFLAGS) -c $<
install: all
@echo "Installing shared lib: libPMusr.so ( you must be root ;-) )"
ifeq ($(OS),LINUX)
cp -pv $(SHLIB) $(ROOTSYS)/lib
cp -pv $(PMUSRPATH)/*.h $(ROOTSYS)/include
endif

478
src/classes/PFitter.cpp Normal file
View File

@ -0,0 +1,478 @@
/***************************************************************************
PFitter.cpp
Author: Andreas Suter
e-mail: andreas.suter@psi.ch
$Id$
***************************************************************************/
/***************************************************************************
* Copyright (C) 2007 by Andreas Suter *
* andreas.suter@psi.c *
* *
* 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 <iostream>
using namespace std;
#include "Minuit2/FunctionMinimum.h"
#include "Minuit2/MnMinimize.h"
#include "Minuit2/MnMigrad.h"
#include "Minuit2/MnMinos.h"
#include "Minuit2/MnSimplex.h"
#include "PFitter.h"
//--------------------------------------------------------------------------
// Constructor
//--------------------------------------------------------------------------
/**
* <p>
*
* \param runInfo
* \param runListCollection
*/
PFitter::PFitter(PMsrHandler *runInfo, PRunListCollection *runListCollection) :
fRunInfo(runInfo)
{
fUseChi2 = true; // chi^2 is the default
fParams = *(runInfo->GetMsrParamList());
fCmdLines = *runInfo->GetMsrCommands();
// init class variables
fFitterFcn = 0;
fFcnMin = 0;
// check msr minuit commands
if (!CheckCommands()) {
return;
}
// create fit function object
fFitterFcn = new PFitterFcn(runListCollection, fUseChi2);
if (!fFitterFcn) {
fIsValid = false;
return;
}
}
//--------------------------------------------------------------------------
// Destructor
//--------------------------------------------------------------------------
/**
* <p>
*
*/
PFitter::~PFitter()
{
fCmdList.clear();
if (fFitterFcn) {
delete fFitterFcn;
fFitterFcn = 0;
}
}
//--------------------------------------------------------------------------
// DoFit
//--------------------------------------------------------------------------
/**
* <p>
*
*/
bool PFitter::DoFit()
{
if (fUseChi2)
cout << endl << "Chi Square fit will be executed" << endl;
else
cout << endl << "Maximum Likelihood fit will be executed" << endl;
// feed minuit parameters
SetParameters();
bool status;
for (unsigned int i=0; i<fCmdList.size(); i++) {
switch (fCmdList[i]) {
case PMN_INTERACTIVE:
break;
case PMN_CONTOURS:
break;
case PMN_EIGEN:
break;
case PMN_HESSE:
break;
case PMN_MACHINE_PRECISION:
break;
case PMN_MIGRAD:
status = ExecuteMigrad();
break;
case PMN_MINIMIZE:
status = ExecuteMinimize();
break;
case PMN_MINOS:
status = ExecuteMinos();
break;
case PMN_PLOT:
break;
case PMN_SAVE:
status = ExecuteSave();
break;
case PMN_SCAN:
break;
case PMN_SIMPLEX:
status = ExecuteSimplex();
break;
case PMN_USER_COVARIANCE:
break;
case PMN_USER_PARAM_STATE:
break;
case PMN_PRINT:
break;
default:
cout << endl << "**PANIC ERROR**: PFitter::DoFit(): You should never have reached this point" << endl;
exit(0);
break;
}
}
return true;
}
//--------------------------------------------------------------------------
// CheckCommands
//--------------------------------------------------------------------------
/**
* <p>
*
*/
bool PFitter::CheckCommands()
{
fIsValid = true;
PMsrLines::iterator it;
for (it = fCmdLines.begin(); it != fCmdLines.end(); ++it) {
it->fLine.ToUpper();
if (it->fLine.Contains("COMMANDS")) {
continue;
} else if (it->fLine.Contains("SET BATCH")) { // needed for backward compatibility
continue;
} else if (it->fLine.Contains("END RETURN")) { // needed for backward compatibility
continue;
} else if (it->fLine.Contains("CHI_SQUARE")) {
fUseChi2 = true;
} else if (it->fLine.Contains("MAX_LIKELYHOOD")) {
fUseChi2 = false;
} else if (it->fLine.Contains("INTERACTIVE")) {
fCmdList.push_back(PMN_INTERACTIVE);
} else if (it->fLine.Contains("CONTOURS")) {
fCmdList.push_back(PMN_CONTOURS);
} else if (it->fLine.Contains("EIGEN")) {
fCmdList.push_back(PMN_EIGEN);
} else if (it->fLine.Contains("HESSE")) {
fCmdList.push_back(PMN_HESSE);
} else if (it->fLine.Contains("MACHINE_PRECISION")) {
fCmdList.push_back(PMN_MACHINE_PRECISION);
} else if (it->fLine.Contains("MIGRAD")) {
fCmdList.push_back(PMN_MIGRAD);
} else if (it->fLine.Contains("MINIMIZE")) {
fCmdList.push_back(PMN_MINIMIZE);
} else if (it->fLine.Contains("MINOS")) {
fCmdList.push_back(PMN_MINOS);
} else if (it->fLine.Contains("PLOT")) {
fCmdList.push_back(PMN_PLOT);
} else if (it->fLine.Contains("SAVE")) {
fCmdList.push_back(PMN_SAVE);
} else if (it->fLine.Contains("SCAN")) {
fCmdList.push_back(PMN_SCAN);
} else if (it->fLine.Contains("SIMPLEX")) {
fCmdList.push_back(PMN_SIMPLEX);
} else if (it->fLine.Contains("STRATEGY")) {
fCmdList.push_back(PMN_STRATEGY);
} else if (it->fLine.Contains("USER_COVARIANCE")) {
fCmdList.push_back(PMN_USER_COVARIANCE);
} else if (it->fLine.Contains("USER_PARAM_STATE")) {
fCmdList.push_back(PMN_USER_PARAM_STATE);
} else if (it->fLine.Contains("PRINT")) {
fCmdList.push_back(PMN_PRINT);
} else { // unkown command
cout << endl << "FATAL ERROR:";
cout << endl << "PFitter::CheckCommands(): In line " << it->fLineNo << " an unkown command is found:";
cout << endl << " " << it->fLine.Data();
cout << endl << "Will stop ...";
cout << endl;
fIsValid = false;
}
}
return fIsValid;
}
//--------------------------------------------------------------------------
// SetParameters
//--------------------------------------------------------------------------
/**
* <p>
*
*/
bool PFitter::SetParameters()
{
PMsrParamList::iterator it;
for (it = fParams.begin(); it != fParams.end(); ++it) {
// check if parameter is fixed
if (it->fStep == 0.0) { // add fixed parameter
fMnUserParams.Add(it->fName.Data(), it->fValue);
} else { // add free parameter
// check if boundaries are given
if (it->fNoOfParams > 5) { // boundaries given
fMnUserParams.Add(it->fName.Data(), it->fValue, it->fStep, it->fLowerBoundary, it->fUpperBoundary);
} else { // no boundaries given
fMnUserParams.Add(it->fName.Data(), it->fValue, it->fStep);
}
}
}
return true;
}
//--------------------------------------------------------------------------
// ExecuteMigrad
//--------------------------------------------------------------------------
/**
* <p>
*
*/
bool PFitter::ExecuteMigrad()
{
cout << "PFitter::ExecuteMigrad(): will call migrad ..." << endl;
// if already some minimization is done use the minuit2 output as input
if (fFcnMin)
fMnUserParams = fFcnMin->UserParameters();
// create migrad object
ROOT::Minuit2::MnMigrad migrad((*fFitterFcn), fMnUserParams);
// minimize
ROOT::Minuit2::FunctionMinimum min = migrad();
if (!min.IsValid()) {
cout << endl << "**WARNING**: PFitter::ExecuteMigrad(): Fit did not converge, sorry ...";
return false;
}
// keep FunctionMinimum object
if (fFcnMin) { // fFcnMin exist hence clean up first
delete fFcnMin;
}
fFcnMin = new ROOT::Minuit2::FunctionMinimum(min);
// fill run info
for (unsigned int i=0; i<fParams.size(); i++) {
fRunInfo->SetMsrParamValue(i, min.UserState().Value(i));
fRunInfo->SetMsrParamStep(i, min.UserState().Error(i));
}
// handle statistics
double minVal = min.Fval();
unsigned int ndf = fFitterFcn->GetTotalNoOfFittedBins();
// subtract number of varied parameters from total no of fitted bins -> ndf
for (unsigned int i=0; i<fParams.size(); i++) {
if (min.UserState().Error(i) != 0.0)
ndf -= 1;
}
// feed run info with new statistics info
fRunInfo->SetMsrStatisticMin(minVal);
fRunInfo->SetMsrStatisticNdf(ndf);
return true;
}
//--------------------------------------------------------------------------
// ExecuteMinimize
//--------------------------------------------------------------------------
/**
* <p>
*
*/
bool PFitter::ExecuteMinimize()
{
cout << "PFitter::ExecuteMinimize(): will call minimize ..." << endl;
// if already some minimization is done use the minuit2 output as input
if (fFcnMin)
fMnUserParams = fFcnMin->UserParameters();
// create minimizer object
ROOT::Minuit2::MnMinimize minimize((*fFitterFcn), fMnUserParams);
// minimize
ROOT::Minuit2::FunctionMinimum min = minimize();
if (!min.IsValid()) {
cout << endl << "**WARNING**: PFitter::ExecuteMinimize(): Fit did not converge, sorry ...";
return false;
}
// keep FunctionMinimum object
if (fFcnMin) { // fFcnMin exist hence clean up first
delete fFcnMin;
}
fFcnMin = new ROOT::Minuit2::FunctionMinimum(min);
// fill run info
for (unsigned int i=0; i<fParams.size(); i++) {
fRunInfo->SetMsrParamValue(i, min.UserState().Value(i));
fRunInfo->SetMsrParamStep(i, min.UserState().Error(i));
}
// handle statistics
double minVal = min.Fval();
unsigned int ndf = fFitterFcn->GetTotalNoOfFittedBins();
// subtract number of varied parameters from total no of fitted bins -> ndf
for (unsigned int i=0; i<fParams.size(); i++) {
if (min.UserState().Error(i) != 0.0)
ndf -= 1;
}
// feed run info with new statistics info
fRunInfo->SetMsrStatisticMin(minVal);
fRunInfo->SetMsrStatisticNdf(ndf);
return true;
}
//--------------------------------------------------------------------------
// ExecuteMinos
//--------------------------------------------------------------------------
/**
* <p>
*
*/
bool PFitter::ExecuteMinos()
{
cout << "PFitter::ExecuteMinos(): will call minos ..." << endl;
// if already some minimization is done use the minuit2 output as input
if (!fFcnMin) {
cout << endl << "**ERROR**: MINOS musn't be called before any minimization (MINIMIZE/MIGRAD/SIMPLEX) is done!!";
cout << endl;
return false;
}
// check if minimum was valid
if (!fFcnMin->IsValid()) {
cout << endl << "**ERROR**: MINOS cannot started since the previews minimization faild :-(";
cout << endl;
return false;
}
fMnUserParams = fFcnMin->UserParameters();
// make minos analysis
ROOT::Minuit2::MnMinos minos((*fFitterFcn), (*fFcnMin));
for (unsigned int i=0; i<fParams.size(); i++) {
// only try to call minos if the parameter is not fixed!!
if (fMnUserParams.Error(i) != 0) {
// 1-sigma MINOS errors
std::pair<double, double> err = minos(i);
// fill msr-file structure
fRunInfo->SetMsrParamStep(i, err.first);
fRunInfo->SetMsrParamPosError(i, err.second);
}
}
return true;
}
//--------------------------------------------------------------------------
// ExecuteSave
//--------------------------------------------------------------------------
/**
* <p>
*
*/
bool PFitter::ExecuteSave()
{
cout << "PFitter::ExecuteSave(): not yet implemented ..." << endl;
// if any minimization was done, otherwise get out immediately
if (!fFcnMin) {
cout << endl << "PFitter::ExecuteSave(): nothing to be saved ...";
return false;
}
return true;
}
//--------------------------------------------------------------------------
// ExecuteSimplex
//--------------------------------------------------------------------------
/**
* <p>
*
*/
bool PFitter::ExecuteSimplex()
{
cout << "PFitter::ExecuteSimplex(): will call minimize ..." << endl;
// if already some minimization is done use the minuit2 output as input
if (fFcnMin)
fMnUserParams = fFcnMin->UserParameters();
// create minimizer object
ROOT::Minuit2::MnSimplex simplex((*fFitterFcn), fMnUserParams);
// minimize
ROOT::Minuit2::FunctionMinimum min = simplex();
if (!min.IsValid()) {
cout << endl << "**WARNING**: PFitter::ExecuteSimplex(): Fit did not converge, sorry ...";
return false;
}
// keep FunctionMinimum object
if (fFcnMin) { // fFcnMin exist hence clean up first
delete fFcnMin;
}
fFcnMin = new ROOT::Minuit2::FunctionMinimum(min);
// fill run info
for (unsigned int i=0; i<fParams.size(); i++) {
fRunInfo->SetMsrParamValue(i, min.UserState().Value(i));
fRunInfo->SetMsrParamStep(i, min.UserState().Error(i));
}
// handle statistics
double minVal = min.Fval();
unsigned int ndf = fFitterFcn->GetTotalNoOfFittedBins();
// subtract number of varied parameters from total no of fitted bins -> ndf
for (unsigned int i=0; i<fParams.size(); i++) {
if (min.UserState().Error(i) != 0.0)
ndf -= 1;
}
// feed run info with new statistics info
fRunInfo->SetMsrStatisticMin(minVal);
fRunInfo->SetMsrStatisticNdf(ndf);
return true;
}

View File

@ -0,0 +1,99 @@
/***************************************************************************
PFitterFcn.cpp
Author: Andreas Suter
e-mail: andreas.suter@psi.ch
$Id$
***************************************************************************/
/***************************************************************************
* Copyright (C) 2007 by Andreas Suter *
* andreas.suter@psi.c *
* *
* 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 <iostream>
using namespace std;
#include "PFitterFcn.h"
//--------------------------------------------------------------------------
// Constructor
//--------------------------------------------------------------------------
/**
* <p>
*
* \param runList
* \param fitType
*/
PFitterFcn::PFitterFcn(PRunListCollection *runList, bool useChi2)
{
fUseChi2 = useChi2;
if (fUseChi2)
fUp = 1.0;
else
fUp = 0.5;
fRunListCollection = runList;
}
//--------------------------------------------------------------------------
// Destructor
//--------------------------------------------------------------------------
/**
* <p>
*/
PFitterFcn::~PFitterFcn()
{
}
//--------------------------------------------------------------------------
/**
* <p>
*
* \param par
*/
double PFitterFcn::operator()(const std::vector<double>& par) const
{
double value = 0.0;
if (fUseChi2) { // chi square
value += fRunListCollection->GetSingleHistoChisq(par);
value += fRunListCollection->GetAsymmetryChisq(par);
value += fRunListCollection->GetRRFChisq(par);
value += fRunListCollection->GetNonMusrChisq(par);
} else { // max likelyhood
value += fRunListCollection->GetSingleHistoMaximumLikelihood(par);
value += fRunListCollection->GetAsymmetryMaximumLikelihood(par);
value += fRunListCollection->GetRRFMaximumLikelihood(par);
value += fRunListCollection->GetNonMusrMaximumLikelihood(par);
}
// cout << endl;
// for (unsigned int i=0; i<par.size(); i++) {
// cout << par[i] << ", ";
// }
//cout << endl << "chisq = " << value;
// cout << endl << "------" << endl;
return value;
}

562
src/classes/PFunction.cpp Normal file
View File

@ -0,0 +1,562 @@
/***************************************************************************
PFunction.cpp
Author: Andreas Suter
e-mail: andreas.suter@psi.ch
$Id$
***************************************************************************/
/***************************************************************************
* Copyright (C) 2007 by Andreas Suter *
* andreas.suter@psi.c *
* *
* 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<cmath>
#include <iostream>
using namespace std;
#include "PFunction.h"
//--------------------------------------------------------------------------
// Constructor
//--------------------------------------------------------------------------
/**
* <p>
*
* info is an abstract syntax tree (AST) generate by the spirit parse library
* (see http://spirit.sourceforge.net/distrib/spirit_1_8_5/libs/spirit/doc/trees.html).
* It contains a single parsed msr-function in an ascii representation.
* Here it takes the from
* assignment (root node)
* |_ 'FUNx'
* |_ '='
* |_ expression
* |_ ...
*
* Since it would be inefficient to evaluate this AST directly it is transferred to
* a more efficient tree fFuncs here in the constructor.
*
* \param info AST parse tree holding a single parsed msr-function in an ascii representation
*/
PFunction::PFunction(tree_parse_info<> info)
{
cout << endl << "in PFunction ...";
fInfo = info;
// init class variables
fValid = true;
fFuncNo = -1;
// set the function number
SetFuncNo();
// generate function evaluation tree
if (!GenerateFuncEvalTree()) {
fValid = false;
}
EvalTreeForString(info);
}
//--------------------------------------------------------------------------
// Destructor
//--------------------------------------------------------------------------
/**
* <p>
*/
PFunction::~PFunction()
{
// cout << endl << "in ~PFunction ...";
fParam.clear();
fMap.clear();
CleanupFuncEvalTree();
}
//-------------------------------------------------------------
// SetFuncNo (protected)
//-------------------------------------------------------------
/**
* <p>
*
* \param i
*/
bool PFunction::SetFuncNo()
{
int funNo = -1;
int status;
bool success = true;
// get root
iter_t i = fInfo.trees.begin(); // assignement
i = i->children.begin(); // FUNx
// get string from tree
string str(i->value.begin(), i->value.end());
// extract function number from string
status = sscanf(str.c_str(), "FUN%d", &funNo);
//cout << endl << "SetFuncNo: status = " << status << ", funNo = " << funNo;
if (status == 1) { // found 1 int
fFuncNo = funNo;
} else { // wrong string
success = false;
}
return success;
}
//-------------------------------------------------------------
// GenerateFuncEvalTree (protected)
//-------------------------------------------------------------
/**
* <p>
*
*/
bool PFunction::GenerateFuncEvalTree()
{
FillFuncEvalTree(fInfo.trees.begin(), fFunc);
return true;
}
//-------------------------------------------------------------
// FillFuncEvalTree (protected)
//-------------------------------------------------------------
/**
* <p>
*
*/
void PFunction::FillFuncEvalTree(iter_t const& i, PFuncTreeNode &node)
{
double dvalue;
int ivalue;
int status;
string str;
PFuncTreeNode child;
if (i->value.id() == PFunctionGrammar::realID) { // handle number
str = string(i->value.begin(), i->value.end()); // get string
status = sscanf(str.c_str(), "%lf", &dvalue); // convert string to double
node.fID = PFunctionGrammar::realID; // keep the ID
node.fDvalue = dvalue; // keep the value
// cout << endl << ">> realID: value = " << dvalue;
} else if (i->value.id() == PFunctionGrammar::parameterID) { // handle parameter number
str = string(i->value.begin(), i->value.end()); // get string
status = sscanf(str.c_str(), "PAR%d", &ivalue); // convert string to parameter number
node.fID = PFunctionGrammar::parameterID; // keep the ID
node.fIvalue = ivalue; // keep the value
// cout << endl << ">> parameterID: value = " << ivalue;
} else if (i->value.id() == PFunctionGrammar::mapID) { // handle map number
str = string(i->value.begin(), i->value.end()); // get string
status = sscanf(str.c_str(), "MAP%d", &ivalue); // convert string to map number
node.fID = PFunctionGrammar::mapID; // keep the ID
node.fIvalue = ivalue; // keep the value
// cout << endl << ">> mapID: value = " << ivalue;
} else if (i->value.id() == PFunctionGrammar::functionID) { // handle function like cos ...
// keep the id
node.fID = PFunctionGrammar::functionID;
// keep function tag
// i: 'funcName', '(', 'expression', ')'
iter_t it = i->children.begin();
str = string(it->value.begin(), it->value.end()); // get string
// cout << endl << ">> functionID: value = " << str;
if (!strcmp(str.c_str(), "COS"))
node.fFunctionTag = FUN_COS;
else if (!strcmp(str.c_str(), "SIN"))
node.fFunctionTag = FUN_SIN;
else if (!strcmp(str.c_str(), "TAN"))
node.fFunctionTag = FUN_TAN;
else if (!strcmp(str.c_str(), "COSH"))
node.fFunctionTag = FUN_COSH;
else if (!strcmp(str.c_str(), "SINH"))
node.fFunctionTag = FUN_SINH;
else if (!strcmp(str.c_str(), "TANH"))
node.fFunctionTag = FUN_TANH;
else if (!strcmp(str.c_str(), "ACOS"))
node.fFunctionTag = FUN_ACOS;
else if (!strcmp(str.c_str(), "ASIN"))
node.fFunctionTag = FUN_ASIN;
else if (!strcmp(str.c_str(), "ATAN"))
node.fFunctionTag = FUN_ATAN;
else if (!strcmp(str.c_str(), "ACOSH"))
node.fFunctionTag = FUN_ACOSH;
else if (!strcmp(str.c_str(), "ASINH"))
node.fFunctionTag = FUN_ASINH;
else if (!strcmp(str.c_str(), "ATANH"))
node.fFunctionTag = FUN_ATANH;
else if (!strcmp(str.c_str(), "LOG"))
node.fFunctionTag = FUN_LOG;
else if (!strcmp(str.c_str(), "LN"))
node.fFunctionTag = FUN_LN;
else if (!strcmp(str.c_str(), "EXP"))
node.fFunctionTag = FUN_EXP;
else {
cout << endl << "**PANIC ERROR**: function " << str << " doesn't exist, but you never should have reached this point!";
assert(0);
}
// add node
node.children.push_back(child);
// i: 'funcName', '(', 'expression', ')'
FillFuncEvalTree(i->children.begin()+2, node.children[0]);
} else if (i->value.id() == PFunctionGrammar::factorID) {
// cout << endl << ">> factorID";
// keep the id
node.fID = PFunctionGrammar::factorID;
// add child lhs
node.children.push_back(child);
FillFuncEvalTree(i->children.begin(), node.children[0]);
} else if (i->value.id() == PFunctionGrammar::termID) {
// keep the id
node.fID = PFunctionGrammar::termID;
// keep operator tag
if (*i->value.begin() == '*')
node.fOperatorTag = OP_MUL;
else
node.fOperatorTag = OP_DIV;
/*
if (node.fOperatorTag == OP_MUL)
cout << endl << ">> termID: value = *";
else
cout << endl << ">> termID: value = /";
*/
// add child lhs
node.children.push_back(child);
FillFuncEvalTree(i->children.begin(), node.children[0]);
// add child rhs
node.children.push_back(child);
FillFuncEvalTree(i->children.begin()+1, node.children[1]);
} else if (i->value.id() == PFunctionGrammar::expressionID) { // handle expression
// keep the id
node.fID = PFunctionGrammar::expressionID;
// keep operator tag
if (*i->value.begin() == '+')
node.fOperatorTag = OP_ADD;
else
node.fOperatorTag = OP_SUB;
/*
if (node.fOperatorTag == OP_ADD)
cout << endl << ">> expressionID: value = +";
else
cout << endl << ">> expressionID: value = -";
*/
// add child lhs
node.children.push_back(child);
FillFuncEvalTree(i->children.begin(), node.children[0]);
// add child rhs
node.children.push_back(child);
FillFuncEvalTree(i->children.begin()+1, node.children[1]);
} else if (i->value.id() == PFunctionGrammar::assignmentID) {
// nothing to be done except to pass the next element in the ast
// i: 'funx', '=', 'expression'
FillFuncEvalTree(i->children.begin()+2, node);
}
}
//-------------------------------------------------------------
// CheckMapAndParamRange (public)
//-------------------------------------------------------------
/**
* <p>
*
* \param mapSize
* \param paramSize
*/
bool PFunction::CheckMapAndParamRange(unsigned int mapSize, unsigned int paramSize)
{
return FindAndCheckMapAndParamRange(fFunc, mapSize, paramSize);
}
//-------------------------------------------------------------
// FindAndCheckMapAndParamRange (protected)
//-------------------------------------------------------------
/**
* <p>
*
* \param i
* \param mapSize
* \param paramSize
*/
bool PFunction::FindAndCheckMapAndParamRange(PFuncTreeNode &node, unsigned int mapSize, unsigned int paramSize)
{
if (node.fID == PFunctionGrammar::realID) {
return true;
} else if (node.fID == PFunctionGrammar::parameterID) {
if (node.fIvalue <= (int) paramSize)
return true;
else
return false;
} else if (node.fID == PFunctionGrammar::mapID) {
if (node.fIvalue <= (int) mapSize)
return true;
else
return false;
} else if (node.fID == PFunctionGrammar::functionID) {
return FindAndCheckMapAndParamRange(node.children[0], mapSize, paramSize);
} else if (node.fID == PFunctionGrammar::factorID) {
return FindAndCheckMapAndParamRange(node.children[0], mapSize, paramSize);
} else if (node.fID == PFunctionGrammar::termID) {
if (FindAndCheckMapAndParamRange(node.children[0], mapSize, paramSize))
return FindAndCheckMapAndParamRange(node.children[1], mapSize, paramSize);
else
return false;
} else if (node.fID == PFunctionGrammar::expressionID) {
if (FindAndCheckMapAndParamRange(node.children[0], mapSize, paramSize))
return FindAndCheckMapAndParamRange(node.children[1], mapSize, paramSize);
else
return false;
} else {
cout << endl << "**PANIC ERROR**: PFunction::FindAndCheckMapAndParamRange: you never should have reached this point!" << endl;
assert(0);
}
return true;
}
//-------------------------------------------------------------
// Eval (public)
//-------------------------------------------------------------
/**
* <p>
*
*/
double PFunction::Eval(vector<double> param)
{
fParam = param;
return EvalNode(fFunc);
}
//-------------------------------------------------------------
// EvalNode (protected)
//-------------------------------------------------------------
/**
* <p>
*
* \param node
*/
double PFunction::EvalNode(PFuncTreeNode &node)
{
if (node.fID == PFunctionGrammar::realID) {
return node.fDvalue;
} else if (node.fID == PFunctionGrammar::parameterID) {
return fParam[node.fIvalue-1];
} else if (node.fID == PFunctionGrammar::mapID) {
return fParam[fMap[node.fIvalue-1]-1];
} else if (node.fID == PFunctionGrammar::functionID) {
if (node.fFunctionTag == FUN_COS) {
return cos(EvalNode(node.children[0]));
} else if (node.fFunctionTag == FUN_SIN) {
return sin(EvalNode(node.children[0]));
} else if (node.fFunctionTag == FUN_TAN) {
return tan(EvalNode(node.children[0]));
} else if (node.fFunctionTag == FUN_COSH) {
return cosh(EvalNode(node.children[0]));
} else if (node.fFunctionTag == FUN_SINH) {
return sinh(EvalNode(node.children[0]));
} else if (node.fFunctionTag == FUN_TANH) {
return tanh(EvalNode(node.children[0]));
} else if (node.fFunctionTag == FUN_ACOS) {
return acos(EvalNode(node.children[0]));
} else if (node.fFunctionTag == FUN_ASIN) {
return asin(EvalNode(node.children[0]));
} else if (node.fFunctionTag == FUN_ATAN) {
return atan(EvalNode(node.children[0]));
} else if (node.fFunctionTag == FUN_ACOSH) {
return acosh(EvalNode(node.children[0]));
} else if (node.fFunctionTag == FUN_ASINH) {
return asinh(EvalNode(node.children[0]));
} else if (node.fFunctionTag == FUN_ATANH) {
return atanh(EvalNode(node.children[0]));
} else if (node.fFunctionTag == FUN_LOG) {
return log(EvalNode(node.children[0]))/log(10);
} else if (node.fFunctionTag == FUN_LN) {
return log(EvalNode(node.children[0]));
} else if (node.fFunctionTag == FUN_EXP) {
return exp(EvalNode(node.children[0]));
} else {
cout << endl << "**PANIC ERROR**: PFunction::EvalNode: node.fID == PFunctionGrammar::functionID: you never should have reached this point!" << endl;
assert(0);
}
} else if (node.fID == PFunctionGrammar::factorID) {
return EvalNode(node.children[0]);
} else if (node.fID == PFunctionGrammar::termID) {
if (node.fOperatorTag == OP_MUL) {
return EvalNode(node.children[0]) * EvalNode(node.children[1]);
} else {
double denominator = EvalNode(node.children[1]);
if (denominator == 0.0) {
cout << endl << "**PANIC ERROR**: PFunction::EvalNode: division by 0.0" << endl;
assert(0);
}
return EvalNode(node.children[0]) / denominator;
}
} else if (node.fID == PFunctionGrammar::expressionID) {
if (node.fOperatorTag == OP_ADD) {
return EvalNode(node.children[0]) + EvalNode(node.children[1]);
} else {
return EvalNode(node.children[0]) - EvalNode(node.children[1]);
}
} else {
cout << endl << "**PANIC ERROR**: PFunction::EvalNode: you never should have reached this point!" << endl;
assert(0);
}
return 0.0;
}
//-------------------------------------------------------------
// CleanupFuncEvalTree (protected)
//-------------------------------------------------------------
/**
* <p>
*
*/
void PFunction::CleanupFuncEvalTree()
{
// clean up all children
CleanupNode(fFunc);
}
//-------------------------------------------------------------
// CleanupNode (protected)
//-------------------------------------------------------------
/**
* <p>
*
* \param node
*/
void PFunction::CleanupNode(PFuncTreeNode &node)
{
if (node.children.size() != 0) {
for (unsigned int i=0; i<node.children.size(); i++) {
CleanupNode(node.children[i]);
}
node.children.clear();
}
}
//-------------------------------------------------------------
// EvalTreeForString (private)
//-------------------------------------------------------------
/**
* <p>
*
* \param info
*/
void PFunction::EvalTreeForString(tree_parse_info<> info)
{
fFuncString = "";
EvalTreeForStringExpression(info.trees.begin());
}
//-------------------------------------------------------------
// EvalTreeForStringExpression (private)
//-------------------------------------------------------------
/**
* <p>
*
* \param i
*/
void PFunction::EvalTreeForStringExpression(iter_t const& i)
{
static int termOp = 0;
if (i->value.id() == PFunctionGrammar::realID) {
assert(i->children.size() == 0);
if (*i->value.begin() == '-')
fFuncString += "(";
fFuncString += string(i->value.begin(), i->value.end()).c_str();
if (*i->value.begin() == '-')
fFuncString += ")";
} else if (i->value.id() == PFunctionGrammar::funLabelID) {
assert(i->children.size() == 0);
//SetFuncNo(i);
fFuncString += string(i->value.begin(), i->value.end()).c_str(); // funx
} else if (i->value.id() == PFunctionGrammar::parameterID) {
assert(i->children.size() == 0);
fFuncString += string(i->value.begin(), i->value.end()).c_str();
} else if (i->value.id() == PFunctionGrammar::mapID) {
assert(i->children.size() == 0);
fFuncString += string(i->value.begin(), i->value.end()).c_str();
} else if (i->value.id() == PFunctionGrammar::functionID) {
assert(i->children.size() == 4);
iter_t it = i->children.begin();
// funcName, '(', expression, ')'
fFuncString += string(it->value.begin(), it->value.end()).c_str();
if (termOp == 0)
fFuncString += "(";
EvalTreeForStringExpression(i->children.begin()+2); // the real stuff
if (termOp == 0)
fFuncString += ")";
} else if (i->value.id() == PFunctionGrammar::factorID) {
EvalTreeForStringExpression(i->children.begin());
} else if (i->value.id() == PFunctionGrammar::termID) {
if (*i->value.begin() == '*') {
assert(i->children.size() == 2);
termOp++;
EvalTreeForStringExpression(i->children.begin());
fFuncString += " * ";
EvalTreeForStringExpression(i->children.begin()+1);
termOp--;
} else if (*i->value.begin() == '/') {
assert(i->children.size() == 2);
termOp++;
EvalTreeForStringExpression(i->children.begin());
fFuncString += " / ";
EvalTreeForStringExpression(i->children.begin()+1);
termOp--;
} else {
assert(0);
}
} else if (i->value.id() == PFunctionGrammar::expressionID) {
if (*i->value.begin() == '+') {
assert(i->children.size() == 2);
if (termOp > 0)
fFuncString += "(";
EvalTreeForStringExpression(i->children.begin());
fFuncString += " + ";
EvalTreeForStringExpression(i->children.begin()+1);
if (termOp > 0)
fFuncString += ")";
} else if (*i->value.begin() == '-') {
assert(i->children.size() == 2);
if (termOp > 0)
fFuncString += "(";
EvalTreeForStringExpression(i->children.begin());
fFuncString += " - ";
EvalTreeForStringExpression(i->children.begin()+1);
if (termOp > 0)
fFuncString += ")";
} else {
assert(0);
}
} else if (i->value.id() == PFunctionGrammar::assignmentID) {
assert(i->children.size() == 3);
EvalTreeForStringExpression(i->children.begin());
EvalTreeForStringExpression(i->children.begin()+1); // this is the string "="
EvalTreeForStringExpression(i->children.begin()+2); // this is the real stuff
} else if (*i->value.begin() == '=') {
fFuncString += " = ";
} else {
assert(0);
}
}

View File

@ -0,0 +1,225 @@
/***************************************************************************
PFunctionHandler.cpp
Author: Andreas Suter
e-mail: andreas.suter@psi.ch
$Id$
***************************************************************************/
/***************************************************************************
* Copyright (C) 2007 by Andreas Suter *
* andreas.suter@psi.c *
* *
* 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 <string>
#include <cassert>
#include "PFunctionHandler.h"
//-------------------------------------------------------------
// Constructor
//-------------------------------------------------------------
/**
* <p>
*
* \param lines
*/
PFunctionHandler::PFunctionHandler(PMsrLines lines)
{
fValid = true;
fLines = lines;
cout << endl << "in PFunctionHandler(PMsrLines lines)";
}
//-------------------------------------------------------------
// Destructor
//-------------------------------------------------------------
/**
* <p>
*
*/
PFunctionHandler::~PFunctionHandler()
{
cout << endl << "in ~PFunctionHandler()" << endl << endl;
fLines.clear();
fFuncs.clear();
}
//-------------------------------------------------------------
// DoParse (public)
//-------------------------------------------------------------
/**
* <p>
*
*/
bool PFunctionHandler::DoParse()
{
cout << endl << "in PFunctionHandler::DoParse() ...";
bool success = true;
PFunctionGrammar function;
TString line;
// feed the function block into the parser. Start with i=1, since i=0 is FUNCTIONS
for (unsigned int i=1; i<fLines.size(); i++) {
cout << endl << "fLines[" << i << "] = '" << fLines[i].fLine.Data() << "'";
// function line to upper case
line = fLines[i].fLine;
line.ToUpper();
// do parsing
tree_parse_info<> info = ast_parse(line.Data(), function, space_p);
if (info.full) {
cout << endl << "parse successfull ..." << endl;
PFunction func(info);
fFuncs.push_back(func);
} else {
cout << endl << "**ERROR**: FUNCTIONS parse failed in line " << fLines[i].fLineNo << endl;
success = false;
break;
}
}
// check that the function numbers are unique
if (success) {
for (unsigned int i=0; i<fFuncs.size(); i++) {
for (unsigned int j=i+1; j<fFuncs.size(); j++) {
if (fFuncs[i].GetFuncNo() == fFuncs[j].GetFuncNo()) {
cout << endl << "**ERROR**: function number " << fFuncs[i].GetFuncNo();
cout << " is at least twice present! Fix this first.";
success = false;
}
}
}
}
if (success) {
for (unsigned int i=0; i<fFuncs.size(); i++)
cout << endl << "func number = " << fFuncs[i].GetFuncNo();
}
return success;
}
//-------------------------------------------------------------
// CheckMapAndParamRange (public)
//-------------------------------------------------------------
/**
* <p>
*
* \param mapSize
* \param paramSize
*/
bool PFunctionHandler::CheckMapAndParamRange(unsigned int mapSize, unsigned int paramSize)
{
bool success = true;
for (unsigned int i=0; i<fFuncs.size(); i++) {
success = fFuncs[i].CheckMapAndParamRange(mapSize, paramSize);
if (!success)
break;
}
return success;
}
//-------------------------------------------------------------
// Eval (public)
//-------------------------------------------------------------
/**
* <p>
*
* \param funNo
*/
double PFunctionHandler::Eval(int funNo, vector<int> map, vector<double> param)
{
if (GetFuncIndex(funNo) == -1) {
cout << endl << "**ERROR**: Couldn't find FUN" << funNo << " for evaluation";
return 0.0;
}
//cout << endl << "PFunctionHandler::Eval: GetFuncIndex("<<funNo<<") = " << GetFuncIndex(funNo);
//cout << endl;
// set correct map
fFuncs[GetFuncIndex(funNo)].SetMap(map);
// return evaluated function
return fFuncs[GetFuncIndex(funNo)].Eval(param);
}
//-------------------------------------------------------------
// GetFuncNo (public)
//-------------------------------------------------------------
/**
* <p>
*
* \param idx
*/
int PFunctionHandler::GetFuncNo(unsigned int idx)
{
if (idx > fFuncs.size())
return -1;
return fFuncs[idx].GetFuncNo();
}
//-------------------------------------------------------------
// GetFuncIndex (public)
//-------------------------------------------------------------
/**
* <p>
*
* \param funcNo
*/
int PFunctionHandler::GetFuncIndex(int funcNo)
{
int index = -1;
for (unsigned int i=0; i<fFuncs.size(); i++) {
if (fFuncs[i].GetFuncNo() == funcNo) {
index = i;
break;
}
}
return index;
}
//-------------------------------------------------------------
// GetFuncString (public)
//-------------------------------------------------------------
/**
* <p>
*
* \param idx
*/
TString* PFunctionHandler::GetFuncString(unsigned int idx)
{
if (idx > fFuncs.size())
return 0;
return fFuncs[idx].GetFuncString();
}

1780
src/classes/PMsrHandler.cpp Normal file

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,643 @@
/***************************************************************************
PRunAsymmetry.cpp
Author: Andreas Suter
e-mail: andreas.suter@psi.ch
$Id$
***************************************************************************/
/***************************************************************************
* Copyright (C) 2007 by Andreas Suter *
* andreas.suter@psi.c *
* *
* 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 <stdio.h>
#include <iostream>
#include "PMusr.h"
#include "PRunAsymmetry.h"
//--------------------------------------------------------------------------
// Constructor
//--------------------------------------------------------------------------
/**
* <p>
*
*/
PRunAsymmetry::PRunAsymmetry() : PRunBase()
{
fFitStartTime = 0.0;
fFitStopTime = 0.0;
fNoOfFitBins = 0;
}
//--------------------------------------------------------------------------
// Constructor
//--------------------------------------------------------------------------
/**
* <p>
*
* \param msrInfo pointer to the msr info structure
* \param runNo number of the run of the msr-file
*/
PRunAsymmetry::PRunAsymmetry(PMsrHandler *msrInfo, PRunDataHandler *rawData, unsigned int runNo) : PRunBase(msrInfo, rawData, runNo)
{
// check if alpha and/or beta is fixed --------------------
PMsrParamList *param = msrInfo->GetMsrParamList();
// check if alpha is given
if (fRunInfo->fAlphaParamNo == -1) { // no alpha given
cout << endl << "PRunAsymmetry::PRunAsymmetry(): no alpha parameter given! This is needed for an asymmetry fit!";
fValid = false;
return;
}
// check if alpha parameter is within proper bounds
if ((fRunInfo->fAlphaParamNo < 0) || (fRunInfo->fAlphaParamNo > (int)param->size())) {
cout << endl << "PRunAsymmetry::PRunAsymmetry(): alpha parameter no = " << fRunInfo->fAlphaParamNo;
cout << endl << " This is out of bound, since there are only " << param->size() << " parameters.";
fValid = false;
return;
}
// check if alpha is fixed
bool alphaFixedToOne = false;
//cout << endl << ">> alpha = " << (*param)[fRunInfo->fAlphaParamNo-1].fValue << ", " << (*param)[fRunInfo->fAlphaParamNo-1].fStep;
if (((*param)[fRunInfo->fAlphaParamNo-1].fStep == 0.0) &&
((*param)[fRunInfo->fAlphaParamNo-1].fValue == 1.0))
alphaFixedToOne = true;
// check if beta is given
bool betaFixedToOne = false;
if (fRunInfo->fBetaParamNo == -1) { // no beta given hence assuming beta == 1
betaFixedToOne = true;
} else if ((fRunInfo->fBetaParamNo < 0) || (fRunInfo->fBetaParamNo > (int)param->size())) { // check if beta parameter is within proper bounds
cout << endl << "PRunAsymmetry::PRunAsymmetry(): beta parameter no = " << fRunInfo->fBetaParamNo;
cout << endl << " This is out of bound, since there are only " << param->size() << " parameters.";
fValid = false;
return;
} else { // check if beta is fixed
if (((*param)[fRunInfo->fBetaParamNo-1].fStep == 0.0) &&
((*param)[fRunInfo->fBetaParamNo-1].fValue == 1.0))
betaFixedToOne = true;
}
// set fAlphaBetaTag
if (alphaFixedToOne && betaFixedToOne) // alpha == 1, beta == 1
fAlphaBetaTag = 1;
else if (!alphaFixedToOne && betaFixedToOne) // alpha != 1, beta == 1
fAlphaBetaTag = 2;
else if (alphaFixedToOne && !betaFixedToOne) // alpha == 1, beta != 1
fAlphaBetaTag = 3;
else
fAlphaBetaTag = 4;
//cout << endl << ">> PRunAsymmetry::PRunAsymmetry(): fAlphaBetaTag = " << fAlphaBetaTag;
// calculate fData
if (!PrepareData())
fValid = false;
}
//--------------------------------------------------------------------------
// Destructor
//--------------------------------------------------------------------------
/**
* <p>
*
*/
PRunAsymmetry::~PRunAsymmetry()
{
fForward.clear();
fForwardErr.clear();
fBackward.clear();
fBackwardErr.clear();
}
//--------------------------------------------------------------------------
// CalcChiSquare
//--------------------------------------------------------------------------
/**
* <p>
*
* \param par parameter vector iterated by minuit
*/
double PRunAsymmetry::CalcChiSquare(const std::vector<double>& par)
{
double chisq = 0.0;
double diff = 0.0;
double asymFcnValue = 0.0;
double a, b, f;
// calculate functions
for (int i=0; i<fMsrInfo->GetNoOfFuncs(); i++) {
fFuncValues[i] = fMsrInfo->EvalFunc(fMsrInfo->GetFuncNo(i), fRunInfo->fMap, par);
}
// calculate chisq
for (unsigned int i=0; i<fData.fValue.size(); i++) {
if ((fData.fTime[i]>=fFitStartTime) && (fData.fTime[i]<=fFitStopTime)) {
switch (fAlphaBetaTag) {
case 1: // alpha == 1, beta == 1
asymFcnValue = fTheory->Func(fData.fTime[i], par, fFuncValues);
break;
case 2: // alpha != 1, beta == 1
a = par[fRunInfo->fAlphaParamNo-1];
f = fTheory->Func(fData.fTime[i], par, fFuncValues);
asymFcnValue = (f*(a+1.0)-(a-1.0))/((a+1.0)-f*(a-1.0));
break;
case 3: // alpha == 1, beta != 1
b = par[fRunInfo->fBetaParamNo-1];
f = fTheory->Func(fData.fTime[i], par, fFuncValues);
asymFcnValue = f*(b+1.0)/(2.0-f*(b-1.0));
break;
case 4: // alpha != 1, beta != 1
a = par[fRunInfo->fAlphaParamNo-1];
b = par[fRunInfo->fBetaParamNo-1];
f = fTheory->Func(fData.fTime[i], par, fFuncValues);
asymFcnValue = (f*(a*b+1.0)-(a-1.0))/((a+1.0)-f*(a*b-1.0));
break;
default:
break;
}
//if (i==0) cout << endl << "A(0) = " << asymFcnValue;
diff = fData.fValue[i] - asymFcnValue;
chisq += diff*diff / (fData.fError[i]*fData.fError[i]);
}
}
//cout << endl << ">> chisq = " << chisq;
return chisq;
}
//--------------------------------------------------------------------------
// CalcMaxLikelihood
//--------------------------------------------------------------------------
/**
* <p>
*
* \param par parameter vector iterated by minuit
*/
double PRunAsymmetry::CalcMaxLikelihood(const std::vector<double>& par)
{
cout << endl << "PRunSingleHisto::CalcMaxLikelihood(): not implemented yet ..." << endl;
return 1.0;
}
//--------------------------------------------------------------------------
// CalcTheory
//--------------------------------------------------------------------------
/**
* <p>
*
*/
void PRunAsymmetry::CalcTheory()
{
// feed the parameter vector
std::vector<double> par;
PMsrParamList *paramList = fMsrInfo->GetMsrParamList();
for (unsigned int i=0; i<paramList->size(); i++)
par.push_back((*paramList)[i].fValue);
// calculate functions
for (int i=0; i<fMsrInfo->GetNoOfFuncs(); i++) {
fFuncValues[i] = fMsrInfo->EvalFunc(fMsrInfo->GetFuncNo(i), fRunInfo->fMap, par);
}
// calculate asymmetry
double asymFcnValue = 0.0;
double a, b, f;
for (unsigned int i=0; i<fData.fTime.size(); i++) {
switch (fAlphaBetaTag) {
case 1: // alpha == 1, beta == 1
asymFcnValue = fTheory->Func(fData.fTime[i], par, fFuncValues);
break;
case 2: // alpha != 1, beta == 1
a = par[fRunInfo->fAlphaParamNo-1];
f = fTheory->Func(fData.fTime[i], par, fFuncValues);
asymFcnValue = (f*(a+1.0)-(a-1.0))/((a+1.0)-f*(a-1.0));
break;
case 3: // alpha == 1, beta != 1
b = par[fRunInfo->fBetaParamNo-1];
f = fTheory->Func(fData.fTime[i], par, fFuncValues);
asymFcnValue = f*(b+1.0)/(2.0-f*(b-1.0));
break;
case 4: // alpha != 1, beta != 1
a = par[fRunInfo->fAlphaParamNo-1];
b = par[fRunInfo->fBetaParamNo-1];
f = fTheory->Func(fData.fTime[i], par, fFuncValues);
asymFcnValue = (f*(a*b+1.0)-(a-1.0))/((a+1.0)-f*(a*b-1.0));
break;
default:
asymFcnValue = 0.0;
break;
}
fData.fTheory.push_back(asymFcnValue);
}
// clean up
par.clear();
}
//--------------------------------------------------------------------------
// PrepareData
//--------------------------------------------------------------------------
/**
* <p>
*
* Error propagation for \f$ A_i = (f_i^{\rm c}-b_i^{\rm c})/(f_i^{\rm c}+b_i^{\rm c})\f$:
* \f[ \Delta A_i = \pm\frac{2}{(f_i^{\rm c}+b_i^{\rm c})^2}\left[
* (b_i^{\rm c})^2 (\Delta f_i^{\rm c})^2 +
* (\Delta b_i^{\rm c})^2 (f_i^{\rm c})^2\right]^{1/2}\f]
*/
bool PRunAsymmetry::PrepareData()
{
//cout << endl << "in PRunAsymmetry::PrepareData(): will feed fData";
// get forward/backward histo from PRunDataHandler object ------------------------
// get the correct run
PRawRunData *runData = fRawData->GetRunData(fRunInfo->fRunName);
if (!runData) { // run not found
cout << endl << "PRunAsymmetry::PrepareData(): Couldn't get run " << fRunInfo->fRunName.Data() << "!";
return false;
}
// keep the time resolution in (us)
fTimeResolution = runData->fTimeResolution/1.0e3;
// keep start/stop time for fit
fFitStartTime = fRunInfo->fFitRange[0];
fFitStopTime = fRunInfo->fFitRange[1];
//cout << endl << "start/stop (fit): " << fFitStartTime << ", " << fFitStopTime;
// check if the t0's are given in the msr-file
if (fRunInfo->fT0[0] == -1) { // t0's are NOT in the msr-file
// check if the t0's are in the data file
if (runData->fT0s.size() != 0) { // t0's in the run data
// keep the proper t0's. For asymmetry runs, forward/backward are holding the histo no
// fForwardHistoNo starts with 1 not with 0 etc. ;-)
fT0s.push_back(runData->fT0s[fRunInfo->fForwardHistoNo-1]); // forward t0
fT0s.push_back(runData->fT0s[fRunInfo->fBackwardHistoNo-1]); // backward t0
} else { // t0's are neither in the run data nor in the msr-file -> not acceptable!
cout << endl << "PRunAsymmetry::PrepareData(): NO t0's found, neither in the run data nor in the msr-file!";
return false;
}
} else { // t0's in the msr-file
// check if t0's are given in the data file
if (runData->fT0s.size() != 0) {
// compare t0's of the msr-file with the one in the data file
if (fabs(fRunInfo->fT0[0]-runData->fT0s[fRunInfo->fForwardHistoNo-1])>5.0) { // given in bins!!
cout << endl << "PRunAsymmetry::PrepareData(): **WARNING**: forward histo";
cout << endl << " t0 from the msr-file is " << fRunInfo->fT0[0];
cout << endl << " t0 from the data file is " << runData->fT0s[fRunInfo->fForwardHistoNo-1];
cout << endl << " This is quite a deviation! Is this done intentionally??";
cout << endl;
}
if (fabs(fRunInfo->fT0[1]-runData->fT0s[fRunInfo->fBackwardHistoNo-1])>5.0) { // given in bins!!
cout << endl << "PRunAsymmetry::PrepareData(): **WARNING**: backward histo";
cout << endl << " t0 from the msr-file is " << fRunInfo->fT0[1];
cout << endl << " t0 from the data file is " << runData->fT0s[fRunInfo->fBackwardHistoNo-1];
cout << endl << " This is quite a deviation! Is this done intentionally??";
cout << endl;
}
}
fT0s.push_back(fRunInfo->fT0[0]); // forward t0
fT0s.push_back(fRunInfo->fT0[1]); // backward t0
}
// check if post pile up data shall be used
unsigned int histoNo[2]; // forward/backward
if (fRunInfo->fFileFormat.Contains("ppc")) {
histoNo[0] = runData->fDataBin.size()/2 + fRunInfo->fForwardHistoNo-1;
histoNo[1] = runData->fDataBin.size()/2 + fRunInfo->fBackwardHistoNo-1;
} else {
histoNo[0] = fRunInfo->fForwardHistoNo-1;
histoNo[1] = fRunInfo->fBackwardHistoNo-1;
}
// first check if forward/backward given in the msr-file are valid
if ((runData->fDataBin.size() < histoNo[0]) || (histoNo[0] < 0) ||
(runData->fDataBin.size() < histoNo[1]) || (histoNo[1] < 0)) {
cout << endl << "PRunAsymmetry::PrepareData(): PANIC ERROR:";
cout << endl << " forward/backward histo no found = " << histoNo[0];
cout << ", " << histoNo[1] << ", but there are only " << runData->fDataBin.size() << " runs!?!?";
cout << endl << " Will quite :-(";
cout << endl;
return false;
}
// get raw forward/backward histo data
for (unsigned int i=0; i<runData->fDataBin[histoNo[0]].size(); i++) {
fForward.push_back(runData->fDataBin[histoNo[0]][i]);
fBackward.push_back(runData->fDataBin[histoNo[1]][i]);
}
// subtract background from histogramms ------------------------------------------
if (isnan(fRunInfo->fBkgFix[0])) { // no fixed background given
if (fRunInfo->fBkgRange[0] != 0) {
if (!SubtractEstimatedBkg())
return false;
} else { // no background given to do the job
cout << endl << "PRunAsymmetry::PrepareData(): Neither fix background nor background bins are given!";
cout << endl << "One of the two is needed! Will quit ...";
return false;
}
} else { // fixed background given
if (!SubtractFixBkg())
return false;
}
// transform raw histo data. This is done the following way (for details see the manual):
// first rebin the data, than calculate the asymmetry
// first get start data, end data, and t0
unsigned int start[2] = {fRunInfo->fDataRange[0], fRunInfo->fDataRange[2]};
unsigned int end[2] = {fRunInfo->fDataRange[1], fRunInfo->fDataRange[3]};
unsigned int t0[2] = {fT0s[0], fT0s[1]};
// check if start, end, and t0 make any sense
// 1st check if start and end are in proper order
for (unsigned int i=0; i<2; i++) {
if (end[i] < start[i]) { // need to swap them
int keep = end[i];
end[i] = start[i];
start[i] = keep;
}
// 2nd check if start is within proper bounds
if ((start[i] < 0) || (start[i] > runData->fDataBin[histoNo[i]].size())) {
cout << endl << "PRunAsymmetry::PrepareData(): start data bin doesn't make any sense!";
return false;
}
// 3rd check if end is within proper bounds
if ((end[i] < 0) || (end[i] > runData->fDataBin[histoNo[i]].size())) {
cout << endl << "PRunAsymmetry::PrepareData(): end data bin doesn't make any sense!";
return false;
}
// 4th check if t0 is within proper bounds
if ((t0[i] < 0) || (t0[i] > runData->fDataBin[histoNo[i]].size())) {
cout << endl << "PRunAsymmetry::PrepareData(): t0 data bin doesn't make any sense!";
return false;
}
}
// everything looks fine, hence fill packed forward and backward histo
PRunData forwardPacked;
PRunData backwardPacked;
double value = 0.0;
double error = 0.0;
// forward
for (unsigned i=start[0]; i<end[0]; i++) {
if (((i-start[0]) % fRunInfo->fPacking == 0) && (i != start[0])) { // fill data
// in order that after rebinning the fit does not need to be redone (important for plots)
// the value is normalize to per bin
value /= fRunInfo->fPacking;
// time shifted so that packing is included correctly, i.e. t0 == t0 after packing
forwardPacked.fTime.push_back(fTimeResolution*((double)i-(double)t0[0]-(double)fRunInfo->fPacking));
forwardPacked.fValue.push_back(value);
if (value == 0.0)
forwardPacked.fError.push_back(1.0);
else
forwardPacked.fError.push_back(TMath::Sqrt(error)/fRunInfo->fPacking);
value = 0.0;
error = 0.0;
}
value += fForward[i];
error += fForwardErr[i]*fForwardErr[i];
}
// backward
for (unsigned i=start[1]; i<end[1]; i++) {
if (((i-start[1]) % fRunInfo->fPacking == 0) && (i != start[1])) { // fill data
// in order that after rebinning the fit does not need to be redone (important for plots)
// the value is normalize to per bin
value /= fRunInfo->fPacking;
// time shifted so that packing is included correctly, i.e. t0 == t0 after packing
backwardPacked.fTime.push_back(fTimeResolution*((double)i-(double)t0[1]-(double)fRunInfo->fPacking));
backwardPacked.fValue.push_back(value);
if (value == 0.0)
backwardPacked.fError.push_back(1.0);
else
backwardPacked.fError.push_back(TMath::Sqrt(error)/fRunInfo->fPacking);
value = 0.0;
error = 0.0;
}
value += fBackward[i];
error += fBackwardErr[i]*fBackwardErr[i];
}
// check if packed forward and backward hist have the same size, otherwise something is wrong
if (forwardPacked.fTime.size() != backwardPacked.fTime.size()) {
cout << endl << "PRunAsymmetry::PrepareData(): **PANIC ERROR**:";
cout << endl << " packed forward and backward histo should have the same number of bins!";
cout << endl << " however found (f/b) : " << forwardPacked.fTime.size() << "/" << backwardPacked.fTime.size();
return false;
}
// form asymmetry including error propagation
double asym;
double f, b, ef, eb;
for (unsigned int i=0; i<forwardPacked.fTime.size(); i++) {
// check that forward time == backward time!!
if (forwardPacked.fTime[i] != backwardPacked.fTime[i]) {
cout << endl << "PRunAsymmetry::PrepareData(): **PANIC ERROR**:";
cout << endl << " forward/backward time are not equal! This cannot be handled";
return false;
}
fData.fTime.push_back(forwardPacked.fTime[i]);
// to make the formulae more readable
f = forwardPacked.fValue[i];
b = backwardPacked.fValue[i];
ef = forwardPacked.fError[i];
eb = backwardPacked.fError[i];
// check that there are indeed bins
if (f+b != 0.0)
asym = (f-b) / (f+b);
else
asym = 0.0;
fData.fValue.push_back(asym);
// calculate the error
if (f+b != 0.0)
error = 2.0/((f+b)*(f+b))*TMath::Sqrt(b*b*ef*ef+eb*eb*f*f);
else
error = 1.0;
fData.fError.push_back(error);
}
/*
FILE *fp = fopen("asym.dat", "w");
for (unsigned int i=0; i<fData.fTime.size(); i++) {
fprintf(fp, "%lf, %lf, %lf\n", fData.fTime[i], fData.fValue[i], fData.fError[i]);
}
fclose(fp);
return false;
*/
// count the number of bins to be fitted
fNoOfFitBins=0;
for (unsigned int i=0; i<fData.fValue.size(); i++) {
if ((fData.fTime[i] >= fFitStartTime) && (fData.fTime[i] <= fFitStopTime))
fNoOfFitBins++;
}
// clean up
forwardPacked.fTime.clear();
forwardPacked.fValue.clear();
forwardPacked.fError.clear();
backwardPacked.fTime.clear();
backwardPacked.fValue.clear();
backwardPacked.fError.clear();
fForward.clear();
fForwardErr.clear();
fBackward.clear();
fBackwardErr.clear();
return true;
}
//--------------------------------------------------------------------------
// SubtractFixBkg
//--------------------------------------------------------------------------
/**
* <p>Subtracts a fixed background from the raw data. The error propagation
* is done the following way: it is assumed that the error of the background
* is Poisson like, i.e. \f$\Delta\mathrm{bkg} = \sqrt{\mathrm{bkg}}\f$.
*
* Error propagation:
* \f[ \Delta f_i^{\rm c} = \pm\left[ (\Delta f_i)^2 + (\Delta \mathrm{bkg})^2 \right]^{1/2} =
* \pm\left[ f_i + \mathrm{bkg} \right]^{1/2}, \f]
* where \f$ f_i^{\rm c} \f$ is the background corrected histogram, \f$ f_i \f$ the raw histogram
* and \f$ \mathrm{bkg} \f$ the fix given background.
*/
bool PRunAsymmetry::SubtractFixBkg()
{
for (unsigned int i=0; i<fForward.size(); i++) {
fForwardErr.push_back(TMath::Sqrt(fForward[i]+fRunInfo->fBkgFix[0]));
fForward[i] -= fRunInfo->fBkgFix[0];
fBackwardErr.push_back(TMath::Sqrt(fBackward[i]+fRunInfo->fBkgFix[1]));
fBackward[i] -= fRunInfo->fBkgFix[1];
}
return true;
}
//--------------------------------------------------------------------------
// SubtractEstimatedBkg
//--------------------------------------------------------------------------
/**
* <p>Subtracts the background given ...
*
* The background corrected histogramms are:
* \f$ f_i^{\rm c} = f_i - \mathrm{bkg} \f$, where \f$ f_i \f$ is the raw data histogram,
* \f$ \mathrm{bkg} \f$ the background estimate, and \f$ f_i^{\rm c} \f$ background corrected
* histogram. The error on \f$ f_i^{\rm c} \f$ is
* \f[ \Delta f_i^{\rm c} = \pm \sqrt{ (\Delta f_i)^2 + (\Delta \mathrm{bkg})^2 } =
* \pm \sqrt{f_i + (\Delta \mathrm{bkg})^2} \f]
* The background error \f$ \Delta \mathrm{bkg} \f$ is
* \f[ \Delta \mathrm{bkg} = \pm\frac{1}{N}\left[\sum_{i=0}^N (\Delta f_i)^2\right]^{1/2} =
* \pm\frac{1}{N}\left[\sum_{i=0}^N f_i \right]^{1/2},\f]
* where \f$N\f$ is the number of bins over which the background is formed.
*/
bool PRunAsymmetry::SubtractEstimatedBkg()
{
double beamPeriod = 0.0;
// check if data are from PSI, RAL, or TRIUMF
if (fRunInfo->fInstitute.Contains("psi"))
beamPeriod = ACCEL_PERIOD_PSI;
else if (fRunInfo->fInstitute.Contains("ral"))
beamPeriod = ACCEL_PERIOD_RAL;
else if (fRunInfo->fInstitute.Contains("triumf"))
beamPeriod = ACCEL_PERIOD_TRIUMF;
else
beamPeriod = 0.0;
// check if start and end are in proper order
unsigned int start[2] = {fRunInfo->fBkgRange[0], fRunInfo->fBkgRange[2]};
unsigned int end[2] = {fRunInfo->fBkgRange[1], fRunInfo->fBkgRange[3]};
for (unsigned int i=0; i<2; i++) {
if (end[i] < start[i]) {
cout << endl << "PRunAsymmetry::SubtractEstimatedBkg(): end = " << end[i] << " > start = " << start[i] << "! Will swap them!";
unsigned int keep = end[i];
end[i] = start[i];
start[i] = keep;
}
}
// calculate proper background range
for (unsigned int i=0; i<2; i++) {
if (beamPeriod != 0.0) {
double beamPeriodBins = beamPeriod/fRunInfo->fPacking;
unsigned int periods = (unsigned int)((double)(end[i] - start[i] + 1) / beamPeriodBins);
end[i] = start[i] + (unsigned int)round((double)periods*beamPeriodBins);
cout << endl << "PRunAsymmetry::SubtractEstimatedBkg(): Background " << start[i] << ", " << end[i];
if (end[i] == start[i])
end[i] = fRunInfo->fBkgRange[2*i+1];
}
}
// check if start is within histogram bounds
if ((start[0] < 0) || (start[0] >= fForward.size()) ||
(start[1] < 0) || (start[1] >= fBackward.size())) {
cout << endl << "PRunAsymmetry::SubtractEstimatedBkg(): background bin values out of bound!";
cout << endl << " histo lengths (f/b) = (" << fForward.size() << "/" << fBackward.size() << ").";
cout << endl << " background start (f/b) = (" << start[0] << "/" << start[1] << ").";
return false;
}
// check if end is within histogram bounds
if ((end[0] < 0) || (end[0] >= fForward.size()) ||
(end[1] < 0) || (end[1] >= fBackward.size())) {
cout << endl << "PRunAsymmetry::SubtractEstimatedBkg(): background bin values out of bound!";
cout << endl << " histo lengths (f/b) = (" << fForward.size() << "/" << fBackward.size() << ").";
cout << endl << " background end (f/b) = (" << end[0] << "/" << end[1] << ").";
return false;
}
// calculate background
double bkg[2] = {0.0, 0.0};
double errBkg[2] = {0.0, 0.0};
// forward
for (unsigned int i=start[0]; i<end[0]; i++)
bkg[0] += fForward[i];
errBkg[0] = TMath::Sqrt(bkg[0])/(end[0] - start[0] + 1);
bkg[0] /= static_cast<double>(end[0] - start[0] + 1);
// backward
for (unsigned int i=start[1]; i<end[1]; i++)
bkg[1] += fBackward[i];
errBkg[1] = TMath::Sqrt(bkg[1])/(end[0] - start[0] + 1);
bkg[1] /= static_cast<double>(end[1] - start[1] + 1);
// correct error for forward, backward
for (unsigned int i=0; i<fForward.size(); i++) {
fForwardErr.push_back(TMath::Sqrt(fForward[i]+errBkg[0]*errBkg[0]));
fBackwardErr.push_back(TMath::Sqrt(fBackward[i]+errBkg[1]*errBkg[1]));
}
// subtract background from data
for (unsigned int i=0; i<fForward.size(); i++) {
fForward[i] -= bkg[0];
fBackward[i] -= bkg[1];
}
return true;
}

149
src/classes/PRunBase.cpp Normal file
View File

@ -0,0 +1,149 @@
/***************************************************************************
PRunBase.cpp
Author: Andreas Suter
e-mail: andreas.suter@psi.ch
$Id$
***************************************************************************/
/***************************************************************************
* Copyright (C) 2007 by Andreas Suter *
* andreas.suter@psi.c *
* *
* 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 <iostream>
#include <TROOT.h>
#include <TSystem.h>
#include <TString.h>
#include <TObjArray.h>
#include <TObjString.h>
#include <TFile.h>
#include <TFolder.h>
#include "TLemRunHeader.h"
#include "PRunBase.h"
//--------------------------------------------------------------------------
// Constructor
//--------------------------------------------------------------------------
/**
* <p> needed otherwise vector's cannot be generated ;-)
*
*/
PRunBase::PRunBase()
{
fRunNo = -1;
fRunInfo = 0;
fRawData = 0;
fTimeResolution = -1.0;
fValid = true;
}
//--------------------------------------------------------------------------
// Constructor
//--------------------------------------------------------------------------
/**
* <p>
*
* \param msrInfo pointer to the msr info structure
* \param runNo number of the run of the msr-file
*/
PRunBase::PRunBase(PMsrHandler *msrInfo, PRunDataHandler *rawData, unsigned int runNo)
{
fValid = true;
fRunNo = runNo;
if ((runNo < 0) || (runNo > msrInfo->GetMsrRunList()->size())) {
fRunInfo = 0;
return;
}
// keep pointer to the msr-file handler
fMsrInfo = msrInfo;
// keep the run header info for this run
fRunInfo = &(*msrInfo->GetMsrRunList())[runNo];
// check the parameter and map range of the functions
if (!fMsrInfo->CheckMapAndParamRange(fRunInfo->fMap.size(), fMsrInfo->GetNoOfParams())) {
cout << endl << "**SEVERE ERROR** PRunBase::PRunBase: map and/or parameter out of range in FUNCTIONS." << endl;
exit(0);
}
// keep the raw data of the runs
fRawData = rawData;
// init private variables
fTimeResolution = -1.0;
for (int i=0; i<fMsrInfo->GetNoOfFuncs(); i++)
fFuncValues.push_back(0.0);
// generate theory
fTheory = new PTheory(msrInfo, runNo);
if (fTheory == 0) {
cout << endl << "**SEVERE ERROR** PRunBase::PRunBase: Couldn't create an instance of PTheory :-(, will quit" << endl;
exit(0);
}
if (!fTheory->IsValid()) {
cout << endl << "**SEVERE ERROR** PRunBase::PRunBase: Theory is not valid :-(, will quit" << endl;
exit(0);
}
}
//--------------------------------------------------------------------------
// Destructor
//--------------------------------------------------------------------------
/**
* <p>
*
*/
PRunBase::~PRunBase()
{
fParamNo.clear();
fData.fTime.clear();
fData.fValue.clear();
fData.fError.clear();
fData.fTheory.clear();
fT0s.clear();
fFuncValues.clear();
}
//--------------------------------------------------------------------------
// CleanUp
//--------------------------------------------------------------------------
/**
* <p> Clean up all localy allocate memory
*
*/
void PRunBase::CleanUp()
{
//cout << endl << "PRunBase::CleanUp() ..." << endl;
if (fTheory) {
delete fTheory;
fTheory = 0;
}
}

View File

@ -0,0 +1,811 @@
/***************************************************************************
PRunDataHandler.cpp
Author: Andreas Suter
e-mail: andreas.suter@psi.ch
$Id$
***************************************************************************/
/***************************************************************************
* Copyright (C) 2007 by Andreas Suter *
* andreas.suter@psi.c *
* *
* 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 <iostream>
#include <fstream>
using namespace std;
#include <TROOT.h>
#include <TSystem.h>
#include <TString.h>
#include <TObjArray.h>
#include <TObjString.h>
#include <TFile.h>
#include <TFolder.h>
#include <TH1F.h>
#include "TLemRunHeader.h"
#include "PRunDataHandler.h"
//--------------------------------------------------------------------------
// Constructor
//--------------------------------------------------------------------------
/**
* <p>
*
*/
PRunDataHandler::PRunDataHandler(PMsrHandler *msrInfo)
{
// cout << endl << "in PRunDataHandler::PRunDataHandler()";
fMsrInfo = msrInfo;
// read files
if (!ReadFile()) // couldn't read file
fAllDataAvailable = false;
else
fAllDataAvailable = true;
}
//--------------------------------------------------------------------------
// Destructor
//--------------------------------------------------------------------------
/**
* <p>
*
*/
PRunDataHandler::~PRunDataHandler()
{
for (unsigned int i=0; i<fData.size(); i++) {
fData[i].fT0s.clear();
for (unsigned int j=0; j<fData[i].fDataBin.size(); j++)
fData[i].fDataBin[j].clear();
}
fData.clear();
}
//--------------------------------------------------------------------------
// GetRunData
//--------------------------------------------------------------------------
/**
* <p>
*
* \param runName
*/
PRawRunData* PRunDataHandler::GetRunData(TString runName)
{
unsigned int i;
for (i=0; i<fData.size(); i++) {
if (!fData[i].fRunName.CompareTo(runName)) // run found
break;
}
if (i == fData.size())
return 0;
else
return &fData[i];
}
//--------------------------------------------------------------------------
// ReadFile
//--------------------------------------------------------------------------
/**
* <p>
*
*/
bool PRunDataHandler::ReadFile()
{
bool success = true;
// loop over the full RUN list to see what needs to be read
PMsrRunList *runList = 0;
runList = fMsrInfo->GetMsrRunList();
if (runList == 0) {
cout << endl << "PRunDataHandler::ReadFile(): Couldn't obtain run list from PMsrHandler: something VERY fishy";
return false;
}
PMsrRunList::iterator run_it;
for (run_it = runList->begin(); run_it != runList->end(); ++run_it) {
//cout << endl << "run : " << run_it->fRunName.Data();
fRunName = run_it->fRunName;
// check is file is already read
if (FileAlreadyRead(*run_it))
continue;
// check if file actually exists
if (!FileExistsCheck(*run_it))
return false;
// everything looks fine, hence try to read the data file
if (!run_it->fFileFormat.CompareTo("root-npp")) // not post pile up corrected histos
success = ReadRootFile();
else if (!run_it->fFileFormat.CompareTo("root-ppc")) // post pile up corrected histos
success = ReadRootFile();
else if (!run_it->fFileFormat.CompareTo("nexus"))
success = ReadNexusFile();
else if (!run_it->fFileFormat.CompareTo("psi-bin"))
success = ReadPsiBinFile();
else if (!run_it->fFileFormat.CompareTo("mud"))
success = ReadMudFile();
else if (!run_it->fFileFormat.CompareTo("nemu"))
success = ReadNemuFile();
else if (!run_it->fFileFormat.CompareTo("ascii"))
success = ReadAsciiFile();
else
success = false;
}
return success;
}
//--------------------------------------------------------------------------
// FileAlreadyRead
//--------------------------------------------------------------------------
/**
* <p>
*
*/
bool PRunDataHandler::FileAlreadyRead(PMsrRunStructure &runInfo)
{
for (unsigned int i=0; i<fData.size(); i++) {
if (!fData[i].fRunName.CompareTo(runInfo.fRunName)) // run alread read
return true;
}
return false;
}
//--------------------------------------------------------------------------
// FileExistsCheck
//--------------------------------------------------------------------------
/**
* <p>
*
*/
bool PRunDataHandler::FileExistsCheck(PMsrRunStructure &runInfo)
{
bool success = true;
// local init
TROOT root("PRunBase", "PRunBase", 0);
TString pathName = "???";
TString str;
TString ext;
runInfo.fRunName.ToLower();
runInfo.fBeamline.ToLower();
runInfo.fInstitute.ToLower();
runInfo.fFileFormat.ToLower();
// file extensions for the various formats
if (!runInfo.fFileFormat.CompareTo("root-npp")) // not post pile up corrected histos
ext = TString("root");
else if (!runInfo.fFileFormat.CompareTo("root-ppc")) // post pile up corrected histos
ext = TString("root");
else if (!runInfo.fFileFormat.CompareTo("nexus"))
ext = TString("nexus");
else if (!runInfo.fFileFormat.CompareTo("psi-bin"))
ext = TString("bin");
else if (!runInfo.fFileFormat.CompareTo("mud"))
ext = TString("mud");
else if (!runInfo.fFileFormat.CompareTo("nemu"))
ext = TString("nemu");
else if (!runInfo.fFileFormat.CompareTo("ascii"))
ext = TString("dat");
else
success = false;
// unkown file format found
if (!success) {
str = runInfo.fFileFormat;
str.ToUpper();
cout << endl << "File Format '" << str.Data() << "' unsupported.";
cout << endl << " support file formats are:";
cout << endl << " ROOT-NPP -> root not post pileup corrected for lem";
cout << endl << " ROOT-PPC -> root post pileup corrected for lem";
cout << endl << " NEXUS -> nexus file format";
cout << endl << " PSI-BIN -> psi bin file format";
cout << endl << " MUD -> triumf mud file format";
cout << endl << " NEMU -> lem ascii file format";
cout << endl << " ASCII -> column like file format";
cout << endl;
return success;
}
// check if the file is in the local directory
str = runInfo.fRunName + TString(".") + ext;
if (gSystem->AccessPathName(str.Data())!=true) { // found in the local dir
pathName = str;
}
// check if the file is found in the directory given in the startup file
// ** STILL MISSING **
// check if the file is found in the directories given by WKMFULLDATAPATH
const char *wkmpath = gSystem->Getenv("WKMFULLDATAPATH");
if (pathName.CompareTo("???") == 0) { // not found in local directory search
str = TString(wkmpath);
// WKMFULLDATAPATH has the structure: path_1:path_2:...:path_n
TObjArray *tokens = str.Tokenize(":");
TObjString *ostr;
for (int i=0; i<tokens->GetEntries(); i++) {
ostr = dynamic_cast<TObjString*>(tokens->At(i));
str = ostr->GetString() + "/" + runInfo.fRunName + TString(".") + ext;
if (gSystem->AccessPathName(str.Data())!=true) { // found
pathName = str;
break;
}
}
}
// check if the file is found in the WKM generated default path
if (pathName.CompareTo("???") == 0) { // not found in WKMFULLDATAPATH search
str = TString(wkmpath);
// WKMFULLDATAPATH has the structure: path_1:path_2:...:path_n
TObjArray *tokens = str.Tokenize(":");
TObjString *ostr;
for (int i=0; i<tokens->GetEntries(); i++) {
ostr = dynamic_cast<TObjString*>(tokens->At(i));
str = ostr->GetString() + TString("/data/") +
runInfo.fInstitute + TString("/") +
runInfo.fBeamline + TString("/") +
runInfo.fRunName + TString(".") + ext;
if (gSystem->AccessPathName(str.Data())!=true) { // found
pathName = str;
break;
}
}
}
// no proper path name found
if (pathName.CompareTo("???") == 0) {
cout << endl << "ERROR: Couldn't find '" << runInfo.fRunName << "' in any standard path.";
cout << endl << " standard search pathes are:";
cout << endl << " 1. the local directory";
cout << endl << " 2. the data directory given in the startup XML file";
cout << endl << " 3. the directories listed in WKMFULLDATAPATH";
cout << endl << " 4. default path construct which is described in the manual";
return false;
}
fRunPathName = pathName;
return true;
}
//--------------------------------------------------------------------------
// ReadRootFile
//--------------------------------------------------------------------------
/**
* <p>
*
*/
bool PRunDataHandler::ReadRootFile()
{
PDoubleVector histoData;
PRawRunData runData;
TFile f(fRunPathName.Data());
if (f.IsZombie()) {
return false;
}
TFolder *folder;
f.GetObject("RunInfo", folder);
if (!folder) {
cout << endl << "Couldn't obtain RunInfo from " << fRunPathName.Data() << endl;
f.Close();
return false;
}
// read header and check if some missing run info need to be fed
TLemRunHeader *runHeader = dynamic_cast<TLemRunHeader*>(folder->FindObjectAny("TLemRunHeader"));
// check if run header is valid
if (!runHeader) {
cout << endl << "Couldn't obtain run header info from ROOT file " << fRunPathName.Data() << endl;
f.Close();
return false;
}
// get time resolution
runData.fTimeResolution = runHeader->GetTimeResolution();
// get number of histogramms
int noOfHistos = runHeader->GetNHist();
// get t0's
Int_t *t0 = runHeader->GetTimeZero();
// check if t0's are there
if (t0[0] != -1) { // ugly, but at the moment there is no other way
// copy t0's so they are not lost
for (int i=0; i<noOfHistos; i++)
runData.fT0s.push_back(t0[i]);
}
// read data ---------------------------------------------------------
// check if histos folder is found
f.GetObject("histos", folder);
if (!folder) {
cout << endl << "Couldn't obtain histos from " << fRunPathName.Data() << endl;
f.Close();
return false;
}
// get all the data
char histoName[32];
// read first the data which are NOT post pileup corrected
for (int i=0; i<noOfHistos; i++) {
sprintf(histoName, "hDecay%02d", i);
TH1F *histo = dynamic_cast<TH1F*>(folder->FindObjectAny(histoName));
if (!histo) {
cout << endl << "PRunDataHandler::ReadRootFile: Couldn't get histo " << histoName;
return false;
}
// fill data
for (int j=1; j<histo->GetNbinsX(); j++)
histoData.push_back(histo->GetBinContent(j));
// store them in runData vector
runData.fDataBin.push_back(histoData);
// clear histoData for the next histo
histoData.clear();
}
// now read the data which ARE post pileup corrected
for (int i=0; i<noOfHistos; i++) {
sprintf(histoName, "hDecay%02d", i+POST_PILEUP_HISTO_OFFSET);
TH1F *histo = dynamic_cast<TH1F*>(folder->FindObjectAny(histoName));
if (!histo) {
cout << endl << "PRunDataHandler::ReadRootFile: Couldn't get histo " << histoName;
return false;
}
// fill data
for (int j=1; j<histo->GetNbinsX(); j++)
histoData.push_back(histo->GetBinContent(j));
// store them in runData vector
runData.fDataBin.push_back(histoData);
// clear histoData for the next histo
histoData.clear();
}
f.Close();
// keep run name
runData.fRunName = fRunName;
// add run to the run list
fData.push_back(runData);
return true;
}
//--------------------------------------------------------------------------
// ReadNexusFile
//--------------------------------------------------------------------------
/**
* <p>
*
*/
bool PRunDataHandler::ReadNexusFile()
{
cout << endl << "PRunDataHandler::ReadNexusFile(): Sorry, not yet implemented ...";
return false;
}
//--------------------------------------------------------------------------
// ReadNemuFile
//--------------------------------------------------------------------------
/**
* <p>
*
*/
bool PRunDataHandler::ReadNemuFile()
{
// cout << endl << "PRunDataHandler::ReadNemuFile(): Sorry, not yet implemented ...";
PDoubleVector histoData;
PRawRunData runData;
// init runData header info
runData.fRunName = TString("");
runData.fRunTitle = TString("");
runData.fSetup = TString("");
runData.fField = nan("NAN");
runData.fTemp = nan("NAN");
runData.fTimeResolution = nan("NAN");
// open file
ifstream f;
// open dump-file
f.open(fRunPathName.Data(), ifstream::in);
if (!f.is_open()) {
cout << endl << "Couldn't open run data (" << fRunPathName.Data() << ") file for reading, sorry ...";
cout << endl;
return false;
}
// read header
bool headerInfo = true;
char instr[128];
TString line;
double dval;
int ival;
bool ok;
int groups = 0, channels = 0;
Ssiz_t idx;
do {
f.getline(instr, sizeof(instr));
line = TString(instr);
if (line.IsWhitespace()) { // end of header reached
headerInfo = false;
} else { // real stuff, hence filter data
if (line.Contains("Title")) {
idx = line.Index(":");
line.Replace(0, idx+1, 0, 0); // remove 'Title:'
StripWhitespace(line);
runData.fRunTitle = line;
} else if (line.Contains("Field")) {
idx = line.Index(":");
line.Replace(0, idx+1, 0, 0); // remove 'Field:'
StripWhitespace(line);
dval = ToDouble(line, ok);
if (ok)
runData.fField = dval;
} else if (line.Contains("Setup")) {
idx = line.Index(":");
line.Replace(0, idx+1, 0, 0); // remove 'Setup:'
StripWhitespace(line);
runData.fSetup = line;
} else if (line.Contains("Temp")) {
idx = line.Index(":");
line.Replace(0, idx+1, 0, 0); // remove 'Temp:'
StripWhitespace(line);
dval = ToDouble(line, ok);
if (ok)
runData.fTemp = dval;
} else if (line.Contains("Groups")) {
idx = line.Index(":");
line.Replace(0, idx+1, 0, 0); // remove 'Groups:'
StripWhitespace(line);
ival = ToInt(line, ok);
if (ok)
groups = ival;
} else if (line.Contains("Channels")) {
idx = line.Index(":");
line.Replace(0, idx+1, 0, 0); // remove 'Channels:'
StripWhitespace(line);
ival = ToInt(line, ok);
if (ok)
channels = ival;
} else if (line.Contains("Resolution")) {
idx = line.Index(":");
line.Replace(0, idx+1, 0, 0); // remove 'Resolution:'
StripWhitespace(line);
dval = ToDouble(line, ok);
if (ok)
runData.fTimeResolution = dval * 1000.0;
}
}
} while (headerInfo);
if ((groups == 0) || (channels == 0) || isnan(runData.fTimeResolution)) {
cout << endl << "PRunDataHandler::ReadNemuFile(): essential header informations are missing!";
f.close();
return false;
}
/*
cout << endl << ">> run title: '" << runData.fRunTitle.Data() << "'";
cout << endl << ">> setup : '" << runData.fSetup.Data() << "'";
cout << endl << ">> field : " << runData.fField;
cout << endl << ">> temp : " << runData.fTemp;
cout << endl << ">> groups : " << groups;
cout << endl << ">> channels : " << channels;
cout << endl << ">> time resolution : " << runData.fTimeResolution;
*/
// read data ---------------------------------------------------------
int status;
unsigned int group_counter = 0;
int val[10];
while (!f.eof()) {
f.getline(instr, sizeof(instr));
// check if empty line, i.e. new group
if (IsWhitespace(instr)) {
runData.fDataBin.push_back(histoData);
histoData.clear();
group_counter++;
}
// extract values
status = sscanf(instr, "%d %d %d %d %d %d %d %d %d %d",
&val[0], &val[1], &val[2], &val[3], &val[4],
&val[5], &val[6], &val[7], &val[8], &val[9]);
// no values found: error
if (status == 0) {
cout << endl << "PRunDataHandler::ReadNemuFile(): **ERROR** while reading data ...";
// clean up
for (unsigned int i=0; i<group_counter; i++)
runData.fDataBin[i].clear();
runData.fDataBin.clear();
return false;
}
// feed data
for (int i=0; i<status; i++)
histoData.push_back(val[i]);
}
// save the last histo
runData.fDataBin.push_back(histoData);
histoData.clear();
// close file
f.close();
// check if all groups are found
if ((int) runData.fDataBin.size() != groups) {
cout << endl << "PRunDataHandler::ReadNemuFile(): **ERROR**";
cout << endl << " expected " << groups << " histos, but found " << runData.fDataBin.size();
// clean up
for (unsigned int i=0; i<runData.fDataBin.size(); i++)
runData.fDataBin[i].clear();
runData.fDataBin.clear();
return false;
}
// check if all groups have enough channels
for (unsigned int i=0; i<runData.fDataBin.size(); i++) {
if ((int) runData.fDataBin[i].size() != channels) {
cout << endl << "PRunDataHandler::ReadNemuFile(): **ERROR**";
cout << endl << " expected " << channels << " bins in histo " << i << ", but found " << runData.fDataBin[i].size();
// clean up
for (unsigned int i=0; i<runData.fDataBin.size(); i++)
runData.fDataBin[i].clear();
runData.fDataBin.clear();
return false;
}
}
// keep run name
runData.fRunName = fRunName;
// add run to the run list
fData.push_back(runData);
return true;
}
//--------------------------------------------------------------------------
// ReadPsiBinFile
//--------------------------------------------------------------------------
/**
* <p>
*
*/
bool PRunDataHandler::ReadPsiBinFile()
{
cout << endl << "PRunDataHandler::ReadPsiBinFile(): Sorry, not yet implemented ...";
return false;
}
//--------------------------------------------------------------------------
// ReadMudFile
//--------------------------------------------------------------------------
/**
* <p>
*
*/
bool PRunDataHandler::ReadMudFile()
{
cout << endl << "PRunDataHandler::ReadMudFile(): Sorry, not yet implemented ...";
return false;
}
//--------------------------------------------------------------------------
// ReadAsciiFile
//--------------------------------------------------------------------------
/**
* <p>
*
*/
bool PRunDataHandler::ReadAsciiFile()
{
cout << endl << "PRunDataHandler::ReadAsciiFile(): Sorry, not yet implemented ...";
return false;
}
//--------------------------------------------------------------------------
// StripWhitespace
//--------------------------------------------------------------------------
/**
* <p>
*
* \param str
*/
bool PRunDataHandler::StripWhitespace(TString &str)
{
char *s = 0;
char *subs = 0;
int i;
int start;
int end;
int size;
size = (int)str.Length();
s = new char[size+1];
if (!s)
return false;
for (int i=0; i<size+1; i++)
s[i] = str[i];
s[size] = 0;
// check for whitespaces at the beginning of the string
i = 0;
while (isblank(s[i]) || iscntrl(s[i])) {
i++;
}
start = i;
// check for whitespaces at the end of the string
i = strlen(s);
while (isblank(s[i]) || iscntrl(s[i])) {
i--;
}
end = i;
if (end < start)
return false;
// make substring
subs = new char[end-start+2];
if (!subs)
return false;
strncpy(subs, s+start, end-start+1);
subs[end-start+1] = 0;
str = TString(subs);
// clean up
if (subs) {
delete [] subs;
subs = 0;
}
if (s) {
delete [] s;
s = 0;
}
return true;
}
//--------------------------------------------------------------------------
// IsWhitespace
//--------------------------------------------------------------------------
/**
* <p>
*
* \param str
*/
bool PRunDataHandler::IsWhitespace(const char *str)
{
unsigned int i=0;
while (isblank(str[i]) || (iscntrl(str[i])) && str[i] != 0)
i++;
if (i == strlen(str))
return true;
else
return false;
}
//--------------------------------------------------------------------------
// ToDouble
//--------------------------------------------------------------------------
/**
* <p>
*
* \param str
* \param ok
*/
double PRunDataHandler::ToDouble(TString &str, bool &ok)
{
char *s;
double value;
int size, status;
ok = true;
size = (int)str.Length();
s = new char[size+1];
if (!s) {
ok = false;
return 0.0;
}
// copy string; stupid way but it works
for (int i=0; i<size+1; i++)
s[i] = str[i];
s[size] = 0;
// extract value
status = sscanf(s, "%lf", &value);
if (status != 1) {
ok = false;
return 0.0;
}
// clean up
if (s) {
delete [] s;
s = 0;
}
return value;
}
//--------------------------------------------------------------------------
// ToInt
//--------------------------------------------------------------------------
/**
* <p>
*
* \param str
* \param ok
*/
int PRunDataHandler::ToInt(TString &str, bool &ok)
{
char *s;
int value;
int size, status;
ok = true;
size = (int)str.Length();
s = new char[size+1];
if (!s) {
ok = false;
return 0;
}
// copy string; stupid way but it works
for (int i=0; i<size+1; i++)
s[i] = str[i];
s[size] = 0;
// extract value
status = sscanf(s, "%d", &value);
if (status != 1) {
ok = false;
return 0;
}
// clean up
if (s) {
delete [] s;
s = 0;
}
return value;
}

View File

@ -0,0 +1,366 @@
/***************************************************************************
PRunListCollection.cpp
Author: Andreas Suter
e-mail: andreas.suter@psi.ch
$Id$
***************************************************************************/
/***************************************************************************
* Copyright (C) 2007 by Andreas Suter *
* andreas.suter@psi.c *
* *
* 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 <iostream>
#include "PRunListCollection.h"
//--------------------------------------------------------------------------
// Constructor
//--------------------------------------------------------------------------
/**
* <p>
*
* \param msrInfo pointer to the msr info structure
* \param runNo number of the run of the msr-file
*/
PRunListCollection::PRunListCollection(PMsrHandler *msrInfo, PRunDataHandler *data)
{
fMsrInfo = msrInfo;
fData = data;
}
//--------------------------------------------------------------------------
// Destructor
//--------------------------------------------------------------------------
/**
* <p>
*
*/
PRunListCollection::~PRunListCollection()
{
//cout << endl << "in ~PRunListCollection() ..." << endl;
//cout << endl << ">> fRunSingleHistoList.size() = " << fRunSingleHistoList.size();
for (unsigned int i=0; i<fRunSingleHistoList.size(); i++)
fRunSingleHistoList[i]->CleanUp();
fRunSingleHistoList.clear();
//cout << endl << ">> fRunAsymmetryList.size() = " << fRunAsymmetryList.size();
for (unsigned int i=0; i<fRunAsymmetryList.size(); i++)
fRunAsymmetryList[i]->CleanUp();
fRunAsymmetryList.clear();
//cout << endl << ">> fRunRRFList.size() = " << fRunRRFList.size();
for (unsigned int i=0; i<fRunRRFList.size(); i++)
fRunRRFList[i]->CleanUp();
fRunRRFList.clear();
//cout << endl << ">> fRunNonMusrList.size() = " << fRunNonMusrList.size();
for (unsigned int i=0; i<fRunNonMusrList.size(); i++)
fRunNonMusrList[i]->CleanUp();
fRunNonMusrList.clear();
}
//--------------------------------------------------------------------------
// Add
//--------------------------------------------------------------------------
/**
* <p>
*
* \param runNo
*/
bool PRunListCollection::Add(int runNo)
{
bool success = true;
PMsrRunStructure *runList = &(*fMsrInfo->GetMsrRunList())[runNo];
cout << endl << "PRunListCollection::Add(): will add run no " << runNo;
cout << ", name = " << runList->fRunName.Data();
cout << ", type = " << runList->fFitType;
int fitType = (*fMsrInfo->GetMsrRunList())[runNo].fFitType;
PRunAsymmetry* asym;
bool status;
switch (fitType) {
case PRUN_SINGLE_HISTO:
fRunSingleHistoList.push_back(new PRunSingleHisto(fMsrInfo, fData, runNo));
if (!fRunSingleHistoList[fRunSingleHistoList.size()-1]->IsValid())
success = false;
break;
case PRUN_ASYMMETRY:
fRunAsymmetryList.push_back(new PRunAsymmetry(fMsrInfo, fData, runNo));
asym = fRunAsymmetryList[fRunAsymmetryList.size()-1];
status = asym->IsValid();
if (!fRunAsymmetryList[fRunAsymmetryList.size()-1]->IsValid())
success = false;
break;
case PRUN_RRF:
fRunRRFList.push_back(new PRunRRF(fMsrInfo, fData, runNo));
if (!fRunRRFList[fRunRRFList.size()-1]->IsValid())
success = false;
break;
case PRUN_NON_MUSR:
fRunNonMusrList.push_back(new PRunNonMusr(fMsrInfo, fData, runNo));
if (!fRunNonMusrList[fRunNonMusrList.size()-1]->IsValid())
success = false;
break;
default:
success = false;
break;
}
return success;
}
//--------------------------------------------------------------------------
// GetSingleHistoChisq
//--------------------------------------------------------------------------
/**
* <p>
*/
double PRunListCollection::GetSingleHistoChisq(const std::vector<double>& par)
{
double chisq = 0.0;
for (unsigned int i=0; i<fRunSingleHistoList.size(); i++)
chisq += fRunSingleHistoList[i]->CalcChiSquare(par);
return chisq;
}
//--------------------------------------------------------------------------
// GetAsymmetryChisq
//--------------------------------------------------------------------------
/**
* <p>
*/
double PRunListCollection::GetAsymmetryChisq(const std::vector<double>& par)
{
double chisq = 0.0;
for (unsigned int i=0; i<fRunAsymmetryList.size(); i++)
chisq += fRunAsymmetryList[i]->CalcChiSquare(par);
return chisq;
}
//--------------------------------------------------------------------------
// GetRRFChisq
//--------------------------------------------------------------------------
/**
* <p>
*/
double PRunListCollection::GetRRFChisq(const std::vector<double>& par)
{
double chisq = 0.0;
for (unsigned int i=0; i<fRunRRFList.size(); i++)
chisq += fRunRRFList[i]->CalcChiSquare(par);
return chisq;
}
//--------------------------------------------------------------------------
// GetNonMusrChisq
//--------------------------------------------------------------------------
/**
* <p>
*/
double PRunListCollection::GetNonMusrChisq(const std::vector<double>& par)
{
double chisq = 0.0;
for (unsigned int i=0; i<fRunNonMusrList.size(); i++)
chisq += fRunNonMusrList[i]->CalcChiSquare(par);
return chisq;
}
//--------------------------------------------------------------------------
// GetSingleHistoMaximumLikelihood
//--------------------------------------------------------------------------
/**
* <p>
*/
double PRunListCollection::GetSingleHistoMaximumLikelihood(const std::vector<double>& par)
{
double mlh = 0.0;
for (unsigned int i=0; i<fRunSingleHistoList.size(); i++)
mlh += fRunSingleHistoList[i]->CalcMaxLikelihood(par);
return mlh;
}
//--------------------------------------------------------------------------
// GetAsymmetryMaximumLikelihood
//--------------------------------------------------------------------------
/**
* <p>
*/
double PRunListCollection::GetAsymmetryMaximumLikelihood(const std::vector<double>& par)
{
double mlh = 0.0;
for (unsigned int i=0; i<fRunAsymmetryList.size(); i++)
mlh += fRunAsymmetryList[i]->CalcMaxLikelihood(par);
return mlh;
}
//--------------------------------------------------------------------------
// GetRRFMaximumLikelihood
//--------------------------------------------------------------------------
/**
* <p>
*/
double PRunListCollection::GetRRFMaximumLikelihood(const std::vector<double>& par)
{
double mlh = 0.0;
for (unsigned int i=0; i<fRunRRFList.size(); i++)
mlh += fRunRRFList[i]->CalcMaxLikelihood(par);
return mlh;
}
//--------------------------------------------------------------------------
// GetNonMusrMaximumLikelihood
//--------------------------------------------------------------------------
/**
* <p>
*/
double PRunListCollection::GetNonMusrMaximumLikelihood(const std::vector<double>& par)
{
double mlh = 0.0;
for (unsigned int i=0; i<fRunNonMusrList.size(); i++)
mlh += fRunNonMusrList[i]->CalcMaxLikelihood(par);
return mlh;
}
//--------------------------------------------------------------------------
// GetTotalNoOfBinsFitted
//--------------------------------------------------------------------------
/**
* <p>
*/
unsigned int PRunListCollection::GetTotalNoOfBinsFitted()
{
unsigned int counts = 0;
for (unsigned int i=0; i<fRunSingleHistoList.size(); i++)
counts += fRunSingleHistoList[i]->GetNoOfFitBins();
for (unsigned int i=0; i<fRunAsymmetryList.size(); i++)
counts += fRunAsymmetryList[i]->GetNoOfFitBins();
for (unsigned int i=0; i<fRunRRFList.size(); i++)
counts += fRunRRFList[i]->GetNoOfFitBins();
for (unsigned int i=0; i<fRunNonMusrList.size(); i++)
counts += fRunNonMusrList[i]->GetNoOfFitBins();
// cout << endl << "Total No of Bins Fitted = " << counts;
return counts;
}
//--------------------------------------------------------------------------
// GetSingleHisto
//--------------------------------------------------------------------------
/**
* <p>
*
* \param index
*/
PRunData* PRunListCollection::GetSingleHisto(unsigned int index)
{
if ((index < 0) || (index > fRunSingleHistoList.size())) {
cout << endl << "PRunListCollection::GetSingleHisto: index = " << index << " out of bounds";
return 0;
}
fRunSingleHistoList[index]->CalcTheory();
PRunData *data = fRunSingleHistoList[index]->GetData();
return data;
}
//--------------------------------------------------------------------------
// GetAsymmetry
//--------------------------------------------------------------------------
/**
* <p>
*
* \param index
*/
PRunData* PRunListCollection::GetAsymmetry(unsigned int index)
{
if ((index < 0) || (index > fRunAsymmetryList.size())) {
cout << endl << "PRunListCollection::GetAsymmetry: index = " << index << " out of bounds";
return 0;
}
fRunAsymmetryList[index]->CalcTheory();
PRunData *data = fRunAsymmetryList[index]->GetData();
return data;
}
//--------------------------------------------------------------------------
// GetRRF
//--------------------------------------------------------------------------
/**
* <p>
*
* \param index
*/
PRunData* PRunListCollection::GetRRF(unsigned int index)
{
if ((index < 0) || (index > fRunRRFList.size())) {
cout << endl << "PRunListCollection::GetRRF: index = " << index << " out of bounds";
return 0;
}
return 0;
}
//--------------------------------------------------------------------------
// GetNonMusr
//--------------------------------------------------------------------------
/**
* <p>
*
* \param index
*/
PRunData* PRunListCollection::GetNonMusr(unsigned int index)
{
if ((index < 0) || (index > fRunNonMusrList.size())) {
cout << endl << "PRunListCollection::GetNonMusr: index = " << index << " out of bounds";
return 0;
}
return 0;
}

144
src/classes/PRunNonMusr.cpp Normal file
View File

@ -0,0 +1,144 @@
/***************************************************************************
PRunNonMusr.cpp
Author: Andreas Suter
e-mail: andreas.suter@psi.ch
$Id$
***************************************************************************/
/***************************************************************************
* Copyright (C) 2007 by Andreas Suter *
* andreas.suter@psi.c *
* *
* 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 <iostream>
#include "PRunNonMusr.h"
//--------------------------------------------------------------------------
// Constructor
//--------------------------------------------------------------------------
/**
* <p>
*
*/
PRunNonMusr::PRunNonMusr() : PRunBase()
{
fFitStartTime = 0.0;
fFitStopTime = 0.0;
fNoOfFitBins = 0;
}
//--------------------------------------------------------------------------
// Constructor
//--------------------------------------------------------------------------
/**
* <p>
*
* \param msrInfo pointer to the msr info structure
* \param runNo number of the run of the msr-file
*/
PRunNonMusr::PRunNonMusr(PMsrHandler *msrInfo, PRunDataHandler *rawData, unsigned int runNo) : PRunBase(msrInfo, rawData, runNo)
{
bool success;
// calculate fData
if (success) {
success = PrepareData();
}
}
//--------------------------------------------------------------------------
// Destructor
//--------------------------------------------------------------------------
/**
* <p>
*
*/
PRunNonMusr::~PRunNonMusr()
{
}
//--------------------------------------------------------------------------
// CalcChiSquare
//--------------------------------------------------------------------------
/**
* <p>
*
* \param par parameter vector iterated by minuit
*/
double PRunNonMusr::CalcChiSquare(const std::vector<double>& par)
{
double chisq = 0.0;
double diff = 0.0;
return chisq;
}
//--------------------------------------------------------------------------
// CalcMaxLikelihood
//--------------------------------------------------------------------------
/**
* <p>
*
* \param par parameter vector iterated by minuit
*/
double PRunNonMusr::CalcMaxLikelihood(const std::vector<double>& par)
{
cout << endl << "PRunSingleHisto::CalcMaxLikelihood(): not implemented yet ..." << endl;
return 1.0;
}
//--------------------------------------------------------------------------
// CalcTheory
//--------------------------------------------------------------------------
/**
* <p>
*
*/
void PRunNonMusr::CalcTheory()
{
}
//--------------------------------------------------------------------------
// PrepareData
//--------------------------------------------------------------------------
/**
* <p>
*
*/
bool PRunNonMusr::PrepareData()
{
bool success = true;
cout << endl << "in PRunNonMusr::PrepareData(): will feed fData";
// count the number of bins to be fitted
fNoOfFitBins=0;
for (unsigned int i=0; i<fData.fValue.size(); i++) {
if ((fData.fTime[i] >= fFitStartTime) && (fData.fTime[i] <= fFitStopTime))
fNoOfFitBins++;
}
return success;
}

144
src/classes/PRunRRF.cpp Normal file
View File

@ -0,0 +1,144 @@
/***************************************************************************
PRunRRF.cpp
Author: Andreas Suter
e-mail: andreas.suter@psi.ch
$Id$
***************************************************************************/
/***************************************************************************
* Copyright (C) 2007 by Andreas Suter *
* andreas.suter@psi.c *
* *
* 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 <iostream>
#include "PRunRRF.h"
//--------------------------------------------------------------------------
// Constructor
//--------------------------------------------------------------------------
/**
* <p>
*
*/
PRunRRF::PRunRRF() : PRunBase()
{
fFitStartTime = 0.0;
fFitStopTime = 0.0;
fNoOfFitBins = 0;
}
//--------------------------------------------------------------------------
// Constructor
//--------------------------------------------------------------------------
/**
* <p>
*
* \param msrInfo pointer to the msr info structure
* \param runNo number of the run of the msr-file
*/
PRunRRF::PRunRRF(PMsrHandler *msrInfo, PRunDataHandler *rawData, unsigned int runNo) : PRunBase(msrInfo, rawData, runNo)
{
bool success;
// calculate fData
if (success) {
success = PrepareData();
}
}
//--------------------------------------------------------------------------
// Destructor
//--------------------------------------------------------------------------
/**
* <p>
*
*/
PRunRRF::~PRunRRF()
{
}
//--------------------------------------------------------------------------
// CalcChiSquare
//--------------------------------------------------------------------------
/**
* <p>
*
* \param par parameter vector iterated by minuit
*/
double PRunRRF::CalcChiSquare(const std::vector<double>& par)
{
double chisq = 0.0;
double diff = 0.0;
return chisq;
}
//--------------------------------------------------------------------------
// CalcMaxLikelihood
//--------------------------------------------------------------------------
/**
* <p>
*
* \param par parameter vector iterated by minuit
*/
double PRunRRF::CalcMaxLikelihood(const std::vector<double>& par)
{
cout << endl << "PRunSingleHisto::CalcMaxLikelihood(): not implemented yet ..." << endl;
return 1.0;
}
//--------------------------------------------------------------------------
// CalcTheory
//--------------------------------------------------------------------------
/**
* <p>
*
*/
void PRunRRF::CalcTheory()
{
}
//--------------------------------------------------------------------------
// PrepareData
//--------------------------------------------------------------------------
/**
* <p>
*
*/
bool PRunRRF::PrepareData()
{
bool success = true;
cout << endl << "in PRunRRF::PrepareData(): will feed fData";
// count the number of bins to be fitted
fNoOfFitBins=0;
for (unsigned int i=0; i<fData.fValue.size(); i++) {
if ((fData.fTime[i] >= fFitStartTime) && (fData.fTime[i] <= fFitStopTime))
fNoOfFitBins++;
}
return success;
}

View File

@ -0,0 +1,342 @@
/***************************************************************************
PRunSingleHisto.cpp
Author: Andreas Suter
e-mail: andreas.suter@psi.ch
$Id$
***************************************************************************/
/***************************************************************************
* Copyright (C) 2007 by Andreas Suter *
* andreas.suter@psi.c *
* *
* 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 <iostream>
#include <fstream>
#include "PMusr.h"
#include "PRunSingleHisto.h"
//--------------------------------------------------------------------------
// Constructor
//--------------------------------------------------------------------------
/**
* <p>
*
*/
PRunSingleHisto::PRunSingleHisto() : PRunBase()
{
fFitStartTime = 0.0;
fFitStopTime = 0.0;
fNoOfFitBins = 0;
}
//--------------------------------------------------------------------------
// Constructor
//--------------------------------------------------------------------------
/**
* <p>
*
* \param msrInfo pointer to the msr info structure
* \param runNo number of the run of the msr-file
*/
PRunSingleHisto::PRunSingleHisto(PMsrHandler *msrInfo, PRunDataHandler *rawData, unsigned int runNo) : PRunBase(msrInfo, rawData, runNo)
{
if (!PrepareData()) {
cout << endl << "**SEVERE ERROR**: PRunSingleHisto::PRunSingleHisto: Couldn't prepare data for fitting!";
cout << endl << " This is very bad :-(, will quit ...";
fValid = false;
}
}
//--------------------------------------------------------------------------
// Destructor
//--------------------------------------------------------------------------
/**
* <p>
*
*/
PRunSingleHisto::~PRunSingleHisto()
{
}
//--------------------------------------------------------------------------
// CalcChiSquare
//--------------------------------------------------------------------------
/**
* <p>
*
* The return value is chisq * fRunInfo->fPacking, the reason is:
* the data d_i and the theory t_i are scaled by the packing, i.e. d_i -> d_i / packing.
* Since the error is 1/sqrt(d_i) and hence error^2 = d_i it follows that
* (d_i - t_i)^2 ~ 1/packing^2 and error^2 ~ 1/packing, and hence the chisq needs
* to be scaled by packing.
*
* \param par parameter vector iterated by minuit
*/
double PRunSingleHisto::CalcChiSquare(const std::vector<double>& par)
{
double chisq = 0.0;
double diff = 0.0;
double N0;
// check if norm is a parameter or a function
if (fRunInfo->fNormParamNo < MSR_PARAM_FUN_OFFSET) { // norm is a parameter
N0 = par[fRunInfo->fNormParamNo-1];
} else { // norm is a function
// get function number
unsigned int funNo = fRunInfo->fNormParamNo-MSR_PARAM_FUN_OFFSET;
// evaluate function
N0 = fMsrInfo->EvalFunc(funNo,fRunInfo->fMap,par);
}
// get tau
double tau;
if (fRunInfo->fLifetimeParamNo != -1)
tau = par[fRunInfo->fLifetimeParamNo-1];
else
tau = PMUON_LIFETIME;
// get background
double bkg = par[fRunInfo->fBkgFitParamNo-1];
// calculate functions
for (int i=0; i<fMsrInfo->GetNoOfFuncs(); i++) {
int funcNo = fMsrInfo->GetFuncNo(i);
//cout << ">> i = " << i << ", funcNo = " << funcNo << endl;
fFuncValues[i] = fMsrInfo->EvalFunc(funcNo, fRunInfo->fMap, par);
}
// calculate chi square
for (unsigned int i=0; i<fData.fValue.size(); i++) {
if ((fData.fTime[i]>=fFitStartTime) && (fData.fTime[i]<=fFitStopTime)) {
diff = fData.fValue[i] -
(N0*TMath::Exp(-fData.fTime[i]/tau)*(1+fTheory->Func(fData.fTime[i], par, fFuncValues))+bkg);
chisq += diff*diff / (fData.fError[i]*fData.fError[i]);
}
}
// static int counter = 0;
// TString fln=fRunInfo->fRunName+"_"+(Long_t)fRunInfo->fForwardHistoNo+"_data.dat";
// ofstream f(fln.Data(),ios_base::out);
// for (unsigned int i=0; i<fData.fValue.size(); i++) {
// f << endl << fData.fTime[i] << " " << fData.fValue[i] << " " << fData.fError[i];
// }
// f.close();
//
// fln=fRunInfo->fRunName+"_"+(Long_t)fRunInfo->fForwardHistoNo+"_theo.dat";
// ofstream ft(fln.Data(),ios_base::out);
// for (unsigned int i=0; i<fData.fValue.size(); i++) {
// ft << endl << fData.fTime[i] << " " << N0*TMath::Exp(-fData.fTime[i]/tau)*(1+fTheory->Func(fData.fTime[i], par))+bkg;
// }
// ft.close();
// counter++;
// if (counter == 4) exit(0);
return chisq*fRunInfo->fPacking;
}
//--------------------------------------------------------------------------
// CalcMaxLikelihood
//--------------------------------------------------------------------------
/**
* <p>
*
* \param par parameter vector iterated by minuit
*/
double PRunSingleHisto::CalcMaxLikelihood(const std::vector<double>& par)
{
cout << endl << "PRunSingleHisto::CalcMaxLikelihood(): not implemented yet ..." << endl;
return 1.0;
}
//--------------------------------------------------------------------------
// CalcTheory
//--------------------------------------------------------------------------
/**
* <p>
*
*/
void PRunSingleHisto::CalcTheory()
{
// feed the parameter vector
std::vector<double> par;
PMsrParamList *paramList = fMsrInfo->GetMsrParamList();
for (unsigned int i=0; i<paramList->size(); i++)
par.push_back((*paramList)[i].fValue);
// calculate asymmetry
double N0 = par[fRunInfo->fNormParamNo-1];
// get tau
double tau;
if (fRunInfo->fLifetimeParamNo != -1)
tau = par[fRunInfo->fLifetimeParamNo-1];
else
tau = PMUON_LIFETIME;
// get background
double bkg = par[fRunInfo->fBkgFitParamNo-1];
// calculate functions
for (int i=0; i<fMsrInfo->GetNoOfFuncs(); i++) {
fFuncValues[i] = fMsrInfo->EvalFunc(fMsrInfo->GetFuncNo(i), fRunInfo->fMap, par);
}
// calculate theory
for (unsigned int i=0; i<fData.fTime.size(); i++) {
fData.fTheory.push_back(N0*TMath::Exp(-fData.fTime[i]/tau)*(1+fTheory->Func(fData.fTime[i], par, fFuncValues))+bkg);
}
// clean up
par.clear();
}
//--------------------------------------------------------------------------
// PrepareData
//--------------------------------------------------------------------------
/**
* <p>
*
*/
bool PRunSingleHisto::PrepareData()
{
// cout << endl << "in PRunSingleHisto::PrepareData(): will feed fData";
// get the proper run
PRawRunData* runData = fRawData->GetRunData(fRunInfo->fRunName);
if (!runData) { // couldn't get run
cout << endl << "PRunSingleHisto::PrepareData(): Couldn't get run " << fRunInfo->fRunName.Data() << "!";
return false;
}
// keep the time resolution in (us)
fTimeResolution = runData->fTimeResolution/1.0e3;
// keep start/stop time for fit
fFitStartTime = fRunInfo->fFitRange[0];
fFitStopTime = fRunInfo->fFitRange[1];
//cout << endl << "start/stop (fit): " << fFitStartTime << ", " << fFitStopTime;
// check if the t0's are given in the msr-file
if (fRunInfo->fT0[0] == -1) { // t0's are NOT in the msr-file
// check if the t0's are in the data file
if (runData->fT0s.size() != 0) { // t0's in the run data
// keep the proper t0's. For single histo runs, forward is holding the histo no
// fForwardHistoNo starts with 1 not with 0 ;-)
fT0s.push_back(runData->fT0s[fRunInfo->fForwardHistoNo-1]);
} else { // t0's are neither in the run data nor in the msr-file -> not acceptable!
cout << endl << "PRunSingleHisto::PrepareData(): NO t0's found, neither in the run data nor in the msr-file!";
return false;
}
} else { // t0's in the msr-file
// check if t0's are given in the data file
if (runData->fT0s.size() != 0) {
// compare t0's of the msr-file with the one in the data file
if (fabs(fRunInfo->fT0[0]-runData->fT0s[fRunInfo->fForwardHistoNo-1])>5.0) { // given in bins!!
cout << endl << "PRunSingleHisto::PrepareData(): **WARNING**:";
cout << endl << " t0 from the msr-file is " << fRunInfo->fT0[0];
cout << endl << " t0 from the data file is " << runData->fT0s[fRunInfo->fForwardHistoNo-1];
cout << endl << " This is quite a deviation! Is this done intentionally??";
cout << endl;
}
}
fT0s.push_back(fRunInfo->fT0[0]);
}
// check if post pile up data shall be used
unsigned int histoNo;
if (fRunInfo->fFileFormat.Contains("ppc")) {
histoNo = runData->fDataBin.size()/2 + fRunInfo->fForwardHistoNo-1;
} else {
histoNo = fRunInfo->fForwardHistoNo-1;
}
if ((runData->fDataBin.size() < histoNo) || (histoNo < 0)) {
cout << endl << "PRunSingleHisto::PrepareData(): PANIC ERROR:";
cout << endl << " histoNo found = " << histoNo << ", but there are only " << runData->fDataBin.size() << " runs!?!?";
cout << endl << " Will quite :-(";
cout << endl;
return false;
}
// transform raw histo data. This is done the following way (for details see the manual):
// for the single histo fit, just the rebinned raw data are copied
// first get start data, end data, and t0
unsigned int start = fRunInfo->fDataRange[0];
unsigned int end = fRunInfo->fDataRange[1];
unsigned int t0 = fT0s[0];
// check if start, end, and t0 make any sense
// 1st check if start and end are in proper order
if (end < start) { // need to swap them
int keep = end;
end = start;
start = keep;
}
// 2nd check if start is within proper bounds
if ((start < 0) || (start > runData->fDataBin[histoNo].size())) {
cout << endl << "PRunSingleHisto::PrepareData(): start data bin doesn't make any sense!";
return false;
}
// 3rd check if end is within proper bounds
if ((end < 0) || (end > runData->fDataBin[histoNo].size())) {
cout << endl << "PRunSingleHisto::PrepareData(): end data bin doesn't make any sense!";
return false;
}
// 4th check if t0 is within proper bounds
if ((t0 < 0) || (t0 > runData->fDataBin[histoNo].size())) {
cout << endl << "PRunSingleHisto::PrepareData(): t0 data bin doesn't make any sense!";
return false;
}
// everything looks fine, hence fill data set
double value = 0.0;
for (unsigned i=start; i<end; i++) {
if (((i-start) % fRunInfo->fPacking == 0) && (i != start)) { // fill data
// in order that after rebinning the fit does not need to be redone (important for plots)
// the value is normalize to per bin
value /= fRunInfo->fPacking;
// time shifted so that packing is included correctly, i.e. t0 == t0 after packing
fData.fTime.push_back(fTimeResolution*((double)i-(double)t0-(double)fRunInfo->fPacking));
fData.fValue.push_back(value);
if (value == 0.0)
fData.fError.push_back(1.0);
else
fData.fError.push_back(TMath::Sqrt(value));
value = 0.0;
}
value += runData->fDataBin[histoNo][i];
}
// count the number of bins to be fitted
fNoOfFitBins=0;
for (unsigned int i=0; i<fData.fValue.size(); i++) {
if ((fData.fTime[i] >= fFitStartTime) && (fData.fTime[i] <= fFitStopTime))
fNoOfFitBins++;
}
return true;
}

View File

@ -0,0 +1,55 @@
/***************************************************************************
PStartupHandler.cpp
Author: Andreas Suter
e-mail: andreas.suter@psi.ch
$Id$
***************************************************************************/
/***************************************************************************
* Copyright (C) 2007 by Andreas Suter *
* andreas.suter@psi.c *
* *
* 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 "PStartupHandler.h"
//--------------------------------------------------------------------------
// Constructor
//--------------------------------------------------------------------------
/*!
* <p>
*/
PStartupHandler::PStartupHandler()
{
}
//--------------------------------------------------------------------------
// Destructor
//--------------------------------------------------------------------------
/*!
* <p>
*/
PStartupHandler::~PStartupHandler()
{
}
// end ---------------------------------------------------------------------

970
src/classes/PTheory.cpp Normal file
View File

@ -0,0 +1,970 @@
/***************************************************************************
PTheory.cpp
Author: Andreas Suter
e-mail: andreas.suter@psi.ch
$Id$
***************************************************************************/
/***************************************************************************
* Copyright (C) 2007 by Andreas Suter *
* andreas.suter@psi.c *
* *
* 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 <iostream>
using namespace std;
#include <TString.h>
#include <TObjString.h>
#include <TObjArray.h>
#include <TMath.h>
#include "PMsrHandler.h"
#include "PTheory.h"
//--------------------------------------------------------------------------
// Constructor
//--------------------------------------------------------------------------
/**
* <p> The theory block his parsed and mapped to a tree. Every line (except the '+')
* is a theory object by itself, i.e. the whole theory is build up recursivly.
* Example:
* Theory block:
* a 1
* tf 2 3
* se 4
* +
* a 5
* tf 6 7
* se 8
* +
* a 9
* tf 10 11
*
* This is mapped into the following binary tree:
*
* a 1
* +/ \*
* a 5 tf 2 3
* + / \* \ *
* a 9 a 5 se 4
* \* \*
* tf 10 11 tf 6 7
* \*
* se 8
*
* \param msrInfo
* \param runNo
* \param parent needed in order to know if PTheory is the root object or a child
* false (default) -> this is the root object
* true -> this is part of an already existing object tree
*/
PTheory::PTheory(PMsrHandler *msrInfo, unsigned int runNo, const bool hasParent)
{
// init stuff
fValid = true;
fAdd = 0;
fMul = 0;
static unsigned int lineNo = 1; // lineNo
static unsigned int depth = 0; // needed to handle '+' properly
if (hasParent == false) { // reset static counters if root object
lineNo = 1; // the lineNo counter and the depth counter need to be
depth = 0; // reset for every root object (new run).
}
// get the input to be analyzed from the msr handler
PMsrLines *fullTheoryBlock = msrInfo->GetMsrTheory();
if (lineNo > fullTheoryBlock->size()-1) {
return;
}
// get the line to be parsed
PMsrLineStructure *line = &(*fullTheoryBlock)[lineNo];
// copy line content to str in order to remove comments
TString str = line->fLine.Copy();
// remove theory line comment if present, i.e. something starting with '('
int index = str.Index("(");
if (index > 0) // theory line comment present
str.Resize(index);
// remove msr-file comment if present, i.e. something starting with '#'
index = str.Index("#");
if (index > 0) // theory line comment present
str.Resize(index);
// tokenize line
TObjArray *tokens;
TObjString *ostr;
tokens = str.Tokenize(" ");
if (!tokens) {
cout << endl << "**SEVERE ERROR**: PTheory(): Couldn't tokenize theory block line " << line->fLineNo << ".";
cout << endl << " line content: " << line->fLine.Data();
cout << endl;
exit(0);
}
ostr = dynamic_cast<TObjString*>(tokens->At(0));
str = ostr->GetString();
// search the theory function
unsigned int idx = SearchDataBase(str);
// function found is not defined
if (idx == (unsigned int) THEORY_UNDEFINED) {
cout << endl << "**ERROR**: PTheory(): Theory line '" << line->fLine.Data() << "'";
cout << endl << " in line no " << line->fLineNo << " is undefined!";
fValid = false;
return;
}
// line is a valid function, hence analyze parameters
if ((unsigned int)(tokens->GetEntries()-1) != fNoOfParam) {
cout << endl << "**ERROR**: PTheory(): Theory line '" << line->fLine.Data() << "'";
cout << " in line no " << line->fLineNo;
cout << " expecting " << fgTheoDataBase[idx].fNoOfParam << ", but found " << tokens->GetEntries()-1;
fValid = false;
}
// keep function index
fType = idx;
// filter out the parameters
int status;
unsigned int value;
bool ok = false;;
for (int i=1; i<tokens->GetEntries(); i++) {
ostr = dynamic_cast<TObjString*>(tokens->At(i));
str = ostr->GetString();
// check if str is map
if (str.Contains("map")) {
status = sscanf(str.Data(), "map%u", &value);
if (status == 1) { // everthing ok
ok = true;
// get parameter from map
PIntVector maps = (*msrInfo->GetMsrRunList())[runNo].fMap;
if ((value <= maps.size()) && (value > 0)) { // everything fine
fParamNo.push_back(maps[value-1]-1);
} else { // map index out of range
cout << endl << "**ERROR**: PTheory: map index " << value << " out of range! See line no " << line->fLineNo;
fValid = false;
}
} else { // something wrong
cout << endl << "**ERROR**: PTheory: map '" << str.Data() << "' not allowed. See line no " << line->fLineNo;
fValid = false;
}
} else if (str.Contains("fun")) { // check if str is fun
status = sscanf(str.Data(), "fun%u", &value);
if (status == 1) { // everthing ok
ok = true;
// handle function, i.e. get, from the function number x (FUNx), the function index,
// add function offset and fill "parameter vector"
fParamNo.push_back(msrInfo->GetFuncIndex(value)+MSR_PARAM_FUN_OFFSET);
} else { // something wrong
fValid = false;
}
} else { // check if str is param no
status = sscanf(str.Data(), "%u", &value);
if (status == 1) { // everthing ok
ok = true;
fParamNo.push_back(value-1);
}
// check if one of the valid entries was found
if (!ok) {
cout << endl << "**ERROR**: PTheory: '" << str.Data() << "' not allowed. See line no " << line->fLineNo;
fValid = false;
}
}
}
// call the next line (only if valid so far and not the last line)
// handle '*'
if (fValid && (lineNo < fullTheoryBlock->size()-1)) {
line = &(*fullTheoryBlock)[lineNo+1];
if (!line->fLine.Contains("+")) { // make sure next line is not a '+'
depth++;
lineNo++;
fMul = new PTheory(msrInfo, runNo, true);
depth--;
}
}
// call the next line (only if valid so far and not the last line)
// handle '+'
if (fValid && (lineNo < fullTheoryBlock->size()-1)) {
line = &(*fullTheoryBlock)[lineNo+1];
if ((depth == 0) && line->fLine.Contains("+")) {
lineNo += 2; // go to the next theory function line
fAdd = new PTheory(msrInfo, runNo, true);
}
}
// make clean and tidy theory block for the msr-file
if (fValid && !hasParent) { // parent theory object
MakeCleanAndTidyTheoryBlock(fullTheoryBlock);
}
// clean up
if (tokens) {
delete tokens;
tokens = 0;
}
}
//--------------------------------------------------------------------------
// Destructor
//--------------------------------------------------------------------------
/**
* <p>
*/
PTheory::~PTheory()
{
//cout << endl << "PTheory::~PTheory() ..." << endl;
fParamNo.clear();
if (fMul) {
delete fMul;
fMul = 0;
}
if (fAdd) {
delete fAdd;
fAdd = 0;
}
}
//--------------------------------------------------------------------------
// IsValid
//--------------------------------------------------------------------------
/**
* <p>Checks if the theory tree is valid. Needs to be implemented!!
*
*/
bool PTheory::IsValid()
{
if (fMul) {
if (fAdd) {
return (fValid && fMul->IsValid() && fAdd->IsValid());
} else {
return (fValid && fMul->IsValid());
}
} else {
if (fAdd) {
return (fValid && fAdd->IsValid());
} else {
return fValid;
}
}
return false;
}
//--------------------------------------------------------------------------
/**
* <p>
*
* \param t
* \param paramValues
*/
double PTheory::Func(register double t, const vector<double>& paramValues, const vector<double>& funcValues) const
{
if (fMul) {
if (fAdd) { // fMul != 0 && fAdd != 0
switch (fType) {
case THEORY_ASYMMETRY:
return Asymmetry(paramValues, funcValues) * fMul->Func(t, paramValues, funcValues) +
fAdd->Func(t, paramValues, funcValues);
break;
case THEORY_SIMPLE_EXP:
return SimpleExp(t, paramValues, funcValues) * fMul->Func(t, paramValues, funcValues) +
fAdd->Func(t, paramValues, funcValues);
break;
case THEORY_GENERAL_EXP:
return GeneralExp(t, paramValues, funcValues) * fMul->Func(t, paramValues, funcValues) +
fAdd->Func(t, paramValues, funcValues);
break;
case THEORY_SIMPLE_GAUSS:
return SimpleGauss(t, paramValues, funcValues) * fMul->Func(t, paramValues, funcValues) +
fAdd->Func(t, paramValues, funcValues);
break;
case THEORY_STATIC_GAUSS_KT:
return StaticGaussKT(t, paramValues, funcValues) * fMul->Func(t, paramValues, funcValues) +
fAdd->Func(t, paramValues, funcValues);
break;
case THEORY_STATIC_KT_TABLE:
return StaticKTTable(t, paramValues, funcValues) * fMul->Func(t, paramValues, funcValues) +
fAdd->Func(t, paramValues, funcValues);
break;
case THEORY_DYNAMIC_KT_TABLE:
return DynamicKTTable(t, paramValues, funcValues) * fMul->Func(t, paramValues, funcValues) +
fAdd->Func(t, paramValues, funcValues);
break;
case THEORY_COMBI_LGKT:
return CombiLGKT(t, paramValues, funcValues) * fMul->Func(t, paramValues, funcValues) +
fAdd->Func(t, paramValues, funcValues);
break;
case THEORY_SPIN_GLASS:
return SpinGlass(t, paramValues, funcValues) * fMul->Func(t, paramValues, funcValues) +
fAdd->Func(t, paramValues, funcValues);
break;
case THEORY_RANDOM_ANISOTROPIC_HYPERFINE:
return RandomAnisotropicHyperfine(t, paramValues, funcValues) * fMul->Func(t, paramValues, funcValues) +
fAdd->Func(t, paramValues, funcValues);
break;
case THEORY_ABRAGAM:
return Abragam(t, paramValues, funcValues) * fMul->Func(t, paramValues, funcValues) +
fAdd->Func(t, paramValues, funcValues);
break;
case THEORY_INTERNAL_FIELD:
return InternalField(t, paramValues, funcValues) * fMul->Func(t, paramValues, funcValues) +
fAdd->Func(t, paramValues, funcValues);
break;
case THEORY_TF_COS:
return TFCos(t, paramValues, funcValues) * fMul->Func(t, paramValues, funcValues) +
fAdd->Func(t, paramValues, funcValues);
break;
case THEORY_BESSEL:
return Bessel(t, paramValues, funcValues) * fMul->Func(t, paramValues, funcValues) +
fAdd->Func(t, paramValues, funcValues);
break;
case THEORY_INTERNAL_BESSEL:
return InternalBessel(t, paramValues, funcValues) * fMul->Func(t, paramValues, funcValues) +
fAdd->Func(t, paramValues, funcValues);
break;
default:
cout << endl << "**PANIC ERROR**: PTheory::Func: You never should have reached this line?!?! (" << fType << ")";
cout << endl;
exit(0);
}
} else { // fMul !=0 && fAdd == 0
switch (fType) {
case THEORY_ASYMMETRY:
return Asymmetry(paramValues, funcValues) * fMul->Func(t, paramValues, funcValues);
break;
case THEORY_SIMPLE_EXP:
return SimpleExp(t, paramValues, funcValues) * fMul->Func(t, paramValues, funcValues);
break;
case THEORY_GENERAL_EXP:
return GeneralExp(t, paramValues, funcValues) * fMul->Func(t, paramValues, funcValues);
break;
case THEORY_SIMPLE_GAUSS:
return SimpleGauss(t, paramValues, funcValues) * fMul->Func(t, paramValues, funcValues);
break;
case THEORY_STATIC_GAUSS_KT:
return StaticGaussKT(t, paramValues, funcValues) * fMul->Func(t, paramValues, funcValues);
break;
case THEORY_STATIC_KT_TABLE:
return StaticKTTable(t, paramValues, funcValues) * fMul->Func(t, paramValues, funcValues);
break;
case THEORY_DYNAMIC_KT_TABLE:
return DynamicKTTable(t, paramValues, funcValues) * fMul->Func(t, paramValues, funcValues);
break;
case THEORY_COMBI_LGKT:
return CombiLGKT(t, paramValues, funcValues) * fMul->Func(t, paramValues, funcValues);
break;
case THEORY_SPIN_GLASS:
return SpinGlass(t, paramValues, funcValues) * fMul->Func(t, paramValues, funcValues);
break;
case THEORY_RANDOM_ANISOTROPIC_HYPERFINE:
return RandomAnisotropicHyperfine(t, paramValues, funcValues) * fMul->Func(t, paramValues, funcValues);
break;
case THEORY_ABRAGAM:
return Abragam(t, paramValues, funcValues) * fMul->Func(t, paramValues, funcValues);
break;
case THEORY_INTERNAL_FIELD:
return InternalField(t, paramValues, funcValues) * fMul->Func(t, paramValues, funcValues);
break;
case THEORY_TF_COS:
return TFCos(t, paramValues, funcValues) * fMul->Func(t, paramValues, funcValues);
break;
case THEORY_BESSEL:
return Bessel(t, paramValues, funcValues) * fMul->Func(t, paramValues, funcValues);
break;
case THEORY_INTERNAL_BESSEL:
return InternalBessel(t, paramValues, funcValues) * fMul->Func(t, paramValues, funcValues);
break;
default:
cout << endl << "**PANIC ERROR**: PTheory::Func: You never should have reached this line?!?! (" << fType << ")";
cout << endl;
exit(0);
}
}
} else { // fMul == 0 && fAdd != 0
if (fAdd) {
switch (fType) {
case THEORY_ASYMMETRY:
return Asymmetry(paramValues, funcValues) + fAdd->Func(t, paramValues, funcValues);
break;
case THEORY_SIMPLE_EXP:
return SimpleExp(t, paramValues, funcValues) + fAdd->Func(t, paramValues, funcValues);
break;
case THEORY_GENERAL_EXP:
return GeneralExp(t, paramValues, funcValues) + fAdd->Func(t, paramValues, funcValues);
break;
case THEORY_SIMPLE_GAUSS:
return SimpleGauss(t, paramValues, funcValues) + fAdd->Func(t, paramValues, funcValues);
break;
case THEORY_STATIC_GAUSS_KT:
return StaticGaussKT(t, paramValues, funcValues) + fAdd->Func(t, paramValues, funcValues);
break;
case THEORY_STATIC_KT_TABLE:
return StaticKTTable(t, paramValues, funcValues) + fAdd->Func(t, paramValues, funcValues);
break;
case THEORY_DYNAMIC_KT_TABLE:
return DynamicKTTable(t, paramValues, funcValues) + fAdd->Func(t, paramValues, funcValues);
break;
case THEORY_COMBI_LGKT:
return CombiLGKT(t, paramValues, funcValues) + fAdd->Func(t, paramValues, funcValues);
break;
case THEORY_SPIN_GLASS:
return SpinGlass(t, paramValues, funcValues) + fAdd->Func(t, paramValues, funcValues);
break;
case THEORY_RANDOM_ANISOTROPIC_HYPERFINE:
return RandomAnisotropicHyperfine(t, paramValues, funcValues) + fAdd->Func(t, paramValues, funcValues);
break;
case THEORY_ABRAGAM:
return Abragam(t, paramValues, funcValues) + fAdd->Func(t, paramValues, funcValues);
break;
case THEORY_INTERNAL_FIELD:
return InternalField(t, paramValues, funcValues) + fAdd->Func(t, paramValues, funcValues);
break;
case THEORY_TF_COS:
return TFCos(t, paramValues, funcValues) + fAdd->Func(t, paramValues, funcValues);
break;
case THEORY_BESSEL:
return Bessel(t, paramValues, funcValues) + fAdd->Func(t, paramValues, funcValues);
break;
case THEORY_INTERNAL_BESSEL:
return InternalBessel(t, paramValues, funcValues) + fAdd->Func(t, paramValues, funcValues);
break;
default:
cout << endl << "**PANIC ERROR**: PTheory::Func: You never should have reached this line?!?! (" << fType << ")";
cout << endl;
exit(0);
}
} else { // fMul == 0 && fAdd == 0
switch (fType) {
case THEORY_ASYMMETRY:
return Asymmetry(paramValues, funcValues);
break;
case THEORY_SIMPLE_EXP:
return SimpleExp(t, paramValues, funcValues);
break;
case THEORY_GENERAL_EXP:
return GeneralExp(t, paramValues, funcValues);
break;
case THEORY_SIMPLE_GAUSS:
return SimpleGauss(t, paramValues, funcValues);
break;
case THEORY_STATIC_GAUSS_KT:
return StaticGaussKT(t, paramValues, funcValues);
break;
case THEORY_STATIC_KT_TABLE:
return StaticKTTable(t, paramValues, funcValues);
break;
case THEORY_DYNAMIC_KT_TABLE:
return DynamicKTTable(t, paramValues, funcValues);
break;
case THEORY_COMBI_LGKT:
return CombiLGKT(t, paramValues, funcValues);
break;
case THEORY_SPIN_GLASS:
return SpinGlass(t, paramValues, funcValues);
break;
case THEORY_RANDOM_ANISOTROPIC_HYPERFINE:
return RandomAnisotropicHyperfine(t, paramValues, funcValues);
break;
case THEORY_ABRAGAM:
return Abragam(t, paramValues, funcValues);
break;
case THEORY_INTERNAL_FIELD:
return InternalField(t, paramValues, funcValues);
break;
case THEORY_TF_COS:
return TFCos(t, paramValues, funcValues);
break;
case THEORY_BESSEL:
return Bessel(t, paramValues, funcValues);
break;
case THEORY_INTERNAL_BESSEL:
return InternalBessel(t, paramValues, funcValues);
break;
default:
cout << endl << "**PANIC ERROR**: PTheory::Func: You never should have reached this line?!?! (" << fType << ")";
cout << endl;
exit(0);
}
}
}
return 0.0;
}
//--------------------------------------------------------------------------
/**
* <p>
*
* \param name
*/
unsigned int PTheory::SearchDataBase(TString name)
{
unsigned int idx = THEORY_UNDEFINED;
for (unsigned int i=0; i<THEORY_MAX; i++) {
if (!name.CompareTo(fgTheoDataBase[i].fName, TString::kIgnoreCase) ||
!name.CompareTo(fgTheoDataBase[i].fAbbrev, TString::kIgnoreCase)) {
idx = fgTheoDataBase[i].fType;
fType = idx;
fNoOfParam = fgTheoDataBase[i].fNoOfParam;
}
}
return idx;
}
//--------------------------------------------------------------------------
// MakeCleanAndTidyTheoryBlock private
//--------------------------------------------------------------------------
/**
* <p>
*
* \param fullTheoryBlock
*/
void PTheory::MakeCleanAndTidyTheoryBlock(PMsrLines *fullTheoryBlock)
{
PMsrLineStructure *line;
TString str, tidy;
char substr[256];
TObjArray *tokens = 0;
TObjString *ostr;
unsigned int idx = THEORY_UNDEFINED;
for (unsigned int i=1; i<fullTheoryBlock->size(); i++) {
// get the line to be prettyfied
line = &(*fullTheoryBlock)[i];
// copy line content to str in order to remove comments
str = line->fLine.Copy();
// tokenize line
tokens = str.Tokenize(" ");
// make a handable string out of the asymmetry token
ostr = dynamic_cast<TObjString*>(tokens->At(0));
str = ostr->GetString();
// check if the line is just a '+'; if so nothing to be done
if (str.Contains("+"))
continue;
// search the theory function
for (unsigned int j=0; j<THEORY_MAX; j++) {
if (!str.CompareTo(fgTheoDataBase[j].fName, TString::kIgnoreCase) ||
!str.CompareTo(fgTheoDataBase[j].fAbbrev, TString::kIgnoreCase)) {
idx = fgTheoDataBase[j].fType;
}
}
// check if theory is indeed defined. This should not be necessay at this point but ...
if (idx == (unsigned int)THEORY_UNDEFINED)
continue;
// check that there enough tokens. This should not be necessay at this point but ...
if ((unsigned int)tokens->GetEntries() < fgTheoDataBase[idx].fNoOfParam + 1)
continue;
// make tidy string
sprintf(substr, "%-10s", fgTheoDataBase[idx].fName.Data());
tidy = TString(substr);
for (unsigned j=1; j<fgTheoDataBase[idx].fNoOfParam+1; j++) {
ostr = dynamic_cast<TObjString*>(tokens->At(j));
str = ostr->GetString();
sprintf(substr, "%6s", str.Data());
tidy += TString(substr);
}
if (fgTheoDataBase[idx].fComment.Length() != 0) {
unsigned int size = tidy.Length();
for (unsigned int k=0; k<35-size; k++)
tidy += TString(" ");
tidy += fgTheoDataBase[idx].fComment;
}
// write tidy string back into theory block
(*fullTheoryBlock)[i].fLine = tidy;
}
// clean up
if (tokens) {
delete tokens;
tokens = 0;
}
}
//--------------------------------------------------------------------------
/**
* <p> Asymmetry
* \f[ = A \f]
*
* <p> Every theory-function handles its parameters the following way: It holds
* an array fParamNo which is holding the parameter/map/function number. The numbering
* is as such: par1, par2, ..., parX1, internalPar1, internalParX2, map1, ..., mapX3,
* fun1, ..., funX4, where X1 is the number of parameters, X2 the number of internal
* parameters, i.e. parameters listed in the runs, X3 the number of maps, and X4 the
* number of used functions.
*
* \param paramValues is an array of parameter values [par1, par2, ..., parX1,
* internalPar1, ..., internalParX2, map1, ..., mapX3, fun1, ..., funX4]
*/
double PTheory::Asymmetry(const vector<double>& paramValues, const vector<double>& funcValues) const
{
double asym;
// check if FUNCTIONS are used
if (fParamNo[0] < MSR_PARAM_FUN_OFFSET) { // parameter or resolved map
asym = paramValues[fParamNo[0]];
} else {
asym = funcValues[fParamNo[0]-MSR_PARAM_FUN_OFFSET];
}
return asym;
}
//--------------------------------------------------------------------------
/**
* <p> Simple exponential
* \f[ = \exp\left(-\lambda t\right) \f].
*
* <p> For details concerning fParamNo and paramValues see PTheory::Asymmetry and
* PTheory::PTheory.
*
* \param t time in \f$(\mu\mathrm{s})\f$
* \param paramValues parameter values, here only one, namely the depolarization
* rate \f$\lambda\f$ in \f$(1/\mu\mathrm{s})\f$
*/
double PTheory::SimpleExp(register double t, const vector<double>& paramValues, const vector<double>& funcValues) const
{
double lambda;
// check if FUNCTIONS are used
if (fParamNo[0] < MSR_PARAM_FUN_OFFSET) { // parameter or resolved map
lambda = paramValues[fParamNo[0]];
} else { // function
lambda = funcValues[fParamNo[0]-MSR_PARAM_FUN_OFFSET];
}
return TMath::Exp(-t*lambda);
}
//--------------------------------------------------------------------------
/**
* <p>
*
* \param t time in \f$(\mu\mathrm{s})\f$
* \param paramValues
*/
double PTheory::GeneralExp(register double t, const vector<double>& paramValues, const vector<double>& funcValues) const
{
double val[2];
// check if FUNCTIONS are used
for (unsigned int i=0; i<2; i++) {
if (fParamNo[i] < MSR_PARAM_FUN_OFFSET) { // parameter or resolved map
val[i] = paramValues[fParamNo[i]];
} else { // function
val[i] = funcValues[fParamNo[i]-MSR_PARAM_FUN_OFFSET];
}
}
return TMath::Exp(-TMath::Power(t*val[0], val[1]));
}
//--------------------------------------------------------------------------
/**
* <p>
*
* \param t time in \f$(\mu\mathrm{s})\f$
* \param paramValues
*/
double PTheory::SimpleGauss(register double t, const vector<double>& paramValues, const vector<double>& funcValues) const
{
double sigma;
// check if FUNCTIONS are used
if (fParamNo[0] < MSR_PARAM_FUN_OFFSET) { // parameter or resolved map
sigma = paramValues[fParamNo[0]];
} else { // function
sigma = funcValues[fParamNo[0]-MSR_PARAM_FUN_OFFSET];
}
return TMath::Exp(-0.5*TMath::Power(t*sigma, 2.0));
}
//--------------------------------------------------------------------------
/**
* <p>
*
* \param t time in \f$(\mu\mathrm{s})\f$
* \param paramValues
*/
double PTheory::StaticGaussKT(register double t, const vector<double>& paramValues, const vector<double>& funcValues) const
{
double sigma;
// check if FUNCTIONS are used
if (fParamNo[0] < MSR_PARAM_FUN_OFFSET) { // parameter or resolved map
sigma = paramValues[fParamNo[0]];
} else { // function
sigma = funcValues[fParamNo[0]-MSR_PARAM_FUN_OFFSET];
}
double sigma_t_2 = t*t*sigma*sigma;
return 0.333333333333333 * (1.0 + 2.0*(1.0 - sigma_t_2)*TMath::Exp(-0.5*sigma_t_2));
}
//--------------------------------------------------------------------------
/**
* <p>
*
* \param t time in \f$(\mu\mathrm{s})\f$
* \param paramValues
*/
double PTheory::StaticKTTable(register double t, const vector<double>& paramValues, const vector<double>& funcValues) const
{
return 0.0;
}
//--------------------------------------------------------------------------
/**
* <p>
*
* \param t time in \f$(\mu\mathrm{s})\f$
* \param paramValues
*/
double PTheory::DynamicKTTable(register double t, const vector<double>& paramValues, const vector<double>& funcValues) const
{
return 0.0;
}
//--------------------------------------------------------------------------
/**
* <p>
*
* \param t time in \f$(\mu\mathrm{s})\f$
* \param paramValues
*/
double PTheory::CombiLGKT(register double t, const vector<double>& paramValues, const vector<double>& funcValues) const
{
double val[2];
// check if FUNCTIONS are used
for (unsigned int i=0; i<2; i++) {
if (fParamNo[i] < MSR_PARAM_FUN_OFFSET) { // parameter or resolved map
val[i] = paramValues[fParamNo[i]];
} else { // function
val[i] = funcValues[fParamNo[i]-MSR_PARAM_FUN_OFFSET];
}
}
double lambdaL_t = t*val[0];
double lambdaG_t_2 = t*t*val[1]*val[1];
return 0.333333333333333 *
(1.0 + 2.0*(1.0-lambdaL_t-lambdaG_t_2)*TMath::Exp(-(lambdaL_t+0.5*lambdaG_t_2)));
}
//--------------------------------------------------------------------------
/**
* <p>
*
* \param t time in \f$(\mu\mathrm{s})\f$
* \param paramValues
*/
double PTheory::SpinGlass(register double t, const vector<double>& paramValues, const vector<double>& funcValues) const
{
if (paramValues[fParamNo[0]] == 0.0)
return 1.0;
double val[3];
// check if FUNCTIONS are used
for (unsigned int i=0; i<3; i++) {
if (fParamNo[i] < MSR_PARAM_FUN_OFFSET) { // parameter or resolved map
val[i] = paramValues[fParamNo[i]];
} else { // function
val[i] = funcValues[fParamNo[i]-MSR_PARAM_FUN_OFFSET];
}
}
double lambda_2 = val[0]*val[0];
double lambda_t_2_q = t*t*lambda_2*val[2];
double rate_2 = 4.0*lambda_2*(1.0-val[2])*t/val[1];
double rateL = TMath::Sqrt(rate_2);
double rateT = TMath::Sqrt(rate_2+lambda_t_2_q);
return 0.333333333333333*(TMath::Exp(-rateL) + 2.0*(1.0-lambda_t_2_q/rateT)*TMath::Exp(-rateT));
}
//--------------------------------------------------------------------------
/**
* <p>Where does this come from ??? please give a reference
*
* \param t time in \f$(\mu\mathrm{s})\f$
* \param paramValues
*/
double PTheory::RandomAnisotropicHyperfine(register double t, const vector<double>& paramValues, const vector<double>& funcValues) const
{
double val[2];
// check if FUNCTIONS are used
for (unsigned int i=0; i<2; i++) {
if (fParamNo[i] < MSR_PARAM_FUN_OFFSET) { // parameter or resolved map
val[i] = paramValues[fParamNo[i]];
} else { // function
val[i] = funcValues[fParamNo[i]-MSR_PARAM_FUN_OFFSET];
}
}
double nu_t = t*val[0];
double lambda_t = t*val[1];
return 0.166666666666667*(1.0-0.5*nu_t)*TMath::Exp(-0.5*nu_t) +
0.333333333333333*(1.0-0.25*nu_t)*TMath::Exp(-0.25*(nu_t+2.44949*lambda_t));
}
//--------------------------------------------------------------------------
/**
* <p>
*
* \param t time in \f$(\mu\mathrm{s})\f$
* \param paramValues
*/
double PTheory::Abragam(register double t, const vector<double>& paramValues, const vector<double>& funcValues) const
{
double val[2];
// check if FUNCTIONS are used
for (unsigned int i=0; i<2; i++) {
if (fParamNo[i] < MSR_PARAM_FUN_OFFSET) { // parameter or resolved map
val[i] = paramValues[fParamNo[i]];
} else { // function
val[i] = funcValues[fParamNo[i]-MSR_PARAM_FUN_OFFSET];
}
}
double gamma_t = t*val[1];
return TMath::Exp(-TMath::Power(val[0]/val[1],2.0)*
(TMath::Exp(-gamma_t)-1.0-gamma_t));
}
//--------------------------------------------------------------------------
/**
* <p>
*
* \param t time in \f$(\mu\mathrm{s})\f$
* \param paramValues
*/
double PTheory::InternalField(register double t, const vector<double>& paramValues, const vector<double>& funcValues) const
{
double val[4];
// check if FUNCTIONS are used
for (unsigned int i=0; i<4; i++) {
if (fParamNo[i] < MSR_PARAM_FUN_OFFSET) { // parameter or resolved map
val[i] = paramValues[fParamNo[i]];
} else { // function
val[i] = funcValues[fParamNo[i]-MSR_PARAM_FUN_OFFSET];
}
}
return 0.666666666666667*
TMath::Cos(DEG_TO_RAD*val[0])+TWO_PI*val[1]*
TMath::Exp(-val[2]*t) +
0.333333333333333*TMath::Exp(-val[3]*t);
}
//--------------------------------------------------------------------------
/**
* <p>
*
* \param t time in \f$(\mu\mathrm{s})\f$
* \param paramValues
*/
double PTheory::TFCos(register double t, const vector<double>& paramValues, const vector<double>& funcValues) const
{
double val[2];
// check if FUNCTIONS are used
for (unsigned int i=0; i<2; i++) {
if (fParamNo[i] < MSR_PARAM_FUN_OFFSET) { // parameter or resolved map
val[i] = paramValues[fParamNo[i]];
} else { // function
val[i] = funcValues[fParamNo[i]-MSR_PARAM_FUN_OFFSET];
}
}
return TMath::Cos(DEG_TO_RAD*val[0]+TWO_PI*val[1]*t);
}
//--------------------------------------------------------------------------
/**
* <p>
*
* \param t time in \f$(\mu\mathrm{s})\f$
* \param paramValues
*/
double PTheory::Bessel(register double t, const vector<double>& paramValues, const vector<double>& funcValues) const
{
double val[2];
// check if FUNCTIONS are used
for (unsigned int i=0; i<2; i++) {
if (fParamNo[i] < MSR_PARAM_FUN_OFFSET) { // parameter or resolved map
val[i] = paramValues[fParamNo[i]];
} else { // function
val[i] = funcValues[fParamNo[i]-MSR_PARAM_FUN_OFFSET];
}
}
return TMath::BesselJ0(DEG_TO_RAD*val[0]+TWO_PI*val[1]*t);
}
//--------------------------------------------------------------------------
/**
* <p>
*
* \param t time in \f$(\mu\mathrm{s})\f$
* \param paramValues
*/
double PTheory::InternalBessel(register double t, const vector<double>& paramValues, const vector<double>& funcValues) const
{
double val[4];
// check if FUNCTIONS are used
for (unsigned int i=0; i<4; i++) {
if (fParamNo[i] < MSR_PARAM_FUN_OFFSET) { // parameter or resolved map
val[i] = paramValues[fParamNo[i]];
} else { // function
val[i] = funcValues[fParamNo[i]-MSR_PARAM_FUN_OFFSET];
}
}
return 0.666666666666667*
TMath::BesselJ0(DEG_TO_RAD*val[0]+TWO_PI*val[1])*
TMath::Exp(-val[2]*t) +
0.333333333333333*TMath::Exp(-val[3]*t);
}