# Building Catalyst.jl reaction network from a .csv file - error in construction?

**URL:** https://discourse.julialang.org/t/building-catalyst-jl-reaction-network-from-a-csv-file-error-in-construction/130043
**Category:** Modelling & Simulations
**Tags:** question, package, catalyst, network
**Created:** [June 19, 2025, 10:13pm UTC](https://discourse.julialang.org/t/building-catalyst-jl-reaction-network-from-a-csv-file-error-in-construction/130043 "2025-06-19T22:13:22Z")
**Posts on this page:** 7
**Page:** 1

<div class="post-metadata">

### Author: ![spackman](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/spackman/32/215941_2.png) [@spackman](https://discourse.julialang.org/u/spackman)
#### Post date: [June 19, 2025, 10:13pm UTC](https://discourse.julialang.org/t/building-catalyst-jl-reaction-network-from-a-csv-file-error-in-construction/130043/1 "2025-06-19T22:13:22Z")

</div>

Hey Julia crew!

I am trying to import a reaction network from a .csv file to use with **Catalyst.jl** via **Reaction NetworkImporters.jl.**

I have been able to successfully construct a `ReactionSystem` object which can print itself using latexify, but additional commands fail with **MethodErrors**.

Here is a minimal example:

```julia
using Pkg
Pkg.activate(".")
using Catalyst, OrdinaryDiffEq, Plots, Latexify, CSV, DataFrames, ReactionNetworkImporters, GraphMakie, CairoMakie, NetworkLayout

function read_CRN(csvfile::String)
  """
  read_CRN(csvfile::String)

  Reads a CSV file containing the net reaction stoichiometry (products - reactants) and returns 
  two DataFrames containing substrate and product stoichiometry matrices, as well as a 
  numeric vector of rate constants from the first column.

  ### Arguments
  - `csvfile::String`: The path to the input CSV file. The file should have a non-numeric 
    first column (rate constants) and numeric data in subsequent columns, where each row represents a reaction.

  ### Returns
  - `product_matrix::Matrix{Int64}`: A transposed matrix with the stoichiometric coefficients of the products in each reaction.
  - `substrate_matrix::Matrix{Float64}`: A transposed matrix with the stoichiometric coefficients of the substrates in each reaction.
  - `rate_constants::Vector{Float64}`: A numeric vector containing the rate constants from the first column of the CSV.
  - `species::Vector{String}`: A vector of species names corresponding to the columns in the stoichiometry matrix.
  - `m_reactions::Int`: The number of reactions.
  - `n_species::Int`: The number of species.

  ### Example
  product_matrix, substrate_matrix, rate_constants, species, m_reactions, n_species = read_CRN("path/to/file.csv")

  """
  
  # Read the CSV file into a DataFrame
  data = CSV.read(csvfile, DataFrame)
  species = names(data)[2:end]
  rate_constants = Vector{Float64}(data[!, 1])

  data_matrix = Matrix{Float64}(data[:, 2:end])

  product_matrix = max.(data_matrix, 0)
  substrate_matrix = -min.(data_matrix, 0)

  # Transpose the product and substrate matrices for compatibility with catalyst.jl
  product_matrix = Matrix(transpose(product_matrix))
  substrate_matrix = Matrix(transpose(substrate_matrix))

  # Get the number of reactions (rows) and species (columns)
  m_reactions = size(data_matrix, 1) # Number of reactions (rows)
  n_species = size(data_matrix, 2) # Number of species (columns)

  # Convert the product matrix to integers
  product_matrix = convert(Matrix{Int}, product_matrix)

  # Return the transposed matrices, rate constants, species names, number of reactions, and number of species
  return product_matrix, substrate_matrix, rate_constants, species, m_reactions, n_species
end

(prod, sub, k, species, m_reactions, n_species) = read_CRN("test_CRN.csv")

@species S(t)[1:n_species]  
@parameters k[1:m_reactions]
@variables t

# Collect to a Vector{Num} type
pars = collect(k)
species = collect(S)

# Create the MatrixNetwork with correct types
mn = MatrixNetwork(pars, sub, prod; species=species, params=pars)

prn = loadrxnetwork(mn)
rn = prn.rn
latexify(rn)

```

When run on a `.csv` file with this contents:

| rate | S1 | S2 | S3 |
| --- | --- | --- | --- |
| 1 | -2 | 1 | 0 |
| 2 | 2 | -1 | 0 |
| 3 | -1 | -1 | 1 |
| 4 | 1 | 1 | -1 |
| 5 | 3 | 0 | -3 |

The expected latex is printed (edited here to render properly):

\begin{align\*} 2.0 \mathrm{\mathtt{S\_1}} &\leftrightarrow \mathrm{\mathtt{S\_2}} \quad (k\_1, k\_2) \\ \mathrm{\mathtt{S\_1}} + \mathrm{\mathtt{S\_2}} &\leftrightarrow \mathrm{\mathtt{S\_3}} \quad (k\_3, k\_4) \\ 3.0 \mathrm{\mathtt{S\_3}} &\rightarrow 3.0 \mathrm{\mathtt{S\_1}} \quad (k\_5) \end{align\*}

However, the network has not been properly constructed. Using

```julia
plot_network(rn)

```

returns this system:

 ![test_CRN](https://global.discourse-cdn.com/julialang/original/3X/8/1/8157301cc8915ccd28c37f1f36e950dba810ce1d.png)

Further, any additional calls to other functions appear to fail. Here is an example:

```julia
deficiency(rn)

```

```error
MethodError: no method matching exactdiv(::Float64, ::Float64)
The function `exactdiv` exists, but no method is defined for this combination of argument types.

Closest candidates are:
  exactdiv(!Matched::Integer, ::Any)
   @ ModelingToolkit C:\.julia\packages\ModelingToolkit\Z9mEq\src\systems\alias_elimination.jl:376

```

All similar functions throw the same error (i.e. \<method\> exists but no method for this combination of argument types), which suggests that the `ReactionSystem` object was not actually constructed properly.

* * *

**Does anyone have any advice for this issue?**  
I am using Catalyst 15.0.8. and ReactionNetworkImporters 0.16.1

---

<div class="post-metadata">

### Author: ![ChrisRackauckas](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/chrisrackauckas/32/77_2.png) [@ChrisRackauckas](https://discourse.julialang.org/u/ChrisRackauckas)
#### Post date: [June 19, 2025, 10:55pm UTC](https://discourse.julialang.org/t/building-catalyst-jl-reaction-network-from-a-csv-file-error-in-construction/130043/2 "2025-06-19T22:55:22Z")

</div>

Is your stoichiometry represented using floats instead of integers? You may need to convert that.

---

<div class="post-metadata">

### Author: ![spackman](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/spackman/32/215941_2.png) [@spackman](https://discourse.julialang.org/u/spackman)
#### Post date: [June 19, 2025, 11:17pm UTC](https://discourse.julialang.org/t/building-catalyst-jl-reaction-network-from-a-csv-file-error-in-construction/130043/3 "2025-06-19T23:17:57Z")

</div>

In a previous version I had issues with the dataframe automatically reading in as a `Matrix{Float}` instead of a `Matrix{Int}`, which causes `MatrixNetwork()` to fail. Either way I don’t think this is the root cause of the error…

---

<div class="post-metadata">

### Author: ![ChrisRackauckas](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/chrisrackauckas/32/77_2.png) [@ChrisRackauckas](https://discourse.julialang.org/u/ChrisRackauckas)
#### Post date: [June 19, 2025, 11:35pm UTC](https://discourse.julialang.org/t/building-catalyst-jl-reaction-network-from-a-csv-file-error-in-construction/130043/4 "2025-06-19T23:35:19Z")

</div>

It is missing a dispatch that is expecting an integer. So it does need to convert at some point.

---

<div class="post-metadata">

### Author: ![isaacsas](https://avatars.discourse-cdn.com/v4/letter/i/f6c823/32.png) [@isaacsas](https://discourse.julialang.org/u/isaacsas)
#### Post date: [June 20, 2025, 1:44am UTC](https://discourse.julialang.org/t/building-catalyst-jl-reaction-network-from-a-csv-file-error-in-construction/130043/5 "2025-06-20T01:44:43Z")

</div>

Network analysis functions generally require integer stoichiometry, so they will fail if you aren’t creating a network with integer stochioimetric coefficients as Chris said.

The graph looks ok to me modulo that the species nodes are incorrectly labeled. That seems like a Catalyst bug with labeling graphs when using array species. I’ve opened an issue so we can hopefully get that fixed.

---

<div class="post-metadata">

### Author: ![spackman](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/spackman/32/215941_2.png) [@spackman](https://discourse.julialang.org/u/spackman)
#### Post date: [June 20, 2025, 5:55pm UTC](https://discourse.julialang.org/t/building-catalyst-jl-reaction-network-from-a-csv-file-error-in-construction/130043/6 "2025-06-20T17:55:06Z")

</div>

Awesome! Thanks!

In the future is it better to raise an issue directly or start with a discussion here? I figured that this did not relate to underlying functionality/structure of the code and was instead a user error which is why I posted here instead.

---

<div class="post-metadata">

### Author: ![isaacsas](https://avatars.discourse-cdn.com/v4/letter/i/f6c823/32.png) [@isaacsas](https://discourse.julialang.org/u/isaacsas)
#### Post date: [June 20, 2025, 8:51pm UTC](https://discourse.julialang.org/t/building-catalyst-jl-reaction-network-from-a-csv-file-error-in-construction/130043/7 "2025-06-20T20:51:51Z")

</div>

Issues are better for feature requests and/or bugs. Discourse is good for general usage questions.
