Skip to content

Instantly share code, notes, and snippets.

@NicoKiaru
Last active January 11, 2024 13:37
Show Gist options
  • Save NicoKiaru/f45f56e3ff2d1fb708821c110fbdee62 to your computer and use it in GitHub Desktop.
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
/**
* 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
@NicoKiaru
Copy link
Author

Thanks a lot @AthiemoneZero , I'll update my script based on your modifications, indeed some parts are not up to date

@522848942
Copy link

image
here is a bug, how can I solve it ?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment