LCOV - code coverage report
Current view: top level - cell - ReactionTable.cpp (source / functions) Hit Total Coverage
Test: coverage.info Lines: 47 69 68.1 %
Date: 2025-12-06 00:15:40 Functions: 9 13 69.2 %

          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

Generated by: LCOV version 1.14