Last active
April 24, 2020 14:35
-
-
Save NicoKiaru/671b3ec6d9b2bf8a2a95cb39adee104c to your computer and use it in GitHub Desktop.
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
/** | |
* Diana analysis for Selene : | |
* Requirements: | |
* - An image which contains associated ROIs for nuclei and cytoplasm | |
* - ROI names should follow the pattern: | |
* - Cyto_#index_of_cell < Cytoplasm ROI | |
* - Nucleus_#index_of_cell < Nucleus ROI | |
* so Cyto_0, Nucleus_0, Cyto_1, Nucleus_1, ... | |
* | |
* - DiAna plugin installed (follow instructions https://imagejdocu.tudor.lu/plugin/analysis/distance_analysis_diana_2d_3d/start) | |
* (do not forget the extra mcib3d jar) | |
* | |
* - Morpholib J update site enabled (to verify...) | |
* - PTBIOP update site enbled (to verify... | |
* | |
* What the script does: | |
* - Performs spot segmentation on each channel | |
* - Measure the average distance between an object from one channel and the 10 nearest object in the other channel | |
* - Distance is the center to center distance | |
* - Outputing the average of the distance of the nClosest object A -> B and B -> A + Stdev + number of objects | |
* | |
* The output measurement is calibrated (in pysical units : so in micron if the original image is in micron) | |
* | |
* Also the detected spots are overlaid on the original image | |
* | |
* What's missing : a way to vary the sensitivity of the spot detection | |
* | |
* @author Nicolas Chiaruttini, EPFL, 2020 | |
* | |
*/ | |
#@ImagePlus(label= "Input composite multi channel image" ) image | |
#@int(label= "Channel A index") channelA | |
#@int(label= "Channel A threshold", value=50) thresholdA | |
#@int(label= "Channel B index") channelB | |
#@int(label= "Channel B threshold", value=25) thresholdB | |
#@int(label= "Number of neighbor to analyse", min = 1) nClosest | |
// Duplicate channels of interest | |
selectImage(image); | |
imageTitle = getTitle(); | |
getDimensions(width, height, channels, slices, frames); | |
run("Duplicate...", "duplicate channels="+channelA); | |
imageATitle = getTitle(); | |
selectImage(image); | |
run("Duplicate...", "duplicate channels="+channelB); | |
imageBTitle = getTitle(); | |
// DiAna does it by default -> annoying behaviour, and that's why we need to merge images back at the end | |
//selectImage(image); | |
//run("Split Channels"); | |
// Performs spots segmentation on each channel | |
run("DiAna_Segment", "img=["+imageATitle+"] peaks=2.0-2.0-"+thresholdA+" spots=10-10-1.5-3-2000-true"); | |
rename("ChannelALabel"); | |
imageALabelTitle = getTitle(); | |
run("DiAna_Segment", "img=["+imageBTitle+"] peaks=2.0-2.0-"+thresholdB+" spots=10-10-1.5-3-2000-true"); | |
rename("ChannelBLabel"); | |
imageBLabelTitle = getTitle(); | |
print("imageALabelTitle="+imageALabelTitle); | |
print("imageBLabelTitle="+imageBLabelTitle); | |
// Removes objects detected in the nucleus | |
for (index=0;index<roiManager("count");index++) { | |
roiManager("select", index); | |
if (startsWith(Roi.getName,"Nucleus_")) { | |
// That's a nucleus, remove this part of the image | |
selectImage(imageALabelTitle); | |
roiManager("select", index); | |
run("Cut"); | |
selectImage(imageBLabelTitle); | |
roiManager("select", index); | |
run("Cut"); | |
} | |
} | |
// Makes ROI for nice display on original image | |
selectImage(imageALabelTitle); | |
run("Select None"); | |
run("Duplicate...", " "); | |
run("16-bit"); | |
setOption("ScaleConversions", true); | |
run("8-bit"); | |
run("Max...", "value=1"); | |
run("Multiply...", "value=255.000"); | |
run("Create Selection"); | |
roiManager("Add"); | |
roiManager("Select", roiManager("count")-1); | |
roiManager("Rename", "channelAObjects"); | |
roiManager("Set Color", "green"); | |
close(); | |
selectImage(imageBLabelTitle); | |
run("Select None"); | |
run("Duplicate...", " "); | |
run("16-bit"); | |
setOption("ScaleConversions", true); | |
run("8-bit"); | |
run("Max...", "value=1"); | |
run("Multiply...", "value=255.000"); | |
run("Create Selection"); | |
roiManager("Add"); | |
roiManager("Select", roiManager("count")-1); | |
roiManager("Rename", "channelBObjects"); | |
roiManager("Set Color", "red"); | |
close(); | |
// Performs a global measurement of object proximity | |
analyse(imageTitle+"_global_-1_"+channelA+"To"+channelB, imageALabelTitle, imageBLabelTitle, 0); | |
analyse(imageTitle+"_global_-1_"+channelB+"To"+channelA, imageBLabelTitle, imageALabelTitle, 0); | |
// Performs a measurement of object proximity per cell | |
// Removes objects detected in the nucleus | |
for (index=0;index<roiManager("count");index++) { | |
roiManager("select", index); | |
if (startsWith(Roi.getName,"Cyto_")) { | |
nameCurrentCell = Roi.getName; | |
// That's a cytoplasm, let's do this the analysis on this - restricted on the cytoplasm | |
selectImage(imageALabelTitle); | |
run("Duplicate...", " "); | |
labelImgAOneCell = getTitle(); | |
roiManager("select", index); | |
run("Make Inverse"); | |
run("Cut"); | |
run("Select None"); | |
selectImage(imageBLabelTitle); | |
run("Duplicate...", " "); | |
labelImgBOneCell = getTitle(); | |
roiManager("select", index); | |
areaCurrentRoi = getValue("Area"); | |
run("Make Inverse"); | |
run("Cut"); | |
run("Select None"); | |
// Performs a global measurement of object proximity | |
analyse(imageTitle+"_"+nameCurrentCell+"_"+channelA+"To"+channelB, labelImgAOneCell, labelImgBOneCell, areaCurrentRoi ); | |
analyse(imageTitle+"_"+nameCurrentCell+"_"+channelB+"To"+channelA, labelImgBOneCell, labelImgAOneCell, areaCurrentRoi ); | |
// Removes temporary images | |
selectImage(labelImgAOneCell); | |
close(); | |
selectImage(labelImgBOneCell); | |
close(); | |
} | |
} | |
// Cleans by closing working images | |
selectWindow(imageALabelTitle); | |
close(); | |
selectWindow(imageATitle); | |
close(); | |
selectWindow(imageBLabelTitle); | |
close(); | |
selectWindow(imageBTitle); | |
close(); | |
// Merge again the channels from original image | |
param = ""; | |
for (iCh=1;iCh<=channels;iCh++) { | |
param+="c"+iCh+"=[C"+iCh+"-"+imageTitle+"] "; | |
} | |
run("Merge Channels...", param+"create"); | |
roiManager("Show All"); | |
// Performs the statistical analysis | |
function analyse(title, labelImgA, labelImgB, areaRoi) { | |
run("DiAna_Analyse", "img1=["+imageATitle+"] img2=["+imageBTitle+"] lab1=["+labelImgA+"] lab2=["+labelImgB+"] adja kclosest="+nClosest+" "); | |
tableName = Table.title; | |
data = Table.getColumn("Dist CenterA-CenterB"); | |
Array.getStatistics(data, min, max, mean, stdDev); | |
Array.sort(data); | |
median = data[data.length/2-1]; | |
print(title+"\t mean \t"+mean); | |
print(title+"\t stdDev \t"+stdDev); | |
print(title+"\t median \t"+median); | |
print(title+"\t area \t"+areaRoi); | |
print(title+"\t n \t"+data.length/nClosest); | |
Table.deleteColumn("Dist CenterA-CenterB"); | |
Table.reset("AdjacencyResults"); | |
} | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment