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])
def test_multipledataset_corefinement(self): # test corefinement of three datasets data361 = ReflectDataset(os.path.join(self.pth, 'e361r.txt')) data365 = ReflectDataset(os.path.join(self.pth, 'e365r.txt')) data366 = ReflectDataset(os.path.join(self.pth, 'e366r.txt')) si = SLD(2.07, name='Si') sio2 = SLD(3.47, name='SiO2') d2o = SLD(6.36, name='d2o') h2o = SLD(-0.56, name='h2o') cm3 = SLD(3.47, name='cm3') polymer = SLD(1, name='polymer') structure361 = si | sio2(10, 4) | polymer(200, 3) | d2o(0, 3) structure365 = si | structure361[1] | structure361[2] | cm3(0, 3) structure366 = si | structure361[1] | structure361[2] | h2o(0, 3) structure365[-1].rough = structure361[-1].rough structure366[-1].rough = structure361[-1].rough structure361[1].thick.setp(vary=True, bounds=(0, 20)) structure361[2].thick.setp(value=200., bounds=(200., 250.), vary=True) structure361[2].sld.real.setp(vary=True, bounds=(0, 2)) structure361[2].vfsolv.setp(value=5., bounds=(0., 100.), vary=True) model361 = ReflectModel(structure361, bkg=2e-5) model365 = ReflectModel(structure365, bkg=2e-5) model366 = ReflectModel(structure366, bkg=2e-5) model361.bkg.setp(vary=True, bounds=(1e-6, 5e-5)) model365.bkg.setp(vary=True, bounds=(1e-6, 5e-5)) model366.bkg.setp(vary=True, bounds=(1e-6, 5e-5)) objective361 = Objective(model361, data361) objective365 = Objective(model365, data365) objective366 = Objective(model366, data366) global_objective = GlobalObjective( [objective361, objective365, objective366]) # are the right numbers of parameters varying? assert_equal(len(global_objective.varying_parameters()), 7) # can we set the parameters? global_objective.setp(np.array([1e-5, 10, 212, 1, 10, 1e-5, 1e-5])) f = CurveFitter(global_objective) f.fit() indiv_chisqr = np.sum( [objective.chisqr() for objective in global_objective.objectives]) # the overall chi2 should be sum of individual chi2 global_chisqr = global_objective.chisqr() assert_almost_equal(global_chisqr, indiv_chisqr) # now check that the parameters were held in common correctly. slabs361 = structure361.slabs() slabs365 = structure365.slabs() slabs366 = structure366.slabs() assert_equal(slabs365[0:2, 0:5], slabs361[0:2, 0:5]) assert_equal(slabs366[0:2, 0:5], slabs361[0:2, 0:5]) assert_equal(slabs365[-1, 3], slabs361[-1, 3]) assert_equal(slabs366[-1, 3], slabs361[-1, 3]) # check that the residuals are the correct lengths res361 = objective361.residuals() res365 = objective365.residuals() res366 = objective366.residuals() res_global = global_objective.residuals() assert_allclose(res_global[0:len(res361)], res361, rtol=1e-5) assert_allclose(res_global[len(res361):len(res361) + len(res365)], res365, rtol=1e-5) assert_allclose(res_global[len(res361) + len(res365):], res366, rtol=1e-5) repr(global_objective)
class TestGlobalFitting(object): 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]) def test_residuals_length(self): # the residuals should be the same length as the data residuals = self.global_objective.residuals() assert_equal(residuals.size, len(self.dataset)) 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) def test_multipledataset_corefinement(self): # test corefinement of three datasets data361 = ReflectDataset(os.path.join(self.pth, 'e361r.txt')) data365 = ReflectDataset(os.path.join(self.pth, 'e365r.txt')) data366 = ReflectDataset(os.path.join(self.pth, 'e366r.txt')) si = SLD(2.07, name='Si') sio2 = SLD(3.47, name='SiO2') d2o = SLD(6.36, name='d2o') h2o = SLD(-0.56, name='h2o') cm3 = SLD(3.47, name='cm3') polymer = SLD(1, name='polymer') structure361 = si | sio2(10, 4) | polymer(200, 3) | d2o(0, 3) structure365 = si | structure361[1] | structure361[2] | cm3(0, 3) structure366 = si | structure361[1] | structure361[2] | h2o(0, 3) structure365[-1].rough = structure361[-1].rough structure366[-1].rough = structure361[-1].rough structure361[1].thick.setp(vary=True, bounds=(0, 20)) structure361[2].thick.setp(value=200., bounds=(200., 250.), vary=True) structure361[2].sld.real.setp(vary=True, bounds=(0, 2)) structure361[2].vfsolv.setp(value=5., bounds=(0., 100.), vary=True) model361 = ReflectModel(structure361, bkg=2e-5) model365 = ReflectModel(structure365, bkg=2e-5) model366 = ReflectModel(structure366, bkg=2e-5) model361.bkg.setp(vary=True, bounds=(1e-6, 5e-5)) model365.bkg.setp(vary=True, bounds=(1e-6, 5e-5)) model366.bkg.setp(vary=True, bounds=(1e-6, 5e-5)) objective361 = Objective(model361, data361) objective365 = Objective(model365, data365) objective366 = Objective(model366, data366) global_objective = GlobalObjective( [objective361, objective365, objective366]) # are the right numbers of parameters varying? assert_equal(len(global_objective.varying_parameters()), 7) # can we set the parameters? global_objective.setp(np.array([1e-5, 10, 212, 1, 10, 1e-5, 1e-5])) f = CurveFitter(global_objective) f.fit() indiv_chisqr = np.sum( [objective.chisqr() for objective in global_objective.objectives]) # the overall chi2 should be sum of individual chi2 global_chisqr = global_objective.chisqr() assert_almost_equal(global_chisqr, indiv_chisqr) # now check that the parameters were held in common correctly. slabs361 = structure361.slabs() slabs365 = structure365.slabs() slabs366 = structure366.slabs() assert_equal(slabs365[0:2, 0:5], slabs361[0:2, 0:5]) assert_equal(slabs366[0:2, 0:5], slabs361[0:2, 0:5]) assert_equal(slabs365[-1, 3], slabs361[-1, 3]) assert_equal(slabs366[-1, 3], slabs361[-1, 3]) # check that the residuals are the correct lengths res361 = objective361.residuals() res365 = objective365.residuals() res366 = objective366.residuals() res_global = global_objective.residuals() assert_allclose(res_global[0:len(res361)], res361, rtol=1e-5) assert_allclose(res_global[len(res361):len(res361) + len(res365)], res365, rtol=1e-5) assert_allclose(res_global[len(res361) + len(res365):], res366, rtol=1e-5) repr(global_objective)
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]), '_scale_{}_{}'.format(sp, cont[6]), '_bkg_{}_{}'.format(sp, cont[6]) ]
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
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) # The global objective is printed to check it is accurate. # In[9]: print(global_objective)
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=False) objectives = [] if neutron: t = len(cont) else: t = sp.size for i in range(t): objectives.append( Objective(models[i], datasets[i], transform=Transform("YX4"))) global_objective = GlobalObjective(objectives) fitter = CurveFitter(global_objective) np.random.seed(1) res = fitter.fit("differential_evolution") print(global_objective) fitter.sample(200, random_state=1) fitter.sampler.reset() res = fitter.sample( 1000, nthin=1, random_state=1, f="{}/{}_chain.txt".format(anal_dir, label), )
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] # The global objective fitting object is defined and the fitting and MCMC performed. # In[ ]: 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]) # ## Fitting # # The differential evolution algorithm is used to find optimal parameters, before the MCMC algorithm probes the parameter space for 1000 steps. # In[ ]: fitter = CurveFitter(global_objective) res = fitter.fit('differential_evolution', seed=1) fitter.sample(200, random_state=1) fitter.sampler.reset() res = fitter.sample(1000, nthin=1, random_state=1,
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. # In[ ]: print(global_objective)
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 fitter.sample(200, random_state=1) fitter.sampler.reset() # The collection is across 5000*200 samples