Skip to content

Commit b043fd5

Browse files
committed
save progress
1 parent 7159cd6 commit b043fd5

File tree

4 files changed

+389
-392
lines changed

4 files changed

+389
-392
lines changed

src/network_analysis.jl

Lines changed: 0 additions & 368 deletions
Original file line numberDiff line numberDiff line change
@@ -4,180 +4,6 @@
44

55
######### Accessors: #########
66

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-
1817
"""
1828
dependents(rx, network)
1839
@@ -1292,197 +1118,3 @@ function conservationlaw_errorcheck(rs, pre_varmap)
12921118
isempty(conservedequations(Catalyst.flatten(rs))) ||
12931119
error("The system has conservation laws but initial conditions were not provided for some species.")
12941120
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

Comments
 (0)