1 package com.github.celldynamics.quimp;
2
3 import java.io.BufferedReader;
4 import java.io.File;
5 import java.io.FileReader;
6 import java.io.FileWriter;
7 import java.io.IOException;
8 import java.io.PrintWriter;
9
10 import com.github.celldynamics.quimp.geom.ExtendedVector2d;
11 import com.github.celldynamics.quimp.plugin.ana.ChannelStat;
12 import com.github.celldynamics.quimp.utils.QuimpToolsCollection;
13
14 import ij.IJ;
15 import ij.measure.ResultsTable;
16
17
18
19
20
21
22
23
24 public class FrameStatistics {
25
26
27
28 public int frame;
29
30
31
32 public double area;
33
34
35
36 public ExtendedVector2d centroid;
37
38
39
40
41
42
43 public double elongation;
44
45
46
47
48
49 public double circularity;
50
51
52
53 public double perimiter;
54
55
56
57
58 public double displacement;
59
60
61
62
63 public double dist;
64
65
66
67
68
69 public double persistance;
70
71
72
73 public double speed;
74
75
76
77
78
79 public double persistanceToSource;
80
81
82
83
84
85 public double dispersion;
86
87
88
89
90
91 public double extension;
92
93
94
95 public ChannelStat[] channels;
96
97
98
99
100 public FrameStatistics() {
101 centroid = new ExtendedVector2d();
102 channels = new ChannelStat[3];
103 channels[0] = new ChannelStat();
104 channels[1] = new ChannelStat();
105 channels[2] = new ChannelStat();
106 }
107
108
109
110
111
112
113
114 public void toScale(double scale, double frameInterval) {
115 area = QuimpToolsCollection.areaToScale(area, scale);
116 perimiter = QuimpToolsCollection.distanceToScale(perimiter, scale);
117 displacement = QuimpToolsCollection.distanceToScale(displacement, scale);
118 dist = QuimpToolsCollection.distanceToScale(dist, scale);
119 speed = QuimpToolsCollection.speedToScale(speed, scale, frameInterval);
120 }
121
122
123
124
125
126
127 void centroidToPixels(double scale) {
128 centroid.setXY(centroid.getX() / scale, centroid.getY() / scale);
129 }
130
131
132
133
134
135
136 public void clearFluo() {
137 this.channels[0] = new ChannelStat();
138 this.channels[1] = new ChannelStat();
139 this.channels[2] = new ChannelStat();
140 }
141
142
143
144
145
146
147
148
149
150
151 public static void write(FrameStatistics[] s, File outfile, double scale, double frameInterval)
152 throws IOException {
153 PrintWriter pw = new PrintWriter(new FileWriter(outfile), true);
154 IJ.log("Writing to file: " + outfile.getName());
155 pw.print("#p2\n#QuimP output - " + outfile.getAbsolutePath() + "\n");
156 pw.print("# Centroids are given in pixels. Distance & speed & area measurements are scaled"
157 + " to micro meters\n");
158 pw.print("# Scale: " + scale + " micro meter per pixel | Frame interval: " + frameInterval
159 + " sec\n");
160 pw.print("# Frame,X-Centroid,Y-Centroid,Displacement,Dist. Traveled,"
161 + "Directionality,Speed,Perimeter,Elongation,Circularity,Area");
162
163 for (int i = 0; i < s.length; i++) {
164 pw.print("\n" + s[i].frame + "," + IJ.d2s(s[i].centroid.getX(), 2) + ","
165 + IJ.d2s(s[i].centroid.getY(), 2) + "," + IJ.d2s(s[i].displacement) + ","
166 + IJ.d2s(s[i].dist) + "," + IJ.d2s(s[i].persistance) + "," + IJ.d2s(s[i].speed) + ","
167 + IJ.d2s(s[i].perimiter) + "," + IJ.d2s(s[i].elongation) + ","
168 + IJ.d2s(s[i].circularity, 3) + "," + IJ.d2s(s[i].area));
169 }
170 pw.print("\n#\n# Fluorescence measurements");
171 writeFluo(s, pw, 0);
172 writeFluo(s, pw, 1);
173 writeFluo(s, pw, 2);
174 pw.close();
175 }
176
177 private static void writeFluo(FrameStatistics[] s, PrintWriter pw, int c) {
178 pw.print("\n#\n# Channel " + (c + 1)
179 + ";Frame, Total Fluo.,Mean Fluo.,Cortex Width, Cyto. Area,Total Cyto. Fluo.,"
180 + " Mean Cyto. Fluo.,"
181 + "Cortex Area,Total Cortex Fluo., Mean Cortex Fluo., %age Cortex Fluo.");
182 for (int i = 0; i < s.length; i++) {
183 pw.print("\n" + s[i].frame + "," + IJ.d2s(s[i].channels[c].totalFluor) + ","
184 + IJ.d2s(s[i].channels[c].meanFluor) + "," + IJ.d2s(s[i].channels[c].cortexWidth));
185 pw.print("," + IJ.d2s(s[i].channels[c].innerArea) + ","
186 + IJ.d2s(s[i].channels[c].totalInnerFluor) + ","
187 + IJ.d2s(s[i].channels[c].meanInnerFluor));
188 pw.print("," + IJ.d2s(s[i].channels[c].cortexArea) + ","
189 + IJ.d2s(s[i].channels[c].totalCorFluo) + "," + IJ.d2s(s[i].channels[c].meanCorFluo)
190 + "," + IJ.d2s(s[i].channels[c].percCortexFluo));
191 }
192 }
193
194
195
196
197
198
199
200
201 public static FrameStatistics[] read(File infile) throws IOException {
202
203 BufferedReader br = new BufferedReader(new FileReader(infile));
204 String thisLine;
205 int i = 0;
206
207 while ((thisLine = br.readLine()) != null) {
208 if (thisLine.startsWith("# Fluorescence measurements")) {
209 break;
210 }
211 if (thisLine.startsWith("#")) {
212 continue;
213 }
214
215 i++;
216 }
217 br.close();
218 FrameStatisticstistics.html#FrameStatistics">FrameStatistics[] stats = new FrameStatistics[i];
219
220 i = 0;
221 String[] split;
222 br = new BufferedReader(new FileReader(infile));
223 while ((thisLine = br.readLine()) != null) {
224 if (thisLine.startsWith("# Channel")) {
225 break;
226 }
227 if (thisLine.startsWith("#")) {
228 continue;
229 }
230
231
232 split = thisLine.split(",");
233
234 stats[i] = new FrameStatistics();
235 stats[i].frame = (int) QuimpToolsCollection.s2d(split[0]);
236 stats[i].centroid.setXY(QuimpToolsCollection.s2d(split[1]),
237 QuimpToolsCollection.s2d(split[2]));
238 stats[i].displacement = QuimpToolsCollection.s2d(split[3]);
239 stats[i].dist = QuimpToolsCollection.s2d(split[4]);
240 stats[i].persistance = QuimpToolsCollection.s2d(split[5]);
241 stats[i].speed = QuimpToolsCollection.s2d(split[6]);
242 stats[i].perimiter = QuimpToolsCollection.s2d(split[7]);
243 stats[i].elongation = QuimpToolsCollection.s2d(split[8]);
244 stats[i].circularity = QuimpToolsCollection.s2d(split[9]);
245 stats[i].area = QuimpToolsCollection.s2d(split[10]);
246
247 i++;
248 }
249
250 readChannel(0, stats, br);
251 readChannel(1, stats, br);
252 readChannel(2, stats, br);
253
254 br.close();
255 return stats;
256 }
257
258 private static void readChannel(int c, FrameStatistics[] stats, BufferedReader br)
259 throws IOException {
260 String thisLine;
261 String[] split;
262 int i = 0;
263 while ((thisLine = br.readLine()) != null) {
264 if (thisLine.startsWith("# Channel")) {
265 break;
266 }
267 if (thisLine.startsWith("#")) {
268 continue;
269 }
270
271 split = thisLine.split(",");
272
273 stats[i].channels[c].totalFluor = QuimpToolsCollection.s2d(split[1]);
274 stats[i].channels[c].meanFluor = QuimpToolsCollection.s2d(split[2]);
275 stats[i].channels[c].cortexWidth = QuimpToolsCollection.s2d(split[3]);
276 stats[i].channels[c].innerArea = QuimpToolsCollection.s2d(split[4]);
277 stats[i].channels[c].totalInnerFluor = QuimpToolsCollection.s2d(split[5]);
278 stats[i].channels[c].meanInnerFluor = QuimpToolsCollection.s2d(split[6]);
279 stats[i].channels[c].cortexArea = QuimpToolsCollection.s2d(split[7]);
280 stats[i].channels[c].totalCorFluo = QuimpToolsCollection.s2d(split[8]);
281 stats[i].channels[c].meanCorFluo = QuimpToolsCollection.s2d(split[9]);
282 stats[i].channels[c].percCortexFluo = QuimpToolsCollection.s2d(split[10]);
283
284 i++;
285 }
286 }
287
288
289
290
291
292
293
294
295 public void addFluoToResultTable(ResultsTable rt, int channelno) {
296
297 ChannelStat cs = channels[channelno];
298 rt.incrementCounter();
299 rt.addValue("frame", frame);
300 rt.addValue("TotalFluo", cs.totalFluor);
301 rt.addValue("MeanFluo", cs.meanFluor);
302 rt.addValue("Cortex Width", cs.cortexWidth);
303 rt.addValue("Cyto. Area", cs.innerArea);
304 rt.addValue("Total Cyto. Fluo.", cs.totalInnerFluor);
305 rt.addValue("Mean Cyto. Fluo.h", cs.meanInnerFluor);
306 rt.addValue("Cortex Area", cs.cortexArea);
307 rt.addValue("Total Cortex Fluo.", cs.totalCorFluo);
308 rt.addValue("Mean Cortex Fluo.", cs.meanCorFluo);
309 rt.addValue("%age Cortex Fluo.", cs.percCortexFluo);
310 }
311
312
313
314
315
316
317
318 public void addStatToResultTable(ResultsTable rt) {
319 rt.incrementCounter();
320 rt.addValue("Frame", frame);
321 rt.addValue("Area", area);
322 rt.addValue("Centroid_x", centroid.getX());
323 rt.addValue("Centroid_y", centroid.getY());
324 rt.addValue("Circularity", circularity);
325 rt.addValue("Displacement", displacement);
326 rt.addValue("Distance", dist);
327 rt.addValue("Elongation", elongation);
328 rt.addValue("Perimeter", perimiter);
329 rt.addValue("Persistance", persistance);
330 rt.addValue("Speed", speed);
331
332 }
333
334 }