iolite has always supported time-resolved data processing from a variety of instruments, including TIMS and solution ICP-MS. Its implementation of the double-spike inversion, which is an approach that calculates mass bias, mixture proportions, etc, sets it apart from most solution mass spectrometry software.
Creech and Paul presented an approach using iolite that calculates the results on a measurement-by-measurement basis to give a better estimate of the uncertainty for each analysis. Although the calculations presented here usually take less than a few seconds on a reasonably modern computer, the measurement-by-measurement approach also has the advantage that the user can adjust selections to see how the uncertainty is affected.
John Creech’s IsoSpike repository includes all the code needed to calculate double-spike inversion results. This post provides a guide to setting up iolite to work with IsoSpike. It does not, however, cover any of the basic concepts of the double spike inversion technique. For that, I would recommend Rudge et al. (1999), available at www.johnrudge.com as a starting point.
Getting IsoSpike
The easiest way to get the IsoSpike library is to download it from GitHub as a zip file: https://github.com/thisisjohnc/isospike/archive/refs/heads/master.zip
Make sure that you unzip the files into a location that you have full read/write access to, and that iolite has full read/write permissions as well. I recommend your Documents folder, but not within your iolite folder (i.e. the folder that contains your reference material files etc).
The unzipped folder will contain several sub-folders. The most important one here is the ‘IsoSpike_Iolite4’ folder, which contains the code for iolite, along with an example DRS for Pt isotopes.
Adding IsoSpike to iolite
For iolite to be able to use the functions within IsoSpike, you’ll need to add the location of the IsoSpike_Iolite4 folder. Do this by going to iolite’s Preferences, and in the Paths section click the + button at the end of the ‘Python Site Packages’ line. This will add a location for iolite to look for python packages each time it starts. When you click the + button, you’ll be asked to choose a folder. Select the IsoSpike_Iolite4 folder (i.e. the folder containing the IsoSpike_iolite4.py file). Then click Save to save your preferences, and restart iolite.
To check that this step has worked, open the Python console (from the Tools menu) and type the following:
from IsoSpike_iolite4 import IsoSpike
If that works without an error, you can now use IsoSpike in your calculations. If not, check that the folder you added to the python site packages list has the IsoSpike_iolite4.py file in it.
Using IsoSpike in a DRS
To use IsoSpike in your custom DRS, start by baseline subtracting your channels and (optionally) applying a mask. Then calculate your three main ratios for the double-spike inversion. You may want to do any interference corrections before creating the ratios. Here’s an example using Ni Isotopes:
# Reference baseline subtracted data
Ni58_CPS = data.timeSeries("Ni58_CPS").data()
Ni60_CPS = data.timeSeries("Ni60_CPS").data()
Ni61_CPS = data.timeSeries("Ni61_CPS").data()
Ni62_CPS = data.timeSeries("Ni62_CPS").data()
x64_CPS = data.timeSeries("Ni64_CPS").data() # This will be corrected for 64Zn interference below...
# Correct for 64Zn interference
Zn66_CPS = data.timeSeries("Zn66_CPS").data()
Zn64 = 1.773 * Zn66_CPS
Ni64_CPS = x64_CPS - Zn64
# Calculate raw ratios
Raw60_58 = Ni60_CPS / Ni58_CPS
Raw61_58 = Ni61_CPS / Ni58_CPS
Raw62_58 = Ni62_CPS / Ni58_CPS
# Add raw ratios to intermediate channels
data.createTimeSeries("Raw60_58", data.Intermediate, indexChannel.time(), Raw60_58)
data.createTimeSeries("Raw61_58", data.Intermediate, indexChannel.time(), Raw61_58)
data.createTimeSeries("Raw62_58", data.Intermediate, indexChannel.time(), Raw62_58)
Before calling the IsoSpike function, the ratio names, un-mixed and spike ratios, and natural log mass ratios for the isotopes will need to be defined. Again, here’s an example using Ni isotopes:
# Double-spike Inversion Parameters
rationames = ['Ni60/Ni58', 'Ni61/Ni58', 'Ni62/Ni58']
unmixedRatios = [0.3852, 0.0167, 0.0534]
spikeRatios = [0.61283, 81.22346, 85.94008]
logMassRatios = [0.03386, 0.05042, 0.06665]
DSsettings = np.array([unmixedRatios, spikeRatios, logMassRatios])
At the end, these are stored in a variable called DSsettings
(not to be confused with DRSsettings: these are Double Spike settings, not DRS settings).
Then IsoSpike can be used by calling the function IsoSpike(DSsettings,ratio1,ratio2,ratio3)
. The arguments are our DSsettings variable we created above, and the data arrays of our three ratios. In our example, this would be:
IsoSpike_results = IsoSpike(DSsettings, Raw60_58, Raw61_58, Raw62_58)
This function returns a series of arrays, including the calculated lambda, alpha and beta values, corrected ratios and αΊ values. These values can then be used as they are, or can be used to calculate delta values relative to a reference material.
To unpack the results and convert them to iolite channels, use the following as a template:
ones = np.ones(len(indexChannel.time())) # initialise an array of ones to multiply results by to get proper numpy arrays
# Unpack results
lam = ones * IsoSpike_results[:, 0]
alpha = ones * IsoSpike_results[:, 1]
beta = ones * IsoSpike_results[:, 2]
#create time series in Iolite
data.createTimeSeries("lambda", data.Output, indexChannel.time(), lam)
data.createTimeSeries("alpha", data.Output, indexChannel.time(), alpha)
data.createTimeSeries("beta", data.Output, indexChannel.time(), beta)
The full Ni isotopes example is available on the iolite GitHub page: https://github.com/iolite-LA-ICP-MS/iolite4-python-examples/tree/master/drs
Thank you for reading! Click here to discuss.