add a full dummy user function class with a global part. This can be used as a starting point to develop new polarization functions. Currently no rge-handling present.

This commit is contained in:
suter_a 2021-04-16 18:32:30 +02:00
parent f775ef3545
commit 5eed60937a
8 changed files with 444 additions and 0 deletions

View File

@ -12,6 +12,7 @@ option(nexus "build optional NeXus support. Needed for ISIS" OFF)
option(ASlibs "build optional ASlibs" OFF) option(ASlibs "build optional ASlibs" OFF)
option(BMWlibs "build optional BMWlibs" OFF) option(BMWlibs "build optional BMWlibs" OFF)
option(BNMRlibs "build optional beta-NMR libs" OFF) option(BNMRlibs "build optional beta-NMR libs" OFF)
option(DummyUserFcn "build optional dummy user function" OFF)
option(qt_based_tools "try to install Qt based tools (musredit, musrWiz, musrStep, mupp)" ON) option(qt_based_tools "try to install Qt based tools (musredit, musrWiz, musrStep, mupp)" ON)
option(try_OpenMP "try to use OpenMP if available" ON) option(try_OpenMP "try to use OpenMP if available" ON)
# define qt_version with possible values 'auto' or version '3', '4', '5', '6' # define qt_version with possible values 'auto' or version '3', '4', '5', '6'
@ -311,6 +312,9 @@ if (BNMRlibs)
else (BNMRlibs) else (BNMRlibs)
message(" BNMRlibs : no") message(" BNMRlibs : no")
endif (BNMRlibs) endif (BNMRlibs)
if (DummyUserFcn)
message(" PDummyUserFcn : yes")
endif (DummyUserFcn)
if (qt_based_tools) if (qt_based_tools)
if (Qt6Core_FOUND) if (Qt6Core_FOUND)

View File

@ -29,3 +29,7 @@ if (nexus)
add_subdirectory(nexus) add_subdirectory(nexus)
endif (nexus) endif (nexus)
if (DummyUserFcn)
add_subdirectory(DummyUserFcn)
endif (DummyUserFcn)

View File

@ -0,0 +1 @@
add_subdirectory(src)

View File

@ -0,0 +1,81 @@
/***************************************************************************
PDummyUserFcn.h
Author: Andreas Suter
e-mail: andreas.suter@psi.ch
***************************************************************************/
/***************************************************************************
* Copyright (C) 2013-2021 by Andreas Suter *
* andreas.suter@psi.ch *
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* *
* This program is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU General Public License for more details. *
* *
* You should have received a copy of the GNU General Public License *
* along with this program; if not, write to the *
* Free Software Foundation, Inc., *
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
***************************************************************************/
#ifndef _PDUMMYUSERFNC_H_
#define _PDUMMYUSERFNC_H_
#include <vector>
#include "PUserFcnBase.h"
class PDummyUserFcnGlobal
{
public:
PDummyUserFcnGlobal();
virtual ~PDummyUserFcnGlobal();
Bool_t IsValid() { return fValid; }
virtual void CalculatePol(const std::vector<Double_t> &param) const;
virtual Double_t GetPolValue(const Double_t t) const;
private:
Bool_t fValid{true};
mutable std::vector<Double_t> fPreviousParam;
mutable Double_t fTimeStep{1.0e-3}; // time in (us), time step 1 (ns) here
mutable std::vector<Double_t> fPol;
ClassDef(PDummyUserFcnGlobal, 1)
};
class PDummyUserFcn : public PUserFcnBase
{
public:
PDummyUserFcn() {}
virtual ~PDummyUserFcn();
virtual Bool_t NeedGlobalPart() const { return true; }
virtual void SetGlobalPart(std::vector<void*> &globalPart, UInt_t idx);
virtual Bool_t GlobalPartIsValid() const;
virtual Double_t operator()(Double_t t, const std::vector<Double_t> &param) const;
private:
Bool_t fValid{true};
Bool_t fInvokedGlobal{false};
Int_t fIdxGlobal;
PDummyUserFcnGlobal *fDummyUserFcnGlobal{nullptr};
// definition of the class for the ROOT dictionary
ClassDef(PDummyUserFcn, 1)
};
#endif // _PDUMMYUSERFNC_H_

View File

@ -0,0 +1,39 @@
/***************************************************************************
PDummyUserFcnLinkDef.h
Author: Andreas Suter
e-mail: andreas.suter@psi.ch
***************************************************************************/
/***************************************************************************
* Copyright (C) 2013-2021 by Andreas Suter *
* andreas.suter@psi.ch *
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* *
* This program is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU General Public License for more details. *
* *
* You should have received a copy of the GNU General Public License *
* along with this program; if not, write to the *
* Free Software Foundation, Inc., *
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
***************************************************************************/
#ifdef __CINT__
#pragma link off all globals;
#pragma link off all classes;
#pragma link off all functions;
#pragma link C++ class PDummyUserFcnGlobal+;
#pragma link C++ class PDummyUserFcn+;
#endif

