Exemple #1
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);
}
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;
}
Exemple #3
0
void montage_copyData(fitsfile *infptr, fitsfile *outfptr, struct imageParams *params)
{
   long    fpixel[4], fpixelo[4];
   int     i, j, nullcnt;
   int     status = 0;
   double *buffer, refval;


   /*************************************************/
   /* 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;


   fpixel[0] = params->ibegin;
   fpixel[1] = params->jbegin;
   fpixel[2] = 1;
   fpixel[3] = 1;

   if(params->plane)
      fpixel[2] = params->plane;

   buffer  = (double *)malloc(params->nelements * sizeof(double));

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

   isflat = 1;

   refval = nan;

   for (j=params->jbegin; j<=params->jend; ++j)
   {
      if(debug >= 2)
      {
         printf("Processing input image row %5d\n", j);
         fflush(stdout);
      }

      if(fits_read_pix(infptr, TDOUBLE, fpixel, params->nelements, &nan,
                       buffer, &nullcnt, &status))
         montage_printFitsError(status);

      for(i=0; i<params->nelements; ++i)
      {
         if(!mNaN(buffer[i]))
         {
            if(mNaN(refval))
               refval = buffer[i];

            if(buffer[i] != refval)
               isflat = 0;
         }
      }

      if (fits_write_pix(outfptr, TDOUBLE, fpixelo, params->nelements,
                         (void *)buffer, &status))
         montage_printFitsError(status);

      ++fpixelo[1];
      ++fpixel [1];
   }


   free(buffer);

   if(isflat)
   {
      if(mNaN(refval))
         strcpy(content, "blank");
      else
         strcpy(content, "flat");
   }
   else
      strcpy(content, "normal");
}
Exemple #4
0
int main(int argc, char **argv)
{
    int       i, j, c, ifile, status;
    long      fpixel[4], nelements;
    int       nullcnt;
    int       imin, jmin, haveMinMax;
    int       imax, jmax;
    int       istart, iend, ilength;
    int       jstart, jend, jlength;
    double   *buffer, *abuffer;
    double    datamin, datamax;
    double    areamin, areamax;

    int       narea1, narea2;
    double    avearea1, avearea2;
    double    maxarea1, maxarea2;

    double    pixel_value;

    double  **data;
    double  **area;

    char      template_file[MAXSTR];
    char      line         [MAXSTR];

    char      infile[2][MAXSTR];
    char      inarea[2][MAXSTR];


    /*************************************************/
    /* Initialize output FITS basic image parameters */
    /*************************************************/

    int  bitpix = DOUBLE_IMG;
    long naxis  = 2;


    /************************************************/
    /* 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] = 255;

    nan = value.d;



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

    debug   = 0;
    noAreas = 0;

    coverageLimit = 0.0001;

    opterr = 0;

    fstatus = stdout;

    while ((c = getopt(argc, argv, "nc:d:s:")) != EOF)
    {
        switch (c)
        {
        case 'n':
            noAreas = 1;
            break;

        case 'c':
            coverageLimit = atof(optarg);
            break;

        case 'd':
            debug = debugCheck(optarg);
            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 level] [-n(o-areas)] [-s statusfile] in1.fits in2.fits out.fits hdr.template\"]\n", argv[0]);
            exit(1);
            break;
        }
    }

    if (argc - optind < 4)
    {
        printf("[struct stat=\"ERROR\", msg=\"Usage: %s [-d level] [-n(o-areas)] [-s statusfile] in1.fits in2.fits out.fits hdr.template\"]\n", argv[0]);
        exit(1);
    }

    strcpy(input_file1,   argv[optind]);
    strcpy(input_file2,   argv[optind + 1]);
    strcpy(output_file,   argv[optind + 2]);
    strcpy(template_file, argv[optind + 3]);

    checkHdr(template_file, 1, 0);

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

    strcpy(output_area_file, output_file);
    strcat(output_file,  ".fits");
    strcat(output_area_file, "_area.fits");

    if(debug >= 1)
    {
        printf("input_file1      = [%s]\n", input_file1);
        printf("input_file2      = [%s]\n", input_file2);
        printf("output_file      = [%s]\n", output_file);
        printf("output_area_file = [%s]\n", output_area_file);
        printf("template_file    = [%s]\n", template_file);
        fflush(stdout);
    }


    /****************************/
    /* Get the input file names */
    /****************************/

    if(strlen(input_file1) > 5
            && strcmp(input_file1+strlen(input_file1)-5, ".fits") == 0)
    {
        strcpy(line, input_file1);

        line[strlen(line)-5] = '\0';

        strcpy(infile[0], line);
        strcat(infile[0],  ".fits");
        strcpy(inarea[0], line);
        strcat(inarea[0], "_area.fits");
    }
    else
    {
        strcpy(infile[0], input_file1);
        strcat(infile[0],  ".fits");
        strcpy(inarea[0], input_file1);
        strcat(inarea[0], "_area.fits");
    }


    if(strlen(input_file2) > 5
            && strcmp(input_file2+strlen(input_file2)-5, ".fits") == 0)
    {
        strcpy(line, input_file2);

        line[strlen(line)-5] = '\0';

        strcpy(infile[1], line);
        strcat(infile[1],  ".fits");
        strcpy(inarea[1], line);
        strcat(inarea[1], "_area.fits");
    }
    else
    {
        strcpy(infile[1], input_file2);
        strcat(infile[1],  ".fits");
        strcpy(inarea[1], input_file2);
        strcat(inarea[1], "_area.fits");
    }

    if(debug >= 1)
    {
        printf("\ninput files:\n\n");

        printf("   [%s][%s]\n", infile[0], inarea[0]);
        printf("   [%s][%s]\n", infile[1], inarea[1]);

        printf("\n");
    }


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

    readTemplate(template_file);

    if(debug >= 1)
    {
        printf("output.naxes[0] =  %ld\n", output.naxes[0]);
        printf("output.naxes[1] =  %ld\n", output.naxes[1]);
        printf("output.crpix1   =  %-g\n", output.crpix1);
        printf("output.crpix2   =  %-g\n", output.crpix2);
        fflush(stdout);
    }


    /*****************************************************/
    /* We open the two input files briefly to get enough */
    /* information to determine the region of overlap    */
    /* (for memory allocation purposes)                  */
    /*****************************************************/

    readFits(infile[0], inarea[0]);

    imin = output.crpix1 - input.crpix1;
    jmin = output.crpix2 - input.crpix2;

    imax = imin + input.naxes[0];
    jmax = jmin + input.naxes[1];

    istart = imin;
    iend   = imax;

    jstart = jmin;
    jend   = jmax;

    if(debug >= 1)
    {
        printf("\nFile 1:\n");
        printf("input.naxes[0]       =  %ld\n",   input.naxes[0]);
        printf("input.naxes[1]       =  %ld\n",   input.naxes[1]);
        printf("input.crpix1         =  %-g\n",   input.crpix1);
        printf("input.crpix2         =  %-g\n",   input.crpix2);
        printf("imin                 =  %d\n",    imin);
        printf("imax                 =  %d\n",    imax);
        printf("jmin                 =  %d\n",    jmin);
        printf("jmax                 =  %d\n\n",  jmax);
        printf("istart               =  %d\n",    istart);
        printf("iend                 =  %d\n",    iend);
        printf("jstart               =  %d\n",    jstart);
        printf("jend                 =  %d\n",    jend);

        fflush(stdout);
    }

    status = 0;

    if(fits_close_file(input.fptr, &status))
        printFitsError(status);

    if(!noAreas)
    {
        if(fits_close_file(input_area.fptr, &status))
            printFitsError(status);
    }

    readFits(infile[1], inarea[1]);

    imin = output.crpix1 - input.crpix1;
    jmin = output.crpix2 - input.crpix2;

    imax = imin + input.naxes[0];
    jmax = jmin + input.naxes[1];

    if(debug >= 1)
    {
        printf("\nFile 2:\n");
        printf("input.naxes[0]       =  %ld\n",   input.naxes[0]);
        printf("input.naxes[1]       =  %ld\n",   input.naxes[1]);
        printf("input.crpix1         =  %-g\n",   input.crpix1);
        printf("input.crpix2         =  %-g\n",   input.crpix2);
        printf("imin                 =  %d\n",    imin);
        printf("imax                 =  %d\n",    imax);
        printf("jmin                 =  %d\n",    jmin);
        printf("jmax                 =  %d\n",    jmax);
        printf("istart               =  %d\n\n",  istart);
        printf("iend                 =  %d\n",    iend);
        printf("jstart               =  %d\n",    jstart);
        printf("jend                 =  %d\n",    jend);
        printf("\n");

        fflush(stdout);
    }

    if(imin > istart) istart = imin;
    if(imax < iend  ) iend   = imax;

    if(jmin > jstart) jstart = jmin;
    if(jmax < jend  ) jend   = jmax;

    if(istart < 0) istart = 0;
    if(jstart < 0) jstart = 0;

    if(iend > output.naxes[0]-1) iend = output.naxes[0]-1;
    if(jend > output.naxes[1]-1) jend = output.naxes[1]-1;

    ilength = iend - istart + 1;
    jlength = jend - jstart + 1;

    if(debug >= 1)
    {
        printf("\nComposite:\n");
        printf("input.naxes[0]       =  %ld\n",   input.naxes[0]);
        printf("input.naxes[1]       =  %ld\n",   input.naxes[1]);
        printf("input.crpix1         =  %-g\n",   input.crpix1);
        printf("input.crpix2         =  %-g\n",   input.crpix2);
        printf("istart               =  %d\n",    istart);
        printf("iend                 =  %d\n",    iend);
        printf("jstart               =  %d\n",    jstart);
        printf("jend                 =  %d\n",    jend);
        printf("ilength              =  %d\n",    ilength);
        printf("jlength              =  %d\n",    jlength);
        printf("\n");

        fflush(stdout);
    }

    if(fits_close_file(input.fptr, &status))
        printFitsError(status);

    if(!noAreas)
    {
        if(fits_close_file(input_area.fptr, &status))
            printFitsError(status);
    }

    /*********************/
    /* Check for overlap */
    /*********************/

    if(ilength <= 0 || jlength <= 0)
        printError("Images don't overlap");


    /***********************************************/
    /* Allocate memory for the output image pixels */
    /***********************************************/

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

    for(j=0; j<jlength; ++j)
        data[j] = (double *)malloc(ilength * sizeof(double));

    if(debug >= 1)
    {
        printf("%d bytes allocated for image pixels\n",
               ilength * jlength * sizeof(double));
        fflush(stdout);
    }


    /****************************/
    /* Initialize data to zeros */
    /****************************/

    for (j=0; j<jlength; ++j)
    {
        for (i=0; i<ilength; ++i)
        {
            data[j][i] = 0.;
        }
    }


    /**********************************************/
    /* Allocate memory for the output pixel areas */
    /**********************************************/

    area = (double **)malloc(jlength * sizeof(double *));

    for(j=0; j<jlength; ++j)
        area[j] = (double *)malloc(ilength * sizeof(double));

    if(debug >= 1)
    {
        printf("%d bytes allocated for pixel areas\n",
               ilength * jlength * sizeof(double));
        fflush(stdout);
    }


    /****************************/
    /* Initialize area to zeros */
    /****************************/

    for (j=0; j<jlength; ++j)
    {
        for (i=0; i<ilength; ++i)
        {
            area[j][i] = 0.;
        }
    }


    /***************************/
    /* For the two input files */
    /***************************/

    time(&currtime);
    start = currtime;

    avearea1 = 0.;
    avearea2 = 0.;
    maxarea1 = 0.;
    maxarea2 = 0.;
    narea1   = 0.;
    narea2   = 0.;

    for(ifile=0; ifile<2; ++ifile)
    {
        /************************/
        /* Read the input image */
        /************************/

        readFits(infile[ifile], inarea[ifile]);

        imin = output.crpix1 - input.crpix1;
        jmin = output.crpix2 - input.crpix2;

        if(debug >= 1)
        {
            printf("\nflux file            =  %s\n",  infile[ifile]);
            printf("input.naxes[0]       =  %ld\n",   input.naxes[0]);
            printf("input.naxes[1]       =  %ld\n",   input.naxes[1]);
            printf("input.crpix1         =  %-g\n",   input.crpix1);
            printf("input.crpix2         =  %-g\n",   input.crpix2);
            printf("\narea file            =  %s\n",  inarea[ifile]);
            printf("input_area.naxes[0]  =  %ld\n",   input.naxes[0]);
            printf("input_area.naxes[1]  =  %ld\n",   input.naxes[1]);
            printf("input_area.crpix1    =  %-g\n",   input.crpix1);
            printf("input_area.crpix2    =  %-g\n",   input.crpix2);
            printf("\nimin                 =  %d\n",  imin);
            printf("jmin                 =  %d\n\n",  jmin);

            fflush(stdout);
        }


        /**********************************************************/
        /* Create the output array by processing the input pixels */
        /**********************************************************/

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

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

        nelements = input.naxes[0];

        status = 0;


        /*****************************/
        /* Loop over the input lines */
        /*****************************/

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


            /***********************************/
            /* Read a line from the input file */
            /***********************************/

            if(fits_read_pix(input.fptr, TDOUBLE, fpixel, nelements, NULL,
                             buffer, &nullcnt, &status))
                printFitsError(status);


            if(noAreas)
            {
                for(i=0; i<input.naxes[0]; ++i)
                    abuffer[i] = 1.;
            }
            else
            {
                if(fits_read_pix(input_area.fptr, TDOUBLE, fpixel, nelements, NULL,
                                 abuffer, &nullcnt, &status))
                    printFitsError(status);
            }

            ++fpixel[1];


            /************************/
            /* For each input pixel */
            /************************/

            for (i=0; i<input.naxes[0]; ++i)
            {
                pixel_value = buffer[i] * abuffer[i];

                if(debug >= 4)
                {
                    printf("input: line %5d / pixel %5d, value = %10.2e (%10.2e) [array: %5d %5d]\n",
                           j, i, buffer[i], abuffer[i], j+jmin-jstart, i+imin-istart);
                    fflush(stdout);
                }

                if(i+imin < istart) continue;
                if(j+jmin < jstart) continue;

                if(i+imin >= iend) continue;
                if(j+jmin >= jend) continue;

                if(debug >= 3)
                {
                    printf("keep: line %5d / pixel %5d, value = %10.2e (%10.2e) [array: %5d %5d]\n",
                           j, i, buffer[i], abuffer[i], j+jmin-jstart, i+imin-istart);
                    fflush(stdout);
                }

                if(ifile == 0)
                {
                    if(mNaN(buffer[i])
                            || abuffer[i] <= 0.)
                    {
                        if(debug >= 5)
                        {
                            printf("First file. Setting data to NaN and area to zero.\n");
                            fflush(stdout);
                        }

                        data[j+jmin-jstart][i+imin-istart] = nan;
                        area[j+jmin-jstart][i+imin-istart] = 0.;

                        if(debug >= 5)
                        {
                            printf("done.\n");
                            fflush(stdout);
                        }

                        continue;
                    }
                    else
                    {
                        if(debug >= 5)
                        {
                            printf("First file. Setting data to pixel value.\n");
                            fflush(stdout);
                        }

                        data[j+jmin-jstart][i+imin-istart] = pixel_value;
                        area[j+jmin-jstart][i+imin-istart] = abuffer[i];

                        ++narea1;
                        avearea1 += abuffer[i];

                        if(abuffer[i] > maxarea1)
                            maxarea1 = abuffer[i];

                        if(debug >= 5)
                        {
                            printf("done.\n");
                            fflush(stdout);
                        }

                    }
                }
                else
                {
                    if(mNaN(buffer[i])
                            || abuffer[i] <= 0.
                            || data[j+jmin-jstart][i+imin-istart] == nan
                            || area[j+jmin-jstart][i+imin-istart] == 0.)
                    {
                        if(debug >= 5)
                        {
                            printf("Second file. One or the other value is NaN (or zero area).\n");
                            fflush(stdout);
                        }

                        data[j+jmin-jstart][i+imin-istart] = nan;
                        area[j+jmin-jstart][i+imin-istart] = 0.;

                        continue;
                    }
                    else
                    {
                        if(debug >= 5)
                        {
                            printf("Second file. Subtracting pixel value.\n");
                            fflush(stdout);
                        }

                        data[j+jmin-jstart][i+imin-istart] -= pixel_value;
                        area[j+jmin-jstart][i+imin-istart] += abuffer[i];

                        ++narea2;
                        avearea2 += abuffer[i];

                        if(abuffer[i] > maxarea2)
                            maxarea2 = abuffer[i];

                        if(debug >= 5)
                        {
                            printf("done.\n");
                            fflush(stdout);
                        }
                    }
                }
            }
        }

        free(buffer);
        free(abuffer);

        if(fits_close_file(input.fptr, &status))
            printFitsError(status);

        if(!noAreas)
        {
            if(fits_close_file(input_area.fptr, &status))
                printFitsError(status);
        }
    }

    if(debug >= 1)
    {
        time(&currtime);
        printf("\nDone reading data (%.0f seconds)\n",
               (double)(currtime - start));
        fflush(stdout);
    }


    /************************************/
    /* Anly keep those pixels that were */
    /* covered twice reasonably fully   */
    /************************************/

    avearea1 = avearea1/narea1;
    avearea2 = avearea2/narea2;

    areamax = maxarea1 + maxarea2;

    if(debug >= 2)
    {
        printf("\npixel areas: %-g + %-g = %-g\n\n", avearea1, avearea2, areamax);
        fflush(stdout);
    }

    for (j=0; j<jlength; ++j)
    {
        for (i=0; i<ilength; ++i)
        {
            if(mNaN(area[j][i]) || area[j][i] == 0.)
            {
                data[j][i] = 0.;
                area[j][i] = 0.;
            }
            else
            {
                if(fabs(area[j][i] - areamax)/areamax > coverageLimit)
                {
                    data[j][i] = 0.;
                    area[j][i] = 0.;
                }
            }
        }
    }


    /*********************************/
    /* Normalize image data based on */
    /* total area added to pixel     */
    /*********************************/

    haveMinMax = 0;

    datamax = 0.,
    datamin = 0.;
    areamin = 0.;
    areamax = 0.;

    imin = 99999;
    imax = 0;

    jmin = 99999;
    jmax = 0;

    for (j=0; j<jlength; ++j)
    {
        for (i=0; i<ilength; ++i)
        {
            if(area[j][i] > 0.)
            {
                data[j][i] = 2. * data[j][i] / area[j][i];

                if(!haveMinMax)
                {
                    datamin = data[j][i];
                    datamax = data[j][i];
                    areamin = area[j][i];
                    areamax = area[j][i];

                    haveMinMax = 1;
                }

                if(data[j][i] < datamin) datamin = data[j][i];
                if(data[j][i] > datamax) datamax = data[j][i];
                if(area[j][i] < areamin) areamin = area[j][i];
                if(area[j][i] > areamax) areamax = area[j][i];

                if(j < jmin) jmin = j;
                if(j > jmax) jmax = j;
                if(i < imin) imin = i;
                if(i > imax) imax = i;
            }
            else
            {
                data[j][i] = nan;
                area[j][i] = 0.;
            }
        }
    }

    imin += istart;
    jmin += jstart;

    imax += istart;
    jmax += jstart;

    if(debug >= 1)
    {
        printf("Data min = %-g\n", datamin);
        printf("Data max = %-g\n", datamax);
        printf("Area min = %-g\n", areamin);
        printf("Area max = %-g\n\n", areamax);
        printf("j min    = %d\n", jmin);
        printf("j max    = %d\n", jmax);
        printf("i min    = %d\n", imin);
        printf("i max    = %d\n", imax);
    }

    if(jmin > jmax || imin > imax)
        printError("All pixels are blank.");


    /********************************/
    /* Create the output FITS files */
    /********************************/

    remove(output_file);
    remove(output_area_file);

    if(fits_create_file(&output.fptr, output_file, &status))
        printFitsError(status);

    if(fits_create_file(&output_area.fptr, output_area_file, &status))
        printFitsError(status);


    /*********************************************************/
    /* Create the FITS image.  All the required keywords are */
    /* handled automatically.                                */
    /*********************************************************/

    if (fits_create_img(output.fptr, bitpix, naxis, output.naxes, &status))
        printFitsError(status);

    if(debug >= 1)
    {
        printf("\nFITS data image created (not yet populated)\n");
        fflush(stdout);
    }

    if (fits_create_img(output_area.fptr, bitpix, naxis, output_area.naxes, &status))
        printFitsError(status);

    if(debug >= 1)
    {
        printf("FITS area image created (not yet populated)\n");
        fflush(stdout);
    }


    /****************************************/
    /* Set FITS header from a template file */
    /****************************************/

    if(fits_write_key_template(output.fptr, template_file, &status))
        printFitsError(status);

    if(debug >= 1)
    {
        printf("Template keywords written to FITS data image\n");
        fflush(stdout);
    }

    if(fits_write_key_template(output_area.fptr, template_file, &status))
        printFitsError(status);

    if(debug >= 1)
    {
        printf("Template keywords written to FITS area image\n\n");
        fflush(stdout);
    }


    /***************************/
    /* Modify BITPIX to be -64 */
    /***************************/

    if(fits_update_key_lng(output.fptr, "BITPIX", -64,
                           (char *)NULL, &status))
        printFitsError(status);

    if(fits_update_key_lng(output_area.fptr, "BITPIX", -64,
                           (char *)NULL, &status))
        printFitsError(status);


    /***************************************************/
    /* Update NAXIS, NAXIS1, NAXIS2, CRPIX1 and CRPIX2 */
    /***************************************************/

    if(fits_update_key_lng(output.fptr, "NAXIS", 2,
                           (char *)NULL, &status))
        printFitsError(status);

    if(fits_update_key_lng(output.fptr, "NAXIS1", imax-imin+1,
                           (char *)NULL, &status))
        printFitsError(status);

    if(fits_update_key_lng(output.fptr, "NAXIS2", jmax-jmin+1,
                           (char *)NULL, &status))
        printFitsError(status);

    if(fits_update_key_dbl(output.fptr, "CRPIX1", output.crpix1-imin, -14,
                           (char *)NULL, &status))
        printFitsError(status);

    if(fits_update_key_dbl(output.fptr, "CRPIX2", output.crpix2-jmin, -14,
                           (char *)NULL, &status))
        printFitsError(status);

    if(fits_update_key_lng(output_area.fptr, "NAXIS", 2,
                           (char *)NULL, &status))
        printFitsError(status);

    if(fits_update_key_lng(output_area.fptr, "NAXIS1", imax-imin+1,
                           (char *)NULL, &status))
        printFitsError(status);

    if(fits_update_key_lng(output_area.fptr, "NAXIS2", jmax-jmin+1,
                           (char *)NULL, &status))
        printFitsError(status);

    if(fits_update_key_dbl(output_area.fptr, "CRPIX1", output.crpix1-imin, -14,
                           (char *)NULL, &status))
        printFitsError(status);

    if(fits_update_key_dbl(output_area.fptr, "CRPIX2", output.crpix2-jmin, -14,
                           (char *)NULL, &status))
        printFitsError(status);

    if(debug >= 1)
    {
        printf("Template keywords BITPIX, CRPIX, and NAXIS updated\n");
        fflush(stdout);
    }


    /************************/
    /* Write the image data */
    /************************/

    fpixel[0] = 1;
    fpixel[1] = 1;
    nelements = imax - imin + 1;

    for(j=jmin; j<=jmax; ++j)
    {
        if (fits_write_pix(output.fptr, TDOUBLE, fpixel, nelements,
                           (void *)(&data[j-jstart][imin-istart]), &status))
            printFitsError(status);

        ++fpixel[1];
    }

    free(data[0]);

    if(debug >= 1)
    {
        printf("Data written to FITS data image\n");
        fflush(stdout);
    }


    /***********************/
    /* Write the area data */
    /***********************/

    fpixel[0] = 1;
    fpixel[1] = 1;
    nelements = imax - imin + 1;

    for(j=jmin; j<=jmax; ++j)
    {
        if (fits_write_pix(output_area.fptr, TDOUBLE, fpixel, nelements,
                           (void *)(&area[j-jstart][imin-istart]), &status))
            printFitsError(status);

        ++fpixel[1];
    }

    free(area[0]);

    if(debug >= 1)
    {
        printf("Data written to FITS area image\n\n");
        fflush(stdout);
    }


    /***********************/
    /* Close the FITS file */
    /***********************/

    if(fits_close_file(output.fptr, &status))
        printFitsError(status);

    if(debug >= 1)
    {
        printf("FITS data image finalized\n");
        fflush(stdout);
    }

    if(fits_close_file(output_area.fptr, &status))
        printFitsError(status);

    if(debug >= 1)
    {
        printf("FITS area image finalized\n\n");
        fflush(stdout);
    }

    if(debug >= 1)
    {
        time(&currtime);
        printf("Done (%.0f seconds total)\n", (double)(currtime - start));
        fflush(stdout);
    }

    fprintf(fstatus, "[struct stat=\"OK\"]\n");
    fflush(stdout);

    exit(0);
}
Exemple #5
0
struct mShrinkReturn *mShrink(char *input_file, int hduin, char *output_file, double shrinkFactor, int fixedSize, int debug)
{
   int       i, j, ii, jj, status, bufrow,  split;
   int       ibuffer, jbuffer, ifactor, nbuf, nullcnt, k, l, imin, imax, jmin, jmax;
   long      fpixel[4], fpixelo[4], nelements, nelementso;
   double    obegin, oend;
   double   *colfact, *rowfact;
   double   *buffer;
   double    xfactor, flux, area;

