Gemmi C++ API
Loading...
Searching...
No Matches
select.hpp
Go to the documentation of this file.
1// Copyright 2018 Global Phasing Ltd.
2//
3// Selections.
4
5#ifndef GEMMI_SELECT_HPP_
6#define GEMMI_SELECT_HPP_
7
8#include <climits> // for INT_MIN, INT_MAX
9#include "model.hpp" // for Model
10
11namespace gemmi {
12
13// from http://www.ccp4.ac.uk/html/pdbcur.html
14// Specification of the selection sets:
15// either
16// /mdl/chn/s1.i1-s2.i2/at[el]:aloc
17// or
18// /mdl/chn/*(res).ic/at[el]:aloc
19//
20
22 struct List {
23 bool all = true;
24 bool inverted = false;
25 std::string list; // comma-separated
26
27 std::string str() const {
28 if (all)
29 return "*";
30 return inverted ? "!" + list : list;
31 }
32
33 bool has(const std::string& name) const {
34 if (all)
35 return true;
36 bool found = is_in_list(name, list);
37 return inverted ? !found : found;
38 }
39 };
40
41 struct FlagList {
42 std::string pattern;
43 bool has(char flag) const {
44 if (pattern.empty())
45 return true;
46 bool invert = (pattern[0] == '!');
47 bool found = (pattern.find(flag, invert ? 1 : 0) != std::string::npos);
48 return invert ? !found : found;
49 }
50 };
51
52 struct SequenceId {
53 int seqnum;
54 char icode;
55
56 bool empty() const {
57 return seqnum == INT_MIN || seqnum == INT_MAX;
58 }
59
60 std::string str() const;
61
62 int compare(const SeqId& seqid) const {
63 if (seqnum != *seqid.num)
64 return seqnum < *seqid.num ? -1 : 1;
65 if (icode != '*' && icode != seqid.icode)
66 return icode < seqid.icode ? -1 : 1;
67 return 0;
68 }
69 };
70
74 double value;
75
76 bool matches(const Atom& a) const {
77 double atom_value = 0.;
78 if (property == 'q')
79 atom_value = a.occ;
80 else if (property == 'b')
81 atom_value = a.b_iso;
82 if (relation < 0)
83 return atom_value < value;
84 if (relation > 0)
85 return atom_value > value;
86 return atom_value == value;
87 }
88
89 std::string str() const;
90 };
91
92 int mdl = 0; // 0 = all
94 SequenceId from_seqid = {INT_MIN, '*'};
95 SequenceId to_seqid = {INT_MAX, '*'};
98 // array corresponding to enum EntityType
99 std::array<char, 6> et_flags;
101 std::vector<char> elements;
105 std::vector<AtomInequality> atom_inequalities;
106
107 Selection() = default;
108 Selection(const std::string& cid);
109
110 std::string str() const;
111
112 bool matches(const Structure&) const { return true; }
113 bool matches(const Model& model) const {
114 return mdl == 0 || mdl == model.num;
115 }
116 bool matches(const Chain& chain) const {
117 return chain_ids.has(chain.name);
118 }
119 bool matches(const Residue& res) const {
120 return (entity_types.all || et_flags[(int)res.entity_type]) &&
121 residue_names.has(res.name) &&
122 from_seqid.compare(res.seqid) <= 0 &&
123 to_seqid.compare(res.seqid) >= 0 &&
124 residue_flags.has(res.flag);
125 }
126 bool matches(const Atom& a) const {
127 return atom_names.has(a.name) &&
128 (elements.empty() || elements[a.element.ordinal()]) &&
129 (altlocs.all || altlocs.has(std::string(a.altloc ? 1 : 0, a.altloc))) &&
130 atom_flags.has(a.flag) &&
131 std::all_of(atom_inequalities.begin(), atom_inequalities.end(),
132 [&](const AtomInequality& i) { return i.matches(a); });
133 }
134 bool matches(const CRA& cra) const {
135 return (cra.chain == nullptr || matches(*cra.chain)) &&
136 (cra.residue == nullptr || matches(*cra.residue)) &&
137 (cra.atom == nullptr || matches(*cra.atom));
138 }
139
141 return {*this, st.models};
142 }
144 return {*this, model.chains};
145 }
147 return {*this, chain.residues};
148 }
150 return {*this, residue.atoms};
151 }
152
153 CRA first_in_model(Model& model) const {
154 if (matches(model))
155 for (Chain& chain : model.chains) {
156 if (matches(chain))
157 for (Residue& res : chain.residues) {
158 if (matches(res))
159 for (Atom& atom : res.atoms) {
160 if (matches(atom))
161 return {&chain, &res, &atom};
162 }
163 }
164 }
165 return {nullptr, nullptr, nullptr};
166 }
167
168 std::pair<Model*, CRA> first(Structure& st) const {
169 for (Model& model : st.models) {
170 CRA cra = first_in_model(model);
171 if (cra.chain)
172 return {&model, cra};
173 }
174 return {nullptr, {nullptr, nullptr, nullptr}};
175 }
176
177 template<typename T>
178 void add_matching_children(const T& orig, T& target) const {
179 for (const auto& orig_child : orig.children())
180 if (matches(orig_child)) {
181 target.children().push_back(orig_child.empty_copy());
182 add_matching_children(orig_child, target.children().back());
183 }
184 }
185 void add_matching_children(const Atom&, Atom&) const {}
186
187 Selection& set_residue_flags(const std::string& pattern) {
188 residue_flags.pattern = pattern;
189 return *this;
190 }
191 Selection& set_atom_flags(const std::string& pattern) {
192 atom_flags.pattern = pattern;
193 return *this;
194 }
195
196 template<typename T>
197 T copy_selection(const T& orig) const {
198 T copied = orig.empty_copy();
199 add_matching_children(orig, copied);
200 return copied;
201 }
202
203 template<typename T>
204 void remove_selected(T& t) const {
205 for (auto& child : t.children())
206 if (matches(child))
207 remove_selected(child);
208 vector_remove_if(t.children(),
209 [&](typename T::child_type& c) { return c.children().empty(); });
210 }
211 void remove_selected(Residue& res) const {
212 if (atom_names.all && elements.empty() && altlocs.all &&
213 atom_flags.pattern.empty() && atom_inequalities.empty())
214 res.atoms.clear();
215 else
216 vector_remove_if(res.atoms, [&](Atom& c) { return matches(c); });
217 }
218
219 template<typename T>
220 void remove_not_selected(T& t) const {
221 vector_remove_if(t.children(), [&](typename T::child_type& c) { return !matches(c); });
222 for (auto& child : t.children())
223 remove_not_selected(child);
224 }
225 void remove_not_selected(Atom&) const {}
226};
227
228} // namespace gemmi
229#endif
#define GEMMI_DLL
Definition fail.hpp:53
Data structures to store macromolecular structure models.
void vector_remove_if(std::vector< T > &v, F &&condition)
Definition util.hpp:267
bool is_in_list(const std::string &name, const std::string &list, char sep=',')
Definition util.hpp:227
Represents atom site in macromolecular structure (~100 bytes).
Definition model.hpp:120
char altloc
Definition model.hpp:123
char flag
Definition model.hpp:127
float b_iso
Definition model.hpp:134
Element element
Definition model.hpp:125
float occ
Definition model.hpp:132
std::string name
Definition model.hpp:122
Residue * residue
Definition model.hpp:627
Chain * chain
Definition model.hpp:626
Atom * atom
Definition model.hpp:628
std::vector< Residue > residues
Definition model.hpp:486
std::string name
Definition model.hpp:485
int ordinal() const
Definition elem.hpp:308
std::vector< Chain > chains
Definition model.hpp:722
std::string name
Definition seqid.hpp:93
std::vector< Atom > atoms
Definition model.hpp:196
EntityType entity_type
Definition model.hpp:191
bool matches(const Atom &a) const
Definition select.hpp:76
bool has(char flag) const
Definition select.hpp:43
bool has(const std::string &name) const
Definition select.hpp:33
std::string str() const
Definition select.hpp:27
int compare(const SeqId &seqid) const
Definition select.hpp:62
std::string str() const
Selection()=default
FlagList atom_flags
Definition select.hpp:104
Selection & set_atom_flags(const std::string &pattern)
Definition select.hpp:191
std::vector< AtomInequality > atom_inequalities
Definition select.hpp:105
FilterProxy< Selection, Atom > atoms(Residue &residue) const
Definition select.hpp:149
bool matches(const Residue &res) const
Definition select.hpp:119
T copy_selection(const T &orig) const
Definition select.hpp:197
Selection(const std::string &cid)
bool matches(const Chain &chain) const
Definition select.hpp:116
bool matches(const Structure &) const
Definition select.hpp:112
bool matches(const Model &model) const
Definition select.hpp:113
CRA first_in_model(Model &model) const
Definition select.hpp:153
FilterProxy< Selection, Residue > residues(Chain &chain) const
Definition select.hpp:146
void remove_not_selected(T &t) const
Definition select.hpp:220
std::string str() const
std::pair< Model *, CRA > first(Structure &st) const
Definition select.hpp:168
void add_matching_children(const T &orig, T &target) const
Definition select.hpp:178
FilterProxy< Selection, Model > models(Structure &st) const
Definition select.hpp:140
FlagList residue_flags
Definition select.hpp:103
void add_matching_children(const Atom &, Atom &) const
Definition select.hpp:185
Selection & set_residue_flags(const std::string &pattern)
Definition select.hpp:187
std::vector< char > elements
Definition select.hpp:101
void remove_not_selected(Atom &) const
Definition select.hpp:225
bool matches(const Atom &a) const
Definition select.hpp:126
FilterProxy< Selection, Chain > chains(Model &model) const
Definition select.hpp:143
void remove_selected(T &t) const
Definition select.hpp:204
bool matches(const CRA &cra) const
Definition select.hpp:134
std::array< char, 6 > et_flags
Definition select.hpp:99
void remove_selected(Residue &res) const
Definition select.hpp:211
OptionalNum num
Definition seqid.hpp:56
char icode
Definition seqid.hpp:57