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'))
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
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
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'))