void test_compute_inverse(CuTest* tc) {
	double x,y, dx, dy;
	sip_t* wcs = sip_from_string(wcsfile, 0, NULL);
	CuAssertPtrNotNull(tc, wcs);
	printf("Read:\n");
	sip_print_to(wcs, stdout);

	CuAssertIntEquals(tc, 4, wcs->a_order);
	CuAssertIntEquals(tc, 4, wcs->b_order);
	CuAssertIntEquals(tc, 0, wcs->ap_order);
	CuAssertIntEquals(tc, 0, wcs->bp_order);
	CuAssertIntEquals(tc, 0, sip_ensure_inverse_polynomials(wcs));

	printf("After ensuring inverse:\n");
	sip_print_to(wcs, stdout);

	CuAssertIntEquals(tc, 4, wcs->a_order);
	CuAssertIntEquals(tc, 4, wcs->b_order);
	CuAssertIntEquals(tc, 5, wcs->ap_order);
	CuAssertIntEquals(tc, 5, wcs->bp_order);

	dx = dy = 100;
	for (y=0; y<=sip_imageh(wcs); y+=dy) {
		for (x=0; x<=sip_imagew(wcs); x+=dx) {
			double ra,dec;
			double x2, y2;
            anbool ok;
			sip_pixelxy2radec(wcs, x, y, &ra, &dec);
			ok = sip_radec2pixelxy(wcs, ra, dec, &x2, &y2);
            CuAssertTrue(tc, ok);
			CuAssertDblEquals(tc, x, x2, 1e-2);
			CuAssertDblEquals(tc, y, y2, 1e-2);
			printf("x,y %g,%g --> error %g,%g\n", x,y, x2-x, y2-y);
		}
	}

	sip_free(wcs);
}
Exemple #2
0
void test_wcs_shift(CuTest* tc) {
    sip_t wcs;
    memset(&wcs, 0, sizeof(sip_t));
    wcs.wcstan.crpix[0] = 324.867;
    wcs.wcstan.crpix[1] = 476.596;
    wcs.wcstan.crval[0] = 39.0268;
    wcs.wcstan.crval[1] = 65.0062;
    wcs.wcstan.cd[0][0] =  0.00061453;
    wcs.wcstan.cd[0][1] = -0.0035865;
    wcs.wcstan.cd[1][0] = -0.0035971;
    wcs.wcstan.cd[1][1] = -0.00061653;
    wcs.a[0][2] = 3.7161e-06;
    wcs.a[1][1] = 2.4926e-06;
    wcs.a[2][0] = -1.9189e-05;
    wcs.b[0][2] = -3.0798e-05;
    wcs.b[1][1] = 1.8929e-07;
    wcs.b[2][0] = 8.5835e-06;

    wcs.ap[0][1] = -3.7374e-05;
    wcs.ap[0][2] = -3.8391e-06;
    wcs.ap[1][0] = 3.582e-05;
    wcs.ap[1][1] = -2.5333e-06;
    wcs.ap[2][0] = 1.9578e-05;
    wcs.bp[0][1] = 0.00028454;
    wcs.bp[0][2] = 3.0996e-05;
    wcs.bp[1][0] = -1.0094e-05;
    wcs.bp[1][1] = -3.7012e-07;
    wcs.bp[2][0] = -8.7938e-06;
    wcs.wcstan.imagew = 1024;
    wcs.wcstan.imageh = 1024;
    wcs.a_order = wcs.b_order = 2;
    wcs.ap_order = wcs.bp_order = 2;

    sip_t wcs2;
    memset(&wcs2, 0, sizeof(sip_t));
    memcpy(&(wcs2.wcstan), &(wcs.wcstan), sizeof(tan_t));

#if 0
    //sip_t* newwcs = wcs_shift(&wcs, 2.52369e-05,1.38956e-05);
    sip_t* newwcs = wcs_shift(&wcs, 10., 10.);
    printf("New1:\n");
    sip_print_to(newwcs, stdout);
    printf("\n");
#else
    wcs_shift(&(wcs.wcstan), 10., 10.);
    printf("New1:\n");
    tan_print_to(&(wcs.wcstan), stdout);
    printf("\n");
#endif

#if 0
    sip_t* newwcs2 = wcs_shift(&wcs2, 10., 10.);
    printf("New2:\n");
    sip_print_to(newwcs2, stdout);
    printf("\n");
#endif
    // 10,10:
    
#if 0
    tan_t* newtan = &(newwcs->wcstan);
#else
    tan_t* newtan = &(wcs.wcstan);
#endif
    CuAssertDblEquals(tc, 39.0973, newtan->crval[0], 1e-4);
    CuAssertDblEquals(tc, 65.0483, newtan->crval[1], 1e-4);
    CuAssertDblEquals(tc, 324.867, newtan->crpix[0], 1e-3);
    CuAssertDblEquals(tc, 476.596, newtan->crpix[1], 1e-3);
    CuAssertDblEquals(tc, 0.00061053, newtan->cd[0][0], 1e-8);
    CuAssertDblEquals(tc, -0.0035872, newtan->cd[0][1], 1e-7);
    CuAssertDblEquals(tc, -0.0035978, newtan->cd[1][0], 1e-7);
    CuAssertDblEquals(tc, -0.00061252, newtan->cd[1][1], 1e-8);

    /*
1,1 shift:
TAN-SIP Structure:
  crval=(39.0338, 65.0104)
  crpix=(324.867, 476.596)
  CD = (   0.00061413     -0.0035866 )
       (   -0.0035972    -0.00061613 )
  image size = (1024 x 1024)
  SIP order: A=2, B=2, AP=2, BP=2
  A =            0           0  3.7161e-06
                 0  2.4926e-06
       -1.9189e-05
  B =            0           0 -3.0798e-05
                 0  1.8929e-07
        8.5835e-06
  AP =            0 -3.7374e-05 -3.8391e-06
         3.582e-05 -2.5333e-06
        1.9578e-05
  BP =            0  0.00028454  3.0996e-05
       -1.0094e-05 -3.7012e-07
       -8.7938e-06
  sqrt(det(CD))=13.119 [arcsec]
.

OK (1 test)



TAN-SIP Structure:
  crval=(39.0268, 65.0062)
  crpix=(324.867, 476.596)
  CD = (   0.00061453     -0.0035865 )
       (   -0.0035971    -0.00061653 )
  image size = (1024 x 1024)
  SIP order: A=2, B=2, AP=2, BP=2
  A =            0           0  3.7161e-06
                 0  2.4926e-06
       -1.9189e-05
  B =            0           0 -3.0798e-05
                 0  1.8929e-07
        8.5835e-06
  AP =            0 -3.7374e-05 -3.8391e-06
         3.582e-05 -2.5333e-06
        1.9578e-05
  BP =            0  0.00028454  3.0996e-05
       -1.0094e-05 -3.7012e-07
       -8.7938e-06
  sqrt(det(CD))=13.119 [arcsec]
.



  crval=(39.0268, 65.0062)
  crpix=(324.867, 476.596)
  CD = (   0.00061453     -0.0035865 )
       (   -0.0035971    -0.00061653 )
  image size = (1024 x 1024)
  SIP order: A=2, B=2, AP=2, BP=2
  A =            0           0  3.7161e-06
                 0  2.4926e-06
       -1.9189e-05
  B =            0           0 -3.0798e-05
                 0  1.8929e-07
        8.5835e-06
  AP =            0 -3.7374e-05 -3.8391e-06
         3.582e-05 -2.5333e-06
        1.9578e-05
  BP =            0  0.00028454  3.0996e-05
       -1.0094e-05 -3.7012e-07
       -8.7938e-06
     */
}
Exemple #3
0
void sip_print(const sip_t* sip) {
	sip_print_to(sip, stderr);
}
Exemple #4
0
static sip_t* run_test(CuTest* tc, sip_t* sip, int N, double* xy, double* radec) {
    int i;
    starxy_t* sxy;
    tweak_t* t;
    sip_t* outsip;
    il* imcorr;
    il* refcorr;
    dl* weights;
    tan_t* tan = &(sip->wcstan);

    printf("Input SIP:\n");
    sip_print_to(sip, stdout);
    fflush(NULL);

    sxy = starxy_new(N, FALSE, FALSE);
    starxy_set_xy_array(sxy, xy);

    imcorr = il_new(256);
    refcorr = il_new(256);
    weights = dl_new(256);
    for (i=0; i<N; i++) {
        il_append(imcorr, i);
        il_append(refcorr, i);
        dl_append(weights, 1.0);
    }

    t = tweak_new();
    tweak_push_wcs_tan(t, tan);

    outsip = t->sip;
    outsip->a_order = outsip->b_order = sip->a_order;
    outsip->ap_order = outsip->bp_order = sip->ap_order;

    t->weighted_fit = TRUE;
    tweak_push_ref_ad_array(t, radec, N);
    tweak_push_image_xy(t, sxy);
    tweak_push_correspondence_indices(t, imcorr, refcorr, NULL, weights);
    tweak_skip_shift(t);

    // push correspondences
    // push image xy
    // push ref ra,dec
    // push ref xy (tan)
    // push tan

    tweak_go_to(t, TWEAK_HAS_LINEAR_CD);

    printf("Output SIP:\n");
    sip_print_to(outsip, stdout);

    CuAssertDblEquals(tc, tan->imagew, outsip->wcstan.imagew, 1e-10);
    CuAssertDblEquals(tc, tan->imageh, outsip->wcstan.imageh, 1e-10);

    // should be exactly equal.
    CuAssertDblEquals(tc, tan->crpix[0], outsip->wcstan.crpix[0], 1e-10);
    CuAssertDblEquals(tc, tan->crpix[1], outsip->wcstan.crpix[1], 1e-10);

    t->sip = NULL;
    tweak_free(t);
    starxy_free(sxy);
    return outsip;
}
Exemple #5
0
sip_t* tweak2(const double* fieldxy, int Nfield,
			  double fieldjitter,
			  int W, int H,
			  const double* indexradec, int Nindex,
			  double indexjitter,
			  const double* quadcenter, double quadR2,
			  double distractors,
			  double logodds_bail,
			  int sip_order,
			  int sip_invorder,
			  const sip_t* startwcs,
			  sip_t* destwcs,
			  int** newtheta, double** newodds,
			  double* crpix,
			  double* p_logodds,
			  int* p_besti,
			  int* testperm,
			  int startorder) {
	int order;
	sip_t* sipout;
	int* indexin;
	double* indexpix;
	double* fieldsigma2s;
	double* weights;
	double* matchxyz;
	double* matchxy;
	int i, Nin=0;
	double logodds = 0;
	int besti = -1;
	int* theta = NULL;
	double* odds = NULL;
	int* refperm = NULL;
	double qc[2];

	memcpy(qc, quadcenter, 2*sizeof(double));

	if (destwcs)
		sipout = destwcs;
	else
		sipout = sip_create();

	indexin = malloc(Nindex * sizeof(int));
	indexpix = malloc(2 * Nindex * sizeof(double));
	fieldsigma2s = malloc(Nfield * sizeof(double));
	weights = malloc(Nfield * sizeof(double));
	matchxyz = malloc(Nfield * 3 * sizeof(double));
	matchxy = malloc(Nfield * 2 * sizeof(double));

	// FIXME --- hmmm, how do the annealing steps and iterating up to
	// higher orders interact?

	assert(startwcs);
	memcpy(sipout, startwcs, sizeof(sip_t));

	logverb("tweak2: starting orders %i, %i\n", sipout->a_order, sipout->ap_order);

	if (!sipout->wcstan.imagew)
		sipout->wcstan.imagew = W;
	if (!sipout->wcstan.imageh)
		sipout->wcstan.imageh = H;

	logverb("Tweak2: starting from WCS:\n");
	if (log_get_level() >= LOG_VERB)
		sip_print_to(sipout, stdout);

	for (order=startorder; order <= sip_order; order++) {
		int step;
		int STEPS = 100;
		// variance growth rate wrt radius.
		double gamma = 1.0;
		//logverb("Starting tweak2 order=%i\n", order);

		for (step=0; step<STEPS; step++) {
			double iscale;
			double ijitter;
			double ra, dec;
			double R2;
			int Nmatch;
			int nmatch, nconf, ndist;
			double pix2;
			double totalweight;

			// clean up from last round (we do it here so that they're
			// valid when we leave the loop)
			free(theta);
			free(odds);
			free(refperm);

			// Anneal
			gamma = pow(0.9, step);
			if (step == STEPS-1)
				gamma = 0.0;
			logverb("Annealing: order %i, step %i, gamma = %g\n", order, step, gamma);
			
			debug("Using input WCS:\n");
			if (log_get_level() > LOG_VERB)
				sip_print_to(sipout, stdout);

			// Project reference sources into pixel space; keep the ones inside image bounds.
			Nin = 0;
			for (i=0; i<Nindex; i++) {
				anbool ok;
				double x,y;
				ra  = indexradec[2*i + 0];
				dec = indexradec[2*i + 1];
				ok = sip_radec2pixelxy(sipout, ra, dec, &x, &y);
				if (!ok)
					continue;
				if (!sip_pixel_is_inside_image(sipout, x, y))
					continue;
				indexpix[Nin*2+0] = x;
				indexpix[Nin*2+1] = y;
				indexin[Nin] = i;
				Nin++;
			}
			logverb("%i reference sources within the image.\n", Nin);
			//logverb("CRPIX is (%g,%g)\n", sip.wcstan.crpix[0], sip.wcstan.crpix[1]);

            if (Nin == 0) {
				sip_free(sipout);
				free(matchxy);
				free(matchxyz);
				free(weights);
				free(fieldsigma2s);
				free(indexpix);
				free(indexin);
                return NULL;
            }

			iscale = sip_pixel_scale(sipout);
			ijitter = indexjitter / iscale;
			//logverb("With pixel scale of %g arcsec/pixel, index adds jitter of %g pix.\n", iscale, ijitter);

			/* CHECK
			 for (i=0; i<Nin; i++) {
			 double x,y;
			 int ii = indexin[i];
			 sip_radec2pixelxy(sipout, indexradec[2*ii+0], indexradec[2*ii+1], &x, &y);
			 logverb("indexin[%i]=%i; (%.1f,%.1f) -- (%.1f,%.1f)\n",
			 i, ii, indexpix[i*2+0], indexpix[i*2+1], x, y);
			 }
			 */

			for (i=0; i<Nfield; i++) {
				R2 = distsq(qc, fieldxy + 2*i, 2);
				fieldsigma2s[i] = (square(fieldjitter) + square(ijitter)) * (1.0 + gamma * R2/quadR2);
			}

			if (order == 1 && step == 0 && TWEAK_DEBUG_PLOTS) {
				TWEAK_DEBUG_PLOT("init", W, H, Nfield, fieldxy, fieldsigma2s,
								 Nin, indexpix, *p_besti, *newtheta,
								 sipout->wcstan.crpix, testperm, qc);
			}

			/*
			 logodds = verify_star_lists(indexpix, Nin,
			 fieldxy, fieldsigma2s, Nfield,
			 W*H, distractors,
			 logodds_bail, HUGE_VAL,
			 &besti, &odds, &theta, NULL,
			 &testperm);
			 */

			pix2 = square(fieldjitter);
			logodds = verify_star_lists_ror(indexpix, Nin,
											fieldxy, fieldsigma2s, Nfield,
											pix2, gamma, qc, quadR2,
											W, H, distractors,
											logodds_bail, HUGE_VAL,
											&besti, &odds, &theta, NULL,
											&testperm, &refperm);

			logverb("Logodds: %g\n", logodds);
			verify_count_hits(theta, besti, &nmatch, &nconf, &ndist);
			logverb("%i matches, %i distractors, %i conflicts (at best log-odds); %i field sources, %i index sources\n", nmatch, ndist, nconf, Nfield, Nin);
			verify_count_hits(theta, Nfield-1, &nmatch, &nconf, &ndist);
			logverb("%i matches, %i distractors, %i conflicts (all sources)\n", nmatch, ndist, nconf);
			if (log_get_level() >= LOG_VERB) {
				matchobj_log_hit_miss(theta, testperm, besti+1, Nfield, LOG_VERB, "Hit/miss: ");
			}

			/*
			 logverb("\nAfter verify():\n");
			 for (i=0; i<Nin; i++) {
			 double x,y;
			 int ii = indexin[refperm[i]];
			 sip_radec2pixelxy(sipout, indexradec[2*ii+0], indexradec[2*ii+1], &x, &y);
			 logverb("indexin[%i]=%i; (%.1f,%.1f) -- (%.1f,%.1f)\n",
			 i, ii, indexpix[i*2+0], indexpix[i*2+1], x, y);
			 }
			 */

			if (TWEAK_DEBUG_PLOTS) {
				char name[32];
				sprintf(name, "o%is%02ipre", order, step);
				TWEAK_DEBUG_PLOT(name, W, H, Nfield, fieldxy, fieldsigma2s,
								 Nin, indexpix, besti, theta,
								 sipout->wcstan.crpix, testperm, qc);
			}

			Nmatch = 0;
			debug("Weights:");
			for (i=0; i<Nfield; i++) {
				double ra,dec;
				if (theta[i] < 0)
					continue;
				assert(theta[i] < Nin);
				int ii = indexin[refperm[theta[i]]];
				assert(ii < Nindex);
				assert(ii >= 0);

				ra  = indexradec[ii*2+0];
				dec = indexradec[ii*2+1];
				radecdeg2xyzarr(ra, dec, matchxyz + Nmatch*3);
				memcpy(matchxy + Nmatch*2, fieldxy + i*2, 2*sizeof(double));
				weights[Nmatch] = verify_logodds_to_weight(odds[i]);
				debug(" %.2f", weights[Nmatch]);
				Nmatch++;

				/*
				 logverb("match img (%.1f,%.1f) -- ref (%.1f, %.1f), odds %g, wt %.3f\n",
				 fieldxy[i*2+0], fieldxy[i*2+1],
				 indexpix[theta[i]*2+0], indexpix[theta[i]*2+1],
				 odds[i],
				 weights[Nmatch-1]);
				 double xx,yy;
				 sip_radec2pixelxy(sipout, ra, dec, &xx, &yy);
				 logverb("check: (%.1f, %.1f)\n", xx, yy);
				 */
			}
			debug("\n");

			if (Nmatch < 2) {
				logverb("No matches -- aborting tweak attempt\n");
				free(theta);
				sip_free(sipout);
				free(matchxy);
				free(matchxyz);
				free(weights);
				free(fieldsigma2s);
				free(indexpix);
				free(indexin);
				return NULL;
			}

			// Update the "quad center" to be the weighted average matched star posn.
			qc[0] = qc[1] = 0.0;
			totalweight = 0.0;
			for (i=0; i<Nmatch; i++) {
				qc[0] += (weights[i] * matchxy[2*i+0]);
				qc[1] += (weights[i] * matchxy[2*i+1]);
				totalweight += weights[i];
			}
			qc[0] /= totalweight;
			qc[1] /= totalweight;
			logverb("Moved quad center to (%.1f, %.1f)\n", qc[0], qc[1]);

            //
            sipout->a_order = sipout->b_order = order;
            sipout->ap_order = sipout->bp_order = sip_invorder;
            logverb("tweak2: setting orders %i, %i\n", sipout->a_order, sipout->ap_order);

            if (crpix) {
                tan_t temptan;
                logverb("Moving tangent point to given CRPIX (%g,%g)\n", crpix[0], crpix[1]);
                fit_tan_wcs_move_tangent_point_weighted(matchxyz, matchxy, weights, Nmatch,
                                                        crpix, &sipout->wcstan, &temptan);
                fit_tan_wcs_move_tangent_point_weighted(matchxyz, matchxy, weights, Nmatch,
                                                        crpix, &temptan, &sipout->wcstan);
            }

            int doshift = 1;
            fit_sip_wcs(matchxyz, matchxy, weights, Nmatch,
                        &(sipout->wcstan), order, sip_invorder,
                        doshift, sipout);

            debug("Got SIP:\n");
            if (log_get_level() > LOG_VERB)
                sip_print_to(sipout, stdout);
            sipout->wcstan.imagew = W;
            sipout->wcstan.imageh = H;
		}
	}

	//logverb("Final logodds: %g\n", logodds);

	// Now, recompute final logodds after turning 'gamma' on again (?)
	// FIXME -- this counts the quad stars in the logodds...
	{
		double gamma = 1.0;
		double iscale;
		double ijitter;
		double ra, dec;
		double R2;
		int nmatch, nconf, ndist;
		double pix2;

		free(theta);
		free(odds);
		free(refperm);
		gamma = 1.0;
		// Project reference sources into pixel space; keep the ones inside image bounds.
		Nin = 0;
		for (i=0; i<Nindex; i++) {
			anbool ok;
			double x,y;
			ra  = indexradec[2*i + 0];
			dec = indexradec[2*i + 1];
			ok = sip_radec2pixelxy(sipout, ra, dec, &x, &y);
			if (!ok)
				continue;
			if (!sip_pixel_is_inside_image(sipout, x, y))
				continue;
			indexpix[Nin*2+0] = x;
			indexpix[Nin*2+1] = y;
			indexin[Nin] = i;
			Nin++;
		}
		logverb("%i reference sources within the image.\n", Nin);

		iscale = sip_pixel_scale(sipout);
		ijitter = indexjitter / iscale;
		for (i=0; i<Nfield; i++) {
			R2 = distsq(qc, fieldxy + 2*i, 2);
			fieldsigma2s[i] = (square(fieldjitter) + square(ijitter)) * (1.0 + gamma * R2/quadR2);
		}

		pix2 = square(fieldjitter);
		logodds = verify_star_lists_ror(indexpix, Nin,
										fieldxy, fieldsigma2s, Nfield,
										pix2, gamma, qc, quadR2,
										W, H, distractors,
										logodds_bail, HUGE_VAL,
										&besti, &odds, &theta, NULL,
										&testperm, &refperm);
		logverb("Logodds: %g\n", logodds);
		verify_count_hits(theta, besti, &nmatch, &nconf, &ndist);
		logverb("%i matches, %i distractors, %i conflicts (at best log-odds); %i field sources, %i index sources\n", nmatch, ndist, nconf, Nfield, Nin);
		verify_count_hits(theta, Nfield-1, &nmatch, &nconf, &ndist);
		logverb("%i matches, %i distractors, %i conflicts (all sources)\n", nmatch, ndist, nconf);
		if (log_get_level() >= LOG_VERB) {
			matchobj_log_hit_miss(theta, testperm, besti+1, Nfield, LOG_VERB,
								  "Hit/miss: ");
		}

		if (TWEAK_DEBUG_PLOTS) {
			TWEAK_DEBUG_PLOT("final", W, H, Nfield, fieldxy, fieldsigma2s,
							 Nin, indexpix, besti, theta,
							 sipout->wcstan.crpix, testperm, qc);
		}
	}


	if (newtheta) {
		// undo the "indexpix" inside-image-bounds cut.
		(*newtheta) = malloc(Nfield * sizeof(int));
		for (i=0; i<Nfield; i++) {
			int nt;
			if (theta[i] < 0)
				nt = theta[i];
			else
				nt = indexin[refperm[theta[i]]];
			(*newtheta)[i] = nt;
		}
	}
	free(theta);
	free(refperm);

	if (newodds)
		*newodds = odds;
	else
		free(odds);

	logverb("Tweak2: final WCS:\n");
	if (log_get_level() >= LOG_VERB)
		sip_print_to(sipout, stdout);

	if (p_logodds)
		*p_logodds = logodds;
	if (p_besti)
		*p_besti = besti;

	free(indexin);
	free(indexpix);
	free(fieldsigma2s);
	free(weights);
	free(matchxyz);
	free(matchxy);

	return sipout;
}