   double   *outdata;
   double  **indata;

   struct mShrinkReturn *returnStruct;


   /************************************************/
   /* 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] = 255;

   nan = value.d;



   /*******************************/
   /* Initialize return structure */
   /**n****************************/

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

   bzero((void *)returnStruct, sizeof(returnStruct));


   returnStruct->status = 1;

   strcpy(returnStruct->msg, "");


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

   time(&currtime);
   start = currtime;

   hdu = hduin;

   xfactor = shrinkFactor;
   
   if(!fixedSize)
   {
      ifactor = ceil(xfactor);

      if((double)ifactor < xfactor)
         xfactor += 2;
   }

   if(xfactor <= 0)
   {
      if(fixedSize)
         mShrink_printError("Requested image size must be positive");
      else
         mShrink_printError("Shrink factor must be positive");

      strcpy(returnStruct->msg, montage_msgstr);
      return returnStruct;
   }

   if(debug >= 1)
   {
      printf("input_file       = [%s]\n", input_file);
      printf("output_file      = [%s]\n", output_file);
      printf("xfactor          = %-g\n",  xfactor);
      printf("ifactor          = %d\n",   ifactor);
      fflush(stdout);
   }


   /************************/
   /* Read the input image */
   /************************/

   if(mShrink_readFits(input_file))
   {
      strcpy(returnStruct->msg, montage_msgstr);
      return returnStruct;
   }


