def test_get_adaptive_integration_grid(): ### Lines LL1 = LorentzianLine("LL1", (-energy_from_lambda(6.0), 15), x0=0.048, width=0.04, c=0.0, weight=0.0) F_c = F_cLine("F_c1", (-energy_from_lambda(6.0), 15), x0=0.0, width=0.02, A=350.0, q=0.02, c=0.0, weight=1) F_I = F_ILine("F_I1", (-energy_from_lambda(6.0), 15), x0=-0.02, width=0.008, A=350.0, q=0.02, kappa=0.01, c=0.0, weight=1) ### CalcStrategy inel = InelasticCalcStrategy(610) quasi = QuasielasticCalcStrategy()
def test_domain_enforcement_visually(): Lorentzian_short = LorentzianLine("Lorentzian_short", (-energy_from_lambda(6.0 * 0.88), 15), x0=-0.3, width=0.5, c=0.2) Lorentzian_mid = LorentzianLine("Lorentzian_mid", (-energy_from_lambda(6.0), 15), x0=-0.3, width=0.5, c=0.2) Lorentzian_long = LorentzianLine("Lorentzian_long", (-energy_from_lambda(6.0 * 1.12), 15), x0=-0.3, width=0.5, c=0.2) e = np.linspace(-10.0, 20.0, 1201) plt.plot(e, Lorentzian_short(e)) plt.plot(e, Lorentzian_mid(e), ls="--", lw=2.0) plt.plot(e, Lorentzian_long(e), ls="dotted", lw=4.0)
def test_DetectorEfficiency_cancel(): # We need some lines L1 = LorentzianLine("Lorentzian1", (-5.0, 5.0), x0=0.0, width=0.4, c=0.0, weight=2) L2 = LorentzianLine(name="Lorentzian2", domain=(-5.0, 5.0), x0=-1.0, width=0.4, c=0.02, weight=1) # Contruct a SqE model sqe = SqE(lines=(L1, L2), lam=6.0, dlam=0.12, lSD=3.43, T=20) new_domain = (-1 * energy_from_lambda(6.0), UPPER_INTEGRATION_LIMIT) sqe.update_domain(new_domain) # init energycutoff decf = DetectorEfficiencyCorrectionFactor(sqe, ne=10, nlam=5) ee, ll = energy_lambda_nrange(15.0, 6.0, 0.12, 10000, 20) # print(detector_efficiency(ee, ll, 1) * decf(ee, ll)) print( trapz(trapz(decf(ee, ll) * decf.legacy_calc(ee, ll, 0), ee, axis=0), ll[0])) # print(trapz(trapz(ones(ll.shape), ee, axis=0), ll[0])) print(trapz(trapz(decf.legacy_calc(ee, ll, 1), ee, axis=0), ll[0])) print(trapz(trapz(decf.legacy_calc(ee, ll, 0), ee, axis=0), ll[0])) print( trapz( trapz(decf.legacy_calc(ee, ll, 0), ee, axis=0) / trapz(trapz(decf.legacy_calc(ee, ll, 1), ee, axis=0), ll[0]), ll[0]))
def test_sqe_normalization(): # We need some lines L1 = LorentzianLine("Lorentzian1", (-5.0, 5.0), x0=0.0, width=0.4, c=0.0, weight=2) L2 = LorentzianLine(name="Lorentzian2", domain=(-5.0, 5.0), x0=-1.0, width=0.4, c=0.02, weight=1) # Contruct a SqE model sqe = SqE(lines=(L1, L2), lam=6.0, dlam=0.12, l_SD=3.43, T=20) new_domain = (-1 * energy_from_lambda(6.0), UPPER_INTEGRATION_LIMIT) sqe.update_domain(new_domain) # integrate over domain from scipy.integrate import quad to_integrate = lambda x: sqe(x) valdom, errdom = quad(to_integrate, *new_domain) valover, errover = quad(to_integrate, -15, 20) print( f"Integration value over domain from {new_domain[0]:.5f} to {UPPER_INTEGRATION_LIMIT}: {valdom:.5f} +- {errdom:.5f}" ) # | normalization factor: {n:.5f}") print( f"Integration value beyond domain from -15.0 to 20.0: {valover:.5f} +- {errover:.5f}" )
def test_transformer_init(): ### Creating a SqE model for transformation # We need some lines L1 = LorentzianLine("Lorentzian1", (-5.0, 5.0), x0=0.0, width=0.4, c=0.0, weight=2) L2 = LorentzianLine(name="Lorentzian2", domain=(-5.0, 5.0), x0=-1.0, width=0.4, c=0.0, weight=1) L3 = F_ILine("FI1", (-energy_from_lambda(6.0), 15), x0=-0.1, width=0.008, A=350.0, q=0.02, kappa=0.01, c=0.0, weight=1) # Contruct a SqE model sqe1 = SqE(lines=(L2, ), lam=6.0, dlam=0.12, lSD=3.43, T=20) sqe2 = SqE(lines=(L1, L2, L3), lam=6.0, dlam=0.12, lSD=3.43, T=20) ### Instantiate a transformer SqtTransformer(sqe2, nlam=20, ne=10000)
def test_manualtransform_arg_model(): ### Creating a SqE model for transformation sqe_arg = SqE_from_arg(T=20.) ### Creating energy, wavelength parameter space lam = sqe_arg.model_params["lam"] dlam = sqe_arg.model_params["dlam"] nlam = 5 #20 ne = 10 #15000 lSD = 3.43 l = linspace(1 - dlam * 1.01, 1 + dlam * 1.01, nlam) * lam ll = tile(l, (ne, 1)) a = -0.99999 * energy_from_lambda(l) ee = linspace(a, 15.0, ne) ### Values for transformation taus = logspace(-6, -1, 101) freqs = MIEZE_DeltaFreq_from_time(taus * 1.0e-9, 3.43, 6.0) mieze_phase = MIEZE_phase(ee, freqs[30], lSD, ll) det_eff = detector_efficiency(ee, ll, 1) tri_distr = triangle_distribution(ll, lam, dlam) print(ll) print(ee) print(mieze_phase) print(det_eff) print(tri_distr)
def test_export_load(): ### Creating a SqE model for transformation # We need some lines L1 = LorentzianLine("Lorentzian1", (-5.0, 5.0), x0=0.0, width=0.00005, c=0.0, weight=0.1) L2 = F_ILine("FI1", (-energy_from_lambda(6.0), 15), x0=-0.01, width=0.008, A=350.0, q=0.02, kappa=0.01, c=0.0, weight=0.9) # Contruct a SqE model sqe = SqE(lines=(L1, L2), lam=6.0, dlam=0.12, lSD=3.43, T=628) # Add the detector efficiency correction decf = DetectorEfficiencyCorrectionFactor(sqe, ne=500, nlam=20) # Add the energycutoff correction eccf = EnergyCutOffCorrectionFactor(sqe, ne=500, nlam=20) ### Instantiate a transformer sqt = SqtTransformer(sqe, corrections=(decf, eccf), nlam=20, ne=500, lSD=3.43, integ_mode="adaptive") ### Export sqt_dict = sqt.export_to_dict() pprint(sqt_dict["corrections"]) sqt.export_to_jsonfile( f"{testdir}/resources/test_transformer_export_load_file.json") print("", "SqE's of the: ", f"- sqe: {sqe}", f"- decf: {decf.sqe}", f"- eccf: {eccf.sqe}", f"- sqt: {sqt.sqemodel}", sep="\n") ### Loading sqt_from_dict = sqt.load_from_dict(**sqt_dict) print("", "Loading successful: ", sqt, sqt_from_dict, sep='\n') sqt_from_file = sqt.load_from_jsonfile( f"{testdir}/resources/test_transformer_export_load_file.json") print("Loading successful: ", sqt, sqt_from_file, sep='\n') print("", "SqE's of the: ", f"- sqe: {sqe}", f"- decf: {sqt_from_dict.corrections[0].sqe}", f"- eccf: {sqt_from_dict.corrections[1].sqe}", f"- sqt: {sqt_from_dict.sqemodel}", sep="\n") print("\n\nThis is the sqt loaded from dict") pprint(sqt_from_file.export_to_dict())
def test_DetectorEfficiencyCorrectionFactor_compare_with_arg(): # We need some lines L1 = LorentzianLine(name="Lorentzian1", domain=(-16.0, 16.0), x0=-1.0, width=0.4, c=0.0, weight=1) # Contruct a SqE model sqe = SqE(lines=(L1, ), lam=6.0, dlam=0.12, lSD=3.43, T=20) # Instantiate a detector efficiency corr factor decf = DetectorEfficiencyCorrectionFactor(sqe) ne = 15000 nlam = 20 lam = 6.0 * linspace(1 - 0.12 * 1.01, 1 + 0.12 * 1.01, nlam) lams = tile(lam, (ne, 1)) a = -0.99999 * energy_from_lambda(lam) b = 15.0 + a es = linspace(a, b, ne) test_decf_val = arg.DetFac_Eint_lamInt(arg.fqe_I, -1.0, 0.4, 15000, 20, 6.0, 0.12, 1, 0.0, 1.0, 20, 0.5, 0.00001, 350.) decf_val_man_int = decf(es, lams) decf_val = decf.correction(es, lams) print("arg res: ", test_decf_val) print("class calc res manualy integrated: ", decf_val_man_int) print("class res: ", decf_val)
def test_correctionFactor_dimensionality(): # We need some lines L1 = LorentzianLine(name="Lorentzian1", domain=(-16.0, 16.0), x0=-1.0, width=0.4, c=0.0, weight=1) # Contruct a SqE model sqe = SqE(lines=(L1, ), lam=6.0, dlam=0.12, lSD=3.43, T=20) # Instantiate a detector efficiency corr factor decf = DetectorEfficiencyCorrectionFactor(sqe) # Instantiate a energy cutoff corr factor eccf = EnergyCutOffCorrectionFactor(sqe) ne = 15 nlam = 5 lam = 6.0 * linspace(1 - 0.12 * 1.01, 1 + 0.12 * 1.01, nlam) lams = tile(lam, (ne, 1)) a = -0.99999 * energy_from_lambda(lam) b = 15.0 + a es = linspace(a, b, ne) print(lams) print(es) print(decf.calc(es, lams)) print(eccf.calc(es, lams))
def test_export_load(): # We need some lines L1 = LorentzianLine("Lorentzian1", (-5.0, 5.0), x0=0.0, width=0.4, c=0.0, weight=2) L2 = LorentzianLine(name="Lorentzian2", domain=(-5.0, 5.0), x0=-1.0, width=0.4, c=0.02, weight=1) # Contruct a SqE model sqe = SqE(lines=(L1, L2), lam=6.0, dlam=0.12, lSD=3.43, T=20) new_domain = (-1 * energy_from_lambda(6.0), UPPER_INTEGRATION_LIMIT) sqe.update_domain(new_domain) # init energycutoff decf = DetectorEfficiencyCorrectionFactor(sqe, ne=10000, nlam=20) # exports corrdict = decf.export_to_dict() decf.export_to_jsonfile( f"{testdir}/resources/test_correction_export_load_file.json") # loading decf_from_dict = decf.load_from_dict(**corrdict) print(decf_from_dict.export_to_dict()) print("", "Loading successful: ", decf, decf_from_dict, sep='\n') decf_from_jsonfile = decf.load_from_jsonfile( f"{testdir}/resources/test_correction_export_load_file.json") print("Loading successful: ", decf, decf_from_jsonfile, sep='\n')
def test_EnergyCutOffCorrectionFactor_vs_arg(): # We need some lines L1 = LorentzianLine(name="Lorentzian1", domain=(-16.0, 16.0), x0=-1.0, width=0.4, c=0.0, weight=1) # Contruct a SqE model sqe = SqE(lines=(L1, ), lam=6.0, dlam=0.12, lSD=3.43, T=20) # Instantiate a energy cutoff corr factor eccf = EnergyCutOffCorrectionFactor(sqe) ne = 15000 nlam = 20 lam = 6.0 * linspace(1 - 0.12 * 1.01, 1 + 0.12 * 1.01, nlam) lams = tile(lam, (ne, 1)) a = -0.99999 * energy_from_lambda(lam) b = 15.0 + a es = linspace(a, b, ne) test_eccf_vals = arg.CutFac_Eint(arg.lorentzian, -1.0, 0.4, 15000, 20, 6.0, 0.12, 1, 0.0, 1.0, 20, 0.5, 0.00001, 350.) eccf_vals = eccf.correction(es, lams) # print(test_eccf_vals.shape) print(test_eccf_vals) # print(eccf_vals.shape) print(eccf_vals)
def visualize_Lines(): Lorentzian = LorentzianLine("Lorentzian1", (-energy_from_lambda(6.0), 15), x0=-0.3, width=0.5, c=0.0) F_c = F_cLine("F_c1", (-energy_from_lambda(6.0), 15), x0=-0.3, width=0.5, A=350.0, q=0.02, c=0.0, weight=1) F_I = F_ILine("F_I1", (-energy_from_lambda(6.0), 15), x0=-0.3, width=0.008, A=350.0, q=0.02, kappa=0.01, c=0.0, weight=1) print(F_I.integrate()) F_I2 = F_ILine("F_I2", (-energy_from_lambda(6.0), 15), x0=-0.3, width=0.1, A=367.0, q=0.124, kappa=0.065, c=0.0, weight=1) print(F_I2.integrate()) e = np.linspace(-0.5, 0.0, 1201) plt.plot(e, Lorentzian(e)) plt.plot(e, F_c(e) * F_c.normalize(), ls="--", lw=2.0) plt.plot(e, F_I(e), ls="dotted", lw=4.0) plt.plot(e, F_I2(e), ls="-.", lw=1.0) plt.show()
def test_from_transformer(): ### Creating a SqE model for transformation # We need some lines L1 = LorentzianLine("Lorentzian1", (-5.0, 5.0), x0=0.0, width=0.4, c=0.0, weight=1) L2 = LorentzianLine(name="Lorentzian2", domain=(-5.0, 5.0), x0=1.5, width=0.4, c=0.0, weight=2) L3 = F_ILine("FI1", (-energy_from_lambda(6.0), 15), x0=-0.1, width=0.008, A=350.0, q=0.02, kappa=0.01, c=0.0, weight=1) # Contruct a SqE model sqe1 = SqE((L1, L2, L3), lam=6.0, dlam=0.12, lSD=3.43, T=20) ### Instantiate a transformer sqt1 = SqtTransformer(sqe1, corrections=(DetectorEfficiencyCorrectionFactor( sqe1, ne=10000, nlam=20), ), ne=10000, nlam=20, lSD=3.43) ### Values for transformation datataus = array([ 2.0e-6, 6.0e-6, 4.1e-5, 2.5e-4, 5.5e-4, 1.0e-3, 1.32e-3, 1.7e-3, 2.2e-3, 2.63e-3, 2.77e-3, 3.3e-3, 4.27e-3, 5.11e-3, 6.77e-3, 8.96e-3, 2.0e-2 ]) x = MIEZE_DeltaFreq_from_time(datataus * 1.0e-9, 3.43, 6.0) ### create artificial data via TRANSFORM!! y = array([sqt1(freq) for freq in x]) yerr = 0.02 * random.randn(len(y)) ### instntiate Minuit obj! m = FitModelCreator.from_transformer(sqt1, x, y + yerr, yerr, [ 0.45, 0.0, 1.2, -1.5, 0.3, 0.0, 2.2, -0.5, 0.01, 350.0, 0.02, 0.01, 0.0, 1.0 ])
def test_update_params(): ### Creating a SqE model for transformation # We need some lines L1 = LorentzianLine("Lorentzian1", (-5.0, 5.0), x0=0.0, width=0.4, c=0.0, weight=2) L2 = LorentzianLine(name="Lorentzian2", domain=(-5.0, 5.0), x0=-1.0, width=0.4, c=0.0, weight=1) L3 = F_ILine("FI1", (-energy_from_lambda(6.0), 15), x0=-0.1, width=0.008, A=350.0, q=0.02, kappa=0.01, c=0.0, weight=1) # Contruct a SqE model sqe = SqE(lines=(L1, L2, L3), lam=6.0, dlam=0.12, lSD=3.43, T=20) # Add the detector efficiency correction decf = DetectorEfficiencyCorrectionFactor(sqe, ne=10000, nlam=20) # Add the energycutoff correction eccf = EnergyCutOffCorrectionFactor(sqe, ne=10000, nlam=20) ### Instantiate a transformer sqt = SqtTransformer(sqe, corrections=(decf, eccf), nlam=20, ne=10000, lSD=3.43) print("\n\nBefore update:") pprint(sqt.export_to_dict()) tdict = dict(T=30, lam=8.0, x0_Lorentzian2=-0.5, width_Lorentzian2=0.025, weight_Lorentzian1=5, nlam=55, kappa_FI1=1.0, some_wired_param=True) sqt.update_params(**tdict) print("\n\nAfter update:") pprint(sqt.export_to_dict())
def test_DetectorEfficiencyCorrectionFactor(): # We need some lines L1 = LorentzianLine("Lorentzian1", (-5.0, 5.0), x0=0.0, width=0.4, c=0.0, weight=2) L2 = LorentzianLine(name="Lorentzian2", domain=(-5.0, 5.0), x0=-1.0, width=0.4, c=0.02, weight=1) # Contruct a SqE model sqe = SqE(lines=(L1, L2), lam=6.0, dlam=0.12, lSD=3.43, T=20) # Instantiate a detector efficiency corr factor decf = DetectorEfficiencyCorrectionFactor(sqe) ne = 10 nlam = 5 lam = 6.0 * linspace(1 - 0.12 * 1.01, 1 + 0.12 * 1.01, nlam) lams = tile(lam, (ne, 1)) a = -0.99999 * energy_from_lambda(lam) b = 15.0 + a es = linspace(a, b, ne) deteff = detector_efficiency(es, lams, 1) tria = triangle_distribution(lams, 6.0, 0.12) print("Triangular wavelenght distr.: ", tria) print("Triangular wavelength distr. shape: ", tria.shape) print("Det. eff. values: ", deteff) print("Det. eff. values shape: :", deteff.shape) sqevals = sqe(es) print("Manual mult.: ", sqevals * deteff * tria) print("Class result: ", decf(es, lams)) print("Are manual and deteffcorrfac identical?: ", all((sqevals * deteff * tria) == decf(es, lams)))
def test_transformer_basics(): ### Creating a SqE model for transformation # We need some lines L1 = LorentzianLine(name="Lorentzian1", domain=(-15.0, 15.0), x0=-1.0, width=0.4, c=0.0, weight=3) L3 = F_ILine("FI1", (-energy_from_lambda(6.0), 15), x0=-0.1, width=0.008, A=350.0, q=0.02, kappa=0.01, c=0.0, weight=1) # Contruct a SqE model sqe1 = SqE(lines=(L1, L3), lam=6.0, dlam=0.12, lSD=3.43, T=20) ### Instantiate a transformer sqt1 = SqtTransformer(sqe1, corrections=(DetectorEfficiencyCorrectionFactor( sqe1, ne=15000, nlam=20), ), ne=15000, nlam=20, lSD=3.43) ### Values for transformation taus = logspace(-6, -1, 11) freqs = MIEZE_DeltaFreq_from_time(taus * 1.0e-9, 3.43, 6.0) ### TRANSFORM!! sqt1vals = [sqt1(freq) for freq in freqs] sqt1vals_arg = arg.Sqt(arg.fqe_I, freqs, -1.0, 0.4, 15000, 20, 3.43, 6.0, 0.12, 0.0, 1.0, 20, 0.00005, 0.1, 350.)
def test_EnergyCutoffCorrectionFactor(): # We need some lines L1 = LorentzianLine("Lorentzian1", (-5.0, 5.0), x0=0.0, width=0.4, c=0.0, weight=2) L2 = LorentzianLine(name="Lorentzian2", domain=(-5.0, 5.0), x0=-1.0, width=0.4, c=0.02, weight=1) # Contruct a SqE model sqe = SqE(lines=(L1, L2), lam=6.0, dlam=0.12, lSD=3.43, T=20) new_domain = (-1 * energy_from_lambda(6.0), UPPER_INTEGRATION_LIMIT) sqe.update_domain(new_domain) # init energycutoff eccf = EnergyCutOffCorrectionFactor(sqe, ne=10000, nlam=20) ne = 10000 nlam = 5 lam = 6.0 * linspace(1 - 0.12 * 1.01, 1 + 0.12 * 1.01, nlam) lams = tile(lam, (ne, 1)) a = -0.99999 * energy_from_lambda(lam) b = 15.0 + a es = linspace(a, b, ne) ### Calculate the trapz integral over the S(q,E) # Only over domain (interval length: 15 meV) I_over_dom_only = trapz(sqe(es[:, 2]), es[:, 2]) print("Trapz integration over the domain.") print(f"Interval {a[2]:.4f} - {b[2]:.4f} -> length {b[2]-a[2]:.4f} meV.") print(f"#Steps = {ne}") print(f"Integral value: {I_over_dom_only:.4f}") # plt.plot(es[:,2], sqe(es[:,2]), label="Over domain only") # plt.show() # Beyond domain same array length es_same_length = linspace(-UPPER_INTEGRATION_LIMIT, UPPER_INTEGRATION_LIMIT, ne) I_beyond_dom_same_length = trapz(sqe(es_same_length), es_same_length) print("\nTrapz integration beyond the domain with varrying stepsize.") print( f"Interval {-UPPER_INTEGRATION_LIMIT} - {UPPER_INTEGRATION_LIMIT} -> length {30.0} meV." ) print(f"#Steps = {ne}") print(f"Integral value: {I_beyond_dom_same_length:.4f}") # plt.plot(es_same_length, sqe(es_same_length), ls="--", label="Beyond domain ne=10000") # plt.show() # Beyond domain same step size es_same_stepsize = arange(-UPPER_INTEGRATION_LIMIT, UPPER_INTEGRATION_LIMIT + 0.001, 15e-3) I_beyond_dom_same_stepsize = trapz(sqe(es_same_stepsize), es_same_stepsize) print("\nTrapz integration beyond the domain with varrying stepsize.") print( f"Interval {-UPPER_INTEGRATION_LIMIT} - {UPPER_INTEGRATION_LIMIT} -> length {30.0} meV." ) print(f"#Steps = {30.0 / 0.015}") print(f"Integral value: {I_beyond_dom_same_stepsize:.4f}")
def calc(self, var): """ Parameters ---------- var : float in this case freq, the MIEZE (difference) frequency of the MIEZE coils Return ------ : float S(q,t) value """ ### Creating energy, wavelength parameter space lam = self.sqemodel.model_params["lam"] dlam = self.sqemodel.model_params["dlam"] l = linspace(1 - dlam * 1.01, 1 + dlam * 1.01, self.params["nlam"]) * lam a = -0.99999 * energy_from_lambda(l) # Selecting integration mode if self.params["integ_mode"] == "adaptive": # print("adaptive grid") ee = self.sqemodel.get_adaptive_integration_grid( self.params["ne"], self.params["nlam"]) # return ee ee = where(ee <= atleast_2d(a), atleast_2d(a), ee) elif self.params["integ_mode"] == "linear": # print("linear grid") ee = linspace(a, UPPER_INTEGRATION_LIMIT, self.params["ne"]) # return ee ne = ee.shape[0] ll = tile(l, (ne, 1)) # return ee, ll ### Creating intgrand arrays sqe = ones((ne, self.params["nlam"])) corrs = tile(sqe, (len(self.corrections), 1, 1)) ### Filling integrand arrays mieze_phase = MIEZE_phase(ee, var, self.params["lSD"], ll) det_eff = detector_efficiency(ee, ll, 1) tri_distr = triangle_distribution(ll, lam, dlam) for cidx, cf in enumerate(self.corrections): corrs[cidx] = cf(ee, ll) corrs = corrs.prod(axis=0) for lamidx, clam in enumerate(l): # clam = current wavelength self.sqemodel.update_domain( (-1 * energy_from_lambda(clam), UPPER_INTEGRATION_LIMIT)) sqe[:, lamidx] = self.sqemodel(ee[:, lamidx]) ### Integration with trapezoidal rule # integrand except phase integrand = det_eff * sqe * tri_distr * corrs # integration for two points of the of known phase difference y1 = trapz(trapz(integrand * cos(mieze_phase), ee, axis=0), l) y2 = trapz(trapz(integrand * cos(mieze_phase + 0.5 * pi), ee, axis=0), l) return (y1**2 + y2**2)**0.5
def test_adaptive_vs_linear(): # L1 = LorentzianLine("LL1", (-energy_from_lambda(6.0), 15), x0=0.048, width=0.04, c=0.0, weight=0.0) L2 = F_cLine("F_c1", (-energy_from_lambda(6.0), 15), x0=0.0, width=0.0001, A=350.0, q=0.02, c=0.0, weight=1) L3 = F_ILine("F_I1", (-energy_from_lambda(6.0), 15), x0=-0.02, width=0.01, A=350.0, q=0.02, kappa=0.01, c=0.0, weight=1) # Contruct a SqE model sqe = SqE(lines=(L1, L2, L3), lam=6.0, dlam=0.12, lSD=3.43, T=20) # Add the detector efficiency correction decf = DetectorEfficiencyCorrectionFactor(sqe, ne=100, nlam=20) ### Construct the adaptive integration grid ne = 100 nlam = 21 l = linspace(1 - sqe.model_params["dlam"], 1 + sqe.model_params["dlam"], nlam) * sqe.model_params["lam"] a = -0.99999 * energy_from_lambda(l) ee = sqe.get_adaptive_integration_grid(ne, nlam) ee = where(ee <= atleast_2d(a), atleast_2d(a), ee) ne = ee.shape[0] ll = tile(l, (ne, 1)) print( f"ee: - Shape: {ee.shape}\n - ee[::50, {nlam//2}]: {ee[::50, nlam//2]}" ) print( f"ll: - Shape: {ll.shape}\n - ll[::50, {nlam//2}]: {ll[::50, nlam//2]}" ) ### Construct a standard linear integration grid nelin = 10000 nlamlin = 21 eelin, lllin = energy_lambda_nrange(15.0, 6.0, 0.12, nelin, nlamlin) print( f"eelin: - Shape: {ee.shape}\n - ee[::{nelin//10}, {nlam//2}]: {eelin[::nelin//10, nlam//2]}" ) print( f"lllin: - Shape: {ll.shape}\n - ll[::{nelin//10}, {nlam//2}]: {lllin[::nelin//10, nlam//2]}" ) ### perform correction calculation from time import time startt = time() adaptcorr = decf.calc(ee, ll) intermedt = time() lincorr = decf.calc(eelin, lllin) stopt = time() print(f"Adaptive integration took: {intermedt - startt:.6f}") print(f"Adaptive grid correction value: {adaptcorr:.6f}") print(f"Linear integration took : {stopt - intermedt:.6f}") print(f"Linear grid correction value : {lincorr:.6f}")
def slow_vis_fitting(): ### Creating a SqE model for transformation # We need some lines # L1 = LorentzianLine("Lorentzian1", (-5.0, 5.0), x0=0.0, width=0.4, c=0.0, weight=1) L2 = LorentzianLine(name="Lorentzian2", domain=(-5.0, 5.0), x0=1.5, width=0.4, c=0.0, weight=2) L3 = F_ILine("FI1", (-energy_from_lambda(6.0), 15), x0=0.0, width=0.008, A=350.0, q=0.02, kappa=0.01, c=0.0, weight=1) # Contruct a SqE model sqe1 = SqE((L2, L3), lam=6.0, dlam=0.12, lSD=3.43, T=20) ### Instantiate a transformer # Consider detector efficiency decf = DetectorEfficiencyCorrectionFactor(sqe1) sqt1 = SqtTransformer(sqe1, corrections=(decf, ), ne=10000, nlam=20, lSD=3.43) ### Creating a logger for debugging: import logging # Create and configure logger logging.basicConfig(filename=f"{testdir}/resources/fit.log", level=logging.INFO, filemode="w") logger = logging.getLogger() ### Values for transformation taus = logspace(-6, -1, 101) datataus = array([ 2.0e-6, 6.0e-6, 4.1e-5, 2.5e-4, 5.5e-4, 1.0e-3, 1.32e-3, 1.7e-3, 2.2e-3, 2.63e-3, 2.77e-3, 3.3e-3, 4.27e-3, 5.11e-3, 6.77e-3, 8.96e-3, 2.0e-2 ]) x = MIEZE_DeltaFreq_from_time(datataus * 1.0e-9, 3.43, 6.0) longx = MIEZE_DeltaFreq_from_time(taus * 1.0e-9, 3.43, 6.0) ### TRANSFORM!! y = array([sqt1(freq) for freq in x]) sqt1vals = array([sqt1(freq) for freq in longx]) yerr = 0.03 * random.randn(len(y)) ### FIT! m = FitModelCreator.from_transformer( sqt1, x, abs(y + yerr), yerr, [-1.5, 0.2, 0.0, 3.0, 0.01, 350.0, 0.02, 0.015, 0.0, 1.0], logger=logger) # m.fixed["c_Lorentzian1"] = True m.fixed["c_Lorentzian2"] = True print("fcn for m:\n", m.fcn) m2 = FitModelCreator.from_Minuit( minuitobj=m, # limit_weight_Lorentzian1=(0, None), # limit_width_Lorentzian1=(0, None), limit_weight_Lorentzian2=(0, None), limit_width_Lorentzian2=(0, None), limit_weight_FI1=(0.0, None), limit_kappa_FI1=(0.0, None), # fix_c_Lorentzian1=True, fix_c_Lorentzian2=True, # fix_weight_Lorentzian1=True fix_c_FI1=True, fix_weight_FI1=True, fix_A_FI1=True, fix_q_FI1=True) print("fcn for m2:\n", m2.fcn) # fmin, res = m.migrad(ncall=1000) # print(fmin) # print(res) fmin, res = m2.migrad(ncall=1000) print(fmin) print(res) ### Gather Fit results # dL1res1 = { # "x0" : 0.0, # "width" : res[0].value, # "c" : res[1].value, # "weight" : res[2].value # } # dL2res1 = { # "x0" : res[3].value, # "width" : res[4].value, # "c" : res[5].value, # "weight" : res[6].value # } dL2res1 = { "x0": res[0].value, "width": res[1].value, "c": res[2].value, "weight": res[3].value } dFI1res = { "width": res[4].value, "A": res[5].value, "q": res[6].value, "kappa": res[7].value, "c": res[8].value, "weight": res[9].value } # L1.update_line_params(**dL1res1) L2.update_line_params(**dL2res1) L3.update_line_params(**dFI1res) sqtres1vals = array([sqt1(freq) for freq in longx]) # ### Gather Fit results # dL1res2 = { # "x0" : 0.0, # "width" : res2[0].value, # "c" : res2[1].value, # "weight" : res2[2].value # } # dL2res2 = { # "x0" : res2[3].value, # "width" : res2[4].value, # "c" : res2[5].value, # "weight" : res2[6].value # } # L1.update_line_params(**dL1res2) # L2.update_line_params(**dL2res2) # sqtres2vals = array([sqt1(freq) for freq in longx]) ### Calculate init guess # dL1ig = { # "x0" : 0.0, # "width" : 0.6, # "c" : 0, # "weight" : 1.0 # } # dL2ig = { # "x0" : -1.5, # "width" : 0.2, # "c" : 0.0, # "weight" : 3.0 # } dL2ig = {"x0": -1.5, "width": 0.2, "c": 0.0, "weight": 3.0} dFI1ig = { "x0": 0.0, "width": 0.01, "A": 350, "q": 0.02, "kappa": 0.015, "c": 0.0, "weight": 1.0 } # L1.update_line_params(**dL1ig) L2.update_line_params(**dL2ig) L3.update_line_params(**dFI1ig) sqtigvals = array([sqt1(freq) for freq in longx]) plt.plot(taus, sqt1vals, label="orig. curve", ls="--", color="C0") plt.plot(taus, sqtres1vals, label="fit curve 1", ls="-", color="C1") # plt.plot(taus, sqtres2vals, label="fit curve 2", ls=":", color="C4") plt.plot(taus, sqtigvals, label="init guess", ls="-.", color="C2") plt.errorbar(datataus, abs(y + yerr), yerr, label="data", ls="", marker="o", color="C0") plt.xscale("log") plt.xlabel("$\\tau_{MIEZE}$ [ns]", fontsize=16.) plt.ylabel("S(q,t) [arb. u.]", fontsize=16.) plt.legend() plt.show()
def test_DetectorEfficiency_quad_vs_trapz(): # We need some lines L1 = LorentzianLine("Lorentzian1", (-5.0, 5.0), x0=0.0, width=0.4, c=0.0, weight=2) L2 = LorentzianLine(name="Lorentzian2", domain=(-5.0, 5.0), x0=-1.0, width=0.4, c=0.02, weight=1) # Contruct a SqE model sqe = SqE(lines=(L1, L2), lam=6.0, dlam=0.12, lSD=3.43, T=20) ### QUAD from scipy.integrate import dblquad # parameter for calculation plam, pdlam = 6.0, 0.12 def dblquadfunc(energy, lam, on): # det_eff = detector_efficiency(energy, lam, 1) # sqeval = sqe(energy) # tri_distr_weight = triangle_distribution(lam, plam, pdlam) return detector_efficiency(energy, lam, on) * sqe(energy) * triangle_distribution( lam, plam, pdlam) # integrate t0quad = time() reson, erron = dblquad( dblquadfunc, plam * (1 - pdlam), plam * (1 + pdlam), lambda x: -0.9999 * energy_from_lambda(x), lambda x: UPPER_INTEGRATION_LIMIT, args=(1, ), #epsabs=1.0e-2 ) resoff, erroff = dblquad( dblquadfunc, plam * (1 - pdlam), plam * (1 + pdlam), lambda x: -0.9999 * energy_from_lambda(x), lambda x: UPPER_INTEGRATION_LIMIT, args=(0, ), #epsabs=1.0e-2 ) t1quad = time() print( f"RESULT: {resoff/reson} +- {resoff/reson * ((erron/reson)**2+(erroff/resoff)**2)**0.5}" ) print(f"dblquad took {t1quad - t0quad} seconds") ### TRAPZ decf = DetectorEfficiencyCorrectionFactor(sqe) ee, ll = energy_lambda_nrange(UPPER_INTEGRATION_LIMIT, 6.0, 0.12, 15000, 20) # integrate t0trapz = time() trapz_res = decf(ee, ll) t1trapz = time() print(f"RESULT: {trapz_res}") print(f"trapz took {t1trapz - t0trapz} seconds")