Exemplo n.º 1
0
int extractAvePlane (char *cubepath, char *impath, int iplane, int nplaneave,
    int *splaneave, int *eplaneave, char *errmsg)
{
    struct stat     buf;
    struct FitsHdr  hdr;

    char   str[1024];
    char   cmd[1024];
    
    int    bitpix;
    int    istatus;
    
    int    nhdu, hdutype, hdunum;

    int    nelements;
   
    int    naxis3;
    int    l;
    int    j;
    int    i;
    int    jj;
    int    nullcnt;

    int    splane;
    int    eplane;

    long   fpixel[4];
    long   fpixelo[4];

    double *fitsbuf;
    double *imbuff;
    
    fitsfile  *infptr;
    fitsfile  *outfptr;

    
    int    debugfile = 1;
    int    debugfile1 = 0;


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


    if ((debugfile) && (fp_debug != (FILE *)NULL)) {

	fprintf (fp_debug, "\nEnter extractAvePlane: cubepath= [%s]\n", 
	    cubepath);
	fprintf (fp_debug, "iplane= [%d]\n", iplane);
	fprintf (fp_debug, "nplaneave= [%d]\n", nplaneave);
	fprintf (fp_debug, "impath= [%s]\n", impath);
        fflush (fp_debug);
    }

    splane = iplane - nplaneave/2;
    eplane = splane + nplaneave - 1;

    if ((debugfile) && (fp_debug != (FILE *)NULL)) {

	fprintf (fp_debug, "splane= [%d] eplane= [%d]\n", splane, eplane);
        fflush (fp_debug);
    }

    istatus = 0;
    if (fits_open_file (&infptr, cubepath, READONLY, &istatus)) {

        if ((debugfile) && (fp_debug != (FILE *)NULL)) {

	    fprintf (fp_debug, "istatus= [%d]\n", istatus);
            fflush (fp_debug);
	}

	sprintf (errmsg, "Failed to open FITS file [%s]\n", cubepath);
	return (-1);
    } 
   
    hdunum = 1; 
    nhdu = 0;
    istatus = 0;
    istatus = fits_get_num_hdus (infptr, &nhdu, &istatus);
    
    if ((debugfile) && (fp_debug != (FILE *)NULL)) {

	fprintf (fp_debug, 
	    "returned fits_get_hdu_num: istatus= [%d] nhdu= [%d]\n",
	    istatus, nhdu);
        fflush (fp_debug);
    }

    if (hdunum > nhdu) {

        sprintf (errmsg, "fname [%s] doesn't contain any HDU", cubepath);
	return (-1);
    }


/*
    Read fits keywords from the first HDU
*/
    hdutype = 0;
    istatus = 0;
    istatus = fits_movabs_hdu (infptr, hdunum, &hdutype, &istatus);

    if ((debugfile) && (fp_debug != (FILE *)NULL)) {

	fprintf (fp_debug, 
	    "returned fits_movabs_hdu: istatus= [%d] hdutype= [%d]\n",
	    istatus, hdutype);
        fflush (fp_debug);
    }

/*
    Read fits keywords
*/
    istatus = 0;
    istatus = fits_read_key (infptr, TSTRING, "simple", str, (char *)NULL, 
        &istatus);
    
    if (istatus == KEY_NO_EXIST) {
        sprintf (errmsg, "keyword SIMPLE not found in fits header");
        return (-1);
    }
   
    if ((strcmp (str, "T") != 0) && (strcmp (str, "F") != 0)) {
        sprintf (errmsg, "keyword SIMPLE must be T or F");
        return (-1);
    }

    istatus = 0;
    istatus = fits_read_key (infptr, TSTRING, "bitpix", str, (char *)NULL, 
        &istatus);
    
    if (istatus == KEY_NO_EXIST) {
        sprintf (errmsg, "keyword BITPIX not found in fits header");
        return (-1);
    }
  
    istatus = str2Integer (str, &bitpix, errmsg);
    if (istatus != 0) {
        sprintf (errmsg, "keyword BITPIX must be an integer");
        return (-1);
    }

    if ((bitpix != 8) &&
        (bitpix != 16) &&
        (bitpix != 32) &&
        (bitpix != 64) &&
        (bitpix != -32) &&
        (bitpix != -64)) {
        
	sprintf (errmsg, 
	    "keyword BITPIX value must be 8, 16, 32, 64, -32, -64");
        return (-1);
    }

    hdr.bitpix = bitpix;

    istatus = 0;
    istatus = fits_read_key (infptr, TSTRING, "naxis", str, (char *)NULL, 
        &istatus);
        
    if (istatus == KEY_NO_EXIST) {
        sprintf (errmsg, "keyword naxis not found in fits header");
        return (-1);
    }

    if ((debugfile) && (fp_debug != (FILE *)NULL)) {

        fprintf (fp_debug, "str= [%s]\n", str);
        fflush (fp_debug);
    }
    istatus = str2Integer (str, &hdr.naxis, errmsg);
    if (istatus < 0) {
        sprintf (errmsg, "Failed to convert naxis to integer");
        return (-1);
    }
    
    if ((debugfile) && (fp_debug != (FILE *)NULL)) {

        fprintf (fp_debug, "naxis= [%d]\n", hdr.naxis);
        fflush (fp_debug);
    }


    istatus = 0;
    istatus = fits_read_key (infptr, TSTRING, "naxis1", str, (char *)NULL, 
        &istatus);
        
    if ((debugfile) && (fp_debug != (FILE *)NULL)) {

        fprintf (fp_debug, "returned fits_read_key: istatus= [%d]\n", istatus);
        fflush (fp_debug);
    }
        
    if (istatus == KEY_NO_EXIST) {
        sprintf (errmsg, "keyword naxis1 not found in fits header");
        return (-1);
    }

    if ((debugfile) && (fp_debug != (FILE *)NULL)) {

        fprintf (fp_debug, "str= [%s]\n", str);
        fflush (fp_debug);
    }

    istatus = str2Integer (str, &hdr.ns, errmsg);
    
    if (istatus < 0) {
        sprintf (errmsg, "Failed to convert naxis1 string to integer");
        return (-1);
    }
    hdr.naxes[0] = hdr.ns;

    istatus = 0;
    istatus = fits_read_key (infptr, TSTRING, "naxis2", str, 
        (char *)NULL, &istatus);
        
    if ((debugfile) && (fp_debug != (FILE *)NULL)) {

        fprintf (fp_debug, "returned fits_read_key: istatus= [%d]\n", istatus);
        fflush (fp_debug);
    }
        
    if (istatus == KEY_NO_EXIST) {
        sprintf (errmsg, "keyword naxis2 not found in fits header");
        return (-1);
    }
    
    if ((debugfile) && (fp_debug != (FILE *)NULL)) {

        fprintf (fp_debug, "str= [%s]\n", str);
        fflush (fp_debug);
    }

    istatus = str2Integer (str, &hdr.nl, errmsg);
    
    if (istatus < 0) {
        sprintf (errmsg, "Failed to convert naxis2 string to integer");
        return (-1);
    }
    hdr.naxes[1] = hdr.nl;

    
    if ((debugfile) && (fp_debug != (FILE *)NULL)) {

        fprintf (fp_debug, "ns= [%d] nl= [%d]\n", hdr.ns, hdr.nl);
        fflush (fp_debug);
    }

    hdr.nplane = 1;

    if (hdr.naxis > 2) {
    
        istatus = 0;
        istatus = fits_read_key (infptr, TSTRING, "naxis3", str, 
            (char *)NULL, &istatus);
        
        if ((debugfile) && (fp_debug != (FILE *)NULL)) {

            fprintf (fp_debug, "returned fits_read_key: istatus= [%d]\n", 
	        istatus);
            fflush (fp_debug);
        }
        
        if (istatus == KEY_NO_EXIST) {
            sprintf (errmsg, "keyword naxis3 not found in fits header");
            return (-1);
        }
    
        if ((debugfile) && (fp_debug != (FILE *)NULL)) {

            fprintf (fp_debug, "str= [%s]\n", str);
            fflush (fp_debug);
        }

        istatus = str2Integer (str, &hdr.naxes[2], errmsg);
    
        if (istatus < 0) {
            sprintf (errmsg, "Failed to convert naxis3 string to integer");
            return (-1);
        }
        hdr.nplane = hdr.naxes[2];
    
        if ((debugfile) && (fp_debug != (FILE *)NULL)) {

            fprintf (fp_debug, "naxes[2]= [%d]\n", hdr.naxes[2]);
            fflush (fp_debug);
        }
    }
    if ((debugfile) && (fp_debug != (FILE *)NULL)) {

        fprintf (fp_debug, "nplane= [%d]\n", hdr.nplane);
        fflush (fp_debug);
    }


    istatus = stat (impath, &buf);
    if ((debugfile) && (fp_debug != (FILE *)NULL)) {
        fprintf (fp_debug, "impath exists? : istatus= [%d]\n", istatus);
        fflush (fp_debug); 
    }

    if (istatus >= 0) {
        sprintf (cmd, "unlink %s", impath);
	istatus = system (cmd);
    }	

/*
    Create output fits file
*/
    istatus = 0;
    if (fits_create_file (&outfptr, impath, &istatus)) {
	    
        sprintf (errmsg, "Failed to create output fitsfile [%s]\n", impath);
        
	if ((debugfile) && (fp_debug != (FILE *)NULL)) {
            fprintf (fp_debug, "err: [%s]\n", errmsg);
	    fflush (fp_debug);
        }
	return (-1);
    }

    if ((debugfile) && (fp_debug != (FILE *)NULL)) {
	fprintf (fp_debug, "outptr created\n");
        fflush (fp_debug);
    }


/* 
    Copy input fits header to output fitsfile
*/
    istatus = 0;
    if (fits_copy_header (infptr, outfptr, &istatus)) {

        strcpy (errmsg, "Failed to copy fitshdr\n");
        
	if ((debugfile) && (fp_debug != (FILE *)NULL)) {
            fprintf (fp_debug, "err: [%s]\n", errmsg);
	    fflush (fp_debug);
        }
	return (-1);
    }

/*
    Update header keyword NAXIS3
*/
    naxis3 = 1;
    istatus = 0;
    if (fits_update_key_lng(outfptr, "NAXIS3", naxis3, (char *)NULL, 
        &istatus)) {
	
        strcpy (errmsg, "Failed to update keyword NAXIS3\n");
	return (-1);
    }

    istatus = 0;
    if (fits_close_file (infptr, &istatus)) {
        sprintf (errmsg, "Failed to close cubepath [%s]\n", cubepath);
        return (-1); 
    }
    
    if ((debugfile) && (fp_debug != (FILE *)NULL)) {
	        
	fprintf (fp_debug, "cubepath= [%s]\n", cubepath);
        fflush (fp_debug);
    }

    istatus = 0;
    if (fits_open_file (&infptr, cubepath, READONLY, &istatus)) {

        if ((debugfile) && (fp_debug != (FILE *)NULL)) {

	    fprintf (fp_debug, "istatus= [%d]\n", istatus);
            fflush (fp_debug);
	}

	sprintf (errmsg, "Failed to open FITS file [%s]\n", cubepath);
	return (-1);
    } 
  
/*
    Create imbuff for average image
*/
    imbuff = (double *)malloc (hdr.ns*hdr.nl*sizeof(double));
    for (i=0; i<hdr.nl*hdr.ns; i++) {
        imbuff[i] = 0.;
    }


/*
    Read data from nth plane and write to output fitsfile
*/
    nelements = hdr.ns;
       
    if ((debugfile) && (fp_debug != (FILE *)NULL)) {

	fprintf (fp_debug, "iplane= [%d]\n", iplane);
        fflush (fp_debug);
    }

    fitsbuf  = (double *)malloc(hdr.ns*sizeof(double));

    if (splane < 1)
        splane = 1;
    
    if (eplane > hdr.nplane)
        eplane = hdr.nplane;

    for (l=splane; l<=eplane; l++) { 
    
        fpixel[0] = 1;
        fpixel[1] = 1;
        fpixel[2] = l;
        fpixel[3] = 1;

        for (j=0; j<hdr.nl; j++) {

	    if (j == 0) {
	        if ((debugfile1) && (fp_debug != (FILE *)NULL)) {
	        
	            fprintf (fp_debug, "l= [%d] fpixel[2]= [%ld]\n", 
		        l, fpixel[2]);
                    fflush (fp_debug);
	        }
            }

	    if (fits_read_pix (infptr, TDOUBLE, fpixel, nelements, &nan,
                fitsbuf, &nullcnt, &istatus)) {
	        break;
	    }
            
	    if (j == 10) {
	        if ((debugfile1) && (fp_debug != (FILE *)NULL)) {
                    for (i=0; i<hdr.ns; i++) {
	                fprintf (fp_debug, "j= [%d] i= [%d] fitsbuf= [%lf]\n",
	                    j, i, fitsbuf[i]);
	                fprintf (fp_debug, "fitsbuf/nplaneave= [%lf]\n",
	                    fitsbuf[i]/nplaneave);
		    }
                    fflush (fp_debug);
	        }
            }         

/*
    Copy data to imbuff for plane averaging
*/
            jj = hdr.ns*j;
	    if ((debugfile1) && (fp_debug != (FILE *)NULL)) {
	        fprintf (fp_debug, "jj= [%d]\n", jj);
                fflush (fp_debug);
	    }
	        
            for (i=0; i<hdr.ns; i++) {
		imbuff[jj+i] += fitsbuf[i]/nplaneave; 
            }         
 
            if (j == 10) {
	        if ((debugfile1) && (fp_debug != (FILE *)NULL)) {
	        
                    for (i=0; i<hdr.ns; i++) {
	                fprintf (fp_debug, "j= [%d] i= [%d] imbuff= [%lf]\n",
	                    j, i, imbuff[jj+i]);
		    }
                    fflush (fp_debug);
	        }
            }         
            fpixel[1]++;
        }
    }

/*
    Write averaged image to output FITS file
*/
    fpixelo[0] = 1;
    fpixelo[1] = 1;
    fpixelo[2] = 1;
    fpixelo[3] = 1;
    
    for (j=0; j<hdr.nl; j++) {

        jj = hdr.ns*j;
        for (i=0; i<hdr.ns; i++) {
	    fitsbuf[i] = imbuff[jj+i]; 
        }
            
	if (j == 10) {
	    if ((debugfile1) && (fp_debug != (FILE *)NULL)) {
	        
                for (i=0; i<hdr.ns; i++) {
	            fprintf (fp_debug, "j= [%d] i= [%d] fitsbuf= [%lf]\n", 
		        j, i, fitsbuf[i]);
		}
                fflush (fp_debug);
	    }
        }         

        
	if (fits_write_pix (outfptr, TDOUBLE, fpixelo, nelements,
			 (void *)fitsbuf, &istatus)) {

            sprintf (errmsg, "fits write error: l= [%d]\n", l);
            return (-1);
        }

        fpixelo[1]++;
    }   


    istatus = 0;
    if (fits_close_file (infptr, &istatus)) {
        sprintf (errmsg, "Failed to close cubepath [%s]\n", cubepath);
        return (-1); 
    }
    
    istatus = 0;
    if (fits_close_file (outfptr, &istatus)) {
        sprintf (errmsg, "Failed to close impath [%s]\n", impath);
        return (-1); 
    }

    *splaneave = splane;
    *eplaneave = eplane;

    return (0);
}
Exemplo n.º 2
0
int montage_copyHeaderInfo(fitsfile *infptr, fitsfile *outfptr, struct imageParams *params)
{
   double tmp;
   int naxis2;
   int status = 0;
   
   if(fits_copy_header(infptr, outfptr, &status))
      montage_printFitsError(status);


   /**********************/
   /* Update header info */
   /**********************/

   if(fits_update_key_lng(outfptr, "BITPIX", -64,
                                  (char *)NULL, &status))
      montage_printFitsError(status);

   if(fits_update_key_lng(outfptr, "NAXIS", 2,
                                  (char *)NULL, &status))
      montage_printFitsError(status);

   if(fits_update_key_lng(outfptr, "NAXIS1", params->nelements,
                                  (char *)NULL, &status))
      montage_printFitsError(status);

   naxis2 = params->jend - params->jbegin + 1;
   if(fits_update_key_lng(outfptr, "NAXIS2", naxis2,
                                  (char *)NULL, &status))
      montage_printFitsError(status);

   if(params->isDSS)
   {
      tmp = params->cnpix[0] + params->ibegin - 1;

      if(fits_update_key_dbl(outfptr, "CNPIX1", tmp, -14,
                                     (char *)NULL, &status))
         montage_printFitsError(status);

      tmp = params->cnpix[1] + params->jbegin - 1;

      if(fits_update_key_dbl(outfptr, "CNPIX2", tmp, -14,
                                     (char *)NULL, &status))
         montage_printFitsError(status);
   }
   else
   {
      tmp = params->crpix[0] - params->ibegin + 1;

      if(fits_update_key_dbl(outfptr, "CRPIX1", tmp, -14,
                                     (char *)NULL, &status))
         montage_printFitsError(status);

      tmp = params->crpix[1] - params->jbegin + 1;

      if(fits_update_key_dbl(outfptr, "CRPIX2", tmp, -14,
                                     (char *)NULL, &status))
         montage_printFitsError(status);
   }

   if(debug)
   {
      printf("naxis1 -> %ld\n", params->nelements);
      printf("naxis2 -> %d\n",  naxis2);

      if(params->isDSS)
      {
         printf("cnpix1 -> %-g\n", params->cnpix[0]+params->ibegin-1);
         printf("cnpix2 -> %-g\n", params->cnpix[1]+params->jbegin-1);
      }
      else
      {
         printf("crpix1 -> %-g\n", params->crpix[0]-params->ibegin+1);
         printf("crpix2 -> %-g\n", params->crpix[1]-params->jbegin+1);
      }

      fflush(stdout);
   }

   return 0;
}
Exemplo n.º 3
0
int main(int argc, char *argv[])
{

    static struct option long_opts[] = {
        {"start",  1, NULL, 's'},
        {"end",    1, NULL, 'e'},
	{0,0,0,0}
    };	

    fitsfile *infptr, *outfptr;   /* FITS file pointers defined in fitsio.h */
    int opt, opti;
    int i, status = 0, ii = 1, jj=1;       /* status must always be initialized = 0  */
    int lo_row, hi_row;
    unsigned char *buffer = 0;

    long nrows;
    int ncols;
    int tfields;
    long  pcount;
    char  extname[FLEN_VALUE];
    char  *ttype[NFIELDS_I];
    char  *tform[NFIELDS_I];
    char  *tunit[NFIELDS_I];
    char  *tcomm[NFIELDS_I];

    float start=0.0, end=1.0;
    while ((opt=getopt_long(argc,argv,"s:e:h",long_opts,&opti))!=-1) {
        switch (opt) {
	    case 's':
	        start = atof(optarg);
		break;
	    case 'e':
	        end = atof(optarg);
		break;
	    case 'h':
	    default:
	        usage();
		exit(0);
		break;
	}	

    }

    if (argc < 3)
    {
      usage();
      return(0);
    }

    //printf("> %s %s\n", argv[1], argv[2]);
    //printf("> %s %s\n", argv[optind], argv[2]);


   /* Allocate space for the table parameters and initialize */
   for (i=0; i<NFIELDS_I; i++)
   {
      ttype[i] = (char *) malloc(FLEN_VALUE*sizeof(char));
      tform[i] = (char *) malloc(FLEN_VALUE*sizeof(char));
      tunit[i] = (char *) malloc(FLEN_VALUE*sizeof(char));
      tcomm[i] = (char *) malloc(FLEN_CARD*sizeof(char));
      strcpy(ttype[i], " ");
   }


    /* Open the input file */
    if ( !fits_open_file(&infptr, argv[optind], READONLY, &status) )
    {
      /* Create the output file */
      if ( !fits_create_file(&outfptr, argv[optind+1], &status) )
      {
        /* Copy every HDU until we get an error */
        //while( !fits_movabs_hdu(infptr, ii++, NULL, &status) )
	
	/* Copy first HDU */
        fits_copy_hdu(infptr, outfptr, 0, &status);

	fits_movnam_hdu(infptr, BINARY_TBL, "SUBINT", 0, &status);

	fits_get_num_rows(infptr, &nrows, &status);
	printf("Number of rows = %ld\n", nrows);
	
	fits_get_num_cols(infptr, &ncols, &status);
	printf("Number of cols = %d\n", ncols);
		
	long width;
	fits_read_key(infptr, TLONG, "NAXIS1", &width, NULL, &status);
	printf("Width = %ld\n", width);
	buffer = (unsigned char *) malloc(width);
	
	/* Copy the fits header */
	fits_copy_header(infptr, outfptr, &status);

//#if 0
	/* Determine low and high row number ot copy */
	lo_row = 1 + start * nrows;
	hi_row = end * nrows;
	printf("lo_row=%d hi_row=%d\n", lo_row, hi_row);

	for (ii=lo_row, jj=1; ii<=hi_row; ii++, jj++) {
	    printf("\rRead %d/%ld", ii, nrows);
	    fits_read_tblbytes( infptr,  ii, 1, width, buffer, &status);

	    fits_write_tblbytes(outfptr, jj, 1, width, buffer, &status);
	}
	nrows = (hi_row-lo_row)+1;
	fits_update_key(outfptr, TLONG, "NAXIS2", &nrows, 0, &status);
	printf("\nDone\n");
//#endif
        /* Reset status after normal error */
        //if (status == END_OF_FILE) status = 0;

        fits_close_file(outfptr,  &status);
      }
      fits_close_file(infptr, &status);
    }

    /* if error occured, print out error message */
    if (status) fits_report_error(stderr, status);
    return(status);
}
Exemplo n.º 4
0
int main(int argc, char *argv[])
{
	fitsfile *afptr, *outfptr;  /* FITS file pointers */
	int status = 0;  /* CFITSIO status value MUST be initialized to zero! */
	int anaxis, check = 1, keytype;
	long npixels = 1, firstpix[3] = {1,1,1};
	long anaxes[3] = {1,1,1};
	double *apix;
	char card[FLEN_CARD];

	if (argc != 3) { 
		printf("Usage: tofitsbp16 inimage outimage \n");
		printf("\n");
		printf("Compiled from cfitsio v2.460\n");
		printf("\n");
		printf("Converts a FITS from BITPIX = -32 to BITPIX = 16\n");
		printf("\n");
		printf("Example: \n");
		printf("  tofitsbp16 in.fit out.fits.\n");
		return(0);
	}

	fits_open_file(&afptr, argv[1], READONLY, &status); /* open input images */

	fits_get_img_dim(afptr, &anaxis, &status);  /* read dimensions */
	fits_get_img_size(afptr, 3, anaxes, &status);

	if (status) {
		fits_report_error(stderr, status); /* print error message */
		return(status);
	}

	/* create the new empty output file if the above checks are OK */
	if (check && !fits_create_file(&outfptr, argv[2], &status) )
	{
		/* copy all the header keywords from first image to new output file */
		fits_copy_header(afptr, outfptr, &status);

		/* change to 16 bit integer variable */
		fits_modify_key_lng (outfptr, "BITPIX", 16, "&", &status );

		npixels = anaxes[0];  /* no. of pixels to read in each row */
		apix = (double *) malloc(npixels * sizeof(double)); /* mem for 1 row */

		if (apix == NULL) {
			printf("Memory allocation error\n");
			return(1);
		}

		/* loop over all planes of the cube (2D images have 1 plane) */
		for (firstpix[2] = 1; firstpix[2] <= anaxes[2]; firstpix[2]++)
		{
			/* loop over all rows of the plane */
			for (firstpix[1] = 1; firstpix[1] <= anaxes[1]; firstpix[1]++)
			{
				/* Read both images as doubles, regardless of actual datatype.  */
				/* Give starting pixel coordinate and no. of pixels to read.    */
				/* This version does not support undefined pixels in the image. */
				if (fits_read_pix(afptr, TDOUBLE, firstpix, npixels, NULL, apix,
					NULL, &status)  )
					break;   /* jump out of loop on error */

				fits_write_pix(outfptr, TDOUBLE, firstpix, npixels,
					apix, &status); /* write new values to output image */
			}
		}    /* end of loop over planes */

		fits_close_file(outfptr, &status);
		free(apix);
	}

	fits_close_file(afptr, &status);
	 
	if (status) fits_report_error(stderr, status); /* print any error message */
		return(status);
}
Exemplo n.º 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;
}
Exemplo n.º 6
0
int generateMedianPlane (char *cubepath, char *impath, int iplane,
    int nplane_in, int *startplane, int *endplane, char *errmsg)
{
    struct stat     buf;
    struct FitsHdr  hdr;

    char   str[1024];
    char   cmd[1024];
    
    int    bitpix;
    int    istatus;
    
    int    nhdu, hdutype, hdunum;

    
    long    nelements;
    
    int    naxis3;
    int    l;
    int    i;
    int    j;
    int    jj;

    int    nullcnt;
    
    int    splane;
    int    eplane;
    int    nplane;
    
    
    int    indx;
    int    indx1;
    int    indx2;

    int    npixel;
    int    midpoint; 

    long   fpixel[4];
    long   fpixelo[4];

    double *fitscubebuf;
    double *outbuf;
    double *fitsbuf1d;
    double *wavebuf;


    fitsfile  *infptr;
    fitsfile  *outfptr;

    
    int    debugfile = 1;


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


    if ((debugfile) && (fp_debug != (FILE *)NULL)) {
        
        fprintf (fp_debug, "\nEnter generateMedianPlane: cubepath= [%s]\n", 
            cubepath);
        fprintf (fp_debug, "impath= [%s]\n", impath);
        fprintf (fp_debug, "iplane= [%d]\n", iplane);
        fprintf (fp_debug, "nplane_in= [%d]\n", nplane_in);
        fflush (fp_debug);
    }

    nplane = nplane_in;

    splane = iplane - nplane/2;
    eplane = splane + nplane - 1;

    if ((debugfile) && (fp_debug != (FILE *)NULL)) {
        
        fprintf (fp_debug, "splane= [%d] eplane= [%d]\n", splane, eplane);
        fflush (fp_debug);
    }


/*
    Open input fits cube 
*/
    istatus = 0;
    if (fits_open_file (&infptr, cubepath, READONLY, &istatus)) {

        if ((debugfile) && (fp_debug != (FILE *)NULL)) {
        
            fprintf (fp_debug, "istatus= [%d]\n", istatus);
            fflush (fp_debug);
        }

        sprintf (errmsg, "Failed to open FITS file [%s]\n", cubepath);
        return (-1);
    } 


    hdunum = 1; 
    nhdu = 0;
    istatus = 0;
    istatus = fits_get_num_hdus (infptr, &nhdu, &istatus);
    
    if ((debugfile) && (fp_debug != (FILE *)NULL)) {
        
        fprintf (fp_debug, 
            "returned fits_get_hdu_num: istatus= [%d] nhdu= [%d]\n",
            istatus, nhdu);
        fflush (fp_debug);
    }

    if (hdunum > nhdu) {

        sprintf (errmsg, "fname [%s] doesn't contain any HDU", cubepath);
        return (-1);
    }


/*
    Read fits keywords from the first HDU
*/
    hdutype = 0;
    istatus = 0;
    istatus = fits_movabs_hdu (infptr, hdunum, &hdutype, &istatus);

    if ((debugfile) && (fp_debug != (FILE *)NULL)) {
        
        fprintf (fp_debug, 
            "returned fits_movabs_hdu: istatus= [%d] hdutype= [%d]\n",
            istatus, hdutype);
        fflush (fp_debug);
    }

/*
    Read fits keywords
*/
    istatus = 0;
    istatus = fits_read_key (infptr, TSTRING, "simple", str, (char *)NULL, 
        &istatus);
    
    if (istatus == KEY_NO_EXIST) {
        sprintf (errmsg, "keyword SIMPLE not found in fits header");
        return (-1);
    }
   
    if ((strcmp (str, "T") != 0) && (strcmp (str, "F") != 0)) {
        sprintf (errmsg, "keyword SIMPLE must be T or F");
        return (-1);
    }

    istatus = 0;
    istatus = fits_read_key (infptr, TSTRING, "bitpix", str, (char *)NULL, 
        &istatus);
    
    if (istatus == KEY_NO_EXIST) {
        sprintf (errmsg, "keyword BITPIX not found in fits header");
        return (-1);
    }
  
    istatus = str2Integer (str, &bitpix, errmsg);
    if (istatus != 0) {
        sprintf (errmsg, "keyword BITPIX must be an integer");
        return (-1);
    }

    if ((bitpix != 8) &&
        (bitpix != 16) &&
        (bitpix != 32) &&
        (bitpix != 64) &&
        (bitpix != -32) &&
        (bitpix != -64)) {
        
        sprintf (errmsg, 
            "keyword BITPIX value must be 8, 16, 32, 64, -32, -64");
        return (-1);
    }

    hdr.bitpix = bitpix;

    istatus = 0;
    istatus = fits_read_key (infptr, TSTRING, "naxis", str, (char *)NULL, 
        &istatus);
        
    if (istatus == KEY_NO_EXIST) {
        sprintf (errmsg, "keyword naxis not found in fits header");
        return (-1);
    }

    if ((debugfile) && (fp_debug != (FILE *)NULL)) {
        
        fprintf (fp_debug, "str= [%s]\n", str);
        fflush (fp_debug);
    }
    istatus = str2Integer (str, &hdr.naxis, errmsg);
    if (istatus < 0) {
        sprintf (errmsg, "Failed to convert naxis to integer");
        return (-1);
    }
    
    if ((debugfile) && (fp_debug != (FILE *)NULL)) {
        
        fprintf (fp_debug, "naxis= [%d]\n", hdr.naxis);
        fflush (fp_debug);
    }


    istatus = 0;
    istatus = fits_read_key (infptr, TSTRING, "naxis1", str, (char *)NULL, 
        &istatus);
        
    if ((debugfile) && (fp_debug != (FILE *)NULL)) {
        
        fprintf (fp_debug, "returned fits_read_key: istatus= [%d]\n", istatus);
        fflush (fp_debug);
    }
        
    if (istatus == KEY_NO_EXIST) {
        sprintf (errmsg, "keyword naxis1 not found in fits header");
        return (-1);
    }

    if ((debugfile) && (fp_debug != (FILE *)NULL)) {
        
        fprintf (fp_debug, "str= [%s]\n", str);
        fflush (fp_debug);
    }

    istatus = str2Integer (str, &hdr.ns, errmsg);
    
    if (istatus < 0) {
        sprintf (errmsg, "Failed to convert naxis1 string to integer");
        return (-1);
    }
    hdr.naxes[0] = hdr.ns;

    istatus = 0;
    istatus = fits_read_key (infptr, TSTRING, "naxis2", str, 
        (char *)NULL, &istatus);
        
    if ((debugfile) && (fp_debug != (FILE *)NULL)) {
        
        fprintf (fp_debug, "returned fits_read_key: istatus= [%d]\n", istatus);
        fflush (fp_debug);
    }
        
    if (istatus == KEY_NO_EXIST) {
        sprintf (errmsg, "keyword naxis2 not found in fits header");
        return (-1);
    }
    
    if ((debugfile) && (fp_debug != (FILE *)NULL)) {
        
        fprintf (fp_debug, "str= [%s]\n", str);
        fflush (fp_debug);
    }

    istatus = str2Integer (str, &hdr.nl, errmsg);
    
    if (istatus < 0) {
        sprintf (errmsg, "Failed to convert naxis2 string to integer");
        return (-1);
    }
    hdr.naxes[1] = hdr.nl;

    
    if ((debugfile) && (fp_debug != (FILE *)NULL)) {
        
        fprintf (fp_debug, "ns= [%d] nl= [%d]\n", hdr.ns, hdr.nl);
        fflush (fp_debug);
    }

    hdr.nplane = 1;

    if (hdr.naxis > 2) {
    
        istatus = 0;
        istatus = fits_read_key (infptr, TSTRING, "naxis3", str, 
            (char *)NULL, &istatus);
        
        if ((debugfile) && (fp_debug != (FILE *)NULL)) {
        
            fprintf (fp_debug, "returned fits_read_key: istatus= [%d]\n", 
                istatus);
            fflush (fp_debug);
        }
        
        if (istatus == KEY_NO_EXIST) {
            sprintf (errmsg, "keyword naxis3 not found in fits header");
            return (-1);
        }
    
        if ((debugfile) && (fp_debug != (FILE *)NULL)) {
        
            fprintf (fp_debug, "str= [%s]\n", str);
            fflush (fp_debug);
        }

        istatus = str2Integer (str, &hdr.naxes[2], errmsg);
    
        if (istatus < 0) {
            sprintf (errmsg, "Failed to convert naxis3 string to integer");
            return (-1);
        }
        hdr.nplane = hdr.naxes[2];
    
        if ((debugfile) && (fp_debug != (FILE *)NULL)) {
        
            fprintf (fp_debug, "naxes[2]= [%d]\n", hdr.naxes[2]);
            fflush (fp_debug);
        }
    }
    if ((debugfile) && (fp_debug != (FILE *)NULL)) {
        
        fprintf (fp_debug, "hdr.nplane= [%d]\n", hdr.nplane);
        fflush (fp_debug);
    }


    if (splane < 1)
        splane = 1;
    
    if (eplane > hdr.nplane)
        eplane = hdr.nplane;

    nplane = eplane - splane + 1;

    if ((debugfile) && (fp_debug != (FILE *)NULL)) {
        
        fprintf (fp_debug, "hdr.nplane= [%d]\n", hdr.nplane);
        fprintf (fp_debug, "splane= [%d] eplane= [%d]\n", splane, eplane);
        fprintf (fp_debug, "nplane= [%d]\n", nplane);
        fflush (fp_debug);
    }


/*
    malloc arrays for reading data
*/
    fitscubebuf  
    = (double *)malloc(hdr.ns*hdr.nl*nplane*sizeof(double));
    
    outbuf  = (double *)malloc(hdr.ns*hdr.nl*sizeof(double));
    
    wavebuf  = (double *)malloc(nplane*sizeof(double));
    
    fitsbuf1d  = (double *)malloc(hdr.ns*sizeof(double));

    nelements = hdr.ns;

    npixel = hdr.ns*hdr.nl;
    
    if ((debugfile) && (fp_debug != (FILE *)NULL)) {
        fprintf (fp_debug, "npixel= [%d]\n", npixel);
        fflush (fp_debug);
    }


/*
    Read cube data to fitscubebuf
*/
    fpixel[0] = 1;
    fpixel[3] = 1;
    
    indx = 0;
    for (l=splane; l<=eplane; l++)
    {
       
        indx2 = hdr.nl*hdr.ns*(l-splane); 

        if ((debugfile) && (fp_debug != (FILE *)NULL)) {
            fprintf (fp_debug, "l= [%d]\n", l);
            fflush (fp_debug);
        }


        fpixel[1] = 1;
        fpixel[2] = l;
        
        for (j=0; j<hdr.nl; j++)
        {
            indx1 = hdr.ns*j; 

            if (fits_read_pix (infptr, TDOUBLE, fpixel, nelements, &nan,
                fitsbuf1d, &nullcnt, &istatus)) {
                break;
            }

            for (i=0; i<nelements; i++) {
                
                fitscubebuf[indx2+indx1+i] = fitsbuf1d[i];
                
                if ((debugfile) && (fp_debug != (FILE *)NULL)) {
                    
                    if ((i == 30) && (j == 25)) {
                        fprintf (fp_debug, "i=[%d] j=[%d] l=[%d] pixel=[%lf]\n",
                            i, j, l, fitscubebuf[indx2+indx1+i]);
                        fflush (fp_debug);
                    }
                }


            }

            fpixel[1]++;
        }
   }

/*
    istatus = 0;
    if (fits_close_file (infptr, &istatus)) {
        sprintf (errmsg, "Failed to close cubepath [%s]\n", cubepath);
        return (-1); 
    }
*/


/*
    Extract wave axis and compute median values
*/
    midpoint = nplane / 2;
    
    if ((debugfile) && (fp_debug != (FILE *)NULL)) {
        fprintf (fp_debug, "midpint= [%d]\n", midpoint);
        fflush (fp_debug);
    }

    for (j=0; j<hdr.nl; j++) {
        
        indx1 = hdr.ns*j;

        for (i=0; i<hdr.ns; i++) {
        
            for (l=0; l<nplane; l++) {
                
                indx = npixel*l + indx1 + i;

                wavebuf[l] = fitscubebuf[indx];
                    
                if ((debugfile) && (fp_debug != (FILE *)NULL)) {
                    
                    if ((i == 30) && (j == 25)) {
                        fprintf (fp_debug, "i=[%d] j=[%d] l=[%d] pixel=[%lf]\n",
                            i, j, l, wavebuf[l]);
                        fflush (fp_debug);
                    }
                }
            }

            sort (wavebuf, nplane);
                
            if ((debugfile) && (fp_debug != (FILE *)NULL)) {
                    
                
                if ((i == 30) && (j == 25)) {
                    
                    fprintf (fp_debug, "after qsort\n");
                    for (l=0; l<nplane; l++) {
                        fprintf (fp_debug, "l=[%d] pixel=[%lf]\n", 
                            l, wavebuf[l]);
                    }
                    fflush (fp_debug);
                }
            }

            outbuf[indx1+i] = wavebuf[midpoint];
            
            if ((debugfile) && (fp_debug != (FILE *)NULL)) {
                if ((i == 30) && (j == 25)) {
                    fprintf (fp_debug, "outbuf= [%lf]\n", outbuf[indx1+i]);
                    fflush (fp_debug);
                }
            }

        }
    }



/*
    Create output fits file
*/
    istatus = stat (impath, &buf);
    if ((debugfile) && (fp_debug != (FILE *)NULL)) {
        fprintf (fp_debug, "impath exists? : istatus= [%d]\n", istatus);
        fflush (fp_debug); 
    }

    if (istatus >= 0) {
        sprintf (cmd, "unlink %s", impath);
        istatus = system (cmd);
    }        


    istatus = 0;
    if (fits_create_file (&outfptr, impath, &istatus)) {
            
        sprintf (errmsg, "Failed to create output fitsfile [%s]\n", 
            impath);
        
        if ((debugfile) && (fp_debug != (FILE *)NULL)) {
            fprintf (fp_debug, "err: [%s]\n", errmsg);
            fflush (fp_debug);
        }
        return (-1);
    }

    if ((debugfile) && (fp_debug != (FILE *)NULL)) {
        fprintf (fp_debug, "outptr created\n");
        fflush (fp_debug);
    }


/* 
    Copy input fits header to output fitsfile
*/
    istatus = 0;
    if (fits_copy_header (infptr, outfptr, &istatus)) {

        strcpy (errmsg, "Failed to copy fitshdr\n");
        
        if ((debugfile) && (fp_debug != (FILE *)NULL)) {
            fprintf (fp_debug, "err: [%s]\n", errmsg);
            fflush (fp_debug);
        }
        return (-1);
    }

    if ((debugfile) && (fp_debug != (FILE *)NULL)) {
        fprintf (fp_debug, "header copied\n");
        fflush (fp_debug);
    }



/*
    Update header keyword NAXIS3
*/
    naxis3 = 1;
    istatus = 0;
    if (fits_update_key_lng(outfptr, "NAXIS3", naxis3, (char *)NULL, 
        &istatus)) {
        
        strcpy (errmsg, "Failed to update keyword NAXIS3\n");
        return (-1);
    }

    if ((debugfile) && (fp_debug != (FILE *)NULL)) {
        fprintf (fp_debug, "naxis3 updated\n");
        fflush (fp_debug);
    }


/*
    Write to output fitsfile
*/
    nelements = hdr.ns;
    fpixelo[0] = 1;
    fpixelo[1] = 1;
    fpixelo[2] = 1;
    fpixelo[3] = 1;
       
    for (j=0; j<hdr.nl; j++) {
    
        jj = hdr.ns*j;
        for (i=0; i<hdr.ns; i++) {
                
            fitsbuf1d[i] = outbuf[jj+i];
        }

        if (fits_write_pix (outfptr, TDOUBLE, fpixelo, nelements,
             (void *)fitsbuf1d, &istatus)) {

            sprintf (errmsg, "fits write error: l= [%d] j= [%d]\n", l, j);
            return (-1);
        }

        fpixelo[1]++;
    }

        
    if ((debugfile) && (fp_debug != (FILE *)NULL)) {
        fprintf (fp_debug, "here2\n");
        fflush (fp_debug);
    }


    istatus = 0;
    if (fits_close_file (infptr, &istatus)) {
        sprintf (errmsg, "Failed to close cubepath [%s]\n", cubepath);
        return (-1); 
    }

    if ((debugfile) && (fp_debug != (FILE *)NULL)) {
        fprintf (fp_debug, "here3\n");
        fflush (fp_debug);
    }


    istatus = 0;
    if (fits_close_file (outfptr, &istatus)) {
        sprintf (errmsg, "Failed to close impath [%s]\n", impath);
        return (-1); 
    }

    *startplane = splane;
    *endplane = eplane;


    return (0);
}
Exemplo n.º 7
0
int main(int argc, char *argv[])
{
	fitsfile *afptr, *outfptr;  /* FITS file pointers */
	int status = 0;  /* CFITSIO status value MUST be initialized to zero! */
	int anaxis, check = 1, ii, op, keytype;
	long npixels = 1, firstpix[3] = {1,1,1}, ntodo;
	long anaxes[3] = {1,1,1};
	double *apix;
	double maxval, minval;
	char card[FLEN_CARD];

	if (argc != 5) { 
		printf("Usage: pruneimage image max min outimage \n");
		printf("\n");
		printf("Compiled from cfitsio v2.460\n");
		printf("\n");
		printf("Trim off the peaks and valley values of the image.\n");
		printf("\n");
		printf("outimage is of format BITPIX = -32\n");
		printf("\n");
		printf("Example: \n");
		printf("  pruneimage in.fit 1000 850 out.fits - sets all values above 1000 to 1000\n");
		printf("                                            and all values below 850 to 850.\n");
		return(0);
	}

	fits_open_file(&afptr, argv[1], READONLY, &status); /* open input images */
	fits_get_img_dim(afptr, &anaxis, &status);  /* read dimensions */
	fits_get_img_size(afptr, 3, anaxes, &status);

	if (status) {
		fits_report_error(stderr, status); /* print error message */
		return(status);
	}

	if (anaxis > 3) {
		printf("Error: images with > 3 dimensions are not supported\n");
		check = 0;
	}

	maxval = atof ( argv[2] );
	minval = atof ( argv[3] );

	/* create the new empty output file if the above checks are OK */
	if (check && !fits_create_file(&outfptr, argv[4], &status) )
	{
		/* copy all the header keywords from first image to new output file */
		fits_copy_header(afptr, outfptr, &status);

		/* change to floating point variable */
		fits_modify_key_lng (outfptr, "BITPIX", -32, "&", &status );

		fits_modify_key_flt (outfptr, "DATAMIN", minval, -10, "&", &status );
		fits_modify_key_flt (outfptr, "DATAMAX", maxval, -10, "&", &status );

		npixels = anaxes[0];  /* no. of pixels to read in each row */
		apix = (double *) malloc(npixels * sizeof(double)); /* mem for 1 row */

		if (apix == NULL) {
			printf("Memory allocation error\n");
			return(1);
		}

		/* loop over all planes of the cube (2D images have 1 plane) */
		for (firstpix[2] = 1; firstpix[2] <= anaxes[2]; firstpix[2]++)
		{
			/* loop over all rows of the plane */
			for (firstpix[1] = 1; firstpix[1] <= anaxes[1]; firstpix[1]++)
			{
				/* Read both images as doubles, regardless of actual datatype.  */
				/* Give starting pixel coordinate and no. of pixels to read.    */
				/* This version does not support undefined pixels in the image. */
				if (fits_read_pix(afptr, TDOUBLE, firstpix, npixels, NULL, apix,
					NULL, &status)  )
					break;   /* jump out of loop on error */



				for(ii=0; ii< npixels; ii++) {
					if ( apix[ii] > maxval )
						apix[ii] = maxval;
					else if ( apix[ii] < minval )
						apix[ii] = minval;
				}

				fits_write_pix(outfptr, TDOUBLE, firstpix, npixels,
					apix, &status); /* write new values to output image */
			}
		}    /* end of loop over planes */

		fits_close_file(outfptr, &status);
		free(apix);
	}

	fits_close_file(afptr, &status);
	 
	if (status) fits_report_error(stderr, status); /* print any error message */
		return(status);
}
Exemplo n.º 8
0
/* Function to write array to FITS file, and copy header info from other file */
void fitswrap_write2file(char *fileout, char *copyhdr, double **array, 
			  long write_size[2], int *status){
  
  /* Variable Declarations & Initializations */
  int k,naxis,bitpix;
  long fpixel[2],naxes[2],bzero;
  char buf_date[FLEN_VALUE],buf_time[FLEN_VALUE],*mod_comm;
  fitsfile *fitsfp,*hdrfp;
  time_t now;
  struct tm *ptr;
  *status = 0;

  /* Open file from which header will be copied */
  hdrfp = fitswrap_open_read(copyhdr, status);

  /* Check for output file -- create & open for write */
  if(access(fileout,F_OK) == 0)          // Check if output file exists
    remove(fileout);                     // If yes, remove it
  if(fits_create_file(&fitsfp, fileout, status)){
    fitswrap_catcherror(status);    // Send pointer not value
  }

  mod_comm = "Modified by fitswrap routine, TPEB.";
  /* Copy header from copyhdr FITS file. */
  fits_copy_header(hdrfp, fitsfp, status);  // Copy header from input FITS
  fits_get_img_param(hdrfp, 2 ,&bitpix, &naxis, naxes, status);
  fits_read_key(hdrfp, TLONG, "BZERO", &bzero, NULL, status);

  /* Check for needed updates */
    // Writing new FITS as double
    if(bitpix != DOUBLE_IMG){
      bitpix = DOUBLE_IMG;
      fits_update_key(fitsfp, TSHORT, "BITPIX", &bitpix, mod_comm, status);
    }
    
    // check for 'zero level' (needed for type long FITS headers)
    // NOTE: If input header does not contain this keyword (status = 202), 
    // skip update & reset CFITSIO status to zero.
    
    if(bzero != 0 || *status != 202){  
      bzero = 0;
      fits_update_key(fitsfp, TSHORT, "BZERO", &bzero, mod_comm, status);
    }
    *status = 0;                       // Reset Status
    
    // Check new axis lengths are correct
    if(naxes[0] != write_size[0])
      fits_update_key(fitsfp, TULONG,"NAXIS1",&write_size[0],mod_comm,status);
    if(naxes[1] != write_size[1])
      fits_update_key(fitsfp, TULONG,"NAXIS2",&write_size[1],mod_comm,status);
    
    
  /* Write array to file */
  fpixel[0] = 1;
  for(k=0; k < write_size[1]; k++){       // Loop over size[1] rows (i.e. y)
    fpixel[1] = k + 1; 
    if(fits_write_pix(fitsfp, TDOUBLE, fpixel, write_size[0], array[k], 
  		      status)){
      fits_report_error(stderr,*status);
      break;
    }
  }
  
  /* Add/modify keyword for date modified 'DATE-MOD' & 'TIME-MOD' */
  time(&now);
  ptr = localtime(&now);
  strftime(buf_date, FLEN_VALUE, "%Y-%m-%d", ptr);
  strftime(buf_time, FLEN_VALUE, "%H:%M:%S", ptr);
  fits_update_key(fitsfp, TSTRING, "DATE-MOD", buf_date, mod_comm, status);
  fits_update_key(fitsfp, TSTRING, "TIME-MOD", buf_time, NULL, status);
  
  /* Clean up */
  fits_close_file(fitsfp, status);
  fits_close_file(hdrfp,  status);
  
  /* Report any CFITSIO errors to stderr */
  if(!*status)
    fitswrap_catcherror(status);    // Send pointer not value
  
  return;
}
Exemplo n.º 9
0
int unpermute_quads(quadfile* quadin, codetree* treein,
					quadfile* quadout, codetree** p_treeout,
					char** args, int argc) {
	int i;
	qfits_header* codehdr;
	qfits_header* hdr;
	int healpix;
	int hpnside;
	int codehp = -1;
	qfits_header* qouthdr;
	qfits_header* qinhdr;
	codetree* treeout;
	anbool allsky;

	codehdr = codetree_header(treein);
	healpix = quadin->healpix;
	hpnside = quadin->hpnside;

	allsky = qfits_header_getboolean(codehdr, "ALLSKY", 0);
	if (allsky)
		logverb("Index is all-sky\n");
	else {
		codehp = qfits_header_getint(codehdr, "HEALPIX", -1);
		if (codehp == -1)
			ERROR("Warning, input code kdtree didn't have a HEALPIX header");
		else if (codehp != healpix) {
			ERROR("Quadfile says it's healpix %i, but code kdtree says %i",
				  healpix, codehp);
			return -1;
		}
	}

	quadout->healpix = healpix;
	quadout->hpnside = hpnside;
	quadout->indexid = quadin->indexid;
	quadout->numstars = quadin->numstars;
	quadout->dimquads = quadin->dimquads;
	quadout->index_scale_upper = quadin->index_scale_upper;
	quadout->index_scale_lower = quadin->index_scale_lower;

	qouthdr = quadfile_get_header(quadout);
	qinhdr  = quadfile_get_header(quadin);

	boilerplate_add_fits_headers(qouthdr);
	qfits_header_add(qouthdr, "HISTORY", "This file was created by the program \"unpermute-quads\".", NULL, NULL);
	qfits_header_add(qouthdr, "HISTORY", "unpermute-quads command line:", NULL, NULL);
	fits_add_args(qouthdr, args, argc);
	qfits_header_add(qouthdr, "HISTORY", "(end of unpermute-quads command line)", NULL, NULL);
	qfits_header_add(qouthdr, "HISTORY", "** unpermute-quads: history from input:", NULL, NULL);
	fits_copy_all_headers(qinhdr, qouthdr, "HISTORY");
	qfits_header_add(qouthdr, "HISTORY", "** unpermute-quads end of history from input.", NULL, NULL);
	qfits_header_add(qouthdr, "COMMENT", "** unpermute-quads: comments from input:", NULL, NULL);
	fits_copy_all_headers(qinhdr, qouthdr, "COMMENT");
	qfits_header_add(qouthdr, "COMMENT", "** unpermute-quads: end of comments from input.", NULL, NULL);
	fits_copy_header(qinhdr, qouthdr, "CXDX");
	fits_copy_header(qinhdr, qouthdr, "CXDXLT1");
	fits_copy_header(qinhdr, qouthdr, "CIRCLE");
	fits_copy_header(qinhdr, qouthdr, "ALLSKY");

	if (quadfile_write_header(quadout)) {
		ERROR("Failed to write quadfile header");
		return -1;
	}

	for (i=0; i<codetree_N(treein); i++) {
		unsigned int stars[quadin->dimquads];
		int ind = codetree_get_permuted(treein, i);
		if (quadfile_get_stars(quadin, ind, stars)) {
			ERROR("Failed to read quad entry");
			return -1;
        }
		if (quadfile_write_quad(quadout, stars)) {
			ERROR("Failed to write quad entry");
			return -1;
		}
	}

	if (quadfile_fix_header(quadout)) {
		ERROR("Failed to fix quadfile header");
		return -1;
	}

	treeout = codetree_new();
	treeout->tree = malloc(sizeof(kdtree_t));
	memcpy(treeout->tree, treein->tree, sizeof(kdtree_t));
	treeout->tree->perm = NULL;

	hdr = codetree_header(treeout);
	fits_copy_header(qinhdr, hdr, "HEALPIX");
	fits_copy_header(qinhdr, hdr, "HPNSIDE");
	fits_copy_header(qinhdr, hdr, "ALLSKY");
	boilerplate_add_fits_headers(hdr);
	qfits_header_add(hdr, "HISTORY", "This file was created by the program \"unpermute-quads\".", NULL, NULL);
	qfits_header_add(hdr, "HISTORY", "unpermute-quads command line:", NULL, NULL);
	fits_add_args(hdr, args, argc);
	qfits_header_add(hdr, "HISTORY", "(end of unpermute-quads command line)", NULL, NULL);
	qfits_header_add(hdr, "HISTORY", "** unpermute-quads: history from input ckdt:", NULL, NULL);
	fits_copy_all_headers(codehdr, hdr, "HISTORY");
	qfits_header_add(hdr, "HISTORY", "** unpermute-quads end of history from input ckdt.", NULL, NULL);
	qfits_header_add(hdr, "COMMENT", "** unpermute-quads: comments from input ckdt:", NULL, NULL);
	fits_copy_all_headers(codehdr, hdr, "COMMENT");
	qfits_header_add(hdr, "COMMENT", "** unpermute-quads: end of comments from input ckdt.", NULL, NULL);
	fits_copy_header(codehdr, hdr, "CXDX");
	fits_copy_header(codehdr, hdr, "CXDXLT1");
	fits_copy_header(codehdr, hdr, "CIRCLE");

	*p_treeout = treeout;
	return 0;
}
Exemplo n.º 10
0
int edit_image(char filename[], char newfilename[], double **ppix )
{
 fitsfile *fptr, *newfptr;
 int status, nfound, day, month, year, timeref;
 int naxis = 2;			/* 2-dimensional image */
 int bitpix = DOUBLE_IMG;		/* Output image type is double */
 int datatype = TDOUBLE;
 long naxes[2];			/* dimensions of the image */
 long fpixel, npixels;
 char date[FLEN_VALUE], time[FLEN_VALUE];
 char *nullcomment;
 char outfilename[MAXLENGTH];

 nullcomment=0;

  /***********************************************************************/
  status = 0;		/* Initialize status before calling fitsio routines */
  /***********************************************************************/

 /* Copy newfilename to outfilename.  'newfilename' is passed has a reference,
  * therefore any change to it will be passed back to the calling routine
  * which is not really what one wants.  (as I discovered...)
  * The addition of the '!' is meaningful here but not necessarly useful in
  * the calling routine. */
 if (!strcmp(newfilename,filename)) {
   strcpy(outfilename,"!");
   strcat(outfilename,filename);
 }
 else {
   strcpy(outfilename,newfilename);
 }
 printf("Writing %s ... ",newfilename);
 fflush(stdout);

/* Open the existing FITS file */
 if ( fits_open_file(&fptr, filename, READONLY, &status) )
 	printerror( status );

/* Create the new FITS file  (should I use a template?)*/
 if ( fits_create_file(&newfptr, outfilename, &status) )
 	printerror( status );

 /* No need to create an image in the new FITS file because the primary
  * array is automatically created when the header is copied */

/* Copy the header from the existing FITS file to the new FITS file */
 if ( fits_copy_header(fptr, newfptr, &status) )
 	printerror( status );
 
/* Get the length of the axes */
 if ( fits_read_keys_lng(newfptr, "NAXIS", 1, 2, naxes, &nfound, &status) )
 	printerror( status );

/* Write the image (array of pixel values) in the new FITS file */
 fpixel = 1;				/* first pixel to write */
 npixels = naxes[0] * naxes[1];	/* number of pixels to write */

 if ( fits_write_img(newfptr, datatype, fpixel, npixels, ppix[0], &status) )
 	printerror( status );

/* Edit header */
 if ( fits_get_system_date(&day, &month, &year, &status) )
 	printerror( status );
 if ( fits_date2str(year, month, day, date, &status) )
 	printerror( status );
 if ( fits_update_key(newfptr, TSTRING, "DATE", date, "", &status) )
 	printerror( status );

 if ( fits_get_system_time(time, &timeref, &status) )
 	printerror( status );
 if ( timeref == 0 )		/* Convert UTC/GMT to Local time */
 	if ( utc2local(time, FITS_FMT) ) {
		printf("Error : Unable to convert time.\n");
		exit(1);
	} 
 if ( status = cnvtimefmt(time, FITS_FMT, IRAF_FMT))
 	printerror( status ); 	/* Stupid IRAF cannot read the new FITS
 					 *  date-time Y2K format */
 if ( fits_update_key(newfptr, TSTRING, "IRAF-TLM", time, nullcomment, &status) )
 	printerror( status );
 
/* Close the existing FITS file */
 if ( fits_close_file(fptr, &status) )
 	printerror( status );

/* Close the new FITS file */
 if ( fits_close_file(newfptr, &status) )
 	printerror( status );

 printf("done\n");

 return(0);
}
Exemplo n.º 11
0
int main(int argc, char *argv[])
{
    int numfiles, ii, numrows, rownum, ichan, itsamp, datidx;
    int spec_per_row, status, maxrows;
    unsigned long int maxfilesize;
    float offset, scale, datum, packdatum, maxval, fulltsubint;
    float *datachunk;
    FILE **infiles;
    struct psrfits pfin, pfout;
    Cmdline *cmd;
    fitsfile *infits, *outfits;
    char outfilename[128], templatename[128], tform[8];
    char *pc1, *pc2;
    int first = 1, dummy = 0, nclipped;
    short int *inrowdata;
    unsigned char *outrowdata;

    if (argc == 1) {
        Program = argv[0];
        usage();
        exit(1);
    }
    // Parse the command line using the excellent program Clig
    cmd = parseCmdline(argc, argv);
    numfiles = cmd->argc;
    infiles = (FILE **) malloc(numfiles * sizeof(FILE *));

    //Set the max. total size (in bytes) of all rows in an output file,
    //leaving some room for PSRFITS header
    maxfilesize = (unsigned long int)(cmd->numgb * GB);
    maxfilesize = maxfilesize - 1000*KB;
    //fprintf(stderr,"cmd->numgb: %f maxfilesize: %ld\n",cmd->numgb,maxfilesize);

#ifdef DEBUG
    showOptionValues();
#endif

    printf("\n         PSRFITS 16-bit to 4-bit Conversion Code\n");
    printf("         by J. Deneva, S. Ransom, & S. Chatterjee\n\n");

    // Open the input files
    status = 0;                 //fits_close segfaults if this is not initialized
    printf("Reading input data from:\n");
    for (ii = 0; ii < numfiles; ii++) {
        printf("  '%s'\n", cmd->argv[ii]);

        //Get the file basename and number from command-line argument
        //(code taken from psrfits2fil)
        pc2 = strrchr(cmd->argv[ii], '.');      // at .fits
        *pc2 = 0;               // terminate string
        pc1 = pc2 - 1;
        while ((pc1 >= cmd->argv[ii]) && isdigit(*pc1))
            pc1--;
        if (pc1 <= cmd->argv[ii]) {     // need at least 1 char before filenum
            puts("Illegal input filename. must have chars before the filenumber");
            exit(1);
        }
        pc1++;                  // we were sitting on "." move to first digit
        pfin.filenum = atoi(pc1);
        pfin.fnamedigits = pc2 - pc1;   // how many digits in filenumbering scheme.
        *pc1 = 0;               // null terminate the basefilename
        strcpy(pfin.basefilename, cmd->argv[ii]);
        pfin.initialized = 0;   // set to 1 in  psrfits_open()
        pfin.status = 0;
        //(end of code taken from psrfits2fil)

        //Open the existing psrfits file
        if (psrfits_open(&pfin, READONLY) != 0) {
            fprintf(stderr, "error opening file\n");
            fits_report_error(stderr, pfin.status);
            exit(1);
        }
        // Create the subint arrays
        if (first) {
            pfin.sub.dat_freqs = (float *) malloc(sizeof(float) * pfin.hdr.nchan);
            pfin.sub.dat_weights = (float *) malloc(sizeof(float) * pfin.hdr.nchan);
            pfin.sub.dat_offsets =
                (float *) malloc(sizeof(float) * pfin.hdr.nchan * pfin.hdr.npol);
            pfin.sub.dat_scales =
                (float *) malloc(sizeof(float) * pfin.hdr.nchan * pfin.hdr.npol);
            //first is set to 0 after data buffer allocation further below
        }

        infits = pfin.fptr;
        spec_per_row = pfin.hdr.nsblk;
	fits_read_key(infits, TINT, "NAXIS2", &dummy, NULL, &status);
	pfin.tot_rows = dummy;
        numrows = dummy;

	//If dealing with 1st input file, create output template
	if (ii == 0) {
	  sprintf(templatename, "%s.template.fits",cmd->outfile);
	  fits_create_file(&outfits, templatename, &status);
	  //fprintf(stderr,"pfin.basefilename: %s\n", pfin.basefilename);
	  //fprintf(stderr,"status: %d\n", status);
	  
	  //Instead of copying HDUs one by one, can move to the SUBINT
	  //HDU, and copy all the HDUs preceding it
	  fits_movnam_hdu(infits, BINARY_TBL, "SUBINT", 0, &status);
	  fits_copy_file(infits, outfits, 1, 0, 0, &status);
	  
	  //Copy the SUBINT table header
	  fits_copy_header(infits, outfits, &status);
	  fits_flush_buffer(outfits, 0, &status);
	  
	  //Set NAXIS2 in the output SUBINT table to 0 b/c we haven't 
	  //written any rows yet
	  dummy = 0;
	  fits_update_key(outfits, TINT, "NAXIS2", &dummy, NULL, &status);
	  
	  //Edit the NBITS key
	  if (DEBUG) {
	    dummy = 8;
	    fits_update_key(outfits, TINT, "NBITS", &dummy, NULL, &status);
	  } else {
	    fits_update_key(outfits, TINT, "NBITS", &(cmd->numbits), NULL,
			    &status);
	  }
	  
	  //Edit the TFORM17 column: # of data bytes per row 
	  //fits_get_colnum(outfits,1,"DATA",&dummy,&status);
	  if (DEBUG)
	    sprintf(tform, "%dB",
		    pfin.hdr.nsblk * pfin.hdr.nchan * pfin.hdr.npol);
	  else
	    sprintf(tform, "%dB", pfin.hdr.nsblk * pfin.hdr.nchan *
		    pfin.hdr.npol * cmd->numbits / 8);
	  
	  fits_update_key(outfits, TSTRING, "TTYPE17", "DATA", NULL, &status);
	  fits_update_key(outfits, TSTRING, "TFORM17", tform, NULL, &status);
	  
	  //Edit NAXIS1: row width in bytes
	  fits_read_key(outfits, TINT, "NAXIS1", &dummy, NULL, &status);
	  if (DEBUG) {
	    dummy = dummy - pfin.hdr.nsblk * pfin.hdr.nchan *
	      pfin.hdr.npol * (pfin.hdr.nbits - 8) / 8;
	  } else {
	    dummy = dummy - pfin.hdr.nsblk * pfin.hdr.nchan *
	      pfin.hdr.npol * (pfin.hdr.nbits - cmd->numbits) / 8;
	  }
	  fits_update_key(outfits, TINT, "NAXIS1", &dummy, NULL, &status);
	  
	  //Set the max # of rows per file, based on the requested 
	  //output file size
	  maxrows = maxfilesize / dummy;
	  //fprintf(stderr,"maxrows: %d\n",maxrows);

	  fits_close_file(outfits, &status);
	  
	  rownum = 0;
	}
	
        while (psrfits_read_subint(&pfin, first) == 0) {
	  fprintf(stderr, "Working on row %d\n", ++rownum);
	  
	  //If this is the first row, store the length of a full subint
	  if (ii == 0 && rownum == 1)
	    fulltsubint = pfin.sub.tsubint;

	  //If this is the last row and it's partial, drop it.
	  //(It's pfin.rownum-1 below because the rownum member of the psrfits struct seems to be intended to indicate at the *start* of what row we are, i.e. a row that has not yet been read. In contrast, pfout.rownum indicates how many rows have been written, i.e. at the *end* of what row we are in the output.)
	  
	  if (pfin.rownum-1 == numrows && fabs(pfin.sub.tsubint - fulltsubint) > pfin.hdr.dt) {
	    fprintf(stderr,
		    "Dropping partial row of length %f s (full row is %f s)\n",
		    pfin.sub.tsubint, fulltsubint);
	    break;
	  }
	  
	  //If we just read in the 1st row, or if we already wrote the last row in the current output file, create a new output file
	  if ((ii == 0 && rownum == 1) || pfout.rownum == maxrows) {
	    //Create new output file from the template
	    pfout.fnamedigits = pfin.fnamedigits;
	    if(ii == 0)
	      pfout.filenum = pfin.filenum;
	    else
	      pfout.filenum++;
	    
	    sprintf(outfilename, "%s.%0*d.fits", cmd->outfile, pfout.fnamedigits, pfout.filenum);
	    fits_create_template(&outfits, outfilename, templatename, &status);
	    //fprintf(stderr,"After fits_create_template, status: %d\n",status);
	    fits_close_file(outfits, &status);
	    
	    //Now reopen the file so that the pfout structure is initialized
	    pfout.status = 0;
	    pfout.initialized = 0;
	    
	    sprintf(pfout.basefilename, "%s.", cmd->outfile);
	    
            if (psrfits_open(&pfout, READWRITE) != 0) {
	      fprintf(stderr, "error opening file\n");
	      fits_report_error(stderr, pfout.status);
	      exit(1);
            }
            outfits = pfout.fptr;
            maxval = pow(2, cmd->numbits) - 1;
	    pfout.rows_per_file = maxrows;
	    
            //fprintf(stderr, "maxval: %f\n", maxval);
	    //fprintf(stderr, "pfout.rows_per_file: %d\n",pfout.rows_per_file);
	    
            //These are not initialized in psrfits_open but are needed 
            //in psrfits_write_subint (not obvious what are the corresponding 
            //fields in any of the psrfits table headers)
            pfout.hdr.ds_freq_fact = 1;
            pfout.hdr.ds_time_fact = 1;
	  }

            //Copy the subint struct from pfin to pfout, but correct 
            //elements that are not the same 
            pfout.sub = pfin.sub;       //this copies array pointers too
            pfout.sub.bytes_per_subint =
                pfin.sub.bytes_per_subint * pfout.hdr.nbits / pfin.hdr.nbits;
            pfout.sub.dataBytesAlloced = pfout.sub.bytes_per_subint;
            pfout.sub.FITS_typecode = TBYTE;

            if (first) {
                //Allocate scaling buffer and output buffer
                datachunk = gen_fvect(spec_per_row);
                outrowdata = gen_bvect(pfout.sub.bytes_per_subint);

                first = 0;
            }
            pfout.sub.data = outrowdata;

            inrowdata = (short int *) pfin.sub.data;
            nclipped = 0;

            // Loop over all the channels:
            for (ichan = 0; ichan < pfout.hdr.nchan * pfout.hdr.npol; ichan++) {
                // Populate datachunk[] by picking out all time samples for ichan
                for (itsamp = 0; itsamp < spec_per_row; itsamp++)
                    datachunk[itsamp] = (float) (inrowdata[ichan + itsamp *
                                                           pfout.hdr.nchan *
                                                           pfout.hdr.npol]);

                // Compute the statistics here, and put the offsets and scales in
                // pf.sub.dat_offsets[] and pf.sub.dat_scales[]

                if (rescale(datachunk, spec_per_row, cmd->numbits, &offset, &scale)
                    != 0) {
                    printf("Rescale routine failed!\n");
                    return (-1);
                }
                pfout.sub.dat_offsets[ichan] = offset;
                pfout.sub.dat_scales[ichan] = scale;

                // Since we have the offset and scale ready, rescale the data:
                for (itsamp = 0; itsamp < spec_per_row; itsamp++) {
                    datum = (scale == 0.0) ? 0.0 :
                        roundf((datachunk[itsamp] - offset) / scale);
                    if (datum < 0.0) {
                        datum = 0;
                        nclipped++;
                    } else if (datum > maxval) {
                        datum = maxval;
                        nclipped++;
                    }

                    inrowdata[ichan + itsamp * pfout.hdr.nchan * pfout.hdr.npol] =
                        (short int) datum;

                }
                // Now inrowdata[ichan] contains rescaled ints.
            }

            // Then do the conversion and store the
            // results in pf.sub.data[] 
            if (cmd->numbits == 8 || DEBUG) {
                for (itsamp = 0; itsamp < spec_per_row; itsamp++) {
                    datidx = itsamp * pfout.hdr.nchan * pfout.hdr.npol;
                    for (ichan = 0; ichan < pfout.hdr.nchan * pfout.hdr.npol;
                         ichan++, datidx++) {
                        pfout.sub.data[datidx] = (unsigned char) inrowdata[datidx];
                    }
                }
            } else if (cmd->numbits == 4) {
                for (itsamp = 0; itsamp < spec_per_row; itsamp++) {
                    datidx = itsamp * pfout.hdr.nchan * pfout.hdr.npol;
                    for (ichan = 0; ichan < pfout.hdr.nchan * pfout.hdr.npol;
                         ichan += 2, datidx += 2) {

                        packdatum = inrowdata[datidx] * 16 + inrowdata[datidx + 1];
                        pfout.sub.data[datidx / 2] = (unsigned char) packdatum;
                    }
                }
            } else {
                fprintf(stderr, "Only 4 or 8-bit output formats supported.\n");
                fprintf(stderr, "Bits per sample requested: %d\n", cmd->numbits);
                exit(1);
            }


            //pfout.sub.offs = (pfout.tot_rows+0.5) * pfout.sub.tsubint;
            fprintf(stderr, "nclipped: %d fraction clipped: %f\n", nclipped,
                    (float) nclipped / (pfout.hdr.nchan * pfout.hdr.npol *
                                        pfout.hdr.nsblk));

            // Now write the row. 
            status = psrfits_write_subint(&pfout);
            if (status) {
                printf("\nError (%d) writing PSRFITS...\n\n", status);
                break;
            }

	    //If current output file has reached the max # of rows, close it
	    if (pfout.rownum == maxrows)
	      fits_close_file(outfits, &status);
        }

        //Close the files 
        fits_close_file(infits, &status);
    }

    fits_close_file(outfits, &status);

    // Free the structure arrays too...
    free(datachunk);
    free(infiles);

    free(pfin.sub.dat_freqs);
    free(pfin.sub.dat_weights);
    free(pfin.sub.dat_offsets);
    free(pfin.sub.dat_scales);

    free(pfin.sub.data);
    free(pfout.sub.data);
    free(pfin.sub.stat);

    return 0;
}
Exemplo n.º 12
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);
}
Exemplo n.º 13
0
/* process this command */
static int ProcessCmd(char *cmd, char **args, int node, int tty)
{
  int ip=0;
  char tbuf[SZ_LINE];
  Finfo finfo, tfinfo;
#if HAVE_CFITSIO
  int x0, x1, y0, y1, bin;
  int xcolnum, ycolnum, hdunum, hdutype;
  int status=0, status2=0;
  int dims[2];
  double cens[2];
  char *cols[2] = {"X", "Y"};
  char *ofile=NULL;
  char *omode=NULL;
  fitsfile *ifptr, *ofptr, *tfptr;
#endif

  switch(*cmd){
  case 'f':
    if( !strcmp(cmd, "fitsFile") ){
      if( args && word(args[0], tbuf, &ip) ){
	if( !(tfinfo=FinfoLookup(tbuf)) ){
	  fprintf(stderr, NOIMAGE, tbuf);
	  return 1;
	}
      } else if( !(tfinfo=FinfoGetCurrent()) ){
	fprintf(stderr, NOFINFO, cmd);
	return 1;
      }
      if( tfinfo->fitsfile ){
	if( node ) fprintf(stdout, "fitsFile\r");
	fprintf(stdout, "%s %s\n", tfinfo->fname, tfinfo->fitsfile);
	fflush(stdout);
      }
      return 0;
    }
    break;
    break;
  case 'i':
    if( !strcmp(cmd, "image") ){
      if( !args || !word(args[0], tbuf, &ip) ){
	fprintf(stderr, WRONGARGS, cmd, 1, 0);
	return 1;
      }
      /* new image */
      if( !(finfo = FinfoNew(tbuf)) ){
	fprintf(stderr, NONEW, cmd);
	return 1;
      }
      /* make it current */
      FinfoSetCurrent(finfo);
      if( node ) fprintf(stdout, "image\r");
      /* return the FITS file name, if possible */
      fprintf(stdout, "%s %s\n",
	      finfo->fname, finfo->fitsfile ? finfo->fitsfile : "?");
      fflush(stdout);
      return 0;
    } else if( !strcmp(cmd, "image_") ){
      if( !args || !word(args[0], tbuf, &ip) ){
	fprintf(stderr, WRONGARGS, cmd, 1, 0);
	return 1;
      }
      /* new image */
      if( !(finfo = FinfoNew(tbuf)) ){
	fprintf(stderr, NONEW, cmd);
	return 1;
      }
      /* make it current */
      FinfoSetCurrent(finfo);
      /* no output! */
      return 0;
    } else if( !strcmp(cmd, "imsection") ){
#if HAVE_CFITSIO
      if( !(finfo=FinfoGetCurrent()) ){
	fprintf(stderr, NOFINFO, cmd);
	return 1;
      }
      ifptr = openFITSFile(finfo->fitsfile, EXTLIST, &hdutype, &status);
      if( status ){
	fprintf(stderr, "ERROR: can't open FITS file '%s'\n", finfo->fitsfile);
	return 1;
      }
      if( !args || !parseSection(args[0], &x0, &x1, &y0, &y1, &bin) ){
	fprintf(stderr,
		"ERROR: can't parse section for '%s' [%s]\n",
		finfo->fitsfile, (args && args[1]) ? args[1] : "NONE");
	return 1;
      }
      if( args[1] ){
	omode = args[1];
      } else {
	omode = "native";
      }
      ofile = "stdout";
      // create image if ifile is an image or omode is not native
      if( (hdutype == IMAGE_HDU) || strcmp(omode, "native") ){
	fits_create_file(&ofptr, ofile, &status);
	if( status ){
	  fits_get_errstatus(status, tbuf);
	  fprintf(stderr,
		  "ERROR: can't open output FITS file to section '%s' [%s]\n",
		  finfo->fitsfile, tbuf);
	  return 1;
	}
	switch(hdutype){
	case IMAGE_HDU:
	  if( bin != 1 ){
	    fprintf(stderr,
		    "ERROR: imsection of an image must use bin 1 for '%s'\n",
		    finfo->fitsfile);
	    return 1;
	  }
	  snprintf(tbuf, SZ_LINE-1, "%d:%d,%d:%d", x0, x1, y0, y1);
	  fits_copy_image_section(ifptr, ofptr, tbuf, &status);
	  break;
	default:
	  dims[0] = x1 - x0 + 1;
	  dims[1] = y1 - y0 + 1;
	  cens[0] = (x0 + x1) / 2;
	  cens[1] = (y0 + y1) / 2;
	  tfptr = filterTableToImage(ifptr, NULL, cols, dims, cens, bin,
				     &status);
	  if( status ){
	    fits_get_errstatus(status, tbuf);
	    fprintf(stderr,
		    "ERROR: can't create image from table for '%s' [%s]\n",
		    finfo->fitsfile, tbuf);
	    return 1;
	  }
	  fits_copy_image_section(tfptr, ofptr, "*,*", &status);
	  closeFITSFile(tfptr, &status2);
	  break;
	}
	if( status ){
	  fits_get_errstatus(status, tbuf);
	  fprintf(stderr,
		  "ERROR: can't write section FITS file for '%s' [%s]\n",
		  finfo->fitsfile, tbuf);
	  closeFITSFile(ofptr, &status);
	  return 1;
	}
	closeFITSFile(ofptr, &status);
      } else {
	// extract (native) table
	snprintf(tbuf, SZ_LINE-1,
		 "x >= %d && x <= %d && y >= %d && y <= %d",
		 x0, x1, y0, y1);
	// ffselect_table(&ifptr, ofile, tbuf, &status);
	// copied from cfileio.c/ffselect_table()
	/* create new empty file to hold copy of the image */
	if (ffinit(&ofptr, ofile, &status) > 0) {
	  fits_get_errstatus(status, tbuf);
	  fprintf(stderr,
		  "ERROR: can't init section file for '%s' [%s]\n",
		  finfo->fitsfile, tbuf);
	  return 1;
	}
	/* save current HDU number in input file */
	fits_get_hdu_num(ifptr, &hdunum);
	/* copy the primary array */
	fits_movabs_hdu(ifptr, 1, NULL, &status);
	if( fits_copy_hdu(ifptr, ofptr, 0, &status) > 0){
	  fits_get_errstatus(status, tbuf);
	  fprintf(stderr,
		  "ERROR: can't copy primary for section file '%s' [%s]\n",
		  finfo->fitsfile, tbuf);
	  fits_close_file(ofptr, &status);
	  return 1;
	}
	/* back to current hdu */
	fits_movabs_hdu(ifptr, hdunum, NULL, &status);
	/* copy all the header keywords from the input to output file */
	if (fits_copy_header(ifptr, ofptr, &status) > 0){
	  fits_get_errstatus(status, tbuf);
	  fprintf(stderr,
		  "ERROR: can't copy header for section file '%s' [%s]\n",
		  finfo->fitsfile, tbuf);
	  fits_close_file(ofptr, &status);
	  return 1;
	}
	/* set number of rows = 0 */
	/* warning: start of cfitsio black magic */
	fits_modify_key_lng(ofptr, "NAXIS2", 0, NULL, &status);
	(ofptr->Fptr)->numrows = 0;
	(ofptr->Fptr)->origrows = 0;
	/* force the header to be scanned */
	if (ffrdef(ofptr, &status) > 0){
	  fits_get_errstatus(status, tbuf);
	  fprintf(stderr,
		  "ERROR: can't rdef for section file '%s' [%s]\n",
		  finfo->fitsfile, tbuf);
	  fits_close_file(ofptr, &status);
	  return 1;
	}
	/* warning: end of cfitsio black magic */
	/* select filtered rows and write to output file */
	if (fits_select_rows(ifptr, ofptr, tbuf, &status) > 0){
	  fits_get_errstatus(status, tbuf);
	  fprintf(stderr,
		  "ERROR: can't select rows for section file '%s' [%s]\n",
		  finfo->fitsfile, tbuf);
	  fits_close_file(ofptr, &status);
	  return 1;
	}
	/* update params for this section */
	if( (fits_get_colnum(ofptr, CASEINSEN, "X", &xcolnum, &status) > 0) ||
	    (fits_get_colnum(ofptr, CASEINSEN, "Y", &ycolnum, &status) > 0) ){
	  fits_get_errstatus(status, tbuf);
	  fprintf(stderr,
		  "ERROR: can't find X,Y cols for section file '%s' [%s]\n",
		  finfo->fitsfile, tbuf);
	  fits_close_file(ofptr, &status);
	  return 1;
	}
	/* we can ignore errors here */
	status = 0;
	snprintf(tbuf, SZ_LINE-1, "TALEN%d", xcolnum);
	fits_modify_key_lng(ofptr, tbuf, x1-x0, NULL, &status);
	status = 0;
	snprintf(tbuf, SZ_LINE-1, "TALEN%d", ycolnum);
	fits_modify_key_lng(ofptr, tbuf, y1-y0, NULL, &status);
	status = 0;
	snprintf(tbuf, SZ_LINE-1, "TLMIN%d", xcolnum);
	fits_modify_key_flt(ofptr, tbuf, x0, 6, NULL, &status);
	status = 0;
	snprintf(tbuf, SZ_LINE-1, "TLMAX%d", xcolnum);
	fits_modify_key_flt(ofptr, tbuf, x1, 6, NULL, &status);
	status = 0;
	snprintf(tbuf, SZ_LINE-1, "TLMIN%d", ycolnum);
	fits_modify_key_flt(ofptr, tbuf, y0, 6, NULL, &status);
	status = 0;
	snprintf(tbuf, SZ_LINE-1, "TLMAX%d", ycolnum);
	fits_modify_key_flt(ofptr, tbuf, y1, 6, NULL, &status);
	/* close the output file */
	status = 0;
	fits_close_file(ofptr, &status);
      }
      closeFITSFile(ifptr, &status);
      return 0;
#else
      fprintf(stderr,
	      "ERROR: for section support, build js9helper with cfitsio\n");
      return 1;
#endif
    } else if( !strcmp(cmd, "info") ){
      if( tty ){
	if( !(finfo=FinfoGetCurrent()) ){
	  fprintf(stderr, NOFINFO, cmd);
	  return 1;
	}
	/* make sure we have a wcs */
	fprintf(stdout, "fname:\t%s\n", finfo->fname);
	fprintf(stdout, "fits:\t%s\n", finfo->fitsfile?finfo->fitsfile:"N/A");
	fflush(stdout);
      }
      return 0;
    }
    break;
  case 'l':
    /* list all images */
    if( !strcmp(cmd, "list") ){
      FinfoList(stdout);
      return 0;
    }
    break;
  case 's':
    if( !strcmp(cmd, "setDataPath") ){
      if( args && word(args[0], tbuf, &ip) ){
	setenv("JS9_DATAPATH", tbuf, 1);
	if( node ) fprintf(stdout, "setDataPath\r");
	fprintf(stdout, "%s\n", getenv("JS9_DATAPATH"));
	fflush(stdout);
      } else {
	fprintf(stderr, WRONGARGS, cmd, 1, 0);
	return 1;
      }
      return 0;
    }
    break;
  case 'u':
    if( !strcmp(cmd, "unimage") ){
      if( !args || !word(args[0], tbuf, &ip) ){
	fprintf(stderr, WRONGARGS, cmd, 1, 0);
	return 1;
      }
      /* close this image */
      FinfoFree(tbuf);
      return 0;
    }
    break;
  case '#':
  case '\0':
    return 0;
  default:
    break;
  }
  /* if we reached here, we did not recognize the command */
  fprintf(stderr, "ERROR: unknown command '%s'\n", cmd);
  /* return the news */
  return 2;
}