Commit ac15d73f authored by Tobias WEBER's avatar Tobias WEBER
Browse files

created small cif2xml tool

parent 78406251
......@@ -1403,7 +1403,8 @@ void MagStructFactDlg::ImportCIF()
return;
m_sett->setValue("dir_cif", QFileInfo(filename).path());
auto [errstr, atoms, generatedatoms, atomnames, lattice] = load_cif<t_vec, t_mat>(filename.toStdString(), g_eps);
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);
......
......@@ -23,6 +23,8 @@ add_definitions(${Boost_CXX_FLAGS})
include_directories("${PROJECT_SOURCE_DIR}" "${Boost_INCLUDE_DIRS}/.." "../.."
"../../ext/gemmi/include" "../../ext/gemmi/third_party")
# main tool
if(BUILD_LIB)
set(CMAKE_POSITION_INDEPENDENT_CODE TRUE)
......@@ -38,3 +40,10 @@ endif()
target_link_libraries(structfact ${Boost_LIBRARIES})
qt5_use_modules(structfact Core Gui Widgets OpenGL)
# cif2xml tool
add_executable(cif2xml
cif2xml.cpp loadcif.h)
target_link_libraries(cif2xml)
/**
* converts a CIF file into a more parsable XML
* @author Tobias Weber <tweber@ill.fr>
* @date may-2019
* @license GPLv3, see 'LICENSE' file
*/
#include "loadcif.h"
#include "libs/_cxx20/math_algos.h"
#include <iostream>
#include <memory>
using t_real = double;
using t_vec = std::vector<t_real>;
using t_mat = m::mat<t_real, std::vector>;
constexpr t_real g_eps = 1e-6;
constexpr int g_prec = 6;
/**
* print vector
*/
std::ostream& operator<<(std::ostream& ostr, const t_vec& vec)
{
for(std::size_t i=0; i<vec.size(); ++i)
{
ostr << vec[i];
if(i < vec.size()-1)
ostr << ", ";
}
return ostr;
}
/**
* print matrix
*/
std::ostream& operator<<(std::ostream& ostr, const t_mat& mat)
{
for(std::size_t i=0; i<mat.size1(); ++i)
{
for(std::size_t j=0; j<mat.size2(); ++j)
{
ostr << mat(i,j);
if(j < mat.size2()-1)
ostr << ", ";
}
if(i < mat.size1()-1)
ostr << "; ";
}
return ostr;
}
/**
* convert CIF to XML
*/
bool convert_cif(const char* pcFileIn, const char* pcFileOut)
{
auto [errstr, atoms, generatedatoms, atomnames, lattice, ops] = load_cif<t_vec, t_mat>(pcFileIn, g_eps);
if(errstr != "")
std::cerr << "CIF importer messages:\n" << errstr << std::endl;
// either open output file (if given) or use standard out
std::ostream *pOstr = &std::cout;
std::unique_ptr<std::ostream> _ofstr;
if(pcFileOut)
{
_ofstr = std::make_unique<std::ofstream>(pcFileOut);
pOstr = _ofstr.get();
}
pOstr->precision(g_prec);
(*pOstr) << "<xml>\n<xtal>" << std::endl;
// lattice
(*pOstr) << "\t<lattice>\n";
(*pOstr) << "\t\t<a> " << lattice.a << " </a>\n";
(*pOstr) << "\t\t<b> " << lattice.b << " </b>\n";
(*pOstr) << "\t\t<c> " << lattice.c << " </c>\n";
(*pOstr) << "\t\t<alpha> " << lattice.alpha << " </alpha>\n";
(*pOstr) << "\t\t<beta> " << lattice.beta << " </beta>\n";
(*pOstr) << "\t\t<gamma> " << lattice.gamma << " </gamma>\n";
(*pOstr) << "\t</lattice>\n";
(*pOstr) << "\n";
// basic atoms
(*pOstr) << "\t<atoms>\n";
for(std::size_t i=0; i<atoms.size(); ++i)
{
if(atomnames.size() == atoms.size())
(*pOstr) << "\t\t<name" << i << "> " << atomnames[i] << " </name" << i << ">\n";
(*pOstr) << "\t\t<pos" << i << "> " << atoms[i] << " </pos" << i << ">\n";
}
(*pOstr) << "\t</atoms>\n";
(*pOstr) << "\n";
// generated atoms
(*pOstr) << "\t<generated_atoms>\n";
for(std::size_t i=0; i<generatedatoms.size(); ++i)
{
(*pOstr) << "\t\t<pos" << i << ">\n";
for(std::size_t j=0; j<generatedatoms[i].size(); ++j)
(*pOstr) << "\t\t\t<gen" << j << "> " << generatedatoms[i][j] << " </gen" << j << ">\n";
(*pOstr) << "\t\t</pos" << i << ">\n";
}
(*pOstr) << "\t</generated_atoms>\n";
(*pOstr) << "\n";
// symops
(*pOstr) << "\t<symops>\n";
for(std::size_t i=0; i<ops.size(); ++i)
(*pOstr) << "\t\t<op" << i << "> " << ops[i] << " </op" << i << ">\n";
(*pOstr) << "\t</symops>\n";
(*pOstr) << "</xtal>\n</xml>" << std::endl;
return true;
}
/**
* show infos about the tool
*/
static void show_infos(const char* pcProg)
{
std::cout << "This is a CIF to XML converter, version 0.5.\n";
std::cout << "Written by Tobias Weber (tweber@ill.fr) in May 2019.\n";
std::cout << "\nUsage: " << pcProg << " <in.cif> <out.xml>\n";
std::cout << std::endl;
}
/**
* entry point
*/
int main(int argc, char** argv)
{
const char* pcFileIn = nullptr;
const char* pcFileOut = nullptr;
if(argc <= 1)
{
show_infos(argv[0]);
return 0;
}
else if(argc == 2)
{
pcFileIn = argv[1];
}
else if(argc >= 3)
{
pcFileIn = argv[1];
pcFileOut = argv[2];
}
if(!convert_cif(pcFileIn, pcFileOut))
return -1;
return 0;
}
......@@ -188,18 +188,24 @@ std::vector<t_mat> get_cif_sg_ops(gemmi::cif::Block& block)
* loads the lattice parameters and the atom positions from a CIF
*/
template<class t_vec, class t_mat, class t_real = typename t_vec::value_type>
std::tuple<std::string, std::vector<t_vec>, std::vector<std::vector<t_vec>>, std::vector<std::string>, Lattice<t_real>>
std::tuple<
std::string /* errors and warnings */,
std::vector<t_vec> /* basic atom positions */,
std::vector<std::vector<t_vec>> /* all generated atoms */,
std::vector<std::string> /* atom names */,
Lattice<t_real> /* lattice */ ,
std::vector<t_mat> /* ops */ >
load_cif(const std::string& filename, t_real eps=1e-6)
{
auto ifstr = std::ifstream(filename);
if(!ifstr)
return std::make_tuple("Cannot open CIF.", std::vector<t_vec>{}, std::vector<std::vector<t_vec>>{}, std::vector<std::string>{}, Lattice{});
return std::make_tuple("Cannot open CIF.", std::vector<t_vec>{}, std::vector<std::vector<t_vec>>{}, std::vector<std::string>{}, Lattice{}, std::vector<t_mat>{});
// load CIF
auto cif = gemmi::cif::read_istream(ifstr, 4096, filename.c_str());
if(!cif.blocks.size())
return std::make_tuple("No blocks in CIF.", std::vector<t_vec>{}, std::vector<std::vector<t_vec>>{}, std::vector<std::string>{}, Lattice{});
return std::make_tuple("No blocks in CIF.", std::vector<t_vec>{}, std::vector<std::vector<t_vec>>{}, std::vector<std::string>{}, Lattice{}, std::vector<t_mat>{});
// get the block
/*const*/ auto& block = cif.sole_block();
......@@ -249,7 +255,7 @@ load_cif(const std::string& filename, t_real eps=1e-6)
generatedatoms.emplace_back(std::move(newatoms));
}
return std::make_tuple(errstr.str(), atoms, generatedatoms, atomnames, latt);
return std::make_tuple(errstr.str(), atoms, generatedatoms, atomnames, latt, ops);
}
......
......@@ -1003,7 +1003,8 @@ void StructFactDlg::ImportCIF()
return;
m_sett->setValue("dir_cif", QFileInfo(filename).path());
auto [errstr, atoms, generatedatoms, atomnames, lattice] = load_cif<t_vec, t_mat>(filename.toStdString(), g_eps);
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());
......
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