Пример #1
0
    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
Пример #2
0
    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
Пример #3
0
    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()
Пример #4
0
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')
Пример #5
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()
Пример #6
0
    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()
Пример #7
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.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()
Пример #8
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(""))

        # 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()
Пример #9
0
    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()
Пример #10
0
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
Пример #11
0
    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()
Пример #12
0
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')
Пример #13
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()
Пример #14
0
    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
Пример #15
0
    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
Пример #16
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("ų")
        ])
        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()
Пример #17
0
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
Пример #18
0
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()
Пример #19
0
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()