Source code for pedophysics.predict.salinity
import numpy as np
from scipy.optimize import minimize
from pedophysics.pedophysical_models.water_ec import SenGoode
from .temperature import *
from .water_ec import *
[docs]def Salinity(soil):
"""
Calculate missing values of soil.df.salinity and return
If any value of the salinity attribute is missing (NaN), it will first compute
the missing values by optimizing the SenGoode function based on the soil's water
electrical conductivity and temperature.
Parameters
----------
soil : object
A custom soil object that contains:
- temperature : array-like
Soil bulk temperature [K]
- salinity : array-like
Soil salinity (NaCl) of the bulk pore fluid [mol/L]
- water_ec : array-like
Soil water real electrical conductivity [S/m]
- df : DataFrame
Data Frame containing all the quantitative information of soil array-like attributes for each state
- info : DataFrame
Data Frame containing descriptive information about how each array-like attribute was determined or modified.
- n_states : int
Number of states or records in the dataframe.
Returns
-------
np.ndarray
soil.df.salinity.values: an array of soil salinity (NaCl) of the bulk pore fluid values
Notes
-----
This function modifies the soil object in-place, updating the `df` dataframe and `info`
dataframe if necessary.
External functions
--------
WaterEC : Compute missing values of soil.df.water_ec and return
Temperature : Set missing values of soil.df.temperature and return
SenGoode : Calculate soil water real electrical conductivity using the Sen and Goode model and return
Example
-------
>>> sample = Soil(water_ec = 0.1)
>>> sample.df.salinity
0 NaN
Name: salinity, dtype: float64
>>> Salinity(sample)
>>> sample.df.salinity
0 0.00846
Name: salinity, dtype: float64
"""
if any(np.isnan(soil.df.salinity[x])for x in range(soil.n_states)): # Go over if any value is missing
WaterEC(soil)
Temperature(soil)
sal = []
def objective_salinity(salinity, water_ec, temperature):
return (SenGoode(temperature, salinity) - water_ec)**2
for x in range(soil.n_states):
result = minimize(objective_salinity, 0.01, args=(soil.df.water_ec[x], soil.df.temperature[x]), bounds=[(0, 1)])
sal.append(np.nan if np.isnan(result.fun) else round(result.x[0], soil.roundn+2))
missing_salinity_before = soil.df['salinity'].isna()
soil.df['salinity'] = [sal[x] if np.isnan(soil.df.salinity[x])
else soil.df.salinity[x] for x in range(soil.n_states)]
missing_salinity_after = soil.df['salinity'].isna()
soil.info['salinity'] = [str(soil.info.salinity[x]) + (
"--> Calculated using SenGood function in predict.Salinity"
if missing_salinity_before[x] and not missing_salinity_after[x]
else "--> Provide salinity; otherwise, water_ec"
if missing_salinity_before[x] and missing_salinity_after[x]
else "")
if missing_salinity_before[x]
else soil.info.salinity[x]
for x in range(soil.n_states)]
return soil.df.salinity.values