示例#1
0
    def test_repr_transform(self):
        p = Transform(None)
        q = eval(repr(p))
        assert p.form == q.form

        p = Transform("logY")
        q = eval(repr(p))
        assert p.form == q.form
示例#2
0
    def test_repr_transform(self):
        p = Transform(None)
        q = eval(repr(p))
        assert (p.form == q.form)

        p = Transform('logY')
        q = eval(repr(p))
        assert (p.form == q.form)
示例#3
0
def setup():
    # load the data.
    DATASET_NAME = os.path.join(refnx.__path__[0],
                                'analysis',
                                'test',
                                'c_PLP0011859_q.txt')

    # load the data
    data = ReflectDataset(DATASET_NAME)

    # the materials we're using
    si = SLD(2.07, name='Si')
    sio2 = SLD(3.47, name='SiO2')
    film = SLD(2, name='film')
    d2o = SLD(6.36, name='d2o')

    structure = si | sio2(30, 3) | film(250, 3) | d2o(0, 3)
    structure[1].thick.setp(vary=True, bounds=(15., 50.))
    structure[1].rough.setp(vary=True, bounds=(1., 6.))
    structure[2].thick.setp(vary=True, bounds=(200, 300))
    structure[2].sld.real.setp(vary=True, bounds=(0.1, 3))
    structure[2].rough.setp(vary=True, bounds=(1, 6))

    model = ReflectModel(structure, bkg=9e-6, scale=1.)
    model.bkg.setp(vary=True, bounds=(1e-8, 1e-5))
    model.scale.setp(vary=True, bounds=(0.9, 1.1))
    model.threads = 1
    # fit on a logR scale, but use weighting
    objective = Objective(model, data, transform=Transform('logY'),
                          use_weights=True)

    return objective
示例#4
0
    def setup_method(self):
        self.pth = os.path.dirname(os.path.abspath(__file__))

        self.si = SLD(2.07, name='Si')
        self.sio2 = SLD(3.47, name='SiO2')
        self.d2o = SLD(6.36, name='d2o')
        self.h2o = SLD(-0.56, name='h2o')
        self.cm3 = SLD(3.5, name='cm3')
        self.polymer = SLD(2, name='polymer')

        self.sio2_l = self.sio2(40, 3)
        self.polymer_l = self.polymer(200, 3)

        self.structure = (self.si | self.sio2_l | self.polymer_l
                          | self.d2o(0, 3))

        fname = os.path.join(self.pth, 'c_PLP0011859_q.txt')

        self.dataset = ReflectDataset(fname)
        self.model = ReflectModel(self.structure, bkg=2e-7)
        self.objective = Objective(self.model,
                                   self.dataset,
                                   use_weights=False,
                                   transform=Transform('logY'))
        self.global_objective = GlobalObjective([self.objective])
示例#5
0
    def _on_plot_type_changed(self, change):
        """
        User would like to plot and fit as logR/linR/RQ4/RQ2, etc
        """
        self.transform = Transform(change["new"])
        if self.objective is not None:
            self.objective.transform = self.transform

        if self.dataset is not None:
            yt, _ = self.transform(self.dataset.x, self.dataset.y)

            self.data_plot.set_xdata(self.dataset.x)
            self.data_plot.set_ydata(yt)

        self.update_model(None)

        # probably have to change LHS axis of the data plot when
        # going between different plot types.
        if change["new"] == "logY":
            self.ax_data.set_yscale("linear")
        else:
            self.ax_data.set_yscale("log")

        self.ax_data.relim()
        self.ax_data.autoscale_view()
        self.fig.canvas.draw()
示例#6
0
    def test_globalfitting(self):
        # smoke test for can the global fitting run?
        # also tests that global fitting gives same output as
        # normal fitting (for a single dataset)
        self.model.scale.setp(vary=True, bounds=(0.1, 2))
        self.model.bkg.setp(vary=True, bounds=(1e-10, 8e-6))
        self.structure[-1].rough.setp(vary=True, bounds=(0.2, 6))
        self.sio2_l.thick.setp(vary=True, bounds=(0.2, 80))
        self.polymer_l.thick.setp(bounds=(0.01, 400), vary=True)
        self.polymer_l.sld.real.setp(vary=True, bounds=(0.01, 4))

        self.objective.transform = Transform('logY')

        starting = np.array(self.objective.parameters)
        with np.errstate(invalid='raise'):
            g = CurveFitter(self.global_objective)
            res_g = g.fit()

            # need the same starting point
            self.objective.setp(starting)
            f = CurveFitter(self.objective)
            res_f = f.fit()

            # individual and global should give the same fit.
            assert_almost_equal(res_g.x, res_f.x)
示例#7
0
    def test_parallel_objective(self):
        # check that a parallel objective works without issue
        # (it could be possible that parallel evaluation fails at a higher
        #  level in e.g. emcee or in scipy.optimize.differential_evolution)
        model = self.model361
        model.threads = 2

        objective = Objective(
            model,
            (self.qvals361, self.rvals361, self.evals361),
            transform=Transform("logY"),
        )
        p0 = np.array(objective.varying_parameters())
        cov = objective.covar()
        walkers = np.random.multivariate_normal(np.atleast_1d(p0),
                                                np.atleast_2d(cov),
                                                size=(100))
        map_logl = np.array(list(map(objective.logl, walkers)))
        map_chi2 = np.array(list(map(objective.chisqr, walkers)))

        wf = Wrapper_fn2(model.model, p0)
        map_mod = np.array(list(map(wf, walkers)))

        with MapWrapper(2) as g:
            mapw_mod = g(wf, walkers)
            mapw_logl = g(objective.logl, walkers)
            mapw_chi2 = g(objective.chisqr, walkers)
        assert_allclose(mapw_logl, map_logl)
        assert_allclose(mapw_chi2, map_chi2)
        assert_allclose(mapw_mod, map_mod)
示例#8
0
 def test_reflectivity_fit(self):
     # a smoke test to make sure the reflectivity fit proceeds
     model = self.model361
     objective = Objective(model,
                           (self.qvals361, self.rvals361, self.evals361),
                           transform=Transform('logY'))
     fitter = CurveFitter(objective)
     with np.errstate(invalid='raise'):
         fitter.fit('differential_evolution')
