diff --git a/synbio_morpher/utils/circuit/agnostic_circuits/circuit.py b/synbio_morpher/utils/circuit/agnostic_circuits/circuit.py index aff71370..dee359c5 100644 --- a/synbio_morpher/utils/circuit/agnostic_circuits/circuit.py +++ b/synbio_morpher/utils/circuit/agnostic_circuits/circuit.py @@ -51,6 +51,7 @@ def init_refcircuit(self, config: dict): self.use_prod_and_deg = config.get('include_prod_deg', True) self.model = construct_bioreaction_model( config.get('data'), config.get('molecular_params'), include_prod_deg=self.use_prod_and_deg) + self.species_names = [s.name for s in self.model.species] self.circuit_size = len(self.model.species) self.data: DataManager = config.get('data') self.qreactions = self.init_reactions(self.model, config) diff --git a/synbio_morpher/utils/circuit/agnostic_circuits/circuit_manager.py b/synbio_morpher/utils/circuit/agnostic_circuits/circuit_manager.py index 5e9ad991..cb481c56 100644 --- a/synbio_morpher/utils/circuit/agnostic_circuits/circuit_manager.py +++ b/synbio_morpher/utils/circuit/agnostic_circuits/circuit_manager.py @@ -11,6 +11,7 @@ from datetime import datetime import inspect import os +import gc # import sys import logging import diffrax as dfx @@ -129,6 +130,30 @@ def compute_interactions(self, circuit: Circuit): filename_addon=filename_addon, subfolder=filename_addon) return circuit + def compute_interactions_batch(self, circuits, batch=True): + # Make sure multi-threading is on + assert self.simulator_args[''] > 1, 'Set the IntaRNA nu' + if self.simulator_args['name'] == 'IntaRNA': + if self.simulator_args['threads'] == 1: + logging.warning( + 'For batch-computation of interaction strengths with IntaRNA, multi-threading is recommended. Set `threads` in the config file within the simulator arguments (`interaction_simulator`) kwargs.') + # And that raw_stdout is set to true, otherwise IntaRNA will only return the first interaction + if self.simulator_args['raw_stdout'] == False: + logging.warning('For batching IntaRNA, setting raw_stdout to True, otherwise the output from the Python API will only return one interaction') + self.simulator_args['raw_stdout'] = True + + # Write temporary fasta file with all interactions + + + # Run simulator with fasta as input + + # Process output from string into csv into numpy + + # Fill in the species that didn't get returned with IntaRNA non-interaction default parameters + + # Delete fasta file + pass + def run_interaction_simulator(self, species: List[Species], quantities, filename=None) -> InteractionDataHandler: data = {s: s.physical_data for s in species} # if filename is not None: @@ -153,7 +178,7 @@ def find_steady_states(self, circuits: List[Circuit], batch=True) -> List[Circui category='time_series', vis_func=VisODE().plot, vis_kwargs={'t': t, - 'legend': [s.name for s in circuit.model.species], + 'legend': circuit.species_names, 'out_type': 'svg'}, analytics_kwargs={'labels': [ s.name for s in circuit.model.species]}, @@ -414,7 +439,7 @@ def prepare_batch_params(circuits: List[Circuit]): vis_func=VisODE().plot, analytics=analytics, vis_kwargs={'t': t, - 'legend': [s.name for s in circuit.model.species], + 'legend': circuit.species_names, 'out_type': 'svg'}) # return {top_name: {subname: circuits[len(v)*i + j] for j, subname in enumerate(v.keys())} # for i, (top_name, v) in enumerate(.items())} @@ -446,9 +471,10 @@ def load_mutations(self, circuit: Circuit): subcircuits[i].circuit_size = circuit.circuit_size subcircuits[i].signal: Signal = circuit.signal subcircuits[i].use_prod_and_deg = circuit.use_prod_and_deg - + # Cannot be by ref subcircuits[i].model = deepcopy(circuit.model) + subcircuits[i].species_names = circuit.species_name subcircuits[i].qreactions = deepcopy(circuit.qreactions) subcircuits[i] = implement_mutation(subcircuits[i], m) return subcircuits @@ -590,6 +616,7 @@ def batch_circuits(self, viable_circuit_nums = [0] next_viable = 0 i = 0 + assert num_subcircuits[0] < self.max_circuits, f'The number of subcircuits {num_subcircuits[0]} in the first circuit is less than the max circuits specified ({self.max_circuits}).' while i < len(num_subcircuits): while (i < len(num_subcircuits)) and (next_viable + num_subcircuits[i] < self.max_circuits): next_viable += num_subcircuits[i] @@ -645,6 +672,7 @@ def batch_circuits(self, logging.warning( f'Single batch: {single_batch_time} \nProjected time: {single_batch_time.total_seconds() * len(subcircuits)/tot_subcircuits}s \nTotal time: {str(datetime.now() - start_time)}') del subcircuits + gc.collect() return circuits def run_batch(self, diff --git a/synbio_morpher/utils/evolution/evolver.py b/synbio_morpher/utils/evolution/evolver.py index 2b8f863b..a67b288b 100644 --- a/synbio_morpher/utils/evolution/evolver.py +++ b/synbio_morpher/utils/evolution/evolver.py @@ -103,12 +103,12 @@ def make_species_iter(circuit: Circuit): if type(self.concurrent_species_to_mutate) == str: if self.concurrent_species_to_mutate == 'single_species_at_a_time': spec_iter = circuit.model.species - elif self.concurrent_species_to_mutate in [s.name for s in circuit.model.species]: + elif self.concurrent_species_to_mutate in circuit.species_names: spec_iter = [ s for s in circuit.model.species if s.name == self.concurrent_species_to_mutate] else: logging.warning(f'Could not find {self.concurrent_species_to_mutate} among the circuit species:') - logging.warning([s.name for s in circuit.model.species]) + logging.warning(circuit.species_names) elif type(self.concurrent_species_to_mutate) == list: spec_iter = [] for c in self.concurrent_species_to_mutate: @@ -239,7 +239,7 @@ def write_mutations(self, mutations: Mutations, overwrite=False): def load_mutations(circuit, filename=None): table = load_csv(filename, load_as='pandas') circuit.mutations = {} - species_names = [s.name for s in circuit.model.species] + species_names = circuit.species_names for i in range(len(table)): mutating_species = circuit.model.species[species_names.index( table.iloc[i]['template_name'])] diff --git a/synbio_morpher/utils/evolution/mutation.py b/synbio_morpher/utils/evolution/mutation.py index 8c3137f2..a784919a 100644 --- a/synbio_morpher/utils/evolution/mutation.py +++ b/synbio_morpher/utils/evolution/mutation.py @@ -125,8 +125,8 @@ def reverse_mut_mapping(self, mut_encoding: int): def implement_mutation(circuit: Circuit, mutation: Mutations): - if mutation.template_name in [s.name for s in circuit.model.species]: - sidx = [s.name for s in circuit.model.species].index(mutation.template_name) + if mutation.template_name in circuit.species_names: + sidx = circuit.species_names.index(mutation.template_name) # circuit.model.species[sidx].name = mutation.mutation_name circuit.model.species[sidx].physical_data = mutation.get_sequence() else: