Skip to content

Commit

Permalink
Merge pull request #48 from morphonets/47-allen-fixes
Browse files Browse the repository at this point in the history
Resolve #47
  • Loading branch information
tferr authored Feb 5, 2021
2 parents 3274c52 + ba515ce commit 48bf974
Show file tree
Hide file tree
Showing 4 changed files with 396 additions and 53 deletions.
26 changes: 11 additions & 15 deletions src/main/java/sc/fiji/snt/annotation/AllenCompartment.java
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,7 @@
* are called.
*
* @author Tiago Ferreira
* @author Cameron Arshadi
*
*/
public class AllenCompartment implements BrainAnnotation {
Expand All @@ -61,6 +62,8 @@ public class AllenCompartment implements BrainAnnotation {
private int structureId;
private UUID uuid;
private JSONObject jsonObj;
// Only access parentStructure via a call to getTreePath()
// This will ensure that parentStructure has been initialized
private ArrayList<AllenCompartment> parentStructure;

/**
Expand Down Expand Up @@ -124,7 +127,6 @@ private String[] getArray(final JSONArray jArray) {
}

protected int depth() {
//initializeAsNeeded();
return jsonObj.getInt("depth");
}

Expand All @@ -133,7 +135,6 @@ protected int graphOrder() {
}

protected String getStructureIdPath() {
//initializeAsNeeded();
return jsonObj.optString("structureIdPath");
}

Expand All @@ -151,7 +152,7 @@ protected int getParentStructureId() {
*/
@Override
public boolean isChildOf(final BrainAnnotation childCompartment) {
if (childCompartment == null || !(childCompartment instanceof AllenCompartment))
if (!(childCompartment instanceof AllenCompartment))
return false;
final AllenCompartment cCompartment = (AllenCompartment) childCompartment;
return id() != cCompartment.id() && getStructureIdPath().contains(String.valueOf(cCompartment.id()));
Expand Down Expand Up @@ -197,8 +198,8 @@ public int getOntologyDepth() {
*/
public AllenCompartment getParent() {
if (getTreePath().size() < 2) return null;
final int lastIdx = Math.max(0, parentStructure.size() - 2);
return parentStructure.get(lastIdx);
final int lastIdx = Math.max(0, getTreePath().size() - 2);
return getTreePath().get(lastIdx);
}

/**
Expand All @@ -209,7 +210,7 @@ public AllenCompartment getParent() {
* @see #getTreePath()
*/
public List<AllenCompartment> getAncestors() {
return parentStructure.subList(0, parentStructure.size()-1);
return getTreePath().subList(0, getTreePath().size()-1);
}

/**
Expand All @@ -226,9 +227,9 @@ public AllenCompartment getAncestor(final int level) {
if (level == 0) return getParent();
int normLevel = (level > 0) ? -level : level;
final int idx = getTreePath().size() - 1 + normLevel;
if (idx < 0 || idx >= parentStructure.size() - 1)
if (idx < 0 || idx >= getTreePath().size() - 1)
throw new IllegalArgumentException ("Ancestor level out of range. Compartment has "+ getOntologyDepth() + " ancestors.");
return parentStructure.get(idx);
return getTreePath().get(idx);
}

/**
Expand Down Expand Up @@ -258,33 +259,29 @@ public List<AllenCompartment> getChildren(final int level) {
final ArrayList<AllenCompartment> children = new ArrayList<>();
final Collection<AllenCompartment> allCompartments = AllenUtils.getOntologies();
for (AllenCompartment c : allCompartments) {
if (isChildOf(c) && c.getTreePath().size() <= maxLevel)
if (c.isChildOf(this) && c.getTreePath().size() <= maxLevel)
children.add(c);
}
return children;
}

@Override
public int id() {
//initializeAsNeeded();
return structureId;
}

@Override
public String name() {
//initializeAsNeeded();
return name;
}

@Override
public String acronym() {
//initializeAsNeeded();
return acronym;
}

@Override
public String[] aliases() {
//initializeAsNeeded();
aliases = getArray(jsonObj.getJSONArray("aliases"));
return aliases;
}
Expand All @@ -295,7 +292,6 @@ public String[] aliases() {
* @return true, if a mesh is available.
*/
public boolean isMeshAvailable() {
//initializeAsNeeded();
return jsonObj.getBoolean("geometryEnable");
}

Expand Down Expand Up @@ -340,7 +336,7 @@ public OBJMesh getMesh() {
*/
@Override
public boolean isParentOf(final BrainAnnotation childCompartment) {
if (childCompartment == null || !(childCompartment instanceof AllenCompartment))
if (!(childCompartment instanceof AllenCompartment))
return false;
final AllenCompartment cCompartment = (AllenCompartment) childCompartment;
return id() != cCompartment.id() && cCompartment.getStructureIdPath().contains(String.valueOf(id()));
Expand Down
68 changes: 30 additions & 38 deletions src/main/java/sc/fiji/snt/annotation/AllenUtils.java
Original file line number Diff line number Diff line change
Expand Up @@ -21,30 +21,10 @@
*/
package sc.fiji.snt.annotation;

import java.io.IOException;
import java.io.InputStream;
import java.net.URL;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.TreeSet;
import java.util.UUID;

import javax.swing.tree.DefaultMutableTreeNode;
import javax.swing.tree.DefaultTreeModel;
import javax.swing.tree.TreeNode;

import org.json.JSONArray;
import org.json.JSONObject;
import org.json.JSONTokener;
import org.scijava.util.ColorRGB;

import sc.fiji.snt.Path;
import sc.fiji.snt.Tree;
import sc.fiji.snt.analysis.graph.DirectedWeightedGraph;
Expand All @@ -53,10 +33,19 @@
import sc.fiji.snt.util.SNTPoint;
import sc.fiji.snt.viewer.OBJMesh;

import javax.swing.tree.DefaultMutableTreeNode;
import javax.swing.tree.DefaultTreeModel;
import javax.swing.tree.TreeNode;
import java.io.IOException;
import java.io.InputStream;
import java.net.URL;
import java.util.*;

/**
* Utility methods for accessing/handling {@link AllenCompartment}s
*
* @author Tiago Ferreira
* @author Cameron Arshadi
*/
public class AllenUtils {

Expand Down Expand Up @@ -168,8 +157,8 @@ private static double[] pointsToVec(double[] p, double[] q) {
}

private static double[] crossProduct(double[] a, double[] b) {
if (a.length != b.length || a.length != 3 || b.length != 3) {
throw new IllegalArgumentException("Vectors a and b are not of equal length or are not 3-dimensional");
if (a.length != 3 || b.length != 3) {
throw new IllegalArgumentException("Vectors a and b must be 3-dimensional");
}
double[] c = new double[3];
c[0] = a[1] * b[2] - a[2] * b[1];
Expand Down Expand Up @@ -197,7 +186,7 @@ private static double[] normalizeVec(double[] v) {
double norm = euclideanNorm(v);
double[] normalized = new double[v.length];
for (int i = 0; i < v.length; i++) {
normalized[i] = (double) v[i] / norm;
normalized[i] = v[i] / norm;
}
return normalized;
}
Expand All @@ -220,11 +209,10 @@ private static double[][] reflectionMatrix(double[] planePoint, double[] planeNo
double d = -1 * a * planePoint[0] - b * planePoint[1] - c * planePoint[2];
// We need to use an affine transformation instead of linear
// since the plane of reflection does not go through the origin.
double[][] A = { { 1-2*a*a, -2*a*b, -2*a*c, -2*a*d },
return new double[][]{ { 1-2*a*a, -2*a*b, -2*a*c, -2*a*d },
{ -2*a*b, 1-2*b*b, -2*b*c, -2*b*d },
{ -2*a*c, -2*b*c, 1-2*c*c, -2*c*d },
{ -2*a*c, -2*b*c, 1-2*c*c, -2*c*d },
{ 0, 0, 0, 1 } };
return A;
}

/**
Expand Down Expand Up @@ -275,25 +263,28 @@ public static boolean isLeftHemisphere(final Tree tree) {
}

public static void assignHemisphereTags(final DirectedWeightedGraph graph) {
graph.vertexSet().forEach(node -> {
node.setHemisphere(isLeftHemisphere(node) ? BrainAnnotation.LEFT_HEMISPHERE : BrainAnnotation.RIGHT_HEMISPHERE);
});
graph.vertexSet().forEach(node ->
node.setHemisphere(
isLeftHemisphere(node) ? BrainAnnotation.LEFT_HEMISPHERE : BrainAnnotation.RIGHT_HEMISPHERE
));
}

/**
* Gets the axis defining mid sagittal plane.
*
* @return the axis defining mid sagittal plane where X=0; Y=1; Z=2;
*/
@SuppressWarnings("SameReturnValue")
public static int getAxisDefiningMidSagittalPlane() {
return 0;
}

public static void assignHemisphereTags(final Tree tree) {
//TODO: Currently we have to tag both the tree nodes and graph vertices. This needs to be simplified!
tree.getNodes().forEach(node -> {
node.setHemisphere(isLeftHemisphere(node) ? BrainAnnotation.LEFT_HEMISPHERE : BrainAnnotation.RIGHT_HEMISPHERE);
});
tree.getNodes().forEach(node ->
node.setHemisphere(
isLeftHemisphere(node) ? BrainAnnotation.LEFT_HEMISPHERE : BrainAnnotation.RIGHT_HEMISPHERE
));
assignHemisphereTags(tree.getGraph());
}

Expand Down Expand Up @@ -334,6 +325,7 @@ public static SNTPoint brainCenter() {
*
* @return the max number of ontology levels.
*/
@SuppressWarnings("SameReturnValue")
public static int getHighestOntologyDepth() {
// No need to compute, as this is unlikely to change
return 10; // computeHighestOntologyDepth();
Expand Down Expand Up @@ -364,7 +356,7 @@ public static DefaultTreeModel getTreeModel(final boolean meshesOnly) {
*
* @return the "flattened" ontologies list
*/
public static Collection<AllenCompartment> getOntologies() {
public static List<AllenCompartment> getOntologies() {
return new AllenTreeModel().getOntologies();
}

Expand All @@ -380,12 +372,11 @@ private AllenTreeModel() {

private AllenCompartment getAreaListCompartment(final int idx) {
final JSONObject area = (JSONObject) areaList.get(idx);
final AllenCompartment ac = new AllenCompartment(UUID.fromString(area.getString("id")));
return ac;
return new AllenCompartment(UUID.fromString(area.getString("id")));
}

private Collection<AllenCompartment> getOntologies() {
final Collection<AllenCompartment> list = new ArrayList<>(areaList.length());
private List<AllenCompartment> getOntologies() {
final List<AllenCompartment> list = new ArrayList<>(areaList.length());
for (int n = 0; n < areaList.length(); n++) {
list.add(getAreaListCompartment(n));
}
Expand All @@ -394,7 +385,7 @@ private Collection<AllenCompartment> getOntologies() {

private DefaultTreeModel getTreeModel(final boolean meshesOnly) {
final TreeSet<AllenCompartment> all = new TreeSet<>(
(ac1, ac2) -> ac1.getStructureIdPath().compareTo(ac2.getStructureIdPath()));
Comparator.comparing(AllenCompartment::getStructureIdPath));
final Map<Integer, AllenCompartment> idsMap = new HashMap<>();
final Set<Integer> visitedIds = new HashSet<>();
root = new DefaultMutableTreeNode();
Expand Down Expand Up @@ -464,6 +455,7 @@ public static OBJMesh getRootMesh(final ColorRGB color) {
throw new IllegalArgumentException(meshLabel + " not found");
final OBJMesh mesh = new OBJMesh(url, "um");
mesh.setColor(color, 95f);
mesh.setVolume(513578693035.138d); // pre-computed surface integral
mesh.setLabel(meshLabel);
return mesh;
}
Expand Down
Loading

0 comments on commit 48bf974

Please sign in to comment.