   // Error if we are trying to shrink to less than one pixel

   if(!fixedSize
   && (   shrinkFactor > input.naxes[0]
       || shrinkFactor > input.naxes[1]))
   {
      mShrink_printError("Trying to shrink image to smaller than one pixel");
      strcpy(returnStruct->msg, montage_msgstr);
      return returnStruct;
   }


   if(debug >= 1)
   {
      printf("\nflux file            =  %s\n",  input_file);
      printf("input.bitpix         =  %ld\n",   input.bitpix);
      printf("input.naxes[0]       =  %ld\n",   input.naxes[0]);
      printf("input.naxes[1]       =  %ld\n",   input.naxes[1]);

      if(haveCtype)   printf("input.ctype1         =  %s\n",    input.ctype1);
      if(haveCtype)   printf("input.typel2         =  %s\n",    input.ctype2);
      if(haveCrval)   printf("input.crval1         =  %-g\n",   input.crval1);
      if(haveCrval)   printf("input.crval2         =  %-g\n",   input.crval2);
      if(haveCrpix)   printf("input.crpix1         =  %-g\n",   input.crpix1);
      if(haveCrpix)   printf("input.crpix2         =  %-g\n",   input.crpix2);
      if(haveCnpix)   printf("input.cnpix1         =  %-g\n",   input.cnpix1);
      if(haveCnpix)   printf("input.cnpix2         =  %-g\n",   input.cnpix2);
      if(havePixelsz) printf("input.xpixelsz       =  %-g\n",   input.xpixelsz);
      if(havePixelsz) printf("input.ypixelsz       =  %-g\n",   input.ypixelsz);
      if(havePP)      printf("input.ppo3           =  %-g\n",   input.ppo3);
      if(havePP)      printf("input.ppo6           =  %-g\n",   input.ppo6);
      if(haveCdelt)   printf("input.cdelt1         =  %-g\n",   input.cdelt1);
      if(haveCdelt)   printf("input.cdelt2         =  %-g\n",   input.cdelt2);
      if(haveCrota2)  printf("input.crota2         =  %-g\n",   input.crota2);
      if(haveCD11)    printf("input.cd11           =  %-g\n",   input.cd11);
      if(haveCD12)    printf("input.cd12           =  %-g\n",   input.cd12);
      if(haveCD21)    printf("input.cd21           =  %-g\n",   input.cd21);
      if(haveCD22)    printf("input.cd22           =  %-g\n",   input.cd22);
      if(havePC11)    printf("input.pc11           =  %-g\n",   input.pc11);
      if(havePC12)    printf("input.pc12           =  %-g\n",   input.pc12);
      if(havePC21)    printf("input.pc21           =  %-g\n",   input.pc21);
      if(havePC22)    printf("input.pc22           =  %-g\n",   input.pc22);
      if(haveEpoch)   printf("input.epoch          =  %-g\n",   input.epoch);
      if(haveEquinox) printf("input.equinox        =  %-g\n",   input.equinox);
      if(haveBunit)   printf("input.bunit          =  %s\n",    input.bunit);
      if(haveBlank)   printf("input.blank          =  %ld\n",   input.blank);
      printf("\n");

      fflush(stdout);
   }