示例#9
0
    def test_residuals(self):
        # weighted, with and without transform
        assert_almost_equal(self.objective.residuals(),
                            (self.data.y - self.mod) / self.data.y_err)

        objective = Objective(self.model, self.data,
                              transform=Transform('lin'))
        assert_almost_equal(objective.residuals(),
                            (self.data.y - self.mod) / self.data.y_err)

        # unweighted, with and without transform
        objective = Objective(self.model, self.data, use_weights=False)
        assert_almost_equal(objective.residuals(),
                            self.data.y - self.mod)

        objective = Objective(self.model, self.data, use_weights=False,
                              transform=Transform('lin'))
        assert_almost_equal(objective.residuals(),
                            self.data.y - self.mod)
示例#10
0
    def test_transform(self):
        pth = os.path.dirname(os.path.abspath(__file__))

        fname = os.path.join(pth, 'c_PLP0011859_q.txt')
        data = ReflectDataset(fname)
        t = Transform('logY')

        yt, et = t(data.x, data.y, y_err=data.y_err)
        assert_equal(yt, np.log10(data.y))

        yt, _ = t(data.x, data.y, y_err=None)
        assert_equal(yt, np.log10(data.y))

        EPy, EPe = EP.EPlog10(data.y, data.y_err)
        assert_equal(yt, EPy)
        assert_equal(et, EPe)
示例#11
0
    def test_code_fragment(self):
        e361 = ReflectDataset(os.path.join(self.pth, "e361r.txt"))

        si = SLD(2.07, name="Si")
        sio2 = SLD(3.47, name="SiO2")
        d2o = SLD(6.36, name="D2O")
        polymer = SLD(1, name="polymer")

        # e361 is an older dataset, but well characterised
        self.structure361 = si | sio2(10, 4) | polymer(200, 3) | d2o(0, 3)
        self.model361 = ReflectModel(self.structure361, bkg=2e-5)

        self.model361.scale.vary = True
        self.model361.bkg.vary = True
        self.model361.scale.range(0.1, 2)
        self.model361.bkg.range(0, 5e-5)

        # d2o
        self.structure361[-1].sld.real.vary = True
        self.structure361[-1].sld.real.range(6, 6.36)

        self.structure361[1].thick.vary = True
        self.structure361[1].thick.range(5, 20)

        self.structure361[2].thick.vary = True
        self.structure361[2].thick.range(100, 220)

        self.structure361[2].sld.real.vary = True
        self.structure361[2].sld.real.range(0.2, 1.5)

        objective = Objective(self.model361, e361, transform=Transform("logY"))
        objective2 = eval(repr(objective))
        assert_allclose(objective2.chisqr(), objective.chisqr())

        exec(repr(objective))
        exec(code_fragment(objective))

        # artificially link the two thicknesses together
        # check that we can reproduce the objective from the repr
        self.structure361[2].thick.constraint = self.structure361[1].thick
        fragment = code_fragment(objective)
        fragment = fragment + "\nobj = objective()\nresult = obj.chisqr()"
        d = {}
        # need to provide the globals dictionary to exec, so it can see imports
        # e.g. https://bit.ly/2RFOF7i (from stackoverflow)
        exec(fragment, globals(), d)
        assert_allclose(d["result"], objective.chisqr())
示例#12
0
    def test_reflectivity_emcee(self):
        model = self.model361
        model.dq = 5.
        objective = Objective(model,
                              (self.qvals361, self.rvals361, self.evals361),
                              transform=Transform('logY'))
        fitter = CurveFitter(objective, nwalkers=100)

        assert_(len(objective.generative().shape) == 1)
        assert_(len(objective.residuals().shape) == 1)

        res = fitter.fit('least_squares')
        res_mcmc = fitter.sample(steps=5, nthin=10, random_state=1,
                                 verbose=False)

        mcmc_val = [mcmc_result.median for mcmc_result in res_mcmc]
        assert_allclose(mcmc_val, res.x, rtol=0.05)
示例#13
0
    def test_resolution_speed_comparator(self):
        fname = os.path.join(self.pth, "c_PLP0011859_q.txt")
        dataset = ReflectDataset(fname)

        sio2 = SLD(3.47, name="SiO2")
        si = SLD(2.07, name="Si")
        d2o = SLD(6.36, name="D2O")
        polymer = SLD(2.0, name="polymer")

        sio2_l = sio2(30, 3)
        polymer_l = polymer(125, 3)

        dx = dataset.x_err
        structure = si | sio2_l | polymer_l | polymer_l | d2o(0, 3)
        model = ReflectModel(structure, bkg=2e-6, dq_type="constant")
        objective = Objective(model,
                              dataset,
                              use_weights=False,
                              transform=Transform("logY"))

        # check that choose_resolution_approach doesn't change state
        # of model
        fastest_method = choose_dq_type(objective)
        assert model.dq_type == "constant"
        assert_equal(dx, objective.data.x_err)

        # check that the comparison worked
        const_time = time.time()
        for i in range(1000):
            objective.generative()
        const_time = time.time() - const_time

        model.dq_type = "pointwise"
        point_time = time.time()
        for i in range(1000):
            objective.generative()
        point_time = time.time() - point_time

        if fastest_method == "pointwise":
            assert point_time < const_time
        elif fastest_method == "constant":
            assert const_time < point_time

        # check that we could use the function to setup a reflectmodel
        ReflectModel(structure, bkg=2e-6, dq_type=choose_dq_type(objective))
示例#14
0
    def test_modelvals_degenerate_layers(self):
        # try fitting dataset with a deposited layer split into two degenerate
        # layers
        fname = os.path.join(self.pth, "c_PLP0011859_q.txt")
        dataset = ReflectDataset(fname)

        sio2 = SLD(3.47, name="SiO2")
        si = SLD(2.07, name="Si")
        d2o = SLD(6.36, name="D2O")
        polymer = SLD(2.0, name="polymer")

        sio2_l = sio2(30, 3)
        polymer_l = polymer(125, 3)

        structure = si | sio2_l | polymer_l | polymer_l | d2o(0, 3)

        polymer_l.thick.setp(value=125, vary=True, bounds=(0, 250))
        polymer_l.rough.setp(value=4, vary=True, bounds=(0, 8))
        structure[-1].rough.setp(vary=True, bounds=(0, 6))
        sio2_l.rough.setp(value=3.16, vary=True, bounds=(0, 8))

        model = ReflectModel(structure, bkg=2e-6)
        objective = Objective(model,
                              dataset,
                              use_weights=False,
                              transform=Transform("logY"))

        model.scale.setp(vary=True, bounds=(0, 2))
        model.bkg.setp(vary=True, bounds=(0, 8e-6))

        slabs = structure.slabs()
        assert_equal(slabs[2, 0:2], slabs[3, 0:2])
        assert_equal(slabs[2, 3], slabs[3, 3])
        assert_equal(slabs[1, 3], sio2_l.rough.value)

        f = CurveFitter(objective)
        f.fit(method="differential_evolution", seed=1, maxiter=3)

        slabs = structure.slabs()
        assert_equal(slabs[2, 0:2], slabs[3, 0:2])
        assert_equal(slabs[2, 3], slabs[3, 3])
