"""
===============
thermobarometry
===============
Perform thermobarometric calculations.
"""
import warnings
import numpy as np
import pandas as pd
import sympy as sym
import inspect
[docs]def Mg_num(df):
"""
Calculate Mg#.
Parameters
----------
df : pandas dataframe
sample compositions in anhydrous mol%.
Returns
-------
Mg_num : float
The Mg#.
"""
Mg_num = df['MgO_primary_mol_dry'] / (df['MgO_primary_mol_dry'] +
df['FeO_primary_mol_dry'])
return Mg_num
[docs]def NaK_num(df):
"""
Calculate NaK#.
Must previously run compute_components_species(),
compute_components_cation(), compute_components_compound()
or compute components_per_ox().
Parameters
----------
df : pandas dataframe with sample compositions in anhydrous mole%
Returns
-------
NaK_num : float
The NaK#.
"""
NaK_num = (
(df['Na2O_primary_wt_dry'] + df['K2O_primary_wt_dry']) /
(df['Na2O_primary_wt_dry'] + df['K2O_primary_wt_dry'] +
df['CaO_primary_wt_dry'])
)
return NaK_num
[docs]def normalize_v2(df, list_parameters, input_suffix, output_suffix, end_sum):
"""
Normalise sample compositions so they sum to a given value.
Concentrations in list_parameters are normalised so that they sum to
value given by end_sum. New values added to df with list_parameter
name appended by output_suffix.
Parameters
----------
df : pandas dataframe
Should contain only one row. To use with a multi-row dataframe use
df.apply().
list_parameters : list
Dataframe columns to be normalised.
input_suffix : str
Original suffix for columns to use.
output_suffix : str
Suffix to be added to create new column name.
end_sum : float
Value that columns should total after normalisation.
Returns
-------
df : pandas datframe
The updated dataframe containing normalised values.
"""
SUM = 0.
for i in range(0, len(list_parameters), 1):
parameter = list_parameters[i]
SUM = df[parameter + input_suffix] + SUM
for i in range(0, len(list_parameters), 1):
parameter = list_parameters[i]
df[parameter + output_suffix] = end_sum * df[parameter + input_suffix] / SUM
return df
[docs]def compute_DMg(df):
"""
Calculate DMg.
Follows method outlined in Beattie, (1993), Contrib. Min. and Pet.
Must previously run compute_components_cation().
Parameters
----------
df : pandas dataframe
Dataframe containing sample compositions in anhydrous mole%.
Returns
-------
DMg : float
Calculated DMg.
"""
Sum_A = (df["FeO_primary_mol_dry"]*0.279)
Sum_A += (df["MnO_primary_mol_dry"]*0.259)
Sum_A += (df["MgO_primary_mol_dry"]*1.)
Sum_A += (df["CaO_primary_mol_dry"]*0.0056)
Sum_A += (df["NiO_primary_mol_dry"]*3.346)
#####
Sum_B = (df["FeO_primary_mol_dry"]*0.031)
Sum_B -= (df["MnO_primary_mol_dry"]*0.049)
Sum_B += (df["CaO_primary_mol_dry"]*0.0135)
Sum_B += (df["NiO_primary_mol_dry"]*-3.665)
Sum_B += 0.0001*(df["TiO2_primary_mol_dry"] +
df["Al2O3_primary_mol_dry"] +
df["Cr2O3_primary_mol_dry"] +
df["Fe2O3_primary_mol_dry"] +
df["Na2O_primary_mol_dry"] +
df["K2O_primary_mol_dry"] +
df["P2O5_primary_mol_dry"])
#####
DMg = (2./3. - Sum_B) / Sum_A
return DMg
[docs]def compute_minerals(df):
"""
Calculate proportions of mineral components.
Using equations listed in Grove (1982, Contrib. Min. Pet., 80:160-182),
compute stable mineral assemblage.
Parameters
----------
df : pandas dataframe
Datframe containing sample compositions. Expects columns with suffix
'_primary_mol_dry'; should be mol% anhydrous compositions.
Should contain only one row. To use with a multi-row dataframe use
df.apply().
Returns
-------
MINS: numpy array
Predicted mineral proportions.
0: Olivine, 1: cpx, 2: plg, 3: qz, 4: opx, 5: spl, 6: ap.
"""
Sum = df["SiO2_primary_mol_dry"] + df["TiO2_primary_mol_dry"] + (df["Al2O3_primary_mol_dry"]*2.)
Sum += (df["Cr2O3_primary_mol_dry"]*2) + df["FeO_primary_mol_dry"]
Sum += df["MnO_primary_mol_dry"] + df["MgO_primary_mol_dry"]
Sum += df["CaO_primary_mol_dry"] + (df["Na2O_primary_mol_dry"]*2) + (df["K2O_primary_mol_dry"]*2)
Sum += df["NiO_primary_mol_dry"] + (df["P2O5_primary_mol_dry"]*2)
####
sio2 = 100. * df["SiO2_primary_mol_dry"] / Sum
tio2 = 100. * df["TiO2_primary_mol_dry"] / Sum
al2o3 = 200. * df["Al2O3_primary_mol_dry"] / Sum
cr2o3 = 200. * df["Cr2O3_primary_mol_dry"] / Sum
feo = 100. * df["FeO_primary_mol_dry"] / Sum
mgo = 100. * df["MgO_primary_mol_dry"] / Sum
cao = 100. * df["CaO_primary_mol_dry"] / Sum
na2o = 200. * df["Na2O_primary_mol_dry"] / Sum
k2o = 200. * df["K2O_primary_mol_dry"] / Sum
p2o5 = 200. * df["P2O5_primary_mol_dry"] / Sum
####
Total = sio2 - cao - 2*(k2o+na2o) + cr2o3 + tio2 + (2*p2o5)
####
ol = (0.5*(feo+mgo+0.5*(al2o3-k2o-na2o)-cao-tio2-cr2o3+5/3*p2o5))/Total*2
####
qz = (sio2-0.5*(feo+mgo)-1.5*cao-0.25*al2o3-2.75*(k2o+na2o)+0.5*cr2o3+0.5*tio2+2.5*p2o5)/Total
####
cpx = (cao-0.5*al2o3+0.5*(k2o+na2o)-5/3*p2o5)/Total*3
####
plg = (0.5*(al2o3+na2o-k2o))/Total*4
####
opx = k2o/Total*4
####
spl = (cr2o3+tio2)/Total*1.5
####
ap = p2o5/3/Total*6
####
Min_Tot = ol + qz + plg + cpx + opx + spl + ap
####
MINS = [ol/Min_Tot, cpx/Min_Tot, plg/Min_Tot, qz/Min_Tot, opx/Min_Tot, spl/Min_Tot, ap/Min_Tot]
return MINS
[docs]def compute_parameter_BK21(df, OL, P, regression_params):
"""
Calculate parameter values using equation
of Brown Krein et al., (2021)
Parameters
----------
df : pandas dataframe
sample compositions in anhydrous wt% need suffix '_primary_wt_dry'
sample compositions in anhydrous mol% need suffix '_primary_mol_dry'.
Should contain only one row. To use with a multi-row dataframe use
df.apply().
OL : flota
Olivine concentration.
P: float
Pressure in GPa.
regression_params: array
Array containing eight calibrated parameter values.
Returns
-------
result: float
either T or predicted mineral percentages.
"""
result = regression_params[0]
result += regression_params[1] * OL
result += regression_params[2] * P
result += regression_params[3] * Mg_num(df)
result += regression_params[4] * NaK_num(df)
result += regression_params[5] * df['TiO2_primary_wt_dry']
result += regression_params[6] * df['K2O_primary_wt_dry']
result += regression_params[7] * (df['CaO_primary_wt_dry']/df['Al2O3_primary_wt_dry'])
return result
[docs]def compute_parameter_TGK12(df, MINS, P, regression_params):
"""
Calculate parameter values using equation
of Till et al., (2012)
Parameters
----------
df : pandas dataframe
sample compositions in anhydrous wt% need suffix '_primary_wt_dry'
sample compositions in anhydrous mol% need suffix '_primary_mol_dry'.
Should contain only one row. To use with a multi-row dataframe use
df.apply().
MINS : array
Concentrations of each mineral.
P: float
Pressure in GPa.
regression_params: array
one row array of 8 calibrated prameter values.
Returns
-------
result: float
either T or predicted mineral percentages
"""
result = regression_params[0]
result += regression_params[1] * (MINS[0]/(MINS[0]+MINS[1]+MINS[2]+MINS[3]))
result += regression_params[2] * P
result += regression_params[3] * (1. - Mg_num(df))
result += regression_params[4] * NaK_num(df)
result += regression_params[5] * df['TiO2_primary_wt_dry']
result += regression_params[6] * df['K2O_primary_wt_dry']
return result
[docs]def compute_components_species(df):
"""
Calculate mole species proportions.
Use equations listed in Appendix A of Lee et al (2009, G-cubed) to compute
proportions of each mole species.
Parameters
----------
df : pandas dataframe
Dataframe containing sample compositions in wt%.
Should contain only one row. To use with a multi-row dataframe use
df.apply().
Returns
-------
df : pandas dataframe
Original dataframe with additional columns:
- anhydrous wt% with suffix '_primary_wt_dry'
- oxide mol% with suffix '_primary_mol'
- species proportions in mol%, e.g., 'Si4O8'
- anhydrous species proportions in mol%, e.g., 'Si4O8_dry'.
"""
MAJOR_OXIDES = ['SiO2','Al2O3','FeO','Fe2O3','MgO','CaO','Na2O','K2O',
'TiO2','MnO','Cr2O3', 'P2O5', 'H2O']
OXIDES_DRY = ['SiO2','Al2O3','FeO','Fe2O3','MgO','CaO','Na2O','K2O',
'TiO2','MnO','Cr2O3', 'P2O5']
OXIDE_WEIGHT = [60.08,101.96,71.84,159.69,40.3,56.08,61.98,
94.2,79.86,70.94,151.99,141.942524,18.014680000000002]
SPECIES = ['Si4O8','Al16/3O8','Fe4Si2O8','Fe16/3O8','Mg4Si2O8',
'Ca4Si2O8','Na2Al2Si2O8','K2Al2Si2O8','Ti4O8','Mn4Si2O8','Cr16/3O8',
'P16/5O8']
SPECIES_DRY = ['Si4O8','Al16/3O8','Fe4Si2O8','Fe16/3O8','Mg4Si2O8',
'Ca4Si2O8','Na2Al2Si2O8','K2Al2Si2O8','Ti4O8','Mn4Si2O8','Cr16/3O8',
'P16/5O8']
normalize_v2(df, OXIDES_DRY, '_primary_wt', '_primary_wt_dry', 100.)
for i in range(0, len(MAJOR_OXIDES), 1):
OXIDE = MAJOR_OXIDES[i]
df[OXIDE + '_primary_mol'] = df[OXIDE + '_primary_wt'] / OXIDE_WEIGHT[i]
normalize_v2(df, MAJOR_OXIDES, '_primary_mol', '_primary_mol', 100.)
df['Si4O8'] = (df['SiO2_primary_mol'] - 0.5*(df['FeO_primary_mol']
+df['MgO_primary_mol']+df['CaO_primary_mol']+df['MnO_primary_mol'])
- df['Na2O_primary_mol'] - df['K2O_primary_mol']) * 0.25
df['Al16/3O8'] = (df['Al2O3_primary_mol'] - df['Na2O_primary_mol']) * (3./8.)
df['Fe4Si2O8'] = df['FeO_primary_mol'] * 0.25
df['Fe16/3O8'] = df['Fe2O3_primary_mol'] * (3./8.)
df['Mg4Si2O8'] = df['MgO_primary_mol'] * 0.25
df['Ca4Si2O8'] = df['CaO_primary_mol'] * 0.25
df['Na2Al2Si2O8'] = df['Na2O_primary_mol']
df['K2Al2Si2O8'] = df['K2O_primary_mol']
df['Ti4O8'] = df['TiO2_primary_mol'] * 0.25
df['Mn4Si2O8'] = df['MnO_primary_mol'] * 0.25
df['Cr16/3O8'] = df['Cr2O3_primary_mol'] * (3./8.)
df['P16/5O8'] = df['P2O5_primary_mol'] * 0.625
df['H16O8'] = df['H2O_primary_mol'] * 0.125
normalize_v2(df, SPECIES, '', '', 100.)
normalize_v2(df, SPECIES_DRY, '', '_dry', 100.)
return
[docs]def compute_components_compound(df):
"""
Calculate proportions of oxides in mol% assuming all Fe is in FeO
and the sample is anhydrous.
Parameters
----------
df : pandas dataframe
The sample compositions in wt%.
Should contain only one row. To use with a multi-row dataframe use
df.apply().
Returns
-------
df : pandas dataframe
Original dataframe with additional columns:
- anhydrous wt% with suffix '_primary_wt_dry'
- anhydrous oxide mol% with suffix '_primary_mol_dry'.
"""
MAJOR_OXIDES = ['SiO2','Al2O3','FeO','MgO','CaO','Na2O','K2O','TiO2',
'MnO','Cr2O3','P2O5', 'NiO']
OXIDE_WEIGHT = [60.08,101.96,71.84,40.3,56.08,61.98,
94.2,79.86,70.94,151.99,141.945,74.71]
df['FeO_primary_wt'] = df['FeO_primary_wt'] + 0.8998 * df['Fe2O3_primary_wt']
df['Fe2O3_primary_wt'] = 0.
normalize_v2(df, MAJOR_OXIDES, '_primary_wt', '_primary_wt_dry', 100.)
for i in range(0, len(MAJOR_OXIDES), 1):
OXIDE = MAJOR_OXIDES[i]
df[OXIDE + '_primary_mol_dry'] = df[OXIDE + '_primary_wt_dry'] / OXIDE_WEIGHT[i]
normalize_v2(df, MAJOR_OXIDES, '_primary_mol_dry', '_primary_mol_dry', 100.)
return
[docs]def compute_components_cation(df):
"""
Calculate proportions of cations in mol% assuming the sample is anhydrous.
Parameters
----------
df : pandas dataframe
Dataframe containing sample compositions in wt%.
Should contain only one row. To use with a multi-row dataframe use
df.apply().
Returns
-------
df : pandas dataframe
Original dataframe with additional columns:
- anhydrous wt% with suffix '_primary_wt_dry'
- cation mol% with suffix '_primary_mol'
- anhydrous cation mol% with suffix '_primary_mol_dry'.
"""
MAJOR_OXIDES = ['SiO2','Al2O3','FeO','Fe2O3','MgO','CaO','Na2O','K2O',
'TiO2','MnO','Cr2O3', 'P2O5', 'NiO', 'H2O']
CAT_WEIGHT = [60.08,50.98,71.85,159.96/2.,40.3,56.08,30.99,
47.1,79.9,70.94,151.99/2.,141.945/2.,74.71, 18.014680000000002]
MAJOR_OXIDES_DRY = ['SiO2','Al2O3','FeO','Fe2O3','MgO','CaO','Na2O','K2O',
'TiO2','MnO','Cr2O3', 'P2O5', 'NiO']
CAT_WEIGHT_DRY = [60.08,50.98,71.85,159.96/2.,40.3,56.08,30.99,
47.1,79.9,70.94,151.99/2.,141.945/2.,74.71]
normalize_v2(df, MAJOR_OXIDES_DRY, '_primary_wt', '_primary_wt_dry', 100.)
normalize_v2(df, MAJOR_OXIDES, '_primary_wt', '_primary_wt', 100.)
for i in range(0, len(MAJOR_OXIDES_DRY), 1):
OXIDE = MAJOR_OXIDES_DRY[i]
df[OXIDE + '_primary_mol_dry'] = df[OXIDE + '_primary_wt_dry'] / CAT_WEIGHT_DRY[i]
for i in range(0, len(MAJOR_OXIDES), 1):
OXIDE = MAJOR_OXIDES[i]
df[OXIDE + '_primary_mol'] = df[OXIDE + '_primary_wt'] / CAT_WEIGHT[i]
normalize_v2(df, MAJOR_OXIDES, '_primary_mol', '_primary_mol', 1.)
normalize_v2(df, MAJOR_OXIDES_DRY, '_primary_mol_dry', '_primary_mol_dry', 1.)
return
[docs]def compute_components_per_oxygen(df):
"""
Calculate proportions of oxides in mol% assuming all Fe is in FeO
and the sample is anhydrous.
Normalise to each to one oxygen per compound.
Parameters
----------
df : pandas dataframe
Dataframe containing sample compositions in wt%.
Should contain only one row. To use with a multi-row dataframe use
df.apply().
Returns
-------
df : pandas dataframe
Original dataframe with additional columns:
- anhydrous wt% with suffix '_primary_wt_dry'
- volatile free oxide mol content per unit oxygen with suffix '_primary_mol_dry'.
"""
MAJOR_OXIDES = ['SiO2','Al2O3','FeO','MgO','CaO','Na2O','K2O',
'TiO2','MnO','Cr2O3', 'P2O5', 'NiO', 'H2O', 'CO2']
MAJOR_OXIDES_DRY = ['SiO2','Al2O3','FeO','MgO','CaO','Na2O','K2O','TiO2',
'MnO','Cr2O3','P2O5', 'NiO']
OXIDE_WEIGHT = [60.08,101.96,71.84,40.3,56.08,61.98,
94.2,79.86,70.94,151.99,141.945,74.71]
#OXIDE_WEIGHT = [60.843, 101.9612, 71.8444, 40.3039, 56.0774, 61.979,
# 94.196, 79.8658, 70.9374, 151.9904, 141.945, 74.6928]
ANO_N = [2., 3., 1., 1., 1., 1., 1., 2., 1., 3., 5., 1.]
CAT_N = [1., 2., 1., 1., 1., 2., 2., 1., 1., 2., 2., 1.]
df['FeO_primary_wt'] = df['FeO_primary_wt'] + 0.8998 * df['Fe2O3_primary_wt']
df['Fe2O3_primary_wt'] = 0.
normalize_v2(df, MAJOR_OXIDES_DRY, '_primary_wt', '_primary_wt_dry', 100.)
normalize_v2(df, MAJOR_OXIDES, '_primary_wt', '_primary_wt', 100.)
SUM = 0.
for i in range(0, len(MAJOR_OXIDES_DRY), 1):
OXIDE = MAJOR_OXIDES_DRY[i]
df[OXIDE + '_primary_mol_dry'] = df[OXIDE + '_primary_wt_dry'] / OXIDE_WEIGHT[i] * ANO_N[i]
SUM += df[OXIDE + '_primary_mol_dry']
O_FACTOR = 1. / SUM
for i in range(0, len(MAJOR_OXIDES_DRY), 1):
OXIDE = MAJOR_OXIDES_DRY[i]
df[OXIDE + '_primary_mol_dry'] = df[OXIDE + '_primary_mol_dry'] * O_FACTOR / ANO_N[i] * CAT_N[i]
return
class PF16:
def __init__(self, df):
self.df = df
self.P_err = 0.24
self.T_err = 39.
def compute_water_correction(self):
"""
Calculate temperature correction from water content.
Equation (1), Plank and Forsyth (2016, G-cubed).
Parameters
----------
df : pandas dataframe
The sample compositions.
Returns
-------
correction : pandas dataframe
The temperature corrections.
"""
correction = (
40.4*self.df['H2O_primary_wt'] -
2.97*self.df['H2O_primary_wt']**2. +
0.0761*self.df['H2O_primary_wt']**3.
)
return correction
def compute_CO2_correction(self):
"""
Calculate temperature correction for samples with equlibration pressures
above 2 GPa (assumed to be influenced by presence of CO2).
Equation (3), Plank and Forsyth (2016, G-cubed).
Parameters
----------
df : pandas dataframe
The sample compositions.
Returns
-------
correction : pandas dataframe
The temperature corrections.
"""
correction = (self.df['SiO2_primary_wt_dry'] - 50.3) / -0.12804
return correction
def compute_temperature(self):
"""
Calculate equlibration temperature.
Equation (1), Plank and Forsyth (2016, G-cubed).
Parameters
----------
df : pandas dataframe
The sample compositions.
Returns
-------
temperature : pandas dataframe
The calculated temperature(s).
"""
temperature = (
1264.5 +
7.85*self.df['Mg4Si2O8_dry'] +
8545./self.df['Si4O8_dry'] -
5.96*self.df['Al16/3O8_dry']
)
return temperature
def compute_pressure1(self, T):
"""
Calculate equlibration pressure.
Equation (2), Plank and Forsyth (2016, G-cubed).
Parameters
----------
df : pandas dataframe
The sample compositions.
Should contain only one row. To use with a multi-row dataframe use
df.apply().
Returns
-------
pressure : pandas dataframe
The calculated pressure(s).
"""
pressure = (
np.log(self.df['Si4O8_dry']) -
4.045 +
0.0114*self.df['Fe4Si2O8_dry'] +
0.00052*self.df['Ca4Si2O8_dry']**2. +
0.0024*self.df['Mg4Si2O8_dry']) / (-336.3/T - 0.0007*np.sqrt(T)
)
return pressure
def compute_pressure(self, T):
"""
Calculate equlibration pressure.
Equation (2), Plank and Forsyth (2016, G-cubed).
Parameters
----------
df : pandas dataframe
The sample compositions.
Should contain only one row. To use with a multi-row dataframe use
df.apply().
T : float
Temperature in oC.
Returns
-------
pressure : pandas dataframe
The calculated pressure(s).
"""
compute_components_species(self.df)
P = (
np.log(self.df['Si4O8_dry']) -
4.045 +
0.0114*self.df['Fe4Si2O8_dry'] +
0.00052*self.df['Ca4Si2O8_dry']**2. +
0.0024*self.df['Mg4Si2O8_dry']) / (-336.3/(T+273.15) - 0.0007*np.sqrt(T+273.15)
)
return {'P': P, 'T': T, 'P_err': self.P_err, 'T_err': T * self.P_err/P}
def compute_pressure_temperature(self):
"""
Compute equilibration pressure and temperature for a given sample.
Parameters
----------
df : pandas dataframe
Dataframe containing the sample primary composition.
Should contain only one row. To use with a multi-row dataframe use
df.apply().
Returns
-------
out : dict
The equilibration pressure and temperature result.
Temperature is in degrees celcius.
Pressure is in GPa.
Associated errors for pressure and temperature.
"""
compute_components_species(self.df)
water_correction = self.compute_water_correction()
T = self.compute_temperature() - water_correction
P = self.compute_pressure1(T)
if P > 2.:
T -= self.compute_CO2_correction()
P = self.compute_pressure1(T)
out = {'P': P, 'T': T - 273.15, 'P_err': self.P_err, 'T_err': self.T_err}
return out
class L09:
def __init__(self, df):
self.df = df
self.P_err = 0.2
self.T_err = 40.
def compute_pressure1(self, T):
"""
Calculate equlibration temperature.
Equation (2), Lee et al (2009, G-cubed).
Parameters
----------
df : pandas dataframe
The sample compositions in species mol%.
Should contain only one row. To use with a multi-row dataframe use
df.apply().
T : float
temperature in oC
Returns
-------
pressure : pandas dataframe
The calculated pressure(s).
"""
pressure = (
(np.log(self.df['Si4O8']) -
4.019 +
0.0165*self.df['Fe4Si2O8'] +
0.0005*(self.df['Ca4Si2O8']**2.)) /
(-770*(T**(-1.)) + 0.0058*(T**0.5) - 0.003*self.df['H16O8'])
)
return pressure
def compute_pressure(self, T):
"""
Calculate equlibration temperature.
Equation (2), Lee et al (2009, G-cubed).
Parameters
----------
df : pandas dataframe
The sample compositions in species mol%.
Should contain only one row. To use with a multi-row dataframe use
df.apply().
T : float
temperature in oC
Returns
-------
pressure : pandas dataframe
The calculated pressure(s).
"""
compute_components_species(self.df)
P = (
(np.log(self.df['Si4O8']) -
4.019 +
0.0165*self.df['Fe4Si2O8'] +
0.0005*(self.df['Ca4Si2O8']**2.)) /
(-770*((T+273.15)**(-1.)) + 0.0058*(T**0.5) - 0.003*self.df['H16O8'])
)
return {'P': P, 'T': T, 'P_err': self.P_err, 'T_err': T * self.P_err/P}
def compute_temperature(self):
"""
Calculate equlibration temperature.
Equation (3), Lee et al (2009, G-cubed).
Parameters
----------
df : pandas dataframe
The sample compositions.
Should contain only one row. To use with a multi-row dataframe use
df.apply().
Returns
-------
temperature : pandas dataframe
The calculated temperature(s).
"""
temperature = (
916.45 +
(13.68 * self.df['Mg4Si2O8']) +
(4580. / self.df['Si4O8']) -
(0.509 * self.df['H16O8'] * self.df['Mg4Si2O8'])
)
return temperature
def compute_pressure_temperature(self):
"""
Compute equilibration pressure and temperature for a given sample.
Parameters
----------
df : pandas dataframe
Dataframe containing the sample primary composition.
Should contain only one row. To use with a multi-row dataframe use
df.apply().
Returns
-------
out : dict
The equilibration pressure and temperature result.
Temperature is in degrees celcius.
Pressure is in GPa.
Associated errors for pressure and temperature.
"""
compute_components_species(self.df)
T = self.compute_temperature()
P = self.compute_pressure1((T+273.15))
return {'P': P, 'T': T, 'P_err': self.P_err, 'T_err': self.T_err}
class TGK12_SPL:
def __init__(self, df):
self.df = df
self.P_err = 0.15
self.T_err = 10.78
def compute_temperature(self, P):
"""
Compute equilibration pressure and temperature for a given sample.
Assumes spinel is stable mantle phase.
Lines (3) and (4) of Table (5), Till et al (2012, JGR).
Parameters
----------
df : pandas dataframe
Dataframe containing the sample primary composition.
Should contain only one row. To use with a multi-row dataframe use
df.apply().
P :
Pressure in GPa.
Returns
-------
out : dict
The equilibration pressure and temperature result.
Temperature is in degrees celcius.
Pressure is in GPa.
Associated errors for pressure and temperature.
"""
compute_components_compound(self.df)
MINS = compute_minerals(self.df)
T = compute_parameter_TGK12(self.df, MINS, P, [1212,0.,119.9,-97.33,-87.76,3.44,-4.58])
return {'P': P, 'T': T, 'P_err': P * self.T_err/T, 'T_err': self.T_err}
def compute_pressure_temperature(self):
"""
Compute equilibration pressure and temperature for a given sample.
Assumes spinel is stable mantle phase.
Lines (3) and (4) of Table (5), Till et al (2012, JGR).
Parameters
----------
df : pandas dataframe
Dataframe containing the sample primary composition.
Should contain only one row. To use with a multi-row dataframe use
df.apply().
Returns
-------
out : dict
The equilibration pressure and temperature result.
Temperature is in degrees celcius.
Pressure is in GPa.
Associated errors for pressure and temperature.
"""
compute_components_compound(self.df)
MINS = compute_minerals(self.df)
P = compute_parameter_TGK12(self.df, MINS, 0., [-0.862,9.471,0.,-2.383,2.922,0.218,-0.146])
T = compute_parameter_TGK12(self.df, MINS, P, [1212,0.,119.9,-97.33,-87.76,3.44,-4.58])
return {'P': P, 'T': T, 'P_err': self.P_err, 'T_err': self.T_err}
class TGK12_PLG:
def __init__(self, df):
self.df = df
self.P_err = 0.08
self.T_err = 11.7
def compute_temperature(self, P):
"""
Compute equilibration pressure and temperature for a given sample.
Assumes plagioclase is stable mantle phase.
Line (2) of Table (5), Till et al (2012, JGR).
Parameters
----------
df : pandas dataframe
Dataframe containing the sample primary composition.
Should contain only one row. To use with a multi-row dataframe use
df.apply().
P : float
Pressure in GPa.
Returns
-------
out : dict
The equilibration pressure and temperature result.
Temperature is in degrees celcius.
Pressure is in GPa.
Associated errors for pressure and temperature.
"""
compute_components_compound(self.df)
MINS = compute_minerals(self.df)
T = compute_parameter_TGK12(self.df, MINS, P, [1216,0.,104.4,-72.83,-194.9,24.08,-1.55])
return {'P': P, 'T': T, 'P_err': P * self.T_err/T, 'T_err': self.T_err}
def compute_pressure_temperature(self):
"""
Compute equilibration pressure and temperature for a given sample.
Assumes plagioclase is stable mantle phase.
Line (1 and 2) of Table (5), Till et al (2012, JGR).
Parameters
----------
df : pandas dataframe
Dataframe containing the sample primary composition.
Should contain only one row. To use with a multi-row dataframe use
df.apply().
Returns
-------
out : dict
The equilibration pressure and temperature result.
Temperature is in degrees celcius.
Pressure is in GPa.
Associated errors for pressure and temperature.
"""
compute_components_compound(self.df)
MINS = compute_minerals(self.df)
P = compute_parameter_TGK12(self.df, MINS, 0., [-1.64,12.94,0.,-2.363,3.51,0.152,-0.176])
T = compute_parameter_TGK12(self.df, MINS, P, [1216,0.,104.4,-72.83,-194.9,24.08,-1.55])
return {'P': P, 'T': T, 'P_err': self.P_err, 'T_err': self.T_err}
class G13:
def __init__(self, df):
self.df = df
self.P_err = 0.24
self.T_err = 24.
def compute_pressure(self):
"""
Calculate equlibration pressure.
Line (1) of Table (4), Grove et al (2013, Contrib Min Pet).
Parameters
----------
df : pandas dataframe
The sample compositions.
Returns
-------
pressure : float
The calculated pressure(s).
"""
compute_components_compound(self.df)
MINS = compute_minerals(self.df)
pressure = -17.3
pressure += 146.4 * MINS[0]
pressure -= 38.4 * (1. - Mg_num(self.df))
pressure += 19.6 * NaK_num(self.df)
pressure += 4.81 * self.df['P2O5_primary_wt_dry']
pressure *= 0.1
return pressure
def compute_temperature1(self, P):
"""
Calculate equlibration temperature.
Line (6) of Table (4), Grove et al (2013, Contrib Min Pet).
Parameters
----------
df : pandas dataframe
The sample compositions.
P: pressure in GPa
Returns
-------
temperature : float
The calculated temperature(s) in oC.
"""
temperature = 1313.67
temperature += 8.423 * ((P*10.)-1.)
temperature -= 149.92 * (1. - Mg_num(self.df))
temperature += 55.02 * NaK_num(self.df)
temperature -= 59.69 * self.df['P2O5_primary_wt_dry']
return temperature
def compute_temperature(self, P):
"""
Calculate equlibration temperature.
Line (6) of Table (4), Grove et al (2013, Contrib Min Pet).
Parameters
----------
df : pandas dataframe
The sample compositions.
P: pressure in GPa
Returns
-------
temperature : float
The calculated temperature(s) in oC.
"""
compute_components_compound(self.df)
T = 1313.67
T += 8.423 * ((P/0.1)-1)
T -= 149.92 * (1. - Mg_num(self.df))
T += 55.02 * NaK_num(self.df)
T -= 59.69 * self.df['P2O5_primary_wt_dry']
return {'P': P, 'T': T, 'P_err': P * self.T_err/T, 'T_err': self.T_err}
def compute_pressure_temperature(self):
"""
Compute equilibration pressure and temperature for a given sample.
Assumes garnet is stable mantle phase.
Line (1) and (6) of Table (4), Grove et al (2013, Contrib Min Pet).
Parameters
----------
df : pandas dataframe
Dataframe containing the sample primary composition.
Should contain only one row. To use with a multi-row dataframe use
df.apply().
Returns
-------
out : dict
The equilibration pressure and temperature result.
Temperature is in degrees celcius.
Pressure is in GPa.
Associated errors for pressure and temperature.
"""
compute_components_compound(self.df)
P = self.compute_pressure()
T = self.compute_temperature1(P)
return {'P': P, 'T': T, 'P_err': self.P_err, 'T_err': self.T_err}
class BK21_GNT:
def __init__(self, df):
self.df = df
self.P_err = 1.26
self.T_err = 18.72
def compute_temperature(self, P):
"""
Calculate equlibration temperature.
Equation 1G-T of Table (1), Brown Krein et al (2021, JGR: Solid Earth).
Parameters
----------
df : pandas dataframe
Dataframe containing the sample primary composition.
Should contain only one row. To use with a multi-row dataframe use
df.apply().
P : float
Pressure in GPa
Returns
-------
out : dict
The equilibration pressure and temperature result.
Temperature is in degrees celcius.
Pressure is in GPa.
Associated errors for pressure and temperature.
"""
T = compute_parameter_BK21(self.df, 0., P/0.1, [1136.36052,0,8.73915,184.88412,-19.48245,29.00187,-23.41730,-22.48205])
return {'P': P, 'T': T, 'P_err': P * self.T_err/T, 'T_err': self.T_err}
def compute_pressure_temperature(self):
"""
Same as TGK12_GNT but equations have been recalibrated with additional data.
Equations 1G-P and 1G-T of Table (1), Brown Krein et al (2021, JGR: Solid Earth).
Parameters
----------
df : pandas dataframe
Dataframe containing the sample primary composition.
Should contain only one row. To use with a multi-row dataframe use
df.apply().
Returns
-------
out : dict
The equilibration pressure and temperature result.
Temperature is in degrees celcius.
Pressure is in GPa.
Associated errors for pressure and temperature.
"""
compute_components_compound(self.df)
MINS = compute_minerals(self.df)
P = 0.1 * compute_parameter_BK21(self.df, MINS[0], 0., [-77.53423,139.87872,0,46.43963,28.72057,1.52179,3.25095,18.62211])
T = compute_parameter_BK21(self.df, 0., P/0.1, [1136.36052,0,8.73915,184.88412,-19.48245,29.00187,-23.41730,-22.48205])
return {'P': P, 'T': T, 'P_err': self.P_err, 'T_err': self.T_err}
class BK21_SPL:
def __init__(self, df):
self.df = df
self.P_err = 1.53
self.T_err = 14.28
def compute_temperature(self, P):
"""
Calculate equlibration temperature.
Line (17) of Table (1), Brown Krein et al (2021, JGR: Solid Earth).
Parameters
----------
df : pandas dataframe
Dataframe containing the sample primary composition.
Should contain only one row. To use with a multi-row dataframe use
df.apply().
P : float
Pressure in GPa
Returns
-------
out : dict
The equilibration pressure and temperature result.
Temperature is in degrees celcius.
Pressure is in GPa.
Associated errors for pressure and temperature.
"""
T = compute_parameter_BK21(self.df, 0., P/0.1, [1049.24929,0,12.71243,63.47484,-3.32516,2.65802,-12.03128,117.75713])
return {'P': P, 'T': T, 'P_err': P * self.T_err/T, 'T_err': self.T_err}
def compute_pressure_temperature(self):
"""
Same as TGK12_SPL but equations have been recalibrated with additional data.
Line (3 and 17) of Table (1), Brown Krein et al (2021, JGR: Solid Earth).
Parameters
----------
df : pandas dataframe
Dataframe containing the sample primary composition.
Should contain only one row. To use with a multi-row dataframe use
df.apply().
Returns
-------
out : dict
The equilibration pressure and temperature result.
Temperature is in degrees celcius.
Pressure is in GPa.
Associated errors for pressure and temperature.
"""
compute_components_compound(self.df)
MINS = compute_minerals(self.df)
P = 0.1 * compute_parameter_BK21(self.df, MINS[0], 0., [-29.5,84.82,0,25.,24.67,2.79,-0.138,-1.848])
T = compute_parameter_BK21(self.df, 0., P/0.1, [1049.24929,0,12.71243,63.47484,-3.32516,2.65802,-12.03128,117.75713])
return {'P': P, 'T': T, 'P_err': self.P_err, 'T_err': self.T_err}
class BK21_PLG:
def __init__(self, df):
self.df = df
self.P_err = 0.79
self.T_err = 11.5
def compute_temperature(self, P):
"""
Calculate equlibration temperature.
Line (6) of Table (1), Brown Krein et al (2021, JGR: Solid Earth).
Parameters
----------
df : pandas dataframe
Dataframe containing the sample primary composition.
Should contain only one row. To use with a multi-row dataframe use
df.apply().
P : float
Pressure in GPa
Returns
-------
out : dict
The equilibration pressure and temperature result.
Temperature is in degrees celcius.
Pressure is in GPa.
Associated errors for pressure and temperature.
"""
T = compute_parameter_BK21(self.df, 0., P/0.1, [1074.38633,0,11.86431,65.55420,-138.22714,20.55173,5.85532,79.01883])
return {'P': P, 'T': T, 'P_err': P * self.T_err/T, 'T_err': self.T_err}
def compute_pressure_temperature(self):
"""
Calculate equlibration conditions.
Line (1 and 7) of Table (1), Brown Krein et al (2021, JGR: Solid Earth).
Parameters
----------
df : pandas dataframe
Dataframe containing the sample primary composition.
Should contain only one row. To use with a multi-row dataframe use
df.apply().
Returns
-------
out : dict
The equilibration pressure and temperature result.
Temperature is in degrees celcius.
Pressure is in GPa.
Associated errors for pressure and temperature.
"""
compute_components_compound(self.df)
MINS = compute_minerals(self.df)
P = 0.1 * compute_parameter_BK21(self.df, MINS[0], 0., [-43.58532,136.94746,0,24.54202,37.54688,2.10967,-0.77250,1.63584])
T = compute_parameter_BK21(self.df, 0., P/0.1, [1074.38633,0,11.86431,65.55420,-138.22714,20.55173,5.85532,79.01883])
return {'P': P, 'T': T, 'P_err': self.P_err, 'T_err': self.T_err}
class BK21:
def __init__(self, df):
self.df = df
self.P_err = [0.79, 1.53, 1.26]
self.T_err = [11.5, 14.28, 18.72]
def compute_pressure(self):
"""
Calculate equlibration pressure.
Brown Krein et al (2021, JGR: Solid Earth).
Parameters
----------
df : pandas dataframe
The sample compositions in wt%.
Returns
-------
pressure : array
The calculated pressure(s) in GPa
in plg, spl and gnt stability fields.
"""
MINS = compute_minerals(self.df)
pressure = [0]*3
# Compute Pressure Plag
pressure[0] = 0.1 * compute_parameter_BK21(self.df, MINS[0], 0., [-43.58532,136.94746,0,24.54202,37.54688,2.10967,-0.77250,1.63584])
# Compute Pressure Spl
pressure[1] = 0.1 * compute_parameter_BK21(self.df, MINS[0], 0., [-29.5,84.82,0,25.,24.67,2.79,-0.138,-1.848])
# Compute Pressure Gnt
pressure[2] = 0.1 * compute_parameter_BK21(self.df, MINS[0], 0., [-77.53423,139.87872,0,46.43963,28.72057,1.52179,3.25095,18.62211])
return pressure
def compute_temperature1(self, P):
"""
Calculate equlibration temperature.
Brown Krein et al (2021, JGR: Solid Earth).
Parameters
----------
df : pandas dataframe
The sample compositions in wt%.
P : float
Pressure in GPa
Returns
-------
temperature : array
The calculated pressure(s) in GPa
in plg, spl and gnt stability fields.
"""
temperature = [0]*3
# Compute Temperature Plag
temperature[0] = compute_parameter_BK21(self.df, 0., P[0]/0.1, [1074.38633,0,11.86431,65.55420,-138.22714,20.55173,5.85532,79.01883])
# Compute Temperature Spl
temperature[1] = compute_parameter_BK21(self.df, 0., P[1]/0.1, [1049.24929,0,12.71243,63.47484,-3.32516,2.65802,-12.03128,117.75713])
# Compute Temperature Gnt
temperature[2] = compute_parameter_BK21(self.df, 0., P[2]/0.1, [1136.36052,0,8.73915,184.88412,-19.48245,29.00187,-23.41730,-22.48205])
return temperature
def compute_temperature(self, P):
"""
Calculate equlibration temperature assuming a known pressure.
Brown Krein et al (2021, JGR: Solid Earth).
Parameters
----------
df : pandas dataframe
The sample compositions in wt%.
P : float
Pressure in GPa
Returns
-------
temperature : array
The calculated pressure(s) in GPa
in plg, spl and gnt stability fields.
"""
compute_components_compound(self.df)
P = self.compute_pressure()
RMSD = self.compute_mins(P)
T = [0]*3
# Compute Temperature Plag
T[0] = compute_parameter_BK21(self.df, 0., P[0]/0.1, [1074.38633,0,11.86431,65.55420,-138.22714,20.55173,5.85532,79.01883])
# Compute Temperature Spl
T[1] = compute_parameter_BK21(self.df, 0., P[1]/0.1, [1049.24929,0,12.71243,63.47484,-3.32516,2.65802,-12.03128,117.75713])
# Compute Temperature Gnt
T[2] = compute_parameter_BK21(self.df, 0., P[2]/0.1, [1136.36052,0,8.73915,184.88412,-19.48245,29.00187,-23.41730,-22.48205])
return {'P': P[np.argmin(RMSD)], 'T': T[np.argmin(RMSD)],
'P_err': P[np.argmin(RMSD)] * self.T_err[np.argmin(RMSD)]/T[np.argmin(RMSD)],
'T_err': self.T_err[np.argmin(RMSD)]}
def compute_mins(self, P):
"""
Determine root mean squared differences between predicted
sample mineralogy and mineralogies in plg, spl and gnt fields.
Brown Krein et al (2021, JGR: Solid Earth).
Parameters
----------
df : pandas dataframe
The sample compositions in wt%.
P: float
pressure in GPa
Returns
-------
RMSD : array
Difference between calculated and predicted
mineralogic make-up for plg, spl and gnt fields.
"""
MINS = compute_minerals(self.df)
RMSD = [0]*3
# Calculated minerals order: OL, CPX, PLG, QTZ
# Mineral Residuals for Plagioclase
Mplg = [0]*4
Mplg[0] = compute_parameter_BK21(self.df, 0., P[0]/0.1, [0.412,0,0.005,-0.162,-0.363,-0.011,-0.001,-0.126])
Mplg[0] -= MINS[0]
Mplg[1] = compute_parameter_BK21(self.df, 0., P[0]/0.1, [-0.256,0,0,0.032,0.339,-0.004,-0.01,0.497])
Mplg[1] -= MINS[1]
Mplg[2] = compute_parameter_BK21(self.df, 0., P[0]/0.1, [0.429,0,0.012,0.132,0.503,0.001,-0.073,-0.157])
Mplg[2] -= MINS[2]
Mplg[3] = compute_parameter_BK21(self.df, 0., P[0]/0.1, [0.423,0,-0.018,0.001,-0.487,-0.001,0.023,-0.225])
Mplg[3] -= MINS[3]
RMSD[0] = np.sqrt((Mplg[0]**2. + Mplg[1]**2. + Mplg[2]**2. + Mplg[3]**2.)/4.)
# Mineral Residuals for Spinel
Mspl = [0]*4
Mspl[0] = compute_parameter_BK21(self.df, 0., P[1]/0.1, [0.294,0,0.009,-0.215,-0.208,-0.027,-0.003,-0.046])
Mspl[0] -= MINS[0]
Mspl[1] = compute_parameter_BK21(self.df, 0., P[1]/0.1, [-0.256,0,0,0.016,0.336,-0.001,-0.006,0.525])
Mspl[1] -= MINS[1]
Mspl[2] = compute_parameter_BK21(self.df, 0., P[1]/0.1, [0.826,0,-0.004,0.116,0.392,-0.012,-0.072,-0.482])
Mspl[2] -= MINS[2]
Mspl[3] = compute_parameter_BK21(self.df, 0., P[1]/0.1, [0.148,0,-0.005,0.085,-0.53,0.023,0.02,-0.107])
Mspl[3] -= MINS[3]
RMSD[1] = np.sqrt((Mspl[0]**2. + Mspl[1]**2. + Mspl[2]**2. + Mspl[3]**2.)/4.)
# Mineral Residuals for Garnet
Mgnt = [0]*4
Mgnt[0] = compute_parameter_BK21(self.df, 0., P[2]/0.1, [0.531,0,0.007,-0.314,-0.185,-0.01,-0.023,-0.107])
Mgnt[0] -= MINS[0]
Mgnt[1] = compute_parameter_BK21(self.df, 0., P[2]/0.1, [-0.192,0,-0.003,0.109,0.358,-0.005,-0.011,0.413])
Mgnt[1] -= MINS[1]
Mgnt[2] = compute_parameter_BK21(self.df, 0., P[2]/0.1, [0.613,0,-0.006,0.237,0.365,-0.018,-0.042,-0.243])
Mgnt[2] -= MINS[2]
Mgnt[3] = compute_parameter_BK21(self.df, 0., P[2]/0.1, [0.048,0,0.003,-0.026,-0.547,0.019,0.010,-0.069])
Mgnt[3] -= MINS[3]
RMSD[2] = np.sqrt((Mgnt[0]**2. + Mgnt[1]**2. + Mgnt[2]**2. + Mgnt[3]**2.)/4.)
return RMSD
def compute_pressure_temperature(self):
"""
Calculate equlibration conditions.
Brown Krein et al (2021, JGR: Solid Earth).
Parameters
----------
df : pandas dataframe
Dataframe containing the sample primary composition.
Should contain only one row. To use with a multi-row dataframe use
df.apply().
Returns
-------
out : dict
The equilibration pressure and temperature result.
Temperature is in degrees celcius.
Pressure is in GPa.
Associated errors for pressure and temperature.
"""
compute_components_compound(self.df)
P = self.compute_pressure()
T = self.compute_temperature1(P)
RMSD = self.compute_mins(P)
return {'P': P[np.argmin(RMSD)], 'T': T[np.argmin(RMSD)],
'P_err': self.P_err[np.argmin(RMSD)], 'T_err': self.T_err[np.argmin(RMSD)]}
class HA15:
def __init__(self, df):
self.df = df
self.P_err = np.nan
self.T_err = 31.
def compute_temperature(self, P):
"""
Calculate temperate of olivine liquidus at 1 bar
using Beattie (1993) Cointrib Min & Pet 115:103-111
Equations 10 and 12.
Convert to desired pressure using Equation from
Herzberg & O'Hara, (2002) G3 9:9
Parameters
----------
df : pandas dataframe
Dataframe containing the sample primary composition.
Should contain only one row. To use with a multi-row dataframe use
df.apply().
P : float
assumed pressure in GPa.
Returns
-------
out : dict
The equilibration pressure and temperature result.
Temperature is in degrees celcius.
Pressure is in GPa.
Associated errors for pressure and temperature.
"""
compute_components_cation(self.df)
DMg = compute_DMg(self.df)
#####
Temp_Denom = 52.05/8.3143
Temp_Denom += 2.*np.log(DMg)
Temp_Denom += 2.*np.log(1.5*(self.df["FeO_primary_mol_dry"]+self.df["MnO_primary_mol_dry"]+self.df["MgO_primary_mol_dry"]+self.df["CaO_primary_mol_dry"]+self.df["NiO_primary_mol_dry"]))
Temp_Denom += 2.*np.log(3.*self.df["SiO2_primary_mol_dry"])
Temp_Denom -= 3.5*np.log(1-self.df["Al2O3_primary_mol_dry"]) + 7*np.log(1-self.df["TiO2_primary_mol_dry"])
Temp_1bar = (113100/8.3143 + P*0.00000411/8.3143)
Temp_1bar /= Temp_Denom
Temp_1bar -= 273.15
#####
T = Temp_1bar + 54.*P - 2.*P**2.
return {'P': P, 'T': T, 'P_err': P * self.T_err/T, 'T_err': self.T_err}
class P08:
def __init__(self, df):
self.df = df
self.P_err = 0.29
self.T_err = 52.
def compute_pressure(self, T):
"""
Calculate temperate and pressure of melt
equilibration by simultaneously solving
Equation 4 of Putirka et al., (2007, Chemical Geology)
and Equation 42 of Putirka (2008).
Parameters
----------
df : pandas dataframe
Dataframe containing the sample primary composition.
Should contain only one row. To use with a multi-row dataframe use
df.apply().
T : float
Temperature in oC
Returns
-------
out : dict
The equilibration pressure and temperature result.
Temperature is in degrees celcius.
Pressure is in GPa.
Associated errors for pressure and temperature.
"""
compute_components_cation(self.df)
aSiO2 = (3*self.df["SiO2_primary_mol_dry"])**-2*(1-self.df["Al2O3_primary_mol_dry"])**(7/2)*(1-self.df["TiO2_primary_mol_dry"])**(7/2)
P = (231.5+0.186*T+0.1244*T*(np.log(aSiO2))-528.*(aSiO2)**0.5+103.3*self.df["TiO2_primary_mol_dry"]+69.9*(self.df["Na2O_primary_mol_dry"]+self.df["K2O_primary_mol_dry"])+77.3*(self.df["Al2O3_primary_mol_dry"]/(self.df["Al2O3_primary_mol_dry"]+self.df["SiO2_primary_mol_dry"])))/10.
return {'P': P, 'T': T, 'P_err': self.P_err, 'T_err': T * self.P_err/P}
def compute_pressure_temperature(self):
"""
Calculate temperate and pressure of melt
equilibration by simultaneously solving
Equation 4 of Putirka et al., (2007, Chemical Geology)
and Equation 42 of Putirka (2008).
Parameters
----------
df : pandas dataframe
Dataframe containing the sample primary composition.
Should contain only one row. To use with a multi-row dataframe use
df.apply().
Returns
-------
out : dict
The equilibration pressure and temperature result.
Temperature is in degrees celcius.
Pressure is in GPa.
Associated errors for pressure and temperature.
"""
compute_components_cation(self.df)
DMg = compute_DMg(self.df)
aSiO2 = (3*self.df["SiO2_primary_mol_dry"])**-2*(1-self.df["Al2O3_primary_mol_dry"])**(7/2)*(1-self.df["TiO2_primary_mol_dry"])**(7/2)
P, T = sym.symbols('P, T')
eq1 = sym.Eq(1 / ((np.log(DMg) + 2.158 - 5.115*10**-2*(self.df["Na2O_primary_wt"]+self.df["K2O_primary_wt"]) + 6.213*10**-2*self.df["H2O_primary_wt"]) / (55.09*P + 4430.)), T)
eq2 = sym.Eq((231.5+0.186*T+0.1244*T*(np.log(aSiO2))-528.*(aSiO2)**0.5+103.3*self.df["TiO2_primary_mol_dry"]+69.9*(self.df["Na2O_primary_mol_dry"]+self.df["K2O_primary_mol_dry"])+77.3*(self.df["Al2O3_primary_mol_dry"]/(self.df["Al2O3_primary_mol_dry"]+self.df["SiO2_primary_mol_dry"])))/10., P)
result = sym.solve([eq1,eq2],(P,T))
T = result[T]
P = result[P]
return {'P': P, 'T': T, 'P_err': self.P_err, 'T_err': self.T_err}
class SD20:
def __init__(self, df):
self.df = df
self.P_err = 0.5
self.T_err = 49.
def compute_temperature(self, P):
"""
Sun & Dasgupta, (2020), EPSL.
Temperature calculated using equation 6.
Parameters
----------
df : pandas dataframe
Dataframe containing the sample primary composition.
Should contain only one row. To use with a multi-row dataframe use
df.apply().
P : float
pressure in GPa
Returns
-------
out : dict
The equilibration pressure and temperature result.
Temperature is in degrees celcius.
Pressure is in GPa.
Associated errors for pressure and temperature.
"""
compute_components_per_oxygen(self.df)
# Phi and Theta defined in Eq 3,
# Omega defined in Eq 5
phi = 2412. + 9.2 * (self.df['CO2_primary_wt']/self.df['SiO2_primary_mol_dry'])
phi += 11.19 * (self.df['H2O_primary_wt']/self.df['SiO2_primary_mol_dry'])
theta = 4.7 + 3.91 * np.log(self.df['SiO2_primary_mol_dry'])
theta += 1.19*((self.df['K2O_primary_mol_dry']+self.df['TiO2_primary_mol_dry'])/self.df['MgO_primary_mol_dry'])
omega = 2.59 + 3.5*(self.df['CaO_primary_mol_dry'] - (2.*self.df['K2O_primary_mol_dry']))
omega += 4.85*self.df['TiO2_primary_mol_dry']
omega += 1.4*(self.df['MgO_primary_mol_dry']/(self.df['MgO_primary_mol_dry']+self.df['FeO_primary_mol_dry']))
omega += 0.5 * self.df['MgO_primary_mol_dry'] * sym.sqrt(self.df['CO2_primary_wt'])
omega += 0.057 * self.df['H2O_primary_wt']
T = (10.**4. / (omega - 0.34*np.sqrt(P) - 1.26*np.log(self.df['MgO_primary_mol_dry']))) - 273.15
return {'P': P, 'T': float(T), 'P_err': float(P * self.T_err/T), 'T_err': self.T_err}
def compute_pressure_temperature(self):
"""
Sun & Dasgupta, (2020), EPSL.
Pressure and temperature calculated using
equations 4 and 6, repsectively.
Pressure and temperature are functions of each other
and must be calculated simultaneously.
Parameters
----------
df : pandas dataframe
Dataframe containing the sample primary composition.
Should contain only one row. To use with a multi-row dataframe use
df.apply().
Returns
-------
out : dict
The equilibration pressure and temperature result.
Temperature is in degrees celcius.
Pressure is in GPa.
Associated errors for pressure and temperature.
"""
compute_components_per_oxygen(self.df)
# Phi and Theta defined in Eq 3,
# Omega defined in Eq 5
phi = 2412. + 9.2 * (self.df['CO2_primary_wt']/self.df['SiO2_primary_mol_dry'])
phi += 11.19 * (self.df['H2O_primary_wt']/self.df['SiO2_primary_mol_dry'])
theta = 4.7 + 3.91 * np.log(self.df['SiO2_primary_mol_dry'])
theta += 1.19*((self.df['K2O_primary_mol_dry']+self.df['TiO2_primary_mol_dry'])/self.df['MgO_primary_mol_dry'])
omega = 2.59 + 3.5*(self.df['CaO_primary_mol_dry'] - (2.*self.df['K2O_primary_mol_dry']))
omega += 4.85*self.df['TiO2_primary_mol_dry']
omega += 1.4*(self.df['MgO_primary_mol_dry']/(self.df['MgO_primary_mol_dry']+self.df['FeO_primary_mol_dry']))
omega += 0.5 * self.df['MgO_primary_mol_dry'] * sym.sqrt(self.df['CO2_primary_wt'])
omega += 0.057 * self.df['H2O_primary_wt']
# Pressure calculated using Eq 4.
# Temperature calculated using Eq 6.
# Must be solved simultaneously.
P, T = sym.symbols('P, T')
eq1 = sym.Eq(13. - sym.sqrt((T/45.9) * (np.log(self.df['Al2O3_primary_mol_dry']/self.df['MgO_primary_mol_dry']) - theta) - (phi/45.9) + 169.), P)
eq2 = sym.Eq(10.**4. / (omega - 0.34*sym.sqrt(P) - 1.26*np.log(self.df['MgO_primary_mol_dry'])), T)
result = sym.solve([eq1,eq2],(P,T))
if len(result) == 0:
T = np.nan
P = np.nan
else:
T = result[0][1] - 273.15
P = result[0][0]
return {'P': float(P), 'T': float(T), 'P_err': self.P_err, 'T_err': self.T_err}
class B93:
def __init__(self, df):
self.df = df
self.T_err = 20.
def compute_temperature(self, P):
"""
Calculate temperate of olivine liquidus at P GPa
using Equation 10 Beattie (1993, Contrib. to Min. and Pet.)
Parameters
----------
df : pandas dataframe
Dataframe containing the sample primary composition.
Should contain only one row. To use with a multi-row dataframe use
df.apply().
P : float
pressure in GPa
Returns
-------
out : dict
The equilibration temperature result.
Temperature is in degrees celcius.
Assumed pressure is in GPa.
Associated errors for pressure and temperature.
"""
compute_components_cation(self.df)
DMg = compute_DMg(self.df)
# Eq 20 of Putirka 2008 Rev in Min. & Geochem. 69:1
# DMg = (0.666-(-0.049*self.df["MnO_primary_mol"]+0.027*self.df["FeO_primary_mol"]))/(self.df["MgO_primary_mol"]+0.259*self.df["MnO_primary_mol_dry"]+0.299*self.df["FeO_primary_mol"])
C_NM = self.df["MgO_primary_mol"] + self.df["FeO_primary_mol"]
C_NM += self.df["CaO_primary_mol"] + self.df["MnO_primary_mol"]
NF = 7/2*np.log(1.-self.df["Al2O3_primary_mol"])
NF += 7.*np.log(1.-self.df["TiO2_primary_mol"])
# Eq 19 of Putirka 2008 Rev in Min. & Geochem. 69:1
T = ((113100./8.3144) + ((P*10.**9.-10.**-5.)*((4.11*10**-6)/8.3144)))
T /= ((52.05/8.3144) + 2.*np.log(DMg) + 2.*np.log(1.5*C_NM) + 2.*np.log(3.*self.df["SiO2_primary_mol"]) - NF)
T -= 273.15
return {'P': P, 'T': T, 'P_err': P * self.T_err/T, 'T_err': self.T_err}
class P07_2:
def __init__(self, df):
self.df = df
self.T_err = 52.
def compute_temperature(self, P):
"""
Calculate temperate of olivine liquidus at P GPa
using Equation 2 of Putirka et al., (2007, Chemical Geology)
Parameters
Parameters
----------
df : pandas dataframe
Dataframe containing the sample primary composition.
Should contain only one row. To use with a multi-row dataframe use
df.apply().
P : float
pressure in GPa
Returns
-------
out : dict
The equilibration temperature result.
Temperature is in degrees celcius.
Assumed pressure is in GPa.
Associated errors for pressure and temperature.
"""
compute_components_cation(self.df)
DMg = compute_DMg(self.df)
# Eq 21 of Putirka 2008 Rev in Min. & Geochem. 69:1
T = 1 / ((np.log(DMg) + 2.158 - 5.115*10**-2*(self.df["Na2O_primary_wt"]+self.df["K2O_primary_wt"]) + 6.213*10**-2*self.df["H2O_primary_wt"]) / (55.09*P + 4430))
return {'P': P, 'T': T, 'P_err': P * self.T_err/T, 'T_err': self.T_err}
class P07_4:
def __init__(self, df):
self.df = df
self.T_err = 52.
def compute_temperature(self, P):
"""
Calculate temperate of olivine liquidus at P GPa
using Equation 4 of Putirka et al., (2007, Chemical Geology)
Parameters
----------
df : pandas dataframe
Dataframe containing the sample primary composition.
Should contain only one row. To use with a multi-row dataframe use
df.apply().
P : float
pressure in GPa
Returns
-------
out : dict
The equilibration temperature result.
Temperature is in degrees celcius.
Assumed pressure is in GPa.
Associated errors for pressure and temperature.
"""
compute_components_cation(self.df)
DMg = compute_DMg(self.df)
C_NM = self.df["MgO_primary_mol"] + self.df["FeO_primary_mol"]
C_NM += self.df["CaO_primary_mol"] + self.df["MnO_primary_mol"]
NF = 7/2*np.log(1.-self.df["Al2O3_primary_mol"])
NF += 7.*np.log(1.-self.df["TiO2_primary_mol"])
# Eq 22 of Putirka 2008 Rev in Min. & Geochem. 69:1
T = (15294.6+1318.8*P+2.4834*P**2)/(8.048+2.8352*np.log(DMg)+2.097*np.log(1.5*C_NM)+2.575*np.log(3*self.df["SiO2_primary_mol"])-1.41*NF+0.222*self.df["H2O_primary_wt"]+0.5*P)
return {'P': P, 'T': T, 'P_err': P * self.T_err/T, 'T_err': self.T_err}
[docs]def compute_sample_pressure_temperature(df, method="PF16", min_SiO2=0.):
"""
Calculate temperate and pressure of melt equilibration.
Parameters
----------
df : pandas dataframe.
Dataframe containing the sample primary composition.
Should contain only one row. To use with a multi-row dataframe use
df.apply().
method: string
choice of thermobaric method
PF16 = Plank & Forsyth (2016), G3
L09 = Lee et al., (2009), G3
TGK12_PLG = Till et al., (2012) in plagioclase stability field.
TGK12_SPL = Till et al., (2012) in spinel stability field.
G13 = Grove et al., (2013) in garnet stability field.
BK21_PLG = Brown Krein et al., (2021) in plagioclase stability field.
BK21_SPL = Brown Krein et al., (2021) in spinel stability field.
BK21_GNT = Brown Krein et al., (2021) in garnet stability field.
BK21 = Brown Krein et al., (2021)
P07_P08 = Putirka et al., (2007) Eq 4. and Putirka (2008) combined.
SD20 = Sun & Dasgupta (2020), EPSL low SiO2 thermobarometer.
Returns
-------
PT : dict
The calculated temperature(s) in oC,
pressures in GPa, and associated errors.
"""
if df['SiO2_primary_wt'] < min_SiO2:
out = {'P': np.nan, 'P_err': np.nan, 'T': np.nan, 'T_err': np.nan}
elif inspect.isclass(method):
out = method(df).compute_pressure_temperature()
elif method == "PF16":
out = PF16(df).compute_pressure_temperature()
elif method == "L09":
out = L09(df).compute_pressure_temperature()
elif method == "TGK12_PLG":
out = TGK12_PLG(df).compute_pressure_temperature()
elif method == "TGK12_SPL":
out = TGK12_SPL(df).compute_pressure_temperature()
elif method == "G13":
out = G13(df).compute_pressure_temperature()
elif method == "BK21_PLG":
out = BK21_PLG(df).compute_pressure_temperature()
elif method == "BK21_SPL":
out = BK21_SPL(df).compute_pressure_temperature()
elif method == "BK21_GNT":
out = BK21_GNT(df).compute_pressure_temperature()
elif method == "BK21":
out = BK21(df).compute_pressure_temperature()
elif method == "P08":
out = P08(df).compute_pressure_temperature()
elif method == "SD20":
out = SD20(df).compute_pressure_temperature()
else:
out = thermobar(df).compute_pressure_temperature()
return out
[docs]def compute_sample_temperature(df, method="HA15", P=1., min_SiO2=0.):
"""
Calculate temperate of melt equilibration.
Parameters
----------
df : pandas dataframe.
Dataframe containing the sample primary composition.
Should contain only one row. To use with a multi-row dataframe use
df.apply().
method: sring
choice of thermobaric method
HA15 = Herzberg & Asimow (2015)
P07_2 = Putirka et al., (2007) equation 2.
P07_4 = Putirka et al., (2007) equation 4.
TGK12_PLG = Till et al., (2012) in plagioclase stability field.
TGK12_SPL = Till et al., (2012) in spinel stability field.
G13 = Grove et al., (2013) in garnet stability field.
BK21_PLG = Brown Krein et al., (2021) in plagioclase stability field.
BK21_SPL = Brown Krein et al., (2021) in spinel stability field.
BK21_GNT = Brown Krein et al., (2021) in garnet stability field.
BK21 = Brown Krein et al., (2021).
SD20 = Sun & Dasgupta (2020), EPSL low SiO2 thermobarometer.
P : float
pressure in GPa
Returns
-------
PT : pandas dataframe
The calculated temperature(s) in oC,
assumed pressures in GPa and associated errors.
"""
if df['SiO2_primary_wt'] < min_SiO2:
out = {'P': np.nan, 'P_err': np.nan, 'T': np.nan, 'T_err': np.nan}
elif inspect.isclass(method):
out = method(df).compute_temperature(P)
elif method == "HA15":
out = HA15(df).compute_temperature(P)
elif method == "P07_2":
out = P07_2(df).compute_temperature(P)
elif method == "P07_4":
out = P07_4(df).compute_temperature(P)
elif method == "B93":
out = B93(df).compute_temperature(P)
elif method == "TGK12_PLG":
out = TGK12_PLG(df).compute_temperature(P)
elif method == "TGK12_SPL":
out = TGK12_SPL(df).compute_temperature(P)
elif method == "G13":
out = G13(df).compute_temperature(P)
elif method == "BK21_PLG":
out = BK21_PLG(df).compute_temperature(P)
elif method == "BK21_SPL":
out = BK21_SPL(df).compute_temperature(P)
elif method == "BK21_GNT":
out = BK21_GNT(df).compute_temperature(P)
elif method == "BK21":
out = BK21(df).compute_temperature(P)
elif method == "SD20":
out = SD20(df).compute_temperature(P)
else:
out = thermobar(df).compute_temperature(P)
return out
[docs]def compute_sample_pressure(df, method="PF16", T=1300., min_SiO2=0.):
"""
Calculate temperate of melt equilibration
Parameters
----------
df : pandas dataframe.
Dataframe containing the sample primary composition.
Should contain only one row. To use with a multi-row dataframe use
df.apply().
method: sring
choice of thermobaric method
PF16 = Plank & Forsyth (2016), G3
L09 = Lee et al., (2009), G3
P08 = Putirka (2008) Eq 42.
T : float
Temperature in oC
Returns
-------
PT : pandas dataframe
The calculated temperature(s) in oC,
assumed pressures in GPa and associated errors.
"""
if df['SiO2_primary_wt'] < min_SiO2:
out = {'P': np.nan, 'P_err': np.nan, 'T': np.nan, 'T_err': np.nan}
elif inspect.isclass(method):
out = method(df).compute_pressure(T)
elif method == "PF16":
out = PF16(df).compute_pressure(T)
elif method == "L09":
out = L09(df).compute_pressure(T)
elif method == "P08":
out = P08(df).compute_pressure(T)
else:
out = thermobar(df).compute_temperature(T)
return out