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

18
src/.kdbgrc.musrfit Executable file
View File

@ -0,0 +1,18 @@
[Breakpoint 0]
Enabled=true
File=musrfit.cpp
Line=464
Temporary=false
[General]
DebuggerCmdStr=
DriverName=GDB
FileVersion=1
OptionsSelected=
ProgramArgs=
TTYLevel=7
WorkingDirectory=
[Memory]
ColumnWidths=80,0
NumExprs=0

66
src/ToDo.txt Normal file
View File

@ -0,0 +1,66 @@
2007/11/28
---------------------
short term:
---------------------
* dump data and theory after fit (ascii/root): **DONE** for now
done for ascii/root asymmetry && single histo: all the rest is missing
* migrate all typedef's and defines -> PMusr.h **DONE**
* Since rootcint cannot handle the spirit include files I will try to remove all the
root dictionary related stuff since almost for sure, nobody will use the classes
from the cint interpreter level 2007/12/27 **DONE**
* begin with the implementation of the FUNCTIONS block
using the spirit parser framework **DONE**
* 2007/12/30: implement functions in PTheory **DONE** 08-01-02
* 2008/01/02: nice function block output needed. **DONE** 08-01-02
* write a little standalone program which is converting the old msr-files to the new ones. **DONE** 08-01-04
* implement max.likelihood fits
* implement table based theory functions (LF stuff)
---------------------
intermediate term:
---------------------
* start writing docu, i.e. transfering WKM doc from German -> English and
describe new features with examples!
* implement RRF stuff
* implement NonMuSR stuff
* implement access to user-function, i.e. functions not
defined within musrfit, using the ROOT dictionary feature
to look for them and use them.
* think about if it is worth to modifiy wkm in order to read
the new msr-files, so that wkmview can be used for an intermediate
time.
---------------------
long term:
---------------------
* implement ROOT based wkmview, i.e. all the graphical stuff needed
including event handler, etc.
* implement FFT with msr-interface
* switch from qmake to cmake
---------------------
problems:
---------------------
* rootcint cannot handle spirit framework includes, hence FUNCTIONS related stuff cannot be included
into a root dictionary.
---------------------
fixes:
---------------------
* Needed to change some part of the Minuit2 source code, otherwise I got a strange linker error message.
In MnMinos.h the constructors (3 overloaded versions) are defined implicitly. When linking against libPMusr.so
which is using libMinuit2Base.so, I got the error message from the linker that is cannot find the reference
to the second constructor. When transfering the implicit definition from the header file to the cxx, the
problem was gone. Since to fiddle in the Minuit2 source code directly is ugly, I should look for a way to
build libPMusr.so which doesn't have this problem.

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);
}

97
src/include/PFitter.h Normal file
View File

@ -0,0 +1,97 @@
/***************************************************************************
PFitter.h
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. *
***************************************************************************/
#ifndef _PFITTER_H_
#define _PFITTER_H_
#include "Minuit2/MnUserParameters.h"
#include "Minuit2/FunctionMinimum.h"
#include "PMsrHandler.h"
#include "PRunListCollection.h"
#include "PFitterFcn.h"
/*
Will handle all the possible minuit commands and actually do things ...
*/
#define PMN_INTERACTIVE 0
#define PMN_CONTOURS 1
#define PMN_EIGEN 2
#define PMN_HESSE 3
#define PMN_MACHINE_PRECISION 4
#define PMN_MIGRAD 5
#define PMN_MINIMIZE 6
#define PMN_MINOS 7
#define PMN_PLOT 8
#define PMN_SAVE 9
#define PMN_SCAN 10
#define PMN_SIMPLEX 12
#define PMN_STRATEGY 13
#define PMN_USER_COVARIANCE 14
#define PMN_USER_PARAM_STATE 15
#define PMN_PRINT 16
class PFitter
{
public:
PFitter(PMsrHandler *runInfo, PRunListCollection *runListCollection);
virtual ~PFitter();
bool IsValid() { return fIsValid; }
bool DoFit();
private:
bool fIsValid;
bool fUseChi2;
PMsrHandler *fRunInfo;
PMsrParamList fParams; ///< msr-file parameters
PMsrLines fCmdLines; ///< all the Minuit commands from the msr-file
PIntVector fCmdList; ///< command list
PFitterFcn *fFitterFcn;
ROOT::Minuit2::MnUserParameters fMnUserParams; ///< minuit2 input parameter list
ROOT::Minuit2::FunctionMinimum *fFcnMin; ///<
bool CheckCommands();
bool SetParameters();
bool ExecuteMigrad();
bool ExecuteMinimize();
bool ExecuteMinos();
bool ExecuteSave();
bool ExecuteSimplex();
};
#endif // _PFITTER_H_

58
src/include/PFitterFcn.h Normal file
View File

@ -0,0 +1,58 @@
/***************************************************************************
PFitterFcn.h
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. *
***************************************************************************/
#ifndef _PFITTERFCN_H_
#define _PFITTERFCN_H_
#include <vector>
#include "Minuit2/FCNBase.h"
#include "PRunListCollection.h"
class PFitterFcn : public ROOT::Minuit2::FCNBase
{
public:
PFitterFcn(PRunListCollection *runList, bool useChi2);
~PFitterFcn();
double Up() const { return fUp; }
double operator()(const std::vector<double>&) const;
unsigned int GetTotalNoOfFittedBins() { return fRunListCollection->GetTotalNoOfBinsFitted(); }
private:
double fUp;
bool fUseChi2;
PRunListCollection *fRunListCollection;
};
#endif // _PFITTERFCN_H_

114
src/include/PFunction.h Normal file
View File

@ -0,0 +1,114 @@
/***************************************************************************
PFunction.h
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. *
***************************************************************************/
#ifndef _PFUNCTION_H_
#define _PFUNCTION_H_
#include <vector>
#include <boost/spirit/tree/ast.hpp>
using namespace boost::spirit;
#include <TString.h>
#include "PFunctionGrammar.h"
//----------------------------------------------------------------------------
#define OP_ADD 0
#define OP_SUB 1
#define OP_MUL 2
#define OP_DIV 3
#define FUN_COS 0
#define FUN_SIN 1
#define FUN_TAN 2
#define FUN_COSH 3
#define FUN_SINH 4
#define FUN_TANH 5
#define FUN_ACOS 6
#define FUN_ASIN 7
#define FUN_ATAN 8
#define FUN_ACOSH 9
#define FUN_ASINH 10
#define FUN_ATANH 11
#define FUN_LOG 12
#define FUN_LN 13
#define FUN_EXP 14
//----------------------------------------------------------------------------
typedef struct func_tree_node {
int fID; ///< tag showing what tree element this is
int fOperatorTag; ///< tag for '+', '-', '*', '/'
int fFunctionTag; ///< tag got "cos", "sin", ...
int fIvalue; ///< for parameter numbers and maps
double fDvalue; ///< for numbers
vector<func_tree_node> children; ///< holding sub-tree
} PFuncTreeNode;
//----------------------------------------------------------------------------
class PFunction {
public:
PFunction(tree_parse_info<> info);
virtual ~PFunction();
virtual bool IsValid() { return fValid; }
virtual int GetFuncNo() { return fFuncNo; }
virtual bool CheckMapAndParamRange(unsigned int mapSize, unsigned int paramSize);
virtual double Eval(vector<double> param);
virtual void SetMap(vector<int> map) { fMap = map; }
virtual TString* GetFuncString() { return &fFuncString; }
protected:
virtual bool SetFuncNo();
virtual bool FindAndCheckMapAndParamRange(PFuncTreeNode &node, unsigned int mapSize, unsigned int paramSize);
virtual bool GenerateFuncEvalTree();
virtual void FillFuncEvalTree(iter_t const& i, PFuncTreeNode &node);
virtual double EvalNode(PFuncTreeNode &node);
virtual void CleanupFuncEvalTree();
virtual void CleanupNode(PFuncTreeNode &node);
private:
tree_parse_info<> fInfo;
vector<double> fParam;
vector<int> fMap;
PFuncTreeNode fFunc;
bool fValid; ///< flag showing if the function is valid
int fFuncNo; ///< function number, i.e. FUNx with x the function number
virtual void EvalTreeForString(tree_parse_info<> info);
virtual void EvalTreeForStringExpression(iter_t const& i);
TString fFuncString; ///< clear text representation of the function
};
#endif // _PFUNCTION_H_

View File

@ -0,0 +1,142 @@
/***************************************************************************
PFunctionGrammer.h
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. *
***************************************************************************/
#ifndef _PFUNCTIONGRAMMAR_H_
#define _PFUNCTIONGRAMMAR_H_
#include <iostream>
using namespace std;
//#define BOOST_SPIRIT_DEBUG
#include <boost/spirit/core.hpp>
#include <boost/spirit/tree/ast.hpp>
using namespace boost::spirit;
typedef char const* iterator_t;
typedef tree_match<iterator_t> parse_tree_match_t;
typedef parse_tree_match_t::tree_iterator iter_t;
//--------------------------------------------------------------------------
/**
*
*/
struct PFunctionGrammar : public grammar<PFunctionGrammar>
{
static const int realID = 1;
static const int funLabelID = 2;
static const int parameterID = 3;
static const int mapID = 4;
static const int functionID = 5;
static const int factorID = 6;
static const int termID = 7;
static const int expressionID = 8;
static const int assignmentID = 9;
template <typename ScannerT>
struct definition
{
definition(PFunctionGrammar const& /*self*/)
{
// Start grammar definition
real = leaf_node_d[ real_p ];
fun_label = leaf_node_d[ ( lexeme_d[ "FUN" >> +digit_p ] ) ];
parameter = leaf_node_d[ ( lexeme_d[ "PAR" >> +digit_p ] ) ];
map = leaf_node_d[ ( lexeme_d[ "MAP" >> +digit_p ] ) ];
function = str_p("COS") >> ch_p('(') >> expression >> ch_p(')')
| str_p("SIN") >> ch_p('(') >> expression >> ch_p(')')
| str_p("TAN") >> ch_p('(') >> expression >> ch_p(')')
| str_p("COSH") >> ch_p('(') >> expression >> ch_p(')')
| str_p("SINH") >> ch_p('(') >> expression >> ch_p(')')
| str_p("TANH") >> ch_p('(') >> expression >> ch_p(')')
| str_p("ACOS") >> ch_p('(') >> expression >> ch_p(')')
| str_p("ASIN") >> ch_p('(') >> expression >> ch_p(')')
| str_p("ATAN") >> ch_p('(') >> expression >> ch_p(')')
| str_p("ACOSH") >> ch_p('(') >> expression >> ch_p(')')
| str_p("ASINH") >> ch_p('(') >> expression >> ch_p(')')
| str_p("ATANH") >> ch_p('(') >> expression >> ch_p(')')
| str_p("LOG") >> ch_p('(') >> expression >> ch_p(')')
| str_p("LN") >> ch_p('(') >> expression >> ch_p(')')
| str_p("EXP") >> ch_p('(') >> expression >> ch_p(')')
;
factor = real
| parameter
| map
| function
| inner_node_d[ch_p('(') >> expression >> ch_p(')')]
;
term = factor >>
*( (root_node_d[ch_p('*')] >> factor)
| (root_node_d[ch_p('/')] >> factor)
);
expression = term >>
*( (root_node_d[ch_p('+')] >> term)
| (root_node_d[ch_p('-')] >> term)
);
assignment = (fun_label >> ch_p('=') >> expression);
// End grammar definition
// turn on the debugging info.
BOOST_SPIRIT_DEBUG_RULE(real);
BOOST_SPIRIT_DEBUG_RULE(fun_label);
BOOST_SPIRIT_DEBUG_RULE(parameter);
BOOST_SPIRIT_DEBUG_RULE(map);
BOOST_SPIRIT_DEBUG_RULE(function);
BOOST_SPIRIT_DEBUG_RULE(factor);
BOOST_SPIRIT_DEBUG_RULE(term);
BOOST_SPIRIT_DEBUG_RULE(expression);
BOOST_SPIRIT_DEBUG_RULE(assignment);
}
rule<ScannerT, parser_context<>, parser_tag<assignmentID> > assignment;
rule<ScannerT, parser_context<>, parser_tag<expressionID> > expression;
rule<ScannerT, parser_context<>, parser_tag<termID> > term;
rule<ScannerT, parser_context<>, parser_tag<factorID> > factor;
rule<ScannerT, parser_context<>, parser_tag<functionID> > function;
rule<ScannerT, parser_context<>, parser_tag<mapID> > map;
rule<ScannerT, parser_context<>, parser_tag<parameterID> > parameter;
rule<ScannerT, parser_context<>, parser_tag<funLabelID> > fun_label;
rule<ScannerT, parser_context<>, parser_tag<realID> > real;
rule<ScannerT, parser_context<>, parser_tag<assignmentID> > const&
start() const { return assignment; }
};
};
#endif // _PFUNCTIONGRAMMAR_H_

View File

@ -0,0 +1,68 @@
/***************************************************************************
PFunctionHandler.h
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. *
***************************************************************************/
#ifndef _PFUNCTIONHANDLER_H_
#define _PFUNCTIONHANDLER_H_
#include <iostream>
#include <vector>
using namespace std;
#include <TString.h>
#include "PMusr.h"
#include "PFunctionGrammar.h"
#include "PFunction.h"
class PFunctionHandler
{
public:
PFunctionHandler(PMsrLines lines);
virtual ~PFunctionHandler();
virtual bool IsValid() { return fValid; }
virtual bool DoParse();
virtual bool CheckMapAndParamRange(unsigned int mapSize, unsigned int paramSize);
virtual double Eval(int funNo, vector<int> map, vector<double> param);
virtual int GetFuncNo(unsigned int idx);
virtual int GetFuncIndex(int funcNo);
virtual unsigned int GetNoOfFuncs() { return fFuncs.size(); }
virtual TString* GetFuncString(unsigned int idx);
private:
bool fValid;
PMsrLines fLines;
vector<PFunction> fFuncs;
};
#endif // _PFUNCTIONHANDLER_H_

114
src/include/PMsrHandler.h Normal file
View File

@ -0,0 +1,114 @@
/***************************************************************************
PMsrHandler.h
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. *
***************************************************************************/
#ifndef _PMSRHANDLER_H_
#define _PMSRHANDLER_H_
/*
#include <vector>
using namespace std;
*/
#include <TString.h>
#include <TComplex.h>
#include "PMusr.h"
#include "PFunctionHandler.h"
#include "PFunctionGrammar.h"
#include "PFunction.h"
//-------------------------------------------------------------
/**
* <p>
*/
class PMsrHandler
{
public:
PMsrHandler(char *fileName);
virtual ~PMsrHandler();
virtual int ReadMsrFile();
virtual int WriteMsrLogFile();
virtual TString* GetMsrTitle() { return &fTitle; }
virtual PMsrParamList* GetMsrParamList() { return &fParam; }
virtual PMsrLines* GetMsrTheory() { return &fTheory; }
virtual PMsrLines* GetMsrFunctions() { return &fFunctions; }
virtual PMsrRunList* GetMsrRunList() { return &fRuns; }
virtual PMsrLines* GetMsrCommands() { return &fCommands; }
virtual PMsrPlotList* GetMsrPlotList() { return &fPlots; }
virtual PMsrStatisticStructure* GetMsrStatistic() { return &fStatistic; }
virtual unsigned int GetNoOfParams() { return fParam.size(); }
virtual bool SetMsrParamValue(unsigned int i, double value);
virtual bool SetMsrParamStep(unsigned int i, double value);
virtual bool SetMsrParamPosError(unsigned int i, double value);
virtual void SetMsrStatisticMin(double min) { fStatistic.fMin = min; }
virtual void SetMsrStatisticNdf(unsigned int ndf) { fStatistic.fNdf = ndf; }
virtual int GetNoOfFuncs() { return fFuncHandler->GetNoOfFuncs(); }
virtual unsigned int GetFuncNo(int idx) { return fFuncHandler->GetFuncNo(idx); }
virtual unsigned int GetFuncIndex(int funNo) { return fFuncHandler->GetFuncIndex(funNo); }
virtual bool CheckMapAndParamRange(unsigned int mapSize, unsigned int paramSize)
{ return fFuncHandler->CheckMapAndParamRange(mapSize, paramSize); }
virtual double EvalFunc(unsigned int i, vector<int> map, vector<double> param)
{ return fFuncHandler->Eval(i,map,param); }
private:
TString fFileName;
TString fTitle; ///< holds the title string of the msr-file
PMsrParamList fParam; ///< holds a list of the fit parameters
PMsrLines fTheory; ///< holds the theory definition
PMsrLines fFunctions; ///< holds the user defined functions
PMsrRunList fRuns; ///< holds a list of run information
PMsrLines fCommands; ///< holds a list of the minuit commands
PMsrPlotList fPlots; ///< holds a list of the plot input parameters
PMsrStatisticStructure fStatistic; ///< holds the statistic info
int fMsrBlockCounter; ///< used to select the proper msr-block
PFunctionHandler *fFuncHandler; ///< needed to parse functions
virtual bool HandleFitParameterEntry(PMsrLines &line);
virtual bool HandleTheoryEntry(PMsrLines &line);
virtual bool HandleFunctionsEntry(PMsrLines &line);
virtual bool HandleRunEntry(PMsrLines &line);
virtual bool HandleCommandsEntry(PMsrLines &line);
virtual bool HandlePlotEntry(PMsrLines &line);
virtual bool HandleStatisticEntry(PMsrLines &line);
virtual void InitRunParameterStructure(PMsrRunStructure &param);
virtual bool FilterFunMapNumber(TString str, const char *filter, int &no);
};
#endif // _PMSRHANDLER_H_

