Esempio n. 1
0
flouble *he_read_healpix_map(char *fname,long *nside,int nfield)
{
  //////
  // Reads a healpix map from file fname. The map will be
  // read from column #nfield. It also returns the map's nside.
  int status=0,hdutype,nfound,anynul;
  long naxes,*naxis,npix;
  fitsfile *fptr;
  flouble *map,nulval;
  char order_in_file[32];
  int nested_in_file=0;

  fits_open_file(&fptr,fname,READONLY,&status);
  fits_movabs_hdu(fptr,2,&hdutype,&status);
  fits_read_key_lng(fptr,"NAXIS",&naxes,NULL,&status);
  naxis=(long *)malloc(naxes*sizeof(long));
  fits_read_keys_lng(fptr,"NAXIS",1,naxes,naxis,&nfound,&status);
  fits_read_key_lng(fptr,"NSIDE",nside,NULL,&status);
  npix=12*(*nside)*(*nside);
  if(npix%naxis[1]!=0) {
    fprintf(stderr,"CRIME: WTFFF\n");
    exit(1);
  }

  if (fits_read_key(fptr, TSTRING, "ORDERING", order_in_file, NULL, &status)) {
    fprintf(stderr, "WARNING: Could not find %s keyword in in file %s\n",
            "ORDERING",fname);
    exit(1);
  }
  if(!strncmp(order_in_file,"NEST",4))
    nested_in_file=1;

  map=(flouble *)my_malloc(npix*sizeof(flouble));
#ifdef _SPREC
  fits_read_col(fptr,TFLOAT,nfield+1,1,1,npix,&nulval,map,&anynul,&status);
#else //_SPREC
  fits_read_col(fptr,TDOUBLE,nfield+1,1,1,npix,&nulval,map,&anynul,&status);
#endif //_SPREC
  free(naxis);

  fits_close_file(fptr,&status);

  flouble *map_ring;
  if(nested_in_file) {
    long ipring,ipnest;

    printf("read_healpix_map: input is nested. Transforming to ring.\n");
    map_ring=(flouble *)my_malloc(npix*sizeof(flouble));
    for(ipnest=0;ipnest<npix;ipnest++) {
      nest2ring(*nside,ipnest,&ipring);
      map_ring[ipring]=map[ipnest];
    }
    free(map);
  }
  else
    map_ring=map;

  return map_ring;
}
Esempio n. 2
0
struct WorldCoor *montage_getFileInfo(fitsfile *infptr, char *header[], struct imageParams *params)
{
   struct WorldCoor *wcs;
   int status = 0;
   int i;

   if(fits_get_image_wcs_keys(infptr, header, &status))
      montage_printFitsError(status);

   if(fits_read_key_lng(infptr, "NAXIS", &params->naxis, (char *)NULL, &status))
      montage_printFitsError(status);
   
   if(fits_read_keys_lng(infptr, "NAXIS", 1, params->naxis, params->naxes, &params->nfound, &status))
      montage_printFitsError(status);
   
   if(debug)
   {
      for(i=0; i<params->naxis; ++i)
         printf("naxis%d = %ld\n",  i+1, params->naxes[i]);

      fflush(stdout);
   }

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

   wcs = wcsinit(header[0]);

   params->isDSS = 0;
   if(wcs->prjcode == WCS_DSS)
      params->isDSS = 1;

   if(wcs == (struct WorldCoor *)NULL)
   {
      fprintf(fstatus, "[struct stat=\"ERROR\", msg=\"Output wcsinit() failed.\"]\n");
      fflush(stdout);
      exit(1);
   }

   /* Extract the CRPIX and (equivalent) CDELT values */
   /* from the WCS structure                          */

   params->crpix[0] = wcs->xrefpix;
   params->crpix[1] = wcs->yrefpix;

   if(params->isDSS)
   {
      params->cnpix[0] = wcs->x_pixel_offset;
      params->cnpix[1] = wcs->y_pixel_offset;
   }
   return wcs;
}
Esempio n. 3
0
void montage_dataRange(fitsfile *infptr, int *imin, int *imax, int *jmin, int *jmax)
{
   long    fpixel[4];
   long    naxis, naxes[10];
   int     i, j, nullcnt, nfound;
   double *buffer;

   int     status = 0;

   /*************************************************/
   /* Make a NaN value to use checking blank pixels */
   /*************************************************/

   union
   {
      double d;
      char   c[8];
   }
   value;

   double nan;

   for(i=0; i<8; ++i)
      value.c[i] = 255;

   nan = value.d;

   if(fits_read_key_lng(infptr, "NAXIS", &naxis, (char *)NULL, &status))
      montage_printFitsError(status);
   
   if(fits_read_keys_lng(infptr, "NAXIS", 1, naxis, naxes, &nfound, &status))
      montage_printFitsError(status);

   fpixel[0] = 1;
   fpixel[1] = 1;
   fpixel[2] = 1;
   fpixel[3] = 1;

   *imin =  1000000000;
   *imax = -1;
   *jmin =  1000000000;
   *jmax = -1;

   buffer  = (double *)malloc(naxes[0] * sizeof(double));

   for (j=1; j<=naxes[1]; ++j)
   {
      if(debug >= 2)
      {
         printf("Processing image row %5d\n", j);
         fflush(stdout);
      }

      if(fits_read_pix(infptr, TDOUBLE, fpixel, naxes[0], &nan,
                       buffer, &nullcnt, &status))
         montage_printFitsError(status);

      for(i=1; i<=naxes[0]; ++i)
      {
         if(!mNaN(buffer[i-1]))
         {
            if(buffer[i-1] != nan)
            {
               if(i < *imin) *imin = i;
               if(i > *imax) *imax = i;
               if(j < *jmin) *jmin = j;
               if(j > *jmax) *jmax = j;
            }
         }
      }

      ++fpixel [1];
   }

   free(buffer);
}
Esempio n. 4
0
/**
 * Function: get_ALL_from_next_in_SPC
 * The function creates and fills a full spectrum structure with
 * the content of a SPC table extension. This is only done when,
 * according to the beam ID, this beam should be corrected.
 * For extensions with higher order beams which are not corrected
 * an emply structure is returned.
 *
 * Parameters:
 * @param SPCn_ptr - pointer to the opened SPC file
 * @param aperID   - pointer to aperture identification number
 * @param beamID   - pointer to beam identification number
 *
 * Returns:
 * @return SPC - the full spectrum structure
 */
full_spectr *
get_ALL_from_next_in_SPC(fitsfile *SPC_ptr, int *aperID, int *beamID)
{
  int f_status=0, hdutype;

  long tmp;
  //long nrows=0;
  char comment[FLEN_COMMENT];

  full_spectr *SPC;


  fits_movrel_hdu (SPC_ptr, 1, &hdutype, &f_status);

  if (f_status)
    {
      *aperID = -1;
      *beamID = -1;
      SPC = NULL;
      return SPC;
    }


  // read the beam ID number
  fits_read_key_lng (SPC_ptr, "BEAMID", &tmp, comment, &f_status);
  if (f_status)
    {
      ffrprt (stderr, f_status);
      aXe_message (aXe_M_FATAL, __FILE__, __LINE__,
		   "get_ALL_from_next_in_SPC: Error getting index keyword OBJECTID");
    }
  *beamID = (int)tmp;

  // check whether this beam should be correct
  if (*beamID > CORRMAX)
    {
      // set it to NULL and return
      SPC = NULL;
      //      fprintf (stdout, "aXe_PETFF: Skipping beam: %c.\n", BEAM(*beamID));
      return SPC;
    }

  // the beam shall be corrected and
  // first must be read in
  SPC = (full_spectr *) malloc (sizeof (full_spectr ));

  // transfer the beam ID
  SPC->beamID = (int)tmp;

  // read the aperture number
  fits_read_key_lng (SPC_ptr, "OBJECTID", &tmp, comment, &f_status);
  if (f_status)
    {
      ffrprt (stderr, f_status);
      aXe_message (aXe_M_FATAL, __FILE__, __LINE__,
		   "get_ALL_from_next_in_SPC: Error getting index keyword OBJECTID");
    }
  // transfer the aperture ID
  *aperID = (int)tmp;
  SPC->aperID = (int)tmp;


  // Get the number of rows
  fits_get_num_rows (SPC_ptr, &tmp, &f_status);
  if (f_status) {
    ffrprt (stderr, f_status);
    aXe_message (aXe_M_FATAL, __FILE__, __LINE__,
		 "get_ALL_from_next_in_SPC: "
		 "Could not determine the number of rows in"
		 " correction function table!");
  }
  SPC->nelems = (int)tmp;

  // load the background subtracted object spectrum
  SPC->obj_spec = get_spectrum_from_SPC(SPC_ptr, "COUNT", "ERROR", SPC->nelems);

  // load the total object spectrum
  SPC->fgr_spec = get_spectrum_from_SPC(SPC_ptr, "TCOUNT", "TERROR", SPC->nelems);

  // load the background spectrum
  SPC->bck_spec = get_spectrum_from_SPC(SPC_ptr, "BCOUNT", "BERROR", SPC->nelems);

  // return the filled structure
  return SPC;
}
Esempio n. 5
0
struct mExamineReturn * mExamine(char *infile, int areaMode, int hdu, int plane3, int plane4, 
                                 double ra, double dec, double radius, int locinpix, int radinpix, int debug)
{
   int    i, j, offscl, nullcnt;
   int    status, clockwise, nfound;
   int    npix, nnull, first;
   int    ixpix, iypix;
   int    maxi, maxj;

   char  *header;
   char   tmpstr[32768];

   char   proj[32];
   int    csys;
   char   csys_str[64];

   char   ctype1[256];
   char   ctype2[256];

   double equinox;

   long   naxis;
   long   naxes[10];

   double naxis1;
   double naxis2;

   double crval1;
   double crval2;

   double crpix1;
   double crpix2;

   double cdelt1;
   double cdelt2;

   double crota2;

   double lon, lat;
   double lonc, latc;
   double rac, decc;
   double racp, deccp;
   double ra1, dec1, ra2, dec2, ra3, dec3, ra4, dec4;
   double xpix, ypix, rpix, rap;

   double x, y, z;
   double xp, yp, zp;

   double rot, beta, dtr;
   double r;

   double sumflux, sumflux2, sumn, mean, background, oldbackground, rms, dot;
   double sigmaref, sigmamax, sigmamin;
   double val, valx, valy, valra, valdec;
   double min, minx, miny, minra, mindec;
   double max, maxx, maxy, maxra, maxdec;
   double x0, y0, z0;

   double  fluxMin, fluxMax, fluxRef, sigma;

   struct WorldCoor *wcs;

   fitsfile *fptr;
   int       ibegin, iend, jbegin, jend;
   long      fpixel[4], nelements;

   double   *data = (double *)NULL;

   struct apPhoto *ap = (struct apPhoto *)NULL;

   int nflux, maxflux;


   struct mExamineReturn *returnStruct;

   returnStruct = (struct mExamineReturn *)malloc(sizeof(struct mExamineReturn));

   memset((void *)returnStruct, 0, sizeof(returnStruct));


   returnStruct->status = 1;

   strcpy(returnStruct->msg, "");


   nflux   = 0;
   maxflux = MAXFLUX;


   /************************************************/
   /* Make a NaN value to use setting blank pixels */
   /************************************************/

   union
   {
      double d;
     char   c[8];
   }
   value;

   double nan;

   for(i=0; i<8; ++i)
      value.c[i] = (char)255;

   nan = value.d;


   dtr = atan(1.)/45.;


   /* Process basic command-line arguments */

   if(debug)
   {
      printf("DEBUG> areaMode = %d \n", areaMode);
      printf("DEBUG> infile   = %s \n", infile);
      printf("DEBUG> ra       = %-g\n", ra);
      printf("DEBUG> dec      = %-g\n", dec);
      printf("DEBUG> radius   = %-g\n", radius);
      fflush(stdout);
   }

   rpix = 0.;

   if(areaMode == APPHOT)
      ap = (struct apPhoto *)malloc(maxflux * sizeof(struct apPhoto));


   /* Open the FITS file and initialize the WCS transform */

   status = 0;
   if(fits_open_file(&fptr, infile, READONLY, &status))
   {
      if(ap) free(ap);
      sprintf(returnStruct->msg, "Cannot open FITS file %s", infile);
      return returnStruct;
   }

   if(hdu > 0)
   {
      status = 0;
      if(fits_movabs_hdu(fptr, hdu+1, NULL, &status))
      {
         if(ap) free(ap);
         sprintf(returnStruct->msg, "Can't find HDU %d", hdu);
         return returnStruct;
      }
   }

   status = 0;
   if(fits_get_image_wcs_keys(fptr, &header, &status))
   {
      if(ap) free(ap);
      sprintf(returnStruct->msg, "Cannot find WCS keys in FITS file %s", infile);
      return returnStruct;
   }

   status = 0;
   if(fits_read_key_lng(fptr, "NAXIS", &naxis, (char *)NULL, &status))
   {
      if(ap) free(ap);
      sprintf(returnStruct->msg, "Cannot find NAXIS keyword in FITS file %s", infile);
      return returnStruct;
   }

   status = 0;
   if(fits_read_keys_lng(fptr, "NAXIS", 1, naxis, naxes, &nfound, &status))
   {
      if(ap) free(ap);
      sprintf(returnStruct->msg, "Cannot find NAXIS1,2 keywords in FITS file %s", infile);
      return returnStruct;
   }


   wcs = wcsinit(header);

   if(wcs == (struct WorldCoor *)NULL)
   {
      if(ap) free(ap);
      sprintf(returnStruct->msg, "WCS initialization failed.");
      return returnStruct;
   }



   /* A bunch of the parameters we want are in the WCS structure */

   clockwise = 0;

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

   naxis1 = wcs->nxpix;
   naxis2 = wcs->nypix;

   crval1 = wcs->xref;
   crval2 = wcs->yref;

   crpix1 = wcs->xrefpix;
   crpix2 = wcs->yrefpix;

   cdelt1 = wcs->xinc;
   cdelt2 = wcs->yinc;

   crota2 = wcs->rot;

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

   strcpy(proj, "");

   if(strlen(ctype1) > 5)
   strcpy (proj, ctype1+5);  


   /* We get the Equinox from the WCS.  If not    */
   /* there we take the command-line value. We    */
   /* then infer Julian/Besselian as best we can. */

   equinox = wcs->equinox;

   csys = EQUJ;
   strcpy(csys_str, "EQUJ");

   if(strncmp(ctype1, "RA--", 4) == 0)
   {
      csys = EQUJ;

      strcpy(csys_str, "EQUJ");

      if(equinox < 1975.)
      {
         csys = EQUB;

         strcpy(csys_str, "EQUB");
      }
   }

   if(strncmp(ctype1, "LON-", 4) == 0)
   {
      csys = GAL;
      strcpy(csys_str, "GAL");
   }

   if(strncmp(ctype1, "GLON", 4) == 0)
   {
      csys = GAL;
      strcpy(csys_str, "GAL");
   }

   if(strncmp(ctype1, "ELON", 4) == 0)
   {
      csys = ECLJ;

      strcpy(csys_str, "ECLJ");

      if(equinox < 1975.)
      {
         csys = ECLB;

         strcpy(csys_str, "ECLB");
      }
   }

   if(debug)
   {
      printf("DEBUG> proj      = [%s]\n", proj);
      printf("DEBUG> csys      = %d\n",   csys);
      printf("DEBUG> clockwise = %d\n",   clockwise);
      printf("DEBUG> ctype1    = [%s]\n", ctype1);
      printf("DEBUG> ctype2    = [%s]\n", ctype2);
      printf("DEBUG> equinox   = %-g\n",  equinox);

      printf("\n");
      fflush(stdout);
   }


   /* To get corners and rotation in EQUJ we need the     */
   /* locations of the center pixel and the one above it. */

   pix2wcs(wcs, wcs->nxpix/2.+0.5, wcs->nypix/2.+0.5, &lonc, &latc);
   convertCoordinates (csys, equinox, lonc, latc, 
                       EQUJ, 2000., &rac, &decc, 0.);

   pix2wcs(wcs, wcs->nxpix/2.+0.5, wcs->nypix/2.+1.5, &lonc, &latc);
   convertCoordinates (csys, equinox, lonc, latc, 
                       EQUJ, 2000., &racp, &deccp, 0.);


   /* Use spherical trig to get the Equatorial rotation angle */

   x = cos(decc*dtr) * cos(rac*dtr);
   y = cos(decc*dtr) * sin(rac*dtr);
   z = sin(decc*dtr);

   xp = cos(deccp*dtr) * cos(racp*dtr);
   yp = cos(deccp*dtr) * sin(racp*dtr);
   zp = sin(deccp*dtr);

   beta = acos(x*xp + y*yp + z*zp) / dtr;

   rot = asin(cos(deccp*dtr) * sin((rac-racp)*dtr)/sin(beta*dtr)) / dtr;


   /* And for the four corners we want them uniformly clockwise */

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


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


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


      pix2wcs(wcs, -0.5, wcs->nypix+0.5, &lon, &lat);
      convertCoordinates (csys, equinox, lon, lat, 
                          EQUJ, 2000., &ra4, &dec4, 0.);
   }
   else
   {
      pix2wcs(wcs, -0.5, -0.5, &lon, &lat);
      convertCoordinates (csys, equinox, lon, lat, 
                          EQUJ, 2000., &ra2, &dec2, 0.);


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


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


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


   // Treat the default region (ALL) as a circle 
   // containing the whole image

   if(areaMode == ALL)
   {
      locinpix = 1;
      radinpix = 1;

      ra  = wcs->nxpix / 2.;
      dec = wcs->nypix / 2.;

      radius = sqrt(wcs->nxpix*wcs->nxpix + wcs->nypix*wcs->nypix)/2.;
   }


   /* Get region statistics */

   ixpix = 1;
   iypix = 1;

   if(radinpix) 
   {
      rpix   = radius;
      radius = rpix * fabs(cdelt2);
   }
   else
      rpix = radius / fabs(cdelt2);

   if(locinpix)
   {
      xpix = ra;
      ypix = dec;

      pix2wcs(wcs, xpix, ypix, &lon, &lat);

      if(wcs->offscl)
      {
         if(ap) free(ap);
         sprintf(returnStruct->msg, "Location off the image.");
         return returnStruct;
      }

      convertCoordinates (csys, equinox, lon, lat,
            EQUJ, 2000., &ra, &dec, 0);
   }
   else
   {
      convertCoordinates (EQUJ, 2000., ra, dec,  
            csys, equinox, &lon, &lat, 0.);

      wcs2pix(wcs, lon, lat, &xpix, &ypix, &offscl);

      if(offscl)
      {
         if(ap) free(ap);
         sprintf(returnStruct->msg, "Location off the image.");
         return returnStruct;
      }
   }



   x0 = cos(ra*dtr) * cos(dec*dtr);
   y0 = sin(ra*dtr) * cos(dec*dtr);
   z0 = sin(dec*dtr);

   ixpix = (int)(xpix+0.5);
   iypix = (int)(ypix+0.5);

   if(debug)
   {
      printf("DEBUG> Region statististics for %-g pixels around (%-g,%-g) [%d,%d] [Equatorial (%-g, %-g)\n",
            rpix, xpix, ypix, ixpix, iypix, ra, dec);
      fflush(stdout);
   }


   // Then read the data

   jbegin = iypix - rpix - 1;
   jend   = iypix + rpix + 1;

   ibegin = ixpix - rpix - 1;
   iend   = ixpix + rpix + 1;

   if(ibegin < 1         ) ibegin = 1;
   if(iend   > wcs->nxpix) iend   = wcs->nxpix;

   nelements = iend - ibegin + 1;

   if(jbegin < 1         ) jbegin = 1;
   if(jend   > wcs->nypix) jend   = wcs->nxpix;

   fpixel[0] = ibegin;
   fpixel[1] = jbegin;
   fpixel[2] = 1;
   fpixel[3] = 1;
   fpixel[2] = plane3;
   fpixel[3] = plane4;


   data = (double *)malloc(nelements * sizeof(double));

   status = 0;

   sumflux  = 0.;
   sumflux2 = 0.;
   npix     = 0;
   nnull    = 0;

   val      = 0.;
   valx     = 0.;
   valy     = 0.;
   valra    = 0.;
   valdec   = 0.;

   max      = 0.;
   maxx     = 0.;
   maxy     = 0.;
   maxra    = 0.;
   maxdec   = 0.;

   min      = 0.;
   minx     = 0.;
   miny     = 0.;
   minra    = 0.;
   mindec   = 0.;

   first = 1;

   if(radius > 0.)
   {
      if(debug)
      {
         printf("\nDEBUG> Location: (%.6f %.6f) -> (%d,%d)\n\n", xpix, ypix, ixpix, iypix);
         printf("DEBUG> Radius: %.6f\n\n", rpix);

         printf("DEBUG> i: %d to %d\n", ibegin, iend);
         printf("DEBUG> j: %d to %d\n", jbegin, jend);
      }

      for (j=jbegin; j<=jend; ++j)
      {
         status = 0;
         if(fits_read_pix(fptr, TDOUBLE, fpixel, nelements, &nan,
                  (void *)data, &nullcnt, &status))
         {
            ++fpixel[1];

            continue;
         }

         for(i=0; i<nelements; ++i)
         {
            if(mNaN(data[i]))
            {
               if(debug)
                  printf("%10s ", "NULL");

               ++nnull;
               continue;
            }

            sumflux  += data[i];
            sumflux2 += data[i]*data[i];
            ++npix;

            x  = ibegin + i;
            y  = j;

            pix2wcs(wcs, x, y, &lon, &lat);

            convertCoordinates(csys, equinox, lon, lat, EQUJ, 2000., &ra, &dec, 0.);

            xp = cos(ra*dtr) * cos(dec*dtr);
            yp = sin(ra*dtr) * cos(dec*dtr);
            zp = sin(dec*dtr);

            dot = xp*x0 + yp*y0 + zp*z0;

            if(dot > 1.)
               dot = 1.;

            r = acos(dot)/dtr / fabs(cdelt2);

            if(debug)
            {
               if(r <= rpix)
                  printf("%10.3f ", data[i]);
               else
                  printf("%10s ", ".");
            }

            if(r > rpix)
               continue;


            if(x == ixpix && y == iypix)
            {
               val = data[i];

               valx = x;
               valy = y;
            }

            if(first)
            {
               first = 0;

               min = data[i];

               minx = x;
               miny = y;

               max = data[i];

               maxx = x;
               maxy = y;

               maxi = i+ibegin;
               maxj = j;
            }

            if(data[i] > max)
            {
               max = data[i];

               maxx = x;
               maxy = y;

               maxi = i+ibegin;
               maxj = j;
            }

            if(data[i] < min)
            {
               min = data[i];

               minx = x;
               miny = y;
            }
         }

         pix2wcs(wcs, valx, valy, &lon, &lat);
         convertCoordinates(csys, equinox, lon, lat, EQUJ, 2000., &valra, &valdec, 0.);

         pix2wcs(wcs, minx, miny, &lon, &lat);
         convertCoordinates(csys, equinox, lon, lat, EQUJ, 2000., &minra, &mindec, 0.);

         pix2wcs(wcs, maxx, maxy, &lon, &lat);
         convertCoordinates(csys, equinox, lon, lat, EQUJ, 2000., &maxra, &maxdec, 0.);

         if(debug)
            printf("\n");

         ++fpixel[1];
      }

      mean     = 0.;
      rms      = 0.;
      sigmaref = 0.;
      sigmamin = 0.;
      sigmamax = 0.;

      if(npix > 0)
      {
         mean = sumflux / npix;
         rms  = sqrt(sumflux2/npix - mean*mean);

         sigmaref = (val - mean) / rms; 
         sigmamin = (min - mean) / rms; 
         sigmamax = (max - mean) / rms; 
      }
   }
   

   /* Finally, print out parameters */

   strcpy(montage_json,  "{");
   strcpy(montage_msgstr,  "");


   if(areaMode == ALL || areaMode == REGION)
   {
      sprintf(tmpstr, "\"proj\":\"%s\",",   proj);                   strcat(montage_json, tmpstr);
      sprintf(tmpstr, " \"csys\":\"%s\",",   csys_str);              strcat(montage_json, tmpstr);
      sprintf(tmpstr, " \"equinox\":%.1f,",  equinox);               strcat(montage_json, tmpstr);
      sprintf(tmpstr, " \"naxis\":%ld,",     naxis);                 strcat(montage_json, tmpstr);
      sprintf(tmpstr, " \"naxis1\":%d,",     (int)naxis1);           strcat(montage_json, tmpstr);
      sprintf(tmpstr, " \"naxis2\":%d,",     (int)naxis2);           strcat(montage_json, tmpstr);

      if(naxis > 2)
      {
         sprintf(tmpstr, " \"naxis3\":%ld,", naxes[2]);              strcat(montage_json, tmpstr);
      }

      if(naxis > 3)
      {
         sprintf(tmpstr, " \"naxis4\":%ld,", naxes[3]);              strcat(montage_json, tmpstr);
      }

      sprintf(tmpstr, " \"crval1\":%.7f,",   crval1);                strcat(montage_json, tmpstr);
      sprintf(tmpstr, " \"crval2\":%.7f,",   crval2);                strcat(montage_json, tmpstr);
      sprintf(tmpstr, " \"crpix1\":%-g,",    crpix1);                strcat(montage_json, tmpstr);
      sprintf(tmpstr, " \"crpix2\":%-g,",    crpix2);                strcat(montage_json, tmpstr);
      sprintf(tmpstr, " \"cdelt1\":%.7f,",   cdelt1);                strcat(montage_json, tmpstr);
      sprintf(tmpstr, " \"cdelt2\":%.7f,",   cdelt2);                strcat(montage_json, tmpstr);
      sprintf(tmpstr, " \"crota2\":%.4f,",   crota2);                strcat(montage_json, tmpstr);
      sprintf(tmpstr, " \"lonc\":%.7f,",     lonc);                  strcat(montage_json, tmpstr);
      sprintf(tmpstr, " \"latc\":%.7f,",     latc);                  strcat(montage_json, tmpstr);
      sprintf(tmpstr, " \"ximgsize\":%.6f,", fabs(naxis1*cdelt1));   strcat(montage_json, tmpstr);
      sprintf(tmpstr, " \"yimgsize\":%.6f,", fabs(naxis1*cdelt2));   strcat(montage_json, tmpstr);
      sprintf(tmpstr, " \"rotequ\":%.4f,",   rot);                   strcat(montage_json, tmpstr);
      sprintf(tmpstr, " \"rac\":%.7f,",      rac);                   strcat(montage_json, tmpstr);
      sprintf(tmpstr, " \"decc\":%.7f,",     decc);                  strcat(montage_json, tmpstr);
      sprintf(tmpstr, " \"ra1\":%.7f,",      ra1);                   strcat(montage_json, tmpstr);
      sprintf(tmpstr, " \"dec1\":%.7f,",     dec1);                  strcat(montage_json, tmpstr);
      sprintf(tmpstr, " \"ra2\":%.7f,",      ra2);                   strcat(montage_json, tmpstr);
      sprintf(tmpstr, " \"dec2\":%.7f,",     dec2);                  strcat(montage_json, tmpstr);
      sprintf(tmpstr, " \"ra3\":%.7f,",      ra3);                   strcat(montage_json, tmpstr);
      sprintf(tmpstr, " \"dec3\":%.7f,",     dec3);                  strcat(montage_json, tmpstr);
      sprintf(tmpstr, " \"ra4\":%.7f,",      ra4);                   strcat(montage_json, tmpstr);
      sprintf(tmpstr, " \"dec4\":%.7f,",     dec4);                  strcat(montage_json, tmpstr);
      sprintf(tmpstr, " \"radius\":%.7f,",   radius);                strcat(montage_json, tmpstr);
      sprintf(tmpstr, " \"radpix\":%.2f,",   rpix);                  strcat(montage_json, tmpstr);
      sprintf(tmpstr, " \"npixel\":%d,",     npix);                  strcat(montage_json, tmpstr);
      sprintf(tmpstr, " \"nnull\":%d,",      nnull);                 strcat(montage_json, tmpstr);
      sprintf(tmpstr, " \"aveflux\":%-g,",   mean);                  strcat(montage_json, tmpstr);
      sprintf(tmpstr, " \"rmsflux\":%-g,",   rms);                   strcat(montage_json, tmpstr);
      sprintf(tmpstr, " \"fluxref\":%-g,",   val);                   strcat(montage_json, tmpstr);
      sprintf(tmpstr, " \"sigmaref\":%-g,",  sigmaref);              strcat(montage_json, tmpstr);
      sprintf(tmpstr, " \"xref\":%.0f,",     valx);                  strcat(montage_json, tmpstr);
      sprintf(tmpstr, " \"yref\":%.0f,",     valy);                  strcat(montage_json, tmpstr);
      sprintf(tmpstr, " \"raref\":%.7f,",    valra);                 strcat(montage_json, tmpstr);
      sprintf(tmpstr, " \"decref\":%.7f,",   valdec);                strcat(montage_json, tmpstr);
      sprintf(tmpstr, " \"fluxmin\":%-g,",   min);                   strcat(montage_json, tmpstr);
      sprintf(tmpstr, " \"sigmamin\":%-g,",  sigmamin);              strcat(montage_json, tmpstr);
      sprintf(tmpstr, " \"xmin\":%.0f,",     minx);                  strcat(montage_json, tmpstr);
      sprintf(tmpstr, " \"ymin\":%.0f,",     miny);                  strcat(montage_json, tmpstr);
      sprintf(tmpstr, " \"ramin\":%.7f,",    minra);                 strcat(montage_json, tmpstr);
      sprintf(tmpstr, " \"decmin\":%.7f,",   mindec);                strcat(montage_json, tmpstr);
      sprintf(tmpstr, " \"fluxmax\":%-g,",   max);                   strcat(montage_json, tmpstr);
      sprintf(tmpstr, " \"sigmamax\":%-g,",  sigmamax);              strcat(montage_json, tmpstr);
      sprintf(tmpstr, " \"xmax\":%.0f,",     maxx);                  strcat(montage_json, tmpstr);
      sprintf(tmpstr, " \"ymax\":%.0f,",     maxy);                  strcat(montage_json, tmpstr);
      sprintf(tmpstr, " \"ramax\":%.7f,",    maxra);                 strcat(montage_json, tmpstr);
      sprintf(tmpstr, " \"decmax\":%.7f",    maxdec);                strcat(montage_json, tmpstr);
   

      sprintf(tmpstr, "proj=\"%s\",",   proj);                   strcat(montage_msgstr, tmpstr);
      sprintf(tmpstr, " csys=\"%s\",",   csys_str);              strcat(montage_msgstr, tmpstr);
      sprintf(tmpstr, " equinox=%.1f,",  equinox);               strcat(montage_msgstr, tmpstr);
      sprintf(tmpstr, " naxis=%ld,",     naxis);                 strcat(montage_msgstr, tmpstr);
      sprintf(tmpstr, " naxis1=%d,",     (int)naxis1);           strcat(montage_msgstr, tmpstr);
      sprintf(tmpstr, " naxis2=%d,",     (int)naxis2);           strcat(montage_msgstr, tmpstr);

      if(naxis > 2)
      {
         sprintf(tmpstr, " naxis3=%ld,", naxes[2]);              strcat(montage_msgstr, tmpstr);
      }

      if(naxis > 3)
      {
         sprintf(tmpstr, " naxis4=%ld,", naxes[3]);              strcat(montage_msgstr, tmpstr);
      }

      sprintf(tmpstr, " crval1=%.7f,",   crval1);                strcat(montage_msgstr, tmpstr);
      sprintf(tmpstr, " crval2=%.7f,",   crval2);                strcat(montage_msgstr, tmpstr);
      sprintf(tmpstr, " crpix1=%-g,",    crpix1);                strcat(montage_msgstr, tmpstr);
      sprintf(tmpstr, " crpix2=%-g,",    crpix2);                strcat(montage_msgstr, tmpstr);
      sprintf(tmpstr, " cdelt1=%.7f,",   cdelt1);                strcat(montage_msgstr, tmpstr);
      sprintf(tmpstr, " cdelt2=%.7f,",   cdelt2);                strcat(montage_msgstr, tmpstr);
      sprintf(tmpstr, " crota2=%.4f,",   crota2);                strcat(montage_msgstr, tmpstr);
      sprintf(tmpstr, " lonc=%.7f,",     lonc);                  strcat(montage_msgstr, tmpstr);
      sprintf(tmpstr, " latc=%.7f,",     latc);                  strcat(montage_msgstr, tmpstr);
      sprintf(tmpstr, " ximgsize=%.6f,", fabs(naxis1*cdelt1));   strcat(montage_msgstr, tmpstr);
      sprintf(tmpstr, " yimgsize=%.6f,", fabs(naxis1*cdelt2));   strcat(montage_msgstr, tmpstr);
      sprintf(tmpstr, " rotequ=%.4f,",   rot);                   strcat(montage_msgstr, tmpstr);
      sprintf(tmpstr, " rac=%.7f,",      rac);                   strcat(montage_msgstr, tmpstr);
      sprintf(tmpstr, " decc=%.7f,",     decc);                  strcat(montage_msgstr, tmpstr);
      sprintf(tmpstr, " ra1=%.7f,",      ra1);                   strcat(montage_msgstr, tmpstr);
      sprintf(tmpstr, " dec1=%.7f,",     dec1);                  strcat(montage_msgstr, tmpstr);
      sprintf(tmpstr, " ra2=%.7f,",      ra2);                   strcat(montage_msgstr, tmpstr);
      sprintf(tmpstr, " dec2=%.7f,",     dec2);                  strcat(montage_msgstr, tmpstr);
      sprintf(tmpstr, " ra3=%.7f,",      ra3);                   strcat(montage_msgstr, tmpstr);
      sprintf(tmpstr, " dec3=%.7f,",     dec3);                  strcat(montage_msgstr, tmpstr);
      sprintf(tmpstr, " ra4=%.7f,",      ra4);                   strcat(montage_msgstr, tmpstr);
      sprintf(tmpstr, " dec4=%.7f,",     dec4);                  strcat(montage_msgstr, tmpstr);
      sprintf(tmpstr, " radius=%.7f,",   radius);                strcat(montage_msgstr, tmpstr);
      sprintf(tmpstr, " radpix=%.2f,",   rpix);                  strcat(montage_msgstr, tmpstr);
      sprintf(tmpstr, " npixel=%d,",     npix);                  strcat(montage_msgstr, tmpstr);
      sprintf(tmpstr, " nnull=%d,",      nnull);                 strcat(montage_msgstr, tmpstr);
      sprintf(tmpstr, " aveflux=%-g,",   mean);                  strcat(montage_msgstr, tmpstr);
      sprintf(tmpstr, " rmsflux=%-g,",   rms);                   strcat(montage_msgstr, tmpstr);
      sprintf(tmpstr, " fluxref=%-g,",   val);                   strcat(montage_msgstr, tmpstr);
      sprintf(tmpstr, " sigmaref=%-g,",  sigmaref);              strcat(montage_msgstr, tmpstr);
      sprintf(tmpstr, " xref=%.0f,",     valx);                  strcat(montage_msgstr, tmpstr);
      sprintf(tmpstr, " yref=%.0f,",     valy);                  strcat(montage_msgstr, tmpstr);
      sprintf(tmpstr, " raref=%.7f,",    valra);                 strcat(montage_msgstr, tmpstr);
      sprintf(tmpstr, " decref=%.7f,",   valdec);                strcat(montage_msgstr, tmpstr);
      sprintf(tmpstr, " fluxmin=%-g,",   min);                   strcat(montage_msgstr, tmpstr);
      sprintf(tmpstr, " sigmamin=%-g,",  sigmamin);              strcat(montage_msgstr, tmpstr);
      sprintf(tmpstr, " xmin=%.0f,",     minx);                  strcat(montage_msgstr, tmpstr);
      sprintf(tmpstr, " ymin=%.0f,",     miny);                  strcat(montage_msgstr, tmpstr);
      sprintf(tmpstr, " ramin=%.7f,",    minra);                 strcat(montage_msgstr, tmpstr);
      sprintf(tmpstr, " decmin=%.7f,",   mindec);                strcat(montage_msgstr, tmpstr);
      sprintf(tmpstr, " fluxmax=%-g,",   max);                   strcat(montage_msgstr, tmpstr);
      sprintf(tmpstr, " sigmamax=%-g,",  sigmamax);              strcat(montage_msgstr, tmpstr);
      sprintf(tmpstr, " xmax=%.0f,",     maxx);                  strcat(montage_msgstr, tmpstr);
      sprintf(tmpstr, " ymax=%.0f,",     maxy);                  strcat(montage_msgstr, tmpstr);
      sprintf(tmpstr, " ramax=%.7f,",    maxra);                 strcat(montage_msgstr, tmpstr);
      sprintf(tmpstr, " decmax=%.7f",    maxdec);                strcat(montage_msgstr, tmpstr);
   }
   
   else if(areaMode == APPHOT)
   {
      // For aperture photometry mode we process the flux vs. radius data
      // to get the integrated source flux. 

      rap = radius;

      jbegin = maxj - rap - 1;
      jend   = maxj + rap + 1;

      ibegin = maxi - rap - 1;
      iend   = maxi + rap + 1;

      nelements = iend - ibegin + 1;

      fpixel[0] = ibegin;
      fpixel[1] = jbegin;
      fpixel[2] = 1;
      fpixel[3] = 1;

      for (j=jbegin; j<=jend; ++j)
      {
         status = 0;
         if(fits_read_pix(fptr, TDOUBLE, fpixel, nelements, &nan,
                          (void *)data, &nullcnt, &status))
         {
            if(ap) free(ap);
            free(data);
            sprintf(returnStruct->msg, "Error reading FITS data.");
            return returnStruct;
         }

         for(i=0; i<nelements; ++i)
         {
            if(mNaN(data[i]))
               continue;

            r = sqrt(((double)i+ibegin-maxi)*((double)i+ibegin-maxi) + ((double)j-maxj)*((double)j-maxj));

            if(r > rap)
               continue;

            ap[nflux].rad  = r;
            ap[nflux].flux = data[i];
            ap[nflux].fit  = 0.;

            ++nflux;
            if(nflux >= maxflux)
            {
               maxflux += MAXFLUX;

               ap = (struct apPhoto *)realloc(ap, maxflux * sizeof(struct apPhoto));
            }
         }

         ++fpixel[1];
      }


      // Sort the data by radius

      qsort(ap, (size_t)nflux, sizeof(struct apPhoto), mExamine_radCompare);


      // Find the peak flux and the minimum flux.

      // The max is constrained to be in the first quarter of the
      // data, just to be careful.

      fluxMax = -1.e99;
      fluxMin =  1.e99;

      for(i=0; i<nflux; ++i)
      {
         if(i < nflux/4 && ap[i].flux > fluxMax)
            fluxMax = ap[i].flux;

         if(ap[i].flux < fluxMin)
            fluxMin = ap[i].flux;
      }


      // Fit the minimum a little more carefully, iterating
      // and excluding points more than 3 sigma above the 
      // minimum.

      background = fluxMin;
      sigma      = fluxMax - fluxMin;

      for(j=0; j<1000; ++j)
      {
         oldbackground = background;

         sumn     = 0.;
         sumflux  = 0.;
         sumflux2 = 0.;

         for(i=0; i<nflux; ++i)
         {
            if(fabs(ap[i].flux - background) > 3.*sigma)
               continue;

            sumn     += 1.;
            sumflux  += ap[i].flux;
            sumflux2 += ap[i].flux * ap[i].flux;
         }

         background = sumflux / sumn;
         sigma      = sqrt(sumflux2/sumn - background*background);

         if(fabs((background - oldbackground) / oldbackground) < 1.e-3)
            break;
      }


      fluxRef = (fluxMax-fluxMin) / exp(1.);

      for(i=0; i<nflux; ++i)
      {
         if(ap[i].flux < fluxRef)
         {
            sigma = ap[i].rad;
            break;
         }
      }

      for(i=0; i<nflux; ++i)
      {
         ap[i].fit = (fluxMax-background) * exp(-(ap[i].rad * ap[i].rad) / (sigma * sigma)) + background;

         if(i == 0)
            ap[i].sum = ap[i].flux - background;
         else
            ap[i].sum = ap[i-1].sum + (ap[i].flux - background);
      }


      if(debug)
      {
         printf("|    rad    |    flux    |     fit     |     sum     |\n");
         fflush(stdout);

         for(i=0; i<nflux; ++i)
         {
            printf("%12.6f %12.6f %12.6f %12.6f  \n", ap[i].rad, ap[i].flux, ap[i].fit, ap[i].sum);
            fflush(stdout);
         }
      }

      sprintf(tmpstr, "\"proj\":\"%s\",",    proj);                 strcat(montage_json, tmpstr);
      sprintf(tmpstr, " \"csys\":\"%s\",",    csys_str);            strcat(montage_json, tmpstr);
      sprintf(tmpstr, " \"equinox\":%.1f,",   equinox);             strcat(montage_json, tmpstr);
      sprintf(tmpstr, " \"naxis\":%ld,",      naxis);               strcat(montage_json, tmpstr);
      sprintf(tmpstr, " \"naxis1\":%d,",      (int)naxis1);         strcat(montage_json, tmpstr);
      sprintf(tmpstr, " \"naxis2\":%d,",      (int)naxis2);         strcat(montage_json, tmpstr);

      if(naxis > 2)
      {
         sprintf(tmpstr, " \"naxis3\":%ld,",   naxes[2]);           strcat(montage_json, tmpstr);
      }

      if(naxis > 3)
      {
         sprintf(tmpstr, " \"naxis4\":%ld,",   naxes[3]);           strcat(montage_json, tmpstr);
      }

      sprintf(tmpstr, " \"crval1\":%.7f,",    crval1);              strcat(montage_json, tmpstr);
      sprintf(tmpstr, " \"crval2\":%.7f,",    crval2);              strcat(montage_json, tmpstr);
      sprintf(tmpstr, " \"crpix1\":%-g,",     crpix1);              strcat(montage_json, tmpstr);
      sprintf(tmpstr, " \"crpix2\":%-g,",     crpix2);              strcat(montage_json, tmpstr);
      sprintf(tmpstr, " \"cdelt1\":%.7f,",    cdelt1);              strcat(montage_json, tmpstr);
      sprintf(tmpstr, " \"cdelt2\":%.7f,",    cdelt2);              strcat(montage_json, tmpstr);
      sprintf(tmpstr, " \"crota2\":%.4f,",    crota2);              strcat(montage_json, tmpstr);
      sprintf(tmpstr, " \"lonc\":%.7f,",      lonc);                strcat(montage_json, tmpstr);
      sprintf(tmpstr, " \"latc\":%.7f,",      latc);                strcat(montage_json, tmpstr);
      sprintf(tmpstr, " \"ximgsize\":%.6f,",  fabs(naxis1*cdelt1)); strcat(montage_json, tmpstr);
      sprintf(tmpstr, " \"yimgsize\":%.6f,",  fabs(naxis1*cdelt2)); strcat(montage_json, tmpstr);
      sprintf(tmpstr, " \"rotequ\":%.4f,",    rot);                 strcat(montage_json, tmpstr);
      sprintf(tmpstr, " \"rac\":%.7f,",       rac);                 strcat(montage_json, tmpstr);
      sprintf(tmpstr, " \"decc\":%.7f,",      decc);                strcat(montage_json, tmpstr);
      sprintf(tmpstr, " \"ra1\":%.7f,",       ra1);                 strcat(montage_json, tmpstr);
      sprintf(tmpstr, " \"dec1\":%.7f,",      dec1);                strcat(montage_json, tmpstr);
      sprintf(tmpstr, " \"ra2\":%.7f,",       ra2);                 strcat(montage_json, tmpstr);
      sprintf(tmpstr, " \"dec2\":%.7f,",      dec2);                strcat(montage_json, tmpstr);
      sprintf(tmpstr, " \"ra3\":%.7f,",       ra3);                 strcat(montage_json, tmpstr);
      sprintf(tmpstr, " \"dec3\":%.7f,",      dec3);                strcat(montage_json, tmpstr);
      sprintf(tmpstr, " \"ra4\":%.7f,",       ra4);                 strcat(montage_json, tmpstr);
      sprintf(tmpstr, " \"dec4\":%.7f,",      dec4);                strcat(montage_json, tmpstr);
      sprintf(tmpstr, " \"totalflux\":%.7e",  ap[nflux/2].sum);     strcat(montage_json, tmpstr);

      sprintf(tmpstr, "proj=\"%s\",",    proj);                 strcat(montage_msgstr, tmpstr);
      sprintf(tmpstr, " csys=\"%s\",",    csys_str);            strcat(montage_msgstr, tmpstr);
      sprintf(tmpstr, " equinox=%.1f,",   equinox);             strcat(montage_msgstr, tmpstr);
      sprintf(tmpstr, " naxis=%ld,",      naxis);               strcat(montage_msgstr, tmpstr);
      sprintf(tmpstr, " naxis1=%d,",      (int)naxis1);         strcat(montage_msgstr, tmpstr);
      sprintf(tmpstr, " naxis2=%d,",      (int)naxis2);         strcat(montage_msgstr, tmpstr);

      if(naxis > 2)
      {
         sprintf(tmpstr, " naxis3=%ld,",   naxes[2]);           strcat(montage_msgstr, tmpstr);
      }

      if(naxis > 3)
      {
         sprintf(tmpstr, " naxis4=%ld,",   naxes[3]);           strcat(montage_msgstr, tmpstr);
      }

      sprintf(tmpstr, " crval1=%.7f,",    crval1);              strcat(montage_msgstr, tmpstr);
      sprintf(tmpstr, " crval2=%.7f,",    crval2);              strcat(montage_msgstr, tmpstr);
      sprintf(tmpstr, " crpix1=%-g,",     crpix1);              strcat(montage_msgstr, tmpstr);
      sprintf(tmpstr, " crpix2=%-g,",     crpix2);              strcat(montage_msgstr, tmpstr);
      sprintf(tmpstr, " cdelt1=%.7f,",    cdelt1);              strcat(montage_msgstr, tmpstr);
      sprintf(tmpstr, " cdelt2=%.7f,",    cdelt2);              strcat(montage_msgstr, tmpstr);
      sprintf(tmpstr, " crota2=%.4f,",    crota2);              strcat(montage_msgstr, tmpstr);
      sprintf(tmpstr, " lonc=%.7f,",      lonc);                strcat(montage_msgstr, tmpstr);
      sprintf(tmpstr, " latc=%.7f,",      latc);                strcat(montage_msgstr, tmpstr);
      sprintf(tmpstr, " ximgsize=%.6f,",  fabs(naxis1*cdelt1)); strcat(montage_msgstr, tmpstr);
      sprintf(tmpstr, " yimgsize=%.6f,",  fabs(naxis1*cdelt2)); strcat(montage_msgstr, tmpstr);
      sprintf(tmpstr, " rotequ=%.4f,",    rot);                 strcat(montage_msgstr, tmpstr);
      sprintf(tmpstr, " rac=%.7f,",       rac);                 strcat(montage_msgstr, tmpstr);
      sprintf(tmpstr, " decc=%.7f,",      decc);                strcat(montage_msgstr, tmpstr);
      sprintf(tmpstr, " ra1=%.7f,",       ra1);                 strcat(montage_msgstr, tmpstr);
      sprintf(tmpstr, " dec1=%.7f,",      dec1);                strcat(montage_msgstr, tmpstr);
      sprintf(tmpstr, " ra2=%.7f,",       ra2);                 strcat(montage_msgstr, tmpstr);
      sprintf(tmpstr, " dec2=%.7f,",      dec2);                strcat(montage_msgstr, tmpstr);
      sprintf(tmpstr, " ra3=%.7f,",       ra3);                 strcat(montage_msgstr, tmpstr);
      sprintf(tmpstr, " dec3=%.7f,",      dec3);                strcat(montage_msgstr, tmpstr);
      sprintf(tmpstr, " ra4=%.7f,",       ra4);                 strcat(montage_msgstr, tmpstr);
      sprintf(tmpstr, " dec4=%.7f,",      dec4);                strcat(montage_msgstr, tmpstr);
      sprintf(tmpstr, " totalflux=%.7e",  ap[nflux/2].sum);     strcat(montage_msgstr, tmpstr);
   }

   strcat(montage_json, "}");

   if(ap) free(ap);
   free(data);

   returnStruct->status = 0;

   strcpy(returnStruct->msg,  montage_msgstr);
   strcpy(returnStruct->json, montage_json);
   strcpy(returnStruct->proj, proj);
   strcpy(returnStruct->csys, csys_str);

   returnStruct->equinox   = equinox;
   returnStruct->naxis     = naxis;
   returnStruct->naxis1    = naxis1;
   returnStruct->naxis2    = naxis2;
   returnStruct->naxis3    = naxes[2];
   returnStruct->naxis4    = naxes[3];
   returnStruct->crval1    = crval1;
   returnStruct->crval2    = crval2;
   returnStruct->crpix1    = crpix1;
   returnStruct->crpix2    = crpix2;
   returnStruct->cdelt1    = cdelt1;
   returnStruct->cdelt2    = cdelt2;
   returnStruct->crota2    = crota2;
   returnStruct->lonc      = lonc;
   returnStruct->latc      = latc;
   returnStruct->ximgsize  = fabs(naxis1*cdelt1);
   returnStruct->yimgsize  = fabs(naxis2*cdelt2);
   returnStruct->rotequ    = rot;
   returnStruct->rac       = rac;
   returnStruct->decc      = decc;
   returnStruct->ra1       = ra1;
   returnStruct->dec1      = dec1;
   returnStruct->ra2       = ra2;
   returnStruct->dec2      = dec2;
   returnStruct->ra3       = ra3;
   returnStruct->dec3      = dec3;
   returnStruct->ra4       = ra4;
   returnStruct->dec4      = dec4;
   returnStruct->radius    = radius;
   returnStruct->radpix    = rpix;
   returnStruct->npixel    = npix;
   returnStruct->nnull     = nnull;
   returnStruct->aveflux   = mean;
   returnStruct->rmsflux   = rms;
   returnStruct->fluxref   = val;
   returnStruct->sigmaref  = sigmaref;
   returnStruct->xref      = valx;
   returnStruct->yref      = valy;
   returnStruct->raref     = valra;
   returnStruct->decref    = valdec;
   returnStruct->fluxmin   = min;
   returnStruct->sigmamin  = sigmamin;
   returnStruct->xmin      = minx;
   returnStruct->ymin      = miny;
   returnStruct->ramin     = minra;
   returnStruct->decmin    = mindec;
   returnStruct->fluxmax   = max;
   returnStruct->sigmamax  = sigmamax;
   returnStruct->xmax      = maxx;
   returnStruct->ymax      = maxy;
   returnStruct->ramax     = maxra;
   returnStruct->decmax    = maxdec;

   if(areaMode == APPHOT)
      returnStruct->totalflux = ap[nflux/2].sum;
   else
      returnStruct->totalflux = 0.;

   return returnStruct;
}
Esempio n. 6
0
int create_input()

