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
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
|
include <imhdr.h>
include <math/curfit.h>
include <pkg/center1d.h>
include <pkg/gtools.h>
include "apertures.h"
define MAXBUF 100000 # Column buffer size
# AP_TRACE -- Trace features in a two dimensional image.
#
# Given an image pointer, the starting dispersion position, and a set
# of apertures defining the centers of features, trace the feature
# centers to other dispersion positions and fit a curve to the positions.
# The user specifies the dispersion step size, the number of dispersion
# lines to sum, and parameters for the feature centering function
# fitting.
procedure ap_trace (image, line, aps, naps, apedit)
char image[SZ_FNAME] # Image name
int line # Starting dispersion position
pointer aps[ARB] # Apertures
int naps # Number of apertures
int apedit # Called from APEDIT?
int step # Tracing step
int nsum # Number of dispersion lines to sum
int nlost # Number of steps lost before quitting
real cradius # Centering radius
real cwidth # Centering width
real cthreshold # Detection threshold for centering
int i, na, dispaxis, apaxis
real center
pointer im, ic, ic1, sp, str
data ic1 /NULL/
int apgeti()
real apgetr()
bool clgetb(), ap_answer()
pointer ap_immap()
errchk ap_immap, ic_open, ap_ltrace, ap_ctrace, ap_default
common /apt_com/ ic
begin
na = 0
do i = 1, naps
if (AP_SELECT(aps[i]) == YES)
na = na + 1
if (naps > 0 && na == 0)
return
# Query user.
call smark (sp)
call salloc (str, SZ_LINE, TY_CHAR)
if (apedit == NO) {
call sprintf (Memc[str], SZ_LINE, "Trace apertures for %s?")
call pargstr (image)
if (!ap_answer ("anstrace", Memc[str])) {
call sfree (sp)
return
}
call sprintf (Memc[str], SZ_LINE,
"Fit traced positions for %s interactively?")
call pargstr (image)
if (ap_answer ("ansfittrace", Memc[str])) {
call apgstr ("ansfittrace", Memc[str], SZ_LINE)
call appstr ("ansfittrace1", Memc[str])
} else
call appstr ("ansfittrace1", "NO")
if (clgetb ("verbose"))
call printf ("Tracing apertures ...\n")
}
# Tracing parameters
step = apgeti ("t_step")
nsum = max (1, abs (apgeti ("t_nsum")))
nlost = apgeti ("t_nlost")
if (ic == NULL || ic1 == NULL) {
call ic_open (ic)
ic1 = ic
call apgstr ("t_function", Memc[str], SZ_LINE)
call ic_pstr (ic, "function", Memc[str])
call ic_puti (ic, "order", apgeti ("t_order"))
call apgstr ("t_sample", Memc[str], SZ_LINE)
call ic_pstr (ic, "sample", Memc[str])
call ic_puti (ic, "naverage", apgeti ("t_naverage"))
call ic_puti (ic, "niterate", apgeti ("t_niterate"))
call ic_putr (ic, "low", apgetr ("t_low_reject"))
call ic_putr (ic, "high", apgetr ("t_high_reject"))
call ic_putr (ic, "grow", apgetr ("t_grow"))
}
im = ap_immap (image, apaxis, dispaxis)
# If no apertures are defined default to the center of the image.
if (naps == 0) {
naps = 1
center = IM_LEN (im, apaxis) / 2.
call ap_default (im, 1, 1, apaxis, center, real (line),
aps[naps])
call sprintf (Memc[str], SZ_LINE,
"TRACE - Default aperture defined centered on %s")
call pargstr (image)
call ap_log (Memc[str], YES, NO, YES)
}
# Centering parameters
cwidth = apgetr ("t_width")
cradius = apgetr ("radius")
cthreshold = apgetr ("threshold")
switch (dispaxis) {
case 1:
call ap_ctrace (image, im, ic, line, step, nsum, nlost, cradius,
cwidth, cthreshold, aps, naps)
case 2:
call ap_ltrace (image, im, ic, line, step, nsum, nlost, cradius,
cwidth, cthreshold, aps, naps)
}
# Log the tracing and write the traced apertures to the database.
call sprintf (Memc[str], SZ_LINE,
"TRACE - %d apertures traced in %s.")
call pargi (na)
call pargstr (image)
if (apedit == NO)
call ap_log (Memc[str], YES, YES, NO)
else
call ap_log (Memc[str], YES, NO, NO)
call appstr ("ansdbwrite1", "yes")
call imunmap (im)
call sfree (sp)
end
procedure ap_trfree ()
pointer ic
common /apt_com/ ic
begin
call ic_closer (ic)
end
# AP_CTRACE -- Trace feature positions for aperture axis 2.
procedure ap_ctrace (image, im, ic, start, step, nsum, nlost, cradius, cwidth,
threshold, aps, naps)
char image[ARB] # Image to be traced.
pointer im # IMIO pointer
pointer ic # ICFIT pointer
int start # Starting column
int step # Tracing step size
int nsum # Number of lines or columns to sum
int nlost # Number of steps lost before quiting
real cradius # Centering radius
real cwidth # Centering width
real threshold # Detection threshold for centering
pointer aps[ARB] # Apertures
int naps # Number of apertures
int nlines, col, col1, col2, line1, line2
int i, j, n, nx, ny, ntrace, istart, lost, fd
real yc, yc1
pointer co, data, sp, str, x, y, wts, gp, gt
real center1d(), ap_cveval()
bool ap_answer()
pointer comap(), gt_init()
errchk ap_cveval, xt_csum, xt_csumb, center1d, icg_fit, ic_fit
errchk ap_gopen, ap_popen
begin
# Set up column access buffering.
co = comap (im, MAXBUF)
# Determine the number of lines to be traced and allocate memory.
nx = IM_LEN(im, 1)
ny = IM_LEN(im, 2)
if (IS_INDEFI (start))
start = nx / 2
nlines = 5 * cwidth
istart = (start - 1) / step + 1
ntrace = istart + (nx - start) / step
# Allocate memory for the traced positions and the weights for fitting.
call smark (sp)
call salloc (str, SZ_LINE, TY_CHAR)
call salloc (x, ntrace, TY_REAL)
call salloc (y, ntrace, TY_REAL)
call salloc (wts, ntrace, TY_REAL)
call aclrr (Memr[y], ntrace)
data = NULL
# Initialize the ICFIT limits and the GTOOLS parameters.
# Set initial interactive flag.
call ic_putr (ic, "xmin", 1.)
call ic_putr (ic, "xmax", real (nx))
call ic_pstr (ic, "xlabel", "Column")
call ic_pstr (ic, "ylabel", "Line")
gt = gt_init()
call gt_setr (gt, GTXMIN, 1. - step / 2)
call gt_setr (gt, GTXMAX, real (nx + step / 2))
# Trace each feature.
line1 = 0
line2 = 0
do j = 1, naps {
if (AP_SELECT(aps[j]) == NO)
next
# Trace from the starting column to the last column while the
# position is not INDEF.
lost = 0
yc = AP_CEN(aps[j], 2) + ap_cveval (AP_CV(aps[j]), real (start))
do i = istart, ntrace {
Memr[y+i-1] = INDEF
if (lost < nlost) {
# Update the scrolling buffer if the feature center is less
# than cwidth from the edge of the buffer.
if (((yc-line1) < cwidth) || ((line2-yc) < cwidth)) {
line1 = max (1, int (yc + .5 - nlines / 2))
line2 = min (ny, line1 + nlines - 1)
line1 = max (1, line2 - nlines + 1)
}
# Sum columns to form the 1D vector for centering.
col = start + (i - istart) * step
col1 = max (1, col - nsum / 2)
col2 = min (nx, col1 + nsum - 1)
col1 = max (1, col2 - nsum + 1)
# If columns in the sum overlap then use buffering.
if (step < nsum)
call xt_csumb (co, col1, col2, line1, line2, data)
else
call xt_csum (co, col1, col2, line1, line2, data)
# Center the feature for the new column using the previous
# center as the starting point. Convert to position
# relative to the start of the data buffer for centering
# and then convert back to position relative to the
# edge of the image.
yc1 = center1d (yc-line1+1, Memr[data], line2-line1+1,
cwidth, EMISSION, cradius, threshold)
if (!IS_INDEF (yc1)) {
lost = 0
yc = yc1 + line1 - 1
Memr[y+i-1] = yc
if (IS_INDEF (Memr[y+i-2])) {
call sprintf (Memc[str], SZ_LINE,
"TRACE - Trace of aperture %d in %s recovered at column %d.")
call pargi (AP_ID(aps[j]))
call pargstr (image)
call pargi (col)
call ap_log (Memc[str], YES, NO, YES)
}
} else {
lost = lost + 1
call sprintf (Memc[str], SZ_LINE,
"TRACE - Trace of aperture %d in %s lost at column %d.")
call pargi (AP_ID(aps[j]))
call pargstr (image)
call pargi (col)
call ap_log (Memc[str], YES, NO, YES)
}
}
}
# Trace from the starting column to the first column while the
# position is not INDEF.
lost = 0
yc = AP_CEN(aps[j], 2) + ap_cveval (AP_CV(aps[j]), real (start))
do i = istart - 1, 1, -1 {
Memr[y+i-1] = INDEF
if (lost < nlost) {
# Update the scrolling buffer if the feature center is less
# than cwidth from the edge of the buffer.
if (((yc-line1) < cwidth) || ((line2-yc) < cwidth)) {
line1 = max (1, int (yc + .5 - nlines / 2))
line2 = min (ny, line1 + nlines - 1)
line1 = max (1, line2 - nlines + 1)
}
# Sum columns to form the 1D vector for centering.
col = start + (i - istart) * step
col1 = max (1, col - nsum / 2)
col2 = min (nx, col1 + nsum - 1)
col1 = max (1, col2 - nsum + 1)
# If columns in the sum overlap then use buffering.
if (step < nsum)
call xt_csumb (co, col1, col2, line1, line2, data)
else
call xt_csum (co, col1, col2, line1, line2, data)
# Center the feature for the new column using the previous
# center as the starting point. Convert to position
# relative to the start of the data buffer for centering
# and then convert back to position relative to the
# edge of the image.
yc1 = center1d (yc-line1+1, Memr[data], line2-line1+1,
cwidth, EMISSION, cradius, threshold)
if (!IS_INDEF (yc1)) {
lost = 0
yc = yc1 + line1 - 1
Memr[y+i-1] = yc
if (IS_INDEF (Memr[y+i])) {
call sprintf (Memc[str], SZ_LINE,
"TRACE - Trace of aperture %d in %s recovered at column %d.")
call pargi (AP_ID(aps[j]))
call pargstr (image)
call pargi ((i - 1) * step + 1)
call ap_log (Memc[str], YES, NO, YES)
}
} else {
lost = lost + 1
call sprintf (Memc[str], SZ_LINE,
"TRACE - Trace of aperture %d in %s lost at column %d.")
call pargi (AP_ID(aps[j]))
call pargstr (image)
call pargi ((i - 1) * step + 1)
call ap_log (Memc[str], YES, NO, YES)
}
}
}
# Order the traced points and exclude INDEF positions.
n = 0
do i = 1, ntrace {
if (IS_INDEF (Memr[y+i-1]))
next
n = n + 1
Memr[x+n-1] = start + (i - istart) * step
Memr[y+n-1] = Memr[y+i-1]
Memr[wts+n-1] = 1.
}
# If all positions are INDEF print a message and go on to the next
# aperture.
if (n < 2) {
call eprintf (
"Not enough points traced for aperture %d of %s\n")
call pargi (AP_ID(aps[j]))
call pargstr (image)
next
}
# Fit a curve to the traced positions and graph the result.
call sprintf (Memc[str], SZ_LINE, "Aperture %d of %s")
call pargi (AP_ID(aps[j]))
call pargstr (image)
call gt_sets (gt, GTTITLE, Memc[str])
call sprintf (Memc[str], SZ_LINE,
"Fit curve to aperture %d of %s interactively")
call pargi (AP_ID(aps[j]))
call pargstr (image)
if (ap_answer ("ansfittrace1", Memc[str])) {
call ap_gopen (gp)
call icg_fit (ic, gp, "gcur", gt,
AP_CV(aps[j]), Memr[x], Memr[y], Memr[wts], n)
} else
call ic_fit (ic, AP_CV(aps[j]), Memr[x], Memr[y], Memr[wts], n,
YES, YES, YES, YES)
call ap_popen (gp, fd, "trace")
if (gp != NULL) {
call icg_graphr (ic, gp, gt, AP_CV(aps[j]),
Memr[x], Memr[y], Memr[wts], n)
call ap_pclose (gp, fd)
}
call asubkr (Memr[y], AP_CEN(aps[j], 2), Memr[y], n)
call ic_fit (ic, AP_CV(aps[j]), Memr[x], Memr[y], Memr[wts], n,
YES, YES, YES, YES)
}
# Free allocated memory.
call gt_free (gt)
call mfree (data, TY_REAL)
call counmap (co)
call sfree (sp)
end
# AP_LTRACE -- Trace feature positions for aperture axis 1.
procedure ap_ltrace (image, im, ic, start, step, nsum, nlost, cradius, cwidth,
threshold, aps, naps)
char image[ARB] # Image to be traced
pointer im # IMIO pointer
pointer ic # ICFIT pointer
int start # Starting line
int step # Tracing step size
int nsum # Number of lines or columns to sum
int nlost # Number of steps lost before quiting
real cradius # Centering radius
real cwidth # Centering width
real threshold # Detection threshold for centering
pointer aps[ARB] # Apertures
int naps # Number of apertures
real xc1
int i, j, n, nx, ny, ntrace, istart, line, line1, line2, fd
pointer data, sp, str, x, y, wts, xc, lost, x1, x2, gp, gt
real center1d(), ap_cveval()
bool ap_answer()
pointer gt_init()
errchk ap_cveval, xt_lsum, xt_lsumb, center1d, icg_fit, ic_fit
errchk ap_gopen, ap_popen
begin
# Determine the number of lines to be traced and allocate memory.
nx = IM_LEN(im, 1)
ny = IM_LEN(im, 2)
if (IS_INDEFI (start))
start = ny / 2
istart = (start - 1) / step + 1
ntrace = istart + (ny - start) / step
# Allocate memory for the traced positions and the weights for fitting.
call smark (sp)
call salloc (str, SZ_LINE, TY_CHAR)
call salloc (x, ntrace * naps, TY_REAL)
call salloc (y, ntrace, TY_REAL)
call salloc (wts, ntrace, TY_REAL)
call salloc (xc, naps, TY_REAL)
call salloc (lost, naps, TY_INT)
call aclrr ( Memr[x], ntrace * naps)
data = NULL
# Set the dispersion lines to be traced.
do i = 1, ntrace
Memr[y+i-1] = start + (i - istart) * step
# Trace from the starting line to the last line.
x1 = x + istart - 1
do i = 1, naps {
if (AP_SELECT(aps[i]) == NO)
next
Memr[xc+i-1] = AP_CEN(aps[i], 1) +
ap_cveval (AP_CV(aps[i]), real (start))
Memi[lost+i-1] = 0
}
do i = istart, ntrace {
line = Memr[y+i-1]
line1 = max (1, line - nsum / 2)
line2 = min (ny, line1 + nsum - 1)
line1 = max (1, line2 - nsum + 1)
# If the sums overlap use buffering.
if (step < nsum)
call xt_lsumb (im, 1, nx, line1, line2, data)
else
call xt_lsum (im, 1, nx, line1, line2, data)
do j = 1, naps {
if (AP_SELECT(aps[j]) == NO)
next
x2 = x1 + (j - 1) * ntrace
Memr[x2] = INDEF
if (Memi[lost+j-1] < nlost) {
xc1 = center1d (Memr[xc+j-1], Memr[data], nx,
cwidth, EMISSION, cradius, threshold)
if (IS_INDEF(xc1)) {
Memi[lost+j-1] = Memi[lost+j-1] + 1
call sprintf (Memc[str], SZ_LINE,
"TRACE - Trace of aperture %d in %s lost at line %d.")
call pargi (AP_ID(aps[j]))
call pargstr (image)
call pargi (line)
call ap_log (Memc[str], YES, NO, YES)
} else {
Memi[lost+j-1] = 0
Memr[xc+j-1] = xc1
Memr[x2] = xc1
if (IS_INDEF (Memr[x2-1])) {
call sprintf (Memc[str], SZ_LINE,
"TRACE - Trace of aperture %d in %s recovered at line %d.")
call pargi (AP_ID(aps[j]))
call pargstr (image)
call pargi (line)
call ap_log (Memc[str], YES, NO, YES)
}
}
}
}
x1 = x1 + 1
}
# Trace from the starting line to the first line.
x1 = x + istart - 2
do i = 1, naps {
if (AP_SELECT(aps[i]) == NO)
next
Memr[xc+i-1] = AP_CEN(aps[i], 1) +
ap_cveval (AP_CV(aps[i]), real (start))
Memi[lost+i-1] = 0
}
do i = istart - 1, 1, -1 {
line = Memr[y+i-1]
line1 = max (1, line - nsum / 2)
line2 = min (ny, line1 + nsum - 1)
line1 = max (1, line2 - nsum + 1)
# If the sums overlap use buffering.
if (step < nsum)
call xt_lsumb (im, 1, nx, line1, line2, data)
else
call xt_lsum (im, 1, nx, line1, line2, data)
do j = 1, naps {
if (AP_SELECT(aps[j]) == NO)
next
x2 = x1 + (j - 1) * ntrace
Memr[x2] = INDEF
if (Memi[lost+j-1] < nlost) {
xc1 = center1d (Memr[xc+j-1], Memr[data], nx,
cwidth, EMISSION, cradius, threshold)
if (IS_INDEF(xc1)) {
Memi[lost+j-1] = Memi[lost+j-1] + 1
call sprintf (Memc[str], SZ_LINE,
"TRACE - Trace of aperture %d in %s lost at line %d.")
call pargi (AP_ID(aps[j]))
call pargstr (image)
call pargi (line)
call ap_log (Memc[str], YES, NO, YES)
} else {
Memi[lost+j-1] = 0
Memr[xc+j-1] = xc1
Memr[x2] = xc1
if (IS_INDEF (Memr[x2+1])) {
call sprintf (Memc[str], SZ_LINE,
"TRACE - Trace of aperture %d in %s recovered at line %d.")
call pargi (AP_ID(aps[j]))
call pargstr (image)
call pargi (line)
call ap_log (Memc[str], YES, NO, YES)
}
}
}
}
x1 = x1 - 1
}
# Initialize the the GTOOLS parameters.
call ic_putr (ic, "xmin", 1.)
call ic_putr (ic, "xmax", real (ny))
call ic_pstr (ic, "xlabel", "Line")
call ic_pstr (ic, "ylabel", "Column")
gt = gt_init()
call gt_setr (gt, GTXMIN, 1. - step / 2)
call gt_setr (gt, GTXMAX, real (ny + step / 2))
do j = 1, naps {
if (AP_SELECT(aps[j]) == NO)
next
# Order the traced points and exclude INDEF positions.
x1 = x + (j - 1) * ntrace
n = 0
do i = 1, ntrace {
if (IS_INDEF (Memr[x1+i-1]))
next
n = n + 1
Memr[x1+n-1] = Memr[x1+i-1]
Memr[y+n-1] = start + (i - istart) * step
Memr[wts+n-1] = 1.
}
# If all positions are INDEF print a message and go on to the next
# aperture.
if (n < 2) {
call eprintf (
"Not enough points traced for aperture %d of %s\n")
call pargi (AP_ID(aps[j]))
call pargstr (image)
next
}
# Fit a curve to the traced positions and graph the result.
call sprintf (Memc[str], SZ_LINE, "Aperture %d of %s")
call pargi (AP_ID(aps[j]))
call pargstr (image)
call gt_sets (gt, GTTITLE, Memc[str])
call sprintf (Memc[str], SZ_LINE,
"Fit curve to aperture %d of %s interactively")
call pargi (AP_ID(aps[j]))
call pargstr (image)
if (ap_answer ("ansfittrace1", Memc[str])) {
call ap_gopen (gp)
call icg_fit (ic, gp, "gcur", gt,
AP_CV(aps[j]), Memr[y], Memr[x1], Memr[wts], n)
} else
call ic_fit (ic, AP_CV(aps[j]), Memr[y], Memr[x1], Memr[wts], n,
YES, YES, YES, YES)
call ap_popen (gp, fd, "trace")
if (gp != NULL) {
call icg_graphr (ic, gp, gt, AP_CV(aps[j]),
Memr[y], Memr[x1], Memr[wts], n)
call ap_pclose (gp, fd)
}
# Subtract the aperture center and refit offset curve.
call asubkr (Memr[x1], AP_CEN(aps[j], 1), Memr[x1], n)
call ic_fit (ic, AP_CV(aps[j]), Memr[y], Memr[x1], Memr[wts], n,
YES, YES, YES, YES)
}
# Free allocated memory.
call gt_free (gt)
call mfree (data, TY_REAL)
call sfree (sp)
end
|