newly added. Not for productive used yetsvn diff | grep Index:
This commit is contained in:
31
src/classes/BUILD
Normal file
31
src/classes/BUILD
Normal 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
138
src/classes/Makefile.PMusr
Normal 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
478
src/classes/PFitter.cpp
Normal 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;
|
||||
}
|
99
src/classes/PFitterFcn.cpp
Normal file
99
src/classes/PFitterFcn.cpp
Normal 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
562
src/classes/PFunction.cpp
Normal 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);
|
||||
}
|
||||
}
|
225
src/classes/PFunctionHandler.cpp
Normal file
225
src/classes/PFunctionHandler.cpp
Normal 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
1780
src/classes/PMsrHandler.cpp
Normal file
File diff suppressed because it is too large
Load Diff
643
src/classes/PRunAsymmetry.cpp
Normal file
643
src/classes/PRunAsymmetry.cpp
Normal 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
149
src/classes/PRunBase.cpp
Normal 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;
|
||||
}
|
||||
}
|
811
src/classes/PRunDataHandler.cpp
Normal file
811
src/classes/PRunDataHandler.cpp
Normal 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;
|
||||
}
|
366
src/classes/PRunListCollection.cpp
Normal file
366
src/classes/PRunListCollection.cpp
Normal 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
144
src/classes/PRunNonMusr.cpp
Normal 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
144
src/classes/PRunRRF.cpp
Normal 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;
|
||||
}
|
||||
|
342
src/classes/PRunSingleHisto.cpp
Normal file
342
src/classes/PRunSingleHisto.cpp
Normal 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;
|
||||
}
|
||||
|
||||
|
55
src/classes/PStartupHandler.cpp
Normal file
55
src/classes/PStartupHandler.cpp
Normal 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
970
src/classes/PTheory.cpp
Normal 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);
|
||||
}
|
||||
|
Reference in New Issue
Block a user