Particle distribution

This tutorial gives an overview on how to draw a set of particles whose parameters follow a desired distribution. To fix ideas, let’s build the argument around cylindrical particles; In this case, the parameters will be radius, $r$; and height, $h$; the same reasoning should apply to other kinds of particles whose parameters differ (e.g. an Icosahedron does not have a parameter “radius”).

No distribution

In the case in which a particle distribution is not applied, all particles are identical; for cylindrical particles, this means having the same radius and the same height (the default value is $5 , \rm{nm}$ for both).

Adding irregularities to a set of identical particles

Let’s start with a concrete example. To create a Gaussian distribution for the radius of cylindrical particles with the following properties,

  • Mean: $5.0 , \rm{nm}$,
  • StdDev: $2.0 , \rm{nm}$,
  • Number of samples: $5$,
  • Sigma Factor: $1.5$,
  • Limits: $(1.0 , \rm{nm},9.0 , \rm{nm})$,

one can roughly use the following recipe:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
#Define Gaussian Distribution:
mean_length = 5.0*nm
stdDev_length = 2.0*nm
distribution = ba.DistributionGaussian(mean_length, stdDev_length)

#Carry out the actual value sampling:
parameter_to_modify = "/Particle/Cylinder/Radius"
number_of_samples = 5
sigma_factor = 2.0
limits = ba.RealLimits.limited(1.0*nm, 9.0*nm))
my_parameter_distribution = ba.ParameterDistribution(parameter_to_modify,
                                                     distribution,
                                                     number_of_samples,
                                                     sigma_factor,
                                                     limits)

#Create the particle distribution with the sampled values:
my_particle_distribution = ba.ParticleDistribution(my_particle,
                                                   my_parameter_distribution)

# Now we can add this distribution to the particle layout.

Parameters of a particle distribution

One can choose among six different distributions in order to break the default regularity of the parameters of the particles. At the same time, each distribution offers several parameters to tweak:


  1. Cosine:
  • Mean1.
  • Sigma1.
  • Number of samples2.
  • Sigma Factor4.
  • Limits3
  • Distributed parameter5
  1. Gate:
  • Min1.
  • Max1.
  • Number of samples2.
  • Distributed parameter5
  1. Gaussian (default):
  • Mean1.
  • StdDev1.
  • Number of samples2.
  • Sigma Factor4.
  • Limits3
  • Distributed parameter5
  1. Log Normal:
  • Median1.
  • ScaleParameter1.
  • Number of samples2.
  • Sigma factor4.
  • Distributed parameter5
  1. Lorentz:
  • Mean1.
  • HWHM1.
  • Number of samples2.
  • Sigma factor4.
  • Limits3
  • Distributed parameter5
  1. Trapezoid:
  • Center1.
  • LeftWidth1.
  • MiddleWidth1.
  • RightWidth1.
  • Number of samples2.
  • Limits3
  • Distributed parameter5

BornAgain provides a function to print the list of available particle parameters and their corresponding values: :

>>print(my_particle.parametersToString())
'/Particle/Abundance':1
'/Particle/PositionX':0
'/Particle/PositionY':0
'/Particle/PositionZ':0
'/Particle/Cylinder/Radius':5
'/Particle/Cylinder/Height':5

Choosing a distribution

A ParticleDistribution is a set of particles in which a given particle paramenter can take numberOfSamples different values. These values are equally spaced between them and the relative number of particles with a particular value is proportional to the height of the chosen distribution.

In order to prevent the extraction of unphysical values, one needs to set limits. For instance, in order to avoid extracting negative values for the radius of a cylinder, one can easily set limits to pass to the ParameterDistribution (line 10 on the recipe snippet above):

limits = ba.RealLimits.limited(1.0, 9.0))

Particle distributions through the GUI

The easiest way of generating a particle distribution from scratch is from the GUI. After that, one can export the layout as a Python script and tweak it to get the desired outcome:

One must note, however, that some functionality is only present through the Python API, for instance, linkParameter is not accessible through the GUI:

# linkParameter allows the height of the cylinders
# to be scaled proportionally to their radii:
par_distr.linkParameter("/Particle/Cylinder/Height")

Further details and a complete working script are provided in the tutorial Cylinders with size distribution.