int fits_update_key_from_str(fitsfile* fptr, int datatype, char* name, char* valstr, char* comment, int* status) { if (*status > 0) return *status; if (datatype == UNDEFINED_TYPE) datatype = fits_detect_key_type(valstr); float cf[2]; double cd[2]; char keyval[FLEN_VALUE]; switch(datatype) { case TSTRING: removequotes(valstr, keyval); fits_update_key_str(fptr, name, keyval, comment, status); break; case TBYTE: case TSBYTE: case TUSHORT: case TSHORT: case TINT: case TLONG: fits_update_key_lng(fptr, name, atol(valstr), comment, status); break; case TUINT: case TULONG: fits_update_key_lng(fptr, name, atof(valstr), comment, status); break; case TLOGICAL: fits_update_key_log(fptr, name, strcasecmp(valstr,"TRUE") == 0 ? TRUE: FALSE , comment, status); break; case TFLOAT: fits_update_key_flt(fptr, name, atof(valstr), -7, comment, status); break; case TDOUBLE: fits_update_key_dbl(fptr, name, atof(valstr), -15, comment, status); break; /* For the complex numbers, we assume the string format: 1+3i or 1+3j */ case TCOMPLEX: if (sscanf(valstr,"(%f,%f)", cf, cf+1) == 2) fits_update_key_fixcmp(fptr, name, cf, -7, comment, status); else fprintf(stderr, " Error in %s : wrong complex format in %s", __func__, valstr); break; case TDBLCOMPLEX: if (sscanf(valstr,"(%lf,%lf)", cd, cd+1) == 2) fits_update_key_dblcmp(fptr, name, cd, -15, comment, status); else fprintf(stderr, " Error in %s : wrong complex format in %s", __func__, valstr); break; default: *status = BAD_DATATYPE; } return *status; }
void write_fits(char *filename, int w, int h, unsigned short *data, double obs_duration, char* obs_type, double obs_temperature, int obs_filterNumber, char* serial_number, char* name, char* ra, char* dec, char* alt, char * az ) { fitsfile *fptr; /* pointer to the FITS file, defined in fitsio.h */ int status; long fpixel, nelements; /* Initialize FITS image parameters */ int bitpix = USHORT_IMG; /* 16-bit unsigned short pixel values */ long naxis = 2; /* 2-dimensional image */ long naxes[2] = { 256,256 }; /* default image 256 wide by 256 rows */ /* Set the actual width and height of the image */ naxes[0] = w; naxes[1] = h; /* Delete old FITS file if it already exists */ remove(filename); /* Must initialize status before calling fitsio routines */ status = 0; /* Create a new FITS file and show error message if one occurs */ if (fits_create_file(&fptr, filename, &status)) show_cfitsio_error( status ); /* Write the required keywords for the primary array image. */ /* Since bitpix = USHORT_IMG, this will cause cfitsio to create */ /* a FITS image with BITPIX = 16 (signed short integers) with */ /* BSCALE = 1.0 and BZERO = 32768. This is the convention that */ /* FITS uses to store unsigned integers. Note that the BSCALE */ /* and BZERO keywords will be automatically written by cfitsio */ /* in this case. */ if ( fits_create_img(fptr, bitpix, naxis, naxes, &status) ) show_cfitsio_error( status ); fpixel = 1; /* first pixel to write */ nelements = naxes[0] * naxes[1]; /* number of pixels to write */ /* Write the array of unsigned integers to the FITS file */ if ( fits_write_img(fptr, TUSHORT, fpixel, nelements, data, &status) ) show_cfitsio_error( status ); /* Write optional keywords to the header */ if ( fits_update_key_dbl(fptr, "EXPTIME", obs_duration, -3, "exposure time (seconds)", &status) ) show_cfitsio_error( status ); if ( fits_update_key_dbl(fptr, "TEMPERAT", obs_temperature, -3, "temperature (C)", &status) ) show_cfitsio_error( status ); if ( fits_update_key_str(fptr, "IMAGETYP", obs_type, "image type", &status) ) show_cfitsio_error( status ); if ( fits_update_key(fptr, TSHORT, "FILTNUM", &obs_filterNumber, NULL, &status)) show_cfitsio_error( status ); if ( fits_write_date(fptr, &status) ) show_cfitsio_error( status ); if ( fits_update_key_str(fptr, "SERIALNO", serial_number, "serial number", &status) ) show_cfitsio_error( status ); if ( fits_update_key_str(fptr, "TARGET", name, "target name", &status) ) show_cfitsio_error( status ); if ( fits_update_key_str(fptr, "RA", ra, "right ascension", &status) ) show_cfitsio_error( status ); if ( fits_update_key_str(fptr, "DEC", dec, "declination", &status) ) show_cfitsio_error( status ); if ( fits_update_key_str(fptr, "EPOCH", "JNOW", "epoch of coordinates", &status) ) show_cfitsio_error( status ); if ( fits_update_key_str(fptr, "OBJCTRA", ra, "right ascension", &status) ) show_cfitsio_error( status ); if ( fits_update_key_str(fptr, "OBJCTDEC", dec, "declination", &status) ) show_cfitsio_error( status ); if ( fits_update_key_dbl(fptr, "ALTITUDE", atof(alt), -4, "Altitude (deg)", &status) ) show_cfitsio_error( status ); if ( fits_update_key_dbl(fptr, "AZIMUTH", atof(az), -4, "Azimuth (deg)", &status) ) show_cfitsio_error( status ); /* Close the file */ if ( fits_close_file(fptr, &status) ) show_cfitsio_error( status ); return; }
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; }