Giter Club home page Giter Club logo

open-physiology-viewer's Introduction

open-physiology-viewer

Overview

Physiology deals with the body in terms of anatomical compartments that delineate portions of interest. The compartments can be defined at various anatomical scales, from organs to cells. Clinical and bioengineering experts are interested to see records of physical measurements associated with certain anatomical compartments.

ApiNATOMY is a methodology to coherently manage knowledge about the scale, parthood and connectivity of anatomical compartments as well as to represent and analyse process mechanisms and associated measurements. It consists of

  • a knowledge model about biophysical entities, and
  • a method to build knowledge representations of physiology processes in terms of biophysical entities and physical operations over these entities.

The current project visualizes 3d ApiNATOMY models as part of the NIH-SPARC MAP-CORE toolset. The main component in the current project accepts as input a JSON model and generates a force-directed graph layout satisfying relational constraints among model resources. The input model format is defined in the ApiNATOMY JSON Schema specification, check project documentation for more detail. Live demonstration of this application can be found here.

Build instructions

  • Install Node.js.
  • Clone (or download and unzip) the project to your file system: git clone https://github.com/metacell/open-physiology-viewer.git
  • Go into the project directory: cd ./open-physiology-viewer
  • Install build dependencies: npm install
  • Run the build script: npm run build

The compiled code is in the open-physiology/dist/ folder. After that you should be able to open a demo app test-app/index.html in your browser.

Google Chrome flags

  • enable GPU rasterization see chrome://flags/#enable-gpu-rasterization

open-physiology-viewer's People

Contributors

alan-wu avatar albatros13 avatar ddelpiano avatar enicolasgomez avatar jrmartin avatar tgbugs avatar vidhya-metacell avatar zsinnema avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

open-physiology-viewer's Issues

continual stream of errors when trying to load a previously working model

When I try to load the following file I get a repeated stream of TypeErrors.
Keast_Flatmap_051420(25).xlsx. This also happens when I try to load the latest models for export and validation, so am stuck on that.

errorHandler.js:16 TypeError: Cannot read property 'version' of undefined
    at Object.eval [as updateDirectives] (ResourceEditor.html:15)
    at Object.debugUpdateDirectives [as updateDirectives] (core.js:30043)
    at checkAndUpdateView (core.js:29439)
    at callViewAction (core.js:29680)
    at execEmbeddedViewsAction (core.js:29643)
    at checkAndUpdateView (core.js:29440)
    at callViewAction (core.js:29680)
    at execComponentViewsAction (core.js:29622)
    at checkAndUpdateView (core.js:29445)
    at callViewAction (core.js:29680)

nextChain property to link between chains

With the new behavior for dealing with branches implemented in issue #12 we need to make sure that we can traverse multiple chains. I suggest that we add a relationship nextChain between the leaf node of one chain and the root of the next chain so that the query can be kept as simple as possible, requiring the addition of only a single new edge type (i.e., apinatomy:nextChain).

Prevent warning generation if both sides of related properties refer to the same template

A -> internalIn -> B and B -> internalLyphs -> [A] where A or B are templates results into a warning that A cannot be internal in 2 lyphs. This is due to the template replacement procedure - each reference to template is replaced to a unique instance - this works fine for most cases but leads to an unjustified warning for the case when both sides of the relationship are specified.

Make chain bundled links parallel

When 2 or more chain links are bundled by a hosting lyph, align them so that their axes are parallel to the lyph's axes (currently they are reversed). This can be fixed by processing hostedNodes on opposite borders in reversed order

Split the schema into connectivity model (Graph) and scaffold model (Scaffold)

The new layout requirements (https://docs.google.com/document/d/1Aub84B5vRVgQmXvZ7hkJEpW2c9MNxYRhjS3kBB7So1I/edit) imply that connectivity models are placed into scaffolds that trigger automated layout. We should define a schema to describe scaffolds, implement support for 2 types of models in the ApiNATOMY viewer (e.g., open, merge, convert from Excel templates etc.), associate scaffolds with connectivity models, refer to scaffold elements from connectivity models, etc.

Should layers of lyph templates be templates?

Currently we can create templates using specific lyphs as layers, e.g., in the definition
{"id": "K-129",
"name": "Segment of Spinal Cord",
"isTemplate": true,
"layers": ["104","105","K-86","KM-27","K-85","K-84","K-83","K-82","K-81","K-80","K-79",...]}
layers here are either materials (abstract) or lyphs (not templates in this example).
Should this be banned? Should we automatically set property isTemplate for such layers in the generated model?
The problem manifests when we auto-generate links for all lyphs which are not templates - these lyphs become visible free flowating lyphs in the model...

JSON schema for ApiNATOMY data and visualization models

As ApiNATOMY models are rich in concepts connected by many relationships, it becomes increasingly harder to maintain ongoing code with the introduction of new rules and scenarios.
We need to ensure that the data input for the viewer is as expected: all entity types are recognized, required fields present, expected data types are correct (i.e., it is a common mistake while coding to confuse what the content of a field is: an id or an object reference) get warning about unspecified/unprocessed properties in the model. Possibly two schemas are neede: 1) for pure data input, 2) for extended JSON objects operated by the viewer.

Logging messages interface

Add filters to skip information messages and show fatal errors or warnings in the dialog showing model conversion results
Add "Download" button to store the logging messages and stats in a file

Z-fighting problem - derive polygonOffsetFactor from data

When creating materials, the polygonOffsetFactor parameter is used to define which objects with the same z-coordinate are located closer to the camera/viewer - smaller values mean the object appears on top of other surfaces. We set this parameter in the model to work for our ongoing scenario (Kidney model).
Refactor code to remove ad-hoc polygonOffsetFactor assignments from the visualization models and introduce a method to derive polygonOffsetFactor for each modeling primitive from the input data (ApiNATOMY model of an organ).

Implement support for elliptic arc links and regions composed of links

