Verified Commit e54566a3 authored by Tobias WEBER's avatar Tobias WEBER
Browse files

cleanups

parent 6f14e98e
......@@ -59,12 +59,16 @@ if(BUILD_LIB)
add_definitions(-DBUILD_LIB)
add_library(takin_magstructfact SHARED
magstructfact.cpp magstructfact.h
magstructfact.cpp magstructfact_file.cpp
magstructfact_plot.cpp magstructfact_main.cpp
magstructfact_nuclei.cpp magstructfact.h
../../tlibs2/libs/qt/gl.cpp ../../tlibs2/libs/qt/gl.h
../../tlibs2/libs/qt/glplot.cpp ../../tlibs2/libs/qt/glplot.h)
else()
add_executable(takin_magstructfact
magstructfact.cpp magstructfact.h
magstructfact.cpp magstructfact_file.cpp
magstructfact_plot.cpp magstructfact_main.cpp
magstructfact_nuclei.cpp magstructfact.h
../../tlibs2/libs/qt/gl.cpp ../../tlibs2/libs/qt/gl.h
../../tlibs2/libs/qt/glplot.cpp ../../tlibs2/libs/qt/glplot.h)
endif()
......
This diff is collapsed.
......@@ -50,6 +50,32 @@
#include "tlibs2/libs/qt/numerictablewidgetitem.h"
// columns of Fourier components table
enum : int
{
COL_NAME = 0,
COL_X, COL_Y, COL_Z, // position
COL_M_MAG, // scale factor of FC
COL_ReM_X, COL_ReM_Y, COL_ReM_Z, // fourier components
COL_ImM_X, COL_ImM_Y, COL_ImM_Z,
COL_RAD, // drawing radius
COL_COL, // colour
NUM_COLS
};
// columns of propagation vectors table
enum : int
{
PROP_COL_NAME = 0,
PROP_COL_X, PROP_COL_Y, PROP_COL_Z, // propagation direction
PROP_COL_CONJ, // conjugate fourier component for this propagation ve>
PROP_NUM_COLS
};
using t_real = double;
using t_cplx = std::complex<t_real>;
using t_vec = tl2::vec<t_real, std::vector>;
......@@ -64,6 +90,19 @@ using t_vec_gl = tl2::t_vec_gl;
using t_mat_gl = tl2::t_mat_gl;
constexpr t_real g_eps = 1e-6;
constexpr int g_prec = 6;
struct PowderLine
{
t_real Q{};
t_real I{};
std::size_t num_peaks = 0;
std::string peaks;
};
struct NuclPos
{
// physically meaningful data
......@@ -85,6 +124,7 @@ public:
MagStructFactDlg(QWidget* pParent = nullptr);
virtual ~MagStructFactDlg() = default;
protected:
QSettings *m_sett = nullptr;
QMenuBar *m_menu = nullptr;
......@@ -130,6 +170,7 @@ protected:
t_mat m_crystA = tl2::unit<t_mat>(3);
t_mat m_crystB = tl2::unit<t_mat>(3);
protected:
// general table operations
void MoveTabItemUp(QTableWidget *pTab);
......@@ -175,6 +216,7 @@ protected:
virtual void closeEvent(QCloseEvent *evt) override;
private:
int m_iCursorRow = -1;
......
/**
* magnetic structure factor tool
* @author Tobias Weber <tweber@ill.fr>
* @date Jan-2019
* @license GPLv3, see 'LICENSE' file
* @desc The present version was forked on 28-Dec-2018 from my privately developed "misc" project (https://github.com/t-weber/misc).
*
* ----------------------------------------------------------------------------
* mag-core (part of the Takin software suite)
* Copyright (C) 2018-2021 Tobias WEBER (Institut Laue-Langevin (ILL),
* Grenoble, France).
* "misc" project
* Copyright (C) 2017-2021 Tobias WEBER (privately developed).
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, version 3 of the License.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
* ----------------------------------------------------------------------------
*/
#include "magstructfact.h"
#include <QtWidgets/QFileDialog>
#include <QtWidgets/QMessageBox>
#include <iostream>
#include <fstream>
#include <random>
#include <chrono>
#include <boost/property_tree/ptree.hpp>
#include <boost/property_tree/xml_parser.hpp>
#include <boost/algorithm/string.hpp>
#include <boost/algorithm/string/replace.hpp>
namespace algo = boost::algorithm;
namespace pt = boost::property_tree;
#include "../structfact/loadcif.h"
#include "tlibs2/libs/maths.h"
#include "tlibs2/libs/phys.h"
#include "tlibs2/libs/algos.h"
#include "tlibs2/libs/qt/helper.h"
using namespace tl2_ops;
void MagStructFactDlg::Load()
{
m_ignoreCalc = 1;
try
{
QString dirLast = m_sett->value("dir", "").toString();
QString filename = QFileDialog::getOpenFileName(this, "Load File", dirLast, "XML Files (*.xml *.XML)");
if(filename=="" || !QFile::exists(filename))
return;
m_sett->setValue("dir", QFileInfo(filename).path());
pt::ptree node;
std::ifstream ifstr{filename.toStdString()};
pt::read_xml(ifstr, node);
// check signature
if(auto optInfo = node.get_optional<std::string>("sfact.meta.info");
!optInfo || !(*optInfo==std::string{"magsfact_tool"} || *optInfo==std::string{"sfact_tool"}))
{
QMessageBox::critical(this, "Structure Factors", "Unrecognised file format.");
return;
}
else if(*optInfo == std::string{"sfact_tool"})
{
QMessageBox::warning(this, "Structure Factors", "File only contains nuclear information. Trying to load.");
}
// clear old tables
DelTabItem(-1);
DelPropItem(-1);
// lattice
if(auto opt = node.get_optional<t_real>("sfact.xtal.a"); opt)
{
std::ostringstream ostr; ostr.precision(g_prec); ostr << *opt;
m_editA->setText(ostr.str().c_str());
}
if(auto opt = node.get_optional<t_real>("sfact.xtal.b"); opt)
{
std::ostringstream ostr; ostr.precision(g_prec); ostr << *opt;
m_editB->setText(ostr.str().c_str());
}
if(auto opt = node.get_optional<t_real>("sfact.xtal.c"); opt)
{
std::ostringstream ostr; ostr.precision(g_prec); ostr << *opt;
m_editC->setText(ostr.str().c_str());
}
if(auto opt = node.get_optional<t_real>("sfact.xtal.alpha"); opt)
{
std::ostringstream ostr; ostr.precision(g_prec); ostr << *opt;
m_editAlpha->setText(ostr.str().c_str());
}
if(auto opt = node.get_optional<t_real>("sfact.xtal.beta"); opt)
{
std::ostringstream ostr; ostr.precision(g_prec); ostr << *opt;
m_editBeta->setText(ostr.str().c_str());
}
if(auto opt = node.get_optional<t_real>("sfact.xtal.gamma"); opt)
{
std::ostringstream ostr; ostr.precision(g_prec); ostr << *opt;
m_editGamma->setText(ostr.str().c_str());
}
if(auto opt = node.get_optional<int>("sfact.order"); opt)
{
m_maxBZ->setValue(*opt);
}
if(auto opt = node.get_optional<int>("sfact.scorder_x"); opt)
{
m_maxSC[0]->setValue(*opt);
}
if(auto opt = node.get_optional<int>("sfact.scorder_y"); opt)
{
m_maxSC[1]->setValue(*opt);
}
if(auto opt = node.get_optional<int>("sfact.scorder_z"); opt)
{
m_maxSC[2]->setValue(*opt);
}
if(auto opt = node.get_optional<int>("sfact.removezeroes"); opt)
{
m_RemoveZeroes->setChecked(*opt != 0);
}
if(auto opt = node.get_optional<int>("sfact.sg_idx"); opt)
{
m_comboSG->setCurrentIndex(*opt);
}
// fourier components
if(auto nuclei = node.get_child_optional("sfact.nuclei"); nuclei)
{
for(const auto &nucl : *nuclei)
{
auto optName = nucl.second.get<std::string>("name", "n/a");
auto optMMag = nucl.second.get<t_real>("M_mag", 1.);
auto optX = nucl.second.get<t_real>("x", 0.);
auto optY = nucl.second.get<t_real>("y", 0.);
auto optZ = nucl.second.get<t_real>("z", 0.);
auto optReMX = nucl.second.get<t_real>("ReMx", 0.);
auto optReMY = nucl.second.get<t_real>("ReMy", 0.);
auto optReMZ = nucl.second.get<t_real>("ReMz", 0.);
auto optImMX = nucl.second.get<t_real>("ImMx", 0.);
auto optImMY = nucl.second.get<t_real>("ImMy", 0.);
auto optImMZ = nucl.second.get<t_real>("ImMz", 0.);
auto optRad = nucl.second.get<t_real>("rad", 1.);
auto optCol = nucl.second.get<std::string>("col", "#ff0000");
AddTabItem(-1, optName, optMMag, optX, optY, optZ,
optReMX, optReMY, optReMZ, optImMX, optImMY, optImMZ,
optRad, optCol);
}
}
// propagation vectors
if(auto propvecs = node.get_child_optional("sfact.propvecs"); propvecs)
{
for(const auto &propvec : *propvecs)
{
auto optName = propvec.second.get<std::string>("name", "n/a");
auto optX = propvec.second.get<t_real>("x", 0.);
auto optY = propvec.second.get<t_real>("y", 0.);
auto optZ = propvec.second.get<t_real>("z", 0.);
auto optConj = propvec.second.get<int>("conjFC", 0);
AddPropItem(-1, optName, optX, optY, optZ, optConj!=0);
}
}
}
catch(const std::exception& ex)
{
QMessageBox::critical(this, "Structure Factors", ex.what());
}
m_ignoreCalc = 0;
CalcB(false);
Calc();
}
void MagStructFactDlg::Save()
{
QString dirLast = m_sett->value("dir", "").toString();
QString filename = QFileDialog::getSaveFileName(this, "Save File", dirLast, "XML Files (*.xml *.XML)");
if(filename=="")
return;
m_sett->setValue("dir", QFileInfo(filename).path());
pt::ptree node;
node.put<std::string>("sfact.meta.info", "magsfact_tool");
node.put<std::string>("sfact.meta.date", tl2::epoch_to_str<t_real>(tl2::epoch<t_real>()));
// lattice
t_real a,b,c, alpha,beta,gamma;
std::istringstream{m_editA->text().toStdString()} >> a;
std::istringstream{m_editB->text().toStdString()} >> b;
std::istringstream{m_editC->text().toStdString()} >> c;
std::istringstream{m_editAlpha->text().toStdString()} >> alpha;
std::istringstream{m_editBeta->text().toStdString()} >> beta;
std::istringstream{m_editGamma->text().toStdString()} >> gamma;
node.put<t_real>("sfact.xtal.a", a);
node.put<t_real>("sfact.xtal.b", b);
node.put<t_real>("sfact.xtal.c", c);
node.put<t_real>("sfact.xtal.alpha", alpha);
node.put<t_real>("sfact.xtal.beta", beta);
node.put<t_real>("sfact.xtal.gamma", gamma);
node.put<int>("sfact.order", m_maxBZ->value());
node.put<int>("sfact.scorder_x", m_maxSC[0]->value());
node.put<int>("sfact.scorder_y", m_maxSC[1]->value());
node.put<int>("sfact.scorder_z", m_maxSC[2]->value());
node.put<int>("sfact.removezeroes", m_RemoveZeroes->isChecked());
node.put<int>("sfact.sg_idx", m_comboSG->currentIndex());
// fourier component list
for(int row=0; row<m_nuclei->rowCount(); ++row)
{
t_real MMag{}, x{},y{},z{}, ReMx{}, ReMy{}, ReMz{}, ImMx{}, ImMy{}, ImMz{}, scale{};
std::istringstream{m_nuclei->item(row, COL_M_MAG)->text().toStdString()} >> MMag;
std::istringstream{m_nuclei->item(row, COL_X)->text().toStdString()} >> x;
std::istringstream{m_nuclei->item(row, COL_Y)->text().toStdString()} >> y;
std::istringstream{m_nuclei->item(row, COL_Z)->text().toStdString()} >> z;
std::istringstream{m_nuclei->item(row, COL_ReM_X)->text().toStdString()} >> ReMx;
std::istringstream{m_nuclei->item(row, COL_ReM_Y)->text().toStdString()} >> ReMy;
std::istringstream{m_nuclei->item(row, COL_ReM_Z)->text().toStdString()} >> ReMz;
std::istringstream{m_nuclei->item(row, COL_ImM_X)->text().toStdString()} >> ImMx;
std::istringstream{m_nuclei->item(row, COL_ImM_Y)->text().toStdString()} >> ImMy;
std::istringstream{m_nuclei->item(row, COL_ImM_Z)->text().toStdString()} >> ImMz;
std::istringstream{m_nuclei->item(row, COL_RAD)->text().toStdString()} >> scale;
pt::ptree itemNode;
itemNode.put<std::string>("name", m_nuclei->item(row, COL_NAME)->text().toStdString());
itemNode.put<t_real>("M_mag", MMag);
itemNode.put<t_real>("x", x);
itemNode.put<t_real>("y", y);
itemNode.put<t_real>("z", z);
itemNode.put<t_real>("ReMx", ReMx);
itemNode.put<t_real>("ReMy", ReMy);
itemNode.put<t_real>("ReMz", ReMz);
itemNode.put<t_real>("ImMx", ImMx);
itemNode.put<t_real>("ImMy", ImMy);
itemNode.put<t_real>("ImMz", ImMz);
itemNode.put<t_real>("rad", scale);
itemNode.put<std::string>("col", m_nuclei->item(row, COL_COL)->text().toStdString());
node.add_child("sfact.nuclei.nucleus", itemNode);
}
// propagation vectors list
for(int row=0; row<m_propvecs->rowCount(); ++row)
{
t_real x{},y{},z{};
int iConj{0};
std::istringstream{m_propvecs->item(row, PROP_COL_X)->text().toStdString()} >> x;
std::istringstream{m_propvecs->item(row, PROP_COL_Y)->text().toStdString()} >> y;
std::istringstream{m_propvecs->item(row, PROP_COL_Z)->text().toStdString()} >> z;
std::istringstream{m_propvecs->item(row, PROP_COL_CONJ)->text().toStdString()} >> iConj;
pt::ptree itemNode;
itemNode.put<std::string>("name", m_propvecs->item(row, PROP_COL_NAME)->text().toStdString());
itemNode.put<t_real>("x", x);
itemNode.put<t_real>("y", y);
itemNode.put<t_real>("z", z);
itemNode.put<int>("conjFC", iConj);
node.add_child("sfact.propvecs.vec", itemNode);
}
std::ofstream ofstr{filename.toStdString()};
if(!ofstr)
{
QMessageBox::critical(this, "Structure Factors", "Cannot open file for writing.");
return;
}
ofstr.precision(g_prec);
pt::write_xml(ofstr, node, pt::xml_writer_make_settings('\t', 1, std::string{"utf-8"}));
}
/**
* load an mCIF
*/
void MagStructFactDlg::ImportCIF()
{/*
QString dirLast = m_sett->value("dir_cif", "").toString();
QString filename = QFileDialog::getOpenFileName(this, "Import CIF", dirLast, "CIF Files (*.cif *.CIF)");
if(filename=="" || !QFile::exists(filename))
return;
m_sett->setValue("dir_cif", QFileInfo(filename).path());
auto [errstr, atoms, generatedatoms, atomnames, lattice, symops] =
load_cif<t_vec, t_mat>(filename.toStdString(), g_eps);
if(errstr)
{
QMessageBox::critical(this, "Structure Factors", errstr);
return;
}
// clear old nuclei
DelTabItem(-1);
DelPropItem(-1);
// lattice
{
std::ostringstream ostr; ostr.precision(g_prec); ostr << lattice.a;
m_editA->setText(ostr.str().c_str());
}
{
std::ostringstream ostr; ostr.precision(g_prec); ostr << lattice.b;
m_editB->setText(ostr.str().c_str());
}
{
std::ostringstream ostr; ostr.precision(g_prec); ostr << lattice.c;
m_editC->setText(ostr.str().c_str());
}
{
std::ostringstream ostr; ostr.precision(g_prec); ostr << lattice.alpha;
m_editAlpha->setText(ostr.str().c_str());
}
{
std::ostringstream ostr; ostr.precision(g_prec); ostr << lattice.beta;
m_editBeta->setText(ostr.str().c_str());
}
{
std::ostringstream ostr; ostr.precision(g_prec); ostr << lattice.gamma;
m_editGamma->setText(ostr.str().c_str());
}
CalcB(false);
// atoms
std::mt19937 gen{tl2::epoch<unsigned int>()};
for(std::size_t atomnum=0; atomnum<atoms.size(); ++atomnum)
{
// random colour
std::ostringstream ostrcol;
std::uniform_int_distribution<int> dist{0, 255};
ostrcol << "#" << std::hex << std::setw(2) << std::setfill('0') << dist(gen)
<< std::setw(2) << std::setfill('0') << dist(gen)
<< std::setw(2) << std::setfill('0') << dist(gen);
for(std::size_t symnr=0; symnr<generatedatoms[atomnum].size(); ++symnr)
{
AddTabItem(-1, atomnames[atomnum], 0, 0,
generatedatoms[atomnum][symnr][0], generatedatoms[atomnum][symnr][1], generatedatoms[atomnum][symnr][2],
1, ostrcol.str());
}
}*/
}
/**
* magnetic structure factor tool
* @author Tobias Weber <tweber@ill.fr>
* @date Jan-2019
* @license GPLv3, see 'LICENSE' file
* @desc The present version was forked on 28-Dec-2018 from my privately developed "misc" project (https://github.com/t-weber/misc).
*
* ----------------------------------------------------------------------------
* mag-core (part of the Takin software suite)
* Copyright (C) 2018-2021 Tobias WEBER (Institut Laue-Langevin (ILL),
* Grenoble, France).
* "misc" project
* Copyright (C) 2017-2021 Tobias WEBER (privately developed).
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, version 3 of the License.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
* ----------------------------------------------------------------------------
*/
#include "magstructfact.h"
#include <QtCore/QDir>
#include <QtWidgets/QApplication>
#include <iostream>
#include "tlibs2/libs/qt/helper.h"
using namespace tl2_ops;
#ifndef BUILD_LIB // build application
int main(int argc, char** argv)
{
tl2::set_gl_format(1, _GL_MAJ_VER, _GL_MIN_VER, 8);
tl2::set_locales();
QApplication::addLibraryPath(QString(".") + QDir::separator() + "qtplugins");
auto app = std::make_unique<QApplication>(argc, argv);
auto dlg = std::make_unique<MagStructFactDlg>(nullptr);
dlg->show();
return app->exec();
}
#else // build library
#include <boost/dll/alias.hpp>
/**
* initialise plugin
*/
bool init()
{
tl2::set_gl_format(1, _GL_MAJ_VER, _GL_MIN_VER, 8);
tl2::set_locales();
return true;
}
/**
* plugin descriptor
* type; title; description
*/
const char* descr()
{
return "dlg;Magnetic Structure Factors;Calculates magnetic structure factors.";
}
/**
* create the plugin main dialog
*/
//std::shared_ptr<QDialog> create(QWidget *pParent)
QDialog* create(QWidget *pParent)
{
//std::cout << "In " << __FUNCTION__ << std::endl;
//return std::make_shared<MagStructFactDlg>(pParent);
return new MagStructFactDlg(pParent);
}
/**
* destroy the plugin main dialog
*/
void destroy(QDialog* dlg)
{
//std::cout << "In " << __FUNCTION__ << std::endl;
if(dlg) delete dlg;
}
BOOST_DLL_ALIAS(init, tl_init);
BOOST_DLL_ALIAS(descr, tl_descr);
BOOST_DLL_ALIAS(create, tl_create);
BOOST_DLL_ALIAS(destroy, tl_destroy);
#endif
This diff is collapsed.
/**
* magnetic structure factor tool
* @author Tobias Weber <tweber@ill.fr>
* @date Jan-2019
* @license GPLv3, see 'LICENSE' file
* @desc The present version was forked on 28-Dec-2018 from my privately developed "misc" project (https://github.com/t-weber/misc).
*
* ----------------------------------------------------------------------------
* mag-core (part of the Takin software suite)