def test_singleton(self): r1 = RandomStateManager.instance() r2 = RandomStateManager.instance() self.assertEqual(r1, r2) r1.seed(123) r2.seed(456) np.testing.assert_equal(r1.get_state(), r2.get_state()) self.assertEqual(r1, r2)
def __init__(self, model, wc_sim_config, options=None): """ Args: model (:obj:`Model`): the model being simulated wc_sim_config (:obj:`WCSimulationConfig`): a whole-cell simulation configuration options (:obj:`dict`, optional): options for submodels, keyed by submodel class name """ # initialize simulation infrastructure self.simulation = SimulationEngine() self.random_state = RandomStateManager.instance() # create simulation attributes self.model = model self.wc_sim_config = wc_sim_config self.options = options self._skipped_submodels = self.prepare_skipped_submodels() # a model without submodels cannot be simulated submodel_ids = set( [submodel.id for submodel in self.model.get_submodels()]) if not submodel_ids - self.skipped_submodels(): raise MultialgorithmError( f"model {self.model.id} cannot be simulated because it contains" f" no submodels")
def __init__(self, id, dynamic_model, reactions, species, dynamic_compartments, local_species_population, options=None): """ Initialize an NRM submodel object Args: id (:obj:`str`): unique id of this dynamic NRM submodel dynamic_model (:obj:`DynamicModel`): the aggregate state of a simulation reactions (:obj:`list` of :obj:`Reaction`): the reactions modeled by this NRM submodel species (:obj:`list` of :obj:`Species`): the species that participate in the reactions modeled by this NRM submodel, with their initial concentrations dynamic_compartments (:obj:`dict`): :obj:`DynamicCompartment`\ s, keyed by id, that contain species which participate in reactions that this NRM submodel models, including adjacent compartments used by its transfer reactions local_species_population (:obj:`LocalSpeciesPopulation`): the store that maintains this NRM submodel's species population options (:obj:`dict`, optional): NRM submodel options Raises: :obj:`MultialgorithmError`: if the initial NRM wait exponential moving average is not positive """ super().__init__(id, dynamic_model, reactions, species, dynamic_compartments, local_species_population) self.random_state = RandomStateManager.instance() self.execution_time_priority_queue = PQDict() self.options = options # to enable testing of uninitialized instances auto_initialize controls initialization here # auto_initialize defaults to True auto_initialize = True if options is not None and 'auto_initialize' in options: auto_initialize = options['auto_initialize'] if auto_initialize: self.initialize()
def setUp(self): # make a Compartment & use it to make a DynamicCompartment comp_id = 'comp_id' self.mean_init_volume = 1E-17 self.compartment = Compartment(id=comp_id, name='name', init_volume=InitVolume( mean=self.mean_init_volume, std=self.mean_init_volume / 40.)) self.compartment.init_density = Parameter( id='density_{}'.format(comp_id), value=1100., units=unit_registry.parse_units('g l^-1')) self.random_state = RandomStateManager.instance() self.dynamic_compartment = DynamicCompartment(None, self.random_state, self.compartment) self.abstract_compartment = Compartment( id=comp_id, name='name', init_volume=InitVolume(mean=self.mean_init_volume, std=0), physical_type=onto['WC:abstract_compartment']) self.abstract_dynamic_compartment = DynamicCompartment( None, self.random_state, self.abstract_compartment)
def setUp(self): comp_id = 'comp_id' # make a LocalSpeciesPopulation self.num_species = 100 species_nums = list(range(0, self.num_species)) self.species_ids = list( map(lambda x: "species_{}[{}]".format(x, comp_id), species_nums)) self.all_pops = 1E6 self.init_populations = dict( zip(self.species_ids, [self.all_pops] * len(species_nums))) self.all_m_weights = 50 self.molecular_weights = dict( zip(self.species_ids, [self.all_m_weights] * len(species_nums))) self.local_species_pop = LocalSpeciesPopulation( 'test', self.init_populations, self.molecular_weights, random_state=RandomStateManager.instance()) # make Compartments & use them to make a DynamicCompartments self.mean_init_volume = 1E-17 self.compartment = Compartment(id=comp_id, name='name', init_volume=InitVolume( mean=self.mean_init_volume, std=self.mean_init_volume / 40.)) self.compartment.init_density = Parameter( id='density_{}'.format(comp_id), value=1100., units=unit_registry.parse_units('g l^-1')) self.random_state = RandomStateManager.instance() self.dynamic_compartment = DynamicCompartment(None, self.random_state, self.compartment, self.species_ids) self.abstract_compartment = Compartment( id=comp_id, name='name', init_volume=InitVolume(mean=self.mean_init_volume, std=0), physical_type=onto['WC:abstract_compartment']) self.abstract_dynamic_compartment = DynamicCompartment( None, self.random_state, self.abstract_compartment)
def __init__(self, id, dynamic_model, reactions, species, dynamic_compartments, local_species_population, default_center_of_mass=None, options=None): """ Initialize an SSA submodel object. Args: id (:obj:`str`): unique id of this dynamic SSA submodel dynamic_model (:obj:`DynamicModel`): the aggregate state of a simulation reactions (:obj:`list` of :obj:`Reaction`): the reactions modeled by this SSA submodel species (:obj:`list` of :obj:`Species`): the species that participate in the reactions modeled by this SSA submodel, with their initial concentrations dynamic_compartments (:obj:`dict`): :obj:`DynamicCompartment`\ s, keyed by id, that contain species which participate in reactions that this SSA submodel models, including adjacent compartments used by its transfer reactions local_species_population (:obj:`LocalSpeciesPopulation`): the store that maintains this SSA submodel's species population default_center_of_mass (:obj:`float`, optional): the center-of-mass for the :obj:`ExponentialMovingAverage` options (:obj:`dict`, optional): SSA submodel options Raises: :obj:`MultialgorithmError`: if the initial SSA wait exponential moving average is not positive """ super().__init__(id, dynamic_model, reactions, species, dynamic_compartments, local_species_population) self.options = options self.num_SsaWaits = 0 # `initial_ssa_wait_ema` must be positive, as otherwise an infinite sequence of SsaWait # messages will be executed at the start of a simulation if no reactions are enabled initial_ssa_wait_ema = config_multialgorithm['initial_ssa_wait_ema'] if initial_ssa_wait_ema <= 0: # pragma: no cover raise MultialgorithmError( f"'initial_ssa_wait_ema' must be positive to avoid infinite sequence of " "SsaWait messages, but it is {initial_ssa_wait_ema}") if default_center_of_mass is None: default_center_of_mass = config_multialgorithm[ 'default_center_of_mass'] self.ema_of_inter_event_time = ExponentialMovingAverage( initial_ssa_wait_ema, center_of_mass=default_center_of_mass) self.random_state = RandomStateManager.instance() self.log_with_time("init: id: {}".format(id)) self.log_with_time("init: species: {}".format( str([s.id for s in species])))
def test_initialize_mass_and_density(self): self.dynamic_compartment.initialize_mass_and_density( self.local_species_pop) estimated_accounted_mass = self.num_species * self.all_pops * self.all_m_weights / Avogadro self.assertAlmostEqual(self.dynamic_compartment.init_accounted_mass, estimated_accounted_mass, places=IEEE_64_BIT_FLOATING_POINT_PLACES) self.assertTrue(0 < self.dynamic_compartment.init_mass) self.assertAlmostEqual(self.dynamic_compartment.accounted_fraction, self.dynamic_compartment.init_accounted_mass / \ self.dynamic_compartment.init_mass, places=IEEE_64_BIT_FLOATING_POINT_PLACES) # test abstract compartment self.abstract_dynamic_compartment.initialize_mass_and_density( self.local_species_pop) self.assertAlmostEqual( self.abstract_dynamic_compartment.init_accounted_mass, estimated_accounted_mass, places=IEEE_64_BIT_FLOATING_POINT_PLACES) self.assertEqual(self.abstract_dynamic_compartment.init_accounted_mass, self.abstract_dynamic_compartment.init_mass) self.assertFalse( hasattr(self.abstract_dynamic_compartment, 'init_accounted_density')) empty_local_species_pop = LocalSpeciesPopulation( 'test', {}, {}, random_state=RandomStateManager.instance()) dynamic_compartment = DynamicCompartment(None, self.random_state, self.compartment) with self.assertRaisesRegex(MultialgorithmError, "initial accounted ratio is 0"): dynamic_compartment.initialize_mass_and_density( empty_local_species_pop) dynamic_compartment = self.specify_init_accounted_fraction( (DynamicCompartment.MAX_ALLOWED_INIT_ACCOUNTED_FRACTION + 1) / 2) with warnings.catch_warnings(record=True) as w: dynamic_compartment.initialize_mass_and_density( self.local_species_pop) self.assertIn("initial accounted ratio (", str(w[-1].message)) self.assertIn(") greater than 1.0", str(w[-1].message)) dynamic_compartment = self.specify_init_accounted_fraction(2) with self.assertRaises(MultialgorithmError): dynamic_compartment.initialize_mass_and_density( self.local_species_pop)
def __init__(self, init_val): self.value = init_val self.random_state = RandomStateManager.instance()
def expected_molar_conc(self, dynamic_submodel, species_id): species = list(filter(lambda s: s.id == species_id, dynamic_submodel.species))[0] init_volume = species.compartment.init_volume.mean copy_num = ModelUtilities.sample_copy_num_from_concentration(species, init_volume, RandomStateManager.instance()) volume = dynamic_submodel.dynamic_compartments[species.compartment.id].volume() return copy_num / (volume * Avogadro)
def run(self, time_max, results_dir=None, progress_bar=True, checkpoint_period=None, seed=None, ode_time_step=None, dfba_time_step=None, profile=False, submodels_to_skip=None, verbose=True, options=None): """ Run one simulation Args: time_max (:obj:`float`): the maximum time of a simulation; a stop condition may end it earlier (sec) results_dir (:obj:`str`, optional): path to a directory in which results are stored progress_bar (:obj:`bool`, optional): whether to show the progress of a simulation in in a real-time bar on a terminal checkpoint_period (:obj:`float`, optional): the period between simulation state checkpoints (sec) ode_time_step (:obj:`float`, optional): time step length of ODE submodel (sec) dfba_time_step (:obj:`float`, optional): time step length of dFBA submodel (sec) profile (:obj:`bool`, optional): whether to output a profile of the simulation's performance created by a Python profiler seed (:obj:`object`, optional): a seed for the simulation's `numpy.random.RandomState`; if provided, `seed` will reseed the simulator's PRNG submodels_to_skip (:obj:`list` of :obj:`str`, optional): submodels that should not be run, identified by their ids verbose (:obj:`bool`, optional): whether to print success output options (:obj:`dict`, optional): options for submodels, passed to `MultialgorithmSimulation` Returns: :obj:`tuple` of (`int`, `str`): number of simulation events, pathname of directory containing the results, or :obj:`tuple` of (`int`, `None`): number of simulation events, `None` if `results_dir is None`, or :obj:`tuple` of (`pstats.Stats`, `None`): profile stats, `None` if `profile is True` Raises: :obj:`MultialgorithmError`: if the simulation raises an exception """ self._prepare() # create simulation configurations # create and validate DE sim configuration self.de_sim_config = SimulationConfig(time_max, output_dir=results_dir, progress=progress_bar, profile=profile) self.de_sim_config.validate() # create and validate WC configuration self.wc_sim_config = WCSimulationConfig( de_simulation_config=self.de_sim_config, random_seed=seed, ode_time_step=ode_time_step, dfba_time_step=dfba_time_step, checkpoint_period=checkpoint_period, submodels_to_skip=submodels_to_skip, verbose=verbose) self.wc_sim_config.validate() # create author metadata for DE sim try: username = getpass.getuser() except KeyError: # pragma: no cover username = '******' self.author_metadata = AuthorMetadata( name='Unknown name', email='Unknown email', username=username, organization='Unknown organization') # create WC sim metadata wc_simulation_metadata = WCSimulationMetadata(self.wc_sim_config) if self.model_path is not None: wc_simulation_metadata.set_wc_model_repo(self.model_path) if seed is not None: RandomStateManager.initialize(seed=seed) # create a multi-algorithmic simulator multialgorithm_simulation = MultialgorithmSimulation( self.model, self.wc_sim_config, options) self.simulation_engine, self.dynamic_model = multialgorithm_simulation.build_simulation( ) self.simulation_engine.initialize() # set stop_condition after the dynamic model is created self.de_sim_config.stop_condition = self.dynamic_model.get_stop_condition( ) # run simulation try: # provide DE config and author metadata to DE sim simulate_rv = self.simulation_engine.simulate( sim_config=self.de_sim_config, author_metadata=self.author_metadata) # add WC sim metadata to the output after the simulation, which requires an empty output dir # TODO: have simulation_engine.simulate() allow certain files in self.de_sim_config.output_dir, and move # this code above if self.de_sim_config.output_dir is not None: WCSimulationMetadata.write_dataclass( wc_simulation_metadata, self.de_sim_config.output_dir) if profile: stats = simulate_rv return stats, None else: num_events = simulate_rv except SimulatorError as e: # pragma: no cover raise MultialgorithmError( f'Simulation terminated with simulator error:\n{e}') except BaseException as e: # pragma: no cover raise MultialgorithmError( f'Simulation terminated with error:\n{e}') if verbose: print(f'Simulated {num_events} events') if results_dir: # summarize results in an HDF5 file in results_dir RunResults(results_dir) if verbose: print(f"Saved checkpoints and run results in '{results_dir}'") return (num_events, results_dir) else: return (num_events, None)