From 5eed60937a0705bcdf330973d4ca5ecd5dab0feb Mon Sep 17 00:00:00 2001 From: Andreas Suter Date: Fri, 16 Apr 2021 18:32:30 +0200 Subject: [PATCH] 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. --- CMakeLists.txt | 4 + src/external/CMakeLists.txt | 4 + src/external/DummyUserFcn/CMakeLists.txt | 1 + src/external/DummyUserFcn/inc/PDummyUserFcn.h | 81 +++++++ .../DummyUserFcn/inc/PDummyUserFcnLinkDef.h | 39 +++ src/external/DummyUserFcn/src/CMakeLists.txt | 78 ++++++ .../DummyUserFcn/src/PDummyUserFcn.cpp | 227 ++++++++++++++++++ .../DummyUserFcn/src/PDummyUserFcn.pc.in | 10 + 8 files changed, 444 insertions(+) create mode 100644 src/external/DummyUserFcn/CMakeLists.txt create mode 100644 src/external/DummyUserFcn/inc/PDummyUserFcn.h create mode 100644 src/external/DummyUserFcn/inc/PDummyUserFcnLinkDef.h create mode 100644 src/external/DummyUserFcn/src/CMakeLists.txt create mode 100644 src/external/DummyUserFcn/src/PDummyUserFcn.cpp create mode 100644 src/external/DummyUserFcn/src/PDummyUserFcn.pc.in diff --git a/CMakeLists.txt b/CMakeLists.txt index 57c6539b..917ec3fa 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -12,6 +12,7 @@ option(nexus "build optional NeXus support. Needed for ISIS" OFF) option(ASlibs "build optional ASlibs" OFF) option(BMWlibs "build optional BMWlibs" 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(try_OpenMP "try to use OpenMP if available" ON) # define qt_version with possible values 'auto' or version '3', '4', '5', '6' @@ -311,6 +312,9 @@ if (BNMRlibs) else (BNMRlibs) message(" BNMRlibs : no") endif (BNMRlibs) +if (DummyUserFcn) + message(" PDummyUserFcn : yes") +endif (DummyUserFcn) if (qt_based_tools) if (Qt6Core_FOUND) diff --git a/src/external/CMakeLists.txt b/src/external/CMakeLists.txt index b49e90e2..cb76d6b9 100644 --- a/src/external/CMakeLists.txt +++ b/src/external/CMakeLists.txt @@ -29,3 +29,7 @@ if (nexus) add_subdirectory(nexus) endif (nexus) +if (DummyUserFcn) + add_subdirectory(DummyUserFcn) +endif (DummyUserFcn) + diff --git a/src/external/DummyUserFcn/CMakeLists.txt b/src/external/DummyUserFcn/CMakeLists.txt new file mode 100644 index 00000000..febd4f0a --- /dev/null +++ b/src/external/DummyUserFcn/CMakeLists.txt @@ -0,0 +1 @@ +add_subdirectory(src) diff --git a/src/external/DummyUserFcn/inc/PDummyUserFcn.h b/src/external/DummyUserFcn/inc/PDummyUserFcn.h new file mode 100644 index 00000000..e3a2f2bd --- /dev/null +++ b/src/external/DummyUserFcn/inc/PDummyUserFcn.h @@ -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 + +#include "PUserFcnBase.h" + +class PDummyUserFcnGlobal +{ + public: + PDummyUserFcnGlobal(); + virtual ~PDummyUserFcnGlobal(); + + Bool_t IsValid() { return fValid; } + virtual void CalculatePol(const std::vector ¶m) const; + virtual Double_t GetPolValue(const Double_t t) const; + + private: + Bool_t fValid{true}; + + mutable std::vector fPreviousParam; + + mutable Double_t fTimeStep{1.0e-3}; // time in (us), time step 1 (ns) here + mutable std::vector fPol; + + ClassDef(PDummyUserFcnGlobal, 1) +}; + +class PDummyUserFcn : public PUserFcnBase +{ + public: + PDummyUserFcn() {} + virtual ~PDummyUserFcn(); + + virtual Bool_t NeedGlobalPart() const { return true; } + virtual void SetGlobalPart(std::vector &globalPart, UInt_t idx); + virtual Bool_t GlobalPartIsValid() const; + + virtual Double_t operator()(Double_t t, const std::vector ¶m) 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_ diff --git a/src/external/DummyUserFcn/inc/PDummyUserFcnLinkDef.h b/src/external/DummyUserFcn/inc/PDummyUserFcnLinkDef.h new file mode 100644 index 00000000..35daaa58 --- /dev/null +++ b/src/external/DummyUserFcn/inc/PDummyUserFcnLinkDef.h @@ -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 diff --git a/src/external/DummyUserFcn/src/CMakeLists.txt b/src/external/DummyUserFcn/src/CMakeLists.txt new file mode 100644 index 00000000..ec094a68 --- /dev/null +++ b/src/external/DummyUserFcn/src/CMakeLists.txt @@ -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 + $ + $ + $ +) + +#--- 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 +) + diff --git a/src/external/DummyUserFcn/src/PDummyUserFcn.cpp b/src/external/DummyUserFcn/src/PDummyUserFcn.cpp new file mode 100644 index 00000000..8048efba --- /dev/null +++ b/src/external/DummyUserFcn/src/PDummyUserFcn.cpp @@ -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 +#include + +#include + +#include + +#include "PDummyUserFcn.h" + + +ClassImp(PDummyUserFcnGlobal) + +//-------------------------------------------------------------------------- +// Constructor +//-------------------------------------------------------------------------- +/** + *

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) +//-------------------------------------------------------------------------- +/** + *

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 ¶m) 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= 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) +//-------------------------------------------------------------------------- +/** + *

+ * + * return: + * + * \param globalPart + * \param idx + */ +void PDummyUserFcn::SetGlobalPart(std::vector &globalPart, UInt_t idx) +{ + fIdxGlobal = static_cast(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(fDummyUserFcnGlobal); + } + } else { + fValid = true; + fDummyUserFcnGlobal = (PDummyUserFcnGlobal*)globalPart[fIdxGlobal]; + } +} + +//-------------------------------------------------------------------------- +// GlobalPartIsValid (public) +//-------------------------------------------------------------------------- +/** + *

+ * + * return: + */ +Bool_t PDummyUserFcn::GlobalPartIsValid() const +{ + return (fValid && fDummyUserFcnGlobal->IsValid()); +} + +//-------------------------------------------------------------------------- +// operator() +//-------------------------------------------------------------------------- +/** + * + */ +Double_t PDummyUserFcn::operator()(Double_t t, const std::vector ¶m) 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); +} diff --git a/src/external/DummyUserFcn/src/PDummyUserFcn.pc.in b/src/external/DummyUserFcn/src/PDummyUserFcn.pc.in new file mode 100644 index 00000000..37ac7645 --- /dev/null +++ b/src/external/DummyUserFcn/src/PDummyUserFcn.pc.in @@ -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}