From da156bd8cf60e89b627ff966e62cd6c3afc338a2 Mon Sep 17 00:00:00 2001 From: Rob Court Date: Thu, 6 Aug 2020 12:01:54 +0100 Subject: [PATCH 01/27] testing post --- components/configuration/VFBToolbar/vfbtoolbarHTML.js | 1 + 1 file changed, 1 insertion(+) diff --git a/components/configuration/VFBToolbar/vfbtoolbarHTML.js b/components/configuration/VFBToolbar/vfbtoolbarHTML.js index 5e7cd675b..492d45bc2 100644 --- a/components/configuration/VFBToolbar/vfbtoolbarHTML.js +++ b/components/configuration/VFBToolbar/vfbtoolbarHTML.js @@ -13,6 +13,7 @@ var feedback + "[VirtualFlyBrain/VFB2].

" + "

If you have a GitHub account you can easily raise a new issue: " + "

" + + "" + "" + "
" + "

" From 9837e53406d1da6c2fae75c79b4591019082fe54 Mon Sep 17 00:00:00 2001 From: Rob Court Date: Thu, 6 Aug 2020 12:37:20 +0100 Subject: [PATCH 02/27] typo fix --- components/configuration/VFBToolbar/vfbtoolbarHTML.js | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/components/configuration/VFBToolbar/vfbtoolbarHTML.js b/components/configuration/VFBToolbar/vfbtoolbarHTML.js index 492d45bc2..310e7e3f0 100644 --- a/components/configuration/VFBToolbar/vfbtoolbarHTML.js +++ b/components/configuration/VFBToolbar/vfbtoolbarHTML.js @@ -12,9 +12,8 @@ var feedback + "you can engage directly with our developer community on GitHub " + "[VirtualFlyBrain/VFB2].

" + "

If you have a GitHub account you can easily raise a new issue: " - + "

" - + "" - + "" + + "" + + "" + "
" + "

" + "

This could simply be a question or a new feature request, but if you have found a bug we missed please copy in " From 63f9f68c696c26800a11ba87cad124f0ec62ab00 Mon Sep 17 00:00:00 2001 From: Rob Court Date: Fri, 7 Aug 2020 10:06:49 +0100 Subject: [PATCH 03/27] limiting typo fix --- .../VFBToolbar/vfbtoolbarHTML.js | 2 +- components/interface/VFBToolbar/VFBToolBar.js | 26 +++---------------- 2 files changed, 4 insertions(+), 24 deletions(-) diff --git a/components/configuration/VFBToolbar/vfbtoolbarHTML.js b/components/configuration/VFBToolbar/vfbtoolbarHTML.js index 310e7e3f0..a8e3c85b5 100644 --- a/components/configuration/VFBToolbar/vfbtoolbarHTML.js +++ b/components/configuration/VFBToolbar/vfbtoolbarHTML.js @@ -12,7 +12,7 @@ var feedback + "you can engage directly with our developer community on GitHub " + "[VirtualFlyBrain/VFB2].

" + "

If you have a GitHub account you can easily raise a new issue: " - + "

" + + "" + "" + "
" + "

" diff --git a/components/interface/VFBToolbar/VFBToolBar.js b/components/interface/VFBToolbar/VFBToolBar.js index 0fc0e9739..717d857f5 100644 --- a/components/interface/VFBToolbar/VFBToolBar.js +++ b/components/interface/VFBToolbar/VFBToolBar.js @@ -95,10 +95,6 @@ export default class VFBToolBar extends React.Component { clickFeedback () { var htmlContent = this.feedbackHTML; window.ga('vfb.send', 'pageview', (window.location.pathname + '?page=Feedback')); - // add clinet data to console - $.getJSON('http://gd.geobytes.com/GetCityDetails?callback=?', function (data) { - console.log('USER: ' + data.geobytesipaddress + ' ' + data.geobytesfqcn); - }); // report console log for agrigated analysis window.ga('vfb.send', 'feedback', window.location.href, window.console.logs.join('\n').replace(/\#/g,escape('#')), ); @@ -151,26 +147,10 @@ export default class VFBToolBar extends React.Component { } // return as much of the log up to the last 10 events < 1000 characters: var logLength = -50; - var limitedLog = window.console.logs.slice(logLength).join('%0A').replace( - /\&/g,escape('&') - ).replace( - /\#/g,escape('#') - ).replace( - /\-/g,'%2D' - ).replace( - /\+/g,'%2B' - ); - while (limitedLog.length > 1000 && logLength < 0) { + var limitedLog = window.console.logs.slice(logLength).join('/n'); + while (limitedLog.length < 1000 && logLength < 0) { logLength += 1; - limitedLog = window.console.logs.slice(logLength).join('%0A').replace( - /\&/g,escape('&') - ).replace( - /\#/g,escape('#') - ).replace( - /\-/g,'%2D' - ).replace( - /\+/g,'%2B' - ); + limitedLog = window.console.logs.slice(logLength).join('/n'); } this.props.htmlOutputHandler( htmlContent.replace( From 09e4b9619f56f94549ca83f7403d8184a35d6e90 Mon Sep 17 00:00:00 2001 From: Rob Court Date: Mon, 10 Aug 2020 18:36:27 +0100 Subject: [PATCH 04/27] Setting what/where queries Ref https://github.com/VirtualFlyBrain/geppetto-vfb/issues/648 --- .../VFBGraph/graphConfiguration.js | 59 +++++++------------ 1 file changed, 20 insertions(+), 39 deletions(-) diff --git a/components/configuration/VFBGraph/graphConfiguration.js b/components/configuration/VFBGraph/graphConfiguration.js index 9bd119bba..139df82a9 100644 --- a/components/configuration/VFBGraph/graphConfiguration.js +++ b/components/configuration/VFBGraph/graphConfiguration.js @@ -1,9 +1,21 @@ -var locationCypherQuery = instance => ({ +var whatIsCypherQuery = instance => ({ "statements": [ { - "statement": "MATCH p=(n:Entity)-[r:INSTANCEOF|part_of|has_synaptic_terminal_in|has_presynaptic_terminal_in" - + "has_postsynaptic_terminal_in|overlaps*..]->(x)" - + "WHERE n.short_form = '" + instance + "' return distinct n,r,x,n.short_form as root", + "statement": "MATCH p=(n:Entity)-[:INSTANCEOF|:SUBCLASSOF*..]->(x) " + + "WHERE n.short_form = '" + instance + "' " + + "AND 'Anatomy' IN labels(x) " + + "RETURN p, n.short_form as root", + "resultDataContents": ["graph"] + } + ] +}); + +var whereIsCypherQuery = instance => ({ + "statements": [ + { + "statement": "MATCH p=(Entity)-[:INSTANCEOF:part_of|has_synaptic_terminal_in|has_presynaptic_terminal_in|has_postsynaptic_terminal_in|overlaps*..]->(x) " + + "WHERE n.short_form = '" + instance + "' " + + "RETURN p, n.short_form as root", "resultDataContents": ["graph"] } ] @@ -55,43 +67,12 @@ var styling = { }, dropDownQueries : [ { - label : "Load Graph for 'fru-M-400042'", - query : () => ({ - "statements": [ - { - "statement": "MATCH p=(n:Entity)-[r:INSTANCEOF|part_of|has_synaptic_terminal_in|has_presynaptic_terminal_in" - + "has_postsynaptic_terminal_in|overlaps*..]->(x)" - + "WHERE n.short_form = 'VFB_00001567' return distinct n,r,x,n.short_form as root", - "resultDataContents": ["graph"] - } - ] - }) - }, - { - label : "Load Graph for 'adult brain template JFRC2'", - query : () => ({ - "statements": [ - { - "statement": "MATCH p=(n:Entity)-[r:INSTANCEOF|part_of|has_synaptic_terminal_in|has_presynaptic_terminal_in" - + "has_postsynaptic_terminal_in|overlaps*..]->(x)" - + "WHERE n.short_form = 'VFB_00017894' return distinct n,r,x,n.short_form as root", - "resultDataContents": ["graph"] - } - ] - }) + label : instance => "What is " + instance , + query : instance => whatIsCypherQuery(instance) }, { - label : "Load Graph for 'Medulla'", - query : () => ({ - "statements": [ - { - "statement": "MATCH p=(n:Entity)-[r:INSTANCEOF|part_of|has_synaptic_terminal_in|has_presynaptic_terminal_in" - + "has_postsynaptic_terminal_in|overlaps*..]->(x)" - + "WHERE n.short_form = 'VFB_00030624' return distinct n,r,x,n.short_form as root", - "resultDataContents": ["graph"] - } - ] - }) + label : instance => "Where is " + instance , + query : instance => whereIsCypherQuery(instance) } ], dropDownHoverBackgroundColor : "#11bffe", From caf1bca15282a1eafc0f4f726749c096b8e5f5cc Mon Sep 17 00:00:00 2001 From: Rob Court Date: Mon, 10 Aug 2020 19:09:44 +0100 Subject: [PATCH 05/27] typo fix --- components/configuration/VFBGraph/graphConfiguration.js | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/components/configuration/VFBGraph/graphConfiguration.js b/components/configuration/VFBGraph/graphConfiguration.js index 139df82a9..0b2dd288f 100644 --- a/components/configuration/VFBGraph/graphConfiguration.js +++ b/components/configuration/VFBGraph/graphConfiguration.js @@ -90,5 +90,6 @@ module.exports = { configuration, styling, restPostConfig, - locationCypherQuery + whatIsCypherQuery, + whereIsCypherQuery }; From 2a7851a83e3cbaef15ab6c187499cfeb38282795 Mon Sep 17 00:00:00 2001 From: Rob Court Date: Tue, 11 Aug 2020 10:51:30 +0100 Subject: [PATCH 06/27] spaces removed --- components/configuration/VFBGraph/graphConfiguration.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/components/configuration/VFBGraph/graphConfiguration.js b/components/configuration/VFBGraph/graphConfiguration.js index 0b2dd288f..7238dfd2d 100644 --- a/components/configuration/VFBGraph/graphConfiguration.js +++ b/components/configuration/VFBGraph/graphConfiguration.js @@ -4,7 +4,7 @@ var whatIsCypherQuery = instance => ({ "statement": "MATCH p=(n:Entity)-[:INSTANCEOF|:SUBCLASSOF*..]->(x) " + "WHERE n.short_form = '" + instance + "' " + "AND 'Anatomy' IN labels(x) " - + "RETURN p, n.short_form as root", + + "RETURN p, n.short_form as root", "resultDataContents": ["graph"] } ] @@ -15,7 +15,7 @@ var whereIsCypherQuery = instance => ({ { "statement": "MATCH p=(Entity)-[:INSTANCEOF:part_of|has_synaptic_terminal_in|has_presynaptic_terminal_in|has_postsynaptic_terminal_in|overlaps*..]->(x) " + "WHERE n.short_form = '" + instance + "' " - + "RETURN p, n.short_form as root", + + "RETURN p, n.short_form as root", "resultDataContents": ["graph"] } ] From 2d2309c99ebf0f2e299eed52ed44c378fc1e741a Mon Sep 17 00:00:00 2001 From: Rob Court Date: Thu, 13 Aug 2020 18:01:42 +0100 Subject: [PATCH 07/27] swapping to client branch feature/200_b --- Dockerfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Dockerfile b/Dockerfile index c86e242e7..d2e9d66a9 100644 --- a/Dockerfile +++ b/Dockerfile @@ -14,7 +14,7 @@ ARG geppettoSimulationRelease=vfb_20200604_a ARG geppettoDatasourceRelease=vfb_20200604_a ARG geppettoModelSwcRelease=v1.0.1 ARG geppettoFrontendRelease=vfb_20200604_a -ARG geppettoClientRelease=v2.4.0 +ARG geppettoClientRelease=feature/200_b ARG ukAcVfbGeppettoRelease=development ARG mvnOpt="-Dhttps.protocols=TLSv1.2 -DskipTests --quiet -Pmaster" From 01a676348cf547377354f6bc8edc33efc75668d3 Mon Sep 17 00:00:00 2001 From: Rob Court Date: Wed, 19 Aug 2020 18:25:17 +0100 Subject: [PATCH 08/27] moving yellow far out --- components/configuration/VFBMain/colours.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/components/configuration/VFBMain/colours.json b/components/configuration/VFBMain/colours.json index 287f5ed53..a16bf2ea5 100644 --- a/components/configuration/VFBMain/colours.json +++ b/components/configuration/VFBMain/colours.json @@ -3,7 +3,6 @@ "0x00ff00", "0xff00ff", "0x0000ff", - "0xffd300", "0x0084f6", "0x008d46", "0xa7613e", @@ -199,5 +198,6 @@ "0x8d35f6", "0x5800a7", "0xed8dff", + "0xffd300", "0x969696" ] From 9ad2d483c947dd57b7c3a186097da4e4ba8b7b1c Mon Sep 17 00:00:00 2001 From: Rob Court Date: Fri, 28 Aug 2020 18:06:12 +0100 Subject: [PATCH 09/27] swapping old cypher has() for exists() --- model/vfb.xmi | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/model/vfb.xmi b/model/vfb.xmi index 8dbb71010..50d05bf19 100644 --- a/model/vfb.xmi +++ b/model/vfb.xmi @@ -244,8 +244,8 @@ name="Find domain individuals for template id" description="Find domain individuals for template id" returnType="//@libraries.3/@types.0" - query=""statement": "MATCH (n:Template {short_form:{ID}})<-[:depicts]-(:Template)<-[r:in_register_with]-(dc:Individual)-[:depicts]->(di:Individual)-[:INSTANCEOF]->(d:Class) WHERE has(r.index) RETURN DISTINCT di.short_form as id, di.label as name, coalesce(di.description[0],d.description[0]) as def, COLLECT(DISTINCT d.label) as type, replace(r.folder,'http:','https:') + '/thumbnailT.png' as file", "parameters" : { "ID" : "$ID" }" - countQuery=""statement": "MATCH (n:Template {short_form:{ID}})<-[:depicts]-(:Template)<-[r:in_register_with]-(dc:Individual)-[:depicts]->(di:Individual)-[:INSTANCEOF]->(d:Class) WHERE has(r.index) RETURN count(di) as count", "parameters" : { "ID" : "$ID" }"/> + query=""statement": "MATCH (n:Template {short_form:{ID}})<-[:depicts]-(:Template)<-[r:in_register_with]-(dc:Individual)-[:depicts]->(di:Individual)-[:INSTANCEOF]->(d:Class) WHERE exists(r.index) RETURN DISTINCT di.short_form as id, di.label as name, coalesce(di.description[0],d.description[0]) as def, COLLECT(DISTINCT d.label) as type, replace(r.folder,'http:','https:') + '/thumbnailT.png' as file", "parameters" : { "ID" : "$ID" }" + countQuery=""statement": "MATCH (n:Template {short_form:{ID}})<-[:depicts]-(:Template)<-[r:in_register_with]-(dc:Individual)-[:depicts]->(di:Individual)-[:INSTANCEOF]->(d:Class) WHERE exists(r.index) RETURN count(di) as count", "parameters" : { "ID" : "$ID" }"/> + query=""statement": "MATCH (n:Template {short_form:{ID}})<-[:depicts]-(:Template)<-[r:in_register_with]-(dc:Individual)-[:depicts]->(di:Individual) WHERE not exists(r.index) OPTIONAL MATCH (di)-[:INSTANCEOF]->(d:Class) RETURN distinct di.short_form as id, di.label as name, coalesce(di.description[0],d.description[0]) as def, COLLECT(DISTINCT d.label) as type, replace(r.folder,'http:','https:') + '/thumbnailT.png' as file", "parameters" : { "ID" : "$ID" }" + countQuery=""statement": "MATCH (n:Template {short_form:{ID}})<-[:depicts]-(:Template)<-[r:in_register_with]-(dc:Individual)-[:depicts]->(di:Individual) WHERE not exists(r.index) RETURN count(di) as count", "parameters" : { "ID" : "$ID" }"/> From 2d65b5fcd5cc6d88f1728c08245c8cdb05922103 Mon Sep 17 00:00:00 2001 From: jrmartin Date: Wed, 23 Sep 2020 16:00:58 -0700 Subject: [PATCH 10/27] Make neurons appear in layers component --- .../controlsMenuConfiguration.js | 90 ++++++++++++---- .../VFBListViewer/ListViewerControlsMenu.js | 101 ++++++++++++++---- .../interface/VFBListViewer/VFBListViewer.js | 3 +- 3 files changed, 156 insertions(+), 38 deletions(-) diff --git a/components/configuration/VFBListViewer/controlsMenuConfiguration.js b/components/configuration/VFBListViewer/controlsMenuConfiguration.js index 6203e90fd..48a7f770b 100644 --- a/components/configuration/VFBListViewer/controlsMenuConfiguration.js +++ b/components/configuration/VFBListViewer/controlsMenuConfiguration.js @@ -1,5 +1,20 @@ import React from "react"; +var ACTIONS = { + COLOR : 'color', + INFO : 'info', + DELETE : 'delete', + SELECT : 'select', + DESELECT : 'deselect', + SHOW : 'hide', + HIDE : 'show', + ZOOM_TO : 'zoom_to', + SHOW_VOLUME : 'show_volume', + HIDE_VOLUME : 'hide_volume', + SHOW_SKELETON : 'show_skeleton', + HIDE_SKELETON : 'hide_skeleton', +}; + const controlsMenuConf = { itemOptions: { customArrow: }, // Global configuration for Menu buttons and drop down @@ -51,6 +66,7 @@ const controlsMenuConf = { } } }, + actions : ACTIONS, // Buttons to display inside the Menu buttons: [ { @@ -70,7 +86,7 @@ const controlsMenuConf = { { label: "Show Info", icon: "fa fa-info", - action: "info" + action: { handlerAction: ACTIONS.INFO } }, { toggle : { @@ -79,12 +95,12 @@ const controlsMenuConf = { false : { label: "Select", icon: "fa fa-check-circle-o", - action: entity => entity.select() + action: { handlerAction: ACTIONS.SELECT, } }, true : { label: "Unselect", icon: "fa fa-check-circle", - action: entity => entity.deselect() + action: { handlerAction: ACTIONS.DESELECT, } } } } @@ -96,12 +112,12 @@ const controlsMenuConf = { false : { label: "Show", icon: "fa fa-eye", - action: entity => entity.show() + action: { handlerAction: ACTIONS.SHOW, } }, true : { label: "Hide", icon: "fa fa-eye-slash", - action: entity => entity.hide() + action: { handlerAction: ACTIONS.HIDE, } } } } @@ -110,36 +126,72 @@ const controlsMenuConf = { label: "Delete", icon: "fa fa-trash", isVisible : entity => entity.getId() != window.templateID, - action: 'delete' + action: { handlerAction: ACTIONS.DELETE }, }, { label: "Zoom To", icon: "fa fa-search-plus", - action: entity => GEPPETTO.SceneController.zoomTo([entity]) + action: { handlerAction: ACTIONS.ZOOM_TO } }, { - label: "Show As", + label: "Show Volume", icon: "", - action: "", + action: {}, position: "right-start", list: [ { toggle : { - condition : entity => entity.isVisible(), + condition : entity => { + var visible = false; + if (entity.getType()[entity.getId() + "_obj"] != undefined && entity[entity.getId() + "_obj"] != undefined) { + visible = GEPPETTO.SceneController.isVisible([entity[entity.getId() + "_obj"]]); + } + return visible; + }, + isVisible : entity => entity.getType().hasVariable(entity.getId() + '_obj'), options : { false : { - label: "Show 3D Volume", + label: "Enable 3D Volume", icon: "gpt-shapeshow", - action: entity => { - entity.show() - } + action: { handlerAction: ACTIONS.SHOW_VOLUME } }, true : { - label: "Hide 3D Volume", + label: "Disable 3D Volume", icon: "gpt-shapehide", - action: entity => { - entity.hide() - } + action: { handlerAction: ACTIONS.HIDE_VOLUME } + } + } + } + }, + ] + }, + { + label: "Show Skeleton", + icon: "", + action: {}, + position: "right-start", + list: [ + { + toggle : { + condition : entity => { + var visible = false; + if (entity.getType()[entity.getId() + "_swc"] != undefined && entity.getType()[entity.getId() + "_swc"].getType().getMetaType() != GEPPETTO.Resources.IMPORT_TYPE && entity[entity.getId() + "_swc"] != undefined) { + visible = GEPPETTO.SceneController.isVisible([entity[entity.getId() + "_swc"]]); + } + return visible; + }, + isVisible : entity => entity.getType().hasVariable(entity.getId() + '_swc'), + options : { + false : { + label: "Enable 3D Skeleton", + icon: "gpt-3dhide", + tooltip : "Show 3D Skeleton", + action: { handlerAction: ACTIONS.SHOW_SKELETON } + }, + true : { + label: "Disable 3D Skeleton", + icon: "gpt-3dshow", + action: { handlerAction: ACTIONS.HIDE_SKELETON } } } } @@ -149,7 +201,7 @@ const controlsMenuConf = { { label: "Color", icon: "fa fa-tint", - action: 'color' + action: { handlerAction: ACTIONS.COLOR } }, ] } diff --git a/components/interface/VFBListViewer/ListViewerControlsMenu.js b/components/interface/VFBListViewer/ListViewerControlsMenu.js index 429ab9e38..88c12d399 100644 --- a/components/interface/VFBListViewer/ListViewerControlsMenu.js +++ b/components/interface/VFBListViewer/ListViewerControlsMenu.js @@ -1,14 +1,11 @@ import React, { Component } from "react"; import Menu from "@geppettoengine/geppetto-ui/menu/Menu"; import { connect } from 'react-redux'; -import controlsConfiguration from '../../configuration/VFBListViewer/controlsMenuConfiguration'; import { SliderPicker } from 'react-color'; import { setTermInfo, SHOW_LIST_VIEWER, INSTANCE_DELETED } from './../../../actions/generals'; -// Special control actions handled by the menu handler -const COLOR = 'color'; -const INFO = 'info'; -const DELETE = 'delete'; +const controlsConfiguration = require('../../configuration/VFBListViewer/controlsMenuConfiguration').default; +const ACTIONS = controlsConfiguration.actions; /** * Menu component to display controls for VFB List Viewer @@ -47,12 +44,28 @@ class ListViewerControlsMenu extends Component { * Handles menu option selection */ menuHandler (action, component) { - // If action belongs to color control, display the color picker - if ( action === COLOR ) { - this.setState({ displayColorPicker: true }); - } else if ( action === INFO ) { - // If action belongs to 'info' control, display term info - let self = this; + switch (action.handlerAction){ + case ACTIONS.SHOW: + this.props.instance.show(); + break; + case ACTIONS.HIDE: + this.props.instance.hide(); + break; + case ACTIONS.SELECT: + this.props.instance.select(); + break; + case ACTIONS.DESELECT: + this.props.instance.deselect(); + break; + case ACTIONS.ZOOM_TO: + GEPPETTO.SceneController.zoomTo([this.props.instance]); + break; + case ACTIONS.DELETE: + this.props.instance.delete(); + this.props.instanceDeleted(INSTANCE_DELETED, this.props.instance); + break; + case ACTIONS.INFO: + var self = this; /** * Needs a 100 ms delay before calling the setTermInfo method, this is due to Menu taking * a few ms to close. @@ -60,12 +73,56 @@ class ListViewerControlsMenu extends Component { setTimeout ( () => { self.props.setTermInfo(self.props.instance, true); }, 100); - } else if ( action === DELETE ) { - this.props.instance.delete(); - this.props.instanceDeleted(INSTANCE_DELETED, this.props.instance); - } else { - // For every other action execute the action as is - action(this.props.instance); + break; + case ACTIONS.COLOR: + this.setState({ displayColorPicker: true }); + break; + case ACTIONS.SHOW_VOLUME: + var color = this.props.instance.getColor(); + var instance = this.props.instance[this.props.instance.getId() + "_obj"]; + if ( instance === null || instance === undefined ){ + instance = this.props.instance; + } + if (instance.getType().getMetaType() == GEPPETTO.Resources.IMPORT_TYPE) { + var col = instance.getParent().getColor(); + instance.getType().resolve(function () { + instance.setColor(col); + GEPPETTO.trigger('experiment:visibility_changed', instance); + GEPPETTO.ControlPanel.refresh(); + }); + } else { + if (GEPPETTO.SceneController.isInstancePresent(instance)) { + GEPPETTO.SceneController.show([instance]); + } else { + GEPPETTO.SceneController.display(instance); instance.setColor(color); + } + } + break; + case ACTIONS.HIDE_VOLUME: + this.props.instance.hide(); + break; + case ACTIONS.SHOW_SKELETON: + var color = this.props.instance.getColor(); + var instance = this.props.instance[this.props.instance.getId() + "_swc"]; + if (instance.getType().getMetaType() == GEPPETTO.Resources.IMPORT_TYPE) { + var col = instance.getParent().getColor(); + instance.getType().resolve( function () { + instance.setColor(col); + GEPPETTO.trigger('experiment:visibility_changed', instance); + GEPPETTO.ControlPanel.refresh(); + }); + } else { + if (GEPPETTO.SceneController.isInstancePresent(instance)) { + GEPPETTO.SceneController.show([instance]); + } else { + GEPPETTO.SceneController.display(instance); + instance.setColor(color); + } + } + break; + case ACTIONS.HIDE_SKELETON: + GEPPETTO.SceneController.hide([this.props.instance[this.props.instance.getId() + "_swc"]]); + break; } } @@ -83,7 +140,14 @@ class ListViewerControlsMenu extends Component { // Button configuration has two options, perform condition to determine which button to use if ( item.toggle ){ let condition = item.toggle.condition(this.props.instance); - list.push(item.toggle.options[condition]); + if ( item.toggle.isVisible !== undefined) { + let visible = item.toggle.isVisible(this.props.instance); + if ( visible ) { + list.push(item.toggle.options[condition]); + } + } else { + list.push(item.toggle.options[condition]); + } } else { if ( item.isVisible !== undefined) { let visible = item.isVisible(this.props.instance); @@ -96,6 +160,7 @@ class ListViewerControlsMenu extends Component { } } + /** * Iterate through button list in Menu configuration */ diff --git a/components/interface/VFBListViewer/VFBListViewer.js b/components/interface/VFBListViewer/VFBListViewer.js index 35fc8f66d..0769db3c6 100644 --- a/components/interface/VFBListViewer/VFBListViewer.js +++ b/components/interface/VFBListViewer/VFBListViewer.js @@ -7,6 +7,7 @@ import { connect } from 'react-redux'; require('../../../css/VFBListViewer.less'); const VISUAL_TYPE = "VisualType"; +const COMPOSITE_VISUAL_TYPE = "CompositeVisualType"; /** * Wrapper class that connects geppetto-client's ListViewer component with VFB. @@ -42,7 +43,7 @@ class VFBListViewer extends Component { // Match Visual Types from ModelFactory for (var i = 0; i < entities.length; i++) { - if (entities[i].metaType === VISUAL_TYPE ) { + if (entities[i].metaType === VISUAL_TYPE || entities[i].metaType === COMPOSITE_VISUAL_TYPE ) { if (idsList.includes(entities[i].path.split(".")[0])){ visuals.push(entities[i]); } From 46542e6be50d41191f6a9af097fbe1972245b6e3 Mon Sep 17 00:00:00 2001 From: jrmartin Date: Thu, 24 Sep 2020 06:35:37 -0700 Subject: [PATCH 11/27] Fixing layers component --- .../VFBCircuitBrowser/VFBCircuitBrowser.js | 2 +- components/interface/VFBGraph/VFBGraph.js | 2 +- .../VFBListViewer/ListViewerControlsMenu.js | 14 +++++++++----- .../interface/VFBListViewer/VFBListViewer.js | 8 ++++---- 4 files changed, 15 insertions(+), 11 deletions(-) diff --git a/components/interface/VFBCircuitBrowser/VFBCircuitBrowser.js b/components/interface/VFBCircuitBrowser/VFBCircuitBrowser.js index 56de50645..4a148490a 100644 --- a/components/interface/VFBCircuitBrowser/VFBCircuitBrowser.js +++ b/components/interface/VFBCircuitBrowser/VFBCircuitBrowser.js @@ -234,7 +234,7 @@ class VFBCircuitBrowser extends Component { } } - resize(){ + resize (){ this.graphResized = true; this.setState( { reload : !this.state.reload } ); } diff --git a/components/interface/VFBGraph/VFBGraph.js b/components/interface/VFBGraph/VFBGraph.js index 6df87af9c..32bdce482 100644 --- a/components/interface/VFBGraph/VFBGraph.js +++ b/components/interface/VFBGraph/VFBGraph.js @@ -213,7 +213,7 @@ class VFBGraph extends Component { } } - resize(){ + resize (){ this.graphResized = true; this.setState( { reload : !this.state.reload } ); } diff --git a/components/interface/VFBListViewer/ListViewerControlsMenu.js b/components/interface/VFBListViewer/ListViewerControlsMenu.js index 88c12d399..44abe0df8 100644 --- a/components/interface/VFBListViewer/ListViewerControlsMenu.js +++ b/components/interface/VFBListViewer/ListViewerControlsMenu.js @@ -80,13 +80,13 @@ class ListViewerControlsMenu extends Component { case ACTIONS.SHOW_VOLUME: var color = this.props.instance.getColor(); var instance = this.props.instance[this.props.instance.getId() + "_obj"]; - if ( instance === null || instance === undefined ){ - instance = this.props.instance; + if ( instance === undefined ) { + instance = this.props.instance.getType()[this.props.instance.getId() + "_obj"]; } if (instance.getType().getMetaType() == GEPPETTO.Resources.IMPORT_TYPE) { - var col = instance.getParent().getColor(); + var self = this; instance.getType().resolve(function () { - instance.setColor(col); + self.props.instance.setColor(color); GEPPETTO.trigger('experiment:visibility_changed', instance); GEPPETTO.ControlPanel.refresh(); }); @@ -99,7 +99,11 @@ class ListViewerControlsMenu extends Component { } break; case ACTIONS.HIDE_VOLUME: - this.props.instance.hide(); + var instance = this.props.instance[this.props.instance.getId() + "_obj"]; + if ( instance === undefined ) { + instance = this.props.instance.getType()[this.props.instance.getId() + "_obj"]; + } + instance.hide(); break; case ACTIONS.SHOW_SKELETON: var color = this.props.instance.getColor(); diff --git a/components/interface/VFBListViewer/VFBListViewer.js b/components/interface/VFBListViewer/VFBListViewer.js index 0769db3c6..dd2ded1cc 100644 --- a/components/interface/VFBListViewer/VFBListViewer.js +++ b/components/interface/VFBListViewer/VFBListViewer.js @@ -37,19 +37,19 @@ class VFBListViewer extends Component { getInstances () { // Retrieve all instances from the ModelFactory let entities = GEPPETTO.ModelFactory.allPaths; - var visuals = []; + var visuals = {}; const { instanceDeleted, idsMap, idsList } = this.props; // Match Visual Types from ModelFactory for (var i = 0; i < entities.length; i++) { if (entities[i].metaType === VISUAL_TYPE || entities[i].metaType === COMPOSITE_VISUAL_TYPE ) { - if (idsList.includes(entities[i].path.split(".")[0])){ - visuals.push(entities[i]); + if (idsList.includes(entities[i].path.split(".")[0]) && visuals[entities[i].path] === undefined ){ + visuals[entities[i].path.split(".")[0]] = entities[i]; } } } - return visuals; + return Object.values(visuals); } render () { From 9606be6f57e0601b3137e2eeb5d1acb394bff772 Mon Sep 17 00:00:00 2001 From: jrmartin Date: Thu, 1 Oct 2020 09:11:42 -0700 Subject: [PATCH 12/27] Fixing circuit browser bugs when opening from term info --- .../interface/VFBCircuitBrowser/Controls.js | 26 +++++++++++--- .../VFBCircuitBrowser/VFBCircuitBrowser.js | 36 +++++++++++-------- 2 files changed, 44 insertions(+), 18 deletions(-) diff --git a/components/interface/VFBCircuitBrowser/Controls.js b/components/interface/VFBCircuitBrowser/Controls.js index f3dea2a64..80515e827 100644 --- a/components/interface/VFBCircuitBrowser/Controls.js +++ b/components/interface/VFBCircuitBrowser/Controls.js @@ -122,7 +122,7 @@ class Controls extends Component { this.state = { typingTimeout: 0, expanded : true, - neuronFields : this.props.neurons + neuronFields : ["", ""] }; this.addNeuron = this.addNeuron.bind(this); this.neuronTextfieldModified = this.neuronTextfieldModified.bind(this); @@ -132,10 +132,18 @@ class Controls extends Component { this.deleteNeuronField = this.deleteNeuronField.bind(this); this.getUpdatedNeuronFields = this.getUpdatedNeuronFields.bind(this); this.circuitQuerySelected = this.props.circuitQuerySelected; + this.initialValidation = false; } componentDidMount () { - this.setState( { expanded : !this.props.resultsAvailable() } ); + let neurons = [...this.props.neurons]; + this.setState( { expanded : !this.props.resultsAvailable(), neuronFields : neurons } ); + this.initialValidation = true; + this.circuitQuerySelected = this.props.circuitQuerySelected; + } + + componentDidUpdate () { + this.circuitQuerySelected = this.props.circuitQuerySelected; } /** @@ -146,6 +154,8 @@ class Controls extends Component { if ( event.target.id === "" ) { id = parseInt(event.target.parentElement.id); } + + this.circuitQuerySelected = ""; // remove neuron textfield let neurons = this.state.neuronFields; neurons.splice(id,1); @@ -153,7 +163,9 @@ class Controls extends Component { this.setState( { neuronFields : neurons } ); if ( this.fieldsValidated(neurons) ) { - this.props.queriesUpdated(neurons); + this.props.queriesUpdated(neurons, true); + } else { + this.props.queriesUpdated(neurons, false); } } @@ -176,7 +188,7 @@ class Controls extends Component { * Validates neurons ID's are valid, checks there's at least 8 numbers in it */ fieldsValidated (neurons) { - var pattern = /\d{8}/; + var pattern = /^[a-zA-Z0-9].*_[a-zA-Z0-9]{8}$/; for ( var i = 0 ; i < neurons.length ; i++ ){ if ( neurons[i] === "" ) { return false; @@ -195,6 +207,7 @@ class Controls extends Component { typingTimeout (target) { let neurons = this.state.neuronFields; neurons[target.id] = target.value; + this.circuitQuerySelected = ""; if ( this.fieldsValidated(neurons) ) { this.setState( { neuronFields : neurons } ); this.props.queriesUpdated(neurons); @@ -258,6 +271,11 @@ class Controls extends Component { } } + if ( this.fieldsValidated(neuronFields) ) { + this.props.queriesUpdated(neuronFields); + this.initialValidation = true; + } + return neuronFields; } diff --git a/components/interface/VFBCircuitBrowser/VFBCircuitBrowser.js b/components/interface/VFBCircuitBrowser/VFBCircuitBrowser.js index 56de50645..daa69e3d8 100644 --- a/components/interface/VFBCircuitBrowser/VFBCircuitBrowser.js +++ b/components/interface/VFBCircuitBrowser/VFBCircuitBrowser.js @@ -162,6 +162,7 @@ class VFBCircuitBrowser extends Component { graph : { nodes : [], links : [] } , legend : {}, loading : true, + queryLoaded : false, dropDownAnchorEl : null, neurons : ["", ""], hops : Math.ceil((configuration.maxHops - configuration.minHops) / 2), @@ -194,11 +195,15 @@ class VFBCircuitBrowser extends Component { let self = this; this.__isMounted = true; this.updateGraph(this.state.neurons , Math.ceil((configuration.maxHops - configuration.minHops) / 2)); + const { circuitQuerySelected } = this.props; + this.circuitQuerySelected = circuitQuerySelected; } componentDidUpdate () { let self = this; if ( this.props.visible && ( !this.focused || this.graphResized ) ) { + const { circuitQuerySelected } = this.props; + this.circuitQuerySelected = circuitQuerySelected; setTimeout( function () { self.resetCamera(); self.focused = true; @@ -216,8 +221,16 @@ class VFBCircuitBrowser extends Component { /** * New neurons have been entered by user, update graph */ - queriesUpdated (neurons) { - this.updateGraph(neurons, this.state.hops); + queriesUpdated (neurons, updateGraph) { + var is_same = (this.state.neurons.length == neurons.length) && this.state.neurons.every(function (element, index) { + return element === neurons[index]; + }); + + this.circuitQuerySelected = ""; + + if ( !this.state.loading && !is_same ) { + this.updateGraph(neurons, this.state.hops); + } } /** @@ -225,6 +238,7 @@ class VFBCircuitBrowser extends Component { */ updateHops (hops) { this.setState({ hops : hops }); + this.updateGraph(this.state.neurons, hops); } resetCamera () { @@ -234,7 +248,7 @@ class VFBCircuitBrowser extends Component { } } - resize(){ + resize (){ this.graphResized = true; this.setState( { reload : !this.state.reload } ); } @@ -270,8 +284,9 @@ class VFBCircuitBrowser extends Component { */ updateGraph (neurons, hops) { if (this.__isMounted){ + console.log("Graph updated", this.state.neurons); // Show loading spinner while cypher query search occurs - this.setState({ loading : true , neurons : neurons, hops : hops }); + this.setState({ loading : true , neurons : neurons, hops : hops, queryLoaded : false }); // Perform cypher query this.queryResults(cypherQuery(neurons.map(d => `'${d}'`).join(','), hops)); } @@ -308,7 +323,7 @@ class VFBCircuitBrowser extends Component { worker.onmessage = function (e) { switch (e.data.resultMessage) { case "OK": - self.setState( { graph : e.data.params.results , legend : e.data.params.colorLabels, loading : false }); + self.setState( { graph : e.data.params.results , legend : e.data.params.colorLabels, loading : false, queryLoaded : true }); self.objectsLoaded = e.data.params.results.nodes.length; setTimeout( function () { self.resetCamera(); @@ -353,16 +368,8 @@ class VFBCircuitBrowser extends Component { render () { let self = this; - const { classes } = this.props; - // Detect when the first load of the Graph component happens - if ( !this.state.loading && this.firstLoad ) { - // Reset CircuitQuerySelected value after first load - this.circuitQuerySelected = ""; - } - if ( !this.state.loading && !this.firstLoad ) { - this.firstLoad = true; - } + const { classes } = this.props; return ( this.state.loading @@ -441,6 +448,7 @@ class VFBCircuitBrowser extends Component { queriesUpdated={self.queriesUpdated} updateHops={self.updateHops} neurons={this.state.neurons} + queryLoaded={this.state.queryLoaded} hops={this.state.hops} resultsAvailable={ () => this.state.graph.nodes.length > 0 } resetCamera={self.resetCamera} From 32072297776a375ee703c099a32713beed2ab7e3 Mon Sep 17 00:00:00 2001 From: jrmartin Date: Thu, 1 Oct 2020 12:13:30 -0700 Subject: [PATCH 13/27] Cleaning code and fixes to circuit browser --- actions/generals.js | 4 ++-- .../interface/VFBCircuitBrowser/Controls.js | 23 +++++++++++++------ .../VFBCircuitBrowser/VFBCircuitBrowser.js | 16 ++++++++----- reducers/generals.js | 8 ++++++- 4 files changed, 35 insertions(+), 16 deletions(-) diff --git a/actions/generals.js b/actions/generals.js index d3ea7e1a2..93c7a86ec 100644 --- a/actions/generals.js +++ b/actions/generals.js @@ -7,7 +7,7 @@ export const INSTANCE_ADDED = 'INSTANCE_ADDED'; export const SHOW_GRAPH = 'SHOW_GRAPH'; export const UPDATE_GRAPH = 'UPDATE_GRAPH'; export const LOAD_CIRCUIT_BROWSER = 'LOAD_CIRCUIT_BROWSER'; -export const UPDATE_CIRCUIT_BROWSER = 'UPDATE_CIRCUIT_BROWSER'; +export const UPDATE_CIRCUIT_QUERY = 'UPDATE_CIRCUIT_QUERY'; export const INSTANCE_SELECTED = 'INSTANCE_SELECTION'; export const INSTANCE_DELETED = 'INSTANCE_DELETED'; export const INSTANCE_VISIBILITY_CHANGED = 'INSTANCE_VISIBILITY_CHANGED'; @@ -40,7 +40,7 @@ export const vfbGraph = (type, instance, queryIndex) => ({ }); export const vfbCircuitBrowser = (type, instance) => ({ - type: LOAD_CIRCUIT_BROWSER, + type: type, data: { instance : instance } }); diff --git a/components/interface/VFBCircuitBrowser/Controls.js b/components/interface/VFBCircuitBrowser/Controls.js index 80515e827..6b915c8b9 100644 --- a/components/interface/VFBCircuitBrowser/Controls.js +++ b/components/interface/VFBCircuitBrowser/Controls.js @@ -22,6 +22,8 @@ import IconButton from '@material-ui/core/IconButton'; import DeleteIcon from '@material-ui/icons/Delete'; import ExpandMoreIcon from '@material-ui/icons/ExpandMore'; import { createMuiTheme, ThemeProvider } from '@material-ui/core/styles'; +import { connect } from "react-redux"; +import { UPDATE_CIRCUIT_QUERY } from './../../../actions/generals'; /** * Create a local theme to override some default values in material-ui components @@ -132,13 +134,11 @@ class Controls extends Component { this.deleteNeuronField = this.deleteNeuronField.bind(this); this.getUpdatedNeuronFields = this.getUpdatedNeuronFields.bind(this); this.circuitQuerySelected = this.props.circuitQuerySelected; - this.initialValidation = false; } componentDidMount () { let neurons = [...this.props.neurons]; this.setState( { expanded : !this.props.resultsAvailable(), neuronFields : neurons } ); - this.initialValidation = true; this.circuitQuerySelected = this.props.circuitQuerySelected; } @@ -155,17 +155,19 @@ class Controls extends Component { id = parseInt(event.target.parentElement.id); } + // Update circuit selection this.circuitQuerySelected = ""; + this.props.vfbCircuitBrowser(UPDATE_CIRCUIT_QUERY, null); + // remove neuron textfield let neurons = this.state.neuronFields; neurons.splice(id,1); // Update state with one less neuron textfield this.setState( { neuronFields : neurons } ); + // If neuron fields are validated, let the VFBCircuitBrowser component know, it will do a graph update if ( this.fieldsValidated(neurons) ) { - this.props.queriesUpdated(neurons, true); - } else { - this.props.queriesUpdated(neurons, false); + this.props.queriesUpdated(neurons); } } @@ -273,7 +275,6 @@ class Controls extends Component { if ( this.fieldsValidated(neuronFields) ) { this.props.queriesUpdated(neuronFields); - this.initialValidation = true; } return neuronFields; @@ -408,4 +409,12 @@ class Controls extends Component { Controls.propTypes = { classes: PropTypes.object.isRequired }; -export default withStyles(styles)(Controls); +function mapStateToProps (state) { + return { ...state } +} + +function mapDispatchToProps (dispatch) { + return { vfbCircuitBrowser: (type, path) => dispatch ( { type : type, data : { instance : path } }), } +} + +export default connect(mapStateToProps, mapDispatchToProps, null, { forwardRef : true } )(withStyles(styles)(Controls)); diff --git a/components/interface/VFBCircuitBrowser/VFBCircuitBrowser.js b/components/interface/VFBCircuitBrowser/VFBCircuitBrowser.js index daa69e3d8..28157a378 100644 --- a/components/interface/VFBCircuitBrowser/VFBCircuitBrowser.js +++ b/components/interface/VFBCircuitBrowser/VFBCircuitBrowser.js @@ -189,6 +189,7 @@ class VFBCircuitBrowser extends Component { // Circuit Browser component has been resized this.graphResized = false; this.circuitQuerySelected = this.props.circuitQuerySelected; + this.lastSelectedQuery = this.cir } componentDidMount () { @@ -202,8 +203,6 @@ class VFBCircuitBrowser extends Component { componentDidUpdate () { let self = this; if ( this.props.visible && ( !this.focused || this.graphResized ) ) { - const { circuitQuerySelected } = this.props; - this.circuitQuerySelected = circuitQuerySelected; setTimeout( function () { self.resetCamera(); self.focused = true; @@ -212,6 +211,10 @@ class VFBCircuitBrowser extends Component { } else if ( !this.props.visible ) { this.focused = false; } + + if ( this.circuitQuerySelected !== this.props.circuitQuerySelected ) { + this.circuitQuerySelected = this.props.circuitQuerySelected; + } } componentWillUnmount () { @@ -219,15 +222,16 @@ class VFBCircuitBrowser extends Component { } /** - * New neurons have been entered by user, update graph + * New neurons have been entered by user, update graph. + * @neurons (array): New list of neurons user has entered */ - queriesUpdated (neurons, updateGraph) { + queriesUpdated (neurons) { + // Check if new list of neurons is the same as the ones already rendered on last update var is_same = (this.state.neurons.length == neurons.length) && this.state.neurons.every(function (element, index) { return element === neurons[index]; }); - - this.circuitQuerySelected = ""; + // Request graph update if the list of new neurons is not the same if ( !this.state.loading && !is_same ) { this.updateGraph(neurons, this.state.hops); } diff --git a/reducers/generals.js b/reducers/generals.js index 50350b189..c4449e6d5 100644 --- a/reducers/generals.js +++ b/reducers/generals.js @@ -9,6 +9,7 @@ import { LOAD_CYPHER_QUERIES, SHOW_GRAPH, LOAD_CIRCUIT_BROWSER, + UPDATE_CIRCUIT_QUERY, INSTANCE_SELECTED, INSTANCE_VISIBILITY_CHANGED, VFB_LOAD_TERM_INFO @@ -212,9 +213,14 @@ function generalReducer (state, action) { case LOAD_CIRCUIT_BROWSER: return { ...state, - circuitQuerySelected : action.data.instance, + circuitQuerySelected : action.data.instance != null ? action.data.instance : {}, circuitBrowserSelected : true }; + case UPDATE_CIRCUIT_QUERY: + return { + ...state, + circuitQuerySelected : action.data.instance != null ? action.data.instance : {} + }; case INSTANCE_ADDED: var newMap = { ...state.idsMap }; var newInstance = action.data.split("."); From 39225abf35f0f929358d838c2d81013c1ff966ce Mon Sep 17 00:00:00 2001 From: jrmartin Date: Fri, 2 Oct 2020 12:55:07 -0700 Subject: [PATCH 14/27] Fix bugs in Term Context --- components/interface/VFBGraph/VFBGraph.js | 56 +++++++++++++---------- 1 file changed, 31 insertions(+), 25 deletions(-) diff --git a/components/interface/VFBGraph/VFBGraph.js b/components/interface/VFBGraph/VFBGraph.js index 6df87af9c..05f7e6a6a 100644 --- a/components/interface/VFBGraph/VFBGraph.js +++ b/components/interface/VFBGraph/VFBGraph.js @@ -115,7 +115,7 @@ function refineData (e) { }); // Worker is done, notify main thread - this.postMessage({ resultMessage: "OK", params: { results: { nodes, links } } }); + this.postMessage({ resultMessage: "OK", params: { results: { nodes, links }, id : e.data.params.value } }); } class VFBGraph extends Component { @@ -124,8 +124,7 @@ class VFBGraph extends Component { super(props); this.state = { graph : { nodes : [], links : [] }, - loading : true, - currentQuery : this.props.instance.id, + currentQuery : this.props.instance != null ? this.props.instance.id : "", dropDownAnchorEl : null, optionsIconColor : stylingConfiguration.defaultRefreshIconColor, nodeSelected : { title : "", id : "" }, @@ -157,6 +156,7 @@ class VFBGraph extends Component { this.graphResized = false; this.focusedInstance = { id : "" }; this.selectedDropDownQuery = -1; + this.loading = true; } componentDidMount () { @@ -191,6 +191,20 @@ class VFBGraph extends Component { let self = this; // Reset camera if graph component is visible, not focused or has been resized if ( this.props.visible && ( !this.focused || this.graphResized ) ) { + /* + * Update graph with selected query index from configuration dropdown selection, this is to allow to lauch the component to be launched + * with specific configuration dropdown query. + */ + stylingConfiguration.dropDownQueries.map((item, index) => { + if ( self.selectedDropDownQuery === -1 || self.selectedDropDownQuery !== parseInt(self.props.graphQueryIndex) ) { + if ( parseInt(self.props.graphQueryIndex) === index ) { + self.selectedDropDownQuery = index; + self.loading = true; + self.queryResults(item.query(self.props.instanceOnFocus.id), self.props.instanceOnFocus.id); + } + } + }); + // Reset camera view after graph component becomes visible setTimeout( function () { self.resetCamera(); self.focused = true; @@ -213,7 +227,7 @@ class VFBGraph extends Component { } } - resize(){ + resize (){ this.graphResized = true; this.setState( { reload : !this.state.reload } ); } @@ -257,9 +271,10 @@ class VFBGraph extends Component { handleMenuClick (query) { if (this.__isMounted){ // Show loading spinner while cypher query search occurs - this.setState({ loading : true , dropDownAnchorEl : null }); + this.loading = true; + this.setState({ dropDownAnchorEl : null }); // Perform cypher query - this.queryResults(query(this.state.currentQuery)) + this.queryResults(query(this.state.currentQuery), this.state.currentQuery) } } @@ -268,7 +283,8 @@ class VFBGraph extends Component { */ queryNewInstance (node) { window.addVfbId(node.title); - this.setState({ loading : true, nodeSelected : node, currentQuery : node.title, optionsIconColor : stylingConfiguration.defaultRefreshIconColor }); + this.loading = true; + this.setState({ nodeSelected : node, optionsIconColor : stylingConfiguration.defaultRefreshIconColor }); // Perform cypher query this.queryResults(cypherQuery(node.title), node.title) } @@ -320,7 +336,8 @@ class VFBGraph extends Component { if (this.__isMounted){ // Show loading spinner while cypher query search occurs - this.setState({ loading : true, currentQuery : idToSearch, optionsIconColor : stylingConfiguration.defaultRefreshIconColor }); + this.loading = true; + this.setState({ optionsIconColor : stylingConfiguration.defaultRefreshIconColor }); // Perform cypher query this.queryResults(cypherQuery(idToSearch), idToSearch); } @@ -357,7 +374,8 @@ class VFBGraph extends Component { worker.onmessage = function (e) { switch (e.data.resultMessage) { case "OK": - self.setState( { graph : e.data.params.results , loading : false }); + self.loading = false; + self.setState( { graph : e.data.params.results, currentQuery : e.data.params.id }); self.objectsLoaded = e.data.params.results.nodes.length; setTimeout( function () { self.resetCamera(); @@ -373,7 +391,6 @@ class VFBGraph extends Component { worker.postMessage({ message: "refine", params: { results: response.data, value: instanceID, configuration : configuration, NODE_WIDTH : NODE_WIDTH, NODE_HEIGHT : NODE_HEIGHT } }); }) .catch( function (error) { - self.setState( { loading : false } ); }) } @@ -404,9 +421,8 @@ class VFBGraph extends Component { const { instanceOnFocus, graphQueryIndex } = this.props; let syncColor = this.state.optionsIconColor; - let loading = this.state.loading; - if ( this.focusedInstance.id !== "" && instanceOnFocus !== this.focusedInstance.id ) { + if ( this.focusedInstance.id !== "" && !instanceOnFocus.id.includes(this.focusedInstance.id) ) { this.instanceFocusChange(instanceOnFocus); if ( this.state.graph.nodes.length === 0 && this.state.graph.links.length === 0 && this.focusedInstance.id !== this.state.currentQuery ){ @@ -418,29 +434,19 @@ class VFBGraph extends Component { } syncColor = stylingConfiguration.defaultRefreshIconColor; // Perform cypher query - loading = true; + this.loading = true; this.queryResults(cypherQuery(idToSearch), idToSearch) } if ( this.focusedInstance.id !== this.state.currentQuery ) { syncColor = stylingConfiguration.outOfSyncIconColor; } - } else if (this.focusedInstance.id !== "" && instanceOnFocus === this.focusedInstance.id ){ - stylingConfiguration.dropDownQueries.map((item, index) => { - if ( self.selectedDropDownQuery === -1 || self.selectedDropDownQuery !== parseInt(graphQueryIndex) ) { - if ( parseInt(graphQueryIndex) === index ) { - self.selectedDropDownQuery = index; - loading = true; - self.queryResults(item.query(instanceOnFocus)); - } - } - }) } - if ( !instanceOnFocus.id.includes(this.focusedInstance.id) ) { + if ( !this.state.currentQuery.includes(this.focusedInstance.id) ) { syncColor = stylingConfiguration.outOfSyncIconColor; } return ( - loading + this.loading ? Date: Fri, 2 Oct 2020 15:06:31 -0700 Subject: [PATCH 15/27] Fixing graph component bugs --- components/interface/VFBGraph/VFBGraph.js | 34 +++++++++++++---------- 1 file changed, 19 insertions(+), 15 deletions(-) diff --git a/components/interface/VFBGraph/VFBGraph.js b/components/interface/VFBGraph/VFBGraph.js index 05f7e6a6a..7a295215a 100644 --- a/components/interface/VFBGraph/VFBGraph.js +++ b/components/interface/VFBGraph/VFBGraph.js @@ -163,11 +163,13 @@ class VFBGraph extends Component { let self = this; this.__isMounted = true; - if (this.state.currentQuery !== undefined && this.state.currentQuery !== null){ - if (this.props.instance.getParent() !== null) { - this.focusedInstance = this.props.instance.getParent(); - } else { - this.focusedInstance = this.props.instance; + if (this.state.currentQuery !== undefined && this.state.currentQuery !== "" && this.state.currentQuery !== null){ + if ( this.props.instance != null ) { + if (this.props.instance.getParent() !== null) { + this.focusedInstance = this.props.instance.getParent(); + } else { + this.focusedInstance = this.props.instance; + } } this.updateGraph(); @@ -200,7 +202,11 @@ class VFBGraph extends Component { if ( parseInt(self.props.graphQueryIndex) === index ) { self.selectedDropDownQuery = index; self.loading = true; - self.queryResults(item.query(self.props.instanceOnFocus.id), self.props.instanceOnFocus.id); + let idToSearch = self.props.instanceOnFocus.id; + if (self.props.instanceOnFocus.getParent() !== null) { + idToSearch = self.props.instanceOnFocus.getParent().id; + } + self.queryResults(item.query(idToSearch), idToSearch); } } }); @@ -208,10 +214,12 @@ class VFBGraph extends Component { setTimeout( function () { self.resetCamera(); self.focused = true; + self.loading = false; self.graphResized = false; }, (self.objectsLoaded * 20)); } else if ( !this.props.visible ) { this.focused = false; + this.loading = true; this.selectedDropDownQuery = -1; } } @@ -290,11 +298,9 @@ class VFBGraph extends Component { } selectedNodeLoaded (instance) { - var loadedId = null; + var loadedId = instance.id; if (instance.getParent() !== null) { loadedId = instance.getParent().id; - } else { - loadedId = instance.id; } if ( this.state.nodeSselected ) { @@ -323,15 +329,13 @@ class VFBGraph extends Component { * Re-render graph with a new instance */ updateGraph () { - var idToSearch = null; + var idToSearch = this.focusedInstance.id; /* * function handler called by the VFBMain whenever there is an update of the instance on focus, * this will reflect and move to the node (if it exists) that we have on focus. */ if (this.focusedInstance.getParent() !== null) { idToSearch = this.focusedInstance.getParent().id; - } else { - idToSearch = this.focusedInstance.id; } if (this.__isMounted){ @@ -391,6 +395,7 @@ class VFBGraph extends Component { worker.postMessage({ message: "refine", params: { results: response.data, value: instanceID, configuration : configuration, NODE_WIDTH : NODE_WIDTH, NODE_HEIGHT : NODE_HEIGHT } }); }) .catch( function (error) { + self.loading = false; }) } @@ -426,12 +431,11 @@ class VFBGraph extends Component { this.instanceFocusChange(instanceOnFocus); if ( this.state.graph.nodes.length === 0 && this.state.graph.links.length === 0 && this.focusedInstance.id !== this.state.currentQuery ){ - let idToSearch = ""; + let idToSearch = this.focusedInstance.id; if (this.focusedInstance.getParent() !== null) { idToSearch = this.focusedInstance.getParent().id; - } else { - idToSearch = this.focusedInstance.id; } + syncColor = stylingConfiguration.defaultRefreshIconColor; // Perform cypher query this.loading = true; From c486208375941e6655761df3c8d0010f36f482f8 Mon Sep 17 00:00:00 2001 From: Dario Del Piano Date: Wed, 7 Oct 2020 11:26:14 +0100 Subject: [PATCH 16/27] fixed 2 issues, 1st if the component was opened before the model loaded the component was broken, second switch between components and this was keeping this in constant loading mode --- components/interface/VFBGraph/VFBGraph.js | 60 +++++++++++++++++------ 1 file changed, 44 insertions(+), 16 deletions(-) diff --git a/components/interface/VFBGraph/VFBGraph.js b/components/interface/VFBGraph/VFBGraph.js index 7a295215a..5aed48f8b 100644 --- a/components/interface/VFBGraph/VFBGraph.js +++ b/components/interface/VFBGraph/VFBGraph.js @@ -122,8 +122,8 @@ class VFBGraph extends Component { constructor (props) { super(props); - this.state = { - graph : { nodes : [], links : [] }, + this.state = { + graph : { nodes : [], links : [] }, currentQuery : this.props.instance != null ? this.props.instance.id : "", dropDownAnchorEl : null, optionsIconColor : stylingConfiguration.defaultRefreshIconColor, @@ -157,6 +157,7 @@ class VFBGraph extends Component { this.focusedInstance = { id : "" }; this.selectedDropDownQuery = -1; this.loading = true; + this.firstLoad = true; } componentDidMount () { @@ -164,14 +165,13 @@ class VFBGraph extends Component { this.__isMounted = true; if (this.state.currentQuery !== undefined && this.state.currentQuery !== "" && this.state.currentQuery !== null){ - if ( this.props.instance != null ) { + if ( this.props.instance !== null ) { if (this.props.instance.getParent() !== null) { this.focusedInstance = this.props.instance.getParent(); } else { this.focusedInstance = this.props.instance; } } - this.updateGraph(); } @@ -186,11 +186,34 @@ class VFBGraph extends Component { if (event.isComposing || event.keyCode === 16) { self.shiftOn = false; } - }); + }); } componentDidUpdate () { let self = this; + + if (this.loading && this.firstLoad) { + if (this.state.currentQuery === undefined || this.state.currentQuery === "" || this.state.currentQuery === null){ + if (this.props.instance !== null && this.props.instance !== undefined) { + if (this.props.instance.getParent() !== null) { + this.focusedInstance = this.props.instance.getParent(); + } else { + this.focusedInstance = this.props.instance; + } + this.firstLoad = false; + this.updateGraph(); + } else if (this.props.instanceOnFocus !== null && this.props.instanceOnFocus !== undefined) { + if (this.props.instanceOnFocus.getParent() !== null) { + this.focusedInstance = this.props.instanceOnFocus.getParent(); + } else { + this.focusedInstance = this.props.instanceOnFocus; + } + this.firstLoad = false; + this.updateGraph(); + } + } + } + // Reset camera if graph component is visible, not focused or has been resized if ( this.props.visible && ( !this.focused || this.graphResized ) ) { /* @@ -211,7 +234,7 @@ class VFBGraph extends Component { } }); // Reset camera view after graph component becomes visible - setTimeout( function () { + setTimeout( function () { self.resetCamera(); self.focused = true; self.loading = false; @@ -219,7 +242,6 @@ class VFBGraph extends Component { }, (self.objectsLoaded * 20)); } else if ( !this.props.visible ) { this.focused = false; - this.loading = true; this.selectedDropDownQuery = -1; } } @@ -234,7 +256,7 @@ class VFBGraph extends Component { this.focused = true; } } - + resize (){ this.graphResized = true; this.setState( { reload : !this.state.reload } ); @@ -424,18 +446,24 @@ class VFBGraph extends Component { render () { let self = this; const { instanceOnFocus, graphQueryIndex } = this.props; - + let syncColor = this.state.optionsIconColor; - + + if (Object.keys(instanceOnFocus).length === 0 && instanceOnFocus.constructor === Object) { + return ( +

Model not loaded, graph not available yet

+ ); + } + if ( this.focusedInstance.id !== "" && !instanceOnFocus.id.includes(this.focusedInstance.id) ) { this.instanceFocusChange(instanceOnFocus); - + if ( this.state.graph.nodes.length === 0 && this.state.graph.links.length === 0 && this.focusedInstance.id !== this.state.currentQuery ){ let idToSearch = this.focusedInstance.id; if (this.focusedInstance.getParent() !== null) { idToSearch = this.focusedInstance.getParent().id; } - + syncColor = stylingConfiguration.defaultRefreshIconColor; // Perform cypher query this.loading = true; @@ -445,7 +473,7 @@ class VFBGraph extends Component { syncColor = stylingConfiguration.outOfSyncIconColor; } } - + if ( !this.state.currentQuery.includes(this.focusedInstance.id) ) { syncColor = stylingConfiguration.outOfSyncIconColor; } @@ -537,7 +565,7 @@ class VFBGraph extends Component { linkWidth={1.25} controls = {
- Reset View}> + Reset View}> - Zoom In}> + Zoom In}> - Zoom Out}> + Zoom Out}> Date: Wed, 7 Oct 2020 15:12:42 -0700 Subject: [PATCH 17/27] Fix 'Term Info - graph links appended each time we move the focus on that specific instance' and 'Layer - Instances not listed in the layer component when added through the term info thumbnail' --- .../controlsMenuConfiguration.js | 7 ++- .../interface/VFBListViewer/VFBListViewer.js | 2 +- .../interface/VFBTermInfo/VFBTermInfo.js | 47 ++++++++++++++----- reducers/generals.js | 13 ++--- 4 files changed, 45 insertions(+), 24 deletions(-) diff --git a/components/configuration/VFBListViewer/controlsMenuConfiguration.js b/components/configuration/VFBListViewer/controlsMenuConfiguration.js index 48a7f770b..9b1997469 100644 --- a/components/configuration/VFBListViewer/controlsMenuConfiguration.js +++ b/components/configuration/VFBListViewer/controlsMenuConfiguration.js @@ -91,6 +91,7 @@ const controlsMenuConf = { { toggle : { condition : entity => entity.isSelected(), + isVisible : entity => entity.isVisible(), options : { false : { label: "Select", @@ -131,7 +132,8 @@ const controlsMenuConf = { { label: "Zoom To", icon: "fa fa-search-plus", - action: { handlerAction: ACTIONS.ZOOM_TO } + action: { handlerAction: ACTIONS.ZOOM_TO }, + isVisible : entity => entity.isVisible() }, { label: "Show Volume", @@ -201,7 +203,8 @@ const controlsMenuConf = { { label: "Color", icon: "fa fa-tint", - action: { handlerAction: ACTIONS.COLOR } + action: { handlerAction: ACTIONS.COLOR }, + isVisible : entity => entity.isVisible() }, ] } diff --git a/components/interface/VFBListViewer/VFBListViewer.js b/components/interface/VFBListViewer/VFBListViewer.js index dd2ded1cc..6f0ff6d4e 100644 --- a/components/interface/VFBListViewer/VFBListViewer.js +++ b/components/interface/VFBListViewer/VFBListViewer.js @@ -61,7 +61,7 @@ class VFBListViewer extends Component { handler={this} filter={() => true} columnConfiguration={this.getColumnConfiguration()} - showPagination={false} + infiniteScroll={true} />
} diff --git a/components/interface/VFBTermInfo/VFBTermInfo.js b/components/interface/VFBTermInfo/VFBTermInfo.js index 889e210a2..456302d63 100644 --- a/components/interface/VFBTermInfo/VFBTermInfo.js +++ b/components/interface/VFBTermInfo/VFBTermInfo.js @@ -126,14 +126,26 @@ class VFBTermInfo extends React.Component { // Look for root node, create a Variable object with the graphs configuration, and attach it to root type object if (type.getMetaType() == GEPPETTO.Resources.COMPOSITE_TYPE_NODE) { - var graphType = new Type({ wrappedObj : { name : GRAPHS, eClass : GRAPHS } }) + let variables = type.getVariables(); + let present = false; - // Variable object holding the information for the graph links - var graphsVariable = new Variable({ wrappedObj : { name : "Graph for" }, values : graphs }); - graphsVariable.setTypes([graphType]); + // Check if link has been added already, if it has, don't add it again + for ( var i = 0; i < variables.length; i++ ){ + if ( variables[i].types[0].wrappedObj.name === GRAPHS ){ + present = true; + } + } + + if ( !present ) { + var graphType = new Type({ wrappedObj : { name : GRAPHS, eClass : GRAPHS } }) - // Add graphs Variable to root node - type.getVariables().push(graphsVariable); + // Variable object holding the information for the graph links + var graphsVariable = new Variable({ wrappedObj : { name : "Graph for" }, values : graphs }); + graphsVariable.setTypes([graphType]); + + // Add graphs Variable to root node + type.getVariables().push(graphsVariable); + } } } @@ -153,14 +165,25 @@ class VFBTermInfo extends React.Component { // Look for root node, create a Variable object with the graphs configuration, and attach it to root type object if (type.getMetaType() == GEPPETTO.Resources.COMPOSITE_TYPE_NODE) { - var circuitBrowserType = new Type({ wrappedObj : { name : CIRCUIT_BROWSER, eClass : CIRCUIT_BROWSER } }) + let variables = type.getVariables(); + let present = false; + // Check if link has been added already, if it has, don't add it again + for ( var i = 0; i < variables.length; i++ ){ + if ( variables[i].types[0].wrappedObj.name === CIRCUIT_BROWSER ){ + present = true; + } + } + + if ( !present ) { + var circuitBrowserType = new Type({ wrappedObj : { name : CIRCUIT_BROWSER, eClass : CIRCUIT_BROWSER } }) - // Variable object holding the information for the graph links - var circuitBrowserVariable = new Variable({ wrappedObj : { name : "Circuit Browser for" }, values : circuitBrowser }); - circuitBrowserVariable.setTypes([circuitBrowserType]); + // Variable object holding the information for the graph links + var circuitBrowserVariable = new Variable({ wrappedObj : { name : "Circuit Browser for" }, values : circuitBrowser }); + circuitBrowserVariable.setTypes([circuitBrowserType]); - // Add graphs Variable to root node - type.getVariables().push(circuitBrowserVariable); + // Add graphs Variable to root node + type.getVariables().push(circuitBrowserVariable); + } } } diff --git a/reducers/generals.js b/reducers/generals.js index 50350b189..be6dd301e 100644 --- a/reducers/generals.js +++ b/reducers/generals.js @@ -140,13 +140,6 @@ function generalReducer (state, action) { var idsLoaded = state.idsLoaded; var newMap = { ...state.idsMap }; - if (newMap[action.data.id] === undefined ) { - return { - ...state, - error: "instance " + action.data.id + "is not present anymore in the map" - }; - } - if (newMap[action.data.id] !== undefined && newMap[action.data.id].components[action.data.component]) { var newComponents = { ...newMap[action.data.id].components }; newMap[action.data.id].components = newComponents; @@ -195,7 +188,8 @@ function generalReducer (state, action) { stepsToLoad: 0, stepsLoaded: 0, idsMap: newMap, - loading: loading + loading: loading, + idsList : !state.idsList.includes(action.data.id) ? [ ...state.idsList, action.data.id ] : [ ...state.idsList ] }; } case VFB_UI_UPDATED: @@ -239,7 +233,8 @@ function generalReducer (state, action) { } return { ...state, - idsMap: newMap + idsMap: newMap, + idsList : !state.idsList.includes(action.data) ? [ ...state.idsList, action.data ] : [ ...state.idsList ] }; case INSTANCE_SELECTED: return { From 3d6d9a5710370e5ea08fd8028bbf8e44e3abb910 Mon Sep 17 00:00:00 2001 From: jrmartin Date: Fri, 9 Oct 2020 15:20:42 -0700 Subject: [PATCH 18/27] Fixing sync bug --- components/interface/VFBGraph/VFBGraph.js | 10 +++++++--- reducers/generals.js | 6 ++++-- 2 files changed, 11 insertions(+), 5 deletions(-) diff --git a/components/interface/VFBGraph/VFBGraph.js b/components/interface/VFBGraph/VFBGraph.js index 5aed48f8b..d115ca081 100644 --- a/components/interface/VFBGraph/VFBGraph.js +++ b/components/interface/VFBGraph/VFBGraph.js @@ -158,6 +158,7 @@ class VFBGraph extends Component { this.selectedDropDownQuery = -1; this.loading = true; this.firstLoad = true; + this.nodeSelectedID = ""; } componentDidMount () { @@ -171,6 +172,7 @@ class VFBGraph extends Component { } else { this.focusedInstance = this.props.instance; } + this.nodeSelectedID = this.focusedInstance.id; } this.updateGraph(); } @@ -285,6 +287,7 @@ class VFBGraph extends Component { */ handleNodeLeftClick (node, event) { this.queryNewInstance(node); + this.nodeSelectedID = node.title; } /** @@ -345,6 +348,7 @@ class VFBGraph extends Component { } else { this.focusedInstance = instance; } + this.nodeSelectedID = this.focusedInstance.id; } /** @@ -469,12 +473,12 @@ class VFBGraph extends Component { this.loading = true; this.queryResults(cypherQuery(idToSearch), idToSearch) } - if ( this.focusedInstance.id !== this.state.currentQuery ) { + if ( this.focusedInstance.id !== this.state.currentQuery && this.nodeSelectedID !== this.state.currentQuery ) { syncColor = stylingConfiguration.outOfSyncIconColor; } } - if ( !this.state.currentQuery.includes(this.focusedInstance.id) ) { + if ( !this.state.currentQuery.includes(this.focusedInstance.id) && this.nodeSelectedID !== this.state.currentQuery ) { syncColor = stylingConfiguration.outOfSyncIconColor; } return ( @@ -607,7 +611,7 @@ class VFBGraph extends Component { onClick={self.zoomOut }> - Refresh}> + Refresh for {this.focusedInstance.name} }> Date: Mon, 12 Oct 2020 13:17:56 -0700 Subject: [PATCH 19/27] Save bug fix attempt --- .../VFBCircuitBrowser/VFBCircuitBrowser.js | 2 +- components/interface/VFBGraph/VFBGraph.js | 74 +++++++++++-------- 2 files changed, 43 insertions(+), 33 deletions(-) diff --git a/components/interface/VFBCircuitBrowser/VFBCircuitBrowser.js b/components/interface/VFBCircuitBrowser/VFBCircuitBrowser.js index 56de50645..4a148490a 100644 --- a/components/interface/VFBCircuitBrowser/VFBCircuitBrowser.js +++ b/components/interface/VFBCircuitBrowser/VFBCircuitBrowser.js @@ -234,7 +234,7 @@ class VFBCircuitBrowser extends Component { } } - resize(){ + resize (){ this.graphResized = true; this.setState( { reload : !this.state.reload } ); } diff --git a/components/interface/VFBGraph/VFBGraph.js b/components/interface/VFBGraph/VFBGraph.js index d115ca081..d9be957e0 100644 --- a/components/interface/VFBGraph/VFBGraph.js +++ b/components/interface/VFBGraph/VFBGraph.js @@ -142,6 +142,7 @@ class VFBGraph extends Component { this.zoomOut = this.zoomOut.bind(this); this.selectedNodeLoaded = this.selectedNodeLoaded.bind(this); this.resize = this.resize.bind(this); + this.sync = this.sync.bind(this); this.highlightNodes = new Set(); this.highlightLinks = new Set(); @@ -193,29 +194,7 @@ class VFBGraph extends Component { componentDidUpdate () { let self = this; - - if (this.loading && this.firstLoad) { - if (this.state.currentQuery === undefined || this.state.currentQuery === "" || this.state.currentQuery === null){ - if (this.props.instance !== null && this.props.instance !== undefined) { - if (this.props.instance.getParent() !== null) { - this.focusedInstance = this.props.instance.getParent(); - } else { - this.focusedInstance = this.props.instance; - } - this.firstLoad = false; - this.updateGraph(); - } else if (this.props.instanceOnFocus !== null && this.props.instanceOnFocus !== undefined) { - if (this.props.instanceOnFocus.getParent() !== null) { - this.focusedInstance = this.props.instanceOnFocus.getParent(); - } else { - this.focusedInstance = this.props.instanceOnFocus; - } - this.firstLoad = false; - this.updateGraph(); - } - } - } - + // Reset camera if graph component is visible, not focused or has been resized if ( this.props.visible && ( !this.focused || this.graphResized ) ) { /* @@ -223,7 +202,7 @@ class VFBGraph extends Component { * with specific configuration dropdown query. */ stylingConfiguration.dropDownQueries.map((item, index) => { - if ( self.selectedDropDownQuery === -1 || self.selectedDropDownQuery !== parseInt(self.props.graphQueryIndex) ) { + if ( (self.selectedDropDownQuery < 0 ) && this.firstLoad ) { if ( parseInt(self.props.graphQueryIndex) === index ) { self.selectedDropDownQuery = index; self.loading = true; @@ -246,6 +225,28 @@ class VFBGraph extends Component { this.focused = false; this.selectedDropDownQuery = -1; } + + if (this.loading && this.firstLoad) { + if (this.state.currentQuery === undefined || this.state.currentQuery === "" || this.state.currentQuery === null){ + if (this.props.instance !== null && this.props.instance !== undefined) { + if (this.props.instance.getParent() !== null) { + this.focusedInstance = this.props.instance.getParent(); + } else { + this.focusedInstance = this.props.instance; + } + this.firstLoad = false; + this.updateGraph(); + } else if (this.props.instanceOnFocus !== null && this.props.instanceOnFocus !== undefined) { + if (this.props.instanceOnFocus.getParent() !== null) { + this.focusedInstance = this.props.instanceOnFocus.getParent(); + } else { + this.focusedInstance = this.props.instanceOnFocus; + } + this.firstLoad = false; + this.updateGraph(); + } + } + } } componentWillUnmount () { @@ -297,6 +298,11 @@ class VFBGraph extends Component { this.graphRef.current.ggv.current.centerAt(node.x , node.y, 1000); this.graphRef.current.ggv.current.zoom(2, 1000); } + + sync () { + this.instanceFocusChange(this.props.instanceOnFocus); + this.updateGraph(); + } /** * Handle Menu drop down clicks @@ -405,6 +411,7 @@ class VFBGraph extends Component { switch (e.data.resultMessage) { case "OK": self.loading = false; + self.focusedInstance = e.data.params; self.setState( { graph : e.data.params.results, currentQuery : e.data.params.id }); self.objectsLoaded = e.data.params.results.nodes.length; setTimeout( function () { @@ -449,19 +456,18 @@ class VFBGraph extends Component { render () { let self = this; - const { instanceOnFocus, graphQueryIndex } = this.props; + const { graphQueryIndex } = this.props; let syncColor = this.state.optionsIconColor; - if (Object.keys(instanceOnFocus).length === 0 && instanceOnFocus.constructor === Object) { + if (Object.keys(this.props.instanceOnFocus).length === 0 && this.props.instanceOnFocus.constructor === Object) { return (

Model not loaded, graph not available yet

); } - if ( this.focusedInstance.id !== "" && !instanceOnFocus.id.includes(this.focusedInstance.id) ) { - this.instanceFocusChange(instanceOnFocus); - + if ( this.focusedInstance.id !== "" && !this.props.instanceOnFocus.id.includes(this.focusedInstance.id) ) { + // If the length of the graph is 0, request a new query using the instanceOnFocus if ( this.state.graph.nodes.length === 0 && this.state.graph.links.length === 0 && this.focusedInstance.id !== this.state.currentQuery ){ let idToSearch = this.focusedInstance.id; if (this.focusedInstance.getParent() !== null) { @@ -473,14 +479,18 @@ class VFBGraph extends Component { this.loading = true; this.queryResults(cypherQuery(idToSearch), idToSearch) } - if ( this.focusedInstance.id !== this.state.currentQuery && this.nodeSelectedID !== this.state.currentQuery ) { + + // Out of sync if instanceOnFocus is not what's on display + if ( this.focusedInstance.id !== this.state.currentQuery ) { syncColor = stylingConfiguration.outOfSyncIconColor; } } - if ( !this.state.currentQuery.includes(this.focusedInstance.id) && this.nodeSelectedID !== this.state.currentQuery ) { + // Out of sync if instanceOnFocus is not what's on display + if ( !this.props.instanceOnFocus.id.includes(this.focusedInstance.id) ) { syncColor = stylingConfiguration.outOfSyncIconColor; } + return ( this.loading ? + onClick={self.sync}>
Options}> From 163ebe0387e1e3f90945a293dc8b776b52544d6c Mon Sep 17 00:00:00 2001 From: jrmartin Date: Tue, 13 Oct 2020 10:05:05 -0700 Subject: [PATCH 20/27] Save work in progress --- .../interface/VFBCircuitBrowser/Controls.js | 37 +++++++------------ .../VFBCircuitBrowser/VFBCircuitBrowser.js | 8 +--- reducers/generals.js | 4 +- 3 files changed, 16 insertions(+), 33 deletions(-) diff --git a/components/interface/VFBCircuitBrowser/Controls.js b/components/interface/VFBCircuitBrowser/Controls.js index f3dea2a64..40ae0e305 100644 --- a/components/interface/VFBCircuitBrowser/Controls.js +++ b/components/interface/VFBCircuitBrowser/Controls.js @@ -230,32 +230,20 @@ class Controls extends Component { */ getUpdatedNeuronFields () { let neuronFields = this.state.neuronFields; - let neuronMatch = false; - // Query preselected - let queriesPassed = Object.keys(this.circuitQuerySelected).length > 0; - if ( queriesPassed) { - // If query is preselected and is not on the list already - if ( !this.state.neuronFields.includes(this.circuitQuerySelected) ) { - for ( var i = 0 ; i < neuronFields.length ; i++ ) { - if ( this.state.neuronFields[i] === "" ) { - neuronFields[i] = this.circuitQuerySelected; - neuronMatch = true; - break; - } - } - } else if ( queriesPassed && neuronFields.includes(this.circuitQuerySelected) ) { - neuronMatch = true; - } - } - - // If preselected query is not on list of existing queries - if ( !neuronMatch ) { - if ( queriesPassed ) { - if ( neuronFields.length < configuration.maxNeurons ) { - neuronFields.push(this.circuitQuerySelected); + for ( var i = 0; i < this.circuitQuerySelected.length; i++ ){ + if ( !this.state.neuronFields.includes(this.circuitQuerySelected[i])) { + for ( var j = 0 ; j < neuronFields.length ; j++ ) { + if ( this.state.neuronFields[j] === "" ) { + neuronFields[j] = this.circuitQuerySelected[i]; + break; + } + } + } else if ( neuronFields.includes(this.circuitQuerySelected[i]) ) { + if ( neuronFields.length < configuration.maxNeurons ) { + neuronFields.push(this.circuitQuerySelected); + } } - } } return neuronFields; @@ -264,6 +252,7 @@ class Controls extends Component { render () { let self = this; const { classes } = this.props; + let neuronFields = this.getUpdatedNeuronFields() let expanded = this.state.expanded; diff --git a/components/interface/VFBCircuitBrowser/VFBCircuitBrowser.js b/components/interface/VFBCircuitBrowser/VFBCircuitBrowser.js index 4a148490a..13169a7f2 100644 --- a/components/interface/VFBCircuitBrowser/VFBCircuitBrowser.js +++ b/components/interface/VFBCircuitBrowser/VFBCircuitBrowser.js @@ -356,13 +356,7 @@ class VFBCircuitBrowser extends Component { const { classes } = this.props; // Detect when the first load of the Graph component happens - if ( !this.state.loading && this.firstLoad ) { - // Reset CircuitQuerySelected value after first load - this.circuitQuerySelected = ""; - } - if ( !this.state.loading && !this.firstLoad ) { - this.firstLoad = true; - } + this.circuitQuerySelected = this.props.circuitQuerySelected; return ( this.state.loading diff --git a/reducers/generals.js b/reducers/generals.js index af5e1b2a1..67b62496d 100644 --- a/reducers/generals.js +++ b/reducers/generals.js @@ -33,7 +33,7 @@ export const GENERAL_DEFAULT_STATE = { termInfoVisible : false, listViewerInfoVisible : true, circuitBrowserSelected : false, - circuitQuerySelected : {}, + circuitQuerySelected : [], layout: { "ThreeDViewer": true, "StackViewer": true, @@ -213,7 +213,7 @@ function generalReducer (state, action) { case LOAD_CIRCUIT_BROWSER: return { ...state, - circuitQuerySelected : action.data.instance, + circuitQuerySelected : !state.circuitQuerySelected.includes(action.data.instance) ? [...state.circuitQuerySelected, action.data.instance] : [...state.circuitQuerySelected] , circuitBrowserSelected : true }; case INSTANCE_ADDED: From f376cd04d7afd5e37546278d11db4ad110e43c56 Mon Sep 17 00:00:00 2001 From: jrmartin Date: Wed, 14 Oct 2020 00:21:08 -0700 Subject: [PATCH 21/27] Cleaning --- components/interface/VFBCircuitBrowser/Controls.js | 8 ++++---- components/interface/VFBGraph/VFBGraph.js | 13 +++++-------- 2 files changed, 9 insertions(+), 12 deletions(-) diff --git a/components/interface/VFBCircuitBrowser/Controls.js b/components/interface/VFBCircuitBrowser/Controls.js index 714cb8e19..e492aeca5 100644 --- a/components/interface/VFBCircuitBrowser/Controls.js +++ b/components/interface/VFBCircuitBrowser/Controls.js @@ -257,10 +257,10 @@ class Controls extends Component { } if ( this.circuitQuerySelected.length > neuronFields.length && !this.state.neuronFields.includes(this.circuitQuerySelected[i])) { - if ( neuronFields.length < configuration.maxNeurons && this.circuitQuerySelected !== "" ) { - neuronFields.push(this.circuitQuerySelected[i]); - } - } + if ( neuronFields.length < configuration.maxNeurons && this.circuitQuerySelected !== "" ) { + neuronFields.push(this.circuitQuerySelected[i]); + } + } } } diff --git a/components/interface/VFBGraph/VFBGraph.js b/components/interface/VFBGraph/VFBGraph.js index e331dde2a..e272726b8 100644 --- a/components/interface/VFBGraph/VFBGraph.js +++ b/components/interface/VFBGraph/VFBGraph.js @@ -128,7 +128,6 @@ class VFBGraph extends Component { currentQuery : this.props.instance != null ? this.props.instance.id : "", dropDownAnchorEl : null, optionsIconColor : stylingConfiguration.defaultRefreshIconColor, - nodeSelected : { title : "", id : "" }, reload : false } this.updateGraph = this.updateGraph.bind(this); @@ -174,7 +173,6 @@ class VFBGraph extends Component { } else { this.focusedInstance = this.props.instance; } - this.nodeSelectedID = this.focusedInstance.id; } this.updateGraph(); } @@ -293,8 +291,8 @@ class VFBGraph extends Component { * Handle Left click on Nodes */ handleNodeLeftClick (node, event) { - this.queryNewInstance(node); this.nodeSelectedID = node.title; + this.queryNewInstance(node); } /** @@ -329,7 +327,7 @@ class VFBGraph extends Component { queryNewInstance (node) { window.addVfbId(node.title); this.loading = true; - this.setState({ nodeSelected : node, optionsIconColor : stylingConfiguration.defaultRefreshIconColor }); + this.setState({ optionsIconColor : stylingConfiguration.defaultRefreshIconColor }); // Perform cypher query this.queryResults(cypherQuery(node.title), node.title) } @@ -340,8 +338,8 @@ class VFBGraph extends Component { loadedId = instance.getParent().id; } - if ( this.state.nodeSselected ) { - if ( this.state.nodeSelected.title === loadedId ) { + if ( this.nodeSselected ) { + if ( this.nodeSelectedID === loadedId ) { return true; } } @@ -360,7 +358,6 @@ class VFBGraph extends Component { } else { this.focusedInstance = instance; } - this.nodeSelectedID = this.focusedInstance.id; } /** @@ -466,7 +463,7 @@ class VFBGraph extends Component { const { graphQueryIndex } = this.props; let syncColor = this.state.optionsIconColor; - + if (Object.keys(this.props.instanceOnFocus).length === 0 && this.props.instanceOnFocus.constructor === Object) { return (

Model not loaded, graph not available yet

From 7d24df42494318b51b51af8f5621d0b04f62073f Mon Sep 17 00:00:00 2001 From: jrmartin Date: Wed, 14 Oct 2020 10:44:24 -0700 Subject: [PATCH 22/27] Fixing couple bugs after merge --- components/VFBMain.js | 4 ++-- .../interface/VFBCircuitBrowser/Controls.js | 18 ++++++++---------- .../VFBCircuitBrowser/VFBCircuitBrowser.js | 5 ++--- 3 files changed, 12 insertions(+), 15 deletions(-) diff --git a/components/VFBMain.js b/components/VFBMain.js index 688c5925d..8d5c10d46 100644 --- a/components/VFBMain.js +++ b/components/VFBMain.js @@ -17,7 +17,7 @@ import VFBQuickHelp from './interface/VFBOverview/QuickHelp'; import VFBGraph from './interface/VFBGraph/VFBGraph'; import VFBCircuitBrowser from './interface/VFBCircuitBrowser/VFBCircuitBrowser'; import { connect } from "react-redux"; -import { SHOW_GRAPH, LOAD_CIRCUIT_BROWSER, VFB_LOAD_TERM_INFO, SHOW_LIST_VIEWER } from './../actions/generals'; +import { SHOW_GRAPH, UPDATE_CIRCUIT_QUERY, VFB_LOAD_TERM_INFO, SHOW_LIST_VIEWER } from './../actions/generals'; require('../css/base.less'); require('../css/VFBMain.less'); @@ -1109,7 +1109,7 @@ class VFBMain extends React.Component { } } - if ( this.props.generals.type == LOAD_CIRCUIT_BROWSER ) { + if ( this.props.generals.type == UPDATE_CIRCUIT_QUERY ) { if ( !this.state.circuitBrowserVisible ) { this.setState({ UIUpdated: true, diff --git a/components/interface/VFBCircuitBrowser/Controls.js b/components/interface/VFBCircuitBrowser/Controls.js index e492aeca5..16dbb0323 100644 --- a/components/interface/VFBCircuitBrowser/Controls.js +++ b/components/interface/VFBCircuitBrowser/Controls.js @@ -142,9 +142,7 @@ class Controls extends Component { this.circuitQuerySelected = this.props.circuitQuerySelected; } - componentDidUpdate () { - this.circuitQuerySelected = this.props.circuitQuerySelected; - } + componentDidUpdate () {} /** * Deletes neuron field, updates control component right after @@ -246,19 +244,19 @@ class Controls extends Component { getUpdatedNeuronFields () { let neuronFields = this.state.neuronFields; let added = false; - for ( var i = 0; i < this.circuitQuerySelected.length; i++ ){ - if ( !this.state.neuronFields.includes(this.circuitQuerySelected[i])) { + for ( var i = 0; i < this.props.circuitQuerySelected.length; i++ ){ + if ( !this.state.neuronFields.includes(this.props.circuitQuerySelected[i])) { for ( var j = 0 ; j < neuronFields.length ; j++ ) { if ( this.state.neuronFields[j] === "" ) { - neuronFields[j] = this.circuitQuerySelected[i]; + neuronFields[j] = this.props.circuitQuerySelected[i]; added = true; break; } } - if ( this.circuitQuerySelected.length > neuronFields.length && !this.state.neuronFields.includes(this.circuitQuerySelected[i])) { - if ( neuronFields.length < configuration.maxNeurons && this.circuitQuerySelected !== "" ) { - neuronFields.push(this.circuitQuerySelected[i]); + if ( this.props.circuitQuerySelected.length > neuronFields.length && !this.state.neuronFields.includes(this.circuitQuerySelected[i])) { + if ( neuronFields.length < configuration.maxNeurons && this.props.circuitQuerySelected !== "" ) { + neuronFields.push(this.props.circuitQuerySelected[i]); } } } @@ -274,7 +272,7 @@ class Controls extends Component { render () { let self = this; const { classes } = this.props; - + this.circuitQuerySelected = this.props.circuitQuerySelected; let neuronFields = this.getUpdatedNeuronFields() let expanded = this.state.expanded; diff --git a/components/interface/VFBCircuitBrowser/VFBCircuitBrowser.js b/components/interface/VFBCircuitBrowser/VFBCircuitBrowser.js index e5df3795f..74bd3229f 100644 --- a/components/interface/VFBCircuitBrowser/VFBCircuitBrowser.js +++ b/components/interface/VFBCircuitBrowser/VFBCircuitBrowser.js @@ -373,9 +373,8 @@ class VFBCircuitBrowser extends Component { let self = this; // Detect when the first load of the Graph component happens - this.circuitQuerySelected = this.props.circuitQuerySelected; - const { classes } = this.props; - + const { classes, circuitQuerySelected } = this.props; + this.circuitQuerySelected = circuitQuerySelected; return ( this.state.loading ? Date: Wed, 14 Oct 2020 10:46:52 -0700 Subject: [PATCH 23/27] Remove debug log statement --- components/interface/VFBCircuitBrowser/VFBCircuitBrowser.js | 1 - 1 file changed, 1 deletion(-) diff --git a/components/interface/VFBCircuitBrowser/VFBCircuitBrowser.js b/components/interface/VFBCircuitBrowser/VFBCircuitBrowser.js index 74bd3229f..b2810b8bd 100644 --- a/components/interface/VFBCircuitBrowser/VFBCircuitBrowser.js +++ b/components/interface/VFBCircuitBrowser/VFBCircuitBrowser.js @@ -287,7 +287,6 @@ class VFBCircuitBrowser extends Component { */ updateGraph (neurons, hops) { if (this.__isMounted){ - console.log("Graph updated", this.state.neurons); // Show loading spinner while cypher query search occurs this.setState({ loading : true , neurons : neurons, hops : hops, queryLoaded : false }); // Perform cypher query From a497f6b09aed1ccc7b25b0c821bfa2a3f5dfcd64 Mon Sep 17 00:00:00 2001 From: jrmartin Date: Wed, 14 Oct 2020 14:33:37 -0700 Subject: [PATCH 24/27] merge development and overwrite development branch vfb.xmi --- model/vfb.xmi | 74 +++++++++++++++++++++++++-------------------------- 1 file changed, 37 insertions(+), 37 deletions(-) diff --git a/model/vfb.xmi b/model/vfb.xmi index d78879c05..8dbb71010 100644 --- a/model/vfb.xmi +++ b/model/vfb.xmi @@ -168,15 +168,15 @@ runForCount="false"> + queryProcessorId="vfbCreateImagesForQueryResultsQueryProcessor"/> + queryProcessorId="vfbCreateResultListForIndividualsForQueryResultsQueryProcessor"/> + query=""statement": "MATCH (n:Template {short_form:{ID}})<-[:depicts]-(:Template)<-[r:in_register_with]-(dc:Individual)-[:depicts]->(di:Individual)-[:INSTANCEOF]->(d:Class) WHERE has(r.index) RETURN DISTINCT di.short_form as id, di.label as name, coalesce(di.description[0],d.description[0]) as def, COLLECT(DISTINCT d.label) as type, replace(r.folder,'http:','https:') + '/thumbnailT.png' as file", "parameters" : { "ID" : "$ID" }" + countQuery=""statement": "MATCH (n:Template {short_form:{ID}})<-[:depicts]-(:Template)<-[r:in_register_with]-(dc:Individual)-[:depicts]->(di:Individual)-[:INSTANCEOF]->(d:Class) WHERE has(r.index) RETURN count(di) as count", "parameters" : { "ID" : "$ID" }"/> + query=""statement": "MATCH (n:Template {short_form:{ID}})<-[:depicts]-(:Template)<-[r:in_register_with]-(dc:Individual)-[:depicts]->(di:Individual) WHERE not has(r.index) OPTIONAL MATCH (di)-[:INSTANCEOF]->(d:Class) RETURN distinct di.short_form as id, di.label as name, coalesce(di.description[0],d.description[0]) as def, COLLECT(DISTINCT d.label) as type, replace(r.folder,'http:','https:') + '/thumbnailT.png' as file", "parameters" : { "ID" : "$ID" }" + countQuery=""statement": "MATCH (n:Template {short_form:{ID}})<-[:depicts]-(:Template)<-[r:in_register_with]-(dc:Individual)-[:depicts]->(di:Individual) WHERE not has(r.index) RETURN count(di) as count", "parameters" : { "ID" : "$ID" }"/> + query=""statement": "MATCH (ep:Class:Expression_pattern)<-[ar:overlaps|part_of]-(:Individual)-[:INSTANCEOF]->(anat:Class) WHERE anat.short_form in {ARRAY_ID_RESULTS} WITH DISTINCT collect(DISTINCT ar.pub) as pubs, anat, ep UNWIND pubs as p MATCH (pub:pub { short_form: p}) WITH anat, ep, collect({ core: { short_form: pub.short_form, label: coalesce(pub.label,''), iri: pub.iri, types: labels(pub) } , PubMed: coalesce(pub.PMID, ''), FlyBase: coalesce(pub.FlyBase, ''), DOI: coalesce(pub.DOI, '') }) as pubs OPTIONAL MATCH (ep)<-[:has_source|SUBCLASSOF|INSTANCEOF*]-(i:Individual)<-[:depicts]-(channel:Individual)-[irw:in_register_with]->(template:Individual)-[:depicts]->(template_anat:Individual) WITH template, channel, template_anat, irw, anat, ep, pubs , i OPTIONAL MATCH (channel)-[:is_specified_output_of]->(technique:Class) WITH CASE WHEN channel IS NULL THEN [] ELSE COLLECT({ anatomy: { short_form: i.short_form, label: coalesce(i.label,''), iri: i.iri, types: labels(i) } , channel_image: { channel: { short_form: channel.short_form, label: coalesce(channel.label,''), iri: channel.iri, types: labels(channel) } , imaging_technique: { short_form: technique.short_form, label: coalesce(technique.label,''), iri: technique.iri, types: labels(technique) } ,image: { template_channel : { short_form: template.short_form, label: coalesce(template.label,''), iri: template.iri, types: labels(template) } , template_anatomy: { short_form: template_anat.short_form, label: coalesce(template_anat.label,''), iri: template_anat.iri, types: labels(template_anat) } ,image_folder: irw.folder, index: coalesce(irw.index, []) + [] }} }) END AS anatomy_channel_image ,anat,ep,pubs RETURN {short_form: anat.short_form, label: coalesce(anat.label,''), iri: anat.iri, types: labels(anat) } as anatomy, { short_form: ep.short_form, label: coalesce(ep.label,''), iri: ep.iri, types: labels(ep) } AS expression_pattern, 'Get JSON for anat_2_ep query' AS query, 'ca9ab19' AS version , pubs, anatomy_channel_image", "parameters" : { "ARRAY_ID_RESULTS" : $ARRAY_ID_RESULTS}" + countQuery=""statement": "MATCH (anat:Class) WHERE anat.short_form IN {ARRAY_ID_RESULTS} OPTIONAL MATCH (ep:Class)<-[ar:overlaps|part_of]-(:Individual)-[:INSTANCEOF]->(anat) RETURN count(ep) as count", "parameters" : { "ARRAY_ID_RESULTS" : $ARRAY_ID_RESULTS}"/> + query=""statement": "MATCH (ep:Expression_pattern:Class)<-[ar:overlaps|part_of]-(anoni:Individual)-[:INSTANCEOF]->(anat:Class) WHERE ep.short_form in [{ID}] WITH anoni, anat, ar OPTIONAL MATCH (p:pub { short_form: ar.pub}) WITH anat, anoni, { core: { short_form: p.short_form, label: coalesce(p.label,''), iri: p.iri, types: labels(p) } , PubMed: coalesce(p.PMID, ''), FlyBase: coalesce(p.FlyBase, ''), DOI: coalesce(p.DOI, '') } AS pub OPTIONAL MATCH (anoni)-[r:Related]->(o:FBdv) WITH CASE WHEN o IS NULL THEN [] ELSE COLLECT ({ relation: { label: r.label, iri: r.uri, type: type(r) } , object: { short_form: o.short_form, label: coalesce(o.label,''), iri: o.iri, types: labels(o) } }) END AS stages ,anoni,anat,pub OPTIONAL MATCH (anat:Synaptic_neuropil)<-[:has_source|SUBCLASSOF|INSTANCEOF*]-(i:Individual)<-[:depicts]-(channel:Individual)-[irw:in_register_with]->(template:Individual)-[:depicts]->(template_anat:Individual) WITH template, channel, template_anat, irw, anoni, anat, pub, stages , i OPTIONAL MATCH (channel)-[:is_specified_output_of]->(technique:Class) WITH CASE WHEN channel IS NULL THEN [] ELSE COLLECT({ anatomy: { short_form: i.short_form, label: coalesce(i.label,''), iri: i.iri, types: labels(i) } , channel_image: { channel: { short_form: channel.short_form, label: coalesce(channel.label,''), iri: channel.iri, types: labels(channel) } , imaging_technique: { short_form: technique.short_form, label: coalesce(technique.label,''), iri: technique.iri, types: labels(technique) } ,image: { template_channel : { short_form: template.short_form, label: coalesce(template.label,''), iri: template.iri, types: labels(template) } , template_anatomy: { short_form: template_anat.short_form, label: coalesce(template_anat.label,''), iri: template_anat.iri, types: labels(template_anat) } ,image_folder: irw.folder, index: coalesce(irw.index, []) + [] }} }) END AS anatomy_channel_image ,anoni,anat,pub,stages RETURN { short_form: anat.short_form, label: coalesce(anat.label,''), iri: anat.iri, types: labels(anat) } AS anatomy, 'Get JSON for ep_2_anat query' AS query, 'ca9ab19' AS version , pub, stages, anatomy_channel_image", "parameters" : { "ID" : "$ID" }" + countQuery=""statement": "MATCH (ep:Class:Expression_pattern)<-[ar:overlaps|part_of]-(anoni:Individual)-[:INSTANCEOF]->(anat:Class) WHERE ep.short_form in [{ID}] RETURN count(anat) as count", "parameters" : { "ID" : "$ID" }"/> @@ -485,7 +485,7 @@ name="Get JSON for Neuron Class" description="Get JSON for Neuron Class" runForCount="false" - query=""statement": "MATCH (primary:Class) WHERE primary.short_form in [{ID}] WITH primary OPTIONAL MATCH (o:Class)<-[r:SUBCLASSOF|INSTANCEOF]-(primary) WITH CASE WHEN o IS NULL THEN [] ELSE COLLECT ({ short_form: o.short_form, label: coalesce(o.label,''), iri: o.iri, types: labels(o), symbol: coalesce(o.`IAO_0000028`[0], '')} ) END AS parents ,primary OPTIONAL MATCH (o)<-[r {type:'Related'}]-(primary) WITH CASE WHEN o IS NULL THEN [] ELSE COLLECT ({ relation: { label: r.label, iri: r.iri, type: type(r) } , object: { short_form: o.short_form, label: coalesce(o.label,''), iri: o.iri, types: labels(o), symbol: coalesce(o.`IAO_0000028`[0], '')} }) END AS relationships ,primary,parents OPTIONAL MATCH (o:Individual)<-[r {type:'Related'}]-(primary) WITH CASE WHEN o IS NULL THEN [] ELSE COLLECT ({ relation: { label: r.label, iri: r.iri, type: type(r) } , object: { short_form: o.short_form, label: coalesce(o.label,''), iri: o.iri, types: labels(o), symbol: coalesce(o.`IAO_0000028`[0], '')} }) END AS related_individuals ,primary,parents,relationships OPTIONAL MATCH (s:Site { short_form: primary.self_xref }) WITH CASE WHEN s IS NULL THEN [] ELSE COLLECT({ link_base: coalesce(s.link_base[0], ''), accession: coalesce(primary.short_form, ''), link_text: primary.label + ' on ' + s.label, homepage: coalesce(s.homepage[0], ''), site: { short_form: s.short_form, label: coalesce(s.label,''), iri: s.iri, types: labels(s), symbol: coalesce(s.`IAO_0000028`[0], '')} , icon: coalesce(s.link_icon_url[0], ''), link_postfix: coalesce(s.link_postfix, '')}) END AS self_xref, primary, parents, relationships, related_individuals OPTIONAL MATCH (s:Site)<-[dbx:database_cross_reference]-(primary) WITH CASE WHEN s IS NULL THEN self_xref ELSE COLLECT({ link_base: coalesce(s.link_base[0], ''), accession: coalesce(dbx.accession[0], ''), link_text: primary.label + ' on ' + s.label, homepage: coalesce(s.homepage[0], ''), site: { short_form: s.short_form, label: coalesce(s.label,''), iri: s.iri, types: labels(s), symbol: coalesce(s.`IAO_0000028`[0], '')} , icon: coalesce(s.link_icon_url[0], ''), link_postfix: coalesce(s.link_postfix, '')}) + self_xref END AS xrefs,primary,parents,relationships,related_individuals CALL apoc.cypher.run('WITH primary OPTIONAL MATCH (primary)<-[:has_source|SUBCLASSOF|INSTANCEOF*]-(i:Individual)<-[:depicts]-(channel:Individual)-[irw:in_register_with] ->(template:Individual)-[:depicts]->(template_anat:Individual) RETURN template, channel, template_anat, i, irw limit 5', {primary:primary}) yield value with value.template as template, value.channel as channel,value.template_anat as template_anat, value.i as i, value.irw as irw, primary, parents, relationships, related_individuals, xrefs OPTIONAL MATCH (channel)-[:is_specified_output_of]->(technique:Class) WITH CASE WHEN channel IS NULL THEN [] ELSE COLLECT({ anatomy: { short_form: i.short_form, label: coalesce(i.label,''), iri: i.iri, types: labels(i), symbol: coalesce(i.`IAO_0000028`[0], '')} , channel_image: { channel: { short_form: channel.short_form, label: coalesce(channel.label,''), iri: channel.iri, types: labels(channel), symbol: coalesce(channel.`IAO_0000028`[0], '')} , imaging_technique: { short_form: technique.short_form, label: coalesce(technique.label,''), iri: technique.iri, types: labels(technique), symbol: coalesce(technique.`IAO_0000028`[0], '')} ,image: { template_channel : { short_form: template.short_form, label: coalesce(template.label,''), iri: template.iri, types: labels(template), symbol: coalesce(template.`IAO_0000028`[0], '')} , template_anatomy: { short_form: template_anat.short_form, label: coalesce(template_anat.label,''), iri: template_anat.iri, types: labels(template_anat), symbol: coalesce(template_anat.`IAO_0000028`[0], '')} ,image_folder: COALESCE(irw.folder[0], ''), index: coalesce(apoc.convert.toInteger(irw.index[0]), []) + [] }} }) END AS anatomy_channel_image ,primary,parents,relationships,related_individuals,xrefs OPTIONAL MATCH (primary)-[rp:has_reference]->(p:pub) where rp.typ = 'syn' WITH CASE WHEN p is null THEN [] ELSE collect({ pub: { core: { short_form: p.short_form, label: coalesce(p.label,''), iri: p.iri, types: labels(p), symbol: coalesce(p.`IAO_0000028`[0], '')} , PubMed: coalesce(p.PMID[0], ''), FlyBase: coalesce(p.FlyBase[0], ''), DOI: coalesce(p.DOI[0], '') } , synonym: { label: coalesce(rp.value, ''), scope: coalesce(rp.scope, ''), type: coalesce(rp.has_synonym_type,'') } }) END AS pub_syn,primary,parents,relationships,related_individuals,xrefs,anatomy_channel_image OPTIONAL MATCH (primary)-[rp:has_reference]->(p:pub) WHERE rp.typ = 'def' WITH CASE WHEN p is null THEN [] ELSE collect({ core: { short_form: p.short_form, label: coalesce(p.label,''), iri: p.iri, types: labels(p), symbol: coalesce(p.`IAO_0000028`[0], '')} , PubMed: coalesce(p.PMID[0], ''), FlyBase: coalesce(p.FlyBase[0], ''), DOI: coalesce(p.DOI[0], '') } ) END AS def_pubs,primary,parents,relationships,related_individuals,xrefs,anatomy_channel_image,pub_syn OPTIONAL MATCH (:Class { label: 'intersectional expression pattern'})<-[:SUBCLASSOF]-(ep:Class)<-[ar:part_of]-(anoni:Individual)-[:INSTANCEOF]->(primary) WITH CASE WHEN ep IS NULL THEN [] ELSE COLLECT({ short_form: ep.short_form, label: coalesce(ep.label,''), iri: ep.iri, types: labels(ep), symbol: coalesce(ep.`IAO_0000028`[0], '')} ) END AS targeting_splits,primary,parents,relationships,related_individuals,xrefs,anatomy_channel_image,pub_syn,def_pubs RETURN { core : { short_form: primary.short_form, label: coalesce(primary.label,''), iri: primary.iri, types: labels(primary), symbol: coalesce(primary.`IAO_0000028`[0], '')} , description : coalesce(primary.description, []), comment : coalesce(primary.comment, []) } AS term, 'Get JSON for Neuron Class' AS query, '58214d4' AS version , parents, relationships, related_individuals, xrefs, anatomy_channel_image, pub_syn, def_pubs, targeting_splits", "parameters" : { "ID" : "$ID" }" + query=""statement": "MATCH (primary:Class) WHERE primary.short_form in [{ID}] WITH primary OPTIONAL MATCH (o:Class)<-[r:SUBCLASSOF|INSTANCEOF]-(primary) WITH CASE WHEN o IS NULL THEN [] ELSE COLLECT ({ short_form: o.short_form, label: coalesce(o.label,''), iri: o.iri, types: labels(o) } ) END AS parents ,primary OPTIONAL MATCH (o:Class)<-[r {type:'Related'}]-(primary) WITH CASE WHEN o IS NULL THEN [] ELSE COLLECT ({ relation: { label: r.label, iri: r.uri, type: type(r) } , object: { short_form: o.short_form, label: coalesce(o.label,''), iri: o.iri, types: labels(o) } }) END AS relationships ,primary,parents OPTIONAL MATCH (o:Individual)<-[r {type:'Related'}]-(primary) WITH CASE WHEN o IS NULL THEN [] ELSE COLLECT ({ relation: { label: r.label, iri: r.uri, type: type(r) } , object: { short_form: o.short_form, label: coalesce(o.label,''), iri: o.iri, types: labels(o) } }) END AS related_individuals ,primary,parents,relationships OPTIONAL MATCH (s:Site { short_form: primary.self_xref }) WITH CASE WHEN s IS NULL THEN [] ELSE COLLECT({ link_base: s.link_base, accession: coalesce(primary.short_form, ''), link_text: primary.label + ' on ' + s.label, site: { short_form: s.short_form, label: coalesce(s.label,''), iri: s.iri, types: labels(s) } , icon: coalesce(s.link_icon_url, ''), link_postfix: coalesce(s.link_postfix, '')}) END AS self_xref, primary, parents, relationships, related_individuals OPTIONAL MATCH (s:Site)<-[dbx:hasDbXref]-(primary) WITH CASE WHEN s IS NULL THEN self_xref ELSE COLLECT({ link_base: s.link_base, accession: coalesce(dbx.accession, ''), link_text: primary.label + ' on ' + s.label, site: { short_form: s.short_form, label: coalesce(s.label,''), iri: s.iri, types: labels(s) } , icon: coalesce(s.link_icon_url, ''), link_postfix: coalesce(s.link_postfix, '')}) + self_xref END AS xrefs,primary,parents,relationships,related_individuals OPTIONAL MATCH (primary)<-[:has_source|SUBCLASSOF|INSTANCEOF*]-(i:Individual)<-[:depicts]-(channel:Individual)-[irw:in_register_with]->(template:Individual)-[:depicts]->(template_anat:Individual) WITH template, channel, template_anat, irw, primary, parents, relationships, related_individuals, xrefs , i limit 5 OPTIONAL MATCH (channel)-[:is_specified_output_of]->(technique:Class) WITH CASE WHEN channel IS NULL THEN [] ELSE COLLECT({ anatomy: { short_form: i.short_form, label: coalesce(i.label,''), iri: i.iri, types: labels(i) } , channel_image: { channel: { short_form: channel.short_form, label: coalesce(channel.label,''), iri: channel.iri, types: labels(channel) } , imaging_technique: { short_form: technique.short_form, label: coalesce(technique.label,''), iri: technique.iri, types: labels(technique) } ,image: { template_channel : { short_form: template.short_form, label: coalesce(template.label,''), iri: template.iri, types: labels(template) } , template_anatomy: { short_form: template_anat.short_form, label: coalesce(template_anat.label,''), iri: template_anat.iri, types: labels(template_anat) } ,image_folder: irw.folder, index: coalesce(irw.index, []) + [] }} }) END AS anatomy_channel_image ,primary,parents,relationships,related_individuals,xrefs OPTIONAL MATCH (primary)-[rp:has_reference { typ: 'syn'}]->(p:pub) WITH CASE WHEN p is null THEN [] ELSE collect({ pub: { core: { short_form: p.short_form, label: coalesce(p.label,''), iri: p.iri, types: labels(p) } , PubMed: coalesce(p.PMID, ''), FlyBase: coalesce(p.FlyBase, ''), DOI: coalesce(p.DOI, '') } , synonym: { label: coalesce(rp.synonym, ''), scope: coalesce(rp.scope, ''), type: coalesce(rp.cat,'') } }) END AS pub_syn,primary,parents,relationships,related_individuals,xrefs,anatomy_channel_image OPTIONAL MATCH (primary)-[rp:has_reference { typ: 'def'}]->(p:pub) WITH CASE WHEN p is null THEN [] ELSE collect({ core: { short_form: p.short_form, label: coalesce(p.label,''), iri: p.iri, types: labels(p) } , PubMed: coalesce(p.PMID, ''), FlyBase: coalesce(p.FlyBase, ''), DOI: coalesce(p.DOI, '') } ) END AS def_pubs,primary,parents,relationships,related_individuals,xrefs,anatomy_channel_image,pub_syn OPTIONAL MATCH (:Class { label: 'intersectional expression pattern'})<-[:SUBCLASSOF]-(ep:Class)<-[ar:part_of]-(anoni:Individual)-[:INSTANCEOF]->(primary) WITH COLLECT({ short_form: ep.short_form, label: coalesce(ep.label,''), iri: ep.iri, types: labels(ep) } ) as targeting_splits,primary,parents,relationships,related_individuals,xrefs,anatomy_channel_image,pub_syn,def_pubs RETURN { core : { short_form: primary.short_form, label: coalesce(primary.label,''), iri: primary.iri, types: labels(primary) } , description : coalesce(primary.description, []), comment : coalesce(primary.`annotation-comment`, []) } AS term, 'Get JSON for Neuron Class' AS query, '2e501bd' AS version , parents, relationships, related_individuals, xrefs, anatomy_channel_image, pub_syn, def_pubs, targeting_splits", "parameters" : { "ID" : "$ID" }" countQuery=""statement": "MATCH (primary:Class {short_form: {ID}} ) RETURN count(primary) as count", "parameters" : { "ID" : "$ID" }"> @@ -495,7 +495,7 @@ name="Get JSON for Split Class" description="Get JSON for Split Class" runForCount="false" - query=""statement": "MATCH (primary:Class) WHERE primary.short_form in [{ID}] WITH primary OPTIONAL MATCH (o:Class)<-[r:SUBCLASSOF|INSTANCEOF]-(primary) WITH CASE WHEN o IS NULL THEN [] ELSE COLLECT ({ short_form: o.short_form, label: coalesce(o.label,''), iri: o.iri, types: labels(o), symbol: coalesce(o.`IAO_0000028`[0], '')} ) END AS parents ,primary OPTIONAL MATCH (o)<-[r {type:'Related'}]-(primary) WITH CASE WHEN o IS NULL THEN [] ELSE COLLECT ({ relation: { label: r.label, iri: r.iri, type: type(r) } , object: { short_form: o.short_form, label: coalesce(o.label,''), iri: o.iri, types: labels(o), symbol: coalesce(o.`IAO_0000028`[0], '')} }) END AS relationships ,primary,parents OPTIONAL MATCH (o:Individual)<-[r {type:'Related'}]-(primary) WITH CASE WHEN o IS NULL THEN [] ELSE COLLECT ({ relation: { label: r.label, iri: r.iri, type: type(r) } , object: { short_form: o.short_form, label: coalesce(o.label,''), iri: o.iri, types: labels(o), symbol: coalesce(o.`IAO_0000028`[0], '')} }) END AS related_individuals ,primary,parents,relationships OPTIONAL MATCH (s:Site { short_form: primary.self_xref }) WITH CASE WHEN s IS NULL THEN [] ELSE COLLECT({ link_base: coalesce(s.link_base[0], ''), accession: coalesce(primary.short_form, ''), link_text: primary.label + ' on ' + s.label, homepage: coalesce(s.homepage[0], ''), site: { short_form: s.short_form, label: coalesce(s.label,''), iri: s.iri, types: labels(s), symbol: coalesce(s.`IAO_0000028`[0], '')} , icon: coalesce(s.link_icon_url[0], ''), link_postfix: coalesce(s.link_postfix, '')}) END AS self_xref, primary, parents, relationships, related_individuals OPTIONAL MATCH (s:Site)<-[dbx:database_cross_reference]-(primary) WITH CASE WHEN s IS NULL THEN self_xref ELSE COLLECT({ link_base: coalesce(s.link_base[0], ''), accession: coalesce(dbx.accession[0], ''), link_text: primary.label + ' on ' + s.label, homepage: coalesce(s.homepage[0], ''), site: { short_form: s.short_form, label: coalesce(s.label,''), iri: s.iri, types: labels(s), symbol: coalesce(s.`IAO_0000028`[0], '')} , icon: coalesce(s.link_icon_url[0], ''), link_postfix: coalesce(s.link_postfix, '')}) + self_xref END AS xrefs,primary,parents,relationships,related_individuals CALL apoc.cypher.run('WITH primary OPTIONAL MATCH (primary)<-[:has_source|SUBCLASSOF|INSTANCEOF*]-(i:Individual)<-[:depicts]-(channel:Individual)-[irw:in_register_with] ->(template:Individual)-[:depicts]->(template_anat:Individual) RETURN template, channel, template_anat, i, irw limit 5', {primary:primary}) yield value with value.template as template, value.channel as channel,value.template_anat as template_anat, value.i as i, value.irw as irw, primary, parents, relationships, related_individuals, xrefs OPTIONAL MATCH (channel)-[:is_specified_output_of]->(technique:Class) WITH CASE WHEN channel IS NULL THEN [] ELSE COLLECT({ anatomy: { short_form: i.short_form, label: coalesce(i.label,''), iri: i.iri, types: labels(i), symbol: coalesce(i.`IAO_0000028`[0], '')} , channel_image: { channel: { short_form: channel.short_form, label: coalesce(channel.label,''), iri: channel.iri, types: labels(channel), symbol: coalesce(channel.`IAO_0000028`[0], '')} , imaging_technique: { short_form: technique.short_form, label: coalesce(technique.label,''), iri: technique.iri, types: labels(technique), symbol: coalesce(technique.`IAO_0000028`[0], '')} ,image: { template_channel : { short_form: template.short_form, label: coalesce(template.label,''), iri: template.iri, types: labels(template), symbol: coalesce(template.`IAO_0000028`[0], '')} , template_anatomy: { short_form: template_anat.short_form, label: coalesce(template_anat.label,''), iri: template_anat.iri, types: labels(template_anat), symbol: coalesce(template_anat.`IAO_0000028`[0], '')} ,image_folder: COALESCE(irw.folder[0], ''), index: coalesce(apoc.convert.toInteger(irw.index[0]), []) + [] }} }) END AS anatomy_channel_image ,primary,parents,relationships,related_individuals,xrefs OPTIONAL MATCH (primary)-[rp:has_reference]->(p:pub) where rp.typ = 'syn' WITH CASE WHEN p is null THEN [] ELSE collect({ pub: { core: { short_form: p.short_form, label: coalesce(p.label,''), iri: p.iri, types: labels(p), symbol: coalesce(p.`IAO_0000028`[0], '')} , PubMed: coalesce(p.PMID[0], ''), FlyBase: coalesce(p.FlyBase[0], ''), DOI: coalesce(p.DOI[0], '') } , synonym: { label: coalesce(rp.value, ''), scope: coalesce(rp.scope, ''), type: coalesce(rp.has_synonym_type,'') } }) END AS pub_syn,primary,parents,relationships,related_individuals,xrefs,anatomy_channel_image OPTIONAL MATCH (primary)-[rp:has_reference]->(p:pub) WHERE rp.typ = 'def' WITH CASE WHEN p is null THEN [] ELSE collect({ core: { short_form: p.short_form, label: coalesce(p.label,''), iri: p.iri, types: labels(p), symbol: coalesce(p.`IAO_0000028`[0], '')} , PubMed: coalesce(p.PMID[0], ''), FlyBase: coalesce(p.FlyBase[0], ''), DOI: coalesce(p.DOI[0], '') } ) END AS def_pubs,primary,parents,relationships,related_individuals,xrefs,anatomy_channel_image,pub_syn OPTIONAL MATCH (:Class { label: 'intersectional expression pattern'})<-[:SUBCLASSOF]-(primary)<-[ar:part_of]-(anoni:Individual)-[:INSTANCEOF]->(n:Neuron) WITH CASE WHEN n IS NULL THEN [] ELSE COLLECT({ short_form: n.short_form, label: coalesce(n.label,''), iri: n.iri, types: labels(n), symbol: coalesce(n.`IAO_0000028`[0], '')} ) END AS target_neurons,primary,parents,relationships,related_individuals,xrefs,anatomy_channel_image,pub_syn,def_pubs RETURN { core : { short_form: primary.short_form, label: coalesce(primary.label,''), iri: primary.iri, types: labels(primary), symbol: coalesce(primary.`IAO_0000028`[0], '')} , description : coalesce(primary.description, []), comment : coalesce(primary.comment, []) } AS term, 'Get JSON for Split Class' AS query, '58214d4' AS version , parents, relationships, related_individuals, xrefs, anatomy_channel_image, pub_syn, def_pubs, target_neurons", "parameters" : { "ID" : "$ID" }" + query=""statement": "MATCH (primary:Class) WHERE primary.short_form in [{ID}] WITH primary OPTIONAL MATCH (o:Class)<-[r:SUBCLASSOF|INSTANCEOF]-(primary) WITH CASE WHEN o IS NULL THEN [] ELSE COLLECT ({ short_form: o.short_form, label: coalesce(o.label,''), iri: o.iri, types: labels(o) } ) END AS parents ,primary OPTIONAL MATCH (o:Class)<-[r {type:'Related'}]-(primary) WITH CASE WHEN o IS NULL THEN [] ELSE COLLECT ({ relation: { label: r.label, iri: r.uri, type: type(r) } , object: { short_form: o.short_form, label: coalesce(o.label,''), iri: o.iri, types: labels(o) } }) END AS relationships ,primary,parents OPTIONAL MATCH (o:Individual)<-[r {type:'Related'}]-(primary) WITH CASE WHEN o IS NULL THEN [] ELSE COLLECT ({ relation: { label: r.label, iri: r.uri, type: type(r) } , object: { short_form: o.short_form, label: coalesce(o.label,''), iri: o.iri, types: labels(o) } }) END AS related_individuals ,primary,parents,relationships OPTIONAL MATCH (s:Site { short_form: primary.self_xref }) WITH CASE WHEN s IS NULL THEN [] ELSE COLLECT({ link_base: s.link_base, accession: coalesce(primary.short_form, ''), link_text: primary.label + ' on ' + s.label, site: { short_form: s.short_form, label: coalesce(s.label,''), iri: s.iri, types: labels(s) } , icon: coalesce(s.link_icon_url, ''), link_postfix: coalesce(s.link_postfix, '')}) END AS self_xref, primary, parents, relationships, related_individuals OPTIONAL MATCH (s:Site)<-[dbx:hasDbXref]-(primary) WITH CASE WHEN s IS NULL THEN self_xref ELSE COLLECT({ link_base: s.link_base, accession: coalesce(dbx.accession, ''), link_text: primary.label + ' on ' + s.label, site: { short_form: s.short_form, label: coalesce(s.label,''), iri: s.iri, types: labels(s) } , icon: coalesce(s.link_icon_url, ''), link_postfix: coalesce(s.link_postfix, '')}) + self_xref END AS xrefs,primary,parents,relationships,related_individuals OPTIONAL MATCH (primary)<-[:has_source|SUBCLASSOF|INSTANCEOF*]-(i:Individual)<-[:depicts]-(channel:Individual)-[irw:in_register_with]->(template:Individual)-[:depicts]->(template_anat:Individual) WITH template, channel, template_anat, irw, primary, parents, relationships, related_individuals, xrefs , i limit 5 OPTIONAL MATCH (channel)-[:is_specified_output_of]->(technique:Class) WITH CASE WHEN channel IS NULL THEN [] ELSE COLLECT({ anatomy: { short_form: i.short_form, label: coalesce(i.label,''), iri: i.iri, types: labels(i) } , channel_image: { channel: { short_form: channel.short_form, label: coalesce(channel.label,''), iri: channel.iri, types: labels(channel) } , imaging_technique: { short_form: technique.short_form, label: coalesce(technique.label,''), iri: technique.iri, types: labels(technique) } ,image: { template_channel : { short_form: template.short_form, label: coalesce(template.label,''), iri: template.iri, types: labels(template) } , template_anatomy: { short_form: template_anat.short_form, label: coalesce(template_anat.label,''), iri: template_anat.iri, types: labels(template_anat) } ,image_folder: irw.folder, index: coalesce(irw.index, []) + [] }} }) END AS anatomy_channel_image ,primary,parents,relationships,related_individuals,xrefs OPTIONAL MATCH (primary)-[rp:has_reference { typ: 'syn'}]->(p:pub) WITH CASE WHEN p is null THEN [] ELSE collect({ pub: { core: { short_form: p.short_form, label: coalesce(p.label,''), iri: p.iri, types: labels(p) } , PubMed: coalesce(p.PMID, ''), FlyBase: coalesce(p.FlyBase, ''), DOI: coalesce(p.DOI, '') } , synonym: { label: coalesce(rp.synonym, ''), scope: coalesce(rp.scope, ''), type: coalesce(rp.cat,'') } }) END AS pub_syn,primary,parents,relationships,related_individuals,xrefs,anatomy_channel_image OPTIONAL MATCH (primary)-[rp:has_reference { typ: 'def'}]->(p:pub) WITH CASE WHEN p is null THEN [] ELSE collect({ core: { short_form: p.short_form, label: coalesce(p.label,''), iri: p.iri, types: labels(p) } , PubMed: coalesce(p.PMID, ''), FlyBase: coalesce(p.FlyBase, ''), DOI: coalesce(p.DOI, '') } ) END AS def_pubs,primary,parents,relationships,related_individuals,xrefs,anatomy_channel_image,pub_syn OPTIONAL MATCH (:Class { label: 'intersectional expression pattern'})<-[:SUBCLASSOF]-(primary)<-[ar:part_of]-(anoni:Individual)-[:INSTANCEOF]->(n:Neuron) WITH COLLECT({ short_form: n.short_form, label: coalesce(n.label,''), iri: n.iri, types: labels(n) } ) as target_neurons,primary,parents,relationships,related_individuals,xrefs,anatomy_channel_image,pub_syn,def_pubs RETURN { core : { short_form: primary.short_form, label: coalesce(primary.label,''), iri: primary.iri, types: labels(primary) } , description : coalesce(primary.description, []), comment : coalesce(primary.`annotation-comment`, []) } AS term, 'Get JSON for Split Class' AS query, '2e501bd' AS version , parents, relationships, related_individuals, xrefs, anatomy_channel_image, pub_syn, def_pubs, target_neurons", "parameters" : { "ID" : "$ID" }" countQuery=""statement": "MATCH (primary:Class {short_form: {ID}} ) RETURN count(primary) as count", "parameters" : { "ID" : "$ID" }"> @@ -505,7 +505,7 @@ name="Get JSON for Individual" description="Get JSON for Individual:Anatomy" runForCount="false" - query=""statement": "MATCH (primary:Individual:Anatomy) WHERE primary.short_form in [{ID}] WITH primary OPTIONAL MATCH (primary)-[:has_source]-(ds:DataSet)-[:has_license]->(l:License) WITH COLLECT ({ dataset: { link : coalesce(ds.dataset_link[0], ''), core : { short_form: ds.short_form, label: coalesce(ds.label,''), iri: ds.iri, types: labels(ds), symbol: coalesce(ds.`IAO_0000028`[0], '')} }, license: { icon : coalesce(l.license_logo[0], ''), link : coalesce(l.license_url[0], ''), core : { short_form: l.short_form, label: coalesce(l.label,''), iri: l.iri, types: labels(l), symbol: coalesce(l.`IAO_0000028`[0], '')} }}) AS dataset_license,primary OPTIONAL MATCH (o:Class)<-[r:SUBCLASSOF|INSTANCEOF]-(primary) WITH CASE WHEN o IS NULL THEN [] ELSE COLLECT ({ short_form: o.short_form, label: coalesce(o.label,''), iri: o.iri, types: labels(o), symbol: coalesce(o.`IAO_0000028`[0], '')} ) END AS parents ,primary,dataset_license OPTIONAL MATCH (o)<-[r {type:'Related'}]-(primary) WITH CASE WHEN o IS NULL THEN [] ELSE COLLECT ({ relation: { label: r.label, iri: r.iri, type: type(r) } , object: { short_form: o.short_form, label: coalesce(o.label,''), iri: o.iri, types: labels(o), symbol: coalesce(o.`IAO_0000028`[0], '')} }) END AS relationships ,primary,dataset_license,parents OPTIONAL MATCH (s:Site { short_form: primary.self_xref }) WITH CASE WHEN s IS NULL THEN [] ELSE COLLECT({ link_base: coalesce(s.link_base[0], ''), accession: coalesce(primary.short_form, ''), link_text: primary.label + ' on ' + s.label, homepage: coalesce(s.homepage[0], ''), site: { short_form: s.short_form, label: coalesce(s.label,''), iri: s.iri, types: labels(s), symbol: coalesce(s.`IAO_0000028`[0], '')} , icon: coalesce(s.link_icon_url[0], ''), link_postfix: coalesce(s.link_postfix, '')}) END AS self_xref, primary, dataset_license, parents, relationships OPTIONAL MATCH (s:Site)<-[dbx:database_cross_reference]-(primary) WITH CASE WHEN s IS NULL THEN self_xref ELSE COLLECT({ link_base: coalesce(s.link_base[0], ''), accession: coalesce(dbx.accession[0], ''), link_text: primary.label + ' on ' + s.label, homepage: coalesce(s.homepage[0], ''), site: { short_form: s.short_form, label: coalesce(s.label,''), iri: s.iri, types: labels(s), symbol: coalesce(s.`IAO_0000028`[0], '')} , icon: coalesce(s.link_icon_url[0], ''), link_postfix: coalesce(s.link_postfix, '')}) + self_xref END AS xrefs,primary,dataset_license,parents,relationships OPTIONAL MATCH (primary)<-[:depicts]-(channel:Individual)-[irw:in_register_with]->(template:Individual)-[:depicts]->(template_anat:Individual) WITH template, channel, template_anat, irw, primary, dataset_license, parents, relationships, xrefs OPTIONAL MATCH (channel)-[:is_specified_output_of]->(technique:Class) WITH CASE WHEN channel IS NULL THEN [] ELSE collect ({ channel: { short_form: channel.short_form, label: coalesce(channel.label,''), iri: channel.iri, types: labels(channel), symbol: coalesce(channel.`IAO_0000028`[0], '')} , imaging_technique: { short_form: technique.short_form, label: coalesce(technique.label,''), iri: technique.iri, types: labels(technique), symbol: coalesce(technique.`IAO_0000028`[0], '')} ,image: { template_channel : { short_form: template.short_form, label: coalesce(template.label,''), iri: template.iri, types: labels(template), symbol: coalesce(template.`IAO_0000028`[0], '')} , template_anatomy: { short_form: template_anat.short_form, label: coalesce(template_anat.label,''), iri: template_anat.iri, types: labels(template_anat), symbol: coalesce(template_anat.`IAO_0000028`[0], '')} ,image_folder: COALESCE(irw.folder[0], ''), index: coalesce(apoc.convert.toInteger(irw.index[0]), []) + [] }}) END AS channel_image,primary,dataset_license,parents,relationships,xrefs OPTIONAL MATCH (o:Individual)<-[r {type:'Related'}]-(primary) WITH CASE WHEN o IS NULL THEN [] ELSE COLLECT ({ relation: { label: r.label, iri: r.iri, type: type(r) } , object: { short_form: o.short_form, label: coalesce(o.label,''), iri: o.iri, types: labels(o), symbol: coalesce(o.`IAO_0000028`[0], '')} }) END AS related_individuals ,primary,dataset_license,parents,relationships,xrefs,channel_image RETURN { core : { short_form: primary.short_form, label: coalesce(primary.label,''), iri: primary.iri, types: labels(primary), symbol: coalesce(primary.`IAO_0000028`[0], '')} , description : coalesce(primary.description, []), comment : coalesce(primary.comment, []) } AS term, 'Get JSON for Individual:Anatomy' AS query, '58214d4' AS version , dataset_license, parents, relationships, xrefs, channel_image, related_individuals", "parameters" : { "ID" : "$ID" }" + query=""statement": "MATCH (primary:Individual:Anatomy) WHERE primary.short_form in [{ID}] WITH primary OPTIONAL MATCH (primary)-[:has_source]->(ds:DataSet)-[:has_license]->(l:License) WITH COLLECT ({ dataset: { link : coalesce(ds.dataset_link, ''), core : { short_form: ds.short_form, label: coalesce(ds.label,''), iri: ds.iri, types: labels(ds) } }, license: { icon : coalesce(l.license_logo, ''), link : coalesce(l.license_url, ''), core : { short_form: l.short_form, label: coalesce(l.label,''), iri: l.iri, types: labels(l) } }}) AS dataset_license,primary OPTIONAL MATCH (o:Class)<-[r:SUBCLASSOF|INSTANCEOF]-(primary) WITH CASE WHEN o IS NULL THEN [] ELSE COLLECT ({ short_form: o.short_form, label: coalesce(o.label,''), iri: o.iri, types: labels(o) } ) END AS parents ,primary,dataset_license OPTIONAL MATCH (o:Class)<-[r {type:'Related'}]-(primary) WITH CASE WHEN o IS NULL THEN [] ELSE COLLECT ({ relation: { label: r.label, iri: r.uri, type: type(r) } , object: { short_form: o.short_form, label: coalesce(o.label,''), iri: o.iri, types: labels(o) } }) END AS relationships ,primary,dataset_license,parents OPTIONAL MATCH (s:Site { short_form: primary.self_xref }) WITH CASE WHEN s IS NULL THEN [] ELSE COLLECT({ link_base: s.link_base, accession: coalesce(primary.short_form, ''), link_text: primary.label + ' on ' + s.label, site: { short_form: s.short_form, label: coalesce(s.label,''), iri: s.iri, types: labels(s) } , icon: coalesce(s.link_icon_url, ''), link_postfix: coalesce(s.link_postfix, '')}) END AS self_xref, primary, dataset_license, parents, relationships OPTIONAL MATCH (s:Site)<-[dbx:hasDbXref]-(primary) WITH CASE WHEN s IS NULL THEN self_xref ELSE COLLECT({ link_base: s.link_base, accession: coalesce(dbx.accession, ''), link_text: primary.label + ' on ' + s.label, site: { short_form: s.short_form, label: coalesce(s.label,''), iri: s.iri, types: labels(s) } , icon: coalesce(s.link_icon_url, ''), link_postfix: coalesce(s.link_postfix, '')}) + self_xref END AS xrefs,primary,dataset_license,parents,relationships OPTIONAL MATCH (primary)<-[:depicts]-(channel:Individual)-[irw:in_register_with]->(template:Individual)-[:depicts]->(template_anat:Individual) WITH template, channel, template_anat, irw, primary, dataset_license, parents, relationships, xrefs OPTIONAL MATCH (channel)-[:is_specified_output_of]->(technique:Class) WITH CASE WHEN channel IS NULL THEN [] ELSE collect ({ channel: { short_form: channel.short_form, label: coalesce(channel.label,''), iri: channel.iri, types: labels(channel) } , imaging_technique: { short_form: technique.short_form, label: coalesce(technique.label,''), iri: technique.iri, types: labels(technique) } ,image: { template_channel : { short_form: template.short_form, label: coalesce(template.label,''), iri: template.iri, types: labels(template) } , template_anatomy: { short_form: template_anat.short_form, label: coalesce(template_anat.label,''), iri: template_anat.iri, types: labels(template_anat) } ,image_folder: irw.folder, index: coalesce(irw.index, []) + [] }}) END AS channel_image,primary,dataset_license,parents,relationships,xrefs OPTIONAL MATCH (o:Individual)<-[r {type:'Related'}]-(primary) WITH CASE WHEN o IS NULL THEN [] ELSE COLLECT ({ relation: { label: r.label, iri: r.uri, type: type(r) } , object: { short_form: o.short_form, label: coalesce(o.label,''), iri: o.iri, types: labels(o) } }) END AS related_individuals ,primary,dataset_license,parents,relationships,xrefs,channel_image RETURN { core : { short_form: primary.short_form, label: coalesce(primary.label,''), iri: primary.iri, types: labels(primary) } , description : coalesce(primary.description, []), comment : coalesce(primary.`annotation-comment`, []) } AS term, 'Get JSON for Individual:Anatomy' AS query, 'ca9ab19' AS version , dataset_license, parents, relationships, xrefs, channel_image, related_individuals", "parameters" : { "ID" : "$ID" }" countQuery=""statement": "MATCH (primary:Individual {short_form: {ID}} ) RETURN count(primary) as count", "parameters" : { "ID" : "$ID" }"> @@ -515,7 +515,7 @@ name="Get JSON for Template" description="Get JSON for Template" runForCount="false" - query=""statement": "MATCH (primary:Template) WHERE primary.short_form in [{ID}] WITH primary MATCH (channel:Individual)<-[irw:in_register_with]-(channel:Individual)-[:depicts]->(primary) WITH { index: coalesce(apoc.convert.toInteger(irw.index), []) + [], extent: irw.extent[0], center: irw.center[0], voxel: irw.voxel[0], orientation: coalesce(irw.orientation[0], ''), image_folder: coalesce(irw.folder[0],''), channel: { short_form: channel.short_form, label: coalesce(channel.label,''), iri: channel.iri, types: labels(channel), symbol: coalesce(channel.`IAO_0000028`[0], '')} } as template_channel,primary OPTIONAL MATCH (technique:Class)<-[:is_specified_output_of]-(channel:Individual)-[irw:in_register_with]->(template:Individual)-[:depicts]->(primary) WHERE technique.short_form = 'FBbi_00000224' AND exists(irw.index) WITH primary, template_channel, collect ({ channel: channel, irw: irw}) AS painted_domains UNWIND painted_domains AS pd MATCH (channel:Individual { short_form: pd.channel.short_form})-[:depicts]-(ai:Individual)-[:INSTANCEOF]->(c:Class) WITH collect({ anatomical_type: { short_form: c.short_form, label: coalesce(c.label,''), iri: c.iri, types: labels(c), symbol: coalesce(c.`IAO_0000028`[0], '')} , anatomical_individual: { short_form: ai.short_form, label: coalesce(ai.label,''), iri: ai.iri, types: labels(ai), symbol: coalesce(ai.`IAO_0000028`[0], '')} , folder: pd.irw.folder[0], center: coalesce (pd.irw.center, []), index: [] + coalesce (pd.irw.index, []) }) AS template_domains,primary,template_channel OPTIONAL MATCH (primary)-[:has_source]-(ds:DataSet)-[:has_license]->(l:License) WITH COLLECT ({ dataset: { link : coalesce(ds.dataset_link[0], ''), core : { short_form: ds.short_form, label: coalesce(ds.label,''), iri: ds.iri, types: labels(ds), symbol: coalesce(ds.`IAO_0000028`[0], '')} }, license: { icon : coalesce(l.license_logo[0], ''), link : coalesce(l.license_url[0], ''), core : { short_form: l.short_form, label: coalesce(l.label,''), iri: l.iri, types: labels(l), symbol: coalesce(l.`IAO_0000028`[0], '')} }}) AS dataset_license,primary,template_channel,template_domains OPTIONAL MATCH (o:Class)<-[r:SUBCLASSOF|INSTANCEOF]-(primary) WITH CASE WHEN o IS NULL THEN [] ELSE COLLECT ({ short_form: o.short_form, label: coalesce(o.label,''), iri: o.iri, types: labels(o), symbol: coalesce(o.`IAO_0000028`[0], '')} ) END AS parents ,primary,template_channel,template_domains,dataset_license OPTIONAL MATCH (o)<-[r {type:'Related'}]-(primary) WITH CASE WHEN o IS NULL THEN [] ELSE COLLECT ({ relation: { label: r.label, iri: r.iri, type: type(r) } , object: { short_form: o.short_form, label: coalesce(o.label,''), iri: o.iri, types: labels(o), symbol: coalesce(o.`IAO_0000028`[0], '')} }) END AS relationships ,primary,template_channel,template_domains,dataset_license,parents OPTIONAL MATCH (s:Site { short_form: primary.self_xref }) WITH CASE WHEN s IS NULL THEN [] ELSE COLLECT({ link_base: coalesce(s.link_base[0], ''), accession: coalesce(primary.short_form, ''), link_text: primary.label + ' on ' + s.label, homepage: coalesce(s.homepage[0], ''), site: { short_form: s.short_form, label: coalesce(s.label,''), iri: s.iri, types: labels(s), symbol: coalesce(s.`IAO_0000028`[0], '')} , icon: coalesce(s.link_icon_url[0], ''), link_postfix: coalesce(s.link_postfix, '')}) END AS self_xref, primary, template_channel, template_domains, dataset_license, parents, relationships OPTIONAL MATCH (s:Site)<-[dbx:database_cross_reference]-(primary) WITH CASE WHEN s IS NULL THEN self_xref ELSE COLLECT({ link_base: coalesce(s.link_base[0], ''), accession: coalesce(dbx.accession[0], ''), link_text: primary.label + ' on ' + s.label, homepage: coalesce(s.homepage[0], ''), site: { short_form: s.short_form, label: coalesce(s.label,''), iri: s.iri, types: labels(s), symbol: coalesce(s.`IAO_0000028`[0], '')} , icon: coalesce(s.link_icon_url[0], ''), link_postfix: coalesce(s.link_postfix, '')}) + self_xref END AS xrefs,primary,template_channel,template_domains,dataset_license,parents,relationships OPTIONAL MATCH (o:Individual)<-[r {type:'Related'}]-(primary) WITH CASE WHEN o IS NULL THEN [] ELSE COLLECT ({ relation: { label: r.label, iri: r.iri, type: type(r) } , object: { short_form: o.short_form, label: coalesce(o.label,''), iri: o.iri, types: labels(o), symbol: coalesce(o.`IAO_0000028`[0], '')} }) END AS related_individuals ,primary,template_channel,template_domains,dataset_license,parents,relationships,xrefs RETURN { core : { short_form: primary.short_form, label: coalesce(primary.label,''), iri: primary.iri, types: labels(primary), symbol: coalesce(primary.`IAO_0000028`[0], '')} , description : coalesce(primary.description, []), comment : coalesce(primary.comment, []) } AS term, 'Get JSON for Template' AS query, '58214d4' AS version , template_channel, template_domains, dataset_license, parents, relationships, xrefs, related_individuals", "parameters" : { "ID" : "$ID" }" + query=""statement": "MATCH (primary:Template) WHERE primary.short_form in [{ID}] WITH primary MATCH (channel:Individual)<-[irw:in_register_with]-(channel:Individual)-[:depicts]->(primary) WITH { index: coalesce(irw.index, []) + [], extent: irw.extent, center: irw.center, voxel: irw.voxel, orientation: irw.orientation, image_folder: irw.folder, channel: { short_form: channel.short_form, label: coalesce(channel.label,''), iri: channel.iri, types: labels(channel) } } as template_channel,primary OPTIONAL MATCH (technique:Class)<-[:is_specified_output_of]-(channel:Individual)-[irw:in_register_with]->(template:Individual)-[:depicts]->(primary) WHERE has(irw.index) WITH primary, template_channel, collect ({ channel: channel, irw: irw}) AS painted_domains UNWIND painted_domains AS pd MATCH (channel:Individual { short_form: pd.channel.short_form})-[:depicts]-(ai:Individual)-[:INSTANCEOF]->(c:Class) WITH collect({ anatomical_type: { short_form: c.short_form, label: coalesce(c.label,''), iri: c.iri, types: labels(c) } , anatomical_individual: { short_form: ai.short_form, label: coalesce(ai.label,''), iri: ai.iri, types: labels(ai) } , folder: pd.irw.folder, center: coalesce (pd.irw.center, []), index: [] + coalesce (pd.irw.index, []) }) AS template_domains,primary,template_channel OPTIONAL MATCH (primary)-[:has_source]->(ds:DataSet)-[:has_license]->(l:License) WITH COLLECT ({ dataset: { link : coalesce(ds.dataset_link, ''), core : { short_form: ds.short_form, label: coalesce(ds.label,''), iri: ds.iri, types: labels(ds) } }, license: { icon : coalesce(l.license_logo, ''), link : coalesce(l.license_url, ''), core : { short_form: l.short_form, label: coalesce(l.label,''), iri: l.iri, types: labels(l) } }}) AS dataset_license,primary,template_channel,template_domains OPTIONAL MATCH (o:Class)<-[r:SUBCLASSOF|INSTANCEOF]-(primary) WITH CASE WHEN o IS NULL THEN [] ELSE COLLECT ({ short_form: o.short_form, label: coalesce(o.label,''), iri: o.iri, types: labels(o) } ) END AS parents ,primary,template_channel,template_domains,dataset_license OPTIONAL MATCH (o:Class)<-[r {type:'Related'}]-(primary) WITH CASE WHEN o IS NULL THEN [] ELSE COLLECT ({ relation: { label: r.label, iri: r.uri, type: type(r) } , object: { short_form: o.short_form, label: coalesce(o.label,''), iri: o.iri, types: labels(o) } }) END AS relationships ,primary,template_channel,template_domains,dataset_license,parents OPTIONAL MATCH (s:Site { short_form: primary.self_xref }) WITH CASE WHEN s IS NULL THEN [] ELSE COLLECT({ link_base: s.link_base, accession: coalesce(primary.short_form, ''), link_text: primary.label + ' on ' + s.label, site: { short_form: s.short_form, label: coalesce(s.label,''), iri: s.iri, types: labels(s) } , icon: coalesce(s.link_icon_url, ''), link_postfix: coalesce(s.link_postfix, '')}) END AS self_xref, primary, template_channel, template_domains, dataset_license, parents, relationships OPTIONAL MATCH (s:Site)<-[dbx:hasDbXref]-(primary) WITH CASE WHEN s IS NULL THEN self_xref ELSE COLLECT({ link_base: s.link_base, accession: coalesce(dbx.accession, ''), link_text: primary.label + ' on ' + s.label, site: { short_form: s.short_form, label: coalesce(s.label,''), iri: s.iri, types: labels(s) } , icon: coalesce(s.link_icon_url, ''), link_postfix: coalesce(s.link_postfix, '')}) + self_xref END AS xrefs,primary,template_channel,template_domains,dataset_license,parents,relationships OPTIONAL MATCH (o:Individual)<-[r {type:'Related'}]-(primary) WITH CASE WHEN o IS NULL THEN [] ELSE COLLECT ({ relation: { label: r.label, iri: r.uri, type: type(r) } , object: { short_form: o.short_form, label: coalesce(o.label,''), iri: o.iri, types: labels(o) } }) END AS related_individuals ,primary,template_channel,template_domains,dataset_license,parents,relationships,xrefs RETURN { core : { short_form: primary.short_form, label: coalesce(primary.label,''), iri: primary.iri, types: labels(primary) } , description : coalesce(primary.description, []), comment : coalesce(primary.`annotation-comment`, []) } AS term, 'Get JSON for Template' AS query, 'ca9ab19' AS version , template_channel, template_domains, dataset_license, parents, relationships, xrefs, related_individuals", "parameters" : { "ID" : "$ID" }" countQuery=""statement": "MATCH (primary:Template {short_form: {ID}} ) RETURN count(primary) as count", "parameters" : { "ID" : "$ID" }"> @@ -525,7 +525,7 @@ name="Get JSON for pub" description="Fetches JSON for pub." runForCount="false" - query=""statement": "MATCH (primary:Individual:pub) WHERE primary.short_form in [{ID}] WITH primary OPTIONAL MATCH (primary)-[:has_reference]-(ds:DataSet)-[:has_license]->(l:License) WITH COLLECT ({ dataset: { link : coalesce(ds.dataset_link[0], ''), core : { short_form: ds.short_form, label: coalesce(ds.label,''), iri: ds.iri, types: labels(ds), symbol: coalesce(ds.`IAO_0000028`[0], '')} }, license: { icon : coalesce(l.license_logo[0], ''), link : coalesce(l.license_url[0], ''), core : { short_form: l.short_form, label: coalesce(l.label,''), iri: l.iri, types: labels(l), symbol: coalesce(l.`IAO_0000028`[0], '')} }}) AS dataset_license,primary RETURN { core : { short_form: primary.short_form, label: coalesce(primary.label,''), iri: primary.iri, types: labels(primary), symbol: coalesce(primary.`IAO_0000028`[0], '')} , description : coalesce(primary.description, []), comment : coalesce(primary.comment, []) } AS term, '58214d4' AS version , dataset_license, {title: coalesce(primary.title[0], '') ,PubMed: coalesce(primary.PMID[0], ''), FlyBase: coalesce(primary.FlyBase[0], ''), DOI: coalesce(primary.DOI[0], '') }AS pub_specific_content", "parameters" : { "ID" : "$ID" }" + query=""statement": "MATCH (primary:pub:Individual {short_form: {ID} }) OPTIONAL MATCH (o)-[r:has_reference]->(primary) WHERE o:DataSet OR o:Class WITH primary, r, o ORDER BY labels(o)[0] DESC, o.label ASC WITH CASE WHEN o IS NULL THEN [] ELSE COLLECT (DISTINCT { relation: { label: r.label, iri: r.uri, type: type(r) }, object: { short_form: o.short_form, label: o.label, iri: o.iri, types: labels(o) } }) END AS relationships, primary RETURN { core: { short_form: primary.short_form, label: primary.label, iri: primary.iri, types: labels(primary) } , description: coalesce(primary.description, []), comment: coalesce(primary.`annotation-comment`, [])} as term, relationships, 'pub' as query, 'manual' AS version", "parameters" : { "ID" : "$ID" }" countQuery=""statement": "MATCH (primary:pub:Individual {short_form: {ID}} ) RETURN count(primary) as count", "parameters" : { "ID" : "$ID" }"> @@ -535,7 +535,7 @@ name="Get JSON for DataSet" description="Get JSON for DataSet" runForCount="false" - query=""statement": "MATCH (primary:DataSet) WHERE primary.short_form in [{ID}] WITH primary CALL apoc.cypher.run('WITH primary OPTIONAL MATCH (primary)<-[:has_source|SUBCLASSOF|INSTANCEOF*]-(i:Individual)<-[:depicts]-(channel:Individual)-[irw:in_register_with] ->(template:Individual)-[:depicts]->(template_anat:Individual) RETURN template, channel, template_anat, i, irw limit 5', {primary:primary}) yield value with value.template as template, value.channel as channel,value.template_anat as template_anat, value.i as i, value.irw as irw, primary OPTIONAL MATCH (channel)-[:is_specified_output_of]->(technique:Class) WITH CASE WHEN channel IS NULL THEN [] ELSE COLLECT({ anatomy: { short_form: i.short_form, label: coalesce(i.label,''), iri: i.iri, types: labels(i), symbol: coalesce(i.`IAO_0000028`[0], '')} , channel_image: { channel: { short_form: channel.short_form, label: coalesce(channel.label,''), iri: channel.iri, types: labels(channel), symbol: coalesce(channel.`IAO_0000028`[0], '')} , imaging_technique: { short_form: technique.short_form, label: coalesce(technique.label,''), iri: technique.iri, types: labels(technique), symbol: coalesce(technique.`IAO_0000028`[0], '')} ,image: { template_channel : { short_form: template.short_form, label: coalesce(template.label,''), iri: template.iri, types: labels(template), symbol: coalesce(template.`IAO_0000028`[0], '')} , template_anatomy: { short_form: template_anat.short_form, label: coalesce(template_anat.label,''), iri: template_anat.iri, types: labels(template_anat), symbol: coalesce(template_anat.`IAO_0000028`[0], '')} ,image_folder: COALESCE(irw.folder[0], ''), index: coalesce(apoc.convert.toInteger(irw.index[0]), []) + [] }} }) END AS anatomy_channel_image ,primary OPTIONAL MATCH (s:Site { short_form: primary.self_xref }) WITH CASE WHEN s IS NULL THEN [] ELSE COLLECT({ link_base: coalesce(s.link_base[0], ''), accession: coalesce(primary.short_form, ''), link_text: primary.label + ' on ' + s.label, homepage: coalesce(s.homepage[0], ''), site: { short_form: s.short_form, label: coalesce(s.label,''), iri: s.iri, types: labels(s), symbol: coalesce(s.`IAO_0000028`[0], '')} , icon: coalesce(s.link_icon_url[0], ''), link_postfix: coalesce(s.link_postfix, '')}) END AS self_xref, primary, anatomy_channel_image OPTIONAL MATCH (s:Site)<-[dbx:database_cross_reference]-(primary) WITH CASE WHEN s IS NULL THEN self_xref ELSE COLLECT({ link_base: coalesce(s.link_base[0], ''), accession: coalesce(dbx.accession[0], ''), link_text: primary.label + ' on ' + s.label, homepage: coalesce(s.homepage[0], ''), site: { short_form: s.short_form, label: coalesce(s.label,''), iri: s.iri, types: labels(s), symbol: coalesce(s.`IAO_0000028`[0], '')} , icon: coalesce(s.link_icon_url[0], ''), link_postfix: coalesce(s.link_postfix, '')}) + self_xref END AS xrefs,primary,anatomy_channel_image OPTIONAL MATCH (primary)-[:has_license]->(l:License) WITH collect ({ icon : coalesce(l.license_logo[0], ''), link : coalesce(l.license_url[0], ''), core : { short_form: l.short_form, label: coalesce(l.label,''), iri: l.iri, types: labels(l), symbol: coalesce(l.`IAO_0000028`[0], '')} }) as license,primary,anatomy_channel_image,xrefs OPTIONAL MATCH (primary)-[rp:has_reference]->(p:pub) WITH CASE WHEN p is null THEN [] ELSE collect({ core: { short_form: p.short_form, label: coalesce(p.label,''), iri: p.iri, types: labels(p), symbol: coalesce(p.`IAO_0000028`[0], '')} , PubMed: coalesce(p.PMID[0], ''), FlyBase: coalesce(p.FlyBase[0], ''), DOI: coalesce(p.DOI[0], '') } ) END AS pubs,primary,anatomy_channel_image,xrefs,license OPTIONAL MATCH (primary)<-[:has_source]-(i:Individual) WITH i, primary, anatomy_channel_image, xrefs, license, pubs OPTIONAL MATCH (i)-[:INSTANCEOF]-(c:Class) WITH DISTINCT { images: count(distinct i),types: count(distinct c) } as dataset_counts,primary,anatomy_channel_image,xrefs,license,pubs RETURN { link : coalesce(primary.dataset_link[0], ''), core : { short_form: primary.short_form, label: coalesce(primary.label,''), iri: primary.iri, types: labels(primary), symbol: coalesce(primary.`IAO_0000028`[0], '')} , description : coalesce(primary.description, []), comment : coalesce(primary.comment, []) } AS term, 'Get JSON for DataSet' AS query, '58214d4' AS version , anatomy_channel_image, xrefs, license, pubs, dataset_counts", "parameters" : { "ID" : "$ID" }" + query=""statement": "MATCH (primary:DataSet) WHERE primary.short_form in [{ID}] WITH primary OPTIONAL MATCH (primary)<-[:has_source|SUBCLASSOF|INSTANCEOF*]-(i:Individual)<-[:depicts]-(channel:Individual)-[irw:in_register_with]->(template:Individual)-[:depicts]->(template_anat:Individual) WITH template, channel, template_anat, irw, primary , i limit 5 OPTIONAL MATCH (channel)-[:is_specified_output_of]->(technique:Class) WITH CASE WHEN channel IS NULL THEN [] ELSE COLLECT({ anatomy: { short_form: i.short_form, label: coalesce(i.label,''), iri: i.iri, types: labels(i) } , channel_image: { channel: { short_form: channel.short_form, label: coalesce(channel.label,''), iri: channel.iri, types: labels(channel) } , imaging_technique: { short_form: technique.short_form, label: coalesce(technique.label,''), iri: technique.iri, types: labels(technique) } ,image: { template_channel : { short_form: template.short_form, label: coalesce(template.label,''), iri: template.iri, types: labels(template) } , template_anatomy: { short_form: template_anat.short_form, label: coalesce(template_anat.label,''), iri: template_anat.iri, types: labels(template_anat) } ,image_folder: irw.folder, index: coalesce(irw.index, []) + [] }} }) END AS anatomy_channel_image ,primary OPTIONAL MATCH (s:Site { short_form: primary.self_xref }) WITH CASE WHEN s IS NULL THEN [] ELSE COLLECT({ link_base: s.link_base, accession: coalesce(primary.short_form, ''), link_text: primary.label + ' on ' + s.label, site: { short_form: s.short_form, label: coalesce(s.label,''), iri: s.iri, types: labels(s) } , icon: coalesce(s.link_icon_url, ''), link_postfix: coalesce(s.link_postfix, '')}) END AS self_xref, primary, anatomy_channel_image OPTIONAL MATCH (s:Site)<-[dbx:hasDbXref]-(primary) WITH CASE WHEN s IS NULL THEN self_xref ELSE COLLECT({ link_base: s.link_base, accession: coalesce(dbx.accession, ''), link_text: primary.label + ' on ' + s.label, site: { short_form: s.short_form, label: coalesce(s.label,''), iri: s.iri, types: labels(s) } , icon: coalesce(s.link_icon_url, ''), link_postfix: coalesce(s.link_postfix, '')}) + self_xref END AS xrefs,primary,anatomy_channel_image OPTIONAL MATCH (primary)-[:has_license]->(l:License) WITH collect ({ icon : coalesce(l.license_logo, ''), link : coalesce(l.license_url, ''), core : { short_form: l.short_form, label: coalesce(l.label,''), iri: l.iri, types: labels(l) } }) as license,primary,anatomy_channel_image,xrefs OPTIONAL MATCH (primary)-[rp:has_reference]->(p:pub) WITH CASE WHEN p is null THEN [] ELSE collect({ core: { short_form: p.short_form, label: coalesce(p.label,''), iri: p.iri, types: labels(p) } , PubMed: coalesce(p.PMID, ''), FlyBase: coalesce(p.FlyBase, ''), DOI: coalesce(p.DOI, '') } ) END AS def_pubs,primary,anatomy_channel_image,xrefs,license RETURN { link : coalesce(primary.dataset_link, ''), core : { short_form: primary.short_form, label: coalesce(primary.label,''), iri: primary.iri, types: labels(primary) } , description : coalesce(primary.description, []), comment : coalesce(primary.`annotation - comment`, []) } AS term, 'Get JSON for DataSet' AS query, '2e501bd' AS version , anatomy_channel_image, xrefs, license, def_pubs", "parameters" : { "ID" : "$ID" }" countQuery=""statement": "MATCH (primary:DataSet {short_form: {ID}} ) RETURN count(primary) as count", "parameters" : { "ID" : "$ID" }"> @@ -545,7 +545,7 @@ name="Get JSON for License" description="Get JSON for License" runForCount="false" - query=""statement": "MATCH (primary:License) WHERE primary.short_form in [{ID}] WITH primary RETURN { icon : coalesce(primary.license_logo[0], ''), link : coalesce(primary.license_url[0], ''), core : { short_form: primary.short_form, label: coalesce(primary.label,''), iri: primary.iri, types: labels(primary), symbol: coalesce(primary.`IAO_0000028`[0], '')} , description : coalesce(primary.description, []), comment : coalesce(primary.comment, []) } AS term, 'Get JSON for License' AS query, '58214d4' AS version", "parameters" : { "ID" : "$ID" }" + query=""statement": "MATCH (primary:License) WHERE primary.short_form in [{ID}] WITH primary RETURN { icon : coalesce(primary.license_logo, ''), link : coalesce(primary.license_url, ''), core : { short_form: primary.short_form, label: coalesce(primary.label,''), iri: primary.iri, types: labels(primary) } , description : coalesce(primary.description, []), comment : coalesce(primary.`annotation - comment`, []) } AS term, 'Get JSON for License' AS query, '2e501bd' AS version", "parameters" : { "ID" : "$ID" }" countQuery=""statement": "MATCH (primary:License {short_form: {ID}} ) RETURN count(primary) as count", "parameters" : { "ID" : "$ID" }"> @@ -555,7 +555,7 @@ name="Get JSON for Cluster" description="Get JSON for Cluster" runForCount="false" - query=""statement": "MATCH (primary:Cluster) WHERE primary.short_form in [{ID}] WITH primary OPTIONAL MATCH (primary)-[:has_source]->(ds:DataSet)-[:has_license]->(l:License) WITH COLLECT ({ dataset: { link : coalesce(ds.dataset_link, ''), core : { short_form: ds.short_form, label: coalesce(ds.label,''), iri: ds.iri, types: labels(ds) } }, license: { icon : coalesce(l.license_logo[0], ''), link : coalesce(l.license_url[0], ''), core : { short_form: l.short_form, label: coalesce(l.label,''), iri: l.iri, types: labels(l) } }}) AS dataset_license,primary OPTIONAL MATCH (o:Class)<-[r:SUBCLASSOF|INSTANCEOF]-(primary) WITH CASE WHEN o IS NULL THEN [] ELSE COLLECT ({ short_form: o.short_form, label: coalesce(o.label,''), iri: o.iri, types: labels(o) } ) END AS parents ,primary,dataset_license OPTIONAL MATCH (o:Class)<-[r {type:'Related'}]-(primary) WITH CASE WHEN o IS NULL THEN [] ELSE COLLECT ({ relation: { label: r.label, iri: r.uri, type: type(r) } , object: { short_form: o.short_form, label: coalesce(o.label,''), iri: o.iri, types: labels(o) } }) END AS relationships ,primary,dataset_license,parents OPTIONAL MATCH (s:Site { short_form: primary.self_xref }) WITH CASE WHEN s IS NULL THEN [] ELSE COLLECT({ link_base: s.link_base[0], accession: coalesce(primary.short_form, ''), link_text: primary.label + ' on ' + s.label, site: { short_form: s.short_form, label: coalesce(s.label,''), iri: s.iri, types: labels(s) } , icon: coalesce(s.link_icon_url[0], ''), link_postfix: coalesce(s.link_postfix, '')}) END AS self_xref, primary, dataset_license, parents, relationships OPTIONAL MATCH (s:Site)<-[dbx:hasDbXref]-(primary) WITH CASE WHEN s IS NULL THEN self_xref ELSE COLLECT({ link_base: s.link_base[0], accession: coalesce(dbx.accession, ''), link_text: primary.label + ' on ' + s.label, site: { short_form: s.short_form, label: coalesce(s.label,''), iri: s.iri, types: labels(s) } , icon: coalesce(s.link_icon_url[0], ''), link_postfix: coalesce(s.link_postfix, '')}) + self_xref END AS xrefs,primary,dataset_license,parents,relationships OPTIONAL MATCH (primary)<-[:depicts]-(channel:Individual)-[irw:in_register_with]->(template:Individual)-[:depicts]->(template_anat:Individual) WITH template, channel, template_anat, irw, primary, dataset_license, parents, relationships, xrefs OPTIONAL MATCH (channel)-[:is_specified_output_of]->(technique:Class) WITH CASE WHEN channel IS NULL THEN [] ELSE collect ({ channel: { short_form: channel.short_form, label: coalesce(channel.label,''), iri: channel.iri, types: labels(channel) } , imaging_technique: { short_form: technique.short_form, label: coalesce(technique.label,''), iri: technique.iri, types: labels(technique) } ,image: { template_channel : { short_form: template.short_form, label: coalesce(template.label,''), iri: template.iri, types: labels(template) } , template_anatomy: { short_form: template_anat.short_form, label: coalesce(template_anat.label,''), iri: template_anat.iri, types: labels(template_anat) } ,image_folder: irw.folder[0], index: coalesce(irw.index[0], []) + [] }}) END AS channel_image,primary,dataset_license,parents,relationships,xrefs OPTIONAL MATCH (o:Individual)<-[r {type:'Related'}]-(primary) WITH CASE WHEN o IS NULL THEN [] ELSE COLLECT ({ relation: { label: r.label, iri: r.uri, type: type(r) } , object: { short_form: o.short_form, label: coalesce(o.label,''), iri: o.iri, types: labels(o) } }) END AS related_individuals ,primary,dataset_license,parents,relationships,xrefs,channel_image RETURN { core : { short_form: primary.short_form, label: coalesce(primary.label,''), iri: primary.iri, types: labels(primary) } , description : coalesce(primary.description, []), comment : coalesce(primary.`annotation-comment`, []) } AS term, 'Get JSON for Individual:Anatomy' AS query, 'ca9ab19' AS version , dataset_license, parents, relationships, xrefs, channel_image, related_individuals", "parameters" : { "ID" : "$ID" }" + query=""statement": "MATCH (primary:Cluster) WHERE primary.short_form in [{ID}] WITH primary OPTIONAL MATCH (primary)-[:has_source]->(ds:DataSet)-[:has_license]->(l:License) WITH COLLECT ({ dataset: { link : coalesce(ds.dataset_link, ''), core : { short_form: ds.short_form, label: coalesce(ds.label,''), iri: ds.iri, types: labels(ds) } }, license: { icon : coalesce(l.license_logo, ''), link : coalesce(l.license_url, ''), core : { short_form: l.short_form, label: coalesce(l.label,''), iri: l.iri, types: labels(l) } }}) AS dataset_license,primary OPTIONAL MATCH (o:Class)<-[r:SUBCLASSOF|INSTANCEOF]-(primary) WITH CASE WHEN o IS NULL THEN [] ELSE COLLECT ({ short_form: o.short_form, label: coalesce(o.label,''), iri: o.iri, types: labels(o) } ) END AS parents ,primary,dataset_license OPTIONAL MATCH (o:Class)<-[r {type:'Related'}]-(primary) WITH CASE WHEN o IS NULL THEN [] ELSE COLLECT ({ relation: { label: r.label, iri: r.uri, type: type(r) } , object: { short_form: o.short_form, label: coalesce(o.label,''), iri: o.iri, types: labels(o) } }) END AS relationships ,primary,dataset_license,parents OPTIONAL MATCH (s:Site { short_form: primary.self_xref }) WITH CASE WHEN s IS NULL THEN [] ELSE COLLECT({ link_base: s.link_base, accession: coalesce(primary.short_form, ''), link_text: primary.label + ' on ' + s.label, site: { short_form: s.short_form, label: coalesce(s.label,''), iri: s.iri, types: labels(s) } , icon: coalesce(s.link_icon_url, ''), link_postfix: coalesce(s.link_postfix, '')}) END AS self_xref, primary, dataset_license, parents, relationships OPTIONAL MATCH (s:Site)<-[dbx:hasDbXref]-(primary) WITH CASE WHEN s IS NULL THEN self_xref ELSE COLLECT({ link_base: s.link_base, accession: coalesce(dbx.accession, ''), link_text: primary.label + ' on ' + s.label, site: { short_form: s.short_form, label: coalesce(s.label,''), iri: s.iri, types: labels(s) } , icon: coalesce(s.link_icon_url, ''), link_postfix: coalesce(s.link_postfix, '')}) + self_xref END AS xrefs,primary,dataset_license,parents,relationships OPTIONAL MATCH (primary)<-[:depicts]-(channel:Individual)-[irw:in_register_with]->(template:Individual)-[:depicts]->(template_anat:Individual) WITH template, channel, template_anat, irw, primary, dataset_license, parents, relationships, xrefs OPTIONAL MATCH (channel)-[:is_specified_output_of]->(technique:Class) WITH CASE WHEN channel IS NULL THEN [] ELSE collect ({ channel: { short_form: channel.short_form, label: coalesce(channel.label,''), iri: channel.iri, types: labels(channel) } , imaging_technique: { short_form: technique.short_form, label: coalesce(technique.label,''), iri: technique.iri, types: labels(technique) } ,image: { template_channel : { short_form: template.short_form, label: coalesce(template.label,''), iri: template.iri, types: labels(template) } , template_anatomy: { short_form: template_anat.short_form, label: coalesce(template_anat.label,''), iri: template_anat.iri, types: labels(template_anat) } ,image_folder: irw.folder, index: coalesce(irw.index, []) + [] }}) END AS channel_image,primary,dataset_license,parents,relationships,xrefs OPTIONAL MATCH (o:Individual)<-[r {type:'Related'}]-(primary) WITH CASE WHEN o IS NULL THEN [] ELSE COLLECT ({ relation: { label: r.label, iri: r.uri, type: type(r) } , object: { short_form: o.short_form, label: coalesce(o.label,''), iri: o.iri, types: labels(o) } }) END AS related_individuals ,primary,dataset_license,parents,relationships,xrefs,channel_image RETURN { core : { short_form: primary.short_form, label: coalesce(primary.label,''), iri: primary.iri, types: labels(primary) } , description : coalesce(primary.description, []), comment : coalesce(primary.`annotation-comment`, []) } AS term, 'Get JSON for Individual:Anatomy' AS query, 'ca9ab19' AS version , dataset_license, parents, relationships, xrefs, channel_image, related_individuals", "parameters" : { "ID" : "$ID" }" countQuery=""statement": "MATCH (primary:Cluster {short_form: {ID}} ) RETURN count(primary) as count", "parameters" : { "ID" : "$ID" }"> From 535873ab62d5f0974ab0194de1a0d19bf9881219 Mon Sep 17 00:00:00 2001 From: Rob Court Date: Thu, 15 Oct 2020 08:24:44 +0100 Subject: [PATCH 25/27] Revert "Merge pull request #690 from VirtualFlyBrain/pipeline2" This reverts commit 9e820520e05339e38558ced7d12b9bde4a9336fc, reversing changes made to 31e325f8400f42d47ca2b32ff80003d869cd0a99. --- .travis.yml | 60 ++++++--------- Dockerfile | 2 +- components/VFBMain.js | 1 - .../circuitBrowserConfiguration.js | 20 ++--- .../VFBGraph/graphConfiguration.js | 35 ++++----- components/configuration/VFBMain/colours.json | 2 +- .../VFBMain/queryBuilderConfiguration.js | 15 +--- .../VFBMain/searchConfiguration.js | 29 ++------ .../VFBTree/VFBTreeConfiguration.js | 16 ++-- css/VFBMain.less | 1 - model/vfb.xmi | 74 +++++++++---------- tests/jest/vfb/batch3/tree-browser-tests.js | 25 ++----- .../layer-component-tests.js | 0 13 files changed, 112 insertions(+), 168 deletions(-) rename tests/jest/vfb/{batch2 => review}/layer-component-tests.js (100%) diff --git a/.travis.yml b/.travis.yml index 07732a67d..7af7db28b 100644 --- a/.travis.yml +++ b/.travis.yml @@ -19,21 +19,21 @@ services: stages: - build - name: debug - if: branch = debug OR branch = pipeline2 OR branch =~ ^(fix|feature).* + if: branch = vfb_geppetto_application OR branch =~ ^(fix|feature).* - test - deploy - name: review - if: branch = debug OR branch = development OR branch = pipeline2 OR branch =~ ^(fix|feature).* + if: branch = vfb_geppetto_application OR branch = development OR branch =~ ^(fix|feature).* jobs: fast_finish: true allow_failures: - - if: branch = debug OR branch = development + - if: branch = vfb_geppetto_application OR branch = development name: review include: - stage: build install: - - export BUILD_TYPE=`if [ "$TRAVIS_BRANCH" == "debug" ]; then echo "development"; elif [ "$TRAVIS_BRANCH" == "pipeline2" ]; then echo "development"; elif [ "$TRAVIS_BRANCH" == "development" ]; then echo "staging"; else echo "release"; fi` + - export BUILD_TYPE=`if [ "$TRAVIS_BRANCH" == "vfb_geppetto_application" ]; then echo "development"; elif [ "$TRAVIS_BRANCH" == "development" ]; then echo "staging"; else echo "release"; fi` - export VFB_REPO=$(echo ${TRAVIS_REPO_SLUG##*/} | awk '{gsub(/\-/,"_",$0);gsub(/\./,"_",$0);print toupper($0)}') - export REPO=$(echo ${TRAVIS_REPO_SLUG} | awk '{gsub(/\./,"_",$0);print tolower($0)}') - export TAG=`if [ "$TRAVIS_BRANCH" == "master" ]; then echo "latest"; else echo ${TRAVIS_BRANCH/\//-}; fi` @@ -57,11 +57,6 @@ jobs: export VFB_R_SERVER=http://r.virtualflybrain.org/ocpu/library/vfbr/R/vfb_nblast; export SOLR_SERVER=https://solr.virtualflybrain.org/solr/ontology/select; fi; - export VFB_TREE_PDB_SERVER=https://pdb.p2.virtualflybrain.org; - export VFB_PDB_SERVER=http://pdb.p2.virtualflybrain.org; - export VFB_OWL_SERVER=http://owl.p2.virtualflybrain.org/kbs/vfb/; - export VFB_R_SERVER=http://r.virtualflybrain.org/ocpu/library/vfbr/R/vfb_nblast; - export SOLR_SERVER=https://solr.p2.virtualflybrain.org/solr/ontology/select; - export TAG="$TAG-TEST" before_script: - docker login -u $DOCKER_USER -p $DOCKER_PASS; @@ -76,7 +71,7 @@ jobs: - stage: test before_install: - - export BUILD_TYPE=`if [ "$TRAVIS_BRANCH" == "debug" ]; then echo "development"; elif [ "$TRAVIS_BRANCH" == "pipeline2" ]; then echo "development"; elif [ "$TRAVIS_BRANCH" == "development" ]; then echo "staging"; else echo "release"; fi` + - export BUILD_TYPE=`if [ "$TRAVIS_BRANCH" == "vfb_geppetto_application" ]; then echo "development"; elif [ "$TRAVIS_BRANCH" == "development" ]; then echo "staging"; else echo "release"; fi` - export VFB_REPO=$(echo ${TRAVIS_REPO_SLUG##*/} | awk '{gsub(/\-/,"_",$0);gsub(/\./,"_",$0);print toupper($0)}') - export REPO=$(echo ${TRAVIS_REPO_SLUG} | awk '{gsub(/\./,"_",$0);print tolower($0)}') - export TAG=`if [ "$TRAVIS_BRANCH" == "master" ]; then echo "latest"; else echo ${TRAVIS_BRANCH/\//-}; fi` @@ -116,7 +111,7 @@ jobs: - stage: test before_install: - - export BUILD_TYPE=`if [ "$TRAVIS_BRANCH" == "debug" ]; then echo "development"; elif [ "$TRAVIS_BRANCH" == "pipeline2" ]; then echo "development"; elif [ "$TRAVIS_BRANCH" == "development" ]; then echo "staging"; else echo "release"; fi` + - export BUILD_TYPE=`if [ "$TRAVIS_BRANCH" == "vfb_geppetto_application" ]; then echo "development"; elif [ "$TRAVIS_BRANCH" == "development" ]; then echo "staging"; else echo "release"; fi` - export VFB_REPO=$(echo ${TRAVIS_REPO_SLUG##*/} | awk '{gsub(/\-/,"_",$0);gsub(/\./,"_",$0);print toupper($0)}') - export REPO=$(echo ${TRAVIS_REPO_SLUG} | awk '{gsub(/\./,"_",$0);print tolower($0)}') - export TAG=`if [ "$TRAVIS_BRANCH" == "master" ]; then echo "latest"; else echo ${TRAVIS_BRANCH/\//-}; fi` @@ -156,7 +151,7 @@ jobs: - stage: test before_install: - - export BUILD_TYPE=`if [ "$TRAVIS_BRANCH" == "debug" ]; then echo "development"; elif [ "$TRAVIS_BRANCH" == "pipeline2" ]; then echo "development"; elif [ "$TRAVIS_BRANCH" == "development" ]; then echo "staging"; else echo "release"; fi` + - export BUILD_TYPE=`if [ "$TRAVIS_BRANCH" == "vfb_geppetto_application" ]; then echo "development"; elif [ "$TRAVIS_BRANCH" == "development" ]; then echo "staging"; else echo "release"; fi` - export VFB_REPO=$(echo ${TRAVIS_REPO_SLUG##*/} | awk '{gsub(/\-/,"_",$0);gsub(/\./,"_",$0);print toupper($0)}') - export REPO=$(echo ${TRAVIS_REPO_SLUG} | awk '{gsub(/\./,"_",$0);print tolower($0)}') - export TAG=`if [ "$TRAVIS_BRANCH" == "master" ]; then echo "latest"; else echo ${TRAVIS_BRANCH/\//-}; fi` @@ -196,7 +191,7 @@ jobs: - stage: deploy install: - - export BUILD_TYPE=`if [ "$TRAVIS_BRANCH" == "debug" ]; then echo "development"; elif [ "$TRAVIS_BRANCH" == "pipeline2" ]; then echo "development"; elif [ "$TRAVIS_BRANCH" == "development" ]; then echo "staging"; else echo "release"; fi` + - export BUILD_TYPE=`if [ "$TRAVIS_BRANCH" == "vfb_geppetto_application" ]; then echo "development"; elif [ "$TRAVIS_BRANCH" == "development" ]; then echo "staging"; else echo "release"; fi` - export VFB_REPO=$(echo ${TRAVIS_REPO_SLUG##*/} | awk '{gsub(/\-/,"_",$0);gsub(/\./,"_",$0);print toupper($0)}') - export REPO=$(echo ${TRAVIS_REPO_SLUG} | awk '{gsub(/\./,"_",$0);print tolower($0)}') - export TAG=`if [ "$TRAVIS_BRANCH" == "master" ]; then echo "latest"; else echo ${TRAVIS_BRANCH/\//-}; fi` @@ -220,40 +215,29 @@ jobs: export VFB_TREE_PDB_SERVER=https://pdb.virtualflybrain.org; export SOLR_SERVER=https://solr.virtualflybrain.org/solr/ontology/select; fi; - export VFB_TREE_PDB_SERVER=https://pdb.p2.virtualflybrain.org; - export VFB_PDB_SERVER=http://pdb.p2.virtualflybrain.org; - export VFB_OWL_SERVER=http://owl.p2.virtualflybrain.org/kbs/vfb/; - export VFB_R_SERVER=http://r.virtualflybrain.org/ocpu/library/vfbr/R/vfb_nblast; - export SOLR_SERVER=https://solr.p2.virtualflybrain.org/solr/ontology/select; docker build --cache-from metacell/java-virgo-maven:development -t=$REPO:$TAG.wss --build-arg VFB_TREE_PDB_SERVER_ARG=$VFB_TREE_PDB_SERVER --build-arg SOLR_SERVER_ARG=$SOLR_SERVER --build-arg VFB_R_SERVER_ARG=$VFB_R_SERVER --build-arg VFB_OWL_SERVER_ARG=$VFB_OWL_SERVER --build-arg VFB_PDB_SERVER_ARG=$VFB_PDB_SERVER --build-arg build_type=$BUILD_TYPE --build-arg targetBranch=$TRAVIS_BRANCH --build-arg originBranch=$BRANCH --build-arg defaultBranch=$DEFAULT_BRANCH --build-arg finalBuild=true $DOCKER_FOLDER && docker push $REPO:$TAG.wss; fi; - stage: debug install: - - export BUILD_TYPE=`if [ "$TRAVIS_BRANCH" == "debug" ]; then echo "development"; elif [ "$TRAVIS_BRANCH" == "pipeline2" ]; then echo "development"; elif [ "$TRAVIS_BRANCH" == "development" ]; then echo "staging"; else echo "release"; fi` + - export BUILD_TYPE=`if [ "$TRAVIS_BRANCH" == "vfb_geppetto_application" ]; then echo "development"; elif [ "$TRAVIS_BRANCH" == "development" ]; then echo "staging"; else echo "release"; fi` - export VFB_REPO=$(echo ${TRAVIS_REPO_SLUG##*/} | awk '{gsub(/\-/,"_",$0);gsub(/\./,"_",$0);print toupper($0)}') - export REPO=$(echo ${TRAVIS_REPO_SLUG} | awk '{gsub(/\./,"_",$0);print tolower($0)}') - export TAG=`if [ "$TRAVIS_BRANCH" == "master" ]; then echo "latest"; else echo ${TRAVIS_BRANCH/\//-}; fi` - - if [ "$BUILD_TYPE" == "development" ]; then export TAG=$TAG-development; fi; - export VFB_PDB_SERVER=http://pdb:7474; - export VFB_OWL_SERVER=http://owl:8080/kbs/vfb/; - export VFB_R_SERVER=http://ocpu:80/ocpu/library/vfbr/R/vfb_nblast; - # - if [ "$BUILD_TYPE" == "development" ]; then - # export VFB_TREE_PDB_SERVER=https://pdb-dev.virtualflybrain.org; - # export SOLR_SERVER=https://solr-dev.virtualflybrain.org/solr/ontology/select; - # export TAG=$TAG-development; - # elif [ "$BUILD_TYPE" == "staging" ]; then - # export VFB_TREE_PDB_SERVER=https://pdb-alpha.virtualflybrain.org; - # export SOLR_SERVER=https://solr-alpha.virtualflybrain.org/solr/ontology/select; - # else - # export VFB_TREE_PDB_SERVER=https://pdb.virtualflybrain.org; - # export SOLR_SERVER=https://solr.virtualflybrain.org/solr/ontology/select; - # fi; - - export VFB_TREE_PDB_SERVER=https://pdb.p2.virtualflybrain.org; - - export VFB_PDB_SERVER=http://pdb.p2.virtualflybrain.org; - - export VFB_OWL_SERVER=http://owl.p2.virtualflybrain.org/kbs/vfb/; - - export VFB_R_SERVER=http://r.virtualflybrain.org/ocpu/library/vfbr/R/vfb_nblast; - - export SOLR_SERVER=https://solr.p2.virtualflybrain.org/solr/ontology/select; + - if [ "$BUILD_TYPE" == "development" ]; then + export VFB_TREE_PDB_SERVER=https://pdb-dev.virtualflybrain.org; + export SOLR_SERVER=https://solr-dev.virtualflybrain.org/solr/ontology/select; + export TAG=$TAG-development; + elif [ "$BUILD_TYPE" == "staging" ]; then + export VFB_TREE_PDB_SERVER=https://pdb-alpha.virtualflybrain.org; + export SOLR_SERVER=https://solr-alpha.virtualflybrain.org/solr/ontology/select; + else + export VFB_TREE_PDB_SERVER=https://pdb.virtualflybrain.org; + export SOLR_SERVER=https://solr.virtualflybrain.org/solr/ontology/select; + fi; before_script: - cd $TRAVIS_BUILD_DIR; - docker login -u $DOCKER_USER -p $DOCKER_PASS; @@ -265,7 +249,7 @@ jobs: - stage: review before_install: - if [ $(ls tests/jest/vfb/review/*.js | wc -l) -lt 1 ]; then travis_terminate 0; fi - - export BUILD_TYPE=`if [ "$TRAVIS_BRANCH" == "debug" ]; then echo "development"; elif [ "$TRAVIS_BRANCH" == "pipeline2" ]; then echo "development"; elif [ "$TRAVIS_BRANCH" == "development" ]; then echo "staging"; else echo "release"; fi` + - export BUILD_TYPE=`if [ "$TRAVIS_BRANCH" == "vfb_geppetto_application" ]; then echo "development"; elif [ "$TRAVIS_BRANCH" == "development" ]; then echo "staging"; else echo "release"; fi` - export VFB_REPO=$(echo ${TRAVIS_REPO_SLUG##*/} | awk '{gsub(/\-/,"_",$0);gsub(/\./,"_",$0);print toupper($0)}') - export REPO=$(echo ${TRAVIS_REPO_SLUG} | awk '{gsub(/\./,"_",$0);print tolower($0)}') - export TAG=`if [ "$TRAVIS_BRANCH" == "master" ]; then echo "latest"; else echo ${TRAVIS_BRANCH/\//-}; fi` @@ -301,4 +285,4 @@ jobs: - echo -e "travis_fold:start:Cleanup" || true - docker stop $(docker ps -a -q) - docker rm $(docker ps -a -q) - - echo -e "travis_fold:end:Cleanup" || true + - echo -e "travis_fold:end:Cleanup" || true \ No newline at end of file diff --git a/Dockerfile b/Dockerfile index 9d81decc6..b3fea6831 100644 --- a/Dockerfile +++ b/Dockerfile @@ -15,7 +15,7 @@ ARG geppettoDatasourceRelease=vfb_20200604_a ARG geppettoModelSwcRelease=v1.0.1 ARG geppettoFrontendRelease=development ARG geppettoClientRelease=VFBv2.2.0.5 -ARG ukAcVfbGeppettoRelease=pipeline2 +ARG ukAcVfbGeppettoRelease=development ARG mvnOpt="-Dhttps.protocols=TLSv1.2 -DskipTests --quiet -Pmaster" diff --git a/components/VFBMain.js b/components/VFBMain.js index 27fd1ebe4..688c5925d 100644 --- a/components/VFBMain.js +++ b/components/VFBMain.js @@ -913,7 +913,6 @@ class VFBMain extends React.Component { focusTermRef={this.focusTermReference} exclude={["ClassQueriesFrom", "Debug"]} order={['Name', - 'Title', 'Label', 'Alternative Names', 'Types', diff --git a/components/configuration/VFBCircuitBrowser/circuitBrowserConfiguration.js b/components/configuration/VFBCircuitBrowser/circuitBrowserConfiguration.js index 35b522323..d71f2fc1b 100644 --- a/components/configuration/VFBCircuitBrowser/circuitBrowserConfiguration.js +++ b/components/configuration/VFBCircuitBrowser/circuitBrowserConfiguration.js @@ -57,6 +57,14 @@ var styling = { defaultNodeDescriptionBackgroundColor : "white", nodeColorsByLabel : { "Template" : "#ff6cc8", + "DataSet" : "#b700b5", + "Anatomy" : "#00a2aa", + "Synaptic_neuropil" : "#00a2aa", + "_Class" : "#0164d8", + "License" : "#0164d8", + "Person" : "#023f00", + "Neuron" : "#7f2100", + "Neuron_projection_bundle" : "#d6007d", "Ganglion" : "#d6007d", "Neuromere" : "#d6007d", "GABAergic" : "#9551ff", @@ -71,19 +79,11 @@ var styling = { "Glial_cell" : "#ff6a3a", "Cell" : "#ff6a3a", "Clone" : "#d6007d", - "Synaptic_neuropil" : "#00a2aa", - "License" : "#0164d8", - "Person" : "#023f00", - "Neuron" : "#7f2100", - "Neuron_projection_bundle" : "#d6007d", + "Property" : "#005f1d", "Resource" : "#005f1d", "Site" : "#005f1d", "Expression_pattern" : "#534700", - "Split" : "#e012e3", - "DataSet" : "#b700b5", - "Anatomy" : "#00a2aa", - "Property" : "#005f1d", - "_Class" : "#0164d8" + "Split" : "#e012e3" }, controlIcons : { home : "fa fa-home", diff --git a/components/configuration/VFBGraph/graphConfiguration.js b/components/configuration/VFBGraph/graphConfiguration.js index 77d0b7037..8819d61f8 100644 --- a/components/configuration/VFBGraph/graphConfiguration.js +++ b/components/configuration/VFBGraph/graphConfiguration.js @@ -1,21 +1,9 @@ var locationCypherQuery = instance => ({ "statements": [ { - "statement": "MATCH p=(n:Entity {short_form:'" + instance + "'})-[r:INSTANCEOF|part_of|has_synaptic_terminal_in|has_presynaptic_terminal_in|" - + "has_postsynaptic_terminal_in|overlaps*..]->(x) " - + "RETURN distinct n,r,x,n.short_form as root", - "resultDataContents": ["graph"] - } - ] -}); - -var whatCypherQuery = instance => ({ - "statements": [ - { - "statement": "MATCH p=(n:Entity {short_form:'" + instance + "'})-[:INSTANCEOF|:SUBCLASSOF*..]->(x) " - + "WHERE (('Cell' IN labels(x)) OR ('synaptic neuropil' IN labels(x))) " - + " OR (('Ganglion' IN labels(x)) OR ('Neuron_projection_bundle' IN labels(x))) " - + "RETURN p, n.short_form as root", + "statement": "MATCH p=(n:Entity)-[r:INSTANCEOF|part_of|has_synaptic_terminal_in|has_presynaptic_terminal_in" + + "has_postsynaptic_terminal_in|overlaps*..]->(x)" + + "WHERE n.short_form = '" + instance + "' return distinct n,r,x,n.short_form as root", "resultDataContents": ["graph"] } ] @@ -74,7 +62,17 @@ var styling = { }, { label : instance => "Show classification of " + instance, - query : instance => whatCypherQuery(instance) + query : instance => ({ + "statements": [ + { + "statement": "MATCH p=(n:Entity)-[:INSTANCEOF|:SUBCLASSOF*..]->(x)" + + "WHERE 'Anatomy' IN labels(x)" + + "AND n.short_form = '" + instance + "'" + + "RETURN p, n.short_form as root", + "resultDataContents": ["graph"] + } + ] + }) } ], dropDownHoverBackgroundColor : "#11bffe", @@ -84,7 +82,7 @@ var styling = { } var restPostConfig = { - url: "https://pdb.p2.virtualflybrain.org/db/data/transaction/commit", + url: "https://pdb.virtualflybrain.org/db/data/transaction/commit", contentType: "application/json" }; @@ -92,6 +90,5 @@ module.exports = { configuration, styling, restPostConfig, - locationCypherQuery, - whatCypherQuery + locationCypherQuery }; diff --git a/components/configuration/VFBMain/colours.json b/components/configuration/VFBMain/colours.json index a16bf2ea5..287f5ed53 100644 --- a/components/configuration/VFBMain/colours.json +++ b/components/configuration/VFBMain/colours.json @@ -3,6 +3,7 @@ "0x00ff00", "0xff00ff", "0x0000ff", + "0xffd300", "0x0084f6", "0x008d46", "0xa7613e", @@ -198,6 +199,5 @@ "0x8d35f6", "0x5800a7", "0xed8dff", - "0xffd300", "0x969696" ] diff --git a/components/configuration/VFBMain/queryBuilderConfiguration.js b/components/configuration/VFBMain/queryBuilderConfiguration.js index c6eb2062f..8de4bf6d9 100644 --- a/components/configuration/VFBMain/queryBuilderConfiguration.js +++ b/components/configuration/VFBMain/queryBuilderConfiguration.js @@ -25,19 +25,6 @@ var queryResultsColMeta = [ "cssClassName": "query-results-name-column", "sortDirectionCycle": ['asc', 'desc', null] }, - { - "columnName": "type", - "order": 2, - "locked": false, - "visible": true, - "customComponent": QueryLinkComponent, - "actions": "window.addVfbId('$entity$');", - "entityIndex": 1, - "entityDelimiter": "----", - "displayName": "Type", - "cssClassName": "query-results-type-column", - "sortDirectionCycle": ['asc', 'desc', null] - }, { "columnName": "expressed_in", "order": 3, @@ -176,7 +163,7 @@ var queryResultsControlConfig = { var queryBuilderDatasourceConfig = { VFB: { - url: 'https://solr.p2.virtualflybrain.org/solr/ontology/select?q=$SEARCH_TERM$+OR+$SEARCH_TERM$*+OR+*$SEARCH_TERM$*&defType=edismax&qf=label^100+synonym^100+label_autosuggest_ws+label_autosuggest_e+label_autosuggest+synonym_autosuggest_ws+synonym_autosuggest+shortform_autosuggest&indent=true&fl=short_form+label+synonym+id+facets_annotation+type:"class"&start=0&pf=true&rows=100&wt=json&bq=shortform_autosuggest:VFB*^110.0+shortform_autosuggest:FBbt*^100.0+label_s:""^2+synonym_s:""+short_form=FBbt_00003982^2+facets_annotation:Deprecated^0.001', + url: "https://solr.virtualflybrain.org/solr/ontology/select?fl=short_form,label,synonym,id,type,has_narrow_synonym_annotation,has_broad_synonym_annotation&start=0&fq=type%3Aclass+OR+type%3Aindividual+OR+type%3Aproperty&fq=ontology_name:(vfb)&fq=shortform_autosuggest:VFB*%20OR%20shortform_autosuggest:FB*%20OR%20is_defining_ontology:true&rows=100&bq=is_obsolete:false%5E100.0%20shortform_autosuggest:VFB*%5E110.0%20shortform_autosuggest:FBbt*%5E100.0%20is_defining_ontology:true%5E100.0%20label_s:%22%22%5E2%20synonym_s:%22%22%20in_subset_annotation:BRAINNAME%5E3%20short_form:FBbt_00003982%5E2&q=$SEARCH_TERM$%20OR%20$SEARCH_TERM$*%20OR%20*$SEARCH_TERM$*&defType=edismax&qf=label%20synonym%20label_autosuggest_ws%20label_autosuggest_e%20label_autosuggest%20synonym_autosuggest_ws%20synonym_autosuggest_e%20synonym_autosuggest%20shortform_autosuggest%20has_narrow_synonym_annotation%20has_broad_synonym_annotation&wt=json&indent=true", crossDomain: true, id: "short_form", label: { field: "label", formatting: "$VALUE$" }, diff --git a/components/configuration/VFBMain/searchConfiguration.js b/components/configuration/VFBMain/searchConfiguration.js index 2b33818d5..e7032751d 100644 --- a/components/configuration/VFBMain/searchConfiguration.js +++ b/components/configuration/VFBMain/searchConfiguration.js @@ -84,22 +84,23 @@ var searchStyle = { }; var datasourceConfiguration = { - "url": "https://solr.p2.virtualflybrain.org/solr/ontology/select", + "url": "https://solr-dev.virtualflybrain.org/solr/ontology/select", "query_settings": { "q": "$SEARCH_TERM$ OR $SEARCH_TERM$* OR *$SEARCH_TERM$*", "defType": "edismax", - "qf": "label^100 synonym^100 label_autosuggest_ws label_autosuggest_e label_autosuggest synonym_autosuggest_ws synonym_autosuggest shortform_autosuggest", + "qf": "label synonym label_autosuggest_ws label_autosuggest_e label_autosuggest synonym_autosuggest_ws synonym_autosuggest_e synonym_autosuggest shortform_autosuggest has_narrow_synonym_annotation has_broad_synonym_annotation", "indent": "true", - "fl": "short_form,label,synonym,id,facets_annotation", + "fl": "short_form,label,synonym,id,type,has_narrow_synonym_annotation,has_broad_synonym_annotation,facets_annotation", "start": "0", - "pf":"true", "fq": [ - "shortform_autosuggest:VFB* OR shortform_autosuggest:FB*" + "type:class OR type:individual OR type:property", + "ontology_name:(vfb)", + "shortform_autosuggest:VFB* OR shortform_autosuggest:FB* OR is_defining_ontology:true" ], "rows": "100", "wt": "json", - "bq": "shortform_autosuggest:VFB*^110.0 shortform_autosuggest:FBbt*^100.0 label_s:\"\"^2 synonym_s:\"\" short_form:FBbt_00003982^2 facets_annotation:Deprecated^0.001" + "bq": "is_obsolete:false^100.0 shortform_autosuggest:VFB*^110.0 shortform_autosuggest:FBbt*^100.0 is_defining_ontology:true^100.0 label_s:\"\"^2 synonym_s:\"\" in_subset_annotation:BRAINNAME^3 short_form:FBbt_00003982^2" } }; @@ -112,7 +113,7 @@ var searchConfiguration = { "filters": [ { "key": "facets_annotation", - "filter_name": "Filters", + "filter_name": "Type", "type": "array", "enabled": "disabled", "disableGlobal": true, @@ -176,13 +177,6 @@ var searchConfiguration = { if (InputString == b.label) { return 1; } - // move exact matches to top ['XX ('ID/Label)] - if (a.label.indexOf(InputString + " (") == 0) { - return -1; - } - if (b.label.indexOf(InputString + " (") == 0) { - return 1; - } // close match without case matching if (InputString.toLowerCase() == a.label.toLowerCase()) { return -1; @@ -190,13 +184,6 @@ var searchConfiguration = { if (InputString.toLowerCase() == b.label.toLowerCase()) { return 1; } - // close match without case matching ['xx ('ID/Label)] - if (a.label.toLowerCase().indexOf(InputString.toLowerCase()) == 0) { - return -1; - } - if (b.label.toLowerCase().indexOf(InputString.toLowerCase()) == 0) { - return 1; - } // match ignoring joinging nonwords if (InputString.toLowerCase().split(/\W+/).join(' ') == a.label.toLowerCase().split(/\W+/).join(' ')) { return -1; diff --git a/components/configuration/VFBTree/VFBTreeConfiguration.js b/components/configuration/VFBTree/VFBTreeConfiguration.js index 57d8f63af..00a4802ab 100644 --- a/components/configuration/VFBTree/VFBTreeConfiguration.js +++ b/components/configuration/VFBTree/VFBTreeConfiguration.js @@ -1,15 +1,15 @@ var restPostConfig = { - url: "https://pdb.p2.virtualflybrain.org/db/data/transaction/commit", + url: "https://pdb.virtualflybrain.org/db/data/transaction/commit", contentType: "application/json" }; var treeCypherQuery = instance => ({ "statements": [ { - "statement": "MATCH (root:Class)<-[:INSTANCEOF]-(t:Template {short_form:'" + instance + "'})" - + "<-[:depicts]-(tc:Template)<-[ie:in_register_with]-(c:Individual)-[:depicts]->(image:" - + "Individual)-[r:INSTANCEOF]->(anat:Class:Nervous_system) WHERE exists(ie.index) WITH root, anat,r,image" - + " MATCH p=allshortestpaths((root)<-[:SUBCLASSOF|part_of*..]-(anat)) " + "statement": "MATCH (root:Class)<-[:INSTANCEOF]-(t:Individual {short_form:'" + instance + "'})" + + "<-[:depicts]-(tc:Individual)<-[ie:in_register_with]-(c:Individual)-[:depicts]->(image:" + + "Individual)-[r:INSTANCEOF]->(anat:Class) WHERE has(ie.index) WITH root, anat,r,image" + + " MATCH p=(root)<-[:SUBCLASSOF|part_of*..]-(anat) " + "RETURN collect(distinct { node_id: id(anat), short_form: anat.short_form, image: image.short_form })" + " AS image_nodes, id(root) AS root, collect(p)", "resultDataContents": ["row", "graph"] @@ -32,7 +32,7 @@ var styling = { { "statement": "MATCH (root:Class)<-[:INSTANCEOF]-(t:Individual {short_form:'FBbt_00007145'})" + "<-[:depicts]-(tc:Individual)<-[ie:in_register_with]-(c:Individual)-[:depicts]->(image:" - + "Individual)-[r:INSTANCEOF]->(anat:Class) WHERE exists(ie.index) WITH root, anat,r,image" + + "Individual)-[r:INSTANCEOF]->(anat:Class) WHERE has(ie.index) WITH root, anat,r,image" + " MATCH p=allShortestPaths((root)<-[:SUBCLASSOF|part_of*..]-(anat)) " + "RETURN collect(distinct { node_id: id(anat), short_form: anat.short_form, image: image.short_form })" + " AS image_nodes, id(root) AS root, collect(p)", @@ -48,7 +48,7 @@ var styling = { { "statement": "MATCH (root:Class)<-[:INSTANCEOF]-(t:Individual {short_form:'VFB_00017894'})" + "<-[:depicts]-(tc:Individual)<-[ie:in_register_with]-(c:Individual)-[:depicts]->(image:" - + "Individual)-[r:INSTANCEOF]->(anat:Class) WHERE exists(ie.index) WITH root, anat,r,image" + + "Individual)-[r:INSTANCEOF]->(anat:Class) WHERE has(ie.index) WITH root, anat,r,image" + " MATCH p=allShortestPaths((root)<-[:SUBCLASSOF|part_of*..]-(anat)) " + "RETURN collect(distinct { node_id: id(anat), short_form: anat.short_form, image: image.short_form })" + " AS image_nodes, id(root) AS root, collect(p)", @@ -64,7 +64,7 @@ var styling = { { "statement": "MATCH (root:Class)<-[:INSTANCEOF]-(t:Individual {short_form:'FBbt_00007050'})" + "<-[:depicts]-(tc:Individual)<-[ie:in_register_with]-(c:Individual)-[:depicts]->(image:" - + "Individual)-[r:INSTANCEOF]->(anat:Class) WHERE exists(ie.index) WITH root, anat,r,image" + + "Individual)-[r:INSTANCEOF]->(anat:Class) WHERE has(ie.index) WITH root, anat,r,image" + " MATCH p=allShortestPaths((root)<-[:SUBCLASSOF|part_of*..]-(anat)) " + "RETURN collect(distinct { node_id: id(anat), short_form: anat.short_form, image: image.short_form })" + " AS image_nodes, id(root) AS root, collect(p)", diff --git a/css/VFBMain.less b/css/VFBMain.less index e17e5d2f4..c426b6408 100644 --- a/css/VFBMain.less +++ b/css/VFBMain.less @@ -1662,4 +1662,3 @@ -o-user-select: text; user-select: text; } - diff --git a/model/vfb.xmi b/model/vfb.xmi index d78879c05..8dbb71010 100644 --- a/model/vfb.xmi +++ b/model/vfb.xmi @@ -168,15 +168,15 @@ runForCount="false"> + queryProcessorId="vfbCreateImagesForQueryResultsQueryProcessor"/> + queryProcessorId="vfbCreateResultListForIndividualsForQueryResultsQueryProcessor"/> + query=""statement": "MATCH (n:Template {short_form:{ID}})<-[:depicts]-(:Template)<-[r:in_register_with]-(dc:Individual)-[:depicts]->(di:Individual)-[:INSTANCEOF]->(d:Class) WHERE has(r.index) RETURN DISTINCT di.short_form as id, di.label as name, coalesce(di.description[0],d.description[0]) as def, COLLECT(DISTINCT d.label) as type, replace(r.folder,'http:','https:') + '/thumbnailT.png' as file", "parameters" : { "ID" : "$ID" }" + countQuery=""statement": "MATCH (n:Template {short_form:{ID}})<-[:depicts]-(:Template)<-[r:in_register_with]-(dc:Individual)-[:depicts]->(di:Individual)-[:INSTANCEOF]->(d:Class) WHERE has(r.index) RETURN count(di) as count", "parameters" : { "ID" : "$ID" }"/> + query=""statement": "MATCH (n:Template {short_form:{ID}})<-[:depicts]-(:Template)<-[r:in_register_with]-(dc:Individual)-[:depicts]->(di:Individual) WHERE not has(r.index) OPTIONAL MATCH (di)-[:INSTANCEOF]->(d:Class) RETURN distinct di.short_form as id, di.label as name, coalesce(di.description[0],d.description[0]) as def, COLLECT(DISTINCT d.label) as type, replace(r.folder,'http:','https:') + '/thumbnailT.png' as file", "parameters" : { "ID" : "$ID" }" + countQuery=""statement": "MATCH (n:Template {short_form:{ID}})<-[:depicts]-(:Template)<-[r:in_register_with]-(dc:Individual)-[:depicts]->(di:Individual) WHERE not has(r.index) RETURN count(di) as count", "parameters" : { "ID" : "$ID" }"/> + query=""statement": "MATCH (ep:Class:Expression_pattern)<-[ar:overlaps|part_of]-(:Individual)-[:INSTANCEOF]->(anat:Class) WHERE anat.short_form in {ARRAY_ID_RESULTS} WITH DISTINCT collect(DISTINCT ar.pub) as pubs, anat, ep UNWIND pubs as p MATCH (pub:pub { short_form: p}) WITH anat, ep, collect({ core: { short_form: pub.short_form, label: coalesce(pub.label,''), iri: pub.iri, types: labels(pub) } , PubMed: coalesce(pub.PMID, ''), FlyBase: coalesce(pub.FlyBase, ''), DOI: coalesce(pub.DOI, '') }) as pubs OPTIONAL MATCH (ep)<-[:has_source|SUBCLASSOF|INSTANCEOF*]-(i:Individual)<-[:depicts]-(channel:Individual)-[irw:in_register_with]->(template:Individual)-[:depicts]->(template_anat:Individual) WITH template, channel, template_anat, irw, anat, ep, pubs , i OPTIONAL MATCH (channel)-[:is_specified_output_of]->(technique:Class) WITH CASE WHEN channel IS NULL THEN [] ELSE COLLECT({ anatomy: { short_form: i.short_form, label: coalesce(i.label,''), iri: i.iri, types: labels(i) } , channel_image: { channel: { short_form: channel.short_form, label: coalesce(channel.label,''), iri: channel.iri, types: labels(channel) } , imaging_technique: { short_form: technique.short_form, label: coalesce(technique.label,''), iri: technique.iri, types: labels(technique) } ,image: { template_channel : { short_form: template.short_form, label: coalesce(template.label,''), iri: template.iri, types: labels(template) } , template_anatomy: { short_form: template_anat.short_form, label: coalesce(template_anat.label,''), iri: template_anat.iri, types: labels(template_anat) } ,image_folder: irw.folder, index: coalesce(irw.index, []) + [] }} }) END AS anatomy_channel_image ,anat,ep,pubs RETURN {short_form: anat.short_form, label: coalesce(anat.label,''), iri: anat.iri, types: labels(anat) } as anatomy, { short_form: ep.short_form, label: coalesce(ep.label,''), iri: ep.iri, types: labels(ep) } AS expression_pattern, 'Get JSON for anat_2_ep query' AS query, 'ca9ab19' AS version , pubs, anatomy_channel_image", "parameters" : { "ARRAY_ID_RESULTS" : $ARRAY_ID_RESULTS}" + countQuery=""statement": "MATCH (anat:Class) WHERE anat.short_form IN {ARRAY_ID_RESULTS} OPTIONAL MATCH (ep:Class)<-[ar:overlaps|part_of]-(:Individual)-[:INSTANCEOF]->(anat) RETURN count(ep) as count", "parameters" : { "ARRAY_ID_RESULTS" : $ARRAY_ID_RESULTS}"/> + query=""statement": "MATCH (ep:Expression_pattern:Class)<-[ar:overlaps|part_of]-(anoni:Individual)-[:INSTANCEOF]->(anat:Class) WHERE ep.short_form in [{ID}] WITH anoni, anat, ar OPTIONAL MATCH (p:pub { short_form: ar.pub}) WITH anat, anoni, { core: { short_form: p.short_form, label: coalesce(p.label,''), iri: p.iri, types: labels(p) } , PubMed: coalesce(p.PMID, ''), FlyBase: coalesce(p.FlyBase, ''), DOI: coalesce(p.DOI, '') } AS pub OPTIONAL MATCH (anoni)-[r:Related]->(o:FBdv) WITH CASE WHEN o IS NULL THEN [] ELSE COLLECT ({ relation: { label: r.label, iri: r.uri, type: type(r) } , object: { short_form: o.short_form, label: coalesce(o.label,''), iri: o.iri, types: labels(o) } }) END AS stages ,anoni,anat,pub OPTIONAL MATCH (anat:Synaptic_neuropil)<-[:has_source|SUBCLASSOF|INSTANCEOF*]-(i:Individual)<-[:depicts]-(channel:Individual)-[irw:in_register_with]->(template:Individual)-[:depicts]->(template_anat:Individual) WITH template, channel, template_anat, irw, anoni, anat, pub, stages , i OPTIONAL MATCH (channel)-[:is_specified_output_of]->(technique:Class) WITH CASE WHEN channel IS NULL THEN [] ELSE COLLECT({ anatomy: { short_form: i.short_form, label: coalesce(i.label,''), iri: i.iri, types: labels(i) } , channel_image: { channel: { short_form: channel.short_form, label: coalesce(channel.label,''), iri: channel.iri, types: labels(channel) } , imaging_technique: { short_form: technique.short_form, label: coalesce(technique.label,''), iri: technique.iri, types: labels(technique) } ,image: { template_channel : { short_form: template.short_form, label: coalesce(template.label,''), iri: template.iri, types: labels(template) } , template_anatomy: { short_form: template_anat.short_form, label: coalesce(template_anat.label,''), iri: template_anat.iri, types: labels(template_anat) } ,image_folder: irw.folder, index: coalesce(irw.index, []) + [] }} }) END AS anatomy_channel_image ,anoni,anat,pub,stages RETURN { short_form: anat.short_form, label: coalesce(anat.label,''), iri: anat.iri, types: labels(anat) } AS anatomy, 'Get JSON for ep_2_anat query' AS query, 'ca9ab19' AS version , pub, stages, anatomy_channel_image", "parameters" : { "ID" : "$ID" }" + countQuery=""statement": "MATCH (ep:Class:Expression_pattern)<-[ar:overlaps|part_of]-(anoni:Individual)-[:INSTANCEOF]->(anat:Class) WHERE ep.short_form in [{ID}] RETURN count(anat) as count", "parameters" : { "ID" : "$ID" }"/> @@ -485,7 +485,7 @@ name="Get JSON for Neuron Class" description="Get JSON for Neuron Class" runForCount="false" - query=""statement": "MATCH (primary:Class) WHERE primary.short_form in [{ID}] WITH primary OPTIONAL MATCH (o:Class)<-[r:SUBCLASSOF|INSTANCEOF]-(primary) WITH CASE WHEN o IS NULL THEN [] ELSE COLLECT ({ short_form: o.short_form, label: coalesce(o.label,''), iri: o.iri, types: labels(o), symbol: coalesce(o.`IAO_0000028`[0], '')} ) END AS parents ,primary OPTIONAL MATCH (o)<-[r {type:'Related'}]-(primary) WITH CASE WHEN o IS NULL THEN [] ELSE COLLECT ({ relation: { label: r.label, iri: r.iri, type: type(r) } , object: { short_form: o.short_form, label: coalesce(o.label,''), iri: o.iri, types: labels(o), symbol: coalesce(o.`IAO_0000028`[0], '')} }) END AS relationships ,primary,parents OPTIONAL MATCH (o:Individual)<-[r {type:'Related'}]-(primary) WITH CASE WHEN o IS NULL THEN [] ELSE COLLECT ({ relation: { label: r.label, iri: r.iri, type: type(r) } , object: { short_form: o.short_form, label: coalesce(o.label,''), iri: o.iri, types: labels(o), symbol: coalesce(o.`IAO_0000028`[0], '')} }) END AS related_individuals ,primary,parents,relationships OPTIONAL MATCH (s:Site { short_form: primary.self_xref }) WITH CASE WHEN s IS NULL THEN [] ELSE COLLECT({ link_base: coalesce(s.link_base[0], ''), accession: coalesce(primary.short_form, ''), link_text: primary.label + ' on ' + s.label, homepage: coalesce(s.homepage[0], ''), site: { short_form: s.short_form, label: coalesce(s.label,''), iri: s.iri, types: labels(s), symbol: coalesce(s.`IAO_0000028`[0], '')} , icon: coalesce(s.link_icon_url[0], ''), link_postfix: coalesce(s.link_postfix, '')}) END AS self_xref, primary, parents, relationships, related_individuals OPTIONAL MATCH (s:Site)<-[dbx:database_cross_reference]-(primary) WITH CASE WHEN s IS NULL THEN self_xref ELSE COLLECT({ link_base: coalesce(s.link_base[0], ''), accession: coalesce(dbx.accession[0], ''), link_text: primary.label + ' on ' + s.label, homepage: coalesce(s.homepage[0], ''), site: { short_form: s.short_form, label: coalesce(s.label,''), iri: s.iri, types: labels(s), symbol: coalesce(s.`IAO_0000028`[0], '')} , icon: coalesce(s.link_icon_url[0], ''), link_postfix: coalesce(s.link_postfix, '')}) + self_xref END AS xrefs,primary,parents,relationships,related_individuals CALL apoc.cypher.run('WITH primary OPTIONAL MATCH (primary)<-[:has_source|SUBCLASSOF|INSTANCEOF*]-(i:Individual)<-[:depicts]-(channel:Individual)-[irw:in_register_with] ->(template:Individual)-[:depicts]->(template_anat:Individual) RETURN template, channel, template_anat, i, irw limit 5', {primary:primary}) yield value with value.template as template, value.channel as channel,value.template_anat as template_anat, value.i as i, value.irw as irw, primary, parents, relationships, related_individuals, xrefs OPTIONAL MATCH (channel)-[:is_specified_output_of]->(technique:Class) WITH CASE WHEN channel IS NULL THEN [] ELSE COLLECT({ anatomy: { short_form: i.short_form, label: coalesce(i.label,''), iri: i.iri, types: labels(i), symbol: coalesce(i.`IAO_0000028`[0], '')} , channel_image: { channel: { short_form: channel.short_form, label: coalesce(channel.label,''), iri: channel.iri, types: labels(channel), symbol: coalesce(channel.`IAO_0000028`[0], '')} , imaging_technique: { short_form: technique.short_form, label: coalesce(technique.label,''), iri: technique.iri, types: labels(technique), symbol: coalesce(technique.`IAO_0000028`[0], '')} ,image: { template_channel : { short_form: template.short_form, label: coalesce(template.label,''), iri: template.iri, types: labels(template), symbol: coalesce(template.`IAO_0000028`[0], '')} , template_anatomy: { short_form: template_anat.short_form, label: coalesce(template_anat.label,''), iri: template_anat.iri, types: labels(template_anat), symbol: coalesce(template_anat.`IAO_0000028`[0], '')} ,image_folder: COALESCE(irw.folder[0], ''), index: coalesce(apoc.convert.toInteger(irw.index[0]), []) + [] }} }) END AS anatomy_channel_image ,primary,parents,relationships,related_individuals,xrefs OPTIONAL MATCH (primary)-[rp:has_reference]->(p:pub) where rp.typ = 'syn' WITH CASE WHEN p is null THEN [] ELSE collect({ pub: { core: { short_form: p.short_form, label: coalesce(p.label,''), iri: p.iri, types: labels(p), symbol: coalesce(p.`IAO_0000028`[0], '')} , PubMed: coalesce(p.PMID[0], ''), FlyBase: coalesce(p.FlyBase[0], ''), DOI: coalesce(p.DOI[0], '') } , synonym: { label: coalesce(rp.value, ''), scope: coalesce(rp.scope, ''), type: coalesce(rp.has_synonym_type,'') } }) END AS pub_syn,primary,parents,relationships,related_individuals,xrefs,anatomy_channel_image OPTIONAL MATCH (primary)-[rp:has_reference]->(p:pub) WHERE rp.typ = 'def' WITH CASE WHEN p is null THEN [] ELSE collect({ core: { short_form: p.short_form, label: coalesce(p.label,''), iri: p.iri, types: labels(p), symbol: coalesce(p.`IAO_0000028`[0], '')} , PubMed: coalesce(p.PMID[0], ''), FlyBase: coalesce(p.FlyBase[0], ''), DOI: coalesce(p.DOI[0], '') } ) END AS def_pubs,primary,parents,relationships,related_individuals,xrefs,anatomy_channel_image,pub_syn OPTIONAL MATCH (:Class { label: 'intersectional expression pattern'})<-[:SUBCLASSOF]-(ep:Class)<-[ar:part_of]-(anoni:Individual)-[:INSTANCEOF]->(primary) WITH CASE WHEN ep IS NULL THEN [] ELSE COLLECT({ short_form: ep.short_form, label: coalesce(ep.label,''), iri: ep.iri, types: labels(ep), symbol: coalesce(ep.`IAO_0000028`[0], '')} ) END AS targeting_splits,primary,parents,relationships,related_individuals,xrefs,anatomy_channel_image,pub_syn,def_pubs RETURN { core : { short_form: primary.short_form, label: coalesce(primary.label,''), iri: primary.iri, types: labels(primary), symbol: coalesce(primary.`IAO_0000028`[0], '')} , description : coalesce(primary.description, []), comment : coalesce(primary.comment, []) } AS term, 'Get JSON for Neuron Class' AS query, '58214d4' AS version , parents, relationships, related_individuals, xrefs, anatomy_channel_image, pub_syn, def_pubs, targeting_splits", "parameters" : { "ID" : "$ID" }" + query=""statement": "MATCH (primary:Class) WHERE primary.short_form in [{ID}] WITH primary OPTIONAL MATCH (o:Class)<-[r:SUBCLASSOF|INSTANCEOF]-(primary) WITH CASE WHEN o IS NULL THEN [] ELSE COLLECT ({ short_form: o.short_form, label: coalesce(o.label,''), iri: o.iri, types: labels(o) } ) END AS parents ,primary OPTIONAL MATCH (o:Class)<-[r {type:'Related'}]-(primary) WITH CASE WHEN o IS NULL THEN [] ELSE COLLECT ({ relation: { label: r.label, iri: r.uri, type: type(r) } , object: { short_form: o.short_form, label: coalesce(o.label,''), iri: o.iri, types: labels(o) } }) END AS relationships ,primary,parents OPTIONAL MATCH (o:Individual)<-[r {type:'Related'}]-(primary) WITH CASE WHEN o IS NULL THEN [] ELSE COLLECT ({ relation: { label: r.label, iri: r.uri, type: type(r) } , object: { short_form: o.short_form, label: coalesce(o.label,''), iri: o.iri, types: labels(o) } }) END AS related_individuals ,primary,parents,relationships OPTIONAL MATCH (s:Site { short_form: primary.self_xref }) WITH CASE WHEN s IS NULL THEN [] ELSE COLLECT({ link_base: s.link_base, accession: coalesce(primary.short_form, ''), link_text: primary.label + ' on ' + s.label, site: { short_form: s.short_form, label: coalesce(s.label,''), iri: s.iri, types: labels(s) } , icon: coalesce(s.link_icon_url, ''), link_postfix: coalesce(s.link_postfix, '')}) END AS self_xref, primary, parents, relationships, related_individuals OPTIONAL MATCH (s:Site)<-[dbx:hasDbXref]-(primary) WITH CASE WHEN s IS NULL THEN self_xref ELSE COLLECT({ link_base: s.link_base, accession: coalesce(dbx.accession, ''), link_text: primary.label + ' on ' + s.label, site: { short_form: s.short_form, label: coalesce(s.label,''), iri: s.iri, types: labels(s) } , icon: coalesce(s.link_icon_url, ''), link_postfix: coalesce(s.link_postfix, '')}) + self_xref END AS xrefs,primary,parents,relationships,related_individuals OPTIONAL MATCH (primary)<-[:has_source|SUBCLASSOF|INSTANCEOF*]-(i:Individual)<-[:depicts]-(channel:Individual)-[irw:in_register_with]->(template:Individual)-[:depicts]->(template_anat:Individual) WITH template, channel, template_anat, irw, primary, parents, relationships, related_individuals, xrefs , i limit 5 OPTIONAL MATCH (channel)-[:is_specified_output_of]->(technique:Class) WITH CASE WHEN channel IS NULL THEN [] ELSE COLLECT({ anatomy: { short_form: i.short_form, label: coalesce(i.label,''), iri: i.iri, types: labels(i) } , channel_image: { channel: { short_form: channel.short_form, label: coalesce(channel.label,''), iri: channel.iri, types: labels(channel) } , imaging_technique: { short_form: technique.short_form, label: coalesce(technique.label,''), iri: technique.iri, types: labels(technique) } ,image: { template_channel : { short_form: template.short_form, label: coalesce(template.label,''), iri: template.iri, types: labels(template) } , template_anatomy: { short_form: template_anat.short_form, label: coalesce(template_anat.label,''), iri: template_anat.iri, types: labels(template_anat) } ,image_folder: irw.folder, index: coalesce(irw.index, []) + [] }} }) END AS anatomy_channel_image ,primary,parents,relationships,related_individuals,xrefs OPTIONAL MATCH (primary)-[rp:has_reference { typ: 'syn'}]->(p:pub) WITH CASE WHEN p is null THEN [] ELSE collect({ pub: { core: { short_form: p.short_form, label: coalesce(p.label,''), iri: p.iri, types: labels(p) } , PubMed: coalesce(p.PMID, ''), FlyBase: coalesce(p.FlyBase, ''), DOI: coalesce(p.DOI, '') } , synonym: { label: coalesce(rp.synonym, ''), scope: coalesce(rp.scope, ''), type: coalesce(rp.cat,'') } }) END AS pub_syn,primary,parents,relationships,related_individuals,xrefs,anatomy_channel_image OPTIONAL MATCH (primary)-[rp:has_reference { typ: 'def'}]->(p:pub) WITH CASE WHEN p is null THEN [] ELSE collect({ core: { short_form: p.short_form, label: coalesce(p.label,''), iri: p.iri, types: labels(p) } , PubMed: coalesce(p.PMID, ''), FlyBase: coalesce(p.FlyBase, ''), DOI: coalesce(p.DOI, '') } ) END AS def_pubs,primary,parents,relationships,related_individuals,xrefs,anatomy_channel_image,pub_syn OPTIONAL MATCH (:Class { label: 'intersectional expression pattern'})<-[:SUBCLASSOF]-(ep:Class)<-[ar:part_of]-(anoni:Individual)-[:INSTANCEOF]->(primary) WITH COLLECT({ short_form: ep.short_form, label: coalesce(ep.label,''), iri: ep.iri, types: labels(ep) } ) as targeting_splits,primary,parents,relationships,related_individuals,xrefs,anatomy_channel_image,pub_syn,def_pubs RETURN { core : { short_form: primary.short_form, label: coalesce(primary.label,''), iri: primary.iri, types: labels(primary) } , description : coalesce(primary.description, []), comment : coalesce(primary.`annotation-comment`, []) } AS term, 'Get JSON for Neuron Class' AS query, '2e501bd' AS version , parents, relationships, related_individuals, xrefs, anatomy_channel_image, pub_syn, def_pubs, targeting_splits", "parameters" : { "ID" : "$ID" }" countQuery=""statement": "MATCH (primary:Class {short_form: {ID}} ) RETURN count(primary) as count", "parameters" : { "ID" : "$ID" }"> @@ -495,7 +495,7 @@ name="Get JSON for Split Class" description="Get JSON for Split Class" runForCount="false" - query=""statement": "MATCH (primary:Class) WHERE primary.short_form in [{ID}] WITH primary OPTIONAL MATCH (o:Class)<-[r:SUBCLASSOF|INSTANCEOF]-(primary) WITH CASE WHEN o IS NULL THEN [] ELSE COLLECT ({ short_form: o.short_form, label: coalesce(o.label,''), iri: o.iri, types: labels(o), symbol: coalesce(o.`IAO_0000028`[0], '')} ) END AS parents ,primary OPTIONAL MATCH (o)<-[r {type:'Related'}]-(primary) WITH CASE WHEN o IS NULL THEN [] ELSE COLLECT ({ relation: { label: r.label, iri: r.iri, type: type(r) } , object: { short_form: o.short_form, label: coalesce(o.label,''), iri: o.iri, types: labels(o), symbol: coalesce(o.`IAO_0000028`[0], '')} }) END AS relationships ,primary,parents OPTIONAL MATCH (o:Individual)<-[r {type:'Related'}]-(primary) WITH CASE WHEN o IS NULL THEN [] ELSE COLLECT ({ relation: { label: r.label, iri: r.iri, type: type(r) } , object: { short_form: o.short_form, label: coalesce(o.label,''), iri: o.iri, types: labels(o), symbol: coalesce(o.`IAO_0000028`[0], '')} }) END AS related_individuals ,primary,parents,relationships OPTIONAL MATCH (s:Site { short_form: primary.self_xref }) WITH CASE WHEN s IS NULL THEN [] ELSE COLLECT({ link_base: coalesce(s.link_base[0], ''), accession: coalesce(primary.short_form, ''), link_text: primary.label + ' on ' + s.label, homepage: coalesce(s.homepage[0], ''), site: { short_form: s.short_form, label: coalesce(s.label,''), iri: s.iri, types: labels(s), symbol: coalesce(s.`IAO_0000028`[0], '')} , icon: coalesce(s.link_icon_url[0], ''), link_postfix: coalesce(s.link_postfix, '')}) END AS self_xref, primary, parents, relationships, related_individuals OPTIONAL MATCH (s:Site)<-[dbx:database_cross_reference]-(primary) WITH CASE WHEN s IS NULL THEN self_xref ELSE COLLECT({ link_base: coalesce(s.link_base[0], ''), accession: coalesce(dbx.accession[0], ''), link_text: primary.label + ' on ' + s.label, homepage: coalesce(s.homepage[0], ''), site: { short_form: s.short_form, label: coalesce(s.label,''), iri: s.iri, types: labels(s), symbol: coalesce(s.`IAO_0000028`[0], '')} , icon: coalesce(s.link_icon_url[0], ''), link_postfix: coalesce(s.link_postfix, '')}) + self_xref END AS xrefs,primary,parents,relationships,related_individuals CALL apoc.cypher.run('WITH primary OPTIONAL MATCH (primary)<-[:has_source|SUBCLASSOF|INSTANCEOF*]-(i:Individual)<-[:depicts]-(channel:Individual)-[irw:in_register_with] ->(template:Individual)-[:depicts]->(template_anat:Individual) RETURN template, channel, template_anat, i, irw limit 5', {primary:primary}) yield value with value.template as template, value.channel as channel,value.template_anat as template_anat, value.i as i, value.irw as irw, primary, parents, relationships, related_individuals, xrefs OPTIONAL MATCH (channel)-[:is_specified_output_of]->(technique:Class) WITH CASE WHEN channel IS NULL THEN [] ELSE COLLECT({ anatomy: { short_form: i.short_form, label: coalesce(i.label,''), iri: i.iri, types: labels(i), symbol: coalesce(i.`IAO_0000028`[0], '')} , channel_image: { channel: { short_form: channel.short_form, label: coalesce(channel.label,''), iri: channel.iri, types: labels(channel), symbol: coalesce(channel.`IAO_0000028`[0], '')} , imaging_technique: { short_form: technique.short_form, label: coalesce(technique.label,''), iri: technique.iri, types: labels(technique), symbol: coalesce(technique.`IAO_0000028`[0], '')} ,image: { template_channel : { short_form: template.short_form, label: coalesce(template.label,''), iri: template.iri, types: labels(template), symbol: coalesce(template.`IAO_0000028`[0], '')} , template_anatomy: { short_form: template_anat.short_form, label: coalesce(template_anat.label,''), iri: template_anat.iri, types: labels(template_anat), symbol: coalesce(template_anat.`IAO_0000028`[0], '')} ,image_folder: COALESCE(irw.folder[0], ''), index: coalesce(apoc.convert.toInteger(irw.index[0]), []) + [] }} }) END AS anatomy_channel_image ,primary,parents,relationships,related_individuals,xrefs OPTIONAL MATCH (primary)-[rp:has_reference]->(p:pub) where rp.typ = 'syn' WITH CASE WHEN p is null THEN [] ELSE collect({ pub: { core: { short_form: p.short_form, label: coalesce(p.label,''), iri: p.iri, types: labels(p), symbol: coalesce(p.`IAO_0000028`[0], '')} , PubMed: coalesce(p.PMID[0], ''), FlyBase: coalesce(p.FlyBase[0], ''), DOI: coalesce(p.DOI[0], '') } , synonym: { label: coalesce(rp.value, ''), scope: coalesce(rp.scope, ''), type: coalesce(rp.has_synonym_type,'') } }) END AS pub_syn,primary,parents,relationships,related_individuals,xrefs,anatomy_channel_image OPTIONAL MATCH (primary)-[rp:has_reference]->(p:pub) WHERE rp.typ = 'def' WITH CASE WHEN p is null THEN [] ELSE collect({ core: { short_form: p.short_form, label: coalesce(p.label,''), iri: p.iri, types: labels(p), symbol: coalesce(p.`IAO_0000028`[0], '')} , PubMed: coalesce(p.PMID[0], ''), FlyBase: coalesce(p.FlyBase[0], ''), DOI: coalesce(p.DOI[0], '') } ) END AS def_pubs,primary,parents,relationships,related_individuals,xrefs,anatomy_channel_image,pub_syn OPTIONAL MATCH (:Class { label: 'intersectional expression pattern'})<-[:SUBCLASSOF]-(primary)<-[ar:part_of]-(anoni:Individual)-[:INSTANCEOF]->(n:Neuron) WITH CASE WHEN n IS NULL THEN [] ELSE COLLECT({ short_form: n.short_form, label: coalesce(n.label,''), iri: n.iri, types: labels(n), symbol: coalesce(n.`IAO_0000028`[0], '')} ) END AS target_neurons,primary,parents,relationships,related_individuals,xrefs,anatomy_channel_image,pub_syn,def_pubs RETURN { core : { short_form: primary.short_form, label: coalesce(primary.label,''), iri: primary.iri, types: labels(primary), symbol: coalesce(primary.`IAO_0000028`[0], '')} , description : coalesce(primary.description, []), comment : coalesce(primary.comment, []) } AS term, 'Get JSON for Split Class' AS query, '58214d4' AS version , parents, relationships, related_individuals, xrefs, anatomy_channel_image, pub_syn, def_pubs, target_neurons", "parameters" : { "ID" : "$ID" }" + query=""statement": "MATCH (primary:Class) WHERE primary.short_form in [{ID}] WITH primary OPTIONAL MATCH (o:Class)<-[r:SUBCLASSOF|INSTANCEOF]-(primary) WITH CASE WHEN o IS NULL THEN [] ELSE COLLECT ({ short_form: o.short_form, label: coalesce(o.label,''), iri: o.iri, types: labels(o) } ) END AS parents ,primary OPTIONAL MATCH (o:Class)<-[r {type:'Related'}]-(primary) WITH CASE WHEN o IS NULL THEN [] ELSE COLLECT ({ relation: { label: r.label, iri: r.uri, type: type(r) } , object: { short_form: o.short_form, label: coalesce(o.label,''), iri: o.iri, types: labels(o) } }) END AS relationships ,primary,parents OPTIONAL MATCH (o:Individual)<-[r {type:'Related'}]-(primary) WITH CASE WHEN o IS NULL THEN [] ELSE COLLECT ({ relation: { label: r.label, iri: r.uri, type: type(r) } , object: { short_form: o.short_form, label: coalesce(o.label,''), iri: o.iri, types: labels(o) } }) END AS related_individuals ,primary,parents,relationships OPTIONAL MATCH (s:Site { short_form: primary.self_xref }) WITH CASE WHEN s IS NULL THEN [] ELSE COLLECT({ link_base: s.link_base, accession: coalesce(primary.short_form, ''), link_text: primary.label + ' on ' + s.label, site: { short_form: s.short_form, label: coalesce(s.label,''), iri: s.iri, types: labels(s) } , icon: coalesce(s.link_icon_url, ''), link_postfix: coalesce(s.link_postfix, '')}) END AS self_xref, primary, parents, relationships, related_individuals OPTIONAL MATCH (s:Site)<-[dbx:hasDbXref]-(primary) WITH CASE WHEN s IS NULL THEN self_xref ELSE COLLECT({ link_base: s.link_base, accession: coalesce(dbx.accession, ''), link_text: primary.label + ' on ' + s.label, site: { short_form: s.short_form, label: coalesce(s.label,''), iri: s.iri, types: labels(s) } , icon: coalesce(s.link_icon_url, ''), link_postfix: coalesce(s.link_postfix, '')}) + self_xref END AS xrefs,primary,parents,relationships,related_individuals OPTIONAL MATCH (primary)<-[:has_source|SUBCLASSOF|INSTANCEOF*]-(i:Individual)<-[:depicts]-(channel:Individual)-[irw:in_register_with]->(template:Individual)-[:depicts]->(template_anat:Individual) WITH template, channel, template_anat, irw, primary, parents, relationships, related_individuals, xrefs , i limit 5 OPTIONAL MATCH (channel)-[:is_specified_output_of]->(technique:Class) WITH CASE WHEN channel IS NULL THEN [] ELSE COLLECT({ anatomy: { short_form: i.short_form, label: coalesce(i.label,''), iri: i.iri, types: labels(i) } , channel_image: { channel: { short_form: channel.short_form, label: coalesce(channel.label,''), iri: channel.iri, types: labels(channel) } , imaging_technique: { short_form: technique.short_form, label: coalesce(technique.label,''), iri: technique.iri, types: labels(technique) } ,image: { template_channel : { short_form: template.short_form, label: coalesce(template.label,''), iri: template.iri, types: labels(template) } , template_anatomy: { short_form: template_anat.short_form, label: coalesce(template_anat.label,''), iri: template_anat.iri, types: labels(template_anat) } ,image_folder: irw.folder, index: coalesce(irw.index, []) + [] }} }) END AS anatomy_channel_image ,primary,parents,relationships,related_individuals,xrefs OPTIONAL MATCH (primary)-[rp:has_reference { typ: 'syn'}]->(p:pub) WITH CASE WHEN p is null THEN [] ELSE collect({ pub: { core: { short_form: p.short_form, label: coalesce(p.label,''), iri: p.iri, types: labels(p) } , PubMed: coalesce(p.PMID, ''), FlyBase: coalesce(p.FlyBase, ''), DOI: coalesce(p.DOI, '') } , synonym: { label: coalesce(rp.synonym, ''), scope: coalesce(rp.scope, ''), type: coalesce(rp.cat,'') } }) END AS pub_syn,primary,parents,relationships,related_individuals,xrefs,anatomy_channel_image OPTIONAL MATCH (primary)-[rp:has_reference { typ: 'def'}]->(p:pub) WITH CASE WHEN p is null THEN [] ELSE collect({ core: { short_form: p.short_form, label: coalesce(p.label,''), iri: p.iri, types: labels(p) } , PubMed: coalesce(p.PMID, ''), FlyBase: coalesce(p.FlyBase, ''), DOI: coalesce(p.DOI, '') } ) END AS def_pubs,primary,parents,relationships,related_individuals,xrefs,anatomy_channel_image,pub_syn OPTIONAL MATCH (:Class { label: 'intersectional expression pattern'})<-[:SUBCLASSOF]-(primary)<-[ar:part_of]-(anoni:Individual)-[:INSTANCEOF]->(n:Neuron) WITH COLLECT({ short_form: n.short_form, label: coalesce(n.label,''), iri: n.iri, types: labels(n) } ) as target_neurons,primary,parents,relationships,related_individuals,xrefs,anatomy_channel_image,pub_syn,def_pubs RETURN { core : { short_form: primary.short_form, label: coalesce(primary.label,''), iri: primary.iri, types: labels(primary) } , description : coalesce(primary.description, []), comment : coalesce(primary.`annotation-comment`, []) } AS term, 'Get JSON for Split Class' AS query, '2e501bd' AS version , parents, relationships, related_individuals, xrefs, anatomy_channel_image, pub_syn, def_pubs, target_neurons", "parameters" : { "ID" : "$ID" }" countQuery=""statement": "MATCH (primary:Class {short_form: {ID}} ) RETURN count(primary) as count", "parameters" : { "ID" : "$ID" }"> @@ -505,7 +505,7 @@ name="Get JSON for Individual" description="Get JSON for Individual:Anatomy" runForCount="false" - query=""statement": "MATCH (primary:Individual:Anatomy) WHERE primary.short_form in [{ID}] WITH primary OPTIONAL MATCH (primary)-[:has_source]-(ds:DataSet)-[:has_license]->(l:License) WITH COLLECT ({ dataset: { link : coalesce(ds.dataset_link[0], ''), core : { short_form: ds.short_form, label: coalesce(ds.label,''), iri: ds.iri, types: labels(ds), symbol: coalesce(ds.`IAO_0000028`[0], '')} }, license: { icon : coalesce(l.license_logo[0], ''), link : coalesce(l.license_url[0], ''), core : { short_form: l.short_form, label: coalesce(l.label,''), iri: l.iri, types: labels(l), symbol: coalesce(l.`IAO_0000028`[0], '')} }}) AS dataset_license,primary OPTIONAL MATCH (o:Class)<-[r:SUBCLASSOF|INSTANCEOF]-(primary) WITH CASE WHEN o IS NULL THEN [] ELSE COLLECT ({ short_form: o.short_form, label: coalesce(o.label,''), iri: o.iri, types: labels(o), symbol: coalesce(o.`IAO_0000028`[0], '')} ) END AS parents ,primary,dataset_license OPTIONAL MATCH (o)<-[r {type:'Related'}]-(primary) WITH CASE WHEN o IS NULL THEN [] ELSE COLLECT ({ relation: { label: r.label, iri: r.iri, type: type(r) } , object: { short_form: o.short_form, label: coalesce(o.label,''), iri: o.iri, types: labels(o), symbol: coalesce(o.`IAO_0000028`[0], '')} }) END AS relationships ,primary,dataset_license,parents OPTIONAL MATCH (s:Site { short_form: primary.self_xref }) WITH CASE WHEN s IS NULL THEN [] ELSE COLLECT({ link_base: coalesce(s.link_base[0], ''), accession: coalesce(primary.short_form, ''), link_text: primary.label + ' on ' + s.label, homepage: coalesce(s.homepage[0], ''), site: { short_form: s.short_form, label: coalesce(s.label,''), iri: s.iri, types: labels(s), symbol: coalesce(s.`IAO_0000028`[0], '')} , icon: coalesce(s.link_icon_url[0], ''), link_postfix: coalesce(s.link_postfix, '')}) END AS self_xref, primary, dataset_license, parents, relationships OPTIONAL MATCH (s:Site)<-[dbx:database_cross_reference]-(primary) WITH CASE WHEN s IS NULL THEN self_xref ELSE COLLECT({ link_base: coalesce(s.link_base[0], ''), accession: coalesce(dbx.accession[0], ''), link_text: primary.label + ' on ' + s.label, homepage: coalesce(s.homepage[0], ''), site: { short_form: s.short_form, label: coalesce(s.label,''), iri: s.iri, types: labels(s), symbol: coalesce(s.`IAO_0000028`[0], '')} , icon: coalesce(s.link_icon_url[0], ''), link_postfix: coalesce(s.link_postfix, '')}) + self_xref END AS xrefs,primary,dataset_license,parents,relationships OPTIONAL MATCH (primary)<-[:depicts]-(channel:Individual)-[irw:in_register_with]->(template:Individual)-[:depicts]->(template_anat:Individual) WITH template, channel, template_anat, irw, primary, dataset_license, parents, relationships, xrefs OPTIONAL MATCH (channel)-[:is_specified_output_of]->(technique:Class) WITH CASE WHEN channel IS NULL THEN [] ELSE collect ({ channel: { short_form: channel.short_form, label: coalesce(channel.label,''), iri: channel.iri, types: labels(channel), symbol: coalesce(channel.`IAO_0000028`[0], '')} , imaging_technique: { short_form: technique.short_form, label: coalesce(technique.label,''), iri: technique.iri, types: labels(technique), symbol: coalesce(technique.`IAO_0000028`[0], '')} ,image: { template_channel : { short_form: template.short_form, label: coalesce(template.label,''), iri: template.iri, types: labels(template), symbol: coalesce(template.`IAO_0000028`[0], '')} , template_anatomy: { short_form: template_anat.short_form, label: coalesce(template_anat.label,''), iri: template_anat.iri, types: labels(template_anat), symbol: coalesce(template_anat.`IAO_0000028`[0], '')} ,image_folder: COALESCE(irw.folder[0], ''), index: coalesce(apoc.convert.toInteger(irw.index[0]), []) + [] }}) END AS channel_image,primary,dataset_license,parents,relationships,xrefs OPTIONAL MATCH (o:Individual)<-[r {type:'Related'}]-(primary) WITH CASE WHEN o IS NULL THEN [] ELSE COLLECT ({ relation: { label: r.label, iri: r.iri, type: type(r) } , object: { short_form: o.short_form, label: coalesce(o.label,''), iri: o.iri, types: labels(o), symbol: coalesce(o.`IAO_0000028`[0], '')} }) END AS related_individuals ,primary,dataset_license,parents,relationships,xrefs,channel_image RETURN { core : { short_form: primary.short_form, label: coalesce(primary.label,''), iri: primary.iri, types: labels(primary), symbol: coalesce(primary.`IAO_0000028`[0], '')} , description : coalesce(primary.description, []), comment : coalesce(primary.comment, []) } AS term, 'Get JSON for Individual:Anatomy' AS query, '58214d4' AS version , dataset_license, parents, relationships, xrefs, channel_image, related_individuals", "parameters" : { "ID" : "$ID" }" + query=""statement": "MATCH (primary:Individual:Anatomy) WHERE primary.short_form in [{ID}] WITH primary OPTIONAL MATCH (primary)-[:has_source]->(ds:DataSet)-[:has_license]->(l:License) WITH COLLECT ({ dataset: { link : coalesce(ds.dataset_link, ''), core : { short_form: ds.short_form, label: coalesce(ds.label,''), iri: ds.iri, types: labels(ds) } }, license: { icon : coalesce(l.license_logo, ''), link : coalesce(l.license_url, ''), core : { short_form: l.short_form, label: coalesce(l.label,''), iri: l.iri, types: labels(l) } }}) AS dataset_license,primary OPTIONAL MATCH (o:Class)<-[r:SUBCLASSOF|INSTANCEOF]-(primary) WITH CASE WHEN o IS NULL THEN [] ELSE COLLECT ({ short_form: o.short_form, label: coalesce(o.label,''), iri: o.iri, types: labels(o) } ) END AS parents ,primary,dataset_license OPTIONAL MATCH (o:Class)<-[r {type:'Related'}]-(primary) WITH CASE WHEN o IS NULL THEN [] ELSE COLLECT ({ relation: { label: r.label, iri: r.uri, type: type(r) } , object: { short_form: o.short_form, label: coalesce(o.label,''), iri: o.iri, types: labels(o) } }) END AS relationships ,primary,dataset_license,parents OPTIONAL MATCH (s:Site { short_form: primary.self_xref }) WITH CASE WHEN s IS NULL THEN [] ELSE COLLECT({ link_base: s.link_base, accession: coalesce(primary.short_form, ''), link_text: primary.label + ' on ' + s.label, site: { short_form: s.short_form, label: coalesce(s.label,''), iri: s.iri, types: labels(s) } , icon: coalesce(s.link_icon_url, ''), link_postfix: coalesce(s.link_postfix, '')}) END AS self_xref, primary, dataset_license, parents, relationships OPTIONAL MATCH (s:Site)<-[dbx:hasDbXref]-(primary) WITH CASE WHEN s IS NULL THEN self_xref ELSE COLLECT({ link_base: s.link_base, accession: coalesce(dbx.accession, ''), link_text: primary.label + ' on ' + s.label, site: { short_form: s.short_form, label: coalesce(s.label,''), iri: s.iri, types: labels(s) } , icon: coalesce(s.link_icon_url, ''), link_postfix: coalesce(s.link_postfix, '')}) + self_xref END AS xrefs,primary,dataset_license,parents,relationships OPTIONAL MATCH (primary)<-[:depicts]-(channel:Individual)-[irw:in_register_with]->(template:Individual)-[:depicts]->(template_anat:Individual) WITH template, channel, template_anat, irw, primary, dataset_license, parents, relationships, xrefs OPTIONAL MATCH (channel)-[:is_specified_output_of]->(technique:Class) WITH CASE WHEN channel IS NULL THEN [] ELSE collect ({ channel: { short_form: channel.short_form, label: coalesce(channel.label,''), iri: channel.iri, types: labels(channel) } , imaging_technique: { short_form: technique.short_form, label: coalesce(technique.label,''), iri: technique.iri, types: labels(technique) } ,image: { template_channel : { short_form: template.short_form, label: coalesce(template.label,''), iri: template.iri, types: labels(template) } , template_anatomy: { short_form: template_anat.short_form, label: coalesce(template_anat.label,''), iri: template_anat.iri, types: labels(template_anat) } ,image_folder: irw.folder, index: coalesce(irw.index, []) + [] }}) END AS channel_image,primary,dataset_license,parents,relationships,xrefs OPTIONAL MATCH (o:Individual)<-[r {type:'Related'}]-(primary) WITH CASE WHEN o IS NULL THEN [] ELSE COLLECT ({ relation: { label: r.label, iri: r.uri, type: type(r) } , object: { short_form: o.short_form, label: coalesce(o.label,''), iri: o.iri, types: labels(o) } }) END AS related_individuals ,primary,dataset_license,parents,relationships,xrefs,channel_image RETURN { core : { short_form: primary.short_form, label: coalesce(primary.label,''), iri: primary.iri, types: labels(primary) } , description : coalesce(primary.description, []), comment : coalesce(primary.`annotation-comment`, []) } AS term, 'Get JSON for Individual:Anatomy' AS query, 'ca9ab19' AS version , dataset_license, parents, relationships, xrefs, channel_image, related_individuals", "parameters" : { "ID" : "$ID" }" countQuery=""statement": "MATCH (primary:Individual {short_form: {ID}} ) RETURN count(primary) as count", "parameters" : { "ID" : "$ID" }"> @@ -515,7 +515,7 @@ name="Get JSON for Template" description="Get JSON for Template" runForCount="false" - query=""statement": "MATCH (primary:Template) WHERE primary.short_form in [{ID}] WITH primary MATCH (channel:Individual)<-[irw:in_register_with]-(channel:Individual)-[:depicts]->(primary) WITH { index: coalesce(apoc.convert.toInteger(irw.index), []) + [], extent: irw.extent[0], center: irw.center[0], voxel: irw.voxel[0], orientation: coalesce(irw.orientation[0], ''), image_folder: coalesce(irw.folder[0],''), channel: { short_form: channel.short_form, label: coalesce(channel.label,''), iri: channel.iri, types: labels(channel), symbol: coalesce(channel.`IAO_0000028`[0], '')} } as template_channel,primary OPTIONAL MATCH (technique:Class)<-[:is_specified_output_of]-(channel:Individual)-[irw:in_register_with]->(template:Individual)-[:depicts]->(primary) WHERE technique.short_form = 'FBbi_00000224' AND exists(irw.index) WITH primary, template_channel, collect ({ channel: channel, irw: irw}) AS painted_domains UNWIND painted_domains AS pd MATCH (channel:Individual { short_form: pd.channel.short_form})-[:depicts]-(ai:Individual)-[:INSTANCEOF]->(c:Class) WITH collect({ anatomical_type: { short_form: c.short_form, label: coalesce(c.label,''), iri: c.iri, types: labels(c), symbol: coalesce(c.`IAO_0000028`[0], '')} , anatomical_individual: { short_form: ai.short_form, label: coalesce(ai.label,''), iri: ai.iri, types: labels(ai), symbol: coalesce(ai.`IAO_0000028`[0], '')} , folder: pd.irw.folder[0], center: coalesce (pd.irw.center, []), index: [] + coalesce (pd.irw.index, []) }) AS template_domains,primary,template_channel OPTIONAL MATCH (primary)-[:has_source]-(ds:DataSet)-[:has_license]->(l:License) WITH COLLECT ({ dataset: { link : coalesce(ds.dataset_link[0], ''), core : { short_form: ds.short_form, label: coalesce(ds.label,''), iri: ds.iri, types: labels(ds), symbol: coalesce(ds.`IAO_0000028`[0], '')} }, license: { icon : coalesce(l.license_logo[0], ''), link : coalesce(l.license_url[0], ''), core : { short_form: l.short_form, label: coalesce(l.label,''), iri: l.iri, types: labels(l), symbol: coalesce(l.`IAO_0000028`[0], '')} }}) AS dataset_license,primary,template_channel,template_domains OPTIONAL MATCH (o:Class)<-[r:SUBCLASSOF|INSTANCEOF]-(primary) WITH CASE WHEN o IS NULL THEN [] ELSE COLLECT ({ short_form: o.short_form, label: coalesce(o.label,''), iri: o.iri, types: labels(o), symbol: coalesce(o.`IAO_0000028`[0], '')} ) END AS parents ,primary,template_channel,template_domains,dataset_license OPTIONAL MATCH (o)<-[r {type:'Related'}]-(primary) WITH CASE WHEN o IS NULL THEN [] ELSE COLLECT ({ relation: { label: r.label, iri: r.iri, type: type(r) } , object: { short_form: o.short_form, label: coalesce(o.label,''), iri: o.iri, types: labels(o), symbol: coalesce(o.`IAO_0000028`[0], '')} }) END AS relationships ,primary,template_channel,template_domains,dataset_license,parents OPTIONAL MATCH (s:Site { short_form: primary.self_xref }) WITH CASE WHEN s IS NULL THEN [] ELSE COLLECT({ link_base: coalesce(s.link_base[0], ''), accession: coalesce(primary.short_form, ''), link_text: primary.label + ' on ' + s.label, homepage: coalesce(s.homepage[0], ''), site: { short_form: s.short_form, label: coalesce(s.label,''), iri: s.iri, types: labels(s), symbol: coalesce(s.`IAO_0000028`[0], '')} , icon: coalesce(s.link_icon_url[0], ''), link_postfix: coalesce(s.link_postfix, '')}) END AS self_xref, primary, template_channel, template_domains, dataset_license, parents, relationships OPTIONAL MATCH (s:Site)<-[dbx:database_cross_reference]-(primary) WITH CASE WHEN s IS NULL THEN self_xref ELSE COLLECT({ link_base: coalesce(s.link_base[0], ''), accession: coalesce(dbx.accession[0], ''), link_text: primary.label + ' on ' + s.label, homepage: coalesce(s.homepage[0], ''), site: { short_form: s.short_form, label: coalesce(s.label,''), iri: s.iri, types: labels(s), symbol: coalesce(s.`IAO_0000028`[0], '')} , icon: coalesce(s.link_icon_url[0], ''), link_postfix: coalesce(s.link_postfix, '')}) + self_xref END AS xrefs,primary,template_channel,template_domains,dataset_license,parents,relationships OPTIONAL MATCH (o:Individual)<-[r {type:'Related'}]-(primary) WITH CASE WHEN o IS NULL THEN [] ELSE COLLECT ({ relation: { label: r.label, iri: r.iri, type: type(r) } , object: { short_form: o.short_form, label: coalesce(o.label,''), iri: o.iri, types: labels(o), symbol: coalesce(o.`IAO_0000028`[0], '')} }) END AS related_individuals ,primary,template_channel,template_domains,dataset_license,parents,relationships,xrefs RETURN { core : { short_form: primary.short_form, label: coalesce(primary.label,''), iri: primary.iri, types: labels(primary), symbol: coalesce(primary.`IAO_0000028`[0], '')} , description : coalesce(primary.description, []), comment : coalesce(primary.comment, []) } AS term, 'Get JSON for Template' AS query, '58214d4' AS version , template_channel, template_domains, dataset_license, parents, relationships, xrefs, related_individuals", "parameters" : { "ID" : "$ID" }" + query=""statement": "MATCH (primary:Template) WHERE primary.short_form in [{ID}] WITH primary MATCH (channel:Individual)<-[irw:in_register_with]-(channel:Individual)-[:depicts]->(primary) WITH { index: coalesce(irw.index, []) + [], extent: irw.extent, center: irw.center, voxel: irw.voxel, orientation: irw.orientation, image_folder: irw.folder, channel: { short_form: channel.short_form, label: coalesce(channel.label,''), iri: channel.iri, types: labels(channel) } } as template_channel,primary OPTIONAL MATCH (technique:Class)<-[:is_specified_output_of]-(channel:Individual)-[irw:in_register_with]->(template:Individual)-[:depicts]->(primary) WHERE has(irw.index) WITH primary, template_channel, collect ({ channel: channel, irw: irw}) AS painted_domains UNWIND painted_domains AS pd MATCH (channel:Individual { short_form: pd.channel.short_form})-[:depicts]-(ai:Individual)-[:INSTANCEOF]->(c:Class) WITH collect({ anatomical_type: { short_form: c.short_form, label: coalesce(c.label,''), iri: c.iri, types: labels(c) } , anatomical_individual: { short_form: ai.short_form, label: coalesce(ai.label,''), iri: ai.iri, types: labels(ai) } , folder: pd.irw.folder, center: coalesce (pd.irw.center, []), index: [] + coalesce (pd.irw.index, []) }) AS template_domains,primary,template_channel OPTIONAL MATCH (primary)-[:has_source]->(ds:DataSet)-[:has_license]->(l:License) WITH COLLECT ({ dataset: { link : coalesce(ds.dataset_link, ''), core : { short_form: ds.short_form, label: coalesce(ds.label,''), iri: ds.iri, types: labels(ds) } }, license: { icon : coalesce(l.license_logo, ''), link : coalesce(l.license_url, ''), core : { short_form: l.short_form, label: coalesce(l.label,''), iri: l.iri, types: labels(l) } }}) AS dataset_license,primary,template_channel,template_domains OPTIONAL MATCH (o:Class)<-[r:SUBCLASSOF|INSTANCEOF]-(primary) WITH CASE WHEN o IS NULL THEN [] ELSE COLLECT ({ short_form: o.short_form, label: coalesce(o.label,''), iri: o.iri, types: labels(o) } ) END AS parents ,primary,template_channel,template_domains,dataset_license OPTIONAL MATCH (o:Class)<-[r {type:'Related'}]-(primary) WITH CASE WHEN o IS NULL THEN [] ELSE COLLECT ({ relation: { label: r.label, iri: r.uri, type: type(r) } , object: { short_form: o.short_form, label: coalesce(o.label,''), iri: o.iri, types: labels(o) } }) END AS relationships ,primary,template_channel,template_domains,dataset_license,parents OPTIONAL MATCH (s:Site { short_form: primary.self_xref }) WITH CASE WHEN s IS NULL THEN [] ELSE COLLECT({ link_base: s.link_base, accession: coalesce(primary.short_form, ''), link_text: primary.label + ' on ' + s.label, site: { short_form: s.short_form, label: coalesce(s.label,''), iri: s.iri, types: labels(s) } , icon: coalesce(s.link_icon_url, ''), link_postfix: coalesce(s.link_postfix, '')}) END AS self_xref, primary, template_channel, template_domains, dataset_license, parents, relationships OPTIONAL MATCH (s:Site)<-[dbx:hasDbXref]-(primary) WITH CASE WHEN s IS NULL THEN self_xref ELSE COLLECT({ link_base: s.link_base, accession: coalesce(dbx.accession, ''), link_text: primary.label + ' on ' + s.label, site: { short_form: s.short_form, label: coalesce(s.label,''), iri: s.iri, types: labels(s) } , icon: coalesce(s.link_icon_url, ''), link_postfix: coalesce(s.link_postfix, '')}) + self_xref END AS xrefs,primary,template_channel,template_domains,dataset_license,parents,relationships OPTIONAL MATCH (o:Individual)<-[r {type:'Related'}]-(primary) WITH CASE WHEN o IS NULL THEN [] ELSE COLLECT ({ relation: { label: r.label, iri: r.uri, type: type(r) } , object: { short_form: o.short_form, label: coalesce(o.label,''), iri: o.iri, types: labels(o) } }) END AS related_individuals ,primary,template_channel,template_domains,dataset_license,parents,relationships,xrefs RETURN { core : { short_form: primary.short_form, label: coalesce(primary.label,''), iri: primary.iri, types: labels(primary) } , description : coalesce(primary.description, []), comment : coalesce(primary.`annotation-comment`, []) } AS term, 'Get JSON for Template' AS query, 'ca9ab19' AS version , template_channel, template_domains, dataset_license, parents, relationships, xrefs, related_individuals", "parameters" : { "ID" : "$ID" }" countQuery=""statement": "MATCH (primary:Template {short_form: {ID}} ) RETURN count(primary) as count", "parameters" : { "ID" : "$ID" }"> @@ -525,7 +525,7 @@ name="Get JSON for pub" description="Fetches JSON for pub." runForCount="false" - query=""statement": "MATCH (primary:Individual:pub) WHERE primary.short_form in [{ID}] WITH primary OPTIONAL MATCH (primary)-[:has_reference]-(ds:DataSet)-[:has_license]->(l:License) WITH COLLECT ({ dataset: { link : coalesce(ds.dataset_link[0], ''), core : { short_form: ds.short_form, label: coalesce(ds.label,''), iri: ds.iri, types: labels(ds), symbol: coalesce(ds.`IAO_0000028`[0], '')} }, license: { icon : coalesce(l.license_logo[0], ''), link : coalesce(l.license_url[0], ''), core : { short_form: l.short_form, label: coalesce(l.label,''), iri: l.iri, types: labels(l), symbol: coalesce(l.`IAO_0000028`[0], '')} }}) AS dataset_license,primary RETURN { core : { short_form: primary.short_form, label: coalesce(primary.label,''), iri: primary.iri, types: labels(primary), symbol: coalesce(primary.`IAO_0000028`[0], '')} , description : coalesce(primary.description, []), comment : coalesce(primary.comment, []) } AS term, '58214d4' AS version , dataset_license, {title: coalesce(primary.title[0], '') ,PubMed: coalesce(primary.PMID[0], ''), FlyBase: coalesce(primary.FlyBase[0], ''), DOI: coalesce(primary.DOI[0], '') }AS pub_specific_content", "parameters" : { "ID" : "$ID" }" + query=""statement": "MATCH (primary:pub:Individual {short_form: {ID} }) OPTIONAL MATCH (o)-[r:has_reference]->(primary) WHERE o:DataSet OR o:Class WITH primary, r, o ORDER BY labels(o)[0] DESC, o.label ASC WITH CASE WHEN o IS NULL THEN [] ELSE COLLECT (DISTINCT { relation: { label: r.label, iri: r.uri, type: type(r) }, object: { short_form: o.short_form, label: o.label, iri: o.iri, types: labels(o) } }) END AS relationships, primary RETURN { core: { short_form: primary.short_form, label: primary.label, iri: primary.iri, types: labels(primary) } , description: coalesce(primary.description, []), comment: coalesce(primary.`annotation-comment`, [])} as term, relationships, 'pub' as query, 'manual' AS version", "parameters" : { "ID" : "$ID" }" countQuery=""statement": "MATCH (primary:pub:Individual {short_form: {ID}} ) RETURN count(primary) as count", "parameters" : { "ID" : "$ID" }"> @@ -535,7 +535,7 @@ name="Get JSON for DataSet" description="Get JSON for DataSet" runForCount="false" - query=""statement": "MATCH (primary:DataSet) WHERE primary.short_form in [{ID}] WITH primary CALL apoc.cypher.run('WITH primary OPTIONAL MATCH (primary)<-[:has_source|SUBCLASSOF|INSTANCEOF*]-(i:Individual)<-[:depicts]-(channel:Individual)-[irw:in_register_with] ->(template:Individual)-[:depicts]->(template_anat:Individual) RETURN template, channel, template_anat, i, irw limit 5', {primary:primary}) yield value with value.template as template, value.channel as channel,value.template_anat as template_anat, value.i as i, value.irw as irw, primary OPTIONAL MATCH (channel)-[:is_specified_output_of]->(technique:Class) WITH CASE WHEN channel IS NULL THEN [] ELSE COLLECT({ anatomy: { short_form: i.short_form, label: coalesce(i.label,''), iri: i.iri, types: labels(i), symbol: coalesce(i.`IAO_0000028`[0], '')} , channel_image: { channel: { short_form: channel.short_form, label: coalesce(channel.label,''), iri: channel.iri, types: labels(channel), symbol: coalesce(channel.`IAO_0000028`[0], '')} , imaging_technique: { short_form: technique.short_form, label: coalesce(technique.label,''), iri: technique.iri, types: labels(technique), symbol: coalesce(technique.`IAO_0000028`[0], '')} ,image: { template_channel : { short_form: template.short_form, label: coalesce(template.label,''), iri: template.iri, types: labels(template), symbol: coalesce(template.`IAO_0000028`[0], '')} , template_anatomy: { short_form: template_anat.short_form, label: coalesce(template_anat.label,''), iri: template_anat.iri, types: labels(template_anat), symbol: coalesce(template_anat.`IAO_0000028`[0], '')} ,image_folder: COALESCE(irw.folder[0], ''), index: coalesce(apoc.convert.toInteger(irw.index[0]), []) + [] }} }) END AS anatomy_channel_image ,primary OPTIONAL MATCH (s:Site { short_form: primary.self_xref }) WITH CASE WHEN s IS NULL THEN [] ELSE COLLECT({ link_base: coalesce(s.link_base[0], ''), accession: coalesce(primary.short_form, ''), link_text: primary.label + ' on ' + s.label, homepage: coalesce(s.homepage[0], ''), site: { short_form: s.short_form, label: coalesce(s.label,''), iri: s.iri, types: labels(s), symbol: coalesce(s.`IAO_0000028`[0], '')} , icon: coalesce(s.link_icon_url[0], ''), link_postfix: coalesce(s.link_postfix, '')}) END AS self_xref, primary, anatomy_channel_image OPTIONAL MATCH (s:Site)<-[dbx:database_cross_reference]-(primary) WITH CASE WHEN s IS NULL THEN self_xref ELSE COLLECT({ link_base: coalesce(s.link_base[0], ''), accession: coalesce(dbx.accession[0], ''), link_text: primary.label + ' on ' + s.label, homepage: coalesce(s.homepage[0], ''), site: { short_form: s.short_form, label: coalesce(s.label,''), iri: s.iri, types: labels(s), symbol: coalesce(s.`IAO_0000028`[0], '')} , icon: coalesce(s.link_icon_url[0], ''), link_postfix: coalesce(s.link_postfix, '')}) + self_xref END AS xrefs,primary,anatomy_channel_image OPTIONAL MATCH (primary)-[:has_license]->(l:License) WITH collect ({ icon : coalesce(l.license_logo[0], ''), link : coalesce(l.license_url[0], ''), core : { short_form: l.short_form, label: coalesce(l.label,''), iri: l.iri, types: labels(l), symbol: coalesce(l.`IAO_0000028`[0], '')} }) as license,primary,anatomy_channel_image,xrefs OPTIONAL MATCH (primary)-[rp:has_reference]->(p:pub) WITH CASE WHEN p is null THEN [] ELSE collect({ core: { short_form: p.short_form, label: coalesce(p.label,''), iri: p.iri, types: labels(p), symbol: coalesce(p.`IAO_0000028`[0], '')} , PubMed: coalesce(p.PMID[0], ''), FlyBase: coalesce(p.FlyBase[0], ''), DOI: coalesce(p.DOI[0], '') } ) END AS pubs,primary,anatomy_channel_image,xrefs,license OPTIONAL MATCH (primary)<-[:has_source]-(i:Individual) WITH i, primary, anatomy_channel_image, xrefs, license, pubs OPTIONAL MATCH (i)-[:INSTANCEOF]-(c:Class) WITH DISTINCT { images: count(distinct i),types: count(distinct c) } as dataset_counts,primary,anatomy_channel_image,xrefs,license,pubs RETURN { link : coalesce(primary.dataset_link[0], ''), core : { short_form: primary.short_form, label: coalesce(primary.label,''), iri: primary.iri, types: labels(primary), symbol: coalesce(primary.`IAO_0000028`[0], '')} , description : coalesce(primary.description, []), comment : coalesce(primary.comment, []) } AS term, 'Get JSON for DataSet' AS query, '58214d4' AS version , anatomy_channel_image, xrefs, license, pubs, dataset_counts", "parameters" : { "ID" : "$ID" }" + query=""statement": "MATCH (primary:DataSet) WHERE primary.short_form in [{ID}] WITH primary OPTIONAL MATCH (primary)<-[:has_source|SUBCLASSOF|INSTANCEOF*]-(i:Individual)<-[:depicts]-(channel:Individual)-[irw:in_register_with]->(template:Individual)-[:depicts]->(template_anat:Individual) WITH template, channel, template_anat, irw, primary , i limit 5 OPTIONAL MATCH (channel)-[:is_specified_output_of]->(technique:Class) WITH CASE WHEN channel IS NULL THEN [] ELSE COLLECT({ anatomy: { short_form: i.short_form, label: coalesce(i.label,''), iri: i.iri, types: labels(i) } , channel_image: { channel: { short_form: channel.short_form, label: coalesce(channel.label,''), iri: channel.iri, types: labels(channel) } , imaging_technique: { short_form: technique.short_form, label: coalesce(technique.label,''), iri: technique.iri, types: labels(technique) } ,image: { template_channel : { short_form: template.short_form, label: coalesce(template.label,''), iri: template.iri, types: labels(template) } , template_anatomy: { short_form: template_anat.short_form, label: coalesce(template_anat.label,''), iri: template_anat.iri, types: labels(template_anat) } ,image_folder: irw.folder, index: coalesce(irw.index, []) + [] }} }) END AS anatomy_channel_image ,primary OPTIONAL MATCH (s:Site { short_form: primary.self_xref }) WITH CASE WHEN s IS NULL THEN [] ELSE COLLECT({ link_base: s.link_base, accession: coalesce(primary.short_form, ''), link_text: primary.label + ' on ' + s.label, site: { short_form: s.short_form, label: coalesce(s.label,''), iri: s.iri, types: labels(s) } , icon: coalesce(s.link_icon_url, ''), link_postfix: coalesce(s.link_postfix, '')}) END AS self_xref, primary, anatomy_channel_image OPTIONAL MATCH (s:Site)<-[dbx:hasDbXref]-(primary) WITH CASE WHEN s IS NULL THEN self_xref ELSE COLLECT({ link_base: s.link_base, accession: coalesce(dbx.accession, ''), link_text: primary.label + ' on ' + s.label, site: { short_form: s.short_form, label: coalesce(s.label,''), iri: s.iri, types: labels(s) } , icon: coalesce(s.link_icon_url, ''), link_postfix: coalesce(s.link_postfix, '')}) + self_xref END AS xrefs,primary,anatomy_channel_image OPTIONAL MATCH (primary)-[:has_license]->(l:License) WITH collect ({ icon : coalesce(l.license_logo, ''), link : coalesce(l.license_url, ''), core : { short_form: l.short_form, label: coalesce(l.label,''), iri: l.iri, types: labels(l) } }) as license,primary,anatomy_channel_image,xrefs OPTIONAL MATCH (primary)-[rp:has_reference]->(p:pub) WITH CASE WHEN p is null THEN [] ELSE collect({ core: { short_form: p.short_form, label: coalesce(p.label,''), iri: p.iri, types: labels(p) } , PubMed: coalesce(p.PMID, ''), FlyBase: coalesce(p.FlyBase, ''), DOI: coalesce(p.DOI, '') } ) END AS def_pubs,primary,anatomy_channel_image,xrefs,license RETURN { link : coalesce(primary.dataset_link, ''), core : { short_form: primary.short_form, label: coalesce(primary.label,''), iri: primary.iri, types: labels(primary) } , description : coalesce(primary.description, []), comment : coalesce(primary.`annotation - comment`, []) } AS term, 'Get JSON for DataSet' AS query, '2e501bd' AS version , anatomy_channel_image, xrefs, license, def_pubs", "parameters" : { "ID" : "$ID" }" countQuery=""statement": "MATCH (primary:DataSet {short_form: {ID}} ) RETURN count(primary) as count", "parameters" : { "ID" : "$ID" }"> @@ -545,7 +545,7 @@ name="Get JSON for License" description="Get JSON for License" runForCount="false" - query=""statement": "MATCH (primary:License) WHERE primary.short_form in [{ID}] WITH primary RETURN { icon : coalesce(primary.license_logo[0], ''), link : coalesce(primary.license_url[0], ''), core : { short_form: primary.short_form, label: coalesce(primary.label,''), iri: primary.iri, types: labels(primary), symbol: coalesce(primary.`IAO_0000028`[0], '')} , description : coalesce(primary.description, []), comment : coalesce(primary.comment, []) } AS term, 'Get JSON for License' AS query, '58214d4' AS version", "parameters" : { "ID" : "$ID" }" + query=""statement": "MATCH (primary:License) WHERE primary.short_form in [{ID}] WITH primary RETURN { icon : coalesce(primary.license_logo, ''), link : coalesce(primary.license_url, ''), core : { short_form: primary.short_form, label: coalesce(primary.label,''), iri: primary.iri, types: labels(primary) } , description : coalesce(primary.description, []), comment : coalesce(primary.`annotation - comment`, []) } AS term, 'Get JSON for License' AS query, '2e501bd' AS version", "parameters" : { "ID" : "$ID" }" countQuery=""statement": "MATCH (primary:License {short_form: {ID}} ) RETURN count(primary) as count", "parameters" : { "ID" : "$ID" }"> @@ -555,7 +555,7 @@ name="Get JSON for Cluster" description="Get JSON for Cluster" runForCount="false" - query=""statement": "MATCH (primary:Cluster) WHERE primary.short_form in [{ID}] WITH primary OPTIONAL MATCH (primary)-[:has_source]->(ds:DataSet)-[:has_license]->(l:License) WITH COLLECT ({ dataset: { link : coalesce(ds.dataset_link, ''), core : { short_form: ds.short_form, label: coalesce(ds.label,''), iri: ds.iri, types: labels(ds) } }, license: { icon : coalesce(l.license_logo[0], ''), link : coalesce(l.license_url[0], ''), core : { short_form: l.short_form, label: coalesce(l.label,''), iri: l.iri, types: labels(l) } }}) AS dataset_license,primary OPTIONAL MATCH (o:Class)<-[r:SUBCLASSOF|INSTANCEOF]-(primary) WITH CASE WHEN o IS NULL THEN [] ELSE COLLECT ({ short_form: o.short_form, label: coalesce(o.label,''), iri: o.iri, types: labels(o) } ) END AS parents ,primary,dataset_license OPTIONAL MATCH (o:Class)<-[r {type:'Related'}]-(primary) WITH CASE WHEN o IS NULL THEN [] ELSE COLLECT ({ relation: { label: r.label, iri: r.uri, type: type(r) } , object: { short_form: o.short_form, label: coalesce(o.label,''), iri: o.iri, types: labels(o) } }) END AS relationships ,primary,dataset_license,parents OPTIONAL MATCH (s:Site { short_form: primary.self_xref }) WITH CASE WHEN s IS NULL THEN [] ELSE COLLECT({ link_base: s.link_base[0], accession: coalesce(primary.short_form, ''), link_text: primary.label + ' on ' + s.label, site: { short_form: s.short_form, label: coalesce(s.label,''), iri: s.iri, types: labels(s) } , icon: coalesce(s.link_icon_url[0], ''), link_postfix: coalesce(s.link_postfix, '')}) END AS self_xref, primary, dataset_license, parents, relationships OPTIONAL MATCH (s:Site)<-[dbx:hasDbXref]-(primary) WITH CASE WHEN s IS NULL THEN self_xref ELSE COLLECT({ link_base: s.link_base[0], accession: coalesce(dbx.accession, ''), link_text: primary.label + ' on ' + s.label, site: { short_form: s.short_form, label: coalesce(s.label,''), iri: s.iri, types: labels(s) } , icon: coalesce(s.link_icon_url[0], ''), link_postfix: coalesce(s.link_postfix, '')}) + self_xref END AS xrefs,primary,dataset_license,parents,relationships OPTIONAL MATCH (primary)<-[:depicts]-(channel:Individual)-[irw:in_register_with]->(template:Individual)-[:depicts]->(template_anat:Individual) WITH template, channel, template_anat, irw, primary, dataset_license, parents, relationships, xrefs OPTIONAL MATCH (channel)-[:is_specified_output_of]->(technique:Class) WITH CASE WHEN channel IS NULL THEN [] ELSE collect ({ channel: { short_form: channel.short_form, label: coalesce(channel.label,''), iri: channel.iri, types: labels(channel) } , imaging_technique: { short_form: technique.short_form, label: coalesce(technique.label,''), iri: technique.iri, types: labels(technique) } ,image: { template_channel : { short_form: template.short_form, label: coalesce(template.label,''), iri: template.iri, types: labels(template) } , template_anatomy: { short_form: template_anat.short_form, label: coalesce(template_anat.label,''), iri: template_anat.iri, types: labels(template_anat) } ,image_folder: irw.folder[0], index: coalesce(irw.index[0], []) + [] }}) END AS channel_image,primary,dataset_license,parents,relationships,xrefs OPTIONAL MATCH (o:Individual)<-[r {type:'Related'}]-(primary) WITH CASE WHEN o IS NULL THEN [] ELSE COLLECT ({ relation: { label: r.label, iri: r.uri, type: type(r) } , object: { short_form: o.short_form, label: coalesce(o.label,''), iri: o.iri, types: labels(o) } }) END AS related_individuals ,primary,dataset_license,parents,relationships,xrefs,channel_image RETURN { core : { short_form: primary.short_form, label: coalesce(primary.label,''), iri: primary.iri, types: labels(primary) } , description : coalesce(primary.description, []), comment : coalesce(primary.`annotation-comment`, []) } AS term, 'Get JSON for Individual:Anatomy' AS query, 'ca9ab19' AS version , dataset_license, parents, relationships, xrefs, channel_image, related_individuals", "parameters" : { "ID" : "$ID" }" + query=""statement": "MATCH (primary:Cluster) WHERE primary.short_form in [{ID}] WITH primary OPTIONAL MATCH (primary)-[:has_source]->(ds:DataSet)-[:has_license]->(l:License) WITH COLLECT ({ dataset: { link : coalesce(ds.dataset_link, ''), core : { short_form: ds.short_form, label: coalesce(ds.label,''), iri: ds.iri, types: labels(ds) } }, license: { icon : coalesce(l.license_logo, ''), link : coalesce(l.license_url, ''), core : { short_form: l.short_form, label: coalesce(l.label,''), iri: l.iri, types: labels(l) } }}) AS dataset_license,primary OPTIONAL MATCH (o:Class)<-[r:SUBCLASSOF|INSTANCEOF]-(primary) WITH CASE WHEN o IS NULL THEN [] ELSE COLLECT ({ short_form: o.short_form, label: coalesce(o.label,''), iri: o.iri, types: labels(o) } ) END AS parents ,primary,dataset_license OPTIONAL MATCH (o:Class)<-[r {type:'Related'}]-(primary) WITH CASE WHEN o IS NULL THEN [] ELSE COLLECT ({ relation: { label: r.label, iri: r.uri, type: type(r) } , object: { short_form: o.short_form, label: coalesce(o.label,''), iri: o.iri, types: labels(o) } }) END AS relationships ,primary,dataset_license,parents OPTIONAL MATCH (s:Site { short_form: primary.self_xref }) WITH CASE WHEN s IS NULL THEN [] ELSE COLLECT({ link_base: s.link_base, accession: coalesce(primary.short_form, ''), link_text: primary.label + ' on ' + s.label, site: { short_form: s.short_form, label: coalesce(s.label,''), iri: s.iri, types: labels(s) } , icon: coalesce(s.link_icon_url, ''), link_postfix: coalesce(s.link_postfix, '')}) END AS self_xref, primary, dataset_license, parents, relationships OPTIONAL MATCH (s:Site)<-[dbx:hasDbXref]-(primary) WITH CASE WHEN s IS NULL THEN self_xref ELSE COLLECT({ link_base: s.link_base, accession: coalesce(dbx.accession, ''), link_text: primary.label + ' on ' + s.label, site: { short_form: s.short_form, label: coalesce(s.label,''), iri: s.iri, types: labels(s) } , icon: coalesce(s.link_icon_url, ''), link_postfix: coalesce(s.link_postfix, '')}) + self_xref END AS xrefs,primary,dataset_license,parents,relationships OPTIONAL MATCH (primary)<-[:depicts]-(channel:Individual)-[irw:in_register_with]->(template:Individual)-[:depicts]->(template_anat:Individual) WITH template, channel, template_anat, irw, primary, dataset_license, parents, relationships, xrefs OPTIONAL MATCH (channel)-[:is_specified_output_of]->(technique:Class) WITH CASE WHEN channel IS NULL THEN [] ELSE collect ({ channel: { short_form: channel.short_form, label: coalesce(channel.label,''), iri: channel.iri, types: labels(channel) } , imaging_technique: { short_form: technique.short_form, label: coalesce(technique.label,''), iri: technique.iri, types: labels(technique) } ,image: { template_channel : { short_form: template.short_form, label: coalesce(template.label,''), iri: template.iri, types: labels(template) } , template_anatomy: { short_form: template_anat.short_form, label: coalesce(template_anat.label,''), iri: template_anat.iri, types: labels(template_anat) } ,image_folder: irw.folder, index: coalesce(irw.index, []) + [] }}) END AS channel_image,primary,dataset_license,parents,relationships,xrefs OPTIONAL MATCH (o:Individual)<-[r {type:'Related'}]-(primary) WITH CASE WHEN o IS NULL THEN [] ELSE COLLECT ({ relation: { label: r.label, iri: r.uri, type: type(r) } , object: { short_form: o.short_form, label: coalesce(o.label,''), iri: o.iri, types: labels(o) } }) END AS related_individuals ,primary,dataset_license,parents,relationships,xrefs,channel_image RETURN { core : { short_form: primary.short_form, label: coalesce(primary.label,''), iri: primary.iri, types: labels(primary) } , description : coalesce(primary.description, []), comment : coalesce(primary.`annotation-comment`, []) } AS term, 'Get JSON for Individual:Anatomy' AS query, 'ca9ab19' AS version , dataset_license, parents, relationships, xrefs, channel_image, related_individuals", "parameters" : { "ID" : "$ID" }" countQuery=""statement": "MATCH (primary:Cluster {short_form: {ID}} ) RETURN count(primary) as count", "parameters" : { "ID" : "$ID" }"> diff --git a/tests/jest/vfb/batch3/tree-browser-tests.js b/tests/jest/vfb/batch3/tree-browser-tests.js index cf36bff45..b9f1e9232 100644 --- a/tests/jest/vfb/batch3/tree-browser-tests.js +++ b/tests/jest/vfb/batch3/tree-browser-tests.js @@ -72,7 +72,7 @@ describe('VFB Tree Browser Component Tests', () => { }); // Check that the Tree Browser is visible - await wait4selector(page, 'div.rst__tree', { visible: true, timeout : 800000 }); + await wait4selector(page, 'div.rst__tree', { visible: true, timeout : 500000 }); }) it('First node in Tree Browser is correctly named', async () => { @@ -99,24 +99,15 @@ describe('VFB Tree Browser Component Tests', () => { // Click on third node of tree browser, 'adult cerebral ganglion' await page.evaluate(async () => document.getElementsByClassName("rst__rowContents rst__rowContentsDragDisabled")[2].click()); // Check tree now expanded with adult cerebral ganglion name - let firstNode = await page.evaluate(async () => { + let thirdNode = await page.evaluate(async () => { return document.getElementsByClassName("nodeSelected")[3].innerText; }); - expect(firstNode).toEqual("adult protocerebrum"); + expect(thirdNode).toEqual("adult optic lobe"); }) - it('Expand node "adult protocerebrum"', async () => { - // Click on third node of tree browser, 'adult cerebral ganglion' - await page.evaluate(async () => document.getElementsByClassName("rst__rowContents rst__rowContentsDragDisabled")[3].click()); - // Check tree now expanded with adult cerebral ganglion name - let sixthNode = await page.evaluate(async () => { - return document.getElementsByClassName("nodeSelected")[6].innerText; - }); - expect(sixthNode).toEqual("adult optic lobe"); - }) it('Click on Node "adult optic lobe"', async () => { - await page.evaluate(async () => document.getElementsByClassName("nodeSelected")[6].click()); + await page.evaluate(async () => document.getElementsByClassName("nodeSelected")[3].click()); // Check Term Info is now populated with adult cerebral ganglion name let element = await findElementByText(page, "adult optic lobe"); expect(element).toBe("adult optic lobe"); @@ -151,11 +142,11 @@ describe('VFB Tree Browser Component Tests', () => { }) it('Click on "eye" icon to render "adult optic lobe" mesh', async () => { - await page.evaluate(() => document.querySelectorAll('.rst__tree i.fa-eye-slash')[3].click()); + await page.evaluate(() => document.querySelectorAll('.rst__tree i.fa-eye-slash')[1].click()); // Wait for 'color picker' selector to show, this is the sign that the click on the eye button worked and the mesh was rendered - await wait4selector(page, 'i.fa-tint', { visible: true, timeout : 500000 }); + await wait4selector(page, '.rst__tree i.fa-tint', { visible: true, timeout : 500000 }); }) - + it('Mesh for "adult optic lobe" rendered in canvas after clicking on eye icon next to node', async () => { expect( await page.evaluate(async () => CanvasContainer.engine.getRealMeshesForInstancePath('VFB_00030870.VFB_00030870_obj').length) @@ -163,7 +154,7 @@ describe('VFB Tree Browser Component Tests', () => { }) it('Color Picker Appears for "adult optic lobe"', async () => { - await page.evaluate(async () => document.querySelectorAll('.rst__tree i.fa-tint')[0].click()); + await page.evaluate(async () => document.querySelectorAll('.rst__tree i.fa-tint')[1].click()); // Wait for color picker to show await wait4selector(page, '#tree-color-picker', { visible: true, timeout : 500000 }) }) diff --git a/tests/jest/vfb/batch2/layer-component-tests.js b/tests/jest/vfb/review/layer-component-tests.js similarity index 100% rename from tests/jest/vfb/batch2/layer-component-tests.js rename to tests/jest/vfb/review/layer-component-tests.js From 9b520e40821545767c807bce078136c566dd6061 Mon Sep 17 00:00:00 2001 From: Rob Court Date: Thu, 15 Oct 2020 08:56:26 +0100 Subject: [PATCH 26/27] Revert "Revert "Merge pull request #690 from VirtualFlyBrain/pipeline2"" This reverts commit 535873ab62d5f0974ab0194de1a0d19bf9881219. --- .travis.yml | 60 +++++++++------ Dockerfile | 2 +- components/VFBMain.js | 1 + .../circuitBrowserConfiguration.js | 20 ++--- .../VFBGraph/graphConfiguration.js | 35 +++++---- components/configuration/VFBMain/colours.json | 2 +- .../VFBMain/queryBuilderConfiguration.js | 15 +++- .../VFBMain/searchConfiguration.js | 29 ++++++-- .../VFBTree/VFBTreeConfiguration.js | 16 ++-- css/VFBMain.less | 1 + model/vfb.xmi | 74 +++++++++---------- .../layer-component-tests.js | 0 tests/jest/vfb/batch3/tree-browser-tests.js | 25 +++++-- 13 files changed, 168 insertions(+), 112 deletions(-) rename tests/jest/vfb/{review => batch2}/layer-component-tests.js (100%) diff --git a/.travis.yml b/.travis.yml index 7af7db28b..07732a67d 100644 --- a/.travis.yml +++ b/.travis.yml @@ -19,21 +19,21 @@ services: stages: - build - name: debug - if: branch = vfb_geppetto_application OR branch =~ ^(fix|feature).* + if: branch = debug OR branch = pipeline2 OR branch =~ ^(fix|feature).* - test - deploy - name: review - if: branch = vfb_geppetto_application OR branch = development OR branch =~ ^(fix|feature).* + if: branch = debug OR branch = development OR branch = pipeline2 OR branch =~ ^(fix|feature).* jobs: fast_finish: true allow_failures: - - if: branch = vfb_geppetto_application OR branch = development + - if: branch = debug OR branch = development name: review include: - stage: build install: - - export BUILD_TYPE=`if [ "$TRAVIS_BRANCH" == "vfb_geppetto_application" ]; then echo "development"; elif [ "$TRAVIS_BRANCH" == "development" ]; then echo "staging"; else echo "release"; fi` + - export BUILD_TYPE=`if [ "$TRAVIS_BRANCH" == "debug" ]; then echo "development"; elif [ "$TRAVIS_BRANCH" == "pipeline2" ]; then echo "development"; elif [ "$TRAVIS_BRANCH" == "development" ]; then echo "staging"; else echo "release"; fi` - export VFB_REPO=$(echo ${TRAVIS_REPO_SLUG##*/} | awk '{gsub(/\-/,"_",$0);gsub(/\./,"_",$0);print toupper($0)}') - export REPO=$(echo ${TRAVIS_REPO_SLUG} | awk '{gsub(/\./,"_",$0);print tolower($0)}') - export TAG=`if [ "$TRAVIS_BRANCH" == "master" ]; then echo "latest"; else echo ${TRAVIS_BRANCH/\//-}; fi` @@ -57,6 +57,11 @@ jobs: export VFB_R_SERVER=http://r.virtualflybrain.org/ocpu/library/vfbr/R/vfb_nblast; export SOLR_SERVER=https://solr.virtualflybrain.org/solr/ontology/select; fi; + export VFB_TREE_PDB_SERVER=https://pdb.p2.virtualflybrain.org; + export VFB_PDB_SERVER=http://pdb.p2.virtualflybrain.org; + export VFB_OWL_SERVER=http://owl.p2.virtualflybrain.org/kbs/vfb/; + export VFB_R_SERVER=http://r.virtualflybrain.org/ocpu/library/vfbr/R/vfb_nblast; + export SOLR_SERVER=https://solr.p2.virtualflybrain.org/solr/ontology/select; - export TAG="$TAG-TEST" before_script: - docker login -u $DOCKER_USER -p $DOCKER_PASS; @@ -71,7 +76,7 @@ jobs: - stage: test before_install: - - export BUILD_TYPE=`if [ "$TRAVIS_BRANCH" == "vfb_geppetto_application" ]; then echo "development"; elif [ "$TRAVIS_BRANCH" == "development" ]; then echo "staging"; else echo "release"; fi` + - export BUILD_TYPE=`if [ "$TRAVIS_BRANCH" == "debug" ]; then echo "development"; elif [ "$TRAVIS_BRANCH" == "pipeline2" ]; then echo "development"; elif [ "$TRAVIS_BRANCH" == "development" ]; then echo "staging"; else echo "release"; fi` - export VFB_REPO=$(echo ${TRAVIS_REPO_SLUG##*/} | awk '{gsub(/\-/,"_",$0);gsub(/\./,"_",$0);print toupper($0)}') - export REPO=$(echo ${TRAVIS_REPO_SLUG} | awk '{gsub(/\./,"_",$0);print tolower($0)}') - export TAG=`if [ "$TRAVIS_BRANCH" == "master" ]; then echo "latest"; else echo ${TRAVIS_BRANCH/\//-}; fi` @@ -111,7 +116,7 @@ jobs: - stage: test before_install: - - export BUILD_TYPE=`if [ "$TRAVIS_BRANCH" == "vfb_geppetto_application" ]; then echo "development"; elif [ "$TRAVIS_BRANCH" == "development" ]; then echo "staging"; else echo "release"; fi` + - export BUILD_TYPE=`if [ "$TRAVIS_BRANCH" == "debug" ]; then echo "development"; elif [ "$TRAVIS_BRANCH" == "pipeline2" ]; then echo "development"; elif [ "$TRAVIS_BRANCH" == "development" ]; then echo "staging"; else echo "release"; fi` - export VFB_REPO=$(echo ${TRAVIS_REPO_SLUG##*/} | awk '{gsub(/\-/,"_",$0);gsub(/\./,"_",$0);print toupper($0)}') - export REPO=$(echo ${TRAVIS_REPO_SLUG} | awk '{gsub(/\./,"_",$0);print tolower($0)}') - export TAG=`if [ "$TRAVIS_BRANCH" == "master" ]; then echo "latest"; else echo ${TRAVIS_BRANCH/\//-}; fi` @@ -151,7 +156,7 @@ jobs: - stage: test before_install: - - export BUILD_TYPE=`if [ "$TRAVIS_BRANCH" == "vfb_geppetto_application" ]; then echo "development"; elif [ "$TRAVIS_BRANCH" == "development" ]; then echo "staging"; else echo "release"; fi` + - export BUILD_TYPE=`if [ "$TRAVIS_BRANCH" == "debug" ]; then echo "development"; elif [ "$TRAVIS_BRANCH" == "pipeline2" ]; then echo "development"; elif [ "$TRAVIS_BRANCH" == "development" ]; then echo "staging"; else echo "release"; fi` - export VFB_REPO=$(echo ${TRAVIS_REPO_SLUG##*/} | awk '{gsub(/\-/,"_",$0);gsub(/\./,"_",$0);print toupper($0)}') - export REPO=$(echo ${TRAVIS_REPO_SLUG} | awk '{gsub(/\./,"_",$0);print tolower($0)}') - export TAG=`if [ "$TRAVIS_BRANCH" == "master" ]; then echo "latest"; else echo ${TRAVIS_BRANCH/\//-}; fi` @@ -191,7 +196,7 @@ jobs: - stage: deploy install: - - export BUILD_TYPE=`if [ "$TRAVIS_BRANCH" == "vfb_geppetto_application" ]; then echo "development"; elif [ "$TRAVIS_BRANCH" == "development" ]; then echo "staging"; else echo "release"; fi` + - export BUILD_TYPE=`if [ "$TRAVIS_BRANCH" == "debug" ]; then echo "development"; elif [ "$TRAVIS_BRANCH" == "pipeline2" ]; then echo "development"; elif [ "$TRAVIS_BRANCH" == "development" ]; then echo "staging"; else echo "release"; fi` - export VFB_REPO=$(echo ${TRAVIS_REPO_SLUG##*/} | awk '{gsub(/\-/,"_",$0);gsub(/\./,"_",$0);print toupper($0)}') - export REPO=$(echo ${TRAVIS_REPO_SLUG} | awk '{gsub(/\./,"_",$0);print tolower($0)}') - export TAG=`if [ "$TRAVIS_BRANCH" == "master" ]; then echo "latest"; else echo ${TRAVIS_BRANCH/\//-}; fi` @@ -215,29 +220,40 @@ jobs: export VFB_TREE_PDB_SERVER=https://pdb.virtualflybrain.org; export SOLR_SERVER=https://solr.virtualflybrain.org/solr/ontology/select; fi; + export VFB_TREE_PDB_SERVER=https://pdb.p2.virtualflybrain.org; + export VFB_PDB_SERVER=http://pdb.p2.virtualflybrain.org; + export VFB_OWL_SERVER=http://owl.p2.virtualflybrain.org/kbs/vfb/; + export VFB_R_SERVER=http://r.virtualflybrain.org/ocpu/library/vfbr/R/vfb_nblast; + export SOLR_SERVER=https://solr.p2.virtualflybrain.org/solr/ontology/select; docker build --cache-from metacell/java-virgo-maven:development -t=$REPO:$TAG.wss --build-arg VFB_TREE_PDB_SERVER_ARG=$VFB_TREE_PDB_SERVER --build-arg SOLR_SERVER_ARG=$SOLR_SERVER --build-arg VFB_R_SERVER_ARG=$VFB_R_SERVER --build-arg VFB_OWL_SERVER_ARG=$VFB_OWL_SERVER --build-arg VFB_PDB_SERVER_ARG=$VFB_PDB_SERVER --build-arg build_type=$BUILD_TYPE --build-arg targetBranch=$TRAVIS_BRANCH --build-arg originBranch=$BRANCH --build-arg defaultBranch=$DEFAULT_BRANCH --build-arg finalBuild=true $DOCKER_FOLDER && docker push $REPO:$TAG.wss; fi; - stage: debug install: - - export BUILD_TYPE=`if [ "$TRAVIS_BRANCH" == "vfb_geppetto_application" ]; then echo "development"; elif [ "$TRAVIS_BRANCH" == "development" ]; then echo "staging"; else echo "release"; fi` + - export BUILD_TYPE=`if [ "$TRAVIS_BRANCH" == "debug" ]; then echo "development"; elif [ "$TRAVIS_BRANCH" == "pipeline2" ]; then echo "development"; elif [ "$TRAVIS_BRANCH" == "development" ]; then echo "staging"; else echo "release"; fi` - export VFB_REPO=$(echo ${TRAVIS_REPO_SLUG##*/} | awk '{gsub(/\-/,"_",$0);gsub(/\./,"_",$0);print toupper($0)}') - export REPO=$(echo ${TRAVIS_REPO_SLUG} | awk '{gsub(/\./,"_",$0);print tolower($0)}') - export TAG=`if [ "$TRAVIS_BRANCH" == "master" ]; then echo "latest"; else echo ${TRAVIS_BRANCH/\//-}; fi` + - if [ "$BUILD_TYPE" == "development" ]; then export TAG=$TAG-development; fi; - export VFB_PDB_SERVER=http://pdb:7474; - export VFB_OWL_SERVER=http://owl:8080/kbs/vfb/; - export VFB_R_SERVER=http://ocpu:80/ocpu/library/vfbr/R/vfb_nblast; - - if [ "$BUILD_TYPE" == "development" ]; then - export VFB_TREE_PDB_SERVER=https://pdb-dev.virtualflybrain.org; - export SOLR_SERVER=https://solr-dev.virtualflybrain.org/solr/ontology/select; - export TAG=$TAG-development; - elif [ "$BUILD_TYPE" == "staging" ]; then - export VFB_TREE_PDB_SERVER=https://pdb-alpha.virtualflybrain.org; - export SOLR_SERVER=https://solr-alpha.virtualflybrain.org/solr/ontology/select; - else - export VFB_TREE_PDB_SERVER=https://pdb.virtualflybrain.org; - export SOLR_SERVER=https://solr.virtualflybrain.org/solr/ontology/select; - fi; + # - if [ "$BUILD_TYPE" == "development" ]; then + # export VFB_TREE_PDB_SERVER=https://pdb-dev.virtualflybrain.org; + # export SOLR_SERVER=https://solr-dev.virtualflybrain.org/solr/ontology/select; + # export TAG=$TAG-development; + # elif [ "$BUILD_TYPE" == "staging" ]; then + # export VFB_TREE_PDB_SERVER=https://pdb-alpha.virtualflybrain.org; + # export SOLR_SERVER=https://solr-alpha.virtualflybrain.org/solr/ontology/select; + # else + # export VFB_TREE_PDB_SERVER=https://pdb.virtualflybrain.org; + # export SOLR_SERVER=https://solr.virtualflybrain.org/solr/ontology/select; + # fi; + - export VFB_TREE_PDB_SERVER=https://pdb.p2.virtualflybrain.org; + - export VFB_PDB_SERVER=http://pdb.p2.virtualflybrain.org; + - export VFB_OWL_SERVER=http://owl.p2.virtualflybrain.org/kbs/vfb/; + - export VFB_R_SERVER=http://r.virtualflybrain.org/ocpu/library/vfbr/R/vfb_nblast; + - export SOLR_SERVER=https://solr.p2.virtualflybrain.org/solr/ontology/select; before_script: - cd $TRAVIS_BUILD_DIR; - docker login -u $DOCKER_USER -p $DOCKER_PASS; @@ -249,7 +265,7 @@ jobs: - stage: review before_install: - if [ $(ls tests/jest/vfb/review/*.js | wc -l) -lt 1 ]; then travis_terminate 0; fi - - export BUILD_TYPE=`if [ "$TRAVIS_BRANCH" == "vfb_geppetto_application" ]; then echo "development"; elif [ "$TRAVIS_BRANCH" == "development" ]; then echo "staging"; else echo "release"; fi` + - export BUILD_TYPE=`if [ "$TRAVIS_BRANCH" == "debug" ]; then echo "development"; elif [ "$TRAVIS_BRANCH" == "pipeline2" ]; then echo "development"; elif [ "$TRAVIS_BRANCH" == "development" ]; then echo "staging"; else echo "release"; fi` - export VFB_REPO=$(echo ${TRAVIS_REPO_SLUG##*/} | awk '{gsub(/\-/,"_",$0);gsub(/\./,"_",$0);print toupper($0)}') - export REPO=$(echo ${TRAVIS_REPO_SLUG} | awk '{gsub(/\./,"_",$0);print tolower($0)}') - export TAG=`if [ "$TRAVIS_BRANCH" == "master" ]; then echo "latest"; else echo ${TRAVIS_BRANCH/\//-}; fi` @@ -285,4 +301,4 @@ jobs: - echo -e "travis_fold:start:Cleanup" || true - docker stop $(docker ps -a -q) - docker rm $(docker ps -a -q) - - echo -e "travis_fold:end:Cleanup" || true \ No newline at end of file + - echo -e "travis_fold:end:Cleanup" || true diff --git a/Dockerfile b/Dockerfile index b3fea6831..9d81decc6 100644 --- a/Dockerfile +++ b/Dockerfile @@ -15,7 +15,7 @@ ARG geppettoDatasourceRelease=vfb_20200604_a ARG geppettoModelSwcRelease=v1.0.1 ARG geppettoFrontendRelease=development ARG geppettoClientRelease=VFBv2.2.0.5 -ARG ukAcVfbGeppettoRelease=development +ARG ukAcVfbGeppettoRelease=pipeline2 ARG mvnOpt="-Dhttps.protocols=TLSv1.2 -DskipTests --quiet -Pmaster" diff --git a/components/VFBMain.js b/components/VFBMain.js index 688c5925d..27fd1ebe4 100644 --- a/components/VFBMain.js +++ b/components/VFBMain.js @@ -913,6 +913,7 @@ class VFBMain extends React.Component { focusTermRef={this.focusTermReference} exclude={["ClassQueriesFrom", "Debug"]} order={['Name', + 'Title', 'Label', 'Alternative Names', 'Types', diff --git a/components/configuration/VFBCircuitBrowser/circuitBrowserConfiguration.js b/components/configuration/VFBCircuitBrowser/circuitBrowserConfiguration.js index d71f2fc1b..35b522323 100644 --- a/components/configuration/VFBCircuitBrowser/circuitBrowserConfiguration.js +++ b/components/configuration/VFBCircuitBrowser/circuitBrowserConfiguration.js @@ -57,14 +57,6 @@ var styling = { defaultNodeDescriptionBackgroundColor : "white", nodeColorsByLabel : { "Template" : "#ff6cc8", - "DataSet" : "#b700b5", - "Anatomy" : "#00a2aa", - "Synaptic_neuropil" : "#00a2aa", - "_Class" : "#0164d8", - "License" : "#0164d8", - "Person" : "#023f00", - "Neuron" : "#7f2100", - "Neuron_projection_bundle" : "#d6007d", "Ganglion" : "#d6007d", "Neuromere" : "#d6007d", "GABAergic" : "#9551ff", @@ -79,11 +71,19 @@ var styling = { "Glial_cell" : "#ff6a3a", "Cell" : "#ff6a3a", "Clone" : "#d6007d", - "Property" : "#005f1d", + "Synaptic_neuropil" : "#00a2aa", + "License" : "#0164d8", + "Person" : "#023f00", + "Neuron" : "#7f2100", + "Neuron_projection_bundle" : "#d6007d", "Resource" : "#005f1d", "Site" : "#005f1d", "Expression_pattern" : "#534700", - "Split" : "#e012e3" + "Split" : "#e012e3", + "DataSet" : "#b700b5", + "Anatomy" : "#00a2aa", + "Property" : "#005f1d", + "_Class" : "#0164d8" }, controlIcons : { home : "fa fa-home", diff --git a/components/configuration/VFBGraph/graphConfiguration.js b/components/configuration/VFBGraph/graphConfiguration.js index 8819d61f8..77d0b7037 100644 --- a/components/configuration/VFBGraph/graphConfiguration.js +++ b/components/configuration/VFBGraph/graphConfiguration.js @@ -1,9 +1,21 @@ var locationCypherQuery = instance => ({ "statements": [ { - "statement": "MATCH p=(n:Entity)-[r:INSTANCEOF|part_of|has_synaptic_terminal_in|has_presynaptic_terminal_in" - + "has_postsynaptic_terminal_in|overlaps*..]->(x)" - + "WHERE n.short_form = '" + instance + "' return distinct n,r,x,n.short_form as root", + "statement": "MATCH p=(n:Entity {short_form:'" + instance + "'})-[r:INSTANCEOF|part_of|has_synaptic_terminal_in|has_presynaptic_terminal_in|" + + "has_postsynaptic_terminal_in|overlaps*..]->(x) " + + "RETURN distinct n,r,x,n.short_form as root", + "resultDataContents": ["graph"] + } + ] +}); + +var whatCypherQuery = instance => ({ + "statements": [ + { + "statement": "MATCH p=(n:Entity {short_form:'" + instance + "'})-[:INSTANCEOF|:SUBCLASSOF*..]->(x) " + + "WHERE (('Cell' IN labels(x)) OR ('synaptic neuropil' IN labels(x))) " + + " OR (('Ganglion' IN labels(x)) OR ('Neuron_projection_bundle' IN labels(x))) " + + "RETURN p, n.short_form as root", "resultDataContents": ["graph"] } ] @@ -62,17 +74,7 @@ var styling = { }, { label : instance => "Show classification of " + instance, - query : instance => ({ - "statements": [ - { - "statement": "MATCH p=(n:Entity)-[:INSTANCEOF|:SUBCLASSOF*..]->(x)" - + "WHERE 'Anatomy' IN labels(x)" - + "AND n.short_form = '" + instance + "'" - + "RETURN p, n.short_form as root", - "resultDataContents": ["graph"] - } - ] - }) + query : instance => whatCypherQuery(instance) } ], dropDownHoverBackgroundColor : "#11bffe", @@ -82,7 +84,7 @@ var styling = { } var restPostConfig = { - url: "https://pdb.virtualflybrain.org/db/data/transaction/commit", + url: "https://pdb.p2.virtualflybrain.org/db/data/transaction/commit", contentType: "application/json" }; @@ -90,5 +92,6 @@ module.exports = { configuration, styling, restPostConfig, - locationCypherQuery + locationCypherQuery, + whatCypherQuery }; diff --git a/components/configuration/VFBMain/colours.json b/components/configuration/VFBMain/colours.json index 287f5ed53..a16bf2ea5 100644 --- a/components/configuration/VFBMain/colours.json +++ b/components/configuration/VFBMain/colours.json @@ -3,7 +3,6 @@ "0x00ff00", "0xff00ff", "0x0000ff", - "0xffd300", "0x0084f6", "0x008d46", "0xa7613e", @@ -199,5 +198,6 @@ "0x8d35f6", "0x5800a7", "0xed8dff", + "0xffd300", "0x969696" ] diff --git a/components/configuration/VFBMain/queryBuilderConfiguration.js b/components/configuration/VFBMain/queryBuilderConfiguration.js index 8de4bf6d9..c6eb2062f 100644 --- a/components/configuration/VFBMain/queryBuilderConfiguration.js +++ b/components/configuration/VFBMain/queryBuilderConfiguration.js @@ -25,6 +25,19 @@ var queryResultsColMeta = [ "cssClassName": "query-results-name-column", "sortDirectionCycle": ['asc', 'desc', null] }, + { + "columnName": "type", + "order": 2, + "locked": false, + "visible": true, + "customComponent": QueryLinkComponent, + "actions": "window.addVfbId('$entity$');", + "entityIndex": 1, + "entityDelimiter": "----", + "displayName": "Type", + "cssClassName": "query-results-type-column", + "sortDirectionCycle": ['asc', 'desc', null] + }, { "columnName": "expressed_in", "order": 3, @@ -163,7 +176,7 @@ var queryResultsControlConfig = { var queryBuilderDatasourceConfig = { VFB: { - url: "https://solr.virtualflybrain.org/solr/ontology/select?fl=short_form,label,synonym,id,type,has_narrow_synonym_annotation,has_broad_synonym_annotation&start=0&fq=type%3Aclass+OR+type%3Aindividual+OR+type%3Aproperty&fq=ontology_name:(vfb)&fq=shortform_autosuggest:VFB*%20OR%20shortform_autosuggest:FB*%20OR%20is_defining_ontology:true&rows=100&bq=is_obsolete:false%5E100.0%20shortform_autosuggest:VFB*%5E110.0%20shortform_autosuggest:FBbt*%5E100.0%20is_defining_ontology:true%5E100.0%20label_s:%22%22%5E2%20synonym_s:%22%22%20in_subset_annotation:BRAINNAME%5E3%20short_form:FBbt_00003982%5E2&q=$SEARCH_TERM$%20OR%20$SEARCH_TERM$*%20OR%20*$SEARCH_TERM$*&defType=edismax&qf=label%20synonym%20label_autosuggest_ws%20label_autosuggest_e%20label_autosuggest%20synonym_autosuggest_ws%20synonym_autosuggest_e%20synonym_autosuggest%20shortform_autosuggest%20has_narrow_synonym_annotation%20has_broad_synonym_annotation&wt=json&indent=true", + url: 'https://solr.p2.virtualflybrain.org/solr/ontology/select?q=$SEARCH_TERM$+OR+$SEARCH_TERM$*+OR+*$SEARCH_TERM$*&defType=edismax&qf=label^100+synonym^100+label_autosuggest_ws+label_autosuggest_e+label_autosuggest+synonym_autosuggest_ws+synonym_autosuggest+shortform_autosuggest&indent=true&fl=short_form+label+synonym+id+facets_annotation+type:"class"&start=0&pf=true&rows=100&wt=json&bq=shortform_autosuggest:VFB*^110.0+shortform_autosuggest:FBbt*^100.0+label_s:""^2+synonym_s:""+short_form=FBbt_00003982^2+facets_annotation:Deprecated^0.001', crossDomain: true, id: "short_form", label: { field: "label", formatting: "$VALUE$" }, diff --git a/components/configuration/VFBMain/searchConfiguration.js b/components/configuration/VFBMain/searchConfiguration.js index e7032751d..2b33818d5 100644 --- a/components/configuration/VFBMain/searchConfiguration.js +++ b/components/configuration/VFBMain/searchConfiguration.js @@ -84,23 +84,22 @@ var searchStyle = { }; var datasourceConfiguration = { - "url": "https://solr-dev.virtualflybrain.org/solr/ontology/select", + "url": "https://solr.p2.virtualflybrain.org/solr/ontology/select", "query_settings": { "q": "$SEARCH_TERM$ OR $SEARCH_TERM$* OR *$SEARCH_TERM$*", "defType": "edismax", - "qf": "label synonym label_autosuggest_ws label_autosuggest_e label_autosuggest synonym_autosuggest_ws synonym_autosuggest_e synonym_autosuggest shortform_autosuggest has_narrow_synonym_annotation has_broad_synonym_annotation", + "qf": "label^100 synonym^100 label_autosuggest_ws label_autosuggest_e label_autosuggest synonym_autosuggest_ws synonym_autosuggest shortform_autosuggest", "indent": "true", - "fl": "short_form,label,synonym,id,type,has_narrow_synonym_annotation,has_broad_synonym_annotation,facets_annotation", + "fl": "short_form,label,synonym,id,facets_annotation", "start": "0", + "pf":"true", "fq": [ - "type:class OR type:individual OR type:property", - "ontology_name:(vfb)", - "shortform_autosuggest:VFB* OR shortform_autosuggest:FB* OR is_defining_ontology:true" + "shortform_autosuggest:VFB* OR shortform_autosuggest:FB*" ], "rows": "100", "wt": "json", - "bq": "is_obsolete:false^100.0 shortform_autosuggest:VFB*^110.0 shortform_autosuggest:FBbt*^100.0 is_defining_ontology:true^100.0 label_s:\"\"^2 synonym_s:\"\" in_subset_annotation:BRAINNAME^3 short_form:FBbt_00003982^2" + "bq": "shortform_autosuggest:VFB*^110.0 shortform_autosuggest:FBbt*^100.0 label_s:\"\"^2 synonym_s:\"\" short_form:FBbt_00003982^2 facets_annotation:Deprecated^0.001" } }; @@ -113,7 +112,7 @@ var searchConfiguration = { "filters": [ { "key": "facets_annotation", - "filter_name": "Type", + "filter_name": "Filters", "type": "array", "enabled": "disabled", "disableGlobal": true, @@ -177,6 +176,13 @@ var searchConfiguration = { if (InputString == b.label) { return 1; } + // move exact matches to top ['XX ('ID/Label)] + if (a.label.indexOf(InputString + " (") == 0) { + return -1; + } + if (b.label.indexOf(InputString + " (") == 0) { + return 1; + } // close match without case matching if (InputString.toLowerCase() == a.label.toLowerCase()) { return -1; @@ -184,6 +190,13 @@ var searchConfiguration = { if (InputString.toLowerCase() == b.label.toLowerCase()) { return 1; } + // close match without case matching ['xx ('ID/Label)] + if (a.label.toLowerCase().indexOf(InputString.toLowerCase()) == 0) { + return -1; + } + if (b.label.toLowerCase().indexOf(InputString.toLowerCase()) == 0) { + return 1; + } // match ignoring joinging nonwords if (InputString.toLowerCase().split(/\W+/).join(' ') == a.label.toLowerCase().split(/\W+/).join(' ')) { return -1; diff --git a/components/configuration/VFBTree/VFBTreeConfiguration.js b/components/configuration/VFBTree/VFBTreeConfiguration.js index 00a4802ab..57d8f63af 100644 --- a/components/configuration/VFBTree/VFBTreeConfiguration.js +++ b/components/configuration/VFBTree/VFBTreeConfiguration.js @@ -1,15 +1,15 @@ var restPostConfig = { - url: "https://pdb.virtualflybrain.org/db/data/transaction/commit", + url: "https://pdb.p2.virtualflybrain.org/db/data/transaction/commit", contentType: "application/json" }; var treeCypherQuery = instance => ({ "statements": [ { - "statement": "MATCH (root:Class)<-[:INSTANCEOF]-(t:Individual {short_form:'" + instance + "'})" - + "<-[:depicts]-(tc:Individual)<-[ie:in_register_with]-(c:Individual)-[:depicts]->(image:" - + "Individual)-[r:INSTANCEOF]->(anat:Class) WHERE has(ie.index) WITH root, anat,r,image" - + " MATCH p=(root)<-[:SUBCLASSOF|part_of*..]-(anat) " + "statement": "MATCH (root:Class)<-[:INSTANCEOF]-(t:Template {short_form:'" + instance + "'})" + + "<-[:depicts]-(tc:Template)<-[ie:in_register_with]-(c:Individual)-[:depicts]->(image:" + + "Individual)-[r:INSTANCEOF]->(anat:Class:Nervous_system) WHERE exists(ie.index) WITH root, anat,r,image" + + " MATCH p=allshortestpaths((root)<-[:SUBCLASSOF|part_of*..]-(anat)) " + "RETURN collect(distinct { node_id: id(anat), short_form: anat.short_form, image: image.short_form })" + " AS image_nodes, id(root) AS root, collect(p)", "resultDataContents": ["row", "graph"] @@ -32,7 +32,7 @@ var styling = { { "statement": "MATCH (root:Class)<-[:INSTANCEOF]-(t:Individual {short_form:'FBbt_00007145'})" + "<-[:depicts]-(tc:Individual)<-[ie:in_register_with]-(c:Individual)-[:depicts]->(image:" - + "Individual)-[r:INSTANCEOF]->(anat:Class) WHERE has(ie.index) WITH root, anat,r,image" + + "Individual)-[r:INSTANCEOF]->(anat:Class) WHERE exists(ie.index) WITH root, anat,r,image" + " MATCH p=allShortestPaths((root)<-[:SUBCLASSOF|part_of*..]-(anat)) " + "RETURN collect(distinct { node_id: id(anat), short_form: anat.short_form, image: image.short_form })" + " AS image_nodes, id(root) AS root, collect(p)", @@ -48,7 +48,7 @@ var styling = { { "statement": "MATCH (root:Class)<-[:INSTANCEOF]-(t:Individual {short_form:'VFB_00017894'})" + "<-[:depicts]-(tc:Individual)<-[ie:in_register_with]-(c:Individual)-[:depicts]->(image:" - + "Individual)-[r:INSTANCEOF]->(anat:Class) WHERE has(ie.index) WITH root, anat,r,image" + + "Individual)-[r:INSTANCEOF]->(anat:Class) WHERE exists(ie.index) WITH root, anat,r,image" + " MATCH p=allShortestPaths((root)<-[:SUBCLASSOF|part_of*..]-(anat)) " + "RETURN collect(distinct { node_id: id(anat), short_form: anat.short_form, image: image.short_form })" + " AS image_nodes, id(root) AS root, collect(p)", @@ -64,7 +64,7 @@ var styling = { { "statement": "MATCH (root:Class)<-[:INSTANCEOF]-(t:Individual {short_form:'FBbt_00007050'})" + "<-[:depicts]-(tc:Individual)<-[ie:in_register_with]-(c:Individual)-[:depicts]->(image:" - + "Individual)-[r:INSTANCEOF]->(anat:Class) WHERE has(ie.index) WITH root, anat,r,image" + + "Individual)-[r:INSTANCEOF]->(anat:Class) WHERE exists(ie.index) WITH root, anat,r,image" + " MATCH p=allShortestPaths((root)<-[:SUBCLASSOF|part_of*..]-(anat)) " + "RETURN collect(distinct { node_id: id(anat), short_form: anat.short_form, image: image.short_form })" + " AS image_nodes, id(root) AS root, collect(p)", diff --git a/css/VFBMain.less b/css/VFBMain.less index c426b6408..e17e5d2f4 100644 --- a/css/VFBMain.less +++ b/css/VFBMain.less @@ -1662,3 +1662,4 @@ -o-user-select: text; user-select: text; } + diff --git a/model/vfb.xmi b/model/vfb.xmi index 8dbb71010..d78879c05 100644 --- a/model/vfb.xmi +++ b/model/vfb.xmi @@ -168,15 +168,15 @@ runForCount="false"> + queryProcessorId="neo4jQueryProcessor"/> + queryProcessorId="neo4jQueryProcessor"/> + query=""statement": "MATCH (n:Template {short_form:{ID}})<-[:depicts]-(:Template)<-[r:in_register_with]-(dc:Individual)-[:depicts]->(di:Individual)-[:INSTANCEOF]->(d:Class) WHERE exists(r.index) RETURN distinct di.short_form as id, di.label as name, coalesce(di.description[0],d.description[0]) as def, COLLECT(DISTINCT d.label) as type, replace(r.folder[0],'http:','https:') + '/thumbnailT.png' as file", "parameters" : { "ID" : "$ID" }" + countQuery=""statement": "MATCH (n:Template {short_form:{ID}})<-[:depicts]-(:Template)<-[r:in_register_with]-(dc:Individual)-[:depicts]->(di:Individual)-[:INSTANCEOF]->(d:Class) WHERE exists(r.index) RETURN count(di) as count", "parameters" : { "ID" : "$ID" }"/> + query=""statement": "MATCH (n:Template {short_form:{ID}})<-[:depicts]-(:Template)<-[r:in_register_with]-(dc:Individual)-[:depicts]->(di:Individual) WHERE not exists(r.index) OPTIONAL MATCH (di)-[:INSTANCEOF]->(d:Class) RETURN distinct di.short_form as id, di.label as name, coalesce(di.description[0],d.description[0]) as def, COLLECT(DISTINCT d.label) as type, replace(r.folder[0],'http:','https:') + '/thumbnailT.png' as file", "parameters" : { "ID" : "$ID" }" + countQuery=""statement": "MATCH (n:Template {short_form:{ID}})<-[:depicts]-(:Template)<-[r:in_register_with]-(dc:Individual)-[:depicts]->(di:Individual) WHERE not exists(r.index) RETURN count(di) as count", "parameters" : { "ID" : "$ID" }"/> + query=""statement": "MATCH (ep:Expression_pattern:Class)<-[ar:overlaps|part_of]-(anoni:Individual)-[:INSTANCEOF]->(anat:Class) WHERE ep.short_form in {ARRAY_ID_RESULTS} WITH anoni, anat, ar OPTIONAL MATCH (p:pub { short_form: ar.pub}) WITH anat, anoni, { core: { short_form: p.short_form, label: coalesce(p.label,''), iri: p.iri, types: labels(p), symbol: coalesce(p.`IAO_0000028`[0], '')} , PubMed: coalesce(p.PMID[0], ''), FlyBase: coalesce(p.FlyBase[0], ''), DOI: coalesce(p.DOI[0], '') } AS pub OPTIONAL MATCH (anoni)-[r:Related]->(o:FBdv) WITH CASE WHEN o IS NULL THEN [] ELSE COLLECT ({ relation: { label: r.label, iri: r.iri, type: type(r) } , object: { short_form: o.short_form, label: coalesce(o.label,''), iri: o.iri, types: labels(o), symbol: coalesce(o.`IAO_0000028`[0], '')} }) END AS stages ,anoni,anat,pub CALL apoc.cypher.run('WITH anat OPTIONAL MATCH (anat:Synaptic_neuropil)<- [:has_source|SUBCLASSOF|INSTANCEOF*]-(i:Individual)<-[:depicts]- (channel:Individual)-[irw:in_register_with] ->(template:Individual)-[:depicts]-> (template_anat:Individual) RETURN template, channel, template_anat, i, irw limit 5', {anat:anat}) yield value with value.template as template, value.channel as channel,value.template_anat as template_anat, value.i as i, value.irw as irw, anoni, anat, pub, stages OPTIONAL MATCH (channel)-[:is_specified_output_of]->(technique:Class) WITH CASE WHEN channel IS NULL THEN [] ELSE COLLECT({ anatomy: { short_form: i.short_form, label: coalesce(i.label,''), iri: i.iri, types: labels(i), symbol: coalesce(i.`IAO_0000028`[0], '')} , channel_image: { channel: { short_form: channel.short_form, label: coalesce(channel.label,''), iri: channel.iri, types: labels(channel), symbol: coalesce(channel.`IAO_0000028`[0], '')} , imaging_technique: { short_form: technique.short_form, label: coalesce(technique.label,''), iri: technique.iri, types: labels(technique), symbol: coalesce(technique.`IAO_0000028`[0], '')} ,image: { template_channel : { short_form: template.short_form, label: coalesce(template.label,''), iri: template.iri, types: labels(template), symbol: coalesce(template.`IAO_0000028`[0], '')} , template_anatomy: { short_form: template_anat.short_form, label: coalesce(template_anat.label,''), iri: template_anat.iri, types: labels(template_anat), symbol: coalesce(template_anat.`IAO_0000028`[0], '')} ,image_folder: COALESCE(irw.folder[0], ''), index: coalesce(apoc.convert.toInteger(irw.index[0]), []) + [] }} }) END AS anatomy_channel_image ,anoni,anat,pub,stages RETURN { short_form: anat.short_form, label: coalesce(anat.label,''), iri: anat.iri, types: labels(anat), symbol: coalesce(anat.`IAO_0000028`[0], '')} AS anatomy, 'Get JSON for ep_2_anat query' AS query, '58214d4' AS version , pub, stages, anatomy_channel_image", "parameters" : { "ARRAY_ID_RESULTS" : $ARRAY_ID_RESULTS}" + countQuery=""statement": "MATCH (ep:Expression_pattern:Class)<-[ar:overlaps|part_of]-(anoni:Individual)-[:INSTANCEOF]->(anat:Class) WHERE ep.short_form in {ARRAY_ID_RESULTS} RETURN count(anat) as count", "parameters" : { "ARRAY_ID_RESULTS" : $ARRAY_ID_RESULTS}"/> + query=""statement": "MATCH (ep:Class:Expression_pattern)<-[ar:overlaps|part_of]-(:Individual)-[:INSTANCEOF]->(anat:Class) WHERE anat.short_form in {ARRAY_ID_RESULTS} WITH DISTINCT collect(DISTINCT ar.pub) as pubs, anat, ep UNWIND pubs as p MATCH (pub:pub { short_form: p}) WITH DISTINCT collect(DISTINCT ar.pub) as pubs, anat, ep UNWIND pubs as p MATCH (pub:pub { short_form: p}) WITH anat, ep, collect({ core: { short_form: pub.short_form, label: coalesce(pub.label,''), iri: pub.iri, types: labels(pub), symbol: coalesce(pub.`IAO_0000028`[0], '')} , PubMed: coalesce(pub.PMID[0], ''), FlyBase: coalesce(pub.FlyBase[0], ''), DOI: coalesce(pub.DOI[0], '') }) as pubs CALL apoc.cypher.run('WITH ep OPTIONAL MATCH (ep)<- [:has_source|SUBCLASSOF|INSTANCEOF*]-(i:Individual)<-[:depicts]- (channel:Individual)-[irw:in_register_with] ->(template:Individual)-[:depicts]-> (template_anat:Individual) RETURN template, channel, template_anat, i, irw limit 5', {ep:ep}) yield value with value.template as template, value.channel as channel,value.template_anat as template_anat, value.i as i, value.irw as irw, anat, ep, pubs OPTIONAL MATCH (channel)-[:is_specified_output_of]->(technique:Class) WITH CASE WHEN channel IS NULL THEN [] ELSE COLLECT({ anatomy: { short_form: i.short_form, label: coalesce(i.label,''), iri: i.iri, types: labels(i), symbol: coalesce(i.`IAO_0000028`[0], '')} , channel_image: { channel: { short_form: channel.short_form, label: coalesce(channel.label,''), iri: channel.iri, types: labels(channel), symbol: coalesce(channel.`IAO_0000028`[0], '')} , imaging_technique: { short_form: technique.short_form, label: coalesce(technique.label,''), iri: technique.iri, types: labels(technique), symbol: coalesce(technique.`IAO_0000028`[0], '')} ,image: { template_channel : { short_form: template.short_form, label: coalesce(template.label,''), iri: template.iri, types: labels(template), symbol: coalesce(template.`IAO_0000028`[0], '')} , template_anatomy: { short_form: template_anat.short_form, label: coalesce(template_anat.label,''), iri: template_anat.iri, types: labels(template_anat), symbol: coalesce(template_anat.`IAO_0000028`[0], '')} ,image_folder: COALESCE(irw.folder[0], ''), index: coalesce(apoc.convert.toInteger(irw.index[0]), []) + [] }} }) END AS anatomy_channel_image ,anat,ep,pubs RETURN { short_form: anat.short_form, label: coalesce(anat.label,''), iri: anat.iri, types: labels(anat), symbol: coalesce(anat.`IAO_0000028`[0], '')} as anatomy, { short_form: ep.short_form, label: coalesce(ep.label,''), iri: ep.iri, types: labels(ep), symbol: coalesce(ep.`IAO_0000028`[0], '')} AS expression_pattern, 'Get JSON for anat_2_ep query' AS query, '58214d4' AS version , pubs, anatomy_channel_image", "parameters" : { "ARRAY_ID_RESULTS" : $ARRAY_ID_RESULTS}" + countQuery=""statement": "MATCH (ep:Class:Expression_pattern)<-[ar:overlaps|part_of]-(anoni:Individual)-[:INSTANCEOF]->(anat:Class) WHERE ep.short_form in {ARRAY_ID_RESULTS} RETURN count(anat) as count", "parameters" : { "ARRAY_ID_RESULTS" : $ARRAY_ID_RESULTS}" /> @@ -485,7 +485,7 @@ name="Get JSON for Neuron Class" description="Get JSON for Neuron Class" runForCount="false" - query=""statement": "MATCH (primary:Class) WHERE primary.short_form in [{ID}] WITH primary OPTIONAL MATCH (o:Class)<-[r:SUBCLASSOF|INSTANCEOF]-(primary) WITH CASE WHEN o IS NULL THEN [] ELSE COLLECT ({ short_form: o.short_form, label: coalesce(o.label,''), iri: o.iri, types: labels(o) } ) END AS parents ,primary OPTIONAL MATCH (o:Class)<-[r {type:'Related'}]-(primary) WITH CASE WHEN o IS NULL THEN [] ELSE COLLECT ({ relation: { label: r.label, iri: r.uri, type: type(r) } , object: { short_form: o.short_form, label: coalesce(o.label,''), iri: o.iri, types: labels(o) } }) END AS relationships ,primary,parents OPTIONAL MATCH (o:Individual)<-[r {type:'Related'}]-(primary) WITH CASE WHEN o IS NULL THEN [] ELSE COLLECT ({ relation: { label: r.label, iri: r.uri, type: type(r) } , object: { short_form: o.short_form, label: coalesce(o.label,''), iri: o.iri, types: labels(o) } }) END AS related_individuals ,primary,parents,relationships OPTIONAL MATCH (s:Site { short_form: primary.self_xref }) WITH CASE WHEN s IS NULL THEN [] ELSE COLLECT({ link_base: s.link_base, accession: coalesce(primary.short_form, ''), link_text: primary.label + ' on ' + s.label, site: { short_form: s.short_form, label: coalesce(s.label,''), iri: s.iri, types: labels(s) } , icon: coalesce(s.link_icon_url, ''), link_postfix: coalesce(s.link_postfix, '')}) END AS self_xref, primary, parents, relationships, related_individuals OPTIONAL MATCH (s:Site)<-[dbx:hasDbXref]-(primary) WITH CASE WHEN s IS NULL THEN self_xref ELSE COLLECT({ link_base: s.link_base, accession: coalesce(dbx.accession, ''), link_text: primary.label + ' on ' + s.label, site: { short_form: s.short_form, label: coalesce(s.label,''), iri: s.iri, types: labels(s) } , icon: coalesce(s.link_icon_url, ''), link_postfix: coalesce(s.link_postfix, '')}) + self_xref END AS xrefs,primary,parents,relationships,related_individuals OPTIONAL MATCH (primary)<-[:has_source|SUBCLASSOF|INSTANCEOF*]-(i:Individual)<-[:depicts]-(channel:Individual)-[irw:in_register_with]->(template:Individual)-[:depicts]->(template_anat:Individual) WITH template, channel, template_anat, irw, primary, parents, relationships, related_individuals, xrefs , i limit 5 OPTIONAL MATCH (channel)-[:is_specified_output_of]->(technique:Class) WITH CASE WHEN channel IS NULL THEN [] ELSE COLLECT({ anatomy: { short_form: i.short_form, label: coalesce(i.label,''), iri: i.iri, types: labels(i) } , channel_image: { channel: { short_form: channel.short_form, label: coalesce(channel.label,''), iri: channel.iri, types: labels(channel) } , imaging_technique: { short_form: technique.short_form, label: coalesce(technique.label,''), iri: technique.iri, types: labels(technique) } ,image: { template_channel : { short_form: template.short_form, label: coalesce(template.label,''), iri: template.iri, types: labels(template) } , template_anatomy: { short_form: template_anat.short_form, label: coalesce(template_anat.label,''), iri: template_anat.iri, types: labels(template_anat) } ,image_folder: irw.folder, index: coalesce(irw.index, []) + [] }} }) END AS anatomy_channel_image ,primary,parents,relationships,related_individuals,xrefs OPTIONAL MATCH (primary)-[rp:has_reference { typ: 'syn'}]->(p:pub) WITH CASE WHEN p is null THEN [] ELSE collect({ pub: { core: { short_form: p.short_form, label: coalesce(p.label,''), iri: p.iri, types: labels(p) } , PubMed: coalesce(p.PMID, ''), FlyBase: coalesce(p.FlyBase, ''), DOI: coalesce(p.DOI, '') } , synonym: { label: coalesce(rp.synonym, ''), scope: coalesce(rp.scope, ''), type: coalesce(rp.cat,'') } }) END AS pub_syn,primary,parents,relationships,related_individuals,xrefs,anatomy_channel_image OPTIONAL MATCH (primary)-[rp:has_reference { typ: 'def'}]->(p:pub) WITH CASE WHEN p is null THEN [] ELSE collect({ core: { short_form: p.short_form, label: coalesce(p.label,''), iri: p.iri, types: labels(p) } , PubMed: coalesce(p.PMID, ''), FlyBase: coalesce(p.FlyBase, ''), DOI: coalesce(p.DOI, '') } ) END AS def_pubs,primary,parents,relationships,related_individuals,xrefs,anatomy_channel_image,pub_syn OPTIONAL MATCH (:Class { label: 'intersectional expression pattern'})<-[:SUBCLASSOF]-(ep:Class)<-[ar:part_of]-(anoni:Individual)-[:INSTANCEOF]->(primary) WITH COLLECT({ short_form: ep.short_form, label: coalesce(ep.label,''), iri: ep.iri, types: labels(ep) } ) as targeting_splits,primary,parents,relationships,related_individuals,xrefs,anatomy_channel_image,pub_syn,def_pubs RETURN { core : { short_form: primary.short_form, label: coalesce(primary.label,''), iri: primary.iri, types: labels(primary) } , description : coalesce(primary.description, []), comment : coalesce(primary.`annotation-comment`, []) } AS term, 'Get JSON for Neuron Class' AS query, '2e501bd' AS version , parents, relationships, related_individuals, xrefs, anatomy_channel_image, pub_syn, def_pubs, targeting_splits", "parameters" : { "ID" : "$ID" }" + query=""statement": "MATCH (primary:Class) WHERE primary.short_form in [{ID}] WITH primary OPTIONAL MATCH (o:Class)<-[r:SUBCLASSOF|INSTANCEOF]-(primary) WITH CASE WHEN o IS NULL THEN [] ELSE COLLECT ({ short_form: o.short_form, label: coalesce(o.label,''), iri: o.iri, types: labels(o), symbol: coalesce(o.`IAO_0000028`[0], '')} ) END AS parents ,primary OPTIONAL MATCH (o)<-[r {type:'Related'}]-(primary) WITH CASE WHEN o IS NULL THEN [] ELSE COLLECT ({ relation: { label: r.label, iri: r.iri, type: type(r) } , object: { short_form: o.short_form, label: coalesce(o.label,''), iri: o.iri, types: labels(o), symbol: coalesce(o.`IAO_0000028`[0], '')} }) END AS relationships ,primary,parents OPTIONAL MATCH (o:Individual)<-[r {type:'Related'}]-(primary) WITH CASE WHEN o IS NULL THEN [] ELSE COLLECT ({ relation: { label: r.label, iri: r.iri, type: type(r) } , object: { short_form: o.short_form, label: coalesce(o.label,''), iri: o.iri, types: labels(o), symbol: coalesce(o.`IAO_0000028`[0], '')} }) END AS related_individuals ,primary,parents,relationships OPTIONAL MATCH (s:Site { short_form: primary.self_xref }) WITH CASE WHEN s IS NULL THEN [] ELSE COLLECT({ link_base: coalesce(s.link_base[0], ''), accession: coalesce(primary.short_form, ''), link_text: primary.label + ' on ' + s.label, homepage: coalesce(s.homepage[0], ''), site: { short_form: s.short_form, label: coalesce(s.label,''), iri: s.iri, types: labels(s), symbol: coalesce(s.`IAO_0000028`[0], '')} , icon: coalesce(s.link_icon_url[0], ''), link_postfix: coalesce(s.link_postfix, '')}) END AS self_xref, primary, parents, relationships, related_individuals OPTIONAL MATCH (s:Site)<-[dbx:database_cross_reference]-(primary) WITH CASE WHEN s IS NULL THEN self_xref ELSE COLLECT({ link_base: coalesce(s.link_base[0], ''), accession: coalesce(dbx.accession[0], ''), link_text: primary.label + ' on ' + s.label, homepage: coalesce(s.homepage[0], ''), site: { short_form: s.short_form, label: coalesce(s.label,''), iri: s.iri, types: labels(s), symbol: coalesce(s.`IAO_0000028`[0], '')} , icon: coalesce(s.link_icon_url[0], ''), link_postfix: coalesce(s.link_postfix, '')}) + self_xref END AS xrefs,primary,parents,relationships,related_individuals CALL apoc.cypher.run('WITH primary OPTIONAL MATCH (primary)<-[:has_source|SUBCLASSOF|INSTANCEOF*]-(i:Individual)<-[:depicts]-(channel:Individual)-[irw:in_register_with] ->(template:Individual)-[:depicts]->(template_anat:Individual) RETURN template, channel, template_anat, i, irw limit 5', {primary:primary}) yield value with value.template as template, value.channel as channel,value.template_anat as template_anat, value.i as i, value.irw as irw, primary, parents, relationships, related_individuals, xrefs OPTIONAL MATCH (channel)-[:is_specified_output_of]->(technique:Class) WITH CASE WHEN channel IS NULL THEN [] ELSE COLLECT({ anatomy: { short_form: i.short_form, label: coalesce(i.label,''), iri: i.iri, types: labels(i), symbol: coalesce(i.`IAO_0000028`[0], '')} , channel_image: { channel: { short_form: channel.short_form, label: coalesce(channel.label,''), iri: channel.iri, types: labels(channel), symbol: coalesce(channel.`IAO_0000028`[0], '')} , imaging_technique: { short_form: technique.short_form, label: coalesce(technique.label,''), iri: technique.iri, types: labels(technique), symbol: coalesce(technique.`IAO_0000028`[0], '')} ,image: { template_channel : { short_form: template.short_form, label: coalesce(template.label,''), iri: template.iri, types: labels(template), symbol: coalesce(template.`IAO_0000028`[0], '')} , template_anatomy: { short_form: template_anat.short_form, label: coalesce(template_anat.label,''), iri: template_anat.iri, types: labels(template_anat), symbol: coalesce(template_anat.`IAO_0000028`[0], '')} ,image_folder: COALESCE(irw.folder[0], ''), index: coalesce(apoc.convert.toInteger(irw.index[0]), []) + [] }} }) END AS anatomy_channel_image ,primary,parents,relationships,related_individuals,xrefs OPTIONAL MATCH (primary)-[rp:has_reference]->(p:pub) where rp.typ = 'syn' WITH CASE WHEN p is null THEN [] ELSE collect({ pub: { core: { short_form: p.short_form, label: coalesce(p.label,''), iri: p.iri, types: labels(p), symbol: coalesce(p.`IAO_0000028`[0], '')} , PubMed: coalesce(p.PMID[0], ''), FlyBase: coalesce(p.FlyBase[0], ''), DOI: coalesce(p.DOI[0], '') } , synonym: { label: coalesce(rp.value, ''), scope: coalesce(rp.scope, ''), type: coalesce(rp.has_synonym_type,'') } }) END AS pub_syn,primary,parents,relationships,related_individuals,xrefs,anatomy_channel_image OPTIONAL MATCH (primary)-[rp:has_reference]->(p:pub) WHERE rp.typ = 'def' WITH CASE WHEN p is null THEN [] ELSE collect({ core: { short_form: p.short_form, label: coalesce(p.label,''), iri: p.iri, types: labels(p), symbol: coalesce(p.`IAO_0000028`[0], '')} , PubMed: coalesce(p.PMID[0], ''), FlyBase: coalesce(p.FlyBase[0], ''), DOI: coalesce(p.DOI[0], '') } ) END AS def_pubs,primary,parents,relationships,related_individuals,xrefs,anatomy_channel_image,pub_syn OPTIONAL MATCH (:Class { label: 'intersectional expression pattern'})<-[:SUBCLASSOF]-(ep:Class)<-[ar:part_of]-(anoni:Individual)-[:INSTANCEOF]->(primary) WITH CASE WHEN ep IS NULL THEN [] ELSE COLLECT({ short_form: ep.short_form, label: coalesce(ep.label,''), iri: ep.iri, types: labels(ep), symbol: coalesce(ep.`IAO_0000028`[0], '')} ) END AS targeting_splits,primary,parents,relationships,related_individuals,xrefs,anatomy_channel_image,pub_syn,def_pubs RETURN { core : { short_form: primary.short_form, label: coalesce(primary.label,''), iri: primary.iri, types: labels(primary), symbol: coalesce(primary.`IAO_0000028`[0], '')} , description : coalesce(primary.description, []), comment : coalesce(primary.comment, []) } AS term, 'Get JSON for Neuron Class' AS query, '58214d4' AS version , parents, relationships, related_individuals, xrefs, anatomy_channel_image, pub_syn, def_pubs, targeting_splits", "parameters" : { "ID" : "$ID" }" countQuery=""statement": "MATCH (primary:Class {short_form: {ID}} ) RETURN count(primary) as count", "parameters" : { "ID" : "$ID" }"> @@ -495,7 +495,7 @@ name="Get JSON for Split Class" description="Get JSON for Split Class" runForCount="false" - query=""statement": "MATCH (primary:Class) WHERE primary.short_form in [{ID}] WITH primary OPTIONAL MATCH (o:Class)<-[r:SUBCLASSOF|INSTANCEOF]-(primary) WITH CASE WHEN o IS NULL THEN [] ELSE COLLECT ({ short_form: o.short_form, label: coalesce(o.label,''), iri: o.iri, types: labels(o) } ) END AS parents ,primary OPTIONAL MATCH (o:Class)<-[r {type:'Related'}]-(primary) WITH CASE WHEN o IS NULL THEN [] ELSE COLLECT ({ relation: { label: r.label, iri: r.uri, type: type(r) } , object: { short_form: o.short_form, label: coalesce(o.label,''), iri: o.iri, types: labels(o) } }) END AS relationships ,primary,parents OPTIONAL MATCH (o:Individual)<-[r {type:'Related'}]-(primary) WITH CASE WHEN o IS NULL THEN [] ELSE COLLECT ({ relation: { label: r.label, iri: r.uri, type: type(r) } , object: { short_form: o.short_form, label: coalesce(o.label,''), iri: o.iri, types: labels(o) } }) END AS related_individuals ,primary,parents,relationships OPTIONAL MATCH (s:Site { short_form: primary.self_xref }) WITH CASE WHEN s IS NULL THEN [] ELSE COLLECT({ link_base: s.link_base, accession: coalesce(primary.short_form, ''), link_text: primary.label + ' on ' + s.label, site: { short_form: s.short_form, label: coalesce(s.label,''), iri: s.iri, types: labels(s) } , icon: coalesce(s.link_icon_url, ''), link_postfix: coalesce(s.link_postfix, '')}) END AS self_xref, primary, parents, relationships, related_individuals OPTIONAL MATCH (s:Site)<-[dbx:hasDbXref]-(primary) WITH CASE WHEN s IS NULL THEN self_xref ELSE COLLECT({ link_base: s.link_base, accession: coalesce(dbx.accession, ''), link_text: primary.label + ' on ' + s.label, site: { short_form: s.short_form, label: coalesce(s.label,''), iri: s.iri, types: labels(s) } , icon: coalesce(s.link_icon_url, ''), link_postfix: coalesce(s.link_postfix, '')}) + self_xref END AS xrefs,primary,parents,relationships,related_individuals OPTIONAL MATCH (primary)<-[:has_source|SUBCLASSOF|INSTANCEOF*]-(i:Individual)<-[:depicts]-(channel:Individual)-[irw:in_register_with]->(template:Individual)-[:depicts]->(template_anat:Individual) WITH template, channel, template_anat, irw, primary, parents, relationships, related_individuals, xrefs , i limit 5 OPTIONAL MATCH (channel)-[:is_specified_output_of]->(technique:Class) WITH CASE WHEN channel IS NULL THEN [] ELSE COLLECT({ anatomy: { short_form: i.short_form, label: coalesce(i.label,''), iri: i.iri, types: labels(i) } , channel_image: { channel: { short_form: channel.short_form, label: coalesce(channel.label,''), iri: channel.iri, types: labels(channel) } , imaging_technique: { short_form: technique.short_form, label: coalesce(technique.label,''), iri: technique.iri, types: labels(technique) } ,image: { template_channel : { short_form: template.short_form, label: coalesce(template.label,''), iri: template.iri, types: labels(template) } , template_anatomy: { short_form: template_anat.short_form, label: coalesce(template_anat.label,''), iri: template_anat.iri, types: labels(template_anat) } ,image_folder: irw.folder, index: coalesce(irw.index, []) + [] }} }) END AS anatomy_channel_image ,primary,parents,relationships,related_individuals,xrefs OPTIONAL MATCH (primary)-[rp:has_reference { typ: 'syn'}]->(p:pub) WITH CASE WHEN p is null THEN [] ELSE collect({ pub: { core: { short_form: p.short_form, label: coalesce(p.label,''), iri: p.iri, types: labels(p) } , PubMed: coalesce(p.PMID, ''), FlyBase: coalesce(p.FlyBase, ''), DOI: coalesce(p.DOI, '') } , synonym: { label: coalesce(rp.synonym, ''), scope: coalesce(rp.scope, ''), type: coalesce(rp.cat,'') } }) END AS pub_syn,primary,parents,relationships,related_individuals,xrefs,anatomy_channel_image OPTIONAL MATCH (primary)-[rp:has_reference { typ: 'def'}]->(p:pub) WITH CASE WHEN p is null THEN [] ELSE collect({ core: { short_form: p.short_form, label: coalesce(p.label,''), iri: p.iri, types: labels(p) } , PubMed: coalesce(p.PMID, ''), FlyBase: coalesce(p.FlyBase, ''), DOI: coalesce(p.DOI, '') } ) END AS def_pubs,primary,parents,relationships,related_individuals,xrefs,anatomy_channel_image,pub_syn OPTIONAL MATCH (:Class { label: 'intersectional expression pattern'})<-[:SUBCLASSOF]-(primary)<-[ar:part_of]-(anoni:Individual)-[:INSTANCEOF]->(n:Neuron) WITH COLLECT({ short_form: n.short_form, label: coalesce(n.label,''), iri: n.iri, types: labels(n) } ) as target_neurons,primary,parents,relationships,related_individuals,xrefs,anatomy_channel_image,pub_syn,def_pubs RETURN { core : { short_form: primary.short_form, label: coalesce(primary.label,''), iri: primary.iri, types: labels(primary) } , description : coalesce(primary.description, []), comment : coalesce(primary.`annotation-comment`, []) } AS term, 'Get JSON for Split Class' AS query, '2e501bd' AS version , parents, relationships, related_individuals, xrefs, anatomy_channel_image, pub_syn, def_pubs, target_neurons", "parameters" : { "ID" : "$ID" }" + query=""statement": "MATCH (primary:Class) WHERE primary.short_form in [{ID}] WITH primary OPTIONAL MATCH (o:Class)<-[r:SUBCLASSOF|INSTANCEOF]-(primary) WITH CASE WHEN o IS NULL THEN [] ELSE COLLECT ({ short_form: o.short_form, label: coalesce(o.label,''), iri: o.iri, types: labels(o), symbol: coalesce(o.`IAO_0000028`[0], '')} ) END AS parents ,primary OPTIONAL MATCH (o)<-[r {type:'Related'}]-(primary) WITH CASE WHEN o IS NULL THEN [] ELSE COLLECT ({ relation: { label: r.label, iri: r.iri, type: type(r) } , object: { short_form: o.short_form, label: coalesce(o.label,''), iri: o.iri, types: labels(o), symbol: coalesce(o.`IAO_0000028`[0], '')} }) END AS relationships ,primary,parents OPTIONAL MATCH (o:Individual)<-[r {type:'Related'}]-(primary) WITH CASE WHEN o IS NULL THEN [] ELSE COLLECT ({ relation: { label: r.label, iri: r.iri, type: type(r) } , object: { short_form: o.short_form, label: coalesce(o.label,''), iri: o.iri, types: labels(o), symbol: coalesce(o.`IAO_0000028`[0], '')} }) END AS related_individuals ,primary,parents,relationships OPTIONAL MATCH (s:Site { short_form: primary.self_xref }) WITH CASE WHEN s IS NULL THEN [] ELSE COLLECT({ link_base: coalesce(s.link_base[0], ''), accession: coalesce(primary.short_form, ''), link_text: primary.label + ' on ' + s.label, homepage: coalesce(s.homepage[0], ''), site: { short_form: s.short_form, label: coalesce(s.label,''), iri: s.iri, types: labels(s), symbol: coalesce(s.`IAO_0000028`[0], '')} , icon: coalesce(s.link_icon_url[0], ''), link_postfix: coalesce(s.link_postfix, '')}) END AS self_xref, primary, parents, relationships, related_individuals OPTIONAL MATCH (s:Site)<-[dbx:database_cross_reference]-(primary) WITH CASE WHEN s IS NULL THEN self_xref ELSE COLLECT({ link_base: coalesce(s.link_base[0], ''), accession: coalesce(dbx.accession[0], ''), link_text: primary.label + ' on ' + s.label, homepage: coalesce(s.homepage[0], ''), site: { short_form: s.short_form, label: coalesce(s.label,''), iri: s.iri, types: labels(s), symbol: coalesce(s.`IAO_0000028`[0], '')} , icon: coalesce(s.link_icon_url[0], ''), link_postfix: coalesce(s.link_postfix, '')}) + self_xref END AS xrefs,primary,parents,relationships,related_individuals CALL apoc.cypher.run('WITH primary OPTIONAL MATCH (primary)<-[:has_source|SUBCLASSOF|INSTANCEOF*]-(i:Individual)<-[:depicts]-(channel:Individual)-[irw:in_register_with] ->(template:Individual)-[:depicts]->(template_anat:Individual) RETURN template, channel, template_anat, i, irw limit 5', {primary:primary}) yield value with value.template as template, value.channel as channel,value.template_anat as template_anat, value.i as i, value.irw as irw, primary, parents, relationships, related_individuals, xrefs OPTIONAL MATCH (channel)-[:is_specified_output_of]->(technique:Class) WITH CASE WHEN channel IS NULL THEN [] ELSE COLLECT({ anatomy: { short_form: i.short_form, label: coalesce(i.label,''), iri: i.iri, types: labels(i), symbol: coalesce(i.`IAO_0000028`[0], '')} , channel_image: { channel: { short_form: channel.short_form, label: coalesce(channel.label,''), iri: channel.iri, types: labels(channel), symbol: coalesce(channel.`IAO_0000028`[0], '')} , imaging_technique: { short_form: technique.short_form, label: coalesce(technique.label,''), iri: technique.iri, types: labels(technique), symbol: coalesce(technique.`IAO_0000028`[0], '')} ,image: { template_channel : { short_form: template.short_form, label: coalesce(template.label,''), iri: template.iri, types: labels(template), symbol: coalesce(template.`IAO_0000028`[0], '')} , template_anatomy: { short_form: template_anat.short_form, label: coalesce(template_anat.label,''), iri: template_anat.iri, types: labels(template_anat), symbol: coalesce(template_anat.`IAO_0000028`[0], '')} ,image_folder: COALESCE(irw.folder[0], ''), index: coalesce(apoc.convert.toInteger(irw.index[0]), []) + [] }} }) END AS anatomy_channel_image ,primary,parents,relationships,related_individuals,xrefs OPTIONAL MATCH (primary)-[rp:has_reference]->(p:pub) where rp.typ = 'syn' WITH CASE WHEN p is null THEN [] ELSE collect({ pub: { core: { short_form: p.short_form, label: coalesce(p.label,''), iri: p.iri, types: labels(p), symbol: coalesce(p.`IAO_0000028`[0], '')} , PubMed: coalesce(p.PMID[0], ''), FlyBase: coalesce(p.FlyBase[0], ''), DOI: coalesce(p.DOI[0], '') } , synonym: { label: coalesce(rp.value, ''), scope: coalesce(rp.scope, ''), type: coalesce(rp.has_synonym_type,'') } }) END AS pub_syn,primary,parents,relationships,related_individuals,xrefs,anatomy_channel_image OPTIONAL MATCH (primary)-[rp:has_reference]->(p:pub) WHERE rp.typ = 'def' WITH CASE WHEN p is null THEN [] ELSE collect({ core: { short_form: p.short_form, label: coalesce(p.label,''), iri: p.iri, types: labels(p), symbol: coalesce(p.`IAO_0000028`[0], '')} , PubMed: coalesce(p.PMID[0], ''), FlyBase: coalesce(p.FlyBase[0], ''), DOI: coalesce(p.DOI[0], '') } ) END AS def_pubs,primary,parents,relationships,related_individuals,xrefs,anatomy_channel_image,pub_syn OPTIONAL MATCH (:Class { label: 'intersectional expression pattern'})<-[:SUBCLASSOF]-(primary)<-[ar:part_of]-(anoni:Individual)-[:INSTANCEOF]->(n:Neuron) WITH CASE WHEN n IS NULL THEN [] ELSE COLLECT({ short_form: n.short_form, label: coalesce(n.label,''), iri: n.iri, types: labels(n), symbol: coalesce(n.`IAO_0000028`[0], '')} ) END AS target_neurons,primary,parents,relationships,related_individuals,xrefs,anatomy_channel_image,pub_syn,def_pubs RETURN { core : { short_form: primary.short_form, label: coalesce(primary.label,''), iri: primary.iri, types: labels(primary), symbol: coalesce(primary.`IAO_0000028`[0], '')} , description : coalesce(primary.description, []), comment : coalesce(primary.comment, []) } AS term, 'Get JSON for Split Class' AS query, '58214d4' AS version , parents, relationships, related_individuals, xrefs, anatomy_channel_image, pub_syn, def_pubs, target_neurons", "parameters" : { "ID" : "$ID" }" countQuery=""statement": "MATCH (primary:Class {short_form: {ID}} ) RETURN count(primary) as count", "parameters" : { "ID" : "$ID" }"> @@ -505,7 +505,7 @@ name="Get JSON for Individual" description="Get JSON for Individual:Anatomy" runForCount="false" - query=""statement": "MATCH (primary:Individual:Anatomy) WHERE primary.short_form in [{ID}] WITH primary OPTIONAL MATCH (primary)-[:has_source]->(ds:DataSet)-[:has_license]->(l:License) WITH COLLECT ({ dataset: { link : coalesce(ds.dataset_link, ''), core : { short_form: ds.short_form, label: coalesce(ds.label,''), iri: ds.iri, types: labels(ds) } }, license: { icon : coalesce(l.license_logo, ''), link : coalesce(l.license_url, ''), core : { short_form: l.short_form, label: coalesce(l.label,''), iri: l.iri, types: labels(l) } }}) AS dataset_license,primary OPTIONAL MATCH (o:Class)<-[r:SUBCLASSOF|INSTANCEOF]-(primary) WITH CASE WHEN o IS NULL THEN [] ELSE COLLECT ({ short_form: o.short_form, label: coalesce(o.label,''), iri: o.iri, types: labels(o) } ) END AS parents ,primary,dataset_license OPTIONAL MATCH (o:Class)<-[r {type:'Related'}]-(primary) WITH CASE WHEN o IS NULL THEN [] ELSE COLLECT ({ relation: { label: r.label, iri: r.uri, type: type(r) } , object: { short_form: o.short_form, label: coalesce(o.label,''), iri: o.iri, types: labels(o) } }) END AS relationships ,primary,dataset_license,parents OPTIONAL MATCH (s:Site { short_form: primary.self_xref }) WITH CASE WHEN s IS NULL THEN [] ELSE COLLECT({ link_base: s.link_base, accession: coalesce(primary.short_form, ''), link_text: primary.label + ' on ' + s.label, site: { short_form: s.short_form, label: coalesce(s.label,''), iri: s.iri, types: labels(s) } , icon: coalesce(s.link_icon_url, ''), link_postfix: coalesce(s.link_postfix, '')}) END AS self_xref, primary, dataset_license, parents, relationships OPTIONAL MATCH (s:Site)<-[dbx:hasDbXref]-(primary) WITH CASE WHEN s IS NULL THEN self_xref ELSE COLLECT({ link_base: s.link_base, accession: coalesce(dbx.accession, ''), link_text: primary.label + ' on ' + s.label, site: { short_form: s.short_form, label: coalesce(s.label,''), iri: s.iri, types: labels(s) } , icon: coalesce(s.link_icon_url, ''), link_postfix: coalesce(s.link_postfix, '')}) + self_xref END AS xrefs,primary,dataset_license,parents,relationships OPTIONAL MATCH (primary)<-[:depicts]-(channel:Individual)-[irw:in_register_with]->(template:Individual)-[:depicts]->(template_anat:Individual) WITH template, channel, template_anat, irw, primary, dataset_license, parents, relationships, xrefs OPTIONAL MATCH (channel)-[:is_specified_output_of]->(technique:Class) WITH CASE WHEN channel IS NULL THEN [] ELSE collect ({ channel: { short_form: channel.short_form, label: coalesce(channel.label,''), iri: channel.iri, types: labels(channel) } , imaging_technique: { short_form: technique.short_form, label: coalesce(technique.label,''), iri: technique.iri, types: labels(technique) } ,image: { template_channel : { short_form: template.short_form, label: coalesce(template.label,''), iri: template.iri, types: labels(template) } , template_anatomy: { short_form: template_anat.short_form, label: coalesce(template_anat.label,''), iri: template_anat.iri, types: labels(template_anat) } ,image_folder: irw.folder, index: coalesce(irw.index, []) + [] }}) END AS channel_image,primary,dataset_license,parents,relationships,xrefs OPTIONAL MATCH (o:Individual)<-[r {type:'Related'}]-(primary) WITH CASE WHEN o IS NULL THEN [] ELSE COLLECT ({ relation: { label: r.label, iri: r.uri, type: type(r) } , object: { short_form: o.short_form, label: coalesce(o.label,''), iri: o.iri, types: labels(o) } }) END AS related_individuals ,primary,dataset_license,parents,relationships,xrefs,channel_image RETURN { core : { short_form: primary.short_form, label: coalesce(primary.label,''), iri: primary.iri, types: labels(primary) } , description : coalesce(primary.description, []), comment : coalesce(primary.`annotation-comment`, []) } AS term, 'Get JSON for Individual:Anatomy' AS query, 'ca9ab19' AS version , dataset_license, parents, relationships, xrefs, channel_image, related_individuals", "parameters" : { "ID" : "$ID" }" + query=""statement": "MATCH (primary:Individual:Anatomy) WHERE primary.short_form in [{ID}] WITH primary OPTIONAL MATCH (primary)-[:has_source]-(ds:DataSet)-[:has_license]->(l:License) WITH COLLECT ({ dataset: { link : coalesce(ds.dataset_link[0], ''), core : { short_form: ds.short_form, label: coalesce(ds.label,''), iri: ds.iri, types: labels(ds), symbol: coalesce(ds.`IAO_0000028`[0], '')} }, license: { icon : coalesce(l.license_logo[0], ''), link : coalesce(l.license_url[0], ''), core : { short_form: l.short_form, label: coalesce(l.label,''), iri: l.iri, types: labels(l), symbol: coalesce(l.`IAO_0000028`[0], '')} }}) AS dataset_license,primary OPTIONAL MATCH (o:Class)<-[r:SUBCLASSOF|INSTANCEOF]-(primary) WITH CASE WHEN o IS NULL THEN [] ELSE COLLECT ({ short_form: o.short_form, label: coalesce(o.label,''), iri: o.iri, types: labels(o), symbol: coalesce(o.`IAO_0000028`[0], '')} ) END AS parents ,primary,dataset_license OPTIONAL MATCH (o)<-[r {type:'Related'}]-(primary) WITH CASE WHEN o IS NULL THEN [] ELSE COLLECT ({ relation: { label: r.label, iri: r.iri, type: type(r) } , object: { short_form: o.short_form, label: coalesce(o.label,''), iri: o.iri, types: labels(o), symbol: coalesce(o.`IAO_0000028`[0], '')} }) END AS relationships ,primary,dataset_license,parents OPTIONAL MATCH (s:Site { short_form: primary.self_xref }) WITH CASE WHEN s IS NULL THEN [] ELSE COLLECT({ link_base: coalesce(s.link_base[0], ''), accession: coalesce(primary.short_form, ''), link_text: primary.label + ' on ' + s.label, homepage: coalesce(s.homepage[0], ''), site: { short_form: s.short_form, label: coalesce(s.label,''), iri: s.iri, types: labels(s), symbol: coalesce(s.`IAO_0000028`[0], '')} , icon: coalesce(s.link_icon_url[0], ''), link_postfix: coalesce(s.link_postfix, '')}) END AS self_xref, primary, dataset_license, parents, relationships OPTIONAL MATCH (s:Site)<-[dbx:database_cross_reference]-(primary) WITH CASE WHEN s IS NULL THEN self_xref ELSE COLLECT({ link_base: coalesce(s.link_base[0], ''), accession: coalesce(dbx.accession[0], ''), link_text: primary.label + ' on ' + s.label, homepage: coalesce(s.homepage[0], ''), site: { short_form: s.short_form, label: coalesce(s.label,''), iri: s.iri, types: labels(s), symbol: coalesce(s.`IAO_0000028`[0], '')} , icon: coalesce(s.link_icon_url[0], ''), link_postfix: coalesce(s.link_postfix, '')}) + self_xref END AS xrefs,primary,dataset_license,parents,relationships OPTIONAL MATCH (primary)<-[:depicts]-(channel:Individual)-[irw:in_register_with]->(template:Individual)-[:depicts]->(template_anat:Individual) WITH template, channel, template_anat, irw, primary, dataset_license, parents, relationships, xrefs OPTIONAL MATCH (channel)-[:is_specified_output_of]->(technique:Class) WITH CASE WHEN channel IS NULL THEN [] ELSE collect ({ channel: { short_form: channel.short_form, label: coalesce(channel.label,''), iri: channel.iri, types: labels(channel), symbol: coalesce(channel.`IAO_0000028`[0], '')} , imaging_technique: { short_form: technique.short_form, label: coalesce(technique.label,''), iri: technique.iri, types: labels(technique), symbol: coalesce(technique.`IAO_0000028`[0], '')} ,image: { template_channel : { short_form: template.short_form, label: coalesce(template.label,''), iri: template.iri, types: labels(template), symbol: coalesce(template.`IAO_0000028`[0], '')} , template_anatomy: { short_form: template_anat.short_form, label: coalesce(template_anat.label,''), iri: template_anat.iri, types: labels(template_anat), symbol: coalesce(template_anat.`IAO_0000028`[0], '')} ,image_folder: COALESCE(irw.folder[0], ''), index: coalesce(apoc.convert.toInteger(irw.index[0]), []) + [] }}) END AS channel_image,primary,dataset_license,parents,relationships,xrefs OPTIONAL MATCH (o:Individual)<-[r {type:'Related'}]-(primary) WITH CASE WHEN o IS NULL THEN [] ELSE COLLECT ({ relation: { label: r.label, iri: r.iri, type: type(r) } , object: { short_form: o.short_form, label: coalesce(o.label,''), iri: o.iri, types: labels(o), symbol: coalesce(o.`IAO_0000028`[0], '')} }) END AS related_individuals ,primary,dataset_license,parents,relationships,xrefs,channel_image RETURN { core : { short_form: primary.short_form, label: coalesce(primary.label,''), iri: primary.iri, types: labels(primary), symbol: coalesce(primary.`IAO_0000028`[0], '')} , description : coalesce(primary.description, []), comment : coalesce(primary.comment, []) } AS term, 'Get JSON for Individual:Anatomy' AS query, '58214d4' AS version , dataset_license, parents, relationships, xrefs, channel_image, related_individuals", "parameters" : { "ID" : "$ID" }" countQuery=""statement": "MATCH (primary:Individual {short_form: {ID}} ) RETURN count(primary) as count", "parameters" : { "ID" : "$ID" }"> @@ -515,7 +515,7 @@ name="Get JSON for Template" description="Get JSON for Template" runForCount="false" - query=""statement": "MATCH (primary:Template) WHERE primary.short_form in [{ID}] WITH primary MATCH (channel:Individual)<-[irw:in_register_with]-(channel:Individual)-[:depicts]->(primary) WITH { index: coalesce(irw.index, []) + [], extent: irw.extent, center: irw.center, voxel: irw.voxel, orientation: irw.orientation, image_folder: irw.folder, channel: { short_form: channel.short_form, label: coalesce(channel.label,''), iri: channel.iri, types: labels(channel) } } as template_channel,primary OPTIONAL MATCH (technique:Class)<-[:is_specified_output_of]-(channel:Individual)-[irw:in_register_with]->(template:Individual)-[:depicts]->(primary) WHERE has(irw.index) WITH primary, template_channel, collect ({ channel: channel, irw: irw}) AS painted_domains UNWIND painted_domains AS pd MATCH (channel:Individual { short_form: pd.channel.short_form})-[:depicts]-(ai:Individual)-[:INSTANCEOF]->(c:Class) WITH collect({ anatomical_type: { short_form: c.short_form, label: coalesce(c.label,''), iri: c.iri, types: labels(c) } , anatomical_individual: { short_form: ai.short_form, label: coalesce(ai.label,''), iri: ai.iri, types: labels(ai) } , folder: pd.irw.folder, center: coalesce (pd.irw.center, []), index: [] + coalesce (pd.irw.index, []) }) AS template_domains,primary,template_channel OPTIONAL MATCH (primary)-[:has_source]->(ds:DataSet)-[:has_license]->(l:License) WITH COLLECT ({ dataset: { link : coalesce(ds.dataset_link, ''), core : { short_form: ds.short_form, label: coalesce(ds.label,''), iri: ds.iri, types: labels(ds) } }, license: { icon : coalesce(l.license_logo, ''), link : coalesce(l.license_url, ''), core : { short_form: l.short_form, label: coalesce(l.label,''), iri: l.iri, types: labels(l) } }}) AS dataset_license,primary,template_channel,template_domains OPTIONAL MATCH (o:Class)<-[r:SUBCLASSOF|INSTANCEOF]-(primary) WITH CASE WHEN o IS NULL THEN [] ELSE COLLECT ({ short_form: o.short_form, label: coalesce(o.label,''), iri: o.iri, types: labels(o) } ) END AS parents ,primary,template_channel,template_domains,dataset_license OPTIONAL MATCH (o:Class)<-[r {type:'Related'}]-(primary) WITH CASE WHEN o IS NULL THEN [] ELSE COLLECT ({ relation: { label: r.label, iri: r.uri, type: type(r) } , object: { short_form: o.short_form, label: coalesce(o.label,''), iri: o.iri, types: labels(o) } }) END AS relationships ,primary,template_channel,template_domains,dataset_license,parents OPTIONAL MATCH (s:Site { short_form: primary.self_xref }) WITH CASE WHEN s IS NULL THEN [] ELSE COLLECT({ link_base: s.link_base, accession: coalesce(primary.short_form, ''), link_text: primary.label + ' on ' + s.label, site: { short_form: s.short_form, label: coalesce(s.label,''), iri: s.iri, types: labels(s) } , icon: coalesce(s.link_icon_url, ''), link_postfix: coalesce(s.link_postfix, '')}) END AS self_xref, primary, template_channel, template_domains, dataset_license, parents, relationships OPTIONAL MATCH (s:Site)<-[dbx:hasDbXref]-(primary) WITH CASE WHEN s IS NULL THEN self_xref ELSE COLLECT({ link_base: s.link_base, accession: coalesce(dbx.accession, ''), link_text: primary.label + ' on ' + s.label, site: { short_form: s.short_form, label: coalesce(s.label,''), iri: s.iri, types: labels(s) } , icon: coalesce(s.link_icon_url, ''), link_postfix: coalesce(s.link_postfix, '')}) + self_xref END AS xrefs,primary,template_channel,template_domains,dataset_license,parents,relationships OPTIONAL MATCH (o:Individual)<-[r {type:'Related'}]-(primary) WITH CASE WHEN o IS NULL THEN [] ELSE COLLECT ({ relation: { label: r.label, iri: r.uri, type: type(r) } , object: { short_form: o.short_form, label: coalesce(o.label,''), iri: o.iri, types: labels(o) } }) END AS related_individuals ,primary,template_channel,template_domains,dataset_license,parents,relationships,xrefs RETURN { core : { short_form: primary.short_form, label: coalesce(primary.label,''), iri: primary.iri, types: labels(primary) } , description : coalesce(primary.description, []), comment : coalesce(primary.`annotation-comment`, []) } AS term, 'Get JSON for Template' AS query, 'ca9ab19' AS version , template_channel, template_domains, dataset_license, parents, relationships, xrefs, related_individuals", "parameters" : { "ID" : "$ID" }" + query=""statement": "MATCH (primary:Template) WHERE primary.short_form in [{ID}] WITH primary MATCH (channel:Individual)<-[irw:in_register_with]-(channel:Individual)-[:depicts]->(primary) WITH { index: coalesce(apoc.convert.toInteger(irw.index), []) + [], extent: irw.extent[0], center: irw.center[0], voxel: irw.voxel[0], orientation: coalesce(irw.orientation[0], ''), image_folder: coalesce(irw.folder[0],''), channel: { short_form: channel.short_form, label: coalesce(channel.label,''), iri: channel.iri, types: labels(channel), symbol: coalesce(channel.`IAO_0000028`[0], '')} } as template_channel,primary OPTIONAL MATCH (technique:Class)<-[:is_specified_output_of]-(channel:Individual)-[irw:in_register_with]->(template:Individual)-[:depicts]->(primary) WHERE technique.short_form = 'FBbi_00000224' AND exists(irw.index) WITH primary, template_channel, collect ({ channel: channel, irw: irw}) AS painted_domains UNWIND painted_domains AS pd MATCH (channel:Individual { short_form: pd.channel.short_form})-[:depicts]-(ai:Individual)-[:INSTANCEOF]->(c:Class) WITH collect({ anatomical_type: { short_form: c.short_form, label: coalesce(c.label,''), iri: c.iri, types: labels(c), symbol: coalesce(c.`IAO_0000028`[0], '')} , anatomical_individual: { short_form: ai.short_form, label: coalesce(ai.label,''), iri: ai.iri, types: labels(ai), symbol: coalesce(ai.`IAO_0000028`[0], '')} , folder: pd.irw.folder[0], center: coalesce (pd.irw.center, []), index: [] + coalesce (pd.irw.index, []) }) AS template_domains,primary,template_channel OPTIONAL MATCH (primary)-[:has_source]-(ds:DataSet)-[:has_license]->(l:License) WITH COLLECT ({ dataset: { link : coalesce(ds.dataset_link[0], ''), core : { short_form: ds.short_form, label: coalesce(ds.label,''), iri: ds.iri, types: labels(ds), symbol: coalesce(ds.`IAO_0000028`[0], '')} }, license: { icon : coalesce(l.license_logo[0], ''), link : coalesce(l.license_url[0], ''), core : { short_form: l.short_form, label: coalesce(l.label,''), iri: l.iri, types: labels(l), symbol: coalesce(l.`IAO_0000028`[0], '')} }}) AS dataset_license,primary,template_channel,template_domains OPTIONAL MATCH (o:Class)<-[r:SUBCLASSOF|INSTANCEOF]-(primary) WITH CASE WHEN o IS NULL THEN [] ELSE COLLECT ({ short_form: o.short_form, label: coalesce(o.label,''), iri: o.iri, types: labels(o), symbol: coalesce(o.`IAO_0000028`[0], '')} ) END AS parents ,primary,template_channel,template_domains,dataset_license OPTIONAL MATCH (o)<-[r {type:'Related'}]-(primary) WITH CASE WHEN o IS NULL THEN [] ELSE COLLECT ({ relation: { label: r.label, iri: r.iri, type: type(r) } , object: { short_form: o.short_form, label: coalesce(o.label,''), iri: o.iri, types: labels(o), symbol: coalesce(o.`IAO_0000028`[0], '')} }) END AS relationships ,primary,template_channel,template_domains,dataset_license,parents OPTIONAL MATCH (s:Site { short_form: primary.self_xref }) WITH CASE WHEN s IS NULL THEN [] ELSE COLLECT({ link_base: coalesce(s.link_base[0], ''), accession: coalesce(primary.short_form, ''), link_text: primary.label + ' on ' + s.label, homepage: coalesce(s.homepage[0], ''), site: { short_form: s.short_form, label: coalesce(s.label,''), iri: s.iri, types: labels(s), symbol: coalesce(s.`IAO_0000028`[0], '')} , icon: coalesce(s.link_icon_url[0], ''), link_postfix: coalesce(s.link_postfix, '')}) END AS self_xref, primary, template_channel, template_domains, dataset_license, parents, relationships OPTIONAL MATCH (s:Site)<-[dbx:database_cross_reference]-(primary) WITH CASE WHEN s IS NULL THEN self_xref ELSE COLLECT({ link_base: coalesce(s.link_base[0], ''), accession: coalesce(dbx.accession[0], ''), link_text: primary.label + ' on ' + s.label, homepage: coalesce(s.homepage[0], ''), site: { short_form: s.short_form, label: coalesce(s.label,''), iri: s.iri, types: labels(s), symbol: coalesce(s.`IAO_0000028`[0], '')} , icon: coalesce(s.link_icon_url[0], ''), link_postfix: coalesce(s.link_postfix, '')}) + self_xref END AS xrefs,primary,template_channel,template_domains,dataset_license,parents,relationships OPTIONAL MATCH (o:Individual)<-[r {type:'Related'}]-(primary) WITH CASE WHEN o IS NULL THEN [] ELSE COLLECT ({ relation: { label: r.label, iri: r.iri, type: type(r) } , object: { short_form: o.short_form, label: coalesce(o.label,''), iri: o.iri, types: labels(o), symbol: coalesce(o.`IAO_0000028`[0], '')} }) END AS related_individuals ,primary,template_channel,template_domains,dataset_license,parents,relationships,xrefs RETURN { core : { short_form: primary.short_form, label: coalesce(primary.label,''), iri: primary.iri, types: labels(primary), symbol: coalesce(primary.`IAO_0000028`[0], '')} , description : coalesce(primary.description, []), comment : coalesce(primary.comment, []) } AS term, 'Get JSON for Template' AS query, '58214d4' AS version , template_channel, template_domains, dataset_license, parents, relationships, xrefs, related_individuals", "parameters" : { "ID" : "$ID" }" countQuery=""statement": "MATCH (primary:Template {short_form: {ID}} ) RETURN count(primary) as count", "parameters" : { "ID" : "$ID" }"> @@ -525,7 +525,7 @@ name="Get JSON for pub" description="Fetches JSON for pub." runForCount="false" - query=""statement": "MATCH (primary:pub:Individual {short_form: {ID} }) OPTIONAL MATCH (o)-[r:has_reference]->(primary) WHERE o:DataSet OR o:Class WITH primary, r, o ORDER BY labels(o)[0] DESC, o.label ASC WITH CASE WHEN o IS NULL THEN [] ELSE COLLECT (DISTINCT { relation: { label: r.label, iri: r.uri, type: type(r) }, object: { short_form: o.short_form, label: o.label, iri: o.iri, types: labels(o) } }) END AS relationships, primary RETURN { core: { short_form: primary.short_form, label: primary.label, iri: primary.iri, types: labels(primary) } , description: coalesce(primary.description, []), comment: coalesce(primary.`annotation-comment`, [])} as term, relationships, 'pub' as query, 'manual' AS version", "parameters" : { "ID" : "$ID" }" + query=""statement": "MATCH (primary:Individual:pub) WHERE primary.short_form in [{ID}] WITH primary OPTIONAL MATCH (primary)-[:has_reference]-(ds:DataSet)-[:has_license]->(l:License) WITH COLLECT ({ dataset: { link : coalesce(ds.dataset_link[0], ''), core : { short_form: ds.short_form, label: coalesce(ds.label,''), iri: ds.iri, types: labels(ds), symbol: coalesce(ds.`IAO_0000028`[0], '')} }, license: { icon : coalesce(l.license_logo[0], ''), link : coalesce(l.license_url[0], ''), core : { short_form: l.short_form, label: coalesce(l.label,''), iri: l.iri, types: labels(l), symbol: coalesce(l.`IAO_0000028`[0], '')} }}) AS dataset_license,primary RETURN { core : { short_form: primary.short_form, label: coalesce(primary.label,''), iri: primary.iri, types: labels(primary), symbol: coalesce(primary.`IAO_0000028`[0], '')} , description : coalesce(primary.description, []), comment : coalesce(primary.comment, []) } AS term, '58214d4' AS version , dataset_license, {title: coalesce(primary.title[0], '') ,PubMed: coalesce(primary.PMID[0], ''), FlyBase: coalesce(primary.FlyBase[0], ''), DOI: coalesce(primary.DOI[0], '') }AS pub_specific_content", "parameters" : { "ID" : "$ID" }" countQuery=""statement": "MATCH (primary:pub:Individual {short_form: {ID}} ) RETURN count(primary) as count", "parameters" : { "ID" : "$ID" }"> @@ -535,7 +535,7 @@ name="Get JSON for DataSet" description="Get JSON for DataSet" runForCount="false" - query=""statement": "MATCH (primary:DataSet) WHERE primary.short_form in [{ID}] WITH primary OPTIONAL MATCH (primary)<-[:has_source|SUBCLASSOF|INSTANCEOF*]-(i:Individual)<-[:depicts]-(channel:Individual)-[irw:in_register_with]->(template:Individual)-[:depicts]->(template_anat:Individual) WITH template, channel, template_anat, irw, primary , i limit 5 OPTIONAL MATCH (channel)-[:is_specified_output_of]->(technique:Class) WITH CASE WHEN channel IS NULL THEN [] ELSE COLLECT({ anatomy: { short_form: i.short_form, label: coalesce(i.label,''), iri: i.iri, types: labels(i) } , channel_image: { channel: { short_form: channel.short_form, label: coalesce(channel.label,''), iri: channel.iri, types: labels(channel) } , imaging_technique: { short_form: technique.short_form, label: coalesce(technique.label,''), iri: technique.iri, types: labels(technique) } ,image: { template_channel : { short_form: template.short_form, label: coalesce(template.label,''), iri: template.iri, types: labels(template) } , template_anatomy: { short_form: template_anat.short_form, label: coalesce(template_anat.label,''), iri: template_anat.iri, types: labels(template_anat) } ,image_folder: irw.folder, index: coalesce(irw.index, []) + [] }} }) END AS anatomy_channel_image ,primary OPTIONAL MATCH (s:Site { short_form: primary.self_xref }) WITH CASE WHEN s IS NULL THEN [] ELSE COLLECT({ link_base: s.link_base, accession: coalesce(primary.short_form, ''), link_text: primary.label + ' on ' + s.label, site: { short_form: s.short_form, label: coalesce(s.label,''), iri: s.iri, types: labels(s) } , icon: coalesce(s.link_icon_url, ''), link_postfix: coalesce(s.link_postfix, '')}) END AS self_xref, primary, anatomy_channel_image OPTIONAL MATCH (s:Site)<-[dbx:hasDbXref]-(primary) WITH CASE WHEN s IS NULL THEN self_xref ELSE COLLECT({ link_base: s.link_base, accession: coalesce(dbx.accession, ''), link_text: primary.label + ' on ' + s.label, site: { short_form: s.short_form, label: coalesce(s.label,''), iri: s.iri, types: labels(s) } , icon: coalesce(s.link_icon_url, ''), link_postfix: coalesce(s.link_postfix, '')}) + self_xref END AS xrefs,primary,anatomy_channel_image OPTIONAL MATCH (primary)-[:has_license]->(l:License) WITH collect ({ icon : coalesce(l.license_logo, ''), link : coalesce(l.license_url, ''), core : { short_form: l.short_form, label: coalesce(l.label,''), iri: l.iri, types: labels(l) } }) as license,primary,anatomy_channel_image,xrefs OPTIONAL MATCH (primary)-[rp:has_reference]->(p:pub) WITH CASE WHEN p is null THEN [] ELSE collect({ core: { short_form: p.short_form, label: coalesce(p.label,''), iri: p.iri, types: labels(p) } , PubMed: coalesce(p.PMID, ''), FlyBase: coalesce(p.FlyBase, ''), DOI: coalesce(p.DOI, '') } ) END AS def_pubs,primary,anatomy_channel_image,xrefs,license RETURN { link : coalesce(primary.dataset_link, ''), core : { short_form: primary.short_form, label: coalesce(primary.label,''), iri: primary.iri, types: labels(primary) } , description : coalesce(primary.description, []), comment : coalesce(primary.`annotation - comment`, []) } AS term, 'Get JSON for DataSet' AS query, '2e501bd' AS version , anatomy_channel_image, xrefs, license, def_pubs", "parameters" : { "ID" : "$ID" }" + query=""statement": "MATCH (primary:DataSet) WHERE primary.short_form in [{ID}] WITH primary CALL apoc.cypher.run('WITH primary OPTIONAL MATCH (primary)<-[:has_source|SUBCLASSOF|INSTANCEOF*]-(i:Individual)<-[:depicts]-(channel:Individual)-[irw:in_register_with] ->(template:Individual)-[:depicts]->(template_anat:Individual) RETURN template, channel, template_anat, i, irw limit 5', {primary:primary}) yield value with value.template as template, value.channel as channel,value.template_anat as template_anat, value.i as i, value.irw as irw, primary OPTIONAL MATCH (channel)-[:is_specified_output_of]->(technique:Class) WITH CASE WHEN channel IS NULL THEN [] ELSE COLLECT({ anatomy: { short_form: i.short_form, label: coalesce(i.label,''), iri: i.iri, types: labels(i), symbol: coalesce(i.`IAO_0000028`[0], '')} , channel_image: { channel: { short_form: channel.short_form, label: coalesce(channel.label,''), iri: channel.iri, types: labels(channel), symbol: coalesce(channel.`IAO_0000028`[0], '')} , imaging_technique: { short_form: technique.short_form, label: coalesce(technique.label,''), iri: technique.iri, types: labels(technique), symbol: coalesce(technique.`IAO_0000028`[0], '')} ,image: { template_channel : { short_form: template.short_form, label: coalesce(template.label,''), iri: template.iri, types: labels(template), symbol: coalesce(template.`IAO_0000028`[0], '')} , template_anatomy: { short_form: template_anat.short_form, label: coalesce(template_anat.label,''), iri: template_anat.iri, types: labels(template_anat), symbol: coalesce(template_anat.`IAO_0000028`[0], '')} ,image_folder: COALESCE(irw.folder[0], ''), index: coalesce(apoc.convert.toInteger(irw.index[0]), []) + [] }} }) END AS anatomy_channel_image ,primary OPTIONAL MATCH (s:Site { short_form: primary.self_xref }) WITH CASE WHEN s IS NULL THEN [] ELSE COLLECT({ link_base: coalesce(s.link_base[0], ''), accession: coalesce(primary.short_form, ''), link_text: primary.label + ' on ' + s.label, homepage: coalesce(s.homepage[0], ''), site: { short_form: s.short_form, label: coalesce(s.label,''), iri: s.iri, types: labels(s), symbol: coalesce(s.`IAO_0000028`[0], '')} , icon: coalesce(s.link_icon_url[0], ''), link_postfix: coalesce(s.link_postfix, '')}) END AS self_xref, primary, anatomy_channel_image OPTIONAL MATCH (s:Site)<-[dbx:database_cross_reference]-(primary) WITH CASE WHEN s IS NULL THEN self_xref ELSE COLLECT({ link_base: coalesce(s.link_base[0], ''), accession: coalesce(dbx.accession[0], ''), link_text: primary.label + ' on ' + s.label, homepage: coalesce(s.homepage[0], ''), site: { short_form: s.short_form, label: coalesce(s.label,''), iri: s.iri, types: labels(s), symbol: coalesce(s.`IAO_0000028`[0], '')} , icon: coalesce(s.link_icon_url[0], ''), link_postfix: coalesce(s.link_postfix, '')}) + self_xref END AS xrefs,primary,anatomy_channel_image OPTIONAL MATCH (primary)-[:has_license]->(l:License) WITH collect ({ icon : coalesce(l.license_logo[0], ''), link : coalesce(l.license_url[0], ''), core : { short_form: l.short_form, label: coalesce(l.label,''), iri: l.iri, types: labels(l), symbol: coalesce(l.`IAO_0000028`[0], '')} }) as license,primary,anatomy_channel_image,xrefs OPTIONAL MATCH (primary)-[rp:has_reference]->(p:pub) WITH CASE WHEN p is null THEN [] ELSE collect({ core: { short_form: p.short_form, label: coalesce(p.label,''), iri: p.iri, types: labels(p), symbol: coalesce(p.`IAO_0000028`[0], '')} , PubMed: coalesce(p.PMID[0], ''), FlyBase: coalesce(p.FlyBase[0], ''), DOI: coalesce(p.DOI[0], '') } ) END AS pubs,primary,anatomy_channel_image,xrefs,license OPTIONAL MATCH (primary)<-[:has_source]-(i:Individual) WITH i, primary, anatomy_channel_image, xrefs, license, pubs OPTIONAL MATCH (i)-[:INSTANCEOF]-(c:Class) WITH DISTINCT { images: count(distinct i),types: count(distinct c) } as dataset_counts,primary,anatomy_channel_image,xrefs,license,pubs RETURN { link : coalesce(primary.dataset_link[0], ''), core : { short_form: primary.short_form, label: coalesce(primary.label,''), iri: primary.iri, types: labels(primary), symbol: coalesce(primary.`IAO_0000028`[0], '')} , description : coalesce(primary.description, []), comment : coalesce(primary.comment, []) } AS term, 'Get JSON for DataSet' AS query, '58214d4' AS version , anatomy_channel_image, xrefs, license, pubs, dataset_counts", "parameters" : { "ID" : "$ID" }" countQuery=""statement": "MATCH (primary:DataSet {short_form: {ID}} ) RETURN count(primary) as count", "parameters" : { "ID" : "$ID" }"> @@ -545,7 +545,7 @@ name="Get JSON for License" description="Get JSON for License" runForCount="false" - query=""statement": "MATCH (primary:License) WHERE primary.short_form in [{ID}] WITH primary RETURN { icon : coalesce(primary.license_logo, ''), link : coalesce(primary.license_url, ''), core : { short_form: primary.short_form, label: coalesce(primary.label,''), iri: primary.iri, types: labels(primary) } , description : coalesce(primary.description, []), comment : coalesce(primary.`annotation - comment`, []) } AS term, 'Get JSON for License' AS query, '2e501bd' AS version", "parameters" : { "ID" : "$ID" }" + query=""statement": "MATCH (primary:License) WHERE primary.short_form in [{ID}] WITH primary RETURN { icon : coalesce(primary.license_logo[0], ''), link : coalesce(primary.license_url[0], ''), core : { short_form: primary.short_form, label: coalesce(primary.label,''), iri: primary.iri, types: labels(primary), symbol: coalesce(primary.`IAO_0000028`[0], '')} , description : coalesce(primary.description, []), comment : coalesce(primary.comment, []) } AS term, 'Get JSON for License' AS query, '58214d4' AS version", "parameters" : { "ID" : "$ID" }" countQuery=""statement": "MATCH (primary:License {short_form: {ID}} ) RETURN count(primary) as count", "parameters" : { "ID" : "$ID" }"> @@ -555,7 +555,7 @@ name="Get JSON for Cluster" description="Get JSON for Cluster" runForCount="false" - query=""statement": "MATCH (primary:Cluster) WHERE primary.short_form in [{ID}] WITH primary OPTIONAL MATCH (primary)-[:has_source]->(ds:DataSet)-[:has_license]->(l:License) WITH COLLECT ({ dataset: { link : coalesce(ds.dataset_link, ''), core : { short_form: ds.short_form, label: coalesce(ds.label,''), iri: ds.iri, types: labels(ds) } }, license: { icon : coalesce(l.license_logo, ''), link : coalesce(l.license_url, ''), core : { short_form: l.short_form, label: coalesce(l.label,''), iri: l.iri, types: labels(l) } }}) AS dataset_license,primary OPTIONAL MATCH (o:Class)<-[r:SUBCLASSOF|INSTANCEOF]-(primary) WITH CASE WHEN o IS NULL THEN [] ELSE COLLECT ({ short_form: o.short_form, label: coalesce(o.label,''), iri: o.iri, types: labels(o) } ) END AS parents ,primary,dataset_license OPTIONAL MATCH (o:Class)<-[r {type:'Related'}]-(primary) WITH CASE WHEN o IS NULL THEN [] ELSE COLLECT ({ relation: { label: r.label, iri: r.uri, type: type(r) } , object: { short_form: o.short_form, label: coalesce(o.label,''), iri: o.iri, types: labels(o) } }) END AS relationships ,primary,dataset_license,parents OPTIONAL MATCH (s:Site { short_form: primary.self_xref }) WITH CASE WHEN s IS NULL THEN [] ELSE COLLECT({ link_base: s.link_base, accession: coalesce(primary.short_form, ''), link_text: primary.label + ' on ' + s.label, site: { short_form: s.short_form, label: coalesce(s.label,''), iri: s.iri, types: labels(s) } , icon: coalesce(s.link_icon_url, ''), link_postfix: coalesce(s.link_postfix, '')}) END AS self_xref, primary, dataset_license, parents, relationships OPTIONAL MATCH (s:Site)<-[dbx:hasDbXref]-(primary) WITH CASE WHEN s IS NULL THEN self_xref ELSE COLLECT({ link_base: s.link_base, accession: coalesce(dbx.accession, ''), link_text: primary.label + ' on ' + s.label, site: { short_form: s.short_form, label: coalesce(s.label,''), iri: s.iri, types: labels(s) } , icon: coalesce(s.link_icon_url, ''), link_postfix: coalesce(s.link_postfix, '')}) + self_xref END AS xrefs,primary,dataset_license,parents,relationships OPTIONAL MATCH (primary)<-[:depicts]-(channel:Individual)-[irw:in_register_with]->(template:Individual)-[:depicts]->(template_anat:Individual) WITH template, channel, template_anat, irw, primary, dataset_license, parents, relationships, xrefs OPTIONAL MATCH (channel)-[:is_specified_output_of]->(technique:Class) WITH CASE WHEN channel IS NULL THEN [] ELSE collect ({ channel: { short_form: channel.short_form, label: coalesce(channel.label,''), iri: channel.iri, types: labels(channel) } , imaging_technique: { short_form: technique.short_form, label: coalesce(technique.label,''), iri: technique.iri, types: labels(technique) } ,image: { template_channel : { short_form: template.short_form, label: coalesce(template.label,''), iri: template.iri, types: labels(template) } , template_anatomy: { short_form: template_anat.short_form, label: coalesce(template_anat.label,''), iri: template_anat.iri, types: labels(template_anat) } ,image_folder: irw.folder, index: coalesce(irw.index, []) + [] }}) END AS channel_image,primary,dataset_license,parents,relationships,xrefs OPTIONAL MATCH (o:Individual)<-[r {type:'Related'}]-(primary) WITH CASE WHEN o IS NULL THEN [] ELSE COLLECT ({ relation: { label: r.label, iri: r.uri, type: type(r) } , object: { short_form: o.short_form, label: coalesce(o.label,''), iri: o.iri, types: labels(o) } }) END AS related_individuals ,primary,dataset_license,parents,relationships,xrefs,channel_image RETURN { core : { short_form: primary.short_form, label: coalesce(primary.label,''), iri: primary.iri, types: labels(primary) } , description : coalesce(primary.description, []), comment : coalesce(primary.`annotation-comment`, []) } AS term, 'Get JSON for Individual:Anatomy' AS query, 'ca9ab19' AS version , dataset_license, parents, relationships, xrefs, channel_image, related_individuals", "parameters" : { "ID" : "$ID" }" + query=""statement": "MATCH (primary:Cluster) WHERE primary.short_form in [{ID}] WITH primary OPTIONAL MATCH (primary)-[:has_source]->(ds:DataSet)-[:has_license]->(l:License) WITH COLLECT ({ dataset: { link : coalesce(ds.dataset_link, ''), core : { short_form: ds.short_form, label: coalesce(ds.label,''), iri: ds.iri, types: labels(ds) } }, license: { icon : coalesce(l.license_logo[0], ''), link : coalesce(l.license_url[0], ''), core : { short_form: l.short_form, label: coalesce(l.label,''), iri: l.iri, types: labels(l) } }}) AS dataset_license,primary OPTIONAL MATCH (o:Class)<-[r:SUBCLASSOF|INSTANCEOF]-(primary) WITH CASE WHEN o IS NULL THEN [] ELSE COLLECT ({ short_form: o.short_form, label: coalesce(o.label,''), iri: o.iri, types: labels(o) } ) END AS parents ,primary,dataset_license OPTIONAL MATCH (o:Class)<-[r {type:'Related'}]-(primary) WITH CASE WHEN o IS NULL THEN [] ELSE COLLECT ({ relation: { label: r.label, iri: r.uri, type: type(r) } , object: { short_form: o.short_form, label: coalesce(o.label,''), iri: o.iri, types: labels(o) } }) END AS relationships ,primary,dataset_license,parents OPTIONAL MATCH (s:Site { short_form: primary.self_xref }) WITH CASE WHEN s IS NULL THEN [] ELSE COLLECT({ link_base: s.link_base[0], accession: coalesce(primary.short_form, ''), link_text: primary.label + ' on ' + s.label, site: { short_form: s.short_form, label: coalesce(s.label,''), iri: s.iri, types: labels(s) } , icon: coalesce(s.link_icon_url[0], ''), link_postfix: coalesce(s.link_postfix, '')}) END AS self_xref, primary, dataset_license, parents, relationships OPTIONAL MATCH (s:Site)<-[dbx:hasDbXref]-(primary) WITH CASE WHEN s IS NULL THEN self_xref ELSE COLLECT({ link_base: s.link_base[0], accession: coalesce(dbx.accession, ''), link_text: primary.label + ' on ' + s.label, site: { short_form: s.short_form, label: coalesce(s.label,''), iri: s.iri, types: labels(s) } , icon: coalesce(s.link_icon_url[0], ''), link_postfix: coalesce(s.link_postfix, '')}) + self_xref END AS xrefs,primary,dataset_license,parents,relationships OPTIONAL MATCH (primary)<-[:depicts]-(channel:Individual)-[irw:in_register_with]->(template:Individual)-[:depicts]->(template_anat:Individual) WITH template, channel, template_anat, irw, primary, dataset_license, parents, relationships, xrefs OPTIONAL MATCH (channel)-[:is_specified_output_of]->(technique:Class) WITH CASE WHEN channel IS NULL THEN [] ELSE collect ({ channel: { short_form: channel.short_form, label: coalesce(channel.label,''), iri: channel.iri, types: labels(channel) } , imaging_technique: { short_form: technique.short_form, label: coalesce(technique.label,''), iri: technique.iri, types: labels(technique) } ,image: { template_channel : { short_form: template.short_form, label: coalesce(template.label,''), iri: template.iri, types: labels(template) } , template_anatomy: { short_form: template_anat.short_form, label: coalesce(template_anat.label,''), iri: template_anat.iri, types: labels(template_anat) } ,image_folder: irw.folder[0], index: coalesce(irw.index[0], []) + [] }}) END AS channel_image,primary,dataset_license,parents,relationships,xrefs OPTIONAL MATCH (o:Individual)<-[r {type:'Related'}]-(primary) WITH CASE WHEN o IS NULL THEN [] ELSE COLLECT ({ relation: { label: r.label, iri: r.uri, type: type(r) } , object: { short_form: o.short_form, label: coalesce(o.label,''), iri: o.iri, types: labels(o) } }) END AS related_individuals ,primary,dataset_license,parents,relationships,xrefs,channel_image RETURN { core : { short_form: primary.short_form, label: coalesce(primary.label,''), iri: primary.iri, types: labels(primary) } , description : coalesce(primary.description, []), comment : coalesce(primary.`annotation-comment`, []) } AS term, 'Get JSON for Individual:Anatomy' AS query, 'ca9ab19' AS version , dataset_license, parents, relationships, xrefs, channel_image, related_individuals", "parameters" : { "ID" : "$ID" }" countQuery=""statement": "MATCH (primary:Cluster {short_form: {ID}} ) RETURN count(primary) as count", "parameters" : { "ID" : "$ID" }"> diff --git a/tests/jest/vfb/review/layer-component-tests.js b/tests/jest/vfb/batch2/layer-component-tests.js similarity index 100% rename from tests/jest/vfb/review/layer-component-tests.js rename to tests/jest/vfb/batch2/layer-component-tests.js diff --git a/tests/jest/vfb/batch3/tree-browser-tests.js b/tests/jest/vfb/batch3/tree-browser-tests.js index b9f1e9232..cf36bff45 100644 --- a/tests/jest/vfb/batch3/tree-browser-tests.js +++ b/tests/jest/vfb/batch3/tree-browser-tests.js @@ -72,7 +72,7 @@ describe('VFB Tree Browser Component Tests', () => { }); // Check that the Tree Browser is visible - await wait4selector(page, 'div.rst__tree', { visible: true, timeout : 500000 }); + await wait4selector(page, 'div.rst__tree', { visible: true, timeout : 800000 }); }) it('First node in Tree Browser is correctly named', async () => { @@ -99,15 +99,24 @@ describe('VFB Tree Browser Component Tests', () => { // Click on third node of tree browser, 'adult cerebral ganglion' await page.evaluate(async () => document.getElementsByClassName("rst__rowContents rst__rowContentsDragDisabled")[2].click()); // Check tree now expanded with adult cerebral ganglion name - let thirdNode = await page.evaluate(async () => { + let firstNode = await page.evaluate(async () => { return document.getElementsByClassName("nodeSelected")[3].innerText; }); - expect(thirdNode).toEqual("adult optic lobe"); + expect(firstNode).toEqual("adult protocerebrum"); }) + it('Expand node "adult protocerebrum"', async () => { + // Click on third node of tree browser, 'adult cerebral ganglion' + await page.evaluate(async () => document.getElementsByClassName("rst__rowContents rst__rowContentsDragDisabled")[3].click()); + // Check tree now expanded with adult cerebral ganglion name + let sixthNode = await page.evaluate(async () => { + return document.getElementsByClassName("nodeSelected")[6].innerText; + }); + expect(sixthNode).toEqual("adult optic lobe"); + }) it('Click on Node "adult optic lobe"', async () => { - await page.evaluate(async () => document.getElementsByClassName("nodeSelected")[3].click()); + await page.evaluate(async () => document.getElementsByClassName("nodeSelected")[6].click()); // Check Term Info is now populated with adult cerebral ganglion name let element = await findElementByText(page, "adult optic lobe"); expect(element).toBe("adult optic lobe"); @@ -142,11 +151,11 @@ describe('VFB Tree Browser Component Tests', () => { }) it('Click on "eye" icon to render "adult optic lobe" mesh', async () => { - await page.evaluate(() => document.querySelectorAll('.rst__tree i.fa-eye-slash')[1].click()); + await page.evaluate(() => document.querySelectorAll('.rst__tree i.fa-eye-slash')[3].click()); // Wait for 'color picker' selector to show, this is the sign that the click on the eye button worked and the mesh was rendered - await wait4selector(page, '.rst__tree i.fa-tint', { visible: true, timeout : 500000 }); + await wait4selector(page, 'i.fa-tint', { visible: true, timeout : 500000 }); }) - + it('Mesh for "adult optic lobe" rendered in canvas after clicking on eye icon next to node', async () => { expect( await page.evaluate(async () => CanvasContainer.engine.getRealMeshesForInstancePath('VFB_00030870.VFB_00030870_obj').length) @@ -154,7 +163,7 @@ describe('VFB Tree Browser Component Tests', () => { }) it('Color Picker Appears for "adult optic lobe"', async () => { - await page.evaluate(async () => document.querySelectorAll('.rst__tree i.fa-tint')[1].click()); + await page.evaluate(async () => document.querySelectorAll('.rst__tree i.fa-tint')[0].click()); // Wait for color picker to show await wait4selector(page, '#tree-color-picker', { visible: true, timeout : 500000 }) }) From f7be3e74a85b0e379e7718a73190493b01bdd5d2 Mon Sep 17 00:00:00 2001 From: Rob Court Date: Thu, 15 Oct 2020 08:59:40 +0100 Subject: [PATCH 27/27] Revert "merge development and overwrite development branch vfb.xmi" This reverts commit a497f6b09aed1ccc7b25b0c821bfa2a3f5dfcd64. --- model/vfb.xmi | 74 +++++++++++++++++++++++++-------------------------- 1 file changed, 37 insertions(+), 37 deletions(-) diff --git a/model/vfb.xmi b/model/vfb.xmi index 8dbb71010..d78879c05 100644 --- a/model/vfb.xmi +++ b/model/vfb.xmi @@ -168,15 +168,15 @@ runForCount="false"> + queryProcessorId="neo4jQueryProcessor"/> + queryProcessorId="neo4jQueryProcessor"/> + query=""statement": "MATCH (n:Template {short_form:{ID}})<-[:depicts]-(:Template)<-[r:in_register_with]-(dc:Individual)-[:depicts]->(di:Individual)-[:INSTANCEOF]->(d:Class) WHERE exists(r.index) RETURN distinct di.short_form as id, di.label as name, coalesce(di.description[0],d.description[0]) as def, COLLECT(DISTINCT d.label) as type, replace(r.folder[0],'http:','https:') + '/thumbnailT.png' as file", "parameters" : { "ID" : "$ID" }" + countQuery=""statement": "MATCH (n:Template {short_form:{ID}})<-[:depicts]-(:Template)<-[r:in_register_with]-(dc:Individual)-[:depicts]->(di:Individual)-[:INSTANCEOF]->(d:Class) WHERE exists(r.index) RETURN count(di) as count", "parameters" : { "ID" : "$ID" }"/> + query=""statement": "MATCH (n:Template {short_form:{ID}})<-[:depicts]-(:Template)<-[r:in_register_with]-(dc:Individual)-[:depicts]->(di:Individual) WHERE not exists(r.index) OPTIONAL MATCH (di)-[:INSTANCEOF]->(d:Class) RETURN distinct di.short_form as id, di.label as name, coalesce(di.description[0],d.description[0]) as def, COLLECT(DISTINCT d.label) as type, replace(r.folder[0],'http:','https:') + '/thumbnailT.png' as file", "parameters" : { "ID" : "$ID" }" + countQuery=""statement": "MATCH (n:Template {short_form:{ID}})<-[:depicts]-(:Template)<-[r:in_register_with]-(dc:Individual)-[:depicts]->(di:Individual) WHERE not exists(r.index) RETURN count(di) as count", "parameters" : { "ID" : "$ID" }"/> + query=""statement": "MATCH (ep:Expression_pattern:Class)<-[ar:overlaps|part_of]-(anoni:Individual)-[:INSTANCEOF]->(anat:Class) WHERE ep.short_form in {ARRAY_ID_RESULTS} WITH anoni, anat, ar OPTIONAL MATCH (p:pub { short_form: ar.pub}) WITH anat, anoni, { core: { short_form: p.short_form, label: coalesce(p.label,''), iri: p.iri, types: labels(p), symbol: coalesce(p.`IAO_0000028`[0], '')} , PubMed: coalesce(p.PMID[0], ''), FlyBase: coalesce(p.FlyBase[0], ''), DOI: coalesce(p.DOI[0], '') } AS pub OPTIONAL MATCH (anoni)-[r:Related]->(o:FBdv) WITH CASE WHEN o IS NULL THEN [] ELSE COLLECT ({ relation: { label: r.label, iri: r.iri, type: type(r) } , object: { short_form: o.short_form, label: coalesce(o.label,''), iri: o.iri, types: labels(o), symbol: coalesce(o.`IAO_0000028`[0], '')} }) END AS stages ,anoni,anat,pub CALL apoc.cypher.run('WITH anat OPTIONAL MATCH (anat:Synaptic_neuropil)<- [:has_source|SUBCLASSOF|INSTANCEOF*]-(i:Individual)<-[:depicts]- (channel:Individual)-[irw:in_register_with] ->(template:Individual)-[:depicts]-> (template_anat:Individual) RETURN template, channel, template_anat, i, irw limit 5', {anat:anat}) yield value with value.template as template, value.channel as channel,value.template_anat as template_anat, value.i as i, value.irw as irw, anoni, anat, pub, stages OPTIONAL MATCH (channel)-[:is_specified_output_of]->(technique:Class) WITH CASE WHEN channel IS NULL THEN [] ELSE COLLECT({ anatomy: { short_form: i.short_form, label: coalesce(i.label,''), iri: i.iri, types: labels(i), symbol: coalesce(i.`IAO_0000028`[0], '')} , channel_image: { channel: { short_form: channel.short_form, label: coalesce(channel.label,''), iri: channel.iri, types: labels(channel), symbol: coalesce(channel.`IAO_0000028`[0], '')} , imaging_technique: { short_form: technique.short_form, label: coalesce(technique.label,''), iri: technique.iri, types: labels(technique), symbol: coalesce(technique.`IAO_0000028`[0], '')} ,image: { template_channel : { short_form: template.short_form, label: coalesce(template.label,''), iri: template.iri, types: labels(template), symbol: coalesce(template.`IAO_0000028`[0], '')} , template_anatomy: { short_form: template_anat.short_form, label: coalesce(template_anat.label,''), iri: template_anat.iri, types: labels(template_anat), symbol: coalesce(template_anat.`IAO_0000028`[0], '')} ,image_folder: COALESCE(irw.folder[0], ''), index: coalesce(apoc.convert.toInteger(irw.index[0]), []) + [] }} }) END AS anatomy_channel_image ,anoni,anat,pub,stages RETURN { short_form: anat.short_form, label: coalesce(anat.label,''), iri: anat.iri, types: labels(anat), symbol: coalesce(anat.`IAO_0000028`[0], '')} AS anatomy, 'Get JSON for ep_2_anat query' AS query, '58214d4' AS version , pub, stages, anatomy_channel_image", "parameters" : { "ARRAY_ID_RESULTS" : $ARRAY_ID_RESULTS}" + countQuery=""statement": "MATCH (ep:Expression_pattern:Class)<-[ar:overlaps|part_of]-(anoni:Individual)-[:INSTANCEOF]->(anat:Class) WHERE ep.short_form in {ARRAY_ID_RESULTS} RETURN count(anat) as count", "parameters" : { "ARRAY_ID_RESULTS" : $ARRAY_ID_RESULTS}"/> + query=""statement": "MATCH (ep:Class:Expression_pattern)<-[ar:overlaps|part_of]-(:Individual)-[:INSTANCEOF]->(anat:Class) WHERE anat.short_form in {ARRAY_ID_RESULTS} WITH DISTINCT collect(DISTINCT ar.pub) as pubs, anat, ep UNWIND pubs as p MATCH (pub:pub { short_form: p}) WITH DISTINCT collect(DISTINCT ar.pub) as pubs, anat, ep UNWIND pubs as p MATCH (pub:pub { short_form: p}) WITH anat, ep, collect({ core: { short_form: pub.short_form, label: coalesce(pub.label,''), iri: pub.iri, types: labels(pub), symbol: coalesce(pub.`IAO_0000028`[0], '')} , PubMed: coalesce(pub.PMID[0], ''), FlyBase: coalesce(pub.FlyBase[0], ''), DOI: coalesce(pub.DOI[0], '') }) as pubs CALL apoc.cypher.run('WITH ep OPTIONAL MATCH (ep)<- [:has_source|SUBCLASSOF|INSTANCEOF*]-(i:Individual)<-[:depicts]- (channel:Individual)-[irw:in_register_with] ->(template:Individual)-[:depicts]-> (template_anat:Individual) RETURN template, channel, template_anat, i, irw limit 5', {ep:ep}) yield value with value.template as template, value.channel as channel,value.template_anat as template_anat, value.i as i, value.irw as irw, anat, ep, pubs OPTIONAL MATCH (channel)-[:is_specified_output_of]->(technique:Class) WITH CASE WHEN channel IS NULL THEN [] ELSE COLLECT({ anatomy: { short_form: i.short_form, label: coalesce(i.label,''), iri: i.iri, types: labels(i), symbol: coalesce(i.`IAO_0000028`[0], '')} , channel_image: { channel: { short_form: channel.short_form, label: coalesce(channel.label,''), iri: channel.iri, types: labels(channel), symbol: coalesce(channel.`IAO_0000028`[0], '')} , imaging_technique: { short_form: technique.short_form, label: coalesce(technique.label,''), iri: technique.iri, types: labels(technique), symbol: coalesce(technique.`IAO_0000028`[0], '')} ,image: { template_channel : { short_form: template.short_form, label: coalesce(template.label,''), iri: template.iri, types: labels(template), symbol: coalesce(template.`IAO_0000028`[0], '')} , template_anatomy: { short_form: template_anat.short_form, label: coalesce(template_anat.label,''), iri: template_anat.iri, types: labels(template_anat), symbol: coalesce(template_anat.`IAO_0000028`[0], '')} ,image_folder: COALESCE(irw.folder[0], ''), index: coalesce(apoc.convert.toInteger(irw.index[0]), []) + [] }} }) END AS anatomy_channel_image ,anat,ep,pubs RETURN { short_form: anat.short_form, label: coalesce(anat.label,''), iri: anat.iri, types: labels(anat), symbol: coalesce(anat.`IAO_0000028`[0], '')} as anatomy, { short_form: ep.short_form, label: coalesce(ep.label,''), iri: ep.iri, types: labels(ep), symbol: coalesce(ep.`IAO_0000028`[0], '')} AS expression_pattern, 'Get JSON for anat_2_ep query' AS query, '58214d4' AS version , pubs, anatomy_channel_image", "parameters" : { "ARRAY_ID_RESULTS" : $ARRAY_ID_RESULTS}" + countQuery=""statement": "MATCH (ep:Class:Expression_pattern)<-[ar:overlaps|part_of]-(anoni:Individual)-[:INSTANCEOF]->(anat:Class) WHERE ep.short_form in {ARRAY_ID_RESULTS} RETURN count(anat) as count", "parameters" : { "ARRAY_ID_RESULTS" : $ARRAY_ID_RESULTS}" /> @@ -485,7 +485,7 @@ name="Get JSON for Neuron Class" description="Get JSON for Neuron Class" runForCount="false" - query=""statement": "MATCH (primary:Class) WHERE primary.short_form in [{ID}] WITH primary OPTIONAL MATCH (o:Class)<-[r:SUBCLASSOF|INSTANCEOF]-(primary) WITH CASE WHEN o IS NULL THEN [] ELSE COLLECT ({ short_form: o.short_form, label: coalesce(o.label,''), iri: o.iri, types: labels(o) } ) END AS parents ,primary OPTIONAL MATCH (o:Class)<-[r {type:'Related'}]-(primary) WITH CASE WHEN o IS NULL THEN [] ELSE COLLECT ({ relation: { label: r.label, iri: r.uri, type: type(r) } , object: { short_form: o.short_form, label: coalesce(o.label,''), iri: o.iri, types: labels(o) } }) END AS relationships ,primary,parents OPTIONAL MATCH (o:Individual)<-[r {type:'Related'}]-(primary) WITH CASE WHEN o IS NULL THEN [] ELSE COLLECT ({ relation: { label: r.label, iri: r.uri, type: type(r) } , object: { short_form: o.short_form, label: coalesce(o.label,''), iri: o.iri, types: labels(o) } }) END AS related_individuals ,primary,parents,relationships OPTIONAL MATCH (s:Site { short_form: primary.self_xref }) WITH CASE WHEN s IS NULL THEN [] ELSE COLLECT({ link_base: s.link_base, accession: coalesce(primary.short_form, ''), link_text: primary.label + ' on ' + s.label, site: { short_form: s.short_form, label: coalesce(s.label,''), iri: s.iri, types: labels(s) } , icon: coalesce(s.link_icon_url, ''), link_postfix: coalesce(s.link_postfix, '')}) END AS self_xref, primary, parents, relationships, related_individuals OPTIONAL MATCH (s:Site)<-[dbx:hasDbXref]-(primary) WITH CASE WHEN s IS NULL THEN self_xref ELSE COLLECT({ link_base: s.link_base, accession: coalesce(dbx.accession, ''), link_text: primary.label + ' on ' + s.label, site: { short_form: s.short_form, label: coalesce(s.label,''), iri: s.iri, types: labels(s) } , icon: coalesce(s.link_icon_url, ''), link_postfix: coalesce(s.link_postfix, '')}) + self_xref END AS xrefs,primary,parents,relationships,related_individuals OPTIONAL MATCH (primary)<-[:has_source|SUBCLASSOF|INSTANCEOF*]-(i:Individual)<-[:depicts]-(channel:Individual)-[irw:in_register_with]->(template:Individual)-[:depicts]->(template_anat:Individual) WITH template, channel, template_anat, irw, primary, parents, relationships, related_individuals, xrefs , i limit 5 OPTIONAL MATCH (channel)-[:is_specified_output_of]->(technique:Class) WITH CASE WHEN channel IS NULL THEN [] ELSE COLLECT({ anatomy: { short_form: i.short_form, label: coalesce(i.label,''), iri: i.iri, types: labels(i) } , channel_image: { channel: { short_form: channel.short_form, label: coalesce(channel.label,''), iri: channel.iri, types: labels(channel) } , imaging_technique: { short_form: technique.short_form, label: coalesce(technique.label,''), iri: technique.iri, types: labels(technique) } ,image: { template_channel : { short_form: template.short_form, label: coalesce(template.label,''), iri: template.iri, types: labels(template) } , template_anatomy: { short_form: template_anat.short_form, label: coalesce(template_anat.label,''), iri: template_anat.iri, types: labels(template_anat) } ,image_folder: irw.folder, index: coalesce(irw.index, []) + [] }} }) END AS anatomy_channel_image ,primary,parents,relationships,related_individuals,xrefs OPTIONAL MATCH (primary)-[rp:has_reference { typ: 'syn'}]->(p:pub) WITH CASE WHEN p is null THEN [] ELSE collect({ pub: { core: { short_form: p.short_form, label: coalesce(p.label,''), iri: p.iri, types: labels(p) } , PubMed: coalesce(p.PMID, ''), FlyBase: coalesce(p.FlyBase, ''), DOI: coalesce(p.DOI, '') } , synonym: { label: coalesce(rp.synonym, ''), scope: coalesce(rp.scope, ''), type: coalesce(rp.cat,'') } }) END AS pub_syn,primary,parents,relationships,related_individuals,xrefs,anatomy_channel_image OPTIONAL MATCH (primary)-[rp:has_reference { typ: 'def'}]->(p:pub) WITH CASE WHEN p is null THEN [] ELSE collect({ core: { short_form: p.short_form, label: coalesce(p.label,''), iri: p.iri, types: labels(p) } , PubMed: coalesce(p.PMID, ''), FlyBase: coalesce(p.FlyBase, ''), DOI: coalesce(p.DOI, '') } ) END AS def_pubs,primary,parents,relationships,related_individuals,xrefs,anatomy_channel_image,pub_syn OPTIONAL MATCH (:Class { label: 'intersectional expression pattern'})<-[:SUBCLASSOF]-(ep:Class)<-[ar:part_of]-(anoni:Individual)-[:INSTANCEOF]->(primary) WITH COLLECT({ short_form: ep.short_form, label: coalesce(ep.label,''), iri: ep.iri, types: labels(ep) } ) as targeting_splits,primary,parents,relationships,related_individuals,xrefs,anatomy_channel_image,pub_syn,def_pubs RETURN { core : { short_form: primary.short_form, label: coalesce(primary.label,''), iri: primary.iri, types: labels(primary) } , description : coalesce(primary.description, []), comment : coalesce(primary.`annotation-comment`, []) } AS term, 'Get JSON for Neuron Class' AS query, '2e501bd' AS version , parents, relationships, related_individuals, xrefs, anatomy_channel_image, pub_syn, def_pubs, targeting_splits", "parameters" : { "ID" : "$ID" }" + query=""statement": "MATCH (primary:Class) WHERE primary.short_form in [{ID}] WITH primary OPTIONAL MATCH (o:Class)<-[r:SUBCLASSOF|INSTANCEOF]-(primary) WITH CASE WHEN o IS NULL THEN [] ELSE COLLECT ({ short_form: o.short_form, label: coalesce(o.label,''), iri: o.iri, types: labels(o), symbol: coalesce(o.`IAO_0000028`[0], '')} ) END AS parents ,primary OPTIONAL MATCH (o)<-[r {type:'Related'}]-(primary) WITH CASE WHEN o IS NULL THEN [] ELSE COLLECT ({ relation: { label: r.label, iri: r.iri, type: type(r) } , object: { short_form: o.short_form, label: coalesce(o.label,''), iri: o.iri, types: labels(o), symbol: coalesce(o.`IAO_0000028`[0], '')} }) END AS relationships ,primary,parents OPTIONAL MATCH (o:Individual)<-[r {type:'Related'}]-(primary) WITH CASE WHEN o IS NULL THEN [] ELSE COLLECT ({ relation: { label: r.label, iri: r.iri, type: type(r) } , object: { short_form: o.short_form, label: coalesce(o.label,''), iri: o.iri, types: labels(o), symbol: coalesce(o.`IAO_0000028`[0], '')} }) END AS related_individuals ,primary,parents,relationships OPTIONAL MATCH (s:Site { short_form: primary.self_xref }) WITH CASE WHEN s IS NULL THEN [] ELSE COLLECT({ link_base: coalesce(s.link_base[0], ''), accession: coalesce(primary.short_form, ''), link_text: primary.label + ' on ' + s.label, homepage: coalesce(s.homepage[0], ''), site: { short_form: s.short_form, label: coalesce(s.label,''), iri: s.iri, types: labels(s), symbol: coalesce(s.`IAO_0000028`[0], '')} , icon: coalesce(s.link_icon_url[0], ''), link_postfix: coalesce(s.link_postfix, '')}) END AS self_xref, primary, parents, relationships, related_individuals OPTIONAL MATCH (s:Site)<-[dbx:database_cross_reference]-(primary) WITH CASE WHEN s IS NULL THEN self_xref ELSE COLLECT({ link_base: coalesce(s.link_base[0], ''), accession: coalesce(dbx.accession[0], ''), link_text: primary.label + ' on ' + s.label, homepage: coalesce(s.homepage[0], ''), site: { short_form: s.short_form, label: coalesce(s.label,''), iri: s.iri, types: labels(s), symbol: coalesce(s.`IAO_0000028`[0], '')} , icon: coalesce(s.link_icon_url[0], ''), link_postfix: coalesce(s.link_postfix, '')}) + self_xref END AS xrefs,primary,parents,relationships,related_individuals CALL apoc.cypher.run('WITH primary OPTIONAL MATCH (primary)<-[:has_source|SUBCLASSOF|INSTANCEOF*]-(i:Individual)<-[:depicts]-(channel:Individual)-[irw:in_register_with] ->(template:Individual)-[:depicts]->(template_anat:Individual) RETURN template, channel, template_anat, i, irw limit 5', {primary:primary}) yield value with value.template as template, value.channel as channel,value.template_anat as template_anat, value.i as i, value.irw as irw, primary, parents, relationships, related_individuals, xrefs OPTIONAL MATCH (channel)-[:is_specified_output_of]->(technique:Class) WITH CASE WHEN channel IS NULL THEN [] ELSE COLLECT({ anatomy: { short_form: i.short_form, label: coalesce(i.label,''), iri: i.iri, types: labels(i), symbol: coalesce(i.`IAO_0000028`[0], '')} , channel_image: { channel: { short_form: channel.short_form, label: coalesce(channel.label,''), iri: channel.iri, types: labels(channel), symbol: coalesce(channel.`IAO_0000028`[0], '')} , imaging_technique: { short_form: technique.short_form, label: coalesce(technique.label,''), iri: technique.iri, types: labels(technique), symbol: coalesce(technique.`IAO_0000028`[0], '')} ,image: { template_channel : { short_form: template.short_form, label: coalesce(template.label,''), iri: template.iri, types: labels(template), symbol: coalesce(template.`IAO_0000028`[0], '')} , template_anatomy: { short_form: template_anat.short_form, label: coalesce(template_anat.label,''), iri: template_anat.iri, types: labels(template_anat), symbol: coalesce(template_anat.`IAO_0000028`[0], '')} ,image_folder: COALESCE(irw.folder[0], ''), index: coalesce(apoc.convert.toInteger(irw.index[0]), []) + [] }} }) END AS anatomy_channel_image ,primary,parents,relationships,related_individuals,xrefs OPTIONAL MATCH (primary)-[rp:has_reference]->(p:pub) where rp.typ = 'syn' WITH CASE WHEN p is null THEN [] ELSE collect({ pub: { core: { short_form: p.short_form, label: coalesce(p.label,''), iri: p.iri, types: labels(p), symbol: coalesce(p.`IAO_0000028`[0], '')} , PubMed: coalesce(p.PMID[0], ''), FlyBase: coalesce(p.FlyBase[0], ''), DOI: coalesce(p.DOI[0], '') } , synonym: { label: coalesce(rp.value, ''), scope: coalesce(rp.scope, ''), type: coalesce(rp.has_synonym_type,'') } }) END AS pub_syn,primary,parents,relationships,related_individuals,xrefs,anatomy_channel_image OPTIONAL MATCH (primary)-[rp:has_reference]->(p:pub) WHERE rp.typ = 'def' WITH CASE WHEN p is null THEN [] ELSE collect({ core: { short_form: p.short_form, label: coalesce(p.label,''), iri: p.iri, types: labels(p), symbol: coalesce(p.`IAO_0000028`[0], '')} , PubMed: coalesce(p.PMID[0], ''), FlyBase: coalesce(p.FlyBase[0], ''), DOI: coalesce(p.DOI[0], '') } ) END AS def_pubs,primary,parents,relationships,related_individuals,xrefs,anatomy_channel_image,pub_syn OPTIONAL MATCH (:Class { label: 'intersectional expression pattern'})<-[:SUBCLASSOF]-(ep:Class)<-[ar:part_of]-(anoni:Individual)-[:INSTANCEOF]->(primary) WITH CASE WHEN ep IS NULL THEN [] ELSE COLLECT({ short_form: ep.short_form, label: coalesce(ep.label,''), iri: ep.iri, types: labels(ep), symbol: coalesce(ep.`IAO_0000028`[0], '')} ) END AS targeting_splits,primary,parents,relationships,related_individuals,xrefs,anatomy_channel_image,pub_syn,def_pubs RETURN { core : { short_form: primary.short_form, label: coalesce(primary.label,''), iri: primary.iri, types: labels(primary), symbol: coalesce(primary.`IAO_0000028`[0], '')} , description : coalesce(primary.description, []), comment : coalesce(primary.comment, []) } AS term, 'Get JSON for Neuron Class' AS query, '58214d4' AS version , parents, relationships, related_individuals, xrefs, anatomy_channel_image, pub_syn, def_pubs, targeting_splits", "parameters" : { "ID" : "$ID" }" countQuery=""statement": "MATCH (primary:Class {short_form: {ID}} ) RETURN count(primary) as count", "parameters" : { "ID" : "$ID" }"> @@ -495,7 +495,7 @@ name="Get JSON for Split Class" description="Get JSON for Split Class" runForCount="false" - query=""statement": "MATCH (primary:Class) WHERE primary.short_form in [{ID}] WITH primary OPTIONAL MATCH (o:Class)<-[r:SUBCLASSOF|INSTANCEOF]-(primary) WITH CASE WHEN o IS NULL THEN [] ELSE COLLECT ({ short_form: o.short_form, label: coalesce(o.label,''), iri: o.iri, types: labels(o) } ) END AS parents ,primary OPTIONAL MATCH (o:Class)<-[r {type:'Related'}]-(primary) WITH CASE WHEN o IS NULL THEN [] ELSE COLLECT ({ relation: { label: r.label, iri: r.uri, type: type(r) } , object: { short_form: o.short_form, label: coalesce(o.label,''), iri: o.iri, types: labels(o) } }) END AS relationships ,primary,parents OPTIONAL MATCH (o:Individual)<-[r {type:'Related'}]-(primary) WITH CASE WHEN o IS NULL THEN [] ELSE COLLECT ({ relation: { label: r.label, iri: r.uri, type: type(r) } , object: { short_form: o.short_form, label: coalesce(o.label,''), iri: o.iri, types: labels(o) } }) END AS related_individuals ,primary,parents,relationships OPTIONAL MATCH (s:Site { short_form: primary.self_xref }) WITH CASE WHEN s IS NULL THEN [] ELSE COLLECT({ link_base: s.link_base, accession: coalesce(primary.short_form, ''), link_text: primary.label + ' on ' + s.label, site: { short_form: s.short_form, label: coalesce(s.label,''), iri: s.iri, types: labels(s) } , icon: coalesce(s.link_icon_url, ''), link_postfix: coalesce(s.link_postfix, '')}) END AS self_xref, primary, parents, relationships, related_individuals OPTIONAL MATCH (s:Site)<-[dbx:hasDbXref]-(primary) WITH CASE WHEN s IS NULL THEN self_xref ELSE COLLECT({ link_base: s.link_base, accession: coalesce(dbx.accession, ''), link_text: primary.label + ' on ' + s.label, site: { short_form: s.short_form, label: coalesce(s.label,''), iri: s.iri, types: labels(s) } , icon: coalesce(s.link_icon_url, ''), link_postfix: coalesce(s.link_postfix, '')}) + self_xref END AS xrefs,primary,parents,relationships,related_individuals OPTIONAL MATCH (primary)<-[:has_source|SUBCLASSOF|INSTANCEOF*]-(i:Individual)<-[:depicts]-(channel:Individual)-[irw:in_register_with]->(template:Individual)-[:depicts]->(template_anat:Individual) WITH template, channel, template_anat, irw, primary, parents, relationships, related_individuals, xrefs , i limit 5 OPTIONAL MATCH (channel)-[:is_specified_output_of]->(technique:Class) WITH CASE WHEN channel IS NULL THEN [] ELSE COLLECT({ anatomy: { short_form: i.short_form, label: coalesce(i.label,''), iri: i.iri, types: labels(i) } , channel_image: { channel: { short_form: channel.short_form, label: coalesce(channel.label,''), iri: channel.iri, types: labels(channel) } , imaging_technique: { short_form: technique.short_form, label: coalesce(technique.label,''), iri: technique.iri, types: labels(technique) } ,image: { template_channel : { short_form: template.short_form, label: coalesce(template.label,''), iri: template.iri, types: labels(template) } , template_anatomy: { short_form: template_anat.short_form, label: coalesce(template_anat.label,''), iri: template_anat.iri, types: labels(template_anat) } ,image_folder: irw.folder, index: coalesce(irw.index, []) + [] }} }) END AS anatomy_channel_image ,primary,parents,relationships,related_individuals,xrefs OPTIONAL MATCH (primary)-[rp:has_reference { typ: 'syn'}]->(p:pub) WITH CASE WHEN p is null THEN [] ELSE collect({ pub: { core: { short_form: p.short_form, label: coalesce(p.label,''), iri: p.iri, types: labels(p) } , PubMed: coalesce(p.PMID, ''), FlyBase: coalesce(p.FlyBase, ''), DOI: coalesce(p.DOI, '') } , synonym: { label: coalesce(rp.synonym, ''), scope: coalesce(rp.scope, ''), type: coalesce(rp.cat,'') } }) END AS pub_syn,primary,parents,relationships,related_individuals,xrefs,anatomy_channel_image OPTIONAL MATCH (primary)-[rp:has_reference { typ: 'def'}]->(p:pub) WITH CASE WHEN p is null THEN [] ELSE collect({ core: { short_form: p.short_form, label: coalesce(p.label,''), iri: p.iri, types: labels(p) } , PubMed: coalesce(p.PMID, ''), FlyBase: coalesce(p.FlyBase, ''), DOI: coalesce(p.DOI, '') } ) END AS def_pubs,primary,parents,relationships,related_individuals,xrefs,anatomy_channel_image,pub_syn OPTIONAL MATCH (:Class { label: 'intersectional expression pattern'})<-[:SUBCLASSOF]-(primary)<-[ar:part_of]-(anoni:Individual)-[:INSTANCEOF]->(n:Neuron) WITH COLLECT({ short_form: n.short_form, label: coalesce(n.label,''), iri: n.iri, types: labels(n) } ) as target_neurons,primary,parents,relationships,related_individuals,xrefs,anatomy_channel_image,pub_syn,def_pubs RETURN { core : { short_form: primary.short_form, label: coalesce(primary.label,''), iri: primary.iri, types: labels(primary) } , description : coalesce(primary.description, []), comment : coalesce(primary.`annotation-comment`, []) } AS term, 'Get JSON for Split Class' AS query, '2e501bd' AS version , parents, relationships, related_individuals, xrefs, anatomy_channel_image, pub_syn, def_pubs, target_neurons", "parameters" : { "ID" : "$ID" }" + query=""statement": "MATCH (primary:Class) WHERE primary.short_form in [{ID}] WITH primary OPTIONAL MATCH (o:Class)<-[r:SUBCLASSOF|INSTANCEOF]-(primary) WITH CASE WHEN o IS NULL THEN [] ELSE COLLECT ({ short_form: o.short_form, label: coalesce(o.label,''), iri: o.iri, types: labels(o), symbol: coalesce(o.`IAO_0000028`[0], '')} ) END AS parents ,primary OPTIONAL MATCH (o)<-[r {type:'Related'}]-(primary) WITH CASE WHEN o IS NULL THEN [] ELSE COLLECT ({ relation: { label: r.label, iri: r.iri, type: type(r) } , object: { short_form: o.short_form, label: coalesce(o.label,''), iri: o.iri, types: labels(o), symbol: coalesce(o.`IAO_0000028`[0], '')} }) END AS relationships ,primary,parents OPTIONAL MATCH (o:Individual)<-[r {type:'Related'}]-(primary) WITH CASE WHEN o IS NULL THEN [] ELSE COLLECT ({ relation: { label: r.label, iri: r.iri, type: type(r) } , object: { short_form: o.short_form, label: coalesce(o.label,''), iri: o.iri, types: labels(o), symbol: coalesce(o.`IAO_0000028`[0], '')} }) END AS related_individuals ,primary,parents,relationships OPTIONAL MATCH (s:Site { short_form: primary.self_xref }) WITH CASE WHEN s IS NULL THEN [] ELSE COLLECT({ link_base: coalesce(s.link_base[0], ''), accession: coalesce(primary.short_form, ''), link_text: primary.label + ' on ' + s.label, homepage: coalesce(s.homepage[0], ''), site: { short_form: s.short_form, label: coalesce(s.label,''), iri: s.iri, types: labels(s), symbol: coalesce(s.`IAO_0000028`[0], '')} , icon: coalesce(s.link_icon_url[0], ''), link_postfix: coalesce(s.link_postfix, '')}) END AS self_xref, primary, parents, relationships, related_individuals OPTIONAL MATCH (s:Site)<-[dbx:database_cross_reference]-(primary) WITH CASE WHEN s IS NULL THEN self_xref ELSE COLLECT({ link_base: coalesce(s.link_base[0], ''), accession: coalesce(dbx.accession[0], ''), link_text: primary.label + ' on ' + s.label, homepage: coalesce(s.homepage[0], ''), site: { short_form: s.short_form, label: coalesce(s.label,''), iri: s.iri, types: labels(s), symbol: coalesce(s.`IAO_0000028`[0], '')} , icon: coalesce(s.link_icon_url[0], ''), link_postfix: coalesce(s.link_postfix, '')}) + self_xref END AS xrefs,primary,parents,relationships,related_individuals CALL apoc.cypher.run('WITH primary OPTIONAL MATCH (primary)<-[:has_source|SUBCLASSOF|INSTANCEOF*]-(i:Individual)<-[:depicts]-(channel:Individual)-[irw:in_register_with] ->(template:Individual)-[:depicts]->(template_anat:Individual) RETURN template, channel, template_anat, i, irw limit 5', {primary:primary}) yield value with value.template as template, value.channel as channel,value.template_anat as template_anat, value.i as i, value.irw as irw, primary, parents, relationships, related_individuals, xrefs OPTIONAL MATCH (channel)-[:is_specified_output_of]->(technique:Class) WITH CASE WHEN channel IS NULL THEN [] ELSE COLLECT({ anatomy: { short_form: i.short_form, label: coalesce(i.label,''), iri: i.iri, types: labels(i), symbol: coalesce(i.`IAO_0000028`[0], '')} , channel_image: { channel: { short_form: channel.short_form, label: coalesce(channel.label,''), iri: channel.iri, types: labels(channel), symbol: coalesce(channel.`IAO_0000028`[0], '')} , imaging_technique: { short_form: technique.short_form, label: coalesce(technique.label,''), iri: technique.iri, types: labels(technique), symbol: coalesce(technique.`IAO_0000028`[0], '')} ,image: { template_channel : { short_form: template.short_form, label: coalesce(template.label,''), iri: template.iri, types: labels(template), symbol: coalesce(template.`IAO_0000028`[0], '')} , template_anatomy: { short_form: template_anat.short_form, label: coalesce(template_anat.label,''), iri: template_anat.iri, types: labels(template_anat), symbol: coalesce(template_anat.`IAO_0000028`[0], '')} ,image_folder: COALESCE(irw.folder[0], ''), index: coalesce(apoc.convert.toInteger(irw.index[0]), []) + [] }} }) END AS anatomy_channel_image ,primary,parents,relationships,related_individuals,xrefs OPTIONAL MATCH (primary)-[rp:has_reference]->(p:pub) where rp.typ = 'syn' WITH CASE WHEN p is null THEN [] ELSE collect({ pub: { core: { short_form: p.short_form, label: coalesce(p.label,''), iri: p.iri, types: labels(p), symbol: coalesce(p.`IAO_0000028`[0], '')} , PubMed: coalesce(p.PMID[0], ''), FlyBase: coalesce(p.FlyBase[0], ''), DOI: coalesce(p.DOI[0], '') } , synonym: { label: coalesce(rp.value, ''), scope: coalesce(rp.scope, ''), type: coalesce(rp.has_synonym_type,'') } }) END AS pub_syn,primary,parents,relationships,related_individuals,xrefs,anatomy_channel_image OPTIONAL MATCH (primary)-[rp:has_reference]->(p:pub) WHERE rp.typ = 'def' WITH CASE WHEN p is null THEN [] ELSE collect({ core: { short_form: p.short_form, label: coalesce(p.label,''), iri: p.iri, types: labels(p), symbol: coalesce(p.`IAO_0000028`[0], '')} , PubMed: coalesce(p.PMID[0], ''), FlyBase: coalesce(p.FlyBase[0], ''), DOI: coalesce(p.DOI[0], '') } ) END AS def_pubs,primary,parents,relationships,related_individuals,xrefs,anatomy_channel_image,pub_syn OPTIONAL MATCH (:Class { label: 'intersectional expression pattern'})<-[:SUBCLASSOF]-(primary)<-[ar:part_of]-(anoni:Individual)-[:INSTANCEOF]->(n:Neuron) WITH CASE WHEN n IS NULL THEN [] ELSE COLLECT({ short_form: n.short_form, label: coalesce(n.label,''), iri: n.iri, types: labels(n), symbol: coalesce(n.`IAO_0000028`[0], '')} ) END AS target_neurons,primary,parents,relationships,related_individuals,xrefs,anatomy_channel_image,pub_syn,def_pubs RETURN { core : { short_form: primary.short_form, label: coalesce(primary.label,''), iri: primary.iri, types: labels(primary), symbol: coalesce(primary.`IAO_0000028`[0], '')} , description : coalesce(primary.description, []), comment : coalesce(primary.comment, []) } AS term, 'Get JSON for Split Class' AS query, '58214d4' AS version , parents, relationships, related_individuals, xrefs, anatomy_channel_image, pub_syn, def_pubs, target_neurons", "parameters" : { "ID" : "$ID" }" countQuery=""statement": "MATCH (primary:Class {short_form: {ID}} ) RETURN count(primary) as count", "parameters" : { "ID" : "$ID" }"> @@ -505,7 +505,7 @@ name="Get JSON for Individual" description="Get JSON for Individual:Anatomy" runForCount="false" - query=""statement": "MATCH (primary:Individual:Anatomy) WHERE primary.short_form in [{ID}] WITH primary OPTIONAL MATCH (primary)-[:has_source]->(ds:DataSet)-[:has_license]->(l:License) WITH COLLECT ({ dataset: { link : coalesce(ds.dataset_link, ''), core : { short_form: ds.short_form, label: coalesce(ds.label,''), iri: ds.iri, types: labels(ds) } }, license: { icon : coalesce(l.license_logo, ''), link : coalesce(l.license_url, ''), core : { short_form: l.short_form, label: coalesce(l.label,''), iri: l.iri, types: labels(l) } }}) AS dataset_license,primary OPTIONAL MATCH (o:Class)<-[r:SUBCLASSOF|INSTANCEOF]-(primary) WITH CASE WHEN o IS NULL THEN [] ELSE COLLECT ({ short_form: o.short_form, label: coalesce(o.label,''), iri: o.iri, types: labels(o) } ) END AS parents ,primary,dataset_license OPTIONAL MATCH (o:Class)<-[r {type:'Related'}]-(primary) WITH CASE WHEN o IS NULL THEN [] ELSE COLLECT ({ relation: { label: r.label, iri: r.uri, type: type(r) } , object: { short_form: o.short_form, label: coalesce(o.label,''), iri: o.iri, types: labels(o) } }) END AS relationships ,primary,dataset_license,parents OPTIONAL MATCH (s:Site { short_form: primary.self_xref }) WITH CASE WHEN s IS NULL THEN [] ELSE COLLECT({ link_base: s.link_base, accession: coalesce(primary.short_form, ''), link_text: primary.label + ' on ' + s.label, site: { short_form: s.short_form, label: coalesce(s.label,''), iri: s.iri, types: labels(s) } , icon: coalesce(s.link_icon_url, ''), link_postfix: coalesce(s.link_postfix, '')}) END AS self_xref, primary, dataset_license, parents, relationships OPTIONAL MATCH (s:Site)<-[dbx:hasDbXref]-(primary) WITH CASE WHEN s IS NULL THEN self_xref ELSE COLLECT({ link_base: s.link_base, accession: coalesce(dbx.accession, ''), link_text: primary.label + ' on ' + s.label, site: { short_form: s.short_form, label: coalesce(s.label,''), iri: s.iri, types: labels(s) } , icon: coalesce(s.link_icon_url, ''), link_postfix: coalesce(s.link_postfix, '')}) + self_xref END AS xrefs,primary,dataset_license,parents,relationships OPTIONAL MATCH (primary)<-[:depicts]-(channel:Individual)-[irw:in_register_with]->(template:Individual)-[:depicts]->(template_anat:Individual) WITH template, channel, template_anat, irw, primary, dataset_license, parents, relationships, xrefs OPTIONAL MATCH (channel)-[:is_specified_output_of]->(technique:Class) WITH CASE WHEN channel IS NULL THEN [] ELSE collect ({ channel: { short_form: channel.short_form, label: coalesce(channel.label,''), iri: channel.iri, types: labels(channel) } , imaging_technique: { short_form: technique.short_form, label: coalesce(technique.label,''), iri: technique.iri, types: labels(technique) } ,image: { template_channel : { short_form: template.short_form, label: coalesce(template.label,''), iri: template.iri, types: labels(template) } , template_anatomy: { short_form: template_anat.short_form, label: coalesce(template_anat.label,''), iri: template_anat.iri, types: labels(template_anat) } ,image_folder: irw.folder, index: coalesce(irw.index, []) + [] }}) END AS channel_image,primary,dataset_license,parents,relationships,xrefs OPTIONAL MATCH (o:Individual)<-[r {type:'Related'}]-(primary) WITH CASE WHEN o IS NULL THEN [] ELSE COLLECT ({ relation: { label: r.label, iri: r.uri, type: type(r) } , object: { short_form: o.short_form, label: coalesce(o.label,''), iri: o.iri, types: labels(o) } }) END AS related_individuals ,primary,dataset_license,parents,relationships,xrefs,channel_image RETURN { core : { short_form: primary.short_form, label: coalesce(primary.label,''), iri: primary.iri, types: labels(primary) } , description : coalesce(primary.description, []), comment : coalesce(primary.`annotation-comment`, []) } AS term, 'Get JSON for Individual:Anatomy' AS query, 'ca9ab19' AS version , dataset_license, parents, relationships, xrefs, channel_image, related_individuals", "parameters" : { "ID" : "$ID" }" + query=""statement": "MATCH (primary:Individual:Anatomy) WHERE primary.short_form in [{ID}] WITH primary OPTIONAL MATCH (primary)-[:has_source]-(ds:DataSet)-[:has_license]->(l:License) WITH COLLECT ({ dataset: { link : coalesce(ds.dataset_link[0], ''), core : { short_form: ds.short_form, label: coalesce(ds.label,''), iri: ds.iri, types: labels(ds), symbol: coalesce(ds.`IAO_0000028`[0], '')} }, license: { icon : coalesce(l.license_logo[0], ''), link : coalesce(l.license_url[0], ''), core : { short_form: l.short_form, label: coalesce(l.label,''), iri: l.iri, types: labels(l), symbol: coalesce(l.`IAO_0000028`[0], '')} }}) AS dataset_license,primary OPTIONAL MATCH (o:Class)<-[r:SUBCLASSOF|INSTANCEOF]-(primary) WITH CASE WHEN o IS NULL THEN [] ELSE COLLECT ({ short_form: o.short_form, label: coalesce(o.label,''), iri: o.iri, types: labels(o), symbol: coalesce(o.`IAO_0000028`[0], '')} ) END AS parents ,primary,dataset_license OPTIONAL MATCH (o)<-[r {type:'Related'}]-(primary) WITH CASE WHEN o IS NULL THEN [] ELSE COLLECT ({ relation: { label: r.label, iri: r.iri, type: type(r) } , object: { short_form: o.short_form, label: coalesce(o.label,''), iri: o.iri, types: labels(o), symbol: coalesce(o.`IAO_0000028`[0], '')} }) END AS relationships ,primary,dataset_license,parents OPTIONAL MATCH (s:Site { short_form: primary.self_xref }) WITH CASE WHEN s IS NULL THEN [] ELSE COLLECT({ link_base: coalesce(s.link_base[0], ''), accession: coalesce(primary.short_form, ''), link_text: primary.label + ' on ' + s.label, homepage: coalesce(s.homepage[0], ''), site: { short_form: s.short_form, label: coalesce(s.label,''), iri: s.iri, types: labels(s), symbol: coalesce(s.`IAO_0000028`[0], '')} , icon: coalesce(s.link_icon_url[0], ''), link_postfix: coalesce(s.link_postfix, '')}) END AS self_xref, primary, dataset_license, parents, relationships OPTIONAL MATCH (s:Site)<-[dbx:database_cross_reference]-(primary) WITH CASE WHEN s IS NULL THEN self_xref ELSE COLLECT({ link_base: coalesce(s.link_base[0], ''), accession: coalesce(dbx.accession[0], ''), link_text: primary.label + ' on ' + s.label, homepage: coalesce(s.homepage[0], ''), site: { short_form: s.short_form, label: coalesce(s.label,''), iri: s.iri, types: labels(s), symbol: coalesce(s.`IAO_0000028`[0], '')} , icon: coalesce(s.link_icon_url[0], ''), link_postfix: coalesce(s.link_postfix, '')}) + self_xref END AS xrefs,primary,dataset_license,parents,relationships OPTIONAL MATCH (primary)<-[:depicts]-(channel:Individual)-[irw:in_register_with]->(template:Individual)-[:depicts]->(template_anat:Individual) WITH template, channel, template_anat, irw, primary, dataset_license, parents, relationships, xrefs OPTIONAL MATCH (channel)-[:is_specified_output_of]->(technique:Class) WITH CASE WHEN channel IS NULL THEN [] ELSE collect ({ channel: { short_form: channel.short_form, label: coalesce(channel.label,''), iri: channel.iri, types: labels(channel), symbol: coalesce(channel.`IAO_0000028`[0], '')} , imaging_technique: { short_form: technique.short_form, label: coalesce(technique.label,''), iri: technique.iri, types: labels(technique), symbol: coalesce(technique.`IAO_0000028`[0], '')} ,image: { template_channel : { short_form: template.short_form, label: coalesce(template.label,''), iri: template.iri, types: labels(template), symbol: coalesce(template.`IAO_0000028`[0], '')} , template_anatomy: { short_form: template_anat.short_form, label: coalesce(template_anat.label,''), iri: template_anat.iri, types: labels(template_anat), symbol: coalesce(template_anat.`IAO_0000028`[0], '')} ,image_folder: COALESCE(irw.folder[0], ''), index: coalesce(apoc.convert.toInteger(irw.index[0]), []) + [] }}) END AS channel_image,primary,dataset_license,parents,relationships,xrefs OPTIONAL MATCH (o:Individual)<-[r {type:'Related'}]-(primary) WITH CASE WHEN o IS NULL THEN [] ELSE COLLECT ({ relation: { label: r.label, iri: r.iri, type: type(r) } , object: { short_form: o.short_form, label: coalesce(o.label,''), iri: o.iri, types: labels(o), symbol: coalesce(o.`IAO_0000028`[0], '')} }) END AS related_individuals ,primary,dataset_license,parents,relationships,xrefs,channel_image RETURN { core : { short_form: primary.short_form, label: coalesce(primary.label,''), iri: primary.iri, types: labels(primary), symbol: coalesce(primary.`IAO_0000028`[0], '')} , description : coalesce(primary.description, []), comment : coalesce(primary.comment, []) } AS term, 'Get JSON for Individual:Anatomy' AS query, '58214d4' AS version , dataset_license, parents, relationships, xrefs, channel_image, related_individuals", "parameters" : { "ID" : "$ID" }" countQuery=""statement": "MATCH (primary:Individual {short_form: {ID}} ) RETURN count(primary) as count", "parameters" : { "ID" : "$ID" }"> @@ -515,7 +515,7 @@ name="Get JSON for Template" description="Get JSON for Template" runForCount="false" - query=""statement": "MATCH (primary:Template) WHERE primary.short_form in [{ID}] WITH primary MATCH (channel:Individual)<-[irw:in_register_with]-(channel:Individual)-[:depicts]->(primary) WITH { index: coalesce(irw.index, []) + [], extent: irw.extent, center: irw.center, voxel: irw.voxel, orientation: irw.orientation, image_folder: irw.folder, channel: { short_form: channel.short_form, label: coalesce(channel.label,''), iri: channel.iri, types: labels(channel) } } as template_channel,primary OPTIONAL MATCH (technique:Class)<-[:is_specified_output_of]-(channel:Individual)-[irw:in_register_with]->(template:Individual)-[:depicts]->(primary) WHERE has(irw.index) WITH primary, template_channel, collect ({ channel: channel, irw: irw}) AS painted_domains UNWIND painted_domains AS pd MATCH (channel:Individual { short_form: pd.channel.short_form})-[:depicts]-(ai:Individual)-[:INSTANCEOF]->(c:Class) WITH collect({ anatomical_type: { short_form: c.short_form, label: coalesce(c.label,''), iri: c.iri, types: labels(c) } , anatomical_individual: { short_form: ai.short_form, label: coalesce(ai.label,''), iri: ai.iri, types: labels(ai) } , folder: pd.irw.folder, center: coalesce (pd.irw.center, []), index: [] + coalesce (pd.irw.index, []) }) AS template_domains,primary,template_channel OPTIONAL MATCH (primary)-[:has_source]->(ds:DataSet)-[:has_license]->(l:License) WITH COLLECT ({ dataset: { link : coalesce(ds.dataset_link, ''), core : { short_form: ds.short_form, label: coalesce(ds.label,''), iri: ds.iri, types: labels(ds) } }, license: { icon : coalesce(l.license_logo, ''), link : coalesce(l.license_url, ''), core : { short_form: l.short_form, label: coalesce(l.label,''), iri: l.iri, types: labels(l) } }}) AS dataset_license,primary,template_channel,template_domains OPTIONAL MATCH (o:Class)<-[r:SUBCLASSOF|INSTANCEOF]-(primary) WITH CASE WHEN o IS NULL THEN [] ELSE COLLECT ({ short_form: o.short_form, label: coalesce(o.label,''), iri: o.iri, types: labels(o) } ) END AS parents ,primary,template_channel,template_domains,dataset_license OPTIONAL MATCH (o:Class)<-[r {type:'Related'}]-(primary) WITH CASE WHEN o IS NULL THEN [] ELSE COLLECT ({ relation: { label: r.label, iri: r.uri, type: type(r) } , object: { short_form: o.short_form, label: coalesce(o.label,''), iri: o.iri, types: labels(o) } }) END AS relationships ,primary,template_channel,template_domains,dataset_license,parents OPTIONAL MATCH (s:Site { short_form: primary.self_xref }) WITH CASE WHEN s IS NULL THEN [] ELSE COLLECT({ link_base: s.link_base, accession: coalesce(primary.short_form, ''), link_text: primary.label + ' on ' + s.label, site: { short_form: s.short_form, label: coalesce(s.label,''), iri: s.iri, types: labels(s) } , icon: coalesce(s.link_icon_url, ''), link_postfix: coalesce(s.link_postfix, '')}) END AS self_xref, primary, template_channel, template_domains, dataset_license, parents, relationships OPTIONAL MATCH (s:Site)<-[dbx:hasDbXref]-(primary) WITH CASE WHEN s IS NULL THEN self_xref ELSE COLLECT({ link_base: s.link_base, accession: coalesce(dbx.accession, ''), link_text: primary.label + ' on ' + s.label, site: { short_form: s.short_form, label: coalesce(s.label,''), iri: s.iri, types: labels(s) } , icon: coalesce(s.link_icon_url, ''), link_postfix: coalesce(s.link_postfix, '')}) + self_xref END AS xrefs,primary,template_channel,template_domains,dataset_license,parents,relationships OPTIONAL MATCH (o:Individual)<-[r {type:'Related'}]-(primary) WITH CASE WHEN o IS NULL THEN [] ELSE COLLECT ({ relation: { label: r.label, iri: r.uri, type: type(r) } , object: { short_form: o.short_form, label: coalesce(o.label,''), iri: o.iri, types: labels(o) } }) END AS related_individuals ,primary,template_channel,template_domains,dataset_license,parents,relationships,xrefs RETURN { core : { short_form: primary.short_form, label: coalesce(primary.label,''), iri: primary.iri, types: labels(primary) } , description : coalesce(primary.description, []), comment : coalesce(primary.`annotation-comment`, []) } AS term, 'Get JSON for Template' AS query, 'ca9ab19' AS version , template_channel, template_domains, dataset_license, parents, relationships, xrefs, related_individuals", "parameters" : { "ID" : "$ID" }" + query=""statement": "MATCH (primary:Template) WHERE primary.short_form in [{ID}] WITH primary MATCH (channel:Individual)<-[irw:in_register_with]-(channel:Individual)-[:depicts]->(primary) WITH { index: coalesce(apoc.convert.toInteger(irw.index), []) + [], extent: irw.extent[0], center: irw.center[0], voxel: irw.voxel[0], orientation: coalesce(irw.orientation[0], ''), image_folder: coalesce(irw.folder[0],''), channel: { short_form: channel.short_form, label: coalesce(channel.label,''), iri: channel.iri, types: labels(channel), symbol: coalesce(channel.`IAO_0000028`[0], '')} } as template_channel,primary OPTIONAL MATCH (technique:Class)<-[:is_specified_output_of]-(channel:Individual)-[irw:in_register_with]->(template:Individual)-[:depicts]->(primary) WHERE technique.short_form = 'FBbi_00000224' AND exists(irw.index) WITH primary, template_channel, collect ({ channel: channel, irw: irw}) AS painted_domains UNWIND painted_domains AS pd MATCH (channel:Individual { short_form: pd.channel.short_form})-[:depicts]-(ai:Individual)-[:INSTANCEOF]->(c:Class) WITH collect({ anatomical_type: { short_form: c.short_form, label: coalesce(c.label,''), iri: c.iri, types: labels(c), symbol: coalesce(c.`IAO_0000028`[0], '')} , anatomical_individual: { short_form: ai.short_form, label: coalesce(ai.label,''), iri: ai.iri, types: labels(ai), symbol: coalesce(ai.`IAO_0000028`[0], '')} , folder: pd.irw.folder[0], center: coalesce (pd.irw.center, []), index: [] + coalesce (pd.irw.index, []) }) AS template_domains,primary,template_channel OPTIONAL MATCH (primary)-[:has_source]-(ds:DataSet)-[:has_license]->(l:License) WITH COLLECT ({ dataset: { link : coalesce(ds.dataset_link[0], ''), core : { short_form: ds.short_form, label: coalesce(ds.label,''), iri: ds.iri, types: labels(ds), symbol: coalesce(ds.`IAO_0000028`[0], '')} }, license: { icon : coalesce(l.license_logo[0], ''), link : coalesce(l.license_url[0], ''), core : { short_form: l.short_form, label: coalesce(l.label,''), iri: l.iri, types: labels(l), symbol: coalesce(l.`IAO_0000028`[0], '')} }}) AS dataset_license,primary,template_channel,template_domains OPTIONAL MATCH (o:Class)<-[r:SUBCLASSOF|INSTANCEOF]-(primary) WITH CASE WHEN o IS NULL THEN [] ELSE COLLECT ({ short_form: o.short_form, label: coalesce(o.label,''), iri: o.iri, types: labels(o), symbol: coalesce(o.`IAO_0000028`[0], '')} ) END AS parents ,primary,template_channel,template_domains,dataset_license OPTIONAL MATCH (o)<-[r {type:'Related'}]-(primary) WITH CASE WHEN o IS NULL THEN [] ELSE COLLECT ({ relation: { label: r.label, iri: r.iri, type: type(r) } , object: { short_form: o.short_form, label: coalesce(o.label,''), iri: o.iri, types: labels(o), symbol: coalesce(o.`IAO_0000028`[0], '')} }) END AS relationships ,primary,template_channel,template_domains,dataset_license,parents OPTIONAL MATCH (s:Site { short_form: primary.self_xref }) WITH CASE WHEN s IS NULL THEN [] ELSE COLLECT({ link_base: coalesce(s.link_base[0], ''), accession: coalesce(primary.short_form, ''), link_text: primary.label + ' on ' + s.label, homepage: coalesce(s.homepage[0], ''), site: { short_form: s.short_form, label: coalesce(s.label,''), iri: s.iri, types: labels(s), symbol: coalesce(s.`IAO_0000028`[0], '')} , icon: coalesce(s.link_icon_url[0], ''), link_postfix: coalesce(s.link_postfix, '')}) END AS self_xref, primary, template_channel, template_domains, dataset_license, parents, relationships OPTIONAL MATCH (s:Site)<-[dbx:database_cross_reference]-(primary) WITH CASE WHEN s IS NULL THEN self_xref ELSE COLLECT({ link_base: coalesce(s.link_base[0], ''), accession: coalesce(dbx.accession[0], ''), link_text: primary.label + ' on ' + s.label, homepage: coalesce(s.homepage[0], ''), site: { short_form: s.short_form, label: coalesce(s.label,''), iri: s.iri, types: labels(s), symbol: coalesce(s.`IAO_0000028`[0], '')} , icon: coalesce(s.link_icon_url[0], ''), link_postfix: coalesce(s.link_postfix, '')}) + self_xref END AS xrefs,primary,template_channel,template_domains,dataset_license,parents,relationships OPTIONAL MATCH (o:Individual)<-[r {type:'Related'}]-(primary) WITH CASE WHEN o IS NULL THEN [] ELSE COLLECT ({ relation: { label: r.label, iri: r.iri, type: type(r) } , object: { short_form: o.short_form, label: coalesce(o.label,''), iri: o.iri, types: labels(o), symbol: coalesce(o.`IAO_0000028`[0], '')} }) END AS related_individuals ,primary,template_channel,template_domains,dataset_license,parents,relationships,xrefs RETURN { core : { short_form: primary.short_form, label: coalesce(primary.label,''), iri: primary.iri, types: labels(primary), symbol: coalesce(primary.`IAO_0000028`[0], '')} , description : coalesce(primary.description, []), comment : coalesce(primary.comment, []) } AS term, 'Get JSON for Template' AS query, '58214d4' AS version , template_channel, template_domains, dataset_license, parents, relationships, xrefs, related_individuals", "parameters" : { "ID" : "$ID" }" countQuery=""statement": "MATCH (primary:Template {short_form: {ID}} ) RETURN count(primary) as count", "parameters" : { "ID" : "$ID" }"> @@ -525,7 +525,7 @@ name="Get JSON for pub" description="Fetches JSON for pub." runForCount="false" - query=""statement": "MATCH (primary:pub:Individual {short_form: {ID} }) OPTIONAL MATCH (o)-[r:has_reference]->(primary) WHERE o:DataSet OR o:Class WITH primary, r, o ORDER BY labels(o)[0] DESC, o.label ASC WITH CASE WHEN o IS NULL THEN [] ELSE COLLECT (DISTINCT { relation: { label: r.label, iri: r.uri, type: type(r) }, object: { short_form: o.short_form, label: o.label, iri: o.iri, types: labels(o) } }) END AS relationships, primary RETURN { core: { short_form: primary.short_form, label: primary.label, iri: primary.iri, types: labels(primary) } , description: coalesce(primary.description, []), comment: coalesce(primary.`annotation-comment`, [])} as term, relationships, 'pub' as query, 'manual' AS version", "parameters" : { "ID" : "$ID" }" + query=""statement": "MATCH (primary:Individual:pub) WHERE primary.short_form in [{ID}] WITH primary OPTIONAL MATCH (primary)-[:has_reference]-(ds:DataSet)-[:has_license]->(l:License) WITH COLLECT ({ dataset: { link : coalesce(ds.dataset_link[0], ''), core : { short_form: ds.short_form, label: coalesce(ds.label,''), iri: ds.iri, types: labels(ds), symbol: coalesce(ds.`IAO_0000028`[0], '')} }, license: { icon : coalesce(l.license_logo[0], ''), link : coalesce(l.license_url[0], ''), core : { short_form: l.short_form, label: coalesce(l.label,''), iri: l.iri, types: labels(l), symbol: coalesce(l.`IAO_0000028`[0], '')} }}) AS dataset_license,primary RETURN { core : { short_form: primary.short_form, label: coalesce(primary.label,''), iri: primary.iri, types: labels(primary), symbol: coalesce(primary.`IAO_0000028`[0], '')} , description : coalesce(primary.description, []), comment : coalesce(primary.comment, []) } AS term, '58214d4' AS version , dataset_license, {title: coalesce(primary.title[0], '') ,PubMed: coalesce(primary.PMID[0], ''), FlyBase: coalesce(primary.FlyBase[0], ''), DOI: coalesce(primary.DOI[0], '') }AS pub_specific_content", "parameters" : { "ID" : "$ID" }" countQuery=""statement": "MATCH (primary:pub:Individual {short_form: {ID}} ) RETURN count(primary) as count", "parameters" : { "ID" : "$ID" }"> @@ -535,7 +535,7 @@ name="Get JSON for DataSet" description="Get JSON for DataSet" runForCount="false" - query=""statement": "MATCH (primary:DataSet) WHERE primary.short_form in [{ID}] WITH primary OPTIONAL MATCH (primary)<-[:has_source|SUBCLASSOF|INSTANCEOF*]-(i:Individual)<-[:depicts]-(channel:Individual)-[irw:in_register_with]->(template:Individual)-[:depicts]->(template_anat:Individual) WITH template, channel, template_anat, irw, primary , i limit 5 OPTIONAL MATCH (channel)-[:is_specified_output_of]->(technique:Class) WITH CASE WHEN channel IS NULL THEN [] ELSE COLLECT({ anatomy: { short_form: i.short_form, label: coalesce(i.label,''), iri: i.iri, types: labels(i) } , channel_image: { channel: { short_form: channel.short_form, label: coalesce(channel.label,''), iri: channel.iri, types: labels(channel) } , imaging_technique: { short_form: technique.short_form, label: coalesce(technique.label,''), iri: technique.iri, types: labels(technique) } ,image: { template_channel : { short_form: template.short_form, label: coalesce(template.label,''), iri: template.iri, types: labels(template) } , template_anatomy: { short_form: template_anat.short_form, label: coalesce(template_anat.label,''), iri: template_anat.iri, types: labels(template_anat) } ,image_folder: irw.folder, index: coalesce(irw.index, []) + [] }} }) END AS anatomy_channel_image ,primary OPTIONAL MATCH (s:Site { short_form: primary.self_xref }) WITH CASE WHEN s IS NULL THEN [] ELSE COLLECT({ link_base: s.link_base, accession: coalesce(primary.short_form, ''), link_text: primary.label + ' on ' + s.label, site: { short_form: s.short_form, label: coalesce(s.label,''), iri: s.iri, types: labels(s) } , icon: coalesce(s.link_icon_url, ''), link_postfix: coalesce(s.link_postfix, '')}) END AS self_xref, primary, anatomy_channel_image OPTIONAL MATCH (s:Site)<-[dbx:hasDbXref]-(primary) WITH CASE WHEN s IS NULL THEN self_xref ELSE COLLECT({ link_base: s.link_base, accession: coalesce(dbx.accession, ''), link_text: primary.label + ' on ' + s.label, site: { short_form: s.short_form, label: coalesce(s.label,''), iri: s.iri, types: labels(s) } , icon: coalesce(s.link_icon_url, ''), link_postfix: coalesce(s.link_postfix, '')}) + self_xref END AS xrefs,primary,anatomy_channel_image OPTIONAL MATCH (primary)-[:has_license]->(l:License) WITH collect ({ icon : coalesce(l.license_logo, ''), link : coalesce(l.license_url, ''), core : { short_form: l.short_form, label: coalesce(l.label,''), iri: l.iri, types: labels(l) } }) as license,primary,anatomy_channel_image,xrefs OPTIONAL MATCH (primary)-[rp:has_reference]->(p:pub) WITH CASE WHEN p is null THEN [] ELSE collect({ core: { short_form: p.short_form, label: coalesce(p.label,''), iri: p.iri, types: labels(p) } , PubMed: coalesce(p.PMID, ''), FlyBase: coalesce(p.FlyBase, ''), DOI: coalesce(p.DOI, '') } ) END AS def_pubs,primary,anatomy_channel_image,xrefs,license RETURN { link : coalesce(primary.dataset_link, ''), core : { short_form: primary.short_form, label: coalesce(primary.label,''), iri: primary.iri, types: labels(primary) } , description : coalesce(primary.description, []), comment : coalesce(primary.`annotation - comment`, []) } AS term, 'Get JSON for DataSet' AS query, '2e501bd' AS version , anatomy_channel_image, xrefs, license, def_pubs", "parameters" : { "ID" : "$ID" }" + query=""statement": "MATCH (primary:DataSet) WHERE primary.short_form in [{ID}] WITH primary CALL apoc.cypher.run('WITH primary OPTIONAL MATCH (primary)<-[:has_source|SUBCLASSOF|INSTANCEOF*]-(i:Individual)<-[:depicts]-(channel:Individual)-[irw:in_register_with] ->(template:Individual)-[:depicts]->(template_anat:Individual) RETURN template, channel, template_anat, i, irw limit 5', {primary:primary}) yield value with value.template as template, value.channel as channel,value.template_anat as template_anat, value.i as i, value.irw as irw, primary OPTIONAL MATCH (channel)-[:is_specified_output_of]->(technique:Class) WITH CASE WHEN channel IS NULL THEN [] ELSE COLLECT({ anatomy: { short_form: i.short_form, label: coalesce(i.label,''), iri: i.iri, types: labels(i), symbol: coalesce(i.`IAO_0000028`[0], '')} , channel_image: { channel: { short_form: channel.short_form, label: coalesce(channel.label,''), iri: channel.iri, types: labels(channel), symbol: coalesce(channel.`IAO_0000028`[0], '')} , imaging_technique: { short_form: technique.short_form, label: coalesce(technique.label,''), iri: technique.iri, types: labels(technique), symbol: coalesce(technique.`IAO_0000028`[0], '')} ,image: { template_channel : { short_form: template.short_form, label: coalesce(template.label,''), iri: template.iri, types: labels(template), symbol: coalesce(template.`IAO_0000028`[0], '')} , template_anatomy: { short_form: template_anat.short_form, label: coalesce(template_anat.label,''), iri: template_anat.iri, types: labels(template_anat), symbol: coalesce(template_anat.`IAO_0000028`[0], '')} ,image_folder: COALESCE(irw.folder[0], ''), index: coalesce(apoc.convert.toInteger(irw.index[0]), []) + [] }} }) END AS anatomy_channel_image ,primary OPTIONAL MATCH (s:Site { short_form: primary.self_xref }) WITH CASE WHEN s IS NULL THEN [] ELSE COLLECT({ link_base: coalesce(s.link_base[0], ''), accession: coalesce(primary.short_form, ''), link_text: primary.label + ' on ' + s.label, homepage: coalesce(s.homepage[0], ''), site: { short_form: s.short_form, label: coalesce(s.label,''), iri: s.iri, types: labels(s), symbol: coalesce(s.`IAO_0000028`[0], '')} , icon: coalesce(s.link_icon_url[0], ''), link_postfix: coalesce(s.link_postfix, '')}) END AS self_xref, primary, anatomy_channel_image OPTIONAL MATCH (s:Site)<-[dbx:database_cross_reference]-(primary) WITH CASE WHEN s IS NULL THEN self_xref ELSE COLLECT({ link_base: coalesce(s.link_base[0], ''), accession: coalesce(dbx.accession[0], ''), link_text: primary.label + ' on ' + s.label, homepage: coalesce(s.homepage[0], ''), site: { short_form: s.short_form, label: coalesce(s.label,''), iri: s.iri, types: labels(s), symbol: coalesce(s.`IAO_0000028`[0], '')} , icon: coalesce(s.link_icon_url[0], ''), link_postfix: coalesce(s.link_postfix, '')}) + self_xref END AS xrefs,primary,anatomy_channel_image OPTIONAL MATCH (primary)-[:has_license]->(l:License) WITH collect ({ icon : coalesce(l.license_logo[0], ''), link : coalesce(l.license_url[0], ''), core : { short_form: l.short_form, label: coalesce(l.label,''), iri: l.iri, types: labels(l), symbol: coalesce(l.`IAO_0000028`[0], '')} }) as license,primary,anatomy_channel_image,xrefs OPTIONAL MATCH (primary)-[rp:has_reference]->(p:pub) WITH CASE WHEN p is null THEN [] ELSE collect({ core: { short_form: p.short_form, label: coalesce(p.label,''), iri: p.iri, types: labels(p), symbol: coalesce(p.`IAO_0000028`[0], '')} , PubMed: coalesce(p.PMID[0], ''), FlyBase: coalesce(p.FlyBase[0], ''), DOI: coalesce(p.DOI[0], '') } ) END AS pubs,primary,anatomy_channel_image,xrefs,license OPTIONAL MATCH (primary)<-[:has_source]-(i:Individual) WITH i, primary, anatomy_channel_image, xrefs, license, pubs OPTIONAL MATCH (i)-[:INSTANCEOF]-(c:Class) WITH DISTINCT { images: count(distinct i),types: count(distinct c) } as dataset_counts,primary,anatomy_channel_image,xrefs,license,pubs RETURN { link : coalesce(primary.dataset_link[0], ''), core : { short_form: primary.short_form, label: coalesce(primary.label,''), iri: primary.iri, types: labels(primary), symbol: coalesce(primary.`IAO_0000028`[0], '')} , description : coalesce(primary.description, []), comment : coalesce(primary.comment, []) } AS term, 'Get JSON for DataSet' AS query, '58214d4' AS version , anatomy_channel_image, xrefs, license, pubs, dataset_counts", "parameters" : { "ID" : "$ID" }" countQuery=""statement": "MATCH (primary:DataSet {short_form: {ID}} ) RETURN count(primary) as count", "parameters" : { "ID" : "$ID" }"> @@ -545,7 +545,7 @@ name="Get JSON for License" description="Get JSON for License" runForCount="false" - query=""statement": "MATCH (primary:License) WHERE primary.short_form in [{ID}] WITH primary RETURN { icon : coalesce(primary.license_logo, ''), link : coalesce(primary.license_url, ''), core : { short_form: primary.short_form, label: coalesce(primary.label,''), iri: primary.iri, types: labels(primary) } , description : coalesce(primary.description, []), comment : coalesce(primary.`annotation - comment`, []) } AS term, 'Get JSON for License' AS query, '2e501bd' AS version", "parameters" : { "ID" : "$ID" }" + query=""statement": "MATCH (primary:License) WHERE primary.short_form in [{ID}] WITH primary RETURN { icon : coalesce(primary.license_logo[0], ''), link : coalesce(primary.license_url[0], ''), core : { short_form: primary.short_form, label: coalesce(primary.label,''), iri: primary.iri, types: labels(primary), symbol: coalesce(primary.`IAO_0000028`[0], '')} , description : coalesce(primary.description, []), comment : coalesce(primary.comment, []) } AS term, 'Get JSON for License' AS query, '58214d4' AS version", "parameters" : { "ID" : "$ID" }" countQuery=""statement": "MATCH (primary:License {short_form: {ID}} ) RETURN count(primary) as count", "parameters" : { "ID" : "$ID" }"> @@ -555,7 +555,7 @@ name="Get JSON for Cluster" description="Get JSON for Cluster" runForCount="false" - query=""statement": "MATCH (primary:Cluster) WHERE primary.short_form in [{ID}] WITH primary OPTIONAL MATCH (primary)-[:has_source]->(ds:DataSet)-[:has_license]->(l:License) WITH COLLECT ({ dataset: { link : coalesce(ds.dataset_link, ''), core : { short_form: ds.short_form, label: coalesce(ds.label,''), iri: ds.iri, types: labels(ds) } }, license: { icon : coalesce(l.license_logo, ''), link : coalesce(l.license_url, ''), core : { short_form: l.short_form, label: coalesce(l.label,''), iri: l.iri, types: labels(l) } }}) AS dataset_license,primary OPTIONAL MATCH (o:Class)<-[r:SUBCLASSOF|INSTANCEOF]-(primary) WITH CASE WHEN o IS NULL THEN [] ELSE COLLECT ({ short_form: o.short_form, label: coalesce(o.label,''), iri: o.iri, types: labels(o) } ) END AS parents ,primary,dataset_license OPTIONAL MATCH (o:Class)<-[r {type:'Related'}]-(primary) WITH CASE WHEN o IS NULL THEN [] ELSE COLLECT ({ relation: { label: r.label, iri: r.uri, type: type(r) } , object: { short_form: o.short_form, label: coalesce(o.label,''), iri: o.iri, types: labels(o) } }) END AS relationships ,primary,dataset_license,parents OPTIONAL MATCH (s:Site { short_form: primary.self_xref }) WITH CASE WHEN s IS NULL THEN [] ELSE COLLECT({ link_base: s.link_base, accession: coalesce(primary.short_form, ''), link_text: primary.label + ' on ' + s.label, site: { short_form: s.short_form, label: coalesce(s.label,''), iri: s.iri, types: labels(s) } , icon: coalesce(s.link_icon_url, ''), link_postfix: coalesce(s.link_postfix, '')}) END AS self_xref, primary, dataset_license, parents, relationships OPTIONAL MATCH (s:Site)<-[dbx:hasDbXref]-(primary) WITH CASE WHEN s IS NULL THEN self_xref ELSE COLLECT({ link_base: s.link_base, accession: coalesce(dbx.accession, ''), link_text: primary.label + ' on ' + s.label, site: { short_form: s.short_form, label: coalesce(s.label,''), iri: s.iri, types: labels(s) } , icon: coalesce(s.link_icon_url, ''), link_postfix: coalesce(s.link_postfix, '')}) + self_xref END AS xrefs,primary,dataset_license,parents,relationships OPTIONAL MATCH (primary)<-[:depicts]-(channel:Individual)-[irw:in_register_with]->(template:Individual)-[:depicts]->(template_anat:Individual) WITH template, channel, template_anat, irw, primary, dataset_license, parents, relationships, xrefs OPTIONAL MATCH (channel)-[:is_specified_output_of]->(technique:Class) WITH CASE WHEN channel IS NULL THEN [] ELSE collect ({ channel: { short_form: channel.short_form, label: coalesce(channel.label,''), iri: channel.iri, types: labels(channel) } , imaging_technique: { short_form: technique.short_form, label: coalesce(technique.label,''), iri: technique.iri, types: labels(technique) } ,image: { template_channel : { short_form: template.short_form, label: coalesce(template.label,''), iri: template.iri, types: labels(template) } , template_anatomy: { short_form: template_anat.short_form, label: coalesce(template_anat.label,''), iri: template_anat.iri, types: labels(template_anat) } ,image_folder: irw.folder, index: coalesce(irw.index, []) + [] }}) END AS channel_image,primary,dataset_license,parents,relationships,xrefs OPTIONAL MATCH (o:Individual)<-[r {type:'Related'}]-(primary) WITH CASE WHEN o IS NULL THEN [] ELSE COLLECT ({ relation: { label: r.label, iri: r.uri, type: type(r) } , object: { short_form: o.short_form, label: coalesce(o.label,''), iri: o.iri, types: labels(o) } }) END AS related_individuals ,primary,dataset_license,parents,relationships,xrefs,channel_image RETURN { core : { short_form: primary.short_form, label: coalesce(primary.label,''), iri: primary.iri, types: labels(primary) } , description : coalesce(primary.description, []), comment : coalesce(primary.`annotation-comment`, []) } AS term, 'Get JSON for Individual:Anatomy' AS query, 'ca9ab19' AS version , dataset_license, parents, relationships, xrefs, channel_image, related_individuals", "parameters" : { "ID" : "$ID" }" + query=""statement": "MATCH (primary:Cluster) WHERE primary.short_form in [{ID}] WITH primary OPTIONAL MATCH (primary)-[:has_source]->(ds:DataSet)-[:has_license]->(l:License) WITH COLLECT ({ dataset: { link : coalesce(ds.dataset_link, ''), core : { short_form: ds.short_form, label: coalesce(ds.label,''), iri: ds.iri, types: labels(ds) } }, license: { icon : coalesce(l.license_logo[0], ''), link : coalesce(l.license_url[0], ''), core : { short_form: l.short_form, label: coalesce(l.label,''), iri: l.iri, types: labels(l) } }}) AS dataset_license,primary OPTIONAL MATCH (o:Class)<-[r:SUBCLASSOF|INSTANCEOF]-(primary) WITH CASE WHEN o IS NULL THEN [] ELSE COLLECT ({ short_form: o.short_form, label: coalesce(o.label,''), iri: o.iri, types: labels(o) } ) END AS parents ,primary,dataset_license OPTIONAL MATCH (o:Class)<-[r {type:'Related'}]-(primary) WITH CASE WHEN o IS NULL THEN [] ELSE COLLECT ({ relation: { label: r.label, iri: r.uri, type: type(r) } , object: { short_form: o.short_form, label: coalesce(o.label,''), iri: o.iri, types: labels(o) } }) END AS relationships ,primary,dataset_license,parents OPTIONAL MATCH (s:Site { short_form: primary.self_xref }) WITH CASE WHEN s IS NULL THEN [] ELSE COLLECT({ link_base: s.link_base[0], accession: coalesce(primary.short_form, ''), link_text: primary.label + ' on ' + s.label, site: { short_form: s.short_form, label: coalesce(s.label,''), iri: s.iri, types: labels(s) } , icon: coalesce(s.link_icon_url[0], ''), link_postfix: coalesce(s.link_postfix, '')}) END AS self_xref, primary, dataset_license, parents, relationships OPTIONAL MATCH (s:Site)<-[dbx:hasDbXref]-(primary) WITH CASE WHEN s IS NULL THEN self_xref ELSE COLLECT({ link_base: s.link_base[0], accession: coalesce(dbx.accession, ''), link_text: primary.label + ' on ' + s.label, site: { short_form: s.short_form, label: coalesce(s.label,''), iri: s.iri, types: labels(s) } , icon: coalesce(s.link_icon_url[0], ''), link_postfix: coalesce(s.link_postfix, '')}) + self_xref END AS xrefs,primary,dataset_license,parents,relationships OPTIONAL MATCH (primary)<-[:depicts]-(channel:Individual)-[irw:in_register_with]->(template:Individual)-[:depicts]->(template_anat:Individual) WITH template, channel, template_anat, irw, primary, dataset_license, parents, relationships, xrefs OPTIONAL MATCH (channel)-[:is_specified_output_of]->(technique:Class) WITH CASE WHEN channel IS NULL THEN [] ELSE collect ({ channel: { short_form: channel.short_form, label: coalesce(channel.label,''), iri: channel.iri, types: labels(channel) } , imaging_technique: { short_form: technique.short_form, label: coalesce(technique.label,''), iri: technique.iri, types: labels(technique) } ,image: { template_channel : { short_form: template.short_form, label: coalesce(template.label,''), iri: template.iri, types: labels(template) } , template_anatomy: { short_form: template_anat.short_form, label: coalesce(template_anat.label,''), iri: template_anat.iri, types: labels(template_anat) } ,image_folder: irw.folder[0], index: coalesce(irw.index[0], []) + [] }}) END AS channel_image,primary,dataset_license,parents,relationships,xrefs OPTIONAL MATCH (o:Individual)<-[r {type:'Related'}]-(primary) WITH CASE WHEN o IS NULL THEN [] ELSE COLLECT ({ relation: { label: r.label, iri: r.uri, type: type(r) } , object: { short_form: o.short_form, label: coalesce(o.label,''), iri: o.iri, types: labels(o) } }) END AS related_individuals ,primary,dataset_license,parents,relationships,xrefs,channel_image RETURN { core : { short_form: primary.short_form, label: coalesce(primary.label,''), iri: primary.iri, types: labels(primary) } , description : coalesce(primary.description, []), comment : coalesce(primary.`annotation-comment`, []) } AS term, 'Get JSON for Individual:Anatomy' AS query, 'ca9ab19' AS version , dataset_license, parents, relationships, xrefs, channel_image, related_individuals", "parameters" : { "ID" : "$ID" }" countQuery=""statement": "MATCH (primary:Cluster {short_form: {ID}} ) RETURN count(primary) as count", "parameters" : { "ID" : "$ID" }">