Repeating analysis of the same type of samples, as typically needed in quality control, is tedious and time consuming. BeautifulJASON provides the framework to speed up these tasks to the point that they can be completely automated and all that is required is to check the report automatically generated. I will illustrate this with an example studying a sample of Styrene-Butadiene Rubber (SBR).
SBR is the most widely used synthetic rubber and can be produced by the copolymerization of butadiene and styrene. The styrene/butadiene ratio influences the properties of the polymer: with high styrene content, the rubbers are harder and less rubbery. It is therefore key to characterize the composition of this copolymer, and NMR is well suited to this task. In fact, the ISO 21561-1 explains the procedure for the quantitative determination of the microstructure of the butadiene and the content of styrene in solution-polymerized SBR by proton NMR. This relies on extracting the integrals from the SBR spectrum as shown in Figure 1 and described in Table 1.
Figure 1: Example of SBR sample and integration ranges
Table 1: Definition of signal integration areas
Integral C includes the integral of the solvent, so this method proposes measuring the integral of the solvent in a blank sample and subtracting it to integral C:
And the content of each microstructure component (trans and cis, and vinyl) of the butadiene portion and the styrene content is calculated as:
All of this can be automated so with BeautifulJASON. We can simply run a script and automatically integrate, calculate the contents and generate a report:
In order to get here, first we need to define the integrals, in this case we will rely on manual integration rather than automatic integration. We open a dataset in JASON and press the key i (or we left click the integration mode button in the context tool bar in the top left-hand corner of the spectrum we selected). We then integrate the regions of interest by holding the left mouse button and dragging and dropping the cursor horizontally to define the integration region. We repeat this for each integration region. Double clicking on the integral bar opens the integral properties dialog, which allows us, for example, to define more precisely the integration region if we wanted to.
Now that we have the integrals defined we can create a JASON analysis rule, so that this integration is always performed whenever this rule is active and we open a dataset.
The ISO 21561-1 indicates that in addition to the spectrum of SBR, we need the spectrum of a blank, but is there any potential alternative if we have no blank available? We could in principle fit the solvent peak and subtract the area of the fitted peak. When peak picking is done in JASON it will automatically model the peaks. If we change the settings in JASON (Peaks tab in the NMR section) we can change the Refinement parameter, which is the number of iterations used when fitting the peak model to the spectral data. Increasing this parameter may result in a closer fit to the experimental data, and when setting the rules, this is taken into account. In addition, JASON has a solvent detection algorithm, so we do not even need to define the peak if all we need is to subtract the solvent.
In the following video I show how I use the automatic peak picking and generate the rules to automatically process, integrate and peak pick this kind of data.
Once we have a rules library to extract the integrals and peaks, we can create a script to process the data using this library, retrieve the integrals and peaks extracted by JASON and do the needed calculations. We will create this script in Python, so first we need to download and install Python. We can then type in the command line:
pip install beautifuljason
There is further information on BeautifulJASON on the site https://pypi.org/project/beautifuljason/
For the script we first import the BeautifulJASON library:
import beautifuljason as bjason
We then create the variables with the location of the raw data and the name of the rules library being used:
file1 = 'C:/Users/Botana.SERVDOMAIN2/Desktop/python_qc/SBR_proton-1-1.jdf'
rules_name = 'ISO_SBR'
Note this is an example, and we could instead retrieve these parameters as arguments passed to this script using, for example, the functionality of the argparse library. We can also define the location of the library file rather than assuming it is already installed in the JASON software of the current computer.
We create the BeautifulJASON object and load the data with the specified rules library:
with jason.create_document(file1, rules=rules_name) as doc: spec = doc.nmr_data[0]
The first NMR dataset in the Json document is nmr_data[0]. From this dataset we can extract information from each integration region (multiplets, which also contains information about the multiplets, if analyzed). The actual integral value as reported in JASON is defined in the value_hz parameter. We extract the integral value for each of the four integrals and we report it showing only 2 decimal places:
multiplet1 = spec.multiplets[0] int_C_file1 = multiplet1.value_hz print('C Integral is : ', "{:.2f}".format(int_C_file1)) multiplet2 = spec.multiplets[1] int_B_file1 = multiplet2.value_hz print('B Integral is : ', "{:.2f}".format(int_B_file1)) multiplet3 = spec.multiplets[2] int_A_file1 = multiplet3.value_hz print('A Integral is : ', "{:.2f}".format(int_A_file1)) multiplet4 = spec.multiplets[3] int_TMS_file1 = multiplet4.value_hz print('TMS Integral is : ', "{:.2f}".format(int_TMS_file1))
If we had only picked the peak we want to subtract, we could retrieve the area from the first peak in the spectrum (peaks[0]). In this case we have potential picked several peaks, so we iterate through each of them, and we retrieve the first peak identified as an NMR solvent:
solvent = None for peak in spec.peaks: if peak.classification == bjason.NMRPeak.PeakClassification.NMRSolvent: solvent = peak break int_solvent = solvent.area print('Solvent Integral is : ', "{:.2f}".format(solvent.area), ' at ', "{:.2f}".format(solvent.pos[0]), ' ppm')
If we were dealing with a solvent with multiple peaks, we could simply keep adding the area of each peak classed as a solvent to int_solvent inside the for loop. Note that we can also add the area of peaks with other classifications by altering the if condition. The if condition in this code is equivalent to
if peak.classification == 2:
Where 2 is the code for an NMR solvent, the documentation webpage shows which other codes can be used: :
https://www.jeoljason.com/beautifuljason/docs/source/beautifuljason.data.html
We have extracted everything we needed from the data, so now we can save and close the JASON document if we want:
doc.close() doc.copy('C:/Users/Botana.SERVDOMAIN2/Desktop/python_qc/simple_integral_example.jjh5')
Then we run the required calculations (note that as opposed to the ISO procedure, I have replaced the scaled integral C of the blank with the solvent peak area):
c_calib = int_C_file1 - int_solvent s_m = c_calib*104/5*100/(c_calib*104/5+(int_B_file1/2+int_A_file1/4)*54) v_ = int_A_file1/2*100/(int_B_file1/2+int_A_file1/4) tc_ = (int_B_file1/2-int_A_file1/4)/(int_B_file1/2+int_A_file1/4)*100
And with all the calculations done, we can save them to a text file, send them to some other script or simply report them in the command prompt:
print(' Styrene content is : ', "{:.2f}".format(s_m), ' % mass') print(' Vinyl content of butadiene is : ', "{:.2f}".format(v_), ' % molar') print(' Trans and cis content of butadiene is : ', "{:.2f}".format(tc_), ' % molar')
The Python script described here is available at:
https://github.com/adolfobotana/Quality_control/blob/main/SBR_analysis_solventsubtraction.py.
The Python script as specified on the ISO 21561-1 is available at:
https://github.com/adolfobotana/Quality_control/blob/main/SBR_analysis_with_blank_hdf5.py.
It is useful to note that this script is coded in a different way. Instead of relying of BeautifulJASON to retrieve all the information, I use BeautifulJASON just to process, analyze and save the data in the standard HDF-5 format. This format is open and there are free and open source programs like HDFView that allow you to see the structure of the dataset and all its contents, as shown in Figure 2. Then I use the Python library h5py to read its contents. This allows you, once the data is analyzed and saved with JASON, to regenerate the report without JASON, directly retrieving the values stored in the HDF5 file.
Figure 2: Example of a dataset viewed with HDFView
For more information on the HDF-5 format used in JASON, please check our webinar:
Your data in JASON: file formats and external access’
For further information on using BeautifulJASON to study batches of samples, please check our previous blog post:
Batch processing with BeautifulJASON