4
4
5
5
# ######## Accessors: #########
6
6
7
- function filter_nonrxsys (network)
8
- systems = get_systems (network)
9
- rxsystems = ReactionSystem[]
10
- for sys in systems
11
- (sys isa ReactionSystem) && push! (rxsystems, sys)
12
- end
13
- rxsystems
14
- end
15
-
16
- function species (network:: ReactionSystem , sts)
17
- [MT. renamespace (network, st) for st in sts]
18
- end
19
-
20
- """
21
- species(network)
22
-
23
- Given a [`ReactionSystem`](@ref), return a vector of all species defined in the system and
24
- any subsystems that are of type `ReactionSystem`. To get the species and non-species
25
- variables in the system and all subsystems, including non-`ReactionSystem` subsystems, uses
26
- `unknowns(network)`.
27
-
28
- Notes:
29
- - If `ModelingToolkit.get_systems(network)` is non-empty will allocate.
30
- """
31
- function species (network)
32
- sts = get_species (network)
33
- systems = filter_nonrxsys (network)
34
- isempty (systems) && return sts
35
- unique ([sts; reduce (vcat, map (sys -> species (sys, species (sys)), systems))])
36
- end
37
-
38
- """
39
- nonspecies(network)
40
-
41
- Return the non-species variables within the network, i.e. those unknowns for which `isspecies
42
- == false`.
43
-
44
- Notes:
45
- - Allocates a new array to store the non-species variables.
46
- """
47
- function nonspecies (network)
48
- unknowns (network)[(numspecies (network) + 1 ): end ]
49
- end
50
-
51
- """
52
- reactionparams(network)
53
-
54
- Given a [`ReactionSystem`](@ref), return a vector of all parameters defined
55
- within the system and any subsystems that are of type `ReactionSystem`. To get
56
- the parameters in the system and all subsystems, including non-`ReactionSystem`
57
- subsystems, use `parameters(network)`.
58
-
59
- Notes:
60
- - Allocates and has to calculate these dynamically by comparison for each reaction.
61
- """
62
- function reactionparams (network)
63
- ps = get_ps (network)
64
- systems = filter_nonrxsys (network)
65
- isempty (systems) && return ps
66
- unique ([ps; reduce (vcat, map (sys -> species (sys, reactionparams (sys)), systems))])
67
- end
68
-
69
- """
70
- numparams(network)
71
-
72
- Return the total number of parameters within the given system and all subsystems.
73
- """
74
- function numparams (network)
75
- nps = length (get_ps (network))
76
- for sys in get_systems (network)
77
- nps += numparams (sys)
78
- end
79
- nps
80
- end
81
-
82
- function namespace_reactions (network:: ReactionSystem )
83
- rxs = reactions (network)
84
- isempty (rxs) && return Reaction[]
85
- map (rx -> namespace_equation (rx, network), rxs)
86
- end
87
-
88
- """
89
- reactions(network)
90
-
91
- Given a [`ReactionSystem`](@ref), return a vector of all `Reactions` in the system.
92
-
93
- Notes:
94
- - If `ModelingToolkit.get_systems(network)` is not empty, will allocate.
95
- """
96
- function reactions (network)
97
- rxs = get_rxs (network)
98
- systems = filter_nonrxsys (network)
99
- isempty (systems) && (return rxs)
100
- [rxs; reduce (vcat, namespace_reactions .(systems); init = Reaction[])]
101
- end
102
-
103
- """
104
- speciesmap(network)
105
-
106
- Given a [`ReactionSystem`](@ref), return a Dictionary mapping species that
107
- participate in `Reaction`s to their index within [`species(network)`](@ref).
108
- """
109
- function speciesmap (network)
110
- nps = get_networkproperties (network)
111
- if isempty (nps. speciesmap)
112
- nps. speciesmap = Dict (S => i for (i, S) in enumerate (species (network)))
113
- end
114
- nps. speciesmap
115
- end
116
-
117
- """
118
- paramsmap(network)
119
-
120
- Given a [`ReactionSystem`](@ref), return a Dictionary mapping from all
121
- parameters that appear within the system to their index within
122
- `parameters(network)`.
123
- """
124
- function paramsmap (network)
125
- Dict (p => i for (i, p) in enumerate (parameters (network)))
126
- end
127
-
128
- """
129
- reactionparamsmap(network)
130
-
131
- Given a [`ReactionSystem`](@ref), return a Dictionary mapping from parameters that
132
- appear within `Reaction`s to their index within [`reactionparams(network)`](@ref).
133
- """
134
- function reactionparamsmap (network)
135
- Dict (p => i for (i, p) in enumerate (reactionparams (network)))
136
- end
137
-
138
- """
139
- numspecies(network)
140
-
141
- Return the total number of species within the given [`ReactionSystem`](@ref) and
142
- subsystems that are `ReactionSystem`s.
143
- """
144
- function numspecies (network)
145
- numspcs = length (get_species (network))
146
- for sys in get_systems (network)
147
- (sys isa ReactionSystem) && (numspcs += numspecies (sys))
148
- end
149
- numspcs
150
- end
151
-
152
- """
153
- numreactions(network)
154
-
155
- Return the total number of reactions within the given [`ReactionSystem`](@ref)
156
- and subsystems that are `ReactionSystem`s.
157
- """
158
- function numreactions (network)
159
- nr = length (get_rxs (network))
160
- for sys in get_systems (network)
161
- (sys isa ReactionSystem) && (nr += numreactions (sys))
162
- end
163
- nr
164
- end
165
-
166
- """
167
- numreactionparams(network)
168
-
169
- Return the total number of parameters within the given [`ReactionSystem`](@ref)
170
- and subsystems that are `ReactionSystem`s.
171
-
172
- Notes
173
- - If there are no subsystems this will be fast.
174
- - As this calls [`reactionparams`](@ref), it can be slow and will allocate if
175
- there are any subsystems.
176
- """
177
- function numreactionparams (network)
178
- length (reactionparams (network))
179
- end
180
-
181
7
"""
182
8
dependents(rx, network)
183
9
@@ -1292,197 +1118,3 @@ function conservationlaw_errorcheck(rs, pre_varmap)
1292
1118
isempty (conservedequations (Catalyst. flatten (rs))) ||
1293
1119
error (" The system has conservation laws but initial conditions were not provided for some species." )
1294
1120
end
1295
-
1296
- # ####################### reaction network operators #######################
1297
-
1298
- """
1299
- ==(rx1::Reaction, rx2::Reaction)
1300
-
1301
- Tests whether two [`Reaction`](@ref)s are identical.
1302
-
1303
- Notes:
1304
- - Ignores the order in which stoichiometry components are listed.
1305
- - *Does not* currently simplify rates, so a rate of `A^2+2*A+1` would be
1306
- considered different than `(A+1)^2`.
1307
- """
1308
- function (== )(rx1:: Reaction , rx2:: Reaction )
1309
- isequal (rx1. rate, rx2. rate) || return false
1310
- issetequal (zip (rx1. substrates, rx1. substoich), zip (rx2. substrates, rx2. substoich)) ||
1311
- return false
1312
- issetequal (zip (rx1. products, rx1. prodstoich), zip (rx2. products, rx2. prodstoich)) ||
1313
- return false
1314
- issetequal (rx1. netstoich, rx2. netstoich) || return false
1315
- rx1. only_use_rate == rx2. only_use_rate
1316
- end
1317
-
1318
- function hash (rx:: Reaction , h:: UInt )
1319
- h = Base. hash (rx. rate, h)
1320
- for s in Iterators. flatten ((rx. substrates, rx. products))
1321
- h ⊻= hash (s)
1322
- end
1323
- for s in Iterators. flatten ((rx. substoich, rx. prodstoich))
1324
- h ⊻= hash (s)
1325
- end
1326
- for s in rx. netstoich
1327
- h ⊻= hash (s)
1328
- end
1329
- Base. hash (rx. only_use_rate, h)
1330
- end
1331
-
1332
- """
1333
- isequivalent(rn1::ReactionSystem, rn2::ReactionSystem; ignorenames = true)
1334
-
1335
- Tests whether the underlying species, parameters and reactions are the same in
1336
- the two [`ReactionSystem`](@ref)s. Ignores the names of the systems in testing
1337
- equality.
1338
-
1339
- Notes:
1340
- - *Does not* currently simplify rates, so a rate of `A^2+2*A+1` would be
1341
- considered different than `(A+1)^2`.
1342
- - Does not include `defaults` in determining equality.
1343
- """
1344
- function isequivalent (rn1:: ReactionSystem , rn2:: ReactionSystem ; ignorenames = true )
1345
- if ! ignorenames
1346
- (nameof (rn1) == nameof (rn2)) || return false
1347
- end
1348
-
1349
- (get_combinatoric_ratelaws (rn1) == get_combinatoric_ratelaws (rn2)) || return false
1350
- isequal (get_iv (rn1), get_iv (rn2)) || return false
1351
- issetequal (get_sivs (rn1), get_sivs (rn2)) || return false
1352
- issetequal (get_unknowns (rn1), get_unknowns (rn2)) || return false
1353
- issetequal (get_ps (rn1), get_ps (rn2)) || return false
1354
- issetequal (MT. get_observed (rn1), MT. get_observed (rn2)) || return false
1355
- issetequal (get_eqs (rn1), get_eqs (rn2)) || return false
1356
-
1357
- # subsystems
1358
- (length (get_systems (rn1)) == length (get_systems (rn2))) || return false
1359
- issetequal (get_systems (rn1), get_systems (rn2)) || return false
1360
-
1361
- true
1362
- end
1363
-
1364
- """
1365
- ==(rn1::ReactionSystem, rn2::ReactionSystem)
1366
-
1367
- Tests whether the underlying species, parameters and reactions are the same in
1368
- the two [`ReactionSystem`](@ref)s. Requires the systems to have the same names
1369
- too.
1370
-
1371
- Notes:
1372
- - *Does not* currently simplify rates, so a rate of `A^2+2*A+1` would be
1373
- considered different than `(A+1)^2`.
1374
- - Does not include `defaults` in determining equality.
1375
- """
1376
- function (== )(rn1:: ReactionSystem , rn2:: ReactionSystem )
1377
- isequivalent (rn1, rn2; ignorenames = false )
1378
- end
1379
-
1380
- # ####################### functions to extend a network ####################
1381
-
1382
- """
1383
- make_empty_network(; iv=DEFAULT_IV, name=gensym(:ReactionSystem))
1384
-
1385
- Construct an empty [`ReactionSystem`](@ref). `iv` is the independent variable,
1386
- usually time, and `name` is the name to give the `ReactionSystem`.
1387
- """
1388
- function make_empty_network (; iv = DEFAULT_IV, name = gensym (:ReactionSystem ))
1389
- ReactionSystem (Reaction[], iv, [], []; name = name)
1390
- end
1391
-
1392
-
1393
- # ############################## units #####################################
1394
-
1395
- """
1396
- validate(rx::Reaction; info::String = "")
1397
-
1398
- Check that all substrates and products within the given [`Reaction`](@ref) have
1399
- the same units, and that the units of the reaction's rate expression are
1400
- internally consistent (i.e. if the rate involves sums, each term in the sum has
1401
- the same units).
1402
-
1403
- """
1404
- function validate (rx:: Reaction ; info:: String = " " )
1405
- validated = MT. _validate ([rx. rate], [string (rx, " : rate" )], info = info)
1406
-
1407
- subunits = isempty (rx. substrates) ? nothing : get_unit (rx. substrates[1 ])
1408
- for i in 2 : length (rx. substrates)
1409
- if get_unit (rx. substrates[i]) != subunits
1410
- validated = false
1411
- @warn (string (" In " , rx, " the substrates have differing units." ))
1412
- end
1413
- end
1414
-
1415
- produnits = isempty (rx. products) ? nothing : get_unit (rx. products[1 ])
1416
- for i in 2 : length (rx. products)
1417
- if get_unit (rx. products[i]) != produnits
1418
- validated = false
1419
- @warn (string (" In " , rx, " the products have differing units." ))
1420
- end
1421
- end
1422
-
1423
- if (subunits != = nothing ) && (produnits != = nothing ) && (subunits != produnits)
1424
- validated = false
1425
- @warn (string (" in " , rx,
1426
- " the substrate units are not consistent with the product units." ))
1427
- end
1428
-
1429
- validated
1430
- end
1431
-
1432
- """
1433
- validate(rs::ReactionSystem, info::String="")
1434
-
1435
- Check that all species in the [`ReactionSystem`](@ref) have the same units, and
1436
- that the rate laws of all reactions reduce to units of (species units) / (time
1437
- units).
1438
-
1439
- Notes:
1440
- - Does not check subsystems, constraint equations, or non-species variables.
1441
- """
1442
- function validate (rs:: ReactionSystem , info:: String = " " )
1443
- specs = get_species (rs)
1444
-
1445
- # if there are no species we don't check units on the system
1446
- isempty (specs) && return true
1447
-
1448
- specunits = get_unit (specs[1 ])
1449
- validated = true
1450
- for spec in specs
1451
- if get_unit (spec) != specunits
1452
- validated = false
1453
- @warn (string (" Species are expected to have units of " , specunits,
1454
- " however, species " , spec, " has units " , get_unit (spec), " ." ))
1455
- end
1456
- end
1457
- timeunits = get_unit (get_iv (rs))
1458
-
1459
- # no units for species, time or parameters then assume validated
1460
- if (specunits in (MT. unitless, nothing )) && (timeunits in (MT. unitless, nothing ))
1461
- all (u == 1.0 for u in ModelingToolkit. get_unit (get_ps (rs))) && return true
1462
- end
1463
-
1464
- rateunits = specunits / timeunits
1465
- for rx in get_rxs (rs)
1466
- rxunits = get_unit (rx. rate)
1467
- for (i, sub) in enumerate (rx. substrates)
1468
- rxunits *= get_unit (sub)^ rx. substoich[i]
1469
- end
1470
-
1471
- # Checks that the reaction's combined units is correct, if not, throws a warning.
1472
- # Needs additional checks because for cases: (1.0^n) and (1.0^n1)*(1.0^n2).
1473
- # These are not considered (be default) considered equal to `1.0` for unitless reactions.
1474
- isequal (rxunits, rateunits) && continue
1475
- if istree (rxunits)
1476
- unitless_exp (rxunits) && continue
1477
- (operation (rxunits) == * ) && all (unitless_exp (arg) for arg in arguments (rxunits)) && continue
1478
- end
1479
- validated = false
1480
- @warn (string (" Reaction rate laws are expected to have units of " , rateunits, " however, " ,
1481
- rx, " has units of " , rxunits, " ." ))
1482
- end
1483
-
1484
- validated
1485
- end
1486
-
1487
- # Checks if a unit consist of exponents with base 1 (and is this unitless).
1488
- unitless_exp (u) = istree (u) && (operation (u) == ^ ) && (arguments (u)[1 ] == 1 )
0 commit comments