5.5 Analysis

This folder contains examples of performing curve fitting and generating analysis report with originpro package.

Batch Fitting Multiple Data Files

'''
This sample is to show how to run gaussian peak fit on multiple data files. 
Then the fitted peak parameters xc, w, A are plotted as a function of temperature
in a three Y axes graph.
'''

import originpro as op
import numpy as np

# One worksheet for imported data, one worksheet for peak fitting result
wks = op.new_sheet()
wks_result = op.new_sheet()


wts = [0, 25, 100, 150, 200]
for i, wt in enumerate(wts):    
    # Import each data file into wks
    fd = op.path('e') + 'Samples\Batch2'
    fn = f'{fd}\Sample 2 {wt} wt.txt'
    wks.from_file(fn, keep_DC=False)
    
    # Baseline subtraction
    spec = wks.to_list(1)
    spec = np.array(spec)
    base = np.linspace(spec[0], spec[-1], len(spec)) # straight line connecting start and end point as baseline
    spec = spec - base
    wks.from_list(1, spec)      
    
    # Run Gaussian fit on subtracted spectrum
    model = op.NLFit('Gaussian')
    model.set_data(wks, 0, 1)
    model.fix_param('y0',0)
    model.fit()
    ret = model.result()
    
    # Fitting result is saved to each row of wks_result
    wks_result.from_list2([wt, ret['xc'], ret['w'], ret['A'], ret['adjr']], i) 
    
wks_result.set_labels(['temperature','fit x','fit width', 'fit area', 'Adj. R-Square'])

# Plot the data
gp = op.new_graph(template='3Ys_Y-YY')
for i in range(3):    
    gp[i].add_plot(wks_result,1+i,0)
    gp[i].rescale()

# Customize Legend
lgnd = gp[0].label('Legend')
lgnd.text='\l(1.1) %(1.1)   \l(2.1) %(2.1)   \l(3.1) %(3.1)'
lgnd.set_int('fsize', 27)
lgnd.set_int('top', 400)

Extract Values from NLFit Report Tables

'''
This sample shows how to use report_table function to
access a table in an Analysis Report Sheet
'''
import originpro as op
import pandas as pd
import os
import re

# Load analysis template book that ships with Origin.
at = op.load_book(op.path('e') + r'Samples\Batch Processing\Sensor Analysis.ogw')

# Get 1st worksheet in book.
wks = at[0]
wks_table = at[1]
df_list = []

# Get folder for data files that ship with Origin.
data_folder = op.path('e') + r'Samples\Curve Fitting'

# Iterate data file folder for file names to import.
for file in os.listdir(data_folder):

    # Filter for specific data files.
    if re.search('^Sensor[0-9]{2}.dat$', file):

        # Full path to file to import.
        imp_file = os.path.join(data_folder, file)

        # Import the file into the worksheet and removing the Data Connector.
        wks.from_file(imp_file, False)

        # Wait for analysis operation to complete.
        op.wait()

        # If  you want to see live updates of the graph, add the line below.
        #op.wait('s', 0.1)
        
        df = wks_table.report_table('Summary')
        df.iloc[:, 0] = file
        
        df_list.append(df)

        print(f'working on {file}')
        
result = pd.concat(df_list)
wks_result = op.new_sheet()
wks_result.from_df(result)

Fit 2 Indepedents and 2 Dependents

import originpro as op
wks = op.new_sheet()
fn=op.path('e') + 'Samples\Curve Fitting\Enzyme2.dat'
wks.from_file(fn, False)
wks.cols_axis('x',2,2)

#Specify the input data range, which follows 
#the independent/dependent order in FDF (x1, x2, v1, v2)
range=f'{wks.lt_range()}!(1,3,2,4)'
model = op.NLFit('HillBurk')
model.set_range(range)
model.fit()
model.report(True)

Linear Regression and Plot

'''
This sample is to show how to run linear regression with Python in Origin. The fitted curve 
and prediction band are then plotted out.
'''

