The residual function defines what a fit compares. It runs the simulation at the trial parameters and returns the differences used by the optimizer. BornAgain provides helpers for masks and derived comparisons; you choose the weighting and residual definition appropriate to your data.
Each helper has a docstring with its full contract, available through
help(ba.valid_pixel_residual), for example.
valid_pixel_residual forms a flat vector of experimental minus simulated
intensities. It gives zero contribution to pixels where either value is
non-finite or the experimental intensity is negative:
def residuals(params):
simulated = get_simulation(params.valuesdict()).simulate()
return ba.valid_pixel_residual(
experimental.intensities(), simulated.intensities())
The vector keeps the full array length, as required by least-squares optimizers; invalid entries are zeroed, not removed. The helper does not divide by uncertainties or otherwise weight the differences.
See Fit with masks.
crop_by_mask extracts the smallest rectangle containing all usable
(False) pixels in a boolean mask:
cropped = ba.crop_by_mask(values, mask)
The data and mask must have matching 2D shapes. Masked pixels inside the rectangle remain in the returned data: this is a crop, not a residual mask. See Expfit GALAXI.
relative_difference compares two Datafields with matching shapes and
physical axes. It returns a Datafield containing
2*(simulation-experiment)/(|simulation|+|experiment|).
Non-finite inputs stay invalid; two finite zeros give zero difference.
This is the quantity shown by plot_difference in
fit monitoring. It does not automatically become the
optimizer’s residual: use its intensities explicitly if that is the
comparison your fit should minimize.
For fitting several measurements together, see Multiple datasets.