Commit c028382e authored by Zolnierczuk, Piotr's avatar Zolnierczuk, Piotr
Browse files

echo simulator (new) and test fixes

parent 086d90fe
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -69,6 +69,7 @@ build-ui:
clean-ui:
	@$(MAKE) -C pysen/ui clean

# ONLY WHEN MOVING BETWEEN PYQT5 AND PYQT6
rebuild-ui: clean-ui build-ui

.PHONY: all build build-dist build-ui build-docs install-user test runtest pylint clean clean-ui clean-docs distclean
+1 −0
Original line number Diff line number Diff line
@@ -5,3 +5,4 @@ echo fit/plot module
from .fit    import fit_echo_current, Spectrum            # NOQA
from .reduce import get_symmetry_phase, get_phase_indices # NOQA
from .phase_table import make_phase_table_classic         # NOQA
from .simulator import SimpleSimulator                    # NOQA
+9 −3
Original line number Diff line number Diff line
@@ -28,6 +28,7 @@ __all__ = [ "linear_fit",
            "basic_eshape",
            "gaussian_eshape",
            "flux_weighted_eshape",
            "spectrum_weighted_eshape",
            "phase_fit_local",
            "phase_fit_global",
            "echo_fit_4point",
@@ -116,6 +117,13 @@ def flux_weighted_eshape(dj, avlam, delam, flux):
    omega_avlam = outer(dj, avlam)*OMEGA_N
    return npsum(flux * sinc(omega_delam) * cos(omega_avlam), axis=-1)/npsum(flux)

def spectrum_weighted_eshape(dj, spectrum):
    """Spectrum (flux) weighted echo shape function
    dj         - field integral difference (Tm)
    spectrum   - neutron spectrum named tuple
    """
    return flux_weighted_eshape(dj, avlam=spectrum.lam, delam=spectrum.dlam, flux=spectrum.flux)

def phase_fit_local(shape_func, dj, counts, ecounts, **kwargs):
    """extract symmetry phase (local fit)
    """
@@ -265,9 +273,7 @@ def fit_echo_current(current, counts, spectrum, lam0, phase0, **kwargs):
        phase_pf,_ = fit_poly_current(current, counts, maximum=not incoherent) # max count
    dj  = np.radians(phasesens*(current  - phase0))/OMEGA_N/lam0 # convert currents to dJ
    ddj = dphase/OMEGA_N/lam0 # fit range
    sfun = partial(flux_weighted_eshape,
                   avlam=spectrum.lam, delam=spectrum.dlam, flux=spectrum.flux)

    sfun   = partial(spectrum_weighted_eshape_spectrum, spectrum=spectrum)
    dj0    = np.radians(phasesens*(phase_pf - phase0))/OMEGA_N/lam0
    res    = echo_fit(sfun, dj, counts[0], counts[1], dj0=dj0, djlim=(dj0-ddj,dj0+ddj))
    maxchi = res['chi2']
+82 −0
Original line number Diff line number Diff line
"""Echo Simulator class
"""
import numpy as np
from numpy import exp, pi

from ..config import wavelength_bandwidth
from ..constants import ANGSTROM, OMEGA_N
from ..echo.fit import Spectrum, spectrum_weighted_eshape as echo_shape

def f_exp(t, t0=1):
    "simple exponential"
    return exp(-(t/t0))

def fqt(t, coh, tcoh, inc, tinc, bgr=0):
    "F(Q,t)"
    return coh*f_exp(t,tcoh)-1/3*(inc*f_exp(t,tinc)+bgr)

MAX_PHI = 5*pi/2  # max phi   = +/- 450 degrees
DEL_PHI = pi/4    # delta phi = 45 degrees
NFINE   = 20
class SimpleSimulator():
    "simple echo simulator"
    #pylint: disable=too-many-instance-attributes
    def __init__(self, lmax=8.0, ntbins=42, pos='p2'):
        """init"""
        nsteps  = int(2*NFINE*MAX_PHI/DEL_PHI)+1
        self.dj = np.linspace(-1, 1, nsteps)*MAX_PHI/(lmax*ANGSTROM*OMEGA_N)
        self.echo  = np.zeros_like(self.dj)
        self.create_spectrum(lmax, ntbins, pos)
        self.set_intensities()
        self.stats = {}

    def create_spectrum(self, lmax=8.0, ntbins=42, pos='p2'):
        "create 'simple' spectrum"
        # fixme - lmax is set here and in the constructor
        lmin  = lmax - wavelength_bandwidth(pos=pos)
        lbin  = np.linspace(lmin,lmax,ntbins+1)*ANGSTROM # neutron wavelength bins
        lave  = (lbin[1:]+lbin[:-1])/2 # average wavelength
        dlam  = (lbin[1:]-lbin[:-1])/2 # delta-lambda
        flux  = (lave[0]/lave)**2
        self.spectrum = Spectrum(lave, dlam, flux)

    def set_intensities(self, coherent=18.0, incoherent=6.0, background=0.0, tau_coh=1.0, tau_inc=1.0):
        "set intensities"
        self.coherent   = coherent
        self.incoherent = incoherent
        self.background = background
        self.tau_coh    = tau_coh
        self.tau_inc    = tau_inc

    def f_qt(self, tau):
        "return F(Q,t)"
        updn = self.coherent + 1/3*self.incoherent - 2/3*self.incoherent
        return fqt(tau, self.coherent, self.tau_coh, self.incoherent, self.tau_inc)/updn

    def f_coh(self, tau):
        "return F_coherent(Q,t)"
        return f_exp(tau, self.tau_coh)

    def f_inc(self, tau):
        "return F_incoherent(Q,t)"
        return f_exp(tau, self.tau_inc)

    def get_echo(self, tau):
        "get echo"
        coh = self.coherent
        inc = self.incoherent
        up = coh+1/3*inc
        dn = 2/3*inc
        fr = up/dn

        ave = (up+dn)/2
        amp = (up-dn)/2
        sqt = self.f_qt(tau)/(up-dn)

        self.echo  = echo_shape(self.dj, self.spectrum)*amp + ave
        self.stats = {'amp': amp, 'ave': ave, 'up': up, 'dn': dn, 'fr': fr, 'sqt': sqt}

        return (self.dj, self.echo)


#EOF
+4 −0
Original line number Diff line number Diff line
#
"TEST INIT MODULE"
from .test_config import *
from .test_echo_fit import *
from .test_echo_flippers import *
from .test_echo_phase_table import *
from .test_echo_reduce import *
from .test_echo_simulator import *
from .test_fit import *
from .test_hardware_cryomech import *
from .test_inout_hdf import *
Loading