def merch_classes(self, tree: Tree): """ Function used to calcule the different comercial volumes depending on the wood purposes That function is rdbh by initialize and process_plot Functions The data criteria to clasify the wood by different uses was obtained from: Doc.: Rodríguez F (2009). Cuantificación de productos forestales en la planificación forestal: Análisis de casos con cubiFOR. In Congresos Forestales Ref.: Rodríguez 2009 """ ht = tree.height # total height as ht to simplify # class_conditions has different lists for each usage, following that: [wood_usage, hmin/ht, dmin, dmax] # [WOOD USE NAME , LOG RELATIVE LENGTH RESPECT TOTAL TREE HEIGHT, MINIMUM DIAMETER, MAXIMUM DIAMETER] class_conditions = [['saw_big', 2.5 / ht, 40, 200], ['saw_small', 2.5 / ht, 25, 200], ['saw_canter', 2.5 / ht, 15, 28], ['chips', 1 / ht, 5, 1000000]] # usage and merch_list are a dictionary and a list that are returned from merch_calculation # to that function, we must send the following information: tree, class_conditions, and the name of our class on this model you are using usage, merch_list = TreeModel.merch_calculation( tree, class_conditions, PinusPinasterGalicia) counter = -1 for k, i in usage.items(): counter += 1 tree.add_value( k, merch_list[counter]) # add merch_list values to each usage
def apply_initialize_tree_model(self, inventory: Inventory, model: TreeModel, operation: Operation): result_inventory = Inventory() for plot in inventory.plots: new_plot = Plot() new_plot.clone(plot, True) try: model.initialize(new_plot) except Exception as e: Tools.print_log_line(str(e), logging.ERROR) new_plot.recalculate() result_inventory.add_plot(new_plot) return result_inventory
def merch_classes(self, tree: Tree): """ Function used to calcule the different comercial volumes depending on the wood purposes That function is rdbh by initialize and process_plot Functions """ ht = tree.height # total height as ht to simplify # class_conditions has different lists for each usage, following that: [wood_usage, hmin/ht, dmin, dmax] # [WOOD USE NAME , LOG RELATIVE LENGTH RESPECT TOTAL TREE HEIGHT, MINIMUM DIAMETER, MAXIMUM DIAMETER] class_conditions = [] # usage and merch_list are a dictionary and a list that are returned from merch_calculation # to that function, we must send the following information: tree, class_conditions, and the name of our class on this model you are using usage, merch_list = TreeModel.merch_calculation(tree, class_conditions, BasicTreeModel) counter = -1 for k,i in usage.items(): counter += 1 tree.add_value(k, merch_list[counter]) # add merch_list values to each usage
def apply_tree_model(self, inventory: Inventory, model: TreeModel, operation: Operation): result_inventory = Inventory() min = operation.get_variable('min_age') if operation.has('min_age') else 0 max = operation.get_variable('max_age') if operation.has('max_age') else 1000 for plot in inventory.plots: cut_pies_mayores = list() dead_pies_mayores = list() result_pies_mayores = list() add_pies_mayores = list() # aquí recojo árboles de masa añadida, con status = I if min <= plot.age <= max: new_plot = Plot() new_plot.clone(plot) search_criteria = SearchCriteria() search_criteria.add_criteria('status', None, EQUAL) source_trees = Tree.get_sord_and_order_tree_list(plot.trees, search_criteria=search_criteria) for tree in source_trees: survives_ratio: float = 0.0 try: survives_ratio = model.survives(operation.get_variable('time'), new_plot, tree) except Exception as e: Tools.print_log_line(str(e), logging.ERROR) if survives_ratio > 0: new_tree = Tree() new_tree.clone(tree) new_tree.add_value('expan', survives_ratio * new_tree.expan) new_tree_dead = Tree() new_tree_dead.clone(tree) new_tree_dead.add_value('status', 'M') new_tree_dead.add_value('expan', (1 - survives_ratio) * new_tree_dead.expan) try: model.grow(operation.get_variable('time'), new_plot, tree, new_tree) except Exception as e: Tools.print_log_line(str(e), logging.ERROR) #ActualizaDatosPieMayor(new_tree); #source_trees.update_tree(tree) result_pies_mayores.append(new_tree) dead_pies_mayores.append(new_tree_dead) # Aquí comienza el código correspondiente a la masa añadida (ingrowth) en las ejecuciones # Su funcionamiento, en principio, será similar a la función de supervivencia # Se añadirá el EXPAN que se considere a cada árbol directamente en las ejecuciones, y mostraremos en el output un "clon" de cada árbol con el valor del # EXPAN añadido, y con el status = I (Ingrowth) para poder identificarlo (como con árboles muertos) new_area_basimetrica: float = 0 distribution: float = 0 # creo esta variable, que estaba sin crear try: new_area_basimetrica = model.add_tree(operation.get_variable('time'), new_plot); except Exception as e: Tools.print_log_line(str(e), logging.ERROR) if new_area_basimetrica > 0: # si no se añade masa, se omite este paso try: distribution = model.new_tree_distribution(operation.get_variable('time'), new_plot, new_area_basimetrica) except Exception as e: Tools.print_log_line(str(e), logging.ERROR) order_criteria = OrderCriteria() order_criteria.add_criteria('dbh') # cambio add_variable por add_criteria tree_to_add: Tree = Tree.get_sord_and_order_tree_list(result_pies_mayores, order_criteria=order_criteria) sum_g = 0 # esta variable recoge el sumatorio de secciones normales de la parcela, para usar el valor en los cálculos posteriores for tree in tree_to_add: sum_g += tree.basal_area # * tree.expan --> no se multiplica por tree.expan if distribution == None: # si no existe una función de distribución # n_trees = len(tree_to_add) # calculamos el nº de árboles de la parcela --> ahora ya no hace falta, pero lo dejo de momento for tree in tree_to_add: # para los árboles que quiero añadir (todos los de la parcela serán modificados, en principio) # voy a añadir una parte proporcional a cada uno; duplico la lista de árboles para que en el output se añada la masa y además se pueda # mostrar que expan se ha añadido a cada árbol, tal cual se hace con los árboles muertos new_d_tree = Tree() # estos árboles serán los que se muestran sin status y pasan a la siguiente ejecución new_d_tree.clone(tree) new_d_tree.add_value('expan', (new_area_basimetrica*10000) / sum_g + new_d_tree.expan) ### hay que revisar este cálculo new_tree_add = Tree() # estos árboles serán los que se muestran con status = I new_tree_add.clone(tree) new_tree_add.add_value('status', 'I') # habría que conseguir que estos árboles aparecieran pintados en el output new_tree_add.add_value('expan', (new_area_basimetrica*10000) / sum_g) ### hay que revisar este cálculo result_pies_mayores.append(new_d_tree) # añado los árboles con EXPAN modificado a la lista add_pies_mayores.append(new_tree_add) # añado los árboles con status = I a una nueva lista # para los modelos en los que sí hay unas condiciones establecidas en new_tree_distribution, entonces se aplica lo siguiente else: # si existe una función de distribución definida por el usuario # var = 0 # acumulador del nº de árboles de cada CD --> ya no es necesario, lo silencio de momento sum_g = 0 # acumulador del sumatorio de secciones normales para cada CD count = 0 # contador para entrar en la posición de la lista que deseamos for tree in tree_to_add: # con este bucle añado el nº de árboles que hay para cada CD puesta por el usuario for k in distribution: # para cada CD puesta por el usuario if tree.dbh >= distribution[count][0] and tree.dbh < distribution[count][1]: # si se cumplen los límites de diámetro # var += 1 # añadimos 1 al nº de árboles que cumplen la condición sum_g += tree.basal_area # * tree.expan --> no se multiplica por tree.expan break # pasamos al siguiente árbol else: # si se deja de cumplir la condición de diámetro (los árboles están ordenados por dbh, de menor a mayor) # distribution[count].append(var) # añadimos el nº de árboles a la lista distribution[count].append(sum_g) # añadimos la suma de secciones normales por CD a la lista count += 1 # avanzamos una posición en la lista # var = 0 # comenzamos la cuenta desde 0 sum_g = 0 # comenzamos la cuenta desde 0 # distribution[count].append(var) # esto es necesario para añadir el valor a la última CD distribution[count].append(sum_g) # esto es necesario para añadir el valor a la última CD for tree in tree_to_add: # aquí se repartirá el valor del área basimétrica en las distintas clases diamétricas (propuestas en el modelo), de manera equitativa para cada árbol for k in distribution: # para cada CD if tree.dbh >= k[0] and tree.dbh < k[1]: # si se cumplen los límites de diámetro (ordenados de menor a mayor) new_d_tree = Tree() # estos árboles serán los que se muestran sin status y pasan a la siguiente ejecución new_d_tree.clone(tree) new_d_tree.add_value('expan', (k[2]*10000) / k[3] + new_d_tree.expan) # añadimos la parte proporcional del expan a cada árbol # OJO! Si hubiera que meter de nuevo el nº de pies en cada CD, entonces las posiciones de las listas variarían! new_tree_add = Tree() # estos árboles serán los que se muestran con status = I new_tree_add.clone(tree) new_tree_add.add_value('status', 'I') # habría que conseguir que estos árboles aparecieran pintados en el output new_tree_add.add_value('expan', (k[2]*10000) / k[3]) # añadimos la parte proporcional del expan a cada árbol result_pies_mayores.append(new_d_tree) # añado los árboles con EXPAN modificado a la lista add_pies_mayores.append(new_tree_add) # añado los árboles con status = I a una nueva lista break # salto al árbol siguiente result_pies_mayores.extend(cut_pies_mayores) # se añaden los pies cortados result_pies_mayores.extend(dead_pies_mayores) # se añaden los pies muertos result_pies_mayores.extend(add_pies_mayores) # añado árboles con status = I new_plot.add_trees(result_pies_mayores) # new_plot.recalculate() --> Spiros try: model.process_plot(operation.get_variable('time'), new_plot, result_pies_mayores) except Exception as e: Tools.print_log_line(str(e), logging.ERROR) new_plot.recalculate() result_inventory.add_plot(new_plot) else: Tools.print_log_line('Plot ' + str(plot.id) + ' was not added', logging.INFO) return result_inventory
CPDs = {} for j in labels: parents = [z for z in labels if (labels.index(z),labels.index(j)) in edges] t,s = tags[labels.index(j)], tuple([tags[labels.index(i)] for i in parents]) key = tuple([j] + parents) first_index = sorted(key).index(j) other_indices = [sorted(key).index(p) for p in parents] transpose_order = tuple([first_index]+other_indices) m = marginals[tuple(sorted(key))].transpose(transpose_order) smoothing = 0#10**(-6) CPDs[t,s] = create_CPD(m, smoothing=smoothing, verbose=False) tree = TreeModel(CPDs, #dictionary of CPDs tags, #variable ids format="CPDs" #latent structure already holds cpds ) anchor_failures = {} anchor_noise = {} anchor_dict = {} for l,a in anchors.items(): anchor_dict[header[l]] = header[a] print 'a is', a #noise[a] holds P(anchor | latent) anchor_noise[header[a]] = 1-noise[a][1,0] print 'anchor',header[a], 'has noise', anchor_noise[header[a]] anchor_failures[header[l],header[a]] = noise[a][0,1] / anchor_noise[header[a]] print 'anchor',header[a], 'has failure', anchor_failures[header[l], header[a]]
parents = [ z for z in labels if (labels.index(z), labels.index(j)) in edges ] t, s = tags[labels.index(j)], tuple( [tags[labels.index(i)] for i in parents]) key = tuple([j] + parents) first_index = sorted(key).index(j) other_indices = [sorted(key).index(p) for p in parents] transpose_order = tuple([first_index] + other_indices) m = marginals[tuple(sorted(key))].transpose(transpose_order) smoothing = 0 #10**(-6) CPDs[t, s] = create_CPD(m, smoothing=smoothing, verbose=False) tree = TreeModel( CPDs, #dictionary of CPDs tags, #variable ids format="CPDs" #latent structure already holds cpds ) anchor_failures = {} anchor_noise = {} anchor_dict = {} for l, a in anchors.items(): anchor_dict[header[l]] = header[a] print 'a is', a #noise[a] holds P(anchor | latent) anchor_noise[header[a]] = 1 - noise[a][1, 0] print 'anchor', header[a], 'has noise', anchor_noise[header[a]] anchor_failures[header[l], header[a]] = noise[a][0, 1] / anchor_noise[header[a]]