.. DO NOT EDIT. .. THIS FILE WAS AUTOMATICALLY GENERATED BY SPHINX-GALLERY. .. TO MAKE CHANGES, EDIT THE SOURCE PYTHON FILE: .. "generated\examples\kidney\plot_gfr_validation.py" .. LINE NUMBERS ARE GIVEN BELOW. .. only:: html .. note:: :class: sphx-glr-download-link-note :ref:`Go to the end ` to download the full example code. .. rst-class:: sphx-glr-example-title .. _sphx_glr_generated_examples_kidney_plot_gfr_validation.py: ======================================== Single-kidney glomerular filtration rate ======================================== This examples illustrates the use of `~dcmri.Kidney` for measurement of single kidney glomerular filtration rate (SK-GFR). The script aims to replicate a validation study comparing MRI-derived measurement of SK-GFR against reference measurement performed with radio-isotopes Basak et al 2018). The study used 124 historical datasets collected in between the years 2000 and 2010 at 1 Tesla and 3 Tesla MRI. The study concluded that while the MRI-derived values were unbiased, the precision was low and significant improvements in data quality would be needed before this technique can be applied in clinical practice. The study was funded by `Kidney Research UK `_. **Reference** Basak S, Buckley DL, Chrysochou C, Banerji A, Vassallo D, Odudu A, Kalra PA, Sourbron SP. Analytical validation of single-kidney glomerular filtration rate and split renal function as measured with magnetic resonance renography. Magn Reson Imaging. 2019 Jun;59:53-60. doi: 10.1016/j.mri.2019.03.005. `[URL] `_. .. GENERATED FROM PYTHON SOURCE LINES 27-29 Setup ----- .. GENERATED FROM PYTHON SOURCE LINES 29-40 .. code-block:: Python # Import packages and fetch data import pandas as pd import numpy as np import matplotlib.pyplot as plt import dcmri as dc # Fetch the data data = dc.fetch('KRUK') .. GENERATED FROM PYTHON SOURCE LINES 41-45 Model definition ---------------- In order to avoid some repetition in this script, we define a function that returns a trained model for a single dataset: .. GENERATED FROM PYTHON SOURCE LINES 45-83 .. code-block:: Python def kidney_model(scan, kidney): # Get B0 and precontrast T1 B0 = scan['field_strength'] T1 = scan[kidney+' T1'] T1 = dc.T1(B0, 'kidney') if T1 is None else T1 # Set kidney model parameters model = dc.Kidney( aif = scan['aorta'], t = scan['time'], vol = scan[kidney+' vol'], R10 = 1/T1, R10a = 1/dc.T1(B0, 'blood'), sequence = 'SS', TR = scan['TR'], FA = scan['FA'], field_strength = B0, agent = scan['agent'], n0 = scan['n0'], ) # Customize free parameter ranges model.set_free( pop = 'Ta', Fp = [0, 0.05], FF = [0, 0.3], Tt = [30, np.inf], ) # Train the kidney model on the data xdata = scan['time'] ydata = scan[kidney] model.train(xdata, ydata) return xdata, ydata, model .. GENERATED FROM PYTHON SOURCE LINES 84-88 Check model fit --------------- Before running the full analysis on all cases, lets illustrate the results by fitting the left kidney of the first subject: .. GENERATED FROM PYTHON SOURCE LINES 88-91 .. code-block:: Python time, signal, model = kidney_model(data[0], 'LK') .. GENERATED FROM PYTHON SOURCE LINES 92-93 Plot the results to check that the model has fitted the data: .. GENERATED FROM PYTHON SOURCE LINES 93-96 .. code-block:: Python model.plot(time, signal) .. image-sg:: /generated/examples/kidney/images/sphx_glr_plot_gfr_validation_001.png :alt: Prediction of the MRI signals., Reconstruction of concentrations. :srcset: /generated/examples/kidney/images/sphx_glr_plot_gfr_validation_001.png :class: sphx-glr-single-img .. GENERATED FROM PYTHON SOURCE LINES 97-100 Print the measured model parameters and any derived parameters and check that standard deviations of measured parameters are small relative to the value, indicating that the parameters are measured reliably: .. GENERATED FROM PYTHON SOURCE LINES 100-103 .. code-block:: Python model.print_params(round_to=3) .. rst-class:: sphx-glr-script-out .. code-block:: none -------------------------------- Free parameters with their stdev -------------------------------- Plasma flow (Fp): 0.035 (0.003) mL/sec/cm3 Plasma volume (vp): 0.278 (0.019) mL/cm3 Filtration fraction (FF): 0.103 (0.017) Tubular mean transit time (Tt): 304.622 (149.971) sec ---------------------------- Fixed and derived parameters ---------------------------- Blood flow (Fb): 0.063 mL/sec/cm3 Tubular flow (Ft): 0.004 mL/sec/cm3 Plasma mean transit time (Tp): 7.239 sec Extracellular volume (ve): 0.252 mL/cm3 Extraction fraction (E): 0.094 Single-kidney glomerular filtration rate (SK-GFR): 0.431 mL/sec Single-kidney renal blood flow (SK-RBF): 7.58 mL/sec .. GENERATED FROM PYTHON SOURCE LINES 104-106 The measured SK-GFR for this kidney (0.43) is somewhat higher than the radio-isotope reference value (0.28): .. GENERATED FROM PYTHON SOURCE LINES 106-113 .. code-block:: Python print('-----------------------------') print('Comparison to reference value') print('-----------------------------') print('Radio-isotope SK-GFR: ', data[0]['LK iso-SK-GFR']) .. rst-class:: sphx-glr-script-out .. code-block:: none ----------------------------- Comparison to reference value ----------------------------- Radio-isotope SK-GFR: 0.2779460500963383 .. GENERATED FROM PYTHON SOURCE LINES 114-118 Fit all data ------------ Now that we have illustrated an individual result in some detail, we proceed to determine SK-GFR for all datasets: .. GENERATED FROM PYTHON SOURCE LINES 118-154 .. code-block:: Python results = [] for scan in data: for kidney in ['LK', 'RK']: if kidney not in scan: continue xdata, ydata, model = kidney_model(scan, kidney) # Export parameters and add reference value pars = model.export_params() pars['iso-SK-GFR'] = [ 'Isotope single-kidney GFR', scan[kidney + ' iso-SK-GFR'], 'mL/sec', 0, ] # Convert to a dataframe pars = pd.DataFrame.from_dict( pars, orient = 'index', columns = ["name", "value", "unit", "stdev"]) pars['subject'] = scan['subject'] pars['kidney'] = kidney pars['visit'] = scan['visit'] pars['parameter'] = pars.index pars['B0'] = scan['field_strength'] # Append to results results.append(pars) # Combine all results into a single dataframe results = pd.concat(results).reset_index(drop=True) .. GENERATED FROM PYTHON SOURCE LINES 155-156 Plot MRI values and reference values .. GENERATED FROM PYTHON SOURCE LINES 156-176 .. code-block:: Python # Validation v1T = pd.pivot_table(results[results.B0==1], values='value', columns='parameter', index=['subject','kidney','visit']) v3T = pd.pivot_table(results[results.B0==3], values='value', columns='parameter', index=['subject','kidney','visit']) iso1T, iso3T = 60*v1T['iso-SK-GFR'].values, 60*v3T['iso-SK-GFR'].values mri1T, mri3T = 60*v1T['SK-GFR'].values, 60*v3T['SK-GFR'].values plt.title('Single-kidney GFR (SK-GFR)') plt.plot(iso1T, mri1T, 'bo', linestyle='None', markersize=4, label='1T') plt.plot(iso3T, mri3T, 'ro', linestyle='None', markersize=4, label='3T') plt.plot(iso3T, iso3T, linestyle='-', color='black') plt.ylabel("MRI SK-GFR (mL/min)") plt.xlabel("Isotope SK-GFR (mL/min)") #plt.xlim(0,100) #plt.ylim(0,200) plt.legend() plt.show() .. image-sg:: /generated/examples/kidney/images/sphx_glr_plot_gfr_validation_002.png :alt: Single-kidney GFR (SK-GFR) :srcset: /generated/examples/kidney/images/sphx_glr_plot_gfr_validation_002.png :class: sphx-glr-single-img .. GENERATED FROM PYTHON SOURCE LINES 177-178 Compute bias and accuracy .. GENERATED FROM PYTHON SOURCE LINES 178-195 .. code-block:: Python v = pd.pivot_table(results, values='value', columns='parameter', index=['subject','kidney','visit']) iso = 60*v['iso-SK-GFR'].values mri = 60*v['SK-GFR'].values diff = mri-iso bias = np.mean(diff) err = 1.96*np.std(diff) bias_err = 1.96*np.std(diff)/np.sqrt(np.size(diff)) print('-----------------') print('Single-kidney GFR') print('-----------------') print('95% CI on the bias (ml/min): ', bias-bias_err, bias+bias_err) # paper 0.56 print('95% CI on individual error (ml/min): ', bias-err, bias+err) # paper [-28, 29] .. rst-class:: sphx-glr-script-out .. code-block:: none ----------------- Single-kidney GFR ----------------- 95% CI on the bias (ml/min): 7.391160008329153 13.99521953118509 95% CI on individual error (ml/min): -39.166366228478346 60.55274576799258 .. GENERATED FROM PYTHON SOURCE LINES 196-200 As the results show, these data do not replicate the results from the original study exactly.. [ ...more results coming soon... ] .. GENERATED FROM PYTHON SOURCE LINES 200-204 .. code-block:: Python # Choose the last image as a thumbnail for the gallery # sphinx_gallery_thumbnail_number = -1 .. rst-class:: sphx-glr-timing **Total running time of the script:** (0 minutes 20.074 seconds) .. _sphx_glr_download_generated_examples_kidney_plot_gfr_validation.py: .. only:: html .. container:: sphx-glr-footer sphx-glr-footer-example .. container:: sphx-glr-download sphx-glr-download-jupyter :download:`Download Jupyter notebook: plot_gfr_validation.ipynb ` .. container:: sphx-glr-download sphx-glr-download-python :download:`Download Python source code: plot_gfr_validation.py ` .. container:: sphx-glr-download sphx-glr-download-zip :download:`Download zipped: plot_gfr_validation.zip ` .. only:: html .. rst-class:: sphx-glr-signature `Gallery generated by Sphinx-Gallery `_