# Native S(q,w) Models

Takin can load S(q,w) plugins via native shared libraries (SO or DLL files). C++ examples to build upon are given in the subdirectory "examples/sqw_module".

The minimal example using the native interface to Takin is given in the following.
Header file "sqwmod.h": ``

    /**
     * S(q,w) module example
     * @author Tobias Weber
     * @date 2016
     * @license GPLv2
     */

    #ifndef __MCONV_SQW_MOD_H__
    #define __MCONV_SQW_MOD_H__

    #include "tools/monteconvo/sqwbase.h"
    #include "tlibs/math/linalg.h"

    class SqwMod : public SqwBase
    {
    	public:
    		using SqwBase::t_var;
    		using t_real = t_real_reso;
    		using t_vec = tl::ublas::vector;

    	protected:
    		// temperature for Bose factor
    		t_real m_dT = t_real(100);

    		// peak width for creation and annihilation
    		t_real m_dSigma[2] = { t_real(0.05), t_real(0.05) };
    		bool m_bUseSingleSigma = 0;

    		// S(q,E) scaling factor
    		t_real m_dS0 = t_real(1.);

    		// incoherent amplitude and width
    		t_real m_dIncAmp = t_real(0.);
    		t_real m_dIncSigma = t_real(0.05);

    		// Brillouin zone centre
    		t_vec m_vecG;

    	public:
    		SqwMod();
    		SqwMod(const std::string& strCfgFile);
    		virtual ~SqwMod();

    		virtual std::tuple, std::vector>
    			disp(t_real dh, t_real dk, t_real dl) const override;
    		virtual t_real operator()(t_real dh, t_real dk, t_real dl, t_real dE) const override;

    		virtual std::vector GetVars() const override;
    		virtual void SetVars(const std::vector&) override;
    		virtual bool SetVarIfAvail(const std::string& strKey, const std::string& strNewVal) override;

    		virtual SqwBase* shallow_copy() const override;
    };
    #endif

