def contrast_gist(request, uid, query=None, return_gist=False): '''contrast_gist is currently a sub for some "view_contrast" view (that should be defined as views.view_contrast, as a simple graph seems more appropriate to show a contrast and its conditions than some static thing we would render! :param uid: the uid for the contrast :param query: a custom query. If not defined, will show a table of concepts asserted. :param return_gist: if True, will return the context with all needed variables ''' contrast_cypher, lookup = Contrast.cypher(uid, return_lookup=True) contrast_cypher = add_cypher_relations(contrast_cypher, lookup) contrast = Contrast.get(uid)[0] if query is None: query = "MATCH (c:condition)-[r:HASCONTRAST]->(con:contrast) WHERE con.id='%s' RETURN c.name as condition_name,con.name as contrast_name;" % ( uid) # Join by newline contrast_cypher["links"] = "\n".join(contrast_cypher["links"]) contrast_cypher["nodes"] = "\n".join(contrast_cypher["nodes"]) context = { "relations": contrast_cypher["links"], "nodes": contrast_cypher["nodes"], "node_type": "contrast", "node_name": contrast["name"], "query": query } if return_gist is True: return context return render(request, 'graph/gist.html', context)
def test_add_task_concept(self): self.assertTrue( self.client.login(username=self.user.username, password=self.password)) task = Task() concept = Concept() contrast = Contrast() tsk = task.create('test_add_task_concept', {'prop': 'prop'}) con = concept.create('test_add_task_concept', {'prop': 'prop'}) cont = contrast.create('test_add_task_concept', {'prop': 'prop'}) concept.link(con.properties['id'], cont.properties['id'], "HASCONTRAST", endnode_type='contrast') response = self.client.post( reverse('add_task_concept', kwargs={'uid': tsk.properties['id']}), {'concept_selection': con.properties['id']}) self.assertEqual(response.status_code, 200) response = self.client.get( reverse('task', kwargs={'uid': tsk.properties['id']})) self.assertEqual(response.status_code, 200) self.assertEqual(len(response.context['task']['relations']['ASSERTS']), 1) self.assertEqual( response.context['task']['relations']['ASSERTS'][0]['id'], con.properties['id']) tsk.delete_related() con.delete_related() tsk.delete() con.delete() cont.delete()
def test_contrast_get_conditions(self): contrast = Contrast() conditions = contrast.get_conditions(self.cont.properties['id']) self.assertEqual(len(conditions), 1) self.assertEqual( conditions[0]['condition_id'], self.cond.properties['id'])
def contrast_gist(request,uid,query=None,return_gist=False): '''contrast_gist is currently a sub for some "view_contrast" view (that should be defined as views.view_contrast, as a simple graph seems more appropriate to show a contrast and its conditions than some static thing we would render! :param uid: the uid for the contrast :param query: a custom query. If not defined, will show a table of concepts asserted. :param return_gist: if True, will return the context with all needed variables ''' contrast_cypher,lookup = Contrast.cypher(uid,return_lookup=True) contrast_cypher = add_cypher_relations(contrast_cypher,lookup) contrast = Contrast.get(uid)[0] if query == None: query = "MATCH (c:condition)-[r:HASCONTRAST]->(con:contrast) WHERE con.id='%s' RETURN c.name as condition_name,con.name as contrast_name;" %(uid) # Join by newline contrast_cypher["links"] = "\n".join(contrast_cypher["links"]) contrast_cypher["nodes"] = "\n".join(contrast_cypher["nodes"]) context = {"relations":contrast_cypher["links"], "nodes":contrast_cypher["nodes"], "node_type":"contrast", "node_name":contrast["name"], "query":query} if return_gist == True: return context return render(request,'graph/gist.html',context)
def add_cypher_relations(cypher, lookup): '''add_cypher_relations will look up relations for connected nodes returned from an object. This is akin to adding one layer of the tree to the graph (and the function could be modified to add more) :param cypher: the cypher object, a dictionary with nodes and links as keys, each a list of them. ''' node_types = list(lookup) for node_type in node_types: for term in lookup[node_type]: if node_type == "condition": new_cypher, lookup = Condition.cypher(term, lookup=lookup, return_lookup=True) elif node_type == "task": new_cypher, lookup = Task.cypher(term, lookup=lookup, return_lookup=True) elif node_type == "contrast": new_cypher, lookup = Contrast.cypher(term, lookup=lookup, return_lookup=True) elif node_type == "concept": new_cypher, lookup = Concept.cypher(term, lookup=lookup, return_lookup=True) cypher = merge_cypher(cypher, new_cypher) return cypher
def add_contrast(request, task_id): '''add_contrast is the function called when the user submits a set of conditions and an operator to specify a new contrast. :param task_id: the id of the task, to return to the correct page after submission ''' if request.method == "POST": relation_type = "HASCONTRAST" #condition --HASCONTRAST-> contrast # Get fields from post post = dict(request.POST) #pickle.dump(post,open('result.pkl','wb')) contrast_name = post.get('contrast_name', '') skip = ["contrast_name", "csrfmiddlewaretoken"] # Get dictionary with new conditions with nonzero weights conditions = dict() condition_ids = [x for x in post.keys() if x not in skip] for condition_id in condition_ids: weight = int(post.get(condition_id, 0)[0]) if weight != 0: conditions[condition_id] = weight if contrast_name != "" and len(conditions) > 0: node = Contrast.create(name=contrast_name) # Make a link between contrast and conditions, specify side as property of relation for condition_id, weight in conditions.items(): properties = {"weight": weight} Condition.link(condition_id, node["id"], relation_type, endnode_type="contrast", properties=properties) return view_task(request, task_id)
def view_task(request, uid, return_context=False): task = Task.get(uid)[0] # Replace newlines with <br>, etc. task["definition"] = clean_html(task["definition"]) contrasts = Task.get_contrasts(task["id"]) # Make a lookup dictionary based on concept id concept_lookup = dict() for contrast in contrasts: contrast_concepts = Contrast.get_concepts(contrast["contrast_id"]) for concept in contrast_concepts: concept_lookup = update_lookup(concept_lookup, concept["concept_id"], contrast) # Retrieve conditions, make associations with contrasts conditions = Task.get_conditions(uid) context = { "task": task, "concepts": concept_lookup, "contrasts": contrasts, "conditions": conditions, "domain": DOMAIN } if return_context == True: return context return render(request, 'atlas/view_task.html', context)
def setUp(self): self.task = Task() self.node_name = "test_name" self.node_properties = {'test_key': 'test_value'} self.graph = Graph("http://graphdb:7474/db/data/") self.task1 = self.task.create( name=self.node_name, properties=self.node_properties) self.task2 = self.task.create( name=self.node_name, properties=self.node_properties) condition = Condition() self.cond = condition.create( name=self.node_name, properties=self.node_properties) contrast = Contrast() self.cont = contrast.create( name=self.node_name, properties=self.node_properties) concept = Concept() self.con = concept.create( name=self.node_name, properties=self.node_properties) self.task.link( self.task1.properties['id'], self.cond.properties['id'], "HASCONDITION", endnode_type='condition') self.task.link( self.task1.properties['id'], self.con.properties['id'], "ASSERTS", endnode_type='concept') condition.link( self.cond.properties['id'], self.cont.properties['id'], "HASCONTRAST", endnode_type='contrast') concept.link( self.con.properties['id'], self.cont.properties['id'], "MEASUREDBY", endnode_type='contrast')
def view_concept(request, uid): concept = Concept.get(uid)[0] # For each measured by (contrast), get the task if "MEASUREDBY" in concept["relations"]: for c in range(len(concept["relations"]["MEASUREDBY"])): contrast = concept["relations"]["MEASUREDBY"][c] tasks = Contrast.get_tasks(contrast["id"]) concept["relations"]["MEASUREDBY"][c]["tasks"] = tasks context = {"concept": concept} return render(request, 'atlas/view_concept.html', context)
def add_cypher_relations(cypher,lookup): '''add_cypher_relations will look up relations for connected nodes returned from an object. This is akin to adding one layer of the tree to the graph (and the function could be modified to add more) :param cypher: the cypher object, a dictionary with nodes and links as keys, each a list of them. ''' node_types = list(lookup) for node_type in node_types: for term in lookup[node_type]: if node_type == "condition": new_cypher,lookup = Condition.cypher(term,lookup=lookup,return_lookup=True) elif node_type == "task": new_cypher,lookup = Task.cypher(term,lookup=lookup,return_lookup=True) elif node_type == "contrast": new_cypher,lookup = Contrast.cypher(term,lookup=lookup,return_lookup=True) elif node_type == "concept": new_cypher,lookup = Concept.cypher(term,lookup=lookup,return_lookup=True) cypher = merge_cypher(cypher,new_cypher) return cypher
def test_contrast_get_tasks(self): contrast = Contrast() tasks = contrast.get_tasks(self.cont.properties['id']) self.assertEqual(len(tasks), 1) self.assertEqual(tasks[0]['task_id'], self.task1.properties['id'])
def test_contrast_get_concepts(self): contrast = Contrast() concepts = contrast.get_concepts(self.cont.properties['id']) self.assertEqual(len(concepts), 1) self.assertEqual(concepts[0]['concept_id'], self.con.properties['id'])
from django.http import HttpResponse, JsonResponse from django.shortcuts import render from django.template import loader, Context from cognitive.apps.atlas.query import Concept, Condition, Contrast, Task from cognitive.apps.atlas.utils import merge_cypher Task = Task() Concept = Concept() Condition = Condition() Contrast = Contrast() # Return full graph visualizations def graph_view(request, label, uid): query = "MATCH (n:{}) where n.id = '{}' OPTIONAL MATCH (n)-[]-(r) return n, r" query = query.format(label, uid) return render(request, "graph/graph.html", {'query': query}) def task_graph(request, uid): nodes = Task.get_graph(uid) context = {"graph": nodes} return render(request, "graph/task.html", context) def concept_graph(request, uid): nodes = Concept.get_graph(uid) context = {"graph": nodes} return render(request, "graph/task.html", context)
def all_contrasts(request): '''all_contrasts returns page with list of all contrasts''' contrasts = Contrast.all(order_by="name", fields=fields) return all_nodes(request, contrasts, "contasts")
from cognitive.apps.atlas.query import Concept, Task, Disorder, \ Contrast, Battery, Theory, Condition, search from cognitive.apps.atlas.utils import clean_html, update_lookup, add_update from django.http import JsonResponse, HttpResponse from cognitive.settings import DOMAIN from django.shortcuts import render from django.template import loader import pickle import json import numpy Concept = Concept() Task = Task() Disorder = Disorder() Contrast = Contrast() Battery = Battery() Theory = Theory() Condition = Condition() # Needed on all pages counts = { "disorders": Disorder.count(), "tasks": Task.count(), "contrasts": Contrast.count(), "concepts": Concept.count(), "batteries": Battery.count(), "theories": Theory.count() } # VIEWS FOR ALL NODES #############################################################