summaryrefslogtreecommitdiffstats
path: root/funtools/doc/funtools.ps
blob: 210149e19444a0bbd3d22fd85c6cee207dd89aec (plain)
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
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
1098
1099
1100
1101
1102
1103
1104
1105
1106
1107
1108
1109
1110
1111
1112
1113
1114
1115
1116
1117
1118
1119
1120
1121
1122
1123
1124
1125
1126
1127
1128
1129
1130
1131
1132
1133
1134
1135
1136
1137
1138
1139
1140
1141
1142
1143
1144
1145
1146
1147
1148
1149
1150
1151
1152
1153
1154
1155
1156
1157
1158
1159
1160
1161
1162
1163
1164
1165
1166
1167
1168
1169
1170
1171
1172
1173
1174
1175
1176
1177
1178
1179
1180
1181
1182
1183
1184
1185
1186
1187
1188
1189
1190
1191
1192
1193
1194
1195
1196
1197
1198
1199
1200
1201
1202
1203
1204
1205
1206
1207
1208
1209
1210
1211
1212
1213
1214
1215
1216
1217
1218
1219
1220
1221
1222
1223
1224
1225
1226
1227
1228
1229
1230
1231
1232
1233
1234
1235
1236
1237
1238
1239
1240
1241
1242
1243
1244
1245
1246
1247
1248
1249
1250
1251
1252
1253
1254
1255
1256
1257
1258
1259
1260
1261
1262
1263
1264
1265
1266
1267
1268
1269
1270
1271
1272
1273
1274
1275
1276
1277
1278
1279
1280
1281
1282
1283
1284
1285
1286
1287
1288
1289
1290
1291
1292
1293
1294
1295
1296
1297
1298
1299
1300
1301
1302
1303
1304
1305
1306
1307
1308
1309
1310
1311
1312
1313
1314
1315
1316
1317
1318
1319
1320
1321
1322
1323
1324
1325
1326
1327
1328
1329
1330
1331
1332
1333
1334
1335
1336
1337
1338
1339
1340
1341
1342
1343
1344
1345
1346
1347
1348
1349
1350
1351
1352
1353
1354
1355
1356
1357
1358
1359
1360
1361
1362
1363
1364
1365
1366
1367
1368
1369
1370
1371
1372
1373
1374
1375
1376
1377
1378
1379
1380
1381
1382
1383
1384
1385
1386
1387
1388
1389
1390
1391
1392
1393
1394
1395
1396
1397
1398
1399
1400
1401
1402
1403
1404
1405
1406
1407
1408
1409
1410
1411
1412
1413
1414
1415
1416
1417
1418
1419
1420
1421
1422
1423
1424
1425
1426
1427
1428
1429
1430
1431
1432
1433
1434
1435
1436
1437
1438
1439
1440
1441
1442
1443
1444
1445
1446
1447
1448
1449
1450
1451
1452
1453
1454
1455
1456
1457
1458
1459
1460
1461
1462
1463
1464
1465
1466
1467
1468
1469
1470
1471
1472
1473
1474
1475
1476
1477
1478
1479
1480
1481
1482
1483
1484
1485
1486
1487
1488
1489
1490
1491
1492
1493
1494
1495
1496
1497
1498
1499
1500
1501
1502
1503
1504
1505
1506
1507
1508
1509
1510
1511
1512
1513
1514
1515
1516
1517
1518
1519
1520
1521
1522
1523
1524
1525
1526
1527
1528
1529
1530
1531
1532
1533
1534
1535
1536
1537
1538
1539
1540
1541
1542
1543
1544
1545
1546
1547
1548
1549
1550
1551
1552
1553
1554
1555
1556
1557
1558
1559
1560
1561
1562
1563
1564
1565
1566
1567
1568
1569
1570
1571
1572
1573
1574
1575
1576
1577
1578
1579
1580
1581
1582
1583
1584
1585
1586
1587
1588
1589
1590
1591
1592
1593
1594
1595
1596
1597
1598
1599
1600
1601
1602
1603
1604
1605
1606
1607
1608
1609
1610
1611
1612
1613
1614
1615
1616
1617
1618
1619
1620
1621
1622
1623
1624
1625
1626
1627
1628
1629
1630
1631
1632
1633
1634
1635
1636
1637
1638
1639
1640
1641
1642
1643
1644
1645
1646
1647
1648
1649
1650
1651
1652
1653
1654
1655
1656
1657
1658
1659
1660
1661
1662
1663
1664
1665
1666
1667
1668
1669
1670
1671
1672
1673
1674
1675
1676
1677
1678
1679
1680
1681
1682
1683
1684
1685
1686
1687
1688
1689
1690
1691
1692
1693
1694
1695
1696
1697
1698
1699
1700
1701
1702
1703
1704
1705
1706
1707
1708
1709
1710
1711
1712
1713
1714
1715
1716
1717
1718
1719
1720
1721
1722
1723
1724
1725
1726
1727
1728
1729
1730
1731
1732
1733
1734
1735
1736
1737
1738
1739
1740
1741
1742
1743
1744
1745
1746
1747
1748
1749
1750
1751
1752
1753
1754
1755
1756
1757
1758
1759
1760
1761
1762
1763
1764
1765
1766
1767
1768
1769
1770
1771
1772
1773
1774
1775
1776
1777
1778
1779
1780
1781
1782
1783
1784
1785
1786
1787
1788
1789
1790
1791
1792
1793
1794
1795
1796
1797
1798
1799
1800
1801
1802
1803
1804
1805
1806
1807
1808
1809
1810
1811
1812
1813
1814
1815
1816
1817
1818
1819
1820
1821
1822
1823
1824
1825
1826
1827
1828
1829
1830
1831
1832
1833
1834
1835
1836
1837
1838
1839
1840
1841
1842
1843
1844
1845
1846
1847
1848
1849
1850
1851
1852
1853
1854
1855
1856
1857
1858
1859
1860
1861
1862
1863
1864
1865
1866
1867
1868
1869
1870
1871
1872
1873
1874
1875
1876
1877
1878
1879
1880
1881
1882
1883
1884
1885
1886
1887
1888
1889
1890
1891
1892
1893
1894
1895
1896
1897
1898
1899
1900
1901
1902
1903
1904
1905
1906
1907
1908
1909
1910
1911
1912
1913
1914
1915
1916
1917
1918
1919
1920
1921
1922
1923
1924
1925
1926
1927
1928
1929
1930
1931
1932
1933
1934
1935
1936
1937
1938
1939
1940
1941
1942
1943
1944
1945
1946
1947
1948
1949
1950
1951
1952
1953
1954
1955
1956
1957
1958
1959
1960
1961
1962
1963
1964
1965
1966
1967
1968
1969
1970
1971
1972
1973
1974
1975
1976
1977
1978
1979
1980
1981
1982
1983
1984
1985
1986
1987
1988
1989
1990
1991
1992
1993
1994
1995
1996
1997
1998
1999
2000
2001
2002
2003
2004
2005
2006
2007
2008
2009
2010
2011
2012
2013
2014
2015
2016
2017
2018
2019
2020
2021
2022
2023
2024
2025
2026
2027
2028
2029
2030
2031
2032
2033
2034
2035
2036
2037
2038
2039
2040
2041
2042
2043
2044
2045
2046
2047
2048
2049
2050
2051
2052
2053
2054
2055
2056
2057
2058
2059
2060
2061
2062
2063
2064
2065
2066
2067
2068
2069
2070
2071
2072
2073
2074
2075
2076
2077
2078
2079
2080
2081
2082
2083
2084
2085
2086
2087
2088
2089
2090
2091
2092
2093
2094
2095
2096
2097
2098
2099
2100
2101
2102
2103
2104
2105
2106
2107
2108
2109
2110
2111
2112
2113
2114
2115
2116
2117
2118
2119
2120
2121
2122
2123
2124
2125
2126
2127
2128
2129
2130
2131
2132
2133
2134
2135
2136
2137
2138
2139
2140
2141
2142
2143
2144
2145
2146
2147
2148
2149
2150
2151
2152
2153
2154
2155
2156
2157
2158
2159
2160
2161
2162
2163
2164
2165
2166
2167
2168
2169
2170
2171
2172
2173
2174
2175
2176
2177
2178
2179
2180
2181
2182
2183
2184
2185
2186
2187
2188
2189
2190
2191
2192
2193
2194
2195
2196
2197
2198
2199
2200
2201
2202
2203
2204
2205
2206
2207
2208
2209
2210
2211
2212
2213
2214
2215
2216
2217
2218
2219
2220
2221
2222
2223
2224
2225
2226
2227
2228
2229
2230
2231
2232
2233
2234
2235
2236
2237
2238
2239
2240
2241
2242
2243
2244
2245
2246
2247
2248
2249
2250
2251
2252
2253
2254
2255
2256
2257
2258
2259
2260
2261
2262
2263
2264
2265
2266
2267
2268
2269
2270
2271
2272
2273
2274
2275
2276
2277
2278
2279
2280
2281
2282
2283
2284
2285
2286
2287
2288
2289
2290
2291
2292
2293
2294
2295
2296
2297
2298
2299
2300
2301
2302
2303
2304
2305
2306
2307
2308
2309
2310
2311
2312
2313
2314
2315
2316
2317
2318
2319
2320
2321
2322
2323
2324
2325
2326
2327
2328
2329
2330
2331
2332
2333
2334
2335
2336
2337
2338
2339
2340
2341
2342
2343
2344
2345
2346
2347
2348
2349
2350
2351
2352
2353
2354
2355
2356
2357
2358
2359
2360
2361
2362
2363
2364
2365
2366
2367
2368
2369
2370
2371
2372
2373
2374
2375
2376
2377
2378
2379
2380
2381
2382
2383
2384
2385
2386
2387
2388
2389
2390
2391
2392
2393
2394
2395
2396
2397
2398
2399
2400
2401
2402
2403
2404
2405
2406
2407
2408
2409
2410
2411
2412
2413
2414
2415
2416
2417
2418
2419
2420
2421
2422
2423
2424
2425
2426
2427
2428
2429
2430
2431
2432
2433
2434
2435
2436
2437
2438
2439
2440
2441
2442
2443
2444
2445
2446
2447
2448
2449
2450
2451
2452
2453
2454
2455
2456
2457
2458
2459
2460
2461
2462
2463
2464
2465
2466
2467
2468
2469
2470
2471
2472
2473
2474
2475
2476
2477
2478
2479
2480
2481
2482
2483
2484
2485
2486
2487
2488
2489
2490
2491
2492
2493
2494
2495
2496
2497
2498
2499
2500
2501
2502
2503
2504
2505
2506
2507
2508
2509
2510
2511
2512
2513
2514
2515
2516
2517
2518
2519
2520
2521
2522
2523
2524
2525
2526
2527
2528
2529
2530
2531
2532
2533
2534
2535
2536
2537
2538
2539
2540
2541
2542
2543
2544
2545
2546
2547
2548
2549
2550
2551
2552
2553
2554
2555
2556
2557
2558
2559
2560
2561
2562
2563
2564
2565
2566
2567
2568
2569
2570
2571
2572
2573
2574
2575
2576
2577
2578
2579
2580
2581
2582
2583
2584
2585
2586
2587
2588
2589
2590
2591
2592
2593
2594
2595
2596
2597
2598
2599
2600
2601
2602
2603
2604
2605
2606
2607
2608
2609
2610
2611
2612
2613
2614
2615
2616
2617
2618
2619
2620
2621
2622
2623
2624
2625
2626
2627
2628
2629
2630
2631
2632
2633
2634
2635
2636
2637
2638
2639
2640
2641
2642
2643
2644
2645
2646
2647
2648
2649
2650
2651
2652
2653
2654
2655
2656
2657
2658
2659
2660
2661
2662
2663
2664
2665
2666
2667
2668
2669
2670
2671
2672
2673
2674
2675
2676
2677
2678
2679
2680
2681
2682
2683
2684
2685
2686
2687
2688
2689
2690
2691
2692
2693
2694
2695
2696
2697
2698
2699
2700
2701
2702
2703
2704
2705
2706
2707
2708
2709
2710
2711
2712
2713
2714
2715
2716
2717
2718
2719
2720
2721
2722
2723
2724
2725
2726
2727
2728
2729
2730
2731
2732
2733
2734
2735
2736
2737
2738
2739
2740
2741
2742
2743
2744
2745
2746
2747
2748
2749
2750
2751
2752
2753
2754
2755
2756
2757
2758
2759
2760
2761
2762
2763
2764
2765
2766
2767
2768
2769
2770
2771
2772
2773
2774
2775
2776
2777
2778
2779
2780
2781
2782
2783
2784
2785
2786
2787
2788
2789
2790
2791
2792
2793
2794
2795
2796
2797
2798
2799
2800
2801
2802
2803
2804
2805
2806
2807
2808
2809
2810
2811
2812
2813
2814
2815
2816
2817
2818
2819
2820
2821
2822
2823
2824
2825
2826
2827
2828
2829
2830
2831
2832
2833
2834
2835
2836
2837
2838
2839
2840
2841
2842
2843
2844
2845
2846
2847
2848
2849
2850
2851
2852
2853
2854
2855
2856
2857
2858
2859
2860
2861
2862
2863
2864
2865
2866
2867
2868
2869
2870
2871
2872
2873
2874
2875
2876
2877
2878
2879
2880
2881
2882
2883
2884
2885
2886
2887
2888
2889
2890
2891
2892
2893
2894
2895
2896
2897
2898
2899
2900
2901
2902
2903
2904
2905
2906
2907
2908
2909
2910
2911
2912
2913
2914
2915
2916
2917
2918
2919
2920
2921
2922
2923
2924
2925
2926
2927
2928
2929
2930
2931
2932
2933
2934
2935
2936
2937
2938
2939
2940
2941
2942
2943
2944
2945
2946
2947
2948
2949
2950
2951
2952
2953
2954
2955
2956
2957
2958
2959
2960
2961
2962
2963
2964
2965
2966
2967
2968
2969
2970
2971
2972
2973
2974
2975
2976
2977
2978
2979
2980
2981
2982
2983
2984
2985
2986
2987
2988
2989
2990
2991
2992
2993
2994
2995
2996
2997
2998
2999
3000
3001
3002
3003
3004
3005
3006
3007
3008
3009
3010
3011
3012
3013
3014
3015
3016
3017
3018
3019
3020
3021
3022
3023
3024
3025
3026
3027
3028
3029
3030
3031
3032
3033
3034
3035
3036
3037
3038
3039
3040
3041
3042
3043
3044
3045
3046
3047
3048
3049
3050
3051
3052
3053
3054
3055
3056
3057
3058
3059
3060
3061
3062
3063
3064
3065
3066
3067
3068
3069
3070
3071
3072
3073
3074
3075
3076
3077
3078
3079
3080
3081
3082
3083
3084
3085
3086
3087
3088
3089
3090
3091
3092
3093
3094
3095
3096
3097
3098
3099
3100
3101
3102
3103
3104
3105
3106
3107
3108
3109
3110
3111
3112
3113
3114
3115
3116
3117
3118
3119
3120
3121
3122
3123
3124
3125
3126
3127
3128
3129
3130
3131
3132
3133
3134
3135
3136
3137
3138
3139
3140
3141
3142
3143
3144
3145
3146
3147
3148
3149
3150
3151
3152
3153
3154
3155
3156
3157
3158
3159
3160
3161
3162
3163
3164
3165
3166
3167
3168
3169
3170
3171
3172
3173
3174
3175
3176
3177
3178
3179
3180
3181
3182
3183
3184
3185
3186
3187
3188
3189
3190
3191
3192
3193
3194
3195
3196
3197
3198
3199
3200
3201
3202
3203
3204
3205
3206
3207
3208
3209
3210
3211
3212
3213
3214
3215
3216
3217
3218
3219
3220
3221
3222
3223
3224
3225
3226
3227
3228
3229
3230
3231
3232
3233
3234
3235
3236
3237
3238
3239
3240
3241
3242
3243
3244
3245
3246
3247
3248
3249
3250
3251
3252
3253
3254
3255
3256
3257
3258
3259
3260
3261
3262
3263
3264
3265
3266
3267
3268
3269
3270
3271
3272
3273
3274
3275
3276
3277
3278
3279
3280
3281
3282
3283
3284
3285
3286
3287
3288
3289
3290
3291
3292
3293
3294
3295
3296
3297
3298
3299
3300
3301
3302
3303
3304
3305
3306
3307
3308
3309
3310
3311
3312
3313
3314
3315
3316
3317
3318
3319
3320
3321
3322
3323
3324
3325
3326
3327
3328
3329
3330
3331
3332
3333
3334
3335
3336
3337
3338
3339
3340
3341
3342
3343
3344
3345
3346
3347
3348
3349
3350
3351
3352
3353
3354
3355
3356
3357
3358
3359
3360
3361
3362
3363
3364
3365
3366
3367
3368
3369
3370
3371
3372
3373
3374
3375
3376
3377
3378
3379
3380
3381
3382
3383
3384
3385
3386
3387
3388
3389
3390
3391
3392
3393
3394
3395
3396
3397
3398
3399
3400
3401
3402
3403
3404
3405
3406
3407
3408
3409
3410
3411
3412
3413
3414
3415
3416
3417
3418
3419
3420
3421
3422
3423
3424
3425
3426
3427
3428
3429
3430
3431
3432
3433
3434
3435
3436
3437
3438
3439
3440
3441
3442
3443
3444
3445
3446
3447
3448
3449
3450
3451
3452
3453
3454
3455
3456
3457
3458
3459
3460
3461
3462
3463
3464
3465
3466
3467
3468
3469
3470
3471
3472
3473
3474
3475
3476
3477
3478
3479
3480
3481
3482
3483
3484
3485
3486
3487
3488
3489
3490
3491
3492
3493
3494
3495
3496
3497
3498
3499
3500
3501
3502
3503
3504
3505
3506
3507
3508
3509
3510
3511
3512
3513
3514
3515
3516
3517
3518
3519
3520
3521
3522
3523
3524
3525
3526
3527
3528
3529
3530
3531
3532
3533
3534
3535
3536
3537
3538
3539
3540
3541
3542
3543
3544
3545
3546
3547
3548
3549
3550
3551
3552
3553
3554
3555
3556
3557
3558
3559
3560
3561
3562
3563
3564
3565
3566
3567
3568
3569
3570
3571
3572
3573
3574
3575
3576
3577
3578
3579
3580
3581
3582
3583
3584
3585
3586
3587
3588
3589
3590
3591
3592
3593
3594
3595
3596
3597
3598
3599
3600
3601
3602
3603
3604
3605
3606
3607
3608
3609
3610
3611
3612
3613
3614
3615
3616
3617
3618
3619
3620
3621
3622
3623
3624
3625
3626
3627
3628
3629
3630
3631
3632
3633
3634
3635
3636
3637
3638
3639
3640
3641
3642
3643
3644
3645
3646
3647
3648
3649
3650
3651
3652
3653
3654
3655
3656
3657
3658
3659
3660
3661
3662
3663
3664
3665
3666
3667
3668
3669
3670
3671
3672
3673
3674
3675
3676
3677
3678
3679
3680
3681
3682
3683
3684
3685
3686
3687
3688
3689
3690
3691
3692
3693
3694
3695
3696
3697
3698
3699
3700
3701
3702
3703
3704
3705
3706
3707
3708
3709
3710
3711
3712
3713
3714
3715
3716
3717
3718
3719
3720
3721
3722
3723
3724
3725
3726
3727
3728
3729
3730
3731
3732
3733
3734
3735
3736
3737
3738
3739
3740
3741
3742
3743
3744
3745
3746
3747
3748
3749
3750
3751
3752
3753
3754
3755
3756
3757
3758
3759
3760
3761
3762
3763
3764
3765
3766
3767
3768
3769
3770
3771
3772
3773
3774
3775
3776
3777
3778
3779
3780
3781
3782
3783
3784
3785
3786
3787
3788
3789
3790
3791
3792
3793
3794
3795
3796
3797
3798
3799
3800
3801
3802
3803
3804
3805
3806
3807
3808
3809
3810
3811
3812
3813
3814
3815
3816
3817
3818
3819
3820
3821
3822
3823
3824
3825
3826
3827
3828
3829
3830
3831
3832
3833
3834
3835
3836
3837
3838
3839
3840
3841
3842
3843
3844
3845
3846
3847
3848
3849
3850
3851
3852
3853
3854
3855
3856
3857
3858
3859
3860
3861
3862
3863
3864
3865
3866
3867
3868
3869
3870
3871
3872
3873
3874
3875
3876
3877
3878
3879
3880
3881
3882
3883
3884
3885
3886
3887
3888
3889
3890
3891
3892
3893
3894
3895
3896
3897
3898
3899
3900
3901
3902
3903
3904
3905
3906
3907
3908
3909
3910
3911
3912
3913
3914
3915
3916
3917
3918
3919
3920
3921
3922
3923
3924
3925
3926
3927
3928
3929
3930
3931
3932
3933
3934
3935
3936
3937
3938
3939
3940
3941
3942
3943
3944
3945
3946
3947
3948
3949
3950
3951
3952
3953
3954
3955
3956
3957
3958
3959
3960
3961
3962
3963
3964
3965
3966
3967
3968
3969
3970
3971
3972
3973
3974
3975
3976
3977
3978
3979
3980
3981
3982
3983
3984
3985
3986
3987
3988
3989
3990
3991
3992
3993
3994
3995
3996
3997
3998
3999
4000
4001
4002
4003
4004
4005
4006
4007
4008
4009
4010
4011
4012
4013
4014
4015
4016
4017
4018
4019
4020
4021
4022
4023
4024
4025
4026
4027
4028
4029
4030
4031
4032
4033
4034
4035
4036
4037
4038
4039
4040
4041
4042
4043
4044
4045
4046
4047
4048
4049
4050
4051
4052
4053
4054
4055
4056
4057
4058
4059
4060
4061
4062
4063
4064
4065
4066
4067
4068
4069
4070
4071
4072
4073
4074
4075
4076
4077
4078
4079
4080
4081
4082
4083
4084
4085
4086
4087
4088
4089
4090
4091
4092
4093
4094
4095
4096
4097
4098
4099
4100
4101
4102
4103
4104
4105
4106
4107
4108
4109
4110
4111
4112
4113
4114
4115
4116
4117
4118
4119
4120
4121
4122
4123
4124
4125
4126
4127
4128
4129
4130
4131
4132
4133
4134
4135
4136
4137
4138
4139
4140
4141
4142
4143
4144
4145
4146
4147
4148
4149
4150
4151
4152
4153
4154
4155
4156
4157
4158
4159
4160
4161
4162
4163
4164
4165
4166
4167
4168
4169
4170
4171
4172
4173
4174
4175
4176
4177
4178
4179
4180
4181
4182
4183
4184
4185
4186
4187
4188
4189
4190
4191
4192
4193
4194
4195
4196
4197
4198
4199
4200
4201
4202
4203
4204
4205
4206
4207
4208
4209
4210
4211
4212
4213
4214
4215
4216
4217
4218
4219
4220
4221
4222
4223
4224
4225
4226
4227
4228
4229
4230
4231
4232
4233
4234
4235
4236
4237
4238
4239
4240
4241
4242
4243
4244
4245
4246
4247
4248
4249
4250
4251
4252
4253
4254
4255
4256
4257
4258
4259
4260
4261
4262
4263
4264
4265
4266
4267
4268
4269
4270
4271
4272
4273
4274
4275
4276
4277
4278
4279
4280
4281
4282
4283
4284
4285
4286
4287
4288
4289
4290
4291
4292
4293
4294
4295
4296
4297
4298
4299
4300
4301
4302
4303
4304
4305
4306
4307
4308
4309
4310
4311
4312
4313
4314
4315
4316
4317
4318
4319
4320
4321
4322
4323
4324
4325
4326
4327
4328
4329
4330
4331
4332
4333
4334
4335
4336
4337
4338
4339
4340
4341
4342
4343
4344
4345
4346
4347
4348
4349
4350
4351
4352
4353
4354
4355
4356
4357
4358
4359
4360
4361
4362
4363
4364
4365
4366
4367
4368
4369
4370
4371
4372
4373
4374
4375
4376
4377
4378
4379
4380
4381
4382
4383
4384
4385
4386
4387
4388
4389
4390
4391
4392
4393
4394
4395
4396
4397
4398
4399
4400
4401
4402
4403
4404
4405
4406
4407
4408
4409
4410
4411
4412
4413
4414
4415
4416
4417
4418
4419
4420
4421
4422
4423
4424
4425
4426
4427
4428
4429
4430
4431
4432
4433
4434
4435
4436
4437
4438
4439
4440
4441
4442
4443
4444
4445
4446
4447
4448
4449
4450
4451
4452
4453
4454
4455
4456
4457
4458
4459
4460
4461
4462
4463
4464
4465
4466
4467
4468
4469
4470
4471
4472
4473
4474
4475
4476
4477
4478
4479
4480
4481
4482
4483
4484
4485
4486
4487
4488
4489
4490
4491
4492
4493
4494
4495
4496
4497
4498
4499
4500
4501
4502
4503
4504
4505
4506
4507
4508
4509
4510
4511
4512
4513
4514
4515
4516
4517
4518
4519
4520
4521
4522
4523
4524
4525
4526
4527
4528
4529
4530
4531
4532
4533
4534
4535
4536
4537
4538
4539
4540
4541
4542
4543
4544
4545
4546
4547
4548
4549
4550
4551
4552
4553
4554
4555
4556
4557
4558
4559
4560
4561
4562
4563
4564
4565
4566
4567
4568
4569
4570
4571
4572
4573
4574
4575
4576
4577
4578
4579
4580
4581
4582
4583
4584
4585
4586
4587
4588
4589
4590
4591
4592
4593
4594
4595
4596
4597
4598
4599
4600
4601
4602
4603
4604
4605
4606
4607
4608
4609
4610
4611
4612
4613
4614
4615
4616
4617
4618
4619
4620
4621
4622
4623
4624
4625
4626
4627
4628
4629
4630
4631
4632
4633
4634
4635
4636
4637
4638
4639
4640
4641
4642
4643
4644
4645
4646
4647
4648
4649
4650
4651
4652
4653
4654
4655
4656
4657
4658
4659
4660
4661
4662
4663
4664
4665
4666
4667
4668
4669
4670
4671
4672
4673
4674
4675
4676
4677
4678
4679
4680
4681
4682
4683
4684
4685
4686
4687
4688
4689
4690
4691
4692
4693
4694
4695
4696
4697
4698
4699
4700
4701
4702
4703
4704
4705
4706
4707
4708
4709
4710
4711
4712
4713
4714
4715
4716
4717
4718
4719
4720
4721
4722
4723
4724
4725
4726
4727
4728
4729
4730
4731
4732
4733
4734
4735
4736
4737
4738
4739
4740
4741
4742
4743
4744
4745
4746
4747
4748
4749
4750
4751
4752
4753
4754
4755
4756
4757
4758
4759
4760
4761
4762
4763
4764
4765
4766
4767
4768
4769
4770
4771
4772
4773
4774
4775
4776
4777
4778
4779
4780
4781
4782
4783
4784
4785
4786
4787
4788
4789
4790
4791
4792
4793
4794
4795
4796
4797
4798
4799
4800
4801
4802
4803
4804
4805
4806
4807
4808
4809
4810
4811
4812
4813
4814
4815
4816
4817
4818
4819
4820
4821
4822
4823
4824
4825
4826
4827
4828
4829
4830
4831
4832
4833
4834
4835
4836
4837
4838
4839
4840
4841
4842
4843
4844
4845
4846
4847
4848
4849
4850
4851
4852
4853
4854
4855
4856
4857
4858
4859
4860
4861
4862
4863
4864
4865
4866
4867
4868
4869
4870
4871
4872
4873
4874
4875
4876
4877
4878
4879
4880
4881
4882
4883
4884
4885
4886
4887
4888
4889
4890
4891
4892
4893
4894
4895
4896
4897
4898
4899
4900
4901
4902
4903
4904
4905
4906
4907
4908
4909
4910
4911
4912
4913
4914
4915
4916
4917
4918
4919
4920
4921
4922
4923
4924
4925
4926
4927
4928
4929
4930
4931
4932
4933
4934
4935
4936
4937
4938
4939
4940
4941
4942
4943
4944
4945
4946
4947
4948
4949
4950
4951
4952
4953
4954
4955
4956
4957
4958
4959
4960
4961
4962
4963
4964
4965
4966
4967
4968
4969
4970
4971
4972
4973
4974
4975
4976
4977
4978
4979
4980
4981
4982
4983
4984
4985
4986
4987
4988
4989
4990
4991
4992
4993
4994
4995
4996
4997
4998
4999
5000
5001
5002
5003
5004
5005
5006
5007
5008
5009
5010
5011
5012
5013
5014
5015
5016
5017
5018
5019
5020
5021
5022
5023
5024
5025
5026
5027
5028
5029
5030
5031
5032
5033
5034
5035
5036
5037
5038
5039
5040
5041
5042
5043
5044
5045
5046
5047
5048
5049
5050
5051
5052
5053
5054
5055
5056
5057
5058
5059
5060
5061
5062
5063
5064
5065
5066
5067
5068
5069
5070
5071
5072
5073
5074
5075
5076
5077
5078
5079
5080
5081
5082
5083
5084
5085
5086
5087
5088
5089
5090
5091
5092
5093
5094
5095
5096
5097
5098
5099
5100
5101
5102
5103
5104
5105
5106
5107
5108
5109
5110
5111
5112
5113
5114
5115
5116
5117
5118
5119
5120
5121
5122
5123
5124
5125
5126
5127
5128
5129
5130
5131
5132
5133
5134
5135
5136
5137
5138
5139
5140
5141
5142
5143
5144
5145
5146
5147
5148
5149
5150
5151
5152
5153
5154
5155
5156
5157
5158
5159
5160
5161
5162
5163
5164
5165
5166
5167
5168
5169
5170
5171
5172
5173
5174
5175
5176
5177
5178
5179
5180
5181
5182
5183
5184
5185
5186
5187
5188
5189
5190
5191
5192
5193
5194
5195
5196
5197
5198
5199
5200
5201
5202
5203
5204
5205
5206
5207
5208
5209
5210
5211
5212
5213
5214
5215
5216
5217
5218
5219
5220
5221
5222
5223
5224
5225
5226
5227
5228
5229
5230
5231
5232
5233
5234
5235
5236
5237
5238
5239
5240
5241
5242
5243
5244
5245
5246
5247
5248
5249
5250
5251
5252
5253
5254
5255
5256
5257
5258
5259
5260
5261
5262
5263
5264
5265
5266
5267
5268
5269
5270
5271
5272
5273
5274
5275
5276
5277
5278
5279
5280
5281
5282
5283
5284
5285
5286
5287
5288
5289
5290
5291
5292
5293
5294
5295
5296
5297
5298
5299
5300
5301
5302
5303
5304
5305
5306
5307
5308
5309
5310
5311
5312
5313
5314
5315
5316
5317
5318
5319
5320
5321
5322
5323
5324
5325
5326
5327
5328
5329
5330
5331
5332
5333
5334
5335
5336
5337
5338
5339
5340
5341
5342
5343
5344
5345
5346
5347
5348
5349
5350
5351
5352
5353
5354
5355
5356
5357
5358
5359
5360
5361
5362
5363
5364
5365
5366
5367
5368
5369
5370
5371
5372
5373
5374
5375
5376
5377
5378
5379
5380
5381
5382
5383
5384
5385
5386
5387
5388
5389
5390
5391
5392
5393
5394
5395
5396
5397
5398
5399
5400
5401
5402
5403
5404
5405
5406
5407
5408
5409
5410
5411
5412
5413
5414
5415
5416
5417
5418
5419
5420
5421
5422
5423
5424
5425
5426
5427
5428
5429
5430
5431
5432
5433
5434
5435
5436
5437
5438
5439
5440
5441
5442
5443
5444
5445
5446
5447
5448
5449
5450
5451
5452
5453
5454
5455
5456
5457
5458
5459
5460
5461
5462
5463
5464
5465
5466
5467
5468
5469
5470
5471
5472
5473
5474
5475
5476
5477
5478
5479
5480
5481
5482
5483
5484
5485
5486
5487
5488
5489
5490
5491
5492
5493
5494
5495
5496
5497
5498
5499
5500
5501
5502
5503
5504
5505
5506
5507
5508
5509
5510
5511
5512
5513
5514
5515
5516
5517
5518
5519
5520
5521
5522
5523
5524
5525
5526
5527
5528
5529
5530
5531
5532
5533
5534
5535
5536
5537
5538
5539
5540
5541
5542
5543
5544
5545
5546
5547
5548
5549
5550
5551
5552
5553
5554
5555
5556
5557
5558
5559
5560
5561
5562
5563
5564
5565
5566
5567
5568
5569
5570
5571
5572
5573
5574
5575
5576
5577
5578
5579
5580
5581
5582
5583
5584
5585
5586
5587
5588
5589
5590
5591
5592
5593
5594
5595
5596
5597
5598
5599
5600
5601
5602
5603
5604
5605
5606
5607
5608
5609
5610
5611
5612
5613
5614
5615
5616
5617
5618
5619
5620
5621
5622
5623
5624
5625
5626
5627
5628
5629
5630
5631
5632
5633
5634
5635
5636
5637
5638
5639
5640
5641
5642
5643
5644
5645
5646
5647
5648
5649
5650
5651
5652
5653
5654
5655
5656
5657
5658
5659
5660
5661
5662
5663
5664
5665
5666
5667
5668
5669
5670
5671
5672
5673
5674
5675
5676
5677
5678
5679
5680
5681
5682
5683
5684
5685
5686
5687
5688
5689
5690
5691
5692
5693
5694
5695
5696
5697
5698
5699
5700
5701
5702
5703
5704
5705
5706
5707
5708
5709
5710
5711
5712
5713
5714
5715
5716
5717
5718
5719
5720
5721
5722
5723
5724
5725
5726
5727
5728
5729
5730
5731
5732
5733
5734
5735
5736
5737
5738
5739
5740
5741
5742
5743
5744
5745
5746
5747
5748
5749
5750
5751
5752
5753
5754
5755
5756
5757
5758
5759
5760
5761
5762
5763
5764
5765
5766
5767
5768
5769
5770
5771
5772
5773
5774
5775
5776
5777
5778
5779
5780
5781
5782
5783
5784
5785
5786
5787
5788
5789
5790
5791
5792
5793
5794
5795
5796
5797
5798
5799
5800
5801
5802
5803
5804
5805
5806
5807
5808
5809
5810
5811
5812
5813
5814
5815
5816
5817
5818
5819
5820
5821
5822
5823
5824
5825
5826
5827
5828
5829
5830
5831
5832
5833
5834
5835
5836
5837
5838
5839
5840
5841
5842
5843
5844
5845
5846
5847
5848
5849
5850
5851
5852
5853
5854
5855
5856
5857
5858
5859
5860
5861
5862
5863
5864
5865
5866
5867
5868
5869
5870
5871
5872
5873
5874
5875
5876
5877
5878
5879
5880
5881
5882
5883
5884
5885
5886
5887
5888
5889
5890
5891
5892
5893
5894
5895
5896
5897
5898
5899
5900
5901
5902
5903
5904
5905
5906
5907
5908
5909
5910
5911
5912
5913
5914
5915
5916
5917
5918
5919
5920
5921
5922
5923
5924
5925
5926
5927
5928
5929
5930
5931
5932
5933
5934
5935
5936
5937
5938
5939
5940
5941
5942
5943
5944
5945
5946
5947
5948
5949
5950
5951
5952
5953
5954
5955
5956
5957
5958
5959
5960
5961
5962
5963
5964
5965
5966
5967
5968
5969
5970
5971
5972
5973
5974
5975
5976
5977
5978
5979
5980
5981
5982
5983
5984
5985
5986
5987
5988
5989
5990
5991
5992
5993
5994
5995
5996
5997
5998
5999
6000
6001
6002
6003
6004
6005
6006
6007
6008
6009
6010
6011
6012
6013
6014
6015
6016
6017
6018
6019
6020
6021
6022
6023
6024
6025
6026
6027
6028
6029
6030
6031
6032
6033
6034
6035
6036
6037
6038
6039
6040
6041
6042
6043
6044
6045
6046
6047
6048
6049
6050
6051
6052
6053
6054
6055
6056
6057
6058
6059
6060
6061
6062
6063
6064
6065
6066
6067
6068
6069
6070
6071
6072
6073
6074
6075
6076
6077
6078
6079
6080
6081
6082
6083
6084
6085
6086
6087
6088
6089
6090
6091
6092
6093
6094
6095
6096
6097
6098
6099
6100
6101
6102
6103
6104
6105
6106
6107
6108
6109
6110
6111
6112
6113
6114
6115
6116
6117
6118
6119
6120
6121
6122
6123
6124
6125
6126
6127
6128
6129
6130
6131
6132
6133
6134
6135
6136
6137
6138
6139
6140
6141
6142
6143
6144
6145
6146
6147
6148
6149
6150
6151
6152
6153
6154
6155
6156
6157
6158
6159
6160
6161
6162
6163
6164
6165
6166
6167
6168
6169
6170
6171
6172
6173
6174
6175
6176
6177
6178
6179
6180
6181
6182
6183
6184
6185
6186
6187
6188
6189
6190
6191
6192
6193
6194
6195
6196
6197
6198
6199
6200
6201
6202
6203
6204
6205
6206
6207
6208
6209
6210
6211
6212
6213
6214
6215
6216
6217
6218
6219
6220
6221
6222
6223
6224
6225
6226
6227
6228
6229
6230
6231
6232
6233
6234
6235
6236
6237
6238
6239
6240
6241
6242
6243
6244
6245
6246
6247
6248
6249
6250
6251
6252
6253
6254
6255
6256
6257
6258
6259
6260
6261
6262
6263
6264
6265
6266
6267
6268
6269
6270
6271
6272
6273
6274
6275
6276
6277
6278
6279
6280
6281
6282
6283
6284
6285
6286
6287
6288
6289
6290
6291
6292
6293
6294
6295
6296
6297
6298
6299
6300
6301
6302
6303
6304
6305
6306
6307
6308
6309
6310
6311
6312
6313
6314
6315
6316
6317
6318
6319
6320
6321
6322
6323
6324
6325
6326
6327
6328
6329
6330
6331
6332
6333
6334
6335
6336
6337
6338
6339
6340
6341
6342
6343
6344
6345
6346
6347
6348
6349
6350
6351
6352
6353
6354
6355
6356
6357
6358
6359
6360
6361
6362
6363
6364
6365
6366
6367
6368
6369
6370
6371
6372
6373
6374
6375
6376
6377
6378
6379
6380
6381
6382
6383
6384
6385
6386
6387
6388
6389
6390
6391
6392
6393
6394
6395
6396
6397
6398
6399
6400
6401
6402
6403
6404
6405
6406
6407
6408
6409
6410
6411
6412
6413
6414
6415
6416
6417
6418
6419
6420
6421
6422
6423
6424
6425
6426
6427
6428
6429
6430
6431
6432
6433
6434
6435
6436
6437
6438
6439
6440
6441
6442
6443
6444
6445
6446
6447
6448
6449
6450
6451
6452
6453
6454
6455
6456
6457
6458
6459
6460
6461
6462
6463
6464
6465
6466
6467
6468
6469
6470
6471
6472
6473
6474
6475
6476
6477
6478
6479
6480
6481
6482
6483
6484
6485
6486
6487
6488
6489
6490
6491
6492
6493
6494
6495
6496
6497
6498
6499
6500
6501
6502
6503
6504
6505
6506
6507
6508
6509
6510
6511
6512
6513
6514
6515
6516
6517
6518
6519
6520
6521
6522
6523
6524
6525
6526
6527
6528
6529
6530
6531
6532
6533
6534
6535
6536
6537
6538
6539
6540
6541
6542
6543
6544
6545
6546
6547
6548
6549
6550
6551
6552
6553
6554
6555
6556
6557
6558
6559
6560
6561
6562
6563
6564
6565
6566
6567
6568
6569
6570
6571
6572
6573
6574
6575
6576
6577
6578
6579
6580
6581
6582
6583
6584
6585
6586
6587
6588
6589
6590
6591
6592
6593
6594
6595
6596
6597
6598
6599
6600
6601
6602
6603
6604
6605
6606
6607
6608
6609
6610
6611
6612
6613
6614
6615
6616
6617
6618
6619
6620
6621
6622
6623
6624
6625
6626
6627
6628
6629
6630
6631
6632
6633
6634
6635
6636
6637
6638
6639
6640
6641
6642
6643
6644
6645
6646
6647
6648
6649
6650
6651
6652
6653
6654
6655
6656
6657
6658
6659
6660
6661
6662
6663
6664
6665
6666
6667
6668
6669
6670
6671
6672
6673
6674
6675
6676
6677
6678
6679
6680
6681
6682
6683
6684
6685
6686
6687
6688
6689
6690
6691
6692
6693
6694
6695
6696
6697
6698
6699
6700
6701
6702
6703
6704
6705
6706
6707
6708
6709
6710
6711
6712
6713
6714
6715
6716
6717
6718
6719
6720
6721
6722
6723
6724
6725
6726
6727
6728
6729
6730
6731
6732
6733
6734
6735
6736
6737
6738
6739
6740
6741
6742
6743
6744
6745
6746
6747
6748
6749
6750
6751
6752
6753
6754
6755
6756
6757
6758
6759
6760
6761
6762
6763
6764
6765
6766
6767
6768
6769
6770
6771
6772
6773
6774
6775
6776
6777
6778
6779
6780
6781
6782
6783
6784
6785
6786
6787
6788
6789
6790
6791
6792
6793
6794
6795
6796
6797
6798
6799
6800
6801
6802
6803
6804
6805
6806
6807
6808
6809
6810
6811
6812
6813
6814
6815
6816
6817
6818
6819
6820
6821
6822
6823
6824
6825
6826
6827
6828
6829
6830
6831
6832
6833
6834
6835
6836
6837
6838
6839
6840
6841
6842
6843
6844
6845
6846
6847
6848
6849
6850
6851
6852
6853
6854
6855
6856
6857
6858
6859
6860
6861
6862
6863
6864
6865
6866
6867
6868
6869
6870
6871
6872
6873
6874
6875
6876
6877
6878
6879
6880
6881
6882
6883
6884
6885
6886
6887
6888
6889
6890
6891
6892
6893
6894
6895
6896
6897
6898
6899
6900
6901
6902
6903
6904
6905
6906
6907
6908
6909
6910
6911
6912
6913
6914
6915
6916
6917
6918
6919
6920
6921
6922
6923
6924
6925
6926
6927
6928
6929
6930
6931
6932
6933
6934
6935
6936
6937
6938
6939
6940
6941
6942
6943
6944
6945
6946
6947
6948
6949
6950
6951
6952
6953
6954
6955
6956
6957
6958
6959
6960
6961
6962
6963
6964
6965
6966
6967
6968
6969
6970
6971
6972
6973
6974
6975
6976
6977
6978
6979
6980
6981
6982
6983
6984
6985
6986
6987
6988
6989
6990
6991
6992
6993
6994
6995
6996
6997
6998
6999
7000
7001
7002
7003
7004
7005
7006
7007
7008
7009
7010
7011
7012
7013
7014
7015
7016
7017
7018
7019
7020
7021
7022
7023
7024
7025
7026
7027
7028
7029
7030
7031
7032
7033
7034
7035
7036
7037
7038
7039
7040
7041
7042
7043
7044
7045
7046
7047
7048
7049
7050
7051
7052
7053
7054
7055
7056
7057
7058
7059
7060
7061
7062
7063
7064
7065
7066
7067
7068
7069
7070
7071
7072
7073
7074
7075
7076
7077
7078
7079
7080
7081
7082
7083
7084
7085
7086
7087
7088
7089
7090
7091
7092
7093
7094
7095
7096
7097
7098
7099
7100
7101
7102
7103
7104
7105
7106
7107
7108
7109
7110
7111
7112
7113
7114
7115
7116
7117
7118
7119
7120
7121
7122
7123
7124
7125
7126
7127
7128
7129
7130
7131
7132
7133
7134
7135
7136
7137
7138
7139
7140
7141
7142
7143
7144
7145
7146
7147
7148
7149
7150
7151
7152
7153
7154
7155
7156
7157
7158
7159
7160
7161
7162
7163
7164
7165
7166
7167
7168
7169
7170
7171
7172
7173
7174
7175
7176
7177
7178
7179
7180
7181
7182
7183
7184
7185
7186
7187
7188
7189
7190
7191
7192
7193
7194
7195
7196
7197
7198
7199
7200
7201
7202
7203
7204
7205
7206
7207
7208
7209
7210
7211
7212
7213
7214
7215
7216
7217
7218
7219
7220
7221
7222
7223
7224
7225
7226
7227
7228
7229
7230
7231
7232
7233
7234
7235
7236
7237
7238
7239
7240
7241
7242
7243
7244
7245
7246
7247
7248
7249
7250
7251
7252
7253
7254
7255
7256
7257
7258
7259
7260
7261
7262
7263
7264
7265
7266
7267
7268
7269
7270
7271
7272
7273
7274
7275
7276
7277
7278
7279
7280
7281
7282
7283
7284
7285
7286
7287
7288
7289
7290
7291
7292
7293
7294
7295
7296
7297
7298
7299
7300
7301
7302
7303
7304
7305
7306
7307
7308
7309
7310
7311
7312
7313
7314
7315
7316
7317
7318
7319
7320
7321
7322
7323
7324
7325
7326
7327
7328
7329
7330
7331
7332
7333
7334
7335
7336
7337
7338
7339
7340
7341
7342
7343
7344
7345
7346
7347
7348
7349
7350
7351
7352
7353
7354
7355
7356
7357
7358
7359
7360
7361
7362
7363
7364
7365
7366
7367
7368
7369
7370
7371
7372
7373
7374
7375
7376
7377
7378
7379
7380
7381
7382
7383
7384
7385
7386
7387
7388
7389
7390
7391
7392
7393
7394
7395
7396
7397
7398
7399
7400
7401
7402
7403
7404
7405
7406
7407
7408
7409
7410
7411
7412
7413
7414
7415
7416
7417
7418
7419
7420
7421
7422
7423
7424
7425
7426
7427
7428
7429
7430
7431
7432
7433
7434
7435
7436
7437
7438
7439
7440
7441
7442
7443
7444
7445
7446
7447
7448
7449
7450
7451
7452
7453
7454
7455
7456
7457
7458
7459
7460
7461
7462
7463
7464
7465
7466
7467
7468
7469
7470
7471
7472
7473
7474
7475
7476
7477
7478
7479
7480
7481
7482
7483
7484
7485
7486
7487
7488
7489
7490
7491
7492
7493
7494
7495
7496
7497
7498
7499
7500
7501
7502
7503
7504
7505
7506
7507
7508
7509
7510
7511
7512
7513
7514
7515
7516
7517
7518
7519
7520
7521
7522
7523
7524
7525
7526
7527
7528
7529
7530
7531
7532
7533
7534
7535
7536
7537
7538
7539
7540
7541
7542
7543
7544
7545
7546
7547
7548
7549
7550
7551
7552
7553
7554
7555
7556
7557
7558
7559
7560
7561
7562
7563
7564
7565
7566
7567
7568
7569
7570
7571
7572
7573
7574
7575
7576
7577
7578
7579
7580
7581
7582
7583
7584
7585
7586
7587
7588
7589
7590
7591
7592
7593
7594
7595
7596
7597
7598
7599
7600
7601
7602
7603
7604
7605
7606
7607
7608
7609
7610
7611
7612
7613
7614
7615
7616
7617
7618
7619
7620
7621
7622
7623
7624
7625
7626
7627
7628
7629
7630
7631
7632
7633
7634
7635
7636
7637
7638
7639
7640
7641
7642
7643
7644
7645
7646
7647
7648
7649
7650
7651
7652
7653
7654
7655
7656
7657
7658
7659
7660
7661
7662
7663
7664
7665
7666
7667
7668
7669
7670
7671
7672
7673
7674
7675
7676
7677
7678
7679
7680
7681
7682
7683
7684
7685
7686
7687
7688
7689
7690
7691
7692
7693
7694
7695
7696
7697
7698
7699
7700
7701
7702
7703
7704
7705
7706
7707
7708
7709
7710
7711
7712
7713
7714
7715
7716
7717
7718
7719
7720
7721
7722
7723
7724
7725
7726
7727
7728
7729
7730
7731
7732
7733
7734
7735
7736
7737
7738
7739
7740
7741
7742
7743
7744
7745
7746
7747
7748
7749
7750
7751
7752
7753
7754
7755
7756
7757
7758
7759
7760
7761
7762
7763
7764
7765
7766
7767
7768
7769
7770
7771
7772
7773
7774
7775
7776
7777
7778
7779
7780
7781
7782
7783
7784
7785
7786
7787
7788
7789
7790
7791
7792
7793
7794
7795
7796
7797
7798
7799
7800
7801
7802
7803
7804
7805
7806
7807
7808
7809
7810
7811
7812
7813
7814
7815
7816
7817
7818
7819
7820
7821
7822
7823
7824
7825
7826
7827
7828
7829
7830
7831
7832
7833
7834
7835
7836
7837
7838
7839
7840
7841
7842
7843
7844
7845
7846
7847
7848
7849
7850
7851
7852
7853
7854
7855
7856
7857
7858
7859
7860
7861
7862
7863
7864
7865
7866
7867
7868
7869
7870
7871
7872
7873
7874
7875
7876
7877
7878
7879
7880
7881
7882
7883
7884
7885
7886
7887
7888
7889
7890
7891
7892
7893
7894
7895
7896
7897
7898
7899
7900
7901
7902
7903
7904
7905
7906
7907
7908
7909
7910
7911
7912
7913
7914
7915
7916
7917
7918
7919
7920
7921
7922
7923
7924
7925
7926
7927
7928
7929
7930
7931
7932
7933
7934
7935
7936
7937
7938
7939
7940
7941
7942
7943
7944
7945
7946
7947
7948
7949
7950
7951
7952
7953
7954
7955
7956
7957
7958
7959
7960
7961
7962
7963
7964
7965
7966
7967
7968
7969
7970
7971
7972
7973
7974
7975
7976
7977
7978
7979
7980
7981
7982
7983
7984
7985
7986
7987
7988
7989
7990
7991
7992
7993
7994
7995
7996
7997
7998
7999
8000
8001
8002
8003
8004
8005
8006
8007
8008
8009
8010
8011
8012
8013
8014
8015
8016
8017
8018
8019
8020
8021
8022
8023
8024
8025
8026
8027
8028
8029
8030
8031
8032
8033
8034
8035
8036
8037
8038
8039
8040
8041
8042
8043
8044
8045
8046
8047
8048
8049
8050
8051
8052
8053
8054
8055
8056
8057
8058
8059
8060
8061
8062
8063
8064
8065
8066
8067
8068
8069
8070
8071
8072
8073
8074
8075
8076
8077
8078
8079
8080
8081
8082
8083
8084
8085
8086
8087
8088
8089
8090
8091
8092
8093
8094
8095
8096
8097
8098
8099
8100
8101
8102
8103
8104
8105
8106
8107
8108
8109
8110
8111
8112
8113
8114
8115
8116
8117
8118
8119
8120
8121
8122
8123
8124
8125
8126
8127
8128
8129
8130
8131
8132
8133
8134
8135
8136
8137
8138
8139
8140
8141
8142
8143
8144
8145
8146
8147
8148
8149
8150
8151
8152
8153
8154
8155
8156
8157
8158
8159
8160
8161
8162
8163
8164
8165
8166
8167
8168
8169
8170
8171
8172
8173
8174
8175
8176
8177
8178
8179
8180
8181
8182
8183
8184
8185
8186
8187
8188
8189
8190
8191
8192
8193
8194
8195
8196
8197
8198
8199
8200
8201
8202
8203
8204
8205
8206
8207
8208
8209
8210
8211
8212
8213
8214
8215
8216
8217
8218
8219
8220
8221
8222
8223
8224
8225
8226
8227
8228
8229
8230
8231
8232
8233
8234
8235
8236
8237
8238
8239
8240
8241
8242
8243
8244
8245
8246
8247
8248
8249
8250
8251
8252
8253
8254
8255
8256
8257
8258
8259
8260
8261
8262
8263
8264
8265
8266
8267
8268
8269
8270
8271
8272
8273
8274
8275
8276
8277
8278
8279
8280
8281
8282
8283
8284
8285
8286
8287
8288
8289
8290
8291
8292
8293
8294
8295
8296
8297
8298
8299
8300
8301
8302
8303
8304
8305
8306
8307
8308
8309
8310
8311
8312
8313
8314
8315
8316
8317
8318
8319
8320
8321
8322
8323
8324
8325
8326
8327
8328
8329
8330
8331
8332
8333
8334
8335
8336
8337
8338
8339
8340
8341
8342
8343
8344
8345
8346
8347
8348
8349
8350
8351
8352
8353
8354
8355
8356
8357
8358
8359
8360
8361
8362
8363
8364
8365
8366
8367
8368
8369
8370
8371
8372
8373
8374
8375
8376
8377
8378
8379
8380
8381
8382
8383
8384
8385
8386
8387
8388
8389
8390
8391
8392
8393
8394
8395
8396
8397
8398
8399
8400
8401
8402
8403
8404
8405
8406
8407
8408
8409
8410
8411
8412
8413
8414
8415
8416
8417
8418
8419
8420
8421
8422
8423
8424
8425
8426
8427
8428
8429
8430
8431
8432
8433
8434
8435
8436
8437
8438
8439
8440
8441
8442
8443
8444
8445
8446
8447
8448
8449
8450
8451
8452
8453
8454
8455
8456
8457
8458
8459
8460
8461
8462
8463
8464
8465
8466
8467
8468
8469
8470
8471
8472
8473
8474
8475
8476
8477
8478
8479
8480
8481
8482
8483
8484
8485
8486
8487
8488
8489
8490
8491
8492
8493
8494
8495
8496
8497
8498
8499
8500
8501
8502
8503
8504
8505
8506
8507
8508
8509
8510
8511
8512
8513
8514
8515
8516
8517
8518
8519
8520
8521
8522
8523
8524
8525
8526
8527
8528
8529
8530
8531
8532
8533
8534
8535
8536
8537
8538
8539
8540
8541
8542
8543
8544
8545
8546
8547
8548
8549
8550
8551
8552
8553
8554
8555
8556
8557
8558
8559
8560
8561
8562
8563
8564
8565
8566
8567
8568
8569
8570
8571
8572
8573
8574
8575
8576
8577
8578
8579
8580
8581
8582
8583
8584
8585
8586
8587
8588
8589
8590
8591
8592
8593
8594
8595
8596
8597
8598
8599
8600
8601
8602
8603
8604
8605
8606
8607
8608
8609
8610
8611
8612
8613
8614
8615
8616
8617
8618
8619
8620
8621
8622
8623
8624
8625
8626
8627
8628
8629
8630
8631
8632
8633
8634
8635
8636
8637
8638
8639
8640
8641
8642
8643
8644
8645
8646
8647
8648
8649
8650
8651
8652
8653
8654
8655
8656
8657
8658
8659
8660
8661
8662
8663
8664
8665
8666
8667
8668
8669
8670
8671
8672
8673
8674
8675
8676
8677
8678
8679
8680
8681
8682
8683
8684
8685
8686
8687
8688
8689
8690
8691
8692
8693
8694
8695
8696
8697
8698
8699
8700
8701
8702
8703
8704
8705
8706
8707
8708
8709
8710
8711
8712
8713
8714
8715
8716
8717
8718
8719
8720
8721
8722
8723
8724
8725
8726
8727
8728
8729
8730
8731
8732
8733
8734
8735
8736
8737
8738
8739
8740
8741
8742
8743
8744
8745
8746
8747
8748
8749
8750
8751
8752
8753
8754
8755
8756
8757
8758
8759
8760
8761
8762
8763
8764
8765
8766
8767
8768
8769
8770
8771
8772
8773
8774
8775
8776
8777
8778
8779
8780
8781
8782
8783
8784
8785
8786
8787
8788
8789
8790
8791
8792
8793
8794
8795
8796
8797
8798
8799
8800
8801
8802
8803
8804
8805
8806
8807
8808
8809
8810
8811
8812
8813
8814
8815
8816
8817
8818
8819
8820
8821
8822
8823
8824
8825
8826
8827
8828
8829
8830
8831
8832
8833
8834
8835
8836
8837
8838
8839
8840
8841
8842
8843
8844
8845
8846
8847
8848
8849
8850
8851
8852
8853
8854
8855
8856
8857
8858
8859
8860
8861
8862
8863
8864
8865
8866
8867
8868
8869
8870
8871
8872
8873
8874
8875
8876
8877
8878
8879
8880
8881
8882
8883
8884
8885
8886
8887
8888
8889
8890
8891
8892
8893
8894
8895
8896
8897
8898
8899
8900
8901
8902
8903
8904
8905
8906
8907
8908
8909
8910
8911
8912
8913
8914
8915
8916
8917
8918
8919
8920
8921
8922
8923
8924
8925
8926
8927
8928
8929
8930
8931
8932
8933
8934
8935
8936
8937
8938
8939
8940
8941
8942
8943
8944
8945
8946
8947
8948
8949
8950
8951
8952
8953
8954
8955
8956
8957
8958
8959
8960
8961
8962
8963
8964
8965
8966
8967
8968
8969
8970
8971
8972
8973
8974
8975
8976
8977
8978
8979
8980
8981
8982
8983
8984
8985
8986
8987
8988
8989
8990
8991
8992
8993
8994
8995
8996
8997
8998
8999
9000
9001
9002
9003
9004
9005
9006
9007
9008
9009
9010
9011
9012
9013
9014
9015
9016
9017
9018
9019
9020
9021
9022
9023
9024
9025
9026
9027
9028
9029
9030
9031
9032
9033
9034
9035
9036
9037
9038
9039
9040
9041
9042
9043
9044
9045
9046
9047
9048
9049
9050
9051
9052
9053
9054
9055
9056
9057
9058
9059
9060
9061
9062
9063
9064
9065
9066
9067
9068
9069
9070
9071
9072
9073
9074
9075
9076
9077
9078
9079
9080
9081
9082
9083
9084
9085
9086
9087
9088
9089
9090
9091
9092
9093
9094
9095
9096
9097
9098
9099
9100
9101
9102
9103
9104
9105
9106
9107
9108
9109
9110
9111
9112
9113
9114
9115
9116
9117
9118
9119
9120
9121
9122
9123
9124
9125
9126
9127
9128
9129
9130
9131
9132
9133
9134
9135
9136
9137
9138
9139
9140
9141
9142
9143
9144
9145
9146
9147
9148
9149
9150
9151
9152
9153
9154
9155
9156
9157
9158
9159
9160
9161
9162
9163
9164
9165
9166
9167
9168
9169
9170
9171
9172
9173
9174
9175
9176
9177
9178
9179
9180
9181
9182
9183
9184
9185
9186
9187
9188
9189
9190
9191
9192
9193
9194
9195
9196
9197
9198
9199
9200
9201
9202
9203
9204
9205
9206
9207
9208
9209
9210
9211
9212
9213
9214
9215
9216
9217
9218
9219
9220
9221
9222
9223
9224
9225
9226
9227
9228
9229
9230
9231
9232
9233
9234
9235
9236
9237
9238
9239
9240
9241
9242
9243
9244
9245
9246
9247
9248
9249
9250
9251
9252
9253
9254
9255
9256
9257
9258
9259
9260
9261
9262
9263
9264
9265
9266
9267
9268
9269
9270
9271
9272
9273
9274
9275
9276
9277
9278
9279
9280
9281
9282
9283
9284
9285
9286
9287
9288
9289
9290
9291
9292
9293
9294
9295
9296
9297
9298
9299
9300
9301
9302
9303
9304
9305
9306
9307
9308
9309
9310
9311
9312
9313
9314
9315
9316
9317
9318
9319
9320
9321
9322
9323
9324
9325
9326
9327
9328
9329
9330
9331
9332
9333
9334
9335
9336
9337
9338
9339
9340
9341
9342
9343
9344
9345
9346
9347
9348
9349
9350
9351
9352
9353
9354
9355
9356
9357
9358
9359
9360
9361
9362
9363
9364
9365
9366
9367
9368
9369
9370
9371
9372
9373
9374
9375
9376
9377
9378
9379
9380
9381
9382
9383
9384
9385
9386
9387
9388
9389
9390
9391
9392
9393
9394
9395
9396
9397
9398
9399
9400
9401
9402
9403
9404
9405
9406
9407
9408
9409
9410
9411
9412
9413
9414
9415
9416
9417
9418
9419
9420
9421
9422
9423
9424
9425
9426
9427
9428
9429
9430
9431
9432
9433
9434
9435
9436
9437
9438
9439
9440
9441
9442
9443
9444
9445
9446
9447
9448
9449
9450
9451
9452
9453
9454
9455
9456
9457
9458
9459
9460
9461
9462
9463
9464
9465
9466
9467
9468
9469
9470
9471
9472
9473
9474
9475
9476
9477
9478
9479
9480
9481
9482
9483
9484
9485
9486
9487
9488
9489
9490
9491
9492
9493
9494
9495
9496
9497
9498
9499
9500
9501
9502
9503
9504
9505
9506
9507
9508
9509
9510
9511
9512
9513
9514
9515
9516
9517
9518
9519
9520
9521
9522
9523
9524
9525
9526
9527
9528
9529
9530
9531
9532
9533
9534
9535
9536
9537
9538
9539
9540
9541
9542
9543
9544
9545
9546
9547
9548
9549
9550
9551
9552
9553
9554
9555
9556
9557
9558
9559
9560
9561
9562
9563
9564
9565
9566
9567
9568
9569
9570
9571
9572
9573
9574
9575
9576
9577
9578
9579
9580
9581
9582
9583
9584
9585
9586
9587
9588
9589
9590
9591
9592
9593
9594
9595
9596
9597
9598
9599
9600
9601
9602
9603
9604
9605
9606
9607
9608
9609
9610
9611
9612
9613
9614
9615
9616
9617
9618
9619
9620
9621
9622
9623
9624
9625
9626
9627
9628
9629
9630
9631
9632
9633
9634
9635
9636
9637
9638
9639
9640
9641
9642
9643
9644
9645
9646
9647
9648
9649
9650
9651
9652
9653
9654
9655
9656
9657
9658
9659
9660
9661
9662
9663
9664
9665
9666
9667
9668
9669
9670
9671
9672
9673
9674
9675
9676
9677
9678
9679
9680
9681
9682
9683
9684
9685
9686
9687
9688
9689
9690
9691
9692
9693
9694
9695
9696
9697
9698
9699
9700
9701
9702
9703
9704
9705
9706
9707
9708
9709
9710
9711
9712
9713
9714
9715
9716
9717
9718
9719
9720
9721
9722
9723
9724
9725
9726
9727
9728
9729
9730
9731
9732
9733
9734
9735
9736
9737
9738
9739
9740
9741
9742
9743
9744
9745
9746
9747
9748
9749
9750
9751
9752
9753
9754
9755
9756
9757
9758
9759
9760
9761
9762
9763
9764
9765
9766
9767
9768
9769
9770
9771
9772
9773
9774
9775
9776
9777
9778
9779
9780
9781
9782
9783
9784
9785
9786
9787
9788
9789
9790
9791
9792
9793
9794
9795
9796
9797
9798
9799
9800
9801
9802
9803
9804
9805
9806
9807
9808
9809
9810
9811
9812
9813
9814
9815
9816
9817
9818
9819
9820
9821
9822
9823
9824
9825
9826
9827
9828
9829
9830
9831
9832
9833
9834
9835
9836
9837
9838
9839
9840
9841
9842
9843
9844
9845
9846
9847
9848
9849
9850
9851
9852
9853
9854
9855
9856
9857
9858
9859
9860
9861
9862
9863
9864
9865
9866
9867
9868
9869
9870
9871
9872
9873
9874
9875
9876
9877
9878
9879
9880
9881
9882
9883
9884
9885
9886
9887
9888
9889
9890
9891
9892
9893
9894
9895
9896
9897
9898
9899
9900
9901
9902
9903
9904
9905
9906
9907
9908
9909
9910
9911
9912
9913
9914
9915
9916
9917
9918
9919
9920
9921
9922
9923
9924
9925
9926
9927
9928
9929
9930
9931
9932
9933
9934
9935
9936
9937
9938
9939
9940
9941
9942
9943
9944
9945
9946
9947
9948
9949
9950
9951
9952
9953
9954
9955
9956
9957
9958
9959
9960
9961
9962
9963
9964
9965
9966
9967
9968
9969
9970
9971
9972
9973
9974
9975
9976
9977
9978
9979
9980
9981
9982
9983
9984
9985
9986
9987
9988
9989
9990
9991
9992
9993
9994
9995
9996
9997
9998
9999
10000
10001
10002
10003
10004
10005
10006
10007
10008
10009
10010
10011
10012
10013
10014
10015
10016
10017
10018
10019
10020
10021
10022
10023
10024
10025
10026
10027
10028
10029
10030
10031
10032
10033
10034
10035
10036
10037
10038
10039
10040
10041
10042
10043
10044
10045
10046
10047
10048
10049
10050
10051
10052
10053
10054
10055
10056
10057
10058
10059
10060
10061
10062
10063
10064
10065
10066
10067
10068
10069
10070
10071
10072
10073
10074
10075
10076
10077
10078
10079
10080
10081
10082
10083
10084
10085
10086
10087
10088
10089
10090
10091
10092
10093
10094
10095
10096
10097
10098
10099
10100
10101
10102
10103
10104
10105
10106
10107
10108
10109
10110
10111
10112
10113
10114
10115
10116
10117
10118
10119
10120
10121
10122
10123
10124
10125
10126
10127
10128
10129
10130
10131
10132
10133
10134
10135
10136
10137
10138
10139
10140
10141
10142
10143
10144
10145
10146
10147
10148
10149
10150
10151
10152
10153
10154
10155
10156
10157
10158
10159
10160
10161
10162
10163
10164
10165
10166
10167
10168
10169
10170
10171
10172
10173
10174
10175
10176
10177
10178
10179
10180
10181
10182
10183
10184
10185
10186
10187
10188
10189
10190
10191
10192
10193
10194
10195
10196
10197
10198
10199
10200
10201
10202
10203
10204
10205
10206
10207
10208
10209
10210
10211
10212
10213
10214
10215
10216
10217
10218
10219
10220
10221
10222
10223
10224
10225
10226
10227
10228
10229
10230
10231
10232
10233
10234
10235
10236
10237
10238
10239
10240
10241
10242
10243
10244
10245
10246
10247
10248
10249
10250
10251
10252
10253
10254
10255
10256
10257
10258
10259
10260
10261
10262
10263
10264
10265
10266
10267
10268
10269
10270
10271
10272
10273
10274
10275
10276
10277
10278
10279
10280
10281
10282
10283
10284
10285
10286
10287
10288
10289
10290
10291
10292
10293
10294
10295
10296
10297
10298
10299
10300
10301
10302
10303
10304
10305
10306
10307
10308
10309
10310
10311
10312
10313
10314
10315
10316
10317
10318
10319
10320
10321
10322
10323
10324
10325
10326
10327
10328
10329
10330
10331
10332
10333
10334
10335
10336
10337
10338
10339
10340
10341
10342
10343
10344
10345
10346
10347
10348
10349
10350
10351
10352
10353
10354
10355
10356
10357
10358
10359
10360
10361
10362
10363
10364
10365
10366
10367
10368
10369
10370
10371
10372
10373
10374
10375
10376
10377
10378
10379
10380
10381
10382
10383
10384
10385
10386
10387
10388
10389
10390
10391
10392
10393
10394
10395
10396
10397
10398
10399
10400
10401
10402
10403
10404
10405
10406
10407
10408
10409
10410
10411
10412
10413
10414
10415
10416
10417
10418
10419
10420
10421
10422
10423
10424
10425
10426
10427
10428
10429
10430
10431
10432
10433
10434
10435
10436
10437
10438
10439
10440
10441
10442
10443
10444
10445
10446
10447
10448
10449
10450
10451
10452
10453
10454
10455
10456
10457
10458
10459
10460
10461
10462
10463
10464
10465
10466
10467
10468
10469
10470
10471
10472
10473
10474
10475
10476
10477
10478
10479
10480
10481
10482
10483
10484
10485
10486
10487
10488
10489
10490
10491
10492
10493
10494
10495
10496
10497
10498
10499
10500
10501
10502
10503
10504
10505
10506
10507
10508
10509
10510
10511
10512
10513
10514
10515
10516
10517
10518
10519
10520
10521
10522
10523
10524
10525
10526
10527
10528
10529
10530
10531
10532
10533
10534
10535
10536
10537
10538
10539
10540
10541
10542
10543
10544
10545
10546
10547
10548
10549
10550
10551
10552
10553
10554
10555
10556
10557
10558
10559
10560
10561
10562
10563
10564
10565
10566
10567
10568
10569
10570
10571
10572
10573
10574
10575
10576
10577
10578
10579
10580
10581
10582
10583
10584
10585
10586
10587
10588
10589
10590
10591
10592
10593
10594
10595
10596
10597
10598
10599
10600
10601
10602
10603
10604
10605
10606
10607
10608
10609
10610
10611
10612
10613
10614
10615
10616
10617
10618
10619
10620
10621
10622
10623
10624
10625
10626
10627
10628
10629
10630
10631
10632
10633
10634
10635
10636
10637
10638
10639
10640
10641
10642
10643
10644
10645
10646
10647
10648
10649
10650
10651
10652
10653
10654
10655
10656
10657
10658
10659
10660
10661
10662
10663
10664
10665
10666
10667
10668
10669
10670
10671
10672
10673
10674
10675
10676
10677
10678
10679
10680
10681
10682
10683
10684
10685
10686
10687
10688
10689
10690
10691
10692
10693
10694
10695
10696
10697
10698
10699
10700
10701
10702
10703
10704
10705
10706
10707
10708
10709
10710
10711
10712
10713
10714
10715
10716
10717
10718
10719
10720
10721
10722
10723
10724
10725
10726
10727
10728
10729
10730
10731
10732
10733
10734
10735
10736
10737
10738
10739
10740
10741
10742
10743
10744
10745
10746
10747
10748
10749
10750
10751
10752
10753
10754
10755
10756
10757
10758
10759
10760
10761
10762
10763
10764
10765
10766
10767
10768
10769
10770
10771
10772
10773
10774
10775
10776
10777
10778
10779
10780
10781
10782
10783
10784
10785
10786
10787
10788
10789
10790
10791
10792
10793
10794
10795
10796
10797
10798
10799
10800
10801
10802
10803
10804
10805
10806
10807
10808
10809
10810
10811
10812
10813
10814
10815
10816
10817
10818
10819
10820
10821
10822
10823
10824
10825
10826
10827
10828
10829
10830
10831
10832
10833
10834
10835
10836
10837
10838
10839
10840
10841
10842
10843
10844
10845
10846
10847
10848
10849
10850
10851
10852
10853
10854
10855
10856
10857
10858
10859
10860
10861
10862
10863
10864
10865
10866
10867
10868
10869
10870
10871
10872
10873
10874
10875
10876
10877
10878
10879
10880
10881
10882
10883
10884
10885
10886
10887
10888
10889
10890
10891
10892
10893
10894
10895
10896
10897
10898
10899
10900
10901
10902
10903
10904
10905
10906
10907
10908
10909
10910
10911
10912
10913
10914
10915
10916
10917
10918
10919
10920
10921
10922
10923
10924
10925
10926
10927
10928
10929
10930
10931
10932
10933
10934
10935
10936
10937
10938
10939
10940
10941
10942
10943
10944
10945
10946
10947
10948
10949
10950
10951
10952
10953
10954
10955
10956
10957
10958
10959
10960
10961
10962
10963
10964
10965
10966
10967
10968
10969
10970
10971
10972
10973
10974
10975
10976
10977
10978
10979
10980
10981
10982
10983
10984
10985
10986
10987
10988
10989
10990
10991
10992
10993
10994
10995
10996
10997
10998
10999
11000
11001
11002
11003
11004
11005
11006
11007
11008
11009
11010
11011
11012
11013
11014
11015
11016
11017
11018
11019
11020
11021
11022
11023
11024
11025
11026
11027
11028
11029
11030
11031
11032
11033
11034
11035
11036
11037
11038
11039
11040
11041
11042
11043
11044
11045
11046
11047
11048
11049
11050
11051
11052
11053
11054
11055
11056
11057
11058
11059
11060
11061
11062
11063
11064
11065
11066
11067
11068
11069
11070
11071
11072
11073
11074
11075
11076
11077
11078
11079
11080
11081
11082
11083
11084
11085
11086
11087
11088
11089
11090
11091
11092
11093
11094
11095
11096
11097
11098
11099
11100
11101
11102
11103
11104
11105
11106
11107
11108
11109
11110
11111
11112
11113
11114
11115
11116
11117
11118
11119
11120
11121
11122
11123
11124
11125
11126
11127
11128
11129
11130
11131
11132
11133
11134
11135
11136
11137
11138
11139
11140
11141
11142
11143
11144
11145
11146
11147
11148
11149
11150
11151
11152
11153
11154
11155
11156
11157
11158
11159
11160
11161
11162
11163
11164
11165
11166
11167
11168
11169
11170
11171
11172
11173
11174
11175
11176
11177
11178
11179
11180
11181
11182
11183
11184
11185
11186
11187
11188
11189
11190
11191
11192
11193
11194
11195
11196
11197
11198
11199
11200
11201
11202
11203
11204
11205
11206
11207
11208
11209
11210
11211
11212
11213
11214
11215
11216
11217
11218
11219
11220
11221
11222
11223
11224
11225
11226
11227
11228
11229
11230
11231
11232
11233
11234
11235
11236
11237
11238
11239
11240
11241
11242
11243
11244
11245
11246
11247
11248
11249
11250
11251
11252
11253
11254
11255
11256
11257
11258
11259
11260
11261
11262
11263
11264
11265
11266
11267
11268
11269
11270
11271
11272
11273
11274
11275
11276
11277
11278
11279
11280
11281
11282
11283
11284
11285
11286
11287
11288
11289
11290
11291
11292
11293
11294
11295
11296
11297
11298
11299
11300
11301
11302
11303
11304
11305
11306
11307
11308
11309
11310
11311
11312
11313
11314
11315
11316
11317
11318
11319
11320
11321
11322
11323
11324
11325
11326
11327
11328
11329
11330
11331
11332
11333
11334
11335
11336
11337
11338
11339
11340
11341
11342
11343
11344
11345
11346
11347
11348
11349
11350
11351
11352
11353
11354
11355
11356
11357
11358
11359
11360
11361
11362
11363
11364
11365
11366
11367
11368
11369
11370
11371
11372
11373
11374
11375
11376
11377
11378
11379
11380
11381
11382
11383
11384
11385
11386
11387
11388
11389
11390
11391
11392
11393
11394
11395
11396
11397
11398
11399
11400
11401
11402
11403
11404
11405
11406
11407
11408
11409
11410
11411
11412
11413
11414
11415
11416
11417
11418
11419
11420
11421
11422
11423
11424
11425
11426
11427
11428
11429
11430
11431
11432
11433
11434
11435
11436
11437
11438
11439
11440
11441
11442
11443
11444
11445
11446
%!PS
%%Title: The Funtools Help Facility
%%Creator: html2ps version 1.0 beta5
%%EndComments
save
2000 dict begin
/d {bind def} bind def
/D {def} d
/t true D
/f false D
/FL [/Times-Roman
/Times-Italic
/Times-Bold
/Times-BoldItalic
/Courier
/Courier-Oblique
/Courier-Bold
/Courier-BoldOblique
/Helvetica
/Helvetica-Oblique
/Helvetica-Bold
/Helvetica-BoldOblique] D
/WF t D
/WI 0 D
/F 1 D
/IW 471 F div D
/IL 621 F div D
/PS 791 D
/EF [0 1 0 0 0 0 0 0 0 0 1 1 0 0 0 0 0 0 0 0 0 0 2 2] D
/EZ [11 9 19 17 15 13 12 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 8 8] D
/Ey [0 0 2 2 2 2 2 2 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0] D
/EG [-1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1] D
/Tm [1 1 0.8 0.8 0.8 0.8 0.8 0.8 0 0 0 0 0 0 0.5 1 1 1 1 0 0 1.3 0 0] D
/Bm [1 1 0.5 0.5 0.5 0.5 0.5 0.5 0 0 0 0 0 0 0.5 1 1 1 1 0 0 1 0 0] D
/Lm [0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 2 2 0 0 2 0 0 0] D
/Rm [0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0] D
/EU [-1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 0 0] D
/NO t D
/YY [[{()}1][{()}0][{()}2]] D
/ZZ [[{()}1][{()}0][{()}2]] D
/Ts EZ 0 get D
/TU f D
/Xp t D
/AU t D
/SN 0 D
/Cf f D
/Tp f D
/Fe f D
/TI 1 Ts mul D
/Fm 14 D
/xL 71 D
/xR 71 D
/yL 706 D
/yR 706 D
/Wl 471 F div D
/Wr 471 F div D
/hL 621 F div D
/hR 621 F div D
/FE {newpath Fm neg Fm M CP BB IW Fm add Fm L IW Fm add IL Fm add neg L CP BB
 Fm neg IL Fm add neg L closepath} D
/LA {PM 0 eq{/IW Wl D /IL hL D}{/IW Wr D /IL hR D}ie /W IW D /LL W D /LS W D
 TU PM 0 eq and{IW 56 F div add SA{Sf div}if 0 translate}
 {PM 0 eq{xL yL}{xR yR}ie translate F SA{Sf mul}if dup scale
 CS CF FS Cf{CA CL get VC}if /Bb f D}ie 0 0 M
 TF not Tc or {Cf{gsave SA{1 Sf div dup scale}if Cb VC FE fill grestore}if}if}D
/Pi 0 Ts mul D
/SG [0.8 1 1] D
/Ab 15 D
/J 0 D
/Tc t D
/NH 6 D
/Nf f D
/Pa f D
/LH 1.2 D
/XR f D
/Xr {/pN E D ( [p ) WB pN WB (] )WB} D
/Db [16#FF 16#FF 16#FF] D
/Dt [16#00 16#00 16#00] D
/eA f D
/Fi f D
/bT f D
/Lc t D
/Dl [16#00 16#00 16#00] D
/LX f D
/Br 0.25 D
/IA ([IMAGE]) D
/DS {/PF f D()WB NL NP()pop RC ZF} D
/Gb f D
/Mb t D
/Hc [16#00 16#00 16#00] D
/Bl 3 D
/MI -15.2 D
/DX (DRAFT) D
/Di 0 D
/Tt 113.385826771654 D
/Th {()2 Al()BR (
      ) 0 1 -1 H()4 FZ Ti ES()EH (
      ) 0 2 -1 H() ME 0 get join EH()Ea()BR()} D
/tH {()0 1 -1 H (Table of Contents) EH()} D
/FD 2 D
/Dy 2 D
/cD [16#F0 16#F0 16#F0] D
/FW 0.6 D
/FU [16#00 16#00 16#00] D
/ET {/RM f D /A0 0 D /PN SN D /OU t D /Ou t D /W IW D /LL W D D1
 Ms not TP and{Ip}if /TF f D} D
[{true statusdict/setduplexmode get exec} stopped cleartomark
%-- End of variable part --
/MySymbol 10 dict dup begin
 /FontType 3 D /FontMatrix [.001 0 0 .001 0 0 ] D /FontBBox [25 -10 600 600] D
 /Encoding 256 array D 0 1 255{Encoding exch /.notdef put}for
 Encoding (e) 0 get /euro put
 /Metrics 2 dict D Metrics begin
  /.notdef 0 D
  /euro 651 D
 end
 /BBox 2 dict D BBox begin
  /.notdef [0 0 0 0] D
  /euro [25 -10 600 600] D
 end
 /CharacterDefs 2 dict D CharacterDefs begin
  /.notdef {} D
  /euro{newpath 114 600 moveto 631 600 lineto 464 200 lineto 573 200 lineto
   573 0 lineto -94 0 lineto 31 300 lineto -10 300 lineto closepath clip
   50 setlinewidth newpath 656 300 moveto 381 300 275 0 360 arc stroke
   -19 350 moveto 600 0 rlineto -19 250 moveto 600 0 rlineto stroke}d
 end
 /BuildChar{0 begin
  /char E D /fontdict E D /charname fontdict /Encoding get char get D
  fontdict begin
   Metrics charname get 0 BBox charname get aload pop setcachedevice
   CharacterDefs charname get exec
  end
 end}D
 /BuildChar load 0 3 dict put /UniqueID 1 D
end
definefont pop

/Cd {aload length 2 idiv dup dict begin {D} repeat currentdict end} D
/EX {EC cvx exec} D
/DU {} d
/BB {pop pop}d
/ie {ifelse} d
/E {exch} d
/M {moveto} d
/R {rmoveto} d
/L {lineto} d
/RL {rlineto} d
/CP {currentpoint} d
/SW {stringwidth} d
/GI {getinterval} d
/PI {putinterval} d
/Sg {setgray} d
/LW {setlinewidth} d
/S {dup () ne OU and{0 Co R AT 3 eq LB and HF not and A1 0 ne A2 0 ne or and
 {A2 0 32 A1 0 6 -1 roll awidthshow}{show}ie 0 Co neg R}{pop}ie
 OU PH 3 eq or{/Ms t D}if} D
/U {OU{gsave CP currentfont /FontInfo get /UnderlinePosition get
 0 E currentfont /FontMatrix get dtransform E pop add newpath M dup SW pop
 CJ 0 RL stroke grestore}if} D
/B {OU Br 0 gt and{CP Ts neg Ts .33 mul R gsave 0 Sg
 CP newpath Ts Br mul 0 360 arc closepath UI 2 mod 0 eq{stroke}{fill}ie
 grestore M CP E Ts Br 1 add mul sub E BB /Ms t D}if}D
/NP {Ms TP not or PA and OU and{TP{OR}if f1{mF k2 /mF E D /YC 0 D}if
 TP TU not PM 0 eq or and{showpage}if DU Ip TE not{LA}if 0.6 LW
 /CI 0 D /TP t D /Hs f D /hl 6 D /Hv 6 D /HI hi D /Ms f D}if Bs XO BO M} D
/Np {LE sub CP E pop gt PL 0 eq and{NP}if}D
/Ip {/PN PN 1 add D /Pn RM{1}{4}ie PN Ns D /PM PN SN sub 2 mod D} D
/GP {E dup 3 -1 roll get PN 1 add 2 mod get dup type /integertype eq
 {get 0 get}{E pop}ie}d
/Fc {dup 2 GP exec SW pop /S1 E D dup 1 GP exec SW pop /S2 E D 0 GP exec SW
 pop /S3 E D S1 0 gt{S2 2 mul S1 add S3 2 mul S1 add 2 copy lt{E}if pop}{0}ie
 S2 S3 add 2 copy lt{E}if pop IW .9 mul div dup 1 gt{1 E div}{pop 1}ie}D
/OR {Df{Sd}if tp not{gsave SA{1 Sf div dup scale}if Fe{Cf{FU VC}if FW LW
 1 setlinejoin FE stroke}if /YO {60 F div dup 40 gt{pop 40}if}D /cs CS D
 /cf CF D /CF 0 D /pf PF D /PF f D /Fn FN D /At AT D /AT 0 D /FN EF Hf 1 add
 get D Fz Fs FS ZZ Fc Fz mul Fs FS EU Hf 1 add get dup type /arraytype eq
 Cf and{VC}{pop 0 Sg}ie IW IL neg YO sub M ZZ 1 GP exec dup SW pop neg 0 R Sh
 0 IL neg YO sub M ZZ 0 GP exec Sh ZZ 2 GP exec dup SW pop IW E sub 2 div
 IL neg YO sub M Sh Fz Fs FS NO{/AW IW Pn SW pop sub D AW 2 div IL neg YO sub
 S1 0 gt S2 AW .45 mul gt or S3 AW .45 mul gt or{Fz 2 mul sub}if M Pn Sh}if
 EU Hf get dup type /arraytype eq Cf and{VC}{pop 0 Sg}ie YY Fc /FN EF Hf get D
 Hz mul HS FS IW YO M YY 1 GP exec dup SW pop neg 0 R Sh 0 YO M YY 0 GP exec Sh
 YY 2 GP exec dup SW pop IW E sub 2 div YO M Sh /FN Fn D /AT At D t Pb XO SZ
 SL get neg R /PF pf D grestore /CF 0 D cs cf FS}if}D
/Sh {dup () ne{CP Hz 4 div sub BB show CP CS add BB}{pop}ie}D
/Pb {/OU E D /Ou OU D /PB t D 0 0 M Ba{/Sa save D /BP t D /Fl t D RC /PL 0 D
 /PH 0 D /W IW D /LE IL .7 mul D /EO 0 D SI ZF /YA 0 D /BO 0 D /C1 () D
 BA 0 Ts neg R Bb{Xl Yl Xh Yh}if Bb CP Sa restore M
 {/Yh E D /Xh E D /Yl E D /Xl E D}if /Fl t D}if
 BL /OU t D /HM f D /Ou t D /PB f D} D
/Bs {/BP Ba not D}D
/reencodeISO {
 dup dup findfont dup length dict begin{1 index /FID ne{D}{pop pop}ie}forall
 /Encoding ISOLatin1Encoding D currentdict end definefont} D
/ISOLatin1Encoding [
/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef
/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef
/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef
/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef
/space/exclam/quotedbl/numbersign/dollar/percent/ampersand/quoteright
/parenleft/parenright/asterisk/plus/comma/hyphen/period/slash
/zero/one/two/three/four/five/six/seven/eight/nine/colon/semicolon
/less/equal/greater/question/at/A/B/C/D/E/F/G/H/I/J/K/L/M/N
/O/P/Q/R/S/T/U/V/W/X/Y/Z/bracketleft/backslash/bracketright
/asciicircum/underscore/quoteleft/a/b/c/d/e/f/g/h/i/j/k/l/m
/n/o/p/q/r/s/t/u/v/w/x/y/z/braceleft/bar/braceright/asciitilde
/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef
/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef
/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef
/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef
/.notdef/space/exclamdown/cent/sterling/currency/yen/brokenbar
/section/dieresis/copyright/ordfeminine/guillemotleft/logicalnot
/hyphen/registered/macron/degree/plusminus/twosuperior/threesuperior
/acute/mu/paragraph/periodcentered/cedilla/onesuperior/ordmasculine
/guillemotright/onequarter/onehalf/threequarters/questiondown
/Agrave/Aacute/Acircumflex/Atilde/Adieresis/Aring/AE/Ccedilla
/Egrave/Eacute/Ecircumflex/Edieresis/Igrave/Iacute/Icircumflex
/Idieresis/Eth/Ntilde/Ograve/Oacute/Ocircumflex/Otilde/Odieresis
/multiply/Oslash/Ugrave/Uacute/Ucircumflex/Udieresis/Yacute
/Thorn/germandbls/agrave/aacute/acircumflex/atilde/adieresis
/aring/ae/ccedilla/egrave/eacute/ecircumflex/edieresis/igrave
/iacute/icircumflex/idieresis/eth/ntilde/ograve/oacute/ocircumflex
/otilde/odieresis/divide/oslash/ugrave/uacute/ucircumflex/udieresis
/yacute/thorn/ydieresis
] D
[128/backslash 129/parenleft 130/parenright 141/circumflex 142/tilde
143/perthousand 144/dagger 145/daggerdbl 146/Ydieresis 147/scaron 148/Scaron
149/oe 150/OE 151/guilsinglleft 152/guilsinglright 153/quotesinglbase
154/quotedblbase 155/quotedblleft 156/quotedblright 157/endash 158/emdash
159/trademark]
aload length 2 idiv 1 1 3 -1 roll{pop ISOLatin1Encoding 3 1 roll put}for
/colorimage where{pop}{
 /colorimage {
  pop pop /Pr E D {/Cv Pr D /Gr Cv length 3 idiv string D 0 1 Gr length 1 sub
   {Gr E dup /i E 3 mul D Cv i get 0.299 mul Cv i 1 add get 0.587 mul add
    Cv i 2 add get 0.114 mul add cvi put}for Gr} image} D
}ie
/pdfmark where{pop}{userdict /pdfmark /cleartomark load put}ie
WF{FL{reencodeISO D}forall}{4 1 FL length 1 sub{FL E get reencodeISO D}for}ie
/Symbol dup dup findfont dup length dict begin
 {1 index /FID ne{D}{pop pop}ie}forall /Encoding [Encoding aload pop]
 dup 128 /therefore put D currentdict end definefont D

/SF {/CS E D SZ SL CS put FO SL FN put /YI CS LH neg mul D dup ST cvs ( ) join
 CS ST cvs join C1 E join ( NF ) join /C1 E D CS NF /Wf WF FN 0 gt or D
 /BW Wf{( ) SW pop}{0}ie D}D
/NF {/cS E D /cF E D cF 0 ge{FL cF get}{cF -1 eq{/Symbol}{/MySymbol}ie}ie
 findfont cS scalefont setfont} D
/FS {CF or /CF E D FR SL CF put CF CF 0 ge{FN 4 mul add}if E SF} D
/PC {SH /BP f D fin not GL not and{NL}if /HM t D /LL LS D} D
/BS {/TX E D Wf{/fin f D /CW 0 D /LK 0 D /SC 0 D
 /RT TX D {RT ( ) search{/NW E D pop /RT E D /WH NW SW pop D CW WH add LL gt
 {TX SC LK SC sub 1 sub NN GI GL{SH cF cS OC
 2 copy cS ne E cF ne or{NF}{pop pop}ie}{PC /CW WH BW add D}ie
 /SC LK D}
 {GL{JC}if
 /CW CW WH add BW add D /HM t D}ie /GL f D /Ph f D
 /LK LK NW length 1 add add D}{pop exit}ie}loop
 /fin t D TX SC LK SC sub GI SH RT () ne{GL not{CC}if}if
 /LC TX length D /WH RT SW pop D CW WH add Hy{HC SW pop add}if LL gt
 {RT GL{SH cF cS OC 2 copy cS ne E cF ne or{NF}{pop pop}ie
 Hy{/Ph t D}if /LL LS D}{NL /LL LS D SH}ie}
 {RT PC Hy{CC}if /Ph Ph Hy or D}ie RT () ne{/GL t D /HM t D}if}
 {TX SW pop LL le{TX SH}{/NW () D 0 2 TX length 1 sub
 {/CW E D TX 0 CW GI dup SW pop LL gt{pop NW SH /HM t D NL/LL W XO sub MR sub D
 /CW CW 2 sub NN D /TX TX CW TX length CW sub GI D TX BS exit}
 {/NW E D}ie}for}ie}ie /HM t D}D
/CC {C0 length 0 gt{JC}if /C0 [C1 L1 YA YB Mf NS NB TB AF Bw] D
 /C1 () D /L0 L1 D /YA 0 D /YB 0 D /Mf 0 D /NS 0 D /NB 0 D}D
/JC {C0 aload length 0 gt{pop pop pop NB add /NB E D NS add /NS E D
 dup Mf gt{/Mf E D}{pop}ie dup YB gt{/YB E D}{pop}ie
 dup YA gt{/YA E D}{pop}ie pop C1 join /C1 E D /C0 [] D}if}D
/OC {C0 length 0 gt{C1 L1 L0 sub YA YB Mf NS NB TB AF Bw GL C0 aload pop
 /Bw E D /AF E D /TB E D /NB E D /NS E D /Mf E D /YB E D /YA E D /C0 [] D
 /L1 E D /C1 E D Ph{HC SH}if NL /GL E D /Bw E D /AF E D /TB E D /NB E D /NS E D
 /Mf E D /YB E D /YA E D /L1 E D /LL W L1 sub XO sub MR sub WH sub D /CW 0 D
 C1 E join /C1 E D}if}D
/BT {/LB t D dup length string copy RS dup dup () ne E ( ) ne and
 {/CI 0 D /LS LL D /LL W L1 sub XO sub MR sub D BS}
 {dup ( ) eq{/GL f D}if dup () eq L1 0 eq or{pop}{SH /BP f D /Ph f D}ie}ie
 /LB f D} D
/BL {CP E pop XO E M} D
/NL {JC /GL f D /SK W XO sub MR sub L1 sub TB{Bw add}if D
 /YA LF{Mf HM Fl not and PF or{LH mul}if}{0 /LF t D}ie YA 2 copy lt{E}if pop D
 C1 () ne{/FB YB Mf SA{Sf mul}if 4 div 2 copy lt{E}if pop D}if Fl{/Ya YA D}if
 CP E pop YA sub YB sub LE neg lt Fl not and PB not and{NP}if NT TL BL
 OU PF not and PB or{/RE L1 TB{Bw sub}if
 W XO sub MR sub div YA YB add LE BO add div 2 copy lt{E}if pop D
 RE 1 gt{BL 1 RE div dup scale}if}if
 AT 2 le{SK AT mul 2 div YA neg R}if
 AT 3 eq{0 YA neg R TB{/NB NB 1 sub D /NS NS 1 sub D}if /NB NB 1 sub NN D
 /A3 NS 6 mul NB add D NS NB add 0 eq
  {/A1 0 D /A2 0 D}
  {NS 0 eq{/A1 SK NB div dup J gt{pop 0}if D /A2 0 D}{J A3 mul SK lt
   {/A1 J D /A2 SK J NB mul sub NS div dup Ab gt{/A1 0 D pop 0}if D}
   {/A1 SK A3 div D /A2 A1 6 mul D}ie}ie}ie /A1 A1 NN D /A2 A2 NN D}if
 AT 4 eq{0 YA neg R PH 2 le{PD 0 lt{/PD L1 D}if PD M1 gt{/M1 PD D}if
 L1 PD sub M2 gt{/M2 L1 PD sub D}if}{DV ID 1 sub get 0 ge{Lo 0 R}if}ie}if
 F0 cF ne Cs cS ne or{F0 Cs NF}if
 /ms Ms D /Ms f D CP FB sub
 C1 cvx exec XO EO sub L1 add TB{BW sub}if dup LM gt{/LM E D}{pop}ie
 PH 0 eq PH 4 eq or Ms and{HF not{/PO t D /AH t D}if
 BB CP YA add E AT 3 eq LB and{A1 sub}if TB{BW sub}if E BB}
 {pop pop}ie Ms HM PH 3 eq and or{/BP f D /Fl f D}if
 /Lo 0 D /L1 0 D /F0 cF D /Cs cS D BP not{0 YB NN neg R}if
 OU f1 and mF not and{k2 /f1 f D}if
 OU PF not and PB or{RE 1 gt{RE dup scale}if}if /Ms ms Ms or D
 /C1 AF{(Cp )}{()}ie D /YA 0 D /YB 0 D BL
 AT 4 eq LB not and PH 3 ge and
 {ID DV length lt{DV ID get dup 0 ge{DO E sub /Lo E D /L1 Lo D}{pop}ie
 /ID ID 1 add D}if}if /T t D CD{/LN LN 1 add D PD}if
 /PD -1 D /NS 0 D /NB 0 D /TB f D /Ph f D /Mf 0 D /HM f D} D
/RS {/TM E D /CN 0 D TM{10 eq{TM CN ( ) PI}if /CN CN 1 add D}forall
 /CN 0 D /BK HM EN and{0}{1}ie D TM
 {dup 32 ne{TM CN 3 2 roll put /CN CN 1 add D /BK 0 D}
 {pop BK 0 eq{TM CN 32 put /CN CN 1 add D}if /BK 1 D}ie}forall
 TM 0 CN GI dup dup () ne E ( ) ne and
 {dup CN 1 sub get 32 eq{/EN f D}{/EN t D}ie}if} D
/join {2 copy length E length add string dup 4 2 roll 2 index 0 3 index
 PI E length E PI}d
/WR {(\n) search{dup () ne BP not or
 {Li 4 le CP E pop YI Li mul add LE add 0 lt and PL 0 eq and{NP}if
 SH NL pop /Li Li 1 sub D WR}{pop pop WR}ie}{SH}ie /CI 0 D /BP f D} D
/SH {dup dup () ne E ( ) ne and PF or CS Mf gt and{/Mf CS D}if
 T not Wf and{( ) E join /T t D}if dup BP{/MF CS D}if
 AT 3 eq{2 copy length dup 0 gt{/NB E NB add D
 {( ) search{/NS NS 1 add D pop pop}{pop exit}ie}loop}{pop pop}ie}if
 CD PD 0 lt and{dup DC search{SW pop /PD E L1 add D pop pop}{pop}ie}if
 0 Np dup SW pop L1 add /L1 E D dup () ne
 {C1 (\() join E join (\)) join AU AF and UF or Wf and{( U ) join}if
 sF{( s ) join}if ( S ) join
 /C1 E D dup length 1 sub get 32 eq /TB E D /Bw BW D}{pop pop}ie} D
/BG {AI LG BC add add 0 eq} D
/ON {OU{Ty AR AI NN get dup 1 add Ln Ns Ty 2 mod 0 eq{(.  )}{(\)  )}ie join
 dup SW pop neg 0 R CP E 0 lt{0 E M}{pop}ie CP BB show /Ms t D}if} D
/Ln {AR AI 3 -1 roll put}D
/SP {dup CI lt BP not and{dup CI sub 0 E R /CI E D}{pop}ie} D
/BN {PF{WR /HM f D}{BT NL}ie} D
/NN {dup 0 lt{pop 0}if} D
/h {(h) HI ST cvs join cvx exec dup 1 get E Nf{0 get E join}{pop}ie} D
/H {/fn FN D /Hi E 1 add D 1 sub /HL E D /H2 HL 2 add D /GS EZ H2 get D
 E Tm H2 get GS mul BE dup 0 gt{1 sub}{pop EG H2 get dup 0 lt{pop AT}if}ie NA
 WW Np /SL SL 1 add D /FN EF H2 get D GS Ey H2 get FS
 EU H2 get Sc Hs not HL Hl lt and Hs HL hl lt and or Hi 0 eq or
 {/HI Hi D /Hs t D /hl HL D /Hv HL D}if HL Hl lt{/hi Hi D}if
 Nf HI 0 gt and{(h) Hi ST cvs join cvx exec 0 get WB}if
 /HF t D /AH f D /PO f D} D
/EH {Bm H2 get GS mul BE OA /SL SL 1 sub NN D /CF 0 D /FN fn D
 SZ SL get FR SL get FS /HF f D /GS Ts D ()Ec} D
/P {E PF{WR}{PO{EP}{BN}ie Ts 4 mul Np AE not{Tm 0 get Ts mul neg SP}if
 dup 0 ge AH and{Pi Pd}if}ie 1 sub dup 0 lt{pop AV AL get}if /AT E D /PO t D} D
/EP {PF{WR}{BN Ts 4 mul Np}ie AE not{Bm 0 get Ts mul neg SP}if
 /AT AV AL get D /PO f D} D
/BE {E PO{EP}{BN}ie Ts 4 mul Np neg SP} D
/HR {/Aw W EO sub D /RW E dup 0 gt{Aw mul}{neg}ie dup Aw gt{pop Aw}if D /RZ E D
 E BN Ts neg SP 1 sub 2 div Aw RW sub mul EO add CP E pop M PF{0 Ps neg R}if
 0 Np OU{gsave RZ LW Cf{Hc VC}{0 Sg}ie CP BB RW 0 RL CP BB stroke grestore}if
 /CI 0 D /BP f D PF not{Ts neg SP}if /Ms t D} D
/AD {I NL EG 14 get dup 0 lt{pop AT}if NA /AE t D Tm 14 get Ts mul neg SP
 Cf{EU 14 get dup -1 eq{pop CA CL get}if Sc}if} D
/DA {BN ()ES OA /AE f D ()Ec Bm 14 get Ts mul neg SP} D
/PR {/MW E D /Li E D Tm 1 get Ps mul BE 0 NA /FN Fp D /PF t D SI /SL SL 1 add D
 /CF 0 D Ps CS mul Ts div MW WC mul CS mul Ts div dup LL gt PL 0 eq and
 {LL div div}{pop}ie Ey 1 get FS CP E pop LE add YI neg div cvi dup Li lt
 AH and{4 lt YI Li mul 5 mul LE add 0 gt or PL 0 eq and{NP}if}{pop}ie
 EU 1 get Sc /GS Ps D}D
/RP {WR NL () /PF f D SI /FN 0 D ES Bm 1 get Ps mul neg SP OA /GS Ts D} D
/SI {/XO Lm 15 get BC NN mul Lm 16 get AI UI sub NN mul add
 Lm 17 get UI NN mul add Lm 20 get LG NN mul add Ts mul
 PF{Lm 1 get Ps mul add}if EO add D
 /MR Rm 15 get BC NN mul Rm 16 get AI UI sub NN mul add
 Rm 17 get UI NN mul add Rm 20 get LG NN mul add Ts mul
 PF{Rm 1 get Ps mul add}if D /LL W XO sub MR sub D} D
/DT {/cC E D BN /LG LG 1 sub D SI /LG LG 1 add D WW 2 div Np BL} D
/DD {WB Cc 0 eq cC 0 eq and L1 0 eq or Lm 20 get Ts mul L1 sub TB{BW add}if
 Ts 2 div lt or NL /LF E D SI BL /cC 0 D} D
/DL {Dc LG Cc put /Cc E D BG{Tm 18 get Ts mul BE}{BN}ie /LG LG 1 add D BL} D
/LD {BN LG 0 gt{/LG LG 1 sub D}if /Cc Dc LG get D SI
 BG{()Bm 18 get Ts mul BE}if BL} D
/UL {BG{Tm 17 get Ts mul BE}{BN}ie NR AI NN 0 put /UI UI 1 add D
 /AI AI 1 add D SI BL} D
/LU {BN /UI UI 1 sub D /AI AI 1 sub D SI BG{()Bm 17 get Ts mul BE}if BL} D
/OL {E BG{Tm 16 get Ts mul BE}{BN}ie TR AI NN Ty put /Ty E D NR AI NN 1 put
 /AI AI 1 add D SI BL 1 Ln} D
/LO {BN /AI AI 1 sub D /Ty TR AI get D SI BG{()Bm 16 get Ts mul BE}if BL} D
/LI {E BN -1 SP /BP f D /CI 0 D 0 Np NR AI 1 sub NN get 1 eq
 {dup dup 0 gt E 4 le and{/Ty E D}{pop}ie
 /L1 L1 Ty AR AI NN get Ns SW pop XO sub dup 0 lt{pop 0}if add D ( ON )}
 {pop ( B )}ie C1 E join /C1 E D CS Mf gt{/Mf CS D}if BL} D
/BQ {Tm 15 get Ts mul BE /BC BC 1 add D SI BL} D
/QB {Bm 15 get Ts mul BE /BC BC 1 sub D SI BL} D
/Al {E EP 1 sub dup 0 lt{pop AV AL get}if NA} D
/Ea {EP OA} D
/WB {PF{WR}{BT}ie} D
/F1 {WB /FN 0 D CS 0 FS} D
/F2 {WB /FN WI D CS 0 FS} D
/HY {/Hy t D WB /Hy f D} D
/YH {WB} D
/A {/LT E D LT 1 eq{/RN E D}if /Lh E D WB /C1 C1 ( Cp ) join D
 Lc AF not and{Cl Sc}if /AF t D} D
/EA {Lc AF and{Ec}{WB}ie TL Pa AF and Lh 0 ne and
 {( \() Lh join (\)) join /AF f D WB}if /AF f D} D
/TL {C1 ( Tl ) apa /C1 E D} d
/apa {AF OU and Lh 0 ne LT 1 eq or and{LT 1 eq{RN ( /) E ST cvs join}
 {(\() Lh join (\)) join}ie E join join}{pop}ie} d
/Cp {/Xc CP /Yc E D D} D
/SS {Cf{dup 0 ge{EU E get dup -1 eq{pop CA CL get}if}{pop CA CL get}ie Sc}
 {pop}ie SZ SL get /SL SL 1 add D} D
/I {WB 8 SS 1 FS} D
/EM {WB 8 SS /CF CF 1 xor D 0 FS} D
/BD {WB 9 SS 2 FS} D
/TT {WB 10 SS /FN Fp D 0 FS} D
/KB {WB 11 SS /FN Fp D 2 FS} D
/CT {WB 12 SS 1 FS} D
/SM {WB 13 SS /FN Fp D 0 FS} D
/Q {/QL QL 1 add D QO QL 2 mod get La get join WB} D
/EQ {QC QL 2 mod get La get join WB /QL QL 1 sub D} D
/RO {WB -1 SS /CF 0 D 0 FS} D
/SY {WB -1 SS -1 FS} D
/MY {WB -1 SS -2 FS} D
/ES {WB /SL SL 1 sub NN D /CF 0 D /FN FO SL get D SZ SL get FR SL get FS ()Ec}D
/FZ {3 sub 1.2 E exp GS mul E WB TL /C1 C1 ( Cp ) join D /SL SL 1 add D 0 FS} D
/Ef {WB TL ()ES /C1 C1 ( Cp ) join D} D
/BZ {dup /Bf E D FZ}D
/Sc {dup -1 ne Cf and{/CL CL 1 add D dup 0 eq{pop [0 0 0]}if
 dup CA E CL E put VS ( VC ) join C1 E join /C1 E D}{pop}ie} D
/Ec {WB Cf{/CL CL 1 sub NN D CA CL get VS ( VC ) join C1 E join /C1 E D}if} D
/VS {dup type /arraytype eq{([) E {ST cvs join ( ) join}forall (]) join}if} D
/VC {{255 div}forall setrgbcolor} D
/Sl {dup type /integertype ne{Ds}if /La E D WB}d
/UN {WB /UF t D} D
/NU {WB /UF f D} D
/SE {WB /sF t D} D
/XE {WB /sF f D} D
/sM {/C1 C1 ( k1 ) join D}d
/eM {/C1 C1 ( k2 ) join D}d
/k1 {/YC CP E pop Ts add D /mF t D /f1 t D}d
/k2 {gsave 3 LW -9 CP E pop Ts 0.2 mul sub M -9 YC L stroke grestore /mF f D}d
/Ac {/AC E D WB}d
/Ca {eA{( \()join AC join(\) )join}if WB}d
/s {OU{gsave 0 CS .25 mul R dup SW pop CJ 0 RL stroke grestore}if}D
/CJ {AT 3 eq LB and{E dup dup length 1 sub A1 mul E
 {( ) search{pop pop E A2 add E}{pop exit}ie}loop 3 -1 roll add
 W CP pop sub 2 copy gt{E}if pop}if}D
/So {/Co E D} D
/SO {C1 Yo ST cvs join ( So ) join /C1 E D (j) SW pop 2 div Pd} D
/Se {E WB CS E div Pd}D
/Pd {dup type /stringtype eq{SW pop}if dup /L1 E L1 add D
 ST cvs ( 0 R ) join C1 E join /C1 E D} D
/Sp {0.35 CO} D
/Sb {-0.2 CO} D
/CO {OV Io Yo put /Yo E CS mul Yo add D /Io Io 1 add D -1.5 Io mul 3 add FZ SO
 CS Yo add dup YA gt{/YA E D}{pop}ie
 Yo neg dup YB gt{/YB E D}{pop}ie} D
/Es {ES /Io Io 1 sub NN D /Yo OV Io get D SO} D
/SB {/N2 0 D 0 1 NI{/N E D{IX N2 get 0 lt{/N2 N2 1 add D}{exit}ie}loop
 /K WS N get FC N get mul D /NY AY N2 get D /BV NY array D
 0 1 NY 1 sub{/TM K string D currentfile TM readhexstring pop pop BV E TM put}
 for BM N BV put /N2 N2 1 add D}for} D
/IC [{/MA E D /MB 0 D}{2 div /MA E D /MB MA D}{/MB E CS sub D /MA CS D}
 {pop /MA YS AB mul D /MB 1 AB sub YS mul D}{pop /MA 0 D /MB 0 D}] D
/IP {BV N get /N N 1 add D} D
/II {/K E D IX K get 0 lt{/EC E D}if /TY E D
 TY 4 eq{/Y E D /X E D}if TY 3 eq{/AB E D}if
 /XW AX K get D /YW AY K get D /IS SG IT K get get D /XS XW IS mul D
 /YS YW IS mul D YS IC TY get exec /MA MA Fl not{3 add}if D} D
/IM {II /ty TY D /xs XS D /ys YS D /ya YA D /yb YB D /ma MA D /mb MB D /k K D
 /ec EC D /BP f D /CI 0 D WB TL L1 xs add dup XO add MR add W gt
 {pop /ma ma Fl{3 add}if D NL /YA ma D /YB mb D /YS ys D /L1 xs D}
 {/L1 E D ma YA gt{/YA ma D}if mb YB gt{/YB mb D}if}ie /TB f D
 OU{CP E pop YS sub LE neg lt Fl not and PB not and{NP /YA ma D /YB mb D}if
 /BP f D ty ST cvs ( ) join IX k get 0 lt{(\() join ec join (\) ) join}if
 k ST cvs join ty 3 eq{AB ST cvs ( ) join E join}if
 ty 4 eq{X ST cvs ( ) join Y ST cvs join ( ) join E join}if C1 E join
 ( DI ) join FP 2 eq FP 1 eq AF and or{( FM ) join}if
 ( Il Cp ) apa /C1 E D /EN f D}if /HM t D /T f D} D
/DI {II /Xc CP /Yc E D D /YN YW neg D /HM t D /CI 0 D /K2 IX K get D gsave
 TY 4 eq{OX X IS mul add OY FY add YS sub Y IS mul sub}
 {/FY YS D CP MB sub 2 copy /OY E D /OX E D}ie
 translate K2 0 ge{/DP AZ K2 get D /BV BM K2 get D XS YS scale /N 0 D XW YW DP
 [XW 0 0 YN 0 YW] {IP} FC K2 get 1 eq{image}{f 3 colorimage}ie}
 {EX}ie grestore XS 0 R /Ms t D} D
/FM {gsave 0 Sg CP MB sub translate XS neg 0 M 0 YS RL XS 0 RL 0 YS neg RL
 XS neg 0 RL stroke grestore} D
/NA {/AT E D /AL AL 1 add D AV AL AT put} D
/OA {AL 0 gt{/AL AL 1 sub D /AT AV AL get D}if} D
/D1 {/BR {CP E pop E BN Mb{CP E pop eq{0 YI R}if}{pop}ie} D
 /Sn {OU{C1 E ST cvs join ( Ld ) join /C1 E D}{pop}ie} D} D
/D1 {/BR {BN} D /Sn {OU {C1 E ST cvs join ( Ld ) join /C1 E D} {pop} ie} D} D
/TC {/TF t D /ML 0 D HN{SW pop dup ML gt{/ML E D}{pop}ie}forall NP /RM RM not D
 RC /OU Tc D Ep /PN 0 D Ms not TP and{Ip}if /W IW ML sub Ts sub D
 /A0 0 D TH{/BR {( ) join BT} D /Sn {pop} D /Au () D}if} D
/TN {0 eq{E EA PF HF or not XR and{HN E get Xr}{pop}ie}
 {OU{Tn 0 ge{() BN}if /Tn E D}{pop}ie WB}ie} D
/NT {OU LB not and Tn 0 ge and{PL 0 eq{Ms not{CS CF FS}if CP dup
 /y E YA sub D W 9 sub CS -1.8 mul XO L1 add 2 add{y M (.) show}for
 HN Tn get dup SW pop IW E sub y M show CP BB M}if /Tn -1 D}if} D
/Ld {/DN E D HN DN Pn put [/View [/XYZ -4 Fl{PS}{CP YA add US E pop}ie null]
 /Dest DN ST cvs cvn /DEST pdfmark} D
/C {ND 1 eq{1 sub}if TI mul /XO E D NL Nf not{pop()}if 0 3 -1 roll 1 A} D
/OP {BP not{NP}if PN 2 mod 0 eq{/Ms t D NP}if}D
/Ep {Xp PN 2 mod 0 eq and OU and{/Pn (-) D showpage /PM 1 D LA}if}D
/Dg [73 86 88 76 67 68 77] D
/Rd [0 [1 1 0][2 1 0][3 1 0][2 1 1][1 1 1][2 2 1][3 3 1][4 4 1][2 1 2]] D
/Ns {/m E D /c E 32 mul D /j m 1000 idiv D /p j 12 add string D
 c 96 le m 0 gt and{c 32 le {/i 0 D /d 77 D /l 100 D /m m j 1000 mul sub D
  j -1 1 {pop p i d c add put /i i 1 add D}for
  4 -2 0 {/j E D /n m l idiv D /m m n l mul sub D /d Dg j get D
   n 0 gt {/x Rd n get D x 0 get -1 1 {pop p i d c add put /i i 1 add D}for
   p i x 1 get sub Dg x 2 get j add get c add put}if /l l 10 idiv D
  }for p 0 i GI}
  {/i ST length 1 sub D m {1 sub dup 0 ge{dup 26 mod c add 1 add
   ST i 3 -1 roll put 26 idiv dup 0 eq{pop exit}if}if /i i 1 sub D}loop
   ST i ST length i sub GI}ie}
 {m p cvs}ie} D
/US {matrix currentmatrix matrix defaultmatrix matrix invertmatrix
 matrix concatmatrix transform} D
/GB {Gb{US}if}D
/Tl {/Rn E D Xc CP pop ne{
 [/Rect [Xc 1 sub Yc cS 0.25 mul sub GB CP E 1 add E cS 0.85 mul add GB]
  /Subtype /Link /Border [0 0 Cf Lc and LX and AU or{0}{1}ie] Rn type
  /nametype eq {/Dest Rn}{/Action [/Subtype /URI /URI Rn] Cd}ie
  /ANN pdfmark}if} D
/Il {/Rn E D [/Rect [Xc Yc GB Xc XS add Yc YS add GB] /Subtype /Link
 /Border [0 0 0] Rn type /nametype eq{/Dest Rn}
 {/Action [/Subtype /URI /URI Rn] Cd}ie /ANN pdfmark} D
/XP {[{/Z Bz 2 div D Z 0 R Z Z RL Z neg Z RL Z neg Z neg RL Z Z neg RL
 Fi cH 1 eq and{fill}if} {Bz 0 RL 0 Bz RL Bz neg 0 RL 0 Bz neg RL
 Fi cH 1 eq and{fill}if} {0 -5 R Bz 0 RL 0 21 RL Bz neg 0 RL 0 -21 RL}]} D
/MS {/Sm E D WB}D
/O {BN()Sm BX} D
/O {BN()0 Sm BX} D
/BX {/Bt E D Bt 2 lt{/Ch E D CS 0.8 mul}{11 mul}ie W XO sub MR sub
 2 copy gt{E}if pop /HZ E D Bt 2 eq{Fi not{pop()}if ( )E join /Ft E D TT
 /PF t D /MW 1 D /Li 1 D /Fw Ft SW pop D Fw HZ gt{/HZ Fw 8 add D}if
 HZ ST cvs( )join}{WB Ch ST cvs( )join}ie L1 HZ add XO add MR add W gt{NL}if
 Bt 2 eq{Ft ES Fw neg HM{CS sub}if Pd}if Bt ST cvs join( Bx )join
 Bt 2 eq HM and{CS Pd}if C1 E join /C1 E D /L1 L1 HZ add D /T f D
 ( ) Pd /PF f D Bt 2 lt{YA CS .8 mul lt{/YA CS .8 mul D}if}
 {YB 5 lt{/YB 5 D}if YA 21 lt{/YA 21 D}if}ie /CI 0 D} D
/Bx {dup 2 eq{E /Bz E D}{E /cH E D /Bz CS .8 mul D}ie
 OU {gsave 0 Sg XP E get exec stroke grestore}{pop}ie Bz 0 R /Ms t D}D
/SD {FD 4 mul Dy add DZ NF newpath 0 0 M DX t charpath pathbbox
 3 -1 roll sub /DY E D E dup /X1 E D sub WM mul WX DY mul add WM DG mul E div
 /DF E D /DR WX DF mul DY mul WM div 2 div D} d
/Sd {gsave 0 IL Di mul neg translate IL IW atan Di 0 eq{neg}if rotate
 FD 4 mul Dy add DZ NF DR X1 sub DY 2 div neg M cD VC DX show grestore} d
/Pt {/tp t D Tp{NP /Pn (TP) D 0 Tt neg R Th BN NP Ep ET RC ZF}if /tp f D} D
/RC {/AI 0 D /LG 0 D /BC 0 D /UI 0 D /PF f D /Cc 0 D /cC 0 D /Dc 10 array D
 /NR [0 1 9{pop 0}for] D /La Ds D /AR 10 array D /TR 10 array D /AV 30 array D
 SI /AL -1 D /AT A0 D AT NA /OV 9 array D /Yo 0 D /Co 0 D /Io 0 D /Hy f D
 /Ph f D /CL -1 D Ct Sc}D
/ZF {/FR [0 1 30{pop 0}for] D /SZ [0 1 30{pop 0}for] D /FO [0 1 30{pop 0}for] D
 /SL 0 D /CF 0 D /FN 0 D 0 Ts SF}D
/QO [[(\234)(\233)(\253\240)(\232)(\273)(\253)][(')(`)(\253\240)(\231)(\273)(\253)]] D
/QC [[(\234)(\234)(\240\273)(\233)(\253)(\273)][(')(')(\240\273)(`)(\253)(\273)]] D
/Hf EF length 2 sub D
/Hz EZ Hf get D
/HS Ey Hf get D
/Fz EZ Hf 1 add get D
/Fs Ey Hf 1 add get D
/LE IL D
/Ps EZ 1 get D
/Fp EF 1 get D
/XO 0 D
/YI 0 D
/CI 0 D
/FP 0 D
/WW Ts 7 mul D
/Mf 0 D
/YA 0 D
/YB 0 D
/Cs Ts D
/GS Ts D
/F0 0 D
/NS 0 D
/NB 0 D
/N 0 D
/C0 [] D
/C1 () D
/Lo 0 D
/L1 0 D
/LM 0 D
/PH 0 D
/EC 0 D
/Lh 0 D
/LT 0 D
/CH 1 string D
/ST 16 string D
/CA 9 array D
/HC (\255) D
/HM f D
/PF f D
/EN f D
/TB f D
/UF f D
/sF f D
/AE f D
/AF f D
/BP t D
/CD f D
/PA t D
/GL f D
/T t D
/HF f D
/AH f D
/SA f D
/PB f D
/f1 f D
/mF f D
/OX 0 D
/OY 0 D
/FY 0 D
/EO 0 D
/FB 0 D
/PL 0 D
/Bw 0 D
/PD -1 D
/TP f D
/tp f D
/TH f D
/Ty 4 D
/Tn -1 D
/Fl t D
/LB t D
/PM 1 D
/Ms f D
/Ba f D
/Bb f D
/Hl 3 D
/hl 6 D
/Hv 6 D
/Hs f D
/HI 0 D
/hi 0 D
/PO t D
/TE f D
/LF t D
/BO 0 D
/Sm 1 D
/Bf 3 D
/A1 0 D
/A2 0 D
/Ds 1 D
/QL -1 D
/Cb Db D
/Ct Dt D
/Cl Dl D
[/Creator (html2ps version 1.0 beta5) /Author () /Keywords () /Subject ()
 /Title (The Funtools Help Facility) /DOCINFO pdfmark
/ND 18 D
/HN [(1) (1) (1) (1) (8) (9) (19) (21) (28) (30) (33) (37) (38) (41) (42) (45)
(48) (51) (53) (??) (54) (56) (56) (87) (57) (58) (60) (62) (64) (65) (76)
(77) (66) (73) (75) (82) (85) (78) (80) (86) (87) (57) (91) (91) (92) (92)
(94) (102) (111) (95) (96) (100) (117) (123) (127) (136) (152) (157) (161)
(164) (165) (167) (171) (1) (1) (1) (3) (1) (1) (1) (8) (9) (19) (21) (28)
(30) (33) (37) (38) (41) (42) (45) (48) (50) (51) (51) (51) (51) (52) (53)
(53) (53) (53) (53) (54) (56) (56) (57) (57) (58) (60) (62) (64) (65) (66)
(73) (75) (76) (77) (80) (82) (85) (86) (87) (87) (87) (88) (90) (91) (98)
(91) (91) (91) (91) (92) (92) (94) (95) (96) (98) (99) (100) (101) (102)
(102) (102) (102) (102) (103) (104) (105) (105) (108) (109) (110) (111)
(111) (111) (111) (111) (111) (112) (113) (114) (114) (115) (116) (116)
(116) (117) (119) (119) (120) (120) (120) (117) (117) (117) (117) (119)
(119) (120) (120) (120) (121) (122) (123) (123) (123) (123) (126) (127)
(127) (127) (127) (127) (129) (129) (130) (131) (131) (132) (132) (133)
(135) (136) (136) (136) (136) (146) (151) (152) (152) (152) (152) (156)
(157) (157) (157) (157) (157) (158) (159) (160) (161) (161) (161) (161)
(161) (161) (162) (162) (163) (164) (164) (164) (164) (164) (165) (165)
(165) (165) (165) (166) (167) (167) (167) (167) (170) (171) (171) (171)
(171) (171) (172) (172) (172) (175) (178) (178) (179) (180) (181) (181)
(182) (182) (183) (183) (184) (184) (184) (184) (185) (185) (185) (186)
(187) (187)] D
/h0 [()(Table of Contents)] D
/h1 [(0.1\240\240)(Funtools: FITS Users Need Tools)] D
/h2 [(0.2\240\240)(Summary)] D
/h3 [(0.3\240\240)(Description)] D
/h4 [(0.3.0.0.1\240\240)(Last updated: January 6, 2006)] D
/h5 [(0.4\240\240)(Funtools Programs)] D
/h6 [(0.5\240\240)(Summary)] D
/h7 [(0.6\240\240)(funcalc - Funtools calculator \(for binary tables\))] D
/h8 [(0.7\240\240)(funcen - find centroid \(for binary tables\))] D
/h9 [(0.8\240\240)(funcnts - count photons in specified regions, with bkgd subtraction)] D
/h10 [(0.9\240\240)(funcone - cone search of a binary table containing RA, Dec columns)] D
/h11 [(0.10\240\240)(fundisp - display data in a Funtools data file)] D
/h12 [(0.11\240\240)(funhead - display a header in a Funtools file)] D
/h13 [(0.12\240\240)(funhist - create a 1D histogram of a column \(from a FITS binary table or raw event file\) or an image)] D
/h14 [(0.13\240\240)(funimage - create a FITS image from a Funtools data file)] D
/h15 [(0.14\240\240)(funindex - create an index for a column of a FITS binary table)] D
/h16 [(0.15\240\240)(funjoin - join two or more FITS binary tables on specified columns)] D
/h17 [(0.16\240\240)(funmerge - merge one or more Funtools table files)] D
/h18 [(0.17\240\240)(funsky - convert between image and sky coordinates)] D
/h19 [(0.18\240\240)(funtable - copy selected rows from a Funtools file to a FITS binary table)] D
/h20 [(0.19\240\240)(funtbl - extract a table from Funtools ASCII output)] D
/h21 [(0.19.0.0.1\240\240)(Last updated: April 1, 2007)] D
/h22 [(0.20\240\240)(FunDS9: Funtools and DS9 Image Display)] D
/h23 [(0.21\240\240)(Summary)] D
/h24 [(0.22\240\240)(Description)] D
/h25 [(0.22.0.0.1\240\240)(Last updated: November 16, 2005)] D
/h26 [(0.23\240\240)(FunLib: the Funtools Programming Interface)] D
/h27 [(0.24\240\240)(Summary)] D
/h28 [(0.25\240\240)(Introduction to the Funtools Programming Interface)] D
/h29 [(0.26\240\240)(Funtools Programming Tutorial)] D
/h30 [(0.27\240\240)(Compiling and Linking)] D
/h31 [(0.28\240\240)(A Short Digression on Subroutine Order)] D
/h32 [(0.29\240\240)(Funtools Programming Examples)] D
/h33 [(0.30\240\240)(The Funtools Programming Reference Manual)] D
/h34 [(0.31\240\240)(FunOpen - open a Funtools data file)] D
/h35 [(0.32\240\240)(FunImageGet - get an image or image section)] D
/h36 [(0.33\240\240)(FunImagePut - put an image to a Funtools file)] D
/h37 [(0.34\240\240)(FunImageRowGet - get row\(s\) of an image)] D
/h38 [(0.35\240\240)(FunImageRowPut - put row\(s\) of an image)] D
/h39 [(0.36\240\240)(FunColumnSelect - select Funtools columns)] D
/h40 [(0.37\240\240)(FunColumnActivate - activate Funtools columns)] D
/h41 [(0.38\240\240)(FunColumnLookup - lookup a Funtools column)] D
/h42 [(0.39\240\240)(FunTableRowGet - get Funtools rows)] D
/h43 [(0.40\240\240)(FunTableRowPut - put Funtools rows)] D
/h44 [(0.41\240\240)(FunParamPut - put a Funtools param value)] D
/h45 [(0.42\240\240)(FunInfoGet - get information from Funtools struct)] D
/h46 [(0.43\240\240)(FunInfoPut - put information into a Funtools struct)] D
/h47 [(0.44\240\240)(FunFlush - flush data to output file)] D
/h48 [(0.45\240\240)(FunClose - close a Funtools data file)] D
/h49 [(0.46\240\240)(FunRef: the Funtools Reference Handle)] D
/h50 [(0.47\240\240)(Summary)] D
/h51 [(0.48\240\240)(Description)] D
/h52 [(0.48.0.0.1\240\240)(Last updated: December 1, 2005)] D
/h53 [(0.49\240\240)(FunFiles: Funtools Data Files)] D
/h54 [(0.50\240\240)(Summary)] D
/h55 [(0.51\240\240)(Description)] D
/h56 [(0.52\240\240)(Supported Data Formats)] D
/h57 [(0.53\240\240)(FITS Images and Binary Tables)] D
/h58 [(0.54\240\240)(Non-FITS Raw Event Files)] D
/h59 [(0.55\240\240)(Non-FITS Array Files)] D
/h60 [(0.56\240\240)(Specifying Image Sections)] D
/h61 [(0.57\240\240)(Binning FITS Binary Tables and Non-FITS Event Files)] D
/h62 [(0.58\240\240)(Table and Spatial Region Filters)] D
/h63 [(0.59\240\240)(Disk Files and Other Supported File Types)] D
/h64 [(0.60\240\240)(Lists of Files)] D
/h65 [(0.60.0.0.1\240\240)(Last updated: February 15, 2006)] D
/h66 [(0.61\240\240)(Funtext: Support for Column-based Text Files)] D
/h67 [(0.62\240\240)(Summary)] D
/h68 [(0.63\240\240)(Description)] D
/h69 [(0.64\240\240)(Standard Text Files)] D
/h70 [(0.65\240\240)(Comments Convert to Header Params)] D
/h71 [(0.66\240\240)(Multiple Tables in a Single File)] D
/h72 [(0.67\240\240)(TEXT\(\) Specifier)] D
/h73 [(0.68\240\240)(Text\(\) Keyword Options)] D
/h74 [(0.69\240\240)(Environment Variables)] D
/h75 [(0.70\240\240)(Restrictions and Problems)] D
/h76 [(0.70.0.0.1\240\240)(Last updated: August 3, 2007)] D
/h77 [(0.71\240\240)(Funview: Database View Support for Tables)] D
/h78 [(0.72\240\240)(Summary)] D
/h79 [(0.73\240\240)(Description)] D
/h80 [(0.74\240\240)(Database Views)] D
/h81 [(0.75\240\240)(Funtools View Attributes)] D
/h82 [(0.76\240\240)(Invoking a Funtools View \(in Place of an Input File\))] D
/h83 [(0.77\240\240)(Basic View Matching Rules)] D
/h84 [(0.78\240\240)(More on View Matching Rules: Single vs. Multiple Matches)] D
/h85 [(0.79\240\240)(View Lists: Applying a View to Any File)] D
/h86 [(0.80\240\240)(Overriding Values Associated with a View)] D
/h87 [(0.81\240\240)(Environment Variables)] D
/h88 [(0.82\240\240)(Restrictions and Problems)] D
/h89 [(0.82.0.0.1\240\240)(Last updated: August 3, 2007)] D
/h90 [(0.83\240\240)(Funfilters: Filtering Rows in a Table)] D
/h91 [(0.84\240\240)(Summary)] D
/h92 [(0.85\240\240)(Description)] D
/h93 [(0.86\240\240)(Filter Expressions)] D
/h94 [(0.87\240\240)(Separators Also Are Operators)] D
/h95 [(0.88\240\240)(Range Lists)] D
/h96 [(0.89\240\240)(Math Operations and Functions)] D
/h97 [(0.90\240\240)(Include Files)] D
/h98 [(0.91\240\240)(Header Parameters)] D
/h99 [(0.92\240\240)(Examples)] D
/h100 [(0.92.0.0.1\240\240)(Last updated: November 17, 2005)] D
/h101 [(0.93\240\240)(Funidx: Using Indexes to Filter Rows in a Table)] D
/h102 [(0.94\240\240)(Summary)] D
/h103 [(0.95\240\240)(Description)] D
/h104 [(0.95.0.0.1\240\240)(Last updated: August 3, 2007)] D
/h105 [(0.96\240\240)(Regions: Spatial Region Filtering)] D
/h106 [(0.97\240\240)(Summary)] D
/h107 [(0.98\240\240)(Description)] D
/h108 [(0.99\240\240)(Region Expressions)] D
/h109 [(0.100\240\240)(Columns Used in Region Filtering)] D
/h110 [(0.101\240\240)(Region Algebra)] D
/h111 [(0.102\240\240)(Region Separators Also Are Operators)] D
/h112 [(0.103\240\240)(Region Exclusion)] D
/h113 [(0.104\240\240)(Include Files)] D
/h114 [(0.105\240\240)(Global and Local Properties of Regions)] D
/h115 [(0.106\240\240)(Coordinate Systems)] D
/h116 [(0.107\240\240)(Specifying Positions, Sizes, and Angles)] D
/h117 [(0.107.0.0.1\240\240)(Last updated: November 17, 2005)] D
/h118 [(0.108\240\240)(RegGeometry: Geometric Shapes in Spatial Region Filtering)] D
/h119 [(0.109\240\240)(Summary)] D
/h120 [(0.110\240\240)(Geometric shapes)] D
/h121 [(0.111\240\240)(Region accelerators)] D
/h122 [(0.111.0.0.1\240\240)(Last updated: March 12, 2007)] D
/h123 [(0.112\240\240)(RegAlgebra: Boolean Algebra on Spatial Regions)] D
/h124 [(0.113\240\240)(Summary)] D
/h125 [(0.114\240\240)(Description)] D
/h126 [(0.114.0.0.1\240\240)(Last updated: November 17, 2005)] D
/h127 [(0.115\240\240)(RegCoords: Spatial Region Coordinates)] D
/h128 [(0.116\240\240)(Summary)] D
/h129 [(0.117\240\240)(Pixel coordinate systems)] D
/h130 [(0.118\240\240)(World Coordinate Systems)] D
/h131 [(0.119\240\240)(WCS Positions and Sizes)] D
/h132 [(0.120\240\240)(NB: The Meaning of Pure Numbers Are Context Sensitive)] D
/h133 [(0.120.0.0.1\240\240)(Last updated: November 17, 2005)] D
/h134 [(0.121\240\240)(RegBounds: Region Boundaries)] D
/h135 [(0.122\240\240)(Summary)] D
/h136 [(0.123\240\240)(Description)] D
/h137 [(0.124\240\240)(Image boundaries : radially-symmetric shapes \(circle, annuli, ellipse\))] D
/h138 [(0.125\240\240)(Image Boundaries: non-radially symmetric shapes \(polygons, boxes\))] D
/h139 [(0.126\240\240)(Row Boundaries are Analytic)] D
/h140 [(0.127\240\240)(Image Boundaries vs. Row Boundaries: Practical Considerations)] D
/h141 [(0.127.0.0.1\240\240)(Last updated: November 16, 2005)] D
/h142 [(0.128\240\240)(RegDiff:Differences Between Funtools and IRAF Regions)] D
/h143 [(0.129\240\240)(Summary)] D
/h144 [(0.130\240\240)(Description)] D
/h145 [(0.130.0.0.1\240\240)(Last updated: November 16, 2005)] D
/h146 [(0.131\240\240)(FunCombine: Combining Region and Table Filters)] D
/h147 [(0.132\240\240)(Summary)] D
/h148 [(0.133\240\240)(Comma Conventions)] D
/h149 [(0.133.0.0.1\240\240)(Last updated: November 16, 2005)] D
/h150 [(0.134\240\240)(FunEnv: Funtools Environment Variables)] D
/h151 [(0.135\240\240)(Summary)] D
/h152 [(0.136\240\240)(Description)] D
/h153 [(0.136.0.0.1\240\240)(Last updated: November 16, 2005)] D
/h154 [(0.137\240\240)(Funtools ChangeLog)] D
/h155 [(0.138\240\240)(Patch Release 1.4.5 \(internal ds9 release\))] D
/h156 [(0.139\240\240)(Patch Release 1.4.4 \(internal ds9 release\))] D
/h157 [(0.140\240\240)(Patch Release 1.4.3 \(internal ds9 release\))] D
/h158 [(0.141\240\240)(Patch Release 1.4.2 \(internal ds9 release\))] D
/h159 [(0.142\240\240)(Patch Release 1.4.1 \(internal ds9 release\))] D
/h160 [(0.143\240\240)(Public Release 1.4.0 \(15 August 2007\))] D
/h161 [(0.144\240\240)(Release 1.3.0b[n] \(mainly internal SAO beta releases\))] D
/h162 [(0.145\240\240)(Patch Release 1.2.4 \(internal SAO and beta release only\))] D
/h163 [(0.146\240\240)(Patch Release 1.2.3 \(12 January 2004\))] D
/h164 [(0.147\240\240)(Patch Release 1.2.3b1 \(19 August 2003\))] D
/h165 [(0.148\240\240)(Patch Release 1.2.2 \(18 May 2003\))] D
/h166 [(0.149\240\240)(Patch Release 1.2.1 \(24 April 2003\))] D
/h167 [(0.150\240\240)(Public Release 1.2.0 \(24 March 2003\))] D
/h168 [(0.151\240\240)(Beta Release 1.2.b3 \(4 February 2003\))] D
/h169 [(0.152\240\240)(Beta Release 1.2.b2 \(7 October 2002\))] D
/h170 [(0.153\240\240)(Beta Release 1.2.b1 \(24 September 2002\))] D
/h171 [(0.154\240\240)(Public Release 1.1.0 \(22 April 2002\))] D
/h172 [(0.155\240\240)(Pre-Release 1.1.0e \(10 April 2002\))] D
/h173 [(0.156\240\240)(Pre-Release 1.1.0e \(19 March 2002\))] D
/h174 [(0.157\240\240)(Pre-Release 1.1.0e \(27 February 2002\))] D
/h175 [(0.158\240\240)(Pre-Release 1.1.0e \(11 February 2002\))] D
/h176 [(0.159\240\240)(Beta Release 1.0.1b5 \(31 January 2002\))] D
/h177 [(0.160\240\240)(Beta Release 1.0.1b4 \(26 January 2002\))] D
/h178 [(0.161\240\240)(Beta Release 1.0.1b3 \(4 January 2002\))] D
/h179 [(0.162\240\240)(Beta Release 1.0.1b2 \(14 November 2001\))] D
/h180 [(0.163\240\240)(Beta Release 1.0.1b1 \(6 November 2001\))] D
/h181 [(0.164\240\240)(Public Release 1.0.0 \(31 July 2001\))] D
/h182 [(0.164.0.0.1\240\240)(Last updated: 22 April 2002)] D
/Hr [-63 63 64 65 -66 -66 66 -67 67 68 69 70 71 72 73 74 75 76 77 78 79
80 81 82 -83 -83 83 -85 85 86 87 -88 -88 88 -91 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
-117 117 -120 120 121 122 123 124 125 126 127 128 129 130 131 -132 -132
132 -134 134 135 136 137 138 139 140 141 142 143 -144 -144 144 -146 146
147 148 149 150 151 152 153 154 155 156 157 -158 -158 158 -165 165 166 167
168 169 170 171 172 173 174 -175 -175 175 -177 177 178 179 -180 -180 180
-182 182 183 184 185 186 187 188 189 190 191 192 193 -194 -194 194 -196
196 197 198 199 -200 -200 200 -202 202 203 204 -205 -205 205 -207 207 208
209 210 211 212 -213 -213 213 -215 215 216 217 218 219 220 221 -222 -222
222 -224 224 225 226 -227 -227 227 -230 230 231 232 -233 -233 233 -235 235
236 237 -238 -238 238 -239 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 -267
267]D
/HV [1 2 2 2 3 4 5 1 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 3 4 5 1 2 2 2 3 4
5 1 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 3 4 5 1 2 2 2 2
2 2 2 2 2 2 2 2 3 4 5 1 2 2 2 2 2 2 2 2 2 2 3 4 5 1 2 2 2 2 2 2 2 2 2 2
2 2 3 4 5 1 2 2 2 2 2 2 2 2 2 2 3 4 5 1 2 2 2 3 4 5 1 2 2 2 2 2 2 2 2 2
2 2 2 3 4 5 1 2 2 2 2 3 4 5 1 2 2 2 3 4 5 1 2 2 2 2 2 2 3 4 5 1 2 2 2 2
2 2 2 3 4 5 1 2 2 2 3 4 5 1 2 2 2 3 4 5 1 2 2 2 3 4 5 1 2 2 2 2 2 2 2 2
2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 3 4 5]D
/Cn [3 0 0 1 1 1 0 16 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 0 3 0 0 1 1 1
0 26 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 0 12 0 0 0
0 0 0 0 0 0 0 0 1 1 1 0 10 0 0 0 0 0 0 0 0 0 1 1 1 0 12 0 0 0 0 0 0 0 0
0 0 0 1 1 1 0 10 0 0 0 0 0 0 0 0 0 1 1 1 0 3 0 0 1 1 1 0 12 0 0 0 0 0 0
0 0 0 0 0 1 1 1 0 4 0 0 0 1 1 1 0 3 0 0 1 1 1 0 6 0 0 0 0 0 1 1 1 0 7 0
0 0 0 0 0 1 1 1 0 3 0 0 1 1 1 0 3 0 0 1 1 1 0 3 0 0 1 1 1 0 28 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 0]D
Hr length 0 gt{[/PageMode /UseOutlines /DOCVIEW pdfmark}if
/Hn 1 D
0 1 Hr length 1 sub{
 /Bn E D [Cn Bn get dup 0 gt{/Count E HV Bn get Bl ge{neg}if}{pop}ie
 /Dest Hr Bn get dup abs ST cvs cvn E 0 ge{(h)Hn ST cvs join cvx exec
 dup 1 get E Nf{0 get E join}{pop}ie /Hn Hn 1 add D}{()}ie
 /Title E dup length 255 gt{0 255 getinterval}if /OUT pdfmark}for
ZF /FN Fp D Ps 0 FS /WC Wf{( )}{<A1A1>}ie SW pop D
ET RC ZF
/Df f D
/R1 (http://hea-www.harvard.edu/saord/ds9/index.html) D
/R2 (http://hea-www.harvard.edu/saord/xpa/index.html) D
/R3 (ftp://cfa-ftp.harvard.edu/pub/gsc/WCSTools/home.html) D
/R4 (http://tdc-www.harvard.edu/software/wcstools/) D
/R5 (http://hea-www.harvard.edu/RD/funtools/changelog.html) D
/R6 (http://hea-www.harvard.edu/RD/funtools/changelog_beta.html) D
/Ba f D /BO 0 D Bs
/UR (help.html) D
/Ti (The Funtools Help Facility) D
/Au () D
/Df f D
/ME [()] D
 TC

/Cb Db D /Ct [16#00 16#00 16#00] D /Cl [16#00 16#00 16#00] D /CL -1 D Ct Sc

/Ba f D /BO 0 D Bs
/UR (help.html) D
/Ti (The Funtools Help Facility) D
/Au () D
/Df f D
/ME [()] D
 TC

NP RC ZF
()1 Sl()WB 0 Sn(


)0 2 0 H(Funtools:)WB 63 Sn()WB 1 Sn( FITS Users Need Tools)EA()EH(


)0 2 1 H(Summary)WB 64 Sn()EH(
This document is the Table of Contents for Funtools.


)0 2 2 H(Description)WB 65 Sn()EH(
Funtools, is a "minimal buy-in" FITS library and utility package developed
at the the High Energy Astrophysics Division of SAO.  The Funtools
library provides simplified access to a wide array of file types:
standard astronomical FITS images and binary tables, raw arrays and
binary event lists, and even tables of ASCII column data.  A
sophisticated region filtering library \201compatible with ds9\202 filters
images and tables using boolean operations between geometric shapes,
support world coordinates, etc.  Funtools also supports advanced
capabilities such as optimized data searching using index files.

The main goal of the Funtools project has been to develop a minimal buy-in
FITS library for researchers who are occasional \201but serious\202 coders.  In
this case, "minimal buy-in" means "easy to learn, easy to use, and easy to
re-learn next month". We have tried to achieve this goal by emphasizing two
essential capabilities.  The first is the ability to develop FITS programs
without knowing much about FITS, i.e., without having to deal with the
arcane rules for generating a properly formatted FITS file.  The second is
to support the use of already-familiar C/Unix facilities, especially C
structs and Unix stdio. Taken together, these two capabilities should allow
researchers to leverage their existing programming expertise while
minimizing the need to learn new and complex coding rules.


)0 P(Choose from the following topics:

)0 P()UL()-1 LI()0 2 1 A(Funtools User Programs)2 1 TN TL()Ec /AF f D(
)UL()-1 LI()0 3 1 A(funcalc: Funtools calculator \201for binary tables\202)3 1 TN TL()Ec /AF f D(

)-1 LI()0 4 1 A(funcen: find centroid \201for binary tables\202)4 1 TN TL()Ec /AF f D(

)-1 LI()0 5 1 A(funcnts: count photons in specified regions)5 1 TN TL()Ec /AF f D(

)-1 LI()0 6 1 A(funcone: cone search on RA, Dec columns)6 1 TN TL()Ec /AF f D(

)-1 LI()0 7 1 A(fundisp: display data in a Funtools data file)7 1 TN TL()Ec /AF f D(

)-1 LI()0 8 1 A(funhead: display a header in a Funtools file)8 1 TN TL()Ec /AF f D(

)-1 LI()0 9 1 A(funhist: create a 1D histogram of a column)9 1 TN TL()Ec /AF f D(

)-1 LI()0 10 1 A(funimage: create a FITS image from a Funtools data file)10 1 TN TL()Ec /AF f D(

)-1 LI()0 11 1 A(funindex: create an index on a column in a binary table)11 1 TN TL()Ec /AF f D(

)-1 LI()0 12 1 A(funjoin: join two or more FITS binary tables on specified columns)12 1 TN TL()Ec /AF f D(

)-1 LI()0 13 1 A(funmerge: merge one or more Funtools table files)13 1 TN TL()Ec /AF f D(

)-1 LI()0 14 1 A(funsky: convert between image and sky coordinates, using WCS info from a FITS header)14 1 TN TL()Ec /AF f D(

)-1 LI()0 15 1 A(funtable: copy selected rows from a Funtools file to a FITS binary table)15 1 TN TL()Ec /AF f D(

)-1 LI()0 16 1 A(funtbl: extract a table from
Funtools ASCII output)16 1 TN TL()Ec /AF f D(

)-1 LI()0 17 1 A(funtools and ds9 image display)17 1 TN TL()Ec /AF f D(
)LU(

)-1 LI()0 18 1 A(Funtools Programming)18 1 TN TL()Ec /AF f D(
)UL()-1 LI()0 19 1 A(Funtools Programming Summary)19 1 TN TL()Ec /AF f D(

)-1 LI()0 20 1 A(Funtools Programming Tutorial)20 1 TN TL()Ec /AF f D(

)-1 LI()0 21 1 A(A Short Digression on Subroutine Order)21 1 TN TL()Ec /AF f D(

)-1 LI()0 22 1 A(Compiling and Linking)22 1 TN TL()Ec /AF f D(

)-1 LI()0 23 1 A(The Funtools Reference Handle)23 1 TN TL()Ec /AF f D(

)-1 LI()0 24 1 A(The Funtools Programming Reference Manual)24 1 TN TL()Ec /AF f D(
)UL()-1 LI( )0 25 1 A(FunOpen: open a Funtools file)25 1 TN TL()Ec /AF f D(

)-1 LI()0 26 1 A(FunImageGet: retrieve image data)26 1 TN TL()Ec /AF f D(

)-1 LI()0 27 1 A(FunImagePut: output image data)27 1 TN TL()Ec /AF f D(

)-1 LI()0 28 1 A(FunImageRowGet: retrieve image data by row)28 1 TN TL()Ec /AF f D(

)-1 LI()0 29 1 A(FunImageRowPut: output image data by row)29 1 TN TL()Ec /AF f D(

)-1 LI()0 30 1 A(FunTableRowGet: retrieve rows from a table)30 1 TN TL()Ec /AF f D(

)-1 LI()0 31 1 A(FunTableRowPut: output rows to a table)31 1 TN TL()Ec /AF f D(

)-1 LI()0 32 1 A(FunColumnSelect: select columns in a table for access)32 1 TN TL()Ec /AF f D(

)-1 LI()0 33 1 A(FunColumnActivate: activate columns in a table for read/write)33 1 TN TL()Ec /AF f D(

)-1 LI()0 34 1 A(FunColumnLookup: lookup info about  the columns in a table)34 1 TN TL()Ec /AF f D(

)-1 LI()0 35 1 A(FunInfoGet: get info about an image or table)35 1 TN TL()Ec /AF f D(

)-1 LI()0 36 1 A(FunInfoPut: put info about an image or table)36 1 TN TL()Ec /AF f D(

)-1 LI()0 37 1 A(FunParamGet: get header param)37 1 TN TL()Ec /AF f D(

)-1 LI()0 38 1 A(FunParamPut: put header param)38 1 TN TL()Ec /AF f D(

)-1 LI()0 39 1 A(FunFlush: flush I/O in a Funtools file)39 1 TN TL()Ec /AF f D(

)-1 LI()0 40 1 A(FunClose: close a Funtools file)40 1 TN TL()Ec /AF f D(
)LU(

)-1 LI()0 41 1 A(Funtools Programming Examples)41 1 TN TL()Ec /AF f D(

)UL( 
)-1 LI()0 2 A(evmerge: merge new columns with existing columns)EA(
)-1 LI()0 2 A(evcols: add column and rows to binary tables)EA(
)-1 LI()0 2 A(imblank: blank out image values below a threshold)EA()LU()LU(

)-1 LI()0 42 1 A(Funtools Data Files)42 1 TN TL()Ec /AF f D(

)UL( 
)-1 LI()0 43 1 A(Supported Data Formats)43 1 TN TL()Ec /AF f D(
)UL()-1 LI()0 44 1 A(FITS File and Extensions)44 1 TN TL()Ec /AF f D(
)-1 LI()0 45 1 A(Non-FITS Raw Event Files)45 1 TN TL()Ec /AF f D(
)-1 LI()0 46 1 A(Non-FITS Array Files)46 1 TN TL()Ec /AF f D(
)-1 LI()0 47 1 A(Column-based Text \201ASCII\202 Files)47 1 TN TL()Ec /AF f D(
)-1 LI()0 48 1 A(Database Views of Tables)48 1 TN TL()Ec /AF f D()LU(
)-1 LI()0 49 1 A(Image Sections and Blocking)49 1 TN TL()Ec /AF f D(
)-1 LI()0 50 1 A(Binning FITS Binary Tables and Non-FITS Event Files)EH(
)-1 LI()0 51 1 A(Disk Files and Other Supported File Types)50 1 TN TL()Ec /AF f D()LU(

)-1 LI(Funtools Data Filtering
)UL()-1 LI()0 52 1 A(Table Filtering)51 1 TN TL()Ec /AF f D(

)-1 LI()0 53 1 A(Fast Table Filtering using Indexes)52 1 TN TL()Ec /AF f D(

)-1 LI()0 54 1 A(Spatial Region Filtering)53 1 TN TL()Ec /AF f D(

)UL()-1 LI()0 55 1 A(Region Geometry)54 1 TN TL()Ec /AF f D(

)-1 LI()0 56 1 A(Region Algebra)55 1 TN TL()Ec /AF f D(

)-1 LI()0 57 1 A(Region Coordinates)56 1 TN TL()Ec /AF f D(

)-1 LI()0 58 1 A(Region Boundaries)57 1 TN TL()Ec /AF f D(

)-1 LI()0 59 1 A(Differences Between Funtools and IRAF Regions)58 1 TN TL()Ec /AF f D(
)LU(
)-1 LI()0 60 1 A(Combining Table and Region Filters)59 1 TN TL()Ec /AF f D(
)LU(

)-1 LI( Miscellaneous
)UL()-1 LI()0 61 1 A(Funtools Environment Variables)60 1 TN TL()Ec /AF f D(

)-1 LI()0 62 1 A(Funtools ChangeLog)61 1 TN TL()Ec /AF f D()LU(
)LU( 



)0 5 3 H(Last)WB 66 Sn( updated: January 6, 2006)EH(


)WB NL NP Ep ET /Tc f D
/Cb Db D /Ct [16#00 16#00 16#00] D /Cl [16#00 16#00 16#00] D /CL -1 D Ct Sc
DS
/Ba f D /BO 0 D Bs
/UR (programs.html) D
/Ti (Funtools Programs) D
/Au () D
/Df f D
/ME [()] D

0 BO R
()1 Sl()WB 2 Sn(
)0 2 4 H(Funtools)WB 67 Sn( Programs)EH(

)0 2 5 H(Summary)WB 68 Sn()EH(

)0 P() 27 129 PR()0 3 1 A(funcalc)3 0 TN TL()Ec /AF f D( [-n] [-a argstr] [-e expr] [-f file] [-l link] [-p prog] [-u] <iname> [oname [columns]]

)0 4 1 A(funcen)4 0 TN TL()Ec /AF f D( [-i] [-n iter] [-t tol] [-v lev] <iname> <region>

)0 5 1 A(funcnts)5 0 TN TL()Ec /AF f D( [switches] <source_file> [source_region] [bkgd_file] [bkgd_region|bkgd_cnts]

)0 6 1 A(funcone)6 0 TN TL()Ec /AF f D( [-n] [-x|-X|-j|-J] [[-l|-L] list] [-r ra_col] [-d dec_col]  <iname> <oname> <ra[hdr]> <dec[hdr]> <radius[dr'"]> [columns]

)0 7 1 A(fundisp)7 0 TN TL()Ec /AF f D( [-f format] [-l] [-n] [-T] <iname> [columns|bitpix=n]

)0 8 1 A(funhead)8 0 TN TL()Ec /AF f D( [-a] [-l] [-s] [-t] [-L] <iname> [oname ename]

)0 9 1 A(funhist)9 0 TN TL()Ec /AF f D( [-n|-w|-T] <iname> [column] [[lo_edge:hi_edge:]bins] 

)0 10 1 A(funimage)10 0 TN TL()Ec /AF f D( [-a] [-l] [-p x|y] <iname> <oname>  [bitpix=n]

)0 11 1 A(funindex)11 0 TN TL()Ec /AF f D( <iname> <key> [oname]

)0 12 1 A(funjoin)12 0 TN TL()Ec /AF f D( [switches] <ifile1> <ifile2> ... <ifilen> <ofile> 

)0 13 1 A(funmerge)13 0 TN TL()Ec /AF f D( <iname1> <iname2> ... <oname>

)0 14 1 A(funsky)14 0 TN TL()Ec /AF f D( [switches] <iname1> [<lname2> <col1> <col2>]

)0 15 1 A(funtable)15 0 TN TL()Ec /AF f D( [-a] [-i|-z] [-m] [-s cols] <iname> <oname> [columns]

)0 16 1 A(funtbl)16 0 TN TL()Ec /AF f D( [-c cols] [-h] [-n table] [-p prog] [-s sep] [-T] <iname>)RP(




)0 2 6 H(funcalc)WB 69 Sn()WB 3 Sn( - Funtools calculator \201for binary tables\202)EA()EH(

)BD() 1 90 PR(funcalc [-n] [-a argstr] [-e expr] [-f file] [-l link] [-p prog] <iname> [oname [columns]])RP()ES(


)0 P() 7 73 PR(  -a argstr    # user arguments to pass to the compiled program
  -e expr      # funcalc expression
  -f file      # file containing funcalc expression
  -l libs      # libs to add to link command  
  -n           # output generated code instead of compiling and executing
  -p prog      # generate named program, no execution
  -u           # die if any variable is undeclared \201don't auto-declare\202)RP(


)0 P()BD(funcalc)ES( is a calculator program that allows arbitrary
expressions to be constructed, compiled, and executed on columns in a
Funtools table \201FITS binary table or raw event file\202. It works by
integrating user-supplied expression\201s\202 into a template C program,
then compiling and executing the program. )BD(funcalc)ES( expressions
are C statements, although some important simplifications \201such
as automatic declaration of variables\202 are supported.

)0 P()BD(funcalc)ES( expressions can be specified in three ways: on the
command line using the )BD(-e [expression])ES( switch, in a file using
the )BD(-f [file])ES( switch, or from stdin \201if neither )BD(-e)ES( nor
)BD(-f)ES( is specified\202. Of course a file containing )BD(funcalc)ES(
expressions can be read from stdin.

)0 P(Each invocation of )BD(funcalc)ES( requires an input Funtools table
file to be specified as the first command line argument.  The output
Funtools table file is the second optional argument. It is needed only
if an output FITS file is being created \201i.e., in cases where the
)BD(funcalc)ES( expression only prints values, no output file is
needed\202. If input and output file are both specified, a third optional
argument can specify the list of columns to activate \201using 
)0 33 1 A(FunColumnActivate\201\202)33 0 TN TL()Ec /AF f D(\202.  Note
that )BD(funcalc)ES( determines whether or not to generate code for
writing an output file based on the presence or absence of an
output file argument.

)0 P(A )BD(funcalc)ES( expression executes on each row of a table and
consists of one or more C statements that operate on the columns of
that row \201possibly using temporary variables\202.  Within an expression,
reference is made to a column of the )BD(current)ES( row using the C
struct syntax )BD(cur->[colname])ES(, e.g. cur->x, cur->pha, etc.
Local scalar variables can be defined using C declarations at very the
beginning of the expression, or else they can be defined automatically
by )BD(funcalc)ES( \201to be of type double\202. Thus, for example, a swap of
columns x and y in a table can be performed using either of the
following equivalent )BD(funcalc)ES( expressions:

) 4 18 PR(  double temp;
  temp = cur->x;
  cur->x = cur->y;
  cur->y = temp;)RP(

or:

) 3 18 PR(  temp = cur->x;
  cur->x = cur->y;
  cur->y = temp;)RP(

When this expression is executed using a command such as:
) 1 40 PR(  funcalc -f swap.expr itest.ev otest.ev)RP(
the resulting file will have values of the x and y columns swapped.

)0 P(By default, the data type of the variable for a column is the same as
the data type of the column as stored in the file. This can be changed
by appending ":[dtype]" to the first reference to that column. In the
example above, to force x and y to be output as doubles, specify the
type 'D' explicitly:
) 3 20 PR(  temp = cur->x:D;
  cur->x = cur->y:D;
  cur->y = temp;)RP(

Data type specifiers follow standard FITS table syntax for defining
columns using TFORM:
)UL()-1 LI(A: ASCII characters
)-1 LI(B: unsigned 8-bit char
)-1 LI(I: signed 16-bit int
)-1 LI(U: unsigned 16-bit int \201not standard FITS\202
)-1 LI(J: signed 32-bit int
)-1 LI(V: unsigned 32-bit int \201not standard FITS\202
)-1 LI(E: 32-bit float
)-1 LI(D: 64-bit float
)-1 LI(X: bits \201treated as an array of chars\202)LU(
Note that only the first reference to a column should contain the
explicit data type specifier.

)0 P(Of course, it is important to handle the data type of the columns
correctly.  One of the most frequent cause of error in )BD(funcalc)ES(
programming is the implicit use of the wrong data type for a column in
expression.  For example, the calculation:
) 1 43 PR(  dx = \201cur->x - cur->y\202/\201cur->x + cur->y\202;)RP(
usually needs to be performed using floating point arithmetic. In
cases where the x and y columns are integers, this can be done by
reading the columns as doubles using an explicit type specification:
) 1 47 PR(  dx = \201cur->x:D - cur->y:D\202/\201cur->x + cur->y\202;)RP(

Alternatively, it can be done using C type-casting in the expression:
) 1 75 PR(  dx = \201\201double\202cur->x - \201double\202cur->y\202/\201\201double\202cur->x + \201double\202cur->y\202;)RP(

)0 P(In addition to accessing columns in the current row, reference also
can be made to the )BD(previous)ES( row using )BD(prev->[colname])ES(,
and to the )BD(next)ES( row using )BD(next->[colname])ES(.  Note that if
)BD(prev->[colname])ES( is specified in the )BD(funcalc)ES(
expression, the very first row is not processed.  If
)BD(next->[colname])ES( is specified in the )BD(funcalc)ES(
expression, the very last row is not processed. In this way,
)BD(prev)ES( and )BD(next)ES( are guaranteed always to point to valid
rows.  For example, to print out the values of the current x column
and the previous y column, use the C fprintf function in a
)BD(funcalc)ES( expression:
) 1 46 PR(  fprintf\201stdout, "%d %d\200n", cur->x, prev->y\202;)RP(

)0 P(New columns can be specified using the same )BD(cur->[colname])ES(
syntax by appending the column type \201and optional tlmin/tlmax/binsiz
specifiers\202, separated by colons. For example, cur->avg:D will define
a new column of type double. Type specifiers are the same those
used above to specify new data types for existing columns.

)0 P(For example, to create and output a new column that is the average value of the
x and y columns, a new "avg" column can be defined:
) 1 36 PR(  cur->avg:D = \201cur->x + cur->y\202/2.0)RP(
Note that the final ';' is not required for single-line expressions.

)0 P(As with FITS TFORM data type specification, the column data type
specifier can be preceded by a numeric count to define an array, e.g.,
"10I" means a vector of 10 short ints, "2E" means two single precision
floats, etc.  A new column only needs to be defined once in a
)BD(funcalc)ES( expression, after which it can be used without
re-specifying the type. This includes reference to elements of a
column array:

) 2 41 PR(  cur->avg[0]:2D = \201cur->x + cur->y\202/2.0;
  cur->avg[1] = \201cur->x - cur->y\202/2.0;)RP(

)0 P(The 'X' \201bits\202 data type is treated as a char array of dimension
\201numeric_count/8\202, i.e., 16X is processed as a 2-byte char array. Each
8-bit array element is accessed separately:
) 2 24 PR(  cur->stat[0]:16X  = 1;
  cur->stat[1]      = 2;)RP(
Here, a 16-bit column is created with the MSB is set to 1 and the LSB set to 2.

)0 P(By default, all processed rows are written to the specified output
file. If you want to skip writing certain rows, simply execute the C
"continue" statement at the end of the )BD(funcalc)ES( expression,
since the writing of the row is performed immediately after the
expression is executed. For example, to skip writing rows whose
average is the same as the current x value:

) 4 41 PR(  cur->avg[0]:2D = \201cur->x + cur->y\202/2.0;
  cur->avg[1] = \201cur->x - cur->y\202/2.0;
  if\201 cur->avg[0] == cur->x \202
    continue;)RP(

)0 P(If no output file argument is specified on the )BD(funcalc)ES( command
line, no output file is opened and no rows are written. This is useful
in expressions that simply print output results instead of generating
a new file:
) 5 73 PR(  fpv = \201cur->av3:D-cur->av1:D\202/\201cur->av1+cur->av2:D+cur->av3\202;
  fbv =  cur->av2/\201cur->av1+cur->av2+cur->av3\202;
  fpu = \201\201double\202cur->au3-cur->au1\202/\201\201double\202cur->au1+cur->au2+cur->au3\202;
  fbu =  cur->au2/\201double\202\201cur->au1+cur->au2+cur->au3\202;
  fprintf\201stdout, "%f\200t%f\200t%f\200t%f\200n", fpv, fbv, fpu, fbu\202;)RP(
In the above example, we use both explicit type specification
\201for "av" columns\202 and type casting \201for "au" columns\202 to ensure that
all operations are performed in double precision.

)0 P(When an output file is specified, the selected input table is
processed and output rows are copied to the output file.  Note that
the output file can be specified as "stdout" in order to write the
output rows to the standard output.  If the output file argument is
passed, an optional third argument also can be passed to specify which
columns to process.

)0 P(In a FITS binary table, it sometimes is desirable to copy all of the
other FITS extensions to the output file as well. This can be done by
appending a '+' sign to the name of the extension in the input file
name. See )BD(funtable)ES( for a related example.

)0 P()BD(funcalc)ES( works by integrating the user-specified expression
into a template C program called )0 2 A(tabcalc.c)EA(.
The completed program then is compiled and executed. Variable
declarations that begin the )BD(funcalc)ES( expression are placed in
the local declaration section of the template main program.  All other
lines are placed in the template main program's inner processing
loop. Other details of program generation are handled
automatically. For example, column specifiers are analyzed to build a
C struct for processing rows, which is passed to 
)0 32 1 A(FunColumnSelect\201\202)32 0 TN TL()Ec /AF f D( and used
in )0 30 1 A(FunTableRowGet\201\202)30 0 TN TL()Ec /AF f D(.  If
an unknown variable is used in the expression, resulting in a
compilation error, the program build is retried after defining the
unknown variable to be of type double.

)0 P(Normally, )BD(funcalc)ES( expression code is added to
)BD(funcalc)ES( row processing loop. It is possible to add code
to other parts of the program by placing this code inside
special directives of the form:
) 3 26 PR(  [directive name]
    ... code goes here ...
  end)RP(

The directives are:
)UL()-1 LI()BD(global)ES( add code and declarations in global space, before the main routine.

)-1 LI()BD(local)ES( add declarations \201and code\202 just after the local declarations in
main

)-1 LI()BD(before)ES( add code just before entering the main row processing loop

)-1 LI()BD(after)ES( add code just after exiting the main row processing loop)LU(

Thus, the following )BD(funcalc)ES( expression will declare global
variables and make subroutine calls just before and just after the
main processing loop:
) 16 62 PR(  global
    double v1, v2;
    double init\201void\202;
    double finish\201double v\202;
  end
  before
    v1  = init\201\202;
  end
  ... process rows, with calculations using v1 ...
  after
    v2 = finish\201v1\202;
    if\201 v2 < 0.0 \202{
      fprintf\201stderr, "processing failed %g -> %g\200n", v1, v2\202;
      exit\2011\202;
    }
  end)RP(
Routines such as init\201\202 and finish\201\202 above are passed to the generated
program for linking using the )BD(-l [link directives ...])ES(
switch. The string specified by this switch will be added to the link
line used to build the program \201before the funtools library\202. For
example, assuming that init\201\202 and finish\201\202 are in the library
libmysubs.a in the /opt/special/lib directory, use:
) 1 47 PR(  funcalc  -l "-L/opt/special/lib -lmysubs" ...)RP(

)0 P(User arguments can be passed to a compiled funcalc program using a string
argument to the "-a" switch.  The string should contain all of the
user arguments. For example, to pass the integers 1 and 2, use:
) 1 22 PR(  funcalc -a "1 2" ...)RP(
The arguments are stored in an internal array and are accessed as
strings via the ARGV\201n\202 macro.  For example, consider the following
expression:
) 11 60 PR(  local
    int pmin, pmax;
  end

  before
    pmin=atoi\201ARGV\2010\202\202;
    pmax=atoi\201ARGV\2011\202\202;
  end

  if\201 \201cur->pha >= pmin\202 && \201cur->pha <= pmax\202 \202
    fprintf\201stderr, "%d %d %d\200n", cur->x, cur->y, cur->pha\202;)RP(
This expression will print out x, y, and pha values for all rows in which
the pha value is between the two user-input values:
) 11 51 PR(  funcalc -a '1 12' -f foo snr.ev'[cir 512 512 .1]'
  512 512 6
  512 512 8
  512 512 5
  512 512 5
  512 512 8

  funcalc -a '5 6' -f foo snr.ev'[cir 512 512 .1]'
  512 512 6
  512 512 5
  512 512 5)RP(

)0 P(Note that it is the user's responsibility to ensure that the correct
number of arguments are passed. The ARGV\201n\202 macro returns a NULL if a
requested argument is outside the limits of the actual number of args,
usually resulting in a SEGV if processed blindly.  To check the
argument count, use the ARGC macro:
) 12 42 PR(  local
    long int seed=1;
    double limit=0.8;
  end

  before
    if\201 ARGC >= 1 \202 seed = atol\201ARGV\2010\202\202;
    if\201 ARGC >= 2 \202 limit = atof\201ARGV\2011\202\202;
    srand48\201seed\202;
  end

  if \201 drand48\201\202 > limit \202 continue;)RP(

)0 P(The macro WRITE_ROW expands to the FunTableRowPut\201\202 call that writes
the current row. It can be used to write the row more than once.  In
addition, the macro NROW expands to the row number currently being
processed. Use of these two macros is shown in the following example:
) 7 41 PR(  if\201 cur->pha:I == cur->pi:I \202 continue;
  a = cur->pha;
  cur->pha = cur->pi;
  cur->pi = a;
  cur->AVG:E  = \201cur->pha+cur->pi\202/2.0;
  cur->NR:I = NROW;
  if\201 NROW < 10 \202 WRITE_ROW;)RP(

)0 P(If the )BD(-p [prog])ES( switch is specified, the expression is not
executed. Rather, the generated executable is saved with the specified
program name for later use.

)0 P(If the )BD(-n)ES( switch is specified, the expression is not
executed. Rather, the generated code is written to stdout. This is
especially useful if you want to generate a skeleton file and add your
own code, or if you need to check compilation errors. Note that the
comment at the start of the output gives the compiler command needed
to build the program on that platform. \201The command can change from
platform to platform because of the use of different libraries,
compiler switches, etc.\202

)0 P(As mentioned previously, )BD(funcalc)ES( will declare a scalar
variable automatically \201as a double\202 if that variable has been used
but not declared.  This facility is implemented using a sed script
named )0 2 A(funcalc.sed)EA(, which processes the
compiler output to sense an undeclared variable error.  This script
has been seeded with the appropriate error information for gcc, and for
cc on Solaris, DecAlpha, and SGI platforms. If you find that automatic
declaration of scalars is not working on your platform, check this sed
script; it might be necessary to add to or edit some of the error
messages it senses.

)0 P(In order to keep the lexical analysis of )BD(funcalc)ES( expressions
\201reasonably\202 simple, we chose to accept some limitations on how
accurately C comments, spaces, and new-lines are placed in the
generated program. In particular, comments associated with local
variables declared at the beginning of an expression \201i.e., not in a
)BD(local...end)ES( block\202 will usually end up in the inner loop, not
with the local declarations:
) 8 69 PR(  /* this comment will end up in the wrong place \201i.e, inner loop\202 */
  double a; /* also in wrong place */
  /* this will be in the the right place \201inner loop\202 */
  if\201 cur->x:D == cur->y:D \202 continue; /* also in right place */
  a = cur->x;
  cur->x = cur->y;
  cur->y = a;
  cur->avg:E  = \201cur->x+cur->y\202/2.0;)RP(
Similarly, spaces and new-lines sometimes are omitted or added in a
seemingly arbitrary manner. Of course, none of these stylistic
blemishes affect the correctness of the generated code.

)0 P(Because )BD(funcalc)ES( must analyze the user expression using the data
file\201s\202 passed on the command line, the input file\201s\202 must be opened
and read twice: once during program generation and once during
execution. As a result, it is not possible to use stdin for the
input file: )BD(funcalc)ES( cannot be used as a filter. We will
consider removing this restriction at a later time.

)0 P(Along with C comments, )BD(funcalc)ES( expressions can have one-line
internal comments that are not passed on to the generated C
program. These internal comment start with the )BD(#)ES( character and
continue up to the new-line:
) 7 56 PR(  double a; # this is not passed to the generated C file
  # nor is this
  a = cur->x;
  cur->x = cur->y;
  cur->y = a;
  /* this comment is passed to the C file */
  cur->avg:E  = \201cur->x+cur->y\202/2.0;)RP(

)0 P(As previously mentioned, input columns normally are identified by
their being used within the inner event loop. There are rare cases
where you might want to read a column and process it outside the main
loop. For example, qsort might use a column in its sort comparison
routine that is not processed inside the inner loop \201and therefore not
implicitly specified as a column to be read\202.  To ensure that such a
column is read by the event loop, use the )BD(explicit)ES( keyword.
The arguments to this keyword specify columns that should be read into
the input record structure even though they are not mentioned in the
inner loop. For example:
 ) 1 17 PR(  explicit pi pha)RP(
will ensure that the pi and pha columns are read for each row,
even if they are not processed in the inner event loop. The )BD(explicit)ES(
statement can be placed anywhere.

)0 P(Finally, note that )BD(funcalc)ES( currently works on expressions
involving FITS binary tables and raw event files. We will consider
adding support for image expressions at a later point, if there is
demand for such support from the community.




)0 2 7 H(funcen)WB 70 Sn()WB 4 Sn( - find centroid \201for binary tables\202)EA()EH(

)BD() 1 56 PR(funcen [-i] [-n iter] [-t tol] [-v lev] <iname> <region>)RP()ES(


)0 P() 4 64 PR(  -i            # use image filtering \201default: event filtering\202
  -n iter       # max number of iterations \201default: 0\202
  -t tol        # pixel tolerance distance \201default: 1.0\202
  -v [0,1,2,3]  # output verbosity level \201default: 0\202)RP(


)0 P()BD(funcen)ES( iteratively calculates the centroid position within one
or more regions of a Funtools table \201FITS binary table or raw event
file\202.  Starting with an input table, an initial region specification,
and an iteration count, the program calculates the average x and y
position within the region and then uses this new position as the
region center for the next iteration. Iteration terminates when the
maximum number of iterations is reached or when the input tolerance
distance is met for that region. A count of events in the final region
is then output, along with the pixel position value \201and, where
available, WCS position\202.

)0 P(The first argument to the program specifies the Funtools table file to
process.  Since the file must be read repeatedly, a value of "stdin"
is not permitted when the number of iterations is non-zero.  Use 
)0 42 1 A(Funtools Bracket Notation)42 0 TN TL()Ec /AF f D( to specify FITS
extensions and filters.

)0 P(The second required argument is the initial region descriptor. Multiple
regions are permitted. However, compound regions \201accelerators,
variable argument regions and regions connected via boolean algebra\202
are not permitted. Points and polygons also are illegal. These
restrictions might be lifted in a future version, if warranted.

)0 P(The )BD(-n)ES( \201iteration number\202 switch specifies the maximum number of
iterations to perform. The default is 0, which means that the program will
simply count and display the number of events in the initial region\201s\202.
Note that when iterations is 0, the data can be input via stdin.

)0 P(The )BD(-t)ES( \201tolerance\202 switch specifies a floating point tolerance
value. If the distance between the current centroid position value and
the last position values is less than this value, iteration terminates.
The default value is 1 pixel.

)0 P(The )BD(-v)ES( \201verbosity\202 switch specifies the verbosity level of the
output. The default is 0, which results in a single line of output for
each input region consisting of the following values:
) 1 30 PR(  counts x y [ra dec coordsys])RP(
The last 3 WCS values are output if WCS information is available in the
data file header. Thus, for example:
) 5 47 PR(  [sh] funcen -n 0 snr.ev "cir 505 508 5"
  915 505.00 508.00 345.284038 58.870920 j2000

  [sh] funcen -n 3 snr.ev "cir 505 508 5"
  1120 504.43 509.65 345.286480 58.874587 j2000)RP(
The first example simply counts the number of events in the initial region.
The second example iterates the centroid calculation three times to determine
a final "best" position.

)0 P( 
Higher levels of verbosity obviously imply more verbose output. At
level 1, the output essentially contains the same information as level
0, but with keyword formatting:

  [sh] funcen -v 1 -n 3 snr.ev "cir 505 508 5"
  event_file:     snr.ev
  initial_region: cir 505 508 5
  tolerance:      1.0000
  iterations:     1

  events:         1120
  x,y\201physical\202:  504.43 509.65
  ra,dec\201j2000\202:  345.286480 58.874587
  final_region1:  cir 504.43 509.65 5)RP(
Level 2 outputs results from intermediate calculations as well.

)0 P(Ordinarily, region filtering is performed using analytic \201event\202
filtering, i.e. that same style of filtering as is performed by
)BD(fundisp)ES( and )BD(funtable)ES(. Use the )BD(-i)ES( switch to specify image
filtering, i.e. the same style filtering as is performed by )BD(funcnts)ES(.
Thus, you can perform a quick calculation of counts in regions, using
either the analytic or image filtering method, by specifying the
 )BD(-n 0)ES( and optional )BD(-i)ES( switches. These two method often
give different results because of how boundary events are processed:
) 5 46 PR(  [sh] funcen  snr.ev "cir 505 508 5"
  915 505.00 508.00 345.284038 58.870920 j2000

  [sh] funcen -i snr.ev "cir 505 508 5"
  798 505.00 508.00 345.284038 58.870920 j2000)RP(
See )0 58 1 A(Region Boundaries)58 0 TN TL()Ec /AF f D( for more information
about how boundaries are calculated using these two methods.




)0 2 8 H(funcnts)WB 71 Sn()WB 5 Sn( - count photons in specified regions, with bkgd subtraction)EA()EH(


)BD() 1 86 PR(funcnts  [switches] <source_file> [source_region] [bkgd_file] [bkgd_region|bkgd_value])RP()ES(


)0 P() 16 79 PR(  -e "source_exposure[;bkgd_exposure]"
                # source \201bkgd\202 FITS exposure image using matching files
  -w "source_exposure[;bkgd_exposure]"
                # source \201bkgd\202 FITS exposure image using WCS transform
  -t "source_timecorr[;bkgd_timecorr]"
                # source \201bkgd\202 time correction value or header parameter name
  -g            # output using nice g format
  -G            # output using %.14g format \201maximum precision\202
  -i "[column;]int1;int2..." # column-based intervals
  -m            # match individual source and bkgd regions
  -p            # output in pixels, even if wcs is present
  -r            # output inner/outer radii \201and angles\202 for annuli \201and pandas\202
  -s            # output summed values
  -v "scol[;bcol]" # src and bkgd value columns for tables
  -T            # output in starbase/rdb format
  -z            # output regions with zero area)ES()RP(


)0 P()BD(funcnts)ES( counts photons in the specified source regions and
reports the results for each region. Regions are specified using the
)0 54 1 A(Spatial Region Filtering)54 0 TN TL()Ec /AF f D( mechanism.
Photons are also counted in the specified bkgd regions applied to the
same data file or a different data file. \201Alternatively, a constant
background value in counts/pixel**2 can be specified.\202  The bkgd regions
are either paired one-to-one with source regions or pooled and
normalized by area, and then subtracted from the source counts in each
region.  Displayed results include the bkgd-subtracted counts in each
region, as well as the error on the counts, the area in
each region, and the surface brightness \201cnts/area**2\202 calculated for
each region.

)0 P(The first argument to the program specifies the FITS input image, array, or
raw event file to process.  If "stdin" is specified, data are read from
the standard input. Use )0 42 1 A(Funtools Bracket
Notation)42 0 TN TL()Ec /AF f D( to specify FITS extensions, image sections, and filters.

)0 P(The optional second argument is the source region descriptor.  If no
region is specified, the entire field is used.

)0 P(The background arguments can take one of two forms, depending on
whether a separate background file is specified. If the source
file is to be used for background as well, the third argument can be
either the background region, or a constant value denoting background
cnts/pixel.  Alternatively, the third argument can be a background
data file, in which case the fourth argument is the background region.
If no third argument is specified, a constant value of 0 is used
\201i.e., no background\202.

)0 P(In summary, the following command arguments are valid:
) 5 77 PR(  [sh] funcnts sfile                        # counts in source file
  [sh] funcnts sfile sregion                # counts in source region
  [sh] funcnts sfile sregion bregion        # bkgd reg. is from source file
  [sh] funcnts sfile sregion bvalue         # bkgd reg. is constant
  [sh] funcnts sfile sregion bfile bregion  # bkgd reg. is from separate file)RP(

)0 P(NB: unlike other Funtools programs, source and background regions are
specified as separate arguments on the command line, rather than being
placed inside brackets as part of the source and background filenames.
This is because regions in funcnts are not simply used as data
filters, but also are used to calculate areas, exposure, etc. If you
put the source region inside the brackets \201i.e. use it simply as a
filter\202 rather than specifying it as argument two, the program still
will only count photons that pass the region filter. However, the area
calculation will be performed on the whole field, since field\201\202 is the
default source region. This rarely is the desired behavior. On the
other hand, with FITS binary tables, it often is useful to put a column
filter in the filename brackets, so that only events matching the
column filter are counted inside the region.

)0 P(For example, to extract the counts within a radius of 22 pixels from the
center of the FITS binary table snr.ev and subtract the background determined
from the same image within an annulus of radii 50-100 pixels:
) 33 82 PR(  [sh] funcnts snr.ev "circle\201502,512,22\202" "annulus\201502,512,50,100\202"
  # source
  #   data file:        snr.ev
  #   degrees/pix:      0.00222222
  # background
  #   data file:        snr.ev
  # column units
  #   area:             arcsec**2
  #   surf_bri:         cnts/arcsec**2
  #   surf_err:         cnts/arcsec**2

  # background-subtracted results
   reg   net_counts     error   background    berror      area  surf_bri  surf_err
  ---- ------------ --------- ------------ --------- --------- --------- ---------
     1     3826.403    66.465      555.597     5.972  96831.98     0.040     0.001
  

  # the following source and background components were used:
  source region\201s\202
  ----------------
  circle\201502,512,22\202
  
   reg       counts    pixels
  ---- ------------ ---------
     1     4382.000      1513
  
  background region\201s\202
  --------------------
  annulus\201502,512,50,100\202
  
   reg       counts    pixels)WR(
  ---- ------------ ---------
  all      8656.000     23572)RP(
The area units for the output columns labeled "area", "surf_bri"
\201surface brightness\202 and "surf_err" will be given either in
arc-seconds \201if appropriate WCS information is in the data file
header\201s\202\202 or in pixels. If the data file has WCS info, but you do not
want arc-second units, use the )BD(-p)ES( switch to force output in
pixels.  Also, regions having zero area are not normally included in
the primary \201background-subtracted\202 table, but are included in the
secondary source and bkgd tables. If you want these regions to be
included in the primary table, use the )BD(-z)ES( switch.

)0 P(Note that a simple sed command will extract the background-subtracted results
for further analysis:
) 6 79 PR(  [sh] cat funcnts.sed
  1,/---- .*/d
  /^$/,$d

  [sh] sed -f funcnts.sed funcnts.out
  1     3826.403    66.465      555.597     5.972  96831.98     0.040     0.001)RP(

)0 P(If separate source and background files are specified, )BD(funcnts)ES( will
attempt to normalize the the background area so that the background
pixel size is the same as the source pixel size. This normalization
can only take place if the appropriate WCS information is contained in
both files \201e.g. degrees/pixel values in CDELT\202. If either
file does not contain the requisite size information, the normalization
is not performed. In this case, it is the user's responsibility to
ensure that the pixel sizes are the same for the two files.

)0 P(Normally, if more than one background region is specified, )BD(funcnts)ES(
will combine them all into a single region and use this background
region to produce the background-subtracted results for each source
region. The )BD(-m)ES( \201match multiple backgrounds\202 switch tells
)BD(funcnts)ES( to make a one to one correspondence between background and
source regions, instead of using a single combined background region.
For example, the default case is to combine 2 background
regions into a single region and then apply that region to each of the
source regions:

) 35 82 PR(  [sh] funcnts snr.ev "annulus\201502,512,0,22,n=2\202" "annulus\201502,512,50,100,n=2\202"
  # source
  #   data file:        snr.ev
  #   degrees/pix:      0.00222222
  # background
  #   data file:        snr.ev
  # column units
  #   area:             arcsec**2
  #   surf_bri:         cnts/arcsec**2
  #   surf_err:         cnts/arcsec**2
  
  # background-subtracted results
   reg   net_counts     error   background    berror      area  surf_bri  surf_err
  ---- ------------ --------- ------------ --------- --------- --------- ---------
     1     3101.029    56.922      136.971     1.472  23872.00     0.130     0.002
     2      725.375    34.121      418.625     4.500  72959.99     0.010     0.000
  
  
  # the following source and background components were used:
  source region\201s\202
  ----------------
  annulus\201502,512,0,22,n=2\202
  
   reg       counts    pixels
  ---- ------------ ---------
     1     3238.000       373
     2     1144.000      1140
  
  background region\201s\202
  --------------------
  annulus\201502,512,50,100,n=2\202)WR(
  
   reg       counts    pixels
  ---- ------------ ---------
  all      8656.000     23572)RP(
Note that the basic region filter rule "each photon is counted once
and no photon is counted more than once" still applies when using The
)BD(-m)ES( to match background regions. That is, if two background
regions overlap, the overlapping pixels will be counted in only one of
them. In a worst-case scenario, if two background regions are the same
region, the first will get all the counts and area and the second
will get none.

)0 P(Using the )BD(-m)ES( switch causes )BD(funcnts)ES( to use each of the two
background regions independently with each of the two source regions:

) 36 82 PR(  [sh] funcnts -m snr.ev "annulus\201502,512,0,22,n=2\202" "ann\201502,512,50,100,n=2\202"
  # source
  #   data file:        snr.ev
  #   degrees/pix:      0.00222222
  # background
  #   data file:        snr.ev
  # column units
  #   area:             arcsec**2
  #   surf_bri:         cnts/arcsec**2
  #   surf_err:         cnts/arcsec**2
  
  # background-subtracted results
   reg   net_counts     error   background    berror      area  surf_bri  surf_err
  ---- ------------ --------- ------------ --------- --------- --------- ---------
     1     3087.015    56.954      150.985     2.395  23872.00     0.129     0.002
     2      755.959    34.295      388.041     5.672  72959.99     0.010     0.000
  
  
  # the following source and background components were used:
  source region\201s\202
  ----------------
  annulus\201502,512,0,22,n=2\202
  
   reg       counts    pixels
  ---- ------------ ---------
     1     3238.000       373
     2     1144.000      1140
  
  background region\201s\202
  --------------------
  ann\201502,512,50,100,n=2\202)WR(
  
   reg       counts    pixels
  ---- ------------ ---------
     1     3975.000      9820
     2     4681.000     13752)RP(

)0 P(Note that most floating point quantities are displayed using "f"
format. You can change this to "g" format using the )BD(-g)ES(
switch.  This can be useful when the counts in each pixel is very
small or very large. If you want maximum precision and don't care
about the columns lining up nicely, use )BD(-G)ES(, which outputs
all floating values as %.14g.

)0 P(When counting photons using the annulus and panda \201pie and annuli\202
shapes, it often is useful to have access to the radii \201and panda
angles\202 for each separate region. The )BD(-r)ES( switch will add radii
and angle columns to the output table:

) 37 122 PR(  [sh] funcnts -r snr.ev "annulus\201502,512,0,22,n=2\202" "ann\201502,512,50,100,n=2\202"
  # source
  #   data file:        snr.ev
  #   degrees/pix:      0.00222222
  # background
  #   data file:        snr.ev
  # column units
  #   area:             arcsec**2
  #   surf_bri:         cnts/arcsec**2
  #   surf_err:         cnts/arcsec**2
  #   radii:            arcsecs
  #   angles:           degrees
  
  # background-subtracted results
   reg   net_counts     error   background    berror      area  surf_bri  surf_err   radius1   radius2    angle1    angle2
  ---- ------------ --------- ------------ --------- --------- --------- --------- --------- --------- --------- ---------
     1     3101.029    56.922      136.971     1.472  23872.00     0.130     0.002      0.00     88.00        NA        NA
     2      725.375    34.121      418.625     4.500  72959.99     0.010     0.000     88.00    176.00        NA        NA
  
  
  # the following source and background components were used:
  source region\201s\202
  ----------------
  annulus\201502,512,0,22,n=2\202
  
   reg       counts    pixels
  ---- ------------ ---------
     1     3238.000       373
     2     1144.000      1140
  
  background region\201s\202)WR(
  --------------------
  ann\201502,512,50,100,n=2\202
  
   reg       counts    pixels
  ---- ------------ ---------
  all      8656.000     23572)RP(

)0 P(Radii are given in units of pixels or arc-seconds \201depending on the
presence of WCS info\202, while the angle values \201when present\202 are in
degrees.  These columns can be used to plot radial profiles. For
example, the script )BD(funcnts.plot)ES( in the funtools
distribution\202 will plot a radial profile using gnuplot \201version 3.7 or
above\202. A simplified version of this script is shown below:

) 74 79 PR(  #!/bin/sh
  
  if [ x"$1" = xgnuplot ]; then
    if [ x`which gnuplot 2>/dev/null` = x ]; then
      echo "ERROR: gnuplot not available"
      exit 1
    fi
    awk '
    BEGIN{HEADER=1; DATA=0; FILES=""; XLABEL="unknown"; YLABEL="unknown"}
    HEADER==1{
      if\201 $1 == "#" && $2 == "data" && $3 == "file:" \202{
        if\201 FILES != "" \202 FILES = FILES ","
        FILES = FILES $4
      }
      else if\201 $1 == "#" && $2 == "radii:" \202{
        XLABEL = $3
      }
      else if\201 $1 == "#" && $2 == "surf_bri:" \202{
        YLABEL = $3
      }
      else if\201 $1 == "----" \202{
        printf "set nokey; set title \200"funcnts\201%s\202\200"\200n", FILES
        printf "set xlabel \200" radius\201%s\202\200"\200n", XLABEL
        printf "set ylabel \200"surf_bri\201%s\202\200"\200n", YLABEL
        print  "plot \200"-\200" using 3:4:6:7:8 with boxerrorbars"
        HEADER = 0
        DATA = 1
        next
      }
    }
    DATA==1{)WR(
      if\201 NF == 12 \202{
        print $9, $10, \201$9+$10\202/2, $7, $8, $7-$8, $7+$8, $10-$9
      }
      else{
        exit
      }
    }
    ' | gnuplot -persist - 1>/dev/null 2>&1
  
  elif [ x"$1" = xds9 ]; then
    awk '
    BEGIN{HEADER=1; DATA=0; XLABEL="unknown"; YLABEL="unknown"}
    HEADER==1{
      if\201 $1 == "#" && $2 == "data" && $3 == "file:" \202{
        if\201 FILES != "" \202 FILES = FILES ","
        FILES = FILES $4
      }
      else if\201 $1 == "#" && $2 == "radii:" \202{
        XLABEL = $3
      }
      else if\201 $1 == "#" && $2 == "surf_bri:" \202{
        YLABEL = $3
      }
      else if\201 $1 == "----" \202{
        printf "funcnts\201%s\202 radius\201%s\202 surf_bri\201%s\202 3\200n", FILES, XLABEL, YLABEL
        HEADER = 0
        DATA = 1
        next
      }
    })WR(
    DATA==1{
      if\201 NF == 12 \202{
        print $9, $7, $8
      }
      else{
        exit
      }
    }
    '
  else
    echo "funcnts -r ... | funcnts.plot [ds9|gnuplot]"
    exit 1
  fi)RP(

Thus, to run )BD(funcnts)ES( and plot the results using gnuplot \201version 3.7
or above\202, use:
) 1 75 PR(  funcnts -r snr.ev "annulus\201502,512,0,50,n=5\202" ...  | funcnts.plot gnuplot)RP(

)0 P(The )BD(-s)ES( \201sum\202 switch causes )BD(funcnts)ES( to produce an
additional table of summed \201integrated\202 background subtracted values,
along with the default table of individual values:

) 51 82 PR(  [sh] funcnts -s snr.ev "annulus\201502,512,0,50,n=5\202" "annulus\201502,512,50,100\202"
  # source
  #   data file:        snr.ev
  #   degrees/pix:      0.00222222
  # background
  #   data file:        snr.ev
  # column units
  #   area:             arcsec**2
  #   surf_bri:         cnts/arcsec**2
  #   surf_err:         cnts/arcsec**2
  
  # summed background-subtracted results
  upto   net_counts     error   background    berror      area  surf_bri  surf_err
  ---- ------------ --------- ------------ --------- --------- --------- ---------
     1     2880.999    54.722      112.001     1.204  19520.00     0.148     0.003
     2     3776.817    65.254      457.183     4.914  79679.98     0.047     0.001
     3     4025.492    71.972     1031.508    11.087 179775.96     0.022     0.000
     4     4185.149    80.109     1840.851    19.786 320831.94     0.013     0.000
     5     4415.540    90.790     2873.460    30.885 500799.90     0.009     0.000
  
  
  # background-subtracted results
   reg       counts     error   background    berror      area  surf_bri  surf_err
  ---- ------------ --------- ------------ --------- --------- --------- ---------
     1     2880.999    54.722      112.001     1.204  19520.00     0.148     0.003
     2      895.818    35.423      345.182     3.710  60159.99     0.015     0.001
     3      248.675    29.345      574.325     6.173 100095.98     0.002     0.000
     4      159.657    32.321      809.343     8.699 141055.97     0.001     0.000
     5      230.390    37.231     1032.610    11.099 179967.96     0.001     0.000
  
  )WR(
  # the following source and background components were used:
  source region\201s\202
  ----------------
  annulus\201502,512,0,50,n=5\202
  
   reg       counts    pixels      sumcnts    sumpix
  ---- ------------ --------- ------------ ---------
     1     2993.000       305     2993.000       305
     2     1241.000       940     4234.000      1245
     3      823.000      1564     5057.000      2809
     4      969.000      2204     6026.000      5013
     5     1263.000      2812     7289.000      7825
  
  background region\201s\202
  --------------------
  annulus\201502,512,50,100\202
  
   reg       counts    pixels
  ---- ------------ ---------
  all      8656.000     23572)RP(

)0 P(The )BD(-t)ES( and )BD(-e)ES( switches can be used to apply timing and
exposure corrections, respectively, to the data. Please note that
these corrections are meant to be used qualitatively, since
application of more accurate correction factors is a complex and
mission-dependent effort. The algorithm for applying these simple
corrections is as follows:
) 9 63 PR(  C =  Raw Counts in Source Region
  Ac=  Area of Source Region
  Tc=  Exposure time for Source Data
  Ec=  Average exposure in Source Region, from exposure map

  B=   Raw Counts in Background Region
  Ab=  Area of Background Region
  Tb=  \201Exposure\202 time for Background Data
  Eb=  Average exposure in Background Region, from exposure map)RP(
Then, Net Counts in Source region is
) 1 37 PR(  Net=  C - B * \201Ac*Tc*Ec\202/\201Ab*Tb*Eb\202)RP(
with the standard propagation of errors for the Error on Net.
The net rate would then be
) 1 27 PR(  Net Rate = Net/\201Ac*Tc*Ec\202)RP(
The average exposure in each region is calculated by summing up the
pixel values in the exposure map for the given region and then
dividing by the number of pixels in that region. Exposure maps often
are generated at a block factor > 1 \201e.g., block 4 means that each
exposure pixel contains 4x4 pixels at full resolution\202 and
)BD(funcnts)ES( will deal with the blocking automatically. Using the
)BD(-e)ES( switch, you can supply both source and background exposure
files \201separated by ";"\202, if you have separate source and background
data files. If you do not supply a background exposure file to go with
a separate background data file, )BD(funcnts)ES( assumes that exposure
already has been applied to the background data file. In addition, it
assumes that the error on the pixels in the background data file is
zero.

)0 P(NB: The )BD(-e)ES( switch assumes that the exposure map overlays the
image file )BD(exactly)ES(, except for the block factor.  Each pixel in
the image is scaled by the block factor to access the corresponding
pixel in the exposure map. If your exposure map does not line up
exactly with the image, )BD(do not use)ES( the )BD(-e)ES( exposure
correction.  In this case, it still is possible to perform exposure
correction )BD(if)ES( both the image and the exposure map have valid
WCS information: use the )BD(-w)ES( switch so that the transformation
from image pixel to exposure pixel uses the WCS information. That is,
each pixel in the image region will be transformed first from image
coordinates to sky coordinates, then from sky coordinates to exposure
coordinates. Please note that using )BD(-w)ES( can increase the time
required to process the exposure correction considerably.

)0 P(A time correction can be applied to both source and
background data using the )BD(-t)ES( switch. The value for the correction can
either be a numeric constant or the name of a header parameter in
the source \201or background\202 file:
) 2 74 PR(  [sh] funcnts -t 23.4 ...            # number for source
  [sh] funcnts -t "LIVETIME;23.4" ... # param for source, numeric for bkgd)RP(
When a time correction is specified, it is applied to the net counts
as well \201see algorithm above\202, so that the units of surface brightness
become cnts/area**2/sec.

)0 P(The )BD(-i)ES( \201interval\202 switch is used to run )BD(funcnts)ES( on multiple
column-based intervals with only a single pass through the data. It is
equivalent to running )BD(funcnts)ES( several times with a different column
filter added to the source and background data each time. For each
interval, the full )BD(funcnts)ES( output is generated, with a linefeed
character \201^L\202 inserted between each run.  In addition, the output for
each interval will contain the interval specification in its header.
Intervals are very useful for generating X-ray hardness ratios
efficiently.  Of course, they are only supported when the input data
are contained in a table.

)0 P(Two formats are supported for interval specification. The most general
format is semi-colon-delimited list of filters to be used as intervals:
) 1 73 PR(  funcnts -i "pha=1:5;pha=6:10;pha=11:15" snr.ev "circle\201502,512,22\202" ...)RP(
Conceptually, this will be equivalent to running )BD(funcnts)ES( three times:
) 3 50 PR(  funcnts snr.ev'[pha=1:5]' "circle\201502,512,22\202"
  funcnts snr.ev'[pha=6:10]' "circle\201502,512,22\202"
  funcnts snr.ev'[pha=11:15]' "circle\201502,512,22\202")RP(
However, using the )BD(-i)ES( switch will require only one pass through
the data.

)0 P(Note that complex filters can be used to specify intervals:
) 1 64 PR(  funcnts -i "pha=1:5&)SY(\160)ES(=4;pha=6:10&)SY(\160)ES(=5;pha=11:15&)SY(\160)ES(=6" snr.ev ...)RP(
The program simply runs the data through each filter in turn and generates
three )BD(funcnts)ES( outputs, separated by the line-feed character.

)0 P(In fact, although the intent is to support intervals for hardness ratios,
the specified filters do not have to be intervals at all. Nor does one
"interval" filter have to be related to another. For example:
) 1 75 PR(  funcnts -i "pha=1:5;pi=6:10;energy=11:15" snr.ev "circle\201502,512,22\202" ...)RP(
is equivalent to running )BD(funcnts)ES( three times with unrelated filter
specifications.

)0 P(A second interval format is supported for the simple case in which a
single column is used to specify multiple homogeneous intervals for
that column. In this format, a column name is specified first,
followed by intervals:
) 1 65 PR(  funcnts -i "pha;1:5;6:10;11:15" snr.ev "circle\201502,512,22\202" ...)RP(
This is equivalent to the first example, but requires less typing. The
)BD(funcnts)ES( program will simply prepend "pha=" before each of the specified
intervals. \201Note that this format does not contain the "=" character in
the column argument.\202

)0 P(Ordinarily, when )BD(funcnts)ES( is run on a FITS binary table \201or a
raw event table\202, one integral count is accumulated for each row
\201event\202 contained within a given region. The )BD(-v "scol[;bcol]")ES(
\201value column\202 switch will accumulate counts using the value from the
specified column for the given event. If only a single column is
specified, it is used for both the source and background regions. Two
separate columns, separated by a semi-colon, can be specified for source
and background. The special token '$none' can be used to specify that
a value column is to be used for one but not the other. For example,
'pha;$none' will use the pha column for the source but use integral
counts for the background, while '$none;pha' will do the converse.
If the value column is of type logical, then the value used will be 1
for T and 0 for F.  Value columns are used, for example, to integrate
probabilities instead of integral counts.

)0 P(If the )BD(-T)ES( \201rdb table\202 switch is used, the output will conform
to starbase/rdb data base format: tabs will be inserted between
columns rather than spaces and line-feed will be inserted between
tables.

)0 P(Finally, note that )BD(funcnts)ES( is an image program, even though it
can be run directly on FITS binary tables. This means that image
filtering is applied to the rows in order to ensure that the same
results are obtained regardless of whether a table or the equivalent
binned image is used. Because of this, however, the number of counts
found using )BD(funcnts)ES( can differ from the number of events found
using row-filter programs such as )BD(fundisp)ES( or )BD(funtable)ES(
For more information about these difference, see the discussion of
)0 58 1 A(Region Boundaries)58 0 TN TL()Ec /AF f D(.




)0 2 9 H(funcone)WB 72 Sn()WB 6 Sn( - cone search of a binary table containing RA, Dec columns)EA()EH(


)BD() 1 81 PR(funcone <switches>  <iname> <oname> <ra[hdr]> <dec[hdr]> <radius[dr'"]> [columns])RP()ES(


)0 P() 9 84 PR(  -d deccol:[hdr]  # Dec column name, units \201def: DEC:d\202
  -j               # join columns from list file
  -J               # join columns from list file, output all rows
  -l listfile      # read centers and radii from a list
  -L listfile      # read centers and radii from a list, output list rows
  -n               # don't use cone limits as a filter
  -r  racol:[hdr]  # RA column name, units \201def: RA:h\202
  -x               # append RA_CEN, DEC_CEN, RAD_CEN, CONE_KEY cols
  -X               # append RA_CEN, DEC_CEN, RAD_CEN, CONE_KEY cols, output all rows)RP(


)0 P(Funcone performs a cone search on the RA and Dec columns of a FITS
binary table. The distance from the center RA, Dec position to the RA,
Dec in each row in the table is calculated. Rows whose distance is
less than the specified radius are output.

)0 P(The first argument to the program specifies the FITS file, raw event
file, or raw array file.  If "stdin" is specified, data are read from
the standard input. Use )0 42 1 A(Funtools Bracket
Notation)42 0 TN TL()Ec /AF f D( to specify FITS extensions, and filters.  The second
argument is the output FITS file.  If "stdout" is specified, the FITS
binary table is written to the standard output.  

)0 P( 
The third and fourth required arguments are the RA and Dec center
position.  By default, RA is specified in hours while Dec is specified
in degrees.  You can change the units of either of these by appending
the character "d" \201degrees\202, "h" \201hours\202 or "r" \201radians\202. Sexagesimal
notation is supported, with colons or spaces separating hms and dms.
\201When using spaces, please ensure that the entire string is quoted.\202

)0 P(The fifth required argument is the radius of the cone search. By default,
the radius value is given in degrees. The units can be changed by appending
the character "d" \201degrees\202, "r" \201radians\202, "'" \201arc minutes\202 or
'"' \201arc seconds\202.

)0 P(By default, all
columns of the input file are copied to the output file.  Selected
columns can be output using an optional sixth argument in the form:
) 1 31 PR(  "column1 column1 ... columnN")RP(
A seventh argument allows you to output selected columns from the list
file when )BD(-j)ES( switch is used. Note that the RA and Dec columns
used in the cone calculation must not be de-selected.

)0 P(Also by default, the RA and Dec column names are named "RA" and "Dec",
and are given in units of hours and degrees respectively. You can
change both the name and the units using the -r [RA] and/or -d [Dec]
switches. Once again, one of "h", "d", or "r" is appended to the
column name to specify units but in this case, there must be a colon ":"
between the name and the unit specification.

)0 P(If the )BD(-l [listfile])ES( switch is used, then one or more of the
center RA, center Dec, and radius can be taken from a list file \201which
can be a FITS table or an ASCII column text file\202. In this case, the
third \201center RA\202, fourth \201center Dec\202, and fifth \201radius\202 command
line arguments can either be a column name in the list file \201if that
parameter varies\202 or else a numeric value \201if that parameter is
static\202. When a column name is specified for the RA, Dec, or radius,
you can append a colon followed by "h", "d", or "r" to specify units
\201also ' and " for radius\202. The cone search algorithm is run once for
each row in the list, taking RA, Dec, and radius values from the
specified columns or from static numeric values specified on the
command line.

)0 P(When using a list, all valid rows from each iteration are written to a
single output file.  Use the )BD(-x)ES( switch to help delineate which
line of the list file was used to produce the given output row\201s\202.
This switch causes the values for the center RA, Dec, radius, and row
number to be appended to the output file, in columns called RA_CEN,
DEC_CEN, RAD_CEN and CONE_KEY, respectively. Alternatively, the
)BD(-j)ES( \201join\202 switch will append all columns from the list row to
the output row \201essentially a join of the list row and input row\202,
along with the CONE_KEY row number. These two switches are mutually
exclusive.

)0 P(The )BD(-X)ES( and )BD(-J)ES( switches write out the same data as their
lower case counterparts for each row satisfying a cone search. In
addition, these switches also write out rows from the event file that
do not satisfy any cone search.  In such cases, that CONE_KEY column
will be given a value of -1 and the center and list position information
will be set to zero for the given row. Thus, all rows of the input
event file are guaranteed to be output, with rows satisfying at least
one cone search having additional search information.

)0 P(The )BD(-L)ES( switch acts similarly to the )BD(-l)ES( switch in that it
takes centers from a list file. However, it also implicitly sets the
-j switch, so that output rows are the join of the input event row and
the center position row.  In addition, this switch also writes out all
center position rows for which no event satisfies the cone search
criteria of that row.  The CONE_KEY column will be given a value of -2
for center rows that were not close to any data row and the event
columns will be zeroed out for such rows. In this way, all centers
rows are guaranteed to be output at least once.

)0 P(If any of "all row" switches \201)BD(-X)ES(, )BD(-J)ES(, or )BD(-L)ES(\202 are
specified, then a new column named JSTAT is added to the output table.
The positive values in this column indicate the center position row number
\201starting from 1\202 in the list file that this data row successful matched
in a cone search. A value of -1 means that the data row did not match
any center position. A value of -2 means that the center position was
not matched by any data row.

)0 P(Given a center position and radius, the cone search algorithm
calculates limit parameters for a box enclosing the specified cone,
and only tests rows whose positions values lie within those limits.
For small files, the overhead associated with this cone limit
filtering can cause the program to run more slowly than if all events
were tested. You can turn off cone limit filtering using the )BD(-n)ES(
switch to see if this speeds up the processing \201especially useful when
processing a large list of positions\202.

)0 P(For example, the default cone search uses columns "RA" and "Dec" in hours
and degrees \201respectively\202 and RA position in hours, Dec and radius in degrees:
) 1 42 PR(  funone in.fits out.fits 23.45 34.56 0.01)RP(
To specify the RA position in degrees:
) 1 44 PR(  funcone in.fits out.fits 23.45d 34.56 0.01)RP(
To get RA and Dec from a list but use a static value for radius \201and
also write identifying info for each row in the list\202:
) 1 57 PR(  funcone -x -l list.txt in.fits out.fits MYRA MYDec 0.01)RP(
User specified columns in degrees, RA position in hours \201sexagesimal
notation\202, Dec position in degrees \201sexagesimal notation\202 and radius
in arc minutes:
) 1 66 PR(  funcone -r myRa:d -d myDec in.fits out.fits 12:30:15.5 30:12 15')RP(




)0 2 10 H(fundisp)WB 73 Sn()WB 7 Sn( - display data in a Funtools data file)EA()EH(


)BD() 1 62 PR(fundisp  [-f format] [-l] [-n] [-T] <iname> [columns|bitpix=n])RP()ES(


)0 P() 5 68 PR(  -f      # format string for display
  -l      # display image as a list containing the columns X, Y, VAL
  -n      # don't output header
  -F [c]  # use specified character as column separator \201def: space\202
  -T      # output in rdb/starbase format \201tab separators\202)RP(


)0 P()BD(fundisp)ES( displays the data in the specified 
)0 42 1 A(FITS Extension)42 0 TN TL()Ec /AF f D(
and/or
)0 49 1 A(Image Section)49 0 TN TL()Ec /AF f D(
of a FITS file, or in a
)0 49 1 A(Section)49 0 TN TL()Ec /AF f D(
of a non-FITS array or raw event file.
)0 P(The first argument to the program specifies the FITS input image, array, or
raw event file to display.  If "stdin" is specified, data are read from
the standard input. Use )0 42 1 A(Funtools Bracket
Notation)42 0 TN TL()Ec /AF f D( to specify FITS extensions, image sections, and filters.

)0 P(If the data being displayed are columns \201either in a FITS binary table
or a raw event file\202, the individual rows are listed. Filters can be
added using bracket notation. Thus:
) 13 75 PR(  [sh] fundisp "test.ev[time-\201int\202time>.15]"
         X       Y     PHA        PI             TIME         DX         DY
   ------- ------- ------- --------- ---------------- ---------- ----------
        10       8      10         8          17.1600       8.50      10.50
         9       9       9         9          17.1600       9.50       9.50
        10       9      10         9          18.1600       9.50      10.50
        10       9      10         9          18.1700       9.50      10.50
         8      10       8        10          17.1600      10.50       8.50
         9      10       9        10          18.1600      10.50       9.50
         9      10       9        10          18.1700      10.50       9.50
        10      10      10        10          19.1600      10.50      10.50
        10      10      10        10          19.1700      10.50      10.50
        10      10      10        10          19.1800      10.50      10.50)RP(
[NB: The FITS binary table test file test.ev, as well as the FITS
image test.fits, are contained in the funtools funtest directory.]

)0 P(When a table is being displayed using )BD(fundisp)ES(, a second optional
argument can be used to specify the columns to display.  For example:
) 12 56 PR(  [sh] fundisp "test.ev[time-\201int\202time>=.99]" "x y time"
          X        Y                  TIME
   -------- -------- ---------------------
          5       -6           40.99000000
          4       -5           59.99000000
         -1        0          154.99000000
         -2        1          168.99000000
         -3        2          183.99000000
         -4        3          199.99000000
         -5        4          216.99000000
         -6        5          234.99000000
         -7        6          253.99000000)RP(

)0 P(The special column )BD($REGION)ES( can be specified to display the
region id of each row:
) 12 89 PR(  [sh $] fundisp "test.ev[time-\201int\202time>=.99&&annulus\2010 0 0 10 n=3\202]" 'x y time $REGION'
          X        Y                  TIME     REGION
   -------- -------- --------------------- ----------
          5       -6           40.99000000          3
          4       -5           59.99000000          2
         -1        0          154.99000000          1
         -2        1          168.99000000          1
         -3        2          183.99000000          2
         -4        3          199.99000000          2
         -5        4          216.99000000          2
         -6        5          234.99000000          3
         -7        6          253.99000000          3)RP(
)0 P(Here only rows with the proper fractional time and whose position also is
within one of the three annuli are displayed.
)0 P(Columns can be excluded from display using a minus sign before the
column:
) 12 64 PR(  [sh $] fundisp "test.ev[time-\201int\202time>=.99]" "-time"
          X        Y      PHA         PI          DX          DY
   -------- -------- -------- ---------- ----------- -----------
          5       -6        5         -6        5.50       -6.50
          4       -5        4         -5        4.50       -5.50
         -1        0       -1          0       -1.50        0.50
         -2        1       -2          1       -2.50        1.50
         -3        2       -3          2       -3.50        2.50
         -4        3       -4          3       -4.50        3.50
         -5        4       -5          4       -5.50        4.50
         -6        5       -6          5       -6.50        5.50
         -7        6       -7          6       -7.50        6.50)RP(
All columns except the time column are displayed.
)0 P(The special column )BD($N)ES( can be specified to display the
ordinal value of each row. Thus, continuing the previous example:
) 12 74 PR(  fundisp "test.ev[time-\201int\202time>=.99]" '-time $n'
         X        Y      PHA         PI          DX          DY          N
   ------- -------- -------- ---------- ----------- ----------- ----------
         5       -6        5         -6        5.50       -6.50        337
         4       -5        4         -5        4.50       -5.50        356
        -1        0       -1          0       -1.50        0.50        451
        -2        1       -2          1       -2.50        1.50        465
        -3        2       -3          2       -3.50        2.50        480
        -4        3       -4          3       -4.50        3.50        496
        -5        4       -5          4       -5.50        4.50        513
        -6        5       -6          5       -6.50        5.50        531
        -7        6       -7          6       -7.50        6.50        550)RP(
Note that the column specification is enclosed in single quotes to protect
'$n' from begin expanded by the shell.

)0 P(In general, the rules for activating and de-activating columns are:
)UL()-1 LI( If only exclude columns are specified, then all columns but
the exclude columns will be activated.
)-1 LI( If only include columns are specified, then only the specified columns
are activated.
)-1 LI( If a mixture of include and exclude columns are specified, then
all but the exclude columns will be active; this last case
is ambiguous and the rule is arbitrary.)LU(
In addition to specifying columns names explicitly, the special
symbols )BD(+)ES( and )BD(-)ES( can be used to activate and
de-activate )BD(all)ES( columns. This is useful if you want to
activate the $REGION column along with all other columns.  According
to the rules, the syntax "$REGION" only activates the region column
and de-activates the rest. Use "+ $REGION" to activate all
columns as well as the region column.

)0 P(If the data being displayed are image data \201either in a FITS primary
image, a FITS image extension, or an array file\202, an mxn pixel display
is produced, where m and n are the dimensions of the image.  By
default, pixel values are displayed using the same data type as in the
file. However, for integer data where the BSCALE and BZERO header parameters
are present, the data is displayed as floats.  In either case, the
display data type can be overridden using an optional second argument
of the form:
) 1 10 PR(  bitpix=n)RP(
where n is 8,16,32,-32,-64, for unsigned char, short, int, float and double,
respectively. 

)0 P(Of course, running )BD(fundisp)ES( on anything but the smallest image
usually results in a display whose size makes it unreadable.
Therefore, one can uses bracket notation \201see below\202
to apply section and/or blocking to the image before generating a
display. For example:
) 9 66 PR(  [sh] fundisp "test.fits[2:6,2:7]" bitpix=-32
                     2          3          4          5          6
            ---------- ---------- ---------- ---------- ----------
         2:       3.00       4.00       5.00       6.00       7.00
         3:       4.00       5.00       6.00       7.00       8.00
         4:       5.00       6.00       7.00       8.00       9.00
         5:       6.00       7.00       8.00       9.00      10.00
         6:       7.00       8.00       9.00      10.00      11.00
         7:       8.00       9.00      10.00      11.00      12.00)RP(

)0 P(Note that is is possible to display a FITS binary table as an image
simply by passing the table through )BD(funimage)ES( first:
) 9 68 PR(  [sh] ./funimage test.ev stdout | fundisp "stdin[2:6,2:7]" bitpix=8
                  2       3       4       5       6
            ------- ------- ------- ------- -------
         2:       3       4       5       6       7
         3:       4       5       6       7       8
         4:       5       6       7       8       9
         5:       6       7       8       9      10
         6:       7       8       9      10      11
         7:       8       9      10      11      12)RP(

If the )BD(-l)ES( \201list\202 switch is used, then an image is displayed as a
list containing the columns: X, Y, VAL. For example:
) 33 45 PR(  fundisp -l "test1.fits[2:6,2:7]" bitpix=-32
            X          Y         VAL
   ---------- ---------- -----------
            2          2        6.00
            3          2        1.00
            4          2        1.00
            5          2        1.00
            6          2        1.00
            2          3        1.00
            3          3        5.00
            4          3        1.00
            5          3        1.00
            6          3        1.00
            2          4        1.00
            3          4        1.00
            4          4        4.00
            5          4        1.00
            6          4        1.00
            2          5        1.00
            3          5        1.00
            4          5        1.00
            5          5        3.00
            6          5        1.00
            2          6        1.00
            3          6        1.00
            4          6        1.00
            5          6        1.00
            6          6        2.00
            2          7        1.00
            3          7        1.00
            4          7        1.00)WR(
            5          7        1.00
            6          7        1.00)RP(

)0 P(If the )BD(-n)ES( \201nohead\202 switch is used, then no header is output for
tables. This is useful, for example, when fundisp output is being
directed into gnuplot.

)0 P(The )BD(fundisp)ES( program uses a default set of display formats:
) 10 33 PR(  datatype      TFORM   format
  --------      -----   --------
  double        D       "%21.8f"
  float         E       "%11.2f"
  int           J       "%10d"
  short         I       "%8d"
  byte          B       "%6d"
  string        A       "%12.12s"
  bits          X       "%8x"
  logical       L       "%1x")RP(
Thus, the default display of 1 double and 2 shorts gives:
) 7 42 PR(  [sh] fundisp snr.ev "time x y"
  
                    TIME        X        Y
   --------------------- -------- --------
       79494546.56818075      546      201
       79488769.94469175      548      201
       ...)RP(
You can change the display format for individual columns or for all
columns of a given data types by means of the -f switch.  The format
string that accompanies -f is a space-delimited list of keyword=format
values.  The keyword values can either be column names \201in which case
the associated format pertains only to that column\202 or FITS table
TFORM specifiers \201in which case the format pertains to all columns
having that data type\202. For example, you can change the double and
short formats for all columns like this:
) 7 53 PR(  [sh] fundisp -f "D=%22.11f I=%3d" snr.ev "time x y"
  
                    TIME   X   Y
  ---------------------- --- ---
    79494546.56818075478 546 201
    79488769.94469174743 548 201
    ...)RP(

)0 P(Alternatively, you can change the format of the time and x columns like this:
) 7 56 PR(  [sh] fundisp -f "time=%22.11f x=%3d" snr.ev "time x y"
  
                    TIME   X        Y
  ---------------------- --- --------
    79494546.56818075478 546      201
    79488769.94469174743 548      201
    ...)RP(
Note that there is a potential conflict if a column has the same name
as one of the TFORM specifiers. In the examples above, the the "X"
column in the table has the same name as the X \201bit\202 datatype.  To
resolve this conflict, the format string is processed such that
TFORM datatype specifiers are checked for first, using a
case-sensitive comparison. If the specified format value is not an
upper case TFORM value, then a case-insensitive check is made on the
column name.  This means that, in the examples above, "X=%3d" will refer
to the X \201bit\202 datatype, while "x=%3d" will refer to the X column:
) 15 38 PR(  [sh] fundisp -f "X=%3d" snr.ev "x y"
  
         X        Y
  -------- --------
       546      201
       548      201
       ...
  
  [sh] fundisp -f "x=%3d" snr.ev "x y"
  
    X        Y
  --- --------
  546      201
  548      201
  ...)RP(
As a rule, therefore, it is best always to specify the column name in
lower case and TFORM data types in upper case. 

)0 P(The )BD(-f [format])ES( will change the format for a single execution
of fundisp. You also can use the )BD(FUN_FORMAT)ES( envronment variable
to change the format for all invocations of fundisp. The format of this
environment variable's value is identical to that used with
the )BD(-f)ES( switch. This global value can be overridden in
individual cases by use of the )BD(-f [format])ES( switch.

)0 P(Caveats: Please also note that it is the user's responsibility to
match the format specifier to the column data type correctly. Also
note that, in order to maintain visual alignment between names and
columns, the column name will be truncated \201on the left\202 if the
format width is less than the length of the name. However, truncation
is not performed if the output is in RDB format \201using the -T switch\202.

)0 P([An older-style format string is supported but deprecated. It
consists of space-delimited C format statements for all data types,
specified in the following order:
) 1 40 PR( double float int short byte string bit.)RP(
This order of the list is based on the assumption that people generally
will want to change the float formats.
)0 P(If "-" is entered instead of a format statement for a given data type, the
default format is used. Also, the format string can be terminated without
specifying all formats, and defaults will be used for the rest of the
list. Note that you must supply a minimum field width, i.e., "%6d" and
"%-6d" are legal, "%d" is not legal.

By using -f [format], you can change the double and short formats like this:
) 7 51 PR(  [sh] fundisp -f "22.11f - - 3d" snr.ev "time x y"
  
                     TIME   X   Y
   ---------------------- --- ---
     79494546.56818075478 546 201
     79488769.94469174743 548 201
     ...)RP(
NB: This format is deprecated and will be removed in a future release.]

)0 P(The )BD(-F[c])ES( switch can be used to specify a \201single-character\202
column separator \201where the default is a space\202. Note that column
formatting will almost certainly also add spaces to pad individual
columns to the required width. These can be removed with a program
such as sed, at the cost of generating unaligned columns. For example:
) 26 117 PR(fundisp -F',' snr.ev'[cir 512 512 .1]'
       X,       Y,     PHA,      PI,                 TIME,      DX,      DY
--------,--------,--------,--------,---------------------,--------,--------
     512,     512,       6,       7,    79493997.45854475,     578,     574
     512,     512,       8,       9,    79494575.58943175,     579,     573
     512,     512,       5,       6,    79493631.03866175,     578,     575
     512,     512,       5,       5,    79493290.86521725,     578,     575
     512,     512,       8,       9,    79493432.00990875,     579,     573

fundisp -F',' snr.ev'[cir 512 512 .1]' | sed 's/ *, */,/g'
       X,Y,PHA,PI,TIME,DX,DY
--------,--------,--------,--------,---------------------,--------,--------
     512,512,6,7,79493997.45854475,578,574
     512,512,8,9,79494575.58943175,579,573
     512,512,5,6,79493631.03866175,578,575
     512,512,5,5,79493290.86521725,578,575
     512,512,8,9,79493432.00990875,579,573

fundisp -f "x=%3d y=%3d pi=%1d pha=%1d time=%20.11f dx=%3d dy=%3d" -F',' snr.ev'[cir 512 512 .1]' | sed 's/ *, */,/g'
  X,Y,A,I,TIME,DX,DY
---,---,-,-,--------------------,---,---
512,512,6,7,79493997.45854474604,578,574
512,512,8,9,79494575.58943174779,579,573
512,512,5,6,79493631.03866174817,578,575
512,512,5,5,79493290.86521725357,578,575
512,512,8,9,79493432.00990875065,579,573)RP(

)0 P(If the )BD(-T)ES( \201rdb table\202 switch is used, the output will conform
to starbase/rdb data base format: tabs will be inserted between
columns rather than spaces. This format is not available when
displaying image pixels \201except in conjunction with the )BD(-l)ES(
switch\202.

)0 P(Finally, note that )BD(fundisp)ES( can be used to create column filters from
the auxiliary tables in a FITS file. For example, the following shell code
will generate a good-time interval \201GTI\202 filter for X-ray data files that
contain a standard GTI extension:
) 3 68 PR(  #!/bin/sh
  sed '1,/---- .*/d
  /^$/,$d' | awk 'tot>0{printf "||"};{printf "time="$1":"$2; tot++}')RP(
If this script is placed in a file called "mkgti", it can be used in a
command such as:
) 1 46 PR(  fundisp foo.fits"[GTI]" | mkgti > gti.filter)RP(
The resulting filter file can then be used in various funtools programs:
) 1 37 PR(  funcnts foo.fits"[@gti.filter]" ...)RP(
to process only the events in the good-time intervals.




)0 2 11 H(funhead)WB 74 Sn()WB 8 Sn( - display a header in a Funtools file)EA()EH(


)BD() 1 50 PR(funhead  [-a] [-s] [-t] [-L] <iname> [oname ename])RP()ES(


)0 P() 4 60 PR(  -a    # display all extension headers
  -s    # display 79 chars instead of 80 before the new-line
  -t    # prepend data type char to each line of output
  -L    # output in rdb/starbase list format)RP(


)0 P()BD(funhead)ES( displays the FITS header parameters in the specified 
)0 42 1 A(FITS Extension)42 0 TN TL()Ec /AF f D(.
)0 P(The first argument to the program specifies the Funtools input file
to display.  If "stdin" is specified, data are read from
the standard input. )0 42 1 A(Funtools Bracket
Notation)42 0 TN TL()Ec /AF f D( is used to specify particular FITS extension to process.
Normally, the full 80 characters of each header card is output,
followed by a new-line. 

)0 P(If the )BD(-a)ES( switch is specified, the header from each FITS
extensions in the file is displayed. Note, however, that the )BD(-a)ES(
switch does not work with FITS files input via stdin. We hope to
remove this restriction in a future release.

)0 P(If the )BD(-s)ES( switch is specified, only 79 characters are output
before the new-line. This helps the display on 80 character terminals.

)0 P(If the )BD(-t)ES( switch is specified, the data type of the parameter
is output as a one character prefix, followed by 77 characters of the
param.  The parameter data types are defined as: FUN_PAR_UNKNOWN
\201'u'\202, FUN_PAR_COMMENT \201'c'\202, FUN_PAR_LOGICAL \201'l'\202, FUN_PAR_INTEGER
\201'i'\202, FUN_PAR_STRING \201's'\202, FUN_PAR_REAL \201'r'\202, FUN_PAR_COMPLEX \201'x'\202.

)0 P(If the )BD(-L)ES( \201rdb table\202 switch is used, the output will conform
to starbase/rdb data base list format.

)0 P(For example to display the EVENTS extension \201binary table\202:
) 17 65 PR(  [sh] funhead "foo.fits[EVENTS]"
  XTENSION= 'BINTABLE'            /  FITS 3D BINARY TABLE                      
  BITPIX  =                    8  /  Binary data                               
  NAXIS   =                    2  /  Table is a matrix                         
  NAXIS1  =                   20  /  Width of table in bytes                   
  NAXIS2  =                30760  /  Number of entries in table                
  PCOUNT  =                    0  /  Random parameter count                    
  GCOUNT  =                    1  /  Group count                               
  TFIELDS =                    7  /  Number of fields in each row              
  EXTNAME = 'EVENTS  '            /  Table name                                
  EXTVER  =                    1  /  Version number of table                   
  TFORM1  = '1I      '            /  Data type for field                       
  TTYPE1  = 'X       '            /  Label for field                           
  TUNIT1  = '        '            /  Physical units for field                  
  TFORM2  = '1I      '            /  Data type for field                       
    etc. ...
  END)RP(

)0 P(To display the third header:
) 14 65 PR(  [sh] funhead "foo.fits[3]"
  XTENSION= 'BINTABLE'            /  FITS 3D BINARY TABLE                      
  BITPIX  =                    8  /  Binary data                               
  NAXIS   =                    2  /  Table is a matrix                         
  NAXIS1  =                   32  /  Width of table in bytes                   
  NAXIS2  =                   40  /  Number of entries in table                
  PCOUNT  =                    0  /  Random parameter count                    
  GCOUNT  =                    1  /  Group count                               
  TFIELDS =                    7  /  Number of fields in each row              
  EXTNAME = 'TGR     '            /  Table name                                
  EXTVER  =                    1  /  Version number of table                   
  TFORM1  = '1D      '            /  Data type for field                       
    etc. ...
  END)RP(

)0 P(To display the primary header \201i.e., extension 0\202:
) 8 59 PR(  sh> funhead "coma.fits[0]"
  SIMPLE  =                    T /STANDARD FITS FORMAT                         
  BITPIX  =                   16 /2-BYTE TWOS-COMPL INTEGER                    
  NAXIS   =                    2 /NUMBER OF AXES                               
  NAXIS1  =                  800 /                                             
  NAXIS2  =                  800 /                                             
  DATATYPE= 'INTEGER*2'          /SHORT INTEGER                                
  END)RP(

)0 P(The funhead program also can edit \201i.e. add, delete, or modify\202 or
display individual headers parameters. Edit mode is signalled by the
presence of two additional command-line arguments: output file and
edit command file, in that order. Edit mode acts as a filter: the
output file will contain the entire input FITS file, including other
extensions. The edit command file can be "stdin", in which case edit
command are read from the standard input.

)0 P(The edit command file contains parameter comments \201having '#' in the
first column\202 and delete and assignment\201modify or add\202 operations.  A
delete operation is specified by preceding the parameter name with a
minus sign "-".  A display operation \201very useful in interactive
sessions, i.e., where the edit commands are taken from stdin\202 is
specified by preceding the parameter name with a question mark "?". In
either case, a parameter value need not be specified.  An assignment
operation is specified in the same two ways that a parameter is
specified in a text header \201but without the comment character that
precedes header params\202, i.e.:

)UL()-1 LI( FITS-style comments have an equal sign "=" between the keyword and
value and an optional slash "/" to signify a comment. The strict FITS
rules on column positions are not enforced.

)-1 LI( Free-form comments can have an optional colon separator between the
keyword and value. In the absence of quote, all tokens after the
keyword are part of the value, i.e. no comment is allowed.)LU(

)0 P(For example, the following interactive session checks for the
existence of parameters, adds new parameters, modifies them, and
modifies and deletes existing parameters:
) 20 55 PR(  sh$ ./funhead snr.ev foo.fits -
  # look for FOO1
  ? FOO1
  WARNING: FOO1 not found
  # add new foo1
  FOO1 = 100
  # add foo2
  FOO2 = 200
  # reset foo1 to a different value
  FOO1 -1
  # delete foo2
  -FOO2
  # change existing value
  EXTVER 2
  ? XS-SORT
  XS-SORT = 'EOF     '            /  type of event sort
  # delete existing value
  -XS-SORT
  # exit
  ^D)RP(

)0 P(See )0 47 1 A(Column-based Text Files)47 0 TN TL()Ec /AF f D(
for more information about header parameter format.

)0 P(
)0 P(


)0 2 12 H(funhist)WB 75 Sn()WB 9 Sn( - create a 1D histogram of a column \201from a FITS binary table or raw event file\202 or an image)EA()EH(


)BD() 1 51 PR(funhist  [-n|-w|-T] <iname> [column] [[lo:hi:]bins])RP()ES(


)0 P() 3 61 PR(  -n    # normalize bin value by the width of each bin
  -w    # specify bin width instead of number of bins in arg3
  -T    # output in rdb/starbase format \201tab separators\202)RP(


)0 P()BD(funhist)ES( creates a one-dimensional histogram from the specified
columns of a )0 42 1 A(FITS Extension)42 0 TN TL()Ec /AF f D(
binary table of a FITS file \201or from a non-FITS raw event file\202, or
from a FITS image or array, and writes that histogram as an ASCII
table. Alternatively, the program can perform a 1D projection of one
of the image axes.

)0 P(The first argument to the program is required, and specifies the
Funtools file: FITS table or image, raw event file, or array.  If
"stdin" is specified, data are read from the standard input. Use 
)0 42 1 A(Funtools Bracket Notation)42 0 TN TL()Ec /AF f D( to specify FITS
extensions, and filters.

)0 P(For a table, the second argument also is required. It specifies the
column to use in generating the histogram.  If the data file is of
type image \201or array\202, the column is optional: if "x" \201or "X"\202, "y"
\201or "Y"\202 is specified, then a projection is performed over the x
\201dim1\202 or y \201dim2\202 axes, respectively. \201That is, this projection will
give the same results as a histogram performed on a table containing
the equivalent x,y event rows.\202  If no column name is specified or
"xy" \201or "XY"\202 is specified for the image, then a histogram is
performed on the values contained in the image pixels.

)0 P(The argument that follows is optional and specifies the number of bins
to use in creating the histogram and, if desired, the range of bin
values.  For image and table histograms, the range should specify the
min and max data values.  For image histograms on the x and y axes,
the range should specify the min and max image bin values.  If this
argument is omitted, the number of output bins for a table is
calculated either from the TLMIN/TLMAX headers values \201if these exist
in the table FITS header for the specified column\202 or by going through
the data to calculate the min and max value. For an image, the number
of output bins is calculated either from the DATAMIN/DATAMAX header
values, or by going through the data to calculate min and max value.
\201Note that this latter calculation might fail if the image cannot be
fit in memory.\202  If the data are floating point \201table or image\202 and
the number of bins is not specified, an arbitrary default of 128 is
used.

)0 P(For binary table processing, the )BD(-w)ES( \201bin width\202 switch can be used
to specify the width of each bin rather than the number of bins. Thus:
) 1 29 PR(  funhist test.ev pha 1:100:5)RP(
means that 5 bins of width 20 are used in the histogram, while:
) 1 32 PR(  funhist -w test.ev pha 1:100:5)RP(
means that 20 bins of width 5 are used in the histogram.

)0 P(The data are divvied up into the specified number of bins and the
resulting 1D histogram \201or projection\202 is output in ASCII table
format. For a table, the output displays the low_edge \201inclusive\202 and
hi_edge \201exclusive\202 values for the data. For example, a 15-row table
containing a "pha" column whose values range from -7.5 to 7.5
can be processed thus:

) 47 62 PR(  [sh] funhist test.ev pha
  # data file:        /home/eric/data/test.ev
  # column:           pha
  # min,max,bins:     -7.5 7.5 15
  
     bin     value               lo_edge               hi_edge
  ------ --------- --------------------- ---------------------
       1        22           -7.50000000           -6.50000000
       2        21           -6.50000000           -5.50000000
       3        20           -5.50000000           -4.50000000
       4        19           -4.50000000           -3.50000000
       5        18           -3.50000000           -2.50000000
       6        17           -2.50000000           -1.50000000
       7        16           -1.50000000           -0.50000000
       8        30           -0.50000000            0.50000000
       9        16            0.50000000            1.50000000
      10        17            1.50000000            2.50000000
      11        18            2.50000000            3.50000000
      12        19            3.50000000            4.50000000
      13        20            4.50000000            5.50000000
      14        21            5.50000000            6.50000000
      15        22            6.50000000            7.50000000
  
  [sh] funhist test.ev pha 1:6
  # data file:          /home/eric/data/test.ev
  # column:             pha
  # min,max,bins:       0.5 6.5 6
  
     bin     value               lo_edge               hi_edge
  ------ --------- --------------------- ---------------------
       1        16            0.50000000            1.50000000)WR(
       2        17            1.50000000            2.50000000
       3        18            2.50000000            3.50000000
       4        19            3.50000000            4.50000000
       5        20            4.50000000            5.50000000
       6        21            5.50000000            6.50000000
  
  [sh] funhist test.ev pha 1:6:3
  # data file:          /home/eric/data/test.ev
  # column:             pha
  # min,max,bins:       0.5 6.5 3
  
     bin     value               lo_edge               hi_edge
  ------ --------- --------------------- ---------------------
       1        33            0.50000000            2.50000000
       2        37            2.50000000            4.50000000
       3        41            4.50000000            6.50000000)RP(

)0 P(For a table histogram, the )BD(-n)ES(\201normalize\202 switch can be used to
normalize the bin value by the width of the bin \201i.e., hi_edge-lo_edge\202:
) 11 74 PR(  [sh] funhist -n test.ev pha 1:6:3 
  # data file:          test.ev
  # column:             pha
  # min,max,bins:       0.5 6.5 3
  # width normalization \201val/\201hi_edge-lo_edge\202\202 is applied
  
     bin                 value               lo_edge               hi_edge
  ------ --------------------- --------------------- ---------------------
       1           16.50000000            0.50000000            2.50000000
       2            6.16666667            2.50000000            4.50000000
       3            4.10000000            4.50000000            6.50000000)RP(
This could used, for example, to produce a light curve with values
having units of counts/second instead of counts.

)0 P(For an image histogram, the output displays the low and high image
values \201both inclusive\202 used to generate the histogram.  For example,
in the following example, 184 pixels had a value of 1, 31 had a value
of 2, while only 2 had a value of 3,4,5,6, or 7:
) 13 74 PR(  [sh] funhist test.fits
  # data file:           /home/eric/data/test.fits
  # min,max,bins:        1 7 7
  
     bin                 value                lo_val                hi_val
  ------ --------------------- --------------------- ---------------------
       1          184.00000000            1.00000000            1.00000000
       2           31.00000000            2.00000000            2.00000000
       3            2.00000000            3.00000000            3.00000000
       4            2.00000000            4.00000000            4.00000000
       5            2.00000000            5.00000000            5.00000000
       6            2.00000000            6.00000000            6.00000000
       7            2.00000000            7.00000000            7.00000000)RP(

)0 P(For the axis projection of an image, the output displays the low and
high image bins \201both inclusive\202 used to generate the projection.  For
example, in the following example, 21 counts had their X bin value of
2, etc.:
) 23 74 PR(  [sh] funhist test.fits x 2:7
  # data file:            /home/eric/data/test.fits
  # column:               X
  # min,max,bins: 2 7 6
   
     bin                 value                lo_bin                hi_bin
  ------ --------------------- --------------------- ---------------------
       1           21.00000000            2.00000000            2.00000000
       2           20.00000000            3.00000000            3.00000000
       3           19.00000000            4.00000000            4.00000000
       4           18.00000000            5.00000000            5.00000000
       5           17.00000000            6.00000000            6.00000000
       6           16.00000000            7.00000000            7.00000000
  
  [sh] funhist test.fits x 2:7:2
  # data file:            /home/eric/data/test.fits
  # column:               X
  # min,max,bins: 2 7 2
   
     bin                 value                lo_bin                hi_bin
  ------ --------------------- --------------------- ---------------------
       1           60.00000000            2.00000000            4.00000000
       2           51.00000000            5.00000000            7.00000000)RP(

)0 P(You can use gnuplot or other plotting programs to graph the
results, using a script such as:
) 7 119 PR(  #!/bin/sh
  sed -e '1,/---- .*/d
  /^$/,$d' | \200
  awk '\200
  BEGIN{print "set nokey; set title \200"funhist\200"; set xlabel \200"bin\200"; set ylabel \200"counts\200"; plot \200"-\200" with boxes"}   \200
  {print $3, $2, $4-$3}'        | \200
  gnuplot -persist - 1>/dev/null 2>&1)RP(

Similar plot commands are supplied in the script )BD(funhist.plot)ES(:
) 1 49 PR(  funhist test.ev pha ...  | funhist.plot gnuplot)RP(




)0 2 13 H(funimage)WB 76 Sn()WB 10 Sn( - create a FITS image from a Funtools data file)EA()EH(


)BD() 3 73 PR(funimage [-a] <iname> <oname> [bitpix=n]
funimage [-l] <iname> <oname> <xcol:xdims> <ycol:ydims> <vcol> [bitpix=n]
funimage [-p x|y] <iname> <oname> [bitpix=n])RP()ES(


)0 P() 3 65 PR(  -a       # append to existing output file as an image extension
  -l       # input is a list file containing xcol, ycol, value
  -p [x|y] # project along x or y axis to create a 1D image)RP(


)0 P()BD(funimage)ES( creates a primary FITS image from the specified
)0 42 1 A(FITS Extension)42 0 TN TL()Ec /AF f D(
and/or
)0 49 1 A(Image Section)49 0 TN TL()Ec /AF f D(
of a FITS file, or from an
)0 49 1 A(Image Section)49 0 TN TL()Ec /AF f D(
of a non-FITS array, or from a raw event file.
)0 P(The first argument to the program specifies the FITS input image,
array, or raw event file to process.  If "stdin" is specified, data are
read from the standard input. Use )0 42 1 A(Funtools
Bracket Notation)42 0 TN TL()Ec /AF f D( to specify FITS extensions, image sections, and
filters.  The second argument is the output FITS file.  If "stdout" is
specified, the FITS image is written to the standard output.  By
default, the output pixel values are of the same data type as those of the
input file \201or type "int" when binning a table\202, but this can be
overridden using an optional third argument of the form:
) 1 10 PR(  bitpix=n)RP(
where n is 8,16,32,-32,-64, for unsigned char, short, int, float and double,
respectively.

)0 P(If the input data are of type image, the appropriate section is
extracted and blocked \201based on how the 
)0 49 1 A(Image Section)49 0 TN TL()Ec /AF f D( is specified\202, and
the result is written to the FITS primary image.  When an integer
image containing the BSCALE and BZERO keywords is converted to float,
the pixel values are scaled and the scaling keywords are deleted from the
output header. When converting integer scaled data to integer
\201possibly of a different size\202, the pixels are not scaled and the
scaling keywords are retained.

)0 P(If the input data is a binary table or raw event file, these are
binned into an image, from which a section is extracted and blocked,
and written to a primary FITS image.  In this case, it is necessary to
specify the two columns that will be used in the 2D binning.  This can
be done on the command line using the )BD(bincols=\201x,y\202)ES( keyword:
) 1 46 PR(  funcnts "foo.ev[EVENTS,bincols=\201detx,dety\202]")RP(
The full form of the )BD(bincols=)ES( specifier is:
) 1 77 PR(  bincols=\201[xname[:tlmin[:tlmax:[binsiz]]]],[yname[:tlmin[:tlmax[:binsiz]]]]\202)RP(
where the tlmin, tlmax, and binsiz specifiers determine the image binning
dimensions:
) 2 56 PR(  dim = \201tlmax - tlmin\202/binsiz     \201floating point data\202
  dim = \201tlmax - tlmin\202/binsiz + 1 \201integer data\202)RP(
Using this syntax, it is possible to bin any two columns of a binary
table at any bin size.  Note that the tlmin, tlmax, and binsiz
specifiers can be omitted if TLMIN, TLMAX, and TDBIN header parameters
\201respectively\202 are present in the FITS binary table header for the
column in question. Note also that if only one parameter is specified,
it is assumed to be tlmax, and tlmin defaults to 1. If two parameters
are specified, they are assumed to be tlmin and tlmax.
See )0 50 1 A(Binning FITS Binary Tables and Non-FITS
Event Files)50 0 TN TL()Ec /AF f D( for more information about binning parameters.

)0 P(By default, a new 2D FITS image file is created and the image is written
to the primary HDU.  If the )BD(-a)ES( \201append\202 switch is specified,
the image is appended to an existing FITS file as an IMAGE extension.
\201If the output file does not exist, the switch is effectively ignored
and the image is written to the primary HDU.\202  This can be useful in a
shell programming environment when processing multiple FITS images
that you want to combine into a single final FITS file.

)0 P()BD(funimage)ES( also can take input from a table containing columns of
x, y, and value \201e.g., the output from )BD(fundisp -l)ES( which
displays each image x and y and the number of counts at that
position.\202 When the )BD(-l)ES( \201list\202 switch is used, the input file is
taken to be a FITS or ASCII table containing \201at least\202 three columns
that specify the x and y image coordinates and the value of that
image pixel. In this case, )BD(funimage)ES( requires four extra
arguments: xcolumn:xdims, ycolumn:ydims, vcolumn and bitpix=n. The x
and y col:dim information takes the form: 
) 3 55 PR(  name:dim               # values range from 1 to dim
  name:min:max           # values range from min to max
  name:min:max:binsiz    # dimensions scaled by binsize)RP(
In particular, the min value should be used whenever the
minimum coordinate value is something other than one. For example:
) 2 69 PR( 
  funimage -l foo.lst foo.fits xcol:0:512 ycol:0:512 value bitpix=-32)RP(

)0 P(The list feature also can be used to read unnamed columns from standard
input: simply replace the column name with a null string. Note
that the dimension information is still required:
) 5 60 PR(  funimage -l stdin foo.fits "":0:512 "":0:512 "" bitpix=-32
  240 250 1
  255 256 2
  ...
  ^D)RP(

)0 P(The list feature provides a simple way to generate a blank image.
If you pass a )0 47 1 A(Column-based Text File)47 0 TN TL()Ec /AF f D(
to funimage in which the text header contains the required image
information, then funimage will correctly make a blank image. For
example, consider the following text file \201called foo.txt\202:
) 3 20 PR(  x:I:1:10  y:I:1:10
  ------    ------
  0         0)RP(
This text file defines two columns, x and y, each of data type 32-bit int and
image dimension 10. The command:
) 1 36 PR(  funimage foo.txt foo.fits bitpix=8)RP(
will create an empty FITS image called foo.fits containing a 10x10
image of unsigned char:
) 13 75 PR(  fundisp foo.fits
           1      2      3      4      5      6      7      8      9     10
      ------ ------ ------ ------ ------ ------ ------ ------ ------ ------
  10:      0      0      0      0      0      0      0      0      0      0
   9:      0      0      0      0      0      0      0      0      0      0
   8:      0      0      0      0      0      0      0      0      0      0
   7:      0      0      0      0      0      0      0      0      0      0
   6:      0      0      0      0      0      0      0      0      0      0
   5:      0      0      0      0      0      0      0      0      0      0
   4:      0      0      0      0      0      0      0      0      0      0
   3:      0      0      0      0      0      0      0      0      0      0
   2:      0      0      0      0      0      0      0      0      0      0
   1:      1      0      0      0      0      0      0      0      0      0)RP(

Note that the text file must contain at least
one row of data. However, in the present example, event position 0,0 is
outside the limits of the image and will be ignored. \201You can, of course,
use real x,y values to seed the image with data.\202

)0 P(Furthermore, you can use the TEXT filter specification to obviate the need for
an input text file altogether. The following command will create the same
10x10 char image without an actual input file:
) 3 69 PR(  funimage stdin'[TEXT\201x:I:10,y:I:10\202]' foo.fits bitpix=8 < /dev/null
or
  funimage /dev/null'[TEXT\201x:I:10,y:I:10\202]' foo.fits bitpix=8)RP(

)0 P(You also can use either of these methods to generate a region mask simply
by appending a region inside the filter brackets and specfying )BD(mask=all)ES(
along with the bitpix. For example, the following command will generate a
10x10 char mask using 3 regions:
) 2 76 PR(  funimage stdin'[TEXT\201x:I:10,y:I:10\202,cir\2015,5,4\202,point\20110,1\202,-cir\2015,5,2\202]' \200
  foo.fits bitpix=8,mask=all < /dev/null)RP(
The resulting mask looks like this:
) 13 75 PR(  fundisp foo.fits
           1      2      3      4      5      6      7      8      9     10
      ------ ------ ------ ------ ------ ------ ------ ------ ------ ------
  10:      0      0      0      0      0      0      0      0      0      0
   9:      0      0      0      0      0      0      0      0      0      0
   8:      0      0      1      1      1      1      1      0      0      0
   7:      0      1      1      1      1      1      1      1      0      0
   6:      0      1      1      0      0      0      1      1      0      0
   5:      0      1      1      0      0      0      1      1      0      0
   4:      0      1      1      0      0      0      1      1      0      0
   3:      0      1      1      1      1      1      1      1      0      0
   2:      0      0      1      1      1      1      1      0      0      0
   1:      0      0      0      0      0      0      0      0      0      2)RP(

)0 P(You can use )BD(funimage)ES( to create 1D image projections along the x
or y axis using the )BD(-p [x|y])ES( switch. This capability works for
both images and tables. For example consider a FITS table named ev.fits
containing the following rows:
) 17 19 PR(         X        Y
  -------- --------
         1        1
         1        2
         1        3
         1        4
         1        5
         2        2
         2        3
         2        4
         2        5
         3        3
         3        4
         3        5
         4        4
         4        5
         5        5)RP(
A corresponding 5x5 image, called dim2.fits, would therefore contain:
) 7 59 PR(              1          2          3          4          5
     ---------- ---------- ---------- ---------- ----------
  5:          1          1          1          1          1
  4:          1          1          1          1          0
  3:          1          1          1          0          0
  2:          1          1          0          0          0
  1:          1          0          0          0          0)RP(
A projection along the y axis can be performed on either the table or
the image:
) 9 59 PR(  funimage -p y ev.fits stdout | fundisp stdin
              1          2          3          4          5
     ---------- ---------- ---------- ---------- ----------
  1:          1          2          3          4          5

  funimage -p y dim2.fits stdout | fundisp stdin
              1          2          3          4          5
     ---------- ---------- ---------- ---------- ----------
  1:          1          2          3          4          5)RP(

)0 P(Furthermore, you can create a 1D image projection along any column of
a table by using the )BD(bincols=[column])ES( filter specification and
specifying a single column. For example, the following command
projects the same 1D image along the y axis of a table as use of
the )BD(-p y)ES( switch:
) 4 59 PR(  funimage ev.fits'[bincols=y]' stdout | fundisp stdin 
              1          2          3          4          5
     ---------- ---------- ---------- ---------- ----------
  1:          1          2          3          4          5)RP(

)0 P(Examples:
)0 P(Create a FITS image from a FITS binary table:
) 1 33 PR(  [sh] funimage test.ev test.fits)RP(

)0 P(Display the FITS image generated from a blocked section of FITS binary table:
) 5 60 PR(  [sh]  funimage "test.ev[2:8,3:7,2]" stdout | fundisp stdin
                    1         2         3
            --------- --------- ---------
         1:        20        28        36
         2:        28        36        44)RP(




)0 2 14 H(funindex)WB 77 Sn()WB 11 Sn( - create an index for a column of a FITS binary table)EA()EH(


)BD() 1 42 PR(funindex <switches>  <iname> <key> [oname])RP()ES(


)0 P() 7 71 PR(  NB: these options are not compatible with Funtools processing. Please
  use the defaults instead.
  -c        # compress output using gzip"
  -a        # ASCII output, ignore -c \201default: FITS table\202"
  -f        # FITS table output \201default: FITS table\202"
  -l        # long output, i.e. with key value\201s\202 \201default: long\202"
  -s        # short output, i.e. no key value\201s\202 \201default: long\202")RP(


)0 P(The funindex script creates an index for the specified column \201key\202 by
running funtable -s \201sort\202 and then saving the column value and the
record number for each sorted row. This index will be used automatically
 by funtools filtering of that column, provided the index file's modification
date is later than that of the data file.

)0 P( 
The first required argument is the name of the FITS binary table
to index. Please note that text files cannot be indexed at this time.
The second required argument is the column \201key\202 name to index. While
multiple keys can be specified in principle, the funtools index processing
assume a single key and will not recognize files containing multiple keys.

)0 P(By default, the output index file name is [root]_[key].idx, where [root]
is the root of the input file. Funtools looks for this specific file name
when deciding whether to use an index for faster filtering. Therefore, the
optional third argument \201output file name\202 should not be used for funtools
processing.

)0 P(For example, to create an index on column Y for a given FITS file, use:
) 1 21 PR(  funindex foo.fits Y)RP(
This will generate an index named foo_y.idx, which will be used by funtools
for filters involving the Y column.




)0 2 15 H(funjoin)WB 78 Sn()WB 12 Sn( - join two or more FITS binary tables on specified columns)EA()EH(


)BD() 1 57 PR(funjoin [switches] <ifile1> <ifile2> ... <ifilen> <ofile>)RP()ES(


)0 P() 11 74 PR(  -a  cols             # columns to activate in all files
  -a1 cols ... an cols # columns to activate in each file
  -b  'c1:bvl,c2:bv2'  # blank values for common columns in all files
  -bn 'c1:bv1,c2:bv2'  # blank values for columns in specific files
  -j  col              # column to join in all files
  -j1 col ... jn col   # column to join in each file
  -m min               # min matches to output a row
  -M max               # max matches to output a row
  -s                   # add 'jfiles' status column
  -S col               # add col as status column
  -t tol               # tolerance for joining numeric cols [2 files only])RP(


)BD(funjoin)ES( joins rows from two or more \201up to 32\202
)0 42 1 A(FITS Binary Table files)42 0 TN TL()Ec /AF f D(, based on the values
of specified join columns in each file. NB: the join columns must have
an index file associated with it. These files are generated using the
)BD(funindex)ES( program.

)0 P(The first argument to the program specifies the first input FITS table
or raw event file. If "stdin" is specified, data are read from the
standard input.  Subsequent arguments specify additional event files
and tables to join.  The last argument is the output FITS file.

)0 P(NB: Do )BD(not)ES( use )0 42 1 A(Funtools Bracket
Notation)42 0 TN TL()Ec /AF f D( to specify FITS extensions and row filters when running
funjoin or you will get wrong results. Rows are accessed and joined
using the index files directly, and this bypasses all filtering.

)0 P(The join columns are specified using the )BD(-j col)ES( switch \201which
specifies a column name to use for all files\202 or with )BD(-j1 col1)ES(,
)BD(-j2 col2)ES(, ... )BD(-jn coln)ES( switches \201which specify a column
name to use for each file\202. A join column must be specified for each file.
If both )BD(-j col)ES( and )BD(-jn coln)ES( are specified for a given
file, then the latter is used. Join columns must either be of type
string or type numeric; it is illegal to mix numeric and string
columns in a given join.  For example, to join three files using the
same key column for each file, use:
) 1 52 PR(  funjoin -j key in1.fits in2.fits in3.fits out.fits)RP(
A different key can be specified for the third file in this way:
) 1 65 PR(  funjoin -j key -j3 otherkey in1.fits in2.fits in3.fits out.fits)RP(

)0 P(The )BD(-a "cols")ES( switch \201and )BD(-a1 "col1")ES(,
)BD(-a2 "cols2")ES( counterparts\202 can be used to specify columns to
activate \201i.e. write to the output file\202 for each input file. By
default, all columns are output.

)0 P(If two or more columns from separate files have the same name, the
second \201and subsequent\202 columns are renamed to have an underscore
and a numeric value appended.

)0 P(The )BD(-m min)ES( and )BD(-M max)ES( switches specify the minimum
and maximum number of joins required to write out a row. The default
minimum is 0 joins \201i.e. all rows are written out\202 and the default maximum
is 63 \201the maximum number of possible joins with a limit of 32 input files\202.
For example, to write out only those rows in which exactly two files
have columns that match \201i.e. one join\202:
) 1 66 PR(  funjoin -j key -m 1 -M 1 in1.fits in2.fits in3.fits ... out.fits)RP(

)0 P(A given row can have the requisite number of joins without all of the
files being joined \201e.g. three files are being joined but only two
have a given join key value\202. In this case, all of the columns of the
non-joined file are written out, by default, using blanks \201zeros or NULLs\202.
The )BD(-b c1:bv1,c2:bv2)ES( and
)BD(-b1 'c1:bv1,c2:bv2' -b2 'c1:bv1,c2:bv2' ...)ES(
switches can be used to set the blank value for columns common to all
files and/or columns in a specified file, respectively. Each blank value
string contains a comma-separated list of column:blank_val specifiers.
For floating point values \201single or double\202, a case-insensitive string
value of "nan" means that the IEEE NaN \201not-a-number\202 should be
used. Thus, for example:
) 1 62 PR(  funjoin -b "AKEY:???" -b1 "A:-1" -b3 "G:NaN,E:-1,F:-100" ...)RP(
means that a non-joined AKEY column in any file will contain the
string "???", the non-joined A column of file 1 will contain a value
of -1, the non-joined G column of file 3 will contain IEEE NaNs, while
the non-joined E and F columns of the same file will contain values -1
and -100, respectively. Of course, where common and specific blank values
are specified for the same column, the specific blank value is used.

)0 P(To distinguish which files are non-blank components of a given row,
the )BD(-s)ES( \201status\202 switch can be used to add a bitmask column named
"JFILES" to the output file. In this column, a bit is set for each
non-blank file composing the given row, with bit 0 corresponds to the
first file, bit 1 to the second file, and so on. The file names
themselves are stored in the FITS header as parameters named JFILE1,
JFILE2, etc.  The )BD(-S col)ES( switch allows you to change the name
of the status column from the default "JFILES".

)0 P(A join between rows is the Cartesian product of all rows in one file
having a given join column value with all rows in a second file having
the same value for its join column and so on. Thus, if file1 has 2
rows with join column value 100, file2 has 3 rows with the same value,
and file3 has 4 rows, then the join results in 2*3*4=24 rows being output.

)0 P(The join algorithm directly processes the index file associated with
the join column of each file. The smallest value of all the current
columns is selected as a base, and this value is used to join
equal-valued columns in the other files. In this way, the index files
are traversed exactly once.

)0 P(The )BD(-t tol)ES( switch specifies a tolerance value for numeric
columns.  At present, a tolerance value can join only two files at a
time.  \201A completely different algorithm is required to join more than
two files using a tolerance, somethng we might consider implementing
in the future.\202

)0 P(The following example shows many of the features of funjoin. The input files
t1.fits, t2.fits, and t3.fits contain the following columns:
) 28 49 PR(  [sh] fundisp t1.fits
        AKEY    KEY      A      B 
 ----------- ------ ------ ------
         aaa      0      0      1
         bbb      1      3      4
         ccc      2      6      7
         ddd      3      9     10
         eee      4     12     13
         fff      5     15     16
         ggg      6     18     19
         hhh      7     21     22

fundisp t2.fits
        AKEY    KEY      C      D 
 ----------- ------ ------ ------
         iii      8     24     25
         ggg      6     18     19
         eee      4     12     13
         ccc      2      6      7
         aaa      0      0      1

fundisp t3.fits
        AKEY    KEY        E        F           G
------------ ------ -------- -------- -----------
         ggg      6       18       19      100.10
         jjj      9       27       28      200.20
         aaa      0        0        1      300.30
         ddd      3        9       10      400.40)RP(

)0 P(Given these input files, the following funjoin command:
) 3 59 PR(  funjoin -s -a1 "-B" -a2 "-D" -a3 "-E" -b \200
  "AKEY:???" -b1 "AKEY:XXX,A:255" -b3 "G:NaN,E:-1,F:-100" \200
  -j key t1.fits t2.fits t3.fits foo.fits)RP(
will join the files on the KEY column, outputting all columns except B
\201in t1.fits\202, D \201in t2.fits\202 and E \201in t3.fits\202, and setting blank
values for AKEY \201globally, but overridden for t1.fits\202 and A \201in file
1\202 and G, E, and F \201in file 3\202.  A JFILES column will be output to
flag which files were used in each row:
) 12 105 PR(        AKEY    KEY      A       AKEY_2  KEY_2      C       AKEY_3  KEY_3        F           G   JFILES
  ------------ ------ ------ ------------ ------ ------ ------------ ------ -------- ----------- --------
         aaa      0      0          aaa      0      0          aaa      0        1      300.30        7
         bbb      1      3          ???      0      0          ???      0     -100         nan        1
         ccc      2      6          ccc      2      6          ???      0     -100         nan        3
         ddd      3      9          ???      0      0          ddd      3       10      400.40        5
         eee      4     12          eee      4     12          ???      0     -100         nan        3
         fff      5     15          ???      0      0          ???      0     -100         nan        1
         ggg      6     18          ggg      6     18          ggg      6       19      100.10        7
         hhh      7     21          ???      0      0          ???      0     -100         nan        1
         XXX      0    255          iii      8     24          ???      0     -100         nan        2
         XXX      0    255          ???      0      0          jjj      9       28      200.20        4)RP(



)0 2 16 H(funmerge)WB 79 Sn()WB 13 Sn( - merge one or more Funtools table files)EA()EH(


)BD() 1 61 PR(funmerge  [-w|-x] -f [colname] <iname1> <iname2>  ... <oname>)RP()ES(


)0 P() 3 68 PR(  -f    # output a column specifying file from which this event came
  -w    # adjust position values using WCS info
  -x    # adjust position values using WCS info and save old values)RP(


)0 P()BD(funmerge)ES( merges FITS data from one or more
)0 42 1 A(FITS Binary Table files)42 0 TN TL()Ec /AF f D(
or raw event files.
)0 P(The first argument to the program specifies the first input FITS table
or raw event file. If "stdin" is specified, data are read from the
standard input.  Use )0 42 1 A(Funtools Bracket
Notation)42 0 TN TL()Ec /AF f D( to specify FITS extensions and row filters.  Subsequent
arguments specify additional event files and tables to merge. \201NB: Stdin
cannot not be used for any of these additional input file arguments.\202
The last argument is the output FITS file. The columns in each input table
must be identical.

)0 P(If an input file begins with the '@' character, it is processed as an
include file, i.e., as a text file containing event file names \201as
well as blank lines and/or comment lines starting with the '#' sign\202.
If standard input is specified as an include file \201'@stdin'\202, then
file names are read from the standard input until EOF \201^D\202.  Event
files and include files can be mixed on a command line.

)0 P(Rows from each table are written sequentially to the output
file.  If the switch )BD(-f [colname])ES( is specified on the command
line, an additional column is added to each row containing the number
of the file from which that row was taken \201starting from one\202. In
this case, the corresponding file names are stored in the header
parameters having the prefix )BD(FUNFIL)ES(, i.e., FUNFIL01,
FUNFIL02, etc.

)0 P(Using the )BD(-w)ES( switch \201or )BD(-x)ES( switch as described
below\202, )BD(funmerge)ES( also can adjust the position column values
using the WCS information in each file. \201By position columns, we mean
the columns that the table is binned on, i.e., those columns defined
by the )BD(bincols=)ES( switch, or \201X,Y\202 by default.\202 To perform WCS
alignment, the WCS of the first file is taken as the base WCS.  Each
position in subsequent files is adjusted by first converting it to the
sky coordinate in its own WCS coordinate system, then by converting
this sky position to the sky position of the base WCS, and finally
converting back to a pixel position in the base system. Note that in
order to perform WCS alignment, the appropriate WCS and TLMIN/TLMAX
keywords must already exist in each FITS file.
)0 P(When performing WCS alignment, you can save the original positions in
the output file by using the )BD(-x)ES( \201for "xtra"\202 switch instead
of the )BD(-w)ES( switch \201i.e., using this switch also implies using
)BD(-w)ES(\202 The old positions are saved in columns having the same
name as the original positional columns, with the added prefix "OLD_".
)0 P(Examples:

)0 P(Merge two tables, and preserve the originating file number for
each row in the column called "FILE" \201along with the corresponding
file name in the header\202:
) 1 51 PR(  [sh] funmerge -f "FILE" test.ev test2.ev merge.ev)RP(

)0 P(Merge two tables with WCS alignment, saving the old position values in
2 additional columns:
) 1 44 PR(  [sh] funmerge -x test.ev test2.ev merge.ev)RP(

)0 P(This program only works on raw event files and binary tables. We have
not yet implemented image and array merging.




)0 2 17 H(funsky)WB 80 Sn()WB 14 Sn( - convert between image and sky coordinates)EA()EH(


)BD() 4 72 PR(  funsky iname[ext]               # RA,Dec \201deg\202 or image pix from stdin
  funsky iname[ext] [lname]       # RA, Dec \201deg\202 or image pix from list
  funsky iname[ext] [col1] [col2]         # named cols:units from stdin
  funsky iname[ext] [lname] [col1] [col2] # named cols:units from list)RP()ES(


)0 P() 5 73 PR(  -d        # always use integer tlmin conversion \201as ds9 does\202
  -r        # convert x,y to RA,Dec \201default: convert RA,Dec to x,y\202
  -o        # include offset from the nominal target position \201in arcsec\202
  -v        # display input values also \201default: display output only\202
  -T        # output display in rdb format \201w/header,tab delimiters\202)RP(


)0 P(Funsky converts input sky coordinates \201RA, Dec\202 to image coordinates \201or vice
versa\202 using the WCS information contained in the specified FITS file. Several
calling sequences are supported in order to make it easy to specify
coordinate positions in different ways.

)0 P(The first required argument is always the input FITS file \201or
extension\202 containing the WCS information in an extension header. Note
that the data from this file is not used. By default, the program
converts input RA and Dec values to X and Y using this WCS
information. If the WCS is associated with a FITS image, then the X,Y
values are image values. If the WCS is associated with a binary table,
then the X, Y values are physical values.  To convert X,Y to RA and
Dec, use the )BD(-r)ES( \201reverse\202 switch.

)0 P(If no other command arguments are supplied, then the input positions
are read from the standard input. Each line is assumed to contain a
single coordinate position consisting of an RA in degrees \201or X in
pixels\202 followed by a Dec in degrees \201or Y in pixels\202. The usual
delimiters are supported \201spaces, commas, tabs\202. For example:
) 9 52 PR( # read from stdin, default column names and units
 [sh] funsky snr.ev
 22.982695    58.606523   # input RA \201hrs\202, Dec\201deg\202
    510.00       510.00
 22.982127    58.607634   # input
    512.00       510.50
 22.981700    58.614301   # input
    513.50       513.50
 ^D                       # end of input)RP(

)0 P(If a second argument is supplied, this argument is assumed to be
a file containing RA \201X\202 and Dec \201Y\202 positions. The file can either be
an ASCII table or a FITS binary table. The order of columns is
unimportant, if the table has a column header. In this case, the
names of the columns must be one of "RA", "DEC", or "X", "Y" for sky
to image and image to sky conversions, respectively. If the table has
no header, then once again, RA \201X\202 is assumed to first, followed
by DEC \201Y\202.
For example:
) 12 50 PR(  # read from file, default column names and units
  [sh] cat hd.in
         RA          DEC
  ---------    ---------
  22.982695    58.606523
  22.982127    58.607634
  22.981700    58.614301

  [sh] funsky snr.ev hd.in
        510.00       510.00
        512.00       510.50
        513.50       513.50)RP(

)0 P(If three arguments are supplied, then the input positions again are
read from the standard input. Each line is assumed to contain a single
coordinate position consisting of an RA \201or X in pixels\202 followed by a
Dec \201or Y in pixels\202, with the usual delimiters supported. However,
the second and third arguments now specify the column names and/or
sky units using a colon-delimited syntax:
) 1 19 PR(  [colname]:[h|d|r])RP(
If the colname is omitted, the names default to "RA", "DEC", "X", "Y",
"COL1", or "COL2" as above. If the units are omitted, the default is degrees
for both RA and Dec. When the -r switch is used \201convert from image
to sky\202 the units are applied to the output instead of the input. The following
examples will serve to illustrate the options:
) 36 66 PR(  # read from stdin, specifying column names \201def. units: degrees\202
  [sh] cat hd.in
       MYRA        MYDEC
  ---------    ---------
  22.982695    58.606523
  22.982127    58.607634
  22.981700    58.614301

  [sh] funsky snr.ev MYRA MYDEC < hd.in
        510.00       510.00
        512.00       510.50
        513.50       513.50

  # read from stdin, specifying column names and units
  [sh] cat dd.in
       MYRA        MYDEC
  ---------    ---------
  344.740432    58.606523
  344.731900    58.607634
  344.725500    58.614301

  [sh] funsky snr.ev MYRA:d MYDEC:d < dd.in
        510.00       510.00
        512.00       510.50
        513.50       513.50

  # read stdin, convert image to sky, specifying output sky units
  [sh] cat im.in
        510.00       510.00
        512.00       510.50
        513.50       513.50)WR(

  [sh] cat im.in | funsky -r snr.ev :d :d
  344.740432    58.606523
  344.731900    58.607634
  344.725500    58.614301)RP(

)0 P(Finally, four command arguments specify both and input file and column names
and/or units:
) 22 64 PR(  [sh] cat dd.in
       MYRA        MYDEC
  ---------    ---------
  344.740432    58.606523
  344.731900    58.607634
  344.725500    58.614301

  [sh] funsky snr.ev dd.in MYRA:d MYDEC:d
        510.00       510.00
        512.00       510.50
        513.50       513.50

  # read file, convert image to sky, specifying output sky units
  [sh] cat im.in
        510.00       510.00
        512.00       510.50
        513.50       513.50

  [sh] funsky -r snr.ev im.in :d :d
    344.740432    58.606523
    344.731900    58.607634
    344.725500    58.614301)RP(

)0 P(By default, the output of funsky consists only of the converted coordinate
position\201s\202, one per output line. This makes parsing in shell scripts easy.
Use the )BD(-v)ES( \201verbose\202 switch to specify that the input
coordinates should be pre-pended to each line. For example:
) 16 53 PR(  [sh] cat dd.in
       MYRA        MYDEC
  ---------    ---------
  344.740432    58.606523
  344.731900    58.607634
  344.725500    58.614301

  [sh] funsky snr.ev dd.in MYRA:d MYDEC:d
        510.00       510.00
        512.00       510.50
        513.50       513.50

  [sh] funsky -v snr.ev dd.in MYRA:d MYDEC:d
    344.740432    58.606523       510.00       510.00
    344.731900    58.607634       512.00       510.50
    344.725500    58.614301       513.50       513.50)RP(

)0 P(In addition, a full starbase table can be output using the )BD(-T)ES(
\201table\202 switch.  This switch can be used with or without the -v
switch. If the -T and -v are both specified, then a descriptive header
parameters are output before the table \201mainly to remind you of the
sky units\202:
) 23 62 PR(  # output table in non-verbose mode
  [sh] funsky -T snr.ev dd.in MYRA:d MYDEC:d
             X               Y
  ------------    ------------
        510.00          510.00
        512.00          510.50
        513.50          513.50
  
  # output table in verbose mode
  [sh] funsky -T -v snr.ev dd.in MYRA:d MYDEC:d
  # IFILE = /Users/eric/data/snr.ev
  # ICOL1 = MYRA
  # ICOL2 = MYDEC
  # IUNITS1 = d
  # IUNITS2 = d
  # OCOL1 = X
  # OCOL2 = Y
  
          MYRA           MYDEC               X               Y
  ------------    ------------    ------------    ------------
    344.740432       58.606523          510.00          510.00
    344.731900       58.607634          512.00          510.50
    344.725500       58.614301          513.50          513.50)RP(

)0 P(Finally, the )BD(-d)ES( \201ds9\202 switch mimicks ds9's use of integer TLMIN
and TLMAX values for all coordinate transformations.  FITS conventions
seem to call for use of floating point TLMIN and TLMAX when the data are
floats. This convention is followed by funsky but results in a
small discrepancy with ds9's converted values for floating point
data. We will remedy this conflict in the future, maybe.




)0 2 18 H(funtable)WB 81 Sn()WB 15 Sn( - copy selected rows from a Funtools file to a FITS binary table)EA()EH(


)BD() 1 62 PR(funtable [-a] [-i|-z] [-m] [-s cols] <iname> <oname> [columns])RP()ES(


)0 P() 5 61 PR(  -a    # append to existing output file as a table extension
  -i    # for image data, only generate X and Y columns
  -m    # for tables, write a separate file for each region
  -s "col1 ..." # columns on which to sort
  -z    # for image data, output zero-valued pixels)RP(


)0 P()BD(funtable)ES( selects rows from the specified
)0 42 1 A(FITS Extension)42 0 TN TL()Ec /AF f D(
\201binary table only\202 of a FITS file, or from a non-FITS raw event
file, and writes those rows to a FITS binary table file. It also
will create a FITS binary table from an image or a raw array file.

)0 P(The first argument to the program specifies the FITS file, raw event
file, or raw array file.  If "stdin" is specified, data are read from
the standard input. Use )0 42 1 A(Funtools Bracket
Notation)42 0 TN TL()Ec /AF f D( to specify FITS extensions, and filters.  The second
argument is the output FITS file.  If "stdout" is specified, the FITS
binary table is written to the standard output.  By default, all
columns of the input file are copied to the output file.  Selected
columns can be output using an optional third argument in the form:
) 1 31 PR(  "column1 column1 ... columnN")RP(

)0 P(The )BD(funtable)ES( program generally is used to select rows from a
FITS binary table using
)0 52 1 A(Table Filters)52 0 TN TL()Ec /AF f D(
and/or
)0 54 1 A(Spatial Region Filters)54 0 TN TL()Ec /AF f D(.
For example, you can copy only selected rows \201and output only selected
columns\202 by executing in a command such as:
) 13 75 PR(  [sh] funtable "test.ev[pha==1&)SY(\160)ES(==10]" stdout "x y pi pha" | fundisp stdin
         X       Y     PHA        PI
   ------- ------- ------- ---------
         1      10       1        10
         1      10       1        10
         1      10       1        10
         1      10       1        10
         1      10       1        10
         1      10       1        10
         1      10       1        10
         1      10       1        10
         1      10       1        10
         1      10       1        10)RP(
)0 P(The special column )BD($REGION)ES( can be specified to write the
region id of each row:
) 12 113 PR(  [sh $] funtable "test.ev[time-\201int\202time>=.99&&annulus\2010 0 0 10 n=3\202]" stdout 'x y time $REGION' | fundisp stdin
          X        Y                  TIME     REGION
   -------- -------- --------------------- ----------
          5       -6           40.99000000          3
          4       -5           59.99000000          2
         -1        0          154.99000000          1
         -2        1          168.99000000          1
         -3        2          183.99000000          2
         -4        3          199.99000000          2
         -5        4          216.99000000          2
         -6        5          234.99000000          3
         -7        6          253.99000000          3)RP(
)0 P(Here only rows with the proper fractional time and whose position also is
within one of the three annuli are written.
)0 P(Columns can be excluded from display using a minus sign before the
column:
) 12 79 PR(  [sh $] funtable "test.ev[time-\201int\202time>=.99]" stdout "-time" | fundisp stdin
          X        Y      PHA         PI          DX          DY
   -------- -------- -------- ---------- ----------- -----------
          5       -6        5         -6        5.50       -6.50
          4       -5        4         -5        4.50       -5.50
         -1        0       -1          0       -1.50        0.50
         -2        1       -2          1       -2.50        1.50
         -3        2       -3          2       -3.50        2.50
         -4        3       -4          3       -4.50        3.50
         -5        4       -5          4       -5.50        4.50
         -6        5       -6          5       -6.50        5.50
         -7        6       -7          6       -7.50        6.50)RP(
All columns except the time column are written.
)0 P(In general, the rules for activating and de-activating columns are:
)UL()-1 LI( If only exclude columns are specified, then all columns but
the exclude columns will be activated.
)-1 LI( If only include columns are specified, then only the specified columns
are activated.
)-1 LI( If a mixture of include and exclude columns are specified, then
all but the exclude columns will be active; this last case
is ambiguous and the rule is arbitrary.)LU(
In addition to specifying columns names explicitly, the special
symbols )EM(+)ES( and )EM(-)ES( can be used to activate and
de-activate )EM(all)ES( columns. This is useful if you want to
activate the $REGION column along with all other columns.  According
to the rules, the syntax "$REGION" only activates the region column
and de-activates the rest. Use "+ $REGION" to activate all
columns as well as the region column.

)0 P(Ordinarily, only the selected table is copied to the output file.  In
a FITS binary table, it sometimes is desirable to copy all of the
other FITS extensions to the output file as well. This can be done by
appending a '+' sign to the name of the extension in the input file
name. For example, the first command below copies only the EVENT table,
while the second command copies other extensions as well:
) 2 64 PR(  [sh] funtable "/proj/rd/data/snr.ev[EVENTS]" events.ev
  [sh] funtable "/proj/rd/data/snr.ev[EVENTS+]" eventsandmore.ev)RP(

)0 P(If the input file is an image or a raw array file, then
)BD(funtable)ES( will generate a FITS binary table from the pixel
values in the image. Note that it is not possible to specify the
columns to output \201using command-line argument 3\202. Instead, there are
two ways to create such a binary table from an image. By default, a
3-column table is generated, where the columns are "X", "Y", and
"VALUE". For each pixel in the image, a single row \201event\202 is
generated with the "X" and "Y" columns assigned the dim1 and dim2
values of the image pixel, respectively and the "VALUE" column
assigned the value of the pixel. With sort of table, running
)BD(funhist)ES( on the "VALUE" column will give the same results as
running )BD(funhist)ES( on the original image.

)0 P(If the )BD(-i)ES( \201"individual" rows\202 switch is specified, then only
the "X" and "Y" columns are generated. In this case, each positive
pixel value in the image generates n rows \201events\202, where n is equal
to the integerized value of that pixel \201plus 0.5, for floating point
data\202.  In effect, )BD(-i)ES( approximately recreates the rows of a
table that would have been binned into the input image. \201Of course,
this is only approximately correct, since the resulting x,y positions
are integerized.\202

)0 P(If the )BD(-s [col1 col2 ... coln])ES( \201"sort"\202 switch is specified,
the output rows of a binary table will be sorted using the
specified columns as sort keys. The sort keys must be scalar columns
and also must be part of the output file \201i.e. you cannot sort on a
column but not include it in the output\202. This facility uses the
)BD(_sort)ES( program \201included with funtools\202, which must be accessible
via your path.

)0 P(For binary tables, the )BD(-m)ES( \201"multiple files"\202 switch will
generate a separate file for each region in the filter specification
i.e. each file contains only the rows from that region. Rows
which pass the filter but are not in any region also are put in a
separate file.

)0 P(The separate output file names generated by the )BD(-m)ES( switch are
produced automatically from the root output file to contain the region id of
the associated region. \201Note that region ids start at 1, so that the
file name associated with id 0 contains rows that pass the filter but
are not in any given region.\202 Output file names are generated as follows:

)UL()-1 LI( A $n specification can be used anywhere in the root file name \201suitably
quoted to protect it from the shell\202 and will be expanded to be the id
number of the associated region. For example:
) 1 78 PR(  funtable -m input.fits'[cir\201512,512,1\202;cir\201520,520,1\202...]' 'foo.goo_$n.fits')RP(
will generate files named foo.goo_0.fits \201for rows not in any region but
still passing the filter\202, foo.goo_1.fits \201rows in region id #1, the first
region\202, foo.goo_2.fits \201rows in region id #2\202, etc. Note that single quotes
in the output root are required to protect the '$' from the shell.

)-1 LI( If $n is not specified, then the region id will be placed before
the first dot \201.\202 in the filename. Thus:
) 1 73 PR(  funtable -m input.fits'[cir\201512,512,1\202;cir\201520,520,1\202...]' foo.evt.fits)RP(
will generate files named foo0.evt.fits \201for rows not in any region but
still passing the filter\202, foo1.evt.fits \201rows in region id #1\202,
foo2.evt.fits \201rows in region id #2\202, etc.

)-1 LI( If no dot is specified in the root output file name, then
the region id will be appended to the filename. Thus:
) 1 70 PR(  funtable -m input.fits'[cir\201512,512,1\202;cir\201520,520,1\202...]' 'foo_evt')RP(
will generate files named foo_evt0 \201for rows not in any region but
still passing the filter\202, foo_evt1 \201rows in region id #1\202,
foo_evt2 \201rows in region id #2\202, etc.)LU(
The multiple file mechanism provide a simple way to generate
individual source data files with a single pass through the data.

)0 P(By default, a new FITS file is created and the binary table is written
to the first extension.  If the )BD(-a)ES( \201append\202 switch is specified,
the table is appended to an existing FITS file as a BINTABLE extension.
Note that the output FITS file must already exist.

)0 P(If the )BD(-z)ES( \201"zero" pixel values\202 switch is specified and
)BD(-i)ES( is not specified, then pixels having a zero value will
be output with their "VALUE" column set to zero. Obviously, this
switch does not make sense when individual events are output.




)0 2 19 H(funtbl)WB 82 Sn()WB 16 Sn( - extract a table from Funtools ASCII output)EA()EH(


)BD() 1 61 PR(funtable [-c cols] [-h] [-n table] [-p prog] [-s sep] <iname>)RP()ES(


)0 P([NB: This program has been deprecated in favor of the ASCII text processing
support in funtools. You can now perform fundisp on funtools ASCII output
files \201specifying the table using bracket notation\202 to extract tables
and columns.]

The )BD(funtbl)ES( script extracts a specified table \201without the
header and comments\202 from a funtools ASCII output file and writes the
result to the standard output.  The first non-switch argument is the
ASCII input file name \201i.e. the saved output from funcnts, fundisp,
funhist, etc.\202. If no filename is specified, stdin is read. The
-n switch specifies which table \201starting from 1\202 to extract. The
default is to extract the first table.  The -c switch is a
space-delimited list of column numbers to output, e.g.  -c "1 3 5"
will extract the first three odd-numbered columns. The default is to
extract all columns. The -s switch specifies the separator string to
put between columns. The default is a single space. The -h switch
specifies that column names should be added in a header line before
the data is output. Without the switch, no header is prepended.  The
-p program switch allows you to specify an awk-like program to run
instead of the default \201which is host-specific and is determined at
build time\202. The -T switch will output the data in rdb format \201i.e.,
with a 2-row header of column names and dashes, and with data columns
separated by tabs\202. The -help switch will print out a message
describing program usage.

)0 P(For example, consider the output from the following funcnts command:
) 37 82 PR(  [sh] funcnts -sr snr.ev "ann 512 512 0 9 n=3"
  # source
  #   data file:        /proj/rd/data/snr.ev
  #   arcsec/pixel:     8
  # background
  #   constant value:   0.000000
  # column units
  #   area:             arcsec**2
  #   surf_bri:         cnts/arcsec**2
  #   surf_err:         cnts/arcsec**2
  
  # summed background-subtracted results
  upto   net_counts     error   background    berror      area  surf_bri  surf_err
  ---- ------------ --------- ------------ --------- --------- --------- ---------
     1      147.000    12.124        0.000     0.000   1600.00     0.092     0.008
     2      625.000    25.000        0.000     0.000   6976.00     0.090     0.004
     3     1442.000    37.974        0.000     0.000  15936.00     0.090     0.002
  
  
  # background-subtracted results
   reg   net_counts     error   background    berror      area  surf_bri  surf_err
  ---- ------------ --------- ------------ --------- --------- --------- ---------
     1      147.000    12.124        0.000     0.000   1600.00     0.092     0.008
     2      478.000    21.863        0.000     0.000   5376.00     0.089     0.004
     3      817.000    28.583        0.000     0.000   8960.00     0.091     0.003
  
  
  # the following source and background components were used:
  source_region\201s\202
  ----------------
  ann 512 512 0 9 n=3)WR(
  
   reg       counts    pixels      sumcnts    sumpix
  ---- ------------ --------- ------------ ---------
     1      147.000        25      147.000        25
     2      478.000        84      625.000       109
     3      817.000       140     1442.000       249)RP(
)0 P(There are four tables in this output. To extract the last one, you
can execute:
) 4 60 PR(  [sh] funcnts -s snr.ev "ann 512 512 0 9 n=3" | funtbl -n 4
  1 147.000 25 147.000 25
  2 478.000 84 625.000 109
  3 817.000 140 1442.000 249)RP(
Note that the output has been re-formatted so that only a single space
separates each column, with no extraneous header or comment information.

)0 P(To extract only columns 1,2, and 4 from the last example \201but with a header
prepended and tabs between columns\202, you can execute:
) 5 82 PR(  [sh] funcnts -s snr.ev "ann 512 512 0 9 n=3" | funtbl -c "1 2 4" -h -n 4 -s "\200t"
  #reg    counts  sumcnts
  1       147.000 147.000
  2       478.000 625.000
  3       817.000 1442.000)RP(
)0 P(Of course, if the output has previously been saved in a file named
foo.out, the same result can be obtained by executing:
) 5 48 PR(  [sh] funtbl -c "1 2 4" -h -n 4 -s "\200t" foo.out
  #reg    counts  sumcnts
  1       147.000 147.000
  2       478.000 625.000
  3       817.000 1442.000)RP(































)0 P()0 0 1 A(Go to Funtools Help Index)0 0 TN TL()Ec /AF f D(

)0 5 20 H(Last)WB 83 Sn( updated: April 1, 2007)EH(

)WB NL
/Cb Db D /Ct [16#00 16#00 16#00] D /Cl [16#00 16#00 16#00] D /CL -1 D Ct Sc
DS
/Ba f D /BO 0 D Bs
/UR (ds9.html) D
/Ti (Funtools and DS9 Image Display) D
/Au () D
/Df f D
/ME [()] D

0 BO R
()1 Sl()WB 17 Sn(


)0 2 21 H(FunDS9:)WB 85 Sn()WB 84 Sn( Funtools and DS9 Image Display)EA()EH(


)0 2 22 H(Summary)WB 86 Sn()EH(
Describes how funtools can be integrated into the ds9 Analysis menu.


)0 2 23 H(Description)WB 87 Sn()EH(
)0 P()R1 2 A(SAOImage/DS9)EA( is an astronomical imaging and data visualization
application used by astronomers around the world.  DS9 can display
standard astronomical FITS images and binary tables, but also has
support for displaying raw array files, shared memory files, and data
files automatically retrieved via FTP and HTTP.  Standard functional
capabilities include multiple frame buffers, colormap and region
manipulation, and many data scaling algorithms. DS9's advanced
features include TrueColor visuals, deep frame buffers, true
PostScript printing, and display of image mosaics. The program's
support of image tiling, "blinking", arbitrary zoom, rotation, and pan
is unparalleled in astronomy. It also has innovative support for
automatic retrieval and display of standard image data such as the
Digital Sky Survey \201using servers at SAO, StScI, or ESO\202.

)0 P(DS9 can communicate with external programs such as Funtools using the
)R2 2 A(XPA)EA(
messaging system.  In addition, programs can be integrated directly
into the DS9 GUI by means of a configurable Analysis menu.  By
default, the DS9 Analysis menu contains algorithms deemed essential to
the core functions of DS9, e.g., display cross-cuts of data,
iso-intensity contours, and WCS grids. However, new programs can be
added to DS9 by creating a set-up file which can be loaded into DS9 
to reconfigure the Analysis menu.

) 7 48 PR(The basic format of the analysis set-up file is:
)0 P(  #
  # Analysis command descriptions:
  #   menu label/description
  #   file templates for this command
  #   "menu" \201add to menu\202 |"bind" \201bind to key\202
  #   analysis command line)RP(

For example, the funcnts program can be specified in this way:
) 4 69 PR(  Funcnts \201counts in source/bkgd regions; options: none\202
  *
  menu
  funcnts $filename $regions\201source,,\202 $regions\201background,,\202 | $text)RP(
As shown above, DS9 supports a macro facility to provide information
as well as task support to command lines. For example, the $regions
macro is expanded by DS9 to provide the current source and/or
background region to the analysis command. The $text macro is expanded
to generate a text window display. It also is possible to query for
parameters using a $param macro, plot data using a $plot macro,
etc. See the DS9 documentation for further details.

)0 P(A set-up file called )0 2 A(funtools.ds9)EA( will
load some useful Funtools applications \201counts in regions, radial
profile, X-ray light curve and energy spectrum, 1D histogram\202 into the DS9
Analysis menu \201version 2.1 and above\202.  The file resides in the bin
directory where Funtools programs are installed. It can be manually
loaded into DS9 from the )BD(Load Analysis Commands ...)ES( option of
the )BD(Analysis)ES( menu.  Alternatively, you can tell DS9 to load
this file automatically at start-up time by adding the pathname to the
)BD(Edit)ES(->)BD(Preferences)ES(->)BD(Analysis Menu)ES(->)BD(Analysis
File)ES( menu option.  \201NB: make sure you select
)BD(Edit)ES(->)BD(Preferences)ES(->)BD(Save Preferences)ES( after setting
the pathname.\202

)0 P(The tasks in this setup file generally process the original disk-based
FITS file.  Funcnts-based results \201radial profile, counts in regions\202
are presented in WCS units, if present in the FITS header. For
situations where a disk file is not available \201e.g., image data
generated and sent to DS9's 'fits' XPA access point\202, versions of the
radial profile and counts in regions tasks also are also offered
utilizing DS9's internal image data. Results are presented in pixels.
Aside from the units, the results should be identical to the file-based
results.





)0 P()0 0 1 A(Go to Funtools Help Index)0 0 TN TL()Ec /AF f D(

)0 5 24 H(Last)WB 88 Sn( updated: November 16, 2005)EH(

)WB NL
/Cb Db D /Ct [16#00 16#00 16#00] D /Cl [16#00 16#00 16#00] D /CL -1 D Ct Sc
DS
/Ba f D /BO 0 D Bs
/UR (library.html) D
/Ti (Funtools Programming) D
/Au () D
/Df f D
/ME [()] D

0 BO R
()1 Sl()WB 18 Sn(


)0 2 25 H(FunLib:)WB 91 Sn()WB 89 Sn( the Funtools Programming Interface)EA()EH(


)0 2 26 H(Summary)WB 92 Sn()EH(
A description of the Funtools library.


)0 2 27 H(Introduction)WB 93 Sn()WB 90 Sn( to the Funtools Programming Interface)EH()EA(
)0 P(To create a Funtools application, you need to include
the funtools.h definitions file in your code:
) 1 23 PR(  #include <funtools.h>)RP(

You then call Funtools subroutines and functions to access Funtools data.
The most important routines are:
)UL(
)0 P()-1 LI( )0 25 1 A(FunOpen)25 0 TN TL()Ec /AF f D(: open a Funtools file
)-1 LI()0 35 1 A(FunInfoGet)35 0 TN TL()Ec /AF f D(: get info about an image or table
)-1 LI()0 26 1 A(FunImageGet)26 0 TN TL()Ec /AF f D(: retrieve image data
)-1 LI()0 28 1 A(FunImageRowGet)28 0 TN TL()Ec /AF f D(: retrieve image data by row
)-1 LI()0 27 1 A(FunImagePut)27 0 TN TL()Ec /AF f D(: output image data
)-1 LI()0 29 1 A(FunImageRowPut)29 0 TN TL()Ec /AF f D(: output image data by row
)-1 LI()0 32 1 A(FunColumnSelect)32 0 TN TL()Ec /AF f D(: select columns in a table for access
)-1 LI()0 30 1 A(FunTableRowGet)30 0 TN TL()Ec /AF f D(: retrieve rows from a table
)-1 LI()0 31 1 A(FunTableRowPut)31 0 TN TL()Ec /AF f D(: output rows to a table
)-1 LI( )0 40 1 A(FunClose)40 0 TN TL()Ec /AF f D(: close a Funtools file)LU(

Your program must be linked against the libfuntools.a library,
along with the math library. The following libraries also might be required
on your system:
)UL()-1 LI( -lsocket -lnsl for socket support
)-1 LI( -ldl           for dynamic loading)LU(
)0 P(For example, on a Solaris system using gcc, use the following link line:
) 1 53 PR(  gcc -o foo foo.c -lfuntools -lsocket -lnsl -ldl -lm)RP(
On a Solaris system using Solaris cc, use the following link line:
) 1 48 PR(  gcc -o foo foo.c -lfuntools -lsocket -lnsl -lm)RP(
On a Linux system using gcc, use the following link line:
) 1 38 PR(  gcc -o foo foo.c -lfuntools -ldl -lm)RP(
Once configure has built a Makefile on your platform, the required
"extra" libraries \201aside from -lm, which always is required\202 are
specified in that file's EXTRA_LIBS variable. For example, under
Linux you will find:
) 3 26 PR(  grep EXTRA_LIBS Makefile
  EXTRA_LIBS      =  -ldl
  ...)RP(

)0 P(The Funtools library contains both the zlib library
\201http://www.gzip.org/zlib/\202 and Doug Mink's WCS library
\201http://tdc-www.harvard.edu/software/wcstools/\202.  It is not necessary
to put these libraries on a Funtools link line. Include files
necessary for using these libraries are installed in the Funtools
include directory.

)0 2 28 H(Funtools)WB 94 Sn()WB 20 Sn( Programming Tutorial)EA()EH(

The
)0 25 1 A(FunOpen\201\202)25 0 TN TL()Ec /AF f D(
function is used to open a FITS file, an array, or a raw event file:
) 4 79 PR(  /* open the input FITS file for reading */
  ifun = FunOpen\201iname, "r", NULL\202;
  /* open the output FITS file for writing, and connect it to the input file */
  ofun = FunOpen\201iname, "w", ifun\202;)RP(
A new output file can inherit header parameters automatically from
existing input file by passing the input Funtools handle as the last
argument to the new file's
)0 25 1 A(FunOpen\201\202)25 0 TN TL()Ec /AF f D(
call as shown above.

)0 P(For image data, you then can call
)0 26 1 A(FunImageGet\201\202)26 0 TN TL()Ec /AF f D(
to read an image into memory.
) 3 61 PR(  float buf=NULL;
  /* extract and bin the data section into an image buffer */
  buf = FunImageGet\201fun, NULL, "bitpix=-32"\202;)RP(
If the \201second\202 buf argument to this call is NULL, buffer space is allocated
automatically. The \201third\202 plist argument can be used to specify the
return data type of the array.  If NULL is specified, the data type of
the input file is used.

)0 P(To process an image buffer, you would generally make a call to 
)0 35 1 A(FunInfoGet\201\202)35 0 TN TL()Ec /AF f D( to determine the
dimensions of the image \201which may have been changed from the original
file dimensions due to )0 49 1 A(Funtools image
sectioning)49 0 TN TL()Ec /AF f D( on the command line\202. In a FITS image, the index along
the dim1 axis varies most rapidly, followed by the dim2 axis, etc.
Thus, to access each pixel in an 2D image, use a double loop such as:)RP(
  buf = FunImageGet\201fun, NULL, "bitpix=-32"\202;
  FunInfoGet\201fun, FUN_SECT_DIM1, &dim1, FUN_SECT_DIM2, &dim2, 0\202;
  for\201i=1; i<=dim2; i++\202{
    for\201j=1; j<=dim1; j++\202{
      ... process buf[\201\201i-1\202*dim1\202+\201j-1\202] ...
    }
  })RP(
or:
) 5 65 PR(  buf = FunImageGet\201fun, NULL, "bitpix=-32"\202;
  FunInfoGet\201fun, FUN_SECT_DIM1, &dim1, FUN_SECT_DIM2, &dim2, 0\202;
  for\201i=0; i<\201dim1*dim2\202; i++\202{
    ... process buf[i] ...
  })RP(
Finally, you can write the resulting image to disk using
)0 27 1 A(FunImagePut\201\202)27 0 TN TL()Ec /AF f D(:
) 1 48 PR(  FunImagePut\201fun2, buf, dim1, dim2, -32, NULL\202;)RP(
Note that Funtools automatically takes care of book-keeping tasks such as
reading and writing FITS headers \201although you can, of course, write
your own header or add your own parameters to a header\202.

)0 P(For binary tables and raw event files, a call to
)0 25 1 A(FunOpen\201\202)25 0 TN TL()Ec /AF f D(
will be followed by a call to the
)0 32 1 A(FunColumnSelect\201\202)32 0 TN TL()Ec /AF f D(
routine to select columns to be read from the input file and/or
written to the output file:

) 8 69 PR(  typedef struct evstruct{
    double time;
    int time2;
  } *Ev, EvRec;
  FunColumnSelect\201fun, sizeof\201EvRec\202, NULL,
                  "time",      "D",     "rw",  FUN_OFFSET\201Ev, time\202,
                  "time2",     "J",     "w",   FUN_OFFSET\201Ev, time2\202,
                  NULL\202;)RP(
Columns whose \201third\202 mode argument contains an "r" are "readable",
i.e., columns will be read from the input file and converted into the
data type specified in the call's second argument. These columns
values then are stored in the specified offset of the user record
structure.  Columns whose mode argument contains a "w" are
"writable", i.e., these values will be written to the output file.
The
)0 32 1 A(FunColumnSelect\201\202)32 0 TN TL()Ec /AF f D(
routine also offers the option of automatically merging user
columns with the original input columns when writing the output
rows.

)0 P(Once a set of columns has been specified, you can retrieve rows using
)0 30 1 A(FunTableRowGet\201\202)30 0 TN TL()Ec /AF f D(,
and write the rows using
)0 31 1 A(FunTableRowPut\201\202)31 0 TN TL()Ec /AF f D(:
) 17 70 PR(  Ev ebuf, ev;
  /* get rows -- let routine allocate the array */
  while\201 \201ebuf = \201Ev\202FunTableRowGet\201fun, NULL, MAXROW, NULL, &got\202\202 \202{
    /* process all rows */
    for\201i=0; i<got; i++\202{
      /* point to the i'th row */
      ev = ebuf+i;
      /* time2 is generated here */
      ev->time2 = \201int\202\201ev->time+.5\202;
      /* change the input time as well */
      ev->time = -\201ev->time/10.0\202;
    }
    /* write out this batch of rows with the new column */
    FunTableRowPut\201fun2, \201char *\202ebuf, got, 0, NULL\202;
    /* free row data */
    if\201 ebuf \202 free\201ebuf\202;
  })RP(
The input rows are retrieved into an array of user structs, which
can be accessed serially as shown above. Once again, Funtools
automatically takes care of book-keeping tasks such as reading and writing
FITS headers \201although you can, of course, write your own header or
add your own parameters to a header\202.

)0 P(When all processing is done, you can call
)0 40 1 A(FunClose\201\202)40 0 TN TL()Ec /AF f D(
to close the file\201s\202:
) 2 17 PR(  FunClose\201fun2\202;
  FunClose\201fun\202;)RP(

)0 P(These are the basics of processing FITS files \201and arrays or raw event
data\202 using Funtools. The routines in these examples are described in
more detail below, along with a few other routines that support
parameter access, data flushing, etc.

)0 2 29 H(Compiling)WB 95 Sn()WB 22 Sn( and Linking)EA()EH(
)0 P(To create a Funtools application, a software developer will include
the funtools.h definitions file in Funtools code:
) 1 23 PR(  #include <funtools.h>)RP(
The program is linked against the libfuntools.a library, along with the
math library \201and the dynamic load library, if the latter is available
on your system\202:
) 1 38 PR(  gcc -o foo foo.c -lfuntools -ldl -lm)RP(
)0 P(If gcc is used, Funtools filtering can be performed using dynamically
loaded shared objects that are built at run-time. Otherwise, filtering
is performed using a slave process.
)0 P(Funtools has been built on the following systems:
)UL()-1 LI( Sun/Solaris 5.X
)-1 LI( Linux/RedHat Linux 5.X,6.X,7.X
)-1 LI( Dec Alpha/OSF1 V4.X
)-1 LI( WindowsNT/Cygwin 1.0
)-1 LI( SGI/IRIX64 6.5)LU(

)0 2 30 H(A)WB 96 Sn()WB 21 Sn( Short Digression on Subroutine Order)EA()EH(
)0 P(There is a natural order for all I/O access libraries. You would not
think of reading a file without first opening it, or writing a file
after closing it. A large part of the experiment in funtools is to use
the idea of "natural order" as a means of making programming
easier. We do this by maintaining the state of processing for a given
funtools file, so that we can do things like write headers and flush
extension padding at the right time, without you having to do it.

)0 P(For example, if you open a new funtools file for writing using
)0 25 1 A(FunOpen\201\202)25 0 TN TL()Ec /AF f D(,
then generate an array of image data and call
)0 27 1 A(FunImagePut\201\202)27 0 TN TL()Ec /AF f D(,
funtools knows to write the image header automatically.
There is no need to think about writing a standard header.
Of course, you can add parameters to the file first by
calling one of the
)0 38 1 A(FunParamPut\201\202)38 0 TN TL()Ec /AF f D(
routines, and these parameters will automatically be added
to the header when it is written out.  There still is no
need to write the header explicitly.

)0 P(Maintaining state in this way means that there are certain rules of
order which should be maintained in any funtools program. In particular,
we strongly recommend the following ordering rules be adhered to:

)UL()-1 LI( When specifying that input extensions be copied to an output file
via a reference handle, open the output file )BD(before)ES( reading the
input file. \201Otherwise the initial copy will not occur\202.

)-1 LI( Always write parameters to an output file using one of the
)0 38 1 A(FunParamPut\201\202)38 0 TN TL()Ec /AF f D( calls
)BD(before)ES( writing any data. \201This is a good idea for all FITS
libraries, to avoid having to recopy data is the FITS header needs
to be extended by adding a single parameter.\202

)-1 LI( If you retrieve an image, and need to know the data
type, use the FUN_SECT_BITPIX option of
)0 35 1 A(FunInfoGet\201\202)35 0 TN TL()Ec /AF f D(,
)BD(after)ES( calling
)0 26 1 A(FunImageGet\201\202)26 0 TN TL()Ec /AF f D(, since
it is possible to change the value of BITPIX from the latter.

)-1 LI( When specifying that input extensions be copied to an output file
via a reference handle, close the output file )BD(before)ES( closing
input file, or else use
)0 39 1 A(FunFlush\201\202)39 0 TN TL()Ec /AF f D(
explicitly on the output file
)BD(before)ES( closing the input file. \201Otherwise the final copy will
not occur\202.)LU(

)0 P(We believe that these are the natural rules that are implied in most
FITS programming tasks. However, we recognize that making explicit use
of "natural order" to decide what automatic action to take on behalf
of the programmer is experimental.  Therefore, if you find that your
needs are not compatible with our preferred order, please let us know
-- it will be most illuminating for us as we evaluate this experiment.

)0 2 31 H(Funtools)WB 97 Sn()WB 41 Sn( Programming Examples)EA()EH(
)0 P(The following complete coding examples are provided to illustrate the
simplicity of Funtools applications.  They can be found in the funtest
subdirectory of the Funtools distribution.  In many cases, you should
be able to modify one of these programs to generate your own Funtools
program:
)UL()-1 LI()0 2 A(evread.c)EA(: read and write binary tables
)-1 LI()0 2 A(evcols.c)EA(: add column and rows to binary tables
)-1 LI()0 2 A(evmerge.c)EA(: merge new columns with existing columns
)-1 LI()0 2 A(evnext.c)EA(: manipulate raw data pointers
)-1 LI()0 2 A(imblank.c)EA(: blank out image values below a threshold
)-1 LI()0 2 A(asc2fits.c)EA(: convert a specific ASCII table to FITS binary table)LU(

)0 2 32 H(The)WB 98 Sn()WB 24 Sn( Funtools Programming Reference Manual)EA()EH(
)0 P() 45 116 PR(#include <funtools.h>

Fun )0 25 1 A(FunOpen\201char *name, char *mode, Fun ref\202)25 0 TN TL()Ec /AF f D(

void *)0 26 1 A(FunImageGet\201Fun fun, void *buf, char *plist\202)26 0 TN TL()Ec /AF f D(

int )0 27 1 A(FunImagePut\201Fun fun, void *buf, int dim1, int dim2, int bitpix, char *plist\202)27 0 TN TL()Ec /AF f D(

void * )0 28 1 A(FunImageRowGet\201Fun fun, void *buf, int rstart, int rstop, char *plist\202)28 0 TN TL()Ec /AF f D(

void * )0 29 1 A(FunImageRowPut\201Fun fun, void *buf, int rstart, int rstop, int dim1, int dim2, int bitpix, char *plist\202)29 0 TN TL()Ec /AF f D(

int )0 32 1 A(FunColumnSelect\201Fun fun, int size, char *plist, ...\202)32 0 TN TL()Ec /AF f D(

void )0 33 1 A(FunColumnActivate\201Fun fun, char *s, char *plist\202)33 0 TN TL()Ec /AF f D(

int )0 34 1 A(FunColumnLookup\201Fun fun, char *s, int which, char **name, int *type, int *mode, int *offset, int *n, int *width\202)34 0 TN TL()Ec /AF f D(

void *)0 30 1 A(FunTableRowGet\201Fun fun, void *rows, int maxrow, char *plist, int *nrow\202)30 0 TN TL()Ec /AF f D(

int )0 31 1 A(FunTableRowPut\201Fun fun, void *rows, int nev, int idx, char *plist\202)31 0 TN TL()Ec /AF f D(

int )0 37 1 A(FunParamGetb\201Fun fun, char *name, int n, int defval, int *got\202)37 0 TN TL()Ec /AF f D(

int )0 37 1 A(FunParamGeti\201Fun fun, char *name, int n, int defval, int *got\202)37 0 TN TL()Ec /AF f D(

double )0 37 1 A(FunParamGetd\201Fun fun, char *name, int n, double defval, int *got\202)37 0 TN TL()Ec /AF f D(

char *)0 37 1 A(FunParamGets\201Fun fun, char *name, int n, char *defval, int *got\202)37 0 TN TL()Ec /AF f D(

int )0 38 1 A(FunParamPutb\201Fun fun, char *name, int n, int value, char *comm, int append\202)38 0 TN TL()Ec /AF f D()WR(

int )0 38 1 A(FunParamPuti\201Fun fun, char *name, int n, int value, char *comm, int append\202)38 0 TN TL()Ec /AF f D(

int )0 38 1 A(FunParamPutd\201Fun fun, char *name, int n, double value, int prec, char *comm, int append\202)38 0 TN TL()Ec /AF f D(

int )0 38 1 A(FunParamPuts\201Fun fun, char *name, int n, char *value, char *comm, int append\202)38 0 TN TL()Ec /AF f D(

int )0 35 1 A(FunInfoGet\201Fun fun, int type, ...\202)35 0 TN TL()Ec /AF f D(

int )0 36 1 A(FunInfoPut\201Fun fun, int type, ...\202)36 0 TN TL()Ec /AF f D(

void )0 39 1 A(FunFlush\201Fun fun, char *plist\202)39 0 TN TL()Ec /AF f D(

void )0 40 1 A(FunClose\201Fun fun\202)40 0 TN TL()Ec /AF f D()RP(




)0 2 33 H(FunOpen)WB 99 Sn()WB 25 Sn( - open a Funtools data file)EA()EH(


)BD() 3 47 PR(  #include <funtools.h>

  Fun FunOpen\201char *name, char *mode, Fun ref\202;)RP()ES(


)0 P(The )BD(FunOpen\201\202)ES( routine opens a Funtools data file for reading or
appending, or creates a new FITS file for writing. The )BD(name)ES(
argument specifies the name of the Funtools data file to open. You can
use IRAF-style bracket notation to specify
)0 42 1 A(Funtools Files, Extensions, and Filters)42 0 TN TL()Ec /AF f D(.
A separate call should be made each time a different FITS extension is
accessed:
) 7 65 PR(  Fun fun;
  char *iname;
  ...
  if\201 !\201fun = FunOpen\201iname, "r", NULL\202\202 \202{
    fprintf\201stderr, "could not FunOpen input file: %s\200n", iname\202;
    exit\2011\202;
  })RP(
)0 P(If )BD(mode)ES( is "r", the file is opened for reading, and processing
is set up to begin at the specified extension. For reading,
)BD(name)ES( can be )BD(stdin)ES(, in which case the standard input is read.

)0 P(If )BD(mode)ES( is "w", the file is created if it does not exist, or
opened and truncated for writing if it does exist. Processing starts
at the beginning of the file.  The )BD(name)ES( can be )BD(stdout)ES(,
in which case the standard output is readied for processing.

)0 P(If )BD(mode)ES( is "a", the file is created if it does not exist, or
opened if it does exist. Processing starts at the end of the file.
The )BD(name)ES( can be )BD(stdout)ES(, in which case the standard
output is readied for processing.

)0 P(When a Funtools file is opened for writing or appending, a previously
opened )0 23 1 A(Funtools reference
handle)23 0 TN TL()Ec /AF f D( can be specified as the third argument. This handle
typically is associated with the input Funtools file that will be used
to generate the data for the output data.  When a reference file is
specified in this way, the output file will inherit the \201extension\202
header parameters from the input file:
) 8 67 PR(  Fun fun, fun2;
  ...
  /* open input file */
  if\201 !\201fun = FunOpen\201argv[1], "r", NULL\202\202 \202
    gerror\201stderr, "could not FunOpen input file: %s\200n", argv[1]\202;
  /* open the output FITS image, inheriting params from input */
  if\201 !\201fun2 = FunOpen\201argv[2], "w", fun\202\202 \202
    gerror\201stderr, "could not FunOpen output file: %s\200n", argv[2]\202;)RP(
Thus, in the above example, the output FITS binary table file will
inherit all of the parameters associated with the input binary table
extension.
)0 P(A file opened for writing with a 
)0 23 1 A(Funtools reference handle)23 0 TN TL()Ec /AF f D( also
inherits the selected columns \201i.e. those columns chosen for
processing using the 
)0 32 1 A(FunColumnSelect\201\202)32 0 TN TL()Ec /AF f D( routine\202
from the reference file as its default columns. This makes it easy to
open an output file in such a way that the columns written to the
output file are the same as the columns read in the input file. Of
course, column selection can easily be tailored using the 
)0 32 1 A(FunColumnSelect\201\202)32 0 TN TL()Ec /AF f D( routine.
In particular, it is easy to merge user-defined columns with the input
columns to generate a new file.  See the 
)0 2 A(evmerge)EA( for a complete example.

)0 P(In addition, when a
)0 23 1 A(Funtools reference handle)23 0 TN TL()Ec /AF f D(
is supplied in a )0 25 1 A(FunOpen\201\202)25 0 TN TL()Ec /AF f D( call,
it is possible also to specify that all other extensions from the
reference file \201other than the input extension being processed\202 should
be copied from the reference file to the output file. This is useful,
for example, in a case where you are processing a FITS binary table 
or image and you want to copy all of the other extensions to
the output file as well.  Copy of other extensions is controlled by
adding a "C" or "c" to the mode string of the 
)0 25 1 A(FunOpen\201\202)25 0 TN TL()Ec /AF f D( call )BD(of the input
reference file)ES(.  If "C" is specified, then other extensions are
)BD(always)ES( copied \201i.e., copy is forced by the application\202.  If
"c" is used, then other extensions are copied if the user requests
copying by adding a plus sign "+" to the extension name in the bracket
specification.  For example, the )BD(funtable)ES( program utilizes
"c" mode, giving users the option of copying all other extensions:
) 6 67 PR(  /* open input file -- allow user copy of other extensions */
  if\201 !\201fun = FunOpen\201argv[1], "rc", NULL\202\202 \202
    gerror\201stderr, "could not FunOpen input file: %s\200n", argv[1]\202;
  /* open the output FITS image, inheriting params from input */
  if\201 !\201fun2 = FunOpen\201argv[2], "w", fun\202\202 \202
    gerror\201stderr, "could not FunOpen output file: %s\200n", argv[2]\202;)RP(

Thus, )BD(funtable)ES( supports either of these command lines:
) 4 60 PR(  # copy only the EVENTS extension
  csh> funtable "test.ev[EVENTS,circle\201512,512,10\202]" foo.ev
  # copy ALL extensions
  csh> funtable "test.ev[EVENTS+,circle\201512,512,10\202]" foo.ev)RP(

)0 P(Use of a )0 23 1 A(Funtools reference
handle)23 0 TN TL()Ec /AF f D( implies that the input file is opened before the output
file.  However, it is important to note that if copy mode \201"c" or "C"\202
is specified for the input file, the actual input file open is delayed
until just after the output file is opened, since the copy of prior
extensions to the output file takes place while Funtools is seeking to
the specified input extension.  This implies that the output file
should be opened before any I/O is done on the input file or else the
copy will fail.  Note also that the copy of subsequent extension will
be handled automatically by
)0 40 1 A(FunClose\201\202)40 0 TN TL()Ec /AF f D(
if the output file is
closed before the input file. Alternatively, it can be done explicitly
by )0 39 1 A(FunFlush\201\202)39 0 TN TL()Ec /AF f D(, but again, this
assumes that the input file still is open.

)0 P(Upon success )0 25 1 A(FunOpen\201\202)25 0 TN TL()Ec /AF f D( returns a
Fun handle that is used in subsequent Funtools calls. On error, NULL
is returned.




)0 2 34 H(FunImageGet)WB 100 Sn()WB 26 Sn( - get an image or image section)EA()EH(


)BD() 3 52 PR(  #include <funtools.h>

  void *FunImageGet\201Fun fun, void *buf, char *plist\202)RP()ES(


)0 P(The )BD(FunImageGet\201\202)ES( routine returns an binned image array of the
specified section of a Funtools data file.  If the input data are
already of type image, the array is generated by extracting the
specified image section and then binning it according to the specified
bin factor.  If the input data are contained in a binary table or raw
event file, the rows are binned on the columns specified by the
)BD(bincols=)ES( keyword \201using appropriate default columns as
necessary\202, after which the image section and bin factors are
applied. In both cases, the data is automatically converted from FITS
to native format, if necessary.
)0 P(The first argument is the Funtools handle returned by 
)0 25 1 A(FunOpen\201\202)25 0 TN TL()Ec /AF f D(.  The second )BD(buf)ES(
argument is a pointer to a data buffer to fill. If NULL is specified,
FunImageGet will allocate a buffer of the appropriate size. Generally
speaking, you always want Funtools to allocate the buffer because
the image dimensions will be determined by
)0 49 1 A(Funtools image sectioning)49 0 TN TL()Ec /AF f D(
on the command line.
)0 P(The third )BD(plist)ES( \201i.e., parameter list\202 argument is a string
containing one or more comma-delimited )BD(keyword=value)ES(
parameters.  It can be used to specify the return data type using the
)BD(bitpix=)ES( keyword.  If no such keyword is specified in the plist
string, the data type of the returned image is the same as the data type
of the original input file, or is of type int for FITS binary tables.

)0 P(If the )BD(bitpix=)ES( keyword is supplied in the plist string, the data
type of the returned image will be one of the supported FITS image
data types:
)UL()-1 LI( 8 unsigned char
)-1 LI( 16 short
)-1 LI( 32 int
)-1 LI( -32 float
)-1 LI( -64 double)LU(
For example:
) 4 57 PR(  void *buf;
  /* extract data section into an image buffer */
  if\201 !\201buf = FunImageGet\201fun, NULL, NULL\202\202 \202
    gerror\201stderr, "could not FunImageGet: %s\200n", iname\202;)RP(
will allocate buf and retrieve the image in the file data format. In
this case, you will have to determine the data type \201using the
FUN_SECT_BITPIX value in the 
)0 35 1 A(FunInfoGet\201\202)35 0 TN TL()Ec /AF f D(
routine\202
and then use a switch statement to process each data type:
) 17 65 PR(  int bitpix;
  void *buf;
  unsigned char *cbuf;
  short *sbuf;
  int *ibuf;
  ...
  buf = FunImageGet\201fun, NULL, NULL\202;
  FunInfoGet\201fun, FUN_SECT_BITPIX,  &bitpix, 0\202;
  /* set appropriate data type buffer to point to image buffer */
  switch\201bitpix\202{
  case 8:
    cbuf = \201unsigned char *\202buf; break;
  case 16:
    sbuf = \201short *\202buf; break;
  case 32:
    ibuf = \201int *\202buf; break;
 ...)RP(
See the 
)0 2 A(imblank example code)EA(
for more details on how to process an image when the data type is not
specified beforehand.

)0 P(It often is easier to specify the data type directly:
) 4 57 PR(  double *buf;
  /* extract data section into a double image buffer */
  if\201 !\201buf = FunImageGet\201fun, NULL, "bitpix=-64"\202\202 \202
    gerror\201stderr, "could not FunImageGet: %s\200n", iname\202;)RP(
will extract the image while converting to type double.

)0 P(On success, a pointer to the image buffer is returned. \201This will be
the same as the second argument, if NULL is not passed to the latter.\202
On error, NULL is returned.

)0 P(In summary, to retrieve image or row data into a binned image, you simply
call FunOpen\201\202 followed by 
)0 26 1 A(FunImageGet\201\202)26 0 TN TL()Ec /AF f D(.  Generally, you
then will want to call
)0 35 1 A(FunInfoGet\201\202)35 0 TN TL()Ec /AF f D(
to retrieve the
axis dimensions \201and data type\202 of the section you are processing
\201so as to take account of sectioning and blocking of the original data\202:
) 20 73 PR(  double *buf;
  int i, j;
  int dim1, dim2;
  ... other declarations, etc.

  /* open the input FITS file */
  if\201 !\201fun = FunOpen\201argv[1], "rc", NULL\202\202 \202
    gerror\201stderr, "could not FunOpen input file: %s\200n", argv[1]\202;

  /* extract and bin the data section into a double float image buffer */
  if\201 !\201buf = FunImageGet\201fun, NULL, "bitpix=-64"\202\202 \202
    gerror\201stderr, "could not FunImageGet: %s\200n", argv[1]\202;

  /* get dimension information from funtools structure */
  FunInfoGet\201fun, FUN_SECT_DIM1, &dim1, FUN_SECT_DIM2, &dim2, 0\202;

  /* loop through pixels and reset values below limit to value */
  for\201i=0; i<dim1*dim2; i++\202{
    if\201 buf[i] <= blimit \202 buf[i] = bvalue;
  })RP(

)0 P(Another useful plist string value is "mask=all", which returns an
image populated with regions id values. Image pixels within a region
will contain the associated region id \201region values start at 1\202, and
otherwise will contain a 0 value. Thus, the returned image is a
region mask which can be used to process the image data \201which
presumably is retrieved by a separate call to FunImageGet\202 pixel by
pixel.

)0 P(If a FITS binary table or a non-FITS raw event file is being binned
into an image, it is necessary to specify the two columns that will be
used in the 2D binning.  This usually is done on the command line
using the )BD(bincols=\201x,y\202)ES( keyword:
) 1 46 PR(  funcnts "foo.ev[EVENTS,bincols=\201detx,dety\202]")RP(

)0 P(The full form of the )BD(bincols=)ES( specifier is:
) 1 77 PR(  bincols=\201[xname[:tlmin[:tlmax:[binsiz]]]],[yname[:tlmin[:tlmax[:binsiz]]]]\202)RP(
where the tlmin, tlmax, and binsiz specifiers determine the image binning
dimensions:
) 2 56 PR(  dim = \201tlmax - tlmin\202/binsiz     \201floating point data\202
  dim = \201tlmax - tlmin\202/binsiz + 1 \201integer data\202)RP(
These tlmin, tlmax, and binsiz specifiers can be omitted if TLMIN,
TLMAX, and TDBIN header parameters \201respectively\202 are present in the
FITS binary table header for the column in question.  Note that if
only one parameter is specified, it is assumed to be tlmax, and tlmin
defaults to 1. If two parameters are specified, they are assumed to be
tlmin and tlmax.

)0 P(If )BD(bincols)ES( is not specified on the command line, Funtools tries
to use appropriate defaults: it looks for the environment variable
FITS_BINCOLS \201or FITS_BINKEY\202. Then it looks for the Chandra
parameters CPREF \201or PREFX\202 in the FITS binary table header. Failing
this, it looks for columns named "X" and "Y" and if these are not
found, it looks for columns containing the characters "X" and "Y".
)0 P(See )0 50 1 A(Binning FITS Binary Tables and
Non-FITS Event Files)50 0 TN TL()Ec /AF f D( for more information.




)0 2 35 H(FunImagePut)WB 101 Sn()WB 27 Sn( - put an image to a Funtools file)EA()EH(

)BD() 4 69 PR(  #include <funtools.h>

  int FunImagePut\201Fun fun, void *buf, int dim1, int dim2, int bitpix,
                  char *plist\202)RP()ES(


The )BD(FunImagePut\201\202)ES( routine outputs an image array to a FITS
file. The image is written either as a primary header/data unit or as
an image extension, depending on whether other data have already been
written to the file.  That is, if the current file position is at the
beginning of the file, a primary HDU is written. Otherwise, an
image extension is written.

)0 P(The first argument is the Funtools handle returned by 
)0 25 1 A(FunOpen\201\202)25 0 TN TL()Ec /AF f D(.  The second )BD(buf)ES(
argument is a pointer to a data buffer to write.  The )BD(dim1)ES(and
)BD(dim2)ES( arguments that follow specify the dimensions of the image,
where dim1 corresponds to naxis1 and dim2 corresponds to naxis2.  The
)BD(bitpix)ES( argument specifies the data type of the image and can
have the following FITS-standard values:
)UL()-1 LI( 8 unsigned char
)-1 LI( 16 short
)-1 LI( 32 int
)-1 LI( -32 float
)-1 LI( -64 double)LU(

)0 P(When )0 31 1 A(FunTableRowPut\201\202)31 0 TN TL()Ec /AF f D( is first
called for a given image, Funtools checks to see if the primary header
has already been written \201by having previously written an image or a
binary table.\202 If not, this image is written to the primary HDU.
Otherwise, it is written to an image extension.
)0 P(Thus, a simple program to generate a FITS image might look like this:
) 16 67 PR(  int i;
  int dim1=512, dim2=512;
  double *dbuf;
  Fun fun;
  dbuf = malloc\201dim1*dim2*sizeof\201double\202\202;
  /* open the output FITS image, preparing to copy input params */
  if\201 !\201fun = FunOpen\201argv[1], "w", NULL\202\202 \202
    gerror\201stderr, "could not FunOpen output file: %s\200n", argv[1]\202;
  for\201i=0; i<\201dim1*dim2\202; i++\202{
    ... fill dbuf ...
  }
  /* put the image \201header will be generated automatically */
  if\201 !FunImagePut\201fun, buf, dim1, dim2, -64, NULL\202 \202
    gerror\201stderr, "could not FunImagePut: %s\200n", argv[1]\202;
  FunClose\201fun\202;
  free\201dbuf\202;)RP(

)0 P(In addition, if a
)0 23 1 A(Funtools reference handle)23 0 TN TL()Ec /AF f D(
was specified when this table was opened, the
parameters from this
)0 23 1 A(Funtools reference handle)23 0 TN TL()Ec /AF f D(
are merged into the new image
header.  Furthermore, if a reference image was specified during 
)0 25 1 A(FunOpen\201\202)25 0 TN TL()Ec /AF f D(, the values of
)BD(dim1)ES(, )BD(dim2)ES(, and )BD(bitpix)ES( in the calling sequence
can all be set to 0.  In this case, default values are taken from the
reference image section.  This is useful if you are reading an image
section in its native data format, processing it, and then writing
that section to a new FITS file.  See the 
)0 2 A(imblank example code)EA(.

)0 P(The data are assumed to be in the native machine format and will
automatically be swapped to FITS big-endian format if necessary.  This
behavior can be over-ridden with the )BD(convert=[true|false])ES(
keyword in the )BD(plist)ES( param list string.

)0 P(When you are finished writing the image, you should call 
)0 39 1 A(FunFlush\201\202)39 0 TN TL()Ec /AF f D( to write out the FITS
image padding. However, this is not necessary if you subsequently call
FunClose\201\202 without doing any other I/O to the FITS file.




)0 2 36 H(FunImageRowGet)WB 102 Sn()WB 28 Sn( - get row\201s\202 of an image)EA()EH(


)BD() 4 65 PR(  #include <funtools.h>

  void *FunImageRowGet\201Fun fun, void *buf, int rstart, int rstop,
                       char *plist\202)RP()ES(


)0 P(The )BD(FunImageRowGet\201\202)ES( routine returns one or more image rows
from the specified section of a Funtools data file.  If the input data
are of type image, the array is generated by extracting the specified
image rows and then binning them according to the specified bin
factor.  If the input data are contained in a binary table or raw
event file, the rows are binned on the columns specified by the
)BD(bincols=)ES( keyword \201using appropriate default columns as needed\202,
after which the image section and bin factors are applied.

)0 P(The first argument is the Funtools handle returned by 
)0 25 1 A(FunOpen\201\202)25 0 TN TL()Ec /AF f D(.  The second )BD(buf)ES(
argument is a pointer to a data buffer to fill. If NULL is specified,
FunImageGet\201\202 will allocate a buffer of the appropriate size.

)0 P(The third and fourth arguments specify the first and last row to
retrieve.  Rows are counted starting from 1, up to the value of
FUN_YMAX\201fun\202.  The final )BD(plist)ES( \201i.e., parameter list\202 argument
is a string containing one or more comma-delimited
)BD(keyword=value)ES( parameters.  It can be used to specify the return
data type using the )BD(bitpix=)ES( keyword.  If no such keyword is
specified in the plist string, the data type of the image is the same
as the data type of the original input file, or is of type int for
FITS binary tables.

)0 P(If the )BD(bitpix=)ES(value is supplied in the plist string, the data
type of the returned image will be one of the supported FITS image
data types:
)UL()-1 LI( 8 unsigned char
)-1 LI( 16 short
)-1 LI( 32 int
)-1 LI( -32 float
)-1 LI( -64 double)LU(

)0 P(For example:
) 17 65 PR(  double *drow;
  Fun fun;
  ... open files ...
  /* get section dimensions */
  FunInfoGet\201fun, FUN_SECT_DIM1, &dim1, FUN_SECT_DIM2, &dim2, 0\202;
  /* allocate one line's worth */
  drow = malloc\201dim1*sizeof\201double\202\202;
  /* retrieve and process each input row \201starting at 1\202 */
  for\201i=1; i <= dim2; i++\202{
    if\201 !FunImageRowGet\201fun, drow, i, i, "bitpix=-64"\202 \202
      gerror\201stderr, "can't FunImageRowGet: %d %s\200n", i, iname\202;
      /* reverse the line */
      for\201j=1; j<=dim1; j++\202{
        ... process drow[j-1] ...
      }
  }
  ...)RP(

)0 P(On success, a pointer to the image buffer is returned. \201This will be
the same as the second argument, if NULL is not passed to the latter.\202
On error, NULL is returned.  Note that the considerations described
above for specifying binning columns in 
)0 26 1 A(FunImageGet\201\202)26 0 TN TL()Ec /AF f D( also apply to
)BD(FunImageRowGet\201\202)ES(.




)0 2 37 H(FunImageRowPut)WB 103 Sn()WB 29 Sn( - put row\201s\202 of an image)EA()EH(


)BD() 4 67 PR(  #include <funtools.h>

  void *FunImageRowPut\201Fun fun, void *buf, int rstart, int rstop,
                       int dim1, int dim2, int bitpix, char *plist\202)RP()ES(


)0 P(The )BD(FunImageRowPut\201\202)ES( routine writes one or more image rows to
the specified FITS image file.  The first argument is the Funtools
handle returned by )0 25 1 A(FunOpen\201\202)25 0 TN TL()Ec /AF f D(.
The second )BD(buf)ES( argument is a pointer to the row data buffer,
while the third and fourth arguments specify the starting and ending
rows to write.  Valid rows values range from 1 to dim2, i.e., row is
one-valued.

)0 P(The )BD(dim1)ES(and )BD(dim2)ES( arguments that follow specify the
dimensions, where dim1 corresponds to naxis1 and dim2 corresponds to
naxis2.  The )BD(bitpix)ES( argument data type of the image and can
have the following FITS-standard values:
)UL()-1 LI( 8 unsigned char
)-1 LI( 16 short
)-1 LI( 32 int
)-1 LI( -32 float
)-1 LI( -64 double)LU(

For example:
) 16 65 PR(  double *drow;
  Fun fun, fun2;
  ... open files ...
  /* get section dimensions */
  FunInfoGet\201fun, FUN_SECT_DIM1, &dim1, FUN_SECT_DIM2, &dim2, 0\202;
  /* allocate one line's worth */
  drow = malloc\201dim1*sizeof\201double\202\202;
  /* retrieve and process each input row \201starting at 1\202 */
  for\201i=1; i <= dim2; i++\202{
    if\201 !FunImageRowGet\201fun, drow, i, i, "bitpix=-64"\202 \202
      gerror\201stderr, "can't FunImageRowGet: %d %s\200n", i, iname\202;
    ... process drow ...
    if\201 !FunImageRowPut\201fun2, drow, i, i, 64, NULL\202 \202
      gerror\201stderr, "can't FunImageRowPut: %d %s\200n", i, oname\202;
  }
  ...)RP(

)0 P(The data are assumed to be in the native machine format and will
automatically be swapped to big-endian FITS format if necessary.  This
behavior can be over-ridden with the )BD(convert=[true|false])ES(
keyword in the )BD(plist)ES( param list string.

)0 P(When you are finished writing the image, you should call 
)0 39 1 A(FunFlush\201\202)39 0 TN TL()Ec /AF f D( to write out the FITS
image padding. However, this is not necessary if you subsequently call
FunClose\201\202 without doing any other I/O to the FITS file.




)0 2 38 H(FunColumnSelect)WB 104 Sn()WB 32 Sn( - select Funtools columns)EA()EH(

)BD() 11 73 PR(  #include <funtools.h>

  int FunColumnSelect\201Fun fun, int size, char *plist, 
                      char *name1, char *type1, char *mode1, int offset1,
                      char *name2, char *type2, char *mode2, int offset2,
                      ...,
                      NULL\202

  int FunColumnSelectArr\201Fun fun, int size, char *plist, 
                         char **names, char **types, char **modes,
                         int *offsets, int nargs\202;)RP()ES(


The )BD(FunColumnSelect\201\202)ES( routine is used to select the columns
from a Funtools binary table extension or raw event file for
processing. This routine allows you to specify how columns in a file
are to be read into a user record structure or written from a user
record structure to an output FITS file.

)0 P(The first argument is the Fun handle associated with this set of
columns. The second argument specifies the size of the user record
structure into which columns will be read.  Typically, the sizeof\201\202
macro is used to specify the size of a record structure.  The third
argument allows you to specify keyword directives for the selection
and is described in more detail below.

)0 P(Following the first three required arguments is a variable length list of
column specifications.  Each column specification will consist of four
arguments:
)UL()-1 LI( )BD(name)ES(: the name of the column

)-1 LI( )BD(type)ES(: the data type of the column as it will be stored in
the user record struct \201not the data type of the input file\202. The
following basic data types are recognized:
)UL()-1 LI(A: ASCII characters
)-1 LI(B: unsigned 8-bit char
)-1 LI(I: signed 16-bit int
)-1 LI(U: unsigned 16-bit int \201not standard FITS\202
)-1 LI(J: signed 32-bit int
)-1 LI(V: unsigned 32-bit int \201not standard FITS\202
)-1 LI(E: 32-bit float
)-1 LI(D: 64-bit float)LU(
The syntax used is similar to that which defines the TFORM parameter
in FITS binary tables. That is, a numeric repeat value can precede
the type character, so that "10I" means a vector of 10 short ints, "E"
means a single precision float, etc.  Note that the column value from
the input file will be converted to the specified data type as the
data is read by
)0 30 1 A(FunTableRowGet\201\202)30 0 TN TL()Ec /AF f D(.

)0 P([ A short digression regarding bit-fields: Special attention is
required when reading or writing the FITS bit-field type
\201"X"\202. Bit-fields almost always have a numeric repeat character
preceding the 'X' specification. Usually this value is a multiple of 8
so that bit-fields fit into an integral number of bytes. For all
cases, the byte size of the bit-field B is \201N+7\202/8, where N is the
numeric repeat character.

)0 P(A bit-field is most easily declared in the user struct as an array of
type char of size B as defined above. In this case, bytes are simply
moved from the file to the user space.  If, instead, a short or int
scalar or array is used, then the algorithm for reading the bit-field
into the user space depends on the size of the data type used along
with the value of the repeat character.  That is, if the user data
size is equal to the byte size of the bit-field, then the data is
simply moved \201possibly with endian-based byte-swapping\202 from one to
the other. If, on the other hand, the data storage is larger than the
bit-field size, then a data type cast conversion is performed to move
parts of the bit-field into elements of the array.  Examples will help
make this clear:

)UL()-1 LI( If the file contains a 16X bit-field and user space specifies a 2B
char array[2], then the bit-field is moved directly into the char array.

)-1 LI( If the file contains a 16X bit-field and user space specifies a 1I
scalar short int, then the bit-field is moved directly into the short int.

)-1 LI( If the file contains a 16X bit-field and user space specifies a 1J
scalar int, then the bit-field is type-cast to unsigned int before
being moved \201use of unsigned avoids possible sign extension\202.

)-1 LI( If the file contains a 16X bit-field and user space specifies a 2J
int array[2], then the bit-field is handled as 2 chars, each of which
are type-cast to unsigned int before being moved \201use of unsigned
avoids possible sign extension\202.

)-1 LI( If the file contains a 16X bit-field and user space specifies a 1B
char, then the bit-field is treated as a char, i.e., truncation will
occur.

)-1 LI( If the file contains a 16X bit-field and user space specifies a 4J
int array[4], then the results are undetermined.
)LU(
For all user data types larger than char, the bit-field is byte-swapped
as necessary to convert to native format, so that bits in the
resulting data in user space can be tested, masked, etc. in the same
way regardless of platform.]

)0 P(In addition to setting data type and size, the )BD(type)ES(
specification allows a few ancillary parameters to be set, using the
full syntax for )BD(type)ES(:
) 1 53 PR( [@][n]<type>[[['B']poff]][:[tlmin[:tlmax[:binsiz]]]])RP(

)0 P(The special character "@" can be prepended to this specification to
indicated that the data element is a pointer in the user record,
rather than an array stored within the record.

)0 P(The [n] value is an integer that specifies the
number of elements that are in this column \201default is 1\202. TLMIN,
TLMAX, and BINSIZ values also can be specified for this column after
the type, separated by colons. If only one such number is specified,
it is assumed to be TLMAX, and TLMIN  and BINSIZ are set to 1.

)0 P(The [poff] value can be used to specify the offset into an
array. By default, this offset value is set to zero and the data
specified starts at the beginning of the array. The offset usually
is specified in terms of the data type of the column. Thus an offset
specification of [5] means a 20-byte offset if the data type is a
32-bit integer, and a 40-byte offset for a double. If you want to
specify a byte offset instead of an offset tied to the column data type,
precede the offset value with 'B', e.g. [B6] means a 6-bye offset,
regardless of the column data type.

The [poff] is especially useful in conjunction with the pointer @
specification, since it allows the data element to anywhere stored
anywhere in the allocated array.  For example, a specification such as
"@I[2]" specifies the third \201i.e., starting from 0\202 element in the
array pointed to by the pointer value. A value of "@2I[4]" specifies
the fifth and sixth values in the array. For example, consider the
following specification: ) 12 67 PR(  typedef struct EvStruct{
    short x[4], *atp;
  } *Event, EventRec;
  /* set up the \201hardwired\202 columns */
  FunColumnSelect\201 fun, sizeof\201EventRec\202, NULL,
                   "2i",    "2I  ",    "w", FUN_OFFSET\201Event, x\202,
                   "2i2",   "2I[2]",   "w", FUN_OFFSET\201Event, x\202,
                   "at2p",  "@2I",     "w", FUN_OFFSET\201Event, atp\202,
                   "at2p4", "@2I[4]",  "w", FUN_OFFSET\201Event, atp\202,
                   "atp9",  "@I[9]",   "w", FUN_OFFSET\201Event, atp\202,
                   "atb20", "@I[B20]", "w", FUN_OFFSET\201Event, atb\202,
                   NULL\202;)RP(
Here we have specified the following columns:
)UL()-1 LI( 2i: two short ints in an array which is stored as part the
record
)-1 LI( 2i2: the 3rd and 4th elements of an array which is stored
as part of the record
)-1 LI( an array of at least 10 elements, not stored in the record but
allocated elsewhere, and used by three different columns:
)UL()-1 LI( at2p: 2 short ints which are the first 2 elements of the allocated array
)-1 LI( at2p4: 2 short ints which are the 5th and 6th elements of 
the allocated array
)-1 LI( atp9: a short int which is the 10th element of the allocated array)LU(
)-1 LI( atb20: a short int which is at byte offset 20 of another allocated array)LU(
In this way, several columns can be specified, all of which are in a
single array. )BD(NB)ES(: it is the programmer's responsibility to
ensure that specification of a positive value for poff does not point
past the end of valid data.

)-1 LI( )BD(read/write mode)ES(: "r" means that the column is read from an
input file into user space by 
)0 30 1 A(FunTableRowGet\201\202)30 0 TN TL()Ec /AF f D(, "w" means that
the column is written to an output file. Both can specified  at the same
time.

)-1 LI( )BD(offset)ES(: the offset into the user data to store
this column. Typically, the macro FUN_OFFSET\201recname, colname\202 is used
to define the offset into a record structure.)LU(

)0 P(When all column arguments have been specified, a final NULL argument
must added to signal the column selection list.

)0 P(As an alternative to the varargs
)0 32 1 A(FunColumnSelect\201\202)32 0 TN TL()Ec /AF f D(
routine, a non-varargs routine called
)0 32 1 A(FunColumnSelectArr\201\202)32 0 TN TL()Ec /AF f D(
also is available. The first three arguments \201fun, size, plist\202 of this
routine are the same as in
)0 32 1 A(FunColumnSelect\201\202)32 0 TN TL()Ec /AF f D(.
Instead of a variable
argument list, however,
)0 32 1 A(FunColumnSelectArr\201\202)32 0 TN TL()Ec /AF f D(
takes 5 additional arguments. The first 4 arrays arguments contain the
names, types, modes, and offsets, respectively, of the columns being
selected. The final argument is the number of columns that are
contained in these arrays. It is the user's responsibility to free
string space allocated in these arrays.

)0 P(Consider the following example:
) 12 54 PR(  typedef struct evstruct{
    int status;
    float pi, pha, *phas;
    double energy;
  } *Ev, EvRec;

  FunColumnSelect\201fun, sizeof\201EvRec\202, NULL,
    "status",  "J",     "r",   FUN_OFFSET\201Ev, status\202,
    "pi",      "E",     "r",  FUN_OFFSET\201Ev, pi\202,
    "pha",     "E",     "r",  FUN_OFFSET\201Ev, pha\202,
    "phas",    "@9E",   "r",  FUN_OFFSET\201Ev, phas\202,
    NULL\202;)RP(
)0 P(Each time a row is read into the Ev struct, the "status" column is
converted to an int data type \201regardless of its data type in the
file\202 and stored in the status value of the struct.  Similarly, "pi"
and "pha", and the phas vector are all stored as floats. Note that the
"@" sign indicates that the "phas" vector is a pointer to a 9 element
array, rather than an array allocated in the struct itself. The row
record can then be processed as required:
) 9 70 PR(  /* get rows -- let routine allocate the row array */
  while\201 \201ebuf = \201Ev\202FunTableRowGet\201fun, NULL, MAXROW, NULL, &got\202\202 \202{
    /* process all rows */
    for\201i=0; i<got; i++\202{
      /* point to the i'th row */
      ev = ebuf+i;
      ev->pi = \201ev->pi+.5\202;
      ev->pha = \201ev->pi-.5\202;
    })RP(

)0 P()0 32 1 A(FunColumnSelect\201\202)32 0 TN TL()Ec /AF f D(
can also be called to define "writable" columns in order to generate a FITS
Binary Table, without reference to any input columns.  For
example, the following will generate a 4-column FITS binary table when
)0 31 1 A(FunTableRowPut\201\202)31 0 TN TL()Ec /AF f D( is used to
write Ev records:

) 12 56 PR(  typedef struct evstruct{
    int status;
    float pi, pha
    double energy;
  } *Ev, EvRec;

  FunColumnSelect\201fun, sizeof\201EvRec\202, NULL,
    "status",  "J",     "w",   FUN_OFFSET\201Ev, status\202,
    "pi",      "E",     "w",   FUN_OFFSET\201Ev, pi\202,
    "pha",     "E",     "w",   FUN_OFFSET\201Ev, pha\202,
    "energy",  "D",       "w",   FUN_OFFSET\201Ev, energy\202,
    NULL\202;)RP(
All columns are declared to be write-only, so presumably the column
data is being generated or read from some other source.

)0 P(In addition, 
)0 32 1 A(FunColumnSelect\201\202)32 0 TN TL()Ec /AF f D(
can be called to define )BD(both)ES( "readable" and "writable" columns.
In this case, the "read" columns
are associated with an input file, while the "write" columns are
associated with the output file. Of course, columns can be specified as both
"readable" and "writable", in which case they are read from input
and \201possibly modified data values are\202 written to the output.
The 
)0 32 1 A(FunColumnSelect\201\202)32 0 TN TL()Ec /AF f D(
call itself is made by passing the input Funtools handle, and it is
assumed that the output file has been opened using this input handle
as its
)0 23 1 A(Funtools reference handle)23 0 TN TL()Ec /AF f D(.

)0 P(Consider the following example:
) 13 54 PR(  typedef struct evstruct{
    int status;
    float pi, pha, *phas;
    double energy;
  } *Ev, EvRec;

  FunColumnSelect\201fun, sizeof\201EvRec\202, NULL,
    "status",  "J",     "r",   FUN_OFFSET\201Ev, status\202,
    "pi",      "E",     "rw",  FUN_OFFSET\201Ev, pi\202,
    "pha",     "E",     "rw",  FUN_OFFSET\201Ev, pha\202,
    "phas",    "@9E",   "rw",  FUN_OFFSET\201Ev, phas\202,
    "energy",  "D",     "w",   FUN_OFFSET\201Ev, energy\202,
    NULL\202;)RP(
As in the "read" example above, each time an row is read into the Ev
struct, the "status" column is converted to an int data type
\201regardless of its data type in the file\202 and stored in the status
value of the struct.  Similarly, "pi" and "pha", and the phas vector
are all stored as floats.  Since the "pi", "pha", and "phas" variables
are declared as "writable" as well as "readable", they also will be
written to the output file.  Note, however, that the "status" variable
is declared as "readable" only, and hence it will not be written to
an output file.  Finally, the "energy" column is declared as
"writable" only, meaning it will not be read from the input file. In
this case, it can be assumed that "energy" will be calculated in the
program before being output along with the other values.

)0 P(In these simple cases, only the columns specified as "writable" will
be output using 
)0 31 1 A(FunTableRowPut\201\202)31 0 TN TL()Ec /AF f D(.  However,
it often is the case that you want to merge the user columns back in
with the input columns, even in cases where not all of the input
column names are explicitly read or even known. For this important
case, the )BD(merge=[type])ES( keyword is provided in the plist string.

)0 P(The )BD(merge=[type])ES( keyword tells Funtools to merge the columns from
the input file with user columns on output.  It is normally used when
an input and output file are opened and the input file provides the
)0 23 1 A(Funtools reference handle)23 0 TN TL()Ec /AF f D(
for the output file. In this case, each time 
)0 30 1 A(FunTableRowGet\201\202)30 0 TN TL()Ec /AF f D( is called, the
raw input rows are saved in a special buffer. If 
)0 31 1 A(FunTableRowPut\201\202)31 0 TN TL()Ec /AF f D( then is called
\201before another call to 
)0 30 1 A(FunTableRowGet\201\202)30 0 TN TL()Ec /AF f D(\202, the contents
of the raw input rows are merged with the user rows according to the
value of )BD(type)ES( as follows:

)UL()-1 LI( )BD(update)ES(: add new user columns, and update value of existing ones \201maintaining the input data type\202

)-1 LI( )BD(replace)ES(: add new user columns, and replace the data type
and value of existing ones.  \201Note that if tlmin/tlmax values are not
specified in the replacing column, but are specified in the original
column being replaced, then the original tlmin/tlmax values are used
in the replacing column.\202

)-1 LI( )BD(append)ES(: only add new columns, do not "replace" or "update" existing ones)LU(

)0 P(Consider the example above. If )BD(merge=update)ES( is specified in the
plist string, then "energy" will be added to the input columns, and
the values of "pi", "pha", and "phas" will be taken from the user
space \201i.e., the values will be updated from the original values, if
they were changed by the program\202.  The data type for "pi", "pha", and
"phas" will be the same as in the original file.  If
)BD(merge=replace)ES( is specified, both the data type and value of
these three input columns will be changed to the data type and value
in the user structure.  If )BD(merge=append)ES( is specified, none of
these three columns will be updated, and only the "energy" column will
be added. Note that in all cases, "status" will be written from the
input data, not from the user record, since it was specified as read-only.

)0 P(Standard applications will call 
)0 32 1 A(FunColumnSelect\201\202)32 0 TN TL()Ec /AF f D(
to define user columns. However, if this routine is not called, the
default behavior is to transfer all input columns into user space. For
this purpose a default record structure is defined such that each data
element is properly aligned on a valid data type boundary.  This
mechanism is used by programs such as fundisp and funtable to process
columns without needing to know the specific names of those columns.
It is not anticipated that users will need such capabilities \201contact
us if you do!\202

)0 P(By default, )0 32 1 A(FunColumnSelect\201\202)32 0 TN TL()Ec /AF f D(
reads/writes rows to/from an "array of structs", where each struct contains
the column values for a single row of the table. This means that the
returned values for a given column are not contiguous. You can
set up the IO to return a "struct of arrays" so that each of the
returned columns are contiguous by specifying )BD(org=structofarrays)ES(
\201abbreviation: )BD(org=soa)ES(\202 in the plist. 
\201The default case is )BD(org=arrayofstructs)ES( or )BD(org=aos)ES(.\202

)0 P(For example, the default setup to retrieve rows from a table would be
to define a record structure for a single event and then call
 )0 32 1 A(FunColumnSelect\201\202)32 0 TN TL()Ec /AF f D(
as follows:
) 14 73 PR(  typedef struct evstruct{
    short region;
    double x, y;
    int pi, pha;
    double time;
  } *Ev, EvRec;

  got = FunColumnSelect\201fun, sizeof\201EvRec\202, NULL,
                        "x",       "D:10:10", mode, FUN_OFFSET\201Ev, x\202,
                        "y",       "D:10:10", mode, FUN_OFFSET\201Ev, y\202,
                        "pi",      "J",       mode, FUN_OFFSET\201Ev, pi\202,
                        "pha",     "J",       mode, FUN_OFFSET\201Ev, pha\202,
                        "time",    "1D",      mode, FUN_OFFSET\201Ev, time\202,
                        NULL\202;)RP(
Subsequently, each call to
FunTableRowGet\201\202)EA(
will return an array of structs, one for each returned row. If instead you
wanted to read columns into contiguous arrays, you specify )BD(org=soa)ES(:
) 14 72 PR(  typedef struct aevstruct{
    short region[MAXROW];
    double x[MAXROW], y[MAXROW];
    int pi[MAXROW], pha[MAXROW];
    double time[MAXROW];
  } *AEv, AEvRec;

  got = FunColumnSelect\201fun, sizeof\201AEvRec\202, "org=soa",
                      "x",       "D:10:10", mode, FUN_OFFSET\201AEv, x\202,
                      "y",       "D:10:10", mode, FUN_OFFSET\201AEv, y\202,
                      "pi",      "J",       mode, FUN_OFFSET\201AEv, pi\202,
                      "pha",     "J",       mode, FUN_OFFSET\201AEv, pha\202,
                      "time",    "1D",      mode, FUN_OFFSET\201AEv, time\202,
                      NULL\202;)RP(
Note that the only modification to the call is in the plist string.

)0 P(Of course, instead of using staticly allocated arrays, you also can specify
dynamically allocated pointers:
) 16 75 PR(  /* pointers to arrays of columns \201used in struct of arrays\202 */
  typedef struct pevstruct{
    short *region;
    double *x, *y;
    int *pi, *pha;
    double *time;
  } *PEv, PEvRec;

  got = FunColumnSelect\201fun, sizeof\201PEvRec\202, "org=structofarrays",
                      "$region", "@I",       mode, FUN_OFFSET\201PEv, region\202,
                      "x",       "@D:10:10", mode, FUN_OFFSET\201PEv, x\202,
                      "y",       "@D:10:10", mode, FUN_OFFSET\201PEv, y\202,
                      "pi",      "@J",       mode, FUN_OFFSET\201PEv, pi\202,
                      "pha",     "@J",       mode, FUN_OFFSET\201PEv, pha\202,
                      "time",    "@1D",      mode, FUN_OFFSET\201PEv, time\202,
                      NULL\202;)RP(
Here, the actual storage space is either allocated by the user or by the 
)0 32 1 A(FunColumnSelect\201\202)32 0 TN TL()Ec /AF f D( call\202.

)0 P(In all of the above cases, the same call is made to retrieve rows, e.g.:
) 1 64 PR(    buf = \201void *\202FunTableRowGet\201fun, NULL, MAXROW, NULL, &got\202;)RP(
However, the individual data elements are accessed differently.
For the default case of an "array of structs", the
individual row records are accessed using:
) 5 69 PR(  for\201i=0; i<got; i++\202{
    ev = \201Ev\202buf+i;
    fprintf\201stdout, "%.2f\200t%.2f\200t%d\200t%d\200t%.4f\200t%.4f\200t%21.8f\200n",
            ev->x, ev->y, ev->pi, ev->pha, ev->dx, ev->dy, ev->time\202;
  })RP(
For a struct of arrays or a struct of array pointers, we have a single struct
through which we access individual columns and rows using:
) 6 63 PR(  aev = \201AEv\202buf;
  for\201i=0; i<got; i++\202{
    fprintf\201stdout, "%.2f\200t%.2f\200t%d\200t%d\200t%.4f\200t%.4f\200t%21.8f\200n",
            aev->x[i], aev->y[i], aev->pi[i], aev->pha[i], 
            aev->dx[i], aev->dy[i], aev->time[i]\202;
  })RP(
Support for struct of arrays in the 
)0 31 1 A(FunTableRowPut\201\202)31 0 TN TL()Ec /AF f D(
call is handled analogously.

)0 P(See the )0 2 A(evread example code)EA(
and
)0 2 A(evmerge example code)EA(
for working examples of how 
)0 32 1 A(FunColumnSelect\201\202)32 0 TN TL()Ec /AF f D( is used.




)0 2 39 H(FunColumnActivate)WB 105 Sn()WB 33 Sn( - activate Funtools columns)EA()EH(


)BD() 3 55 PR(  #include <funtools.h>

  void FunColumnActivate\201Fun fun, char *s, char *plist\202)RP()ES(


)0 P(The )BD(FunColumnActivate\201\202)ES( routine determines which columns \201set up
by )0 32 1 A(FunColumnSelect\201\202)32 0 TN TL()Ec /AF f D(\202
ultimately will be read and/or written.  By default, all columns that
are selected using 
)0 32 1 A(FunColumnSelect\201\202)32 0 TN TL()Ec /AF f D(
are activated.  The 
)0 33 1 A(FunColumnActivate\201\202)33 0 TN TL()Ec /AF f D(
routine can be used to turn off/off activation of specific columns.

)0 P(The first argument is the Fun handle associated with this set of
columns.  The second argument is a space-delimited list of columns to
activate or de-activate. Columns preceded by "+" are activated and
columns preceded by a "-" are de-activated. If a column is named
without "+" or "-", it is activated. The reserved strings "$region"
and '$n' are used to activate a special columns containing the filter
region value and row value, respectively, associated with
this row. For example, if a filter containing two circular regions is
specified as part of the Funtools file name, this column will contain
a value of 1 or 2, depending on which region that row was in. The
reserved strings "$x" and "$y" are used to activate the current
binning columns. Thus, if the columns DX and DY are specified as
binning columns:
) 1 42 PR(  [sh $] fundisp foo.fits[bincols=\201DX,DY\202])RP(
then "$x" and "$y" will refer to these columns in a call to
)0 33 1 A(FunColumnActivate\201\202)33 0 TN TL()Ec /AF f D(.

)0 P(In addition, if the activation string contains only columns to be
activated, then the routine will de-activate all other columns.
Similarly, if the activation string contains only
columns to de-activate, then the routine will activate all other columns
before activating the list.  This makes it simple to change the
activation state of all columns without having to know all of the
column names. For example:
)UL()-1 LI( )BD("pi pha time")ES(     # only these three columns will be active
)-1 LI( )BD("-pi -pha -time")ES(  # all but these columns will be active
)-1 LI( )BD("pi -pha")ES(         # only pi is active, pha is not, others are not
)-1 LI( )BD("+pi -pha")ES(        # same as above
)-1 LI( )BD("pi -pha -time")ES(   # only pi is active, all others are not
)-1 LI( )BD("pi pha")ES(          # pha and pi are active, all others are not
)-1 LI( )BD("pi pha -x -y")ES(    # pha and pi are active, all others are not)LU(

)0 P(You can use the column activation list to reorder columns, since
columns are output in the order specified. For example:
) 19 77 PR(  # default output order
  fundisp snr.ev'[cir 512 512 .1]' 
         X        Y      PHA       PI                  TIME       DX       DY
  -------- -------- -------- -------- --------------------- -------- --------
       512      512        6        7     79493997.45854475      578      574
       512      512        8        9     79494575.58943175      579      573
       512      512        5        6     79493631.03866175      578      575
       512      512        5        5     79493290.86521725      578      575
       512      512        8        9     79493432.00990875      579      573

  # re-order the output by specifying explicit order
  fundisp snr.ev'[cir 512 512 .1]' "time x y dy dx pi pha"
                   TIME        X        Y       DY       DX       PI      PHA
  --------------------- -------- -------- -------- -------- -------- --------
      79493997.45854475      512      512      574      578        7        6
      79494575.58943175      512      512      573      579        9        8
      79493631.03866175      512      512      575      578        6        5
      79493290.86521725      512      512      575      578        5        5
      79493432.00990875      512      512      573      579        9        8)RP(

)0 P(A "+" sign by itself means to activate all columns, so that you can reorder
just a few columns without specifying all of them:
) 9 77 PR(  # reorder 3 columns and then output the rest
  fundisp snr.ev'[cir 512 512 .1]' "time pi pha +"
                   TIME       PI      PHA        Y        X       DX       DY
  --------------------- -------- -------- -------- -------- -------- --------
      79493997.45854475        7        6      512      512      578      574
      79494575.58943175        9        8      512      512      579      573
      79493631.03866175        6        5      512      512      578      575
      79493290.86521725        5        5      512      512      578      575
      79493432.00990875        9        8      512      512      579      573)RP(
The column activation/deactivation is performed in the order of the
specified column arguments. This means you can mix "+", "-" \201which
de-activates all columns\202 and specific column names to reorder and
select columns in one command. For example, consider the following:
) 9 59 PR(  # reorder and de-activate
  fundisp snr.ev'[cir 512 512 .1]' "time pi pha + -x -y"
                   TIME       PI      PHA       DX       DY
  --------------------- -------- -------- -------- --------
      79493997.45854475        7        6      578      574
      79494575.58943175        9        8      579      573
      79493631.03866175        6        5      578      575
      79493290.86521725        5        5      578      575
      79493432.00990875        9        8      579      573)RP(
We first activate "time", "pi", and "pha" so that they are output first.
We then activate all of the other columns, and then de-activate "x" and "y".
Note that this is different from:
) 9 77 PR(  # probably not what you want ...
  fundisp snr.ev'[cir 512 512 .1]' "time pi pha -x -y +"
                   TIME       PI      PHA        Y        X       DX       DY
  --------------------- -------- -------- -------- -------- -------- --------
      79493997.45854475        7        6      512      512      578      574
      79494575.58943175        9        8      512      512      579      573
      79493631.03866175        6        5      512      512      578      575
      79493290.86521725        5        5      512      512      578      575
      79493432.00990875        9        8      512      512      579      573)RP(
Here, "x" and "y" are de-activated, but then all columns including "x" and
"y" are again re-activated.

)0 P(Typically, 
)0 33 1 A(FunColumnActivate\201\202)33 0 TN TL()Ec /AF f D( uses a
list of columns that are passed into the program from the command line.  For
example, the code for funtable contains the following:
) 9 66 PR(  char *cols=NULL;

  /* open the input FITS file */
  if\201 !\201fun = FunOpen\201argv[1], "rc", NULL\202\202 \202
    gerror\201stderr, "could not FunOpen input file: %s\200n", argv[1]\202;

  /* set active flag for specified columns */
  if\201 argc >= 4 \202 cols = argv[3];
  FunColumnActivate\201fun, cols, NULL\202;)RP(

The )0 25 1 A(FunOpen\201\202)25 0 TN TL()Ec /AF f D( call sets the
default columns to be all columns in the input file. The 
)0 33 1 A(FunColumnActivate\201\202)33 0 TN TL()Ec /AF f D( call
then allows the user to control which columns ultimately will be
activated \201i.e., in this case, written to the new file\202.  For example:
) 1 39 PR(  funtable test.ev foo.ev "pi pha time")RP(
will process only the three columns mentioned, while:
) 1 33 PR(  funtable test.ev foo.ev "-time")RP(
will process all columns except "time".

)0 P(If )0 33 1 A(FunColumnActivate\201\202)33 0 TN TL()Ec /AF f D(
is called with a null string, then the environment variable
)BD(FUN_COLUMNS)ES( will be used to provide a global value, if present.
This is the reason why we call the routine even if no columns
are specified on the command line \201see example above\202, instead
of calling it this way:
) 4 45 PR(  /* set active flag for specified columns */
  if\201 argc >= 4 \202{
    FunColumnActivate\201fun, argv[3], NULL\202;
  })RP(




)0 2 40 H(FunColumnLookup)WB 106 Sn()WB 34 Sn( - lookup a Funtools column)EA()EH(

)BD() 5 56 PR(  #include <funtools.h>

  int FunColumnLookup\201Fun fun, char *s, int which,
                      char **name, int *type, int *mode,
                      int *offset, int *n, int *width\202)RP()ES(


)0 P(The )BD(FunColumnLookup\201\202)ES( routine returns information about a named
\201or indexed\202 column.  The first argument is the Fun handle associated
with this set of columns. The second argument is the name of the
column to look up.  If the name argument is NULL, the argument that
follows is the zero-based index into the column array of the column
for which information should be returned.  The next argument is a
pointer to a char *, which will contain the name of the column. The
arguments that follow are the addresses of int values into which
the following information will be returned:
)UL()-1 LI( )BD(type)ES(: data type of column:
)UL()-1 LI(A: ASCII characters
)-1 LI(B: unsigned 8-bit char
)-1 LI(I: signed 16-bit int
)-1 LI(U: unsigned 16-bit int \201not standard FITS\202
)-1 LI(J: signed 32-bit int
)-1 LI(V: unsigned 32-bit int \201not standard FITS\202
)-1 LI(E: 32-bit float
)-1 LI(D: 64-bit float)LU(
)-1 LI( )BD(mode)ES(: bit flag status of column, including:
)UL()-1 LI( COL_ACTIVE      1 is column activated?
)-1 LI( COL_IBUF        2 is column in the raw input data?
)-1 LI( COL_PTR         4 is column a pointer to an array?
)-1 LI( COL_READ      010 is read mode selected?
)-1 LI( COL_WRITE     020 is write mode selected?
)-1 LI( COL_REPLACEME 040 is this column being replaced by user data?)LU(
)-1 LI( )BD(offset)ES(: byte offset in struct
)-1 LI( )BD(n)ES(: number of elements \201i.e. size of vector\202 in this column
)-1 LI( )BD(width)ES(: size in bytes of this column)LU(
If the named column exists, the routine returns a positive integer,
otherwise zero is returned. \201The positive integer is the index+1 into
the column array where this column was located.\202

If NULL is passed as the return address of one \201or more\202 of these
values, no data is passed back for that information.  For
example:
) 2 76 PR(  if\201 !FunColumnLookup\201fun, "phas", 0, NULL NULL, NULL, NULL, &npha, NULL\202 \202
    gerror\201stderr, "can't find phas column\200n"\202;)RP(
only returns information about the size of the phas vector.




)0 2 41 H(FunTableRowGet)WB 107 Sn()WB 30 Sn( - get Funtools rows)EA()EH(


)BD() 4 68 PR(  #include <funtools.h>

  void *FunTableRowGet\201Fun fun, void *rows, int maxrow, char *plist,
                       int *nrow\202)RP()ES(


)0 P(The )BD(FunTableRowGet\201\202)ES( routine retrieves rows from a Funtools
binary table or raw event file, and places the values of columns
selected by )0 32 1 A(FunColumnSelect\201\202)32 0 TN TL()Ec /AF f D(
into an array of user structs.  Selected column values are
automatically converted to the specified user data type \201and to native
data format\202 as necessary.

)0 P(The first argument is the Fun handle associated with this row data.
The second )BD(rows)ES( argument is the array of user structs into
which the selected columns will be stored. If NULL is passed, the
routine will automatically allocate space for this array. \201This
includes proper allocation of pointers within each struct, if the "@"
pointer type is used in the selection of columns.  Note that if you
pass NULL in the second argument, you should free this space using the
standard free\201\202 system call when you are finished with the array of
rows.\202  The third )BD(maxrow)ES( argument specifies the maximum number
of rows to be returned. Thus, if )BD(rows)ES( is allocated by the
user, it should be at least of size maxrow*sizeof\201evstruct\202.  

)0 P(The fourth )BD(plist)ES( argument is a param list string.  Currently,
the keyword/value pair "mask=transparent" is supported in the plist
argument.  If this string is passed in the call's plist argument, then
all rows are passed back to the user \201instead of just rows passing
the filter\202. This is only useful when 
)0 32 1 A(FunColumnSelect\201\202)32 0 TN TL()Ec /AF f D( also is
used to specify "$region" as a column to return for each row.  In
such a case, rows found within a region have a returned region value
greater than 0 \201corresponding to the region id of the region in which
they are located\202, rows passing the filter but not in a region have
region value of -1, and rows not passing any filter have region
value of 0. Thus, using "mask=transparent" and the returned region
value, a program can process all rows and decide on an action based
on whether a given row passed the filter or not.

)0 P(The final argument is a pointer to an int variable that will return
the actual number of rows returned.  The routine returns a pointer to
the array of stored rows, or NULL if there was an error. \201This pointer
will be the same as the second argument, if the latter is non-NULL\202.
) 16 69 PR(  /* get rows -- let routine allocate the row array */
  while\201 \201buf = \201Ev\202FunTableRowGet\201fun, NULL, MAXROW, NULL, &got\202\202 \202{
    /* process all rows */
    for\201i=0; i<got; i++\202{
      /* point to the i'th row */
      ev = buf+i;
      /* rearrange some values. etc. */
      ev->energy = \201ev->pi+ev->pha\202/2.0;
      ev->pha = -ev->pha;
      ev->pi = -ev->pi;
    }
    /* write out this batch of rows */
    FunTableRowPut\201fun2, buf, got, 0, NULL\202;
    /* free row data */
    if\201 buf \202 free\201buf\202;
  })RP(
As shown above, successive calls to 
)0 30 1 A(FunTableRowGet\201\202)30 0 TN TL()Ec /AF f D( will return the
next set of rows from the input file until all rows have been read,
i.e., the routine behaves like sequential Unix I/O calls such as
fread\201\202. See )0 2 A(evmerge example code)EA( for a
more complete example.

)0 P(Note that FunTableRowGet\201\202 also can be called as FunEventsGet\201\202, for
backward compatibility.




)0 2 42 H(FunTableRowPut)WB 108 Sn()WB 31 Sn( - put Funtools rows)EA()EH(


) 1 70 PR()BD(int FunTableRowPut\201Fun fun, void *rows, int nev, int idx, char *plist\202)ES()RP(


The )BD(FunTableRowPut\201\202)ES( routine writes rows to a FITS binary
table, taking its input from an array of user structs that contain
column values selected by a previous call to 
)0 32 1 A(FunColumnSelect\201\202)32 0 TN TL()Ec /AF f D(.  Selected
column values are automatically converted from native data format to
FITS data format as necessary.

)0 P(The first argument is the Fun handle associated with this row data.
The second )BD(rows)ES( argument is the array of user structs to
output. The third )BD(nrow)ES( argument specifies the number number of
rows to write.  The routine will write )BD(nrow)ES( records, starting
from the location specified by )BD(rows)ES(.

)0 P(The fourth )BD(idx)ES( argument is the index of the first raw input
row to write, in the case where rows from the user buffer are
being merged with their raw input row counterparts \201see below\202. Note
that this )BD(idx)ES( value is has nothing to do with the
row buffer specified in argument 1.  It merely matches the row
being written with its corresponding \201hidden\202 raw row.  Thus, if you
read a number of rows, process them, and then write them out all at
once starting from the first user row, the value of )BD(idx)ES(
should be 0:
) 14 70 PR(  Ev ebuf, ev;
  /* get rows -- let routine allocate the row array */
  while\201 \201ebuf = \201Ev\202FunTableRowGet\201fun, NULL, MAXROW, NULL, &got\202\202 \202{
    /* process all rows */
    for\201i=0; i<got; i++\202{
      /* point to the i'th row */
      ev = ebuf+i;
      ...
    }
    /* write out this batch of rows, starting with the first */
    FunTableRowPut\201fun2, \201char *\202ebuf, got, 0, NULL\202;
    /* free row data */
    if\201 ebuf \202 free\201ebuf\202;
  })RP(

)0 P(On the other hand, if you write out the rows one at a time \201possibly
skipping rows\202, then, when writing the i'th row from the input
array of rows, set )BD(idx)ES( to the value of i:
) 14 70 PR(  Ev ebuf, ev;
  /* get rows -- let routine allocate the row array */
  while\201 \201ebuf = \201Ev\202FunTableRowGet\201fun, NULL, MAXROW, NULL, &got\202\202 \202{
    /* process all rows */
    for\201i=0; i<got; i++\202{
      /* point to the i'th row */
      ev = ebuf+i;
      ...
      /* write out the current \201i.e., i'th\202 row */
      FunTableRowPut\201fun2, \201char *\202ev, 1, i, NULL\202;
    }
    /* free row data */
    if\201 ebuf \202 free\201ebuf\202;
  })RP(

)0 P(The final argument is a param list string that is not currently used.
The routine returns the number of rows output.  This should be equal
to the value passed in the third )BD(nrowFunParamGet)WB 37 Sn( - get a Funtools param value)EA()EH(


)BD() 9 74 PR(  #include <funtools.h>

  int FunParamGetb\201Fun fun, char *name, int n, int defval, int *got\202

  int FunParamGeti\201Fun fun, char *name, int n, int defval, int *got\202

  double FunParamGetd\201Fun fun, char *name, int n, double defval, int *got\202

  char *FunParamGets\201Fun fun, char *name, int n, char *defval, int *got\202)RP()ES(


)0 P(The four routines )BD(FunParamGetb\201\202)ES(, )BD(FunParamGeti\201\202)ES(,
)BD(FunParamGetd\201\202)ES(, and )BD(FunParamGets\201\202)ES(, return the value of
a FITS header parameter as a boolean, int, double, and string,
respectively. The string returned by )BD(FunParamGets\201\202)ES( is a malloc'ed
copy of the header value and should be freed when no longer needed.

)0 P(The first argument is the Fun handle associated with the FITS header
being accessed. Normally, the header is associated with the FITS
extension that you opened with )BD(FunOpen\201\202)ES(. However, you can use
FunInfoPut\201\202 to specify access of the primary header. In particular,
if you set the FUN_PRIMARYHEADER parameter to 1, then the primary
header is used for all parameter access until the value is reset to
0. For example:
) 9 75 PR(  int val;
  FunParamGeti\201fun, "NAXIS", 1, 0, &got\202;              # current header
  val=1;
  FunInfoPut\201fun, FUN_PRIMARYHEADER, &val, 0\202;         # switch to ...
  FunParamGeti\201fun, "NAXIS", 1, 0, &got\202;              # ... primary header
  FunParamGeti\201fun, "NAXIS", 2, 0, &got\202;              # ... primary header
  val=0;
  FunInfoPut\201fun, FUN_PRIMARYHEADER, &val, 0\202;         # switch back to ...
  FunParamGeti\201fun, "NAXIS", 2, 0, &got\202;              # current header)RP(

)0 P(Alternatively, you can use the FUN_PRIMARY macro to access parameters
from the primary header on a per-parameter basis:
) 2 72 PR(  FunParamGeti\201fun, "NAXIS1", 0, 0, &got\202;              # current header
  FunParamGeti\201FUN_PRIMARY\201fun\202, "NAXIS1", 0, 0, &got\202; # primary header)RP(
)BD(NB: FUN_PRIMARY is deprecated.)ES(
It makes use of a global parameter and therefore will not not
appropriate for threaded applications, when we make funtools
thread-safe. We recommend use of FunInfoPut\201\202 to switch between the
extension header and the primary header.

)0 P(For output data, access to the primary header is only possible until
the header is written out, which usually takes place when the first
data are written.

)0 P(The second argument is the name of the parameter to access.  The third
)BD(n)ES( argument, if non-zero, is an integer that will be added as a
suffix to the parameter name.  This makes it easy to use a simple loop
to process parameters having the same root name.  For example, to
gather up all values of TLMIN and TLMAX for each column in a binary
table, you can use:
) 4 74 PR(  for\201i=0, got=1; got; i++\202{
    fun->cols[i]->tlmin = \201int\202FunParamGeti\201fun, "TLMIN", i+1, 0.0, &got\202;
    fun->cols[i]->tlmax = \201int\202FunParamGeti\201fun, "TLMAX", i+1, 0.0, &got\202;
  })RP(

)0 P(The fourth )BD(defval)ES( argument is the default value to return if
the parameter does not exist. Note that the data type of this
parameter is different for each specific FunParamGet\201\202 call. The final
)BD(got)ES( argument will be 0 if no param was found. Otherwise the
data type of the parameter is returned as follows: FUN_PAR_UNKNOWN
\201'u'\202, FUN_PAR_COMMENT \201'c'\202, FUN_PAR_LOGICAL \201'l'\202, FUN_PAR_INTEGER
\201'i'\202, FUN_PAR_STRING \201's'\202, FUN_PAR_REAL \201'r'\202, FUN_PAR_COMPLEX \201'x'\202.

)0 P(These routines return the value of the header parameter, or the
specified default value if the header parameter does not exist.  The
returned value is a malloc'ed string and should be freed when no
longer needed.

)0 P(By default, )BD(FunParamGets\201\202)ES( returns the string value of the
named parameter.  However, you can use FunInfoPut\201\202 to retrieve the
raw 80-character FITS card instead.  In particular, if you set the
FUN_RAWPARAM parameter to 1, then card images will be returned by
FunParamGets\201\202 until the value is reset to 0.

)0 P(Alternatively, if the FUN_RAW macro is applied to the name, then the
80-character raw FITS card is returned instead.  
)BD(NB: FUN_RAW is deprecated.)ES( 
It makes use of a global parameter and therefore will not not
appropriate for threaded applications, when we make funtools
thread-safe. We recommend use of FunInfoPut\201\202 to switch between the
extension header and the primary header.

)0 P(Note that in addition to the behaviors described above, the
routine )BD(FunParamGets\201\202)ES( will return the 80 raw characters of the
)BD(nth)ES( FITS card \201including the comment\202 if )BD(name)ES( is specified as
NULL and )BD(n)ES( is positive. For example, to loop through all FITS
header cards in a given extension and print out the raw card, use:
) 9 55 PR(  for\201i=1; ;i++\202{
    if\201 \201s = FunParamGets\201fun, NULL, i, NULL, &got\202\202 \202{
      fprintf\201stdout, "%.80s\200n", s\202;
      free\201s\202;
    }
    else{
      break;
    }
  })RP(




)0 2 43 H(FunParamPut)WB 109 Sn()WB 38 Sn( - put a Funtools param value)EA()EH(


)BD() 13 71 PR(  #include <funtools.h>

  int FunParamPutb\201Fun fun, char *name, int n, int value, char *comm,
                   int append\202

  int FunParamPuti\201Fun fun, char *name, int n, int value, char *comm,
                   int append\202

  int FunParamPutd\201Fun fun, char *name, int n, double value, int prec,
                   char *comm, int append\202

  int FunParamPuts\201Fun fun, char *name, int n, char *value, char *comm,
                   int append\202)RP()ES(


)0 P(The four routines )BD(FunParamPutb\201\202)ES(, )BD(FunParamPuti\201\202)ES(,
)BD(FunParamPutd\201\202)ES(, and )BD(FunParamPuts\201\202)ES(, will set the value
of a FITS header parameter as a boolean, int, double, and string,
respectively.

)0 P(The first argument is the Fun handle associated with the FITS header
being accessed. Normally, the header is associated with the FITS
extension that you opened with )BD(FunOpen\201\202)ES(.
However, you can use FunInfoPut\201\202 to specify that use of the primary
header. In particular, if you set the FUN_PRIMARYHEADER parameter to
1, then the primary header is used for all parameter access until the
value is reset to 0. For example:
) 5 69 PR(  int val;
  FunParamPuti\201fun, "NAXIS1", 0, 10, NULL, 1\202;       # current header
  val=1;
  FunInfoPut\201fun, FUN_PRIMARYHEADER, &val, 0\202;       # switch to ...
  FunParamPuti\201fun, "NAXIS1", 0, 10, NULL, 1\202;       # primary header)RP(
\201You also can use the deprecated FUN_PRIMARY macro, to access
parameters from the primary header.\202

)0 P(The second argument is the )BD(name)ES( of the parameter.  \201
In accordance with FITS standards, the special names )BD(COMMENT)ES(
and )BD(HISTORY)ES(, as well as blank names, are output without the "= "
value indicator in columns 9 and 10.

)0 P(The third )BD(n)ES( argument, if non-zero, is an integer that will be
added as a suffix to the parameter name.  This makes it easy to use a
simple loop to process parameters having the same root name.  For
example, to set the values of TLMIN and TLMAX for each column in a
binary table, you can use:
) 4 70 PR(  for\201i=0; i<got; i++\202{
    FunParamPutd\201fun, "TLMIN", i+1, tlmin[i], 7, "min column val", 1\202;
    FunParamPutd\201fun, "TLMAX", i+1, tlmax[i], 7, "max column val", 1\202;
  })RP(

)0 P(The fourth )BD(defval)ES( argument is the value to set.  Note that the
data type of this argument is different for each specific
FunParamPut\201\202 call. The )BD(comm)ES( argument is the comment
string to add to this header parameter. Its value can be NULL.  The
final )BD(append)ES( argument determines whether the parameter is added
to the header if it does not exist. If set to a non-zero value, the
header parameter will be appended to the header if it does not exist.
If set to 0, the value will only be used to change an existing parameter.

)0 P(Note that the double precision routine FunParamPutd\201\202 supports an
extra )BD(prec)ES( argument after the )BD(value)ES( argument, in order
to specify the precision when converting the double value to ASCII. In
general a 20.[prec] format is used \201since 20 characters are alloted to
a floating point number in FITS\202 as follows: if the double value being
put to the header is less than 0.1 or greater than or equal to
10**\20120-2-[prec]\202, then %20.[prec]e format is used \201i.e., scientific
notation\202; otherwise %20.[prec]f format is used \201i.e., numeric
notation\202.

)0 P(As a rule, parameters should be set before writing the table or image.
It is, however, possible to update the value of an )BD(existing)ES(
parameter after writing an image or table \201but not to add a new
one\202. Such updating only works if the parameter already exists and if
the output file is seekable, i.e. if it is a disk file or is stdout
being redirected to a disk file.

)0 P(It is possible to add a new parameter to a header after the data has
been written, but only if space has previously been reserved. To reserve
space, add a blank parameter whose value is the name of the parameter you
eventually will update. Then, when writing the new parameter, specify a 
value of 2 for the append flag. The parameter writing routine will
first look to update an existing parameter, as usual. If an existing
parameter is not found, an appropriately-valued blank parameter will be
searched for and replaced.  For example:
) 8 71 PR(  /* add blank card to be used as a place holder for IPAR1 update */
  FunParamPuts\201fun, NULL, 0, "IPAR1", "INTEGER Param", 0\202;
  ...
  /* write header and data */
  FunTableRowPut\201fun, events, got, 0, NULL\202;
  ...
  /* update param in file after writing data -- note append = 2 here */
  FunParamPuti\201fun, "IPAR", 1, 400, "INTEGER Param", 2\202;)RP(

)0 P(The parameter routines return a 1 if the routine was successful and a 0 on
failure. In general, the major reason for failure is that you did not
set the append argument to a non-zero value and the parameter did not
already exist in the file.




)0 2 44 H(FunInfoGet)WB 110 Sn()WB 35 Sn( - get information from Funtools struct)EA()EH(


)BD() 3 52 PR(  #include <funtools.h>

  int FunInfoGet\201Fun fun, int type, char *addr, ...\202)RP()ES(


)0 P(The )BD(FunInfoGet\201\202)ES( routine returns information culled from the
Funtools structure.  The first argument is the Fun handle from which
information is to be retrieved.  This first required argument is followed
by a variable length list of pairs of arguments. Each pair consists
of an integer representing the type of information to retrieve and the
address where the information is to be stored. The list is terminated by a 0.
The routine returns the number of get actions performed.

)0 P(The full list of available information is described below.  Please note
that only a few of these will be useful to most application developers.
For imaging applications, the most important types are:
) 3 47 PR(  FUN_SECT_DIM1   int  /* dim1 for section */
  FUN_SECT_DIM2   int  /* dim2 for section */
  FUN_SECT_BITPIX int  /* bitpix for section */)RP(
These would be used to determine the dimensions and data type of image
data retrieved using the
)0 26 1 A(FunImageGet\201\202)26 0 TN TL()Ec /AF f D( routine. For
example:
) 17 68 PR(  /* extract and bin the data section into an image buffer */
  buf = FunImageGet\201fun, NULL, NULL\202;
  /* get required information from funtools structure.
     this should come after the FunImageGet\201\202 call, in case the call
     changed sect_bitpix */
  FunInfoGet\201fun,
             FUN_SECT_BITPIX,  &bitpix,
             FUN_SECT_DIM1,    &dim1,
             FUN_SECT_DIM2,    &dim2,
             0\202;
  /* loop through pixels and reset values below limit to value */
  for\201i=0; i<dim1*dim2; i++\202{
    switch\201bitpix\202{
    case 8:
      if\201 cbuf[i] <= blimit \202 cbuf[i] = bvalue;
    ...
  })RP(
It is important to bear in mind that the call to 
)0 26 1 A(FunImageGet\201\202)26 0 TN TL()Ec /AF f D(
can change the value of FUN_SECT_BITPIX \201e.g. if "bitpix=n" is passed
in the param list\202.  Therefore, a call to
)0 35 1 A(FunInfoGet\201\202)35 0 TN TL()Ec /AF f D(
should be made )BD(after)ES( the call to 
)0 26 1 A(FunImageGet\201\202)26 0 TN TL()Ec /AF f D(,
in order to retrieve the updated bitpix value.
See the )0 2 A(imblank example code)EA( for more
details. 

)0 P(It also can be useful to retrieve the World Coordinate System
information from the Funtools structure. Funtools uses the the WCS
Library developed by Doug Mink at SAO, which is available 
)R3 2 A(here)EA(.
\201More information about the WCSTools project in general can be found
)R4 2 A(here)EA(.\202
The )0 25 1 A(FunOpen\201\202)25 0 TN TL()Ec /AF f D( routine initializes
two WCS structures that can be used with this WCS Library.
Applications can retrieve either of these two WCS structures using
)BD(FunInfoGet\201\202)ES(:
) 2 75 PR(  FUN_WCS  struct WorldCoor * /* wcs structure, for image coordinates*/
  FUN_WCS0 struct WorldCoor * /* wcs structure, for physical coordinates */)RP(
The structure retrieved by FUN_WCS is a WCS library handle containing
parameters suitable for use with image coordinates, regardless of whether the
data are images or tables. For this structure, the WCS reference point
\201CRPIX\202 has been converted to image coordinates if the underlying file
is a table \201and therefore in physical coordinates\202. You therefore must
ensure that the positions being passed to a routine like pix2wcs are in
image coordinates. The FUN_WCS0 structure has not had its WCS
reference point converted to image coordinates. It therefore is useful
when passing processing physical coordinates from a table.

)0 P(Once a WCS structure has been retrieved, it can be used as the first
argument to the WCS library routines. \201If the structure is NULL, no
WCS information was contained in the file.\202 The two important WCS routines
that Funtools uses are:
) 5 66 PR(  #include <wcs.h>
  void pix2wcs \201wcs,xpix,ypix,xpos,ypos\202
    struct WorldCoor *wcs; /* World coordinate system structure */
    double xpix,ypix;      /* x and y coordinates in pixels */
    double *xpos,*ypos;    /* RA and Dec in degrees \201returned\202 */)RP(

which converts pixel coordinates to sky coordinates, and:

) 5 67 PR(  void wcs2pix \201wcs, xpos, ypos, xpix, ypix, offscl\202
    struct WorldCoor *wcs; /* World coordinate system structure */
    double xpos,ypos;      /* World coordinates in degrees */
    double *xpix,*ypix;    /* coordinates in pixels */
    int *offscl;           /* 0 if within bounds, else off scale */)RP(
which converts sky coordinates to pixel coordinates. Again, please note
that the wcs structure returned by FUN_WCS assumes that image coordinates
are passed to the pix2wcs routine, while FUN_WCS0 assumes that physical
coordinates are passed.

)0 P(Note that funtools.h file automatically includes wcs.h.  An example
program that utilizes these WCS structure to call WCS Library routines
is )0 2 A(twcs.c)EA(.

)0 P(The following is the complete list of information that can be returned:
) 52 79 PR(  name            type            comment
  ---------       --------        ---------------------------------------------
  FUN_FNAME     char *            /* file name */
  FUN_GIO       GIO               /* gio handle */
  FUN_HEADER    FITSHead          /* fitsy header struct */
  FUN_TYPE      int               /* TY_TABLE,TY_IMAGE,TY_EVENTS,TY_ARRAY */
  FUN_BITPIX    int               /* bits/pixel in file */
  FUN_MIN1      int               /* tlmin of axis1 -- tables */
  FUN_MAX1      int               /* tlmax of axis1 -- tables */
  FUN_MIN2      int               /* tlmin of axis2 -- tables */
  FUN_MAX2      int               /* tlmax of axis2 -- tables */
  FUN_DIM1      int               /* dimension of axis1 */
  FUN_DIM2      int               /* dimension of axis2 */
  FUN_ENDIAN    int               /* 0=little, 1=big endian */
  FUN_FILTER    char *            /* supplied filter */
  FUN_IFUN      FITSHead          /* pointer to reference header */
  FUN_IFUN0     FITSHead          /* same as above, but no reset performed */
  /* image information */
  FUN_DTYPE     int               /* data type for images */
  FUN_DLEN      int               /* length of image in bytes */
  FUN_DPAD      int               /* padding to end of extension */
  FUN_DOBLANK   int               /* was blank keyword defined? */
  FUN_BLANK     int               /* value for blank */
  FUN_SCALED    int               /* was bscale/bzero defined? */
  FUN_BSCALE    double            /* bscale value */
  FUN_BZERO     double            /* bzero value */
  /* table information */
  FUN_NROWS     int               /* number of rows in file \201naxis2\202 */
  FUN_ROWSIZE   int               /* size of user row struct */
  FUN_BINCOLS   char *            /* specified binning columns */
  FUN_OVERFLOW  int               /* overflow detected during binning? */)WR(
  /* array information */
  FUN_SKIP      int               /* bytes to skip in array header */
  /* section information */
  FUN_SECT_X0   int               /* low dim1 value of section */
  FUN_SECT_X1   int               /* hi dim1 value of section */
  FUN_SECT_Y0   int               /* low dim2 value of section */
  FUN_SECT_Y1   int               /* hi dim2 value of section */
  FUN_SECT_BLOCK int              /* section block factor */
  FUN_SECT_BTYPE int              /* 's' \201sum\202, 'a' \201average\202 for binning */
  FUN_SECT_DIM1 int               /* dim1 for section */
  FUN_SECT_DIM2 int               /* dim2 for section */
  FUN_SECT_BITPIX int             /* bitpix for section */
  FUN_SECT_DTYPE int              /* data type for section */
  FUN_RAWBUF    char *            /* pointer to raw row buffer */
  FUN_RAWSIZE   int               /* byte size of raw row records */
  /* column  information */
  FUN_NCOL      int               /* number of row columns defined */
  FUN_COLS      FunCol            /* array of row columns */
  /* WCS information */
  FUN_WCS       struct WorldCoor * /* wcs structure, converted for images*/
  FUN_WCS0      struct WorldCoor * /* wcs structure, not converted */)RP(

)0 P(Row applications would not normally need any of this information.
An example of how these values can be used in more complex programs is
the )0 2 A(evnext example code)EA(. In this program, the
time value for each row is changed to be the value of the succeeding
row. The program thus reads the time values for a batch of rows,
changes the time values to be the value for the succeeding row, and
then merges these changed time values back with the other columns to
the output file. It then reads the next batch, etc.

)0 P(This does not work for the last row read in each batch, since there
is no succeeding row until the next batch is read. Therefore, the
program saves that last row until it has read the next batch, then
processes the former before starting on the new batch. In order to
merge the last row successfully, the code uses FUN_RAWBUF to save
and restore the raw input data associated with each batch of
rows. Clearly, this requires some information about how funtools
works internally. We are happy to help you write such programs as the
need arises.




)0 2 45 H(FunInfoPut)WB 111 Sn()WB 36 Sn( - put information into a Funtools struct)EA()EH(


)BD() 3 52 PR(  #include <funtools.h>

  int FunInfoPut\201Fun fun, int type, char *addr, ...\202)RP()ES(


)0 P(The )BD(FunInfoPut\201\202)ES( routine puts information into a Funtools
structure.  The first argument is the Fun handle from which
information is to be retrieved.  After this first required argument
comes a variable length list of pairs of arguments. Each pair consists
of an integer representing the type of information to store and the
address of the new information to store in the struct. The variable
list is terminated by a 0.  The routine returns the number of put
actions performed.

)0 P(The full list of available information is described above with the 
)0 36 1 A(FunInfoPut\201\202)36 0 TN TL()Ec /AF f D( routine. Although
use of this routine is expected to be uncommon, there is one
important situation in which it plays an essential part: writing
multiple extensions to a single output file.

)0 P(For input, multiple extensions are handled by calling 
)0 25 1 A(FunOpen\201\202)25 0 TN TL()Ec /AF f D( for each extension to be
processed. When opening multiple inputs, it sometimes is the case that
you will want to process them and then write them \201including their
header parameters\202 to a single output file.  To accomplish this, you
open successive input extensions using 
)0 25 1 A(FunOpen\201\202)25 0 TN TL()Ec /AF f D( and then call
)BD(FunInfoPut\201\202)ES( to set the 
)0 23 1 A(Funtools reference handle)23 0 TN TL()Ec /AF f D(
of the output file to that of the newly opened input extension:
) 4 71 PR(  /* open a new input extension */
  ifun=FunOpen\201tbuf, "r", NULL\202\202 \202
  /* make the new extension the reference handle for the output file */
  FunInfoPut\201ofun, FUN_IFUN, &ifun, 0\202;)RP(

Resetting FUN_IFUN has same effect as when a funtools handle is passed
as the final argument to 
)0 25 1 A(FunOpen\201\202)25 0 TN TL()Ec /AF f D(.  The state of the output
file is reset so that a new extension is ready to be written.
Thus, the next I/O call on the output extension will output the
header, as expected.

)0 P(For example, in a binary table, after resetting FUN_IFUN you can then
call )0 32 1 A(FunColumnSelect\201\202)32 0 TN TL()Ec /AF f D( to
select the columns for output. When you then call 
)0 27 1 A(FunImagePut\201\202)27 0 TN TL()Ec /AF f D( or )0 31 1 A(FunTableRowPut\201\202)31 0 TN TL()Ec /AF f D(, a new
extension will be written that contains the header parameters from the
reference extension. Remember to call 
)0 39 1 A(FunFlush\201\202)39 0 TN TL()Ec /AF f D( to complete output of a
given extension.

)0 P(A complete example of this capability is given
in the )0 2 A(evcol example code)EA(.
The central algorithm is:
)UL()-1 LI( open the output file without a reference handle
)-1 LI( loop: open each input extension in turn
)UL()-1 LI( set the reference handle for output to the newly opened input extension
)-1 LI( read the input rows or image and perform processing
)-1 LI( write new rows or image to the output file
)-1 LI( flush the output
)-1 LI( close input extension)LU(
)-1 LI( close output file)LU(
Note that )0 39 1 A(FunFlush\201\202)39 0 TN TL()Ec /AF f D( is called
after processing each input extension in order to ensure that the
proper padding is written to the output file.  A call to 
)0 39 1 A(FunFlush\201\202)39 0 TN TL()Ec /AF f D( also ensures that the
extension header is written to the output file in the case where there
are no rows to output.

)0 P(If you wish to output a new extension without using a 
)0 23 1 A(Funtools reference handle)23 0 TN TL()Ec /AF f D(, you can
call FunInfoPut\201\202 to reset the FUN_OPS value directly.  For a binary
table, you would then call FunColumnSelect\201\202 to set up the columns for
this new extension.
) 6 59 PR(  /* reset the operations performed on this handle */
  int ops=0;
  FunInfoPut\201ofun, FUN_OPS, &ops, 0\202;
  FunColumnSelect\201fun, sizeof\201EvRec\202, NULL,
                  "MYCOL", "J", "w", FUN_OFFSET\201Ev, mycol\202,
                  NULL\202;)RP(
Once the FUN_OPS variable has been reset, the next I/O call on the
output extension will output the header, as expected.




)0 2 46 H(FunFlush)WB 112 Sn()WB 39 Sn( - flush data to output file)EA()EH(


)BD() 3 37 PR(  #include <funtools.h>

  void FunFlush\201Fun fun, char *plist\202)RP()ES(


)0 P(The )BD(FunFlush)ES( routine will flush data to a FITS output file.  In
particular, it can be called after all rows have been written \201using
the )0 31 1 A(FunTableRowPut\201\202)31 0 TN TL()Ec /AF f D( routine\202
in order to add the null padding that is required to complete a FITS
block. It also should be called after completely writing an image using
)0 27 1 A(FunImagePut\201\202)27 0 TN TL()Ec /AF f D( or after writing
the final row of an image using
)0 31 1 A(FunTableRowPut\201\202)31 0 TN TL()Ec /AF f D(.

)0 P(The )BD(plist)ES( \201i.e., parameter list\202 argument is a string
containing one or more comma-delimited )BD(keyword=value)ES(
parameters.  If the plist string contains the parameter
"copy=remainder" and the file was opened with a reference file, which,
in turn, was opened for extension copying \201i.e. the input 
)0 25 1 A(FunOpen\201\202)25 0 TN TL()Ec /AF f D( mode also was "c" or "C"\202,
then FunFlush also will copy the remainder of the FITS extensions from
the input reference file to the output file.  This normally would be
done only at the end of processing.

)0 P(Note that )0 39 1 A(FunFlush\201\202)39 0 TN TL()Ec /AF f D( is called
with "copy=remainder" in the mode string by FunClose\201\202.  This means
that if you close the output file before the reference input file, it
is not necessary to call 
)0 39 1 A(FunFlush\201\202)39 0 TN TL()Ec /AF f D( explicitly, unless you
are writing more than one extension.  See the 
)0 2 A(evmerge example code)EA(. However, it is safe to
call )0 39 1 A(FunFlush\201\202)39 0 TN TL()Ec /AF f D( more than once
without fear of re-writing either the padding or the copied
extensions.

)0 P(In addition, if )0 39 1 A(FunFlush\201\202)39 0 TN TL()Ec /AF f D( is
called on an output file with the plist set to "copy=reference" and if
the file was opened with a reference file, the reference extension is
written to the output file.  This mechanism provides a simple way to
copy input extensions to an output file without processing the former.
For example, in the code fragment below, an input extension is set to
be the reference file for a newly opened output extension. If that
reference extension is not a binary table, it is written to the output
file:
) 22 73 PR(  /* process each input extension in turn */
  for\201ext=0; ;ext++\202{
    /* get new extension name */
    sprintf\201tbuf, "%s[%d]", argv[1], ext\202;
    /* open input extension -- if we cannot open it, we are done */
    if\201 !\201ifun=FunOpen\201tbuf, "r", NULL\202\202 \202
      break;
    /* make the new extension the reference handle for the output file */
    FunInfoPut\201ofun, FUN_IFUN, &ifun, 0\202;
    /* if its not a binary table, just write it out */
    if\201 !\201s=FunParamGets\201ifun, "XTENSION", 0, NULL, &got\202\202 || 
      strcmp\201s, "BINTABLE"\202\202{
      if\201 s \202 free\201s\202;
      FunFlush\201ofun, "copy=reference"\202;
      FunClose\201ifun\202;
      continue;
    }
    else{
      /* process binary table */
      ....
    }
  })RP(




)0 2 47 H(FunClose)WB 113 Sn()WB 40 Sn( - close a Funtools data file)EA()EH(


)BD() 3 24 PR(  #include <funtools.h>

  void FunClose\201Fun fun\202)RP()ES(


)0 P(The )BD(FunClose\201\202)ES( routine closes a previously-opened Funtools data
file, freeing control structures. If a 
)0 23 1 A(Funtools reference handle)23 0 TN TL()Ec /AF f D(
was passed to
the )0 25 1 A(FunOpen\201\202)25 0 TN TL()Ec /AF f D( call for this file,
and if copy mode also was specified for that file, then 
)0 40 1 A(FunClose\201\202)40 0 TN TL()Ec /AF f D( also will copy the
remaining extensions from the input file to the output file \201if the
input file still is open\202.  Thus, we recommend always closing the
output Funtools file )BD(before)ES( the input file.  \201Alternatively,
you can call )0 39 1 A(FunFlush\201\202)39 0 TN TL()Ec /AF f D(
explicitly\202.




)0 2 48 H(FunRef:)WB 114 Sn()WB 23 Sn( the Funtools Reference Handle)EA()EH(


)0 2 49 H(Summary)WB 115 Sn()EH(
A description of how to use a Funtools reference handle to connect a
Funtools input file to an output file.


)0 2 50 H(Description)WB 116 Sn()EH(
)0 P(The Funtools reference handle connects a Funtools input file to a
Funtools output file so that parameters \201or even whole extensions\202 can
be copied from the one to the other. To make the connection, the Funtools
handle of the input file is passed to the 
final argument of the
)0 25 1 A(FunOpen\201\202)25 0 TN TL()Ec /AF f D( call for the output file:
) 4 67 PR(  if\201 !\201ifun = FunOpen\201argv[1], "r", NULL\202\202 \202
    gerror\201stderr, "could not FunOpen input file: %s\200n", argv[1]\202;
  if\201 !\201ofun = FunOpen\201argv[2], "w", ifun\202\202 \202
    gerror\201stderr, "could not FunOpen output file: %s\200n", argv[2]\202;)RP(
It does not matter what type of input or output file \201or extension\202 is
opened, or whether they are the same type. When the output image or
binary table is written using
)0 27 1 A(FunImagePut\201\202)27 0 TN TL()Ec /AF f D(
or
)0 31 1 A(FunTableRowPut\201\202)31 0 TN TL()Ec /AF f D(
an appropriate header will be written first, with parameters copied
from the input extension. Of course, invalid parameters will be
removed first, e.g., if the input is a binary table and the output is
an image, then binary table parameters such as TFORM, TUNIT,
etc. parameters will not be copied to the output.

)0 P(Use of a reference handle also allows default values to be passed
to
)0 27 1 A(FunImagePut\201\202)27 0 TN TL()Ec /AF f D( in order to
write out an output image with the same dimensions and data type
as the input image. To use the defaults from the input, a value
of 0 is entered for dim1, dim2, and bitpix. For example:
) 5 40 PR(  fun = FunOpen\201argv[1], "r", NULL\202;
  fun2 = FunOpen\201argv[2], "w", fun\202;
  buf = FunImageGet\201fun, NULL, NULL\202;
  ... process image data ...
  FunImagePut\201fun2, buf, 0, 0, 0, NULL\202;)RP(
Of course, you often want to get information about the data type
and dimensions of the image for processing. The above code
is equivalent to the following:
) 7 61 PR(  fun = FunOpen\201argv[1], "r", NULL\202;
  fun2 = FunOpen\201argv[2], "w", fun\202;
  buf = FunImageGet\201fun, NULL, NULL\202;
  FunInfoGet\201fun, FUN_SECT_DIM1, &dim1, FUN_SECT_DIM2, &dim2, 
             FUN_SECT_BITPIX, &bitpix, 0\202;
  ... process image data ...
  FunImagePut\201fun2, buf, dim1, dim2, bitpix, NULL\202;)RP(

)0 P(It is possible to change the reference handle for a given output Funtools
handle using the 
)0 36 1 A(FunInfoPut\201\202)36 0 TN TL()Ec /AF f D( routine:
) 2 71 PR(  /* make the new extension the reference handle for the output file */
  FunInfoPut\201fun2, FUN_IFUN, &fun, 0\202;)RP(
When this is done, Funtools specially resets the output file to start
a new output extension, which is connected to the new input reference
handle. You can use this mechanism to process multiple input extensions
into a single output file, by successively opening the former and
setting the reference handle for the latter. For example:
) 18 73 PR(  /* open a new output FITS file */
  if\201 !\201fun2 = FunOpen\201argv[2], "w", NULL\202\202 \202
    gerror\201stderr, "could not FunOpen output file: %s\200n", argv[2]\202;
  /* process each input extension in turn */
  for\201ext=0; ;ext++\202{
    /* get new extension name */
    sprintf\201tbuf, "%s[%d]", argv[1], ext\202;
    /* open it -- if we cannot open it, we are done */
    if\201 !\201fun=FunOpen\201tbuf, "r", NULL\202\202 \202
      break;
    /* make the new extension the reference handle for the output file */
    FunInfoPut\201fun2, FUN_IFUN, &fun, 0\202;
    ... process ...
    /* flush output extension \201write padding, etc.\202 */
    FunFlush\201fun2, NULL\202;
    /* close the input extension */
    FunClose\201fun\202;
  })RP(
In this example, the output file is opened first. Then each successive
input extension is opened, and the output reference handle is set to
the newly opened input handle. After data processing is performed, the
output extension is flushed and the input extension is closed, in
preparation for the next input extension.
)0 P(Finally, a reference handle can be used to copy other extensions from
the input file to the output file.  Copy of other extensions is
controlled by adding a "C" or "c" to the mode string of the
)0 25 1 A(FunOpen\201\202)25 0 TN TL()Ec /AF f D(
call )BD(of the input reference file)ES(.  If "C" is specified, then
other extensions are )BD(always)ES( copied \201i.e., copy is forced by the
application\202.  If "c" is used, then other extensions are copied if the
user requests copying by adding a plus sign "+" to the extension name
in the bracket specification.  For example, the )BD(funtable)ES(
program utilizes user-specified "c" mode so that the second example
below will copy all extensions:
) 4 60 PR(  # copy only the EVENTS extension
  csh> funtable "test.ev[EVENTS,circle\201512,512,10\202]" foo.ev
  # copy ALL extensions
  csh> funtable "test.ev[EVENTS+,circle\201512,512,10\202]" foo.ev)RP(
When extension copy is specified in the input file, the call to
)0 25 1 A(FunOpen\201\202)25 0 TN TL()Ec /AF f D(
on the input file delays the actual file open until the output file
also is opened \201or until I/O is performed on the input file, which
ever happens first\202. Then, when the output file is opened, the input
file is also opened and input extensions are copied to the output
file, up to the specific extension being opened. Processing of input
and output extensions then proceed.
)0 P(When extension processing is complete, the remaining extensions need to
be copied from input to output. This can be done explicitly, using the
)0 39 1 A(FunFlush\201\202)39 0 TN TL()Ec /AF f D(
call with the "copy=remaining" plist:
) 1 34 PR(  FunFlush\201fun, "copy=remaining"\202;)RP(
Alternatively, this will happen automatically, if the output file
is closed )BD(before)ES( the input file:
) 5 77 PR(  /* we could explicitly flush remaining extensions that need copying */
  /* FunFlush\201fun2, "copy=remaining"\202; */
  /* but if we close output before input, end flush is done automatically  */
  FunClose\201fun2\202;
  FunClose\201fun\202;)RP(







































)0 P()0 0 1 A(Go to Funtools Help Index)0 0 TN TL()Ec /AF f D(

)0 5 51 H(Last)WB 117 Sn( updated: December 1, 2005)EH(

)WB NL
/Cb Db D /Ct [16#00 16#00 16#00] D /Cl [16#00 16#00 16#00] D /CL -1 D Ct Sc
DS
/Ba f D /BO 0 D Bs
/UR (files.html) D
/Ti (Funtools Data Files) D
/Au () D
/Df f D
/ME [()] D

0 BO R
()1 Sl()WB 42 Sn(


)0 2 52 H(FunFiles:)WB 120 Sn()WB 118 Sn( Funtools Data Files)EA()EH(


)0 2 53 H(Summary)WB 121 Sn()EH(
This document describes the data file formats \201FITS, array, raw
events\202 as well as the file types \201gzip, socket, etc.\202 supported
by Funtools.


)0 2 54 H(Description)WB 122 Sn()EH(
)0 P(Funtools supports FITS images and binary tables, and binary files
containing array \201homogeneous\202 data or event \201heterogeneous\202 data.
IRAF-style brackets are appended to the filename to specify various
kinds of information needed to characterize these data:
) 3 49 PR(  file[ext|ind|ARRAY\201\202|EVENTS\201\202,section][filters]
  or
  file[ext|ind|ARRAY\201\202|EVENTS\201\202,section,filters])RP(
where:
)UL()-1 LI( )BD(file)ES( is the Funtools file name
)-1 LI( )BD(ext)ES( is the FITS extension name
)-1 LI( )BD(ind)ES( is the FITS extension number
)-1 LI( )BD(ARRAY\201\202)ES( is an array specification
)-1 LI( )BD(EVENTS\201\202)ES( is an event specification
)-1 LI( )BD(section)ES( is the image section specification
)-1 LI( )BD(filters)ES( are spatial region and table \201row\202 filters)LU(

)0 2 55 H(Supported)WB 123 Sn()WB 43 Sn( Data Formats)EA()EH(
)0 P(Funtools programs \201and the underlying libraries\202 support the
following data file formats:
)UL()-1 LI( FITS images \201and image extensions\202
)-1 LI( FITS binary tables
)-1 LI( binary files containing an array of homogeneous data
)-1 LI( binary files containing events, i.e. records of heterogeneous data
)-1 LI( column-based text files, which are documented )0 47 1 A(here)47 0 TN TL()Ec /AF f D(
)-1 LI( non-disk files and lists of files)LU(
Information needed to identify and characterize
the event or image data can be specified on the command line 
using IRAF-style bracket notation appended to the filename:
) 5 69 PR(  foo.fits                              # open FITS default extension
  image.fits[3]                         # open FITS extension #3
  events.fits[EVENTS]                   # open EVENTS extension
  array.file[ARRAY\201s1024\202]              # open 1024x1024 short array
  events.file[EVENTS\201x:1024,y:1024...\202] # open non-FITS event list)RP(
Note that in many Unix shells \201e.g., csh and tcsh\202, filenames must
be enclosed in quotes to protect the brackets from shell processing.

)0 2 56 H(FITS)WB 124 Sn()WB 44 Sn( Images and Binary Tables)EA()EH(
)0 P(When )0 25 1 A(FunOpen\201\202)25 0 TN TL()Ec /AF f D( opens a FITS file
without a bracket specifier, the default behavior is to look for a
valid image in the primary HDU. In the absence of a primary image,
Funtools will try to open an extension named either )BD(EVENTS)ES( or
)BD(STDEVT)ES(, if one of these exists. This default behavior supports
both FITS image processing and standard X-ray event list processing
\201which, after all, is what we at SAO/HEAD do\202.

)0 P(In order to open a FITS binary table or image extension explicitly, it
is necessary to specify either the extension name or the extension
number in brackets:
) 3 71 PR(  foo.fits[1]                      # open extension #1: the primary HDU
  foo.fits[3]                      # open extension #3 of a FITS file
  foo.fits[GTI]                    # open GTI extension of a FITS file)RP(
The ext argument specifies the name of the FITS extension \201i.e. the
value of the EXTENSION header parameter in a FITS extension\202, while
the index specifies the value of the FITS EXTVER header parameter.
Following FITS conventions, extension numbers start at 1.

)0 P(When a FITS data file is opened for reading using 
)0 25 1 A(FunOpen\201\202)25 0 TN TL()Ec /AF f D(, the specified extension
is automatically located and is used to initialize the Funtools internal
data structures.

)0 2 57 H(Non-FITS)WB 125 Sn()WB 45 Sn( Raw Event Files)EA()EH(

In addition to FITS tables, Funtools programs and libraries can operate
on non-FITS files containing heterogeneous event records. To specify
such an event file, use:

)UL()-1 LI( file[EVENTS\201event-spec\202]
)-1 LI( file[EVENTS\201\202])LU(
where )BD(event-spec)ES( is a string that specified the names, data
types, and optional image dimensions for each element of the event
record:
)UL()-1 LI( [name]:[n][type]:[\201lodim:\202hidim])LU(

)0 P(Data types follow standard conventions for FITS binary tables, but include
two extra unsigned types \201'U' and 'V'\202:
)UL()-1 LI( )BD(B)ES( -- unsigned 8-bit char
)-1 LI( )BD(I)ES( -- signed 16-bit int
)-1 LI( )BD(J)ES( -- signed 32-bit int
)-1 LI( )BD(K)ES( -- signed 64-bit int
)-1 LI( )BD(E)ES( -- 32-bit float
)-1 LI( )BD(D)ES( -- 64-bit float
)-1 LI( )BD(U)ES( -- unsigned 16-bit int
)-1 LI( )BD(V)ES( -- unsigned 32-bit int)LU(
An optional integer value )BD(n)ES( can be prefixed to the type to indicate
that the element is an array of n values. For example:
) 1 37 PR(  foo.fits[EVENTS\201x:I,y:I,status:4J\202])RP(
defines x and y as 16-bit ints and status as an array of 4 32-bit ints.

)0 P(Furthermore, image dimensions can be attached to the event specification
in order to tell Funtools how to bin the events into an image. They
follow the conventions for the FITS TLMIN/TLMAX keywords. If the low
image dimension is not specified, it defaults to 1.  Thus:

)UL()-1 LI( RAWX:J:1:100
)-1 LI( RAWX:J:100)LU(
both specify that the dimension of this column runs from 1 to 100.

)0 P(NB: it is required that all padding be specified in the record
definition. Thus, when writing out whole C structs instead of
individual record elements, great care must be taken to include
the compiler-added padding in the event definition.

)0 P(For example, suppose a FITS binary table has the following set of column
definitions:
) 22 54 PR(  TTYPE1  = 'X                 ' / Label for field
  TFORM1  = '1I                ' / Data type for field
  TLMIN1  =                    1 / Min. axis value
  TLMAX1  =                   10 / Max. axis value
  TTYPE2  = 'Y                 ' / Label for field
  TFORM2  = '1I                ' / Data type for field
  TLMIN2  =                    2 / Min. axis value
  TLMAX2  =                   11 / Max. axis value
  TTYPE3  = 'PHA               ' / Label for field
  TFORM3  = '1I                ' / Data type for field
  TTYPE4  = 'PI                ' / Label for field
  TFORM4  = '1J                ' / Data type for field
  TTYPE5  = 'TIME              ' / Label for field
  TFORM5  = '1D                ' / Data type for field 
  TTYPE6  = 'DX                ' / Label for field
  TFORM6  = '1E                ' / Data type for field
  TLMIN6  =                    1 / Min. axis value
  TLMAX6  =                   10 / Max. axis value
  TTYPE7  = 'DY                ' / Label for field
  TFORM7  = '1E                ' / Data type for field
  TLMIN7  =                    3 / Min. axis value
  TLMAX7  =                   12 / Max. axis value)RP(

An raw event file containing these same data would have the event
specification:
) 1 61 PR(  EVENTS\201X:I:10,Y:I:2:11,PHA:I,PI:J,TIME:D,DX:E:10,DY:E:3:12\202)RP(

)0 P(If no event specification string is included within the EVENTS\201\202 operator,
then the event specification is taken from the )BD(EVENTS)ES( environment
variable:
) 1 65 PR(  setenv EVENTS "X:I:10,Y:I:10,PHA:I,PI:J,TIME:D,DX:E:10,DY:E:10")RP(

)0 P(In addition to knowing the data structure, it is necessary to know the
)EM(endian)ES( ordering of the data, i.e., whether or not the data is
in )EM(bigendian)ES( format, so that we can convert to the native
format for this platform. This issue does not arise for FITS Binary
Tables because all FITS files use big-endian ordering, regardless of
platform. But for non-FITS data, big-endian data produced on a Sun
workstation but read on a Linux PC needs to be byte-swapped, since PCs
use little-endian ordering. To specify an ordering, use the
)EM(bigendian=)ES( or )EM(endian=)ES( keywords on the command-line
or the EVENTS_BIGENDIAN or EVENTS_ENDIAN environment variables.  The
value of the )EM(bigendian)ES( variables should be "true" or "false",
while the value of the )EM(endian)ES( variables should be "little" or
"big".

)0 P(For example, a PC can access data produced by a Sun using:
) 7 35 PR(  hrc.nepr[EVENTS\201\202,bigendian=true]
or
  hrc.nepr[EVENTS\201\202,endian=big]
or
  setenv EVENTS_BIGENDIAN true
or
  setenv EVENTS_ENDIAN big)RP(
If none of these are specified, the data are assumed to follow the
format for that platform and no byte-swapping is performed.

)0 2 58 H(Non-FITS)WB 126 Sn()WB 46 Sn( Array Files)EA()EH(

In addition to FITS images, Funtools programs and libraries can operate
on non-FITS files containing arrays of homogeneous data. To specify
an array file, use:
)UL()-1 LI( file[ARRAY\201array-spec\202]
)-1 LI( file[ARRAY\201\202])LU(

where array-spec is of the form:
)UL()-1 LI( [type][dim1][.dim2][:skip][endian])LU(

and where [type] is:
)UL()-1 LI( b   \2018-bit unsigned char\202
)-1 LI( s   \20116-bit short int\202
)-1 LI( u   \20116-bit unsigned short int\202
)-1 LI( i   \20132-bit int\202
)-1 LI( r,f \20132-bit float\202
)-1 LI( d   \20164-bit float\202)LU(

)0 P(The dim1 specification is required, but dim2 is optional and defaults
to dim1.  The skip specification is optional and defaults to 0.  The
optional endian specification can be 'l' or 'b' and defaults to the
endian type for the current machine.

)0 P(If no array specification is included within the ARRAY\201\202 operator,
then the array specification is taken from the )BD(ARRAY)ES( environment
variable. For example:

) 7 76 PR(  foo.arr[ARRAY\201r512\202]          # bitpix=-32 dim1=512 dim2=512
  foo.arr[ARRAY\201r512.400\202]      # bitpix=-32 dim1=512 dim2=400
  foo.arr[ARRAY\201r512.400]\202      # bitpix=-32 dim1=512 dim2=400
  foo.arr[ARRAY\201r512.400:2880\202] # bitpix=-32 dim1=512 dim2=400 skip=2880
  foo.arr[ARRAY\201r512l\202]         # bitpix=-32 dim1=512 dim2=512 endian=little
  setenv ARRAY "r512.400:2880"
  foo.arr[ARRAY\201\202]              # bitpix=-32 dim1=512 dim2=400 skip=2880)RP(

)0 2 59 H(Specifying)WB 127 Sn()WB 49 Sn( Image Sections)EA()EH(

Once a data file \201and possibly, a FITS extension\202 has been specified,
the next \201optional\202 part of a bracket specification can be used to
select image )BD(section)ES( information, i.e., to specify the x,y
limits of an image section, as well as the blocking factor to apply to
that section. This information can be added to any file specification but
only is used by Funtools image processing routines.

)0 P(The format of the image section specification is one of the following:
)UL()-1 LI( file[xy0:xy1,block]
)-1 LI( file[x0:x1,y0:y1,block]
)-1 LI( file[x0:x1,*,block]
)-1 LI( file[*,y0:y1,block]
)-1 LI( file[*,block])LU(
where the limit values can be ints or "*" for default. A single "*"
can be used instead of val:val, as shown.  Note that blocking is
applied to the section after it is extracted.

)0 P(In addition to image sections specified by the lo and hi x,y limits, image
sections using center positions can be specified:
)UL()-1 LI( file[dim1@xcen,dim2@ycen]
)-1 LI( file[xdim2@xcen@ycen]
)-1 LI( file[dim1@xcen,dim2@ycen,block]
)-1 LI( file[dim@xcen@ycen,block])LU(
Note that the \201float\202 values for dim, dim1, dim2, xcen, ycen must be
specified or else the expression does not make sense!

)0 P(In all cases, block is optional and defaults to 1. An 's' or 'a' can
be appended to signify "sum" or "average" blocking \201default is "sum"\202.
Section specifications are given in image coordinates by default. If you
wish to specify physical coordinates, add a 'p' as the last character
of the section specification, before the closing bracket.
For example:
) 2 21 PR()UL()-1 LI( file[-8:-7,-8:-7p]
)-1 LI( file[-8:-7,-8:-7,2p])LU()RP(
A section can be specified in any Funtools file name. If the operation
to be applied to that file is an imaging operation, then the
specification will be utilized. If the operation is purely a table
operation, then the section specification is ignored.

)0 P(Do not be confused by:
) 2 15 PR(  foo.fits[2]
  foo.fits[*,2])RP(
The former specifies opening the second extension of the FITS file.
The latter specifies application of block 2 to the image section.

)0 P(Note that the section specification must come after
any of FITS )BD(ext)ES( name or )BD(ind)ES( number,
but all sensible defaults are supported:
)UL()-1 LI( file[ext]
)-1 LI( file[ext,index]
)-1 LI( file[index]
)-1 LI( file[ext,section]
)-1 LI( file[ext,index,section]
)-1 LI( file[index,section]
)-1 LI( file[section])LU(

)0 2 60 H(Binning)WB 128 Sn()WB 50 Sn( FITS Binary Tables and Non-FITS Event Files)EH(

If a FITS binary table or a non-FITS raw event file is to be binned
into a 2D image \201e.g., using the 
)0 10 1 A(funimage)10 0 TN TL()Ec /AF f D(
program\202, it is necessary to specify the two columns to be used for the
binning, as well as the dimensions of the image.  Funtools first looks
for a specifier of the form:
) 1 74 PR( bincols=\201[xnam[:tlmin[:tlmax:[binsiz]]]],[ynam[:tlmin[:tlmax[:binsiz]]]]\202)RP(
in bracket syntax, and uses the column names thus specified. The tlmin, tlmax,
and binsiz specifiers determine the image binning dimensions using:
) 2 56 PR(  dim = \201tlmax - tlmin\202/binsiz     \201floating point data\202
  dim = \201tlmax - tlmin\202/binsiz + 1 \201integer data\202)RP(
These tlmin, tlmax, and binsiz specifiers can be omitted if TLMIN,
TLMAX, and TDBIN header parameters are present in the FITS binary
table header, respectively. If only one parameter is specified, it is
assumed to be tlmax, and tlmin defaults to 1. If two parameters are
specified, they are assumed to be tlmin and tlmax.

For example, to bin an HRC event list columns "VPOS" and "UPOS", use:
) 1 31 PR(  hrc.nepr[bincols=\201VPOS,UPOS\202])RP(
or
) 1 42 PR(  hrc.nepr[bincols=\201VPOS:49152,UPOS:4096\202])RP(
Note that you can optionally specify the dimensions of these columns
to cover cases where neither TLMAX keywords are defined in
the header.  If either dimension is specified, then both must be specified.

)0 P(You can set the FITS_BINCOLS or EVENTS_BINCOLS environment variable as
an alternative to adding the "bincols=" specifier to each file name
for FITS binary tables and raw event files, respectively.  If no
binning keywords or environment variables are specified, or if the
specified columns are not in the binary table, the Chandra parameters
CPREF \201or PREFX\202 are searched for in the FITS binary table header.
Failing this, columns named "X" and "Y" are sought.  If these are not
found, the code looks for columns containing the characters "X" and
"Y".  Thus, you can bin on "DETX" and "DETX" columns without
specifying them, if these are the only column names containing the "X"
and "Y" characters.

)0 P(Ordinarily, each event or row contributes one count to an image pixel
during the 2D binning process. Thus, if five events all have the same
\201x,y\202 position, the image pixel value for that position will have a
value of five. It is possible to specify a variable contribution
for each event by using the vcol=[colname] filter spec:
) 1 15 PR( vcol=[colname])RP(
The vcol colname is a column containing a numeric value in each event row
that will be used as the contribution of the given event to its image
pixel. For example, consider an event file that has the following content:
) 10 24 PR(  x:e:4    y:e:4    v:e
  ------   ------   ----
  1        1        1.0
  2        2        2.0
  3        3        3.0
  4        4        0.0
  1        1        1.0
  2        2        2.0
  3        3        3.0
  4        4        4.0)RP(
There are two events with x,y value of \2011,1\202 so ordinarily a 2D image will
have a value of 2 in the \2011,1\202 pixel. If the v column is specified as the 
value column:
) 1 20 PR(  foo.fits'[vcol=v]')RP(
then each pixel will contain the additive sum of the associated \201x,y\202
column values from the v column.  For example, image pixel \2011,1\202 will
contain 1. + 1. = 2, image pixel \2012,2\202 will contain \2012 + 2\202 = 4, etc.

)0 P(An important variation on the use of a value column to specify the
contribution an event makes to an image pixel is when the value column
contains the reciprocal of the event contribution. For this case, the
column name should be prefixed with a / \201divide sign\202 thus:
) 1 21 PR(  foo.fits'[vcol=/v]')RP(
Each image pixel value will then be the sum of the reciprocals of the value
column. A zero in the value column results in NaN \201not a number\202.
Thus, in the above example, image pixel \2011.1\202 will contain 1/1 + 1/1 = 2,
image pixel \2012,2\202 will contain \2011/2 + 1/2\202 = 1, etc. Image pixel \2014,4\202
will contain \2011/0 + 1/4\202 = NaN.

)0 P(You can set the FITS_VCOL or EVENTS_VCOL environment variable as
an alternative to adding the "vcol=" specifier to each file name
for FITS binary tables and raw event files, respectively.

)0 P(Finally, when binning events, the data type of the resulting 2D image
must be specified. This can be done with the "bitpix=[n]" keyword in
the bracket specification.  For example:
) 1 45 PR(  events.fits[bincols=\201VPOS,UPOS\202,bitpix=-32])RP(
will create a floating point image binned on columns VPOS and UPOS.
If no bitpix keyword is specified, bitpix=32 is assumed.  As with
bincols values, you also can use the FITS_BITPIX and EVENTS_BITPIX
environment variables to set this value for FITS binary tables and
raw event files, respectively.

)0 P(The )BD(funimage)ES( program also allows you to create a 1D image projection
along any column of a table by using the )BD(bincols=[column])ES(
filter specification and specifying a single column.
For example, the following command projects a 1D image along
the chipx column of a table:
) 1 43 PR(  funimage ev.fits'[bincols=chipx]' im.fits)RP(
See )0 10 1 A(funimage)10 0 TN TL()Ec /AF f D( for more
information about creating 1D and 2D images.

)0 P(Finally, please note that Funtools supports most FITS standards.
We will add missing support as required by the community. In general,
however, we do not support non-standard extensions. For example, we
sense the presence of the binary table 'variable length array'
proposed extension and we pass it along when copying and filtering
files, but we do not process it. We will add support for new standards
as they become official.

)0 2 61 H(Table)WB 129 Sn()WB 119 Sn( and Spatial Region Filters)EH(
)0 P(Note that, in addition extensions and image sections, Funtools bracket
notation can be used to specify table and spatial region filters.  These
filters are always placed after the image section information.  They
can be specified in the same bracket or in a separate bracket
immediately following:
)UL()-1 LI( file[ext|ind|ARRAY\201\202|EVENTS\201\202,section][filters]
)-1 LI( file[ext|ind|ARRAY\201\202|EVENTS\201\202,section,filters])LU(
where:
)UL()-1 LI( )BD(file)ES( is the Funtools file name
)-1 LI( )BD(ARRAY\201\202)ES( is an array specification
)-1 LI( )BD(EVENTS\201\202)ES( is an event list specification
)-1 LI( )BD(ext)ES( is the FITS extension name
)-1 LI( )BD(ind)ES( is the FITS extension number
)-1 LI( )BD(section)ES( is the image section to extract
)-1 LI( )BD(filters)ES( are spatial region and table \201row\202 filters to apply)LU(

The topics of table and region filtering are covered in detail in:
)UL()-1 LI()0 52 1 A(Table Filtering)52 0 TN TL()Ec /AF f D(
)-1 LI()0 54 1 A(Spatial Region Filtering)54 0 TN TL()Ec /AF f D()LU(

)0 2 62 H(Disk)WB 130 Sn()WB 51 Sn( Files and Other Supported File Types)EA()EH(
)0 P(The specified )BD(file)ES( usually is an ordinary disk file. In
addition, gzip'ed files are supported in Funtools: gzip'ed input files
are automatically uncompressed as they are read, and gzip'ed output
files are compressed as they are written. NB: if a FITS binary table
is written in gzip format, the number of rows in the table will be set
to -1. Such a file will work with Funtools programs but will not work
with other FITS programs such as ds9.

)0 P(The special keywords "stdin" and "stdout" designate Unix standard
input and standard output, respectively. The string "-" \201hyphen\202 will
be taken to mean "stdin" if the file is opened for reading and
"stdout" if the file is opened for writing.

)0 P(A file also can be an INET socket on the same or another machine using
the syntax:
) 1 14 PR(  machine:port)RP(
Thus, for example:
) 1 14 PR(  karapet:1428)RP(
specifies that I/O should be performed to/from port 1428 on the
machine karapet.  If no machine name is specified, the default is to
use the current machine:
) 1 7 PR(  :1428)RP(
This means to open port 1428 on the current machine. Socket support
allows you to generate a distributed pipe:
) 2 48 PR(  on karapet:       funtask1 in.fits bynars:1428
  on bynars:        funtask2 :1428 out.fits)RP(
The socket mechanism thus supports simple parallel processing using
)BD(process decomposition)ES(. Note that parallel processing using
)BD(data decomposition)ES( is supported via the )BD(section)ES( specifier \201see
below\202, and the )BD(row#)ES( specifier, which is part of 
)0 52 1 A(Table Filtering)52 0 TN TL()Ec /AF f D(.

)0 P(A file also can be a pointer to shared memory using the syntax:
) 1 22 PR(  shm:[id|@key][:size])RP(
A shared memory segment is specified with a )BD(shm:)ES( prefix,
followed by either the shared memory id or the shared memory key
\201where the latter is prefixed by the '@' character\202.  The size \201in
bytes\202 of the shared memory segment can then be appended \201preceded by
the ':' character\202. If the size specification is absent, the code will
attempt to determine the length automatically. 

If the open mode contains the string "w+", then the memory segment will be
created if it does not exist. \201It also will be released and deleted when the
file is closed.\202 In the case where a memory segment is being created, the
length of the segment is required.

)0 P(A file also can be Unix piped command \201i.e. a program to run\202 using the syntax:
) 1 31 PR(  "pipe: command arg1 ... argn")RP(
The output from the command must be a valid FITS file. It is important
to use quotes to protect spaces so that command arguments are passed
correctly. A silly example is:
) 1 60 PR(  fundisp "pipe: funtable 'foo.fits[cir 512 512 .1]' stdout")RP(
This seemed like a good idea at the time ...

)0 2 63 H(Lists)WB 131 Sn()WB 51 Sn( of Files)EA()EH(

)0 P(Funtools also will process a list of files as a single file using the
syntax:
) 1 31 PR(  "list: file1 file2 ... filen")RP(
The files in the list are separated by whitespace. Any of the
above file types can be used. For example, if two files, foo1.fits and
foo2.fits, are part of the same observation, they can be processed as
a single file \201using their own filters\202:
) 17 77 PR(  fundisp "list: foo1.fits[cir\201512,512,10\202] foo2.fits[cir\201511,511,10\202]"
         X        Y      PHA       PI                  TIME       DX       DY
  -------- -------- -------- -------- --------------------- -------- --------
       512      512        6        7     79493997.45854475      578      574
       512      512        8        9     79494575.58943175      579      573
       512      512        5        6     79493631.03866175      578      575
       512      512        5        5     79493290.86521725      578      575
       512      512        8        9     79493432.00990875      579      573
       511      511        5        5     79488631.09462625      580      575
       511      511       10       11     79488780.60006675      580      573
       511      511        4        4     79494562.35474326      580      575
       511      511        6        6     79488203.01561825      580      575
       511      511        6        6     79488017.99730176      580      575
       511      511        4        4     79494332.45355175      580      575
       511      511        9       10     79492685.94014275      581      574
       511      511        5        5     79487708.71298325      580      575
       511      511        8        9     79493719.00160225      581      573)RP(
Again, note that it is important to avoid spaces in the filters
because the list separator also is whitespace. To protect whitespace
in a filter, enclose the file specification in quotes:
) 1 72 PR(  fundisp "list: 'foo1.fits[cir 512 512 .1]' foo2.fits[cir\201511,511,.1\202]")RP(





)0 P()0 0 1 A(Go to Funtools Help Index)0 0 TN TL()Ec /AF f D(

)0 5 64 H(Last)WB 132 Sn( updated: February 15, 2006)EH(

)WB NL
/Cb Db D /Ct [16#00 16#00 16#00] D /Cl [16#00 16#00 16#00] D /CL -1 D Ct Sc
DS
/Ba f D /BO 0 D Bs
/UR (text.html) D
/Ti (Column-based Text Files) D
/Au () D
/Df f D
/ME [()] D

0 BO R
()1 Sl()WB 47 Sn(


)0 2 65 H(Funtext:)WB 134 Sn()WB 133 Sn( Support for Column-based Text Files)EA()EH(


)0 2 66 H(Summary)WB 135 Sn()EH(
)0 P(This document contains a summary of the options for processing column-based
text files.


)0 2 67 H(Description)WB 136 Sn()EH(

)0 P(Funtools will automatically sense and process "standard"
column-based text files as if they were FITS binary tables without any
change in Funtools syntax. In particular, you can filter text files
using the same syntax as FITS binary tables:
) 3 54 PR(  fundisp foo.txt'[cir 512 512 .1]'
  fundisp -T foo.txt > foo.rdb
  funtable foo.txt'[pha=1:10,cir 512 512 10]' foo.fits)RP(

)0 P(The first example displays a filtered selection of a text file.  The
second example converts a text file to an RDB file.  The third example
converts a filtered selection of a text file to a FITS binary table.

)0 P(Text files can also be used in Funtools image programs. In this case,
you must provide binning parameters \201as with raw event files\202, using
the bincols keyword specifier:

) 1 75 PR(  bincols=\201[xname[:tlmin[:tlmax:[binsiz]]]],[yname[:tlmin[:tlmax[:binsiz]]])RP(

For example:
) 1 64 PR(  funcnts foo'[bincols=\201x:1024,y:1024\202]' "ann 512 512 0 10 n=10")RP(

)0 2 68 H(Standard)WB 137 Sn( Text Files)EH(

)0 P(Standard text files have the following characteristics:

)UL()-1 LI( Optional comment lines start with #
)-1 LI( Optional blank lines are considered comments
)-1 LI( An optional table header consists of the following \201in order\202:
)UL(     )-1 LI( a single line of alpha-numeric column names
     )-1 LI( an optional line of unit strings containing the same number of cols
     )-1 LI( an optional line of dashes containing the same number of cols)LU(
)-1 LI( Data lines follow the optional header and \201for the present\202 consist of
     the same number of columns as the header.
)-1 LI( Standard delimiters such as space, tab, comma, semi-colon, and bar.)LU(

)0 P(Examples:

) 26 46 PR(  # rdb file
  foo1  foo2    foo3    foos
  ----  ----    ----    ----
  1     2.2     3       xxxx
  10    20.2    30      yyyy

  # multiple consecutive whitespace and dashes
  foo1   foo2    foo3 foos
  ---    ----    ---- ----
     1    2.2    3    xxxx
    10   20.2    30   yyyy

  # comma delims and blank lines
  foo1,foo2,foo3,foos

  1,2.2,3,xxxx
  10,20.2,30,yyyy

  # bar delims with null values
  foo1|foo2|foo3|foos
  1||3|xxxx
  10|20.2||yyyy

  # header-less data
  1     2.2   3 xxxx
  10    20.2 30 yyyy)RP(

)0 P(The default set of token delimiters consists of spaces, tabs, commas,
semi-colons, and vertical bars. Several parsers are used
simultaneously to analyze a line of text in different ways.  One way
of analyzing a line is to allow a combination of spaces, tabs, and
commas to be squashed into a single delimiter \201no null values between
consecutive delimiters\202. Another way is to allow tab, semi-colon, and
vertical bar delimiters to support null values, i.e. two consecutive
delimiters implies a null value \201e.g. RDB file\202.  A successful parser
is one which returns a consistent number of columns for all rows, with
each column having a consistent data type.  More than one parser can
be successful. For now, it is assumed that successful parsers all
return the same tokens for a given line. \201Theoretically, there are
pathological cases, which will be taken care of as needed\202. Bad parsers
are discarded on the fly.

)0 P(If the header does not exist, then names "col1", "col2", etc.  are
assigned to the columns to allow filtering.  Furthermore, data types
for each column are determined by the data types found in the columns
of the first data line, and can be one of the following: string, int,
and double. Thus, all of the above examples return the following
display:
) 4 58 PR(  fundisp foo'[foo1>5]'
        FOO1                  FOO2       FOO3         FOOS
  ---------- --------------------- ---------- ------------
          10           20.20000000         30         yyyy)RP(

)0 2 69 H(Comments)WB 138 Sn( Convert to Header Params)EH(

)0 P(Comments which precede data rows are converted into header parameters and
will be written out as such using funimage or funhead. Two styles of comments
are recognized:

)0 P(1. FITS-style comments have an equal sign "=" between the keyword and
value and an optional slash "/" to signify a comment. The strict FITS
rules on column positions are not enforced. In addition, strings only
need to be quoted if they contain whitespace. For example, the following
are valid FITS-style comments:

) 5 55 PR(  # fits0 = 100
  # fits1 = /usr/local/bin
  # fits2 = "/usr/local/bin /opt/local/bin"
  # fits3c = /usr/local/bin /opt/local/bin /usr/bin
  # fits4c = "/usr/local/bin /opt/local/bin" / path dir)RP(

Note that the fits3c comment is not quoted and therefore its value is the
single token "/usr/local/bin" and the comment is "opt/local/bin /usr/bin".
This is different from the quoted comment in fits4c.

)0 P(2. Free-form comments can have an optional colon separator between the
keyword and value. In the absence of quote, all tokens after the
keyword are part of the value, i.e. no comment is allowed. If a string
is quoted, then slash "/" after the string will signify a comment.
For example:

) 9 54 PR(  # com1 /usr/local/bin
  # com2 "/usr/local/bin /opt/local/bin"
  # com3 /usr/local/bin /opt/local/bin /usr/bin
  # com4c "/usr/local/bin /opt/local/bin" / path dir
  
  # com11: /usr/local/bin
  # com12: "/usr/local/bin /opt/local/bin"
  # com13: /usr/local/bin /opt/local/bin /usr/bin
  # com14c: "/usr/local/bin /opt/local/bin" / path dir)RP(
  
)0 P(Note that com3 and com13 are not quoted, so the whole string is part of
the value, while comz4c and com14c are quoted and have comments following
the values.

)0 P(Some text files have column name and data type information in the header.
You can specify the format of column information contained in the
header using the "hcolfmt=" specification. See below for a detailed
description.

)0 2 70 H(Multiple)WB 139 Sn( Tables in a Single File)EH(

)0 P( 
Multiple tables are supported in a single file. If an RDB-style file
is sensed, then a ^L \201vertical tab\202 will signify end of
table. Otherwise, an end of table is sensed when a new header \201i.e.,
all alphanumeric columns\202 is found. \201Note that this heuristic does not
work for single column tables where the column type is ASCII and the
table that follows also has only one column.\202 You also can specify
characters that signal an end of table condition using the )BD(eot=)ES(
keyword. See below for details.

)0 P(You can access the nth table \201starting from 1\202 in a multi-table file
by enclosing the table number in brackets, as with a FITS extension:

) 1 18 PR(  fundisp foo'[2]')RP(
The above example will display the second table in the file.
\201Index values start at 1 in oder to maintain logical compatibility
with FITS files, where extension numbers also start at 1\202.


)0 2 71 H(TEXT\201\202)WB 140 Sn( Specifier)EH(

)0 P(As with ARRAY\201\202 and EVENTS\201\202 specifiers for raw image arrays and raw
event lists respectively, you can use TEXT\201\202 on text files to pass
key=value options to the parsers. An empty set of keywords is
equivalent to not having TEXT\201\202 at all, that is:

) 2 23 PR(  fundisp foo
  fundisp foo'[TEXT\201\202]')RP(

are equivalent. A multi-table index number is placed before the TEXT\201\202
specifier as the first token, when indexing into a multi-table:

  fundisp foo'[2,TEXT\201...\202]'

)0 P(The filter specification is placed after the TEXT\201\202 specifier, separated
by a comma, or in an entirely separate bracket:

) 2 47 PR(  fundisp foo'[TEXT\201...\202,circle 512 512 .1]'
  fundisp foo'[2,TEXT\201...\202][circle 512 512 .1]')RP(

)0 2 72 H(Text\201\202)WB 141 Sn( Keyword Options)EH(

)0 P( 
The following is a list of keywords that can be used within the TEXT\201\202
specifier \201the first three are the most important\202:

)0 DL(
)0 P()0 DT( delims="[delims]"
)DD(Specify token delimiters for this file. Only a single parser having these
delimiters will be used to process the file.
) 2 40 PR(  fundisp foo.fits'[TEXT\201delims="!"\202]'
  fundisp foo.fits'[TEXT\201delims="\200t%"\202]')RP(

)0 P()0 DT( comchars="[comchars]"
)DD( Specify comment characters. You must include "\200n" to allow blank lines.
These comment characters will be used for all standard parsers \201unless delims
are also specified\202.
) 1 42 PR(  fundisp foo.fits'[TEXT\201comchars="!\200n"\202]')RP(

)0 P()0 DT( cols="[name1:type1 ...]"
)DD( Specify names and data type of columns. This overrides header
names and/or data types in the first data row or default names and
data types for header-less tables.
) 1 70 PR(  fundisp foo.fits'[TEXT\201cols="x:I,y:I,pha:I,pi:I,time:D,dx:E,dy:e"\202]')RP(
)0 P(If the column specifier is the only keyword, then the cols= is not
required \201in analogy with EVENTS\201\202\202:
) 1 63 PR(  fundisp foo.fits'[TEXT\201x:I,y:I,pha:I,pi:I,time:D,dx:E,dy:e\202]')RP(
Of course, an index is allowed in this case:
) 1 65 PR(  fundisp foo.fits'[2,TEXT\201x:I,y:I,pha:I,pi:I,time:D,dx:E,dy:e\202]')RP(

)0 P()0 DT( eot="[eot delim]"
)DD( Specify end of table string specifier for multi-table files. RDB
files support ^L. The end of table specifier is a string and the whole
string must be found alone on a line to signify EOT. For example:
) 1 37 PR(  fundisp foo.fits'[TEXT\201eot="END"\202]')RP(
will end the table when a line contains "END" is found. Multiple lines
are supported, so that:
) 1 43 PR(  fundisp foo.fits'[TEXT\201eot="END\200nGAME"\202]')RP(
will end the table when a line contains "END" followed by a line
containing "GAME".
)0 P(In the absence of an EOT delimiter, a new table will be sensed when a new
header \201all alphanumeric columns\202 is found.

)0 P()0 DT( null1="[datatype]"
)DD( Specify data type of a single null value in row 1.
Since column data types are determined by the first row, a null value
in that row will result in an error and a request to specify names and
data types using cols=. If you only have a one null in row 1, you don't
need to specify all names and columns. Instead, use null1="type" to
specify its data type.

)0 P()0 DT( alen=[n]
)DD(Specify size in bytes for ASCII type columns.
FITS binary tables only support fixed length ASCII columns, so a
size value must be specified. The default is 16 bytes.

)0 P()0 DT( nullvalues=["true"|"false"]
)DD(Specify whether to expect null values.
Give the parsers a hint as to whether null values should be allowed. The
default is to try to determine this from the data.

)0 P()0 DT( whitespace=["true"|"false"]
)DD( Specify whether surrounding white space should be kept as part of
string tokens.  By default surrounding white space is removed from
tokens.

)0 P()0 DT( header=["true"|"false"]
)DD(Specify whether to require a header.  This is needed by tables
containing all string columns \201and with no row containing dashes\202, in
order to be able to tell whether the first row is a header or part of
the data. The default is false, meaning that the first row will be
data. If a row dashes are present, the previous row is considered the
column name row.

)0 P()0 DT( units=["true"|"false"]
)DD(Specify whether to require a units line.
Give the parsers a hint as to whether a row specifying units should be
allowed. The default is to try to determine this from the data.

)0 P()0 DT( i2f=["true"|"false"]
)DD(Specify whether to allow int to float conversions.
If a column in row 1 contains an integer value, the data type for that
column will be set to int. If a subsequent row contains a float in
that same column, an error will be signaled. This flag specifies that,
instead of an error, the float should be silently truncated to
int. Usually, you will want an error to be signaled, so that you can
specify the data type using cols= \201or by changing the value of
the column in row 1\202.

)0 P()0 DT( comeot=["true"|"false"|0|1|2]
)DD(Specify whether comment signifies end of table.
If comeot is 0 or false, then comments do not signify end of table and
can be interspersed with data rows. If the value is true or 1 \201the
default for standard parsers\202, then non-blank lines \201e.g. lines
beginning with '#'\202 signify end of table but blanks are allowed
between rows. If the value is 2, then all comments, including blank
lines, signify end of table.

)0 P()0 DT( lazyeot=["true"|"false"]
)DD(Specify whether "lazy" end of table should be permitted \201default is
true for standard formats, except rdb format where explicit ^L is required
between tables\202. A lazy EOT can occur when a new table starts directly
after an old one, with no special EOT delimiter. A check for this EOT
condition is begun when a given row contains all string tokens. If, in
addition, there is a mismatch between the number of tokens in the
previous row and this row, or a mismatch between the number of string
tokens in the prev row and this row, a new table is assumed to have
been started. For example:
) 9 20 PR(  ival1 sval3
  ----- -----
  1     two
  3     four

  jval1 jval2 tval3
  ----- ----- ------
  10    20    thirty
  40    50    sixty)RP(
Here the line "jval1 ..." contains all string tokens.  In addition,
the number of tokens in this line \2013\202 differs from the number of
tokens in the previous line \2012\202. Therefore a new table is assumed
to have started. Similarly:
) 9 20 PR(  ival1 ival2 sval3
  ----- ----- -----
  1     2     three
  4     5     six

  jval1 jval2 tval3
  ----- ----- ------
  10    20    thirty
  40    50    sixty)RP(
Again, the line "jval1 ..." contains all string tokens. The number of
string tokens in the previous row \2011\202 differs from the number of
tokens in the current row\2013\202. We therefore assume a new table as been
started. This lazy EOT test is not performed if lazyeot is explicitly
set to false.

)0 P()0 DT( hcolfmt=[header column format]
)DD( Some text files have column name and data type information in the header.
For example, VizieR catalogs have headers containing both column names
and data types:
) 3 95 PR(  #Column e_Kmag  \201F6.3\202  ?\201k_msigcom\202 K total magnitude uncertainty \2014\202  [ucd=ERROR]
  #Column Rflg    \201A3\202    \201rd_flg\202 Source of JHK default mag \2016\202  [ucd=REFER_CODE]
  #Column Xflg    \201I1\202    [0,2] \201gal_contam\202 Extended source contamination \20110\202 [ucd=CODE_MISC])RP(

while Sextractor files have headers containing column names alone:

) 4 79 PR(  #   1 X_IMAGE         Object position along x                         [pixel]
  #   2 Y_IMAGE         Object position along y                         [pixel]
  #   3 ALPHA_J2000     Right ascension of barycenter \201J2000\202           [deg]
  #   4 DELTA_J2000     Declination of barycenter \201J2000\202               [deg])RP(
The hcolfmt specification allows you to describe which header lines
contain column name and data type information. It consists of a string 
defining the format of the column line, using "$col" \201or "$name"\202 to
specify placement of the column name, "$fmt" to specify placement of the
data format, and "$skip" to specify tokens to ignore. You also can
specify tokens explicitly \201or, for those users familiar with how
sscanf works, you can specify scanf skip specifiers using "%*"\202.
For example, the VizieR hcolfmt above might be specified in several ways:
) 3 67 PR(  Column $col \201$fmt\202    # explicit specification of "Column" string
  $skip  $col \201$fmt\202    # skip one token
  %*s $col  \201$fmt\202      # skip one string \201using scanf format\202)RP(
while the Sextractor format might be specified using:
) 2 59 PR(  $skip $col            # skip one token  
  %*d $col              # skip one int \201using scanf format\202)RP(
You must ensure that the hcolfmt statement only senses actual column
definitions, with no false positives or negatives.  For example, the
first Sextractor specification, "$skip $col", will consider any header
line containing two tokens to be a column name specifier, while the
second one, "%*d $col", requires an integer to be the first token. In
general, it is preferable to specify formats as explicitly as
possible.

)0 P(Note that the VizieR-style header info is sensed automatically by the
funtools standard VizieR-like parser, using the hcolfmt "Column $col
\201$fmt\202".  There is no need for explicit use of hcolfmt in this case.

)0 P()0 DT( debug=["true"|"false"]
)DD(Display debugging information during parsing.
)LD(

)0 2 73 H(Environment)WB 142 Sn( Variables)EH(

)0 P( 
Environment variables are defined to allow many of these TEXT\201\202 values to be
set without having to include them in TEXT\201\202 every time a file is processed:

) 10 36 PR(  keyword       environment variable
  -------       --------------------
  delims        TEXT_DELIMS
  comchars      TEXT_COMCHARS
  cols          TEXT_COLUMNS
  eot           TEXT_EOT
  null1         TEXT_NULL1
  alen          TEXT_ALEN
  bincols       TEXT_BINCOLS
  hcolfmt       TEXT_HCOLFMT)RP(

)0 2 74 H(Restrictions)WB 143 Sn( and Problems)EH(

)0 P( 
As with raw event files, the '+' \201copy extensions\202 specifier is not
supported for programs such as funtable.

)0 P(String to int and int to string data conversions are allowed by the
text parsers. This is done more by force of circumstance than by
conviction: these transitions often happens with VizieR catalogs,
which we want to support fully. One consequence of allowing these
transitions is that the text parsers can get confused by columns which
contain a valid integer in the first row and then switch to a
string. Consider the following table:
) 4 20 PR(  xxx   yyy     zzz
  ----  ----    ----
  111   aaa     bbb
  ccc   222     ddd)RP(
The xxx column has an integer value in row one a string in row two,
while the yyy column has the reverse. The parser will erroneously
treat the first column as having data type int:
) 5 38 PR(  fundisp foo.tab
         XXX          YYY          ZZZ
  ---------- ------------ ------------
         111        'aaa'        'bbb'
  1667457792        '222'        'ddd')RP(
while the second column is processed correctly. This situation can be avoided
in any number of ways, all of which force the data type of the first column
to be a string. For example, you can edit the file and explicitly quote the
first row of the column:
) 10 40 PR(  xxx   yyy     zzz
  ----  ----    ----
  "111" aaa     bbb
  ccc   222     ddd

  [sh] fundisp foo.tab
           XXX          YYY          ZZZ
  ------------ ------------ ------------
         '111'        'aaa'        'bbb'
         'ccc'        '222'        'ddd')RP(
You can edit the file and explicitly set the data type of the first column:
) 10 40 PR(  xxx:3A   yyy  zzz
  ------   ---- ----
  111      aaa  bbb
  ccc      222  ddd

  [sh] fundisp foo.tab
           XXX          YYY          ZZZ
  ------------ ------------ ------------
         '111'        'aaa'        'bbb'
         'ccc'        '222'        'ddd')RP(
You also can explicitly set the column names and data types of all columns,
without editing the file:
) 5 52 PR(  [sh] fundisp foo.tab'[TEXT\201xxx:3A,yyy:3A,zzz:3a\202]'
           XXX          YYY          ZZZ
  ------------ ------------ ------------
         '111'        'aaa'        'bbb'
         'ccc'        '222'        'ddd')RP(
The issue of data type transitions \201which to allow and which to disallow\202
is still under discussion.





)0 P()0 0 1 A(Go to Funtools Help Index)0 0 TN TL()Ec /AF f D(

)0 5 75 H(Last)WB 144 Sn( updated: August 3, 2007)EH(

)WB NL
/Cb Db D /Ct [16#00 16#00 16#00] D /Cl [16#00 16#00 16#00] D /CL -1 D Ct Sc
DS
/Ba f D /BO 0 D Bs
/UR (view.html) D
/Ti (Database View Support for Tables) D
/Au () D
/Df f D
/ME [()] D

0 BO R
()1 Sl()WB 48 Sn(


)0 2 76 H(Funview:)WB 146 Sn()WB 145 Sn( Database View Support for Tables)EA()EH(


)0 2 77 H(Summary)WB 147 Sn()EH(
)0 P(This document contains a summary of the options for utilizing
database-inspired Views of tables.


)0 2 78 H(Description)WB 148 Sn()EH(

)0 2 79 H(Database)WB 149 Sn( Views)EH(
)0 P(In database parlance, a )BD(View)ES( defines a "virtual table", i.e.,
a description of row and/or column selection filters \201but with no
permanent storage space allocated\202. When used in place of a table, a
View selects the specified rows and/or columns from one or more real
tables. Views enable you to see complicated data tables in a more
convenient format. They also can be used as a security mechanism, by
restricting user access to specific columns and/or rows.  [See:
) 1 72 PR(http://www.cs.unibo.it/~ciaccia/COURSES/RESOURCES/SQLTutorial/sqlch5.htm)RP(
for a good discussion of SQL Views.]

)0 P(Funtools supports an expanded notion of Views for all tabular data
\201FITS tables, raw binary tables, and ASCII column files\202. Funtools
Views allow you to pre-set values for the filter specification, the
columns to activate, and display format \201though the latter is for
fundisp only\202.  Setting the filter and column activation values
provides functionality equivalent to that of a classical database
View, while the ability to set the format is similar to classical
report writing capabilities.

)0 2 80 H(Funtools)WB 150 Sn( View Attributes)EH(
)0 P(A Funtools View is a text file containing one or more of the following
columns:
) 7 46 PR(  column         description
  ------         -----------------------------
  view           name of view
  file           data file name or template
  filter         filter specification
  columns        columns to activate
  format         fundisp format specification)RP( 
All of the attribute columns are optional, including
the )BD(view)ES( name itself. This means that a View can be named or
unnamed. Unnamed Views can refer to a specific file or a template of
files \201obviously if neither the view or the file column is specified,
the input View specification will never be used\202. You can specify any
combination of filter, column, and format parameters. \201It also is
possible to apply file-specific View to other files; see the discussion
on )BD(View Lists)ES( below\202. Each column has a size limit of 1024 characters.

)0 P(For example, consider the following View file:
) 13 70 PR(  view    file                    format  columns       filter
  ----    ----------------------  ------  ------------  -------
  x3      ${HOME}/data/snr.ev     I=%4d   x y pi pha    cir 512 512 .1 
  x2      ${HOME}/data/snr.ev             x y pi pha    cir 512 512 .1 
  x1      ${HOME}/data/snr.ev                           cir 512 512 .1 
  x1a     ${HOME}/data/snr.ev             x y pi pha
  x0      ${HOME}/data/snr.ev
  xf                              I=%4d
  xc                                      x y pi pha
  xr                                                    cir 512 512 .1
          *.ev                            x y pi pha
          *.fit                           x y dx dy     cir 400 400  3
          *.fits                  I=%3d   x y dx dy     cir 400 400  3)RP(
This database example is in rdb format, i.e. using tab delimiters and
permitting null values. Any valid ASCII table format is acceptable,
but if you use a format that does not permit null values, it will be
necessary to quote the null strings.

)0 P(The first five entries \201x3, x2, x1, x1a, x0\202 are named entries defining
default values specifically for the snr.ev data file. Typically, you
would use these Views by specifying View name, and the corresponding
file, filter, column, and format values would be used. Note that the x0
View is essentially an alias for the pathname of this file.

)0 P(The next three entries define defaults that can be applied to any
file.  You typically would use these View names in conjunction with
a specific file name \201see )BD(View Lists)ES( below\202 so that the associated
parameter\201s\202 were applied to that file.

)0 P(The last three entry in the database define unnamed Views that
pertains to all files ending with the specified templates. In these
cases, any View that specifies a file name matching the file template
would be processed with the associated parameter attributes.

)0 2 81 H(Invoking)WB 151 Sn( a Funtools View \201in Place of an Input File\202)EH(
)0 P(To use a Funtools View, you simply pre-pend the "v:" prefix to a View name or
a file name where an input file name usually is specified. For example:
) 1 14 PR(  fundisp v:x3)RP(
specifies that the View named x3 \201with its file name and associated
parameters\202 is processed as the input file to fundisp. Using the
example database, above, this is equivalent to:
) 1 73 PR(  fundisp  -f "I=%4d" ${HOME}/data/snr.ev'[cir 512 512 .1]'  "x y pi pha")RP(
That is, the format is used with fundisp's -f \201format\202 switch, while the
filename and extension are composed of the x3 View's filename and
region filter.

)0 P(Similarly, executing a command such as:
) 1 19 PR(  fundisp v:foo.fit)RP(
will match the unnamed View associated with the template "*.fit".
This is equivalent to executing:
) 1 46 PR(  fundisp foo.fit'[cir 400 400 3]' "x y dx dy")RP(
Of course, if you omit the "v:" prefix, then no View processing takes place:
) 2 66 PR(  fundisp foo.fit    # process foo.fit without any View parameters
  fundisp x3         # error \201assuming there is no file named x3\202)RP(

)0 2 82 H(Basic)WB 152 Sn( View Matching Rules)EH(

)0 P(When a "v:" prefix is recognized, Funtools searches for a View database
file in the following order:
) 5 59 PR(  location             description
  ------------         ------------------------------------
  FUN_VIEWFILE         environment variable \201any file name\202
  ./.funtools.vu       hidden file, default name
  $HOME/.funtools.vu   hidden file, default name)RP(
The first View database file located is used to construct a new
filename, as well as an activation column specification and a format
specification. The following rules are used:

)0 P(1. An attempt is made to match the input name \201i.e., the part of the
input View after the "v:" prefix\202 against the )BD(view)ES( column value
\201if present\202 of each row in the database. If a match is found, the
values of all non-blank columns are saved for later use.  Also note
that the first match terminates the search: i.e., )BD(the order of the
database rows matters)ES(.

)0 P(2. If no )BD(view)ES( match is made, an attempt is made to match the input
name against the )BD(file)ES( column value \201if present\202. Matching is
performed on the full pathname of both the input name and the
database file name, and on the non-directory \201root\202 part of these
files. This means that the root specification:
) 1 18 PR(  fundisp v:snr.ev)RP(
will match a row in the database that has a full pathname in the file,
allowing you to use a )BD(file)ES(-matched View without having to
specify the full pathname. In this example, the "v:snr.ev" View
specification will match the first row \201v:x3\202 in the database:
) 1 67 PR(  x3   ${HOME}/data/snr.ev     I=%4d   x y pi pha    cir 512 512 .1)RP(
even though the row contains a fully qualified pathname as the file
value. Once again, values of all non-blank columns are saved, and the
first match terminates the search.

)0 P(3. If neither a )BD(view)ES( or a )BD(view)ES( match has been found,
then a simple template match is attempted against the )BD(view)ES(
values. Template matching supports a simplified version of file
globbing \201not a regular expression\202, with support for a single "*"
\201all characters\202, "?" \201single character\202, or "[...]" \201range\202 specification.

)0 P(4. If no template match was found on the )BD(view)ES( column, then a
simple template match is attempted against the )BD(file)ES( columns.

)0 P(5. If no match is found, then the filename \201minus the "v:" prefix\202 is 
returned.

)0 2 83 H(More)WB 153 Sn( on View Matching Rules: Single vs. Multiple Matches )EH(

The matching rules described above stop after the first match,
regardless of whether that match provides values for all three
parameters \201filter, columns, and format\202. In cases where a )BD(view)ES(
or )BD(file)ES( match does not provide all three values, it is possible
that a template match might do so. With regard to the example View
database above, the x1 View provides only a filter, while omitting
both the format and columns values. But note that the final rows in
the database could provide the values via a template match on the
filename. This sort of multiple matching is especially valuable in
order to provide "global" values to several Views.

)0 P(Obviously, multiple matching might not be wanted in every
case. Therefore, we support both multiple matching and single matching
according to the value of the FUN_VIEWMATCH environment variable.  If
the FUN_VIEWMATCH environment variable exists and if its value begins
with "s", then a single match is used and missing parameters are not
filled in with subsequent template matches on the file name. That is,
matching rules above are followed exactly as explained above.  If the
value of this environment variable begins with "m" \201or does not exist\202,
then multiple matches are used to try to fill in missing parameters.
In this case, template matching always takes place and missing values are
taken from these template matches.

)0 P(Thus, in the example above, the View specification:
) 1 14 PR(  fundisp v:x1)RP(
will take the file name and filter value from the x1 View:
) 1 70 PR(  x1      ${HOME}/data/snr.ev                           cir 512 512 .1)RP(
The column value then will be taken from the "*.ev" file template match
against the x1 file name:
) 1 52 PR(          *.ev                            x y pi pha)RP(
Note once again that order is important: missing values are taken in the
order in which the template matches are processed.

)0 2 84 H(View)WB 154 Sn( Lists: Applying a View to Any File)EH(

)0 P(It is possible to apply a named View, or even several Views, to any
data file by appending a )BD(viewlist)ES( immediately after the standard "v:"
prefix. A viewlist takes the form:
) 1 15 PR(  :v1,v2,...vn:)RP(
where v1, v2, etc. are named Views. The two ":" colon characters surrounding
the list are required. Thus, the syntax for applying a viewlist to a file is:
) 1 34 PR(  v::view1,view2,...viewn:filename)RP(
Note that the name after the last ":" is assumed to be a file; it is
not permissible \201or sensible\202 to use a View name.

)0 P(For example, the View specification:
) 1 19 PR(  fundisp v::x2:foo)RP(
applies the x2 View to the file foo \201even if there is a View named foo\202
and \201in using our example database\202 is equivalent to:
) 1 45 PR(  ./fundisp foo'[cir 512 512 .1] "x y pi pha")RP(
The same command can be effected using a list of Views:
) 1 23 PR(  fundisp v::x1,x1a:foo)RP(

)0 P(What happens if a viewlist is used and the file also matches a
template? Consider, for example, this View specification:
) 1 23 PR(  fundisp v::x2:foo.fit)RP(
Here, the x2 View will supply filter and column values, while the
template *.fit can also supply \201different\202 filter and column
values. In this case, the explicitly specified Views of the viewlist
trump the matched view values.

)0 P(On the other hand, if a file template match can supply a View value
that is not supplied by the viewlist, then that value will be taken
from the file template match. For example:
) 1 24 PR(  fundisp v::x2:foo.fits)RP(
does not explicitly supply a format value, but the file match on *.fits
can and does. You can avoid supplying missing values using file template
matching by replacing the first ":" with a "-" in a viewlist
specification:
) 1 24 PR(  fundisp v:-x2:foo.fits)RP(
The use of ":+" to explicitly allow file template matching is also
supported, but is the same as the default case. Note that the nuances
of viewlist support are subject to change as our experience and
understanding grow.

)0 2 85 H(Overriding)WB 155 Sn( Values Associated with a View)EH(

)0 P(To override values associated with a View, simply supply the override
values in the correct place on the command line. Thus, given
the example database described above, the command:
) 1 14 PR(  fundisp v:x3)RP(
specifies that the View named x3, along with its file name and
associated parameters, be processed as the input file to fundisp in
this way:
) 1 73 PR(  fundisp  -f "I=%4d" ${HOME}/data/snr.ev'[cir 512 512 .1]'  "x y pi pha")RP(
To override one or more of these values, simply specify a new value
for the format, filter, or columns.  For example, if your input View file
contains a filter, then the View will use that filter as an override
of the View filter:
) 1 31 PR(  fundisp v:x3'[cir 400 400 3]')RP(
will use the columns and format of the x3 View but not the x3 filter. Further
examples are:
) 2 67 PR(  fundisp v:x3 "x y dx dy"    # activate a different set of columns
  fundisp -f "I=%3d" v:x3     # use a different format statement)RP(

)0 P(Note that extension names, extension index values, and other
non-filter specifications )BD(do not)ES( override the View
filter. Thus:
) 1 22 PR(  fundisp v:foo.fit[3])RP(
will still use the filter associated with the .fit template \201see above\202, since
the "3" is an extension index, not a filter.

)0 2 86 H(Environment)WB 156 Sn( Variables)EH(

The following environment variables are used by Funtools Views:
)0 DL()0 DT()BD(FUN_VIEWNAME)ES(
)DD( The )BD(FUN_VIEWNAME)ES( environment variable specifies the
name and location of the View database file. If not present, the
files ./.funtools.vu and $HOME/.funtools.vu are searched for, in
that order.

)0 DT()BD(FUN_VIEWMATCH)ES(
)DD( The )BD(FUN_VIEWMATCH)ES( environment variable specifies whether a
single match or multiple match algorithm is used to locate parameter
values. If the value of this environment variable begins with "s",
then a single match is used and missing parameters are not filled in
with subsequent template matches on the file name. If the value begins
with "m", then multiple matches are used to try to fill in missing 
parameters. The default is to use multiple matches.)LD(

)0 2 87 H(Restrictions)WB 157 Sn( and Problems)EH(

Support for overriding a filter \201while not overriding extension names,
extension indexes, etc.\202 requires that we can sense the presence of a
filter in a bracket specification. It is unclear yet whether our
algorithm is perfect.

)0 P()0 0 1 A(Go to Funtools Help Index)0 0 TN TL()Ec /AF f D(

)0 5 88 H(Last)WB 158 Sn( updated: August 3, 2007)EH(

)WB NL
/Cb Db D /Ct [16#00 16#00 16#00] D /Cl [16#00 16#00 16#00] D /CL -1 D Ct Sc
DS
/Ba f D /BO 0 D Bs
/UR (filters.html) D
/Ti (Table Filtering) D
/Au () D
/Df f D
/ME [()] D

0 BO R
()1 Sl()WB 52 Sn(


)0 2 89 H(Funfilters:)WB 165 Sn()WB 159 Sn( Filtering Rows in a Table)EA()EH(


)0 2 90 H(Summary)WB 166 Sn()EH(
)0 P(This document contains a summary of the user interface for 
filtering rows in binary tables.


)0 2 91 H(Description)WB 167 Sn()EH(
)0 P(Table filtering allows a program to select rows from an table \201e.g.,
X-ray event list\202 by checking each row against one or more expressions
involving the columns in the table. When a table is filtered, only
valid rows satisfying these expressions are passed through for processing.

)0 P(A filter expression is specified using bracket notation appended to
the filename of the data being processed:
) 1 23 PR(  foo.fits[pha==1&)SY(\160)ES(==2])RP(
It is also possible to put region specification inside a file and
then pass the filename in bracket notation:
) 1 19 PR(  foo.fits[@my.reg])RP(
Filters must be placed after the extension and image section
information, when such information is present. The correct order is:
)UL()-1 LI( file[fileinfo,sectioninfo][filters]
)-1 LI( file[fileinfo,sectioninfo,filters])LU(
where:
)UL()-1 LI( )BD(file)ES( is the Funtools file name
)-1 LI( )BD(fileinfo)ES( is an ARRAY, EVENT, FITS extension, or FITS index
)-1 LI( )BD(sectioninfo)ES( is the image section to extract
)-1 LI( )BD(filters)ES( are spatial region and table \201row\202 filters to apply)LU(
See )0 42 1 A(Funtools Files)42 0 TN TL()Ec /AF f D( for more information
on file and image section specifications.

)0 2 92 H(Filter)WB 168 Sn( Expressions)EH(

)0 P(Table filtering can be performed on columns of data in a FITS
binary table or a raw event file.  Table filtering is accomplished by
means of )BD(table filter specifications)ES(.  An table filter
specification consists of one or more )BD(filter expressions)ES( Filter
specifications also can contain comments and local/global processing
directives.

)0 P(More specifically, a filter specification consist of one or more lines
containing:
) 13 75 PR(  # comment until end of line
  # include the following file in the table descriptor
  @file
  # each row expression can contain filters separated by operators
  [filter_expression] BOOLOP [filter_expression2], ...
  # each row expression can contain filters separated by the comma operator
  [filter_expression1], [filter_expression2], ...
  # the special row# keyword allows a range of rows to be processed
  row#=m:n
  # or a single row
  row#=m
  # regions are supported -- but are described elsewhere
  [spatial_region_expression])RP(

)0 P(A single filter expression consists of an arithmetic, logical, or
other operations involving one or more column values from a
table. Columns can be compared to other columns, to header values,
or to numeric constants. Standard math functions can be applied to
columns. Separate filter expressions can be combined using boolean operators.
Standard C semantics can be used when constructing expressions, with
the usual precedence and associativity rules holding sway:
) 15 55 PR(  Operator                                Associativity
  --------                                -------------
  \201\202                                      left to right
  !! \201logical not\202                        right to left
  !  \201bitwise not\202 - \201unary minus\202        right to left
  *  /                                    left to right
  +  -                                    left to right
  < <= > >=                               left to right
  == !=                                   left to right
  &  \201bitwise and\202                        left to right
  ^  \201bitwise exclusive or\202               left to right
  |  \201bitwise inclusive or\202               left to right
  && \201logical and\202                        left to right
  || \201logical or\202                         left to right
  =                                       right to left)RP(
For example, if energy and pha are columns in a table, 
then the following are valid expressions:
) 4 24 PR(  pha>1
  energy == pha
  \201pha>1\202 && \201energy<=2\202
  max\201pha,energy\202>=2.5)RP(

)0 P(Comparison values can be integers or floats. Integer comparison values can be
specified in decimal, octal \201using '0' as prefix\202, hex \201using '0x' as prefix\202
or binary \201using '0b' as prefix\202. Thus, the following all specify the same
comparison test of a status mask:
) 4 40 PR(  \201status & 15\202 == 8           # decimal
  \201status & 017\202 == 010        # octal
  \201status & 0xf\202 == 0x8        # hex
  \201status & 0b1111\202 == 0b1000  # binary)RP(
)0 P(The special keyword row# allows you to process a range of rows.
When row# is specified, the filter code skips to the designated
row  and only processes the specified number of rows. The
"*" character can be utilized as the high limit value to denote
processing of the remaining rows. Thus:
) 1 14 PR(  row#=100:109)RP(
processes 10 rows, starting with row 100 \201counting from 1\202,
while:
) 1 12 PR(  row#=100:*)RP(
specifies that all but the first 99 rows are to be processed.

)0 P(Spatial region filtering allows a program to select regions of an
image or rows of a table \201e.g., X-ray events\202 using simple geometric
shapes and boolean combinations of shapes.  For a complete description
of regions, see )0 54 1 A(Spatial Region Filtering)54 0 TN TL()Ec /AF f D(.

)0 2 93 H(Separators)WB 169 Sn()WB 160 Sn( Also Are Operators)EA()EH(
)0 P(As mentioned previously, multiple filter expressions can be specified
in a filter descriptor, separated by commas or new-lines.
When such a comma or new-line separator is used, the boolean AND operator
is automatically generated in its place. Thus and expression such as:
) 1 15 PR(  pha==1,pi=2:4)RP(
is equivalent to:
) 1 26 PR(  \201pha==1\202 && \201pi>=2&)SY(\160)ES(<=4\202)RP(
)0 P([Note that the behavior of separators is different for filter expressions
and spatial region expressions.  The former uses AND as the operator, while
the latter user OR. See
)0 60 1 A(Combining Region and Table Filters)60 0 TN TL()Ec /AF f D(
for more information about these conventions and how they are treated
when combined.]

)0 2 94 H(Range)WB 170 Sn()WB 161 Sn( Lists)EA()EH()0 P( 
)0 P(Aside from the standard C syntax, filter expressions can make use of
IRAF-style )BD(range lists)ES( which specify a range of values. The
syntax requires that the column name be followed by an '=' sign, which
is followed by one or more comma-delimited range expressions of the form:
) 4 52 PR(  col = vv              # col == vv in range
  col = :vv             # col <= vv in range
  col = vv:             # col >= vv in range
  col = vv1:vv2         # vv1 <= col <= vv2 in range)RP(
The vv's above must be numeric constants; the right hand side of a
range list cannot contain a column name or header value.
)0 P(Note that, unlike an ordinary comma separator, the comma separator used
between two or more range expressions denotes OR.  Thus, when two or
more range expressions are combined with a comma separator, the resulting
expression is a shortcut for more complicated boolean logic. For example:
) 1 18 PR(  col = :3,6:8,10:)RP(
is equivalent to:
) 1 47 PR(  \201col<=3\202 || \201col>=6 && col <=8\202 || \201col >=10\202)RP(
Note also that the single-valued rangelist:
) 1 11 PR(  col = val)RP(
is equivalent to the C-based filter expression:
) 1 12 PR(  col == val)RP(
assuming, of course, that val is a numeric constant.

)0 2 95 H(Math)WB 171 Sn()WB 162 Sn( Operations and Functions)EA()EH()0 P( 
)0 P(It is permissible to specify C math functions as part of the filter syntax.
When the filter parser recognizes a function call, it automatically
includes the math.h and links in the C math library.  Thus, it is
possible to filter rows by expressions such as these:
)UL()-1 LI(\201pi+pha\202>\2012+log\201pi\202-pha\202
)-1 LI( min\201pi,pha\202*14>x
)-1 LI( max\201pi,pha\202==\201pi+1\202
)-1 LI( feq\201pi,pha\202
)-1 LI( div\201pi,pha\202>0)LU(
The function feq\201a,b\202 returns true \2011\202 if the difference between a and b
\201taken as double precision values\202 is less than approximately 10E-15.
The function div\201a,b\202 divides a by b, but returns NaN \201not a number\202
if b is 0. It is a safe way to avoid floating point errors when
dividing one column by another.

)0 2 96 H(Include)WB 172 Sn()WB 163 Sn( Files)EA()EH()0 P( 
)0 P(The special )BD(@filename)ES( directive specifies an include file
containing filter expressions. This file is processed as part of
the overall filter descriptor:
) 1 23 PR(  foo.fits[pha==1,@foo])RP(

)0 2 97 H(Header)WB 173 Sn()WB 164 Sn( Parameters)EA()EH()0 P( 
)0 P(The filter syntax supports comparison between a column value and a
header parameter value of a FITS binary tables \201raw event files have no
such header\202.  The header parameters can be taken from the binary
table header or the primary header.  For example, assuming there is a
header value MEAN_PHA in one of these headers, you can select photons
having exactly this value using:

)UL()-1 LI( pha==MEAN_PHA)LU(

)0 2 98 H(Examples)WB 174 Sn()EH(
)0 P(Table filtering is more easily described by means of examples.
Consider data containing the following table structure:
)UL()-1 LI( double TIME
)-1 LI( int X
)-1 LI( int Y
)-1 LI( short PI
)-1 LI( short PHA
)-1 LI( int DX
)-1 LI( int DY)LU(

)0 P(Tables can be filtered on these columns using IRAF/QPOE range syntax or
any valid C syntax.  The following examples illustrate the possibilities:
)0 DL(
)0 P()0 DT( pha=10
)0 DT( pha==10
)DD( select rows whose pha value is exactly 10

)0 P()0 DT( pha=10:50
)DD( select rows whose pha value is in the range of 10 to 50

)0 P()0 DT( pha=10:50,100
)DD( select rows whose pha value is in the range of 10 to 50 or is
equal to 100

)0 P()0 DT( pha>=10 && pha<=50
)DD( select rows whose pha value is in the range of 10 to 50

)0 P()0 DT( pi=1,2&&pha>3
)DD( select rows whose pha value is 1 or 2 and whose pi value is 3

)0 P()0 DT( pi=1,2 || pha>3
)DD( select rows whose pha value is 1 or 2 or whose pi value is 3

)0 P()0 DT( pha==pi+1
)DD( select rows whose pha value is 1 less than the pi value

)0 P()0 DT( \201pha==pi+1\202 && \201time>50000.0\202
)DD( select rows whose pha value is 1 less than the pi value
and whose time value is greater than 50000

)0 P()0 DT(\201pi+pha\202>20
)DD( select rows in which the sum of the pi and pha values is greater
than 20

)0 P()0 DT( pi%2==1
)DD( select rows in which the pi value is odd)LD(

)0 P(Currently, integer range list limits cannot be specified in binary
notation \201use decimal, hex, or octal instead\202. Please contact us if
this is a problem.





)0 P()0 0 1 A(Go to Funtools Help Index)0 0 TN TL()Ec /AF f D(

)0 5 99 H(Last)WB 175 Sn( updated: November 17, 2005)EH(

)WB NL
/Cb Db D /Ct [16#00 16#00 16#00] D /Cl [16#00 16#00 16#00] D /CL -1 D Ct Sc
DS
/Ba f D /BO 0 D Bs
/UR (idx.html) D
/Ti (Table Filtering with Indexes) D
/Au () D
/Df f D
/ME [()] D

0 BO R
()1 Sl()WB 53 Sn(


)0 2 100 H(Funidx:)WB 177 Sn()WB 176 Sn( Using Indexes to Filter Rows in a Table)EA()EH(


)0 2 101 H(Summary)WB 178 Sn()EH(
)0 P(This document contains a summary of the user interface for 
filtering rows in binary tables with indexes.


)0 2 102 H(Description)WB 179 Sn()EH(
)0 P(Funtools )0 52 1 A(Table Filtering)52 0 TN TL()Ec /AF f D( allows rows in a
table to be selected based on the values of one or more columns in the
row. Because the actual filter code is compiled on the fly, it is very
efficient. However, for very large files \201hundreds of Mb or larger\202,
evaluating the filter expression on each row can take a long time. Therefore,
funtools supports index files for columns, which are used automatically during
filtering to reduce dramatically the number of row evaluations performed.
The speed increase for indexed filtering can be an order of magnitude or
more, depending on the size of the file.

)0 P(The )0 11 1 A(funindex)11 0 TN TL()Ec /AF f D( program creates an
index on one or more columns in a binary table. For example, to create an index
for the column pi in the file huge.fits, use:
) 1 23 PR(  funindex huge.fits pi)RP(
This will create an index named huge_pi.idx.

)0 P(When a filter expression is initialized for row evaluation, funtools
looks for an index file for each column in the filter expression. If
found, and if the file modification date of the index file is later
than that of the data file, then the index will be used to reduce the
number of rows that are evaluated in the filter. When 
)0 54 1 A(Spatial Region Filtering)54 0 TN TL()Ec /AF f D( is part of the
expression, the columns associated with the region are checked for index
files.

)0 P(If an index file is not available for a given column, then in general,
all rows must be checked when that column is part of a filter
expression.  This is not true, however, when a non-indexed column is
part of an AND expression. In this case, only the rows that pass the
other part of the AND expression need to be checked. Thus, in some cases,
filtering speed can increase significantly even if all columns are not
indexed.

)0 P(Also note that certain types of filter expression syntax cannot make
use of indices. For example, calling functions with column names as
arguments implies that all rows must be checked against the function
value. Once again, however, if this function is part of an AND
expression, then a significant improvement in speed still is possible
if the other part of the AND expression is indexed.

)0 P(For example, note below the dramatic speedup in searching a 1 Gb
file using an AND filter, even when one of the columns \201pha\202 has no
index:

) 49 69 PR(  time fundisp \200
  huge.fits'[idx_activate=0,idx_debug=1,pha=2348&&cir 4000 4000 1]' \200
  "x y pha"
          x           y        pha                                   
 ---------- ----------- ----------                                    
    3999.48     4000.47       2348
    3999.48     4000.47       2348
    3999.48     4000.47       2348
    3999.48     4000.47       2348
    3999.48     4000.47       2348
    3999.48     4000.47       2348
    3999.48     4000.47       2348
    3999.48     4000.47       2348
    3999.48     4000.47       2348
    3999.48     4000.47       2348
    3999.48     4000.47       2348
    3999.48     4000.47       2348
    3999.48     4000.47       2348
    3999.48     4000.47       2348
    3999.48     4000.47       2348
    3999.48     4000.47       2348
    42.36u 13.07s 6:42.89 13.7%

  time fundisp \200
  huge.fits'[idx_activate=1,idx_debug=1,pha=2348&&cir 4000 4000 1]' \200
  "x y pha"
          x           y        pha                                    
 ---------- ----------- ----------                                    
 idxeq: [INDEF]                                   
 idxand sort: x[ROW 8037025:8070128] y[ROW 5757665:5792352]             
 idxand\2011\202: INDEF [IDX_OR_SORT]                                   )WR(
 idxall\2011\202: [IDX_OR_SORT]                                   
    3999.48     4000.47       2348
    3999.48     4000.47       2348
    3999.48     4000.47       2348
    3999.48     4000.47       2348
    3999.48     4000.47       2348
    3999.48     4000.47       2348
    3999.48     4000.47       2348
    3999.48     4000.47       2348
    3999.48     4000.47       2348
    3999.48     4000.47       2348
    3999.48     4000.47       2348
    3999.48     4000.47       2348
    3999.48     4000.47       2348
    3999.48     4000.47       2348
    3999.48     4000.47       2348
    3999.48     4000.47       2348
    1.55u 0.37s 1:19.80 2.4%)RP(

When all columns are indexed, the increase in speed can be even more dramatic:
) 50 67 PR(  time fundisp \200
  huge.fits'[idx_activate=0,idx_debug=1,pi=770&&cir 4000 4000 1]' \200
  "x y pi"
          x           y         pi                                    
 ---------- ----------- ----------                                    
    3999.48     4000.47        770
    3999.48     4000.47        770
    3999.48     4000.47        770
    3999.48     4000.47        770
    3999.48     4000.47        770
    3999.48     4000.47        770
    3999.48     4000.47        770
    3999.48     4000.47        770
    3999.48     4000.47        770
    3999.48     4000.47        770
    3999.48     4000.47        770
    3999.48     4000.47        770
    3999.48     4000.47        770
    3999.48     4000.47        770
    3999.48     4000.47        770
    3999.48     4000.47        770
    42.60u 12.63s 7:28.63 12.3%

  time fundisp \200
  huge.fits'[idx_activate=1,idx_debug=1,pi=770&&cir 4000 4000 1]' \200
  "x y pi"
          x           y         pi                                    
 ---------- ----------- ----------                                    
 idxeq: pi start=9473025,stop=9492240 => pi[ROW 9473025:9492240]          
 idxand sort: x[ROW 8037025:8070128] y[ROW 5757665:5792352]               
 idxor sort/merge: pi[ROW 9473025:9492240] [IDX_OR_SORT]                   )WR(
 idxmerge\2015\202: [IDX_OR_SORT] pi[ROW]                                   
 idxall\2011\202: [IDX_OR_SORT]                                   
    3999.48     4000.47        770
    3999.48     4000.47        770
    3999.48     4000.47        770
    3999.48     4000.47        770
    3999.48     4000.47        770
    3999.48     4000.47        770
    3999.48     4000.47        770
    3999.48     4000.47        770
    3999.48     4000.47        770
    3999.48     4000.47        770
    3999.48     4000.47        770
    3999.48     4000.47        770
    3999.48     4000.47        770
    3999.48     4000.47        770
    3999.48     4000.47        770
    3999.48     4000.47        770
    1.67u 0.30s 0:24.76 7.9%)RP(

)0 P(The miracle of indexed filtering \201and indeed, of any indexing\202 is the
speed of the binary search on the index, which is of order log2\201n\202
instead of n. \201The funtools binary search method is taken from
http://www.tbray.org/ongoing/When/200x/2003/03/22/Binary, to whom
grateful acknowledgement is made.\202  This means that the larger the
file, the better the performance. Conversely, it also means that for
small files, using an index \201and the overhead involved\202 can slow
filtering down somewhat. Our tests indicate that on a file containing
a few tens of thousands of rows, indexed filtering can be 10 to 20
percent slower than non-indexed filtering. Of course, your mileage
will vary with conditions \201disk access speed, amount of available
memory, process load, etc.\202

)0 P(Any problem encountered during index processing will result in
indexing being turned off, and replaced by filtering all rows. You can turn
filtering off manually by setting the idx_activate variable to 0 \201in a filter
expression\202 or the FILTER_IDX_ACTIVATE environment variable to 0 \201in the global
environment\202. Debugging output showing how the indexes are being processed can
be displayed to stderr by setting the idx_debug variable to 1 \201in a filter
expression\202 or the FILTER_IDX_DEBUG environment variable to 1 \201in the global
environment\202.

)0 P(Currently, indexed filtering only works with FITS binary tables and raw
event files. It does not work with text files. This restriction might be
removed in a future release.





)0 P()0 0 1 A(Go to Funtools Help Index)0 0 TN TL()Ec /AF f D(

)0 5 103 H(Last)WB 180 Sn( updated: August 3, 2007)EH(

)WB NL
/Cb Db D /Ct [16#00 16#00 16#00] D /Cl [16#00 16#00 16#00] D /CL -1 D Ct Sc
DS
/Ba f D /BO 0 D Bs
/UR (regions.html) D
/Ti (Spatial Region Filtering) D
/Au () D
/Df f D
/ME [()] D

0 BO R
()1 Sl()WB 54 Sn(


)0 2 104 H(Regions:)WB 182 Sn()WB 181 Sn( Spatial Region Filtering)EA()EH(


)0 2 105 H(Summary)WB 183 Sn()EH(
)0 P(This document contains a summary of the user interface for spatial
region filtering images and tables.


)0 2 106 H(Description)WB 184 Sn()EH(
)0 P(Spatial region filtering allows a program to select regions of an
image or rows of a table \201e.g., X-ray events\202 to process using
simple geometric shapes and boolean combinations of shapes.  When an
image is filtered, only pixels found within these shapes are
processed. When a table is filtered, only rows found within these
shapes are processed.

)0 P(Spatial region filtering for images and tables is accomplished by
means of )BD(region specifications)ES(.  A region specification
consists of one or more )BD(region expressions)ES(, which are geometric
shapes,combined according to the rules of boolean algebra.  Region
specifications also can contain comments and local/global processing
directives.

)0 P(Typically, region specifications are specified using bracket notation
appended to the filename of the data being processed:
) 1 31 PR(  foo.fits[circle\201512,512,100\202])RP(
It is also possible to put region specification inside a file and
then pass the filename in bracket notation:
) 1 19 PR(  foo.fits[@my.reg])RP(

)0 P(When region filters are passed in bracket notation in this manner, the
filtering is set up automatically when the file is opened and all
processing occurs through the filter. Programs also can use the filter
library API to open filters explicitly.

)0 2 107 H(Region)WB 185 Sn( Expressions)EH(

More specifically, region specifications consist of one or more lines
containing:
) 9 68 PR(  # comment until end of line
  global   keyword=value keyword=value  ... # set global value\201s\202
  # include the following file in the region descriptor
  @file
  # use the FITS image as a mask \201cannot be used with other regions\202
  @fitsimage
  # each region expression contains shapes separated by operators
  [region_expression1], [region_expression2], ...
  [region_expression], [region_expression], ...)RP(

)0 P(A single region expression consists of:
) 8 72 PR(  # parens and commas are optional, as is the + sign
  [+-]shape\201num , num , ...\202 OP1 shape num num num OP2 shape ...

e.g.:

  \201[+-]shape\201num , num , ...\202 && shape num  num || shape\201num, num\202
  # a comment can come after a region -- reserved for local properties
  [+-]shape\201num , num , ...\202  # local properties go here, e.g. color=red)RP(

)0 P(Thus, a region descriptor consists of one or more )BD(region
expressions)ES( or )BD(regions)ES(, separated by comas, new-lines, or
semi-colons.  Each )BD(region)ES( consists of one or more )BD(geometric
shapes)ES( combined using standard boolean operation.  Several types
of shapes are supported, including:

) 11 57 PR(  shape:        arguments:
  -----         ----------------------------------------
  ANNULUS       xcenter ycenter inner_radius outer_radius
  BOX           xcenter ycenter xwidth yheight \201angle\202
  CIRCLE        xcenter ycenter radius
  ELLIPSE       xcenter ycenter xwidth yheight \201angle\202
  FIELD         none
  LINE          x1 y1 x2 y2
  PIE           xcenter ycenter angle1 angle2
  POINT         x1 y1
  POLYGON       x1 y1 x2 y2 ... xn yn)RP(

)0 P(In addition, the following regions accept )BD(accelerator)ES( syntax:

) 13 73 PR(  shape      arguments
  -----      ------------------------------------------
  ANNULUS    xcenter ycenter radius1 radius2 ... radiusn
  ANNULUS    xcenter ycenter inner_radius outer_radius n=[number]
  BOX        xcenter ycenter xw1 yh1 xw2 yh2 ... xwn yhn \201angle\202
  BOX        xcenter ycenter xwlo yhlo xwhi yhhi n=[number] \201angle\202
  CIRCLE     xcenter ycenter r1 r2 ... rn              # same as annulus
  CIRCLE     xcenter ycenter rinner router n=[number]  # same as annulus
  ELLIPSE    xcenter ycenter xw1 yh1 xw2 yh2 ... xwn yhn \201angle\202
  ELLIPSE    xcenter ycenter xwlo yhlo xwhi yhhi n=[number] \201angle\202
  PIE        xcenter ycenter angle1 angle2 \201angle3\202 \201angle4\202 \201angle5\202 ...
  PIE        xcenter ycenter angle1 angle2 \201n=[number]\202
  POINT      x1 y1 x2 y2 ... xn yn)RP(
Note that the circle accelerators are simply aliases for the annulus
accelerators.  See )0 55 1 A(region geometry)55 0 TN TL()Ec /AF f D(
for more information about accelerators.

)0 P(Finally, the following are combinations of pie with different shapes
\201called "panda" for "Pie AND Annulus"\202 allow for easy specification of
radial sections:

) 6 75 PR(  shape:  arguments:
  -----   ---------
  PANDA   xcen ycen ang1 ang2 nang irad orad nrad   # circular
  CPANDA  xcen ycen ang1 ang2 nang irad orad nrad   # circular
  BPANDA  xcen ycen ang1 ang2 nang xwlo yhlo xwhi yhhi nrad \201ang\202 # box
  EPANDA  xcen ycen ang1 ang2 nang xwlo yhlo xwhi yhhi nrad \201ang\202 # ellipse)RP(

The panda and cpanda specify combinations of annulus and circle with pie,
respectively and give identical results. The bpanda combines box and pie,
while epanda combines ellipse and pie.
See )0 55 1 A(region geometry)55 0 TN TL()Ec /AF f D(
for more information about pandas.

)0 P(The following "shapes" are ignored by funtools \201generated by ds9\202:
) 8 62 PR(  shape:        arguments:
  -----         ---------
  PROJECTION    x1 y1 x2 y2 width    # NB: ignored by funtools
  RULER         x1 y1 x2 y2          # NB: ignored by funtools
  TEXT          x y                  # NB: ignored by funtools
  GRID                               # NB: ignored by funtools
  TILE                               # NB: ignored by funtools
  COMPASS                            # NB: ignored by funtools)RP(

)0 P(All arguments to regions are real values; integer values are
automatically converted to real where necessary.  All angles are in
degrees and run from the positive image x-axis to the positive image
y-axis. If a rotation angle is part of the associated WCS header, that
angle is added implicitly as well.

)0 P(Note that 3-letter abbreviations are supported for all shapes, so that
you can specify "circle" or "cir".

)0 P()0 2 108 H(Columns)WB 186 Sn( Used in Region Filtering)EH(
)0 P(By default, the x,y values in a region expression refer to the two
"image binning" columns, i.e. the columns that would be used to
bin the data into an image. For images, these are just the 2 dimensions
of the image. For tables, these usually default to x and y but
can be changed as required. For example, in Funtools, new binning
columns are specified using a bincols=\201col1,col2\202 statement within
the bracket string on the command line.
)0 P(Alternate columns for region filtering can be specified by the syntax:
) 1 25 PR(  \201col1,col2\202=region\201...\202)RP(
e.g.:
) 3 34 PR(  \201X,Y\202=annulus\201x,y,ri,ro\202
  \201PHA,PI\202=circle\201x,y,r\202
  \201DX,DY\202=ellipse\201x,y,a,b[,angle]\202)RP(

)0 P()0 2 109 H(Region)WB 187 Sn( Algebra)EH(

\201See also )0 56 1 A(Region Algebra)56 0 TN TL()Ec /AF f D( for more complete
information.\202

)0 P(Region shapes can be combined together using Boolean operators:
) 6 72 PR(  Symbol        Operation       Use
  --------      ---------       -----------------------------------
  !             not             Exclude this shape from this region
  & or &&       and             Include only the overlap of these shapes
  | or ||       inclusive or    Include all of both shapes
  ^             exclusive or    Include both shapes except their overlap)RP(
Note that the !region syntax must be combined with another region in order
that we be able to assign a region id properly. That is,
) 1 21 PR(  !circle\201512,512,10\202)RP(
is not a legal region because there is no valid region id to work with.
To get the full field without a circle, combine the above with field\201\202,
as in:
) 1 32 PR(  field\201\202 && !circle\201512,512,10\202)RP(

)0 2 110 H()WB 188 Sn( Region Separators Also Are Operators)EH(

)0 P(As mentioned previously, multiple region expressions can be specified
in a region descriptor, separated by commas, new-lines, or
semi-colons.  When such a separator is used, the boolean OR operator
is automatically generated in its place but, unlike explicit use of
the OR operator, the region ID is incremented \201starting from 1\202.

)0 P(For example, the two shapes specified in this example are given the
same region value:
) 1 50 PR(  foo.fits[circle\201512,512,10\202||circle\201400,400,20\202])RP(
On the other hand, the two shapes defined in the following example are
given different region values:
) 1 49 PR(  foo.fits[circle\201512,512,10\202,circle\201400,400,20\202])RP(

)0 P(Of course these two examples will both mask the same table rows or
pixels. However, in programs that distinguish region id's \201such as
)0 5 1 A(funcnts)5 0 TN TL()Ec /AF f D( \202, they will act
differently.  The explicit OR operator will result in one region
expression consisting of two shapes having the same region id and
funcnts will report a single region. The comma operator will cause
funcnts to report two region expressions, each with one shape, in
its output.

)0 P(In general, commas are used to separate region expressions entered
in bracket notation on the command line:
) 2 57 PR(  # regions are added to the filename in bracket notation
  foo.fits[circle\201512,512,100\202,circle\201400,400,20\202])RP(
New-lines are used to separate region
expressions in a file:
) 4 58 PR(  # regions usually are separated by new-lines in a file
  # use @filename to include this file on the command line
  circle\201512,512,100\202
  circle\201400,400,20\202)RP(
Semi-colons are provided for backward compatibility with the original
IRAF/PROS implementation and can be used in either case.

)0 P(If a pixel is covered by two different regions expressions, it is
given the mask value of the )BD(first)ES( region that contains that
pixel.  That is, successive regions )BD(do not)ES( overwrite previous
regions in the mask, as was the case with the original PROS regions.
In this way, an individual pixel is covered by one and only one
region.  This means that one must sometimes be careful about the order
in which regions are defined.  If region N is fully contained within
region M, then N should be defined )BD(before)ES( M, or else it will be
"covered up" by the latter.

)0 2 111 H(Region)WB 189 Sn( Exclusion)EH(
)0 P(Shapes also can be globally excluded from all the region specifiers in
a region descriptor by using a minus sign before a region:

) 4 73 PR(  operator      arguments:
  --------      -----------
  -             Globally exclude the region expression following '-' sign
                from ALL regions specified in this file)RP(
The global exclude region can be used by itself; in such a case, field\201\202 is
implied.

)0 P(A global exclude differs from the local exclude \201i.e. a shape prefixed
by the logical not "!" symbol\202 in that global excludes are logically
performed last, so that no region will contain pixels from a globally
excluded shape. A local exclude is used in a boolean expression with
an include shape, and only excludes pixels from that include shape.
Global excludes cannot be used in boolean expressions.

)0 2 112 H(Include)WB 190 Sn( Files)EH(

)0 P(The )BD(@filename)ES( directive specifies an include file
containing region expressions. This file is processed as part of
the overall region descriptor:
) 1 35 PR(  foo.fits[circle\201512,512,10\202,@foo])RP(
A filter include file simply includes text without changing the state
of the filter. It therefore can be used in expression. That is, if the
file foo1 contains "pi==1" and foo2 contains "pha==2" then
the following expressions are equivalent:
) 3 57 PR(  "[@foo1&&@foo2]"   is equivalent to   "[pi==1&&pha==2]"
  "[pha==1||@foo2]"  is equivalent to   "[pi==1||pha==2]"
  "[@foo1,@foo2]"    is equivalent to   "[pi==1,pha==2]")RP(
Be careful that you specify evaluation order properly using
parenthesis, especially if the include file contains multiple
filter statements. For example, consider a file containing two
regions such as:
) 2 19 PR(  circle 512 512 10
  circle 520 520 10)RP(
If you want to include only events \201or pixels\202 that are in these regions
and have a pi value of 4, then the correct syntax is:
) 1 17 PR(    pi==4&&\201@foo\202)RP(
since this is equivalent to:
) 1 53 PR(    pi==4 && \201circle 512 512 10 || circle 520 520 10\202)RP(
If you leave out the parenthesis, you are filtering this statement:
) 1 52 PR(    pi==4 && circle 512 512 10 || circle 520 520 10\202)RP(
which is equivalent to:
) 1 54 PR(    \201pi==4 && circle 512 512 10\202 || circle 520 520 10\202)RP(
The latter syntax only applies the pi test to the first region.

)0 P(For image-style filtering, the )BD(@filename)ES( can specify an 8-bit
or 16-bit FITS image. In this case, the pixel values in the mask image
are used as the region mask. The valid pixels in the mask must have
positive values.  Zero values are excluded from the mask and negative
values are not allowed.  Moreover, the region id value is taken as
the image pixel value and the total number of regions is taken to be
the highest pixel value. The dimensions of the image mask must be less
than or equal to the image dimensions of the data. The mask will be
replicated as needed to match the size of the image. \201Thus, best
results are obtained when the data dimensions are an even multiple of
the mask dimensions.\202

)0 P(An image mask can be used in any image filtering operation, regardless
of whether the data is of type image or table. For example, the
)0 5 1 A(funcnts)5 0 TN TL()Ec /AF f D( \202
program performs image filtering on images or tables, and so
FITS image masks are valid input for either type of data in this
program.. An image mask cannot be used in a program such as
)0 7 1 A(fundisp)7 0 TN TL()Ec /AF f D( \202
when the input data is a table, because fundisp displays
rows of a table and processes these rows using event-style filtering.

)0 2 113 H(Global)WB 191 Sn( and Local Properties of Regions)EH(

)0 P(The ds9 image display program describes a host of properties such as
color, font, fix/free state, etc. Such properties can be specified
globally \201for all regions\202 or locally \201for an individual region\202.
The )BD(global)ES( keyword specifies properties and qualifiers for all
regions, while local properties are specified in comments on the same
line as the region:
) 4 30 PR(  global color=red
  circle\20110,10,2\202
  circle\20120,20,3\202 # color=blue
  circle\20130,30,4\202)RP(
The first and third circles will be red, which the second circle will
be blue.  Note that funtools currently ignores region properties, as
they are used in display only.

)0 2 114 H()WB 192 Sn( Coordinate Systems)EH(

For each region, it is important to specify the coordinate system
used to interpret the region, i.e., to set the context in which position and
size values are interpreted. For this purpose, the following keywords
are recognized:

) 12 68 PR(  name                  description
  ----                  ------------------------------------------
  PHYSICAL              pixel coords of original file using LTM/LTV
  IMAGE                 pixel coords of current file
  FK4, B1950            sky coordinate systems
  FK5, J2000            sky coordinate systems
  GALACTIC              sky coordinate systems
  ECLIPTIC              sky coordinate systems
  ICRS                  currently same as J2000
  LINEAR                linear wcs as defined in file
  AMPLIFIER             mosaic coords of original file using ATM/ATV
  DETECTOR              mosaic coords of original file using DTM/DTV)RP(

)0 P()0 2 115 H(Specifying)WB 193 Sn( Positions, Sizes, and Angles)EH(

The arguments to region shapes can be floats or integers describing
positions and sizes.  They can be specified as pure numbers or using
explicit formatting directives:

) 21 57 PR(  position arguments    description
  ------------------    ------------------------------
  [num]                 context-dependent \201see below\202
  [num]d                degrees
  [num]r                radians
  [num]p                physical pixels
  [num]i                image pixels
  [num]:[num]:[num]     hms for 'odd' position arguments
  [num]:[num]:[num]     dms for 'even' position arguments
  [num]h[num]m[num]s    explicit hms
  [num]d[num]m[num]s    explicit dms

  size arguments        description
  --------------        -----------
  [num]                 context-dependent \201see below\202
  [num]"                arc seconds
  [num]'                arc minutes
  [num]d                degrees
  [num]r                radians
  [num]p                physical pixels
  [num]i                image pixels)RP(


When a "pure number" \201i.e. one without a format directive such as 'd'
for 'degrees'\202 is specified, its interpretation depends on the context
defined by the 'coordsys' keyword. In general, the rule is:

)0 P()BD(All pure numbers have implied units corresponding to the current
coordinate system.)ES(

)0 P(If no such system is explicitly specified, the default system is
implicitly assumed to be PHYSICAL.

)0 P(In practice this means that for IMAGE and PHYSICAL systems, pure
numbers are pixels.  Otherwise, for all systems other than linear,
pure numbers are degrees. For LINEAR systems, pure numbers are in the
units of the linear system.  This rule covers both positions and
sizes.

)0 P(The input values to each shape can be specified in several coordinate
systems including:

) 12 68 PR(  name                  description
  ----                  ----------------------------
  IMAGE                 pixel coords of current file
  LINEAR                linear wcs as defined in file
  FK4, B1950            various sky coordinate systems
  FK5, J2000
  GALACTIC
  ECLIPTIC
  ICRS
  PHYSICAL              pixel coords of original file using LTM/LTV
  AMPLIFIER             mosaic coords of original file using ATM/ATV
  DETECTOR              mosaic coords of original file using DTM/DTV)RP(

)0 P(If no coordinate system is specified, PHYSICAL is assumed. PHYSICAL or
a World Coordinate System such as J2000 is preferred and most general.
The coordinate system specifier should appear at the beginning of the
region description, on a separate line \201in a file\202, or followed by a
new-line or semicolon; e.g.,

) 2 26 PR(  global coordsys physical
  circle 6500 9320 200)RP(

The use of celestial input units automatically implies WORLD
coordinates of the reference image.  Thus, if the world coordinate
system of the reference image is J2000, then

) 1 27 PR(  circle 10:10:0 20:22:0 3')RP(

is equivalent to:

) 1 35 PR(  circle 10:10:0 20:22:0 3' # j2000)RP()RP(
Note that by using units as described above, you may mix coordinate
systems within a region specifier; e.g.,

) 1 32 PR(  circle 6500 9320 3' # physical)RP(

)0 P(Note that, for regions which accept a rotation angle:

) 2 29 PR(ellipse \201x, y, r1, r2, angle\202
box\201x, y, w, h, angle\202)RP(

the angle is relative to the specified coordinate system. In
particular, if the region is specified in WCS coordinates, the angle
is related to the WCS system, not x/y image coordinate axis.  For WCS
systems with no rotation, this obviously is not an issue.  However,
some images do define an implicit rotation \201e.g., by using a non-zero
CROTA value in the WCS parameters\202 and for these images, the angle
will be relative to the WCS axes. In such case, a region specification
such as:

) 1 54 PR(fk4;ellipse\20122:59:43.985, +58:45:26.92,320", 160", 30\202)RP(

will not, in general, be the same region specified as:

) 1 38 PR(physical;ellipse\201465, 578, 40, 20, 30\202)RP(

even when positions and sizes match. The angle is relative to WCS axes
in the first case, and relative to physical x,y axes in the second.


)0 P(More detailed descriptions are available for:
)0 55 1 A(Region Geometry)55 0 TN TL()Ec /AF f D(,
)0 56 1 A(Region Algebra)56 0 TN TL()Ec /AF f D(,
)0 57 1 A(Region Coordinates)57 0 TN TL()Ec /AF f D(, and
)0 58 1 A(Region Boundaries)58 0 TN TL()Ec /AF f D(.





)0 P()0 0 1 A(Go to Funtools Help Index)0 0 TN TL()Ec /AF f D(

)0 5 116 H(Last)WB 194 Sn( updated: November 17, 2005)EH(

)WB NL
/Cb Db D /Ct [16#00 16#00 16#00] D /Cl [16#00 16#00 16#00] D /CL -1 D Ct Sc
DS
/Ba f D /BO 0 D Bs
/UR (reggeometry.html) D
/Ti (Region Geometry) D
/Au () D
/Df f D
/ME [()] D

0 BO R
()1 Sl()WB 55 Sn(


)0 2 117 H(RegGeometry:)WB 196 Sn()WB 195 Sn( Geometric Shapes in Spatial Region Filtering)EA()EH(


)0 2 118 H(Summary)WB 197 Sn()EH(
)0 P(This document describes the geometry of regions available for spatial
filtering in IRAF/PROS analysis.


)0 2 119 H(Geometric)WB 198 Sn( shapes)EH(
)0 P(Several   geometric shapes are  used to   describe  regions. The valid
shapes are:

) 11 57 PR(  shape:        arguments:
  -----         ----------------------------------------
  ANNULUS       xcenter ycenter inner_radius outer_radius
  BOX           xcenter ycenter xwidth yheight \201angle\202
  CIRCLE        xcenter ycenter radius
  ELLIPSE       xcenter ycenter xwidth yheight \201angle\202
  FIELD         none
  LINE          x1 y1 x2 y2
  PIE           xcenter ycenter angle1 angle2
  POINT         x1 y1
  POLYGON       x1 y1 x2 y2 ... xn yn)RP(


All arguments are real values; integer values are automatically
converted to real where necessary.  All angles are in degrees and
specify angles that run counter-clockwise from the positive y-axis.

)0 P(Shapes can be specified using "command" syntax:
) 1 23 PR(  [shape] arg1 arg2 ...)RP(
or using "routine" syntax:
) 1 26 PR(  [shape]\201arg1, arg2, ...\202)RP(
or by any combination of the these. \201Of course, the parentheses must
balance and there cannot be more commas than necessary.\202 The shape
keywords are case-insensitive.  Furthermore, any shape can be
specified by a three-character unique abbreviation.  For example, one
can specify three circular regions as:

) 1 64 PR(  "foo.fits[CIRCLE 512 512 50;CIR\201128 128, 10\202;cir\201650,650,20\202]")RP(

\201Quotes generally are required to protect the region descriptor
from being processed by the Unix shell.\202

)2 1 1 HR(
)0 P(The  )BD(annulus)ES(    shape  specifies  annuli, centered  at  xcenter,
ycenter, with inner and outer radii \201r1, r2\202. For example,
) 1 20 PR(  ANNULUS 25 25 5 10)RP(
specifies an annulus centered at 25.0 25.0 with an inner radius of 5.0 and
an outer radius of 10. Assuming \201as will be done for all examples in this
document, unless otherwise noted\202 this shape is used in a mask of size 40x40,
it will look like this:
) 42 51 PR(        1234567890123456789012345678901234567890
        ----------------------------------------
        40:........................................
        39:........................................
        38:........................................
        37:........................................
        36:........................................
        35:........................................
        34:....................111111111...........
        33:...................11111111111..........
        32:.................111111111111111........
        31:.................111111111111111........
        30:................11111111111111111.......
        29:...............1111111.....1111111......
        28:...............111111.......111111......
        27:...............11111.........11111......
        26:...............11111.........11111......
        25:...............11111.........11111......
        24:...............11111.........11111......
        23:...............11111.........11111......
        22:...............111111.......111111......
        21:...............1111111.....1111111......
        20:................11111111111111111.......
        19:.................111111111111111........
        18:.................111111111111111........
        17:...................11111111111..........
        16:....................111111111...........
        15:........................................
        14:........................................
        13:........................................
        12:........................................)WR(
        11:........................................
        10:........................................
        9:........................................
        8:........................................
        7:........................................
        6:........................................
        5:........................................
        4:........................................
        3:........................................
        2:........................................
        1:........................................)RP(

)2 1 1 HR(
)0 P(The )BD(box)ES( shape specifies an orthogonally oriented box,
centered at xcenter, ycenter, of size xwidth, yheight. It requires four
arguments and accepts an optional fifth argument to specify a rotation angle.
When the rotation angle is specified \201in degrees\202, the box is rotated by
an angle that runs counter-clockwise from the positive y-axis.

)0 P(The )BD(box)ES( shape specifies a rotated box, centered at
xcenter, ycenter, of size xwidth, yheight. The box is rotated by an angle
specified in degrees that runs counter-clockwise from the positive y-axis.
If the angle argument is omitted, it defaults to 0.

)2 1 1 HR(
)0 P(The )BD(circle)ES( shape specifies a circle, centered at xcenter,
ycenter, of radius r.  It requires three arguments.

)2 1 1 HR(
)0 P(The )BD(ellipse)ES( shape specifies an ellipse, centered at
xcenter, ycenter, with y-axis width a and the y-axis length b defined such
that:
) 1 27 PR(  x**2/a**2 + y**2/b**2 = 1)RP(
Note that a can be less than, equal to, or greater than b. The ellipse
is rotated the specified number of degrees.  The rotation is done according
to astronomical convention, counter-clockwise from the positive y-axis.
An ellipse defined by:
) 1 23 PR(  ELLIPSE 20 20 5 10 45)RP(
will look like this:
) 42 49 PR(         1234567890123456789012345678901234567890
         ----------------------------------------
      40:........................................
      39:........................................
      38:........................................
      37:........................................
      36:........................................
      35:........................................
      34:........................................
      33:........................................
      32:........................................
      31:........................................
      30:........................................
      29:........................................
      28:........................................
      27:............111111......................
      26:............11111111....................
      25:............111111111...................
      24:............11111111111.................
      23:............111111111111................
      22:............111111111111................
      21:.............111111111111...............
      20:.............1111111111111..............
      19:..............111111111111..............
      18:...............111111111111.............
      17:...............111111111111.............
      16:................11111111111.............
      15:..................111111111.............
      14:...................11111111.............
      13:.....................111111.............
      12:........................................)WR(
      11:........................................
      10:........................................
       9:........................................
       8:........................................
       7:........................................
       6:........................................
       5:........................................
       4:........................................
       3:........................................
       2:........................................
       1:........................................)RP(


)2 1 1 HR(
)0 P(The )BD(field)ES( shape specifies the entire field as a
region.  It is not usually specified explicitly, but is used implicitly in the
case where no regions are specified, that is, in cases where either a null
string or some abbreviation of the string "none" is input.
)BD(Field)ES( takes no arguments.

)2 1 1 HR(
)0 P(The )BD(pie)ES( shape specifies an angular wedge of the entire field,
centered at xcenter, ycenter.  The wedge runs between the two specified angles.
The angles are given in degrees, running counter-clockwise from the positive
x-axis. For example,
) 1 18 PR(  PIE 20 20 90 180)RP(
defines a region from 90 degrees to 180 degrees, i.e., quadrant 2 of the
Cartesian plane. The display of such a region looks like this:

) 42 51 PR(        1234567890123456789012345678901234567890
        ----------------------------------------
        40:11111111111111111111....................
        39:11111111111111111111....................
        38:11111111111111111111....................
        37:11111111111111111111....................
        36:11111111111111111111....................
        35:11111111111111111111....................
        34:11111111111111111111....................
        33:11111111111111111111....................
        32:11111111111111111111....................
        31:11111111111111111111....................
        30:11111111111111111111....................
        29:11111111111111111111....................
        28:11111111111111111111....................
        27:11111111111111111111....................
        26:11111111111111111111....................
        25:11111111111111111111....................
        24:11111111111111111111....................
        23:11111111111111111111....................
        22:11111111111111111111....................
        21:11111111111111111111....................
        20:........................................
        19:........................................
        18:........................................
        17:........................................
        16:........................................
        15:........................................
        14:........................................
        13:........................................
        12:........................................)WR(
        11:........................................
        10:........................................
        9:........................................
        8:........................................
        7:........................................
        6:........................................
        5:........................................
        4:........................................
        3:........................................
        2:........................................
        1:........................................)RP(
The pie slice specified is always a counter-clockwise sweep between
the angles, starting at the first angle and ending at the second.  Thus:
) 1 17 PR(  PIE 10 15 30 60)RP(
describes a 30 degree sweep from 2 o'clock to 1 o'clock, while:
) 1 17 PR(  PIE 10 15 60 30)RP(
describes a 330 degree counter-clockwise sweep from 1 o'clock to 2 o'clock
passing through 12 o'clock \2010 degrees\202. Note in both of these examples that
the center of the slice can be anywhere on the plane.  The second mask looks
like this:

) 42 51 PR(        1234567890123456789012345678901234567890
        ----------------------------------------
        40:111111111111111111111111................
        39:11111111111111111111111.................
        38:11111111111111111111111.................
        37:1111111111111111111111..................
        36:1111111111111111111111..................
        35:111111111111111111111...................
        34:11111111111111111111....................
        33:11111111111111111111....................
        32:1111111111111111111....................1
        31:1111111111111111111..................111
        30:111111111111111111.................11111
        29:111111111111111111................111111
        28:11111111111111111...............11111111
        27:1111111111111111..............1111111111
        26:1111111111111111.............11111111111
        25:111111111111111............1111111111111
        24:111111111111111..........111111111111111
        23:11111111111111.........11111111111111111
        22:11111111111111........111111111111111111
        21:1111111111111.......11111111111111111111
        20:111111111111......1111111111111111111111
        19:111111111111....111111111111111111111111
        18:11111111111....1111111111111111111111111
        17:11111111111..111111111111111111111111111
        16:1111111111.11111111111111111111111111111
        15:1111111111111111111111111111111111111111
        14:1111111111111111111111111111111111111111
        13:1111111111111111111111111111111111111111
        12:1111111111111111111111111111111111111111)WR(
        11:1111111111111111111111111111111111111111
        10:1111111111111111111111111111111111111111
        9:1111111111111111111111111111111111111111
        8:1111111111111111111111111111111111111111
        7:1111111111111111111111111111111111111111
        6:1111111111111111111111111111111111111111
        5:1111111111111111111111111111111111111111
        4:1111111111111111111111111111111111111111
        3:1111111111111111111111111111111111111111
        2:1111111111111111111111111111111111111111
        1:1111111111111111111111111111111111111111)RP(
The pie slice goes to the edge of the field. To limit its scope, pie
usually is is combined with other shapes, such as circles and annuli,
using boolean operations. \201See below and in "help regalgebra"\202.

)0 P(Pie Performance Notes: 
)0 P(Pie region processing time is proportional to the size of the image,
and not the size of the region. This is because the pie shape is the
only infinite length shape, and we essentially must check all y rows
for inclusion \201unlike other regions, where the y limits can be
calculated beforehand\202. Thus, pie can run very slowly on large images.
In particular, it will run MUCH more slowly than the panda shape in
image-based region operations \201such as funcnts\202. We recommend use of
panda over pie where ever possible.

)0 P(If you must use pie, always try to put it last in a boolean &&
expression.  The reason for this is that the filter code is optimized
to exit as soon as the result is know. Since pie is the slowest
region, it is better to avoid executing it if another region can decide
the result. Consider, for example, the difference in time required to
process a Chandra ACIS file when a pie and circle are combined in
two different orders:

) 5 74 PR(  time ./funcnts nacis.fits "circle 4096 4096 100 && pie 4096 4096 10 78"
2.87u 0.38s 0:35.08 9.2%

  time ./funcnts nacis.fits "pie 4096 4096 10 78 && circle 4096 4096 100 "
89.73u 0.36s 1:03.50 141.8%)RP(

)0 P(Black-magic performance note:

)0 P(Panda region processing uses a )BD(quick test)ES( pie region instead of
the normal pie region when combining its annulus and pie shapes. This
)BD(qtpie)ES( shape differs from the normal pie in that it utilizes the
y limits from the previous region with which it is combined. In a
panda shape, which is a series of annuli combined with pies, the
processing time is thus reduced to that of the annuli.

)0 P(You can use the qtpie shape instead of pie in cases where you are
combining pie with another shape using the && operator. This will
cause the pie limits to be set using limits from the other shape, and
will speed up the processing considerably.  For example, the above
execution of funcnts can be improved considerably using this technique:

) 2 75 PR(  time ./funcnts nacis.fits "circle 4096 4096 100 && qtpie 4096 4096 10 78"
4.66u 0.33s 0:05.87 85.0%)RP(

)0 P(We emphasize that this is a quasi-documented feature and might change in
the future. The qtpie shape is not recognized by ds9 or other programs.

)2 1 1 HR(
)0 P(The )BD(line)ES( shape allows single pixels in a line between \201x1,y1\202 and
\201x2,y2\202 to be included or excluded. For example:
) 44 49 PR(  LINE \2015,6, 24,25\202
) 43 49 PR(displays as:
) 42 49 PR(         1234567890123456789012345678901234567890
         ----------------------------------------
      40:........................................
      39:........................................
      38:........................................
      37:........................................
      36:........................................
      35:........................................
      34:........................................
      33:........................................
      32:........................................
      31:........................................
      30:........................................
      29:........................................
      28:........................................
      27:........................................
      26:........................................
      25:.......................1................
      24:......................1.................
      23:.....................1..................
      22:....................1...................
      21:...................1....................
      20:..................1.....................
      19:.................1......................
      18:................1.......................
      17:...............1........................
      16:..............1.........................
      15:.............1..........................
      14:............1...........................)WR(
      13:...........1............................)WR(
      12:..........1.............................)WR(
      11:.........1..............................
      10:........1...............................
       9:.......1................................
       8:......1.................................
       7:.....1..................................
       6:....1...................................
       5:........................................
       4:........................................
       3:........................................
       2:........................................
       1:........................................)RP(

)2 1 1 HR(
)0 P(The )BD(point)ES( shape allows single pixels to be included or
excluded.  Although the \201x,y\202 values are real numbers, they are truncated
to integer and the corresponding pixel is included or excluded, as specified.

)0 P(Several points can be put in one region declaration; unlike the
original IRAF implementation, each now is given a different region mask value.
This makes it easier, for example, for funcnts to determine the number of
photons in the individual pixels. For example,
) 1 37 PR(  POINT \2015,6,  10,11,  20,20,  35,30\202)RP(
will give the different region mask values to all four points, as shown below:

) 42 49 PR(         1234567890123456789012345678901234567890
         ----------------------------------------
      40:........................................
      39:........................................
      38:........................................
      37:........................................
      36:........................................
      35:........................................
      34:........................................
      33:........................................
      32:........................................
      31:........................................
      30:..................................4.....
      29:........................................
      28:........................................
      27:........................................
      26:........................................
      25:........................................
      24:........................................
      23:........................................
      22:........................................
      21:........................................
      20:...................3....................
      19:........................................
      18:........................................
      17:........................................
      16:........................................
      15:........................................
      14:........................................
      13:........................................
      12:........................................)WR(
      11:.........2..............................
      10:........................................
       9:........................................
       8:........................................
       7:........................................
       6:....1...................................
       5:........................................
       4:........................................
       3:........................................
       2:........................................
       1:........................................)RP(

)2 1 1 HR(
)0 P(The )BD(polygon)ES( shape specifies a polygon with vertices
\201x1, y1\202 ... \201xn, yn\202. The polygon is closed automatically: one should
not specify the last vertex to be the same as the first.  Any number of
vertices are allowed.  For example, the following polygon defines a
right triangle as shown below:
) 1 33 PR(  POLYGON \20110,10,  10,30,  30,30\202)RP(

looks like this:

) 42 49 PR(         1234567890123456789012345678901234567890
         ----------------------------------------
      40:........................................
      39:........................................
      38:........................................
      37:........................................
      36:........................................
      35:........................................
      34:........................................
      33:........................................
      32:........................................
      31:........................................
      30:..........11111111111111111111..........
      29:..........1111111111111111111...........
      28:..........111111111111111111............
      27:..........11111111111111111.............
      26:..........1111111111111111..............
      25:..........111111111111111...............
      24:..........11111111111111................
      23:..........1111111111111.................
      22:..........111111111111..................
      21:..........11111111111...................
      20:..........1111111111....................
      19:..........111111111.....................
      18:..........11111111......................
      17:..........1111111.......................
      16:..........111111........................
      15:..........11111.........................
      14:..........1111..........................
      13:..........111...........................
      12:..........11............................)WR(
      11:..........1.............................
      10:........................................
       9:........................................
       8:........................................
       7:........................................
       6:........................................
       5:........................................
       4:........................................
       3:........................................
       2:........................................
       1:........................................)RP(
Note that polygons can get twisted upon themselves if edge lines
cross.  Thus:
) 1 37 PR(  POL \20110,10,  20,20,  20,10,  10,20\202)RP(
will produce an area which is two triangles, like butterfly wings, as shown
below:

) 42 49 PR(         1234567890123456789012345678901234567890
         ----------------------------------------
      40:........................................
      39:........................................
      38:........................................
      37:........................................
      36:........................................
      35:........................................
      34:........................................
      33:........................................
      32:........................................
      31:........................................
      30:........................................
      29:........................................
      28:........................................
      27:........................................
      26:........................................
      25:........................................
      24:........................................
      23:........................................
      22:........................................
      21:........................................
      20:........................................
      19:..........1........1....................
      18:..........11......11....................
      17:..........111....111....................
      16:..........1111..1111....................
      15:..........1111111111....................
      14:..........1111..1111....................
      13:..........111....111....................
      12:..........11......11....................)WR(
      11:..........1........1....................
      10:........................................
       9:........................................
       8:........................................
       7:........................................
       6:........................................
       5:........................................
       4:........................................
       3:........................................
       2:........................................
       1:........................................)RP(

)2 1 1 HR(
)0 P(The following are combinations of pie with different shapes
\201called "panda" for "Pie AND Annulus"\202 allow for easy specification of
radial sections:
) 6 76 PR(  shape:   arguments:
  -----    ---------
  PANDA    xcen ycen ang1 ang2 nang irad orad nrad   # circular
  CPANDA   xcen ycen ang1 ang2 nang irad orad nrad   # circular
  BPANDA   xcen ycen ang1 ang2 nang xwlo yhlo xwhi yhhi nrad \201ang\202 # box
  EPANDA   xcen ycen ang1 ang2 nang xwlo yhlo xwhi yhhi nrad \201ang\202 # ellipse)RP(

The )BD(panda)ES( \201)BD(P)ES(ies )BD(AND)ES( )BD(A)ES(nnuli\202 shape can be
used to create combinations of pie and annuli markers. It is analogous
to a Cartesian product on those shapes, i.e., the result is several
shapes generated by performing a boolean AND between pies and
annuli. Thus, the panda and cpanda specify combinations of annulus and
circle with pie, respectively and give identical results. The bpanda
combines box and pie, while epanda combines ellipse and pie.

)0 P(Consider the example shown below:
) 1 31 PR(  PANDA\20120,20, 0,360,3, 0,15,4\202)RP(
Here, 3 pie slices centered at 20, 20 are combined with 4 annuli, also
centered at 20, 20. The result is a mask with 12 regions \201displayed in
base 16 to save characters\202:
) 42 51 PR(        1234567890123456789012345678901234567890
        ----------------------------------------
        40:........................................
        39:........................................
        38:........................................
        37:........................................
        36:........................................
        35:........................................
        34:..............44444444444...............
        33:............444444444444444.............
        32:...........88444444444444444............
        31:.........888844443333344444444..........
        30:........88888833333333333444444.........
        29:........88888733333333333344444.........
        28:.......8888877733333333333344444........
        27:......888887777332222233333344444.......
        26:......888877777622222222333334444.......
        25:.....88887777766622222222333334444......
        24:.....88887777666622222222233334444......
        23:.....88887777666651111222233334444......
        22:.....88877776666551111122223333444......
        21:.....88877776666555111122223333444......
        20:.....888777766665559999aaaabbbbccc......
        19:.....888777766665559999aaaabbbbccc......
        18:.....888777766665599999aaaabbbbccc......
        17:.....88887777666659999aaaabbbbcccc......
        16:.....888877776666aaaaaaaaabbbbcccc......
        15:.....888877777666aaaaaaaabbbbbcccc......
        14:......8888777776aaaaaaaabbbbbcccc.......
        13:......888887777bbaaaaabbbbbbccccc.......
        12:.......88888777bbbbbbbbbbbbccccc........)WR(
        11:........888887bbbbbbbbbbbbccccc.........
        10:........888888bbbbbbbbbbbcccccc.........
        9:.........8888ccccbbbbbcccccccc..........
        8:...........88ccccccccccccccc............
        7:............ccccccccccccccc.............
        6:..............ccccccccccc...............
        5:........................................
        4:........................................
        3:........................................
        2:........................................
        1:........................................)RP(

)2 1 1 HR(
)0 P(Several regions with different mask values can be combined in the 
same mask.  This supports comparing data from the different regions.  
\201For information on how to combine different shapes into a single 
region, see "help regalgebra".\202  For example, consider the following 
set of regions:
) 3 24 PR(  ANNULUS 25 25 5 10
  ELLIPSE 20 20 5 10 315 
  BOX 15 15 5 10)RP(
The resulting mask will look as follows:

) 42 49 PR(         1234567890123456789012345678901234567890
         ----------------------------------------
      40:........................................
      39:........................................
      38:........................................
      37:........................................
      36:........................................
      35:........................................
      34:....................111111111...........
      33:...................11111111111..........
      32:.................111111111111111........
      31:.................111111111111111........
      30:................11111111111111111.......
      29:...............1111111.....1111111......
      28:...............111111.......111111......
      27:...............11111.222222..11111......
      26:...............111112222222..11111......
      25:...............111112222222..11111......
      24:...............111112222222..11111......
      23:...............111112222222..11111......
      22:...............111111222222.111111......
      21:..............211111112222.1111111......
      20:............322211111111111111111.......
      19:............32222111111111111111........
      18:............22222111111111111111........
      17:............222222211111111111..........
      16:............22222222111111111...........
      15:............222222222...................
      14:............22222222....................
      13:............222222......................
      12:............33333.......................)WR(
      11:............33333.......................
      10:........................................
       9:........................................
       8:........................................
       7:........................................
       6:........................................
       5:........................................
       4:........................................
       3:........................................
       2:........................................
       1:........................................)RP(
Note that when a pixel is in 2 or more regions, it is arbitrarily
assigned to a one of the regions in question \201often based on how a
give C compiler optimizes boolean expressions\202.

)0 P()0 2 120 H(Region)WB 199 Sn( accelerators)EH(

)0 P(Two types of \200fBaccelerators)ES(, to simplify region specification,
are provided as natural extensions to the ways shapes are described.
These are: extended lists of parameters, specifying multiple regions,
valid for annulus, box, circle, ellipse, pie, and points; and 
)BD(n=)ES(, valid for annulus, box, circle, ellipse, and pie \201not
point\202.  In both cases, one specification is used to define several
different regions, that is, to define shapes with different mask
values in the region mask.

)0 P(The following regions accept )BD(accelerator)ES( syntax:
) 13 73 PR(  shape      arguments
  -----      ------------------------------------------
  ANNULUS    xcenter ycenter radius1 radius2 ... radiusn
  ANNULUS    xcenter ycenter inner_radius outer_radius n=[number]
  BOX        xcenter ycenter xw1 yh1 xw2 yh2 ... xwn yhn \201angle\202
  BOX        xcenter ycenter xwlo yhlo xwhi yhhi n=[number] \201angle\202
  CIRCLE     xcenter ycenter r1 r2 ... rn              # same as annulus
  CIRCLE     xcenter ycenter rinner router n=[number]  # same as annulus
  ELLIPSE    xcenter ycenter xw1 yh1 xw2 yh2 ... xwn yhn \201angle\202
  ELLIPSE    xcenter ycenter xwlo yhlo xwhi yhhi n=[number] \201angle\202
  PIE        xcenter ycenter angle1 angle2 \201angle3\202 \201angle4\202 \201angle5\202 ...
  PIE        xcenter ycenter angle1 angle2 \201n=[number]\202
  POINT      x1 y1 x2 y2 ... xn yn)RP(
Note that the circle accelerators are simply aliases for the annulus
accelerators.  

)0 P(For example, several annuli at the same center can be specified in one
region expression by specifying more than two radii.  If )BD(N)ES(
radii are specified, then )BD(N)ES(-1 annuli result, with the outer
radius of each preceding annulus being the inner radius of the
succeeding annulus.  Each annulus is considered a separate region, and
is given a separate mask value. For example,
) 1 30 PR(  ANNULUS 20 20 0 2 5 10 15 20)RP(
specifies five different annuli centered at 20 20, and is equivalent to:
) 5 25 PR(  ANNULUS 20.0 20.0  0  2
  ANNULUS 20.0 20.0  2  5
  ANNULUS 20.0 20.0  5 10
  ANNULUS 20.0 20.0 10 15
  ANNULUS 20.0 20.0 15 20)RP(
The mask is shown below:

) 42 49 PR(         1234567890123456789012345678901234567890
         ----------------------------------------
      40:........................................
      39:.............5555555555555..............
      38:...........55555555555555555............
      37:.........555555555555555555555..........
      36:........55555555555555555555555.........
      35:......555555555555555555555555555.......
      34:.....55555555544444444444555555555......
      33:....5555555544444444444444455555555.....
      32:....5555555444444444444444445555555.....
      31:...555555444444444444444444444555555....
      30:..55555544444444444444444444444555555...
      29:..55555544444443333333334444444555555...
      28:.5555554444444333333333334444444555555..
      27:.5555544444433333333333333344444455555..
      26:555555444444333333333333333444444555555.
      25:555554444443333333333333333344444455555.
      24:555554444433333332222233333334444455555.
      23:555554444433333322222223333334444455555.
      22:555554444433333222222222333334444455555.
      21:555554444433333222111222333334444455555.
      20:555554444433333222111222333334444455555.
      19:555554444433333222111222333334444455555.
      18:555554444433333222222222333334444455555.
      17:555554444433333322222223333334444455555.
      16:555554444433333332222233333334444455555.
      15:555554444443333333333333333344444455555.
      14:555555444444333333333333333444444555555.
      13:.5555544444433333333333333344444455555..
      12:.5555554444444333333333334444444555555..)WR(
      11:..55555544444443333333334444444555555...
      10:..55555544444444444444444444444555555...
       9:...555555444444444444444444444555555....
       8:....5555555444444444444444445555555.....
       7:....5555555544444444444444455555555.....
       6:.....55555555544444444444555555555......
       5:......555555555555555555555555555.......
       4:........55555555555555555555555.........
       3:.........555555555555555555555..........
       2:...........55555555555555555............
       1:.............5555555555555..............)RP(

)0 P(For boxes and ellipses, if an odd number of arguments is specified,
then the last argument is assumed to be an angle. Otherwise, the
angle is assumed to be zero. For example:
) 1 38 PR(  ellipse 20 20 3 5 6 10 9 15 12 20 45)RP(
specifies an 3 ellipses at a 45 degree angle:
) 42 51 PR(        1234567890123456789012345678901234567890
        ----------------------------------------
        40:........................................
        39:........................................
        38:........................................
        37:........................................
        36:........33333333........................
        35:......333333333333......................
        34:.....3333333333333333...................
        33:....333333333333333333..................
        32:....33333332222233333333................
        31:...3333332222222222333333...............
        30:...33333222222222222233333..............
        29:...333332222222222222223333.............
        28:...3333222222211112222223333............
        27:...33332222211111111222223333...........
        26:...333322222111111111122223333..........
        25:...3333222211111111111122223333.........
        24:....3332222111111..1111122223333........
        23:....333322211111.....11112222333........
        22:....33332222111.......11112223333.......
        21:.....33322221111.......11122223333......
        20:.....33332221111.......11112223333......
        19:.....33332222111.......11112222333......
        18:......33332221111.......11122223333.....
        17:.......33322221111.....111112223333.....
        16:.......3333222211111..1111112222333.....
        15:........3333222211111111111122223333....
        14:.........333322221111111111222223333....
        13:..........33332222211111111222223333....
        12:...........3333222222111122222223333....)WR(
        11:............333322222222222222233333....
        10:.............33333222222222222233333....
        9:..............3333332222222222333333....
        8:...............33333333222223333333.....
        7:.................333333333333333333.....
        6:..................3333333333333333......
        5:.....................333333333333.......
        4:.......................33333333.........
        3:........................................
        2:........................................
        1:........................................)RP(
Note in the above example that the lower limit is not part of the
region for boxes, circles, and ellipses. This makes circles and annuli
equivalent, i.e.:
) 2 26 PR(  circle  20 20 5 10 15 20
  annulus 20 20 5 10 15 20)RP(
both give the following region mask:
) 42 51 PR(        1234567890123456789012345678901234567890
        ----------------------------------------
        40:........................................
        39:.............3333333333333..............
        38:...........33333333333333333............
        37:.........333333333333333333333..........
        36:........33333333333333333333333.........
        35:......333333333333333333333333333.......
        34:.....33333333322222222222333333333......
        33:....3333333322222222222222233333333.....
        32:....3333333222222222222222223333333.....
        31:...333333222222222222222222222333333....
        30:..33333322222222222222222222222333333...
        29:..33333322222221111111112222222333333...
        28:.3333332222222111111111112222222333333..
        27:.3333322222211111111111111122222233333..
        26:333333222222111111111111111222222333333.
        25:333332222221111111111111111122222233333.
        24:33333222221111111.....11111112222233333.
        23:3333322222111111.......1111112222233333.
        22:333332222211111.........111112222233333.
        21:333332222211111.........111112222233333.
        20:333332222211111.........111112222233333.
        19:333332222211111.........111112222233333.
        18:333332222211111.........111112222233333.
        17:3333322222111111.......1111112222233333.
        16:33333222221111111.....11111112222233333.
        15:333332222221111111111111111122222233333.
        14:333333222222111111111111111222222333333.
        13:.3333322222211111111111111122222233333..
        12:.3333332222222111111111112222222333333..)WR(
        11:..33333322222221111111112222222333333...
        10:..33333322222222222222222222222333333...
        9:...333333222222222222222222222333333....
        8:....3333333222222222222222223333333.....
        7:....3333333322222222222222233333333.....
        6:.....33333333322222222222333333333......
        5:......333333333333333333333333333.......
        4:........33333333333333333333333.........
        3:.........333333333333333333333..........
        2:...........33333333333333333............
        1:.............3333333333333..............)RP(

)0 P(As a final example, specifying several angles in one pie slice
expression is equivalent to specifying several separate slices with
the same center.  As with the annulus, if )BD(N)ES( angles are
specified, then )BD(N)ES(-1 slices result, with the ending angle of
each preceding slice being the starting angle of the succeeding slice.
Each slice is considered a separate region, and is given a separate
mask value. For example, 
) 1 26 PR(  PIE 12 12 315 45 115 270)RP(
specifies three regions as shown below:
) 42 51 PR(        1234567890123456789012345678901234567890
        ----------------------------------------
        40:2222222222222222222222222222222222222222
        39:2222222222222222222222222222222222222221
        38:2222222222222222222222222222222222222211
        37:2222222222222222222222222222222222222111
        36:2222222222222222222222222222222222221111
        35:3222222222222222222222222222222222211111
        34:3222222222222222222222222222222222111111
        33:3322222222222222222222222222222221111111
        32:3322222222222222222222222222222211111111
        31:3332222222222222222222222222222111111111
        30:3332222222222222222222222222221111111111
        29:3333222222222222222222222222211111111111
        28:3333222222222222222222222222111111111111
        27:3333322222222222222222222221111111111111
        26:3333322222222222222222222211111111111111
        25:3333322222222222222222222111111111111111
        24:3333332222222222222222221111111111111111
        23:3333332222222222222222211111111111111111
        22:3333333222222222222222111111111111111111
        21:3333333222222222222221111111111111111111
        20:3333333322222222222211111111111111111111
        19:3333333322222222222111111111111111111111
        18:3333333332222222221111111111111111111111
        17:3333333332222222211111111111111111111111
        16:3333333333222222111111111111111111111111
        15:3333333333222221111111111111111111111111
        14:3333333333322211111111111111111111111111
        13:3333333333322111111111111111111111111111
        12:33333333333.1111111111111111111111111111)WR(
        11:3333333333331111111111111111111111111111
        10:333333333333.111111111111111111111111111
        9:333333333333..11111111111111111111111111
        8:333333333333...1111111111111111111111111
        7:333333333333....111111111111111111111111
        6:333333333333.....11111111111111111111111
        5:333333333333......1111111111111111111111
        4:333333333333.......111111111111111111111
        3:333333333333........11111111111111111111
        2:333333333333.........1111111111111111111
        1:333333333333..........111111111111111111)RP(

)0 P(The annulus, box, circle, ellipse, and pie shapes also accept an
)BD(n=[int])ES( syntax for specifying multiple regions. The
)BD(n=[int])ES(syntax interprets the previous \201shape-dependent\202
arguments as lower and upper limits for the region and creates n
shapes with evenly spaced boundaries.  For example, if )BD(n=[int])ES(
is specified in an annulus, the two immediately preceding radii
\201)BD(rn)ES( and )BD(rm)ES(\202 are divided into )BD(int)ES( annuli, such
that the inner radius of the first is )BD(rn)ES( and the outer radius
of the last is )BD(rm)ES(. For example,
) 1 24 PR(  ANNULUS 20 20 5 20 n=3)RP(
is equivalent to:
) 1 26 PR(  ANNULUS 20 20 5 10 15 20)RP(
If this syntax is used with an ellipse or box, then the two preceding
pairs of values are taken to be lower and upper limits for a set of
ellipses or boxes. A circle uses the two preceding arguments for upper
and lower radii.  For pie, the two preceding angles are divided into n
wedges such that the starting angle of the first is the lower bound
and the ending angle of the last is the upper bound.  In all cases,
the )BD(n=[int])ES( syntax allows any single alphabetic character
before the "=", i.e, i=3, z=3, etc. are all equivalent.

)0 P(Also note that for boxes and ellipses, the optional angle argument is
always specified after the )BD(n=[int])ES( syntax. For example:
) 45 57 PR(  ellipse 20 20 4 6 16 24 n=3 45
) 44 57 PR(specifies 3 elliptical regions at an angle of 45 degrees:

) 42 45 PR(  1234567890123456789012345678901234567890
  ----------------------------------------
  40:........33333333........................
  39:.....33333333333333.....................
  38:....33333333333333333...................
  37:...33333333333333333333.................
  36:..33333333333333333333333...............
  35:.3333333333222223333333333..............
  34:3333333322222222222233333333............
  33:33333332222222222222223333333...........
  32:333333222222222222222222333333..........
  31:3333322222222222222222222333333.........
  30:33333222222222111122222222333333........
  29:333332222222111111112222222333333.......
  28:3333222222211111111111222222333333......
  27:3333222222111111111111112222233333......
  26:33332222221111111111111112222233333.....
  25:33332222211111111.111111112222233333....
  24:333322222111111......111111222223333....
  23:333322222111111.......111112222233333...
  22:33333222221111.........11111222223333...
  21:333332222211111.........11112222233333..
  20:.33332222211111.........11111222223333..
  19:.33333222221111.........111112222233333.
  18:..33332222211111.........11112222233333.
  17:..333332222211111.......111111222233333.
  16:...333322222111111......111111222223333.
  15:...333332222211111111.111111112222233333)WR(
  14:....333332222211111111111111122222233333)WR(
  13:.....33333222221111111111111122222233333
  12:.....33333322222211111111111222222233333)WR(
  11:......3333332222222111111112222222333333
  10:.......333333222222221111222222222333333
  9:........33333322222222222222222222333333
  8:.........333333222222222222222222333333.
  7:..........33333332222222222222223333333.
  6:...........3333333322222222222233333333.
  5:.............3333333333222223333333333..
  4:..............33333333333333333333333...
  3:................33333333333333333333....
  2:..................33333333333333333.....
  1:....................33333333333333......)RP(

)0 P(Both the variable argument syntax and the )BD(n=[int])ES( syntax must
occur alone in a region descriptor \201aside from the optional angle for
boxes and ellipses\202.  They cannot be combined. Thus, it is not valid
to precede or follow an )BD(n=[int])ES( accelerator with more angles or
radii, as in this example:
) 3 49 PR(  # INVALID -- one too many angles before a=5 ...
  # and no angles are allowed after a=5
  PIE 12 12 10 25 50 a=5 85 135)RP(
Instead, use three separate specifications, such as:
) 3 21 PR(  PIE 12 12 10 25
  PIE 12 12 25 50 a=5
  PIE 12 12 85 135)RP(
The original \201IRAF\202 implementation of region filtering permitted this
looser syntax, but we found it caused more confusion than it was worth
and therefore removed it.

)0 P(NB: Accelerators may be combined with other shapes in a boolean
expression in any order. \201This is a change starting with funtools
v1.1.1. Prior to this release, the accelerator shape had to be
specified last\202.  The actual region mask id values returned depend on the
order in which the shapes are specified, although the total number of
pixels or rows that pass the filter will be consistent. For this
reason, use of accelerators in boolean expressions is discouraged in
programs such as funcnts, where region mask id values are used
to count events or image pixels.

)0 P([All region masks displayed in this document were generated using the
)BD(fundisp)ES( routine and the undocumented "mask=all" argument \201with
spaced removed using sed \202:
) 2 72 PR(  fundisp "funtools/funtest/test40.fits[ANNULUS 25 25 5 10]" mask=all |\200
  sed 's/ //g')RP(
Note that you must supply an image of the appropriate size -- in this case,
a FITS image of dimension 40x40 is used.]





)0 P()0 0 1 A(Go to Funtools Help Index)0 0 TN TL()Ec /AF f D(

)0 5 121 H(Last)WB 200 Sn( updated: March 12, 2007)EH(

)WB NL
/Cb Db D /Ct [16#00 16#00 16#00] D /Cl [16#00 16#00 16#00] D /CL -1 D Ct Sc
DS
/Ba f D /BO 0 D Bs
/UR (regalgebra.html) D
/Ti (Region Algebra) D
/Au () D
/Df f D
/ME [()] D

0 BO R
()1 Sl()WB 56 Sn(


)0 2 122 H(RegAlgebra:)WB 202 Sn()WB 201 Sn( Boolean Algebra on Spatial Regions)EA()EH(


)0 2 123 H(Summary)WB 203 Sn()EH(
)0 P(This document describes the boolean arithmetic defined for 
region expressions.


)0 2 124 H(Description)WB 204 Sn()EH(
)0 P(When defining a region, several shapes can be  combined using boolean
operations.  The boolean operators are \201in order of precedence\202:
) 6 53 PR(  Symbol        Operator                Associativity
  ------        --------                -------------
  !             not                     right to left
  &             and                     left to right
  ^             exclusive or            left to right
  |             inclusive or            left to right)RP(
For example,  to  create a mask  consisting  of a large  circle with a
smaller  box   removed,  one  can  use   the   )BD(and)ES( and )BD(not)ES(
operators:
) 1 36 PR(  CIRCLE\20111,11,15\202 & !BOX\20111,11,3,6\202)RP(

and the resulting mask is:
) 42 49 PR(         1234567890123456789012345678901234567890
         ----------------------------------------
       1:1111111111111111111111..................
       2:1111111111111111111111..................
       3:11111111111111111111111.................
       4:111111111111111111111111................
       5:111111111111111111111111................
       6:1111111111111111111111111...............
       7:1111111111111111111111111...............
       8:1111111111111111111111111...............
       9:111111111...1111111111111...............
      10:111111111...1111111111111...............
      11:111111111...1111111111111...............
      12:111111111...1111111111111...............
      13:111111111...1111111111111...............
      14:111111111...1111111111111...............
      15:1111111111111111111111111...............
      16:1111111111111111111111111...............
      17:111111111111111111111111................
      18:111111111111111111111111................
      19:11111111111111111111111.................
      20:1111111111111111111111..................
      21:1111111111111111111111..................
      22:111111111111111111111...................
      23:..11111111111111111.....................
      24:...111111111111111......................
      25:.....11111111111........................
      26:........................................
      27:........................................
      28:........................................
      29:........................................)WR(
      30:........................................
      31:........................................
      32:........................................
      33:........................................
      34:........................................
      35:........................................
      36:........................................
      37:........................................
      38:........................................
      39:........................................
      40:........................................)RP(
A three-quarter circle can be defined as:
) 1 40 PR(  CIRCLE\20120,20,10\202 & !PIE\20120,20,270,360\202)RP(

and looks as follows:
) 42 49 PR(         1234567890123456789012345678901234567890
         ----------------------------------------
       1:........................................
       2:........................................
       3:........................................
       4:........................................
       5:........................................
       6:........................................
       7:........................................
       8:........................................
       9:........................................
      10:........................................
      11:...............111111111................
      12:..............11111111111...............
      13:............111111111111111.............
      14:............111111111111111.............
      15:...........11111111111111111............
      16:..........1111111111111111111...........
      17:..........1111111111111111111...........
      18:..........1111111111111111111...........
      19:..........1111111111111111111...........
      20:..........1111111111111111111...........
      21:..........1111111111....................
      22:..........1111111111....................
      23:..........1111111111....................
      24:..........1111111111....................
      25:...........111111111....................
      26:............11111111....................
      27:............11111111....................
      28:..............111111....................
      29:...............11111....................)WR(
      30:........................................
      31:........................................
      32:........................................
      33:........................................
      34:........................................
      35:........................................
      36:........................................
      37:........................................
      38:........................................
      39:........................................
      40:........................................)RP(
Two non-intersecting ellipses can be made into the same region:
) 1 40 PR(  ELL\20120,20,10,20,90\202 | ELL\2011,1,20,10,0\202)RP(

and looks as follows:
) 42 49 PR(         1234567890123456789012345678901234567890
         ----------------------------------------
       1:11111111111111111111....................
       2:11111111111111111111....................
       3:11111111111111111111....................
       4:11111111111111111111....................
       5:1111111111111111111.....................
       6:111111111111111111......................
       7:1111111111111111........................
       8:111111111111111.........................
       9:111111111111............................
      10:111111111...............................
      11:...........11111111111111111............
      12:........111111111111111111111111........
      13:.....11111111111111111111111111111......
      14:....11111111111111111111111111111111....
      15:..11111111111111111111111111111111111...
      16:.1111111111111111111111111111111111111..
      17:111111111111111111111111111111111111111.
      18:111111111111111111111111111111111111111.
      19:111111111111111111111111111111111111111.
      20:111111111111111111111111111111111111111.
      21:111111111111111111111111111111111111111.
      22:111111111111111111111111111111111111111.
      23:111111111111111111111111111111111111111.
      24:.1111111111111111111111111111111111111..
      25:..11111111111111111111111111111111111...
      26:...11111111111111111111111111111111.....
      27:.....11111111111111111111111111111......
      28:.......111111111111111111111111.........
      29:...........11111111111111111............)WR(
      30:........................................
      31:........................................
      32:........................................
      33:........................................
      34:........................................
      35:........................................
      36:........................................
      37:........................................
      38:........................................
      39:........................................
      40:........................................)RP(
You can use several boolean operations in a single region expression,
to create arbitrarily complex regions.  With the important exception
below, you can apply the operators in any order, using parentheses if
necessary to override the natural precedences of the operators.

)0 P(NB: Using a panda shape is always much more efficient than explicitly
specifying "pie & annulus", due to the ability of panda to place a
limit on the number of pixels checked in the pie shape.  If you are
going to specify the intersection of pie and annulus, use panda
instead.

)0 P(As described in "help regreometry", the )BD(PIE)ES( slice goes to the
edge of the field. To limit its scope, )BD(PIE)ES( usually is is
combined with other shapes, such as circles and annuli, using boolean
operations.  In this context, it is worth noting that that there is a
difference between )BD(-PIE)ES( and )BD(&!PIE)ES(. The former is a
global exclude of all pixels in the )BD(PIE)ES( slice, while the latter
is a local excludes of pixels affecting only the region\201s\202 with which
the )BD(PIE)ES( is combined.  For example, the following region uses
)BD(&!PIE)ES( as a local exclude of a single circle. Two other circles
are also defined and are unaffected by the local exclude:
) 21 56 PR(        CIRCLE\2011,8,1\202
        CIRCLE\2018,8,7\202&!PIE\2018,8,60,120\202&!PIE\2018,8,240,300\202
        CIRCLE\20115,8,2\202

          1 2 3 4 5 6 7 8 9 0 1 2 3 4 5
          - - - - - - - - - - - - - - -
      15: . . . . . . . . . . . . . . .
      14: . . . . 2 2 2 2 2 2 2 . . . .
      13: . . . 2 2 2 2 2 2 2 2 2 . . .
      12: . . 2 2 2 2 2 2 2 2 2 2 2 . .
      11: . . 2 2 2 2 2 2 2 2 2 2 2 . .
      10: . . . . 2 2 2 2 2 2 2 . . . .
       9: . . . . . . 2 2 2 . . . . 3 3
       8: 1 . . . . . . . . . . . . 3 3
       7: . . . . . . 2 2 2 . . . . 3 3
       6: . . . . 2 2 2 2 2 2 2 . . . .
       5: . . 2 2 2 2 2 2 2 2 2 2 2 . .
       4: . . 2 2 2 2 2 2 2 2 2 2 2 . .
       3: . . . 2 2 2 2 2 2 2 2 2 . . .
       2: . . . . 2 2 2 2 2 2 2 . . . .
       1: . . . . . . . . . . . . . . .)RP(
Note that the two other regions are not affected by the )BD(&!PIE)ES(,
which only affects the circle with which it is combined.

)0 P(On the other hand, a )BD(-PIE)ES( is an global exclude that does
affect other regions with which it overlaps:
) 23 39 PR(        CIRCLE\2011,8,1\202
        CIRCLE\2018,8,7\202
        -PIE\2018,8,60,120\202
        -PIE\2018,8,240,300\202
        CIRCLE\20115,8,2\202

          1 2 3 4 5 6 7 8 9 0 1 2 3 4 5
          - - - - - - - - - - - - - - -
      15: . . . . . . . . . . . . . . .
      14: . . . . 2 2 2 2 2 2 2 . . . .
      13: . . . 2 2 2 2 2 2 2 2 2 . . .
      12: . . 2 2 2 2 2 2 2 2 2 2 2 . .
      11: . . 2 2 2 2 2 2 2 2 2 2 2 . .
      10: . . . . 2 2 2 2 2 2 2 . . . .
       9: . . . . . . 2 2 2 . . . . . .
       8: . . . . . . . . . . . . . . .
       7: . . . . . . 2 2 2 . . . . . .
       6: . . . . 2 2 2 2 2 2 2 . . . .
       5: . . 2 2 2 2 2 2 2 2 2 2 2 . .
       4: . . 2 2 2 2 2 2 2 2 2 2 2 . .
       3: . . . 2 2 2 2 2 2 2 2 2 . . .
       2: . . . . 2 2 2 2 2 2 2 . . . .
       1: . . . . . . . . . . . . . . .)RP(
The two smaller circles are entirely contained within the two exclude
)BD(PIE)ES( slices and therefore are excluded from the region.





)0 P()0 0 1 A(Go to Funtools Help Index)0 0 TN TL()Ec /AF f D(

)0 5 125 H(Last)WB 205 Sn( updated: November 17, 2005)EH(

)WB NL
/Cb Db D /Ct [16#00 16#00 16#00] D /Cl [16#00 16#00 16#00] D /CL -1 D Ct Sc
DS
/Ba f D /BO 0 D Bs
/UR (regcoords.html) D
/Ti (Spatial Region Coordinates) D
/Au () D
/Df f D
/ME [()] D

0 BO R
()1 Sl()WB 57 Sn(


)0 2 126 H(RegCoords:)WB 207 Sn()WB 206 Sn( Spatial Region Coordinates)EA()EH(


)0 2 127 H(Summary)WB 208 Sn()EH(
)0 P(This document describes the specification of coordinate systems, and the 
interpretation of coordinate values, for spatial region filtering.


)0 2 128 H(Pixel)WB 209 Sn( coordinate systems)EH(
)0 P(The default coordinate system for regions is PHYSICAL, which means
that region position and size values are taken from the original
data. \201Note that this is a change from the original IRAF/PROS
implementation, in which the IMAGE coordinate system was the default.\202
PHYSICAL coordinates always refer to pixel positions on the original
image \201using IRAF LTM and LTV keywords\202.  With PHYSICAL coordinates,
if a set of coordinates specifies the position of an object in an
original FITS file, the same coordinates will specify the same object
in any FITS derived from the original.  Physical coordinates are
invariant with blocking of FITS files or taking sections of images,
even when a blocked section is written to a new file.

)0 P(Thus, although a value in pixels refers, by default, to the PHYSICAL
coordinate system, you may specify that position values refer to the
image coordinate system using the )BD(global)ES( or )BD(local)ES(
properties commands:

) 2 23 PR(  global coordsys image
  circle 512 512 100)RP(

The )BD(global)ES( command changes the coordinate system for all
regions that follow, while the )BD(local)ES( command changes the
coordinate system only for the region immediately following:
) 3 22 PR(  local coordsys image
  circle 512 512 100
  circle 1024 1024 200)RP(
This changes the coordinate system only for the region that follows.
In the above example, the second region uses the global coordinate
system \201PHYSICAL by default\202.

)0 P()0 2 129 H(World)WB 210 Sn( Coordinate Systems)EH(

If World Coordinate System information is contained in the data file
being filtered, it also is possible to define regions using a sky
coordinate system. Supported systems include:

) 10 67 PR(  name                  description
  ----                  -----------
  PHYSICAL              pixel coords of original file using LTM/LTV
  IMAGE                 pixel coords of current file
  FK4, B1950            sky coordinate systems
  FK5, J2000            sky coordinate systems
  GALACTIC              sky coordinate systems
  ECLIPTIC              sky coordinate systems
  ICRS                  currently same as J2000
  LINEAR                linear wcs as defined in file)RP(

In addition, two mosaic coordinate systems have been defined that
utilize the \201evolving\202 IRAF mosaic keywords:

) 4 68 PR(  name                  description
  ----                  -----------
  AMPLIFIER             mosaic coords of original file using ATM/ATV
  DETECTOR              mosaic coords of original file using DTM/DTV)RP(
Again, to use one of these coordinate systems, the )BD(global)ES( or
)BD(local)ES( properties commands are used:

) 1 26 PR(  global coordsys galactic)RP(

)0 2 130 H(WCS)WB 211 Sn( Positions and Sizes)EH(

In addition to pixels, positional values in a WCS-enabled region can
be specified using sexagesimal or degrees format:

) 11 57 PR(  position arguments    description
  ------------------    -----------
  [num]                 context-dependent \201see below\202
  [num]d                degrees
  [num]r                radians
  [num]p                physical pixels
  [num]i                image pixels
  [num]:[num]:[num]     hms for 'odd' position arguments
  [num]:[num]:[num]     dms for 'even' position arguments
  [num]h[num]m[num]s    explicit hms
  [num]d[num]m[num]s    explicit dms)RP(

If ':' is used as sexagesimal separator, the value is considered to be
specifying hours/minutes/seconds if it is the first argument of a
positional pair, and degrees/minutes/seconds for the second argument
of a pair \201except for galactic coordinates, which always use degrees\202:

) 7 78 PR(  argument      description
  -----------   -----------
  10:20:30.0    10 hours, 20 minutes, 30 seconds for 1st positional argument
                10 degrees, 20 minutes, 30 seconds for 2nd positional argument
  10h20m30.0    10 hours, 20 minutes, 30 seconds
  10d20m30.0    10 degrees, 20 minutes, 30 seconds
  10.20d        10.2 degrees)RP(

Similarly, the units of size values are defined by the formating
character\201s\202 attached to a number:

) 9 53 PR(  size arguments        description
  --------------        -----------
  [num]                 context-dependent \201see below\202
  [num]"                arc seconds
  [num]'                arc minutes
  [num]d                degrees
  [num]r                radians
  [num]p                physical pixels
  [num]i                image pixels)RP(

For example:
) 8 34 PR(  argument      description
  -----------   -----------
  10            ten pixels
  10'           ten minutes of arc
  10"           ten seconds of arc
  10d           ten degrees
  10p           ten pixels
  0.5r          half of a radian)RP(

)0 P(An example of using sky coordinate systems follows:

) 4 65 PR(  global coordsys B1950
  -box 175.54d 20.01156d 10' 10'
  local coordsys J2000
  pie 179.57d 22.4d 0 360 n=4 && annulus 179.57d 22.4d 3' 24' n=5)RP(

At the FK4 1950 coordinates 175.54d RA, 20.01156d DEC exclude a 10
minute by 10 minute box.  Then at the FK5 2000 coordinates 179.57d RA
22.4d DEC draw a radial profile regions pattern with 4 quadrants and 5
annuli ranging from 3 minutes to 24 minutes in diameter.  In this
example, the default coordinate system is overridden by the commands
in the regions spec.

)0 2 131 H(NB:)WB 212 Sn( The Meaning of Pure Numbers Are Context Sensitive)EH(

)0 P(When a "pure number" \201i.e. one without a format directive such as 'd'
for 'degrees'\202 is specified as a position or size, its interpretation
depends on the context defined by the 'coordsys' keyword. In general,
the rule is:

)0 P()BD(All pure numbers have implied units corresponding to the current
coordinate system.)ES(

)0 P(If no coordinate system is explicitly specified, the default system is
implicitly assumed to be PHYSICAL.  In practice this means that for
IMAGE and PHYSICAL systems, pure numbers are pixels.  Otherwise,
for all systems other than LINEAR, pure numbers are degrees. For
LINEAR systems, pure numbers are in the units of the linear system.
This rule covers both positions and sizes.

)0 P(As a corollary, when a sky-formatted number is used with the IMAGE
or PHYSICAL coordinate system \201which includes the default case of no
coordsys being specified\202, the formatted number is assumed to be in
the units of the WCS contained in the current file. If no sky WCS is
specified, an error results.

)0 P(Examples:

) 2 43 PR(  circle\201512,512,10\202
  ellipse 202.44382d 47.181656d 0.01d 0.02d)RP(

)0 P(In the absence of a specified coordinate system, the circle uses the
default PHYSICAL units of pixels, while the ellipse explicitly uses degrees,
presumably to go with the WCS in the current file.

) 5 43 PR( global coordsys=fk5 
 global color=green font="system 10 normal"
 circle 202.44382 47.181656 0.01
 circle 202.44382 47.181656 10p
 ellipse\201512p,512p,10p,15p,20\202)RP(


)0 P(Here, the circles use the FK5 units of degrees \201except for the
explicit use of pixels in the second radius\202, while the ellipse
explicitly specifies pixels. The ellipse angle is in degrees.

)0 P(Note that Chandra data format appears to use "coordsys=physical"
implicitly.  Therefore, for most Chandra applications, valid regions
can be generated safely by asking ds9 to save/display regions in
pixels using the PHYSICAL coordsys.





)0 P()0 0 1 A(Go to Funtools Help Index)0 0 TN TL()Ec /AF f D(

)0 5 132 H(Last)WB 213 Sn( updated: November 17, 2005)EH(

)WB NL
/Cb Db D /Ct [16#00 16#00 16#00] D /Cl [16#00 16#00 16#00] D /CL -1 D Ct Sc
DS
/Ba f D /BO 0 D Bs
/UR (regbounds.html) D
/Ti (Spatial Region Boundaries) D
/Au () D
/Df f D
/ME [()] D

0 BO R
()1 Sl()WB 58 Sn(


)0 2 133 H(RegBounds:)WB 215 Sn()WB 214 Sn( Region Boundaries)EA()EH(


)0 2 134 H(Summary)WB 216 Sn()EH(
Describes how spatial region boundaries are handled.


)0 2 135 H(Description)WB 217 Sn()EH(
)0 P(The golden rule for spatial region filtering was first enunciated by
Leon VanSpeybroeck in 1986:

)0 P()BD(Each photon will be counted once, and no photon will be counted
more than once)ES(.

)0 P(This means that we must be careful about boundary
conditions.  For example, if a circle is contained in an annulus such
that the inner radius of the annulus is the same as the radius of the
circle, then photons on that boundary must always be assigned to one
or the other region. That is, the number of photons in both regions
must equal the sum of the number of photons in each region taken
separately.

With this in mind, the rules for determining whether a boundary image
pixel or table row are assigned to a region are defined below.

)0 2 136 H(Image)WB 218 Sn( boundaries : radially-symmetric shapes \201circle, annuli, ellipse\202)EH(

For image filtering, pixels whose center is inside the boundary are
included.  This also applies non-radially-symmetric shapes.  When a
pixel center is exactly on the boundary, the pixel assignment rule is:

)UL()-1 LI( the outer boundary of a symmetric shape does not include such pixels
)-1 LI( the inner boundary of a symmetric shape \201annulus\202 includes such pixels)LU(

In this way, an annulus with radius from 0 to 1, centered exactly on a
pixel, includes the pixel on which it is centered, but none of its
neighbors.

These rules ensure that when defining concentric shapes, no pixels are
omitted between concentric regions and no pixels are claimed by two
regions.  When applied to small symmetric shapes, the shape is less
likely to be skewed, as would happen with non-radially-symmetric
rules.  These rules differ from the rules for box-like shapes, which
are more likely to be positioned adjacent to one another.

)0 2 137 H(Image)WB 219 Sn( Boundaries: non-radially symmetric shapes \201polygons, boxes\202)EH(

For image filtering, pixels whose center is inside the boundary are
included. This also applies radially-symmetric shapes.  When a pixel
center is exactly on the boundary of a non-radially symmetric region,
the pixel is included in the right or upper region, but not the left
or lower region.  This ensures that geometrically adjoining regions
touch but don't overlap.

)0 2 138 H(Row)WB 220 Sn( Boundaries are Analytic)EH(

When filtering table rows, the boundary rules are the same as for
images, except that the calculation is not done on the center of a
pixel, \201since table rows, especially X-ray events rows, often have
discrete, floating point positions\202 but are calculated exactly. That
is, an row is inside the boundary without regard to its integerized
pixel value.  For rows that are exactly on a region boundary, the
above rules are applied to ensure that all rows are counted once and
no row is counted more than once.

)0 P(Because row boundaries are calculated differently from image boundaries,
certain programs will give different results when filtering the same
region file. In particular, fundisp/funtable \201which utilize analytic
row filtering\202 perform differently from funcnts \201which performs image
filtering, even on tables\202.

)0 2 139 H(Image)WB 221 Sn( Boundaries vs. Row Boundaries: Practical Considerations)EH(

)0 P(You will sometimes notice a discrepancy between running funcnts on an
binary table file and running fundisp on the same file with the same filter.
For example, consider the following:
) 2 49 PR(  fundisp test1.fits"[box\2014219,3887,6,6,0\202]" | wc
  8893  320148 3752846)RP(
Since fundisp has a 2-line header, there are actually 8891 photons
that pass the filter.  But then run funtable and select only the
rows that pass this filter, placing them in a new file:
) 1 58 PR(  ./funtable test1.fits"[box\2014219,3887,6,6,0\202]" test2.fits)RP(
Now run funcnts using the original filter on the derived file:
) 12 61 PR(  ./funcnts test2.fits "physical; box\2014219,3887,6,6,0\202"

  [... lot of processed output ...]

  # the following source and background components were used:
  source region\201s\202
  ----------------
  physical; box\2014219,3887,6,6,0\202
 
   reg       counts    pixels
  ---- ------------ ---------
     1     7847.000        36)RP(
There are 1044 rows \201events\202 that pass the row filter in fundisp \201or
funtable\202 but fail to make it through funcnts. Why?

)0 P(The reason can be traced to how analytic row filtering \201fundisp, funtable\202
differs from integerized pixel filtering\201funcnts, funimage\202. Consider the
region:
) 1 22 PR(  box\2014219,3887,6,6,0\202)RP(
Analytically \201i.e., using row filtering\202, positions will pass this
filter successfully if:
) 2 19 PR(  4216 <= x <= 4222
  3884 <= y <= 3890)RP(
For example, photons with position values of x=4216.4 or y=3884.08 will pass.

)0 P(Integerized image filtering is different in that the pixels that will
pass this filter have centers at:
) 2 40 PR(  x = 4217, 4218, 4219, 4220, 4221, 4222
  y = 3885, 3886, 3887, 3888, 3889, 3890)RP(
Note that there are 6 pixels in each direction, as specified by the region.
That means that positions will pass the filter successfully if:
) 2 24 PR(  4217 <= \201int\202x <= 4222
  3885 <= \201int\202y <= 3890)RP(
Photons with position values of x=4216.4 or y=3884.08 will NOT pass.

)0 P(Note that the position values are integerized, in effect, binned into
image values.  This means that x=4222.4 will pass this filter, but not
the analytic filter above. We do this to maintain the design goal that
either all counts in a pixel are included in an integerized filter, or
else none are included.

)0 P([It could be argued that the correct photon limits for floating point
row data really should be:
) 2 23 PR(  4216.5 <= x <= 4222.5
  3884.5 <= y <= 3890.5)RP(
since each pixel extends for .5 on either side of the center. We chose
to the maintain integerized algorithm for all image-style filtering so
that funcnts would give the exact same results regardless of whether
a table or a derived non-blocked binned image is used.]





)0 P()0 0 1 A(Go to Funtools Help Index)0 0 TN TL()Ec /AF f D(

)0 5 140 H(Last)WB 222 Sn( updated: November 16, 2005)EH(

)WB NL
/Cb Db D /Ct [16#00 16#00 16#00] D /Cl [16#00 16#00 16#00] D /CL -1 D Ct Sc
DS
/Ba f D /BO 0 D Bs
/UR (regdiff.html) D
/Ti (Differences Between Funtools and IRAF Regions) D
/Au () D
/Df f D
/ME [()] D

0 BO R
()1 Sl()WB 59 Sn(


)0 2 141 H(RegDiff:Differences)WB 224 Sn()WB 223 Sn( Between Funtools and IRAF Regions)EA()EH(


)0 2 142 H(Summary)WB 225 Sn()EH(
Describes the differences between Funtools/ds9 regions and the old IRAF/PROS
regions.


)0 2 143 H(Description)WB 226 Sn()EH(
)0 P(We have tried to make Funtools regions compatible with their
predecessor, IRAF/PROS regions. For simple regions and simple boolean
algebra between regions, there should be no difference between the two
implementations.  The following is a list of differences and
incompatibilities between the two:

)UL(
)0 P()-1 LI(If a pixel is covered by two different regions expressions,
Funtools assigns the mask value of the )BD(first)ES( region that
contains that pixel.  That is, successive regions )BD(do not)ES(
overwrite previous regions in the mask, as was the case with the
original PROS regions.  This means that one must define overlapping
regions in the reverse order in which they were defined in PROS.  If
region N is fully contained within region M, then N should be defined
)BD(before)ES( M, or else it will be "covered up" by the latter. This
change is necessitated by the use of optimized filter compilation, i.e.,
Funtools only tests individual regions until a proper match is made.

)0 P()-1 LI( The )BD(PANDA)ES( region has replaced the old PROS syntax in which
a )BD(PIE)ES( accelerator was combined with an )BD(ANNULUS)ES( accelerator
using )BD(AND)ES(. That is,
) 1 48 PR(  ANNULUS\20120,20,0,15,n=4\202 & PIE\20120,20,0,360,n=3\202)RP(
has been replaced by:
) 1 29 PR(  PANDA\20120,20,0,360,3,0,15,4\202)RP(
The PROS syntax was inconsistent with the meaning of the )BD(AND)ES( operator.

)0 P()-1 LI( The meaning of pure numbers \201i.e., without format specifiers\202 in 
regions has been clarified, as has the syntax for specifying coordinate
systems. See the general discussion on
)0 54 1 A(Spatial Region Filtering)54 0 TN TL()Ec /AF f D(
for more information.
)LU(





)0 P()0 0 1 A(Go to Funtools Help Index)0 0 TN TL()Ec /AF f D(

)0 5 144 H(Last)WB 227 Sn( updated: November 16, 2005)EH(

)WB NL
/Cb Db D /Ct [16#00 16#00 16#00] D /Cl [16#00 16#00 16#00] D /CL -1 D Ct Sc
DS
/Ba f D /BO 0 D Bs
/UR (combo.html) D
/Ti (Combining Region and Table Filters) D
/Au () D
/Df f D
/ME [()] D

0 BO R
()1 Sl()WB 60 Sn(


)0 2 145 H(FunCombine:)WB 230 Sn()WB 228 Sn( Combining Region and Table Filters)EA()EH(


)0 2 146 H(Summary)WB 231 Sn()EH(
)0 P(This document discusses the conventions for combining region and table
filters, especially with regards to the comma operator.



)0 2 147 H(Comma)WB 232 Sn()WB 229 Sn( Conventions)EA()EH(
)0 P(Filter specifications consist of a series of boolean expressions,
separated by commas. These expressions can be table filters,
spatial region filters, or combinations thereof. Unfortunately,
common usage requires that the comma operator must act differently
in different situations. Therefore, while its use is intuitive in
most cases, commas can be a source of confusion.

)0 P(According to long-standing usage in IRAF, when a comma separates two
table filters, it takes on the meaning of a boolean )BD(and)ES(. Thus:
) 1 24 PR(  foo.fits[pha==1,pi==2])RP(
is equivalent to:
) 1 27 PR(  foo.fits[pha==1 && pi==2])RP(

When a comma separates two spatial region filters, however, it has
traditionally taken on the meaning of a boolean )BD(or)ES(. Thus:
) 1 46 PR(  foo.fits[circle\20110,10,3\202,ellipse\20120,20,8,5\202])RP(
is equivalent to:
) 1 49 PR(  foo.fits[circle\20110,10,3\202 || ellipse\20120,20,8,5\202])RP(
\201except that in the former case, each region is given a unique id
in programs such as funcnts\202.

)0 P(Region and table filters can be combined:
) 1 34 PR(  foo.fits[circle\20110,10,3\202,pi=1:5])RP(
or even:
) 1 61 PR(  foo.fits[pha==1&&circle\20110,10,3\202,pi==2&&ellipse\20120,20,8,5\202])RP(
In these cases, it is not obvious whether the command should utilize an
)BD(or)ES( or )BD(and)ES( operator. We therefore arbitrarily chose to
implement the following rule:
)UL()-1 LI( if both expressions contain a region, the operator used is )BD(or)ES(.
)-1 LI( if one \201or both\202 expression\201s\202 does not contain a region, the operator
used is )BD(and)ES(.)LU(
This rule handles the cases of pure regions and pure column filters properly.
It unambiguously assigns the boolean )BD(and)ES( to all mixed cases. Thus:
) 1 34 PR(  foo.fits[circle\20110,10,3\202,pi=1:5])RP(
and
) 1 34 PR(  foo.fits[pi=1:5,circle\20110,10,3\202])RP(
both are equivalent to:
) 1 37 PR(  foo.fits[circle\20110,10,3\202 && pi=1:5])RP(

)0 P([NB: This arbitrary rule )BD(replaces the previous arbitrary rule)ES(
\201pre-funtools 1.2.3\202 which stated:
)UL()-1 LI( if the 2nd expression contains a region, the operator used is )BD(or)ES(.
)-1 LI( if the 2nd expression does not contain a region, the operator
used is )BD(and)ES(.)LU(
In that scenario, the )BD(or)ES( operator was implied by:
) 1 21 PR(  pha==4,circle 5 5 1)RP(
while the )BD(and)ES( operator was implied by
) 1 21 PR(  circle 5 5 1,pha==4)RP(
Experience showed that this non-commutative treatment of the comma
operator was confusing and led to unexpected results.]

)0 P(The comma rule must be considered provisional: comments and complaints
are welcome to help clarify the matter. Better still, we recommend
that the comma operator be avoided in such cases in favor of an
explicit boolean operator.





)0 P()0 0 1 A(Go to Funtools Help Index)0 0 TN TL()Ec /AF f D(

)0 5 148 H(Last)WB 233 Sn( updated: November 16, 2005)EH(

)WB NL
/Cb Db D /Ct [16#00 16#00 16#00] D /Cl [16#00 16#00 16#00] D /CL -1 D Ct Sc
DS
/Ba f D /BO 0 D Bs
/UR (env.html) D
/Ti (Funtools Environment Variables) D
/Au () D
/Df f D
/ME [()] D

0 BO R
()1 Sl()WB 61 Sn(


)0 2 149 H(FunEnv:)WB 235 Sn()WB 234 Sn( Funtools Environment Variables)EA()EH(


)0 2 150 H(Summary)WB 236 Sn()EH(
Describes the environment variables which can be used to tailor the overall
Funtools environment.


)0 2 151 H(Description)WB 237 Sn()EH(
)0 P(The following environment variables are supported by Funtools:
)0 DL()0 P()0 DT()BD(FITS_EXTNAME)ES(
)DD( The )BD(FITS_EXTNAME)ES( environment variable specifies the
default FITS extension name when )0 25 1 A(FunOpen\201\202)25 0 TN TL()Ec /AF f D( is called on a file lacking
a primary image. Thus,
) 1 29 PR(  setenv FITS_EXTNAME "NEWEV")RP(
will allow you to call )0 25 1 A(FunOpen\201\202)25 0 TN TL()Ec /AF f D( on files without specifying NEWEV in
the
)0 42 1 A(Funtools bracket specification)42 0 TN TL()Ec /AF f D(.
If no FITS_EXTNAME variable is defined and the extension name also is
not passed in the bracket specification, then the default will be to
look for standard X-ray event table extension names "EVENTS" or
"STDEVT" \201we are, after all, and X-ray astronomy group at heart!\202.

)0 P()0 DT()BD(FITS_EXTNUM)ES(
)DD( The )BD(FITS_EXTNUM)ES( environment variable specifies the
default FITS extension number when )0 25 1 A(FunOpen\201\202)25 0 TN TL()Ec /AF f D( is called on a file lacking
a primary image. Thus,
) 1 22 PR(  setenv FITS_EXTNUM 7)RP(
will allow you to call )0 25 1 A(FunOpen\201\202)25 0 TN TL()Ec /AF f D( on files to open the seventh 
extension without specifying the number in the
)0 42 1 A(Funtools bracket specification)42 0 TN TL()Ec /AF f D(.

)0 P()0 DT()BD(FITS_BINCOLS)ES( and )BD(EVENTS_BINCOLS)ES(
)DD( These environment variable specifies the default binning key for 
FITS binary tables and raw event files, respectively. They can be
over-ridden using the )BD(bincols=[naxis1,naxis2])ES( keyword in a
)0 42 1 A(Funtools bracket specification)42 0 TN TL()Ec /AF f D(.
The value of each environment variable
is a pair of comma-delimited columns, enclosed in parentheses, to use
for binning.  For example, if you want to bin on detx and dety by
default, then use:
) 1 35 PR(  setenv FITS_BINCOLS "\201detx,dety\202")RP(
in preference to adding a bincols specification to each filename:
) 1 31 PR(  foo.fits[bincols=\201detx,dety\202])RP(

)0 P()0 DT()BD(FITS_BITPIX)ES( and )BD(EVENTS_BITPIX)ES(
)DD( These environment variable specifies the default bitpix value for
binning FITS binary tables and raw event files, respectively. They can
be over-ridden using the )BD(bitpix=[value])ES( keyword in a 
)0 42 1 A(Funtools bracket specification)42 0 TN TL()Ec /AF f D(.  The value
of each environment variable is one of the standard FITS bitpix values
\2018,16,32,-32,-64\202.  For example, if you want binning routines to
create a floating array, then use:
) 1 24 PR(  setenv FITS_BITPIX -32)RP(
in preference to adding a bitpix specification to each filename:
) 1 22 PR(  foo.fits[bitpix=-32])RP(

)0 P()0 DT()BD(ARRAY)ES(
)DD( The )BD(ARRAY)ES( environment variable specifies the default
definition of an array file for Funtools.
It is used if there is no array specification passed in the
)BD(ARRAY\201\202)ES( directive in a
)0 46 1 A(Non-FITS Array specification)46 0 TN TL()Ec /AF f D(.
The value of the environment variable is a valid array specification such as:
) 2 25 PR(  setenv ARRAY "s100.150"
  foo.arr[ARRAY\201\202])RP(
This can be defined in preference to adding the specification to each filename:
) 1 26 PR(  foo.arr[ARRAY\201s100.150\202])RP(

)0 P()0 DT()BD(EVENTS)ES(
)DD( The )BD(EVENTS)ES( environment variable specifies the default
definition of an raw event file for Funtools.
It is used if there is no EVENTS specification passed in the
)BD(EVENTS\201\202)ES( directive in a
)0 45 1 A(Non-FITS EVENTS specification)45 0 TN TL()Ec /AF f D(.
The value of the environment variable is a valid EVENTS specification such as:
) 2 73 PR(  setenv EVENTS "x:J:1024,y:J:1024,pi:I,pha:I,time:D,dx:E:1024,dx:E:1024"
  foo.ev[EVENTS\201\202])RP(
This can be defined in preference to adding the specification to each filename:
) 1 73 PR(  foo.ev[EVENTS\201x:J:1024,y:J:1024,pi:I,pha:I,time:D,dx:E:1024,dx:E:1024\202])RP()LD(

The following filter-related environment variables are supported by Funtools:
)0 DL(
)0 P()0 DT()BD(FILTER_PTYPE)ES(
)DD( The )BD(FILTER_PTYPE)ES( environment variable specifies how to
build a filter.  There are three possible methods:
)0 DL()0 DT(process or p
)DD(The filter is compiled and linked against the funtools library \201which
must therefore be accessible in the original install directory\202 to produce
a slave program. This program is fed events or image data and returns
filter results.

)0 DT(dynamic or d \201gcc only\202
)DD(The filter is compiled and linked against the funtools library \201which
must therefore be accessible in the original install directory\202 to produce
a dynamic shared object, which is loaded into the funtools program and
executed as a subroutine. \201Extensive testing has shown that, contrary to
expectations, this method is no faster than using a slave process.\202

)0 DT(contained or c
)DD(The filter and all supporting region code is compiled and linked
without reference to the funtools library to produce a slave program
\201which is fed events or image data and returns filter results\202. This method
is slower than the other two, because of the time it takes to compile the
region filtering code. It is used by stand-alone programs such as ds9,
which do not have access to the funtools library.)LD(

By default, )BD(dynamic)ES( is generally used for gcc compilers and
)BD(process)ES( for other compilers. However the filter building algorithm
will check for required external files and will use )BD(contained)ES( is
these are missing.

)0 P()0 DT()BD(FUN_MAXROW)ES(
)DD( The )BD(FUN_MAXROW)ES( environment variable is used by core
row-processing Funtools programs \201funtable, fundisp, funcnts, funhist,
funmerge, and funcalc\202 to set the maximum number of rows read at once
\201i.e. it sets the third argument to the FunTableRowGet\201\202 call\202.  The
default is 8192. Note that this variable is a convention only: it will
not be a part of a non-core Funtools program unless code is explicitly
added, since each call to FunTableRowGet\201\202 specifies its own maximum
number of rows to read. NB: if you make this value very large, you
probably will need to increase )BD(FUN_MAXBUFSIZE)ES( \201see below\202 as well.

)0 P()0 DT()BD(FUN_MAXBUFSIZE)ES(
)DD( The )BD(FUN_MAXBUFSIZE)ES( environment variable is used to limit the
max buffer size that will be allocated to hold table row data.  This
buffer size is calculated to be the row size of the table multiplied
by the maximum number of rows read at once \201see above\202. Since the
row size is unlimited \201and we have examples of it being larger than 5
Mb\202, it is possible that the total buffer size will exceed the machine
capabilities. We therefore set a default value of 5Mb for the max buffer
size, and adjust maxrow so that the total size calculated is less than
this max buffer size. \201If the row size is greater than this max buffer
size, then maxrow is set to 1.\202 This environment variable will change
the max buffer size allowed.

)0 P()0 DT()BD(FILTER_CC)ES(
)DD( The )BD(FILTER_CC)ES( environment variable specifies the compiler to
use for compiling a filter specification. You also can use the )BD(CC)ES(
environment variable. If neither has been set, then gcc will be used
if available. Otherwise cc is used if available.

)0 P()0 DT()BD(FILTER_EXTRA)ES(
)DD( The )BD(FILTER_EXTRA)ES( environment variable specifies extra options
to add to a filter compile command line. In principle, you can add libraries,
include files, and compiler switches. This variable should be used with care.

)0 P()0 DT()BD(FILTER_TMPDIR)ES(
)DD( The )BD(FILTER_TMPDIR)ES( environment variable specifies the temporary
directory for filter compilation intermediate files. You also can use
the )BD(TMPDIR)ES( and )BD(TMP)ES( variables. By default, /tmp is used
as the temporary directory.

)0 P()0 DT()BD(FILTER_KEEP)ES(
)DD( The )BD(FILTER_KEEP)ES( environment variable specifies whether the
intermediate filter files \201i.e. C source file and compile log file\202
should be saved after a filter is built. The default is "false", so that
these intermediate files are deleted. This variable is useful for debugging,
but care should be taken to reset its value to false when debugging is
complete.
)LD(





)0 P()0 0 1 A(Go to Funtools Help Index)0 0 TN TL()Ec /AF f D(

)0 5 152 H(Last)WB 238 Sn( updated: November 16, 2005)EH(


)WB NL
/Cb Db D /Ct [16#00 16#00 16#00] D /Cl [16#00 16#00 16#00] D /CL -1 D Ct Sc
DS
/Ba f D /BO 0 D Bs
/UR (changelog.html) D
/Ti (Funtools ChangeLog) D
/Au () D
/Df f D
/ME [()] D

0 BO R
()1 Sl()WB 62 Sn(
)0 2 153 H(Funtools)WB 239 Sn( ChangeLog)EH(

)0 P(This ChangeLog covers both the Funtools library and the suite of
applications. It will be updated as we continue to develop and improve
Funtools.  The up-to-date version can be found
)R5 2 A(here)EA(.
[The changelog for the initial development of Funtools, covering the
beta releases, can be found
)R6 2 A(here)EA(.]

)0 2 154 H()WB 240 Sn( Patch Release 1.4.5 \201internal ds9 release\202)EH(
)UL()0 P()-1 LI( Removed permission checking from Find\201\202 on cygwin systems. This was broken
by Windows 7.
)0 P()-1 LI( Removed addition of -no-cpp-precomp flag from gcc 4.2 and beyond.)LU(

)0 2 155 H()WB 241 Sn( Patch Release 1.4.4 \201internal ds9 release\202)EH(
)UL()0 P()-1 LI( Fixed -J funcone, which was not properly outputting all rows.
)0 P()-1 LI( Filter: when an image is flipped, the rotation angle must be reversed.
)0 P()-1 LI( Filter: add support for windows-based ipc communication when using tcc
compiler.)LU(

)0 2 156 H()WB 242 Sn( Patch Release 1.4.3 \201internal ds9 release\202)EH(
)UL()0 P()-1 LI( Filter: improve checks for existence of compiler, even if CC is set.
)0 P()-1 LI( Change launch.h to xlaunch.h to avoid conflict with OS X.
)0 P()-1 LI( handle flipped images in filtering)LU(

)0 2 157 H()WB 243 Sn( Patch Release 1.4.2 \201internal ds9 release\202)EH(
)UL()0 P( 
)-1 LI( Port to gcc 4.2.
)0 P()-1 LI( Fix 1-byte filters on intel machines \201missing SW1 no-op\202.
)0 P()-1 LI( Remove ambiguity from filt.l \201and calc.l\202 using [A-z] in a
case-insensitive lexer.
)0 P()-1 LI( In funsky, the default unit for RA was changed from hours to degrees.
)0 P()-1 LI( Fixed bug in funtable in which TCRVL header values were output as strings.
)0 P()-1 LI( Added support for running funtools filters in Rosetta \201i.e. running PPC
executables on an Intel Mac\202 by sensing and handling data swap requirements.
Only works with FILTER_PTYPE set to 'c' \201can't link against wrong architecture
libraries\202.
)0 P()-1 LI( Fixed bug in FITS library to allow "-" in extension names.
)0 P()-1 LI( Code and documentation now agree that the copy extension specifier \201'+'\202
comes after the extension name.)LU(

)0 2 158 H()WB 244 Sn( Patch Release 1.4.1 \201internal ds9 release\202)EH(
)UL()0 P()-1 LI( Modified internal Launch\201\202 routine to use posix_spawn\201\202, if necessary.
This is required for OS X 10.5 \201leopard\202, which frowns upon use of fork\201\202
and exec\201\202. Also modified zprocess routines to use Launch\201\202.)LU(

)0 2 159 H()WB 245 Sn( Public Release 1.4.0 \20115 August 2007\202)EH(

)UL()-1 LI( Public release of production-quality code, incorporating changes
and improvements from previous beta releases, including:
)UL()-1 LI( Support for access to ASCII text column files.
)-1 LI( Support for fast indexed access of binary tables.
)-1 LI( Support for database views of tables, i.e. pre-set values for the filter
  specification, the columns to activate, and display format.
)-1 LI( New programs include funcone \201cone search\202, funindex \201create index files\202,
  and funcen \201calculate centroids within regions\202.)LU(
)LU(

)0 2 160 H()WB 246 Sn( Release 1.3.0b[n] \201mainly internal SAO beta releases\202)EH(
)UL(
)0 P()-1 LI( Added -F[c] switch to change the column delimiter to the
specified character.

)0 P()-1 LI( Extended fundisp's format switch \201-f\202 so that it can now handle complex
formats such as 'x=sometext%3d- y=othertest%3d.ext'.

)0 P()-1 LI( Added support for creating and processing 1D FITS images.

)0 P()-1 LI( Added vcol=colname and vcol=/colname to filter specifications to
support use of a third value column when binning 2D images.

)0 P()-1 LI( Added switches to funcone to write out data rows are not within
any cone \201-J, -X\202 and centers which have no close data rows \201-L\202.

)0 P()-1 LI( In funjoin, added ability to specify a numeric tolerance for when joining
two files.

)0 P()-1 LI( shared memory support in gio now can create a shared segment if w+ is
specified as the open mode.

)0 P()-1 LI( Changed reggeometry man page so that examples correctly show angles
going counter-clockwise from the x-axis instead of from the y-axis.

)0 P()-1 LI( Added checks to funmerge to ensure that all files have the same columns.

)0 P()-1 LI( Fixed bug in text support that prevented header-less files from being
processed properly.

)0 P()-1 LI( Added support for 64-bit images \201bitpix=64\202 and table columns \201TFORM=K\202.

)0 P()-1 LI( Filter code was not applying bscale/bzero to columns.

)0 P( 
)-1 LI( Fixed funimage bug that caused a .5/block error in WCS CRPIX values
generated from binary tables.

)0 P()-1 LI( Added feq\201a,b\202 and div\201a,b\202 macros to funcalc.

)0 P()-1 LI( Added support for single-line #define to funcalc.

)0 P()-1 LI( Updated wcs library to 3.6.6

)0 P()-1 LI( Fix bug in funcen in which ra,dec was not being calculated correctly
if physical and image coords did not match up.

)0 P()-1 LI( The filter syntax "col1 = col2" now explicitly generates an error
\201you really want to do "col1 == col2"\202.

)0 P()-1 LI( Added -o switch to include offset from the nominal target position.

)0 P()-1 LI( Fundisp now displays multi-dimensional vector columns properly.

)0 P()-1 LI( Documented support for lists of files processed as a single file
using "list: file1 ... filen" syntax.

)0 P()-1 LI( Fixed bugs in support for pipe file type \201i.e. ability to pass
commands as a filename using "pipe: cmd arg1 ... argn" syntax\202.

)0 P()-1 LI( Fixed bug in funhist processing of image-based pixel histograms
\201i.e using "xy" for columns\202 where a region was specified. All pixels
outside the region were erroneously being added to the bin containing
the 0 value.

)0 P()-1 LI( Disabled multi-file processing in funds9, which was breaking support
for pathnames containing spaces and is not used by ds9 anyway.

)0 P()-1 LI( Added support for Views of tables, i.e.  pre-set values for the
filter specification, the columns to activate, and display format
\201though the latter is for fundisp only\202.

)0 P()-1 LI( Added -l switch to funimage to read x, y, val columns from a list.

)0 P()-1 LI( Removed useless and meaningless section syntax foo'[*]' because it
breaks pointer de-referencing on string columns \201i.e. foo'[*xxx=='a']'\202.
Use foo'[*,*]' instead, as documented.

)0 P()-1 LI( String variables were not always being terminated properly in the
filter code because FITS 'A' data is not necessarily null-terminated.

)0 P()-1 LI( Added funtools version number to all usage\201\202 displays.

)0 P()-1 LI( Added explanation of switch arguments to many usage\201\202 displays.

)0 P()-1 LI( The filter keyword row# now supports single row selection as well
as range selection, i.e., "row#=100" along with previous "row#=100:200".

)0 P()-1 LI( fundisp now outputs "0x" before hex values.

)0 P()-1 LI( Fixed bug in filter parser which processed rangelists incorrectly
if spaces were put into the rangelist \201i.e. "pha= 1 : 3" instead of
pha=1:3\202.

)0 P()-1 LI( Fixed a bug in funindex which created a wrongly named index file
if more than one "." was in the input file name.

)0 P()-1 LI( Added support to funcone to take ra, dec, radius from a list
\201i.e. columns in a FITS file or a text file\202.

)0 P()-1 LI( Fixed a bug in FunColumnActivate so that if some columns are
explicitly activated while others are de-activated, only the
explicitly activated columns are activated \201code was activating all
columns in this case\202.

)0 P()-1 LI( Fixed a bug in funindex which prevented indexing tables containing
a column named N.

)0 P()-1 LI( fundisp now encloses ASCII column values in single quotes \201unless
-T is specified to output RDB format\202.

)0 P()-1 LI( If a filter specification only involves indexed columns, then the
compiled filter is not used.

)0 P()-1 LI( Funmerge can now be given a list of files to merge using @list syntax.
Also removed the restriction on how many files can be merged \201was limited to
the max number of open files\202.

)0 P()-1 LI( Added ability to edit \201add, delete, modify\202 header parameters in funhead
by specifying an output file \201editing acts as a filter\202 and an edit command
file \201which can be stdin\202.

)0 P()-1 LI( Funtools now contains preliminary code to support \201fast\202 indexed access
of binary tables. See idx.html or "man funidx" for more details.

)0 P()-1 LI( Funtools now contains preliminary code supporting access to ASCII
column files. See text.html or "man funtext" for more details.

)0 P()-1 LI( Fixed bug in funcalc in which columns used in an expression were
always being replaced by new columns, with all associated parameters
\201e.g. WCS\202 were being deleted. Now this only happens if the column
explicitly changes its data type.

)0 P()-1 LI( Fixed bug in funcalc in which the raw data and user data became out
of sync for one row after every 8192 \201FUN_MAXROW\202 rows.

)0 P()-1 LI( Fixed bug in gio in which gseek returned 0 instead of the current byte
offset for disk files.

)0 P()-1 LI( Added funcone program to perform cone search on RA, Dec columns in
a FITS binary table.

)0 P()-1 LI( Fixed bug in polygon, pie and rotated box region filtering for
tables \201nearby rows exactly in line between two non-vertical or
non-horizontal vertices were being accepted incorrectly\202.

)0 P()-1 LI( Fixed pie and panda regions so that the angles now start from
positive x axis == 0 degrees and run counter-clockwise, as
documented. They were going from positive y. NB: a similar change
was made to ds9 release 4.0b3. You must be using ds9 4.0b3 or later
in order to have the correct behavior when generating regions in ds9
and using them in funtools.

)0 P()-1 LI( Added -p [prog] switch to funcalc to save the generated program.
instead of executing \201and deleting\202 it.

)0 P()-1 LI( Upgraded zlib to 1.2.3.
)LU(

)0 2 161 H()WB 247 Sn( Patch Release 1.2.4 \201internal SAO and beta release only\202)EH(
)UL(
)0 P()-1 LI( In funcalc, added support for user-specified arguments via the
-a [argstr] switch. These arguments are accessed in the compiled program
using the supplied ARGC and ARGV\201n\202 macros.

)0 P()-1 LI( Added -n \201no header display\202 to fundisp to skip outputting header.

)0 P()-1 LI( Added checks for various types of blank filters.

)0 P( 
)-1 LI( Added macros NROW \201current row number\202 and WRITE_ROW \201write current
row to disk\202 to funcalc.

)0 P()-1 LI( funcalc no longer requires that at least one data column be
specified in the compiled expression.

)0 P()-1 LI( Added FUN_NROWS to FunInfoGet\201\202 to return the total number of rows in
an input table \201i.e. value of NAXIS2\202.

)0 P( 
)-1 LI( The compiled funcalc program now includes stdlib.h and unistd.h.

)0 P()-1 LI( The util/NaN.h header file is now modified at configure time to
contain endian status for the target architecture. References to
specific platforms have been removed.

)0 P()-1 LI( Added -m switch to funtable to output multiple files, one for
each input region \201and a separate file for events that pass the
filters but are not in any region\202.

)0 P()-1 LI( Added ability to add new parameters \201FunParamPutx\202 after writing
data if space is previously reserved in the form of a blank parameter
whose value is the name of the param to be updated. \201Also requires the
append argument of FunParamPutx be set to 2\202.

)0 P( 
)-1 LI( Added ability to build shared libraries. With --enable-shared=yes,
shared library is built but not used. With --enable-shared=link,
shared library is linked against \201requires proper installation and/or
use of LD_LIBRARY_PATH\202.

)0 P()-1 LI( Added -v [column] support to funcnts so that counts in a table
can be accumulated using values from a specified column \201instead of
the default case where an integral count is accumulated for each event
in a region\202.

)0 P()-1 LI( Added funcen program to calculate centroids within regions
\201binary tables only\202. Also added support for a funcen-based centroid
tool to funtools.ds9.

)0 P()-1 LI( Fixed bug which prevented successful filtering of columns containing
arrays.

)0 P()-1 LI( Added filter check to ensure that a column is not incorrectly used
as an array.

)0 P()-1 LI( Fundisp now displays column arrays indexed from 0, not 1.

)0 P()-1 LI( Added -i [interval] support to funcnts so that multiple intervals
can be processed in a single pass through the data. For example,
specifying -i "pha=1:5;pha=6:10;pha=11:15" will generate results in
each of 3 pha bands.

)0 P()-1 LI( Fixed calculation of LTV quantities when binning floating point
column data \201value was off by 0.5\202.

)0 P()-1 LI( Added support for 'D' in floating point header values.

)0 P()-1 LI( Added -a switch to funimage and funtable to append output image or
table to an existing FITS file \201as an IMAGE or BINTABLE extension\202.

)0 P()-1 LI( Added support for column scaling \201TSCAL and TZERO\202 on input columns.
Note that the default column type is changed to accommodate scaling \201e.g.
a column of type 'I' is changed to 'J', 'J' is changed to 'D'\202 so that
the scaled values can be handled properly by programs such as fundisp
\201which utilize default types\202.

)0 P( 
)-1 LI( Added support to FunColumnSelect\201\202 for handling structs of arrays
\201i.e. where returned columns are contiguous\202 instead of the default array
of structs \201returned row are contiguous\202. This is done by specifying
"org=structofarrays" in the plist and passing a single struct containing
the arrays.

)0 P()-1 LI( When writing an rdb/starbase file, fundisp now outputs the full
column name, regardless of the width of the column \201which ordinarily
is truncated to match\202.

)0 P()-1 LI( Fixed support for large files by changing all file positions variables
from "long" declarations to "off_t.

)0 P()-1 LI( Fixed bug in funcalc incorrectly processed multiple array
references \201e.g. cur->foo[0]=cur->x;cur->foo[1]=cur->y;\202 within a single
line of code.

)0 P()-1 LI( Added FILTER_CFLAGS environment variable for all filtering. Also added
--with-filter-cc and --with-filter-cflags options on configure to allow
specification of a default C compiler and associated CFLAGS for filtering.
All of this is necessary in order to support 64-bit libraries under Solaris.

)0 P()-1 LI( Added the funtbl script to extract a table from Funtools ASCII output.

)0 P()-1 LI( Added code to funimage to update IRAF DATASEC keyword.

)0 P()-1 LI( Added checks to ensure that image dimensions are positive.

)0 P()-1 LI( Fixed a bug in funimage where int data was being scaled using BSCALE and
BZERO but these keywords also were being retained in the output image header.
Now the data are not scaled unless the output data type is float \201in which
case the scaling parameters are removed\202.

)0 P()-1 LI( Fixed a bug in funmerge which prevented merging of files unless one of
the -f, -w, or -x switches were used.

)0 P()-1 LI( Fixed a bug in funtable and fundisp which caused the special '$n' column
to be output incorrectly.

)0 P()-1 LI( Fixed sort option in funtable, which previously worked only if the
record size was an even divisor of 8192 \201and returned garbage otherwise\202.

)0 P()-1 LI( Fixed bug in filters involving FITS data type 'X' \201bitfield\202.

)0 P()-1 LI( Fixed bug in funcnts in which the output angles and radii were
being displayed incorrectly when multiple panda shapes were specified.

)0 P()-1 LI( Fixed bug in pandas and pies using n= syntax when first angle
specified was greater than second. The resulting mask was of
the correct shape but contained only a single region.

)0 P()-1 LI( Table row access routines will now decrease maxrows if memory cannot be
allocated for maxrows*sizeof\201row\202, i.e. if the size of a row is so large that
space for maxrows cannot be allocated.

)0 P()-1 LI( The FUN_MAXBUFSIZE environment variable was added to limit the
max buffer size that will be allocated to hold table row data. The
default is 5Mb.

)0 P()-1 LI( Generated PostScript and PDF versions of the help pages.

)0 P()-1 LI( Moved OPTIONS section before \201often-lengthy\202 DESCRIPTION section in
man pages.

)0 P()-1 LI( All memory allocation now does error checking on the result
\201except wcs library, which is external code\202.

)0 P()-1 LI( Removed some compiler warnings that surfaced when using gcc -O2.
 
)0 P()-1 LI( Updated wcs library to 3.5.5.

)0 P()-1 LI( Upgraded zlib to 1.2.1.
)LU(

)0 2 162 H()WB 248 Sn( Patch Release 1.2.3 \20112 January 2004\202)EH(
)UL(
)0 P()-1 LI( Generated man pages from the html pages. These are installed
automatically at build time.

)0 P()-1 LI( Changed instances of sprintf\201\202 to snprintf\201\202 to protect
against buffer overflow.

)0 P()-1 LI( Fixed a number of compiler warnings in non-ANSI compilers.

)0 P()-1 LI( Increased SZ_LINE parameter value from 1024 to 4096.
)LU(

)0 2 163 H()WB 249 Sn( Patch Release 1.2.3b1 \20119 August 2003\202)EH(
)UL(
)0 P()-1 LI( The rule for using comma to separate a table filter expression 
and a region expression has been changed. The rule now states:
)UL()-1 LI( if both expressions contain a region, the operator used is )BD(or)ES(.
)-1 LI( if one \201or both\202 expression\201s\202 does not contain a region, the operator
used is )BD(and)ES(.)LU(
This rule handles the cases of pure regions and pure column filters properly.
It unambiguously assigns the boolean )BD(and)ES( to all mixed cases. Thus:
) 1 34 PR(  foo.fits[circle\20110,10,3\202,pi=1:5])RP(
and
) 1 34 PR(  foo.fits[pi=1:5,circle\20110,10,3\202])RP(
both are equivalent to:
) 1 37 PR(  foo.fits[circle\20110,10,3\202 && pi=1:5])RP(

)0 P()-1 LI( When include files are used in filters, they now have implied
parentheses surrounding them. Thus, if a region file foo.reg contains two
regions \201e.g. circle 1 2 3 and circle 4 5 6\202, the syntax:
) 1 21 PR(    pha=4:5&&@foo.reg)RP(
is equivalent to:
) 1 42 PR(    pha=4:5 && \201circle 1 2 3 || cir 4 5 6\202)RP(
instead of:
) 1 40 PR(    pha=4:5 && circle 1 2 3 || cir 4 5 6)RP(
and the pha filter is applied to both regions.

)0 P()-1 LI( Filters and comments now can be terminated with the string
literal "\200n" as well as ";" and the new-line character. This means
that a region can have comments embedded in it:
) 1 72 PR(    funcnts foo.fits "circle 512 512 10 # color=red\200n circle 512 512 20")RP(

)0 P()-1 LI( Added capability to update the value of an existing parameter
after writing the table or image \201assuming the output image is a
disk file or is being redirected into a file\202.

)0 P()-1 LI( Improved handling of parentheses in filter expressions.

)0 P( 
)-1 LI( Fixed a bug in image \201not event\202 regions in which circles and
annuli with radius of 1 pixel were not being processed. No counts and
no area would be found in such regions.

)0 P()-1 LI( Fixed a bug in funcnts in which the radii column values for out of sync
if multiple annuli were specified \201instead of a single varargs or accel
annulus\202.

)0 P()-1 LI( By default, fundisp will display integer image data as floats
if the BSCALE and BZERO header parameters are present.

)0 P()-1 LI( Added -L switch to funhead to output starbase list format.

)0 P()-1 LI( Changed the name of the routine _FunColumnSelect to
FunColumnSelectArr, in order to emphasize that it is not
a private routine.

)0 P()-1 LI( Funcalc now checks to ensure that a column was specified as part of
the expression.

)0 P()-1 LI( Funcalc local variables in the compiled program now use a "__" prefix
to avoid conflicts with user-defined variables.

)0 P()-1 LI( Unofficial unsigned short \201bitpix=-16\202 image data now is scaled
correctly using BSCALE and BZERO header parameters.

)0 P()-1 LI( Ported to Intel icc and gcc 3.3 compilers.

)0 P()-1 LI( Updated wcs library to 3.5.1.

)0 P()-1 LI( Changed license from public domain to GNU GPL.
)LU(

)0 2 164 H()WB 250 Sn( Patch Release 1.2.2 \20118 May 2003\202)EH(
)UL(
)0 P( 
)-1 LI( Fixed funcalc so that it now actually compiles an expression and
runs it, instead of getting a "filter compilation error". Oops!

)0 P()-1 LI( Fixed bug in FunOpen in which the bracket specification was being
removed from the filename if a disk file was opened for "w" or "a".

)0 P()-1 LI( Fixed bug in FunFlush which prevented two successive calls to
FunImagePut from writing the second extension header properly.

)0 P()-1 LI( All filter routines now use gerror\201stderr, ...\202 call instead of
fprintf\201stderr, ...\202  so that output to stderr can be turned off \201via
setgerror\201level\202 or GERROR environment variable\202.

)0 P()-1 LI( All standard Funtools programs check for GERROR environment
variable before setting gerror flag.

)0 P()-1 LI( Some error messages about invalid region arguments were not being
printed.

)0 P()-1 LI( FITS parameters/headers now conform more closely to FITS standard:
)UL()-1 LI( Blank keywords are treated in the same way as COMMENTS and HISTORY cards
)-1 LI( XTENSION keywords are now exactly 8 characters long
)-1 LI( 'E' is output instead of 'e' in floating point param values
)-1 LI( PCOUNT and GCOUNT are output correctly for image extensions
)-1 LI( EXTEND=T is output in primary header
)-1 LI( COMMENTS and HISTORY start in column 9)LU(
)LU(

)0 2 165 H()WB 251 Sn( Patch Release 1.2.1 \20124 April 2003\202)EH(
)UL(
)0 P()-1 LI( Varargs ellipse and box annular regions were being
processed incorrectly when the following conditions all were met:
)UL()-1 LI( the region was specified in physical or wcs coordinates
)-1 LI( the data file contained LTM/LTV keywords, i.e., it
was blocked with respect to the original data file
)-1 LI( the program being run was an image program \201e.g. funcnts, funimage\202)LU(
Varargs ellipse and boxes are regions of the form:
) 2 43 PR(  ellipse x y a1 b1 a2 b2 ... an bn [angle]
  box x y l1 w1 l2 w2 ... ln wn [angle])RP(
where at least 2 sets of axis \201length\202 values were specified to form
an annulus \201i.e. simple ellipses and boxes worked properly\202.  With all
of the above conditions met, a region in physical coordinates saw its
second length argument converted incorrectly from physical coordinates
to image coordinates. In simple terms, this means that funcnts did not
process elliptical or box regions in physical coords on blocked images
properly.  Note that blocking on the command line \201e.g. foo.fits[*,*,2]\202
did work when no LTM/LTV keywords existed in the file.

)0 P()-1 LI( The fundisp -f switch now supports specification of
column-specific display formats as well as a more convenient way to
specify datatype-specific display formats. Both use keyword=value
specifiers. For columns, use:
) 1 58 PR(    fundisp -f "colname1=format1 colname2=format2 ..." ...)RP(
e.g.
) 1 40 PR(    fundisp -f "time=%13.2f pha=%3d" ...)RP(
You also can specify display formats for individual datatypes using the FITS
binary table TFORM variables as the keywords:
) 1 65 PR(    fundisp -f "D=double_format E=float_format J=int_format etc.")RP(
e.g.
) 1 35 PR(    fundisp -f "D=%13.2f I=%3d" ...)RP(
The old position-dependent syntax is deprecated.

)0 P()-1 LI( Fundisp will now print out a single 16-bit \201or 32-bit\202 unsigned
int for a column whose data format is 16X \201or 32X\202, instead of
printing 2 \201or 4\202 unsigned chars.

)0 P()-1 LI( Fixed bug in which fundisp was not able to display bitfield data for
raw event lists.

)0 P()-1 LI( Previously, when binning columns used implicitly in a region
and explicitly in a filter could suffer from a case sensitivity problem.
This has been fixed.

)0 P()-1 LI( Fixed internal mask=all switch on fundisp.

)0 P()-1 LI( Filter include files now simply include text without changing the state
of the filter. They therefore can be used in expression. That is, if foo1 
contains "pi==1" and foo2 contains "pha==2" then the following expressions
are equivalent:
) 3 57 PR(    "[@foo1&&@foo2]" is equivalent to "[pi==1&&pha==2]"
    "[pha==1||@foo2]"  is equivalent to "[pi==1||pha==2]"
    "[@foo1,@foo2]" is equivalent to "[pi==1,pha==2]")RP(

)0 P()-1 LI( Fixed bug in filter specification which caused a SEGV if a varargs-style
region was enclosed in parens.

)0 P()-1 LI( Updated wcs library to 3.3.2.
)LU(

)0 2 166 H()WB 252 Sn( Public Release 1.2.0 \20124 March 2003\202)EH(
)UL(
)0 P()-1 LI( BSCALE and BZERO are now always applied to int pixel data, instead of
only being applied if the desired output is floating point.
)LU(

)0 2 167 H()WB 253 Sn( Beta Release 1.2.b3 \2014 February 2003\202)EH(
)UL(
)0 P()-1 LI( In FunColumnSelect, added the ability to specify an offset into
an array in the type specification, using the extended syntax:
) 1 48 PR( [@][n]<type>[[poff]][:[tlmin[:tlmax[:binsiz]]]])RP(
The [poff] string specifies the offset.  For example, a type specification
such as "@I[2]" specifies the third \201i.e., starting from 0\202 element in
the array pointed to by the pointer value. A value of "@2I[4]" specifies
the fifth and sixth values in the array.

)0 P()-1 LI( Added a non-varargs version of FunColumnSelect called _FunColumnSelect:
) 3 76 PR(int _FunColumnSelect\201Fun fun, int size, char *plist, 
                     char **names, char **types, char **modes, int *offsets,
                     int nargs\202;)RP(

)0 P()-1 LI( Added support for sorting binary tables by column name using:
funtable -s "col1 col2 ... coln" ...

)0 P()-1 LI( Added the FUN_RAW macro which, when applied to the "name" parameter
of FunParamGets\201\202, returns the 80-character raw FITS card instead of
only the value.

)0 P()-1 LI( Added support for comparing column values with binary masks of the
form 0b[01]+, e.g.:
) 1 23 PR(  \201status&0b111\202==0b001)RP(
Previously, such masks had to be specified in decimal, octal, or hex.

)0 P()-1 LI( Completed support for type 'L' \201logical\202 in fundisp and in filtering of
binary tables.

)0 P()-1 LI( Fixed bug in funhist that was improperly setting the number of bins
when the data was of type float.

)0 P()-1 LI( Fixed bug in filter/Makefile where the filter OBJPATH #define was
being passed to the wrong module.
)LU(

)0 2 168 H()WB 254 Sn( Beta Release 1.2.b2 \2017 October 2002\202)EH(
)UL(
)0 P()-1 LI( Updated wcs library to 3.1.3.

)0 P()-1 LI( Added support for reading gzip'ed files via stdin.
)LU(

)0 2 169 H()WB 255 Sn( Beta Release 1.2.b1 \20124 September 2002\202)EH(
)UL(
)0 P()-1 LI( Added the following accelerators to region filtering:
) 8 73 PR(  shape:      arguments:
  -----       ---------
  BOX         xcenter ycenter xw1 yh1 xw2 yh2 ... xwn yhn \201angle\202
  BOX         xcenter ycenter xwlo yhin xwout yhhi n=[number] \201angle\202
  CIRCLE      xcenter ycenter r1 r2 ... rn              # same as annulus
  CIRCLE      xcenter ycenter rinner router n=[number]  # same as annulus
  ELLIPSE     xcenter ycenter xw1 yh1 xw2 yh2 ... xwn yhn \201angle\202
  ELLIPSE     xcenter ycenter xwlo yhin xwout yhhi n=[number] \201angle\202)RP(

)0 P()-1 LI( Added the following new pandas \201Pie AND Annulus\202 to region filtering:
) 5 77 PR(  shape:    arguments:
  -----     ---------
  CPANDA    xcen ycen ang1 ang2 nang irad orad nrad  # same as panda
  BPANDA    xcen ycen ang1 ang2 nang ixlo iylo ixhi iyhi nrad \201ang\202 # box
  EPANDA    xcen ycen ang1 ang2 nang ixlo iylo ixhi iyhi nrad \201ang\202 # ellipse)RP(

)0 P()-1 LI( Added support for filtering images using simple FITS image masks,
i.e. 8-bit or 16-bit FITS images where the value of a pixel is the
region id number for that pixel \201and therefore must be greater than
0\202. The image section being filtered must either be the same size as the
mask dimensions or else be an even multiple of the mask. This works with
image-style filtering, i.e., funcnts can utilize a mask on both
images and binary tables.

)0 P()-1 LI( Added '$n' to fundisp column specification to allow display of
ordinal value of each row passing the filter.

)0 P()-1 LI( Added code to support region filtering on image sections.

)0 P()-1 LI( Fixed bugs which prevented filtering more than one ASCII region file.

)0 P()-1 LI( Fixed bug occasionally causing filter slave processes to become zombies.

)0 P()-1 LI( Fixed bugs in event filtering: annulus with inner radius of 0
\201i.e., a circle\202 was rejecting events with coordinates xcen, ycen.
Also, pie with angles of 0 and 360 was rejecting some events.
Image filtering \201e.g. funcnts\202 did not have these problems.

)0 P()-1 LI( Filters now accept global exclude regions without an include region.
In such a case, the field region is implied. That is, "-circle\201x,y,r\202"
is equivalent to "field; -circle\201x,y,r\202", etc.

)0 P()-1 LI( Fixed panda so that it can be used as a global exclude.

)0 P()-1 LI( Allow empty ds9 region file \201comments and globals only\202 to be
a valid filter. Totally ignore zero length region or include file.

)0 P( 
)-1 LI( Fixed funcnts bug that was displaying 0 value as inner radius of
a circle, instead of just one radius value.
)LU(

)0 2 170 H()WB 256 Sn( Public Release 1.1.0 \20122 April 2002\202)EH(

)0 P(New features include:
)UL()0 P()-1 LI( Funtools programs now accept gzip'ed files as valid input.

)0 P()-1 LI( Improved security via replacement of system\201\202 function.

)0 P()-1 LI( fundisp, funcnts, funhist can output starbase/rdb format \201tabs between columns, form-feeds between tables\202.

)0 P()-1 LI( Improved support for Windows platform, as well as new support for Mac OSX.)LU(

)0 2 171 H()WB 257 Sn( Pre-Release 1.1.0e \20110 April 2002\202)EH(
)UL( 

)0 P()-1 LI( Added enough support to skip over variable length arrays in BINTABLES.
We will add full support if this non-standard construct becomes more widely
used.

)0 P()-1 LI( Fixed bug in underlying fitsy _gread\201\202 routine that was returning
an arbitrary bytes-read value if the input fd was invalid.
)LU(

)0 2 172 H()WB 258 Sn( Pre-Release 1.1.0e \20119 March 2002\202)EH(
)UL( 

)0 P()-1 LI( Added additional check for Windows/PC to filter/Nan.h.

)0 P()-1 LI( Upgraded zlib library to 1.1.4 \201fix double free security hole\202.
)LU(


)0 2 173 H()WB 259 Sn( Pre-Release 1.1.0e \20127 February 2002\202)EH(
)UL( 

)0 P()-1 LI( Changed filter/process.[ch] to filter/zprocess.[ch] to avoid name
collision with Cygwin include file.

)0 P()-1 LI( Added -a switch to funhead to display all headers in a FITS file.
)LU(

)0 2 174 H()WB 260 Sn( Pre-Release 1.1.0e \20111 February 2002\202)EH(
)UL( 

)0 P()-1 LI( Fixed filter parser so that it ignores ds9 "ruler" and "text" markers
only up to the first \200n or ; \201was ignoring to last \200n\202.

)0 P()-1 LI( The NBLOCK parameter in fitsy/headdata.c was too large for Mac OS X
\201max size of a declared char buf seems to be about .5 Mb\202.
)LU(

)0 2 175 H()WB 261 Sn( Beta Release 1.0.1b5 \20131 January 2002\202)EH(
)UL( 

)0 P()-1 LI( Fixed bug introduced in calculated IRAF LTM values in 1.0.1b3.

)0 P()-1 LI( Fixed bug in filter parser giving wrong answers when two range
lists were combined with and explicit boolean operator:
) 1 34 PR(  $ fundisp $S"[x=512&&y=511,512]")RP(
incorrectly acted like:
) 1 39 PR(  fundisp $S"[\201x=512&&y=511\202||\201y=512\202]")RP(
instead of:
) 1 37 PR(  fundisp $S"[x=512&&\201y=511||y=512\202]")RP(
In general, we recommend use of explicit parentheses.

)0 P()-1 LI( Fixed filter/NaN.h to recognize Compaq Alpha again \201broken by their last change to cc\202.

)0 P()-1 LI( Removed redundant varargs definitions that conflicted with Alpha compiler definitions.

)0 P()-1 LI( Added blank line to inc.sed to work around Apple Mac OS X bug in which the
"i" \201insert\202 command was treating final \200\200 as continuation \200 in the text.

)0 P( 
)-1 LI( Added include of mkrtemp.h to mkrtemp.c to get conditional compilation
for Mac OSX.

)0 P()-1 LI( Added support for --with-zlib to fitsy so that ds9 could use its own
copy of zlib \201and not build the copy in fitsy\202.

)0 P()-1 LI( Removed config.cache and Makefile files from distribution tar file.
)LU(

)0 2 176 H()WB 262 Sn( Beta Release 1.0.1b4 \20126 January 2002\202)EH(
)UL( 

)0 P()-1 LI( Make explicit that column filters are not permitted in an image
expression \201such as the funcnts region arguments\202.

)0 P()-1 LI( Fix bug in region parser in which a region \201without parens\202,
followed immediately by an operator:
) 1 24 PR(  circle 512 512 .5&)SY(\160)ES(==1)RP(
was not processing the final argument of the region correctly.

)0 P()-1 LI( Ignore new "tile" directive in filters \201used by ds9\202.
)LU(

)0 2 177 H()WB 263 Sn( Beta Release 1.0.1b3 \2014 January 2002\202)EH(
)UL( 

)0 P()-1 LI( Made modifications to Makefile.in to make releases easier.

)0 P()-1 LI( Added instructions Makefile.in so that funtools.h will always
have correct #defines for FUN_VERSION, FUN_MAJOR_VERSION,
FUN_MINOR_VERSION, and FUN_PATCH_LEVEL.

)0 P()-1 LI( Allow #include statements in funcalc program files.

)0 P()-1 LI( funimage now updates all 4 CDX_Y values by the block factor.

)0 P()-1 LI( Minor changes to make funtools work under darwin \201Mac OS X\202.
)LU(

)0 2 178 H()WB 264 Sn( Beta Release 1.0.1b2 \20114 November 2001\202)EH(
)UL( 

)0 P()-1 LI( Fixed FunOpen\201\202 bug \201introduced in b1\202 in which filenames without
extensions SEGV'ed on open. Yikes!

)0 P()-1 LI( Funmerge now extends the tlmin/tlmax values of the output
binning columns so that merged events from widely separated files are
valid in the output table.

)0 P()-1 LI( In funhist, added -w switch to specify bin width \201lo:hi:width\202
instead of number of bins \201lo:hi:num\202. Added support for this new 
width option in funtools.ds9.

)0 P()-1 LI( If a tdbin value was set using bincols=\201name:tlmin:tlmax:tdbin, ...\202,
the WCS parameters were not being updated properly.

)0 P()-1 LI( Cleaned up build support for zlib.
)LU(

)0 2 179 H()WB 265 Sn( Beta Release 1.0.1b1 \2016 November 2001\202)EH(
)UL( 

)0 P()-1 LI( Added support for gzip'ed files to the underlying fitsy/gio
library.  This means that all funtools programs now accept gzip'ed
files as valid input:
) 1 41 PR(  funcnts foo.fits.gz "circle 504 512 10")RP(
It is no longer necessary to run gunzip and pipe the results to
stdin of a funtools program.

)0 P()-1 LI( Funtools tasks are now placed in a sub-menu in the DS9 Analysis
menu, instead of at the top level.

)0 P()-1 LI( Fixed a bug in funcnts in which the bottom-most pixel of a small
circle or annulus region could be missed when the region is only one
pixel wide for that value of y.

)0 P()-1 LI( Added -n switch to funhist so that table histograms could be
normalized by the width of the bin \201val/\201hi_edge-lo_edge\202\202.

)0 P()-1 LI( Added -T switch to fundisp, funcnts, funhist to output in
starbase/rdb format \201uses tabs instead of spaces between columns,
form-feeds between tables, etc.\202

)0 P()-1 LI( Fixed a bug in which the field\201\202 region was not being properly
processed in combination with an image section. This could affect
funcnts processing of image data where an image section was specified
\201though it usually resulted in a funcnts error\202.

)0 P()-1 LI( Fixed bug in display of binary table header for vector columns.

)0 P()-1 LI( Filters now recognize hex constants \201starting with 0x\202 and long
constants \201ending with L\202.

)0 P()-1 LI(Filenames containing a ':' are now only treated as sockets if they
actually are in the form of a valid ip:port.

)0 P()-1 LI(Replaced funtools.ds9 with a new version that calls a new funds9
script, instead of calling funcnts or funhist directly. The new script
supports gzip'ed files and bracket specifications on filenames at the
same time, which the direct call could not. Also the new script has
better error reporting.

)0 P()-1 LI( Replaced system\201\202 call used to compile filter and funcalc
expression with a special launch\201\202 call, which performs execvp\201\202
directly without going through sh. \201launch\201\202 works under DOS and has
fewer security problems.\202

)0 P()-1 LI( Fixed image filter code in which the field\201\202 region was being ignored
if it was combined with one or more exclude regions \201and no other include
regions\202, resulting in no valid pixels.

)0 P()-1 LI( Changed use of getdtable\201\202 to FD_SETSIZE in calls to select\201\202.

)0 P()-1 LI( Added code to guard against FITS binary tables without proper TFORMx
parameters.

)0 P()-1 LI( Added support to FunParamGets so that it returns the raw FITS card
if the specified input name is NULL and the input n value is positive.

)0 P()-1 LI( Fixed bug in underlying fitsy code that set the comment in a
header parameter.
)LU(


)0 2 180 H()WB 266 Sn( Public Release 1.0.0 \20131 July 2001\202)EH(
)UL( 
)0 P()-1 LI( "a new day with no mistakes ... yet")LU(

)2 1 1 HR()0 0 1 A(Index to the Funtools Help Pages)0 0 TN TL()Ec /AF f D(
)0 5 181 H(Last)WB 267 Sn( updated: 22 April 2002)EH(
)WB NL
/TE t D NP TU PM 0 eq and{/Pn () D showpage}if end restore