   /***********************************************/
   /* If we are going for a fixed size, the scale */
   /* factor needs to be computed.                */
   /***********************************************/

   if(fixedSize)
   {
      if(input.naxes[0] > input.naxes[1])
         xfactor = (double)input.naxes[0]/(int)xfactor;
      else
         xfactor = (double)input.naxes[1]/(int)xfactor;

      ifactor = ceil(xfactor);

      if((double)ifactor < xfactor)
         xfactor += 2;

      if(debug >= 1)
      {
         printf("xfactor         -> %-g\n",  xfactor);
         printf("ifactor         -> %d\n",   ifactor);
         fflush(stdout);
      }
   }

   /***********************************************/
   /* Compute all the parameters for the shrunken */
   /* output file.                                */
   /***********************************************/

   output.naxes[0] = floor((double)input.naxes[0]/xfactor);
   output.naxes[1] = floor((double)input.naxes[1]/xfactor);
   
   if(debug >= 1)
   {
      printf("output.naxes[0] = %ld\n",  output.naxes[0]);
      printf("output.naxes[1] = %ld\n",  output.naxes[1]);
      fflush(stdout);
   }

   strcpy(output.ctype1, input.ctype1);
   strcpy(output.ctype2, input.ctype2);

   output.crval1   = input.crval1;
   output.crval2   = input.crval2;
   output.crpix1   = (input.crpix1-0.5)/xfactor + 0.5;
   output.crpix2   = (input.crpix2-0.5)/xfactor + 0.5;
   output.cdelt1   = input.cdelt1*xfactor;
   output.cdelt2   = input.cdelt2*xfactor;
   output.crota2   = input.crota2;
   output.cd11     = input.cd11*xfactor;
   output.cd12     = input.cd12*xfactor;
   output.cd21     = input.cd21*xfactor;
   output.cd22     = input.cd22*xfactor;
   output.pc11     = input.pc11;
   output.pc12     = input.pc12;
   output.pc21     = input.pc21;
   output.pc22     = input.pc22;
   output.epoch    = input.epoch;
   output.equinox  = input.equinox;

   strcpy(output.bunit, input.bunit);

   if(haveCnpix)
   {
      input.crpix1    = input.ppo3 / input.xpixelsz - input.cnpix1 + 0.5; 
      input.crpix2    = input.ppo6 / input.ypixelsz - input.cnpix2 + 0.5; 

      output.crpix1   = (input.crpix1-0.5)/xfactor + 0.5;
      output.crpix2   = (input.crpix2-0.5)/xfactor + 0.5;

      output.xpixelsz = input.xpixelsz * xfactor;
      output.ypixelsz = input.ypixelsz * xfactor;

      output.cnpix1   = input.ppo3 / output.xpixelsz - output.crpix1 + 0.5;
      output.cnpix2   = input.ppo6 / output.ypixelsz - output.crpix2 + 0.5;
   }


   /********************************/
   /* Create the output FITS files */
   /********************************/

   status = 0;

   remove(output_file);               

   if(fits_create_file(&output.fptr, output_file, &status)) 
   {
      mShrink_printFitsError(status);
      strcpy(returnStruct->msg, montage_msgstr);
      return returnStruct;
   }


   /******************************************************/
   /* Create the FITS image.  Copy over the whole header */
   /******************************************************/

   if(fits_copy_header(input.fptr, output.fptr, &status))
   {
      mShrink_printFitsError(status);
      strcpy(returnStruct->msg, montage_msgstr);
      return returnStruct;
   }

   if(debug >= 1)
   {
      printf("\nFITS header copied to output\n"); 
      fflush(stdout);
   }


   /************************************/
   /* Reset all the WCS header kewords */
   /************************************/

   if(fits_update_key_lng(output.fptr, "NAXIS", 2,
                                  (char *)NULL, &status))
   {
      mShrink_printFitsError(status);
      strcpy(returnStruct->msg, montage_msgstr);
      return returnStruct;
   }

   if(fits_update_key_lng(output.fptr, "NAXIS1", output.naxes[0],
                                  (char *)NULL, &status))
   {
      mShrink_printFitsError(status);
      strcpy(returnStruct->msg, montage_msgstr);
      return returnStruct;
   }

   if(fits_update_key_lng(output.fptr, "NAXIS2", output.naxes[1],
                                  (char *)NULL, &status))
   {
      mShrink_printFitsError(status);
      strcpy(returnStruct->msg, montage_msgstr);
      return returnStruct;
   }

   if(haveBunit && fits_update_key_str(output.fptr, "BUNIT", output.bunit,
                                  (char *)NULL, &status))
   {
      mShrink_printFitsError(status);
      strcpy(returnStruct->msg, montage_msgstr);
      return returnStruct;
   }

   if(haveBlank && fits_update_key_lng(output.fptr, "BLANK", output.blank,
                                  (char *)NULL, &status))
   {
      mShrink_printFitsError(status);
      strcpy(returnStruct->msg, montage_msgstr);
      return returnStruct;
   }

   if(haveCtype && fits_update_key_str(output.fptr, "CTYPE1", output.ctype1,
                                  (char *)NULL, &status))
   {
      mShrink_printFitsError(status);
      strcpy(returnStruct->msg, montage_msgstr);
      return returnStruct;
   }

   if(haveCtype && fits_update_key_str(output.fptr, "CTYPE2", output.ctype2,
                                  (char *)NULL, &status))
   {
      mShrink_printFitsError(status);
      strcpy(returnStruct->msg, montage_msgstr);
      return returnStruct;
   }

   if(haveCrval && fits_update_key_dbl(output.fptr, "CRVAL1", output.crval1, -14,
                                  (char *)NULL, &status))
   {
      mShrink_printFitsError(status);
      strcpy(returnStruct->msg, montage_msgstr);
      return returnStruct;
   }

   if(haveCrval && fits_update_key_dbl(output.fptr, "CRVAL2", output.crval2, -14,
                                  (char *)NULL, &status))
   {
      mShrink_printFitsError(status);
      strcpy(returnStruct->msg, montage_msgstr);
      return returnStruct;
   }

   if(haveCrpix && fits_update_key_dbl(output.fptr, "CRPIX1", output.crpix1, -14,
                                  (char *)NULL, &status))
   {
      mShrink_printFitsError(status);
      strcpy(returnStruct->msg, montage_msgstr);
      return returnStruct;
   }

   if(haveCrpix && fits_update_key_dbl(output.fptr, "CRPIX2", output.crpix2, -14,
                                  (char *)NULL, &status))
   {
      mShrink_printFitsError(status);
      strcpy(returnStruct->msg, montage_msgstr);
      return returnStruct;
   }

   if(haveCnpix && fits_update_key_dbl(output.fptr, "CNPIX1", output.cnpix1, -14,
                                  (char *)NULL, &status))
   {
      mShrink_printFitsError(status);
      strcpy(returnStruct->msg, montage_msgstr);
      return returnStruct;
   }

   if(haveCnpix && fits_update_key_dbl(output.fptr, "CNPIX2", output.cnpix2, -14,
                                  (char *)NULL, &status))
   {
      mShrink_printFitsError(status);
      strcpy(returnStruct->msg, montage_msgstr);
      return returnStruct;
   }

   if(havePixelsz && fits_update_key_dbl(output.fptr, "XPIXELSZ", output.xpixelsz, -14,
                                  (char *)NULL, &status))
   {
      mShrink_printFitsError(status);
      strcpy(returnStruct->msg, montage_msgstr);
      return returnStruct;
   }

   if(havePixelsz && fits_update_key_dbl(output.fptr, "YPIXELSZ", output.ypixelsz, -14,
                                  (char *)NULL, &status))
   {
      mShrink_printFitsError(status);
      strcpy(returnStruct->msg, montage_msgstr);
      return returnStruct;
   }

   if(haveCdelt && fits_update_key_dbl(output.fptr, "CDELT1", output.cdelt1, -14,
                                     (char *)NULL, &status))
   {
      mShrink_printFitsError(status);
      strcpy(returnStruct->msg, montage_msgstr);
      return returnStruct;
   }

   if(haveCdelt && fits_update_key_dbl(output.fptr, "CDELT2", output.cdelt2, -14,
                                  (char *)NULL, &status))
   {
      mShrink_printFitsError(status);
      strcpy(returnStruct->msg, montage_msgstr);
      return returnStruct;
   }

   if(haveCrota2 && fits_update_key_dbl(output.fptr, "CROTA2", output.crota2, -14,
                                  (char *)NULL, &status))
   {
      mShrink_printFitsError(status);
      strcpy(returnStruct->msg, montage_msgstr);
      return returnStruct;
   }

   if(haveCD11 && fits_update_key_dbl(output.fptr, "CD1_1", output.cd11, -14,
                                  (char *)NULL, &status))
   {
      mShrink_printFitsError(status);
      strcpy(returnStruct->msg, montage_msgstr);
      return returnStruct;
   }

   if(haveCD12 && fits_update_key_dbl(output.fptr, "CD1_2", output.cd12, -14,
                                  (char *)NULL, &status))
   {
      mShrink_printFitsError(status);
      strcpy(returnStruct->msg, montage_msgstr);
      return returnStruct;
   }

   if(haveCD21 && fits_update_key_dbl(output.fptr, "CD2_1", output.cd21, -14,
                                  (char *)NULL, &status))
   {
      mShrink_printFitsError(status);
      strcpy(returnStruct->msg, montage_msgstr);
      return returnStruct;
   }

   if(haveCD22 && fits_update_key_dbl(output.fptr, "CD2_2", output.cd22, -14,
                                  (char *)NULL, &status))
   {
      mShrink_printFitsError(status);
      strcpy(returnStruct->msg, montage_msgstr);
      return returnStruct;
   }

   if(havePC11 && fits_update_key_dbl(output.fptr, "PC1_1", output.pc11, -14,
                                  (char *)NULL, &status))
   {
      mShrink_printFitsError(status);
      strcpy(returnStruct->msg, montage_msgstr);
      return returnStruct;
   }

   if(havePC12 && fits_update_key_dbl(output.fptr, "PC1_2", output.pc12, -14,
                                  (char *)NULL, &status))
   {
      mShrink_printFitsError(status);
      strcpy(returnStruct->msg, montage_msgstr);
      return returnStruct;
   }

   if(havePC21 && fits_update_key_dbl(output.fptr, "PC2_1", output.pc21, -14,
                                  (char *)NULL, &status))
   {
      mShrink_printFitsError(status);
      strcpy(returnStruct->msg, montage_msgstr);
      return returnStruct;
   }

   if(havePC22 && fits_update_key_dbl(output.fptr, "PC2_2", output.pc22, -14,
                                  (char *)NULL, &status))
   {
      mShrink_printFitsError(status);
      strcpy(returnStruct->msg, montage_msgstr);
      return returnStruct;
   }

   if(haveEpoch && fits_update_key_dbl(output.fptr, "EPOCH", output.epoch, -14,
                                  (char *)NULL, &status))
   {
      mShrink_printFitsError(status);
      strcpy(returnStruct->msg, montage_msgstr);
      return returnStruct;
   }

   if(haveEquinox && fits_update_key_dbl(output.fptr, "EQUINOX", output.equinox, -14,
                                  (char *)NULL, &status))
   {
      mShrink_printFitsError(status);
      strcpy(returnStruct->msg, montage_msgstr);
      return returnStruct;
   }


   if(debug >= 1)
   {
      printf("Output header keywords set\n\n");
      fflush(stdout);
   }



   /***********************************************/ 
   /* Allocate memory for a line of output pixels */ 
   /***********************************************/ 

   outdata = (double *)malloc(output.naxes[0] * sizeof(double));


   /*************************************************************************/ 
   /* We could probably come up with logic that would work for both scale   */
   /* factors of less than one and greater than one but the it would be too */
   /* hard to follow.  Instead, we put in a big switch here to deal with    */
   /* the two cases separately.                                             */
   /*************************************************************************/ 

