This page was generated from docs/Examples/CO2_in_Melt_Inclusion_Vapour_Bubbles/Example8a_PropagatingCO2Uncertainties.ipynb. Interactive online version: Binder badge.

Python Notebook Download

Progapagating uncertainty in melt inclusion vapour bubble reconstructions

  • This notebook shows how to use Monte Carlo methods to propagate uncertainty in bubble density, bubble volume and melt density to calculate the uncertainty in the equivalent amount of CO2 in the bubble - e.g. how many ppm you add back into the glass

  • In this instance, we get uncertainty in bubble density from repeated Raman measurements, uncertainty in melt density from the code DensityX, and estimate the uncertainty in bubble volume from optical measurements as ~30-50%.

[1]:
## Install DiadFit if you havent already
#!pip install DiadFit --upgrade
[2]:
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
# The code to do the MC is in DiadFit, make sure you cite!
import DiadFit as pf
pf.__version__
[2]:
'1.0.0'

Scenario 1 - You have measured x and y using an optical microscope, but you didnt measure Z, so you are assuming it is the average of x and y.

[3]:
df_noZ=pd.read_excel('Melt_inclusions_all_dimensions.xlsx', sheet_name='noZ')
df_noZ.head()
[3]:
SampleID Melt_x_um Melt_y_um VB_x_um VB_y_um CO2_dens_gcm3 err_CO2_dens_gcm3 melt_dens_kgm3 err_melt_dens_kgm3 Unnamed: 9 constant Vol_melt Vol_VB Vol% CO2_in_melt
0 Test_melt_1 50 33 10 15.0 0.030 0.010 2601 130.05 NaN 4.18879 35853.426159 981.747704 2.738226 3.158276
1 Test_melt_2 40 42 5 5.0 0.040 0.020 2603 130.15 NaN 4.18879 36065.483663 65.449847 0.181475 0.278871
2 Test_melt_3 30 50 6 5.0 0.050 0.010 2700 135.00 NaN 4.18879 31415.926536 86.393798 0.275000 0.509259
3 Test_melt_4 20 30 3 2.5 0.036 0.020 2606 130.30 NaN 4.18879 7853.981634 10.799225 0.137500 0.189946
4 Test_melt_5 100 21 11 12.0 0.042 0.015 2704 135.20 NaN 4.18879 66523.224440 794.822941 1.194805 1.855836
  • We are assuming the error on the measurements is 1um, but for Z, lets assume the error is half the difference between x and y.

[9]:
vol_noZ_av, vol_noZ_all, fig=pf.propagate_CO2_in_bubble(sample_ID=df_noZ['SampleID'],  N_dup=1000, vol_perc_bub=None,
CO2_bub_dens_gcm3=df_noZ['CO2_dens_gcm3'], melt_dens_kgm3=df_noZ['melt_dens_kgm3'],
MI_x=df_noZ['Melt_x_um'], MI_y=df_noZ['Melt_y_um'],VB_x=df_noZ['VB_x_um'], VB_y=df_noZ['VB_y_um'],
error_MI_x=1, error_MI_y=1,error_MI_z=0.5*np.abs(df_noZ['Melt_y_um']-df_noZ['Melt_x_um']),error_VB_x=1, error_VB_y=1,
 error_VB_z=np.abs(df_noZ['VB_y_um']-df_noZ['VB_x_um']),
error_type_dimension='Abs', error_dist_dimension='normal',
error_CO2_bub_dens_gcm3=df_noZ['err_CO2_dens_gcm3'], error_type_CO2_bub_dens_gcm3='Abs', error_dist_CO2_bub_dens_gcm3='normal',
error_melt_dens_kgm3=df_noZ['err_melt_dens_kgm3'], error_type_melt_dens_kgm3='Abs', error_dist_melt_dens_kgm3='normal', neg_values=True)

vol_noZ_av.head()
working on sample number 0
[9]:
Filename CO2_eq_in_melt_noMC mean_MC_CO2_equiv_melt_ppm med_MC_CO2_equiv_melt_ppm std_MC_IQR_CO2_equiv_melt_ppm 16th_quantile_melt_ppm 84th_quantile_melt_ppm
0 Test_melt_1 315.827639 342.152023 305.403692 181.101886 151.279370 513.483142
1 Test_melt_2 27.887058 28.974437 26.647298 16.954758 12.480985 46.390500
2 Test_melt_3 50.925926 31.805252 48.978685 23.642208 28.854819 76.139236
3 Test_melt_4 18.994628 19.983244 16.084909 15.292613 5.066951 35.652177
4 Test_melt_5 185.583647 162.166698 163.250032 149.272392 72.941783 371.486566
../../_images/Examples_CO2_in_Melt_Inclusion_Vapour_Bubbles_Example8a_PropagatingCO2Uncertainties_6_2.png