示例#15
0
def make_model(names, bs, thicks, roughs, fig_i, data, show=False, mcmc=False):
    no_layers = len(bs)
    layers = []
    for i in range(no_layers):
        names.append('layer' + str(i))

    for i in range(no_layers):
        sld = SLD(bs[i], name=names[i])
        layers.append(sld(thicks[i], roughs[i]))

    layers[0].thick.setp(vary=True, bounds=(thicks[i] - 1, thicks[i] + 1))
    layers[0].sld.real.setp(vary=True, bounds=(bs[i] - 1, bs[i] + 1))

    for layer in layers[1:]:
        layer.thick.setp(vary=True, bounds=(thicks[i] - 1, thicks[i] + 1))
        layer.sld.real.setp(vary=True, bounds=(bs[i] - 1, bs[i] + 1))
        layer.rough.setp(vary=True, bounds=(0, 5))

    structure = layers[0]
    for layer in layers[1:]:
        structure |= layer
    print(structure)
    model = ReflectModel(structure, bkg=3e-6, dq=5.0)
    #model.scale.setp(bounds=(0.6, 1.2), vary=True)
    #model.bkg.setp(bounds=(1e-9, 9e-6), vary=True)
    objective = Objective(model, data, transform=Transform('logY'))
    fitter = CurveFitter(objective)
    if mcmc:
        fitter.sample(1000)
        process_chain(objective, fitter.chain, nburn=300, nthin=100)
    else:
        fitter.fit('differential_evolution')
    print(objective.parameters)

    if show:
        plt.figure(fig_i)
        plt.plot(*structure.sld_profile())
        plt.ylabel('SLD /$10^{-6} \AA^{-2}$')
        plt.xlabel('distance / $\AA$')
    return structure, fitter, objective, fig_i + 1
示例#16
0
def make_model(names, bs, thicks, roughs, fig_i, data, show=False, mcmc=False):
    extent = sum(
        thicks[:, 0])  # (float or Parameter) – Total extent of spline region
    vs = array(
        bs
    )[:,
      0]  #(Sequence of float/Parameter) – the real part of the SLD values of each of the knots.
    dz = cum_sum(
        array(thicks[:, 0])
    )  #(Sequence of float/Parameter) – the lateral offset between successive knots.
    print(dz)
    name = "number of nots " + str(len(names))  #(str) – Name of component
    component = Spline(extent, vs, dz, name)
    front = SLD(0)
    front = front(0, 0)
    back = SLD(0)
    back = back(0, 0)
    structure = front | component | back
    model = ReflectModel(structure, bkg=3e-6, dq=5.0)
    objective = Objective(model, data, transform=Transform('logY'))
    fitter = CurveFitter(objective)
    fitter.fit('differential_evolution')
    return structure, fitter, objective, fig_i + 1
示例#17
0
    def test_globalfitting(self):
        # smoke test for can the global fitting run?
        # also tests that global fitting gives same output as
        # normal fitting (for a single dataset)
        self.model.scale.setp(vary=True, bounds=(0.1, 2))
        self.model.bkg.setp(vary=True, bounds=(1e-10, 8e-6))
        self.structure[-1].rough.setp(vary=True, bounds=(0.2, 6))
        self.sio2_l.thick.setp(vary=True, bounds=(0.2, 80))
        self.polymer_l.thick.setp(bounds=(0.01, 400), vary=True)
        self.polymer_l.sld.real.setp(vary=True, bounds=(0.01, 4))

        self.objective.transform = Transform('logY')

        with np.errstate(invalid='raise'):
            g = CurveFitter(self.global_objective)
            res_g = g.fit(method='differential_evolution', seed=1, maxiter=10)

            f = CurveFitter(self.objective)
            res_f = f.fit(method='differential_evolution', seed=1, maxiter=10)

            # individual and global should give the same fit. Because we use DE
            # there is no dependence on starting point, so long as we set a
            # seed.
            assert_almost_equal(res_g.x, res_f.x)
示例#18
0
def getObjective(data, nLayers, bs_contrast_layer=None,
                 contrast_layer=None,
                 limits = None, doMCMC=False,
                 logpExtra=None, onlyStructure=False,
                 both=False, globalObjective=False):

    if globalObjective:
        if bs_contrast_layer is None:
            bs_contrast_layer = 6
        if contrast_layer is None:
            contrast_layer = 1
#         print("data, nLayers, bs_contrast_layer=None,\n contrast_layer=None,\nlimits = None, doMCMC=False,\nlogpExtra=None, onlyStructure=False,\nboth=False, globalObjective=False: ",
#                      data, nLayers, bs_contrast_layer,
#                      contrast_layer,
#                      limits, doMCMC,
#                      logpExtra, onlyStructure,
#                      both, globalObjective)

    air = SLD(0,name="air layer")
    airSlab = air(10,0)

    sio2 = SLD(10,name="bottem layer")
    sio2Slab = sio2(10,0)


    if limits is None:
        limits = [350,50,4,6]
    
#     maxThick = 350
#     lowerThick = 50
#     upperThick = maxThick - nLayers*lowerThick
#     lowerB = 4
#     upperB = 6

    maxThick = float(limits[0])
    lowerThick = limits[1]
    upperThick = maxThick - nLayers*lowerThick
    lowerB = limits[2]
    upperB = limits[3]

    if globalObjective:
        thick_contrast_layer=Parameter(maxThick/nLayers,
                                        "layer1 thickness")
        rough_contrast_layer=Parameter(0,
                                    "layer0/contrast roughness")
        sldcontrastA=SLD(5,name="contrast A layer")
        sldcontrastASlab= sldcontrastA(thick_contrast_layer,rough_contrast_layer)
        sldcontrastASlab.thick.setp(vary=True, bounds=(lowerThick,upperThick))
        sldcontrastASlab.sld.real.setp(vary=True, bounds=(lowerB,upperB))

        sldcontrastB=SLD(5,name="contrast B layer")
        sldcontrastBSlab = sldcontrastB(thick_contrast_layer,rough_contrast_layer)
        sldcontrastBSlab.thick.setp(vary=True, bounds=(lowerThick,upperThick))
        sldcontrastBSlab.sld.real.setp(vary=True, bounds=(lowerB,upperB))


    if nLayers>=1 and not globalObjective:
        sld1 = SLD(5,name="first layer")
        sld1Slab = sld1(maxThick/nLayers,0)
        sld1Slab.thick.setp(vary=True, bounds=(lowerThick,upperThick))
        sld1Slab.sld.real.setp(vary=True, bounds=(lowerB,upperB))

    if nLayers>=2:
        sld2 = SLD(5,name="second layer")
        sld2Slab = sld2(maxThick/nLayers,0)
        sld2Slab.thick.setp(vary=True, bounds=(lowerThick,upperThick))
        sld2Slab.sld.real.setp(vary=True, bounds=(lowerB,upperB))

    if nLayers>=3:
        sld3 = SLD(5,name="third layer")
        sld3Slab = sld3(maxThick/nLayers,0)
        sld3Slab.thick.setp(vary=True, bounds=(lowerThick,upperThick))
        sld3Slab.sld.real.setp(vary=True, bounds=(lowerB,upperB))

    if nLayers>=4:
        sld4 = SLD(5,name="forth layer")
        sld4Slab = sld4(maxThick/nLayers,0)
        sld4Slab.thick.setp(vary=True, bounds=(lowerThick,upperThick))
        sld4Slab.sld.real.setp(vary=True, bounds=(lowerB,upperB))

