def set_structure_data(self, *args): 'Called when the user presses [Get structure].' z = self.element.Z if z is None: return ref = ase.data.reference_states[z] if ref is None: structure = None else: structure = ref['symmetry'] if ref is None or structure not in [s[0] for s in self.structure_data]: ui.error( _('Unsupported or unknown structure'), _('Element = {0}, structure = {1}').format( self.element.symbol, structure)) return self.structure.value = structure a = ref['a'] self.a.value = a self.fourindex = self.needs_4index[structure] if self.fourindex: try: c = ref['c'] except KeyError: c = ref['c/a'] * a self.c.value = c
def add(self): newatoms = self.get_atoms() if newatoms is None: # Error dialog was shown return newcenter = self.getcoords() # Not newatoms.center() because we want the same centering method # used for adding atoms relative to selections (mean). previous_center = newatoms.positions.mean(0) newatoms.positions += newcenter - previous_center atoms = self.gui.atoms if len(atoms) and self.picky.value: from ase.geometry import get_distances disps, dists = get_distances(atoms.positions, newatoms.positions) mindist = dists.min() if mindist < 0.5: ui.showerror( _('Bad positions'), _('Atom would be less than 0.5 Å from ' 'an existing atom. To override, ' 'uncheck the check positions option.')) return self.gui.add_atoms_and_select(newatoms)
def status(self, atoms): # use where here: XXX natoms = len(atoms) indices = np.arange(natoms)[self.images.selected[:natoms]] ordered_indices = [ i for i in self.images.selected_ordered if i < len(atoms) ] n = len(indices) self.nselected = n if n == 0: self.window.update_status_line('') return Z = atoms.numbers[indices] R = atoms.positions[indices] if n == 1: tag = atoms.get_tags()[indices[0]] text = (u' #%d %s (%s): %.3f Å, %.3f Å, %.3f Å ' % ((indices[0], names[Z[0]], symbols[Z[0]]) + tuple(R[0]))) text += _(' tag=%(tag)s') % dict(tag=tag) magmoms = get_magmoms(self.atoms) if magmoms.any(): # TRANSLATORS: mom refers to magnetic moment text += _(' mom={0:1.2f}'.format(magmoms[indices][0])) charges = self.atoms.get_initial_charges() if charges.any(): text += _(' q={0:1.2f}'.format(charges[indices][0])) elif n == 2: D = R[0] - R[1] d = sqrt(np.dot(D, D)) text = u' %s-%s: %.3f Å' % (symbols[Z[0]], symbols[Z[1]], d) elif n == 3: d = [] for c in range(3): D = R[c] - R[(c + 1) % 3] d.append(np.dot(D, D)) a = [] for c in range(3): t1 = 0.5 * (d[c] + d[(c + 1) % 3] - d[(c + 2) % 3]) t2 = sqrt(d[c] * d[(c + 1) % 3]) try: t3 = acos(t1 / t2) except ValueError: if t1 > 0: t3 = 0 else: t3 = pi a.append(t3 * 180 / pi) text = (u' %s-%s-%s: %.1f°, %.1f°, %.1f°' % tuple([symbols[z] for z in Z] + a)) elif len(ordered_indices) == 4: angle = self.atoms.get_dihedral(*ordered_indices, mic=True) text = (u'%s %s → %s → %s → %s: %.1f°' % tuple([_('dihedral')] + [symbols[z] for z in Z] + [angle])) else: text = ' ' + formula(Z) self.window.update_status_line(text)
def about(name, version, webpage): text = [name, '', _('Version') + ': ' + version, _('Web-page') + ': ' + webpage] win = Window(_('About')) win.add(Text('\n'.join(text)))
def repeat_images(self, repeat): from ase.constraints import FixAtoms repeat = np.array(repeat) oldprod = self.repeat.prod() images = [] constraints_removed = False for i, atoms in enumerate(self): refcell = atoms.get_cell() fa = [] for c in atoms._constraints: if isinstance(c, FixAtoms): fa.append(c) else: constraints_removed = True atoms.set_constraint(fa) del atoms[len(atoms) // oldprod:] atoms *= repeat atoms.cell = refcell images.append(atoms) if constraints_removed: from ase.gui.ui import tk, showwarning # We must be able to show warning before the main GUI # has been created. So we create a new window, # then show the warning, then destroy the window. tmpwindow = tk.Tk() tmpwindow.withdraw() # Host window will never be shown showwarning( _('Constraints discarded'), _('Constraints other than FixAtoms ' 'have been discarded.')) tmpwindow.destroy() self.initialize(images, filenames=self.filenames) self.repeat = repeat
def set_structure_data(self, *args): 'Called when the user presses [Get structure].' if not self.element.check(): return z = self.element.Z ref = ase.data.reference_states[z] if ref is None: structure = None else: structure = ref['symmetry'] if ref is None or structure not in [s[0] for s in self.structure_data]: ui.error(_('Unsupported or unknown structure'), _('Element = {0}, structure = {1}') .format(self.element.symbol, structure)) return self.structure.value = structure a = ref['a'] self.a.value = a self.fourindex = self.needs_4index[structure] if self.fourindex: try: c = ref['c'] except KeyError: c = ref['c/a'] * a self.c.value = c
def __init__(self, gui): self.gui = gui selected = self.selection() if not selected.any(): ui.error(_('No atoms selected!')) return win = ui.Window(_('Modify')) element = Element(callback=self.set_element) win.add(element) win.add(ui.Button(_('Change element'), partial(self.set_element, element))) self.tag = ui.SpinBox(0, -1000, 1000, 1, self.set_tag) win.add([_('Tag'), self.tag]) self.magmom = ui.SpinBox(0.0, -10, 10, 0.1, self.set_magmom) win.add([_('Moment'), self.magmom]) atoms = self.gui.atoms Z = atoms.numbers if Z.ptp() == 0: element.Z = Z[0] tags = atoms.get_tags()[selected] if tags.ptp() == 0: self.tag.value = tags[0] magmoms = get_magmoms(atoms)[selected] if magmoms.round(2).ptp() == 0.0: self.magmom.value = round(magmoms[0], 2)
def get_atoms(self): # Get the text, whether it's a combobox item or not val = self.combobox.widget.get() if val == current_selection_string: selection = self.gui.images.selected.copy() if selection.any(): atoms = self.gui.atoms.copy() return atoms[selection[:len(self.gui.atoms)]] if val in atomic_numbers: # Note: This means val is a symbol! return Atoms(val) if val.isdigit() and int(val) < len(chemical_symbols): return Atoms(numbers=[int(val)]) from ase.collections import g2 if val in g2.names: return g2[val] if os.path.exists(val): return self.readfile(val) # May show UI error ui.showerror(_('Cannot add atoms'), _('{} is neither atom, molecule, nor file') .format(val)) return None
def info(gui): images = gui.images nimg = len(images) atoms = gui.atoms natoms = len(atoms) if len(atoms) < 1: txt = _('This frame has no atoms.') else: img = gui.frame uc = atoms.cell if nimg > 1: equal = True for i in range(nimg): equal = equal and (uc == images[i].cell).all() if equal: uctxt = ucconst else: uctxt = ucvaries else: uctxt = '' if nimg == 1: imgtxt = singleimage else: imgtxt = multiimage % (img, nimg - 1) periodic = [[_('no'), _('yes')][periodic] for periodic in atoms.pbc] # TRANSLATORS: This has the form Periodic: no, no, yes pbcstring = _('Periodic: %s, %s, %s') % tuple(periodic) txt = format % ((imgtxt, natoms) + tuple(uc.flat) + (pbcstring,) + (uctxt,)) return txt
def open(self, button=None, filename=None): from ase.io.formats import all_formats, get_ioformat labels = [_('Automatic')] values = [''] def key(item): return item[1][0] for format, (description, code) in sorted(list(all_formats.items()), key=key): io = get_ioformat(format) if io.read and description != '?': labels.append(_(description)) values.append(format) format = [None] def callback(value): format[0] = value chooser = ui.LoadFileDialog(self.window.win, _('Open ...')) ui.Label(_('Choose parser:')).pack(chooser.top) formats = ui.ComboBox(labels, values, callback) formats.pack(chooser.top) filename = filename or chooser.go() if filename: self.images.read([filename], slice(None), format[0]) self.set_colors() self.set_coordinates(self.images.nimages - 1, focus=True)
def toggle(self, value): self.gui.colormode = value if value == 'jmol': text = '' else: scalars = np.array([ self.gui.get_color_scalars(i) for i in range(len(self.gui.images)) ]) mn = scalars.min() mx = scalars.max() colorscale = [ '#{0:02X}AA00'.format(red) for red in range(0, 240, 10) ] self.gui.colormode_data = colorscale, mn, mx unit = { 'tag': '', 'force': 'eV/Ang', 'velocity': '??', 'charge': '|e|', 'initial charge': '|e|', u'magmom': 'μB' }[value] text = '[{0},{1}]: [{2:.6f},{3:.6f}] {4}'.format( _('Green'), _('Yellow'), mn, mx, unit) self.label.text = text self.radio.value = value self.gui.draw() return text # for testing
def toggle(self, value): self.gui.colormode = value if value == 'jmol': text = '' else: scalars = np.array([self.gui.get_color_scalars(i) for i in range(len(self.gui.images))]) mn = scalars.min() mx = scalars.max() colorscale = ['#{0:02X}AA00'.format(red) for red in range(0, 240, 10)] self.gui.colormode_data = colorscale, mn, mx unit = {'tag': '', 'force': 'eV/Ang', 'velocity': '??', 'charge': '|e|', u'magmom': 'μB'}[value] text = '[{0},{1}]: [{2:.6f},{3:.6f}] {4}'.format( _('Green'), _('Yellow'), mn, mx, unit) self.label.text = text self.radio.value = value self.gui.draw() return text # for testing
def open(self, button=None, filename=None): from ase.io.formats import all_formats, get_ioformat labels = [_('Automatic')] values = [''] def key(item): return item[1][0] for format, (description, code) in sorted(all_formats.items(), key=key): io = get_ioformat(format) if io.read and description != '?': labels.append(_(description)) values.append(format) format = [None] def callback(value): format[0] = value chooser = ui.LoadFileDialog(self.window.win, _('Open ...')) ui.Label(_('Choose parser:')).pack(chooser.top) formats = ui.ComboBox(labels, values, callback) formats.pack(chooser.top) filename = filename or chooser.go() if filename: self.images.read([filename], slice(None), format[0]) self.set_frame(len(self.images) - 1, focus=True)
def __init__(self, gui): self.gui = gui selected = self.selection() if not selected.any(): ui.error(_('No atoms selected!')) return win = ui.Window(_('Modify')) element = Element(callback=self.set_element) win.add(element) win.add( ui.Button(_('Change element'), partial(self.set_element, element))) self.tag = ui.SpinBox(0, -1000, 1000, 1, self.set_tag) win.add([_('Tag'), self.tag]) self.magmom = ui.SpinBox(0.0, -10, 10, 0.1, self.set_magmom) win.add([_('Moment'), self.magmom]) atoms = self.gui.atoms Z = atoms.numbers if Z.ptp() == 0: element.Z = Z[0] tags = atoms.get_tags()[selected] if tags.ptp() == 0: self.tag.value = tags[0] magmoms = get_magmoms(atoms)[selected] if magmoms.round(2).ptp() == 0.0: self.magmom.value = round(magmoms[0], 2)
def __init__(self, symbol='', callback=None): list.__init__(self, [ _('Element:'), ui.Entry(symbol, 3, self.enter), ui.Button(_('Help'), self.show_help), ui.Label('', 'red') ]) self.callback = callback
def pywindow(title, callback): code = callback() if code is None: ui.error( _('No Python code'), _('You have not (yet) specified a consistent set of parameters.')) else: win = ui.Window(title) win.add(ui.Text(code))
def __init__(self, symbol='', callback=None, allow_molecule=False): list.__init__(self, [ _('Element:'), ui.Entry(symbol, 10 if allow_molecule else 3, self.enter), ui.Button(_('Help'), self.show_help), ui.Label('', 'red') ]) self.callback = callback self.allow_molecule = allow_molecule
def save_dialog(gui, filename=None): dialog = ui.SaveFileDialog(gui.window.win, _('Save ...')) ui.Text(text).pack(dialog.top) filename = filename or dialog.go() if not filename: return filename, index = parse_filename(filename) if index is None: index = slice(gui.frame, gui.frame + 1) elif isinstance(index, basestring): index = string2index(index) elif isinstance(index, slice): pass else: if index < 0: index += len(gui.images) index = slice(index, index + 1) format = filetype(filename, read=False) io = get_ioformat(format) extra = {} remove_hidden = False if format in ['png', 'eps', 'pov']: bbox = np.empty(4) size = gui.window.size / gui.scale bbox[0:2] = np.dot(gui.center, gui.axes[:, :2]) - size / 2 bbox[2:] = bbox[:2] + size extra['rotation'] = gui.axes extra['show_unit_cell'] = gui.window['toggle-show-unit-cell'] extra['bbox'] = bbox colors = gui.get_colors(rgb=True) extra['colors'] = [ rgb for rgb, visible in zip(colors, gui.images.visible) if visible ] remove_hidden = True images = [ gui.images.get_atoms(i, remove_hidden=remove_hidden) for i in range(*index.indices(len(gui.images))) ] if len(images) > 1 and io.single: # We want to write multiple images, but the file format does not # support it. The solution is to write multiple files, inserting # a number in the file name before the suffix. j = filename.rfind('.') filename = filename[:j] + '{0:05d}' + filename[j:] for i, atoms in enumerate(images): write(filename.format(i), atoms, **extra) else: try: write(filename, images, **extra) except Exception as err: from ase.gui.ui import showerror showerror(_('Error'), err) raise
def apply(self): self.makeatoms() if self.atoms is not None: self.gui.new_atoms(self.atoms) return True else: ui.error(_('No valid atoms.'), _('You have not (yet) specified a consistent set of ' 'parameters.')) return False
def reset(self, gui): """create a new color window""" self.win = ui.Window(_('Colors')) self.gui = gui self.win.add(ui.Label(_('Choose how the atoms are colored:'))) values = ['jmol', 'tag', 'force', 'velocity', 'initial charge', 'magmom', 'neighbors'] labels = [_('By atomic number, default "jmol" colors'), _('By tag'), _('By force'), _('By velocity'), _('By initial charge'), _('By magnetic moment'), _('By number of neighbors'), ] haveit = ['numbers', 'positions', 'forces', 'momenta', 'initial_charges', 'initial_magmoms'] for key in self.gui.atoms.arrays: if key not in haveit: values.append(key) labels.append('By user-defined "{}"'.format(key)) self.radio = ui.RadioButtons(labels, values, self.toggle, vertical=True) self.radio.value = gui.colormode self.win.add(self.radio) self.activate() self.label = ui.Label() self.win.add(self.label) if hasattr(self, 'mnmx'): self.win.add(self.cmaps) self.win.add(self.mnmx)
def toggle(self, value): self.gui.colormode = value if value == 'jmol' or value == 'neighbors': if hasattr(self, 'mnmx'): "delete the min max fields by creating a new window" del self.mnmx del self.cmaps self.win.close() self.reset(self.gui) text = '' else: scalars = np.ma.array([self.gui.get_color_scalars(i) for i in range(len(self.gui.images))]) mn = np.min(scalars) mx = np.max(scalars) self.gui.colormode_data = None, mn, mx cmaps = ['default', 'old'] try: import pylab as plt cmaps += [m for m in plt.cm.datad if not m.endswith("_r")] except ImportError: pass self.cmaps = [_('cmap:'), ui.ComboBox(cmaps, cmaps, self.update_colormap), _('N:'), ui.SpinBox(26, 0, 100, 1, self.update_colormap)] self.update_colormap('default') try: unit = {'tag': '', 'force': 'eV/Ang', 'velocity': '(eV/amu)^(1/2)', 'charge': '|e|', 'initial charge': '|e|', u'magmom': 'μB'}[value] except KeyError: unit = '' text = '' rng = mx - mn # XXX what are optimal allowed range and steps ? self.mnmx = [_('min:'), ui.SpinBox(mn, mn - 10 * rng, mx + rng, rng / 10., self.change_mnmx), _('max:'), ui.SpinBox(mx, mn - 10 * rng, mx + rng, rng / 10., self.change_mnmx), _(unit)] self.win.close() self.reset(self.gui) self.label.text = text self.radio.value = value self.gui.draw() return text # for testing
def __init__(self, gui): self.win = ui.Window(_('Colors')) self.gui = gui self.win.add(ui.Label(_('Choose how the atoms are colored:'))) values = [ 'jmol', 'tag', 'force', 'velocity', 'initial charge', 'magmom', 'neighbors' ] labels = [ _('By atomic number, default "jmol" colors'), _('By tag'), _('By force'), _('By velocity'), _('By initial charge'), _('By magnetic moment'), _('By number of neighbors'), ] self.radio = ui.RadioButtons(labels, values, self.toggle, vertical=True) self.radio.value = gui.colormode self.win.add(self.radio) self.activate() self.label = ui.Label() self.win.add(self.label)
def __init__(self, gui): win = ui.Window('Graphs') self.expr = ui.Entry('', 50, self.plot) win.add([self.expr, ui.helpbutton(graph_help_text)]) win.add([ui.Button(_('Plot'), self.plot, 'xy'), ' x, y1, y2, ...'], 'w') win.add([ui.Button(_('Plot'), self.plot, 'y'), ' y1, y2, ...'], 'w') win.add([ui.Button(_('Save'), self.save)], 'w') self.gui = gui
def apply(self, *args): self.makeatoms() if self.atoms is not None: self.gui.new_atoms(self.atoms) return True else: error( _("No valid atoms."), _("You have not (yet) specified a consistent set of " "parameters.")) return False
def apply(self): self.make() if self.atoms is not None: self.gui.new_atoms(self.atoms) return True else: ui.error( _('No valid atoms.'), _('You have not (yet) specified a consistent ' 'set of parameters.')) return False
def update_gui_method(self, *args): 'Switch between layer specification and Wulff construction.' self.update_direction_table() self.update_new_direction_and_size_stuff() if self.method.value == 'wulff': self.layerlabel.text = _( 'Surface energies (as energy/area, NOT per atom):') else: self.layerlabel.text = _('Number of layers:') self.update()
def apply(self, callbackarg=None): self.makeatoms() if self.atoms is not None: self.gui.new_atoms(self.atoms) return True else: ui.error( _('No valid atoms.'), _('You have not (yet) specified a consistent set of ' 'parameters.')) return False
def __init__(self, gui): self.gui = gui win = ui.Window(_('Rotate')) win.add(_('Rotation angles:')) self.rotate = [ui.SpinBox(42.0, -360, 360, 1, self.change) for i in '123'] win.add(self.rotate) win.add(ui.Button(_('Update'), self.update_angles)) win.add(_('Note:\nYou can rotate freely\n' 'with the mouse, by holding\n' 'down mouse button 2.')) self.update_angles()
def apply(self, *args): """ create gui atoms from currently active atoms""" self.update() if self.atoms is not None: self.gui.new_atoms(self.atoms) return True else: error( _('No valid atoms.'), _('You have not (yet) specified a consistent set of ' 'parameters.')) return False
def __init__(self, gui): win = ui.Window(_('Repeat')) win.add(_('Repeat atoms:')) self.repeat = [ui.SpinBox(r, 1, 9, 1, self.change) for r in gui.images.repeat] win.add(self.repeat) win.add(ui.Button(_('Set unit cell'), self.set_unit_cell)) for sb, vec in zip(self.repeat, gui.atoms.cell): if not vec.any(): sb.active = False self.gui = gui
def __init__(self, gui): win = ui.Window('Graphs') self.expr = ui.Entry('', 50, self.plot) win.add([self.expr, ui.helpbutton(graph_help_text)]) win.add([ui.Button(_('Plot'), self.plot, 'xy'), ' x, y1, y2, ...'], 'w') win.add([ui.Button(_('Plot'), self.plot, 'y'), ' y1, y2, ...'], 'w') win.add([ui.Button(_('Save'), self.save), ui.Button(_('Clear'), self.clear)], 'w') self.gui = gui
def packimageselection(self, outerbox, txt1=_(" (rerun simulation)"), txt2=_(" (continue simulation)")): "Make the frame for selecting starting config if more than one." self.startframe = ui.Frame(_("Select starting configuration:")) pack(outerbox, [self.startframe]) vbox = ui.VBox() self.startframe.add(vbox) vbox.show() self.numconfig_format = _("There are currently %i " "configurations loaded.") self.numconfig_label = ui.Label("") pack(vbox, [self.numconfig_label]) lbl = ui.Label( _("Choose which one to use as the " "initial configuration")) pack(vbox, [lbl]) self.start_radio_first = ui.RadioButton( None, _("The first configuration %s.") % txt1) pack(vbox, [self.start_radio_first]) self.start_radio_nth = ui.RadioButton(self.start_radio_first, _("Configuration number ")) self.start_nth_adj = ui.Adjustment(0, 0, 1, 1) self.start_nth_spin = ui.SpinButton(self.start_nth_adj, 0, 0) self.start_nth_spin.set_sensitive(False) pack(vbox, [self.start_radio_nth, self.start_nth_spin]) self.start_radio_last = ui.RadioButton( self.start_radio_first, _("The last configuration %s.") % txt2) self.start_radio_last.set_active(True) pack(vbox, self.start_radio_last) self.start_radio_nth.connect("toggled", self.start_radio_nth_toggled) self.setupimageselection()
def __init__(self, gui): # XXXXXXXXXXX still array based, not Atoms-based. Will crash win = ui.Window(_('Add atoms')) self.element = Element() win.add(self.element) self.absolute_position = ui.Entry('0,0,0') self.relative_position = ui.Entry('1.5,0,0') win.add([_('Absolute position:'), self.absolute_position, ui.Button(_('Add'), self.add_absolute)]) win.add([_('Relative to average position (of selection):'), self.relative_position, ui.Button(_('Add'), self.add_relative)]) self.gui = gui
def txt2pos(txt): try: x, y, z = (float(x) for x in txt.split(',')) except ValueError as ex: ui.error(_('Bad position'), ex) else: return x, y, z
def reciprocal(self): if self.atoms.number_of_lattice_vectors != 3: self.bad_plot(_('Requires 3D cell.')) return kwargs = dict(cell=self.atoms.cell, vectors=True) self.pipe('reciprocal', kwargs)
def run(self, *args): if not self.setup_atoms(): return self.begin() e = self.atoms.get_potential_energy() txt = _("Potential Energy:\n") txt += _(" %8.2f eV\n") % (e, ) txt += _(" %8.4f eV/atom\n\n") % (e / len(self.atoms), ) if self.forces.get_active(): txt += _("Forces:\n") forces = self.atoms.get_forces() for f in forces: txt += " %8.3f, %8.3f, %8.3f eV/Å\n" % tuple(f) self.output.set_text(txt) self.activate_output() self.end()
def reciprocal(self): if self.atoms.cell.rank != 3: self.bad_plot(_('Requires 3D cell.')) return kwargs = dict(cell=self.atoms.cell.uncomplete(self.atoms.pbc), vectors=True) return self.pipe('reciprocal', kwargs)
def __init__(self, symbol='', callback=None): list.__init__(self, [_('Element:'), ui.Entry(symbol, 3, self.enter), ui.Label('', 'red')]) self.callback = callback self._symbol = None self._Z = None
def save(self): dialog = ui.SaveFileDialog(self.gui.window.win, _('Save data to file ... ')) filename = dialog.go() if filename: expr = self.expr.value data = self.gui.images.graph(expr) np.savetxt(filename, data.T, header=expr)
def __init__(self, gui): win = ui.Window(_('Constraints')) win.add([ui.Button(_('Constrain'), self.selected), _('selected atoms')]) win.add([ui.Button(_('Constrain'), self.immobile), _('immobile atoms')]) win.add([ui.Button(_('Unconstrain'), self.unconstrain), _('selected atoms')]) win.add(ui.Button(_('Clear constraints'), self.clear)) self.gui = gui
def get_atoms(self): "Make an atoms object from the active image" images = self.gui.images atoms = images[self.getimagenumber()] natoms = len(atoms) // images.repeat.prod() if natoms < 1: error(_("No atoms present")) return None return atoms[:natoms]
def setup_atoms(self): self.atoms = self.get_atoms() if self.atoms is None: return False try: self.calculator = self.gui.simulation['calc'] except KeyError: error(_("No calculator: Use Calculate/Set Calculator on the menu.")) return False self.atoms.set_calculator(self.calculator()) return True
def nanotube(gui): nt = gui.nanotube_window() nt.apply() nt.element[1].value = '?' nt.apply() assert ui.error.called( _('You have not (yet) specified a consistent set of parameters.')) nt.element[1].value = 'C' nt.ok() assert len(gui.images[0]) == 20
def add_direction(self, direction, layers, energy): i = len(self.direction_table_rows) if self.method.value == 'wulff': spin = ui.SpinBox(energy, 0.0, 1000.0, 0.1, self.update) else: spin = ui.SpinBox(layers, 1, 100, 1, self.update) up = ui.Button(_('Up'), self.row_swap_next, i - 1) down = ui.Button(_('Down'), self.row_swap_next, i) delete = ui.Button(_('Delete'), self.row_delete, i) self.direction_table_rows.add([str(direction) + ':', spin, up, down, delete]) up.active = i > 0 down.active = False delete.active = i > 0 if i > 0: down, delete = self.direction_table_rows[-2][3:] down.active = True delete.active = True
def row_add(self, widget=None): 'Add a row to the list of directions.' if self.fourindex: n = 4 else: n = 3 idx = tuple(a.value for a in self.new_direction[1:1 + 2 * n:2]) if not any(idx): ui.error(_('At least one index must be non-zero'), '') return if n == 4 and sum(idx) != 0: ui.error(_('Invalid hexagonal indices', 'The sum of the first three numbers must be zero')) return new = [idx, 5, 1.0] if self.method.value == 'wulff': new[1] = self.new_direction[-2].value else: new[2] = self.new_direction[-2].value self.direction_table.append(new) self.add_direction(*new) self.update()
def makebutbox(self, vbox, helptext=None): self.buttons = ui.HButtonBox() runbut = ui.Button(_("Run")) runbut.connect('clicked', self.run) closebut = ui.Button('Close') closebut.connect('clicked', lambda x: self.destroy()) for w in (runbut, closebut): self.buttons.pack_start(w, 0, 0) w.show() if helptext: helpbut = [help(helptext)] else: helpbut = [] pack(vbox, helpbut + [self.buttons], end=True, bottom=True)
def save_dialog(gui, filename=None): dialog = ui.SaveFileDialog(gui.window.win, _('Save ...')) ui.Text(text).pack(dialog.top) filename = filename or dialog.go() if not filename: return filename, index = parse_filename(filename) if index is None: index = slice(gui.frame, gui.frame + 1) elif isinstance(index, basestring): index = string2index(index) elif isinstance(index, slice): pass else: if index < 0: index += len(gui.images) index = slice(index, index + 1) format = filetype(filename, read=False) io = get_ioformat(format) extra = {} remove_hidden = False if format in ['png', 'eps', 'pov']: bbox = np.empty(4) size = gui.window.size / gui.scale bbox[0:2] = np.dot(gui.center, gui.axes[:, :2]) - size / 2 bbox[2:] = bbox[:2] + size extra['rotation'] = gui.axes extra['show_unit_cell'] = gui.window['toggle-show-unit-cell'] extra['bbox'] = bbox colors = gui.get_colors(rgb=True) extra['colors'] = [rgb for rgb, visible in zip(colors, gui.images.visible) if visible] remove_hidden = True images = [gui.images.get_atoms(i, remove_hidden=remove_hidden) for i in range(*index.indices(len(gui.images)))] if len(images) > 1 and io.single: # We want to write multiple images, but the file format does not # support it. The solution is to write multiple files, inserting # a number in the file name before the suffix. j = filename.rfind('.') filename = filename[:j] + '{0:05d}' + filename[j:] for i, atoms in enumerate(images): write(filename.format(i), atoms, **extra) else: write(filename, images, **extra)
def material_from_selection(self, *args): box_selection = self.get_selection() selection = self.gui.images.selected.copy() if selection.any(): Z = [] for n in range(len(selection)): if selection[n]: Z += [self.gui.atoms.Z[n]] name = formula(Z) if (box_selection == selection).all(): name += ': ' + self.texture_selection.get_text() texture_button = ui.combo_box_new_text() for t in self.finish_list: texture_button.append_text(t) texture_button.set_active(1) transparency = ui.Adjustment(0, 0.0, 1.0, 0.01) transparency_spin = ui.SpinButton(transparency, 0, 0) transparency_spin.set_digits(2) delete_button = ui.Button('Delete') index = len(self.materials) delete_button.connect("clicked", self.delete_material, {"n": index}) self.materials += [[ True, selection, texture_button, ui.Label(_(" transparency: ")), transparency_spin, ui.Label(" "), delete_button, ui.Label() ]] self.materials[-1][-1].set_markup(" " + name) pack(self.tbox, [ self.materials[-1][2], self.materials[-1][3], self.materials[-1][4], self.materials[-1][5], self.materials[-1][6], self.materials[-1][7] ]) else: error(_('Can not create new texture! Must have some atoms selected ' 'to create a new material!'))
def check(self): self._symbol = self[1].value if not self._symbol: self.error(_('No element specified!')) return False self._Z = ase.data.atomic_numbers.get(self._symbol) if self._Z is None: try: self._Z = int(self._symbol) except ValueError: self.error() return False self._symbol = ase.data.chemical_symbols[self._Z] self[2].text = '' return True
def __init__(self, gui): self.win = ui.Window(_('Colors')) self.gui = gui self.win.add(ui.Label(_('Choose how the atoms are colored:'))) values = ['jmol', 'tag', 'force', 'velocity', 'charge', 'magmom'] labels = [_('By atomic number, default "jmol" colors'), _('By tag'), _('By force'), _('By velocity'), _('By charge'), _('By magnetic moment')] self.radio = ui.RadioButtons(labels, values, self.toggle, vertical=True) self.radio.value = gui.colormode self.win.add(self.radio) self.activate() self.label = ui.Label() self.win.add(self.label)