-
Notifications
You must be signed in to change notification settings - Fork 0
/
Lyso_puncta_coloc.ijm
196 lines (172 loc) · 6.22 KB
/
Lyso_puncta_coloc.ijm
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
/*
* LYSOSOMAL PUNCTA AND COLOCALIZATION v1.0
* ----------------------------------------
*
* This macro allows to quantify lysosomal (and other) puncta, plus colocalization with
* other lysosomal marker (CatD, LC3, etc).
*
* Ideally, the image will have 3 channels, being channel 1 used for cell segmentation.
* In this version, channels 2 and 3 are puncta to be quantified.
*
* Cell segmentation is performed via a manually adjusted threshold.
* Puncta segmentation is automated, with a predefined threshold.
*
* The macro creates a custom table with results.
* This window can remain open and it will be updated with each image.
*
* Only one image should be open for the macro to work.
* I will include a batch mode on the github repo in the next version.
*
* The script has been optimized for in vivo immunostaining, where lysosomal labelling can be noisy.
* Hence, the macro includes a Difference of Gaussians filter to enhance contrast.
* (I will make this optional in the future).
*
* Federico N. Soria (January 2021)
* federico.soria@achucarro.org
*/
//INITIALIZATION
if (nImages==0) {
exit("No images open. Please open an image");
}
run("Select None");
run("Clear Results");
roiManager("reset");
run("Set Measurements...", "area limit display redirect=None decimal=2");
print("\\Clear");
//IMAGE INFO
name=getTitle();
getDimensions(width, height, channels, slices, frames);
//GUI DIALOG
ch_list=newArray(channels);
for (i=0; i<channels; i++){
ch_list[i]=""+i+1+"";
}
thres_list = getList("threshold.methods");
Dialog.create("Macro Parameters");
Dialog.addNumber("Minimum sigma for DifGaus filter", 1);
Dialog.addNumber("Maximum sigma for DifGaus filter", 50);
Dialog.addMessage("\n");
Dialog.addChoice("Channel for cell segmentation", ch_list, "1");
Dialog.addString("Name for ref channel", "TH");
Dialog.addNumber("Min cell size in calibrated units", 20); //This is used to separate somas from isolated neurites.
Dialog.addMessage("\n");
Dialog.addChoice("Channel for reference puncta", ch_list, "2");
Dialog.addString("Name for ref puncta channel", "LAMP2");
Dialog.addChoice("Threshold for ref puncta channel", thres_list, "Default");
Dialog.addNumber("Min puncta size", 10);
Dialog.addMessage("\n");
Dialog.addChoice("Channel for colocalized puncta", ch_list, "3");
Dialog.addString("Name for coloc puncta channel", "CatD");
Dialog.addChoice("Threshold for coloc puncta channel", thres_list, "Moments");
Dialog.addNumber("Min puncta size", 10);
Dialog.addCheckbox("Save values to file", true);
Dialog.show();
gmin=Dialog.getNumber();
gmax=Dialog.getNumber();
seg_chan=Dialog.getChoice();
seg_name=Dialog.getString();
cell_size=Dialog.getNumber();
ref_chan=Dialog.getChoice();
ref_name=Dialog.getString();
ref_thres=Dialog.getChoice();
ref_size=Dialog.getNumber();
coloc_chan=Dialog.getChoice();
coloc_name=Dialog.getString();
coloc_thres=Dialog.getChoice();
coloc_size=Dialog.getNumber();
savetofile=Dialog.getCheckbox();
//IMAGE PREPROCESSING
run("Grays");
difgaus(gmin, gmax, "DifGaus");
selectWindow("DifGaus");
run("Split Channels");
//CELL SEGMENTATION
selectWindow("C"+seg_chan+"-DifGaus");
rename(name+"_"+seg_name);
run("Threshold...");
waitForUser("Set Threshold", "Set Threshold for cell segmentation using the upper sliding bar \nCheck the 'Dark Background' box if necessary. \nThen click OK. \nDo not press Apply!");
run("Convert to Mask");
run("Analyze Particles...", "size="+cell_size+"-Infinity show=Outlines summarize");
selectWindow(name+"_"+seg_name);
setOption("BlackBackground", true);
run("Fill Holes");
run("Create Selection");
run("Enlarge...", "enlarge=5 pixel"); //This is to ensure you get also the lysosomes close to the membrane.
roiManager("Add");
//PUNCTA QUANTIFICATION
setBackgroundColor(0, 0, 0);
selectWindow("C"+ref_chan+"-DifGaus");
rename(ref_name);
puncta (ref_thres+" dark", ref_size);
selectWindow("C"+coloc_chan+"-DifGaus");
rename(coloc_name);
puncta (coloc_thres+" dark", coloc_size);
//COLOCALIZATION (number of CH3 puncta colocalizing with CH2)
selectWindow(ref_name);
setAutoThreshold("Default dark");
run("Create Selection");
roiManager("Add");
selectWindow(coloc_name);
run("Duplicate...", "title=["+coloc_name+" in "+ref_name+"]");
roiManager("Select", 1);
run("Clear Outside");
run("Select None");
run("Analyze Particles...", "size=4-Infinity pixel summarize");
//GET VALUES
IJ.renameResults("Summary","Results");
if (savetofile==true) {
dir=getDirectory("Choose Directory to save files");
saveAs("Results", dir+File.separator+name+".xls");
selectWindow("Log");
saveAs("Text", dir+File.separator+name+".txt");
}
cells=getResult("Count", 0);
ref_val=getResult("Count", 1);
coloc_val=getResult("Count", 2);
coloc_in=getResult("Count", 3);
coloc_out=coloc_val-coloc_in;
selectWindow("Results");
run("Close");
//CUSTOM TABLE
myTable(name,cells,ref_val,coloc_val,coloc_in,coloc_out);
function myTable(a,b,c,d,e,f){
title1="Quantification";
title2="["+title1+"]";
if (isOpen(title1)){
print(title2, a+"\t"+b+"\t"+c+"\t"+d+"\t"+e+"\t"+f);
}
else{
run("Table...", "name="+title2+" width=800 height=500");
print(title2, "\\Headings:File\tCells\tNumber of "+ref_name+"\tNumber of "+coloc_name+"\t"+coloc_name+" in "+ref_name+"\t"+coloc_name+" outside "+ref_name);
print(title2, a+"\t"+b+"\t"+c+"\t"+d+"\t"+e+"\t"+f);
}
}
waitForUser("Copy Results to Excel");
//EXIT
run("Tile");
waitForUser("Close all windows");
run("Close All");
//FUNCTION FOR IMAGE ENHANCEMENT (from Jorge Valero @Achucarro)
function difgaus (min, max, finalname){
run("Duplicate...", "title=min duplicate");
run("Gaussian Blur...", "sigma="+min+" stack");
run("Duplicate...", "title=max duplicate");
run("Gaussian Blur...", "sigma="+max+" stack");
imageCalculator("Subtract stack", "min","max");
selectWindow("max");
close();
selectWindow("min");
rename(finalname);
}
//FUNCTION FOR PUNCTA QUANTIFICATION ("autothres is the Automatic Threshold chosen. "Size" is minimum size in pixels for segmentation)
function puncta (autothres, size){
setAutoThreshold(autothres);
run("Convert to Mask");
roiManager("Select", 0);
setBackgroundColor(0, 0, 0);
run("Clear Outside");
run("Select None");
run("Watershed");
run("Analyze Particles...", "size="+size+"-Infinity pixel summarize");
print("Threshold used for "+getTitle()+": "+autothres);
}