예제 #1
0
def paste(widget):
    """Copies a widget (and all its children) from the clipboard to the given
    destination (parent, sizer and position inside the sizer). Returns True on success."""
    error = None
    if not wx.TheClipboard.Open():
        misc.error_message("Clipboard can't be opened.")
        return False

    try:
        data_object = None
        for fmt in [widget_data_format, sizer_data_format, window_data_format]:
            if wx.TheClipboard.IsSupported(fmt):
                data_object = wx.CustomDataObject(fmt)
                break
        if data_object is None:
            misc.info_message(
                "The clipboard doesn't contain wxGlade widget data.")
            return False
        if not wx.TheClipboard.GetData(data_object):
            misc.error_message("Data can't be copied from clipboard.")
            return False
    finally:
        wx.TheClipboard.Close()
    format_name = data_object.GetFormat().GetId().split(".")[
        1]  # e.g. 'wxglade.widget' -> 'widget'
    compatible, message = widget.check_compatibility(None, format_name)
    if not compatible:
        wx.Bell()
        if message:
            misc.error_message(message)
        return False
    if not widget.clipboard_paste(data_object.GetData()):
        misc.error_message("Paste failed")
    def generate_code(self, preview=False, out_path=None, widget=None):
        if config.use_gui:
            common.property_panel.flush()
        else:
            np.flush_current_property()
        if out_path is None:
            out_path = os.path.expanduser(self.output_path.strip())
            if not os.path.isabs(out_path) and (out_path and self.filename):
                out_path = os.path.join(os.path.dirname(self.filename),
                                        out_path)
                out_path = os.path.normpath(out_path)

        if not out_path:
            msg = "You must specify an output file before generating any code."
            if not self.filename:
                msg += "\nFor relative file names, the project needs to be saved first."
            return misc.error_message(msg)

        name_p = self.properties["name"]
        class_p = self.properties["class"]
        if self.language != "XRC":
            if not preview and (name_p.is_active() or
                                class_p.is_active()) and not self.top_window:
                return misc.error_message(
                    "Please select a top window for the application or deactivate "
                    "the Name and Class properties for Application.\n"
                    "In that case, only code for the windows will be generated, not for the "
                    "application.")

        if preview:
            writer = common.code_writers["python"].copy()
        else:
            writer = common.code_writers[self.language]  #.copy()

        try:
            writer.new_project(self, out_path, preview)
            writer.generate_code(self.node, widget)
            writer.finalize()
        except errors.WxgBaseException as inst:
            misc.error_message(_("Error generating code:\n%s") % inst)
            return
        except EnvironmentError as inst:
            bugdialog.ShowEnvironmentError(
                _('An IO/OS related error is occurred:'), inst)
            bugdialog.Show(_('Generate Code'), inst)
            return
        finally:
            writer.clean_up(self.node)

        if preview or not config.use_gui: return
        if config.preferences.show_completion:
            # Show informational dialog
            misc.info_message("Code generation completed successfully")
        else:
            # Show message in application status bar
            app = wx.GetApp()
            frame = app.GetTopWindow()
            frame.user_message(_('Code generated'))
예제 #3
0
    def gradient(self, params):
        """Manage the calculation of the gradient figure of merit.

        To calculate the gradient, we update the system, run a forward and
        adjoint simulation, and then calculate the gradient using
        :func:`calc_gradient`.  Most of these operations are done in parallel
        using MPI.

        Parameters
        ----------
        params : numpy.ndarray
            List of design parameters of the system

        Returns
        -------
        numpy.ndarray
            (Master node only) The gradient of the figure of merit computed  with 
            respect to the design variables
        """
        # update system
        self.update_system(params)
        self.sim.update()

        # run the forward simulation
        if (not np.array_equal(self.prev_params, params)):
            self.sim.solve_forward()

        # get dFdx which will be used as the source for the adjoint simulation
        # dFdx is calculated on the root node and then broadcast to the other
        # nodes.
        # TODO: parallelize this operation?
        comm = MPI.COMM_WORLD

        # This should return only non-null on RANK=0
        dFdx = self.calc_dFdx(self.sim, params)

        #if(isinstance(self.sim, fdfd.FDFD_TE)):
        dFdx = comm.bcast(dFdx, root=0)
        #elif(isinstance(self.sim, fdfd.FDFD_3D)):
        #    pass

        # run the adjoint source
        self.sim.set_adjoint_sources(dFdx)
        self.sim.solve_adjoint()

        if (NOT_PARALLEL):
            info_message('Calculating gradient...')

        grad_f = self.calc_gradient(self.sim, params)
        grad_y = self.calc_grad_y(self.sim, params)

        if (NOT_PARALLEL):
            return grad_f + grad_y
        else:
            return None
