Line data Source code
1 : #include "ReactionTable.hpp" 2 : #include "ExceptionWithLocation.hpp" 3 : #include "Reaction.hpp" 4 : 5 : #include <algorithm> 6 : 7 : namespace cell 8 : { 9 : 10 15 : ReactionTable::ReactionTable(const DiscTypeRegistry& discTypeRegistry) 11 15 : : discTypeRegistry_(discTypeRegistry) 12 : { 13 15 : } 14 : 15 11 : const DiscTypeMap<std::vector<Reaction>>& ReactionTable::getTransformations() const 16 : { 17 11 : return transformations_; 18 : } 19 : 20 11 : const DiscTypeMap<std::vector<Reaction>>& ReactionTable::getDecompositions() const 21 : { 22 11 : return decompositions_; 23 : } 24 : 25 11 : const DiscTypePairMap<std::vector<Reaction>>& ReactionTable::getCombinations() const 26 : { 27 11 : return combinations_; 28 : } 29 : 30 11 : const DiscTypePairMap<std::vector<Reaction>>& ReactionTable::getExchanges() const 31 : { 32 11 : return exchanges_; 33 : } 34 : 35 15 : void ReactionTable::addReaction(const Reaction& reaction) 36 : { 37 15 : reaction.validate(discTypeRegistry_); 38 15 : checkIfIsDuplicateReaction(reaction); 39 : 40 11 : reactions_.push_back(reaction); 41 : 42 11 : createLookupMaps(); 43 11 : } 44 : 45 0 : void ReactionTable::setReactions(const std::vector<Reaction>& reactions) 46 : { 47 0 : reactions_ = reactions; 48 0 : createLookupMaps(); 49 0 : } 50 : 51 0 : void ReactionTable::removeDiscType(DiscTypeID discTypeToRemove) 52 : { 53 0 : std::vector<Reaction> remainingReactions; 54 0 : for (const auto& reaction : reactions_) 55 : { 56 0 : if (reaction.getEduct1() == discTypeToRemove || 57 0 : (reaction.hasEduct2() && reaction.getEduct2() == discTypeToRemove) || 58 0 : reaction.getProduct1() == discTypeToRemove || 59 0 : (reaction.hasProduct2() && reaction.getProduct2() == discTypeToRemove)) 60 0 : continue; 61 : 62 0 : remainingReactions.push_back(reaction); 63 : } 64 : 65 0 : reactions_ = remainingReactions; 66 0 : createLookupMaps(); 67 0 : } 68 : 69 0 : void ReactionTable::clear() 70 : { 71 0 : reactions_.clear(); 72 0 : createLookupMaps(); 73 0 : } 74 : 75 0 : const std::vector<Reaction>& ReactionTable::getReactions() const 76 : { 77 0 : return reactions_; 78 : } 79 : 80 11 : void ReactionTable::createLookupMaps() 81 : { 82 11 : transformations_.clear(); 83 11 : decompositions_.clear(); 84 11 : combinations_.clear(); 85 11 : exchanges_.clear(); 86 : 87 24 : for (const auto& reaction : reactions_) 88 : { 89 13 : if (isUnary(reaction)) 90 : { 91 5 : auto& map = unaryMap(*this, reaction); 92 5 : map[reaction.getEduct1()].push_back(reaction); 93 : } 94 : else 95 : { 96 8 : auto& map = binaryMap(*this, reaction); 97 8 : map[std::minmax(reaction.getEduct1(), reaction.getEduct2())].push_back(reaction); 98 : } 99 : } 100 11 : } 101 : 102 15 : void ReactionTable::checkIfIsDuplicateReaction(const Reaction& reaction) const 103 : { 104 15 : const std::vector<Reaction>* reactions = nullptr; 105 15 : if (isUnary(reaction)) 106 : { 107 6 : const auto& map = unaryMap(*this, reaction); 108 6 : if (!map.contains(reaction.getEduct1())) 109 4 : return; 110 2 : reactions = &map.at(reaction.getEduct1()); 111 : } 112 : else 113 : { 114 9 : const auto& map = binaryMap(*this, reaction); 115 9 : if (!map.contains(std::minmax(reaction.getEduct1(), reaction.getEduct2()))) 116 7 : return; 117 2 : reactions = &map.at(std::minmax(reaction.getEduct1(), reaction.getEduct2())); 118 : } 119 : 120 4 : for (const auto& existingReaction : *reactions) 121 : { 122 4 : if (existingReaction == reaction) 123 4 : throw ExceptionWithLocation("Duplicate reaction \"" + toString(existingReaction, discTypeRegistry_) + "\""); 124 : } 125 : } 126 : 127 28 : bool ReactionTable::isUnary(const Reaction& r) const 128 : { 129 28 : return r.getType() == Reaction::Type::Transformation || r.getType() == Reaction::Type::Decomposition; 130 : } 131 : 132 : } // namespace cell