Skip to content

Instantly share code, notes, and snippets.

@NicoKiaru
Last active April 24, 2020 14:35
Show Gist options
  • Save NicoKiaru/671b3ec6d9b2bf8a2a95cb39adee104c to your computer and use it in GitHub Desktop.
Save NicoKiaru/671b3ec6d9b2bf8a2a95cb39adee104c to your computer and use it in GitHub Desktop.
/**
* 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