Fitting sum of "n" curves to data

96 views
Skip to first unread message

Kiyan Kheradvar

unread,
Apr 1, 2021, 11:42:45 PM4/1/21
to lmfit-py
Hi everyone, 

Lmfit describes how to fit the sum of 2 or more curves to a dataset (https://lmfit.github.io/lmfit-py/model.html#composite-models-adding-or-multiplying-models). However, this requires someone to manually type in and define each curve. I want your insight on this question: how can I create code that can automatically define curves and add them according to Lmfit's model? Specifically, I want to type in a natural number as input, let's call that "n", and the output should be the sum of "n" curves fitted to the data. 

Thank you for your kind attention. 

Best Regards,

Kiyan

Matt Newville

unread,
Apr 2, 2021, 8:34:48 AM4/2/21
to lmfit-py
On Thu, Apr 1, 2021 at 10:42 PM Kiyan Kheradvar <kiya...@gmail.com> wrote:
Hi everyone, 

Lmfit describes how to fit the sum of 2 or more curves to a dataset (https://lmfit.github.io/lmfit-py/model.html#composite-models-adding-or-multiplying-models). However, this requires someone to manually type in and define each curve. I want your insight on this question: how can I create code that can automatically define curves and add them according to Lmfit's model? Specifically, I want to type in a natural number as input, let's call that "n", and the output should be the sum of "n" curves fitted to the data. 


Um, well, the examples are deliberately simple.  I think that like (as an important example, and almost sorry to pick on them) the otherwise extensive matplotlib examples, some of the lmfit examples might also give the incorrect impression that fitting scripts need to be simple scripts (akin to confusing matplotlib with matplotlib.pyplot). 


That is, one can (and people have) write code that programmatically sums models, perhaps using a class or perhaps just a function to build a model.   One "almost simple" approach (that I never actually use myself, preferring classes or GUIs to build models) would be something like:

    def build_model(ngaussians=3, background_type='linear'):
            model = None
            if background_type.startswith('lin'):
                model = LinearModel(prefix='bgline_')
            elif background_type.startswith('quad'):
                model = QuadraticModel(prefix='bgquad_')
            for i in range(ngaussians): 
                if model is None:      
                    model = GaussianModel(prefix='g1_')
                else: 
                    model += GaussianModel(prefix=f'g{i+1}_')
           return model

Of course, that's completely untested and you can make that more complicated if you want ;).

--Matt

Alle Meije Wink

unread,
Apr 2, 2021, 10:14:51 PM4/2/21
to lmfi...@googlegroups.com
Dear Kiyan,

The example that I found really helpful is this one: https://lmfit.github.io/lmfit-py/examples/example_fit_multi_datasets.html

I think that does exactly what you describe: it generates data as the sum of 5 curves + noise, and then fits 5 curves to the noisy data.

You can use that script and give it the parameter N for the number of curves used to generate the data (replacing the 5 in "for _ in np.arange(5):" by N).

The number of fitted curves in this example is the same as the number of generated curves, but you could easily decouple those for playing around.

Hope that helps!

bw
Alle Meije
Reply all
Reply to author
Forward
0 new messages