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 17 : ReactionTable::ReactionTable(const DiscTypeRegistry& discTypeRegistry) 11 17 : : discTypeRegistry_(discTypeRegistry) 12 : { 13 17 : } 14 : 15 12 : const DiscTypeMap<std::vector<Reaction>>& ReactionTable::getTransformations() const 16 : { 17 12 : return transformations_; 18 : } 19 : 20 12 : const DiscTypeMap<std::vector<Reaction>>& ReactionTable::getDecompositions() const 21 : { 22 12 : return decompositions_; 23 : } 24 : 25 12 : const DiscTypePairMap<std::vector<Reaction>>& ReactionTable::getCombinations() const 26 : { 27 12 : return combinations_; 28 : } 29 : 30 12 : const DiscTypePairMap<std::vector<Reaction>>& ReactionTable::getExchanges() const 31 : { 32 12 : return exchanges_; 33 : } 34 : 35 16 : void ReactionTable::addReaction(const Reaction& reaction) 36 : { 37 16 : reaction.validate(discTypeRegistry_); 38 16 : checkIfIsDuplicateReaction(reaction); 39 : 40 12 : reactions_.push_back(reaction); 41 : 42 12 : createLookupMaps(); 43 12 : } 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 12 : void ReactionTable::createLookupMaps() 81 : { 82 12 : transformations_.clear(); 83 12 : decompositions_.clear(); 84 12 : combinations_.clear(); 85 12 : exchanges_.clear(); 86 : 87 26 : for (const auto& reaction : reactions_) 88 : { 89 14 : if (isUnary(reaction)) 90 : { 91 6 : auto& map = unaryMap(*this, reaction); 92 6 : 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 12 : } 101 : 102 16 : void ReactionTable::checkIfIsDuplicateReaction(const Reaction& reaction) const 103 : { 104 16 : const std::vector<Reaction>* reactions = nullptr; 105 16 : if (isUnary(reaction)) 106 : { 107 7 : const auto& map = unaryMap(*this, reaction); 108 7 : if (!map.contains(reaction.getEduct1())) 109 5 : 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 30 : bool ReactionTable::isUnary(const Reaction& r) const 128 : { 129 30 : return r.getType() == Reaction::Type::Transformation || r.getType() == Reaction::Type::Decomposition; 130 : } 131 : 132 : } // namespace cell