This release brings deep changes to BornAgain.
Most importantly, we now fully concentrate our support on the BornAgain Python interface. The graphical user interface is withdrawn.
This also simplifies deployment. BornAgain can now be installed through the following channels:
There are also important changes in the sample model. We remove
the Layout class from the model hierarchy, make inter-particle
structures direct children of Layer, and start supporting
bulk 3D structures and random occupancy of particle sites.
This release breaks Python scripts. We therefore offer a migration service: Send us your script from BornAgain 23 or earlier, and we will convert it to BornAgain 24 using an AI coding agent.
For further improvements and bug fixes, see the CHANGELOG.
We thank our student intern Giorgi Tsartsidze for substantial contributions to this release.
Best greetings from the BornAgain maintainer team:
Ammar Nejati, Mikhail Svechnikov, Joachim Wuttke
[1] https://pypi.org/project/BornAgain [2] https://jugit.fz-juelich.de/mlz/homebrew
And now the details:
This release comes without graphical user interface (GUI). The GUI of BornAgain 23 has become obsolete, and should no longer be used. From today on, BornAgain is meant to be used through its Python interface only.
The principal reasons for this decision were the following:
After more than ten years of development, the GUI was still incomplete. It was of great help for getting started with BornAgain, but it was not versatile enough for real-life data analysis demands. Most users sooner or later fell back to Python scripting. In the overwhelming majority of published work, BornAgain has always been used through its Python interface.
Further development of the GUI would have bound a disproportionate part of our resources. Termination of GUI support allowed us to remove more than half of the entire source code. In the future, we will have more time for extending the physics modelled by BornAgain.
Finally, the recent progress in AI will facilitate use of the Python interface. It is now perfectly possible to steer Python sessions in natural language, using an agent like Claude Code.
Real-space visualization of the sample model has been ported from the
GUI to Python. A VTK based sample viewer can be called through
ba.showSample3D(sample), as demonstrated in many example scripts.
Along with the GUI, we also removed all fitting infrastructure from our C++ code base. All fitting is now to be done in Python, as demonstrated by several example scripts.
In the instrument model, we added support for a detector below the horizon and for a beam entering from below.
Support for polarization has been improved. The polarization analyzer now takes three arguments: direction, parallel transmission, and antiparallel transmission.
The Offspecular simulation now performs adaptive integration along phi_f; therefore
the n_phi argument has been removed. The integration can be controlled
with setOffspecIntegratorOptions.
In the Sample model, we completely removed the Layout class. To recall,
the previous model hierarchy was
Sample
Layer
Layout
IInterference class, except if particles are uncorrelatedThe new model hierarchy is
Sample
Layer
StructThe interparticle structure is specified by classes that inherit from the
abstract interface class Struct. The prefix “Interference” has been dropped
from all class names.
Struct
Struct2D
Disordered2D
Dilute2DDense2DOrdered2D
Crystal1D (former Infinite1DLattice)Crystal2D (former Infinite2DLattice)FiniteCrystal2D (former Finite2DLattice)Paracrystal2DRadialParacrystalStruct3D
Disordered3D
Dilute3DIn the future, we intend to add Ordered3D classes to support bulk lattices.
All Ordered2D subclasses now take the particle as their first
constructor argument.
The Disordered2D and Disordered3D stand for random particle assemblies:
Dilute2D/Dilute3D, where particles
are uncorrelated, and Dense2D, where excluded-volume interactions
are accounted for via Percus–Yevick.
In the past, 2D structures were always deposited on top of a reference plane. This was the bottom interface of a layer, except for the substrate where the reference was the top interface.
Now 2D structures must be added using new functions
Layer::deposit2DLayer::suspend2DWhile “deposit” attaches the bottom of the embedded particles to the bottom
of the layer, “suspend” attaches the top of the particles to the top of the
layer. Note: deposit2D must not be used with the substrate layer, and
suspend2D must not be used with the top layer.
If a plane is only partly covered by structure, or is to be covered by an incoherent mixture of different structures, then use the functions
Layer::addDeposit2DLayer::addSuspend2Dwhich take an additional coverage argument (with values between 0 and 1).
The new Mixture class, implemented upon user request, represents randomly
occupied particle sites, each filled by one of several particle kinds.
For 2D ordered systems, the parameter lateralPositionVariance (formerly
positionVariance) now has the dimension of a length (instead of area).
There are a few changes to form factor classes:
Ellipsoid addedHemiEllipsoid replaced by EllipsoidalSegmentHorizontalCylinder accepts cutFromTop and cutFromBottom argumentsFixed analytic continuation of a few form and structure factors, to correctly use the bilinear dot product q·q = qx²+qy²+qz² instead of sesquilinear |q|² = |qx|²+|qy|²+|qz|². Results change significantly for simulations with evanescent waves.
The Material class has been reengineered so that refraction-index-based
and SLD-based materials can be used together.
The SimulationOption setUseAvgMaterials is now true by default. This means
that the transmission and reflection computation uses a refractive index that
takes into account not only the bulk material of a layer but also its particle
decoration. The new default ensures correctness (within the limits of DWBA)
even for dense decorations.
Setting the option back to false is a legitimate approximation for dilute decorations, but has no computational advantages. Therefore it should be rarely needed, except perhaps for reproducing previous simulations.
We used the occasion of these breaking changes to simplify and unify some more class and function names.
Functions to extract axes and data from class Datafield (which holds
simulation results) are now named xCenters, yCenters, intensities, errors.
Explicit conversion to NumPy is no longer needed.
In ba_plot:
plot2d_to_row and plot2d_to_grid.frame_aspect, unit_aspect, spacing.May 20, 2026