#     if nLayers>=1:
#         sld1Slab.thick.setp(vary=True, bounds=(lowerThick,upperThick))
#         sld1Slab.sld.real.setp(vary=True, bounds=(lowerB,upperB))

#     if nLayers>=2:
#         sld2Slab.thick.setp(vary=True, bounds=(lowerThick,upperThick))
#         sld2Slab.sld.real.setp(vary=True, bounds=(lowerB,upperB))

#     if nLayers>=3:
#         sld3Slab.thick.setp(vary=True, bounds=(lowerThick,upperThick))
#         sld3Slab.sld.real.setp(vary=True, bounds=(lowerB,upperB))

#     if nLayers>=4:
#         sld4Slab.thick.setp(vary=True, bounds=(lowerThick,upperThick))
#         sld4Slab.sld.real.setp(vary=True, bounds=(lowerB,upperB))

    if globalObjective and contrast_layer==1:
        if nLayers==1:
            structure1 = airSlab|sldcontrastASlab|sio2Slab
            structure2 = airSlab|sldcontrastBSlab|sio2Slab
        if nLayers==2:
            structure1 = airSlab|sldcontrastASlab|sld2Slab|sio2Slab
            structure2 = airSlab|sldcontrastBSlab|sld2Slab|sio2Slab
        if nLayers==3:
            structure1 = airSlab|sldcontrastASlab|sld2Slab|sld3Slab|sio2Slab
            structure2 = airSlab|sldcontrastBSlab|sld2Slab|sld3Slab|sio2Slab
        if nLayers==4:
            structure1 = airSlab|sldcontrastASlab|sld2Slab|sld3Slab|sld4Slab|sio2Slab
            structure2 = airSlab|sldcontrastBSlab|sld2Slab|sld3Slab|sld4Slab|sio2Slab
        if onlyStructure:
            returns = structure1,structure2
        elif both:
            model1 = ReflectModel(structure1, bkg=3e-6, dq=5.0)
            model1.scale.setp(bounds=(0.85, 1.2), vary=True)
            model1.bkg.setp(bounds=(1e-9, 9e-6), vary=True)
            objective1 = Objective(model1, data[0],
                      transform=Transform('logY'),
                      logp_extra=logpExtra)
            model2 = ReflectModel(structure2, bkg=3e-6, dq=5.0)
            model2.scale.setp(bounds=(0.85, 1.2), vary=True)
            model2.bkg.setp(bounds=(1e-9, 9e-6), vary=True)
            objective2 = Objective(model2, data[1],
                      transform=Transform('logY'),
                      logp_extra=logpExtra)
            returns = GlobalObjective([objective1, objective2]), structure1, structure2
            print("GlobalObjective and 2 structures")
        else:
            model1 = ReflectModel(structure1, bkg=3e-6, dq=5.0)
            model1.scale.setp(bounds=(0.85, 1.2), vary=True)
            model1.bkg.setp(bounds=(1e-9, 9e-6), vary=True)
            objective1 = Objective(model1, data[0],
                      transform=Transform('logY'),
                      logp_extra=logpExtra)
            model2 = ReflectModel(structure2, bkg=3e-6, dq=5.0)
            model2.scale.setp(bounds=(0.85, 1.2), vary=True)
            model2.bkg.setp(bounds=(1e-9, 9e-6), vary=True)
            objective2 = Objective(model2, data[1],
                      transform=Transform('logY'),
                      logp_extra=logpExtra)
            returns = GlobalObjective([objective1, objective2])

    elif not globalObjective:
        if nLayers==1:
            structure = airSlab|sld1Slab|sio2Slab
        if nLayers==2:
            structure = airSlab|sld1Slab|sld2Slab|sio2Slab
        if nLayers==3:
            structure = airSlab|sld1Slab|sld2Slab|sld3Slab|sio2Slab
        if nLayers==4:
            structure = airSlab|sld1Slab|sld2Slab|sld3Slab|sld4Slab|sio2Slab
        if onlyStructure:
            returns = structure
        elif both:
            model = ReflectModel(structure, bkg=3e-6, dq=5.0)
            objective = Objective(model, data,
                      transform=Transform('logY'),
                      logp_extra=logpExtra)
            returns = objective, structure
        else:
            model = ReflectModel(structure, bkg=3e-6, dq=5.0)
            objective = Objective(model, data, transform=Transform('logY'),logp_extra=logpExtra)
            returns = objective
    else:
        print("error contrast layer not at sld1Slab ie contrast_layer!=0")
#     print(returns)
    return returns
