aboutsummaryrefslogtreecommitdiff
path: root/vo/votools
diff options
context:
space:
mode:
Diffstat (limited to 'vo/votools')
-rw-r--r--vo/votools/.url19212128891
-rw-r--r--vo/votools/.url19212128901
-rw-r--r--vo/votools/.url19212128911
-rw-r--r--vo/votools/.url19212128921
-rw-r--r--vo/votools/.url19212128931
-rw-r--r--vo/votools/.url19212128941
-rw-r--r--vo/votools/Notes0
-rw-r--r--vo/votools/aladin.cl43
-rw-r--r--vo/votools/colbyid.cl51
-rw-r--r--vo/votools/colbyname.cl51
-rw-r--r--vo/votools/colbyucd.cl51
-rw-r--r--vo/votools/console.x84
-rwxr-xr-xvo/votools/cross_comp.sh42
-rw-r--r--vo/votools/dalclient.par12
-rw-r--r--vo/votools/dbglevel.par1
-rw-r--r--vo/votools/dispname.par3
-rw-r--r--vo/votools/doc/_docs35
-rw-r--r--vo/votools/doc/aladin.hlp50
-rw-r--r--vo/votools/doc/colbyid.hlp94
-rw-r--r--vo/votools/doc/colbyname.hlp94
-rw-r--r--vo/votools/doc/colbyucd.hlp92
-rw-r--r--vo/votools/doc/dispname.hlp44
-rw-r--r--vo/votools/doc/dss.hlp88
-rw-r--r--vo/votools/doc/getcat.hlp144
-rw-r--r--vo/votools/doc/getimg.hlp142
-rw-r--r--vo/votools/doc/getspec.hlp1
-rw-r--r--vo/votools/doc/hub.hlp56
-rw-r--r--vo/votools/doc/mkregdb.hlp93
-rw-r--r--vo/votools/doc/nedoverlay.hlp74
-rw-r--r--vo/votools/doc/obslogoverlay.hlp98
-rw-r--r--vo/votools/doc/overhandler.hlp0
-rw-r--r--vo/votools/doc/qstring.hlp71
-rw-r--r--vo/votools/doc/radiooverlay.hlp64
-rw-r--r--vo/votools/doc/regdb.hlp117
-rw-r--r--vo/votools/doc/regmetalist.hlp34
-rw-r--r--vo/votools/doc/sesame.hlp124
-rw-r--r--vo/votools/doc/stilts.hlp27
-rw-r--r--vo/votools/doc/tabclip.hlp39
-rw-r--r--vo/votools/doc/taboverlay.hlp61
-rw-r--r--vo/votools/doc/tblhandler.hlp0
-rw-r--r--vo/votools/doc/topcat.hlp50
-rw-r--r--vo/votools/doc/voclient.hlp22
-rw-r--r--vo/votools/doc/vodata.hlp189
-rw-r--r--vo/votools/doc/votcopy.hlp102
-rw-r--r--vo/votools/doc/votget.hlp107
-rw-r--r--vo/votools/doc/votpos.hlp119
-rw-r--r--vo/votools/doc/wcsinfo.hlp77
-rw-r--r--vo/votools/doc/xrayoverlay.hlp65
-rw-r--r--vo/votools/dss.cl107
-rw-r--r--vo/votools/gasplib/calcds.x139
-rw-r--r--vo/votools/gasplib/ccgseq.x94
-rw-r--r--vo/votools/gasplib/ccgsxy.x200
-rw-r--r--vo/votools/gasplib/dcmpsv.f230
-rw-r--r--vo/votools/gasplib/eqtopix.x43
-rw-r--r--vo/votools/gasplib/fitsvd.f35
-rw-r--r--vo/votools/gasplib/gsctab.x66
-rw-r--r--vo/votools/gasplib/ksbsvd.f24
-rw-r--r--vo/votools/gasplib/mkpkg22
-rw-r--r--vo/votools/gasplib/pixtoeq.x37
-rw-r--r--vo/votools/gasplib/rdaslf.x131
-rw-r--r--vo/votools/gasplib/rdxy.x43
-rw-r--r--vo/votools/gasplib/regren.f309
-rw-r--r--vo/votools/gasplib/treqst.x33
-rw-r--r--vo/votools/gasplib/trsteq.x45
-rw-r--r--vo/votools/gasplib/varsvd.f21
-rw-r--r--vo/votools/getcat.cl178
-rw-r--r--vo/votools/getimg.cl177
-rw-r--r--vo/votools/getspec.cl89
-rw-r--r--vo/votools/hub.cl70
-rw-r--r--vo/votools/imgcat.cl139
-rw-r--r--vo/votools/makewcs.par3
-rw-r--r--vo/votools/mkpkg40
-rw-r--r--vo/votools/mkregdb.cl141
-rw-r--r--vo/votools/nedoverlay.cl116
-rw-r--r--vo/votools/obslogoverlay.cl166
-rw-r--r--vo/votools/prettystr.cl89
-rw-r--r--vo/votools/qstring.cl89
-rw-r--r--vo/votools/radiooverlay.cl73
-rw-r--r--vo/votools/regdb.cl341
-rw-r--r--vo/votools/regmetalist.cl71
-rw-r--r--vo/votools/resdb.x100
-rw-r--r--vo/votools/sbquery.par7
-rw-r--r--vo/votools/sesame.par12
-rw-r--r--vo/votools/t_dalclient.x140
-rw-r--r--vo/votools/t_dispname.x49
-rw-r--r--vo/votools/t_makewcs.x334
-rw-r--r--vo/votools/t_sbquery.x406
-rw-r--r--vo/votools/t_sesame.x135
-rw-r--r--vo/votools/t_vodata.x736
-rw-r--r--vo/votools/t_votcopy.x45
-rw-r--r--vo/votools/t_votget.x122
-rw-r--r--vo/votools/t_votsize.x32
-rw-r--r--vo/votools/tabclip.cl49
-rw-r--r--vo/votools/taboverlay.cl73
-rw-r--r--vo/votools/tests/vodata_001.cl27
-rwxr-xr-xvo/votools/tests/zztest.csh18
-rw-r--r--vo/votools/topcat.cl43
-rw-r--r--vo/votools/vocdctl.par1
-rw-r--r--vo/votools/vodata.par16
-rw-r--r--vo/votools/votcopy.par6
-rw-r--r--vo/votools/votget.par10
-rw-r--r--vo/votools/votools.cl76
-rw-r--r--vo/votools/votools.hd58
-rw-r--r--vo/votools/votools.men62
-rw-r--r--vo/votools/votools.par7
-rw-r--r--vo/votools/votpos.cl118
-rw-r--r--vo/votools/votsize.par2
-rw-r--r--vo/votools/wcsinfo.cl307
-rw-r--r--vo/votools/x_votools.x11
-rw-r--r--vo/votools/xrayoverlay.cl74
110 files changed, 9154 insertions, 0 deletions
diff --git a/vo/votools/.url1921212889 b/vo/votools/.url1921212889
new file mode 100644
index 00000000..53adfaa6
--- /dev/null
+++ b/vo/votools/.url1921212889
@@ -0,0 +1 @@
+http://iraf.noao.edu/votest/dpix1.fits
diff --git a/vo/votools/.url1921212890 b/vo/votools/.url1921212890
new file mode 100644
index 00000000..2a45ddbf
--- /dev/null
+++ b/vo/votools/.url1921212890
@@ -0,0 +1 @@
+http://iraf.noao.edu/votest/dpix2.fits
diff --git a/vo/votools/.url1921212891 b/vo/votools/.url1921212891
new file mode 100644
index 00000000..5fef3733
--- /dev/null
+++ b/vo/votools/.url1921212891
@@ -0,0 +1 @@
+http://iraf.noao.edu/votest/dpix3.fits
diff --git a/vo/votools/.url1921212892 b/vo/votools/.url1921212892
new file mode 100644
index 00000000..aae04c1d
--- /dev/null
+++ b/vo/votools/.url1921212892
@@ -0,0 +1 @@
+http://iraf.noao.edu/votest/dpix4.fits
diff --git a/vo/votools/.url1921212893 b/vo/votools/.url1921212893
new file mode 100644
index 00000000..fe894a23
--- /dev/null
+++ b/vo/votools/.url1921212893
@@ -0,0 +1 @@
+http://iraf.noao.edu/votest/dpix5.fits
diff --git a/vo/votools/.url1921212894 b/vo/votools/.url1921212894
new file mode 100644
index 00000000..ec8b4ce9
--- /dev/null
+++ b/vo/votools/.url1921212894
@@ -0,0 +1 @@
+http://iraf.noao.edu/votest/dpix6.fits
diff --git a/vo/votools/Notes b/vo/votools/Notes
new file mode 100644
index 00000000..e69de29b
--- /dev/null
+++ b/vo/votools/Notes
diff --git a/vo/votools/aladin.cl b/vo/votools/aladin.cl
new file mode 100644
index 00000000..5b4299bc
--- /dev/null
+++ b/vo/votools/aladin.cl
@@ -0,0 +1,43 @@
+#{ ALADIN -- Start or stop the ALADIN app.
+
+procedure aladin (cmd)
+
+string cmd { prompt = "Command" }
+bool bkg = yes { prompt = "Run in background?" }
+bool verbose = no { prompt = "Print actions?" }
+
+begin
+ string action, command, ch
+ bool verb
+
+
+ if ($nargs > 0)
+ action = cmd
+ else
+ action = "start"
+ verb = verbose
+ command = "!" // osfn ("vo$java/app.aladin")
+
+
+ if (action == "stop" || action == "off") {
+ if (verb)
+ printf ("Stopping Aladin .... ")
+ command = command // " -kill"
+ print (command) | cl(, >& "dev$null")
+
+
+ } else if (action == "status") {
+ command = command // " -status"
+ print (command) | cl()
+
+ } else {
+ # Default is to start the app
+ if (verb)
+ printf ("Starting Aladin .... ")
+ command = command // " -bg"
+ print (command) | cl(, >& "dev$null")
+ }
+
+ if (verb)
+ printf ("\n")
+end
diff --git a/vo/votools/colbyid.cl b/vo/votools/colbyid.cl
new file mode 100644
index 00000000..2316ecb5
--- /dev/null
+++ b/vo/votools/colbyid.cl
@@ -0,0 +1,51 @@
+#{ COLBYID -- Find the column number (1-indexed) containing the specified
+# value of the ID attribute.
+
+procedure colbyid (table, id)
+
+string table { prompt = "Table name" }
+string id { prompt = "ID attribute" }
+
+int column = 0 { prompt = "Found column number (or -1)"}
+string ucd = "" { prompt = "Found column UCD" }
+string name = "" { prompt = "Found column Name" }
+bool print = no { prompt = "Print the field number?" }
+bool found = no { prompt = "Was attribute found??" }
+
+begin
+ string ltab, lid
+ int nfound
+
+ ltab = table # get parameters
+ lid = id
+ column = -1
+ nfound = 0
+
+ tinfo (ltab, ttout-) # get table info
+ for (i=1; i <= tinfo.ncols; i=i+1) {
+ keypar (ltab, "TID" // i, >& "dev$null")
+ found = keypar.found
+ if (keypar.found == yes && keypar.value == lid) {
+ if (nfound == 0) {
+ column = i
+
+ keypar (ltab, "TTYPE" // i, >& "dev$null")
+ name = ""
+ if (keypar.found == yes)
+ name = keypar.value
+
+ keypar (ltab, "TUCD" // i, >& "dev$null")
+ ucd = ""
+ if (keypar.found == yes)
+ ucd = keypar.value
+ }
+ nfound = nfound + 1
+ }
+ }
+
+ if (nfound > 1)
+ printf ("Warning: %d columns found with ID='%s'\n", nfound, id)
+
+ if (print)
+ print (column)
+end
diff --git a/vo/votools/colbyname.cl b/vo/votools/colbyname.cl
new file mode 100644
index 00000000..b98b85d6
--- /dev/null
+++ b/vo/votools/colbyname.cl
@@ -0,0 +1,51 @@
+#{ COLBYNAME -- Find the column number (1-indexed) containing the specified
+# value of the NAME attribute.
+
+procedure colbyname (table, name)
+
+string table { prompt = "Table name" }
+string name { prompt = "NAME attribute" }
+
+int column = 0 { prompt = "Found column number (or -1)"}
+string ucd = "" { prompt = "Found column name" }
+string id = "" { prompt = "Found column ID" }
+bool print = no { prompt = "Print the field number?" }
+bool found = no { prompt = "Was attribute found??" }
+
+begin
+ string ltab, lname
+ int nfound
+
+
+ ltab = table # get parameters
+ lname = name
+ column = -1
+ nfound = 0
+
+ tinfo (ltab, ttout-) # get table info
+ for (i=1; i <= tinfo.ncols; i=i+1) {
+ keypar (ltab, "TTYPE" // i, >& "dev$null")
+ found = keypar.found
+ if (keypar.found == yes && keypar.value == lname) {
+ if (nfound == 0) {
+ column = i
+
+ keypar (ltab, "TUCD" // i, >& "dev$null")
+ ucd = ""
+ if (keypar.found == yes)
+ ucd = keypar.value
+
+ keypar (ltab, "TID" // i, >& "dev$null")
+ id = ""
+ if (keypar.found == yes)
+ id = keypar.value
+ }
+ }
+ }
+
+ if (nfound > 1)
+ printf ("Warning: %d columns found with NAME='%s'\n", nfound, name)
+
+ if (print)
+ print (column)
+end
diff --git a/vo/votools/colbyucd.cl b/vo/votools/colbyucd.cl
new file mode 100644
index 00000000..051b2d78
--- /dev/null
+++ b/vo/votools/colbyucd.cl
@@ -0,0 +1,51 @@
+#{ COLBYUCD -- Find the column number (1-indexed) containing the specified
+# value of the UCD attribute.
+
+procedure colbyucd (table, ucd)
+
+string table { prompt = "Table name" }
+string ucd { prompt = "UCD attribute" }
+
+int column = 0 { prompt = "Found column number (or -1)"}
+string name = "" { prompt = "found column name" }
+string id = "" { prompt = "found column ID" }
+bool print = no { prompt = "Print the field number?" }
+bool found = no { prompt = "Was attribute found??" }
+
+begin
+ string ltab, lucd
+ int nfound
+
+ ltab = table # get parameters
+ lucd = ucd
+ column = -1
+ nfound = 0
+
+ tinfo (ltab, ttout-) # get table info
+ for (i=1; i <= tinfo.ncols; i=i+1) {
+ keypar (ltab, "TUCD" // i, >& "dev$null")
+ found = keypar.found
+ if (keypar.found == yes && keypar.value == lucd) {
+ if (nfound == 0) {
+ column = i
+
+ keypar (ltab, "TTYPE" // i, >& "dev$null")
+ name = ""
+ if (keypar.found == yes)
+ name = keypar.value
+
+ keypar (ltab, "TID" // i, >& "dev$null")
+ id = ""
+ if (keypar.found == yes)
+ id = keypar.value
+ }
+ nfound = nfound + 1
+ }
+ }
+
+ if (nfound > 1)
+ printf ("Warning: %d columns found with UCD='%s'\n", nfound, ucd)
+
+ if (print)
+ print (column)
+end
diff --git a/vo/votools/console.x b/vo/votools/console.x
new file mode 100644
index 00000000..b49846db
--- /dev/null
+++ b/vo/votools/console.x
@@ -0,0 +1,84 @@
+#
+# CONSOLE -- Small VO Client console/utility tasks
+
+
+# VOCDCTL -- VO Client daemon control
+
+procedure t_vocdctl ()
+
+int fdi, fdo
+char cmd[SZ_FNAME], buf[SZ_FNAME]
+
+int vx_initVOClient()
+int ndopen(), reopen()
+bool streq()
+
+define start_ 99
+
+begin
+ call aclrs (cmd, SZ_FNAME)
+
+ call clgstr ("cmd", cmd, SZ_FNAME)
+
+ if (streq (cmd, "start")) {
+ # Initialize the VO Client interface.
+start_ if (vx_initVOClient("console") == ERR) {
+ call clputi ("status", ERR)
+ call error (0, "Error initializing VO Client")
+ return
+ }
+
+ } else if (streq (cmd, "stop")) {
+ # Close the VO Client interface. It's possible we might not
+ # already be connected, so open a raw socket and send the text
+ # string directly.
+
+ iferr {
+ fdi = ndopen ("inet:6200", READ_WRITE)
+ fdo = reopen (fdi, READ_WRITE)
+
+ # Pack and pad the string so we can speak C.
+ call strpak ("END ", buf, 4)
+ call write (fdo, buf, 4)
+ call flush (fdo)
+
+ call close (fdi)
+ call close (fdo)
+ } then {
+ call eprintf ("Shutdown failed -- no server?\n")
+ }
+
+
+ } else if (streq (cmd, "restart")) {
+ # Restart the VO Client interface.
+ call vx_closeVOClient (1)
+ goto start_
+
+ } else {
+ call eprintf ("Invalid command: '%s'\n")
+ call pargstr (cmd)
+ }
+end
+
+
+# DBGLEVEL -- Set the VO Client debug level.
+
+procedure t_dbglevel ()
+
+int level
+
+int vx_initVOClient(), clgeti()
+
+begin
+ # Initialize the VO Client interface.
+ if (vx_initVOClient("") == ERR) {
+ call clputi ("status", ERR)
+ call error (0, "Error initializing VO Client")
+ return
+ }
+
+ level = clgeti ("level")
+ call vx_dbglevel (level)
+
+ call vx_closeVOClient (0)
+end
diff --git a/vo/votools/cross_comp.sh b/vo/votools/cross_comp.sh
new file mode 100755
index 00000000..f60a53bb
--- /dev/null
+++ b/vo/votools/cross_comp.sh
@@ -0,0 +1,42 @@
+#!/bin/sh
+
+# Usage: svc.sh <upload.tbl> <maxdist> <catalog>
+#
+# <upload.tbl> input table (req'd colnames: 'ra', 'dec')
+# <maxdist> max separation for matching (arcsec)
+# <catalog> catalog name to match (see below)
+#
+#
+# Matching catalogs names Allowed output formats
+#
+# TWOMASS_PSC votable
+# SDSS_DR7 tab
+# USNO_B1 bar
+# IRAS_PSC csv
+
+base="http://vao-web.ipac.caltech.edu/cgi-bin/VAOPortal/"
+
+# Upload the user table.
+rpath=`curl -s -S -F "file=@$1" ${base}nph-fileupload`
+
+# Do the comparison.
+data="maxdist=$2&tableA=$rpath&tableB=$3&custom_cntr1=cntr&custom_ra1=ra&custom_dec1=dec"
+oxml=`curl -c c.txt -s -S -d ${data} ${base}nph-catalogCompare`
+
+# Get the filenames.
+m=`echo $oxml | sed -e 's/<[a-z]*>//g' -e 's/<\/[a-z]*>//g' | awk '{print $2}'`
+u=`echo $oxml | sed -e 's/<[a-z]*>//g' -e 's/<\/[a-z]*>//g' | awk '{print $3}'`
+
+
+# Download and convert the matched results table.
+mxml=`curl -b c.txt -s -S -d "type=votable&file=$m" ${base}nph-tableConvert`
+ftp -V -o ${1}_match.xml $mxml
+stilts tcopy ${1}_match.xml ${1}_match.fits ofmt=fits-basic #2>1 /dev/null
+
+# Download and convert the un-matched results table.
+uxml=`curl -b c.txt -s -S -d "type=votable&file=$u" ${base}nph-tableConvert`
+ftp -V -o ${1}_unmatch.xml $uxml
+stilts tcopy ${1}_unmatch.xml ${1}_unmatch.fits ofmt=fits-basic #2>1 /dev/null
+
+# Clean up.
+/bin/rm -f c.txt ${1}_*match.xml
diff --git a/vo/votools/dalclient.par b/vo/votools/dalclient.par
new file mode 100644
index 00000000..eebb47b7
--- /dev/null
+++ b/vo/votools/dalclient.par
@@ -0,0 +1,12 @@
+svc_url,s,q,"",,,Service URL
+svc_type,s,q,"cone",,,Service type
+ra,r,h,,0.,360.,RA (J2000 decimal degrees)
+dec,r,h,,-90.,90.,Dec (J2000 decimal degrees)
+sr,r,h,,,,(Cone) Search radius (degrees)
+xsize,r,h,0.0,,,(SIAP) RA Search box size (degrees)
+ysize,r,h,0.0,,,(SIAP) Dec Search box size (degrees)
+output,s,h,"STDOUT",,,Output filename
+otype,s,h,"votable","csv|votable",,Output format type
+imfmt,s,h,"image/fits",,,Desired image format
+status,i,h,,,,Service status code
+reslen,i,h,,,,Length of result string
diff --git a/vo/votools/dbglevel.par b/vo/votools/dbglevel.par
new file mode 100644
index 00000000..865725c9
--- /dev/null
+++ b/vo/votools/dbglevel.par
@@ -0,0 +1 @@
+level,i,q,0,,,Debug level
diff --git a/vo/votools/dispname.par b/vo/votools/dispname.par
new file mode 100644
index 00000000..870268b8
--- /dev/null
+++ b/vo/votools/dispname.par
@@ -0,0 +1,3 @@
+frame,i,q,,1,,"Display frame number"
+name,s,h,"",,,"Name of the displayed image (output)"
+verbose,b,h,no,,,"Print name to STDOUT?"
diff --git a/vo/votools/doc/_docs b/vo/votools/doc/_docs
new file mode 100644
index 00000000..6086ab9d
--- /dev/null
+++ b/vo/votools/doc/_docs
@@ -0,0 +1,35 @@
+_docs
+aladin.hlp
+colbyid.hlp
+colbyname.hlp
+colbyucd.hlp
+dispname.hlp
+dss.hlp
+getcat.hlp
+getimg.hlp
+getspec.hlp
+hub.hlp
+imgcat.hlp
+makewcs.hlp
+mkregdb.hlp
+nedoverlay.hlp
+obslogoverlay.hlp
+overhandler.hlp
+qstring.hlp
+radiooverlay.hlp
+rawcaller.hlp
+regdb.hlp
+sesame.hlp
+stilts.hlp
+taboverlay.hlp
+topcat.hlp
+urlget.hlp
+vocatalog.hlp
+voclient.hlp
+vodata.hlp
+voimage.hlp
+votcopy.hlp
+votget.hlp
+votpos.hlp
+wcsinfo.hlp
+xrayoverlay.hlp
diff --git a/vo/votools/doc/aladin.hlp b/vo/votools/doc/aladin.hlp
new file mode 100644
index 00000000..d86ba655
--- /dev/null
+++ b/vo/votools/doc/aladin.hlp
@@ -0,0 +1,50 @@
+.help aladin Mar12 votools
+.ih
+NAME
+aladin -- Start/Stop/Status of the Aladin external task
+.ih
+USAGE
+aladin command
+.ih
+PARAMETERS
+.ls command
+Command to execute. If not specified, the default action is to start
+the application.
+.le
+.ls bkg = yes
+Run the application in the background?
+.le
+.ls verbose = no
+Print actions?
+.le
+
+.ih
+DESCRIPTION
+The \fIALADIN\fR task is used to start, stop, or check the status of
+the Aladin external application. If no command argument is given, the
+default action is to start the application if it is not already running.
+If command is \fIstop\fR then a running Aladin application is shutdown.
+
+If the command is \fIstatus\fR then the output will be "on" or "off"
+depending on whether the application is running.
+
+.ih
+EXAMPLES
+1. Demonstrated uses of the command:
+
+.nf
+ votools> aladin status # check if Aladin is running
+ off
+ votools> aladin start # start Aladin
+ votools> aladin status # check if Aladin is running
+ on
+ votools> aladin stop # stop Aladin
+.fi
+
+.ih
+REVISIONS
+.le
+.ih
+SEE ALSO
+hub, topcat, samp
+.endhelp
diff --git a/vo/votools/doc/colbyid.hlp b/vo/votools/doc/colbyid.hlp
new file mode 100644
index 00000000..34510f57
--- /dev/null
+++ b/vo/votools/doc/colbyid.hlp
@@ -0,0 +1,94 @@
+.help colbyid Mar12 votools
+.ih
+NAME
+colbyid -- Identify VOTable column by ID attribute
+.ih
+USAGE
+colbyid input id
+.ih
+PARAMETERS
+.ls input
+The input VOTable.
+.le
+.ls id
+The ID attribute name
+.le
+.ls column = 0
+Found column number (1-indexed, or -1 if not found)
+.le
+.ls ucd = ""
+Value of the UCD attribute for the found column.
+.le
+.ls name = ""
+Value of the NAME attribute for the found column.
+.le
+.ls print = no
+Print column field number?
+.le
+.ls found = no
+Was column found in table?
+.le
+
+.ih
+DESCRIPTION
+The \fICOLBYID\fR task is used to find the column in a VOTable with the
+named \fIID\fR attribute value of a table column. This attribute is not
+generally guaranteed to be unique within a table and so the task will print
+a warning if multiple values are found, but only the first value found will
+be saved. This attribute value is not generally guaranteed to be the same
+across VO services (e.g. an 'RA' and 'Dec' column may have alternate IDs),
+and so some knowledge of the table contents is assumed.
+
+If a column with the specified attribute is found, the \fIcolumn\fR parameter
+will be the one-indexed column number and the \fIfound\fR parameter will
+be set, otherwise the \fIcolumn\fR value will be '-1'. If the column is
+found, the \fIucd\fR and \fIname\fR values will be filled in with the
+corresponding attributes for that column or the null string.
+
+If the \fIprint\fR parameter is set, the column number will be printed to the
+standard output.
+
+.ih
+EXAMPLES
+1. Find the column in the table where the 'id' attribute is 'RA' in a
+VOTable document:
+
+.nf
+ votools> colbyid vodata$usno-b.xml RA print+
+ 2
+ votools> colbyid http://iraf.noao.edu/votest/usno-b.xml RA print+
+ 2
+ votools> colbyid file:///<path>/data/usno-b.xml RA print+
+ 2
+ votools> colbyid file:///localhost/<path>/data/usno-b.xml RA print+
+ 2
+.fi
+
+Or when a parameter is not found:
+
+.nf
+ votools> colbyid vodata$usno-b.xml FOO print+
+ -1
+.fi
+
+If a matching column is found in the table, the task parameters may be
+queried for additional information:
+
+.nf
+ votools> =colbyid.column
+ 2
+ votools> =colbyid.found
+ yes
+ votools> =colbyid.ucd
+ POS_EQ_RA_MAIN
+ votools> =colbyid.name
+ RA
+.fi
+
+.ih
+REVISIONS
+.le
+.ih
+SEE ALSO
+colbyucd, colbyname
+.endhelp
diff --git a/vo/votools/doc/colbyname.hlp b/vo/votools/doc/colbyname.hlp
new file mode 100644
index 00000000..880d1b8f
--- /dev/null
+++ b/vo/votools/doc/colbyname.hlp
@@ -0,0 +1,94 @@
+.help colbyname Mar12 votools
+.ih
+NAME
+colbyname -- Identify VOTable column by NAMED attribute
+.ih
+USAGE
+colbyname input name
+.ih
+PARAMETERS
+.ls input
+The input VOTable.
+.le
+.ls name
+The NAMED attribute name
+.le
+.ls column = 0
+Found column number (1-indexed, or -1 if not found)
+.le
+.ls ucd = ""
+Value of the UCD attribute for the found column.
+.le
+.ls name = ""
+Value of the NAME attribute for the found column.
+.le
+.ls print = no
+Print column field number?
+.le
+.ls found = no
+Was column found in table?
+.le
+
+.ih
+DESCRIPTION
+The \fICOLBYNAMED\fR task is used to find the column in a VOTable with the
+named \fINAMED\fR attribute value of a table column. This attribute is not
+generally guaranteed to be unique within a table and so the task will print
+a warning if multiple values are found, but only the first value found will
+be saved. This attribute value is not generally guaranteed to be the same
+across VO services (e.g. an 'RA' and 'Dec' column may have alternate NAMEs),
+and so some knowledge of the table contents is assumed.
+
+If a column with the specified attribute is found, the \fIcolumn\fR parameter
+will be the one-indexed column number and the \fIfound\fR parameter will
+be set, otherwise the \fIcolumn\fR value will be '-1'. If the column is
+found, the \fIucd\fR and \fIname\fR values will be filled in with the
+corresponding attributes for that column or the null string.
+
+If the \fIprint\fR parameter is set, the column number will be printed to the
+standard output.
+
+.ih
+EXAMPLES
+1. Find the column in the table where the 'name' attribute is 'RA' in a
+VOTable document:
+
+.nf
+ votools> colbyname vodata$usno-b.xml RA print+
+ 2
+ votools> colbyname http://iraf.noao.edu/votest/usno-b.xml RA print+
+ 2
+ votools> colbyname file:///<path>/usno-b.xml RA print+
+ 2
+ votools> colbyname file:///localhost/<path>/usno-b.xml RA print+
+ 2
+.fi
+
+Or when a parameter is not found:
+
+.nf
+ votools> colbyname vodata$usno-b.xml FOO print+
+ -1
+.fi
+
+If a matching column is found in the table, the task parameters may be
+queried for additional information:
+
+.nf
+ votools> =colbyname.column
+ 2
+ votools> =colbyname.found
+ yes
+ votools> =colbyname.ucd
+ POS_EQ_RA_MAIN
+ votools> =colbyname.name
+ RA
+.fi
+
+.ih
+REVISIONS
+.le
+.ih
+SEE ALSO
+colbyucd, colbyid
+.endhelp
diff --git a/vo/votools/doc/colbyucd.hlp b/vo/votools/doc/colbyucd.hlp
new file mode 100644
index 00000000..abe52cbc
--- /dev/null
+++ b/vo/votools/doc/colbyucd.hlp
@@ -0,0 +1,92 @@
+.help colbyucd Mar12 votools
+.ih
+NAME
+colbyucd -- Identify VOTable column by UCD attribute
+.ih
+USAGE
+colbyucd input ucd
+.ih
+PARAMETERS
+.ls input
+The input VOTable.
+.le
+.ls ucd
+The UCD attribute name
+.le
+.ls column = 0
+Found column number (1-indexed, or -1 if not found)
+.le
+.ls id = ""
+Value of the ID attribute for the found column.
+.le
+.ls name = ""
+Value of the NAME attribute for the found column.
+.le
+.ls print = no
+Print column field number?
+.le
+.ls found = no
+Was column found in table?
+.le
+
+.ih
+DESCRIPTION
+The \fICOLBYUCD\fR task is used to find the column in a VOTable with the
+named \fIUCD\fR attribute value of a table column. This attribute is not
+generally guaranteed to be unique within a table and so the task will print
+a warning if multiple values are found, but only the first value found will
+be saved.
+
+If a column with the specified attribute is found, the \fIcolumn\fR parameter
+will be the one-indexed column number and the \fIfound\fR parameter will
+be set, otherwise the \fIcolumn\fR value will be '-1'. If the column is
+found, the \fIid\fR and \fIname\fR values will be filled in with the
+corresponding attributes for that column or the null string.
+
+If the \fIprint\fR parameter is set, the column number will be printed to the
+standard output.
+
+.ih
+EXAMPLES
+1. Find the column in the table where the 'ucd' attribute is 'RA' in a
+VOTable document:
+
+.nf
+ votools> colbyucd vodata$usno-b.xml POS_EQ_RA_MAIN print+
+ 2
+ votools> colbyucd http://iraf.noao.edu/votest/usno-b.xml POS_EQ_RA_MAIN print+
+ 2
+ votools> colbyucd file:///<path>/usno-b.xml POS_EQ_RA_MAIN print+
+ 2
+ votools> colbyucd file:///localhost/<path>/usno-b.xml POS_EQ_RA_MAIN print+
+ 2
+.fi
+
+Or when a parameter is not found:
+
+.nf
+ votools> colbyucd vodata$usno-b.xml FOO print+
+ -1
+.fi
+
+If a matching column is found in the table, the task parameters may be
+queried for additional information:
+
+.nf
+ votools> =colbyucd.column
+ 2
+ votools> =colbyucd.found
+ yes
+ votools> =colbyid.ucd
+ POS_EQ_RA_MAIN
+ votools> =colbyucd.name
+ RA
+.fi
+
+.ih
+REVISIONS
+.le
+.ih
+SEE ALSO
+colbyid, colbyname
+.endhelp
diff --git a/vo/votools/doc/dispname.hlp b/vo/votools/doc/dispname.hlp
new file mode 100644
index 00000000..9c6cb6f3
--- /dev/null
+++ b/vo/votools/doc/dispname.hlp
@@ -0,0 +1,44 @@
+.help dispname Mar12 votools
+.ih
+NAME
+dispname -- Get the currently displayed image name
+.ih
+USAGE
+dispname frame
+
+.ih
+PARAMETERS
+.ls frame
+Frame number to query.
+.le
+
+.ih
+DESCRIPTION
+
+The \fIDISPNAME\fR task is used to get the name of the image displayed
+in the frame number specified by the \fIframe\fR parameter.
+
+.ih
+EXAMPLES
+
+1. Print the displayed image name to the STDOUT
+
+.nf
+ votools> display dev$pix 1
+ votools> dispname 1 verbose+
+ dev$pix
+.fi
+
+2. Get the name, but use it within as script as a parameter:
+
+.nf
+ int frame_num = 1
+ dispname (frame_num)
+ printf ("The displayed image is '%s'\n", dispname.name)
+.fi
+
+
+.ih
+SEE ALSO
+
+.endhelp
diff --git a/vo/votools/doc/dss.hlp b/vo/votools/doc/dss.hlp
new file mode 100644
index 00000000..caac4123
--- /dev/null
+++ b/vo/votools/doc/dss.hlp
@@ -0,0 +1,88 @@
+.help dss Mar12 votools
+.ih
+NAME
+dss -- Display a DSS2 image of a named field
+.ih
+USAGE
+dss field
+.ih
+PARAMETERS
+.ls field
+Name of target field to display. If the null string then the \fIra\fR,
+\fIdec\fR and \fIsize\fR parameters determine the image to display. If
+specified as an image name, the WCS footprint of the image is used to
+determine the displayed image.
+.le
+.ls ra = 0.0
+RA (J2000) of field.
+.le
+.ls dec = 0.0
+Dec (J2000) of field.
+.le
+.ls size = 0.25
+Size of field (decimal degrees).
+.le
+.ls frame = 1
+Image display frame.
+.le
+.ls use_display = yes
+Display the retrieved image? If 'no', the image is retrieved to the
+system cache but is not displayed.
+.le
+.ls grid = no
+Overlay a coordinate grid on the image display?
+.le
+.ls verbose = yes
+Print actions?
+.le
+.ls save = yes
+Save the retrieved image? If 'no', the field is displayed but the
+image is not saved for later use, otherwise the name of the retrieved
+file is written to the \fIimname\fR parameter.
+.le
+.ls imname = ""
+Saved image name.
+.le
+
+.ih
+DESCRIPTION
+The \fIDSS\fR task is used to query and optionally display an image of
+the named \fIfield\fR. If the \fIfield\fR param is the null string,
+the \fIra\fR, \fIdec\fR and \fIsize\fR parameters determine the image
+to display. If \fIfield\fR is specified as an image name, the WCS
+footprint of the image is used to determine the query parameters.
+
+The \fIuse_display\fR parameter determines whether an image is displayed
+to the specified \fIframe\fR. If disabled, the image will be retrieved
+to the system cache and the filename will be written to the \fIimname\fR
+parameter.
+
+.ih
+EXAMPLES
+1. Display a half-degree image of M31.
+
+.nf
+ votools> dss m31 size=0.5
+.fi
+
+2. Display the DSS version of the dev$ypix field, overlay a grid.
+
+.nf
+ votools> dss dev$ypix grid+
+.fi
+
+3. Get an image of a field but don't display it
+
+.nf
+ votools> dss m83 use_display-
+ votools> =dss.imname
+ cache$m83.fits
+.fi
+
+.ih
+REVISIONS
+
+.ih
+SEE ALSO
+
+.endhelp
diff --git a/vo/votools/doc/getcat.hlp b/vo/votools/doc/getcat.hlp
new file mode 100644
index 00000000..b8ee9cd8
--- /dev/null
+++ b/vo/votools/doc/getcat.hlp
@@ -0,0 +1,144 @@
+.help getcat Mar12 votools
+.ih
+NAME
+getcat -- Query catalog data services in the VO
+.ih
+USAGE
+getcat resource fields
+.ih
+PARAMETERS
+.ls resource
+List of the VO data services to query.
+.le
+.ls fields
+List of objects or images used to specify the position of the query. An
+object name will be resolved to a position using the \fISESAME\fR service
+and the \fIsize\fR parameter will determine the query size. If an image
+name is given, the center position and image corners will be used to
+determine the query position and size.
+.le
+.ls pos = ""
+A string specifying the position of the query. Positions are specified as
+J2000 RA and Dec in decimal degrees separate by a comma.
+.le
+.ls size = 0.25
+Query size in decimal degrees.
+.le
+.ls samp = no
+If enabled, each result table is broadcast as a SAMP message to other
+VO applications.
+.le
+.ls plot = no
+Plot the result table to the standard graphics stream?
+The \fIplot\fR parameter is ignored when using multiple resources or fields.
+.le
+.ls display = no
+If enabled, an image of the \fIfield\fR will be displayed. If the
+\fIfield\fR is an object name, a DSS image of the field will be displayed,
+if the \fIfield\fR is an image then the image will be displayed. The
+\fIdisplay\fR parameter is ignored when using multiple resources or fields.
+.le
+.ls overplot = no
+If enabled, the objects in the result table will be overlayed on the
+image display. The \fIoverplot\fR parameter is ignored when using multiple
+resources or fields.
+.le
+.ls output = "STDOUT"
+Output filename. If the \fIoutput\fR parameter is "STDOUT" the result table
+will be written to the standard output stream. If the output name is a
+null string, no result table will be printed or saved.
+.le
+.ls format = "ascii"
+Format of the result table. Allowed values are
+.ls vot | xml
+A new VOTable.
+.le
+.ls asv
+Ascii separated values.
+.le
+.ls bsv
+Bar separated values.
+.le
+.ls csv
+Comma separated values.
+.le
+.ls tsv
+Tab separated values.
+.le
+.ls html
+Standalone HTML document.
+.le
+.ls shtml
+Single HTML <table> element. This format may be used to generate the <table>
+code for inclusion in another HTML document.
+.le
+.ls fits
+FITS binary table
+.le
+.le
+.ls status = 0
+Return status code. A non-zero value indicates an error in the query.
+.le
+
+.ih
+DESCRIPTION
+The \fIGETCAT\fR task is used to retrieve data from one or more VO
+catalog services. An individual \fIresource\fR name may be
+specified as a user-defined alias, a VO \fIShortName\fR, a VO \fIivorn\fR
+identifier string, or as a base service URL. If specified as a service URL,
+additional parameters to specify the position and size will be determined
+from the \fIfields\fR, \fIpos\fR and \fIsize\fR parameters. Multiple
+resources may be specified as a comma-delimited string or as an \fI@file\fR.
+
+The position to be queried may be specified by the \fIfields\fR parameter
+as either a list of object names that are resolved to equatorial coordinates
+automatically, or as a list of images where the WCS footprint of the image is
+used to determine the center and size. For object names, the \fIsize\fR
+parameter is specified in decimal degrees as the radius around the position
+to query. The \fIpos\fR parameter may be specified as a comma-separated
+set of RA/Dec values given in decimal degrees.
+
+Result tables may be broadcast to other VO applications using SAMP messaging
+by enabling the \fIsamp\fR parameter. If the \fIdisplay\fR parameter is
+enabled then images used as input will be displayed, if object names are
+used a DSS image of the field will be displayed. The \fIoverplot\fR parameter
+may be set to overplot the result catalog on the image display automatically.
+The \fIdisplay\fR and \fIoverplot\fR parameters are only used for
+single-resource and single-object queries.
+
+Results may be saved to disk in a format specified by the \fIformat\fR
+parameter (described above). If the \fIoutput\fR parameter is the null
+string then no local results will be saved or printed, the value "STDOUT"
+may be used to print the result table to the standard output stream (except
+in the case of FITS bintable output).
+
+.ih
+EXAMPLES
+1. Find the GSC2.3 catalog sources within 0.1 degrees of 3c273. Display
+the field and overplot the catalog positions on the image display, but do
+not print the results. Then do the same but plot a graph instead of
+overlay the display.
+
+.nf
+ votools> getcat gsc2.3 3c273 size=0.1 display+ overplot+ output=""
+ votools> getcat gsc2.3 3c273 size=0.1 plot+ output=""
+.fi
+
+2. Find the 2MASS point-source catalog objects in each extension of a
+NEWFIRM mosaic image:
+
+.nf
+ votools> getcat 2mass-psc @newfirm.fits format="fits" output="nf"
+.fi
+
+The result tables are saved as FITS bintables with the root name 'nf'
+followed by a running number indicating the extension.
+
+
+.ih
+REVISIONS
+.le
+.ih
+SEE ALSO
+getimg, vodata, votpos
+.endhelp
diff --git a/vo/votools/doc/getimg.hlp b/vo/votools/doc/getimg.hlp
new file mode 100644
index 00000000..7b780f9d
--- /dev/null
+++ b/vo/votools/doc/getimg.hlp
@@ -0,0 +1,142 @@
+.help getimg Mar12 votools
+.ih
+NAME
+getimg -- Query image data services in the VO
+.ih
+USAGE
+getimg resource fields
+.ih
+PARAMETERS
+.ls resource
+List of the VO data services to query.
+.le
+.ls fields
+List of objects or images used to specify the position of the query. An
+object name will be resolved to a position using the \fISESAME\fR service
+and the \fIsize\fR parameter will determine the query size. If an image
+name is given, the center position and image corners will be used to
+determine the query position and size.
+.le
+.ls pos = ""
+A string specifying the position of the query. Positions are specified as
+J2000 RA and Dec in decimal degrees separate by a comma.
+.le
+.ls size = 0.25
+Query size in decimal degrees.
+.le
+.ls samp = no
+If enabled, each result table is broadcast as a SAMP message to other
+VO applications.
+.le
+.ls plot = no
+Plot the result table to the standard graphics stream?
+The \fIplot\fR parameter is ignored when using multiple resources or fields.
+.le
+.ls display = no
+If enabled, an image of the \fIfield\fR will be displayed. If the
+\fIfield\fR is an object name, a DSS image of the field will be displayed,
+if the \fIfield\fR is an image then the image will be displayed. The
+\fIdisplay\fR parameter is ignored when using multiple resources or fields.
+.le
+.ls overplot = no
+If enabled, the objects in the result table will be overlayed on the
+image display. The \fIoverplot\fR parameter is ignored when using multiple
+resources or fields.
+.le
+.ls output = "STDOUT"
+Output filename. If the \fIoutput\fR parameter is "STDOUT" the result table
+will be written to the standard output stream. If the output name is a
+null string, no result table will be printed or saved.
+.le
+.ls format = "ascii"
+Format of the result table. Allowed values are
+.ls vot | xml
+A new VOTable.
+.le
+.ls asv
+Ascii separated values.
+.le
+.ls bsv
+Bar separated values.
+.le
+.ls csv
+Comma separated values.
+.le
+.ls tsv
+Tab separated values.
+.le
+.ls html
+Standalone HTML document.
+.le
+.ls shtml
+Single HTML <table> element. This format may be used to generate the <table>
+code for inclusion in another HTML document.
+.le
+.ls fits
+FITS binary table
+.le
+.le
+.ls status = 0
+Return status code. A non-zero value indicates an error in the query.
+.le
+
+.ih
+DESCRIPTION
+The \fIGETIMG\fR task is used to retrieve data from one or more VO
+image services. An individual \fIresource\fR name may be
+specified as a user-defined alias, a VO \fIShortName\fR, a VO \fIivorn\fR
+identifier string, or as a base service URL. If specified as a service URL,
+additional parameters to specify the position and size will be determined
+from the \fIfields\fR, \fIpos\fR and \fIsize\fR parameters. Multiple
+resources may be specified as a comma-delimited string or as an \fI@file\fR.
+
+The position to be queried may be specified by the \fIfields\fR parameter
+as either a list of object names that are resolved to equatorial coordinates
+automatically, or as a list of images where the WCS footprint of the image is
+used to determine the center and size. For object names, the \fIsize\fR
+parameter is specified in decimal degrees as the radius around the position
+to query. The \fIpos\fR parameter may be specified as a comma-separated
+set of RA/Dec values given in decimal degrees.
+
+Result tables may be broadcast to other VO applications using SAMP messaging
+by enabling the \fIsamp\fR parameter. If the \fIdisplay\fR parameter is
+enabled then images used as input will be displayed, if object names are
+used a DSS image of the field will be displayed. The \fIoverplot\fR parameter
+may be set to overlay the result catalog on the image display automatically.
+The \fIdisplay\fR and \fIoverplot\fR parameters are only used for
+single-resource and single-object queries.
+
+Results may be saved to disk in a format specified by the \fIformat\fR
+parameter (described above). If the \fIoutput\fR parameter is the null
+string then no local results will be saved or printed, the value "STDOUT"
+may be used to print the result table to the standard output stream (except
+in the case of FITS bintable output).
+
+.ih
+EXAMPLES
+1. Find the HST GOODS images within 0.1 degrees of 3c273. Display
+the field and overlay the central image positions on the image display,
+do not print the results. Then do the same, but plot the results instead
+of overlaying the display, append the GSC2.3 catalog.
+
+.nf
+ votools> getimg hst.goods 3c273 size=0.1 display+ overplot+ output=""
+ votools> getimg hst.goods 3c273 size=0.1 plot+ output=""
+ votools> getimg gsc2.3 3c273 size=0.1 plot+ overplot+ output=""
+.fi
+
+2. Find the NVSS (all-sky 21-cm radio survey) images for each extension of a
+NEWFIRM mosaic image, save the raw VOTable results:
+
+.nf
+ votools> getimg nvss @newfirm.fits format="raw" output="nf"
+.fi
+
+
+.ih
+REVISIONS
+.le
+.ih
+SEE ALSO
+getcat, vodata
+.endhelp
diff --git a/vo/votools/doc/getspec.hlp b/vo/votools/doc/getspec.hlp
new file mode 100644
index 00000000..8b137891
--- /dev/null
+++ b/vo/votools/doc/getspec.hlp
@@ -0,0 +1 @@
+
diff --git a/vo/votools/doc/hub.hlp b/vo/votools/doc/hub.hlp
new file mode 100644
index 00000000..949f559b
--- /dev/null
+++ b/vo/votools/doc/hub.hlp
@@ -0,0 +1,56 @@
+.help hub Mar12 votools
+.ih
+NAME
+hub -- Start/Stop/Status of the Hub external task
+.ih
+USAGE
+hub command
+.ih
+PARAMETERS
+.ls command
+Command to execute. If not specified, the default action is to start
+the application.
+.le
+.ls bkg = yes
+Run the application in the background?
+.le
+.ls gui = yes
+Run the application with a GUI control window?
+.le
+.ls verbose = no
+Print actions?
+.le
+
+.ih
+DESCRIPTION
+The \fIHUB\fR task is used to start, stop, or check the status of
+the SAMP Hub. If no command argument is given, the
+default action is to start the external JSamp Hub if it is not already running
+or if there is no internal Hub available from Topcat or Aladin, SAMP
+messaging is enabled as well
+If command is \fIstop\fR then a running Hub application is shutdown and
+SAMP messaging is disabled in the CL.
+
+If the command is \fIstatus\fR then the output will be "on" or "off"
+depending on whether a Hub is available.
+
+.ih
+EXAMPLES
+1. Demonstrated uses of the command:
+
+.nf
+ votools> hub status # check if Hub is running
+ off
+ votools> hub start # start Hub
+ votools> hub status # check if Hub is running
+ on
+ votools> hub stop # stop Hub
+.fi
+
+.ih
+REVISIONS
+.le
+.ih
+SEE ALSO
+hub, topcat, samp
+.endhelp
diff --git a/vo/votools/doc/mkregdb.hlp b/vo/votools/doc/mkregdb.hlp
new file mode 100644
index 00000000..5e0a4b86
--- /dev/null
+++ b/vo/votools/doc/mkregdb.hlp
@@ -0,0 +1,93 @@
+.help mkregdb Mar12 votools
+.ih
+NAME
+mkregdb -- Create a local registry database
+.ih
+USAGE
+mkregdb query
+.ih
+PARAMETERS
+.ls query
+Registry query term(s).
+.le
+.ls output = ""
+Output filename.
+.le
+.ls type = ""
+Constraint on the resource type (e.g. 'catalog' or 'image')
+.le
+.ls bandpass = ""
+Constraint on the resource spectral coverage.
+.le
+.ls content = ""
+Constraint on the resource content level.
+.le
+.ls sql = ""
+Arbitrary SQL predicate string.
+.le
+.ls header = yes
+Print header?
+.le
+.ls nresults = 0
+Updated with the number of resources found.
+.le
+.ls status = 0
+Status value, a non-zero value indicates an error.
+.le
+
+.ih
+DESCRIPTION
+
+The \fIMKREGDB\fR task is used to create a local resource database that
+matches a given query term and service constraints. The \fIquery\fR
+parameter is a search term or phrase for the Registry, results may be
+constrained by specifying the \fItype\fR, \fIbandpass\fR, \fIcontent\fR
+or \fIsql\fR parameters. Output is written to the \fIoutput\fR filename
+(or "STDOUT" if a null string).
+
+The \fItype\fR parameter is currently limited to supported data services,
+namely 'image', 'catalog' or 'spectra'. The \fIcontent\fR parameter can be
+used to select only research-grade service, EPO data, etc. Allowed content
+values are described in the IVOA Resource Metadata document
+(http://www.ivoa.net/Documents/latest/RM.html).
+
+The \fIbandpass\fR constraint may be one of the following values:
+.nf
+ radio
+ millimeter
+ infrared, IR
+ optical
+ ultraviolet, ultra-violet, EUV, UV
+ xray, x-ray
+ gamma, gammaray, gamma-ray
+.fi
+
+When done, the \fInresults\fR parameter is updated with the number of
+matching records found. Note that non-data services (e.g. institutional
+names) are not included in the result table. If an error is encountered,
+or no results are found, the \fIstatus\fR parameter will contain a
+non-zero value.
+
+.ih
+EXAMPLES
+
+1) Create a local database of VO Resources containing image data on quasars:
+
+.nf
+ votools> mkregdb quasar type="image"
+.fi
+
+2) Create a local database of all IR catalog services.
+
+.nf
+ votools> mkregdb "" bandpass="infrared" type="catalog"
+.fi
+
+.ih
+REVISIONS
+
+.ih
+SEE ALSO
+regdb, registry
+
+.endhelp
diff --git a/vo/votools/doc/nedoverlay.hlp b/vo/votools/doc/nedoverlay.hlp
new file mode 100644
index 00000000..204c1108
--- /dev/null
+++ b/vo/votools/doc/nedoverlay.hlp
@@ -0,0 +1,74 @@
+.help nedoverlay Mar12 votools
+.ih
+NAME
+nedoverlay -- Overlay NED objects in the image display
+.ih
+USAGE
+nedoverlay image
+.ih
+PARAMETERS
+.ls image
+Input image.
+.le
+.ls append = yes
+Append the display?
+.le
+.ls size = 0.25
+Field size.
+.le
+.ls galaxies = no
+Mark galaxies on the display? This is disabled by default so as not to
+clutter the display.
+.le
+.ls radios = yes
+Mark radio sources on the display?
+.le
+.ls xrays = yes
+Mark X-Ray sources on the display?
+.le
+.ls mkcolor = 208
+Marker color.
+.le
+.ls galcolor = 207
+Galaxy marker color.
+.le
+.ls verbose = no
+Print actions?
+.le
+.ls status = 0
+Service status code.
+.le
+
+.ih
+DESCRIPTION
+The \fINEDOVERLAY\fR task is used to overlay sources from the NED service on
+the image display. If the \fIimage\fR parameter is an object name, it's
+position will be resolved and a query for sources within \fIsize\fR degrees
+of that position will be used. If it is an image name, the WCS footprint
+of the image will be used to generate the query.
+
+If the \fIgalaxies\fR parameter is set, a small cross will be drawn at the
+position of each NED galaxy using the color specified by the \fIgalcolor\fR
+parameter. All other markers will be drawn and labelled using the
+\fImarkcolor\fR value.
+
+.ih
+EXAMPLES
+1. Display an image of m83 and overlay the NED radio sources in the field.
+
+.nf
+ votools> nedoverlay m83 append-
+
+or
+
+ votools> dss m83
+ votools> nedoverlay m83 append+
+.fi
+
+.ih
+REVISIONS
+
+.ih
+SEE ALSO
+radiooverlay, xrayoverlay, obslogoverlay
+.endhelp
diff --git a/vo/votools/doc/obslogoverlay.hlp b/vo/votools/doc/obslogoverlay.hlp
new file mode 100644
index 00000000..ef049c10
--- /dev/null
+++ b/vo/votools/doc/obslogoverlay.hlp
@@ -0,0 +1,98 @@
+.help obslogoverlay Mar12 votools
+.ih
+NAME
+obslogedoverlay -- Overlay observation logs in the image display
+.ih
+USAGE
+obslogoverlay input mission
+.ih
+PARAMETERS
+.ls input
+Input image or field name.
+.le
+.ls mission
+Mission name. A small set of space based missions are supported directly,
+however the task can be easily modified to add other available observation
+logs.
+.le
+.ls size = 0.25
+Field size in degrees. If the \fIinput\fR parameter is not an image, it is
+assumed to be an object name, the query will be for all observations within
+\fIfield\fR degrees of the field center.
+.le
+.ls frame = 1
+Display frame.
+.le
+.ls display = yes
+Display the image/field? If enabled, the input image or a DSS image of
+the field will be displayed before overlaying the catalog.
+.le
+.ls print = no
+List the observations on the standard output?
+.le
+.ls mkcolor = 0
+Marker color. If zero, a predefined color for each mission will be used.
+.le
+.ls mksize = 60
+Marker size (arcsec).
+.le
+.ls maxobs = 0
+Max observations to draw. If zero, all returned results are displayed.
+.le
+.ls verbose = no
+Print actions?
+.le
+.ls status = 0
+Service status code.
+.le
+
+.ih
+DESCRIPTION
+
+The \fIOBSLOGOVERLAY\fR task is used to overlay markers indicating
+observations from the selected space mission. The \fIinput\fR parameter
+may be either an image name containing a valid WCS, or the name of an
+object that will be used to form the query. If an image, the WCS
+footprint will determine the query size, otherwise the \fIsize\fR
+parameter will specify the query size.
+
+The \fImission\fR parameter specifies which mission's observations are
+to be queried. Currently allowed values are:
+.nf
+ EXOSAT FUSE HST
+ IUE Spitzer XMM
+.fi
+Additional missions and ground-based observation logs will be added
+in future versions. This task is meant as a convenience application,
+using other tasks in the \fIVOTOOLS\fR package any observation log
+available from the VO could be overlayed using a small script task.
+
+If the \fIdisplay\fR task is enabled, the \fIinput\fR image (or a DSS
+field containing the named object) will be displayed to frame
+\fIframe\fR in the image display. The \fIprint\fR parameter may be used to
+list instead of overlay the observation positions.
+
+Markers indicating the center of the observation will be drawn using a
+size (in arcsec) specified by the \fImksize\fR parameter. If the
+\fImkcolor\fR parameter is zero, a pre-determined marker color will be
+used for each mission, allowing multiple missions to be overlayed. The
+\fImaxobs\fR parameter can be used to limit the number of markers drawn
+on the display. Note that no attempt is made to drawn a realistic
+instrumental footprint.
+
+.ih
+EXAMPLES
+1. Overlay the IUE observations of the dev$ypix test image:
+.nf
+ votools> obslogoverlay dev$ypix iue maxobs=30
+or
+ votools> obslogoverlay m51 iue size=0.2 display+ frame=1 maxobs=50
+.fi
+
+.ih
+REVISIONS
+
+.ih
+SEE ALSO
+radiooverlay, xrayoverlay, nedoverlay
+.endhelp
diff --git a/vo/votools/doc/overhandler.hlp b/vo/votools/doc/overhandler.hlp
new file mode 100644
index 00000000..e69de29b
--- /dev/null
+++ b/vo/votools/doc/overhandler.hlp
diff --git a/vo/votools/doc/qstring.hlp b/vo/votools/doc/qstring.hlp
new file mode 100644
index 00000000..55c46cba
--- /dev/null
+++ b/vo/votools/doc/qstring.hlp
@@ -0,0 +1,71 @@
+.help qstring Mar12 votools
+.ih
+NAME
+qstring -- Generate a query string URL
+.ih
+USAGE
+qstring base field
+.ih
+PARAMETERS
+.ls base
+Base URL or resource name.
+.le
+.ls field
+Query image or field name.
+.le
+.ls type = "catalog"
+Data service type.
+.le
+.ls ra = 0.0
+RA position of query string (object or image center if provided).
+.le
+.ls dec = 0.0
+Dec position of query string (object or image center if provided).
+.le
+.ls size = 0.25
+Desired query size (or size derived from image).
+.le
+
+.ih
+DESCRIPTION
+The \fIQSTRING\fR task .....
+
+.ih
+EXAMPLES
+1. Print the query string used to access the NED service for the field
+covering the dev$ypix test image:
+
+.nf
+ votools> qstring ned dev$ypix
+ http://ned.ipac.caltech.edu/cgi-bin/nph-NEDobjsearch?search_type=Near+Position+Search&of=xml_main&RA=202.47023333333&DEC=47.194552777778&SR=0.1088616739748&RUNID=iraf2160
+.fi
+
+1. Print the query string used to access the NED service for the field
+covering the dev$ypix test image:
+
+.nf
+ votools> qstring ned dev$ypix
+ http://ned.ipac.caltech.edu/cgi-bin/nph-NEDobjsearch?search_type=Near+Position+Search&of=xml_main&RA=202.47023333333&DEC=47.194552777778&SR=0.1088616739748&RUNID=iraf2160
+.fi
+
+2. Print the query string used to access the DSS image service for the field
+covering the dev$ypix test image:
+
+.nf
+ votools> qstring dss dev$ypix type="image"
+ http://skyview.gsfc.nasa.gov/cgi-bin/vo/sia.pl?survey=dss2&POS=202.47023333333,47.194552777778&SIZE=0.1088616739748&RUNID=iraf2160
+.fi
+
+3. Construct a catalog query string for a local URL at an explicit position:
+.nf
+ votools> qstring http://foo.bar/cat ra=1.23 dec=2.34 size=0.2
+ http://foo.bar/cat?RA=1.23&DEC=2.34&SR=0.2&RUNID=iraf2160
+.fi
+
+.ih
+REVISIONS
+.le
+.ih
+SEE ALSO
+getcat, getimg, getspec, vodata
+.endhelp
diff --git a/vo/votools/doc/radiooverlay.hlp b/vo/votools/doc/radiooverlay.hlp
new file mode 100644
index 00000000..1396626d
--- /dev/null
+++ b/vo/votools/doc/radiooverlay.hlp
@@ -0,0 +1,64 @@
+.help radiooverlay Mar12 votools
+.ih
+NAME
+radiooverlay -- Overlay NVSS radio contours in the image display
+.ih
+USAGE
+radiooverlay image
+.ih
+PARAMETERS
+.ls image
+Input image.
+.le
+.ls size = 0.25
+Field size.
+.le
+.ls ncontours = 0
+Number of contours to be drawn. If 0, the contour interval may
+be specified, otherwise 20-30 nicely spaced contours are
+drawn. A maximum of 40 contours can be drawn.
+.le
+.ls append = yes
+Append the display?
+.le
+.ls verbose = no
+Print actions?
+.le
+.ls device = "imdred"
+Overlay device.
+.le
+.ls status = 0
+Service status code.
+.le
+
+.ih
+DESCRIPTION
+The \fIRADIOOVERLAY\fR task is used to overlay contours from the NVSS 21-cm
+all-sky survey on the image display. If the \fIimage\fR parameter is an
+object name, it's position will be resolved and a query for sources within
+\fIsize\fR degrees of that position will be used. If it is an image name,
+the WCS footprint of the image will be used to generate the query.
+
+The \fICONTOUR\fR task is used to draw the overlays and should be consulted
+to adjust the overlay as desired.
+
+.ih
+EXAMPLES
+1. Display an image of m83 and overlay the NVSS radio contours in the field.
+
+.nf
+ votools> radiooverlay m83 append-
+
+or
+
+ votools> dss m83
+ votools> radiooverlay m83 append+
+.fi
+
+.ih
+REVISIONS
+
+.ih
+SEE ALSO
+nedoverlay, xrayoverlay, obslogoverlay, contour
+.endhelp
diff --git a/vo/votools/doc/regdb.hlp b/vo/votools/doc/regdb.hlp
new file mode 100644
index 00000000..52c7a74d
--- /dev/null
+++ b/vo/votools/doc/regdb.hlp
@@ -0,0 +1,117 @@
+.help regdb Mar12 votools
+.ih
+NAME
+regdb -- Manage/Query a local VO Registry database
+.ih
+USAGE
+regdb arg1 <arg2> <arg3>
+.ih
+PARAMETERS
+.ls arg1, arg2, arg3
+Command argument strings. The \fIarg1\fR parameter is in general the name
+of an operation to be performed (see below), depending on its value the
+additional \fIarg\fR parameters may or may not be required.
+.le
+.ls type = ""
+Service type constraint term.
+.le
+.ls bandpass = ""
+Bandpass constraint term.
+.le
+.ls verbose = no
+Verbose output?
+.le
+.ls status = 0
+Status value, a non-zero value indicates an error or no results found..
+.le
+
+.ls OUTPUT PARAMETERS
+If a matching record is found, one or more of the following task parameters
+may be updated with the record values:
+.nf
+ (alias = "") Resource alias
+ (ivorn = "") Ivorn string
+ (sname = "") Short Name
+ (svctype = "") Resource type
+ (bpass = "") Bandpass
+ (url = "") Service URL
+ (desc = "") Description (Title string)
+.fi
+
+
+.ih
+DESCRIPTION
+
+The \fIREGDB\fR task is used to query or manage the local registry database
+file defined by the VO package \fIresdb\fR parameter. A local registry
+database allows tasks to use preferred resources without generating a
+query to the VO Registry each time information about the resource is
+needed (e.g. the service URL), or to refer to a resource by a user-defined
+alias. The \fIarg1\fR parameter may be either a command to manage the
+database, or a search term for the database, in all cases the results are
+written to the standard output.
+
+Searches may be constrained by setting the \fItype\fR or \fIbandpass\fR
+parameter to match only those records meeting the constraints. This can
+be used for example to select the image service in a registry database
+containing multiple services with the same name alias.
+
+.ih
+COMMANDS
+
+If the first argument to the task is not in the following list of allowed
+commands, it is assumed to be a search term. Record searches are done
+as case-insensitive substring matches against all the saved fields of
+the record.
+
+The following commands are supported:
+
+.nf
+ list List the registry database records
+ resolve Resolve (search) for the \fIarg2\fR string
+ search Search for (resolve) the \fIarg2\fR string
+
+ type Print the service type for records matching \fIarg2\fR
+ alias Print the DB alias for records matching \fIarg2\fR
+ bpass Print the bandpass value for records matching \fIarg2\fR
+ ivorn Print the VO identifier for records matching \fIarg2\fR
+ sname Print the VO ShortName for records matching \fIarg2\fR
+ url Print the ServiceURL for records matching \fIarg2\fR
+ desc Print the Description for records matching \fIarg2\fR
+
+ add Add a record for the service
+ del Delete the record that matches the \fIarg2\fR string
+ update Do a new Registry query and update the local DB
+ rename Rename the local record alias
+.fi
+
+.ih
+EXAMPLES
+
+1) List the local resource database. Repeat but list only the image
+services. Repeat again looking for radio catalog services.
+.nf
+ votools> regdb list
+ votools> regdb list type="image"
+ votools> regdb list type="catalog" bandpass="radio"
+.fi
+
+2) Print the URL for the DSS service in the registry database.
+.nf
+ votools> regdb url alias="dss"
+.fi
+
+3) Find the one X-Ray service in the registry database:
+.nf
+ votools> regdb resolve bandpass="x-ray"
+.fi
+
+
+.ih
+REVISIONS
+
+.ih
+SEE ALSO
+mkregdb, registry
+
+.endhelp
diff --git a/vo/votools/doc/regmetalist.hlp b/vo/votools/doc/regmetalist.hlp
new file mode 100644
index 00000000..a349cf1e
--- /dev/null
+++ b/vo/votools/doc/regmetalist.hlp
@@ -0,0 +1,34 @@
+.help regmetalist Mar12 votools
+.ih
+NAME
+regmetalist -- List the metadata fields of a Registry record
+.ih
+USAGE
+regmetalist
+.ih
+PARAMETERS
+.ls all = no
+List all available fields, or just common ones.
+.le
+
+.ih
+DESCRIPTION
+The \fIREGMETALIST\fR task is used to print the names of the queryable
+fields of the registry. These fields may be used to create SQL predicates
+that may be appended to a query to help constrain the search.
+
+.ih
+EXAMPLES
+1. Demonstrated uses of the command:
+
+.nf
+ votools> regmetalist
+.fi
+
+.ih
+REVISIONS
+
+.ih
+SEE ALSO
+registry, regdb, mkregdb
+.endhelp
diff --git a/vo/votools/doc/sesame.hlp b/vo/votools/doc/sesame.hlp
new file mode 100644
index 00000000..d2d3fbec
--- /dev/null
+++ b/vo/votools/doc/sesame.hlp
@@ -0,0 +1,124 @@
+.help sesame Mar12 votools
+.ih
+NAME
+sesame -- Resolve a target name into a coordinate position
+.ih
+USAGE
+sesame <target>
+.ih
+PARAMETERS
+.ls target
+List of objects to be resolved. Targets may be specified as a
+comma-delimited list string or in an @file to resolve multiple targets. When
+the \fIrange\fR parameter is non-null, this will be the root part of the
+target name.
+.le
+.ls range = ""
+A range string used to expand the \fItarget\fR parameter to a list of names
+to be resolved (e.g. if \fItarget\fR is "ngc" then \fIrange\fR may be
+specified as "1-100" to create a list of the first 100 NGC objects).
+.le
+.ls verbose = yes
+Print coordinates to the stdout? If enabled the sexagesimal coordinates
+of the resolved target will be printed to the STDOUT where they may be easily
+scanned into variables in a script. In all cases, the output parameters
+below are updated with the target information once the task has completed.
+.le
+.ls long = no
+Print long-form output to the stdout? If enabled the target name,
+sexagesimal coordinates, position error (in arcsec) and object type are
+printed on the output line.
+.le
+.ls pos = ""
+A sesagesimal string of the J2000 RA/Dec position (output).
+.le
+.ls ra = 0.0
+J2000 RA of the object in decimal degrees (output).
+.le
+.ls dec = 0.0
+J2000 Declination of the object in decimal degrees (output).
+.le
+.ls ra_err = 0.0
+Error of the RA position in arcsec (output).
+.le
+.ls dec_err = 0.0
+Error of the Dec position in arcsec (output).
+.le
+.ls otype = ""
+Object type (output).
+.le
+.ls status = ""
+Status return code of the web service (output).
+.le
+
+.ih
+DESCRIPTION
+
+The \fBSESAME\fR task invokes the Sesame name resolver service from CDS to
+convert an object identifier (e.g. catalog name) to an ICRS coordinate pair.
+The service will first try to resolve the object using the NED database, and
+if not found will use the Simbad database, the VizieR database is used to
+resolve the coordinates as a final option. The \fItarget\fR parameter may
+be specified as a comma-delimited list or in an @file to resolve multiple
+target names. If the \fIrange\fR parameter is set, it may contain a range
+string that will be expanded to append numeric values to the \fItarget\fR
+value (e.g. to dynamically create catalog names).
+
+If the \fBverbose\fR parameter is set the ra/dec coords are written to the
+STDOUT where they may be easily scanned into script variables. If the
+\fIlong\fR parameter is enabled, all known information about the object is
+printed (as name, ra, dec, ra_err, dec_err and object type).
+
+In cases where only a single object is resolved the \fBpos\vR, \fBra\fR,
+\fBdec\fR, \fBraw_err\fR, \fBdec_err\fR, \fBotype\fR, and \fBstatus\fR
+parameters are updated with the resolved values. The \fRstatus\fR
+parameter will be zero is successful, non-zero is the object could not be
+resolved or the service could not be reached.
+
+.ih
+EXAMPLES
+1. Find the coordinates of M51 (i.e. the dev$pix image):
+
+.nf
+ votools> sesame m51
+ 13:29:55.72 +47:13:53.4
+
+ votools> sesame m51 long+
+ m51 13:29:52.69 +47:11:42. 0. 0. Sy
+
+ votools> sesame m51
+ votools> lpar sesame
+ target = "m51" Target name to resolve
+ (verbose = no) Print position to stdout?\n
+ (pos = "13:29:55.72 +47:13:53.4") Position (sexagesimal string)
+ (ra = 202.4821936) Resolved RA (J2000 decimal degrees)
+ (dec = 47.2315089) Resolved DEC (J2000 decimal degrees)
+ (ra_err = 134.) Error on Resolved RA (arcsec)
+ (dec_err = 134.) Error on Resolved DEC (arcsec)
+ (otype = "GPair") Resolved object type description
+ (status = 0) Resolved DEC (J2000 decimal degrees)
+ (mode = "ql")
+.fi
+
+
+2. Create a local copy of the Messier catalog.
+
+.nf
+ votools> for (i=1; i < 100; i=i+1) {
+ >>> printf ("m%d\n", i) | scan (s1)
+ >>> sesame (s1, verb-)
+ >>> printf ("m%d %s %s\n", i, sesame.pos, sesame.otype)
+ >>> }
+
+ or
+
+ votools> sesame m range="1-110" long+ | fields STDIN "1-3"
+.fi
+
+.ih
+REVISIONS
+.le
+.ih
+SEE ALSO
+voclient
+.endhelp
diff --git a/vo/votools/doc/stilts.hlp b/vo/votools/doc/stilts.hlp
new file mode 100644
index 00000000..b89e0575
--- /dev/null
+++ b/vo/votools/doc/stilts.hlp
@@ -0,0 +1,27 @@
+.help stilts Mar12 votools
+.ih
+NAME
+stilts -- Starlink Tables Infrastructure Library Tool Set
+.ih
+USAGE
+stilts <task> <args>
+
+.ih
+DESCRIPTION
+
+STILTS is used as a foreign task by the NVO package for converting
+VOTables and other utility functions. A full description of the tasks
+available can be found at
+
+.nf
+ http://www.star.bris.ac.uk/~mbt/stilts/
+.fi
+
+STILTS is distributed with the NVO package however it requires Java
+to be available on the machine. The current version requires J2SE1.4
+or later.
+
+.ih
+SEE ALSO
+voclient
+.endhelp
diff --git a/vo/votools/doc/tabclip.hlp b/vo/votools/doc/tabclip.hlp
new file mode 100644
index 00000000..ae359268
--- /dev/null
+++ b/vo/votools/doc/tabclip.hlp
@@ -0,0 +1,39 @@
+.help tabclip Mar12 votools
+.ih
+NAME
+tabclip -- Clip a table to a specified box region
+.ih
+USAGE
+tabclip intab outtab xcol ycol x1 y1 x2 y2
+.ih
+PARAMETERS
+.ls intab
+The input table name.
+.le
+.ls outtab
+The out table name.
+.le
+.ls xcol, ycol
+The X and Y column names.
+.le
+.ls x1, y1
+The lower-left clipping values.
+.le
+.ls x2, y2
+The upper-right clipping values.
+.le
+
+.ih
+DESCRIPTION
+
+The \fITABCLIP\fR task is used clip a table (i.e. select rows) where
+the value is the \fIxcol\fR and \fIycol\fR columns fall within the
+box specified by the \fIx1\fR, \fIy1\fR, \fIx2\fR, \fIx2\fR values.
+
+.ih
+REVISIONS
+
+.ih
+SEE ALSO
+
+.endhelp
diff --git a/vo/votools/doc/taboverlay.hlp b/vo/votools/doc/taboverlay.hlp
new file mode 100644
index 00000000..c69722bd
--- /dev/null
+++ b/vo/votools/doc/taboverlay.hlp
@@ -0,0 +1,61 @@
+.help taboverlay Mar12 votools
+.ih
+NAME
+taboverlay -- General table overlay in the image display
+.ih
+USAGE
+taboverlay image catalog
+.ih
+PARAMETERS
+.ls image
+The input image.
+.le
+.ls catalog
+The input catalog.
+.le
+.ls labcol = 1
+Label column number (one-indexed).
+.le
+.ls racol = 2
+RA column number (one-indexed).
+.le
+.ls deccol =3INDEF
+Dec column number (one-indexed).
+.le
+.ls mkcolor = 208
+Marker color index to use.
+.le
+.ls status = 0
+Status of the service. A non-zero value indicates no results were found.
+.le
+
+.ih
+DESCRIPTION
+
+The \fITABOVERLAY\fR task is used to overlay a catalog of positions on
+the image display. The input catalog file is assumed to be an ascii
+table of the form (index,ra,dec) however the \fIracol\fR, \fIdeccol\fR and
+\fIlabcol\fR parameters can be used to select columns from tables containing
+more information. Markers will be drawn using the color specified by the
+\fImkcolor\fR parameter.
+
+.ih
+EXAMPLES
+1. Query for catalog positions of NGC188 and extract the (numbered) position
+columns to the file 'ngc188.pos'. Then display an image of the field and
+overlay the catalog positions.
+
+.nf
+ votools> getcat gsc2.3 ngc188 size=0.1 output="ngc188.xml"
+ votools> votpos ngc188.xml number+ out="ngc188.pos"
+ votools> dss ngc188
+ votools> taboverlay ngc188 ngc188.pos
+.fi
+
+.ih
+REVISIONS
+.
+.ih
+SEE ALSO
+getcat, getimg
+.endhelp
diff --git a/vo/votools/doc/tblhandler.hlp b/vo/votools/doc/tblhandler.hlp
new file mode 100644
index 00000000..e69de29b
--- /dev/null
+++ b/vo/votools/doc/tblhandler.hlp
diff --git a/vo/votools/doc/topcat.hlp b/vo/votools/doc/topcat.hlp
new file mode 100644
index 00000000..441c5b18
--- /dev/null
+++ b/vo/votools/doc/topcat.hlp
@@ -0,0 +1,50 @@
+.help topcat Mar12 votools
+.ih
+NAME
+topcat -- Start/Stop/Status of the Topcat external task
+.ih
+USAGE
+topcat command
+.ih
+PARAMETERS
+.ls command
+Command to execute. If not specified, the default action is to start
+the application.
+.le
+.ls bkg = yes
+Run the application in the background?
+.le
+.ls verbose = no
+Print actions?
+.le
+
+.ih
+DESCRIPTION
+The \fITOPCAT\fR task is used to start, stop, or check the status of
+the Topcat external application. If no command argument is given, the
+default action is to start the application if it is not already running.
+If command is \fIstop\fR then a running Topcat application is shutdown.
+
+If the command is \fIstatus\fR then the output will be "on" or "off"
+depending on whether the application is running.
+
+.ih
+EXAMPLES
+1. Demonstrated uses of the command:
+
+.nf
+ votools> topcat status # check if Topcat is running
+ off
+ votools> topcat start # start Topcat
+ votools> topcat status # check if Topcat is running
+ on
+ votools> topcat stop # stop Topcat
+.fi
+
+.ih
+REVISIONS
+.le
+.ih
+SEE ALSO
+hub, aladin, samp
+.endhelp
diff --git a/vo/votools/doc/voclient.hlp b/vo/votools/doc/voclient.hlp
new file mode 100644
index 00000000..8b5c1773
--- /dev/null
+++ b/vo/votools/doc/voclient.hlp
@@ -0,0 +1,22 @@
+.help voclient Mar12 votools
+.ih
+NAME
+voclient -- The VO Client / IRAF Interface
+
+.ih
+INTRODUCTION
+
+.ih
+DESCRIPTION
+
+
+.ih
+EXAMPLES
+
+.ih
+REVISIONS
+.le
+.ih
+SEE ALSO
+conecaller, siapcaller, datascope, registry, vizier
+.endhelp
diff --git a/vo/votools/doc/vodata.hlp b/vo/votools/doc/vodata.hlp
new file mode 100644
index 00000000..25df9068
--- /dev/null
+++ b/vo/votools/doc/vodata.hlp
@@ -0,0 +1,189 @@
+.help vodata Mar12 votools
+.ih
+NAME
+vodata -- General-purpose query and access to VO data services
+
+.ih
+USAGE
+vodata resources objects
+
+.ih
+PARAMETERS
+.ls resources
+List of resources to query
+.le
+.ls objects
+List of targets to query
+.le
+.ls ra = 0.0
+Resolved RA (J2000 decimal degrees)
+.le
+.ls dec = 0.0
+Resolved Dec (J2000 decimal degrees)
+.le
+.ls size = 0.0
+Query size (decimal degrees)
+.le
+.ls output = ""
+Output filename base
+.le
+.ls format = "raw"
+Output format
+.le
+.ls samp = yes
+Broadcast as samp message?
+.le
+.ls bandpass = ""
+Bandpass constraint
+.le
+.ls type = ""
+Service type constraint
+.le
+.ls nthreads = 1
+Number of simultaneous query threads
+.le
+.ls resdb = ")_.resdb"
+Resource database
+.le
+.ls header = yes
+List result column headers only?
+.le
+.ls verbose = 1
+Query verbosity level
+.le
+.ls quiet = yes
+Suppress task output?
+.le
+.ls status = 0
+Service status code
+.le
+
+.ih
+DESCRIPTION
+
+
+
+
+
+.ih
+EXAMPLES
+
+1) Query the GSC 2.3 catalog for stars a) within the 0.1 degree default
+search size around NGC 1234: b) around all positions contained in file
+'pos.txt': c) for the list of objects given on the command line: d)
+query a list of services for a list of positions: e) print a count of
+results that would be returned from 3 services for each position in a file:
+(f) find the 2MASS point sources in the dev$ypix test image:
+
+.nf
+ votools> vodata gsc2.3 ngc1234 (a)
+ votools> vodata gsc2.3 @pos.txt (b)
+ votools> vodata gsc2.3 m31,m51,m93 (c)
+ votools> vodata @svcs.txt @pos.txt (d)
+ votools> vodata hst,chandra,gsc2.3 @pos.txt (e)
+ votools> vodata 2mass-psc dev$ypix (f)
+.fi
+
+
+2) Query all available image services having data of the subdwarf galaxy
+IC 10:
+
+.nf
+ votools> vodata any IC10 type="image" *
+.fi
+
+Note that we use the reserved word '\fIany\fR' for the service name and
+constrain by image type. The task will automatically query the Registry to
+create the list of services to be queried.
+
+
+3) Query for X-ray image data around Abell2712:
+
+.nf
+ votools> vodata any abell2712 type="image" bandpass="x-ray"
+.fi
+
+In this case we constrain both the service type as well as the spectral
+coverage published for the resource in the Registry. The object name is
+resolved to coordinates internally.
+
+
+4) Use the Registry to query for resources using the search terms
+"cooling flow". Upon examining the output the user notices a
+Vizier paper titled "\fICooling Flows in 207 clusters of Galaxies\fR"
+that looks interesting. Use the \fBvodata\fR task to download all
+tables associated with this paper, save tables in the default
+CSV format:
+.nf
+
+ votools> registry "cooling flow" verb+
+ votools> vodata J/MNRAS/292/419 output="white97" all+
+
+.fi
+All tables will be written to the current directory to files having a
+root name 'white97' (chosen based on the author and publication date).
+
+
+5) Query for the images available from 2MASS at a given position,
+extract the positions and service URLs to separate files:
+
+.nf
+ votools> vodata 2mass output="2mass" type="image" ra=12:34 dec=-23:12
+ votools> votpos 2mass.xml out="2mass.pos"
+ votools> votget 2mass.pos
+.fi
+
+The query produces files with the root name '2mass', and extensions of
+"\fI.csv\fR" (the main response), "\fI.pos\fR" (the extracted pos- itions),
+and "\fI.urls\fR" (the access references). The user inspects the files and
+notices that the references return both FITS and HTML files, but she only
+wants the FITS image date and uses \fBvotget\fR to download only those.
+
+
+6) Use \fIvodata\fR as a test client for a locally-installed SIAP service:
+
+.nf
+ votools> vodata http://localhost/siap.pl type="image" ra=180.0 dec=0.0
+.fi
+
+In this case we force the serviceURL being used by simply specifying it as
+the resource parameter, but since we can't do a Registry query to discover
+what type of service this is, we must use the '\fItype\fR' parameter to
+indicate it is an image service.
+
+
+7) Use the \fITSELECT\fR task select rows from a VOTable of QSOs (made
+with an earlier query) where the redshift is > 0.2. Use \fITDUMP\fR to
+print only the positions then call \fIVODATA\fR to see whether HST has
+observed any of these objects:
+
+.nf
+ votools> tselect qso_survey.xml high_z.fits "Z > 0.2"
+ votools> tdump high_z.fits columns="RA,DEC" > pos.txt
+ votools> vodata hstpaec @pos.txt
+.fi
+
+
+8) Query the VO for GALEX data of M51. Because the \fIShortName\fR GALEX
+is not unique, we must either specify the IVO identifier of a
+specific service to query, or if we're interested in results from all
+supported data services with \fIgalex\fR in the name:
+
+.nf
+ votools> vodata galex M51 all+ output="m51"
+.fi
+
+The results come from the Cone and SIAP services both called \fIGALEX\fR,
+as well as an additional SIAP service called 'GALEX_Atlas'. Note that the
+service names are case insensitive in either case.
+
+
+
+
+.ih
+REVISIONS
+.le
+.ih
+SEE ALSO
+conecaller, siapcaller, datascope, registry, vizier
+.endhelp
diff --git a/vo/votools/doc/votcopy.hlp b/vo/votools/doc/votcopy.hlp
new file mode 100644
index 00000000..f47d4af3
--- /dev/null
+++ b/vo/votools/doc/votcopy.hlp
@@ -0,0 +1,102 @@
+.help votcopy Mar12 votools
+.ih
+NAME
+votcopy -- Copy VOTables to a new format
+.ih
+USAGE
+votcopy input output format
+.ih
+PARAMETERS
+.ls input
+The list of input VOTables.
+.le
+.ls output
+The list of output file names.
+.le
+.ls format
+
+.ls vot | xml
+A new VOTable.
+.le
+.ls asv
+Ascii separated values.
+.le
+.ls bsv
+Bar separated values.
+.le
+.ls csv
+Comma separated values.
+.le
+.ls tsv
+Tab separated values.
+.le
+.ls html
+Standalone HTML document.
+.le
+.ls shtml
+Single HTML <table> element. This format may be used to generate the <table>
+code for inclusion in another HTML document.
+.le
+.ls fits
+FITS binary table
+.le
+
+.le
+.ls header = yes
+Print a header on formats that support it?
+.le
+.ls verbose = yes
+Print verbose output?
+.le
+
+.ih
+DESCRIPTION
+
+
+.ih
+EXAMPLES
+1. Find the coordinates of M51 (i.e. the dev$pix image):
+
+.nf
+ votools> sesame m51
+ 13:29:55.72 +47:13:53.4
+
+ votools> sesame m51 long+
+ m51 13:29:52.69 +47:11:42. 0. 0. Sy
+
+ votools> sesame m51
+ votools> lpar sesame
+ target = "m51" Target name to resolve
+ (verbose = no) Print position to stdout?\n
+ (pos = "13:29:55.72 +47:13:53.4") Position (sexagesimal string)
+ (ra = 202.4821936) Resolved RA (J2000 decimal degrees)
+ (dec = 47.2315089) Resolved DEC (J2000 decimal degrees)
+ (ra_err = 134.) Error on Resolved RA (arcsec)
+ (dec_err = 134.) Error on Resolved DEC (arcsec)
+ (otype = "GPair") Resolved object type description
+ (status = 0) Resolved DEC (J2000 decimal degrees)
+ (mode = "ql")
+.fi
+
+
+2. Create a local copy of the Messier catalog.
+
+.nf
+ votools> for (i=1; i < 100; i=i+1) {
+ >>> printf ("m%d\n", i) | scan (s1)
+ >>> sesame (s1, verb-)
+ >>> printf ("m%d %s %s\n", i, sesame.pos, sesame.otype)
+ >>> }
+
+ or
+
+ votools> sesame m range="1-110" long+ | fields STDIN "1-3"
+.fi
+
+.ih
+REVISIONS
+.le
+.ih
+SEE ALSO
+voclient
+.endhelp
diff --git a/vo/votools/doc/votget.hlp b/vo/votools/doc/votget.hlp
new file mode 100644
index 00000000..cdbf7637
--- /dev/null
+++ b/vo/votools/doc/votget.hlp
@@ -0,0 +1,107 @@
+.help votget Mar12 votools
+.ih
+NAME
+votget -- Download data referenced in a VOTable
+.ih
+USAGE
+votget input base
+.ih
+PARAMETERS
+.ls input
+The list of input VOTables.
+.le
+.ls base
+The base output filename.
+.le
+.ls extn = "fits"
+Filename extension. The \fIextn\fR string will be appended to each
+downloaded filename.
+.le
+.ls format
+Format to download. If not a null string and the \fIextn\fR string is a
+substring of the value of the column containing the UCD "VOX:Image_Format",
+the referenced file will be downloaded.
+.le
+.ls acref = "VOX:Image_AccessReference"
+The UCD of the column containing the image access reference.
+.le
+.ls col = INDEF
+The (one-indexed) column number containing the image access reference. If
+specified, the UCD values will be ignored and the specific column will be
+used.
+.le
+.ls sequential = yes
+If enabled, sequential file numbers will be appended to the \fIbase\fR
+name for each downloaded file. Otherwise, an image name will be constructed
+from the access URL. In the latter case, no check is made to prevent
+overwriting of files.
+.le
+.ls nthreads = 4
+Number of simultaneous download threads to execute.
+.le
+.ls list = no
+List access references instead of downloading? Enabling this option may
+be used to extract a list of access URLs from the table.
+.le
+
+.ih
+DESCRIPTION
+
+The \fIVOTGET\fR task is used to download data referenced in a VOTable
+(e.g. the result of a query to an image or spectral service) to the local
+machine. The \fIinput\fR parameter may be a list of VOTables, in which
+case the parameters will apply to all files in input the list. The
+\fIformat\fR parameter is used to select the image format to download from
+the file, it is a case-insensitive substring of the VOTable column
+containing the UCD "VOC:Image_Format". If this column does not exist, or
+if the \fIformat\fR parameter is the null string, then all images will be
+retrieved. The \fIacref\fR parameter parameter specified the UCD that
+identifies the access reference to retrieve (i.e. a table may contain
+multiple URLs per row, the UCD uniquely identifies the desired data
+column), the default value of "VOX:Image_AccessReference" is the standard
+value used for current VO data services. Alternatively, the \fIcol\fR
+parameter may be used to specify the column number (one-indexed) to
+retrieve (e.g. to download other URLs in the table).
+
+The \fIbase\fR parameter defines the root part of the saved image name, and
+\fIextn\fR provides the extension. If the \fIsequential\fR parameter is
+set then files will be numbered in the order they were retrieved and saved
+to a filename of the form "\fI<base><seqno>.<extn>\fR". Otherwise, a
+filename is constructed from the access URL and may or may not be either
+unique or helpful.
+
+Data are retrieved using multiple simultaneous threads in order make most
+efficient use of the network and data service. The \fInthreads\fR
+parameter determines how many simultaneous downloads will be in progress at
+any one time. Once a download completes, a new thread is started until all
+files have been retrieved.
+
+The \fIlist\fR parameter may be used to simply extract a list of URLs from
+all of the input tables. When enabled, the \fIbase\fR paramter is not
+required and a list of URLs, one per line, will be printed on the standard
+output.
+
+
+.ih
+EXAMPLES
+1. Download all images referenced in the test Simple Image Access service
+result table, saved files will
+
+.nf
+ votools> votget data$sia.xml test
+.fi
+
+2. Extrace the access URLs from the same table without actually downloading
+the files:
+
+.nf
+ votools> votget data$sia.xml list+
+.fi
+
+.ih
+REVISIONS
+.le
+.ih
+SEE ALSO
+votcopy
+.endhelp
diff --git a/vo/votools/doc/votpos.hlp b/vo/votools/doc/votpos.hlp
new file mode 100644
index 00000000..5a817327
--- /dev/null
+++ b/vo/votools/doc/votpos.hlp
@@ -0,0 +1,119 @@
+.help votpos Mar12 votools
+.ih
+NAME
+votpos -- Extract the position columns from a VOTable
+.ih
+USAGE
+votpos input
+.ih
+PARAMETERS
+.ls input
+The list of input VOTables.
+.le
+.ls output = STDOUT
+The output filename.
+.le
+.ls ra_col = INDEF
+RA column number (one-indexed). If specified as other than INDEF, the named
+column will be used instead of the column determined by the primary position
+UCD (i.e. 'POS_EQ_RA_MAIN' or 'pos.eq.ra;meta.main').
+.le
+.ls dec_col = INDEF
+Dec column number (one-indexed). If specified as other than INDEF, the named
+column will be used instead of the column determined by the primary position
+UCD (i.e. 'POS_EQ_DEC_MAIN' or 'pos.eq.dec;meta.main').
+.le
+.ls rows = "-"
+A range specification of rows to extract.
+.le
+.ls header = no
+Print a output header?
+.le
+.ls number = no
+Print the row number of each position? If enabled, the output will consist
+of the (index,ra,dec) values from the table, otherwise just the (ra,dec) will
+be printed.
+.le
+.ls plot = no
+Plot the result table on the standard graphics stream? If enabled, a plot
+of the (ra,dec) positions will be drawn to the graphics terminal.
+.le
+.ls overplot = no
+Over an existing display/plot? If enabled, and existing plot will be
+appended using the same axis labels and scale.
+.le
+.ls color = 1
+Plot marker color (in the range 1 to 9).
+.le
+.ls title = ""
+Title string to put on a plot.
+.le
+.ls verbose = yes
+Print verbose output?
+.le
+.ls status = 0
+Status of the service. A non-zero value indicates no results were found.
+.le
+
+.ih
+DESCRIPTION
+
+The \fIVOTPOS\fR task is used to extract the primary position columns from
+a VOTable. These columns are defined by the UCD 'POS_EQ_RA_MAIN' and
+'POS_EQ_DEC_MAIN' for Cone Search services, or by 'pos.eq.ra;meta.main'
+and 'pos.eq.dec;meta.main' for other VO services. If the \fIra_col\fR
+and \fIdec_col\fR parameters are set, the (one-indexed) column number in
+the table will be used regardless of the UCD value. Rows of the table
+may be selected by specifying a range string to the \fIrows\fR parameter.
+
+If the \fIheader\fR parameter is enabled, a table header will prepend the
+list of extracted positions. If the \fInumber\fR parameter is enabled,
+the row number will be printed as the first column of the output.
+
+A plot of the positions may be displayed by setting the \fIplot\fR parameter.
+Subsequent tables may be appended to the plot by specifying the
+\fIoverplot\fR parameter. When not overplotting, the \fIcolor\fR parameter
+number 1 will always be used, otherwise each overplot will automatically
+increment the marker color to make the points a unique color. In all cases,
+the marker shape will be a box meaning that when overplotted points are at
+the same position they will be drawn in the last color used and may be
+confused with earlier points at the same position. A title string may be
+put on the plot by specifying the \fItitle\fR parameter.
+
+
+.ih
+EXAMPLES
+1. Query for catalog positions of NGC188 and extract the (numbered) position
+columns to the file 'ngc188.pos'.
+
+.nf
+ votools> getcat gsc2.3 ngc188 size=0.1 output="ngc188.xml"
+ votools> votpos ngc188.xml number+ out="ngc188.pos"
+.fi
+
+2. Use the VOTable is the first example but plot the positions on the
+graphics terminal. Overplot a second catalog query of the 2MASS Point
+SOurce Catalog without saving the extracted positions.
+
+.nf
+ votools> votpos ngc188.xml plot+ out="ngc188.pos"
+ votools> getcat 2mass-psc ngc188 size=0.1 output="2mass.xml"
+ votools> votpos 2mass.xml plot+ overplot+ out=""
+.fi
+
+3. Query the GSC 2.3 catalog to overlay an image displayed of the NGC188 field.
+
+.nf
+ votools> dss ngc188 size=0.1
+ votools> getcat gsc2.3 ngc188 size=0.1 output="ngc188.xml"
+ votools> votpos ngc188.xml number+ out="ngc188.pos"
+ votools> taboverlay ngc188 ngc188.pos
+.fi
+
+.ih
+REVISIONS
+.
+.ih
+SEE ALSO
+getcat, getimg
+.endhelp
diff --git a/vo/votools/doc/wcsinfo.hlp b/vo/votools/doc/wcsinfo.hlp
new file mode 100644
index 00000000..a387bf4c
--- /dev/null
+++ b/vo/votools/doc/wcsinfo.hlp
@@ -0,0 +1,77 @@
+.help wcsinfo Mar12 votools
+.ih
+NAME
+wcsinfo -- Determine the WCS information of an image
+.ih
+USAGE
+wcsinfo image
+.ih
+PARAMETERS
+.ls image
+The input image name.
+.le
+.ls verbose = no
+Print verbose output?
+.le
+
+.ls OUTPUT PARAMETERS
+After reading the image, the following task parameters are updated with
+the values derived from the input image:
+
+.nf
+ (pos = "") POS string
+ (size = 0.) SIZE value
+ (ra = 0.) RA value
+ (dec = 0.) DEC value
+ (llx = 0.) LLX wcs corner
+ (lly = 0.) LLY wcs corner
+ (urx = 0.) URX wcs corner
+ (ury = 0.) URY wcs corner
+ (midx = 0.) X wcs midpoint
+ (midy = 0.) Y wcs midpoint
+ (scale = 0.) Scale ("/pix)
+ (rot = 0.) Rotation (deg)
+ (width = 0.) Plt width (arcmin)
+ (height = 0.) Plt height (arcmin)
+ (axmap = "") Axis mapping
+ (epoch = 0.) Epoch
+ (equinox = 0.) Equinox
+ (ctype1 = "") CTYPE1
+ (ctype2 = "") CTYPE2
+ (crval1 = 0.) CRVAL1
+ (crval2 = 0.) CRVAL2
+ (crpix1 = 0.) CRPIX1
+ (crpix2 = 0.) CRPIX2
+ (cd11 = 0.) CD1_1
+ (cd12 = 0.) CD1_2
+ (cd21 = 0.) CD2_1
+ (cd22 = 0.) CD2_2
+ (ispix = no) Pixel only coords?
+.fi
+
+.ih
+DESCRIPTION
+
+The \fIWCSINFO\fR task is used to determine the WCS information in an image
+in ways which make it easy for script developers to use specific values
+easily (e.g. the plate center, scale, size, corners, etc). Images of
+arbitrary axis mapping and rotation can be used. If no WCS information
+can be found in the image, the \fIispix\fR parameter will be set to
+'yes'.
+
+
+.ih
+EXAMPLES
+1. Summarize the WCS information about the dev$ypix test image:
+
+.nf
+ votools> wcsinfo dev$ypix
+.fi
+
+.ih
+REVISIONS
+.
+.ih
+SEE ALSO
+getcat, getimg
+.endhelp
diff --git a/vo/votools/doc/xrayoverlay.hlp b/vo/votools/doc/xrayoverlay.hlp
new file mode 100644
index 00000000..c6282909
--- /dev/null
+++ b/vo/votools/doc/xrayoverlay.hlp
@@ -0,0 +1,65 @@
+.help xrayoverlay Mar12 votools
+.ih
+NAME
+xrayoverlay -- Overlay RASS3 broad-band X-Ray contours in the image display
+.ih
+USAGE
+xrayoverlay image
+.ih
+PARAMETERS
+.ls image
+Input image.
+.le
+.ls size = 0.25
+Field size.
+.le
+.ls ncontours = 0
+Number of contours to be drawn. If 0, the contour interval may
+be specified, otherwise 20-30 nicely spaced contours are
+drawn. A maximum of 40 contours can be drawn.
+.le
+.ls append = yes
+Append the display?
+.le
+.ls verbose = no
+Print actions?
+.le
+.ls device = "imdred"
+Overlay device.
+.le
+.ls status = 0
+Service status code.
+.le
+
+.ih
+DESCRIPTION
+The \fIRADIOOVERLAY\fR task is used to overlay contours from the RASS3
+broad-band
+all-sky survey on the image display. If the \fIimage\fR parameter is an
+object name, it's position will be resolved and a query for sources within
+\fIsize\fR degrees of that position will be used. If it is an image name,
+the WCS footprint of the image will be used to generate the query.
+
+The \fICONTOUR\fR task is used to draw the overlays and should be consulted
+to adjust the overlay as desired.
+
+.ih
+EXAMPLES
+1. Display an image of m83 and overlay the RASS3 X-Ray contours in the field.
+
+.nf
+ votools> xrayoverlay m83 append-
+
+or
+
+ votools> dss m83
+ votools> xrayoverlay m83 append+
+.fi
+
+.ih
+REVISIONS
+
+.ih
+SEE ALSO
+nedoverlay, xrayoverlay, obslogoverlay, contour
+.endhelp
diff --git a/vo/votools/dss.cl b/vo/votools/dss.cl
new file mode 100644
index 00000000..bdfd03e3
--- /dev/null
+++ b/vo/votools/dss.cl
@@ -0,0 +1,107 @@
+#{ DSS -- Display a DSS image of a named field, image or position.
+
+procedure dss (field)
+
+string field { prompt = "Input field" }
+
+real ra = 0.0 { prompt = "RA of field" }
+real dec = 0.0 { prompt = "Dec of field" }
+real size = 0.25 { prompt = "Field size" }
+int frame = 1 { prompt = "Display frame" }
+bool use_display = yes { prompt = "Verbose output?" }
+bool grid = no { prompt = "Overlay coordinate grid?" }
+bool verbose = yes { prompt = "Verbose output?" }
+bool save = yes { prompt = "Save image?" }
+string imname = "" { prompt = "Output image name" }
+
+begin
+ string url, imurl, img, query, restab, base
+ real lra, ldec, fra, fdec, sz
+ bool lsave, isim, fcache, do_grid
+
+ lra = ra # Initialize
+ ldec = dec
+ sz = size
+ lsave = save
+ isim = no
+ do_grid = grid
+ restab = mktemp ("tmp$dss")
+
+ base = "http://archive.eso.org/bin/dss_sia/dss.sia?VERSION=1.0&"
+
+
+ fcache = yes
+ if (field == "") {
+ fra = ra
+ fdec = dec
+ lsave = no
+ isim = no
+ fcache = no
+ img = mktemp ("dss") // ".fits"
+ if (imaccess ("cache$tmp.fits") == yes)
+ imdelete ("cache$tmp.fits", verify-, >& "dev$null")
+ field = "tmp"
+ imname = "cache$" // field// ".fits"
+
+ } else if (imaccess (field)) {
+ iferr { wcsinfo (field, verb-) } then {
+ error (0, "Cannot determine image coords for `"//field//"'")
+ } else {
+ fra = wcsinfo.midx
+ fdec = wcsinfo.midy
+ sz = max (wcsinfo.width, wcsinfo.height) / 60.0
+ img = field
+ isim = yes
+ field = strsub (field, "$", "_")
+ imname = field
+ }
+ } else {
+ sesame (field, verbose-)
+ fra = sesame.ra
+ fdec = sesame.dec
+ img = "cache$" // field// "_t.fits"
+ imname = "cache$" // field// ".fits"
+ isim = no
+ }
+
+ # Form the query string.
+ printf ("POS=%.5f,%.5f&SIZE=%.3f", fra, fdec, sz) | scan (query)
+ url = base // query
+ if (vo.runid != "")
+ url = url // "&RUNID=" // vo.runid
+
+
+ # Perform the SIA query string.
+ urlget (url, restab, extn="xml", use_cache=fcache, cache="cache$")
+
+ # Extract the URL from the first row, this'll be the image we use.
+ tdump (restab, row=1, col="Url", pwidth=2048, cdfile="dev$null",
+ pfile="dev$null") | scan (imurl)
+
+ # Download the image.
+ if (vo.runid != "")
+ imurl = imurl // "&RUNID=" // vo.runid
+ urlget (imurl, img, extn="fits", use_cache=fcache, cache="cache$")
+ if (lsave) {
+ #copy ("cache$" // field //"_t.fits", "cache$" // field //".fits")
+ copy (img, "cache$" // field //".fits")
+ img = "cache$" // field // ".fits"
+ } else {
+ if (fcache)
+ img = "cache$" // field // "_t.fits[0]"
+ }
+ ;
+
+ # Display the image.
+ if (use_display)
+ display (img, frame, fill+, >& "dev$null")
+
+ if (do_grid)
+ wcslab (img, 1, use-, fill+, overplot+, append+,
+ labout-, dev="imdc")
+
+ # clean up
+ delete (restab, verify-)
+ if (! isim && ! lsave)
+ imdelete (img, go_ahead+, verify-, >& "dev$null")
+end
diff --git a/vo/votools/gasplib/calcds.x b/vo/votools/gasplib/calcds.x
new file mode 100644
index 00000000..0f434b26
--- /dev/null
+++ b/vo/votools/gasplib/calcds.x
@@ -0,0 +1,139 @@
+include <math.h>
+define SZ_CDMATRIX 4 # CD1_1, CD1_2, CD2_1, CD2_2
+
+# CALCDS -- Procedure to calculate the values of the CD matrix from
+# information given by a extracted Guide Star file.
+
+procedure calcds (plt_centre_ra,
+ plt_centre_dec,
+ plt_centre_x,
+ plt_centre_y,
+ x_corner,
+ y_corner,
+ x_pixel_size,
+ y_pixel_size,
+ plate_scale,
+ x_size,
+ y_size,
+ im_cen_ra,
+ im_cen_dec,
+ amd_x,
+ amd_y,
+ cd_matrix)
+
+double plt_centre_ra # Plate centre RA (radians)
+double plt_centre_dec # Plate centre DEC
+double plt_centre_x # X center position (microns)
+double plt_centre_y # Y center position
+int x_corner # x lower left of the extracted subset
+int y_corner # y
+double x_pixel_size # X scan pixel size (microns)
+double y_pixel_size # Y scan pixel size
+double plate_scale # Plate scale (arcsec/mm)
+int x_size # Extracted image size x_axis (pixel)
+int y_size # Extracted image size y_axis (pixel)
+double im_cen_ra # Extracted image center RA (radians)
+double im_cen_dec # Extracted image center DEC (radians)
+double amd_x[ARB] # Xi plate solution coefficients
+double amd_y[ARB] # Eta coefficients (arsec/mm)
+double cd_matrix[SZ_CDMATRIX] # CD1_1, CD1_2, CD2_1, CD2_2 (degrees/pixel)
+
+pointer sp, xip, etap, x_arr, y_arr, u, v, w, cvm
+int sx, sy, xlim, ylim
+int i, j, k, nterms, xi, eta, npts
+double x_coeff[2], y_coeff[2], xchisqr, ychisqr
+double x_sigma[2], y_sigma[2], x, y, xc, yc
+real ww[100]
+double new_plt_centre_x, new_plt_centre_y, xref, yref, mag, color
+double ra, dec
+int nx,ny,nxy
+
+begin
+ mag = 0.0
+ color= 0.0
+ # calculate new plate center in microns
+ new_plt_centre_x = (x_size/2.)*x_pixel_size
+ new_plt_centre_y = (y_size/2.)*y_pixel_size
+
+ call smark (sp)
+ call salloc (xip, 100, TY_DOUBLE)
+ call salloc (etap, 100, TY_DOUBLE)
+ call salloc (x_arr, 2*100, TY_DOUBLE)
+ call salloc (y_arr, 2*100, TY_DOUBLE)
+
+ sx = max (1, x_size/10)
+ sy = max (1, y_size/10)
+
+ xlim = x_size - mod(x_size, sx)
+ ylim = y_size - mod(y_size, sy)
+ nx = xlim/sx
+ ny = ylim/sy
+ nxy = nx*ny
+ xi = xip
+ eta = etap
+ k = 0
+ do i = sx, xlim, sx {
+ y = i # x coord. from lower left
+ do j = sy, ylim, sy {
+ x =j # y coord. from lower left
+ xc = x + x_corner
+ yc = y + y_corner
+ # Obtain ra and dec from this grid (w/r to the original lower
+ # left corner) given the original plate center.
+ call ccgseq (plt_centre_ra, plt_centre_dec,
+ plt_centre_x, plt_centre_y,
+ x_pixel_size, y_pixel_size, plate_scale, amd_x, amd_y,
+ xc, yc, mag, color, ra, dec)
+
+ # Calculate xi and eta given the new plate center
+ call treqst (im_cen_ra, im_cen_dec, ra, dec, Memd[xi], Memd[eta])
+ xi = xi + 1
+ eta = eta + 1
+
+ # pixel to mm from the new plate center, notice x, y are
+ # w/r to the new lower left corner
+# xref = (new_plt_centre_x - x * x_pixel_size) / 1000.
+ xref = (x * x_pixel_size - new_plt_centre_x) / 1000.
+ yref = (y * y_pixel_size - new_plt_centre_y) / 1000.
+
+ # form normal equations for the model
+ # xi = a*xref + b*yref
+ # eta = c*yref + d*xref
+ #
+ Memd[x_arr+k] = xref # XAR(j,1)
+ Memd[x_arr+k+nxy] = yref # XAR(j,2)
+ Memd[y_arr+k] = yref # YAR(i,1)
+ Memd[y_arr+k+nxy] = xref # YAR(i,2)
+
+ k = k + 1
+ ww[k] = 1.0
+ }
+ }
+
+ # calculate coefficients now
+
+ npts = k
+ nterms = 2
+ call salloc (u, npts*nterms, TY_DOUBLE)
+ call salloc (v, nterms*nterms, TY_DOUBLE)
+ call salloc (w, nterms, TY_DOUBLE)
+ call salloc (cvm, nterms*nterms, TY_DOUBLE)
+ call fitsvd (Memd[x_arr], Memd[xip], ww, npts, x_coeff,
+ nterms, Memd[u], Memd[v], Memd[w], xchisqr)
+ call varsvd (Memd[v], nterms, Memd[w], Memd[cvm], nterms)
+ do i =1, nterms
+ x_sigma[i] = sqrt(Memd[cvm+(i-1)+(i-1)*nterms])
+ call fitsvd (Memd[y_arr], Memd[etap], ww, npts, y_coeff,
+ nterms, Memd[u], Memd[v], Memd[w], ychisqr)
+ call varsvd (Memd[v], nterms, Memd[w], Memd[cvm], nterms)
+ do i =1, nterms
+ y_sigma[i] = sqrt(Memd[cvm+(i-1)+(i-1)*nterms])
+
+ # degrees/pixel = (arcsec/mm)*(mm/pixel)*(degrees/arcsec)
+ cd_matrix[1] = x_coeff[1]*(x_pixel_size/1000.)*(1/3600.)
+ cd_matrix[2] = x_coeff[2]*(y_pixel_size/1000.)*(1/3600.)
+ cd_matrix[3] = y_coeff[2]*(y_pixel_size/1000.)*(1/3600.)
+ cd_matrix[4] = y_coeff[1]*(x_pixel_size/1000.)*(1/3600.)
+
+ call sfree (sp)
+end
diff --git a/vo/votools/gasplib/ccgseq.x b/vo/votools/gasplib/ccgseq.x
new file mode 100644
index 00000000..f0e071f3
--- /dev/null
+++ b/vo/votools/gasplib/ccgseq.x
@@ -0,0 +1,94 @@
+# CCGSEQ -- Routine for computing RA and Dec for a given X,Y pixel
+# position on a GSSS plate.
+
+procedure ccgseq (plate_centre_ra, plate_centre_dec, plate_centre_x,
+ plate_centre_y, x_pixel_size, y_pixel_size,
+ plate_scale, amd_x, amd_y, object_x, object_y,
+ object_mag, object_col, object_ra, object_dec)
+
+double plate_centre_ra #Plate Right Ascension (radians)
+double plate_centre_dec #Plate Declination (radians)
+double plate_centre_x #Position used in soln.(microns)
+double plate_centre_y # "
+double x_pixel_size #Scan pixel size (microns)
+double y_pixel_size # "
+double plate_scale #Plate scale (arcsec/mm)
+double amd_x[20] #Plate model coefficients
+double amd_y[20] # "
+double object_x #Pixel position for object
+double object_y # "
+double object_mag #Magnitude
+double object_col #Colour
+double object_ra #Object RA (radians)
+double object_dec # " Dec
+
+double x #Position from centre (mm)
+double y # "
+double xi_object #Standard coords (arcsec)
+double eta_object # "
+double p1,p2,p3,p4
+
+begin
+ # Convert x,y from pixels to mm measured from the plate centre
+
+ x = (plate_centre_x - object_x * x_pixel_size) / 1000.0d0
+ y = (object_y * y_pixel_size - plate_centre_y) / 1000.0d0
+
+ # Compute standard coordinates from x,y and plate model coefficients
+
+ p1 = amd_x(1) *x +
+ amd_x(2) *y +
+ amd_x(3) +
+ amd_x(4) *x**2 +
+ amd_x(5) *x*y +
+ amd_x(6) *y**2
+
+ p2 = amd_x(7) *(x**2+y**2) +
+ amd_x(8) *x**3 +
+ amd_x(9) *x**2*y +
+ amd_x(10) *x*y**2 +
+ amd_x(11) *y**3
+
+ p3 = amd_x(12) *x*(x**2+y**2) +
+ amd_x(13) *x*(x**2+y**2)**2 +
+ amd_x(14) *object_mag +
+ amd_x(15) *object_mag**2 +
+ amd_x(16) *object_mag**3
+
+ p4 = amd_x(17) *object_mag*x +
+ amd_x(18) *object_mag*(x**2+y**2) +
+ amd_x(19) *object_mag*x*(x**2+y**2) +
+ amd_x(20) *object_col
+
+ xi_object = p1 + p2 + p3 + p4
+
+ p1 = amd_y(1) *y +
+ amd_y(2) *x +
+ amd_y(3) +
+ amd_y(4) *y**2 +
+ amd_y(5) *x*y +
+ amd_y(6) *x**2
+
+ p2 = amd_y(7) *(x**2+y**2) +
+ amd_y(8) *y**3 +
+ amd_y(9) *y**2*x +
+ amd_y(10) *y*x**2 +
+ amd_y(11) *x**3
+
+ p3 = amd_y(12) *y*(x**2+y**2) +
+ amd_y(13) *y*(x**2+y**2)**2 +
+ amd_y(14) *object_mag +
+ amd_y(15) *object_mag**2 +
+ amd_y(16) *object_mag**3
+
+ p4 = amd_y(17) *object_mag*y +
+ amd_y(18) *object_mag*(x**2+y**2) +
+ amd_y(19) *object_mag*y*(x**2+y**2) +
+ amd_y(20) *object_col
+
+ eta_object = p1 + p2 + p3 + p4
+
+ call trsteq (plate_centre_ra, plate_centre_dec,
+ xi_object, eta_object, object_ra, object_dec)
+
+end
diff --git a/vo/votools/gasplib/ccgsxy.x b/vo/votools/gasplib/ccgsxy.x
new file mode 100644
index 00000000..588dacef
--- /dev/null
+++ b/vo/votools/gasplib/ccgsxy.x
@@ -0,0 +1,200 @@
+define MAX_ITERATIONS 20
+# CCGSXY -- Routine for computing X,Y pixel position from a given RA and Dec
+# on a GSSS plate.
+
+procedure ccgsxy (plate_centre_ra,
+ plate_centre_dec,
+ plate_centre_x,
+ plate_centre_y,
+ x_pixel_size,
+ y_pixel_size,
+ plate_scale,
+ amd_x,
+ amd_y,
+ object_x,
+ object_y,
+ object_mag,
+ object_col,
+ object_ra,
+ object_dec)
+
+
+double plate_centre_ra #Plate Right Ascension (radians)
+double plate_centre_dec #Plate Declination (radians)
+double plate_centre_x #Position used in soln.(microns)
+double plate_centre_y # "
+double x_pixel_size #Scan pixel size (microns)
+double y_pixel_size # "
+double plate_scale #Plate scale (arcsec/mm)
+double amd_x[20] #Plate model coefficients
+double amd_y[20] # "
+double object_x #Pixel position for object
+double object_y # "
+double object_mag #Object magnitude
+double object_col #Colour
+double object_ra #Object RA (radians)
+double object_dec # " Dec
+double xi_object #Standard coords (arcsec)
+double eta_object # "
+
+double x #Position from centre (mm)
+double y # "
+double delta_x #correction to x
+double delta_y #correction to y
+int n_iterations #no.iterations used
+
+double f #Function for x model
+double g #Function for y model
+double fx #Deriv. x model wrt x
+double gx #Deriv. y model wrt x
+double fy #Deriv. x model wrt y
+double gy #deriv. y model wrt y
+
+int ierr #Stats flag
+
+begin
+
+ #
+ # Convert RA and Dec to standard coordinates
+ #
+ call treqst (plate_centre_ra, plate_centre_dec,
+ object_ra, object_dec, xi_object, eta_object)
+
+ # Iterate by Newtons method
+ n_iterations = 0
+ ierr = 0
+
+ # Get initial estimate of x,y
+ x = xi_object / plate_scale
+ y = eta_object / plate_scale
+
+ while (ierr == 0) {
+ n_iterations=n_iterations+1
+
+ #
+ # X plate model
+ #
+ f = amd_x(1)*x +
+ amd_x(2)*y +
+ amd_x(3) +
+ amd_x(4)*x*x +
+ amd_x(5)*x*y +
+ amd_x(6)*y*y +
+ amd_x(7)*(x*x+y*y) +
+ amd_x(8)*x*x*x +
+ amd_x(9)*x*x*y +
+ amd_x(10)*x*y*y +
+ amd_x(11)*y*y*y +
+ amd_x(12)*x*(x*x+y*y) +
+ amd_x(13)*x*(x*x+y*y)**2 +
+ amd_x(14)*object_mag +
+ amd_x(15)*object_mag**2 +
+ amd_x(16)*object_mag**3 +
+ amd_x(17)*object_mag*x +
+ amd_x(18)*object_mag*(x*x+y*y) +
+ amd_x(19)*object_mag*x*(x*x+y*y) +
+ amd_x(20)*object_col -
+ xi_object
+ #
+ # Derivative of X model wrt x
+ #
+ fx = amd_x(1) +
+ amd_x(4)*2.0*x +
+ amd_x(5)*y +
+ amd_x(7)*2.0*x +
+ amd_x(8)*3.0*x*x +
+ amd_x(9)*2.0*x*y +
+ amd_x(10)*y*y +
+ amd_x(12)*(3.0*x*x+y*y) +
+ amd_x(13)*(5.0*x**4+6.0*x*x*y*y+y**4) +
+ amd_x(17)*object_mag +
+ amd_x(18)*object_mag*2.0*x +
+ amd_x(19)*object_mag*(3.0*x*x+y*y)
+ #
+ # Derivative of X model wrt y
+ #
+ fy = amd_x(2) +
+ amd_x(5)*x +
+ amd_x(6)*2.0*y +
+ amd_x(7)*2.0*y +
+ amd_x(9)*x*x +
+ amd_x(10)*x*2.0*y +
+ amd_x(11)*3.0*y*y +
+ amd_x(12)*2.0*x*y +
+ amd_x(13)*4.0*x*y*(x*x+y*y) +
+ amd_x(18)*object_mag*2.0*y +
+ amd_x(19)*object_mag*2.0*x*y
+ #
+ # Y plate model
+ #
+ g = amd_y(1)*y +
+ amd_y(2)*x +
+ amd_y(3) +
+ amd_y(4)*y*y +
+ amd_y(5)*y*x +
+ amd_y(6)*x*x +
+ amd_y(7)*(x*x+y*y) +
+ amd_y(8)*y*y*y +
+ amd_y(9)*y*y*x +
+ amd_y(10)*y*x*x +
+ amd_y(11)*x*x*x +
+ amd_y(12)*y*(x*x+y*y) +
+ amd_y(13)*y*(x*x+y*y)**2 +
+ amd_y(14)*object_mag +
+ amd_y(15)*object_mag**2 +
+ amd_y(16)*object_mag**3 +
+ amd_y(17)*object_mag*y +
+ amd_y(18)*object_mag*(x*x+y*y) +
+ amd_y(19)*object_mag*y*(x*x+y*y) +
+ amd_y(20)*object_col -
+ eta_object
+ #
+ # Derivative of Y model wrt x
+ #
+ gx = amd_y(2) +
+ amd_y(5)*y +
+ amd_y(6)*2.0*x +
+ amd_y(7)*2.0*x +
+ amd_y(9)*y*y +
+ amd_y(10)*y*2.0*x +
+ amd_y(11)*3.0*x*x +
+ amd_y(12)*2.0*x*y +
+ amd_y(13)*4.0*x*y*(x*x+y*y) +
+ amd_y(18)*object_mag*2.0*x +
+ amd_y(19)*object_mag*y*2.0*x
+ #
+ # Derivative of Y model wrt y
+ #
+ gy = amd_y(1) +
+ amd_y(4)*2.0*y +
+ amd_y(5)*x +
+ amd_y(7)*2.0*y +
+ amd_y(8)*3.0*y*y +
+ amd_y(9)*2.0*y*x +
+ amd_y(10)*x*x +
+ amd_y(12)*3.0*y*y +
+ amd_y(13)*(5.0*y**4+6.0*x*x*y*y+x**4) +
+ amd_y(17)*object_mag +
+ amd_y(18)*object_mag*2.0*y +
+ amd_y(19)*object_mag*(x*x+3.0*y*y)
+
+ delta_x = (-f * gy + g * fy) / (fx * gy - fy * gx)
+ delta_y = (-g * fx + f * gx) / (fx * gy - fy * gx)
+ x = x + delta_x
+ y = y + delta_y
+
+ if (dmax1 (dabs(delta_x), dabs(delta_y),
+ dabs(f), dabs(g)) < 1.e-5)
+ ierr=1
+
+ if (n_iterations == MAX_ITERATIONS)
+ ierr=2
+
+ }
+
+ # Convert x,y from mm about plate centre to pixels
+
+ object_x = (plate_centre_x - x*1000.0d0) / x_pixel_size
+ object_y = (plate_centre_y + y*1000.0d0) / y_pixel_size
+
+end
diff --git a/vo/votools/gasplib/dcmpsv.f b/vo/votools/gasplib/dcmpsv.f
new file mode 100644
index 00000000..1e0c9bac
--- /dev/null
+++ b/vo/votools/gasplib/dcmpsv.f
@@ -0,0 +1,230 @@
+ subroutine dcmpsv (a,m,n,w,v)
+ parameter (nmax=1000)
+ real*8 a(m,n),w(n),v(n,n),rv1(nmax)
+ real*8 c, g, f, h, s, y, z, x, scale, anorm
+
+ g=0.0
+ scale=0.0
+ anorm=0.0
+ do i=1,n
+ l=i+1
+ rv1(i)=scale*g
+ g=0.0
+ s=0.0
+ scale=0.0
+ if (i.le.m) then
+ do k=i,m
+ scale=scale+dabs(a(k,i))
+ enddo
+ if (scale.ne.0.0) then
+ do k=i,m
+ a(k,i)=a(k,i)/scale
+ s=s+a(k,i)*a(k,i)
+ enddo
+ f=a(i,i)
+ g=-dsign(dsqrt(s),f)
+ h=f*g-s
+ a(i,i)=f-g
+ if (i.ne.n) then
+ do j=l,n
+ s=0.0
+ do k=i,m
+ s=s+a(k,i)*a(k,j)
+ enddo
+ f=s/h
+ do k=i,m
+ a(k,j)=a(k,j)+f*a(k,i)
+ enddo
+ enddo
+ endif
+ do k= i,m
+ a(k,i)=scale*a(k,i)
+ enddo
+ endif
+ endif
+ w(i)=scale *g
+ g=0.0
+ s=0.0
+ scale=0.0
+ if ((i.le.m).and.(i.ne.n)) then
+ do k=l,n
+ scale=scale+dabs(a(i,k))
+ enddo
+ if (scale.ne.0.0) then
+ do k=l,n
+ a(i,k)=a(i,k)/scale
+ s=s+a(i,k)*a(i,k)
+ enddo
+ f=a(i,l)
+ g=-dsign(dsqrt(s),f)
+ h=f*g-s
+ a(i,l)=f-g
+ do k=l,n
+ rv1(k)=a(i,k)/h
+ enddo
+ if (i.ne.m) then
+ do j=l,m
+ s=0.0
+ do k=l,n
+ s=s+a(j,k)*a(i,k)
+ enddo
+ do k=l,n
+ a(j,k)=a(j,k)+s*rv1(k)
+ enddo
+ enddo
+ endif
+ do k=l,n
+ a(i,k)=scale*a(i,k)
+ enddo
+ endif
+ endif
+ anorm=dmax1(anorm,(dabs(w(i))+dabs(rv1(i))))
+ enddo
+ do i=n,1,-1
+ if (i.lt.n) then
+ if (g.ne.0.0) then
+ do j=l,n
+ v(j,i)=(a(i,j)/a(i,l))/g
+ enddo
+ do j=l,n
+ s=0.0
+ do k=l,n
+ s=s+a(i,k)*v(k,j)
+ enddo
+ do k=l,n
+ v(k,j)=v(k,j)+s*v(k,i)
+ enddo
+ enddo
+ endif
+ do j=l,n
+ v(i,j)=0.0
+ v(j,i)=0.0
+ enddo
+ endif
+ v(i,i)=1.0
+ g=rv1(i)
+ l=i
+ enddo
+ do i=n,1,-1
+ l=i+1
+ g=w(i)
+ if (i.lt.n) then
+ do j=l,n
+ a(i,j)=0.0
+ enddo
+ endif
+ if (g.ne.0.0) then
+ g=1.0/g
+ if (i.ne.n) then
+ do j=l,n
+ s=0.0
+ do k=l,m
+ s=s+a(k,i)*a(k,j)
+ enddo
+ f=(s/a(i,i))*g
+ do k=i,m
+ a(k,j)=a(k,j)+f*a(k,i)
+ enddo
+ enddo
+ endif
+ do j=i,m
+ a(j,i)=a(j,i)*g
+ enddo
+ else
+ do j= i,m
+ a(j,i)=0.0
+ enddo
+ endif
+ a(i,i)=a(i,i)+1.0
+ enddo
+ do k=n,1,-1
+ do its=1,30
+ do l=k,1,-1
+ nm=l-1
+ if ((dabs(rv1(l))+anorm).eq.anorm) go to 2
+ if ((dabs(w(nm))+anorm).eq.anorm) go to 1
+ enddo
+1 c=0.0
+ s=1.0
+ do i=l,k
+ f=s*rv1(i)
+ if ((dabs(f)+anorm).ne.anorm) then
+ g=w(i)
+ h=dsqrt(f*f+g*g)
+ w(i)=h
+ h=1.0/h
+ c= (g*h)
+ s=-(f*h)
+ do j=1,m
+ y=a(j,nm)
+ z=a(j,i)
+ a(j,nm)=(y*c)+(z*s)
+ a(j,i)=-(y*s)+(z*c)
+ enddo
+ endif
+ enddo
+2 z=w(k)
+ if (l.eq.k) then
+ if (z.lt.0.0) then
+ w(k)=-z
+ do j=1,n
+ v(j,k)=-v(j,k)
+ enddo
+ endif
+ go to 3
+ endif
+ if (its.eq.30) pause 'nO CONVERGENCE IN 30 ITERATIONS'
+ x=w(l)
+ nm=k-1
+ y=w(nm)
+ g=rv1(nm)
+ h=rv1(k)
+ f=((y-z)*(y+z)+(g-h)*(g+h))/(2.0*h*y)
+ g=dsqrt(f*f+1.0)
+ f=((x-z)*(x+z)+h*((y/(f+dsign(g,f)))-h))/x
+ c=1.0
+ s=1.0
+ do j=l,nm
+ i=j+1
+ g=rv1(i)
+ y=w(i)
+ h=s*g
+ g=c*g
+ z=dsqrt(f*f+h*h)
+ rv1(j)=z
+ c=f/z
+ s=h/z
+ f= (x*c)+(g*s)
+ g=-(x*s)+(g*c)
+ h=y*s
+ y=y*c
+ do nm=1,n
+ x=v(nm,j)
+ z=v(nm,i)
+ v(nm,j)= (x*c)+(z*s)
+ v(nm,i)=-(x*s)+(z*c)
+ enddo
+ z=sqrt(f*f+h*h)
+ w(j)=z
+ if (z.ne.0.0) then
+ z=1.0/z
+ c=f*z
+ s=h*z
+ endif
+ f= (c*g)+(s*y)
+ x=-(s*g)+(c*y)
+ do nm=1,m
+ y=a(nm,j)
+ z=a(nm,i)
+ a(nm,j)= (y*c)+(z*s)
+ a(nm,i)=-(y*s)+(z*c)
+ enddo
+ enddo
+ rv1(l)=0.0
+ rv1(k)=f
+ w(k)=x
+ enddo
+3 continue
+ enddo
+ return
+ end
diff --git a/vo/votools/gasplib/eqtopix.x b/vo/votools/gasplib/eqtopix.x
new file mode 100644
index 00000000..569f8699
--- /dev/null
+++ b/vo/votools/gasplib/eqtopix.x
@@ -0,0 +1,43 @@
+include <math.h>
+define SZ_CDMTX 4
+
+# EQTOPIX -- procedure to obtain pixel coordinates from the equatorial
+# ones, giving the center position and scale of the frame.
+
+procedure eqtopix (plt_ra_cen, plt_dec_cen, plt_x_cen, plt_y_cen,
+ cdmtx, ra, dec, x, y)
+
+double plt_ra_cen # Plate centre (radians)
+double plt_dec_cen # " "
+double plt_x_cen # Plate center in x (pixels)
+double plt_y_cen # Plate center in y (pixels)
+double cdmtx[SZ_CDMTX] # CD Matrix (cd11, cd12, cd21, cd22)
+double ra # Objects RA position (radians)
+double dec # Objects DEC position (radians)
+double x # Position from centre (pixels)
+double y # "
+
+double xi # Standard coordinate (degrees)
+double eta # "
+double det, cd11, cd12, cd21, cd22
+double xi_arcs, eta_arcs # Standard coord. in arc seconds.
+
+begin
+
+ cd11 = cdmtx[1]
+ cd12 = cdmtx[2]
+ cd21 = cdmtx[3]
+ cd22 = cdmtx[4]
+
+ det = (cd11*cd22 - cd21*cd12)
+ call treqst (plt_ra_cen, plt_dec_cen, ra, dec,
+ xi_arcs, eta_arcs)
+ xi = xi_arcs/3600.0 # To degrees
+ eta = eta_arcs/3600.0 # To degrees
+ # Calculate x[i] and y[i] by solving the linear equations:
+ # xi = cd11(X-Xo) + cd12(Y-Yo)
+ # eta = cd21(X-Xo) + cd22(Y-Yo)
+
+ x = (cd22*xi - cd12*eta)/det + plt_x_cen
+ y = (cd11*eta - cd21*xi)/det + plt_y_cen
+end
diff --git a/vo/votools/gasplib/fitsvd.f b/vo/votools/gasplib/fitsvd.f
new file mode 100644
index 00000000..a4bb4350
--- /dev/null
+++ b/vo/votools/gasplib/fitsvd.f
@@ -0,0 +1,35 @@
+ subroutine fitsvd (x, y, wg, npts, coef, nterms,
+ * u, v, w, chisq)
+ parameter(nmax=1000,mmax=50,tol=1.d-14)
+
+ real wg(npts)
+ real*8 x(npts,nterms), y(npts), coef(nterms), v(nterms,nterms),
+ * u(npts,nterms), w(nterms), b(nmax)
+ real*8 wmax, thresh, chisq, sum
+
+ do i=1,npts
+ do j=1,nterms
+ u(i,j)=x(i,j)*wg(i)
+ enddo
+ b(i)=y(i)*wg(i)
+ enddo
+ call dcmpsv (u,npts,nterms,w,v)
+ wmax=0.
+ do j=1,nterms
+ if(w(j).gt.wmax) wmax=w(j)
+ enddo
+ thresh=tol*wmax
+ do j=1,nterms
+ if(w(j).lt.thresh) w(j)=0.
+ enddo
+ call ksbsvd (u, w, v, npts, nterms, b, coef)
+ chisq=0.
+ do i=1,npts
+ sum=0.
+ do j=1,nterms
+ sum=sum+coef(j)*x(i,j)
+ enddo
+ chisq=chisq+((y(i)-sum)*wg(i))**2
+ enddo
+ return
+ end
diff --git a/vo/votools/gasplib/gsctab.x b/vo/votools/gasplib/gsctab.x
new file mode 100644
index 00000000..0f48f8dd
--- /dev/null
+++ b/vo/votools/gasplib/gsctab.x
@@ -0,0 +1,66 @@
+include <tbset.h>
+
+define NUM_COLS 5 # Number of table columns
+
+procedure gsctab (tp, cd, nrows)
+
+pointer tp # GSC table descriptor
+pointer cd[NUM_COLS] # Table column descriptors
+int nrows # Number of rows in table
+
+pointer sp, tname
+char colname[SZ_COLNAME,NUM_COLS]
+pointer null
+
+pointer tbtopn()
+int tbpsta()
+
+begin
+ call smark (sp)
+ call salloc (tname, SZ_FNAME, TY_CHAR)
+ call clgstr ("gsctable", Memc[tname], SZ_FNAME)
+
+ # Open the GSC table
+ tp = tbtopn (Memc[tname], READ_WRITE, 0)
+
+ # Number of rows (coordinates) in the table
+ nrows = tbpsta (tp, TBL_NROWS)
+
+ call strcpy ("RA_DEG", colname[1,1], SZ_COLNAME)
+ call strcpy ("DEC_DEG", colname[1,2], SZ_COLNAME)
+ call strcpy ("x_pix", colname[1,3], SZ_COLNAME)
+ call strcpy ("y_pix", colname[1,4], SZ_COLNAME)
+ call strcpy ("valid", colname[1,5], SZ_COLNAME)
+
+ # Find the table columns
+ call tbcfnd (tp, colname, cd, NUM_COLS)
+
+ if (cd[1] <= 0)
+ call error (0, "No R.A. column found in table")
+
+ if (cd[2] <= 0)
+ call error (0, "No Dec. column found in table")
+
+ if (cd[3] <= 0)
+ # Create the output (pixel coordinate) column
+ call tbcdef (tp, cd[3], colname[1,3], "pixels",
+ "%6.1f", TY_REAL, 0, 1)
+
+ if (cd[4] <= 0)
+ # Create the output (pixel coordinate) column
+ call tbcdef (tp, cd[4], colname[1,4], "pixels",
+ "%6.1f", TY_REAL, 0, 1)
+
+ if (cd[5] <= 0) {
+ # Create the output (valid flag) column
+ call tbcdef (tp, cd[5], colname[1,5], EOS,
+ "%1b", TY_INT, 0, 1)
+
+ # Initialize to false
+ call salloc (null, nrows, TY_INT)
+ call amovki (NO, Memi[null], nrows)
+ call tbcpti (tp, cd[5], Memi[null], 1, nrows)
+ }
+
+ call sfree (sp)
+end
diff --git a/vo/votools/gasplib/ksbsvd.f b/vo/votools/gasplib/ksbsvd.f
new file mode 100644
index 00000000..d93609e9
--- /dev/null
+++ b/vo/votools/gasplib/ksbsvd.f
@@ -0,0 +1,24 @@
+ subroutine ksbsvd (u,w,v,m,n,b,x)
+ parameter (nmax=1000)
+ real*8 u(m,n),w(n),v(n,n),b(m),x(n),tmp(nmax)
+ real*8 s
+
+ do j=1,n
+ s=0.
+ if(w(j).ne.0.)then
+ do i=1,m
+ s=s+u(i,j)*b(i)
+ enddo
+ s=s/w(j)
+ endif
+ tmp(j)=s
+ enddo
+ do j=1,n
+ s=0.
+ do jj=1,n
+ s=s+v(j,jj)*tmp(jj)
+ enddo
+ x(j)=s
+ enddo
+ return
+ end
diff --git a/vo/votools/gasplib/mkpkg b/vo/votools/gasplib/mkpkg
new file mode 100644
index 00000000..0da7b00c
--- /dev/null
+++ b/vo/votools/gasplib/mkpkg
@@ -0,0 +1,22 @@
+$checkout libpkg.a ../
+$update libpkg.a
+$checkin libpkg.a ../
+$exit
+
+libpkg.a:
+ ccgseq.x
+ ccgsxy.x
+ eqtopix.x <math.h>
+ gsctab.x <tbset.h>
+ pixtoeq.x <math.h>
+ rdaslf.x
+ rdxy.x
+ trsteq.x <math.h>
+ treqst.x
+ calcds.x <math.h>
+ regren.f
+ fitsvd.f
+ dcmpsv.f
+ ksbsvd.f
+ varsvd.f
+ ;
diff --git a/vo/votools/gasplib/pixtoeq.x b/vo/votools/gasplib/pixtoeq.x
new file mode 100644
index 00000000..123403f0
--- /dev/null
+++ b/vo/votools/gasplib/pixtoeq.x
@@ -0,0 +1,37 @@
+include <math.h>
+define SZ_CDMTX 4
+
+# PHYSTOPIX -- procedure to obtain pixel coordinates from the equatorial
+# ones, giving the center position and scale of the frame.
+
+procedure pixtoeq (plt_ra_cen, plt_dec_cen, plt_x_cen, plt_y_cen,
+ cdmtx, x, y, ra, dec)
+
+double plt_ra_cen # Plate centre (radians)
+double plt_dec_cen # " "
+double plt_x_cen # Plate center in x (pixels)
+double plt_y_cen # Plate center in y (pixels)
+double cdmtx[SZ_CDMTX] # CD Matrix (cd11, cd12, cd21, cd22)
+double ra # Objects RA position (radians)
+double dec # Objects DEC position (radians)
+double x # Position from centre (pixels)
+double y # "
+
+double xi # Standard coordinate (degrees)
+double eta # "
+double cd11, cd12, cd21, cd22
+double xi_arcs, eta_arcs # Standard coord. in arc seconds.
+
+begin
+
+ cd11 = cdmtx[1]
+ cd12 = cdmtx[2]
+ cd21 = cdmtx[3]
+ cd22 = cdmtx[4]
+
+ xi = cd11*(x-plt_x_cen) + cd12*(y-plt_y_cen)
+ eta = cd21*(x-plt_x_cen) + cd22*(y-plt_y_cen)
+ xi_arcs = xi*3600.0 # to arcs
+ eta_arcs = eta*3600.0
+ call trsteq (plt_ra_cen, plt_dec_cen, xi_arcs, eta_arcs, ra, dec)
+end
diff --git a/vo/votools/gasplib/rdaslf.x b/vo/votools/gasplib/rdaslf.x
new file mode 100644
index 00000000..3cd57c0b
--- /dev/null
+++ b/vo/votools/gasplib/rdaslf.x
@@ -0,0 +1,131 @@
+# code: Nelson Zarate January 89
+
+define SZ_KEYWORD 8
+define NTERMS_MODEL 20
+
+# RD_ASLF -- Read astrometry solution parameters obtained with program
+# 'pltsol'
+
+procedure rd_aslf (im, fd, namd, icd, crpix1, crpix2, crval1,
+ crval2, x_pixel_size, y_pixel_size, plate_scale,
+ namdx, namdy)
+
+pointer im # image file descriptor
+pointer fd # Ascii file descriptor
+bool namd # Are new coefficient from pltsol in header?
+bool icd # Use CD values?
+double crpix1, crpix2 # Reference pixel
+double crval1, crval2 # Reference equatorial position (degrees)
+double x_pixel_size # Y pixel size (microns)
+double y_pixel_size # X pixel size (microns)
+double plate_scale # [arc_sec/mm]
+double namdx[NTERMS_MODEL] # New coeff in x direction
+double namdy[NTERMS_MODEL] # New coeff in y direction
+
+char buf[SZ_KEYWORD]
+char outstr[SZ_LINE]
+int nch, fscan(), getline(), i, j, k, ic, ctoi(), ip, ii
+int strncmp(), ctowrd(), ctod(), idb_find()
+double imgetd()
+pointer pp, rp
+
+begin
+
+ # Clear the coefficient arrays.
+ call aclrd (namdx, NTERMS_MODEL)
+ call aclrd (namdy, NTERMS_MODEL)
+
+ if (im == -1) {
+ nch = getline (fd, outstr) # Title line
+ nch = getline (fd, outstr) # Blank line
+ nch = fscan (fd)
+ call gargwrd (buf, SZ_KEYWORD)
+ call gargd (crpix1)
+ call gargstr (outstr, SZ_LINE)
+ nch = fscan (fd)
+ call gargwrd (buf, SZ_KEYWORD)
+ call gargd (crpix2)
+ call gargstr (outstr, SZ_LINE)
+ nch = fscan (fd)
+ call gargwrd (buf, SZ_KEYWORD)
+ call gargd (crval1)
+ call gargstr (outstr, SZ_LINE)
+ nch = fscan (fd)
+ call gargwrd (buf, SZ_KEYWORD)
+ call gargd (crval2)
+ call gargstr (outstr, SZ_LINE)
+ nch = fscan (fd)
+ call gargwrd (buf, SZ_KEYWORD)
+ call gargd (x_pixel_size)
+ call gargstr (outstr, SZ_LINE)
+ nch = fscan (fd)
+ call gargwrd (buf, SZ_KEYWORD)
+ call gargd (y_pixel_size)
+ call gargstr (outstr, SZ_LINE)
+ nch = fscan (fd)
+ call gargwrd (buf, SZ_KEYWORD)
+ call gargd (plate_scale)
+ call gargstr (outstr, SZ_LINE)
+
+ do i = 1, NTERMS_MODEL { # read XCOEFF
+ k = 7 # starting character number for digits
+ nch = fscan (fd)
+ call gargwrd (buf, SZ_KEYWORD)
+ nch = ctoi (buf, k, ic)
+ if (strncmp (buf, "YCOEFF", 6) == 0) {
+ call gargd (namdy[ic])
+ break
+ }
+ call gargd (namdx[ic])
+ call gargstr (outstr, SZ_LINE)
+ }
+ do j = 2, NTERMS_MODEL {
+ k = 7 # starting character number for digits
+ nch = fscan (fd)
+ if (nch == EOF)
+ break
+ call gargwrd (buf, SZ_KEYWORD)
+ nch = ctoi (buf, k, ic)
+ # in case there is more than one set of coeeficients, take only
+ # the first one.
+ if (strncmp (buf, "XCOEFF", 6) == 0)
+ break
+ call gargd (namdy[ic])
+ call gargstr (outstr, SZ_LINE)
+ }
+ } else {
+ crpix1 = imgetd (im, "CRPIX1")
+ crpix2 = imgetd (im, "CRPIX2")
+ crval1 = imgetd (im, "CRVAL1")
+ crval2 = imgetd (im, "CRVAL2")
+ if (namd) {
+ x_pixel_size = imgetd (im, "XPIXELSZ")
+ y_pixel_size = imgetd (im, "YPIXELSZ")
+ plate_scale = imgetd (im, "PLTSCALE")
+ }
+
+ # Are new coefficients from 'pltsol' task in header
+ if (namd) {
+ do k = 1, NTERMS_MODEL {
+ namdx[k] = 0.0
+ namdy[k] = 0.0
+ }
+ call strcpy ("NAMDX?", buf, SZ_KEYWORD)
+ if (idb_find (im, buf, rp) == 0)
+ call error (13,"New solution coefficients (NAMDX*) not found")
+ for (pp=rp; Memc[pp] != EOS; pp=pp+81) {
+ k = 6
+ ii = 11 # starting char number of keyword value
+ ip = 1
+ # get keyword
+ nch = ctowrd (Memc[pp], ip, buf, SZ_KEYWORD)
+ # get keyword sequence
+ nch = ctoi (buf, k, ic)
+ if (strncmp (buf, "NAMDX", 5) == 0)
+ nch = ctod (Memc[pp], ii, namdx[ic])
+ else if (strncmp (buf, "NAMDY", 5) == 0)
+ nch = ctod (Memc[pp], ii, namdy[ic])
+ }
+ }
+ }
+end
diff --git a/vo/votools/gasplib/rdxy.x b/vo/votools/gasplib/rdxy.x
new file mode 100644
index 00000000..360f9cd0
--- /dev/null
+++ b/vo/votools/gasplib/rdxy.x
@@ -0,0 +1,43 @@
+include <mach.h>
+
+# RDXY -- procedure to get (x,y) pixel values from a line.
+# The line can have any number of columns but only up to 162
+# characters per line.
+#
+procedure rdxy (line, icol, x, y)
+
+char line[SZ_LINE] # input line with (x,y) in it
+int icol[2] # X, Y column numbers within the line
+double x # X pixel value
+double y # Y pixel value
+
+pointer sp, pp
+int i, ip, ic, ctowrd(), ctod()
+int maxcol, nchar
+
+begin
+
+ # find the right most column to read from buffer
+ maxcol = max (icol[1], icol[2])
+
+ call smark (sp)
+ call salloc (pp, maxcol*MAX_DIGITS, TY_CHAR)
+
+ ip = 1
+ ic = pp
+ do i = 1, maxcol {
+ nchar = ctowrd (line, ip, Memc[ic], MAX_DIGITS)
+ # store word in equal length array
+ call amovkc (" ", Memc[ic+nchar], MAX_DIGITS-nchar)
+ Memc[ic+MAX_DIGITS] = EOS
+ ic = ic + MAX_DIGITS+1
+ }
+
+ # get the output parameters
+
+ nchar = ctod (Memc[pp], (icol(1)-1)*(MAX_DIGITS+1)+1, x)
+ nchar = ctod (Memc[pp], (icol(2)-1)*(MAX_DIGITS+1)+1, y)
+
+ call sfree (sp)
+
+end
diff --git a/vo/votools/gasplib/regren.f b/vo/votools/gasplib/regren.f
new file mode 100644
index 00000000..7433b15f
--- /dev/null
+++ b/vo/votools/gasplib/regren.f
@@ -0,0 +1,309 @@
+c The following is the IDL version of the regression routine by Bevington
+c Some modification have been made to the book version in regard to the input
+c X array and the data type of some of the arrays.
+
+c FUNCTION REGRESS,X,Y,W,YFIT,A0,SIGMA,FTEST,R,RMUL,CHISQ
+c;
+c;+
+c; NAME:
+c; REGRESS
+c; PURPOSE:
+c; Multiple linear regression fit.
+c; Fit the function:
+c; Y(i) = A0 + A(0)*X(0,i) + A(1)*X(1,i) + ... +
+c; A(Nterms-1)*X(Nterms-1,i)
+c; CATEGORY:
+c; G2 - Correlation and regression analysis.
+c; CALLING SEQUENCE:
+c; Coeff = REGRESS(X,Y,W,YFIT,A0,SIGMA,FTEST,RMUL,CHISQ)
+c; INPUTS:
+c; X = array of independent variable data. X must
+c; be dimensioned (Nterms, Npoints) where there are Nterms
+c; coefficients to be found (independent variables) and
+c; Npoints of samples.
+c; Y = vector of dependent variable points, must
+c; have Npoints elements.
+c; W = vector of weights for each equation, must
+c; be a Npoints elements vector. For no
+c; weighting, set w(i) = 1., for instrumental weighting
+c; w(i) = 1/standard_deviation(Y(i)), for statistical
+c; weighting w(i) = 1./Y(i)
+c;
+c; OUTPUTS:
+c; Function result = coefficients = vector of
+c; Nterms elements. Returned as a column
+c; vector.
+c;
+c; OPTIONAL OUTPUT PARAMETERS:
+c; Yfit = array of calculated values of Y, Npoints
+c; elements.
+c; A0 = Constant term.
+c; Sigma = Vector of standard deviations for
+c; coefficients.
+c; Ftest = value of F for test of fit.
+c; Rmul = multiple linear correlation coefficient.
+c; R = Vector of linear correlation coefficient.
+c; Chisq = Reduced weighted chi squared.
+c; COMMON BLOCKS:
+c; None.
+c; SIDE EFFECTS:
+c; None.
+c; RESTRICTIONS:
+c; None.
+c; PROCEDURE:
+c; Adapted from the program REGRES, Page 172,
+c; Bevington, Data Reduction and Error Analysis for the
+c; Physical Sciences, 1969.
+c;
+c; MODIFICATION HISTORY:
+c; Written, DMS, RSI, September, 1982.
+c;-
+c;
+c SY = SIZE(Y) ;GET DIMENSIONS OF X AND Y.
+c SX = SIZE(X)
+c IF (N_ELEMENTS(W) NE SY(1)) OR (SX(0) NE 2) OR (SY(1) NE SX(2)) THEN BEGIN
+c PRINT,'REGRESS - Incompatible arrays'
+c RETURN,0
+c ENDIF
+c;
+c NTERM = SX(1) ;# OF TERMS
+c NPTS = SY(1) ;# OF OBSERVATIONS
+c ;
+c SW = TOTAL(W) ;SUM OF WEIGHTS
+c YMEAN = TOTAL(Y*W)/SW ;Y MEAN
+c XMEAN = (X * (REPLICATE(1.,NTERM) # W)) # REPLICATE(1./SW,NPTS)
+c WMEAN = SW/NPTS
+c WW = W/WMEAN
+c ;
+c NFREE = NPTS-1 ;DEGS OF FREEDOM
+c SIGMAY = SQRT(TOTAL(WW * (Y-YMEAN)^2)/NFREE) ;W*(Y(I)-YMEAN)
+c XX = X- XMEAN # REPLICATE(1.,NPTS) ;X(J,I) - XMEAN(I)
+c WX = REPLICATE(1.,NTERM) # WW * XX ;W(I)*(X(J,I)-XMEAN(I))
+c SIGMAX = SQRT( XX*WX # REPLICATE(1./NFREE,NPTS)) ;W(I)*(X(J,I)-XM)*(X(K,I)-XM)
+c R = WX #(Y - YMEAN) / (SIGMAX * SIGMAY * NFREE)
+c ARRAY = INVERT((WX # TRANSPOSE(XX))/(NFREE * SIGMAX #SIGMAX))
+c A = (R # ARRAY)*(SIGMAY/SIGMAX) ;GET COEFFICIENTS
+c YFIT = A # X ;COMPUTE FIT
+c A0 = YMEAN - TOTAL(A*XMEAN) ;CONSTANT TERM
+c YFIT = YFIT + A0 ;ADD IT IN
+c FREEN = NPTS-NTERM-1 > 1 ;DEGS OF FREEDOM, AT LEAST 1.
+c CHISQ = TOTAL(WW*(Y-YFIT)^2)*WMEAN/FREEN ;WEIGHTED CHI SQUARED
+c SIGMA = SQRT(ARRAY(INDGEN(NTERM)*(NTERM+1))/WMEAN/(NFREE*SIGMAX^2)) ;ERROR TERM
+c RMUL = TOTAL(A*R*SIGMAX/SIGMAY) ;MULTIPLE LIN REG COEFF
+c IF RMUL LT 1. THEN FTEST = RMUL/NTERM / ((1.-RMUL)/FREEN) ELSE FTEST=1.E6
+c RMUL = SQRT(RMUL)
+c RETURN,A
+c END
+
+ subroutine regren (x, ndim1, ndim2, y, weight, npts, nterms, yfit,
+ *a0, a, sigmaa, chisqr)
+ double precision sum, ymean, sigma, chisq
+ integer npts, nterms
+ double precision x(ndim1,ndim2),y(1),yfit(1)
+ double precision r(20), array(20,20), sigmax(20), xmean(20)
+ double precision chisqr, a0, a(1)
+ real weight(1), sigmaa(1)
+ real sigma0, ftest, freen, free1, rmul
+ real fnpts, det, varnce, wmean, freej
+ integer i, j, k
+c
+c initialize sums and arrays
+c
+11 sum=0.
+ ymean=0.
+ sigma=0.
+ chisq=0.
+ rmul=0.
+ do 17 i=1,npts
+17 yfit(i)=0.
+21 do 28 j=1,nterms
+ xmean(j)=0.
+ sigmax(j)=0.
+ r(j)=0.
+ a(j)=0.
+ sigmaa(j)=0.
+ do 28 k=1,nterms
+28 array(j,k)=0.
+c
+c accumulate weighted sums
+c
+30 do 50 i=1,npts
+ sum=sum+weight(i)
+ ymean=ymean+weight(i)*y(i)
+ do 44 j=1,nterms
+44 xmean(j)=xmean(j)+weight(i)*x(j,i)
+50 continue
+51 ymean=ymean/sum
+ do 53 j=1,nterms
+53 xmean(j)=xmean(j)/sum
+ fnpts=npts
+ wmean=sum/fnpts
+ do 57 i=1,npts
+57 weight(i)=weight(i)/wmean
+c
+c accumulate matrices r and array
+c
+61 do 67 i=1,npts
+ sigma=sigma+weight(i)*(y(i)-ymean)**2
+ do 67 j=1,nterms
+ sigmax(j)=sigmax(j)+weight(i)*(x(j,i)-xmean(j))**2
+ r(j)=r(j)+weight(i)*(x(j,i)-xmean(j))*(y(i)-ymean)
+ do 67 k=1,j
+67 array(j,k)=array(j,k)+weight(i)*(x(j,i)-xmean(j))*
+ *(x(k,i)-xmean(k))
+71 free1=npts-1
+72 sigma=dsqrt(sigma/free1)
+ do 78 j=1,nterms
+74 sigmax(j)=dsqrt(sigmax(j)/free1)
+ r(j)=r(j)/(free1*sigmax(j)*sigma)
+ do 78 k=1,j
+ array(j,k)=array(j,k)/(free1*sigmax(j)*sigmax(k))
+78 array(k,j)=array(j,k)
+c
+c invert symmetric matrix
+c
+81 call minv20 (array,nterms,det)
+ if (det) 101,91,101
+91 a0=0.
+ sigma0=0.
+ rmul=0.
+ chisqr=0.
+ ftest=0.
+ goto 150
+c
+c calculate coefficients, fit, and chi square
+c
+101 a0=ymean
+102 do 108 j=1,nterms
+ do 104 k=1,nterms
+104 a(j)=a(j)+r(k)*array(j,k)
+105 a(j)=a(j)*sigma/sigmax(j)
+106 a0=a0-a(j)*xmean(j)
+107 do 108 i=1,npts
+108 yfit(i)=yfit(i)+a(j)*x(j,i)
+111 do 113 i=1,npts
+ yfit(i)=yfit(i)+a0
+113 chisq=chisq+weight(i)*(y(i)-yfit(i))**2
+ freen=npts-nterms-1
+115 chisqr=chisq*wmean/freen
+c
+c calculate uncertainties
+c
+124 varnce=chisqr
+131 do 133 j=1,nterms
+132 sigmaa(j)=array(j,j)*varnce/(free1*sigmax(j)**2)
+ sigmaa(j)=sqrt(sigmaa(j))
+133 rmul=rmul+a(j)*r(j)*sigmax(j)/sigma
+ freej=nterms
+c +noao: When rmul = 1, the following division (stmt 135) would blow up.
+c It has been changed so ftest is set to -99999. in this case.
+ if (1. - rmul) 135, 935, 135
+135 ftest=(rmul/freej)/((1.-rmul)/freen)
+ goto 136
+935 ftest = -99999.
+c -noao
+136 rmul=sqrt(rmul)
+141 sigma0=varnce/fnpts
+ do 145 j=1,nterms
+ do 145 k=1,nterms
+145 sigma0=sigma0+varnce*xmean(j)*xmean(k)*array(j,k)/
+ *(free1*sigmax(j)*sigmax(k))
+146 sigma0=sqrt(sigma0)
+150 return
+ end
+c subroutine matinv.f
+c
+c source
+c bevington, pages 302-303.
+c
+c purpose
+c invert a symmetric matrix and calculate its determinant
+c
+c usage
+c call matinv (array, norder, det)
+c
+c description of parameters
+c array - input matrix which is replaced by its inverse
+c norder - degree of matrix (order of determinant)
+c det - determinant of input matrix
+c
+c subroutines and function subprograms required
+c none
+c
+c comment
+c dimension statement valid for norder up to 20
+c
+ subroutine minv20 (array,norder,det)
+ double precision array,amax,save
+ dimension array(20,20),ik(20),jk(20)
+c
+10 det=1.
+11 do 100 k=1,norder
+c
+c find largest element array(i,j) in rest of matrix
+c
+ amax=0.
+21 do 30 i=k,norder
+ do 30 j=k,norder
+23 if (dabs(amax)-dabs(array(i,j))) 24,24,30
+24 amax=array(i,j)
+ ik(k)=i
+ jk(k)=j
+30 continue
+c
+c interchange rows and columns to put amax in array(k,k)
+c
+31 if (amax) 41,32,41
+32 det=0.
+ goto 140
+41 i=ik(k)
+ if (i-k) 21,51,43
+43 do 50 j=1,norder
+ save=array(k,j)
+ array(k,j)=array(i,j)
+50 array(i,j)=-save
+51 j=jk(k)
+ if (j-k) 21,61,53
+53 do 60 i=1,norder
+ save=array(i,k)
+ array(i,k)=array(i,j)
+60 array(i,j)=-save
+c
+c accumulate elements of inverse matrix
+c
+61 do 70 i=1,norder
+ if (i-k) 63,70,63
+63 array(i,k)=-array(i,k)/amax
+70 continue
+71 do 80 i=1,norder
+ do 80 j=1,norder
+ if (i-k) 74,80,74
+74 if (j-k) 75,80,75
+75 array(i,j)=array(i,j)+array(i,k)*array(k,j)
+80 continue
+81 do 90 j=1,norder
+ if (j-k) 83,90,83
+83 array(k,j)=array(k,j)/amax
+90 continue
+ array(k,k)=1./amax
+100 det=det*amax
+c
+c restore ordering of matrix
+c
+101 do 130 l=1,norder
+ k=norder-l+1
+ j=ik(k)
+ if (j-k) 111,111,105
+105 do 110 i=1,norder
+ save=array(i,k)
+ array(i,k)=-array(i,j)
+110 array(i,j)=save
+111 i=jk(k)
+ if (i-k) 130,130,113
+113 do 120 j=1,norder
+ save=array(k,j)
+ array(k,j)=-array(i,j)
+120 array(i,j)=save
+130 continue
+140 return
+ end
diff --git a/vo/votools/gasplib/treqst.x b/vo/votools/gasplib/treqst.x
new file mode 100644
index 00000000..9e6b6548
--- /dev/null
+++ b/vo/votools/gasplib/treqst.x
@@ -0,0 +1,33 @@
+define ARCSEC_PER_RADIAN 206264.8062470964d0
+# TREQST -- Procedure to convert RA and Dec to standard coordinates
+# given the plate centre.
+
+procedure treqst (plate_centre_ra, plate_centre_dec,
+ object_ra, object_dec, xi_object, eta_object)
+
+double plate_centre_ra #i: (radians)
+double plate_centre_dec #i: (radians)
+double object_ra #i: (radians)
+double object_dec #i: (radians)
+double xi_object #o: standard coordinate (rad)
+double eta_object #o: standard coordinate (rad)
+
+double div
+
+begin
+ # Find divisor
+ div=(dsin(object_dec)*dsin(plate_centre_dec)+
+ dcos(object_dec)*dcos(plate_centre_dec)*
+ dcos(object_ra-plate_centre_ra))
+
+ # Compute standard coords and convert to arcsec
+
+ xi_object = dcos(object_dec)*dsin(object_ra-plate_centre_ra)*
+ ARCSEC_PER_RADIAN/div
+
+ eta_object = (dsin(object_dec)*dcos(plate_centre_dec)-
+ dcos(object_dec)*dsin(plate_centre_dec)*
+ dcos(object_ra-plate_centre_ra))*
+ ARCSEC_PER_RADIAN/div
+
+end
diff --git a/vo/votools/gasplib/trsteq.x b/vo/votools/gasplib/trsteq.x
new file mode 100644
index 00000000..68ce7997
--- /dev/null
+++ b/vo/votools/gasplib/trsteq.x
@@ -0,0 +1,45 @@
+define ARCSEC_PER_RADIAN 206264.8062470964d0
+
+# TRSTEQ -- procedure to compute the RA and Dec from Standard coordinates,
+# given the plate centre.
+#
+# In rectangular coordinates the vector (1, xi, eta) points toward
+# the object; the origin is the observer's location, the x-axis points
+# toward the reference pixel (plate centre), the y-axis is in the direction
+# of increasing right ascension, and the z-axis is in the direction of
+# increasing declination. The coordinate system is then rotated by the
+# declination so the x-axis passes through the equator at the RA of the
+# reference pixel; the components of the vector in this coordinate system
+# are used to compute (RA - reference_RA) and declination.
+#
+# original, written by ???
+# Phil Hodge, 15-Nov-1999 Rewrite, based on tables$lib/stxtools/xtwcs.x.
+
+procedure trsteq (ra0, dec0, xi, eta, ra, dec)
+
+double ra0, dec0 # i: RA & Dec at plate centre (radians)
+double xi, eta # i: standard coordinates (arcsec)
+double ra, dec # o: right ascension & declination (radians)
+#--
+double xi_r, eta_r # xi & eta in radians
+double x, y, z # vector (not unit length) pointing toward object
+double dra # RA at (xi,eta) - RA at plate centre
+
+begin
+ xi_r = xi / ARCSEC_PER_RADIAN
+ eta_r = eta / ARCSEC_PER_RADIAN
+
+ # Rotate the rectangular coordinate system of the vector (1, xi, eta)
+ # by the declination so the x-axis will pass through the equator.
+ x = cos (dec0) - eta_r * sin (dec0)
+ y = xi_r
+ z = sin (dec0) + eta_r * cos (dec0)
+
+ if (x == 0.d0 && y == 0.d0)
+ dra = 0.d0
+ else
+ dra = atan2 (y, x)
+ ra = ra0 + dra
+
+ dec = atan2 (z, sqrt (x*x + y*y))
+end
diff --git a/vo/votools/gasplib/varsvd.f b/vo/votools/gasplib/varsvd.f
new file mode 100644
index 00000000..81e800f3
--- /dev/null
+++ b/vo/votools/gasplib/varsvd.f
@@ -0,0 +1,21 @@
+ subroutine varsvd (v,ma,w,cvm,ncvm)
+ parameter (mmax=20)
+ real*8 v(ma,ma),w(ma),cvm(ncvm,ncvm),wti(mmax)
+ real*8 sum
+
+ do i=1,ma
+ wti(i)=0.
+ if(w(i).ne.0.0d0) wti(i)=1./(w(i)*w(i))
+ enddo
+ do i=1,ma
+ do j=1,i
+ sum=0.
+ do k=1,ma
+ sum=sum+v(i,k)*v(j,k)*wti(k)
+ enddo
+ cvm(i,j)=sum
+ cvm(j,i)=sum
+ enddo
+ enddo
+ return
+ end
diff --git a/vo/votools/getcat.cl b/vo/votools/getcat.cl
new file mode 100644
index 00000000..e1a137c5
--- /dev/null
+++ b/vo/votools/getcat.cl
@@ -0,0 +1,178 @@
+#{ GETCAT -- Call a Cone service URL and return the raw result.
+
+procedure getcat (resource, fields)
+
+string resource { prompt = "Resource name" }
+string fields { prompt = "Query images/fields" }
+string pos = "" { prompt = "POS string" }
+real size = 0.25 { prompt = "SIZE value (degrees)" }
+
+bool samp = no { prompt = "Broadcast result table(s)?" }
+bool plot = no { prompt = "Plot result table(s)?" }
+bool display = no { prompt = "Display field?" }
+bool overplot = no { prompt = "Overplot display?" }
+string output = "STDOUT" { prompt = "Output filename" }
+string format = "raw" { prompt = "Output format",
+ min="ascii|csv|votable|fits|xml|raw"}
+int status = 0 { prompt = "Service status code" }
+
+begin
+ string lname, lres, lpos, url, loname, tname, ltype, args, tcat
+ bool ldisp, lover, lplot
+ real ra, dec
+ int nread, len, nres, nfields, nrows, ncols, comma
+
+
+ # Get params to local variables
+ #lres = resource
+ #lname = fields
+ lpos = ""
+ lname = ""
+ print (resource) | translit ("STDIN"," ","+") | scan (lres)
+ print (fields) | translit ("STDIN"," ","+") | scan (lname)
+ if (fields == "") {
+ lpos = pos
+ }
+
+ ltype = format
+ loname = output
+ ldisp = display
+ lover = overplot
+ lplot = plot
+
+ tcat = mktemp ("tmp$tcat")
+
+ files (lres, sort-) | count ("STDIN") | scan (nres)
+ if (substr (lname, 1, 1) == "@") {
+ if (imaccess (substr (lname, 2, strlen (lname))) == yes) {
+ sections (lname, opt="root", > tcat)
+ count (tcat) | scan (nfields)
+ }
+ } else {
+ if (lpos == "") {
+ nfields = 1
+ } else {
+ files (lname, sort-, > tcat)
+ count (tcat) | scan (nfields)
+ }
+ }
+
+ # Simple error checking.
+ if (loname == "STDOUT" && ltype == "fits") {
+ error (0, "FITS output not allowed to STDOUT")
+ }
+
+ if (nres > 1 || nfields > 1) {
+ vodata (lres, "@"//tcat, size=size, samp=samp, count-, all-,
+ type="catalog", output=output, format=format)
+
+ delete (tcat, verify-, >& "dev$null")
+ return
+ }
+
+ # Resolve resource name.
+ if (lres == "")
+ error (0, "No resource specified")
+
+ if (substr (lres, 1, 7) == "http://") {
+ url = lres
+
+ #} else if (access ("uparm$url") == yes) {
+ # list = "uparm$url" ; nread = fscan (list, url) ; list = ""
+ } else {
+ regdb ("resolve", lres, type="C", >& "dev$null")
+ if (regdb.status == 0 && regdb.svctype != "C") {
+ error (0, "Resource '" // lres // "' is not a catalog service")
+ } else if (regdb.status == 1) {
+ url = regResolver (lres) # not found, query the Registry
+ } else {
+ url = regdb.url
+ }
+
+ if (url == "INDEF") {
+ error (0, "Resource '" // lres // "' is not a known service")
+ }
+ }
+
+ # Make sure the URL has a trailing '/' or '&'
+ len = strlen (url)
+ if (substr(url,len-4,len) == "&amp;")
+ url = substr (url, 1, len-5)
+ if (substr(url,len,len) != '?' && substr(url,len,len) != '&') {
+ if (strstr ("?", url) == 0)
+ url = url // "?"
+ else
+ url = url // "&"
+ }
+
+
+ # Determine the query params from the image WCS.
+ if (imaccess (lname) == no) {
+ if (lpos == "") {
+ #error (0, "Cannot open image '" // lname // "'")
+ sesame (lname, verbose-)
+ ra = sesame.ra
+ dec = sesame.dec
+
+ if (ldisp)
+ dss (lname, use_disp+)
+ lname = "cache$" // lname // ".fits"
+ args = "RA=" // ra // "&DEC=" // dec // "&SR=" // size
+ } else {
+ comma = stridx (",", lpos)
+ ra = real (substr(lpos,1,comma-1))
+ dec = real (substr(lpos,comma+1,strlen(lpos)))
+ args = "RA=" // ra
+ args = args // "&DEC=" // dec
+ args = args // "&SR=" // size
+ }
+
+ } else {
+ wcsinfo (lname)
+ args = "RA=" // wcsinfo.ra
+ args = args // "&DEC=" // wcsinfo.dec
+ args = args // "&SR=" // wcsinfo.size
+
+ if (ldisp)
+ display (lname, 1, >& "dev$null")
+ }
+
+ if (vo.runid != "")
+ args = args // "&RUNID=" // vo.runid
+
+ # Create a temporary output name.
+ tname = mktemp ("tmp$raw") // ".xml"
+
+ # Call the raw service via the URLGET generic task.
+ urlget (url//args, tname, extn="", use_cache+, cache="cache$")
+
+ if (samp)
+ samp ("loadVOTable", tname, id=lres, >& "dev$null")
+
+ # Get the size of the result table.
+ votsize (osfn(tname)) |& scan (nrows, ncols)
+ if (nrows == 0) {
+ print ("No results found.")
+ delete (tcat, verify-, >& "dev$null")
+ delete (tname, verify-, >& "dev$null")
+ status = 1
+ return
+ }
+
+ # Do the overlay if we displayed an image.
+ if (ldisp && lover) {
+ votpos (tname, out=tcat, verb-, number+, header-)
+ taboverlay (lname, tcat, lab=1, ra=2, dec=3, mkcolor=207)
+ }
+ if (lplot)
+ votpos (tname, out="", verb-, plot+, number-, overplot=lover)
+
+ # If we didn't want a VOTable, convert the file and rename to
+ # desired output name. A null output name means we don't want
+ # to see the table at all.
+ if (loname != "")
+ votcopy (tname, loname, ltype, header+, verb-)
+
+ delete (tname, verify-)
+ delete (tcat, verify-, >& "dev$null")
+end
diff --git a/vo/votools/getimg.cl b/vo/votools/getimg.cl
new file mode 100644
index 00000000..4353c582
--- /dev/null
+++ b/vo/votools/getimg.cl
@@ -0,0 +1,177 @@
+#{ GETIMG -- Call an SIA service URL and return the raw result.
+
+procedure getimg (resource, fields)
+
+string resource { prompt = "Resource name" }
+string fields { prompt = "Query images/fields" }
+string pos = "" { prompt = "POS string" }
+real size = 0.25 { prompt = "SIZE value (degrees)" }
+
+bool samp = no { prompt = "Broadcast result table(s)?" }
+bool plot = no { prompt = "Plot result table(s)?" }
+bool display = no { prompt = "Display field?" }
+bool overplot = no { prompt = "Overplot display?" }
+string output = "STDOUT" { prompt = "Output filename" }
+string format = "ascii" { prompt = "Output format",
+ min="ascii|csv|votable|fits|xml|raw"}
+int status = 0 { prompt = "Service status code" }
+
+begin
+ string lname, lres, lpos, url, loname, tname, ltype, args, tcat
+ bool ldisp, lover, lplot
+ real ra, dec
+ int nread, len, nres, nfields, nrows, ncols
+
+
+ # Get params to local variables.
+ #lres = resource
+ #lname = fields
+ lpos = ""
+ lname = ""
+ print (resource) | translit ("STDIN"," ","+") | scan (lres)
+ print (fields) | translit ("STDIN"," ","+") | scan (lname)
+ if (fields == "") {
+ lpos = pos
+ }
+
+ ltype = format
+ loname = output
+ ldisp = display
+ lover = overplot
+ lplot = plot
+
+ tcat = mktemp ("tmp$tcat")
+ files (lres, sort-) | count ("STDIN") | scan (nres)
+ if (substr (lname, 1, 1) == "@") {
+ if (imaccess (substr (lname, 2, strlen (lname))) == yes) {
+ sections (lname, opt="root", > tcat)
+ count (tcat) | scan (nfields)
+ }
+ } else {
+ if (lpos == "") {
+ nfields = 1
+ } else {
+ files (lname, sort-, > tcat)
+ count (tcat) | scan (nfields)
+ }
+ }
+
+ # Simple error checking.
+ if (loname == "STDOUT" && ltype == "fits") {
+ error (0, "FITS output not allowed to STDOUT")
+ }
+
+
+ if (nres > 1 || nfields > 1) {
+ vodata (lres, "@"//tcat, size=size, samp=samp, count-, all-,
+ type="image", output=output, format=format)
+ delete (tcat, verify-, >& "dev$null")
+ return
+ }
+
+ # Resolve resource name
+ if (lres == "")
+ error (0, "No resource specified")
+
+ if (substr (lres, 1, 7) == "http://") {
+ url = lres
+ len = strlen (url)
+ if (substr(url,len,len) != '?' && substr(url,len,len) != '&') {
+ if (strstr ("?", url) == 0)
+ url = url // "?"
+ else
+ url = url // "&"
+ }
+
+ #} else if (access ("uparm$url") == yes) {
+ # list = "uparm$url" ; nread = fscan (list, url) ; list = ""
+ } else {
+ regdb ("resolve", lres, type="I", >& "dev$null")
+ if (regdb.status == 0 && regdb.svctype != "I") {
+ error (0, "Resource '" // lres // "' is not a catalog service")
+ } else if (regdb.status == 1) {
+ url = regResolver (lres) # not found, query the Registry
+ } else {
+ url = regdb.url
+ }
+
+ if (url == "INDEF") {
+ error (0, "Resource '" // lres // "' is not a known service")
+ }
+ }
+
+ # Make sure the URL has a trailing '/' or '&'
+ len = strlen (url)
+ if (substr(url,len-4,len) == "&amp;")
+ url = substr (url, 1, len-5)
+ if (substr(url,len,len) != '?' && substr(url,len,len) != '&') {
+ if (strstr ("?", url) == 0)
+ url = url // "?"
+ else
+ url = url // "&"
+ }
+
+
+ # Determine the query params from the image WCS.
+ if (imaccess (lname) == no) {
+ if (lpos == "") {
+ sesame (lname, verbose-)
+ ra = sesame.ra
+ dec = sesame.dec
+
+ if (ldisp)
+ dss (lname, use_disp+)
+ lname = "cache$" // lname // ".fits"
+ args = "POS=" // lpos // "&SIZE=" // size
+
+ } else {
+ lname = ""
+ args = "POS=" // lpos // "&SIZE=" // size
+ }
+
+ } else {
+ wcsinfo (lname)
+ args = "POS=" // wcsinfo.pos // "&SIZE=" // wcsinfo.size
+ }
+
+ if (vo.runid != "")
+ args = args // "&RUNID=" // vo.runid
+
+ # Create a temporary output name.
+ tname = mktemp ("tmp$raw") // ".xml"
+
+ # Call the raw service via the URLGET generic task.
+ urlget (url//args, tname, extn="", use_cache+, cache="cache$")
+
+ if (samp)
+ samp ("loadVOTable", tname, id=lres, >& "dev$null")
+
+ # Get the size of the result table.
+ votsize (osfn(tname)) |& scan (nrows, ncols)
+ if (nrows == 0) {
+ print ("No results found.")
+ delete (tcat, verify-, >& "dev$null")
+ delete (tname, verify-, >& "dev$null")
+ status = 1
+ return
+ }
+
+
+ # Do the overlay if we displayed an image.
+ if (ldisp && lover && nrows > 0) {
+ votpos (tname, out=tcat, verb-, number+, header-)
+ taboverlay (lname, tcat, lab=1, ra=2, dec=3, mkcolor=207)
+ }
+ if (lplot)
+ votpos (tname, out="", verb-, plot+, number-, overplot=lover)
+
+ # If we didn't want a VOTable, convert the file and rename to
+ # desired output name
+ if (loname != "")
+ votcopy (tname, loname, ltype, header+, verb-)
+
+ delete (tcat, verify-, >& "dev$null")
+ delete (tname, verify-, >& "dev$null")
+end
+
+
diff --git a/vo/votools/getspec.cl b/vo/votools/getspec.cl
new file mode 100644
index 00000000..12f02882
--- /dev/null
+++ b/vo/votools/getspec.cl
@@ -0,0 +1,89 @@
+#{ GETSPEC -- Call an SSA service URL and return the raw result.
+
+procedure getspec (resource, image)
+
+string resource { prompt = "Resource name" }
+string image { prompt = "Query image" }
+string pos = "" { prompt = "POS string" }
+real size = 0.25 { prompt = "SIZE value (degrees)" }
+
+bool display = no { prompt = "Display field?" }
+bool overlay = no { prompt = "Overlay display?" }
+string output = "STDOUT" { prompt = "Output filename" }
+string format = "ascii" { prompt = "Output format",
+ min="ascii|csv|votable|fits|raw" }
+int status = 0 { prompt = "Service status code" }
+
+begin
+ string lname, lres, url, loname, tname, ltype, args
+ bool ldisp, lover
+ real ra, dec
+ int nread, len
+
+
+ # Get params to local variables.
+ lname = image
+ ltype = format
+ loname = output
+ ldisp = display
+ lover = overlay
+
+ lres = resource # resolve resource name
+ if (resource == "")
+ error (0, "No resource specified")
+
+ if (substr (lres, 1, 7) == "http://") {
+ url = lres
+ len = strlen (url)
+ if (substr(url,len,len) != '?' && substr(url,len,len) != '&') {
+ if (strstr ("?", url) == 0)
+ url = url // "?"
+ else
+ url = url // "&"
+ }
+
+ #} else if (access ("uparm$url") == yes) {
+ # list = "uparm$url" ; nread = fscan (list, url) ; list = ""
+ } else {
+ regdb ("resolve", lres, type="S")
+ url = regdb.url
+ if (regdb.svctype != "S")
+ error (0, "Resource '" // lres // "' is not a spectral service")
+ }
+
+
+ # Determine the query params from the image WCS.
+ if (imaccess (lname) == no) {
+ #error (0, "Cannot open image '" // lname // "'")
+ sesame (lname, verbose-)
+ ra = sesame.ra
+ dec = sesame.dec
+
+ if (ldisp)
+ dss (lname, use_disp+)
+ lname = "cache$" // lname // ".fits"
+ args = "POS=" // ra // "," // dec // "&SIZE=" // size
+
+ } else {
+ wcsinfo (lname)
+ args = "POS=" // wcsinfo.pos // "&SIZE=" // wcsinfo.size
+ }
+
+ if (vo.runid != "")
+ args = args // "&RUNID=" // vo.runid
+
+
+ # Create a temporary output name.
+ tname = mktemp ("tmp$raw") // ".xml"
+
+ # Call the raw service via the URLGET generic task.
+ urlget (url//args, tname, extn="", use_cache+, cache="cache$")
+
+ # If we didn't want a VOTable, convert the file and rename to
+ # desired output name
+ votcopy (tname, loname, ltype, header+, verb-)
+
+ delete (tname, verify-)
+end
+
+
diff --git a/vo/votools/hub.cl b/vo/votools/hub.cl
new file mode 100644
index 00000000..58a9a970
--- /dev/null
+++ b/vo/votools/hub.cl
@@ -0,0 +1,70 @@
+#{ HUB -- Start or stop the Hub
+
+procedure hub (cmd)
+
+string cmd { prompt = "Command" }
+bool bkg = yes { prompt = "Run in background?" }
+bool gui = yes { prompt = "Run a GUI window?" }
+bool verbose = no { prompt = "Verbose output?" }
+
+begin
+ string action, command, ch
+ bool verb, do_gui, stat
+
+ action = cmd
+ verb = verbose
+ do_gui = gui
+ command = "!" // osfn ("vo$java/app.hub")
+
+ if (action == "start" || action == "on") {
+ command = command // " -bg"
+ if (!do_gui) {
+ command = command // " -no-gui"
+ }
+ ;
+ print (command) | cl(, >& "dev$null")
+
+retry:
+ i = 0
+ stat = sampHubAccess ()
+ for (i=0; stat == no; i = i + 1) {
+ if (verb)
+ print ("Waiting for Hub to start ...")
+ sleep (1)
+
+ if (i > 60) # only wait a minute to start
+ break
+
+ stat = sampHubAccess ()
+ }
+
+ if (stat) {
+ samp on
+ if (verb)
+ print ("Hub and SAMP started")
+ } else {
+ printf ("Cannot start or contact SAMP Hub.\n")
+prompt:
+ printf ("Would you like to try again (y/n) ? ")
+
+ ch = cl.ukey # get reply
+ print ("")
+ if (ch == "y") {
+ goto retry
+ } else if (substr(ch,1,4) == "\\015") {
+ goto prompt
+ }
+ }
+ ;
+
+ } else if (action == "stop" || action == "off") {
+ samp off
+ command = command // " -kill"
+ print (command) | cl(, >& "dev$null")
+
+
+ } else if (action == "status") {
+ command = command // " -status"
+ print (command) | cl()
+ }
+end
diff --git a/vo/votools/imgcat.cl b/vo/votools/imgcat.cl
new file mode 100644
index 00000000..7abdf74a
--- /dev/null
+++ b/vo/votools/imgcat.cl
@@ -0,0 +1,139 @@
+#{ IMGCAT -- Create a catalog of stellar objects in an image.
+
+procedure imgcat (image, catalog)
+
+string image { prompt = "Image name" }
+string catalog { prompt = "Output catalog name" }
+
+string format = "text" { prompt = "Output format" }
+bool verbose = no { prompt = "Verbose?" }
+
+bool dosplit = yes { prompt = "Split detected objects?" }
+string method = "thresh" { prompt = "Detection method (ace|thresh)",
+ enum = "ace|thresh" }
+real ellipse = 0.33 { prompt = "Ellipticity cutoff?" }
+real threshold = 5. { prompt = "Detected threshold?" }
+
+int ndetected = 0 { prompt = "Num detected objects" }
+int nel_clip = 0 { prompt = "Num clipped for ellipticity" }
+int nobjs = 0 { prompt = "Num remaining objects" }
+
+begin
+ string img, fmt, catdef, cat, ccscript
+ string tcat, tc1, tc2, tc3, tc4, tdef, expr, detcode
+ int nstars, nx, ny
+ bool verb, split
+ real ellip, sigma, stddev, immean, lthresh
+
+
+ # Check for proper packages and reset environment.
+ ;
+ reset imtype = "fits"
+ reset clobber = yes
+ #flpr 0
+
+
+ # Get the task parameters.
+ img = image
+ cat = catalog
+ verb = verbose
+ fmt = format
+ ellip = ellipse
+ detcode = method
+ split = dosplit
+ sigma = threshold
+
+
+ # If we have zero values, replace them with the image mean.
+ minmax (img, update-, >& "dev$null")
+ if (minmax.minval == 0) {
+ imstat (img, field="mean", format-) | scan (immean)
+ imreplace (img, immean, upper=0.0)
+ }
+
+
+ # Do the object detection.
+ if (detcode == "ace") {
+ # Initialize
+ catdef = mktemp ("/tmp/cd")
+
+ print ("WX\nWY\nPX\nPY\nFLUX\nELLIP\n", > catdef)
+
+ # Remove the DATASEC keyword if present since it may not be valid for
+ # the image, but will be used by ACE anyway.
+ hselect (img, "DATASEC", yes) | scan (s1)
+ if (nscan() == 1)
+ hedit (img, "DATASEC", delete+, update+, verify-, >& "dev$null")
+
+
+ # Run the DETECT task to locate the stars.
+ iferr {
+ detect (img, catdefs=catdef, catalog=cat, hsigma=sigma,
+ doeval+, dosplit=split, dogrow+)
+return
+ detect (img, catdefs=catdef, catalog=cat, hsigma=sigma,
+ doeval+, dosplit=split, dogrow+) | \
+ match ("detected", "STDIN") | scan (nstars)
+ delete (catdef, verify-)
+ } then {
+ error (0, "Error creating image catalog\n")
+ }
+
+ # Now filter the catalog to pull out the "stellar" objects identified
+ # by a low ellipticity. Sort on FLUX.
+ tcat = mktemp ("/tmp/tc")
+ tinfo (cat, ttout-)
+ nstars = tinfo.nrows
+ fields (cat, "1-6", > tcat)
+ if (ellip > 0.0) {
+ expr = "c6 == INDEF || c6 < " // ellip
+ tselect (tcat, cat, expr)
+ tcopy (cat, tcat, >& "dev$null")
+ }
+ tinfo (tcat, ttout-)
+ tsort (tcat, col="c5", ascend-)
+
+
+ tcalc (tcat, "c1", "c1 * 15.0")
+ tdump (tcat, cd="dev$null", pf="dev$null", data="STDOUT",
+ col="c1,c2,c3,c4,c5", row="1-", > cat)
+
+ # Sort the table and save the results to parameters.
+ tsort (cat, col="c4")
+
+ # Clean up.
+ if (access (tcat) == yes)
+ delete (tcat, verify-, >& "dev$null")
+
+ } else if (detcode == "thresh") {
+
+ # Get the stddev of the image
+ imstat (img, fields="stddev", format-) | scan (stddev)
+ lthresh = 1 * stddev
+
+ starfind (img, "image.obj", 1., lthresh, wcs="world",
+ wxf="%12.2H", wyf="%12.1h")
+
+ i = 0
+ printf ("|id |ra |dec |\n", > cat)
+ list = "image.obj"
+ while (fscan (list, z, z, x, y) != EOF) {
+ if (i > 18)
+ printf (" %14d %14.8f %14.8f\n", (i-18), x, y, >> cat)
+ i = i + 1
+ }
+ list = ""
+ nstars = i - 18
+
+ delete ("image.obj", verify-, >& "dev$null")
+ ellip = 0.0 # disable ellipticity check
+ }
+
+ ndetected = nstars
+ nobjs = tinfo.nrows
+
+return
+ # Run the cross-compare script.
+ ccscript = osfn ("votools$cross_comp.sh")
+ printf ("!%s %s 1.5 TWOMASS_PSC\n", ccscript, cat) | cl()
+end
diff --git a/vo/votools/makewcs.par b/vo/votools/makewcs.par
new file mode 100644
index 00000000..88b8cfae
--- /dev/null
+++ b/vo/votools/makewcs.par
@@ -0,0 +1,3 @@
+infiles,f,a,,,,Input image names
+verbose,b,h,YES,,,Verbose?
+mode,s,h,"al"
diff --git a/vo/votools/mkpkg b/vo/votools/mkpkg
new file mode 100644
index 00000000..5b078632
--- /dev/null
+++ b/vo/votools/mkpkg
@@ -0,0 +1,40 @@
+# Make the VO package compiled tasks.
+
+$call relink
+$exit
+
+update:
+ $call relink
+ $call install
+ ;
+
+relink:
+ $set LIBS = "-lasttools -lxtools -lstg -lds -ltbtables -lslalib"
+
+ $update libpkg.a
+ $omake x_votools.x
+ $link x_votools.o libpkg.a $(LIBS) -o xx_votools.e
+ ;
+
+install:
+ $move xx_votools.e vobin$x_votools.e
+ ;
+
+
+libpkg.a:
+ $set XFLAGS = "$(XFLAGS) -g -q"
+
+ @gasplib
+
+ console.x
+ resdb.x
+ t_dalclient.x <ctype.h>
+ t_makewcs.x <imhdr.h> <error.h> <imhdr.h> <imio.h> <mach.h> <math.h>
+ t_sbquery.x <time.h>
+ t_sesame.x
+ t_vodata.x
+ t_votcopy.x
+ t_votsize.x
+ t_votget.x
+ t_dispname.x
+ ;
diff --git a/vo/votools/mkregdb.cl b/vo/votools/mkregdb.cl
new file mode 100644
index 00000000..0f968e0e
--- /dev/null
+++ b/vo/votools/mkregdb.cl
@@ -0,0 +1,141 @@
+#{ MKREGDB -- Make a Registry Database using constraints.
+
+procedure mkregdb (query)
+
+string query { prompt = "Query Term" }
+
+string output = "" { prompt = "Output filename" }
+string type = "" { prompt = "Resource type" }
+string bandpass = "" { prompt = "Bandpass" }
+string content = "" { prompt = "Content Level" }
+string sql = "" { prompt = "SQL predicate" }
+
+bool header = yes { prompt = "Print header?" }
+int nresults = 0 { prompt = "Number of results?" }
+int status = 0 { prompt = "status code" }
+
+begin
+ string qterm, fstr, qstr, id, typ, lout
+ string bpass, clevel, sqlstr, stype, ch
+ string t, a, b, i, u, d
+ int res, count, istart, iend, n, vnlines, rec
+ bool hdr
+
+
+ reset clobber = yes # set the environment
+
+ lout = output
+ hdr = header
+ stype = type
+ bpass = bandpass
+ clevel = content
+ sqlstr = sql
+
+ if (lout == "")
+ lout = "STDOUT"
+
+ # Build a sql predicate string from the contraints (if any).
+ qstr = ""
+ if (stype != "") {
+ s1 = strlwr (stype)
+ if (s1 == "sia" || substr (s1,1,2) == "im")
+ qstr = "(Tag like '%images%')"
+ else
+ qstr = "(xml like '%" // stype // "%')"
+ }
+ if (bpass != "") {
+ s1 = "([coverage/waveband] like '%" // bpass // "%')"
+ if (qstr != "")
+ qstr = qstr // " AND " // s1
+ else
+ qstr = s1
+ }
+ if (clevel != "") {
+ s1 = "([content/contentLevel] like '%" // clevel // "%')"
+ if (qstr != "")
+ qstr = qstr // " AND " // s1
+ else
+ qstr = s1
+ }
+ if ($nargs > 0)
+ qterm = query
+ else {
+ qterm = ""
+ sqlstr = "(Title like '%')"
+ }
+ if (sqlstr != "") {
+ s1 = "(" // sqlstr // ")"
+ if (qstr != "")
+ qstr = qstr // " AND " // s1
+ else
+ qstr = s1
+ }
+
+
+ # Do the Registry query.
+ nresults = 0
+ if (qstr != "")
+ res = regSearch (qstr, qterm, 0)
+ else
+ res = regSearch (qterm, 0)
+ count = regResCount (res)
+ istart = 0
+ iend = count
+
+ if (count == 0) {
+ status = 1
+ return
+ }
+
+ # Dump the query constraints we used in the search.
+ printf ("", > lout)
+ if (hdr) {
+ printf ("# VO Resource utility database\n", >> lout)
+ printf ("# \n", >> lout)
+ printf ("# \t Query Term: '%s'\n", qterm, >> lout)
+ printf ("# \t ServiceType: %s\n", stype, >> lout)
+ printf ("# \t Bandpass: %s\n", bpass, >> lout)
+ printf ("# \tContentLevel: %s\n", clevel, >> lout)
+ printf ("# \t SQL: %s\n", sqlstr, >> lout)
+ printf ("# \n", >> lout)
+ printf ("# type,alias,bandpass,ivorn,url,title\n", >> lout)
+ printf ("# \n", >> lout)
+ }
+
+ for (n=istart; n < iend; n=n+1) {
+
+ t = trim (regValue (res, "ServiceType", n))
+ a = trim (regValue (res, "ShortName", n))
+ b = trim (regValue (res, "CoverageSpectral", n))
+ i = trim (regValue (res, "Identifier", n))
+ u = trim (regValue (res, "ServiceURL", n))
+ d = trim (regValue (res, "Title", n))
+
+ if (t == "" || u == "") # probably not a data service, skip it
+ next
+ if (b == "") # unknown bandpass matches any
+ b = "*"
+ if (a == "") # construct ShortName from IVORN
+ a = substr (i, strldx("/",i)+1, strlen (i))
+
+ # Fix up the values for proper entry in the database.
+ if (stridx (" ", a) > 0) a = strlwr (strsub (a, " ", "_"))
+ if (stridx (",", b) > 0) b = strlwr (strsub (b, ",", ":"))
+ if (stridx (" ", d) > 0) d = strsub (d, " ", ":")
+ if (stridx (",", d) > 0) d = strsub (d, ",", ";")
+
+ b = strlwr (b)
+ t = strlwr (t)
+ if (strstr ("image", t) > 0)
+ t = "I"
+ else if (strstr ("cone", t) > 0)
+ t = "C"
+ else if (strstr ("spectra", t) > 0)
+ t = "S"
+ else
+ t = "O"
+
+ printf ("%s,%s,%s,%s,%s,%s,%s\n", t, a, b, i, a, u, d, >> lout)
+ nresults = nresults + 1
+ }
+end
diff --git a/vo/votools/nedoverlay.cl b/vo/votools/nedoverlay.cl
new file mode 100644
index 00000000..50d8e8c0
--- /dev/null
+++ b/vo/votools/nedoverlay.cl
@@ -0,0 +1,116 @@
+#{ NEDOVERLAY -- Overlay NED catalog sources on an image display.
+
+procedure nedoverlay (image)
+
+string image { prompt = "Input image" }
+
+bool append = yes { prompt = "Append display?" }
+real size = 0.25 { prompt = "Field size" }
+bool galaxies = no { prompt = "Mark Galaxies?" }
+bool radios = yes { prompt = "Mark Radio sources?" }
+bool xrays = yes { prompt = "Mark X-Ray sources?" }
+int mkcolor = 208 { prompt = "Marker color" }
+int galcolor = 207 { prompt = "Galaxy marker color" }
+bool verbose = no { prompt = "Verbose output?" }
+int status = 0 { prompt = "Service status code" }
+
+begin
+ string img, ned, coords, tvcoords, url, query
+ string fields, pos_all, pos_l, pos_w, base
+ real ra, dec, sz
+ bool verb, app, gal, rad, xry
+ int mcol, gcol, nobjs
+
+
+ img = image # Get params to local variables
+ verb = verbose
+ app = append
+ mcol = mkcolor
+ gal = galaxies
+ rad = radios
+ xry = xrays
+ gcol = galcolor
+ sz = size
+
+ base = "http://ned.ipac.caltech.edu/cgi-bin/nph-NEDobjsearch"
+ base = base // "?search_type=Near+Position+Search&of=xml_main&"
+
+ if (imaccess (img)) {
+ iferr { wcsinfo (img) } then {
+ error (0, "Cannot determine image coords for `"//img//"'")
+ } else {
+ ra = wcsinfo.midx
+ dec = wcsinfo.midy
+ sz = max (wcsinfo.width, wcsinfo.height) / 60.0
+ if (app == no)
+ display (img, 1, >& "dev$null")
+ }
+ } else {
+ sesame (img, verbose-)
+ if (app == no)
+ dss (img, size=sz, use_display+)
+ ra = sesame.ra
+ dec = sesame.dec
+ img = "cache$" // img // ".fits"
+ }
+
+
+ # Get NED sources
+ printf ("RA=%.4f&DEC=%.4f&SR=%.4f\n", ra, dec, sz) | scan (query)
+ url = base // query // "&RUNID=" // vo.runid
+
+ ned = mktemp ("/tmp/ned")
+
+
+ # Download and convert the file.
+ votcopy (url, ned, format="ascii")
+
+ # Create temp files for the output
+ coords = mktemp ("tmp$ned_coords_")
+ tvcoords = mktemp ("tmp$ned_tvcoords_")
+ pos_all = mktemp ("tmp$pos_all_")
+ pos_l = mktemp ("tmp$pos_l_")
+ pos_w = mktemp ("tmp$pos_w_")
+
+ # Select the RA,Dec from the output NED table.
+ fields (ned, "3,4,5", >& pos_all)
+
+
+ # Expand the list of object types we want to mark.
+ fields = mktemp ("tmp$ned_fields_")
+ print ("G_Lens\nGClstr\nGPair\nQSO\n", > fields)
+ if (rad) print ("Radio\n", >> fields)
+ if (xry) print ("Xray\n", >> fields)
+
+ # Mark the Galaxies on the display.
+ if (galaxies) {
+ match (" G ", ned) | fields("STDIN","3,4,5", >& pos_all)
+ count (pos_all) | scan (nobjs)
+ wcsctran (pos_all, "c1", img, verb-,
+ inwcs="world", outwcs="logical", units="n n")
+ tvmark (frame=1, coords="c1", mark="plus", radii=10, color=gcol,
+ txsize=1, nxoffset=5, nyoffset=-10)
+ delete ("c1", verify-, >& "dev$null")
+ }
+ if (verbose)
+ printf ("%d objects found\n", nobjs)
+
+ # Mark the requested objects on the display.
+ list = fields
+ while (fscan (list, s1) != EOF) {
+ match (s1, ned) | fields("STDIN", "3,4,5", >& pos_w)
+ count(pos_w) | scan(nobjs)
+
+ if (nobjs > 0) {
+ if (verbose)
+ printf ("%-10s : %d found\n", s1, nobjs)
+ wcsctran (pos_w,pos_l,img,"world","logical",verb-,units="n n") | \
+ tvmark (frame=1, coords=pos_l, mark="circle", radii=10,
+ color=mcol, txsize=1, lab+, nxoffset=5, nyoffset=-10)
+ }
+ }
+ list = ""
+
+ # Clean up.
+ delete ("tmp$ned*,tmp$pos_*", verify-, >& "dev$null")
+end
diff --git a/vo/votools/obslogoverlay.cl b/vo/votools/obslogoverlay.cl
new file mode 100644
index 00000000..0fdc6863
--- /dev/null
+++ b/vo/votools/obslogoverlay.cl
@@ -0,0 +1,166 @@
+#{ OBSLOGOVERLAY -- Overlay an observation catalog on the display.
+
+procedure obslogoverlay (field, mission)
+
+string field { prompt = "Query image/field name" }
+string mission { prompt = "Mission name?" }
+
+real size = 0.25 { prompt = "Query size" }
+int frame = 1 { prompt = "Display frame" }
+bool display = yes { prompt = "Display image/field?" }
+bool print = no { prompt = "List instead of overlay?" }
+int mkcolor = 0 { prompt = "Marker color" }
+int mksize = 60 { prompt = "Marker size (arcsec)" }
+int maxobs = 0 { prompt = "Max observations to draw" }
+
+bool verbose = yes { prompt = "Verbose output?" }
+int status = 0 { prompt = "Service status code" }
+
+begin
+ string obs, lname, olog, tvcoords, rad, raw, pcols
+ real ra, dec, sz, scale
+ bool verb, disp, llist
+ int mcol, fr, nres, max, mksz
+
+
+ lname = field # Get params to local variables
+ obs = mission
+ fr = frame
+ sz = size
+ max = maxobs
+ mksz = mksize * 10
+ mcol = mkcolor
+ verb = verbose
+ llist = print
+ if (llist)
+ disp = no
+ else
+ disp = display
+
+
+ if (imaccess (lname) == yes) {
+ iferr { wcsinfo (lname) } then {
+ status = 1
+ error (0, "Cannot determine image coords for `"//lname//"'")
+ } else {
+ ra = wcsinfo.midx
+ dec = wcsinfo.midy
+ sz = wcsinfo.size
+ scale = wcsinfo.scale
+ if (disp)
+ display (lname, fr, >& "dev$null")
+ }
+ } else {
+ sesame (lname, verbose-)
+ ra = sesame.ra
+ dec = sesame.dec
+ scale = 0.1
+ if (disp)
+ dss (lname, use_disp+)
+ lname = "cache$" // lname // ".fits"
+ }
+
+
+ # Do a generic 1' box
+ printf ("%.1f,%.1f\n", (scale*mksz), (scale*mksz)) | scan(rad)
+
+ # Create temp file for the output
+ olog = mktemp ("tmp$olog")
+ raw = mktemp ("tmp$olog")
+
+ # Get observation log sources
+ switch (substr (strupr (obs), 1, 1)) {
+ case "E": # EXOSAT Observation log
+ { vodata ("ivo://nasa.heasarc/exolog", "", ra=ra, dec=dec,
+ size=sz, format="raw", >& raw)
+ pcols = "4,5"
+ if (mcol == 0)
+ mcol = 206
+ }
+ case "F": # FUSE Observation log
+ { vodata ("ivo://nasa.heasarc/fuselog", "", ra=ra, dec=dec,
+ size=sz, format="raw", >& raw)
+ pcols = "4,5"
+ if (mcol == 0)
+ mcol = 208
+ }
+ case "H": # HST Observation log
+ { vodata ("ivo://nasa.heasarc/hstaec", "", ra=ra, dec=dec,
+ size=sz, format="raw", >& raw)
+ pcols = "3,4"
+ if (mcol == 0)
+ mcol = 204
+ }
+ case "I": # IUE Observation log
+ { vodata ("ivo://nasa.heasarc/iuelog", "", ra=ra, dec=dec,
+ size=sz, format="raw", >& raw)
+ pcols = "3,4"
+ if (mcol == 0)
+ mcol = 208
+ }
+ case "S": # Spitzer Observation log
+ { vodata ("ivo://nasa.heasarc/spitzmastr", "", ra=ra, dec=dec,
+ size=sz, format="raw", >& raw)
+ pcols = "3,4"
+ if (mcol == 0)
+ mcol = 205
+ }
+ case "X": # XMM Observation log
+ { vodata ("ivo://nasa.heasarc/xmmmaster", "", ra=ra, dec=dec,
+ size=sz, format="raw", >& raw)
+ pcols = "5,6"
+ if (mcol == 0)
+ mcol = 207
+ }
+
+ # =================================================================
+ # FIXME -- These no longer work. Mar2012
+ # =================================================================
+ case "R": # Rosat Observation log
+ { # FIXME
+ vodata ("rosatlog", "", ra=ra, dec=dec, size=sz,
+ format="raw", >& raw)
+ pcols = "10,11"
+ if (mcol == 0)
+ mcol = 208
+ }
+ case "C": # Chandra Observation log
+ { # FIXME
+ vodata ("ivo://CDS.VizieR/B/chandra", "", ra=ra, dec=dec,
+ size=sz, format="raw", >& raw)
+ pcols = "3,4"
+ if (mcol == 0)
+ mcol = 205
+ }
+ }
+
+ votpos (raw, number-, >& olog)
+ count (olog) | scan (nres)
+ if (max == 0)
+ max = nres
+ if (verbose)
+ printf ("%d observations found for %s\n", max, strupr(obs))
+
+
+ # Mark the display.
+ if (llist) {
+ type (raw)
+ } else {
+ tvcoords = mktemp ("tmp$tvc")
+
+ type (olog) | head ("STDIN", nl=max) | \
+ wcsctran ("STDIN", tvcoords, lname, verbose=verb,
+ inwcs="world", outwcs="logical", units="n n")
+ tvmark (frame=fr, coords=tvcoords, mark="rectangle", length=rad,
+ color=mcol, txsize=1, lab+)
+
+ delete (tvcoords, verify-, >& "dev$null")
+ }
+
+ # Clean up.
+ #delete (raw, verify-, >& "dev$null")
+ #delete (olog, verify-, >& "dev$null")
+
+ status = 0
+end
+
diff --git a/vo/votools/prettystr.cl b/vo/votools/prettystr.cl
new file mode 100644
index 00000000..a9915af5
--- /dev/null
+++ b/vo/votools/prettystr.cl
@@ -0,0 +1,89 @@
+#{ PRETTYSTR -- Pretty-print a string. A pretty abusive way to use the
+# CL string functions.
+
+procedure prettystr (instr)
+
+struct instr { prompt = "Input string" }
+
+int start_col = 18 { prompt = "Starting column" }
+int end_col = 75 { prompt = "Ending column" }
+bool comment = no { prompt = "Comment string?" }
+
+begin
+ struct ip, op, cp
+ string spaces
+ int scol, ecol, lnum
+ int sp, ep, oep, slen, ncols
+ bool done, comm
+
+ scol = start_col
+ ecol = end_col + 2
+ ip = instr
+ comm = comment
+ if (comm)
+ scol = scol + 1
+
+ lnum = 1
+ done = no
+ spaces = " "
+ op = ""
+
+ slen = strlen (ip)
+ if (slen >= 511)
+ slen = 512
+ ncols= (ecol - scol + 1)
+ sp = 1
+ ep = ncols
+ oep = 1
+
+
+ # Handle the easy case first. If it's a short string or there are
+ # no spaces just print it.
+ if (slen <= ep) {
+ print (ip)
+
+ } else {
+ while (!done) {
+ # Get char at ending guess.
+ cp = substr (ip,ep,ep)
+ if (cp != " " && cp != "\t" && cp != "\n" && cp != ",") {
+ # back up to the previous whitespace
+ while (ep > oep) {
+ cp = substr (ip,ep,ep)
+ if (cp == " " || cp == "\t" || cp == "\n" || cp == ",")
+ break
+ else
+ ep = ep - 1
+ }
+ if (ep <= oep) {
+ # Long string, no commas, just dump it
+ print (ip)
+ return
+ }
+ }
+
+ # Whitespace - break here
+ line = substr (ip, sp, ep)
+ printf ("%s\n", line)
+ if (comm) printf ("#")
+ if (lnum >= 1)
+ printf ("%s", substr (spaces, 1, (scol-1)))
+
+ # Update pointers
+ sp = ep + 1
+ if ((ep + ncols) > slen) {
+ # last chunk
+ ep = slen
+ line = substr (ip, sp, ep)
+ printf ("%s\n", line)
+
+ done = yes
+
+ } else {
+ oep = ep
+ ep = ep + ncols
+ }
+ lnum = lnum + 1
+ }
+ }
+end
diff --git a/vo/votools/qstring.cl b/vo/votools/qstring.cl
new file mode 100644
index 00000000..1c4d51f5
--- /dev/null
+++ b/vo/votools/qstring.cl
@@ -0,0 +1,89 @@
+#{ QSTRING -- Build a VO query URL from arguments.
+
+procedure qstring (base, field)
+
+string base { prompt = "Base URL or resource" }
+string field { prompt = "Query image/field" }
+
+string type = "catalog" { prompt = "Service type" }
+
+real ra = 0.0 { prompt = "RA of field" }
+real dec = 0.0 { prompt = "Dec of field" }
+real size = 0.25 { prompt = "Field size" }
+
+begin
+ string lname, lres, url, tname, largs
+ real lra, ldec, lsize
+ int nread, len
+
+
+ # Get params to local variables
+ lsize = size
+ largs = "test"
+
+ # Resolve resource name.
+ lres = base
+ if (lres == "")
+ error (0, "No base URL specified")
+
+ if (substr (lres, 1, 7) == "http://") {
+ url = lres
+ lname = ""
+ } else {
+ lname = field
+ if (type == "catalog")
+ regdb ("resolve", lres, type="C", >& "dev$null")
+ else
+ regdb ("resolve", lres, >& "dev$null")
+
+ if (regdb.status == 1)
+ url = regResolver (lres) # not found, query the Registry
+ else
+ url = regdb.url
+ }
+
+ # Make sure the URL ends in a '?' or an '&'.
+ len = strlen (url)
+ if (substr(url,len,len) != '?' && substr(url,len,len) != '&') {
+ if (strstr ("?", url) == 0)
+ url = url // "?"
+ else
+ url = url // "&"
+ }
+
+ # Determine the position information.
+ if (imaccess (lname) == no) {
+ # Field is not an image, assume it is an object name. If we
+ # can resolve the name use that, otherwise use the input params.
+ sesame (lname, verbose-)
+ if (sesame.status == 0) {
+ ra = sesame.ra
+ dec = sesame.dec
+ }
+
+ if (type == "catalog")
+ largs = "RA=" // ra // "&DEC=" // dec // "&SR=" // lsize
+ else
+ largs = "POS=" // ra // "," // dec // "&SIZE=" // lsize
+
+ } else {
+ # Determine the query params from an image WCS.
+ wcsinfo (lname)
+ if (type == "catalog") {
+ largs = "RA=" // wcsinfo.ra
+ largs = largs // "&DEC=" // wcsinfo.dec
+ largs = largs // "&SR=" // wcsinfo.size
+ } else {
+ largs = "POS=" // wcsinfo.ra // "," // wcsinfo.dec
+ largs = largs // "&SIZE=" // wcsinfo.size
+ }
+ }
+
+ # Add the RUNID logging param.
+ if (vo.runid != "")
+ largs = largs // "&RUNID=" // vo.runid
+
+
+ # Printe the derived query string.
+ print (url // largs)
+end
diff --git a/vo/votools/radiooverlay.cl b/vo/votools/radiooverlay.cl
new file mode 100644
index 00000000..07a2e14c
--- /dev/null
+++ b/vo/votools/radiooverlay.cl
@@ -0,0 +1,73 @@
+#{ RADIOOVERLAY -- Overlay a radio contour on the image display.
+
+procedure radiooverlay (image)
+
+string image { prompt = "Input image" }
+
+real size = 0.25 { prompt = "Query size" }
+int ncontours = 0 { prompt = "No. contours to draw" }
+
+bool append = yes { prompt = "Append display?" }
+bool verbose = yes { prompt = "Verbose output?" }
+string device = "imdred" { prompt = "Overlay device" }
+int status = 0 { prompt = "Service status code" }
+
+begin
+ string img, rimg, imname, ovdev, url, query, base
+ string fields, pos_all, pos_l, pos_w, restab
+ real ra, dec, sz
+ bool verb, app, disp
+ int siap, count, ncont
+
+
+ img = image # Get params to local variables
+ sz = size
+ verb = verbose
+ app = append
+ ncont = ncontours
+ ovdev = device
+ restab = mktemp ("tmp$res") // ".xml"
+ rimg = mktemp ("tmp$img") // ".fits"
+
+
+ if (imaccess (img)) {
+ iferr { wcsinfo (img) } then {
+ error (0, "Cannot determine image coords for `"//img//"'")
+ } else {
+ ra = wcsinfo.midx
+ dec = wcsinfo.midy
+ sz = max (wcsinfo.width, wcsinfo.height) / 60.0
+ if (!app)
+ display (img, 1, >& "dev$null")
+ }
+ } else {
+ sesame (img, verbose-)
+ ra = sesame.ra
+ dec = sesame.dec
+ if (!app)
+ dss (img, size=sz, use_display+)
+ }
+
+
+ # Create temp files for the output
+ rimg = mktemp ("tmp$rad") // ".fits"
+
+ # Get NVSS image, force the use of the SkyView service.
+ base = "http://skyview.gsfc.nasa.gov/cgi-bin/vo/sia.pl?survey=nvss&"
+ printf ("POS=%.5f,%.5f&SIZE=%.3f", ra, dec, sz) | scan (query)
+ url = base // query // "&RUNID=" // vo.runid
+
+ # Download the query string.
+ urlget (url, restab, use_cache+, cache="cache$")
+
+ tdump (restab, row=1, col="URL", pwidth=2048, cdfile="dev$null",
+ pfile="dev$null") | scan (rimg)
+
+ # Overlay the contours
+ contour (rimg, dev=ovdev, title="", perim-, fill+, xres=64, yres=64,
+ ncontours=ncont, >& "dev$null")
+
+ # Clean up.
+ delete (restab, verify-, >& "dev$null")
+ imdelete (rimg, >& "dev$null")
+end
diff --git a/vo/votools/regdb.cl b/vo/votools/regdb.cl
new file mode 100644
index 00000000..28891d55
--- /dev/null
+++ b/vo/votools/regdb.cl
@@ -0,0 +1,341 @@
+#{ REGDB -- Registry DB utility.
+
+procedure regdb (arg1, arg2, arg3)
+
+string arg1 { prompt = "Command/Search Term" }
+string arg2 { prompt = "Search Term" }
+string arg3 { prompt = "Optional arg" }
+
+string type = "" { prompt = "Service type constraint" }
+string bandpass = "" { prompt = "Bandpass constraint" }
+
+string alias = "" { prompt = "Resource alias" }
+string ivorn = "" { prompt = "Ivorn string" }
+string sname = "" { prompt = "Short Name" }
+
+string svctype = "" { prompt = "Resource type" }
+string bpass = "" { prompt = "Bandpass" }
+string url = "" { prompt = "Service URL" }
+string desc = "" { prompt = "Description" }
+
+bool verbose = no { prompt = "Print result?" }
+int status = 0 { prompt = "status code" }
+
+begin
+ string tf, t, a, b, i, s, u, d, lterm, cmds = ""
+ string lcmd, lalias, ltype, lbpass, livorn, lsname, ldesc, lresdb, lnew
+ bool verb, found
+
+
+ # Initialize the command dictionary.
+ cmds = cmds // "|list|resolve|search"
+ cmds = cmds // "|type|alias|bpass|ivorn|sname|url|desc"
+ cmds = cmds // "|add|del|update|rename|"
+
+
+ if ($nargs == 1 && strdic (arg1, cmds) > 0) {
+ # cl> regdb list
+ lcmd = arg1
+ lterm = ""
+
+ } else if ($nargs == 3 && arg1 == "rename") {
+ # cl> regdb rename <old> <new>
+ lcmd = arg1
+ lterm = ""
+ lnew = arg3
+
+ } else if ($nargs == 1 || strdic (arg1, cmds) == 0) {
+ # cl> regdb <ivorn> | <alias> | <sname>
+ lcmd = "resolve"
+ lterm = strlwr (arg1)
+
+ } else if ($nargs > 1 && strdic(arg1,cmds) > 0 && strdic(arg2,cmds) == 0) {
+ # cl> regdb list <ivorn> | <alias> | <sname>
+ lcmd = arg1
+ lterm = strlwr (arg2)
+ } else {
+ lcmd = arg1
+ lterm = ""
+ }
+
+ lalias = strlwr (alias)
+ ltype = strlwr (substr (type,1,1))
+ lbpass = strlwr (bandpass)
+
+ lsname = strlwr (sname)
+ livorn = strlwr (ivorn)
+ lresdb = vo.resdb # from package param file
+ ldesc = ""
+ verb = verbose
+
+ # Dump the database to a parsable file.
+ tf = mktemp ("tmp$tf")
+ translit (lresdb, ",", " ") | fields ("STDIN", "1-", > tf)
+
+
+ status = 0
+
+ # Resolve the search term.
+ if (lcmd != "list" && lterm != "") {
+ found = no
+ delete ("uparm$url", verify-, >& "dev$null")
+ list = tf
+ status = 1
+ while (fscan (list, t, a, b, i, s, u, d) != EOF) {
+
+ if (lterm == strlwr(a) || lterm == strlwr(b) ||
+ lterm == strlwr(i) || lterm == strlwr(s)) {
+
+ if ((lbpass != "" && lbpass != strlwr(b)))
+ next
+ if ((ltype != "" && ltype != strlwr(t)))
+ next
+
+ printf ("%s\n", d) | \
+ translit ("STDIN", ":", " ", collapse+) | scan (ldesc)
+ svctype = t ; alias = a ; bpass = b ; ivorn = i
+ sname = s ; url = u ; desc = ldesc
+ print (u, > "uparm$url")
+ found = yes
+ status = 0
+ break;
+ }
+ }
+ list = ""
+
+ if (found == no) {
+ printf ("Resource '%s' not found\n", lterm)
+ #
+ # FIXME -- Should we call the Registry here for a search????
+ #
+ svctype = "" ; bpass = "" ; ivorn = "" ; desc = "" ; url = ""
+ if (lalias != "") alias = lterm
+ if (lsname != "") sname = lterm
+ status = 1
+ goto done_
+ }
+ ;
+ }
+
+
+ if (lcmd == "list") { # LIST
+ list = tf
+ while (fscan (list, t, a, b, i, s, u, d) != EOF) {
+
+ if (lterm == "") {
+ # cl> regdb list bandpass=optical
+ if (ltype != "" && ltype != strlwr(t))
+ next
+ if (lbpass != "" && strstr (lbpass, strlwr(b)) == 0)
+ next
+
+ printf ("%-10s ", a)
+ printf ("%s ", t)
+ if (lbpass == "") printf ("%-8s ", b)
+ printf ("%s\n", d) | translit ("STDIN", ":", " ", collapse+)
+
+ } else {
+ # cl> regdb list <ivorn> | <alias> | <sname>
+
+ if (lterm == strlwr(a) || lterm == strlwr(b) ||
+ lterm == strlwr(i) || lterm == strlwr(s)) {
+ printf (" Alias: %s\n", a)
+ printf (" ShortName: %s\n", s)
+ printf (" Title: %s\n", d)
+ printf (" Type: %s\n", t)
+ printf (" Bandpass: %s\n", b)
+ printf (" Ivorn: %s\n", i)
+ printf (" SvcURL: %s\n", u)
+ #break;
+ }
+ }
+ }
+ list = ""
+
+ } else if (lcmd == "type") { # TYPE
+ print (t)
+
+ } else if (lcmd == "alias") { # ALIAS
+ if (lterm != "") {
+ print (a)
+ } else {
+ list = tf
+ while (fscan (list, t, a, b, i, s, u, d) != EOF) {
+ if ((lalias!="" && lalias == strlwr(a)) ||
+ (ldesc !="" && ldesc == strlwr(d)) ||
+ (livorn!="" && livorn == strlwr(i)) ||
+ (ltype != "" && ltype == strlwr(t)) ||
+ (lbpass != "" && lbpass == strlwr(b)) ||
+ (lsname!="" && lsname == strlwr(s)) ) {
+
+ if (verbose)
+ print (a)
+ else
+ alias = a
+ }
+ }
+ list = ""
+ }
+ svctype = "" ; bpass = "" ; ivorn = "" ; desc = "" ; url = ""
+ alias = "" ; sname = ""
+ } else if (lcmd == "bpass") { # BPASS
+ if (lterm != "") {
+ print (b)
+ } else {
+ list = tf
+ while (fscan (list, t, a, b, i, s, u, d) != EOF) {
+ if ((lalias!="" && lalias == strlwr(a)) ||
+ (ldesc !="" && ldesc == strlwr(d)) ||
+ (livorn!="" && livorn == strlwr(i)) ||
+ (ltype != "" && ltype == strlwr(t)) ||
+ (lbpass != "" && lbpass == strlwr(b)) ||
+ (lsname!="" && lsname == strlwr(s)) ) {
+
+ if (verbose)
+ print (b)
+ else
+ bpass = b
+ }
+ }
+ list = ""
+ }
+ svctype = "" ; bpass = "" ; ivorn = "" ; desc = "" ; url = ""
+ alias = "" ; sname = ""
+ } else if (lcmd == "ivorn") { # IVORN
+ if (lterm != "") {
+ print (i)
+ } else {
+ list = tf
+ while (fscan (list, t, a, b, i, s, u, d) != EOF) {
+ if ((lalias!="" && lalias == strlwr(a)) ||
+ (ldesc !="" && ldesc == strlwr(d)) ||
+ (livorn!="" && livorn == strlwr(i)) ||
+ (ltype != "" && ltype == strlwr(t)) ||
+ (lbpass != "" && lbpass == strlwr(b)) ||
+ (lsname!="" && lsname == strlwr(s)) ) {
+
+ if (verbose)
+ print (i)
+ else
+ ivorn = i
+ }
+ }
+ list = ""
+ }
+ svctype = "" ; bpass = "" ; ivorn = "" ; desc = "" ; url = ""
+ alias = "" ; sname = ""
+ } else if (lcmd == "sname") { # SNAME
+ if (lterm != "") {
+ print (s)
+ } else {
+ list = tf
+ while (fscan (list, t, a, b, i, s, u, d) != EOF) {
+ if ((lalias!="" && lalias == strlwr(a)) ||
+ (ldesc !="" && ldesc == strlwr(d)) ||
+ (livorn!="" && livorn == strlwr(i)) ||
+ (ltype != "" && ltype == strlwr(t)) ||
+ (lbpass != "" && lbpass == strlwr(b)) ||
+ (lsname!="" && lsname == strlwr(s)) ) {
+
+ if (verbose)
+ print (s)
+ else
+ sname = s
+ }
+ }
+ list = ""
+ }
+ svctype = "" ; bpass = "" ; ivorn = "" ; desc = "" ; url = ""
+ alias = "" ; sname = ""
+ } else if (lcmd == "url") { # URL
+ if (lterm != "") {
+ print (u)
+ } else {
+ list = tf
+ while (fscan (list, t, a, b, i, s, u, d) != EOF) {
+ if ((lalias!="" && lalias == strlwr(a)) ||
+ (ldesc !="" && ldesc == strlwr(d)) ||
+ (livorn!="" && livorn == strlwr(i)) ||
+ (ltype != "" && ltype == strlwr(t)) ||
+ (lbpass != "" && lbpass == strlwr(b)) ||
+ (lsname!="" && lsname == strlwr(s)) ) {
+
+ if (verbose)
+ print (u)
+ else
+ url = u
+ }
+ }
+ list = ""
+ }
+ svctype = "" ; bpass = "" ; ivorn = "" ; desc = "" ; url = ""
+ alias = "" ; sname = ""
+ } else if (lcmd == "desc") { # DESCRIPTION
+ if (lterm != "") {
+ print (d)
+ } else {
+ list = tf
+ while (fscan (list, t, a, b, i, s, u, d) != EOF) {
+ if ((lalias!="" && lalias == strlwr(a)) ||
+ (ldesc !="" && ldesc == strlwr(d)) ||
+ (livorn!="" && livorn == strlwr(i)) ||
+ (ltype != "" && ltype == strlwr(t)) ||
+ (lbpass != "" && lbpass == strlwr(b)) ||
+ (lsname!="" && lsname == strlwr(s)) ) {
+
+ if (verbose)
+ print (d)
+ }
+ }
+ list = ""
+ }
+ svctype = "" ; bpass = "" ; ivorn = "" ; desc = "" ; url = ""
+ alias = "" ; sname = ""
+
+
+ } else if (lcmd == "add") { # ADD TO DB
+
+ } else if (lcmd == "del") { # DELETE FROM DN
+
+ } else if (lcmd == "update") { # UPDATE DB
+
+ } else if (lcmd == "rename") { # RENAME ALIAS
+ # Need arg3
+
+
+ } else if (lcmd == "resolve" || lcmd == "search") { # RESOLVE
+ list = tf
+ status = 1
+ while (fscan (list, t, a, b, i, s, u, d) != EOF) {
+ if ((lalias != "" && lalias == strlwr(a)) ||
+ (lterm != "" && lterm == strlwr(a)) ||
+ (ldesc != "" && ldesc == strlwr(d)) ||
+ (livorn != "" && livorn == strlwr(i)) ||
+ (lterm == "") ||
+ (lsname!="" && lsname == strlwr(s)) ) {
+
+ if ((ltype != "" && ltype != strlwr(t)) ||
+ (lbpass != "" && lbpass != strlwr(b)) )
+ next
+
+ printf ("%s\n", d) | \
+ translit ("STDIN", ":", " ", collapse+) | scan (ldesc)
+ svctype = t ; alias = a ; bpass = b ; ivorn = i
+ sname = s ; url = u ; desc = ldesc
+ status = 0
+ break
+ }
+ }
+ list = ""
+
+ } else {
+ printf ("Command '%s' not found\n", lcmd)
+ status = 1
+ }
+
+done_:
+ type = ""
+ bandpass = ""
+
+ del (tf, verify-)
+end
diff --git a/vo/votools/regmetalist.cl b/vo/votools/regmetalist.cl
new file mode 100644
index 00000000..87a0d67b
--- /dev/null
+++ b/vo/votools/regmetalist.cl
@@ -0,0 +1,71 @@
+#{ REGMETALIST -- List the queryable metadata in a Registry resource.
+
+procedure regmetalist ()
+
+bool all = no
+
+begin
+
+ if (all) {
+ print ("Title")
+ print ("ShortName ")
+ print ("Identifier")
+ print ("ServiceURL")
+ print ("ReferenceURL")
+ print ("Description")
+ print ("Subject")
+ print ("ResourceType")
+ print ("Type")
+ print ("Creator")
+ print ("Facility")
+ print ("Instrument")
+ print ("Contributor")
+ print ("CoverageSpatial")
+ print ("CoverageTemporal")
+ print ("CoverageSpectral")
+ print ("ContentLevel")
+ print ("Version")
+
+ print (" ")
+ print (" ")
+ }
+
+ print(" COLUMNS FOR ALL RESOURCES COLUMNS FOR CONE SERVICES")
+ print(" dbid MaxSearchRadius")
+ print(" status MaxRecords")
+ print(" Identifier VOTableColumns")
+ print(" Title")
+ print(" ShortName")
+ print(" CurationPublisherName COLUMNS FOR SIAP SERVICES")
+ print(" CurationPublisherIdentifier VOTableColumns")
+ print(" CurationPublisherDescription ImageServiceType")
+ print(" CurationPublisherReferenceURL MaxqueryRegionSizeLat")
+ print(" CurationCreatorName MaxqueryRegionSizeLong")
+ print(" CurationCreatorLogo MaxImageExtentLat")
+ print(" CurationContributor MaxImageExtentLong")
+ print(" CurationDate MaxImageSizeLat")
+ print(" CurationVersion MaxImageSizeLong")
+ print(" CurationContactName MaxFileSize")
+ print(" CurationContactEmail MaxRecords")
+ print(" CurationContactAddress")
+ print(" CurationContactPhone")
+ print(" Subject COLUMNS FOR SKYNODE SERVICES")
+ print(" Description Compliance")
+ print(" ReferenceURL Latitude")
+ print(" Type Longitude")
+ print(" Facility PrimaryTable")
+ print(" Instrument PrimaryKey")
+ print(" ContentLevel MaxRecords")
+ print(" ModificationDate")
+ print(" ServiceURL")
+ print(" CoverageSpatial")
+ print(" CoverageSpectral")
+ print(" CoverageTemporal")
+ print(" CoverageRegionOfRegard")
+ print(" ResourceType")
+ print(" xml")
+ print(" harvestedfrom")
+ print(" harvestedfromDate")
+ print(" footprint")
+ print(" validationLevel")
+end
diff --git a/vo/votools/resdb.x b/vo/votools/resdb.x
new file mode 100644
index 00000000..3437b122
--- /dev/null
+++ b/vo/votools/resdb.x
@@ -0,0 +1,100 @@
+#
+# RESDB -- Utility routines to manage the local resource database
+
+
+bool procedure rdb_lookup (resdb, term, type, sname, ivorn, svcurl)
+
+char resdb[ARB] #i resource database
+char term[ARB] #i search term
+char type[ARB] #i service type
+char sname[ARB] #i short name
+char ivorn[ARB] #i ivorn string
+char svcurl[ARB] #i URL string
+
+char typ[SZ_FNAME], alias[SZ_FNAME], bpass[SZ_FNAME], line[SZ_LINE]
+char ivo[SZ_FNAME], shortname[SZ_FNAME], url[SZ_FNAME]
+int fd, ip, i, lnum
+
+int access(), open(), getline()
+bool streq()
+
+begin
+ if (access (resdb, 0, 0) == NO) {
+ call eprintf ("Error: cannot open resdb '%s'\n")
+ call pargstr (resdb)
+ return
+ }
+
+ call strlwr (term)
+
+ # Open the resource database
+ fd = open (resdb, READ_ONLY, TEXT_FILE)
+ for (lnum=0; getline (fd, line) != EOF; lnum=lnum+1) {
+
+ if (line[1] == '#' || line[1] == EOS || line[1] == '\n')
+ next
+
+ call aclrc (type, SZ_FNAME)
+ call aclrc (alias, SZ_FNAME)
+ call aclrc (bpass, SZ_FNAME)
+ call aclrc (ivo, SZ_FNAME)
+ call aclrc (url, SZ_FNAME)
+ call aclrc (shortname, SZ_FNAME)
+
+ ip = 1
+ for (i=1; line[ip] != ','; i=i+1) { # type string
+ typ[i] = line[ip]
+ ip = ip + 1
+ }
+ call strlwr (typ)
+ ip = ip + 1
+
+ for (i=1; line[ip] != ','; i=i+1) { # alias string
+ alias[i] = line[ip]
+ ip = ip + 1
+ }
+ call strlwr (alias)
+ ip = ip + 1
+
+ for (i=1; line[ip] != ','; i=i+1) { # bandpass string
+ bpass[i] = line[ip]
+ ip = ip + 1
+ }
+ call strlwr (typ)
+ ip = ip + 1
+
+ for (i=1; line[ip] != ','; i=i+1) { # ivorn string
+ ivo[i] = line[ip]
+ ip = ip + 1
+ }
+ call strlwr (typ)
+ ip = ip + 1
+
+ for (i=1; line[ip] != ','; i=i+1) { # ShortName string
+ shortname[i] = line[ip]
+ ip = ip + 1
+ }
+ call strlwr (typ)
+ ip = ip + 1
+
+ for (i=1; line[ip] != ','; i=i+1) { # URL string
+ url[i] = line[ip]
+ ip = ip + 1
+ }
+ call strlwr (typ)
+ ip = ip + 1
+
+
+ if (type[1] == EOS || typ[1] == type[1]) {
+ if (streq (alias, term)) {
+ call strcpy (shortname, sname, SZ_FNAME)
+ call strcpy (ivo, ivorn, SZ_FNAME)
+ call strcpy (url, svcurl, SZ_FNAME)
+ return (true)
+ }
+ }
+ }
+ call close (fd)
+
+ return (false)
+end
diff --git a/vo/votools/sbquery.par b/vo/votools/sbquery.par
new file mode 100644
index 00000000..9d509491
--- /dev/null
+++ b/vo/votools/sbquery.par
@@ -0,0 +1,7 @@
+ra,r,q,,0.,360.,RA (J2000 decimal degrees)
+dec,r,q,,-90.,90.,Dec (J2000 decimal degrees)
+sr,r,q,,0.,,Search radius (arcsec)
+epoch,s,h,"now",,,Epoch of query (JD)
+fields,s,h,"name,ra,dec,vmag,dra,ddec",,,Object attributes to print
+fmt,b,h,yes,,,Format output?
+status,i,h,,,,Service status code
diff --git a/vo/votools/sesame.par b/vo/votools/sesame.par
new file mode 100644
index 00000000..5910258d
--- /dev/null
+++ b/vo/votools/sesame.par
@@ -0,0 +1,12 @@
+target,s,q,"",,,"Target names to resolve"
+range,s,h,"",,,"Target range string"
+verbose,b,h,yes,,,"Print position to stdout?"
+long,b,h,no,,,"Long format?
+"
+pos,s,h,"",,,"Resolved position (sexagesimal string)"
+ra,r,h,,0.,360.,"Resolved RA (J2000 decimal degrees)"
+dec,r,h,,-90.,90.,"Resolved Dec (J2000 decimal degrees)"
+ra_err,r,h,,0.,360.,"Error on RA (arcsec)"
+dec_err,r,h,,-90.,90.,"Error on Dec (arcsec)"
+otype,s,h,"",,,"Resolved object type description"
+status,i,h,,,,"Service status code"
diff --git a/vo/votools/t_dalclient.x b/vo/votools/t_dalclient.x
new file mode 100644
index 00000000..dcc12eff
--- /dev/null
+++ b/vo/votools/t_dalclient.x
@@ -0,0 +1,140 @@
+#
+# DALCLIENT -- Call a VO DAL service and return the raw VOTable result.
+
+include <ctype.h>
+
+
+define SZ_URL 512
+define SZ_RESULT 16777216 # allow up to 16M of results
+
+
+procedure t_dalclient ()
+
+pointer sp, result, ip
+pointer fname, otype, svctype, svcurl, fmt
+double ra, dec, sr, rasz, decsz
+int out, reslen
+
+double clgetd()
+bool streq()
+
+int open()
+
+int vx_initVOClient()
+int vx_conecaller() # returns the length of the result
+int vx_siapcaller() # returns the length of the result
+int vx_rawurl() # returns the length of the result
+
+begin
+ # Allocate local storage.
+ call smark (sp)
+ call salloc (fmt, SZ_FNAME, TY_CHAR)
+ call salloc (fname, SZ_FNAME, TY_CHAR)
+ call salloc (otype, SZ_FNAME, TY_CHAR)
+ call salloc (svctype, SZ_FNAME, TY_CHAR)
+ call salloc (svcurl, SZ_URL, TY_CHAR)
+
+ # Clear string arrays.
+ call aclrs (Memc[fmt], SZ_FNAME)
+ call aclrs (Memc[fname], SZ_FNAME)
+ call aclrs (Memc[otype], SZ_FNAME)
+ call aclrs (Memc[svctype], SZ_FNAME)
+ call aclrs (Memc[svcurl], SZ_URL)
+
+
+ # Get the task parameters.
+ call clgstr ("svc_url", Memc[svcurl], SZ_URL) # service URL
+ call clgstr ("svc_type", Memc[svctype], SZ_FNAME) # service type
+ call clgstr ("output", Memc[fname], SZ_FNAME) # output fname|STDOUT
+
+
+ # We're a hidden task so we should only be called with a few
+ # known types. Make the rest of the parameter queries depending
+ # on the type of service we're calling.
+
+ if (streq (Memc[svctype], "cone")) {
+ ra = clgetd ("ra") # position (decimal deg)
+ dec = clgetd ("dec")
+ sr = clgetd ("sr")
+
+ } else if (streq ( Memc[svctype], "siap")) {
+ ra = clgetd ("ra") # position (decimal deg)
+ dec = clgetd ("dec")
+ rasz = clgetd ("xsize")
+ decsz = clgetd ("ysize")
+ call clgstr ("imfmt", Memc[fmt], SZ_FNAME)
+
+ } else if (streq ( Memc[svctype], "raw")) {
+ ; # no-op, got the service url above
+
+ } else {
+ call eprintf ("Invalid service type '%s'\n")
+ call pargstr (svctype)
+ call sfree (sp)
+ return
+ }
+ call clgstr ("otype", Memc[otype], SZ_FNAME) # "csv" or "votable"
+
+
+ # Allocate space for the result after we've verified the parameters.
+ call calloc (result, SZ_RESULT, TY_CHAR)
+
+ # Now call the requested service.
+ if (streq ("cone", Memc[svctype])) {
+ reslen = vx_coneCaller (Memc[svcurl], ra, dec, sr, Memc[otype],
+ Memc[result], SZ_RESULT)
+
+ } else if (streq ("siap", Memc[svctype])) {
+ reslen = vx_siapCaller (Memc[svcurl], ra, dec, rasz, decsz,
+ Memc[fmt], Memc[otype], Memc[result], SZ_RESULT)
+
+ } else if (streq ("raw", Memc[svctype])) {
+ # Initialize the VO Client interface.
+ if (vx_initVOClient("") == ERR) {
+ call clputi ("status", ERR)
+ call error (0, "Error initializing VO Client")
+ return
+ }
+
+ reslen = vx_rawurl (Memc[svcurl], Memc[result], SZ_RESULT)
+
+ call vx_closeVOClient (0)
+ }
+
+
+ # Skip leading whitespace and newlines.
+ for (ip = result; IS_WHITE(Memc[ip]) || Memc[ip] == '\n'; ) {
+ ip = ip + 1
+ reslen = reslen - 1
+ }
+
+
+ # Print the results to the screen.
+ if (reslen > 1) {
+ if (streq (Memc[fname], "STDOUT")) {
+ call write (STDOUT, Memc[ip], reslen)
+ call printf ("\n")
+ } else {
+ out = open (Memc[fname], NEW_FILE, TEXT_FILE)
+ call write (out, Memc[ip], reslen)
+ call fprintf (out, "\n")
+ call close (out)
+ }
+
+ if (reslen >= SZ_RESULT) {
+ call eprintf ("\n\nResults possibly truncated....\n\n")
+ call clputi ("status", ERR)
+ } else {
+ call clputi ("status", OK)
+ }
+
+ } else {
+ call eprintf ("No results from service\n")
+ call clputi ("status", ERR)
+ }
+ call clputi ("reslen", reslen)
+
+ # Clean up.
+ call mfree (result, TY_CHAR)
+ call sfree (sp)
+end
diff --git a/vo/votools/t_dispname.x b/vo/votools/t_dispname.x
new file mode 100644
index 00000000..fbf7f37d
--- /dev/null
+++ b/vo/votools/t_dispname.x
@@ -0,0 +1,49 @@
+include <fset.h>
+include <gset.h>
+include <imhdr.h>
+include <imset.h>
+
+define TV_NLINES 128
+
+
+# T_DISPNAME -- Get the displayed image name.
+
+procedure t_dispname ()
+
+pointer image # pointer to name of the image
+
+pointer sp, im, iw, tmpname
+int frame, wcs_status
+bool verbose
+
+int clgeti(), imstati()
+bool clgetb()
+pointer imd_mapframe(), iw_open()
+
+begin
+ # Set standard output to flush on newline.
+ call fseti (STDOUT, F_FLUSHNL, YES)
+
+ # Allocate working space.
+ call smark (sp)
+ call salloc (image, SZ_FNAME, TY_CHAR)
+ call salloc (tmpname, SZ_FNAME, TY_CHAR)
+
+ frame = clgeti ("frame")
+ verbose = clgetb ("verbose")
+
+
+ # Open the frame as an image.
+ im = imd_mapframe (frame, READ_WRITE, YES)
+ iw = iw_open (im, frame, Memc[image], SZ_FNAME, wcs_status)
+
+ call clpstr ("name", Memc[image])
+ if (verbose) {
+ call printf ("%s\n")
+ call pargstr (Memc[image])
+ }
+
+ call iw_close (iw)
+ call imunmap (im)
+ call sfree (sp)
+end
diff --git a/vo/votools/t_makewcs.x b/vo/votools/t_makewcs.x
new file mode 100644
index 00000000..593027eb
--- /dev/null
+++ b/vo/votools/t_makewcs.x
@@ -0,0 +1,334 @@
+include <error.h>
+
+# MAKEWCS -- Task to write the WCS information into a header of an image
+# subset from the scanned plate catalog.
+
+procedure t_makewcs()
+
+int imtopenp(), imtgetim()
+int list
+char image[SZ_FNAME]
+bool verbose, clgetb()
+
+begin
+ list = imtopenp ("infiles")
+ verbose = clgetb("verbose")
+ while (imtgetim(list, image, SZ_FNAME) != EOF) {
+ call makecd(image)
+ if (verbose) {
+ call printf (" WCS for %s\n")
+ call pargstr(image)
+ call flush(STDOUT)
+ }
+ }
+
+end
+
+include <imhdr.h>
+include <math.h>
+
+define SZ_KEYWORD 8
+
+# MAKECD -- Procedure to calculate the WCS values for a subset of a
+# scanned plate that contains a general plate solution.
+#
+# Calculates CRPIX, CRVAL and CD matrix from the information in the GSSS
+# header wich consist on the positions of the lower left corner of the
+# subimage (CNPIX1, CNPIX2) w/r to the lower left corner of the scanned plate.
+# From here create a grid of 100x100 points and do a local solution to
+# the CD values and translate the reference position to the center of the
+# subimage.
+#
+
+procedure makecd(image)
+
+char image[SZ_FNAME]
+
+double amdx[20], amdy[20] # Plate Soln.coeff.
+double plate_cen_x, plate_cen_y # center position (microns)
+double plate_cen_ra, plate_cen_dec # in radians
+double x_pixel_size, y_pixel_size # step size (microns)
+double plate_scale # arcsec/mm
+int ra_h, ra_m # RA hours, minutes
+double ra_s # RA seconds
+char dec_sign[1] #
+int dec_d, dec_m # DEC degrees, minutes
+double dec_s # DEC seconds
+double object_mag, object_col # Magnitud, color for object
+double im_x_center_pix, im_y_center_pix # Pixel position of image center
+ # w/r to the original scanned plate
+int xcorner, ycorner # Lower left position of image w/r to
+ # original scanned plate
+int xsize, ysize # Naxis1, naxis2
+real crpix1, crpix2
+double crval1, crval2
+double cdmatx[4]
+double imgetd()
+real imgetr()
+int imgeti()
+char parname[8]
+int i
+pointer im
+int immap(), imaccf()
+errchk imgetd, imgeti
+
+begin
+ im = immap (image, READ_WRITE, 0)
+
+ # See if image header has the General Plate solution.
+ if (imaccf(im,"PPO3 ") == NO)
+ call error(0,"No Plate solution available in header")
+
+ # If we have an old DSS image (i.e. the one with the CRPIX), rename
+ # this keyword to CNPIX and proceed.
+
+ if (imaccf(im,"CRPIX1") == YES ) {
+ if (imaccf(im,"CRVAL1") == YES) {
+ if (imaccf(im,"CD1_1") == NO ){
+ # This is the case when we have CRPIX1, CRVAL1 and no CD1_1
+ # so, proceed to calculate the WCS again.
+ crpix1 = imgetr (im, "CRPIX1")
+ call imdelf (im, "CRPIX1")
+ call imaddr (im, "CNPIX1", crpix1)
+ crpix2 = imgetr (im, "CRPIX2")
+ call imdelf (im, "CRPIX2")
+ call imaddr (im, "CNPIX2", crpix2)
+ }
+ } else {
+ crpix1 = imgetr (im, "CRPIX1")
+ call imdelf (im, "CRPIX1")
+ call imaddr (im, "CNPIX1", crpix1)
+ crpix2 = imgetr (im, "CRPIX2")
+ call imdelf (im, "CRPIX2")
+ call imaddr (im, "CNPIX2", crpix2)
+ }
+ }
+ if (imaccf(im,"CNPIX1") == NO )
+ call error(0,"Lower left position CNPIX(1,2) not found")
+ plate_cen_x = imgetd(im, "PPO3 ")
+ plate_cen_y = imgetd(im, "PPO6 ")
+ x_pixel_size = imgetd(im, "XPIXELSZ")
+ y_pixel_size = imgetd(im, "YPIXELSZ")
+ plate_scale = imgetd(im, "PLTSCALE")
+ ra_h = imgeti (im, "PLTRAH ")
+ ra_m = imgeti (im, "PLTRAM ")
+ ra_s = imgetd (im, "PLTRAS ")
+ call imgstr(im, "PLTDECSN", dec_sign, 1)
+ dec_d = imgeti (im, "PLTDECD ")
+ dec_m = imgeti (im, "PLTDECM ")
+ dec_s = imgetd (im, "PLTDECS ")
+
+ plate_cen_ra = DEGTORAD ((ra_h + ra_m/60.0d0 + ra_s/3600.0)*15.0d0)
+ plate_cen_dec = DEGTORAD (dec_d + dec_m/60.0d0 + dec_s/3600.0d0)
+ if (dec_sign[1] == '-')
+ plate_cen_dec = -plate_cen_dec
+
+ # Get general plate solution coefficients
+ do i = 1, 20 {
+ call sprintf(parname, SZ_LINE, "AMDX%d")
+ call pargi(i)
+ amdx[i] = imgetd (im, parname)
+ }
+ do i = 1, 20 {
+ call sprintf(parname, SZ_LINE, "AMDY%d")
+ call pargi(i)
+ amdy[i] = imgetd (im, parname)
+ }
+
+ if (imaccf(im, "CNPIX1") == YES) {
+ xcorner = imgetr (im, "CNPIX1")
+ ycorner = imgetr (im, "CNPIX2")
+ } else
+ call error(0,"CNPIXs keyword found")
+
+ xsize = IM_LEN(im,1)
+ ysize = IM_LEN(im,2)
+ crpix1 = xsize/2.
+ crpix2 = ysize/2.
+
+ # Center of image w/r to original lower left corner of
+ # scanned plate
+ im_x_center_pix = xcorner + (xsize/2.) - 0.5
+ im_y_center_pix = ycorner + (ysize/2.) - 0.5
+
+ # Calculate equatorial coordinates for the center of subset giving
+ # the complete plate solution w/r to the original lower left corner
+ call ccgseq (plate_cen_ra,
+ plate_cen_dec,
+ plate_cen_x,
+ plate_cen_y,
+ x_pixel_size,
+ y_pixel_size,
+ plate_scale,
+ amdx,
+ amdy,
+ im_x_center_pix,
+ im_y_center_pix,
+ object_mag,
+ object_col,
+ crval1,
+ crval2)
+
+
+ # calculate CD matrix values for the input subset from the original
+ # plate solution.
+ call calcds (plate_cen_ra,
+ plate_cen_dec,
+ plate_cen_x,
+ plate_cen_y,
+ xcorner,
+ ycorner,
+ x_pixel_size,
+ y_pixel_size,
+ plate_scale,
+ xsize,
+ ysize,
+ crval1,
+ crval2,
+ amdx,
+ amdy,
+ cdmatx)
+
+ # Now update the image header
+
+ iferr (call addkf (im, "CTYPE1", 8, TY_CHAR,
+ "r.a. in tangent plane proyection"))
+ ;
+ call impstr (im, "CTYPE1", "RA---TAN")
+
+ iferr (call addkf (im, "CTYPE2", 8, TY_CHAR,
+ "dec. in tangent plane proyection"))
+ ;
+ call impstr (im, "CTYPE2", "DEC--TAN")
+
+ iferr (call addkf (im, "CRPIX1", 1, TY_REAL,
+ "reference pixel of first axis"))
+ ;
+ call imputr (im, "CRPIX1", crpix1)
+
+ iferr (call addkf (im, "CRPIX2", 1, TY_REAL,
+ "reference pixel of second axis"))
+ ;
+ call imputr (im, "CRPIX2", crpix2)
+
+ iferr (call addkf (im, "CRVAL1", 1, TY_REAL,
+ "r.a. at pixel crpix1 in decimal degrees"))
+ ;
+ call imputd (im, "CRVAL1", RADTODEG(crval1))
+
+ iferr (call addkf (im, "CRVAL2", 1, TY_REAL,
+ "dec. at pixel crpix2 in decimal degrees"))
+ ;
+ call imputd (im, "CRVAL2", RADTODEG(crval2))
+
+ # now add the new CD values
+ iferr (call addkf (im, "CD1_1", 1, TY_REAL,
+ "Change in r.a. per pixel along the first axis"))
+ ;
+ else
+ call addkf (im, "", 1, TY_REAL,
+ "evaluated at the reference pixel")
+ call imputd (im, "CD1_1", cdmatx[1])
+
+ iferr (call addkf (im, "CD1_2", 1, TY_REAL,
+ "ditto along the second axis"))
+ ;
+ call imputd (im, "CD1_2", cdmatx[2])
+
+ iferr (call addkf (im, "CD2_1", 1, TY_REAL,
+ "Change in dec. per pixel along the first axis"))
+ ;
+ else
+ call addkf (im, "", 1, TY_REAL,
+ "evaluated at the reference pixel")
+ call imputd (im, "CD2_1", cdmatx[3])
+
+ iferr (call addkf (im, "CD2_2", 1, TY_REAL,
+ "ditto along the second axis"))
+ ;
+ call imputd (im, "CD2_2", cdmatx[4])
+
+ call imunmap (im)
+end
+
+include <syserr.h>
+include <imhdr.h>
+include <imio.h>
+include <mach.h>
+
+define SZ_VALSTR 80
+# ADDKF -- Add a user field to the image header. It is an error if the named
+# field already exists.
+
+procedure addkf (im, key, lenv, datatype, comment)
+
+pointer im # image descriptor
+char key[SZ_KEYWORD] # name of the new parameter
+int lenv # keyword value length
+int datatype # datatype of parameter
+char comment[SZ_VALSTR] # comment describing new parameter
+
+int max_lenuserarea, diff, slen
+pointer sp, keyname, rp, ua, op
+int idb_kwlookup(), idb_findrecord(), strlen()
+errchk syserrs
+
+begin
+ call smark (sp)
+ call salloc (keyname, SZ_FNAME, TY_CHAR)
+ call strcpy (key, Memc[keyname], SZ_FNAME)
+
+ # Check for a redefinition.
+ if ((idb_kwlookup (key) > 0) || (idb_findrecord (im, key, rp) > 0))
+ call syserrs (SYS_IDBREDEF, key)
+
+ # Open the user area string for appending. If the user area is not
+ # empty the last character must be the newline record delimiter,
+ # else the new record we add will be invalid.
+
+ max_lenuserarea = (LEN_IMDES + IM_LENHDRMEM(im) - IMU + 1) * SZ_STRUCT
+ ua = IM_USERAREA(im)
+
+ for (rp=ua; Memc[rp] != EOS; rp=rp+1)
+ ;
+ if (rp - ua + SZ_VALSTR + 1 >= max_lenuserarea)
+ call syserrs (SYS_IDBOVFL, key)
+
+ if (rp > ua && Memc[rp-1] != '\n') {
+ Memc[rp] = '\n'
+ rp = rp + 1
+ }
+
+ # Append the new record with an uninitialized value field. Keyword
+ # value pairs are encoded in FITS format.
+
+ do op = rp, rp + SZ_VALSTR # blank fill card
+ Memc[op] = ' '
+
+ # Add the "= 'value' / comment".
+ slen = strlen(Memc[keyname])
+ call amovc (Memc[keyname], Memc[rp], slen)
+ if (slen != 0)
+ Memc[rp+9-1] = '='
+ if (datatype == TY_CHAR) {
+ Memc[rp+11-1] = '\''
+ Memc[rp+20-1] = '\''
+ }
+
+ # Add the comment field.
+ diff = lenv - 20
+ if (diff > 0) {
+ Memc[rp+34-1+diff] = '/'
+ call amovc (comment, Memc[rp+36-1+diff],
+ min (SZ_VALSTR-36+1-diff, strlen(comment)))
+ } else {
+ Memc[rp+32-1] = '/'
+ call amovc (comment, Memc[rp+34-1],
+ min (SZ_VALSTR-34+1, strlen(comment)))
+ }
+ # Terminate the card.
+ Memc[rp+SZ_VALSTR] = '\n'
+ Memc[rp+SZ_VALSTR+1] = EOS
+
+ call sfree (sp)
+end
diff --git a/vo/votools/t_sbquery.x b/vo/votools/t_sbquery.x
new file mode 100644
index 00000000..cba977ef
--- /dev/null
+++ b/vo/votools/t_sbquery.x
@@ -0,0 +1,406 @@
+#
+
+# SBQUERY -- Call the IMCCE SkyBoT (Sky Bodies Tracker) service to locate
+# minor planets within a radius at a given position and epoch.
+#
+
+include <time.h>
+
+
+# Possible fields.
+define SB_FIELDS "|num|name|class|ra|dec|vmag|poserr|cdist|dra|ddec|\
+ |dgeo|dhelio|px|py|pz|vx|vy|vz|jd0|"
+
+define SB_NFIELDS 20 # accounts for the newline
+
+define SB_KNUM "NUM" # keywords
+define SB_KNAME "NAME"
+define SB_KCLASS "CLASS"
+define SB_KRA "RA"
+define SB_KDEC "DEC"
+define SB_KVMAG "VMAG"
+define SB_KPOSERR "POSERR"
+define SB_KCDIST "CDIST"
+define SB_KDRA "DRA"
+define SB_KDDEC "DDEC"
+define SB_KDGEO "DGEO"
+define SB_KDHELIO "DHELIO"
+define SB_KPX "PX"
+define SB_KPY "PY"
+define SB_KPZ "PZ"
+define SB_KVX "VX"
+define SB_KVY "VY"
+define SB_KVZ "VZ"
+define SB_KJD0 "JD0"
+
+define SB_LNUM "number" # attribute keywords
+define SB_LNAME "name"
+define SB_LCLASS "class"
+define SB_LRA "ra"
+define SB_LDEC "dec"
+define SB_LVMAG "vmag"
+define SB_LPOSERR "poserr"
+define SB_LCDIST "cdist"
+define SB_LDRA "dra"
+define SB_LDDEC "ddec"
+define SB_LDGEO "dgeo"
+define SB_LDHELIO "dhelio"
+define SB_LPX "px"
+define SB_LPY "py"
+define SB_LPZ "pz"
+define SB_LVX "vx"
+define SB_LVY "vy"
+define SB_LVZ "vz"
+define SB_LJD0 "jd0"
+
+define SB_FNUM 1 # field numbers
+define SB_FNAME 2
+define SB_FCLASS 3
+define SB_FRA 4
+define SB_FDEC 5
+define SB_FVMAG 6
+define SB_FPOSERR 7
+define SB_FCDIST 8
+define SB_FDRA 9
+define SB_FDDEC 10
+# NL
+define SB_FDGEO 12
+define SB_FDHELIO 13
+define SB_FPX 14
+define SB_FPY 15
+define SB_FPZ 16
+define SB_FVX 17
+define SB_FVY 18
+define SB_FVZ 19
+define SB_FJD0 20
+
+define SB_FREAL "%-10.4f"
+define SB_FWSTRING "%-12s"
+define SB_FSTRING "%-10s"
+define SB_FINTEGER "%10d"
+define SB_FSEX "%-012h"
+
+
+
+procedure t_sbquery ()
+
+pointer sp, fields, fieldstr, epoch
+double ra, dec, sr, ut, jd_epoch
+int sb, nobjs, nfields, i, gmtco
+int tm[LEN_TMSTRUCT]
+bool fmt
+long otime, ntime
+
+real clgetr()
+bool clgetb(), streq()
+int vx_initVOClient(), vx_skybotnobjs(), vx_skybot()
+int sb_fields()
+long clktime()
+double ast_date_to_julday()
+
+begin
+ call smark (sp)
+ call salloc (epoch, SZ_FNAME, TY_CHAR)
+ call salloc (fields, SZ_LINE, TY_INT)
+ call salloc (fieldstr, SZ_LINE, TY_CHAR)
+
+ call aclrs (Memc[epoch], SZ_FNAME)
+ call aclri (Memc[fields], SZ_LINE)
+ call aclrs (Memc[fieldstr], SZ_LINE)
+
+
+ ra = clgetr ("ra") # Get the parameters
+ dec = clgetr ("dec")
+ sr = clgetr ("sr")
+ call clgstr ("epoch", Memc[epoch], SZ_LINE)
+ if (streq (Memc[epoch], "now")) {
+ # Handle the special case of 'now', i.e. find out what time it is.
+ call zgmtco (gmtco)
+ call brktime (clktime(0)+gmtco, tm)
+ ut = real (TM_HOUR(tm)) +
+ (real(TM_MIN(tm))/60.) +
+ (real(TM_SEC(tm))/3600.)
+ jd_epoch = ast_date_to_julday (TM_YEAR(tm), TM_MONTH(tm),
+ TM_MDAY(tm), ut)
+
+ } else {
+ # Convert the user-supplied epoch.
+ call sscan (Memc[epoch])
+ call gargd (jd_epoch)
+ }
+ call clgstr ("fields", Memc[fieldstr], SZ_LINE)
+ fmt = clgetb ("fmt")
+
+ if (vx_initVOClient("") == ERR) { # Initialize
+ call clputi ("status", ERR)
+ return
+ }
+
+ if (fmt) {
+ call printf ("#\n# Search Terms: ")
+ call printf ("Position=(%H,%h) sr=%.1f epoch=%.4f\n")
+ call pargd (ra)
+ call pargd (dec)
+ call pargd (sr)
+ call pargd (jd_epoch)
+ call printf ("#\n")
+ call flush (STDOUT)
+ }
+
+ # Call the service
+ otime = clktime (0)
+ sb = vx_skybot (ra, dec, sr, sr, jd_epoch)
+ ntime = clktime (otime)
+
+ if (sb != NULL) {
+ nobjs = vx_skybotnobjs (sb)
+ if (fmt) {
+ call printf ("# Found %d objects in %d seconds\n#\n")
+ call pargi (nobjs)
+ call pargl (ntime)
+ }
+ } else {
+ call eprintf ("Error in calling SkyBoT service\n")
+ call sfree (sp)
+ call clputi ("status", ERR)
+ call vx_closeVOClient (0)
+ return
+ }
+
+ # Get the selected fields.
+ nfields = sb_fields (Memc[fieldstr], Memi[fields], SB_NFIELDS)
+ if (nfields <= 0) {
+ call vx_closeVOClient (0)
+ call sfree (sp)
+ return
+ }
+
+ # Finally, print the table of results.
+ if (fmt)
+ call sb_pheader (Memi[fields], nfields)
+ for (i=0; i < nobjs; i=i+1)
+ call sb_print (sb, i, Memi[fields], nfields)
+
+ call vx_closeVOClient (0)
+
+ call clputi ("status", OK)
+end
+
+
+# SB_FIELDS -- Procedure to decode the fields string into a list of the
+# fields to be printed.
+
+int procedure sb_fields (fieldstr, fields, max_nfields)
+
+char fieldstr[ARB] #I string containing the list of fields
+int fields[ARB] #O fields array
+int max_nfields #I maximum number of fields
+
+int nfields, flist, field
+pointer sp, fname
+int fntopenb(), fntgfnb(), strdic()
+
+begin
+ nfields = 0
+
+ call smark (sp)
+ call salloc (fname, SZ_FNAME, TY_CHAR)
+
+ flist = fntopenb (fieldstr, NO)
+ while (fntgfnb (flist, Memc[fname], SZ_FNAME) != EOF &&
+ (nfields < max_nfields)) {
+ field = strdic (Memc[fname], Memc[fname], SZ_FNAME, SB_FIELDS)
+ if (field == 0)
+ next
+ nfields = nfields + 1
+ fields[nfields] = field
+ }
+ call fntclsb (flist)
+
+ call sfree (sp)
+
+ return (nfields)
+end
+
+
+# SB_PHEADER -- Print the banner fields.
+
+procedure sb_pheader (fields, nfields)
+
+int fields[ARB] # fields to be printed
+int nfields # number of fields
+
+int i
+
+begin
+ call printf ("#")
+ do i = 1, nfields {
+
+ switch (fields[i]) {
+ case SB_FNUM:
+ call printf (SB_FSTRING)
+ call pargstr (SB_KNUM)
+ case SB_FNAME:
+ call printf (SB_FWSTRING)
+ call pargstr (SB_KNAME)
+ case SB_FCLASS:
+ call printf (SB_FSTRING)
+ call pargstr (SB_KCLASS)
+ case SB_FRA:
+ call printf (SB_FWSTRING)
+ call pargstr (SB_KRA)
+ case SB_FDEC:
+ call printf (SB_FWSTRING)
+ call pargstr (SB_KDEC)
+ case SB_FVMAG:
+ call printf (SB_FSTRING)
+ call pargstr (SB_KVMAG)
+ case SB_FPOSERR:
+ call printf (SB_FSTRING)
+ call pargstr (SB_KPOSERR)
+ case SB_FCDIST:
+ call printf (SB_FSTRING)
+ call pargstr (SB_KCDIST)
+ case SB_FDRA:
+ call printf (SB_FSTRING)
+ call pargstr (SB_KDRA)
+ case SB_FDDEC:
+ call printf (SB_FSTRING)
+ call pargstr (SB_KDDEC)
+ case SB_FDGEO:
+ call printf (SB_FSTRING)
+ call pargstr (SB_KDGEO)
+ case SB_FDHELIO:
+ call printf (SB_FSTRING)
+ call pargstr (SB_KDHELIO)
+ case SB_FPX:
+ call printf (SB_FSTRING)
+ call pargstr (SB_KPX)
+ case SB_FPY:
+ call printf (SB_FSTRING)
+ call pargstr (SB_KPY)
+ case SB_FPZ:
+ call printf (SB_FSTRING)
+ call pargstr (SB_KPZ)
+ case SB_FVX:
+ call printf (SB_FSTRING)
+ call pargstr (SB_KVX)
+ case SB_FVY:
+ call printf (SB_FSTRING)
+ call pargstr (SB_KVY)
+ case SB_FVZ:
+ call printf (SB_FSTRING)
+ call pargstr (SB_KVZ)
+ case SB_FJD0:
+ call printf (SB_FSTRING)
+ call pargstr (SB_KJD0)
+ }
+ }
+ call printf ("\n")
+ call flush (STDOUT)
+end
+
+
+# SB_PRINT -- Print the banner fields.
+
+procedure sb_print (sb, objnum, fields, nfields)
+
+int sb # skybot pointer
+int objnum # skybot result number
+int fields[ARB] # fields to be printed
+int nfields # number of fields
+
+int i, len
+char buf[SZ_LINE]
+double dval
+
+int vx_skybotstr()
+double vx_skybotdbl()
+
+begin
+ do i = 1, nfields {
+ call aclrs (buf, SZ_LINE)
+
+ switch (fields[i]) {
+ case SB_FNUM:
+ len = vx_skybotstr (sb, SB_LNUM, objnum, buf, SZ_FNAME)
+ call printf (SB_FSTRING)
+ call pargstr (buf)
+ case SB_FNAME:
+ len = vx_skybotstr (sb, SB_LNAME, objnum, buf, SZ_FNAME)
+ call printf (SB_FWSTRING)
+ call pargstr (buf)
+ case SB_FCLASS:
+ len = vx_skybotstr (sb, SB_LCLASS, objnum, buf, SZ_FNAME)
+ call printf (SB_FSTRING)
+ call pargstr (buf)
+
+ case SB_FRA:
+ dval = vx_skybotdbl (sb, SB_LRA, objnum)
+ call printf (SB_FSEX)
+ call pargd (dval)
+ case SB_FDEC:
+ dval = vx_skybotdbl (sb, SB_LDEC, objnum)
+ call printf (SB_FSEX)
+ call pargd (dval)
+ case SB_FVMAG:
+ dval = vx_skybotdbl (sb, SB_LVMAG, objnum)
+ call printf (SB_FREAL)
+ call pargd (dval)
+ case SB_FPOSERR:
+ dval = vx_skybotdbl (sb, SB_LPOSERR, objnum)
+ call printf (SB_FREAL)
+ call pargd (dval)
+ case SB_FCDIST:
+ dval = vx_skybotdbl (sb, SB_LCDIST, objnum)
+ call printf (SB_FREAL)
+ call pargd (dval)
+ case SB_FDRA:
+ dval = vx_skybotdbl (sb, SB_LDRA, objnum)
+ call printf (SB_FREAL)
+ call pargd (dval)
+ case SB_FDDEC:
+ dval = vx_skybotdbl (sb, SB_LDDEC, objnum)
+ call printf (SB_FREAL)
+ call pargd (dval)
+ case SB_FDGEO:
+ dval = vx_skybotdbl (sb, SB_LDGEO, objnum)
+ call printf (SB_FREAL)
+ call pargd (dval)
+ case SB_FDHELIO:
+ dval = vx_skybotdbl (sb, SB_LDHELIO, objnum)
+ call printf (SB_FREAL)
+ call pargd (dval)
+ case SB_FPX:
+ dval = vx_skybotdbl (sb, SB_LPX, objnum)
+ call printf (SB_FREAL)
+ call pargd (dval)
+ case SB_FPY:
+ dval = vx_skybotdbl (sb, SB_LPY, objnum)
+ call printf (SB_FREAL)
+ call pargd (dval)
+ case SB_FPZ:
+ dval = vx_skybotdbl (sb, SB_LPZ, objnum)
+ call printf (SB_FREAL)
+ call pargd (dval)
+ case SB_FVX:
+ dval = vx_skybotdbl (sb, SB_LVX, objnum)
+ call printf (SB_FREAL)
+ call pargd (dval)
+ case SB_FVY:
+ dval = vx_skybotdbl (sb, SB_LVY, objnum)
+ call printf (SB_FREAL)
+ call pargd (dval)
+ case SB_FVZ:
+ dval = vx_skybotdbl (sb, SB_LVZ, objnum)
+ call printf (SB_FREAL)
+ call pargd (dval)
+ case SB_FJD0:
+ dval = vx_skybotdbl (sb, SB_LJD0, objnum)
+ call printf (SB_FREAL)
+ call pargd (dval)
+ }
+ }
+ call printf ("\n")
+ call flush (STDOUT)
+end
diff --git a/vo/votools/t_sesame.x b/vo/votools/t_sesame.x
new file mode 100644
index 00000000..61a40bce
--- /dev/null
+++ b/vo/votools/t_sesame.x
@@ -0,0 +1,135 @@
+#
+# SESAME -- Call the Sesame web service to resovle an object name to
+# (J2000) Equatorial coordinates using the VO Client interface.
+
+
+define NRANGES 64
+
+procedure t_sesame ()
+
+char target[SZ_FNAME], root[SZ_FNAME], tname[SZ_FNAME], range_str[SZ_FNAME]
+char pos[SZ_LINE], otype[SZ_LINE], ip, op
+double ra, dec, ra_err, dec_err
+int sr, len, ntargets, nobjs, nvalues, number, list, status
+int ranges[2,NRANGES]
+bool verbose, full
+
+int vx_initVOClient()
+int vx_nameresolver(), vx_resolverpos(), vx_resolverotype()
+double vx_resolverra(), vx_resolverdec()
+double vx_errresolverra(), vx_errresolverdec()
+
+int fntopnb(), fntgfnb(), fntlenb()
+int decode_ranges(), get_next_number()
+bool clgetb(), streq()
+
+begin
+ status = OK
+
+ # Get the target name and verbose parameter.
+ call clgstr ("target", target, SZ_FNAME)
+ call clgstr ("range", range_str, SZ_FNAME)
+ verbose = clgetb ("verbose")
+ full = clgetb ("long")
+
+
+ # Initialize the VO Client interface.
+ if (vx_initVOClient("") == ERR) {
+ call clputi ("status", ERR)
+ call error (0, "Error initializing VO Client")
+ return
+ }
+
+ # Encode spaces in the object name.
+ for (ip=1; target[ip] != EOS; ip=ip+1) {
+ if (target[ip] == ' ')
+ target[ip] = '+'
+ }
+
+ # Open the target list.
+ list = fntopnb (target, NO)
+ nobjs = fntlenb (list)
+ ntargets = nobjs
+
+ # Loop over the object list.
+ while (nobjs > 0) {
+
+ # Get the target name from the list.
+ if (fntgfnb (list, root, SZ_FNAME) == EOF)
+ break;
+
+ # Initialize the range string decoding.
+ nvalues = 0
+ if (range_str[1] != EOS) {
+ if (decode_ranges (range_str, ranges, NRANGES, nvalues)==ERR) {
+ call eprintf ("Error decoding range string '%s'\n")
+ call pargstr (range_str)
+ break
+ }
+ }
+
+ # Loop over the range string.
+ while (nvalues == 0 || get_next_number (ranges, number) != EOF) {
+
+ call strcpy (root, tname, SZ_FNAME) # single target
+ if (nvalues > 0) { # target list
+ call sprintf (tname, SZ_FNAME, "%s%d")
+ call pargstr (root)
+ call pargi (number)
+ }
+
+ # Call the service and get the results.
+ sr = vx_nameresolver (tname)
+
+ len = vx_resolverpos (sr, pos, SZ_LINE)
+ ra = vx_resolverra (sr)
+ dec = vx_resolverdec (sr)
+ ra_err = vx_errresolverra (sr) / 1000. # convert to arcsec
+ dec_err = vx_errresolverdec (sr) / 1000.
+ len = vx_resolverotype (sr, otype, SZ_LINE)
+
+ if (streq (pos, "nul") && streq (otype, "nul"))
+ status = ERR
+
+ # If we're not being quiet, print the RA and Dec so they may be
+ # easily scanned into variables from a script.
+ if (verbose) {
+ if (status == ERR) # no resolution
+ call strcpy ("INDEF INDEF", pos, SZ_FNAME)
+
+ if (full) {
+ call printf ("%s %s %.3f %.3f %s\n")
+ call pargstr (tname)
+ call pargstr (pos)
+ call pargd (ra_err)
+ call pargd (dec_err)
+ call pargstr (otype)
+ } else {
+ call printf ("%s\n")
+ call pargstr (pos)
+ }
+ }
+
+ if (nvalues == 0)
+ break
+ }
+ ntargets = ntargets + nvalues
+
+ nobjs = nobjs - 1
+ }
+
+ # Save the results to the parameter file in any case.
+ if (ntargets == 1) {
+ call clpstr ("pos", pos)
+ call clputd ("ra", ra)
+ call clputd ("dec", dec)
+ call clputd ("ra_err", ra_err)
+ call clputd ("dec_err", dec_err)
+ call clpstr ("otype", otype)
+ } else
+ status = ERR
+
+ call clputi ("status", status)
+
+ call vx_closeVOClient (0)
+end
diff --git a/vo/votools/t_vodata.x b/vo/votools/t_vodata.x
new file mode 100644
index 00000000..e6b3de58
--- /dev/null
+++ b/vo/votools/t_vodata.x
@@ -0,0 +1,736 @@
+#
+# VODATA -- Query and Access VO Data Services
+
+include <ctype.h>
+include <error.h>
+include <imhdr.h>
+include <mwset.h>
+include <tbset.h>
+
+
+define DEBUG FALSE
+define DEF_BASE "res"
+
+define BP_NAMES "|any|radio|millimeter|infrared|optical|uv|x-ray|gamma-ray|"
+define BP_ANY 1
+define BP_RADIO 2
+define BP_MILLIMETER 3
+define BP_INFRARED 4
+define BP_OPTICAL 5
+define BP_UV 6
+define BP_XRAY 7
+define BP_GAMMARAY 8
+
+define TYP_NAMES "|any|catalog|image|spectral|"
+define TYP_ANY 1
+define TYP_CATALOG 2
+define TYP_IMAGE 3
+define TYP_SPECTRAL 4
+
+define OUT_FMTS "|ascii|csv|tsv|html|raw|fits|"
+define FMT_ASCII 1
+define FMT_CSV 2
+define FMT_TSV 3
+define FMT_HTML 4
+define FMT_RAW 5
+define FMT_FITS 6
+
+
+# resources list of Resources to query (or "" or ServiceURL)
+# objects list of Object names/images to query (or VOTable of positions)
+# ra RA of query position
+# dec Dec of query position
+# sr Search radius (degrees, or min or sec)
+#
+# bandpass bandpass constraint (radio|infrared|optical|uv|xray|gamma)
+# type service type to query (catalog|image)
+# count print only a count of the results
+# all query all data sources
+# extract extract positions and URLs
+#
+# format output format (|fits|ascii|csv|tsv|html|raw)
+# output output filename (or 'samp' to broadcast table)
+# sequential use sequential file numbers (or object name)
+#
+# verbose verbose output?
+#
+
+
+procedure t_vodata ()
+
+char resources[SZ_LINE], objects[SZ_FNAME]
+char format[SZ_FNAME], verb[SZ_FNAME], output[SZ_FNAME]
+char bandpass[SZ_FNAME], svctype[SZ_FNAME], dbgflag[SZ_FNAME]
+char fmt[SZ_FNAME], sr[SZ_FNAME], allflag[SZ_FNAME]
+char resdb[SZ_FNAME], resfile[SZ_FNAME], objfile[SZ_FNAME]
+char pos[SZ_FNAME], size[SZ_FNAME], ivorn[SZ_FNAME], listflag[SZ_FNAME]
+char sname[SZ_FNAME], url[SZ_FNAME], type[SZ_FNAME]
+
+pointer sp, name, tout, old, new, extn
+pointer cmd, bpass, stype
+int fd, verbose, ndat
+int objlist, reslist, nres, nobjs, n
+bool quiet, do_samp, count, all
+double ra, dec, srad
+
+int clgeti(), strdic(), open(), imaccess(), vod_rename()
+int access(), fntopnb(), fntgfnb(), fntlenb()
+real clgetr()
+bool clgetb(), streq(), rdb_lookup()
+
+begin
+ call smark (sp)
+ call salloc (name, SZ_FNAME, TY_CHAR)
+ call salloc (tout, SZ_PATHNAME, TY_CHAR)
+ call salloc (old, SZ_PATHNAME, TY_CHAR)
+ call salloc (new, SZ_PATHNAME, TY_CHAR)
+ call salloc (cmd, SZ_PATHNAME, TY_CHAR)
+ call salloc (extn, SZ_PATHNAME, TY_CHAR)
+
+ call salloc (bpass, SZ_FNAME, TY_CHAR)
+ call salloc (stype, SZ_FNAME, TY_CHAR)
+
+
+ # Get the task parameters.
+ call clgstr ("resources", resources, SZ_LINE) # query params
+ all = clgetb ("all")
+ if (!all)
+ call clgstr ("objects", objects, SZ_LINE)
+ call clgstr ("size", sr, SZ_FNAME)
+
+ count = clgetb ("count")
+ verbose = clgeti ("verbose")
+ quiet = clgetb ("quiet")
+ do_samp = clgetb ("samp")
+
+ call clgstr ("output", output, SZ_FNAME) # output params
+ call clgstr ("format", format, SZ_FNAME)
+ call clgstr ("bandpass", bandpass, SZ_FNAME) # constraints
+ call clgstr ("type", svctype, SZ_FNAME)
+ call clgstr ("resdb", resdb, SZ_FNAME)
+
+
+ ################################
+ # Build up arguments
+ ################################
+
+ # Get the resources to query.
+ call mktemp ("/tmp/res", resfile, SZ_FNAME)
+ fd = open (resfile, NEW_FILE, TEXT_FILE)
+
+ if (resources[1] == EOS || streq (resources, "any")) {
+ call fprintf (fd, "any\n")
+ nres = INDEFI
+ call strcpy ("+l", listflag, SZ_FNAME)
+ } else {
+ reslist = fntopnb (resources, NO)
+ nres = fntlenb (reslist)
+ while (fntgfnb (reslist, Memc[name], SZ_FNAME) != EOF) {
+ if (rdb_lookup (resdb, Memc[name], type, sname, ivorn, url)) {
+ # Found an alias, print the unambiguous IVORN.
+ call fprintf (fd, "%s\n")
+ call pargstr (ivorn)
+ } else {
+ # Not an alias, let the task resolve it.
+ call fprintf (fd, "%s\n")
+ call pargstr (Memc[name])
+ }
+ }
+ call fntclsb (reslist)
+ call strcpy ("+n", listflag, SZ_FNAME)
+ }
+ call close (fd)
+
+
+ # Get the object names to query.
+ call mktemp ("/tmp/obj", objfile, SZ_FNAME)
+ fd = open (objfile, NEW_FILE, TEXT_FILE)
+
+ if (objects[1] != EOS) {
+ objlist = fntopnb (objects, NO)
+ nobjs = fntlenb (objlist)
+ while (fntgfnb (objlist, Memc[name], SZ_FNAME) != EOF) {
+
+ if (imaccess (Memc[name], READ_ONLY) == YES) {
+ call vod_img_query (Memc[name], ra, dec, srad, pos, size)
+
+ call fprintf (fd, "%g %g\n")
+ call pargd (ra)
+ call pargd (dec)
+ call sprintf (sr, SZ_FNAME, "%.6g")
+ call pargd (srad)
+
+ } else {
+ # Object name, let the task resolve it.
+ call fprintf (fd, "%s\n")
+ call pargstr (Memc[name])
+ }
+ }
+ call fntclsb (objlist)
+
+ } else {
+ # No names given, use the explicit position in the parameters.
+ nobjs = 1
+ call fprintf (fd, "%g %g\n")
+ call pargr (clgetr ("ra"))
+ call pargr (clgetr ("dec"))
+ }
+ call close (fd)
+
+
+ # FIXME -- In this release we're limited to image services for blind
+ # queries due to the catalog services querying non-std
+ # interfaces in VODATA>
+ # until we figure out the threading error problem.
+ if (IS_INDEFI(nres)) {
+ if (svctype[1] == EOS || !streq (svctype, "image")) {
+ call eprintf (
+ "Error: Blind resource queries limited to 'image' services\n")
+ return
+ }
+ }
+
+
+ # Check constraints.
+ call aclrc (Memc[bpass], SZ_FNAME)
+ if (bandpass[1] == EOS || bandpass[1] == NULL) {
+ call strcpy ("any", Memc[bpass], SZ_FNAME)
+ } else {
+ n = strdic (bandpass, Memc[bpass], SZ_FNAME, BP_NAMES)
+ if (!quiet && n == 0) {
+ call eprintf ("Invalid bandpass constraint '%s', ignoring.\n")
+ call pargstr (bandpass)
+ }
+ }
+
+ call aclrc (Memc[stype], SZ_FNAME)
+ if (svctype[1] == EOS || svctype[1] == NULL) {
+ call strcpy ("any", Memc[stype], SZ_FNAME)
+ } else {
+ n = strdic (svctype, Memc[stype], SZ_FNAME, TYP_NAMES)
+ if (!quiet && n == 0) {
+ call eprintf ("Invalid service constraint '%s', ignoring.\n")
+ call pargstr (svctype)
+ }
+ }
+
+ # Get output processing options.
+ call vod_get_format (format, fmt, Memc[extn])
+ if (IS_INDEFI(nres) || do_samp || all) {
+ # Unknown multiple resources.
+ call strcpy (output, Memc[tout], SZ_FNAME)
+ } else
+ call strcpy ("/tmp/vod", Memc[tout], SZ_FNAME)
+ if (output[1] == EOS)
+ call strcpy ("vod", output, SZ_FNAME) # set default name
+
+
+ call strcpy ("+n", verb, SZ_FNAME) # query verbosity
+ if (verbose > 1)
+ call strcpy ("-v", verb, SZ_FNAME)
+ if (verbose > 2)
+ call strcpy ("-vv", verb, SZ_FNAME)
+
+ if (all) # query all data svcs?
+ call strcpy ("-a", allflag, SZ_FNAME)
+ else
+ call strcpy ("+n", allflag, SZ_FNAME)
+
+ if (access ("/tmp/VOC_VDEBUG", 0, 0) == YES) # debug flag
+ call strcpy ("+d", dbgflag, SZ_FNAME)
+ else
+ call strcpy ("+n", dbgflag, SZ_FNAME)
+
+
+ ######################################
+ # Call the VODATA task interface.
+ ######################################
+ call vx_vodata (16, # argc
+ "-t", Memc[stype], # type constraint
+ "-b", Memc[bpass], # bandpass constraint
+ "-O", Memc[tout], # output filename (temp)
+ verb, # query verbosity
+ allflag, # query all data?
+ dbgflag, # debug flag
+ listflag, # svc_list flag
+ "-q", # suppress output
+ "-N", # numeric output name
+ "-R", # output format
+ resfile, # resources to query
+ objfile, sr) # objects to query
+
+
+ if (!quiet && (nres > 1 || IS_INDEFI(nres)) && streq(output,"STDOUT")) {
+ call printf("# Rows Cols File \tResource Title\n")
+ call printf("#\n")
+ }
+
+ # Clean up the output filenames. For a single resource/object we
+ # still end up with a name file 'foo_000_000.xml', use a more
+ # logical naming scheme.
+ if (!all) {
+ ndat = vod_rename (output, Memc[tout], format, Memc[extn],
+ nres, nobjs, quiet, count, do_samp)
+ }
+
+ if (!quiet && (nres > 1 || IS_INDEFI(nres)) && streq(output,"STDOUT")) {
+ call printf ("#\n# Data found for %d of %d resources queried.\n")
+ call pargi (ndat)
+ call pargi (nres)
+ }
+
+ # Clean up the temporary resource and object/position files.
+ if (access (resfile, 0, 0) == YES)
+ call delete (resfile)
+ if (access (objfile, 0, 0) == YES)
+ call delete (objfile)
+end
+
+
+# VOD_RENAME -- Clean up the output filenames. For a single resource/object
+# we still end up with a name file 'foo_000_000.xml', use a more logical
+# naming scheme.
+
+int procedure vod_rename (output, tout, format, extn, nres, nobjs,
+ quiet, count, samp)
+
+char output[ARB] #i output base name
+char tout[ARB] #i temp output name
+char format[ARB] #i output format
+char extn[ARB] #i filename extension
+int nres #i number of resources
+int nobjs #i number of objects
+bool quiet #i print summary?
+bool count #i print result count only?
+bool samp #i broadcast as SAMP message?
+
+pointer sp, line, svc, obj, dir, new, old
+int i, j, ip, sfd, nch, nfound, nrows, ncols, stat
+
+int access(), stridx(), strldx(), getline(), open(), ctoi()
+int vot_convert()
+bool streq()
+
+begin
+ call smark (sp)
+ call salloc (svc, SZ_FNAME, TY_CHAR)
+ call salloc (obj, SZ_FNAME, TY_CHAR)
+ call salloc (new, SZ_FNAME, TY_CHAR)
+ call salloc (old, SZ_FNAME, TY_CHAR)
+ call salloc (line, SZ_LINE, TY_CHAR)
+ call salloc (dir, SZ_PATHNAME, TY_CHAR)
+
+ nrows = 0
+ ncols = 0
+ nfound = 0
+
+ # Get the cwd.
+ call fpathname (".", Memc[dir], SZ_PATHNAME)
+ ip = stridx ('/', Memc[dir])
+ call strcpy (Memc[dir+ip-1], Memc[dir], SZ_PATHNAME)
+
+ call sprintf (Memc[obj], SZ_FNAME, "%s.objects")
+ call pargstr (output)
+
+ sfd = NULL
+ if (IS_INDEFI(nres)) {
+ # Get the number of services queried.
+ call sprintf (Memc[svc], SZ_FNAME, "%s.services")
+ call pargstr (output)
+ sfd = open (Memc[svc], READ_ONLY, TEXT_FILE)
+ nch = getline (sfd, Memc[line])
+
+ ip = 20
+ nch = ctoi (Memc[line], ip, nres)
+
+ nch = getline (sfd, Memc[line]) # Skip ahead
+ nch = getline (sfd, Memc[line])
+ }
+
+ # Process the output files as needed.
+
+ for (i=0; i < nres; i=i+1) {
+ if (IS_INDEFI(nres))
+ nch = getline (sfd, Memc[line])
+
+ for (j=0; j < nobjs; j=j+1) {
+ # Construct the vodata filename.
+ call sprintf (Memc[old], SZ_FNAME, "%s_%03d_%03d.xml")
+ call pargstr (tout)
+ call pargi (i)
+ call pargi (j)
+
+ if (streq ("STDOUT", output) || streq ("STDERR", output)) {
+ call strcpy (output, Memc[new], SZ_FNAME)
+ if (access (Memc[old], 0, 0) == YES) {
+ call fcopy (Memc[old], Memc[new])
+ call delete (Memc[old])
+ nfound = nfound + 1
+ }
+
+ } else {
+
+ if (nres == 1 && nobjs == 1) {
+ call sprintf (Memc[new], SZ_FNAME, "%s%s%s")
+ call pargstr (Memc[dir])
+ call pargstr (output)
+ call pargstr (extn)
+ } else if (nres == 1) {
+ call sprintf (Memc[new], SZ_FNAME, "%s%s_%03d%s")
+ call pargstr (Memc[dir])
+ call pargstr (output)
+ call pargi (j)
+ call pargstr (extn)
+ } else if (nobjs == 1) {
+ call sprintf (Memc[new], SZ_FNAME, "%s%s_%03d%s")
+ call pargstr (Memc[dir])
+ call pargstr (output)
+ call pargi (i)
+ call pargstr (extn)
+ } else {
+ call sprintf (Memc[new], SZ_FNAME, "%s%s_%03d_%03d%s")
+ call pargstr (Memc[dir])
+ call pargstr (output)
+ call pargi (i)
+ call pargi (j)
+ call pargstr (extn)
+ }
+
+ if (access (Memc[old], 0, 0) == YES) {
+ if (!quiet) {
+ call vod_tinfo (Memc[old], nrows, ncols)
+ ip = strldx ('/', Memc[new])
+ call eprintf (" %5d %4d %s")
+ call pargi (nrows)
+ call pargi (ncols)
+ call pargstr (Memc[new+ip])
+ if (nres > 1) {
+ call eprintf (" %s")
+ call pargstr (Memc[new+22])
+ } else
+ call eprintf ("\n")
+ }
+
+ if (count) {
+ # If ony printing a count, delete saved results.
+ if (access (Memc[old], 0, 0) == YES)
+ call delete (Memc[old])
+ } else {
+
+ if (access (Memc[new], 0, 0) == NO) {
+ if (!streq (extn, "xml")) {
+ stat = vot_convert (Memc[old], Memc[new],
+ format)
+ call delete (Memc[old])
+ } else
+ call frename (Memc[old], Memc[new])
+ }
+
+ if (samp) # broadcast the table
+ call vod_bcast_table (Memc[new])
+ }
+
+ nfound = nfound + 1
+ }
+ }
+
+ if (DEBUG) {
+ call eprintf ("%d/%d: %s -> %s\n")
+ call pargi (nres) ; call pargi (nobjs)
+ call pargstr (Memc[old])
+ call pargstr (Memc[new])
+ }
+ }
+ }
+
+
+ if (count || streq (output, "STDOUT")) {
+ # If ony printing a count, delete saved results.
+ if (access (Memc[svc], 0, 0) == YES)
+ call delete (Memc[svc])
+ if (access (Memc[obj], 0, 0) == YES)
+ call delete (Memc[obj])
+ }
+ if (sfd != NULL)
+ call close (sfd)
+ call sfree (sp)
+
+ return (nfound)
+end
+
+
+# VOD_TINFO -- Get table dimensions.
+
+procedure vod_tinfo (tblname, nrows, ncols)
+
+char tblname[ARB] #i table name
+int nrows, ncols #o table dimensions
+
+pointer tp, tbtopn()
+int tbpsta()
+
+begin
+ iferr {
+ tp = tbtopn (tblname, READ_ONLY, 0)
+ } then {
+ call eprintf ("Error: can't open '%s'\n")
+ call pargstr (tblname)
+ return
+ }
+
+ nrows = tbpsta (tp, TBL_NROWS)
+ ncols = tbpsta (tp, TBL_NCOLS)
+
+ call tbtclo (tp)
+end
+
+
+# VOD_BCAST_TABLE -- Broadcast a table name for loading.
+
+procedure vod_bcast_table (tblname)
+
+char tblname[ARB] #i table name
+
+pointer sp, cwd, cmd, name
+int status
+
+begin
+ call smark (sp)
+ call salloc (cwd, SZ_PATHNAME, TY_CHAR)
+ call salloc (cmd, SZ_PATHNAME, TY_CHAR)
+ call salloc (name, SZ_PATHNAME, TY_CHAR)
+
+ # Get the current working dir
+ call zfgcwd (Memc[cwd], SZ_PATHNAME, status)
+ call strupk (Memc[cwd], Memc[cwd], SZ_PATHNAME)
+
+ # Broadcast the table
+ call sprintf (Memc[cmd], SZ_PATHNAME, "samp loadVOTAble file://%s\n")
+ call pargstr (tblname)
+
+ # FIXME -- Need to be using the real SAMP interface here.
+ call clcmd (Memc[cmd])
+
+ call sfree (sp)
+end
+
+
+# VOD_GET_FORMAT -- Convert the format parameter to the flag and file extn.
+
+procedure vod_get_format (format, fmt, extn)
+
+char format[ARB] #i format parameter
+char fmt[ARB] #o format flag
+char extn[ARB] #o output extension
+
+int ofmt
+int strdic()
+
+begin
+ ofmt = strdic (format, fmt, SZ_FNAME, OUT_FMTS)
+ switch (ofmt) {
+ case FMT_ASCII:
+ call strcpy ("-A", fmt, SZ_FNAME)
+ call strcpy (".asv", extn, SZ_FNAME)
+ case FMT_CSV:
+ call strcpy ("-C", fmt, SZ_FNAME)
+ call strcpy (".csv", extn, SZ_FNAME)
+ case FMT_TSV:
+ call strcpy ("-T", fmt, SZ_FNAME)
+ call strcpy (".tsv", extn, SZ_FNAME)
+ case FMT_HTML:
+ call strcpy ("-H", fmt, SZ_FNAME)
+ call strcpy (".html", extn, SZ_FNAME)
+ case FMT_RAW:
+ call strcpy ("-R", fmt, SZ_FNAME)
+ call strcpy (".xml", extn, SZ_FNAME)
+ case FMT_FITS:
+ call strcpy ("-F", fmt, SZ_FNAME)
+ call strcpy (".fits", extn, SZ_FNAME)
+ default:
+ call strcpy ("-R", fmt, SZ_FNAME)
+ call strcpy (".xml", extn, SZ_FNAME)
+ }
+end
+
+
+# VOD_TBL_COPY -- Copy a single table to a new file. If the file exists, append
+# as a new extension.
+
+procedure vod_tbl_copy (oldfile, newfile)
+
+char oldfile[ARB] # i: current file name
+char newfile[ARB] # i: new file name
+
+int phu_copied # set by tbfpri and ignored
+pointer sp, oldname, newname
+
+bool use_fcopy # true if we should copy the file with fcopy
+
+bool streq()
+int tbtacc()
+errchk tbfpri, tbtcpy
+
+begin
+ call smark (sp)
+ call salloc (oldname, SZ_FNAME, TY_CHAR)
+ call salloc (newname, SZ_FNAME, TY_CHAR)
+
+ # Check to make sure the copy is legal
+
+ use_fcopy = false
+ if (streq (oldfile, newfile)) {
+ call eprintf ("Cannot copy table to itself: %s\n")
+ call pargstr (oldfile)
+
+ if (tbtacc (oldfile) == YES)
+ use_fcopy = true
+
+ if (use_fcopy) {
+ call tbtext (oldfile, Memc[oldname], SZ_FNAME)
+ call tbtext (newfile, Memc[newname], SZ_FNAME)
+
+ iferr (call fcopy (Memc[oldname], Memc[newname])) {
+ call erract (EA_WARN)
+ }
+ }
+
+ } else {
+ # Table extensions are copied by the table
+ # library function tbtcpy
+ iferr {
+ call tbfpri (oldfile, newfile, phu_copied)
+ call tbtcpy (oldfile, newfile)
+ } then {
+ call erract (EA_WARN)
+ }
+ }
+
+ call sfree (sp)
+ return
+end
+
+
+# VOD_IMG_QUERY -- Get the query params for the named image.
+
+procedure vod_img_query (imname, ra, dec, sr, pos, size)
+
+char imname[ARB] #i image name
+double ra, dec, sr #o RA/DEC/SR params
+char pos[ARB] #o POS string
+char size[ARB] #o SIZE string
+
+double r[IM_MAXDIM], w[IM_MAXDIM], cd[2,2]
+double xrot, yrot, rot, scale
+
+pointer im, mw, ctw, co
+int stat
+double cx, cy, ra0, dec0
+
+pointer immap()
+int sk_decim(), mw_stati()
+pointer mw_sctran()
+
+begin
+ # Open the image.
+ iferr {
+ im = immap (imname, READ_ONLY, 0)
+ } then {
+ # Unable to decode image WCS
+ call eprintf ("Error: Cannot open image '%s'\n")
+ call pargstr (imname)
+ return
+ }
+
+
+ # Get the WCS.
+ iferr {
+ stat = sk_decim (im, "world", mw, co)
+ if (stat == ERR || mw == NULL) {
+ # Unable to decode image WCS
+ call eprintf ("Error: No image WCS present.\n")
+ return
+
+ } else if (mw != NULL) {
+ ctw = mw_sctran (mw, "logical", "world", 03B)
+ cx = IM_LEN(im,1) / 2
+ cy = IM_LEN(im,2) / 2
+ call mw_c2trand (ctw, cx, cy, ra0, dec0)
+
+ # Get the CD matrix for scale and rotation
+ call vod_gfterm (mw, r, w, cd, mw_stati (mw, MW_NPHYSDIM))
+ scale = 3600. * sqrt ((cd[1,1]**2 + cd[2,1]**2 +
+ cd[1,2]**2 + cd[2,2]**2) / 2.)
+
+ xrot = abs (atan2 ( cd[2,1], cd[1,1]))
+ yrot = abs (atan2 (-cd[1,2], cd[2,2]))
+ rot = (xrot + yrot) / 2.0 # NOT USED
+
+
+ ra = ra0
+ dec = dec0
+ sr = max (((scale * IM_LEN(im,1)) / 3600.),
+ (scale * IM_LEN(im,2)) / 3600.)
+
+ call sprintf (pos, SZ_FNAME, "%.6g,%.6g")
+ call pargd (ra0)
+ call pargd (dec0)
+ call sprintf (size, SZ_FNAME, "%.4g,%.4g")
+ call pargd ((scale * IM_LEN(im,1)) / 3600.)
+ call pargd ((scale * IM_LEN(im,2)) / 3600.)
+ }
+
+ } then {
+ # Unable to decode image WCS
+ call eprintf ("Error: Unable to decode WCS.\n")
+ }
+
+ call imunmap (im)
+end
+
+
+# VOD_GFTERM -- Compute the output FITS CRPIX, CRVAL, and CD arrays from the
+# MWCS LTERM and WTERM. Note that the CD matrix terms are still transposed
+# from the usual Fortran order.
+
+procedure vod_gfterm (mw, crpix, crval, cd, ndim)
+
+pointer mw #i the input mwcs pointer
+double crpix[ndim] #o the output FITS CRPIX array
+double crval[ndim] #o the output FITS CRVAL array
+double cd[ndim,ndim] #o the output FITS CD matrix
+int ndim #i the dimensionality of the wcs
+
+pointer sp, r, wcd, ltv, ltm, iltm
+int i
+
+errchk mw_gwtermd, mw_gltermd
+
+begin
+ call smark (sp)
+ call salloc (r, ndim, TY_DOUBLE)
+ call salloc (wcd, ndim * ndim, TY_DOUBLE)
+ call salloc (ltv, ndim, TY_DOUBLE)
+ call salloc (ltm, ndim * ndim, TY_DOUBLE)
+ call salloc (iltm, ndim * ndim, TY_DOUBLE)
+
+ iferr {
+ call mw_gwtermd (mw, Memd[r], crval, Memd[wcd], ndim)
+ call mw_gltermd (mw, Memd[ltm], Memd[ltv], ndim)
+ call mwvmuld (Memd[ltm], Memd[r], crpix, ndim)
+ call aaddd (crpix, Memd[ltv], crpix, ndim)
+ call mwinvertd (Memd[ltm], Memd[iltm], ndim)
+ call mwmmuld (Memd[wcd], Memd[iltm], cd, ndim)
+
+ } then {
+ # Set up a default value.
+ call aclrd (cd, ndim*ndim)
+ for (i=1; i <= ndim; i=i+1) {
+ crpix[i] = 1.0d0
+ crval[i] = 1.0d0
+ cd[i,i] = 1.0d0
+ }
+ }
+
+ call sfree (sp)
+end
diff --git a/vo/votools/t_votcopy.x b/vo/votools/t_votcopy.x
new file mode 100644
index 00000000..8a115227
--- /dev/null
+++ b/vo/votools/t_votcopy.x
@@ -0,0 +1,45 @@
+#
+# VOTCOPY -- Copy a VOTable from one format to another.
+
+
+procedure t_votcopy ()
+
+char in[SZ_LINE], out[SZ_LINE], format[SZ_LINE]
+int inlist, outlist
+bool header, verbose
+
+int clpopni(), clplen(), clgfil(), vot_convert()
+bool clgetb()
+
+begin
+ # Get the task parameters.
+ inlist = clpopni ("input")
+ outlist = clpopni ("output")
+
+ call clgstr ("format", format, SZ_LINE)
+ header = clgetb ("header")
+ verbose = clgetb ("verbose")
+
+ if (clplen (inlist) != clplen (outlist)) {
+ call eprintf ("Number of input and output files not the same.\n")
+ call clpcls (inlist)
+ call clpcls (outlist)
+ return
+ }
+
+ # Loop over the files,
+ while (clgfil (inlist, in, SZ_LINE) != EOF &&
+ (clgfil (outlist, out, SZ_LINE) != EOF)) {
+
+ if (vot_convert (in, out, format) == ERR)
+ break
+ }
+
+ call clpcls (inlist)
+ call clpcls (outlist)
+
+ # Don't save the calling parameters.
+ call clpstr ("input", "")
+ call clpstr ("output", "")
+ call clpstr ("format", "")
+end
diff --git a/vo/votools/t_votget.x b/vo/votools/t_votget.x
new file mode 100644
index 00000000..c189638f
--- /dev/null
+++ b/vo/votools/t_votget.x
@@ -0,0 +1,122 @@
+#
+# VOTGET -- Download Access References from a VOTable
+
+include <ctype.h>
+include <votParse_spp.h>
+
+
+define DEF_BASE "file"
+define DEF_EXTN "fits"
+
+
+# input input list of VOTables
+#
+# base base output filename
+# extn output filename extension
+# sequential use sequential file numbers
+#
+# list list, rather than download, access references
+# nthreads Number of simultaneous downloads
+#
+# col column number to use for acred (0-indexed)
+# acref ucd to identify the access reference column
+# format format to download (e.g. 'fits' or 'jpeg')
+
+
+procedure t_votget ()
+
+pointer sp, in, base, extn, efname, acref, format, in_osfn, line
+char nth[SZ_FNAME], cnum[SZ_FNAME], seq[SZ_FNAME]
+int efd, inlist, nthreads, col
+bool sequential, list
+
+int open(), getline(), clgeti(), clpopni(), clgfil()
+bool clgetb()
+
+begin
+ call smark (sp)
+ call salloc (in, SZ_FNAME, TY_CHAR)
+ call salloc (base, SZ_FNAME, TY_CHAR)
+ call salloc (extn, SZ_FNAME, TY_CHAR)
+ call salloc (efname, SZ_FNAME, TY_CHAR)
+ call salloc (acref, SZ_FNAME, TY_CHAR)
+ call salloc (format, SZ_FNAME, TY_CHAR)
+ call salloc (line, SZ_LINE, TY_CHAR)
+
+ call strcpy ("", Memc[base], SZ_LINE)
+
+ # Get the task parameters.
+ inlist = clpopni ("input")
+
+ list = clgetb ("list")
+ if (!list)
+ call clgstr ("base", Memc[base], SZ_LINE)
+ call clgstr ("extn", Memc[extn], SZ_LINE)
+ call clgstr ("format", Memc[format], SZ_FNAME)
+ call clgstr ("acref", Memc[acref], SZ_FNAME)
+
+ nthreads = clgeti ("nthreads")
+ col = clgeti ("col")
+ list = clgetb ("list")
+ sequential = clgetb ("sequential")
+
+
+ # Convert integer args to strings for passing to the task.
+ call sprintf (nth, SZ_FNAME, "%d")
+ call pargi (nthreads)
+ if (!IS_INDEFI(col)) {
+ call sprintf (cnum, SZ_FNAME, "%d")
+ call pargi (col)
+ }
+
+ if (list)
+ call mktemp ("/tmp/ex", Memc[efname], SZ_FNAME)
+
+ if (sequential)
+ call strcpy ("-s", seq, SZ_FNAME)
+ else
+ call strcpy ("+n", seq, SZ_FNAME)
+
+
+ # Loop over the files,
+ while (clgfil (inlist, Memc[in], SZ_LINE) != EOF) {
+
+ call fmapfn (Memc[in], Memc[in_osfn], SZ_PATHNAME)
+ call strupk (Memc[in_osfn], Memc[in_osfn], SZ_PATHNAME)
+
+ # Call the application part of the task.
+ if (IS_INDEFI(col)) {
+ if (list) {
+ call vx_voget (7, "-o", Memc[efname], "-f", Memc[format],
+ "-u", Memc[acref], Memc[in_osfn])
+ } else {
+ call vx_voget (12, "-b", Memc[base], "-N", nth, seq,
+ "-e", Memc[extn], "-f", Memc[format],
+ "-u", Memc[acref], Memc[in_osfn])
+ }
+ } else {
+ if (list) {
+ call vx_voget (7, "-o", Memc[efname], "-f", Memc[format],
+ "-F", cnum, Memc[in_osfn])
+ } else {
+ call vx_voget (12, "-b", Memc[base], "-N", nth, seq,
+ "-e", Memc[extn], "-f", Memc[format],
+ "-F", cnum, Memc[in_osfn])
+ }
+ }
+ }
+
+ # Print the extracted access references from the concatenated file.
+ if (list) {
+ efd = open (Memc[efname], READ_ONLY, TEXT_FILE)
+ while (getline (efd, Memc[line]) != EOF) {
+ call printf ("%s")
+ call pargstr (Memc[line])
+ }
+ call close (efd)
+ call delete (Memc[efname])
+ }
+
+ call clpcls (inlist)
+ call sfree (sp)
+end
diff --git a/vo/votools/t_votsize.x b/vo/votools/t_votsize.x
new file mode 100644
index 00000000..6fae7049
--- /dev/null
+++ b/vo/votools/t_votsize.x
@@ -0,0 +1,32 @@
+#
+# VOTSIZE -- Simply get the size of a VOTable. We need to work on the
+# VOTable itself since the TABLES tasks don't generally behave well when
+# there are no rows in a table.
+
+include <ctype.h>
+include <votParse_spp.h>
+
+
+procedure t_votsize ()
+
+char in[SZ_LINE]
+char out[SZ_LINE], line[SZ_LINE]
+
+int fd, nchars
+int vx_voinfo(), open(), getline()
+
+begin
+ # Get the table name.
+ call clgstr ("input", in, SZ_LINE)
+
+ call mktemp ("/tmp/sz", out, SZ_LINE)
+ call vx_voinfo (3, "-s", out, in)
+
+ fd = open (out, READ_ONLY, TEXT_FILE)
+ nchars = getline (fd, line)
+ call close (fd)
+
+ call printf ("%s")
+ call pargstr (line)
+ call delete (out)
+end
diff --git a/vo/votools/tabclip.cl b/vo/votools/tabclip.cl
new file mode 100644
index 00000000..bf53f2dc
--- /dev/null
+++ b/vo/votools/tabclip.cl
@@ -0,0 +1,49 @@
+# TABCLIP -- Clip a table to the specified boundaries.
+
+procedure tabclip (intab, outtab, xcol, ycol, x1, y1, x2, y2)
+
+string intab { prompt="Input table" }
+string outtab { prompt="Output table" }
+string xcol { prompt="Name of X column" }
+string ycol { prompt="Name of Y column" }
+real x1 { prompt="Left X clipping value" }
+real y1 { prompt="Bottom Y clipping value" }
+real x2 { prompt="Right X clipping value" }
+real y2 { prompt="Top Y clipping value" }
+
+begin
+ string expr, in, out, xc, yc, ttab
+ real xv1, yv1, xv2, yv2, temp
+
+ # Get the parameters
+ in = intab ; out = outtab
+ xc = xcol ; yc = ycol
+ xv1 = x1 ; yv1 = y1
+ xv2 = x2 ; yv2 = y2
+
+ # Swap if needed.
+ if (xv1 > xv2) { temp = xv2 ; xv2 = xv1 ; xv1 = temp }
+ if (yv1 > yv2) { temp = yv2 ; yv2 = yv1 ; yv1 = temp }
+
+
+ if (access (in) == no)
+ error (0, "tabclip: Input table doesn't exist.")
+ if (access (out) == no)
+ error (0, "tabclip: Cannot open output table.")
+
+ # Form the clipping expression.
+ expr = xc // " >= " // xv1 // " && "
+ expr += yc // " >= " // yv1 // " && "
+ expr += xc // " <= " // xv2 // " && "
+ expr += yc // " <= " // yv2
+
+ # Do the selection.
+ if (in != out) {
+ tselect (in, out, expr)
+ } else {
+ ttab = mktemp ("/tmp/tt")
+ tselect (in, ttab, expr)
+ copy (ttab, out)
+ delete (ttab, verify-, >& "dev$null")
+ }
+end
diff --git a/vo/votools/taboverlay.cl b/vo/votools/taboverlay.cl
new file mode 100644
index 00000000..e8193e84
--- /dev/null
+++ b/vo/votools/taboverlay.cl
@@ -0,0 +1,73 @@
+#{ TABOVERLAY -- Overlay a catalog of sources on an image display. The
+# catalog is assumed to be a text file, the user supplies the columns
+# defining the RA/Dec columns (and optional label). These will be
+# converted to image coords based on the WCS of the image.
+
+procedure taboverlay (image, catalog)
+
+string image { prompt = "Input image" }
+string catalog { prompt = "Input catalog" }
+
+int labcol = 1 { prompt = "Label column" }
+int racol = 2 { prompt = "RA column" }
+int deccol = 3 { prompt = "Dec column" }
+int mkcolor = 208 { prompt = "Marker color" }
+int status = 0 { prompt = "Service status code" }
+
+begin
+ string img, cat, coords, tvcoords, pos_all
+ real ra, dec, size
+ int mcol, c1, c2, c3
+
+
+ # Get params to local variables.
+ img = image
+ mcol = mkcolor
+ c1 = racol
+ c2 = deccol
+ c3 = labcol
+ cat = catalog
+
+ if (imaccess (img)) {
+ iferr { wcsinfo (img) } then {
+ error (0, "Cannot determine image coords for `"//img//"'")
+ } else {
+ ra = wcsinfo.midx
+ dec = wcsinfo.midy
+ size = max (wcsinfo.width, wcsinfo.height) / 60.0
+ }
+ } else {
+ #error (0, "Image '"// img // "' not found.")
+ sesame (img, verbose-)
+ ra = sesame.ra
+ dec = sesame.dec
+ img = "cache$" // img // ".fits"
+ }
+
+
+ # Create temp files for the output
+ coords = mktemp ("tmp$to")
+ tvcoords = mktemp ("tmp$to")
+ pos_all = mktemp ("tmp$to")
+
+ # Select the RA,Dec and optional columns from the table.
+ fields (cat, c1//","//c2//","//c3, >& pos_all)
+
+ # Mark the objects on the display.
+ wcsctran (pos_all, "c1", img, verb-,
+ inwcs="world", outwcs="logical", units="n n")
+ tvmark (frame=1, coords="c1", mark="circle", radii=10, color=mcol,
+ txsize=1, nxoffset=5, nyoffset=-10)
+ delete ("c1", verify-, >& "dev$null")
+
+ if (mkcolor > 217) # update the marker color
+ mkcolor = 204
+ else
+ mkcolor = mkcolor + 1
+
+ # Clean up.
+ delete (coords, verify-, >& "dev$null")
+ delete (pos_all, verify-, >& "dev$null")
+ delete (tvcoords, verify-, >& "dev$null")
+end
+
diff --git a/vo/votools/tests/vodata_001.cl b/vo/votools/tests/vodata_001.cl
new file mode 100644
index 00000000..79beeb3b
--- /dev/null
+++ b/vo/votools/tests/vodata_001.cl
@@ -0,0 +1,27 @@
+#
+# VODATA task unit tests
+
+# Set the test description string.
+votest.descr = "VODATA task unit tests"
+
+vodata.size = 0.05
+vodata.output = "STDOUT"
+
+delete ("/tmp/svcs.txt", verify-, >& "dev$null")
+print ("hst\nchandra\ngsc2.3", > "/tmp/svcs.txt")
+delete ("/tmp/pos.txt", verify-, >& "dev$null")
+print ("m31\nm32\nm33\n", > "/tmp/pos.txt")
+
+printf ("Example 1)\n")
+vodata ("gsc2.3", "ngc1234")
+vodata ("gsc2.3", "@/tmp/pos.txt")
+vodata ("gsc2.3", "m31,m51,m93")
+vodata ("@/tmp/svcs.txt", "@/tmp/pos.txt")
+vodata ("hst,chandra,gsc2.3", "@/tmp/pos.txt")
+vodata ("2mass-psc", "dev$ypix")
+
+printf ("Example 2)\n")
+vodata ("any", "IC10", type="image")
+
+printf ("Example 3)\n")
+vodata ("any", "abell2712", type="image", bandpass="x-ray")
diff --git a/vo/votools/tests/zztest.csh b/vo/votools/tests/zztest.csh
new file mode 100755
index 00000000..146f6b9f
--- /dev/null
+++ b/vo/votools/tests/zztest.csh
@@ -0,0 +1,18 @@
+#!/bin/csh -f
+
+set n = 0
+echo > /tmp/z/zzlist
+foreach i (`cat /tmp/_im.s`)
+ echo $n " " $i
+
+ echo "b xerror_" > /tmp/c
+ echo "b zpanic_" >> /tmp/c
+ echo "run vodata resources='"$i"' @zz.dpar" >> /tmp/c
+ echo "thread apply all bt" >> /tmp/c
+ echo "quit" >> /tmp/c
+
+ echo $n " " $i >> /tmp/z/zzlist
+ gdb -x /tmp/c ./xx_votools.e >& /tmp/z/$n.out
+
+ set n = `expr $n + 1`
+end
diff --git a/vo/votools/topcat.cl b/vo/votools/topcat.cl
new file mode 100644
index 00000000..a8192fb1
--- /dev/null
+++ b/vo/votools/topcat.cl
@@ -0,0 +1,43 @@
+#{ TOPCAT -- Start or stop the TOPCAT app.
+
+procedure topcat (cmd)
+
+string cmd { prompt = "Command" }
+bool bkg = yes { prompt = "Run in background?" }
+bool verbose = no { prompt = "Print actions?" }
+
+begin
+ string action, command, ch
+ bool verb
+
+
+ if ($nargs > 0)
+ action = cmd
+ else
+ action = "start"
+ verb = verbose
+ command = "!" // osfn ("vo$java/app.topcat")
+
+
+ if (action == "stop" || action == "off") {
+ if (verb)
+ printf ("Stopping Topcat .... ")
+ command = command // " -kill"
+ print (command) | cl(, >& "dev$null")
+
+
+ } else if (action == "status") {
+ command = command // " -status"
+ print (command) | cl()
+
+ } else {
+ # Default is to start the app
+ if (verb)
+ printf ("Starting Topcat .... ")
+ command = command // " -bg"
+ print (command) | cl(, >& "dev$null")
+ }
+
+ if (verb)
+ printf ("\n")
+end
diff --git a/vo/votools/vocdctl.par b/vo/votools/vocdctl.par
new file mode 100644
index 00000000..9e0abdf6
--- /dev/null
+++ b/vo/votools/vocdctl.par
@@ -0,0 +1 @@
+cmd,s,q,"",,,Command
diff --git a/vo/votools/vodata.par b/vo/votools/vodata.par
new file mode 100644
index 00000000..d1b87209
--- /dev/null
+++ b/vo/votools/vodata.par
@@ -0,0 +1,16 @@
+resources,s,q,"",,,"List of resources to query"
+objects,s,q,"",,,"List of targets to query"
+ra,r,h,0.0,0.,360.,"Resolved RA (J2000 decimal degrees)"
+dec,r,h,0.0,-90.,90.,"Resolved Dec (J2000 decimal degrees)"
+size,r,h,0.25,0.,360.,"Query size (decimal degrees)"
+output,s,h,"STDOUT",,,"Output filename base"
+format,s,h,"raw",,,"Output format"
+samp,b,h,no,,,"Broadcast as samp message?"
+count,b,h,no,,,"Print only a count of results?"
+verbose,i,h,1,1,3,"Query verbosity level"
+all,b,h,no,,,"Query all resource services?"
+bandpass,s,h,"",,,"Bandpass constraint"
+type,s,h,"",,,"Service type constraint"
+resdb,s,h,)_.resdb,,,"Resource database"
+quiet,b,h,no,,,"Suppress task output?"
+status,i,h,,,,"Service status code"
diff --git a/vo/votools/votcopy.par b/vo/votools/votcopy.par
new file mode 100644
index 00000000..81abab02
--- /dev/null
+++ b/vo/votools/votcopy.par
@@ -0,0 +1,6 @@
+input,s,a,,,,Input VOTable names
+output,s,a,,,,Output file names
+format,s,a,,,,Output format
+header,b,h,yes,,,Header?
+verbose,b,h,yes,,,Verbose?
+mode,s,h,"al"
diff --git a/vo/votools/votget.par b/vo/votools/votget.par
new file mode 100644
index 00000000..b3129c00
--- /dev/null
+++ b/vo/votools/votget.par
@@ -0,0 +1,10 @@
+input,s,a,,,,Input VOTable names
+base,s,q,,,,Base output file name
+extn,s,h,"fits",,,Filename extension
+format,s,h,"fits",,,Format to download
+acref,s,h,"VOX:Image_AccessReference",,,UCD to identify access reference
+col,i,h,INDEF,,,Column number to use for acref
+sequential,b,h,yes,,,Use sequential file numbers
+nthreads,i,h,4,,,Number of download threads?
+list,b,h,yes,,,List instead of download access refs?
+mode,s,h,"al"
diff --git a/vo/votools/votools.cl b/vo/votools/votools.cl
new file mode 100644
index 00000000..abfb1976
--- /dev/null
+++ b/vo/votools/votools.cl
@@ -0,0 +1,76 @@
+#{ VOTOOLS -- VO Toolbox Sub-Package
+
+# Logical directories.
+reset votools = "vo$votools/"
+reset handlers = "vo$handlers/"
+reset vojava = "vo$java/"
+reset vodata = "vo$votest/data/"
+
+
+package votools
+
+# Compiled tasks.
+task dalclient,
+ dispname,
+ makewcs,
+ sesame,
+ votcopy,
+ votsize,
+ votget,
+ vodata,
+ sbquery = votools$x_votools.e
+
+
+# Script tasks.
+task tblhandler = handlers$tblhandler.cl # SAMP handlers
+#task imghandler = handlers$imghandler.cl
+task overhandler = handlers$overhandler.cl
+
+task nedoverlay = votools$nedoverlay.cl # Catalog overlays
+task radiooverlay = votools$radiooverlay.cl
+task xrayoverlay = votools$xrayoverlay.cl
+task obslogoverlay = votools$obslogoverlay.cl
+
+task dss = votools$dss.cl # Image access
+
+task getimg = votools$getimg.cl # Data access
+task getcat = votools$getcat.cl
+task getspec = votools$getspec.cl
+task imgcat = votools$imgcat.cl
+
+task regdb = votools$regdb.cl
+task mkregdb = votools$mkregdb.cl
+task wcsinfo = votools$wcsinfo.cl
+
+task hub = votools$hub.cl # External apps
+task topcat = votools$topcat.cl
+task aladin = votools$aladin.cl
+
+task taboverlay = votools$taboverlay.cl # Table tools
+task votpos = votools$votpos.cl
+task tabclip = votools$tabclip.cl
+
+task regmetalist = votools$regmetalist.cl # Utility routines
+task colbyid = votools$colbyid.cl
+task colbyname = votools$colbyname.cl
+task colbyucd = votools$colbyucd.cl
+task qstring = votools$qstring.cl
+task prettystr = votools$prettystr.cl
+
+
+# Foreign (Java) tasks.
+printf ("$task $voclientd = $%s/voclientd\nkeep\n", osfn("vojava$")) | cl()
+
+
+# Hidden tasks.
+#hidetask dalclient
+hidetask regmetalist
+#hidetask tabclip
+#hidetask sbquery
+hidetask qstring
+
+#hidetask vocdctl
+hidetask voclientd
+
+
+clbye()
diff --git a/vo/votools/votools.hd b/vo/votools/votools.hd
new file mode 100644
index 00000000..6cc78388
--- /dev/null
+++ b/vo/votools/votools.hd
@@ -0,0 +1,58 @@
+# Help directory for the VO Toolbox package.
+
+$doc = "./doc/"
+$vosrc = "./"
+$votools = "./"
+
+revisions sys=Revisions
+
+# Data Query Utilities
+getcat hlp=doc$getcat.hlp, src=votools$getcat.cl
+getimg hlp=doc$getimg.hlp, src=votools$getimg.cl
+#getspec hlp=doc$getspec.hlp, src=votools$getspec.cl
+#getlines hlp=doc$getlines.hlp, src=votools$getlines.cl
+vodata hlp=doc$vodata.hlp, src=votools$t_vodata.x
+
+# Image Utilities
+dss hlp=doc$dss.hlp, src=votools$dss.cl
+imgcat hlp=doc$imgcat.hlp, src=votools$imgcat.cl
+dispname hlp=doc$dispname.hlp, src=votools$t_dispname.x
+wcsinfo hlp=doc$wcsinfo.hlp, src=votools$wcsinfo.cl
+
+# VO Service Tools
+sesame hlp=doc$sesame.hlp, src=votools$t_sesame.x
+
+# Simple Catalog Tools
+nedoverlay hlp=doc$nedoverlay.hlp, src=votools$nedoverlay.cl
+obslogoverlay hlp=doc$obslogoverlay.hlp, src=votools$obslogoverlay.cl
+radiooverlay hlp=doc$radiooverlay.hlp, src=votools$radiooverlay.cl
+xrayoverlay hlp=doc$xrayoverlay.hlp, src=votools$xrayoverlay.cl
+
+# Registry Tools
+mkregdb hlp=doc$mkregdb.hlp, src=votools$mkregdb.cl
+regdb hlp=doc$regdb.hlp, src=votools$regdb.cl
+regmetalist hlp=doc$regmetalist.hlp, src=votools$regmetalist.cl
+
+# VOTable Utilities
+votcopy hlp=doc$votcopy.hlp, src=votools$t_votcopy.x
+votget hlp=doc$votget.hlp, src=votools$t_votget.x
+votpos hlp=doc$votpos.hlp, src=votools$votpos.cl
+votsize hlp=doc$votsize.hlp, src=votools$t_votsize.x
+
+# Table Utilities
+colbyid hlp=doc$colbyid.hlp, src=votools$colbyid.cl
+colbyucd hlp=doc$colbyucd.hlp, src=votools$colbyucd.cl
+colbyname hlp=doc$colbyname.hlp, src=votools$colbyname.cl
+tabclip hlp=doc$tabclip.hlp, src=votools$tabclip.cl
+taboverlay hlp=doc$taboverlay.hlp, src=votools$taboverlay.cl
+
+# External Apps
+aladin hlp=doc$aladin.hlp, src=votools$aladin.cl
+hub hlp=doc$hub.hlp, src=votools$hub.cl
+stilts hlp=doc$stilts.hlp
+topcat hlp=doc$topcat.hlp, src=votools$topcat.cl
+voclient hlp=doc$voclient.hlp
+
+# Utilities
+qstring hlp=doc$qstring.hlp, src=votools$qstring.cl
+
diff --git a/vo/votools/votools.men b/vo/votools/votools.men
new file mode 100644
index 00000000..2d8149d2
--- /dev/null
+++ b/vo/votools/votools.men
@@ -0,0 +1,62 @@
+
+ Toplevel apps:
+
+ registry - Query the VO Registry
+
+ Toolbox sub-package:
+
+ DATA QUERY/ACCESS TOOLS
+ getcat - Query catalog data services in the VO
+ getimg - Query image data services in the VO
+ getspec - Query spectral data services in the VO (NYI)
+ getlines - Query spectral line data services in the VO (NYI)
+ vodata - General purpose query of VO data service
+
+ IMAGE UTILITIES
+ dss - Display a DSS2 image of a named field
+ imgcat - Create a catalog of detections in an image
+ wcsinfo - Summarize the WCS information of an image
+ dispname - Get the currently displayed image name
+
+ VO SERVICE TOOLS
+ sesame - Resolve an object name to a position
+
+ SIMPLE CATALOG TOOLS
+ nedoverlay - Overlay NED objects in the image display
+ obslogoverlay - Overlay an observation catalog (HST, XMM, etc)
+ radiooverlay - Overlay NVSS radio contours in the image display
+ xrayoverlay - Overlay RASS3 X-Ray contours in the image display
+
+ REGISTRY TOOLS
+ mkregdb - Create a local VO Registry database
+ regdb - Manage/Query a local VO Registry database
+ regmetalist - List the metadata fields of a Registry record
+
+ VOTABLE UTILITY TOOLS
+ votcopy - Copy a VOTable to another format
+ votget - Download data referenced in a VOTable
+ votpos - Extract the main positional columns from a VOTable
+ votsize - Get the size of a VOTable
+
+ TABLE UTILITIES
+ colbyid - Identify VOTable column by ID attribute
+ colbyucd - Identify VOTable column by UCD attribute
+ colbyname - Identify VOTable column by NAME attribute
+ tabclip - Clip a table to given boundaries
+ taboverlay - General table overlay in the image display
+
+ EXTERNAL APPLICATIONS
+ aladin - Start/Stop/Status of the Aladin image display application
+ hub - Start/Stop/Status of the SAMP Hub
+ topcat - Start/Stop/Status of the TOPCAT table display application
+
+ SAMP MESSAGE HANDLERS
+ overhandler - Default SAMP handler for image overlays
+ tblhandler - Default SAMP handler for table loading messages
+ imghandler - Default SAMP handler for image loading messages
+
+ HIDDEN TASKS
+ qstring - Generate a query string URL
+ makewcs - Create an IRAF WCS from a plate solution
+ prettystr - Pretty-print a long string
+
diff --git a/vo/votools/votools.par b/vo/votools/votools.par
new file mode 100644
index 00000000..716df601
--- /dev/null
+++ b/vo/votools/votools.par
@@ -0,0 +1,7 @@
+# VO Toolbox Sub-Package parameter file
+
+graphics,s,h,"stdgraph",,,Interactive graphics output device
+cursor,*gcur,h,"",,,Graphics cursor input
+resdb,s,h,)_.resdb,,,"Resource database"
+runid,s,h,)_.runid,,,"RunID string"
+version,s,h,"V1.0: March 1, 2012"
diff --git a/vo/votools/votpos.cl b/vo/votools/votpos.cl
new file mode 100644
index 00000000..75802abb
--- /dev/null
+++ b/vo/votools/votpos.cl
@@ -0,0 +1,118 @@
+#{ VOTPOS -- Extract the main RA/Dec columns from a VOTable.
+
+procedure votpos (input)
+
+string input { prompt = "Input VOTable" }
+string output = "STDOUT" { prompt = "Output filename" }
+
+int ra_col = INDEF { prompt = "RA column number" }
+int dec_col = INDEF { prompt = "RA column number" }
+string rows = "-" { prompt = "Rows to print" }
+
+bool header = no { prompt = "Print output header?" }
+bool number = no { prompt = "Number output rows?" }
+bool plot = no { prompt = "Plot coordinate points?" }
+bool overplot = yes { prompt = "Overplot an existing plot?" }
+int color = 1 { prompt = "Plot marker color" }
+string title = "" { prompt = "Plot title" }
+
+bool verbose = yes { prompt = "Verbose output?" }
+int status = 0 { prompt = "Service status code" }
+
+begin
+ int racol, deccol, lcolor
+ string lin, lout, ra_name, dec_name, tpos, pfields, ltitle
+ bool do_number, do_hdr, do_plot, do_overplot
+
+
+ lin = input
+ lout = output
+ do_plot = plot
+ do_number = number
+ do_hdr = header
+ ltitle = title
+
+ do_overplot = overplot
+ if (do_overplot)
+ lcolor = color + 1
+ else
+ lcolor = 1
+
+
+ # Get the RA column using either the old or new UCD.
+ if (ra_col > 0) {
+ racol = ra_col
+ keypar (lin, "TTYPE" // racol)
+ ra_name = keypar.value
+ } else {
+ colbyucd (lin, "POS_EQ_RA_MAIN")
+ if (colbyucd.column < 0) {
+ colbyucd (lin, "pos.eq.ra;meta.main")
+ if (colbyucd.column < 0) {
+ error (0, "No RA column found in table")
+ } else {
+ racol = colbyucd.column
+ ra_name = colbyucd.name
+ }
+ } else {
+ racol = colbyucd.column
+ ra_name = colbyucd.name
+ }
+ }
+
+ # Get the Dec column using either the old or new UCD.
+ if (dec_col > 0) {
+ deccol = dec_col
+ keypar (lin, "TTYPE" // deccol)
+ dec_name = keypar.value
+ } else {
+ colbyucd (lin, "POS_EQ_DEC_MAIN")
+ if (colbyucd.column < 0) {
+ colbyucd (lin, "pos.eq.dec;meta.main")
+ if (colbyucd.column < 0) {
+ error (0, "No DEC column found in table")
+ } else {
+ deccol = colbyucd.column
+ dec_name = colbyucd.name
+ }
+ } else {
+ deccol = colbyucd.column
+ dec_name = colbyucd.name
+ }
+ }
+
+ # Extract the position columnms
+ tpos = mktemp ("tmp$pos")
+ tprint (lin, prparam-, prdata+, showrow=do_number, showhdr=do_hdr,
+ column=ra_name//","//dec_name, rows=rows, option="plain", > tpos)
+
+
+ # Print the selected columns.
+ if (lout == "STDOUT") {
+ type (tpos)
+ } else if (lout != "") {
+ copy (tpos, lout, verbose-, >& "dev$null")
+ }
+
+ # Plot the positions?
+ if (do_plot) {
+ pfields = "1,2"
+ if (do_number)
+ pfields = "2,3"
+
+ fields (tpos, pfields) | graph ("STDIN", point+,
+ xformat="%H", yformat="%h", xlabel="RA", ylabel="Dec",
+ title=ltitle, marker="box", szmarker=0.01, colors=lcolor,
+ vx1=0.15, vx2=0.95, vy1=0.1, vy2=0.95, round-,
+ append=do_overplot)
+ }
+
+ # Update and save the plot color.
+ if (overplot && lcolor < 8)
+ color = lcolor + 1
+ else
+ color = 1
+ overplot = no
+
+ delete (tpos, verify-, >& "dev$null")
+end
diff --git a/vo/votools/votsize.par b/vo/votools/votsize.par
new file mode 100644
index 00000000..cd3690ca
--- /dev/null
+++ b/vo/votools/votsize.par
@@ -0,0 +1,2 @@
+input,s,a,,,,Input VOTable name
+mode,s,h,"al"
diff --git a/vo/votools/wcsinfo.cl b/vo/votools/wcsinfo.cl
new file mode 100644
index 00000000..8d9d965c
--- /dev/null
+++ b/vo/votools/wcsinfo.cl
@@ -0,0 +1,307 @@
+# WCSINFO --
+
+procedure wcsinfo (image)
+
+string image { prompt="Image name" }
+bool verbose = no { prompt="Verbose?" }
+
+string pos = "" { prompt="POS string" }
+real size = 0.0 { prompt="SIZE value" }
+real ra = 0.0 { prompt="RA value" }
+real dec = 0.0 { prompt="DEC value" }
+
+real llx = 0.0 { prompt="LLX wcs corner" }
+real lly = 0.0 { prompt="LLY wcs corner" }
+real urx = 0.0 { prompt="URX wcs corner" }
+real ury = 0.0 { prompt="URY wcs corner" }
+real midx = 0.0 { prompt="X wcs midpoint" }
+real midy = 0.0 { prompt="Y wcs midpoint" }
+real scale = 0.0 { prompt="Scale (\"/pix)" }
+real rot = 0.0 { prompt="Rotation (deg)" }
+real width = 0.0 { prompt="Plt width (arcmin)" }
+real height = 0.0 { prompt="Plt height (arcmin)" }
+string axmap = "" { prompt="Axis mapping" }
+real epoch = 0.0 { prompt="Epoch" }
+real equinox = 0.0 { prompt="Equinox" }
+string ctype1 = "" { prompt="CTYPE1" }
+string ctype2 = "" { prompt="CTYPE2" }
+real crval1 = 0.0 { prompt="CRVAL1" }
+real crval2 = 0.0 { prompt="CRVAL2" }
+real crpix1 = 0.0 { prompt="CRPIX1" }
+real crpix2 = 0.0 { prompt="CRPIX2" }
+real cd11 = 0.0 { prompt="CD1_1" }
+real cd12 = 0.0 { prompt="CD1_2" }
+real cd21 = 0.0 { prompt="CD2_1" }
+real cd22 = 0.0 { prompt="CD2_2" }
+bool ispix = no { prompt="Pixel only coords?" }
+
+begin
+ string img, lpos
+ real cdelt1, cdelt2 # old wcs/pix increment
+ real crota1, crota2 # old rotation keywords
+ real sys_epoch, sys_equinox # epoch info
+ real xrot, yrot # plate scale and rotation
+ real x1, x2, y1, y2 # corner pos
+ real lllx, llly, lurx, lury, lmx, lmy
+ int nx, ny, cx, cy
+ string imtmp, img_orig, cfile, ofile
+ bool verb
+
+
+ # Check for proper packages and reset environment.
+ reset imtype = "fits"
+ #flpr 0
+
+
+ # Get the task parameters.
+ img = image
+ verb = verbose
+
+ # Initialize.
+ cd11 = 1.0 ; cd12 = 0.0
+ cd21 = 0.0 ; cd22 = 1.0
+ crpix1 = 0.0 ; crpix2 = 0.0
+ crval1 = 0.0 ; crval2 = 0.0
+ cdelt1 = 0.0 ; cdelt2 = 0.0
+ ctype1 = "" ; ctype2 = ""
+ crota1 = 0.0 ; crota2 = 90.0 # assume normal x/y axes and
+ scale = 1.0 ; rot = 0.0 # default to 1"/pix scale
+ xrot = 0.0 ; yrot = 0.0 ; rot = 0.0
+ sys_epoch = 0.0
+ sys_equinox = 0.0
+
+ # Work on a copy of the image, not the original.
+ imtmp = mktemp ("/tmp/w")
+ imcopy (img, imtmp, verbose-)
+ img_orig = img
+ img = imtmp
+
+ # Get the size and midpoint of the image (in pixels).
+ hselect (img, "i_naxis1,i_naxis2", yes) | scan (nx, ny)
+ cx = nx / 2
+ cy = ny / 2
+
+
+ # First, see whether we have FITS standard keywords or a plate
+ # solution header (e.g. from DSS). If the latter, fix it.
+ hselect (img, "cd1_1,cd2_2", yes) | scan (x, y)
+ if (nscan() < 2) {
+ hselect (img, "amdx1,amdy1", yes) | scan (x, y)
+ if (nscan() >= 1) {
+ if (verb)
+ print ("Converting platesol header to std WCS... ")
+ makewcs (img, verbose-)
+ }
+ }
+
+
+ # Now convert the image explicitly to FK5. This will also give us a
+ # standard CD matrix instead of the CROTA/CDELT keywords
+ imcctran (img, "FK5", nx=20, ny=20, longpole-, verbose-, update+)
+
+ hselect (img, "crval1,crval2", yes) | scan (crval1, crval2)
+ if (nscan() != 2) {
+ if (verb)
+ print ("No CRVAL keywords")
+ }
+
+ hselect (img, "crpix1,crpix2", yes) | scan (crpix1, crpix2)
+ if (nscan() != 2) {
+ if (verb)
+ print ("No CRPIX keywords")
+ }
+
+ hselect (img, "ctype1,ctype2", yes) | scan (ctype1, ctype2)
+ if (nscan() == 2) {
+ s1 = strlwr (ctype1)
+ if (strstr ("dec", s1) == 1 || strstr ("lat", s1) == 1) {
+ axmap = "2 1"
+ } else if (strstr ("ra", s1) == 1 || strstr ("lon", s1) == 1) {
+ axmap = "1 2"
+ } else {
+ axmap = "1 2"
+ ispix = yes
+ }
+ ;
+ if (strstr ("-sip", strlwr (s1)) > 0) {
+ ctype1 = substr (ctype1, 1, (strlen(ctype1)-4))
+ ctype2 = substr (ctype2, 1, (strlen(ctype2)-4))
+ hedit (img, "ctype1", ctype1, verify-,update+,show-, >& "dev$null")
+ hedit (img, "ctype2", ctype2, verify-,update+,show-, >& "dev$null")
+ hedit (img, "WAT0_001", "", verify-,del+,update+,show-,>&"dev$null")
+ hedit (img, "WAT1_001", "", verify-,del+,update+,show-,>&"dev$null")
+ hedit (img, "WAT2_001", "", verify-,del+,update+,show-,>&"dev$null")
+ }
+ ;
+
+ # Check for an invalid WAT keyword suggesting physical coords. If we
+ # have them and CTYPE keywords, delete the WAT values.
+ hselect (img, "WAT0_001", "yes") | scan (s1)
+ if (s1 == "system=physical") {
+ hedit (img, "WAT0_001", del+, verify-, show-, update+)
+ hedit (img, "WAT1_001", del+, verify-, show-, update+)
+ hedit (img, "WAT2_001", del+, verify-, show-, update+)
+ hedit (img, "LTM1_1", del+, verify-, show-, update+)
+ hedit (img, "LTM2_2", del+, verify-, show-, update+)
+ hedit (img, "LTV1", del+, verify-, show-, update+)
+ hedit (img, "LTV2", del+, verify-, show-, update+)
+ }
+ ;
+
+ } else if (verb) {
+ print ("No CTYPE keywords")
+ }
+
+
+ if (ispix) {
+ # See if we have an RA/DEC keyword and put it at the middle of the image.
+ hselect (img, "ra,dec", yes) | scan (x, y)
+ if (nscan() == 2) {
+ crval1 = x * 15.
+ if (x > 24)
+ crval1 = x
+ crval2 = y
+ crpix1 = cx
+ crpix2 = cy
+ scale = 1.
+ rot = 0.
+ }
+
+
+ } else {
+ # If we have CD matrix keywords use 'em, otherwise try to fall back
+ # to the older CDELT keywords.
+ hselect (img, "cd1_1,cd2_2", yes) | scan (x, y)
+ if (nscan() >= 1) {
+ # Get the CD matrix from the image. We initialize the values above
+ # so if they don't exist in the header we won't change the value here
+ # (but we need to read them one at a time).
+ hselect (img, "cd1_1", yes) | scan (cd11)
+ hselect (img, "cd1_2", yes) | scan (cd12)
+ hselect (img, "cd2_1", yes) | scan (cd21)
+ hselect (img, "cd2_2", yes) | scan (cd22)
+
+ # Compute the plate scale (arcsec/pixel) for the image.
+ scale = 3600. * sqrt ((cd11**2+cd21**2+cd12**2+cd22**2)/2.)
+ xrot = abs (datan ( cd21, cd11))
+ yrot = abs (datan (-cd12, cd22))
+ rot = (xrot + yrot) / 2.0
+
+ } else {
+ hselect (img, "cdelt1,cdelt2", yes) | scan (cdelt1,cdelt2)
+ if (nscan() == 2)
+ scale = 3600. * sqrt ((cdelt1**2 + cdelt2**2) / 2.)
+
+ hselect (img, "crota1", yes) | scan (crota1)
+ if (nscan() == 1)
+ xrot = crota1
+ hselect (img, "crota2", yes) | scan (crota2)
+ if (nscan() == 1)
+ yrot = crota2
+ rot = yrot
+
+ }
+ }
+
+
+ # Get the epoch and equinox
+ x = -1.0 ; y = -1.0
+ hselect (img, "epoch", yes) | scan (x)
+ if (nscan() == 1 && x > 0.0)
+ sys_epoch = x
+ else
+ sys_epoch = 2000.0
+
+ hselect (img, "equinox", yes) | scan (x)
+ if (nscan() == 1 && y > 0.0)
+ sys_equinox = y
+ else
+ sys_equinox = 2000.0
+
+ epoch = sys_epoch
+ equinox = sys_equinox
+
+ if (ispix) {
+
+ lllx = (crval1 - (cx/3600.))/15.; # assumes hours of RA
+ llly = (crval2 - (cy/3600.));
+ lurx = (crval1 + (cx/3600.))/15.; # assumes hours of RA
+ lury = (crval2 + (cy/3600.));
+ lmx = crval1 / 15.
+ lmy = crval2
+
+ llx = lllx * 15.0 ; lly = llly
+ urx = lurx * 15.0 ; ury = lury
+ midx = lmx * 15.0 ; midy = lmy
+
+ } else {
+
+ cfile = mktemp ("/tmp/cf")
+ ofile = mktemp ("/tmp/of")
+ print ("1.0 1.0", > cfile)
+ print (nx // " " // ny, >> cfile)
+ print (cx // " " // cy, >> cfile)
+ skyctran (cfile, ofile, img, img//" world", >& "dev$null")
+
+ tail (ofile, nl=1) | head ("STDIN", nl=1) | scan (x, y, lmx, lmy )
+ tail (ofile, nl=2) | head ("STDIN", nl=1) | scan (x, y, lurx, lury)
+ tail (ofile, nl=3) | head ("STDIN", nl=1) | scan (x, y, lllx, llly)
+
+ # Update the task parameters.
+ if (axmap == "1 2") {
+ llx = lllx * 15.0 ; lly = llly
+ urx = lurx * 15.0 ; ury = lury
+ midx = lmx * 15.0 ; midy = lmy
+ ra = midx ; dec = midy
+
+ } else {
+ lly = lllx * 15.0 ; llx = llly
+ ury = lurx * 15.0 ; urx = lury
+ midy = lmx * 15.0 ; midx = lmy
+ ra = midy ; dec = midx
+ }
+ printf ("%g,%g\n", ra, dec) | scan (lpos)
+ pos = lpos
+ size = max ((scale * nx), (scale * ny)) / 3600. # in degrees
+
+ delete (cfile, verify-, >& "dev$null")
+ delete (ofile, verify-, >& "dev$null")
+ }
+ width = real (scale * nx) / 60. # plate width in arcmin
+ height = real (scale * ny) / 60. # plate height in arcmin
+
+
+ if (verb) {
+ print ("CRPIX1 = " // crpix1)
+ print ("CRPIX2 = " // crpix2)
+ print ("CTYPE1 = " // ctype1)
+ print ("CTYPE2 = " // ctype2)
+ printf ("CRVAL1 = %g\t/ X wcs = %.3H\n", crval1, crval1)
+ printf ("CRVAL2 = %g\t/ Y wcs = %.3h\n", crval2, crval2)
+ print ("CD1_1 = " // cd11)
+ print ("CD1_2 = " // cd12)
+ print ("CD2_1 = " // cd21)
+ print ("CD2_2 = " // cd22)
+ print ("CDELT1 = " // cdelt1) ; print ("CDELT2 = " // cdelt2)
+ print ("CROTA1 = " // crota1) ; print ("CROTA2 = " // crota2)
+
+ print ("EPOCH = " // sys_epoch)
+ print ("EQUINOX = " // sys_equinox)
+ print ("PLTSCALE= " // scale // " / arc/pix")
+ print ("PLT_ROT = " // rot // " / degrees")
+ printf ("PLT_WID = %-14.9g\t/ Field width (arcmin)\n", width);
+ printf ("PLT_HGT = %-14.9g\t/ Field height (arcmin)\n", height);
+ printf ("PLT_LLX = %-14.9g\t/ LL X wcs = %.3h\n", lllx*15., lllx)
+ printf ("PLT_URX = %-14.9g\t/ UR X wcs = %.3h\n", lurx*15., lurx)
+ printf ("PLT_MX = %-14.9g\t/ Mid X wcs = %.3h\n", lmx*15., lmx)
+ printf ("PLT_LLY = %-14.9g\t/ LL Y wcs = %.3h\n", llly, llly)
+ printf ("PLT_URY = %-14.9g\t/ UR Y wcs = %.3h\n", lury, lury)
+ printf ("PLT_MY = %-14.9g\t/ Mid Y wcs = %.3h\n", lmy, lmy)
+ printf ("AXMAP = %s\t\t\t/ Axis mapping\n", axmap)
+ printf ("ISPIX = %b\t\t\t/ Pixel mapping?\n", ispix)
+ }
+
+ # Clean up.
+ if (imaccess (imtmp) == yes)
+ delete (imtmp//".fits", verify-, >& "dev$null")
+end
diff --git a/vo/votools/x_votools.x b/vo/votools/x_votools.x
new file mode 100644
index 00000000..6d158a01
--- /dev/null
+++ b/vo/votools/x_votools.x
@@ -0,0 +1,11 @@
+task dalclient = t_dalclient,
+ dbglevel = t_dbglevel,
+ sesame = t_sesame,
+ votcopy = t_votcopy,
+ votsize = t_votsize,
+ votget = t_votget,
+ vodata = t_vodata,
+ sbquery = t_sbquery,
+ vocdctl = t_vocdctl,
+ dispname = t_dispname,
+ makewcs = t_makewcs
diff --git a/vo/votools/xrayoverlay.cl b/vo/votools/xrayoverlay.cl
new file mode 100644
index 00000000..073d4190
--- /dev/null
+++ b/vo/votools/xrayoverlay.cl
@@ -0,0 +1,74 @@
+#{ RADIOOVERLAY -- Overlay a radio contour on the image display.
+
+procedure xrayoverlay (image)
+
+string image { prompt = "Input image" }
+
+real size = 0.25 { prompt = "Query size" }
+int ncontours = 0 { prompt = "No. contours to draw" }
+
+bool append = yes { prompt = "Append display?" }
+bool verbose = yes { prompt = "Verbose output?" }
+string device = "imdgreen" { prompt = "Overlay device" }
+int status = 0 { prompt = "Service status code" }
+
+begin
+ string img, rimg, imname, ovdev, base, url, query
+ string fields, pos_all, pos_l, pos_w, restab
+ real ra, dec, sz
+ bool verb, app
+ int siap, count, ncont
+
+
+ img = image # Get params to local variables
+ sz = size
+ verb = verbose
+ app = append
+ ncont = ncontours
+ ovdev = device
+ restab = mktemp ("tmp$res") // ".xml"
+ rimg = mktemp ("tmp$img") // ".fits"
+
+ base = "http://skyview.gsfc.nasa.gov/cgi-bin/vo/sia.pl?survey=rass3&"
+
+ if (imaccess (img)) {
+ iferr { wcsinfo (img) } then {
+ error (0, "Cannot determine image coords for `"//img//"'")
+ } else {
+ ra = wcsinfo.midx
+ dec = wcsinfo.midy
+ sz = max (wcsinfo.width, wcsinfo.height) / 60.0
+ if (!app)
+ display (img, 1, >& "dev$null")
+ }
+ } else {
+ sesame (img, verbose-)
+ ra = sesame.ra
+ dec = sesame.dec
+ if (!app)
+ dss (img, size=sz, use_display+)
+ }
+
+ # Create temp files for the output
+ rimg = mktemp ("tmp$radov") // ".fits"
+
+ # Generate the query string from the RASS3 broad-band x-ray survey.
+ printf ("POS=%.5f,%.5f&SIZE=%.3f", ra, dec, sz) | scan (query)
+ url = base // query // "&RUNID=" // vo.runid
+
+
+ # Download the query string.
+ urlget (url, restab)
+
+ tdump (restab, row=1, col="URL", pwidth=2048, cdfile="dev$null",
+ pfile="dev$null") | scan (rimg)
+
+ # Overlay the contours
+ contour (rimg, dev=ovdev, title="", perim-, fill+, xres=64, yres=64,
+ ncontours=ncont, >& "dev$null")
+
+ # Clean up.
+ delete (restab, verify-, >& "dev$null")
+ imdelete (rimg, >& "dev$null")
+end
+