User Guide
kinetic_block_visitor.hpp
Go to the documentation of this file.
1 /*
2  * Copyright 2023 Blue Brain Project, EPFL.
3  * See the top-level LICENSE file for details.
4  *
5  * SPDX-License-Identifier: Apache-2.0
6  */
7 
8 #pragma once
9 
10 /**
11  * \file
12  * \brief \copybrief nmodl::visitor::KineticBlockVisitor
13  */
14 
15 #include <memory>
16 #include <string>
17 #include <unordered_map>
18 #include <unordered_set>
19 #include <vector>
20 
21 #include "visitors/ast_visitor.hpp"
22 
23 namespace nmodl {
24 namespace visitor {
25 
26 /**
27  * \addtogroup visitor_classes
28  * \{
29  */
30 
31 /**
32  * \class KineticBlockVisitor
33  * \brief %Visitor for kinetic block statements
34  *
35  * Replaces each KINETIC block with a DERIVATIVE block
36  * containing a system of ODEs that is equivalent to
37  * the original set of reaction statements
38  *
39  * Note: assumes that the order of statements between the first and last
40  * reaction statement (those starting with "~") does not matter.
41  *
42  * If there is a CONSERVE statement it is rewritten in an equivalent
43  * form which is then be used by the SympySolver visitor to replace
44  * the ODE for the last state variable on the LHS of the CONSERVE statement
45  *
46  */
48  private:
49  /// update stoichiometric matrices with reaction var term
50  void process_reac_var(const std::string& varname, int count = 1);
51 
52  /// update CONSERVE statement with reaction var term
53  void process_conserve_reac_var(const std::string& varname, int count = 1);
54 
55  void set_compartment_factor(int var_index, const std::string& factor);
56  void compute_compartment_factor(ast::Compartment& node, const ast::Name& name);
58 
59  /// Unroll loops in KINETIC blocks.
60  ///
61  /// The subsequent processing in KineticBlockVisitor fails if there's any
62  /// reaction equation inside a `FROM .. TO ..` block. The solution is to
63  /// unroll any loops first to satisfy the assumption.
65 
66  /// stochiometric matrices nu_L, nu_R
67  /// forwards/backwards fluxes k_f, k_b
68  /// (see kinetic_schemes.ipynb notebook for details)
69  struct RateEqs {
70  std::vector<std::vector<int>> nu_L;
71  std::vector<std::vector<int>> nu_R;
72  std::vector<std::string> k_f;
73  std::vector<std::string> k_b;
74  } rate_eqs;
75 
76  /// multiplicative factors for ODEs from COMPARTMENT statements
77  std::vector<std::string> compartment_factors;
78 
79  /// additive constant terms for ODEs from reaction statements like ~ x << (a)
80  std::vector<std::string> additive_terms;
81 
82  /// multiplicate constant terms for fluxes from non-state vars as reactants
83  /// e.g. reaction statements like ~ x <-> c (a,a)
84  /// where c is not a state var, which is equivalent to the ODE
85  /// x' = a * (c - x)
86  std::vector<std::string> non_state_var_fflux;
87  std::vector<std::string> non_state_var_bflux;
88 
89  /// generated set of fluxes and ODEs
90  std::vector<std::string> fflux;
91  std::vector<std::string> bflux;
92  std::vector<std::string> odes;
93 
94  /// current expressions for the `fflux`, `bflux` variables that can be used in the mod file
95  /// and that are determined by the preceeding kinetic reaction statement, i.e. their
96  /// value changes depending on their location inside the kinetic block
97  std::string modfile_fflux;
98  std::string modfile_bflux;
99 
100  /// number of state variables
102 
103  /// state variables vector
104  std::vector<std::string> state_var;
105 
106  /// unordered_map from state variable to corresponding index
107  std::unordered_map<std::string, int> state_var_index;
108 
109  /// unordered_map from array state variable to its size (for summing over each element of any
110  /// array state vars in a CONSERVE statement)
111  std::unordered_map<std::string, int> array_state_var_size;
112 
113  /// true if we are visiting a reaction statement
114  bool in_reaction_statement = false;
115 
116  /// true if we are visiting the left hand side of reaction statement
118 
119  /// true if we are visiting a CONSERVE statement
120  bool in_conserve_statement = false;
121 
122  /// counts the number of CONSERVE statements in Kinetic blocks
124 
125  /// conserve statement equation as string
127 
128  /// conserve statement: current state variable being processed
130 
131  /// conserve statement: current state var multiplicative factor being processed
133 
134  /// current statement index
135  int i_statement = 0;
136 
137  /// vector of kinetic block nodes
138  std::vector<ast::KineticBlock*> kinetic_blocks;
139 
140  /// statements to remove from block
141  std::unordered_set<ast::Statement*> statements_to_remove;
142 
143  /// current statement block being visited
145 
146  public:
147  KineticBlockVisitor() = default;
148  inline int get_conserve_statement_count() const {
150  }
151 
153  void visit_reaction_operator(ast::ReactionOperator& node) override;
154  void visit_react_var_name(ast::ReactVarName& node) override;
156  void visit_conserve(ast::Conserve& node) override;
157  void visit_compartment(ast::Compartment& node) override;
158  void visit_statement_block(ast::StatementBlock& node) override;
159  void visit_kinetic_block(ast::KineticBlock& node) override;
160  void visit_program(ast::Program& node) override;
161 };
162 
163 /** \} */ // end of visitor_classes
164 
165 } // namespace visitor
166 } // namespace nmodl
nmodl::visitor::KineticBlockVisitor::visit_wrapped_expression
void visit_wrapped_expression(ast::WrappedExpression &node) override
visit node of type ast::WrappedExpression
Definition: kinetic_block_visitor.cpp:374
nmodl::visitor::KineticBlockVisitor::compute_compartment_factor
void compute_compartment_factor(ast::Compartment &node, const ast::Name &name)
Definition: kinetic_block_visitor.cpp:161
nmodl::visitor::KineticBlockVisitor::array_state_var_size
std::unordered_map< std::string, int > array_state_var_size
unordered_map from array state variable to its size (for summing over each element of any array state...
Definition: kinetic_block_visitor.hpp:111
nmodl::visitor::KineticBlockVisitor::RateEqs
stochiometric matrices nu_L, nu_R forwards/backwards fluxes k_f, k_b (see kinetic_schemes....
Definition: kinetic_block_visitor.hpp:69
nmodl::visitor::KineticBlockVisitor::visit_statement_block
void visit_statement_block(ast::StatementBlock &node) override
visit node of type ast::StatementBlock
Definition: kinetic_block_visitor.cpp:394
nmodl::visitor::KineticBlockVisitor::process_conserve_reac_var
void process_conserve_reac_var(const std::string &varname, int count=1)
update CONSERVE statement with reaction var term
Definition: kinetic_block_visitor.cpp:68
nmodl::ast::Conserve
Represent CONSERVE statement in NMODL.
Definition: conserve.hpp:38
nmodl::visitor::KineticBlockVisitor::get_conserve_statement_count
int get_conserve_statement_count() const
Definition: kinetic_block_visitor.hpp:148
nmodl::visitor::KineticBlockVisitor::non_state_var_fflux
std::vector< std::string > non_state_var_fflux
multiplicate constant terms for fluxes from non-state vars as reactants e.g.
Definition: kinetic_block_visitor.hpp:86
nmodl::visitor::KineticBlockVisitor::conserve_statement_count
int conserve_statement_count
counts the number of CONSERVE statements in Kinetic blocks
Definition: kinetic_block_visitor.hpp:123
nmodl
encapsulates code generation backend implementations
Definition: ast_common.hpp:26
nmodl::ast::ReactVarName
TODO.
Definition: react_var_name.hpp:38
nmodl::visitor::KineticBlockVisitor::compartment_factors
std::vector< std::string > compartment_factors
multiplicative factors for ODEs from COMPARTMENT statements
Definition: kinetic_block_visitor.hpp:77
nmodl::visitor::KineticBlockVisitor::visit_program
void visit_program(ast::Program &node) override
visit node of type ast::Program
Definition: kinetic_block_visitor.cpp:682
nmodl::visitor::KineticBlockVisitor::state_var_count
int state_var_count
number of state variables
Definition: kinetic_block_visitor.hpp:101
nmodl::visitor::KineticBlockVisitor::visit_compartment
void visit_compartment(ast::Compartment &node) override
visit node of type ast::Compartment
Definition: kinetic_block_visitor.cpp:202
nmodl::visitor::KineticBlockVisitor::fflux
std::vector< std::string > fflux
generated set of fluxes and ODEs
Definition: kinetic_block_visitor.hpp:90
nmodl::visitor::KineticBlockVisitor::conserve_equation_statevar
std::string conserve_equation_statevar
conserve statement: current state variable being processed
Definition: kinetic_block_visitor.hpp:129
nmodl::visitor::KineticBlockVisitor::visit_reaction_operator
void visit_reaction_operator(ast::ReactionOperator &node) override
visit node of type ast::ReactionOperator
Definition: kinetic_block_visitor.cpp:219
nmodl::visitor::KineticBlockVisitor::rate_eqs
struct nmodl::visitor::KineticBlockVisitor::RateEqs rate_eqs
nmodl::visitor::KineticBlockVisitor
Visitor for kinetic block statements
Definition: kinetic_block_visitor.hpp:47
nmodl::ast::ReactionOperator
TODO.
Definition: reaction_operator.hpp:38
nmodl::visitor::KineticBlockVisitor::visit_conserve
void visit_conserve(ast::Conserve &node) override
visit node of type ast::Conserve
Definition: kinetic_block_visitor.cpp:107
nmodl::visitor::KineticBlockVisitor::KineticBlockVisitor
KineticBlockVisitor()=default
nmodl::visitor::KineticBlockVisitor::in_reaction_statement_lhs
bool in_reaction_statement_lhs
true if we are visiting the left hand side of reaction statement
Definition: kinetic_block_visitor.hpp:117
nmodl::visitor::KineticBlockVisitor::i_statement
int i_statement
current statement index
Definition: kinetic_block_visitor.hpp:135
nmodl::visitor::KineticBlockVisitor::in_conserve_statement
bool in_conserve_statement
true if we are visiting a CONSERVE statement
Definition: kinetic_block_visitor.hpp:120
nmodl::visitor::KineticBlockVisitor::set_compartment_factor
void set_compartment_factor(int var_index, const std::string &factor)
Definition: kinetic_block_visitor.cpp:149
nmodl::visitor::KineticBlockVisitor::statements_to_remove
std::unordered_set< ast::Statement * > statements_to_remove
statements to remove from block
Definition: kinetic_block_visitor.hpp:141
nmodl::visitor::AstVisitor
Concrete visitor for all AST classes.
Definition: ast_visitor.hpp:37
nmodl::visitor::KineticBlockVisitor::modfile_fflux
std::string modfile_fflux
current expressions for the fflux, bflux variables that can be used in the mod file and that are dete...
Definition: kinetic_block_visitor.hpp:97
nmodl::visitor::KineticBlockVisitor::visit_reaction_statement
void visit_reaction_statement(ast::ReactionStatement &node) override
visit node of type ast::ReactionStatement
Definition: kinetic_block_visitor.cpp:251
nmodl::visitor::KineticBlockVisitor::state_var
std::vector< std::string > state_var
state variables vector
Definition: kinetic_block_visitor.hpp:104
nmodl::visitor::KineticBlockVisitor::conserve_equation_str
std::string conserve_equation_str
conserve statement equation as string
Definition: kinetic_block_visitor.hpp:126
nmodl::visitor::KineticBlockVisitor::compute_indexed_compartment_factor
void compute_indexed_compartment_factor(ast::Compartment &node, const ast::Name &name)
Definition: kinetic_block_visitor.cpp:178
nmodl::ast::KineticBlock
TODO.
Definition: kinetic_block.hpp:39
nmodl::visitor::KineticBlockVisitor::bflux
std::vector< std::string > bflux
Definition: kinetic_block_visitor.hpp:91
nmodl::ast::Compartment
Represent COMPARTMENT statement in NMODL.
Definition: compartment.hpp:39
nmodl::visitor::KineticBlockVisitor::visit_react_var_name
void visit_react_var_name(ast::ReactVarName &node) override
visit node of type ast::ReactVarName
Definition: kinetic_block_visitor.cpp:229
nmodl::ast::StatementBlock
Represents block encapsulating list of statements.
Definition: statement_block.hpp:53
nmodl::visitor::KineticBlockVisitor::modfile_bflux
std::string modfile_bflux
Definition: kinetic_block_visitor.hpp:98
nmodl::visitor::KineticBlockVisitor::RateEqs::k_b
std::vector< std::string > k_b
Definition: kinetic_block_visitor.hpp:73
nmodl::ast::ReactionStatement
TODO.
Definition: reaction_statement.hpp:39
nmodl::visitor::KineticBlockVisitor::additive_terms
std::vector< std::string > additive_terms
additive constant terms for ODEs from reaction statements like ~ x << (a)
Definition: kinetic_block_visitor.hpp:80
nmodl::visitor::KineticBlockVisitor::visit_kinetic_block
void visit_kinetic_block(ast::KineticBlock &node) override
visit node of type ast::KineticBlock
Definition: kinetic_block_visitor.cpp:403
nmodl::visitor::KineticBlockVisitor::state_var_index
std::unordered_map< std::string, int > state_var_index
unordered_map from state variable to corresponding index
Definition: kinetic_block_visitor.hpp:107
nmodl::visitor::KineticBlockVisitor::kinetic_blocks
std::vector< ast::KineticBlock * > kinetic_blocks
vector of kinetic block nodes
Definition: kinetic_block_visitor.hpp:138
nmodl::visitor::KineticBlockVisitor::current_statement_block
ast::StatementBlock * current_statement_block
current statement block being visited
Definition: kinetic_block_visitor.hpp:144
nmodl::visitor::KineticBlockVisitor::unroll_kinetic_blocks
void unroll_kinetic_blocks(ast::Program &node)
Unroll loops in KINETIC blocks.
Definition: kinetic_block_visitor.cpp:647
nmodl::visitor::KineticBlockVisitor::RateEqs::k_f
std::vector< std::string > k_f
Definition: kinetic_block_visitor.hpp:72
nmodl::visitor::KineticBlockVisitor::odes
std::vector< std::string > odes
Definition: kinetic_block_visitor.hpp:92
nmodl::ast::Name
Represents a name.
Definition: name.hpp:44
nmodl::visitor::KineticBlockVisitor::process_reac_var
void process_reac_var(const std::string &varname, int count=1)
update stoichiometric matrices with reaction var term
Definition: kinetic_block_visitor.cpp:27
nmodl::ast::Program
Represents top level AST node for whole NMODL input.
Definition: program.hpp:39
nmodl::visitor::KineticBlockVisitor::in_reaction_statement
bool in_reaction_statement
true if we are visiting a reaction statement
Definition: kinetic_block_visitor.hpp:114
nmodl::visitor::KineticBlockVisitor::RateEqs::nu_R
std::vector< std::vector< int > > nu_R
Definition: kinetic_block_visitor.hpp:71
nmodl::visitor::KineticBlockVisitor::RateEqs::nu_L
std::vector< std::vector< int > > nu_L
Definition: kinetic_block_visitor.hpp:70
nmodl::ast::WrappedExpression
Wrap any other expression type.
Definition: wrapped_expression.hpp:38
nmodl::visitor::KineticBlockVisitor::non_state_var_bflux
std::vector< std::string > non_state_var_bflux
Definition: kinetic_block_visitor.hpp:87
nmodl::visitor::KineticBlockVisitor::conserve_equation_factor
std::string conserve_equation_factor
conserve statement: current state var multiplicative factor being processed
Definition: kinetic_block_visitor.hpp:132
ast_visitor.hpp
Concrete visitor for all AST classes.