Last active
January 11, 2024 13:37
-
-
Save NicoKiaru/f45f56e3ff2d1fb708821c110fbdee62 to your computer and use it in GitHub Desktop.
Performs cell detection in QuPath from an ABBA registered project with imported regions #BIOP #ABBA #QuPath
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** | |
* ABBA Script : performs a cell detection on the root node annotation | |
* imported from ABBA and restores the child objects after the detection has been performed | |
* To use and modify like you need / want | |
* You need to have imported the regions before running this script. See https://gist.github.com/NicoKiaru/723d8e628a3bb03902bb3f0f2f0fa466 for instance | |
* See https://biop.github.io/ijp-imagetoatlas/ | |
* Author: Olivier Burri, Nicolas Chiaruttini, BIOP, EPFL | |
* Date: 2022-01-26 | |
*/ | |
// setImageType('FLUORESCENCE'); // if your image is fluorescent | |
// If you just want to clear the detections and keep the previously ABBA imported annotations | |
clearDetections() | |
// or, if you want to reset and re-import all annotations from ABBA | |
// clearAllObjects(); | |
// qupath.ext.biop.abba.AtlasTools.loadWarpedAtlasAnnotations(getCurrentImageData(), "acronym", true); | |
def project = getProject() | |
// We want to run cell detection only once on the entire brain, which means we need to select the Root node. We can find it by name | |
def root = getAnnotationObjects().find{ it.getName().equals( 'Root' ) } | |
// Duplicate root node. It is a bit contrived but this is how you can copy an annotation | |
def regionMeasured = PathObjectTools.transformObject( root, null, true ) | |
// Temporary name | |
regionMeasured.setName( "Measured Region" ) | |
// Need to add it to the current hierarchy | |
addObject( regionMeasured ) | |
// So that we can select it | |
setSelectedObject( regionMeasured ) | |
// RUN CELL DETECTION | |
// Modify the line below by inserting your cell detection plugin line | |
// ********************************************************************* | |
// ********************************************************************* | |
runPlugin( 'qupath.imagej.detect.cells.WatershedCellDetection', | |
'{"detectionImage": "FL CY3", "requestedPixelSizeMicrons": 2.0, "backgroundRadiusMicrons": 8.0, "medianRadiusMicrons": 0.0, "sigmaMicrons": 2.0, "minAreaMicrons": 20.0, "maxAreaMicrons": 400.0, "threshold": 200.0, "watershedPostProcess": true, "cellExpansionMicrons": 0.0, "includeNuclei": true, "smoothBoundaries": true, "makeMeasurements": true}') | |
// ********************************************************************* | |
// ********************************************************************* | |
// We no longer need the object we used for detection. We remove it but keep the child objects, which are the cells | |
removeObject( regionMeasured, true ) | |
// We can now add the cells to the original root object | |
def cells = getDetectionObjects() | |
root.addPathObjects( cells ) | |
// Update the view for the user | |
fireHierarchyUpdate() | |
// From here, the rest of the script adds to all cells their coordinates in the reference atlas | |
// to their measurement list | |
// Get ABBA transform file located in entry path | |
def targetEntry = getProjectEntry() | |
def targetEntryPath = targetEntry.getEntryPath() | |
def fTransform = new File(targetEntryPath.toFile(), "ABBA-Transform-Adult Mouse Brain - Allen Brain Atlas V3p1.json" ) | |
if ( !fTransform.exists() ) { | |
logger.error( "ABBA transformation file not found for entry {}", targetEntry ) | |
return | |
} | |
def pixelToCCFTransform = Warpy.getRealTransform( fTransform ).inverse() // Needs the inverse transform | |
getDetectionObjects().forEach{ detection -> | |
def ccfCoordinates = new RealPoint(3) | |
def ml = detection.getMeasurementList() | |
ccfCoordinates.setPosition( [detection.getROI().getCentroidX(),detection.getROI().getCentroidY(), 0] as double[] ) | |
// The Z=0 pixel coordinate is automatically transformed to the right atlas position in Z thanks to the fact that the slice | |
// position is already known by the transform | |
// This applies the transform in place to cffCoordinates | |
pixelToCCFTransform.apply(ccfCoordinates, ccfCoordinates) | |
// Fianlly: Add the coordinates as measurements | |
ml.addMeasurement("Allen CCFv3 X mm", ccfCoordinates.getDoublePosition(0) ) | |
ml.addMeasurement("Allen CCFv3 Y mm", ccfCoordinates.getDoublePosition(1) ) | |
ml.addMeasurement("Allen CCFv3 Z mm", ccfCoordinates.getDoublePosition(2) ) | |
ml.addMeasurement("Count: Num Spots", 1 ) | |
} | |
// imports | |
import qupath.ext.biop.warpy.* | |
import net.imglib2.RealPoint | |
import qupath.lib.measurements.MeasurementList | |
import qupath.lib.objects.PathObjectTools | |
import qupath.lib.objects.PathObjects | |
import qupath.lib.objects.PathCellObject | |
import qupath.lib.objects.PathObject | |
import qupath.lib.objects.PathDetectionObject | |
import qupath.lib.roi.ROIs | |
import qupath.lib.regions.ImagePlane |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
here is a bug, how can I solve it ?