253
src/include/PMusr.h Normal file
View File

@ -0,0 +1,253 @@
/***************************************************************************
PMusr.h
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. *
***************************************************************************/
#ifndef _PMUSR_H_
#define _PMUSR_H_
#include <vector>
using namespace std;
#include <TComplex.h>
#include <TString.h>
#define PMUSR_SUCCESS 0
#define PMUSR_WRONG_STARTUP_SYNTAX -1
#define PMUSR_MSR_FILE_NOT_FOUND -2
#define PMUSR_MSR_ALLOCATION_ERROR -3
#define PMUSR_MSR_SYNTAX_ERROR -4
#define PMUSR_TOKENIZE_ERROR -5
#define PMUSR_MSR_LOG_FILE_WRITE_ERROR -6
#define PRUN_SINGLE_HISTO 0
#define PRUN_ASYMMETRY 2
#define PRUN_RRF 4
#define PRUN_NON_MUSR 8
// muon life time in (us)
#define PMUON_LIFETIME 2.19705
// accelerator cycles in (us), needed to determine proper background
#define ACCEL_PERIOD_PSI 0.01975
#define ACCEL_PERIOD_TRIUMF 0.04337
#define ACCEL_PERIOD_RAL 0.0
// used to filter post pileup correct data histos from root files
#define POST_PILEUP_HISTO_OFFSET 20
//-------------------------------------------------------------
// msr block header tags
#define MSR_TAG_TITLE 0
#define MSR_TAG_FITPARAMETER 1
#define MSR_TAG_THEORY 2
#define MSR_TAG_FUNCTIONS 3
#define MSR_TAG_RUN 4
#define MSR_TAG_COMMANDS 5
#define MSR_TAG_PLOT 6
#define MSR_TAG_STATISTIC 7
//-------------------------------------------------------------
// msr fit type tags
#define MSR_FITTYPE_SINGLE_HISTO 0
#define MSR_FITTYPE_ASYM 2
#define MSR_FITTYPE_ASYM_RRF 4
#define MSR_FITTYPE_NO_MUSR 8
//-------------------------------------------------------------
// msr plot type tags
#define MSR_PLOT_SINGLE_HISTO 0
#define MSR_PLOT_ASYM 2
#define MSR_PLOT_ASYM_RRF 4
#define MSR_PLOT_NO_MUSR 8
//-------------------------------------------------------------
// map and fun offsets for parameter parsing
#define MSR_PARAM_MAP_OFFSET 1000
#define MSR_PARAM_FUN_OFFSET 2000
//-------------------------------------------------------------
/**
* <p> typedef to make to code more readable.
*/
typedef vector<int> PIntVector;
//------------------------------------------------------------------------
/**
* <p>
*/
typedef vector<double> PDoubleVector;
//-------------------------------------------------------------
/**
* <p> typedef to make to code more readable.
*/
typedef vector<TComplex> PComplexVector;
//------------------------------------------------------------------------------------------
/**
* <p>Predominantly used in PRunBase.
*/
typedef struct {
vector<double> fTime;
vector<double> fValue;
vector<double> fError;
vector<double> fTheory;
} PRunData;
//------------------------------------------------------------------------
/**
* <p>
*/
typedef struct {
TString fRunName; ///< name of the run
TString fRunTitle; ///< run title
TString fSetup; ///< description of the setup of this run
double fField; ///< magnetic field value
double fTemp; ///< temperature during the run
double fTimeResolution; ///< time resolution of the run
vector<unsigned int> fT0s; ///< vector of t0's of a run
vector<PDoubleVector> fDataBin; ///< vector of all histos of a run
} PRawRunData;
//------------------------------------------------------------------------
/**
* <p>
*/
typedef vector<PRawRunData> PRawRunDataList;
//-------------------------------------------------------------
/**
* <p> Helper structure for parsing. Keeps a msr-file line string and the corresponding line number.
*/
typedef struct {
int fLineNo; ///< original line number of the msr-file
TString fLine; ///< msr-file line
} PMsrLineStructure;
//-------------------------------------------------------------
/**
* <p> typedef to make to code more readable: list of msr-file lines.
*/
typedef vector<PMsrLineStructure> PMsrLines;
//-------------------------------------------------------------
/**
* <p> Holds the information of a parameter.
*/
typedef struct {
int fNoOfParams; ///< how many parameters are given
int fNo; ///< parameter number
TString fName; ///< name
double fValue; ///< value
double fStep; ///< step / error / neg_error, depending on the situation
bool fPosErrorPresent; ///< positive error is defined (as a number)
double fPosError; ///< positive error if present
double fLowerBoundary; ///< lower boundary for the fit parameter
double fUpperBoundary; ///< upper boundary for the fit parameter
} PMsrParamStructure;
//-------------------------------------------------------------
/**
* <p> typedef to make to code more readable: vector of fit parameters.
*/
typedef vector<PMsrParamStructure> PMsrParamList;
//-------------------------------------------------------------
/**
* <p> Holds the information of a single plot block
*
*/
typedef struct {
TString fRunName; ///< name of the run file
TString fBeamline; ///< e.g. mue4, mue1, pim3, emu, m15, ... (former: run type)
TString fInstitute; ///< e.g. psi, ral, triumf (former: run format)
TString fFileFormat; ///< e.g. root, nexus, psi-bin, mud
int fFitType; ///< fit type: 0=single histo fit, 2=asymmetry fit, 4=asymmetry in RRF, 8=non muSR
int fAlphaParamNo; ///< alpha
int fBetaParamNo; ///<
int fNormParamNo; ///<
int fBkgFitParamNo; ///<
int fPhaseParamNo; ///<
int fLifetimeParamNo; ///<
bool fLifetimeCorrection; ///<
PIntVector fMap; ///<
int fForwardHistoNo; ///<
int fBackwardHistoNo; ///<
double fBkgFix[2]; ///<
int fBkgRange[4]; ///<
int fDataRange[4]; ///<
int fT0[2]; ///<
double fFitRange[2]; ///<
int fPacking; ///<
double fRRFFreq; ///< rotating reference frequency
int fRRFPacking; ///< rotating reference packing
int fAlpha2ParamNo; ///<
int fBeta2ParamNo; ///<
int fRightHistoNo; ///<
int fLeftHistoNo; ///<
} PMsrRunStructure;
//-------------------------------------------------------------
/**
* <p> typedef to make to code more readable: list of runs with its parameters.
*/
typedef vector<PMsrRunStructure> PMsrRunList;
//-------------------------------------------------------------
/**
* <p> Holds the information of a single plot block
*/
typedef struct {
int fPlotType; ///< plot type
PComplexVector fRuns; ///< list of runs to be plotted
double fTmin; ///< time minimum
double fTmax; ///< time maximum
double fYmin; ///< asymmetry/counts minimum
double fYmax; ///< asymmetry/counts maximum
} PMsrPlotStructure;
//-------------------------------------------------------------
/**
* <p> typedef to make to code more readable: list of plots.
*/
typedef vector<PMsrPlotStructure> PMsrPlotList;
//-------------------------------------------------------------
/**
* <p>
*/
typedef struct {
PMsrLines fStatLines;
bool fChisq; ///< flag telling if min = chi2 or min = max.likelyhood
double fMin; ///< chi2 or max. likelyhood
unsigned int fNdf; ///< number of degrees of freedom
} PMsrStatisticStructure;
#endif // _PMUSR_H_

View File

@ -0,0 +1,69 @@
/***************************************************************************
PRunAsymmetry.h
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. *
***************************************************************************/
#ifndef _PRUNASYMMETRY_H_
#define _PRUNASYMMETRY_H_
#include "PRunBase.h"
class PRunAsymmetry : public PRunBase
{
public:
PRunAsymmetry();
PRunAsymmetry(PMsrHandler *msrInfo, PRunDataHandler *rawData, unsigned int runNo);
virtual ~PRunAsymmetry();
virtual double CalcChiSquare(const std::vector<double>& par);
virtual double CalcMaxLikelihood(const std::vector<double>& par);
virtual void CalcTheory();
virtual unsigned int GetNoOfFitBins() { return fNoOfFitBins; }
protected:
virtual bool PrepareData();
private:
unsigned int fAlphaBetaTag; ///< 1-> alpha = beta = 1; 2-> alpha != 1, beta = 1; 3-> alpha = 1, beta != 1; 4-> alpha != 1, beta != 1
double fFitStartTime;
double fFitStopTime;
unsigned int fNoOfFitBins;
vector<double> fForward; ///< forward histo data
vector<double> fForwardErr; ///< forward histo errors
vector<double> fBackward; ///< backward histo data
vector<double> fBackwardErr; ///< backward histo errors
bool SubtractFixBkg();
bool SubtractEstimatedBkg();
};
#endif // _PRUNASYMMETRY_H_

97
src/include/PRunBase.h Normal file
View File

@ -0,0 +1,97 @@
/***************************************************************************
PRunBase.h
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. *
***************************************************************************/
#ifndef _PRUNBASE_H_
#define _PRUNBASE_H_
#include <vector>
using namespace std;
#include <TString.h>
#include "PMusr.h"
#include "PMsrHandler.h"
#include "PRunDataHandler.h"
#include "PTheory.h"
//#include "PFunctions.h"
//------------------------------------------------------------------------------------------
/**
* brauche ich eine base class um zwischen den verschiedenen run-modi unterscheiden zu können?
* Ich meine:
* - single histogram
* - asymmetry
* - RRF
* - non muSR
*
* --> JA
*
* PTheory and PFunctions werden direkt für jeden run generiert, da man dann maps und functions
* direkt für den spezifischen run umsetzen kann (da man eliminiert alle maps und functions). Dies
* garantiert effiziente theory-Aufrufe da diese in chisq/maxlikelyhood x-fach aufgerufen werden.
*/
class PRunBase
{
public:
PRunBase();
PRunBase(PMsrHandler *msrInfo, PRunDataHandler *rawData, unsigned int runNo);
virtual ~PRunBase();
virtual double CalcChiSquare(const vector<double>& par) = 0; // pure virtual, i.e. needs to be implemented by the deriving class!!
virtual double CalcMaxLikelihood(const vector<double>& par) = 0; // pure virtual, i.e. needs to be implemented by the deriving class!!
virtual void CalcTheory() = 0; // pure virtual, i.e. needs to be implemented by the deriving class!!
virtual PRunData* GetData() { return &fData; }
virtual void CleanUp();
virtual bool IsValid() { return fValid; }
protected:
bool fValid;
unsigned int fRunNo; ///< number of the run within the msr file
PMsrHandler *fMsrInfo; ///< msr-file handler
PMsrRunStructure *fRunInfo; ///< run info used to filter out needed infos for the run
PRunDataHandler *fRawData; ///< holds the raw run data
vector<int> fParamNo; ///< vector of parameter numbers for the specifc run
PRunData fData; ///< data to be fitted
double fTimeResolution; ///< time resolution
vector<int> fT0s; ///< all t0's of a run! The derived classes will handle it
virtual bool PrepareData() = 0; // pure virtual, i.e. needs to be implemented by the deriving class!!
vector<double> fFuncValues; ///< is keeping the values of the functions from the FUNCTIONS block
PTheory *fTheory; ///< theory needed to calculate chi-square
};
#endif // _PRUNBASE_H_

View File

@ -0,0 +1,76 @@
/***************************************************************************
PRunDataHandler.h
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. *
***************************************************************************/
#ifndef _PRUNDATAHANDLER_H_
#define _PRUNDATAHANDLER_H_
#include <vector>
using namespace std;
#include <TString.h>
#include "PMusr.h"
#include "PMsrHandler.h"
class PRunDataHandler
{
public:
PRunDataHandler(PMsrHandler *msrInfo);
virtual ~PRunDataHandler();
virtual bool IsAllDataAvailable() { return fAllDataAvailable; }
virtual PRawRunData* GetRunData(TString runName);
private:
PMsrHandler *fMsrInfo;
bool fAllDataAvailable; ///< flag indicating if all data sets could be read
TString fRunName; ///< current run name
TString fRunPathName; ///< current path file name
PRawRunDataList fData; ///< keeping all the raw data
virtual bool ReadFile();
virtual bool FileAlreadyRead(PMsrRunStructure &runInfo);
virtual bool FileExistsCheck(PMsrRunStructure &runInfo);
virtual bool ReadRootFile();
virtual bool ReadNexusFile();
virtual bool ReadNemuFile();
virtual bool ReadPsiBinFile();
virtual bool ReadMudFile();
virtual bool ReadAsciiFile();
virtual bool StripWhitespace(TString &str);
virtual bool IsWhitespace(const char *str);
virtual double ToDouble(TString &str, bool &ok);
virtual int ToInt(TString &str, bool &ok);
};
#endif // _PRUNDATAHANDLER_H_

View File

@ -0,0 +1,86 @@
/***************************************************************************
PRunListCollection.h
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. *
***************************************************************************/
#ifndef _PRUNLISTCOLLECTION_H_
#define _PRUNLISTCOLLECTION_H_
#include <vector>
using namespace std;
#include "PMusr.h"
#include "PMsrHandler.h"
#include "PRunDataHandler.h"
#include "PRunSingleHisto.h"
#include "PRunAsymmetry.h"
#include "PRunRRF.h"
#include "PRunNonMusr.h"
class PRunListCollection
{
public:
PRunListCollection(PMsrHandler *msrInfo, PRunDataHandler *data);
virtual ~PRunListCollection();
virtual bool Add(int runNo);
virtual double GetSingleHistoChisq(const std::vector<double>& par);
virtual double GetAsymmetryChisq(const std::vector<double>& par);
virtual double GetRRFChisq(const std::vector<double>& par);
virtual double GetNonMusrChisq(const std::vector<double>& par);
virtual double GetSingleHistoMaximumLikelihood(const std::vector<double>& par);
virtual double GetAsymmetryMaximumLikelihood(const std::vector<double>& par);
virtual double GetRRFMaximumLikelihood(const std::vector<double>& par);
virtual double GetNonMusrMaximumLikelihood(const std::vector<double>& par);
virtual unsigned int GetTotalNoOfBinsFitted();
virtual unsigned int GetNoOfSingleHisto() { return fRunSingleHistoList.size(); }
virtual unsigned int GetNoOfAsymmetry() { return fRunAsymmetryList.size(); }
virtual unsigned int GetNoOfRRF() { return fRunRRFList.size(); }
virtual unsigned int GetNoOfNonMusr() { return fRunNonMusrList.size(); }
virtual PRunData* GetSingleHisto(unsigned int index);
virtual PRunData* GetAsymmetry(unsigned int index);
virtual PRunData* GetRRF(unsigned int index);
virtual PRunData* GetNonMusr(unsigned int index);
private:
PMsrHandler *fMsrInfo; ///< keeps all msr file info
PRunDataHandler *fData; ///< handles all raw data
vector<PRunSingleHisto*> fRunSingleHistoList;
vector<PRunAsymmetry*> fRunAsymmetryList;
vector<PRunRRF*> fRunRRFList;
vector<PRunNonMusr*> fRunNonMusrList;
};
#endif // _PRUNLISTCOLLECTION_H_

59
src/include/PRunNonMusr.h Normal file
View File

@ -0,0 +1,59 @@
/***************************************************************************
PRunNonMusr.h
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. *
***************************************************************************/
#ifndef _PRUNNONMUSR_H_
#define _PRUNNONMUSR_H_
#include "PRunBase.h"
class PRunNonMusr : public PRunBase
{
public:
PRunNonMusr();
PRunNonMusr(PMsrHandler *msrInfo, PRunDataHandler *rawData, unsigned int runNo);
virtual ~PRunNonMusr();
virtual double CalcChiSquare(const std::vector<double>& par);
virtual double CalcMaxLikelihood(const std::vector<double>& par);
virtual void CalcTheory();
virtual unsigned int GetNoOfFitBins() { return fNoOfFitBins; }
protected:
virtual bool PrepareData();
private:
double fFitStartTime;
double fFitStopTime;
unsigned int fNoOfFitBins;
};
#endif // _PRUNNONMUSR_H_

59
src/include/PRunRRF.h Normal file
View File

@ -0,0 +1,59 @@
/***************************************************************************
PRunRRF.h
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. *
***************************************************************************/
#ifndef _PRUNRRF_H_
#define _PRUNRRF_H_
#include "PRunBase.h"
class PRunRRF : public PRunBase
{
public:
PRunRRF();
PRunRRF(PMsrHandler *msrInfo, PRunDataHandler *rawData, unsigned int runNo);
virtual ~PRunRRF();
virtual double CalcChiSquare(const std::vector<double>& par);
virtual double CalcMaxLikelihood(const std::vector<double>& par);
virtual void CalcTheory();
virtual unsigned int GetNoOfFitBins() { return fNoOfFitBins; }
protected:
virtual bool PrepareData();
private:
double fFitStartTime;
double fFitStopTime;
unsigned int fNoOfFitBins;
};
#endif // _PRUNRRF_H_

View File

@ -0,0 +1,59 @@
/***************************************************************************
PRunSingleHisto.h
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. *
***************************************************************************/
#ifndef _PRUNSINGLEHISTO_H_
#define _PRUNSINGLEHISTO_H_
#include "PRunBase.h"
class PRunSingleHisto : public PRunBase
{
public:
PRunSingleHisto();
PRunSingleHisto(PMsrHandler *msrInfo, PRunDataHandler *rawData, unsigned int runNo);
virtual ~PRunSingleHisto();
virtual double CalcChiSquare(const std::vector<double>& par);
virtual double CalcMaxLikelihood(const std::vector<double>& par);
virtual void CalcTheory();
virtual unsigned int GetNoOfFitBins() { return fNoOfFitBins; }
protected:
virtual bool PrepareData();
private:
double fFitStartTime;
double fFitStopTime;
unsigned int fNoOfFitBins;
};
#endif // _PRUNSINGLEHISTO_H_

View File

@ -0,0 +1,46 @@
/***************************************************************************
PStartupHandler.h
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. *
***************************************************************************/
#ifndef _PSTARTUPHANDLER_H_
#define _PSTARTUPHANDLER_H_
#include <TSAXParser.h>
#include <TString.h>
class PStartupHandler : public TSAXParser
{
public:
PStartupHandler();
virtual ~PStartupHandler();
};
#endif // _PSTARTUPHANDLER_H_

202
src/include/PTheory.h Normal file
View File

@ -0,0 +1,202 @@
/***************************************************************************
PTheory.h
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. *
***************************************************************************/
#ifndef _PTHEORY_H_
#define _PTHEORY_H_
#include <vector>
#include <TString.h>
#include "PMsrHandler.h"
// --------------------------------------------------------
// function handling tags
// --------------------------------------------------------
// function tags
#define THEORY_UNDEFINED -1
#define THEORY_ASYMMETRY 0
#define THEORY_SIMPLE_EXP 1
#define THEORY_GENERAL_EXP 2
#define THEORY_SIMPLE_GAUSS 3
#define THEORY_STATIC_GAUSS_KT 4
#define THEORY_STATIC_KT_TABLE 5
#define THEORY_DYNAMIC_KT_TABLE 6
#define THEORY_COMBI_LGKT 7
#define THEORY_SPIN_GLASS 8
#define THEORY_RANDOM_ANISOTROPIC_HYPERFINE 9
#define THEORY_ABRAGAM 10
#define THEORY_INTERNAL_FIELD 11
#define THEORY_TF_COS 12
#define THEORY_BESSEL 13
#define THEORY_INTERNAL_BESSEL 14
#define THEORY_USER 15
// function parameter tags, i.e. how many parameters has a specific function
#define THEORY_PARAM_ASYMMETRY 1 // asymetry
#define THEORY_PARAM_SIMPLE_EXP 1 // damping
#define THEORY_PARAM_GENERAL_EXP 2 // damping, exponents
#define THEORY_PARAM_SIMPLE_GAUSS 1 // damping
#define THEORY_PARAM_STATIC_GAUSS_KT 1 // damping
#define THEORY_PARAM_STATIC_KT_TABLE 2 // frequency, damping
#define THEORY_PARAM_DYNAMIC_KT_TABLE 3 // frequency, damping, hop-rate
#define THEORY_PARAM_COMBI_LGKT 2 // Lorentz rate, Gauss rate
#define THEORY_PARAM_SPIN_GLASS 3 // rate, hop-rate, order parameter
#define THEORY_PARAM_RANDOM_ANISOTROPIC_HYPERFINE 2 // frequency, rate
#define THEORY_PARAM_ABRAGAM 2 // rate, hop-rate
#define THEORY_PARAM_INTERNAL_FIELD 4 // phase, frequency, TF damping, damping
#define THEORY_PARAM_TF_COS 2 // phase, frequency
#define THEORY_PARAM_BESSEL 2 // phase, frequency
#define THEORY_PARAM_INTERNAL_BESSEL 5 // fraction, phase, frequency, TF damping, damping
// number of available user functions
#define THEORY_MAX 15
// deg -> rad factor
#define DEG_TO_RAD 0.0174532925199432955
// 2 pi
#define TWO_PI 6.28318530717958623
class PTheory;
//--------------------------------------------------------------------------------------
/**
* <p>Structure holding the infos of a the available internally defined functions.
*/
typedef struct theo_data_base {
unsigned int fType; ///< function tag
unsigned int fNoOfParam; ///< number of parameters for this function
bool fTable; ///< table flag, indicating if the function is generate from a table
TString fName; ///< name of the function as written into the msr-file
TString fAbbrev; ///< abbreviation of the function name
TString fComment; ///< comment added in the msr-file theory block to help the used
} PTheoDataBase;
//--------------------------------------------------------------------------------------
/*!
* <p> Holds the functions available for the user.
*/
static PTheoDataBase fgTheoDataBase[THEORY_MAX] = {
{THEORY_ASYMMETRY, THEORY_PARAM_ASYMMETRY, false,
"asymmetry", "a", ""},
{THEORY_SIMPLE_EXP, THEORY_PARAM_SIMPLE_EXP, false,
"simplExpo", "se", "(rate)"},
{THEORY_GENERAL_EXP, THEORY_PARAM_GENERAL_EXP, false,
"generExpo", "ge", "(rate exponent)"},
{THEORY_SIMPLE_GAUSS, THEORY_PARAM_SIMPLE_GAUSS, false,
"simpleGss", "sg", "(rate)"},
{THEORY_STATIC_GAUSS_KT, THEORY_PARAM_STATIC_GAUSS_KT, false,
"statGssKt", "stg", "(rate)"},
{THEORY_STATIC_KT_TABLE, THEORY_PARAM_STATIC_KT_TABLE, true,
"statKTTab", "sktt", "(frequency damping table)"},
{THEORY_DYNAMIC_KT_TABLE, THEORY_PARAM_DYNAMIC_KT_TABLE, true,
"dynmKTTab", "dktt", "(frequency damping hopprate table)"},
{THEORY_COMBI_LGKT, THEORY_PARAM_COMBI_LGKT, false,
"combiLGKT", "lgkt", "(LorentzRate GaussRate)"},
{THEORY_SPIN_GLASS, THEORY_PARAM_SPIN_GLASS, false,
"spinGlass", "spg", "(rate hopprate order)"},
{THEORY_RANDOM_ANISOTROPIC_HYPERFINE, THEORY_PARAM_RANDOM_ANISOTROPIC_HYPERFINE, false,
"rdAnisoHf", "rahf", "(frequency rate)"},
{THEORY_ABRAGAM, THEORY_PARAM_ABRAGAM, false,
"abragam", "ab", "(rate hopprate)"},
{THEORY_INTERNAL_FIELD, THEORY_PARAM_INTERNAL_FIELD, false,
"internFld", "if", "(phase frequency Trate Lrate)"},
{THEORY_TF_COS, THEORY_PARAM_TF_COS, false,
"TFieldCos", "tf", "(phase frequency)"},
{THEORY_BESSEL, THEORY_PARAM_BESSEL, false,
"bessel", "b", "(phase frequency)"},
{THEORY_INTERNAL_BESSEL, THEORY_PARAM_INTERNAL_BESSEL, false,
"internBsl", "ib", "(phase frequency Trate Lrate)"}};
//--------------------------------------------------------------------------------------
/**
* <p>
*/
class PTheory
{
public:
PTheory(PMsrHandler *msrInfo, unsigned int runNo, const bool hasParent = false);
virtual ~PTheory();
virtual bool IsValid();
virtual double Func(register double t, const vector<double>& paramValues, const vector<double>& funcValues) const;
private:
virtual unsigned int SearchDataBase(TString name);
virtual void MakeCleanAndTidyTheoryBlock(PMsrLines* fullTheoryBlock);
virtual double Asymmetry(const vector<double>& paramValues, const vector<double>& funcValues) const;
virtual double SimpleExp(register double t, const vector<double>& paramValues, const vector<double>& funcValues) const;
virtual double GeneralExp(register double t, const vector<double>& paramValues, const vector<double>& funcValues) const;
virtual double SimpleGauss(register double t, const vector<double>& paramValues, const vector<double>& funcValues) const;
virtual double StaticGaussKT(register double t, const vector<double>& paramValues, const vector<double>& funcValues) const;
virtual double StaticKTTable(register double t, const vector<double>& paramValues, const vector<double>& funcValues) const;
virtual double DynamicKTTable(register double t, const vector<double>& paramValues, const vector<double>& funcValues) const;
virtual double CombiLGKT(register double t, const vector<double>& paramValues, const vector<double>& funcValues) const;
virtual double SpinGlass(register double t, const vector<double>& paramValues, const vector<double>& funcValues) const;
virtual double RandomAnisotropicHyperfine(register double t, const vector<double>& paramValues, const vector<double>& funcValues) const;
virtual double Abragam(register double t, const vector<double>& paramValues, const vector<double>& funcValues) const;
virtual double InternalField(register double t, const vector<double>& paramValues, const vector<double>& funcValues) const;
virtual double TFCos(register double t, const vector<double>& paramValues, const vector<double>& funcValues) const;
virtual double Bessel(register double t, const vector<double>& paramValues, const vector<double>& funcValues) const;
virtual double InternalBessel(register double t, const vector<double>& paramValues, const vector<double>& funcValues) const;
// variables
bool fValid;
unsigned int fType;
vector<unsigned int> fParamNo; ///< holds the parameter numbers for the theory (including maps and functions, see constructor desciption)
unsigned int fNoOfParam;
// PTable *fTable;
PTheory *fAdd, *fMul;
// unsigned int fTotalNoOfMsrParam;
// TString fUserFun;
// TString fUserFunPreParsed;
PMsrHandler *fMsrInfo;
};
#endif // _PTHEORY_H_

247
src/msr2msr.cpp Normal file
View File

