예제 #1
0
파일: sip_wrap.c 프로젝트: Abhin33t/astropy
static void
PySip_dealloc(
    PySip* self) {

  sip_free(&self->x);
  Py_TYPE(self)->tp_free((PyObject*)self);
}
예제 #2
0
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);
}
예제 #3
0
파일: sip.c 프로젝트: jhunkeler/pywcs
int
sip_init(
    sip_t* sip,
    const unsigned int a_order, const double* a,
    const unsigned int b_order, const double* b,
    const unsigned int ap_order, const double* ap,
    const unsigned int bp_order, const double* bp,
    const double* crpix /* [2] */) {

  unsigned int       a_size       = 0;
  unsigned int       b_size       = 0;
  unsigned int       ap_size      = 0;
  unsigned int       bp_size      = 0;
  unsigned int       scratch_size = 0;
  int                status       = 0;
  struct wcserr**    err          = NULL;
  static const char *function     = "sip_init";

  assert(sip != NULL);
  sip_clear(sip);
  err = &(sip->err);

  /* We we have one of A/B or AP/BP, we must have both. */
  if ((a == NULL) ^ (b == NULL)) {
    return wcserr_set(
      SIP_ERRMSG(WCSERR_BAD_COORD_TRANS),
      "Both A and B SIP transform must be defined");
  }

  if ((ap == NULL) ^ (bp == NULL)) {
    return wcserr_set(
      SIP_ERRMSG(WCSERR_BAD_COORD_TRANS),
      "Both AP and BP SIP transform must be defined");
  }


  if (a != NULL) {
    sip->a_order = a_order;
    a_size = (a_order + 1) * (a_order + 1) * sizeof(double);
    sip->a = malloc(a_size);
    if (sip->a == NULL) {
      sip_free(sip);
      status = wcserr_set(
        SIP_ERRMSG(WCSERR_MEMORY), "Memory allocation failed");
      goto exit;
    }
    memcpy(sip->a, a, a_size);
    if (a_order > scratch_size) {
      scratch_size = a_order;
    }

    sip->b_order = b_order;
    b_size = (b_order + 1) * (b_order + 1) * sizeof(double);
    sip->b = malloc(b_size);
    if (sip->b == NULL) {
      sip_free(sip);
      status = wcserr_set(
        SIP_ERRMSG(WCSERR_MEMORY), "Memory allocation failed");
      goto exit;
    }
    memcpy(sip->b, b, b_size);
    if (b_order > scratch_size) {
      scratch_size = b_order;
    }
  }

  if (ap != NULL) {
    sip->ap_order = ap_order;
    ap_size = (ap_order + 1) * (ap_order + 1) * sizeof(double);
    sip->ap = malloc(ap_size);
    if (sip->ap == NULL) {
      sip_free(sip);
      status = wcserr_set(
        SIP_ERRMSG(WCSERR_MEMORY), "Memory allocation failed");
      goto exit;
    }
    memcpy(sip->ap, ap, ap_size);
    if (ap_order > scratch_size) {
      scratch_size = ap_order;
    }

    sip->bp_order = bp_order;
    bp_size = (bp_order + 1) * (bp_order + 1) * sizeof(double);
    sip->bp = malloc(bp_size);
    if (sip->bp == NULL) {
      sip_free(sip);
      status = wcserr_set(
        SIP_ERRMSG(WCSERR_MEMORY), "Memory allocation failed");
      goto exit;
    }
    memcpy(sip->bp, bp, bp_size);
    if (bp_order > scratch_size) {
      scratch_size = bp_order;
    }
  }

  scratch_size = (scratch_size + 1) * sizeof(double);
  sip->scratch = malloc(scratch_size);
  if (sip->scratch == NULL) {
    sip_free(sip);
    status = wcserr_set(
                        SIP_ERRMSG(WCSERR_MEMORY), "Memory allocation failed");
    goto exit;
  }

  sip->crpix[0] = crpix[0];
  sip->crpix[1] = crpix[1];

 exit:

  return status;
}
예제 #4
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;
}