To model scaffold components F1, F2, F3, F4 etc., we need to be able to define area between two straight edges and an elliptic curve. Existing templates model layout of TOO map as a combination of axes and semicircle links, but this method does not allow us to define 4 regions and retain graphical content within their contours.
This can be addressed by extending the schema for defining regions by allowing regions to be composed of links (similarly to the levels in chains, but with common start and end node)

performance on large models

The viewer currently grinds to a near halt when working on large models. This happens even when most of the model is not visible.

load model directly from google sheets link or google sheets document id

Google sheets provides a direct link to download the xlsx version of a spreadsheet. The viewer should be able to accept the document id or google sheets url and construct the xlsx link from that. There should be a button to reimport the same doc id without having to enter it again so that the author can set the document they are working for their whole authoring session.
The format of the output is https://docs.google.com/spreadsheets/d/{spreadsheet-id}/export?format=xlsx and the interface box should accept https://docs.google.com/spreadsheets/d/{spreadsheet-id}.+ and {spreadsheet-id} as values. The internal api should require only the spreadsheet-id, and will need to handle cases where the spreadsheet id is not actually for a spreadsheet, and cases where the spreadsheet is not accessible. Advice to users is if they are concerned about sharing the document with edit permissions then they can set link sharing to view only and the viewer will still be able to download the document without having to do the api key dance.

Adding this feature will entirely remove the need to manually download the xlsx sheets from google sheets, which is massively time consuming during the authoring workflow.

region z-fighting

The surfaces of regions need to have a polygon priority ordering to keep regions from z-fighting. Sometimes this could be inferred from the order in which scaffolds are loaded, but other times we would always want the F component to be below the D component because F is larger than D.

Link group templates, e.g., chains, to nested groups

The ApiNATOMY schema allows users to define group templates within nested groups. Users may also refer to group templates defined in other groups. Model generator currently does not process correctly references to templates (in particular, chains), defined in other groups.

We should:

  1. in a group, skip references to templates (trying to expand a chain defined in another group currently throws an exception as the reference is a string and not an object).
  2. include resources generated from the template into all groups that refer to the template.
    Without this functionality, it is impossible to create groups that combine several external chains

fatal error messages should remain visbile

When loading the attached file a red error message appears briefly and then disappears and the model is only partially loaded. I think the only thing that needs to be done is to keep the error visible and maybe add a note that the model may not have loaded correctly. Keast_Flatmap_051420.xlsx

querying over chains vs queyring the link-node structure

Chains provide a way to directly query from link to link and across chains. The link node structure requires traversing links, nodes, and clones. Both types of queries cannot be run at the same time, we need to settle on a single representation that we will query. Preferably this would be a direct relationship between links that deals specifically with the anatomical connectivity rather than the structure needed to render the anatomy in the viewer.

Reference resource type

When converting ApiNATOMY models to JSON-LD external ontology identifiers and references are currently conflated. To avoid this it would be helpful to have a Reference type that was a subclass of the External type that would make it possible to distinguish between external ontology ids and literature references since the semantics are significantly different.

Writing this I also realize that it might make sense to create another subclass of external ids that are OntologyId or OntologyTerm which would provide a way to differentiate ontology ids from other external ids rather than making them the default interpretation (if they continue to be of type External).

As the publication key has already been split from the external key in the model, it might make sense to have an edge that is ontologyTerm with specific semantics as well which could be used to unambiguously translate to rdf:type using the json-ld @context. This would (for example) make it possible to automatically include axon segments as the type of the named individual links/lyphs from the model.

Lyph borders

Work on the borderModel and borderLinkModel to enable

  • creation of overall border and individual side borders (axis, two radial borders and outer longitudinal border), and process relationships among borders and other entities (e.g., boundary nodes)
  • drawing and highlighting of lyph borders
  • possibility to use a border as a rotational axis for an internal lyph

Coalescences check box appears to have opposite effect

The earlier version of graph.json (before commit 030d687) contains an example of a coalescence between lyph 78 and lyph 24. However these two lyphs are only adjacent in the viewer when the Coalescences box is unchecked:

screen shot 2018-11-20 at 4 15 49 pm

The lyphs drift apart when the box is checked:

screen shot 2018-11-20 at 4 16 05 pm

jsonld schema generated context is empty

For some reason the @context entries derived from graphScheme.json are no longer being extracted when I run on the json-ld branch branch or on master. @albatros13 was there some change to graphScheme.json that would cause this? Does the viewer pull the schema from github directly? I'm very confused right now.

Handle nested resource definitions

A series of tests are needed to check that nested objects are processed correctly.
For example, a user may define a chain by specifying some properties of levels (links) using nested objects
{
"id": "t1", "lyphTemplate": "template1",
"root": "n1", "leaf" : "n2,
"levels": [{"source": {"layout":{"x": -100}}}, {}, {}, {}, {"target": {"layout": {"x": 100}}}]
}
Here property {"layout":{"x": -100}} should be applied to the first node of the chain which is its root "n1". Similarly, {"layout": {"x": 100}} applies to the last node in the chain, or its leaf "n2".
While the definitions
{
"id": "t1", "lyphTemplate": "template1",
"levels": [{"source": "n1"}, {}, {}, {}, {"target": "n2"}]
},
{ "id": "n1", "layout":{"x": -100} },
{ "id": "n2", "layout":{"x": 100} }
are processed correctly, nested objects are often not expected by the model generator (but they are validated by the schema and hence should be processed).

Lyphs on border bug

After switching off and on visualization of layers, layers in the lyph on border do not reappear

Visualize query execution results

Implement a function that sends query requests to SciGraph-based service and shows returned results as a dynamic group in the model viewer.

Forcing content of the lyph to stay on top of it

Container lyphs represent organs with inner structure (e.g., Kidney lobus with two omega trees). The viewer should keep dependent entities (omega tree nodes and edges with conveying lyphs) within the boundaries of the host lyph.

The updateViewObjects of the lyphModel.js needs updating: currently 'boundToRectangle' method only pushes link source and target nodes to the straight rectangle while in practice the host lyph can be tilted, so we need to force these links to be within the lyph shape (for simplicity, we can do it for the rectangle shape, but accounting for its transformation/rotation).

In the case of 3d lyph icons, the host lyph is a tube/cyst/bag and the dependent entities are free to float in the whole its volume (this is what happens conceptually and should be implemented ideally, but 3d visualization is of low priority, 'nice to have' feature).

stack overflow when trying to download flattened jsonld

Some changes between the current live version (49) and the backup copy from Aug 31st have induced a stack overflow to occur when trying to export the flattened json-ld. I'm loading the version from the 31st, because I can't track down the issue right now, but it basically entails dumping the standard resourcemaps and comparing the diff to see what is causing the issue. @MCSZ if you know what you changed this morning you might be able to figure it out faster than I can without having to save and compare the resource maps (though fixing the code so that this can't happen will require that).

Copy of Keast_Flatmap_051420 - August 31, 1 53 PM.xlsx
Keast_Flatmap_051420(49).xlsx

errorHandler.js:16 Error: Uncaught (in promise): RangeError: Maximum call stack size exceeded
RangeError: Maximum call stack size exceeded
    at Object.../node_modules/jsonld/dist/node6/lib/util.js.api.clone (util.js:36)
    at Object.../node_modules/jsonld/dist/node6/lib/util.js.api.clone (util.js:44)
    at Object.../node_modules/jsonld/dist/node6/lib/util.js.api.clone (util.js:62)
    at Object.../node_modules/jsonld/dist/node6/lib/util.js.api.clone (util.js:44)
    at Object.../node_modules/jsonld/dist/node6/lib/util.js.api.clone (util.js:62)
    at Object.../node_modules/jsonld/dist/node6/lib/util.js.api.clone (util.js:44)
    at Object.../node_modules/jsonld/dist/node6/lib/util.js.api.clone (util.js:62)
    at Object.../node_modules/jsonld/dist/node6/lib/util.js.api.clone (util.js:44)
    at Object.../node_modules/jsonld/dist/node6/lib/util.js.api.clone (util.js:62)
    at Object.../node_modules/jsonld/dist/node6/lib/util.js.api.clone (util.js:44)
    at resolvePromise (zone.js:831)
    at resolvePromise (zone.js:788)
    at zone.js:892
    at ZoneDelegate.../node_modules/zone.js/dist/zone.js.ZoneDelegate.invokeTask (zone.js:423)
    at Object.onInvokeTask (core.js:26247)
    at ZoneDelegate.../node_modules/zone.js/dist/zone.js.ZoneDelegate.invokeTask (zone.js:422)
    at Zone.../node_modules/zone.js/dist/zone.js.Zone.runTask (zone.js:195)
    at drainMicroTaskQueue (zone.js:601)
    at ZoneTask.../node_modules/zone.js/dist/zone.js.ZoneTask.invokeTask [as invoke] (zone.js:502)
    at invokeTask (zone.js:1744)

Add tests for angular components

Significant model manipulations may happen on input data change or when UI operations are called. We need regression tests for all major commands (create a new model, load, merge, save, edit resources, etc.)

Tests for levels and levelIn relationship pair

To complete issue #12, I added a property to the Link class to point to the chain in which this link is a level. Theoretically, one link can be used in several chains, so this relationship may need to be revised.
Alternatively, we need a check to issue a warning if the modeller creates chains that share a link.
We also need to add unit tests to make sure the relationship auto-completes.
Also, we do not assemble chains by collecting links with set-up property levelIn as their order is unclear, this has to be reflected in the documentation and via logging.

Sharing of end nodes in housed chains

When a chain is generated to stretch alone housing lyphs, its end points (root and leaf) are placed to the first and the last housing lyphs. This is achieved by setting the node's property "internalIn". The problem arises when a user tries to join several chains by sharing their end nodes - the same node is forced to be internal in two different lyphs causing model inconsistency. When this happens with border nodes, we clone the nodes, but no actions are taken for internal nodes.

Keast Spinal model debugging

Find the cause of issues:
Remaining references to undefined resources:
{"s_lnk-snl16":[["lnk-snl16","source"]],"t_lnk-snl16":[["lnk-snl16","target"]],"s_lnk-snl26":[["lnk-snl26","source"]],"t_lnk-snl26":[["lnk-snl26","target"]],"s_ns255":[["ns255","source"]],"t_ns255":[["ns255","target"]]}
Property "internalIn" of the first resource (Lyph) should match the second resource:
{"id":"an-img_11","name":"Axon of FOS to IMG from DRG","class":"Lyph","external":["GO:0030424"],"color":"#ff7f00","border":"b_an-img_11","internalLyphColumns":1,"thickness":{},"length":{},"supertype":"229","inheritedExternal":["CL:0000540"],"conveys":"lnk-an-img_11","layers":["ref_mat_54_229_an-img_11_1","ref_mat_56_229_an-img_11_2","ref_mat_116_229_an-img_11_3"],"internalIn":"K101","inCoalescences":[],"scale":{"width":40,"height":80},"hidden":true}
"sn-hypo_11"
Property "internalIn" of the first resource (Lyph) should match the second resource:
{"id":"an-pg_11","name":"Axon of POS through PG","class":"Lyph","external":["GO:0030424"],"color":"#e7298a","border":"b_an-pg_11","internalLyphColumns":1,"thickness":{},"length":{},"supertype":"229","inheritedExternal":["CL:0000540"],"conveys":"lnk-an-pg_11","layers":["ref_mat_54_229_an-pg_11_1","ref_mat_56_229_an-pg_11_2","ref_mat_116_229_an-pg_11_3"],"internalIn":"K103","inCoalescences":[],"scale":{"width":40,"height":80},"hidden":true}
"sn-hypo_11"
Property "internalIn" of the first resource (Lyph) should match the second resource:
{"id":"sn-img_3","name":"Soma to SPOG neuron 3 in IMG","class":"Lyph","external":["ILX:0110736"],"color":"#a6cee3","border":"b_sn-img_3","internalLyphColumns":1,"thickness":{},"length":{},"supertype":"229","inheritedExternal":["CL:0000540"],"conveys":"lnk-sn-img_3","layers":["ref_mat_54_229_sn-img_3_1","ref_mat_56_229_sn-img_3_2","ref_mat_116_229_sn-img_3_3"],"internalIn":"K102","inCoalescences":[],"scale":{"width":40,"height":80},"hidden":true}
"sn-hypo_3"
Property "internalIn" of the first resource (Lyph) should match the second resource:
{"id":"an-pg_3","name":"Axon to SPOG neuron 3 in PG","class":"Lyph","external":["GO:0030424"],"color":"#1f78b4","border":"b_an-pg_3","internalLyphColumns":1,"thickness":{},"length":{},"supertype":"229","inheritedExternal":["CL:0000540"],"conveys":"lnk-an-pg_3","layers":["ref_mat_54_229_an-pg_3_1","ref_mat_56_229_an-pg_3_2","ref_mat_116_229_an-pg_3_3"],"internalIn":"sn-hypo_3","inCoalescences":[],"scale":{"width":40,"height":80},"hidden":true}
"sn-blad_3"
Property "internalIn" of the first resource (Lyph) should match the second resource:
{"id":"an-pg_3","name":"Axon to SPOG neuron 3 in PG","class":"Lyph","external":["GO:0030424"],"color":"#1f78b4","border":"b_an-pg_3","internalLyphColumns":1,"thickness":{},"length":{},"supertype":"229","inheritedExternal":["CL:0000540"],"conveys":"lnk-an-pg_3","layers":["ref_mat_54_229_an-pg_3_1","ref_mat_56_229_an-pg_3_2","ref_mat_116_229_an-pg_3_3"],"internalIn":"sn-hypo_3","inCoalescences":[],"scale":{"width":40,"height":80},"hidden":true}
"sn-blad2_3"
Property "internalIn" of the first resource (Lyph) should match the second resource:
{"id":"an-pg_11","name":"Axon of POS through PG","class":"Lyph","external":["GO:0030424"],"color":"#e7298a","border":"b_an-pg_11","internalLyphColumns":1,"thickness":{},"length":{},"supertype":"229","inheritedExternal":["CL:0000540"],"conveys":"lnk-an-pg_11","layers":["ref_mat_54_229_an-pg_11_1","ref_mat_56_229_an-pg_11_2","ref_mat_116_229_an-pg_11_3"],"internalIn":"K103","inCoalescences":[],"scale":{"width":40,"height":80},"hidden":true}
"sn-blad-bn_11"
Property "internalIn" of the first resource (Lyph) should match the second resource:
{"id":"sn-blad-bn_11","name":"Neuron segment from PG to bladder neck_neuron 11","class":"Lyph","external":["GO:0030424"],"color":"#33a02c","border":"b_sn-blad-bn_11","internalLyphColumns":1,"internalLyphs":["an-pg_11","sn-blad-bn_11"],"thickness":{},"length":{},"conveys":"lnk-sn-blad-bn_11","internalIn":"n-blad","inCoalescences":[],"scale":{"width":40,"height":80}}
"sn-blad-bn_11"
Property "internalIn" of the first resource (Lyph) should match the second resource:
{"id":"an-pg_11","name":"Axon of POS through PG","class":"Lyph","external":["GO:0030424"],"color":"#e7298a","border":"b_an-pg_11","internalLyphColumns":1,"thickness":{},"length":{},"supertype":"229","inheritedExternal":["CL:0000540"],"conveys":"lnk-an-pg_11","layers":["ref_mat_54_229_an-pg_11_1","ref_mat_56_229_an-pg_11_2","ref_mat_116_229_an-pg_11_3"],"internalIn":"K103","inCoalescences":[],"scale":{"width":40,"height":80},"hidden":true}
"sn-blad-bn2_11"
Property "internalIn" of the first resource (Lyph) should match the second resource:
{"id":"an-pg_11","name":"Axon of POS through PG","class":"Lyph","external":["GO:0030424"],"color":"#e7298a","border":"b_an-pg_11","internalLyphColumns":1,"thickness":{},"length":{},"supertype":"229","inheritedExternal":["CL:0000540"],"conveys":"lnk-an-pg_11","layers":["ref_mat_54_229_an-pg_11_1","ref_mat_56_229_an-pg_11_2","ref_mat_116_229_an-pg_11_3"],"internalIn":"K103","inCoalescences":[],"scale":{"width":40,"height":80},"hidden":true}
"sn-blad-bn3_11"
Property "internalIn" of the first resource (Lyph) should match the second resource:
{"id":"an-pg_11","name":"Axon of POS through PG","class":"Lyph","external":["GO:0030424"],"color":"#e7298a","border":"b_an-pg_11","internalLyphColumns":1,"thickness":{},"length":{},"supertype":"229","inheritedExternal":["CL:0000540"],"conveys":"lnk-an-pg_11","layers":["ref_mat_54_229_an-pg_11_1","ref_mat_56_229_an-pg_11_2","ref_mat_116_229_an-pg_11_3"],"internalIn":"K103","inCoalescences":[],"scale":{"width":40,"height":80},"hidden":true}
"sn-blad-bd_11"
Property "internalIn" of the first resource (Lyph) should match the second resource:
{"id":"an-pg_11","name":"Axon of POS through PG","class":"Lyph","external":["GO:0030424"],"color":"#e7298a","border":"b_an-pg_11","internalLyphColumns":1,"thickness":{},"length":{},"supertype":"229","inheritedExternal":["CL:0000540"],"conveys":"lnk-an-pg_11","layers":["ref_mat_54_229_an-pg_11_1","ref_mat_56_229_an-pg_11_2","ref_mat_116_229_an-pg_11_3"],"internalIn":"K103","inCoalescences":[],"scale":{"width":40,"height":80},"hidden":true}
"sn-blad-bd2_11"
Property "internalIn" of the first resource (Lyph) should match the second resource:
{"id":"an-pg_11","name":"Axon of POS through PG","class":"Lyph","external":["GO:0030424"],"color":"#e7298a","border":"b_an-pg_11","internalLyphColumns":1,"thickness":{},"length":{},"supertype":"229","inheritedExternal":["CL:0000540"],"conveys":"lnk-an-pg_11","layers":["ref_mat_54_229_an-pg_11_1","ref_mat_56_229_an-pg_11_2","ref_mat_116_229_an-pg_11_3"],"internalIn":"K103","inCoalescences":[],"scale":{"width":40,"height":80},"hidden":true}
"sn-blad-bd3_11"
Property "internalIn" of the first resource (Lyph) should match the second resource:
{"id":"an-pg_4","name":"Axon through pelvic ganglia axon_4","class":"Lyph","external":["GO:0030424"],"color":"#ff7f00","border":"b_an-pg_4","internalLyphColumns":1,"thickness":{},"length":{},"supertype":"229","inheritedExternal":["CL:0000540"],"conveys":"lnk-an-pg_4","layers":["ref_mat_54_229_an-pg_4_1","ref_mat_56_229_an-pg_4_2","ref_mat_116_229_an-pg_4_3"],"internalIn":"K104","inCoalescences":[],"scale":{"width":40,"height":80},"hidden":true}
"sn-blad_4"
Property "internalIn" of the first resource (Lyph) should match the second resource:
{"id":"an-pg_4","name":"Axon through pelvic ganglia axon_4","class":"Lyph","external":["GO:0030424"],"color":"#ff7f00","border":"b_an-pg_4","internalLyphColumns":1,"thickness":{},"length":{},"supertype":"229","inheritedExternal":["CL:0000540"],"conveys":"lnk-an-pg_4","layers":["ref_mat_54_229_an-pg_4_1","ref_mat_56_229_an-pg_4_2","ref_mat_116_229_an-pg_4_3"],"internalIn":"K104","inCoalescences":[],"scale":{"width":40,"height":80},"hidden":true}
"sn-blad2_4"
Property "internalIn" of the first resource (Lyph) should match the second resource:
{"id":"an-PG_10","name":"Axon to FOS neuron 10 in pelvic ganglia","class":"Lyph","external":["GO:0030424"],"color":"#7570b3","border":"b_an-PG_10","internalLyphColumns":1,"thickness":{},"length":{},"supertype":"229","inheritedExternal":["CL:0000540"],"conveys":"lnk-an-PG_10","layers":["ref_mat_54_229_an-PG_10_1","ref_mat_56_229_an-PG_10_2","ref_mat_116_229_an-PG_10_3"],"internalIn":"K104","inCoalescences":[],"scale":{"width":40,"height":80},"hidden":true}
"sn-blad-bn_10"
Property "internalIn" of the first resource (Lyph) should match the second resource:
{"id":"an-PG_10","name":"Axon to FOS neuron 10 in pelvic ganglia","class":"Lyph","external":["GO:0030424"],"color":"#7570b3","border":"b_an-PG_10","internalLyphColumns":1,"thickness":{},"length":{},"supertype":"229","inheritedExternal":["CL:0000540"],"conveys":"lnk-an-PG_10","layers":["ref_mat_54_229_an-PG_10_1","ref_mat_56_229_an-PG_10_2","ref_mat_116_229_an-PG_10_3"],"internalIn":"K104","inCoalescences":[],"scale":{"width":40,"height":80},"hidden":true}
"sn-blad-bn2_10"
Property "internalIn" of the first resource (Lyph) should match the second resource:
{"id":"an-PG_10","name":"Axon to FOS neuron 10 in pelvic ganglia","class":"Lyph","external":["GO:0030424"],"color":"#7570b3","border":"b_an-PG_10","internalLyphColumns":1,"thickness":{},"length":{},"supertype":"229","inheritedExternal":["CL:0000540"],"conveys":"lnk-an-PG_10","layers":["ref_mat_54_229_an-PG_10_1","ref_mat_56_229_an-PG_10_2","ref_mat_116_229_an-PG_10_3"],"internalIn":"K104","inCoalescences":[],"scale":{"width":40,"height":80},"hidden":true}
"sn-blad-bn3_10"
Property "internalIn" of the first resource (Lyph) should match the second resource:
{"id":"an-PG_10","name":"Axon to FOS neuron 10 in pelvic ganglia","class":"Lyph","external":["GO:0030424"],"color":"#7570b3","border":"b_an-PG_10","internalLyphColumns":1,"thickness":{},"length":{},"supertype":"229","inheritedExternal":["CL:0000540"],"conveys":"lnk-an-PG_10","layers":["ref_mat_54_229_an-PG_10_1","ref_mat_56_229_an-PG_10_2","ref_mat_116_229_an-PG_10_3"],"internalIn":"K104","inCoalescences":[],"scale":{"width":40,"height":80},"hidden":true}
"sn-blad-bd_10"
Property "internalIn" of the first resource (Lyph) should match the second resource:
{"id":"an-PG_10","name":"Axon to FOS neuron 10 in pelvic ganglia","class":"Lyph","external":["GO:0030424"],"color":"#7570b3","border":"b_an-PG_10","internalLyphColumns":1,"thickness":{},"length":{},"supertype":"229","inheritedExternal":["CL:0000540"],"conveys":"lnk-an-PG_10","layers":["ref_mat_54_229_an-PG_10_1","ref_mat_56_229_an-PG_10_2","ref_mat_116_229_an-PG_10_3"],"internalIn":"K104","inCoalescences":[],"scale":{"width":40,"height":80},"hidden":true}
"sn-blad-bd2_10"
Property "internalIn" of the first resource (Lyph) should match the second resource:
{"id":"an-PG_10","name":"Axon to FOS neuron 10 in pelvic ganglia","class":"Lyph","external":["GO:0030424"],"color":"#7570b3","border":"b_an-PG_10","internalLyphColumns":1,"thickness":{},"length":{},"supertype":"229","inheritedExternal":["CL:0000540"],"conveys":"lnk-an-PG_10","layers":["ref_mat_54_229_an-PG_10_1","ref_mat_56_229_an-PG_10_2","ref_mat_116_229_an-PG_10_3"],"internalIn":"K104","inCoalescences":[],"scale":{"width":40,"height":80},"hidden":true}
"sn-blad-bd3_10"
Property "internalIn" of the first resource (Lyph) should match the second resource:
{"id":"sn-pg_1","name":"Soma to PPOG neuron 1 in pelvic ganglia","class":"Lyph","external":["ILX:0110736"],"color":"#a6cee3","border":"b_sn-pg_1","internalLyphColumns":1,"thickness":{},"length":{},"supertype":"229","inheritedExternal":["CL:0000540"],"conveys":"lnk-sn-pg_1","layers":["ref_mat_54_229_sn-pg_1_1","ref_mat_56_229_sn-pg_1_2","ref_mat_116_229_sn-pg_1_3"],"internalIn":"K103","inCoalescences":[],"scale":{"width":40,"height":80},"hidden":true}
"sn-blad-bn_1"
Property "internalIn" of the first resource (Lyph) should match the second resource:
{"id":"sn-pg_1","name":"Soma to PPOG neuron 1 in pelvic ganglia","class":"Lyph","external":["ILX:0110736"],"color":"#a6cee3","border":"b_sn-pg_1","internalLyphColumns":1,"thickness":{},"length":{},"supertype":"229","inheritedExternal":["CL:0000540"],"conveys":"lnk-sn-pg_1","layers":["ref_mat_54_229_sn-pg_1_1","ref_mat_56_229_sn-pg_1_2","ref_mat_116_229_sn-pg_1_3"],"internalIn":"K103","inCoalescences":[],"scale":{"width":40,"height":80},"hidden":true}
"sn-blad-bn2_1"
Property "internalIn" of the first resource (Lyph) should match the second resource:
{"id":"sn-pg_1","name":"Soma to PPOG neuron 1 in pelvic ganglia","class":"Lyph","external":["ILX:0110736"],"color":"#a6cee3","border":"b_sn-pg_1","internalLyphColumns":1,"thickness":{},"length":{},"supertype":"229","inheritedExternal":["CL:0000540"],"conveys":"lnk-sn-pg_1","layers":["ref_mat_54_229_sn-pg_1_1","ref_mat_56_229_sn-pg_1_2","ref_mat_116_229_sn-pg_1_3"],"internalIn":"K103","inCoalescences":[],"scale":{"width":40,"height":80},"hidden":true}
"sn-blad-bd_1"
Property "internalIn" of the first resource (Lyph) should match the second resource:
{"id":"sn-pg_1","name":"Soma to PPOG neuron 1 in pelvic ganglia","class":"Lyph","external":["ILX:0110736"],"color":"#a6cee3","border":"b_sn-pg_1","internalLyphColumns":1,"thickness":{},"length":{},"supertype":"229","inheritedExternal":["CL:0000540"],"conveys":"lnk-sn-pg_1","layers":["ref_mat_54_229_sn-pg_1_1","ref_mat_56_229_sn-pg_1_2","ref_mat_116_229_sn-pg_1_3"],"internalIn":"K103","inCoalescences":[],"scale":{"width":40,"height":80},"hidden":true}
"sn-blad-bd2_1"
Property "internalIn" of the first resource (Lyph) should match the second resource:
{"id":"sn-pg_2","name":"Soma to SPOG neuron 2 in pelvic ganglia","class":"Lyph","external":["ILX:0110736"],"color":"#a6cee3","border":"b_sn-pg_2","internalLyphColumns":1,"thickness":{},"length":{},"supertype":"229","inheritedExternal":["CL:0000540"],"conveys":"lnk-sn-pg_2","layers":["ref_mat_54_229_sn-pg_2_1","ref_mat_56_229_sn-pg_2_2","ref_mat_116_229_sn-pg_2_3"],"internalIn":"K103","inCoalescences":[],"scale":{"width":40,"height":80}}
"sn-blad_2"
Property "internalIn" of the first resource (Lyph) should match the second resource:
{"id":"sn-pg_2","name":"Soma to SPOG neuron 2 in pelvic ganglia","class":"Lyph","external":["ILX:0110736"],"color":"#a6cee3","border":"b_sn-pg_2","internalLyphColumns":1,"thickness":{},"length":{},"supertype":"229","inheritedExternal":["CL:0000540"],"conveys":"lnk-sn-pg_2","layers":["ref_mat_54_229_sn-pg_2_1","ref_mat_56_229_sn-pg_2_2","ref_mat_116_229_sn-pg_2_3"],"internalIn":"K103","inCoalescences":[],"scale":{"width":40,"height":80}}
"sn-blad2_2"
Property "internalIn" of the first resource (Lyph) should match the second resource:
{"id":"an-bd0tobd1_1","name":"Axon to PPOG neuron 1 in bladder dome layer 0","class":"Lyph","external":["GO:0030424"],"color":"#fdbf6f","border":"b_an-bd0tobd1_1","internalLyphColumns":1,"thickness":{},"length":{},"supertype":"229","inheritedExternal":["CL:0000540"],"conveys":"lnk-an-bd0tobd1_1","layers":["ref_mat_54_229_an-bd0tobd1_1_1","ref_mat_56_229_an-bd0tobd1_1_2","ref_mat_116_229_an-bd0tobd1_1_3"],"internalIn":"sn-blad-bd_1","inCoalescences":[],"scale":{"width":40,"height":80},"hidden":true}
"ref_mat_KM_1_K99"
Property "internalIn" of the first resource (Lyph) should match the second resource:
{"id":"an-bd0forbd2_1","name":"Axon to PPOG neuron 1 in bladder dome layer 0 for layer 2","class":"Lyph","external":["GO:0030424"],"color":"#cab2d6","border":"b_an-bd0forbd2_1","internalLyphColumns":1,"thickness":{},"length":{},"supertype":"229","inheritedExternal":["CL:0000540"],"conveys":"lnk-an-bd0forbd2_1","layers":["ref_mat_54_229_an-bd0forbd2_1_1","ref_mat_56_229_an-bd0forbd2_1_2","ref_mat_116_229_an-bd0forbd2_1_3"],"internalIn":"sn-blad-bd2_1","inCoalescences":[],"scale":{"width":40,"height":80},"hidden":true}
"ref_mat_KM_1_K99"
Property "internalIn" of the first resource (Lyph) should match the second resource:
{"id":"an-bd0_2","class":"Lyph","generated":true,"border":"b_an-bd0_2","internalLyphColumns":1,"thickness":{},"length":{},"conveys":"lnk_an-bd0_2","internalIn":"sn-blad2_2","inCoalescences":[],"width":20.480000000000004,"height":40.96000000000001,"scale":{"width":40,"height":80}}
"ref_mat_KM_1_K99"
Property "internalIn" of the first resource (Lyph) should match the second resource:
{"id":"an-bd0_3","name":"Axon to SPOG neuron 3 in Bladder dome layer 0","class":"Lyph","external":["GO:0030424"],"color":"#fb9a99","border":"b_an-bd0_3","internalLyphColumns":1,"thickness":{},"length":{},"supertype":"229","inheritedExternal":["CL:0000540"],"conveys":"lnk-an-bd0_3","layers":["ref_mat_54_229_an-bd0_3_1","ref_mat_56_229_an-bd0_3_2","ref_mat_116_229_an-bd0_3_3"],"internalIn":"sn-blad2_3","inCoalescences":[],"scale":{"width":40,"height":80},"hidden":true}
"ref_mat_KM_1_K99"
Property "internalIn" of the first resource (Lyph) should match the second resource:
{"id":"an_bd0-bv_10","name":"Axon to FOS neuron 10 bladder dome 0 to blood vessel","class":"Lyph","external":["GO:0030424"],"color":"#b2df8a","border":"b_an_bd0-bv_10","internalLyphColumns":1,"thickness":{},"length":{},"supertype":"229","inheritedExternal":["CL:0000540"],"conveys":"lnk-an_bd0-bv_10","layers":["ref_mat_54_229_an_bd0-bv_10_1","ref_mat_56_229_an_bd0-bv_10_2","ref_mat_116_229_an_bd0-bv_10_3"],"internalIn":"sn-blad-bd_10","inCoalescences":[],"scale":{"width":40,"height":80},"hidden":true}
"ref_mat_KM_1_K99"
Property "internalIn" of the first resource (Lyph) should match the second resource:
{"id":"an_bd0-bd1_10","name":"Axon to FOS neuron 10 bladder dome 0 to bladder dome 1","class":"Lyph","external":["GO:0030424"],"color":"#33a02c","border":"b_an_bd0-bd1_10","internalLyphColumns":1,"thickness":{},"length":{},"supertype":"229","inheritedExternal":["CL:0000540"],"conveys":"lnk-an_bd0-bd1_10","layers":["ref_mat_54_229_an_bd0-bd1_10_1","ref_mat_56_229_an_bd0-bd1_10_2","ref_mat_116_229_an_bd0-bd1_10_3"],"internalIn":"sn-blad-bd2_10","inCoalescences":[],"scale":{"width":40,"height":80},"hidden":true}
"ref_mat_KM_1_K99"
Property "internalIn" of the first resource (Lyph) should match the second resource:
{"id":"an_bd0-bd3_10","name":"Axon to FOS neuron 10 bladder dome 0 to bladder dome 3","class":"Lyph","external":["GO:0030424"],"color":"#e31a1c","border":"b_an_bd0-bd3_10","internalLyphColumns":1,"thickness":{},"length":{},"supertype":"229","inheritedExternal":["CL:0000540"],"conveys":"lnk-an_bd0-bd3_10","layers":["ref_mat_54_229_an_bd0-bd3_10_1","ref_mat_56_229_an_bd0-bd3_10_2","ref_mat_116_229_an_bd0-bd3_10_3"],"internalIn":"sn-blad-bd3_10","inCoalescences":[],"scale":{"width":40,"height":80},"hidden":true}
"ref_mat_KM_1_K99"
Property "internalIn" of the first resource (Lyph) should match the second resource:
{"id":"an-bd_4","name":"Axon through bladder dome_4","class":"Lyph","external":["GO:0030424"],"color":"#ffff99","border":"b_an-bd_4","internalLyphColumns":1,"thickness":{},"length":{},"supertype":"229","inheritedExternal":["CL:0000540"],"conveys":"lnk-an-bd_4","layers":["ref_mat_54_229_an-bd_4_1","ref_mat_56_229_an-bd_4_2","ref_mat_116_229_an-bd_4_3"],"internalIn":"sn-blad2_4","inCoalescences":[],"scale":{"width":40,"height":80},"hidden":true}
"ref_mat_KM_11_K99"
Property "internalIn" of the first resource (Lyph) should match the second resource:
{"id":"an-bn0tobn1_1","name":"Axon to PPOG neuron 1 in bladder neck layer 0","class":"Lyph","external":["GO:0030424"],"color":"#1f78b4","border":"b_an-bn0tobn1_1","internalLyphColumns":1,"thickness":{},"length":{},"supertype":"229","inheritedExternal":["CL:0000540"],"conveys":"lnk-an-bn0tobn1_1","layers":["ref_mat_54_229_an-bn0tobn1_1_1","ref_mat_56_229_an-bn0tobn1_1_2","ref_mat_116_229_an-bn0tobn1_1_3"],"internalIn":"sn-blad-bn_1","inCoalescences":[],"scale":{"width":40,"height":80},"hidden":true}
"ref_mat_KM_1_K100"
Property "internalIn" of the first resource (Lyph) should match the second resource:
{"id":"an_bn0-bv_10","name":"Axon to FOS neuron 10 bladder neck 0 to blood vessel","class":"Lyph","external":["GO:0030424"],"color":"#e7298a","border":"b_an_bn0-bv_10","internalLyphColumns":1,"thickness":{},"length":{},"supertype":"229","inheritedExternal":["CL:0000540"],"conveys":"lnk-an_bn0-bv_10","layers":["ref_mat_54_229_an_bn0-bv_10_1","ref_mat_56_229_an_bn0-bv_10_2","ref_mat_116_229_an_bn0-bv_10_3"],"internalIn":"sn-blad-bn_10","inCoalescences":[],"scale":{"width":40,"height":80},"hidden":true}
"ref_mat_KM_1_K100"
Property "internalIn" of the first resource (Lyph) should match the second resource:
{"id":"an-bn0forbn2_1","name":"Axon to PPOG neuron 1 in bladder neck layer 0 for layer 2","class":"Lyph","external":["GO:0030424"],"color":"#33a02c","border":"b_an-bn0forbn2_1","internalLyphColumns":1,"thickness":{},"length":{},"supertype":"229","inheritedExternal":["CL:0000540"],"conveys":"lnk-an-bn0forbn2_1","layers":["ref_mat_54_229_an-bn0forbn2_1_1","ref_mat_56_229_an-bn0forbn2_1_2","ref_mat_116_229_an-bn0forbn2_1_3"],"internalIn":"sn-blad-bn2_1","inCoalescences":[],"scale":{"width":40,"height":80},"hidden":true}
"ref_mat_KM_87_K100"
Property "internalIn" of the first resource (Lyph) should match the second resource:
{"id":"an-bn0_2","name":"Axon to SPOG neuron 2 in bladder neck layer 0","class":"Lyph","external":["GO:0030424"],"color":"#a6cee3","border":"b_an-bn0_2","internalLyphColumns":1,"thickness":{},"length":{},"supertype":"229","inheritedExternal":["CL:0000540"],"conveys":"lnk-an-bn0_2","layers":["ref_mat_54_229_an-bn0_2_1","ref_mat_56_229_an-bn0_2_2","ref_mat_116_229_an-bn0_2_3"],"internalIn":"sn-blad_2","inCoalescences":[],"scale":{"width":40,"height":80}}
"ref_mat_KM_87_K100"
Property "internalIn" of the first resource (Lyph) should match the second resource:
{"id":"an_bn0-bn1_10","name":"Axon to FOS neuron 10 bladder neck 0 to bladder neck 1","class":"Lyph","external":["GO:0030424"],"color":"#e6ab02","border":"b_an_bn0-bn1_10","internalLyphColumns":1,"thickness":{},"length":{},"supertype":"229","inheritedExternal":["CL:0000540"],"conveys":"lnk-an_bn0-bn1_10","layers":["ref_mat_54_229_an_bn0-bn1_10_1","ref_mat_56_229_an_bn0-bn1_10_2","ref_mat_116_229_an_bn0-bn1_10_3"],"internalIn":"sn-blad-bn2_10","inCoalescences":[],"scale":{"width":40,"height":80},"hidden":true}
"ref_mat_KM_87_K100"
Property "internalIn" of the first resource (Lyph) should match the second resource:
{"id":"an_bn0-bn3_10","name":"Axon to FOS neuron 10 bladder neck 0 to bladder neck 3","class":"Lyph","external":["GO:0030424"],"color":"#666666","border":"b_an_bn0-bn3_10","internalLyphColumns":1,"thickness":{},"length":{},"supertype":"229","inheritedExternal":["CL:0000540"],"conveys":"lnk-an_bn0-bn3_10","layers":["ref_mat_54_229_an_bn0-bn3_10_1","ref_mat_56_229_an_bn0-bn3_10_2","ref_mat_116_229_an_bn0-bn3_10_3"],"internalIn":"sn-blad-bn3_10","inCoalescences":[],"scale":{"width":40,"height":80},"hidden":true}
"ref_mat_KM_87_K100"
Property "internalIn" of the first resource (Lyph) should match the second resource:
{"id":"an-bn_4","name":"Axon through bladder neck_4","class":"Lyph","external":["GO:0030424"],"color":"#cab2d6","border":"b_an-bn_4","internalLyphColumns":1,"thickness":{},"length":{},"supertype":"229","inheritedExternal":["CL:0000540"],"conveys":"lnk-an-bn_4","layers":["ref_mat_54_229_an-bn_4_1","ref_mat_56_229_an-bn_4_2","ref_mat_116_229_an-bn_4_3"],"internalIn":"sn-blad_4","inCoalescences":[],"scale":{"width":40,"height":80},"hidden":true}
"ref_mat_KM_11_K100"
Property "internalIn" of the first resource (Lyph) should match the second resource:
{"id":"an-bn3-3_11","name":"Axon to bladder neck layer 3 for layer 1","class":"Lyph","external":["GO:0030424"],"color":"#a6cee3","border":"b_an-bn3-3_11","internalLyphColumns":1,"thickness":{},"length":{},"supertype":"229","inheritedExternal":["CL:0000540"],"conveys":"lnk-an-bn3-3_11","layers":["ref_mat_54_229_an-bn3-3_11_1","ref_mat_56_229_an-bn3-3_11_2","ref_mat_116_229_an-bn3-3_11_3"],"internalIn":"sn-blad-bn3_11","inCoalescences":[],"scale":{"width":40,"height":80},"hidden":true}
"ref_mat_KM_11_K100"
Property "fasciculatesIn" of the first resource (Link) should match the second resource:
{"id":"dn_drg-l6_10_lnk_1","class":"Link","generated":true,"color":"#000","source":"dn_drg-l6_10_node_0_join_0","target":"ns160_join_0","conveyingLyph":"dn_drg-l6_10_lyph_1","levelIn":"dn_drg-l6_10","fasciculatesIn":"ref_mat_KM_9_K_129_K27_1","length":64,"geometry":"link","lineWidth":"0.003","hidden":true}
"ref_mat_KM_9_K_129_K28_1"

anti-aliasing

When rendering wires for the scaffolds the aliasing of the borders/arcs/lines becomes quite apparent. It would be nice to have those anti-aliased.

in chains with a single explicit root or leaf that node should be a root

While working out the issues with connectivity queries today we ran into a major point of confusion that should not be allowed to happen. All the dendrite chains had been specified as being "leafed" that is, they had a leaf but no root. For sake of sanity chains with only a single explicit root/leaf should have that be the root. This helps with the follow-your-nose approach to exploring apinatomy models and provides unambiguous behavior when only a single named (not generated) node is associated with a chain. Otherwise you have to query all chains in both directions.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.