import originpro as op

# Import data file
wb = op.new_book()
wks = wb[0]
fn=op.path('e') + 'Samples\Curve Fitting\Linear Fit.dat'
wks.from_file(fn,False)

#Perform linear fit 
lr = op.LinearFit()
lr.set_data(wks, 0, 1)
lr.fix_intercept(-0.7)
r, c = lr.report(3) # Return the result report sheet and fitted curve sheet.
wReport=op.find_sheet('w', r)
wCurves=op.find_sheet('w', c)

# Plot the data and fitted curve and confidence band
gp = op.new_graph()
gl = gp[0]

# Plot data as scatter plot
pltdata = gl.add_plot(wks, 1, 0, type='s')

# Add the confidence band
conf = gl.add_plot(wCurves, 2, 0) 
gl.add_plot(wCurves, 3, 0)

# Group the newly added plots, starting from 1 to skip the scatter data
gl.group(True, 1)
conf.colorinc=0
conf.transparency = 80
conf.set_fill_area(op.ocolor('Red')) # fill the color to the next plot

gl.add_plot(wCurves, 1, 0) # Plot the fitted line

gl.rescale()

# Customize legend
lgnd = gl.label('Legend')
lgnd.text='\\l(4) Linear Fit\n\\l(2) Confidence Band'
lgnd.set_int('left',1400)
lgnd.set_int('top',700)
lgnd.set_int('showframe',0)

Load and Run Multiple Linear Fit Templates

'''
Import each data file in a sample folder into an Analysis Template and
perform the fitting and update the reports with graphs, so you end up
with a book for each file in the Origin workspace for further examination
'''
import originpro as op
import pandas as pd
import os
import re


# location of sample data files that ship with Origin.
data_folder = op.path('e') + r'Samples\Curve Fitting'

# Iterate data file folder for file names to import.
for file in os.listdir(data_folder):
    if re.search('^Sensor[0-9]{2}.dat$', file):
        print(f'working on {file}')
        imp_file = os.path.join(data_folder, file)
        # Load analysis template book that ships with Origin.
        at = op.load_book(op.path('e') + r'Samples\Batch Processing\Sensor Analysis.ogw')
        # This template put Data sheet as 1st worksheet in book.
        wks = at[0]
        # Import the file into the worksheet and removing the Data Connector.
        wks.from_file(imp_file, False)

        # Wait for analysis operation to complete.
        op.wait()

Open Dialog for Interactive Control of the Fitting

"""
Fitting a curve on a graph and open dialog to adjust the parameters before final fitting
"""
import originpro as op

wks = op.new_sheet()
fn=op.path('e') + 'Samples\Curve Fitting\Gaussian.dat'
wks.from_file(fn, False)
graph = op.new_graph(template='scatter')
gl=graph[0]
dp = gl.add_plot(wks, 1, 0)
gl.rescale()

model = op.NLFit('Gauss')
model.set_range(dp.lt_range())
"""
dialog is modal, so wont close until OK, but you can use Minimize button 
to rollup the dialog and interact with the graph, then click Minimize again 
to open the dialog to continue
"""
model.param_box()
#after the dialog, still need to call Fit for final processing
model.fit()
rr=model.result()
#accessing parameters and errors
xc=rr['xc']
xc_err=rr['e_xc']
#accessing other fitting stats
chisqr=rr['chisqr']
adjr=rr['adjr']
print(f'AdjR2={adjr}, xc={xc}+-{xc_err}')

Sequential Fit Multiple Files

'''
Import each data file in a sample folder into and perform fitting with parameters dialog
to check each fit and generate a sheet with result parameters and stats.
'''
import originpro as op
import os

