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 14 : ReactionTable::ReactionTable(const DiscTypeRegistry& discTypeRegistry) 11 14 : : discTypeRegistry_(discTypeRegistry) 12 : { 13 14 : } 14 : 15 10 : const DiscTypeMap<std::vector<Reaction>>& ReactionTable::getTransformations() const 16 : { 17 10 : return transformations_; 18 : } 19 : 20 10 : const DiscTypeMap<std::vector<Reaction>>& ReactionTable::getDecompositions() const 21 : { 22 10 : return decompositions_; 23 : } 24 : 25 10 : const DiscTypePairMap<std::vector<Reaction>>& ReactionTable::getCombinations() const 26 : { 27 10 : return combinations_; 28 : } 29 : 30 10 : const DiscTypePairMap<std::vector<Reaction>>& ReactionTable::getExchanges() const 31 : { 32 10 : return exchanges_; 33 : } 34 : 35 14 : void ReactionTable::addReaction(const Reaction& reaction) 36 : { 37 14 : reaction.validate(discTypeRegistry_); 38 14 : checkIfIsDuplicateReaction(reaction); 39 : 40 10 : reactions_.push_back(reaction); 41 : 42 10 : createLookupMaps(); 43 10 : } 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 10 : void ReactionTable::createLookupMaps() 81 : { 82 10 : transformations_.clear(); 83 10 : decompositions_.clear(); 84 10 : combinations_.clear(); 85 10 : exchanges_.clear(); 86 : 87 22 : for (const auto& reaction : reactions_) 88 : { 89 12 : if (isUnary(reaction)) 90 : { 91 5 : auto& map = unaryMap(*this, reaction); 92 5 : map[reaction.getEduct1()].push_back(reaction); 93 : } 94 : else 95 : { 96 7 : auto& map = binaryMap(*this, reaction); 97 7 : map[std::make_pair(reaction.getEduct1(), reaction.getEduct2())].push_back(reaction); 98 7 : if (reaction.getEduct1() != reaction.getEduct2()) 99 7 : map[std::make_pair(reaction.getEduct2(), reaction.getEduct1())].push_back(reaction); 100 : } 101 : } 102 10 : } 103 : 104 14 : void ReactionTable::checkIfIsDuplicateReaction(const Reaction& reaction) const 105 : { 106 14 : const std::vector<Reaction>* reactions = nullptr; 107 14 : if (isUnary(reaction)) 108 : { 109 6 : const auto& map = unaryMap(*this, reaction); 110 6 : if (!map.contains(reaction.getEduct1())) 111 4 : return; 112 2 : reactions = &map.at(reaction.getEduct1()); 113 : } 114 : else 115 : { 116 8 : const auto& map = binaryMap(*this, reaction); 117 8 : if (!map.contains(std::make_pair(reaction.getEduct1(), reaction.getEduct2()))) 118 6 : return; 119 2 : reactions = &map.at(std::make_pair(reaction.getEduct1(), reaction.getEduct2())); 120 : } 121 : 122 4 : for (const auto& existingReaction : *reactions) 123 : { 124 4 : if (existingReaction == reaction) 125 4 : throw ExceptionWithLocation("Duplicate reaction \"" + toString(existingReaction, discTypeRegistry_) + "\""); 126 : } 127 : } 128 : 129 26 : bool ReactionTable::isUnary(const Reaction& r) const 130 : { 131 26 : return r.getType() == Reaction::Type::Transformation || r.getType() == Reaction::Type::Decomposition; 132 : } 133 : 134 : } // namespace cell