Skip to content

Commit

Permalink
Merge pull request #5 from Naveiras-Lab/update-qp0.5.1
Browse files Browse the repository at this point in the history
Update qp0.5.1
  • Loading branch information
lacan authored Apr 19, 2024
2 parents be6dfe9 + 31e2c33 commit cd723cf
Show file tree
Hide file tree
Showing 13 changed files with 77 additions and 172 deletions.
87 changes: 53 additions & 34 deletions Code/AdipoQuant.groovy
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,7 @@ mq_classes.each { the_class ->
}
}

getQuPath().getAvailablePathClasses().setAll(all_classes)
Platform.runLater{ getQuPath().getAvailablePathClasses().setAll(all_classes) }
fireHierarchyUpdate()

def ij = IJExtension.getImageJInstance()
Expand All @@ -105,7 +105,7 @@ tissues.eachWithIndex{ tissue, i ->
}

fireHierarchyUpdate()
def imageName = getCurrentImageData().getServer().getShortServerName()
def imageName = getCurrentImageNameWithoutExtension()
println("Processing complete for " + imageName );
//ij.quit()

Expand All @@ -121,8 +121,11 @@ class AdipocyteDetector {
IJ.run("Close All")

// Returns the image as an ImageJ ImagePlus object with ROIs and the overlay
def image = GUIUtils.getImagePlus(tissue, this.downsample, true, true)

def request = RegionRequest.createInstance( getCurrentServerPath(), this.downsample, tissue.getROI() )
def pathImage = IJExtension.extractROIWithOverlay(getCurrentServer(), tissue, getCurrentHierarchy(), request, true, getCurrentViewer().getOverlayOptions());

def image = pathImage.getImage()

// Pick up pixel size
def px_size = image.getCalibration().pixelWidth

Expand All @@ -146,24 +149,17 @@ class AdipocyteDetector {
IJ.run(hsb_image, "HSB Stack", "")
hsb_image.show()

// Call Color Deconvolution and recover the images (must be done through GUI for now)
IJ.run(image, "Colour Deconvolution", "vectors=H&E hide")

//Pickup the images for later processing
def col1 = WindowManager.getImage( image.getTitle()+"-(Colour_1)" )
def col2 = WindowManager.getImage( image.getTitle()+"-(Colour_2)" )
def col3 = WindowManager.getImage( image.getTitle()+"-(Colour_3)" )

// Call Color Deconvolution and recover the images )
def cols = colorDeconvolution( image, "H&E" )

// Creates the final image we are going to process from the hue and brightness image obtained
def ic = new ImageCalculator()
def adip_raw_image = ic.run("Subtract create", col3, col1)
def adip_raw_image = ic.run("Subtract create", cols[2], cols[0])

adip_raw_image.show()

image.close()
col1.close()
col2.close()
col3.close()
cols.each{ it.close() }

def saturation = hsb_image.getStack().getProcessor(2) // Saturation is the second image
saturation.multiply(8)
Expand All @@ -181,8 +177,11 @@ class AdipocyteDetector {
IJ.run( adip_mask, "Invert", "") // IB?
IJ.run( adip_mask, "Watershed", "" )
adip_mask.show()


IJ.run( adip_mask, "Options...", "iterations=50 count=5 pad do=Erode" )


adip_mask.setRoi( all_edges )
//IJ.run(adip_mask, "Make Inverse", "")
IJ.setRawThreshold(adip_mask, 0, 127, null)
Expand All @@ -192,25 +191,29 @@ class AdipocyteDetector {
def rm = RoiManager.getInstance() ?: new RoiManager()
// Save as Detections in QuPath
def adips = rm.getRoisAsArray() as List
rm.runCommand("Reset")
rm.reset()
rm.close()

def um = GeneralTools.micrometerSymbol()

def total_area = 0

// Measurement of adipocytes areas and displaying of the data in QuPath
adips.eachWithIndex{ adip, idx ->
def qu_adip = ROIConverterIJ.convertToPathROI( adip, image.getCalibration(), this.downsample, 0,0,0)
def det = new PathDetectionObject(qu_adip, getPathClass("Adipocyte"))
def det = IJTools.convertToDetection( adip, this.downsample, image )
det.setPathClass( getPathClass("Adipocyte") )
def area = adip.getStatistics().area
det.getMeasurementList().putMeasurement( "Adipocyte Index", idx+1 )
det.getMeasurementList().putMeasurement( "Area "+Utils.um+"^2", area * px_size * px_size )
det.getMeasurementList().putMeasurement( "Area "+um+"^2", area * px_size * px_size )

tissue.addPathObject(det)
tissue.addChildObject(det)
total_area += area
}

tissue.getMeasurementList().clear();
tissue.getMeasurementList().putMeasurement( "Total Adipocyte Area "+Utils.um+"^2", total_area * px_size * px_size )
tissue.getMeasurementList().clear()
tissue.getMeasurementList().putMeasurement( "Total Adipocyte Area "+um+"^2", total_area * px_size * px_size )
Interpreter.batchMode = false
fireHierarchyUpdate()
}

// Excludes the artifacts from the ROI we want to process
Expand All @@ -219,20 +222,20 @@ class AdipocyteDetector {
return tissue_roi
}

if (artifacts.size > 0) {
if (artifacts.size() > 0) {

def rm = RoiManager.getInstance() ?: new RoiManager()
rm.runCommand("Reset")
rm.reset()
artifacts.each{ rm.addRoi(it) }
def all_artifacts
if ( artifacts.size == 1 ) {
if ( artifacts.size() == 1 ) {
all_artifacts = artifacts[0]
} else {
rm.setSelectedIndexes((0..rm.getCount()-1) as int[])
rm.runCommand(image, "OR")
all_artifacts = image.getRoi()
}
rm.runCommand("Reset")
rm.reset()
// AND then XOR with tissue
IJ.log(""+all_artifacts)
rm.addRoi(all_artifacts)
Expand All @@ -243,13 +246,32 @@ class AdipocyteDetector {
rm.addRoi( overlap_artifacts )
rm.setSelectedIndexes([1,2] as int[])
rm.runCommand(image, "XOR")
rm.reset()
rm.close()
return image.getRoi()
}
}

// Use Color Deconvolution Plugin in MarrowQuant
public ImagePlus[] colorDeconvolution ( ImagePlus image, String stain ) {
def cd = new Colour_Deconvolution()
def matList = cd.getStainList()
def mt = matList.get( stain )
def stackList = mt.compute( false, true, image )
// This returns an array of ImageStacks

// Make into an ImagePlus
def imageStack = new ImageStack( stackList[0].getWidth(), stackList[0].getHeight() )

stackList.each { imageStack.addSlice( it.getProcessor( 1 ) ) }

def deconvolved = stackList.collect{ new ImagePlus( image.getTitle()+"-"+stain, it ) }

return deconvolved
}
}
// Import BIOP library to do fun things
import ch.epfl.biop.qupath.utils.*


import ij.IJ
import sc.fiji.colourDeconvolution.*
import ij.WindowManager
Expand All @@ -258,18 +280,15 @@ import ij.ImagePlus
import ij.process.ImageProcessor
import ij.plugin.frame.RoiManager
import qupath.lib.objects.PathDetectionObject
import qupath.imagej.objects.ROIConverterIJ
import ij.macro.Interpreter
import ch.epfl.biop.qupath.utils.Utils
import ij.ImageStack
import ij.gui.Roi
import qupath.imagej.gui.IJExtension
import qupath.lib.gui.helpers.DisplayHelpers

import qupath.imagej.helpers.*
import qupath.lib.roi.PathObjectToolsAwt
import qupath.lib.objects.PathAnnotationObject






Original file line number Diff line number Diff line change
Expand Up @@ -9,13 +9,14 @@



import ch.epfl.biop.qupath.utils.*
import qupath.ext.biop.utils.Results


selectDetections();
runPlugin('qupath.lib.plugins.objects.ShapeFeaturesPlugin', '{"area": false, "perimeter": true, "circularity": true, "useMicrons": true}');

def um = Utils.um
def um = GeneralTools.micrometerSymbol()

def columns = ["Adipocyte Index", "Parent", "Area "+um+"^2"]

def resultsfolder = buildFilePath(PROJECT_BASE_DIR, "results")
Expand All @@ -25,6 +26,6 @@ def resultsfile = new File(resultsfolder, "adipocyte-measurements.txt")
println(resultsfile.getAbsolutePath())

def detections = getDetectionObjects()
Utils.sendResultsToFile(columns, detections, resultsfile)
Results.sendResultsToFile(columns, detections, resultsfile)

println("Completed")
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ def outputPath = buildFilePath( PROJECT_BASE_DIR, 'results' )
mkdirs( outputPath )

// Give the results file a name
def fileName = 'MarrowQuant_Results.txt'
def fileName = 'MarrowQuant_Results_20230721_final.txt'

// Write results in the desired directory to the desired filename
def file = new File( outputPath, fileName )
Expand All @@ -54,12 +54,12 @@ def columns = [ "Image Name",
"Tt.Ad.Ar_"+U+"^2",
"It.Ar_"+U+"^2",
"Ma.Ar_"+U+"^2",
"Other.Ar_"+U+"^2",
"Un.Ar_"+U+"^2",
"Hm.Ar/(Hm.Ar+Tt.Ad.Ar)_%_Equation_1",
"Hm.Ar/Ma.Ar_%_Equation_2",
"Tt.Ad.Ar/Ma.Ar_%",
"It.Ar/Ma.Ar_%",
"Other.Ar/Ma.Ar_%",
"Un.Ar/Ma.Ar_%",
"Aj.Ad.N",
"Ad_Min_Size",
"Ad_Max_Size",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -83,9 +83,9 @@ ij.quit()

// end of script//

// MarrowQnat class starts below
// MarrowQuat class starts below
@ToString(includeNames=true)
class MarrowQuant {
class MarrowQuant1 {

def downsample = 4
def adipMin = 5
Expand Down Expand Up @@ -120,7 +120,7 @@ class MarrowQuant {
def boneMaskImage
def hematoMaskImage

final private static Logger logger = LoggerFactory.getLogger( MarrowQuant.class )
final private static Logger logger = LoggerFactory.getLogger( MarrowQuant1.class )

public void run() {
def all_annotations = getAnnotationObjects()
Expand All @@ -144,7 +144,14 @@ class MarrowQuant {
//tissueAnnotation.getChildObjects().find{ it.getPathClass() == getPathClass("BG") }
def tissue_artifacts = tissueAnnotation.getChildObjects().findAll{ it.getPathClass() == getPathClass("Artifact") }

def mergedArtifactsAnnotation = PathUtils.merge( tissue_artifacts )
// Merge artifacts for later use
def hasMerged = mergeAnnotations( tissue_artifacts )
def mergedArtifactsAnnotation
if( hasMerged ) {
mergedArtifactsAnnotation = getSelectedObject()
} else {
mergedArtifactsAnnotation = tissue_artifacts[0]
}

this.image = getImagePlus( tissueAnnotation, downsample)

Expand Down Expand Up @@ -515,6 +522,7 @@ class MarrowQuant {
}
measurements.putMeasurement( "Aj.Ad.N", rois.size() )
measurements.putMeasurement("Ad.MA.Ar_Nby_"+U+"^2", rois.size()/ round( ( area_hemato + area_adips + area_imv ) * px_size * px_size ,0 ) )
rm.reset()
rm.close()
}

Expand Down Expand Up @@ -670,7 +678,7 @@ class MarrowQuant {
}

// The lines below allow us to user the Builder Pattern withourh having to declare it in the MarrowQuant class
@Builder(builderStrategy = ExternalStrategy, forClass = MarrowQuant, prefix = 'assign', buildMethodName = 'create')
@Builder(builderStrategy = ExternalStrategy, forClass = MarrowQuant1, prefix = 'assign', buildMethodName = 'create')
class MQBuilder {
MQBuilder() {
downsample = 4
Expand Down
24 changes: 4 additions & 20 deletions Code/Remove_Overview_And_Label_Images.groovy
Original file line number Diff line number Diff line change
Expand Up @@ -7,21 +7,10 @@
* but otherwise everything kept the same.
*/

import qupath.lib.gui.QuPathGUI
import qupath.lib.gui.panels.ProjectBrowser
import qupath.lib.images.ImageData
import qupath.lib.images.servers.ImageServerProvider
import qupath.lib.io.PathIO
import qupath.lib.projects.Project
import qupath.lib.projects.ProjectIO

import java.awt.image.BufferedImage

// Get the running QuPath instance
def qupath = QuPathGUI.getInstance()

def qupath = getQuPath()
// Get the current project
def project = qupath.getProject()
def project = getProject()
if (project == null) {
println("No project open!")
return
Expand All @@ -36,11 +25,6 @@ for (def entry in project.getImageList()) {
}

sleep(1000)
getQuPath().refreshProject()
ProjectIO.writeProject(project)
fireHierarchyUpdate()

// Write the new project itself
//ProjectIO.writeProject(projectNew)
qupath.refreshProject()

print("Done! Project written to ")
fireHierarchyUpdate()
Binary file removed Setup/Extensions/Colour_Deconvolution-3.0.2.jar
Binary file not shown.
17 changes: 0 additions & 17 deletions Setup/Extensions/colourdeconvolution.txt

This file was deleted.

Binary file removed Setup/Extensions/qupath-extension-biop-1.1.0.jar
Binary file not shown.
Loading

0 comments on commit cd723cf

Please sign in to comment.