diff options
Diffstat (limited to 'vendor/voclient/voapps/lib/voFITS.c')
-rw-r--r-- | vendor/voclient/voapps/lib/voFITS.c | 467 |
1 files changed, 467 insertions, 0 deletions
diff --git a/vendor/voclient/voapps/lib/voFITS.c b/vendor/voclient/voapps/lib/voFITS.c new file mode 100644 index 00000000..b6d9c48e --- /dev/null +++ b/vendor/voclient/voapps/lib/voFITS.c @@ -0,0 +1,467 @@ +#include <string.h> +#include <stdio.h> +#include <math.h> +#include <unistd.h> +#include "voApps.h" +#include "fitsio.h" + + +#define MAX_IMAGES 20480 /* max images to process */ + +#define dabs(x) ((x<0.0?-x:x)) + + +/** + * Private methods. + */ +static void vot_printFrameInfo (FILE *fd, frameInfo *im); +static int vot_getFrameWcs (fitsfile *fptr, frameInfo *info); + +extern int vot_fileType (char *name); + + + + +/** + * VOT_IMAGEINFO -- Get information about a FITS file structure and WCS. + * + * @fn info = vot_imageInfo (char *name, int do_all) + * + * @brief Get information about a FITS file structure and WCS. + * @param name name of FITS file to open + * @param do_all do all extensions in an MEF file? + * @return pointer to ImInfo structure + */ +ImInfo * +vot_imageInfo (char *name, int do_all) +{ + fitsfile *fptr; + ImInfo *info = (ImInfo *) NULL; + long naxes[3] = {0, 0, 0}, nrows=0; + int nextns=0, naxis=0, bitpix=0, extnum=0; + int hdupos=0, hdutype=0, ncols=0, i=0, status=0; + double cxsum=0.0, cysum=0.0, rxsum=0.0, rysum=0.0; + + + /* Check for file existence. + */ + if (access (name, F_OK) != 0) { + fprintf (stderr, "Error: cannot open image '%s'\n", name); + return ((ImInfo *) NULL); + } + if (vot_fileType (name) != VOT_FITS) { + fprintf (stderr, "Error: file '%s' is not a FITS image\n", name); + return ((ImInfo *) NULL); + } + + info = (ImInfo *) calloc (1, sizeof (ImInfo)); + if (fits_open_file (&fptr, name, READONLY, &status) == 0) { + fits_get_num_hdus (fptr, &nextns, &status); + fits_get_hdu_num (fptr, &hdupos); /* get the current HDU position */ + + strncpy (info->imname, name, strlen(name)); + info->nextend = (nextns - 1); + info->extns = (frameInfo *) calloc (nextns, sizeof (frameInfo)); + + for (; !status; hdupos++) { /* Main loop for each HDU */ + fits_get_hdu_type (fptr, &hdutype, &status); /* Get the HDU type */ + + if (hdutype == IMAGE_HDU) { /* primary array or image HDU */ + fits_get_img_param (fptr, 10, &bitpix, &naxis, naxes, &status); + + if (hdupos == 0) { /* PHU */ + info->frame.is_image = 1; + info->frame.is_table = 0; + info->frame.naxis = naxis; + info->frame.bitpix = bitpix; + for (i=0; i < naxis; i++) + info->frame.naxes[i] = naxes[i]; + + } else { /* EHU */ + extnum = hdupos - 1; + info->extns[extnum].is_image = 1; + info->extns[extnum].is_table = 0; + info->extns[extnum].extnum = extnum; + info->extns[extnum].naxis = naxis; + info->extns[extnum].bitpix = bitpix; + for (i=0; i < naxis; i++) + info->extns[extnum].naxes[i] = naxes[i]; + + if (vot_getFrameWcs (fptr, &info->extns[extnum]) == 0) + info->extns[extnum].has_wcs = 1; + } + + } else { /* a table HDU */ + if (hdupos > 0) { /* EHU */ + fits_get_num_rows (fptr, &nrows, &status); + fits_get_num_cols (fptr, &ncols, &status); + + extnum = hdupos - 1; + info->extns[extnum].is_image = 0; + info->extns[extnum].is_table = 1; + info->extns[extnum].naxis = 2; + info->extns[extnum].bitpix = 0; + info->extns[extnum].naxes[0] = ncols; + info->extns[extnum].naxes[1] = nrows; + } + +#ifdef GET_TBLINFO + printf ("%s Table: %d columns x %ld rows\n", + ((hdutype==ASCII_TBL) ? "ASCII" : "Binary"); ncols, nrows); + printf(" COL NAME FORMAT\n"); + for (i = 1; i <= ncols; i++) { + fits_make_keyn ("TTYPE", i, keyname,&status); + fits_read_key (fptr, TSTRING, keyname,colname,NULL,&status); + fits_make_keyn ("TFORM", i, keyname,&status); + fits_read_key (fptr, TSTRING, keyname,coltype,NULL,&status); + printf(" %3d %-16s %-16s\n", i, colname, coltype); + } +#endif + } + + /* Move to next extension. + */ + fits_movrel_hdu (fptr, 1, NULL, &status); + } + + if (status == END_OF_FILE) + status = 0; /* reset normal error */ + + } else if (status) /* print any error message */ + fits_report_error (stderr, status); + + + /* Compute the values for the entire frame. + */ + info->frame.lx = info->frame.ly = 360.0; + info->frame.ux = info->frame.uy = -360.0; + + info->frame.cx = info->extns[0].cx; + info->frame.cy = info->extns[0].cy; + info->frame.lx = info->extns[0].lx; + info->frame.ly = info->extns[0].ly; + info->frame.ux = info->extns[0].ux; + info->frame.uy = info->extns[0].uy; + info->frame.rotang = info->extns[0].rotang; + info->frame.xrval = info->extns[0].xrval; + info->frame.yrval = info->extns[0].yrval; + info->frame.xrpix = info->extns[0].xrpix; + info->frame.yrpix = info->extns[0].yrpix; + info->frame.radius = info->extns[0].radius; + + if (nextns == 1) { + for (i=0; i < naxis; i++) + info->frame.naxes[i] = info->extns[0].naxes[i]; + } + memcpy (&info->frame.xc[0], &info->extns[0].xc[0], (sizeof(double)*4)); + memcpy (&info->frame.yc[0], &info->extns[0].yc[0], (sizeof(double)*4)); + + for (i=1; i < nextns; i++) { + if (info->extns[i].lx < info->frame.lx) + info->frame.lx = info->extns[i].lx; + if (info->extns[i].ly < info->frame.ly) + info->frame.ly = info->extns[i].ly; + + if (info->extns[i].ux > info->frame.ux) + info->frame.ux = info->extns[i].ux; + if (info->extns[i].uy > info->frame.uy) + info->frame.uy = info->extns[i].uy; + cxsum += info->extns[i].cx; + cysum += info->extns[i].cy; + + rxsum += info->extns[i].naxes[0]; + rysum += info->extns[i].naxes[1]; + + info->frame.scale = info->extns[i].scale; + info->frame.rotang = info->extns[i].rotang; + strcpy (info->frame.ctype, info->extns[i].ctype); + } + + if (nextns > 1) { + info->frame.xrval = info->frame.cx = (cxsum / (double) nextns); + info->frame.yrval = info->frame.cy = (cysum / (double) nextns); + info->frame.xrpix = info->frame.radius / + (info->frame.scale / 3600.) / 2.0; + info->frame.yrpix = info->frame.radius / + (info->frame.scale / 3600.) / 2.0; + } else { + info->frame.xrval = info->frame.cx = info->extns[0].cx; + info->frame.yrval = info->frame.cy = info->extns[0].cy; + info->frame.xrpix = info->extns[0].xrpix; + info->frame.yrpix = info->extns[0].yrpix; + strcpy (info->frame.ctype, info->extns[0].ctype); + } + + info->frame.width = ((info->frame.ux+360.) - (info->frame.lx+360.)); + info->frame.height = ((info->frame.uy+ 90.) - (info->frame.ly+ 90.)); + info->frame.radius = sqrt ( + (info->frame.cx - info->frame.lx) * + (info->frame.cx - info->frame.lx) + + (info->frame.cy - info->frame.ly) * + (info->frame.cy - info->frame.ly) ); + info->frame.xc[0] = info->frame.lx; info->frame.yc[0] = info->frame.ly; + info->frame.xc[1] = info->frame.lx; info->frame.yc[1] = info->frame.uy; + info->frame.xc[2] = info->frame.ux; info->frame.yc[2] = info->frame.uy; + info->frame.xc[3] = info->frame.ux; info->frame.yc[3] = info->frame.ly; + + + fits_close_file (fptr, &status); + return ( (ImInfo *) info); +} + + +/** + * VOT_IMAGENEXTNS -- Get the number of extensions in an MEF file. + * + * @fn nextn = vot_imageNExtns (char *name) + * + * @brief Get the number of extensions in an MEF file. + * @param name name of FITS file to open + * @return number of extensions in an MEF file + */ +int +vot_imageNExtns (char *image) +{ + fitsfile *fptr; + int nextns = -1, status = 0; + + + if (fits_open_file (&fptr, image, READONLY, &status) == 0) { + fits_get_num_hdus (fptr, &nextns, &status); + fits_close_file (fptr, &status); + } + + return (nextns); +} + + +/** + * VOT_PRINTIMAGEINFO -- Print the image information. + * + * @fn vot_printImageInfo (FILE *fd, ImInfo *im) + * + * @brief Print the image information. + * @param fd output file descriptor (or stdout/stderr) + * @param im image information structure + * @return nothing + */ +void +vot_printImageInfo (FILE *fd, ImInfo *im) +{ + register int i; + + fprintf (fd, "Name: %s nextns = %d\n", im->imname, im->nextend); + + fprintf (fd, "Frame:\n"); im->frame.extnum = -1; + vot_printFrameInfo (fd, &im->frame); + + for (i=1; i < im->nextend; i++) + vot_printFrameInfo (fd, &im->extns[i]); +} + + +/** + * VOC_FREEIMAGEINFO -- Free the image information structure. + * + * @fn vot_freeImageInfo (ImInfo *im) + * + * @brief Free the image information structure. + * @param im image information structure + * @return nothing + */ +void +vot_freeImageInfo (ImInfo *im) +{ + free ((void *) im->extns); /* extension structs */ + free ((void *) im); /* main image structs */ +} + + + +/**************************************************************************** + *** Private procedures + ****************************************************************************/ + +/** + * VOT_PRINTFRAMEINFO -- Print information about a specific frame. + */ +static void +vot_printFrameInfo (FILE *fd, frameInfo *im) +{ + if (im->extnum >= 0) { + fprintf (fd, "\nExt: %d dims[%d] = %d %d %d\t", + im->extnum, im->naxis, im->naxes[0], im->naxes[1], im->naxes[2]); + fprintf (fd, " image: %d table: %d has_wcs: %d flip: %d\n", + im->is_image, im->is_table, im->has_wcs, im->axflip); + } + + fprintf (fd, + " center: %8.4f %8.4f ll: %8.4f %8.4f ur: %8.4f %8.4f\n", + im->cx, im->cy, im->lx, im->ly, im->ux, im->uy); + fprintf (fd, " corners: %8.4f %8.4f %8.4f %8.4f\n", + im->xc[1], im->yc[1], im->xc[2], im->yc[2]); + fprintf (fd, "\t %8.4f %8.4f %8.4f %8.4f\n", + im->xc[0], im->yc[0], im->xc[3], im->yc[3]); + fprintf (fd, + " crval: %8.4f %8.4f crpix: %8.4f %8.4f ctype: '%s'\n", + im->xrval, im->yrval, im->xrpix, im->yrpix, im->ctype); + fprintf (fd, + " w/h: %8.4f %8.4f radius: %8.4f rot: %8.4f scale: %8.4f\n", + dabs(im->width), dabs(im->height), im->radius, im->rotang, im->scale); +} + + +/** + * VOT_GETFRAMEWCS -- Get the WCS information for a given frame. + */ +static int +vot_getFrameWcs (fitsfile *fptr, frameInfo *info) +{ + double xrval=0.0, yrval=0.0, xrpix=0.0, yrpix=0.0, xpix=0.0, ypix=0.0; + double xinc=0.0, yinc=0.0, rot=0.0, scale=0.0, xrot=0.0, yrot=0.0; + double cx=0.0, cy=0.0, lx=0.0, ly=0.0, ux=0.0, uy=0.0; + double cd11=0.0, cd12=0.0, cd21=0.0, cd22=0.0, cdelt1=0.0, cdelt2=0.0; + int i, axflip=0, status = 0; + char str[32], ctype[5], comment[80]; + + + /* Get the header WCS keywords. + */ + fits_read_img_coord (fptr, &xrval, &yrval, &xrpix, + &yrpix, &xinc, &yinc, &rot, ctype, &status); + + info->xrval = xrval; + info->yrval = yrval; + info->xrpix = xrpix; + info->yrpix = yrpix; + info->has_wcs = 1; + info->is_image = 1; + strcpy (info->ctype, ctype); + + xpix = (double) 0.5; /* Lower-left */ + ypix = (double) 0.5; + status = 0; + fits_pix_to_world (xpix, ypix, xrval, yrval, xrpix, yrpix, xinc, yinc, + rot, ctype, &info->xc[0], &info->yc[0], &status); + + xpix = (double) 0.5; /* Upper-left */ + ypix = (double) info->naxes[1] - 0.5; + status = 0; + fits_pix_to_world (xpix, ypix, xrval, yrval, xrpix, yrpix, xinc, yinc, + rot, ctype, &info->xc[1], &info->yc[1], &status); + + xpix = (double) info->naxes[0] - 0.5; /* Upper-right */ + ypix = (double) info->naxes[1] - 0.5; + status = 0; + fits_pix_to_world (xpix, ypix, xrval, yrval, xrpix, yrpix, xinc, yinc, + rot, ctype, &info->xc[2], &info->yc[2], &status); + + xpix = (double) info->naxes[0] - 0.5; /* Lower-right */ + ypix = (double) 0.5; + status = 0; + fits_pix_to_world (xpix, ypix, xrval, yrval, xrpix, yrpix, xinc, yinc, + rot, ctype, &info->xc[3], &info->yc[3], &status); + + xpix = (double) info->naxes[0] / 2. - 0.5; /* Center */ + ypix = (double) info->naxes[1] / 2. - 0.5; + status = 0; + fits_pix_to_world (xpix, ypix, xrval, yrval, xrpix, yrpix, xinc, yinc, + rot, ctype, &info->cx, &info->cy, &status); + info->cx = xrval; + info->cy = yrval; + + /* Get center and cone radius. + */ + lx = info->lx = info->xc[0]; /* Lower-left */ + ly = info->ly = info->yc[0]; + ux = info->ux = info->xc[2]; /* Upper-right */ + uy = info->uy = info->yc[2]; + cx = info->cx; + cy = info->cy; + status = 0; + if ((i = fits_read_key_dbl(fptr, "CD1_1", &cd11, comment, &status))==0) { + fits_read_key_dbl (fptr, "CD1_2", &cd12, comment, &status); + fits_read_key_dbl (fptr, "CD2_1", &cd21, comment, &status); + fits_read_key_dbl (fptr, "CD2_2", &cd22, comment, &status); + + scale = 3600.0 * sqrt ((cd11*cd11+cd21*cd21+cd12*cd12+cd22*cd22) / 2.); + xrot = dabs (atan2 ( cd21, cd11)); + yrot = dabs (atan2 (-cd12, cd22)); + rot = (xrot + yrot) / 2.0; + } else { + /* Old-style keywords. + */ + status = 0; + if (!fits_read_key_dbl (fptr, "CDELT1", &cdelt1, comment, &status)) { + fits_read_key_dbl (fptr, "CDELT2", &cdelt2, comment, &status); + + scale = 3600.0 * sqrt ((cdelt1*cdelt1 + cdelt2*cdelt2) / 2.); + + if (!fits_read_key_dbl (fptr, "CROTA1", &xrot, comment, &status)) { + fits_read_key_dbl (fptr, "CROTA2", &yrot, comment, &status); + rot = (xrot + yrot) / 2.0; + } + } else + info->has_wcs = 0; + } + + status = 0; + memset (str, 0, 32); + if ((i = fits_read_key_str(fptr, "CTYPE1", str, comment, &status))==0) { + if (strncasecmp (str,"DEC",3) == 0 || strncasecmp (str,"LAT",3) == 0) + axflip = 1; + } + + /* For a bad/approximate WCS, compute in rough coords. + */ + if ( (lx == cx) && (ly == cy) ) { + double s = (scale / 3600.0); + + lx = info->lx = cx - (info->naxes[0]/2 * s); /* Lower-left */ + ly = info->ly = cy - (info->naxes[1]/2 * s); + ux = info->ux = cx + (info->naxes[0]/2 * s); /* Upper-right */ + uy = info->uy = cy + (info->naxes[1]/2 * s); + + info->xc[0] = cx - (info->naxes[0]/2 * s); /* Lower-left */ + info->yc[0] = cy - (info->naxes[1]/2 * s); + + info->xc[1] = cx - (info->naxes[0]/2 * s); /* Upper-left */ + info->yc[1] = cy + (info->naxes[1]/2 * s); + + info->xc[2] = cx + (info->naxes[0]/2 * s); /* Upper-right */ + info->yc[2] = cy + (info->naxes[1]/2 * s); + + info->xc[3] = cx + (info->naxes[0]/2 * s); /* Lower-right */ + info->yc[3] = cy - (info->naxes[1]/2 * s); + } + + /* FIXME -- Doens't handle rotation properly. */ + info->width = dabs((ux - lx)); /* in degrees */ + info->height = dabs((uy - ly)); + info->radius = sqrt ((cx - lx) * (cx - lx) + (cy - ly) * (cy - ly)); + info->rotang = rot; + info->scale = scale; + info->axflip = axflip; + + return (info->has_wcs); +} + + +/***************************************************************************** + * Program main. + ****************************************************************************/ +#ifdef UNIT_TEST +int +main (int argc, char *argv[]) +{ + ImInfo *img = (ImInfo *) NULL; + + + if ( (img = vot_imageInfo (argv[1], 1)) ) { + vot_printImageInfo (stdout, img); + vot_freeImageInfo (img); + } + + return (0); +} +#endif |