Skip to content
Snippets Groups Projects
Commit 41b73247 authored by Pospelov, Gennady's avatar Pospelov, Gennady
Browse files

Minor style fixes in python examples

parent 6eab15be
No related branches found
No related tags found
No related merge requests found
...@@ -23,11 +23,11 @@ def get_sample(params): ...@@ -23,11 +23,11 @@ def get_sample(params):
cylinder_ff = ba.FormFactorCylinder(radius, height) cylinder_ff = ba.FormFactorCylinder(radius, height)
cylinder = ba.Particle(m_particle, cylinder_ff) cylinder = ba.Particle(m_particle, cylinder_ff)
particle_layout = ba.ParticleLayout() layout = ba.ParticleLayout()
particle_layout.addParticle(cylinder) layout.addParticle(cylinder)
air_layer = ba.Layer(m_air) air_layer = ba.Layer(m_air)
air_layer.addLayout(particle_layout) air_layer.addLayout(layout)
substrate_layer = ba.Layer(m_substrate, 0) substrate_layer = ba.Layer(m_substrate, 0)
multi_layer = ba.MultiLayer() multi_layer = ba.MultiLayer()
...@@ -59,10 +59,9 @@ def create_real_data(): ...@@ -59,10 +59,9 @@ def create_real_data():
""" """
params = {'radius': 5.0*nm, 'height': 10.0*nm} params = {'radius': 5.0*nm, 'height': 10.0*nm}
# retrieving simulated data in the form of numpy array
simulation = get_simulation(params, add_masks=False) simulation = get_simulation(params, add_masks=False)
simulation.runSimulation() simulation.runSimulation()
# retrieving simulated data in the form of numpy array
real_data = simulation.result().array() real_data = simulation.result().array()
# spoiling simulated data with the noise to produce "real" data # spoiling simulated data with the noise to produce "real" data
...@@ -81,7 +80,7 @@ def add_mask_to_simulation(simulation): ...@@ -81,7 +80,7 @@ def add_mask_to_simulation(simulation):
with the mask value either "True" (detector bin is excluded from the simulation) with the mask value either "True" (detector bin is excluded from the simulation)
or False (will be simulated). or False (will be simulated).
Every subsequent mask override previously defined masks in this area. Every subsequent mask overrides previously defined mask in this area.
In the code below we put masks in such way that simulated image will look like In the code below we put masks in such way that simulated image will look like
a Pac-Man from ancient arcade game. a Pac-Man from ancient arcade game.
......
...@@ -2,7 +2,6 @@ ...@@ -2,7 +2,6 @@
Fitting example: fit along slices Fitting example: fit along slices
""" """
import numpy as np
from matplotlib import pyplot as plt from matplotlib import pyplot as plt
import bornagain as ba import bornagain as ba
from bornagain import deg, angstrom, nm from bornagain import deg, angstrom, nm
...@@ -25,11 +24,11 @@ def get_sample(params): ...@@ -25,11 +24,11 @@ def get_sample(params):
cylinder_ff = ba.FormFactorCylinder(radius, height) cylinder_ff = ba.FormFactorCylinder(radius, height)
cylinder = ba.Particle(m_particle, cylinder_ff) cylinder = ba.Particle(m_particle, cylinder_ff)
particle_layout = ba.ParticleLayout() layout = ba.ParticleLayout()
particle_layout.addParticle(cylinder) layout.addParticle(cylinder)
air_layer = ba.Layer(m_air) air_layer = ba.Layer(m_air)
air_layer.addLayout(particle_layout) air_layer.addLayout(layout)
substrate_layer = ba.Layer(m_substrate, 0) substrate_layer = ba.Layer(m_substrate, 0)
multi_layer = ba.MultiLayer() multi_layer = ba.MultiLayer()
...@@ -43,15 +42,16 @@ def get_simulation(params, add_masks=True): ...@@ -43,15 +42,16 @@ def get_simulation(params, add_masks=True):
Create and return GISAXS simulation with beam and detector defined Create and return GISAXS simulation with beam and detector defined
""" """
simulation = ba.GISASSimulation() simulation = ba.GISASSimulation()
simulation.setDetectorParameters(100, -1.0*deg, 1.0*deg, simulation.setDetectorParameters(100, -1.0*deg, 1.0*deg, 100, 0.0*deg, 2.0*deg)
100, 0.0*deg, 2.0*deg)
simulation.setBeamParameters(1.0*angstrom, 0.2*deg, 0.0*deg) simulation.setBeamParameters(1.0*angstrom, 0.2*deg, 0.0*deg)
simulation.setBeamIntensity(1e+08) simulation.setBeamIntensity(1e+08)
simulation.setSample(get_sample(params)) simulation.setSample(get_sample(params))
if add_masks: if add_masks:
# At this point we mask all the detector and then unmask two areas """
# corresponding to the vertical and horizontal lines. This will make At this point we mask all the detector and then unmask two areas
# simulation/fitting to be performed along slices only. corresponding to the vertical and horizontal lines. This will make
simulation/fitting to be performed along slices only.
"""
simulation.maskAll() simulation.maskAll()
simulation.addMask(ba.HorizontalLine(alpha_slice_value*deg), False) simulation.addMask(ba.HorizontalLine(alpha_slice_value*deg), False)
simulation.addMask(ba.VerticalLine(phi_slice_value*deg), False) simulation.addMask(ba.VerticalLine(phi_slice_value*deg), False)
...@@ -62,22 +62,18 @@ def create_real_data(): ...@@ -62,22 +62,18 @@ def create_real_data():
""" """
Generating "real" data by adding noise to the simulated data. Generating "real" data by adding noise to the simulated data.
""" """
# initial values which we will have to find later during the fit
params = {'radius': 5.0*nm, 'height': 10.0*nm} params = {'radius': 5.0*nm, 'height': 10.0*nm}
# retrieving simulated data in the form of numpy array
simulation = get_simulation(params, add_masks=False) simulation = get_simulation(params, add_masks=False)
simulation.setBackground(ba.PoissonNoiseBackground())
simulation.runSimulation() simulation.runSimulation()
# retrieving simulated data in the form of numpy array return simulation.result().array()
real_data = simulation.result().array()
# spoiling simulated data with the noise to produce "real" data
noise_factor = 0.1
noisy = np.random.normal(real_data, noise_factor*np.sqrt(real_data))
noisy[noisy < 0.1] = 0.1
return noisy
class PlotObserver(): class PlotObserver:
""" """
Draws fit progress every nth iteration. Here we plot slices along real Draws fit progress every nth iteration. Here we plot slices along real
and simulated images to see fit progress. and simulated images to see fit progress.
...@@ -87,8 +83,15 @@ class PlotObserver(): ...@@ -87,8 +83,15 @@ class PlotObserver():
self.fig = plt.figure(figsize=(10.25, 7.69)) self.fig = plt.figure(figsize=(10.25, 7.69))
self.fig.canvas.draw() self.fig.canvas.draw()
def plot_real_data(self, data, nplot): def __call__(self, fit_objective):
plt.subplot(2, 2, nplot) self.update(fit_objective)
@staticmethod
def plot_real_data(data):
"""
Plot experimental data as colormap with horizontal/vertical lines
representing slices on top.
"""
plt.subplots_adjust(wspace=0.2, hspace=0.2) plt.subplots_adjust(wspace=0.2, hspace=0.2)
ba.plot_histogram(data, title="Experimental data") ba.plot_histogram(data, title="Experimental data")
# line representing vertical slice # line representing vertical slice
...@@ -100,8 +103,11 @@ class PlotObserver(): ...@@ -100,8 +103,11 @@ class PlotObserver():
[alpha_slice_value, alpha_slice_value], [alpha_slice_value, alpha_slice_value],
color='gray', linestyle='-', linewidth=1) color='gray', linestyle='-', linewidth=1)
def plot_slices(self, slices, title, nplot): @staticmethod
plt.subplot(2, 2, nplot) def plot_slices(slices, title):
"""
Plots vertical and horizontal projections.
"""
plt.subplots_adjust(wspace=0.2, hspace=0.3) plt.subplots_adjust(wspace=0.2, hspace=0.3)
for label, slice in slices: for label, slice in slices:
plt.semilogy(slice.getBinCenters(), plt.semilogy(slice.getBinCenters(),
...@@ -111,8 +117,11 @@ class PlotObserver(): ...@@ -111,8 +117,11 @@ class PlotObserver():
plt.legend(loc='upper right') plt.legend(loc='upper right')
plt.title(title) plt.title(title)
def display_fit_parameters(self, fit_objective, nplot): @staticmethod
plt.subplot(2, 2, nplot) def display_fit_parameters(fit_objective):
"""
Displays fit parameters, chi and iteration number.
"""
plt.title('Parameters') plt.title('Parameters')
plt.axis('off') plt.axis('off')
...@@ -121,45 +130,49 @@ class PlotObserver(): ...@@ -121,45 +130,49 @@ class PlotObserver():
plt.text(0.01, 0.85, "Iterations " + '{:d}'. plt.text(0.01, 0.85, "Iterations " + '{:d}'.
format(iteration_info.iterationCount())) format(iteration_info.iterationCount()))
plt.text(0.01, 0.75, "Chi2 " + '{:8.4f}'.format(iteration_info.chi2())) plt.text(0.01, 0.75, "Chi2 " + '{:8.4f}'.format(iteration_info.chi2()))
index = 0 for index, params in enumerate(iteration_info.parameters()):
params = iteration_info.parameterMap()
for key in params:
plt.text(0.01, 0.55 - index * 0.1, plt.text(0.01, 0.55 - index * 0.1,
'{:30.30s}: {:6.3f}'.format(key, params[key])) '{:30.30s}: {:6.3f}'.format(params.name(), params.value))
index = index + 1
plt.tight_layout() plt.tight_layout()
plt.draw() plt.draw()
plt.pause(0.01) plt.pause(0.01)
def update(self, fit_objective): def update(self, fit_objective):
"""
Callback to access fit_objective on every n'th iteration.
"""
self.fig.clf() self.fig.clf()
real_data = fit_objective.experimentalData().histogram2d() real_data = fit_objective.experimentalData().histogram2d()
simul_data = fit_objective.simulationResult().histogram2d() simul_data = fit_objective.simulationResult().histogram2d()
# plot real data # plot real data
self.plot_real_data(real_data, nplot=1) plt.subplot(2, 2, 1)
self.plot_real_data(real_data)
# horizontal slices # horizontal slices
slices =[ slices = [
("real", real_data.projectionX(alpha_slice_value)), ("real", real_data.projectionX(alpha_slice_value)),
("simul", simul_data.projectionX(alpha_slice_value)) ("simul", simul_data.projectionX(alpha_slice_value))
] ]
title = ( "Horizontal slice at alpha =" + title = ("Horizontal slice at alpha =" + '{:3.1f}'.format(alpha_slice_value))
'{:3.1f}'.format(alpha_slice_value) ) plt.subplot(2, 2, 2)
self.plot_slices(slices, title, nplot=2) self.plot_slices(slices, title)
# vertical slices # vertical slices
slices =[ slices = [
("real", real_data.projectionY(phi_slice_value)), ("real", real_data.projectionY(phi_slice_value)),
("simul", simul_data.projectionY(phi_slice_value)) ("simul", simul_data.projectionY(phi_slice_value))
] ]
title = "Vertical slice at phi =" + '{:3.1f}'.format(phi_slice_value) title = "Vertical slice at phi =" + '{:3.1f}'.format(phi_slice_value)
self.plot_slices(slices, title, nplot=3) plt.subplot(2, 2, 3)
self.plot_slices(slices, title)
# display fit parameters # display fit parameters
self.display_fit_parameters(fit_objective, nplot=4) plt.subplot(2, 2, 4)
self.display_fit_parameters(fit_objective)
def run_fitting(): def run_fitting():
...@@ -175,7 +188,7 @@ def run_fitting(): ...@@ -175,7 +188,7 @@ def run_fitting():
# creating custom observer which will draw fit progress # creating custom observer which will draw fit progress
plotter = PlotObserver() plotter = PlotObserver()
fit_objective.initPlot(10, plotter.update) fit_objective.initPlot(10, plotter)
params = ba.Parameters() params = ba.Parameters()
params.add("radius", 6.*nm, min=4.0, max=8.0) params.add("radius", 6.*nm, min=4.0, max=8.0)
......
""" """
Fitting example: demonstrates how to fit two datasets simultaneously. Fitting example: simultaneous fit of two datasets
""" """
import numpy as np import numpy as np
...@@ -21,16 +21,16 @@ def get_sample(params): ...@@ -21,16 +21,16 @@ def get_sample(params):
m_substrate = ba.HomogeneousMaterial("Substrate", 6e-6, 2e-8) m_substrate = ba.HomogeneousMaterial("Substrate", 6e-6, 2e-8)
m_particle = ba.HomogeneousMaterial("Particle", 6e-4, 2e-8) m_particle = ba.HomogeneousMaterial("Particle", 6e-4, 2e-8)
formFactor = ba.FormFactorHemiEllipsoid(radius_a, radius_b, height) formfactor = ba.FormFactorHemiEllipsoid(radius_a, radius_b, height)
hemiEllipsoid = ba.Particle(m_particle, formFactor) particle = ba.Particle(m_particle, formfactor)
particle_layout = ba.ParticleLayout() layout = ba.ParticleLayout()
particle_layout.addParticle(hemiEllipsoid) layout.addParticle(particle)
air_layer = ba.Layer(m_air) air_layer = ba.Layer(m_air)
air_layer.addLayout(particle_layout) air_layer.addLayout(layout)
substrate_layer = ba.Layer(m_substrate, 0) substrate_layer = ba.Layer(m_substrate)
multi_layer = ba.MultiLayer() multi_layer = ba.MultiLayer()
multi_layer.addLayer(air_layer) multi_layer.addLayer(air_layer)
multi_layer.addLayer(substrate_layer) multi_layer.addLayer(substrate_layer)
...@@ -87,11 +87,15 @@ class PlotObserver(): ...@@ -87,11 +87,15 @@ class PlotObserver():
Draws fit progress every nth iteration. Real data, simulated data Draws fit progress every nth iteration. Real data, simulated data
and chi2 map will be shown for both datasets. and chi2 map will be shown for both datasets.
""" """
def __init__(self, draw_every_nth=10): def __init__(self):
self.fig = plt.figure(figsize=(12.8, 10.24)) self.fig = plt.figure(figsize=(12.8, 10.24))
self.fig.canvas.draw() self.fig.canvas.draw()
def plot_datasets(self, fit_objective, canvas): def __call__(self, fit_objective):
self.update(fit_objective)
@staticmethod
def plot_dataset(fit_objective, canvas):
for i_dataset in range(0, fit_objective.fitObjectCount()): for i_dataset in range(0, fit_objective.fitObjectCount()):
real_data = fit_objective.experimentalData(i_dataset) real_data = fit_objective.experimentalData(i_dataset)
simul_data = fit_objective.simulationResult(i_dataset) simul_data = fit_objective.simulationResult(i_dataset)
...@@ -101,17 +105,36 @@ class PlotObserver(): ...@@ -101,17 +105,36 @@ class PlotObserver():
plt.subplot(canvas[i_dataset*3]) plt.subplot(canvas[i_dataset*3])
ba.plot_colormap(real_data, title="\"Real\" data - #"+str(i_dataset+1), ba.plot_colormap(real_data, title="\"Real\" data - #"+str(i_dataset+1),
zmin=1.0, zmax=zmax, zlabel="") zmin=1.0, zmax=zmax, zlabel="")
plt.subplot(canvas[1+i_dataset*3]) plt.subplot(canvas[1+i_dataset*3])
ba.plot_colormap(simul_data, title="Simulated data - #"+str(i_dataset+1), ba.plot_colormap(simul_data, title="Simulated data - #"+str(i_dataset+1),
zmin=1.0, zmax=zmax, zlabel="") zmin=1.0, zmax=zmax, zlabel="")
plt.subplot(canvas[2+i_dataset*3]) plt.subplot(canvas[2+i_dataset*3])
ba.plot_colormap(chi2_map, title="Chi2 map - #"+str(i_dataset+1), ba.plot_colormap(chi2_map, title="Chi2 map - #"+str(i_dataset+1),
zmin=0.001, zmax=10.0, zlabel="") zmin=0.001, zmax=10.0, zlabel="")
@staticmethod
def display_fit_parameters(fit_objective):
"""
Displays fit parameters, chi and iteration number.
"""
plt.title('Parameters')
plt.axis('off')
def plot_fit_parameters(self, fit_objective, canvas): iteration_info = fit_objective.iterationInfo()
# fit parameters
plt.subplot(canvas[6:]) plt.text(0.01, 0.85, "Iterations " + '{:d}'.
format(iteration_info.iterationCount()))
plt.text(0.01, 0.75, "Chi2 " + '{:8.4f}'.format(iteration_info.chi2()))
for index, params in enumerate(iteration_info.parameters()):
plt.text(0.01, 0.55 - index * 0.1,
'{:30.30s}: {:6.3f}'.format(params.name(), params.value))
@staticmethod
def plot_fit_parameters(fit_objective):
"""
Displays fit parameters, chi and iteration number.
"""
plt.axis('off') plt.axis('off')
iteration_info = fit_objective.iterationInfo() iteration_info = fit_objective.iterationInfo()
...@@ -119,15 +142,11 @@ class PlotObserver(): ...@@ -119,15 +142,11 @@ class PlotObserver():
plt.text(0.01, 0.95, "Iterations " + '{:d}'. plt.text(0.01, 0.95, "Iterations " + '{:d}'.
format(iteration_info.iterationCount())) format(iteration_info.iterationCount()))
plt.text(0.01, 0.70, "Chi2 " + '{:8.4f}'.format(iteration_info.chi2())) plt.text(0.01, 0.70, "Chi2 " + '{:8.4f}'.format(iteration_info.chi2()))
index = 0 for index, params in enumerate(iteration_info.parameters()):
params = iteration_info.parameterMap()
for key in params:
plt.text(0.01, 0.30 - index * 0.3, plt.text(0.01, 0.30 - index * 0.3,
'{:30.30s}: {:6.3f}'.format(key, params[key])) '{:30.30s}: {:6.3f}'.format(params.name(), params.value))
index = index + 1
def update(self, fit_suite): def update(self, fit_objective):
self.fig.clf() self.fig.clf()
# we divide figure to have 3x3 subplots, with two first rows occupying # we divide figure to have 3x3 subplots, with two first rows occupying
...@@ -136,14 +155,14 @@ class PlotObserver(): ...@@ -136,14 +155,14 @@ class PlotObserver():
3, 3, width_ratios=[1, 1, 1], height_ratios=[4, 4, 1]) 3, 3, width_ratios=[1, 1, 1], height_ratios=[4, 4, 1])
canvas.update(left=0.05, right=0.95, hspace=0.5, wspace=0.2) canvas.update(left=0.05, right=0.95, hspace=0.5, wspace=0.2)
self.plot_datasets(fit_suite, canvas) self.plot_dataset(fit_objective, canvas)
self.plot_fit_parameters(fit_suite, canvas) plt.subplot(canvas[6:])
self.plot_fit_parameters(fit_objective)
plt.draw() plt.draw()
plt.pause(0.01) plt.pause(0.01)
def run_fitting(): def run_fitting():
""" """
main function to run fitting main function to run fitting
...@@ -166,7 +185,6 @@ def run_fitting(): ...@@ -166,7 +185,6 @@ def run_fitting():
params.add("radius_b", 6.*nm, vary=False) params.add("radius_b", 6.*nm, vary=False)
params.add("height", 4.*nm, min=2.0, max=10.0) params.add("height", 4.*nm, min=2.0, max=10.0)
print("begin")
minimizer = ba.Minimizer() minimizer = ba.Minimizer()
result = minimizer.minimize(fit_objective.evaluate, params) result = minimizer.minimize(fit_objective.evaluate, params)
fit_objective.finalize(result) fit_objective.finalize(result)
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment