void montage_dataRange(fitsfile *infptr, int *imin, int *imax, int *jmin, int *jmax) { long fpixel[4]; long naxis, naxes[10]; int i, j, nullcnt, nfound; double *buffer; int status = 0; /*************************************************/ /* Make a NaN value to use checking blank pixels */ /*************************************************/ union { double d; char c[8]; } value; double nan; for(i=0; i<8; ++i) value.c[i] = 255; nan = value.d; if(fits_read_key_lng(infptr, "NAXIS", &naxis, (char *)NULL, &status)) montage_printFitsError(status); if(fits_read_keys_lng(infptr, "NAXIS", 1, naxis, naxes, &nfound, &status)) montage_printFitsError(status); fpixel[0] = 1; fpixel[1] = 1; fpixel[2] = 1; fpixel[3] = 1; *imin = 1000000000; *imax = -1; *jmin = 1000000000; *jmax = -1; buffer = (double *)malloc(naxes[0] * sizeof(double)); for (j=1; j<=naxes[1]; ++j) { if(debug >= 2) { printf("Processing image row %5d\n", j); fflush(stdout); } if(fits_read_pix(infptr, TDOUBLE, fpixel, naxes[0], &nan, buffer, &nullcnt, &status)) montage_printFitsError(status); for(i=1; i<=naxes[0]; ++i) { if(!mNaN(buffer[i-1])) { if(buffer[i-1] != nan) { if(i < *imin) *imin = i; if(i > *imax) *imax = i; if(j < *jmin) *jmin = j; if(j > *jmax) *jmax = j; } } } ++fpixel [1]; } free(buffer); }
struct mExamineReturn * mExamine(char *infile, int areaMode, int hdu, int plane3, int plane4, double ra, double dec, double radius, int locinpix, int radinpix, int debug) { int i, j, offscl, nullcnt; int status, clockwise, nfound; int npix, nnull, first; int ixpix, iypix; int maxi, maxj; char *header; char tmpstr[32768]; char proj[32]; int csys; char csys_str[64]; char ctype1[256]; char ctype2[256]; double equinox; long naxis; long naxes[10]; double naxis1; double naxis2; double crval1; double crval2; double crpix1; double crpix2; double cdelt1; double cdelt2; double crota2; double lon, lat; double lonc, latc; double rac, decc; double racp, deccp; double ra1, dec1, ra2, dec2, ra3, dec3, ra4, dec4; double xpix, ypix, rpix, rap; double x, y, z; double xp, yp, zp; double rot, beta, dtr; double r; double sumflux, sumflux2, sumn, mean, background, oldbackground, rms, dot; double sigmaref, sigmamax, sigmamin; double val, valx, valy, valra, valdec; double min, minx, miny, minra, mindec; double max, maxx, maxy, maxra, maxdec; double x0, y0, z0; double fluxMin, fluxMax, fluxRef, sigma; struct WorldCoor *wcs; fitsfile *fptr; int ibegin, iend, jbegin, jend; long fpixel[4], nelements; double *data = (double *)NULL; struct apPhoto *ap = (struct apPhoto *)NULL; int nflux, maxflux; struct mExamineReturn *returnStruct; returnStruct = (struct mExamineReturn *)malloc(sizeof(struct mExamineReturn)); memset((void *)returnStruct, 0, sizeof(returnStruct)); returnStruct->status = 1; strcpy(returnStruct->msg, ""); nflux = 0; maxflux = MAXFLUX; /************************************************/ /* 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] = (char)255; nan = value.d; dtr = atan(1.)/45.; /* Process basic command-line arguments */ if(debug) { printf("DEBUG> areaMode = %d \n", areaMode); printf("DEBUG> infile = %s \n", infile); printf("DEBUG> ra = %-g\n", ra); printf("DEBUG> dec = %-g\n", dec); printf("DEBUG> radius = %-g\n", radius); fflush(stdout); } rpix = 0.; if(areaMode == APPHOT) ap = (struct apPhoto *)malloc(maxflux * sizeof(struct apPhoto)); /* Open the FITS file and initialize the WCS transform */ status = 0; if(fits_open_file(&fptr, infile, READONLY, &status)) { if(ap) free(ap); sprintf(returnStruct->msg, "Cannot open FITS file %s", infile); return returnStruct; } if(hdu > 0) { status = 0; if(fits_movabs_hdu(fptr, hdu+1, NULL, &status)) { if(ap) free(ap); sprintf(returnStruct->msg, "Can't find HDU %d", hdu); return returnStruct; } } status = 0; if(fits_get_image_wcs_keys(fptr, &header, &status)) { if(ap) free(ap); sprintf(returnStruct->msg, "Cannot find WCS keys in FITS file %s", infile); return returnStruct; } status = 0; if(fits_read_key_lng(fptr, "NAXIS", &naxis, (char *)NULL, &status)) { if(ap) free(ap); sprintf(returnStruct->msg, "Cannot find NAXIS keyword in FITS file %s", infile); return returnStruct; } status = 0; if(fits_read_keys_lng(fptr, "NAXIS", 1, naxis, naxes, &nfound, &status)) { if(ap) free(ap); sprintf(returnStruct->msg, "Cannot find NAXIS1,2 keywords in FITS file %s", infile); return returnStruct; } wcs = wcsinit(header); if(wcs == (struct WorldCoor *)NULL) { if(ap) free(ap); sprintf(returnStruct->msg, "WCS initialization failed."); return returnStruct; } /* A bunch of the parameters we want are in the WCS structure */ clockwise = 0; strcpy(ctype1, wcs->ctype[0]); strcpy(ctype2, wcs->ctype[1]); naxis1 = wcs->nxpix; naxis2 = wcs->nypix; crval1 = wcs->xref; crval2 = wcs->yref; crpix1 = wcs->xrefpix; crpix2 = wcs->yrefpix; cdelt1 = wcs->xinc; cdelt2 = wcs->yinc; crota2 = wcs->rot; if((cdelt1 < 0 && cdelt2 < 0) || (cdelt1 > 0 && cdelt2 > 0)) clockwise = 1; strcpy(proj, ""); if(strlen(ctype1) > 5) strcpy (proj, ctype1+5); /* We get the Equinox from the WCS. If not */ /* there we take the command-line value. We */ /* then infer Julian/Besselian as best we can. */ equinox = wcs->equinox; csys = EQUJ; strcpy(csys_str, "EQUJ"); if(strncmp(ctype1, "RA--", 4) == 0) { csys = EQUJ; strcpy(csys_str, "EQUJ"); if(equinox < 1975.) { csys = EQUB; strcpy(csys_str, "EQUB"); } } if(strncmp(ctype1, "LON-", 4) == 0) { csys = GAL; strcpy(csys_str, "GAL"); } if(strncmp(ctype1, "GLON", 4) == 0) { csys = GAL; strcpy(csys_str, "GAL"); } if(strncmp(ctype1, "ELON", 4) == 0) { csys = ECLJ; strcpy(csys_str, "ECLJ"); if(equinox < 1975.) { csys = ECLB; strcpy(csys_str, "ECLB"); } } if(debug) { printf("DEBUG> proj = [%s]\n", proj); printf("DEBUG> csys = %d\n", csys); printf("DEBUG> clockwise = %d\n", clockwise); printf("DEBUG> ctype1 = [%s]\n", ctype1); printf("DEBUG> ctype2 = [%s]\n", ctype2); printf("DEBUG> equinox = %-g\n", equinox); printf("\n"); fflush(stdout); } /* To get corners and rotation in EQUJ we need the */ /* locations of the center pixel and the one above it. */ pix2wcs(wcs, wcs->nxpix/2.+0.5, wcs->nypix/2.+0.5, &lonc, &latc); convertCoordinates (csys, equinox, lonc, latc, EQUJ, 2000., &rac, &decc, 0.); pix2wcs(wcs, wcs->nxpix/2.+0.5, wcs->nypix/2.+1.5, &lonc, &latc); convertCoordinates (csys, equinox, lonc, latc, EQUJ, 2000., &racp, &deccp, 0.); /* Use spherical trig to get the Equatorial rotation angle */ x = cos(decc*dtr) * cos(rac*dtr); y = cos(decc*dtr) * sin(rac*dtr); z = sin(decc*dtr); xp = cos(deccp*dtr) * cos(racp*dtr); yp = cos(deccp*dtr) * sin(racp*dtr); zp = sin(deccp*dtr); beta = acos(x*xp + y*yp + z*zp) / dtr; rot = asin(cos(deccp*dtr) * sin((rac-racp)*dtr)/sin(beta*dtr)) / dtr; /* And for the four corners we want them uniformly clockwise */ if(!clockwise) { pix2wcs(wcs, -0.5, -0.5, &lon, &lat); convertCoordinates (csys, equinox, lon, lat, EQUJ, 2000., &ra1, &dec1, 0.); pix2wcs(wcs, wcs->nxpix+0.5, -0.5, &lon, &lat); convertCoordinates (csys, equinox, lon, lat, EQUJ, 2000., &ra2, &dec2, 0.); pix2wcs(wcs, wcs->nxpix+0.5, wcs->nypix+0.5, &lon, &lat); convertCoordinates (csys, equinox, lon, lat, EQUJ, 2000., &ra3, &dec3, 0.); pix2wcs(wcs, -0.5, wcs->nypix+0.5, &lon, &lat); convertCoordinates (csys, equinox, lon, lat, EQUJ, 2000., &ra4, &dec4, 0.); } else { pix2wcs(wcs, -0.5, -0.5, &lon, &lat); convertCoordinates (csys, equinox, lon, lat, EQUJ, 2000., &ra2, &dec2, 0.); pix2wcs(wcs, wcs->nxpix+0.5, -0.5, &lon, &lat); convertCoordinates (csys, equinox, lon, lat, EQUJ, 2000., &ra1, &dec1, 0.); pix2wcs(wcs, wcs->nxpix+0.5, wcs->nypix+0.5, &lon, &lat); convertCoordinates (csys, equinox, lon, lat, EQUJ, 2000., &ra4, &dec4, 0.); pix2wcs(wcs, -0.5, wcs->nypix+0.5, &lon, &lat); convertCoordinates (csys, equinox, lon, lat, EQUJ, 2000., &ra3, &dec3, 0.); } // Treat the default region (ALL) as a circle // containing the whole image if(areaMode == ALL) { locinpix = 1; radinpix = 1; ra = wcs->nxpix / 2.; dec = wcs->nypix / 2.; radius = sqrt(wcs->nxpix*wcs->nxpix + wcs->nypix*wcs->nypix)/2.; } /* Get region statistics */ ixpix = 1; iypix = 1; if(radinpix) { rpix = radius; radius = rpix * fabs(cdelt2); } else rpix = radius / fabs(cdelt2); if(locinpix) { xpix = ra; ypix = dec; pix2wcs(wcs, xpix, ypix, &lon, &lat); if(wcs->offscl) { if(ap) free(ap); sprintf(returnStruct->msg, "Location off the image."); return returnStruct; } convertCoordinates (csys, equinox, lon, lat, EQUJ, 2000., &ra, &dec, 0); } else { convertCoordinates (EQUJ, 2000., ra, dec, csys, equinox, &lon, &lat, 0.); wcs2pix(wcs, lon, lat, &xpix, &ypix, &offscl); if(offscl) { if(ap) free(ap); sprintf(returnStruct->msg, "Location off the image."); return returnStruct; } } x0 = cos(ra*dtr) * cos(dec*dtr); y0 = sin(ra*dtr) * cos(dec*dtr); z0 = sin(dec*dtr); ixpix = (int)(xpix+0.5); iypix = (int)(ypix+0.5); if(debug) { printf("DEBUG> Region statististics for %-g pixels around (%-g,%-g) [%d,%d] [Equatorial (%-g, %-g)\n", rpix, xpix, ypix, ixpix, iypix, ra, dec); fflush(stdout); } // Then read the data jbegin = iypix - rpix - 1; jend = iypix + rpix + 1; ibegin = ixpix - rpix - 1; iend = ixpix + rpix + 1; if(ibegin < 1 ) ibegin = 1; if(iend > wcs->nxpix) iend = wcs->nxpix; nelements = iend - ibegin + 1; if(jbegin < 1 ) jbegin = 1; if(jend > wcs->nypix) jend = wcs->nxpix; fpixel[0] = ibegin; fpixel[1] = jbegin; fpixel[2] = 1; fpixel[3] = 1; fpixel[2] = plane3; fpixel[3] = plane4; data = (double *)malloc(nelements * sizeof(double)); status = 0; sumflux = 0.; sumflux2 = 0.; npix = 0; nnull = 0; val = 0.; valx = 0.; valy = 0.; valra = 0.; valdec = 0.; max = 0.; maxx = 0.; maxy = 0.; maxra = 0.; maxdec = 0.; min = 0.; minx = 0.; miny = 0.; minra = 0.; mindec = 0.; first = 1; if(radius > 0.) { if(debug) { printf("\nDEBUG> Location: (%.6f %.6f) -> (%d,%d)\n\n", xpix, ypix, ixpix, iypix); printf("DEBUG> Radius: %.6f\n\n", rpix); printf("DEBUG> i: %d to %d\n", ibegin, iend); printf("DEBUG> j: %d to %d\n", jbegin, jend); } for (j=jbegin; j<=jend; ++j) { status = 0; if(fits_read_pix(fptr, TDOUBLE, fpixel, nelements, &nan, (void *)data, &nullcnt, &status)) { ++fpixel[1]; continue; } for(i=0; i<nelements; ++i) { if(mNaN(data[i])) { if(debug) printf("%10s ", "NULL"); ++nnull; continue; } sumflux += data[i]; sumflux2 += data[i]*data[i]; ++npix; x = ibegin + i; y = j; pix2wcs(wcs, x, y, &lon, &lat); convertCoordinates(csys, equinox, lon, lat, EQUJ, 2000., &ra, &dec, 0.); xp = cos(ra*dtr) * cos(dec*dtr); yp = sin(ra*dtr) * cos(dec*dtr); zp = sin(dec*dtr); dot = xp*x0 + yp*y0 + zp*z0; if(dot > 1.) dot = 1.; r = acos(dot)/dtr / fabs(cdelt2); if(debug) { if(r <= rpix) printf("%10.3f ", data[i]); else printf("%10s ", "."); } if(r > rpix) continue; if(x == ixpix && y == iypix) { val = data[i]; valx = x; valy = y; } if(first) { first = 0; min = data[i]; minx = x; miny = y; max = data[i]; maxx = x; maxy = y; maxi = i+ibegin; maxj = j; } if(data[i] > max) { max = data[i]; maxx = x; maxy = y; maxi = i+ibegin; maxj = j; } if(data[i] < min) { min = data[i]; minx = x; miny = y; } } pix2wcs(wcs, valx, valy, &lon, &lat); convertCoordinates(csys, equinox, lon, lat, EQUJ, 2000., &valra, &valdec, 0.); pix2wcs(wcs, minx, miny, &lon, &lat); convertCoordinates(csys, equinox, lon, lat, EQUJ, 2000., &minra, &mindec, 0.); pix2wcs(wcs, maxx, maxy, &lon, &lat); convertCoordinates(csys, equinox, lon, lat, EQUJ, 2000., &maxra, &maxdec, 0.); if(debug) printf("\n"); ++fpixel[1]; } mean = 0.; rms = 0.; sigmaref = 0.; sigmamin = 0.; sigmamax = 0.; if(npix > 0) { mean = sumflux / npix; rms = sqrt(sumflux2/npix - mean*mean); sigmaref = (val - mean) / rms; sigmamin = (min - mean) / rms; sigmamax = (max - mean) / rms; } } /* Finally, print out parameters */ strcpy(montage_json, "{"); strcpy(montage_msgstr, ""); if(areaMode == ALL || areaMode == REGION) { sprintf(tmpstr, "\"proj\":\"%s\",", proj); strcat(montage_json, tmpstr); sprintf(tmpstr, " \"csys\":\"%s\",", csys_str); strcat(montage_json, tmpstr); sprintf(tmpstr, " \"equinox\":%.1f,", equinox); strcat(montage_json, tmpstr); sprintf(tmpstr, " \"naxis\":%ld,", naxis); strcat(montage_json, tmpstr); sprintf(tmpstr, " \"naxis1\":%d,", (int)naxis1); strcat(montage_json, tmpstr); sprintf(tmpstr, " \"naxis2\":%d,", (int)naxis2); strcat(montage_json, tmpstr); if(naxis > 2) { sprintf(tmpstr, " \"naxis3\":%ld,", naxes[2]); strcat(montage_json, tmpstr); } if(naxis > 3) { sprintf(tmpstr, " \"naxis4\":%ld,", naxes[3]); strcat(montage_json, tmpstr); } sprintf(tmpstr, " \"crval1\":%.7f,", crval1); strcat(montage_json, tmpstr); sprintf(tmpstr, " \"crval2\":%.7f,", crval2); strcat(montage_json, tmpstr); sprintf(tmpstr, " \"crpix1\":%-g,", crpix1); strcat(montage_json, tmpstr); sprintf(tmpstr, " \"crpix2\":%-g,", crpix2); strcat(montage_json, tmpstr); sprintf(tmpstr, " \"cdelt1\":%.7f,", cdelt1); strcat(montage_json, tmpstr); sprintf(tmpstr, " \"cdelt2\":%.7f,", cdelt2); strcat(montage_json, tmpstr); sprintf(tmpstr, " \"crota2\":%.4f,", crota2); strcat(montage_json, tmpstr); sprintf(tmpstr, " \"lonc\":%.7f,", lonc); strcat(montage_json, tmpstr); sprintf(tmpstr, " \"latc\":%.7f,", latc); strcat(montage_json, tmpstr); sprintf(tmpstr, " \"ximgsize\":%.6f,", fabs(naxis1*cdelt1)); strcat(montage_json, tmpstr); sprintf(tmpstr, " \"yimgsize\":%.6f,", fabs(naxis1*cdelt2)); strcat(montage_json, tmpstr); sprintf(tmpstr, " \"rotequ\":%.4f,", rot); strcat(montage_json, tmpstr); sprintf(tmpstr, " \"rac\":%.7f,", rac); strcat(montage_json, tmpstr); sprintf(tmpstr, " \"decc\":%.7f,", decc); strcat(montage_json, tmpstr); sprintf(tmpstr, " \"ra1\":%.7f,", ra1); strcat(montage_json, tmpstr); sprintf(tmpstr, " \"dec1\":%.7f,", dec1); strcat(montage_json, tmpstr); sprintf(tmpstr, " \"ra2\":%.7f,", ra2); strcat(montage_json, tmpstr); sprintf(tmpstr, " \"dec2\":%.7f,", dec2); strcat(montage_json, tmpstr); sprintf(tmpstr, " \"ra3\":%.7f,", ra3); strcat(montage_json, tmpstr); sprintf(tmpstr, " \"dec3\":%.7f,", dec3); strcat(montage_json, tmpstr); sprintf(tmpstr, " \"ra4\":%.7f,", ra4); strcat(montage_json, tmpstr); sprintf(tmpstr, " \"dec4\":%.7f,", dec4); strcat(montage_json, tmpstr); sprintf(tmpstr, " \"radius\":%.7f,", radius); strcat(montage_json, tmpstr); sprintf(tmpstr, " \"radpix\":%.2f,", rpix); strcat(montage_json, tmpstr); sprintf(tmpstr, " \"npixel\":%d,", npix); strcat(montage_json, tmpstr); sprintf(tmpstr, " \"nnull\":%d,", nnull); strcat(montage_json, tmpstr); sprintf(tmpstr, " \"aveflux\":%-g,", mean); strcat(montage_json, tmpstr); sprintf(tmpstr, " \"rmsflux\":%-g,", rms); strcat(montage_json, tmpstr); sprintf(tmpstr, " \"fluxref\":%-g,", val); strcat(montage_json, tmpstr); sprintf(tmpstr, " \"sigmaref\":%-g,", sigmaref); strcat(montage_json, tmpstr); sprintf(tmpstr, " \"xref\":%.0f,", valx); strcat(montage_json, tmpstr); sprintf(tmpstr, " \"yref\":%.0f,", valy); strcat(montage_json, tmpstr); sprintf(tmpstr, " \"raref\":%.7f,", valra); strcat(montage_json, tmpstr); sprintf(tmpstr, " \"decref\":%.7f,", valdec); strcat(montage_json, tmpstr); sprintf(tmpstr, " \"fluxmin\":%-g,", min); strcat(montage_json, tmpstr); sprintf(tmpstr, " \"sigmamin\":%-g,", sigmamin); strcat(montage_json, tmpstr); sprintf(tmpstr, " \"xmin\":%.0f,", minx); strcat(montage_json, tmpstr); sprintf(tmpstr, " \"ymin\":%.0f,", miny); strcat(montage_json, tmpstr); sprintf(tmpstr, " \"ramin\":%.7f,", minra); strcat(montage_json, tmpstr); sprintf(tmpstr, " \"decmin\":%.7f,", mindec); strcat(montage_json, tmpstr); sprintf(tmpstr, " \"fluxmax\":%-g,", max); strcat(montage_json, tmpstr); sprintf(tmpstr, " \"sigmamax\":%-g,", sigmamax); strcat(montage_json, tmpstr); sprintf(tmpstr, " \"xmax\":%.0f,", maxx); strcat(montage_json, tmpstr); sprintf(tmpstr, " \"ymax\":%.0f,", maxy); strcat(montage_json, tmpstr); sprintf(tmpstr, " \"ramax\":%.7f,", maxra); strcat(montage_json, tmpstr); sprintf(tmpstr, " \"decmax\":%.7f", maxdec); strcat(montage_json, tmpstr); sprintf(tmpstr, "proj=\"%s\",", proj); strcat(montage_msgstr, tmpstr); sprintf(tmpstr, " csys=\"%s\",", csys_str); strcat(montage_msgstr, tmpstr); sprintf(tmpstr, " equinox=%.1f,", equinox); strcat(montage_msgstr, tmpstr); sprintf(tmpstr, " naxis=%ld,", naxis); strcat(montage_msgstr, tmpstr); sprintf(tmpstr, " naxis1=%d,", (int)naxis1); strcat(montage_msgstr, tmpstr); sprintf(tmpstr, " naxis2=%d,", (int)naxis2); strcat(montage_msgstr, tmpstr); if(naxis > 2) { sprintf(tmpstr, " naxis3=%ld,", naxes[2]); strcat(montage_msgstr, tmpstr); } if(naxis > 3) { sprintf(tmpstr, " naxis4=%ld,", naxes[3]); strcat(montage_msgstr, tmpstr); } sprintf(tmpstr, " crval1=%.7f,", crval1); strcat(montage_msgstr, tmpstr); sprintf(tmpstr, " crval2=%.7f,", crval2); strcat(montage_msgstr, tmpstr); sprintf(tmpstr, " crpix1=%-g,", crpix1); strcat(montage_msgstr, tmpstr); sprintf(tmpstr, " crpix2=%-g,", crpix2); strcat(montage_msgstr, tmpstr); sprintf(tmpstr, " cdelt1=%.7f,", cdelt1); strcat(montage_msgstr, tmpstr); sprintf(tmpstr, " cdelt2=%.7f,", cdelt2); strcat(montage_msgstr, tmpstr); sprintf(tmpstr, " crota2=%.4f,", crota2); strcat(montage_msgstr, tmpstr); sprintf(tmpstr, " lonc=%.7f,", lonc); strcat(montage_msgstr, tmpstr); sprintf(tmpstr, " latc=%.7f,", latc); strcat(montage_msgstr, tmpstr); sprintf(tmpstr, " ximgsize=%.6f,", fabs(naxis1*cdelt1)); strcat(montage_msgstr, tmpstr); sprintf(tmpstr, " yimgsize=%.6f,", fabs(naxis1*cdelt2)); strcat(montage_msgstr, tmpstr); sprintf(tmpstr, " rotequ=%.4f,", rot); strcat(montage_msgstr, tmpstr); sprintf(tmpstr, " rac=%.7f,", rac); strcat(montage_msgstr, tmpstr); sprintf(tmpstr, " decc=%.7f,", decc); strcat(montage_msgstr, tmpstr); sprintf(tmpstr, " ra1=%.7f,", ra1); strcat(montage_msgstr, tmpstr); sprintf(tmpstr, " dec1=%.7f,", dec1); strcat(montage_msgstr, tmpstr); sprintf(tmpstr, " ra2=%.7f,", ra2); strcat(montage_msgstr, tmpstr); sprintf(tmpstr, " dec2=%.7f,", dec2); strcat(montage_msgstr, tmpstr); sprintf(tmpstr, " ra3=%.7f,", ra3); strcat(montage_msgstr, tmpstr); sprintf(tmpstr, " dec3=%.7f,", dec3); strcat(montage_msgstr, tmpstr); sprintf(tmpstr, " ra4=%.7f,", ra4); strcat(montage_msgstr, tmpstr); sprintf(tmpstr, " dec4=%.7f,", dec4); strcat(montage_msgstr, tmpstr); sprintf(tmpstr, " radius=%.7f,", radius); strcat(montage_msgstr, tmpstr); sprintf(tmpstr, " radpix=%.2f,", rpix); strcat(montage_msgstr, tmpstr); sprintf(tmpstr, " npixel=%d,", npix); strcat(montage_msgstr, tmpstr); sprintf(tmpstr, " nnull=%d,", nnull); strcat(montage_msgstr, tmpstr); sprintf(tmpstr, " aveflux=%-g,", mean); strcat(montage_msgstr, tmpstr); sprintf(tmpstr, " rmsflux=%-g,", rms); strcat(montage_msgstr, tmpstr); sprintf(tmpstr, " fluxref=%-g,", val); strcat(montage_msgstr, tmpstr); sprintf(tmpstr, " sigmaref=%-g,", sigmaref); strcat(montage_msgstr, tmpstr); sprintf(tmpstr, " xref=%.0f,", valx); strcat(montage_msgstr, tmpstr); sprintf(tmpstr, " yref=%.0f,", valy); strcat(montage_msgstr, tmpstr); sprintf(tmpstr, " raref=%.7f,", valra); strcat(montage_msgstr, tmpstr); sprintf(tmpstr, " decref=%.7f,", valdec); strcat(montage_msgstr, tmpstr); sprintf(tmpstr, " fluxmin=%-g,", min); strcat(montage_msgstr, tmpstr); sprintf(tmpstr, " sigmamin=%-g,", sigmamin); strcat(montage_msgstr, tmpstr); sprintf(tmpstr, " xmin=%.0f,", minx); strcat(montage_msgstr, tmpstr); sprintf(tmpstr, " ymin=%.0f,", miny); strcat(montage_msgstr, tmpstr); sprintf(tmpstr, " ramin=%.7f,", minra); strcat(montage_msgstr, tmpstr); sprintf(tmpstr, " decmin=%.7f,", mindec); strcat(montage_msgstr, tmpstr); sprintf(tmpstr, " fluxmax=%-g,", max); strcat(montage_msgstr, tmpstr); sprintf(tmpstr, " sigmamax=%-g,", sigmamax); strcat(montage_msgstr, tmpstr); sprintf(tmpstr, " xmax=%.0f,", maxx); strcat(montage_msgstr, tmpstr); sprintf(tmpstr, " ymax=%.0f,", maxy); strcat(montage_msgstr, tmpstr); sprintf(tmpstr, " ramax=%.7f,", maxra); strcat(montage_msgstr, tmpstr); sprintf(tmpstr, " decmax=%.7f", maxdec); strcat(montage_msgstr, tmpstr); } else if(areaMode == APPHOT) { // For aperture photometry mode we process the flux vs. radius data // to get the integrated source flux. rap = radius; jbegin = maxj - rap - 1; jend = maxj + rap + 1; ibegin = maxi - rap - 1; iend = maxi + rap + 1; nelements = iend - ibegin + 1; fpixel[0] = ibegin; fpixel[1] = jbegin; fpixel[2] = 1; fpixel[3] = 1; for (j=jbegin; j<=jend; ++j) { status = 0; if(fits_read_pix(fptr, TDOUBLE, fpixel, nelements, &nan, (void *)data, &nullcnt, &status)) { if(ap) free(ap); free(data); sprintf(returnStruct->msg, "Error reading FITS data."); return returnStruct; } for(i=0; i<nelements; ++i) { if(mNaN(data[i])) continue; r = sqrt(((double)i+ibegin-maxi)*((double)i+ibegin-maxi) + ((double)j-maxj)*((double)j-maxj)); if(r > rap) continue; ap[nflux].rad = r; ap[nflux].flux = data[i]; ap[nflux].fit = 0.; ++nflux; if(nflux >= maxflux) { maxflux += MAXFLUX; ap = (struct apPhoto *)realloc(ap, maxflux * sizeof(struct apPhoto)); } } ++fpixel[1]; } // Sort the data by radius qsort(ap, (size_t)nflux, sizeof(struct apPhoto), mExamine_radCompare); // Find the peak flux and the minimum flux. // The max is constrained to be in the first quarter of the // data, just to be careful. fluxMax = -1.e99; fluxMin = 1.e99; for(i=0; i<nflux; ++i) { if(i < nflux/4 && ap[i].flux > fluxMax) fluxMax = ap[i].flux; if(ap[i].flux < fluxMin) fluxMin = ap[i].flux; } // Fit the minimum a little more carefully, iterating // and excluding points more than 3 sigma above the // minimum. background = fluxMin; sigma = fluxMax - fluxMin; for(j=0; j<1000; ++j) { oldbackground = background; sumn = 0.; sumflux = 0.; sumflux2 = 0.; for(i=0; i<nflux; ++i) { if(fabs(ap[i].flux - background) > 3.*sigma) continue; sumn += 1.; sumflux += ap[i].flux; sumflux2 += ap[i].flux * ap[i].flux; } background = sumflux / sumn; sigma = sqrt(sumflux2/sumn - background*background); if(fabs((background - oldbackground) / oldbackground) < 1.e-3) break; } fluxRef = (fluxMax-fluxMin) / exp(1.); for(i=0; i<nflux; ++i) { if(ap[i].flux < fluxRef) { sigma = ap[i].rad; break; } } for(i=0; i<nflux; ++i) { ap[i].fit = (fluxMax-background) * exp(-(ap[i].rad * ap[i].rad) / (sigma * sigma)) + background; if(i == 0) ap[i].sum = ap[i].flux - background; else ap[i].sum = ap[i-1].sum + (ap[i].flux - background); } if(debug) { printf("| rad | flux | fit | sum |\n"); fflush(stdout); for(i=0; i<nflux; ++i) { printf("%12.6f %12.6f %12.6f %12.6f \n", ap[i].rad, ap[i].flux, ap[i].fit, ap[i].sum); fflush(stdout); } } sprintf(tmpstr, "\"proj\":\"%s\",", proj); strcat(montage_json, tmpstr); sprintf(tmpstr, " \"csys\":\"%s\",", csys_str); strcat(montage_json, tmpstr); sprintf(tmpstr, " \"equinox\":%.1f,", equinox); strcat(montage_json, tmpstr); sprintf(tmpstr, " \"naxis\":%ld,", naxis); strcat(montage_json, tmpstr); sprintf(tmpstr, " \"naxis1\":%d,", (int)naxis1); strcat(montage_json, tmpstr); sprintf(tmpstr, " \"naxis2\":%d,", (int)naxis2); strcat(montage_json, tmpstr); if(naxis > 2) { sprintf(tmpstr, " \"naxis3\":%ld,", naxes[2]); strcat(montage_json, tmpstr); } if(naxis > 3) { sprintf(tmpstr, " \"naxis4\":%ld,", naxes[3]); strcat(montage_json, tmpstr); } sprintf(tmpstr, " \"crval1\":%.7f,", crval1); strcat(montage_json, tmpstr); sprintf(tmpstr, " \"crval2\":%.7f,", crval2); strcat(montage_json, tmpstr); sprintf(tmpstr, " \"crpix1\":%-g,", crpix1); strcat(montage_json, tmpstr); sprintf(tmpstr, " \"crpix2\":%-g,", crpix2); strcat(montage_json, tmpstr); sprintf(tmpstr, " \"cdelt1\":%.7f,", cdelt1); strcat(montage_json, tmpstr); sprintf(tmpstr, " \"cdelt2\":%.7f,", cdelt2); strcat(montage_json, tmpstr); sprintf(tmpstr, " \"crota2\":%.4f,", crota2); strcat(montage_json, tmpstr); sprintf(tmpstr, " \"lonc\":%.7f,", lonc); strcat(montage_json, tmpstr); sprintf(tmpstr, " \"latc\":%.7f,", latc); strcat(montage_json, tmpstr); sprintf(tmpstr, " \"ximgsize\":%.6f,", fabs(naxis1*cdelt1)); strcat(montage_json, tmpstr); sprintf(tmpstr, " \"yimgsize\":%.6f,", fabs(naxis1*cdelt2)); strcat(montage_json, tmpstr); sprintf(tmpstr, " \"rotequ\":%.4f,", rot); strcat(montage_json, tmpstr); sprintf(tmpstr, " \"rac\":%.7f,", rac); strcat(montage_json, tmpstr); sprintf(tmpstr, " \"decc\":%.7f,", decc); strcat(montage_json, tmpstr); sprintf(tmpstr, " \"ra1\":%.7f,", ra1); strcat(montage_json, tmpstr); sprintf(tmpstr, " \"dec1\":%.7f,", dec1); strcat(montage_json, tmpstr); sprintf(tmpstr, " \"ra2\":%.7f,", ra2); strcat(montage_json, tmpstr); sprintf(tmpstr, " \"dec2\":%.7f,", dec2); strcat(montage_json, tmpstr); sprintf(tmpstr, " \"ra3\":%.7f,", ra3); strcat(montage_json, tmpstr); sprintf(tmpstr, " \"dec3\":%.7f,", dec3); strcat(montage_json, tmpstr); sprintf(tmpstr, " \"ra4\":%.7f,", ra4); strcat(montage_json, tmpstr); sprintf(tmpstr, " \"dec4\":%.7f,", dec4); strcat(montage_json, tmpstr); sprintf(tmpstr, " \"totalflux\":%.7e", ap[nflux/2].sum); strcat(montage_json, tmpstr); sprintf(tmpstr, "proj=\"%s\",", proj); strcat(montage_msgstr, tmpstr); sprintf(tmpstr, " csys=\"%s\",", csys_str); strcat(montage_msgstr, tmpstr); sprintf(tmpstr, " equinox=%.1f,", equinox); strcat(montage_msgstr, tmpstr); sprintf(tmpstr, " naxis=%ld,", naxis); strcat(montage_msgstr, tmpstr); sprintf(tmpstr, " naxis1=%d,", (int)naxis1); strcat(montage_msgstr, tmpstr); sprintf(tmpstr, " naxis2=%d,", (int)naxis2); strcat(montage_msgstr, tmpstr); if(naxis > 2) { sprintf(tmpstr, " naxis3=%ld,", naxes[2]); strcat(montage_msgstr, tmpstr); } if(naxis > 3) { sprintf(tmpstr, " naxis4=%ld,", naxes[3]); strcat(montage_msgstr, tmpstr); } sprintf(tmpstr, " crval1=%.7f,", crval1); strcat(montage_msgstr, tmpstr); sprintf(tmpstr, " crval2=%.7f,", crval2); strcat(montage_msgstr, tmpstr); sprintf(tmpstr, " crpix1=%-g,", crpix1); strcat(montage_msgstr, tmpstr); sprintf(tmpstr, " crpix2=%-g,", crpix2); strcat(montage_msgstr, tmpstr); sprintf(tmpstr, " cdelt1=%.7f,", cdelt1); strcat(montage_msgstr, tmpstr); sprintf(tmpstr, " cdelt2=%.7f,", cdelt2); strcat(montage_msgstr, tmpstr); sprintf(tmpstr, " crota2=%.4f,", crota2); strcat(montage_msgstr, tmpstr); sprintf(tmpstr, " lonc=%.7f,", lonc); strcat(montage_msgstr, tmpstr); sprintf(tmpstr, " latc=%.7f,", latc); strcat(montage_msgstr, tmpstr); sprintf(tmpstr, " ximgsize=%.6f,", fabs(naxis1*cdelt1)); strcat(montage_msgstr, tmpstr); sprintf(tmpstr, " yimgsize=%.6f,", fabs(naxis1*cdelt2)); strcat(montage_msgstr, tmpstr); sprintf(tmpstr, " rotequ=%.4f,", rot); strcat(montage_msgstr, tmpstr); sprintf(tmpstr, " rac=%.7f,", rac); strcat(montage_msgstr, tmpstr); sprintf(tmpstr, " decc=%.7f,", decc); strcat(montage_msgstr, tmpstr); sprintf(tmpstr, " ra1=%.7f,", ra1); strcat(montage_msgstr, tmpstr); sprintf(tmpstr, " dec1=%.7f,", dec1); strcat(montage_msgstr, tmpstr); sprintf(tmpstr, " ra2=%.7f,", ra2); strcat(montage_msgstr, tmpstr); sprintf(tmpstr, " dec2=%.7f,", dec2); strcat(montage_msgstr, tmpstr); sprintf(tmpstr, " ra3=%.7f,", ra3); strcat(montage_msgstr, tmpstr); sprintf(tmpstr, " dec3=%.7f,", dec3); strcat(montage_msgstr, tmpstr); sprintf(tmpstr, " ra4=%.7f,", ra4); strcat(montage_msgstr, tmpstr); sprintf(tmpstr, " dec4=%.7f,", dec4); strcat(montage_msgstr, tmpstr); sprintf(tmpstr, " totalflux=%.7e", ap[nflux/2].sum); strcat(montage_msgstr, tmpstr); } strcat(montage_json, "}"); if(ap) free(ap); free(data); returnStruct->status = 0; strcpy(returnStruct->msg, montage_msgstr); strcpy(returnStruct->json, montage_json); strcpy(returnStruct->proj, proj); strcpy(returnStruct->csys, csys_str); returnStruct->equinox = equinox; returnStruct->naxis = naxis; returnStruct->naxis1 = naxis1; returnStruct->naxis2 = naxis2; returnStruct->naxis3 = naxes[2]; returnStruct->naxis4 = naxes[3]; returnStruct->crval1 = crval1; returnStruct->crval2 = crval2; returnStruct->crpix1 = crpix1; returnStruct->crpix2 = crpix2; returnStruct->cdelt1 = cdelt1; returnStruct->cdelt2 = cdelt2; returnStruct->crota2 = crota2; returnStruct->lonc = lonc; returnStruct->latc = latc; returnStruct->ximgsize = fabs(naxis1*cdelt1); returnStruct->yimgsize = fabs(naxis2*cdelt2); returnStruct->rotequ = rot; returnStruct->rac = rac; returnStruct->decc = decc; returnStruct->ra1 = ra1; returnStruct->dec1 = dec1; returnStruct->ra2 = ra2; returnStruct->dec2 = dec2; returnStruct->ra3 = ra3; returnStruct->dec3 = dec3; returnStruct->ra4 = ra4; returnStruct->dec4 = dec4; returnStruct->radius = radius; returnStruct->radpix = rpix; returnStruct->npixel = npix; returnStruct->nnull = nnull; returnStruct->aveflux = mean; returnStruct->rmsflux = rms; returnStruct->fluxref = val; returnStruct->sigmaref = sigmaref; returnStruct->xref = valx; returnStruct->yref = valy; returnStruct->raref = valra; returnStruct->decref = valdec; returnStruct->fluxmin = min; returnStruct->sigmamin = sigmamin; returnStruct->xmin = minx; returnStruct->ymin = miny; returnStruct->ramin = minra; returnStruct->decmin = mindec; returnStruct->fluxmax = max; returnStruct->sigmamax = sigmamax; returnStruct->xmax = maxx; returnStruct->ymax = maxy; returnStruct->ramax = maxra; returnStruct->decmax = maxdec; if(areaMode == APPHOT) returnStruct->totalflux = ap[nflux/2].sum; else returnStruct->totalflux = 0.; return returnStruct; }
void montage_copyData(fitsfile *infptr, fitsfile *outfptr, struct imageParams *params) { long fpixel[4], fpixelo[4]; int i, j, nullcnt; int status = 0; double *buffer, refval; /*************************************************/ /* Make a NaN value to use checking blank pixels */ /*************************************************/ union { double d; char c[8]; } value; double nan; for(i=0; i<8; ++i) value.c[i] = 255; nan = value.d; fpixel[0] = params->ibegin; fpixel[1] = params->jbegin; fpixel[2] = 1; fpixel[3] = 1; if(params->plane) fpixel[2] = params->plane; buffer = (double *)malloc(params->nelements * sizeof(double)); fpixelo[0] = 1; fpixelo[1] = 1; fpixelo[2] = 1; fpixelo[3] = 1; isflat = 1; refval = nan; for (j=params->jbegin; j<=params->jend; ++j) { if(debug >= 2) { printf("Processing input image row %5d\n", j); fflush(stdout); } if(fits_read_pix(infptr, TDOUBLE, fpixel, params->nelements, &nan, buffer, &nullcnt, &status)) montage_printFitsError(status); for(i=0; i<params->nelements; ++i) { if(!mNaN(buffer[i])) { if(mNaN(refval)) refval = buffer[i]; if(buffer[i] != refval) isflat = 0; } } if (fits_write_pix(outfptr, TDOUBLE, fpixelo, params->nelements, (void *)buffer, &status)) montage_printFitsError(status); ++fpixelo[1]; ++fpixel [1]; } free(buffer); if(isflat) { if(mNaN(refval)) strcpy(content, "blank"); else strcpy(content, "flat"); } else strcpy(content, "normal"); }
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; }
double Girard() { int i, j, ibad; double area; double lon, lat; Vec side[16]; double ang [16]; Vec tmp; double pi, dtr, sumang, cosAng, sinAng; pi = atan(1.0) * 4.; dtr = pi / 180.; sumang = 0.; if(nv < 3) return(0.); if(debug >= 4) { for(i=0; i<nv; ++i) { lon = atan2(V[i].y, V[i].x)/dtr; lat = asin(V[i].z)/dtr; printf("Girard(): %3d [%13.6e,%13.6e,%13.6e] -> (%10.6f,%10.6f)\n", i, V[i].x, V[i].y, V[i].z, lon, lat); fflush(stdout); } } for(i=0; i<nv; ++i) { Cross (&V[i], &V[(i+1)%nv], &side[i]); (void) Normalize(&side[i]); } for(i=0; i<nv; ++i) { Cross (&side[i], &side[(i+1)%nv], &tmp); sinAng = Normalize(&tmp); cosAng = -Dot(&side[i], &side[(i+1)%nv]); /* Remove center point of colinear segments */ ang[i] = atan2(sinAng, cosAng); if(debug >= 4) { if(i==0) printf("\n"); printf("Girard(): angle[%d] = %13.6e -> %13.6e (from %13.6e / %13.6e)\n", i, ang[i], ang[i] - pi/2., sinAng, cosAng); fflush(stdout); } if(ang[i] > pi - 0.0175) /* Direction changes of less than */ { /* a degree can be tricky */ ibad = (i+1)%nv; if(debug >= 4) { printf("Girard(): ---------- Corner %d bad; Remove point %d -------------\n", i, ibad); fflush(stdout); } --nv; for(j=ibad; j<nv; ++j) { V[j].x = V[j+1].x; V[j].y = V[j+1].y; V[j].z = V[j+1].z; } return(Girard()); } sumang += ang[i]; } area = sumang - (nv-2.)*pi; if(mNaN(area) || area < 0.) area = 0.; if(debug >= 4) { printf("\nGirard(): area = %13.6e [%d]\n\n", area, nv); fflush(stdout); } return(area); }
int main(int argc, char **argv) { int i, j, countRange, countNaN, status; int haveMinMax, haveVal, writeOutput; long fpixel[4], nelements; double *inbuffer; double NaNvalue; double minblank, maxblank; double *outbuffer; char *end; /************************************************/ /* Make a NaN value to use setting blank pixels */ /************************************************/ union { double d; char c[8]; } value; double nan; for(i=0; i<8; ++i) value.c[i] = 255; nan = value.d; /***************************************/ /* Process the command-line parameters */ /***************************************/ fstatus = stdout; debug = 0; haveVal = 0; writeOutput = 1; for(i=0; i<argc; ++i) { if(strcmp(argv[i], "-d") == 0) { if(i+1 >= argc) { printf("[struct stat=\"ERROR\", msg=\"No debug level given\"]\n"); exit(1); } debug = strtol(argv[i+1], &end, 0); if(end - argv[i+1] < strlen(argv[i+1])) { printf("[struct stat=\"ERROR\", msg=\"Debug level string is invalid: '%s'\"]\n", argv[i+1]); exit(1); } if(debug < 0) { printf("[struct stat=\"ERROR\", msg=\"Debug level value cannot be negative\"]\n"); exit(1); } argv += 2; argc -= 2; } if(strcmp(argv[i], "-v") == 0) { if(i+1 >= argc) { printf("[struct stat=\"ERROR\", msg=\"No value given for NaN conversion\"]\n"); exit(1); } NaNvalue = strtod(argv[i+1], &end); if(end - argv[i+1] < strlen(argv[i+1])) { printf("[struct stat=\"ERROR\", msg=\"NaN conversion value string is invalid: '%s'\"]\n", argv[i+1]); exit(1); } haveVal = 1; argv += 2; argc -= 2; } } if (argc < 3) { printf ("[struct stat=\"ERROR\", msg=\"Usage: %s [-d level][-v NaN-value] in.fits out.fits [minblank maxblank] (output file name '-' means no file)\"]\n", argv[0]); exit(1); } strcpy(input_file, argv[1]); if(input_file[0] == '-') { printf ("[struct stat=\"ERROR\", msg=\"Invalid input file '%s'\"]\n", input_file); exit(1); } strcpy(output_file, argv[2]); if(output_file[0] == '-') writeOutput = 0; haveMinMax = 0; minblank = -2; maxblank = 2; if(argc > 3) { haveMinMax = 1; minblank = strtod(argv[3], &end); if(end < argv[3] + strlen(argv[3])) { printf ("[struct stat=\"ERROR\", msg=\"min blank value string is not a number\"]\n"); exit(1); } maxblank = strtod(argv[4], &end); if(end < argv[4] + strlen(argv[4])) { printf ("[struct stat=\"ERROR\", msg=\"max blank value string is not a number\"]\n"); exit(1); } } if(debug >= 1) { printf("input_file = [%s]\n", input_file); printf("output_file = [%s]\n", output_file); printf("minblank = %-g\n", minblank); printf("maxblank = %-g\n", maxblank); fflush(stdout); } /************************/ /* Read the input image */ /************************/ time(&currtime); start = currtime; readFits(input_file); if(debug >= 1) { printf("input.naxes[0] = %ld\n", input.naxes[0]); printf("input.naxes[1] = %ld\n", input.naxes[1]); printf("input.crpix1 = %-g\n", input.crpix1); printf("input.crpix2 = %-g\n", input.crpix2); fflush(stdout); } output.naxes[0] = input.naxes[0]; output.naxes[1] = input.naxes[1]; output.crpix1 = input.crpix1; output.crpix2 = input.crpix2; if(writeOutput) { /********************************/ /* Create the output FITS files */ /********************************/ remove(output_file); status = 0; if(fits_create_file(&output.fptr, output_file, &status)) printFitsError(status); if(debug >= 1) { printf("\nFITS output file created (not yet populated)\n"); fflush(stdout); } /********************************/ /* Copy all the header keywords */ /* from the input to the output */ /********************************/ if(fits_copy_header(input.fptr, output.fptr, &status)) printFitsError(status); if(debug >= 1) { printf("Header keywords copied to FITS output file\n\n"); fflush(stdout); } /***************************/ /* Modify BITPIX to be -64 */ /***************************/ if(fits_update_key_lng(output.fptr, "BITPIX", -64, (char *)NULL, &status)) printFitsError(status); } /*****************************************************/ /* Allocate memory for the input/output image pixels */ /* (same size as the input image) */ /*****************************************************/ outbuffer = (double *)malloc(output.naxes[0] * sizeof(double)); if(debug >= 1) { printf("%ld bytes allocated for row of output image pixels\n", output.naxes[0] * sizeof(double)); fflush(stdout); } inbuffer = (double *)malloc(input.naxes[0] * sizeof(double)); if(debug >= 1) { printf("%ld bytes allocated for row of input image pixels\n", input.naxes[0] * sizeof(double)); fflush(stdout); } /*****************************/ /* Loop over the input lines */ /*****************************/ fpixel[0] = 1; fpixel[1] = 1; fpixel[2] = 1; fpixel[3] = 1; nelements = input.naxes[0]; status = 0; countRange = 0; countNaN = 0; for (j=0; j<input.naxes[1]; ++j) { if(debug >= 2) { if(debug >= 3) printf("\n"); printf("\rProcessing input row %5d [So far rangeCount=%d, nanCount=%d]", j, countRange, countNaN); if(debug >= 3) printf("\n"); fflush(stdout); } for (i=0; i<output.naxes[0]; ++i) outbuffer[i] = 0.; /***********************************/ /* Read a line from the input file */ /***********************************/ if(fits_read_pix(input.fptr, TDOUBLE, fpixel, nelements, NULL, inbuffer, NULL, &status)) printFitsError(status); /************************/ /* For each input pixel */ /************************/ for (i=0; i<input.naxes[0]; ++i) { if(mNaN(inbuffer[i]) && haveVal) { ++countNaN; outbuffer[i] = NaNvalue; if(debug >= 3) { printf("pixel[%d][%d] converted to %-g\n", j, i, NaNvalue); fflush(stdout); } } else if(haveMinMax && inbuffer[i] >= minblank && inbuffer[i] <= maxblank) { ++countRange; if(haveVal) { ++countNaN; outbuffer[i] = NaNvalue; if(debug >= 3) { printf("pixel[%d][%d] converted to NaN -> %-g\n", j, i, NaNvalue); fflush(stdout); } } else { outbuffer[i] = nan; if(debug >= 3) { printf("pixel[%d][%d] converted to NaN\n", j, i); fflush(stdout); } } } else outbuffer[i] = inbuffer[i]; } /***************************/ /* Write the output buffer */ /***************************/ if(writeOutput) { if (fits_write_pix(output.fptr, TDOUBLE, fpixel, nelements, outbuffer, &status)) printFitsError(status); } ++fpixel[1]; } if(debug >= 1) { time(&currtime); printf("\nDone copying data (%d seconds)\n", (int)(currtime - start)); fflush(stdout); } /************************/ /* Close the FITS files */ /************************/ if(fits_close_file(input.fptr, &status)) printFitsError(status); if(writeOutput) { if(fits_close_file(output.fptr, &status)) printFitsError(status); } if(debug >= 1) { time(&currtime); printf("Done (%d seconds total)\n", (int)(currtime - start)); fflush(stdout); } free(inbuffer); free(outbuffer); printf("[struct stat=\"OK\", rangeCount=%d, nanCount=%d]\n", countRange, countNaN); fflush(stdout); exit(0); }
/* * Use Girard's theorem to compute the area of a sky polygon. */ double Girard() { int i, j, ibad; double area; double lon, lat; Vec side[16]; double ang[16]; Vec tmp; double sumang, cosAng, sinAng; sumang = 0; if (nv < 3) return 0; if (DEBUG >= 4) { for (i = 0; i < nv; ++i) { lon = atan2(V[i].y, V[i].x) / DEG_TO_RADIANS; lat = asin(V[i].z) / DEG_TO_RADIANS; printf("Girard(): %3d [%13.6e,%13.6e,%13.6e] -> (%10.6f,%10.6f)\n", i, V[i].x, V[i].y, V[i].z, lon, lat); fflush(stdout); } } for (i = 0; i < nv; ++i) { Cross(&V[i], &V[(i + 1) % nv], &side[i]); Normalize(&side[i]); } for (i = 0; i < nv; ++i) { Cross(&side[i], &side[(i + 1) % nv], &tmp); sinAng = Normalize(&tmp); cosAng = -Dot(&side[i], &side[(i + 1) % nv]); // Remove center point of colinear segments ang[i] = atan2(sinAng, cosAng); if (DEBUG >= 4) { if (i == 0) printf("\n"); printf("Girard(): angle[%d] = %13.6e -> %13.6e (from %13.6e / %13.6e)\n", i, ang[i], ang[i] - M_PI / 2., sinAng, cosAng); fflush(stdout); } // Direction changes of less than a degree can be tricky if (ang[i] > M_PI - 0.0175) { ibad = (i + 1) % nv; if (DEBUG >= 4) { printf("Girard(): ---------- Corner %d bad; " "Remove point %d -------------\n", i, ibad); fflush(stdout); } --nv; for (j = ibad; j < nv; ++j) { V[j].x = V[j + 1].x; V[j].y = V[j + 1].y; V[j].z = V[j + 1].z; } return (Girard()); } sumang += ang[i]; } area = sumang - (nv - 2.) * M_PI; if (mNaN(area) || area < 0.) area = 0.; if (DEBUG >= 4) { printf("\nGirard(): area = %13.6e [%d]\n\n", area, nv); fflush(stdout); } return area; }