diff --git a/hexrd/ui/material_site_editor.py b/hexrd/ui/material_site_editor.py
index 795ac0470..2b346b829 100644
--- a/hexrd/ui/material_site_editor.py
+++ b/hexrd/ui/material_site_editor.py
@@ -3,8 +3,11 @@
import numpy as np
from PySide2.QtCore import QItemSelectionModel, QObject, Signal
-from PySide2.QtWidgets import QLineEdit, QSizePolicy, QTableWidgetItem
+from PySide2.QtWidgets import (
+ QComboBox, QLineEdit, QSizePolicy, QTableWidgetItem
+)
+from hexrd.constants import chargestate
from hexrd.material import Material
from hexrd.ui.periodic_table_dialog import PeriodicTableDialog
@@ -16,10 +19,12 @@
COLUMNS = {
'symbol': 0,
- 'occupancy': 1,
- 'thermal_factor': 2
+ 'charge': 1,
+ 'occupancy': 2,
+ 'thermal_factor': 3
}
+DEFAULT_CHARGE = '0'
DEFAULT_U = Material.DFLT_U[0]
OCCUPATION_MIN = 0
@@ -44,6 +49,7 @@ def __init__(self, site, parent=None):
self._site = site
+ self.charge_comboboxes = []
self.occupancy_spinboxes = []
self.thermal_factor_spinboxes = []
@@ -143,12 +149,17 @@ def atom_types(self, v):
# Reset all the occupancies
atoms = self.atoms
previous_u_values = {x['symbol']: x['U'] for x in atoms}
+ previous_charges = {x['symbol']: x['charge'] for x in atoms}
atoms.clear()
for symbol in v:
- # Use the previous U if available. Otherwise, use the default.
- U = previous_u_values.get(symbol, DEFAULT_U)
- atoms.append({'symbol': symbol, 'U': U})
+ # Use previous values if available. Otherwise, use the defaults.
+ atom = {
+ 'symbol': symbol,
+ 'U': previous_u_values.get(symbol, DEFAULT_U),
+ 'charge': previous_charges.get(symbol, DEFAULT_CHARGE),
+ }
+ atoms.append(atom)
self.reset_occupancies()
self.update_table()
@@ -195,6 +206,22 @@ def create_symbol_label(self, v):
w = QTableWidgetItem(v)
return w
+ def create_charge_combobox(self, charge, symbol):
+ cb = QComboBox(self.ui.table)
+
+ if charge not in chargestate[symbol]:
+ raise Exception(f'Invalid charge {charge} for {symbol}')
+
+ cb.addItems(chargestate[symbol])
+ cb.setCurrentText(charge)
+ cb.currentIndexChanged.connect(self.update_config)
+
+ size_policy = QSizePolicy(QSizePolicy.Expanding, QSizePolicy.Expanding)
+ cb.setSizePolicy(size_policy)
+
+ self.charge_comboboxes.append(cb)
+ return cb
+
def create_occupancy_spinbox(self, v):
sb = ScientificDoubleSpinBox(self.ui.table)
sb.setKeyboardTracking(False)
@@ -225,6 +252,7 @@ def create_thermal_factor_spinbox(self, v):
return sb
def clear_table(self):
+ self.charge_comboboxes.clear()
self.occupancy_spinboxes.clear()
self.thermal_factor_spinboxes.clear()
self.ui.table.clearContents()
@@ -260,6 +288,9 @@ def update_table(self):
w = self.create_symbol_label(atom['symbol'])
self.ui.table.setItem(i, COLUMNS['symbol'], w)
+ w = self.create_charge_combobox(atom['charge'], atom['symbol'])
+ self.ui.table.setCellWidget(i, COLUMNS['charge'], w)
+
w = self.create_occupancy_spinbox(atom['occupancy'])
self.ui.table.setCellWidget(i, COLUMNS['occupancy'], w)
@@ -293,6 +324,9 @@ def update_config(self):
for i, w in enumerate(self.fractional_coords_widgets):
self.fractional_coords[i] = w.value()
+ for atom, combobox in zip(self.atoms, self.charge_comboboxes):
+ atom['charge'] = combobox.currentText()
+
for atom, spinbox in zip(self.atoms, self.occupancy_spinboxes):
atom['occupancy'] = spinbox.value()
diff --git a/hexrd/ui/material_structure_editor.py b/hexrd/ui/material_structure_editor.py
index 989d2a719..cec40b781 100644
--- a/hexrd/ui/material_structure_editor.py
+++ b/hexrd/ui/material_structure_editor.py
@@ -23,11 +23,13 @@
'atoms': [
{
'symbol': 'O',
+ 'charge': '0',
'occupancy': 0.5,
'U': 1e-6
},
{
'symbol': 'Ce',
+ 'charge': '0',
'occupancy': 0.5,
'U': 1e-6
}
@@ -234,6 +236,7 @@ def update_material(self):
# Convert the sites back to the material data format
info_array = []
type_array = []
+ charge_array = []
U_array = []
for site in self.sites:
@@ -241,6 +244,7 @@ def update_material(self):
info_array.append((*site['fractional_coords'],
atom['occupancy']))
type_array.append(ptable[atom['symbol']])
+ charge_array.append(atom['charge'])
U_array.append(atom['U'])
if any(isinstance(x, np.ndarray) for x in U_array):
@@ -249,7 +253,7 @@ def update_material(self):
U_array[i] = scalar_to_tensor(U)
mat = self.material
- mat._set_atomdata(type_array, info_array, U_array)
+ mat._set_atomdata(type_array, info_array, U_array, charge_array)
self.material_modified.emit()
@@ -263,11 +267,13 @@ def generate_sites(self):
'atoms': [
{
'symbol': 'Na',
+ 'charge': '0',
'occupancy': 0.5,
'U': 4.18e-7
},
{
'symbol': 'Br',
+ 'charge': '0',
'occupancy': 0.5,
'U': 4.18e-7
}
@@ -287,6 +293,7 @@ def coords_equal(v1, v2, tol=1.e-5):
info_array = mat._atominfo
type_array = mat._atomtype
+ charge_array = mat.charge
U_array = mat._U
if any(isinstance(x, np.ndarray) for x in U_array):
@@ -322,6 +329,7 @@ def coords_equal(v1, v2, tol=1.e-5):
for i in indices:
atom = {
'symbol': ptableinverse[type_array[i]],
+ 'charge': charge_array[i],
'occupancy': info_array[i][3],
'U': U_array[i]
}
diff --git a/hexrd/ui/resources/ui/material_site_editor.ui b/hexrd/ui/resources/ui/material_site_editor.ui
index 2f38a69a1..a04114540 100644
--- a/hexrd/ui/resources/ui/material_site_editor.ui
+++ b/hexrd/ui/resources/ui/material_site_editor.ui
@@ -52,6 +52,11 @@
Symbol
+
+
+ Charge
+
+
Occupancy