示例#1
0
void startree_search_for(const startree_t* s, const double* xyzcenter, double radius2,
						 double** xyzresults, double** radecresults,
						 int** starinds, int* nresults) {
    kdtree_qres_t* res = NULL;
	int opts;
    double* xyz;
    int i, N;

	opts = KD_OPTIONS_SMALL_RADIUS;
	if (xyzresults || radecresults)
		opts |= KD_OPTIONS_RETURN_POINTS;

	res = kdtree_rangesearch_options(s->tree, xyzcenter, radius2, opts);
	
    if (!res || !res->nres) {
        if (xyzresults)
            *xyzresults = NULL;
        if (radecresults)
            *radecresults = NULL;
        if (starinds)
			*starinds = NULL;
        *nresults = 0;
		if (res)
			kdtree_free_query(res);
        return;
    }

    xyz = res->results.d;
    N = res->nres;
    *nresults = N;

    if (radecresults) {
        *radecresults = malloc(N * 2 * sizeof(double));
        for (i=0; i<N; i++)
            xyzarr2radecdegarr(xyz + i*3, (*radecresults) + i*2);
    }
    if (xyzresults) {
        // Steal the results array.
        *xyzresults = xyz;
        res->results.d = NULL;
    }
	if (starinds) {
		*starinds = malloc(res->nres * sizeof(int));
		for (i=0; i<N; i++)
			(*starinds)[i] = res->inds[i];
    }
    kdtree_free_query(res);
}
示例#2
0
文件: hd.c 项目: Carl4/astrometry.net
bl* henry_draper_get(hd_catalog_t* hdcat,
                     double racenter, double deccenter,
                     double r_arcsec) {
    double r2;
    double xyz[3];
    kdtree_qres_t* q;
    bl* res;
    int i;
    hd_entry_t hd;

    radecdeg2xyzarr(racenter, deccenter, xyz);
    r2 = arcsec2distsq(r_arcsec);
    q = kdtree_rangesearch(hdcat->kd, xyz, r2);
    if (!q) {
        return NULL;
    }

    res = bl_new(256, sizeof(hd_entry_t));
    for (i=0; i<q->nres; i++) {
        double* pt = q->results.d + i*3;
        xyzarr2radecdeg(pt, &(hd.ra), &(hd.dec));
        hd.hd = q->inds[i] + 1;
        bl_append(res, &hd);
    }

    kdtree_free_query(q);

    return res;
}
示例#3
0
int hpquads(startree_t* starkd,
			codefile_t* codes,
			quadfile_t* quads,
			int Nside,
			double scale_min_arcmin,
			double scale_max_arcmin,
			int dimquads,
			int passes,
			int Nreuses,
			int Nloosen,
			int id,
			anbool scanoccupied,

			void* sort_data,
			int (*sort_func)(const void*, const void*),
			int sort_size,
			
			char** args, int argc) {
	hpquads_t myhpquads;
	hpquads_t* me = &myhpquads;

	int i;
	int pass;
	anbool circle = TRUE;
	double radius2;
	il* hptotry;
	int Nhptotry = 0;
	int nquads;
	double hprad;
	double quadscale;

	int skhp, sknside;

	qfits_header* qhdr;
	qfits_header* chdr;

	int N;
	int dimcodes;
	int quadsize;
	int NHP;

	memset(me, 0, sizeof(hpquads_t));

	if (Nside > HP_MAX_INT_NSIDE) {
		ERROR("Error: maximum healpix Nside = %i", HP_MAX_INT_NSIDE);
		return -1;
	}
	if (Nreuses > 255) {
		ERROR("Error, reuse (-r) must be less than 256");
		return -1;
	}

	me->Nside = Nside;
	me->dimquads = dimquads;
	NHP = 12 * Nside * Nside;
	dimcodes = dimquad2dimcode(dimquads);
	quadsize = sizeof(unsigned int) * dimquads;

	logmsg("Nside=%i.  Nside^2=%i.  Number of healpixes=%i.  Healpix side length ~ %g arcmin.\n",
		   me->Nside, me->Nside*me->Nside, NHP, healpix_side_length_arcmin(me->Nside));

	me->sort_data = sort_data;
	me->sort_func = sort_func;
	me->sort_size = sort_size;

	tic();
	me->starkd = starkd;
	N = startree_N(me->starkd);
	logmsg("Star tree contains %i objects.\n", N);

	// get the "HEALPIX" header from the skdt...
	skhp = qfits_header_getint(startree_header(me->starkd), "HEALPIX", -1);
	if (skhp == -1) {
		if (!qfits_header_getboolean(startree_header(me->starkd), "ALLSKY", FALSE)) {
			logmsg("Warning: skdt does not contain \"HEALPIX\" header.  Code and quad files will not contain this header either.\n");
		}
	}
    // likewise "HPNSIDE"
	sknside = qfits_header_getint(startree_header(me->starkd), "HPNSIDE", 1);

    if (sknside && Nside % sknside) {
        logerr("Error: Nside (-n) must be a multiple of the star kdtree healpixelisation: %i\n", sknside);
		return -1;
    }

	if (!scanoccupied && (N*(skhp == -1 ? 1 : sknside*sknside*12) < NHP)) {
		logmsg("\n\n");
		logmsg("NOTE, your star kdtree is sparse (has only a fraction of the stars expected)\n");
		logmsg("  so you probably will get much faster results by setting the \"-E\" command-line\n");
		logmsg("  flag.\n");
		logmsg("\n\n");
	}

	quads->dimquads = me->dimquads;
	codes->dimcodes = dimcodes;
	quads->healpix = skhp;
	codes->healpix = skhp;
	quads->hpnside = sknside;
	codes->hpnside = sknside;
	if (id) {
		quads->indexid = id;
		codes->indexid = id;
	}

	qhdr = quadfile_get_header(quads);
	chdr = codefile_get_header(codes);

	add_headers(qhdr, args, argc, startree_header(me->starkd), circle, passes);
	add_headers(chdr, args, argc, startree_header(me->starkd), circle, passes);

    if (quadfile_write_header(quads)) {
        ERROR("Couldn't write headers to quad file");
		return -1;
    }
    if (codefile_write_header(codes)) {
        ERROR("Couldn't write headers to code file");
		return -1;
    }

    quads->numstars = codes->numstars = N;
	me->quad_dist2_upper = arcmin2distsq(scale_max_arcmin);
	me->quad_dist2_lower = arcmin2distsq(scale_min_arcmin);
    codes->index_scale_upper = quads->index_scale_upper = distsq2rad(me->quad_dist2_upper);
    codes->index_scale_lower = quads->index_scale_lower = distsq2rad(me->quad_dist2_lower);
	
	me->nuses = calloc(N, sizeof(unsigned char));

	// hprad = sqrt(2) * (healpix side length / 2.)
	hprad = arcmin2dist(healpix_side_length_arcmin(Nside)) * M_SQRT1_2;
	quadscale = 0.5 * sqrt(me->quad_dist2_upper);
	// 1.01 for a bit of safety.  we'll look at a few extra stars.
	radius2 = square(1.01 * (hprad + quadscale));
	me->radius2 = radius2;

	logmsg("Healpix radius %g arcsec, quad scale %g arcsec, total %g arcsec\n",
		   distsq2arcsec(hprad*hprad),
		   distsq2arcsec(quadscale*quadscale),
		   distsq2arcsec(radius2));

	hptotry = il_new(1024);

	if (scanoccupied) {
		logmsg("Scanning %i input stars...\n", N);
		for (i=0; i<N; i++) {
			double xyz[3];
			int j;
			if (startree_get(me->starkd, i, xyz)) {
				ERROR("Failed to get star %i", i);
				return -1;
			}
			j = xyzarrtohealpix(xyz, Nside);
			il_insert_unique_ascending(hptotry, j);
			if (log_get_level() > LOG_VERB) {
				double ra,dec;
				if (startree_get_radec(me->starkd, i, &ra, &dec)) {
					ERROR("Failed to get RA,Dec for star %i\n", i);
					return -1;
				}
				logdebug("star %i: RA,Dec %g,%g; xyz %g,%g,%g; hp %i\n",
						 i, ra, dec, xyz[0], xyz[1], xyz[2], j);
			}
		}
		logmsg("Will check %zu healpixes.\n", il_size(hptotry));
		if (log_get_level() > LOG_VERB) {
			logdebug("Checking healpixes: [ ");
			for (i=0; i<il_size(hptotry); i++)
				logdebug("%i ", il_get(hptotry, i));
			logdebug("]\n");
		}

	} else {
		if (skhp == -1) {
			// Try all healpixes.
			il_free(hptotry);
			hptotry = NULL;
			Nhptotry = NHP;
		} else {
			// The star kdtree may itself be healpixed
			int starhp, starx, stary;
			// In that case, the healpixes we are interested in form a rectangle
			// within a big healpix.  These are the coords (in [0, Nside)) of
			// that rectangle.
			int x0, x1, y0, y1;
			int x, y;

			healpix_decompose_xy(skhp, &starhp, &starx, &stary, sknside);
			x0 =  starx    * (Nside / sknside);
			x1 = (starx+1) * (Nside / sknside);
			y0 =  stary    * (Nside / sknside);
			y1 = (stary+1) * (Nside / sknside);

			for (y=y0; y<y1; y++) {
				for (x=x0; x<x1; x++) {
					int j = healpix_compose_xy(starhp, x, y, Nside);
					il_append(hptotry, j);
				}
			}
			assert(il_size(hptotry) == (Nside/sknside) * (Nside/sknside));
		}
	}
	if (hptotry)
		Nhptotry = il_size(hptotry);

	me->quadlist = bl_new(65536, quadsize);

	if (Nloosen)
		me->retryhps = il_new(1024);

	for (pass=0; pass<passes; pass++) {
		char key[64];
		int nthispass;

		logmsg("Pass %i of %i.\n", pass+1, passes);
		logmsg("Trying %i healpixes.\n", Nhptotry);

		nthispass = build_quads(me, Nhptotry, hptotry, Nreuses);

		logmsg("Made %i quads (out of %i healpixes) this pass.\n", nthispass, Nhptotry);
		logmsg("Made %i quads so far.\n", (me->bigquadlist ? bt_size(me->bigquadlist) : 0) + (int)bl_size(me->quadlist));

		sprintf(key, "PASS%i", pass+1);
		fits_header_mod_int(chdr, key, nthispass, "quads created in this pass");
		fits_header_mod_int(qhdr, key, nthispass, "quads created in this pass");

		logmsg("Merging quads...\n");
		if (!me->bigquadlist)
			me->bigquadlist = bt_new(quadsize, 256);
		for (i=0; i<bl_size(me->quadlist); i++) {
			void* q = bl_access(me->quadlist, i);
			bt_insert2(me->bigquadlist, q, FALSE, compare_quads, &me->dimquads);
		}
		bl_remove_all(me->quadlist);
	}

	il_free(hptotry);
	hptotry = NULL;

	if (Nloosen) {
		int R;
		for (R=Nreuses+1; R<=Nloosen; R++) {
			il* trylist;
			int nthispass;

			logmsg("Loosening reuse maximum to %i...\n", R);
			logmsg("Trying %zu healpixes.\n", il_size(me->retryhps));
			if (!il_size(me->retryhps))
				break;

			trylist = me->retryhps;
			me->retryhps = il_new(1024);
			nthispass = build_quads(me, il_size(trylist), trylist, R);
			logmsg("Made %i quads (out of %zu healpixes) this pass.\n", nthispass, il_size(trylist));
			il_free(trylist);
			for (i=0; i<bl_size(me->quadlist); i++) {
				void* q = bl_access(me->quadlist, i);
				bt_insert2(me->bigquadlist, q, FALSE, compare_quads, &me->dimquads);
			}
			bl_remove_all(me->quadlist);
		}
	}
	if (me->retryhps)
		il_free(me->retryhps);

	kdtree_free_query(me->res);
	me->res = NULL;
	me->inds = NULL;
	me->stars = NULL;
	free(me->nuses);
	me->nuses = NULL;

	logmsg("Writing quads...\n");

	// add the quads from the big-quadlist
	nquads = bt_size(me->bigquadlist);
	for (i=0; i<nquads; i++) {
		unsigned int* q = bt_access(me->bigquadlist, i);
		quad_write(codes, quads, q, me->starkd, me->dimquads, dimcodes);
	}
	// add the quads that were made during the final round.
	for (i=0; i<bl_size(me->quadlist); i++) {
		unsigned int* q = bl_access(me->quadlist, i);
		quad_write(codes, quads, q, me->starkd, me->dimquads, dimcodes);
	}

	// fix output file headers.
	if (quadfile_fix_header(quads)) {
		ERROR("Failed to fix quadfile headers");
		return -1;
	}
	if (codefile_fix_header(codes)) {
		ERROR("Failed to fix codefile headers");
		return -1;
	}

	bl_free(me->quadlist);
	bt_free(me->bigquadlist);

	toc();
	logmsg("Done.\n");
	return 0;
}
示例#4
0
void verify_get_all_matches(const double* refxys, int NR,
							const double* testxys, const double* testsigma2s, int NT,
							double effective_area,
							double distractors,
							double nsigma,
							double limit,
							il*** p_reflist,
							dl*** p_problist) {
	double* refcopy;
	kdtree_t* rtree;
	int Nleaf = 10;
	int i,j;
	double logd;
	double logbg;
	double loglimit;

	il** reflist;
	dl** problist;

	reflist  = calloc(NT, sizeof(il*));
	problist = calloc(NT, sizeof(dl*));

	// Build a tree out of the index stars in pixel space...
	// kdtree scrambles the data array so make a copy first.
	refcopy = malloc(2 * NR * sizeof(double));
	memcpy(refcopy, refxys, 2 * NR * sizeof(double));
	rtree = kdtree_build(NULL, refcopy, NR, 2, Nleaf, KDTT_DOUBLE, KD_BUILD_SPLIT);

	logbg = log(1.0 / effective_area);
	logd  = log(distractors / effective_area);
	loglimit = log(distractors / effective_area * limit);

	for (i=0; i<NT; i++) {
		const double* testxy;
		double sig2;
		kdtree_qres_t* res;

		testxy = testxys + 2*i;
		sig2 = testsigma2s[i];

		logverb("\n");
		logverb("test star %i: (%.1f,%.1f), sigma: %.1f\n", i, testxy[0], testxy[1], sqrt(sig2));

		// find all ref stars within nsigma.
		res = kdtree_rangesearch_options(rtree, testxy, sig2*nsigma*nsigma,
										 KD_OPTIONS_SORT_DISTS | KD_OPTIONS_SMALL_RADIUS);

		if (res->nres == 0) {
			kdtree_free_query(res);
			continue;
		}

		reflist[i] = il_new(4);
		problist[i] = dl_new(4);

		for (j=0; j<res->nres; j++) {
			double d2;
			int refi;
			double loggmax, logfg;

			d2 = res->sdists[j];
			refi = res->inds[j];

			// peak value of the Gaussian
			loggmax = log((1.0 - distractors) / (2.0 * M_PI * sig2 * NR));
			// value of the Gaussian
			logfg = loggmax - d2 / (2.0 * sig2);

			if (logfg < loglimit)
				continue;

			logverb("  ref star %i, dist %.2f, sigmas: %.3f, logfg: %.1f (%.1f above distractor, %.1f above bg, %.1f above keep-limit)\n",
					refi, sqrt(d2), sqrt(d2 / sig2), logfg, logfg - logd, logfg - logbg, logfg - loglimit);

			il_append(reflist[i], refi);
			dl_append(problist[i], logfg);
		}

		kdtree_free_query(res);
	}
	kdtree_free(rtree);
	free(refcopy);

	*p_reflist  = reflist;
	*p_problist = problist;
}
示例#5
0
static PyObject* spherematch_kdtree_rangesearch(PyObject* self,
                                                PyObject* args) {
    double* X;
    PyObject* rtn;
    npy_intp dims[1];
    long i;
    kdtree_t* kd;
    int D, N;
    PyObject* pyO;
    PyObject* pyI;
    PyObject* pyInds;
    PyObject* pyDists = NULL;
    PyArray_Descr* dtype = PyArray_DescrFromType(NPY_DOUBLE);
    int req = NPY_C_CONTIGUOUS | NPY_ALIGNED | NPY_NOTSWAPPED
        | NPY_ELEMENTSTRIDES;
    double radius;
    kdtree_qres_t* res;
    int getdists, sortdists;
    int opts;

    if (!PyArg_ParseTuple(args, "lOdii", &i, &pyO, &radius,
                          &getdists, &sortdists)) {
        PyErr_SetString(PyExc_ValueError, "need five args: kdtree identifier (int), query point (numpy array of floats), radius (double), get distances (int 0/1), sort distances (int 0/1)");
        return NULL;
    }
    // Nasty!
    kd = (kdtree_t*)i;
    D = kd->ndim;

    if (sortdists) {
        getdists = 1;
    }

    Py_INCREF(dtype);
    pyI = PyArray_FromAny(pyO, dtype, 1, 1, req, NULL);
    if (!pyI) {
        PyErr_SetString(PyExc_ValueError, "Failed to convert query point array to np array of float");
        Py_XDECREF(dtype);
        return NULL;
    }
    N = (int)PyArray_DIM(pyI, 0);
    if (N != D) {
        PyErr_SetString(PyExc_ValueError, "Query point must have size == dimension of tree");
        Py_DECREF(pyI);
        Py_DECREF(dtype);
        return NULL;
    }

    X = PyArray_DATA(pyI);

    opts = 0;
    if (getdists) {
        opts |= KD_OPTIONS_COMPUTE_DISTS;
    }
    if (sortdists) {
        opts |= KD_OPTIONS_SORT_DISTS;
    }

    res = kdtree_rangesearch_options(kd, X, radius*radius, opts);
    N = res->nres;
    dims[0] = N;
    res->inds = realloc(res->inds, N * sizeof(uint32_t));
    pyInds = PyArray_SimpleNewFromData(1, dims, NPY_UINT32, res->inds);
    res->inds = NULL;

    if (getdists) {
        res->sdists = realloc(res->sdists, N * sizeof(double));
        pyDists = PyArray_SimpleNewFromData(1, dims, NPY_DOUBLE, res->sdists);
        res->sdists = NULL;
    }

    kdtree_free_query(res);

    Py_DECREF(pyI);
    Py_DECREF(dtype);
    if (getdists) {
        rtn = Py_BuildValue("(OO)", pyInds, pyDists);
        Py_DECREF(pyDists);
    } else {
        rtn = Py_BuildValue("O", pyInds);
    }
    Py_DECREF(pyInds);
    return rtn;
}