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> void addAll(const T &descriptors) {
100  for (const auto &descriptor : descriptors) {
101  add(descriptor);
102  }
103  }
104 
105  /**
106  * Access a positive integer that represents the like/unlike pairings of
107  * this descriptor list. The like/unlike is represented by set bits in an
108  * integer value and means larger integer values indicates a higher
109  * descriptor pairing preference.
110  *
111  * @return an integer representing the descriptor pairings
112  */
113  std::uint32_t getPairing() const { return d_pairing; }
114 
115  int compareTo(const PairList &that) const {
116  if (d_descriptors.size() != that.d_descriptors.size()) {
117  throw std::runtime_error("Descriptor lists should be the same length!");
118  }
119  Descriptor thisRef = d_descriptors[0];
120  Descriptor thatRef = that.d_descriptors[0];
121  for (auto i = 1u; i < d_descriptors.size(); ++i) {
122  if (thisRef == d_descriptors[i] && thatRef != that.d_descriptors[i]) {
123  return +1;
124  }
125  if (thisRef != d_descriptors[i] && thatRef == that.d_descriptors[i]) {
126  return -1;
127  }
128  }
129  return 0;
130  }
131 
132  bool operator<(const PairList &that) const { return compareTo(that) == -1; }
133 
134  std::string toString() const {
135  // handles cases that would break the toString method
136  if (d_descriptors.empty() || d_descriptors[0] == Descriptor::NONE) {
137  return "";
138  }
139 
140  std::stringstream ss;
141  auto basis = d_descriptors[0];
142  ss << to_string(basis) << ':';
143 
144  basis = ref(basis);
145 
146  // build like (l) / unlike (u) descriptor pairing
147  for (auto it = d_descriptors.begin() + 1; it != d_descriptors.end(); ++it) {
148  ss << (basis == ref(*it) ? "l" : "u");
149  }
150 
151  return ss.str();
152  }
153 
154 private:
155  std::vector<Descriptor> d_descriptors;
156 
157  std::uint32_t d_pairing = 0;
158 
159  /**
160  * Adds the descriptor to the descriptor list and stores the pair in an set
161  * bit (32-bit integer).
162  *
163  * @param descriptor the descriptor to add an pair
164  * @return whether the descriptor was added
165  */
166  void addAndPair(Descriptor descriptor) {
167  // if this isn't the first descriptor - check the pairing
168  if (!d_descriptors.empty() && d_descriptors[0] == descriptor) {
169  // set the bit to indicate a pair
170  d_pairing |= 0x1 << (31 - d_descriptors.size());
171  }
172  d_descriptors.push_back(ref(descriptor));
173  }
174 };
175 
176 } // namespace CIPLabeler
177 } // namespace RDKit
bool operator<(const PairList &that) const
Definition: Pairlist.h:132
std::string toString() const
Definition: Pairlist.h:134
PairList(Descriptor ref)
Definition: Pairlist.h:51
static Descriptor ref(Descriptor descriptor)
Definition: Pairlist.h:34
std::uint32_t getPairing() const
Definition: Pairlist.h:113
int compareTo(const PairList &that) const
Definition: Pairlist.h:115
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:99
Descriptor getRefDescriptor() const
Definition: Pairlist.h:68
static std::string to_string(const Descriptor &desc)
Definition: Descriptor.h:54
Std stuff.
Definition: Abbreviations.h:17