   if(xfactor < 1.)
   {
      /************************************************/ 
      /* Allocate memory for "ifactor" lines of input */ 
      /************************************************/ 

      nbuf = 2;

      indata = (double **)malloc(nbuf * sizeof(double *));

      for(j=0; j<nbuf; ++j)
         indata[j] = (double *)malloc((input.naxes[0]+1) * sizeof(double));


      /**********************************************************/
      /* Create the output array by processing the input pixels */
      /**********************************************************/

      ibuffer = 0;

      buffer  = (double *)malloc(input.naxes[0] * sizeof(double));
      colfact = (double *)malloc(nbuf * sizeof(double));
      rowfact = (double *)malloc(nbuf * sizeof(double));

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

      fpixelo[0] = 1;
      fpixelo[1] = 1;

      nelements = input.naxes[0];

      status = 0;


      /******************************/
      /* Loop over the output lines */
      /******************************/

      split = 0;

      for(l=0; l<output.naxes[1]; ++l)
      {
         obegin = (fpixelo[1] - 1.) * xfactor;
         oend   =  fpixelo[1] * xfactor;

         if(floor(oend) == oend)
            oend = obegin;

         if(debug >= 2)
         {
            printf("OUTPUT row %d: obegin = %.2f -> oend = %.3f\n\n", l, obegin, oend);
            fflush(stdout);
         }

         rowfact[0] = 1.;
         rowfact[1] = 0.;


         /******************************************/
         /* If we have gone over into the next row */
         /******************************************/

         if(l == 0 || (int)oend > (int)obegin)
         {
            rowfact[0] = 1.;
            rowfact[1] = 0.;

            if(l > 0)
            {
               split = 1;

               jbuffer = (ibuffer + 1) % nbuf;

               rowfact[1] = (oend - (int)(fpixelo[1] * xfactor))/xfactor;
               rowfact[0] = 1. - rowfact[1];
            }
            else
            {
               jbuffer = 0;
            }

            if(debug >= 2)
            {
               printf("Reading input image row %5ld  (ibuffer %d)\n", fpixel[1], jbuffer);
               fflush(stdout);
            }

            if(debug >= 2)
            {
               printf("Rowfact:  %-g %-g\n", rowfact[0], rowfact[1]);
               fflush(stdout);
            }


            /***********************************/
            /* Read a line from the input file */
            /***********************************/

            if(fpixel[1] <= input.naxes[1])
            {
               if(fits_read_pix(input.fptr, TDOUBLE, fpixel, nelements, &nan,
                                buffer, &nullcnt, &status))
               {
                  mShrink_printFitsError(status);
                  strcpy(returnStruct->msg, montage_msgstr);
                  return returnStruct;
               }
            }
            
            ++fpixel[1];


            /************************/
            /* For each input pixel */
            /************************/

            indata[jbuffer][input.naxes[0]] = nan;

            for (i=0; i<input.naxes[0]; ++i)
            {
               indata[jbuffer][i] = buffer[i];

               if(debug >= 4)
               {
                  printf("input: line %5ld / pixel %5d: indata[%d][%d] = %10.3e\n",
                     fpixel[1]-2, i, jbuffer, i, indata[jbuffer][i]);
                  fflush(stdout);
               }
            }

            if(debug >= 4)
            {
               printf("---\n");
               fflush(stdout);
            }
         }


         /*************************************/
         /* Write out the next line of output */
         /*************************************/

         nelementso = output.naxes[0];

         for(k=0; k<nelementso; ++k)
         {
            /* When "expanding" we never need to use more than two   */
            /* pixels in more than two rows.  The row factors were   */
            /* computed above and the column factors will be compute */
            /* here as we go.                                        */

            outdata[k] = nan;

            colfact[0] = 1.;
            colfact[1] = 0.;

            obegin =  (double)k     * xfactor;
            oend   = ((double)k+1.) * xfactor;

            if(floor(oend) == oend)
               oend = obegin;

            imin = (int)obegin;

            if((int)oend > (int)obegin)
            {
               colfact[1] = (oend - (int)(((double)k+1.) * xfactor))/xfactor;
               colfact[0] = 1. - colfact[1];
            }

            flux = 0;
            area = 0;

            for(jj=0; jj<2; ++jj)
            {
               if(rowfact[jj] == 0.)
                  continue;

               for(ii=0; ii<2; ++ii)
               {
                  bufrow = (ibuffer + jj) % nbuf;

                  if(!mNaN(indata[bufrow][imin+ii]) && colfact[ii] > 0.)
                  {
                     flux += indata[bufrow][imin+ii] * colfact[ii] * rowfact[jj];
                     area += colfact[ii] * rowfact[jj];

                     if(debug >= 3)
                     {
                        printf("output[%d][%d] -> %10.2e (area: %10.2e) (using indata[%d][%d] = %10.2e, colfact[%d] = %5.3f, rowfact[%d] = %5.3f)\n", 
                           l, k, flux, area,
                           bufrow, imin+ii, indata[bufrow][imin+ii], 
                           imin+ii, colfact[ii],
                           jj, rowfact[jj]);

                        fflush(stdout);
                     }
                  }
               }
            }

            if(area > 0.)
               outdata[k] = flux/area;
            else
               outdata[k] = nan;

            if(debug >= 3)
            {
               printf("\nflux[%d] = %-g / area = %-g --> outdata[%d] = %-g\n",
                  k, flux, area, k, outdata[k]);
               
               printf("---\n");
               fflush(stdout);
            }
         }

         if(fpixelo[1] <= output.naxes[1])
         {
            if(debug >= 2)
            {
               printf("\nWRITE output image row %5ld\n===========================================\n", fpixelo[1]);
               fflush(stdout);
            }

            if (fits_write_pix(output.fptr, TDOUBLE, fpixelo, nelementso, 
                               (void *)(outdata), &status))
            {
               mShrink_printFitsError(status);
               strcpy(returnStruct->msg, montage_msgstr);
               return returnStruct;
            }
         }

         ++fpixelo[1];

         if(split)
         {
            ibuffer = jbuffer;
            split = 0;
         }


         /***************************************************************/
         /* Special case:  The expansion factor is integral and we have */
         /* gotten to the point where we need the next line.            */
         /***************************************************************/

         oend   =  fpixelo[1] * xfactor;

         if(fpixel[1] <= input.naxes[1] && floor(oend) == oend)
         {
            if(debug >= 2)
            {
               printf("Reading input image row %5ld  (ibuffer %d)\n", fpixel[1], jbuffer);
               fflush(stdout);
            }

            if(fits_read_pix(input.fptr, TDOUBLE, fpixel, nelements, &nan,
                             buffer, &nullcnt, &status))
            {
               mShrink_printFitsError(status);
               strcpy(returnStruct->msg, montage_msgstr);
               return returnStruct;
            }
            
            ++fpixel[1];

            indata[jbuffer][input.naxes[0]] = nan;

            for (i=0; i<input.naxes[0]; ++i)
            {
               indata[jbuffer][i] = buffer[i];

               if(debug >= 4)
               {
                  printf("input: line %5ld / pixel %5d: indata[%d][%d] = %10.3e\n",
                     fpixel[1]-2, i, jbuffer, i, indata[jbuffer][i]);
                  fflush(stdout);
               }
            }

            if(debug >= 4)
            {
               printf("---\n");
               fflush(stdout);
            }
         }
      }
   }
   else
   {
      /************************************************/ 
      /* Allocate memory for "ifactor" lines of input */ 
      /************************************************/ 

      nbuf = ifactor + 1;

      indata = (double **)malloc(nbuf * sizeof(double *));

      for(j=0; j<nbuf; ++j)
         indata[j] = (double *)malloc(input.naxes[0] * sizeof(double));



      /**********************************************************/
      /* Create the output array by processing the input pixels */
      /**********************************************************/

      ibuffer = 0;

      buffer  = (double *)malloc(input.naxes[0] * sizeof(double));
      colfact = (double *)malloc(input.naxes[0] * sizeof(double));
      rowfact = (double *)malloc(input.naxes[1] * sizeof(double));

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

      fpixelo[0] = 1;
      fpixelo[1] = 1;

      nelements = input.naxes[0];

      status = 0;


      /*****************************/
      /* Loop over the input lines */
      /*****************************/

      l = 0;

      obegin =  (double)l     * xfactor;
      oend   = ((double)l+1.) * xfactor;

      jmin = floor(obegin);
      jmax = ceil (oend);

      for(jj=jmin; jj<=jmax; ++jj)
      {
         rowfact[jj-jmin] = 1.;

              if(jj <= obegin && jj+1 <= oend) rowfact[jj-jmin] = jj+1. - obegin;
         else if(jj <= obegin && jj+1 >= oend) rowfact[jj-jmin] = oend - obegin;
         else if(jj >= obegin && jj+1 >= oend) rowfact[jj-jmin] = oend - jj;

         if(rowfact[jj-jmin] < 0.)
            rowfact[jj-jmin] = 0.;

         if(debug >= 4)
         {
            printf("rowfact[%d]  %-g\n", jj, rowfact[jj]);
            fflush(stdout);
         }
      }

      for (j=0; j<input.naxes[1]; ++j)
      {
         if(debug >= 2)
         {
            printf("Reading input image row %5ld  (ibuffer %d)\n", fpixel[1], ibuffer);
            fflush(stdout);
         }


         /***********************************/
         /* Read a line from the input file */
         /***********************************/

         if(fits_read_pix(input.fptr, TDOUBLE, fpixel, nelements, &nan,
                          buffer, &nullcnt, &status))
         {
            mShrink_printFitsError(status);
            strcpy(returnStruct->msg, montage_msgstr);
            return returnStruct;
         }
         
         ++fpixel[1];

         /************************/
         /* For each input pixel */
         /************************/

         for (i=0; i<input.naxes[0]; ++i)
         {
            indata[ibuffer][i] = buffer[i];

            if(debug >= 4)
            {
               printf("input: line %5d / pixel %5d: indata[%d][%d] = %10.2e\n",
                  j, i, ibuffer, i, indata[ibuffer][i]);
               fflush(stdout);
            }
         }

         if(debug >= 4)
         {
            printf("---\n");
            fflush(stdout);
         }


         /**************************************************/
         /* If we have enough for the next line of output, */
         /* compute and write it                           */
         /**************************************************/

         if(j == jmax || fpixel[1] == input.naxes[1])
         {
            nelementso = output.naxes[0];

            for(k=0; k<nelementso; ++k)
            {
               /* OK, we are trying to determine the correct flux   */
               /* for output pixel k in output line l.  We have all */
               /* the input lines we need (modulo looping back from */
               /* indata[ibuffer])                                  */

               outdata[k] = nan;

               obegin =  (double)k     * xfactor;
               oend   = ((double)k+1.) * xfactor;

               imin = floor(obegin);
               imax = ceil (oend);

               if(debug >= 3)
               {
                  printf("\nimin = %4d, imax = %4d, jmin = %4d, jmax = %4d\n", imin, imax, jmin, jmax);
                  fflush(stdout);
               }

               flux = 0;
               area = 0;

               for(ii=imin; ii<=imax; ++ii)
               {
                  colfact[ii-imin] = 1.;

                       if(ii <= obegin && ii+1 <= oend) colfact[ii-imin] = ii+1. - obegin;
                  else if(ii <= obegin && ii+1 >= oend) colfact[ii-imin] = oend - obegin;
                  else if(ii >= obegin && ii+1 >= oend) colfact[ii-imin] = oend - ii;

                  if(colfact[ii-imin] < 0.)
                     colfact[ii-imin] = 0.;
               }

               for(jj=jmin; jj<=jmax; ++jj)
               {
                  if(rowfact[jj-jmin] == 0.)
                     continue;

                  for(ii=imin; ii<=imax; ++ii)
                  {
                     bufrow = (ibuffer - jmax + jj + nbuf) % nbuf;

                     if(!mNaN(indata[bufrow][ii]) && colfact[ii-imin] > 0.)
                     {
                        flux += indata[bufrow][ii] * colfact[ii-imin] * rowfact[jj-jmin];
                        area += colfact[ii-imin] * rowfact[jj-jmin];

                        if(debug >= 3)
                        {
                           printf("output[%d][%d] -> %10.2e (area: %10.2e) (using indata[%d][%d] = %10.2e, colfact[%d-%d] = %5.3f, rowfact[%d-%d] = %5.3f)\n", 
                              l, k, flux, area,
                              bufrow, ii, indata[bufrow][ii], 
                              ii, imin, colfact[ii-imin],
                              jj, jmin, rowfact[jj-jmin]);

                           fflush(stdout);
                        }
                     }
                  }

                  if(debug >= 3)
                  {
                     printf("---\n");
                     fflush(stdout);
                  }
               }

               if(area > 0.)
                  outdata[k] = flux/area;
               else
                  outdata[k] = nan;

               if(debug >= 3)
               {
                  printf("\nflux = %-g / area = %-g --> outdata[%d] = %-g\n",
                     flux, area, k, outdata[k]);
                  
                  fflush(stdout);
               }
            }

            if(fpixelo[1] <= output.naxes[1])
            {
               if(debug >= 2)
               {
                  printf("\nWRITE output image row %5ld\n===========================================\n", fpixelo[1]);
                  fflush(stdout);
               }

               if (fits_write_pix(output.fptr, TDOUBLE, fpixelo, nelementso, 
                                  (void *)(outdata), &status))
               {
                  mShrink_printFitsError(status);
                  strcpy(returnStruct->msg, montage_msgstr);
                  return returnStruct;
               }
            }

            ++fpixelo[1];

            ++l;

            obegin =  (double)l     * xfactor;
            oend   = ((double)l+1.) * xfactor;

            jmin = floor(obegin);
            jmax = ceil (oend);

            for(jj=jmin; jj<=jmax; ++jj)
            {
               rowfact[jj-jmin] = 1.;

                    if(jj <= obegin && jj+1 <= oend) rowfact[jj-jmin] = jj+1. - obegin;
               else if(jj <= obegin && jj+1 >= oend) rowfact[jj-jmin] = oend - obegin;
               else if(jj >= obegin && jj+1 >= oend) rowfact[jj-jmin] = oend - jj;

               if(rowfact[jj-jmin] < 0.)
                  rowfact[jj-jmin] = 0.;

               if(debug >= 4)
               {
                  printf("rowfact[%d-%d] -> %-g\n", jj, jmin, rowfact[jj-jmin]);
                  fflush(stdout);
               }
            }
         }

         ibuffer = (ibuffer + 1) % nbuf;
      }
   }