示例#19
0
def getObjective(data, thicknesses, slds, layerNames, logpExtra=None):

    air = SLD(0, name="air layer")
    airSlab = air(10, 0)
    sio2 = SLD(10, name="bottem layer")
    sio2Slab = sio2(10, 0)

    #     print(" ... ",slds[0].startPoint)
    if len(layerNames) >= 1:
        i = 0
        sld1 = SLD(float(slds[i].startPoint), name=layerNames[i])
        sld1Slab = sld1(thicknesses[i].startPoint, thicknesses[i].roughness)
        sld1Slab.thick.setp(vary=thicknesses[i].vary,
                            bounds=(thicknesses[i].lower,
                                    thicknesses[i].upper))
        sld1Slab.sld.real.setp(vary=slds[i].vary,
                               bounds=(slds[i].lower, slds[i].upper))
    else:
        print(layerNames, " : variable 'layerNames' is empty")

    if len(layerNames) >= 2:
        i = 1
        sld2 = SLD(slds[i].startPoint, name=layerNames[i])
        sld2Slab = sld2(thicknesses[i].startPoint, thicknesses[i].roughness)
        sld2Slab.thick.setp(vary=thicknesses[i].vary,
                            bounds=(thicknesses[i].lower,
                                    thicknesses[i].upper))
        sld2Slab.sld.real.setp(vary=slds[i].vary,
                               bounds=(slds[i].lower, slds[i].upper))

    if len(layerNames) >= 3:
        i = 2
        sld3 = SLD(slds[i].startPoint, name=layerNames[i])
        sld3Slab = sld3(thicknesses[i].startPoint, thicknesses[i].roughness)
        sld3Slab.thick.setp(vary=thicknesses[i].vary,
                            bounds=(thicknesses[i].lower,
                                    thicknesses[i].upper))
        sld3Slab.sld.real.setp(vary=slds[i].vary,
                               bounds=(slds[i].lower, slds[i].upper))

    if len(layerNames) >= 4:
        i = 3
        sld4 = SLD(slds[i].startPoint, name=layerNames[i])
        sld4Slab = sld4(thicknesses[i].startPoint, thicknesses[i].roughness)
        sld4Slab.thick.setp(vary=thicknesses[i].vary,
                            bounds=(thicknesses[i].lower,
                                    thicknesses[i].upper))
        sld4Slab.sld.real.setp(vary=slds[i].vary,
                               bounds=(slds[i].lower, slds[i].upper))

    if len(layerNames) == 1:
        structure = airSlab | sld1Slab | sio2Slab
    if len(layerNames) == 2:
        structure = airSlab | sld1Slab | sld2Slab | sio2Slab
    if len(layerNames) == 3:
        structure = airSlab | sld1Slab | sld2Slab | sld3Slab | sio2Slab
    if len(layerNames) == 4:
        structure = airSlab | sld1Slab | sld2Slab | sld3Slab | sld4Slab | sio2Slab
    model = ReflectModel(structure, bkg=3e-6, dq=5.0)
    objective = Objective(model,
                          data,
                          transform=Transform('logY'),
                          logp_extra=logpExtra)
    return objective, structure
示例#20
0
    def __init__(self):
        # attributes for the graph
        # for the graph
        self.qmin = 0.005
        self.qmax = 0.5
        self.qpnt = 1000
        self.fig = None

        self.ax_data = None
        self.ax_residual = None
        self.ax_sld = None
        # gridspecs specify how the plots are laid out. Gridspec1 is when the
        # residuals plot is displayed. Gridspec2 is when it's not visible
        self._gridspec1 = gridspec.GridSpec(2,
                                            2,
                                            height_ratios=[5, 1],
                                            width_ratios=[1, 1],
                                            hspace=0.01)
        self._gridspec2 = gridspec.GridSpec(1, 2)

        self.theoretical_plot = None
        self.theoretical_plot_sld = None

        # attributes for a user dataset
        self.dataset = None
        self.objective = None
        self._curvefitter = None
        self.data_plot = None
        self.residuals_plot = None
        self.data_plot_sld = None

        self.dataset_name = widgets.Text(description="dataset:")
        self.dataset_name.disabled = True
        self.chisqr = widgets.FloatText(description="chi-squared:")
        self.chisqr.disabled = True

        # fronting
        slab0 = Slab(0, 0, 0)
        slab1 = Slab(25, 3.47, 3)
        slab2 = Slab(0, 2.07, 3)

        structure = slab0 | slab1 | slab2
        rename_params(structure)
        self.model = ReflectModel(structure)
        structure = slab0 | slab1 | slab2
        self.model = ReflectModel(structure)

        # give some default parameter limits
        self.model.scale.bounds = (0.1, 2)
        self.model.bkg.bounds = (1e-8, 2e-5)
        self.model.dq.bounds = (0, 20)
        for slab in self.model.structure:
            slab.thick.bounds = (0, 2 * slab.thick.value)
            slab.sld.real.bounds = (0, 2 * slab.sld.real.value)
            slab.sld.imag.bounds = (0, 2 * slab.sld.imag.value)
            slab.rough.bounds = (0, 2 * slab.rough.value)

        # the main GUI widget
        self.display_box = widgets.VBox()

        self.tab = widgets.Tab()
        self.tab.set_title(0, "Model")
        self.tab.set_title(1, "Limits")
        self.tab.set_title(2, "Options")
        self.tab.observe(self._on_tab_changed, names="selected_index")

        # an output area for messages.
        self.output = widgets.Output()

        # options tab
        self.plot_type = widgets.Dropdown(
            options=["lin", "logY", "YX4", "YX2"],
            value="lin",
            description="Plot Type:",
            disabled=False,
        )
        self.plot_type.observe(self._on_plot_type_changed, names="value")
        self.use_weights = widgets.RadioButtons(
            options=["Yes", "No"],
            value="Yes",
            description="use dataset weights?",
            style={"description_width": "initial"},
        )
        self.use_weights.observe(self._on_use_weights_changed, names="value")
        self.transform = Transform("lin")
        self.display_residuals = widgets.Checkbox(
            value=False, description="Display residuals")
        self.display_residuals.observe(self._on_display_residuals_changed,
                                       names="value")

        self.model_view = None
        self.set_model(self.model)
示例#21
0
# In[ ]:

model_lipid_1 = ReflectModel(structure_lipid_1)
model_lipid_1.scale.setp(vary=True, bounds=(0.005, 10))
model_lipid_1.bkg.setp(dataset_1.y[-2], vary=False)

model_lipid_2 = ReflectModel(structure_lipid_2)
model_lipid_2.scale.setp(vary=True, bounds=(0.005, 10))
model_lipid_2.bkg.setp(dataset_2.y[-2], vary=False)

# The global objective fitting object is defined and the fitting and MCMC performed.

# In[ ]:

# building the global objective
objective_n1 = Objective(model_lipid_1, dataset_1, transform=Transform('YX4'))
objective_n2 = Objective(model_lipid_2, dataset_2, transform=Transform('YX4'))

global_objective = GlobalObjective([objective_n1, objective_n2])

# ## Fitting
#
# The differential evolution algorithm is used to find optimal parameters, before the MCMC algorithm probes the parameter space for 1000 steps.

# In[ ]:

