Summary
When calling bionetgen.run() multiple times in a loop and storing the results in a list, all entries in the list end up pointing to the same data from the final simulation. The data appears to be overwritten on each iteration, and even using .copy() on the returned numpy recarray does not create independent copies.
Expected Behavior
Each call to bionetgen.run() should return independent data that is not affected by subsequent calls.
Actual Behavior
All stored results reference the same underlying data, which gets overwritten with each new call to bionetgen.run().
Minimal Reproducible Example
import bionetgen
import numpy as np
# Simple BNGL model template
bngl_template = """
begin model
begin parameters
A {AREA}
RasTotal 1000 * A
end parameters
begin molecule types
Ras(a~p~0)
end molecule types
begin species
Ras(a~0) RasTotal
end species
begin observables
Molecules Ras_act Ras(a~p)
end observables
begin reaction rules
RasActivation: Ras(a~0) -> Ras(a~p) 0.01
RasDeactivation: Ras(a~p) -> Ras(a~0) 0.02
end reaction rules
end model
simulate({method=>"ssa", t_end=>1000, n_steps=>1000})
"""
# Run simulations for different areas
Areas = [1, 4, 9]
results = []
for A in Areas:
bngl_content = bngl_template.replace("{AREA}", str(A))
with open(f"test_A_{A}.bngl", "w") as f:
f.write(bngl_content)
result = bionetgen.run(f"test_A_{A}.bngl")
results.append(result[0]) # Store the data array
print(f"Area={A}, Final Ras_act: {result[0]['Ras_act'][-1]}")
# Check stored results - they should be different but they're all the same
print("\n--- Checking stored results ---")
for i, data in enumerate(results):
print(f"Results[{i}] (Area={Areas[i]}): Final Ras_act = {data['Ras_act'][-1]}")
Output:
Area=1, Final Ras_act: 123.0
Area=4, Final Ras_act: 456.0
Area=9, Final Ras_act: 789.0
--- Checking stored results ---
Results[0] (Area=1): Final Ras_act = 789.0 # Should be 123.0!
Results[1] (Area=4): Final Ras_act = 789.0 # Should be 456.0!
Results[2] (Area=9): Final Ras_act = 789.0 # Correct
All results show the same value (from the last simulation), even though they were different when first returned.
Attempted Fix That Didn't Work
# Attempting to copy the data
result = bionetgen.run(f"test_A_{A}.bngl")
data_copy = result[0].copy() # numpy recarray .copy() method
results.append(data_copy)
This also fails - all copies still reference the same underlying data.
Workaround
The only reliable workaround is to reload the data from the .gdat files after all simulations complete:
# Run all simulations first
for A in Areas:
bngl_content = bngl_template.replace("{AREA}", str(A))
with open(f"test_A_{A}.bngl", "w") as f:
f.write(bngl_content)
bionetgen.run(f"test_A_{A}.bngl")
# Then load results from .gdat files
results = []
for A in Areas:
data = np.genfromtxt(f"test_A_{A}.gdat", names=True)
results.append(data)
Environment
- PyBioNetGen version: 0.8.6
- Python version: 3.12.3
- Operating system: macOS (Darwin 23.6.0)
Impact
This issue makes it impossible to store and compare results from multiple BioNetGen simulations in memory, forcing users to reload data from disk. This is both inefficient and non-intuitive.
Summary
When calling
bionetgen.run()multiple times in a loop and storing the results in a list, all entries in the list end up pointing to the same data from the final simulation. The data appears to be overwritten on each iteration, and even using.copy()on the returned numpy recarray does not create independent copies.Expected Behavior
Each call to
bionetgen.run()should return independent data that is not affected by subsequent calls.Actual Behavior
All stored results reference the same underlying data, which gets overwritten with each new call to
bionetgen.run().Minimal Reproducible Example
Output:
All results show the same value (from the last simulation), even though they were different when first returned.
Attempted Fix That Didn't Work
This also fails - all copies still reference the same underlying data.
Workaround
The only reliable workaround is to reload the data from the
.gdatfiles after all simulations complete:Environment
Impact
This issue makes it impossible to store and compare results from multiple BioNetGen simulations in memory, forcing users to reload data from disk. This is both inefficient and non-intuitive.