def bng_simulate(model, times, method='ode', output_dir='/tmp', cleanup=True): """ Simulate a model with BNG's simulator and return the trajectories. Adapted from pysb.bng.run_ssa. Parameters ---------- model : pysb.Model or string Model to simulate. Can be either a pysb.Model or a string representing BNGL model. times: list of floats Sample times. method: string 'ode' or 'ssa' output_dir : string, optional Location for temporary files generated by BNG. Defaults to '/tmp'. cleanup : bool, optional If True (default), delete the temporary files after the simulation is finished. If False, leave them in place (in `output_dir`). Useful for debugging. """ times = list(times) run_ssa_code = """ begin actions generate_network({overwrite=>1}); simulate_%s({sample_times=>%s});\n end actions """ % (method, times) if not isinstance(model, str): model = BngGenerator(model).get_content() bng_filename = '%d_%d_temp.bngl' % ( os.getpid(), random.randint(0, 10000)) gdat_filename = bng_filename.replace('.bngl', '.gdat') cdat_filename = bng_filename.replace('.bngl', '.cdat') net_filename = bng_filename.replace('.bngl', '.net') try: working_dir = os.getcwd() os.chdir(output_dir) bng_file = open(bng_filename, 'w') bng_file.write(model) bng_file.write(run_ssa_code) bng_file.close() p = subprocess.Popen(['perl', _get_bng_path(), bng_filename], stdout=subprocess.PIPE, stderr=subprocess.PIPE) (p_out, p_err) = p.communicate() if p.returncode: raise GenerateNetworkError(p_out.rstrip("at line") + "\n" + p_err.rstrip()) output_arr = _parse_bng_outfile(gdat_filename) finally: if cleanup: for filename in [bng_filename, gdat_filename, cdat_filename, net_filename]: if os.access(filename, os.F_OK): os.unlink(filename) os.chdir(working_dir) return output_arr
def save_bng_dirs_to_hdf5(data_basename, num_conditions, filename): """Load the .gdat files in each of the listed directories to HDF5. The HDF5 file created contains two datasets: * A dataset named ``'data'`` which contains the simulation results in a four-dimensional numpy array of floats with shape `(num_conditions, num_simulations, num_observables, num_timepoints)`. * A dataset named ``'dtypes'`` containing the string-pickled dtype of the simulation results. The dtype contains the names of all of the observables from the original record array, and hence can be used to get the index for a particular observable in the full table of simulation results. Parameters ---------- data_basename : string For parsing multiple directories, the base name of the .gdat data directories before the index of the job condition is appended, e.g., 'data\_' for the list of directories 'data_0', 'data_1', 'data_2'. However, when there is only a single directory being parsed (i.e., num_conditions is 1), then this argument is taken to be the full name of the data directory, e.g., 'data_0', and no index is appended. num_conditions : int The number of data directories/conditions, e.g., 3 for the list of directories 'data_0', 'data_1', 'data_2'. filename : string The name of the HDF5 file to create. Returns ------- h5py dataset The dataset containing the parsed simulation results and the corresponding dtype list. """ dataset = None print "Loading BNG simulation results from data directories..." for condition_index in range(num_conditions): if num_conditions == 1: data_dir = data_basename else: data_dir = '%s%d' % (data_basename, condition_index) print "Loading data from directory %s" % data_dir gdat_files = glob.glob('%s/*.gdat' % data_dir) for sim_index, gdat_file in enumerate(gdat_files): ssa_result = bng._parse_bng_outfile(gdat_file) # Initialize the dataset if dataset is None: num_simulations = len(gdat_files) num_observables = len(ssa_result.dtype) num_timepoints = len(ssa_result) f = h5py.File('%s.hdf5' % filename, 'w') dataset = f.create_dataset('data', (num_conditions, num_simulations, num_observables, num_timepoints), dtype='float', chunks=(1, min(SIM_CHUNK_SIZE, num_simulations), 1, min(TIME_CHUNK_SIZE, num_timepoints)), compression=9, shuffle=True) # Make sure there's no funny business assert len(gdat_files) == num_simulations assert len(ssa_result.dtype) == num_observables assert len(ssa_result) == num_timepoints # Load the data into the appropriate slot in the dataset dataset[condition_index, sim_index, :, :] = \ ssa_result.view('float').reshape(num_timepoints, -1).T print "\rLoaded BNG file %d of %d" % (sim_index+1, num_simulations), sys.stdout.flush() # (end iteration over all .gdat files in the directory) print # Add a newline # (end iteration over all data directories) # Pickle the dtype with the observables and save in the dataset dtype_pck = pickle.dumps(ssa_result.dtype) f.create_dataset('dtypes', dtype='uint8', data=map(ord, dtype_pck)) f.close() return dataset