diff --git a/.github/workflows/build_cmake.yml b/.github/workflows/build_cmake.yml index 2245e0b1cb..566f526ac1 100644 --- a/.github/workflows/build_cmake.yml +++ b/.github/workflows/build_cmake.yml @@ -194,14 +194,14 @@ jobs: otool -L libinchi.?.?.?.dylib cp -p libinchi* ../Avogadro2.app/Contents/Frameworks/ # finally, fixup the binaries - cd ../bin - for exe in obabel obmm eht_bind genXrdPattern; do - for libpath in `otool -L ${exe} | grep '/Users/runner/work' | awk '{print $1}'`; do - export lib=`echo $libpath | cut -d '/' -f 9`; - echo "Fixing $exe $lib $libpath" - install_name_tool -change $libpath @executable_path/../Frameworks/$lib $exe - done - done + #cd ../bin + #for exe in obabel obmm eht_bind genXrdPattern; do + # for libpath in `otool -L ${exe} | grep '/Users/runner/work' | awk '{print $1}'`; do + # export lib=`echo $libpath | cut -d '/' -f 9`; + # echo "Fixing $exe $lib $libpath" + # install_name_tool -change $libpath @executable_path/../Frameworks/$lib $exe + # done + #done - name: Run tests if: matrix.config.os == 'ubuntu-20.04' diff --git a/.github/workflows/build_m1.yml b/.github/workflows/build_m1.yml index 8da270d647..746e8dc2b3 100644 --- a/.github/workflows/build_m1.yml +++ b/.github/workflows/build_m1.yml @@ -101,14 +101,14 @@ jobs: otool -L libinchi.?.?.?.dylib cp -p libinchi* ../Avogadro2.app/Contents/Frameworks/ # finally, fixup the binaries - cd ../bin - for exe in obabel obmm eht_bind genXrdPattern; do - for libpath in `otool -L ${exe} | grep '/Users/runner' | awk '{print $1}'`; do - export lib=`echo $libpath | cut -d '/' -f 10`; - echo "Fixing $exe $lib $libpath" - install_name_tool -change $libpath @executable_path/../Frameworks/$lib $exe - done - done + #cd ../bin + #for exe in obabel obmm eht_bind genXrdPattern; do + # for libpath in `otool -L ${exe} | grep '/Users/runner' | awk '{print $1}'`; do + # export lib=`echo $libpath | cut -d '/' -f 10`; + # echo "Fixing $exe $lib $libpath" + # install_name_tool -change $libpath @executable_path/../Frameworks/$lib $exe + # done + #done - name: Install the Apple certificate diff --git a/avogadro/core/coordinateblockgenerator.cpp b/avogadro/core/coordinateblockgenerator.cpp index ddf3c24314..0a40039b4f 100644 --- a/avogadro/core/coordinateblockgenerator.cpp +++ b/avogadro/core/coordinateblockgenerator.cpp @@ -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': @@ -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 @@ -89,10 +91,14 @@ std::string CoordinateBlockGenerator::generateCoordinateBlock() // Use fixed number format. m_stream << std::fixed; + // Count the number for each element + std::vector 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) @@ -137,6 +143,9 @@ 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; @@ -193,4 +202,4 @@ std::string CoordinateBlockGenerator::generateCoordinateBlock() return m_stream.str(); } -} // namespace Avogadro +} // namespace Avogadro::Core diff --git a/avogadro/core/coordinateblockgenerator.h b/avogadro/core/coordinateblockgenerator.h index 600240d9c2..44f0f266de 100644 --- a/avogadro/core/coordinateblockgenerator.h +++ b/avogadro/core/coordinateblockgenerator.h @@ -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)") * - @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") diff --git a/avogadro/qtplugins/coordinateeditor/coordinateeditordialog.cpp b/avogadro/qtplugins/coordinateeditor/coordinateeditordialog.cpp index 96b76c368d..f73260d420 100644 --- a/avogadro/qtplugins/coordinateeditor/coordinateeditordialog.cpp +++ b/avogadro/qtplugins/coordinateeditor/coordinateeditordialog.cpp @@ -42,9 +42,9 @@ #define FORMAT_DEBUG(x) #endif // ENABLE_FORMAT_DEBUG -using Avogadro::QtGui::Molecule; -using Avogadro::Core::Elements; using Avogadro::Vector3; +using Avogadro::Core::Elements; +using Avogadro::QtGui::Molecule; namespace { @@ -96,7 +96,7 @@ struct AtomStruct Vector3 pos; }; -} // end anon namespace +} // namespace namespace Avogadro::QtPlugins { @@ -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)), @@ -385,6 +385,28 @@ 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; @@ -821,4 +843,4 @@ void CoordinateEditorDialog::clearClicked() m_ui->text->document()->clear(); } -} // namespace Avogadro +} // namespace Avogadro::QtPlugins diff --git a/avogadro/qtplugins/coordinateeditor/coordinateeditordialog.ui b/avogadro/qtplugins/coordinateeditor/coordinateeditordialog.ui index fedf142f58..1862a884e3 100644 --- a/avogadro/qtplugins/coordinateeditor/coordinateeditordialog.ui +++ b/avogadro/qtplugins/coordinateeditor/coordinateeditordialog.ui @@ -68,7 +68,7 @@ - <html><head/><body><p>Specification of format. Each character indicates a value to write per atom:</p><p><span style=" font-weight:600;">#</span> - Atom index (1, 2, ..., numAtoms)<br/><span style=" font-weight:600;">Z</span> - Atomic number (e.g. &quot;6&quot; for carbon)<br/><span style=" font-weight:600;">G</span> - GAMESS-style atomic number (e.g. &quot;6.0&quot; for carbon)<br/><span style=" font-weight:600;">N</span> - Element name (e.g. &quot;Carbon&quot;)<br/><span style=" font-weight:600;">S</span> - Element symbol (e.g. &quot;C&quot; for carbon)<br/><span style=" font-weight:600;">x</span> - X position coordinate<br/><span style=" font-weight:600;">y</span> - Y position coordinate<br/><span style=" font-weight:600;">z</span> - Z position coordinate<br/><span style=" font-weight:600;">a</span> - 'a' lattice coordinate (crystals only)<br/><span style=" font-weight:600;">b</span> - 'b' lattice coordinate (crystals only)<br/><span style=" font-weight:600;">c</span> - 'c' lattice coordinate (crystals only)<br/><span style=" font-weight:600;">_</span> - A literal space (&quot; &quot;), useful for alignment<br/><span style=" font-weight:600;">0</span> - A literal 0 (&quot;0&quot;), useful for optimization flags<br/><span style=" font-weight:600;">1</span> - A literal 1 (&quot;1&quot;), useful for optimization flags<br/></p></body></html> + <html><head/><body><p>Specification of format. Each character indicates a value to write per atom:</p><p><span style=" font-weight:600;">#</span> - Atom index (1, 2, ..., numAtoms)<br/><span style=" font-weight:600;">Z</span> - Atomic number (e.g. &quot;6&quot; for carbon)<br/><span style=" font-weight:600;">G</span> - GAMESS-style atomic number (e.g. &quot;6.0&quot; for carbon)<br/><span style=" font-weight:600;">N</span> - Element name (e.g. &quot;Carbon&quot;)<br/><span style=" font-weight:600;">S</span> - Element symbol (e.g. &quot;C&quot; for carbon)<br/><span style=" font-weight:700;">L</span> - Atom label (e.g., &quot;C2&quot; for second carbon atom, &quot;H1&quot; for first hydrogen) <br/><span style=" font-weight:600;">x</span> - X position coordinate<br/><span style=" font-weight:600;">y</span> - Y position coordinate<br/><span style=" font-weight:600;">z</span> - Z position coordinate<br/><span style=" font-weight:600;">a</span> - 'a' lattice coordinate (crystals only)<br/><span style=" font-weight:600;">b</span> - 'b' lattice coordinate (crystals only)<br/><span style=" font-weight:600;">c</span> - 'c' lattice coordinate (crystals only)<br/><span style=" font-weight:600;">_</span> - A literal space (&quot; &quot;), useful for alignment<br/><span style=" font-weight:600;">0</span> - A literal 0 (&quot;0&quot;), useful for optimization flags<br/><span style=" font-weight:600;">1</span> - A literal 1 (&quot;1&quot;), useful for optimization flags<br/></p></body></html>