File: LargeParticles.py

package info (click to toggle)
bornagain 23.0-4
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 103,936 kB
  • sloc: cpp: 423,131; python: 40,997; javascript: 11,167; awk: 630; sh: 318; ruby: 173; xml: 130; makefile: 51; ansic: 24
file content (114 lines) | stat: -rwxr-xr-x 3,523 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
#!/usr/bin/env python3
"""
Large cylinders in DWBA.

This example demonstrates that for large particles (~1000nm) the form factor
oscillates rapidly within one detector bin and analytical calculations
(performed for the bin center) give completely wrong intensity pattern.
In this case Monte-Carlo integration over detector bin should be used.
"""
import bornagain as ba
from bornagain import angstrom, ba_plot as bp, deg, nm

default_cylinder_radius = 10*nm
default_cylinder_height = 20*nm


def get_sample(cylinder_radius, cylinder_height):
    # Materials
    vacuum = ba.RefractiveMaterial("Vacuum", 0, 0)
    material_substrate = ba.RefractiveMaterial("Substrate", 6e-6, 2e-8)
    material_particle = ba.RefractiveMaterial("Particle", 6e-4, 2e-8)

    # Particle layout
    cylinder_ff = ba.Cylinder(cylinder_radius, cylinder_height)
    cylinder = ba.Particle(material_particle, cylinder_ff)
    particle_layout = ba.ParticleLayout()
    particle_layout.addParticle(cylinder)

    # Layers
    vacuum_layer = ba.Layer(vacuum)
    vacuum_layer.addLayout(particle_layout)
    substrate_layer = ba.Layer(material_substrate)

    # Sample
    sample = ba.Sample()
    sample.addLayer(vacuum_layer)
    sample.addLayer(substrate_layer)
    return sample


def get_simulation(sample, integration_flag):
    """
    A GISAXS simulation with defined beam and detector.
    If integration_flag=True, the simulation will integrate over detector bins.
    """
    beam = ba.Beam(1, 1*angstrom, 0.2*deg)
    n = <%= test_mode ? 21 : 201 %>
    det = ba.SphericalDetector(n, -1.5*deg, 1.5*deg, n, 0, 3*deg)
    simulation = ba.ScatteringSimulation(beam, sample, det)
    simulation.options().setMonteCarloIntegration(integration_flag, <%= test_mode ? 500 : 50 %>)
    if not "__no_terminal__" in globals():
        simulation.setTerminalProgressMonitor()
    return simulation


def simulate():
    ret = []

    # conditions to define cylinders scale factor and integration flag
    conditions = [{
        'title': "Small cylinders, analytical calculations",
        'scale': 1,
        'integration': False,
        'zmin': 1e-5,
        'zmax': 1e2
    }, {
        'title': "Small cylinders, Monte-Carlo integration",
        'scale': 1,
        'integration': True,
        'zmin': 1e-5,
        'zmax': 1e2
    }, {
        'title': "Large cylinders, analytical calculations",
        'scale': 100,
        'integration': False,
        'zmin': 1e-5,
        'zmax': 1e10
    }, {
        'title': "Large cylinders, Monte-Carlo integration",
        'scale': 100,
        'integration': True,
        'zmin': 1e-5,
        'zmax': 1e10
    }]

    # run simulation 4 times
    for i_plot, condition in enumerate(conditions):
        scale = condition['scale']
        integration_flag = condition['integration']

        sample = get_sample(default_cylinder_radius*scale,
                            default_cylinder_height*scale)
        simulation = get_simulation(sample, integration_flag)
        result = simulation.simulate()
        result.setTitle(condition['title'])
        ret.append(result)

    return ret


if __name__ == '__main__':
    results = simulate()
    <%- if test_mode -%>
    from bornagain import ba_check
    ba_check.persistence_test(results)
    <%- elsif figure_mode -%>
    plotargs = bp.parse_commandline()
    plotargs['fontsize'] = 12
    bp.plot_to_grid(results, 2, **plotargs)
    bp.export(**plotargs)
    <%- else -%>
    bp.plot_to_grid(results, 2)
    bp.plt.show()
    <%- end -%>