aboutsummaryrefslogtreecommitdiff
path: root/vendor/voclient/voapps/voatlas.c
diff options
context:
space:
mode:
Diffstat (limited to 'vendor/voclient/voapps/voatlas.c')
-rw-r--r--vendor/voclient/voapps/voatlas.c660
1 files changed, 660 insertions, 0 deletions
diff --git a/vendor/voclient/voapps/voatlas.c b/vendor/voclient/voapps/voatlas.c
new file mode 100644
index 00000000..a72f4422
--- /dev/null
+++ b/vendor/voclient/voapps/voatlas.c
@@ -0,0 +1,660 @@
+/**
+ * VOATLAS -- Query the SkyView Image service for an all-sky image.
+ *
+ * Usage: voatlas [<opts>] <name> | <ra dec>
+ *
+ * Where
+ * -%%,--test run unit tests
+ * -h,--nelp this message
+ * -d,--debug enable debug messages
+ * -r,--return return result from method
+ *
+ * -b,--band <bpass> Bandpass
+ * -l,--list List available surveys for position
+ * -p,--survey <survey> Survey program name
+ * -g,--graphic Get a graphic image (i.e. JPEG)
+ * -n,--naxis <npix> Set returned image size
+ *
+ * -s,--size <size> Field size
+ * <size>s Field size (arcsec)
+ * <size>m Field size (arcmin)
+ * <size>d Field size (degrees, default)
+ * -F,--field <field> Resolve query field name
+ * -R,--ra <ra> Set query RA position
+ * -D,--dec <dec> Set query Dec position
+ * -P,--pos <ra,dec> Set query as a POS string
+ * -S,--samp Broadcast as SAMP message
+ * -o <name> Save image to named file
+ *
+ * <name> Target name to be resolved to position
+ * <ra> <dec> Position to query (dec. deg or Eq. sexagesimal)
+ *
+ *
+ * @file voatlas.c
+ * @author Mike Fitzpatrick
+ * @date 7/03/12
+ *
+ * @brief Query the SkyView Image service for an all-sky image.
+ */
+
+
+#define _GNU_SOURCE /* for strcasestr() on linux */
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <string.h>
+#include <ctype.h>
+#include "VOClient.h"
+#include "voApps.h"
+#include "samp.h"
+
+
+static double ra = 0.0; /* default values */
+static double dec = 0.0;
+static double size = 0.25;
+
+static int debug = FALSE; /* debug output */
+static int do_samp = FALSE; /* broadcast SAMP msg? */
+static int graphic = FALSE; /* get graphics format? */
+static int list_surveys = FALSE; /* list results? */
+static int verbose = FALSE; /* verbose output? */
+static char *field = NULL; /* Input field name */
+static char *pos = NULL; /* Input position */
+static char *bpass = NULL; /* Bandpass */
+
+static char svc_url[SZ_URL], survey[SZ_FNAME];
+
+
+static char *base_url = "http://skyview.gsfc.nasa.gov/cgi-bin/vo/sia.pl?";
+
+static int voa_resolveField (char *field, double *ra, double *dec);
+static int voa_resolvePos (char *pos, double *ra, double *dec);
+static double voa_getSize (char *arg);
+static int voa_callService (char *url, double ra, double dec, double size,
+ char *ofname, char *format, int maximages);
+
+extern double sexa (char *s);
+extern char *strcasestr ();
+extern int vot_atoi (char *v);
+extern double vot_atof (char *v);
+
+
+#ifdef USE_RESBUF
+static char *resbuf; /* result buffer */
+#endif
+
+
+/* Task specific option declarations.
+ */
+int voatlas (int argc, char **argv, size_t *len, void **result);
+
+static int do_return = 0;
+static Task self = { "voatlas", voatlas, 0, 0, 0 };
+static char *opts = "%hF:R:D:P:b:dgs:o:Srlp:n:v";
+static struct option long_opts[] = {
+ { "field", 1, 0, 'F'}, /* query field name */
+ { "ra", 1, 0, 'R'}, /* RA of position */
+ { "dec", 1, 0, 'D'}, /* Dec of position */
+ { "pos", 1, 0, 'P'}, /* POS position */
+ { "graphics", 2, 0, 'g'}, /* graphics format? */
+ { "band", 1, 0, 'b'}, /* bandpass */
+ { "list", 2, 0, 'l'}, /* list surveys */
+ { "survey", 1, 0, 'p'}, /* survey name */
+ { "naxis", 1, 0, 'n'}, /* image size */
+ { "size", 1, 0, 's'}, /* query size */
+ { "output", 1, 0, 'o'}, /* set output name */
+ { "samp", 2, 0, 'S'}, /* broadcast SAMP */
+ { "verbose", 2, 0, 'v'}, /* required */
+ { "help", 2, 0, 'h'}, /* required */
+ { "debug", 2, 0, 'd'}, /* required (debug) */
+ { "test", 2, 0, '%'}, /* required */
+ { "return", 1, 0, 'r'}, /* required */
+ { NULL, 0, 0, 0 }
+};
+
+static void Usage (void);
+static void Tests (char *input);
+
+
+
+/**
+ * Application entry point.
+ */
+int
+voatlas (int argc, char **argv, size_t *reslen, void **result)
+{
+ char **pargv, optval[SZ_FNAME], ch;
+ char *iname = NULL, *oname = NULL, *dlname = NULL;
+ char tmp[SZ_FNAME], buf[SZ_FNAME];
+ int i=1, status = OK, apos = 0, samp = -1, naxis = 512;
+
+
+ /* Initialize.
+ */
+ memset (buf, 0, SZ_FNAME);
+ memset (tmp, 0, SZ_FNAME);
+ memset (survey, 0, SZ_FNAME);
+ memset (svc_url, 0, SZ_URL);
+
+ *reslen = 0;
+ *result = NULL;
+
+
+ /* Parse the argument list.
+ */
+ pargv = vo_paramInit (argc, argv, opts, long_opts);
+ while ((ch = vo_paramNext (opts,long_opts,argc,pargv,optval,&apos)) != 0) {
+ i++;
+ if (ch > 0) {
+ switch (ch) {
+ case '%': Tests (optval); return (self.nfail);
+ case 'h': Usage (); return (OK);
+ case 'd': debug++; break;
+ case 'r': do_return++; break;
+
+ case 'b': bpass = strdup (optval); i++; break;
+ case 'g': graphic++; break;
+ case 'l': list_surveys++;
+ strcpy (survey, "list"); break;
+ case 'p': strcpy (survey, optval); i++; break;
+ case 'n': naxis = vot_atoi (optval); i++; break;
+
+ case 'F': field = strdup (optval); i++; break;
+ case 'R': if (strchr (optval, (int)':'))
+ ra = (15. * (double) sexa (optval));
+ else
+ ra = (double) vot_atof (optval);
+ i++;
+ break;
+ case 'D': if (strchr (optval, (int)':'))
+ dec = (double) sexa (optval);
+ else
+ dec = (double) vot_atof (optval);
+ i++;
+ break;
+ case 'P': sscanf (optval, "%lf,%lf", &ra, &dec);
+ i++;
+ break;
+
+ case 's': size = voa_getSize(optval); i++; break;
+ case 'o': oname = strdup (optval); i++; break;
+
+ case 'S': do_samp = 1; break;
+ case 'v': verbose = 1; break;
+
+ default:
+ fprintf (stderr, "Invalid argument '%c'\n", ch);
+ return (ERR);
+ }
+
+ } else if (ch == PARG_ERR) {
+ return (ERR);
+
+ } else {
+ if (i == (argc-2)) {
+ sprintf (buf, "%s %s", optval, argv[i+1]);
+ pos = strdup (buf);
+ sscanf (pos, "%lf %lf", &ra, &dec);
+ } else
+ field = strdup (optval);
+ break;
+ }
+ }
+
+
+ /* Sanity checks.
+ */
+ if (!field && !pos && (ra == 0.0 && dec == 0.0)) {
+ fprintf (stderr, "Error: no field/position specified.\n");
+ return (ERR);
+ }
+
+ if (!survey[0]) {
+ /* No survey specified so go by the bandpass.
+ */
+ if (!bpass)
+ strcpy (survey, "dss2b");
+ else {
+ if (strncasecmp (bpass, "optical", 3) == 0)
+ strcpy (survey, "dss");
+ else if (strncasecmp (bpass, "infrared", 3) == 0 ||
+ strncasecmp (bpass, "ir", 2) == 0)
+ strcpy (survey, "2massk");
+ else if (strncasecmp (bpass, "x-ray", 1) == 0)
+ strcpy (survey, "pspc2int");
+ else if (strncasecmp (bpass, "euv", 3) == 0)
+ strcpy (survey, "euve83");
+ else if (strncasecmp (bpass, "gamma-ray", 5) == 0)
+ strcpy (survey, "egret1000");
+ else if (strncasecmp (bpass, "radio", 3) == 0)
+ strcpy (survey, "4850mhz");
+ }
+ } else if (strcasecmp (survey, "list") == 0) {
+ list_surveys = 1;
+ memset (survey, 0, SZ_FNAME);
+ }
+
+
+ /* Setup the output name.
+ */
+ if (oname) {
+ dlname = oname; /* output name specified */
+ } else if (do_samp) {
+ strcpy (tmp, "/tmp/voatlasXXXXXX"); /* temp download name */
+ mktemp (tmp);
+ dlname = tmp;
+ } else {
+ if (field)
+ sprintf (buf, "%s.%s", field, (graphic ? "jpg" : "fits"));
+
+ else if (pos) {
+ char *ip, *op;
+
+ memset (buf, 0, SZ_FNAME);
+ for (op=buf, ip=pos; *ip; ip++)
+ *op++ = (*ip == ' ' ? '_' : *ip);
+ strcat (buf, ".");
+ strcat (buf, (graphic ? "jpg" : "fits"));
+
+ } else if (list_surveys) {
+ if (verbose)
+ fprintf (stderr,
+ "Warning: no field/position specified, using (0.,0.).\n");
+
+ } else {
+ fprintf (stderr, "Error: no output name specified.\n");
+ status = ERR;
+ goto done_;
+ }
+ dlname = oname = strdup (buf);
+ }
+
+
+ if (debug) {
+ fprintf (stderr, "field='%s' pos='%s' ra=%g dec=%g\n",
+ field, pos, ra, dec);
+ fprintf (stderr, "bpass='%s' survey='%s'\n", bpass, survey);
+ fprintf (stderr, "oname='%s'\n", oname);
+ }
+
+ /* Initialize the VOClient code. Error messages are printed by the
+ * interface so we just quit if there is a problem.
+ */
+ if (voc_initVOClient ("runid=voc.voatlas") == ERR)
+ return (ERR);
+
+ /* Sanity checks
+ */
+ if (iname == NULL) iname = strdup ("stdin");
+ if (oname == NULL) oname = strdup ("stdout");
+ if (strcmp (iname, "-") == 0) { free (iname), iname = strdup ("stdin"); }
+ if (strcmp (oname, "-") == 0) { free (oname), oname = strdup ("stdout"); }
+
+ if (field && pos) {
+ fprintf (stderr,
+ "Error: only one of 'field' or 'pos' may be specified.\n");
+ status = ERR;
+ goto done_;
+ } else if (field) {
+ if (voa_resolveField (field, &ra, &dec) == OK) {
+ fprintf (stderr, "Error: cannot resolve object '%s'\n", field);
+ status = ERR;
+ goto done_;
+ }
+ } else if (pos) {
+ if (voa_resolvePos (pos, &ra, &dec) != OK) {
+ fprintf (stderr, "Error: cannot convert position '%s'\n", pos);
+ status = ERR;
+ goto done_;
+ }
+ }
+
+
+ /* Form the service URL.
+ */
+ memset (svc_url, 0, SZ_URL);
+ sprintf (svc_url, "%snaxis=%d&", base_url, naxis);
+ if (survey[0]) {
+ strcat (svc_url, "survey=");
+ strcat (svc_url, survey);
+ strcat (svc_url, "&");
+ }
+ if (debug)
+ fprintf (stderr, "ra = %g dec = %g\nurl='%s'\n", ra, dec, svc_url);
+
+
+ /* Call the SkyView SIA service.
+ */
+ if (voa_callService (svc_url, ra, dec, size, dlname,
+ (graphic ? "jpeg" : "fits"), 1) == ERR) {
+ fprintf (stderr, "Error: cannot contact SkyView service\n");
+ status = ERR;
+ goto done_;
+ }
+
+ /* Broadcast the image as a message if requested.
+ */
+ if (do_samp) {
+ if ((samp = sampInit ("voatlas", "VOClient Task")) >= 0) {
+ char url[SZ_LINE], cwd[SZ_LINE];
+
+ samp_setSyncMode (samp); /* use asynchronous mode */
+ sampStartup (samp); /* register w/ Hub */
+
+ memset (url, 0, SZ_LINE);
+ memset (cwd, 0, SZ_LINE);
+ getcwd (cwd, SZ_LINE);
+ if (tmp[0])
+ sprintf (url, "file://%s", dlname);
+ else
+ sprintf (url, "file://%s/%s", cwd, oname);
+
+ if (verbose)
+ printf ("Displaying image %s ...\n", url);
+ (void) samp_imageLoadFITS (samp, "all", url, "", field);
+
+ if (tmp[0])
+ unlink (dlname);
+ sampShutdown (samp);
+ }
+ }
+
+
+ /* See if we're returning the image.
+ */
+ if (do_return) {
+ vo_setResultFromFile (dlname, reslen, result);
+ unlink (dlname);
+ }
+
+
+ /* Clean up and shutdown.
+ */
+done_:
+ if (pos) free (pos);
+ if (field) free (field);
+ if (iname) free (iname);
+ if (oname) free (oname);
+
+ voc_closeVOClient (1);
+ vo_paramFree (argc, pargv);
+
+ sleep (2); /* FIXME -- SkyView seems to have a reset issue... */
+
+ return (status);
+}
+
+
+/**
+ * USAGE -- Print task help summary.
+ */
+static void
+Usage (void)
+{
+ fprintf (stderr, "\n Usage:\n\t"
+ "voatlas [<opts>] [<field> | <pos>]\n\n"
+ " where\n"
+ " -%%,--test run unit test\n"
+ " -d,--debug enable debugging\n"
+ " -h,--nelp this messag\n"
+ " -r,--return return result from metho\n"
+ "\n"
+ " -b,--band <bpass> Bandpas\n"
+ " -p,--survey <survey> Survey program nam\n"
+ " -g,--graphic Get a graphic image (i.e. JPEG\n"
+ " -n,--naxis <npix> Set returned image size\n"
+ "\n"
+ " -s,--size <size> Field siz\n"
+ " <size>s Field size (arcsec\n"
+ " <size>m Field size (arcmin\n"
+ " <size>d Field size (degrees, default\n"
+ " -F,--field <field> Resolve query field nam\n"
+ " -R,--ra <ra> Set query RA positio\n"
+ " -D,--dec <dec> Set query Dec positio\n"
+ " -P,--pos <ra,dec> Set query as a POS strin\n"
+ " -S,--samp Broadcast as SAMP messag\n"
+ " -v,--verbose Verbose output\n"
+ " -o <name> Save image to named fil\n"
+ "\n"
+ " <name> Target name to be resolved\n"
+ " <ra> <dec> Position to query\n"
+ "\n"
+ "Examples:\n\n"
+ " 1) Display an image of M83 on Aladin using SAMP\n\n"
+ " %% voatlas --samp m83\n"
+ "\n"
+ " 2) Get a 256x256 JPEG image of the Sombrero galaxy\n\n"
+ " %% voatlas -o gal.jpg -n 256 --graphic sombrero\n"
+ "\n"
+ " 3) Get a 20 arcmin Wise 2.2micron survey image of m101\n\n"
+ " %% voatlas -s 20m --survey=wise22 m101\n"
+ "\n"
+ " 4) Get a radio image of 3c273, image will be '3c273.fits'\n\n"
+ " %% voatlas --band=radio 3c273\n"
+ "\n"
+ " 5) List (verbose) the survey images available for ngc1234\n\n"
+ " %% voatlas --survey=list -v ngc1234\n"
+ "\n"
+ );
+}
+
+
+/**
+ * Tests -- Task unit tests.
+ */
+static void
+Tests (char *input)
+{
+ Task *task = &self;
+
+ vo_taskTest (task, "--help", NULL);
+ vo_taskTest (task, "-S", "m83", NULL); // Ex 1
+ vo_taskTest (task, "--samp", "m83", NULL);
+
+ vo_taskTest (task, "-o", "gal.jpg", "-n", "256", // Ex 2
+ "--graphic", "sombrero", NULL);
+
+ vo_taskTest (task, "-s", "20m", "--survey=wise22", "m101", NULL); // Ex 3
+
+ vo_taskTest (task, "--band=radio", "3c273", NULL); // Ex 4
+
+ vo_taskTest (task, "--survey=list", "-v", "ngc1234", NULL); // Ex 5
+
+ vo_taskTest (task, "m51", NULL);
+ vo_taskTest (task, "-o", "m51.fits", "m51", NULL);
+ vo_taskTest (task, "--ra=202.47", "--dec=47.195", "--samp", NULL);
+
+ /* Clean up any files we created.
+ */
+ if (access ("m51.fits", F_OK) == 0) unlink ("m51.fits");
+ if (access ("m101.fits", F_OK) == 0) unlink ("m101.fits");
+ if (access ("3c273.fits", F_OK) == 0) unlink ("3c273.fits");
+ if (access ("gal.jpg", F_OK) == 0) unlink ("gal.jpg");
+
+ vo_taskTestReport (self);
+}
+
+
+
+/**
+ * Simple test routine to call a Siap search service and summarize results.
+ */
+static int
+voa_callService (char *svc_url, double ra, double dec, double size,
+ char *ofname, char *format, int maximages)
+{
+ char *acref = NULL, *fmt = NULL, *program = NULL;
+ double dra, ddec;
+ int i, nrec = 0, recnum = 0;
+ FILE *fd = (FILE *) NULL;
+
+
+ DAL siap; /* DAL Connection */
+ Query query; /* query handle */
+ QResponse qr; /* query response handle */
+ QRecord rec; /* result record handle */
+ QRAttribute v; /* dataset attribute */
+
+
+ /* Get a new connection to the named service.
+ */
+ siap = voc_openSiapConnection (svc_url); /* open a connection */
+
+ /* Form a query. Here we'll use the one search size we're given for
+ * both the RA,DEC sizes, and specify a null format.
+ */
+ query = voc_getSiapQuery (siap, ra, dec, size, size,
+ (list_surveys ? NULL : (graphic ? "image/jpeg" : "image/fits")));
+
+
+ if (VOAPP_DEBUG) {
+ fprintf (stderr, "Executing Query:\n %s\n\n",
+ voc_getQueryString (query, SIAP_CONN, 0));
+ }
+
+
+ /* Execute the query.
+ */
+ qr = voc_executeQuery (query); /* execute the query */
+ if ((nrec = voc_getRecordCount (qr)) <= 0)
+ return (ERR);
+
+ if (do_return && list_surveys)
+ fd = fopen (ofname, "w+");
+ else
+ fd = stdout;
+
+
+ /* Download the first 'maximages' images.
+ */
+ for (i=0; i < nrec && i < nrec; i++) {
+ rec = voc_getRecord (qr, i); /* get a row in the table */
+
+ v = voc_getAttribute (rec, "Format"); /* get the right format */
+ if (!(fmt = voc_stringValue(v)) || strcasestr (fmt, format) == NULL)
+ if (!list_surveys)
+ continue;
+
+ v = voc_getAttribute (rec, "Title"); /* get the survey */
+ program = voc_stringValue(v);
+ if (list_surveys) {
+ v = voc_getAttribute (rec, "Ra"); dra = voc_floatValue (v);
+ v = voc_getAttribute (rec, "Dec"); ddec = voc_floatValue (v);
+ if (verbose)
+ fprintf (fd, "%3d %12.12s %g %g %s\n",
+ (i+1), program, dra, ddec, fmt);
+ else
+ fprintf (fd, "%3d %12.12s %s\n", (i+1), program, fmt);
+
+ } else if (program) {
+ int plen = strlen (program);
+ int slen = strlen (survey);
+
+ if (strncasecmp (program, survey, min(plen,slen)) == 0) {
+ if ((v = voc_getAttribute (rec, "AccessReference"))) {
+ acref = voc_stringValue (v);
+ if (verbose) {
+ printf ("Downloading %d of %d: '%s' ....",
+ i, nrec, ofname);
+ fflush (stdout);
+ }
+ if ( voc_getDataset (rec, acref, ofname) != OK ) {
+ if (verbose)
+ printf ("error downloading file\n");
+ return (ERR);
+ }
+ if (verbose)
+ printf ("done\n");
+
+ if ( ++recnum >= maximages )
+ break;
+ }
+ }
+ }
+ }
+
+ if (fd != stdout)
+ fclose (fd);
+
+ voc_closeConnection (siap); /* close the siap connection */
+ return (OK);
+}
+
+
+/**
+ * VOA_RESOLVEPOS -- Resolve a position string to decimal degrees.
+ */
+static int
+voa_resolvePos (char *pos, double *ra, double *dec)
+{
+ char *ip = NULL, *s1 = NULL, *s2 = NULL;
+
+
+ if ( (ip = strchr (pos, (int)' '))) {
+ *ip = '\0';
+ s1 = pos;
+ s2 = ip + 1;
+
+ if (strchr (s1, (int)':'))
+ *ra = (15. * (double) sexa (s1));
+ else
+ *ra = (double) vot_atof (s1);
+ *dec = (strchr (s2,(int)':') ?
+ (double) sexa (s2) : (double) vot_atof (s2));
+
+ return (OK);
+ } else
+ return (ERR);
+
+}
+
+
+/**
+ * VOA_RESOLVEFIELD -- Resolve an object field name to a position in decimal
+ * degrees.
+ */
+static int
+voa_resolveField (char *field, double *ra, double *dec)
+{
+ Sesame sr;
+ extern char *vo_urlEncode();
+
+
+ if ((sr = voc_nameResolver (vo_urlEncode (field))) != 0) {
+ *ra = (double) voc_resolverRA (sr);
+ *dec = (double) voc_resolverDEC (sr);
+ }
+ return ((sr > 0) ? OK : ERR);
+}
+
+
+/**
+ * VOA_GETSIZE -- Convert an argument size spec into a decimal degree value.
+ */
+static double
+voa_getSize (char *arg)
+{
+ int len = strlen (arg);
+ int unit = 'd';
+ double size = (double) 0.0;
+
+
+ if (isalpha ((int) arg[len-1]) && arg[len-1] != '.') {
+ unit = tolower (arg[len-1]);
+ if (strchr ("mdsMDS", unit) == NULL) {
+ fprintf (stderr, "Error: Invalid size unit '%c'\n", unit);
+ return (size);
+ }
+ arg[len-1] = '\0';
+ }
+
+ /* Convert to decimal degrees for the query.
+ */
+ switch (unit) {
+ case 'd': return ( vot_atof (arg) );
+ case 'm': return ( vot_atof (arg) / 60. );
+ case 's': return ( vot_atof (arg) / 3600. );
+ }
+
+ return ((double) 0.0);
+}