You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
Non-Deterministic results PreProcess.reduce(extend=True) due to internal MCMC sampling #136
Describe the bug
When running PreProcess.reduce(extend=True) on the same model multiple times, the function returns different sets of removed reactions. This non-determinism prevents reproducibility for downstream analysis.
To Reproduce
Steps to reproduce the behavior:
Go to your root directory.
Create a test file.
here is a minimal script using e_coli_core.json to recreate the error
import numpy as np
import cobra.io
from dingo.preprocess import PreProcess
def test_extend_nondeterminism():
ecoli = cobra.io.load_json_model("ext_data/e_coli_core.json")
np.random.seed(42)
preprocessor_A = PreProcess(ecoli.copy(), tol=1e-6, verbose=False)
removed_A, _ = preprocessor_A.reduce(extend=True)
np.random.seed(42)
preprocessor_B = PreProcess(ecoli.copy(), tol=1e-6, verbose=False)
removed_B, _ = preprocessor_B.reduce(extend=True)
set_A, set_B = frozenset(removed_A), frozenset(removed_B)
if set_A != set_B:
print(f"Reactions removed ONLY in Run A: {sorted(set_A - set_B)}")
print(f"Reactions removed ONLY in Run B: {sorted(set_B - set_A)}")
if __name__ == "__main__":
test_extend_nondeterminism()
Expected behavior
Given the same metabolic model and the same algorithm parameters, reduce(extend=True) should always return the same set of removed reactions.
Screenshots
Proposed fix
Add an optional steady_states parameter to reduce().
When steady_states is provided by the caller, the internal sampling step is skipped entirely and the provided matrix is used directly for correlation estimation. When steady_states=None (the default), the current internal sampling behaviour is preserved as a fallback for convenience, but a UserWarning is emitted so the user is informed that results will not be reproducible.
"Hi Palash, this looks like a clear issue. I'd like to work on adding the steady_states parameter and warning fallback as proposed. Is this still available?"
Hey @PalashMendhe, I’ve opened PR #145 to address this issue.
I traced the non-reproducibility to the internal MCMC sampling used by PreProcess.reduce(extend=True). The sampler uses its own random number generator, so np.random.seed() does not control those samples.
The PR adds an optional steady_states argument to reduce(), allowing precomputed steady states to be supplied and bypass the internal sampling. When they aren't supplied, the existing behavior is preserved with a UserWarning about reproducibility.
I’ve also added tests for the supplied steady-state path and input validation, and the full test suite passes (27 tests, OK).
Would appreciate your review.
Activity
Arun-sunny23 commentedon Sep 2, 2026
"Hi Palash, this looks like a clear issue. I'd like to work on adding the steady_states parameter and warning fallback as proposed. Is this still available?"
aryamanDutta commentedon Sep 5, 2026
Hey @PalashMendhe, I’ve opened PR #145 to address this issue.
I traced the non-reproducibility to the internal MCMC sampling used by PreProcess.reduce(extend=True). The sampler uses its own random number generator, so np.random.seed() does not control those samples.
The PR adds an optional steady_states argument to reduce(), allowing precomputed steady states to be supplied and bypass the internal sampling. When they aren't supplied, the existing behavior is preserved with a UserWarning about reproducibility.
I’ve also added tests for the supplied steady-state path and input validation, and the full test suite passes (27 tests, OK).
Would appreciate your review.