<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
  <channel>
    <title>Chapter 9 :: Coding For Chemists</title>
    <link>https://codingforchemistsbook.com/book_material/chapter-9/index.html</link>
    <description>Data Download Data for Chapter 9&#xA;Alternatively, individual files can be found in the Data section.&#xA;Code from chapter &#39;&#39;&#39; A quick test script to check the accuracy of numerical integration Written by: Chris Johnson and Ben Lear (authors@codechembook.com) v1.0.0 - 250220 - initial version &#39;&#39;&#39; import numpy as np import scipy.integrate as spi # Gaussian parameters for the simulation A = 1 # amplitude x0 = 0 # center sigma = 1 # width # Create the test data and calculate the analytical value of integral xdata = np.linspace(-10, 10, 11) ydata = A * np.exp(-1 * (xdata - x0)**2 / (2 * sigma**2)) area = A * sigma * np.sqrt(2 * np.pi) # Compute the area using the rectangle rule, the trapezoid rule, or Simpson&#39;s rule area_rect = np.sum(ydata[:-1] * (xdata[1:] - xdata[:-1])) # height * width area_trap = spi.trapezoid(ydata, x = xdata) area_simp = spi.simpson(ydata, x = xdata) # Print the error print(f&#39;Area = {area:8.6f}&#39;) print( &#39;Errors: Absolute --&gt; % Diff&#39;) print(f&#39;Rectangle: {area - area_rect:8.6f} --&gt; {100*(area - area_rect)/area:4.1f}%&#39;) print(f&#39;Trapezoid: {area - area_trap:8.6f} --&gt; {100*(area - area_trap)/area:4.1f}%&#39;) print(f&#34;Simpson&#39;s: {area - area_simp:8.6f} --&gt; {100*(area - area_simp)/area:4.1f}%&#34;) &#39;&#39;&#39; Integrate the intensities of azide peaks in an FTIR and produce a kinetics plot Requires: FTIR spectra in .csv format for each time point filename must include the time the spectrum was taken Written by: Chris Johnson and Ben Lear (authors@codechembook.com) v1.0.0 - 250220 - initial version &#39;&#39;&#39; import numpy as np from plotly.subplots import make_subplots from codechembook.quickTools import quickOpenFilenames, quickPopupMessage from codechembook.quickPlots import customColorList from codechembook.symbols.chem import wavenumber as wn from codechembook.numericalTools import integrateRange # Get and sort the spectrum file names quickPopupMessage(message = &#39;Select CSV files containing the FTIR spectra.&#39;) data_files = sorted(quickOpenFilenames(filetypes = &#39;CSV files, *.csv&#39;)) # Set the upper and lower wavenumbers for the integration integration_limits = np.array([1950, 2150]) # Make a color scale for the different traces in the figure colors = customColorList(len(data_files)) # Get samples of a continuously changing color scale # Loop through files, read data and times, put them in a dict, and add to the plot data = [] fig = make_subplots(rows = 1, cols = 3) for c, file in zip(colors, data_files): wavenumber, absorption = np.genfromtxt(file, delimiter = &#39;,&#39;, unpack = True) time = float(file.stem.split(&#39;_&#39;)[1]) # get the time from the file name # Create a dictionary with everything we need for this file, add it to the list data.append(dict(wavenumber = wavenumber, absorption = absorption, time = time)) # Add the trace to the plot fig.add_scatter(x = wavenumber, y = absorption, line = dict(color = c), name = time, row = 1, col = 1) # Loop through the spectra to background subtract and integrate for c, spec in zip(colors, data): # Find the indicies of the points at the limits of integration xmin_index = np.argmin(abs(spec[&#39;wavenumber&#39;] - integration_limits[0])) xmax_index = np.argmin(abs(spec[&#39;wavenumber&#39;] - integration_limits[1])) # Calculate line that connects the x and y values at the limits of integration m = (spec[&#39;absorption&#39;][xmax_index] - spec[&#39;absorption&#39;][xmin_index]) / (spec[&#39;wavenumber&#39;][xmax_index] - spec[&#39;wavenumber&#39;][xmin_index]) b = spec[&#39;absorption&#39;][xmin_index] - m * spec[&#39;wavenumber&#39;][xmin_index] # Subtract the baseline from the data and add it to the figure spec[&#39;back corr&#39;] = spec[&#39;absorption&#39;] - (m * spec[&#39;wavenumber&#39;] + b) fig.add_scatter(x = spec[&#39;wavenumber&#39;], y = spec[&#39;back corr&#39;], line = dict(color = c), showlegend = False, row = 1, col = 2) # Integrate the baseline-corrected data and store it in the dict spec[&#39;integral&#39;] = integrateRange(spec[&#39;back corr&#39;], spec[&#39;wavenumber&#39;], integration_limits) # Calculate the maximum y value for this spectrum section spec[&#39;ymax&#39;] = np.max(spec[&#39;back corr&#39;][xmin_index:xmax_index]) # Find the max y height to determine the zoom range for the y-axis ymax = max([spec[&#39;ymax&#39;] for spec in data]) # Plot the kinetic trace tdata = np.array([spec[&#39;time&#39;] for spec in data]) # get array of times intdata = np.array([spec[&#39;integral&#39;] for spec in data]) # get array of integrals fig.add_scatter(x = tdata, y = intdata, name = &#39;kinetic trace&#39;, line = dict(color = &#39;black&#39;), row = 1, col = 3) # Format the plot fig.update_xaxes(title = f&#39;wavenumber / {wn}&#39;, row = 1, col = 1) fig.update_yaxes(title = &#39;absorption&#39;, row = 1, col = 1) fig.update_xaxes(title = f&#39;wavenumber / {wn}&#39;, range = integration_limits, row = 1, col = 2) fig.update_yaxes(title = &#39;absorption&#39;, range = [-0.1 * ymax, 1.1 * ymax], row = 1, col = 2) fig.update_xaxes(title = &#39;time /s&#39;, row = 1, col = 3) fig.update_yaxes(title = f&#39;intensity / AU{wn}&#39;, row = 1, col = 3) fig.update_layout(template = &#39;simple_white&#39;) fig.show(&#39;browser&#39;) # format for the static plot fig.update_layout(template = &#39;simple_white&#39;, showlegend = False, width = 4 * 300, height = 1.2 * 300, margin = {&#39;b&#39;: 10, &#39;t&#39;: 30, &#39;l&#39;: 10, &#39;r&#39;: 10}) fig.show(&#39;png&#39;) fig.write_image(format = &#39;png&#39;, file = &#39;IntegrateAzide.png&#39;) Solutions to Exercises Targeted exercises Integrating data using scipy.integrate Exercise 0 The cumulative integral is the integral from the beginning of the data up to a given data point, plotted against the value of the last data point integrated. Write a code that plots the cumulative integral of a Gaussian function with an amplitude of 1, a center of 5, and a width of 1, from 0 to 10 with 100 points on the $x$-axis.</description>
    <generator>Hugo</generator>
    <language>en-us</language>
    <managingEditor>authors@codingforchemistsbook.com (Benjamin Lear and Christopher Johnson)</managingEditor>
    <webMaster>authors@codingforchemistsbook.com (Benjamin Lear and Christopher Johnson)</webMaster>
    <atom:link href="https://codingforchemistsbook.com/book_material/chapter-9/index.xml" rel="self" type="application/rss+xml" />
  </channel>
</rss>