def merch_classes_plot(self, plot: Plot): """ Function to calculate the wood uses values to the plot. That function is run by initialize and process_plot functions. """ plot_trees: list[Tree] = plot.short_trees_on_list( 'dbh', DESC) # stablish an order to calculate tree variables plot_unwinding = plot_veneer = plot_saw_big = plot_saw_small = plot_saw_canter = plot_post = plot_stake = plot_chips = 0 for tree in plot_trees: # for each tree, we are going to add the simple values to the plot value # plot_unwinding += tree.unwinding # plot_veneer += tree.veneer plot_saw_big += tree.saw_big plot_saw_small += tree.saw_small plot_saw_canter += tree.saw_canter # plot_post += tree.post # plot_stake += tree.stake plot_chips += tree.chips # plot.add_value('UNWINDING', plot_unwinding/1000) # now, we add the plot value to each variable, changing the unit to m3 # plot.add_value('VENEER', plot_veneer/1000) plot.add_value('SAW_BIG', plot_saw_big / 1000) plot.add_value('SAW_SMALL', plot_saw_small / 1000) plot.add_value('SAW_CANTER', plot_saw_canter / 1000) # plot.add_value('POST', plot_post/1000) # plot.add_value('STAKE', plot_stake/1000) plot.add_value('CHIPS', plot_chips / 1000)
def biomass_plot(self, plot: Plot): """ Function to calculate the wood uses values to the plot. That function is run by initialize and process_plot functions. """ plot_trees: list[Tree] = plot.short_trees_on_list( 'dbh', DESC) # stablish an order to calculate tree variables plot_wsw = plot_wsb = plot_w_cork = plot_wthickb = plot_wstb = plot_wb2_7 = plot_wb2_t = plot_wthinb = plot_wl = plot_wtbl = plot_wbl0_7 = plot_wr = plot_wt = 0 for tree in plot_trees: # for each tree, we are going to add the simple values to the plot value plot_wsw += tree.wsw # plot_wsb += tree.wsb # plot_w_cork += tree.w_cork plot_wthickb += tree.wthickb # plot_wstb += tree.wstb plot_wb2_7 += tree.wb2_7 # plot_wb2_t += tree.wb2_t # plot_wthinb += tree.wthinb # plot_wl += tree.wl plot_wtbl += tree.wtbl # plot_wbl0_7 += tree.wbl0_7 plot_wr += tree.wr plot_wt += tree.wt plot.add_value('WSW', plot_wsw / 1000) # Wsw # wsw = stem wood (Tn) # plot.add_value('WSB', plot_wsb/1000) # Wsb # wsb = stem bark (Tn) # plot.add_value('W_CORK', plot_w_cork/1000) # W Fresh Cork # w_cork = fresh cork biomass (Tn) plot.add_value('WTHICKB', plot_wthickb / 1000) # Wthickb # wthickb = Thick branches > 7 cm (Tn) # plot.add_value('WSTB', plot_wstb/1000) # Wstb # wstb = wsw + wthickb, stem + branches >7 cm (Tn) plot.add_value('WB2_7', plot_wb2_7 / 1000) # Wb2_7 # wb2_7 = branches (2-7 cm) (Tn) # plot.add_value('WB2_T', plot_wb2_t/1000) # Wb2_t # wb2_t = wb2_7 + wthickb; branches >2 cm (Tn) # plot.add_value('WTHINB', plot_wthinb/1000) # Wthinb # wthinb = Thin branches (2-0.5 cm) (Tn) # plot.add_value('WB05', plot_wb05) # wb05 = thinniest branches (<0.5 cm) (Kg) # plot.add_value('WL', plot_wl/1000) # Wl # wl = leaves (Tn) plot.add_value( 'WTBL', plot_wtbl / 1000) # Wtbl # wtbl = wthinb + wl; branches <2 cm and leaves (Tn) # plot.add_value('WBL0_7', plot_wbl0_7/1000) # Wbl0_7 # wbl0_7 = wb2_7 + wthinb + wl; branches <7 cm and leaves (Tn) plot.add_value('WR', plot_wr / 1000) # Wr # wr = roots (Tn) plot.add_value('WT', plot_wt / 1000) # Wt # wt = biomasa total (Tn)
def initialize(self, plot: Plot): """ Function that update the gaps on the information with the inventory data Site Index equation: Doc.: Álvarez JG, González AD, Soalleiro R, Barrio-Anta M (2005). Ecoregional site index models for Pinus pinaster in Galicia (northwestern Spain). Annals of Forest Science, 62(2), 115-127 Ref.: Álvarez et al. (2005) Height/Diameter equation: Doc.: Diéguez-Aranda U, Rojo A, Castedo-Dorado F, et al (2009). Herramientas selvícolas para la gestión forestal sostenible en Galicia. Forestry, 82, 1-16 Ref.: Diéguez-Aranda et al, 2009 """ print( '#----------------------------------------------------------------------------#' ) print( ' Pinus pinaster atlantica model (Galicia) is running ' ) print( '#----------------------------------------------------------------------------#' ) try: # errors inside that construction will be annodbhced # site index is defined as top height at a base age of 20 years, setting this value with 't2' I = 0 # dummy variable which assumes a value of 0 for the interior ecoregion and 1 for the coastal ecoregion. t1 = plot.age t2 = 20 z = (0.1352 + 0.0276 * I) * ((plot.dominant_h / t1)**( 0.9831 + 0.0940 * I)) * (t1**(-0.2108 - 0.0929 * I)) SI = plot.dominant_h * (1 - math.exp(-z * t2)) / ( (1 - math.exp(-z * t1))**(1.4202 + 0.0801 * I)) plot.add_value('SI', SI) plot_trees: list[Tree] = plot.short_trees_on_list( 'dbh', DESC) # stablish an order to calculate tree variables bal: float = 0 for tree in plot_trees: # for each tree... #-----------------------------------BASAL AREA-----------------------------------------# tree.add_value('bal', bal) # the first tree must receive 0 value (m2) tree.add_value( 'basal_area', math.pi * (tree.dbh / 2)** 2) # normal (at 1.30m) section (cm2) calculation tree.add_value('ba_ha', tree.basal_area * tree.expan / 10000) # basimetric area per ha (m2/ha) bal += tree.basal_area * tree.expan / 10000 # then, that value is acumulated tree.add_value( 'hd_ratio', tree.height * 100 / tree.dbh) # height/diameter ratio (%) calculation tree.add_value( 'normal_circumference', math.pi * tree.dbh ) # normal (at 1.30m) circumference (cm) calculation #-----------------------------------HEIGHT-----------------------------------------# if tree.height == 0: # if the tree hasn't height (m) value, it is calculated I = 0 # dummy variable which assumes a value of 0 for the interior ecoregion and 1 for the coastal ecoregion. h = (1.3**(1.894 + 1.469 * I) + (plot.dominant_h**(1.894 + 1.469 * I) - 1.3** (1.894 + 1.469 * I)) * ((1 - math.exp(-(0.04611 - 0.04734 * I) * tree.dbh)) / (1 - math.exp(-(0.04611 - 0.04734 * I) * plot.dominant_dbh))))**(1 / 1.633) tree.add_value('height', h) #-----------------------------------FUNCTIONS-----------------------------------------# self.crown( tree, plot, 'initialize') # activate crown variables calculation self.vol(tree, plot) # activate volume variables calculation self.merch_classes( tree) # activate wood uses variables calculation self.biomass(tree) # activate biomass variables calculation self.merch_classes_plot( plot) # activate wood uses (plot) variables calculation self.biomass_plot( plot) # activate biomass (plot) variables calculation except Exception: self.catch_model_exception()
def initialize(self, plot: Plot): """ Function that update the gaps on the information with the inventory data Height/Diameter equation: Doc.: Saldaña AMC (2010). Bases para la gestión de masas naturales de Pinus halepensis Mill. en el Valle del Ebro (Doctoral dissertation, Universidad Politécnica de Madrid) Ref.: Saldaña, 2010 SI equation: a) Doc.: Saldaña AMC (2010). Bases para la gestión de masas naturales de Pinus halepensis Mill. en el Valle del Ebro (Doctoral dissertation, Universidad Politécnica de Madrid) Ref.: Saldaña, 2010 Doc.: Rojo A, Saldaña, AM, Barrio-Anta M, Notivol-Paíno E, Gorgoso-Varela JJ (2017). Site index curves for natural Aleppo pine forests in the central Ebro valley (Spain) Ref.: Rojo et al, 2017 b) Doc.: Montero G, Cañellas I, Ruiz-Peinado R (2002). Growth and yield models for Pinus halepensis Mill. Forest Systems, 10(1), 179-201 Ref.: Montero et al, 2002 """ print( '#----------------------------------------------------------------------------#' ) print( ' Pinus halepensis model (Cataluña) is running ' ) print( '#----------------------------------------------------------------------------#' ) try: # errors inside that construction will be announced #-----------------------------------SI-----------------------------------------# # a) t2 = 60 # age to calculate SI part1 = plot.dominant_h + 16.3229 + math.sqrt( (plot.dominant_h - 16.3229)**2 + 8185.244 * plot.dominant_h * (plot.age**(-1.3097))) part2 = plot.dominant_h - 16.3229 + math.sqrt( (plot.dominant_h - 16.3229)**2 + 8185.244 * plot.dominant_h * (plot.age**(-1.3097))) SI = (part1) / (2 + (8185.244 * (t2**(-1.3097)) / (part2))) # b) # SI = 1.521453 * ((1 - math.exp(-0.203954*plot.age))**(1 / 1.046295)) # calculated to 80 years plot.add_value('SI', SI) # Site Index (m) calculation plot_wt = 0 plot_trees: list[Tree] = plot.short_trees_on_list( 'dbh', DESC) # stablish an order to calculate tree variables bal: float = 0 for tree in plot_trees: # for each tree... #-----------------------------------BASAL AREA-----------------------------------------# tree.add_value('bal', bal) # the first tree must receive 0 value (m2) tree.add_value( 'basal_area', math.pi * (tree.dbh / 2)** 2) # normal (at 1.30m) section (cm2) calculation tree.add_value('ba_ha', tree.basal_area * tree.expan / 10000) # basimetric area per ha (m2/ha) bal += tree.basal_area * tree.expan / 10000 # then, that value is acumulated tree.add_value( 'hd_ratio', tree.height * 100 / tree.dbh) # height/diameter ratio (%) calculation tree.add_value( 'normal_circumference', math.pi * tree.dbh ) # normal (at 1.30m) circumference (cm) calculation #-----------------------------------HEIGHT-----------------------------------------# if tree.height == 0: # if the tree hasn't height (m) value, it is calculated tree.add_value( 'height', 1.3 + (plot.mean_h - 1.3) * math.exp(0.3532 * (1 - plot.qm_dbh / tree.dbh)) * math.exp(0.0315 * (tree.dbh / plot.qm_dbh - 1 / tree.dbh))) #-----------------------------------FUNCTIONS-----------------------------------------# # self.crown(tree, plot, 'initialize') # activate crown variables calculation self.vol(tree, plot) # activate volume variables calculation self.merch_classes( tree) # activate wood uses variables calculation self.biomass(tree) # activate biomass variables calculation self.merch_classes_plot( plot) # activate wood uses (plot) variables calculation self.biomass_plot( plot) # activate biomass (plot) variables calculation except Exception: self.catch_model_exception()
def initialize(self, plot: Plot): """ Function that update the gaps on the information with the inventory data Height/Diameter equation: Doc.: Lizarralde I (2008). Dinámica de rodales y competencia en las masas de pino silvestre (Pinus sylvestris L.) y pino negral (Pinus pinaster Ait.) de los Sistemas Central e Ibérico Meridional. Tesis Doctoral. 230 pp Ref.: Lizarralde 2008 SI equation: Doc.: Bravo-Oviedo A, del Río M, Montero G (2004). Site index curves and growth model for Mediterranean maritime pine (Pinus pinaster Ait.) in Spain. Forest Ecology and Management, 201(2-3), 187-197 Ref.: Bravo-Oviedo et al. 2004 """ print( '#----------------------------------------------------------------------------#' ) print( ' Pinus pinaster mesogeensis model (Sistema Ibérico Meridional) is running ' ) print( '#----------------------------------------------------------------------------#' ) try: # errors inside that construction will be announced #-----------------------------------SI-----------------------------------------# t = 80 # site index is defined as top height at a base age of 80 years, settíng this value with 't' plot.add_value( 'SI', math.exp(4.016 + (math.log(plot.dominant_h) - 4.016) * math.pow(t / plot.age, -0.5031)) ) # Site Index (m) calculation plot_trees: list[Tree] = plot.short_trees_on_list( 'dbh', DESC) # stablish an order to calculate tree variables bal: float = 0 for tree in plot_trees: # for each tree... #-----------------------------------BASAL AREA-----------------------------------------# tree.add_value('bal', bal) # the first tree must receive 0 value (m2) tree.add_value( 'basal_area', math.pi * (tree.dbh / 2)** 2) # normal (at 1.30m) section (cm2) calculation tree.add_value('ba_ha', tree.basal_area * tree.expan / 10000) # basimetric area per ha (m2/ha) bal += tree.basal_area * tree.expan / 10000 # then, that value is acumulated tree.add_value( 'hd_ratio', tree.height * 100 / tree.dbh) # height/diameter ratio (%) calculation tree.set_value( 'normal_circumference', math.pi * tree.dbh ) # normal (at 1.30m) circumference (cm) calculation #-----------------------------------HEIGHT-----------------------------------------# if tree.height == 0: # if the tree hasn't height (m) value, it is calculated tree.add_value( 'height', (13 + (32.3287 + 1.6688 * plot.dominant_h * 10 - 0.1279 * plot.qm_dbh * 10) * math.exp(-11.4522 / math.sqrt(tree.dbh * 10))) / 10) #-----------------------------------FUNCTIONS-----------------------------------------# self.crown( tree, plot, 'initialize') # activate crown variables calculation self.vol(tree, plot) # activate volume variables calculation self.merch_classes( tree) # activate wood uses variables calculation self.biomass(tree) # activate biomass variables calculation self.merch_classes_plot( plot) # activate wood uses (plot) variables calculation self.biomass_plot( plot) # activate biomass (plot) variables calculation except Exception: self.catch_model_exception()
def initialize(self, plot: Plot): """ Function that update the gaps on the information with the inventory data SI equations: a) Doc.: Martín-Benito D, Gea-Izquierdo G, del Río M, Canellas I (2008). Long-term trends in dominant-height growth of black pine using dynamic models. Forest Ecology and Management, 256(5), 1230-1238 Ref.: Martín-Benito et al, 2008 b) Doc.: Palahí M, Grau JM (2003). Preliminary site index model and individual-tree growth and mortality models for black pine (Pinus nigra Arn.) in Catalonia (Spain). Forest Systems, 12(1), 137-148 Ref.: Palahí and Grau, 2003 Height-Diameter equation: a) Doc.: Palahí M, Grau JM (2003). Preliminary site index model and individual-tree growth and mortality models for black pine (Pinus nigra Arn.) in Catalonia (Spain). Forest Systems, 12(1), 137-148 Ref.: Palahí and Grau, 2003 """ print( '#----------------------------------------------------------------------------#' ) print( ' Pinus nigra model (Cataluña) is running ' ) print( '#----------------------------------------------------------------------------#' ) try: # errors inside that construction will be announced #-----------------------------------SI-----------------------------------------# # Empiezo calculando SI, necesario para el cálculo de la altura # a) en el cálculo de Xo, la raíz es negativa y peta el simulador --> en el paper explica que el modelo es viable a partir de 50 años # Xo = 0.5*(math.log(plot.dominant_h) + math.sqrt(- (math.log(plot.dominant_h))**2 + 4*43.73549*(plot.dominant_h**(-0.38048)))) # SI = math.exp(Xo)*math.exp((-43.73549*(plot.age**(-0.38048))) / Xo) # plot.add_value('SI', SI) # b) Utiliza diferencias de edades, y hay que introducir en h2 la edad a la que se quiere calcular el SI --> R2 = 0.98 # t2 y h2 son del momento al que se avanza; t1 y h1 los momentos presentes # es la del mismo estudio de donde se usan los crecimientos --> SE QUEDA ESTA DE MOMENTO t1 = plot.age t2 = 60 # --> t2 es la edad a la que se calcula el SI h1 = plot.dominant_h h2 = (t2**2) / (16.884 + t2 * (t1 / h1 - 0.033 * t1 - 16.884 / t1 + 0.033 * t2)) plot.add_value('SI', h2) # Site Index (m) calculation plot_trees: list[Tree] = plot.short_trees_on_list( 'dbh', DESC) # stablish an order to calculate tree variables bal: float = 0 for tree in plot_trees: # for each tree... #-----------------------------------BASAL AREA-----------------------------------------# tree.add_value('bal', bal) # the first tree must receive 0 value (m2) tree.add_value( 'basal_area', math.pi * (tree.dbh / 2)** 2) # normal (at 1.30m) section (cm2) calculation tree.add_value('ba_ha', tree.basal_area * tree.expan / 10000) # basimetric area per ha (m2/ha) bal += tree.basal_area * tree.expan / 10000 # then, that value is acumulated tree.add_value( 'hd_ratio', tree.height * 100 / tree.dbh) # height/diameter ratio (%) calculation tree.add_value( 'normal_circumference', math.pi * tree.dbh ) # normal (at 1.30m) circumference (cm) calculation #-----------------------------------HEIGHT-----------------------------------------# if tree.height == 0: # if the tree hasn't height (m) value, it is calculated beta6 = 0.4666 beta7 = -0.4356 beta8 = 0.0092 tree.add_value( 'height', 1.3 + (plot.dominant_h - 1.3) * ((tree.dbh / plot.dominant_dbh)** (beta6 + beta7 * (tree.dbh / plot.dominant_dbh) + beta8 * plot.si))) #-----------------------------------FUNCTIONS-----------------------------------------# # self.crown(tree, plot, 'initialize') # activate crown variables calculation self.vol(tree, plot) # activate volume variables calculation self.merch_classes( tree) # activate wood uses variables calculation self.biomass(tree) # activate biomass variables calculation self.merch_classes_plot( plot) # activate wood uses (plot) variables calculation self.biomass_plot( plot) # activate biomass (plot) variables calculation except Exception: self.catch_model_exception()
def initialize(self, plot: Plot): """ Function that update the gaps on the information with the inventory data Height/Diameter equation: Doc.: Diéguez-Aranda U, Rojo A, Castedo-Dorado F, et al (2009). Herramientas selvícolas para la gestión forestal sostenible en Galicia. Forestry, 82, 1-16 Ref.: Diéguez-Aranda et al, 2009 SI equation: Doc.: Barrio-Anta M, Diéguez-Aranda U (2005). Site quality of pedunculate oak (Quercus robur L.) stands in Galicia (northwest Spain). European Journal of Forest Research, 124(1), 19-28 Ref.: Barrio-Anta and Diéguez-Aranda, 2005 """ print( '#----------------------------------------------------------------------------#' ) print( ' Quercus robur model (Galicia) is running ' ) print( '#----------------------------------------------------------------------------#' ) try: # errors inside that construction will be announced #-----------------------------------SI-----------------------------------------# plot.add_value( 'SI', 129.0321 * ((plot.dominant_h / 129.0321)**((plot.age / 60)**0.301881)) ) # Site Index (m) calculation for 60 years as reference age plot_trees: list[Tree] = plot.short_trees_on_list( 'dbh', DESC) # stablish an order to calculate tree variables bal: float = 0 for tree in plot_trees: # for each tree... #-----------------------------------BASAL AREA-----------------------------------------# tree.add_value('bal', bal) # the first tree must receive 0 value (m2) tree.add_value( 'basal_area', math.pi * (tree.dbh / 2)** 2) # normal (at 1.30m) section (cm2) calculation tree.add_value('ba_ha', tree.basal_area * tree.expan / 10000) # basimetric area per ha (m2/ha) bal += tree.basal_area * tree.expan / 10000 # then, that value is acumulated tree.add_value( 'hd_ratio', tree.height * 100 / tree.dbh) # height/diameter ratio (%) calculation tree.add_value( 'normal_circumference', math.pi * tree.dbh ) # normal (at 1.30m) circumference (cm) calculation #-----------------------------------HEIGHT-----------------------------------------# if tree.height == 0: # if the tree hasn't height (m) value, it is calculated tree.add_value( 'height', (1.3**(1.067) + (plot.dominant_h**(1.067) - 1.3**(1.067)) * ((1 - math.exp(-0.06160 * tree.dbh)) / (1 - math.exp(-0.06160 * plot.dominant_dbh)))** (1 / 1.067))) #-----------------------------------FUNCTIONS-----------------------------------------# # self.crown(tree, plot, 'process_plot') # activate crown variables calculation self.vol(tree, plot) # activate volume variables calculation self.merch_classes( tree) # activate wood uses variables calculation self.biomass(tree) # activate biomass variables calculation self.merch_classes_plot( plot) # activate wood uses (plot) variables calculation self.biomass_plot( plot) # activate biomass (plot) variables calculation except Exception: self.catch_model_exception()
def initialize(self, plot: Plot): """ Function that update the gaps on the information with the inventory data Height/Diameter equation: Doc.: Calama R, Montero G (2004). Interregional nonlinear height diameter model with random coefficients for stone pine in Spain. Canadian Journal of Forest Research, 34(1), 150-163 Ref.: Calama and Montero, 2004 SI equation: a) Doc.: Calama R, Cañadas N, Montero G (2003). Inter-regional variability in site index models for even-aged stands of stone pine (Pinus pinea L.) in Spain. Annals of Forest Science, 60(3), 259-269 Ref.: Calama et al, 2003 b) Doc.: Casanueva GM, Ponce RA (2007). Patrón de crecimiento en altura dominante en masas naturales y artificiales de Pinus pinea L.: comparación a través de modelos dinámicos. Cuadernos de la SECF, (23) Ref.: Casanueva and Ponce, 2007 c) Doc.: Cañadas MN, Calama R, Güemes GCG (2005). Modelo de calidad de estación para Pinus pinea L. en las masas del sistema central (Valles del Tiétar y Alberche), mediante aplicación de la metodología propuesta por Goelz & Burk (1992). In Congresos Forestales Ref.: Cañadas et al, 2005 """ print( '#----------------------------------------------------------------------------#' ) print( ' Pinus pinea model (Sistema Central) is running ' ) print( '#----------------------------------------------------------------------------#' ) try: # errors inside that construction will be announced global P9010 # the explanation of that variable is on P9010_distribution function P9010 = 0 # define the variable that later we will use plot_trees: list[Tree] = plot.short_trees_on_list( 'dbh', DESC) # stablish an order to calculate tree variables bal: float = 0 for tree in plot_trees: # for each tree... #-----------------------------------BASAL AREA-----------------------------------------# tree.add_value('bal', bal) # the first tree must receive 0 value (m2) tree.add_value( 'basal_area', math.pi * (tree.dbh / 2)** 2) # normal (at 1.30m) section (cm2) calculation tree.add_value('ba_ha', tree.basal_area * tree.expan / 10000) # basimetric area per ha (m2/ha) bal += tree.basal_area * tree.expan / 10000 # then, that value is acumulated tree.add_value( 'hd_ratio', tree.height * 100 / tree.dbh) # height/diameter ratio (%) calculation tree.add_value( 'normal_circumference', math.pi * tree.dbh ) # normal (at 1.30m) circumference (cm) calculation if P9010 == 0: # condition needed to only calculate that variable once P9010 = self.P9010_distribution( plot, tree ) # that line is needed to activate the calculation of P9010, needed later #-----------------------------------HEIGHT-----------------------------------------# if tree.height == 0: # if the tree hasn't height (m) value, it is calculated K = 0 # 0 for Central Spain in general; 1 for Catalonia and West Andalusia tree.add_value( 'height', 1.3 + math.exp((1.7306 + 0.0882 * plot.dominant_h - 0.0062 * P9010 - 0.0936 * K) + (-25.2776 + 1.6999 * math.log(plot.density) + 4.743 * K) / (tree.dbh + 1))) #-----------------------------------FUNCTIONS-----------------------------------------# # self.crown(tree, plot, 'initialize') # activate crown variables calculation self.vol(tree, plot) # activate volume variables calculation self.merch_classes( tree) # activate wood uses variables calculation self.biomass(tree) # activate biomass variables calculation self.merch_classes_plot( plot) # activate wood uses (plot) variables calculation self.biomass_plot( plot) # activate biomass (plot) variables calculation #-----------------------------------SI - Dominant Height-----------------------------------------# # On this model, we didn't update height values on grow function, so Dominant Height was calculates by using the height values before the execution # In order to correct that value, we add the calculation methodology used on SIMANFOR project to update that value after the height values update plot.add_value( 'DOMINANT_H', -plot.dominant_h ) # Dominant Height is calculated befores process_plot, so we eliminate this value to recalculate it with tree_expansion: float = 0.0 # the new tree.height values selection_trees = list() for tree in plot_trees: # for each tree on the list (ordered by dbh), we calculate how many trees are needed to Dominant Height calculation if tree_expansion < 100: tree_expansion += tree.expan selection_trees.append(tree) else: break acumulate: float = 0 result: float = 0 for tree in selection_trees: # for each selected tree, we calculate the relative weight for each of them on the Dominant Height value if acumulate + tree.expan < 100: result += tree.height * tree.expan acumulate += tree.expan else: result += (100 - acumulate) * tree.height dom_h = result / 100 plot.add_value( 'DOMINANT_H', dom_h) # adding new Dominant Height value to the plot # a) T2 = 100 # Age when we want to obtain the Site Index (years) SI = math.exp(4.1437 + (math.log(plot.dominant_h) - 4.1437) * ((T2 / plot.age)**(-0.3935))) # b) #a = 0.005994 #m1 = 14.08433 #m2 = -12.0075 #Xo = (math.log(plot.dominant_h) - m1) / (m2 + math.log(1 - math.exp(-a * plot.age))) #t = 80 # Age when we want to obtain the Site Index (years) #SI = math.exp(m1 + m2 * Xo) * ((1 - math.exp(-a * t)) ** Xo) # c) #Hj = plot.dominant_h #tj = plot.age #ti = 80 # Age when we want to obtain the Site Index (years) #b1 = 0.252147664 #b2 = 1.225418697 #b3 = 0.498226472 #b4 = 0.785418166 #SI = 1.3 + (Hj - 1.3) * ((1 - math.exp(- b1 * ((Hj / tj) ** b2) * (tj ** b3) * ti)) / ( # 1 - math.exp(- b1 * ((Hj / tj) ** b2) * (tj ** b3) * tj)))**b4 plot.add_value('SI', SI) # Site Index (m) calculation except Exception: self.catch_model_exception()
def initialize(self, plot: Plot): """ Function that update the gaps on the information with the inventory data Height/Diameter equation: Doc.: Sánchez-González M, Cañellas I, Montero G (2007). Generalized height-diameter and crown diameter prediction models for cork oak forests in Spain. Forest Systems, 16(1), 76-88 Ref.: Sánchez-González et al, 2007 Doc.: Sánchez-González M, Calama R, Cañellas I, Montero G (2007). Management oriented growth models for multifunctional Mediterranean Forests: the case of Cork Oak (Quercus suber L.). In EFI proceedings (Vol. 56, pp. 71-84) Ref.: Sánchez-González et al, 2007 SI equation: Doc.: Sánchez-González M, Tomé M, Montero G (2005). Modelling height and diameter growth of dominant cork oak trees in Spain. Annals of Forest Science, 62(7), 633-643 Ref.: Sánchez-González et al, 2005 Doc.: Sánchez-González M, Calama R, Cañellas I, Montero G (2007). Management oriented growth models for multifunctional Mediterranean Forests: the case of Cork Oak (Quercus suber L.). In EFI proceedings (Vol. 56, pp. 71-84) Ref.: Sánchez-González et al, 2007 Dominant diameter equation: Doc.: Sánchez-González M, Tomé M, Montero G (2005). Modelling height and diameter growth of dominant cork oak trees in Spain. Annals of Forest Science, 62(7), 633-643 Ref.: Sánchez-González et al, 2005 Doc.: Sánchez-González M, Calama R, Cañellas I, Montero G (2007). Management oriented growth models for multifunctional Mediterranean Forests: the case of Cork Oak (Quercus suber L.). In EFI proceedings (Vol. 56, pp. 71-84) Ref.: Sánchez-González et al, 2007 """ print('#----------------------------------------------------------------------------#') print(' Quercus suber model (Cataluña) is running ') print('#----------------------------------------------------------------------------#') try: # errors inside that construction will be announced #-----------------------------------SI-----------------------------------------# # site index is defined as top height at a base age of 80 years t2 = 80 # age to estimate the SI and Dominant_diamter (years) SI = 20.7216 / ((1 - (1 - 20.7216/plot.dominant_h)*(plot.age/t2)) ** 1.4486) plot.add_value('SI', SI) # Site Index (m) calculation # a1 = math.log(1 - math.exp(-0.0063*plot.age)) # a2 = math.log(1 - math.exp(-0.0063*t2)) # dbh must be diameter under bark (cm) # DD = ((83.20 + 5.28*plot.si - 1.53*plot.dominant_h*100/plot.dominant_dbh)**(1 - a2/a1)) * (plot.dominant_dbh**(a2/a1)) # plot.add_value('DOMINANT_DBH', DD ) plot_trees: list[Tree] = plot.short_trees_on_list('dbh', DESC) # stablish an order to calculate tree variables bal: float = 0 for tree in plot_trees: # for each tree... #-----------------------------------DBH CALCULATION-----------------------------------------# if tree.dbh == 0: tree.add_value('dbh', tree.dbh_oc - tree.bark/10) # dbh under cork calculated if it is not at the initial inventory (cm) if tree.dbh_oc != 0 and tree.bark == 0: tree.add_value('bark', (tree.dbh_oc - tree.dbh)*10) # cork calculated using dbh outside and inside cork (mm) if tree.dbh_oc == 0: tree.add_value('dbh_oc', tree.dbh + tree.bark/10) # diameter outside bark calculation (cm) #-----------------------------------BASAL AREA-----------------------------------------# tree.add_value('bal', bal) # the first tree must receive 0 value (m2) tree.add_value('basal_area', math.pi * (tree.dbh / 2) ** 2) # normal (at 1.30m) section (cm2) calculation tree.add_value('ba_ha', tree.basal_area * tree.expan / 10000) # basimetric area per ha (m2/ha) bal += tree.basal_area * tree.expan / 10000 # then, that value is acumulated tree.add_value('hd_ratio', tree.height * 100 / tree.dbh) # height/diameter ratio (%) calculation tree.add_value('normal_circumference', math.pi * tree.dbh) # normal (at 1.30m) circumference (cm) calculation #-----------------------------------HEIGHT-----------------------------------------# if tree.height == 0: # if the tree hasn't height (m) value, it is calculated tree.add_value('height', 1.3 + (plot.dominant_h - 1.3)*((tree.dbh/plot.dominant_dbh)**0.4898)) #-----------------------------------FUNCTIONS-----------------------------------------# self.crown(tree, plot, 'initialize') # activate crown variables calculation self.vol(tree, plot) # activate volume variables calculation # self.merch_classes(tree) # activate wood uses variables calculation self.biomass(tree) # activate biomass variables calculation # self.merch_classes_plot(plot) # activate wood uses (plot) variables calculation self.biomass_plot(plot) # activate biomass (plot) variables calculation except Exception: self.catch_model_exception()
def initialize(self, plot: Plot): """ Function that update the gaps on the information with the inventory data Height/Diameter equation: Doc.: Lizarralde I (2008). Dinámica de rodales y competencia en las masas de pino silvestre (Pinus sylvestris L.) y pino negral (Pinus pinaster Ait.) de los Sistemas Central e Ibérico Meridional. Tesis Doctoral. 230 pp Ref.: Lizarralde 2008 SI equation: Doc.: Rojo A, Montero, G (1996). El pino silvestre en la Sierra de Guadarrama MAPA. Ref.: Rojo and Montero, 1996 Doc.: Bravo F, Montero G (2001). Site index estimation in Scots pine (Pinus sylvestris L.) using soil attributes. Forestry 74, 396‐406 Ref.: Bravo and Montero, 2001 """ print( '#----------------------------------------------------------------------------#' ) print( ' Pinus sylvestris model (Sistema Ibérico Meridional) is running ' ) print( '#----------------------------------------------------------------------------#' ) try: # errors inside that construction will be announced #-----------------------------------SI-----------------------------------------# # site index is defined as top height at a base age of 100 years plot.add_value('SI', (plot.dominant_h * 0.8534446) / (pow( (1 - math.exp(float(-0.270 * plot.age / 10))), 2.2779))) # Site Index (m) calculation plot_trees: list[Tree] = plot.short_trees_on_list( 'dbh', DESC) # stablish an order to calculate tree variables bal: float = 0 for tree in plot_trees: # for each tree... #-----------------------------------BASAL AREA-----------------------------------------# tree.add_value('bal', bal) # the first tree must receive 0 value (m2) tree.add_value( 'basal_area', math.pi * (tree.dbh / 2)** 2) # normal (at 1.30m) section (cm2) calculation tree.add_value('ba_ha', tree.basal_area * tree.expan / 10000) # basimetric area per ha (m2/ha) bal += tree.basal_area * tree.expan / 10000 # then, that value is acumulated tree.add_value( 'hd_ratio', tree.height * 100 / tree.dbh) # height/diameter ratio (%) calculation tree.add_value( 'normal_circumference', math.pi * tree.dbh ) # normal (at 1.30m) circumference (cm) calculation #-----------------------------------HEIGHT-----------------------------------------# if tree.height == 0: # if the tree hasn't height (m) value, it is calculated tree.add_value( 'height', (13 + (27.0392 + 1.4853 * plot.dominant_h * 10 - 0.1437 * plot.qm_dbh * 10) * math.exp(-8.0048 / math.sqrt(tree.dbh * 10))) / 10) #-----------------------------------FUNCTIONS-----------------------------------------# self.crown( tree, plot, 'initialize') # activate crown variables calculation self.vol(tree, plot) # activate volume variables calculation self.merch_classes( tree) # activate wood uses variables calculation self.biomass(tree) # activate biomass variables calculation self.merch_classes_plot( plot) # activate wood uses (plot) variables calculation self.biomass_plot( plot) # activate biomass (plot) variables calculation except Exception: self.catch_model_exception()
def process_plot(self, time: int, plot: Plot, trees: list): """ Function that update the trees information once the grow function was executed The equations on that function are the same that in "initialize" function """ print( '#----------------------------------------------------------------------------#' ) print( ' Pinus pinea model (Sistema Central) is running ' ) print( '#----------------------------------------------------------------------------#' ) if time != 5: print( 'BE CAREFUL! That model was developed to 5 year execution, and you are trying to make a', time, 'years execution!') print( 'Please, change your execution conditions to the recommended (5 year execution). If not, the output values will be not correct.' ) try: # errors inside that construction will be announced dbh_list.sort( reverse=True ) # we need to sort the list from higher to lower dbh, as plot_trees does it global P9010 # the explanation of that variable is on P9010_distribution function P9010 = 0 # leave the variable value as 0 to calculate it again on that execution count = 0 # counter needed to dbh_list plot_trees: list[Tree] = plot.short_trees_on_list( 'dbh', DESC) # stablish an order to calculate tree variables bal: float = 0.0 for tree in plot_trees: # for each tree... if tree.status is None: # only update tree alive data #-----------------------------------BASAL AREA-----------------------------------------# tree.add_value( 'basal_area', math.pi * (tree.dbh / 2)** 2) # normal (at 1.30m) section (cm2) calculation tree.add_value( 'bal', bal) # the first tree must receive 0 value (m2) tree.add_value('ba_ha', tree.basal_area * tree.expan / 10000) # basimetric area per ha (m2/ha) bal += tree.basal_area * tree.expan / 10000 # then, that value is acumulated if P9010 == 0: # condition needed to only calculate that variable once P9010 = self.P9010_distribution( plot, tree ) # that line is neede to activate the calculation of P9010, needed later # Hdom_new is a SI equation used to predict the Dominant Height 5 years later (execution) Hdom_new = math.exp( 4.1437 + (math.log(plot.dominant_h) - 4.1437) * pow( ((plot.age + 5) / plot.age), -0.3935) ) # that variable need to be calculated again only once K = 0 # 0 for Central Spain in general; 1 for Catalonia and West Andalusia old_height = 1.3 + math.exp( (1.7306 + 0.0882 * plot.dominant_h - 0.0062 * P9010 - 0.0936 * K) + (-25.2776 + 1.6999 * math.log(plot.density) + 4.743 * K) / (dbh_list[count][0] + 1) ) # height calculation before execution (m) new_height = 1.3 + math.exp( (1.7306 + 0.0882 * (Hdom_new) - 0.0062 * P9010 - 0.0936 * K) + (-25.2776 + 1.6999 * math.log(plot.density) + 4.743 * K) / (dbh_list[count][1] + 1) ) # height calculation after execution (m) ht = tree.height * new_height / old_height # obtaining the new height of the tree by comparing values tree.add_value('height', ht) # adding new tree height value (m) count += 1 # add 1 value to move the variable to the next tree position tree.add_value( 'hd_ratio', tree.height * 100 / tree.dbh) # height/diameter ratio (%) calculation tree.add_value( 'normal_circumference', math.pi * tree.dbh ) # normal (at 1.30m) circumference (cm) calculation #-----------------------------------FUNCTIONS-----------------------------------------# # self.crown(tree, plot, 'process_plot') # activate crown variables calculation self.vol(tree, plot) # activate volume variables calculation self.merch_classes( tree) # activate wood uses variables calculation self.biomass( tree) # activate biomass variables calculation self.merch_classes_plot( plot) # activate wood uses (plot) variables calculation self.biomass_plot( plot) # activate biomass (plot) variables calculation #-----------------------------------Dominant Height-----------------------------------------# # On this model, we didn't update height values on grow function, so Dominant Height was calculates by using the height values before the execution # In order to correct that value, we add the calculation methodology used on SIMANFOR project to update that value after the height values update plot.add_value( 'DOMINANT_H', -plot.dominant_h ) # Dominant Height is calculated befores process_plot, so we eliminate this value to recalculate it with tree_expansion: float = 0.0 # the new tree.height values selection_trees = list() for tree in plot_trees: # for each tree on the list (ordered by dbh), we calculate how many trees are needed to Dominant Height calculation if tree_expansion < 100: tree_expansion += tree.expan selection_trees.append(tree) else: break acumulate: float = 0 result: float = 0 for tree in selection_trees: # for each selected tree, we calculate the relative weight for each of them on the Dominant Height value if acumulate + tree.expan < 100: result += tree.height * tree.expan acumulate += tree.expan else: result += (100 - acumulate) * tree.height dom_h = result / 100 plot.add_value( 'DOMINANT_H', dom_h) # adding new Dominant Height value to the plot number = len(dbh_list) while number > 0: # that loop leaves the dbh_list empty to the next execution dbh_list.pop(0) number -= 1 except Exception: self.catch_model_exception()
def initialize(self, plot: Plot): """ Function that update the gaps on the information with the inventory data Height/Diameter equation: Doc.: Dorado FC, Diéguez-Aranda U, Anta MB, Rodríguez MS, von Gadow K (2006). A generalized height–diameter model including random components for radiata pine plantations in northwestern Spain. Forest Ecology and Management, 229(1-3), 202-213 Ref.: Dorado et al, 2006 SI equation: Doc.: Diéguez-Aranda U, Burkhart HE, Rodríguez-Soalleiro R (2005). Modeling dominant height growth of radiata pine (Pinus radiata D. Don) plantations in north-western Spain. Forest Ecology and Management, 215(1-3), 271-284 Ref.: Diéguez-Aranda et al, 2006 """ print( '#----------------------------------------------------------------------------#' ) print( ' Pinus radiata model (Galicia) is running ' ) print( '#----------------------------------------------------------------------------#' ) try: # errors inside that construction will be announced #-----------------------------------SI-----------------------------------------# t = 20 # desired age to SI (years) Lo = math.log(1 - math.exp(-0.06738 * plot.age)) Xo = 0.5 * (math.log(plot.dominant_h) + 1.755 * Lo + math.sqrt( (math.log(plot.dominant_h) + 1.755 * Lo)**2 - 4 * 12.44 * Lo)) SI = plot.dominant_h * ( (1 - math.exp(-0.06738 * t) / (1 - math.exp(-0.06738 * plot.age)))**(-1.755 + 12.44 / Xo)) # site index is defined as top height at a base age of 20 years plot.add_value('SI', SI) # Site Index (m) calculation plot_trees: list[Tree] = plot.short_trees_on_list( 'dbh', DESC) # stablish an order to calculate tree variables bal: float = 0 for tree in plot_trees: # for each tree... #-----------------------------------BASAL AREA-----------------------------------------# tree.add_value('bal', bal) # the first tree must receive 0 value (m2) tree.add_value( 'basal_area', math.pi * (tree.dbh / 2)** 2) # normal (at 1.30m) section (cm2) calculation tree.add_value('ba_ha', tree.basal_area * tree.expan / 10000) # basimetric area per ha (m2/ha) bal += tree.basal_area * tree.expan / 10000 # then, that value is acumulated tree.add_value( 'hd_ratio', tree.height * 100 / tree.dbh) # height/diameter ratio (%) calculation tree.add_value( 'normal_circumference', math.pi * tree.dbh ) # normal (at 1.30m) circumference (cm) calculation #-----------------------------------HEIGHT-----------------------------------------# if tree.height == 0: # if the tree hasn't height (m) value, it is calculated a = 0.0296 b = 1.633 tree.add_value( 'height', (1.3**b + (plot.dominant_h**b - 1.3**b) * (1 - math.exp(-a * tree.dbh)) / (1 - math.exp(-a * plot.dominant_diameter))**(1 / b))) #-----------------------------------FUNCTIONS-----------------------------------------# self.crown( tree, plot, 'initialize') # activate crown variables calculation self.vol(tree, plot) # activate volume variables calculation self.merch_classes( tree) # activate wood uses variables calculation self.biomass(tree) # activate biomass variables calculation self.merch_classes_plot( plot) # activate wood uses (plot) variables calculation self.biomass_plot( plot) # activate biomass (plot) variables calculation except Exception: self.catch_model_exception()
def initialize(self, plot: Plot): """ Function that update the gaps on the information with the inventory data Height/Diameter equation: Doc.: Adame P, del Río M, Canellas I (2008). A mixed nonlinear height–diameter model for pyrenean oak (Quercus pyrenaica Willd.). Forest ecology and management, 256(1-2), 88-98 Ref.: Adame et al, 2008 SI equation: Doc.: Adame P, Cañellas I, Roig S, del Río M (2006). Modelling dominant height growth and site index curves for rebollo oak (Quercus pyrenaica Willd.). Annals of Forest Science, 63(8), 929-940 Ref.: Adame et al, 2006 """ print( '#----------------------------------------------------------------------------#' ) print( ' Quercus pyrenaica model (Castilla y León) is running ' ) print( '#----------------------------------------------------------------------------#' ) try: # errors inside that construction will be announced #-----------------------------------SI-----------------------------------------# parA1 = 15.172 parA2 = -4.2126 parA3 = 0.1439 parA4 = 0.6711 H0 = plot.dominant_h t2 = 1 - math.exp(-parA3 * pow(60, parA4)) t1 = 1 - math.exp(-parA3 * pow(plot.age, parA4)) X = (math.log(H0) - parA1 * math.log(t1)) / (1 + parA2 * math.log(t1)) plot.add_value( 'SI', math.exp(X) * pow(t2, parA1 + parA2 * X) ) # Site Index (m) calculation to 60 years as reference plot_trees: list[Tree] = plot.short_trees_on_list( 'dbh', DESC) # stablish an order to calculate tree variables bal: float = 0 for tree in plot_trees: # for each tree... #-----------------------------------BASAL AREA-----------------------------------------# tree.add_value('bal', bal) # the first tree must receive 0 value (m2) tree.add_value( 'basal_area', math.pi * (tree.dbh / 2)** 2) # normal (at 1.30m) section (cm2) calculation tree.add_value('ba_ha', tree.basal_area * tree.expan / 10000) # basimetric area per ha (m2/ha) bal += tree.basal_area * tree.expan / 10000 # then, that value is acumulated tree.add_value( 'hd_ratio', tree.height * 100 / tree.dbh) # height/diameter ratio (%) calculation tree.add_value( 'normal_circumference', math.pi * tree.dbh ) # normal (at 1.30m) circumference (cm) calculation #-----------------------------------HEIGHT-----------------------------------------# if tree.height == 0: # if the tree hasn't height (m) value, it is calculated tree.add_value( 'height', 1.3 + (3.099 - 0.00203 * plot.basal_area + 1.02491 * plot.dominant_h * math.exp(-8.5052 / tree.dbh))) #-----------------------------------FUNCTIONS-----------------------------------------# # self.crown(tree, plot, 'initialize') # activate crown variables calculation self.vol(tree, plot) # activate volume variables calculation self.merch_classes( tree) # activate wood uses variables calculation self.biomass(tree) # activate biomass variables calculation self.merch_classes_plot( plot) # activate wood uses (plot) variables calculation self.biomass_plot( plot) # activate biomass (plot) variables calculation except Exception: self.catch_model_exception()
def initialize(self, plot: Plot): """ Function that update the gaps on the information with the inventory data Reineke Index equation (value): Doc.: del Río M, Montero G (2011). Modelo de simulación de claras en masas de Pinus sylvestris L. Monografias INIA: Forestal n. 3 Ref.: del Río and Montero, 2011 Site Index equation: Doc.: del Río M, Montero G (2011). Modelo de simulación de claras en masas de Pinus sylvestris L. Monografias INIA: Forestal n. 3 Ref.: del Río and Montero, 2011 Volume equation: Doc.: del Río M, Montero G (2011). Modelo de simulación de claras en masas de Pinus sylvestris L. Monografias INIA: Forestal n. 3 Ref.: del Río and Montero, 2011 """ print('#----------------------------------------------------------------------------#') print(' Pinus sylvestris "SILVES" model (Spain) is running ') print('#----------------------------------------------------------------------------#') try: #-----------------------------------FIRST: calculate PLOT data by using TREE data-----------------------------------------# tree_expansion: float = 0.0 expansion_trees: list[Tree] = plot.short_trees_on_list('dbh', DESC) selection_trees = list() for tree in expansion_trees: if tree_expansion < 100: tree_expansion += tree.expan selection_trees.append(tree) else: break sum_expan: float = 0 sum_prod_basal_area_expan: float = 0 ## sum_edad: float = 0 sum_dbh_expan: float = 0 sum_dbh_2_expan: float = 0 max_dbh: float = 0 min_dbh: float = 9999 max_h: float = 0 min_h: float = 9999 max_ba: float = 0 min_ba: float = 9999 sum_height_expan: float = 0 sum_lcw_expan: float = 0 prod_lcw_lcw_expan: float = 0 # sum_canopy_cover: float = 0 # sum_vol_expan: float = 0 # sum_bole_vol_expan: float = 0 for tree in expansion_trees: sum_expan += tree.expan sum_prod_basal_area_expan += tree.basal_area * tree.expan ## sum_edad += tree.tree_age * tree.expan sum_dbh_expan += tree.dbh * tree.expan sum_dbh_2_expan += math.pow(tree.dbh, 2) * tree.expan max_dbh = tree.dbh if tree.dbh > max_dbh else max_dbh min_dbh = tree.dbh if tree.dbh < min_dbh else min_dbh max_h = tree.height if tree.height > max_h else max_h min_h = tree.height if tree.height < min_h else min_h max_ba = tree.basal_area if tree.basal_area > max_ba else max_ba min_ba = tree.basal_area if tree.basal_area < min_ba else min_ba sum_height_expan += tree.height * tree.expan # if tree.lcw != '': # sum_lcw_expan += tree.lcw * tree.expan # prod_lcw_lcw_expan += math.pow(tree.lcw, 2) * tree.expan # sum_canopy_cover += math.pi * (math.pow(tree.lcw, 2) / 4) * tree.expan # sum_vol_expan += tree.vol * tree.expan # sum_bole_vol_expan += tree.bole_vol * tree.expan plot.add_value('BASAL_AREA', sum_prod_basal_area_expan / 10000) plot.add_value('DOMINANT_H', plot.get_dominant_height(selection_trees)) plot.add_value('DENSITY', sum_expan) if sum_expan != 0: plot.add_value('MEAN_DBH', sum_dbh_expan / sum_expan) plot.add_value('QM_DBH', math.sqrt(sum_dbh_2_expan / sum_expan)) plot.add_value('DOMINANT_DBH', plot.get_dominant_diameter(selection_trees)) plot.add_value('DBH_MAX', max_dbh) plot.add_value('DBH_MIN', min_dbh) plot.add_value('BA_MAX', max_ba) plot.add_value('BA_MIN', min_ba) if sum_expan != 0: plot.add_value('MEAN_H', sum_height_expan / sum_expan) # plot.add_value('CROWN_MEAN_D', sum_lcw_expan / sum_expan) plot.add_value('MEAN_BA', sum_prod_basal_area_expan / sum_expan) plot.add_value('H_MAX', max_h) plot.add_value('H_MIN', min_h) plot.add_value('SEC_DOMINANTE', plot.get_dominant_section(selection_trees)) # if sum_expan != 0: # plot.add_value('CROWN_DOM_D', math.sqrt(prod_lcw_lcw_expan / sum_expan)) if plot.qm_dbh != 0: # plot.add_value('REINEKE', sum_expan * math.pow(25/plot.qm_dbh, -1.605)) plot.add_value('REINEKE', sum_expan * math.pow(25/plot.qm_dbh, -1.75)) else: plot.add_value('REINEKE', 0) if sum_expan != 0: if Plot.dominant_h != 0: plot.add_value('HART', 10000 / (plot.dominant_h * math.sqrt(sum_expan))) # plot.add_value('CANOPY_COVER', sum_canopy_cover / 10000) # plot.add_value('VOL', sum_vol_expan / 1000) # plot.add_value('BOLE_VOL', sum_bole_vol_expan / 1000) # if plot.vol > plot.bole_vol: # sometimes, only bole_vol is calculated # plot.bark_vol = plot.vol - plot.bole_vol #-----------------------------------SECOND: calculate PLOT data by using PLOT data-----------------------------------------# # Site Index parA = 0.8534446 parB = -0.27 parC = 0.439 SiteIndex = parA * plot.dominant_h / pow( 1 - math.exp( parB * plot.age / 10 ) , 1 / parC ) # equation for Site Index plot.add_value('SI', SiteIndex) # store Site Index in database IC = plot.si / 10 plot.add_value('QI', IC) # Initial Volume parB0 = 1.42706 parB1 = 0.388317 parB2 = -30.691629 parB3 = 1.034549 Volume_W_Bark = math.exp(parB0 + parB1*plot.si/10 + parB2/plot.age + parB3*math.log(plot.basal_area)) # equation for stand volumen plot.add_value('VOL', Volume_W_Bark) # store initial stand volume in database except Exception: self.catch_model_exception()
def apply_cut_down_model( self, old_plot: Plot, new_plot: Plot, #cut_down, cut_criteria, volume, time, min_age, max_age): """ Function that includes the equations needed in the cuts. Harvest equations: Doc.: del Río M, Montero G (2011). Modelo de simulación de claras en masas de Pinus sylvestris L. Monografias INIA: Forestal n. 3 Ref.: del Río and Montero, 2011 """ # trimType values: ( ByTallest, BySmallest, Systematic ) --> Thinning types # cutDownType values: ( PercentOfTrees, Volume, Area ) --> Variable used to evaluate the thinning # volume ---> value: (% of "Variable" reduced after the thinning) print('#----------------------------------------------------------------------------#') print(' Pinus sylvestris "SILVES" model (Spain) is running ') print('#----------------------------------------------------------------------------#') if time != 0: print('BE CAREFUL! When you plan a HARVEST the time must be 0, and you wrote a', time, 'years for the harvest period!') print('Please, change your time value to 0 and run your scenario again.') try: value = volume # new_plot.add_value('VAR_9', value); # That line is not needed; at the start, old_plot and new_plot values are the same # new_plot.add_value('AGE', old_plot.age) # store new age in database, it is supposed to be the same # new_plot.add_value('SI', old_plot.si) # Dominant height at plot age for actual site index # DOMINANT Height --> nothing changes with time = 0 # parA17 = 1.9962 # parB17 = 0.2642 # parC17 = 0.46 # parA29 = 3.1827 # parB29 = 0.3431 # parC29 = 0.3536 # H0_17 = 10 * parA17 * pow( 1 - math.exp( -1 * parB17 * old_plot.age / 10 ), 1 / parC17 ) # H0_29 = 10 * parA29 * pow( 1 - math.exp( -1 * parB29 * old_plot.age / 10 ), 1 / parC29 ) # Dom_Height = H0_17 + ( H0_29 - H0_17 ) * ( old_plot.si / 10 - 1.7 ) / 1.2 # Dominant height at plot age for actual site index # new_plot.add_value('DOMINANT_H', Dom_Height) # store Dominant height in database # Parameter for Volume and Basal Area equations # parA0 = 5.103222 parB0 = 1.42706 parB1 = 0.388317 parB2 = -30.691629 parB3 = 1.034549 # Thinning parameters if cut_criteria == CUTTYPES_DICT['PERCENTOFTREES']: tpuN = value/100 # ratio of thinning trees per hectare and total before thinning TPH = (1 - tpuN)*old_plot.density # trees per hectare after thinning parC0 = 0.531019 parC1 = 0.989792 parC2 = 0.517850 QMD = parC0 + parC1*old_plot.qm_dbh + parC2*old_plot.qm_dbh*pow(tpuN, 2) # equation to calculate quadratic mean diameter MTBA = math.pi*pow(QMD/2, 2) # average mean basal area SBA = MTBA*TPH/10000 # trees per hectare Volume = math.exp(parB0 + parB1*old_plot.si/10 + parB2/old_plot.age + parB3*math.log(SBA)) # equation to calculate volume elif cut_criteria == CUTTYPES_DICT['AREA']: tpuBA = value/100 # ratio of thinning basal area and total before thinning SBA = (1 - tpuBA)*old_plot.basal_area # basal area after thinning parC0 = 0.144915 parC1 = 0.969819 parC2 = 0.678010 QMD = pow(parC0 + parC1*pow(old_plot.qm_dbh, 0.5) + parC2*tpuBA, 2) # equation to calculate quadratic mean diameter MTBA = math.pi*pow(QMD/2, 2) # average mean basal area TPH = SBA * 10000 / MTBA # trees per hectare Volume = math.exp(parB0 + parB1*old_plot.si/10 + parB2/old_plot.age + parB3*math.log(SBA)) # equation to calculate volume elif cut_criteria == CUTTYPES_DICT['VOLUME']: tpuVOL = value/100 # ratio of thinning volume and total before thinning Volume = ( 1 - tpuVOL )*old_plot.vol # volume after thinning ### Provided we do not have equations for thinning by volume, stimations are based on stimations by basal area parC0 = 0.144915 parC1 = 0.969819 parC2 = 0.678010 SBA = math.exp( -1*parB0 - parB1*old_plot.si/10 - parB2/old_plot.age + math.log(Volume)/parB3) # equation to calculate stand basal area tpuBA = 1 - SBA/old_plot.basal_area # ratio of thinning basal area and total before thinning QMD = pow(parC0 + parC1*pow(old_plot.qm_dbh, 0.5) + parC2*tpuBA, 2) # equation to calculate quadratic mean diameter MTBA = math.pi*pow(QMD/2, 2) # average mean basal area TPH = SBA*10000/MTBA # trees per hectare new_plot.add_value('DENSITY', TPH) # store trees per hectare in database new_plot.add_value('QM_DBH', QMD) # store quadratic mean diameter new_plot.add_value('BASAL_AREA', SBA) # store basal area in database new_plot.add_value('VOL', Volume) # store total stand volume with bark in database except Exception: self.catch_model_exception()
def apply_grow_model(self, old_plot: Plot, new_plot: Plot, time: int): """ Function that includes the equations needed in the executions. BE CAREFUL!! Is not needed to store the new plot age on the 'AGE' variable, the simulator will do it by his own. Dominant Height equation: Doc.: del Río M, Montero G (2011). Modelo de simulación de claras en masas de Pinus sylvestris L. Monografias INIA: Forestal n. 3 Ref.: del Río and Montero, 2011 Basal Area Growth equation: Doc.: del Río M, Montero G (2011). Modelo de simulación de claras en masas de Pinus sylvestris L. Monografias INIA: Forestal n. 3 Ref.: del Río and Montero, 2011 Survive equation: Doc.: del Río M, Montero G (2011). Modelo de simulación de claras en masas de Pinus sylvestris L. Monografias INIA: Forestal n. 3 Ref.: del Río and Montero, 2011 Reineke Index equation (value): Doc.: del Río M, Montero G (2011). Modelo de simulación de claras en masas de Pinus sylvestris L. Monografias INIA: Forestal n. 3 Ref.: del Río and Montero, 2011 Site Index equation: Doc.: del Río M, Montero G (2011). Modelo de simulación de claras en masas de Pinus sylvestris L. Monografias INIA: Forestal n. 3 Ref.: del Río and Montero, 2011 Volume equation: Doc.: del Río M, Montero G (2011). Modelo de simulación de claras en masas de Pinus sylvestris L. Monografias INIA: Forestal n. 3 Ref.: del Río and Montero, 2011 """ print('#----------------------------------------------------------------------------#') print(' Pinus sylvestris "SILVES" model (Spain) is running ') print('#----------------------------------------------------------------------------#') if time != 5: print('BE CAREFUL! That model was developed to xx year execution, and you are trying to make a', time, 'years execution!') print('Please, change your execution conditions to the recommended (xx year execution). If not, the output values will be not correct.') try: # new_plot.add_value('AGE', old_plot.age + time) # store new age in database # BE CAREFUL!! Is not needed to store the new plot age on the 'AGE' variable, the simulator will do it by his own. # if you need to use the "actualised" age, just create another new variable to do it. new_age = old_plot.age + time # That line is not needed; at the start, old_plot and new_plot values are the same # new_plot.add_value('SI', old_plot.si) # store Site Index in database, constant value for each plot # Dominant Height parA17 = 1.9962 parB17 = 0.2642 parC17 = 0.46 parA29 = 3.1827 parB29 = 0.3431 parC29 = 0.3536 H0_17 = 10 * parA17 * pow(1 - math.exp(float(-1 * parB17 * new_age / 10)), 1 / parC17) # Dominant height at plot age if site index was 17 H0_29 = 10 * parA29 * pow(1 - math.exp(float(-1 * parB29 * new_age / 10)), 1 / parC29) # Dominant height at plot age if site index was 29 Dom_Height = H0_17 + (H0_29 - H0_17) * ( old_plot.si / 10 - 1.7 ) / 1.2 # Dominant height at plot age for actual site index new_plot.add_value('DOMINANT_H', Dom_Height) # store Dominant height in database # Basal Area parA0 = 5.103222 parB0 = 1.42706 parB1 = 0.388317 parB2 = -30.691629 parB3 = 1.034549 Basal_area = pow(old_plot.basal_area, old_plot.age/new_age) * math.exp(parA0*(1 - old_plot.age/new_age)) # basal area calculus new_plot.add_value('BASAL_AREA', Basal_area) # store basal area in database # Mortality parA0 = -2.34935 parA1 = 0.000000099 parA2 = 4.87390 TPH = pow( pow( old_plot.density, parA0) + parA1 * ( pow( new_age / 100, parA2) - pow( old_plot.age / 100, parA2 ) ), 1 / parA0 ) # density calculus; new value of trees per hectare new_plot.add_value('DENSITY', TPH) # store trees per hectare in database # VOLUME # Volume_W_Bark_new = math.exp(parB0 + parB1*old_plot.si/10 + parB2/old_plot.age + parB3*math.log(old_plot.basal_area)) # calculate new volume # Volume_W_Bark = math.exp(parB0 + parB1*old_plot.si/10 + parB2/new_age + parB3*(old_plot.age/new_age)*math.log(old_plot.basal_area) + parB3*parA0*(1 - old_plot.age/new_age)) # calculate new volume # new_plot.add_value('VOL', Volume_W_Bark) # store total stand volume with bark in database # as temporal solution, I used the vol equation changing the values to the new situation, because INIT and CUTS are using the same equation Volume_W_Bark_mix = math.exp(parB0 + parB1*old_plot.si/10 + parB2/new_age + parB3*math.log(new_plot.basal_area)) # calculate new volume new_plot.add_value('VOL', Volume_W_Bark_mix) # Mean Height parA0 = -1.155649 parA1 = 0.976772 H_mean = parA0 + parA1 * new_plot.dominant_h # calculus of mean height new_plot.add_value('MEAN_H', H_mean) # store mean height in database # QUADRATIC Mean Diameter: MTBA = new_plot.basal_area * 10000 / new_plot.density # Mean Tree Basal Area QMD = 2 * math.sqrt( MTBA / math.pi ) # Quadratic mean diameter new_plot.add_value('QM_DBH', QMD) # store quadratic mean diameter # Reineke Index Reineke = new_plot.density * pow(25 / new_plot.qm_dbh, -1.75) # Reineke density index new_plot.add_value('REINEKE', Reineke) # store Reineke index in database # Hart index Hart = 10000 / (new_plot.dominant_h * math.sqrt(new_plot.density)) # Hart index new_plot.add_value('HART', Hart) # Store Hart index in database except Exception: self.catch_model_exception()