Skip to content
GitLab
Projects
Groups
Snippets
/
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Sign in
Toggle navigation
Menu
Open sidebar
Scientific Software
Takin
mag-core
Commits
2bb7f73d
Verified
Commit
2bb7f73d
authored
May 26, 2022
by
Tobias WEBER
Browse files
cleanups
parent
575d741b
Changes
9
Expand all
Hide whitespace changes
Inline
Side-by-side
.gitignore
View file @
2bb7f73d
...
...
@@ -32,6 +32,7 @@ data/**
res/**
tlibs
tlibs2
pathslib
data
# Temporary files
...
...
tools/structfact/CMakeLists.txt
View file @
2bb7f73d
...
...
@@ -24,6 +24,12 @@
cmake_minimum_required
(
VERSION 3.0
)
project
(
structfact
)
enable_language
(
CXX
)
list
(
APPEND CMAKE_MODULE_PATH
"
${
PROJECT_SOURCE_DIR
}
"
"
${
PROJECT_SOURCE_DIR
}
/../../tlibs2/cmake"
)
set
(
CMAKE_VERBOSE_MAKEFILE TRUE
)
option
(
BUILD_LIB
"build as dynamic library"
FALSE
)
...
...
@@ -40,6 +46,12 @@ endif()
find_package
(
Boost REQUIRED
)
find_package
(
Qt5 REQUIRED COMPONENTS Core Gui Widgets
)
find_package
(
Qhull
)
if
(
Qhull_FOUND
)
add_definitions
(
-DUSE_QHULL
)
include_directories
(
"
${
Qhull_INCLUDE_DIRS
}
"
)
endif
()
set
(
CMAKE_AUTOUIC TRUE
)
set
(
CMAKE_AUTOMOC TRUE
)
...
...
@@ -61,12 +73,18 @@ if(BUILD_LIB)
add_definitions
(
-DBUILD_LIB
)
add_library
(
takin_structfact SHARED
structfact.cpp structfact.h
structfact.cpp structfact_file.cpp
structfact_structplot.cpp structfact_main.cpp
structfact_findsg.cpp structfact_nuclei.cpp
structfact.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_structfact
structfact.cpp structfact.h
structfact.cpp structfact_file.cpp
structfact_structplot.cpp structfact_main.cpp
structfact_findsg.cpp structfact_nuclei.cpp
structfact.h
../../tlibs2/libs/qt/gl.cpp ../../tlibs2/libs/qt/gl.h
../../tlibs2/libs/qt/glplot.cpp ../../tlibs2/libs/qt/glplot.h
)
endif
()
...
...
@@ -78,4 +96,8 @@ if(CMAKE_SYSTEM_NAME STREQUAL "Darwin")
)
endif
()
target_link_libraries
(
takin_structfact
${
Boost_LIBRARIES
}
Qt5::Core Qt5::Gui Qt5::Widgets
)
target_link_libraries
(
takin_structfact
${
Boost_LIBRARIES
}
${
Qhull_LIBRARIES
}
Qt5::Core Qt5::Gui Qt5::Widgets
)
tools/structfact/structfact.cpp
View file @
2bb7f73d
This diff is collapsed.
Click to expand it.
tools/structfact/structfact.h
View file @
2bb7f73d
...
...
@@ -64,6 +64,23 @@ 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
;
enum
:
int
{
COL_NAME
=
0
,
COL_SCATLEN_RE
,
COL_SCATLEN_IM
,
COL_X
,
COL_Y
,
COL_Z
,
COL_RAD
,
COL_COL
,
NUM_COLS
};
struct
NuclPos
{
std
::
string
name
;
...
...
@@ -78,6 +95,7 @@ public:
StructFactDlg
(
QWidget
*
pParent
=
nullptr
);
~
StructFactDlg
()
=
default
;
protected:
QSettings
*
m_sett
=
nullptr
;
QMenuBar
*
m_menu
=
nullptr
;
...
...
@@ -116,6 +134,7 @@ protected:
t_mat
m_crystA
=
tl2
::
unit
<
t_mat
>
(
3
);
t_mat
m_crystB
=
tl2
::
unit
<
t_mat
>
(
3
);
protected:
// for nuclei tab
void
AddTabItem
(
int
row
=-
1
,
const
std
::
string
&
name
=
"n/a"
,
t_real
bRe
=
0.
,
t_real
bIm
=
0.
,
...
...
@@ -124,15 +143,11 @@ protected:
void
MoveTabItemUp
();
void
MoveTabItemDown
();
void
Add3DItem
(
int
row
=-
1
);
void
Set3DStatusMsg
(
const
std
::
string
&
msg
);
void
TableCurCellChanged
(
int
rowNew
,
int
colNew
,
int
rowOld
,
int
colOld
);
void
TableCellEntered
(
const
QModelIndex
&
idx
);
void
TableItemChanged
(
QTableWidgetItem
*
item
);
void
ShowTableContextMenu
(
const
QPoint
&
pt
);
void
Load
();
void
Save
();
void
ImportCIF
();
...
...
@@ -144,6 +159,10 @@ protected:
void
CalcB
(
bool
bFullRecalc
=
true
);
void
Calc
();
void
Add3DItem
(
int
row
=-
1
);
void
Set3DStatusMsg
(
const
std
::
string
&
msg
);
void
ShowStructPlot
();
void
PlotMouseDown
(
bool
left
,
bool
mid
,
bool
right
);
void
PlotMouseUp
(
bool
left
,
bool
mid
,
bool
right
);
void
PickerIntersection
(
const
t_vec3_gl
*
pos
,
std
::
size_t
objIdx
,
const
t_vec3_gl
*
posSphere
);
...
...
@@ -164,6 +183,7 @@ protected:
virtual
void
closeEvent
(
QCloseEvent
*
evt
)
override
;
private:
int
m_iCursorRow
=
-
1
;
bool
m_ignoreChanges
=
1
;
...
...
@@ -175,6 +195,7 @@ private:
static
std
::
vector
<
std
::
string
>
g_default_colours
;
private:
std
::
vector
<
int
>
GetSelectedRows
(
bool
sort_reversed
=
false
)
const
;
std
::
vector
<
int
>
GetSelectedRows_FindSG
(
bool
sort_reversed
=
false
)
const
;
...
...
tools/structfact/structfact_file.cpp
0 → 100644
View file @
2bb7f73d
/**
* structure factor tool
* @author Tobias Weber <tweber@ill.fr>
* @date Dec-2018
* @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
"structfact.h"
#include
<QtWidgets/QFileDialog>
#include
<QtWidgets/QMessageBox>
#include
<iostream>
#include
<fstream>
#include
<random>
#include
<boost/property_tree/ptree.hpp>
#include
<boost/property_tree/xml_parser.hpp>
namespace
pt
=
boost
::
property_tree
;
#include
"loadcif.h"
#include
"tlibs2/libs/maths.h"
#include
"tlibs2/libs/algos.h"
using
namespace
tl2_ops
;
std
::
vector
<
std
::
string
>
StructFactDlg
::
g_default_colours
{{
"#ff0000"
,
"#0000ff"
,
"#00ff00"
,
"#000000"
,
}};
void
StructFactDlg
::
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
opt
=
node
.
get_optional
<
std
::
string
>
(
"sfact.meta.info"
);
!
opt
||
*
opt
!=
std
::
string
{
"sfact_tool"
})
{
QMessageBox
::
critical
(
this
,
"Structure Factors"
,
"Unrecognised file format."
);
return
;
}
// clear old nuclei
DelTabItem
(
-
1
);
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.removezeroes"
);
opt
)
{
m_RemoveZeroes
->
setChecked
(
*
opt
!=
0
);
}
if
(
auto
opt
=
node
.
get_optional
<
int
>
(
"sfact.sg_idx"
);
opt
)
{
m_comboSG
->
setCurrentIndex
(
*
opt
);
}
// nuclei
if
(
auto
nuclei
=
node
.
get_child_optional
(
"sfact.nuclei"
);
nuclei
)
{
std
::
size_t
nucIdx
=
0
;
for
(
const
auto
&
nucl
:
*
nuclei
)
{
auto
optName
=
nucl
.
second
.
get
<
std
::
string
>
(
"name"
,
"n/a"
);
auto
optbRe
=
nucl
.
second
.
get
<
t_real
>
(
"b_Re"
,
0.
);
auto
optbIm
=
nucl
.
second
.
get
<
t_real
>
(
"b_Im"
,
0.
);
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
optRad
=
nucl
.
second
.
get
<
t_real
>
(
"rad"
,
1.
);
auto
optCol
=
nucl
.
second
.
get
<
std
::
string
>
(
"col"
,
g_default_colours
[
nucIdx
%
g_default_colours
.
size
()]);
AddTabItem
(
-
1
,
optName
,
optbRe
,
optbIm
,
optX
,
optY
,
optZ
,
optRad
,
optCol
);
++
nucIdx
;
}
}
}
catch
(
const
std
::
exception
&
ex
)
{
QMessageBox
::
critical
(
this
,
"Structure Factors"
,
ex
.
what
());
}
m_ignoreCalc
=
0
;
CalcB
(
false
);
Calc
();
}
void
StructFactDlg
::
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"
,
"sfact_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.removezeroes"
,
m_RemoveZeroes
->
isChecked
());
node
.
put
<
int
>
(
"sfact.sg_idx"
,
m_comboSG
->
currentIndex
());
// nucleus list
for
(
int
row
=
0
;
row
<
m_nuclei
->
rowCount
();
++
row
)
{
t_real
bRe
{},
bIm
{},
x
{},
y
{},
z
{},
scale
{};
std
::
istringstream
{
m_nuclei
->
item
(
row
,
COL_SCATLEN_RE
)
->
text
().
toStdString
()}
>>
bRe
;
std
::
istringstream
{
m_nuclei
->
item
(
row
,
COL_SCATLEN_IM
)
->
text
().
toStdString
()}
>>
bIm
;
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_RAD
)
->
text
().
toStdString
()}
>>
scale
;
pt
::
ptree
itemNode
;
itemNode
.
put
<
std
::
string
>
(
"name"
,
m_nuclei
->
item
(
row
,
COL_NAME
)
->
text
().
toStdString
());
itemNode
.
put
<
t_real
>
(
"b_Re"
,
bRe
);
itemNode
.
put
<
t_real
>
(
"b_Im"
,
bIm
);
itemNode
.
put
<
t_real
>
(
"x"
,
x
);
itemNode
.
put
<
t_real
>
(
"y"
,
y
);
itemNode
.
put
<
t_real
>
(
"z"
,
z
);
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
);
}
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 a TAZ file
*/
void
StructFactDlg
::
ImportTAZ
()
{
m_ignoreCalc
=
1
;
try
{
QString
dirLast
=
m_sett
->
value
(
"dir_taz"
,
""
).
toString
();
QString
filename
=
QFileDialog
::
getOpenFileName
(
this
,
"Load File"
,
dirLast
,
"TAZ Files (*.taz *.TAZ)"
);
if
(
filename
==
""
||
!
QFile
::
exists
(
filename
))
return
;
m_sett
->
setValue
(
"dir_taz"
,
QFileInfo
(
filename
).
path
());
pt
::
ptree
node
;
std
::
ifstream
ifstr
{
filename
.
toStdString
()};
pt
::
read_xml
(
ifstr
,
node
);
// clear old nuclei
DelTabItem
(
-
1
);
if
(
auto
opt
=
node
.
get_optional
<
t_real
>
(
"taz.sample.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
>
(
"taz.sample.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
>
(
"taz.sample.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
>
(
"taz.sample.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
>
(
"taz.sample.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
>
(
"taz.sample.gamma"
);
opt
)
{
std
::
ostringstream
ostr
;
ostr
.
precision
(
g_prec
);
ostr
<<
*
opt
;
m_editGamma
->
setText
(
ostr
.
str
().
c_str
());
}
if
(
auto
opt
=
node
.
get_optional
<
std
::
string
>
(
"taz.sample.spacegroup"
);
opt
)
{
// TODO
//std::cout << *opt << std::endl;
}
// nuclei
if
(
auto
opt
=
node
.
get_optional
<
std
::
size_t
>
(
"taz.sample.atoms.num"
);
opt
)
{
std
::
size_t
numAtoms
=
*
opt
;
for
(
std
::
size_t
atomIdx
=
0
;
atomIdx
<
numAtoms
;
++
atomIdx
)
{
std
::
string
strNum
=
tl2
::
var_to_str
(
atomIdx
);
std
::
string
name
=
node
.
get
<
std
::
string
>
(
"taz.sample.atoms."
+
strNum
+
".name"
,
"n/a"
);
t_real
x
=
node
.
get
<
t_real
>
(
"taz.sample.atoms."
+
strNum
+
".x"
,
0.
);
t_real
y
=
node
.
get
<
t_real
>
(
"taz.sample.atoms."
+
strNum
+
".y"
,
0.
);
t_real
z
=
node
.
get
<
t_real
>
(
"taz.sample.atoms."
+
strNum
+
".z"
,
0.
);
// TODO
t_real
bRe
=
0.
;
t_real
bIm
=
0.
;
t_real
rad
=
1.
;
std
::
string
col
=
g_default_colours
[
atomIdx
%
g_default_colours
.
size
()];
AddTabItem
(
-
1
,
name
,
bRe
,
bIm
,
x
,
y
,
z
,
rad
,
col
);
}
}
}
catch
(
const
std
::
exception
&
ex
)
{
QMessageBox
::
critical
(
this
,
"Structure Factors"
,
ex
.
what
());
}
m_ignoreCalc
=
0
;
GenerateFromSG
();
CalcB
(
false
);
Calc
();
}
/**
* save a TAZ file
*/
void
StructFactDlg
::
ExportTAZ
()
{
QString
dirLast
=
m_sett
->
value
(
"dir_taz"
,
""
).
toString
();
QString
filename
=
QFileDialog
::
getSaveFileName
(
this
,
"Export TAZ"
,
dirLast
,
"TAZ Files (*.taz *.TAZ)"
);
if
(
filename
==
""
||
!
QFile
::
exists
(
filename
))
return
;
m_sett
->
setValue
(
"dir_taz"
,
QFileInfo
(
filename
).
path
());
std
::
ofstream
ofstr
{
filename
.
toStdString
()};
if
(
!
ofstr
)
{
QMessageBox
::
critical
(
this
,
"Structure Factors"
,
"Cannot open file for writing."
);
return
;
}
ofstr
.
precision
(
g_prec
);
ofstr
<<
"<taz>
\n
"
;
ofstr
<<
"
\t
<meta><info>Exported from Takin/Structfact.</info></meta>
\n
"
;
// sample infos
ofstr
<<
"
\t
<sample>
\n
"
;
ofstr
<<
"
\t\t
<a>"
<<
m_editA
->
text
().
toStdString
()
<<
"</a>
\n
"
;
ofstr
<<
"
\t\t
<b>"
<<
m_editB
->
text
().
toStdString
()
<<
"</b>
\n
"
;
ofstr
<<
"
\t\t
<c>"
<<
m_editC
->
text
().
toStdString
()
<<
"</c>
\n
"
;
ofstr
<<
"
\t\t
<alpha>"
<<
m_editAlpha
->
text
().
toStdString
()
<<
"</alpha>
\n
"
;
ofstr
<<
"
\t\t
<beta>"
<<
m_editBeta
->
text
().
toStdString
()
<<
"</beta>
\n
"
;
ofstr
<<
"
\t\t
<gamma>"
<<
m_editGamma
->
text
().
toStdString
()
<<
"</gamma>
\n
"
;
// P1 only has the identity trafo, so we can directly output all raw nucleus positions
ofstr
<<
"
\t\t
<spacegroup>P1</spacegroup>
\n
"
;
// nucleus list
ofstr
<<
"
\t\t
<atoms>
\n
"
;
ofstr
<<
"
\t\t\t
<num>"
<<
m_nuclei
->
rowCount
()
<<
"</num>
\n
"
;
for
(
int
row
=
0
;
row
<
m_nuclei
->
rowCount
();
++
row
)
{
ofstr
<<
"
\t\t\t
<"
<<
row
<<
">
\n
"
;
ofstr
<<
"
\t\t\t\t
<name>"
<<
m_nuclei
->
item
(
row
,
COL_NAME
)
->
text
().
toStdString
()
<<
"</name>
\n
"
;
ofstr
<<
"
\t\t\t\t
<x>"
<<
m_nuclei
->
item
(
row
,
COL_X
)
->
text
().
toStdString
()
<<
"</x>
\n
"
;
ofstr
<<
"
\t\t\t\t
<y>"
<<
m_nuclei
->
item
(
row
,
COL_Y
)
->
text
().
toStdString
()
<<
"</y>
\n
"
;
ofstr
<<
"
\t\t\t\t
<z>"
<<
m_nuclei
->
item
(
row
,
COL_Z
)
->
text
().
toStdString
()
<<
"</z>
\n
"
;
ofstr
<<
"
\t\t\t
</"
<<
row
<<
">
\n
"
;
}
ofstr
<<
"
\t\t
</atoms>
\n
"
;
ofstr
<<
"
\t
</sample>
\n
"
;
ofstr
<<
"</taz>
\n
"
;
}
/**
* load a CIF
*/
void
StructFactDlg
::
ImportCIF
()
{
m_ignoreCalc
=
1
;
try
{
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
.
c_str
());
return
;
}
// clear old nuclei
DelTabItem
(
-
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
());
}
// 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
());
}
}