RDKit
Open-source cheminformatics and machine learning.
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 
20 namespace RDKit {
21 namespace 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  */
32 class PairList {
33  public:
34  static Descriptor ref(Descriptor descriptor) {
35  switch (descriptor) {
36  case Descriptor::R:
37  case Descriptor::M:
38  case Descriptor::seqCis:
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  */
62  PairList(const PairList &head, const PairList &tail) {
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:
85  case Descriptor::seqCis:
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.
Definition: Abbreviations.h:19