{
  const double TWOPI = 2.0 * 3.14159265358979323846;

  /* These must match wcstab.keyrec. */
  const char infile[] = "test/wcstab.keyrec";
  const long NAXIS1 = 256;
  const long NAXIS2 = 128;
  const long NAXIS3 =   4;
  const char *ttype1[3] = {"CelCoords", "RAIndex", "DecIndex"};
  const char *tform1[3] = {"5600E", "70E", "40E"};
  const char *tunit1[3] = {"deg", "", ""};
  const char *ttype2[4] = {"WaveIndex", "WaveCoord",
                           "TimeIndex", "TimeCoord"};
  const char *tform2[4] = {"8E", "8D", "8E", "8D"};
  const char *tunit2[4] = {"", "m", "", "a"};

  /* The remaining parameters may be chosen at will. */
  float  refval[] = {150.0f, -30.0f};
  float  span[]   = {5.0f, (5.0f*K2)/K1};
  float  sigma[]  = {0.10f, 0.05f};
  double wcoord[] = {0.21106114, 0.21076437, 2.0e-6, 2.2e-6,
                     500.0e-9, 650.0e-9, 1.24e-9, 2.48e-9};
  double windex[] = {0.5, 1.5, 1.5, 2.5, 2.5, 3.5, 3.5, 4.5};
  double tcoord[] = {1997.84512, 1997.84631, 1993.28451, 1993.28456,
                     2001.59234, 2001.59239, 2002.18265, 2002.18301};
  double tindex[] = {0.0, 1.0, 1.0, 2.0, 2.0, 3.0, 3.0, 4.0};

  char   keyrec[84];
  int    i, status;
  long   dummy, firstelem, k1, k2, p1, p2, p3;
  float  array[2*K1*K2], *fp, image[256];
  double s, t, x1, x2, z, z1, z2;
  FILE   *stream;
  fitsfile *fptr;

  /* Look for the input header keyrecords. */
  if ((stream = fopen(infile+5, "r")) == 0x0) {
    if ((stream = fopen(infile, "r")) == 0x0) {
      printf("ERROR opening %s\n", infile);
      return 1;
    }
  }

  /* Create the FITS output file, deleting any pre-existing file. */
  status = 0;
  fits_create_file(&fptr, "!wcstab.fits", &status);

  /* Convert header keyrecords to FITS. */
  while (fgets(keyrec, 82, stream) != NULL) {
    /* Ignore meta-comments (copyright information, etc.). */
    if (keyrec[0] == '#') continue;

    /* Strip off the newline. */
    i = strlen(keyrec) - 1;
    if (keyrec[i] == '\n') keyrec[i] = '\0';

    fits_write_record(fptr, keyrec, &status);
  }
  fclose(stream);

  /* Create and write some phoney image data. */
  firstelem = 1;
  for (p3 = 0; p3 < NAXIS3; p3++) {
    for (p2 = 0; p2 < NAXIS2; p2++) {
      fp = image;
      s = (p3 + 1) * cos(0.2 * p2);
      t = cos(0.8*p2);
      for (p1 = 0; p1 < NAXIS1; p1++) {
        /* Do not adjust your set! */
        *(fp++) = sin(0.1*(p1+p2) + s) * cos(0.4*p1) * t;
      }

      fits_write_img_flt(fptr, 0L, firstelem, NAXIS1, image, &status);
      firstelem += NAXIS1;
    }
  }


  /* Add the first binary table extension. */
  fits_create_tbl(fptr, BINARY_TBL, 1L, 3L, (char **)ttype1, (char **)tform1,
     (char **)tunit1, NULL, &status);

  /* Write EXTNAME and EXTVER near the top, after TFIELDS. */
  fits_read_key_lng(fptr, "TFIELDS", &dummy, NULL, &status);
  fits_insert_key_str(fptr, "EXTNAME", "WCS-TABLE",
    "WCS Coordinate lookup table", &status);
  fits_insert_key_lng(fptr, "EXTVER", 1L, "Table number 1", &status);

  /* Write the TDIM1 keyrecord after TFORM1. */
  fits_read_key_str(fptr, "TFORM1", keyrec, NULL, &status);
  sprintf(keyrec, "(2,%ld,%ld)", K1, K2);
  fits_insert_key_str(fptr, "TDIM1", keyrec, "Dimensions of 3-D array",
    &status);

  /* Plate carrée projection with a bit of noise for the sake of realism. */
  fp = array;
  for (k2 = 0; k2 < K2; k2++) {
    for (k1 = 0; k1 < K1; k1++) {
      /* Box-Muller transformation: uniform -> normal distribution. */
      x1 = lcprng();
      x2 = lcprng();
      if (x1 == 0.0) x1 = 1.0;
      z  = sqrt(-2.0 * log(x1));
      x2 *= TWOPI;
      z1 = z * cos(x2);
      z2 = z * sin(x2);

      *(fp++) = refval[0] + span[0] * (k1/(K1-1.0) - 0.5) + z1 * sigma[0];
      *(fp++) = refval[1] + span[1] * (k2/(K2-1.0) - 0.5) + z2 * sigma[1];
    }
  }
  fits_write_col_flt(fptr, 1, 1L, 1L, 2*K1*K2, array, &status);

  fp = array;
  for (k1 = 0; k1 < K1; k1++) {
    *(fp++) = 4.0f * k1;
  }
  fits_write_col_flt(fptr, 2, 1L, 1L, K1, array, &status);

  fp = array;
  for (k2 = 0; k2 < K2; k2++) {
    *(fp++) = 4.0f * k2;
  }
  fits_write_col_flt(fptr, 3, 1L, 1L, K2, array, &status);


  /* Add the second binary table extension. */
  if (fits_create_tbl(fptr, BINARY_TBL, 1L, 4L, (char **)ttype2,
     (char **)tform2, (char **)tunit2, NULL, &status)) {
    fits_report_error(stderr, status);
    return 1;
  }

  /* Write EXTNAME and EXTVER near the top, after TFIELDS. */
  fits_read_key_lng(fptr, "TFIELDS", &dummy, NULL, &status);
  fits_insert_key_str(fptr, "EXTNAME", "WCS-TABLE",
    "WCS Coordinate lookup table", &status);
  fits_insert_key_lng(fptr, "EXTVER", 2L, "Table number 2", &status);

  /* Write the TDIM2 keyrecord after TFORM2. */
  fits_read_key_str(fptr, "TFORM2", keyrec, NULL, &status);
  fits_insert_key_str(fptr, "TDIM2", "(1,8)", "Dimensions of 2-D array",
    &status);

  /* Write the TDIM4 keyrecord after TFORM4. */
  fits_read_key_str(fptr, "TFORM4", keyrec, NULL, &status);
  fits_insert_key_str(fptr, "TDIM4", "(1,8)", "Dimensions of 2-D array",
    &status);


  fits_write_col_dbl(fptr, 1, 1L, 1L, 8L, windex, &status);
  fits_write_col_dbl(fptr, 2, 1L, 1L, 8L, wcoord, &status);
  fits_write_col_dbl(fptr, 3, 1L, 1L, 8L, tindex, &status);
  fits_write_col_dbl(fptr, 4, 1L, 1L, 8L, tcoord, &status);

  fits_close_file(fptr, &status);

  if (status) {
    fits_report_error(stderr, status);
    return 1;
  }

  return 0;
}
Esempio n. 7
0
int HEALPixIn(struct healpix *hpxdat)

{
  char   crdsys[32], ordering[32];
  int    anynul, hdutype, iaxis, nfound, status;
  long   firstpix, ipix, lastpix, naxis, *naxes = 0x0, nside = 0, repeat;
  float  *datap, nulval;
  LONGLONG firstelem, irow, nelem, npix = 0, nrow = 0;
  fitsfile *fptr;

  status = 0;
  hpxdat->data = 0x0;

  /* Open the FITS file and move to the first HDU with NAXIS != 0. */
  if (fits_open_data(&fptr, hpxdat->infile, READONLY, &status)) goto fitserr;

  /* Is this the primary HDU or an extension? */
  if (fits_get_hdu_type(fptr, &hdutype, &status)) goto fitserr;
  if (!(hdutype == IMAGE_HDU || hdutype == BINARY_TBL)) {
    fprintf(stderr, "ERROR: %s does not contain HEALPix data.\n",
            hpxdat->infile);
    return 1;
  }


  /* Get the image size. */
  if (fits_read_key_lng(fptr, "NAXIS", &naxis, 0x0, &status)) goto fitserr;
  naxes = malloc(naxis*sizeof(long));
  if (fits_read_keys_lng(fptr, "NAXIS", 1, (int)naxis, naxes, &nfound,
                         &status)) goto fitserr;

  if (hdutype == IMAGE_HDU) {
    /* Look for the first non-degenerate image axis. */
    for (iaxis = 0; iaxis < nfound; iaxis++) {
      if (naxes[iaxis] > 1) {
        /* Assume for now that it is the total number of pixels. */
        npix = naxes[iaxis];
        break;
      }
    }

  } else if (hdutype == BINARY_TBL) {
    /* Binary tables are simpler. */
    if (nfound > 1) nrow = naxes[1];

    /* (Note that fits_get_coltypell() is not available in cfitsio 2.x.) */
    if (fits_get_coltype(fptr, hpxdat->col, 0x0, &repeat, 0x0, &status)) {
      goto fitserr;
    }
    nelem = (LONGLONG)repeat;
  }

  if (!npix && !nrow) {
    fprintf(stderr, "ERROR: Could not determine image size.\n");
    goto cleanup;
  }


  /* Number of pixels per side of each base-resolution pixel. */
  if (fits_read_key_lng(fptr, "NSIDE", &nside, 0x0, &status)) {
    /* Some HEALPix files, e.g. SFD dust maps, don't record NSIDE. */
    if (status != KEY_NO_EXIST) goto fitserr;
    status = 0;
  }

  /* FIRSTPIX and LASTPIX, if present, record the 0-relative pixel numbers of
   * the first and last pixels stored in the data. */
  firstpix = -1;
  if (fits_read_key_lng(fptr, "FIRSTPIX", &firstpix, 0x0, &status)) {
    if (status != KEY_NO_EXIST) goto fitserr;
    status = 0;
  }

  lastpix = -1;
  if (fits_read_key_lng(fptr, "LASTPIX", &lastpix, 0x0, &status)) {
    if (status != KEY_NO_EXIST) goto fitserr;
    status = 0;
  }

  if (!nside) {
    /* Deduce NSIDE. */
    if (lastpix >= 0) {
      /* If LASTPIX is present without NSIDE we can only assume it's npix. */
      nside = (int)(sqrt((double)((lastpix+1) / 12)) + 0.5);
    } else if (npix) {
      nside = (int)(sqrt((double)(npix / 12)) + 0.5);
    } else if (nrow) {
      nside = (int)(sqrt((double)((nrow * nelem) / 12)) + 0.5);
    }
  }

  hpxdat->nside = (int)nside;
  hpxdat->npix  = 12*nside*nside;

  /* Ensure that FIRSTPIX and LASTPIX are set. */
  if (firstpix < 0) firstpix = 0;
  if (lastpix  < 0) lastpix  = hpxdat->npix - 1;


  /* Any sign of a coordinate system identifier? */
  if (fits_read_key_str(fptr, "COORDSYS", crdsys, 0x0, &status)) {
    if (status != KEY_NO_EXIST) goto fitserr;
    status = 0;
  } else if (crdsys[0] == 'G') {
    hpxdat->crdsys = 'G';
  } else if (crdsys[0] == 'E') {
    hpxdat->crdsys = 'E';
  } else if (crdsys[0] == 'C') {
    /* ("celestial") */
    hpxdat->crdsys = 'Q';
  }

  /* Nested or ring ordering? */
  if (fits_read_key_str(fptr, "ORDERING", ordering, 0x0, &status)) {
    /* Some HEALPix files, e.g. SFD dust maps, don't record ORDERING. */
    if (status != KEY_NO_EXIST) goto fitserr;
    status = 0;

  } else if (strcmp(ordering, "NESTED") == 0) {
    hpxdat->ordering = 'N';

  } else if (strcmp(ordering, "RING") == 0) {
    hpxdat->ordering = 'R';

  } else {
    fprintf(stderr, "WARNING: Invalid ORDERING keyword: %s.\n", ordering);
  }


  /* Allocate memory and read the data. */
  if ((hpxdat->data = malloc((hpxdat->npix)*sizeof(float))) == NULL) {
    perror("HPXcvt");
    goto cleanup;
  }

  nulval = HEALPIX_NULLVAL;
  datap = hpxdat->data;
  for (ipix = 0; ipix < firstpix; ipix++) {
    *(datap++) = nulval;
  }

  firstelem = (LONGLONG)1;
  if (hdutype == IMAGE_HDU) {
    if (fits_read_img_flt(fptr, 0l, firstelem, npix, nulval, datap, &anynul,
        &status)) goto fitserr;

  } else if (hdutype == BINARY_TBL) {
    for (irow = 0; irow < nrow; irow++) {
      if (fits_read_col_flt(fptr, hpxdat->col, irow+1, firstelem, nelem,
          nulval, datap, &anynul, &status)) goto fitserr;
      datap += nelem;
    }
  }

  datap = hpxdat->data + (lastpix + 1);
  for (ipix = (lastpix+1); ipix < hpxdat->npix; ipix++) {
    *(datap++) = nulval;
  }

  /* Clean up. */
  fits_close_file(fptr, &status);
  status = 0;
  return 0;

fitserr:
  fits_report_error(stderr, status);
cleanup:
  if (naxes) free(naxes);
  if (hpxdat->data) free(hpxdat->data);
  hpxdat->data = 0x0;
  return 1;
}
Esempio n. 8
0
float *read_healpix_map(const char *infile, long *nside, char *coordsys, char *ordering) {
  
  /* Local Declarations */
  long     naxes, *naxis, npix, npercol, irow;
  int      status, hdutype, nfound, anynul;
  float    nulval, *map;
  char     comment[FLEN_COMMENT];
  fitsfile *fptr;

  /* Initializations */
  status = 0;

  /* Open the file */
  if ( fits_open_file(&fptr, infile, READONLY, &status) ) {
    printerror( status );
    return (float *)NULL;
  }

  /* Move to the HDU */
  if ( fits_movabs_hdu(fptr, 2, &hdutype, &status) ) {
    printerror( status );
    return (float *)NULL;
  }
  if (hdutype != BINARY_TBL) {
    fprintf(stderr, "%s (%d): Extension is not binary!\n", __FILE__, __LINE__);
    return (float *)NULL;
  }

  /* Read the sizes of the array */
  if ( fits_read_key_lng(fptr, "NAXIS", &naxes, comment, &status) ) {
    printerror( status );
    return (float *)NULL;
  }
  naxis = (long *)malloc(((size_t)naxes)*sizeof(long));
  if ( fits_read_keys_lng(fptr, "NAXIS", 1, naxes, naxis, &nfound, &status) 
       || nfound != naxes ) {
    printerror( status );
    return (float *)NULL;
  }
  if ( fits_read_key_lng(fptr, "NSIDE", nside, comment, &status) ) {
    printerror(status);
    return (float *)NULL;
  }
  npix = 12*(*nside)*(*nside);
  if ( (npix%naxis[1]) != 0 ) {
    fprintf(stderr, "%s (%d): Problem with npix.\n", __FILE__, __LINE__);
    return (float *)NULL;
  }
  npercol = npix/naxis[1];

  if (fits_read_key(fptr, TSTRING, "COORDSYS",coordsys, comment, &status)) {
    fprintf(stderr, "WARNING: Could not find %s keyword in in file %s\n", 
	    "COORDSYS",infile);
    status = 0;
  }

  if (fits_read_key(fptr, TSTRING, "ORDERING", ordering, comment, &status)) {
    fprintf(stderr, "WARNING: Could not find %s keyword in in file %s\n", 
	    "ORDERING",infile);
    status = 0;
  }

  /* Read the array */
  map = (float *)malloc(((size_t)npix)*sizeof(float));
  nulval = HEALPIX_NULLVAL;
  for (irow = 0; irow < naxis[1]; irow++) {
    if ( fits_read_col(fptr, TFLOAT, 1, irow+1, 1, npercol, &nulval, 
		       &(map[irow*npercol]), &anynul, &status) ) {
      printerror(status);
      return (float *)NULL;
    }
  }

  /* Close the file */
  if ( fits_close_file(fptr, &status) ) {
    printerror( status );
    return (float *)NULL;
  }

  /* Later */
  return map;
}