Example 1 - Run for a single samle

  • This function lets you investigate for 1 MI how different values propagate to uncertainty in calculated CO2 contents

  • Here, we show a scenario where you dont use the x-y-z dimensions, you just input the bubble vol% and the error on it (as reported in many supporting datasets)

[10]:
#  Which of your samples do you want to look at? here we look at the first one
sample_i=0
## How many duplicates do you want in the simulation?
N_dup=1000

######################### VAPOUR BUBBLE VOLUMES ###########################
# What is the measured vol% of your bubble
vol_perc_bub=5
# What is your estimated error on this value? Is this an absolute error, a percentage error - do you think the error is distributed normally or uniformly etc
error_vol_perc_bub=40
error_type_vol_perc_bub='Perc'
error_dist_vol_perc_bub='normal'


######################### VAPOUR BUBBLE DENSITIES ###########################
# What is your measured bubble density in g/cm3 by Raman or microthermometry?
CO2_bub_dens_gcm3=0.02
# What is the error on that value? Here we use the absolute error outputted by DiadFit. This is an absolute error and it should follow a normal distribution as its a 1 sigma value
error_CO2_bub_dens_gcm3=0.01
error_type_CO2_bub_dens_gcm3='Abs'
error_dist_CO2_bub_dens_gcm3='normal'

######################### SILICATE MELT DENSITIES ###########################
# Melt density (e.g. from DensityX)
melt_dens_kgm3=2700
# Estimated error on that - here we use 200 kg/m3, its absolute, and distributed normally
error_melt_dens_kgm3=80
error_type_melt_dens_kgm3='Abs'
error_dist_melt_dens_kgm3='normal'

## Now lets calculate the distribution
test_dist=pf.propagate_CO2_in_bubble_ind(sample_i=sample_i,  N_dup=N_dup,
vol_perc_bub=vol_perc_bub,
error_vol_perc_bub=error_vol_perc_bub, error_type_vol_perc_bub=error_type_vol_perc_bub,
error_dist_vol_perc_bub=error_dist_vol_perc_bub,
CO2_bub_dens_gcm3=CO2_bub_dens_gcm3, error_CO2_bub_dens_gcm3=error_CO2_bub_dens_gcm3,
error_type_CO2_bub_dens_gcm3=error_type_CO2_bub_dens_gcm3,
error_dist_CO2_bub_dens_gcm3=error_dist_CO2_bub_dens_gcm3,
melt_dens_kgm3=melt_dens_kgm3, error_melt_dens_kgm3=error_melt_dens_kgm3,
error_type_melt_dens_kgm3=error_type_melt_dens_kgm3,
error_dist_melt_dens_kgm3=error_dist_melt_dens_kgm3, len_loop=1, neg_values=True)
using error on the bubble volume percent, not the entered dimensions, as error_vol_perc_bub was not None
[11]:
# Now lets look at the simulation for this one sapmle. The column 'CO2_eq_melt_ppm_noMC' is the same answer as above. The column CO2_eq_melt_ppm_MC gives 1 MonteCarlo result.
test_dist
[11]:
CO2_eq_melt_ppm_MC CO2_eq_melt_ppm_noMC vol_perc_bub_with_noise CO2_bub_dens_gcm3_with_noise melt_dens_kgm3_with_noise vol_perc_bub CO2_bub_dens_gcm3 error_type_vol_perc_bub error_dist_Vol error_CO2_bub_dens_gcm3 error_type_CO2_bub_dens_gcm3 error_dist_CO2_bub_dens_gcm3
0 184.027060 370.37037 4.831051 0.010431 2738.272230 5 0.02 Perc normal 0.01 Abs normal
1 331.485215 370.37037 7.000886 0.012853 2714.556235 5 0.02 Perc normal 0.01 Abs normal
2 558.692180 370.37037 3.619383 0.039636 2567.751507 5 0.02 Perc normal 0.01 Abs normal
3 530.544696 370.37037 4.255368 0.034486 2766.049050 5 0.02 Perc normal 0.01 Abs normal
4 909.139425 370.37037 8.238086 0.028807 2610.302722 5 0.02 Perc normal 0.01 Abs normal
... ... ... ... ... ... ... ... ... ... ... ... ...
995 166.182144 370.37037 2.466667 0.018581 2757.999512 5 0.02 Perc normal 0.01 Abs normal
996 263.174731 370.37037 3.855987 0.018293 2680.219760 5 0.02 Perc normal 0.01 Abs normal
997 344.687962 370.37037 8.222711 0.011141 2657.776998 5 0.02 Perc normal 0.01 Abs normal
998 158.276474 370.37037 2.400432 0.017365 2633.646470 5 0.02 Perc normal 0.01 Abs normal
999 853.307478 370.37037 5.146933 0.044449 2681.073321 5 0.02 Perc normal 0.01 Abs normal

1000 rows × 12 columns

[12]:
# Lets do the basic math just to persuade ourselves this is working
vol_perc_bub=5
melt_dens_gcm3=2.7
bub_dens_gcm3=0.02
CO2_eq_bubble=10**4*(bub_dens_gcm3*vol_perc_bub)/melt_dens_gcm3
CO2_eq_bubble
[12]:
370.3703703703703
[13]:
## Lets plot some of these outputs to check they look how we expect
fig, ((ax1, ax2), (ax3, ax4)) = plt.subplots(2, 2, figsize=(10,8))
ax1.hist(test_dist['vol_perc_bub_with_noise'], bins=50);
ax1.set_xlabel('MC bubble volume (vol%)')
ax1.set_ylabel('# of simulations')

ax2.hist(test_dist['melt_dens_kgm3_with_noise'], bins=50);
ax2.set_xlabel('MC Melt Density (kg/cm3)')

ax3.hist(test_dist['CO2_bub_dens_gcm3_with_noise'], bins=50);
ax3.set_xlabel('MC Bubble Density (g/cm3)')
ax3.set_ylabel('# of simulations')

ax4.hist(test_dist['CO2_eq_melt_ppm_MC'], bins=50, color='red');
ax4.set_xlabel('CO2 equivalent in the melt held in the bubble (ppm)')
# Plotting preferred value - no Monte Carlo (as no negs can skew)
ax4.plot([test_dist['CO2_eq_melt_ppm_noMC'].iloc[0],
          test_dist['CO2_eq_melt_ppm_noMC'].iloc[0]], [0, N_dup/15], '-k', label='Preferred value');

# Plot standard deviation of simulation
ax4.plot([test_dist['CO2_eq_melt_ppm_noMC'].iloc[0]+np.std(test_dist['CO2_eq_melt_ppm_MC']),
          test_dist['CO2_eq_melt_ppm_noMC'].iloc[0]+np.std(test_dist['CO2_eq_melt_ppm_MC'])], [0, N_dup/15], ':k', label='Preferred+value+1s MC');
ax4.plot([test_dist['CO2_eq_melt_ppm_noMC'].iloc[0]-np.std(test_dist['CO2_eq_melt_ppm_MC']),
          test_dist['CO2_eq_melt_ppm_noMC'].iloc[0]-np.std(test_dist['CO2_eq_melt_ppm_MC'])], [0, N_dup/15], ':k', label='Preferred-value+1s MC');
ax4.legend()

[13]:
<matplotlib.legend.Legend at 0x1404dfdbad0>
../../_images/Examples_CO2_in_Melt_Inclusion_Vapour_Bubbles_Example8a_PropagatingCO2Uncertainties_11_1.png

Now lets load in some real data

  • This data has the values for errors as columns for each melt inclusion (a row)

  • The function outputs 2 things, av is just the mean, and std dev of the simulations. test_dist is all the simulations so you can plot them up!