@ -0,0 +1,247 @@
/***************************************************************************
msr2msr.cpp
Author: Andreas Suter
e-mail: andreas.suter@psi.ch
$Id$
***************************************************************************/
/***************************************************************************
* Copyright (C) 2007 by Andreas Suter *
* andreas.suter@psi.ch *
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* *
* This program is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU General Public License for more details. *
* *
* You should have received a copy of the GNU General Public License *
* along with this program; if not, write to the *
* Free Software Foundation, Inc., *
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
***************************************************************************/
#include <iostream>
#include <fstream>
using namespace std;
#include <cctype>
#include <cstring>
#include <cstdlib>
#include <TString.h>
#include <TObjArray.h>
#include <TObjString.h>
//-------------------------------------------------------------
// msr block header tags
#define MSR_TAG_TITLE 0
#define MSR_TAG_FITPARAMETER 1
#define MSR_TAG_THEORY 2
#define MSR_TAG_FUNCTIONS 3
#define MSR_TAG_RUN 4
#define MSR_TAG_COMMANDS 5
#define MSR_TAG_PLOT 6
#define MSR_TAG_STATISTIC 7
#define MSR_TAG_NO_BLOCK 8
//--------------------------------------------------------------------------
void msr2msr_syntax()
{
cout << endl << "usage: msr2msr <msr-file-in> <msr-file-out> | [--help]";
cout << endl << " <msr-file-in> : input msr-file";
cout << endl << " <msr-file-out>: converted msr-output-file";
cout << endl << " if the <msr-file-in> is already in the 2008 format";
cout << endl << " the output file will be identical to the input file.";
cout << endl << endl;
}
//--------------------------------------------------------------------------
bool msr2msr_run(char *str)
{
TString run(str);
TString line(str);
TObjArray *tokens;
TObjString *ostr[2];
// for filtering
run.ToUpper();
// tokenize run
tokens = line.Tokenize(" ");
if (tokens->GetEntries() < 4) {
cout << endl << "**ERROR**: Something is wrong with the RUN block header:";
cout << endl << " >> " << str;
cout << endl << " >> no <msr-file-out> is created";
cout << endl;
return false;
}
if (run.Contains("NEMU")) {
ostr[0] = dynamic_cast<TObjString*>(tokens->At(1)); // file name
sprintf(str, "RUN %s MUE4 PSI NEMU (name beamline institute data-file-format)", ostr[0]->GetString().Data());
} else if (run.Contains("PSI")) {
ostr[0] = dynamic_cast<TObjString*>(tokens->At(1)); // file name
ostr[1] = dynamic_cast<TObjString*>(tokens->At(1)); // beamline
sprintf(str, "RUN %s %s PSI PSI-BIN (name beamline institute data-file-format)",
ostr[0]->GetString().Data(), ostr[1]->GetString().Data());
} else if (run.Contains("TRIUMF")) {
ostr[0] = dynamic_cast<TObjString*>(tokens->At(1)); // file name
ostr[1] = dynamic_cast<TObjString*>(tokens->At(1)); // beamline
sprintf(str, "RUN %s %s TRIUMF MUD (name beamline institute data-file-format)",
ostr[0]->GetString().Data(), ostr[1]->GetString().Data());
} else if (run.Contains("RAL")) {
ostr[0] = dynamic_cast<TObjString*>(tokens->At(1)); // file name
ostr[1] = dynamic_cast<TObjString*>(tokens->At(1)); // beamline
sprintf(str, "RUN %s %s RAL NEXUS (name beamline institute data-file-format)",
ostr[0]->GetString().Data(), ostr[1]->GetString().Data());
}
cout << endl;
// clean up
if (tokens) {
delete tokens;
tokens = 0;
}
return true;
}
//--------------------------------------------------------------------------
void msr2msr_param(char *str, int &tag)
{
// check for comment header which needs to be replaced
if (strstr(str, "Nr.")) {
strcpy(str, "# No Name Value Step Pos_Error Boundaries");
return;
}
// handle parameter line
TString line(str);
TObjArray *tokens;
TObjString *ostr[6];
char sstr[256];
char spaces[256];
tokens = line.Tokenize(" ");
unsigned int noTokens = tokens->GetEntries();
if (noTokens == 4) {
strcat(str, " none");
} else if (noTokens == 6) {
for (unsigned int i=0; i<6; i++)
ostr[i] = dynamic_cast<TObjString*>(tokens->At(i));
// number
sprintf(sstr, "%10s", ostr[0]->GetString().Data());
// name
strcat(sstr, " ");
strcat(sstr, ostr[1]->GetString().Data());
memset(spaces, 0, sizeof(spaces));
memset(spaces, ' ', 12-strlen(ostr[1]->GetString().Data()));
strcat(sstr, spaces);
// value
strcat(sstr, ostr[2]->GetString().Data());
memset(spaces, 0, sizeof(spaces));
memset(spaces, ' ', 10-strlen(ostr[2]->GetString().Data()));
strcat(sstr, spaces);
// step
strcat(sstr, ostr[3]->GetString().Data());
memset(spaces, 0, sizeof(spaces));
memset(spaces, ' ', 12-strlen(ostr[3]->GetString().Data()));
strcat(sstr, spaces);
// pos. error
strcat(sstr, "none ");
// lower boundary
strcat(sstr, ostr[4]->GetString().Data());
memset(spaces, 0, sizeof(spaces));
memset(spaces, ' ', 8-strlen(ostr[4]->GetString().Data()));
strcat(sstr, spaces);
// upper boundary
strcat(sstr, ostr[5]->GetString().Data());
strcpy(str, sstr);
}
// clean up
if (tokens) {
delete tokens;
tokens = 0;
}
// check if the end of the parameter block is reached
unsigned int i;
for (i=0; i<strlen(str); i++) {
if (!isblank(str[i]) || !iscntrl(str[i]))
break;
}
if (i == strlen(str)) // end reached
tag = MSR_TAG_NO_BLOCK;
}
//--------------------------------------------------------------------------
int main(int argc, char *argv[])
{
// check the number of arguments
if (argc != 3) {
msr2msr_syntax();
return 0;
}
// open input msr-file
ifstream fin;
fin.open(argv[1], iostream::in);
if (!fin.is_open()) {
cout << endl << "**ERROR**: Couldn't open input msr-file " << argv[1];
cout << endl << " Will quit." << endl;
return 0;
}
// open input msr-file
ofstream fout;
fout.open(argv[2], iostream::out);
if (!fout.is_open()) {
cout << endl << "**ERROR**: Couldn't open output msr-file " << argv[2];
cout << endl << " Will quit." << endl;
fin.close();
return 0;
}
// read input file and write output file
char str[256];
int tag;
bool success = true;
while (!fin.eof() && success) {
fin.getline(str, sizeof(str));
if (strstr(str, "FITPARAMETER")) {
tag = MSR_TAG_FITPARAMETER;
} else if (strstr(str, "RUN")) { // analyze and change header
success = msr2msr_run(str);
}
if (tag == MSR_TAG_FITPARAMETER) {
msr2msr_param(str, tag);
}
fout << str << endl;
}
// close files
fout.close();
fin.close();
// check if conversion seems to be OK
if (!success) {
sprintf(str, "rm -rf %s", argv[2]);
system(str);
}
// clean up
return 1;
}

22
src/msr2msr.pro Normal file
View File

@ -0,0 +1,22 @@
#------------------------------------------------------
# msr2msr.pro
# qmake file for msr2msr
#
# Andreas Suter, 2008/01/03
#
# $Id$
#
#------------------------------------------------------
MAKEFILE = Makefile.msr2msr
CONFIG += warn_on debug
SOURCES = msr2msr.cpp \
INCLUDEPATH += $$(ROOTSYS)/include
ROOTLIBS = $(shell $(ROOTSYS)/bin/root-config --libs)
unix:LIBS += $${ROOTLIBS}
TARGET=msr2msr

615
src/musrfit.cpp Normal file
View File

@ -0,0 +1,615 @@
/***************************************************************************
musrfit.cpp
Author: Andreas Suter
e-mail: andreas.suter@psi.ch
$Id$
***************************************************************************/
/***************************************************************************
* Copyright (C) 2007 by Andreas Suter *
* andreas.suter@psi.ch *
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* *
* This program is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU General Public License for more details. *
* *
* You should have received a copy of the GNU General Public License *
* along with this program; if not, write to the *
* Free Software Foundation, Inc., *
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
***************************************************************************/
#include <iostream>
#include <fstream>
using namespace std;
#include "TString.h"
#include "TFile.h"
#include "TCanvas.h"
#include "TH1.h"
#include "PMusr.h"
#include "PStartupHandler.h"
#include "PMsrHandler.h"
#include "PRunDataHandler.h"
#include "PRunListCollection.h"
#include "PFitter.h"
//--------------------------------------------------------------------------
/**
* <p>
*
*/
void musrfit_syntax()
{
cout << endl << "usage: musrfit [<msr-file> [--debug] | [--dump <type>]] | --version | --help";
cout << endl << " <msr-file>: msr input file";
cout << endl << " 'msrfit <msf-file>' will execute msrfit";
cout << endl << " 'msrfit' or 'msrfit --help' will show this help";
cout << endl << " 'msrfit --version' will print the msrfit version";
cout << endl << " --debug is used to print additional infos";
cout << endl << " --dump <type> is writing a data file with the fit data and the theory";
cout << endl << " <type> can be 'ascii', 'root'";
cout << endl << endl;
}
//--------------------------------------------------------------------------
/**
* <p>
*
* \param msrHandler
*/
void musrfit_debug_info(PMsrHandler* msrHandler)
{
int i;
// print title
cout << endl << "----------";
cout << endl << "title = " << msrHandler->GetMsrTitle()->Data();
// print parameters
cout << endl << "----------";
cout << endl << "parameters";
PMsrParamList::iterator param_it;
for (param_it = msrHandler->GetMsrParamList()->begin(); param_it != msrHandler->GetMsrParamList()->end(); ++param_it) {
cout << endl << param_it->fNo << ": ";
cout << param_it->fName << ", ";
cout << param_it->fValue << ", ";
cout << param_it->fStep << ", ";
switch (param_it->fNoOfParams) {
case 5:
cout << param_it->fPosError;
break;
case 6:
cout << param_it->fLowerBoundary << ", ";
cout << param_it->fUpperBoundary;
break;
case 7:
cout << param_it->fPosError << ", ";
cout << param_it->fLowerBoundary << ", ";
cout << param_it->fUpperBoundary;
break;
default:
break;
}
}
// print theory
cout << endl << "----------";
PMsrLines::iterator theo_it;
theo_it = msrHandler->GetMsrTheory()->begin();
for (; theo_it != msrHandler->GetMsrTheory()->end(); ++theo_it)
cout << endl << theo_it->fLine.Data();
// print functions
// print run
cout << endl << "----------";
cout << endl << "runs";
PMsrRunList::iterator runs_it;
int runNo = 1;
for (runs_it = msrHandler->GetMsrRunList()->begin(); runs_it != msrHandler->GetMsrRunList()->end(); ++runs_it) {
cout << endl << "******";
cout << endl << "run no " << runNo++;
cout << endl << "run (name, beamline, institute, data-file-format): ";
cout << endl << " " << runs_it->fRunName << ", " << runs_it->fBeamline << ", " << runs_it->fInstitute << ", " << runs_it->fFileFormat;
cout << endl << "fittype " << runs_it->fFitType;
cout << endl << "alpha " << runs_it->fAlphaParamNo;
cout << endl << "beta " << runs_it->fBetaParamNo;
cout << endl << "norm " << runs_it->fNormParamNo;
cout << endl << "backgr.fit " << runs_it->fBkgFitParamNo;
cout << endl << "rphase " << runs_it->fPhaseParamNo;
cout << endl << "lifetime " << runs_it->fLifetimeParamNo;
if (runs_it->fLifetimeCorrection)
cout << endl << "lifetimecorrection true";
else
cout << endl << "lifetimecorrection false";
cout << endl << "map ";
for (PIntVector::iterator it = runs_it->fMap.begin(); it != runs_it->fMap.end(); ++it)
cout << *it << ", ";
cout << endl << "forward " << runs_it->fForwardHistoNo;
cout << endl << "backward " << runs_it->fBackwardHistoNo;
cout << endl << "backgr.fix ";
for (int i=0; i<2; i++)
cout << runs_it->fBkgFix[i] << ", ";
cout << endl << "background ";
for (int i=0; i<4; i++)
cout << runs_it->fBkgRange[i] << ", ";
cout << endl << "data ";
for (int i=0; i<4; i++)
cout << runs_it->fDataRange[i] << ", ";
cout << endl << "t0 ";
for (int i=0; i<2; i++)
cout << runs_it->fT0[i] << ", ";
cout << endl << "fit ";
for (int i=0; i<2; i++)
cout << runs_it->fFitRange[i] << ", ";
cout << endl << "packing " << runs_it->fPacking;
cout << endl << "rrffrequency " << runs_it->fRRFFreq;
cout << endl << "rrfpacking " << runs_it->fRRFPacking;
cout << endl << "alpha2 " << runs_it->fAlpha2ParamNo;
cout << endl << "beta2 " << runs_it->fBeta2ParamNo;
cout << endl << "right " << runs_it->fRightHistoNo;
cout << endl << "left " << runs_it->fLeftHistoNo;
}
// print commands
cout << endl << "----------";
cout << endl << "commands";
PMsrLines::iterator commands_it;
commands_it = msrHandler->GetMsrCommands()->begin();
++commands_it; // the first entry is just the COMMANDS block statment
for (; commands_it != msrHandler->GetMsrCommands()->end(); ++commands_it)
cout << endl << commands_it->fLine.Data();
// print plot
cout << endl << "----------";
PMsrPlotList::iterator plot_it;
i = 1;
for (plot_it = msrHandler->GetMsrPlotList()->begin(); plot_it != msrHandler->GetMsrPlotList()->end(); ++plot_it) {
cout << endl << i++ << ". plot " << plot_it->fPlotType;
cout << endl << "runs = ";
PComplexVector::iterator plot_run_it;
for (plot_run_it = plot_it->fRuns.begin(); plot_run_it != plot_it->fRuns.end(); ++plot_run_it) {
switch (plot_it->fPlotType) {
case MSR_PLOT_SINGLE_HISTO:
case MSR_PLOT_ASYM:
case MSR_PLOT_NO_MUSR:
cout << plot_run_it->Re() << ", ";
break;
case MSR_PLOT_ASYM_RRF:
cout << "(" << plot_run_it->Re() << "," << plot_run_it->Im() << "), ";
break;
default:
cout << endl << "??";
break;
}
}
if (plot_it->fTmin == -999.0) {
cout << endl << "range = autorange";
} else {
if (plot_it->fYmin == -999.0) { // only time range given
cout << endl << "range = [ " << plot_it->fTmin << ", " << plot_it->fTmax << "]";
} else {
cout << endl << "range = [ " << plot_it->fTmin << ", " << plot_it->fTmax << ", " << plot_it->fYmin << ", " << plot_it->fYmax << "]";
}
}
}
// print statistic
cout << endl << "----------";
cout << endl << "statistic";
PMsrLines::iterator statistic_it;
statistic_it = msrHandler->GetMsrStatistic()->fStatLines.begin();
++statistic_it; // the first entry is just the STATISTIC block statment
for (; statistic_it != msrHandler->GetMsrStatistic()->fStatLines.end(); ++statistic_it)
cout << endl << statistic_it->fLine.Data();
cout << endl << "----------" << endl;
}
//--------------------------------------------------------------------------
/**
* <p>
*
* \param fln
* \param data
* \param runCounter
*/
void musrfit_write_ascii(TString fln, PRunData *data, int runCounter)
{
// generate dump file name
TString fileName = fln.Copy();
TString count("_");
count += runCounter;
Ssiz_t index = fln.Index(".");
fln.Insert(index, count);
//cout << endl << "fln = " << fln.Data();
ofstream f;
// open dump-file
f.open(fln.Data(), iostream::out);
if (!f.is_open()) {
cout << endl << "Couldn't open dump (" << fln.Data() << ") file for writting, sorry ...";
cout << endl;
return;
}
// dump data
f << "% number of data values = " << data->fTime.size() << endl;
f << "% time (us), value, error, theory" << endl;
for (unsigned int i=0; i<data->fTime.size(); i++) {
f << data->fTime[i] << ", " << data->fValue[i] << ", " << data->fError[i] << ", " << data->fTheory[i] << endl;
}
// close file
f.close();
}
//--------------------------------------------------------------------------
/**
* <p>
*
* \param fileName
*/
void musrfit_dump_ascii(char *fileName, PRunListCollection *runList)
{
TString fln(fileName);
fln.ReplaceAll(".msr", ".dat");
// go through the run list, get the data and dump it in a file
int runCounter = 0;
// single histos
unsigned int size = runList->GetNoOfSingleHisto();
PRunData *data;
if (size > 0) {
for (unsigned int i=0; i<size; i++) {
data = runList->GetSingleHisto(i);
if (data) {
// dump data
musrfit_write_ascii(fln, data, runCounter);
runCounter++;
}
}
}
// asymmetry
size = runList->GetNoOfAsymmetry();
if (size > 0) {
for (unsigned int i=0; i<size; i++) {
data = runList->GetAsymmetry(i);
if (data) {
// dump data
musrfit_write_ascii(fln, data, runCounter);
runCounter++;
}
}
}
// rrf
size = runList->GetNoOfRRF();
if (size > 0) {
for (unsigned int i=0; i<size; i++) {
data = runList->GetRRF(i);
if (data) {
// dump data
musrfit_write_ascii(fln, data, runCounter);
runCounter++;
}
}
}
// nonMusr
size = runList->GetNoOfNonMusr();
if (size > 0) {
for (unsigned int i=0; i<size; i++) {
data = runList->GetNonMusr(i);
if (data) {
// dump data
musrfit_write_ascii(fln, data, runCounter);
runCounter++;
}
}
}
}
//--------------------------------------------------------------------------
/**
* <p>
*
* \param f
* \param fln
* \param data
* \param runCounter
*/
void musrfit_write_root(TFile &f, TString fln, PRunData *data, int runCounter)
{
char name[128];
TString title = fln.Copy();
sprintf(name, "_%d", runCounter);
title.ReplaceAll(".root", name);
sprintf(name, "c%d", runCounter);
TCanvas *c = new TCanvas(name, title.Data(), 10, 10, 800, 600);
// create histos
Double_t diff = data->fTime[1]-data->fTime[0];
Double_t start = -diff/2.0;
Double_t end = data->fTime[data->fTime.size()-1]+diff/2.0;
TH1F *hdata = new TH1F("hdata", "run data", data->fTime.size(), start, end);
TH1F *htheo = new TH1F("htheo", "run theory", data->fTime.size(), start, end);
// fill data
for (unsigned int i=0; i<data->fTime.size(); i++) {
hdata->SetBinContent(i, data->fValue[i]);
hdata->SetBinError(i, data->fError[i]);
htheo->SetBinContent(i, data->fTheory[i]);
}
hdata->SetMarkerStyle(20);
hdata->Draw("*H HIST E1");
htheo->SetLineColor(2);
htheo->SetLineWidth(3);
htheo->Draw("C SAME");
f.WriteTObject(c);
// clean up
if (hdata) {
delete hdata;
hdata = 0;
}
if (htheo) {
delete htheo;
htheo = 0;
}
if (c) {
delete c;
c = 0;
}
}
//--------------------------------------------------------------------------
/**
* <p>
*
* \param fileName
*/
void musrfit_dump_root(char *fileName, PRunListCollection *runList)
{
TString fln(fileName);
fln.ReplaceAll(".msr", ".root");
TFile f(fln.Data(), "recreate");
// go through the run list, get the data and dump it in a file
int runCounter = 0;
// single histos
unsigned int size = runList->GetNoOfSingleHisto();
PRunData *data;
if (size > 0) {
for (unsigned int i=0; i<size; i++) {
data = runList->GetSingleHisto(i);
if (data) {
// dump data
musrfit_write_root(f, fln, data, runCounter);
runCounter++;
}
}
}
// asymmetry
size = runList->GetNoOfAsymmetry();
if (size > 0) {
for (unsigned int i=0; i<size; i++) {
data = runList->GetAsymmetry(i);
if (data) {
// dump data
musrfit_write_root(f, fln, data, runCounter);
runCounter++;
}
}
}
// rrf
size = runList->GetNoOfRRF();
if (size > 0) {
for (unsigned int i=0; i<size; i++) {
data = runList->GetRRF(i);
if (data) {
// dump data
musrfit_write_root(f, fln, data, runCounter);
runCounter++;
}
}
}
// nonMusr
size = runList->GetNoOfNonMusr();
if (size > 0) {
for (unsigned int i=0; i<size; i++) {
data = runList->GetNonMusr(i);
if (data) {
// dump data
musrfit_write_root(f, fln, data, runCounter);
runCounter++;
}
}
}
}
//--------------------------------------------------------------------------
int main(int argc, char *argv[])
{
bool show_syntax = false;
int status;
bool debug = false;
TString dump("");
// check syntax
if (argc == 2) {
if (!strcmp(argv[1], "--version")) {
cout << endl << "msrfit version: $Id$";
cout << endl << endl;
return PMUSR_SUCCESS;
} else if (!strcmp(argv[1], "--help")) {
show_syntax = true;
} else { // assume file name
// check if filename has extension msr
if (!strstr(argv[1], ".msr")) {
cout << endl << "ERROR: " << argv[1] << " is not a msr-file!" << endl;
show_syntax = true;
} else {
show_syntax = false;
}
}
} else if (argc == 3) {
if (!strcmp(argv[2], "--debug"))
debug = true;
else
show_syntax = true;
} else if (argc == 4) {
if (!strcmp(argv[2], "--dump"))
dump = TString(argv[3]);
else
show_syntax = true;
} else {
show_syntax = true;
}
if (show_syntax) {
musrfit_syntax();
return PMUSR_WRONG_STARTUP_SYNTAX;
}
// read startup file
PStartupHandler *startupHandler = new PStartupHandler();
// read msr-file
PMsrHandler *msrHandler = new PMsrHandler(argv[1]);
status = msrHandler->ReadMsrFile();
if (status != PMUSR_SUCCESS) {
switch (status) {
case PMUSR_MSR_FILE_NOT_FOUND:
cout << endl << "couldn't find " << argv[1] << endl << endl;
break;
case PMUSR_MSR_SYNTAX_ERROR:
cout << endl << "syntax error in file " << argv[1] << ", full stop here." << endl << endl;
default:
cout << endl << "unkown error when trying to read the msr-file" << endl << endl;
break;
}
return status;
}
if (debug)
musrfit_debug_info(msrHandler);
// read all the necessary runs (raw data)
PRunDataHandler *dataHandler = new PRunDataHandler(msrHandler);
bool success = dataHandler->IsAllDataAvailable();
if (!success) {
cout << endl << "Couldn't read all data files, will quit ..." << endl;
}
// generate the necessary fit histogramms for the fit
PRunListCollection *runListCollection = 0;
if (success) {
// feed all the necessary histogramms for the fit
runListCollection = new PRunListCollection(msrHandler, dataHandler);
for (unsigned int i=0; i < msrHandler->GetMsrRunList()->size(); i++) {
success = runListCollection->Add(i);
if (!success) {
cout << endl << "Couldn't handle run no " << i << " ";
cout << (*msrHandler->GetMsrRunList())[i].fRunName.Data();
break;
}
}
}
// do fitting
PFitter *fitter = 0;
if (success) {
fitter = new PFitter(msrHandler, runListCollection);
success = fitter->IsValid();
if (success)
fitter->DoFit();
}
// write log file
if (success) {
status = msrHandler->WriteMsrLogFile();
if (status != PMUSR_SUCCESS) {
switch (status) {
case PMUSR_MSR_LOG_FILE_WRITE_ERROR:
cout << endl << "couldn't write mlog-file" << endl << endl;
break;
case PMUSR_TOKENIZE_ERROR:
cout << endl << "couldn't generate mlog-file name" << endl << endl;
break;
default:
cout << endl << "unkown error when trying to write the mlog-file" << endl << endl;
break;
}
}
}
// check if dump is wanted
if (success && !dump.IsNull()) {
cout << endl << "will write dump file ..." << endl;
dump.ToLower();
if (dump.Contains("ascii"))
musrfit_dump_ascii(argv[1], runListCollection);
else if (dump.Contains("root"))
musrfit_dump_root(argv[1], runListCollection);
else
cout << endl << "do not know format " << dump.Data() << ", sorry :-| " << endl;
}
// clean up
if (startupHandler) {
delete startupHandler;
startupHandler = 0;
}
if (msrHandler) {
delete msrHandler;
msrHandler = 0;
}
if (dataHandler) {
delete dataHandler;
dataHandler = 0;
}
if (runListCollection) {
delete runListCollection;
runListCollection = 0;
}
if (fitter) {
delete fitter;
fitter = 0;
}
cout << endl << "done ..." << endl;
return PMUSR_SUCCESS;
}
// end ---------------------------------------------------------------------

