Restructured the interdependencies within the BMWlibs (maybe other commits will follow)

This commit is contained in:
Bastian M. Wojek
2011-03-20 18:03:49 +00:00
parent dc86404f88
commit aaa0638729
51 changed files with 60 additions and 3223 deletions

455
src/external/BMWtools/BMWIntegrator.cpp vendored Normal file
View File

@@ -0,0 +1,455 @@
/***************************************************************************
BMWIntegrator.cpp
Author: Bastian M. Wojek
e-mail: bastian.wojek@psi.ch
$Id$
***************************************************************************/
/***************************************************************************
* Copyright (C) 2009 by Bastian M. Wojek *
* bastian.wojek@psi.ch *
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* *
* This program is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU General Public License for more details. *
* *
* You should have received a copy of the GNU General Public License *
* along with this program; if not, write to the *
* Free Software Foundation, Inc., *
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
***************************************************************************/
#include "BMWIntegrator.h"
#include "cuba.h"
#define USERDATA NULL
#define SEED 0
std::vector<double> TDWaveGapIntegralCuhre::fPar;
/**
* <p>Integrate the function using the Cuhre interface
*
* <p><b>return:</b>
* - value of the integral
*/
double TDWaveGapIntegralCuhre::IntegrateFunc()
{
const unsigned int NCOMP(1);
const double EPSREL (1e-4);
const double EPSABS (1e-6);
const unsigned int VERBOSE (0);
const unsigned int LAST (4);
const unsigned int MINEVAL (0);
const unsigned int MAXEVAL (50000);
const unsigned int KEY (13);
int nregions, neval, fail;
double integral[NCOMP], error[NCOMP], prob[NCOMP];
Cuhre(fNDim, NCOMP, Integrand, USERDATA,
EPSREL, EPSABS, VERBOSE | LAST, MINEVAL, MAXEVAL,
KEY,
&nregions, &neval, &fail, integral, error, prob);
return integral[0];
}
/**
* <p>Calculate the function value for the use with Cuhre---actual implementation of the function
*
* <p><b>return:</b>
* - 0
*
* \param ndim number of dimensions of the integral (2 here)
* \param x point where the function should be evaluated
* \param ncomp number of components of the integrand (1 here)
* \param f function value
* \param userdata additional user parameters (required by the interface, NULL here)
*/
int TDWaveGapIntegralCuhre::Integrand(const int *ndim, const double x[],
const int *ncomp, double f[], void *userdata) // x = {E, phi}, fPar = {twokBT, Delta(T), Ec, phic}
{
double deltasq(TMath::Power(fPar[1]*TMath::Cos(2.0*x[1]*fPar[3]),2.0));
f[0] = 1.0/TMath::Power(TMath::CosH(TMath::Sqrt(x[0]*x[0]*fPar[2]*fPar[2]+deltasq)/fPar[0]),2.0);
return 0;
}
std::vector<double> TCosSqDWaveGapIntegralCuhre::fPar;
/**
* <p>Integrate the function using the Cuhre interface
*
* <p><b>return:</b>
* - value of the integral
*/
double TCosSqDWaveGapIntegralCuhre::IntegrateFunc()
{
const unsigned int NCOMP(1);
const double EPSREL (1e-8);
const double EPSABS (1e-6);
const unsigned int VERBOSE (0);
const unsigned int LAST (4);
const unsigned int MINEVAL (0);
const unsigned int MAXEVAL (500000);
const unsigned int KEY (13);
int nregions, neval, fail;
double integral[NCOMP], error[NCOMP], prob[NCOMP];
Cuhre(fNDim, NCOMP, Integrand, USERDATA,
EPSREL, EPSABS, VERBOSE | LAST, MINEVAL, MAXEVAL,
KEY,
&nregions, &neval, &fail, integral, error, prob);
return integral[0];
}
/**
* <p>Calculate the function value for the use with Cuhre---actual implementation of the function
*
* <p><b>return:</b>
* - 0
*
* \param ndim number of dimensions of the integral (2 here)
* \param x point where the function should be evaluated
* \param ncomp number of components of the integrand (1 here)
* \param f function value
* \param userdata additional user parameters (required by the interface, NULL here)
*/
int TCosSqDWaveGapIntegralCuhre::Integrand(const int *ndim, const double x[],
const int *ncomp, double f[], void *userdata) // x = {E, phi}, fPar = {twokBT, DeltaD(T), Ec, phic, DeltaS(T)}
{
double deltasq(TMath::Power(fPar[1]*TMath::Cos(2.0*x[1]*fPar[3]) + fPar[4], 2.0));
f[0] = TMath::Power(TMath::Cos(x[1]*fPar[3])/TMath::CosH(TMath::Sqrt(x[0]*x[0]*fPar[2]*fPar[2]+deltasq)/fPar[0]),2.0);
return 0;
}
std::vector<double> TSinSqDWaveGapIntegralCuhre::fPar;
/**
* <p>Integrate the function using the Cuhre interface
*
* <p><b>return:</b>
* - value of the integral
*/
double TSinSqDWaveGapIntegralCuhre::IntegrateFunc()
{
const unsigned int NCOMP(1);
const double EPSREL (1e-8);
const double EPSABS (1e-10);
const unsigned int VERBOSE (0);
const unsigned int LAST (4);
const unsigned int MINEVAL (0);
const unsigned int MAXEVAL (500000);
const unsigned int KEY (13);
int nregions, neval, fail;
double integral[NCOMP], error[NCOMP], prob[NCOMP];
Cuhre(fNDim, NCOMP, Integrand, USERDATA,
EPSREL, EPSABS, VERBOSE | LAST, MINEVAL, MAXEVAL,
KEY,
&nregions, &neval, &fail, integral, error, prob);
return integral[0];
}
/**
* <p>Calculate the function value for the use with Cuhre---actual implementation of the function
*
* <p><b>return:</b>
* - 0
*
* \param ndim number of dimensions of the integral (2 here)
* \param x point where the function should be evaluated
* \param ncomp number of components of the integrand (1 here)
* \param f function value
* \param userdata additional user parameters (required by the interface, NULL here)
*/
int TSinSqDWaveGapIntegralCuhre::Integrand(const int *ndim, const double x[],
const int *ncomp, double f[], void *userdata) // x = {E, phi}, fPar = {twokBT, DeltaD(T), Ec, phic, DeltaS(T)}
{
double deltasq(TMath::Power(fPar[1]*TMath::Cos(2.0*x[1]*fPar[3]) + fPar[4],2.0));
f[0] = TMath::Power(TMath::Sin(x[1]*fPar[3]),2.0)/TMath::Power(TMath::CosH(TMath::Sqrt(x[0]*x[0]*fPar[2]*fPar[2]+deltasq)/fPar[0]),2.0);
return 0;
}
std::vector<double> TAnSWaveGapIntegralCuhre::fPar;
/**
* <p>Integrate the function using the Cuhre interface
*
* <p><b>return:</b>
* - value of the integral
*/
double TAnSWaveGapIntegralCuhre::IntegrateFunc()
{
const unsigned int NCOMP(1);
const double EPSREL (1e-4);
const double EPSABS (1e-6);
const unsigned int VERBOSE (0);
const unsigned int LAST (4);
const unsigned int MINEVAL (100);
const unsigned int MAXEVAL (1000000);
const unsigned int KEY (13);
int nregions, neval, fail;
double integral[NCOMP], error[NCOMP], prob[NCOMP];
Cuhre(fNDim, NCOMP, Integrand, USERDATA,
EPSREL, EPSABS, VERBOSE | LAST, MINEVAL, MAXEVAL,
KEY,
&nregions, &neval, &fail, integral, error, prob);
return integral[0];
}
/**
* <p>Calculate the function value for the use with Cuhre---actual implementation of the function
*
* <p><b>return:</b>
* - 0
*
* \param ndim number of dimensions of the integral (2 here)
* \param x point where the function should be evaluated
* \param ncomp number of components of the integrand (1 here)
* \param f function value
* \param userdata additional user parameters (required by the interface, NULL here)
*/
int TAnSWaveGapIntegralCuhre::Integrand(const int *ndim, const double x[],
const int *ncomp, double f[], void *userdata) // x = {E, phi}, fPar = {twokBT, Delta(T),a, Ec, phic}
{
double deltasq(TMath::Power(fPar[1]*(1.0+fPar[2]*TMath::Cos(4.0*x[1]*fPar[4])),2.0));
f[0] = 1.0/TMath::Power(TMath::CosH(TMath::Sqrt(x[0]*x[0]*fPar[3]*fPar[3]+deltasq)/fPar[0]),2.0);
return 0;
}
std::vector<double> TAnSWaveGapIntegralDivonne::fPar;
/**
* <p>Integrate the function using the Divonne interface
*
* <p><b>return:</b>
* - value of the integral
*/
double TAnSWaveGapIntegralDivonne::IntegrateFunc()
{
const unsigned int NCOMP(1);
const double EPSREL (1e-4);
const double EPSABS (1e-6);
const unsigned int VERBOSE (0);
const unsigned int MINEVAL (1000);
const unsigned int MAXEVAL (1000000);
const unsigned int KEY1 (47);
const unsigned int KEY2 (1);
const unsigned int KEY3 (1);
const unsigned int MAXPASS (5);
const double BORDER (0.);
const double MAXCHISQ (10.);
const double MINDEVIATION (.25);
const unsigned int NGIVEN (0);
const unsigned int LDXGIVEN (fNDim);
const unsigned int NEXTRA (0);
int nregions, neval, fail;
double integral[NCOMP], error[NCOMP], prob[NCOMP];
Divonne(fNDim, NCOMP, Integrand, USERDATA,
EPSREL, EPSABS, VERBOSE, SEED, MINEVAL, MAXEVAL,
KEY1, KEY2, KEY3, MAXPASS, BORDER, MAXCHISQ, MINDEVIATION,
NGIVEN, LDXGIVEN, NULL, NEXTRA, NULL,
&nregions, &neval, &fail, integral, error, prob);
return integral[0];
}
/**
* <p>Calculate the function value for the use with Divonne---actual implementation of the function
*
* <p><b>return:</b>
* - 0
*
* \param ndim number of dimensions of the integral (2 here)
* \param x point where the function should be evaluated
* \param ncomp number of components of the integrand (1 here)
* \param f function value
* \param userdata additional user parameters (required by the interface, NULL here)
*/
int TAnSWaveGapIntegralDivonne::Integrand(const int *ndim, const double x[],
const int *ncomp, double f[], void *userdata) // x = {E, phi}, fPar = {twokBT, Delta(T),a, Ec, phic}
{
double deltasq(TMath::Power(fPar[1]*(1.0+fPar[2]*TMath::Cos(4.0*x[1]*fPar[4])),2.0));
f[0] = 1.0/TMath::Power(TMath::CosH(TMath::Sqrt(x[0]*x[0]*fPar[3]*fPar[3]+deltasq)/fPar[0]),2.0);
return 0;
}
std::vector<double> TAnSWaveGapIntegralSuave::fPar;
/**
* <p>Integrate the function using the Suave interface
*
* <p><b>return:</b>
* - value of the integral
*/
double TAnSWaveGapIntegralSuave::IntegrateFunc()
{
const unsigned int NCOMP(1);
const double EPSREL (1e-4);
const double EPSABS (1e-6);
const unsigned int VERBOSE (0);
const unsigned int LAST (4);
const unsigned int MINEVAL (1000);
const unsigned int MAXEVAL (1000000);
const unsigned int NNEW (1000);
const double FLATNESS (25.);
int nregions, neval, fail;
double integral[NCOMP], error[NCOMP], prob[NCOMP];
Suave(fNDim, NCOMP, Integrand, USERDATA,
EPSREL, EPSABS, VERBOSE | LAST, SEED, MINEVAL, MAXEVAL,
NNEW, FLATNESS,
&nregions, &neval, &fail, integral, error, prob);
return integral[0];
}
/**
* <p>Calculate the function value for the use with Suave---actual implementation of the function
*
* <p><b>return:</b>
* - 0
*
* \param ndim number of dimensions of the integral (2 here)
* \param x point where the function should be evaluated
* \param ncomp number of components of the integrand (1 here)
* \param f function value
* \param userdata additional user parameters (required by the interface, NULL here)
*/
int TAnSWaveGapIntegralSuave::Integrand(const int *ndim, const double x[],
const int *ncomp, double f[], void *userdata) // x = {E, phi}, fPar = {twokBT, Delta(T),a, Ec, phic}
{
double deltasq(TMath::Power(fPar[1]*(1.0+fPar[2]*TMath::Cos(4.0*x[1]*fPar[4])),2.0));
f[0] = 1.0/TMath::Power(TMath::CosH(TMath::Sqrt(x[0]*x[0]*fPar[3]*fPar[3]+deltasq)/fPar[0]),2.0);
return 0;
}
std::vector<double> TNonMonDWave1GapIntegralCuhre::fPar;
/**
* <p>Integrate the function using the Cuhre interface
*
* <p><b>return:</b>
* - value of the integral
*/
double TNonMonDWave1GapIntegralCuhre::IntegrateFunc()
{
const unsigned int NCOMP(1);
const double EPSREL (1e-4);
const double EPSABS (1e-6);
const unsigned int VERBOSE (0);
const unsigned int LAST (4);
const unsigned int MINEVAL (100);
const unsigned int MAXEVAL (1000000);
const unsigned int KEY (13);
int nregions, neval, fail;
double integral[NCOMP], error[NCOMP], prob[NCOMP];
Cuhre(fNDim, NCOMP, Integrand, USERDATA,
EPSREL, EPSABS, VERBOSE | LAST, MINEVAL, MAXEVAL,
KEY,
&nregions, &neval, &fail, integral, error, prob);
return integral[0];
}
/**
* <p>Calculate the function value for the use with Cuhre---actual implementation of the function
*
* <p><b>return:</b>
* - 0
*
* \param ndim number of dimensions of the integral (2 here)
* \param x point where the function should be evaluated
* \param ncomp number of components of the integrand (1 here)
* \param f function value
* \param userdata additional user parameters (required by the interface, NULL here)
*/
int TNonMonDWave1GapIntegralCuhre::Integrand(const int *ndim, const double x[],
const int *ncomp, double f[], void *userdata) // x = {E, phi}, fPar = {twokBT, Delta(T),a, Ec, phic}
{
double deltasq(TMath::Power(fPar[1]*(fPar[2]*TMath::Cos(2.0*x[1]*fPar[4])+(1.0-fPar[2])*TMath::Cos(6.0*x[1]*fPar[4])),2.0));
f[0] = 1.0/TMath::Power(TMath::CosH(TMath::Sqrt(x[0]*x[0]*fPar[3]*fPar[3]+deltasq)/fPar[0]),2.0);
return 0;
}
std::vector<double> TNonMonDWave2GapIntegralCuhre::fPar;
/**
* <p>Integrate the function using the Cuhre interface
*
* <p><b>return:</b>
* - value of the integral
*/
double TNonMonDWave2GapIntegralCuhre::IntegrateFunc()
{
const unsigned int NCOMP(1);
const double EPSREL (1e-4);
const double EPSABS (1e-6);
const unsigned int VERBOSE (0);
const unsigned int LAST (4);
const unsigned int MINEVAL (100);
const unsigned int MAXEVAL (1000000);
const unsigned int KEY (13);
int nregions, neval, fail;
double integral[NCOMP], error[NCOMP], prob[NCOMP];
Cuhre(fNDim, NCOMP, Integrand, USERDATA,
EPSREL, EPSABS, VERBOSE | LAST, MINEVAL, MAXEVAL,
KEY,
&nregions, &neval, &fail, integral, error, prob);
return integral[0];
}
/**
* <p>Calculate the function value for the use with Cuhre---actual implementation of the function
*
* <p><b>return:</b>
* - 0
*
* \param ndim number of dimensions of the integral (2 here)
* \param x point where the function should be evaluated
* \param ncomp number of components of the integrand (1 here)
* \param f function value
* \param userdata additional user parameters (required by the interface, NULL here)
*/
int TNonMonDWave2GapIntegralCuhre::Integrand(const int *ndim, const double x[],
const int *ncomp, double f[], void *userdata) // x = {E, phi}, fPar = {twokBT, Delta(T),a, Ec, phic}
{
double deltasq(4.0*fPar[2]/27.0*TMath::Power(fPar[1]*TMath::Cos(2.0*x[1]*fPar[4]), 2.0) \
/ TMath::Power(1.0 + fPar[2]*TMath::Cos(2.0*x[1]*fPar[4])*TMath::Cos(2.0*x[1]*fPar[4]), 3.0));
f[0] = 1.0/TMath::Power(TMath::CosH(TMath::Sqrt(x[0]*x[0]*fPar[3]*fPar[3]+deltasq)/fPar[0]),2.0);
return 0;
}

