selectObjects { p -> p.getPathClass() == getPathClass("Stroma") && p.isAnnotation() }for (cell in getSelectedObject().getChildObjects())
cell.setPathClass(cell.getParent().getPathClass())
fireHierarchyUpdate()
double val = pathObject.getMeasurementList().getMeasurementValue(feature)
// Set positive or negative class
if (val < threshold || val > threshold2){
pathObject.setPathClass(Positive)
}else pathObject.setPathClass(Negative)
selectObjects { p -> p.getParent().getPathClass() == getPathClass("Stroma") && p.isDetection() }
for (cell in getSelectedObject().getChildObjects())
cell.setPathClass(cell.getParent().getPathClass())
fireHierarchyUpdate();
I end up with violet cells again.
Do I need to adapt it to my case?
I also get a Error list:
INFO: Starting script at Thu Nov 02 23:52:44 GMT+01:00 2017
ERROR: Error at line 1: Cannot invoke method getChildObjects() on null object
ERROR: Script error
at org.codehaus.groovy.runtime.NullObject.invokeMethod(NullObject.java:91)
at org.codehaus.groovy.runtime.callsite.PogoMetaClassSite.call(PogoMetaClassSite.java:48)
at org.codehaus.groovy.runtime.callsite.CallSiteArray.defaultCall(CallSiteArray.java:48)
at org.codehaus.groovy.runtime.callsite.NullCallSite.call(NullCallSite.java:35)
at org.codehaus.groovy.runtime.callsite.CallSiteArray.defaultCall(CallSiteArray.java:48)
at org.codehaus.groovy.runtime.callsite.AbstractCallSite.call(AbstractCallSite.java:113)
at org.codehaus.groovy.runtime.callsite.AbstractCallSite.call(AbstractCallSite.java:117)
at Script16.run(Script16.groovy:2)
at org.codehaus.groovy.jsr223.GroovyScriptEngineImpl.eval(GroovyScriptEngineImpl.java:343)
at org.codehaus.groovy.jsr223.GroovyScriptEngineImpl.eval(GroovyScriptEngineImpl.java:152)
at qupath.lib.scripting.DefaultScriptEditor.executeScript(DefaultScriptEditor.java:765)
at qupath.lib.scripting.DefaultScriptEditor.executeScript(DefaultScriptEditor.java:695)
at qupath.lib.scripting.DefaultScriptEditor.executeScript(DefaultScriptEditor.java:677)
at qupath.lib.scripting.DefaultScriptEditor.access$400(DefaultScriptEditor.java:136)
at qupath.lib.scripting.DefaultScriptEditor$2.run(DefaultScriptEditor.java:1029)
at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:511)
at java.util.concurrent.FutureTask.run(FutureTask.java:266)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
at java.lang.Thread.run(Thread.java:745)
import static qupath.lib.classifiers.PathClassifierTools.*
import qupath.lib.objects.PathDetectionObject
// Load two detection classifiers
c1 = loadClassifier(new File('/path/to/classifier1.qpclassifier'))
c2 = loadClassifier(new File('/path/to/classifier2.qpclassifier'))
// Find annotations (could use a predicate)
annotations = getAnnotationObjects()
// Apply first classifier to all detections inside the first annotation
hierarchy = getCurrentHierarchy()
cells1 = hierarchy.getDescendantObjects(annotations[0], null, PathDetectionObject)
c1.classifyPathObjects(cells1)
// Apply the second classifier to all detections inside the second annotation
cells2 = hierarchy.getDescendantObjects(annotations[1], null, PathDetectionObject)
c2.classifyPathObjects(cells2)
// Set classification for all objects in the third annotation
cells3 = hierarchy.getDescendantObjects(annotations[2], null, PathDetectionObject)
cells3.each {it.setPathClass(getPathClass('Something else'))}
fireHierarchyUpdate()for (cell in getSelectedObject().getChildObjects())
cell.setPathClass(cell.getParent().getPathClass())
fireHierarchyUpdate();
This script was just a
demonstration of how to run a for loop on the cells within a specific
annotation object class. The actual function of it is to set all of the
cells within the object to the class of the parent object, which is not what
you want. You need to replace
cell.setPathClass(cell.getParent().getPathClass())
with
whatever code you want to run on each cell.
On the
upside, Pete's post just showed how to do what I was not sure how to do!
I am still
trying to figure out how to get Pete's script to work with multiple annotations
of a particular class, but am getting an error where cells1 is null, despite it
containing many polygon objects.
println(cells1)
results in
INFO: [Polygon, Polygon, Polygon, Polygon, Polygon, etc etc.
and the
error:
ERROR:
Error at line 18: Cannot invoke method classifyPathObjects() on null object
I will
update if I can figure it out!
Sample
code modification: (attempting to use annotations directly in
ClassifyPathObjects fails, I think because it only expects a single
pathObject. I hoped I could iterate)
import static qupath.lib.classifiers.PathClassifierTools.*
import qupath.lib.objects.PathDetectionObject
// Load
classifier
c1 = loadClassifier(new File('C:\\Users\\Svidro\\Desktop\\Endometrium
project\\classifiers'))
hierarchy = getCurrentHierarchy();
selectObjects
{ p -> p.getPathClass() == getPathClass("Stroma") };
annotations
= hierarchy.getSelectionModel().getSelectedObjects()
println(annotations)
cells = []
// Apply
classifier to all detections inside annotations
for (annotation in annotations){
cells.addAll(hierarchy.getDescendantObjects(annotation, null, PathDetectionObject));
}
println(cells)
c1.classifyPathObjects(cells);
fireHierarchyUpdate();
println("Done");
import static qupath.lib.classifiers.PathClassifierTools.*
import qupath.lib.objects.PathDetectionObject
// Load detection classifier, make sure to use the full path and file name! The following is written for a Windows based system
c1 = loadClassifier(new File('C:\\File Path\\test.qpclassifier'))
// Select the annotations that you want to classify the cells from, based on their class. In this case all "Stroma" annotations
selectObjects { p -> p.getPathClass() == getPathClass("Stroma") };
//Store the annotations in "annotations" and create an empty array where you can keep the list of cells you want to classify.
hierarchy = getCurrentHierarchy();
annotations = hierarchy.getSelectionModel().getSelectedObjects()
cells = []
//Iterate over all annotations and keep track of the cells within them in the "cells" list
for (annotation in annotations){
cells.addAll(hierarchy.getDescendantObjects(annotation, null, PathDetectionObject));
}
// Apply classifier to all detections inside the selected annotationsc1 = loadClassifier(new File('C:\\File Path\\test.qpclassifier'))c1 = loadClassifier('C:\\File Path\\test.qpclassifier')import static qupath.lib.classifiers.PathClassifierTools.*fireHierarchyUpdate()def annotations = getAnnotationObjects()
def rim = annotations.findAll {it.getPathClass() == getPathClass("RIM") }
rim.each {
cells = hierarchy.getDescendantObjects(it, null, PathDetectionObject)
c1.classifyPathObjects(cells)
}
def tissue = annotations.findAll {it.getPathClass() == getPathClass("Tissue") }
tissue.each {
cells = hierarchy.getDescendantObjects(it, null, PathDetectionObject)
c2.classifyPathObjects(cells)
}
fireHierarchyUpdate()
hierarchy = getCurrentHierarchy();
line.
Also, if you want to make the code easier to read, you can use the curly brackets button at the end of the Google group forum bar {} with your code selected!