Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Interface object for catmaid_interface #2

Closed
wants to merge 3 commits into from
Closed
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
214 changes: 214 additions & 0 deletions catmaid_interface.py
Original file line number Diff line number Diff line change
Expand Up @@ -44,9 +44,185 @@ def get_catmaid_url( proj_opts, xyz, nodeid=None, skid=None, tool='tracingtool',
return '&'.join(strs)


class CatmaidAPI(object):
def __init__(self, baseurl, project_id, token, authname=None, authpass=None):
self.baseurl = baseurl
self.project_id = project_id
self.token = token
self.authname = authname
self.authpass = authpass

self.auth_token = catmaid_auth_token(self.token, self.authname, self.authpass)

@property
def proj_opts(self):
return {
'baseurl': self.baseurl,
'project_id': self.project_id,
'token': self.token,
'authname': self.authname,
'authpass': self.authpass
}

def __getitem__(self, key):
return self.proj_opts[key]

def __str__(self):
return json.dumps(self.proj_opts, sort_keys=True)

def get(self, relative_url, params=None, raw=False):
"""
Get data from a running instance of CATMAID.

Parameters
----------
relative_url : str
URL to send the request to, relative to the baseurl
params : dict or str
JSON-like key/value data to be included in the get URL
raw : bool
Whether to return the response as a string (defaults to returning a dict)

Returns
-------
dict or str
Data returned from CATMAID: type depends on the 'raw' parameter.
"""
url = requests.compat.urljoin(self.baseurl, relative_url)
response = requests.get(url, params=dict(params), auth=self.auth_token)
return response.json() if not raw else response.text

def post(self, relative_url, data=None, raw=False):
"""
Post data to a running instance of CATMAID.

Parameters
----------
relative_url : str
URL to send the request to, relative to the baseurl
params : dict or str
JSON-like key/value data to be included in the request as a payload
raw : bool
Whether to return the response as a string (defaults to returning a dict)

Returns
-------
dict or str
Data returned from CATMAID: type depends on the 'raw' parameter.
"""
url = requests.compat.urljoin(self.baseurl, relative_url)
response = requests.post(url, data=dict(data), auth=self.auth_token)
return response.json() if not raw else response.text

def fetch(self, relative_url, method='GET', data=None, raw=False):
"""
Interact with the CATMAID server in a manner very similar to the javascript CATMAID.fetch API.

Parameters
----------
relative_url : str
URL to send the request to, relative to the baseurl
method : str
'GET' or 'POST' (default 'GET')
data : dict or str
JSON-like key/value data to be included in the request as a payload
raw : bool
Whether to return the response as a string (defaults to returning a dict)

Returns
-------
dict or str
Data returned from CATMAID: type depends on the 'raw' parameter.
"""
return {'POST': self.post, 'GET': self.get}[method.upper()](relative_url, data, raw)

def get_catmaid_url(self, xyz, nodeid=None, skid=None, tool='tracingtool',zoomlevel=0):
return get_catmaid_url(self.proj_opts, xyz, nodeid, skid, tool, zoomlevel)

def get_neuron_name(self, skeleton_id):
"""
Given a skeleton ID, fetch the neuron name
"""
return get_neuron_name(skeleton_id, self.proj_opts)

def get_skeleton_json(self, skeleton_id, withtags=True):
"""
skeleton_object: Fetch full JSON info (plus a few other useful things) for a skeleton
sk[0] is the list of skeleton nodes
sk[1] is the list of connectors
sk[2] is tags
sk[3] is the skeleton id
sk[4] is the neuron name
sk[5] is the number of postsynaptic targets for each presynaptic connector
"""
return get_skeleton_json(skeleton_id, self.proj_opts, withtags)

def get_treenode_and_connector_geometry(self, skeleton_id):
"""
Return a dict of the same form as the JSON returned by the 'Treenode and connector geometry' option in the
export widget.

See CATMAID code for original js implementation:
http://github.com/catmaid/CATMAID/blob/master/django/applications/catmaid/static/js/widgets/export-widget.js#L449
"""
return get_treenode_and_connector_geometry(skeleton_id, self.proj_opts)

def get_connector_info(self, connector_id):
return get_connector_info(connector_id, self.proj_opts)

def add_annotation(self, annotation_list, id_list):
"""
Add a single annotation to a list of skeleton IDs.
"""
return add_annotation(annotation_list, id_list, self.proj_opts)

def get_ids_from_annotation(self, annotation_id_list):
"""
Given an annotation id, get all skeleton ids with that annotation
"""
return get_ids_from_annotation(annotation_id_list, self.proj_opts)

def get_ids_by_nodecount(self, min_nodes):
"""
Ids of all skeletons with more nodes than min_nodes
"""
return get_ids_by_nodecount(min_nodes, self.proj_opts)

def get_connected_skeleton_info(self, id_list):
"""
Get skeleton ids, nodes, and number of synapses connected upstream/downstream for a list of ids.
"""
return get_connected_skeleton_info(id_list, self.proj_opts)

def increase_id_list(self, id_list, min_pre=0, min_post=0, hops=1):
"""
Grow a list of skeleton ids along the connectivity network
"""
return increase_id_list(id_list, self.proj_opts, min_pre, min_post, hops)

def post_synaptic_count(self, connector_list):
"""
Count how many postsynaptic targets are associated with each connector in a list of connectors
"""
return post_synaptic_count(connector_list, self.proj_opts)

def write_skeletons_from_list(self, id_list):
"""
pull JSON files (plus key details) for
"""
return write_skeletons_from_list(id_list, self.proj_opts)

def get_connectivity_graph(self, id_list):
return get_connectivity_graph(id_list, self.proj_opts)

def get_skeleton_statistics(self, skid):
"""
Retrieve basic statistics about skeletons like number of synapses and total length
"""
return get_skeleton_statistics(skid, self.proj_opts)


# IN FUTURE, DEFINE API CALLS AS INSTANCE METHODS ON THE OBJECT; THE BELOW ARE FOR BACKWARDS COMPATIBILITY

# get_neuron_name: Given a skeleton ID, fetch the neuron name
def get_neuron_name( skeleton_id, proj_opts ):
Expand Down Expand Up @@ -79,6 +255,44 @@ def get_skeleton_json( skeleton_id, proj_opts, withtags = True):
d.append([])
return d

def get_treenode_and_connector_geometry(skeleton_id, proj_opts):
"""
See CATMAID code for original js implementation:
http://github.com/catmaid/CATMAID/blob/master/django/applications/catmaid/static/js/widgets/export-widget.js#L449
"""
url = proj_opts['baseurl'] + '/{}/{}/1/0/compact-skeleton'.format( proj_opts['project_id'], skeleton_id)
data = requests.get(
url, auth=catmaid_auth_token(proj_opts['token'], proj_opts['authname'], proj_opts['authpass'])
).json()

skeleton = {
'treenodes': dict(),
'connectors': dict()
}

for treenode in data[0]:
skeleton['treenodes'][treenode[0]] = {
'location': treenode[3:6],
'parent_id': treenode[1]
}

for connector in data[1]:
if connector[2] not in [0, 1]:
continue

conn_id = connector[1]
if conn_id not in skeleton['connectors']:
skeleton['connectors'][conn_id] = {
'presynaptic_to': [],
'postsynaptic_to': []
}

skeleton['connectors'][conn_id]['location'] = connector[3:6]
relation = 'postsynaptic_to' if connector[2] == 1 else 'presynaptic_to'
skeleton['connectors'][conn_id][relation].append(connector[0])

return skeleton

def get_connector_info( connector_id, proj_opts):
url = proj_opts['baseurl'] + '/{}/connectors/{}/'.format( proj_opts['project_id'], connector_id )
d = requests.get( url, auth = catmaid_auth_token( proj_opts['token'], proj_opts['authname'], proj_opts['authpass'] ) ).json()
Expand Down