Source code for pygypsy.basal_area_factor

"""Basal Area correction factor estimators"""
# TODO: validate that none of the variables taken from kwargs are missing
import logging
import numpy as np

from pygypsy.basal_area_simulate import (
    sim_basal_area_aw,
    sim_basal_area_sw,
    sim_basal_area_sb,
    sim_basal_area_pl,
)


LOGGER = logging.getLogger(__name__)


[docs]def get_basal_area_factors_for_all_species(**kwargs): f_sb = 0 f_aw = 0 f_sw = 0 f_pl = 0 if kwargs['N0_Aw'] > 0: f_aw = estimate_basal_area_factor_aw(**kwargs) if kwargs['N0_Sb'] > 0: f_sb = estimate_basal_area_factor_sb(**kwargs) if kwargs['N0_Sw'] > 0: f_sw = estimate_basal_area_factor_sw(**kwargs) if kwargs['N0_Pl'] > 0: f_pl = estimate_basal_area_factor_pl(**kwargs) return { 'f_Aw':f_aw, 'f_Sb':f_sb, 'f_Sw':f_sw, 'f_Pl':f_pl, }
[docs]def estimate_basal_area_factor_aw(**kwargs): '''This function guarantees that the trajectory of the species basal area passes through the basal area measured when the data was collected (inventory data) There is a trade-off between the precision one wants this estimate, which is given by the parameter - acceptableDiff -, and the time the convergence time :param float startTage: Clock that uses the oldest species as a reference to become the stand age :param float SI_bh_Aw: site index of species Aw :param float N_bh_AwT: density of sp Aw at time T (it varies over time) :param float BA_Aw0: basal area of Aw at breast height age, assumed to be very small :param float BA_AwT: basal area of Aw at time T :param float SDF_Aw0: Stand Density Factor of species Aw :param float N0_Aw: initial density of species Aw at breast height age :param list densities: array of 'densities' objects ''' age_at_observation = kwargs['startTage'] site_index = kwargs['SI_bh_Aw'] present_density = kwargs['N_bh_AwT'] basal_area_at_bh_age = kwargs['BA_Aw0'] present_basal_area = kwargs['BA_AwT'] sdf_aw = kwargs['SDF_Aw0'] density_at_bh_age = kwargs['N0_Aw'] densities = kwargs['densities'] factor = 100 factor1 = 100 * factor tolerance = 0.01 * present_basal_area within_tolerance = False iter_count = 0 while not within_tolerance: ba_est = sim_basal_area_aw(age_at_observation, site_index, density_at_bh_age, basal_area_at_bh_age, sdf_aw, factor, densities, use_correction_factor_future=False, stop_at_initial_age=True, fix_proportion_and_density_to_initial_age=False, species_proportion_at_bh_age=None, present_density=present_density)[-1] if abs(present_basal_area - ba_est) < tolerance: within_tolerance = True else: if (present_basal_area - ba_est) < 0: factor1 = factor factor_p = factor \ * (1 \ + (np.log10(present_basal_area) - np.log10(abs(ba_est))) \ / (100*np.log10(abs(ba_est)))) factor = (factor_p+factor)/2 elif (present_basal_area - ba_est) > 0: factor = (factor+factor1)/2 iter_count += 1 if iter_count == 10000: LOGGER.warning(('Slow convergence with Basal Area: %s' ' and factor:%s '), ba_est, factor) break return factor
[docs]def estimate_basal_area_factor_sb(**kwargs): '''Black spruce basal area factor estimator This function guarantees that the trajectory of the species basal area passes through the basal area measured when the data was collected (inventory data) :param float startTage: Clock that uses the oldest species as a reference to become the stand age :param float SI_bh_Sb: site index of species Sb :param float N_bh_SbT: density of sp Sb at time T (it varies over time) :param float BA_Sb0: basal area of Sb at breast height age, assumed to be very small :param float BA_SbT: basal area of Sb at time T :param float N0_Sb: initial density of species Sb at breast height age :param float y2bh_Sb: time elapseed in years from zero to breast height age of sp Sb :param float startTageSb: species specific ages counted independently :param float SC_Sb: proportion of species Sb in the stand :param list densities: array of 'densities' objects ''' age_at_observation = kwargs['startTage'] site_index = kwargs['SI_bh_Sb'] densities = kwargs['densities'] density_at_bh_age = kwargs['N0_Sb'] basal_area_at_bh_age = kwargs['BA_Sb0'] present_basal_area = kwargs['BA_SbT'] species_proportion_at_bh_age = kwargs['SC_Sb'] present_density = kwargs['N_bh_SbT'] factor = 1.2 factor1 = 1.5 * factor tolerance = 0.1 within_tolerance = False iter_count = 0 while not within_tolerance: ba_est = sim_basal_area_sb(age_at_observation, site_index, density_at_bh_age, basal_area_at_bh_age, factor, densities, fix_proportion_and_density_to_initial_age=True, species_proportion_at_bh_age=species_proportion_at_bh_age, present_density=present_density, stop_at_initial_age=True)[-1] if abs(present_basal_area - ba_est) < tolerance: within_tolerance = True else: if (present_basal_area - ba_est) < 0: factor1 = factor factor_p = factor \ * ( 1 \ + (np.log10(present_basal_area) - np.log10(abs(ba_est))) \ / (10*np.log10(abs(ba_est)))) factor = (factor_p+factor)/2 elif (present_basal_area - ba_est) > 0: factor = (factor+factor1)/2 iter_count += 1 if iter_count == 1500: LOGGER.warning(('Slow convergence with Basal Area: %s' ' and factor:%s '), ba_est, factor) break return factor
[docs]def estimate_basal_area_factor_sw(**kwargs): '''White Spruce basal area factor estimator This function guarantees that the trajectory of the species basal area passes through the basal area measured when the data was collected (inventory data) :param float startTage: Clock that uses the oldest species as a reference to become the stand age :param float SI_bh_Sw: site index of species Sw :param float N_bh_SwT: density of sp Sw at time T (it varies over time) :param float BA_Sw0: basal area of Sw at breast height age, assumed to be very small :param float BA_SwT: basal area of Sw at time T :param float N0_Sw: initial density of species Sw at breast height age :param float y2bh_Sw: time elapseed in years from zero to breast height age of sp Sw :param float startTageSw: species specific ages counted independently :param float SC_Sw: proportion of species Sw in the stand :param float SDF_Pl0: Stand Density Factor of species Pl :param float SDF_Aw0: Stand Density Factor of species Aw :param float SDF_Sb0: Stand Density Factor of species Sb :param list densities: array of 'densities' objects ''' age_at_observation = kwargs['startTage'] site_index = kwargs['SI_bh_Sw'] densities = kwargs['densities'] density_at_bh_age = kwargs['N0_Sw'] species_proportion_at_bh_age = kwargs['SC_Sw'] sdf_aw = kwargs['SDF_Aw0'] sdf_pl = kwargs['SDF_Pl0'] sdf_sb = kwargs['SDF_Sb0'] basal_area_at_bh_age = kwargs['BA_Sw0'] present_basal_area = kwargs['BA_SwT'] present_density = kwargs['N_bh_SwT'] factor = 2.5 tolerance = 0.1 within_tolerance = False iter_count = 0 factor1 = 1.5 * factor while not within_tolerance: ba_est = sim_basal_area_sw(age_at_observation, site_index, density_at_bh_age, sdf_aw, sdf_pl, sdf_sb, basal_area_at_bh_age, factor, densities, fix_proportion_and_density_to_initial_age=True, species_proportion_at_bh_age=species_proportion_at_bh_age, present_density=present_density, stop_at_initial_age=True)[-1] if abs(present_basal_area - ba_est) < tolerance: within_tolerance = True else: if (present_basal_area - ba_est) < 0: factor1 = factor factor_p = factor \ * (1 \ + (np.log10(present_basal_area) - np.log10(abs(ba_est))) \ / (10*np.log10(abs(ba_est)))) factor = (factor_p+factor)/2 elif (present_basal_area - ba_est) > 0: factor = (factor + factor1)/2 iter_count += 1 if iter_count == 1500: LOGGER.warning(('Slow convergence with Basal Area: %s' ' and factor:%s '), ba_est, factor) break return factor
[docs]def estimate_basal_area_factor_pl(**kwargs): '''Lodgepole pine basal area factor estimator This function guarantees that the trajectory of the species basal area passes through the basal area measured when the data was collected (inventory data) :param float startTage: Clock that uses the oldest species as a reference to become the stand age :param float SI_bh_Pl: site index of species Pl :param float N_bh_PlT: density of sp Pl at time T (it varies over time) :param float BA_Pl0: basal area of Pl at breast height age, assumed to be very small :param float BA_PlT: basal area of Pl at time T :param float N0_Pl: initial density of species Pl at breast height age :param float y2bh_Pl: time elapseed in years from zero to breast height age of sp Pl :param float startTagePl: species specific ages counted independently :param float SC_Pl: proportion of species Pl in the stand :param float SDF_Sw0: Stand Density Factor of species Sw :param float SDF_Aw0: Stand Density Factor of species Aw :param float SDF_Sb0: Stand Density Factor of species Sb :param list densities: array of 'densities' objects ''' age_at_observation = kwargs['startTage'] site_index = kwargs['SI_bh_Pl'] density_at_bh_age = kwargs['N0_Pl'] densities = kwargs['densities'] sdf_aw = kwargs['SDF_Aw0'] sdf_sw = kwargs['SDF_Sw0'] sdf_sb = kwargs['SDF_Sb0'] basal_area_at_bh_age = kwargs['BA_Pl0'] present_basal_area = kwargs['BA_PlT'] species_proportion_at_bh_age = kwargs['SC_Pl'] present_density = kwargs['N_bh_PlT'] factor = 100.0 tolerance = 0.1 within_tolerance = False iter_count = 0 factor1 = 1.5 * factor while not within_tolerance: ba_est = sim_basal_area_pl(age_at_observation, site_index, density_at_bh_age, sdf_aw, sdf_sw, sdf_sb, basal_area_at_bh_age, factor, densities, fix_proportion_and_density_to_initial_age=True, species_proportion_at_bh_age=species_proportion_at_bh_age, present_density=present_density, stop_at_initial_age=True)[-1] if abs(present_basal_area - ba_est) < tolerance: within_tolerance = True else: if (present_basal_area - ba_est) < 0: factor1 = factor factor_p = factor * (present_basal_area / ba_est) factor = (factor_p+factor)/2 elif (present_basal_area - ba_est) > 0: factor = (factor + factor1)/2 iter_count += 1 if iter_count == 150: LOGGER.warning(('Slow convergence with Basal Area: %s' ' and factor:%s '), ba_est, factor) break return factor