コード例 #1
0
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)
コード例 #2
0
def test_from_Minuit_and_adjust_it():
    ### 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)
    # Contruct a SqE model
    sqe1 = SqE((L1, L2), 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=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))

    ### initialize Minuits!
    m = FitModelCreator.from_transformer(sqt1, x, y + yerr, yerr,
                                         [0.45, 0.0, 1.2, -1.5, 0.3, 0.0, 2.2])
    m.fixed["c_Lorentzian1"] = True
    m.fixed["c_Lorentzian2"] = True

    # Adjust fit behavior -> reinitialize another Minuit obj
    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),
                                     fix_c_Lorentzian1=True,
                                     fix_c_Lorentzian2=True)
コード例 #3
0
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
    ])
コード例 #4
0
def test_adaptive_vs_linear():
    ### Instantiate a transformer
    sqtadapt = SqtTransformer.load_from_dict(**STANDARD_SQT.export_to_dict())
    sqtlinear = SqtTransformer.load_from_dict(**STANDARD_SQT.export_to_dict())
    sqtlinear.update_params(ne=50000, integ_mode="linear")

    ### Values for transformation
    taus = logspace(-4, 1, 81)
    freqs = MIEZE_DeltaFreq_from_time(taus * 1.0e-9, 3.43, 6.0)

    ### perform transformation
    from time import time
    startt = time()
    adaptvals = array([sqtadapt(freq) for freq in freqs])
    intermedt = time()
    linearvals = array([sqtlinear(freq) for freq in freqs])
    stopt = time()

    print(f"Adaptive integration took: {intermedt - startt:.1f}")
    print(f"Linear integration took  : {stopt - intermedt:.1f}")
コード例 #5
0
def test_transform_arg_model():
    ### Creating a SqE model for transformation
    sqe_arg = SqE_from_arg(T=20.)

    ### Instantiate a transformer
    sqt_arg = SqtTransformer(sqe_arg,
                             corrections=(DetectorEfficiencyCorrectionFactor(
                                 sqe_arg, 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!!
    sqt_argvals = [sqt_arg(freq) for freq in freqs]
    # For the next step to work, A1 needs to be manually removed
    # from arg.Sqt calculation.
    sqt_argmodulevals = 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.)
コード例 #6
0
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)
    # Contruct a SqE model
    sqe1 = SqE(lines=(L1,), lam=6.0, dlam=0.12, l_SD=3.43, T=20)

    ### Instantiate a transformer
    sqt1 = SqtTransformer(
        sqe1,
        corrections=(DetectorEfficiencyCorrectionFactor(sqe1, n_e=15000, n_lam=20),),
        n_e=15000,
        n_lam=20,
        l_SD=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.
    )
コード例 #7
0
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()
コード例 #8
0
ファイル: fit.py プロジェクト: LukasBeddrich/modelmiezelb
def simple_fit_multi_sqt_curves(transformer,
                                contrastdata,
                                pnames,
                                p0s,
                                cdidx=0,
                                constraints=None,
                                ncalls=150,
                                iomanager=None,
                                export_root=None):
    """
    Finally a function that does what my ipynb does for fitting for one particular model

    Parameters
    ----------
    transformer  :   modelmiezelb.transformer.SqtTransformer
        the theoretical model for the fit
    contrastdata :   iterable
        contains the modelmiezelb.io.ContrastData objects
    pnames       :   iterable
        contains names of the parameters in the fit
    p0s          :   list
        list of parameter lists. len(p0s) needs to equal len(contrastdata)
        len(p0s[i]) needs to equal len(pnames)
    cdidx        :   int, optional
        index of the data set within a ContrastData object
    contstraints :   dict, optional
        contraints for Minuit object
    ncalls       :   int, optional
        number of function calls in Minuit.migrad
    iomanager    :   None, modelmiezelb.io.IOManager, optional
        used for export
        !!! needs to contain JSONExporter, otherwise filenames do not make sense !!!
    export_root  :   str, optional
        directory where to save the results
        Needs to be given if iomanager is passed to function

    Return
    ------
    minuits      :   list
        list of Minuit objects after fitting

    Note
    ----
    This function assumes that MIEZE times are given in nanoseconds (ns)!
    If not the result is rubbish! 
    """
    from time import time, localtime, strftime

    try:
        assert len(contrastdata) == len(p0s)
        assert len(p0s[0]) == len(pnames)
    except:
        raise AssertionError("The dimensions of the inputs do not match!\
            Check you input for inconsistencies.")

    minuits = [None] * len(contrastdata)

    t0 = time()
    for idx in range(len(contrastdata)):
        ti = time()

        tempcd = contrastdata[idx]
        taus, c, cerr = tempcd.getData(cdidx)[[0, -2, -1]]
        freqs = MIEZE_DeltaFreq_from_time(
            taus * 1.0e-9, transformer.params["lSD"],
            transformer.sqemodel.model_params["lam"])

        # Init base Minuit object
        mbase = FitModelCreator.from_transformer(transformer, freqs, c, cerr,
                                                 p0s[idx])

        # Add constraints
        default_constraints = {
            "error_" + n: val * 0.006
            for n, val in zip(pnames, p0s[idx])
        }
        if constraints:
            default_constraints.update(constraints)

        m = FitModelCreator.from_Minuit(mbase, **default_constraints)
        fmin, res = m.migrad(ncall=ncalls)
        minuits[idx] = m
        print(fmin)
        print(res)

        print("Fitting is {}% done.".format(
            float(idx + 1) / len(contrastdata) * 100))
        print("Last iteration took {:.2f} seconds".format(time() - ti))
        print("Total seconds elapsed: {:.2f} s".format(time() - t0))
        print("The fitting step was finished at {}\n".format(
            strftime("%H:%M:%S  %a %Y/%m/%d", localtime())))

        tempcd.fitparams = minuit_to_dict(m)

        if bool(iomanager) and bool(export_root):
            export_path = join(export_root, f"{tempcd.get('keys')[cdidx]}")
            components = [
                f"_{k}{str(tempcd.get(k))}"
                for k in ["foilnum", "arcnum", "description"] if tempcd.get(k)
            ]
            export_path += "".join(components) + ".json"

            iomanager.export((export_path, tempcd))

    return minuits