519
src/external/BMWtools/BMWIntegrator.h vendored Normal file
View File

@@ -0,0 +1,519 @@
/***************************************************************************
BMWIntegrator.h
Author: Bastian M. Wojek
e-mail: bastian.wojek@psi.ch
$Id$
***************************************************************************/
/***************************************************************************
* Copyright (C) 2009 by Bastian M. Wojek *
* bastian.wojek@psi.ch *
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* *
* This program is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU General Public License for more details. *
* *
* You should have received a copy of the GNU General Public License *
* along with this program; if not, write to the *
* Free Software Foundation, Inc., *
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
***************************************************************************/
#ifndef _BMWIntegrator_H_
#define _BMWIntegrator_H_
#include "Math/GSLIntegrator.h"
#include "Math/GSLMCIntegrator.h"
#include "TMath.h"
#include <cmath>
#include <vector>
using namespace std;
/**
* <p>Base class for 1D integrations using the GNU Scientific Library integrator.
* The function which should be integrated has to be implemented in a derived class.
* Note: The purpose of this is to offer an easy-to-use interface---not the most efficient integration routine.
*/
class TIntegrator {
public:
TIntegrator();
virtual ~TIntegrator();
void SetParameters(const std::vector<double> &par) const { fPar=par; }
virtual double FuncAtX(double) const = 0;
double IntegrateFunc(double, double);
protected:
mutable vector<double> fPar; ///< parameters of the integrand
private:
static double FuncAtXgsl(double, void *);
ROOT::Math::GSLIntegrator *fIntegrator; ///< pointer to the GSL integrator
mutable double (*fFunc)(double, void *); ///< pointer to the integrand function
};
/**
* <p>Constructor of the base class for 1D integrations
* Allocation of memory for an integration using the adaptive 31 point Gauss-Kronrod rule
*/
inline TIntegrator::TIntegrator() : fFunc(0) {
fIntegrator = new ROOT::Math::GSLIntegrator(ROOT::Math::Integration::kADAPTIVE,ROOT::Math::Integration::kGAUSS31);
}
/**
* <p>Destructor of the base class for 1D integrations
* Clean up.
*/
inline TIntegrator::~TIntegrator(){
fPar.clear();
delete fIntegrator;
fIntegrator=0;
fFunc=0;
}
/**
* <p>Method for passing the integrand function value to the integrator.
*
* <p><b>return:</b>
* - function value of the integrand
*
* \param x point at which the function value is calculated
* \param obj pointer to the integrator
*/
inline double TIntegrator::FuncAtXgsl(double x, void *obj)
{
return ((TIntegrator*)obj)->FuncAtX(x);
}
/**
* <p>Calculate the integral of the function between the given boundaries
*
* <p><b>return:</b>
* - value of the integral
*
* \param x1 lower boundary
* \param x2 upper boundary
*/
inline double TIntegrator::IntegrateFunc(double x1, double x2)
{
fFunc = &TIntegrator::FuncAtXgsl;
return fIntegrator->Integral(fFunc, (this), x1, x2);
}
/**
* <p>Base class for multidimensional Monte-Carlo integrations using the GNU Scientific Library integrator.
* The function which should be integrated has to be implemented in a derived class.
* Note: The purpose of this is to offer an easy-to-use interface---not the most efficient integration routine.
*/
class TMCIntegrator {
public:
TMCIntegrator();
virtual ~TMCIntegrator();
void SetParameters(const std::vector<double> &par) const { fPar=par; }
virtual double FuncAtX(double *) const = 0;
double IntegrateFunc(size_t, double *, double *);
protected:
mutable vector<double> fPar; ///< parameters of the integrand
private:
static double FuncAtXgsl(double *, size_t, void *);
ROOT::Math::GSLMCIntegrator *fMCIntegrator; ///< pointer to the GSL integrator
mutable double (*fFunc)(double *, size_t, void *); ///< pointer to the integrand function
};
/**
* <p>Constructor of the base class for multidimensional Monte-Carlo integrations
* Allocation of memory for an integration using the MISER algorithm of Press and Farrar
*/
inline TMCIntegrator::TMCIntegrator() : fFunc(0) {
fMCIntegrator = new ROOT::Math::GSLMCIntegrator(ROOT::Math::MCIntegration::kMISER, 1.E-6, 1.E-4, 500000);
}
/**
* <p>Destructor of the base class for 1D integrations
* Clean up.
*/
inline TMCIntegrator::~TMCIntegrator(){
fPar.clear();
delete fMCIntegrator;
fMCIntegrator=0;
fFunc=0;
}
/**
* <p>Method for passing the integrand function value to the integrator.
*
* <p><b>return:</b>
* - function value of the integrand
*
* \param x point at which the function value is calculated
* \param dim number of dimensions
* \param obj pointer to the integrator
*/
inline double TMCIntegrator::FuncAtXgsl(double *x, size_t dim, void *obj)
{
return ((TMCIntegrator*)obj)->FuncAtX(x);
}
/**
* <p>Calculate the integral of the function between the given boundaries
*
* <p><b>return:</b>
* - value of the integral
*
* \param dim number of dimensions
* \param x1 lower boundary array
* \param x2 upper boundary array
*/
inline double TMCIntegrator::IntegrateFunc(size_t dim, double *x1, double *x2)
{
fFunc = &TMCIntegrator::FuncAtXgsl;
return fMCIntegrator->Integral(fFunc, dim, x1, x2, (this));
}
/**
* <p>Two-dimensional integrator class for the efficient calculation of the superfluid density within the semi-classical model
* assuming a cylindrical Fermi surface and a d_{x^2-y^2} symmetry of the superconducting order parameter.
* The integration uses the Cuhre algorithm of the Cuba library.
*/
class TDWaveGapIntegralCuhre {
public:
TDWaveGapIntegralCuhre() : fNDim(2) {}
~TDWaveGapIntegralCuhre() { fPar.clear(); }
void SetParameters(const std::vector<double> &par) { fPar=par; }
static int Integrand(const int*, const double[], const int*, double[], void*);
double IntegrateFunc();
protected:
static vector<double> fPar; ///< parameters of the integrand
unsigned int fNDim; ///< dimension of the integral
};
/**
* <p>Two-dimensional integrator class for the efficient calculation of the superfluid density along the a-axis
* within the semi-classical model assuming a cylindrical Fermi surface and a mixed d_{x^2-y^2} + s symmetry of the
* superconducting order parameter (effectively: d_{x^2-y^2} with shifted nodes and a-b-anisotropy).
* The integration uses the Cuhre algorithm of the Cuba library.
*/
class TCosSqDWaveGapIntegralCuhre {
public:
TCosSqDWaveGapIntegralCuhre() : fNDim(2) {}
~TCosSqDWaveGapIntegralCuhre() { fPar.clear(); }
void SetParameters(const std::vector<double> &par) { fPar=par; }
static int Integrand(const int*, const double[], const int*, double[], void*);
double IntegrateFunc();
protected:
static vector<double> fPar; ///< parameters of the integrand
unsigned int fNDim; ///< dimension of the integral
};
/**
* <p>Two-dimensional integrator class for the efficient calculation of the superfluid density along the b-axis
* within the semi-classical model assuming a cylindrical Fermi surface and a mixed d_{x^2-y^2} + s symmetry of the
* superconducting order parameter (effectively: d_{x^2-y^2} with shifted nodes and a-b-anisotropy).
* The integration uses the Cuhre algorithm of the Cuba library.
*/
class TSinSqDWaveGapIntegralCuhre {
public:
TSinSqDWaveGapIntegralCuhre() : fNDim(2) {}
~TSinSqDWaveGapIntegralCuhre() { fPar.clear(); }
void SetParameters(const std::vector<double> &par) { fPar=par; }
static int Integrand(const int*, const double[], const int*, double[], void*);
double IntegrateFunc();
protected:
static vector<double> fPar; ///< parameters of the integrand
unsigned int fNDim; ///< dimension of the integral
};
/**
* <p>Two-dimensional integrator class for the efficient calculation of the superfluid density within the semi-classical model
* assuming a cylindrical Fermi surface and an "anisotropic s-wave" symmetry of the superconducting order parameter.
* The integration uses the Cuhre algorithm of the Cuba library.
*/
class TAnSWaveGapIntegralCuhre {
public:
TAnSWaveGapIntegralCuhre() : fNDim(2) {}
~TAnSWaveGapIntegralCuhre() { fPar.clear(); }
void SetParameters(const std::vector<double> &par) { fPar=par; }
static int Integrand(const int*, const double[], const int*, double[], void*);
double IntegrateFunc();
protected:
static vector<double> fPar; ///< parameters of the integrand
unsigned int fNDim; ///< dimension of the integral
};
/**
* <p>Two-dimensional integrator class for the efficient calculation of the superfluid density within the semi-classical model
* assuming a cylindrical Fermi surface and an "anisotropic s-wave" symmetry of the superconducting order parameter.
* The integration uses the Divonne algorithm of the Cuba library.
*/
class TAnSWaveGapIntegralDivonne {
public:
TAnSWaveGapIntegralDivonne() : fNDim(2) {}
~TAnSWaveGapIntegralDivonne() { fPar.clear(); }
void SetParameters(const std::vector<double> &par) { fPar=par; }
static int Integrand(const int*, const double[], const int*, double[], void*);
double IntegrateFunc();
protected:
static vector<double> fPar; ///< parameters of the integrand
unsigned int fNDim; ///< dimension of the integral
};
/**
* <p>Two-dimensional integrator class for the efficient calculation of the superfluid density within the semi-classical model
* assuming a cylindrical Fermi surface and an "anisotropic s-wave" symmetry of the superconducting order parameter.
* The integration uses the Suave algorithm of the Cuba library.
*/
class TAnSWaveGapIntegralSuave {
public:
TAnSWaveGapIntegralSuave() : fNDim(2) {}
~TAnSWaveGapIntegralSuave() { fPar.clear(); }
void SetParameters(const std::vector<double> &par) { fPar=par; }
static int Integrand(const int*, const double[], const int*, double[], void*);
double IntegrateFunc();
protected:
static vector<double> fPar; ///< parameters of the integrand
unsigned int fNDim; ///< dimension of the integral
};
/**
* <p>Two-dimensional integrator class for the efficient calculation of the superfluid density within the semi-classical model
* assuming a cylindrical Fermi surface and an "non-monotonic d-wave" symmetry of the superconducting order parameter.
* The integration uses the Cuhre algorithm of the Cuba library.
*/
class TNonMonDWave1GapIntegralCuhre {
public:
TNonMonDWave1GapIntegralCuhre() : fNDim(2) {}
~TNonMonDWave1GapIntegralCuhre() { fPar.clear(); }
void SetParameters(const std::vector<double> &par) { fPar=par; }
static int Integrand(const int*, const double[], const int*, double[], void*);
double IntegrateFunc();
protected:
static vector<double> fPar; ///< parameters of the integrand
unsigned int fNDim; ///< dimension of the integral
};
/**
* <p>Two-dimensional integrator class for the efficient calculation of the superfluid density within the semi-classical model
* assuming a cylindrical Fermi surface and an "non-monotonic d-wave" symmetry of the superconducting order parameter.
* The integration uses the Cuhre algorithm of the Cuba library.
*/
class TNonMonDWave2GapIntegralCuhre {
public:
TNonMonDWave2GapIntegralCuhre() : fNDim(2) {}
~TNonMonDWave2GapIntegralCuhre() { fPar.clear(); }
void SetParameters(const std::vector<double> &par) { fPar=par; }
static int Integrand(const int*, const double[], const int*, double[], void*);
double IntegrateFunc();
protected:
static vector<double> fPar; ///< parameters of the integrand
unsigned int fNDim; ///< dimension of the integral
};
/**
* <p>Test class for the 2D MC integration
* Integral: x*y dx dy
*/
class T2DTest : public TMCIntegrator {
public:
T2DTest() {}
~T2DTest() {}
double FuncAtX(double *) const;
};
/**
* <p>Calculate the function value---actual implementation of the function x*y
*
* <p><b>return:</b>
* - function value
*
* \param x point where the function should be evaluated
*/
inline double T2DTest::FuncAtX(double *x) const
{
return x[0]*x[1];
}
/**
* <p>Class for the 2D Monte-Carlo integration for the calculation of the superfluid density within the semi-classical model
* assuming a cylindrical Fermi surface and a d_{x^2-y^2} symmetry of the superconducting order parameter.
* The integration uses the GSL integration routines.
*/
class TDWaveGapIntegral : public TMCIntegrator {
public:
TDWaveGapIntegral() {}
~TDWaveGapIntegral() {}
double FuncAtX(double *) const;
};
/**
* <p>Calculate the function value---actual implementation of the function
*
* <p><b>return:</b>
* - function value
*
* \param x point where the function should be evaluated
*/
inline double TDWaveGapIntegral::FuncAtX(double *x) const // x = {E, phi}, fPar = {T, Delta(T)}
{
double twokt(2.0*0.08617384436*fPar[0]); // kB in meV/K
double deltasq(TMath::Power(fPar[1]*TMath::Cos(2.0*x[1]),2.0));
return -1.0/(2.0*twokt*TMath::CosH(TMath::Sqrt(x[0]*x[0]+deltasq)/twokt)*TMath::CosH(TMath::Sqrt(x[0]*x[0]+deltasq)/twokt));
}
/**
* <p>Class for the 2D Monte-Carlo integration for the calculation of the superfluid density within the semi-classical model
* assuming a cylindrical Fermi surface and an "anisotropic s-wave" symmetry of the superconducting order parameter.
* The integration uses the GSL integration routines.
*/
class TAnSWaveGapIntegral : public TMCIntegrator {
public:
TAnSWaveGapIntegral() {}
~TAnSWaveGapIntegral() {}
double FuncAtX(double *) const;
};
/**
* <p>Calculate the function value---actual implementation of the function
*
* <p><b>return:</b>
* - function value
*
* \param x point where the function should be evaluated
*/
inline double TAnSWaveGapIntegral::FuncAtX(double *x) const // x = {E, phi}, fPar = {T, Delta(T), a}
{
double twokt(2.0*0.08617384436*fPar[0]); // kB in meV/K
double deltasq(TMath::Power(fPar[1]*(1.0+fPar[2]*TMath::Cos(4.0*x[1])),2.0));
return -1.0/(2.0*twokt*TMath::CosH(TMath::Sqrt(x[0]*x[0]+deltasq)/twokt)*TMath::CosH(TMath::Sqrt(x[0]*x[0]+deltasq)/twokt));
}
/**
* <p>Class for the 1D integration of j0(a*x)*exp(-b*x)
* The integration uses the GSL integration routines.
*/
class TIntBesselJ0Exp : public TIntegrator {
public:
TIntBesselJ0Exp() {}
~TIntBesselJ0Exp() {}
double FuncAtX(double) const;
};
/**
* <p>Calculate the function value---actual implementation of the function j0(a*x)*exp(-b*x)
*
* <p><b>return:</b>
* - function value
*
* \param x point where the function should be evaluated
*/
inline double TIntBesselJ0Exp::FuncAtX(double x) const
{
double w0t(TMath::TwoPi()*fPar[0]*x);
double j0;
if (fabs(w0t) < 0.001) { // check zero time limits of the spherical bessel functions j0(x) and j1(x)
j0 = 1.0;
} else {
j0 = TMath::Sin(w0t)/w0t;
}
return j0 * TMath::Exp(-fPar[1]*x);
}
/**
* <p>Class for the 1D integration of sin(a*x)*exp(-b*x*x)
* The integration uses the GSL integration routines.
*/
class TIntSinGss : public TIntegrator {
public:
TIntSinGss() {}
~TIntSinGss() {}
double FuncAtX(double) const;
};
/**
* <p>Calculate the function value---actual implementation of the function sin(a*x)*exp(-b*x*x)
*
* <p><b>return:</b>
* - function value
*
* \param x point where the function should be evaluated
*/
inline double TIntSinGss::FuncAtX(double x) const
{
return TMath::Sin(TMath::TwoPi()*fPar[0]*x) * TMath::Exp(-0.5*fPar[1]*fPar[1]*x*x);
}
/**
* <p>Class for the 1D integration of the "DeRenzi Spin Glass Interpolation Integrand"
* See Eq. (5) of R. De Renzi and S. Fanesi, Physica B 289-290, 209-212 (2000).
* doi:10.1016/S0921-4526(00)00368-9
* The integration uses the GSL integration routines.
*/
class TIntSGInterpolation : public TIntegrator {
public:
TIntSGInterpolation() {}
~TIntSGInterpolation() {}
double FuncAtX(double) const;
};
/**
* <p>Calculate the function value---actual implementation of the function
*
* <p><b>return:</b>
* - function value
*
* \param x point where the function should be evaluated
*/
inline double TIntSGInterpolation::FuncAtX(double x) const
{
// Parameters: nu_L [MHz], a [1/us], lambda [1/us], beta [1], t [us]
double wt(TMath::TwoPi()*fPar[0]*x);
double expo(0.5*fPar[1]*fPar[1]*x*x/fPar[3]+fPar[2]*fPar[4]);
return (wt*TMath::Cos(wt)-TMath::Sin(wt))/(wt*wt)*TMath::Exp(-TMath::Power(expo,fPar[3]))/TMath::Power(expo,(1.0-fPar[3]));
}
/**
* <p>Class for the 1D integration for the calculation of the superfluid density within the semi-classical model
* assuming a cylindrical Fermi surface and an isotropic s-wave symmetry of the superconducting order parameter.
* The integration uses the GSL integration routines.
*/
class TGapIntegral : public TIntegrator {
public:
TGapIntegral() {}
~TGapIntegral() {}
double FuncAtX(double) const; // variable: E
};
/**
* <p>Calculate the function value---actual implementation of the function df/dE * E / sqrt(E^2 - Delta^2)
*
* <p><b>return:</b>
* - function value
*
* \param x point where the function should be evaluated
*/
inline double TGapIntegral::FuncAtX(double e) const
{
return 1.0/(TMath::Power(TMath::CosH(TMath::Sqrt(e*e+fPar[1]*fPar[1])/fPar[0]),2.0));
}
#endif //_TIntegrator_H_

