1 package com.github.celldynamics.quimp.geom;
2
3 import java.awt.Point;
4 import java.util.ArrayList;
5 import java.util.Collections;
6 import java.util.List;
7 import java.util.function.Predicate;
8
9 import com.github.celldynamics.quimp.utils.QuimPArrayUtils;
10
11
12
13
14
15
16
17
18
19
20
21 public class MapTracker {
22
23
24
25
26 public static final int BAD_INDEX = -1;
27
28
29
30
31 public boolean includeFirst = false;
32
33
34
35
36 int[][] forwardMap;
37
38
39
40
41 int[][] backwardMap;
42
43
44
45
46 int rowsFrames;
47
48
49
50
51 int colsIndexes;
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72 public MapTracker(double[][] originMap, double[][] coordMap) {
73
74 forwardMap = QuimPArrayUtils.initInteger2dArray(originMap.length, originMap[0].length);
75 backwardMap = QuimPArrayUtils.initInteger2dArray(forwardMap.length, forwardMap[0].length);
76
77 QuimPArrayUtils.fill2Darray(forwardMap, -1);
78 QuimPArrayUtils.fill2Darray(backwardMap, -1);
79
80 rowsFrames = forwardMap.length;
81 colsIndexes = forwardMap[0].length;
82 double[] minV = new double[3];
83 double[] minI = new double[3];
84
85 for (int i = 1; i < rowsFrames; i++) {
86 for (int j = 0; j < colsIndexes; j++) {
87 double p = originMap[i][j];
88 double[] diffA = rowDiff(p, coordMap[i - 1]);
89 double[] diffB = rowDiff(p, rowAdd(-1, coordMap[i - 1]));
90 double[] diffC = rowDiff(p, rowAdd(+1, coordMap[i - 1]));
91
92 double[] minDiffA = QuimPArrayUtils.minArrayIndexElement(diffA);
93 double[] minDiffB = QuimPArrayUtils.minArrayIndexElement(diffB);
94 double[] minDiffC = QuimPArrayUtils.minArrayIndexElement(diffC);
95
96
97 minV[0] = minDiffA[0];
98 minV[1] = minDiffB[0];
99 minV[2] = minDiffC[0];
100 minI[0] = minDiffA[1];
101 minI[1] = minDiffB[1];
102 minI[2] = minDiffC[1];
103 double[] minMinV = QuimPArrayUtils.minArrayIndexElement(minV);
104 backwardMap[i][j] = (int) minI[(int) minMinV[1]];
105 }
106 }
107
108
109 for (int i = 0; i < rowsFrames - 1; i++) {
110 for (int j = 0; j < colsIndexes; j++) {
111 double p = coordMap[i][j];
112 double[] diffA = rowDiff(p, originMap[i + 1]);
113 double[] diffB = rowDiff(p, rowAdd(-1, originMap[i + 1]));
114 double[] diffC = rowDiff(p, rowAdd(+1, originMap[i + 1]));
115
116 double[] minDiffA = QuimPArrayUtils.minArrayIndexElement(diffA);
117 double[] minDiffB = QuimPArrayUtils.minArrayIndexElement(diffB);
118 double[] minDiffC = QuimPArrayUtils.minArrayIndexElement(diffC);
119
120
121 minV[0] = minDiffA[0];
122 minV[1] = minDiffB[0];
123 minV[2] = minDiffC[0];
124 minI[0] = minDiffA[1];
125 minI[1] = minDiffB[1];
126 minI[2] = minDiffC[1];
127 double[] minMinV = QuimPArrayUtils.minArrayIndexElement(minV);
128 forwardMap[i][j] = (int) minI[(int) minMinV[1]];
129 }
130 }
131 }
132
133
134
135
136
137
138
139
140
141
142 private double[] rowDiff(double p, double[] row) {
143 double[] cpy = new double[row.length];
144 for (int i = 0; i < cpy.length; i++) {
145 cpy[i] = Math.abs(p - row[i]);
146 }
147 return cpy;
148 }
149
150
151
152
153
154
155
156
157
158
159 private double[] rowAdd(double val, double[] row) {
160 double[] cpy = new double[row.length];
161 System.arraycopy(row, 0, cpy, 0, row.length);
162 for (int i = 0; i < cpy.length; i++) {
163 cpy[i] += val;
164 }
165 return cpy;
166 }
167
168
169
170
171
172
173
174
175
176 public int getNext(int frame, int membraneIndex) {
177 if (frame >= rowsFrames || membraneIndex >= colsIndexes || frame < 0 || membraneIndex < 0) {
178 return BAD_INDEX;
179 }
180 return forwardMap[frame][membraneIndex];
181 }
182
183
184
185
186
187
188
189
190
191 public int getPrev(int currentFrame, int membraneIndex) {
192 if (currentFrame >= rowsFrames || membraneIndex >= colsIndexes || currentFrame < 0
193 || membraneIndex < 0) {
194 return BAD_INDEX;
195 }
196 return backwardMap[currentFrame][membraneIndex];
197 }
198
199
200
201
202
203
204
205
206
207
208
209
210 @Deprecated
211 public int[] trackForward(int currentFrame, int membraneIndex, int timeSpan) {
212 if (includeFirst) {
213 timeSpan++;
214 }
215 int[] ret = new int[timeSpan];
216 if (includeFirst) {
217 ret[0] = membraneIndex;
218 } else {
219 ret[0] = getNext(currentFrame, membraneIndex);
220 }
221 for (int t = 1; t < timeSpan; t++) {
222 ret[t] = getNext(currentFrame + t, (int) ret[t - 1]);
223 }
224 return ret;
225 }
226
227
228
229
230
231
232
233
234
235
236
237
238 public List<Point> trackForwardValid(int currentFrame, int membraneIndex, int timeSpan) {
239 if (includeFirst) {
240 timeSpan++;
241 }
242 ArrayList<Point> ret = new ArrayList<>();
243 if (includeFirst) {
244 ret.add(new Point(currentFrame, membraneIndex));
245 } else {
246 ret.add(new Point(currentFrame + 1, getNext(currentFrame, membraneIndex)));
247 }
248 for (int t = 1; t < timeSpan; t++) {
249 ret.add(new Point(ret.get(t - 1).x + 1, getNext(currentFrame + t, (int) ret.get(t - 1).y)));
250 }
251
252 ret.removeIf(new PredicateBadIndex());
253
254 return ret;
255 }
256
257
258
259
260
261
262
263
264
265
266
267
268 @Deprecated
269 public int[] trackBackward(int currentFrame, int membraneIndex, int timeSpan) {
270 if (includeFirst) {
271 timeSpan++;
272 }
273 int[] ret = new int[timeSpan];
274 if (includeFirst) {
275 ret[timeSpan - 1] = membraneIndex;
276 } else {
277 ret[timeSpan - 1] = getPrev(currentFrame, membraneIndex);
278 }
279 for (int t = timeSpan - 2; t >= 0; t--) {
280 ret[t] = getPrev(currentFrame - (timeSpan - t - 1), (int) ret[t + 1]);
281 }
282 return ret;
283 }
284
285
286
287
288
289
290
291
292
293
294
295
296 public List<Point> trackBackwardValid(int currentFrame, int membraneIndex, int timeSpan) {
297 if (includeFirst) {
298 timeSpan++;
299 }
300 ArrayList<Point> ret = new ArrayList<>();
301 if (includeFirst) {
302 ret.add(new Point(currentFrame, membraneIndex));
303 } else {
304 ret.add(new Point(currentFrame - 1, getPrev(currentFrame, membraneIndex)));
305 }
306 for (int t = 1; t < timeSpan; t++) {
307 ret.add(new Point(ret.get(t - 1).x - 1, getPrev(currentFrame - t, (int) ret.get(t - 1).y)));
308 }
309
310 Collections.reverse(ret);
311 ret.removeIf(new PredicateBadIndex());
312
313 return ret;
314 }
315
316
317
318
319
320
321
322
323
324
325
326
327 @Deprecated
328 public int[] getForwardFrames(int currentFrame, int timeSpan) {
329 int f;
330 if (includeFirst) {
331 timeSpan++;
332 }
333 int[] ret = new int[timeSpan];
334 if (includeFirst) {
335 f = currentFrame;
336 } else {
337 f = currentFrame + 1;
338 }
339 int l = 0;
340 do {
341 ret[l++] = f++;
342 } while (l < timeSpan);
343 return ret;
344 }
345
346
347
348
349
350
351
352
353
354
355
356
357 @Deprecated
358 public int[] getBackwardFrames(int currentFrame, int timeSpan) {
359 int f;
360 if (includeFirst) {
361 timeSpan++;
362 }
363 int[] ret = new int[timeSpan];
364 if (includeFirst) {
365 f = currentFrame;
366 } else {
367 f = currentFrame - 1;
368 }
369 int l = timeSpan - 1;
370 do {
371 ret[l--] = f--;
372 } while (l >= 0);
373 return ret;
374 }
375
376
377
378
379
380
381
382 class PredicateBadIndex implements Predicate<Point> {
383
384 @Override
385 public boolean test(Point t) {
386 if (t.y == MapTracker.BAD_INDEX) {
387 return true;
388 } else {
389 return false;
390 }
391 }
392 }
393 }