[14]:
# Download here - https://github.com/PennyWieser/DiadFit/blob/main/docs/Examples/CO2_in_Melt_Inclusion_Vapour_Bubbles/Wieser_2021_Kilauea.xlsx
df=pd.read_excel('Wieser_2021_Kilauea.xlsx', sheet_name='Sheet2')
df.head()
[14]:
sample PEC_amount Na2O_PEC Al2O3_PEC P2O5_PEC CaO_PEC K2O_PEC TiO2_PEC SiO2_PEC MgO_PEC FeOt_PEC MnO_PEC H2O_Liq_meas CO2_Liq_meas Melt_dens Melt_dens_err Vol_% CO2_dens_gcm3 CO2_dens_gcm3_std_Dev
0 LL8_613b 16.60 2.469 12.900 0.229 10.702 0.349 2.394 49.770 9.328 11.336 0.142 0.240274 28.979265 2.728376 0.081851 2.723415 0.021977 0.000662
1 LL8_615 30.59 2.131 10.928 0.229 9.435 0.334 1.815 49.676 13.612 11.336 0.151 0.238325 37.495154 2.705747 0.081172 4.254140 0.022912 0.006003
2 LL8_617_a 30.02 2.092 11.323 0.291 9.757 0.324 2.009 49.028 13.349 11.338 0.135 0.235590 41.302324 2.716938 0.081508 3.996225 0.029050 0.000521
3 LL8_623_b 26.68 2.103 11.895 0.299 10.022 0.449 2.448 48.418 12.514 11.331 0.177 0.216237 23.837194 2.728426 0.081853 5.110120 0.052225 0.009579
4 LL8_626 27.81 2.181 11.612 0.209 9.789 0.330 2.027 49.215 12.783 11.331 0.172 0.228748 5.660589 2.714561 0.081437 5.645210 0.029996 0.008963
[15]:
av, test_dist, fig=pf.propagate_CO2_in_bubble(sample_ID=df['sample'],
N_dup=1000, vol_perc_bub=df['Vol_%'],
CO2_bub_dens_gcm3=df['CO2_dens_gcm3'], melt_dens_kgm3=df['Melt_dens']*1000,
error_vol_perc_bub=50, error_type_vol_perc_bub='Perc', error_dist_vol_perc_bub='normal',
error_CO2_bub_dens_gcm3=df['CO2_dens_gcm3_std_Dev'],
error_type_CO2_bub_dens_gcm3='Abs', error_dist_CO2_bub_dens_gcm3='normal',
error_melt_dens_kgm3=df['Melt_dens_err']*1000, error_type_melt_dens_kgm3='Abs', error_dist_melt_dens_kgm3='normal',
 neg_values=True)
av.head()

