from hestia_earth.calculation.abstract_model import Model
from hestia_earth.calculation.utils import summation
from hestia_earth.calculation.data.constants.generic import ATOMIC_WEIGHT_CONVERSIONS
from hestia_earth.utils.api import download_hestia
MODEL_KEY = 'n2OToAirFertilizerAndExcretaDirectAndIndirectIpcc2006'
[docs]class N2OToAirFertilizerAndExcretaIndirectIpcc2006(Model):
def __init__(self):
# Define model tier
self.tier = 1
self.term = download_hestia(MODEL_KEY)
# Define model requirements
self.inorgN_total = None
self.orgN_total = None
self.excretaN_total = None
self.nh3ToAirInorganicFertilizer = None
self.nh3ToAirOrganicFertilizer = None
self.nh3ToAirExcreta = None
self.nh3ToAirCropResidueDecomposition = None
self.noxToAirInorganicFertilizer = None
self.noxToAirOrganicFertilizer = None
self.noxToAirExcreta = None
self.noxToAirCropResidueDecomposition = None
self.no3ToGroundwaterInorganicFertilizer = None
self.no3ToGroundwaterOrganicFertilizer = None
self.no3ToGroundwaterExcreta = None
self.no3ToGroundwaterCropResidueDecomposition = None
# Instantiate variables
self.n2OToAirInorganicFertilizerIndirect = None
self.n2OToAirOrganicFertilizerIndirect = None
self.n2OToAirExcretaIndirect = None
self.n2OToAirCropResidueDecompositionIndirect = None
# Define model coeffients
self.ef_nh3nox_no2 = 0.01 * ATOMIC_WEIGHT_CONVERSIONS['Conv_Mol_N2ON_N2O']
self.ef_no3n_no2 = 0.0075 * ATOMIC_WEIGHT_CONVERSIONS['Conv_Mol_N2ON_N2O']
self.ef_frac_vol_inorgN = 0.1
self.ef_frac_vol_orgN = 0.2
self.conv_no3n_no3 = ATOMIC_WEIGHT_CONVERSIONS['Conv_Mol_NO3N_NO3']
self.conv_nh3n_nh3 = ATOMIC_WEIGHT_CONVERSIONS['Conv_Mol_NH3N_NH3']
self.conv_non_no = ATOMIC_WEIGHT_CONVERSIONS['Conv_Mol_NON_NO']
def calculate_n2OToAirInorganicFertilizerIndirect(self):
# Calculate N2O emissions
self.n2OToAirInorganicFertilizerIndirect =\
self.ef_nh3nox_no2 * (self.inorgN_total * self.ef_frac_vol_inorgN
if self.noxToAirInorganicFertilizer == {} or self. nh3ToAirInorganicFertilizer == {}
else self.nh3ToAirInorganicFertilizer/self.conv_nh3n_nh3
+ self.noxToAirInorganicFertilizer/self.conv_non_no) + self.ef_no3n_no2 *\
self.no3ToGroundwaterInorganicFertilizer/self.conv_no3n_no3
return self.n2OToAirInorganicFertilizerIndirect
def calculate_n2OToAirOrganicFertilizerIndirect(self):
# Calculate N2O emissions
self.n2OToAirOrganicFertilizerIndirect =\
self.ef_nh3nox_no2 * (self.orgN_total * self.ef_frac_vol_orgN if self.noxToAirOrganicFertilizer == {} or
self.nh3ToAirOrganicFertilizer == {}
else self.nh3ToAirOrganicFertilizer/self.conv_nh3n_nh3
+ self.noxToAirOrganicFertilizer/self.conv_non_no) + self.ef_no3n_no2 *\
self.no3ToGroundwaterOrganicFertilizer/self.conv_no3n_no3
return self.n2OToAirOrganicFertilizerIndirect
def calculate_n2OToAirExcretaIndirect(self):
# Calculate N2O emissions
self.n2OToAirExcretaIndirect =\
self.ef_nh3nox_no2 * (self.excretaN_total * self.ef_frac_vol_orgN if self.noxToAirExcreta == {} or
self.nh3ToAirExcreta == {}
else self.nh3ToAirExcreta/self.conv_nh3n_nh3
+ self.noxToAirExcreta/self.conv_non_no) + self.ef_no3n_no2 *\
self.no3ToGroundwaterExcreta/self.conv_no3n_no3
return self.n2OToAirExcretaIndirect
def calculate_n2OToAirCropResidueDecompositionIndirect(self):
# Calculate N2O emissions
nh3ToAirCropResidueDecomposition = self.nh3ToAirCropResidueDecomposition \
if self.nh3ToAirCropResidueDecomposition != {} else 0
self.n2OToAirCropResidueDecompositionIndirect =\
self.ef_nh3nox_no2 * (0 if self.noxToAirCropResidueDecomposition == {} else
nh3ToAirCropResidueDecomposition/self.conv_nh3n_nh3 +
self.noxToAirCropResidueDecomposition/self.conv_non_no) +\
self.ef_no3n_no2 * self.no3ToGroundwaterCropResidueDecomposition/self.conv_no3n_no3
return self.n2OToAirCropResidueDecompositionIndirect
def complete(self, completeness):
self.inorgN_total = 0 if self.inorgN_total == {} and completeness['fertilizer'] else self.inorgN_total
self.orgN_total = 0 if self.orgN_total == {} and completeness['fertilizer'] else self.orgN_total
self.excretaN_total = 0 if self.excretaN_total == {} and completeness['products'] else self.excretaN_total
def check_n2OToAirInorganicFertilizerIndirect(self, cycle):
# Check that we have all the inputs
inputs = cycle["inputs"].evalues()
self.inorgN_total = summation([sum(input["value"]) if "units" in input["term"] and
input["term"]["units"] == "kg N" and
input["term"]["termType"] == "inorganicFertilizer"
else {} for input in inputs])
self.nh3ToAirInorganicFertilizer = summation(cycle['emissions']['nh3ToAirInorganicFertilizer']['value'])
self.noxToAirInorganicFertilizer = summation(cycle['emissions']['noxToAirInorganicFertilizer']['value'])
self.no3ToGroundwaterInorganicFertilizer =\
summation(cycle['emissions']['no3ToGroundwaterInorganicFertilizer']['value'])\
self.complete(cycle['dataCompleteness'])
return self.inorgN_total != {} and self.no3ToGroundwaterInorganicFertilizer != {}
def check_n2OToAirOrganicFertilizerIndirect(self, cycle):
# Check that we have all the inputs
inputs = cycle['inputs'].evalues()
self.orgN_total = summation([sum(input['value']) if 'units' in input['term'] and
input['term']['units'] == 'kg N' and
input['term']['termType'] == 'organicFertilizer'
else {} for input in inputs])
self.nh3ToAirOrganicFertilizer = summation(cycle['emissions']['nh3ToAirOrganicFertilizer']['value'])
self.noxToAirOrganicFertilizer = summation(cycle['emissions']['noxToAirOrganicFertilizer']['value'])
self.no3ToGroundwaterOrganicFertilizer = \
summation(cycle['emissions']['no3ToGroundwaterOrganicFertilizer']['value'])
self.complete(cycle['dataCompleteness'])
return self.orgN_total != {} and self.no3ToGroundwaterOrganicFertilizer != {}
def check_n2OToAirExcretaIndirect(self, cycle):
# Check that we have all the products
products = cycle["products"].evalues()
self.excretaN_total = summation([sum(product["value"]) if "units" in product["term"] and
product["term"]["units"] == "kg N" and
product["term"]["termType"] == "animalProduct" else {}
for product in products])
self.nh3ToAirExcreta = summation(cycle['emissions']['nh3ToAirExcreta']['value'])
self.noxToAirExcreta = summation(cycle['emissions']['noxToAirExcreta']['value'])
self.no3ToGroundwaterExcreta = summation(cycle['emissions']['no3ToGroundwaterExcreta']['value'])
self.complete(cycle['dataCompleteness'])
return self.excretaN_total != {} and self.no3ToGroundwaterExcreta != {}
def check_n2OToAirCropResidueDecompositionIndirect(self, cycle):
# Check that we have all the products
self.nh3ToAirCropResidueDecomposition =\
summation(cycle['emissions']['nh3ToAirCropResidueDecomposition']['value'])
self.noxToAirCropResidueDecomposition =\
summation(cycle['emissions']['noxToAirCropResidueDecomposition']['value'])
self.no3ToGroundwaterCropResidueDecomposition =\
summation(cycle['emissions']['no3ToGroundwaterCropResidueDecomposition']['value'])\
self.complete(cycle['dataCompleteness'])
return self.no3ToGroundwaterCropResidueDecomposition != {}