Exemple #1
0
    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
Exemple #2
0
    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
Exemple #3
0
    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
Exemple #4
0
    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]]