# -*- coding: utf-8 -*-
"""Functions related to TOOLS found in the Tools Menu in Cytoscape.
"""
"""Copyright 2020-2022 The Cytoscape Consortium
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated
documentation files (the "Software"), to deal in the Software without restriction, including without limitation the
rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit
persons to whom the Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the
Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO
THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
"""
# External library imports
import sys
import time
# Internal module imports
from . import commands
from . import sandbox
# Internal module convenience imports
from .exceptions import CyError
from .py4cytoscape_utils import *
from .py4cytoscape_logger import cy_log
from .py4cytoscape_tuning import CATCHUP_NETWORK_MERGE_SECS
[docs]@cy_log
def analyze_network(directed=False, base_url=DEFAULT_BASE_URL):
"""Calculate various network statistics.
The results are added to the Node and Edge tables and the Results Panel.
The summary statistics in the Results Panel are also returned by the function
as a list of named values.
Args:
directed (bool): If True, the network is considered a directed graph. Default is False.
base_url (str): Ignore unless you need to specify a custom domain,
port or version to connect to the CyREST API. Default is http://127.0.0.1:1234
and the latest version of the CyREST API supported by this version of py4cytoscape.
Returns:
dict: Named list of summary statistics
Raises:
requests.exceptions.RequestException: if can't connect to Cytoscape or Cytoscape returns an error
Examples:
>>> analyze_network()
{'networkTitle': 'galFiltered.sif (undirected)', 'nodeCount': '330', 'edgeCount': '359', 'avNeighbors': '2.379032258064516', 'diameter': '27', 'radius': '14', 'avSpl': '9.127660963823953', 'cc': '0.06959203036053131', 'density': '0.009631709546819902', 'heterogeneity': '0.8534500004035027', 'centralization': '0.06375695335900727', 'ncc': '26'}
>>> analyze_network(True)
{'networkTitle': 'galFiltered.sif (directed)', 'nodeCount': '330', 'edgeCount': '359', 'avNeighbors': '2.16969696969697', 'diameter': '10', 'radius': '1', 'avSpl': '3.4919830756382395', 'cc': '0.03544266191325015', 'density': '0.003297411808050106', 'ncc': '26', 'mnp': '1', 'nsl': '0'}
"""
res = commands.commands_post(f'analyzer analyze directed={directed}', base_url=base_url)
return res
[docs]@cy_log
def cybrowser_close(id=None, base_url=DEFAULT_BASE_URL):
"""Cybrowser Close.
Close an internal web browser and remove all content. Provide an id for the browser you want to close.
Args:
id (str): The identifier for the browser window to close
base_url (str): Ignore unless you need to specify a custom domain,
port or version to connect to the CyREST API. Default is http://127.0.0.1:1234
and the latest version of the CyREST API supported by this version of py4cytoscape.
Returns:
dict: {}
Raises:
requests.exceptions.RequestException: if can't connect to Cytoscape or Cytoscape returns an error
Examples:
>>> cybrowser_close('CyGame')
{}
"""
id_str = f' id="{id}"' if id is not None else ''
res = commands.commands_post(f'cybrowser close{id_str}', base_url=base_url)
return res
[docs]@cy_log
def cybrowser_dialog(id=None, text=None, title=None, url=None, base_url=DEFAULT_BASE_URL):
"""Launch Cytoscape's internal web browser in a separate window
Provide an id for the window if you want subsequent control of the window e.g., via cybrowser hide.
Args:
id (str): The identifier for the new browser window
text (str): HTML text to initially load into the browser
title (str): Text to be shown in the title bar of the browser window
url (str): The URL the browser should load
base_url (str): Ignore unless you need to specify a custom domain,
port or version to connect to the CyREST API. Default is http://127.0.0.1:1234
and the latest version of the CyREST API supported by this version of py4cytoscape.
Returns:
dict: {'id': id} where ``id`` is the one provided as a parameter to this function
Raises:
requests.exceptions.RequestException: if can't connect to Cytoscape or Cytoscape returns an error
Examples:
>>> cybrowser_dialog(id='Test Window', title='Hello Africa', text='<HTML><HEAD><TITLE>Hello</TITLE></HEAD><BODY>Hello, world!</BODY></HTML>')
{'id': 'Test Window'}
>>> cybrowser_dialog(id='CytoWindow', title='Cytoscape Home Page', url='http://www.cytoscape.org')
{'id': 'CytoWindow'}
See Also:
:meth:`cybrowser_show`, :meth:`cybrowser_hide`
"""
id_str = f' id="{id}"' if id else ''
text_str = f' text="{text}"' if text else ''
title_str = f' title="{title}"' if title else ''
url_str = f' url="{url}"' if url else ''
res = commands.commands_post(f'cybrowser dialog{id_str}{text_str}{title_str}{url_str}', base_url=base_url)
return res
[docs]@cy_log
def cybrowser_hide(id=None, base_url=DEFAULT_BASE_URL):
"""Cybrowser Hide.
Hide an existing browser, whether it's in the Results panel or a separate window.
Args:
id (str): The identifier for the browser window to hide
base_url (str): Ignore unless you need to specify a custom domain,
port or version to connect to the CyREST API. Default is http://127.0.0.1:1234
and the latest version of the CyREST API supported by this version of py4cytoscape.
Returns:
dict: {}
Raises:
requests.exceptions.RequestException: if can't connect to Cytoscape or Cytoscape returns an error
Examples:
>>> cybrowser_hide('CyGame')
{}
See Also:
:meth:`cybrowser_show`, :meth:`cybrowser_dialog`
"""
id_str = f' id="{id}"' if id else ''
res = commands.commands_post(f'cybrowser hide{id_str}', base_url=base_url)
return res
[docs]@cy_log
def cybrowser_list(base_url=DEFAULT_BASE_URL):
"""Cybrowser List.
List all browsers that are currently open, whether as a dialog or in the results panel.
Args:
base_url (str): Ignore unless you need to specify a custom domain,
port or version to connect to the CyREST API. Default is http://127.0.0.1:1234
and the latest version of the CyREST API supported by this version of py4cytoscape.
Returns:
list: [{'id': id, 'title': title, 'url': current url}]
Raises:
requests.exceptions.RequestException: if can't connect to Cytoscape or Cytoscape returns an error
Examples:
>>> cybrowser_list()
[{'id': 'CytoManual ID', 'title': 'CytoManual Page', 'url': 'http://manual.cytoscape.org/en/stable/'}, {'id': ...} ...]
Note:
In the return value, there is a dict for each browser window,
and the ``id`` and ``title`` were provided in the ``cybrowser_show()`` call, and the ``url`` is for the page currently
loaded in the browser window
"""
res = commands.commands_post('cybrowser list', base_url=base_url)
return res
[docs]@cy_log
def cybrowser_send(id=None, script='', base_url=DEFAULT_BASE_URL):
"""Cybrowser Send.
Send the text to the browser indicated by the id and return the response, if any. Note that the JSON result
field could either be a bare string or JSON formatted text.
Args:
id (str): The identifier for the new browser window
script (str) A string that represents a JavaScript variable, script, or call to be executed in the browser.
Note that only string results are returned.
base_url (str): Ignore unless you need to specify a custom domain,
port or version to connect to the CyREST API. Default is http://127.0.0.1:1234
and the latest version of the CyREST API supported by this version of py4cytoscape.
Returns:
dict: {'browserId': id, 'result': result}
Raises:
CyError: if the browser could not execute the command
requests.exceptions.RequestException: if can't connect to Cytoscape or Cytoscape returns an error
Examples:
>>> cybrowser_send(id='Test Window', script='navigator.userAgent')
{'browserId': 'Test Window', 'result': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/608.1 (KHTML, like Gecko) JavaFX/13 Safari/608.1 CyBrowser/1.2.0'}
>>> cybrowser_send(id='CytoWindow', script="window.location='http://google.com'")
{'browserId': 'CytoWindow', 'result': 'http://google.com'}
Note:
In the return result, ``id`` is the one provided as a parameter to this function and
``result`` is the string returned as a result of executing the script
See Also:
:meth:`cybrowser_show`, :meth:`cybrowser_hide`, :meth:`cybrowser_dialog`
"""
id_str = f' id="{id}"' if id else ''
res = commands.commands_post(f'cybrowser send{id_str} script="{script}"', base_url=base_url)
return res
[docs]@cy_log
def cybrowser_show(id=None, text=None, title=None, url=None, base_url=DEFAULT_BASE_URL):
"""Cybrowser Show.
Launch Cytoscape's internal web browser in a pane in the Result Panel. Provide an id for the window
if you want subsequent control of the window via cybrowser hide.
Args:
id (str): The identifier for the new browser window
text (str): HTML text to initially load into the browser
title (str): Text to be shown in the title bar of the browser window
url (str): The URL the browser should load
base_url (str): Ignore unless you need to specify a custom domain,
port or version to connect to the CyREST API. Default is http://127.0.0.1:1234
and the latest version of the CyREST API supported by this version of py4cytoscape.
Returns:
dict: {'id': id} where ``id`` is the one provided as a parameter to this function
Raises:
requests.exceptions.RequestException: if can't connect to Cytoscape or Cytoscape returns an error
Examples:
>>> cybrowser_show(id='Test Window', title='Hello Africa', text='<HTML><HEAD><TITLE>Hello</TITLE></HEAD><BODY>Hello, world!</BODY></HTML>')
{'id': 'Test Window'}
>>> cybrowser_show(id='CytoWindow', title='Cytoscape Home Page', url='http://www.cytoscape.org')
{'id': 'CytoWindow'}
See Also:
:meth:`cybrowser_dialog`, :meth:`cybrowser_hide`
"""
id_str = f' id="{id}"' if id else ''
text_str = f' text="{text}"' if text else ''
title_str = f' title="{title}"' if title else ''
url_str = f' url="{url}"' if url else ''
res = commands.commands_post(f'cybrowser show{id_str}{text_str}{title_str}{url_str}', base_url=base_url)
return res
[docs]@cy_log
def cybrowser_version(base_url=DEFAULT_BASE_URL):
"""Display the version of the CyBrowser app.
Args:
base_url (str): Ignore unless you need to specify a custom domain,
port or version to connect to the CyREST API. Default is http://127.0.0.1:1234
and the latest version of the CyREST API supported by this version of py4cytoscape.
Returns:
dict: {'version': app version} where app version is the CyBrowser app version
Raises:
requests.exceptions.RequestException: if can't connect to Cytoscape or Cytoscape returns an error
Examples:
>>> cybrowser_version()
{'version': '1.2.0'}
"""
res = commands.commands_post('cybrowser version', base_url=base_url)
return res
[docs]@cy_log
def diffusion_basic(base_url=DEFAULT_BASE_URL):
"""Diffusion Basic.
Diffusion will send the selected network view and its selected nodes to a web-based REST service to calculate
network propagation. Results are returned and represented by columns in the node table.
Columns are created for each execution of Diffusion and their names are returned in the response. The nodes
you would like to use as input should be selected. This will be used to generate the contents of the
``diffusion_input`` column, which represents the query vector and corresponds to h in the diffusion equation.
Args:
base_url (str): Ignore unless you need to specify a custom domain,
port or version to connect to the CyREST API. Default is http://127.0.0.1:1234
and the latest version of the CyREST API supported by this version of py4cytoscape.
Returns:
dict: {'heatColumn': 'diffusion_output_heat', 'rankColumn': 'diffusion_output_rank'} where ``heatColumn`` is the name of the node table column containing each node's calculated heat and ``rankColumn`` is the name of the node table column containing the node's (0-based) rank
Raises:
requests.exceptions.RequestException: if can't connect to Cytoscape or Cytoscape returns an error
Examples:
>>> diffusion_basic()
{'heatColumn': 'diffusion_output_heat', 'rankColumn': 'diffusion_output_rank'}
"""
res = commands.commands_post('diffusion diffuse', base_url=base_url)
return res
[docs]@cy_log
def diffusion_advanced(heat_column_name=None, time=None, base_url=DEFAULT_BASE_URL):
"""Diffusion Advanced.
Diffusion will send the selected network view and its selected nodes to a web-based REST service to calculate
network propagation. Results are returned and represented by columns in the node table. Advanced operation supports
parameters.
Columns are created for each execution of Diffusion and their names are returned in the response. The nodes
you would like to use as input should be selected. This will be used to generate the contents of the
``diffusion_input`` column, which represents the query vector and corresponds to h in the diffusion equation.
Args:
heat_column_name (str): A node column name intended to override the default table column ``diffusion_input``.
This represents the query vector and corresponds to h in the diffusion equation.
time (str): The extent of spread over the network. This corresponds to t in the diffusion equation.
base_url (str): Ignore unless you need to specify a custom domain,
port or version to connect to the CyREST API. Default is http://127.0.0.1:1234
and the latest version of the CyREST API supported by this version of py4cytoscape.
Returns:
dict: {'heatColumn': 'diffusion_output_heat', 'rankColumn': 'diffusion_output_rank'} where ``heatColumn`` is the name of the node table column containing each node's calculated heat and ``rankColumn`` is the name of the node table column containing the node's (0-based) rank
Raises:
CyError: if an invalid parameter is passed
requests.exceptions.RequestException: if can't connect to Cytoscape or Cytoscape returns an error
Examples:
>>> diffusion_advanced(heat_column_name='diffusion_output_heat', time=0.1)
{'heatColumn': 'diffusion_output_1_heat', 'rankColumn': 'diffusion_output_1_rank'}
"""
heat_str = f' heatColumnName="{heat_column_name}"' if heat_column_name else ''
time_str = f' time="{time}"' if time else ''
res = commands.commands_post(f'diffusion diffuse_advanced{heat_str}{time_str}', base_url=base_url)
return res
[docs]@cy_log
def merge_networks(sources=None,
title=None,
operation="union",
node_keys=None,
node_merge_map=None,
nodes_only=False,
edge_keys=None,
edge_merge_map=None,
network_merge_map=None,
in_network_merge=True,
base_url=DEFAULT_BASE_URL):
"""Merge Networks.
Combine networks via union, intersection, or difference operations. Lots of optional parameters choose from!
Args:
sources (list): List of network names to be merged.
title (str): Title of the resulting merged network. Default is a concatentation of operation and source network titles.
operation (str): Type of merge: union (default), intersection or difference.
node_keys (list): An order-dependent list of columns to match nodes across source networks. Default is "name"
column for all sources.
node_merge_map (list): A list of column merge records specifying how to merge node table data. Each record should
be of the form: ["network1 column", "network2 column", "merged column", "type"], where column names are
provided and type is String, Integer, Double or List.
nodes_only (bool): If True, this will merge the node tables and ignore edge and network table data. Default is False.
edge_keys (list): An order-dependent list of columns to match edges across source networks. Default is "name"
column for all sources.
edge_merge_map (list): A list of column merge records specifying how to merge edge table data. Each record should
be of the form: ["network1 column", "network2 column", "merged column", "type"], where column names are
provided and type is String, Integer, Double or List.
network_merge_map (list): A list of column merge records specifying how to merge network table data. Each record
should be of the form: ["network1 column", "network2 column", "merged column", "type"], where column names
are provided and type is String, Integer, Double or List.
in_network_merge (bool) If True (default), nodes and edges with matching attributes in the same network will be
merged.
base_url (str): Ignore unless you need to specify a custom domain,
port or version to connect to the CyREST API. Default is http://127.0.0.1:1234
and the latest version of the CyREST API supported by this version of py4cytoscape.
Returns:
int: SUID of merged network
Raises:
CyError: if an invalid parameter is passed
requests.exceptions.RequestException: if can't connect to Cytoscape or Cytoscape returns an error
Examples:
>>> merge_networks(['Network_0', 'Network_1'])
366343
>>> merge_networks(['Network_0', 'Network_1'], title='nodes mapped')
366343
>>> merge_networks(['Network_0', 'Network_1'], node_merge_map=[['given name', 'first name', 'called', 'String'], ['score', 'age', 'score_m', 'Integer']], title='nodes mapped')
366343
"""
cmd_string = 'network merge' # a good start
# Sources must be supplied
if sources is None:
raise CyError('Missing sources!')
# Create mandatory args
cmd_string += f' sources="{",".join(sources)}" operation={operation} nodesOnly={nodes_only} inNetworkMerge={in_network_merge}'
# Add optional args
if not title is None:
cmd_string += f' netName="{title}"'
if not node_keys is None:
cmd_string += f' nodeKeys="{",".join(node_keys)}"'
if not edge_keys is None:
cmd_string += f' edgeKeys="{",".join(edge_keys)}"'
if not node_merge_map is None:
record_list = [f'{{{",".join(rec)}}}' for rec in node_merge_map]
cmd_string += f' nodeMergeMap="{",".join(record_list)}"'
if not edge_merge_map is None:
record_list = [f'{{{",".join(rec)}}}' for rec in edge_merge_map]
cmd_string += f' edgeMergeMap="{",".join(record_list)}"'
if not network_merge_map is None:
record_list = [f'{{{",".join(rec)}}}' for rec in network_merge_map]
cmd_string += f' networkMergeMap="{",".join(record_list)}"'
res = commands.commands_post(cmd_string, base_url=base_url)
# Wait for Cytoscape to finish adding __annotations column to Network table
time.sleep(CATCHUP_NETWORK_MERGE_SECS)
return res['SUID'] if 'SUID' in res else res
[docs]@cy_log
def import_file_from_url(source_url, dest_file, overwrite=True, base_url=DEFAULT_BASE_URL):
"""Transfer a cloud-based file to the current Cytoscape directory.
The source URL identifies a file to be transferred from a cloud resource to either the
to the current Cytoscape directory (if executing on the Cytoscape workstation) or sandbox (if
executing on a remote server or a sandbox was explicitly created). If the destination file already
exists, it is overwritten. The ``dest_file`` can be an absolute path if the workflow is
executing on the local Cytoscape workstation.
Supported URLs include:
**Raw URL**: URL directly references the file to download (e.g., http://tpsoft.com/museum_images/IBM%20PC.JPG
**Dropbox**: Use the standard Dropbox ``Get Link`` feature to create the ``source_url`` link in the clipboard (e.g., https://www.dropbox.com/s/r15azh0xb53smu1/GDS112_full.soft?dl=0)
**GDrive**: Use the standard Google Drive ``Get Link`` feature to create the ``source_url`` link in the clipboard (e.g., https://drive.google.com/file/d/12sJaKQQbesF10xsrbgiNtUcqCQYY1YI3/view?usp=sharing)
**OneDrive**: Use the OneDrive web site to right click on the file, choose the ``Embed`` menu option, then copy the URL in the iframe's ``src`` parameter into the clipboard (e.g., https://onedrive.live.com/embed?cid=C357475E90DD89C4&resid=C357475E90DD89C4%217207&authkey=ACEU5LrVtI_jWTU)
**GitHub**: Use the GitHub web site to show the file or a link to it, and capture the URL in the clipboard (e.g., https://github.com/cytoscape/file-transfer-app/blob/master/test_data/GDS112_full.soft)
Note that GitHub enforces a limit on the size of a file that can be stored there. We advise that you take this
into account when choosing a cloud service for your files.
When you capture a URL in the clipboard, you should copy it into your program for use with this function.
This function is most useful for Notebooks running on the local Cytoscape workstation. For Notebooks
that could run on a remote server, consider using sandbox_url_to() and related sandbox functions.
Args:
source_url (str): URL addressing cloud file to download
dest_file (str): Name of file to write (as Cytoscape-relative path, absolute file system path or sandbox-relative path)
overwrite (bool): False causes error if dest_file already exists; True replaces it if it exists
base_url (str): Ignore unless you need to specify a custom domain,
port or version to connect to the CyREST API. Default is http://localhost:1234
and the latest version of the CyREST API supported by this version of py4cytoscape.
Returns:
dict: {'filePath': <new file's absolute path in Cytoscape workstation>, 'fileByteCount': number of bytes read}
Raises:
CyError: if file name or URL is invalid
requests.exceptions.HTTPError: if can't connect to Cytoscape, Cytoscape returns an error, or sandbox is invalid
Examples:
>>> import_file_from_url('https://www.dropbox.com/s/r15azh0xb53smu1/GDS112_full.soft?dl=0', 'test file')
{'filePath': 'C:\\Users\\CyDeveloper\\CytoscapeConfiguration\\filetransfer\\default_sandbox\\test file', 'fileByteCount': 5536880}
>>> import_file_from_url('https://www.dropbox.com/s/r15azh0xb53smu1/GDS112_full.soft?dl=0', 'test file', overwrite=True)
{'filePath': 'C:\\Users\\CyDeveloper\\CytoscapeConfiguration\\filetransfer\\default_sandbox\\test file', 'fileByteCount': 5536880}
See Also:
`Sandboxing <https://py4cytoscape.readthedocs.io/en/latest/concepts.html#sandboxing>`_ in the Concepts section in the py4cytoscape User Manual.
"""
return sandbox.sandbox_url_to(source_url, dest_file, overwrite=overwrite, sandbox_name=None, base_url=base_url)