How many curves does the profile need?
Decomposing a measured profile into component curves has one question that no least-squares fit can answer for you: how many curves are there? Add enough of them and any data set can be fitted perfectly, peaks and noise alike. The usual answers weigh fit quality against the number of parameters with an information criterion — AIC, AICc, BIC — and accept whichever model scores best.
Fit answers it differently. You state how good the fit has to be, and the program removes every curve it can remove without breaking that promise.
An R-factor budget
The maximum acceptable R-factor is yours to set. It is not a penalty term to be calibrated; it is the accuracy your measurement deserves — the noise level, the counting statistics, the precision you are prepared to claim in a paper. Everything below follows from it.
Where it starts
Fit → Automatically begins with more curves than any profile needs. It subtracts the background, then puts a curve on every point of every peak — every point standing above the background threshold — and marks a fit interval around each peak. Each interval is then decomposed on its own. If you picked positions yourself, those are the starting curves instead.
How it removes them
The decomposition is a loop of attempts, each of which is allowed to fail:
- Fit the model as it stands.
- Save the parameters of that fit — it is the best result so far, and the loop may have to come back to it.
- Drop every curve whose amplitude has collapsed to less than a thousandth of the largest one. A curve with no amplitude left is not a component of the profile, whatever the fit says about it.
- Drop one more curve, chosen by the strategy of this pass (below).
- If the R-factor is still inside the budget, the curves were surplus: keep the smaller model and try to remove another one. If it is not, fit again without them.
- If the fit cannot bring the R-factor back inside the budget, the last curve was load-bearing. Restore the saved parameters, put that curve back and end the pass — the collapsed curves stay gone, since nothing that had no amplitude is worth restoring.
The loop runs twice, with a different choice at step 4 each time. First it removes the curve sitting where the experimental profile is steepest: on a flank, a curve is doing the work of a shoulder that the neighbouring peaks can usually take over, so that is where a redundant component is most likely to hide. Then it removes the curve of smallest amplitude: the weakest remaining component, the classic candidate for being noise. A final fit polishes what survived.
A re-fit inside the loop only has to show that the budget can be met, so it
stops as soon as the R-factor is back inside it. Only the final fit runs to full
precision. That is what keeps the method fast although it fits the model once
for every curve it removes: on the two-peak sample that ships with Fit
(Data/2.dat, two-branch Pseudo-Voigt curves, a budget of 0.01 %)
it starts from 32 curves and ends with 3 in well under a minute.
What you get
A model with as few curves as the accuracy you asked for permits, and no tuning parameter between you and that decision. Ask for less accuracy and you get a coarser, simpler decomposition; ask for more and the program keeps the components it needs to deliver it. Nothing is discarded silently: every removal that failed is undone, and the live R-factor chart shows each attempt — a jump up where a curve was removed, a step back down where the previous best was restored.
Compared with the published approaches
Iteratively deleting weak components, re-fitting and rolling back when the result is worse is not new in itself. The closest published method we know of is GaussPy+ (Riener et al., Astronomy & Astrophysics 628, A78, 2019), which removes components below a significance or amplitude threshold, re-fits, and keeps the smaller model only if its AICc improves; derivatives of the profile are used there to propose components rather than to pick one for deletion. Other approaches decide the number of components by F-test or BIC, by reversible-jump MCMC over a Bayesian posterior, or by greedy sparse deconvolution that grows the model instead of pruning it.
Two things here appear to be uncommon: the accept/reject test is a fixed R-factor ceiling you choose rather than a relative improvement in an information criterion, and one of the deletion strategies picks the curve standing on the steepest slope of the measured profile. We have found no publication combining those two, which is not the same as claiming there is none — if you know of one, the issue tracker is the place to say so.
Where it lives
The algorithm is in the compute engine, not the interface, so it runs the same
way in the desktop application and against a remote fit_server. In
the sources it is TFitTask.MinimizeNumberOfCurvesAlg in
Server/fit_task.pas,
with the two deletion strategies beside it; the maximum acceptable R-factor is a
problem setting, reachable from the interface (Fit → Set Max Acceptable
Difference…, in percent) and over the REST API.