Source code for MagmaPandas.MagmaFrames.olivine

import pandas as pd
from typing_extensions import Self

from MagmaPandas.configuration import configuration
from MagmaPandas.enums import Unit
from MagmaPandas.Fe_redox.Fe3Fe2_models import Fe3Fe2_models_dict
from MagmaPandas.MagmaFrames.magmaFrame import MagmaFrame
from MagmaPandas.MagmaFrames.melt import Melt
from MagmaPandas.MagmaSeries import MagmaSeries


[docs] class Olivine(MagmaFrame): """ Subclass of :py:class:`~MagmaPandas.MagmaFrames.magmaFrame.MagmaFrame` extended with olivine specific methods. """ # @property # def _constructor(self): # """This is the key to letting Pandas know how to keep # derivatives of `MagmaBase` the same type as yours. It should # be enough to return the name of the Class. However, in # some cases, `__finalize__` is not called and `new attributes` are # not carried over. We can fix that by constructing a callable # that makes sure to call `__finalize__` every time.""" # def _c(*args, weights=None, **kwargs): # if weights is None: # weights = self._weights.copy(deep=True) # return Olivine(*args, weights=weights, **kwargs).__finalize__(self) # return _c @property def forsterite(self) -> pd.Series: """ Forsterite contents """ if self._units == Unit.WT_PERCENT: moles = self.moles() else: moles = self type = self._datatype.value Mg = {"oxide": "MgO", "cation": "Mg"} Fe = {"oxide": "FeO", "cation": "Fe"} self.recalculate(inplace=True) return pd.Series( moles[Mg[type]] / (moles[Fe[type]] + moles[Mg[type]]), name="Fo#", ) @property def formula(self) -> Self: """ Mineral formulas normalised to 4 O p.f.u. """ return self.mineral_formula(O=4)
[docs] def calculate_FeMg_Kd( self, melt_wtpc: Melt | MagmaSeries, T_K, P_bar=1, **kwargs ) -> pd.Series: """ Calculate Fe-Mg exchange coefficients (Kd) based on measured olivine and melt compositions as (Fe2+/Mg)olivine / (Fe2+/Mg)liquid """ if (not self.index.equals(melt_wtpc.index)) & ( melt_wtpc.isinstance(pd.DataFrame) ): raise AttributeError("olivine and melt indeces do not match") dfO2 = kwargs.get("dfO2", configuration.dfO2) Fe3Fe2_model_name = kwargs.get("Fe3Fe2_model", configuration.Fe3Fe2_model) Fe3Fe2_model = Fe3Fe2_models_dict[Fe3Fe2_model_name] melt_mol_fractions = melt_wtpc.moles() olivine_mol_fractions = self.moles() Fe3Fe2 = Fe3Fe2_model.calculate_Fe3Fe2( mol_fractions=melt_mol_fractions, T_K=T_K, P_bar=P_bar, dfO2=dfO2, **kwargs, ) Fe_melt_total = 1 + Fe3Fe2 Fe2_FeTotal_melt = 1 / Fe_melt_total Fe2_melt = melt_mol_fractions["Fe"] * Fe2_FeTotal_melt Kd = (olivine_mol_fractions["Fe"] / olivine_mol_fractions["Mg"]) / ( Fe2_melt / melt_mol_fractions["Mg"] ) return Kd