View File

@@ -0,0 +1,456 @@
/***************************************************************************
BMWStartupHandler.cpp
Author: Bastian M. Wojek
e-mail: bastian.wojek@psi.ch
$Id$
based upon:
PStartupHandler.cpp
by Andreas Suter
***************************************************************************/
/***************************************************************************
* Copyright (C) 2007-2008 by Andreas Suter, Bastian M. Wojek *
* *
* *
* 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 <cstdlib>
#include <iostream>
using namespace std;
#include <cassert>
#include "BMWStartupHandler.h"
ClassImpQ(BMWStartupHandler)
//--------------------------------------------------------------------------
// Constructor
//--------------------------------------------------------------------------
/**
* <p>Constructor. Check if the BMW_startup.xml file is found in the local directory
*/
BMWStartupHandler::BMWStartupHandler() :
fDebug(false), fLEM(false), fVortex(false), fLF(false), fDataPath(""), fDeltat(0.), fDeltaB(0.), fWisdomFile(""), fWisdomFileFloat(""), fNSteps(0), fGridSteps(0), fDeltatLF(0.), fNStepsLF(0)
{
}
//--------------------------------------------------------------------------
// Destructor
//--------------------------------------------------------------------------
/**
* <p>Destructor
*/
BMWStartupHandler::~BMWStartupHandler()
{
// clean up
fEnergyList.clear();
fEnergyLabelList.clear();
fEnergies.clear();
}
//--------------------------------------------------------------------------
// OnStartDocument
//--------------------------------------------------------------------------
/**
* <p>Called on start of the XML file reading. Initializes all necessary variables.
*/
void BMWStartupHandler::OnStartDocument()
{
fKey = eEmpty;
}
//--------------------------------------------------------------------------
// OnEndDocument
//--------------------------------------------------------------------------
/**
* <p>Called on end of XML file reading.
*/
void BMWStartupHandler::OnEndDocument()
{
// check if anything was set, and if not set some default stuff
CheckLists();
}
//--------------------------------------------------------------------------
// OnStartElement
//--------------------------------------------------------------------------
/**
* <p>Called when a XML start element is found. Filters out the needed elements
* and sets a proper key.
*
* \param str XML element name
* \param attributes not used
*/
void BMWStartupHandler::OnStartElement(const char *str, const TList *attributes)
{
if (!strcmp(str, "debug")) {
fKey = eDebug;
} else if (!strcmp(str, "LEM")) {
fKey = eLEM;
} else if (!strcmp(str, "VortexLattice")) {
fKey = eVortex;
} else if (!strcmp(str, "LFRelaxation")) {
fKey = eLF;
} else if (!strcmp(str, "data_path")) {
fKey = eDataPath;
} else if (!strcmp(str, "energy_label")) {
fKey = eEnergyLabel;
} else if (!strcmp(str, "energy")) {
fKey = eEnergy;
} else if (!strcmp(str, "delta_t")) {
fKey = eDeltat;
} else if (!strcmp(str, "delta_B")) {
fKey = eDeltaB;
} else if (!strcmp(str, "wisdom")) {
fKey = eWisdomFile;
} else if (!strcmp(str, "wisdom_float")) {
fKey = eWisdomFileFloat;
} else if (!strcmp(str, "N_theory")) {
fKey = eNSteps;
} else if (!strcmp(str, "N_VortexGrid")) {
fKey = eGridSteps;
} else if (!strcmp(str, "delta_t_LF")) {
fKey = eDeltatLF;
} else if (!strcmp(str, "N_LF")) {
fKey = eNStepsLF;
}
}
//--------------------------------------------------------------------------
// OnEndElement
//--------------------------------------------------------------------------
/**
* <p>Called when a XML end element is found. Resets the handler key.
*
* \param str not used
*/
void BMWStartupHandler::OnEndElement(const char *str)
{
fKey = eEmpty;
}
//--------------------------------------------------------------------------
// OnCharacters
//--------------------------------------------------------------------------
/**
* <p>Content of a given XML element. Filters out the data and feeds them to
* the internal variables.
*
* \param str XML element string
*/
void BMWStartupHandler::OnCharacters(const char *str)
{
switch (fKey) {
case eDebug:
if (!strcmp(str, "1"))
fDebug = true;
else
fDebug = false;
break;
case eLEM:
fLEM = true;
break;
case eVortex:
fVortex = true;
break;
case eLF:
fLF = true;
break;
case eDataPath:
// set the data path to the given path
fDataPath = str;
break;
case eEnergyLabel:
// add str to the energy label list
fEnergyLabelList.push_back(str);
break;
case eEnergy:
// add str to the energy list
fEnergyList.push_back(atof(str));
break;
case eDeltat:
// convert str to double and assign it to the deltat-member
fDeltat = atof(str);
break;
case eDeltaB:
// convert str to double and assign it to the deltaB-member
fDeltaB = atof(str);
break;
case eWisdomFile:
// set the wisdom file to the given name
fWisdomFile = str;
break;
case eWisdomFileFloat:
// set the float-wisdom file to the given name
fWisdomFileFloat = str;
break;
case eNSteps:
// convert str to int and assign it to the NSteps-member
fNSteps = atoi(str);
break;
case eGridSteps:
// convert str to int and assign it to the GridSteps-member
fGridSteps = atoi(str);
break;
case eDeltatLF:
// convert str to double and assign it to the deltatLF-member
fDeltatLF = atof(str);
break;
case eNStepsLF:
// convert str to int and assign it to the NStepsLF-member
fNStepsLF = atoi(str);
break;
default:
break;
}
}
//--------------------------------------------------------------------------
// OnComment
//--------------------------------------------------------------------------
/**
* <p>Called when a XML comment is found. Not used.
*
* \param str not used.
*/
void BMWStartupHandler::OnComment(const char *str)
{
// nothing to be done for now
}
//--------------------------------------------------------------------------
// OnWarning
//--------------------------------------------------------------------------
/**
* <p>Called when the XML parser emits a warning.
*
* \param str warning string
*/
void BMWStartupHandler::OnWarning(const char *str)
{
cerr << endl << "BMWStartupHandler::OnWarning: BMWStartupHandler **WARNING** " << str;
cerr << endl;
}
//--------------------------------------------------------------------------
// OnError
//--------------------------------------------------------------------------
/**
* <p>Called when the XML parser emits an error.
*
* \param str error string
*/
void BMWStartupHandler::OnError(const char *str)
{
cerr << endl << "BMWStartupHandler::OnError: BMWStartupHandler **ERROR** " << str;
cerr << endl;
}
//--------------------------------------------------------------------------
// OnFatalError
//--------------------------------------------------------------------------
/**
* <p>Called when the XML parser emits a fatal error.
*
* \param str fatal error string
*/
void BMWStartupHandler::OnFatalError(const char *str)
{
cerr << endl << "BMWStartupHandler::OnFatalError: BMWStartupHandler **FATAL ERROR** " << str;
cerr << endl;
}
//--------------------------------------------------------------------------
// OnCdataBlock
//--------------------------------------------------------------------------
/**
* <p>Not used.
*
* \param str not used
* \param len not used
*/
void BMWStartupHandler::OnCdataBlock(const char *str, int len)
{
// nothing to be done for now
}
//--------------------------------------------------------------------------
// CheckList
//--------------------------------------------------------------------------
/**
* <p>Check if the default lists are present and if not, feed them with some default settings
*
*/
void BMWStartupHandler::CheckLists()
{
// check if anything was set, and if not set some default stuff
if(fLF) {
// check if delta_t_LF is given, if not set default
if(fDebug)
cout << endl << "BMWStartupHandler::CheckLists: check specified LF time resolution for the Laplace transform ... " << endl;
if(!fDeltatLF) {
cout << "BMWStartupHandler::CheckLists: You did not specify the LF time resolution. Setting the default (0.04 ns)." << endl;
fDeltatLF = 0.00004;
} else {
if(fDebug)
cout << fDeltatLF << " us" << endl;
}
// check if N_LF is given, if not set default
if(fDebug)
cout << endl << "BMWStartupHandler::CheckLists: check length of the Laplace transform ..." << endl;
if (!fNStepsLF) {
cout << "BMWStartupHandler::CheckLists: You did not specify the length of the Laplace transform. Setting the default (524288)." << endl;
fNStepsLF = 524288;
} else {
if(fDebug)
cout << fNStepsLF << endl;
}
} else {
// check if delta_t is given, if not set default
if(fDebug)
cout << endl << "BMWStartupHandler::CheckLists: check specified time resolution ... " << endl;
if(!fDeltat) {
cout << "BMWStartupHandler::CheckLists: You did not specify the time resolution. Setting the default (10 ns)." << endl;
fDeltat = 0.01;
} else {
if(fDebug)
cout << fDeltat << " us" << endl;
}
// check if delta_B is given, if not set default
if(fDebug)
cout << endl << "BMWStartupHandler::CheckLists: check specified field resolution ..." << endl;
if(!fDeltaB) {
cout << "BMWStartupHandler::CheckLists: You did not specify the field resolution. Setting the default (0.1 G)." << endl;
fDeltaB = 0.1;
} else {
if(fDebug)
cout << fDeltaB << " G" << endl;
}
}
// check if any wisdom-file is specified
if(fDebug)
cout << endl << "BMWStartupHandler::CheckLists: check wisdom file ..." << endl;
if (!fWisdomFile.size()) {
cout << "BMWStartupHandler::CheckLists: You did not specify a wisdom file. No FFTW plans will be loaded or saved." << endl;
fWisdomFile = "";
} else {
if(fDebug)
cout << fWisdomFile << endl;
}
// check if any float-wisdom-file is specified
if(fDebug)
cout << endl << "BMWStartupHandler::CheckLists: check float-wisdom file ..." << endl;
if (!fWisdomFile.size()) {
cout << "BMWStartupHandler::CheckLists: You did not specify a float-wisdom file. No FFTW plans will be loaded or saved." << endl;
fWisdomFileFloat = "";
} else {
if(fDebug)
cout << fWisdomFileFloat << endl;
}
if (fLEM) {
// check if any data path is given
if(fDebug)
cout << endl << "BMWStartupHandler::CheckLists: check data path ..." << endl;
if (fDataPath.empty()) {
cerr << "BMWStartupHandler::CheckLists: This is not going to work, you have to set a valid data path where to find the rge-files in the xml-file!" << endl;
assert(!fDataPath.empty());
} else {
if(fDebug)
cout << fDataPath << endl;
}
// check if any energies are given
if(fDebug)
cout << endl << "BMWStartupHandler::CheckLists: check energy list ..." << endl;
if (fEnergyList.size() != fEnergyLabelList.size()) {
cerr << "BMWStartupHandler::CheckLists: The number of energies and energy labels are different! Please fix it!" << endl \
<< "BMWStartupHandler::CheckLists: The program will be terminated now!" << endl;
assert(fEnergyList.size() == fEnergyLabelList.size());
}
if (fEnergyList.empty()) {
cerr << "BMWStartupHandler::CheckLists: Energy list empty!" << endl \
<< "BMWStartupHandler::CheckLists: Trying to use the standard energies: 0.0 to 35.0 keV in 0.1 keV steps" << endl;
for (double x(0.0); x<= 35.0; x+=0.1) {
fEnergyList.push_back(x);
}
}
if (fEnergyLabelList.empty()) {
cerr << "BMWStartupHandler::CheckLists: Energy label list empty!" << endl \
<< "BMWStartupHandler::CheckLists: Trying to use the specified energies as labels in the format %02.1f..." << endl \
<< "BMWStartupHandler::CheckLists: Most probably this will go wrong and should therefore be fixed in the xml-file!" << endl;
char eChar[5];
for(unsigned int i(0); i<fEnergyList.size(); i++) {
sprintf(eChar, "%02.1f", fEnergyList[i]);
fEnergyLabelList.push_back(string(eChar));
}
}
// fill the energies and labels in the map
fEnergies.clear();
for(unsigned int i(0); i < fEnergyList.size(); i++) {
fEnergies[fEnergyList[i]] = fEnergyLabelList[i];
}
if(fDebug) {
cout << "Energies and Labels:" << endl;
for ( map<double, string>::const_iterator iter(fEnergies.begin()); iter != fEnergies.end(); ++iter )
cout << iter->first << " " << iter->second << endl;
}
// check if any number of steps for the theory function is specified
if(fDebug)
cout << endl << "BMWStartupHandler::CheckLists: check number of steps for theory ..." << endl;
if (!fNSteps) {
cout << "BMWStartupHandler::CheckLists: You did not specify the number of steps for the theory. Setting the default (3000)." << endl;
fNSteps = 3000;
} else {
if(fDebug)
cout << fNSteps << endl;
}
}
if (fVortex) {
// check if any number of steps for the theory function is specified
if(fDebug)
cout << endl << "BMWStartupHandler::CheckLists: check number of steps for Vortex grid ..." << endl;
if (!fGridSteps) {
cout << "BMWStartupHandler::CheckLists: You did not specify the number of steps for the grid. Setting the default (256)." << endl;
fGridSteps = 256;
} else {
if(fDebug)
cout << fGridSteps << endl;
}
}
}
// -------------------------------------------------------------------------
// end
// -------------------------------------------------------------------------