working on sample number 0
didnt get inside else loop
using error on the bubble volume percent, not the entered dimensions, as error_vol_perc_bub was not None
didnt get inside else loop
using error on the bubble volume percent, not the entered dimensions, as error_vol_perc_bub was not None
didnt get inside else loop
using error on the bubble volume percent, not the entered dimensions, as error_vol_perc_bub was not None
didnt get inside else loop
using error on the bubble volume percent, not the entered dimensions, as error_vol_perc_bub was not None
didnt get inside else loop
using error on the bubble volume percent, not the entered dimensions, as error_vol_perc_bub was not None
didnt get inside else loop
using error on the bubble volume percent, not the entered dimensions, as error_vol_perc_bub was not None
didnt get inside else loop
using error on the bubble volume percent, not the entered dimensions, as error_vol_perc_bub was not None
didnt get inside else loop
using error on the bubble volume percent, not the entered dimensions, as error_vol_perc_bub was not None
didnt get inside else loop
using error on the bubble volume percent, not the entered dimensions, as error_vol_perc_bub was not None
didnt get inside else loop
using error on the bubble volume percent, not the entered dimensions, as error_vol_perc_bub was not None
didnt get inside else loop
using error on the bubble volume percent, not the entered dimensions, as error_vol_perc_bub was not None
didnt get inside else loop
using error on the bubble volume percent, not the entered dimensions, as error_vol_perc_bub was not None
didnt get inside else loop
using error on the bubble volume percent, not the entered dimensions, as error_vol_perc_bub was not None
didnt get inside else loop
using error on the bubble volume percent, not the entered dimensions, as error_vol_perc_bub was not None
didnt get inside else loop
using error on the bubble volume percent, not the entered dimensions, as error_vol_perc_bub was not None
didnt get inside else loop
using error on the bubble volume percent, not the entered dimensions, as error_vol_perc_bub was not None
didnt get inside else loop
using error on the bubble volume percent, not the entered dimensions, as error_vol_perc_bub was not None
didnt get inside else loop
using error on the bubble volume percent, not the entered dimensions, as error_vol_perc_bub was not None
didnt get inside else loop
using error on the bubble volume percent, not the entered dimensions, as error_vol_perc_bub was not None
didnt get inside else loop
using error on the bubble volume percent, not the entered dimensions, as error_vol_perc_bub was not None
working on sample number 20
didnt get inside else loop
using error on the bubble volume percent, not the entered dimensions, as error_vol_perc_bub was not None
didnt get inside else loop
using error on the bubble volume percent, not the entered dimensions, as error_vol_perc_bub was not None
didnt get inside else loop
using error on the bubble volume percent, not the entered dimensions, as error_vol_perc_bub was not None
didnt get inside else loop
using error on the bubble volume percent, not the entered dimensions, as error_vol_perc_bub was not None
didnt get inside else loop
using error on the bubble volume percent, not the entered dimensions, as error_vol_perc_bub was not None
didnt get inside else loop
using error on the bubble volume percent, not the entered dimensions, as error_vol_perc_bub was not None
didnt get inside else loop
using error on the bubble volume percent, not the entered dimensions, as error_vol_perc_bub was not None
didnt get inside else loop
using error on the bubble volume percent, not the entered dimensions, as error_vol_perc_bub was not None
didnt get inside else loop
using error on the bubble volume percent, not the entered dimensions, as error_vol_perc_bub was not None
didnt get inside else loop
using error on the bubble volume percent, not the entered dimensions, as error_vol_perc_bub was not None
didnt get inside else loop
using error on the bubble volume percent, not the entered dimensions, as error_vol_perc_bub was not None
didnt get inside else loop
using error on the bubble volume percent, not the entered dimensions, as error_vol_perc_bub was not None
didnt get inside else loop
using error on the bubble volume percent, not the entered dimensions, as error_vol_perc_bub was not None
didnt get inside else loop
using error on the bubble volume percent, not the entered dimensions, as error_vol_perc_bub was not None
didnt get inside else loop
using error on the bubble volume percent, not the entered dimensions, as error_vol_perc_bub was not None
didnt get inside else loop
using error on the bubble volume percent, not the entered dimensions, as error_vol_perc_bub was not None
didnt get inside else loop
using error on the bubble volume percent, not the entered dimensions, as error_vol_perc_bub was not None
didnt get inside else loop
using error on the bubble volume percent, not the entered dimensions, as error_vol_perc_bub was not None
didnt get inside else loop
using error on the bubble volume percent, not the entered dimensions, as error_vol_perc_bub was not None
didnt get inside else loop
using error on the bubble volume percent, not the entered dimensions, as error_vol_perc_bub was not None
working on sample number 40
didnt get inside else loop
using error on the bubble volume percent, not the entered dimensions, as error_vol_perc_bub was not None
didnt get inside else loop
using error on the bubble volume percent, not the entered dimensions, as error_vol_perc_bub was not None
didnt get inside else loop
using error on the bubble volume percent, not the entered dimensions, as error_vol_perc_bub was not None
didnt get inside else loop
using error on the bubble volume percent, not the entered dimensions, as error_vol_perc_bub was not None
didnt get inside else loop
using error on the bubble volume percent, not the entered dimensions, as error_vol_perc_bub was not None
didnt get inside else loop
using error on the bubble volume percent, not the entered dimensions, as error_vol_perc_bub was not None
didnt get inside else loop
using error on the bubble volume percent, not the entered dimensions, as error_vol_perc_bub was not None
didnt get inside else loop
using error on the bubble volume percent, not the entered dimensions, as error_vol_perc_bub was not None
didnt get inside else loop
using error on the bubble volume percent, not the entered dimensions, as error_vol_perc_bub was not None
didnt get inside else loop
using error on the bubble volume percent, not the entered dimensions, as error_vol_perc_bub was not None
didnt get inside else loop
using error on the bubble volume percent, not the entered dimensions, as error_vol_perc_bub was not None
didnt get inside else loop
using error on the bubble volume percent, not the entered dimensions, as error_vol_perc_bub was not None
didnt get inside else loop
using error on the bubble volume percent, not the entered dimensions, as error_vol_perc_bub was not None
didnt get inside else loop
using error on the bubble volume percent, not the entered dimensions, as error_vol_perc_bub was not None
didnt get inside else loop
using error on the bubble volume percent, not the entered dimensions, as error_vol_perc_bub was not None
didnt get inside else loop
using error on the bubble volume percent, not the entered dimensions, as error_vol_perc_bub was not None
[15]:
Filename CO2_eq_in_melt_noMC mean_MC_CO2_equiv_melt_ppm med_MC_CO2_equiv_melt_ppm std_MC_IQR_CO2_equiv_melt_ppm 16th_quantile_melt_ppm 84th_quantile_melt_ppm
0 LL8_613b 219.365581 217.215534 218.985842 114.200710 101.939183 330.340602
1 LL8_615 360.243929 358.298977 350.438083 195.562328 161.084693 552.209349
2 LL8_617_a 427.279031 427.858356 423.736977 217.283396 210.811546 645.378337
3 LL8_623_b 978.127362 980.211686 969.344386 529.055224 437.304821 1495.415269
4 LL8_626 623.806538 611.552947 553.109461 361.732326 256.610321 980.074974
../../_images/Examples_CO2_in_Melt_Inclusion_Vapour_Bubbles_Example8a_PropagatingCO2Uncertainties_14_2.png