OpenMS  3.0.0
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-2022.
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 
62  template <typename RandomAccessContainer>
64  {
65 public:
66 
67  typedef std::unordered_map<UInt64, Size> UniqueIdMap;
68 
84  Size
85  uniqueIdToIndex(UInt64 unique_id) const
86  {
87  Size index;
88  try
89  {
90  index = uniqueid_to_index_.at(unique_id);
91  if (getBase_().at(index).getUniqueId() != unique_id)
92  {
93  throw std::out_of_range("unique_id_to_index_");
94  }
95  }
96  catch (std::out_of_range &)
97  {
98  try
99  {
100  this->updateUniqueIdToIndex();
101  index = uniqueid_to_index_.at(unique_id);
102  }
103  catch (std::out_of_range &)
104  {
105  index = -1; // which means: invalid
106  }
107  }
108  return index;
109  }
110 
115  void
117  {
118  Size num_valid_unique_id = 0;
119  // add or update unique id of existing features
120  for (Size index = 0; index < getBase_().size(); ++index)
121  {
122  UInt64 unique_id = getBase_()[index].getUniqueId();
123  if (UniqueIdInterface::isValid(unique_id))
124  {
125  uniqueid_to_index_[unique_id] = index;
126  ++num_valid_unique_id;
127  }
128  }
129  // remove invalid or outdated entries
131  for (UniqueIdMap::iterator iter = uniqueid_to_index_.begin(); iter != uniqueid_to_index_.end(); /* see loop */)
132  {
133  if (iter->second >= getBase_().size() || getBase_()[iter->second].getUniqueId() != iter->first)
134  {
135  iter = uniqueid_to_index_.erase(iter);
136  }
137  else
138  {
139  ++iter;
140  }
141  }
142  if (uniqueid_to_index_.size() != num_valid_unique_id)
143  {
144  std::stringstream ss;
145  ss << "Duplicate valid unique ids detected! RandomAccessContainer has size()==" << getBase_().size();
146  ss << ", num_valid_unique_id==" << num_valid_unique_id;
147  ss << ", uniqueid_to_index_.size()==" << uniqueid_to_index_.size();
148  throw Exception::Postcondition(__FILE__, __LINE__, OPENMS_PRETTY_FUNCTION, ss.str());
149  }
150  return;
151  }
152 
166  Size
168  {
169  Size invalid_uids(0);
170  uniqueid_to_index_.clear();
171  // add unique id of existing features
172  for (Size index = 0; index < getBase_().size(); ++index)
173  {
174  UInt64 unique_id = getBase_()[index].getUniqueId();
175  if (!UniqueIdInterface::isValid(unique_id))
176  {
177  getBase_()[index].ensureUniqueId();
178  unique_id = getBase_()[index].getUniqueId();
179  }
180 
181  // see if UID already present
182  while (uniqueid_to_index_.find(unique_id) != uniqueid_to_index_.end()) // double entry!
183  {
184  getBase_()[index].setUniqueId();
185  unique_id = getBase_()[index].getUniqueId();
186  ++invalid_uids;
187  }
188 
189  uniqueid_to_index_[unique_id] = index;
190 
191  }
192 
193  return invalid_uids;
194  }
195 
200  void
202  {
203  std::swap(uniqueid_to_index_, rhs.uniqueid_to_index_);
204  return;
205  }
206 
207 protected:
208 
213  const RandomAccessContainer &
214  getBase_() const
215  {
216  return *static_cast<const RandomAccessContainer *>(this);
217  }
218 
223  RandomAccessContainer &
225  {
226  return *static_cast<RandomAccessContainer *>(this);
227  }
228 
234 
235  };
236 
237 } //namespace OpenMS
238 
OpenMS::Exception::Postcondition
Postcondition failed exception.
Definition: Exception.h:171
OpenMS::UniqueIdIndexer::updateUniqueIdToIndex
void updateUniqueIdToIndex() const
Updates the hash map from unique id to index.
Definition: UniqueIdIndexer.h:116
UniqueIdInterface.h
OpenMS::UInt64
OPENMS_UINT64_TYPE UInt64
Unsigned integer type (64bit)
Definition: Types.h:77
OpenMS::Size
size_t Size
Size type e.g. used as variable which can hold result of size()
Definition: Types.h:127
OpenMS::UniqueIdIndexer::swap
void swap(UniqueIdIndexer &rhs)
Swap.
Definition: UniqueIdIndexer.h:201
OpenMS::UniqueIdIndexer::uniqueIdToIndex
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:85
OpenMS
Main OpenMS namespace.
Definition: FeatureDeconvolution.h:47
Exception.h
OpenMS::UniqueIdIndexer
A base class for random access containers for classes derived from UniqueIdInterface that adds functi...
Definition: UniqueIdIndexer.h:63
OpenMS::UniqueIdIndexer::getBase_
const RandomAccessContainer & getBase_() const
A little helper to get access to the base (!) class RandomAccessContainer.
Definition: UniqueIdIndexer.h:214
OpenMS::UniqueIdIndexer::resolveUniqueIdConflicts
Size resolveUniqueIdConflicts()
Assign new UID's to doubly occurring UID's.
Definition: UniqueIdIndexer.h:167
OpenMS::UniqueIdInterface::INVALID
Definition: UniqueIdInterface.h:60
OpenMS::UniqueIdIndexer::uniqueid_to_index_
UniqueIdMap uniqueid_to_index_
hash map from unique id to index of features
Definition: UniqueIdIndexer.h:233
OpenMS::UniqueIdIndexer::getBase_
RandomAccessContainer & getBase_()
A little helper to get access to the base (!) class RandomAccessContainer.
Definition: UniqueIdIndexer.h:224
OpenMS::UniqueIdIndexer::UniqueIdMap
std::unordered_map< UInt64, Size > UniqueIdMap
Definition: UniqueIdIndexer.h:67
OpenMS::UniqueIdInterface::isValid
static bool isValid(UInt64 unique_id)
Returns true if the unique_id is valid, false otherwise.
Definition: UniqueIdInterface.h:68