25
src/musrfit.pro Normal file
View File

@ -0,0 +1,25 @@
#------------------------------------------------------
# musrfit.pro
# qmake file for musrfit
#
# Andreas Suter, 2007/05/14
#
# $Id$
#
#------------------------------------------------------
MAKEFILE = Makefile.musrfit
CONFIG += warn_on debug
SOURCES = musrfit.cpp \
INCLUDEPATH += $$(ROOTSYS)/include
INCLUDEPATH += ./include
PSILIBS = -lTLemRunHeader -lPMusr
ROOTLIBS = $(shell $(ROOTSYS)/bin/root-config --libs)
unix:LIBS += $${PSILIBS}
unix:LIBS += $${ROOTLIBS}
TARGET=musrfit

View File

@ -0,0 +1,32 @@
#include <fstream>
using namespace std;
int main()
{
ofstream f;
// open mlog-file
f.open("fio_test.txt", iostream::out);
if (!f.is_open()) {
return -1;
}
const int prec=6;
double val = 0.258466548916354835498465;
f.width(9);
f.precision(prec);
f << left << val;
f << " ";
f.width(9);
f.precision(prec);
f << left << val;
f << " ";
f.width(9);
f.precision(prec);
f << left << val;
f.close();
return 0;
}

View File

@ -0,0 +1,17 @@
#------------------------------------------------------
# fio_test.pro
# qmake file for fio_test
#
# Andreas Suter, 2007/05/14
#
# $Id$
#
#------------------------------------------------------
MAKEFILE = Makefile
CONFIG += warn_on debug
SOURCES = fio_test.cpp
TARGET=fio_test

View File

@ -0,0 +1 @@
0.258467 0.258467 0.258467

View File

@ -0,0 +1,84 @@
/***************************************************************************
PGlobalChiSquare.cpp
Author: Andreas Suter
e-mail: andreas.suter@psi.ch
$Id$
***************************************************************************/
/***************************************************************************
* Copyright (C) 2007 by Andreas Suter *
* andreas.suter@psi.ch *
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* *
* This program is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU General Public License for more details. *
* *
* You should have received a copy of the GNU General Public License *
* along with this program; if not, write to the *
* Free Software Foundation, Inc., *
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
***************************************************************************/
#include <math.h>
#include <iostream>
#include "PGlobalChiSquare.h"
namespace ROOT {
namespace Minuit2 {
//--------------------------------------------------------------------------
/**
* <p>
*/
PGlobalChiSquare::PGlobalChiSquare(PRunList &runList)
{
fRunList = runList;
}
//--------------------------------------------------------------------------
/**
* <p>
*/
PGlobalChiSquare::~PGlobalChiSquare()
{
}
//--------------------------------------------------------------------------
/**
* <p>
*
* \param par
*/
double PGlobalChiSquare::operator()(const std::vector<double>& par) const
{
double chi2 = 0.0;
double funcValue;
double diff;
// calculate chi2 for the given model
for (unsigned int i=0; i<fRunList.size(); i++) { // run loop
for (unsigned int j=0; j<fRunList[i].fTime.size(); j++) { // data loop
funcValue = par[i]*exp(-par[2]*fRunList[i].fTime[j]); // par[i] since par[0] = ampl of run 0, etc.
diff = funcValue - fRunList[i].fValue[j];
chi2 += diff*diff/(fRunList[i].fError[j]*fRunList[i].fError[j]);
}
}
return chi2;
}
} // namespace Minuit2
} // namespace ROOT

View File

@ -0,0 +1,62 @@
/***************************************************************************
PGlobalChiSquare.h
Author: Andreas Suter
e-mail: andreas.suter@psi.ch
$Id$
***************************************************************************/
/***************************************************************************
* Copyright (C) 2007 by Andreas Suter *
* andreas.suter@psi.ch *
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* *
* This program is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU General Public License for more details. *
* *
* You should have received a copy of the GNU General Public License *
* along with this program; if not, write to the *
* Free Software Foundation, Inc., *
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
***************************************************************************/
#ifndef _PGLOBALCHISQUARE_H_
#define _PGLOBALCHISQUARE_H_
#include <vector>
#include "Minuit2/FCNBase.h"
#include "mn2test.h"
namespace ROOT {
namespace Minuit2 {
class PGlobalChiSquare : public FCNBase
{
public:
PGlobalChiSquare(PRunList &runList);
~PGlobalChiSquare();
double Up() const { return 1.0; }
double operator()(const std::vector<double>&) const;
private:
PRunList fRunList;
};
} // namespace Minuit2
} // namespace ROOT
#endif // _PGLOBALCHISQUARE_H_

View File

@ -0,0 +1,157 @@
/***************************************************************************
mn2test.cpp
Author: Andreas Suter
e-mail: andreas.suter@psi.ch
$Id$
***************************************************************************/
/***************************************************************************
* Copyright (C) 2007 by Andreas Suter *
* andreas.suter@psi.ch *
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* *
* This program is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU General Public License for more details. *
* *
* You should have received a copy of the GNU General Public License *
* along with this program; if not, write to the *
* Free Software Foundation, Inc., *
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
***************************************************************************/
#include <stdlib.h>
#include <math.h>
#include <iostream>
#include <vector>
#include "Minuit2/FunctionMinimum.h"
#include "Minuit2/MnUserParameters.h"
#include "Minuit2/MnMinimize.h"
#include "Minuit2/MnMinos.h"
#include "PGlobalChiSquare.h"
#include "mn2test.h"
using namespace ROOT::Minuit2;
//----------------------------------------------------------------------------
/**
* <p>generates data for testing
* model = ampl * exp(-lambda * t), where ampl is depending on the run, but
* not lambda
*/
void generateData(PRunList &data)
{
PRun run;
const unsigned int length = 100;
double value;
for (unsigned int i=0; i<2; i++) { // run loop
for (unsigned int j=0; j<length; j++) { // data loop
run.fTime.push_back((double)j/(double)length);
value = (2*i+10)*exp(-1.7*(double)j/(double)length);
value += 2.0*sqrt(value)*((double)random()/(double)RAND_MAX-0.5);
run.fValue.push_back(value);
run.fError.push_back(sqrt(value/4.0));
}
data.push_back(run);
// clean up
run.fTime.clear();
run.fValue.clear();
run.fError.clear();
}
}
//----------------------------------------------------------------------------
int main(int argc, char *argv[])
{
if (argc || argv);
int success = 1;
PRunList runs;
generateData(runs);
unsigned int max = 25;
if (runs[0].fTime.size() < max)
max = runs[0].fTime.size();
for (unsigned int i=0; i<runs.size(); i++) { // run loop
std::cout << std::endl << "run " << i;
for (unsigned int j=0; j<max; j++) { // data loop
std::cout << std::endl << runs[i].fTime[j] << ", " << runs[i].fValue[j] << ", " << runs[i].fError[j];
}
std::cout << std::endl;
}
PGlobalChiSquare chi2(runs); // chi2 object derived from ROOT::Minuit2::FCNBase
// create parameters ---------------------------------
MnUserParameters upar;
// model = ampl_i * exp(-lambda * t), i = run no.
upar.Add("ampl1", 10.0, 1.0); // ampl1
upar.Add("ampl2", 12.0, 1.0); // ampl2
upar.Add("lambda", 0.1, 0.01); // lambda
// create minimizer ---------------------------------
MnMinimize minimize(chi2, upar);
// minimize
FunctionMinimum min = minimize();
if (min.IsValid()) {
std::cout << std::endl << "minimize (MIGRAD/SIMPLEX) found minimum ...";
} else {
std::cout << std::endl << "minimize (MIGRAD/SIMPLEX) failed to find minimum ...";
}
std::cout << std::endl << "Chi2 = " << min.Fval()
<< ", NDF = " << 2*runs[0].fTime.size()-3
<< ", Chi2r = " << min.Fval()/((double)(2*runs[0].fTime.size()-3)) << std::endl;
// make minos analysis
MnMinos minos(chi2, min);
// 1-sigma MINOS errors
std::pair<double, double> e0 = minos(0);
std::pair<double, double> e1 = minos(1);
std::pair<double, double> e2 = minos(2);
// print out parameters
unsigned int i=0;
std::cout << std::endl << "1-sigma minos errors:" << std::endl;
i=0;
std::cout << std::endl << upar.Name(i) << ": "
<< min.UserState().Value(i) << " "
<< e0.first << " "
<< e0.second;
i++;
std::cout << std::endl << upar.Name(i) << ": "
<< min.UserState().Value(i) << " "
<< e1.first << " "
<< e1.second;
i++;
std::cout << std::endl << upar.Name(i) << ": "
<< min.UserState().Value(i) << " "
<< e2.first << " "
<< e2.second;
std::cout << std::endl << std::endl;
// clean up
runs.clear();
return success;
}

View File

@ -0,0 +1,45 @@
/***************************************************************************
mn2test.h
Author: Andreas Suter
e-mail: andreas.suter@psi.ch
$Id$
***************************************************************************/
/***************************************************************************
* Copyright (C) 2007 by Andreas Suter *
* andreas.suter@psi.ch *
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* *
* This program is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU General Public License for more details. *
* *
* You should have received a copy of the GNU General Public License *
* along with this program; if not, write to the *
* Free Software Foundation, Inc., *
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
***************************************************************************/
#ifndef _MN2TEST_H_
#define _MN2TEST_H_
#include <vector>
typedef struct {
std::vector<double> fTime;
std::vector<double> fValue;
std::vector<double> fError;
} PRun;
typedef std::vector<PRun> PRunList;
#endif // _MN2TEST_H_

View File

@ -0,0 +1,26 @@
#------------------------------------------------------
# mn2test.pro
# qmake file for mn2test
#
# Andreas Suter, 2007/10/23
#
# $Id$
#
#------------------------------------------------------
MAKEFILE = Makefile.mn2test
CONFIG += warn_on debug
HEADERS = PGlobalChiSquare.h
SOURCES = mn2test.cpp \
PGlobalChiSquare.cpp
INCLUDEPATH += /usr/local/include
INCLUDEPATH += ./
unix:LIBS += -L/usr/local/lib -lMinuit2Base -lbsd -lm -ldl -lutil
TARGET=mn2test

View File