data_folder = op.path('e') + r'Samples\Batch Processing'
#only to process 3 files
names = ['T285K.csv', 'T305K.csv', 'T345K.csv']
pk_centers=[]
Rsqrs=[]
wdata = op.new_sheet()
graph = op.new_graph(template='scatter')
gl=graph[0]
model = op.NLFit('Gauss')
show_hint=True
for file in names:
    f = os.path.join(data_folder, file)
    print(f'working on {f}')
    wdata.from_file(f, False)
    dp = gl.add_plot(wdata, 1, 0)
    gl.rescale()
    model.set_range(dp.lt_range())
    if show_hint:
        op.messagebox('You can click the Minimize button on the Parameters Dialog to manipulate the graph')
        show_hint = False
    model.param_box()
    model.fit()

    if not op.messagebox('Take a look at the fit', True):
        model.result()#must call either result or report to end the fitting
        break
        
    rr=model.result()
    gl.remove(dp)
    Rsqrs.append(rr['adjr'])
    pk_centers.append(rr['xc'])
    
wdata.get_book().destroy()    
graph.destroy()
wks = op.new_sheet()
wks.from_list(0, names, 'File Name')
wks.from_list(1, pk_centers, 'Peak Center')
wks.from_list(2, Rsqrs, 'R-sqr')

Simple Curve Fit on a Graph

"""
Simple example of doing a non-linear fitting with a report sheet
"""
import originpro as op

wks = op.new_sheet()
fn=op.path('e') + 'Samples\Curve Fitting\Gaussian.dat'
wks.from_file(fn, False)
graph = op.new_graph(template='scatter')
gl=graph[0]
dp = gl.add_plot(wks, 1, 0)
gl.rescale()

#do the fitting and generate report
model = op.NLFit('Gauss')
model.set_range(dp.lt_range())
model.fit()
r, c = model.report()
wReport=op.find_sheet('w', r)
wReport.activate()

Simple Curve Fit to XY Data

"""
Simple example of doing a non-linear fitting without creating report sheet
"""
import originpro as op

wks = op.new_sheet()
fn=op.path('e') + 'Samples\Curve Fitting\Gaussian.dat'
wks.from_file(fn, False)


#do the fitting and receive fitting parameters. No report will be generated
model = op.NLFit('Gauss')
model.set_data(wks, 0, 1)
model.fix_param('y0', 0)
model.fit()
rr=model.result()

#accessing parameters and errors
xc=rr['xc']
xc_err=rr['e_xc']
#accessing other fitting stats
chisqr=rr['chisqr']
adjr=rr['adjr']

print(f'xc={xc}+-{xc_err}')

Simple Curve Fit with Report

"""
Simple example of doing a non-linear fitting with a report sheet
"""
import originpro as op

wks = op.new_sheet()
fn=op.path('e') + 'Samples\Curve Fitting\Gaussian.dat'
wks.from_file(fn, False)

#do the fitting and generate report
model = op.NLFit('Gauss')
model.set_data(wks, 0, 1)
model.fit()
r, c = model.report()
wReport=op.find_sheet('w', r)
wReport.activate()

Tabulate Multiple Nonlinear Fit Results

'''
This sample is to show how to run non-linear regression on multiple datasets and output 
the fitted result.
'''

import originpro as op
import pandas as pd

# Import data file
wb = op.new_book()
wks = wb[0]
fn=op.path('e') + 'Samples\Curve Fitting\Step01.dat'
wks.from_file(fn, dctype='Import Filter')

# Perform nonlinear curve fit on each dataset
model = op.NLFit('Asymptotic1')
nn = int(wks.cols/2)
result = []
for i in range(nn):
    col_name = wks.get_label(2*i, 'L')
    model.set_data(wks, 2*i, 2*i+1)
    model.fit()
    ret = model.result()
    result.append([col_name, ret['a'], ret['b'], ret['c'], ret['adjr']])    
df = pd.DataFrame(result, columns=['data','fit a','fit b', 'fit c', 'Adj. R-Square'])

# Generate the result
wks = op.new_sheet(lname='Result')
wks.from_df(df)