   /*******************/
   /* Close the files */
   /*******************/

   if(fits_close_file(input.fptr, &status))
   {
      mShrink_printFitsError(status);
      strcpy(returnStruct->msg, montage_msgstr);
      return returnStruct;
   }

   if(fits_close_file(output.fptr, &status))
   {
      mShrink_printFitsError(status);
      strcpy(returnStruct->msg, montage_msgstr);
      return returnStruct;
   }

   if(debug >= 1)
   {
      printf("FITS data image finalized\n"); 
      fflush(stdout);
   }

   time(&currtime);

   returnStruct->status = 0;

   sprintf(returnStruct->msg,  "time=%.0f",       (double)(currtime - start));
   sprintf(returnStruct->json, "{\"time\"=%.0f}", (double)(currtime - start));

   returnStruct->time = (double)(currtime - start);

   return returnStruct;
}
Exemple #6
0
double Girard()
{
   int    i, j, ibad;

   double area;
   double lon, lat;

   Vec    side[16];
   double ang [16];

   Vec    tmp;

   double pi, dtr, sumang, cosAng, sinAng;

   pi  = atan(1.0) * 4.;
   dtr = pi / 180.;

   sumang = 0.;

   if(nv < 3)
      return(0.);

   if(debug >= 4)
   {
      for(i=0; i<nv; ++i)
      {
	 lon = atan2(V[i].y, V[i].x)/dtr;
	 lat = asin(V[i].z)/dtr;

	 printf("Girard(): %3d [%13.6e,%13.6e,%13.6e] -> (%10.6f,%10.6f)\n", 
	    i, V[i].x, V[i].y, V[i].z, lon, lat);
	 
	 fflush(stdout);
      }
   }

   for(i=0; i<nv; ++i)
   {
      Cross (&V[i], &V[(i+1)%nv], &side[i]);

      (void) Normalize(&side[i]);
   }

   for(i=0; i<nv; ++i)
   {
      Cross (&side[i], &side[(i+1)%nv], &tmp);

      sinAng =  Normalize(&tmp);
      cosAng = -Dot(&side[i], &side[(i+1)%nv]);


      /* Remove center point of colinear segments */

      ang[i] = atan2(sinAng, cosAng);

      if(debug >= 4)
      {
	 if(i==0)
	    printf("\n");

	 printf("Girard(): angle[%d] = %13.6e -> %13.6e (from %13.6e / %13.6e)\n", i, ang[i], ang[i] - pi/2., sinAng, cosAng);
	 fflush(stdout);
      }

      if(ang[i] > pi - 0.0175)  /* Direction changes of less than */
      {                         /* a degree can be tricky         */
	 ibad = (i+1)%nv;

	 if(debug >= 4)
	 {
	    printf("Girard(): ---------- Corner %d bad; Remove point %d -------------\n", 
	       i, ibad);
	    fflush(stdout);
	 }

	 --nv;

	 for(j=ibad; j<nv; ++j)
	 {
	    V[j].x = V[j+1].x;
	    V[j].y = V[j+1].y;
	    V[j].z = V[j+1].z;
	 }

	 return(Girard());
      }

      sumang += ang[i];
   }

   area = sumang - (nv-2.)*pi;

   if(mNaN(area) || area < 0.)
      area = 0.;

   if(debug >= 4)
   {
      printf("\nGirard(): area = %13.6e [%d]\n\n", area, nv);
      fflush(stdout);
   }

   return(area);
}
Exemple #7
0
int main(int argc, char **argv)
{
   int       i, j, countRange, countNaN, status;
   int       haveMinMax, haveVal, writeOutput;
   long      fpixel[4], nelements;
   double   *inbuffer;
   double    NaNvalue;

   double    minblank, maxblank;
   double   *outbuffer;

   char     *end;


   /************************************************/
   /* 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] = 255;

   nan = value.d;


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

   fstatus = stdout;

   debug   = 0;
   haveVal = 0;

   writeOutput = 1;

   for(i=0; i<argc; ++i)
   {
      if(strcmp(argv[i], "-d") == 0)
      {
	 if(i+1 >= argc)
	 {
	    printf("[struct stat=\"ERROR\", msg=\"No debug level given\"]\n");
	    exit(1);
	 }

	 debug = strtol(argv[i+1], &end, 0);

	 if(end - argv[i+1] < strlen(argv[i+1]))
	 {
	    printf("[struct stat=\"ERROR\", msg=\"Debug level string is invalid: '%s'\"]\n", argv[i+1]);
	    exit(1);
	 }

	 if(debug < 0)
	 {
	    printf("[struct stat=\"ERROR\", msg=\"Debug level value cannot be negative\"]\n");
	    exit(1);
	 }

	 argv += 2;
	 argc -= 2;
      }

      if(strcmp(argv[i], "-v") == 0)
      {
	 if(i+1 >= argc)
	 {
	    printf("[struct stat=\"ERROR\", msg=\"No value given for NaN conversion\"]\n");
	    exit(1);
	 }

	 NaNvalue = strtod(argv[i+1], &end);

	 if(end - argv[i+1] < strlen(argv[i+1]))
	 {
	    printf("[struct stat=\"ERROR\", msg=\"NaN conversion value string is invalid: '%s'\"]\n", argv[i+1]);
	    exit(1);
	 }

	 haveVal = 1;

	 argv += 2;
	 argc -= 2;
      }
   }
   
   if (argc < 3) 
   {
      printf ("[struct stat=\"ERROR\", msg=\"Usage: %s [-d level][-v NaN-value] in.fits out.fits [minblank maxblank] (output file name '-' means no file)\"]\n", argv[0]);
      exit(1);
   }

   strcpy(input_file,  argv[1]);

   if(input_file[0] == '-')
   {
      printf ("[struct stat=\"ERROR\", msg=\"Invalid input file '%s'\"]\n", input_file);
      exit(1);
   }

   strcpy(output_file, argv[2]);

   if(output_file[0] == '-')
      writeOutput = 0;


   haveMinMax = 0;

   minblank = -2;
   maxblank =  2;

   if(argc > 3)
   {
      haveMinMax = 1;

      minblank = strtod(argv[3], &end);

      if(end < argv[3] + strlen(argv[3]))
      {
	 printf ("[struct stat=\"ERROR\", msg=\"min blank value string is not a number\"]\n");
	 exit(1);
      }

      maxblank = strtod(argv[4], &end);

      if(end < argv[4] + strlen(argv[4]))
      {
	 printf ("[struct stat=\"ERROR\", msg=\"max blank value string is not a number\"]\n");
	 exit(1);
      }
   }

   if(debug >= 1)
   {
      printf("input_file       = [%s]\n", input_file);
      printf("output_file      = [%s]\n", output_file);
      printf("minblank         = %-g\n",  minblank);
      printf("maxblank         = %-g\n",  maxblank);
      fflush(stdout);
   }


   /************************/
   /* Read the input image */
   /************************/

   time(&currtime);
   start = currtime;

   readFits(input_file);

   if(debug >= 1)
   {
      printf("input.naxes[0]       =  %ld\n",   input.naxes[0]);
      printf("input.naxes[1]       =  %ld\n",   input.naxes[1]);
      printf("input.crpix1         =  %-g\n",   input.crpix1);
      printf("input.crpix2         =  %-g\n",   input.crpix2);

      fflush(stdout);
   }

   output.naxes[0] = input.naxes[0];
   output.naxes[1] = input.naxes[1];
   output.crpix1   = input.crpix1;
   output.crpix2   = input.crpix2;


   if(writeOutput)
   {
      /********************************/
      /* Create the output FITS files */
      /********************************/

      remove(output_file);               

      status = 0;
      if(fits_create_file(&output.fptr, output_file, &status)) 
	 printFitsError(status);           

      if(debug >= 1)
      {
	 printf("\nFITS output file created (not yet populated)\n"); 
	 fflush(stdout);
      }


      /********************************/
      /* Copy all the header keywords */
      /* from the input to the output */
      /********************************/

      if(fits_copy_header(input.fptr, output.fptr, &status))
	 printFitsError(status);           

      if(debug >= 1)
      {
	 printf("Header keywords copied to FITS output file\n\n"); 
	 fflush(stdout);
      }


      /***************************/
      /* Modify BITPIX to be -64 */
      /***************************/

      if(fits_update_key_lng(output.fptr, "BITPIX", -64,
			     (char *)NULL, &status))
	 printFitsError(status);
   }


   /*****************************************************/ 
   /* Allocate memory for the input/output image pixels */ 
   /* (same size as the input image)                    */ 
   /*****************************************************/ 

   outbuffer = (double *)malloc(output.naxes[0] * sizeof(double));

   if(debug >= 1)
   {
      printf("%ld bytes allocated for row of output image pixels\n", 
	 output.naxes[0] * sizeof(double));
      fflush(stdout);
   }

   inbuffer = (double *)malloc(input.naxes[0] * sizeof(double));

   if(debug >= 1)
   {
      printf("%ld bytes allocated for row of input image pixels\n", 
	 input.naxes[0] * sizeof(double));
      fflush(stdout);
   }


   /*****************************/
   /* Loop over the input lines */
   /*****************************/

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

   nelements = input.naxes[0];

   status = 0;

   countRange = 0;
   countNaN   = 0;

   for (j=0; j<input.naxes[1]; ++j)
   {
      if(debug >= 2)
      {
	 if(debug >= 3)
	    printf("\n");

	 printf("\rProcessing input row %5d [So far rangeCount=%d, nanCount=%d]",
	    j, countRange, countNaN);

	 if(debug >= 3)
	    printf("\n");

	 fflush(stdout);
      }

      for (i=0; i<output.naxes[0]; ++i)
	 outbuffer[i] = 0.;


      /***********************************/
      /* Read a line from the input file */
      /***********************************/

      if(fits_read_pix(input.fptr, TDOUBLE, fpixel, nelements, NULL,
		       inbuffer, NULL, &status))
	 printFitsError(status);
      

      /************************/
      /* For each input pixel */
      /************************/

      for (i=0; i<input.naxes[0]; ++i)
      {
	 if(mNaN(inbuffer[i]) && haveVal) 
         {
            ++countNaN;

	    outbuffer[i] = NaNvalue;

            if(debug >= 3)
            {
	       printf("pixel[%d][%d] converted to %-g\n", j, i, NaNvalue);
	       fflush(stdout);
	    }
         }

	 else if(haveMinMax
	      && inbuffer[i] >= minblank 
	      && inbuffer[i] <= maxblank)
	 {
            ++countRange;

            if(haveVal) 
	    {
	       ++countNaN;

	       outbuffer[i] = NaNvalue;

               if(debug >= 3)
               {
	          printf("pixel[%d][%d] converted to NaN -> %-g\n", j, i, NaNvalue);
	          fflush(stdout);
	       }
	    }
            else
	    {
	       outbuffer[i] = nan;

               if(debug >= 3)
               {
	          printf("pixel[%d][%d] converted to NaN\n", j, i);
	          fflush(stdout);
	       }
	    }
	 }
	 else
	    outbuffer[i] = inbuffer[i];
      }


      /***************************/
      /* Write the output buffer */
      /***************************/

      if(writeOutput)
      {
	 if (fits_write_pix(output.fptr, TDOUBLE, fpixel, nelements, 
			    outbuffer, &status))
	    printFitsError(status);
      }

      ++fpixel[1];
   }


   if(debug >= 1)
   {
      time(&currtime);
      printf("\nDone copying data (%d seconds)\n", 
	 (int)(currtime - start));
      fflush(stdout);
   }


   /************************/
   /* Close the FITS files */
   /************************/

   if(fits_close_file(input.fptr, &status))
      printFitsError(status);

   if(writeOutput)
   {
      if(fits_close_file(output.fptr, &status))
	 printFitsError(status);           
   }

   if(debug >= 1)
   {
      time(&currtime);
      printf("Done (%d seconds total)\n", (int)(currtime - start));
      fflush(stdout);
   }

   free(inbuffer);
   free(outbuffer);

   printf("[struct stat=\"OK\", rangeCount=%d, nanCount=%d]\n", countRange, countNaN);
   fflush(stdout);

   exit(0);
}
Exemple #8
0
/*
 * Use Girard's theorem to compute the area of a sky polygon.
 */
