RDKit
Open-source cheminformatics and machine learning.
Loading...
Searching...
No Matches
Pairlist.h
Go to the documentation of this file.
1//
2//
3// Copyright (C) 2020 Schrödinger, LLC
4//
5// @@ All Rights Reserved @@
6// This file is part of the RDKit.
7// The contents are covered by the terms of the BSD license
8// which is included in the file license.txt, found at the root
9// of the RDKit source tree.
10//
11#pragma once
12
13#include <cstdint>
14#include <sstream>
15#include <string>
16#include <vector>
17
18#include "../Descriptor.h"
19
20namespace RDKit {
21namespace CIPLabeler {
22
23/**
24 * Implementation of a descriptor list that allows descriptors to be added and
25 * ignored. The list maintains an integer value throughout which stores the
26 * pairing of descriptors and allows easy comparison between descriptor lists in
27 * that higher priority descriptor pairing will always have a higher integer
28 * value. The integer value can be access via the {@link #getPairing()} method.
29 *
30 * @see Descriptor
31 */
32class PairList {
33 public:
34 static Descriptor ref(Descriptor descriptor) {
35 switch (descriptor) {
36 case Descriptor::R:
37 case Descriptor::M:
39 return Descriptor::R;
40 case Descriptor::S:
41 case Descriptor::P:
43 return Descriptor::S;
44 default:
45 return Descriptor::NONE;
46 }
47 }
48
49 PairList() = default;
50
52
53 /**
54 * Creates a new list from a provided head and tail. The head and tail
55 * ignored descriptors are first transferred and then their descriptors. In
56 * either list, descriptors that are ignored by the other will be not be
57 * added to the new instance.
58 *
59 * @param head the head of the list (prefix)
60 * @param tail the tail of the list (suffix)
61 */
63 // add descriptors to the new instance (ignored descriptors not added)
64 addAll(head.d_descriptors);
65 addAll(tail.d_descriptors);
66 }
67
68 Descriptor getRefDescriptor() const { return ref(d_descriptors[0]); }
69
70 /**
71 * Adds a descriptor to the descriptor list. If the provided descriptor is
72 * present in the ignore set the descriptor will not be added.
73 *
74 * @param descriptor the descriptor to add.
75 * @return whether the descriptor was added to the list
76 */
77
78 bool add(Descriptor descriptor) {
79 switch (descriptor) {
80 case Descriptor::R:
81 case Descriptor::S:
82 case Descriptor::M:
83 case Descriptor::P:
86 addAndPair(descriptor);
87 return true;
88 default:
89 return false;
90 }
91 }
92
93 /**
94 * Adds multiple descriptors to the descriptor list. If the descriptor is
95 * present in the ignore set it will not be added to the list.
96 *
97 * @param descriptors a collection of descriptors to be added
98 */
99 template <typename T>
100 void addAll(const T &descriptors) {
101 for (const auto &descriptor : descriptors) {
102 add(descriptor);
103 }
104 }
105
106 /**
107 * Access a positive integer that represents the like/unlike pairings of
108 * this descriptor list. The like/unlike is represented by set bits in an
109 * integer value and means larger integer values indicates a higher
110 * descriptor pairing preference.
111 *
112 * @return an integer representing the descriptor pairings
113 */
114 std::uint32_t getPairing() const { return d_pairing; }
115
116 int compareTo(const PairList &that) const {
117 if (d_descriptors.size() != that.d_descriptors.size()) {
118 throw std::runtime_error("Descriptor lists should be the same length!");
119 }
120 Descriptor thisRef = d_descriptors[0];
121 Descriptor thatRef = that.d_descriptors[0];
122 for (auto i = 1u; i < d_descriptors.size(); ++i) {
123 if (thisRef == d_descriptors[i] && thatRef != that.d_descriptors[i]) {
124 return +1;
125 }
126 if (thisRef != d_descriptors[i] && thatRef == that.d_descriptors[i]) {
127 return -1;
128 }
129 }
130 return 0;
131 }
132
133 bool operator<(const PairList &that) const { return compareTo(that) == -1; }
134
135 std::string toString() const {
136 // handles cases that would break the toString method
137 if (d_descriptors.empty() || d_descriptors[0] == Descriptor::NONE) {
138 return "";
139 }
140
141 std::stringstream ss;
142 auto basis = d_descriptors[0];
143 ss << to_string(basis) << ':';
144
145 basis = ref(basis);
146
147 // build like (l) / unlike (u) descriptor pairing
148 for (auto it = d_descriptors.begin() + 1; it != d_descriptors.end(); ++it) {
149 ss << (basis == ref(*it) ? "l" : "u");
150 }
151
152 return ss.str();
153 }
154
155 private:
156 std::vector<Descriptor> d_descriptors;
157
158 std::uint32_t d_pairing = 0;
159
160 /**
161 * Adds the descriptor to the descriptor list and stores the pair in an set
162 * bit (32-bit integer).
163 *
164 * @param descriptor the descriptor to add an pair
165 * @return whether the descriptor was added
166 */
167 void addAndPair(Descriptor descriptor) {
168 // if this isn't the first descriptor - check the pairing
169 if (!d_descriptors.empty() && d_descriptors[0] == descriptor) {
170 // set the bit to indicate a pair
171 d_pairing |= 0x1 << (31 - d_descriptors.size());
172 }
173 d_descriptors.push_back(ref(descriptor));
174 }
175};
176
177} // namespace CIPLabeler
178} // namespace RDKit
bool operator<(const PairList &that) const
Definition Pairlist.h:133
std::string toString() const
Definition Pairlist.h:135
PairList(Descriptor ref)
Definition Pairlist.h:51
static Descriptor ref(Descriptor descriptor)
Definition Pairlist.h:34
std::uint32_t getPairing() const
Definition Pairlist.h:114
int compareTo(const PairList &that) const
Definition Pairlist.h:116
bool add(Descriptor descriptor)
Definition Pairlist.h:78
PairList(const PairList &head, const PairList &tail)
Definition Pairlist.h:62
void addAll(const T &descriptors)
Definition Pairlist.h:100
Descriptor getRefDescriptor() const
Definition Pairlist.h:68
static std::string to_string(const Descriptor &desc)
Definition Descriptor.h:54
Std stuff.
bool rdvalue_is(const RDValue_cast_t)