diff --git a/resources/surface_description.json b/resources/surface_description.json index 3e4cc21..2b2c16a 100644 --- a/resources/surface_description.json +++ b/resources/surface_description.json @@ -99,7 +99,7 @@ "orbital": { "cmap": "RedWhiteBlue", "displayName": "Orbital", - "occName": "mo", + "occName": "orbital", "needsWavefunction": true, "needsOrbital": true, "units": "au", @@ -249,7 +249,7 @@ }, "orbital": { "displayName": "Orbital", - "occName": "mo", + "occName": "orbital", "needsWavefunction": true, "needsOrbital": true, "needsIsovalue": true, diff --git a/src/core/chemicalstructure.cpp b/src/core/chemicalstructure.cpp index 8281920..f331660 100644 --- a/src/core/chemicalstructure.cpp +++ b/src/core/chemicalstructure.cpp @@ -1296,38 +1296,38 @@ QString ChemicalStructure::getFragmentLabelForAtoms( QString ChemicalStructure::getFragmentLabel(const FragmentIndex &index) { const auto &fragments = symmetryUniqueFragments(); if (m_fragmentLabels.size() != fragments.size()) { - ankerl::unordered_dense::map> - formulaToIndex; - char currentLabel = 'A'; - int labelCount = 0; + struct LabelInfo { + int formula_id; + QString current_letter; + }; + ankerl::unordered_dense::map formulaToLabel; + int next_id = 1; for (const auto &[fragmentIndex, fragment] : fragments) { QString formula = formulaSumForAtoms(fragment.atomIndices, false); - auto it = formulaToIndex.find(formula); - - if (it == formulaToIndex.end()) { - QString label = QString(1, currentLabel); - formulaToIndex[formula] = {label, 1}; - m_fragmentLabels[fragmentIndex] = "1" + label; - - labelCount++; - if (labelCount == 26) { - currentLabel = 'A'; - labelCount = 0; - } else { - currentLabel++; - } + auto it = formulaToLabel.find(formula); + + if (it == formulaToLabel.end()) { + formulaToLabel[formula] = {next_id++, "A"}; + m_fragmentLabels[fragmentIndex] = + QString::number(formulaToLabel[formula].formula_id) + + formulaToLabel[formula].current_letter; } else { - auto &[label, count] = it->second; - count++; - m_fragmentLabels[fragmentIndex] = QString::number(count) + label; + auto &labelInfo = it->second; + char nextChar = + static_cast(labelInfo.current_letter[0].toLatin1() + 1); + labelInfo.current_letter = QString(QChar(nextChar)); + + m_fragmentLabels[fragmentIndex] = + QString::number(labelInfo.formula_id) + labelInfo.current_letter; } } } const auto kv = m_fragmentLabels.find(index); - if (kv != m_fragmentLabels.end()) + if (kv != m_fragmentLabels.end()) { return kv->second; + } return "??"; } diff --git a/src/core/globalconfiguration.cpp b/src/core/globalconfiguration.cpp index 127abe0..413ed87 100644 --- a/src/core/globalconfiguration.cpp +++ b/src/core/globalconfiguration.cpp @@ -1,6 +1,5 @@ #include "globalconfiguration.h" -// Initialize static membes GlobalConfiguration *GlobalConfiguration::instance = nullptr; QMutex GlobalConfiguration::mutex; @@ -13,6 +12,9 @@ GlobalConfiguration *GlobalConfiguration::getInstance() { } bool GlobalConfiguration::load() { + if (m_haveData) + return m_haveData; + qDebug() << "Loading surface descriptions"; bool surfaceSuccess = isosurface::loadSurfaceDescriptionConfiguration( surfacePropertyDescriptions, surfaceDescriptions, surfaceResolutionLevels); @@ -24,15 +26,16 @@ bool GlobalConfiguration::load() { if (!colorMapSuccess) { qWarning() << "Unable to load surface descriptions from file"; } - return surfaceSuccess && colorMapSuccess; + m_haveData = surfaceSuccess && colorMapSuccess; + return m_haveData; } -const QMap & +const isosurface::SurfacePropertyDescriptions & GlobalConfiguration::getPropertyDescriptions() const { return surfacePropertyDescriptions; } -const QMap & +const isosurface::SurfaceDescriptions & GlobalConfiguration::getSurfaceDescriptions() const { return surfaceDescriptions; } @@ -42,16 +45,12 @@ GlobalConfiguration::getSurfaceResolutionLevels() const { return surfaceResolutionLevels; } - -const QMap GlobalConfiguration::getColorMapDescriptions() const { +const QMap +GlobalConfiguration::getColorMapDescriptions() const { return colorMapDescriptions; } QString GlobalConfiguration::getColorMapNameForProperty( const QString &propertyName) const { - auto it = surfacePropertyDescriptions.find(propertyName); - if (it != surfacePropertyDescriptions.end()) { - return it->cmap; - } - return "Viridis"; + return surfacePropertyDescriptions.get(propertyName).cmap; } diff --git a/src/core/globalconfiguration.h b/src/core/globalconfiguration.h index 05ddccb..c5ef45b 100644 --- a/src/core/globalconfiguration.h +++ b/src/core/globalconfiguration.h @@ -1,6 +1,6 @@ #pragma once -#include "isosurface_parameters.h" #include "colormap.h" +#include "isosurface_parameters.h" #include #include @@ -9,11 +9,11 @@ class GlobalConfiguration { static GlobalConfiguration *instance; static QMutex mutex; - QMap - surfacePropertyDescriptions; - QMap surfaceDescriptions; + isosurface::SurfacePropertyDescriptions surfacePropertyDescriptions; + isosurface::SurfaceDescriptions surfaceDescriptions; QMap surfaceResolutionLevels; QMap colorMapDescriptions; + bool m_haveData{false}; protected: GlobalConfiguration() {} // Constructor must be protected or private @@ -29,10 +29,9 @@ class GlobalConfiguration { bool load(); - const QMap & + const isosurface::SurfacePropertyDescriptions & getPropertyDescriptions() const; - const QMap & - getSurfaceDescriptions() const; + const isosurface::SurfaceDescriptions &getSurfaceDescriptions() const; const QMap &getSurfaceResolutionLevels() const; QString getColorMapNameForProperty(const QString &) const; diff --git a/src/core/isosurface_parameters.cpp b/src/core/isosurface_parameters.cpp index 95a2452..f1733e4 100644 --- a/src/core/isosurface_parameters.cpp +++ b/src/core/isosurface_parameters.cpp @@ -101,6 +101,8 @@ QString kindToString(Kind kind) { return "electron_density"; case Kind::DeformationDensity: return "deformation_density"; + case Kind::Orbital: + return "orbital"; default: return "unknown"; }; @@ -120,6 +122,8 @@ QString defaultPropertyForKind(Kind kind) { return "dnorm"; case Kind::DeformationDensity: return "None"; + case Kind::Orbital: + return "Isovalue"; default: return "unknown"; }; @@ -142,13 +146,15 @@ Kind stringToKind(const QString &s) { else if (s == "def" || s == "deformation_density" || s == "Deformation Density") return Kind::DeformationDensity; + else if (s == "mo" || s == "orbital" || s == "Orbital") + return Kind::Orbital; else return Kind::Unknown; } -QMap +inline SurfacePropertyDescriptions loadPropertyDescriptions(const nlohmann::json &json) { - QMap properties; + SurfacePropertyDescriptions properties; auto s = [](const std::string &str) { return QString::fromStdString(str); }; qDebug() << "Load property descriptions"; @@ -161,10 +167,11 @@ loadPropertyDescriptions(const nlohmann::json &json) { try { SurfacePropertyDescription spd; from_json(item.value(), spd); - properties.insert(s(item.key()), spd); + properties.descriptions.insert(spd.displayName, spd); // allow referring by the occName or displayName as well - properties.insert(spd.occName, spd); - properties.insert(spd.displayName, spd); + properties.displayNameLookup.insert(s(item.key()), spd.displayName); + properties.displayNameLookup.insert(spd.occName, spd.displayName); + properties.displayNameLookup.insert(spd.displayName, spd.displayName); } catch (nlohmann::json::exception &e) { qWarning() << "Failed to parse property" << s(item.key()) << ":" << e.what(); @@ -173,9 +180,8 @@ loadPropertyDescriptions(const nlohmann::json &json) { return properties; } -QMap -loadSurfaceDescriptions(const nlohmann::json &json) { - QMap surfaces; +inline SurfaceDescriptions loadSurfaceDescriptions(const nlohmann::json &json) { + SurfaceDescriptions surfaces; if (!json.contains("surfaces") || !json["surfaces"].is_object()) { qWarning() << "JSON does not contain a 'surfaces' object"; @@ -188,9 +194,11 @@ loadSurfaceDescriptions(const nlohmann::json &json) { try { SurfaceDescription sd; from_json(item.value(), sd); - surfaces.insert(s(item.key()), sd); - surfaces.insert(sd.occName, sd); - surfaces.insert(sd.displayName, sd); + surfaces.descriptions.insert(sd.displayName, sd); + + surfaces.displayNameLookup.insert(s(item.key()), sd.displayName); + surfaces.displayNameLookup.insert(sd.occName, sd.displayName); + surfaces.displayNameLookup.insert(sd.displayName, sd.displayName); } catch (nlohmann::json::exception &e) { qWarning() << "Failed to parse surface" << s(item.key()) << ":" << e.what(); @@ -222,9 +230,8 @@ QMap loadResolutionLevels(const nlohmann::json &json) { } bool loadSurfaceDescriptionConfiguration( - QMap &propertyDescriptions, - QMap &descriptions, - QMap &resolutions) { + SurfacePropertyDescriptions &propertyDescriptions, + SurfaceDescriptions &descriptions, QMap &resolutions) { QFile file(":/resources/surface_description.json"); if (!file.open(QIODevice::ReadOnly)) { qWarning("Couldn't open config file."); @@ -247,32 +254,38 @@ bool loadSurfaceDescriptionConfiguration( return true; } +SurfaceDescription SurfaceDescriptions::get(const QString &s) const { + auto loc = displayNameLookup.find(s); + if (loc != displayNameLookup.end()) + return descriptions.value(*loc); + return {}; +} + +SurfacePropertyDescription +SurfacePropertyDescriptions::get(const QString &s) const { + auto loc = displayNameLookup.find(s); + if (loc != displayNameLookup.end()) + return descriptions.value(*loc); + return {}; +} + SurfaceDescription getSurfaceDescription(Kind kind) { QString s = kindToString(kind); const auto &descriptions = GlobalConfiguration::getInstance()->getSurfaceDescriptions(); - auto loc = descriptions.find(s); - if (loc != descriptions.end()) - return *loc; - return {}; + return descriptions.get(s); } QString getSurfaceDisplayName(QString s) { const auto &descriptions = GlobalConfiguration::getInstance()->getSurfaceDescriptions(); - auto loc = descriptions.find(s); - if (loc != descriptions.end()) - return (*loc).displayName; - return s; + return descriptions.get(s).displayName; } QString getSurfacePropertyDisplayName(QString s) { const auto &descriptions = GlobalConfiguration::getInstance()->getPropertyDescriptions(); - auto loc = descriptions.find(s); - if (loc != descriptions.end()) - return (*loc).displayName; - return s; + return descriptions.get(s).displayName; } } // namespace isosurface diff --git a/src/core/isosurface_parameters.h b/src/core/isosurface_parameters.h index e706a4b..03f73eb 100644 --- a/src/core/isosurface_parameters.h +++ b/src/core/isosurface_parameters.h @@ -47,13 +47,19 @@ inline const char *resolutionToString(Resolution res) { } inline Resolution stringToResolution(const QString &res) { - if (res.compare("Very Low", Qt::CaseInsensitive) == 0) return Resolution::VeryLow; - if (res.compare("Low", Qt::CaseInsensitive) == 0) return Resolution::Low; - if (res.compare("Medium", Qt::CaseInsensitive) == 0) return Resolution::Medium; - if (res.compare("High", Qt::CaseInsensitive) == 0) return Resolution::High; - if (res.compare("Very High", Qt::CaseInsensitive) == 0) return Resolution::VeryHigh; - if (res.compare("Absurd", Qt::CaseInsensitive) == 0) return Resolution::Absurd; - return Resolution::Custom; // Default case + if (res.compare("Very Low", Qt::CaseInsensitive) == 0) + return Resolution::VeryLow; + if (res.compare("Low", Qt::CaseInsensitive) == 0) + return Resolution::Low; + if (res.compare("Medium", Qt::CaseInsensitive) == 0) + return Resolution::Medium; + if (res.compare("High", Qt::CaseInsensitive) == 0) + return Resolution::High; + if (res.compare("Very High", Qt::CaseInsensitive) == 0) + return Resolution::VeryHigh; + if (res.compare("Absurd", Qt::CaseInsensitive) == 0) + return Resolution::Absurd; + return Resolution::Custom; // Default case } enum class Kind { @@ -68,9 +74,9 @@ enum class Kind { }; struct OrbitalDetails { - QString label{"HOMO"}; - int index{0}; - bool occupied{true}; + QString label{"HOMO"}; + int index{0}; + bool occupied{true}; }; struct Parameters { @@ -82,7 +88,6 @@ struct Parameters { MolecularWavefunction *wfn{nullptr}; Eigen::Isometry3d wfn_transform{Eigen::Isometry3d::Identity()}; QStringList additionalProperties; - }; struct Result { @@ -122,18 +127,29 @@ struct SurfaceDescription { SurfaceDescription getSurfaceDescription(Kind); +struct SurfaceDescriptions { + QMap descriptions; + QMap displayNameLookup; + SurfaceDescription get(const QString &) const; +}; + +struct SurfacePropertyDescriptions { + QMap descriptions; + QMap displayNameLookup; + SurfacePropertyDescription get(const QString &) const; +}; + QString getSurfaceDisplayName(QString); QString getSurfacePropertyDisplayName(QString); -bool loadSurfaceDescriptionConfiguration( - QMap &, - QMap &, QMap &); +bool loadSurfaceDescriptionConfiguration(SurfacePropertyDescriptions &, + SurfaceDescriptions &, + QMap &); } // namespace isosurface -void to_json(nlohmann::json& j, const isosurface::SurfacePropertyDescription&); -void from_json(const nlohmann::json& j, isosurface::SurfacePropertyDescription&); -void to_json(nlohmann::json& j, const isosurface::SurfaceDescription&); -void from_json(const nlohmann::json& j, isosurface::SurfaceDescription&); - - +void to_json(nlohmann::json &j, const isosurface::SurfacePropertyDescription &); +void from_json(const nlohmann::json &j, + isosurface::SurfacePropertyDescription &); +void to_json(nlohmann::json &j, const isosurface::SurfaceDescription &); +void from_json(const nlohmann::json &j, isosurface::SurfaceDescription &); diff --git a/src/core/meshpropertymodel.cpp b/src/core/meshpropertymodel.cpp index 00488ee..55f71f2 100644 --- a/src/core/meshpropertymodel.cpp +++ b/src/core/meshpropertymodel.cpp @@ -1,10 +1,14 @@ #include "meshpropertymodel.h" +#include "globalconfiguration.h" #include MeshPropertyModel::MeshPropertyModel(QObject *parent) : QAbstractListModel(parent), m_mesh(nullptr) { - loadSurfaceDescriptionConfiguration( - m_propertyDescriptions, m_surfaceDescriptions, m_defaultIsovalues); + auto *g = GlobalConfiguration::getInstance(); + + m_propertyDescriptions = g->getPropertyDescriptions(); + m_surfaceDescriptions = g->getSurfaceDescriptions(); + m_defaultIsovalues = g->getSurfaceResolutionLevels(); } bool MeshPropertyModel::isValid() const { @@ -69,16 +73,17 @@ QVariant MeshPropertyModel::data(const QModelIndex &index, int role) const { switch (role) { case Qt::DisplayRole: { // Use display name from property description if available - auto it = m_propertyDescriptions.find(propertyName); - if (it != m_propertyDescriptions.end()) { + auto it = m_propertyDescriptions.descriptions.find(propertyName); + if (it != m_propertyDescriptions.descriptions.end()) { return it->displayName; } return propertyName; } case Qt::DecorationRole: { // Load icon if specified in the property description - auto it = m_propertyDescriptions.find(propertyName); - if (it != m_propertyDescriptions.end() && !it->iconName.isEmpty()) { + auto it = m_propertyDescriptions.descriptions.find(propertyName); + if (it != m_propertyDescriptions.descriptions.end() && + !it->iconName.isEmpty()) { return QIcon(QString(":/images/%1").arg(it->iconName)); } return QVariant(); @@ -86,22 +91,22 @@ QVariant MeshPropertyModel::data(const QModelIndex &index, int role) const { case PropertyNameRole: return propertyName; case PropertyUnitsRole: { - auto it = m_propertyDescriptions.find(propertyName); - if (it != m_propertyDescriptions.end()) { + auto it = m_propertyDescriptions.descriptions.find(propertyName); + if (it != m_propertyDescriptions.descriptions.end()) { return it->units; } return ""; } case PropertyDescriptionRole: { - auto it = m_propertyDescriptions.find(propertyName); - if (it != m_propertyDescriptions.end()) { + auto it = m_propertyDescriptions.descriptions.find(propertyName); + if (it != m_propertyDescriptions.descriptions.end()) { return it->description; } return ""; } case PropertyColorMapRole: { - auto it = m_propertyDescriptions.find(propertyName); - if (it != m_propertyDescriptions.end()) { + auto it = m_propertyDescriptions.descriptions.find(propertyName); + if (it != m_propertyDescriptions.descriptions.end()) { return it->cmap; } return "Viridis"; // default colormap @@ -192,8 +197,8 @@ QString MeshPropertyModel::getSelectedPropertyColorMap() const { if (!m_mesh) return "Viridis"; QString propertyName = getSelectedProperty(); - auto it = m_propertyDescriptions.find(propertyName); - if (it != m_propertyDescriptions.end()) { + auto it = m_propertyDescriptions.descriptions.find(propertyName); + if (it != m_propertyDescriptions.descriptions.end()) { return it->cmap; } return "Viridis"; diff --git a/src/core/meshpropertymodel.h b/src/core/meshpropertymodel.h index 2550077..6667504 100644 --- a/src/core/meshpropertymodel.h +++ b/src/core/meshpropertymodel.h @@ -73,7 +73,7 @@ public slots: Mesh *m_mesh{nullptr}; bool m_blockedWhileResetting{false}; - QMap m_propertyDescriptions; - QMap m_surfaceDescriptions; + isosurface::SurfacePropertyDescriptions m_propertyDescriptions; + isosurface::SurfaceDescriptions m_surfaceDescriptions; QMap m_defaultIsovalues; }; diff --git a/src/dialogs/surfacedropdown.cpp b/src/dialogs/surfacedropdown.cpp index 6e3e4a3..742df87 100644 --- a/src/dialogs/surfacedropdown.cpp +++ b/src/dialogs/surfacedropdown.cpp @@ -21,16 +21,16 @@ void SurfaceTypeDropdown::setCurrent(QString val) { isosurface::SurfaceDescription SurfaceTypeDropdown::currentSurfaceDescription() const { - return m_surfaceDescriptions.value(current()); + return m_surfaceDescriptions.get(current()); } void SurfaceTypeDropdown::setDescriptions( - const SurfaceDescriptionMap &surfaceDescriptions) { + const isosurface::SurfaceDescriptions &surfaceDescriptions) { m_surfaceDescriptions = surfaceDescriptions; clear(); - for (auto it = m_surfaceDescriptions.constBegin(); - it != m_surfaceDescriptions.constEnd(); ++it) { + for (auto it = m_surfaceDescriptions.descriptions.constBegin(); + it != m_surfaceDescriptions.descriptions.constEnd(); ++it) { addItem(it.value().displayName, it.key()); } } @@ -53,12 +53,13 @@ QString SurfacePropertyTypeDropdown::current() const { isosurface::SurfacePropertyDescription SurfacePropertyTypeDropdown::currentSurfacePropertyDescription() const { - return m_surfacePropertyDescriptions.value(current()); + return m_surfacePropertyDescriptions.descriptions.value(current()); } void SurfacePropertyTypeDropdown::setDescriptions( - const SurfaceDescriptionMap &surfaceDescriptions, - const SurfacePropertyDescriptionMap &surfacePropertyDescriptions) { + const isosurface::SurfaceDescriptions &surfaceDescriptions, + const isosurface::SurfacePropertyDescriptions + &surfacePropertyDescriptions) { m_surfaceDescriptions = surfaceDescriptions; m_surfacePropertyDescriptions = surfacePropertyDescriptions; } @@ -85,13 +86,13 @@ void SurfacePropertyTypeDropdown::onSurfaceSelectionChanged( isosurface::SurfaceDescription SurfacePropertyTypeDropdown::getSurfaceDescription( const QString &surfaceKey) const { - return m_surfaceDescriptions.value(surfaceKey); + return m_surfaceDescriptions.get(surfaceKey); } isosurface::SurfacePropertyDescription SurfacePropertyTypeDropdown::getSurfacePropertyDescription( const QString &propertyKey) const { - return m_surfacePropertyDescriptions.value(propertyKey); + return m_surfacePropertyDescriptions.get(propertyKey); } /// Resolution Combo box diff --git a/src/dialogs/surfacedropdown.h b/src/dialogs/surfacedropdown.h index e9759c7..e667dae 100644 --- a/src/dialogs/surfacedropdown.h +++ b/src/dialogs/surfacedropdown.h @@ -2,62 +2,64 @@ #include "isosurface_parameters.h" #include - -using SurfaceDescriptionMap = QMap; -using SurfacePropertyDescriptionMap = QMap; - class SurfaceTypeDropdown : public QComboBox { - Q_OBJECT + Q_OBJECT public: - SurfaceTypeDropdown(QWidget *parent = nullptr); - QString current() const; - void setCurrent(QString); + SurfaceTypeDropdown(QWidget *parent = nullptr); + QString current() const; + void setCurrent(QString); - void setDescriptions(const SurfaceDescriptionMap &surfaceDescriptions); - isosurface::SurfaceDescription currentSurfaceDescription() const; + void + setDescriptions(const isosurface::SurfaceDescriptions &surfaceDescriptions); + isosurface::SurfaceDescription currentSurfaceDescription() const; signals: - void selectionChanged(QString); - void descriptionChanged(QString); + void selectionChanged(QString); + void descriptionChanged(QString); private slots: - void onCurrentIndexChanged(int); + void onCurrentIndexChanged(int); + private: - SurfaceDescriptionMap m_surfaceDescriptions; + isosurface::SurfaceDescriptions m_surfaceDescriptions; }; - class SurfacePropertyTypeDropdown : public QComboBox { - Q_OBJECT + Q_OBJECT public: - SurfacePropertyTypeDropdown(QWidget *parent = nullptr); - QString current() const; - void setDescriptions(const SurfaceDescriptionMap &surfaceDescriptions, - const SurfacePropertyDescriptionMap &surfacePropertyDescriptions); - isosurface::SurfacePropertyDescription currentSurfacePropertyDescription() const; + SurfacePropertyTypeDropdown(QWidget *parent = nullptr); + QString current() const; + void + setDescriptions(const isosurface::SurfaceDescriptions &surfaceDescriptions, + const isosurface::SurfacePropertyDescriptions + &surfacePropertyDescriptions); + isosurface::SurfacePropertyDescription + currentSurfacePropertyDescription() const; signals: - void selectionChanged(QString); + void selectionChanged(QString); private slots: - void onCurrentIndexChanged(int); + void onCurrentIndexChanged(int); public slots: - void onSurfaceSelectionChanged(QString); + void onSurfaceSelectionChanged(QString); + private: - SurfaceDescriptionMap m_surfaceDescriptions; - SurfacePropertyDescriptionMap m_surfacePropertyDescriptions; - isosurface::SurfaceDescription getSurfaceDescription(const QString &surfaceKey) const; - isosurface::SurfacePropertyDescription getSurfacePropertyDescription(const QString &propertyKey) const; + isosurface::SurfaceDescriptions m_surfaceDescriptions; + isosurface::SurfacePropertyDescriptions m_surfacePropertyDescriptions; + isosurface::SurfaceDescription + getSurfaceDescription(const QString &surfaceKey) const; + isosurface::SurfacePropertyDescription + getSurfacePropertyDescription(const QString &propertyKey) const; }; - class ResolutionDropdown : public QComboBox { - Q_OBJECT - public: - ResolutionDropdown(QWidget *parent = nullptr); - isosurface::Resolution currentLevel() const; - float currentResolutionValue() const; - - private slots: - void onCurrentIndexChanged(int); - - private: - void populateDropdown(); - isosurface::Resolution m_resolutionLevel{isosurface::Resolution::High}; + Q_OBJECT +public: + ResolutionDropdown(QWidget *parent = nullptr); + isosurface::Resolution currentLevel() const; + float currentResolutionValue() const; + +private slots: + void onCurrentIndexChanged(int); + +private: + void populateDropdown(); + isosurface::Resolution m_resolutionLevel{isosurface::Resolution::High}; }; diff --git a/src/dialogs/surfacegenerationdialog.cpp b/src/dialogs/surfacegenerationdialog.cpp index 30d1563..aab47eb 100644 --- a/src/dialogs/surfacegenerationdialog.cpp +++ b/src/dialogs/surfacegenerationdialog.cpp @@ -22,10 +22,17 @@ void SurfaceGenerationDialog::init() { m_surfacePropertyDescriptions = g->getPropertyDescriptions(); } + for (const auto &k : m_surfaceDescriptions.descriptions) { + qDebug() << k.displayName << k.occName; + } ui->surfaceComboBox->setDescriptions(m_surfaceDescriptions); ui->propertyComboBox->setDescriptions(m_surfaceDescriptions, m_surfacePropertyDescriptions); + for (int i = 0; i < ui->surfaceComboBox->count(); i++) { + qDebug() << ui->surfaceComboBox->itemText(i); + } + updateIsovalue(); setupOrbitalUI(); @@ -49,8 +56,8 @@ void SurfaceGenerationDialog::initConnections() { connect(ui->surfaceComboBox, &SurfaceTypeDropdown::selectionChanged, this, &SurfaceGenerationDialog::surfaceChanged); - connect(ui->propertyComboBox, &SurfacePropertyTypeDropdown::selectionChanged, this, - &SurfaceGenerationDialog::propertyChanged); + connect(ui->propertyComboBox, &SurfacePropertyTypeDropdown::selectionChanged, + this, &SurfaceGenerationDialog::propertyChanged); connect(this, &SurfaceGenerationDialog::accepted, this, &SurfaceGenerationDialog::validate); @@ -87,7 +94,8 @@ isosurface::Kind SurfaceGenerationDialog::currentKind() const { } QString SurfaceGenerationDialog::currentPropertyName() const { - if(ui->propertyComboBox->currentText() == "None") return "None"; + if (ui->propertyComboBox->currentText() == "None") + return "None"; const auto ¤tSurfaceProperty = ui->propertyComboBox->currentSurfacePropertyDescription(); @@ -143,7 +151,7 @@ void SurfaceGenerationDialog::updateSettings() { void SurfaceGenerationDialog::updateIsovalue() { double defaultIsovalue = - m_surfaceDescriptions.value(m_currentSurfaceType).defaultIsovalue; + m_surfaceDescriptions.get(m_currentSurfaceType).defaultIsovalue; ui->isovalueLineEdit->setText(QString::number(defaultIsovalue)); } @@ -170,9 +178,7 @@ void SurfaceGenerationDialog::propertyChanged(QString property) { adjustSize(); } -void SurfaceGenerationDialog::updatePropertyOptions() { - updateOrbitalLabels(); -} +void SurfaceGenerationDialog::updatePropertyOptions() { updateOrbitalLabels(); } void SurfaceGenerationDialog::updateSurfaceOptions() { bool hideSurfaceOptions = true; @@ -197,111 +203,120 @@ void SurfaceGenerationDialog::updateSurfaceOptions() { } void SurfaceGenerationDialog::updateOrbitalLabels() { - ui->orbitalSelectionListWidget->clear(); - m_orbitalLabels.clear(); - bool needsOrbital = needOrbitalBox(); + ui->orbitalSelectionListWidget->clear(); + m_orbitalLabels.clear(); + bool needsOrbital = needOrbitalBox(); - if (!needsOrbital) { - ui->orbitalBox->setVisible(false); - return; - } - ui->orbitalBox->setVisible(true); - - const bool haveExistingWfn = !m_availableWavefunctions.empty() && - ui->wavefunctionCombobox->currentIndex() > 0; - - if (haveExistingWfn) { - // Get current wavefunction - const auto &[wfn, _] = m_availableWavefunctions[ui->wavefunctionCombobox->currentIndex() - 1]; - const int nOcc = wfn->numberOfOccupiedOrbitals(); - const int nOrb = wfn->numberOfOrbitals(); - const auto &energies = wfn->orbitalEnergies(); - - // Generate labels based on actual wavefunction - for (int i = 0; i < nOrb; ++i) { - isosurface::OrbitalDetails info; - info.occupied = i < nOcc; - - if (info.occupied) { - info.index = i; - if (i == nOcc - 1) { - info.label = QString("%1 (HOMO)").arg(i); - } else { - info.label = QString("%1 (HOMO-%2)").arg(i).arg(nOcc - 1 - i); - } - } else { - info.index = i; - if (i == nOcc) { - info.label = QString("%1 (LUMO)").arg(i); - } else { - info.label = QString("%1 (LUMO+%2)").arg(i).arg(i - nOcc); - } - } - - // Filter based on orbital type selection - const int typeIndex = ui->orbitalTypeComboBox->currentIndex(); - if (typeIndex == 0 && !info.occupied) continue; // Occupied only - if (typeIndex == 1 && info.occupied) continue; // Virtual only - - m_orbitalLabels.push_back(info); - - // Add to list widget with energy if available - QString displayText = info.label; - if (energies.size() > i) { - double energy = energies[i]; - displayText += QString(" (%.3f au)").arg(energy); - } - - auto *item = new QListWidgetItem(displayText); - item->setData(Qt::UserRole, i); // Store orbital index - ui->orbitalSelectionListWidget->addItem(item); + if (!needsOrbital) { + ui->orbitalBox->setVisible(false); + return; + } + ui->orbitalBox->setVisible(true); + + const bool haveExistingWfn = !m_availableWavefunctions.empty() && + ui->wavefunctionCombobox->currentIndex() > 0; + + if (haveExistingWfn) { + // Get current wavefunction + const auto &[wfn, _] = + m_availableWavefunctions[ui->wavefunctionCombobox->currentIndex() - 1]; + const int nOcc = wfn->numberOfOccupiedOrbitals(); + const int nOrb = wfn->numberOfOrbitals(); + const auto &energies = wfn->orbitalEnergies(); + + // Generate labels based on actual wavefunction + for (int i = 0; i < nOrb; ++i) { + isosurface::OrbitalDetails info; + info.occupied = i < nOcc; + + if (info.occupied) { + info.index = i; + if (i == nOcc - 1) { + info.label = QString("%1 (HOMO)").arg(i); + } else { + info.label = QString("%1 (HOMO-%2)").arg(i).arg(nOcc - 1 - i); } - } else { - // No wavefunction yet - show generic labels - const int defaultNumOrbitals = 4; // Show reasonable number of options - - for (int i = defaultNumOrbitals-1; i >= 0; --i) { - isosurface::OrbitalDetails info; - info.occupied = true; - info.index = i; - info.label = (i == defaultNumOrbitals-1) ? "HOMO" : QString("HOMO-%1").arg(defaultNumOrbitals-1 - i); - - if (ui->orbitalTypeComboBox->currentIndex() != 1) { // Not virtual only - m_orbitalLabels.push_back(info); - ui->orbitalSelectionListWidget->addItem(info.label); - } + } else { + info.index = i; + if (i == nOcc) { + info.label = QString("%1 (LUMO)").arg(i); + } else { + info.label = QString("%1 (LUMO+%2)").arg(i).arg(i - nOcc); } + } - for (int i = 0; i < defaultNumOrbitals; ++i) { - isosurface::OrbitalDetails info; - info.occupied = false; - info.index = defaultNumOrbitals + i; - info.label = (i == 0) ? "LUMO" : QString("LUMO+%1").arg(i); + // Filter based on orbital type selection + const int typeIndex = ui->orbitalTypeComboBox->currentIndex(); + if (typeIndex == 0 && !info.occupied) + continue; // Occupied only + if (typeIndex == 1 && info.occupied) + continue; // Virtual only - if (ui->orbitalTypeComboBox->currentIndex() != 0) { // Not occupied only - m_orbitalLabels.push_back(info); - ui->orbitalSelectionListWidget->addItem(info.label); - } - } - } -} + m_orbitalLabels.push_back(info); -void SurfaceGenerationDialog::setupOrbitalUI() { - // Replace the simple combobox with a more flexible list widget - ui->orbitalSelectionListWidget->setSelectionMode(QAbstractItemView::ExtendedSelection); + // Add to list widget with energy if available + QString displayText = info.label; + if (energies.size() > i) { + double energy = energies[i]; + displayText += QString(" (%.3f au)").arg(energy); + } - // Add orbital type selector - ui->orbitalTypeComboBox->addItems({"Occupied", "Virtual", "All"}); + auto *item = new QListWidgetItem(displayText); + item->setData(Qt::UserRole, i); // Store orbital index + ui->orbitalSelectionListWidget->addItem(item); + } + } else { + // No wavefunction yet - show generic labels + const int defaultNumOrbitals = 4; // Show reasonable number of options + + for (int i = defaultNumOrbitals - 1; i >= 0; --i) { + isosurface::OrbitalDetails info; + info.occupied = true; + info.index = i; + info.label = (i == defaultNumOrbitals - 1) + ? "HOMO" + : QString("HOMO-%1").arg(defaultNumOrbitals - 1 - i); + + if (ui->orbitalTypeComboBox->currentIndex() != 1) { // Not virtual only + m_orbitalLabels.push_back(info); + ui->orbitalSelectionListWidget->addItem(info.label); + } + } - connect(ui->orbitalTypeComboBox, QOverload::of(&QComboBox::currentIndexChanged), - this, &SurfaceGenerationDialog::updateOrbitalLabels); + for (int i = 0; i < defaultNumOrbitals; ++i) { + isosurface::OrbitalDetails info; + info.occupied = false; + info.index = defaultNumOrbitals + i; + info.label = (i == 0) ? "LUMO" : QString("LUMO+%1").arg(i); - connect(ui->orbitalSelectionListWidget, &QListWidget::itemSelectionChanged, - this, [this]() { - // Enable the OK button only if at least one orbital is selected - bool hasSelection = !ui->orbitalSelectionListWidget->selectedItems().isEmpty(); - ui->buttonBox->button(QDialogButtonBox::Ok)->setEnabled(hasSelection); - }); + if (ui->orbitalTypeComboBox->currentIndex() != 0) { // Not occupied only + m_orbitalLabels.push_back(info); + ui->orbitalSelectionListWidget->addItem(info.label); + } + } + } +} + +void SurfaceGenerationDialog::setupOrbitalUI() { + // Replace the simple combobox with a more flexible list widget + ui->orbitalSelectionListWidget->setSelectionMode( + QAbstractItemView::ExtendedSelection); + + // Add orbital type selector + ui->orbitalTypeComboBox->addItems({"Occupied", "Virtual", "All"}); + + connect(ui->orbitalTypeComboBox, + QOverload::of(&QComboBox::currentIndexChanged), this, + &SurfaceGenerationDialog::updateOrbitalLabels); + + connect( + ui->orbitalSelectionListWidget, &QListWidget::itemSelectionChanged, this, + [this]() { + // Enable the OK button only if at least one orbital is selected + bool hasSelection = + !ui->orbitalSelectionListWidget->selectedItems().isEmpty(); + ui->buttonBox->button(QDialogButtonBox::Ok)->setEnabled(hasSelection); + }); } bool SurfaceGenerationDialog::needIsovalueBox() { @@ -353,7 +368,9 @@ bool SurfaceGenerationDialog::needWavefunction() { const auto ¤tSurface = ui->surfaceComboBox->currentSurfaceDescription(); const auto ¤tSurfaceProperty = ui->propertyComboBox->currentSurfacePropertyDescription(); - qDebug() << "Current surface" << currentSurface.displayName << currentSurface.needsWavefunction << "Current property: " << currentSurfaceProperty.occName + qDebug() << "Current surface" << currentSurface.displayName + << currentSurface.needsWavefunction + << "Current property: " << currentSurfaceProperty.occName << currentSurfaceProperty.needsWavefunction; return currentSurface.needsWavefunction || currentSurfaceProperty.needsWavefunction; diff --git a/src/dialogs/surfacegenerationdialog.h b/src/dialogs/surfacegenerationdialog.h index 17573a6..d491826 100644 --- a/src/dialogs/surfacegenerationdialog.h +++ b/src/dialogs/surfacegenerationdialog.h @@ -6,9 +6,9 @@ #include #include "generic_atom_index.h" +#include "isosurface_parameters.h" #include "molecular_wavefunction.h" #include "ui_surfacegenerationdialog.h" -#include "isosurface_parameters.h" #include "wavefunction_parameters.h" static const char *densityUnits = "e au-3"; @@ -42,7 +42,8 @@ private slots: signals: void surfaceParametersChosenNew(isosurface::Parameters); - void surfaceParametersChosenNeedWavefunction(isosurface::Parameters, wfn::Parameters); + void surfaceParametersChosenNeedWavefunction(isosurface::Parameters, + wfn::Parameters); private: isosurface::Kind currentKind() const; @@ -71,13 +72,13 @@ private slots: wfn::Parameters getCurrentWavefunctionParameters(); std::vector m_atomIndices; - QString m_currentSurfaceType{"hirshfeld"}; + QString m_currentSurfaceType{"Hirshfeld"}; std::vector m_availableWavefunctions; std::vector m_orbitalLabels; - QMap m_surfaceDescriptions; - QMap m_surfacePropertyDescriptions; + isosurface::SurfaceDescriptions m_surfaceDescriptions; + isosurface::SurfacePropertyDescriptions m_surfacePropertyDescriptions; int m_charge{0}, m_multiplicity{1}; Ui::SurfaceGenerationDialog *ui;