예제 #4
0
    def check_gradient(self, params, indices=[], plot=True):
        """Verify that the gradient is accurate.

        It is highly recommended that the accuracy of the gradients be checked
        prior to being used. If the accuracy is above ~1%, it is likely that
        there is an inconsitency between how the figure of merit and adjoint
        sources (dFdx) are being computed.

        The adjoint method gradient error is evaluated by comparing the
        gradient computed using the adjoint method to a gradient computed by
        direct finite differences.  In other words, the "correct" derivatives
        to which the adjoint method gradient is compared are given by

        .. math::
            \\frac{\partial F}{\partial p_i} \\approx \\frac{F(p_i + \Delta p) - F(p_i)}{\Delta p}

        Note that this method for calculating the gradient is not used in a
        practical setting because it requires performing N+1 simulations in
        order to compute the gradient with respect to N design variables
        (compared to only 2 simulations in the case of the adjoint method).

        Parameters
        ----------
        params : numpy.ndarray
            design parameters
        indices : list or numpy.ndarray
            list of gradient indices to check. An empty list indicates that the
            whole gradient should be verified. A subset of indices may be
            desirable for large problems.  (default = [])

        Returns
        -------
        float
            Relative error in gradient.
        """

        if (indices == []):
            indices = np.arange(0, len(params), 1)

        # make sure everything is up to date
        self.update_system(params)
        self.sim.update()

        grad_am = self.gradient(params)
        grad_fd = np.zeros(len(indices))

        fom0 = self.fom(params)

        # calculate the "true" derivatives using finite differences
        if (NOT_PARALLEL):
            info_message('Checking gradient...')

        for i in range(len(indices)):
            if (NOT_PARALLEL):
                print('\tDerivative %d of %d' % (i + 1, len(indices)))

            j = indices[i]
            p0 = params[j]
            params[j] += self._step
            fom1 = self.fom(params)
            if (NOT_PARALLEL):
                grad_fd[i] = (fom1 - fom0) / self._step
            params[j] = p0

        if (NOT_PARALLEL):
            errors = np.abs(grad_fd - grad_am[indices]) / np.abs(grad_fd)
            error_tot = np.linalg.norm(
                grad_fd - grad_am[indices]) / np.linalg.norm(grad_fd)

            if (error_tot < 0.01):
                info_message('The total error in the gradient is %0.4E' % \
                             (error_tot))
            else:
                warning_message('The total error in the gradient is %0.4E '
                                'which is over 1%%' % (error_tot), \
                                'emopt.adjoint_method')

            if (plot):
                import matplotlib.pyplot as plt
                f = plt.figure()
                ax1 = f.add_subplot(311)
                ax2 = f.add_subplot(312)
                ax3 = f.add_subplot(313)

                ax1.bar(indices, grad_fd)
                ax1.set_title('Finite Differences')
                ax2.bar(indices, grad_am[indices])
                ax2.set_title('Adjoint Method')
                ax3.bar(indices, errors)
                ax3.set_title('Error in Adjoint Method')

                ax3.set_yscale('log', nonposy='clip')

                plt.show()

            return error_tot
        else:
            return None
예제 #5
0
    def generate_code(self, preview=False, out_path=None, widget=None):
        np.flush_current_property()
        if out_path is None:
            out_path = os.path.expanduser(self.output_path.strip())
            if not out_path and self.multiple_files: out_path = "."
            if not os.path.isabs(out_path) and (out_path and self.filename):
                out_path = os.path.join(os.path.dirname(self.filename),
                                        out_path)
                out_path = os.path.normpath(out_path)

        if not out_path:
            msg = "You must specify an output file before generating any code."
            if not self.filename:
                msg += "\nFor relative file names, the project needs to be saved first."
            return misc.error_message(msg)

        name_p = self.properties["name"]
        class_p = self.properties["class"]
        if self.language != "XRC":
            if not preview and (name_p.is_active() or
                                class_p.is_active()) and not self.top_window:
                return misc.error_message(
                    "Please select a top window for the application or deactivate "
                    "the Name and Class properties for Application.\n"
                    "In that case, only code for the windows will be generated, not for the "
                    "application.")

        if preview:
            writer = common.code_writers["preview"]
        else:
            writer = common.code_writers[self.language]

        error = writer.new_project(self, out_path, preview)
        if error:
            # prerequisites were checked and there is a problem
            misc.error_message(_("Error generating code:\n%s") % error)
            return

        try:
            writer.generate_code(self, widget)
            writer.finalize()
        except EnvironmentError as inst:
            bugdialog.ShowEnvironmentError(
                _('An IO related error has occurred:'), inst)
            return
        except UnicodeEncodeError as inst:
            msg = _("Could not convert generated source code to encoding %s.\n"
                    '(characters "%s")')
            chars = inst.object[inst.start:
                                inst.end]  # .encode('unicode-escape')
            msg = msg % (self.encoding, chars)
            misc.error_message(msg)
            return
        except Exception as inst:
            # unexpected / internal error
            if config.testing or config.debugging: raise
            bugdialog.Show(_('Generate Code'), inst)
            return
        finally:
            writer.clean_up(widget or self)

        if preview or not config.use_gui: return
        if config.preferences.show_completion:
            # Show informational dialog
            misc.info_message("Code generation completed successfully")
        else:
            # Show message in application status bar
            app = wx.GetApp()
            frame = app.GetTopWindow()
            frame.user_message(_('Code generated'))