Skip to content

Commit

Permalink
Add support for atom labels in the coordinate editor
Browse files Browse the repository at this point in the history
  • Loading branch information
ghutchis committed Oct 7, 2023
1 parent 79e1641 commit 2ec502c
Show file tree
Hide file tree
Showing 4 changed files with 37 additions and 2 deletions.
10 changes: 10 additions & 0 deletions avogadro/core/coordinateblockgenerator.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@ std::string CoordinateBlockGenerator::generateCoordinateBlock()
for (it = begin; it != end; ++it) {
switch (*it) {
case 'S':
case 'L':
needElementSymbol = true;
break;
case 'N':
Expand Down Expand Up @@ -76,6 +77,7 @@ std::string CoordinateBlockGenerator::generateCoordinateBlock()
{
atomicNumberPrecision = 0,
atomicNumberWidth = 3,
atomicLabelWidth = 8, // 3 element symbol + 5 index
coordinatePrecision = 6,
coordinateWidth = 11,
elementNameWidth = 13, // Currently the longest element name
Expand All @@ -89,10 +91,14 @@ std::string CoordinateBlockGenerator::generateCoordinateBlock()
// Use fixed number format.
m_stream << std::fixed;

// Count the number for each element
std::vector<unsigned int> elementCounts(Elements::elementCount(), 0);

// Iterate through the atoms
for (Index atomI = 0; atomI < numAtoms; ++atomI) {
atom = m_molecule->atom(atomI);
atomicNumber = atom.atomicNumber();
elementCounts[atomicNumber]++;
if (needElementSymbol)
symbol = Core::Elements::symbol(atomicNumber);
if (needElementName)
Expand Down Expand Up @@ -137,6 +143,10 @@ std::string CoordinateBlockGenerator::generateCoordinateBlock()
case 'S':
m_stream << std::left << std::setw(elementSymbolWidth) << symbol;
break;
case 'L':
m_stream << std::left << symbol
<< elementCounts[atomicNumber] << " ";
break;
case 'N':
m_stream << std::left << std::setw(elementNameWidth) << name;
break;
Expand Down
1 change: 1 addition & 0 deletions avogadro/core/coordinateblockgenerator.h
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@ class AVOGADROCORE_EXPORT CoordinateBlockGenerator
* about each atom in the coordinate block.
* - @c #: Atom index (one-based index)
* - @c Z: Atomic number (e.g. "6" for carbon)
* - @c L: Atomic label (e.g., "C1" for first carbon, "H2" for second hydrogen")
* - @c G: GAMESS-styled Atomic number (e.g. "6.0" for carbon)
* - @c S: Element symbol (e.g. "C" for carbon)
* - @c N: Element name (e.g. "Carbon")
Expand Down
26 changes: 25 additions & 1 deletion avogadro/qtplugins/coordinateeditor/coordinateeditordialog.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -140,7 +140,7 @@ CoordinateEditorDialog::CoordinateEditorDialog(QWidget* parent_)
SLOT(textModified(bool)));

// Setup spec edit
QRegExp specRegExp("[#ZGSNabcxyz01_]*");
QRegExp specRegExp("[#ZGSLNabcxyz01_]*");
auto* specValidator = new QRegExpValidator(specRegExp, this);
m_ui->spec->setValidator(specValidator);
connect(m_ui->presets, SIGNAL(currentIndexChanged(int)),
Expand Down Expand Up @@ -385,6 +385,30 @@ void CoordinateEditorDialog::validateInputWorker()
break;
}

case 'L': {
// Validate label (symbol + number)

QString cleanToken(tokenCursor.selectedText().toLower());
if (!cleanToken.isEmpty())
cleanToken.replace(0, 1, cleanToken[0].toUpper());

// Split the label into symbol and number
QRegExp labelSplitter("([A-Z][a-z]?)(\\d+)");
if (labelSplitter.indexIn(cleanToken) == -1) {
m_ui->text->markInvalid(tokenCursor, tr("Invalid atom label."));
break;
}
// check the symbol
std::string tokenStd(labelSplitter.cap(1).toStdString());
atom.atomicNumber = Elements::atomicNumberFromSymbol(tokenStd);
if (atom.atomicNumber == Avogadro::InvalidElement)
m_ui->text->markInvalid(tokenCursor, tr("Invalid element symbol."));
else
m_ui->text->markValid(tokenCursor, tr("Element symbol."));
break;

}

case '#': {
// Validate integer:
bool isInt;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,7 @@
<item>
<widget class="QLineEdit" name="spec">
<property name="toolTip">
<string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Specification of format. Each character indicates a value to write per atom:&lt;/p&gt;&lt;p&gt;&lt;span style=&quot; font-weight:600;&quot;&gt;#&lt;/span&gt; - Atom index (1, 2, ..., numAtoms)&lt;br/&gt;&lt;span style=&quot; font-weight:600;&quot;&gt;Z&lt;/span&gt; - Atomic number (e.g. &amp;quot;6&amp;quot; for carbon)&lt;br/&gt;&lt;span style=&quot; font-weight:600;&quot;&gt;G&lt;/span&gt; - GAMESS-style atomic number (e.g. &amp;quot;6.0&amp;quot; for carbon)&lt;br/&gt;&lt;span style=&quot; font-weight:600;&quot;&gt;N&lt;/span&gt; - Element name (e.g. &amp;quot;Carbon&amp;quot;)&lt;br/&gt;&lt;span style=&quot; font-weight:600;&quot;&gt;S&lt;/span&gt; - Element symbol (e.g. &amp;quot;C&amp;quot; for carbon)&lt;br/&gt;&lt;span style=&quot; font-weight:600;&quot;&gt;x&lt;/span&gt; - X position coordinate&lt;br/&gt;&lt;span style=&quot; font-weight:600;&quot;&gt;y&lt;/span&gt; - Y position coordinate&lt;br/&gt;&lt;span style=&quot; font-weight:600;&quot;&gt;z&lt;/span&gt; - Z position coordinate&lt;br/&gt;&lt;span style=&quot; font-weight:600;&quot;&gt;a&lt;/span&gt; - 'a' lattice coordinate (crystals only)&lt;br/&gt;&lt;span style=&quot; font-weight:600;&quot;&gt;b&lt;/span&gt; - 'b' lattice coordinate (crystals only)&lt;br/&gt;&lt;span style=&quot; font-weight:600;&quot;&gt;c&lt;/span&gt; - 'c' lattice coordinate (crystals only)&lt;br/&gt;&lt;span style=&quot; font-weight:600;&quot;&gt;_&lt;/span&gt; - A literal space (&amp;quot; &amp;quot;), useful for alignment&lt;br/&gt;&lt;span style=&quot; font-weight:600;&quot;&gt;0&lt;/span&gt; - A literal 0 (&amp;quot;0&amp;quot;), useful for optimization flags&lt;br/&gt;&lt;span style=&quot; font-weight:600;&quot;&gt;1&lt;/span&gt; - A literal 1 (&amp;quot;1&amp;quot;), useful for optimization flags&lt;br/&gt;&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
<string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Specification of format. Each character indicates a value to write per atom:&lt;/p&gt;&lt;p&gt;&lt;span style=&quot; font-weight:600;&quot;&gt;#&lt;/span&gt; - Atom index (1, 2, ..., numAtoms)&lt;br/&gt;&lt;span style=&quot; font-weight:600;&quot;&gt;Z&lt;/span&gt; - Atomic number (e.g. &amp;quot;6&amp;quot; for carbon)&lt;br/&gt;&lt;span style=&quot; font-weight:600;&quot;&gt;G&lt;/span&gt; - GAMESS-style atomic number (e.g. &amp;quot;6.0&amp;quot; for carbon)&lt;br/&gt;&lt;span style=&quot; font-weight:600;&quot;&gt;N&lt;/span&gt; - Element name (e.g. &amp;quot;Carbon&amp;quot;)&lt;br/&gt;&lt;span style=&quot; font-weight:600;&quot;&gt;S&lt;/span&gt; - Element symbol (e.g. &amp;quot;C&amp;quot; for carbon)&lt;br/&gt;&lt;span style=&quot; font-weight:700;&quot;&gt;L&lt;/span&gt; - Atom label (e.g., &amp;quot;C2&amp;quot; for second carbon atom, &amp;quot;H1&amp;quot; for first hydrogen) &lt;br/&gt;&lt;span style=&quot; font-weight:600;&quot;&gt;x&lt;/span&gt; - X position coordinate&lt;br/&gt;&lt;span style=&quot; font-weight:600;&quot;&gt;y&lt;/span&gt; - Y position coordinate&lt;br/&gt;&lt;span style=&quot; font-weight:600;&quot;&gt;z&lt;/span&gt; - Z position coordinate&lt;br/&gt;&lt;span style=&quot; font-weight:600;&quot;&gt;a&lt;/span&gt; - 'a' lattice coordinate (crystals only)&lt;br/&gt;&lt;span style=&quot; font-weight:600;&quot;&gt;b&lt;/span&gt; - 'b' lattice coordinate (crystals only)&lt;br/&gt;&lt;span style=&quot; font-weight:600;&quot;&gt;c&lt;/span&gt; - 'c' lattice coordinate (crystals only)&lt;br/&gt;&lt;span style=&quot; font-weight:600;&quot;&gt;_&lt;/span&gt; - A literal space (&amp;quot; &amp;quot;), useful for alignment&lt;br/&gt;&lt;span style=&quot; font-weight:600;&quot;&gt;0&lt;/span&gt; - A literal 0 (&amp;quot;0&amp;quot;), useful for optimization flags&lt;br/&gt;&lt;span style=&quot; font-weight:600;&quot;&gt;1&lt;/span&gt; - A literal 1 (&amp;quot;1&amp;quot;), useful for optimization flags&lt;br/&gt;&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
</property>
</widget>
</item>
Expand Down

0 comments on commit 2ec502c

Please sign in to comment.