@ -0,0 +1,22 @@
#include <math.h>
#include <iostream>
using namespace std;
int main()
{
double value;
value = nan("NAN");
if (isnan(value))
cout << endl << "value is not a number";
else
cout << endl << "value is a number";
cout << endl << "value = " << value;
cout << endl << "done ..." << endl;
return 0;
}

View File

@ -0,0 +1,17 @@
#------------------------------------------------------
# nanTest.pro
# qmake file for nanTest
#
# Andreas Suter, 2007/05/14
#
# $Id$
#
#------------------------------------------------------
MAKEFILE = Makefile
CONFIG += warn_on debug
SOURCES = nanTest.cpp
TARGET=nanTest

View File

@ -0,0 +1,110 @@
#include <iostream>
using namespace std;
#include <TROOT.h>
#include <TSystem.h>
#include <TFile.h>
#include <TFolder.h>
#include <TH1F.h>
#include "TLemRunHeader.h"
int main(int argc, char *argv[])
{
if (argc != 2) {
cout << endl;
cout << "SYNTAX: nemuRootFileRead PathFileName";
cout << endl;
return 1;
}
TROOT root("nemuRootFileRead", "nemuRootFileRead", 0);
// get file name
char *str = gSystem->ExpandPathName(argv[1]);
// check that the file name exists
if (gSystem->AccessPathName(str)==true) {
cout << endl << "file " << str << " doesn't exist :-(" << endl;
cout << endl << "will quit now ..." << endl;
return 1;
}
// define file
TFile f(str);
if (f.IsZombie()) {
cout << endl << "couldn't open file " << str << endl;
cout << endl << "will quit now ..." << endl;
return 1;
}
cout << endl << "opened file " << str;
// get RunInfo Folder
TFolder *folder = 0;
f.GetObject("RunInfo", folder);
// check if RunInfo Folder is valid
if (!folder) {
cout << endl << "Couldn't obtain RunInfo folder from ROOT file " << str;
cout << endl << "will quit now ..." << endl;
return 1;
}
// get run header
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 " << str;
cout << endl << "will quit now ..." << endl;
return 1;
}
cout << endl << "Run No : " << runHeader->GetRunNumber();
cout << endl << "Run Title: " << runHeader->GetRunTitle().GetString().Data();
// get histos folder
f.GetObject("histos", folder);
// check if histos Folder is valid
if (!folder) {
cout << endl << "Couldn't obtain histos folder from ROOT file " << str;
cout << endl << "will quit now ..." << endl;
return 1;
}
// get histo hDecay00
TH1F *histo = dynamic_cast<TH1F*>(folder->FindObject("DecayAnaModule/hDecay00"));
// check if histo hDecay00 was found
if (!histo) {
cout << endl << "Couldn't obtain hDecay00 histo from ROOT file " << str;
cout << endl << "will quit now ..." << endl;
return 1;
}
// print out first 10 values of hDecay00 and some other info
cout << endl << "hDecay00: No of Bins: " << histo->GetNbinsX();
int max;
if (max > histo->GetNbinsX())
max = histo->GetNbinsX();
else
max = 10;
cout << endl << "hDecay00: Data:";
for (int i=0; i<max; i++) {
cout << endl << i << ": " << histo->GetBinContent(i+1);
}
if (f.IsOpen())
f.Close();
cout << endl << "closed file .." << endl;
if (str)
delete str;
cout << endl;
return 0;
}

View File

@ -0,0 +1,23 @@
#------------------------------------------------------
# nemuRootFileRead.pro
# qmake file for rootSystemTest
#
# Andreas Suter, 2007/05/14
#
# $Id$
#
#------------------------------------------------------
MAKEFILE = Makefile
CONFIG += warn_on debug
SOURCES = nemuRootFileRead.cpp \
INCLUDEPATH += $$(ROOTSYS)/include
ROOTLIBS = -lCore -lCint -lRIO -lGraf -lGraf3d -lGpad -lHist -lMatrix -lMinuit -lGui
NEMULIBS = -lTLemRunHeader
unix:LIBS += -L$$(ROOTSYS)/lib $${ROOTLIBS} $${NEMULIBS} -lbsd -lm -ldl -lutil
TARGET=nemuRootFileRead

View File

@ -0,0 +1,24 @@
{
gStyle->SetOptStat(000000000);
TCanvas *cov = new TCanvas("cov", "Minuit2 Output Covariance Matrix", 500, 500);
TH2D *f = new TH2D("f", "Minuit2 Output Covariance Matrix", 16, 0.0, 16.0, 16, 0.0, 16.0);
double x, y, z;
for (unsigned int i=0; i<16; i++) {
for (unsigned int j=0; j<16; j++) {
x = (double)i;
y = (double)j;
z = x/16.0-y/16.0+(x-8.0)*(y-8.0)/(8.0*8.0);
f->Fill(x,y,z);
}
}
TFile ff("test.root", "recreate");
cov->Draw();
f->Draw("COLZ");
cov->Write();
ff.Close();
}

View File

@ -0,0 +1,30 @@
{
TFile f("test.root", "recreate");
// make a histo with errors
TH1F *h = new TH1F("h", "histo test", 20, -0.05, 1.05);
TH1F *hc = new TH1F("hc", "curve", 20, -0.05, 1.05);
for (unsigned int i=0; i<20; i++) {
x = (double)i/20.0;
value = TMath::Sqrt(1.5*x+0.1*TMath::Power(x,3.0)-0.4*TMath::Power(x,5.0));
hc->SetBinContent(i, value+0.1*TMath::Sqrt(value)-value*value);
h->SetBinContent(i, value);
h->SetBinError(i, TMath::Power(value, 5.0));
}
TCanvas *c1 = new TCanvas("c1", "my Canvas c1", 10, 10, 800, 600);
h->SetMarkerStyle(20);
h->Draw("*H HIST E1");
hc->SetLineColor(2);
hc->SetLineWidth(3);
hc->Draw("C SAME");
TCanvas *c2 = new TCanvas("c2", "my Canvas c2", 10, 10, 800, 600);
h->SetMarkerStyle(23);
h->Draw("*H HIST E1");
f.WriteTObject(c1);
f.WriteTObject(c2);
}

View File

@ -0,0 +1,105 @@
/*******************************************************************
minuit2test.C
author: Andreas Suter
e-mail: andreas.suter@psi.ch
$Id$
********************************************************************/
#include <iostream>
#include <TF1.h>
#include <TH1.h>
#include <TVirtualFitter.h>
#include <TCanvas.h>
#include <TMath.h>
const double gGammaMu = TMath::TwoPi()*0.01355;
const double gTauMu = 2.19705; // in (us)
TF1 *gFitFcn;
//------------------------------------------------------------------
/**
* <p>Background (flat for the moment)
*
* \param x
* \param par par[0] is the background
*/
Double_t Background(Double_t *x, Double_t *par)
{
return par[0];
}
//------------------------------------------------------------------
/**
* <p>Asymmetry
*
* \param x
* \param par par[0] = asymmetry
* par[1] = lambda
* par[2] = B
* par[3] = phase
*/
Double_t Asymmetry(Double_t *x, Double_t *par)
{
return par[0]*TMath::Exp(-par[1]*x[0])*TMath::Cos(gGammaMu*par[2]*x[0]+par[3]/180.0*TMath::Pi());
}
//------------------------------------------------------------------
/**
* <p>Spectrum
*
* \param x
* \param par
*/
Double_t Spectrum(Double_t *x, Double_t *par)
{
return par[0]*TMath::Exp(-x[0]/gTauMu)*(1.0 + Asymmetry(x,&par[1])) + Background(x,&par[5]);
}
//------------------------------------------------------------------
/**
* <p>minuit2test
*
* \param x
* \param par
*/
void minuit2test()
{
TH1::AddDirectory(kFALSE);
TCanvas *c1 = new TCanvas("c1","Fitting Test",10,10,500,500);
// create a TF1 with the range from 0.0 to 12.0 and 6 parameters
gFitFcn = new TF1("gFitFcn", Spectrum, 0.0, 12.0, 6);
gFitFcn->SetNpx(1200);
// set parameters
gFitFcn->SetParNames("N0", "asym", "lambda", "B", "phase", "Bkg");
gFitFcn->SetParameter(0, 30.0); // N0
// gFitFcn->SetParLimits(0, 0.0, 1.0e6);
gFitFcn->SetParameter(1, 0.11); // asym
// gFitFcn->SetParLimits(1, 0.0, 0.33);
gFitFcn->SetParameter(2, 0.3); // lambda
// gFitFcn->SetParLimits(2, 0.0, 100.0);
gFitFcn->SetParameter(3, 100.0); // B
// gFitFcn->SetParLimits(3, 0.0, 1000.0);
gFitFcn->SetParameter(4, 0.0); // phase
// gFitFcn->SetParLimits(4, -90.0, 90.0);
gFitFcn->SetParameter(5, 5.0); // Bkg
// gFitFcn->SetParLimits(5, 0.0, 1000.0);
cout << endl << "gFitFcn->Integral(0.0, 12.0) = " << gFitFcn->Integral(0.0, 12.0);
cout << endl;
// fill histo
TH1F *histo = new TH1F("histo","Minuit2 Test",1200,0.0,12.0);
histo->FillRandom("gFitFcn", 100*(int)gFitFcn->Integral(0.0, 12.0));
histo->Rebin(5);
histo->Draw();
TVirtualFitter::SetDefaultFitter("Minuit2");
histo->Fit("gFitFcn", "LE"); // L->likleyhood, E->minos
}

View File

@ -0,0 +1,35 @@
#include <iostream>
using namespace std;
#include <TROOT.h>
#include <TSystem.h>
int main(int argc, char *argv[])
{
if (argc != 2) {
cout << endl;
cout << "SYNTAX: rootSystemTest PathFileName";
cout << endl;
return 1;
}
TROOT root("rootSystemTest", "rootSystemTest", 0);
cout << endl;
cout << "Path name: " << argv[1] << endl;
char *str = gSystem->ExpandPathName(argv[1]);
cout << "Path name expanded: " << str << endl;
if (gSystem->AccessPathName(str)==true) {
cout << endl << "file " << str << " doesn't exist :-(" << endl;
} else {
cout << endl << "file " << str << " exists :-)" << endl;
}
cout << "done ..." << endl;
if (str)
delete str;
return 0;
}

View File

@ -0,0 +1,22 @@
#------------------------------------------------------
# rootSystemTest.pro
# qmake file for rootSystemTest
#
# Andreas Suter, 2007/05/14
#
# $Id$
#
#------------------------------------------------------
MAKEFILE = Makefile
CONFIG += warn_on debug
SOURCES = rootSystemTest.cpp \
INCLUDEPATH += $$(ROOTSYS)/include
ROOTLIBS = -lCore -lCint
unix:LIBS += -L$$(ROOTSYS)/lib $${ROOTLIBS} -lbsd -lm -ldl -lutil
TARGET=rootSystemTest

View File

View File

@ -0,0 +1,620 @@
/***************************************************************************
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
* \param param the parameter vector
* \param map the map vector
*/
PFunction::PFunction(tree_parse_info<> info, vector<double> param, vector<int> map)
{
cout << endl << "in PFunction ...";
fInfo = info;
fParam = param;
fMap = map;
// init class variables
fValid = true;
fFuncNo = -1;
// check parameter and map range
if (!CheckParameterAndMapRange()) {
fValid = false;
return;
}
// generate function evaluation tree
if (!GenerateFuncEvalTree()) {
fValid = false;
return;
}
EvaluateTree(info);
cout << endl << "fFuncString: '" << fFuncString << "'";
cout << endl;
}
//--------------------------------------------------------------------------
// Destructor
//--------------------------------------------------------------------------
/**
* <p>
*/
PFunction::~PFunction()
{
// cout << endl << "in ~PFunction ...";
fParam.clear();
fMap.clear();
CleanupFuncEvalTree();
}
//-------------------------------------------------------------
// CheckParameterRange (protected)
//-------------------------------------------------------------
/**
* <p>
*
*/
bool PFunction::CheckParameterAndMapRange()
{
return CheckParameterAndMapInTree(fInfo.trees.begin());
}
//-------------------------------------------------------------
// CheckParameterAndMapInTree (protected)
//-------------------------------------------------------------
/**
* <p> walk through the tree and check if the parameter found
* are within a valid range given by the size of fParam.
*
* \param i
*/
bool PFunction::CheckParameterAndMapInTree(iter_t const& i)
{
bool success = true;
int value;
if (i->value.id() == PFunctionGrammar::funLabelID) {
assert(i->children.size() == 0);
SetFuncNo(i);
} else if (i->value.id() == PFunctionGrammar::parameterID) {
assert(i->children.size() == 0);
string str(i->value.begin(), i->value.end());
cout << endl << "parameterID: value = " << str << endl;
sscanf(str.c_str(), "PAR%d", &value);
//cout << endl << ">> value = " << value << ", fParam.size() = " << fParam.size();
if (value > (int)fParam.size()) { // parameter number found > number of parameters
cout << endl << "**ERROR**: found parameter " << str << " with only " << fParam.size() << " parameters present?!?";
fValid = false;
}
} else if (i->value.id() == PFunctionGrammar::mapID) {
assert(i->children.size() == 0);
string str(i->value.begin(), i->value.end());
cout << endl << "mapID: value = " << str << endl;
sscanf(str.c_str(), "MAP%d", &value);
//cout << endl << ">> value = " << value << ", fParam.size() = " << fParam.size();
if (value > (int)fMap.size()) { // parameter number found > number of parameters
cout << endl << "**ERROR**: found map " << str << " with only " << fMap.size() << " maps present?!?";
fValid = false;
}
} else if (i->value.id() == PFunctionGrammar::functionID) {
cout << endl << "children = " << i->children.size() << endl;
assert(i->children.size() == 4);
// i: 'funcName', '(', 'expression', ')'
success = CheckParameterAndMapInTree(i->children.begin()+2); // thats the real stuff
} else if (i->value.id() == PFunctionGrammar::factorID) {
// i: real | parameter | map | function | expression
assert(i->children.size() == 1);
success = CheckParameterAndMapInTree(i->children.begin());
} else if (i->value.id() == PFunctionGrammar::termID) {
// '*'/'/' i: lhs, rhs
assert(i->children.size() == 2);
success = CheckParameterAndMapInTree(i->children.begin());
success = CheckParameterAndMapInTree(i->children.begin()+1);
} else if (i->value.id() == PFunctionGrammar::expressionID) {
// '+'/'-' i: lhs, rhs
assert(i->children.size() == 2);
success = CheckParameterAndMapInTree(i->children.begin());
success = CheckParameterAndMapInTree(i->children.begin()+1);
} else if (i->value.id() == PFunctionGrammar::assignmentID) {
// i: 'FUNx', '=', 'expression'
assert(i->children.size() == 3);
success = CheckParameterAndMapInTree(i->children.begin()); // FUNx
success = CheckParameterAndMapInTree(i->children.begin()+2); // this is the real stuff
}
return success;
}
//-------------------------------------------------------------
// SetFuncNo (protected)
//-------------------------------------------------------------
/**
* <p>
*
* \param i
*/
bool PFunction::SetFuncNo(iter_t const& i)
{
int funNo = -1;
int status;
bool success = true;
// 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);
}
}
//-------------------------------------------------------------
// Eval (public)
//-------------------------------------------------------------
/**
* <p>
*
*/
double PFunction::Eval()
{
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();
}
}
//-------------------------------------------------------------
// EvaluateTree (protected)
//-------------------------------------------------------------
long PFunction::EvaluateTree(tree_parse_info<> info)
{
return EvalTreeExpression(info.trees.begin());
}
//-------------------------------------------------------------
// EvalTreeExpression (protected)
//-------------------------------------------------------------
long PFunction::EvalTreeExpression(iter_t const& i)
{
static int counter = 0;
static int termOp = 0;
cout << endl << counter <<": in EvalExpression. i->value = '" <<
string(i->value.begin(), i->value.end()) <<
"' i->children.size() = " << i->children.size() << endl;
if (i->value.id() == PFunctionGrammar::realID) {
assert(i->children.size() == 0);
cout << endl << "realID: children = " << i->children.size();
cout << endl << "realID: " << string(i->value.begin(), i->value.end());
cout << endl << "-----";
if (*i->value.begin() == '-')
fFuncString += "(";
fFuncString += string(i->value.begin(), i->value.end());
if (*i->value.begin() == '-')
fFuncString += ")";
} else if (i->value.id() == PFunctionGrammar::funLabelID) {
assert(i->children.size() == 0);
//SetFuncNo(i);
cout << endl << "funLabelID: children = " << i->children.size();
cout << endl << "funLabelID: value = " << string(i->value.begin(), i->value.end());
cout << endl << "-----";
fFuncString += string(i->value.begin(), i->value.end()); // funx
} else if (i->value.id() == PFunctionGrammar::parameterID) {
assert(i->children.size() == 0);
cout << endl << "parameterID: children = " << i->children.size();
cout << endl << "parameterID: value = " << string(i->value.begin(), i->value.end());
cout << endl << "-----";
fFuncString += string(i->value.begin(), i->value.end());
} else if (i->value.id() == PFunctionGrammar::mapID) {
assert(i->children.size() == 0);
cout << endl << "mapID: children = " << i->children.size();
cout << endl << "mapID: value = " << string(i->value.begin(), i->value.end());
cout << endl << "-----";
fFuncString += string(i->value.begin(), i->value.end());
} else if (i->value.id() == PFunctionGrammar::functionID) {
assert(i->children.size() == 4);
cout << endl << "functionID: children = " << i->children.size();
iter_t it = i->children.begin();
cout << endl << "functionID: value = " << string(it->value.begin(), it->value.end());
cout << endl << "-----";
// funcName, '(', expression, ')'
counter++;
fFuncString += string(it->value.begin(), it->value.end());
if (termOp == 0)
fFuncString += "(";
EvalTreeExpression(i->children.begin()+2); // the real stuff
if (termOp == 0)
fFuncString += ")";
counter--;
} else if (i->value.id() == PFunctionGrammar::factorID) {
cout << endl << "factorID: children = " << i->children.size();
counter++;
return EvalTreeExpression(i->children.begin());
counter--;
} else if (i->value.id() == PFunctionGrammar::termID) {
cout << endl << "termID: children = " << i->children.size();
if (*i->value.begin() == '*') {
cout << endl << "termID: '*'";
assert(i->children.size() == 2);
counter++;
termOp++;
EvalTreeExpression(i->children.begin());
fFuncString += " * ";
EvalTreeExpression(i->children.begin()+1);
termOp--;
counter--;
} else if (*i->value.begin() == '/') {
cout << endl << "termID: '/'";
assert(i->children.size() == 2);
counter++;
termOp++;
EvalTreeExpression(i->children.begin());
fFuncString += " / ";
EvalTreeExpression(i->children.begin()+1);
termOp--;
counter--;
} else {
assert(0);
}
} else if (i->value.id() == PFunctionGrammar::expressionID) {
cout << endl << "expressionID: children = " << i->children.size();
if (*i->value.begin() == '+') {
cout << endl << "expressionID: '+'";
assert(i->children.size() == 2);
counter++;
if (termOp > 0)
fFuncString += "(";
EvalTreeExpression(i->children.begin());
fFuncString += " + ";
EvalTreeExpression(i->children.begin()+1);
if (termOp > 0)
fFuncString += ")";
counter--;
} else if (*i->value.begin() == '-') {
cout << endl << "expressionID: '-'";
assert(i->children.size() == 2);
counter++;
if (termOp > 0)
fFuncString += "(";
EvalTreeExpression(i->children.begin());
fFuncString += " - ";
EvalTreeExpression(i->children.begin()+1);
if (termOp > 0)
fFuncString += ")";
counter--;
} else {
assert(0);
}
} else if (i->value.id() == PFunctionGrammar::assignmentID) {
cout << endl << "assignmentID: children = " << i->children.size();
assert(i->children.size() == 3);
counter++;
EvalTreeExpression(i->children.begin());
EvalTreeExpression(i->children.begin()+1); // this is the string "="
EvalTreeExpression(i->children.begin()+2); // this is the real stuff
counter--;
} else if (*i->value.begin() == '=') {
cout << endl << "'=' in assignment";
fFuncString += " = ";
} else {
assert(0);
}
return 0;
}

