OpenMS
UniqueIdIndexer.h
Go to the documentation of this file.
1 // --------------------------------------------------------------------------
2 // OpenMS -- Open-Source Mass Spectrometry
3 // --------------------------------------------------------------------------
4 // Copyright The OpenMS Team -- Eberhard Karls University Tuebingen,
5 // ETH Zurich, and Freie Universitaet Berlin 2002-2023.
6 //
7 // This software is released under a three-clause BSD license:
8 // * Redistributions of source code must retain the above copyright
9 // notice, this list of conditions and the following disclaimer.
10 // * Redistributions in binary form must reproduce the above copyright
11 // notice, this list of conditions and the following disclaimer in the
12 // documentation and/or other materials provided with the distribution.
13 // * Neither the name of any author or any participating institution
14 // may be used to endorse or promote products derived from this software
15 // without specific prior written permission.
16 // For a full list of authors, refer to the file AUTHORS.
17 // --------------------------------------------------------------------------
18 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
19 // AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
20 // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
21 // ARE DISCLAIMED. IN NO EVENT SHALL ANY OF THE AUTHORS OR THE CONTRIBUTING
22 // INSTITUTIONS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
23 // EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
24 // PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
25 // OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
26 // WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
27 // OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
28 // ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29 //
30 // --------------------------------------------------------------------------
31 // $Maintainer: Chris Bielow $
32 // $Authors: Clemens Groepl $
33 // --------------------------------------------------------------------------
34 
35 #pragma once
36 
39 
40 #ifdef _MSC_VER // disable some BOOST warnings that distract from ours
41 # pragma warning( push ) // save warning state
42 # pragma warning( disable : 4396 )
43 #endif
44 
45 #include <unordered_map>
46 #include <sstream>
47 
48 #ifdef _MSC_VER
49 # pragma warning( pop ) // restore old warning state
50 #endif
51 
52 
53 namespace OpenMS
54 {
55 
65  template<typename T>
67  {
68 public:
69  typedef std::unordered_map<UInt64, Size> UniqueIdMap;
70 
86  Size
87  uniqueIdToIndex(UInt64 unique_id) const
88  {
89  Size index;
90  try
91  {
92  index = uniqueid_to_index_.at(unique_id);
93  if (getBase_().at(index).getUniqueId() != unique_id)
94  {
95  throw std::out_of_range("unique_id_to_index_");
96  }
97  }
98  catch (std::out_of_range &)
99  {
100  try
101  {
102  this->updateUniqueIdToIndex();
103  index = uniqueid_to_index_.at(unique_id);
104  }
105  catch (std::out_of_range &)
106  {
107  index = -1; // which means: invalid
108  }
109  }
110  return index;
111  }
112 
117  void
119  {
120  Size num_valid_unique_id = 0;
121  // add or update unique id of existing features
122  for (Size index = 0; index < getBase_().size(); ++index)
123  {
124  UInt64 unique_id = getBase_()[index].getUniqueId();
125  if (UniqueIdInterface::isValid(unique_id))
126  {
127  uniqueid_to_index_[unique_id] = index;
128  ++num_valid_unique_id;
129  }
130  }
131  // remove invalid or outdated entries
133  for (UniqueIdMap::iterator iter = uniqueid_to_index_.begin(); iter != uniqueid_to_index_.end(); /* see loop */)
134  {
135  if (iter->second >= getBase_().size() || getBase_()[iter->second].getUniqueId() != iter->first)
136  {
137  iter = uniqueid_to_index_.erase(iter);
138  }
139  else
140  {
141  ++iter;
142  }
143  }
144  if (uniqueid_to_index_.size() != num_valid_unique_id)
145  {
146  std::stringstream ss;
147  ss << "Duplicate valid unique ids detected! RandomAccessContainer has size()==" << getBase_().size();
148  ss << ", num_valid_unique_id==" << num_valid_unique_id;
149  ss << ", uniqueid_to_index_.size()==" << uniqueid_to_index_.size();
150  throw Exception::Postcondition(__FILE__, __LINE__, OPENMS_PRETTY_FUNCTION, ss.str());
151  }
152  return;
153  }
154 
168  Size
170  {
171  Size invalid_uids(0);
172  uniqueid_to_index_.clear();
173  // add unique id of existing features
174  for (Size index = 0; index < getBase_().size(); ++index)
175  {
176  UInt64 unique_id = getBase_()[index].getUniqueId();
177  if (!UniqueIdInterface::isValid(unique_id))
178  {
179  getBase_()[index].ensureUniqueId();
180  unique_id = getBase_()[index].getUniqueId();
181  }
182 
183  // see if UID already present
184  while (uniqueid_to_index_.find(unique_id) != uniqueid_to_index_.end()) // double entry!
185  {
186  getBase_()[index].setUniqueId();
187  unique_id = getBase_()[index].getUniqueId();
188  ++invalid_uids;
189  }
190 
191  uniqueid_to_index_[unique_id] = index;
192 
193  }
194 
195  return invalid_uids;
196  }
197 
202  void
204  {
205  std::swap(uniqueid_to_index_, rhs.uniqueid_to_index_);
206  return;
207  }
208 
209 protected:
210 
213  const auto& getBase_() const
214  {
215  const T& derived = static_cast<const T&>(*this); // using CRTP
216  return derived.getData();
217  }
218 
221  auto& getBase_()
222  {
223  T& derived = static_cast<T&>(*this); // using CRTP
224  return derived.getData();
225  }
226 
232 
233  };
234 
235 } //namespace OpenMS
236 
Postcondition failed exception.
Definition: Exception.h:173
A base class for containers with elements derived from UniqueIdInterface. This adds functionality to ...
Definition: UniqueIdIndexer.h:67
const auto & getBase_() const
A little helper to get access to the base (!) class RandomAccessContainer.
Definition: UniqueIdIndexer.h:213
std::unordered_map< UInt64, Size > UniqueIdMap
Definition: UniqueIdIndexer.h:69
UniqueIdMap uniqueid_to_index_
hash map from unique id to index of features
Definition: UniqueIdIndexer.h:231
Size uniqueIdToIndex(UInt64 unique_id) const
Returns the index of the feature with the given unique id, or Size(-1) if none exists in this random ...
Definition: UniqueIdIndexer.h:87
Size resolveUniqueIdConflicts()
Assign new UID's to doubly occurring UID's.
Definition: UniqueIdIndexer.h:169
void updateUniqueIdToIndex() const
Updates the hash map from unique id to index.
Definition: UniqueIdIndexer.h:118
auto & getBase_()
A little helper to get access to the base (!) class RandomAccessContainer.
Definition: UniqueIdIndexer.h:221
void swap(UniqueIdIndexer &rhs)
Swap.
Definition: UniqueIdIndexer.h:203
static bool isValid(UInt64 unique_id)
Returns true if the unique_id is valid, false otherwise.
Definition: UniqueIdInterface.h:68
@ INVALID
Definition: UniqueIdInterface.h:60
OPENMS_UINT64_TYPE UInt64
Unsigned integer type (64bit)
Definition: Types.h:77
size_t Size
Size type e.g. used as variable which can hold result of size()
Definition: Types.h:127
Main OpenMS namespace.
Definition: FeatureDeconvolution.h:48