Exemplo n.º 1
0
    def is_respected(self, comp: AbstractComponent, comp_port_id: int,
                     ngbr: AbstractComponent, ngbr_port_id: int,
                     field: Field) -> bool:
        flag = True
        wait_policy: List[List[int]] = ngbr.get_wait_policy(ngbr_port_id)
        if (wait_policy):
            if (self._stack.get(ngbr) is None):
                self._stack[ngbr] = ([ngbr_port_id], [field])
            else:
                self._stack[ngbr][0].append(ngbr_port_id)
                self._stack[ngbr][1].append(field)
            # If more than one policy matches, take the first one
            flag = False
            i = 0
            while (i < len(wait_policy) and not flag):
                port_count: List[int] = [
                    self._stack[ngbr][0].count(wait_port)
                    for wait_port in wait_policy[i]
                ]
                if (0 not in port_count):
                    flag = True
                    self._stack_policy[ngbr] = wait_policy[i]
                i += 1
            if (not flag):
                util.print_terminal(
                    "Signal is waiting for fields "
                    "arriving at other ports.", '')

        return flag
Exemplo n.º 2
0
    def _respect_waiting(self, comp: AbstractComponent,
                         neighbor: AbstractComponent, port: int, field: Field,
                         input_port: int) -> bool:
        flag = True
        wait_policy: List[List[int]] = neighbor.get_wait_policy(input_port)
        if (wait_policy):
            if (self._stack_waiting.get(neighbor) is None):
                self._stack_waiting[neighbor] = ([input_port], [field])
            else:
                self._stack_waiting[neighbor][0].append(input_port)
                self._stack_waiting[neighbor][1].append(field)
            # If more than one policy matches, take the first one
            flag = False
            i = 0
            while (i < len(wait_policy) and not flag):
                port_count = [
                    self._stack_waiting[neighbor][0].count(wait_port)
                    for wait_port in wait_policy[i]
                ]
                if (0 not in port_count):
                    flag = True
                    self._stack_wait_policy[neighbor] = wait_policy[i]
                i += 1
            if (not flag):
                util.print_terminal(
                    "Signal is waiting for fields "
                    "arriving at other ports.", '')

        return flag
Exemplo n.º 3
0
    def __str__(self) -> str:

        util.print_terminal("State of component '{}':".format(self.name))
        for i in range(self._nbr_ports):
            print(self._ports[i])

        return str()
Exemplo n.º 4
0
 def _print_computation_state(self, elapsed_time: float) -> None:
     str_to_print = ("Solved method(s) {} ({} steps) ".format(
         self._methods[0], self._steps[0]))
     for i in range(1, len(self._methods)):
         str_to_print += "and {} ({} steps) ".format(
             self._methods[i], self._steps[i])
     str_to_print += "for {} km length in {} s".format(
         self._length, str(elapsed_time))
     util.print_terminal(str_to_print, '')
Exemplo n.º 5
0
def plot_graph(fig, resolution, fig_title, filename):
    if (fig_title is not None):
        fig.suptitle(fig_title, fontsize=16)
    fig.tight_layout()  # Avoiding overlapping texts (legend)
    fig.set_size_inches(resolution[0]/fig.dpi, resolution[1]/fig.dpi)
    if (filename != ""):
        fig.savefig(filename, bbox_inches='tight')
        util.print_terminal("Graph has been saved on filename '{}'"
                            .format(filename))
    else:
        plt.show()
Exemplo n.º 6
0
    def __str__(self):

        if (self._comps):
            util.print_terminal("Structure of layout '{}':".format(self.name))
            for comp in self._comps:
                for port_nbr in range(len(comp)):
                    if (comp.get_neighbor(port_nbr) is not None):
                            comp.print_port_state(port_nbr)
        else:
            util.print_terminal("Layout '{}' is empty".format(self.name))

        return str()
Exemplo n.º 7
0
    def __str__(self):

        if (self._comps):
            util.print_terminal("Structure of layout '{}':".format(self.name))
            for comp in self._comps:
                for port in comp:
                    if (not port.is_free()):
                        print(port)
        else:
            util.print_terminal("Layout '{}' is empty".format(self.name))

        return str()
Exemplo n.º 8
0
    def _respect_coprop(self, comp: AbstractComponent,
                        neighbor: AbstractComponent, port: int, field: Field,
                        input_port: int) -> bool:
        """Check if need to wait for other copropagating fields."""
        flag = True
        if (self._stack_coprop.get((comp, port)) is not None):
            self._stack_coprop[(comp, port)][1][0] -= 1
            if (self._stack_coprop[(comp, port)][1][0] > 0):
                flag = False
                util.print_terminal("Signal is waiting for copropagating "
                    "fields.", '')

        return flag
Exemplo n.º 9
0
    def is_respected(self, comp: AbstractComponent, comp_port_id: int,
                     ngbr: AbstractComponent, ngbr_port_id: int,
                     field: Field) -> bool:
        flag = True
        comp_port: Port = comp[comp_port_id]
        if (self._stack.get(comp_port) is not None):
            self._stack[comp_port][1][0] -= 1
            if (self._stack[comp_port][1][0] > 0):
                flag = False
                util.print_terminal(
                    "Signal is waiting for copropagating "
                    "fields.", '')

        return flag
Exemplo n.º 10
0
    def _shooting_method(self, waves: Array[cst.NPFT], solvers: List[Solver],
                         eqs: List[AbstractEquation], steps: int,
                         step_method: STEP_METHOD_TYPE) -> Array[cst.NPFT]:

        # N.B.: take last equation to get criterion by defaults
        #       -> need to handle different cases that might pop up

        def apply_ic(eqs, waves_init, end):

            res = np.zeros_like(waves_init)
            for eq in eqs:
                res = eq.initial_condition(waves_init, end)

            return res

        error_bound = self._error
        # First iteration for co-prop or counter prop scheme
        if (self._start_shooting_forward):
            waves_f = apply_ic(eqs, waves, False)
            waves_f = step_method(waves_f, solvers, steps, True, 1)
        else:
            waves_b = apply_ic(eqs, waves, True)
            waves_b = step_method(waves_b, solvers, steps, False, -2)
            waves_f = apply_ic(eqs, waves, False)
            waves_f = step_method(waves_f, solvers, steps, True, 1)
        # Start loop till convergence criterion is met
        cached_criterion = 0.0
        error = error_bound * 1e10
        while (error > error_bound):
            waves_f_back_up = waves_f
            waves_b = apply_ic(eqs, waves_f, True)
            waves_b = step_method(waves_b, solvers, steps, False, -2)
            waves_f = apply_ic(eqs, waves_b, False)
            waves_f = step_method(waves_f, solvers, steps, True, 1)
            new_cached_criterion = eqs[-1].get_criterion(waves_f, waves_b)
            old_error = error
            error = abs(cached_criterion - new_cached_criterion)
            util.print_terminal(
                "Shooting method is running and got error = {}".format(error),
                '')
            cached_criterion = new_cached_criterion
            if (old_error < error):
                util.warning_terminal(
                    "Shooting method stopped before "
                    "reaching error bound value as error is increasing.")
                error = 0.0
                waves_f = waves_f_back_up

        return waves_f
Exemplo n.º 11
0
    def method_wrapper(self, *args, **kwargs):
        back_up_residual: float = self.residual
        res: bool = has_converged(self, *args, **kwargs)
        # Stop if divergence not accepted
        if (self._crt_iter and self.residual > back_up_residual):
            util.warning_terminal("Divergent method !")
            if (self.stop_if_divergent):
                res = True
        self._crt_iter += 1
        # Stop if the maximum nbr of steps is reached
        if (not res and self._crt_iter >= self._max_nbr_iter):
            util.print_terminal("Maximum number of iterations reached.", '')
            res = True
        if (res):
            self.reset()

        return res
Exemplo n.º 12
0
    def __call__(self, domain: Domain, ports: List[int],
                 fields: List[Field]) -> Tuple[List[int], List[Field]]:

        if (os.path.isfile(self._full_path_to_file) and self.add_fields):
            with open(self._full_path_to_file, 'ab') as file_container:
                pickle.dump(fields, file_container)
            util.print_terminal(
                "{} field(s) added to existing file '{}'.".format(
                    len(fields), self.file_name))
        else:
            with open(self._full_path_to_file, 'wb') as file_container:
                pickle.dump(fields, file_container)
                util.print_terminal(
                    "{} field(s) added in new file '{}'.".format(
                        len(fields), self.file_name))

        return self.output_ports(ports), []
Exemplo n.º 13
0
 def _init_propagation(self, comp: AbstractComponent, output_port: int,
                       output_field: Field) -> None:
     """Propagate one Field"""
     # Recording field ----------------------------------------------
     if (comp.save or (comp in self._leaf_comps)):
         comp[output_port].save_field(output_field)
     # Propagate output_field to neighbors of comp ------------------
     neighbor: Optional[AbstractPassComp] = None
     potential_neighbor = comp[output_port].ngbr_comp
     if (isinstance(potential_neighbor, AbstractPassComp)):  # no starter
         neighbor = potential_neighbor
     if (neighbor is not None):
         input_port_neighbor = comp[output_port].ngbr_port
         if (not neighbor[input_port_neighbor].is_unidir()):
             if (neighbor.save):  # Recording field
                 neighbor[input_port_neighbor].save_field(output_field)
             # Valid propagation management -----------------------------
             util.print_terminal(
                 "Component '{}' has sent a signal from "
                 "port {} to port {} of component '{}'.".format(
                     comp.name, output_port, input_port_neighbor,
                     neighbor.name))
             input_ports_neighbor, output_fields = \
                 self._comply_with_constraints(comp, neighbor, output_port,
                                               output_field,
                                               input_port_neighbor)
             if (output_fields):  # Constraints respected
                 if (self._check_field_time_overlap(output_fields)):
                     # Make sure time windows overlap if >1 field
                     field_time_data = self._match_field_time(output_fields)
                     # Send the fields into the component
                     output_ports_neighbor, output_fields_neighbor =\
                         neighbor(self.domain, input_ports_neighbor,
                                  output_fields)
                     # Reset original time window
                     self._reset_field_time(output_fields, field_time_data)
                     # Recursive function
                     self._propagate(neighbor, output_ports_neighbor,
                                     output_fields_neighbor)
                 else:  # Time window of output_fields not overlapping
                     util.warning_terminal(
                         "Fields can not be accepted at "
                         "the entrance of component '{}' as their time "
                         "windows are not overlapping.".format(
                             neighbor.name), '')
Exemplo n.º 14
0
    def _add_edge(self, comp_1: AbstractComponent, port_comp_1: int,
                  comp_2: AbstractComponent, port_comp_2: int,
                  unidir: bool = False) -> None:
        """Add a new edge in the Layout

        The edge can be either unidirectionnal or bidirectionnal.  In
        case of bidirectionnal edge, only the first component is linked
        to the second one.

        Parameters
        ----------
        comp_1 : AbstractComponent
            The first component of the edge.
        port_comp_1 :
            The port of the first component.
        comp_2 : AbstractComponent
            The second component of the edge.
        port_comp_2 :
            The port of the second component.
        unidir :
            If True, unidirectionnal link.

        """
        # Adding new edge ----------------------------------------------
        if (comp_1.is_port_free(port_comp_1)
                and comp_2.is_port_free(port_comp_2) and comp_1 != comp_2):
            self.add_comp(comp_1)
            self.add_comp(comp_2)
            comp_1.link_to(port_comp_1, comp_2, port_comp_2)
            if (unidir):    # Undirected edge
                comp_2.link_to(port_comp_2, comp_1, cst.UNIDIR_PORT)
            else:   # Directed edge
                comp_2.link_to(port_comp_2, comp_1, port_comp_1)
        # Edge can not be added ----------------------------------------
        else:
            util.warning_terminal("Linking of component '{}' and component "
                "'{}' has encountered a problem, action aborted:"
                .format(comp_1.name, comp_2.name))
            if (comp_1 == comp_2):
                util.print_terminal("Component '{}' can not be linked to "
                    "itself".format(comp_1.name), '')
            else:
                comp_1.print_port_state(port_comp_1)
                comp_2.print_port_state(port_comp_2)
Exemplo n.º 15
0
    def _add_edge(self,
                  port_1: Port,
                  port_2: Port,
                  unidir: bool = False) -> None:
        """Add a new edge in the Layout

        The edge can be either unidirectionnal or bidirectionnal.  In
        case of unidirectionnal edge, only the first component is linked
        to the second one.

        Parameters
        ----------
        port_1 : Port
            The first port of the edge.
        port_2 : Port
            The second port of the edge.
        unidir :
            If True, unidirectionnal link.

        """
        # Adding new edge ----------------------------------------------
        free_ports = port_1.is_free() and port_2.is_free()
        if (free_ports and port_1.comp != port_2.comp):
            self.add_comp(port_1.comp)
            self.add_comp(port_2.comp)
            port_1.link_to(port_2)
            if (unidir):  # Undirected edge
                port_2.link_unidir_to(port_1)
            else:  # Directed edge
                port_2.link_to(port_1)
        # Edge can not be added ----------------------------------------
        else:
            util.warning_terminal(
                "Linking of component '{}' and component "
                "'{}' has encountered a problem, action aborted:".format(
                    port_1.comp.name, port_2.comp.name))
            if (port_1.comp == port_2.comp):
                util.print_terminal(
                    "Component '{}' can not be linked to "
                    "itself".format(port_1.comp.name), '')
            else:
                print(port_1)
                print(port_2)
Exemplo n.º 16
0
    def print_port_state(self, port_nbr: int) -> None:

        if (self.is_port_valid(port_nbr)):
            port_ = self._ports[port_nbr]
            if (port_ is None):
                util.print_terminal("Port {} of component '{}' is free."
                      .format(port_nbr, self.name), '')
            else:
                if (port_[1] != cst.UNIDIR_PORT):
                    util.print_terminal("Port {} of component '{}' is linked "
                        "to port {} of component '{}'."
                        .format(port_nbr, self.name, port_[1], port_[0].name),
                        '')
                else:
                    util.print_terminal("Port {} of component '{}' has an "
                        "unidirectionnaly link from component '{}'."
                        .format(port_nbr, self.name, port_[0].name), '')
Exemplo n.º 17
0
    def __str__(self) -> str:
        if (self._ngbr_comp is None):
            util.print_terminal(
                "Port {} of component '{}' is free.".format(
                    self._port, self._comp.name), '')
        else:
            if (self._unidir):
                util.print_terminal(
                    "Port {} of component '{}' has an "
                    "unidirectionnal link from component '{}'.".format(
                        self._port, self._comp.name, self._ngbr_comp.name), '')
            else:
                util.print_terminal(
                    "Port {} of component '{}' is linked "
                    "to port {} of component '{}'.".format(
                        self._port, self._comp.name, self._ngbr_port,
                        self._ngbr_comp.name), '')

        return str()
