///////////////////////////////////////////////////////// /// Add applicable FITS keywords to header ///////////////////////////////////////////////////////// void ATIKCCD::addFITSKeywords(fitsfile *fptr, INDI::CCDChip *targetChip) { INDI::CCD::addFITSKeywords(fptr, targetChip); if (m_isHorizon) { int status = 0; fits_update_key_dbl(fptr, "Gain", ControlN[CONTROL_GAIN].value, 3, "Gain", &status); fits_update_key_dbl(fptr, "Offset", ControlN[CONTROL_OFFSET].value, 3, "Offset", &status); } }
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; }
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; }
int main(int argc, char **argv) { int i, j, c, ifile, status; long fpixel[4], nelements; int nullcnt; int imin, jmin, haveMinMax; int imax, jmax; int istart, iend, ilength; int jstart, jend, jlength; double *buffer, *abuffer; double datamin, datamax; double areamin, areamax; int narea1, narea2; double avearea1, avearea2; double maxarea1, maxarea2; double pixel_value; double **data; double **area; char template_file[MAXSTR]; char line [MAXSTR]; char infile[2][MAXSTR]; char inarea[2][MAXSTR]; /*************************************************/ /* Initialize output FITS basic image parameters */ /*************************************************/ int bitpix = DOUBLE_IMG; long naxis = 2; /************************************************/ /* Make a NaN value to use setting blank pixels */ /************************************************/ union { double d; char c[8]; } value; double nan; for(i=0; i<8; ++i) value.c[i] = 255; nan = value.d; /***************************************/ /* Process the command-line parameters */ /***************************************/ debug = 0; noAreas = 0; coverageLimit = 0.0001; opterr = 0; fstatus = stdout; while ((c = getopt(argc, argv, "nc:d:s:")) != EOF) { switch (c) { case 'n': noAreas = 1; break; case 'c': coverageLimit = atof(optarg); break; case 'd': debug = debugCheck(optarg); break; case 's': if((fstatus = fopen(optarg, "w+")) == (FILE *)NULL) { printf("[struct stat=\"ERROR\", msg=\"Cannot open status file: %s\"]\n", optarg); exit(1); } break; default: printf("[struct stat=\"ERROR\", msg=\"Usage: %s [-d level] [-n(o-areas)] [-s statusfile] in1.fits in2.fits out.fits hdr.template\"]\n", argv[0]); exit(1); break; } } if (argc - optind < 4) { printf("[struct stat=\"ERROR\", msg=\"Usage: %s [-d level] [-n(o-areas)] [-s statusfile] in1.fits in2.fits out.fits hdr.template\"]\n", argv[0]); exit(1); } strcpy(input_file1, argv[optind]); strcpy(input_file2, argv[optind + 1]); strcpy(output_file, argv[optind + 2]); strcpy(template_file, argv[optind + 3]); checkHdr(template_file, 1, 0); if(strlen(output_file) > 5 && strncmp(output_file+strlen(output_file)-5, ".fits", 5) == 0) output_file[strlen(output_file)-5] = '\0'; strcpy(output_area_file, output_file); strcat(output_file, ".fits"); strcat(output_area_file, "_area.fits"); if(debug >= 1) { printf("input_file1 = [%s]\n", input_file1); printf("input_file2 = [%s]\n", input_file2); printf("output_file = [%s]\n", output_file); printf("output_area_file = [%s]\n", output_area_file); printf("template_file = [%s]\n", template_file); fflush(stdout); } /****************************/ /* Get the input file names */ /****************************/ if(strlen(input_file1) > 5 && strcmp(input_file1+strlen(input_file1)-5, ".fits") == 0) { strcpy(line, input_file1); line[strlen(line)-5] = '\0'; strcpy(infile[0], line); strcat(infile[0], ".fits"); strcpy(inarea[0], line); strcat(inarea[0], "_area.fits"); } else { strcpy(infile[0], input_file1); strcat(infile[0], ".fits"); strcpy(inarea[0], input_file1); strcat(inarea[0], "_area.fits"); } if(strlen(input_file2) > 5 && strcmp(input_file2+strlen(input_file2)-5, ".fits") == 0) { strcpy(line, input_file2); line[strlen(line)-5] = '\0'; strcpy(infile[1], line); strcat(infile[1], ".fits"); strcpy(inarea[1], line); strcat(inarea[1], "_area.fits"); } else { strcpy(infile[1], input_file2); strcat(infile[1], ".fits"); strcpy(inarea[1], input_file2); strcat(inarea[1], "_area.fits"); } if(debug >= 1) { printf("\ninput files:\n\n"); printf(" [%s][%s]\n", infile[0], inarea[0]); printf(" [%s][%s]\n", infile[1], inarea[1]); printf("\n"); } /*************************************************/ /* Process the output header template to get the */ /* image size, coordinate system and projection */ /*************************************************/ readTemplate(template_file); if(debug >= 1) { printf("output.naxes[0] = %ld\n", output.naxes[0]); printf("output.naxes[1] = %ld\n", output.naxes[1]); printf("output.crpix1 = %-g\n", output.crpix1); printf("output.crpix2 = %-g\n", output.crpix2); fflush(stdout); } /*****************************************************/ /* We open the two input files briefly to get enough */ /* information to determine the region of overlap */ /* (for memory allocation purposes) */ /*****************************************************/ readFits(infile[0], inarea[0]); imin = output.crpix1 - input.crpix1; jmin = output.crpix2 - input.crpix2; imax = imin + input.naxes[0]; jmax = jmin + input.naxes[1]; istart = imin; iend = imax; jstart = jmin; jend = jmax; if(debug >= 1) { printf("\nFile 1:\n"); printf("input.naxes[0] = %ld\n", input.naxes[0]); printf("input.naxes[1] = %ld\n", input.naxes[1]); printf("input.crpix1 = %-g\n", input.crpix1); printf("input.crpix2 = %-g\n", input.crpix2); printf("imin = %d\n", imin); printf("imax = %d\n", imax); printf("jmin = %d\n", jmin); printf("jmax = %d\n\n", jmax); printf("istart = %d\n", istart); printf("iend = %d\n", iend); printf("jstart = %d\n", jstart); printf("jend = %d\n", jend); fflush(stdout); } status = 0; if(fits_close_file(input.fptr, &status)) printFitsError(status); if(!noAreas) { if(fits_close_file(input_area.fptr, &status)) printFitsError(status); } readFits(infile[1], inarea[1]); imin = output.crpix1 - input.crpix1; jmin = output.crpix2 - input.crpix2; imax = imin + input.naxes[0]; jmax = jmin + input.naxes[1]; if(debug >= 1) { printf("\nFile 2:\n"); printf("input.naxes[0] = %ld\n", input.naxes[0]); printf("input.naxes[1] = %ld\n", input.naxes[1]); printf("input.crpix1 = %-g\n", input.crpix1); printf("input.crpix2 = %-g\n", input.crpix2); printf("imin = %d\n", imin); printf("imax = %d\n", imax); printf("jmin = %d\n", jmin); printf("jmax = %d\n", jmax); printf("istart = %d\n\n", istart); printf("iend = %d\n", iend); printf("jstart = %d\n", jstart); printf("jend = %d\n", jend); printf("\n"); fflush(stdout); } if(imin > istart) istart = imin; if(imax < iend ) iend = imax; if(jmin > jstart) jstart = jmin; if(jmax < jend ) jend = jmax; if(istart < 0) istart = 0; if(jstart < 0) jstart = 0; if(iend > output.naxes[0]-1) iend = output.naxes[0]-1; if(jend > output.naxes[1]-1) jend = output.naxes[1]-1; ilength = iend - istart + 1; jlength = jend - jstart + 1; if(debug >= 1) { printf("\nComposite:\n"); printf("input.naxes[0] = %ld\n", input.naxes[0]); printf("input.naxes[1] = %ld\n", input.naxes[1]); printf("input.crpix1 = %-g\n", input.crpix1); printf("input.crpix2 = %-g\n", input.crpix2); printf("istart = %d\n", istart); printf("iend = %d\n", iend); printf("jstart = %d\n", jstart); printf("jend = %d\n", jend); printf("ilength = %d\n", ilength); printf("jlength = %d\n", jlength); printf("\n"); fflush(stdout); } if(fits_close_file(input.fptr, &status)) printFitsError(status); if(!noAreas) { if(fits_close_file(input_area.fptr, &status)) printFitsError(status); } /*********************/ /* Check for overlap */ /*********************/ if(ilength <= 0 || jlength <= 0) printError("Images don't overlap"); /***********************************************/ /* Allocate memory for the output image pixels */ /***********************************************/ data = (double **)malloc(jlength * sizeof(double *)); for(j=0; j<jlength; ++j) data[j] = (double *)malloc(ilength * sizeof(double)); if(debug >= 1) { printf("%d bytes allocated for image pixels\n", ilength * jlength * sizeof(double)); fflush(stdout); } /****************************/ /* Initialize data to zeros */ /****************************/ for (j=0; j<jlength; ++j) { for (i=0; i<ilength; ++i) { data[j][i] = 0.; } } /**********************************************/ /* Allocate memory for the output pixel areas */ /**********************************************/ area = (double **)malloc(jlength * sizeof(double *)); for(j=0; j<jlength; ++j) area[j] = (double *)malloc(ilength * sizeof(double)); if(debug >= 1) { printf("%d bytes allocated for pixel areas\n", ilength * jlength * sizeof(double)); fflush(stdout); } /****************************/ /* Initialize area to zeros */ /****************************/ for (j=0; j<jlength; ++j) { for (i=0; i<ilength; ++i) { area[j][i] = 0.; } } /***************************/ /* For the two input files */ /***************************/ time(&currtime); start = currtime; avearea1 = 0.; avearea2 = 0.; maxarea1 = 0.; maxarea2 = 0.; narea1 = 0.; narea2 = 0.; for(ifile=0; ifile<2; ++ifile) { /************************/ /* Read the input image */ /************************/ readFits(infile[ifile], inarea[ifile]); imin = output.crpix1 - input.crpix1; jmin = output.crpix2 - input.crpix2; if(debug >= 1) { printf("\nflux file = %s\n", infile[ifile]); printf("input.naxes[0] = %ld\n", input.naxes[0]); printf("input.naxes[1] = %ld\n", input.naxes[1]); printf("input.crpix1 = %-g\n", input.crpix1); printf("input.crpix2 = %-g\n", input.crpix2); printf("\narea file = %s\n", inarea[ifile]); printf("input_area.naxes[0] = %ld\n", input.naxes[0]); printf("input_area.naxes[1] = %ld\n", input.naxes[1]); printf("input_area.crpix1 = %-g\n", input.crpix1); printf("input_area.crpix2 = %-g\n", input.crpix2); printf("\nimin = %d\n", imin); printf("jmin = %d\n\n", jmin); fflush(stdout); } /**********************************************************/ /* Create the output array by processing the input pixels */ /**********************************************************/ buffer = (double *)malloc(input.naxes[0] * sizeof(double)); abuffer = (double *)malloc(input.naxes[0] * sizeof(double)); fpixel[0] = 1; fpixel[1] = 1; fpixel[2] = 1; fpixel[3] = 1; nelements = input.naxes[0]; status = 0; /*****************************/ /* Loop over the input lines */ /*****************************/ for (j=0; j<input.naxes[1]; ++j) { if(debug >= 2) { printf("\rProcessing input row %5d ", j); fflush(stdout); } /***********************************/ /* Read a line from the input file */ /***********************************/ if(fits_read_pix(input.fptr, TDOUBLE, fpixel, nelements, NULL, buffer, &nullcnt, &status)) printFitsError(status); if(noAreas) { for(i=0; i<input.naxes[0]; ++i) abuffer[i] = 1.; } else { if(fits_read_pix(input_area.fptr, TDOUBLE, fpixel, nelements, NULL, abuffer, &nullcnt, &status)) printFitsError(status); } ++fpixel[1]; /************************/ /* For each input pixel */ /************************/ for (i=0; i<input.naxes[0]; ++i) { pixel_value = buffer[i] * abuffer[i]; if(debug >= 4) { printf("input: line %5d / pixel %5d, value = %10.2e (%10.2e) [array: %5d %5d]\n", j, i, buffer[i], abuffer[i], j+jmin-jstart, i+imin-istart); fflush(stdout); } if(i+imin < istart) continue; if(j+jmin < jstart) continue; if(i+imin >= iend) continue; if(j+jmin >= jend) continue; if(debug >= 3) { printf("keep: line %5d / pixel %5d, value = %10.2e (%10.2e) [array: %5d %5d]\n", j, i, buffer[i], abuffer[i], j+jmin-jstart, i+imin-istart); fflush(stdout); } if(ifile == 0) { if(mNaN(buffer[i]) || abuffer[i] <= 0.) { if(debug >= 5) { printf("First file. Setting data to NaN and area to zero.\n"); fflush(stdout); } data[j+jmin-jstart][i+imin-istart] = nan; area[j+jmin-jstart][i+imin-istart] = 0.; if(debug >= 5) { printf("done.\n"); fflush(stdout); } continue; } else { if(debug >= 5) { printf("First file. Setting data to pixel value.\n"); fflush(stdout); } data[j+jmin-jstart][i+imin-istart] = pixel_value; area[j+jmin-jstart][i+imin-istart] = abuffer[i]; ++narea1; avearea1 += abuffer[i]; if(abuffer[i] > maxarea1) maxarea1 = abuffer[i]; if(debug >= 5) { printf("done.\n"); fflush(stdout); } } } else { if(mNaN(buffer[i]) || abuffer[i] <= 0. || data[j+jmin-jstart][i+imin-istart] == nan || area[j+jmin-jstart][i+imin-istart] == 0.) { if(debug >= 5) { printf("Second file. One or the other value is NaN (or zero area).\n"); fflush(stdout); } data[j+jmin-jstart][i+imin-istart] = nan; area[j+jmin-jstart][i+imin-istart] = 0.; continue; } else { if(debug >= 5) { printf("Second file. Subtracting pixel value.\n"); fflush(stdout); } data[j+jmin-jstart][i+imin-istart] -= pixel_value; area[j+jmin-jstart][i+imin-istart] += abuffer[i]; ++narea2; avearea2 += abuffer[i]; if(abuffer[i] > maxarea2) maxarea2 = abuffer[i]; if(debug >= 5) { printf("done.\n"); fflush(stdout); } } } } } free(buffer); free(abuffer); if(fits_close_file(input.fptr, &status)) printFitsError(status); if(!noAreas) { if(fits_close_file(input_area.fptr, &status)) printFitsError(status); } } if(debug >= 1) { time(&currtime); printf("\nDone reading data (%.0f seconds)\n", (double)(currtime - start)); fflush(stdout); } /************************************/ /* Anly keep those pixels that were */ /* covered twice reasonably fully */ /************************************/ avearea1 = avearea1/narea1; avearea2 = avearea2/narea2; areamax = maxarea1 + maxarea2; if(debug >= 2) { printf("\npixel areas: %-g + %-g = %-g\n\n", avearea1, avearea2, areamax); fflush(stdout); } for (j=0; j<jlength; ++j) { for (i=0; i<ilength; ++i) { if(mNaN(area[j][i]) || area[j][i] == 0.) { data[j][i] = 0.; area[j][i] = 0.; } else { if(fabs(area[j][i] - areamax)/areamax > coverageLimit) { data[j][i] = 0.; area[j][i] = 0.; } } } } /*********************************/ /* Normalize image data based on */ /* total area added to pixel */ /*********************************/ haveMinMax = 0; datamax = 0., datamin = 0.; areamin = 0.; areamax = 0.; imin = 99999; imax = 0; jmin = 99999; jmax = 0; for (j=0; j<jlength; ++j) { for (i=0; i<ilength; ++i) { if(area[j][i] > 0.) { data[j][i] = 2. * data[j][i] / area[j][i]; if(!haveMinMax) { datamin = data[j][i]; datamax = data[j][i]; areamin = area[j][i]; areamax = area[j][i]; haveMinMax = 1; } if(data[j][i] < datamin) datamin = data[j][i]; if(data[j][i] > datamax) datamax = data[j][i]; if(area[j][i] < areamin) areamin = area[j][i]; if(area[j][i] > areamax) areamax = area[j][i]; if(j < jmin) jmin = j; if(j > jmax) jmax = j; if(i < imin) imin = i; if(i > imax) imax = i; } else { data[j][i] = nan; area[j][i] = 0.; } } } imin += istart; jmin += jstart; imax += istart; jmax += jstart; if(debug >= 1) { printf("Data min = %-g\n", datamin); printf("Data max = %-g\n", datamax); printf("Area min = %-g\n", areamin); printf("Area max = %-g\n\n", areamax); printf("j min = %d\n", jmin); printf("j max = %d\n", jmax); printf("i min = %d\n", imin); printf("i max = %d\n", imax); } if(jmin > jmax || imin > imax) printError("All pixels are blank."); /********************************/ /* Create the output FITS files */ /********************************/ remove(output_file); remove(output_area_file); if(fits_create_file(&output.fptr, output_file, &status)) printFitsError(status); if(fits_create_file(&output_area.fptr, output_area_file, &status)) printFitsError(status); /*********************************************************/ /* Create the FITS image. All the required keywords are */ /* handled automatically. */ /*********************************************************/ if (fits_create_img(output.fptr, bitpix, naxis, output.naxes, &status)) printFitsError(status); if(debug >= 1) { printf("\nFITS data image created (not yet populated)\n"); fflush(stdout); } if (fits_create_img(output_area.fptr, bitpix, naxis, output_area.naxes, &status)) printFitsError(status); if(debug >= 1) { printf("FITS area image created (not yet populated)\n"); fflush(stdout); } /****************************************/ /* Set FITS header from a template file */ /****************************************/ if(fits_write_key_template(output.fptr, template_file, &status)) printFitsError(status); if(debug >= 1) { printf("Template keywords written to FITS data image\n"); fflush(stdout); } if(fits_write_key_template(output_area.fptr, template_file, &status)) printFitsError(status); if(debug >= 1) { printf("Template keywords written to FITS area image\n\n"); fflush(stdout); } /***************************/ /* Modify BITPIX to be -64 */ /***************************/ if(fits_update_key_lng(output.fptr, "BITPIX", -64, (char *)NULL, &status)) printFitsError(status); if(fits_update_key_lng(output_area.fptr, "BITPIX", -64, (char *)NULL, &status)) printFitsError(status); /***************************************************/ /* Update NAXIS, NAXIS1, NAXIS2, CRPIX1 and CRPIX2 */ /***************************************************/ if(fits_update_key_lng(output.fptr, "NAXIS", 2, (char *)NULL, &status)) printFitsError(status); if(fits_update_key_lng(output.fptr, "NAXIS1", imax-imin+1, (char *)NULL, &status)) printFitsError(status); if(fits_update_key_lng(output.fptr, "NAXIS2", jmax-jmin+1, (char *)NULL, &status)) printFitsError(status); if(fits_update_key_dbl(output.fptr, "CRPIX1", output.crpix1-imin, -14, (char *)NULL, &status)) printFitsError(status); if(fits_update_key_dbl(output.fptr, "CRPIX2", output.crpix2-jmin, -14, (char *)NULL, &status)) printFitsError(status); if(fits_update_key_lng(output_area.fptr, "NAXIS", 2, (char *)NULL, &status)) printFitsError(status); if(fits_update_key_lng(output_area.fptr, "NAXIS1", imax-imin+1, (char *)NULL, &status)) printFitsError(status); if(fits_update_key_lng(output_area.fptr, "NAXIS2", jmax-jmin+1, (char *)NULL, &status)) printFitsError(status); if(fits_update_key_dbl(output_area.fptr, "CRPIX1", output.crpix1-imin, -14, (char *)NULL, &status)) printFitsError(status); if(fits_update_key_dbl(output_area.fptr, "CRPIX2", output.crpix2-jmin, -14, (char *)NULL, &status)) printFitsError(status); if(debug >= 1) { printf("Template keywords BITPIX, CRPIX, and NAXIS updated\n"); fflush(stdout); } /************************/ /* Write the image data */ /************************/ fpixel[0] = 1; fpixel[1] = 1; nelements = imax - imin + 1; for(j=jmin; j<=jmax; ++j) { if (fits_write_pix(output.fptr, TDOUBLE, fpixel, nelements, (void *)(&data[j-jstart][imin-istart]), &status)) printFitsError(status); ++fpixel[1]; } free(data[0]); if(debug >= 1) { printf("Data written to FITS data image\n"); fflush(stdout); } /***********************/ /* Write the area data */ /***********************/ fpixel[0] = 1; fpixel[1] = 1; nelements = imax - imin + 1; for(j=jmin; j<=jmax; ++j) { if (fits_write_pix(output_area.fptr, TDOUBLE, fpixel, nelements, (void *)(&area[j-jstart][imin-istart]), &status)) printFitsError(status); ++fpixel[1]; } free(area[0]); if(debug >= 1) { printf("Data written to FITS area image\n\n"); fflush(stdout); } /***********************/ /* Close the FITS file */ /***********************/ if(fits_close_file(output.fptr, &status)) printFitsError(status); if(debug >= 1) { printf("FITS data image finalized\n"); fflush(stdout); } if(fits_close_file(output_area.fptr, &status)) printFitsError(status); if(debug >= 1) { printf("FITS area image finalized\n\n"); fflush(stdout); } if(debug >= 1) { time(&currtime); printf("Done (%.0f seconds total)\n", (double)(currtime - start)); fflush(stdout); } fprintf(fstatus, "[struct stat=\"OK\"]\n"); fflush(stdout); exit(0); }
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; }