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};
51
52struct SeqId {
54
55 OptionalNum num; // sequence number
56 char icode = ' '; // insertion code
57
58 SeqId() = default;
59 SeqId(int num_, char icode_) { num = num_; icode = icode_; }
61 explicit SeqId(const std::string& str) {
62 char* endptr;
63 num = std::strtol(str.c_str(), &endptr, 10);
64 if (endptr == str.c_str() || (*endptr != '\0' && endptr[1] != '\0'))
65 throw std::invalid_argument("Not a seqid: " + str);
66 icode = (*endptr | 0x20);
67 }
68
69 bool operator==(const SeqId& o) const {
70 return num == o.num && ((icode ^ o.icode) & ~0x20) == 0;
71 }
72 bool operator!=(const SeqId& o) const { return !operator==(o); }
73 bool operator<(const SeqId& o) const {
74 return (*num * 256 + icode) < (*o.num * 256 + o.icode);
75 }
76
77 char has_icode() const { return icode != ' '; }
78
79 std::string str() const {
80 std::string r = num.str();
81 if (icode != ' ')
82 r += icode;
83 return r;
84 }
85};
86
87// Sequence ID (sequence number + insertion code) + residue name + segment ID
88struct ResidueId {
90 std::string segment; // segid - up to 4 characters in the PDB file
91 std::string name;
92
93 // used for first_conformation iterators, etc.
94 SeqId group_key() const { return seqid; }
95
96 bool matches(const ResidueId& o) const {
97 return seqid == o.seqid && segment == o.segment && name == o.name;
98 }
99 bool matches_noseg(const ResidueId& o) const {
100 return seqid == o.seqid && name == o.name;
101 }
102 bool operator==(const ResidueId& o) const { return matches(o); }
103 std::string str() const { return cat(seqid.str(), '(', name, ')'); }
104};
105
106inline std::string atom_str(const std::string& chain_name,
107 const ResidueId& res_id,
108 const std::string& atom_name,
109 char altloc) {
110 std::string r = chain_name;
111 r += '/';
112 r += res_id.name;
113 r += ' ';
114 r += res_id.seqid.str();
115 r += '/';
116 r += atom_name;
117 if (altloc) {
118 r += '.';
119 r += altloc;
120 }
121 return r;
122}
123
125 std::string chain_name;
127 std::string atom_name;
128 char altloc = '\0';
129
130 AtomAddress() = default;
131 AtomAddress(const std::string& ch, const ResidueId& resid,
132 const std::string& atom, char alt='\0')
133 : chain_name(ch), res_id(resid), atom_name(atom), altloc(alt) {}
134 AtomAddress(const std::string& ch, const SeqId& seqid, const std::string& res,
135 const std::string& atom, char alt='\0')
136 : chain_name(ch), res_id({seqid, "", res}), atom_name(atom), altloc(alt) {}
137 bool operator==(const AtomAddress& o) const {
138 return chain_name == o.chain_name && res_id.matches(o.res_id) &&
139 atom_name == o.atom_name && altloc == o.altloc;
140 }
141
142 std::string str() const {
144 }
145};
146
147} // namespace gemmi
148
149namespace std {
150template <> struct hash<gemmi::ResidueId> {
151 size_t operator()(const gemmi::ResidueId& r) const {
152 size_t seqid_hash = (*r.seqid.num << 7) + (r.seqid.icode | 0x20);
153 return seqid_hash ^ hash<string>()(r.segment) ^ hash<string>()(r.name);
154 }
155};
156} // namespace std
157
158#endif
std::string atom_str(const Chain &chain, const ResidueId &res_id, const Atom &atom)
Definition model.hpp:591
std::string cat(Args const &... args)
Definition util.hpp:32
Definition seqid.hpp:149
std::string chain_name
Definition seqid.hpp:125
AtomAddress(const std::string &ch, const ResidueId &resid, const std::string &atom, char alt='\0')
Definition seqid.hpp:131
AtomAddress(const std::string &ch, const SeqId &seqid, const std::string &res, const std::string &atom, char alt='\0')
Definition seqid.hpp:134
AtomAddress()=default
std::string atom_name
Definition seqid.hpp:127
bool operator==(const AtomAddress &o) const
Definition seqid.hpp:137
ResidueId res_id
Definition seqid.hpp:126
std::string str() const
Definition seqid.hpp:142
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
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:91
SeqId group_key() const
Definition seqid.hpp:94
bool operator==(const ResidueId &o) const
Definition seqid.hpp:102
std::string segment
Definition seqid.hpp:90
bool matches(const ResidueId &o) const
Definition seqid.hpp:96
std::string str() const
Definition seqid.hpp:103
bool matches_noseg(const ResidueId &o) const
Definition seqid.hpp:99
OptionalNum num
Definition seqid.hpp:55
SeqId(int num_, char icode_)
Definition seqid.hpp:59
bool operator==(const SeqId &o) const
Definition seqid.hpp:69
SeqId(OptionalNum num_, char icode_)
Definition seqid.hpp:60
char has_icode() const
Definition seqid.hpp:77
bool operator<(const SeqId &o) const
Definition seqid.hpp:73
bool operator!=(const SeqId &o) const
Definition seqid.hpp:72
SeqId()=default
char icode
Definition seqid.hpp:56
SeqId(const std::string &str)
Definition seqid.hpp:61
std::string str() const
Definition seqid.hpp:79
size_t operator()(const gemmi::ResidueId &r) const
Definition seqid.hpp:151