def show_contact_map(model, **kwargs): gen = KappaGenerator(model, dialect='complx') #kappa_filename = '%d_%d_temp.ka' % (os.getpid(), random.randint(0, 10000)) kappa_filename = '%s.ka' % model.name jpg_filename = kappa_filename.replace('.ka', '.jpg') args = ['--output-high-res-contact-map-jpg', jpg_filename] run_complx(gen, kappa_filename, args, **kwargs) open_file(jpg_filename)
def contact_map(model, output_dir='.', base_filename=None, do_open=False, **kwargs): """Runs complx with arguments for generating the contact map. Parameters ---------- model : pysb.core.Model The model for generating the contact map. output_dir : string The subdirectory in which to generate the Kappa (.ka) file for the model and all output files produced by complx. Default value is '.' Note that only relative paths can be specified; paths are relative to the directory where the current Python instance is running. If the specified directory does not exist, an Exception is thrown. base_filename : string The base filename to be used for generation of the Kappa (.ka) file and all output files produced by complx. Defaults to a string of the form:: '%s_%d_%d_temp' % (model.name, os.getpid(), random.randint(0,10000)) The contact map filenames append '_cm.jpg' and '_cm.dot' to this base filename; the reachable complexes filename appends '_rch.dot'. do_open : boolean If do_open is set to True, then calls the :py:func:`open_file` method to display the contact map using the default program for opening .jpg files. **kwargs : other keyword arguments Any other keyword arguments are passed through to the function :py:func:`run_complx`. """ gen = KappaGenerator(model, dialect='complx') if not base_filename: base_filename = '%s/%s_%d_%d_temp' % ( output_dir, model.name, os.getpid(), random.randint(0, 10000)) kappa_filename = base_filename + '.ka' jpg_filename = base_filename + '_cm.jpg' dot_filename = base_filename + '_cm.dot' reachables_filename = base_filename + '_rch.dot' args = [ '--output-high-res-contact-map-jpg', jpg_filename, '--output-high-res-contact-map-dot', dot_filename, '--output-reachable-complexes', reachables_filename ] run_complx(gen, kappa_filename, args, **kwargs) if do_open: open_file(jpg_filename)
def run_kasim(model, time=10000, points=200, output_dir='.'): gen = KappaGenerator(model) #kappa_filename = '%d_%d_temp.ka' % (os.getpid(), random.randint(0, 10000)) kappa_filename = '%s/%s_%d_%d_temp.ka' % (output_dir, model.name, os.getpid(), random.randint(0, 10000)) im_filename = kappa_filename.replace('.ka', '_im.gv') fm_filename = kappa_filename.replace('.ka', '_fm.gv') out_filename = kappa_filename.replace('.ka', '.out') args = ['-i', kappa_filename, '-t', str(time), '-p', str(points), '-o', out_filename, '-im', im_filename, '-flux', fm_filename] try: kappa_file = open(kappa_filename, 'w') kappa_file.write(gen.get_content()) kappa_file.close() # FIXME print "Running kasim" p = subprocess.Popen(['KaSim'] + args) #stdout=subprocess.PIPE, stderr=subprocess.STDOUT) p.communicate() if p.returncode: raise Exception(p.stdout.read()) except Exception as e: raise Exception("problem running KaSim: " + str(e)) #finally: #if cleanup: # for filename in [kappa_filename, im_filename, # fm_filename, out_filename]: # if os.access(filename, os.F_OK): # os.unlink(filename) output_dict = {'out':out_filename, 'im':im_filename, 'fm':'flux.dot'} return output_dict
def export(self, dialect='kasim'): """Generate the corresponding Kappa for the PySB model associated with the exporter. A wrapper around :py:class:`pysb.generator.kappa.KappaGenerator`. Parameters ---------- dialect : (optional) string, either 'kasim' (default) or 'complx' The Kappa file syntax for the Kasim simulator is slightly different from that of the complx analyzer. This argument specifies which type of Kappa to produce ('kasim' is the default). Returns ------- string The Kappa output. """ kappa_str = '' if self.docstring: kappa_str += '# ' + self.docstring.replace('\n', '\n# ') + '\n' gen = KappaGenerator(self.model, dialect=dialect) kappa_str += gen.get_content() return kappa_str
def run_kasim(model, time=10000, points=200, output_dir='.', cleanup=False, base_filename=None, dump_influence_map=False, perturbation=None): """Run KaSim on the given model with the provided arguments. Parameters ---------- model : pysb.core.Model The model to simulate/analyze using KaSim. time : number The amount of time (in arbitrary units) to run a simulation. Identical to the -t argument when using KaSim at the command line. Default value is 10000. If set to 0, no simulation will be run, but the influence map will be generated (if dump_influence_map is set to True). points : integer The number of data points to collect for plotting. Identical to the -p argument when using KaSim at the command line. Default value is 200. output_dir : string The subdirectory in which to generate the Kappa (.ka) file for the model and all output files produced by KaSim. Default value is '.' Note that only relative paths can be specified; paths are relative to the directory where the current Python instance is running. If the specified directory does not exist, an Exception is thrown. cleanup : boolean Specifies whether output files produced by KaSim should be deleted after execution is completed. Default value is False. base_filename : The base filename to be used for generation of the Kappa (.ka) file and all output files produced by KaSim. Defaults to a string of the form:: '%s_%d_%d_temp' % (model.name, program id, random.randint(0,10000)) The influence map filename appends '_im.dot' to this base filename; the flux map filename appends '_fm.dot'; and the simulation output file appends '.out' dump_influence_map : boolean Specifies whether or not to produce the influence map. Default value is False. perturbation : string or None Optional perturbation language syntax to be appended to the Kappa file. See KaSim manual for more details. Default value is None (no perturbation). Returns ------- A dict with three entries giving the filenames for the files produced: * output_dict['out'] gives the .out filename * output_dict['im'] gives the influence map filename * output_dict['fm'] gives the flux map filename """ gen = KappaGenerator(model) if not base_filename: base_filename = '%s/%s_%d_%d_temp' % (output_dir, model.name, os.getpid(), random.randint(0, 10000)) kappa_filename = base_filename + '.ka' im_filename = base_filename + '_im.dot' fm_filename = base_filename + '_fm.dot' out_filename = base_filename + '.out' args = ['-i', kappa_filename, '-t', str(time), '-p', str(points), '-o', out_filename] try: kappa_file = open(kappa_filename, 'w') # Generate the Kappa model code from the PySB model and write it to # the Kappa file: kappa_file.write(gen.get_content()) # If desired, add instructions to the kappa file to generate the # influence map: if dump_influence_map: kappa_file.write('%def: "dumpInfluenceMap" "true"\n') kappa_file.write('%%def: "influenceMapFileName" "%s"\n\n' % im_filename) # If any perturbation language code has been passed in, add it to the # Kappa file: if perturbation: kappa_file.write('\n%s\n' % perturbation) kappa_file.close() print "Running kasim" p = subprocess.Popen(['KaSim'] + args) #stdout=subprocess.PIPE, stderr=subprocess.STDOUT) p.communicate() if p.returncode: raise Exception(p.stdout.read()) except Exception as e: raise Exception("Problem running KaSim: " + str(e)) finally: if cleanup: for filename in [kappa_filename, im_filename, fm_filename, out_filename]: if os.access(filename, os.F_OK): os.unlink(filename) output_dict = {'out':out_filename, 'im':im_filename, 'fm':'flux.dot'} return output_dict
def run_simulation(model, time=10000, points=200, cleanup=True, output_prefix=None, output_dir=None, flux_map=False, perturbation=None, seed=None, verbose=False): """Runs the given model using KaSim and returns the parsed results. Parameters ---------- model : pysb.core.Model The model to simulate/analyze using KaSim. time : number The amount of time (in arbitrary units) to run a simulation. Identical to the -u time -l argument when using KaSim at the command line. Default value is 10000. If set to 0, no simulation will be run. points : integer The number of data points to collect for plotting. Note that this is not identical to the -p argument of KaSim when called from the command line, which denotes plot period (time interval between points in plot). Default value is 200. Note that the number of points actually returned by the simulator will be points + 1 (including the 0 point). cleanup : boolean Specifies whether output files produced by KaSim should be deleted after execution is completed. Default value is True. output_prefix: str Prefix of the temporary directory name. Default is 'tmpKappa_<model name>_'. output_dir : string The directory in which to create the temporary directory for the .ka and other output files. Defaults to the system temporary file directory (e.g. /tmp). If the specified directory does not exist, an Exception is thrown. flux_map: boolean Specifies whether or not to produce the flux map (generated over the full duration of the simulation). Default value is False. perturbation : string or None Optional perturbation language syntax to be appended to the Kappa file. See KaSim manual for more details. Default value is None (no perturbation). seed : integer A seed integer for KaSim random number generator. Set to None to allow KaSim to use a random seed (default) or supply a seed for deterministic behaviour (e.g. for testing) verbose : boolean Whether to pass the output of KaSim through to stdout/stderr. Returns ------- If flux_map is False, returns the kasim simulation data as a Numpy ndarray. Data is accessed using the syntax:: results[index_name] The index 'time' gives the time coordinates of the simulation. Data for the observables can be accessed by indexing the array with the names of the observables. Each entry in the ndarray has length points + 1, due to the inclusion of both the zero point and the final timepoint. If flux_map is True, returns an instance of SimulationResult, a namedtuple with two members, `timecourse` and `flux_map`. The `timecourse` field contains the simulation ndarray, and the `flux_map` field is an instance of a pygraphviz AGraph containing the flux map. The flux map can be rendered as a pdf using the dot layout program as follows:: fluxmap.draw('fluxmap.pdf', prog='dot') """ gen = KappaGenerator(model) if output_prefix is None: output_prefix = 'tmpKappa_%s_' % model.name base_directory = tempfile.mkdtemp(prefix=output_prefix, dir=output_dir) base_filename = os.path.join(base_directory, model.name) kappa_filename = base_filename + '.ka' fm_filename = base_filename + '_fm.dot' out_filename = base_filename + '.out' if points == 0: raise ValueError('The number of data points cannot be zero.') plot_period = (float(time) / points) if time > 0 else 1.0 args = [ '-i', kappa_filename, '-u', 'time', '-l', str(time), '-p', '%.5f' % plot_period, '-o', out_filename ] if seed: args.extend(['-seed', str(seed)]) # Generate the Kappa model code from the PySB model and write it to # the Kappa file: with open(kappa_filename, 'w') as kappa_file: kappa_file.write(gen.get_content()) # If desired, add instructions to the kappa file to generate the # flux map: if flux_map: kappa_file.write('%%mod: [true] do $FLUX "%s" [true]\n' % fm_filename) # If any perturbation language code has been passed in, add it to # the Kappa file: if perturbation: kappa_file.write('\n%s\n' % perturbation) # Run KaSim kasim_path = pf.get_path('kasim') p = subprocess.Popen([kasim_path] + args, stdout=subprocess.PIPE, stderr=subprocess.PIPE, cwd=base_directory) if verbose: for line in iter(p.stdout.readline, b''): print('@@', line, end='') (p_out, p_err) = p.communicate() if p.returncode: raise KasimInterfaceError(p_out + '\n' + p_err) # The simulation data, as a numpy array data = _parse_kasim_outfile(out_filename) if flux_map: try: import pygraphviz flux_graph = pygraphviz.AGraph(fm_filename) except ImportError: if cleanup: raise RuntimeError("Couldn't import pygraphviz, which is " "required to return the flux map as a " "pygraphviz AGraph object. Either install " "pygraphviz or set cleanup=False to retain " "dot files.") else: warnings.warn("pygraphviz could not be imported so no AGraph " "object returned (returning None); flux map " "dot file available at %s" % fm_filename) flux_graph = None if cleanup: shutil.rmtree(base_directory) # If a flux map was generated, return both the simulation output and the # flux map as a pygraphviz graph if flux_map: return SimulationResult(data, flux_graph) # If no flux map was requested, return only the simulation data else: return data
def run_static_analysis(model, influence_map=False, contact_map=False, cleanup=True, output_prefix=None, output_dir=None, verbose=False): """Run static analysis (KaSa) on to get the contact and influence maps. If neither influence_map nor contact_map are set to True, then a ValueError is raised. Parameters ---------- model : pysb.core.Model The model to simulate/analyze using KaSa. influence_map : boolean Whether to compute the influence map. contact_map : boolean Whether to compute the contact map. cleanup : boolean Specifies whether output files produced by KaSa should be deleted after execution is completed. Default value is True. output_prefix: str Prefix of the temporary directory name. Default is 'tmpKappa_<model name>_'. output_dir : string The directory in which to create the temporary directory for the .ka and other output files. Defaults to the system temporary file directory (e.g. /tmp). If the specified directory does not exist, an Exception is thrown. verbose : boolean Whether to pass the output of KaSa through to stdout/stderr. Returns ------- StaticAnalysisResult, a namedtuple with two fields, `contact_map` and `influence_map`, each containing the respective result as an instance of a pygraphviz AGraph. If the either the contact_map or influence_map argument to the function is False, the corresponding entry in the StaticAnalysisResult returned by the function will be None. """ # Make sure the user has asked for an output! if not influence_map and not contact_map: raise ValueError('Either contact_map or influence_map (or both) must ' 'be set to True in order to perform static analysis.') gen = KappaGenerator(model, _warn_no_ic=False) if output_prefix is None: output_prefix = 'tmpKappa_%s_' % model.name base_directory = tempfile.mkdtemp(prefix=output_prefix, dir=output_dir) base_filename = os.path.join(base_directory, str(model.name)) kappa_filename = base_filename + '.ka' im_filename = base_filename + '_im.dot' cm_filename = base_filename + '_cm.dot' # NOTE: in the args passed to KaSa, the directory for the .dot files is # specified by the --output_directory option, and the output_contact_map # and output_influence_map should only be the base filenames (without # a directory prefix). # Contact map args: if contact_map: cm_args = [ '--compute-contact-map', '--output-contact-map', os.path.basename(cm_filename), '--output-contact-map-directory', base_directory ] else: cm_args = ['--no-compute-contact-map'] # Influence map args: if influence_map: im_args = [ '--compute-influence-map', '--output-influence-map', os.path.basename(im_filename), '--output-influence-map-directory', base_directory ] else: im_args = ['--no-compute-influence-map'] # Full arg list args = [kappa_filename] + cm_args + im_args # Generate the Kappa model code from the PySB model and write it to # the Kappa file: with open(kappa_filename, 'w') as kappa_file: kappa_file.write(gen.get_content()) # Run KaSa using the given args kasa_path = pf.get_path('kasa') p = subprocess.Popen([kasa_path] + args, stdout=subprocess.PIPE, stderr=subprocess.PIPE, cwd=base_directory) if verbose: for line in iter(p.stdout.readline, b''): print('@@', line, end='') (p_out, p_err) = p.communicate() if p.returncode: raise KasaInterfaceError(p_out + '\n' + p_err) # Try to create the graphviz objects from the .dot files created try: import pygraphviz # Convert the contact map to a Graph cmap = pygraphviz.AGraph(cm_filename) if contact_map else None imap = pygraphviz.AGraph(im_filename) if influence_map else None except ImportError: if cleanup: raise RuntimeError( "Couldn't import pygraphviz, which is " "required to return the influence and contact maps " " as pygraphviz AGraph objects. Either install " "pygraphviz or set cleanup=False to retain " "dot files.") else: warnings.warn("pygraphviz could not be imported so no AGraph " "objects returned (returning None); " "contact/influence maps available at %s" % base_directory) cmap = None imap = None # Clean up the temp directory if desired if cleanup: shutil.rmtree(base_directory) return StaticAnalysisResult(cmap, imap)
def generate_influence_map(model): gen = KappaGenerator(model) kappa_filename = '%d_%d_temp.ka' % (os.getpid(), random.randint(0, 10000)) dot_filename = kappa_filename.replace('.ka', '.jpg') args = ['--output-influence-map-jpg', jpg_filename] run_complx(gen, kappa_filename, args)
def run_static_analysis(model, influence_map=False, contact_map=False, cleanup=True, output_prefix=None, output_dir=None, verbose=False): """Run static analysis (KaSa) on to get the contact and influence maps. If neither influence_map nor contact_map are set to True, then a ValueError is raised. Parameters ---------- model : pysb.core.Model The model to simulate/analyze using KaSa. influence_map : boolean Whether to compute the influence map. contact_map : boolean Whether to compute the contact map. cleanup : boolean Specifies whether output files produced by KaSa should be deleted after execution is completed. Default value is True. output_prefix: str Prefix of the temporary directory name. Default is 'tmpKappa_<model name>_'. output_dir : string The directory in which to create the temporary directory for the .ka and other output files. Defaults to the system temporary file directory (e.g. /tmp). If the specified directory does not exist, an Exception is thrown. verbose : boolean Whether to pass the output of KaSa through to stdout/stderr. Returns ------- StaticAnalysisResult, a namedtuple with two fields, `contact_map` and `influence_map`, each containing the respective result as an instance of a networkx MultiGraph. If the either the contact_map or influence_map argument to the function is False, the corresponding entry in the StaticAnalysisResult returned by the function will be None. Notes ----- To view a networkx file graphically, use `draw_network`:: import networkx as nx nx.draw_networkx(g, with_labels=True) You can use `graphviz_layout` to use graphviz for layout (requires pydot library):: import networkx as nx pos = nx.drawing.nx_pydot.graphviz_layout(g, prog='dot') nx.draw_networkx(g, pos, with_labels=True) For further information, see the networkx documentation on visualization: https://networkx.github.io/documentation/latest/reference/drawing.html """ # Make sure the user has asked for an output! if not influence_map and not contact_map: raise ValueError('Either contact_map or influence_map (or both) must ' 'be set to True in order to perform static analysis.') gen = KappaGenerator(model, _warn_no_ic=False) if output_prefix is None: output_prefix = 'tmpKappa_%s_' % model.name base_directory = tempfile.mkdtemp(prefix=output_prefix, dir=output_dir) base_filename = os.path.join(base_directory, str(model.name)) kappa_filename = base_filename + '.ka' im_filename = base_filename + '_im.dot' cm_filename = base_filename + '_cm.dot' # NOTE: in the args passed to KaSa, the directory for the .dot files is # specified by the --output_directory option, and the output_contact_map # and output_influence_map should only be the base filenames (without # a directory prefix). # Contact map args: if contact_map: cm_args = [ '--compute-contact-map', '--output-contact-map', os.path.basename(cm_filename), '--output-contact-map-directory', base_directory ] else: cm_args = ['--no-compute-contact-map'] # Influence map args: if influence_map: im_args = [ '--compute-influence-map', '--output-influence-map', os.path.basename(im_filename), '--output-influence-map-directory', base_directory ] else: im_args = ['--no-compute-influence-map'] # Full arg list args = [kappa_filename] + cm_args + im_args # Generate the Kappa model code from the PySB model and write it to # the Kappa file: with open(kappa_filename, 'w') as kappa_file: file_data = gen.get_content() logger.debug('Kappa file contents:\n\n' + file_data) kappa_file.write(file_data) # Run KaSa using the given args kasa_path = pf.get_path('kasa') p = subprocess.Popen([kasa_path] + args, stdout=subprocess.PIPE, stderr=subprocess.PIPE, cwd=base_directory) if verbose: for line in iter(p.stdout.readline, b''): print('@@', line, end='') (p_out, p_err) = p.communicate() if p.returncode: raise KasaInterfaceError( p_out.decode('utf8') + '\n' + p_err.decode('utf8')) # Try to create the graphviz objects from the .dot files created try: # Convert the contact map to a Graph cmap = read_dot(cm_filename) if contact_map else None imap = read_dot(im_filename) if influence_map else None except ImportError: if cleanup: raise else: warnings.warn("The pydot library could not be " "imported, so no MultiGraph " "object returned (returning None); " "contact/influence maps available at %s" % base_directory) cmap = None imap = None # Clean up the temp directory if desired if cleanup: shutil.rmtree(base_directory) return StaticAnalysisResult(cmap, imap)
def run_static_analysis(model, influence_map=False, contact_map=False, cleanup=True, output_prefix=None, output_dir=None, verbose=False): """Run static analysis (KaSa) on to get the contact and influence maps. If neither influence_map nor contact_map are set to True, then a ValueError is raised. Parameters ---------- model : pysb.core.Model The model to simulate/analyze using KaSa. influence_map : boolean Whether to compute the influence map. contact_map : boolean Whether to compute the contact map. cleanup : boolean Specifies whether output files produced by KaSa should be deleted after execution is completed. Default value is True. output_prefix: str Prefix of the temporary directory name. Default is 'tmpKappa_<model name>_'. output_dir : string The directory in which to create the temporary directory for the .ka and other output files. Defaults to the system temporary file directory (e.g. /tmp). If the specified directory does not exist, an Exception is thrown. verbose : boolean Whether to pass the output of KaSa through to stdout/stderr. Returns ------- StaticAnalysisResult, a namedtuple with two fields, `contact_map` and `influence_map`, each containing the respective result as an instance of a pygraphviz AGraph. If the either the contact_map or influence_map argument to the function is False, the corresponding entry in the StaticAnalysisResult returned by the function will be None. """ # Make sure the user has asked for an output! if not influence_map and not contact_map: raise ValueError('Either contact_map or influence_map (or both) must ' 'be set to True in order to perform static analysis.') gen = KappaGenerator(model, _warn_no_ic=False) if output_prefix is None: output_prefix = 'tmpKappa_%s_' % model.name base_directory = tempfile.mkdtemp(prefix=output_prefix, dir=output_dir) base_filename = os.path.join(base_directory, str(model.name)) kappa_filename = base_filename + '.ka' im_filename = base_filename + '_im.dot' cm_filename = base_filename + '_cm.dot' # NOTE: in the args passed to KaSa, the directory for the .dot files is # specified by the --output_directory option, and the output_contact_map # and output_influence_map should only be the base filenames (without # a directory prefix). # Contact map args: if contact_map: cm_args = ['--compute-contact-map', '--output-contact-map', os.path.basename(cm_filename)] else: cm_args = ['--no-compute-contact-map'] # Influence map args: if influence_map: im_args = ['--compute-influence-map', '--output-influence-map', os.path.basename(im_filename)] else: im_args = ['--no-compute-influence-map'] # Full arg list args = [kappa_filename, '--output-directory', base_directory] \ + cm_args + im_args # Generate the Kappa model code from the PySB model and write it to # the Kappa file: with open(kappa_filename, 'w') as kappa_file: kappa_file.write(gen.get_content()) # Run KaSa using the given args kasa_path = _get_kappa_path('KaSa') p = subprocess.Popen([kasa_path] + args, stdout=subprocess.PIPE, stderr=subprocess.PIPE) if verbose: for line in iter(p.stdout.readline, b''): print('@@', line, end='') (p_out, p_err) = p.communicate() if p.returncode: raise KasaInterfaceError(p_out + '\n' + p_err) # Try to create the graphviz objects from the .dot files created try: import pygraphviz # Convert the contact map to a Graph cmap = pygraphviz.AGraph(cm_filename) if contact_map else None imap = pygraphviz.AGraph(im_filename) if influence_map else None except ImportError: if cleanup: raise RuntimeError( "Couldn't import pygraphviz, which is " "required to return the influence and contact maps " " as pygraphviz AGraph objects. Either install " "pygraphviz or set cleanup=False to retain " "dot files.") else: warnings.warn( "pygraphviz could not be imported so no AGraph " "objects returned (returning None); " "contact/influence maps available at %s" % base_directory) cmap = None imap = None # Clean up the temp directory if desired if cleanup: shutil.rmtree(base_directory) return StaticAnalysisResult(cmap, imap)
def run_simulation(model, time=10000, points=200, cleanup=True, output_prefix=None, output_dir=None, flux_map=False, perturbation=None, seed=None, verbose=False): """Runs the given model using KaSim and returns the parsed results. Parameters ---------- model : pysb.core.Model The model to simulate/analyze using KaSim. time : number The amount of time (in arbitrary units) to run a simulation. Identical to the -t argument when using KaSim at the command line. Default value is 10000. If set to 0, no simulation will be run. points : integer The number of data points to collect for plotting. Identical to the -p argument when using KaSim at the command line. Default value is 200. Note that the number of points actually returned by the simulator will be points + 1 (including the 0 point). cleanup : boolean Specifies whether output files produced by KaSim should be deleted after execution is completed. Default value is True. output_prefix: str Prefix of the temporary directory name. Default is 'tmpKappa_<model name>_'. output_dir : string The directory in which to create the temporary directory for the .ka and other output files. Defaults to the system temporary file directory (e.g. /tmp). If the specified directory does not exist, an Exception is thrown. flux_map: boolean Specifies whether or not to produce the flux map (generated over the full duration of the simulation). Default value is False. perturbation : string or None Optional perturbation language syntax to be appended to the Kappa file. See KaSim manual for more details. Default value is None (no perturbation). seed : integer A seed integer for KaSim random number generator. Set to None to allow KaSim to use a random seed (default) or supply a seed for deterministic behaviour (e.g. for testing) verbose : boolean Whether to pass the output of KaSim through to stdout/stderr. Returns ------- If flux_map is False, returns the kasim simulation data as a Numpy ndarray. Data is accessed using the syntax:: results[index_name] The index 'time' gives the time coordinates of the simulation. Data for the observables can be accessed by indexing the array with the names of the observables. Each entry in the ndarray has length points + 1, due to the inclusion of both the zero point and the final timepoint. If flux_map is True, returns an instance of SimulationResult, a namedtuple with two members, `timecourse` and `flux_map`. The `timecourse` field contains the simulation ndarray, and the `flux_map` field is an instance of a pygraphviz AGraph containing the flux map. The flux map can be rendered as a pdf using the dot layout program as follows:: fluxmap.draw('fluxmap.pdf', prog='dot') """ gen = KappaGenerator(model) if output_prefix is None: output_prefix = 'tmpKappa_%s_' % model.name base_directory = tempfile.mkdtemp(prefix=output_prefix, dir=output_dir) base_filename = os.path.join(base_directory, model.name) kappa_filename = base_filename + '.ka' fm_filename = base_filename + '_fm.dot' out_filename = base_filename + '.out' args = ['-i', kappa_filename, '-t', str(time), '-p', str(points), '-o', out_filename] if seed: args.extend(['-seed', str(seed)]) # Generate the Kappa model code from the PySB model and write it to # the Kappa file: with open(kappa_filename, 'w') as kappa_file: kappa_file.write(gen.get_content()) # If desired, add instructions to the kappa file to generate the # flux map: if flux_map: kappa_file.write('%%mod: [true] do $FLUX "%s" [true]\n' % fm_filename) # If any perturbation language code has been passed in, add it to # the Kappa file: if perturbation: kappa_file.write('\n%s\n' % perturbation) # Run KaSim kasim_path = _get_kappa_path('KaSim') p = subprocess.Popen([kasim_path] + args, stdout=subprocess.PIPE, stderr=subprocess.PIPE) if verbose: for line in iter(p.stdout.readline, b''): print('@@', line, end='') (p_out, p_err) = p.communicate() if p.returncode: raise KasimInterfaceError(p_out + '\n' + p_err) # The simulation data, as a numpy array data = _parse_kasim_outfile(out_filename) if flux_map: try: import pygraphviz flux_graph = pygraphviz.AGraph(fm_filename) except ImportError: if cleanup: raise RuntimeError( "Couldn't import pygraphviz, which is " "required to return the flux map as a " "pygraphviz AGraph object. Either install " "pygraphviz or set cleanup=False to retain " "dot files.") else: warnings.warn( "pygraphviz could not be imported so no AGraph " "object returned (returning None); flux map " "dot file available at %s" % fm_filename) flux_graph = None if cleanup: shutil.rmtree(base_directory) # If a flux map was generated, return both the simulation output and the # flux map as a pygraphviz graph if flux_map: return SimulationResult(data, flux_graph) # If no flux map was requested, return only the simulation data else: return data
def run(self, tspan=None, initials=None, param_values=None, n_runs=1, output_dir=None, output_file_basename=None, cleanup=None, **additional_args): """ Simulate a model using Kappa Parameters ---------- tspan: vector-like time span of simulation initials: vector-like, optional initial conditions of model param_values : vector-like or dictionary, optional Values to use for every parameter in the model. Ordering is determined by the order of model.parameters. If not specified, parameter values will be taken directly from model.parameters. n_runs: int number of simulations to run output_dir : string, optional Location for temporary files generated by Kappa. If None (the default), uses a temporary directory provided by the system. A temporary directory with a random name is created within the supplied location. output_file_basename : string, optional This argument is used as a prefix for the temporary Kappa output directory, rather than the individual files. cleanup : bool, optional If True (default), delete the temporary files after the simulation is finished. If False, leave them in place (Useful for debugging). The default value, None, means to use the value specified in :py:func:`__init__`. additional_args: kwargs, optional Additional arguments to pass to Kappa * seed : int, optional Random number seed for Kappa simulation * perturbation : string, optional Optional perturbation language syntax to be appended to the Kappa file. See KaSim manual for more details. Examples -------- >>> import numpy as np >>> from pysb.examples import michment >>> from pysb.simulator import KappaSimulator >>> sim = KappaSimulator(michment.model, tspan=np.linspace(0, 1)) >>> x = sim.run(n_runs=1) """ super(KappaSimulator, self).run(tspan=tspan, initials=initials, param_values=param_values, _run_kwargs=locals()) if cleanup is None: cleanup = self.cleanup tspan_lin_spaced = np.allclose( self.tspan, np.linspace(self.tspan[0], self.tspan[-1], len(self.tspan))) if not tspan_lin_spaced or self.tspan[0] != 0.0: raise SimulatorException('Kappa requires tspan to be linearly ' 'spaced starting at t=0') points = len(self.tspan) time = self.tspan[-1] plot_period = time / (len(self.tspan) - 1) if output_file_basename is None: output_file_basename = 'tmpKappa_%s_' % self.model.name base_directory = tempfile.mkdtemp(prefix=output_file_basename, dir=output_dir) base_filename = os.path.join(base_directory, self.model.name) kappa_filename_pattern = base_filename + '_{}.ka' out_filename_pattern = base_filename + '_{}_run{}.out' base_args = ['-u', 'time', '-l', str(time), '-p', '%.5f' % plot_period] if 'seed' in additional_args: seed = additional_args.pop('seed') base_args.extend(['-seed', str(seed)]) kasim_path = pf.get_path('kasim') n_param_sets = self.initials_length gen = KappaGenerator(self.model, _exclude_ic_param=True) file_data_base = gen.get_content() # Check if a perturbation has been set try: perturbation = additional_args.pop('perturbation') except KeyError: perturbation = None # Check no unknown arguments have been set if additional_args: raise ValueError('Unknown argument(s): {}'.format(', '.join( additional_args.keys()))) # Kappa column names, for sanity check kappa_col_names = tuple(['time'] + [o.name for o in self.model.observables]) tout = [] observable_traj = [] try: for pset_idx in range(n_param_sets): file_data = file_data_base + '' for param, param_value in zip(self.model.parameters, self.param_values[pset_idx]): file_data += "%var: '{}' {:e}\n".format( param.name, param_value) file_data += '\n' for cp, values in self.initials_dict.items(): file_data += "%init: {} {}\n".format( values[pset_idx], gen.format_complexpattern(cp)) # If any perturbation language code has been passed in, add it # to the Kappa file: if perturbation: file_data += '%s\n' % perturbation # Generate the Kappa model code from the PySB model and write # it to the Kappa file: kappa_filename = kappa_filename_pattern.format(pset_idx) with open(kappa_filename, 'w') as kappa_file: self._logger.debug('Kappa file contents:\n\n' + file_data) kappa_file.write(file_data) for sim_rpt in range(n_runs): # Run Kappa out_filename = out_filename_pattern.format( pset_idx, sim_rpt) args = [kasim_path] + base_args + [ '-i', kappa_filename, '-o', out_filename ] # Run KaSim self._logger.debug('Running: {}'.format(' '.join(args))) p = subprocess.Popen(args, stdout=subprocess.PIPE, stderr=subprocess.PIPE, cwd=base_directory) for line in p.stdout: self._logger.debug('@@' + line.decode('utf8')[:-1]) (p_out, p_err) = p.communicate() if p.returncode: raise KasimInterfaceError( p_out.decode('utf8') + '\n' + p_err.decode('utf8')) # The simulation data, as a numpy array data = _parse_kasim_outfile(out_filename) # Sanity check that observables are in correct order assert data.dtype.names == kappa_col_names data = data.view('<f8') # Handle case with single row output if data.ndim == 1: data.shape = (1, data.shape[0]) # Parse into format tout.append(data[:, 0]) observable_traj.append(data[:, 1:]) finally: if cleanup: shutil.rmtree(base_directory) return SimulationResult(self, tout=tout, observables_and_expressions=observable_traj, simulations_per_param_set=n_runs)
def run_kasim(model, time=10000, points=200, output_dir='.', cleanup=False, base_filename=None, dump_influence_map=False, perturbation=None): """Run KaSim on the given model with the provided arguments. Parameters ---------- model : pysb.core.Model The model to simulate/analyze using KaSim. time : number The amount of time (in arbitrary units) to run a simulation. Identical to the -t argument when using KaSim at the command line. Default value is 10000. If set to 0, no simulation will be run, but the influence map will be generated (if dump_influence_map is set to True). points : integer The number of data points to collect for plotting. Identical to the -p argument when using KaSim at the command line. Default value is 200. output_dir : string The subdirectory in which to generate the Kappa (.ka) file for the model and all output files produced by KaSim. Default value is '.' Note that only relative paths can be specified; paths are relative to the directory where the current Python instance is running. If the specified directory does not exist, an Exception is thrown. cleanup : boolean Specifies whether output files produced by KaSim should be deleted after execution is completed. Default value is False. base_filename : The base filename to be used for generation of the Kappa (.ka) file and all output files produced by KaSim. Defaults to a string of the form:: '%s_%d_%d_temp' % (model.name, program id, random.randint(0,10000)) The influence map filename appends '_im.dot' to this base filename; the flux map filename appends '_fm.dot'; and the simulation output file appends '.out' dump_influence_map : boolean Specifies whether or not to produce the influence map. Default value is False. perturbation : string or None Optional perturbation language syntax to be appended to the Kappa file. See KaSim manual for more details. Default value is None (no perturbation). Returns ------- A dict with three entries giving the filenames for the files produced: * output_dict['out'] gives the .out filename * output_dict['im'] gives the influence map filename * output_dict['fm'] gives the flux map filename """ gen = KappaGenerator(model) if not base_filename: base_filename = '%s/%s_%d_%d_temp' % ( output_dir, model.name, os.getpid(), random.randint(0, 10000)) kappa_filename = base_filename + '.ka' im_filename = base_filename + '_im.dot' fm_filename = base_filename + '_fm.dot' out_filename = base_filename + '.out' args = [ '-i', kappa_filename, '-t', str(time), '-p', str(points), '-o', out_filename ] try: kappa_file = open(kappa_filename, 'w') # Generate the Kappa model code from the PySB model and write it to # the Kappa file: kappa_file.write(gen.get_content()) # If desired, add instructions to the kappa file to generate the # influence map: if dump_influence_map: kappa_file.write('%def: "dumpInfluenceMap" "true"\n') kappa_file.write('%%def: "influenceMapFileName" "%s"\n\n' % im_filename) # If any perturbation language code has been passed in, add it to the # Kappa file: if perturbation: kappa_file.write('\n%s\n' % perturbation) kappa_file.close() print "Running kasim" p = subprocess.Popen(['KaSim'] + args) #stdout=subprocess.PIPE, stderr=subprocess.STDOUT) p.communicate() if p.returncode: raise Exception(p.stdout.read()) except Exception as e: raise Exception("Problem running KaSim: " + str(e)) finally: if cleanup: for filename in [ kappa_filename, im_filename, fm_filename, out_filename ]: if os.access(filename, os.F_OK): os.unlink(filename) output_dict = {'out': out_filename, 'im': im_filename, 'fm': 'flux.dot'} return output_dict
def run_static_analysis(model, influence_map=False, contact_map=False, cleanup=True, output_prefix=None, output_dir=None, verbose=False): """Run static analysis (KaSa) on to get the contact and influence maps. If neither influence_map nor contact_map are set to True, then a ValueError is raised. Parameters ---------- model : pysb.core.Model The model to simulate/analyze using KaSa. influence_map : boolean Whether to compute the influence map. contact_map : boolean Whether to compute the contact map. cleanup : boolean Specifies whether output files produced by KaSa should be deleted after execution is completed. Default value is True. output_prefix: str Prefix of the temporary directory name. Default is 'tmpKappa_<model name>_'. output_dir : string The directory in which to create the temporary directory for the .ka and other output files. Defaults to the system temporary file directory (e.g. /tmp). If the specified directory does not exist, an Exception is thrown. verbose : boolean Whether to pass the output of KaSa through to stdout/stderr. Returns ------- StaticAnalysisResult, a namedtuple with two fields, `contact_map` and `influence_map`, each containing the respective result as an instance of a networkx MultiGraph. If the either the contact_map or influence_map argument to the function is False, the corresponding entry in the StaticAnalysisResult returned by the function will be None. Notes ----- To view a networkx file graphically, use `draw_network`:: import networkx as nx nx.draw_networkx(g, with_labels=True) You can use `graphviz_layout` to use graphviz for layout (requires pydot library):: import networkx as nx pos = nx.drawing.nx_pydot.graphviz_layout(g, prog='dot') nx.draw_networkx(g, pos, with_labels=True) For further information, see the networkx documentation on visualization: https://networkx.github.io/documentation/latest/reference/drawing.html """ # Make sure the user has asked for an output! if not influence_map and not contact_map: raise ValueError('Either contact_map or influence_map (or both) must ' 'be set to True in order to perform static analysis.') gen = KappaGenerator(model, _warn_no_ic=False) if output_prefix is None: output_prefix = 'tmpKappa_%s_' % model.name base_directory = tempfile.mkdtemp(prefix=output_prefix, dir=output_dir) base_filename = os.path.join(base_directory, str(model.name)) kappa_filename = base_filename + '.ka' im_filename = base_filename + '_im.dot' cm_filename = base_filename + '_cm.dot' # NOTE: in the args passed to KaSa, the directory for the .dot files is # specified by the --output_directory option, and the output_contact_map # and output_influence_map should only be the base filenames (without # a directory prefix). # Contact map args: if contact_map: cm_args = ['--compute-contact-map', '--output-contact-map', os.path.basename(cm_filename), '--output-contact-map-directory', base_directory] else: cm_args = ['--no-compute-contact-map'] # Influence map args: if influence_map: im_args = ['--compute-influence-map', '--output-influence-map', os.path.basename(im_filename), '--output-influence-map-directory', base_directory] else: im_args = ['--no-compute-influence-map'] # Full arg list args = [kappa_filename] + cm_args + im_args # Generate the Kappa model code from the PySB model and write it to # the Kappa file: with open(kappa_filename, 'w') as kappa_file: file_data = gen.get_content() logger.debug('Kappa file contents:\n\n' + file_data) kappa_file.write(file_data) # Run KaSa using the given args kasa_path = pf.get_path('kasa') p = subprocess.Popen([kasa_path] + args, stdout=subprocess.PIPE, stderr=subprocess.PIPE, cwd=base_directory) if verbose: for line in iter(p.stdout.readline, b''): print('@@', line, end='') (p_out, p_err) = p.communicate() if p.returncode: raise KasaInterfaceError( p_out.decode('utf8') + '\n' + p_err.decode('utf8')) # Try to create the graphviz objects from the .dot files created try: # Convert the contact map to a Graph cmap = read_dot(cm_filename) if contact_map else None imap = read_dot(im_filename) if influence_map else None except ImportError: if cleanup: raise else: warnings.warn( "The pydot library could not be " "imported, so no MultiGraph " "object returned (returning None); " "contact/influence maps available at %s" % base_directory) cmap = None imap = None # Clean up the temp directory if desired if cleanup: shutil.rmtree(base_directory) return StaticAnalysisResult(cmap, imap)