Source code for MagmaPandas.MagmaFrames.magnetite

import elementMass as e
import pandas as pd
from typing_extensions import Self

from MagmaPandas.enums import Datatype, Unit
from MagmaPandas.MagmaFrames.magmaFrame import MagmaFrame
from MagmaPandas.parse_io import check_components

_endmember_required_elements = ["MgO", "MnO", "FeO", "Fe2O3", "TiO2", "Al2O3"]


[docs] class Magnetite(MagmaFrame): """ Subclass of :py:class:`~MagmaPandas.MagmaFrames.magmaFrame.MagmaFrame` extended with magnetite specific methods. """
[docs] def endmembers(self): """ Calculations according to Lindsley, as implemented in QUILF """ composition = check_components( composition=self, components=_endmember_required_elements ) cations = composition.cations(norm_to=3) magnetite = ( cations[["Mg", "Mn", "Fe"]].sum(axis=1) - 2 * cations["Ti"] - cations["Al"] / 2 ) / 3 mg_ulvospinel = cations["Mg"] / 2 mn_ulvospinel = cations["Mn"] / 2 ulvospinel = cations["Ti"] - mn_ulvospinel - mg_ulvospinel total = magnetite + ulvospinel + mg_ulvospinel ulvospinel = (ulvospinel + mg_ulvospinel) / total magnetite = 1 - ulvospinel return pd.DataFrame( {"magnetite": magnetite, "ulvospinel": ulvospinel}, index=self.index )
[docs] def Fe_speciation(self) -> Self: """ Calculations according to Lindsley, as implemented in QUILF """ # TODO add code to catch when total iron is given as Fe2O3 old_datatype = self._datatype elements = {Datatype.OXIDE: ("FeO", "Fe2O3"), Datatype.CATION: ("Fe", "Fe3")}[ old_datatype ] if all(c in self.elements for c in elements): return self composition = check_components( composition=self, components=_endmember_required_elements ) cations = composition.cations(normalise=False) totals = cations["total"] cations_norm = cations.div(totals, axis=0) * 3 # normalised to 3 cations total magnetite = ( cations_norm[["Mg", "Mn", "Fe"]].sum(axis=1) - 2 * cations_norm["Ti"] - cations_norm["Al"] / 2 ) / 3 Fe3 = 2 * magnetite Fe2 = ( magnetite + 2 * cations_norm["Ti"] + cations_norm["Al"] / 2 - cations_norm["Mg"] - cations_norm["Mn"] ) # cations_norm = cations_norm.drop(columns=["Fe"]) cations_norm["Fe3"] = Fe3 cations_norm["Fe"] = Fe2 cations_Fe_calc = (cations_norm / 3).mul(totals, axis=0).recalculate() if old_datatype == Datatype.CATION: return cations_Fe_calc oxide_wt_pc = cations_Fe_calc.oxides(normalise=False).wt_pc(normalise=False) oxide_wt_pc["total"] = oxide_wt_pc[oxide_wt_pc.elements].sum(axis=1) # oxide_names = e.get_oxide_names(cations_Fe_calc.elements) # oxide_weights = e.compound_weights(oxide_names) # cation_amounts = e.cation_numbers(oxide_names) # oxide_wt_pc = cations_Fe_calc.rename( # columns={ # cation: oxide # for cation, oxide in zip(cations_Fe_calc.elements, oxide_names) # } # ).recalculate() # oxide_wt_pc[oxide_wt_pc.elements] = ( # oxide_wt_pc[oxide_wt_pc.elements] # .mul(oxide_weights, axis=1) # .div(cation_amounts, axis=1) # ) # oxide_wt_pc._units = Unit.WT_PERCENT # oxide_wt_pc._datatype = Datatype.OXIDE return oxide_wt_pc