double Girard() {
  int i, j, ibad;

  double area;
  double lon, lat;

  Vec side[16];
  double ang[16];

  Vec tmp;

  double sumang, cosAng, sinAng;

  sumang = 0;

  if (nv < 3)
    return 0;

  if (DEBUG >= 4) {
    for (i = 0; i < nv; ++i) {
      lon = atan2(V[i].y, V[i].x) / DEG_TO_RADIANS;
      lat = asin(V[i].z) / DEG_TO_RADIANS;

      printf("Girard(): %3d [%13.6e,%13.6e,%13.6e] -> (%10.6f,%10.6f)\n", i,
             V[i].x, V[i].y, V[i].z, lon, lat);

      fflush(stdout);
    }
  }

  for (i = 0; i < nv; ++i) {
    Cross(&V[i], &V[(i + 1) % nv], &side[i]);

    Normalize(&side[i]);
  }

  for (i = 0; i < nv; ++i) {
    Cross(&side[i], &side[(i + 1) % nv], &tmp);

    sinAng = Normalize(&tmp);
    cosAng = -Dot(&side[i], &side[(i + 1) % nv]);

    // Remove center point of colinear segments

    ang[i] = atan2(sinAng, cosAng);

    if (DEBUG >= 4) {
      if (i == 0)
        printf("\n");

      printf("Girard(): angle[%d] = %13.6e -> %13.6e (from %13.6e / %13.6e)\n",
             i, ang[i], ang[i] - M_PI / 2., sinAng, cosAng);
      fflush(stdout);
    }

    // Direction changes of less than a degree can be tricky
    if (ang[i] > M_PI - 0.0175) {
      ibad = (i + 1) % nv;

      if (DEBUG >= 4) {
        printf("Girard(): ---------- Corner %d bad; "
               "Remove point %d -------------\n",
               i, ibad);
        fflush(stdout);
      }

      --nv;

      for (j = ibad; j < nv; ++j) {
        V[j].x = V[j + 1].x;
        V[j].y = V[j + 1].y;
        V[j].z = V[j + 1].z;
      }

      return (Girard());
    }

    sumang += ang[i];
  }

  area = sumang - (nv - 2.) * M_PI;

  if (mNaN(area) || area < 0.)
    area = 0.;

  if (DEBUG >= 4) {
    printf("\nGirard(): area = %13.6e [%d]\n\n", area, nv);
    fflush(stdout);
  }

  return area;
}