Commit f28beeda authored by Tobias WEBER's avatar Tobias WEBER

continued with space groups

parent f633a2d0
......@@ -14,7 +14,8 @@ set(CMAKE_AUTOMOC ON)
set(CMAKE_CXX_STANDARD 17)
add_definitions(-std=c++17 -fconcepts)
include_directories("${PROJECT_SOURCE_DIR}" "../..")
include_directories("${PROJECT_SOURCE_DIR}" "../.."
"../../ext/gemmi/include" "../../ext/gemmi/third_party")
# -----------------------------------------------------------------------------
......
......@@ -7,9 +7,9 @@
*/
#include "browser.h"
#include <sstream>
#include "../structfact/loadcif.h"
#include <QtWidgets/QMenuBar>
#include <sstream>
// ----------------------------------------------------------------------------
......@@ -50,84 +50,87 @@ SgBrowserDlg::SgBrowserDlg(QWidget* pParent, QSettings *pSett)
// load data
SetupSpaceGroups();
SetupMagSpaceGroups();
SetupNuclSpaceGroups();
// ------------------------------------------------------------------------
// connections
connect(m_pTree, &QTreeWidget::currentItemChanged, this, &SgBrowserDlg::SpaceGroupSelected);
connect(treeMagSG, &QTreeWidget::currentItemChanged, this, &SgBrowserDlg::MagSpaceGroupSelected);
connect(treeNuclSG, &QTreeWidget::currentItemChanged, this, &SgBrowserDlg::NuclSpaceGroupSelected);
connect(pShowBNS, &QAction::toggled, this, &SgBrowserDlg::SwitchToBNS);
// synchronise symops when switching the sg tab
connect(tabSGs, &QTabWidget::currentChanged, this, [this](int idx) -> void
{
switch(idx)
{
case 0: MagSpaceGroupSelected(treeMagSG->currentItem()); break;
case 1: NuclSpaceGroupSelected(treeNuclSG->currentItem()); break;
}
});
// ------------------------------------------------------------------------
}
// ----------------------------------------------------------------------------
/**
* load space group list
* load magnetic space group list
*/
void SgBrowserDlg::SetupSpaceGroups()
void SgBrowserDlg::SetupMagSpaceGroups()
{
std::cerr << "Loading space groups ... ";
m_sgs.Load("magsg.info");
std::cerr << "Loading magnetic space groups ... ";
m_magsgs.Load("magsg.info");
std::cerr << "Done." << std::endl;
const auto *pSgs = m_sgs.GetSpacegroups();
if(pSgs)
{
for(const auto& sg : *pSgs)
SetupSpaceGroup(sg);
}
}
const auto *pSgs = m_magsgs.GetSpacegroups();
if(!pSgs) return;
/**
* add space group to tree widget
*/
void SgBrowserDlg::SetupSpaceGroup(const Spacegroup<t_mat_sg, t_vec_sg>& sg)
{
int iNrStruct = sg.GetStructNumber();
int iNrMag = sg.GetMagNumber();
// find top-level item with given structural sg number
auto get_topsg = [](QTreeWidget *pTree, int iStructNr) -> QTreeWidgetItem*
for(const auto& sg : *pSgs)
{
for(int item=0; item<pTree->topLevelItemCount(); ++item)
int iNrStruct = sg.GetStructNumber();
int iNrMag = sg.GetMagNumber();
// find top-level item with given structural sg number
auto get_topsg = [](QTreeWidget *pTree, int iStructNr) -> QTreeWidgetItem*
{
QTreeWidgetItem *pItem = pTree->topLevelItem(item);
if(!pItem) continue;
for(int item=0; item<pTree->topLevelItemCount(); ++item)
{
QTreeWidgetItem *pItem = pTree->topLevelItem(item);
if(!pItem) continue;
if(pItem->data(0, Qt::UserRole) == iStructNr)
return pItem;
}
if(pItem->data(0, Qt::UserRole) == iStructNr)
return pItem;
}
return nullptr;
};
return nullptr;
};
// find existing top-level structural space group or insert new one
auto *pTopItem = get_topsg(m_pTree, iNrStruct);
if(!pTopItem)
{
QString structname = ("(" + std::to_string(iNrStruct) + ") " + sg.GetName()).c_str();
// find existing top-level structural space group or insert new one
auto *pTopItem = get_topsg(treeMagSG, iNrStruct);
if(!pTopItem)
{
QString structname = ("(" + std::to_string(iNrStruct) + ") " + sg.GetName()).c_str();
pTopItem = new QTreeWidgetItem();
pTopItem->setText(0, structname);
pTopItem->setData(0, Qt::UserRole, iNrStruct);
pTopItem->setData(0, Qt::UserRole+1, iNrMag);
m_pTree->addTopLevelItem(pTopItem);
}
pTopItem = new QTreeWidgetItem();
pTopItem->setText(0, structname);
pTopItem->setData(0, Qt::UserRole, iNrStruct);
pTopItem->setData(0, Qt::UserRole+1, iNrMag);
treeMagSG->addTopLevelItem(pTopItem);
}
// create magnetic group and add it as sub-item for the corresponding structural group
QString magname = ("(" + sg.GetNumber() + ") " + sg.GetName()).c_str();
// create magnetic group and add it as sub-item for the corresponding structural group
QString magname = ("(" + sg.GetNumber() + ") " + sg.GetName()).c_str();
auto *pSubItem = new QTreeWidgetItem();
pSubItem->setText(0, magname);
pSubItem->setData(0, Qt::UserRole, iNrStruct);
pSubItem->setData(0, Qt::UserRole+1, iNrMag);
pTopItem->addChild(pSubItem);
auto *pSubItem = new QTreeWidgetItem();
pSubItem->setText(0, magname);
pSubItem->setData(0, Qt::UserRole, iNrStruct);
pSubItem->setData(0, Qt::UserRole+1, iNrMag);
pTopItem->addChild(pSubItem);
}
}
// ----------------------------------------------------------------------------
/**
......@@ -136,25 +139,26 @@ void SgBrowserDlg::SetupSpaceGroup(const Spacegroup<t_mat_sg, t_vec_sg>& sg)
void SgBrowserDlg::SwitchToBNS(bool bBNS)
{
m_showBNS = bBNS;
SpaceGroupSelected(m_pTree->currentItem());
MagSpaceGroupSelected(treeMagSG->currentItem());
}
/**
* space group selected
* magnetic space group selected
*/
void SgBrowserDlg::SpaceGroupSelected(QTreeWidgetItem *pItem)
void SgBrowserDlg::MagSpaceGroupSelected(QTreeWidgetItem *pItem)
{
if(!pItem) return;
// clean up
m_pSymOps->clear();
m_pWyc->clear();
listSymOps->clear();
listWyc->clear();
int iNrStruct = pItem->data(0, Qt::UserRole).toInt();
int iNrMag = pItem->data(0, Qt::UserRole+1).toInt();
const auto* pSg = m_sgs.GetSpacegroupByNumber(iNrStruct, iNrMag);
const auto* pSg = m_magsgs.GetSpacegroupByNumber(iNrStruct, iNrMag);
if(!pSg) return;
......@@ -233,7 +237,7 @@ void SgBrowserDlg::SpaceGroupSelected(QTreeWidgetItem *pItem)
auto *pOpItem = new QListWidgetItem();
pOpItem->setText(print_sym(rot, trans, inv).c_str());
m_pSymOps->addItem(pOpItem);
listSymOps->addItem(pOpItem);
}
}
......@@ -259,13 +263,136 @@ void SgBrowserDlg::SpaceGroupSelected(QTreeWidgetItem *pItem)
pWycItem->addChild(pSubItem);
}
m_pWyc->addTopLevelItem(pWycItem);
listWyc->addTopLevelItem(pWycItem);
pWycItem->setExpanded(true);
}
}
}
// ----------------------------------------------------------------------------
// ----------------------------------------------------------------------------
/**
* load nuclear space group list
*/
void SgBrowserDlg::SetupNuclSpaceGroups()
{
m_nuclsgs = get_sgs<t_mat44_sg>(false, false);
for(int iSG=0; iSG<static_cast<int>(m_nuclsgs.size()); ++iSG)
{
int iNrStruct = std::get<0>(m_nuclsgs[iSG]);
const std::string& strName = std::get<1>(m_nuclsgs[iSG]);
// find top-level item with given structural sg number
auto get_topsg = [](QTreeWidget *pTree, int iStructNr) -> QTreeWidgetItem*
{
for(int item=0; item<pTree->topLevelItemCount(); ++item)
{
QTreeWidgetItem *pItem = pTree->topLevelItem(item);
if(!pItem) continue;
if(pItem->data(0, Qt::UserRole) == iStructNr)
return pItem;
}
return nullptr;
};
// find existing top-level structural space group or insert new one
auto *pTopItem = get_topsg(treeNuclSG, iNrStruct);
if(!pTopItem)
{
QString structname = ("(" + std::to_string(iNrStruct) + ") " + strName).c_str();
pTopItem = new QTreeWidgetItem();
pTopItem->setText(0, structname);
pTopItem->setData(0, Qt::UserRole, iNrStruct);
pTopItem->setData(0, Qt::UserRole+1, iSG);
treeNuclSG->addTopLevelItem(pTopItem);
}
// create nuclear group config and add it as sub-item for the corresponding structural group
QString magname = ("(" + std::to_string(iNrStruct) +
"-" + std::to_string(pTopItem->childCount()+1) + ") " + strName).c_str();
auto *pSubItem = new QTreeWidgetItem();
pSubItem->setText(0, magname);
pSubItem->setData(0, Qt::UserRole, iNrStruct);
pSubItem->setData(0, Qt::UserRole+1, iSG);
pTopItem->addChild(pSubItem);
}
}
/**
* nuclear space group selected
*/
void SgBrowserDlg::NuclSpaceGroupSelected(QTreeWidgetItem *pItem)
{
if(!pItem) return;
// clean up
listSymOps->clear();
listWyc->clear();
int iNrStruct = pItem->data(0, Qt::UserRole).toInt();
int iNrSG = pItem->data(0, Qt::UserRole+1).toInt();
if(iNrSG < 0 || iNrSG >= m_nuclsgs.size())
return;
const auto& sg = m_nuclsgs[iNrSG];
const auto& trafos = std::get<2>(sg);
// print a symmetry operator
auto print_sym = [](const t_mat44_sg& mat) -> std::string
{
std::ostringstream ostr;
for(std::size_t i=0; i<3; ++i)
{
// rotation matrix
ostr << "( ";
for(std::size_t j=0; j<3; ++j)
ostr << std::setw(ostr.precision()*1.5) << std::right << mat(i,j);
ostr << " )";
// translation vector
ostr << std::setw(ostr.precision()*2) << std::right << "( ";
ostr << std::setw(ostr.precision()*1.5) << std::right << mat(i, 3);
ostr << " )";
if(i < mat.size1()-2)
ostr << "\n";
}
return ostr.str();
};
// iterate over symmetries
for(std::size_t iOp=0; iOp<trafos.size(); ++iOp)
{
const auto& trafo = trafos[iOp];
auto *pOpItem = new QListWidgetItem();
pOpItem->setText(print_sym(trafo).c_str());
listSymOps->addItem(pOpItem);
}
}
// ----------------------------------------------------------------------------
// ----------------------------------------------------------------------------
void SgBrowserDlg::showEvent(QShowEvent *pEvt)
{
QDialog::showEvent(pEvt);
......@@ -289,5 +416,4 @@ void SgBrowserDlg::closeEvent(QCloseEvent *pEvt)
QDialog::closeEvent(pEvt);
}
// ----------------------------------------------------------------------------
......@@ -25,18 +25,22 @@
using t_real_sg = double;
using t_vec_sg = m::qvec_adapter<int, 3, t_real_sg, QGenericMatrix>;
using t_mat_sg = m::qmat_adapter<int, 3, 3, t_real_sg, QGenericMatrix>;
using t_mat44_sg = m::qmat_adapter<int, 4, 4, t_real_sg, QGenericMatrix>;
class SgBrowserDlg : public QDialog, Ui::SgBrowserDlg
{
private:
QSettings *m_pSettings = nullptr;
Spacegroups<t_mat_sg, t_vec_sg> m_sgs;
Spacegroups<t_mat_sg, t_vec_sg> m_magsgs;
std::vector<std::tuple<int, std::string, std::vector<t_mat44_sg>>> m_nuclsgs;
bool m_showBNS = true;
private:
void SetupSpaceGroup(const Spacegroup<t_mat_sg, t_vec_sg>& sg);
void SetupSpaceGroups();
void SetupMagSpaceGroups();
void SetupNuclSpaceGroups();
protected:
virtual void showEvent(QShowEvent *pEvt) override;
......@@ -44,7 +48,9 @@ protected:
virtual void closeEvent(QCloseEvent *pEvt) override;
// slots
void SpaceGroupSelected(QTreeWidgetItem *pItem);
void MagSpaceGroupSelected(QTreeWidgetItem *pItem);
void NuclSpaceGroupSelected(QTreeWidgetItem *pItem);
void SwitchToBNS(bool bBNS);
public:
......
<?xml version="1.0" encoding="UTF-8"?>
<!--
/**
* space group browser
* @author Tobias Weber <tweber@ill.fr>
* @date Apr-2018
* @license GPLv3, see 'LICENSE' file
* @desc The present version was forked on 8-Nov-2018 from the privately developed "magtools" project (https://github.com/t-weber/magtools).
*/
-->
<ui version="4.0">
<class>SgBrowserDlg</class>
<widget class="QDialog" name="SgBrowserDlg">
......@@ -15,8 +6,8 @@
<rect>
<x>0</x>
<y>0</y>
<width>640</width>
<height>420</height>
<width>610</width>
<height>440</height>
</rect>
</property>
<property name="windowTitle">
......@@ -25,7 +16,7 @@
<property name="sizeGripEnabled">
<bool>true</bool>
</property>
<layout class="QGridLayout" name="gridLayout">
<layout class="QGridLayout" name="gridLayout_4">
<property name="leftMargin">
<number>4</number>
</property>
......@@ -43,38 +34,137 @@
</property>
<item row="0" column="0">
<widget class="QSplitter" name="splitter">
<property name="frameShape">
<enum>QFrame::NoFrame</enum>
</property>
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<widget class="QTreeWidget" name="m_pTree">
<widget class="QTabWidget" name="tabSGs">
<property name="sizePolicy">
<sizepolicy hsizetype="Expanding" vsizetype="Expanding">
<horstretch>1</horstretch>
<verstretch>1</verstretch>
</sizepolicy>
</property>
<property name="showDropIndicator" stdset="0">
<bool>false</bool>
</property>
<property name="alternatingRowColors">
<bool>true</bool>
</property>
<property name="allColumnsShowFocus">
<bool>true</bool>
<property name="currentIndex">
<number>0</number>
</property>
<attribute name="headerVisible">
<bool>false</bool>
</attribute>
<column>
<property name="text">
<string notr="true">1</string>
</property>
</column>
<widget class="QWidget" name="tabMag">
<attribute name="title">
<string>Magnetic</string>
</attribute>
<layout class="QGridLayout" name="gridLayout">
<property name="leftMargin">
<number>4</number>
</property>
<property name="topMargin">
<number>4</number>
</property>
<property name="rightMargin">
<number>4</number>
</property>
<property name="bottomMargin">
<number>4</number>
</property>
<property name="spacing">
<number>2</number>
</property>
<item row="0" column="0">
<widget class="QTreeWidget" name="treeMagSG">
<property name="sizePolicy">
<sizepolicy hsizetype="Expanding" vsizetype="Expanding">
<horstretch>1</horstretch>
<verstretch>1</verstretch>
</sizepolicy>
</property>
<property name="editTriggers">
<set>QAbstractItemView::NoEditTriggers</set>
</property>
<property name="showDropIndicator" stdset="0">
<bool>false</bool>
</property>
<property name="alternatingRowColors">
<bool>true</bool>
</property>
<property name="allColumnsShowFocus">
<bool>true</bool>
</property>
<attribute name="headerVisible">
<bool>false</bool>
</attribute>
<column>
<property name="text">
<string notr="true">1</string>
</property>
</column>
</widget>
</item>
</layout>
</widget>
<widget class="QWidget" name="tabNucl">
<attribute name="title">
<string>Nuclear</string>
</attribute>
<layout class="QGridLayout" name="gridLayout_5">
<property name="leftMargin">
<number>4</number>
</property>
<property name="topMargin">
<number>4</number>
</property>
<property name="rightMargin">
<number>4</number>
</property>
<property name="bottomMargin">
<number>4</number>
</property>
<property name="spacing">
<number>2</number>
</property>
<item row="0" column="0">
<widget class="QTreeWidget" name="treeNuclSG">
<property name="sizePolicy">
<sizepolicy hsizetype="Expanding" vsizetype="Expanding">
<horstretch>1</horstretch>
<verstretch>1</verstretch>
</sizepolicy>
</property>
<property name="editTriggers">
<set>QAbstractItemView::NoEditTriggers</set>
</property>
<property name="tabKeyNavigation">
<bool>false</bool>
</property>
<property name="showDropIndicator" stdset="0">
<bool>false</bool>
</property>
<property name="dragDropOverwriteMode">
<bool>false</bool>
</property>
<property name="alternatingRowColors">
<bool>true</bool>
</property>
<property name="selectionMode">
<enum>QAbstractItemView::SingleSelection</enum>
</property>
<property name="selectionBehavior">
<enum>QAbstractItemView::SelectRows</enum>
</property>
<property name="allColumnsShowFocus">
<bool>true</bool>
</property>
<property name="headerHidden">
<bool>true</bool>
</property>
<column>
<property name="text">
<string notr="true">1</string>
</property>
</column>
</widget>
</item>
</layout>
</widget>
</widget>
<widget class="QTabWidget" name="tabWidget">
<widget class="QTabWidget" name="tabOps">
<property name="sizePolicy">
<sizepolicy hsizetype="Expanding" vsizetype="Expanding">
<horstretch>2</horstretch>
......@@ -105,7 +195,13 @@
<number>2</number>
</property>
<item row="0" column="0">
<widget class="QListWidget" name="m_pSymOps">
<widget class="QListWidget" name="listSymOps">
<property name="sizePolicy">
<sizepolicy hsizetype="Expanding" vsizetype="Expanding">
<horstretch>1</horstretch>
<verstretch>1</verstretch>
</sizepolicy>
</property>
<property name="showDropIndicator" stdset="0">
<bool>false</bool>
</property>
......@@ -143,7 +239,7 @@
<number>2</number>
</property>
<item row="0" column="0">
<widget class="QTreeWidget" name="m_pWyc">
<widget class="QTreeWidget" name="listWyc">
<property name="showDropIndicator" stdset="0">
<bool>false</bool>
</property>
......@@ -174,10 +270,12 @@
</layout>
</widget>
<tabstops>
<tabstop>m_pTree</tabstop>
<tabstop>tabWidget</tabstop>
<tabstop>m_pSymOps</tabstop>
<tabstop>m_pWyc</tabstop>
<tabstop>tabSGs</tabstop>
<tabstop>treeMagSG</tabstop>
<tabstop>treeNuclSG</tabstop>
<tabstop>tabOps</tabstop>
<tabstop>listSymOps</tabstop>
<tabstop>listWyc</tabstop>
</tabstops>
<resources/>
<connections/>
......
......@@ -182,14 +182,16 @@ load_cif(const std::string& filename, t_real eps=1e-6)
*/
template<class t_mat, class t_real = typename t_mat::value_type>
std::vector<std::tuple<int, std::string, std::vector<t_mat>>>
get_sgs()
get_sgs(bool bAddNr=true, bool bAddHall=true)
{
std::vector<std::tuple<int, std::string, std::vector<t_mat>>> sgs;
for(const auto &sg : gemmi::spacegroup_tables::main)
{
std::ostringstream ostrDescr;
ostrDescr << "#" << sg.number << ": " << sg.hm << " (" << sg.hall << ")";
if(bAddNr) ostrDescr << "#" << sg.number << ": ";
ostrDescr << sg.hm;
if(bAddHall) ostrDescr << " (" << sg.hall << ")";
std::vector<t_mat> ops;
for(const auto &op : sg.operations().all_ops_sorted())
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment