コード例 #1
0
sip_t* wcs_pv2sip_header(qfits_header* hdr,
                         double* xy, int Nxy,
               
                         double stepsize,
                         double xlo, double xhi,
                         double ylo, double yhi,

                         int imageW, int imageH,
                         int order,
                         anbool forcetan,
                         int doshift) {
	double* radec = NULL;
	int rtn = -1;
	tan_t tanwcs;
	double x,y, px,py;
	double* rddist = NULL;
	int i, j;
    int nx, ny;
    double xstep, ystep;
    sip_t* sip = NULL;

    /**
     From http://iraf.noao.edu/projects/mosaic/tpv.html

     p = PV1_

     xi' = p0 +
           p1 * xi + p2 * eta + p3 * r +
           p4 * xi^2 + p5 * xi * eta + p6 * eta^2 +
           p7 * xi^3 + p8 * xi^2 * eta + p9 * xi * eta^2 +
              p10 * eta^3 + p11 * r^3 + 
           p12 * xi^4 + p13 * xi^3 * eta + p14 * xi^2 * eta^2 +
              p15 * xi * eta^3 + p16 * eta^4 +
	       p17 * xi^5 + p18 * xi^4 * eta + p19 * xi^3 * eta^2 +
	          p20 * xi^2 * eta^3 + p21 * xi * eta^4 + p22 * eta^5 + p23 * r^5 +
           p24 * xi^6 + p25 * xi^5 * eta + p26 * xi^4 * eta^2 +
              p27 * xi^3 * eta^3 + p28 * xi^2 * eta^4 + p29 * xi * eta^5 +
              p30 * eta^6
           p31 * xi^7 + p32 * xi^6 * eta + p33 * xi^5 * eta^2 +
              p34 * xi^4 * eta^3 + p35 * xi^3 * eta^4 + p36 * xi^2 * eta^5 +
              p37 * xi * eta^6 + p38 * eta^7 + p39 * r^7

     p = PV2_
     eta' = p0 +
            p1 * eta + p2 * xi + p3 * r +
            p4 * eta^2 + p5 * eta * xi + p6 * xi^2 +
            p7 * eta^3 + p8 * eta^2 * xi + p9 * eta * xi^2 + p10 * xi^3 +
                 p11 * r^3 +
            p12 * eta^4 + p13 * eta^3 * xi + p14 * eta^2 * xi^2 +
                 p15 * eta * xi^3 + p16 * xi^4 +
            p17 * eta^5 + p18 * eta^4 * xi + p19 * eta^3 * xi^2 +
	             p20 * eta^2 * xi^3 + p21 * eta * xi^4 + p22 * xi^5 +
                 p23 * r^5 +
            p24 * eta^6 + p25 * eta^5 * xi + p26 * eta^4 * xi^2 +
                 p27 * eta^3 * xi^3 + p28 * eta^2 * xi^4 + p29 * eta * xi^5 +
                 p30 * xi^6
            p31 * eta^7 + p32 * eta^6 * xi + p33 * eta^5 * xi^2 +
                 p34 * eta^4 * xi^3 + p35 * eta^3 * xi^4 + p36 * eta^2 * xi^5 +
                 p37 * eta * xi^6 + p38 * xi^7 + p39 * r^7

     Note the "cross-over" -- the xi' powers are in terms of xi,eta
     while the eta' powers are in terms of eta,xi.
     */

	//           1  x  y  r x2 xy y2 x3 x2y xy2 y3 r3 x4 x3y x2y2 xy3 y4
	//          x5 x4y x3y2 x2y3 xy4 y5 r5 x6 x5y x4y2, x3y3 x2y4 xy5 y6
	//          x7 x6y x5y2 x4y3 x3y4 x2y5 xy6 y7 r7
	int xp[] = {
     0,
     1, 0, 0,
     2, 1, 0,
     3, 2, 1, 0, 0,
     4, 3, 2, 1, 0,
     5, 4, 3, 2, 1, 0, 0,
     6, 5, 4, 3, 2, 1, 0,
     7, 6, 5, 4, 3, 2, 1, 0, 0};
	int yp[] = {
     0,
     0, 1, 0,
     0, 1, 2,
     0, 1, 2, 3, 0,
     0, 1, 2, 3, 4,
     0, 1, 2, 3, 4, 5, 0,
     0, 1, 2, 3, 4, 5, 6,
     0, 1, 2, 3, 4, 5, 6, 7, 0};
	int rp[] = {
     0,
     0, 0, 1,
     0, 0, 0,
     0, 0, 0, 0, 3,
     0, 0, 0, 0, 0,
     0, 0, 0, 0, 0, 0, 5,
     0, 0, 0, 0, 0, 0, 0,
     0, 0, 0, 0, 0, 0, 0, 0, 7};
	double xpows[8];
	double ypows[8];
	double rpows[8];
	double pv1[40];
	double pv2[40];
	double r;

    char* ct;
    ct = fits_get_dupstring(hdr, "CTYPE1");
    if ((ct && streq(ct, "RA---TPV")) || forcetan) {
        // http://iraf.noao.edu/projects/ccdmosaic/tpv.html
        logmsg("Replacing CTYPE1 = %s header with RA---TAN\n", ct);
        fits_update_value(hdr, "CTYPE1", "RA---TAN");
    }
    ct = fits_get_dupstring(hdr, "CTYPE2");
    if ((ct && streq(ct, "DEC--TPV")) || forcetan) {
        logmsg("Replacing CTYPE2 = %s header with DEC--TAN\n", ct);
        fits_update_value(hdr, "CTYPE2", "DEC--TAN");
    }

	tan_read_header(hdr, &tanwcs);

    if (log_get_level() >= LOG_VERB) {
        printf("Read TAN header:\n");
        tan_print(&tanwcs);
    }

    if (imageW && (imageW != tanwcs.imagew)) {
        logmsg("Overriding image width %f with user-specified %i\n",
               tanwcs.imagew, imageW);
        tanwcs.imagew = imageW;
    }
    if (imageH && (imageH != tanwcs.imageh)) {
        logmsg("Overriding image height %f with user-specified %i\n",
               tanwcs.imageh, imageH);
        tanwcs.imageh = imageH;
    }

	for (i=0; i<sizeof(pv1)/sizeof(double); i++) {
		char key[10];
        double defaultval;

        if (i == 1) {
            defaultval = 1.0;
        } else {
            defaultval = 0.0;
        }
		sprintf(key, "PV1_%i", i);
		pv1[i] = qfits_header_getdouble(hdr, key, defaultval);
		sprintf(key, "PV2_%i", i);
		pv2[i] = qfits_header_getdouble(hdr, key, defaultval);
	}


    // choose grid for evaluating TAN-PV WCS
    if (xlo == 0 && xhi == 0) {
        xlo = 1.;
        xhi = tanwcs.imagew;
    }
    if (ylo == 0 && yhi == 0) {
        ylo = 1.;
        yhi = tanwcs.imageh;
    }

	assert(xhi >= xlo);
	assert(yhi >= ylo);

	if (stepsize == 0)
        stepsize = 100.;
    nx = MAX(2, round((xhi - xlo)/stepsize));
    ny = MAX(2, round((yhi - ylo)/stepsize));
    xstep = (xhi - xlo) / (double)(nx - 1);
    ystep = (yhi - ylo) / (double)(ny - 1);

	logverb("Stepping from x = %g to %g, steps of %g\n", xlo, xhi, xstep);
	logverb("Stepping from y = %g to %g, steps of %g\n", ylo, yhi, ystep);

    Nxy = nx * ny;

    if (xy == NULL) {
        int k = 0;
        xy = malloc(Nxy * 2 * sizeof(double));
        for (i=0; i<ny; i++) {
            y = ylo + i*ystep;
            for (j=0; j<nx; j++) {
                x = xlo + j*xstep;
                //if (i == 0)
                //printf("x=%f\n", x);
                xy[k] = x;
                k++;
                xy[k] = y;
                k++;
            }
            //printf("y=%f\n", y);
        }
        assert(k == (Nxy*2));
    }

    // distorted RA,Dec
	rddist = malloc(2 * Nxy * sizeof(double));

	for (j=0; j<Nxy; j++) {
        double ix = xy[2*j+0];
		double iy = xy[2*j+1];

		tan_pixelxy2iwc(&tanwcs, ix, iy, &x, &y);
        // "x,y" here are most commonly known as "xi, eta".
		r = sqrt(x*x + y*y);
        // compute powers of x,y
		xpows[0] = ypows[0] = rpows[0] = 1.0;
		for (i=1; i<sizeof(xpows)/sizeof(double); i++) {
			xpows[i] = xpows[i-1]*x;
			ypows[i] = ypows[i-1]*y;
			rpows[i] = rpows[i-1]*r;
		}
		px = py = 0;
		for (i=0; i<sizeof(xp)/sizeof(int); i++) {
			px += pv1[i] * xpows[xp[i]] * ypows[yp[i]] * rpows[rp[i]];
            // here's the "cross-over" mentioned above
			py += pv2[i] * ypows[xp[i]] * xpows[yp[i]] * rpows[rp[i]];
		}

        // Note that the PV terms *include* a linear term, so no need
        // to re-add x,y to px,py.
        tan_iwc2radec(&tanwcs, px, py,
                      rddist + 2*j, rddist + 2*j + 1);
	}

    sip = malloc(sizeof(sip_t));
    assert(sip);
    {
        double* starxyz;
        starxyz = malloc(3 * Nxy * sizeof(double));
        for (i=0; i<Nxy; i++)
            radecdegarr2xyzarr(rddist + i*2, starxyz + i*3);
        memset(sip, 0, sizeof(sip_t));
        rtn = fit_sip_coefficients(starxyz, xy, NULL, Nxy,
                                   &tanwcs, order, order, sip);
        assert(rtn == 0);

        if (log_get_level() >= LOG_VERB) {
            printf("Fit SIP:\n");
            sip_print(sip);
        }

        // FIXME? -- use xlo,xhi,ylo,yhi here??  Not clear.
        sip_compute_inverse_polynomials(sip, 0, 0, 0, 0, 0, 0);

        if (log_get_level() >= LOG_VERB) {
            printf("Fit SIP inverse polynomials:\n");
            sip_print(sip);
        }
        free(starxyz);
    }

	free(rddist);
	free(radec);
    return sip;
}
コード例 #2
0
ファイル: anqfits.c プロジェクト: Carl4/astrometry.net
const anqfits_image_t* anqfits_get_image_const(const anqfits_t* qf, int ext) {
    assert(ext >= 0 && ext < qf->Nexts);
    if (!qf->exts[ext].image) {
        anqfits_image_t* img;
        const qfits_header* hdr = anqfits_get_header_const(qf, ext);
        int naxis1, naxis2, naxis3;
        if (!hdr) {
            qfits_error("Failed to get header for ext %i\n", ext);
            return NULL;
        }
        img = anqfits_image_new();

        // from qfits_image.c : qfitsloader_init()
        img->bitpix = qfits_header_getint(hdr, "BITPIX", -1);
        img->naxis  = qfits_header_getint(hdr, "NAXIS",  -1);
        naxis1 = qfits_header_getint(hdr, "NAXIS1", -1);
        naxis2 = qfits_header_getint(hdr, "NAXIS2", -1);
        naxis3 = qfits_header_getint(hdr, "NAXIS3", -1);
        img->bzero  = qfits_header_getdouble(hdr, "BZERO", 0.0);
        img->bscale = qfits_header_getdouble(hdr, "BSCALE", 1.0);

        if (img->bitpix == -1) {
            qfits_error("Missing BITPIX in file %s ext %i", qf->filename, ext);
            goto bailout;
        }
        if (!((img->bitpix == 8) || (img->bitpix == 16) ||
              (img->bitpix == 32) ||
              (img->bitpix == -32) || (img->bitpix == -64))) {
            qfits_error("Invalid BITPIX %i in file %s ext %i",
                        img->bitpix, qf->filename, ext);
            goto bailout;
        }
        img->bpp = BYTESPERPIXEL(img->bitpix);

        if (img->naxis < 0) {
            qfits_error("No NAXIS in file %s ext %i", qf->filename, ext);
            goto bailout;
        }
        if (img->naxis==0) {
            qfits_error("NAXIS = 0 in file %s ext %i", qf->filename, ext);
            goto bailout;
        }
        if (img->naxis > 3) {
            qfits_error("NAXIS = %i > 3 unsupported in file %s ext %i",
                        img->naxis, qf->filename, ext);
            goto bailout;
        }
        /* NAXIS1 must always be present */
        if (naxis1 < 0) {
            qfits_error("No NAXIS1 in file %s ext %i", qf->filename, ext);
            goto bailout;
        }
        img->width = 1;
        img->height = 1;
        img->planes = 1;
        switch (img->naxis) {
        case 1:
            img->width = naxis1;
            break;
        case 3:
            if (naxis3 < 0) {
                qfits_error("No NAXIS3 in file %s ext %i", qf->filename, ext);
                goto bailout;
            }
            img->planes = naxis3;
            // no break: fall through to...
        case 2:
            if (naxis2 < 0) {
                qfits_error("No NAXIS2 in file %s ext %i", qf->filename, ext);
                goto bailout;
            }
            img->height = naxis2;
            img->width = naxis1;
            break;
        }
        qf->exts[ext].image = img;
        return img;

    bailout:
        anqfits_image_free(img);
        return NULL;
    }
    return qf->exts[ext].image;
}
コード例 #3
0
ファイル: sip_qfits.c プロジェクト: rasmi/astrometry.net
tan_t* tan_read_header(const qfits_header* hdr, tan_t* dest) {
	tan_t tan;
	double nil = -1e300;
	char* ct1;
	char* ct2;
	int swap;
	int W, H;
	anbool is_sin;

	memset(&tan, 0, sizeof(tan_t));

	ct1 = fits_get_dupstring(hdr, "CTYPE1");
	ct2 = fits_get_dupstring(hdr, "CTYPE2");
	swap = check_tan_ctypes(ct1, ct2, &is_sin);
	if (swap == -1) {
		ERROR("TAN header: expected CTYPE1 = RA---TAN, CTYPE2 = DEC--TAN "
			  "(or vice versa), or RA---SIN, DEC--SIN or vice versa; "
			  "got CTYPE1 = \"%s\", CYTPE2 = \"%s\"\n",
			  ct1, ct2);
	}
	free(ct1);
	free(ct2);
	if (swap == -1)
		return NULL;

	sip_get_image_size(hdr, &W, &H);
	tan.imagew = W;
	tan.imageh = H;

	{
		const char* keys[] = { "CRVAL1", "CRVAL2", "CRPIX1", "CRPIX2",
						 "CD1_1", "CD1_2", "CD2_1", "CD2_2" };
		double* vals[] = { &(tan.crval[0]), &(tan.crval[1]),
						   &(tan.crpix[0]), &(tan.crpix[1]),
						   &(tan.cd[0][0]), &(tan.cd[0][1]),
						   &(tan.cd[1][0]), &(tan.cd[1][1]) };
		int i;
        for (i=0; i<4; i++) {
			*(vals[i]) = qfits_header_getdouble(hdr, keys[i], nil);
			if (*(vals[i]) == nil) {
				ERROR("TAN header: missing or invalid value for \"%s\"", keys[i]);
				return NULL;
			}
		}
        // Try CD
        int gotcd = 1;
        char* complaint = NULL;
        for (i=4; i<8; i++) {
			*(vals[i]) = qfits_header_getdouble(hdr, keys[i], nil);
			if (*(vals[i]) == nil) {
                asprintf_safe(&complaint, "TAN header: missing or invalid value for key \"%s\"", keys[i]);
                gotcd = 0;
                break;
            }
        }
        if (!gotcd) {
            double cdelt1,cdelt2;
            // Try CDELT
            char* key = "CDELT1";
            cdelt1 = qfits_header_getdouble(hdr, key, nil);
            if (cdelt1 == nil) {
				ERROR("%s; also tried but didn't find \"%s\"", complaint, key);
                free(complaint);
				return NULL;
			}
            key = "CDELT2";
            cdelt2 = qfits_header_getdouble(hdr, key, nil);
            if (cdelt2 == nil) {
				ERROR("%s; also tried but didn't find \"%s\"", complaint, key);
                free(complaint);
				return NULL;
			}
            tan.cd[0][0] = cdelt1;
            tan.cd[0][1] = 0.0;
            tan.cd[1][0] = 0.0;
            tan.cd[1][1] = cdelt2;
        }
	}

	if (swap == 1) {
		double tmp;
		tmp = tan.crval[0];
		tan.crval[0] = tan.crval[1];
		tan.crval[1] = tmp;
		// swap CD1_1 <-> CD2_1
		tmp = tan.cd[0][0];
		tan.cd[0][0] = tan.cd[1][0];
		tan.cd[1][0] = tmp;
		// swap CD1_2 <-> CD2_2
		tmp = tan.cd[0][1];
		tan.cd[0][1] = tan.cd[1][1];
		tan.cd[1][1] = tmp;
	}

	tan.sin = is_sin;

	if (!dest)
		dest = malloc(sizeof(tan_t));
	memcpy(dest, &tan, sizeof(tan_t));
	return dest;
}
コード例 #4
0
ファイル: starkd.c プロジェクト: dstndstn/astrometry.net
double startree_get_jitter(const startree_t* s) {
    return qfits_header_getdouble(s->header, "JITTER", 0.0);
}
コード例 #5
0
ファイル: starkd.c プロジェクト: dstndstn/astrometry.net
double startree_get_cut_dedup(const startree_t* s) {
    return qfits_header_getdouble(s->header, "CUTDEDUP", 0.0);
}
コード例 #6
0
void fits_guess_scale_hdr(const qfits_header* hdr,
                          sl** p_methods, dl** p_scales) {
	sip_t sip;
	double val;
	anbool gotsip = FALSE;
    char* errstr;

    sl* methods = NULL;
    dl* scales = NULL;

    if (p_methods) {
        if (!*p_methods)
            *p_methods = sl_new(4);
        methods = *p_methods;
    }
    if (p_scales) {
        if (!*p_scales)
            *p_scales = dl_new(4);
        scales = *p_scales;
    }

	memset(&sip, 0, sizeof(sip_t));

    errors_start_logging_to_string();

	if (sip_read_header(hdr, &sip)) {
        val = sip_pixel_scale(&sip);
        if (val != 0.0) {
            addscale(methods, scales, "sip", val);
            gotsip = TRUE;
		}
	}
    errstr = errors_stop_logging_to_string("\n  ");
    logverb("fits-guess-scale: failed to read SIP/TAN header:\n  %s\n", errstr);
    free(errstr);

	if (!gotsip) {
		// it might have a correct CD matrix but be missing other parts (eg CRVAL)
		double cd11, cd12, cd21, cd22;
		double errval = -HUGE_VAL;
		cd11 = qfits_header_getdouble(hdr, "CD1_1", errval);
		cd12 = qfits_header_getdouble(hdr, "CD1_2", errval);
		cd21 = qfits_header_getdouble(hdr, "CD2_1", errval);
		cd22 = qfits_header_getdouble(hdr, "CD2_2", errval);
		if ((cd11 != errval) && (cd12 != errval) && (cd21 != errval) && (cd22 != errval)) {
			val = cd11 * cd22 - cd12 * cd21;
			if (val != 0.0)
                addscale(methods, scales, "cd", sqrt(fabs(val)));
		}
	}

	val = qfits_header_getdouble(hdr, "PIXSCALE", -1.0);
	if (val != -1.0)
        addscale(methods, scales, "pixscale", val);

    /* Why all this?
     val = qfits_header_getdouble(hdr, "PIXSCAL1", -1.0);
     if (val != -1.0) {
     if (val != 0.0) {
     printf("scale pixscal1 %g\n", val);
     } else {
     val = atof(qfits_pretty_string(qfits_header_getstr(hdr, "PIXSCAL1")));
     if (val != 0.0) {
     printf("scale pixscal1 %g\n", val);
     }
     }
     }
     */

     val = qfits_header_getdouble(hdr, "PIXSCAL1", 0.0);
     if (val != 0.0)
         addscale(methods, scales, "pixscal1", val);

     val = qfits_header_getdouble(hdr, "PIXSCAL2", 0.0);
     if (val != 0.0)
         addscale(methods, scales, "pixscal2", val);

     val = qfits_header_getdouble(hdr, "PLATESC", 0.0);
     if (val != 0.0)
         addscale(methods, scales, "platesc", val);

	val = qfits_header_getdouble(hdr, "CCDSCALE", 0.0);
     if (val != 0.0)
         addscale(methods, scales, "ccdscale", val);

	val = qfits_header_getdouble(hdr, "CDELT1", 0.0);
     if (val != 0.0)
         addscale(methods, scales, "cdelt1", 3600.0 * fabs(val));
}