View File

@@ -0,0 +1,113 @@
/***************************************************************************
BMWStartupHandler.h
Author: Bastian M. Wojek
e-mail: bastian.wojek@psi.ch
$Id$
based upon:
PStartupHandler.h
by Andreas Suter
***************************************************************************/
/***************************************************************************
* Copyright (C) 2007-2008 by Andreas Suter, Bastian M. Wojek *
* *
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* *
* This program is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU General Public License for more details. *
* *
* You should have received a copy of the GNU General Public License *
* along with this program; if not, write to the *
* Free Software Foundation, Inc., *
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
***************************************************************************/
#ifndef _BMWSTARTUPHANDLER_H_
#define _BMWSTARTUPHANDLER_H_
#include <TList.h>
#include <TQObject.h>
#include <string>
#include <vector>
#include <map>
/**
* <p>Handles the XML musrfit startup file (BMW_startup.xml) where default settings for some plugin libraries are stored:
* - TRIM.SP data file path and energies
* - time and field resolutions for Fourier transforms
* - paths to FFTW3 wisdom files (double and float)
* - number of steps for one-dimensional theory functions (where needed)
* - number of steps for two-dimensional grids when calculating spatial field distributions in vortex lattices
* - time resolutions and lengths of Laplace transforms used in the calculation of LF-relaxation functions
* - flag for debugging the information contained in the startup file
*/
class BMWStartupHandler : public TQObject {
public:
BMWStartupHandler();
virtual ~BMWStartupHandler();
virtual void OnStartDocument(); // SLOT
virtual void OnEndDocument(); // SLOT
virtual void OnStartElement(const char*, const TList*); // SLOT
virtual void OnEndElement(const char*); // SLOT
virtual void OnCharacters(const char*); // SLOT
virtual void OnComment(const char*); // SLOT
virtual void OnWarning(const char*); // SLOT
virtual void OnError(const char*); // SLOT
virtual void OnFatalError(const char*); // SLOT
virtual void OnCdataBlock(const char*, int); // SLOT
virtual void CheckLists();
virtual const string GetDataPath() const { return fDataPath; } ///< returns the path to TRIM.SP files
virtual map<double, string> GetEnergies() const { return fEnergies; } ///< returns energies and file labels of available TRIM.SP files
virtual const double GetDeltat() const { return fDeltat; } ///< returns the time resolution of P(t) when using Fourier transforms
virtual const double GetDeltaB() const { return fDeltaB; } ///< returns the field resolution of p(B) when using Fourier transforms
virtual const string GetWisdomFile() const { return fWisdomFile; } ///< returns the path to the FFTW3 double-wisdom file
virtual const string GetWisdomFileFloat() const { return fWisdomFileFloat; } ///< returns the path to the FFTW3 float-wisdom file
virtual const unsigned int GetNSteps() const { return fNSteps; } ///< returns the number of steps in one-dimensional theory functions
virtual const unsigned int GetGridSteps() const { return fGridSteps; } ///< returns the number of steps in each direction when calculating two-dimensional spatial field distributions
virtual const double GetDeltatLF() const { return fDeltatLF; } ///< returns the time resolution of P(t) when using Laplace transforms for the calculation of LF-relaxation functions
virtual const unsigned int GetNStepsLF() const { return fNStepsLF; } ///< returns the length of the Laplace transforms for the calculation of LF-relaxation functions
virtual const bool GetDebug() const { return fDebug; } ///< true = debug the xml-entries
private:
enum EKeyWords {eEmpty, eComment, eDebug, eLEM, eVortex, eLF, eDataPath, eEnergyLabel, \
eEnergy, eEnergyList, eDeltat, eDeltaB, eWisdomFile, eWisdomFileFloat, \
eNSteps, eGridSteps, eDeltatLF, eNStepsLF};
EKeyWords fKey; ///< xml filter key
bool fDebug; ///< debug flag
bool fLEM; ///< low-energy muSR flag
bool fVortex; ///< vortex-lattice flag
bool fLF; ///< longitudinal-field flag
string fDataPath; ///< path to TRIM.SP files
vector<string> fEnergyLabelList; ///< file labels of the TRIM.SP files
vector<double> fEnergyList; ///< muon implantation energies of the TRIM.SP files
map<double, string> fEnergies; ///< muon implantation energies and file labels of the TRIM.SP files
double fDeltat; ///< time resolution of P(t) when using Fourier transforms
double fDeltaB; ///< field resolution of p(B) when using Fourier transforms
string fWisdomFile; ///< FFTW3 double-wisdom file
string fWisdomFileFloat; ///< FFTW3 float-wisdom file
unsigned int fNSteps; ///< number of steps in one-dimensional theory functions
unsigned int fGridSteps; ///< number of steps in each direction when calculating two-dimensional spatial field distributions
double fDeltatLF; ///< time resolution of P(t) when using Laplace transforms for the calculation of LF-relaxation functions
unsigned int fNStepsLF; ///< length of the Laplace transforms for the calculation of LF-relaxation functions
ClassDef(BMWStartupHandler, 1)
};
#endif // _BMWSTARTUPHANDLER_H_

