int readFits(char *fluxfile) { int status, nfound; long naxes[2]; double crpix[2]; char errstr[MAXSTR]; status = 0; checkHdr(fluxfile, 0, 0); if(fits_open_file(&input.fptr, fluxfile, READONLY, &status)) { sprintf(errstr, "Image file %s missing or invalid FITS", fluxfile); printError(errstr); } if(fits_read_keys_lng(input.fptr, "NAXIS", 1, 2, naxes, &nfound, &status)) printFitsError(status); input.naxes[0] = naxes[0]; input.naxes[1] = naxes[1]; if(fits_read_keys_dbl(input.fptr, "CRPIX", 1, 2, crpix, &nfound, &status)) printFitsError(status); input.crpix1 = crpix[0]; input.crpix2 = crpix[1]; 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); }
int main(int argc, char **argv) { int c; char header[32768]; char temp [MAXSTR]; char fmt [MAXSTR]; char rfmt [MAXSTR]; char pfmt [MAXSTR]; char cfmt [MAXSTR]; char ofile [MAXSTR]; char scale [MAXSTR]; int i, j; int namelen, nimages, ntotal, stat; double xpos, ypos; double lon, lat; double oxpix, oypix; int oxpixMin, oypixMin; int oxpixMax, oypixMax; int offscl, mode; int ncols; FILE *fraw; FILE *fproj; FILE *fcorr; /***************************************/ /* Process the command-line parameters */ /***************************************/ debug = 0; opterr = 0; fstatus = stdout; while ((c = getopt(argc, argv, "ds:")) != EOF) { switch (c) { case 'd': debug = 1; 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][-s statusfile] images.tbl hdr.template raw.tbl projected.tbl corrected.tbl\"]\n", argv[0]); exit(1); break; } } if (argc - optind < 5) { printf("[struct stat=\"ERROR\", msg=\"Usage: %s [-d][-s statusfile] images.tbl hdr.template raw.tbl projected.tbl corrected.tbl\"]\n", argv[0]); exit(1); } strcpy(origimg_file, argv[optind]); strcpy(template_file, argv[optind + 1]); strcpy(rawimg_file, argv[optind + 2]); strcpy(projimg_file, argv[optind + 3]); strcpy(corrimg_file, argv[optind + 4]); checkHdr(template_file, 1, 0); if(debug) { printf("\norigimg_file = [%s]\n", origimg_file); printf("template_file = [%s]\n\n", template_file); printf("rawimg_file = [%s]\n", rawimg_file); printf("projimg_file = [%s]\n", projimg_file); printf("corrimg_file = [%s]\n", corrimg_file); fflush(stdout); } /*************************************************/ /* Process the output header template to get the */ /* image size, coordinate system and projection */ /*************************************************/ readTemplate(template_file); if(debug) { printf("\noutput.sys = %d\n", output.sys); printf("output.epoch = %-g\n", output.epoch); printf("output proj = %s\n", output.wcs->ptype); fflush(stdout); } /*********************************************/ /* Open the image header metadata table file */ /*********************************************/ ncols = topen(origimg_file); if(ncols <= 0) { fprintf(fstatus, "[struct stat=\"ERROR\", msg=\"Invalid image metadata file: %s\"]\n", origimg_file); exit(1); } icntr = tcol("cntr"); ictype1 = tcol("ctype1"); ictype2 = tcol("ctype2"); iequinox = tcol("equinox"); inl = tcol("nl"); ins = tcol("ns"); icrval1 = tcol("crval1"); icrval2 = tcol("crval2"); icrpix1 = tcol("crpix1"); icrpix2 = tcol("crpix2"); icdelt1 = tcol("cdelt1"); icdelt2 = tcol("cdelt2"); icrota2 = tcol("crota2"); iepoch = tcol("epoch"); ifname = tcol("fname"); iscale = tcol("scale"); icd11 = tcol("cd1_1"); icd12 = tcol("cd1_2"); icd21 = tcol("cd2_1"); icd22 = tcol("cd2_2"); if(ins < 0) ins = tcol("naxis1"); if(inl < 0) inl = tcol("naxis2"); if(ifname < 0) ifname = tcol("file"); if(icd11 >= 0 && icd12 >= 0 && icd21 >= 0 && icd12 >= 0) mode = CD; else if(icdelt1 >= 0 && icdelt2 >= 0 && icrota2 >= 0) mode = CDELT; else { fprintf(fstatus, "[struct stat=\"ERROR\", msg=\"Not enough information to determine coverages (CDELTs or CD matrix)\"]\n"); exit(1); } if(icntr < 0 || ictype1 < 0 || ictype2 < 0 || inl < 0 || ins < 0 || icrval1 < 0 || icrval2 < 0 || icrpix1 < 0 || icrpix2 < 0 || ifname < 0) { fprintf(fstatus, "[struct stat=\"ERROR\", msg=\"Need columns: cntr ctype1 ctype2 nl ns crval1 crval2 crpix1 crpix2 cdelt1 cdelt2 crota2 fname (equinox optional)\"]\n"); exit(1); } /******************************************************/ /* Scan the table to get the true 'file' column width */ /******************************************************/ namelen = 0; while(1) { stat = tread(); if(stat < 0) break; strcpy(input.fname, fileName(tval(ifname))); if(strlen(input.fname) > namelen) namelen = strlen(input.fname); } tseek(0); /*************************************/ /* Write headers to the output files */ /*************************************/ if((fraw = (FILE *)fopen(rawimg_file, "w+")) == (FILE *)NULL) { fprintf(fstatus, "[struct stat=\"ERROR\", msg=\"Invalid output metadata file: %s\"]\n", rawimg_file); exit(1); } fprintf(fraw, "\\datatype=fitshdr\n"); if(iscale >= 0) { sprintf(fmt, "|%%5s|%%8s|%%8s|%%6s|%%6s|%%10s|%%10s|%%10s|%%10s|%%11s|%%11s|%%8s|%%7s|%%10s|%%%ds|\n", namelen+2); fprintf(fraw, fmt, "cntr", "ctype1", "ctype2", "naxis1", "naxis2", "crval1", "crval2", "crpix1", "crpix2", "cdelt1", "cdelt2", "crota2", "equinox", "scale", "file"); fprintf(fraw, fmt, "int", "char", "char", "int", "int", "double", "double", "double", "double", "double", "double", "double", "int", "double", "char"); } else { sprintf(fmt, "|%%5s|%%8s|%%8s|%%6s|%%6s|%%10s|%%10s|%%10s|%%10s|%%11s|%%11s|%%8s|%%7s|%%%ds|\n", namelen+2); fprintf(fraw, fmt, "cntr", "ctype1", "ctype2", "naxis1", "naxis2", "crval1", "crval2", "crpix1", "crpix2", "cdelt1", "cdelt2", "crota2", "equinox", "file"); fprintf(fraw, fmt, "int", "char", "char", "int", "int", "double", "double", "double", "double", "double", "double", "double", "int", "char"); } if((fproj = (FILE *)fopen(projimg_file, "w+")) == (FILE *)NULL) { fprintf(fstatus, "[struct stat=\"ERROR\", msg=\"Invalid output metadata file: %s\"]\n", projimg_file); exit(1); } fprintf(fproj, "\\datatype=fitshdr\n"); sprintf(fmt, "|%%5s|%%8s|%%8s|%%6s|%%6s|%%10s|%%10s|%%10s|%%10s|%%11s|%%11s|%%8s|%%7s|%%%ds|\n", namelen+2); fprintf(fproj, fmt, "cntr", "ctype1", "ctype2", "naxis1", "naxis2", "crval1", "crval2", "crpix1", "crpix2", "cdelt1", "cdelt2", "crota2", "equinox", "file"); fprintf(fproj, fmt, "int", "char", "char", "int", "int", "double", "double", "double", "double", "double", "double", "double", "int", "char"); if((fcorr = (FILE *)fopen(corrimg_file, "w+")) == (FILE *)NULL) { fprintf(fstatus, "[struct stat=\"ERROR\", msg=\"Invalid output metadata file: %s\"]\n", corrimg_file); exit(1); } fprintf(fcorr, "\\datatype=fitshdr\n"); fprintf(fcorr, fmt, "cntr", "ctype1", "ctype2", "naxis1", "naxis2", "crval1", "crval2", "crpix1", "crpix2", "cdelt1", "cdelt2", "crota2", "equinox", "file"); fprintf(fcorr, fmt, "int", "char", "char", "int", "int", "double", "double", "double", "double", "double", "double", "double", "int", "char"); /************************************************/ /* Read the metadata and process each image WCS */ /************************************************/ namelen = 0; nimages = 0; ntotal = 0; if(iscale >= 0) sprintf(rfmt, " %%5d %%8s %%8s %%6d %%6d %%10.6f %%10.6f %%10.2f %%10.2f %%11.8f %%11.8f %%8.5f %%7.0f %%10s %%%ds\n", namelen+2); else sprintf(rfmt, " %%5d %%8s %%8s %%6d %%6d %%10.6f %%10.6f %%10.2f %%10.2f %%11.8f %%11.8f %%8.5f %%7.0f %%%ds\n", namelen+2); sprintf(pfmt, " %%5d %%8s %%8s %%6d %%6d %%10.6f %%10.6f %%10.2f %%10.2f %%11.8f %%11.8f %%8.5f %%7.0f p%%%ds\n", namelen+2); sprintf(cfmt, " %%5d %%8s %%8s %%6d %%6d %%10.6f %%10.6f %%10.2f %%10.2f %%11.8f %%11.8f %%8.5f %%7.0f c%%%ds\n", namelen+2); while(1) { stat = tread(); if(stat < 0) break; ++ntotal; strcpy(input.ctype1, tval(ictype1)); strcpy(input.ctype2, tval(ictype2)); input.cntr = atoi(tval(icntr)); input.naxis1 = atoi(tval(ins)); input.naxis2 = atoi(tval(inl)); input.crpix1 = atof(tval(icrpix1)); input.crpix2 = atof(tval(icrpix2)); input.crval1 = atof(tval(icrval1)); input.crval2 = atof(tval(icrval2)); if(mode == CDELT) { input.cdelt1 = atof(tval(icdelt1)); input.cdelt2 = atof(tval(icdelt2)); input.crota2 = atof(tval(icrota2)); } else { input.cd11 = atof(tval(icd11)); input.cd12 = atof(tval(icd12)); input.cd21 = atof(tval(icd21)); input.cd22 = atof(tval(icd22)); } input.epoch = 2000; strcpy(header, ""); sprintf(temp, "SIMPLE = T" ); stradd(header, temp); sprintf(temp, "BITPIX = -64" ); stradd(header, temp); sprintf(temp, "NAXIS = 2" ); stradd(header, temp); sprintf(temp, "NAXIS1 = %d", input.naxis1 ); stradd(header, temp); sprintf(temp, "NAXIS2 = %d", input.naxis2 ); stradd(header, temp); sprintf(temp, "CTYPE1 = '%s'", input.ctype1 ); stradd(header, temp); sprintf(temp, "CTYPE2 = '%s'", input.ctype2 ); stradd(header, temp); sprintf(temp, "CRVAL1 = %11.6f", input.crval1 ); stradd(header, temp); sprintf(temp, "CRVAL2 = %11.6f", input.crval2 ); stradd(header, temp); sprintf(temp, "CRPIX1 = %11.6f", input.crpix1 ); stradd(header, temp); sprintf(temp, "CRPIX2 = %11.6f", input.crpix2 ); stradd(header, temp); if(mode == CDELT) { sprintf(temp, "CDELT1 = %11.6f", input.cdelt1 ); stradd(header, temp); sprintf(temp, "CDELT2 = %11.6f", input.cdelt2 ); stradd(header, temp); sprintf(temp, "CROTA2 = %11.6f", input.crota2 ); stradd(header, temp); } else { sprintf(temp, "CD1_1 = %11.6f", input.cd11 ); stradd(header, temp); sprintf(temp, "CD1_2 = %11.6f", input.cd12 ); stradd(header, temp); sprintf(temp, "CD2_1 = %11.6f", input.cd21 ); stradd(header, temp); sprintf(temp, "CD2_2 = %11.6f", input.cd22 ); stradd(header, temp); } sprintf(temp, "EQUINOX = %d", input.equinox); stradd(header, temp); sprintf(temp, "END" ); stradd(header, temp); if(iequinox >= 0) input.equinox = atoi(tval(iequinox)); strcpy(input.fname, fileName(tval(ifname))); if(iscale >= 0) strcpy(scale, tval(iscale)); if(strlen(input.fname) > namelen) namelen = strlen(input.fname); if(debug) { printf("Image header to wcsinit():\n%s\n", header); fflush(stdout); } input.wcs = wcsinit(header); checkWCS(input.wcs, 0); if(input.wcs == (struct WorldCoor *)NULL) { fprintf(fstatus, "[struct stat=\"ERROR\", msg=\"Bad WCS for image %d\"]\n", nimages); exit(1); } /***************************************************/ /* Check the boundaries of the input image against */ /* the output region of interest */ /***************************************************/ oxpixMin = 100000000; oxpixMax = -100000000; oypixMin = 100000000; oypixMax = -100000000; /* Check input left and right */ for (j=0; j<input.naxis2+1; ++j) { pix2wcs(input.wcs, 0.5, j+0.5, &xpos, &ypos); convertCoordinates(input.sys, input.epoch, xpos, ypos, output.sys, output.epoch, &lon, &lat, 0.0); wcs2pix(output.wcs, lon, lat, &oxpix, &oypix, &offscl); if(!offscl) { if(oxpix < oxpixMin) oxpixMin = oxpix; if(oxpix > oxpixMax) oxpixMax = oxpix; if(oypix < oypixMin) oypixMin = oypix; if(oypix > oypixMax) oypixMax = oypix; } pix2wcs(input.wcs, input.naxis1+0.5, j+0.5, &xpos, &ypos); convertCoordinates(input.sys, input.epoch, xpos, ypos, output.sys, output.epoch, &lon, &lat, 0.0); wcs2pix(output.wcs, lon, lat, &oxpix, &oypix, &offscl); if(!offscl) { if(oxpix < oxpixMin) oxpixMin = oxpix; if(oxpix > oxpixMax) oxpixMax = oxpix; if(oypix < oypixMin) oypixMin = oypix; if(oypix > oypixMax) oypixMax = oypix; } } /* Check input top and bottom */ for (i=0; i<input.naxis1+1; ++i) { pix2wcs(input.wcs, i+0.5, 0.5, &xpos, &ypos); convertCoordinates(input.sys, input.epoch, xpos, ypos, output.sys, output.epoch, &lon, &lat, 0.0); wcs2pix(output.wcs, lon, lat, &oxpix, &oypix, &offscl); if(!offscl) { if(oxpix < oxpixMin) oxpixMin = oxpix; if(oxpix > oxpixMax) oxpixMax = oxpix; if(oypix < oypixMin) oypixMin = oypix; if(oypix > oypixMax) oypixMax = oypix; } pix2wcs(input.wcs, i+0.5, input.naxis2+0.5, &xpos, &ypos); convertCoordinates(input.sys, input.epoch, xpos, ypos, output.sys, output.epoch, &lon, &lat, 0.0); wcs2pix(output.wcs, lon, lat, &oxpix, &oypix, &offscl); if(!offscl) { if(oxpix < oxpixMin) oxpixMin = oxpix; if(oxpix > oxpixMax) oxpixMax = oxpix; if(oypix < oypixMin) oypixMin = oypix; if(oypix > oypixMax) oypixMax = oypix; } } /***************************************************/ /* Check the boundaries of the region of interest */ /* against the input image */ /***************************************************/ /* Check ouput left and right */ for (j=0; j<output.wcs->nypix+1; ++j) { pix2wcs(output.wcs, 0.5, j+0.5, &xpos, &ypos); convertCoordinates(output.sys, output.epoch, xpos, ypos, input.sys, input.epoch, &lon, &lat, 0.0); wcs2pix(input.wcs, lon, lat, &oxpix, &oypix, &offscl); if(!offscl) { if(0.5 < oxpixMin) oxpixMin = 0.5; if(0.5 > oxpixMax) oxpixMax = 0.5; if(j+0.5 < oypixMin) oypixMin = j+0.5; if(j+0.5 > oypixMax) oypixMax = j+0.5; } pix2wcs(output.wcs, output.wcs->nxpix+0.5, j+0.5, &xpos, &ypos); convertCoordinates(output.sys, output.epoch, xpos, ypos, input.sys, input.epoch, &lon, &lat, 0.0); wcs2pix(input.wcs, lon, lat, &oxpix, &oypix, &offscl); if(!offscl) { if(output.wcs->nxpix+0.5 < oxpixMin) oxpixMin = output.wcs->nxpix+0.5; if(output.wcs->nxpix+0.5 > oxpixMax) oxpixMax = output.wcs->nxpix+0.5; if(j+0.5 < oypixMin) oypixMin = j+0.5; if(j+0.5 > oypixMax) oypixMax = j+0.5; } } /* Check input top and bottom */ for (i=0; i<output.wcs->nxpix+1; ++i) { pix2wcs(output.wcs, i+0.5, 0.5, &xpos, &ypos); convertCoordinates(output.sys, output.epoch, xpos, ypos, input.sys, input.epoch, &lon, &lat, 0.0); wcs2pix(input.wcs, lon, lat, &oxpix, &oypix, &offscl); if(!offscl) { if(i+0.5 < oxpixMin) oxpixMin = i+0.5; if(i+0.5 > oxpixMax) oxpixMax = i+0.5; if(0.5 < oypixMin) oypixMin = 0.5 ; if(0.5 > oypixMax) oypixMax = 0.5 ; } pix2wcs(output.wcs, i+0.5, output.wcs->nypix+0.5, &xpos, &ypos); convertCoordinates(output.sys, output.epoch, xpos, ypos, input.sys, input.epoch, &lon, &lat, 0.0); wcs2pix(input.wcs, lon, lat, &oxpix, &oypix, &offscl); if(!offscl) { if(i+0.5 < oxpixMin) oxpixMin = i+0.5; if(i+0.5 > oxpixMax) oxpixMax = i+0.5; if(output.wcs->nypix+0.5 < oypixMin) oypixMin = output.wcs->nypix+0.5; if(output.wcs->nypix+0.5 > oypixMax) oypixMax = output.wcs->nypix+0.5; } } if(oxpixMax < oxpixMin) continue; if(oypixMax < oypixMin) continue; /* Remove any possible compression extension */ strcpy(ofile, input.fname); if(strlen(ofile) > 3 && strcmp(ofile+strlen(ofile)-3, ".gz") == 0) ofile[strlen(ofile)-3] = '\0'; else if(strlen(ofile) > 2 && strcmp(ofile+strlen(ofile)-2, ".Z") == 0) ofile[strlen(ofile)-2] = '\0'; else if(strlen(ofile) > 2 && strcmp(ofile+strlen(ofile)-2, ".z") == 0) ofile[strlen(ofile)-2] = '\0'; else if(strlen(ofile) > 4 && strcmp(ofile+strlen(ofile)-4, ".zip") == 0) ofile[strlen(ofile)-4] = '\0'; else if(strlen(ofile) > 2 && strcmp(ofile+strlen(ofile)-2, "-z") == 0) ofile[strlen(ofile)-2] = '\0'; else if(strlen(ofile) > 3 && strcmp(ofile+strlen(ofile)-3, "-gz") == 0) ofile[strlen(ofile)-3] = '\0'; /* Make sure the extension is ".fits" */ if(strlen(ofile) > 5 && strcmp(ofile+strlen(ofile)-5, ".fits") == 0) ofile[strlen(ofile)-5] = '\0'; else if(strlen(ofile) > 5 && strcmp(ofile+strlen(ofile)-5, ".FITS") == 0) ofile[strlen(ofile)-5] = '\0'; else if(strlen(ofile) > 4 && strcmp(ofile+strlen(ofile)-4, ".fit") == 0) ofile[strlen(ofile)-4] = '\0'; else if(strlen(ofile) > 4 && strcmp(ofile+strlen(ofile)-4, ".FIT") == 0) ofile[strlen(ofile)-4] = '\0'; else if(strlen(ofile) > 4 && strcmp(ofile+strlen(ofile)-4, ".fts") == 0) ofile[strlen(ofile)-4] = '\0'; else if(strlen(ofile) > 4 && strcmp(ofile+strlen(ofile)-4, ".FTS") == 0) ofile[strlen(ofile)-4] = '\0'; strcat(ofile, ".fits"); if(iscale >= 0) { fprintf(fraw, rfmt, nimages+1, output.wcs->ctype[0], output.wcs->ctype[1], oxpixMax - oxpixMin + 1, oypixMax - oypixMin + 1, output.wcs->crval[0], output.wcs->crval[1], output.wcs->crpix[0] - oxpixMin, output.wcs->crpix[1] - oypixMin, output.wcs->cdelt[0], output.wcs->cdelt[1], output.wcs->rot, output.epoch, scale, ofile); } else { fprintf(fraw, rfmt, nimages+1, output.wcs->ctype[0], output.wcs->ctype[1], oxpixMax - oxpixMin + 1, oypixMax - oypixMin + 1, output.wcs->crval[0], output.wcs->crval[1], output.wcs->crpix[0] - oxpixMin, output.wcs->crpix[1] - oypixMin, output.wcs->cdelt[0], output.wcs->cdelt[1], output.wcs->rot, output.epoch, ofile); } fprintf(fproj, pfmt, nimages+1, output.wcs->ctype[0], output.wcs->ctype[1], oxpixMax - oxpixMin + 1, oypixMax - oypixMin + 1, output.wcs->crval[0], output.wcs->crval[1], output.wcs->crpix[0] - oxpixMin, output.wcs->crpix[1] - oypixMin, output.wcs->cdelt[0], output.wcs->cdelt[1], output.wcs->rot, output.epoch, ofile); fprintf(fcorr, cfmt, nimages+1, output.wcs->ctype[0], output.wcs->ctype[1], oxpixMax - oxpixMin + 1, oypixMax - oypixMin + 1, output.wcs->crval[0], output.wcs->crval[1], output.wcs->crpix[0] - oxpixMin, output.wcs->crpix[1] - oypixMin, output.wcs->cdelt[0], output.wcs->cdelt[1], output.wcs->rot, output.epoch, ofile); ++nimages; } fclose(fraw); fclose(fproj); fclose(fcorr); fprintf(fstatus, "[struct stat=\"OK\", count=\"%d\", total=\"%d\"]\n", nimages, ntotal); fflush(stdout); exit(0); }
int main(int argc, char **argv) { int socket, ihead, pastHeader; int i, c, nread, count, port, raw; int timeout; struct timeval timer; char save; char *hostPtr; char *portPtr; char *dataref; char buf [MAXLEN]; char lead [MAXLEN]; char head [MAXLEN]; char request[MAXLEN]; char urlStr [MAXLEN]; char hostStr[MAXLEN]; int fd; fd_set fdset; FILE *fdebug; fdebug = stdout; fstatus = stdout; strcpy(hostStr, "irsa.ipac.caltech.edu"); debug = 0; opterr = 0; port = 80; raw = 0; timeout = 0; while ((c = getopt(argc, argv, "drt:")) != EOF) { switch (c) { case 'd': debug = 1; break; case 'r': raw = 1; break; case 't': timeout = atoi(optarg); break; default: printf("[struct stat=\"ERROR\", msg=\"Usage: %s [-d][-r] remoteref localfile\"]\n",argv[0]); exit(0); break; } } if(argc - optind < 2) { printf("[struct stat=\"ERROR\", msg=\"Usage: %s [-d][-r] remoteref localfile\"]\n",argv[0]); exit(0); } /* Try to open the output file */ if(debug) { fprintf(fdebug, "DEBUG> localfile = [%s]\n", argv[optind+1]); fflush(fdebug); } fd = open(argv[optind+1], O_WRONLY | O_CREAT, 0644); if(fd < 0) { fprintf(fdebug, "[struct stat=\"ERROR\", msg=\"Output file(%s) open failed\"]\n", argv[optind+1]); exit(0); } /* Parse the reference string to get host and port info */ strcpy(urlStr, argv[optind]); if(debug) { fprintf(fdebug, "DEBUG> urlStr = [%s]\n", urlStr); fflush(fdebug); } if(strncmp(urlStr, "http://", 7) != 0) { printf("[struct stat=\"ERROR\", msg=\"Invalid URL string (must start 'http://')\n"); exit(0); } hostPtr = urlStr + 7; dataref = hostPtr; while(1) { if(*dataref == ':' || *dataref == '/' || *dataref == '\0') break; ++dataref; } if(*dataref == '\0') { printf("[struct stat=\"ERROR\", msg=\"No data reference given in URL\"]\n"); exit(0); } save = *dataref; *dataref = '\0'; strcpy(hostStr, hostPtr); *dataref = save; if(*dataref == ':') { portPtr = dataref+1; dataref = portPtr; while(1) { if(*dataref == '/' || *dataref == '\0') break; ++dataref; } if(*dataref == '\0') { printf("[struct stat=\"ERROR\", msg=\"No data reference given in URL\"]\n"); exit(0); } *dataref = '\0'; port = atoi(portPtr); *dataref = '/'; if(port <= 0) { printf("[struct stat=\"ERROR\", msg=\"Illegal port number in URL\"]\n"); exit(0); } } /* Connect to the port on the host we want */ if(debug) { fprintf(fdebug, "DEBUG> hostStr = [%s]\n", hostStr); fprintf(fdebug, "DEBUG> port = %d\n", port); fflush(fdebug); } socket = tcp_connect(hostStr, port); /* Send a request for the file we want */ if(raw) sprintf(request, "GET %s\r\n\r\n", dataref); else sprintf(request, "GET %s HTTP/1.0\r\nHost: %s\r\n\r\n", dataref, hostStr); if(debug) { fprintf(fdebug, "DEBUG> request = [%s]\n", request); fflush(fdebug); } send(socket, request, strlen(request), 0); /* Set a timeout in case the initial return takes forever */ if(timeout > 0) { if(debug) { fprintf(fdebug, "DEBUG> Setting timeout at %d seconds\n", timeout); fflush(fdebug); } timer.tv_sec = (time_t)timeout; timer.tv_usec = 0; FD_ZERO(&fdset); FD_SET(socket, &fdset); if (select(FD_SETSIZE, &fdset, (fd_set *)0, (fd_set *)0, &timer) < 0) { if (errno != EINTR) /* if not interrupt */ { printf("[struct stat=\"ERROR\", msg=\"Illegal return from select()\"]\n"); exit(0); } } if(!FD_ISSET(socket, &fdset)) { printf("[struct stat=\"ERROR\", msg=\"Connection timed out\"]\n"); exit(0); } } /* Read the data coming back */ count = 0; ihead = 0; pastHeader = 0; while(1) { nread = read(socket, buf, MAXLEN); if(nread <= 0) break; if(debug) { fprintf(fdebug, "DEBUG> read %d bytes\n", nread); fflush(fdebug); } if(!pastHeader && ihead == 0 && strncmp(buf, "HTTP", 4) != 0) { if(debug) { fprintf(fdebug, "DEBUG> No HTTP header on this one.\n"); fflush(fdebug); for(i=0; i<40; ++i) lead[i] = buf[i]; lead[40] = '\0'; fprintf(fdebug, "DEBUG> Starts with: [%s]... \n", lead); fflush(fdebug); } pastHeader = 1; } if(!pastHeader) { for(i=0; i<nread; ++i) { head[ihead] = buf[i]; ++ihead; } head[ihead] = '\0'; if(debug) { fprintf(fdebug, "DEBUG> Header ->\n%s\nDEBUG> Length = %d\n", head, ihead); fflush(fdebug); } for(i=0; i<ihead-3; ++i) { if(strncmp(head+i, "\r\n\r\n", 4) == 0 && ihead-i-4 > 0) { if(debug) { fprintf(fdebug, "DEBUG> End of header found: %d - %d\n", i, i+3); fprintf(fdebug, "DEBUG> Writing %d from header array\n", ihead-i-4); fflush(fdebug); } write(fd, head+i+4, ihead-i-4); pastHeader = 1; break; } } } else { count += nread; if(debug) { fprintf(fdebug, "DEBUG> Writing %d\n", nread); fflush(fdebug); } write(fd, buf, nread); } } close(fd); checkHdr(argv[optind+1], 0, 0); printf("[struct stat=\"OK\", count=\"%d\"]\n", count); fflush(fdebug); exit(0); }