Exemplo n.º 18
0
    def _shooting_method(
            self, waves: np.ndarray, noises: np.ndarray,
            solvers: List[AbstractSolver],
            noise_solvers: List[Optional[AbstractSolver]],
            eqs: List[SOLVER_CALLABLE_TYPE], steps: int,
            step_method: STEP_METHOD_TYPE) -> Tuple[np.ndarray, np.ndarray]:
        """Run the shooting algorithm."""
        if ((self._boundary_cond is not None)
                and (self._conv_checker is not None)):
            # Aliases for cleaner code
            forward = lambda waves, noises: self._forward_method(
                waves, noises, solvers, noise_solvers, eqs, steps, step_method,
                True)
            backward = lambda waves, noises: self._backward_method(
                waves, noises, solvers, noise_solvers, eqs, steps, step_method,
                True)
            apply_cond = lambda waves, noises, fiber_end:\
                self._boundary_cond.apply_cond(waves, noises, fiber_end)
            get_input = lambda waves, noises, fiber_end:\
                self._boundary_cond.get_input(waves, noises, fiber_end)
            get_output = lambda waves, waves_, noises, noises_:\
                self._boundary_cond.get_output(waves, waves_, noises, noises_)
            has_converged = lambda waves, waves_, noises, noises_:\
                self._conv_checker.has_converged(np.vstack((waves, waves_)),
                                                 np.vstack((noises, noises_)))
            converged: bool = False
            first_iter: bool = True
            waves_b: np.ndarray  # Backward propagating waves
            waves_f: np.ndarray  # Forward propagating waves
            noises_b: np.ndarray  # Backward propagating noises
            noises_f: np.ndarray  # Forward propagating noises
            # Start loop till convergence criterion is met
            while (not converged):
                if (first_iter):
                    waves_b, noises_b = get_input(waves, noises, True)
                    first_iter = False
                else:
                    waves_b, noises_b = apply_cond(waves_f, noises_f, True)
                waves_b, noises_b = backward(waves_b, noises_b)
                waves_f, noises_f = apply_cond(waves_b, noises_b, False)
                waves_f, noises_f = forward(waves_f, noises_f)
                converged = has_converged(waves_f, waves_b, noises_f, noises_b)
                util.print_terminal(
                    "Shooting method is running and got "
                    "residual = {}".format(self._conv_checker.residual), '')
            waves, noises = get_output(waves_f, waves_b, noises_f, noises_b)
            # Save channels and noises to storage if required
            if (self.save_all and self._channels.size):
                channels_f = self._channels[:(len(self._channels) // 2)]
                channels_b = self._channels[(len(self._channels) // 2):]
                noises_f = self._noises[:(len(self._noises) // 2)]
                noises_b = self._noises[(len(self._noises) // 2):]
                self._channels, self._noises = get_output(
                    channels_f, channels_b, noises_f, noises_b)
        else:

            raise MissingInfoError(
                "Boundary condition and convergence "
                "checker must be provided for running shooting method.")

        return waves, noises
Exemplo n.º 19
0
def animation2d(x_datas: np.ndarray,
                y_datas: np.ndarray,
                z_datas: Optional[np.ndarray] = None,
                x_label: Optional[str] = None,
                y_label: Optional[str] = None,
                x_range: Optional[Tuple[float, float]] = None,
                y_range: Optional[Tuple[float, float]] = None,
                line_styles: List[str] = ['-'],
                line_widths: List[float] = [1.],
                line_labels: Optional[List[Optional[str]]] = None,
                line_colors: Optional[List[str]] = None,
                line_opacities: List[float] = [0.2],
                plot_title: Optional[str] = None,
                fig_title: Optional[str] = None,
                filename: str = "",
                resolution: Tuple[float, float] = (1920., 1080.),
                interval: float = 100.,
                repeat: bool = True,
                repeat_delay: float = 1000.) -> None:
    """Plot an 2D animation.

    Parameters
    ----------
    x_datas :
        The data on the x axis.
    y_datas :
        The data on the y axis.
    z_datas :
        The data on the z axis, will be display as text
    x_label :
        The labels for each axis along the x axis.
    y_label :
        The labels for each axis along the y axis.
    x_range :
        The ranges for each axis along the x axis.
    y_range :
        The ranges for each axis along the y axis.
    line_styles :
        The linestyle of the line.
    line_widths :
        The linewidth of the line.
    line_labels :
        The labels for each line.
    line_colors :
        The color of each line.
    line_opacities :
        The opacity of each line.
    plot_title :
        The title of the animation.
    fig_title :
        The figure title.
    filename :
        The filename where to save the animation. If provided, the
        animation will be saved.
    resolution :
        The resolution with which to save the animation.
    interval :
        The interval in between each frame.
    repeat :
        Either to repeat the animation when it is displayed.
    repeat_delay :
        The delay in between each repetition.

    """
    # N.B. if y_datas comes from field, np.ndarray is multidim
    # Initializing -----------------------------------------------------
    fig = plt.gcf()
    ax = plt.axes()
    # Managing x and y labels ------------------------------------------
    x_label_: Optional[str]
    x_label_ = check_axis_labels([x_label], axis_labels)[0]
    y_label_: Optional[str]
    y_label_ = check_axis_labels([y_label], axis_labels)[0]
    if (x_label_ is not None):
        plt.xlabel(x_label_)
    if (y_label_ is not None):
        plt.ylabel(y_label_)
    # Plot title -------------------------------------------------------
    if (plot_title is not None):
        plt.title(plot_title)
    # Padding ----------------------------------------------------------
    nbr_channels: int = 1
    nbr_images: int = 1
    y_datas_: np.ndarray
    x_datas_: np.ndarray
    if (y_datas.ndim == 3):  #  (channels, image, y_data)
        nbr_channels = y_datas.shape[0]
        nbr_images = y_datas.shape[1]
        if (x_datas.ndim < 2):
            x_datas_ = util.vstack_ndarray(np.array([x_datas]), nbr_images)
            x_datas_ = util.vstack_ndarray(np.array([x_datas_]), nbr_channels)
        elif (x_datas.ndim < 3):
            x_datas_ = util.vstack_ndarray(x_datas, nbr_images)
            x_datas_ = util.vstack_ndarray(np.array([x_datas_]), nbr_channels)
        else:  # Should be ndim = 3
            if (nbr_channels > x_datas.shape[0]):
                x_datas_ = util.vstack_ndarray([x_datas_], nbr_channels)
            else:
                x_datas_ = x_datas
        y_datas_ = y_datas
    elif (y_datas.ndim == 2):  # (image, y_data)
        nbr_images = y_datas.shape[0]
        if (x_datas.ndim < 2):
            x_datas_ = util.vstack_ndarray(np.array([x_datas]), nbr_images)
        else:
            if (nbr_images > x_datas.shape[0]):
                x_datas_ = util.vstack_ndarray(x_datas, len(y_datas))
            else:
                x_datas_ = x_datas
        y_datas_ = y_datas
        x_datas_ = np.array([x_datas_])
        y_datas_ = np.array([y_datas_])
    else:
        util.warning_terminal(
            "The y_datas must be at least two dimensional, "
            "shape can be (image, y_data) or (channels, image, y_data)")

        return None
    # Lines charact. management ----------------------------------------
    line_styles = util.make_list(line_styles, nbr_channels)
    line_widths = util.make_list(line_widths, nbr_channels)
    line_opacities = util.make_list(line_opacities, nbr_channels)
    # Lables management ------------------------------------------------
    line_labels = util.make_list(line_labels, nbr_channels, '')
    line_labels_: List[str] = []
    if (line_labels is not None):
        for i in range(nbr_channels):
            crt_line_label = line_labels[i]
            if (crt_line_label is None or crt_line_label == ''):
                line_labels_.append("channel {}".format(i))
            else:
                line_labels_.append(crt_line_label + " (ch.{})".format(i))
    # Colors management ------------------------------------------------
    if (line_colors is not None):
        line_colors_ = line_colors
    else:
        line_colors_ = linecolors
    # Line2D creation --------------------------------------------------
    lines = []
    for i in range(nbr_channels):
        line = ax.plot([], [],
                       c=line_colors_[i % len(line_colors_)],
                       ls=line_styles[i],
                       label=line_labels_[i],
                       lw=line_widths[i])[0]
        lines.append(line)
    plt.ticklabel_format(axis='both', style='sci', scilimits=(-2, 2))
    if (line_labels is not None):
        plt.legend(loc="best")
    min_y = 0.
    max_y = 0.
    if (y_range is None):
        max_y = np.amax(y_datas_)
        max_y = max_y + 0.2 * max_y
        ax.set_ylim(0., max_y)
    else:
        max_y = y_range[1]
        ax.set_ylim(y_range[0], max_y)
    # Animation creation -----------------------------------------------
    text_plot = [ax.text(0., 0., '', style='italic', fontsize=10)]
    fill_lines = []
    for j, line in enumerate(lines):
        fill_lines.append(ax.fill_between([], []))

    def update(i):
        mins: List[float] = []
        maxs: List[float] = []
        for j, line in enumerate(lines):  # Browsing channels -> plots
            fill_lines[j].remove()
            line.set_data(x_datas_[j][i], y_datas_[j][i])
            facecolor = line_colors_[j % len(line_colors_)]
            fill_lines[j] = ax.fill_between(x_datas_[j][i],
                                            y_datas_[j][i],
                                            alpha=line_opacities[j],
                                            facecolor=facecolor)
            mins.append(x_datas_[j][i][0])
            maxs.append(x_datas_[j][i][-1])

        if (x_range is None):
            min_x = min(mins)
            max_x = max(maxs)
            ax.set_xlim(min_x, max_x)
        else:
            min_x = x_range[0]
            max_x = x_range[1]
            ax.set_xlim(x_range[0], x_range[1])
        if (z_datas is not None):
            x_pos = max_x - (max_x - min_x) * 0.1
            y_pos = min_y + (max_y - min_y) * 0.1
            text_plot[0].set_position((x_pos, y_pos))
            text_plot[0].set_text("z = {} km".format(str(z_datas[i])))

        return lines

    def init():
        for line in lines:
            line.set_data([], [])

        return lines

    ani = animation.FuncAnimation(fig,
                                  update,
                                  frames=nbr_images,
                                  interval=interval,
                                  repeat=repeat,
                                  repeat_delay=repeat_delay,
                                  init_func=init)
    # Plotting / saving ------------------------------------------------
    if (fig_title is not None):
        fig.suptitle(fig_title, fontsize=16)
    fig.tight_layout()  # Avoiding overlapping texts (legend)
    fig.set_size_inches(resolution[0] / fig.dpi, resolution[1] / fig.dpi)
    if (filename != ""):
        ani.save(filename)
        util.print_terminal(
            "Graph has been saved on filename '{}'".format(filename))
        fig.clf()
    else:
        plt.show()
Exemplo n.º 20
0
def plot(x_datas: List[Array[float]],
         y_datas: List[Array[float]],
         x_labels: Optional[List[str]] = None,
         y_labels: Optional[List[str]] = None,
         x_ranges: Optional[List[float]] = None,
         y_ranges: Optional[List[float]] = None,
         plot_linestyles: List[str] = ['-'],
         plot_labels: List[Optional[Union[str, List[str]]]] = [None],
         plot_titles: Optional[List[str]] = None,
         plot_colors: Optional[List[str]] = None,
         plot_groups: Optional[List[int]] = None,
         split: Optional[bool] = None,
         opacity: float = 0.2,
         fig_title: Optional[str] = None,
         filename: str = ""):

    # N.B. if y_datas comes from field, np.ndarray is multidim
    # initializing -----------------------------------------------------
    plt.clf()
    # Managing x and y labels ------------------------------------------
    x_labels = check_xy_labels(x_labels, xy_labels)
    y_labels = check_xy_labels(y_labels, xy_labels)
    # Padding ----------------------------------------------------------
    y_datas = util.make_list(y_datas)
    x_datas = util.make_list(x_datas, len(y_datas))
    if (len(y_datas) < len(x_datas)):
        util.warning_terminal(
            "The number of y data must be equal or greater "
            "than the number of x data, graph creation aborted.")
        return None
    #x_datas, y_datas = util.pad_list_with_last_elem(x_datas, y_datas, True)
    x_labels = util.make_list(x_labels, len(x_datas))
    y_labels = util.make_list(y_labels, len(y_datas))
    x_ranges = util.make_list(x_ranges, len(x_datas))
    y_ranges = util.make_list(y_ranges, len(y_datas))
    plot_labels = util.make_list(plot_labels, len(x_datas))
    plot_colors = util.make_list(plot_colors, len(x_datas))
    plot_linestyles = util.make_list(plot_linestyles, len(x_datas))
    plot_titles = util.make_list(plot_titles, len(x_datas), '')
    if (plot_groups is not None):
        plot_groups = util.make_list(plot_groups, len(x_datas))
    # Preparing graph parameters
    if (split is None):
        if (plot_groups is None):
            nbr_graphs = 1
            graphs = [[i for i in range(len(x_datas))]]
        else:
            nbr_graphs = max(plot_groups) + 1
            graphs = [[] for i in range(nbr_graphs)]
            for i in range(len(plot_groups)):
                graphs[plot_groups[i]].append(i)
    else:
        if (split):
            nbr_graphs = len(x_datas)
            graphs = [[i] for i in range(len(x_datas))]
        else:
            nbr_graphs = 1
            graphs = [[i for i in range(len(x_datas))]]
    plot_titles, graphs = util.pad_list_with_last_elem(plot_titles, graphs)
    # Nonexistent field  management (no field recorded in component)
    for i in range(len(y_datas)):
        if (y_datas[i] is None):
            util.warning_terminal("Try to plot a nonexistent field!")
            y_datas[i] = np.zeros(0)
            x_datas[i] = np.zeros(0)
    # Plot graph -------------------------------------------------------
    if (nbr_graphs < 4):
        nbr_row = nbr_graphs
    elif (nbr_graphs == 4):
        nbr_row = 2
    else:
        nbr_row = 3
    nbr_col = math.ceil(nbr_graphs / nbr_row)
    for i, graph in enumerate(graphs):
        plt_to_add = plt.subplot(nbr_row, nbr_col, i + 1)
        for plot in graph:
            add_single_plot(plt_to_add, x_datas[plot], y_datas[plot],
                            x_labels[plot], y_labels[plot], x_ranges[plot],
                            y_ranges[plot], plot_titles[i], plot_labels[plot],
                            plot_linestyles[plot], plot_colors[plot], opacity)
    # Finalizing -------------------------------------------------------
    if (fig_title is not None):
        plt.suptitle(fig_title, fontsize=16)
    plt.tight_layout()  # Avoiding overlapping texts (legend)
    if (filename != ""):
        plt.savefig(filename)
        util.print_terminal(
            "Graph has been saved on filename '{}'".format(filename))
    else:
        plt.show()
Exemplo n.º 21
0
 def print_propagation(self, comp: AbstractComponent, comp_port_id: int,
                       ngbr: AbstractComponent, ngbr_port_id: int) -> None:
     util.print_terminal("Component '{}' has sent a signal from "
                         "port {} to port {} of component '{}'.".format(
                             comp.name, comp_port_id, ngbr_port_id,
                             ngbr.name))