View File

@@ -0,0 +1,43 @@
/***************************************************************************
BMWStartupHandlerLinkDef.h
Author: Bastian M. Wojek
e-mail: bastian.wojek@psi.ch
$Id$
***************************************************************************/
/***************************************************************************
* Copyright (C) 2009 by Bastian M. Wojek *
* *
* *
* 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. *
***************************************************************************/
// root dictionary stuff --------------------------------------------------
#ifdef __CINT__
#pragma link off all globals;
#pragma link off all classes;
#pragma link off all functions;
#pragma link C++ class BMWStartupHandler+;
#endif //__CINT__
// root dictionary stuff --------------------------------------------------

60
src/external/BMWtools/Makefile.am vendored Normal file
View File

@@ -0,0 +1,60 @@
## Process this file with automake to create Makefile.in
h_sources = \
BMWStartupHandler.h \
TTrimSPDataHandler.h \
BMWIntegrator.h
h_linkdef = \
BMWStartupHandlerLinkDef.h
dict_h_sources = \
BMWStartupHandlerDict.h
cpp_sources = \
BMWStartupHandler.cpp \
TTrimSPDataHandler.cpp \
BMWIntegrator.cpp
dict_cpp_sources = \
BMWStartupHandlerDict.cpp
include_HEADERS = $(h_sources)
noinst_HEADERS = $(h_linkdef) $(dict_h_sources)
INCLUDES = -I$(top_srcdir)/src/include $(LEM_CFLAGS) $(PMUSR_CFLAGS) $(ROOT_CFLAGS)
AM_CXXFLAGS = $(LOCAL_LIB_CXXFLAGS)
BUILT_SOURCES = $(dict_cpp_sources) $(dict_h_sources)
AM_LDFLAGS = $(LOCAL_LIB_LDFLAGS) -L@ROOTLIBDIR@
CLEANFILES = *Dict.cpp *Dict.h *~ core
%Dict.cpp %Dict.h: %.h %LinkDef.h
@ROOTCINT@ -v -f $*Dict.cpp -c -p $(INCLUDES) $^
lib_LTLIBRARIES = libBMWtools.la
libBMWtools_la_SOURCES = $(h_sources) $(cpp_sources) $(dict_h_sources) $(dict_cpp_sources)
libBMWtools_la_LIBADD = $(ROOT_LIBS)
libBMWtools_la_LDFLAGS = -version-info $(PLUGIN_LIBRARY_VERSION) -release $(PLUGIN_RELEASE) $(AM_LDFLAGS)
## For the moment do not build pkgconfig files for musrfit plug-ins...
## pkgconfigdir = $(libdir)/pkgconfig
## pkgconfig_DATA = PTFitPofB.pc
## However, create some symbolic links to the shared library
## in order to unify the function call on different operating systems
if IS_DARWIN
install-exec-hook:
$(LN_S) $(libdir)/libBMWtools.dylib $(libdir)/libBMWtools.so
uninstall-hook:
rm -f $(libdir)/libBMWtools.so
endif
if IS_CYGWIN
install-exec-hook:
$(LN_S) $(bindir)/cygBMWtools-$(PLUGIN_MAJOR_VERSION)-$(PLUGIN_MINOR_VERSION)-$(PLUGIN_MAJOR_VERSION).dll $(libdir)/libBMWtools.so
uninstall-hook:
rm -f $(libdir)/libBMWtools.so
endif

