Source code for fO2calculate.batch_calculate

import pandas as pd
import warnings as w
import numpy as np

from fO2calculate import core
from fO2calculate import sample_class
from fO2calculate import batchfile
from fO2calculate import calculate

[docs]class BatchFile(batchfile.BatchFile): """Performs model functions on a batchfile.BatchFile object """ pass
[docs] def calculate_dIW(self, temperature, pressure=None, returnlogfO2="automatic", interactions=core.standard_interactions, **kwargs): """ Calculates the fO2 of all samples in a BatchFile in terms of number of log units from the iron-wüstite buffer (dIW). Parameters ---------- temperature: float, int, or str Temperature in degrees C. Can be passed as float, in which case the passed value is used as the temperature for all samples. Alternatively, temperature information for each individual sample may already be present in the BatchFile object. If so, pass the str value corresponding to the column title in the BatchFile object. pressure: float, int, or str Pressure in bars. Only required if it is desired that the fO2 be returned both as dIW and as logfO2. Can be passed as float, in which case the passed value is used as the pressure for all samples. Alternatively, pressure information for each individual sample may already be present in the BatchFile object. If so, pass the str value corresponding to the column title in the BatchFile object. returnlogfO2: str or bool If set to True, function will return fO2 values both in terms of dIW and as logfO2. If True, a pressure must also be passed. If set to "automatic" (the default), will be set to True if a pressure is passed or set to False if no pressure is passed. interactions: list OPTIONAL. List of strings of element names. Elements are solutes in a metal Fe liquid alloy for which interaction parameters are known and for which the user wishes to calculate the effects of interaction within the alloy. Elements need not be infinitely dilute. Compositional and temperature ranges for which interaction parameters are known are given in the interaction_parameters script within this library. Returns ------- pandas DataFrame Original data passed plus newly calculated dIW values are returned. """ batch_data = self.get_data().copy() if isinstance(temperature, str): file_has_temp = True temp_name = temperature elif isinstance(temperature, float) or isinstance(temperature, int): file_has_temp = False else: raise core.InputError("temperature must be type str, int, or float") if isinstance(pressure, str): file_has_pressure = True pressure_name = pressure if returnlogfO2 == "automatic": returnlogfO2 = True elif isinstance(pressure, float) or isinstance(pressure, int): file_has_pressure = False if returnlogfO2 == "automatic": returnlogfO2 = True elif pressure is None: file_has_pressure = False if returnlogfO2 == "automatic": returnlogfO2 = False else: raise core.InputError("If returnlogfO2 is True, you must " + "also pass a pressure.") else: raise core.InputError("pressure must be type None, str, int, or" + " float") dIW_vals = [] logfO2_vals = [] warnings = [] iterno = 0 for index, row in batch_data.iterrows(): iterno += 1 percent = iterno/len(batch_data.index) batchfile.status_bar.status_bar(percent, index) try: if file_has_temp: temperature = row[temp_name] # Get sample comps as Sample class with defaults sample_comp = self.get_sample_composition(index, units='wtpt', asSampleClass=True, how='combined') sample_comp.set_default_units(self.default_units) sample_comp.set_default_normalization( self.default_normalization) # Run the calculation calc = calculate.calculate_dIW(sample=sample_comp, temperature=temperature, interactions=interactions, **kwargs) dIW_vals.append(calc.result) except Exception: dIW_vals.append(np.nan) warnings.append("Calculation Failed.") try: # Also return logfO2 if called for if returnlogfO2 is True: if file_has_pressure: pressure = row[pressure_name] dIW = calc.result logfO2 = calculate.calc_logfO2_from_IW(pressure=pressure, temperature=temperature, dIW=dIW) logfO2_vals.append(logfO2) except Exception: logfO2_vals.append(np.nan) batch_data["dIW_Calculated"] = dIW_vals if returnlogfO2 is True: batch_data["logfO2_dIW"] = logfO2_vals if warnings: batch_data["Warnings"] = warnings else: pass if file_has_temp is False: batch_data["Temperature_C_Modeled"] = [temperature]*len(batch_data.index) if file_has_pressure is False and pressure is not None: batch_data["Pressure_Modeled"] = [pressure]*len(batch_data.index) return batch_data
[docs] def calculate_dSiSiO2(self, temperature, aSiO2, pressure=None, returnlogfO2="automatic", returndIW="automatic", interactions=core.standard_interactions, **kwargs): """ Calculates the fO2 of all samples in a BatchFile in terms of number of log units from the Si-SiO2 buffer. Parameters ---------- temperature: float, int, or str Temperature in degrees C. Can be passed as float, in which case the passed value is used as the temperature for all samples. Alternatively, temperature information for each individual sample may already be present in the BatchFile object. If so, pass the str value corresponding to the column title in the BatchFile object. aSiO2: float, int, or str Activity of SiO2 in the melt. Can be passed as float, in which case the passed value is used as the aSiO2 for all samples. Alternatively, aSiO2 information for each individual sample may already be present in the BatchFile object. If so, pass the str value corresponding to the column title in the BatchFile object. pressure: float, int, or str Pressure in bars. Only required if it is desired that the fO2 be returned both as dSiSiO2 and as logfO2. Can be passed as float, in which case the passed value is used as the pressure for all samples. Alternatively, pressure information for each individual sample may already be present in the BatchFile object. If so, pass the str value corresponding to the column title in the BatchFile object. returnlogfO2: str or bool If set to True, function will return fO2 values both in terms of dSiSiO2 and as logfO2. If True, a pressure must also be passed. If set to "automatic" (the default), will be set to True if a pressure is passed or set to False if no pressure is passed. returndIW: str or bool If set to True, function will return fO2 values both in terms of dSiSiO2 and as dIW. If True, a pressure must also be passed. If set to "automatic" (the default), will be set to True if a pressure is passed or set to False if no pressure is passed. interactions: list OPTIONAL. List of strings of element names. Elements are solutes in a metal Fe liquid alloy for which interaction parameters are known and for which the user wishes to calculate the effects of interaction within the alloy. Elements need not be infinitely dilute. Compositional and temperature ranges for which interaction parameters are known are given in the interaction_parameters script within this library. Returns ------- pandas DataFrame Original data passed plus calculated dSiSiO2 values are returned. """ batch_data = self.get_data().copy() if isinstance(temperature, str): file_has_temp = True temp_name = temperature elif isinstance(temperature, float) or isinstance(temperature, int): file_has_temp = False else: raise core.InputError("temperature must be type str, int, or float") if isinstance(aSiO2, str): file_has_aSiO2 = True aSiO2_name = aSiO2 elif isinstance(aSiO2, float) or isinstance(aSiO2, int): file_has_aSiO2 = False else: raise core.InputError("aSiO2 must be type str, int, or float") if isinstance(pressure, str): file_has_pressure = True pressure_name = pressure if returnlogfO2 == "automatic": returnlogfO2 = True if returndIW == "automatic": returndIW = True elif isinstance(pressure, float) or isinstance(pressure, int): file_has_pressure = False if returnlogfO2 == "automatic": returnlogfO2 = True if returndIW == "automatic": returndIW = True elif pressure is None: file_has_pressure = False if returnlogfO2 == "automatic": returnlogfO2 = False if returndIW == "automatic": returndIW = False else: raise core.InputError("If returnlogfO2 or returndIW is True," + " you must also pass a pressure.") else: raise core.InputError("pressure must be type None, str, int, or" + " float") dSiSiO2_vals = [] logfO2_vals = [] dIW_vals = [] warnings = [] iterno = 0 for index, row in batch_data.iterrows(): iterno += 1 percent = iterno/len(batch_data.index) batchfile.status_bar.status_bar(percent, index) try: if file_has_temp: temperature = row[temp_name] if file_has_aSiO2: aSiO2 = row[aSiO2_name] # Get sample comps as Sample class with defaults sample_comp = self.get_sample_composition(index, units='wtpt', asSampleClass=True, how='combined') sample_comp.set_default_units(self.default_units) sample_comp.set_default_normalization( self.default_normalization) # Run the calculation calc = calculate.calculate_dSiSiO2(sample=sample_comp, temperature=temperature, aSiO2=aSiO2, interactions=interactions, **kwargs) dSiSiO2_vals.append(calc.result) except Exception: dSiSiO2_vals.append(np.nan) warnings.append("Calculation Failed.") # Also return logfO2/dIW if called for if returndIW is True or returnlogfO2 is True: try: if file_has_pressure: pressure = row[pressure_name] dSiSiO2 = calc.result logfO2 = calculate.calc_logfO2_from_SiSiO2(pressure=pressure, temperature=temperature, dSiSiO2=dSiSiO2) logfO2_vals.append(logfO2) if returndIW is True: dIW = calculate.calc_dIW_from_logfO2(pressure=pressure, temperature=temperature, logfO2=logfO2) dIW_vals.append(dIW) except Exception: logfO2_vals.append(np.nan) dIW_vals.append(np.nan) batch_data["dSiSiO2_Calculated"] = dSiSiO2_vals if returnlogfO2 is True: batch_data["logfO2_dSiSiO2"] = logfO2_vals if returndIW is True: batch_data["dIW_SiSiO2"] = dIW_vals if warnings: batch_data["Warnings"] = warnings else: pass if file_has_temp is False: batch_data["Temperature_C_Modeled"] = [temperature]*len(batch_data.index) if file_has_aSiO2 is False: batch_data["aSiO2_Modeled"] = [aSiO2]*len(batch_data.index) if file_has_pressure is False and pressure is not None: batch_data["Pressure_Modeled"] = [pressure]*len(batch_data.index) return batch_data
[docs] def calculate_gamma_Fe_metal(self, temperature, interactions=core.standard_interactions, print_warnings=False, **kwargs): """ Calculates the activity coefficient, gamma, for iron. Interaction parameters epsilon are computed for all elements passed to interactions, so long as interaction parameter values are known. Parameters ---------- temperature: float, int, or str Temperature in degrees C. Can be passed as float, in which case the passed value is used as the temperature for all samples. Alternatively, temperature information for each individual sample may already be present in the BatchFile object. If so, pass the str value corresponding to the column title in the BatchFile object. interactions: list OPTIONAL. List of strings of element names. Elements are solutes in a metal Fe liquid alloy for which interaction parameters are known and for which the user wishes to calculate the effects of interaction within the alloy. Elements need not be infinitely dilute. Compositional and temperature ranges for which interaction parameters are known are given in the interaction_parameters script within this library. print_warnings: bool OPTIONAL. Default is True. If set to True, any warnings related to the lack of compositional data or interaction parameters will be printed. Returns ------- pandas DataFrame Original data passed plus newly calculated values are returned. """ batch_data = self.get_data().copy() if isinstance(temperature, str): file_has_temp = True temp_name = temperature elif isinstance(temperature, float) or isinstance(temperature, int): file_has_temp = False else: raise core.InputError("temperature must be type str, int, or float") gammaFe_vals = [] warnings = [] iterno = 0 for index, row in batch_data.iterrows(): iterno += 1 percent = iterno/len(batch_data.index) batchfile.status_bar.status_bar(percent, index) try: if file_has_temp: temperature = row[temp_name] # Get sample comps as Sample class with defaults sample_comp = self.get_sample_composition(index, units='wtpt', asSampleClass=True, how='combined') sample_comp.set_default_units(self.default_units) sample_comp.set_default_normalization( self.default_normalization) # Run the calculation calc = calculate.calculate_gamma_Fe_metal(sample=sample_comp, temperature=temperature, interactions=interactions, **kwargs) gammaFe_vals.append(calc.result) except Exception: gammaFe_vals.append(np.nan) warnings.append("Calculation Failed.") batch_data["gamma_Fe_metal"] = gammaFe_vals if warnings: batch_data["Warnings"] = warnings else: pass if file_has_temp is False: batch_data["Temperature_C_Modeled"] = [temperature]*len(batch_data.index) return batch_data
[docs] def calculate_gamma_solute_metal(self, temperature, species=core.standard_interactions, interactions=core.standard_interactions, gammaFe="calculate", print_warnings=False, **kwargs): """ Calculates the activity coefficient, gamma, for multiple solutes in an Fe-rich metal alloy. Interaction parameters epsilon are computed for all elements passed to interactions, so long as interaction parameter values are known. Parameters ---------- sample: Sample class Composition of silicate melt and metal phases as a sample object. species: str String of the name of the element for which to calculate gamma temperature: float, int, or str Temperature in degrees C. Can be passed as float, in which case the passed value is used as the temperature for all samples. Alternatively, temperature information for each individual sample may already be present in the BatchFile object. If so, pass the str value corresponding to the column title in the BatchFile object. gammaFe: float, int, or str OPTIONAL. Default is "calculate" in which case the gammaFe value will be calculated here. If the gammaFe value is already known, it can be passed here to avoid having to calculate it again. Can be passed as float or int, in which case the passed value is used as the gammaFe for all samples. Alternatively, gammaFe values for each individual sample may already be present in the BatchFile object. If so, pass the str value corresponding to the column title in the BatchFile object. elements: list OPTIONAL. List of elements for which to calculate gamma values, if that list is different than the list of interactions. Default value is None, in which case the elements list = interactions. interactions: list OPTIONAL. List of strings of element names. Elements are solutes in a metal Fe liquid alloy for which interaction parameters are known and for which the user wishes to calculate the effects of interaction within the alloy. Elements need not be infinitely dilute. Compositional and temperature ranges for which interaction parameters are known are given in the interaction_parameters script within this library. print_warnings: bool OPTIONAL. Default is True. If set to True, any warnings related to the lack of compositional data or interaction parameters will be printed. Returns ------- pandas DataFrame Original data passed plus newly calculated values are returned. """ batch_data = self.get_data().copy() if isinstance(temperature, str): file_has_temp = True temp_name = temperature elif isinstance(temperature, float) or isinstance(temperature, int): file_has_temp = False else: raise core.InputError("temperature must be type str, int, or float") if isinstance(gammaFe, str): if gammaFe == "calculate": file_has_gammaFe = False else: file_has_gammaFe = True gammaFe_name = gammaFe elif isinstance(gammaFe, float) or isinstance(gammaFe, int): file_has_gammaFe = False else: raise core.InputError("If passed, gammaFe argument must be" + " 'calculate' or type float, int, or str." + " Not sure what you want here? Don't pass" + " this argument.") if isinstance(species, str): species = [species] specno = 0 iterno = 0 for spec in species: specno += 1 gamma_solute_vals = [] for index, row in batch_data.iterrows(): iterno += 1 percno = iterno*specno length = len(batch_data.index) * len(species) percent = iterno/length batchfile.status_bar.status_bar(percent, index) if file_has_temp is True: temperature = row[temp_name] if file_has_gammaFe is True: gammaFe = row[gammaFe_name] sample_comp = self.get_sample_composition(index, units='wtpt', asSampleClass=True, how='combined', silence_warnings=True) # run the calculation calc = calculate.calculate_gamma_solute_metal(sample=sample_comp, species=spec, temperature=temperature, gammaFe=gammaFe, interactions=interactions, print_warnings=print_warnings, **kwargs) gamma_solute_vals.append(calc.result) column_head_title = "gamma_" + spec + "_metal" batch_data[column_head_title] = gamma_solute_vals if file_has_temp is False: batch_data["Temperature_C_Modeled"] = [temperature]*len(batch_data.index) return batch_data