Gemmi C++ API
Loading...
Searching...
No Matches
seqid.hpp
Go to the documentation of this file.
1// Copyright 2017 Global Phasing Ltd.
2//
3// SeqId -- residue number and insertion code together.
4
5#ifndef GEMMI_SEQID_HPP_
6#define GEMMI_SEQID_HPP_
7
8#include <climits> // for INT_MIN
9#include <cstdlib> // for strtol
10#include <stdexcept> // for invalid_argument
11#include <string>
12#include "util.hpp" // for cat
13
14namespace gemmi {
15
16// Optional int value. N is a special value that means not-set.
17template<int N> struct OptionalInt {
18 enum { None=N };
19 int value = None;
20
21 OptionalInt() = default;
22 OptionalInt(int n) : value(n) {}
23 bool has_value() const { return value != None; }
24 std::string str(char null='?') const {
25 return has_value() ? std::to_string(value) : std::string(1, null);
26 }
27 OptionalInt& operator=(int n) { value = n; return *this; }
28 bool operator==(const OptionalInt& o) const { return value == o.value; }
29 bool operator!=(const OptionalInt& o) const { return value != o.value; }
30 bool operator<(const OptionalInt& o) const {
31 return has_value() && o.has_value() && value < o.value;
32 }
33 bool operator==(int n) const { return value == n; }
34 bool operator!=(int n) const { return value != n; }
36 return OptionalInt(has_value() && o.has_value() ? value + o.value : N);
37 }
39 return OptionalInt(has_value() && o.has_value() ? value - o.value : N);
40 }
41 OptionalInt& operator+=(int n) { if (has_value()) value += n; return *this; }
42 OptionalInt& operator-=(int n) { if (has_value()) value -= n; return *this; }
43 explicit operator int() const { return value; }
44 explicit operator bool() const { return has_value(); }
45 // these are defined for partial compatibility with C++17 std::optional
46 using value_type = int;
47 int& operator*() { return value; }
48 const int& operator*() const { return value; }
49 int& emplace(int n) { value = n; return value; }
50 void reset() noexcept { value = None; }
51};
52
53struct SeqId {
55
56 OptionalNum num; // sequence number
57 char icode = ' '; // insertion code
58
59 SeqId() = default;
60 SeqId(int num_, char icode_) { num = num_; icode = icode_; }
62 explicit SeqId(const std::string& str) {
63 char* endptr;
64 num = std::strtol(str.c_str(), &endptr, 10);
65 if (endptr == str.c_str() || (*endptr != '\0' && endptr[1] != '\0'))
66 throw std::invalid_argument("Not a seqid: " + str);
67 icode = (*endptr | 0x20);
68 }
69
70 bool operator==(const SeqId& o) const {
71 return num == o.num && ((icode ^ o.icode) & ~0x20) == 0;
72 }
73 bool operator!=(const SeqId& o) const { return !operator==(o); }
74 bool operator<(const SeqId& o) const {
75 return (*num * 256 + icode) < (*o.num * 256 + o.icode);
76 }
77 bool operator<=(const SeqId& o) const { return !(o < *this); }
78
79 char has_icode() const { return icode != ' '; }
80
81 std::string str() const {
82 std::string r = num.str();
83 if (icode != ' ')
84 r += icode;
85 return r;
86 }
87};
88
89// Sequence ID (sequence number + insertion code) + residue name + segment ID
90struct ResidueId {
92 std::string segment; // segid - up to 4 characters in the PDB file
93 std::string name;
94
95 // used for first_conformation iterators, etc.
96 SeqId group_key() const { return seqid; }
97
98 bool matches(const ResidueId& o) const {
99 return seqid == o.seqid && segment == o.segment && name == o.name;
100 }
101 bool matches_noseg(const ResidueId& o) const {
102 return seqid == o.seqid && name == o.name;
103 }
104 bool operator==(const ResidueId& o) const { return matches(o); }
105 std::string str() const { return cat(seqid.str(), '(', name, ')'); }
106};
107
108inline std::string atom_str(const std::string& chain_name,
109 const ResidueId& res_id,
110 const std::string& atom_name,
111 char altloc) {
112 std::string r = chain_name;
113 r += '/';
114 r += res_id.name;
115 r += ' ';
116 r += res_id.seqid.str();
117 r += '/';
118 r += atom_name;
119 if (altloc) {
120 r += '.';
121 r += altloc;
122 }
123 return r;
124}
125
127 std::string chain_name;
129 std::string atom_name;
130 char altloc = '\0';
131
132 AtomAddress() = default;
133 AtomAddress(const std::string& ch, const ResidueId& resid,
134 const std::string& atom, char alt='\0')
135 : chain_name(ch), res_id(resid), atom_name(atom), altloc(alt) {}
136 AtomAddress(const std::string& ch, const SeqId& seqid, const std::string& res,
137 const std::string& atom, char alt='\0')
138 : chain_name(ch), res_id({seqid, "", res}), atom_name(atom), altloc(alt) {}
139 bool operator==(const AtomAddress& o) const {
140 return chain_name == o.chain_name && res_id.matches(o.res_id) &&
141 atom_name == o.atom_name && altloc == o.altloc;
142 }
143
144 std::string str() const {
146 }
147};
148
149} // namespace gemmi
150
151namespace std {
152template <> struct hash<gemmi::ResidueId> {
153 size_t operator()(const gemmi::ResidueId& r) const {
154 size_t seqid_hash = (*r.seqid.num << 7) + (r.seqid.icode | 0x20);
155 return seqid_hash ^ hash<string>()(r.segment) ^ hash<string>()(r.name);
156 }
157};
158} // namespace std
159
160#endif
std::string atom_str(const Chain &chain, const ResidueId &res_id, const Atom &atom)
Definition model.hpp:613
std::string cat(Args const &... args)
Definition util.hpp:33
Definition seqid.hpp:151
std::string chain_name
Definition seqid.hpp:127
AtomAddress(const std::string &ch, const ResidueId &resid, const std::string &atom, char alt='\0')
Definition seqid.hpp:133
AtomAddress(const std::string &ch, const SeqId &seqid, const std::string &res, const std::string &atom, char alt='\0')
Definition seqid.hpp:136
AtomAddress()=default
std::string atom_name
Definition seqid.hpp:129
bool operator==(const AtomAddress &o) const
Definition seqid.hpp:139
ResidueId res_id
Definition seqid.hpp:128
std::string str() const
Definition seqid.hpp:144
std::string str(char null='?') const
Definition seqid.hpp:24
int & emplace(int n)
Definition seqid.hpp:49
OptionalInt()=default
bool operator==(int n) const
Definition seqid.hpp:33
bool operator!=(const OptionalInt &o) const
Definition seqid.hpp:29
OptionalInt(int n)
Definition seqid.hpp:22
OptionalInt & operator-=(int n)
Definition seqid.hpp:42
void reset() noexcept
Definition seqid.hpp:50
bool operator==(const OptionalInt &o) const
Definition seqid.hpp:28
bool has_value() const
Definition seqid.hpp:23
const int & operator*() const
Definition seqid.hpp:48
OptionalInt operator+(OptionalInt o) const
Definition seqid.hpp:35
bool operator<(const OptionalInt &o) const
Definition seqid.hpp:30
OptionalInt & operator=(int n)
Definition seqid.hpp:27
bool operator!=(int n) const
Definition seqid.hpp:34
OptionalInt & operator+=(int n)
Definition seqid.hpp:41
int & operator*()
Definition seqid.hpp:47
OptionalInt operator-(OptionalInt o) const
Definition seqid.hpp:38
std::string name
Definition seqid.hpp:93
SeqId group_key() const
Definition seqid.hpp:96
bool operator==(const ResidueId &o) const
Definition seqid.hpp:104
std::string segment
Definition seqid.hpp:92
bool matches(const ResidueId &o) const
Definition seqid.hpp:98
std::string str() const
Definition seqid.hpp:105
bool matches_noseg(const ResidueId &o) const
Definition seqid.hpp:101
OptionalNum num
Definition seqid.hpp:56
SeqId(int num_, char icode_)
Definition seqid.hpp:60
bool operator==(const SeqId &o) const
Definition seqid.hpp:70
SeqId(OptionalNum num_, char icode_)
Definition seqid.hpp:61
char has_icode() const
Definition seqid.hpp:79
bool operator<(const SeqId &o) const
Definition seqid.hpp:74
bool operator<=(const SeqId &o) const
Definition seqid.hpp:77
bool operator!=(const SeqId &o) const
Definition seqid.hpp:73
SeqId()=default
char icode
Definition seqid.hpp:57
SeqId(const std::string &str)
Definition seqid.hpp:62
std::string str() const
Definition seqid.hpp:81
size_t operator()(const gemmi::ResidueId &r) const
Definition seqid.hpp:153
Utilities. Mostly for working with strings and vectors.