Skip to content

Commit

Permalink
SmallStructure: add symop_xyz and determine_spacegroup_from()
Browse files Browse the repository at this point in the history
In chemical CIF files, the space group name might be less reliable
than using symmetry operations from _space_group_symop_operation_xyz
or _symmetry_equiv_pos_as_xyz.

Calling determine_spacegroup_from("xn") tries to determine SG from
the operations first; if it's not there, H-M name is used;
The argument can be "n" or "x" or "xn" or "nx".
n = spacegroup H-M name, x = list of xyz symmetry operation

This is a tentative and backward compatible API. It may change.
It's not documented yet.

for #308
  • Loading branch information
wojdyr committed Apr 22, 2024
1 parent f47af09 commit 1c2e109
Show file tree
Hide file tree
Showing 3 changed files with 42 additions and 0 deletions.
31 changes: 31 additions & 0 deletions include/gemmi/small.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -56,16 +56,47 @@ struct SmallStructure {
std::string name;
UnitCell cell;
std::string spacegroup_hm;
std::vector<std::string> symop_xyz;
const SpaceGroup* sg_cache = nullptr;
std::vector<Site> sites;
std::vector<AtomType> atom_types;
double wavelength = 0.; // the first wavelength if multiple

std::vector<Site> get_all_unit_cell_sites() const;

/// \param order should be one of: "n", "x", "nx", "xn", ""
/// n = spacegroup H-M name, x = list of xyz symmetry operation
bool determine_spacegroup_from(const std::string& order) {
sg_cache = nullptr;
for (char letter : order) {
if (letter == 'n' || letter == 'N')
sg_cache = find_spacegroup(); // from spacegroup_hm
else if (letter == 'x' || letter == 'X')
sg_cache = find_spacegroup_from_symop_xyz();
if (sg_cache)
break;
}
// Note: if sg_cache is left null, find_spacegroup() uses spacegroup_hm,
// as it was before determine_spacegroup_from() was introduced.
setup_cell_images();
return sg_cache != nullptr;
}

const SpaceGroup* find_spacegroup() const {
if (sg_cache)
return sg_cache;
return find_spacegroup_by_name(spacegroup_hm, cell.alpha, cell.gamma);
}

const SpaceGroup* find_spacegroup_from_symop_xyz() const {
std::vector<Op> ops;
ops.reserve(symop_xyz.size());
for (const std::string& xyz : symop_xyz)
ops.push_back(parse_triplet(xyz));
GroupOps gops = split_centering_vectors(ops);
return find_spacegroup_by_ops(gops);
}

const AtomType* get_atom_type(const std::string& symbol) const {
for (const AtomType& at : atom_types)
if (at.symbol == symbol)
Expand Down
9 changes: 9 additions & 0 deletions include/gemmi/smcif.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,15 @@ SmallStructure make_small_structure_from_block(const cif::Block& block_) {
st.spacegroup_hm = as_string(*val);
break;
}
for (const char* tag : {"_space_group_symop_operation_xyz",
"_symmetry_equiv_pos_as_xyz"}) {
if (const cif::Column col = block.find_values(tag)) {
st.symop_xyz.reserve(col.length());
for (const std::string& value : col)
st.symop_xyz.push_back(cif::as_string(value));
break;
}
}

enum { kLabel, kSymbol, kX, kY, kZ, kUiso, kBiso, kOcc, kDisorderGroup };
cif::Table atom_table = block.find("_atom_site_",
Expand Down
2 changes: 2 additions & 0 deletions python/read.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -131,13 +131,15 @@ void add_small(py::module& m) {
.def_readwrite("name", &SmallStructure::name)
.def_readwrite("cell", &SmallStructure::cell)
.def_readwrite("spacegroup_hm", &SmallStructure::spacegroup_hm)
.def_readwrite("symop_xyz", &SmallStructure::symop_xyz)
.def_readonly("sites", &SmallStructure::sites)
.def_readonly("atom_types", &SmallStructure::atom_types)
.def_readwrite("wavelength", &SmallStructure::wavelength)
.def("add_site", [](SmallStructure& self, const SmallStructure::Site& site) {
self.sites.push_back(site);
})
.def("find_spacegroup", &SmallStructure::find_spacegroup)
.def("determine_spacegroup_from", &SmallStructure::determine_spacegroup_from)
.def("get_atom_type", &SmallStructure::get_atom_type)
.def("get_all_unit_cell_sites", &SmallStructure::get_all_unit_cell_sites)
.def("remove_hydrogens", &SmallStructure::remove_hydrogens)
Expand Down

0 comments on commit 1c2e109

Please sign in to comment.