View File

@ -0,0 +1,111 @@
/***************************************************************************
PFunction.h
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. *
***************************************************************************/
#ifndef _PFUNCTION_H_
#define _PFUNCTION_H_
#include <vector>
#include <string>
#include <boost/spirit/tree/ast.hpp>
using namespace boost::spirit;
#include "PFunctionGrammar.h"
//----------------------------------------------------------------------------
#define OP_ADD 0
#define OP_SUB 1
#define OP_MUL 2
#define OP_DIV 3
#define FUN_COS 0
#define FUN_SIN 1
#define FUN_TAN 2
#define FUN_COSH 3
#define FUN_SINH 4
#define FUN_TANH 5
#define FUN_ACOS 6
#define FUN_ASIN 7
#define FUN_ATAN 8
#define FUN_ACOSH 9
#define FUN_ASINH 10
#define FUN_ATANH 11
#define FUN_LOG 12
#define FUN_LN 13
#define FUN_EXP 14
//----------------------------------------------------------------------------
typedef struct func_tree_node {
int fID; ///< tag showing what tree element this is
int fOperatorTag; ///< tag for '+', '-', '*', '/'
int fFunctionTag; ///< tag got "cos", "sin", ...
int fIvalue; ///< for parameter numbers and maps
double fDvalue; ///< for numbers
vector<func_tree_node> children; ///< holding sub-tree
} PFuncTreeNode;
//----------------------------------------------------------------------------
class PFunction {
public:
PFunction(tree_parse_info<> info, vector<double> param, vector<int> map);
virtual ~PFunction();
virtual bool IsValid() { return fValid; }
virtual int GetFuncNo() { return fFuncNo; }
virtual double Eval();
protected:
virtual bool CheckParameterAndMapRange();
virtual bool CheckParameterAndMapInTree(iter_t const& i);
virtual bool SetFuncNo(iter_t const& i);
virtual bool GenerateFuncEvalTree();
virtual void FillFuncEvalTree(iter_t const& i, PFuncTreeNode &node);
virtual double EvalNode(PFuncTreeNode &node);
virtual void CleanupFuncEvalTree();
virtual void CleanupNode(PFuncTreeNode &node);
virtual long EvaluateTree(tree_parse_info<> info);
virtual long EvalTreeExpression(iter_t const& i);
private:
tree_parse_info<> fInfo;
vector<double> fParam;
vector<int> fMap;
PFuncTreeNode fFunc;
bool fValid; ///< flag showing if the function is valid
int fFuncNo; ///< function number, i.e. FUNx with x the function number
string fFuncString;
};
#endif // _PFUNCTION_H_

View File

@ -0,0 +1,142 @@
/***************************************************************************
PFunctionGrammer.h
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. *
***************************************************************************/
#ifndef _PFUNCTIONGRAMMAR_H_
#define _PFUNCTIONGRAMMAR_H_
#include <iostream>
using namespace std;
//#define BOOST_SPIRIT_DEBUG
#include <boost/spirit/core.hpp>
#include <boost/spirit/tree/ast.hpp>
using namespace boost::spirit;
typedef char const* iterator_t;
typedef tree_match<iterator_t> parse_tree_match_t;
typedef parse_tree_match_t::tree_iterator iter_t;
//--------------------------------------------------------------------------
/**
*
*/
struct PFunctionGrammar : public grammar<PFunctionGrammar>
{
static const int realID = 1;
static const int funLabelID = 2;
static const int parameterID = 3;
static const int mapID = 4;
static const int functionID = 5;
static const int factorID = 6;
static const int termID = 7;
static const int expressionID = 8;
static const int assignmentID = 9;
template <typename ScannerT>
struct definition
{
definition(PFunctionGrammar const& /*self*/)
{
// Start grammar definition
real = leaf_node_d[ real_p ];
fun_label = leaf_node_d[ ( lexeme_d[ "FUN" >> +digit_p ] ) ];
parameter = leaf_node_d[ ( lexeme_d[ "PAR" >> +digit_p ] ) ];
map = leaf_node_d[ ( lexeme_d[ "MAP" >> +digit_p ] ) ];
function = str_p("COS") >> ch_p('(') >> expression >> ch_p(')')
| str_p("SIN") >> ch_p('(') >> expression >> ch_p(')')
| str_p("TAN") >> ch_p('(') >> expression >> ch_p(')')
| str_p("COSH") >> ch_p('(') >> expression >> ch_p(')')
| str_p("SINH") >> ch_p('(') >> expression >> ch_p(')')
| str_p("TANH") >> ch_p('(') >> expression >> ch_p(')')
| str_p("ACOS") >> ch_p('(') >> expression >> ch_p(')')
| str_p("ASIN") >> ch_p('(') >> expression >> ch_p(')')
| str_p("ATAN") >> ch_p('(') >> expression >> ch_p(')')
| str_p("ACOSH") >> ch_p('(') >> expression >> ch_p(')')
| str_p("ASINH") >> ch_p('(') >> expression >> ch_p(')')
| str_p("ATANH") >> ch_p('(') >> expression >> ch_p(')')
| str_p("LOG") >> ch_p('(') >> expression >> ch_p(')')
| str_p("LN") >> ch_p('(') >> expression >> ch_p(')')
| str_p("EXP") >> ch_p('(') >> expression >> ch_p(')')
;
factor = real
| parameter
| map
| function
| inner_node_d[ch_p('(') >> expression >> ch_p(')')]
;
term = factor >>
*( (root_node_d[ch_p('*')] >> factor)
| (root_node_d[ch_p('/')] >> factor)
);
expression = term >>
*( (root_node_d[ch_p('+')] >> term)
| (root_node_d[ch_p('-')] >> term)
);
assignment = (fun_label >> ch_p('=') >> expression);
// End grammar definition
// turn on the debugging info.
BOOST_SPIRIT_DEBUG_RULE(real);
BOOST_SPIRIT_DEBUG_RULE(fun_label);
BOOST_SPIRIT_DEBUG_RULE(parameter);
BOOST_SPIRIT_DEBUG_RULE(map);
BOOST_SPIRIT_DEBUG_RULE(function);
BOOST_SPIRIT_DEBUG_RULE(factor);
BOOST_SPIRIT_DEBUG_RULE(term);
BOOST_SPIRIT_DEBUG_RULE(expression);
BOOST_SPIRIT_DEBUG_RULE(assignment);
}
rule<ScannerT, parser_context<>, parser_tag<assignmentID> > assignment;
rule<ScannerT, parser_context<>, parser_tag<expressionID> > expression;
rule<ScannerT, parser_context<>, parser_tag<termID> > term;
rule<ScannerT, parser_context<>, parser_tag<factorID> > factor;
rule<ScannerT, parser_context<>, parser_tag<functionID> > function;
rule<ScannerT, parser_context<>, parser_tag<mapID> > map;
rule<ScannerT, parser_context<>, parser_tag<parameterID> > parameter;
rule<ScannerT, parser_context<>, parser_tag<funLabelID> > fun_label;
rule<ScannerT, parser_context<>, parser_tag<realID> > real;
rule<ScannerT, parser_context<>, parser_tag<assignmentID> > const&
start() const { return assignment; }
};
};
#endif // _PFUNCTIONGRAMMAR_H_

View File

@ -0,0 +1,417 @@
/***************************************************************************
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 <qfile.h>
#include <qtextstream.h>
#include <qstring.h>
#include "PFunctionHandler.h"
//-------------------------------------------------------------
// Constructor
//-------------------------------------------------------------
/**
* <p>
*
* \param fln
*/
PFunctionHandler::PFunctionHandler(char *fln)
{
fValid = true;
fFileName = QString(fln);
cout << endl << "in PFunctionHandler(char *fln)";
cout << endl << "fFileName = " << fFileName.latin1();
fValid = ReadFile();
if (fValid)
fValid = MapsAreValid();
}
//-------------------------------------------------------------
// Constructor
//-------------------------------------------------------------
/**
* <p>
*
* \param lines
*/
PFunctionHandler::PFunctionHandler(vector<QString> lines)
{
fValid = true;
fFileName = "";
cout << endl << "in PFunctionHandler(vector<QString> lines)";
if (lines.size() == 0) {
fValid = false;
return;
}
// analyze input
bool done = false;
int status;
int val[10];
double dval[10];
bool inFcnBlock = false;
for (unsigned int i=0; i<lines.size(); i++) {
if (lines[i].startsWith("#")) // comment hence ignore
continue;
lines[i] = lines[i].upper();
if (lines[i].startsWith("PAR")) {
cout << endl << "this is a parameter line ...";
status = sscanf(lines[i].latin1(), "PAR %lf %lf %lf %lf %lf %lf %lf %lf %lf %lf",
&dval[0], &dval[1], &dval[2], &dval[3], &dval[4],
&dval[5], &dval[6], &dval[7], &dval[8], &dval[9]);
if (status < 0) {
done = true;
fValid = false;
cout << endl << "invalid PAR line, sorry ...";
} else { // fill map
cout << endl << "PAR line, status = " << status;
for (int i=0; i<status; i++)
fParam.push_back(dval[i]);
}
} else if (lines[i].startsWith("MAP")) {
cout << endl << "this is a map line ...";
status = sscanf(lines[i].latin1(), "MAP %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]);
if (status < 0) {
done = true;
fValid = false;
cout << endl << "invalid MAP line, sorry ...";
} else { // fill map
cout << endl << "MAP line, status = " << status;
for (int i=0; i<status; i++)
fMap.push_back(val[i]);
}
} else if (lines[i].startsWith("FUNCTIONS")) {
cout << endl << "the functions block start ...";
inFcnBlock = true;
} else if (lines[i].startsWith("END")) {
cout << endl << "end tag found; rest will be ignored";
done = true;
} else if (inFcnBlock) {
fLines.push_back(lines[i]);
}
}
// check if all blocks are given
if ((fMap.size() == 0) || (fParam.size() == 0) || (fLines.size() == 0)) {
if (fMap.size() == 0)
cout << endl << "MAP block is missing ...";
if (fParam.size() == 0)
cout << endl << "PAR block is missing ...";
if (fLines.size() == 0)
cout << endl << "FUNCTION block is missing ...";
fValid = false;
}
fValid = MapsAreValid();
if (fValid) {
cout << endl << "Functions: ";
for (unsigned int i=0; i<fLines.size(); i++)
cout << endl << fLines[i].latin1();
}
}
//-------------------------------------------------------------
// Destructor
//-------------------------------------------------------------
/**
* <p>
*
*/
PFunctionHandler::~PFunctionHandler()
{
cout << endl << "in ~PFunctionHandler()" << endl << endl;
fParam.clear();
fMap.clear();
fLines.clear();
fFuncs.clear();
}
//-------------------------------------------------------------
// DoParse (public)
//-------------------------------------------------------------
/**
* <p>
*
*/
bool PFunctionHandler::DoParse()
{
cout << endl << "in PFunctionHandler::DoParse() ...";
bool success = true;
PFunctionGrammar function;
for (unsigned int i=0; i<fLines.size(); i++) {
cout << endl << "fLines[" << i << "] = '" << fLines[i].latin1() << "'";
tree_parse_info<> info = ast_parse(fLines[i].latin1(), function, space_p);
if (info.full) {
cout << endl << "parse successfull ..." << endl;
PFunction func(info, fParam, fMap);
fFuncs.push_back(func);
} else {
cout << endl << "parse failed ... (" << i << ")" << endl;
success = false;
break;
}
}
// check that all functions are valid. It could be that parsing was fine but
// the parameter index, or map index was out of range
if (success) {
for (unsigned int i=0; i<fFuncs.size(); i++) {
if (!fFuncs[i].IsValid()) {
cout << endl << "**ERROR**: function fun" << fFuncs[i].GetFuncNo();
cout << " has a problem with either parameter or map out of range!";
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;
}
//-------------------------------------------------------------
// Eval (public)
//-------------------------------------------------------------
/**
* <p>
*
* \param i
*/
double PFunctionHandler::Eval(int i)
{
if (GetFuncIndex(i) == -1) {
cout << endl << "**ERROR**: Couldn't find FUN" << i << " for evaluation";
return 0.0;
}
cout << endl << "PFunctionHandler::Eval: GetFuncIndex("<<i<<") = " << GetFuncIndex(i);
cout << endl;
return fFuncs[GetFuncIndex(i)].Eval();
}
//-------------------------------------------------------------
// GetFuncNo (public)
//-------------------------------------------------------------
/**
* <p>
*
* \param i
*/
unsigned int PFunctionHandler::GetFuncNo(unsigned int i)
{
if (i > fFuncs.size())
return -1;
return fFuncs[i].GetFuncNo();
}
//-------------------------------------------------------------
// ReadFile (private)
//-------------------------------------------------------------
/**
* <p>
*
*/
bool PFunctionHandler::ReadFile()
{
cout << endl << "in ~PFunctionHandler::ReadFile()";
if (fFileName.isEmpty()) {
cout << endl << "PFunctionHandler::ReadFile(): **ERROR**";
cout << endl << " no file name given :-(. Will quit";
return false;
}
QFile f(fFileName);
if (!f.exists()) {
cout << endl << "PFunctionHandler::ReadFile(): **ERROR**";
cout << endl << " File '" << fFileName.latin1() << "' does not exist.";
return false;
}
if (!f.open(IO_ReadOnly)) {
cout << endl << "PFunctionHandler::ReadFile(): **ERROR**";
cout << endl << " File '" << fFileName.latin1() << "' couldn't being opened.";
return false;
}
QTextStream stream(&f);
QString line;
bool done = false;
bool success = true;
int status;
int val[10];
double dval[10];
bool inFcnBlock = false;
while ( !stream.atEnd() && !done) {
line = stream.readLine(); // line of text excluding '\n'
if (line.startsWith("#")) // comment hence ignore
continue;
line = line.upper();
if (line.startsWith("PAR")) {
cout << endl << "this is a parameter line ...";
status = sscanf(line.latin1(), "PAR %lf %lf %lf %lf %lf %lf %lf %lf %lf %lf",
&dval[0], &dval[1], &dval[2], &dval[3], &dval[4],
&dval[5], &dval[6], &dval[7], &dval[8], &dval[9]);
if (status < 0) {
done = true;
success = false;
cout << endl << "invalid PAR line, sorry ...";
} else { // fill map
cout << endl << "PAR line, status = " << status;
for (int i=0; i<status; i++)
fParam.push_back(dval[i]);
}
} else if (line.startsWith("MAP")) {
cout << endl << "this is a map line ...";
status = sscanf(line.latin1(), "MAP %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]);
if (status < 0) {
done = true;
success = false;
cout << endl << "invalid MAP line, sorry ...";
} else { // fill map
cout << endl << "MAP line, status = " << status;
for (int i=0; i<status; i++)
fMap.push_back(val[i]);
}
} else if (line.startsWith("FUNCTIONS")) {
cout << endl << "the functions block start ...";
inFcnBlock = true;
} else if (line.startsWith("END")) {
cout << endl << "end tag found; rest will be ignored";
done = true;
} else if (inFcnBlock) {
fLines.push_back(line);
}
}
f.close();
// check if all blocks are given
if ((fMap.size() == 0) || (fParam.size() == 0) || (fLines.size() == 0)) {
if (fMap.size() == 0)
cout << endl << "MAP block is missing ...";
if (fParam.size() == 0)
cout << endl << "PAR block is missing ...";
if (fLines.size() == 0)
cout << endl << "FUNCTION block is missing ...";
success = false;
}
if (success) {
cout << endl << "Functions: ";
for (unsigned int i=0; i<fLines.size(); i++)
cout << endl << fLines[i].latin1();
}
return success;
}
//-------------------------------------------------------------
// MapsAreValid (private)
//-------------------------------------------------------------
/**
* <p>
*
*/
bool PFunctionHandler::MapsAreValid()
{
bool success = true;
int maxParam = fParam.size();
for (unsigned int i=0; i<fMap.size(); i++)
if (fMap[i] > maxParam)
success = false;
if (!success)
cout << endl << "invalid MAP found ...";
return success;
}
//-------------------------------------------------------------
// GetFuncIndex (private)
//-------------------------------------------------------------
/**
* <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;
}

View File

@ -0,0 +1,86 @@
/***************************************************************************
PFunctionHandler.h
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. *
***************************************************************************/
#ifndef _PFUNCTIONHANDLER_H_
#define _PFUNCTIONHANDLER_H_
#include <iostream>
#include <vector>
using namespace std;
#include <qstring.h>
#include "PFunctionGrammar.h"
#include "PFunction.h"
class PFunctionHandler
{
public:
PFunctionHandler(char *fln);
PFunctionHandler(vector<QString> lines);
virtual ~PFunctionHandler();
virtual bool IsValid() { return fValid; }
virtual bool DoParse();
virtual double Eval(int i);
virtual unsigned int GetFuncNo(unsigned int i);
virtual unsigned int GetNoOfFuncs() { return fFuncs.size(); }
private:
bool fValid;
QString fFileName;
vector<double> fParam;
vector<int> fMap;
vector<QString> fLines;
vector<PFunction> fFuncs;
virtual bool ReadFile();
virtual bool MapsAreValid();
virtual int GetFuncIndex(int funcNo);
};
// cint dictionary stuff --------------------------------------
#ifdef __CINT__
#pragma link off all globals;
#pragma link off all classes;
#pragma link off all functions;
#pragma link C++ class PFunctionHandler+;
#endif // end __CINT__
//-------------------------------------------------------------
#endif // _PFUNCTIONHANDLER_H_

View File

@ -0,0 +1,28 @@
#----------------------------------------------
# function input file
#----------------------------------------------
#
# '#' are comment lines
#
# The file has the following structure:
#
# PAR <par1> <par2> ... <parN>
# MAP <map1> <map2> ... <mapM>
# FUNCTIONS
# fun1 = <function>
# fun2 = <function>
# funX = <function>
# END
#----------------------------------------------
PAR 1.0 2.1 3.5 -0.87 0.87
MAP 2 1 4 5
FUNCTIONS
fun0 = sin(par3/(par1+map2))
#fun0 = par1 + map3 * cos(cos(par2 - map1))
#fun8 = log(sin(par1)) + exp(-1.0*map2)
#fun1 = par1 + map1 * (0.01355+par1*(2.1 - (-2.3 / 3.4)))
#fun2 = par1 * par2 - map3
#fun3 = -3.2 + (par2-par1)/(map2+map3)
#fun7 = 1.2
END
#----------------------------------------------

BIN
src/tests/spirit/spirit.pdf Normal file

Binary file not shown.

View File

@ -0,0 +1,100 @@
#include <iostream>
using namespace std;
#include "PFunctionHandler.h"
//-----------------------------------------------------
void syntax()
{
cout << endl << "spirit_fcn_test [--file <filename>] | [--help]";
cout << endl << " without arguments: interactive mode";
cout << endl << " --file <filename>: function block etc. from file";
cout << endl << " --help: this help";
cout << endl << endl;
}
//-----------------------------------------------------
void handle_input(vector<QString> &lines)
{
cout << endl << "will handle input ...";
cout << endl << "you should provide a PAR, a MAP, and a FUNCTION block";
cout << endl << " Map block:";
cout << endl << " MAP <map1> <map2> ... <mapM>";
cout << endl << " Parameter block:";
cout << endl << " PAR <par1> <par2> ... <parN>";
cout << endl << " Function Block:";
cout << endl << " FUNCTION";
cout << endl << " fun1 = <function1>";
cout << endl << " fun2 = <function2>";
cout << endl << " ...";
cout << endl << " funX = <functionX>";
cout << endl << " END";
cout << endl << "to get out of the input handle type '.q'";
cout << endl;
bool done = false;
char str[128];
do {
cout << ">> ";
cin.getline(str, sizeof(str));
if (!strcmp(str, ".q"))
done = true;
else
lines.push_back(str);
} while (!done);
}
//-----------------------------------------------------
int main(int argc, char *argv[])
{
bool inputFile = false;
if (argc > 3) {
syntax();
return 0;
} else if (argc == 2) {
syntax();
return 0;
} else if (argc == 3) {
if (strcmp(argv[1], "--file")) {
syntax();
return 0;
} else {
inputFile = true;
}
}
PFunctionHandler *fcnHandler = 0;
if (inputFile) {
fcnHandler = new PFunctionHandler(argv[2]);
} else {
vector<QString> lines;
handle_input(lines);
cout << endl << "lines.size() = " << lines.size();
fcnHandler = new PFunctionHandler(lines);
}
if (fcnHandler == 0) {
cout << endl << "Couldn't invoke function handler, sorry ..." << endl;
return 0;
}
bool go_on = fcnHandler->IsValid();
if (go_on) {
cout << endl << "will do the parsing ...";
if (fcnHandler->DoParse()) {
cout << endl << "will do the evaluation ...";
for (unsigned int i=0; i<fcnHandler->GetNoOfFuncs(); i++)
cout << endl << "FUN" << fcnHandler->GetFuncNo(i) << " = " << fcnHandler->Eval(fcnHandler->GetFuncNo(i));
}
}
// clean up
if (fcnHandler) {
delete fcnHandler;
fcnHandler = 0;
}
return 1;
}

View File

@ -0,0 +1,24 @@
#------------------------------------------------------
# spirit_fcn_test.pro
# qmake file for spirit_fcn_test
#
# Andreas Suter, 2007/12/10
#
# $Id$
#
#------------------------------------------------------
MAKEFILE = Makefile
CONFIG += warn_on debug
HEADERS = PFunctionGrammar.h \
PFunction.h \
PFunctionHandler.h
SOURCES = spirit_fcn_test.cpp \
PFunction.cpp \
PFunctionHandler.cpp
TARGET=spirit_fcn_test

View File

View File

@ -0,0 +1,37 @@
#include <iostream>
using namespace std;
#include "PPointObj.h"
PPointObj::PPointObj(unsigned int counter) : fCounter(counter)
{
fTest = new int[5];
for (unsigned int i=0; i<5; i++)
fTest[i] = 10*counter+i;
cout << endl << "in PPointObj() " << fCounter << ": fTest = " << fTest;
cout << endl;
}
PPointObj::~PPointObj()
{
cout << endl << "in ~PPointObj() " << fCounter << ": fTest = " << fTest;
cout << endl;
}
void PPointObj::PrintTest()
{
cout << endl << fCounter << ": ";
for (unsigned int i=0; i<5; i++)
cout << fTest[i] << ", ";
cout << endl;
}
void PPointObj::CleanUp()
{
if (fTest) {
delete [] fTest;
fTest = 0;
}
}

View File

@ -0,0 +1,17 @@
#ifndef _PPOINTOBJ_H_
#define _PPOINTOBJ_H_
class PPointObj {
public:
PPointObj(unsigned int counter);
~PPointObj();
void PrintTest();
void CleanUp();
private:
int fCounter;
int *fTest;
};
#endif // _PPOINTOBJ_H_

View File

@ -0,0 +1,10 @@
#include "PStlCheck.h"
PStlCheck::PStlCheck()
{
}
PStlCheck::~PStlCheck()
{
fPpo.clear();
}

View File

@ -0,0 +1,17 @@
#ifndef _PSTLCHECK_H_
#define _PSTLCHECK_H_
#include <list>
using namespace std;
#include "PPointObj.h"
class PStlCheck {
public:
PStlCheck();
~PStlCheck();
list<PPointObj> fPpo;
};
#endif // _PSTLCHECK_H_

View File

@ -0,0 +1,28 @@
#include <iostream>
#include <list>
using namespace std;
#include "PStlCheck.h"
int main()
{
PStlCheck check;
unsigned int counter = 0;
for (unsigned int i=0; i<2; i++) {
check.fPpo.push_back(PPointObj(counter++));
cout << endl << "----------";
}
cout << endl << "size = " << check.fPpo.size();
cout << endl;
list<PPointObj>::iterator iter;
for (iter=check.fPpo.begin(); iter!=check.fPpo.end(); ++iter)
iter->PrintTest();
for (iter=check.fPpo.begin(); iter!=check.fPpo.end(); ++iter)
iter->CleanUp();
return 0;
}

View File

@ -0,0 +1,22 @@
#------------------------------------------------------
# stl_check.pro
# qmake file for stl_check
#
# Andreas Suter, 2007/05/14
#
# $Id$
#
#------------------------------------------------------
MAKEFILE = Makefile.stl_check
CONFIG += warn_on debug
HEADERS = PStlCheck.h \
PPointObj.h
SOURCES = stl_check.cpp \
PStlCheck.cpp \
PPointObj.cpp
TARGET=stl_check

View File

@ -0,0 +1,36 @@
#include <iostream>
using namespace std;
#include "PPointObj.h"
#define PPO_SIZE 100
PPointObj::PPointObj(unsigned int counter) : fCounter(counter)
{
fTest = new int[PPO_SIZE];
for (unsigned int i=0; i<PPO_SIZE; i++)
fTest[i] = 2*PPO_SIZE*counter+i;
cout << endl << "in PPointObj() " << fCounter << ": fTest = " << fTest;
cout << endl;
}
PPointObj::~PPointObj()
{
if (fTest) {
delete [] fTest;
fTest = 0;
}
cout << endl << "in ~PPointObj() " << fCounter << ": fTest = " << fTest;
cout << endl;
}
void PPointObj::PrintTest()
{
cout << endl << fCounter << ": ";
for (unsigned int i=0; i<PPO_SIZE; i++)
cout << fTest[i] << ", ";
cout << endl;
}

View File

@ -0,0 +1,16 @@
#ifndef _PPOINTOBJ_H_
#define _PPOINTOBJ_H_
class PPointObj {
public:
PPointObj(unsigned int counter);
~PPointObj();
void PrintTest();
private:
int fCounter;
int *fTest;
};
#endif // _PPOINTOBJ_H_

View File

@ -0,0 +1,29 @@
#include "PStlCheck.h"
PStlCheck::PStlCheck()
{
}
PStlCheck::~PStlCheck()
{
fPpo.clear();
}
void PStlCheck::Add(unsigned int count)
{
fPpo.push_back(new PPointObj(count));
}
void PStlCheck::CleanUp()
{
for (unsigned int i=0; i<fPpo.size(); i++) {
fPpo[i]->~PPointObj();
}
}
void PStlCheck::PrintTest()
{
for (unsigned int i=0; i<fPpo.size(); i++)
fPpo[i]->PrintTest();
}

View File

@ -0,0 +1,22 @@
#ifndef _PSTLCHECK_H_
#define _PSTLCHECK_H_
#include <vector>
using namespace std;
#include "PPointObj.h"
class PStlCheck {
public:
PStlCheck();
~PStlCheck();
void Add(unsigned int count);
void CleanUp();
void PrintTest();
private:
vector<PPointObj*> fPpo;
};
#endif // _PSTLCHECK_H_

View File

@ -0,0 +1,21 @@
#include <iostream>
#include <vector>
using namespace std;
#include "PStlCheck.h"
int main()
{
PStlCheck check;
for (unsigned int i=0; i<2; i++) {
check.Add(i);
cout << endl << "----------";
}
check.PrintTest();
check.CleanUp();
return 0;
}

View File

@ -0,0 +1,22 @@
#------------------------------------------------------
# stl_check_2.pro
# qmake file for stl_check_2
#
# Andreas Suter, 2007/05/14
#
# $Id$
#
#------------------------------------------------------
MAKEFILE = Makefile.stl_check_2
CONFIG += warn_on debug
HEADERS = PStlCheck.h \
PPointObj.h
SOURCES = stl_check_2.cpp \
PStlCheck.cpp \
PPointObj.cpp
TARGET=stl_check_2