def __init__(self, gui): SetupWindow.__init__(self) self.set_title("Nanotube") vbox = gtk.VBox() # Intoductory text self.packtext(vbox, introtext) # Choose the element and bond length label1 = gtk.Label("Element: ") #label.set_alignment(0.0, 0.2) self.element = gtk.Entry(max=3) self.element.set_text("C") self.element.connect('activate', self.update_element) self.bondlength = gtk.Adjustment(1.42, 0.0, 1000.0, 0.01) label2 = gtk.Label(" Bond length: ") label3 = gtk.Label("Å") bond_box = gtk.SpinButton(self.bondlength, 10.0, 3) pack(vbox, [label1, self.element, label2, bond_box, label3]) self.elementinfo = gtk.Label("") self.elementinfo.modify_fg(gtk.STATE_NORMAL, gtk.gdk.color_parse('#FF0000')) pack(vbox, [self.elementinfo]) pack(vbox, gtk.Label("")) # Choose the structure. pack(vbox, [gtk.Label("Select roll-up vector (n,m) and tube length:")]) label1 = gtk.Label("n: ") label2 = gtk.Label(" m: ") self.n = gtk.Adjustment(5, 1, 100, 1) self.m = gtk.Adjustment(5, 0, 100, 1) spinn = gtk.SpinButton(self.n, 0, 0) spinm = gtk.SpinButton(self.m, 0, 0) label3 = gtk.Label(" Length: ") self.length = gtk.Adjustment(1, 1, 100, 1) spinl = gtk.SpinButton(self.length, 0, 0) pack(vbox, [label1, spinn, label2, spinm, label3, spinl]) self.err = gtk.Label("") self.err.modify_fg(gtk.STATE_NORMAL, gtk.gdk.color_parse('#FF0000')) pack(vbox, [self.err]) pack(vbox, gtk.Label("")) self.n.connect('value-changed', self.update_n) self.m.connect('value-changed', self.update_m) # Buttons self.pybut = PyButton("Creating a nanoparticle.") self.pybut.connect('clicked', self.makeatoms) buts = cancel_apply_ok(cancel=lambda widget: self.destroy(), apply=self.apply, ok=self.ok) pack(vbox, [self.pybut, buts], end=True, bottom=True) # Finalize setup self.add(vbox) vbox.show() self.show() self.gui = gui
def __init__(self, gui): SetupWindow.__init__(self) self.set_title(_("Nanotube")) vbox = gtk.VBox() # Intoductory text self.packtext(vbox, introtext) # Choose the element and bond length label1 = gtk.Label(_("Element: ")) #label.set_alignment(0.0, 0.2) self.element = gtk.Entry(max=3) self.element.set_text("C") self.element.connect('activate', self.update_element) self.bondlength = gtk.Adjustment(1.42, 0.0, 1000.0, 0.01) label2 = gtk.Label(_(" Bond length: ")) label3 = gtk.Label(_("Å")) bond_box = gtk.SpinButton(self.bondlength, 10.0, 3) pack(vbox, [label1, self.element, label2, bond_box, label3]) self.elementinfo = gtk.Label("") self.elementinfo.modify_fg(gtk.STATE_NORMAL, gtk.gdk.color_parse('#FF0000')) pack(vbox, [self.elementinfo]) pack(vbox, gtk.Label("")) # Choose the structure. pack(vbox, [gtk.Label(_("Select roll-up vector (n,m) " "and tube length:"))]) label1 = gtk.Label("n: ") label2 = gtk.Label(" m: ") self.n = gtk.Adjustment(5, 1, 100, 1) self.m = gtk.Adjustment(5, 0, 100, 1) spinn = gtk.SpinButton(self.n, 0, 0) spinm = gtk.SpinButton(self.m, 0, 0) label3 = gtk.Label(_(" Length: ")) self.length = gtk.Adjustment(1, 1, 100, 1) spinl = gtk.SpinButton(self.length, 0, 0) pack(vbox, [label1, spinn, label2, spinm, label3, spinl]) self.err = gtk.Label("") self.err.modify_fg(gtk.STATE_NORMAL, gtk.gdk.color_parse('#FF0000')) pack(vbox, [self.err]) pack(vbox, gtk.Label("")) # Buttons self.pybut = PyButton(_("Creating a nanoparticle.")) self.pybut.connect('clicked', self.makeatoms) buts = cancel_apply_ok(cancel=lambda widget: self.destroy(), apply=self.apply, ok=self.ok) pack(vbox, [self.pybut, buts], end=True, bottom=True) # Finalize setup self.add(vbox) vbox.show() self.show() self.gui = gui
def __init__(self, gui): SetupWindow.__init__(self) self.set_title(_("Create Bulk Crystal by Spacegroup")) self.atoms = None vbox = gtk.VBox() self.packtext(vbox, introtext) self.structinfo = gtk.combo_box_new_text() self.structures = {} for c in crystal_definitions: self.structinfo.append_text(c[0]) self.structures[c[0]] = c self.structinfo.set_active(0) self.structinfo.connect("changed", self.set_lattice_type) self.spacegroup = gtk.Entry(max=14) self.spacegroup.set_text('P 1') self.elementinfo = gtk.Label("") self.spacegroupinfo = gtk.Label(_('Number: 1')) pack(vbox, [ gtk.Label(_("Lattice: ")), self.structinfo, gtk.Label(_("\tSpace group: ")), self.spacegroup, gtk.Label(' '), self.spacegroupinfo, gtk.Label(' '), self.elementinfo ]) pack(vbox, [gtk.Label("")]) self.size = [gtk.Adjustment(1, 1, 100, 1) for i in range(3)] buttons = [gtk.SpinButton(s, 0, 0) for s in self.size] pack(vbox, [ gtk.Label(_("Size: x: ")), buttons[0], gtk.Label(_(" y: ")), buttons[1], gtk.Label(_(" z: ")), buttons[2], gtk.Label(_(" unit cells")) ]) pack(vbox, [gtk.Label("")]) self.lattice_lengths = [ gtk.Adjustment(3.0, 0.0, 1000.0, 0.01) for i in range(3) ] self.lattice_angles = [ gtk.Adjustment(90.0, 0.0, 180.0, 1) for i in range(3) ] self.lattice_lbuts = [ gtk.SpinButton(self.lattice_lengths[i], 0, 0) for i in range(3) ] self.lattice_abuts = [ gtk.SpinButton(self.lattice_angles[i], 0, 0) for i in range(3) ] for i in self.lattice_lbuts: i.set_digits(5) for i in self.lattice_abuts: i.set_digits(3) self.lattice_lequals = [gtk.combo_box_new_text() for i in range(3)] self.lattice_aequals = [gtk.combo_box_new_text() for i in range(3)] self.lattice_lequals[0].append_text(_('free')) self.lattice_lequals[0].append_text(_('equals b')) self.lattice_lequals[0].append_text(_('equals c')) self.lattice_lequals[0].append_text(_('fixed')) self.lattice_lequals[1].append_text(_('free')) self.lattice_lequals[1].append_text(_('equals a')) self.lattice_lequals[1].append_text(_('equals c')) self.lattice_lequals[1].append_text(_('fixed')) self.lattice_lequals[2].append_text(_('free')) self.lattice_lequals[2].append_text(_('equals a')) self.lattice_lequals[2].append_text(_('equals b')) self.lattice_lequals[2].append_text(_('fixed')) self.lattice_aequals[0].append_text(_('free')) self.lattice_aequals[0].append_text(_('equals beta')) self.lattice_aequals[0].append_text(_('equals gamma')) self.lattice_aequals[0].append_text(_('fixed')) self.lattice_aequals[1].append_text(_('free')) self.lattice_aequals[1].append_text(_('equals alpha')) self.lattice_aequals[1].append_text(_('equals gamma')) self.lattice_aequals[1].append_text(_('fixed')) self.lattice_aequals[2].append_text(_('free')) self.lattice_aequals[2].append_text(_('equals alpha')) self.lattice_aequals[2].append_text(_('equals beta')) self.lattice_aequals[2].append_text(_('fixed')) for i in range(3): self.lattice_lequals[i].set_active(0) self.lattice_aequals[i].set_active(0) pack(vbox, [gtk.Label(_('Lattice parameters'))]) pack(vbox, [ gtk.Label(_('\t\ta:\t')), self.lattice_lbuts[0], gtk.Label(' '), self.lattice_lequals[0], gtk.Label(_('\talpha:\t')), self.lattice_abuts[0], gtk.Label(' '), self.lattice_aequals[0] ]) pack(vbox, [ gtk.Label(_('\t\tb:\t')), self.lattice_lbuts[1], gtk.Label(' '), self.lattice_lequals[1], gtk.Label(_('\tbeta:\t')), self.lattice_abuts[1], gtk.Label(' '), self.lattice_aequals[1] ]) pack(vbox, [ gtk.Label(_('\t\tc:\t')), self.lattice_lbuts[2], gtk.Label(' '), self.lattice_lequals[2], gtk.Label(_('\tgamma:\t')), self.lattice_abuts[2], gtk.Label(' '), self.lattice_aequals[2] ]) self.get_data = gtk.Button(_("Get from database")) self.get_data.connect("clicked", self.get_from_database) self.get_data.set_sensitive(False) pack(vbox, [gtk.Label(" "), self.get_data]) pack(vbox, [gtk.Label("")]) pack(vbox, [gtk.Label(_("Basis: "))]) self.elements = [[ gtk.Entry(max=3), gtk.Entry(max=8), gtk.Entry(max=8), gtk.Entry(max=8), True ]] self.element = self.elements[0][0] add_atom = gtk.Button(stock=gtk.STOCK_ADD) add_atom.connect("clicked", self.add_basis_atom) add_atom.connect("activate", self.add_basis_atom) pack(vbox, [ gtk.Label(_(' Element:\t')), self.elements[0][0], gtk.Label(_('\tx: ')), self.elements[0][1], gtk.Label(_(' y: ')), self.elements[0][2], gtk.Label(_(' z: ')), self.elements[0][3], gtk.Label('\t'), add_atom ]) self.vbox_basis = gtk.VBox() swin = gtk.ScrolledWindow() swin.set_border_width(0) swin.set_policy(gtk.POLICY_AUTOMATIC, gtk.POLICY_AUTOMATIC) vbox.pack_start(swin, True, True, 0) swin.add_with_viewport(self.vbox_basis) self.vbox_basis.get_parent().set_shadow_type(gtk.SHADOW_NONE) self.vbox_basis.get_parent().set_size_request(-1, 100) swin.show() pack(self.vbox_basis, [gtk.Label('')]) pack(vbox, [self.vbox_basis]) self.vbox_basis.show() pack(vbox, [gtk.Label("")]) self.status = gtk.Label("") pack(vbox, [self.status]) pack(vbox, [gtk.Label("")]) self.pybut = PyButton(_("Creating a crystal.")) self.pybut.connect('clicked', self.update) clear = gtk.Button(stock=gtk.STOCK_CLEAR) clear.connect("clicked", self.clear) buts = cancel_apply_ok(cancel=lambda widget: self.destroy(), apply=self.apply, ok=self.ok) pack(vbox, [self.pybut, clear, buts], end=True, bottom=True) self.structinfo.connect("changed", self.update) self.spacegroup.connect("activate", self.update) for s in self.size: s.connect("value-changed", self.update) for el in self.elements: if el[-1]: for i in el[:-1]: i.connect("activate", self.update) i.connect("changed", self.update) for i in range(3): self.lattice_lbuts[i].connect("value-changed", self.update) self.lattice_abuts[i].connect("value-changed", self.update) self.lattice_lequals[i].connect("changed", self.update) self.lattice_aequals[i].connect("changed", self.update) self.clearing_in_process = False self.gui = gui self.add(vbox) vbox.show() self.show()
class SetupBulkCrystal(SetupWindow): """Window for setting up a surface.""" def __init__(self, gui): SetupWindow.__init__(self) self.set_title(_("Create Bulk Crystal by Spacegroup")) self.atoms = None vbox = gtk.VBox() self.packtext(vbox, introtext) self.structinfo = gtk.combo_box_new_text() self.structures = {} for c in crystal_definitions: self.structinfo.append_text(c[0]) self.structures[c[0]] = c self.structinfo.set_active(0) self.structinfo.connect("changed", self.set_lattice_type) self.spacegroup = gtk.Entry(max=14) self.spacegroup.set_text('P 1') self.elementinfo = gtk.Label("") self.spacegroupinfo = gtk.Label(_('Number: 1')) pack(vbox, [ gtk.Label(_("Lattice: ")), self.structinfo, gtk.Label(_("\tSpace group: ")), self.spacegroup, gtk.Label(' '), self.spacegroupinfo, gtk.Label(' '), self.elementinfo ]) pack(vbox, [gtk.Label("")]) self.size = [gtk.Adjustment(1, 1, 100, 1) for i in range(3)] buttons = [gtk.SpinButton(s, 0, 0) for s in self.size] pack(vbox, [ gtk.Label(_("Size: x: ")), buttons[0], gtk.Label(_(" y: ")), buttons[1], gtk.Label(_(" z: ")), buttons[2], gtk.Label(_(" unit cells")) ]) pack(vbox, [gtk.Label("")]) self.lattice_lengths = [ gtk.Adjustment(3.0, 0.0, 1000.0, 0.01) for i in range(3) ] self.lattice_angles = [ gtk.Adjustment(90.0, 0.0, 180.0, 1) for i in range(3) ] self.lattice_lbuts = [ gtk.SpinButton(self.lattice_lengths[i], 0, 0) for i in range(3) ] self.lattice_abuts = [ gtk.SpinButton(self.lattice_angles[i], 0, 0) for i in range(3) ] for i in self.lattice_lbuts: i.set_digits(5) for i in self.lattice_abuts: i.set_digits(3) self.lattice_lequals = [gtk.combo_box_new_text() for i in range(3)] self.lattice_aequals = [gtk.combo_box_new_text() for i in range(3)] self.lattice_lequals[0].append_text(_('free')) self.lattice_lequals[0].append_text(_('equals b')) self.lattice_lequals[0].append_text(_('equals c')) self.lattice_lequals[0].append_text(_('fixed')) self.lattice_lequals[1].append_text(_('free')) self.lattice_lequals[1].append_text(_('equals a')) self.lattice_lequals[1].append_text(_('equals c')) self.lattice_lequals[1].append_text(_('fixed')) self.lattice_lequals[2].append_text(_('free')) self.lattice_lequals[2].append_text(_('equals a')) self.lattice_lequals[2].append_text(_('equals b')) self.lattice_lequals[2].append_text(_('fixed')) self.lattice_aequals[0].append_text(_('free')) self.lattice_aequals[0].append_text(_('equals beta')) self.lattice_aequals[0].append_text(_('equals gamma')) self.lattice_aequals[0].append_text(_('fixed')) self.lattice_aequals[1].append_text(_('free')) self.lattice_aequals[1].append_text(_('equals alpha')) self.lattice_aequals[1].append_text(_('equals gamma')) self.lattice_aequals[1].append_text(_('fixed')) self.lattice_aequals[2].append_text(_('free')) self.lattice_aequals[2].append_text(_('equals alpha')) self.lattice_aequals[2].append_text(_('equals beta')) self.lattice_aequals[2].append_text(_('fixed')) for i in range(3): self.lattice_lequals[i].set_active(0) self.lattice_aequals[i].set_active(0) pack(vbox, [gtk.Label(_('Lattice parameters'))]) pack(vbox, [ gtk.Label(_('\t\ta:\t')), self.lattice_lbuts[0], gtk.Label(' '), self.lattice_lequals[0], gtk.Label(_('\talpha:\t')), self.lattice_abuts[0], gtk.Label(' '), self.lattice_aequals[0] ]) pack(vbox, [ gtk.Label(_('\t\tb:\t')), self.lattice_lbuts[1], gtk.Label(' '), self.lattice_lequals[1], gtk.Label(_('\tbeta:\t')), self.lattice_abuts[1], gtk.Label(' '), self.lattice_aequals[1] ]) pack(vbox, [ gtk.Label(_('\t\tc:\t')), self.lattice_lbuts[2], gtk.Label(' '), self.lattice_lequals[2], gtk.Label(_('\tgamma:\t')), self.lattice_abuts[2], gtk.Label(' '), self.lattice_aequals[2] ]) self.get_data = gtk.Button(_("Get from database")) self.get_data.connect("clicked", self.get_from_database) self.get_data.set_sensitive(False) pack(vbox, [gtk.Label(" "), self.get_data]) pack(vbox, [gtk.Label("")]) pack(vbox, [gtk.Label(_("Basis: "))]) self.elements = [[ gtk.Entry(max=3), gtk.Entry(max=8), gtk.Entry(max=8), gtk.Entry(max=8), True ]] self.element = self.elements[0][0] add_atom = gtk.Button(stock=gtk.STOCK_ADD) add_atom.connect("clicked", self.add_basis_atom) add_atom.connect("activate", self.add_basis_atom) pack(vbox, [ gtk.Label(_(' Element:\t')), self.elements[0][0], gtk.Label(_('\tx: ')), self.elements[0][1], gtk.Label(_(' y: ')), self.elements[0][2], gtk.Label(_(' z: ')), self.elements[0][3], gtk.Label('\t'), add_atom ]) self.vbox_basis = gtk.VBox() swin = gtk.ScrolledWindow() swin.set_border_width(0) swin.set_policy(gtk.POLICY_AUTOMATIC, gtk.POLICY_AUTOMATIC) vbox.pack_start(swin, True, True, 0) swin.add_with_viewport(self.vbox_basis) self.vbox_basis.get_parent().set_shadow_type(gtk.SHADOW_NONE) self.vbox_basis.get_parent().set_size_request(-1, 100) swin.show() pack(self.vbox_basis, [gtk.Label('')]) pack(vbox, [self.vbox_basis]) self.vbox_basis.show() pack(vbox, [gtk.Label("")]) self.status = gtk.Label("") pack(vbox, [self.status]) pack(vbox, [gtk.Label("")]) self.pybut = PyButton(_("Creating a crystal.")) self.pybut.connect('clicked', self.update) clear = gtk.Button(stock=gtk.STOCK_CLEAR) clear.connect("clicked", self.clear) buts = cancel_apply_ok(cancel=lambda widget: self.destroy(), apply=self.apply, ok=self.ok) pack(vbox, [self.pybut, clear, buts], end=True, bottom=True) self.structinfo.connect("changed", self.update) self.spacegroup.connect("activate", self.update) for s in self.size: s.connect("value-changed", self.update) for el in self.elements: if el[-1]: for i in el[:-1]: i.connect("activate", self.update) i.connect("changed", self.update) for i in range(3): self.lattice_lbuts[i].connect("value-changed", self.update) self.lattice_abuts[i].connect("value-changed", self.update) self.lattice_lequals[i].connect("changed", self.update) self.lattice_aequals[i].connect("changed", self.update) self.clearing_in_process = False self.gui = gui self.add(vbox) vbox.show() self.show() def update(self, *args): """ all changes of physical constants are handled here, atoms are set up""" if self.clearing_in_process: return True self.update_element() a_equals = self.lattice_lequals[0].get_active() b_equals = self.lattice_lequals[1].get_active() c_equals = self.lattice_lequals[2].get_active() alpha_equals = self.lattice_aequals[0].get_active() beta_equals = self.lattice_aequals[1].get_active() gamma_equals = self.lattice_aequals[2].get_active() sym = self.spacegroup.get_text() valid = True try: no = int(sym) spg = Spacegroup(no).symbol self.spacegroupinfo.set_label(_('Symbol: %s') % str(spg)) spg = no except: try: no = Spacegroup(sym).no self.spacegroupinfo.set_label(_('Number: %s') % str(no)) spg = no except: self.spacegroupinfo.set_label(_('Invalid Spacegroup!')) valid = False if a_equals == 0: self.lattice_lbuts[0].set_sensitive(True) elif a_equals == 1: self.lattice_lbuts[0].set_sensitive(False) self.lattice_lbuts[0].set_value(self.lattice_lbuts[1].get_value()) elif a_equals == 2: self.lattice_lbuts[0].set_sensitive(False) self.lattice_lbuts[0].set_value(self.lattice_lbuts[2].get_value()) else: self.lattice_lbuts[0].set_sensitive(False) if b_equals == 0: self.lattice_lbuts[1].set_sensitive(True) elif b_equals == 1: self.lattice_lbuts[1].set_sensitive(False) self.lattice_lbuts[1].set_value(self.lattice_lbuts[0].get_value()) elif b_equals == 2: self.lattice_lbuts[1].set_sensitive(False) self.lattice_lbuts[1].set_value(self.lattice_lbuts[2].get_value()) else: self.lattice_lbuts[1].set_sensitive(False) if c_equals == 0: self.lattice_lbuts[2].set_sensitive(True) elif c_equals == 1: self.lattice_lbuts[2].set_sensitive(False) self.lattice_lbuts[2].set_value(self.lattice_lbuts[0].get_value()) elif c_equals == 2: self.lattice_lbuts[2].set_sensitive(False) self.lattice_lbuts[2].set_value(self.lattice_lbuts[1].get_value()) else: self.lattice_lbuts[2].set_sensitive(False) if alpha_equals == 0: self.lattice_abuts[0].set_sensitive(True) elif alpha_equals == 1: self.lattice_abuts[0].set_sensitive(False) self.lattice_abuts[0].set_value(self.lattice_abuts[1].get_value()) elif alpha_equals == 2: self.lattice_abuts[0].set_sensitive(False) self.lattice_abuts[0].set_value(self.lattice_abuts[2].get_value()) else: self.lattice_abuts[0].set_sensitive(False) if beta_equals == 0: self.lattice_abuts[1].set_sensitive(True) elif beta_equals == 1: self.lattice_abuts[1].set_sensitive(False) self.lattice_abuts[1].set_value(self.lattice_abuts[0].get_value()) elif beta_equals == 2: self.lattice_abuts[1].set_sensitive(False) self.lattice_abuts[1].set_value(self.lattice_abuts[2].get_value()) else: self.lattice_abuts[1].set_sensitive(False) if gamma_equals == 0: self.lattice_abuts[2].set_sensitive(True) elif gamma_equals == 1: self.lattice_abuts[2].set_sensitive(False) self.lattice_abuts[2].set_value(self.lattice_abuts[0].get_value()) elif gamma_equals == 2: self.lattice_abuts[2].set_sensitive(False) self.lattice_abuts[2].set_value(self.lattice_abuts[1].get_value()) else: self.lattice_abuts[2].set_sensitive(False) valid = len(self.elements[0][0].get_text()) and valid self.get_data.set_sensitive(valid and self.get_n_elements() == 1 and self.update_element()) self.atoms = None if valid: basis_count = -1 for el in self.elements: if el[-1]: basis_count += 1 if basis_count: symbol_str = '[' basis_str = "[" symbol = [] basis = [] else: symbol_str = '' basis_str = '' basis = None for el in self.elements: if el[-1]: symbol_str += "'" + el[0].get_text() + "'" if basis_count: symbol_str += ',' symbol += [el[0].get_text()] exec 'basis += [[float(' + el[1].get_text( ) + '),float(' + el[2].get_text( ) + '),float(' + el[3].get_text() + ')]]' else: symbol = el[0].get_text() exec 'basis = [[float(' + el[1].get_text( ) + '),float(' + el[2].get_text( ) + '),float(' + el[3].get_text() + ')]]' basis_str += '[' + el[1].get_text() + ',' + el[2].get_text( ) + ',' + el[3].get_text() + '],' basis_str = basis_str[:-1] if basis_count: symbol_str = symbol_str[:-1] + ']' basis_str += ']' size_str = '(' + str(int(self.size[0].get_value())) + ',' + str( int(self.size[1].get_value())) + ',' + str( int(self.size[2].get_value())) + ')' size = (int(self.size[0].get_value()), int(self.size[1].get_value()), int(self.size[2].get_value())) cellpar_str = '' cellpar = [] for i in self.lattice_lbuts: cellpar_str += str(i.get_value()) + ',' cellpar += [i.get_value()] for i in self.lattice_abuts: cellpar_str += str(i.get_value()) + ',' cellpar += [i.get_value()] cellpar_str = '[' + cellpar_str[:-1] + ']' args = { 'symbols': symbol, 'basis': basis, 'size': size, 'spacegroup': spg, 'cellpar': cellpar } args_str = { 'symbols': symbol_str, 'basis': basis_str, 'size': size_str, 'spacegroup': spg, 'cellpar': cellpar_str } self.pybut.python = py_template % args_str try: self.atoms = crystal(**args) label = label_template % { 'natoms': self.atoms.get_number_of_atoms(), 'symbols': formula(self.atoms.get_atomic_numbers()), 'volume': self.atoms.get_volume() } self.status.set_label(label) except: self.atoms = None self.status.set_markup( _("Please specify a consistent set of atoms.")) else: self.atoms = None self.status.set_markup( _("Please specify a consistent set of atoms.")) 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: oops( _( "No valid atoms.", "You have not (yet) specified a consistent set of " "parameters.")) return False def ok(self, *args): if self.apply(): self.destroy() def add_basis_atom(self, *args): """ add an atom to the customizable basis """ n = len(self.elements) self.elements += [[ gtk.Entry(max=3), gtk.Entry(max=8), gtk.Entry(max=8), gtk.Entry(max=8), gtk.Label('\t\t\t'), gtk.Label('\tx: '), gtk.Label(' y: '), gtk.Label(' z: '), gtk.Label(' '), gtk.Button(stock=gtk.STOCK_DELETE), True ]] self.elements[n][-2].connect("clicked", self.delete_basis_atom, {'n': n}) pack(self.vbox_basis, [ self.elements[n][4], self.elements[n][0], self.elements[n][5], self.elements[n][1], self.elements[n][6], self.elements[n][2], self.elements[n][7], self.elements[n][3], self.elements[n][8], self.elements[n][9] ]) self.update() def delete_basis_atom(self, button, index, *args): """ delete atom index from customizable basis""" n = index['n'] self.elements[n][-1] = False for i in range(10): self.elements[n][i].destroy() self.update() def get_n_elements(self): """ counts how many basis atoms are actually active """ n = 0 for el in self.elements: if el[-1]: n += 1 return n def clear(self, *args): """ reset to original state """ self.clearing_in_process = True self.clear_lattice() self.structinfo.set_active(0) self.set_lattice_type() self.clearing_in_process = False self.update() def clear_lattice(self, *args): """ delete all custom settings """ self.atoms = None if len(self.elements) > 1: for n, el in enumerate(self.elements[1:]): self.elements[n + 1][-1] = False for i in range(10): self.elements[n + 1][i].destroy() for i in range(4): self.elements[0][i].set_text("") self.spacegroup.set_sensitive(True) for i in self.lattice_lbuts: i.set_sensitive(True) for i in self.lattice_abuts: i.set_sensitive(True) for i in range(3): self.lattice_lequals[i].set_sensitive(True) self.lattice_aequals[i].set_sensitive(True) self.lattice_lequals[i].set_active(0) self.lattice_aequals[i].set_active(0) for s in self.size: s.set_value(1) def set_lattice_type(self, *args): """ set defaults from original """ self.clearing_in_process = True self.clear_lattice() lattice = crystal_definitions[self.structinfo.get_active()] self.spacegroup.set_text(str(lattice[1])) self.spacegroup.set_sensitive(lattice[2]) for s, i in zip(self.size, lattice[3]): s.set_value(i) self.lattice_lbuts[0].set_value(lattice[4][0]) self.lattice_lbuts[1].set_value(lattice[4][1]) self.lattice_lbuts[2].set_value(lattice[4][2]) self.lattice_abuts[0].set_value(lattice[4][3]) self.lattice_abuts[1].set_value(lattice[4][4]) self.lattice_abuts[2].set_value(lattice[4][5]) self.lattice_lequals[0].set_active(lattice[5][0]) self.lattice_lequals[1].set_active(lattice[5][1]) self.lattice_lequals[2].set_active(lattice[5][2]) self.lattice_aequals[0].set_active(lattice[5][3]) self.lattice_aequals[1].set_active(lattice[5][4]) self.lattice_aequals[2].set_active(lattice[5][5]) self.lattice_lequals[0].set_sensitive(lattice[6][0]) self.lattice_lequals[1].set_sensitive(lattice[6][1]) self.lattice_lequals[2].set_sensitive(lattice[6][2]) self.lattice_aequals[0].set_sensitive(lattice[6][3]) self.lattice_aequals[1].set_sensitive(lattice[6][4]) self.lattice_aequals[2].set_sensitive(lattice[6][5]) for n, at in enumerate(lattice[7]): l = 0 if n > 0: l = len(self.elements) self.add_basis_atom() for i, s in enumerate(at): self.elements[l][i].set_text(s) self.clearing_in_process = False self.update() def get_from_database(self, *args): element = self.elements[0][0].get_text() z = ase.data.atomic_numbers[self.legal_element] ref = ase.data.reference_states[z] lattice = ref['symmetry'] index = 0 while index < len(crystal_definitions ) and crystal_definitions[index][0] != lattice: index += 1 if index == len(crystal_definitions) or not self.legal_element: oops(_("Can't find lattice definition!")) return False self.structinfo.set_active(index) self.lattice_lbuts[0].set_value(ref['a']) if lattice == 'hcp': self.lattice_lbuts[2].set_value(ref['c/a'] * ref['a']) self.elements[0][0].set_text(element) if lattice in ['fcc', 'bcc', 'diamond']: self.elements[0][1].set_text('0') self.elements[0][2].set_text('0') self.elements[0][3].set_text('0')
class SetupNanotube(SetupWindow): "Window for setting up a (Carbon) nanotube." def __init__(self, gui): SetupWindow.__init__(self) self.set_title("Nanotube") vbox = gtk.VBox() # Intoductory text self.packtext(vbox, introtext) # Choose the element and bond length label1 = gtk.Label("Element: ") #label.set_alignment(0.0, 0.2) self.element = gtk.Entry(max=3) self.element.set_text("C") self.element.connect('activate', self.update_element) self.bondlength = gtk.Adjustment(1.42, 0.0, 1000.0, 0.01) label2 = gtk.Label(" Bond length: ") label3 = gtk.Label("Å") bond_box = gtk.SpinButton(self.bondlength, 10.0, 3) pack(vbox, [label1, self.element, label2, bond_box, label3]) self.elementinfo = gtk.Label("") self.elementinfo.modify_fg(gtk.STATE_NORMAL, gtk.gdk.color_parse('#FF0000')) pack(vbox, [self.elementinfo]) pack(vbox, gtk.Label("")) # Choose the structure. pack(vbox, [gtk.Label("Select roll-up vector (n,m) and tube length:")]) label1 = gtk.Label("n: ") label2 = gtk.Label(" m: ") self.n = gtk.Adjustment(5, 1, 100, 1) self.m = gtk.Adjustment(5, 0, 100, 1) spinn = gtk.SpinButton(self.n, 0, 0) spinm = gtk.SpinButton(self.m, 0, 0) label3 = gtk.Label(" Length: ") self.length = gtk.Adjustment(1, 1, 100, 1) spinl = gtk.SpinButton(self.length, 0, 0) pack(vbox, [label1, spinn, label2, spinm, label3, spinl]) self.err = gtk.Label("") self.err.modify_fg(gtk.STATE_NORMAL, gtk.gdk.color_parse('#FF0000')) pack(vbox, [self.err]) pack(vbox, gtk.Label("")) self.n.connect('value-changed', self.update_n) self.m.connect('value-changed', self.update_m) # Buttons self.pybut = PyButton("Creating a nanoparticle.") self.pybut.connect('clicked', self.makeatoms) buts = cancel_apply_ok(cancel=lambda widget: self.destroy(), apply=self.apply, ok=self.ok) pack(vbox, [self.pybut, buts], end=True, bottom=True) # Finalize setup self.add(vbox) vbox.show() self.show() self.gui = gui def update_n(self, *args): if self.m.value > self.n.value: self.m.value = self.n.value self.err.set_text("m decreased! (m may not be larger than n.)") else: self.err.set_text("") def update_m(self, *args): if self.m.value > self.n.value: self.n.value = self.m.value self.err.set_text("n increased! (m may not be larger than n.)") else: self.err.set_text("") def update_element(self, *args): "Called when a new element may have been entered." # Assumes the element widget is self.element and that a label # for errors is self.elementinfo. The chemical symbol is # placed in self.legalelement - or None if the element is # invalid. elem = self.element.get_text() if not elem: self.invalid_element(" No element specified!") return False try: z = int(elem) except ValueError: # Probably a symbol try: z = ase.data.atomic_numbers[elem] except KeyError: self.invalid_element() return False try: symb = ase.data.chemical_symbols[z] except KeyError: self.invalid_element() return False self.elementinfo.set_text("") self.legal_element = symb return True def makeatoms(self, *args): self.update_element() if self.legal_element is None: self.atoms = None self.pybut.python = None else: n = int(self.n.value) m = int(self.m.value) symb = self.legal_element length = int(self.length.value) bl = self.bondlength.value self.atoms = nanotube(n, m, length=length, bond=bl, symbol=symb) self.pybut.python = py_template % { 'n': n, 'm': m, 'length': length, 'symb': symb, 'bl': bl } def apply(self, *args): self.makeatoms() if self.atoms is not None: self.gui.new_atoms(self.atoms) return True else: oops( "No valid atoms.", "You have not (yet) specified a consistent set of parameters.") return False def ok(self, *args): if self.apply(): self.destroy()
def __init__(self, gui): SetupWindow.__init__(self) self.set_title(_('Surface')) self.atoms = None vbox = gtk.VBox() # Intoductory text self.packtext(vbox, introtext) # Choose the element label = gtk.Label(_('Element: ')) element = gtk.Entry(max=3) self.element = element self.elementinfo = gtk.Label('') pack(vbox, [label, element, self.elementinfo]) self.element.connect('activate', self.update) self.legal_element = False # Choose the surface structure label = gtk.Label(_('Structure: ')) self.structchoice = gtk.combo_box_new_text() self.surfinfo = {} for s in surfaces: assert len(s) == 5 self.structchoice.append_text(s[0]) self.surfinfo[s[0]] = s pack(vbox, [label, self.structchoice]) self.structchoice.connect('changed', self.update) # Choose the lattice constant tbl = gtk.Table(2, 3) label = gtk.Label(_('Lattice constant: ')) tbl.attach(label, 0, 1, 0, 1) vbox2 = gtk.VBox() # For the non-HCP stuff self.vbox_hcp = gtk.VBox() # For the HCP stuff. self.lattice_const = gtk.Adjustment(3.0, 0.0, 1000.0, 0.01) lattice_box = gtk.SpinButton(self.lattice_const, 10.0, 3) lattice_box.numeric = True pack(vbox2, [gtk.Label(_('a:')), lattice_box, gtk.Label(_(u'Å'))]) tbl.attach(vbox2, 1, 2, 0, 1) lattice_button = gtk.Button(_('Get from database')) tbl.attach(lattice_button, 2, 3, 0, 1) # HCP stuff self.hcp_ideal = (8 / 3)**(1 / 3) self.lattice_const_c = gtk.Adjustment(self.lattice_const.value * self.hcp_ideal, 0.0, 1000.0, 0.01) lattice_box_c = gtk.SpinButton(self.lattice_const_c, 10.0, 3) lattice_box_c.numeric = True pack(self.vbox_hcp, [gtk.Label('c:'), lattice_box_c, gtk.Label(u'Å')]) self.hcp_c_over_a_format = 'c/a: %.3f ' + _('(%.1f %% of ideal)') self.hcp_c_over_a_label = gtk.Label(self.hcp_c_over_a_format % (self.hcp_ideal, 100.0)) pack(self.vbox_hcp, [self.hcp_c_over_a_label]) tbl.attach(self.vbox_hcp, 1, 2, 1, 2) tbl.show_all() pack(vbox, [tbl]) self.lattice_const.connect('value-changed', self.update) self.lattice_const_c.connect('value-changed', self.update) lattice_button.connect('clicked', self.get_lattice_const) pack(vbox, gtk.Label('')) # System size self.size = [gtk.Adjustment(1, 1, 100, 1) for i in range(3)] buttons = [gtk.SpinButton(s, 0, 0) for s in self.size] self.vacuum = gtk.Adjustment(10.0, 0, 100.0, 0.1) vacuum_box = gtk.SpinButton(self.vacuum, 0.0, 1) pack(vbox, [gtk.Label(_('Size: \tx: ')), buttons[0], gtk.Label(_(' unit cells'))]) pack(vbox, [gtk.Label(_('\t\ty: ')), buttons[1], gtk.Label(_(' unit cells'))]) pack(vbox, [gtk.Label(_(' \t\tz: ')), buttons[2], gtk.Label(_(' layers, ')), vacuum_box, gtk.Label(_(u' Å vacuum'))]) self.nosize = _('\t\tNo size information yet.') self.sizelabel = gtk.Label(self.nosize) pack(vbox, [self.sizelabel]) for s in self.size: s.connect('value-changed', self.update) self.vacuum.connect('value-changed', self.update) pack(vbox, gtk.Label('')) # Buttons self.pybut = PyButton(_('Creating a surface slab.')) self.pybut.connect('clicked', self.update) buts = cancel_apply_ok(cancel=lambda widget: self.destroy(), apply=self.apply, ok=self.ok) pack(vbox, [self.pybut, buts], end=True, bottom=True) self.add(vbox) vbox.show() self.show() self.gui = gui # Hide the HCP stuff to begin with. self.vbox_hcp.hide_all()
class SetupNanotube(SetupWindow): "Window for setting up a (Carbon) nanotube." def __init__(self, gui): SetupWindow.__init__(self) self.set_title(_("Nanotube")) vbox = gtk.VBox() # Intoductory text self.packtext(vbox, introtext) # Choose the element and bond length label1 = gtk.Label(_("Element: ")) #label.set_alignment(0.0, 0.2) self.element = gtk.Entry(max=3) self.element.set_text("C") self.element.connect('activate', self.makeatoms) self.bondlength = gtk.Adjustment(1.42, 0.0, 1000.0, 0.01) label2 = gtk.Label(_(" Bond length: ")) label3 = gtk.Label(_(u"Å")) bond_box = gtk.SpinButton(self.bondlength, 10.0, 3) pack(vbox, [label1, self.element, label2, bond_box, label3]) self.elementinfo = gtk.Label("") self.elementinfo.modify_fg(gtk.STATE_NORMAL, gtk.gdk.color_parse('#FF0000')) pack(vbox, [self.elementinfo]) pack(vbox, gtk.Label("")) # Choose the structure. pack(vbox, [gtk.Label(_("Select roll-up vector (n,m) " "and tube length:"))]) label1 = gtk.Label("n: ") label2 = gtk.Label(" m: ") self.n = gtk.Adjustment(5, 1, 100, 1) self.m = gtk.Adjustment(5, 0, 100, 1) spinn = gtk.SpinButton(self.n, 0, 0) spinm = gtk.SpinButton(self.m, 0, 0) label3 = gtk.Label(_(" Length: ")) self.length = gtk.Adjustment(1, 1, 100, 1) spinl = gtk.SpinButton(self.length, 0, 0) pack(vbox, [label1, spinn, label2, spinm, label3, spinl]) self.err = gtk.Label("") self.err.modify_fg(gtk.STATE_NORMAL, gtk.gdk.color_parse('#FF0000')) pack(vbox, [self.err]) pack(vbox, gtk.Label("")) self.status = gtk.Label("") pack(vbox, [self.status]) pack(vbox, [gtk.Label("")]) # Buttons self.pybut = PyButton(_("Creating a nanoparticle.")) self.pybut.connect('clicked', self.makeatoms) buts = cancel_apply_ok(cancel=lambda widget: self.destroy(), apply=self.apply, ok=self.ok) pack(vbox, [self.pybut, buts], end=True, bottom=True) # Finalize setup self.makeatoms() self.bondlength.connect('value-changed', self.makeatoms) self.m.connect('value-changed', self.makeatoms) self.n.connect('value-changed', self.makeatoms) self.length.connect('value-changed', self.makeatoms) self.add(vbox) vbox.show() self.show() self.gui = gui def update_element(self, *args): "Called when a new element may have been entered." # Assumes the element widget is self.element and that a label # for errors is self.elementinfo. The chemical symbol is # placed in self.legalelement - or None if the element is # invalid. elem = self.element.get_text() if not elem: self.invalid_element(_(" No element specified!")) return False try: z = int(elem) except ValueError: # Probably a symbol try: z = ase.data.atomic_numbers[elem] except KeyError: self.invalid_element() return False try: symb = ase.data.chemical_symbols[z] except KeyError: self.invalid_element() return False self.elementinfo.set_text("") self.legal_element = symb return True def makeatoms(self, *args): self.update_element() if self.legal_element is None: self.atoms = None self.pybut.python = None else: n = int(self.n.value) m = int(self.m.value) symb = self.legal_element length = int(self.length.value) bl = self.bondlength.value self.atoms = nanotube(n, m, length=length, bond=bl, symbol=symb) # XXX can this be translated? self.pybut.python = py_template % { 'n': n, 'm': m, 'length': length, 'symb': symb, 'bl': bl } h = np.zeros(3) uc = self.atoms.get_cell() for i in range(3): norm = np.cross(uc[i - 1], uc[i - 2]) norm /= np.sqrt(np.dot(norm, norm)) h[i] = np.abs(np.dot(norm, uc[i])) label = label_template % { 'natoms': self.atoms.get_number_of_atoms(), 'symbols': formula(self.atoms.get_atomic_numbers()), 'volume': self.atoms.get_volume(), 'diameter': self.atoms.get_cell()[0][0] / 2.0 } self.status.set_markup(label) def apply(self, *args): self.makeatoms() if self.atoms is not None: self.gui.new_atoms(self.atoms) return True else: oops( _("No valid atoms."), _("You have not (yet) specified a consistent " "set of parameters.")) return False def ok(self, *args): if self.apply(): self.destroy()
class SetupNanotube(SetupWindow): "Window for setting up a (Carbon) nanotube." def __init__(self, gui): SetupWindow.__init__(self) self.set_title(_("Nanotube")) vbox = gtk.VBox() # Intoductory text self.packtext(vbox, introtext) # Choose the element and bond length label1 = gtk.Label(_("Element: ")) #label.set_alignment(0.0, 0.2) self.element = gtk.Entry(max=3) self.element.set_text("C") self.element.connect('activate', self.update_element) self.bondlength = gtk.Adjustment(1.42, 0.0, 1000.0, 0.01) label2 = gtk.Label(_(" Bond length: ")) label3 = gtk.Label(_("Å")) bond_box = gtk.SpinButton(self.bondlength, 10.0, 3) pack(vbox, [label1, self.element, label2, bond_box, label3]) self.elementinfo = gtk.Label("") self.elementinfo.modify_fg(gtk.STATE_NORMAL, gtk.gdk.color_parse('#FF0000')) pack(vbox, [self.elementinfo]) pack(vbox, gtk.Label("")) # Choose the structure. pack(vbox, [gtk.Label(_("Select roll-up vector (n,m) " "and tube length:"))]) label1 = gtk.Label("n: ") label2 = gtk.Label(" m: ") self.n = gtk.Adjustment(5, 1, 100, 1) self.m = gtk.Adjustment(5, 0, 100, 1) spinn = gtk.SpinButton(self.n, 0, 0) spinm = gtk.SpinButton(self.m, 0, 0) label3 = gtk.Label(_(" Length: ")) self.length = gtk.Adjustment(1, 1, 100, 1) spinl = gtk.SpinButton(self.length, 0, 0) pack(vbox, [label1, spinn, label2, spinm, label3, spinl]) self.err = gtk.Label("") self.err.modify_fg(gtk.STATE_NORMAL, gtk.gdk.color_parse('#FF0000')) pack(vbox, [self.err]) pack(vbox, gtk.Label("")) # Buttons self.pybut = PyButton(_("Creating a nanoparticle.")) self.pybut.connect('clicked', self.makeatoms) buts = cancel_apply_ok(cancel=lambda widget: self.destroy(), apply=self.apply, ok=self.ok) pack(vbox, [self.pybut, buts], end=True, bottom=True) # Finalize setup self.add(vbox) vbox.show() self.show() self.gui = gui def update_element(self, *args): "Called when a new element may have been entered." # Assumes the element widget is self.element and that a label # for errors is self.elementinfo. The chemical symbol is # placed in self.legalelement - or None if the element is # invalid. elem = self.element.get_text() if not elem: self.invalid_element(_(" No element specified!")) return False try: z = int(elem) except ValueError: # Probably a symbol try: z = ase.data.atomic_numbers[elem] except KeyError: self.invalid_element() return False try: symb = ase.data.chemical_symbols[z] except KeyError: self.invalid_element() return False self.elementinfo.set_text("") self.legal_element = symb return True def makeatoms(self, *args): self.update_element() if self.legal_element is None: self.atoms = None self.pybut.python = None else: n = int(self.n.value) m = int(self.m.value) symb = self.legal_element length = int(self.length.value) bl = self.bondlength.value self.atoms = nanotube(n, m, length=length, bond=bl, symbol=symb) # XXX can this be translated? self.pybut.python = py_template % {'n': n, 'm':m, 'length':length, 'symb':symb, 'bl':bl} def apply(self, *args): self.makeatoms() if self.atoms is not None: self.gui.new_atoms(self.atoms) return True else: oops(_("No valid atoms."), _("You have not (yet) specified a consistent " "set of parameters.")) return False def ok(self, *args): if self.apply(): self.destroy()
def __init__(self, gui): SetupWindow.__init__(self) self.set_title("Surface") self.atoms = None vbox = gtk.VBox() # Intoductory text self.packtext(vbox, introtext) # Choose the element label = gtk.Label("Element: ") element = gtk.Entry(max=3) self.element = element self.elementinfo = gtk.Label("") pack(vbox, [label, element, self.elementinfo]) self.element.connect('activate', self.update) self.legal_element = False # Choose the surface structure label = gtk.Label("Structure: ") self.structchoice = gtk.combo_box_new_text() self.surfinfo = {} for s in surfaces: assert len(s) == 5 self.structchoice.append_text(s[0]) self.surfinfo[s[0]] = s pack(vbox, [label, self.structchoice]) self.structchoice.connect('changed', self.update) # Choose the lattice constant tbl = gtk.Table(2, 3) label = gtk.Label("Lattice constant: ") tbl.attach(label, 0, 1, 0, 1) vbox2 = gtk.VBox() # For the non-HCP stuff self.vbox_hcp = gtk.VBox() # For the HCP stuff. self.lattice_const = gtk.Adjustment(3.0, 0.0, 1000.0, 0.01) lattice_box = gtk.SpinButton(self.lattice_const, 10.0, 3) lattice_box.numeric = True pack(vbox2, [gtk.Label("a:"), lattice_box, gtk.Label("Å")]) tbl.attach(vbox2, 1, 2, 0, 1) lattice_button = gtk.Button("Get from database") tbl.attach(lattice_button, 2, 3, 0, 1) # HCP stuff self.hcp_ideal = (8.0/3)**(1.0/3) self.lattice_const_c = gtk.Adjustment(self.lattice_const.value * self.hcp_ideal, 0.0, 1000.0, 0.01) lattice_box_c = gtk.SpinButton(self.lattice_const_c, 10.0, 3) lattice_box_c.numeric = True pack(self.vbox_hcp, [gtk.Label("c:"), lattice_box_c, gtk.Label("Å")]) self.hcp_c_over_a_format = "c/a: %.3f (%.1f %% of ideal)" self.hcp_c_over_a_label = gtk.Label(self.hcp_c_over_a_format % (self.hcp_ideal, 100.0)) pack(self.vbox_hcp, [self.hcp_c_over_a_label]) tbl.attach(self.vbox_hcp, 1, 2, 1, 2) tbl.show_all() pack(vbox, [tbl]) self.lattice_const.connect('value-changed', self.update) self.lattice_const_c.connect('value-changed', self.update) lattice_button.connect('clicked', self.get_lattice_const) pack(vbox, gtk.Label("")) # System size self.size = [gtk.Adjustment(1, 1, 100, 1) for i in range(3)] buttons = [gtk.SpinButton(s, 0, 0) for s in self.size] self.vacuum = gtk.Adjustment(10.0, 0, 100.0, 0.1) vacuum_box = gtk.SpinButton(self.vacuum, 0.0, 1) pack(vbox, [gtk.Label("Size: \tx: "), buttons[0], gtk.Label(" unit cells")]) pack(vbox, [gtk.Label("\t\ty: "), buttons[1], gtk.Label(" unit cells")]) pack(vbox, [gtk.Label(" \t\tz: "), buttons[2], gtk.Label(" layers, "), vacuum_box, gtk.Label(" Å vacuum")]) self.nosize = "\t\tNo size information yet." self.sizelabel = gtk.Label(self.nosize) pack(vbox, [self.sizelabel]) for s in self.size: s.connect('value-changed', self.update) self.vacuum.connect('value-changed', self.update) pack(vbox, gtk.Label("")) # Buttons self.pybut = PyButton("Creating a surface slab.") self.pybut.connect('clicked', self.update) buts = cancel_apply_ok(cancel=lambda widget: self.destroy(), apply=self.apply, ok=self.ok) pack(vbox, [self.pybut, buts], end=True, bottom=True) self.add(vbox) vbox.show() self.show() self.gui = gui # Hide the HCP stuff to begin with. self.vbox_hcp.hide_all()
class SetupSurfaceSlab(SetupWindow): """Window for setting up a surface.""" def __init__(self, gui): SetupWindow.__init__(self) self.set_title("Surface") self.atoms = None vbox = gtk.VBox() # Intoductory text self.packtext(vbox, introtext) # Choose the element label = gtk.Label("Element: ") element = gtk.Entry(max=3) self.element = element self.elementinfo = gtk.Label("") pack(vbox, [label, element, self.elementinfo]) self.element.connect('activate', self.update) self.legal_element = False # Choose the surface structure label = gtk.Label("Structure: ") self.structchoice = gtk.combo_box_new_text() self.surfinfo = {} for s in surfaces: assert len(s) == 5 self.structchoice.append_text(s[0]) self.surfinfo[s[0]] = s pack(vbox, [label, self.structchoice]) self.structchoice.connect('changed', self.update) # Choose the lattice constant tbl = gtk.Table(2, 3) label = gtk.Label("Lattice constant: ") tbl.attach(label, 0, 1, 0, 1) vbox2 = gtk.VBox() # For the non-HCP stuff self.vbox_hcp = gtk.VBox() # For the HCP stuff. self.lattice_const = gtk.Adjustment(3.0, 0.0, 1000.0, 0.01) lattice_box = gtk.SpinButton(self.lattice_const, 10.0, 3) lattice_box.numeric = True pack(vbox2, [gtk.Label("a:"), lattice_box, gtk.Label("Å")]) tbl.attach(vbox2, 1, 2, 0, 1) lattice_button = gtk.Button("Get from database") tbl.attach(lattice_button, 2, 3, 0, 1) # HCP stuff self.hcp_ideal = (8.0/3)**(1.0/3) self.lattice_const_c = gtk.Adjustment(self.lattice_const.value * self.hcp_ideal, 0.0, 1000.0, 0.01) lattice_box_c = gtk.SpinButton(self.lattice_const_c, 10.0, 3) lattice_box_c.numeric = True pack(self.vbox_hcp, [gtk.Label("c:"), lattice_box_c, gtk.Label("Å")]) self.hcp_c_over_a_format = "c/a: %.3f (%.1f %% of ideal)" self.hcp_c_over_a_label = gtk.Label(self.hcp_c_over_a_format % (self.hcp_ideal, 100.0)) pack(self.vbox_hcp, [self.hcp_c_over_a_label]) tbl.attach(self.vbox_hcp, 1, 2, 1, 2) tbl.show_all() pack(vbox, [tbl]) self.lattice_const.connect('value-changed', self.update) self.lattice_const_c.connect('value-changed', self.update) lattice_button.connect('clicked', self.get_lattice_const) pack(vbox, gtk.Label("")) # System size self.size = [gtk.Adjustment(1, 1, 100, 1) for i in range(3)] buttons = [gtk.SpinButton(s, 0, 0) for s in self.size] self.vacuum = gtk.Adjustment(10.0, 0, 100.0, 0.1) vacuum_box = gtk.SpinButton(self.vacuum, 0.0, 1) pack(vbox, [gtk.Label("Size: \tx: "), buttons[0], gtk.Label(" unit cells")]) pack(vbox, [gtk.Label("\t\ty: "), buttons[1], gtk.Label(" unit cells")]) pack(vbox, [gtk.Label(" \t\tz: "), buttons[2], gtk.Label(" layers, "), vacuum_box, gtk.Label(" Å vacuum")]) self.nosize = "\t\tNo size information yet." self.sizelabel = gtk.Label(self.nosize) pack(vbox, [self.sizelabel]) for s in self.size: s.connect('value-changed', self.update) self.vacuum.connect('value-changed', self.update) pack(vbox, gtk.Label("")) # Buttons self.pybut = PyButton("Creating a surface slab.") self.pybut.connect('clicked', self.update) buts = cancel_apply_ok(cancel=lambda widget: self.destroy(), apply=self.apply, ok=self.ok) pack(vbox, [self.pybut, buts], end=True, bottom=True) self.add(vbox) vbox.show() self.show() self.gui = gui # Hide the HCP stuff to begin with. self.vbox_hcp.hide_all() # update_element inherited from SetupWindow def update(self, *args): "Called when something has changed." struct = self.structchoice.get_active_text() if struct: structinfo = self.surfinfo[struct] if structinfo[1] == 'hcp': self.vbox_hcp.show_all() ca = self.lattice_const_c.value / self.lattice_const.value self.hcp_c_over_a_label.set_text(self.hcp_c_over_a_format % (ca, 100 * ca / self.hcp_ideal)) else: self.vbox_hcp.hide_all() # Abort if element or structure is invalid if not (self.update_element() and struct): self.sizelabel.set_text(self.nosize) self.atoms = None self.pybut.python = None return False # Make the atoms assert self.legal_element kw = {} kw2 = {} if structinfo[3]: # Support othogonal keyword? kw['orthogonal'] = structinfo[2] kw2['orthoarg'] = ', orthogonal='+str(kw['orthogonal']) else: kw2['orthoarg'] = '' kw2['func'] = structinfo[4].__name__ kw['symbol'] = self.legal_element kw['size'] = [int(s.value) for s in self.size] kw['a'] = self.lattice_const.value kw['vacuum'] = self.vacuum.value # Now create the atoms try: self.atoms = structinfo[4](**kw) except ValueError, e: # The values were illegal - for example some size # constants must be even for some structures. self.pybut.python = None self.atoms = None self.sizelabel.set_text(str(e).replace(". ", ".\n")) return False kw2.update(kw) self.pybut.python = py_template % kw2 # Find the heights of the unit cell h = np.zeros(3) uc = self.atoms.get_cell() for i in range(3): norm = np.cross(uc[i-1], uc[i-2]) norm /= np.sqrt(np.dot(norm, norm)) h[i] = np.abs(np.dot(norm, uc[i])) natoms = len(self.atoms) txt = ("\t\t%.2f Å x %.2f Å x %.2f Å, %i atoms." % (h[0], h[1], h[2], natoms)) self.sizelabel.set_text(txt) return True
def __init__(self, gui): SetupWindow.__init__(self) self.set_title(_("Create Bulk Crystal by Spacegroup")) self.atoms = None vbox = gtk.VBox() self.packtext(vbox, introtext) self.structinfo = gtk.combo_box_new_text() self.structures = {} for c in crystal_definitions: self.structinfo.append_text(c[0]) self.structures[c[0]] = c self.structinfo.set_active(0) self.structinfo.connect("changed",self.set_lattice_type) self.spacegroup = gtk.Entry(max=14) self.spacegroup.set_text('P 1') self.elementinfo = gtk.Label("") self.spacegroupinfo = gtk.Label(_('Number: 1')) pack(vbox,[gtk.Label(_("Lattice: ")),self.structinfo,gtk.Label(_("\tSpace group: ")),self.spacegroup,gtk.Label(' '),self.spacegroupinfo,gtk.Label(' '),self.elementinfo]) pack(vbox,[gtk.Label("")]) self.size = [gtk.Adjustment(1, 1, 100, 1) for i in range(3)] buttons = [gtk.SpinButton(s, 0, 0) for s in self.size] pack(vbox, [gtk.Label(_("Size: x: ")), buttons[0], gtk.Label(_(" y: ")), buttons[1], gtk.Label(_(" z: ")), buttons[2], gtk.Label(_(" unit cells"))]) pack(vbox,[gtk.Label("")]) self.lattice_lengths = [gtk.Adjustment(3.0, 0.0, 1000.0, 0.01) for i in range(3)] self.lattice_angles = [gtk.Adjustment(90.0,0.0, 180.0, 1) for i in range(3)] self.lattice_lbuts = [gtk.SpinButton(self.lattice_lengths[i], 0, 0) for i in range(3)] self.lattice_abuts = [gtk.SpinButton(self.lattice_angles[i] , 0, 0) for i in range(3)] for i in self.lattice_lbuts: i.set_digits(5) for i in self.lattice_abuts: i.set_digits(3) self.lattice_lequals = [gtk.combo_box_new_text() for i in range(3)] self.lattice_aequals = [gtk.combo_box_new_text() for i in range(3)] self.lattice_lequals[0].append_text(_('free')) self.lattice_lequals[0].append_text(_('equals b')) self.lattice_lequals[0].append_text(_('equals c')) self.lattice_lequals[0].append_text(_('fixed')) self.lattice_lequals[1].append_text(_('free')) self.lattice_lequals[1].append_text(_('equals a')) self.lattice_lequals[1].append_text(_('equals c')) self.lattice_lequals[1].append_text(_('fixed')) self.lattice_lequals[2].append_text(_('free')) self.lattice_lequals[2].append_text(_('equals a')) self.lattice_lequals[2].append_text(_('equals b')) self.lattice_lequals[2].append_text(_('fixed')) self.lattice_aequals[0].append_text(_('free')) self.lattice_aequals[0].append_text(_('equals beta')) self.lattice_aequals[0].append_text(_('equals gamma')) self.lattice_aequals[0].append_text(_('fixed')) self.lattice_aequals[1].append_text(_('free')) self.lattice_aequals[1].append_text(_('equals alpha')) self.lattice_aequals[1].append_text(_('equals gamma')) self.lattice_aequals[1].append_text(_('fixed')) self.lattice_aequals[2].append_text(_('free')) self.lattice_aequals[2].append_text(_('equals alpha')) self.lattice_aequals[2].append_text(_('equals beta')) self.lattice_aequals[2].append_text(_('fixed')) for i in range(3): self.lattice_lequals[i].set_active(0) self.lattice_aequals[i].set_active(0) pack(vbox,[gtk.Label(_('Lattice parameters'))]) pack(vbox,[gtk.Label(_('\t\ta:\t')) , self.lattice_lbuts[0],gtk.Label(' '),self.lattice_lequals[0], gtk.Label(_('\talpha:\t')), self.lattice_abuts[0],gtk.Label(' '),self.lattice_aequals[0]]) pack(vbox,[gtk.Label(_('\t\tb:\t')) , self.lattice_lbuts[1],gtk.Label(' '),self.lattice_lequals[1], gtk.Label(_('\tbeta:\t')) , self.lattice_abuts[1],gtk.Label(' '),self.lattice_aequals[1]]) pack(vbox,[gtk.Label(_('\t\tc:\t')) , self.lattice_lbuts[2],gtk.Label(' '),self.lattice_lequals[2], gtk.Label(_('\tgamma:\t')), self.lattice_abuts[2],gtk.Label(' '),self.lattice_aequals[2]]) self.get_data = gtk.Button(_("Get from database")) self.get_data.connect("clicked", self.get_from_database) self.get_data.set_sensitive(False) pack(vbox,[gtk.Label(" "),self.get_data]) pack(vbox,[gtk.Label("")]) pack(vbox,[gtk.Label(_("Basis: "))]) self.elements = [[gtk.Entry(max=3),gtk.Entry(max=8),gtk.Entry(max=8),gtk.Entry(max=8),True]] self.element = self.elements[0][0] add_atom = gtk.Button(stock = gtk.STOCK_ADD) add_atom.connect("clicked",self.add_basis_atom) add_atom.connect("activate",self.add_basis_atom) pack(vbox,[gtk.Label(_(' Element:\t')),self.elements[0][0],gtk.Label(_('\tx: ')), self.elements[0][1],gtk.Label(_(' y: ')),self.elements[0][2], gtk.Label(_(' z: ')),self.elements[0][3],gtk.Label('\t'),add_atom]) self.vbox_basis = gtk.VBox() swin = gtk.ScrolledWindow() swin.set_border_width(0) swin.set_policy(gtk.POLICY_AUTOMATIC, gtk.POLICY_AUTOMATIC) vbox.pack_start(swin, True, True, 0) swin.add_with_viewport(self.vbox_basis) self.vbox_basis.get_parent().set_shadow_type(gtk.SHADOW_NONE) self.vbox_basis.get_parent().set_size_request(-1, 100) swin.show() pack(self.vbox_basis,[gtk.Label('')]) pack(vbox,[self.vbox_basis]) self.vbox_basis.show() pack(vbox,[gtk.Label("")]) self.status = gtk.Label("") pack(vbox,[self.status]) pack(vbox,[gtk.Label("")]) self.pybut = PyButton(_("Creating a crystal.")) self.pybut.connect('clicked', self.update) clear = gtk.Button(stock = gtk.STOCK_CLEAR) clear.connect("clicked", self.clear) buts = cancel_apply_ok(cancel=lambda widget: self.destroy(), apply=self.apply, ok=self.ok) pack(vbox, [self.pybut, clear, buts], end=True, bottom=True) self.structinfo.connect("changed", self.update) self.spacegroup.connect("activate", self.update) for s in self.size: s.connect("value-changed",self.update) for el in self.elements: if el[-1]: for i in el[:-1]: i.connect("activate", self.update) i.connect("changed", self.update) for i in range(3): self.lattice_lbuts[i].connect("value-changed", self.update) self.lattice_abuts[i].connect("value-changed", self.update) self.lattice_lequals[i].connect("changed", self.update) self.lattice_aequals[i].connect("changed", self.update) self.clearing_in_process = False self.gui = gui self.add(vbox) vbox.show() self.show()
class SetupBulkCrystal(SetupWindow): """Window for setting up a surface.""" def __init__(self, gui): SetupWindow.__init__(self) self.set_title(_("Create Bulk Crystal by Spacegroup")) self.atoms = None vbox = gtk.VBox() self.packtext(vbox, introtext) self.structinfo = gtk.combo_box_new_text() self.structures = {} for c in crystal_definitions: self.structinfo.append_text(c[0]) self.structures[c[0]] = c self.structinfo.set_active(0) self.structinfo.connect("changed",self.set_lattice_type) self.spacegroup = gtk.Entry(max=14) self.spacegroup.set_text('P 1') self.elementinfo = gtk.Label("") self.spacegroupinfo = gtk.Label(_('Number: 1')) pack(vbox,[gtk.Label(_("Lattice: ")),self.structinfo,gtk.Label(_("\tSpace group: ")),self.spacegroup,gtk.Label(' '),self.spacegroupinfo,gtk.Label(' '),self.elementinfo]) pack(vbox,[gtk.Label("")]) self.size = [gtk.Adjustment(1, 1, 100, 1) for i in range(3)] buttons = [gtk.SpinButton(s, 0, 0) for s in self.size] pack(vbox, [gtk.Label(_("Size: x: ")), buttons[0], gtk.Label(_(" y: ")), buttons[1], gtk.Label(_(" z: ")), buttons[2], gtk.Label(_(" unit cells"))]) pack(vbox,[gtk.Label("")]) self.lattice_lengths = [gtk.Adjustment(3.0, 0.0, 1000.0, 0.01) for i in range(3)] self.lattice_angles = [gtk.Adjustment(90.0,0.0, 180.0, 1) for i in range(3)] self.lattice_lbuts = [gtk.SpinButton(self.lattice_lengths[i], 0, 0) for i in range(3)] self.lattice_abuts = [gtk.SpinButton(self.lattice_angles[i] , 0, 0) for i in range(3)] for i in self.lattice_lbuts: i.set_digits(5) for i in self.lattice_abuts: i.set_digits(3) self.lattice_lequals = [gtk.combo_box_new_text() for i in range(3)] self.lattice_aequals = [gtk.combo_box_new_text() for i in range(3)] self.lattice_lequals[0].append_text(_('free')) self.lattice_lequals[0].append_text(_('equals b')) self.lattice_lequals[0].append_text(_('equals c')) self.lattice_lequals[0].append_text(_('fixed')) self.lattice_lequals[1].append_text(_('free')) self.lattice_lequals[1].append_text(_('equals a')) self.lattice_lequals[1].append_text(_('equals c')) self.lattice_lequals[1].append_text(_('fixed')) self.lattice_lequals[2].append_text(_('free')) self.lattice_lequals[2].append_text(_('equals a')) self.lattice_lequals[2].append_text(_('equals b')) self.lattice_lequals[2].append_text(_('fixed')) self.lattice_aequals[0].append_text(_('free')) self.lattice_aequals[0].append_text(_('equals beta')) self.lattice_aequals[0].append_text(_('equals gamma')) self.lattice_aequals[0].append_text(_('fixed')) self.lattice_aequals[1].append_text(_('free')) self.lattice_aequals[1].append_text(_('equals alpha')) self.lattice_aequals[1].append_text(_('equals gamma')) self.lattice_aequals[1].append_text(_('fixed')) self.lattice_aequals[2].append_text(_('free')) self.lattice_aequals[2].append_text(_('equals alpha')) self.lattice_aequals[2].append_text(_('equals beta')) self.lattice_aequals[2].append_text(_('fixed')) for i in range(3): self.lattice_lequals[i].set_active(0) self.lattice_aequals[i].set_active(0) pack(vbox,[gtk.Label(_('Lattice parameters'))]) pack(vbox,[gtk.Label(_('\t\ta:\t')) , self.lattice_lbuts[0],gtk.Label(' '),self.lattice_lequals[0], gtk.Label(_('\talpha:\t')), self.lattice_abuts[0],gtk.Label(' '),self.lattice_aequals[0]]) pack(vbox,[gtk.Label(_('\t\tb:\t')) , self.lattice_lbuts[1],gtk.Label(' '),self.lattice_lequals[1], gtk.Label(_('\tbeta:\t')) , self.lattice_abuts[1],gtk.Label(' '),self.lattice_aequals[1]]) pack(vbox,[gtk.Label(_('\t\tc:\t')) , self.lattice_lbuts[2],gtk.Label(' '),self.lattice_lequals[2], gtk.Label(_('\tgamma:\t')), self.lattice_abuts[2],gtk.Label(' '),self.lattice_aequals[2]]) self.get_data = gtk.Button(_("Get from database")) self.get_data.connect("clicked", self.get_from_database) self.get_data.set_sensitive(False) pack(vbox,[gtk.Label(" "),self.get_data]) pack(vbox,[gtk.Label("")]) pack(vbox,[gtk.Label(_("Basis: "))]) self.elements = [[gtk.Entry(max=3),gtk.Entry(max=8),gtk.Entry(max=8),gtk.Entry(max=8),True]] self.element = self.elements[0][0] add_atom = gtk.Button(stock = gtk.STOCK_ADD) add_atom.connect("clicked",self.add_basis_atom) add_atom.connect("activate",self.add_basis_atom) pack(vbox,[gtk.Label(_(' Element:\t')),self.elements[0][0],gtk.Label(_('\tx: ')), self.elements[0][1],gtk.Label(_(' y: ')),self.elements[0][2], gtk.Label(_(' z: ')),self.elements[0][3],gtk.Label('\t'),add_atom]) self.vbox_basis = gtk.VBox() swin = gtk.ScrolledWindow() swin.set_border_width(0) swin.set_policy(gtk.POLICY_AUTOMATIC, gtk.POLICY_AUTOMATIC) vbox.pack_start(swin, True, True, 0) swin.add_with_viewport(self.vbox_basis) self.vbox_basis.get_parent().set_shadow_type(gtk.SHADOW_NONE) self.vbox_basis.get_parent().set_size_request(-1, 100) swin.show() pack(self.vbox_basis,[gtk.Label('')]) pack(vbox,[self.vbox_basis]) self.vbox_basis.show() pack(vbox,[gtk.Label("")]) self.status = gtk.Label("") pack(vbox,[self.status]) pack(vbox,[gtk.Label("")]) self.pybut = PyButton(_("Creating a crystal.")) self.pybut.connect('clicked', self.update) clear = gtk.Button(stock = gtk.STOCK_CLEAR) clear.connect("clicked", self.clear) buts = cancel_apply_ok(cancel=lambda widget: self.destroy(), apply=self.apply, ok=self.ok) pack(vbox, [self.pybut, clear, buts], end=True, bottom=True) self.structinfo.connect("changed", self.update) self.spacegroup.connect("activate", self.update) for s in self.size: s.connect("value-changed",self.update) for el in self.elements: if el[-1]: for i in el[:-1]: i.connect("activate", self.update) i.connect("changed", self.update) for i in range(3): self.lattice_lbuts[i].connect("value-changed", self.update) self.lattice_abuts[i].connect("value-changed", self.update) self.lattice_lequals[i].connect("changed", self.update) self.lattice_aequals[i].connect("changed", self.update) self.clearing_in_process = False self.gui = gui self.add(vbox) vbox.show() self.show() def update(self, *args): """ all changes of physical constants are handled here, atoms are set up""" if self.clearing_in_process: return True self.update_element() a_equals = self.lattice_lequals[0].get_active() b_equals = self.lattice_lequals[1].get_active() c_equals = self.lattice_lequals[2].get_active() alpha_equals = self.lattice_aequals[0].get_active() beta_equals = self.lattice_aequals[1].get_active() gamma_equals = self.lattice_aequals[2].get_active() sym = self.spacegroup.get_text() valid = True try: no = int(sym) spg = Spacegroup(no).symbol self.spacegroupinfo.set_label(_('Symbol: %s') % str(spg)) spg = no except: try: no = Spacegroup(sym).no self.spacegroupinfo.set_label(_('Number: %s') % str(no)) spg = no except: self.spacegroupinfo.set_label(_('Invalid Spacegroup!')) valid = False if a_equals == 0: self.lattice_lbuts[0].set_sensitive(True) elif a_equals == 1: self.lattice_lbuts[0].set_sensitive(False) self.lattice_lbuts[0].set_value(self.lattice_lbuts[1].get_value()) elif a_equals == 2: self.lattice_lbuts[0].set_sensitive(False) self.lattice_lbuts[0].set_value(self.lattice_lbuts[2].get_value()) else: self.lattice_lbuts[0].set_sensitive(False) if b_equals == 0: self.lattice_lbuts[1].set_sensitive(True) elif b_equals == 1: self.lattice_lbuts[1].set_sensitive(False) self.lattice_lbuts[1].set_value(self.lattice_lbuts[0].get_value()) elif b_equals == 2: self.lattice_lbuts[1].set_sensitive(False) self.lattice_lbuts[1].set_value(self.lattice_lbuts[2].get_value()) else: self.lattice_lbuts[1].set_sensitive(False) if c_equals == 0: self.lattice_lbuts[2].set_sensitive(True) elif c_equals == 1: self.lattice_lbuts[2].set_sensitive(False) self.lattice_lbuts[2].set_value(self.lattice_lbuts[0].get_value()) elif c_equals == 2: self.lattice_lbuts[2].set_sensitive(False) self.lattice_lbuts[2].set_value(self.lattice_lbuts[1].get_value()) else: self.lattice_lbuts[2].set_sensitive(False) if alpha_equals == 0: self.lattice_abuts[0].set_sensitive(True) elif alpha_equals == 1: self.lattice_abuts[0].set_sensitive(False) self.lattice_abuts[0].set_value(self.lattice_abuts[1].get_value()) elif alpha_equals == 2: self.lattice_abuts[0].set_sensitive(False) self.lattice_abuts[0].set_value(self.lattice_abuts[2].get_value()) else: self.lattice_abuts[0].set_sensitive(False) if beta_equals == 0: self.lattice_abuts[1].set_sensitive(True) elif beta_equals == 1: self.lattice_abuts[1].set_sensitive(False) self.lattice_abuts[1].set_value(self.lattice_abuts[0].get_value()) elif beta_equals == 2: self.lattice_abuts[1].set_sensitive(False) self.lattice_abuts[1].set_value(self.lattice_abuts[2].get_value()) else: self.lattice_abuts[1].set_sensitive(False) if gamma_equals == 0: self.lattice_abuts[2].set_sensitive(True) elif gamma_equals == 1: self.lattice_abuts[2].set_sensitive(False) self.lattice_abuts[2].set_value(self.lattice_abuts[0].get_value()) elif gamma_equals == 2: self.lattice_abuts[2].set_sensitive(False) self.lattice_abuts[2].set_value(self.lattice_abuts[1].get_value()) else: self.lattice_abuts[2].set_sensitive(False) valid = len(self.elements[0][0].get_text()) and valid self.get_data.set_sensitive(valid and self.get_n_elements() == 1 and self.update_element()) self.atoms = None if valid: basis_count = -1 for el in self.elements: if el[-1]: basis_count += 1 if basis_count: symbol_str = '[' basis_str = "[" symbol = [] basis = [] else: symbol_str = '' basis_str = '' basis = None for el in self.elements: if el[-1]: symbol_str += "'"+el[0].get_text()+"'" if basis_count: symbol_str += ',' symbol += [el[0].get_text()] exec 'basis += [[float('+el[1].get_text()+'),float('+el[2].get_text()+'),float('+el[3].get_text()+')]]' else: symbol = el[0].get_text() exec 'basis = [[float('+el[1].get_text()+'),float('+el[2].get_text()+'),float('+el[3].get_text()+')]]' basis_str += '['+el[1].get_text()+','+el[2].get_text()+','+el[3].get_text()+'],' basis_str = basis_str[:-1] if basis_count: symbol_str = symbol_str[:-1]+']' basis_str += ']' size_str = '('+str(int(self.size[0].get_value()))+','+str(int(self.size[1].get_value()))+','+str(int(self.size[2].get_value()))+')' size = (int(self.size[0].get_value()),int(self.size[1].get_value()),int(self.size[2].get_value())) cellpar_str = '' cellpar = [] for i in self.lattice_lbuts: cellpar_str += str(i.get_value())+',' cellpar += [i.get_value()] for i in self.lattice_abuts: cellpar_str += str(i.get_value())+',' cellpar += [i.get_value()] cellpar_str = '['+cellpar_str[:-1]+']' args = {'symbols' : symbol, 'basis' : basis, 'size' : size, 'spacegroup' : spg, 'cellpar' : cellpar} args_str = {'symbols' : symbol_str, 'basis' : basis_str, 'size' : size_str, 'spacegroup' : spg, 'cellpar' : cellpar_str} self.pybut.python = py_template % args_str try: self.atoms = crystal(**args) label = label_template % {'natoms' : self.atoms.get_number_of_atoms(), 'symbols' : formula(self.atoms.get_atomic_numbers()), 'volume' : self.atoms.get_volume()} self.status.set_label(label) except: self.atoms = None self.status.set_markup(_("Please specify a consistent set of atoms.")) else: self.atoms = None self.status.set_markup(_("Please specify a consistent set of atoms.")) 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: oops(_("No valid atoms.", "You have not (yet) specified a consistent set of " "parameters.")) return False def ok(self, *args): if self.apply(): self.destroy() def add_basis_atom(self,*args): """ add an atom to the customizable basis """ n = len(self.elements) self.elements += [[gtk.Entry(max=3),gtk.Entry(max=8),gtk.Entry(max=8),gtk.Entry(max=8), gtk.Label('\t\t\t'),gtk.Label('\tx: '),gtk.Label(' y: '), gtk.Label(' z: '),gtk.Label(' '), gtk.Button(stock=gtk.STOCK_DELETE),True]] self.elements[n][-2].connect("clicked",self.delete_basis_atom,{'n':n}) pack(self.vbox_basis,[self.elements[n][4],self.elements[n][0],self.elements[n][5], self.elements[n][1],self.elements[n][6],self.elements[n][2], self.elements[n][7],self.elements[n][3],self.elements[n][8], self.elements[n][9]]) self.update() def delete_basis_atom(self, button, index, *args): """ delete atom index from customizable basis""" n = index['n'] self.elements[n][-1] = False for i in range(10): self.elements[n][i].destroy() self.update() def get_n_elements(self): """ counts how many basis atoms are actually active """ n = 0 for el in self.elements: if el[-1]: n += 1 return n def clear(self, *args): """ reset to original state """ self.clearing_in_process = True self.clear_lattice() self.structinfo.set_active(0) self.set_lattice_type() self.clearing_in_process = False self.update() def clear_lattice(self, *args): """ delete all custom settings """ self.atoms = None if len(self.elements) > 1: for n, el in enumerate(self.elements[1:]): self.elements[n+1][-1] = False for i in range(10): self.elements[n+1][i].destroy() for i in range(4): self.elements[0][i].set_text("") self.spacegroup.set_sensitive(True) for i in self.lattice_lbuts: i.set_sensitive(True) for i in self.lattice_abuts: i.set_sensitive(True) for i in range(3): self.lattice_lequals[i].set_sensitive(True) self.lattice_aequals[i].set_sensitive(True) self.lattice_lequals[i].set_active(0) self.lattice_aequals[i].set_active(0) for s in self.size: s.set_value(1) def set_lattice_type(self, *args): """ set defaults from original """ self.clearing_in_process = True self.clear_lattice() lattice = crystal_definitions[self.structinfo.get_active()] self.spacegroup.set_text(str(lattice[1])) self.spacegroup.set_sensitive(lattice[2]) for s, i in zip(self.size,lattice[3]): s.set_value(i) self.lattice_lbuts[0].set_value(lattice[4][0]) self.lattice_lbuts[1].set_value(lattice[4][1]) self.lattice_lbuts[2].set_value(lattice[4][2]) self.lattice_abuts[0].set_value(lattice[4][3]) self.lattice_abuts[1].set_value(lattice[4][4]) self.lattice_abuts[2].set_value(lattice[4][5]) self.lattice_lequals[0].set_active(lattice[5][0]) self.lattice_lequals[1].set_active(lattice[5][1]) self.lattice_lequals[2].set_active(lattice[5][2]) self.lattice_aequals[0].set_active(lattice[5][3]) self.lattice_aequals[1].set_active(lattice[5][4]) self.lattice_aequals[2].set_active(lattice[5][5]) self.lattice_lequals[0].set_sensitive(lattice[6][0]) self.lattice_lequals[1].set_sensitive(lattice[6][1]) self.lattice_lequals[2].set_sensitive(lattice[6][2]) self.lattice_aequals[0].set_sensitive(lattice[6][3]) self.lattice_aequals[1].set_sensitive(lattice[6][4]) self.lattice_aequals[2].set_sensitive(lattice[6][5]) for n, at in enumerate(lattice[7]): l = 0 if n > 0: l = len(self.elements) self.add_basis_atom() for i, s in enumerate(at): self.elements[l][i].set_text(s) self.clearing_in_process = False self.update() def get_from_database(self, *args): element = self.elements[0][0].get_text() z = ase.data.atomic_numbers[self.legal_element] ref = ase.data.reference_states[z] lattice = ref['symmetry'] index = 0 while index < len(crystal_definitions) and crystal_definitions[index][0] != lattice: index += 1 if index == len(crystal_definitions) or not self.legal_element: oops(_("Can't find lattice definition!")) return False self.structinfo.set_active(index) self.lattice_lbuts[0].set_value(ref['a']) if lattice == 'hcp': self.lattice_lbuts[2].set_value(ref['c/a']*ref['a']) self.elements[0][0].set_text(element) if lattice in ['fcc', 'bcc', 'diamond']: self.elements[0][1].set_text('0') self.elements[0][2].set_text('0') self.elements[0][3].set_text('0')
class SetupNanoparticle(SetupWindow): "Window for setting up a nanoparticle." # Structures: Abbreviation, name, 4-index (boolean), two lattice const (bool), factory structure_data = (('fcc', _('Face centered cubic (fcc)'), False, False, FaceCenteredCubic), ('bcc', _('Body centered cubic (bcc)'), False, False, BodyCenteredCubic), ('sc', _('Simple cubic (sc)'), False, False, SimpleCubic), ('hcp', _('Hexagonal closed-packed (hcp)'), True, True, HexagonalClosedPacked), ('graphite', _('Graphite'), True, True, Graphite), ) #NB: HCP is broken! # A list of import statements for the Python window. import_names = {'fcc': 'from ase.cluster.cubic import FaceCenteredCubic', 'bcc': 'from ase.cluster.cubic import BodyCenteredCubic', 'sc': 'from ase.cluster.cubic import SimpleCubic', 'hcp': 'from ase.cluster.hexagonal import HexagonalClosedPacked', 'graphite': 'from ase.cluster.hexagonal import Graphite', } # Default layer specifications for the different structures. default_layers = {'fcc': [( (1,0,0), 6), ( (1,1,0), 9), ( (1,1,1), 5)], 'bcc': [( (1,0,0), 6), ( (1,1,0), 9), ( (1,1,1), 5)], 'sc': [( (1,0,0), 6), ( (1,1,0), 9), ( (1,1,1), 5)], 'hcp': [( (0,0,0,1), 5), ( (1,0,-1,0), 5)], 'graphite': [( (0,0,0,1), 5), ( (1,0,-1,0), 5)] } def __init__(self, gui): SetupWindow.__init__(self) self.set_title(_("Nanoparticle")) self.atoms = None self.no_update = True vbox = gtk.VBox() # Intoductory text self.packtext(vbox, introtext) # Choose the element label = gtk.Label(_("Element: ")) label.set_alignment(0.0, 0.2) element = gtk.Entry(max=3) self.element = element lattice_button = gtk.Button(_("Get structure")) lattice_button.connect('clicked', self.set_structure_data) self.elementinfo = gtk.Label(" ") pack(vbox, [label, element, self.elementinfo, lattice_button], end=True) self.element.connect('activate', self.update) self.legal_element = False # The structure and lattice constant label = gtk.Label(_("Structure: ")) self.structure = gtk.combo_box_new_text() self.list_of_structures = [] self.needs_4index = {} self.needs_2lat = {} self.factory = {} for abbrev, name, n4, c, factory in self.structure_data: self.structure.append_text(name) self.list_of_structures.append(abbrev) self.needs_4index[abbrev] = n4 self.needs_2lat[abbrev] = c self.factory[abbrev] = factory self.structure.set_active(0) self.fourindex = self.needs_4index[self.list_of_structures[0]] self.structure.connect('changed', self.update_structure) label2 = gtk.Label(_("Lattice constant: a =")) self.lattice_const_a = gtk.Adjustment(3.0, 0.0, 1000.0, 0.01) self.lattice_const_c = gtk.Adjustment(5.0, 0.0, 1000.0, 0.01) self.lattice_box_a = gtk.SpinButton(self.lattice_const_a, 10.0, 3) self.lattice_box_c = gtk.SpinButton(self.lattice_const_c, 10.0, 3) self.lattice_box_a.numeric = True self.lattice_box_c.numeric = True self.lattice_label_c = gtk.Label(" c =") pack(vbox, [label, self.structure]) pack(vbox, [label2, self.lattice_box_a, self.lattice_label_c, self.lattice_box_c]) self.lattice_label_c.hide() self.lattice_box_c.hide() self.lattice_const_a.connect('value-changed', self.update) self.lattice_const_c.connect('value-changed', self.update) # Choose specification method label = gtk.Label(_("Method: ")) self.method = gtk.combo_box_new_text() for meth in (_("Layer specification"), _("Wulff construction")): self.method.append_text(meth) self.method.set_active(0) self.method.connect('changed', self.update_gui_method) pack(vbox, [label, self.method]) pack(vbox, gtk.Label("")) self.old_structure = None frame = gtk.Frame() pack(vbox, frame) framebox = gtk.VBox() frame.add(framebox) framebox.show() self.layerlabel = gtk.Label("Missing text") # Filled in later pack(framebox, [self.layerlabel]) # This box will contain a single table that is replaced when # the list of directions is changed. self.direction_table_box = gtk.VBox() pack(framebox, self.direction_table_box) pack(self.direction_table_box, gtk.Label(_("Dummy placeholder object"))) pack(framebox, gtk.Label("")) pack(framebox, [gtk.Label(_("Add new direction:"))]) self.newdir_label = [] self.newdir_box = [] self.newdir_index = [] packlist = [] for txt in ('(', ', ', ', ', ', '): self.newdir_label.append(gtk.Label(txt)) adj = gtk.Adjustment(0, -100, 100, 1) self.newdir_box.append(gtk.SpinButton(adj, 1, 0)) self.newdir_index.append(adj) packlist.append(self.newdir_label[-1]) packlist.append(self.newdir_box[-1]) self.newdir_layers = gtk.Adjustment(5, 0, 100, 1) self.newdir_layers_box = gtk.SpinButton(self.newdir_layers, 1, 0) self.newdir_esurf = gtk.Adjustment(1.0, 0, 1000.0, 0.1) self.newdir_esurf_box = gtk.SpinButton(self.newdir_esurf, 10, 3) addbutton = gtk.Button(_("Add")) addbutton.connect('clicked', self.row_add) packlist.extend([gtk.Label("): "), self.newdir_layers_box, self.newdir_esurf_box, gtk.Label(" "), addbutton]) pack(framebox, packlist) self.defaultbutton = gtk.Button(_("Set all directions to default " "values")) self.defaultbutton.connect('clicked', self.default_direction_table) self.default_direction_table() # Extra widgets for the Wulff construction self.wulffbox = gtk.VBox() pack(vbox, self.wulffbox) label = gtk.Label(_("Particle size: ")) self.size_n_radio = gtk.RadioButton(None, _("Number of atoms: ")) self.size_n_radio.set_active(True) self.size_n_adj = gtk.Adjustment(100, 1, 100000, 1) self.size_n_spin = gtk.SpinButton(self.size_n_adj, 0, 0) self.size_dia_radio = gtk.RadioButton(self.size_n_radio, _("Volume: ")) self.size_dia_adj = gtk.Adjustment(1.0, 0, 100.0, 0.1) self.size_dia_spin = gtk.SpinButton(self.size_dia_adj, 10.0, 2) pack(self.wulffbox, [label, self.size_n_radio, self.size_n_spin, gtk.Label(" "), self.size_dia_radio, self.size_dia_spin, gtk.Label(_(u"ų"))]) self.size_n_radio.connect("toggled", self.update_gui_size) self.size_dia_radio.connect("toggled", self.update_gui_size) self.size_n_adj.connect("value-changed", self.update_size_n) self.size_dia_adj.connect("value-changed", self.update_size_dia) label = gtk.Label(_("Rounding: If exact size is not possible, " "choose the size")) pack(self.wulffbox, [label]) self.round_above = gtk.RadioButton(None, _("above ")) self.round_below = gtk.RadioButton(self.round_above, _("below ")) self.round_closest = gtk.RadioButton(self.round_above, _("closest ")) self.round_closest.set_active(True) butbox = gtk.HButtonBox() self.smaller_button = gtk.Button(_("Smaller")) self.larger_button = gtk.Button(_("Larger")) self.smaller_button.connect('clicked', self.wulff_smaller) self.larger_button.connect('clicked', self.wulff_larger) pack(butbox, [self.smaller_button, self.larger_button]) buts = [self.round_above, self.round_below, self.round_closest] for b in buts: b.connect("toggled", self.update) buts.append(butbox) pack(self.wulffbox, buts, end=True) # Information pack(vbox, gtk.Label("")) infobox = gtk.VBox() label1 = gtk.Label(_("Number of atoms: ")) self.natoms_label = gtk.Label("-") label2 = gtk.Label(_(" Approx. diameter: ")) self.dia1_label = gtk.Label("-") pack(infobox, [label1, self.natoms_label, label2, self.dia1_label]) pack(infobox, gtk.Label("")) infoframe = gtk.Frame(_("Information about the created cluster:")) infoframe.add(infobox) infobox.show() pack(vbox, infoframe) # Buttons self.pybut = PyButton(_("Creating a nanoparticle.")) self.pybut.connect('clicked', self.makeatoms) helpbut = help(helptext) buts = cancel_apply_ok(cancel=lambda widget: self.destroy(), apply=self.apply, ok=self.ok) pack(vbox, [self.pybut, helpbut, buts], end=True, bottom=True) self.auto = gtk.CheckButton(_("Automatic Apply")) fr = gtk.Frame() fr.add(self.auto) fr.show_all() pack(vbox, [fr], end=True, bottom=True) # Finalize setup self.update_structure() self.update_gui_method() self.add(vbox) vbox.show() self.show() self.gui = gui self.no_update = False def default_direction_table(self, widget=None): "Set default directions and values for the current crystal structure." self.direction_table = [] struct = self.get_structure() for direction, layers in self.default_layers[struct]: adj1 = gtk.Adjustment(layers, -100, 100, 1) adj2 = gtk.Adjustment(1.0, -1000.0, 1000.0, 0.1) adj1.connect("value-changed", self.update) adj2.connect("value-changed", self.update) self.direction_table.append([direction, adj1, adj2]) self.update_direction_table() def update_direction_table(self): "Update the part of the GUI containing the table of directions." #Discard old table oldwidgets = self.direction_table_box.get_children() assert len(oldwidgets) == 1 oldwidgets[0].hide() self.direction_table_box.remove(oldwidgets[0]) del oldwidgets # It should now be gone tbl = gtk.Table(len(self.direction_table)+1, 7) pack(self.direction_table_box, [tbl]) for i, data in enumerate(self.direction_table): tbl.attach(gtk.Label("%s: " % (str(data[0]),)), 0, 1, i, i+1) if self.method.get_active(): # Wulff construction spin = gtk.SpinButton(data[2], 1.0, 3) else: # Layers spin = gtk.SpinButton(data[1], 1, 0) tbl.attach(spin, 1, 2, i, i+1) tbl.attach(gtk.Label(" "), 2, 3, i, i+1) but = gtk.Button(_("Up")) but.connect("clicked", self.row_swap_next, i-1) if i == 0: but.set_sensitive(False) tbl.attach(but, 3, 4, i, i+1) but = gtk.Button(_("Down")) but.connect("clicked", self.row_swap_next, i) if i == len(self.direction_table)-1: but.set_sensitive(False) tbl.attach(but, 4, 5, i, i+1) but = gtk.Button(_("Delete")) but.connect("clicked", self.row_delete, i) if len(self.direction_table) == 1: but.set_sensitive(False) tbl.attach(but, 5, 6, i, i+1) tbl.show_all() self.update() def get_structure(self): "Returns the crystal structure chosen by the user." return self.list_of_structures[self.structure.get_active()] def update_structure(self, widget=None): "Called when the user changes the structure." s = self.get_structure() if s != self.old_structure: old4 = self.fourindex self.fourindex = self.needs_4index[s] if self.fourindex != old4: # The table of directions is invalid. self.default_direction_table() self.old_structure = s if self.needs_2lat[s]: self.lattice_label_c.show() self.lattice_box_c.show() else: self.lattice_label_c.hide() self.lattice_box_c.hide() if self.fourindex: self.newdir_label[3].show() self.newdir_box[3].show() else: self.newdir_label[3].hide() self.newdir_box[3].hide() self.update() def update_gui_method(self, widget=None): "Switch between layer specification and Wulff construction." self.update_direction_table() if self.method.get_active(): self.wulffbox.show() self.layerlabel.set_text(_("Surface energies (as energy/area, " "NOT per atom):")) self.newdir_layers_box.hide() self.newdir_esurf_box.show() else: self.wulffbox.hide() self.layerlabel.set_text(_("Number of layers:")) self.newdir_layers_box.show() self.newdir_esurf_box.hide() self.update() def wulff_smaller(self, widget=None): "Make a smaller Wulff construction." n = len(self.atoms) self.size_n_radio.set_active(True) self.size_n_adj.value = n-1 self.round_below.set_active(True) self.apply() def wulff_larger(self, widget=None): "Make a larger Wulff construction." n = len(self.atoms) self.size_n_radio.set_active(True) self.size_n_adj.value = n+1 self.round_above.set_active(True) self.apply() def row_add(self, widget=None): "Add a row to the list of directions." if self.fourindex: n = 4 else: n = 3 idx = tuple( [int(a.value) for a in self.newdir_index[:n]] ) if not np.array(idx).any(): oops(_("At least one index must be non-zero")) return if n == 4 and np.array(idx)[:3].sum() != 0: oops(_("Invalid hexagonal indices", "The sum of the first three numbers must be zero")) return adj1 = gtk.Adjustment(self.newdir_layers.value, -100, 100, 1) adj2 = gtk.Adjustment(self.newdir_esurf.value, -1000.0, 1000.0, 0.1) adj1.connect("value-changed", self.update) adj2.connect("value-changed", self.update) self.direction_table.append([idx, adj1, adj2]) self.update_direction_table() def row_delete(self, widget, row): del self.direction_table[row] self.update_direction_table() def row_swap_next(self, widget, row): dt = self.direction_table dt[row], dt[row+1] = dt[row+1], dt[row] self.update_direction_table() def update_gui_size(self, widget=None): "Update gui when the cluster size specification changes." self.size_n_spin.set_sensitive(self.size_n_radio.get_active()) self.size_dia_spin.set_sensitive(self.size_dia_radio.get_active()) def update_size_n(self, widget=None): if not self.size_n_radio.get_active(): return at_vol = self.get_atomic_volume() dia = 2.0 * (3 * self.size_n_adj.value * at_vol / (4 * np.pi))**(1.0/3) self.size_dia_adj.value = dia self.update() def update_size_dia(self, widget=None): if not self.size_dia_radio.get_active(): return at_vol = self.get_atomic_volume() n = round(np.pi / 6 * self.size_dia_adj.value**3 / at_vol) self.size_n_adj.value = n self.update() def update(self, *args): if self.no_update: return self.update_element() if self.auto.get_active(): self.makeatoms() if self.atoms is not None: self.gui.new_atoms(self.atoms) else: self.clearatoms() self.makeinfo() def set_structure_data(self, *args): "Called when the user presses [Get structure]." if not self.update_element(): oops(_("Invalid element.")) return z = ase.data.atomic_numbers[self.legal_element] ref = ase.data.reference_states[z] if ref is None: structure = None else: structure = ref['symmetry'] if ref is None or not structure in self.list_of_structures: oops(_("Unsupported or unknown structure", "Element = %s, structure = %s" % (self.legal_element, structure))) return for i, s in enumerate(self.list_of_structures): if structure == s: self.structure.set_active(i) a = ref['a'] self.lattice_const_a.set_value(a) self.fourindex = self.needs_4index[structure] if self.fourindex: try: c = ref['c'] except KeyError: c = ref['c/a'] * a self.lattice_const_c.set_value(c) self.lattice_label_c.show() self.lattice_box_c.show() else: self.lattice_label_c.hide() self.lattice_box_c.hide() def makeatoms(self, *args): "Make the atoms according to the current specification." if not self.update_element(): self.clearatoms() self.makeinfo() return False assert self.legal_element is not None struct = self.list_of_structures[self.structure.get_active()] if self.needs_2lat[struct]: # a and c lattice constants lc = {'a': self.lattice_const_a.value, 'c': self.lattice_const_c.value} lc_str = str(lc) else: lc = self.lattice_const_a.value lc_str = "%.5f" % (lc,) if self.method.get_active() == 0: # Layer-by-layer specification surfaces = [x[0] for x in self.direction_table] layers = [int(x[1].value) for x in self.direction_table] self.atoms = self.factory[struct](self.legal_element, copy(surfaces), layers, latticeconstant=lc) imp = self.import_names[struct] self.pybut.python = py_template_layers % {'import': imp, 'element': self.legal_element, 'surfaces': str(surfaces), 'layers': str(layers), 'latconst': lc_str, 'factory': imp.split()[-1] } else: # Wulff construction assert self.method.get_active() == 1 surfaces = [x[0] for x in self.direction_table] surfaceenergies = [x[2].value for x in self.direction_table] self.update_size_dia() if self.round_above.get_active(): rounding = "above" elif self.round_below.get_active(): rounding = "below" elif self.round_closest.get_active(): rounding = "closest" else: raise RuntimeError("No rounding!") self.atoms = wulff_construction(self.legal_element, surfaces, surfaceenergies, self.size_n_adj.value, self.factory[struct], rounding, lc) self.pybut.python = py_template_wulff % {'element': self.legal_element, 'surfaces': str(surfaces), 'energies': str(surfaceenergies), 'latconst': lc_str, 'natoms': self.size_n_adj.value, 'structure': struct, 'rounding': rounding } self.makeinfo() def clearatoms(self): self.atoms = None self.pybut.python = None def get_atomic_volume(self): s = self.list_of_structures[self.structure.get_active()] a = self.lattice_const_a.value c = self.lattice_const_c.value if s == 'fcc': return a**3 / 4 elif s == 'bcc': return a**3 / 2 elif s == 'sc': return a**3 elif s == 'hcp': return np.sqrt(3.0)/2 * a * a * c / 2 elif s == 'graphite': return np.sqrt(3.0)/2 * a * a * c / 4 else: raise RuntimeError("Unknown structure: "+s) def makeinfo(self): """Fill in information field about the atoms. Also turns the Wulff construction buttons [Larger] and [Smaller] on and off. """ if self.atoms is None: self.natoms_label.set_label("-") self.dia1_label.set_label("-") self.smaller_button.set_sensitive(False) self.larger_button.set_sensitive(False) else: self.natoms_label.set_label(str(len(self.atoms))) at_vol = self.get_atomic_volume() dia = 2 * (3 * len(self.atoms) * at_vol / (4 * np.pi))**(1.0/3.0) self.dia1_label.set_label(_(u"%.1f Å") % (dia,)) self.smaller_button.set_sensitive(True) self.larger_button.set_sensitive(True) def apply(self, *args): self.makeatoms() if self.atoms is not None: self.gui.new_atoms(self.atoms) return True else: oops(_("No valid atoms."), _("You have not (yet) specified a consistent set of " "parameters.")) return False def ok(self, *args): if self.apply(): self.destroy()
def __init__(self, gui): SetupWindow.__init__(self) self.set_title(_("Nanoparticle")) self.atoms = None self.no_update = True vbox = gtk.VBox() # Intoductory text self.packtext(vbox, introtext) # Choose the element label = gtk.Label(_("Element: ")) label.set_alignment(0.0, 0.2) element = gtk.Entry(max=3) self.element = element lattice_button = gtk.Button(_("Get structure")) lattice_button.connect('clicked', self.set_structure_data) self.elementinfo = gtk.Label(" ") pack(vbox, [label, element, self.elementinfo, lattice_button], end=True) self.element.connect('activate', self.update) self.legal_element = False # The structure and lattice constant label = gtk.Label(_("Structure: ")) self.structure = gtk.combo_box_new_text() self.list_of_structures = [] self.needs_4index = {} self.needs_2lat = {} self.factory = {} for abbrev, name, n4, c, factory in self.structure_data: self.structure.append_text(name) self.list_of_structures.append(abbrev) self.needs_4index[abbrev] = n4 self.needs_2lat[abbrev] = c self.factory[abbrev] = factory self.structure.set_active(0) self.fourindex = self.needs_4index[self.list_of_structures[0]] self.structure.connect('changed', self.update_structure) label2 = gtk.Label(_("Lattice constant: a =")) self.lattice_const_a = gtk.Adjustment(3.0, 0.0, 1000.0, 0.01) self.lattice_const_c = gtk.Adjustment(5.0, 0.0, 1000.0, 0.01) self.lattice_box_a = gtk.SpinButton(self.lattice_const_a, 10.0, 3) self.lattice_box_c = gtk.SpinButton(self.lattice_const_c, 10.0, 3) self.lattice_box_a.numeric = True self.lattice_box_c.numeric = True self.lattice_label_c = gtk.Label(" c =") pack(vbox, [label, self.structure]) pack(vbox, [label2, self.lattice_box_a, self.lattice_label_c, self.lattice_box_c]) self.lattice_label_c.hide() self.lattice_box_c.hide() self.lattice_const_a.connect('value-changed', self.update) self.lattice_const_c.connect('value-changed', self.update) # Choose specification method label = gtk.Label(_("Method: ")) self.method = gtk.combo_box_new_text() for meth in (_("Layer specification"), _("Wulff construction")): self.method.append_text(meth) self.method.set_active(0) self.method.connect('changed', self.update_gui_method) pack(vbox, [label, self.method]) pack(vbox, gtk.Label("")) self.old_structure = None frame = gtk.Frame() pack(vbox, frame) framebox = gtk.VBox() frame.add(framebox) framebox.show() self.layerlabel = gtk.Label("Missing text") # Filled in later pack(framebox, [self.layerlabel]) # This box will contain a single table that is replaced when # the list of directions is changed. self.direction_table_box = gtk.VBox() pack(framebox, self.direction_table_box) pack(self.direction_table_box, gtk.Label(_("Dummy placeholder object"))) pack(framebox, gtk.Label("")) pack(framebox, [gtk.Label(_("Add new direction:"))]) self.newdir_label = [] self.newdir_box = [] self.newdir_index = [] packlist = [] for txt in ('(', ', ', ', ', ', '): self.newdir_label.append(gtk.Label(txt)) adj = gtk.Adjustment(0, -100, 100, 1) self.newdir_box.append(gtk.SpinButton(adj, 1, 0)) self.newdir_index.append(adj) packlist.append(self.newdir_label[-1]) packlist.append(self.newdir_box[-1]) self.newdir_layers = gtk.Adjustment(5, 0, 100, 1) self.newdir_layers_box = gtk.SpinButton(self.newdir_layers, 1, 0) self.newdir_esurf = gtk.Adjustment(1.0, 0, 1000.0, 0.1) self.newdir_esurf_box = gtk.SpinButton(self.newdir_esurf, 10, 3) addbutton = gtk.Button(_("Add")) addbutton.connect('clicked', self.row_add) packlist.extend([gtk.Label("): "), self.newdir_layers_box, self.newdir_esurf_box, gtk.Label(" "), addbutton]) pack(framebox, packlist) self.defaultbutton = gtk.Button(_("Set all directions to default " "values")) self.defaultbutton.connect('clicked', self.default_direction_table) self.default_direction_table() # Extra widgets for the Wulff construction self.wulffbox = gtk.VBox() pack(vbox, self.wulffbox) label = gtk.Label(_("Particle size: ")) self.size_n_radio = gtk.RadioButton(None, _("Number of atoms: ")) self.size_n_radio.set_active(True) self.size_n_adj = gtk.Adjustment(100, 1, 100000, 1) self.size_n_spin = gtk.SpinButton(self.size_n_adj, 0, 0) self.size_dia_radio = gtk.RadioButton(self.size_n_radio, _("Volume: ")) self.size_dia_adj = gtk.Adjustment(1.0, 0, 100.0, 0.1) self.size_dia_spin = gtk.SpinButton(self.size_dia_adj, 10.0, 2) pack(self.wulffbox, [label, self.size_n_radio, self.size_n_spin, gtk.Label(" "), self.size_dia_radio, self.size_dia_spin, gtk.Label(_(u"ų"))]) self.size_n_radio.connect("toggled", self.update_gui_size) self.size_dia_radio.connect("toggled", self.update_gui_size) self.size_n_adj.connect("value-changed", self.update_size_n) self.size_dia_adj.connect("value-changed", self.update_size_dia) label = gtk.Label(_("Rounding: If exact size is not possible, " "choose the size")) pack(self.wulffbox, [label]) self.round_above = gtk.RadioButton(None, _("above ")) self.round_below = gtk.RadioButton(self.round_above, _("below ")) self.round_closest = gtk.RadioButton(self.round_above, _("closest ")) self.round_closest.set_active(True) butbox = gtk.HButtonBox() self.smaller_button = gtk.Button(_("Smaller")) self.larger_button = gtk.Button(_("Larger")) self.smaller_button.connect('clicked', self.wulff_smaller) self.larger_button.connect('clicked', self.wulff_larger) pack(butbox, [self.smaller_button, self.larger_button]) buts = [self.round_above, self.round_below, self.round_closest] for b in buts: b.connect("toggled", self.update) buts.append(butbox) pack(self.wulffbox, buts, end=True) # Information pack(vbox, gtk.Label("")) infobox = gtk.VBox() label1 = gtk.Label(_("Number of atoms: ")) self.natoms_label = gtk.Label("-") label2 = gtk.Label(_(" Approx. diameter: ")) self.dia1_label = gtk.Label("-") pack(infobox, [label1, self.natoms_label, label2, self.dia1_label]) pack(infobox, gtk.Label("")) infoframe = gtk.Frame(_("Information about the created cluster:")) infoframe.add(infobox) infobox.show() pack(vbox, infoframe) # Buttons self.pybut = PyButton(_("Creating a nanoparticle.")) self.pybut.connect('clicked', self.makeatoms) helpbut = help(helptext) buts = cancel_apply_ok(cancel=lambda widget: self.destroy(), apply=self.apply, ok=self.ok) pack(vbox, [self.pybut, helpbut, buts], end=True, bottom=True) self.auto = gtk.CheckButton(_("Automatic Apply")) fr = gtk.Frame() fr.add(self.auto) fr.show_all() pack(vbox, [fr], end=True, bottom=True) # Finalize setup self.update_structure() self.update_gui_method() self.add(vbox) vbox.show() self.show() self.gui = gui self.no_update = False
def __init__(self, gui): SetupWindow.__init__(self) self.set_title("Nanoparticle") self.atoms = None self.no_update = True vbox = gtk.VBox() # Intoductory text self.packtext(vbox, introtext) # Choose the element label = gtk.Label("Element: ") label.set_alignment(0.0, 0.2) element = gtk.Entry(max=3) self.element = element lattice_button = gtk.Button("Get structure") lattice_button.connect('clicked', self.set_structure_data) self.elementinfo = gtk.Label(" ") pack(vbox, [label, element, self.elementinfo, lattice_button], end=True) self.element.connect('activate', self.update) self.legal_element = False # The structure and lattice constant label = gtk.Label("Structure: ") self.structure = gtk.combo_box_new_text() self.list_of_structures = [] self.needs_4index = {} self.needs_2lat = {} self.factory = {} for abbrev, name, n4, c, factory in self.structure_data: self.structure.append_text(name) self.list_of_structures.append(abbrev) self.needs_4index[abbrev] = n4 self.needs_2lat[abbrev] = c self.factory[abbrev] = factory self.structure.set_active(0) self.fourindex = self.needs_4index[self.list_of_structures[0]] self.structure.connect('changed', self.update_structure) label2 = gtk.Label("Lattice constant: a =") self.lattice_const_a = gtk.Adjustment(3.0, 0.0, 1000.0, 0.01) self.lattice_const_c = gtk.Adjustment(5.0, 0.0, 1000.0, 0.01) self.lattice_box_a = gtk.SpinButton(self.lattice_const_a, 10.0, 3) self.lattice_box_c = gtk.SpinButton(self.lattice_const_c, 10.0, 3) self.lattice_box_a.numeric = True self.lattice_box_c.numeric = True self.lattice_label_c = gtk.Label(" c =") pack(vbox, [label, self.structure]) pack(vbox, [ label2, self.lattice_box_a, self.lattice_label_c, self.lattice_box_c ]) self.lattice_label_c.hide() self.lattice_box_c.hide() self.lattice_const_a.connect('value-changed', self.update) self.lattice_const_c.connect('value-changed', self.update) # Choose specification method label = gtk.Label("Method: ") self.method = gtk.combo_box_new_text() for meth in ("Layer specification", "Wulff construction"): self.method.append_text(meth) self.method.set_active(0) self.method.connect('changed', self.update_gui_method) pack(vbox, [label, self.method]) pack(vbox, gtk.Label("")) self.old_structure = None frame = gtk.Frame() pack(vbox, frame) framebox = gtk.VBox() frame.add(framebox) framebox.show() self.layerlabel = gtk.Label("Missing text") # Filled in later pack(framebox, [self.layerlabel]) # This box will contain a single table that is replaced when # the list of directions is changed. self.direction_table_box = gtk.VBox() pack(framebox, self.direction_table_box) pack(self.direction_table_box, gtk.Label("Dummy placeholder object")) pack(framebox, gtk.Label("")) pack(framebox, [gtk.Label("Add new direction:")]) self.newdir_label = [] self.newdir_box = [] self.newdir_index = [] packlist = [] for txt in ('(', ', ', ', ', ', '): self.newdir_label.append(gtk.Label(txt)) adj = gtk.Adjustment(0, -100, 100, 1) self.newdir_box.append(gtk.SpinButton(adj, 1, 0)) self.newdir_index.append(adj) packlist.append(self.newdir_label[-1]) packlist.append(self.newdir_box[-1]) self.newdir_layers = gtk.Adjustment(5, 0, 100, 1) self.newdir_layers_box = gtk.SpinButton(self.newdir_layers, 1, 0) self.newdir_esurf = gtk.Adjustment(1.0, 0, 1000.0, 0.1) self.newdir_esurf_box = gtk.SpinButton(self.newdir_esurf, 10, 3) addbutton = gtk.Button("Add") addbutton.connect('clicked', self.row_add) packlist.extend([ gtk.Label("): "), self.newdir_layers_box, self.newdir_esurf_box, gtk.Label(" "), addbutton ]) pack(framebox, packlist) self.defaultbutton = gtk.Button("Set all directions to default values") self.defaultbutton.connect('clicked', self.default_direction_table) self.default_direction_table() # Extra widgets for the Wulff construction self.wulffbox = gtk.VBox() pack(vbox, self.wulffbox) label = gtk.Label("Particle size: ") self.size_n_radio = gtk.RadioButton(None, "Number of atoms: ") self.size_n_radio.set_active(True) self.size_n_adj = gtk.Adjustment(100, 1, 100000, 1) self.size_n_spin = gtk.SpinButton(self.size_n_adj, 0, 0) self.size_dia_radio = gtk.RadioButton(self.size_n_radio, "Volume: ") self.size_dia_adj = gtk.Adjustment(1.0, 0, 100.0, 0.1) self.size_dia_spin = gtk.SpinButton(self.size_dia_adj, 10.0, 2) pack(self.wulffbox, [ label, self.size_n_radio, self.size_n_spin, gtk.Label(" "), self.size_dia_radio, self.size_dia_spin, gtk.Label("ų") ]) self.size_n_radio.connect("toggled", self.update_gui_size) self.size_dia_radio.connect("toggled", self.update_gui_size) self.size_n_adj.connect("value-changed", self.update_size_n) self.size_dia_adj.connect("value-changed", self.update_size_dia) label = gtk.Label( "Rounding: If exact size is not possible, choose the size") pack(self.wulffbox, [label]) self.round_above = gtk.RadioButton(None, "above ") self.round_below = gtk.RadioButton(self.round_above, "below ") self.round_closest = gtk.RadioButton(self.round_above, "closest ") self.round_closest.set_active(True) butbox = gtk.HButtonBox() self.smaller_button = gtk.Button("Smaller") self.larger_button = gtk.Button("Larger") self.smaller_button.connect('clicked', self.wulff_smaller) self.larger_button.connect('clicked', self.wulff_larger) pack(butbox, [self.smaller_button, self.larger_button]) buts = [self.round_above, self.round_below, self.round_closest] for b in buts: b.connect("toggled", self.update) buts.append(butbox) pack(self.wulffbox, buts, end=True) # Information pack(vbox, gtk.Label("")) infobox = gtk.VBox() label1 = gtk.Label("Number of atoms: ") self.natoms_label = gtk.Label("-") label2 = gtk.Label(" Approx. diameter: ") self.dia1_label = gtk.Label("-") pack(infobox, [label1, self.natoms_label, label2, self.dia1_label]) pack(infobox, gtk.Label("")) infoframe = gtk.Frame("Information about the created cluster:") infoframe.add(infobox) infobox.show() pack(vbox, infoframe) # Buttons self.pybut = PyButton("Creating a nanoparticle.") self.pybut.connect('clicked', self.makeatoms) helpbut = help(helptext) buts = cancel_apply_ok(cancel=lambda widget: self.destroy(), apply=self.apply, ok=self.ok) pack(vbox, [self.pybut, helpbut, buts], end=True, bottom=True) self.auto = gtk.CheckButton("Automatic Apply") fr = gtk.Frame() fr.add(self.auto) fr.show_all() pack(vbox, [fr], end=True, bottom=True) # Finalize setup self.update_structure() self.update_gui_method() self.add(vbox) vbox.show() self.show() self.gui = gui self.no_update = False
class SetupNanoparticle(SetupWindow): "Window for setting up a nanoparticle." # Structures: Abbreviation, name, 4-index (boolean), two lattice const (bool), factory structure_data = ( ('fcc', 'Face centered cubic (fcc)', False, False, FaceCenteredCubic), ('bcc', 'Body centered cubic (bcc)', False, False, BodyCenteredCubic), ('sc', 'Simple cubic (sc)', False, False, SimpleCubic), ('hcp', 'Hexagonal closed-packed (hcp)', True, True, HexagonalClosedPacked), ('graphite', 'Graphite', True, True, Graphite), ) #NB: HCP is broken! # A list of import statements for the Python window. import_names = { 'fcc': 'from ase.cluster.cubic import FaceCenteredCubic', 'bcc': 'from ase.cluster.cubic import BodyCenteredCubic', 'sc': 'from ase.cluster.cubic import SimpleCubic', 'hcp': 'from ase.cluster.hexagonal import HexagonalClosedPacked', 'graphite': 'from ase.cluster.hexagonal import Graphite', } # Default layer specifications for the different structures. default_layers = { 'fcc': [((1, 0, 0), 6), ((1, 1, 0), 9), ((1, 1, 1), 5)], 'bcc': [((1, 0, 0), 6), ((1, 1, 0), 9), ((1, 1, 1), 5)], 'sc': [((1, 0, 0), 6), ((1, 1, 0), 9), ((1, 1, 1), 5)], 'hcp': [((0, 0, 0, 1), 5), ((1, 0, -1, 0), 5)], 'graphite': [((0, 0, 0, 1), 5), ((1, 0, -1, 0), 5)] } def __init__(self, gui): SetupWindow.__init__(self) self.set_title("Nanoparticle") self.atoms = None self.no_update = True vbox = gtk.VBox() # Intoductory text self.packtext(vbox, introtext) # Choose the element label = gtk.Label("Element: ") label.set_alignment(0.0, 0.2) element = gtk.Entry(max=3) self.element = element lattice_button = gtk.Button("Get structure") lattice_button.connect('clicked', self.set_structure_data) self.elementinfo = gtk.Label(" ") pack(vbox, [label, element, self.elementinfo, lattice_button], end=True) self.element.connect('activate', self.update) self.legal_element = False # The structure and lattice constant label = gtk.Label("Structure: ") self.structure = gtk.combo_box_new_text() self.list_of_structures = [] self.needs_4index = {} self.needs_2lat = {} self.factory = {} for abbrev, name, n4, c, factory in self.structure_data: self.structure.append_text(name) self.list_of_structures.append(abbrev) self.needs_4index[abbrev] = n4 self.needs_2lat[abbrev] = c self.factory[abbrev] = factory self.structure.set_active(0) self.fourindex = self.needs_4index[self.list_of_structures[0]] self.structure.connect('changed', self.update_structure) label2 = gtk.Label("Lattice constant: a =") self.lattice_const_a = gtk.Adjustment(3.0, 0.0, 1000.0, 0.01) self.lattice_const_c = gtk.Adjustment(5.0, 0.0, 1000.0, 0.01) self.lattice_box_a = gtk.SpinButton(self.lattice_const_a, 10.0, 3) self.lattice_box_c = gtk.SpinButton(self.lattice_const_c, 10.0, 3) self.lattice_box_a.numeric = True self.lattice_box_c.numeric = True self.lattice_label_c = gtk.Label(" c =") pack(vbox, [label, self.structure]) pack(vbox, [ label2, self.lattice_box_a, self.lattice_label_c, self.lattice_box_c ]) self.lattice_label_c.hide() self.lattice_box_c.hide() self.lattice_const_a.connect('value-changed', self.update) self.lattice_const_c.connect('value-changed', self.update) # Choose specification method label = gtk.Label("Method: ") self.method = gtk.combo_box_new_text() for meth in ("Layer specification", "Wulff construction"): self.method.append_text(meth) self.method.set_active(0) self.method.connect('changed', self.update_gui_method) pack(vbox, [label, self.method]) pack(vbox, gtk.Label("")) self.old_structure = None frame = gtk.Frame() pack(vbox, frame) framebox = gtk.VBox() frame.add(framebox) framebox.show() self.layerlabel = gtk.Label("Missing text") # Filled in later pack(framebox, [self.layerlabel]) # This box will contain a single table that is replaced when # the list of directions is changed. self.direction_table_box = gtk.VBox() pack(framebox, self.direction_table_box) pack(self.direction_table_box, gtk.Label("Dummy placeholder object")) pack(framebox, gtk.Label("")) pack(framebox, [gtk.Label("Add new direction:")]) self.newdir_label = [] self.newdir_box = [] self.newdir_index = [] packlist = [] for txt in ('(', ', ', ', ', ', '): self.newdir_label.append(gtk.Label(txt)) adj = gtk.Adjustment(0, -100, 100, 1) self.newdir_box.append(gtk.SpinButton(adj, 1, 0)) self.newdir_index.append(adj) packlist.append(self.newdir_label[-1]) packlist.append(self.newdir_box[-1]) self.newdir_layers = gtk.Adjustment(5, 0, 100, 1) self.newdir_layers_box = gtk.SpinButton(self.newdir_layers, 1, 0) self.newdir_esurf = gtk.Adjustment(1.0, 0, 1000.0, 0.1) self.newdir_esurf_box = gtk.SpinButton(self.newdir_esurf, 10, 3) addbutton = gtk.Button("Add") addbutton.connect('clicked', self.row_add) packlist.extend([ gtk.Label("): "), self.newdir_layers_box, self.newdir_esurf_box, gtk.Label(" "), addbutton ]) pack(framebox, packlist) self.defaultbutton = gtk.Button("Set all directions to default values") self.defaultbutton.connect('clicked', self.default_direction_table) self.default_direction_table() # Extra widgets for the Wulff construction self.wulffbox = gtk.VBox() pack(vbox, self.wulffbox) label = gtk.Label("Particle size: ") self.size_n_radio = gtk.RadioButton(None, "Number of atoms: ") self.size_n_radio.set_active(True) self.size_n_adj = gtk.Adjustment(100, 1, 100000, 1) self.size_n_spin = gtk.SpinButton(self.size_n_adj, 0, 0) self.size_dia_radio = gtk.RadioButton(self.size_n_radio, "Volume: ") self.size_dia_adj = gtk.Adjustment(1.0, 0, 100.0, 0.1) self.size_dia_spin = gtk.SpinButton(self.size_dia_adj, 10.0, 2) pack(self.wulffbox, [ label, self.size_n_radio, self.size_n_spin, gtk.Label(" "), self.size_dia_radio, self.size_dia_spin, gtk.Label("ų") ]) self.size_n_radio.connect("toggled", self.update_gui_size) self.size_dia_radio.connect("toggled", self.update_gui_size) self.size_n_adj.connect("value-changed", self.update_size_n) self.size_dia_adj.connect("value-changed", self.update_size_dia) label = gtk.Label( "Rounding: If exact size is not possible, choose the size") pack(self.wulffbox, [label]) self.round_above = gtk.RadioButton(None, "above ") self.round_below = gtk.RadioButton(self.round_above, "below ") self.round_closest = gtk.RadioButton(self.round_above, "closest ") self.round_closest.set_active(True) butbox = gtk.HButtonBox() self.smaller_button = gtk.Button("Smaller") self.larger_button = gtk.Button("Larger") self.smaller_button.connect('clicked', self.wulff_smaller) self.larger_button.connect('clicked', self.wulff_larger) pack(butbox, [self.smaller_button, self.larger_button]) buts = [self.round_above, self.round_below, self.round_closest] for b in buts: b.connect("toggled", self.update) buts.append(butbox) pack(self.wulffbox, buts, end=True) # Information pack(vbox, gtk.Label("")) infobox = gtk.VBox() label1 = gtk.Label("Number of atoms: ") self.natoms_label = gtk.Label("-") label2 = gtk.Label(" Approx. diameter: ") self.dia1_label = gtk.Label("-") pack(infobox, [label1, self.natoms_label, label2, self.dia1_label]) pack(infobox, gtk.Label("")) infoframe = gtk.Frame("Information about the created cluster:") infoframe.add(infobox) infobox.show() pack(vbox, infoframe) # Buttons self.pybut = PyButton("Creating a nanoparticle.") self.pybut.connect('clicked', self.makeatoms) helpbut = help(helptext) buts = cancel_apply_ok(cancel=lambda widget: self.destroy(), apply=self.apply, ok=self.ok) pack(vbox, [self.pybut, helpbut, buts], end=True, bottom=True) self.auto = gtk.CheckButton("Automatic Apply") fr = gtk.Frame() fr.add(self.auto) fr.show_all() pack(vbox, [fr], end=True, bottom=True) # Finalize setup self.update_structure() self.update_gui_method() self.add(vbox) vbox.show() self.show() self.gui = gui self.no_update = False def default_direction_table(self, widget=None): "Set default directions and values for the current crystal structure." self.direction_table = [] struct = self.get_structure() for direction, layers in self.default_layers[struct]: adj1 = gtk.Adjustment(layers, -100, 100, 1) adj2 = gtk.Adjustment(1.0, -1000.0, 1000.0, 0.1) adj1.connect("value-changed", self.update) adj2.connect("value-changed", self.update) self.direction_table.append([direction, adj1, adj2]) self.update_direction_table() def update_direction_table(self): "Update the part of the GUI containing the table of directions." #Discard old table oldwidgets = self.direction_table_box.get_children() assert len(oldwidgets) == 1 oldwidgets[0].hide() self.direction_table_box.remove(oldwidgets[0]) del oldwidgets # It should now be gone tbl = gtk.Table(len(self.direction_table) + 1, 7) pack(self.direction_table_box, [tbl]) for i, data in enumerate(self.direction_table): tbl.attach(gtk.Label("%s: " % (str(data[0]), )), 0, 1, i, i + 1) if self.method.get_active(): # Wulff construction spin = gtk.SpinButton(data[2], 1.0, 3) else: # Layers spin = gtk.SpinButton(data[1], 1, 0) tbl.attach(spin, 1, 2, i, i + 1) tbl.attach(gtk.Label(" "), 2, 3, i, i + 1) but = gtk.Button("Up") but.connect("clicked", self.row_swap_next, i - 1) if i == 0: but.set_sensitive(False) tbl.attach(but, 3, 4, i, i + 1) but = gtk.Button("Down") but.connect("clicked", self.row_swap_next, i) if i == len(self.direction_table) - 1: but.set_sensitive(False) tbl.attach(but, 4, 5, i, i + 1) but = gtk.Button("Delete") but.connect("clicked", self.row_delete, i) if len(self.direction_table) == 1: but.set_sensitive(False) tbl.attach(but, 5, 6, i, i + 1) tbl.show_all() self.update() def get_structure(self): "Returns the crystal structure chosen by the user." return self.list_of_structures[self.structure.get_active()] def update_structure(self, widget=None): "Called when the user changes the structure." s = self.get_structure() if s != self.old_structure: old4 = self.fourindex self.fourindex = self.needs_4index[s] if self.fourindex != old4: # The table of directions is invalid. self.default_direction_table() self.old_structure = s if self.needs_2lat[s]: self.lattice_label_c.show() self.lattice_box_c.show() else: self.lattice_label_c.hide() self.lattice_box_c.hide() if self.fourindex: self.newdir_label[3].show() self.newdir_box[3].show() else: self.newdir_label[3].hide() self.newdir_box[3].hide() self.update() def update_gui_method(self, widget=None): "Switch between layer specification and Wulff construction." self.update_direction_table() if self.method.get_active(): self.wulffbox.show() self.layerlabel.set_text( "Surface energies (as energy/area, NOT per atom):") self.newdir_layers_box.hide() self.newdir_esurf_box.show() else: self.wulffbox.hide() self.layerlabel.set_text("Number of layers:") self.newdir_layers_box.show() self.newdir_esurf_box.hide() self.update() def wulff_smaller(self, widget=None): "Make a smaller Wulff construction." n = len(self.atoms) self.size_n_radio.set_active(True) self.size_n_adj.value = n - 1 self.round_below.set_active(True) self.apply() def wulff_larger(self, widget=None): "Make a larger Wulff construction." n = len(self.atoms) self.size_n_radio.set_active(True) self.size_n_adj.value = n + 1 self.round_above.set_active(True) self.apply() def row_add(self, widget=None): "Add a row to the list of directions." if self.fourindex: n = 4 else: n = 3 idx = tuple([int(a.value) for a in self.newdir_index[:n]]) if not np.array(idx).any(): oops("At least one index must be non-zero") return if n == 4 and np.array(idx)[:3].sum() != 0: oops("Invalid hexagonal indices", "The sum of the first three numbers must be zero") return adj1 = gtk.Adjustment(self.newdir_layers.value, -100, 100, 1) adj2 = gtk.Adjustment(self.newdir_esurf.value, -1000.0, 1000.0, 0.1) adj1.connect("value-changed", self.update) adj2.connect("value-changed", self.update) self.direction_table.append([idx, adj1, adj2]) self.update_direction_table() def row_delete(self, widget, row): del self.direction_table[row] self.update_direction_table() def row_swap_next(self, widget, row): dt = self.direction_table dt[row], dt[row + 1] = dt[row + 1], dt[row] self.update_direction_table() def update_gui_size(self, widget=None): "Update gui when the cluster size specification changes." self.size_n_spin.set_sensitive(self.size_n_radio.get_active()) self.size_dia_spin.set_sensitive(self.size_dia_radio.get_active()) def update_size_n(self, widget=None): if not self.size_n_radio.get_active(): return at_vol = self.get_atomic_volume() dia = 2.0 * (3 * self.size_n_adj.value * at_vol / (4 * np.pi))**(1.0 / 3) self.size_dia_adj.value = dia self.update() def update_size_dia(self, widget=None): if not self.size_dia_radio.get_active(): return at_vol = self.get_atomic_volume() n = round(np.pi / 6 * self.size_dia_adj.value**3 / at_vol) self.size_n_adj.value = n self.update() def update(self, *args): if self.no_update: return self.update_element() if self.auto.get_active(): self.makeatoms() if self.atoms is not None: self.gui.new_atoms(self.atoms) else: self.clearatoms() self.makeinfo() def set_structure_data(self, *args): "Called when the user presses [Get structure]." if not self.update_element(): oops("Invalid element.") return z = ase.atomic_numbers[self.legal_element] ref = ase.data.reference_states[z] if ref is None: structure = None else: structure = ref['symmetry'].lower() if ref is None or not structure in self.list_of_structures: oops( "Unsupported or unknown structure", "Element = %s, structure = %s" % (self.legal_element, structure)) return for i, s in enumerate(self.list_of_structures): if structure == s: self.structure.set_active(i) a = ref['a'] self.lattice_const_a.set_value(a) self.fourindex = self.needs_4index[structure] if self.fourindex: try: c = ref['c'] except KeyError: c = ref['c/a'] * a self.lattice_const_c.set_value(c) self.lattice_label_c.show() self.lattice_box_c.show() else: self.lattice_label_c.hide() self.lattice_box_c.hide() def makeatoms(self, *args): "Make the atoms according to the current specification." if not self.update_element(): self.clearatoms() self.makeinfo() return False assert self.legal_element is not None struct = self.list_of_structures[self.structure.get_active()] if self.needs_2lat[struct]: # a and c lattice constants lc = { 'a': self.lattice_const_a.value, 'c': self.lattice_const_c.value } lc_str = str(lc) else: lc = self.lattice_const_a.value lc_str = "%.5f" % (lc, ) if self.method.get_active() == 0: # Layer-by-layer specification surfaces = [x[0] for x in self.direction_table] layers = [int(x[1].value) for x in self.direction_table] self.atoms = self.factory[struct](self.legal_element, copy(surfaces), layers, latticeconstant=lc) imp = self.import_names[struct] self.pybut.python = py_template_layers % { 'import': imp, 'element': self.legal_element, 'surfaces': str(surfaces), 'layers': str(layers), 'latconst': lc_str, 'factory': imp.split()[-1] } else: # Wulff construction assert self.method.get_active() == 1 surfaces = [x[0] for x in self.direction_table] surfaceenergies = [x[2].value for x in self.direction_table] self.update_size_dia() if self.round_above.get_active(): rounding = "above" elif self.round_below.get_active(): rounding = "below" elif self.round_closest.get_active(): rounding = "closest" else: raise RuntimeError("No rounding!") self.atoms = wulff_construction(self.legal_element, surfaces, surfaceenergies, self.size_n_adj.value, self.factory[struct], rounding, lc) self.pybut.python = py_template_wulff % { 'element': self.legal_element, 'surfaces': str(surfaces), 'energies': str(surfaceenergies), 'latconst': lc_str, 'natoms': self.size_n_adj.value, 'structure': struct, 'rounding': rounding } self.makeinfo() def clearatoms(self): self.atoms = None self.pybut.python = None def get_atomic_volume(self): s = self.list_of_structures[self.structure.get_active()] a = self.lattice_const_a.value c = self.lattice_const_c.value if s == 'fcc': return a**3 / 4 elif s == 'bcc': return a**3 / 2 elif s == 'sc': return a**3 elif s == 'hcp': return np.sqrt(3.0) / 2 * a * a * c / 2 elif s == 'graphite': return np.sqrt(3.0) / 2 * a * a * c / 4 else: raise RuntimeError("Unknown structure: " + s) def makeinfo(self): """Fill in information field about the atoms. Also turns the Wulff construction buttons [Larger] and [Smaller] on and off. """ if self.atoms is None: self.natoms_label.set_label("-") self.dia1_label.set_label("-") self.smaller_button.set_sensitive(False) self.larger_button.set_sensitive(False) else: self.natoms_label.set_label(str(len(self.atoms))) at_vol = self.get_atomic_volume() dia = 2 * (3 * len(self.atoms) * at_vol / (4 * np.pi))**(1.0 / 3.0) self.dia1_label.set_label("%.1f Å" % (dia, )) self.smaller_button.set_sensitive(True) self.larger_button.set_sensitive(True) def apply(self, *args): self.makeatoms() if self.atoms is not None: self.gui.new_atoms(self.atoms) return True else: oops( "No valid atoms.", "You have not (yet) specified a consistent set of parameters.") return False def ok(self, *args): if self.apply(): self.destroy()
class SetupSurfaceSlab(SetupWindow): """Window for setting up a surface.""" def __init__(self, gui): SetupWindow.__init__(self) self.set_title(_("Surface")) self.atoms = None vbox = gtk.VBox() # Intoductory text self.packtext(vbox, introtext) # Choose the element label = gtk.Label(_("Element: ")) element = gtk.Entry(max=3) self.element = element self.elementinfo = gtk.Label("") pack(vbox, [label, element, self.elementinfo]) self.element.connect("activate", self.update) self.legal_element = False # Choose the surface structure label = gtk.Label(_("Structure: ")) self.structchoice = gtk.combo_box_new_text() self.surfinfo = {} for s in surfaces: assert len(s) == 5 self.structchoice.append_text(s[0]) self.surfinfo[s[0]] = s pack(vbox, [label, self.structchoice]) self.structchoice.connect("changed", self.update) # Choose the lattice constant tbl = gtk.Table(2, 3) label = gtk.Label(_("Lattice constant: ")) tbl.attach(label, 0, 1, 0, 1) vbox2 = gtk.VBox() # For the non-HCP stuff self.vbox_hcp = gtk.VBox() # For the HCP stuff. self.lattice_const = gtk.Adjustment(3.0, 0.0, 1000.0, 0.01) lattice_box = gtk.SpinButton(self.lattice_const, 10.0, 3) lattice_box.numeric = True pack(vbox2, [gtk.Label(_("a:")), lattice_box, gtk.Label(_("Å"))]) tbl.attach(vbox2, 1, 2, 0, 1) lattice_button = gtk.Button(_("Get from database")) tbl.attach(lattice_button, 2, 3, 0, 1) # HCP stuff self.hcp_ideal = (8.0 / 3) ** (1.0 / 3) self.lattice_const_c = gtk.Adjustment(self.lattice_const.value * self.hcp_ideal, 0.0, 1000.0, 0.01) lattice_box_c = gtk.SpinButton(self.lattice_const_c, 10.0, 3) lattice_box_c.numeric = True pack(self.vbox_hcp, [gtk.Label("c:"), lattice_box_c, gtk.Label("Å")]) self.hcp_c_over_a_format = "c/a: %.3f " + _("(%.1f %% of ideal)") self.hcp_c_over_a_label = gtk.Label(self.hcp_c_over_a_format % (self.hcp_ideal, 100.0)) pack(self.vbox_hcp, [self.hcp_c_over_a_label]) tbl.attach(self.vbox_hcp, 1, 2, 1, 2) tbl.show_all() pack(vbox, [tbl]) self.lattice_const.connect("value-changed", self.update) self.lattice_const_c.connect("value-changed", self.update) lattice_button.connect("clicked", self.get_lattice_const) pack(vbox, gtk.Label("")) # System size self.size = [gtk.Adjustment(1, 1, 100, 1) for i in range(3)] buttons = [gtk.SpinButton(s, 0, 0) for s in self.size] self.vacuum = gtk.Adjustment(10.0, 0, 100.0, 0.1) vacuum_box = gtk.SpinButton(self.vacuum, 0.0, 1) pack(vbox, [gtk.Label(_("Size: \tx: ")), buttons[0], gtk.Label(_(" unit cells"))]) pack(vbox, [gtk.Label(_("\t\ty: ")), buttons[1], gtk.Label(_(" unit cells"))]) pack( vbox, [ gtk.Label(_(" \t\tz: ")), buttons[2], gtk.Label(_(" layers, ")), vacuum_box, gtk.Label(_(" Å vacuum")), ], ) self.nosize = _("\t\tNo size information yet.") self.sizelabel = gtk.Label(self.nosize) pack(vbox, [self.sizelabel]) for s in self.size: s.connect("value-changed", self.update) self.vacuum.connect("value-changed", self.update) pack(vbox, gtk.Label("")) # Buttons self.pybut = PyButton(_("Creating a surface slab.")) self.pybut.connect("clicked", self.update) buts = cancel_apply_ok(cancel=lambda widget: self.destroy(), apply=self.apply, ok=self.ok) pack(vbox, [self.pybut, buts], end=True, bottom=True) self.add(vbox) vbox.show() self.show() self.gui = gui # Hide the HCP stuff to begin with. self.vbox_hcp.hide_all() # update_element inherited from SetupWindow def update(self, *args): "Called when something has changed." struct = self.structchoice.get_active_text() if struct: structinfo = self.surfinfo[struct] if structinfo[1] == "hcp": self.vbox_hcp.show_all() ca = self.lattice_const_c.value / self.lattice_const.value self.hcp_c_over_a_label.set_text(self.hcp_c_over_a_format % (ca, 100 * ca / self.hcp_ideal)) else: self.vbox_hcp.hide_all() # Abort if element or structure is invalid if not (self.update_element() and struct): self.sizelabel.set_text(self.nosize) self.atoms = None self.pybut.python = None return False # Make the atoms assert self.legal_element kw = {} kw2 = {} if structinfo[3]: # Support othogonal keyword? kw["orthogonal"] = structinfo[2] kw2["orthoarg"] = ", orthogonal=" + str(kw["orthogonal"]) else: kw2["orthoarg"] = "" kw2["func"] = structinfo[4].__name__ kw["symbol"] = self.legal_element kw["size"] = [int(s.value) for s in self.size] kw["a"] = self.lattice_const.value kw["vacuum"] = self.vacuum.value # Now create the atoms try: self.atoms = structinfo[4](**kw) except ValueError, e: # The values were illegal - for example some size # constants must be even for some structures. self.pybut.python = None self.atoms = None self.sizelabel.set_text(str(e).replace(". ", ".\n")) return False kw2.update(kw) self.pybut.python = py_template % kw2 # Find the heights of the unit cell h = np.zeros(3) uc = self.atoms.get_cell() for i in range(3): norm = np.cross(uc[i - 1], uc[i - 2]) norm /= np.sqrt(np.dot(norm, norm)) h[i] = np.abs(np.dot(norm, uc[i])) natoms = len(self.atoms) txt = "\t\t%.2f Å x %.2f Å x %.2f Å, %s" % (h[0], h[1], h[2], _("%i atoms.") % natoms) self.sizelabel.set_text(txt) return True
class SetupSurfaceSlab(SetupWindow): """Window for setting up a surface.""" def __init__(self, gui): SetupWindow.__init__(self) self.set_title(_('Surface')) self.atoms = None vbox = gtk.VBox() # Intoductory text self.packtext(vbox, introtext) # Choose the element label = gtk.Label(_('Element: ')) element = gtk.Entry(max=3) self.element = element self.elementinfo = gtk.Label('') pack(vbox, [label, element, self.elementinfo]) self.element.connect('activate', self.update) self.legal_element = False # Choose the surface structure label = gtk.Label(_('Structure: ')) self.structchoice = gtk.combo_box_new_text() self.surfinfo = {} for s in surfaces: assert len(s) == 5 self.structchoice.append_text(s[0]) self.surfinfo[s[0]] = s pack(vbox, [label, self.structchoice]) self.structchoice.connect('changed', self.update) # Choose the lattice constant tbl = gtk.Table(2, 3) label = gtk.Label(_('Lattice constant: ')) tbl.attach(label, 0, 1, 0, 1) vbox2 = gtk.VBox() # For the non-HCP stuff self.vbox_hcp = gtk.VBox() # For the HCP stuff. self.lattice_const = gtk.Adjustment(3.0, 0.0, 1000.0, 0.01) lattice_box = gtk.SpinButton(self.lattice_const, 10.0, 3) lattice_box.numeric = True pack(vbox2, [gtk.Label(_('a:')), lattice_box, gtk.Label(_(u'Å'))]) tbl.attach(vbox2, 1, 2, 0, 1) lattice_button = gtk.Button(_('Get from database')) tbl.attach(lattice_button, 2, 3, 0, 1) # HCP stuff self.hcp_ideal = (8 / 3)**(1 / 3) self.lattice_const_c = gtk.Adjustment(self.lattice_const.value * self.hcp_ideal, 0.0, 1000.0, 0.01) lattice_box_c = gtk.SpinButton(self.lattice_const_c, 10.0, 3) lattice_box_c.numeric = True pack(self.vbox_hcp, [gtk.Label('c:'), lattice_box_c, gtk.Label(u'Å')]) self.hcp_c_over_a_format = 'c/a: %.3f ' + _('(%.1f %% of ideal)') self.hcp_c_over_a_label = gtk.Label(self.hcp_c_over_a_format % (self.hcp_ideal, 100.0)) pack(self.vbox_hcp, [self.hcp_c_over_a_label]) tbl.attach(self.vbox_hcp, 1, 2, 1, 2) tbl.show_all() pack(vbox, [tbl]) self.lattice_const.connect('value-changed', self.update) self.lattice_const_c.connect('value-changed', self.update) lattice_button.connect('clicked', self.get_lattice_const) pack(vbox, gtk.Label('')) # System size self.size = [gtk.Adjustment(1, 1, 100, 1) for i in range(3)] buttons = [gtk.SpinButton(s, 0, 0) for s in self.size] self.vacuum = gtk.Adjustment(10.0, 0, 100.0, 0.1) vacuum_box = gtk.SpinButton(self.vacuum, 0.0, 1) pack(vbox, [gtk.Label(_('Size: \tx: ')), buttons[0], gtk.Label(_(' unit cells'))]) pack(vbox, [gtk.Label(_('\t\ty: ')), buttons[1], gtk.Label(_(' unit cells'))]) pack(vbox, [gtk.Label(_(' \t\tz: ')), buttons[2], gtk.Label(_(' layers, ')), vacuum_box, gtk.Label(_(u' Å vacuum'))]) self.nosize = _('\t\tNo size information yet.') self.sizelabel = gtk.Label(self.nosize) pack(vbox, [self.sizelabel]) for s in self.size: s.connect('value-changed', self.update) self.vacuum.connect('value-changed', self.update) pack(vbox, gtk.Label('')) # Buttons self.pybut = PyButton(_('Creating a surface slab.')) self.pybut.connect('clicked', self.update) buts = cancel_apply_ok(cancel=lambda widget: self.destroy(), apply=self.apply, ok=self.ok) pack(vbox, [self.pybut, buts], end=True, bottom=True) self.add(vbox) vbox.show() self.show() self.gui = gui # Hide the HCP stuff to begin with. self.vbox_hcp.hide_all() # update_element inherited from SetupWindow def update(self, *args): "Called when something has changed." struct = self.structchoice.get_active_text() if struct: structinfo = self.surfinfo[struct] if structinfo[1] == 'hcp': self.vbox_hcp.show_all() ca = self.lattice_const_c.value / self.lattice_const.value self.hcp_c_over_a_label.set_text(self.hcp_c_over_a_format % (ca, 100 * ca / self.hcp_ideal)) else: self.vbox_hcp.hide_all() # Abort if element or structure is invalid if not (self.update_element() and struct): self.sizelabel.set_text(self.nosize) self.atoms = None self.pybut.python = None return False # Make the atoms assert self.legal_element kw = {} kw2 = {} if structinfo[3]: # Support othogonal keyword? kw['orthogonal'] = structinfo[2] kw2['orthoarg'] = ', orthogonal=' + str(kw['orthogonal']) else: kw2['orthoarg'] = '' kw2['func'] = structinfo[4].__name__ kw['symbol'] = self.legal_element kw['size'] = [int(s.value) for s in self.size] kw['a'] = self.lattice_const.value kw['vacuum'] = self.vacuum.value # Now create the atoms try: self.atoms = structinfo[4](**kw) except ValueError as e: # The values were illegal - for example some size # constants must be even for some structures. self.pybut.python = None self.atoms = None self.sizelabel.set_text(str(e).replace('. ', '.\n')) return False kw2.update(kw) self.pybut.python = py_template % kw2 # Find the heights of the unit cell h = np.zeros(3) uc = self.atoms.get_cell() for i in range(3): norm = np.cross(uc[i - 1], uc[i - 2]) norm /= np.sqrt(np.dot(norm, norm)) h[i] = np.abs(np.dot(norm, uc[i])) natoms = len(self.atoms) txt = ('\t\t%.2f Å x %.2f Å x %.2f Å, %s' % (h[0], h[1], h[2], _('%i atoms.') % natoms)) self.sizelabel.set_text(txt) return True def get_lattice_const(self, *args): if not self.update_element(): oops(_('Invalid element.')) return z = ase.data.atomic_numbers[self.legal_element] ref = ase.data.reference_states[z] surface = self.structchoice.get_active_text() if not surface: oops(_('No structure specified!')) return struct = self.surfinfo[surface][1] if ref is None or ref['symmetry'] != struct: from ase.data.alternatives import alternative_structures alt = alternative_structures[z] if alt and alt['symmetry'] == struct: ref = alt else: oops(_('%(struct)s lattice constant unknown for %(element)s.') % dict(struct=struct.upper(), element=self.legal_element)) a = ref['a'] self.lattice_const.set_value(a) if struct == 'hcp': c = ref['c/a'] * a self.lattice_const_c.set_value(c) def apply(self, *args): self.update() if self.atoms is not None: self.gui.new_atoms(self.atoms) return True else: oops(_('No valid atoms.'), _('You have not (yet) specified ' 'a consistent set of parameters.')) return False def ok(self, *args): if self.apply(): self.destroy()
class SetupSurfaceSlab(SetupWindow): """Window for setting up a surface.""" def __init__(self, gui): SetupWindow.__init__(self) self.set_title(_('Surface')) self.atoms = None vbox = gtk.VBox() # Intoductory text self.packtext(vbox, introtext) # Choose the element label = gtk.Label(_('Element: ')) element = gtk.Entry(max=3) self.element = element self.elementinfo = gtk.Label('') pack(vbox, [label, element, self.elementinfo]) self.element.connect('activate', self.update) self.legal_element = False # Choose the surface structure label = gtk.Label(_('Structure: ')) self.structchoice = gtk.combo_box_new_text() self.surfinfo = {} for s in surfaces: assert len(s) == 5 self.structchoice.append_text(s[0]) self.surfinfo[s[0]] = s pack(vbox, [label, self.structchoice]) self.structchoice.connect('changed', self.update) # Choose the lattice constant tbl = gtk.Table(2, 3) label = gtk.Label(_('Lattice constant: ')) tbl.attach(label, 0, 1, 0, 1) vbox2 = gtk.VBox() # For the non-HCP stuff self.vbox_hcp = gtk.VBox() # For the HCP stuff. self.lattice_const = gtk.Adjustment(3.0, 0.0, 1000.0, 0.01) lattice_box = gtk.SpinButton(self.lattice_const, 10.0, 3) lattice_box.numeric = True pack(vbox2, [gtk.Label(_('a:')), lattice_box, gtk.Label(_(u'Å'))]) tbl.attach(vbox2, 1, 2, 0, 1) lattice_button = gtk.Button(_('Get from database')) tbl.attach(lattice_button, 2, 3, 0, 1) # HCP stuff self.hcp_ideal = (8 / 3)**(1 / 3) self.lattice_const_c = gtk.Adjustment( self.lattice_const.value * self.hcp_ideal, 0.0, 1000.0, 0.01) lattice_box_c = gtk.SpinButton(self.lattice_const_c, 10.0, 3) lattice_box_c.numeric = True pack(self.vbox_hcp, [gtk.Label('c:'), lattice_box_c, gtk.Label(u'Å')]) self.hcp_c_over_a_format = 'c/a: %.3f ' + _('(%.1f %% of ideal)') self.hcp_c_over_a_label = gtk.Label(self.hcp_c_over_a_format % (self.hcp_ideal, 100.0)) pack(self.vbox_hcp, [self.hcp_c_over_a_label]) tbl.attach(self.vbox_hcp, 1, 2, 1, 2) tbl.show_all() pack(vbox, [tbl]) self.lattice_const.connect('value-changed', self.update) self.lattice_const_c.connect('value-changed', self.update) lattice_button.connect('clicked', self.get_lattice_const) pack(vbox, gtk.Label('')) # System size self.size = [gtk.Adjustment(1, 1, 100, 1) for i in range(3)] buttons = [gtk.SpinButton(s, 0, 0) for s in self.size] self.vacuum = gtk.Adjustment(10.0, 0, 100.0, 0.1) vacuum_box = gtk.SpinButton(self.vacuum, 0.0, 1) pack(vbox, [ gtk.Label(_('Size: \tx: ')), buttons[0], gtk.Label(_(' unit cells')) ]) pack( vbox, [gtk.Label(_('\t\ty: ')), buttons[1], gtk.Label(_(' unit cells'))]) pack(vbox, [ gtk.Label(_(' \t\tz: ')), buttons[2], gtk.Label(_(' layers, ')), vacuum_box, gtk.Label(_(u' Å vacuum')) ]) self.nosize = _('\t\tNo size information yet.') self.sizelabel = gtk.Label(self.nosize) pack(vbox, [self.sizelabel]) for s in self.size: s.connect('value-changed', self.update) self.vacuum.connect('value-changed', self.update) pack(vbox, gtk.Label('')) # Buttons self.pybut = PyButton(_('Creating a surface slab.')) self.pybut.connect('clicked', self.update) buts = cancel_apply_ok(cancel=lambda widget: self.destroy(), apply=self.apply, ok=self.ok) pack(vbox, [self.pybut, buts], end=True, bottom=True) self.add(vbox) vbox.show() self.show() self.gui = gui # Hide the HCP stuff to begin with. self.vbox_hcp.hide_all() # update_element inherited from SetupWindow def update(self, *args): "Called when something has changed." struct = self.structchoice.get_active_text() if struct: structinfo = self.surfinfo[struct] if structinfo[1] == 'hcp': self.vbox_hcp.show_all() ca = self.lattice_const_c.value / self.lattice_const.value self.hcp_c_over_a_label.set_text( self.hcp_c_over_a_format % (ca, 100 * ca / self.hcp_ideal)) else: self.vbox_hcp.hide_all() # Abort if element or structure is invalid if not (self.update_element() and struct): self.sizelabel.set_text(self.nosize) self.atoms = None self.pybut.python = None return False # Make the atoms assert self.legal_element kw = {} kw2 = {} if structinfo[3]: # Support othogonal keyword? kw['orthogonal'] = structinfo[2] kw2['orthoarg'] = ', orthogonal=' + str(kw['orthogonal']) else: kw2['orthoarg'] = '' kw2['func'] = structinfo[4].__name__ kw['symbol'] = self.legal_element kw['size'] = [int(s.value) for s in self.size] kw['a'] = self.lattice_const.value kw['vacuum'] = self.vacuum.value # Now create the atoms try: self.atoms = structinfo[4](**kw) except ValueError as e: # The values were illegal - for example some size # constants must be even for some structures. self.pybut.python = None self.atoms = None self.sizelabel.set_text(str(e).replace('. ', '.\n')) return False kw2.update(kw) self.pybut.python = py_template % kw2 # Find the heights of the unit cell h = np.zeros(3) uc = self.atoms.get_cell() for i in range(3): norm = np.cross(uc[i - 1], uc[i - 2]) norm /= np.sqrt(np.dot(norm, norm)) h[i] = np.abs(np.dot(norm, uc[i])) natoms = len(self.atoms) txt = ('\t\t%.2f Å x %.2f Å x %.2f Å, %s' % (h[0], h[1], h[2], _('%i atoms.') % natoms)) self.sizelabel.set_text(txt) return True def get_lattice_const(self, *args): if not self.update_element(): oops(_('Invalid element.')) return z = ase.data.atomic_numbers[self.legal_element] ref = ase.data.reference_states[z] surface = self.structchoice.get_active_text() if not surface: oops(_('No structure specified!')) return struct = self.surfinfo[surface][1] if ref is None or ref['symmetry'] != struct: from ase.data.alternatives import alternative_structures alt = alternative_structures[z] if alt and alt['symmetry'] == struct: ref = alt else: oops( _('%(struct)s lattice constant unknown for %(element)s.') % dict(struct=struct.upper(), element=self.legal_element)) a = ref['a'] self.lattice_const.set_value(a) if struct == 'hcp': c = ref['c/a'] * a self.lattice_const_c.set_value(c) def apply(self, *args): self.update() if self.atoms is not None: self.gui.new_atoms(self.atoms) return True else: oops( _('No valid atoms.'), _('You have not (yet) specified ' 'a consistent set of parameters.')) return False def ok(self, *args): if self.apply(): self.destroy()