Gemmi C++ API
Loading...
Searching...
No Matches
small.hpp
Go to the documentation of this file.
1// Copyright 2018 Global Phasing Ltd.
2//
3// Representation of small molecule or inorganic crystal.
4// Flat list of atom sites. Minimal functionality.
5
6#ifndef GEMMI_SMALL_HPP_
7#define GEMMI_SMALL_HPP_
8
9#include <cctype> // for isalpha
10#include <algorithm> // for any_of
11#include <bitset>
12#include <string>
13#include <vector>
14#include "elem.hpp" // Element
15#include "math.hpp" // SMat33
16#include "symmetry.hpp" // find_spacegroup_by_name
17#include "unitcell.hpp" // UnitCell, Fractional
18#include "util.hpp" // vector_remove_if
19
20namespace gemmi {
21
23 struct Site {
24 std::string label;
25 std::string type_symbol;
27 double occ = 1.0;
28 double u_iso = 0.;
29 SMat33<double> aniso = {0, 0, 0, 0, 0, 0};
32 signed char charge = 0; // [-8, +8]
33
34 Position orth(const gemmi::UnitCell& cell_) const {
35 return cell_.orthogonalize(fract);
36 }
37
38 std::string element_and_charge_symbol() const {
39 std::string s = element.name();
40 if (charge != 0) {
41 s += std::to_string(std::abs(charge));
42 s += charge > 0 ? '+' : '-';
43 }
44 return s;
45 }
46 };
47
48 struct AtomType {
49 std::string symbol;
51 signed char charge = 0; // [-8, +8]
54 };
55
56 std::string name;
58 std::string spacegroup_hm;
59 std::vector<Site> sites;
60 std::vector<AtomType> atom_types;
61 double wavelength = 0.; // the first wavelength if multiple
62
63 std::vector<Site> get_all_unit_cell_sites() const;
64
68
69 const AtomType* get_atom_type(const std::string& symbol) const {
70 for (const AtomType& at : atom_types)
71 if (at.symbol == symbol)
72 return &at;
73 return nullptr;
74 }
75
76 // similar to Model::present_elements() from model.hpp
77 std::bitset<(size_t)El::END> present_elements() const {
78 std::bitset<(size_t)El::END> table;
79 for (const Site& atom : sites)
80 table.set((size_t)atom.element.elem);
81 return table;
82 }
83
85 vector_remove_if(sites, [](const Site& a) { return a.element.is_hydrogen(); });
86 }
87
88 // pre: atoms on special positions have "chemical" occupancy (i.e. not divided
89 // by n for n-fold symmetry)
91 for (Site& site : sites) {
93 if (n_mates != 0)
94 site.occ /= (n_mates + 1);
95 }
96 }
97
101};
102
103template<typename T>
104inline void split_element_and_charge(const std::string& label, T* dest) {
105 int len = label.size() > 1 && std::isalpha(label[1]) ? 2 : 1;
106 dest->element = len == 1 ? impl::find_single_letter_element(label[0] & ~0x20)
107 : find_element(label.c_str());
108 if (dest->element != El::X && (label.back() == '+' || label.back() == '-')) {
109 int sign = label.back() == '+' ? 1 : -1;
110 if (label.size() - len == 1)
111 dest->charge = sign;
112 else if (label.size() - len == 2 && label[len] >= '0' && label[len] <= '9')
113 dest->charge = sign * (label[len] - '0');
114 }
115}
116
117inline std::vector<SmallStructure::Site>
119 const double SPECIAL_POS_TOL = 0.4;
120 std::vector<Site> all;
121 for (const Site& site : sites) {
122 size_t start = all.size();
123 all.push_back(site);
124 for (const FTransform& image : cell.images) {
125 Fractional fpos = image.apply(site.fract);
126 if (std::any_of(all.begin() + start, all.end(), [&](const Site& other) {
127 return cell.distance_sq(fpos, other.fract) < sq(SPECIAL_POS_TOL);
128 }))
129 continue;
130 all.push_back(site);
131 all.back().fract = fpos;
132 }
133 }
134 return all;
135}
136
137} // namespace gemmi
138#endif
void vector_remove_if(std::vector< T > &v, F &&condition)
Definition util.hpp:266
El find_element(const char *symbol)
Definition elem.hpp:267
const SpaceGroup * find_spacegroup_by_name(std::string name, double alpha=0., double gamma=0.) noexcept
void split_element_and_charge(const std::string &label, T *dest)
Definition small.hpp:104
bool is_hydrogen() const
Definition elem.hpp:303
const char * name() const
Definition elem.hpp:309
Like Transform, but apply() arg is Fractional (not Vec3 - for type safety).
Definition unitcell.hpp:112
Fractional coordinates.
Definition unitcell.hpp:50
Coordinates in Angstroms - orthogonal (Cartesian) coordinates.
Definition unitcell.hpp:32
SMat33< double > aniso
Definition small.hpp:29
Position orth(const gemmi::UnitCell &cell_) const
Definition small.hpp:34
std::string element_and_charge_symbol() const
Definition small.hpp:38
std::string spacegroup_hm
Definition small.hpp:58
std::vector< Site > get_all_unit_cell_sites() const
Definition small.hpp:118
std::vector< Site > sites
Definition small.hpp:59
void setup_cell_images()
Definition small.hpp:98
std::vector< AtomType > atom_types
Definition small.hpp:60
void change_occupancies_to_crystallographic(double max_dist=0.4)
Definition small.hpp:90
const SpaceGroup * find_spacegroup() const
Definition small.hpp:65
std::string name
Definition small.hpp:56
void remove_hydrogens()
Definition small.hpp:84
const AtomType * get_atom_type(const std::string &symbol) const
Definition small.hpp:69
std::bitset<(size_t) El::END > present_elements() const
Definition small.hpp:77
Unit cell.
Definition unitcell.hpp:139
Position orthogonalize(const Fractional &f) const
Definition unitcell.hpp:371
std::vector< FTransform > images
Definition unitcell.hpp:158
void set_cell_images_from_spacegroup(const SpaceGroup *sg)
Definition unitcell.hpp:337
int is_special_position(const Fractional &fpos, double max_dist) const
Counts nearby symmetry mates (0 = none, 3 = 4-fold axis, etc).
Definition unitcell.hpp:503