OpenMS
Loading...
Searching...
No Matches
DigestionEnzymeDB.h
Go to the documentation of this file.
1// Copyright (c) 2002-present, OpenMS Inc. -- EKU Tuebingen, ETH Zurich, and FU Berlin
2// SPDX-License-Identifier: BSD-3-Clause
3//
4// --------------------------------------------------------------------------
5// $Maintainer: Xiao Liang $
6// $Authors: Xiao Liang, Chris Bielow $
7// --------------------------------------------------------------------------
8
9#pragma once
10
15
16#include <algorithm>
17#include <cctype>
18#include <set>
19#include <map>
20#include <memory>
21
22namespace OpenMS
23{
33 template<typename DigestionEnzymeType, typename InstanceType> class DigestionEnzymeDB
34 {
35 public:
36
40 typedef typename std::set<const DigestionEnzymeType*>::const_iterator ConstEnzymeIterator;
41 typedef typename std::set<const DigestionEnzymeType*>::iterator EnzymeIterator;
43
46 static const InstanceType* getInstance()
47 {
48 // function-local static: initialization is thread-safe (C++11), so concurrent first calls
49 // (e.g. from an OpenMP loop or another Python thread) construct exactly one database
50 static const InstanceType* db_ = new InstanceType;
51 return db_;
52 }
53
59 {
60 for (ConstEnzymeIterator it = const_enzymes_.begin(); it != const_enzymes_.end(); ++it)
61 {
62 delete *it;
63 }
64 }
66
75 const DigestionEnzymeType* getEnzyme(const std::string& name) const
76 {
77 const DigestionEnzymeType* enzyme = findEnzyme_(name);
78 if (enzyme == nullptr)
79 {
80 throw Exception::ElementNotFound(__FILE__, __LINE__, OPENMS_PRETTY_FUNCTION, name);
81 }
82 return enzyme;
83 }
84
87 const DigestionEnzymeType* getEnzymeByRegEx(const std::string& cleavage_regex) const
88 {
89 if (!hasRegEx(cleavage_regex))
90 {
91 // @TODO: why does this use a different exception than "getEnzyme"?
92 throw Exception::IllegalArgument(__FILE__, __LINE__, OPENMS_PRETTY_FUNCTION,
93 std::string("Enzyme with regex " + cleavage_regex + " was not registered in Enzyme DB, register first!").c_str());
94 }
95 return enzyme_regex_.at(cleavage_regex);
96 }
97
99 void getAllNames(std::vector<std::string>& all_names) const
100 {
101 all_names.clear();
102 for (ConstEnzymeIterator it = const_enzymes_.begin(); it != const_enzymes_.end(); ++it)
103 {
104 all_names.push_back((*it)->getName());
105 }
106 }
108
113 bool hasEnzyme(const std::string& name) const
114 {
115 return (findEnzyme_(name) != nullptr);
116 }
117
119 bool hasRegEx(const std::string& cleavage_regex) const
120 {
121 return (enzyme_regex_.contains(cleavage_regex));
122 }
123
125 bool hasEnzyme(const DigestionEnzymeType* enzyme) const
126 {
127 return (const_enzymes_.contains(enzyme) );
128 }
130
134 inline ConstEnzymeIterator beginEnzyme() const { return const_enzymes_.begin(); } // we only allow constant iterators -- this DB is not meant to be modifiable
135 inline ConstEnzymeIterator endEnzyme() const { return const_enzymes_.end(); }
136
138 protected:
139 DigestionEnzymeDB() = default;
140
142 DigestionEnzymeDB(const DigestionEnzymeDB& enzymes_db) = delete;
144
149 DigestionEnzymeDB& operator=(const DigestionEnzymeDB& enzymes_db) = delete;
151
154 void addEnzyme_(const DigestionEnzymeType* enzyme)
155 {
156 std::string name = enzyme->getName();
157
158 // if an enzyme with the same name exists, remove the old one first
159 // (compare names only: a synonym or lookup key of another enzyme must not remove that enzyme)
160 auto existing = std::find_if(const_enzymes_.begin(), const_enzymes_.end(),
161 [&name](const DigestionEnzymeType* e) { return e->getName() == name; });
162 if (existing != const_enzymes_.end())
163 {
164 const DigestionEnzymeType* old = *existing;
165 const_enzymes_.erase(existing);
166 // remove old name/synonym entries, but only those that point to the enzyme being replaced
167 auto points_to_old = [old](const auto& entry) { return entry.second == old; };
168 std::erase_if(enzyme_names_, points_to_old);
169 std::erase_if(enzyme_keys_, points_to_old);
170 // remove old regex entry
171 if (!old->getRegEx().empty())
172 {
173 enzyme_regex_.erase(old->getRegEx());
174 }
175 delete old;
176 }
177
178 // add to internal storage
179 const_enzymes_.insert(enzyme);
180 // add to internal indices (by name and its synonyms, as written ...
181 enzyme_names_[name] = enzyme;
182 for (const auto& syn : enzyme->getSynonyms())
183 {
184 enzyme_names_[syn] = enzyme;
185 }
186 // ... and as lookup keys, see getEnzyme(); a synonym never re-points an existing key)
187 enzyme_keys_[lookupKey_(name)] = enzyme;
188 for (const auto& syn : enzyme->getSynonyms())
189 {
190 enzyme_keys_.emplace(lookupKey_(syn), enzyme);
191 }
192 // ... and by regex
193 if (enzyme->getRegEx() != "")
194 {
195 enzyme_regex_[enzyme->getRegEx()] = enzyme;
196 }
197 return;
198 }
199
203 void loadFromProviders_(std::vector<std::unique_ptr<DigestionEnzymeDataProvider<DigestionEnzymeType>>>& providers)
204 {
205 for (auto& provider : providers)
206 {
207 auto enzymes = provider->loadEnzymes();
208 for (auto& enzyme : enzymes)
209 {
210 addEnzyme_(enzyme.release());
211 }
212 }
213 }
214
216 static std::string lookupKey_(const std::string& name)
217 {
218 std::string key;
219 key.reserve(name.size());
220 for (unsigned char c : name)
221 {
222 if (std::isspace(c) || c == '-' || c == '_') continue;
223 key += static_cast<char>(std::tolower(c));
224 }
225 return key;
226 }
227
229 const DigestionEnzymeType* findEnzyme_(const std::string& name) const
230 {
231 auto pos = enzyme_names_.find(name);
232 if (pos != enzyme_names_.end()) return pos->second;
233 pos = enzyme_keys_.find(lookupKey_(name));
234 return (pos != enzyme_keys_.end()) ? pos->second : nullptr;
235 }
236
237 std::map<std::string, const DigestionEnzymeType*> enzyme_names_;
238
239 std::map<std::string, const DigestionEnzymeType*> enzyme_keys_;
240
241 std::map<std::string, const DigestionEnzymeType*> enzyme_regex_;
242
243 std::set<const DigestionEnzymeType*> const_enzymes_;
244
245 };
246}
247
Digestion enzyme database (base class)
Definition DigestionEnzymeDB.h:34
void getAllNames(std::vector< std::string > &all_names) const
returns all the enzyme names (does NOT include synonym names)
Definition DigestionEnzymeDB.h:99
bool hasEnzyme(const std::string &name) const
returns true if the db contains a enzyme with the given name (supports synonym names; matched as in g...
Definition DigestionEnzymeDB.h:113
const DigestionEnzymeType * findEnzyme_(const std::string &name) const
returns the enzyme with the given name or synonym (see getEnzyme()), or nullptr if unknown
Definition DigestionEnzymeDB.h:229
DigestionEnzymeDB(const DigestionEnzymeDB &enzymes_db)=delete
copy constructor
bool hasRegEx(const std::string &cleavage_regex) const
returns true if the db contains a enzyme with the given regex
Definition DigestionEnzymeDB.h:119
ConstEnzymeIterator endEnzyme() const
Definition DigestionEnzymeDB.h:135
virtual ~DigestionEnzymeDB()
destructor
Definition DigestionEnzymeDB.h:58
static std::string lookupKey_(const std::string &name)
key for lenient name lookup (see getEnzyme()): lowercase, without whitespace, '-' and '_'
Definition DigestionEnzymeDB.h:216
void loadFromProviders_(std::vector< std::unique_ptr< DigestionEnzymeDataProvider< DigestionEnzymeType > > > &providers)
Definition DigestionEnzymeDB.h:203
ConstEnzymeIterator beginEnzyme() const
Definition DigestionEnzymeDB.h:134
std::map< std::string, const DigestionEnzymeType * > enzyme_names_
index by names and synonyms (as written)
Definition DigestionEnzymeDB.h:237
const DigestionEnzymeType * getEnzymeByRegEx(const std::string &cleavage_regex) const
Definition DigestionEnzymeDB.h:87
static const InstanceType * getInstance()
Definition DigestionEnzymeDB.h:46
std::map< std::string, const DigestionEnzymeType * > enzyme_regex_
index by regex
Definition DigestionEnzymeDB.h:241
DigestionEnzymeDB & operator=(const DigestionEnzymeDB &enzymes_db)=delete
assignment operator
std::set< constDigestionEnzymeType * >::const_iterator ConstEnzymeIterator
Definition DigestionEnzymeDB.h:40
std::map< std::string, const DigestionEnzymeType * > enzyme_keys_
index by lookupKey_() of names and synonyms
Definition DigestionEnzymeDB.h:239
std::set< constDigestionEnzymeType * >::iterator EnzymeIterator
Definition DigestionEnzymeDB.h:41
bool hasEnzyme(const DigestionEnzymeType *enzyme) const
returns true if the db contains the enzyme of the given pointer
Definition DigestionEnzymeDB.h:125
const DigestionEnzymeType * getEnzyme(const std::string &name) const
Definition DigestionEnzymeDB.h:75
std::set< const DigestionEnzymeType * > const_enzymes_
set of enzymes
Definition DigestionEnzymeDB.h:243
void addEnzyme_(const DigestionEnzymeType *enzyme)
Definition DigestionEnzymeDB.h:154
Abstract interface for providing digestion enzyme data.
Definition DigestionEnzymeDataProvider.h:30
Element could not be found exception.
Definition Exception.h:657
A method or algorithm argument contains illegal values.
Definition Exception.h:633
Main OpenMS namespace.
Definition openswathalgo/include/OpenMS/OPENSWATHALGO/DATAACCESS/ISpectrumAccess.h:19