Example #1
0
int checkHdr(char *infile, int hdrflag, int hdu)
{
   int       i, len, ncard, morekeys;

   int       status = 0;

   char     *keyword;
   char     *value;

   char      fitskeyword[80];
   char      fitsvalue  [80];
   char      fitscomment[80];
   char      tmpstr     [80];

   char     *end;

   char      line  [1024];
   char      pline [1024];

   char     *ptr1;
   char     *ptr2;

   FILE     *fp;
   fitsfile *infptr;

   static int maxhdr;

   if(!mHeader)
   {
      mHeader = malloc(MAXHDR);
      maxhdr = MAXHDR;
   }

   havePLTRAH  = 0;

   haveSIMPLE  = 0;
   haveBITPIX  = 0;
   haveNAXIS   = 0;
   haveNAXIS1  = 0;
   haveNAXIS2  = 0;
   haveCTYPE1  = 0;
   haveCTYPE2  = 0;
   haveCRPIX1  = 0;
   haveCRPIX2  = 0;
   haveCDELT1  = 0;
   haveCDELT2  = 0;
   haveCD1_1   = 0;
   haveCD1_2   = 0;
   haveCD2_1   = 0;
   haveCD2_2   = 0;
   haveCRVAL1  = 0;
   haveCRVAL2  = 0;
   haveBSCALE  = 0;
   haveBZERO   = 0;
   haveBLANK   = 0;
   haveEPOCH   = 0;
   haveEQUINOX = 0;


   /****************************************/
   /* Initialize the WCS transform library */
   /* and find the pixel location of the   */
   /* sky coordinate specified             */
   /****************************************/

   errorCount = 0;

   if(hdrCheck_outfile)
   {
      fout = fopen(hdrCheck_outfile, "w+");

      if(fout == (FILE *)NULL)
      {
         fprintf(fstatus, "[struct stat=\"ERROR\", msg=\"Cannot open output file %s.\"]\n", hdrCheck_outfile);
         fflush(fstatus);
         exit(1);
      }
   }

   strcpy(mHeader, "");

   if(fits_open_file(&infptr, infile, READONLY, &status) == 0)
   {
      if(CHdebug)
      {
         printf("\nFITS file\n");
         fflush(stdout);
      }

      if(hdrflag == HDR)
      {
       fprintf(fstatus, "[struct stat=\"ERROR\", msg=\"FITS file (%s) cannot be used as a header template\"]\n",
                infile);
         fflush(fstatus);
         exit(1);
      }

      if(hdu > 0)
      {
         if(fits_movabs_hdu(infptr, hdu+1, NULL, &status))
            FITSerror(status);
      }

      if(fits_get_hdrspace (infptr, &ncard, &morekeys, &status))
         FITSerror(status);
      
      if(ncard > 1000)
         mHeader = realloc(mHeader, ncard * 80 + 1024);

      if(CHdebug)
      {
         printf("ncard = %d\n", ncard);
         fflush(stdout);
      }

      for (i=1; i<=ncard; i++)
      {
         if(fits_read_keyn (infptr, i, fitskeyword, fitsvalue, fitscomment, &status))
            FITSerror(status);

         if(fitsvalue[0] == '\'')
         {
            strcpy(tmpstr, fitsvalue+1);

            if(tmpstr[strlen(tmpstr)-1] == '\'')
               tmpstr[strlen(tmpstr)-1] =  '\0';
         }
         else
            strcpy(tmpstr, fitsvalue);

         fitsCheck(fitskeyword, tmpstr);

         sprintf(line, "%-8s= %20s", fitskeyword, fitsvalue);

         if(strncmp(line, "COMMENT", 7) != 0)
            strAdd(mHeader, line);
      }

      strAdd(mHeader, "END");

      if(fits_close_file(infptr, &status))
         FITSerror(status);
   }
   else
   {
      if(CHdebug)
      {
         printf("\nTemplate file\n");
         fflush(stdout);
      }

      if(hdrflag == FITS)
      {
         fp = fopen(infile, "r");

         if(fp == (FILE *)NULL)
         {
            fprintf(fstatus, "[struct stat=\"ERROR\", msg=\"File %s not found.\"]\n", infile);
            fflush(fstatus);
            exit(1);
         }

         fclose(fp);

         fprintf(fstatus, "[struct stat=\"ERROR\", msg=\"File (%s) is not a FITS image\"]\n",
                infile);
         fflush(fstatus);
         exit(1);
      }

      fp = fopen(infile, "r");

      if(fp == (FILE *)NULL)
      {
         fprintf(fstatus, "[struct stat=\"ERROR\", msg=\"File %s not found.\"]\n", infile);
         fflush(fstatus);
         exit(1);
      }

      while(1)
      {
         if(fgets(line, 1024, fp) == (char *)NULL)
            break;

         if(line[(int)strlen(line)-1] == '\n')
            line[(int)strlen(line)-1]  = '\0';
         
         if(line[(int)strlen(line)-1] == '\r')
            line[(int)strlen(line)-1]  = '\0';
         
         strcpy(pline, line);

         if((int)strlen(line) > 80)
         {
            fprintf(fstatus, "[struct stat=\"ERROR\", msg=\"FITS header lines cannot be greater than 80 characters.\"]\n");
            fflush(fstatus);
            exit(1);
         }

         len = (int)strlen(pline);

         keyword = pline;

         while(*keyword == ' ' && keyword < pline+len)
            ++keyword;

         end = keyword;

         while(*end != ' ' && *end != '=' && end < pline+len)
            ++end;

         value = end;

         while((*value == '=' || *value == ' ' || *value == '\'')
               && value < pline+len)
            ++value;

         *end = '\0';
         end = value;

         if(*end == '\'')
            ++end;

         while(*end != ' ' && *end != '\'' && end < pline+len)
            ++end;

         *end = '\0';

         fitsCheck(keyword, value);

         strAdd(mHeader, line);
         
         if((int)strlen(mHeader) + 160 > maxhdr)
         {
            maxhdr += MAXHDR;
            mHeader = realloc(mHeader, maxhdr);
         }
      }

      fclose(fp);
   }


   /********************************************************/
   /*                                                      */
   /* Check to see if we have the minimum FITS header info */
   /*                                                      */
   /********************************************************/

   if(!haveBITPIX)
      errorOutput("No BITPIX keyword in FITS header");

   if(!haveNAXIS)
      errorOutput("No NAXIS keyword in FITS header");

   if(!haveNAXIS1)
      errorOutput("No NAXIS1 keyword in FITS header");

   if(!haveNAXIS2)
      errorOutput("No NAXIS2 keyword in FITS header");

   if(havePLTRAH)
   {
      /* If we have this parameter, we'll assume this is a DSS header  */
      /* the WCS checking routine should be able to verify if it isn't */

      free(mHeader);

      maxhdr = 0;
      
      mHeader = (char *)NULL;

      return(0);
   }

   if(!haveCTYPE1)
      errorOutput("No CTYPE1 keyword in FITS header");

   if(!haveCTYPE2)
      errorOutput("No CTYPE2 keyword in FITS header");

   if(!haveCRPIX1)
      errorOutput("No CRPIX1 keyword in FITS header");

   if(!haveCRPIX2)
      errorOutput("No CRPIX2 keyword in FITS header");

   if(!haveCRVAL1)
      errorOutput("No CRVAL1 keyword in FITS header");

   if(!haveCRVAL2)
      errorOutput("No CRVAL2 keyword in FITS header");

   if(!haveCD1_1 
   && !haveCD1_2 
   && !haveCD2_1 
   && !haveCD2_2)
   {
      if(!haveCDELT1)
         errorOutput("No CDELT1 keyword (or incomplete CD matrix) in FITS header");
      else if(!haveCDELT2)
         errorOutput("No CDELT2 keyword (or incomplete CD matrix) in FITS header");
   }

   if(strlen(ctype1) < 8)
      errorOutput("CTYPE1 must be at least 8 characters");

   if(strlen(ctype2) < 8)
      errorOutput("CTYPE2 must be at least 8 characters");

   ptr1 = ctype1;

   while(*ptr1 != '-' && *ptr1 != '\0') ++ptr1;
   while(*ptr1 == '-' && *ptr1 != '\0') ++ptr1;

   ptr2 = ctype2;

   while(*ptr2 != '-' && *ptr2 != '\0') ++ptr2;
   while(*ptr2 == '-' && *ptr2 != '\0') ++ptr2;

   if(strlen(ptr1) == 0
   || strlen(ptr2) == 0)
      errorOutput("Invalid CTYPE1 or CTYPE2 projection information");

   if(strcmp(ptr1, ptr2) != 0)
      errorOutput("CTYPE1, CTYPE2 projection information mismatch");

   if(hdrStringent)
   {
      if(strlen(ptr1) != 3)
         errorOutput("Invalid CTYPE1 projection information");

      if(strlen(ptr2) != 3)
         errorOutput("Invalid CTYPE2 projection information");
   }


   /****************************************/
   /* Initialize the WCS transform library */
   /* and find the pixel location of the   */
   /* sky coordinate specified             */
   /****************************************/

   /*
   if(CHdebug)
   {
      printf("header = \n%s\n", mHeader);
      fflush(stdout);
   }
   */

   hdrCheck_wcs = wcsinit(mHeader);

   checkWCS(hdrCheck_wcs, 0);

   if(errorCount > 0)
   {
      fprintf(fstatus, "[struct stat=\"ERROR\", msg=\"%d Errors\"]\n", 
         errorCount);
      fflush(fstatus);
      exit(1);
   }

   return(0);
}
Example #2
0
bool FITSImage::loadFITS ( const QString &inFilename, QProgressDialog *progress )
{
    int status=0, nulval=0, anynull=0;
    long fpixel[2], nelements, naxes[2];
    char error_status[512];

    qDeleteAll(starCenters);
    starCenters.clear();

    if (mode == FITS_NORMAL && progress)
    {
        progress->setLabelText(i18n("Please hold while loading FITS file..."));
        progress->setWindowTitle(i18n("Loading FITS"));
    }

    if (mode == FITS_NORMAL && progress)
        progress->setValue(30);

    if (fptr)
    {

        fits_close_file(fptr, &status);

        if (tempFile)
            QFile::remove(filename);
    }

    filename = inFilename;

    if (filename.contains("/tmp/"))
        tempFile = true;
    else
        tempFile = false;

    filename.remove("file://");


    if (fits_open_image(&fptr, filename.toAscii(), READONLY, &status))
    {
        fits_report_error(stderr, status);
        fits_get_errstatus(status, error_status);
        if (progress)
            KMessageBox::error(0, i18n("Could not open file %1 (fits_get_img_param). Error %2", filename, QString::fromUtf8(error_status)), i18n("FITS Open"));
        return false;
    }


    if (mode == FITS_NORMAL && progress)
        if (progress->wasCanceled())
            return false;

    if (mode == FITS_NORMAL && progress)
        progress->setValue(40);


    if (fits_get_img_param(fptr, 2, &(stats.bitpix), &(stats.ndim), naxes, &status))
    {
        fits_report_error(stderr, status);
        fits_get_errstatus(status, error_status);

        if (progress)
            KMessageBox::error(0, i18n("FITS file open error (fits_get_img_param): %1", QString::fromUtf8(error_status)), i18n("FITS Open"));
        return false;
    }

    if (stats.ndim < 2)
    {
        if (progress)
            KMessageBox::error(0, i18n("1D FITS images are not supported in KStars."), i18n("FITS Open"));
        return false;
    }


    if (fits_get_img_type(fptr, &data_type, &status))
    {
        fits_report_error(stderr, status);
        fits_get_errstatus(status, error_status);

        if (progress)
            KMessageBox::error(0, i18n("FITS file open error (fits_get_img_type): %1", QString::fromUtf8(error_status)), i18n("FITS Open"));
        return false;
    }

    if (mode == FITS_NORMAL && progress)
        if (progress->wasCanceled())
            return false;

    if (mode == FITS_NORMAL && progress)
        progress->setValue(60);

    stats.dim[0] = naxes[0];
    stats.dim[1] = naxes[1];

    delete (image_buffer);
    image_buffer = NULL;

    image_buffer = new float[stats.dim[0] * stats.dim[1]];

    if (image_buffer == NULL)
    {
        qDebug() << "Not enough memory for image_buffer";
        return false;
    }
    if (mode == FITS_NORMAL && progress)
    {
        if (progress->wasCanceled())
        {
        delete (image_buffer);
        return false;
        }
    }

    if (mode == FITS_NORMAL && progress)
        progress->setValue(70);

    nelements = stats.dim[0] * stats.dim[1];
    fpixel[0] = 1;
    fpixel[1] = 1;

    qApp->processEvents();

    if (fits_read_2d_flt(fptr, 0, nulval, naxes[0], naxes[0], naxes[1], image_buffer, &anynull, &status))
    {
        fprintf(stderr, "fits_read_pix error\n");
        fits_report_error(stderr, status);
        return false;
    }

    if (mode == FITS_NORMAL && progress)
    {
        if (progress->wasCanceled())
        {
            delete (image_buffer);
            return false;
        }
    }

    calculateStats();

    if (mode == FITS_NORMAL && progress)
        progress->setValue(80);

    //currentWidth  = stats.dim[0];
   // currentHeight = stats.dim[1];

    qApp->processEvents();

    if (mode == FITS_NORMAL)
    {
        checkWCS();

        if (progress)
            progress->setValue(90);
    }

    if (mode == FITS_NORMAL && progress)
    {
        if (progress->wasCanceled())
        {
            delete (image_buffer);
            return false;
        }
    }

    if (mode == FITS_NORMAL && progress)
        progress->setValue(100);

    starsSearched = false;

    return true;

}
Example #3
0
int get_hhdr (char *fname, struct Hdr_rec *hdr_rec, char *msg)
{
   char      header[80000];
   char      str[132];
   FILE     *fptr;
   int       i, status, csys, nfailed, first_failed, clockwise;
   double    lon, lat, equinox;
   double    ra2000, dec2000;
   double    ra, dec;
   double    x1, y1, z1;
   double    x2, y2, z2;

   double    dtr = 1.745329252e-2;

   struct WorldCoor *wcs;

   struct stat buf;

   nfailed      = 0;
   first_failed = 0;
   status       = 0;

   fptr = fopen(fname, "r");
 
   if(fptr == (FILE *)NULL)
   {
      sprintf (msg, "Cannot open header file %s", fname);

      if(showbad)
      {
	 printf("[struct stat=\"INFO\", msg=\"Cannot open file\", file=\"%s\"]\n",
	    fname);
	 
	 fflush(stdout);
      }
      return (1);
   }

   stat(fname, &buf);

   hdr_rec->size = buf.st_size;

   hdr_rec->hdu = 1;

   strcpy(header, "");

   while(1)
   {
      if(fgets(str, 80, fptr) == (char *)NULL)
         break;
      
      while(str[strlen(str)-1] == '\n'
         || str[strlen(str)-1] == '\r')
            str[strlen(str)-1] =  '\0';

      for(i=strlen(str); i<80; ++i)
	 str[i] = ' ';

      str[80] = '\0';

      strcat(header, str);
   }

   wcs = wcsinit(header);

   if(wcs == (struct WorldCoor *)NULL) 
   {
      if(hdr_rec->hdu == 1)
	 first_failed = 1;

      ++nfailed;

      if(showbad)
      {
	 printf("[struct stat=\"INFO\", msg=\"WCS lib init failure\", file=\"%s\", hdu=%d]\n",
	    fname, hdr_rec->hdu);
	 
	 fflush(stdout);
      }

      ++hdr_rec->hdu;
      
      return(1);
   } 

   if(checkWCS(wcs, 1) == 1)
   {
      if(debug)
      {
	 printf("Bad WCS for file %s\n", fname);
	 fflush(stdout);
      }

      wcs = (struct WorldCoor *)NULL;

      if(hdr_rec->hdu == 1)
	 first_failed = 1;

      ++nfailed;

      if(showbad)
      {
	 printf("[struct stat=\"INFO\", msg=\"Bad WCS\", file=\"%s\", hdu=%d]\n",
	    fname, hdr_rec->hdu);
	 
	 fflush(stdout);
      }

      ++hdr_rec->hdu;

      return(1);
   }

   hdr_rec->ns = (int) wcs->nxpix;
   hdr_rec->nl = (int) wcs->nypix;

   strcpy(hdr_rec->ctype1, wcs->ctype[0]);
   strcpy(hdr_rec->ctype2, wcs->ctype[1]);

   hdr_rec->crpix1  = wcs->xrefpix;
   hdr_rec->crpix2  = wcs->yrefpix;
   hdr_rec->equinox = wcs->equinox;
   hdr_rec->crval1  = wcs->xref;
   hdr_rec->crval2  = wcs->yref;
   hdr_rec->cdelt1  = wcs->xinc;
   hdr_rec->cdelt2  = wcs->yinc;
   hdr_rec->crota2  = wcs->rot;

   if(hdr_rec->cdelt1 > 0.
   && hdr_rec->cdelt2 > 0.
   && (hdr_rec->crota2 < -90. || hdr_rec->crota2 > 90.))
   {
      hdr_rec->cdelt1 = -hdr_rec->cdelt1;
      hdr_rec->cdelt2 = -hdr_rec->cdelt2;

      hdr_rec->crota2 += 180.;

      while(hdr_rec->crota2 >= 360.)
	 hdr_rec->crota2 -= 360.;

      while(hdr_rec->crota2 <= -360.)
	 hdr_rec->crota2 += 360.;
   }


   /* Convert center of image to sky coordinates */

   csys = EQUJ;

   if(strncmp(hdr_rec->ctype1, "RA",   2) == 0)
      csys = EQUJ;
   if(strncmp(hdr_rec->ctype1, "GLON", 4) == 0)
      csys = GAL;
   if(strncmp(hdr_rec->ctype1, "ELON", 4) == 0)
      csys = ECLJ;

   equinox = hdr_rec->equinox;

   pix2wcs (wcs, hdr_rec->ns/2., hdr_rec->nl/2., &lon, &lat);


   /* Convert lon, lat to EQU J2000 */

   convertCoordinates (csys, equinox, lon, lat,
		       EQUJ, 2000., &ra2000, &dec2000, 0.);

   hdr_rec->ra2000  = ra2000;
   hdr_rec->dec2000 = dec2000;

   clockwise = 0;

   if((hdr_rec->cdelt1 < 0 && hdr_rec->cdelt2 < 0)
   || (hdr_rec->cdelt1 > 0 && hdr_rec->cdelt2 > 0)) clockwise = 1;


   if(clockwise)
   {
      pix2wcs(wcs, -0.5, -0.5, &lon, &lat);
      convertCoordinates (csys, equinox, lon, lat,
			  EQUJ, 2000., &ra, &dec, 0.);

      hdr_rec->ra1 = ra;
      hdr_rec->dec1 = dec;


      pix2wcs(wcs, wcs->nxpix+0.5, -0.5, &lon, &lat);
      convertCoordinates (csys, equinox, lon, lat,
			  EQUJ, 2000., &ra, &dec, 0.);

      hdr_rec->ra2 = ra;
      hdr_rec->dec2 = dec;


      pix2wcs(wcs, wcs->nxpix+0.5, wcs->nypix+0.5, &lon, &lat);
      convertCoordinates (csys, equinox, lon, lat,
			  EQUJ, 2000., &ra, &dec, 0.);

      hdr_rec->ra3 = ra;
      hdr_rec->dec3 = dec;


      pix2wcs(wcs, -0.5, wcs->nypix+0.5, &lon, &lat);
      convertCoordinates (csys, equinox, lon, lat,
			  EQUJ, 2000., &ra, &dec, 0.);

      hdr_rec->ra4 = ra;
      hdr_rec->dec4 = dec;
   }
   else
   {
      pix2wcs(wcs, -0.5, -0.5, &lon, &lat);
      convertCoordinates (csys, equinox, lon, lat,
			  EQUJ, 2000., &ra, &dec, 0.);

      hdr_rec->ra1 = ra;
      hdr_rec->dec1 = dec;


      pix2wcs(wcs, wcs->nxpix+0.5, -0.5, &lon, &lat);
      convertCoordinates (csys, equinox, lon, lat,
			  EQUJ, 2000., &ra, &dec, 0.);

      hdr_rec->ra2 = ra;
      hdr_rec->dec2 = dec;


      pix2wcs(wcs, wcs->nxpix+0.5, wcs->nypix+0.5, &lon, &lat);
      convertCoordinates (csys, equinox, lon, lat,
			  EQUJ, 2000., &ra, &dec, 0.);

      hdr_rec->ra3 = ra;
      hdr_rec->dec3 = dec;


      pix2wcs(wcs, -0.5, wcs->nypix+0.5, &lon, &lat);
      convertCoordinates (csys, equinox, lon, lat,
			  EQUJ, 2000., &ra, &dec, 0.);

      hdr_rec->ra4 = ra;
      hdr_rec->dec4 = dec;
   }


   x1 = cos(hdr_rec->ra2000*dtr) * cos(hdr_rec->dec2000*dtr);
   y1 = sin(hdr_rec->ra2000*dtr) * cos(hdr_rec->dec2000*dtr);
   z1 = sin(hdr_rec->dec2000*dtr);

   x2 = cos(ra*dtr) * cos(dec*dtr);
   y2 = sin(ra*dtr) * cos(dec*dtr);
   z2 = sin(dec*dtr);

   hdr_rec->radius = acos(x1*x2 + y1*y2 + z1*z2) / dtr;

   hdr_rec->cntr = cntr;
   print_rec (hdr_rec);

   status = 0;
   fclose(fptr);

   return(nfailed);
}
Example #4
0
int main(int argc, char **argv)
{
   int    c;
   char   header[32768];
   char   temp  [MAXSTR];
   char   fmt   [MAXSTR];
   char   rfmt  [MAXSTR];
   char   pfmt  [MAXSTR];
   char   cfmt  [MAXSTR];
   char   ofile [MAXSTR];
   char   scale [MAXSTR];
   int    i, j;
   int    namelen, nimages, ntotal, stat;
   double xpos, ypos;
   double lon, lat;
   double oxpix, oypix;
   int    oxpixMin, oypixMin;
   int    oxpixMax, oypixMax;
   int    offscl, mode;
   int    ncols;
   FILE  *fraw;
   FILE  *fproj;
   FILE  *fcorr;


   /***************************************/
   /* Process the command-line parameters */
   /***************************************/

   debug   = 0;
   opterr  = 0;

   fstatus = stdout;

   while ((c = getopt(argc, argv, "ds:")) != EOF) 
   {
      switch (c) 
      {
         case 'd':
            debug = 1;
            break;

         case 's':
            if((fstatus = fopen(optarg, "w+")) == (FILE *)NULL)
            {
               printf("[struct stat=\"ERROR\", msg=\"Cannot open status file: %s\"]\n",
                  optarg);
               exit(1);
            }
            break;

         default:
	    printf("[struct stat=\"ERROR\", msg=\"Usage: %s [-d][-s statusfile] images.tbl hdr.template raw.tbl projected.tbl corrected.tbl\"]\n", argv[0]);
            exit(1);
            break;
      }
   }

   if (argc - optind < 5) 
   {
      printf("[struct stat=\"ERROR\", msg=\"Usage: %s [-d][-s statusfile] images.tbl hdr.template raw.tbl projected.tbl corrected.tbl\"]\n", argv[0]);
      exit(1);
   }

   strcpy(origimg_file,  argv[optind]);
   strcpy(template_file, argv[optind + 1]);
   strcpy(rawimg_file,   argv[optind + 2]);
   strcpy(projimg_file,  argv[optind + 3]);
   strcpy(corrimg_file,  argv[optind + 4]);

   checkHdr(template_file, 1, 0);

   if(debug)
   {
      printf("\norigimg_file   = [%s]\n", origimg_file);
      printf("template_file  = [%s]\n\n", template_file);
      printf("rawimg_file    = [%s]\n", rawimg_file);
      printf("projimg_file   = [%s]\n", projimg_file);
      printf("corrimg_file   = [%s]\n", corrimg_file);
      fflush(stdout);
   }


   /*************************************************/ 
   /* Process the output header template to get the */ 
   /* image size, coordinate system and projection  */ 
   /*************************************************/ 

   readTemplate(template_file);

   if(debug)
   {
      printf("\noutput.sys       =  %d\n",  output.sys);
      printf("output.epoch     =  %-g\n", output.epoch);
      printf("output proj      =  %s\n",  output.wcs->ptype);

      fflush(stdout);
   }


   /*********************************************/ 
   /* Open the image header metadata table file */
   /*********************************************/ 

   ncols = topen(origimg_file);

   if(ncols <= 0)
   {
      fprintf(fstatus, "[struct stat=\"ERROR\", msg=\"Invalid image metadata file: %s\"]\n",
         origimg_file);
      exit(1);
   }


   icntr    = tcol("cntr");
   ictype1  = tcol("ctype1");
   ictype2  = tcol("ctype2");
   iequinox = tcol("equinox");
   inl      = tcol("nl");
   ins      = tcol("ns");
   icrval1  = tcol("crval1");
   icrval2  = tcol("crval2");
   icrpix1  = tcol("crpix1");
   icrpix2  = tcol("crpix2");
   icdelt1  = tcol("cdelt1");
   icdelt2  = tcol("cdelt2");
   icrota2  = tcol("crota2");
   iepoch   = tcol("epoch");
   ifname   = tcol("fname");
   iscale   = tcol("scale");

   icd11    = tcol("cd1_1");
   icd12    = tcol("cd1_2");
   icd21    = tcol("cd2_1");
   icd22    = tcol("cd2_2");

   if(ins < 0)
      ins = tcol("naxis1");

   if(inl < 0)
      inl = tcol("naxis2");

   if(ifname < 0)
      ifname = tcol("file");

   if(icd11 >= 0 && icd12 >= 0  && icd21 >= 0  && icd12 >= 0)
      mode = CD;

   else if(icdelt1 >= 0 && icdelt2 >= 0  && icrota2 >= 0)
      mode = CDELT;

   else
   {
      fprintf(fstatus, "[struct stat=\"ERROR\", msg=\"Not enough information to determine coverages (CDELTs or CD matrix)\"]\n");
      exit(1);
   }


   if(icntr   < 0
   || ictype1 < 0
   || ictype2 < 0
   || inl     < 0
   || ins     < 0
   || icrval1 < 0
   || icrval2 < 0
   || icrpix1 < 0
   || icrpix2 < 0
   || ifname  < 0)
   {
      fprintf(fstatus, "[struct stat=\"ERROR\", msg=\"Need columns: cntr ctype1 ctype2 nl ns crval1 crval2 crpix1 crpix2 cdelt1 cdelt2 crota2 fname (equinox optional)\"]\n");
      exit(1);
   }


   /******************************************************/
   /* Scan the table to get the true 'file' column width */
   /******************************************************/

   namelen = 0;

   while(1)
   {
      stat = tread();

      if(stat < 0)
	 break;

      strcpy(input.fname, fileName(tval(ifname)));

      if(strlen(input.fname) > namelen)
	 namelen = strlen(input.fname);
   }

   tseek(0);


   /*************************************/
   /* Write headers to the output files */
   /*************************************/

   if((fraw = (FILE *)fopen(rawimg_file, "w+")) == (FILE *)NULL)
   {
      fprintf(fstatus, "[struct stat=\"ERROR\", msg=\"Invalid output metadata file: %s\"]\n",
         rawimg_file);
      exit(1);
   }

   fprintf(fraw, "\\datatype=fitshdr\n");

   if(iscale >= 0)
   {
      sprintf(fmt, "|%%5s|%%8s|%%8s|%%6s|%%6s|%%10s|%%10s|%%10s|%%10s|%%11s|%%11s|%%8s|%%7s|%%10s|%%%ds|\n", namelen+2);

      fprintf(fraw, fmt,
	 "cntr",
	 "ctype1",
	 "ctype2",
	 "naxis1",
	 "naxis2",
	 "crval1",
	 "crval2",
	 "crpix1",
	 "crpix2",
	 "cdelt1",
	 "cdelt2",
	 "crota2",
	 "equinox",
	 "scale",
	 "file");

      fprintf(fraw, fmt,
	 "int",
	 "char",
	 "char",
	 "int",
	 "int",
	 "double",
	 "double",
	 "double",
	 "double",
	 "double",
	 "double",
	 "double",
	 "int",
	 "double",
	 "char");
   }
   else
   {
      sprintf(fmt, "|%%5s|%%8s|%%8s|%%6s|%%6s|%%10s|%%10s|%%10s|%%10s|%%11s|%%11s|%%8s|%%7s|%%%ds|\n", namelen+2);


      fprintf(fraw, fmt,
	 "cntr",
	 "ctype1",
	 "ctype2",
	 "naxis1",
	 "naxis2",
	 "crval1",
	 "crval2",
	 "crpix1",
	 "crpix2",
	 "cdelt1",
	 "cdelt2",
	 "crota2",
	 "equinox",
	 "file");

      fprintf(fraw, fmt,
	 "int",
	 "char",
	 "char",
	 "int",
	 "int",
	 "double",
	 "double",
	 "double",
	 "double",
	 "double",
	 "double",
	 "double",
	 "int",
	 "char");
   }

   if((fproj = (FILE *)fopen(projimg_file, "w+")) == (FILE *)NULL)
   {
      fprintf(fstatus, "[struct stat=\"ERROR\", msg=\"Invalid output metadata file: %s\"]\n",
         projimg_file);
      exit(1);
   }

   fprintf(fproj, "\\datatype=fitshdr\n");

   sprintf(fmt, "|%%5s|%%8s|%%8s|%%6s|%%6s|%%10s|%%10s|%%10s|%%10s|%%11s|%%11s|%%8s|%%7s|%%%ds|\n", namelen+2);

   fprintf(fproj, fmt,
      "cntr",
      "ctype1",
      "ctype2",
      "naxis1",
      "naxis2",
      "crval1",
      "crval2",
      "crpix1",
      "crpix2",
      "cdelt1",
      "cdelt2",
      "crota2",
      "equinox",
      "file");

   fprintf(fproj, fmt,
      "int",
      "char",
      "char",
      "int",
      "int",
      "double",
      "double",
      "double",
      "double",
      "double",
      "double",
      "double",
      "int",
      "char");


   if((fcorr = (FILE *)fopen(corrimg_file, "w+")) == (FILE *)NULL)
   {
      fprintf(fstatus, "[struct stat=\"ERROR\", msg=\"Invalid output metadata file: %s\"]\n",
         corrimg_file);
      exit(1);
   }

   fprintf(fcorr, "\\datatype=fitshdr\n");

   fprintf(fcorr, fmt,
      "cntr",
      "ctype1",
      "ctype2",
      "naxis1",
      "naxis2",
      "crval1",
      "crval2",
      "crpix1",
      "crpix2",
      "cdelt1",
      "cdelt2",
      "crota2",
      "equinox",
      "file");

   fprintf(fcorr, fmt,
      "int",
      "char",
      "char",
      "int",
      "int",
      "double",
      "double",
      "double",
      "double",
      "double",
      "double",
      "double",
      "int",
      "char");


   /************************************************/
   /* Read the metadata and process each image WCS */
   /************************************************/

   namelen = 0;
   nimages = 0;
   ntotal  = 0;

   if(iscale >= 0)
      sprintf(rfmt, " %%5d %%8s %%8s %%6d %%6d %%10.6f %%10.6f %%10.2f %%10.2f %%11.8f %%11.8f %%8.5f %%7.0f %%10s %%%ds\n", namelen+2);
   else
      sprintf(rfmt, " %%5d %%8s %%8s %%6d %%6d %%10.6f %%10.6f %%10.2f %%10.2f %%11.8f %%11.8f %%8.5f %%7.0f %%%ds\n", namelen+2);

   sprintf(pfmt, " %%5d %%8s %%8s %%6d %%6d %%10.6f %%10.6f %%10.2f %%10.2f %%11.8f %%11.8f %%8.5f %%7.0f p%%%ds\n", namelen+2);

   sprintf(cfmt, " %%5d %%8s %%8s %%6d %%6d %%10.6f %%10.6f %%10.2f %%10.2f %%11.8f %%11.8f %%8.5f %%7.0f c%%%ds\n", namelen+2);

   while(1)
   {
      stat = tread();

      if(stat < 0)
	 break;
      
      ++ntotal;

      strcpy(input.ctype1, tval(ictype1));
      strcpy(input.ctype2, tval(ictype2));

      input.cntr      = atoi(tval(icntr));
      input.naxis1    = atoi(tval(ins));
      input.naxis2    = atoi(tval(inl));
      input.crpix1    = atof(tval(icrpix1));
      input.crpix2    = atof(tval(icrpix2));
      input.crval1    = atof(tval(icrval1));
      input.crval2    = atof(tval(icrval2));

      if(mode == CDELT)
      {
	 input.cdelt1    = atof(tval(icdelt1));
	 input.cdelt2    = atof(tval(icdelt2));
	 input.crota2    = atof(tval(icrota2));
      }
      else
      {
	 input.cd11      = atof(tval(icd11));
	 input.cd12      = atof(tval(icd12));
	 input.cd21      = atof(tval(icd21));
	 input.cd22      = atof(tval(icd22));
      }

      input.epoch     = 2000;

      strcpy(header, "");
      sprintf(temp, "SIMPLE  = T"                    ); stradd(header, temp);
      sprintf(temp, "BITPIX  = -64"                  ); stradd(header, temp);
      sprintf(temp, "NAXIS   = 2"                    ); stradd(header, temp);
      sprintf(temp, "NAXIS1  = %d",     input.naxis1 ); stradd(header, temp);
      sprintf(temp, "NAXIS2  = %d",     input.naxis2 ); stradd(header, temp);
      sprintf(temp, "CTYPE1  = '%s'",   input.ctype1 ); stradd(header, temp);
      sprintf(temp, "CTYPE2  = '%s'",   input.ctype2 ); stradd(header, temp);
      sprintf(temp, "CRVAL1  = %11.6f", input.crval1 ); stradd(header, temp);
      sprintf(temp, "CRVAL2  = %11.6f", input.crval2 ); stradd(header, temp);
      sprintf(temp, "CRPIX1  = %11.6f", input.crpix1 ); stradd(header, temp);
      sprintf(temp, "CRPIX2  = %11.6f", input.crpix2 ); stradd(header, temp);

      if(mode == CDELT)
      {
      sprintf(temp, "CDELT1  = %11.6f", input.cdelt1 ); stradd(header, temp);
      sprintf(temp, "CDELT2  = %11.6f", input.cdelt2 ); stradd(header, temp);
      sprintf(temp, "CROTA2  = %11.6f", input.crota2 ); stradd(header, temp);
      }
      else
      {
      sprintf(temp, "CD1_1   = %11.6f", input.cd11   ); stradd(header, temp);
      sprintf(temp, "CD1_2   = %11.6f", input.cd12   ); stradd(header, temp);
      sprintf(temp, "CD2_1   = %11.6f", input.cd21   ); stradd(header, temp);
      sprintf(temp, "CD2_2   = %11.6f", input.cd22   ); stradd(header, temp);
      }

      sprintf(temp, "EQUINOX = %d",     input.equinox); stradd(header, temp);
      sprintf(temp, "END"                            ); stradd(header, temp);
      
      if(iequinox >= 0)
	 input.equinox = atoi(tval(iequinox));

      strcpy(input.fname, fileName(tval(ifname)));

      if(iscale >= 0)
	 strcpy(scale, tval(iscale));

      if(strlen(input.fname) > namelen)
	 namelen = strlen(input.fname);

      if(debug)
      {
	 printf("Image header to wcsinit():\n%s\n", header);
	 fflush(stdout);
      }

      input.wcs = wcsinit(header);

      checkWCS(input.wcs, 0);
			     
      if(input.wcs == (struct WorldCoor *)NULL)
      {
	 fprintf(fstatus, "[struct stat=\"ERROR\", msg=\"Bad WCS for image %d\"]\n", 
	    nimages);
	 exit(1);
      }


      /***************************************************/
      /* Check the boundaries of the input image against */
      /* the output region of interest                   */
      /***************************************************/

      oxpixMin =  100000000;
      oxpixMax = -100000000;
      oypixMin =  100000000;
      oypixMax = -100000000;

      /* Check input left and right */

      for (j=0; j<input.naxis2+1; ++j)
      {
	 pix2wcs(input.wcs, 0.5, j+0.5, &xpos, &ypos);

	 convertCoordinates(input.sys, input.epoch, xpos, ypos,
			    output.sys, output.epoch, &lon, &lat, 0.0);
	 
	 wcs2pix(output.wcs, lon, lat, &oxpix, &oypix, &offscl);

	 if(!offscl)
	 {
	    if(oxpix < oxpixMin) oxpixMin = oxpix;
	    if(oxpix > oxpixMax) oxpixMax = oxpix;
	    if(oypix < oypixMin) oypixMin = oypix;
	    if(oypix > oypixMax) oypixMax = oypix;
	 }

	 pix2wcs(input.wcs, input.naxis1+0.5, j+0.5, &xpos, &ypos);

	 convertCoordinates(input.sys, input.epoch, xpos, ypos,
			    output.sys, output.epoch, &lon, &lat, 0.0);
	 
	 wcs2pix(output.wcs, lon, lat, &oxpix, &oypix, &offscl);

	 if(!offscl)
	 {
	    if(oxpix < oxpixMin) oxpixMin = oxpix;
	    if(oxpix > oxpixMax) oxpixMax = oxpix;
	    if(oypix < oypixMin) oypixMin = oypix;
	    if(oypix > oypixMax) oypixMax = oypix;
	 }
      }


      /* Check input top and bottom */

      for (i=0; i<input.naxis1+1; ++i)
      {
	 pix2wcs(input.wcs, i+0.5, 0.5, &xpos, &ypos);

	 convertCoordinates(input.sys, input.epoch, xpos, ypos,
			    output.sys, output.epoch, &lon, &lat, 0.0);
	 
	 wcs2pix(output.wcs, lon, lat, &oxpix, &oypix, &offscl);

	 if(!offscl)
	 {
	    if(oxpix < oxpixMin) oxpixMin = oxpix;
	    if(oxpix > oxpixMax) oxpixMax = oxpix;
	    if(oypix < oypixMin) oypixMin = oypix;
	    if(oypix > oypixMax) oypixMax = oypix;
	 }

	 pix2wcs(input.wcs, i+0.5, input.naxis2+0.5, &xpos, &ypos);

	 convertCoordinates(input.sys, input.epoch, xpos, ypos,
			    output.sys, output.epoch, &lon, &lat, 0.0);
	 
	 wcs2pix(output.wcs, lon, lat, &oxpix, &oypix, &offscl);

	 if(!offscl)
	 {
	    if(oxpix < oxpixMin) oxpixMin = oxpix;
	    if(oxpix > oxpixMax) oxpixMax = oxpix;
	    if(oypix < oypixMin) oypixMin = oypix;
	    if(oypix > oypixMax) oypixMax = oypix;
	 }
      }


      /***************************************************/
      /* Check the boundaries of the region of interest  */
      /* against the input image                         */
      /***************************************************/

      /* Check ouput left and right */

      for (j=0; j<output.wcs->nypix+1; ++j)
      {
	 pix2wcs(output.wcs, 0.5, j+0.5, &xpos, &ypos);

	 convertCoordinates(output.sys, output.epoch, xpos, ypos,
			     input.sys,  input.epoch, &lon, &lat, 0.0);
	 
	 wcs2pix(input.wcs, lon, lat, &oxpix, &oypix, &offscl);

	 if(!offscl)
	 {
	    if(0.5   < oxpixMin) oxpixMin = 0.5;
	    if(0.5   > oxpixMax) oxpixMax = 0.5;

	    if(j+0.5 < oypixMin) oypixMin = j+0.5;
	    if(j+0.5 > oypixMax) oypixMax = j+0.5;
	 }

	 pix2wcs(output.wcs, output.wcs->nxpix+0.5, j+0.5, &xpos, &ypos);

	 convertCoordinates(output.sys, output.epoch, xpos, ypos,
			     input.sys,  input.epoch, &lon, &lat, 0.0);
	 
	 wcs2pix(input.wcs, lon, lat, &oxpix, &oypix, &offscl);

	 if(!offscl)
	 {
	    if(output.wcs->nxpix+0.5 < oxpixMin) oxpixMin = output.wcs->nxpix+0.5;
	    if(output.wcs->nxpix+0.5 > oxpixMax) oxpixMax = output.wcs->nxpix+0.5;

	    if(j+0.5 < oypixMin) oypixMin = j+0.5;
	    if(j+0.5 > oypixMax) oypixMax = j+0.5;
	 }
      }


      /* Check input top and bottom */

      for (i=0; i<output.wcs->nxpix+1; ++i)
      {
	 pix2wcs(output.wcs, i+0.5, 0.5, &xpos, &ypos);

	 convertCoordinates(output.sys, output.epoch, xpos, ypos,
			     input.sys,  input.epoch, &lon, &lat, 0.0);
	 
	 wcs2pix(input.wcs, lon, lat, &oxpix, &oypix, &offscl);

	 if(!offscl)
	 {
	    if(i+0.5 < oxpixMin) oxpixMin = i+0.5;
	    if(i+0.5 > oxpixMax) oxpixMax = i+0.5;

	    if(0.5   < oypixMin) oypixMin = 0.5  ;
	    if(0.5   > oypixMax) oypixMax = 0.5  ;
	 }

	 pix2wcs(output.wcs, i+0.5, output.wcs->nypix+0.5, &xpos, &ypos);

	 convertCoordinates(output.sys, output.epoch, xpos, ypos,
			     input.sys,  input.epoch, &lon, &lat, 0.0);
	 
	 wcs2pix(input.wcs, lon, lat, &oxpix, &oypix, &offscl);

	 if(!offscl)
	 {
	    if(i+0.5 < oxpixMin) oxpixMin = i+0.5;
	    if(i+0.5 > oxpixMax) oxpixMax = i+0.5;

	    if(output.wcs->nypix+0.5 < oypixMin) oypixMin = output.wcs->nypix+0.5;
	    if(output.wcs->nypix+0.5 > oypixMax) oypixMax = output.wcs->nypix+0.5;
	 }
      }

      if(oxpixMax < oxpixMin) continue;
      if(oypixMax < oypixMin) continue;


      /* Remove any possible compression extension */

      strcpy(ofile, input.fname);

      if(strlen(ofile) > 3 && strcmp(ofile+strlen(ofile)-3, ".gz") == 0)
	 ofile[strlen(ofile)-3] = '\0';

      else if(strlen(ofile) > 2 && strcmp(ofile+strlen(ofile)-2, ".Z") == 0)
	 ofile[strlen(ofile)-2] = '\0';

      else if(strlen(ofile) > 2 && strcmp(ofile+strlen(ofile)-2, ".z") == 0)
	 ofile[strlen(ofile)-2] = '\0';

      else if(strlen(ofile) > 4 && strcmp(ofile+strlen(ofile)-4, ".zip") == 0)
	 ofile[strlen(ofile)-4] = '\0';

      else if(strlen(ofile) > 2 && strcmp(ofile+strlen(ofile)-2, "-z") == 0)
	 ofile[strlen(ofile)-2] = '\0';

      else if(strlen(ofile) > 3 && strcmp(ofile+strlen(ofile)-3, "-gz") == 0)
	 ofile[strlen(ofile)-3] = '\0';


      /* Make sure the extension is ".fits" */

      if(strlen(ofile) > 5 && strcmp(ofile+strlen(ofile)-5, ".fits") == 0)
	 ofile[strlen(ofile)-5] = '\0';

      else if(strlen(ofile) > 5 && strcmp(ofile+strlen(ofile)-5, ".FITS") == 0)
	 ofile[strlen(ofile)-5] = '\0';

      else if(strlen(ofile) > 4 && strcmp(ofile+strlen(ofile)-4, ".fit") == 0)
	 ofile[strlen(ofile)-4] = '\0';

      else if(strlen(ofile) > 4 && strcmp(ofile+strlen(ofile)-4, ".FIT") == 0)
	 ofile[strlen(ofile)-4] = '\0';

      else if(strlen(ofile) > 4 && strcmp(ofile+strlen(ofile)-4, ".fts") == 0)
	 ofile[strlen(ofile)-4] = '\0';

      else if(strlen(ofile) > 4 && strcmp(ofile+strlen(ofile)-4, ".FTS") == 0)
	 ofile[strlen(ofile)-4] = '\0';

      strcat(ofile, ".fits");

      if(iscale >= 0)
      {
	 fprintf(fraw, rfmt,
	   nimages+1,
	   output.wcs->ctype[0],
	   output.wcs->ctype[1],
	   oxpixMax - oxpixMin + 1,
	   oypixMax - oypixMin + 1,
	   output.wcs->crval[0],
	   output.wcs->crval[1],
	   output.wcs->crpix[0] - oxpixMin,
	   output.wcs->crpix[1] - oypixMin,
	   output.wcs->cdelt[0],
	   output.wcs->cdelt[1],
	   output.wcs->rot,
	   output.epoch,
	   scale,
	   ofile);
      }
      else
      {
	 fprintf(fraw, rfmt,
	   nimages+1,
	   output.wcs->ctype[0],
	   output.wcs->ctype[1],
	   oxpixMax - oxpixMin + 1,
	   oypixMax - oypixMin + 1,
	   output.wcs->crval[0],
	   output.wcs->crval[1],
	   output.wcs->crpix[0] - oxpixMin,
	   output.wcs->crpix[1] - oypixMin,
	   output.wcs->cdelt[0],
	   output.wcs->cdelt[1],
	   output.wcs->rot,
	   output.epoch,
	   ofile);
      }

      fprintf(fproj, pfmt,
	nimages+1,
	output.wcs->ctype[0],
	output.wcs->ctype[1],
	oxpixMax - oxpixMin + 1,
	oypixMax - oypixMin + 1,
	output.wcs->crval[0],
	output.wcs->crval[1],
	output.wcs->crpix[0] - oxpixMin,
	output.wcs->crpix[1] - oypixMin,
	output.wcs->cdelt[0],
	output.wcs->cdelt[1],
	output.wcs->rot,
	output.epoch,
	ofile);

      fprintf(fcorr, cfmt,
	nimages+1,
	output.wcs->ctype[0],
	output.wcs->ctype[1],
	oxpixMax - oxpixMin + 1,
	oypixMax - oypixMin + 1,
	output.wcs->crval[0],
	output.wcs->crval[1],
	output.wcs->crpix[0] - oxpixMin,
	output.wcs->crpix[1] - oypixMin,
	output.wcs->cdelt[0],
	output.wcs->cdelt[1],
	output.wcs->rot,
	output.epoch,
	ofile);

      ++nimages;
   }


   fclose(fraw);
   fclose(fproj);
   fclose(fcorr);

   fprintf(fstatus, "[struct stat=\"OK\", count=\"%d\", total=\"%d\"]\n", 
      nimages, ntotal);
   fflush(stdout);

   exit(0);
}