View File

@ -0,0 +1,78 @@
# - DummyUserFcn library --------------------------------------------------------
#--- generate necessary dictionaries ------------------------------------------
set(MUSRFIT_INC ${CMAKE_SOURCE_DIR}/src/include)
set(DUMMY_USER_FUNC_INC ${CMAKE_CURRENT_SOURCE_DIR}/../inc)
# ROOT requires that the dictonary header files are found at configuration time.
# Hence, target_include_directories cannot be used here because, targets are
# setup only afterwards.
include_directories(${DUMMY_USER_FUNC_INC})
root_generate_dictionary(
PDummyUserFcnDict
PDummyUserFcn.h
OPTIONS
-I${FFTW3_INCLUDE_DIR}
-I${MUSRFIT_INC}
-I${DUMMY_USER_FUNC_INC}
-inlineInputHeader
LINKDEF ${DUMMY_USER_FUNC_INC}/PDummyUserFcnLinkDef.h
MODULE PDummyUserFcn
)
#--- create pkg-config info ---------------------------------------------------
set(prefix "${CMAKE_INSTALL_PREFIX}")
set(exec_prefix "\$\{prefix\}")
set(libdir "\$\{exec_prefix\}/lib")
set(includedir "\$\{prefix\}/include")
set(P_DUMMY_USER_FUNC_VERSION "1.0.0")
set(P_DUMMY_USER_FUNC_LIBRARY_NAME "PDummyUserFcn")
configure_file("PDummyUserFcn.pc.in" "PDummyUserFcn.pc" @ONLY)
#--- lib creation -------------------------------------------------------------
add_library(PDummyUserFcn SHARED
PDummyUserFcn.cpp
PDummyUserFcnDict.cxx
)
#--- set target properties, e.g. version --------------------------------------
set_target_properties(PDummyUserFcn
PROPERTIES
VERSION ${P_DUMMY_USER_FUNC_VERSION}
)
#--- make sure that the include directory is found ----------------------------
target_include_directories(
PDummyUserFcn BEFORE PRIVATE
$<BUILD_INTERFACE:${FFTW3_INCLUDE_DIR}>
$<BUILD_INTERFACE:${MUSRFIT_INC}>
$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/../inc>
)
#--- add library dependencies -------------------------------------------------
target_link_libraries(PDummyUserFcn ${FFTW3_LIBRARY} ${ROOT_LIBRARIES} PUserFcnBase)
#--- install PDummyUserFcn solib -------------------------------------------------
install(TARGETS PDummyUserFcn DESTINATION lib)
#--- install root pcm's and rootmaps ------------------------------------------
install(
FILES ${CMAKE_CURRENT_BINARY_DIR}/libPDummyUserFcn_rdict.pcm
${CMAKE_CURRENT_BINARY_DIR}/libPDummyUserFcn.rootmap
DESTINATION lib
)
#--- install PDummyUserFcn header ------------------------------------------------
install(
FILES
${CMAKE_CURRENT_SOURCE_DIR}/../inc/PDummyUserFcn.h
DESTINATION
include
)
#--- install pkg-config info --------------------------------------------------
install(
FILES ${CMAKE_CURRENT_BINARY_DIR}/PDummyUserFcn.pc
DESTINATION lib/pkgconfig
)

View File

