Ticket #34755: nonlinear_extended.diff

File nonlinear_extended.diff, 30.8 KB (added by feranick@…, 12 years ago)
  • doc/UsersGuide.html

    Description: Add multiple non-linear data fitting functions
     One of the most used features in software for scientific data analysis is
     the ability to perform non linear peak fitting (specifically Lorentzian and
     Gaussian fits). Xmgrace sorely lacks this capability, unless you consider
     adding manually the required formula.
     .
     This implements a substantial library of such functions and documentation
     for their use.
    Author: Nicola Ferralis <feranick@hotmail.com>
    Bug: http://plasma-gate.weizmann.ac.il/Grace/phpbb/w3todo.php?action=view_report&project_id=1&todo_id=2220
    Bug-Debian: http://bugs.debian.org/578435
    Bug-Ubuntu: https://bugs.launchpad.net/ubuntu/+source/grace/+bug/535459
    Last-Update: 2010-05-26
    old new  
    15161516sample range or to produce an evenly spaced set from an irregular
    15171517one.</P>
    15181518
     1519<P>Under the "Library" menu, several functions are available under the
     1520categories: "Gaussian Functions", "Lorentzian Functions", "Peak Functions",
     1521 "Periodic Peak Functions" and "Baseline Functions".</P>
     1522
     1523<P><i>Gaussian</i><br>&nbsp y = A0 + (A3*2*sqrt(ln(2)/pi)/A2)*exp(-4*ln(2)*((x-A1)/A2)^2)<br>
     1524&nbsp where: A0: Baseline offset; A1: Center of the peak; A2: Full width at half
     1525maximum; A3: Peak area.<br> The center and initial amplitude of the peak can be set from
     1526 user input (via mouse coordinates). </P>
     1527
     1528<br>
     1529<P><i>Gaussian (Chromatography):</i><br>
     1530&nbsp y = A0 + (1/sqrt(2*pi))*(A3/A2)*exp(-(x-A1)^2/2*A2^2)
     1531 A0: Baseline offset; A1: Center of the peak (retention time); A2:
     1532 Standard deviation of the peak; A3: Peak area. <br> The center and initial amplitude of the peak can be set from
     1533 user input (via mouse coordinates). </P>
     1534
     1535<br>
     1536<P><i>Lorentzian</i><br>&nbsp y = A0 + (2*A2*A3/pi)/(4*(x-A1)^2 + A2^2)<br>
     1537&nbsp where: A0: Baseline offset; A1: Center of the peak; A2: Full width at half
     1538maximum; A3: Peak area. <br> The center and initial amplitude of the peak can be set from
     1539 user input (via mouse coordinates).</P>
     1540
     1541<br>
     1542<P><i>Peak Functions</i><br>
     1543<i>Pseudo Voigt 1</i><br>
     1544&nbsp y = A0 + A3 * (A4*(2/pi)*A2/(4*(x-A1)^2+A2^2) + <br>(1-A4)*exp(-4*ln(2)*(x-A1)^2/A2^2)*(sqrt(4*ln(2))/(A2*sqrt(pi))))<br>
     1545&nbsp where: Gaussian and Lorentzian have the same width; A0: Baseline offset;
     1546 A1: Center of the peak; A2: Full width at half maximum; A3: Amplitude;
     1547 A4: Profile shape factor.<br>
     1548<i>Pseudo Voigt 2</i><br>
     1549&nbsp y = A0 + A3 * (A5*(2/pi)*A2/(4*(x-A1)^2+A2^2) + (1-A5)*exp(-4*ln(2)*(x-A1)^2/A4^2)*(sqrt(4*ln(2))/(A2*sqrt(pi))))<br>
     1550&nbsp where: Gaussian and Lorentzian have different width; A0: Baseline offset;
     1551 A1: Center of the peak; A2: Full width at half maximum; A3: Amplitude;
     1552 A4: Profile shape factor.<br>
     1553<i>Doniach-Sunjic</i><br>
     1554&nbsp y = A0 + A3*cos((pi*A4/2)+(1-A4)*atan((x-A1)/A2))/(A2^2+(x-A1)^2)^((1-A4)/2)<br>
     1555&nbsp where:A0: Baseline offset; A1: Center of the peak; A2: Full width at half maximum;<br>
     1556&nbspA3: Peak area; A4: Asymmetry parameter.<br>
     1557<i>Asymmetric double Sigmoidal</i><br>
     1558&nbsp y = A0 + A3*(1/(1+exp(-(x-A1+A2/2)/A4)))*(1-(1/(1+exp(-(x-A1-A2/2)/A5))))<br>
     1559&nbsp where: A0: Baseline offset; A1: Center of the peak; A2: Width 1;
     1560 A3: Amplitude; A4: Width 2; A5: Width 5.<br>
     1561<i>Logarithm Normal:</i> <br>
     1562&nbsp y = A0 + A3*exp(-((ln(x)-ln(A1))^2)/(2*A2))<br>
     1563&nbsp where: A0: Baseline offset; A1: Center of the peak; A2: Width <br>
     1564<i>Gram-Charlier A-Series (GCAS)</i><br>
     1565&nbsp y = A0 + A3/(A2*sqrt(2*pi))*exp(-0.5*((x-A1)/A2)^2)*(1+(A4/6)*
     1566 (((x-A1)/A2)^3-3*(x-A1)/A2)+(A5/24)*(((x-A1)/A2)^4-6*((x-A1)/A2)^3+3))<br>
     1567&nbsp where: A0: Baseline offset; A1: Center of the peak; A2: Standard deviation;
     1568 A3: Peak Area; A4: Skew; A5: Excess. <br>
     1569<i>Edgeworth-Cramer Series</i><br>
     1570&nbsp y = A0 + A3/(A2*sqrt(2*pi))*exp(-0.5*((x-A1)/A2)^2)*(1+(A4/6)*
     1571 (((x-A1)/A2)^3-3*(x-A1)/A2)+(A5/24)*(((x-A1)/A2)^4-6 *((x-A1)/A2)^3+3)
     1572 +(A5^2/720)*(((x-A1)/A2)^6-15*((x-A1)/A2)^4+45*((x-A1)/A2)^2-15))<br>
     1573&nbsp where: A0: Baseline offset; A1: Center of the peak; A2: Standard deviation;
     1574 A3: Peak Area; A4: Skew; A5: Excess. <br>
     1575<i>Inverse Polynomial</i><br>
     1576&nbsp y=A0+A3/(1+ A4*(2*(x-A1)/A2)^2 + A5*(2*(x-A1)/A2)^4 + A6*(2*(x-A1)/A2)^6) <br>
     1577&nbsp where: A0: Baseline offset; A1: Center of the peak; A2: Standard deviation;
     1578 A3: Peak Area; A4, A5, A6: Parameters. <br>
     1579 </P>
     1580
     1581<br>
     1582<P><i>Periodic Peak Functions</i><br>
     1583<i>Sine:</i> <br>
     1584&nbspy=A0+A3*sin(pi*(x-A1)/A2)<br>
     1585&nbspwhere: A0: Baseline offset; A1: Center; A2: Width; A3: Amplitude.<br>
     1586<i>Sine Square: </i><br>
     1587&nbspy=A0+A3*sin(pi*(x-A1)/A2)^2<br>
     1588&nbspwhere: A0: Baseline offset; A1: Center; A2: Width; A3: Amplitude.<br>
     1589<i>Sine damp: </i><br>
     1590&nbspy=A0+A3*exp(-x/A4)*sin(pi*(x-A1)/A2)<br>
     1591&nbspwhere: A0: Baseline offset; A1: Center; A2: Width; A3: Amplitude; A4: Decay time. <br>
     1592</P>
     1593
     1594<br>
     1595<P><i>Baseline Functions</i><br>
     1596<i>Exponential Decay 1:</i><br>
     1597&nbsp;y=A0+A3*exp(-(x-A1)/A2)<br>
     1598<b>Exponential Decay 2:</b> <br>
     1599&nbsp;y=A0+A3*exp(-(x-A1)/A2)+A6*exp(-(x-A4)/A5);<br>
     1600<i>Exponential Growth 1:</i> <br>
     1601&nbsp;y=A0+A3*exp((x-A1)/A2)<br>
     1602<i>Exponential Growth 2: </i><br>
     1603&nbsp;y=A0+A3*exp(-(x-A1)/A2)+A6*exp((x-A4)/A5);<br>
     1604<i>Hyperbolic:</i><br>
     1605&nbsp;y=A0+(A1*x)/(A2+x)<br>
     1606<i>Bradley:</i> <br>
     1607&nbsp;y=A0*ln(-A1*ln(x))<br>
     1608<i>Logarithm 3 Parameters: </i><br>
     1609&nbsp;y=A0-A1*ln(x+A2)<br>
     1610<i>Weibull Probability Density 2 Parameters: </i><br>
     1611&nbsp;y=(A0/A1)*((x/A1)^(A0-1))*exp(-(x/A1)^A0)<br>
     1612<i>Weibull Cumulative Distribution 2 Parameters: </i><br>
     1613&nbsp;y=1-exp(-(x/A1)^A0)<br>
     1614</P>
     1615
    15191616<H3><A NAME="correlation/covariance"></A> Correlation/covariance          </H3>
    15201617
    15211618<P>This popup can be used to compute autocorrelation
  • grace-5.1.22

    old new  
    258258    return (vp);
    259259}
    260260
     261WPoint Vpoint2Wpoint(VPoint vp)
     262{
     263    WPoint wp;
     264    view2world(vp.x, vp.y, &wp.x, &wp.y);
     265    return (wp);
     266}
    261267
    262268void symplus(VPoint vp, double s)
    263269{
  • grace-5.1.22

    old new  
    236236double xy_xconv(double wx);
    237237double xy_yconv(double wy);
    238238VPoint Wpoint2Vpoint(WPoint wp);
     239WPoint Vpoint2Wpoint(VPoint vp);
    239240int world2view(double x, double y, double *xv, double *yv);
    240241void view2world(double xv, double yv, double *xw, double *yw);
    241242
  • src/events.c

    old new  
    111111    int axisno;
    112112    Datapoint dpoint;
    113113    GLocator locator;
     114    static char buf[256];
    114115   
    115116    cg = get_cg();
    116117    get_tracking_props(&track_setno, &move_dir, &add_at);
     
    487488                }
    488489                select_line(anchor_x, anchor_y, x, y, 0);
    489490                break;
     491            case PEAK_POS:
     492                anchor_point(x, y, vp);
     493                sprintf(buf, "Initial peak position, intensity: %f, %f \n", Vpoint2Wpoint(vp).x, Vpoint2Wpoint(vp).y);
     494                stufftext(buf);
     495                nonl_parms[1].value = Vpoint2Wpoint(vp).x;
     496                nonl_parms[3].value = Vpoint2Wpoint(vp).y;
     497                set_actioncb(NULL);
     498                update_nonl_frame();
     499                break;
     500            case PEAK_POS1:
     501                anchor_point(x, y, vp);
     502                sprintf(buf, "Initial position, intensity peak #1: %f, %f \n", Vpoint2Wpoint(vp).x, Vpoint2Wpoint(vp).y);
     503                stufftext(buf);
     504                nonl_parms[1].value = Vpoint2Wpoint(vp).x;
     505                nonl_parms[3].value = Vpoint2Wpoint(vp).y;
     506                set_actioncb((void*) PEAK_POS2);
     507                update_nonl_frame();
     508                break;
     509            case PEAK_POS2:
     510                anchor_point(x, y, vp);
     511                sprintf(buf, "Initial position, intensity peak #2: %f, %f \n", Vpoint2Wpoint(vp).x, Vpoint2Wpoint(vp).y);
     512                stufftext(buf);
     513                nonl_parms[4].value = Vpoint2Wpoint(vp).x;
     514                nonl_parms[6].value = Vpoint2Wpoint(vp).y;
     515                set_actioncb(NULL);
     516                update_nonl_frame();
     517                break;
     518            case PEAK_POS1B:
     519                anchor_point(x, y, vp);
     520                sprintf(buf, "Initial position, intensity peak #1: %f, %f \n", Vpoint2Wpoint(vp).x, Vpoint2Wpoint(vp).y);
     521                stufftext(buf);
     522                nonl_parms[1].value = Vpoint2Wpoint(vp).x;
     523                nonl_parms[3].value = Vpoint2Wpoint(vp).y;
     524                set_actioncb((void*) PEAK_POS2B);
     525                update_nonl_frame();
     526                break;
     527            case PEAK_POS2B:
     528                anchor_point(x, y, vp);
     529                sprintf(buf, "Initial position, intensity peak #2: %f, %f \n", Vpoint2Wpoint(vp).x, Vpoint2Wpoint(vp).y);
     530                stufftext(buf);
     531                nonl_parms[4].value = Vpoint2Wpoint(vp).x;
     532                nonl_parms[6].value = Vpoint2Wpoint(vp).y;
     533                set_actioncb((void*) PEAK_POS3B);
     534                update_nonl_frame();
     535                break;
     536            case PEAK_POS3B:
     537                anchor_point(x, y, vp);
     538                sprintf(buf, "Initial position, intensity peak #3: %f, %f \n", Vpoint2Wpoint(vp).x, Vpoint2Wpoint(vp).y);
     539                stufftext(buf);
     540                nonl_parms[7].value = Vpoint2Wpoint(vp).x;
     541                nonl_parms[9].value = Vpoint2Wpoint(vp).y;
     542                set_actioncb(NULL);
     543                update_nonl_frame();
     544                break;
    490545            default:
    491546                break;
    492547            }
     
    567622void set_action(CanvasAction act)
    568623{
    569624    int i;
     625    static char buf[256];
    570626/*
    571627 * indicate what's happening with a message in the left footer
    572628 */
     
    760816        set_cursor(0);
    761817        set_left_footer("Pick ending point");
    762818        break;
     819    case PEAK_POS:
     820        set_cursor(0);
     821        set_left_footer("Click on the approximate position of the maximum of the peak");
     822        sprintf(buf, "Click on the approximate position of the maximum of the peak.\n");
     823        stufftext(buf);
     824        break;
     825    case PEAK_POS1:
     826        set_cursor(0);
     827        set_left_footer("Click on the approximate position of the maximum of the peak #1");
     828        sprintf(buf, "Click on the approximate position of the maximum of the peak #1.\n");
     829        stufftext(buf);
     830        break;
     831    case PEAK_POS2:
     832        set_cursor(0);
     833        set_left_footer("Click on the approximate position of the maximum of the peak #2");
     834        sprintf(buf, "Click on the approximate position of the maximum of the peak #2.\n");
     835        stufftext(buf);
     836        break;
     837    case PEAK_POS1B:
     838        set_cursor(0);
     839        set_left_footer("Click on the approximate position of the maximum of the peak #1");
     840        sprintf(buf, "Click on the approximate position of the maximum of the peak #1.\n");
     841        stufftext(buf);
     842        break;
     843    case PEAK_POS2B:
     844        set_cursor(0);
     845        set_left_footer("Click on the approximate position of the maximum of the peak #2");
     846        sprintf(buf, "Click on the approximate position of the maximum of the peak #2.\n");
     847        stufftext(buf);
     848        break;
     849    case PEAK_POS3B:
     850        set_cursor(0);
     851        set_left_footer("Click on the approximate position of the maximum of the peak #3");
     852        sprintf(buf, "Click on the approximate position of the maximum of the peak #3.\n");
     853        stufftext(buf);
     854        break;
    763855    }
    764856
    765857    action_flag = act;
  • src/events.h

    old new  
    8181    ZOOMY_1ST,
    8282    ZOOMY_2ND,
    8383    DISLINE1ST,
    84     DISLINE2ND
     84    DISLINE2ND,
     85    PEAK_POS,
     86    PEAK_POS1,
     87    PEAK_POS2,
     88    PEAK_POS1B,
     89    PEAK_POS2B,
     90    PEAK_POS3B
    8591} CanvasAction;
    8692
    8793/* add points at */
  • src/nonlwin.c

    old new  
    77 * Copyright (c) 1996-2000 Grace Development Team
    88 *
    99 * Maintained by Evgeny Stambulchik
     10 * Additional non linear fitting functions by Nicola Ferralis
    1011 *
    1112 *
    1213 *                           All Rights Reserved
     
    4748#include "parser.h"
    4849#include "motifinc.h"
    4950#include "protos.h"
     51#include "events.h"
    5052
    5153/* nonlprefs.load possible values */
    5254#define LOAD_VALUES         0
     
    98100static void nonl_wf_cb(int value, void *data);
    99101static void do_constr_toggle(int onoff, void *data);
    100102
     103static void nonl_Lorentzian_cb(void *data);
     104static void nonl_doubleLorentzian_cb(void *data);
     105static void nonl_tripleLorentzian_cb(void *data);
     106static void nonl_Gaussian_cb(void *data);
     107static void nonl_doubleGaussian_cb(void *data);
     108static void nonl_tripleGaussian_cb(void *data);
     109static void nonl_Gaussian2_cb(void *data);
     110static void nonl_PsVoight1_cb(void *data);
     111static void nonl_PsVoight2_cb(void *data);
     112static void nonl_DS_cb(void *data);
     113static void nonl_Asym2Sig_cb(void *data);
     114static void nonl_LogNormal_cb(void *data);
     115static void nonl_GCAS_cb(void *data);
     116static void nonl_ECS_cb(void *data);
     117static void nonl_InvPoly_cb(void *data);
     118static void nonl_Sine_cb(void *data);
     119static void nonl_Sinesq_cb(void *data);
     120static void nonl_Sinedamp_cb(void *data);
     121static void nonl_ExpDec1_cb(void *data);
     122static void nonl_ExpDec2_cb(void *data);
     123static void nonl_ExpGrow1_cb(void *data);
     124static void nonl_ExpGrow2_cb(void *data);
     125static void nonl_Hyperbol_cb(void *data);
     126static void nonl_Bradley_cb(void *data);
     127static void nonl_Log3_cb(void *data);
     128static void nonl_WeibullPD_cb(void *data);
     129static void nonl_WeibullCD_cb(void *data);
     130
    101131static void update_nonl_frame_cb(void *data);
    102132static void reset_nonl_frame_cb(void *data);
    103133
     
    118148    if (nonl_frame == NULL) {
    119149        int i;
    120150        OptionItem np_option_items[MAXPARM + 1], option_items[5];
    121         Widget menubar, menupane;
     151        Widget menubar, menupane, submenugauss, submenulorentz, submenupeak, submenubaseline, submenuperiodic;
    122152        Widget nonl_tab, nonl_main, nonl_advanced;
    123153        Widget sw, title_fr, fr3, rc1, rc2, rc3, lab;
    124154
     
    145175        CreateMenuSeparator(menupane);
    146176        CreateMenuButton(menupane, "Update", 'U', update_nonl_frame_cb, NULL);
    147177
     178        menupane = CreateMenu(menubar, "Library", 'L', FALSE);
     179
     180        submenugauss = CreateMenu(menupane, "Gaussian Functions", 'G', FALSE);
     181        CreateMenuButton(submenugauss, "Single", 'g', nonl_Gaussian_cb, NULL);
     182        CreateMenuButton(submenugauss, "Double", 'D', nonl_doubleGaussian_cb, NULL);
     183        CreateMenuButton(submenugauss, "Triple", 'T', nonl_tripleGaussian_cb, NULL);
     184        CreateMenuSeparator(submenugauss);
     185        CreateMenuButton(submenugauss, "Single (chromatography)", 'c', nonl_Gaussian2_cb, NULL);
     186        CreateMenuSeparator(menupane);
     187
     188        submenulorentz = CreateMenu(menupane, "Lorentzian Functions", 'L', FALSE);
     189        CreateMenuButton(submenulorentz, "Single", 'S', nonl_Lorentzian_cb, NULL);
     190        CreateMenuButton(submenulorentz, "Double", 'D', nonl_doubleLorentzian_cb, NULL);
     191        CreateMenuButton(submenulorentz, "Triple", 'T', nonl_tripleLorentzian_cb, NULL);
     192        CreateMenuSeparator(menupane);
     193
     194        submenupeak = CreateMenu(menupane, "Peak Functions", 'P', FALSE);
     195        CreateMenuButton(submenupeak, "Pseudo Voigt 1", 'V', nonl_PsVoight1_cb, NULL);
     196        CreateMenuButton(submenupeak, "Pseudo Voigt 2", 'o', nonl_PsVoight2_cb, NULL);
     197        CreateMenuButton(submenupeak, "Doniach-Sunjic", 'D', nonl_DS_cb, NULL);
     198        CreateMenuButton(submenupeak, "Asymmetric Double Sigmoidal", 'S', nonl_Asym2Sig_cb, NULL);
     199        CreateMenuButton(submenupeak, "LogNormal", 'L', nonl_LogNormal_cb, NULL);
     200        CreateMenuButton(submenupeak, "Gram-Charlier A-Series", 'C', nonl_GCAS_cb, NULL);
     201        CreateMenuButton(submenupeak, "Edgeworth-Cramer Series", 'E', nonl_ECS_cb, NULL);
     202        CreateMenuButton(submenupeak, "Inverse Polynomial", 'I', nonl_InvPoly_cb, NULL);
     203        CreateMenuSeparator(menupane);
     204
     205        submenuperiodic = CreateMenu(menupane, "Periodic Peak Functions", 'e', FALSE);
     206        CreateMenuButton(submenuperiodic, "Sine", 'S', nonl_Sine_cb, NULL);
     207        CreateMenuButton(submenuperiodic, "Sine Square", 'q', nonl_Sinesq_cb, NULL);
     208        CreateMenuButton(submenuperiodic, "Sine Damp", 'D', nonl_Sinedamp_cb, NULL);
     209        CreateMenuSeparator(menupane);
     210
     211        submenubaseline = CreateMenu(menupane, "Baseline Functions", 'B', FALSE);
     212        CreateMenuButton(submenubaseline, "Exponential Decay 1", 'D', nonl_ExpDec1_cb, NULL);
     213        CreateMenuButton(submenubaseline, "Exponential Decay 2", 'e', nonl_ExpDec2_cb, NULL);
     214        CreateMenuButton(submenubaseline, "Exponential Growth 1", 'G', nonl_ExpGrow1_cb, NULL);
     215        CreateMenuButton(submenubaseline, "Exponential Growth 2", 'r', nonl_ExpGrow2_cb, NULL);
     216        CreateMenuButton(submenubaseline, "Hyperbolic Function", 'H', nonl_Hyperbol_cb, NULL);
     217        CreateMenuSeparator(submenubaseline);
     218        CreateMenuButton(submenubaseline, "Bradley", 'B', nonl_Bradley_cb, NULL);
     219        CreateMenuButton(submenubaseline, "Logarithm 3", 'L', nonl_Log3_cb, NULL);
     220        CreateMenuSeparator(submenubaseline);
     221        CreateMenuButton(submenubaseline, "Weibull Probability Density", 'W', nonl_WeibullPD_cb, NULL);
     222        CreateMenuButton(submenubaseline, "Weibull Cumulative", 'w', nonl_WeibullCD_cb, NULL);
     223        CreateMenuSeparator(menupane);
     224
     225        CreateMenuButton(menupane, "Reset fit parameters", 'R', reset_nonl_frame_cb, NULL);
    148226        menupane = CreateMenu(menubar, "Help", 'H', TRUE);
    149227
    150228        CreateMenuHelpButton(menupane, "On fit", 'f',
     
    712790    }
    713791    return TRUE;
    714792}
     793
     794
     795static void nonl_Lorentzian_cb(void *data)
     796{   int i;
     797    nonl_opts.title   = copy_string(nonl_opts.title, "Lorentzian function");
     798    nonl_opts.formula = copy_string(nonl_opts.formula, "y = A0 + (2*A2*A3/pi)/(4*(x-A1)^2 + A2^2)");
     799    nonl_opts.parnum = 4;
     800
     801    for (i=0; i<nonl_opts.parnum; i++)
     802        {nonl_parms[i].value=1;}
     803
     804    sprintf(buf, "A0: Baseline offset\nA1: Center of the peak\nA2: Full width at half maximum\nA3: Peak area\n\n");
     805    stufftext(buf);
     806
     807    set_actioncb( (void *) PEAK_POS);
     808    update_nonl_frame();
     809}
     810
     811static void nonl_doubleLorentzian_cb(void *data)
     812{   int i;
     813    nonl_opts.title   = copy_string(nonl_opts.title, "Double Lorentzian function");
     814    nonl_opts.formula = copy_string(nonl_opts.formula, "y = A0 + (2*A2*A3/pi)/(4*(x-A1)^2 + A2^2) + (2*A5*A6/pi)/(4*(x-A4)^2 + A5^2)");
     815    nonl_opts.parnum = 7;
     816
     817    for (i=0; i<nonl_opts.parnum; i++)
     818        {nonl_parms[i].value=1;}
     819
     820    sprintf(buf, "A0: Baseline offset\nA1, A4: Center of peaks 1, 2\nA2, A5: Full width at half maximum of peaks 1, 2\nA3, A6: Area of peaks 1, 2\n\n");
     821    stufftext(buf);
     822    set_actioncb( (void *) PEAK_POS1);
     823    update_nonl_frame();
     824}
     825
     826static void nonl_tripleLorentzian_cb(void *data)
     827{   int i;
     828    nonl_opts.title   = copy_string(nonl_opts.title, "Double Lorentzian function");
     829    nonl_opts.formula = copy_string(nonl_opts.formula, "y = A0 + (2*A2*A3/pi)/(4*(x-A1)^2 + A2^2) + (2*A5*A6/pi)/(4*(x-A4)^2 + A5^2) + (2*A8*A9/pi)/(4*(x-A7)^2 + A8^2)");
     830    nonl_opts.parnum = 10;
     831
     832    for (i=0; i<nonl_opts.parnum; i++)
     833        {nonl_parms[i].value=1;}
     834
     835    sprintf(buf, "A0: Baseline offset\nA1, A4, A7: Center of peaks 1, 2, 3\nA2, A5, A7: Full width at half maximum of peaks 1, 2, 3\nA3, A6, A9: Area of peaks 1, 2, 3\n\n");
     836    stufftext(buf);
     837    set_actioncb( (void *) PEAK_POS1B);
     838    update_nonl_frame();
     839}
     840
     841static void nonl_Gaussian_cb(void *data)
     842{   int i;
     843    nonl_opts.title   = copy_string(nonl_opts.title, "Gaussian function");
     844    nonl_opts.formula = copy_string(nonl_opts.formula, "y = A0 + (A3*2*sqrt(ln(2)/pi)/A2)*exp(-4*ln(2)*((x-A1)/A2)^2)");
     845    nonl_opts.parnum = 4;
     846    for (i=0; i<nonl_opts.parnum; i++)
     847        {nonl_parms[i].value=1;}
     848    sprintf(buf, "A0: Baseline offset\nA1: Center of the peak\nA2: Full width at half maximum\nA3: Peak area\n\n");
     849    stufftext(buf);
     850    set_actioncb( (void *) PEAK_POS);
     851    update_nonl_frame();
     852}
     853
     854static void nonl_doubleGaussian_cb(void *data)
     855{   int i;
     856    nonl_opts.title   = copy_string(nonl_opts.title, "Double Gaussian function");
     857    nonl_opts.formula = copy_string(nonl_opts.formula, "y = A0 + (A3*2*sqrt(ln(2)/pi)/A2)*exp(-4*ln(2)*((x-A1)/A2)^2) + (A6*2*sqrt(ln(2)/pi)/A5)*exp(-4*ln(2)*((x-A4)/A5)^2)");
     858    nonl_opts.parnum = 7;
     859
     860    for (i=0; i<nonl_opts.parnum; i++)
     861        {nonl_parms[i].value=1;}
     862
     863    sprintf(buf, "A0: Baseline offset\nA1, A4: Center of peaks 1, 2\nA2, A5: Full width at half maximum of peaks 1, 2\nA3, A6: Area of peaks 1, 2\n\n");
     864    stufftext(buf);
     865    set_actioncb( (void *) PEAK_POS1);
     866    update_nonl_frame();
     867}
     868
     869static void nonl_tripleGaussian_cb(void *data)
     870{   int i;
     871    nonl_opts.title   = copy_string(nonl_opts.title, "Double Gaussian function");
     872    nonl_opts.formula = copy_string(nonl_opts.formula, "y = A0 + (A3*2*sqrt(ln(2)/pi)/A2)*exp(-4*ln(2)*((x-A1)/A2)^2) + (A6*2*sqrt(ln(2)/pi)/A5)*exp(-4*ln(2)*((x-A4)/A5)^2)+ (A9*2*sqrt(ln(2)/pi)/A8)*exp(-4*ln(2)*((x-A7)/A8)^2)");
     873    nonl_opts.parnum = 10;
     874
     875    for (i=0; i<nonl_opts.parnum; i++)
     876        {nonl_parms[i].value=1;}
     877
     878    sprintf(buf, "A0: Baseline offset\nA1, A4, A7: Center of peaks 1, 2, 3\nA2, A5, A8: Full width at half maximum of peaks 1, 2, 3\nA3, A6, A9: Area of peaks 1, 2, 3\n\n");
     879    stufftext(buf);
     880    set_actioncb( (void *) PEAK_POS1B);
     881    update_nonl_frame();
     882}
     883
     884static void nonl_Gaussian2_cb(void *data)
     885{   int i;
     886    nonl_opts.title   = copy_string(nonl_opts.title, "Gaussian (chromatography) function");
     887    nonl_opts.formula = copy_string(nonl_opts.formula, "y = A0 + (1/sqrt(2*pi))*(A3/A2)*exp(-(x-A1)^2/2*A2^2)");
     888    nonl_opts.parnum = 4;
     889    for (i=0; i<nonl_opts.parnum; i++)
     890        {nonl_parms[i].value=1;}
     891    sprintf(buf, "A0: Baseline offset\nA1: Center of the peak (retention time)\nA2: Standard deviation of the peak\nA3: Peak area\n\n");
     892    stufftext(buf);
     893    set_actioncb( (void *) PEAK_POS);
     894    update_nonl_frame();
     895}
     896
     897static void nonl_PsVoight1_cb(void *data)
     898{   int i;
     899    nonl_opts.title   = copy_string(nonl_opts.title, "Pseudo Voigt 1 function");
     900    nonl_opts.formula = copy_string(nonl_opts.formula, "y = A0 + A3 * (A4*(2/pi)*A2/(4*(x-A1)^2+A2^2) + (1-A4)*exp(-4*ln(2)*(x-A1)^2/A2^2)*(sqrt(4*ln(2))/(A2*sqrt(pi))))");
     901    nonl_opts.parnum = 5;
     902    for (i=0; i<nonl_opts.parnum-1; i++)
     903        {nonl_parms[i].value=1;}
     904    nonl_parms[4].value=0.5;
     905    sprintf(buf, "Gaussian and Lorentzian have the same width\nA0: Baseline offset\nA1: Center of the peak\nA2: Full width at half maximum\nA3: Amplitude\nA4: Profile shape factor \n\n");
     906    stufftext(buf);
     907    set_actioncb( (void *) PEAK_POS);
     908    update_nonl_frame();
     909}
     910
     911static void nonl_PsVoight2_cb(void *data)
     912{   int i;
     913    nonl_opts.title   = copy_string(nonl_opts.title, "Pseudo Voigt 2 function");
     914    nonl_opts.formula = copy_string(nonl_opts.formula, "y = A0 + A3 * (A5*(2/pi)*A2/(4*(x-A1)^2+A2^2) + (1-A5)*exp(-4*ln(2)*(x-A1)^2/A4^2)*(sqrt(4*ln(2))/(A2*sqrt(pi))))");
     915    nonl_opts.parnum = 6;
     916    for (i=0; i<nonl_opts.parnum-1; i++)
     917        {nonl_parms[i].value=1;}
     918    nonl_parms[5].value=0.5;
     919    sprintf(buf, "Gaussian and Lorentzian have different width\nA0: Baseline offset\nA1: Center of the peak\nA2: Full width at half maximum (Lorentzian)\nA3: Amplitude\nA4: Full width at half maximum (Gaussian) \nA5: Profile shape factor \n\n");
     920    stufftext(buf);
     921    set_actioncb( (void *) PEAK_POS);
     922    update_nonl_frame();
     923}
     924
     925static void nonl_DS_cb(void *data)
     926{   nonl_opts.title   = copy_string(nonl_opts.title, "Doniach-Sunjic function");
     927    nonl_opts.formula = copy_string(nonl_opts.formula, "y = A0 + A3*cos((pi*A4/2)+(1-A4)*atan((x-A1)/A2))/(A2^2+(x-A1)^2)^((1-A4)/2)");
     928    nonl_opts.parnum = 5;
     929
     930    nonl_parms[0].value=1;
     931    nonl_parms[2].value=1;
     932    nonl_parms[4].value=0.5;
     933
     934    sprintf(buf, "A0: Baseline offset\nA1: Center of the peak\nA2: Full width at half maximum\nA3: Peak area\nA4: Asymmetry parameter \n\n");
     935    stufftext(buf);
     936    set_actioncb( (void *) PEAK_POS);
     937    update_nonl_frame();
     938}
     939
     940static void nonl_Asym2Sig_cb(void *data)
     941{   int i;
     942    nonl_opts.title   = copy_string(nonl_opts.title, "Asymmetric double sigmoidal function");
     943    nonl_opts.formula = copy_string(nonl_opts.formula, "y = A0 + A3*(1/(1+exp(-(x-A1+A2/2)/A4)))*(1-(1/(1+exp(-(x-A1-A2/2)/A5))))");
     944    nonl_opts.parnum = 6;
     945    for (i=0; i<nonl_opts.parnum; i++)
     946        {nonl_parms[i].value=1;}
     947    sprintf(buf, "A0: Baseline offset\nA1: Center of the peak\nA2: Width 1\nA3: Amplitude\nA4: Width 2\nA5: Width 5 \n\n");
     948    stufftext(buf);
     949    set_actioncb( (void *) PEAK_POS);
     950    update_nonl_frame();
     951}
     952
     953static void nonl_LogNormal_cb(void *data)
     954{   int i;
     955    nonl_opts.title   = copy_string(nonl_opts.title, "Log Normal Function");
     956    nonl_opts.formula = copy_string(nonl_opts.formula, "y = A0 + A3*exp(-((ln(x)-ln(A1))^2)/(2*A2))");
     957    nonl_opts.parnum = 4;
     958    for (i=0; i<nonl_opts.parnum; i++)
     959        {nonl_parms[i].value=1;}
     960    sprintf(buf, "A0: Baseline offset\nA1: Center of the peak\nA2: Width\nA3: Amplitude\n\n");
     961    stufftext(buf);
     962    set_actioncb( (void *) PEAK_POS);
     963    update_nonl_frame();
     964}
     965
     966static void nonl_GCAS_cb(void *data)
     967{   int i;
     968    nonl_opts.title   = copy_string(nonl_opts.title, "Gram-Charlier A-Series");
     969    nonl_opts.formula = copy_string(nonl_opts.formula, "y = A0 + A3/(A2*sqrt(2*pi))*exp(-0.5*((x-A1)/A2)^2)*(1+(A4/6)*(((x-A1)/A2)^3-3*(x-A1)/A2)+(A5/24)*(((x-A1)/A2)^4-6*((x-A1)/A2)^3+3))");
     970    nonl_opts.parnum = 5;
     971    for (i=0; i<nonl_opts.parnum; i++)
     972        {nonl_parms[i].value=1;}
     973    sprintf(buf, "A0: Baseline offset\nA1: Center of the peak\nA2: Standard deviation\nA3: Peak Area\nA4: Skew\nA5: Excess\n\n");
     974    stufftext(buf);
     975    set_actioncb( (void *) PEAK_POS);
     976    update_nonl_frame();
     977}
     978
     979static void nonl_ECS_cb(void *data)
     980{   int i;
     981    nonl_opts.title   = copy_string(nonl_opts.title, "Edgeworth-Cramer Series");
     982    nonl_opts.formula = copy_string(nonl_opts.formula, "y = A0 + A3/(A2*sqrt(2*pi))*exp(-0.5*((x-A1)/A2)^2)*(1+(A4/6)*(((x-A1)/A2)^3-3*(x-A1)/A2)+(A5/24)*(((x-A1)/A2)^4-6*((x-A1)/A2)^3+3) + (A5^2/720)*(((x-A1)/A2)^6-15*((x-A1)/A2)^4+45*((x-A1)/A2)^2-15))");
     983    nonl_opts.parnum = 5;
     984    for (i=0; i<nonl_opts.parnum; i++)
     985        {nonl_parms[i].value=1;}
     986    sprintf(buf, "A0: Baseline offset\nA1: Center of the peak\nA2: Standard deviation\nA3: Peak Area\nA4: Skew\nA5: Excess\n\n");
     987    stufftext(buf);
     988    set_actioncb( (void *) PEAK_POS);
     989    update_nonl_frame();
     990}
     991
     992static void nonl_InvPoly_cb(void *data)
     993{   int i;
     994    nonl_opts.title   = copy_string(nonl_opts.title, "Inverse Polynomial Function");
     995    nonl_opts.formula = copy_string(nonl_opts.formula, "y=A0+A3/(1+ A4*(2*(x-A1)/A2)^2 + A5*(2*(x-A1)/A2)^4 + A6*(2*(x-A1)/A2)^6)");
     996    nonl_opts.parnum = 7;
     997    for (i=0; i<nonl_opts.parnum; i++)
     998        {nonl_parms[i].value=1;}
     999    sprintf(buf, "A0: Baseline offset\nA1: Center of the peak\nA2: Standard deviation\nA3: Peak Area\nA4, A5, A6: Parameters\n\n");
     1000    stufftext(buf);
     1001    set_actioncb( (void *) PEAK_POS);
     1002    update_nonl_frame();
     1003}
     1004
     1005static void nonl_Sine_cb(void *data)
     1006{   int i;
     1007    nonl_opts.title   = copy_string(nonl_opts.title, "Sine Function");
     1008    nonl_opts.formula = copy_string(nonl_opts.formula, "y=A0+A3*sin(pi*(x-A1)/A2)");
     1009    nonl_opts.parnum = 4;
     1010    for (i=0; i<nonl_opts.parnum; i++)
     1011        {nonl_parms[i].value=1;}
     1012    sprintf(buf, "A0: Baseline offset\nA1: Center\nA2: Width\nA3: Amplitude\n\n");
     1013    stufftext(buf);
     1014    set_actioncb( (void *) PEAK_POS);
     1015    update_nonl_frame();
     1016}
     1017
     1018static void nonl_Sinesq_cb(void *data)
     1019{   int i;
     1020    nonl_opts.title   = copy_string(nonl_opts.title, "Sine Function");
     1021    nonl_opts.formula = copy_string(nonl_opts.formula, "y=A0+A3*(sin(pi*(x-A1)/A2))^2");
     1022    nonl_opts.parnum = 4;
     1023    for (i=0; i<nonl_opts.parnum; i++)
     1024        {nonl_parms[i].value=1;}
     1025    sprintf(buf, "A0: Baseline offset\nA1: Center\nA2: Width\nA3: Amplitude\n\n");
     1026    stufftext(buf);
     1027    set_actioncb( (void *) PEAK_POS);
     1028    update_nonl_frame();
     1029}
     1030
     1031static void nonl_Sinedamp_cb(void *data)
     1032{   int i;
     1033    nonl_opts.title   = copy_string(nonl_opts.title, "Sine Function");
     1034    nonl_opts.formula = copy_string(nonl_opts.formula, "y=A0+A3*exp(-x/A4)*sin(pi*(x-A1)/A2)");
     1035    nonl_opts.parnum = 5;
     1036    for (i=0; i<nonl_opts.parnum; i++)
     1037        {nonl_parms[i].value=1;}
     1038    sprintf(buf, "A0: Baseline offset\nA1: Center\nA2: Width\nA3: Amplitude\nA4: Decay time\n\n");
     1039    stufftext(buf);
     1040    set_actioncb( (void *) PEAK_POS);
     1041    update_nonl_frame();
     1042}
     1043
     1044static void nonl_ExpDec1_cb(void *data)
     1045{   int i;
     1046    nonl_opts.title   = copy_string(nonl_opts.title, "Exponential Decay 1");
     1047    nonl_opts.formula = copy_string(nonl_opts.formula, "y=A0+A3*exp(-(x-A1)/A2)");
     1048    nonl_opts.parnum = 4;
     1049    for (i=0; i<nonl_opts.parnum; i++)
     1050        {nonl_parms[i].value=1;}
     1051    update_nonl_frame();
     1052}
     1053
     1054static void nonl_ExpDec2_cb(void *data)
     1055{   int i;
     1056    nonl_opts.title   = copy_string(nonl_opts.title, "Exponential Decay 2");
     1057    nonl_opts.formula = copy_string(nonl_opts.formula, "y=A0+A3*exp(-(x-A1)/A2)+A6*exp(-(x-A4)/A5)");
     1058    nonl_opts.parnum = 7;
     1059    for (i=0; i<nonl_opts.parnum; i++)
     1060        {nonl_parms[i].value=1;}
     1061    update_nonl_frame();
     1062}
     1063
     1064static void nonl_ExpGrow1_cb(void *data)
     1065{   int i;
     1066    nonl_opts.title   = copy_string(nonl_opts.title, "Exponential Growth 1");
     1067    nonl_opts.formula = copy_string(nonl_opts.formula, "y=A0+A3*exp((x-A1)/A2)");
     1068    nonl_opts.parnum = 4;
     1069    for (i=0; i<nonl_opts.parnum; i++)
     1070        {nonl_parms[i].value=1;}
     1071    update_nonl_frame();
     1072}
     1073
     1074static void nonl_ExpGrow2_cb(void *data)
     1075{   int i;
     1076    nonl_opts.title   = copy_string(nonl_opts.title, "Exponential Growth 2");
     1077    nonl_opts.formula = copy_string(nonl_opts.formula, "y=A0+A3*exp((x-A1)/A2)+A6*exp((x-A4)/A5)");
     1078    nonl_opts.parnum = 7;
     1079    for (i=0; i<nonl_opts.parnum; i++)
     1080        {nonl_parms[i].value=1;}
     1081    update_nonl_frame();
     1082}
     1083
     1084static void nonl_Hyperbol_cb(void *data)
     1085{   int i;
     1086    nonl_opts.title   = copy_string(nonl_opts.title, "Hyperbolic");
     1087    nonl_opts.formula = copy_string(nonl_opts.formula, "y=A0+(A1*x)/(A2+x)");
     1088    nonl_opts.parnum = 3;
     1089    for (i=0; i<nonl_opts.parnum; i++)
     1090        {nonl_parms[i].value=1;}
     1091    update_nonl_frame();
     1092}
     1093
     1094static void nonl_Bradley_cb(void *data)
     1095{   int i;
     1096    nonl_opts.title   = copy_string(nonl_opts.title, "Bradley");
     1097    nonl_opts.formula = copy_string(nonl_opts.formula, "y=A0*ln(-A1*ln(x))");
     1098    nonl_opts.parnum = 2;
     1099    for (i=0; i<nonl_opts.parnum; i++)
     1100        {nonl_parms[i].value=1;}
     1101    update_nonl_frame();
     1102}
     1103
     1104static void nonl_Log3_cb(void *data)
     1105{   int i;
     1106    nonl_opts.title   = copy_string(nonl_opts.title, "Logarithm 3");
     1107    nonl_opts.formula = copy_string(nonl_opts.formula, "y=A0-A1*ln(x+A2)");
     1108    nonl_opts.parnum = 3;
     1109    for (i=0; i<nonl_opts.parnum; i++)
     1110        {nonl_parms[i].value=1;}
     1111    update_nonl_frame();
     1112}
     1113
     1114static void nonl_WeibullPD_cb(void *data)
     1115{   int i;
     1116    nonl_opts.title   = copy_string(nonl_opts.title, "Weibull Probability Density");
     1117    nonl_opts.formula = copy_string(nonl_opts.formula, "y=(A0/A1)*((x/A1)^(A0-1))*exp(-(x/A1)^A0)");
     1118    nonl_opts.parnum = 2;
     1119    for (i=0; i<nonl_opts.parnum; i++)
     1120        {nonl_parms[i].value=1;}
     1121    update_nonl_frame();
     1122}
     1123
     1124static void nonl_WeibullCD_cb(void *data)
     1125{   int i;
     1126    nonl_opts.title   = copy_string(nonl_opts.title, "Weibull Cumulative Distribution");
     1127    nonl_opts.formula = copy_string(nonl_opts.formula, "y=1-exp(-(x/A1)^A0)");
     1128    nonl_opts.parnum = 2;
     1129    for (i=0; i<nonl_opts.parnum; i++)
     1130        {nonl_parms[i].value=1;}
     1131    update_nonl_frame();
     1132}