C++ implementation file "sqwmod.cpp": `

    /**
     * S(q,w) module example
     * @author Tobias Weber
     * @date 2016
     * @license GPLv2
     *
     * compile with:
     * g++ -std=c++11 -I. -shared -fPIC -o plugins/sqwmod.so sqwmod.cpp tools/monteconvo/sqwbase.cpp tlibs/log/log.cpp
     */

    #include "sqwmod.h"

    #include "libs/version.h"
    #include "tlibs/string/string.h"
    #include "tlibs/math/math.h"
    #include "tlibs/phys/neutrons.h"

    #include

    using t_real = typename SqwMod::t_real;

    // ----------------------------------------------------------------------------
    // constructors

    SqwMod::SqwMod() : m_vecG(tl::make_vec({1,0,0}))
    {
    	SqwBase::m_bOk = 1;
    }

    SqwMod::SqwMod(const std::string& strCfgFile) : SqwMod()
    {
    	tl::log_info("Config file: \"", strCfgFile, "\".");
    	SqwBase::m_bOk = 1;
    }

    SqwMod::~SqwMod()
    {
    }

    // ----------------------------------------------------------------------------
    // dispersion, spectral weight and structure factor

    std::tuple, std::vector>
    	SqwMod::disp(t_real dh, t_real dk, t_real dl) const
    {
    	t_real dEp = 0;		// energy (boson creation)
    	t_real dwp = 1;		// spectral weight (boson creation)
    	t_real dEm = -dEp;	// energy (boson annihilation)
    	t_real dwm = dwp;	// spectral weight (boson annihilation)

    	// TODO: calculate dispersion relation

    	return std::make_tuple(std::vector({dEp, dEm}),
    		std::vector({dwp, dwm}));
    }

    t_real SqwMod::operator()(t_real dh, t_real dk, t_real dl, t_real dE) const
    {
    	t_real dcut = t_real(0.02);

    	std::vector vecE, vecW;
    	std::tie(vecE, vecW) = disp(dh, dk, dl);

    	t_real dInc=0, dS_p=0, dS_m=0;
    	if(!tl::float_equal(m_dIncAmp, t_real(0)))
    		dInc = tl::gauss_model(dE, t_real(0), m_dIncSigma, m_dIncAmp, t_real(0));

    	t_real dS = 0;
    	for(std::size_t iE=0; iE SqwMod::GetVars() const
    {
    	std::vector vecVars;

    	vecVars.push_back(SqwBase::t_var{"T", "real", tl::var_to_str(m_dT)});
    	vecVars.push_back(SqwBase::t_var{"sigma_create", "real", tl::var_to_str(m_dSigma[0])});
    	vecVars.push_back(SqwBase::t_var{"sigma_annihilate", "real", tl::var_to_str(m_dSigma[1])});
    	vecVars.push_back(SqwBase::t_var{"single_sigma", "bool", tl::var_to_str(m_bUseSingleSigma)});
    	vecVars.push_back(SqwBase::t_var{"inc_amp", "real", tl::var_to_str(m_dIncAmp)});
    	vecVars.push_back(SqwBase::t_var{"inc_sigma", "real", tl::var_to_str(m_dIncSigma)});
    	vecVars.push_back(SqwBase::t_var{"S0", "real", tl::var_to_str(m_dS0)});
    	vecVars.push_back(SqwBase::t_var{"G", "vector", vec_to_str(m_vecG)});

    	return vecVars;
    }

    void SqwMod::SetVars(const std::vector& vecVars)
    {
    	if(!vecVars.size()) return;

    	for(const SqwBase::t_var& var : vecVars)
    	{
    		const std::string& strVar = std::get<0>(var);
    		const std::string& strVal = std::get<2>(var);

    		if(strVar == "T") m_dT = tl::str_to_var(strVal);
    		else if(strVar == "sigma_create") m_dSigma[0] = tl::str_to_var(strVal);
    		else if(strVar == "sigma_annihilate") m_dSigma[1] = tl::str_to_var(strVal);
    		else if(strVar == "single_sigma") m_bUseSingleSigma = tl::str_to_var(strVal);
    		else if(strVar == "inc_amp") m_dIncAmp = tl::str_to_var(strVal);
    		else if(strVar == "inc_sigma") m_dIncSigma = tl::str_to_var(strVal);
    		else if(strVar == "S0") m_dS0 = tl::str_to_var(strVal);
    		else if(strVar == "G") m_vecG = str_to_vec(strVal);
    	}
    }

    bool SqwMod::SetVarIfAvail(const std::string& strKey, const std::string& strNewVal)
    {
    	return SqwBase::SetVarIfAvail(strKey, strNewVal);
    }

    // ----------------------------------------------------------------------------
    // copy

    SqwBase* SqwMod::shallow_copy() const
    {
    	SqwMod *pMod = new SqwMod();

    	pMod->m_dT = this->m_dT;
    	pMod->m_dSigma[0] = this->m_dSigma[0];
    	pMod->m_dSigma[1] = this->m_dSigma[1];
    	pMod->m_bUseSingleSigma = this->m_bUseSingleSigma;
    	pMod->m_dIncAmp = this->m_dIncAmp;
    	pMod->m_dIncSigma = this->m_dIncSigma;
    	pMod->m_vecG = this->m_vecG;
    	pMod->m_dS0 = this->m_dS0;

    	return pMod;
    }

    // ----------------------------------------------------------------------------
    // SO interface

    static const char* pcModIdent = "tstmod";
    static const char* pcModName = "Test Module";

    std::tuple sqw_info()
    {
    	tl::log_info("In ", __func__, ".");

    	return std::make_tuple(TAKIN_VER, pcModIdent, pcModName);
    }

    std::shared_ptr sqw_construct(const std::string& strCfgFile)
    {
    	tl::log_info("In ", __func__, ".");

    	return std::make_shared(strCfgFile);
    }

    // exports from so file
    BOOST_DLL_ALIAS(sqw_info, takin_sqw_info);
    BOOST_DLL_ALIAS(sqw_construct, takin_sqw);

`