@ -0,0 +1,227 @@
/***************************************************************************
PDummyUserFcn.cpp
Author: Andreas Suter
e-mail: andreas.suter@psi.ch
***************************************************************************/
/***************************************************************************
* Copyright (C) 2009-2021 by Andreas Suter *
* andreas.suter@psi.ch *
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* *
* This program is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU General Public License for more details. *
* *
* You should have received a copy of the GNU General Public License *
* along with this program; if not, write to the *
* Free Software Foundation, Inc., *
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
***************************************************************************/
#include <cassert>
#include <cmath>
#include <iostream>
#include <TMath.h>
#include "PDummyUserFcn.h"
ClassImp(PDummyUserFcnGlobal)
//--------------------------------------------------------------------------
// Constructor
//--------------------------------------------------------------------------
/**
* <p>Here would go all the stuff which will be needed by the global part.
* For instance specific information which come from a startup XML file.
* This could be case if muon-stopping information is needed for the
* calculation, or any other user function specific stuff which is not
* part of the parameters which will be propagated from the msr-file.
*/
PDummyUserFcnGlobal::PDummyUserFcnGlobal()
{
// nothing needed here for the dummy
}
//--------------------------------------------------------------------------
// Destructor
//--------------------------------------------------------------------------
/**
*
*/
PDummyUserFcnGlobal::~PDummyUserFcnGlobal()
{
fPreviousParam.clear();
fPol.clear();
}
//--------------------------------------------------------------------------
// CalculatePol (public)
//--------------------------------------------------------------------------
/**
* <p>Calculates the polarization function for the dummy user function.
* For the Dummy this is just an exp(-lambda t), where lambda is comming
* from the param.
*
* \param param the parameter for this user function
*/
void PDummyUserFcnGlobal::CalculatePol(const std::vector<Double_t> &param) const
{
// param: [0] lambda
// check that param is new and hence a calculation is needed
Bool_t newParams = false;
if (fPreviousParam.size() == 0) {
for (UInt_t i=0; i<param.size(); i++)
fPreviousParam.push_back(param[i]);
newParams = true;
} else {
assert(param.size() == fPreviousParam.size());
for (UInt_t i=0; i<param.size(); i++) {
if (param[i] != fPreviousParam[i]) {
newParams = true;
break;
}
}
}
if (!newParams)
return;
// keep parameters
for (UInt_t i=0; i<param.size(); i++)
fPreviousParam[i] = param[i];
// calculate the "polarization" in the time interval t = [0, 20] us
Double_t dt = fTimeStep, t = 0.0;
Int_t noOfPoints = 20.0 / dt;
fPol.resize(noOfPoints); // this makes sure that the polarization vector is long enough
for (Int_t i=0; i<noOfPoints; i++) {
t = i*dt;
fPol[i] = exp(-param[0] * i * dt);
}
}
//--------------------------------------------------------------------------
// GetMagneticField
//--------------------------------------------------------------------------
/**
*
*/
Double_t PDummyUserFcnGlobal::GetPolValue(const Double_t t) const
{
Double_t result = -1.0;
if (t < 0)
return 1.0;
if (t >= 20.0)
return 0.0;
Int_t idx = (Int_t)(t/fTimeStep);
if ((idx >=0) && (idx < fPol.size()))
result = fPol[idx];
return result;
}
//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
ClassImp(PDummyUserFcn)
//--------------------------------------------------------------------------
// Destructor
//--------------------------------------------------------------------------
/**
*
*/
PDummyUserFcn::~PDummyUserFcn()
{
if ((fDummyUserFcnGlobal != nullptr) && fInvokedGlobal) {
delete fDummyUserFcnGlobal;
fDummyUserFcnGlobal = nullptr;
}
}
//--------------------------------------------------------------------------
// SetGlobalPart (public)
//--------------------------------------------------------------------------
/**
* <p>
*
* <b>return:</b>
*
* \param globalPart
* \param idx
*/
void PDummyUserFcn::SetGlobalPart(std::vector<void*> &globalPart, UInt_t idx)
{
fIdxGlobal = static_cast<Int_t>(idx);
if ((Int_t)globalPart.size() <= fIdxGlobal) {
fDummyUserFcnGlobal = new PDummyUserFcnGlobal();
if (fDummyUserFcnGlobal == nullptr) {
fValid = false;
std::cerr << std::endl << ">> PDummyUserFcn::SetGlobalPart(): **ERROR** Couldn't invoke global user function object, sorry ..." << std::endl;
} else if (!fDummyUserFcnGlobal->IsValid()) {
fValid = false;
std::cerr << std::endl << ">> PDummyUserFcn::SetGlobalPart(): **ERROR** initialization of global user function object failed, sorry ..." << std::endl;
} else {
fValid = true;
fInvokedGlobal = true;
globalPart.resize(fIdxGlobal+1);
globalPart[fIdxGlobal] = dynamic_cast<PDummyUserFcnGlobal*>(fDummyUserFcnGlobal);
}
} else {
fValid = true;
fDummyUserFcnGlobal = (PDummyUserFcnGlobal*)globalPart[fIdxGlobal];
}
}
//--------------------------------------------------------------------------
// GlobalPartIsValid (public)
//--------------------------------------------------------------------------
/**
* <p>
*
* <b>return:</b>
*/
Bool_t PDummyUserFcn::GlobalPartIsValid() const
{
return (fValid && fDummyUserFcnGlobal->IsValid());
}
//--------------------------------------------------------------------------
// operator()
//--------------------------------------------------------------------------
/**
*
*/
Double_t PDummyUserFcn::operator()(Double_t t, const std::vector<Double_t> &param) const
{
// param: [0] lambda
assert(param.size() == 1);
// for negative time return polarization == 1
if (t <= 0.0)
return 1.0;
// calculate field if parameter have changed
fDummyUserFcnGlobal->CalculatePol(param);
// return the lookup table value
return fDummyUserFcnGlobal->GetPolValue(t);
}

View File

@ -0,0 +1,10 @@
prefix=@prefix@
exec_prefix=@exec_prefix@
libdir=@libdir@
includedir=@includedir@
Name: PDummyUserFcn
Description: C++ shared library providing the spin valve fitter class
Version: @P_DUMMY_USER_FUNC_VERSION@
Libs: -L${libdir} -l@P_DUMMY_USER_FUNC_LIBRARY_NAME@
Cflags: -I${includedir}