Пример #1
0
int main(int argc, char **argv)
{
   int       i, j, l, m, c, count, ismag, ncol;
   int       dl, dm, width, haveFlux, isImg, csys;
   int       side, ibegin, iend, nstep, useCenter;
   int       racol, deccol, fluxcol;
   int       ra1col, dec1col;
   int       ra2col, dec2col;
   int       ra3col, dec3col;
   int       ra4col, dec4col;
   long      fpixel, nelements;
   double    rac, decc;
   double    ra[4], dec[4];
   double    x,  y,  z;
   double    x0, y0, z0;
   double    x1, y1, z1;
   double    oxpix, oypix, equinox;
   int       offscl;
   double    ilon;
   double    ilat;
   double    pixscale, len, sideLength, dtr;
   double    offset;

   double    xn, yn, zn;
   double    ran, decn;
   double    sina, cosa;
   double    sind, cosd;

   double    a11, a12, a13;
   double    a21, a22, a23;
   double    a31, a32, a33;

   double    x0p, y0p, z0p;
   double    x1p, y1p, z1p;

   double    lon0, lon1;
   double    xp, yp;
   double    lon;

   double    pixel_value;

   double    weights[5][5];

   double    weights3[5][5] = {{0.0, 0.0, 0.0, 0.0, 0.0},
                               {0.0, 0.1, 0.2, 0.1, 0.0},
                               {0.0, 0.2, 1.0, 0.2, 0.0},
                               {0.0, 0.1, 0.2, 0.1, 0.0},
                               {0.0, 0.0, 0.0, 0.0, 0.0}};

   double    weights5[5][5] = {{0.0, 0.1, 0.2, 0.1, 0.0},
                               {0.1, 0.3, 0.5, 0.3, 0.1},
                               {0.2, 0.5, 1.0, 0.5, 0.2},
                               {0.1, 0.3, 0.5, 0.3, 0.1},
                               {0.0, 0.1, 0.2, 0.1, 0.0}};

   double  **data;

   int       status = 0;

   char      input_file   [MAXSTR];
   char      colname      [MAXSTR];
   char      output_file  [MAXSTR];
   char      template_file[MAXSTR];

   int       bitpix = DOUBLE_IMG; 
   long      naxis  = 2;  

   double    sumweights;
   double    refmag;

   dtr = atan(1.0)/45.;


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

   ismag  = 0;
   opterr = 0;

   useCenter = 0;

   strcpy(colname, "");

   while ((c = getopt(argc, argv, "pm:d:w:c:")) != EOF) 
   {
      switch (c) 
      {
         case 'm':
	    ismag = 1;
	    refmag = atof(optarg);
            break;

         case 'd':
            debug = debugCheck(optarg);
            break;

         case 'w':
	    width  = atoi(optarg);
            break;

         case 'c':
            strcpy(colname, optarg);
            break;

         case 'p':
            useCenter = 1;
            break;

         default:
	    printf("[struct stat=\"ERROR\", msg=\"Usage: %s [-c column][-m refmag][-d level][-w size] in.tbl out.fits hdr.template\"]\n", argv[0]);
            exit(1);
            break;
      }
   }

   if (argc - optind < 3) 
   {
      printf("[struct stat=\"ERROR\", msg=\"Usage: %s [-c column][-m refmag][-d level][-w size] in.tbl out.fits hdr.template\"]\n", argv[0]);
      exit(1);
   }

   strcpy(input_file,    argv[optind]);
   strcpy(output_file,   argv[optind+1]);
   strcpy(template_file, argv[optind+2]);

   if(debug >= 1)
   {
      printf("input_file    = [%s]\n", input_file);
      printf("colname       = [%s]\n", colname);
      printf("output_file   = [%s]\n", output_file);
      printf("template_file = [%s]\n", template_file);
      printf("width         = %d\n",   width);
      printf("ismag         = %d\n",   ismag);
      fflush(stdout);
   }


   /********************************************/
   /* Set the weights for spreading the points */
   /********************************************/

   sumweights = 0.;

   for(i=0; i<5; ++i)
   {
      for(j=0; j<5; ++j)
      {
	 if(width == 3)
	    sumweights += weights3[i][j];

	 else if(width == 5)
	    sumweights += weights5[i][j];
      }
   }

   for(i=0; i<5; ++i)
   {
      for(j=0; j<5; ++j)
      {
	 if(width == 3)
	    weights[i][j] = weights3[i][j]/sumweights;

	 else if(width == 5)
	    weights[i][j] = weights5[i][j]/sumweights;

	 else 
	    weights[i][j] = 0.;
      }
   }

   if(width != 3 && width != 5)
      weights[2][2] = 1.;




   /************************************************/ 
   /* Open the table file and find the data column */ 
   /************************************************/ 

   ncol = topen(input_file);

   if(ncol <= 0)
   {
      printf("[struct stat=\"ERROR\", msg=\"Can't open input table %s\"]\n", input_file);
      exit(0);
   }

   racol   = tcol( "ra");
   deccol  = tcol("dec");

    ra1col = tcol( "ra1");
   dec1col = tcol("dec1");
    ra2col = tcol( "ra2");
   dec2col = tcol("dec2");
    ra3col = tcol( "ra3");
   dec3col = tcol("dec3");
    ra4col = tcol( "ra4");
   dec4col = tcol("dec4");

   haveFlux = 1;
   if(strlen(colname) == 0)
      haveFlux = 0;
   else
      fluxcol = tcol(colname);

   isImg = 1;

   if(ra1col < 0 || dec1col < 0
   || ra2col < 0 || dec2col < 0
   || ra3col < 0 || dec3col < 0
   || ra4col < 0 || dec4col < 0)
      isImg = 0;

   if(useCenter)
      isImg = 0;

   if(!isImg)
   {
      if(racol <  0)
      {
	 printf("[struct stat=\"ERROR\", msg=\"Can't find column 'ra'\"]\n");
	 exit(0);
      }

      if(deccol <  0)
      {
	 printf("[struct stat=\"ERROR\", msg=\"Can't find column 'dec'\"]\n");
	 exit(0);
      }
   }

   if(haveFlux && fluxcol <  0)
   {
      printf("[struct stat=\"ERROR\", msg=\"Can't find column '%s'\"]\n", colname);
      exit(0);
   }


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

   readTemplate(template_file);

   pixscale = fabs(output.wcs->xinc);

   if(fabs(output.wcs->yinc) > pixscale)
      pixscale = fabs(output.wcs->yinc);

   csys = EQUJ;

   if(strncmp(output.wcs->c1type, "RA",   2) == 0)
      csys = EQUJ;
   if(strncmp(output.wcs->c1type, "GLON", 4) == 0)
      csys = GAL;
   if(strncmp(output.wcs->c1type, "ELON", 4) == 0)
      csys = ECLJ;

   equinox = output.wcs->equinox;

   if(debug >= 1)
   {
      printf("output.naxes[0] =  %ld\n", output.naxes[0]);
      printf("output.naxes[1] =  %ld\n", output.naxes[1]);
      printf("output.sys      =  %d\n",  output.sys);
      printf("output.epoch    =  %-g\n", output.epoch);
      printf("output proj     =  %s\n",  output.wcs->ptype);
      printf("output crval[0] =  %-g\n", output.wcs->crval[0]);
      printf("output crval[1] =  %-g\n", output.wcs->crval[1]);
      printf("output crpix[0] =  %-g\n", output.wcs->crpix[0]);
      printf("output crpix[1] =  %-g\n", output.wcs->crpix[1]);
      printf("output cdelt[0] =  %-g\n", output.wcs->cdelt[0]);
      printf("output cdelt[1] =  %-g\n", output.wcs->cdelt[1]);

      fflush(stdout);
   }


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

   data = (double **)malloc(output.naxes[1] * sizeof(double *));

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

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


   /**********************************************************/
   /* Initialize pointers to the start of each row of pixels */
   /**********************************************************/

   for(i=1; i<output.naxes[1]; i++)
      data[i] = data[i-1] + output.naxes[0];

   if(debug >= 1)
   {
      printf("pixel line pointers populated\n"); 
      fflush(stdout);
   }

   for (j=0; j<output.naxes[1]; ++j)
   {
      for (i=0; i<output.naxes[0]; ++i)
      {
	 data[j][i] = 0.;
      }
   }


   /************************/
   /* Create the FITS file */
   /************************/

   remove(output_file);               

   if(fits_create_file(&output.fptr, output_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("FITS image created (not yet populated)\n"); 
      fflush(stdout);
   }


   /*****************************/
   /* Loop over the input files */
   /*****************************/

   time(&currtime);
   start = currtime;


   /*******************/
   /* For each source */
   /*******************/

   count = 0;

   while(tread() >= 0)
   {
      ++count;

      if(isImg)
      {
	 if(debug && count/1000*1000 == count)
	 {
	    printf("%9d image outlines processed\n", count);
	    fflush(stdout);
	 }

	 ra [0] = atof(tval( ra1col));
	 dec[0] = atof(tval(dec1col));
	 ra [1] = atof(tval( ra2col));
	 dec[1] = atof(tval(dec2col));
	 ra [2] = atof(tval( ra3col));
	 dec[2] = atof(tval(dec3col));
	 ra [3] = atof(tval( ra4col));
	 dec[3] = atof(tval(dec4col));

	 for(side=0; side<4; ++side)
	 {
	    ibegin = side;
	    iend   = (side+1)%4;

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

	    x1 = cos(ra[iend]*dtr) * cos(dec[iend]*dtr);
	    y1 = sin(ra[iend]*dtr) * cos(dec[iend]*dtr);
	    z1 = sin(dec[iend]*dtr);

	    xn = y0*z1 - z0*y1;
	    yn = z0*x1 - x0*z1;
	    zn = x0*y1 - y0*x1;

	    len = sqrt(xn*xn + yn*yn + zn*zn);

	    xn = xn / len;
	    yn = yn / len;
	    zn = zn / len;

	    ran  = atan2(yn, xn);
	    decn = asin(zn);

	    sina = sin(ran);
	    cosa = cos(ran);

	    sind = sin(decn);
	    cosd = cos(decn);

	    a11 =  cosa*sind;
	    a12 =  sina*sind;
	    a13 = -cosd;
	    a21 = -sina;
	    a22 =  cosa;
	    a23 =  0.;
	    a31 =  cosa*cosd;
	    a32 =  sina*cosd;
	    a33 =  sind;

	    x0p =  a11*x0 + a12*y0 + a13*z0;
	    y0p =  a21*x0 + a22*y0 + a23*z0;
	    z0p =  a31*x0 + a32*y0 + a33*z0;

	    x1p =  a11*x1 + a12*y1 + a13*z1;
	    y1p =  a21*x1 + a22*y1 + a23*z1;
	    z1p =  a31*x1 + a32*y1 + a33*z1;

	    lon0 = atan2(y0p, x0p);
	    lon1 = atan2(y1p, x1p);

	    if(fabs(lon1-lon0)/dtr > 180.)
	    {
	       if(lon0 < 0.) lon0 += 360.*dtr;
	       if(lon1 < 0.) lon1 += 360.*dtr;
	    }

	    sideLength = acos(x0*x1 + y0*y1 + z0*z1) / dtr;

            offset = pixscale/2.*dtr;
	    if(lon0 > lon1)
	       offset = -offset;

	    nstep = (lon1 - lon0)/offset;

	    lon = lon0;
	    for(i=0; i<nstep; ++i)
	    {
	       lon += offset;

	       xp = cos(lon);
	       yp = sin(lon);

	       x = a11*xp + a21*yp;
	       y = a12*xp + a22*yp;
	       z = a13*xp + a23*yp;

	       rac  = atan2(y,x)/dtr;
	       decc = asin(z)/dtr;

	       convertCoordinates (EQUJ,   2000.,    rac,   decc,
				   csys, equinox, &ilon, &ilat, 0.);

               offscl = 0;

	       wcs2pix(output.wcs, ilon, ilat, &oxpix, &oypix, &offscl);

               fixxy(&oxpix, &oypix, &offscl);

	       if(haveFlux)
		  pixel_value = atof(tval(fluxcol));
	       else
		  pixel_value = 1;

	       l = (int)(oxpix + 0.5) - 1;
	       m = (int)(oypix + 0.5) - 1;

	       if(!offscl)
		  data[m][l] = pixel_value;
	    }
	 }
      }
      else
      {
	 if(debug && count/1000*1000 == count)
	 {
	    printf("%9d sources processed\n", count);
	    fflush(stdout);
	 }

	 rac  = atof(tval(racol));
	 decc = atof(tval(deccol));

	 convertCoordinates (EQUJ,   2000.,    rac,   decc,
			     csys, equinox, &ilon, &ilat, 0.);

	 if(haveFlux)
	    pixel_value = atof(tval(fluxcol));
	 else
	    pixel_value = 1;

	 if(ismag)
	    pixel_value = pow(10., 0.4 * (refmag - pixel_value));

	 wcs2pix(output.wcs, ilon, ilat, &oxpix, &oypix, &offscl);

	 if(pixel_value < 1.e10)
	 {
	    if(debug >= 3)
	    {
	       printf(" value = %11.3e at coord = (%12.8f,%12.8f)", pixel_value, ilon, ilat);

	       if(offscl)
	       {
		  printf(" -> opix = (%7.1f,%7.1f) OFF SCALE\n",
		     oxpix, oypix);
		  fflush(stdout);
	       }
	       else
	       {
		  printf(" -> opix = (%7.1f,%7.1f)\n",
		     oxpix, oypix);
		  fflush(stdout);
	       }
	    }
	    else if(pixel_value > 1000000.)
	    {
	       printf(" value = %11.3e at coord = (%12.8f,%12.8f)", pixel_value, ilon, ilat);

	       if(offscl)
	       {
		  printf(" -> opix = (%7.1f,%7.1f) OFF SCALE\n",
		     oxpix, oypix);
		  fflush(stdout);
	       }
	       else
	       {
		  printf(" -> opix = (%7.1f,%7.1f)\n",
		     oxpix, oypix);
		  fflush(stdout);
	       }
	    }

	    if(!offscl)
	    {
	       l = (int)(oxpix + 0.5) - 1;
	       m = (int)(oypix + 0.5) - 1;

	       if(l < 0 || m < 0 || l >= output.naxes[0] || m >= output.naxes[1])
	       {
		  /*
		  printf("ERROR: l=%d, m=%d\n", l, m);
		  fflush(stdout);
		  */
	       }

	       else
	       {
		  for(dl=-2; dl<=2; ++dl)
		  {
		     if(l+dl < 0 || l+dl>= output.naxes[0])
			continue;

		     for(dm=-2; dm<=2; ++dm)
		     {
			if(m+dm < 0 || m+dm>= output.naxes[1])
			   continue;

			data[m+dm][l+dl] += weights[dm+2][dl+2] * pixel_value;
		     }
		  }
	       }
	    }
	 }
      }
   }


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

   fpixel    = 1;
   nelements = output.naxes[0] * output.naxes[1];

   if (fits_write_img(output.fptr, TDOUBLE, fpixel, nelements, data[0], &status))
      printFitsError(status);

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


   /*************************************/
   /* Add keywords 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 image\n"); 
      fflush(stdout);
   }


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

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

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


   time(&currtime);

   printf("[struct stat=\"OK\", time=%d]\n", 
      (int)(currtime - start));
   fflush(stdout);

   exit(0);
}
Пример #2
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);
}