Loading Makefile +1 −0 Original line number Diff line number Diff line Loading @@ -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 pysen/echo/__init__.py +1 −0 Original line number Diff line number Diff line Loading @@ -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 pysen/echo/fit.py +9 −3 Original line number Diff line number Diff line Loading @@ -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", Loading Loading @@ -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) """ Loading Loading @@ -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'] Loading pysen/echo/simulator.py 0 → 100644 +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 test/__init__.py +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 Loading
Makefile +1 −0 Original line number Diff line number Diff line Loading @@ -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
pysen/echo/__init__.py +1 −0 Original line number Diff line number Diff line Loading @@ -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
pysen/echo/fit.py +9 −3 Original line number Diff line number Diff line Loading @@ -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", Loading Loading @@ -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) """ Loading Loading @@ -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'] Loading
pysen/echo/simulator.py 0 → 100644 +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
test/__init__.py +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