# A differential evolution algorithm is used to obtain an best fit
fitter = CurveFitter(global_objective)
# A seed is used to ensure reproduciblity
res = fitter.fit('differential_evolution', seed=1)
# The first 200*200 samples are binned
model_lipid2 = ReflectModel(structure_lipid2)
model_lipid2.scale.setp(vary=True, bounds=(0.005, 10))
model_lipid2.bkg.setp(dataset2.y[-1], vary=False)

model_lipid3 = ReflectModel(structure_lipid3)
model_lipid3.scale.setp(vary=True, bounds=(0.005, 10))
model_lipid3.bkg.setp(dataset3.y[-1], vary=False)

model_lipid4 = ReflectModel(structure_lipid4)
model_lipid4.scale.setp(vary=True, bounds=(0.005, 10))
model_lipid4.bkg.setp(dataset4.y[-1], vary=False)

models = [model_lipid1, model_lipid2, model_lipid3, model_lipid4]

objective1 = Objective(model_lipid1, dataset1, transform=Transform('YX4'))
objective2 = Objective(model_lipid2, dataset2, transform=Transform('YX4'))
objective3 = Objective(model_lipid3, dataset3, transform=Transform('YX4'))
objective4 = Objective(model_lipid4, dataset4, transform=Transform('YX4'))

global_objective = GlobalObjective(
    [objective1, objective2, objective3, objective4])

# The chain is read in by refnx, and processed to assigned it to the global objective.

# In[8]:

chain = refnx.analysis.load_chain('{}/{}/chain.txt'.format(
    analysis_dir, lipid))

processed_chain = refnx.analysis.process_chain(global_objective, chain)
示例#23
0
    hold_phih=True,
)

models = []
t = len(cont)

for i in range(t):
    models.append(ReflectModel(structures[i]))
    models[i].scale.setp(vary=True, bounds=(0.005, 10))
    models[i].bkg.setp(datasets[i].y[-1], vary=True, bounds=(1e-4, 1e-10))

objectives = []
t = len(cont)
for i in range(t):
    objectives.append(
        Objective(models[i], datasets[i], transform=Transform("YX4")))

global_objective = GlobalObjective(objectives)

chain = refnx.analysis.load_chain("{}_chain.txt".format(anal_dir))

pchain = refnx.analysis.process_chain(global_objective, chain)

