Pulse oximetry -------------- Background ^^^^^^^^^^ A pulse oximeter measures the oxygen saturation of the blood and changes in blood volume in a tissue by measuring the plethysmograph signal. The device is based on two physical principles: (1) the presence of a pulsatile signal generated by arterial blood; (2) the fact that oxyhemoglobin (O₂Hb) and deoxygenated hemoglobin (Hb) have different optical absorption spectra. A pulse oximeter is usually clipped to an appendage, most commonly a finger, but sometimes an ear lobe or nose septum is used. A light source, usually an LED, on one side of the tissue penetrates through the tissue to be detected by a photodetector on the other side. As the light passes through the tissue, it is absorbed by various species. Much absorption happens in the tissue, some more in venous and capillary blood, and still more in non-pulsatile arterial blood. On top of all of that absorption is varying absorption due to pulsatile arterial blood. It is this varying absorption that is measured in pulse oximetry. Pulse detection ~~~~~~~~~~~~~~~~ The transmitted light intensity fluctuates from peaks to valleys according to the systolic and diastolic phases of the cardiac cycle. This fluctuation is typically measured in the IR region of the light spectrum, around 940 nm. The time-trace of this variation is directly proportional to the blood pulsatile motion. Therefore, we can use it to deduce the pulse rate, the number of beats per minute. Measurement of oxygen saturation ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ In addition to measuring a pulse rate, we also wish to measure **oxygen saturation**, which is defined as the ratio of oxyhemoglobin to the total hemoglobin concentration. We cannot exactly measure this with pulse oximetry because we cannot take into account the contributions of nonfunctional hemoglobin, such as carboxyhemoglobin and methemoglobin. So, instead, we define the oxygen saturation, as determined by pulse oximetry, to be .. math:: \begin{align} \text{SpO}_2 = \frac{C_\mathrm{O_2Hb}}{C_\mathrm{O_2Hb} + C_\mathrm{Hb}}. \end{align} To measure SpO₂, we consider absorption at a second wavelength in addition to the IR used to measure the pulse. Below, I show the absoprtion spectra for O₂Hb and Hb. Between about 600 and 800 nm, Hb has a higher extinction coefficient than O₂Hb. If we monitor transmission of light at this second wavelength, in addition to the 940 nM we are already using to detect the pulse, we can determine SpO₂. In particular, there is a big gap between the extinction coefficient of O₂Hb and Hb in the red region, around 660 nm, and the gap is the opposite as in the IR, where O₂Hb has a lower extinction coefficient. .. bokeh-plot:: :source-position: none import pandas as pd import bokeh.plotting import bokeh.io df = pd.read_csv('../pulse_ox/spectra.csv', comment='#') p = bokeh.plotting.figure( frame_width=400, frame_height=200, y_axis_type='log', x_axis_label='wavelength (nm)', y_axis_label='extinction coefficient (1/cm-M)', x_range=[250, 1000], ) p.line( source=df, x='wavelength (nm)', y='molar extinction coefficient for Hb (1/cm-M)', legend_label='Hb', line_width=2 ) p.line( source=df, x='wavelength (nm)', y='molar extinction coefficient for O2Hb (1/cm-M)', legend_label='O₂Hb', line_width=2, line_color='tomato' ) bokeh.io.show(p) Obtaining SpO₂ by monitoring transmission at 660 nm and 940 nm requires a bit of theory. To start, recall the Beer-Lambert Law. .. math:: \begin{align} \frac{I}{I_0} = \mathrm{e}^{-\epsilon c d}, \end{align} where the left-hand-side is the ratio of the transmitted to incident light intensity, :math:`C` is the concentration of absorbant species, and :math:`d` is the path length. The extinction coefficient is dependent on the species and on the wavelength, as we can see in the spectra above. The contributions of multiple absorbant species multiply (the product of the extinction coefficients and concentrations add). So in the case of light passing through a tissue, we have .. math:: \begin{align} \frac{I}{I_0} = \exp\left[-\epsilon_\mathrm{tissue}C_\mathrm{tissue}d_\mathrm{tissue} - \left(\epsilon_\mathrm{Hb}C_\mathrm{Hb} + \epsilon_\mathrm{O_2Hb}C_\mathrm{O_2Hb}\right)d\right], \end{align} where we have used the subscript "tissue" to denote all absorbing species besides those in arterial blood. Here, :math:`d` is the path length through arterial blood. During a pulse, the path length through the arterial blood increases due to dilation of the arteries. Let :math:`d_v` be the path length through arterial blood at a "valley" of a pulse and :math:`d_p = d_v + \Delta d` be the path length through arterial blood at a peak of a pulse. We can then write .. math:: \begin{align} \frac{I_v}{I_0} &= \exp\left[-\epsilon_\mathrm{tissue}C_\mathrm{tissue}d_\mathrm{tissue} - \left(\epsilon_\mathrm{Hb}C_\mathrm{Hb} + \epsilon_\mathrm{O_2Hb}C_\mathrm{O_2Hb}\right)d_v\right], \\[1em] \frac{I_p}{I_0} &= \exp\left[-\epsilon_\mathrm{tissue}C_\mathrm{tissue}d_\mathrm{tissue} - \left(\epsilon_\mathrm{Hb}C_\mathrm{Hb} + \epsilon_\mathrm{O_2Hb}C_\mathrm{O_2Hb}\right)(d_v + \Delta d)\right], \end{align} where the v and p subscripts refer to valleys and peaks of the plethysmograph. Dividing these two expressions yields .. math:: \begin{align} \frac{I_p}{I_v} &= \exp\left[\left(\epsilon_\mathrm{Hb}C_\mathrm{Hb} + \epsilon_\mathrm{O_2Hb}C_\mathrm{O_2Hb}\right)\Delta d\right], \end{align} or, considering the logarithm, .. math:: \begin{align} \ln\left(\frac{I_p}{I_v}\right) &= \left(\epsilon_\mathrm{Hb}C_\mathrm{Hb} + \epsilon_\mathrm{O_2Hb}C_\mathrm{O_2Hb}\right)\Delta d. \end{align} In the above expression, assuming we know the extinction coefficients, we have three unknowns, the concentrations :math:`C_\mathrm{Hb}` and :math:`C_\mathrm{O_2Hb}` that are necessary to compute SpO₂ and :math:`\Delta d`. However, if we make the measurements at two different wavelengths, say :math:`\lambda_1` and :math:`\lambda_2`, we can eliminate :math:`\Delta d`. .. math:: \begin{align} \frac{\ln\left(\left.I_p(\lambda_1)\middle/ I_v(\lambda_1)\right.\right)}{\ln\left(\left.I_p(\lambda_2)\middle/ I_v(\lambda_2)\right.\right)} &= \frac{\epsilon^1_\mathrm{Hb}C_\mathrm{Hb} + \epsilon^1_\mathrm{O_2Hb}C_\mathrm{O_2Hb}} {\epsilon^2_\mathrm{Hb}C_\mathrm{Hb} + \epsilon^2_\mathrm{O_2Hb}C_\mathrm{O_2Hb}}, \end{align} where the superscripts 1 and 2 on the extinction coefficients refer to the wavelengths :math:`\lambda_1` and :math:`\lambda_2`. Multiplying the numerator and denominator by :math:`\left. 1 \middle/ (C_\mathrm{Hb} + C_\mathrm{O_2Hb})\right.` and using the relationship between the concentrations and SpO₂, this can be written as .. math:: \begin{align} \frac{\ln\left(\left.I_p(\lambda_1)\middle/ I_v(\lambda_1)\right.\right)}{\ln\left(\left.I_p(\lambda_2)\middle/ I_v(\lambda_2)\right.\right)} &= \frac{\epsilon^1_\mathrm{Hb}(1-\mathrm{SpO_2}) + \epsilon^1_\mathrm{O_2Hb}\mathrm{SpO_2}} {\epsilon^2_\mathrm{Hb}(1-\mathrm{SpO_2}) + \epsilon^2_\mathrm{O_2Hb}\mathrm{SpO_2}}, \end{align} The left-hand-side of the above equation is referred to as the **modulation ratio** and is denoted :math:`R`, .. math:: \begin{align} R \equiv \frac{\ln\left(\left.I_p(\lambda_1)\middle/ I_v(\lambda_1)\right.\right)}{\ln\left(\left.I_p(\lambda_2)\middle/ I_v(\lambda_2)\right.\right)}. \end{align} We can then rearrange to get SpO₂ in terms of :math:`R`. .. math:: \begin{align} \mathrm{SpO_2} = \frac{\epsilon^1_\mathrm{Hb} - \epsilon^2_\mathrm{Hb}R}{\epsilon^1_\mathrm{Hb} - \epsilon^1_\mathrm{O_2Hb} + \left(\epsilon^2_\mathrm{O_2Hb} - \epsilon^2_\mathrm{Hb}\right)R}. \end{align} This expression emphasizes the importance of choosing wavelengths such that the extinction coefficients for oxygenated and deoxygenated hemoglobin differ by as much as possible. For this reason, we choose :math:`\lambda_1 = 660` nm and :math:`\lambda_2 = 940` nm. You could look up the extinction coefficients off of the above spectra for these wavelengths, measure :math:`R` from your measured traces, and compute the oxygen saturation. The problem with this approach is that light is scattered in the tissue and the Beer-Lambert law breaks down. In practice, pulse oximeter manufacturers obtain calibration curves based on measurements of :math:`R` and independently measured oxygen saturation. The calibration curves are then used to convert :math:`R` to SpO₂. These calibration curves are obtained from an approximate expression for the modulation ratio. Defining :math:`I_v(\lambda_i)` as :math:`\mathrm{DC}_i` (the baseline signal due to all absorbing and scattering material apart from pulsatile arterial blood) and :math:`\mathrm{AC}_i = I_p(\lambda_i) - I_v(\lambda_i) = I_p(\lambda_i) - \mathrm{DC}_i` as the magnitude of the varying signal, we can write .. math:: \begin{align} \ln\left(\frac{I_p(\lambda_i)}{I_v(\lambda_i)}\right) = \ln\left(\frac{\mathrm{AC}_i + \mathrm{DC}_i}{\mathrm{DC}_i}\right) = \ln\left(1 + \left. \mathrm{AC}_i \middle/ \mathrm{DC}_i\right.\right) \approx \frac{\mathrm{AC}_i}{\mathrm{DC}_i}, \end{align} where in the last step, we have used the fact that :math:`\left. \mathrm{AC}_i \middle/ \mathrm{DC}_i\right. \ll 1` and performed a Taylor series expansion to first order. Thus, .. math:: \begin{align} R \approx \frac{\left. \mathrm{AC}_1 \middle/ \mathrm{DC}_1\right.}{\left. \mathrm{AC}_2 \middle/ \mathrm{DC}_2\right.}. \end{align} As an example of a calibration curve, `Tremper and Barker `_ gave a curve valid for :math:`0.4 \le R \le 3.3` as :math:`\mathrm{SpO_2} = aR^2 + bR + c`, with :math:`a = -3.3`, :math:`b = -21.1`, and :math:`c = 109.6`. Unfortunately, there is no guarantee this calibration will work with your device. (The `Tremper and Barker paper `_ is really worth reading for a more detailed background about pulse oximetry.) Diagnostics from pulse oximetry ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Pulse oximeters are used in many monitoring and diagnostic applications. Of immediate interest is the oxygen saturation, SpO₂. The SpO₂ for a health individual should be above 95%. People with lung disease or sleep apnea can have levels around 90%. Inter-pulse intervals are also of interest. Surprisingly, in a healthy individual, the intervals between successive heartbeats vary in a rather chaotic manner. It has been reported that patients with congestive heart failure (CHF) have decreased cardiac chaos as compared to healthy individuals (see, e.g., `Poon and Merrill, 1997 `_). A frequency spectrum (obtainable by FFT) will not sufficiently reveal irregular heartbeats and peak-identifications must be used. Specification ^^^^^^^^^^^^^ Your task is to construct a pulse oximeter using the modified KY-039 module in your kit. (See descriptions below about the modified KY-039 module.) Your pulse oximeter should have the following design characteristics. 1. It is operated from a computer with a dashboard. The dashboard should minimally show a pulse trace, a display of heart rate, and a display of the blood oxygen saturation. 2. You may also wish to include real-time displays of statistics of interpulse times. 3. Your dashboard should have controls to download acquired traces for further analysis. Documentation ~~~~~~~~~~~~~ The documentation for use of the pulse oximeter can be minimal. You may even which to have instructions for attaching the KY-039 module to the patient's finger and operation displayed on the dashboard. It is, however, important to include all design considerations, schematics, etc., as already required in the write-up. Suggestions ~~~~~~~~~~~ A modified KY-039 module is used to illuminate tissue and detect transmitted light. As purchased, the KY-039 module has an IR LED (940 nm). Current flows through a 330 Ω resistor, through the LED, and then to ground. We have modified the KY-039 to also include a red LED (660 nm). The red LED and the IR LED both share the same ground on the board, but their anodes are both exposed and may be connected to Arduino or any other circuitry for control. Importantly, because they no longer are connected to the resistor in the KY-039, **you need to include a resistor before the anode of the LEDs**. This is very important; you have one KY-039 in your kit, and you do not want to destroy the LEDs. The KY-039 also has a photodetector that we have not modified. In addition to connecting the LEDs to a controlled voltage source, you need to connect the photodetector according to the pinout below. Vcc should not exceed 5 V. The pinout for the KY-039 module is shown below. .. image:: KY-039_pinout.png :width: 200 :alt: Pinout of KY-039 module The anodes of the LED are exposed, and their cathodes are connected to GND of the KY-039 module. Vout is the signal from the photodetector. There is a single photodetector on the KY-039 module, so you cannot simultaneously acquire a signal for the red and IR wavelengths. You therefore need to do the following. 1. Switch on the red LED. 2. Acquire a measurement. 3. Switch off the red LED. 4. Switch on the IR LED. 5. Acquire a measurement. 6. Switch off the IR LED. 7. Repeat. You should also think about the following design considerations. 1. What sampling rate should you use to be able to resolve peaks and valleys in the cardiac cycle? 2. What kind of filtering is necessary? 3. Do you need to amplify the signals? 4. Do you need sample-and-hold circuits?