Source code for openalea.elongwheat.converter

# -*- coding: latin-1 -*-

from __future__ import division  # use "//" to do integer division
import pandas as pd

from openalea.elongwheat import simulation

"""
    elongwheat.converter
    ~~~~~~~~~~~~~~~~~~~~~~~

    The module :mod:`elongwheat.converter` defines functions to convert
    :class:`dataframes <pandas.DataFrame>` to/from ElongWheat inputs or outputs format.

"""

#: the columns which define the topology in the input/output dataframe
HIDDENZONE_TOPOLOGY_COLUMNS = ['plant', 'axis', 'metamer']
ELEMENT_TOPOLOGY_COLUMNS = ['plant', 'axis', 'metamer', 'organ', 'element']  # Mature + emerging elements
AXIS_TOPOLOGY_COLUMNS = ['plant', 'axis']


[docs] def from_dataframes(hiddenzone_inputs, element_inputs, axis_inputs): """ Convert inputs/outputs from Pandas dataframe to Elong-Wheat format. :param pandas.DataFrame axis_inputs: axis inputs dataframe to convert, with one line by axis :param pandas.DataFrame hiddenzone_inputs: Hidden zone inputs dataframe to convert, with one line by Hidden zone. :param pandas.DataFrame element_inputs: Emergeing and mature element inputs dataframe to convert, with one line by element. :return: The inputs in a dictionary. :rtype: dict [str, dict] .. seealso:: :attr:`simulation.Simulation.inputs` for the structure of Elong-Wheat inputs. """ all_hiddenzone_dict = {} all_element_dict = {} all_axis_dict = {} all_length_dict = {} cumulated_internode_length = {} # -- Convert input dataframe into dictionaries hiddenzone_inputs_columns = hiddenzone_inputs.columns.difference(HIDDENZONE_TOPOLOGY_COLUMNS) emerging_element_inputs_columns = element_inputs.columns.difference(ELEMENT_TOPOLOGY_COLUMNS) axis_inputs_columns = axis_inputs.columns.difference(AXIS_TOPOLOGY_COLUMNS) for axis_inputs_id, axis_inputs_group in axis_inputs.groupby(AXIS_TOPOLOGY_COLUMNS): # Axis axis_inputs_series = axis_inputs_group.loc[axis_inputs_group.first_valid_index()] axis_inputs_dict = axis_inputs_series[axis_inputs_columns].to_dict() all_axis_dict[axis_inputs_id] = axis_inputs_dict # Complete dict of lengths all_length_dict[axis_inputs_id] = {} for i in range(axis_inputs_dict['nb_leaves']): all_length_dict[axis_inputs_id][i+1] = {'sheath': [], 'cumulated_internode': []} cumulated_internode_length[axis_inputs_id] = [] for element_inputs_id, element_inputs_group in sorted(element_inputs.groupby(ELEMENT_TOPOLOGY_COLUMNS)): # Elements element_inputs_series = element_inputs_group.loc[element_inputs_group.first_valid_index()] element_inputs_dict = element_inputs_series[emerging_element_inputs_columns].to_dict() all_element_dict[element_inputs_id] = element_inputs_dict # Complete dict of lengths axis_id, phytomer_id, organ = element_inputs_id[:2], element_inputs_id[2], element_inputs_id[3] if organ == 'sheath' and not element_inputs_dict['is_growing']: all_length_dict[axis_id][phytomer_id]['sheath'].append(element_inputs_dict['length']) elif organ == 'internode' and not element_inputs_dict['is_growing']: # WARNING: this algo won't copy previous internode length for a phytomer without internode cumulated_internode_length[axis_id].append(element_inputs_dict['length']) if not all_length_dict[axis_id][phytomer_id]['cumulated_internode']: # if list is empty for that phytomer, the list of all phytomer lengths is written all_length_dict[axis_id][phytomer_id]['cumulated_internode'].extend(cumulated_internode_length[axis_id]) else: # only the last internode length is written (case of organs with hidden and visible part) all_length_dict[axis_id][phytomer_id]['cumulated_internode'].append(element_inputs_dict['length']) for hiddenzone_inputs_id, hiddenzone_inputs_group in sorted(hiddenzone_inputs.groupby(HIDDENZONE_TOPOLOGY_COLUMNS)): # hiddenzone hiddenzone_inputs_series = hiddenzone_inputs_group.loc[hiddenzone_inputs_group.first_valid_index()] hiddenzone_inputs_dict = hiddenzone_inputs_series[hiddenzone_inputs_columns].to_dict() all_hiddenzone_dict[hiddenzone_inputs_id] = hiddenzone_inputs_dict # Complete dict of length axis_id = hiddenzone_inputs_id[:2] phytomer_id = hiddenzone_inputs_id[2] if hiddenzone_inputs_dict['leaf_is_emerged'] and hiddenzone_inputs_dict['leaf_is_growing']: growing_sheath_length = max(0, hiddenzone_inputs_dict['leaf_L'] - hiddenzone_inputs_dict['lamina_Lmax']) # TODO mettre ce calcul ailleurs certainement. all_length_dict[axis_id][phytomer_id]['sheath'].append(growing_sheath_length) if hiddenzone_inputs_dict['internode_is_growing']: cumulated_internode_length[axis_id].append(hiddenzone_inputs_dict['internode_L']) all_length_dict[axis_id][phytomer_id]['cumulated_internode'].extend(cumulated_internode_length[axis_id]) elif not hiddenzone_inputs_dict['internode_is_growing'] and hiddenzone_inputs_id + ('internode',) not in element_inputs.groupby(ELEMENT_TOPOLOGY_COLUMNS[:-1]).groups.keys(): all_length_dict[axis_id][phytomer_id]['cumulated_internode'].extend(cumulated_internode_length[axis_id]) return {'hiddenzone': all_hiddenzone_dict, 'elements': all_element_dict, 'axes': all_axis_dict, 'sheath_internode_lengths': all_length_dict}
[docs] def to_dataframes(data_dict): """ Convert outputs from Elong-Wheat format to Pandas dataframe. :param dict data_dict: The outputs in Elong-Wheat format. :return: One dataframe for hiddenzone outputs, one dataframe for element outputs and one dataframe for axis outputs. :rtype: (pandas.DataFrame, pandas.DataFrame, pandas.DataFrame) .. seealso:: :attr:`simulation.Simulation.outputs` for the structure of Elong-Wheat outputs. """ dataframes_dict = {} for (current_key, current_topology_columns, current_outputs_names) in (('hiddenzone', HIDDENZONE_TOPOLOGY_COLUMNS, simulation.HIDDENZONE_OUTPUTS), ('elements', ELEMENT_TOPOLOGY_COLUMNS, simulation.ELEMENT_OUTPUTS), ('axes', AXIS_TOPOLOGY_COLUMNS, simulation.AXIS_OUTPUTS)): current_data_dict = data_dict[current_key] current_ids_df = pd.DataFrame(current_data_dict.keys(), columns=current_topology_columns) current_data_df = pd.DataFrame(current_data_dict.values()) current_df = pd.concat([current_ids_df, current_data_df], axis=1) current_df.sort_values(by=current_topology_columns, inplace=True) current_columns_sorted = current_topology_columns + current_outputs_names current_df = current_df.reindex(current_columns_sorted, axis=1, copy=False) current_df.reset_index(drop=True, inplace=True) dataframes_dict[current_key] = current_df return dataframes_dict['hiddenzone'], dataframes_dict['elements'], dataframes_dict['axes']