para_labels = [
    '_scale_{}_{}'.format(sp, cont[0]), '_bkg_{}_{}'.format(sp, cont[0]),
    '-d_h_{}'.format(sp), '-d_t_{}'.format(sp), '_rough_{}'.format(sp),
    '_scale_{}_{}'.format(sp, cont[1]), '_bkg_{}_{}'.format(sp, cont[1]),
    '_scale_{}_{}'.format(sp, cont[2]), '_bkg_{}_{}'.format(sp, cont[2]),
    '_scale_{}_{}'.format(sp, cont[3]), '_bkg_{}_{}'.format(sp, cont[3]),
    '_scale_{}_{}'.format(sp, cont[4]), '_bkg_{}_{}'.format(sp, cont[4]),
    '_scale_{}_{}'.format(sp, cont[5]), '_bkg_{}_{}'.format(sp, cont[5]),
示例#24
0
structure = si | sio2(30, 3) | film(250, 3) | d2o(0, 3)
structure[1].thick.setp(vary=True, bounds=(15., 50.))
structure[1].rough.setp(vary=True, bounds=(1., 6.))
structure[2].thick.setp(vary=True, bounds=(200, 300))
structure[2].sld.real.setp(vary=True, bounds=(0.1, 3))
structure[2].rough.setp(vary=True, bounds=(1, 6))

model = ReflectModel(structure, bkg=9e-6, scale=1.)
model.bkg.setp(vary=True, bounds=(1e-8, 1e-5))
model.scale.setp(vary=True, bounds=(0.9, 1.1))

# fit on a logR scale, but use weighting
objective = Objective(model,
                      data,
                      transform=Transform('logY'),
                      use_weights=True)

# create the fit instance
fitter = CurveFitter(objective)

# do the fit
res = fitter.fit(method='differential_evolution')

# see the fit results
print(objective)

fig = plt.figure()
ax = fig.add_subplot(2, 1, 1)
ax.scatter(data.x, data.y, label=DATASET_NAME)
ax.semilogy()
示例#25
0
def getObjective(data,
                 nLayers,
                 limits=None,
                 doMCMC=False,
                 fitDq=False,
                 logpExtra=None,
                 onlyStructure=False,
                 both=False):

    air = SLD(0, name="air layer")
    airSlab = air(10, 0)

    sio2 = SLD(10, name="bottem layer")
    sio2Slab = sio2(10, 0)

    if limits is None:
        limits = [350, 50, 4, 6]

#     maxThick = 350
#     lowerThick = 50
#     upperThick = maxThick - nLayers*lowerThick
#     lowerB = 4
#     upperB = 6

    maxThick = float(limits[0])
    lowerThick = limits[1]
    upperThick = maxThick - nLayers * lowerThick
    lowerB = limits[2]
    upperB = limits[3]
    if nLayers >= 1:
        sld1 = SLD(5, name="first layer")
        sld1Slab = sld1(maxThick / nLayers, 0)

    if nLayers >= 2:
        sld2 = SLD(5, name="second layer")
        sld2Slab = sld2(maxThick / nLayers, 0)

    if nLayers >= 3:
        sld3 = SLD(5, name="second layer")
        sld3Slab = sld3(maxThick / nLayers, 0)

    if nLayers >= 4:
        sld4 = SLD(5, name="second layer")
        sld4Slab = sld4(maxThick / nLayers, 0)

    if nLayers >= 1:
        sld1Slab.thick.setp(vary=True, bounds=(lowerThick, upperThick))
        sld1Slab.sld.real.setp(vary=True, bounds=(lowerB, upperB))

    if nLayers >= 2:
        sld2Slab.thick.setp(vary=True, bounds=(lowerThick, upperThick))
        sld2Slab.sld.real.setp(vary=True, bounds=(lowerB, upperB))

    if nLayers >= 3:
        sld3Slab.thick.setp(vary=True, bounds=(lowerThick, upperThick))
        sld3Slab.sld.real.setp(vary=True, bounds=(lowerB, upperB))

    if nLayers >= 4:
        sld4Slab.thick.setp(vary=True, bounds=(lowerThick, upperThick))
        sld4Slab.sld.real.setp(vary=True, bounds=(lowerB, upperB))

    if nLayers == 1:
        structure = airSlab | sld1Slab | sio2Slab
    if nLayers == 2:
        structure = airSlab | sld1Slab | sld2Slab | sio2Slab
    if nLayers == 3:
        structure = airSlab | sld1Slab | sld2Slab | sld3Slab | sio2Slab
    if nLayers == 4:
        structure = airSlab | sld1Slab | sld2Slab | sld3Slab | sld4Slab | sio2Slab
    if onlyStructure:
        returns = structure
    elif both:
        model = ReflectModel(structure, bkg=3e-6, dq=5.0)
        if fitDq:
            model.dq.setp(vary=True, bounds=(0., 10.))
        objective = Objective(model,
                              data,
                              transform=Transform('logY'),
                              logp_extra=logpExtra)
        returns = objective, structure
    else:
        model = ReflectModel(structure, bkg=3e-6, dq=5.0)
        if fitDq:
            model.dq.setp(vary=True, bounds=(0., 10.))
        objective = Objective(model,
                              data,
                              transform=Transform('logY'),
                              logp_extra=logpExtra)
        returns = objective
    return returns
示例#26
0
lipid_2.thick_heads.constraint = lipid_1.thick_heads
structure_lipid_2[-1].rough.constraint = structure_lipid_1[-1].rough

model_lipid1 = ReflectModel(structure_lipid_1)
model_lipid1.scale.setp(vary=True, bounds=(0.005, 10))
model_lipid1.bkg.setp(dataset1.y[-2], vary=False)

model_lipid2 = ReflectModel(structure_lipid_2)
model_lipid2.scale.setp(vary=True, bounds=(0.005, 10))
model_lipid2.bkg.setp(dataset2.y[-2], vary=False)

models = [model_lipid1, model_lipid2]
structures = [structure_lipid_1, structure_lipid_2]

# building the global objective
objective_n1 = Objective(model_lipid1, dataset1, transform=Transform('YX4'))
objective_n2 = Objective(model_lipid2, dataset2, transform=Transform('YX4'))

global_objective = GlobalObjective([objective_n1, objective_n2])

# The chain is read in by refnx, and processed to assigned it to the global objective.

# In[ ]:

chain = refnx.analysis.load_chain('{}/{}/{}_chain_neutron.txt'.format(
    analysis_dir, lipid, sp))

processed_chain = refnx.analysis.process_chain(global_objective, chain)

# The global objective is printed to check it is accurate.
示例#27
0
def global_fitter_setup(global_pilot_file, dqvals=5.0):
    # Parse the global_fitter setup from Igor.
    # TODO deal with user generated non-slab models.
    with open(global_pilot_file, 'r') as f:
        data_files = f.readline().split()
        pilot_files = f.readline().split()

    constraints = np.loadtxt(global_pilot_file, skiprows=2, dtype=int)

    # open the datafiles
    datasets = []
    for data_file in data_files:
        dataset = ReflectDataset(data_file)
        datasets.append(dataset)

    # deal with the individual pilot files
    parameters = []
    for pilot_file in pilot_files:
        pars = np.loadtxt(pilot_file, skiprows=4)

        # lets just assume for now that the data has resolution info
        # and that we're doing a slab model.
        pv = pars[:, 0][:]
        varies = (pars[:, 1].astype(int) == 0)

        # workout bounds, and account for the fact that MotofitMPI
        # doesn't set bounds for parameters that are fixed
        bounds = []
        for idx in range(np.size(pv)):
            if not varies[idx]:
                bounds.append((0, 2 * pv[idx]))
            else:
                bounds.append(pars[idx, 2:4])

        P = to_parameters(pv,
                          varies=varies,
                          bounds=bounds)
        parameters.append(P)

    # now create CurveFitting instances
    T = Transform('logY')
    fitters = []

    for parameter, dataset in zip(parameters, datasets):
        t_data_y, t_data_yerr = T.transform(dataset.x,
                                            dataset.y,
                                            dataset.y_err)

        if isinstance(dqvals, numbers.Real):
            _dqvals = float(dqvals)
        else:
            _dqvals = dataset.x_err

        c = CurveFitter(ReflectivityFitFunction(T.transform, workers=True),
                        (dataset.x, t_data_y, t_data_yerr),
                        parameter,
                        fcn_kws={'dqvals': _dqvals})
        fitters.append(c)

    # create globalfitter
    # setup constraints
    unique, indices = np.unique(constraints, return_index=True)

    # TODO assertions for checking linkage integrity

    n_datasets = len(datasets)

    def is_unique(row, col):
        ravelled_idx = row * n_datasets + col
        return ravelled_idx in indices

    cons = []
    for col in range(n_datasets):
        for row in range(len(parameters[col])):
            if constraints[row, col] == -1 or is_unique(row, col):
                continue
            # so it's not unique, but which parameter does it depend on?
            # find location of master parameter
            master = np.extract(unique == constraints[row, col], indices)[0]
            m_col = master % n_datasets
            m_row = (master - m_col) // n_datasets
            constraint = 'd%u:p%u = d%u:p%u' % (col, row, m_col, m_row)
            cons.append(constraint)

            # also have to rejig the bounds because MotoMPI doesn't
            # set bounds for those that aren't unique. But this is bad for
            # lmfit because it'll clip them.
            par = fitters[col].params['p%u' % row]
            m_par = fitters[m_col].params['p%u' % m_row]
            par.min = m_par.min
            par.max = m_par.max

    global_fitter = GlobalFitter(fitters, constraints=cons)

    # # update the constraints
    # global_fitter.params.update_constraints()

    return global_fitter
示例#28
0
 def test_transform_pickle(self):
     # can you pickle the Transform object?
     pkl = pickle.dumps(Transform('logY'))
     pickle.loads(pkl)
示例#29
0
def global_fitter_setup(global_pilot_file, dqvals=5.0):
    # Parse the global_fitter setup from Igor.
    # TODO deal with user generated non-slab models.
    with open(global_pilot_file, 'r') as f:
        data_files = f.readline().split()
        pilot_files = f.readline().split()

    constraints = np.loadtxt(global_pilot_file, skiprows=2, dtype=int)

    # open the datafiles
    datasets = []
    for data_file in data_files:
        dataset = ReflectDataset(data_file)
        datasets.append(dataset)

    # deal with the individual pilot files
    parameters = []
    for pilot_file in pilot_files:
        pars = np.loadtxt(pilot_file, skiprows=4)

        # lets just assume for now that the data has resolution info
        # and that we're doing a slab model.
        pv = pars[:, 0][:]
        varies = (pars[:, 1].astype(int) == 0)

        # workout bounds, and account for the fact that MotofitMPI
        # doesn't set bounds for parameters that are fixed
        bounds = []
        for idx in range(np.size(pv)):
            if not varies[idx]:
                bounds.append((0, 2 * pv[idx]))
            else:
                bounds.append(pars[idx, 2:4])

        P = to_parameters(pv, varies=varies, bounds=bounds)
        parameters.append(P)

    # now create CurveFitting instances
    T = Transform('logY')
    fitters = []

    for parameter, dataset in zip(parameters, datasets):
        t_data_y, t_data_yerr = T.transform(dataset.x, dataset.y,
                                            dataset.y_err)

        if isinstance(dqvals, numbers.Real):
            _dqvals = float(dqvals)
        else:
            _dqvals = dataset.x_err

        c = CurveFitter(ReflectivityFitFunction(T.transform, workers=True),
                        (dataset.x, t_data_y, t_data_yerr),
                        parameter,
                        fcn_kws={'dqvals': _dqvals})
        fitters.append(c)

    # create globalfitter
    # setup constraints
    unique, indices = np.unique(constraints, return_index=True)

    # TODO assertions for checking linkage integrity

    n_datasets = len(datasets)

    def is_unique(row, col):
        ravelled_idx = row * n_datasets + col
        return ravelled_idx in indices

    cons = []
    for col in range(n_datasets):
        for row, val in enumerate(parameters[col]):
            if constraints[row, col] == -1 or is_unique(row, col):
                continue
            # so it's not unique, but which parameter does it depend on?
            # find location of master parameter
            master = np.extract(unique == constraints[row, col], indices)[0]
            m_col = master % n_datasets
            m_row = (master - m_col) // n_datasets
            constraint = 'd%u:p%u = d%u:p%u' % (col, row, m_col, m_row)
            cons.append(constraint)

            # also have to rejig the bounds because MotoMPI doesn't
            # set bounds for those that aren't unique. But this is bad for
            # lmfit because it'll clip them.
            par = fitters[col].params['p%u' % row]
            m_par = fitters[m_col].params['p%u' % m_row]
            par.min = m_par.min
            par.max = m_par.max

    global_fitter = GlobalFitter(fitters, constraints=cons)

    # # update the constraints
    # global_fitter.params.update_constraints()

    return global_fitter
示例#30
0
    n = l.reshape(timesteps, sim.layers.shape[1]-layers_to_cut, sim.layers.shape[2])

    data_dir = '../data/reflectometry2/dspc_{}/'.format(surface_pressure)
    dataset = ReflectDataset(os.path.join(data_dir, '{}{}.dat'.format(contrast, surface_pressure)))

    refy = np.zeros((n.shape[0], dataset.x.size))
    sldy = []
    chi = np.zeros((n.shape[0]))
    print(n.shape[0])
    for i in range(n.shape[0]):
        sim.av_layers = n[i, :, :]
        model = ReflectModel(sim)
        model.scale.setp(1, vary=True, bounds=(0.00000001, np.inf))
        model.bkg.setp(dataset.y[-1], vary=False)
        objective = Objective(model, dataset, transform=Transform('YX4'))
        fitter = CurveFitter(objective)
        res = fitter.fit()
        refy[i] = model(dataset.x, x_err=dataset.x_err)*(dataset.x)**4
        sldy.append(sim.sld_profile()[1])
        chi[i] = objective.chisqr()
        all_chi = np.append(all_chi, objective.chisqr())
        if i == 0:
            ax1.errorbar(dataset.x,
                         dataset.y*(dataset.x)**4 * 10**(ci-1),
                         yerr=dataset.y_err*(
                             dataset.x)**4 * 10**(ci-1),
                         linestyle='', marker='o',
                         color=sns.color_palette()[ci])
        if i % 5 == 0:
            ax1.plot(dataset.x,
示例#31
0
def seperateNLayer(data, nLayers, limits = None, doMCMC=False): #used

    air = SLD(0,name="air layer")
    airSlab = air(10,0)

    sio2 = SLD(10,name="bottem layer")
    sio2Slab = sio2(10,0)


    if limits is None:
        limits = [350,50,4,6]
    
#     maxThick = 350
#     lowerThick = 50
#     upperThick = maxThick - nLayers*lowerThick
#     lowerB = 4
#     upperB = 6

    maxThick = float(limits[0])
    lowerThick = limits[1]
    upperThick = maxThick - nLayers*lowerThick
    lowerB = limits[2]
    upperB = limits[3]
    if nLayers>=1:
        sld1 = SLD(5,name="first layer")
        sld1Slab = sld1(maxThick/nLayers,0)

    if nLayers>=2:
        sld2 = SLD(5,name="second layer")
        sld2Slab = sld2(maxThick/nLayers,0)

    if nLayers>=3:
        sld3 = SLD(5,name="second layer")
        sld3Slab = sld3(maxThick/nLayers,0)

    if nLayers>=4:
        sld4 = SLD(5,name="second layer")
        sld4Slab = sld4(maxThick/nLayers,0)

    if nLayers>=1:
        sld1Slab.thick.setp(vary=True, bounds=(lowerThick,upperThick))
        sld1Slab.sld.real.setp(vary=True, bounds=(lowerB,upperB))

    if nLayers>=2:
        sld2Slab.thick.setp(vary=True, bounds=(lowerThick,upperThick))
        sld2Slab.sld.real.setp(vary=True, bounds=(lowerB,upperB))

    if nLayers>=3:
        sld3Slab.thick.setp(vary=True, bounds=(lowerThick,upperThick))
        sld3Slab.sld.real.setp(vary=True, bounds=(lowerB,upperB))

    if nLayers>=4:
        sld4Slab.thick.setp(vary=True, bounds=(lowerThick,upperThick))
        sld4Slab.sld.real.setp(vary=True, bounds=(lowerB,upperB))

    if nLayers>=1:
        structure = airSlab|sld1Slab|sio2Slab
    if nLayers>=2:
        structure = airSlab|sld1Slab|sld2Slab|sio2Slab
    if nLayers>=3:
        structure = airSlab|sld1Slab|sld2Slab|sld3Slab|sio2Slab
    if nLayers>=4:
        structure = airSlab|sld1Slab|sld2Slab|sld3Slab|sld4Slab|sio2Slab

    model = ReflectModel(structure, bkg=3e-6, dq=5.0)
    objective = Objective(model, data, transform=Transform('logY'))
    fitter = CurveFitter(objective)
    if not doMCMC:
        fitter.fit("differential_evolution")
    else:
        fitter.sample(500)
        fitter.sampler.reset()
        fitter.sample(40, nthin=50)
        pass
#     print(objective.parameters)
    lp = objective.logpost()
#     print("log: ", lp)
    return lp