XEphem/GUI/xephem/gscnet.c

448 lines
12 KiB
C

/* fetch GSC stars from the network.
*/
#include <stdio.h>
#include <math.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include "xephem.h"
static int moreObjF (ObjF **opp, int nop, int nnew);
/* fetch GSC 2.3 stars around the given field of view from STScI.
* if find some add them to the list at *opp and return new total, else
* limit FOV to 30 arc mins -- these fields can be very dense.
* return -1 with a diagnostic message in msg[].
*/
int
gsc23fetch (
char *url, /* everything in the URL except the query */
Now *np, /* current circumstances */
double ra, double dec, /* RA/Dec of center of view, rads, J2000 */
double fov, /* diamater of field of view, rads */
double lmag, /* limiting magnitude desired */
ObjF **opp, /* *opp is malloced with stars found */
int nop, /* number already at *opp */
char msg[]) /* return diagnostic message here, if returning -1 */
{
#define GSC23MAXFOV degrad(30./60.0) /* max fov */
/* http://gsss.stsci.edu/webservices/vo/ConeSearch.aspx?RA=10.0&DEC=5.0&SR=0.2&FORMAT=CSV */
static char ifmt[] = "%[^,],%lf,%lf,%*[^,],%*[^,],%*[^,],%*[^,],%lf,%lf,%*[^,],%*[^,],%lf,%lf,%lf,%*[^,],%*[^,],%*[^,],%*[^,],%*[^,],%*[^,],%*[^,],%*[^,],%*[^,],%*[^,],%*[^,],%*[^,],%*[^,],%*[^,],%*[^,],%*[^,],%*[^,],%d";
static char gfmt[] = " GET http://%s%s?RA=%g&DEC=%g&SR=%g&FORMAT=CSV HTTP/1.0\r\nUser-Agent: xephem/%s\r\n\r\n";
char host[1024];
char buf[2048];
char *hp1;
int sockfd;
int n, nstars, nnew;
/* clamp fov */
if (fov > GSC23MAXFOV) {
static int fovwarned;
if (!fovwarned) {
xe_msg (1, "All GSC 2.3 downloads will be limited to %.2f degree FOV",
raddeg(GSC23MAXFOV));
fovwarned = 1;
}
fov = GSC23MAXFOV;
}
/* extract host */
if (strncmp (url, "http://", 7)) {
strcpy (msg, "URL must start with http://");
return (-1);
}
if (!(hp1 = strchr (url+7, '/'))) {
strcpy (msg, "no host found in URL");
return (-1);
}
sprintf (host, "%.*s", (int)(hp1-(url+7)), url+7);
/* format the GET */
(void) sprintf (buf, gfmt, host, hp1, raddeg(ra), raddeg(dec),
raddeg(fov)/2, PATCHLEVEL);
/* let user abort */
stopd_up();
/* send the GET method to host and connection to read response */
sockfd = httpGET (host, buf, msg);
if (sockfd < 0) {
stopd_down();
return (-1);
}
/* now read lines of stars from the socket and collect in opp array */
nnew = 0;
pm_up();
pm_set(0);
while ((n = recvlineb (sockfd, buf, sizeof(buf))) > 0) {
char name[1024];
double radeg, decdeg;
double fmag, jmag, bmag, vmag, rmag;
int class;
Obj *op;
/* look for total */
if (sscanf (buf, " Objects found : %d", &nstars) == 1)
continue;
/* crack */
if (sscanf (buf, ifmt, name, &radeg, &decdeg, &fmag, &jmag, &bmag,
&vmag, &rmag, &class) != 9)
continue;
if (fmag>lmag && jmag>lmag && bmag>lmag && vmag>lmag && rmag>lmag)
continue;
/* good -- grow list */
if (moreObjF (opp, nop, 1) < 0) {
(void) strcpy (msg, "No memory");
(void) close (sockfd);
stopd_down();
return (-1);
}
op = (Obj *)(&(*opp)[nop++]);
zero_mem ((void *)op, sizeof(ObjF));
/* add */
(void) sprintf (op->o_name, "GSC2.3 %.*s", MAXNM-8, name);
op->o_type = FIXED;
switch (class) {
case 0: op->f_class = 'S'; break;
case 1: op->f_class = 'G'; break;
default: op->f_class = 'T'; break;
}
op->f_RA = degrad (radeg);
op->f_dec = degrad (decdeg);
op->f_epoch = (float)J2000;
if (vmag<=lmag)
set_fmag (op, vmag);
else if (bmag<=lmag)
set_fmag (op, bmag);
else if (rmag<=lmag)
set_fmag (op, rmag);
else if (fmag<=lmag)
set_fmag (op, fmag);
else
set_fmag (op, jmag);
if (nstars > 0)
pm_set (100*nnew++/nstars);
}
(void) close (sockfd);
stopd_down();
pm_down();
if (n < 0) {
(void) strcpy (msg, syserrstr());
return (-1);
}
return (nop);
}
#if 0 /* depricated */
/* fetch GSC stars around the given field of view from the named xephem host.
* if find some add them to the list at *opp and return new total, else
* return -1 with a diagnostic message in msg[].
*/
int
gscnetfetch (
char *url, /* http://<host>/xephemdbd.pl or whatever */
Now *np, /* current circumstances */
double ra, double dec, /* RA/Dec of center of view, rads, J2000 */
double fov, /* diamater of field of view, rads */
double mag, /* limiting magnitude desired */
ObjF **opp, /* *opp is malloced with stars found */
int nop, /* number already at *opp */
char msg[]) /* return diagnostic message here, if returning -1 */
{
static char ofmt[] = "GET http://%s%s?VERSION=3&FMT=EDB&CENTRIC=GEO&PRECES=ASTRO&GS=on&DATE=Now&TIME=&RA=%s&DEC=%s&FOV=%g&MAG=%g&LAT=0+0+0&LONG=0+0+0&ELEV=0 HTTP/1.0\r\nUser-Agent: xephem/%s\r\n\r\n";
char *h0p, *h1p, host[1024];
char rbuf[32], *rbp, dbuf[32], *dbp;
char buf[2048];
int sockfd;
int n;
/* confirm http and pull out the host from url */
if ((h0p = strstr (url, "http://")) || (h0p = strstr (url, "HTTP://")))
h0p += 7;
else {
strcpy (msg, "URL must begin with http://");
return (-1);
}
h1p = strchr (h0p, '/');
if (!h1p) {
(void) strcpy (msg, "No host in xephemdbd url");
return (-1);
}
(void) sprintf (host, "%.*s", (int)(h1p-h0p), h0p);
/* format the GET -- skip leading blanks in rbuf and dbuf */
fs_sexa (rbuf, radhr(ra), 2, 36000);
for (rbp = rbuf; *rbp == ' '; rbp++) continue;
fs_sexa (dbuf, raddeg(dec), 3, 3600);
for (dbp = dbuf; *dbp == ' '; dbp++) continue;
(void) sprintf (buf, ofmt, host, h1p, rbp, dbp, raddeg(fov), mag, PATCHLEVEL);
/* let user abort */
stopd_up();
/* send the GET method to host and connection to read response */
sockfd = httpGET (host, buf, msg);
if (sockfd < 0) {
stopd_down();
return (-1);
}
/* now read lines of stars from the socket and collect good lines in
* opp array
*/
while ((n = recvlineb (sockfd, buf, sizeof(buf))) > 0) {
Obj o, *op;
if (db_crack_line (buf, &o, NULL, 0, NULL) < 0 || o.o_type != FIXED)
continue;
if (moreObjF (opp, nop, 1) < 0) {
(void) strcpy (msg, "No memory");
(void) close (sockfd);
stopd_down();
return (-1);
}
op = (Obj *)(&(*opp)[nop++]);
memcpy ((void *)op, (void *)&o, sizeof(ObjF));
}
(void) close (sockfd);
stopd_down();
if (n < 0) {
(void) strcpy (msg, syserrstr());
return (-1);
}
return (nop);
}
/* fetch GSC stars around the given field of view from ESO.
* if find some add them to the list at *opp and return new total, else
* return -1 with a diagnostic message in msg[].
*/
int
gscesofetch (
Now *np, /* current circumstances */
double ra, double dec, /* RA/Dec of center of view, rads, J2000 */
double fov, /* diamater of field of view, rads */
double mag, /* limiting magnitude desired */
ObjF **opp, /* *opp is malloced with stars found */
int nop, /* number already at *opp */
char msg[]) /* return diagnostic message here, if returning -1 */
{
static char eso_host[] = "archive.eso.org";
static char ifmt[] = "%s %lf %lf %lf %lf %lf %lf %*s %lf %*s %*s %d";
static char ofmt[] = "GET http://%s/skycat/servers/gsc-server?%.6f%c%.6f&r=0,%.1f&m=0,%g&s=R&f=1&* HTTP/1.0\r\nUser-Agent: xephem/%s\r\n\r\n";
static char eofcode[] = "[EOD]";
char buf[1024];
int sockfd;
int n;
/* format the GET */
(void) sprintf (buf, ofmt, eso_host, radhr(ra), dec<0?'-':'+', fabs(raddeg(dec)),
raddeg(fov/2)*60, mag, PATCHLEVEL);
/* let user abort */
stopd_up();
/* send the GET method to host and connection to read response */
sockfd = httpGET (eso_host, buf, msg);
if (sockfd < 0) {
stopd_down();
return (-1);
}
/* now read lines of stars from the socket and collect in opp array */
while ((n = recvlineb (sockfd, buf, sizeof(buf))) > 0) {
double rh, rm, rs;
double dd, dm, ds;
char name[32];
double m;
Obj *op;
int c;
if (strncmp (buf, eofcode, sizeof(eofcode)-1) == 0)
break;
if (sscanf (buf,ifmt,name,&rh,&rm,&rs,&dd,&dm,&ds,&m,&c) != 9)
continue;
if (moreObjF (opp, nop, 1) < 0) {
(void) strcpy (msg, "No memory");
(void) close (sockfd);
stopd_down();
return (-1);
}
op = (Obj *)(&(*opp)[nop++]);
zero_mem ((void *)op, sizeof(ObjF));
(void) sprintf (op->o_name, "GSC %.4s-%.4s", name+1, name+6);
op->o_type = FIXED;
op->f_class = c == 0 ? 'S' : 'T';
op->f_RA = (float) hrrad (rs/3600.0 + rm/60.0 + rh);
dd = fabs(dd);
op->f_dec = (float) degrad (ds/3600.0 + dm/60.0 + dd);
if (buf[23] == '-')
op->f_dec *= -1.0;
op->f_epoch = (float)J2000;
set_fmag (op, m);
}
(void) close (sockfd);
stopd_down();
if (n < 0) {
(void) strcpy (msg, syserrstr());
return (-1);
}
return (nop);
}
/* fetch GSC 2.2 stars around the given field of view from STScI.
* if find some add them to the list at *opp and return new total, else
* limit FOV to 30 arc mins -- these fields can be very dense.
* return -1 with a diagnostic message in msg[].
*/
int
gsc22fetch (
Now *np, /* current circumstances */
double ra, double dec, /* RA/Dec of center of view, rads, J2000 */
double fov, /* diamater of field of view, rads */
double mag, /* limiting magnitude desired */
ObjF **opp, /* *opp is malloced with stars found */
int nop, /* number already at *opp */
char msg[]) /* return diagnostic message here, if returning -1 */
{
#define GSC22MAXFOV degrad(0.5) /* max fov */
/* http://www-gsss.stsci.edu/cgi-bin/gsc22query.exe?ra=1%3A2%3A3&dec=4%3A5%3A6&r1=0&r2=5&m1=0.0&m2=19.5&n=20000&submit2=Submit+Request */
static char host[] = "www-gsss.stsci.edu";
static char ifmt[] = "%s %lf %lf %*lf %*lf %*lf %lf %lf %*lf %*lf %lf %*lf %lf %*lf %lf %*lf %lf %*lf %*lf %*lf %*lf %d";
static char ofmt[] = "GET http://%s/cgi-bin/gsc22query.exe?ra=%d%%3A%d%%3A%d&dec=%c%d%%3A%d%%3A%d&r1=0&r2=%g&m1=0.0&m2=%g&n=100000&submit2=Submit+Request HTTP/1.0\r\nUser-Agent: xephem/%s\r\n\r\n";
static char eofcode[] = "[EOD]";
char buf[1024];
char dsign;
int rh, rm, rs, dd, dm, ds;
double fmag, jmag, vmag, nmag, pmRA, pmdec;
int class;
int sockfd;
int n;
/* clamp fov */
if (fov > GSC22MAXFOV) {
sprintf (msg, "GSC 22 FOV is limited to %.2f degree",
raddeg(GSC22MAXFOV));
return (-1);
}
/* format the GET */
fs_sexa (buf, radhr(ra), 3, 3600);
sscanf (buf, "%d:%d:%d", &rh, &rm, &rs);
fs_sexa (buf, raddeg(fabs(dec)), 4, 3600);
sscanf (buf, "%d:%d:%d", &dd, &dm, &ds);
dsign = dec < 0 ? '-' : '+';
(void) sprintf (buf, ofmt, host, rh, rm, rs, dsign, dd, dm, ds,
raddeg(fov/2)*60, mag, PATCHLEVEL);
/* let user abort */
stopd_up();
/* send the GET method to host and connection to read response */
sockfd = httpGET (host, buf, msg);
if (sockfd < 0) {
stopd_down();
return (-1);
}
/* now read lines of stars from the socket and collect in opp array */
while ((n = recvlineb (sockfd, buf, sizeof(buf))) > 0) {
char name[32];
Obj *op;
if (strncmp (buf, eofcode, sizeof(eofcode)-1) == 0)
break;
if (sscanf (buf, ifmt, name, &radeg, &decdeg, &pmRA, &pmdec,
&fmag, &jmag, &vmag, &nmag, &class) != 10)
continue;
if (moreObjF (opp, nop, 1) < 0) {
(void) strcpy (msg, "No memory");
(void) close (sockfd);
stopd_down();
return (-1);
}
op = (Obj *)(&(*opp)[nop++]);
zero_mem ((void *)op, sizeof(ObjF));
(void) sprintf (op->o_name, "GSC2 %.*s", MAXNM-6, name);
op->o_type = FIXED;
switch (class) {
case 0: op->f_class = 'S'; break;
case 1: op->f_class = 'G'; break;
default: op->f_class = 'T'; break;
}
op->f_RA = degrad (radeg);
op->f_pmRA = (float) 1.327e-11*pmRA; /* mas/yr -> rad/dy */
op->f_dec = degrad (decdeg);
op->f_pmdec = (float) 1.327e-11*pmdec; /* mas/yr -> rad/dy */
if (fabs(op->f_dec) < PI/2)
op->f_pmRA /= cos (op->f_dec);
op->f_epoch = (float)J2000;
if (vmag < 30)
set_fmag (op, vmag);
else if (fmag < 30)
set_fmag (op, fmag);
else if (jmag < 30)
set_fmag (op, jmag);
else if (nmag < 30)
set_fmag (op, nmag);
else
set_fmag (op, 0.0);
}
(void) close (sockfd);
stopd_down();
if (n < 0) {
(void) strcpy (msg, syserrstr());
return (-1);
}
return (nop);
}
#endif
/* grow *opp, which already contains nop, to hold nnew more.
* if ok update *opp and return 0, else -1.
*/
static int
moreObjF (opp, nop, nnew)
ObjF **opp;
int nop;
int nnew;
{
char *newmem;
/* extend *opp for nnew more ObjF's */
if (*opp)
newmem = realloc ((void *)*opp, (nop+nnew)*sizeof(ObjF));
else
newmem = malloc (nnew * sizeof(ObjF));
if (!newmem)
return (-1);
*opp = (ObjF *)newmem;
return (0);
}