View File

@@ -0,0 +1,506 @@
/***************************************************************************
TTrimSPDataHandler.cpp
Author: Bastian M. Wojek
e-mail: bastian.wojek@psi.ch
2009/05/15
***************************************************************************/
/***************************************************************************
* Copyright (C) 2009 by Bastian M. Wojek *
* *
* *
* 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 "TTrimSPDataHandler.h"
#include <iostream>
#include <fstream>
#include <string>
#include <cmath>
#include <cassert>
#include <algorithm>
using namespace std;
//--------------------
// Constructor of the TrimSPData class -- reading all available trim.SP-rge-files with a given name into std::vectors
//--------------------
TTrimSPData::TTrimSPData(const string &path, map<double, string> &energies, bool debug) {
// sort the energies in ascending order - this might be useful for later applications (energy-interpolations etc.)
// after the change from the vector to the map this is not necessary any more - since maps are always ordered!
// sort(energies.begin(), energies.end());
double zz(0.0), nzz(0.0);
vector<double> vzz, vnzz;
string word, energyStr;
bool goodFile(false);
for ( map<double, string>::const_iterator iter(energies.begin()); iter != energies.end(); ++iter ) {
energyStr = path + iter->second + ".rge";
ifstream *rgeFile = new ifstream(energyStr.c_str());
if(! *rgeFile) {
cerr << "TTrimSPData::TTrimSPData: file " << energyStr << " not found! Try next energy..." << endl;
delete rgeFile;
rgeFile = 0;
} else {
while(*rgeFile >> word) {
if(word == "PARTICLES") {
goodFile = true;
break;
}
}
if (goodFile) {
fEnergy.push_back(iter->first);
while(!rgeFile->eof()) {
*rgeFile >> zz >> nzz;
vzz.push_back(zz);
vnzz.push_back(nzz);
}
fDZ.push_back(0.5*(vzz[2]-vzz[0])); // it happens that TRIM.SP uses different step sizes in one output file, therefore take the average
while(zz < 2100.0){
zz += fDZ.back();
vzz.push_back(zz);
vnzz.push_back(0.0);
}
fDataZ.push_back(vzz);
fDataNZ.push_back(vnzz);
rgeFile->close();
delete rgeFile;
rgeFile = 0;
vzz.clear();
vnzz.clear();
goodFile = false;
} else {
cerr << "TTrimSPData::TTrimSPData: " << energyStr << " does not seem to be a valid unmodified TRIM.SP output file!" << endl;
continue;
}
}
}
if (debug)
cout << "TTrimSPData::TTrimSPData: Read in " << fDataNZ.size() << " implantation profiles in total." << endl;
fOrigDataNZ = fDataNZ;
for(unsigned int i(0); i<fEnergy.size();++i)
fIsNormalized.push_back(false);
fEnergyIter = fEnergy.end();
}
void TTrimSPData::UseHighResolution(double e) {
fEnergyIter = find(fEnergy.begin(), fEnergy.end(), e);
if(fEnergyIter != fEnergy.end()) {
unsigned int i(fEnergyIter - fEnergy.begin());
vector<double> vecZ;
vector<double> vecNZ;
for(double zz(1.); zz<2100.; zz+=1.) {
vecZ.push_back(zz);
vecNZ.push_back(GetNofZ(zz/10.0, e));
}
fDataZ[i] = vecZ;
fDataNZ[i] = vecNZ;
fOrigDataNZ[i] = vecNZ;
fDZ[i] = 1.;
fIsNormalized[i] = false;
return;
}
cout << "TTrimSPData::DataZ: No implantation profile available for the specified energy... Nothing happens." << endl;
return;
}
//---------------------
// Method returning z-vector calculated by trim.SP for given energy[keV]
//---------------------
vector<double> TTrimSPData::DataZ(double e) const {
fEnergyIter = find(fEnergy.begin(), fEnergy.end(), e);
if(fEnergyIter != fEnergy.end()) {
unsigned int i(fEnergyIter - fEnergy.begin());
return fDataZ[i];
}
// default
cout << "TTrimSPData::DataZ: No implantation profile available for the specified energy... You get back the first one." << endl;
return fDataZ[0];
}
//---------------------
// Method returning actual n(z)-vector calculated by trim.SP and
// potentially altered by the WeightLayers- or the Normalize-method for given energy[keV]
//---------------------
vector<double> TTrimSPData::DataNZ(double e) const {
fEnergyIter = find(fEnergy.begin(), fEnergy.end(), e);
if(fEnergyIter != fEnergy.end()) {
unsigned int i(fEnergyIter - fEnergy.begin());
return fDataNZ[i];
}
// default
cout << "TTrimSPData::DataNZ: No implantation profile available for the specified energy... You get back the first one." << endl;
return fDataNZ[0];
}
//---------------------
// Method returning original n(z)-vector calculated by trim.SP for given energy[keV]
//---------------------
vector<double> TTrimSPData::OrigDataNZ(double e) const {
fEnergyIter = find(fEnergy.begin(), fEnergy.end(), e);
if(fEnergyIter != fEnergy.end()) {
unsigned int i(fEnergyIter - fEnergy.begin());
return fOrigDataNZ[i];
}
// default
cout << "TTrimSPData::OrigDataNZ: No implantation profile available for the specified energy... You get back the first one." << endl;
return fOrigDataNZ[0];
}
double TTrimSPData::DataDZ(double e) const {
fEnergyIter = find(fEnergy.begin(), fEnergy.end(), e);
if(fEnergyIter != fEnergy.end()) {
unsigned int i(fEnergyIter - fEnergy.begin());
return fDZ[i];
}
// default
cout << "TTrimSPData::DataDZ: No implantation profile available for the specified energy... The resolution will be zero!" << endl;
return 0.0;
}
//---------------------
// Method returning fraction of muons implanted in the specified layer for a given energy[keV]
// Parameters: Energy[keV], LayerNumber[1], Interfaces[nm]
//---------------------
double TTrimSPData::LayerFraction(double e, unsigned int layno, const vector<double>& interface) const {
if(layno < 1 && layno > (interface.size()+1)) {
cout << "TTrimSPData::LayerFraction: No such layer available according to your specified interfaces... Returning 0.0!" << endl;
return 0.0;
}
fEnergyIter = find(fEnergy.begin(), fEnergy.end(), e);
if(fEnergyIter != fEnergy.end()) {
unsigned int i(fEnergyIter - fEnergy.begin());
// Because we do not know if the implantation profile is normalized or not, do not care about this and calculate the fraction from the beginning
// Total "number of muons"
double totalNumber(0.0);
for(unsigned int j(0); j<fDataZ[i].size(); j++)
totalNumber += fDataNZ[i][j];
// "number of muons" in layer layno
double layerNumber(0.0);
if(!(layno-1)){
for(unsigned int j(0); j<fDataZ[i].size(); j++)
if(fDataZ[i][j] < interface[0]*10.0)
layerNumber += fDataNZ[i][j];
} else if(!(layno-interface.size()-1)){
for(unsigned int j(0); j<fDataZ[i].size(); j++)
if(fDataZ[i][j] >= *(interface.end()-1)*10.0)
layerNumber += fDataNZ[i][j];
} else {
for(unsigned int j(0); j<fDataZ[i].size(); j++)
if(fDataZ[i][j] >= interface[layno-2]*10.0 && fDataZ[i][j] < interface[layno-1]*10.0)
layerNumber += fDataNZ[i][j];
}
// fraction of muons in layer layno
// cout << "Fraction of muons in layer " << layno << ": " << layerNumber/totalNumber << endl;
return layerNumber/totalNumber;
}
// default
cout << "TTrimSPData::LayerFraction: No implantation profile available for the specified energy... Returning 0.0" << endl;
return 0.0;
}
//---------------------
// Method putting different weight to different layers of your thin film
// Parameters: Implantation Energy[keV], Interfaces[nm], Weights [0.0 <= w[i] <= 1.0]
// Example: 25.0, (50, 100), (1.0, 0.33, 1.0)
// at 25keV consider 3 layers, where the first ends after 50nm, the second after 100nm (these are NOT the layer thicknesses!!)
// the first and last layers get the full n(z), where only one third of the muons in the second layer will be taken into account
//---------------------
void TTrimSPData::WeightLayers(double e, const vector<double>& interface, const vector<double>& weight) const {
if(weight.size()-interface.size()-1) {
cout << "TTrimSPData::WeightLayers: For the weighting the number of interfaces has to be one less than the number of weights!" << endl;
cout << "TTrimSPData::WeightLayers: No weighting of the implantation profile will be done unless you take care of that!" << endl;
return;
}
for(unsigned int i(0); i<interface.size(); i++) {
if (interface[i]<0.0) {
cout << "TTrimSPData::WeightLayers: One of your layer interfaces has a negative coordinate! - No weighting will be done!" << endl;
return;
}
else if (i>1) {
if (interface[i]<interface[i-1]) {
cout << "TTrimSPData::WeightLayers: The specified interfaces appear to be not in ascending order! - No weighting will be done!" << endl;
return;
}
}
}
for(unsigned int i(0); i<weight.size(); i++) {
if (weight[i]>1.0 || weight[i]<0.0) {
cout << "TTrimSPData::WeightLayers: At least one of the specified weights is out of range - no weighting will be done!" << endl;
return;
}
}
fEnergyIter = find(fEnergy.begin(), fEnergy.end(), e);
// If all weights are equal to one, use the original n(z) vector
for(unsigned int i(0); i<weight.size(); i++) {
if(weight[i]-1.0)
break;
if(i == weight.size() - 1) {
if(fEnergyIter != fEnergy.end()) {
unsigned int j(fEnergyIter - fEnergy.begin());
fDataNZ[j] = fOrigDataNZ[j];
fIsNormalized[j] = false;
return;
}
}
}
if(fEnergyIter != fEnergy.end()) {
unsigned int i(fEnergyIter - fEnergy.begin());
unsigned int k(0);
for(unsigned int j(0); j<fDataZ[i].size(); j++) {
if(k<interface.size()) {
if(fDataZ[i][j] < interface[k]*10.0)
fDataNZ[i][j] = fOrigDataNZ[i][j]*weight[k];
else {
k++;
fDataNZ[i][j] = fOrigDataNZ[i][j]*weight[k];
}
}
else
fDataNZ[i][j] = fOrigDataNZ[i][j]*weight[k];
}
fIsNormalized[i] = false;
return;
}
cout << "TTrimSPData::WeightLayers: No implantation profile available for the specified energy... No weighting done." << endl;
return;
}
//---------------------
// Method returning n(z) for given z[nm] and energy[keV]
//---------------------
double TTrimSPData::GetNofZ(double zz, double e) const {
vector<double> z, nz;
fEnergyIter = find(fEnergy.begin(), fEnergy.end(), e);
if(fEnergyIter != fEnergy.end()) {
unsigned int i(fEnergyIter - fEnergy.begin());
z = fDataZ[i];
nz = fDataNZ[i];
} else {
cout << "TTrimSPData::GetNofZ: No implantation profile available for the specified energy... Quitting!" << endl;
exit(-1);
}
if(zz < 0)
return 0.0;
bool found = false;
unsigned int i;
for (i=0; i<z.size(); i++) {
if (z[i]/10.0 >= zz) {
found = true;
break;
}
}
if (!found)
return 0.0;
if (i == 0)
return nz[0]*10.0*zz/z[0];
return fabs(nz[i-1]+(nz[i]-nz[i-1])*(10.0*zz-z[i-1])/(z[i]-z[i-1]));
}
//---------------------
// Method normalizing the n(z)-vector calculated by trim.SP for a given energy[keV]
//---------------------
void TTrimSPData::Normalize(double e) const {
fEnergyIter = find(fEnergy.begin(), fEnergy.end(), e);
if(fEnergyIter != fEnergy.end()) {
unsigned int i(fEnergyIter - fEnergy.begin());
double nZsum = 0.0;
for (unsigned int j(0); j<fDataZ[i].size(); j++)
nZsum += fDataNZ[i][j];
nZsum *= fDZ[i];
for (unsigned int j(0); j<fDataZ[i].size(); j++)
fDataNZ[i][j] /= nZsum;
fIsNormalized[i] = true;
return;
}
// default
cout << "TTrimSPData::Normalize: No implantation profile available for the specified energy... No normalization done." << endl;
return;
}
//---------------------
// Method telling you if the n(z)-vector calculated by trim.SP for a given energy [keV] has been normalized
//---------------------
bool TTrimSPData::IsNormalized(double e) const {
fEnergyIter = find(fEnergy.begin(), fEnergy.end(), e);
if(fEnergyIter != fEnergy.end()) {
unsigned int i(fEnergyIter - fEnergy.begin());
return fIsNormalized[i];
}
cout << "TTrimSPData::IsNormalized: No implantation profile available for the specified energy... Returning false! Check your code!" << endl;
return false;
}
//---------------------
// Calculate the mean range in (nm) for a given energy e
//---------------------
double TTrimSPData::MeanRange(double e) const {
fEnergyIter = find(fEnergy.begin(), fEnergy.end(), e);
if(fEnergyIter != fEnergy.end()) {
unsigned int i(fEnergyIter - fEnergy.begin());
if (!fIsNormalized[i])
Normalize(e);
double mean(0.0);
for(unsigned int j(0); j<fDataNZ[i].size(); j++){
mean += fDataNZ[i][j]*fDataZ[i][j];
}
mean *= fDZ[i]/10.0;
return mean;
}
cout << "TTrimSPData::MeanRange: No implantation profile available for the specified energy... Returning -1! Check your code!" << endl;
return -1.;
}
//---------------------
// Find the peak range in (nm) for a given energy e
//---------------------
double TTrimSPData::PeakRange(double e) const {
fEnergyIter = find(fEnergy.begin(), fEnergy.end(), e);
if(fEnergyIter != fEnergy.end()) {
unsigned int i(fEnergyIter - fEnergy.begin());
vector<double>::const_iterator nziter;
nziter = max_element(fDataNZ[i].begin(),fDataNZ[i].end());
if(nziter != fDataNZ[i].end()){
unsigned int j(nziter - fDataNZ[i].begin());
return fDataZ[i][j]/10.0;
}
cout << "TTrimSPData::PeakRange: No maximum found in the implantation profile... Returning -1! Please check the profile!" << endl;
return -1.;
}
cout << "TTrimSPData::PeakRange: No implantation profile available for the specified energy... Returning -1! Check your code!" << endl;
return -1.;
}
//---------------------
// Convolve the n(z)-vector calculated by trim.SP for a given energy e [keV] with a gaussian exp(-z^2/(2*w^2))
// No normalization is done!
//---------------------
void TTrimSPData::ConvolveGss(double w, double e) const {
if(!w)
return;
vector<double> z, nz, gss;
double nn;
fEnergyIter = find(fEnergy.begin(), fEnergy.end(), e);
if(fEnergyIter != fEnergy.end()) {
unsigned int i(fEnergyIter - fEnergy.begin());
z = fDataZ[i];
nz = fOrigDataNZ[i];
for(unsigned int k(0); k<z.size(); k++) {
gss.push_back(exp(-z[k]*z[k]/200.0/w/w));
}
for(unsigned int k(0); k<nz.size(); k++) {
nn = 0.0;
for(unsigned int j(0); j<nz.size(); j++) {
nn += nz[j]*gss[abs(int(k)-int(j))];
}
fDataNZ[i][k] = nn;
}
fIsNormalized[i] = false;
return;
}
cout << "TTrimSPData::ConvolveGss: No implantation profile available for the specified energy... No convolution done!" << endl;
return;
}

View File

@@ -0,0 +1,83 @@
/***************************************************************************
TTrimSPDataHandler.h
Author: Bastian M. Wojek
e-mail: bastian.wojek@psi.ch
2009/05/15
***************************************************************************/
/***************************************************************************
* Copyright (C) 2009 by Bastian M. Wojek *
* *
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* *
* This program is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU General Public License for more details. *
* *
* You should have received a copy of the GNU General Public License *
* along with this program; if not, write to the *
* Free Software Foundation, Inc., *
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
***************************************************************************/
#ifndef _TTrimSPDataHandler_H_
#define _TTrimSPDataHandler_H_
#include <vector>
#include <string>
#include <map>
using namespace std;
/**
* <p>Class used to handle a set of low energy muon implantation profiles
*/
class TTrimSPData {
public:
TTrimSPData(const string&, map<double, string>&, bool debug = false);
~TTrimSPData() {
fDataZ.clear();
fDataNZ.clear();
fOrigDataNZ.clear();
fEnergy.clear();
fDZ.clear();
fIsNormalized.clear();
}
vector<double> Energy() const {return fEnergy;}
vector<double> DataZ(double) const;
vector<double> DataNZ(double) const;
vector<double> OrigDataNZ(double) const;
double DataDZ(double) const;
void UseHighResolution(double);
void WeightLayers(double, const vector<double>&, const vector<double>&) const;
double LayerFraction(double, unsigned int, const vector<double>&) const;
double GetNofZ(double, double) const;
void Normalize(double) const;
bool IsNormalized(double) const;
void ConvolveGss(double, double) const;
double MeanRange(double) const;
double PeakRange(double) const;
private:
vector<double> fEnergy; ///< vector holding all available muon energies
vector<double> fDZ; ///< vector holding the spatial resolution of the TRIM.SP output for all energies
vector< vector<double> > fDataZ; ///< discrete points in real space for which n(z) has been calculated for all energies
mutable vector< vector<double> > fDataNZ; ///< n(z) for all energies
vector< vector<double> > fOrigDataNZ; ///< original (unmodified) implantation profiles for all energies as read in from rge-files
mutable vector<bool> fIsNormalized; ///< tag indicating if the implantation profiles are normalized (for each energy separately)
mutable vector<double>::const_iterator fEnergyIter; ///< iterator traversing the vector of available energies
};
#endif // _TTrimSPDataHandler_H_