コード例 #1
0
int MANGLE(kdtree_dualtree_rangesearch)(kdtree_t* kd1, kdtree_t* kd2,
										double maxdist,
										rangesearch_callback callback, void* baton) {
	int xnode, ynode;
	il* nodes;
	il* leaves;

	if (kdtree_treetype(kd1) != kdtree_treetype(kd2)) {
		ERROR("Trees must be the same type.");
		return -1;
	}

	if (!kd1->split.any || !kd2->split.any) {
		ERROR("This function only supports splitting-plane trees.\n");
		return -1;
	}

	nodes = il_new(256);
	leaves = il_new(256);
	// root nodes.
	xnode = ynode = 0;
	if (KD_IS_LEAF(xtree, xnode))
		il_append(leaves, xnode);
	else
		il_append(nodes, xnode);

	dualtree_recurse(xtree, ytree, nodes, leaves, ynode, callbacks);

	il_free(nodes);
	il_free(leaves);
	return 0;
}
コード例 #2
0
int parse_depth_string(il* depths, const char* str) {
    unsigned int lasthi = 0;
    unsigned int lo, hi;

    while (str && *str) {
        int nread;
        char div[2];
        lo = 0;
        hi = 0;
        // 10-20
        if (sscanf(str, "%u-%u", &lo, &hi) == 2) {
            sscanf(str, "%*u-%*u%n", &nread);
            if (lo > hi) {
                logerr("Depth range %i to %i is invalid: max must be >= min!\n", lo, hi);
                return -1;
            }
            if (lo == 0) {
                logerr("Depth lower limit %i is invalid: depths must be >= 1.\n", lo);
                return -1;
            }
            // 30-
        } else if (sscanf(str, "%u%1[-]", &lo, div) == 2) {
            sscanf(str, "%*u%*1[-]%n", &nread);
            if (lo == 0) {
                logerr("Depth lower limit %i is invalid: depths must be >= 1.\n", lo);
                return -1;
            }
            // -100
        } else if (sscanf(str, "-%u", &hi) == 1) {
            sscanf(str, "-%*u%n", &nread);
            if (hi == 0) {
                logerr("Depth upper limit %i is invalid: depths must be >= 1.\n", hi);
                return -1;
            }
            lo = 1;
            // 7
        } else if (sscanf(str, "%u", &hi) == 1) {
            sscanf(str, "%*u%n", &nread);
            if (hi == 0) {
                logerr("Depth %i is invalid: depths must be >= 1.\n", hi);
                return -1;
            }
            lo = lasthi + 1;

        } else {
            logerr("Failed to parse depth range: \"%s\"\n", str);
            return -1;
        }

        il_append(depths, lo);
        il_append(depths, hi);
        lasthi = hi;
        str += nread;
        while ((*str == ',') || isspace((unsigned)(*str)))
            str++;
    }
    return 0;
}
コード例 #3
0
ファイル: test_bl.c プロジェクト: Carl4/astrometry.net
void test_il_sorted(CuTest* tc) {
	int vals[] = {34951,34950,34949,35049,35149,29951,29950,29949,34999,34998,5099,5199,39849,39949,4999,35249,29952,34952,5299,35349,29953,34953,5399,35449,29954,34954,5499,35549,29955,34955,5599,35649,29956,34956,5699,35749,29957,34957,5799,35849,29958,34958,5899,35949,29959,34959,5999,36049,29960,34960,6099,36149,29961,34961,6199,36249,29962,34962,6299,36349,29963,34963,6399,36449,29964,34964,6499,36549,29965,34965,6599,36649,29966,34966,6699,36749,29967,34967,6799,36849,29968,34968,6899,36949,29969,34969,6999,37049,29970,34970,7099,37149,29971,34971,7199,37249,29972,34972,7299,37349,29973,34973,7399,37449,29974,34974,7499,37549,29975,34975,7599,37649,29976,34976,7699,37749,29977,34977,7799,37849,29978,34978,7899,37949,29979,34979,7999,38049,29980,34980,8099,38149,29981,34981,8199,38249,29982,34982,8299,38349,29983,34983,8399,38449,29984,34984,8499,38549,29985,34985,8599,38649,29986,34986,8699,38749,29987,34987,8799,38849,29988,34988,8899,38949,29989,34989,8999,39049,29990,34990,9099,39149,29991,34991,9199,39249,29992,34992,9299,39349,29993,34993,9399,39449,29994,34994,9499,39549,29995,34995,9599,39649,29996,34996,9699,39749,29997,34997,9799,29998,9899,29999,9999};
	int i, N;
	il* lst;
	N = sizeof(vals)/sizeof(int);
	lst = il_new(256);
	for (i=0; i<N; i++)
		il_append(lst, vals[i]);
	CuAssertIntEquals(tc, N, il_size(lst));
	for (i=0; i<N; i++)
		CuAssertIntEquals(tc, vals[i], il_get(lst, i));

	printf("Before sorting:\n");
	il_print(lst);

	il_sort(lst, TRUE);

	printf("After sorting:\n");
	il_print(lst);

	CuAssertIntEquals(tc, 0, il_check_consistency(lst));
	CuAssertIntEquals(tc, 0, il_check_sorted_ascending(lst, TRUE));
	for (i=1; i<N; i++)
		CuAssertTrue(tc, il_get(lst, i-1) < il_get(lst, i));
	for (i=0; i<N; i++)
		CuAssertIntEquals(tc, 1, il_sorted_contains(lst, vals[i]));
}
コード例 #4
0
il* constellations_get_lines(int c) {
    il* list;
    const int* lines;
    int i;
    check_const_num(c);
    list = il_new(16);
    lines = constellation_lines[c];
    for (i=0; i<2*constellation_nlines[c]; i++) {
        il_append(list, lines[i]);
    }
    return list;
}
コード例 #5
0
ファイル: solvedclient.c プロジェクト: Carl4/astrometry.net
il* solvedclient_get_fields(int filenum, int firstfield, int lastfield,
							int maxnfields) {
	char* buf;
	int bufsize;
	il* list;
	char* cptr;
	int fld;
	int nchars;

	if (connect_to_server())
		return NULL;
	bufsize = 100 + 10 * (maxnfields ? maxnfields : (1 + lastfield - firstfield));
	buf = malloc(bufsize);
	nchars = sprintf(buf, "getall %i %i %i %i\n", filenum, firstfield,
					 lastfield, maxnfields);
	if ((fwrite(buf, 1, nchars, fserver) != nchars) ||
		fflush(fserver)) {
		fprintf(stderr, "Failed to send command (%s) to solvedserver: %s\n", buf, strerror(errno));
		return NULL;
	}
	// wait for response.
	if (!fgets(buf, bufsize, fserver)) {
		fprintf(stderr, "Couldn't read response: %s\n", strerror(errno));
		fclose(fserver);
		fserver = NULL;
		free(buf);
		return NULL;
	}
	if (sscanf(buf, "unsolved %i%n", &fld, &nchars) != 1) {
		fprintf(stderr, "Couldn't parse response: %s\n", buf);
		free(buf);
		return NULL;
	}
	if (fld != filenum) {
		fprintf(stderr, "Expected file number %i, not %i.\n", filenum, fld);
		free(buf);
		return NULL;
	}
	cptr = buf + nchars;
	list = il_new(256);
	while (*cptr && *cptr != '\n') {
		if (sscanf(cptr, " %i%n", &fld, &nchars) != 1) {
			fprintf(stderr, "Couldn't parse response: %s\n", buf);
			il_free(list);
			free(buf);
			return NULL;
		}
		cptr += nchars;
		il_append(list, fld);
	}
	free(buf);
	return list;
}
コード例 #6
0
ファイル: agreeable.c プロジェクト: Carl4/astrometry.net
static void write_field(bl* agreeing,
						bl* leftover,
						int fieldfile,
						int fieldnum) {
	int i;

	if (!bl_size(agreeing))
		il_append(unsolved, fieldnum);
	else {
		il_append(solved, fieldnum);
		if (solvedserver)
			solvedclient_set(fieldfile, fieldnum);
		if (solvedfile) {
			char fn[256];
			sprintf(fn, solvedfile, fieldfile);
			solvedfile_set(fn, fieldnum);
		}
	}

	for (i=0; agreeing && i<bl_size(agreeing); i++) {
		MatchObj* mo = bl_access(agreeing, i);
		if (matchfile_write_match(agreemf, mo))
			fprintf(stderr, "Error writing an agreeing match.");
		fprintf(stderr, "Field %i: Logodds %g (%g)\n", fieldnum, mo->logodds, exp(mo->logodds));
	}

	if (leftover && bl_size(leftover)) {
		fprintf(stderr, "Field %i: writing %i leftovers...\n", fieldnum,
				bl_size(leftover));
		for (i=0; i<bl_size(leftover); i++) {
			MatchObj* mo = bl_access(leftover, i);
			if (matchfile_write_match(leftovermf, mo))
				fprintf(stderr, "Error writing a leftover match.");
		}
	}
}
コード例 #7
0
ファイル: test_bl.c プロジェクト: Carl4/astrometry.net
void test_il_remove_index_range_1(CuTest* tc) {
	il* lst = il_new(4);
	il_append(lst, 0);
	il_append(lst, 1);
	il_append(lst, 2);
	il_append(lst, 3);
	il_append(lst, 4);
	il_append(lst, 5);
	il_remove_index_range(lst, 2, 2);
	// [0 1 2 3 4 5] -> [0 1 4 5]
	CuAssertIntEquals(tc, 4, il_size(lst));
	CuAssertIntEquals(tc, 4, il_get(lst, 2));
}
コード例 #8
0
ファイル: starkd.c プロジェクト: Carl4/astrometry.net
static bl* get_chunks(startree_t* s, il* wordsizes) {
    bl* chunks = bl_new(4, sizeof(fitsbin_chunk_t));
    fitsbin_chunk_t chunk;
    kdtree_t* kd = s->tree;

    fitsbin_chunk_init(&chunk);
    chunk.tablename = "sweep";
	chunk.forced_type = fitscolumn_u8_type();
    chunk.itemsize = sizeof(uint8_t);
    chunk.nrows = kd->ndata;
    chunk.data = s->sweep;
    chunk.userdata = &(s->sweep);
    chunk.required = FALSE;
    bl_append(chunks, &chunk);
    if (wordsizes)
        il_append(wordsizes, sizeof(uint8_t));

    fitsbin_chunk_clean(&chunk);
    return chunks;
}
コード例 #9
0
static int build_quads(hpquads_t* me, int Nhptotry, il* hptotry, int R) {
	int nthispass = 0;
	int lastgrass = 0;
	int i;

	for (i=0; i<Nhptotry; i++) {
		anbool ok;
		int hp;
		if ((i * 80 / Nhptotry) != lastgrass) {
			printf(".");
			fflush(stdout);
			lastgrass = i * 80 / Nhptotry;
		}
		if (hptotry)
			hp = il_get(hptotry, i);
		else
			hp = i;
		me->hp = hp;
		me->quad_created = FALSE;
		ok = find_stars(me, me->radius2, R);
		if (ok)
			create_quad(me, TRUE);

		if (me->quad_created)
			nthispass++;
		else {
			if (R && me->Nstars && me->retryhps)
				// there were some stars, and we're counting how many times stars are used.
				//il_insert_unique_ascending(me->retryhps, hp);
				// we don't mind hps showing up multiple times because we want to make up for the lost
				// passes during loosening...
				il_append(me->retryhps, hp);
			// FIXME -- could also track which hps are worth visiting in a future pass
		}
	}
	printf("\n");
	return nthispass;
}
コード例 #10
0
ファイル: practice_problems.c プロジェクト: gaibo/C
// okay just make a bfs and then add in like an extra counter
// that counts number of things added to list and then short circuit
il* limited_bfs(graph *g, unsigned int start_key, unsigned int max_steps) {
    // check for errors
    if (start_key>=g->n_vertices) {
        fprintf(stderr,"bfs: no such vertex (%u)\n",start_key);
        exit(1);
    }
    
    il *prev_reached, *reached;
    reached = NULL;
    iq *q = iq_new();
    int curr;
    int list_elements = 0;
    enqueue(q, start_key);
    
    while (q->n > 0) {
        curr = dequeue(q);
        if (g->vs[curr]->done)
            continue;
        g->vs[curr]->done = 1;
        prev_reached = reached;
        reached = il_append(prev_reached,il_singleton(curr));
        il_free(prev_reached);
        list_elements++;
        if (list_elements >= max_steps) {
            iq_free(q);
            return reached;
        }
        il *neighbors = g->es[curr];
        while (neighbors != NULL) {
            int n = neighbors->n;
            enqueue(q,n);
            neighbors = neighbors->next;
        }
    }
    iq_free(q);
    return reached;
}
コード例 #11
0
int main(int argc, char** args) {
    int c;
    char* wcsfn = NULL;
    char* outfn = NULL;
    char* infn = NULL;
    sip_t sip;
    double scale = 1.0;
    anbool pngformat = TRUE;

    char* hdpath = NULL;
    anbool HD = FALSE;

    cairos_t thecairos;
    cairos_t* cairos = &thecairos;

    cairo_surface_t* target = NULL;
    cairo_t* cairot = NULL;

    cairo_surface_t* surfbg = NULL;
    cairo_t* cairobg = NULL;

    cairo_surface_t* surfshapes = NULL;
    cairo_t* cairoshapes = NULL;

    cairo_surface_t* surfshapesmask = NULL;
    cairo_t* cairoshapesmask = NULL;

    cairo_surface_t* surffg = NULL;
    cairo_t* cairo = NULL;

    double lw = 2.0;
    // circle linewidth.
    double cw = 2.0;

    double ngc_fraction = 0.02;

    // NGC linewidth
    double nw = 2.0;

    // leave a gap short of connecting the points.
    double endgap = 5.0;
    // circle radius.
    double crad = endgap;

    double fontsize = 14.0;

    double label_offset = 15.0;

    int W = 0, H = 0;
    unsigned char* img = NULL;

    anbool NGC = FALSE, constell = FALSE;
    anbool bright = FALSE;
    anbool common_only = FALSE;
    anbool print_common_only = FALSE;
    int Nbright = 0;
    double ra, dec, px, py;
    int i, N;
    anbool justlist = FALSE;
    anbool only_messier = FALSE;

    anbool grid = FALSE;
    double gridspacing = 0.0;
    double gridcolor[3] = { 0.2, 0.2, 0.2 };

    int loglvl = LOG_MSG;

	char halign = 'L';
	char valign = 'C';
    sl* json = NULL;

    anbool whitetext = FALSE;

    while ((c = getopt(argc, args, OPTIONS)) != -1) {
        switch (c) {
		case 'V':
			valign = optarg[0];
			break;
		case 'O':
			halign = optarg[0];
			break;
        case 'F':
            ngc_fraction = atof(optarg);
            break;
        case 'h':
            print_help(args[0]);
            exit(0);
        case 'J':
            json = sl_new(4);
            break;
        case 'G':
            gridspacing = atof(optarg);
            break;
        case 'g':
            {
            char *tail = NULL;
            gridcolor[0] = strtod(optarg,&tail);
            if (*tail) { tail++; gridcolor[1] = strtod(tail,&tail); }
            if (*tail) { tail++; gridcolor[2] = strtod(tail,&tail); }
            }
            break;
        case 'D':
            HD = TRUE;
            break;
        case 'd':
            hdpath = optarg;
            break;
        case 'M':
            only_messier = TRUE;
            break;
        case 'n':
            nw = atof(optarg);
            break;
        case 'f':
            fontsize = atof(optarg);
            break;
        case 'L':
            justlist = TRUE;
            outfn = NULL;
            break;
        case 'x':
        	whitetext = TRUE;
        	break;
        case 'v':
            loglvl++;
            break;
            break;
        case 'j':
            print_common_only = TRUE;
            break;
        case 'c':
            common_only = TRUE;
            break;
        case 'b':
            Nbright = atoi(optarg);
            break;
        case 'B':
            bright = TRUE;
            break;
        case 'N':
            NGC = TRUE;
            break;
        case 'C':
            constell = TRUE;
            break;
        case 'p':
            pngformat = FALSE;
            break;
        case 's':
            scale = atof(optarg);
            break;
        case 'o':
            outfn = optarg;
            break;
        case 'i':
            infn = optarg;
            break;
        case 'w':
            wcsfn = optarg;
            break;
        case 'W':
            W = atoi(optarg);
            break;
        case 'H':
            H = atoi(optarg);
            break;
        }
    }

    log_init(loglvl);
    log_to(stderr);
    fits_use_error_system();

    if (optind != argc) {
        print_help(args[0]);
        exit(-1);
    }

    if (!(outfn || justlist) || !wcsfn) {
        logerr("Need (-o or -L) and -w args.\n");
        print_help(args[0]);
        exit(-1);
    }

    // read WCS.
    logverb("Trying to parse SIP/TAN header from %s...\n", wcsfn);
    if (!file_exists(wcsfn)) {
        ERROR("No such file: \"%s\"", wcsfn);
        exit(-1);
    }
    if (sip_read_header_file(wcsfn, &sip)) {
        logverb("Got SIP header.\n");
    } else {
        ERROR("Failed to parse SIP/TAN header from %s", wcsfn);
        exit(-1);
    }

    if (!(NGC || constell || bright || HD || grid)) {
        logerr("Neither constellations, bright stars, HD nor NGC/IC overlays selected!\n");
        print_help(args[0]);
        exit(-1);
    }

    if (gridspacing > 0.0)
        grid = TRUE;

    // adjust for scaling...
    lw /= scale;
    cw /= scale;
    nw /= scale;
    crad /= scale;
    endgap /= scale;
    fontsize /= scale;
    label_offset /= scale;

    if (!W || !H) {
        W = sip.wcstan.imagew;
        H = sip.wcstan.imageh;
    }
    if (!(infn || (W && H))) {
        logerr("Image width/height unspecified, and no input image given.\n");
        exit(-1);
    }


    if (infn) {
		cairoutils_fake_ppm_init();
        img = cairoutils_read_ppm(infn, &W, &H);
        if (!img) {
            ERROR("Failed to read input image %s", infn);
            exit(-1);
        }
        cairoutils_rgba_to_argb32(img, W, H);
    } else if (!justlist) {
        // Allocate a black image.
        img = calloc(4 * W * H, 1);
        if (!img) {
            SYSERROR("Failed to allocate a blank image on which to plot!");
            exit(-1);
        }
    }

    if (HD && !hdpath) {
        logerr("If you specify -D (plot Henry Draper objs), you also have to give -d (path to Henry Draper catalog)\n");
        exit(-1);
    }

    if (!justlist) {
        /*
         Cairo layers:

         -background: surfbg / cairobg
         --> gets drawn first, in black, masked by surfshapesmask

         -shapes: surfshapes / cairoshapes
         --> gets drawn second, masked by surfshapesmask

         -foreground/text: surffg / cairo
         --> gets drawn last.
         */
        surffg = cairo_image_surface_create(CAIRO_FORMAT_ARGB32, W, H);
        cairo = cairo_create(surffg);
        cairo_set_line_join(cairo, CAIRO_LINE_JOIN_BEVEL);
        cairo_set_antialias(cairo, CAIRO_ANTIALIAS_GRAY);
        cairo_set_source_rgba(cairo, 1.0, 1.0, 1.0, 1.0);
        cairo_scale(cairo, scale, scale);
        //cairo_select_font_face(cairo, "helvetica", CAIRO_FONT_SLANT_NORMAL, CAIRO_FONT_WEIGHT_BOLD);
        cairo_select_font_face(cairo, "DejaVu Sans Mono Book", CAIRO_FONT_SLANT_NORMAL, CAIRO_FONT_WEIGHT_BOLD);
        cairo_set_font_size(cairo, fontsize);

        surfshapes = cairo_image_surface_create(CAIRO_FORMAT_ARGB32, W, H);
        cairoshapes = cairo_create(surfshapes);
        cairo_set_line_join(cairoshapes, CAIRO_LINE_JOIN_BEVEL);
        cairo_set_antialias(cairoshapes, CAIRO_ANTIALIAS_GRAY);
        cairo_set_source_rgba(cairoshapes, 1.0, 1.0, 1.0, 1.0);
        cairo_scale(cairoshapes, scale, scale);
        cairo_select_font_face(cairoshapes, "DejaVu Sans Mono Book", CAIRO_FONT_SLANT_NORMAL, CAIRO_FONT_WEIGHT_BOLD);
        cairo_set_font_size(cairoshapes, fontsize);

        surfshapesmask = cairo_image_surface_create(CAIRO_FORMAT_A8, W, H);
        cairoshapesmask = cairo_create(surfshapesmask);
        cairo_set_line_join(cairoshapesmask, CAIRO_LINE_JOIN_BEVEL);
        cairo_set_antialias(cairoshapesmask, CAIRO_ANTIALIAS_GRAY);
        cairo_set_source_rgba(cairoshapesmask, 1.0, 1.0, 1.0, 1.0);
        cairo_scale(cairoshapesmask, scale, scale);
        cairo_select_font_face(cairoshapesmask, "DejaVu Sans Mono Book", CAIRO_FONT_SLANT_NORMAL, CAIRO_FONT_WEIGHT_BOLD);
        cairo_set_font_size(cairoshapesmask, fontsize);
        cairo_paint(cairoshapesmask);
        cairo_stroke(cairoshapesmask);

        surfbg = cairo_image_surface_create(CAIRO_FORMAT_A8, W, H);
        cairobg = cairo_create(surfbg);
        cairo_set_line_join(cairobg, CAIRO_LINE_JOIN_BEVEL);
        cairo_set_antialias(cairobg, CAIRO_ANTIALIAS_GRAY);
        cairo_set_source_rgba(cairobg, 0, 0, 0, 1);
        cairo_scale(cairobg, scale, scale);
        cairo_select_font_face(cairobg, "DejaVu Sans Mono Book", CAIRO_FONT_SLANT_NORMAL, CAIRO_FONT_WEIGHT_BOLD);
        cairo_set_font_size(cairobg, fontsize);

        cairos->bg = cairobg;
        cairos->fg = cairo;
        cairos->shapes = cairoshapes;
        cairos->shapesmask = cairoshapesmask;
        cairos->imgW = (float)W/scale;
        cairos->imgH = (float)H/scale;
//    }

    if (grid) {
        double ramin, ramax, decmin, decmax;
        double ra, dec;
        double rastep = gridspacing / 60.0;
        double decstep = gridspacing / 60.0;
        // how many line segments
        int N = 10;
        double px, py;
        int i;

        cairo_set_source_rgba(cairo, gridcolor[0], gridcolor[1], gridcolor[2], 1.0);

        sip_get_radec_bounds(&sip, 100, &ramin, &ramax, &decmin, &decmax);
		logverb("Plotting grid lines from RA=%g to %g in steps of %g; Dec=%g to %g in steps of %g\n",
				ramin, ramax, rastep, decmin, decmax, decstep);
        for (dec = decstep * floor(decmin / decstep); dec<=decmax; dec+=decstep) {
			logverb("  dec=%g\n", dec);
            for (i=0; i<=N; i++) {
                ra = ramin + ((double)i / (double)N) * (ramax - ramin);
                if (!sip_radec2pixelxy(&sip, ra, dec, &px, &py))
                    continue;
                // first time, move_to; else line_to
                ((ra == ramin) ? cairo_move_to : cairo_line_to)(cairo, px, py);
            }
            cairo_stroke(cairo);
        }
        for (ra = rastep * floor(ramin / rastep); ra <= ramax; ra += rastep) {
            //for (dec=decmin; dec<=decmax; dec += (decmax - decmin)/(double)N) {
			logverb("  ra=%g\n", ra);
            for (i=0; i<=N; i++) {
                dec = decmin + ((double)i / (double)N) * (decmax - decmin);
                if (!sip_radec2pixelxy(&sip, ra, dec, &px, &py))
                    continue;
                // first time, move_to; else line_to
                ((dec == decmin) ? cairo_move_to : cairo_line_to)(cairo, px, py);
            }
            cairo_stroke(cairo);
        }

        cairo_set_source_rgba(cairo, 1.0, 1.0, 1.0, 1.0);
    }
  }

    if (constell) {
        N = constellations_n();

        logverb("Checking %i constellations.\n", N);
        for (c=0; c<N; c++) {
            const char* shortname = NULL;
            const char* longname;
            il* lines;
            il* uniqstars;
            il* inboundstars;
            float r,g,b;
            int Ninbounds;
            int Nunique;
            cairo_text_extents_t textents;
            double cmass[3];

            uniqstars = constellations_get_unique_stars(c);
            inboundstars = il_new(16);

            Nunique = il_size(uniqstars);
            debug("%s: %zu unique stars.\n", shortname, il_size(uniqstars));

            // Count the number of unique stars belonging to this contellation
            // that are within the image bounds
            Ninbounds = 0;
            for (i=0; i<il_size(uniqstars); i++) {
                int star;
                star = il_get(uniqstars, i);
                constellations_get_star_radec(star, &ra, &dec);
                debug("star %i: ra,dec (%g,%g)\n", il_get(uniqstars, i), ra, dec);
                if (!sip_radec2pixelxy(&sip, ra, dec, &px, &py))
                    continue;
                if (px < 0 || py < 0 || px*scale > W || py*scale > H)
                    continue;
                Ninbounds++;
                il_append(inboundstars, star);
            }
            il_free(uniqstars);
            debug("%i are in-bounds.\n", Ninbounds);
            // Only draw this constellation if at least 2 of its stars
            // are within the image bounds.
            if (Ninbounds < 2) {
                il_free(inboundstars);
                continue;
            }

            // Set the color based on the location of the first in-bounds star.
            // This is a hack -- we have two different constellation
            // definitions with different numbering schemes!
            if (!justlist && (il_size(inboundstars) > 0)) {
                // This is helpful for videos: ensuring that the same
                // color is chosen for a constellation in each frame.
                int star = il_get(inboundstars, 0);
                constellations_get_star_radec(star, &ra, &dec);
                if (whitetext) {
                	r = g = b = 1;
                } else {
                	color_for_radec(ra, dec, &r, &g, &b);
                }
                cairo_set_source_rgba(cairoshapes, r,g,b,0.8);
                cairo_set_line_width(cairoshapes, cw);
                cairo_set_source_rgba(cairo, r,g,b,0.8);
                cairo_set_line_width(cairo, cw);
            }

            // Draw circles around each star.
            // Find center of mass (of the in-bounds stars)
            cmass[0] = cmass[1] = cmass[2] = 0.0;
            for (i=0; i<il_size(inboundstars); i++) {
                double xyz[3];
                int star = il_get(inboundstars, i);
                constellations_get_star_radec(star, &ra, &dec);
                if (!sip_radec2pixelxy(&sip, ra, dec, &px, &py))
                    continue;
                if (px < 0 || py < 0 || px*scale > W || py*scale > H)
                    continue;
                if (!justlist) {
                    cairo_arc(cairobg, px, py, crad+1.0, 0.0, 2.0*M_PI);
                    cairo_stroke(cairobg);
                    cairo_arc(cairoshapes, px, py, crad, 0.0, 2.0*M_PI);
                    cairo_stroke(cairoshapes);
                }
                radecdeg2xyzarr(ra, dec, xyz);
                cmass[0] += xyz[0];
                cmass[1] += xyz[1];
                cmass[2] += xyz[2];
            }
            cmass[0] /= il_size(inboundstars);
            cmass[1] /= il_size(inboundstars);
            cmass[2] /= il_size(inboundstars);
            xyzarr2radecdeg(cmass, &ra, &dec);

            il_free(inboundstars);

            if (!sip_radec2pixelxy(&sip, ra, dec, &px, &py))
                continue;

            shortname = constellations_get_shortname(c);
            longname = constellations_get_longname(c);
            assert(shortname && longname);

            logverb("%s at (%g, %g)\n", longname, px, py);

            if (Ninbounds == Nunique) {
                printf("The constellation %s (%s)\n", longname, shortname);
            } else {
                printf("Part of the constellation %s (%s)\n", longname, shortname);
            }

            if (justlist)
                continue;

            // If the label will be off-screen, move it back on.
            cairo_text_extents(cairo, shortname, &textents);
			
            if (px < 0)
                px = 0;
            if (py < textents.height)
                py = textents.height;
            if ((px + textents.width)*scale > W)
                px = W/scale - textents.width;
            if ((py+textents.height)*scale > H)
                py = H/scale - textents.height;
            logverb("%s at (%g, %g)\n", shortname, px, py);

            add_text(cairos, longname, px, py, halign, valign);

            // Draw the lines.
            cairo_set_line_width(cairo, lw);
            lines = constellations_get_lines(c);
            for (i=0; i<il_size(lines)/2; i++) {
                int star1, star2;
                double ra1, dec1, ra2, dec2;
                double px1, px2, py1, py2;
                double dx, dy;
                double dist;
                double gapfrac;
                star1 = il_get(lines, i*2+0);
                star2 = il_get(lines, i*2+1);
                constellations_get_star_radec(star1, &ra1, &dec1);
                constellations_get_star_radec(star2, &ra2, &dec2);
                if (!sip_radec2pixelxy(&sip, ra1, dec1, &px1, &py1) ||
                    !sip_radec2pixelxy(&sip, ra2, dec2, &px2, &py2))
                    continue;
                dx = px2 - px1;
                dy = py2 - py1;
                dist = hypot(dx, dy);
                gapfrac = endgap / dist;
                cairo_move_to(cairoshapes, px1 + dx*gapfrac, py1 + dy*gapfrac);
                cairo_line_to(cairoshapes, px1 + dx*(1.0-gapfrac), py1 + dy*(1.0-gapfrac));
                cairo_stroke(cairoshapes);
            }
            il_free(lines);
        }
        logverb("done constellations.\n");
    }

    if (bright) {
        double dy = 0;
        cairo_font_extents_t extents;
        pl* brightstars = pl_new(16);

        if (!justlist) {
            cairo_set_source_rgba(cairoshapes, 0.75, 0.75, 0.75, 0.8);
            cairo_font_extents(cairo, &extents);
            dy = extents.ascent * 0.5;
            cairo_set_line_width(cairoshapes, cw);
        }

        N = bright_stars_n();
        logverb("Checking %i bright stars.\n", N);

        for (i=0; i<N; i++) {
            const brightstar_t* bs = bright_stars_get(i);

            if (!sip_radec2pixelxy(&sip, bs->ra, bs->dec, &px, &py))
                continue;
            if (px < 0 || py < 0 || px*scale > W || py*scale > H)
                continue;
            if (!(bs->name && strlen(bs->name)))
                continue;
            if (common_only && !(bs->common_name && strlen(bs->common_name)))
                continue;

            if (strcmp(bs->common_name, "Maia") == 0)
                continue;

            pl_append(brightstars, bs);
        }

        // keep only the Nbright brightest?
        if (Nbright && (pl_size(brightstars) > Nbright)) {
            pl_sort(brightstars, sort_by_mag);
            pl_remove_index_range(brightstars, Nbright, pl_size(brightstars)-Nbright);
        }

        for (i=0; i<pl_size(brightstars); i++) {
            char* text;
            const brightstar_t* bs = pl_get(brightstars, i);

            if (!sip_radec2pixelxy(&sip, bs->ra, bs->dec, &px, &py))
                continue;
            if (bs->common_name && strlen(bs->common_name))
                if (print_common_only || common_only)
                    text = strdup(bs->common_name);
                else
                    asprintf_safe(&text, "%s (%s)", bs->common_name, bs->name);
            else
                text = strdup(bs->name);

            logverb("%s at (%g, %g)\n", text, px, py);

            if (json) {
                sl* names = sl_new(4);
                char* namearr;
                if (bs->common_name && strlen(bs->common_name))
                    sl_append(names, bs->common_name);
                if (bs->name)
					sl_append(names, bs->name);
				
                namearr = sl_join(names, "\", \"");

                sl_appendf(json,
                           "{ \"type\"  : \"star\", "
                           "  \"pixelx\": %g,       "
                           "  \"pixely\": %g,       "
                           "  \"name\"  : \"%s\",   "
                           "  \"names\" : [ \"%s\" ] } "
                           , px, py,
                           (bs->common_name && strlen(bs->common_name)) ? bs->common_name : bs->name,
                           namearr);
                free(namearr);
                sl_free2(names);
            }

            if (bs->common_name && strlen(bs->common_name))
                printf("The star %s (%s)\n", bs->common_name, bs->name);
            else
                printf("The star %s\n", bs->name);

            if (!justlist) {
                float r,g,b;
                // set color based on RA,Dec to match constellations above.
                if (whitetext) {
                	r = g = b = 1;
                } else {
                	color_for_radec(bs->ra, bs->dec, &r, &g, &b);
                }
                cairo_set_source_rgba(cairoshapes, r,g,b,0.8);
                cairo_set_source_rgba(cairo, r,g,b, 0.8);
            }

            if (!justlist)
                add_text(cairos, text, px + label_offset, py + dy,
						 halign, valign);

            free(text);

            if (!justlist) {
                // plot a black circle behind the light circle...
                cairo_arc(cairobg, px, py, crad+1.0, 0.0, 2.0*M_PI);
                cairo_stroke(cairobg);

                cairo_arc(cairoshapes, px, py, crad, 0.0, 2.0*M_PI);
                cairo_stroke(cairoshapes);
            }
        }
        pl_free(brightstars);
    }

    if (NGC) {
        double imscale;
        double imsize;
        double dy = 0;
        cairo_font_extents_t extents;

        if (!justlist) {
            cairo_set_source_rgb(cairoshapes, 1.0, 1.0, 1.0);
            cairo_set_source_rgb(cairo, 1.0, 1.0, 1.0);
            cairo_set_line_width(cairo, nw);
            cairo_font_extents(cairo, &extents);
            dy = extents.ascent * 0.5;
        }

        // arcsec/pixel
        imscale = sip_pixel_scale(&sip);
        // arcmin
        imsize = imscale * (imin(W, H) / scale) / 60.0;
        N = ngc_num_entries();

        logverb("Checking %i NGC/IC objects.\n", N);

        for (i=0; i<N; i++) {
            ngc_entry* ngc = ngc_get_entry(i);
            sl* str;
            sl* names;
            double pixsize;
            float ara, adec;
            char* text;

            if (!ngc)
                break;
            if (ngc->size < imsize * ngc_fraction)
                continue;

            if (ngcic_accurate_get_radec(ngc->is_ngc, ngc->id, &ara, &adec) == 0) {
                ngc->ra = ara;
                ngc->dec = adec;
            }

            if (!sip_radec2pixelxy(&sip, ngc->ra, ngc->dec, &px, &py))
                continue;
            if (px < 0 || py < 0 || px*scale > W || py*scale > H)
                continue;

            str = sl_new(4);
            //sl_appendf(str, "%s %i", (ngc->is_ngc ? "NGC" : "IC"), ngc->id);
            names = ngc_get_names(ngc, NULL);
            if (names) {
                int n;
                for (n=0; n<sl_size(names); n++) {
                    if (only_messier && strncmp(sl_get(names, n), "M ", 2))
                        continue;
                    sl_append(str, sl_get(names, n));
                }
            }
            sl_free2(names);

            text = sl_implode(str, " / ");

            printf("%s\n", text);

            pixsize = ngc->size * 60.0 / imscale;

            if (!justlist) {
                // black circle behind the white one...
                cairo_arc(cairobg, px, py, pixsize/2.0+1.0, 0.0, 2.0*M_PI);
                cairo_stroke(cairobg);

                cairo_move_to(cairoshapes, px + pixsize/2.0, py);
                cairo_arc(cairoshapes, px, py, pixsize/2.0, 0.0, 2.0*M_PI);
                debug("size: %f arcsec, pixsize: %f pixels\n", ngc->size, pixsize);
                cairo_stroke(cairoshapes);

                add_text(cairos, text, px + label_offset, py + dy,
						 halign, valign);
            }

            if (json) {
                char* namelist = sl_implode(str, "\", \"");
                sl_appendf(json,
                           "{ \"type\"   : \"ngc\", "
                           "  \"names\"  : [ \"%s\" ], "
                           "  \"pixelx\" : %g, "
                           "  \"pixely\" : %g, "
                           "  \"radius\" : %g }"
                           , namelist, px, py, pixsize/2.0);
                free(namelist);
            }

            free(text);
            sl_free2(str);
        }
    }

    if (HD) {
        double rac, decc, ra2, dec2;
        double arcsec;
        hd_catalog_t* hdcat;
        bl* hdlist;
        int i;

        if (!justlist)
            cairo_set_source_rgb(cairo, 1.0, 1.0, 1.0);

		logverb("Reading HD catalog: %s\n", hdpath);
        hdcat = henry_draper_open(hdpath);
        if (!hdcat) {
            ERROR("Failed to open HD catalog");
            exit(-1);
        }
		logverb("Got %i HD stars\n", henry_draper_n(hdcat));

        sip_pixelxy2radec(&sip, W/(2.0*scale), H/(2.0*scale), &rac, &decc);
        sip_pixelxy2radec(&sip, 0.0, 0.0, &ra2, &dec2);
        arcsec = arcsec_between_radecdeg(rac, decc, ra2, dec2);
        // Fudge
        arcsec *= 1.1;
        hdlist = henry_draper_get(hdcat, rac, decc, arcsec);
		logverb("Found %zu HD stars within range (%g arcsec of RA,Dec %g,%g)\n", bl_size(hdlist), arcsec, rac, decc);

        for (i=0; i<bl_size(hdlist); i++) {
            double px, py;
            char* txt;
            hd_entry_t* hd = bl_access(hdlist, i);
            if (!sip_radec2pixelxy(&sip, hd->ra, hd->dec, &px, &py)) {
                continue;
			}
            if (px < 0 || py < 0 || px*scale > W || py*scale > H) {
				logverb("  HD %i at RA,Dec (%g, %g) -> pixel (%.1f, %.1f) is out of bounds\n",
						hd->hd, hd->ra, hd->dec, px, py);
                continue;
			}
            asprintf_safe(&txt, "HD %i", hd->hd);
            if (!justlist) {
                cairo_text_extents_t textents;
                cairo_text_extents(cairo, txt, &textents);
                cairo_arc(cairobg, px, py, crad+1.0, 0.0, 2.0*M_PI);
                cairo_stroke(cairobg);
                cairo_arc(cairoshapes, px, py, crad, 0.0, 2.0*M_PI);
                cairo_stroke(cairoshapes);

                px -= (textents.width * 0.5);
                py -= (crad + 4.0);

                add_text(cairos, txt, px, py, halign, valign);
            }

            if (json)
                sl_appendf(json,
                           "{ \"type\"  : \"hd\","
                           "  \"pixelx\": %g, "
                           "  \"pixely\": %g, "
                           "  \"name\"  : \"HD %i\" }"
                           , px, py, hd->hd);

            printf("%s\n", txt);
            free(txt);
        }
        bl_free(hdlist);
        henry_draper_close(hdcat);
    }

    if (json) {
        FILE* fout = stderr;
        char* annstr = sl_implode(json, ",\n");
        fprintf(fout, "{ \n");
        fprintf(fout, "  \"status\": \"solved\",\n");
        fprintf(fout, "  \"git-revision\": %s,\n", AN_GIT_REVISION);
        fprintf(fout, "  \"git-date\": \"%s\",\n", AN_GIT_DATE);
        fprintf(fout, "  \"annotations\": [\n%s\n]\n", annstr);
        fprintf(fout, "}\n");
        free(annstr);
    }
    sl_free2(json);
    json = NULL;

    if (justlist)
        return 0;

    target = cairo_image_surface_create_for_data(img, CAIRO_FORMAT_ARGB32, W, H, W*4);
    cairot = cairo_create(target);
    cairo_set_source_rgba(cairot, 0, 0, 0, 1);

    // Here's where you set the background surface's properties...
    cairo_set_source_surface(cairot, surfbg, 0, 0);
    cairo_mask_surface(cairot, surfshapesmask, 0, 0);
    cairo_stroke(cairot);

    // Add on the shapes.
    cairo_set_source_surface(cairot, surfshapes, 0, 0);
    //cairo_mask_surface(cairot, surfshapes, 0, 0);
    cairo_mask_surface(cairot, surfshapesmask, 0, 0);
    cairo_stroke(cairot);

    // Add on the foreground.
    cairo_set_source_surface(cairot, surffg, 0, 0);
    cairo_mask_surface(cairot, surffg, 0, 0);
    cairo_stroke(cairot);

    // Convert image for output...
    cairoutils_argb32_to_rgba(img, W, H);

    if (pngformat) {
        if (cairoutils_write_png(outfn, img, W, H)) {
            ERROR("Failed to write PNG");
            exit(-1);
        }
    } else {
        if (cairoutils_write_ppm(outfn, img, W, H)) {
            ERROR("Failed to write PPM");
            exit(-1);
        }
    }

    cairo_surface_destroy(target);
    cairo_surface_destroy(surfshapesmask);
    cairo_surface_destroy(surffg);
    cairo_surface_destroy(surfbg);
    cairo_surface_destroy(surfshapes);
    cairo_destroy(cairo);
    cairo_destroy(cairot);
    cairo_destroy(cairobg);
    cairo_destroy(cairoshapes);
    cairo_destroy(cairoshapesmask);
    free(img);

    return 0;
}
コード例 #12
0
ファイル: hpsplit.c プロジェクト: Carl4/astrometry.net
int main(int argc, char *argv[]) {
    int argchar;
	char* progname = argv[0];
	sl* infns = sl_new(16);
	char* outfnpat = NULL;
	char* racol = "RA";
	char* deccol = "DEC";
	char* tempdir = "/tmp";
	anbool gzip = FALSE;
	sl* cols = sl_new(16);
	int loglvl = LOG_MSG;
	int nside = 1;
	double margin = 0.0;
	int NHP;
	double md;
	char* backref = NULL;
	
	fitstable_t* intable;
	fitstable_t** outtables;

	char** myargs;
	int nmyargs;
	int i;

    while ((argchar = getopt (argc, argv, OPTIONS)) != -1)
        switch (argchar) {
		case 'b':
			backref = optarg;
			break;
		case 't':
			tempdir = optarg;
			break;
		case 'c':
			sl_append(cols, optarg);
			break;
		case 'g':
			gzip = TRUE;
			break;
		case 'o':
			outfnpat = optarg;
			break;
		case 'r':
			racol = optarg;
			break;
		case 'd':
			deccol = optarg;
			break;
		case 'n':
			nside = atoi(optarg);
			break;
		case 'm':
			margin = atof(optarg);
			break;
		case 'v':
			loglvl++;
			break;
        case '?':
            fprintf(stderr, "Unknown option `-%c'.\n", optopt);
        case 'h':
			printHelp(progname);
            return 0;
        default:
            return -1;
        }

	if (sl_size(cols) == 0) {
		sl_free2(cols);
		cols = NULL;
	}

	nmyargs = argc - optind;
	myargs = argv + optind;

	for (i=0; i<nmyargs; i++)
		sl_append(infns, myargs[i]);
	
	if (!sl_size(infns)) {
		printHelp(progname);
		printf("Need input filenames!\n");
		exit(-1);
	}
	log_init(loglvl);
	fits_use_error_system();

	NHP = 12 * nside * nside;
	logmsg("%i output healpixes\n", NHP);
	outtables = calloc(NHP, sizeof(fitstable_t*));
	assert(outtables);

	md = deg2dist(margin);

	/**
	 About the mincaps/maxcaps:

	 These have a center and radius-squared, describing the region
	 inside a small circle on the sphere.

	 The "mincaps" describe the regions that are definitely owned by a
	 single healpix -- ie, more than MARGIN distance from any edge.
	 That is, the mincap is the small circle centered at (0.5, 0.5) in
	 the healpix and with radius = the distance to the closest healpix
	 boundary, MINUS the margin distance.

	 Below, we first check whether a new star is within the "mincap"
	 of any healpix.  If so, we stick it in that healpix and continue.

	 Otherwise, we check all the "maxcaps" -- these are the healpixes
	 it could *possibly* be in.  We then refine with
	 healpix_within_range_of_xyz.  The maxcap distance is the distance
	 to the furthest boundary point, PLUS the margin distance.
	 */


	cap_t* mincaps = malloc(NHP * sizeof(cap_t));
	cap_t* maxcaps = malloc(NHP * sizeof(cap_t));
	for (i=0; i<NHP; i++) {
		// center
		double r2;
		double xyz[3];
		double* cxyz;
		double step = 1e-3;
		double v;
		double r2b, r2a;

		cxyz = mincaps[i].xyz;
		healpix_to_xyzarr(i, nside, 0.5, 0.5, mincaps[i].xyz);
		memcpy(maxcaps[i].xyz, cxyz, 3 * sizeof(double));
		logverb("Center of HP %i: (%.3f, %.3f, %.3f)\n", i, cxyz[0], cxyz[1], cxyz[2]);

		// radius-squared:
		// max is the easy one: max of the four corners (I assume)
		r2 = 0.0;
		healpix_to_xyzarr(i, nside, 0.0, 0.0, xyz);
		logverb("  HP %i corner 1: (%.3f, %.3f, %.3f), distsq %.3f\n", i, xyz[0], xyz[1], xyz[2], distsq(xyz, cxyz, 3));
		r2 = MAX(r2, distsq(xyz, cxyz, 3));
		healpix_to_xyzarr(i, nside, 1.0, 0.0, xyz);
		logverb("  HP %i corner 1: (%.3f, %.3f, %.3f), distsq %.3f\n", i, xyz[0], xyz[1], xyz[2], distsq(xyz, cxyz, 3));
		r2 = MAX(r2, distsq(xyz, cxyz, 3));
		healpix_to_xyzarr(i, nside, 0.0, 1.0, xyz);
		logverb("  HP %i corner 1: (%.3f, %.3f, %.3f), distsq %.3f\n", i, xyz[0], xyz[1], xyz[2], distsq(xyz, cxyz, 3));
		r2 = MAX(r2, distsq(xyz, cxyz, 3));
		healpix_to_xyzarr(i, nside, 1.0, 1.0, xyz);
		logverb("  HP %i corner 1: (%.3f, %.3f, %.3f), distsq %.3f\n", i, xyz[0], xyz[1], xyz[2], distsq(xyz, cxyz, 3));
		r2 = MAX(r2, distsq(xyz, cxyz, 3));
		logverb("  max distsq: %.3f\n", r2);
		logverb("  margin dist: %.3f\n", md);
		maxcaps[i].r2 = square(sqrt(r2) + md);
		logverb("  max cap distsq: %.3f\n", maxcaps[i].r2);
		r2a = r2;

		r2 = 1.0;
		r2b = 0.0;
		for (v=0; v<=1.0; v+=step) {
			healpix_to_xyzarr(i, nside, 0.0, v, xyz);
			r2 = MIN(r2, distsq(xyz, cxyz, 3));
			r2b = MAX(r2b, distsq(xyz, cxyz, 3));
			healpix_to_xyzarr(i, nside, 1.0, v, xyz);
			r2 = MIN(r2, distsq(xyz, cxyz, 3));
			r2b = MAX(r2b, distsq(xyz, cxyz, 3));
			healpix_to_xyzarr(i, nside, v, 0.0, xyz);
			r2 = MIN(r2, distsq(xyz, cxyz, 3));
			r2b = MAX(r2b, distsq(xyz, cxyz, 3));
			healpix_to_xyzarr(i, nside, v, 1.0, xyz);
			r2 = MIN(r2, distsq(xyz, cxyz, 3));
			r2b = MAX(r2b, distsq(xyz, cxyz, 3));
		}
		mincaps[i].r2 = square(MAX(0, sqrt(r2) - md));
		logverb("\nhealpix %i: min rad    %g\n", i, sqrt(r2));
		logverb("healpix %i: max rad    %g\n", i, sqrt(r2a));
		logverb("healpix %i: max rad(b) %g\n", i, sqrt(r2b));
		assert(r2a >= r2b);
	}

	if (backref) {
		fitstable_t* tab = fitstable_open_for_writing(backref);
		int maxlen = 0;
		char* buf;
		for (i=0; i<sl_size(infns); i++) {
			char* infn = sl_get(infns, i);
			maxlen = MAX(maxlen, strlen(infn));
		}
		fitstable_add_write_column_array(tab, fitscolumn_char_type(), maxlen,
										 "filename", NULL);
		fitstable_add_write_column(tab, fitscolumn_i16_type(), "index", NULL);
		if (fitstable_write_primary_header(tab) ||
			fitstable_write_header(tab)) {
			ERROR("Failed to write header of backref table \"%s\"", backref);
			exit(-1);
		}
		buf = malloc(maxlen+1);
		assert(buf);

		for (i=0; i<sl_size(infns); i++) {
			char* infn = sl_get(infns, i);
			int16_t ind;
			memset(buf, 0, maxlen);
			strcpy(buf, infn);
			ind = i;
			if (fitstable_write_row(tab, buf, &ind)) {
				ERROR("Failed to write row %i of backref table: %s = %i",
					  i, buf, ind);
				exit(-1);
			}
		}
		if (fitstable_fix_header(tab) ||
			fitstable_close(tab)) {
			ERROR("Failed to fix header & close backref table");
			exit(-1);
		}
		logmsg("Wrote backref table %s\n", backref);
		free(buf);
	}

	for (i=0; i<sl_size(infns); i++) {
		char* infn = sl_get(infns, i);
		char* originfn = infn;
		int r, NR;
		tfits_type any, dubl;
		il* hps = NULL;
		bread_t* rowbuf;
		int R;
		char* tempfn = NULL;
		char* padrowdata = NULL;
		int ii;

		logmsg("Reading input \"%s\"...\n", infn);

		if (gzip) {
			char* cmd;
			int rtn;
			tempfn = create_temp_file("hpsplit", tempdir);
			asprintf_safe(&cmd, "gunzip -cd %s > %s", infn, tempfn);
			logmsg("Running: \"%s\"\n", cmd);
			rtn = run_command_get_outputs(cmd, NULL, NULL);
			if (rtn) {
				ERROR("Failed to run command: \"%s\"", cmd);
				exit(-1);
			}
			free(cmd);
			infn = tempfn;
		}

		intable = fitstable_open(infn);
		if (!intable) {
			ERROR("Couldn't read catalog %s", infn);
			exit(-1);
		}
		NR = fitstable_nrows(intable);
		logmsg("Got %i rows\n", NR);

		any = fitscolumn_any_type();
		dubl = fitscolumn_double_type();

		fitstable_add_read_column_struct(intable, dubl, 1, 0, any, racol, TRUE);
		fitstable_add_read_column_struct(intable, dubl, 1, sizeof(double), any, deccol, TRUE);

		fitstable_use_buffered_reading(intable, 2*sizeof(double), 1000);

		R = fitstable_row_size(intable);
		rowbuf = buffered_read_new(R, 1000, NR, refill_rowbuffer, intable);

		if (fitstable_read_extension(intable, 1)) {
			ERROR("Failed to find RA and DEC columns (called \"%s\" and \"%s\" in the FITS file)", racol, deccol);
			exit(-1);
		}

		for (r=0; r<NR; r++) {
			int hp = -1;
			double ra, dec;
			int j;
			double* rd;
			void* rowdata;
			void* rdata;

			if (r && ((r % 100000) == 0)) {
			  logmsg("Reading row %i of %i\n", r, NR);
			}

			//printf("reading RA,Dec for row %i\n", r);
			rd = fitstable_next_struct(intable);
			ra = rd[0];
			dec = rd[1];

			logverb("row %i: ra,dec %g,%g\n", r, ra, dec);
			if (margin == 0) {
				hp = radecdegtohealpix(ra, dec, nside);
				logverb("  --> healpix %i\n", hp);
			} else {

				double xyz[3];
				anbool gotit = FALSE;
				double d2;
				if (!hps)
					hps = il_new(4);
				radecdeg2xyzarr(ra, dec, xyz);
				for (j=0; j<NHP; j++) {
					d2 = distsq(xyz, mincaps[j].xyz, 3);
					if (d2 <= mincaps[j].r2) {
						logverb("  -> in mincap %i  (dist %g vs %g)\n", j, sqrt(d2), sqrt(mincaps[j].r2));
						il_append(hps, j);
						gotit = TRUE;
						break;
					}
				}
				if (!gotit) {
					for (j=0; j<NHP; j++) {
						d2 = distsq(xyz, maxcaps[j].xyz, 3);
						if (d2 <= maxcaps[j].r2) {
							logverb("  -> in maxcap %i  (dist %g vs %g)\n", j, sqrt(d2), sqrt(maxcaps[j].r2));
							if (healpix_within_range_of_xyz(j, nside, xyz, margin)) {
								logverb("  -> and within range.\n");
								il_append(hps, j);
							}
						}
					}
				}

				//hps = healpix_rangesearch_radec(ra, dec, margin, nside, hps);

				logverb("  --> healpixes: [");
				for (j=0; j<il_size(hps); j++)
					logverb(" %i", il_get(hps, j));
				logverb(" ]\n");
			}

			//printf("Reading rowdata for row %i\n", r);
			rowdata = buffered_read(rowbuf);
			assert(rowdata);


			j=0;
			while (1) {
				if (hps) {
					if (j >= il_size(hps))
						break;
					hp = il_get(hps, j);
					j++;
				}
				assert(hp < NHP);
				assert(hp >= 0);

				if (!outtables[hp]) {
					char* outfn;
					fitstable_t* out;

					// MEMLEAK the output filename.  You'll live.
					asprintf_safe(&outfn, outfnpat, hp);
					logmsg("Opening output file \"%s\"...\n", outfn);
					out = fitstable_open_for_writing(outfn);
					if (!out) {
						ERROR("Failed to open output table \"%s\"", outfn);
						exit(-1);
					}
					// Set the output table structure.
					if (cols) {
					  fitstable_add_fits_columns_as_struct3(intable, out, cols, 0);
					} else
						fitstable_add_fits_columns_as_struct2(intable, out);

					if (backref) {
						tfits_type i16type;
						tfits_type i32type;
						// R = fitstable_row_size(intable);
						int off = R;
						i16type = fitscolumn_i16_type();
						i32type = fitscolumn_i32_type();
						fitstable_add_read_column_struct(out, i16type, 1, off,
														 i16type, "backref_file", TRUE);
						off += sizeof(int16_t);
						fitstable_add_read_column_struct(out, i32type, 1, off,
														 i32type, "backref_index", TRUE);
					}

					//printf("Output table:\n");
					//fitstable_print_columns(out);

					if (fitstable_write_primary_header(out) ||
						fitstable_write_header(out)) {
						ERROR("Failed to write output file headers for \"%s\"", outfn);
						exit(-1);
					}
					outtables[hp] = out;
				}

				if (backref) {
					int16_t brfile;
					int32_t brind;
					if (!padrowdata) {
						padrowdata = malloc(R + sizeof(int16_t) + sizeof(int32_t));
						assert(padrowdata);
					}
					// convert to FITS endian
					brfile = htons(i);
					brind  = htonl(r);
					// add backref data to rowdata
					memcpy(padrowdata, rowdata, R);
					memcpy(padrowdata + R, &brfile, sizeof(int16_t));
					memcpy(padrowdata + R + sizeof(int16_t), &brind, sizeof(int32_t));
					rdata = padrowdata;
				} else {
					rdata = rowdata;
				}

				if (cols) {
				  if (fitstable_write_struct_noflip(outtables[hp], rdata)) {
				    ERROR("Failed to copy a row of data from input table \"%s\" to output healpix %i", infn, hp);
				  }
				} else {
				  if (fitstable_write_row_data(outtables[hp], rdata)) {
				    ERROR("Failed to copy a row of data from input table \"%s\" to output healpix %i", infn, hp);
				  }
				}

				if (!hps)
					break;
			}
			if (hps)
				il_remove_all(hps);

		}
		buffered_read_free(rowbuf);
		// wack... buffered_read_free() just frees its internal buffer,
		// not the "rowbuf" struct itself.
		// who wrote this crazy code?  Oh, me of 5 years ago.  Jerk.
		free(rowbuf);

		fitstable_close(intable);
		il_free(hps);

		if (tempfn) {
			logverb("Removing temp file %s\n", tempfn);
			if (unlink(tempfn)) {
				SYSERROR("Failed to unlink() temp file \"%s\"", tempfn);
			}
			tempfn = NULL;
		}

		// fix headers so that the files are valid at this point.
		for (ii=0; ii<NHP; ii++) {
		  if (!outtables[ii])
		    continue;
		  off_t offset = ftello(outtables[ii]->fid);
		  if (fitstable_fix_header(outtables[ii])) {
		    ERROR("Failed to fix header for healpix %i after reading input file \"%s\"", ii, originfn);
		    exit(-1);
		  }
		  fseeko(outtables[ii]->fid, offset, SEEK_SET);
		}

		if (padrowdata) {
			free(padrowdata);
			padrowdata = NULL;
		}

	}

	for (i=0; i<NHP; i++) {
		if (!outtables[i])
			continue;
		if (fitstable_fix_header(outtables[i]) ||
			fitstable_fix_primary_header(outtables[i]) ||
			fitstable_close(outtables[i])) {
			ERROR("Failed to close output table for healpix %i", i);
			exit(-1);
		}
	}

	free(outtables);
	sl_free2(infns);
	sl_free2(cols);

	free(mincaps);
	free(maxcaps);

    return 0;
}
コード例 #13
0
int main(int argc, char** args) {
    char* filename = NULL;
    int npoints;
    int i, j;
    int* healpixes;
    int argchar;
    char* progname = args[0];
    il** lists;
    anbool quiet = FALSE;
    rdlist* rdls;
    int Nside = 1;
    int N;

    while ((argchar = getopt (argc, args, OPTIONS)) != -1)
        switch (argchar) {
        case 'N':
            Nside = atoi(optarg);
            break;
        case 'f':
            filename = optarg;
            break;
        case 'h':
            printHelp(progname);
            exit(0);
        case 'q':
            quiet = TRUE;
            break;
        case '?':
            fprintf(stderr, "Unknown option `-%c'.\n", optopt);
        default:
            exit(-1);
        }

    if (!filename) {
        printHelp(progname);
        exit(-1);
    }

    fprintf(stderr, "Opening RDLS file %s...\n", filename);
    rdls = rdlist_open(filename);
    if (!rdls) {
        fprintf(stderr, "Failed to open RDLS file.\n");
        exit(-1);
    }

    N = 12 * Nside * Nside;

    healpixes = malloc(N * sizeof(int));
    lists     = calloc(N,  sizeof(il*));

    /*
     for (i=0; i<N; i++) {
     lists[i] = il_new(256);
     }
     */

    for (j=1; j<=rdls_n_fields(rdls); j++) {
        rd* points;

        points = rdlist_get_field(rdls, j);
        if (!points) {
            fprintf(stderr, "error reading field %i\n", j);
            break;
        }

        memset(healpixes, 0, N * sizeof(int));

        npoints = rd_size(points);

        for (i=0; i<npoints; i++) {
            double ra, dec;
            int hp;

            ra  = deg2rad(rd_refra (points, i));
            dec = deg2rad(rd_refdec(points, i));

            if (Nside > 1)
                hp = radectohealpix_nside(ra, dec, Nside);
            else
                hp = radectohealpix(ra, dec);
            if ((hp < 0) || (hp >= N)) {
                printf("hp=%i\n", hp);
                continue;
            }
            healpixes[hp] = 1;
        }
        if (!quiet) {
            printf("Field %i: healpixes  ", j);
            for (i=0; i<N; i++) {
                if (healpixes[i])
                    printf("%i  ", i);
            }
            printf("\n");
            fflush(stdout);
        }

        for (i=0; i<N; i++)
            if (healpixes[i]) {
                if (!lists[i])
                    lists[i] = il_new(256);
                il_append(lists[i], j);
            }

        free_rd(points);
    }

    for (i=0; i<N; i++) {
        int N;
        if (!lists[i]) 
            continue;
        printf("HP %i: ", i);
        N = il_size(lists[i]);
        for (j=0; j<N; j++)
            printf("%i ", il_get(lists[i], j));
        il_free(lists[i]);
        printf("\n");
    }

    free(lists);
    free(healpixes);

    rdlist_close(rdls);
    return 0;
}
コード例 #14
0
ファイル: verify2.c プロジェクト: Carl4/astrometry.net
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;
}
コード例 #15
0
int uniformize_catalog(fitstable_t* intable, fitstable_t* outtable,
					   const char* racol, const char* deccol,
					   const char* sortcol, anbool sort_ascending,
					   double sort_min_cut,
					   // ?  Or do this cut in a separate process?
					   int bighp, int bignside,
					   int nmargin,
					   // uniformization nside.
					   int Nside,
					   double dedup_radius,
					   int nsweeps,
					   char** args, int argc) {
	anbool allsky;
	intmap_t* starlists;
	int NHP;
	anbool dense = FALSE;
	double dedupr2 = 0.0;
	tfits_type dubl;
	int N;
	int* inorder = NULL;
	int* outorder = NULL;
	int outi;
	double *ra = NULL, *dec = NULL;
	il* myhps = NULL;
	int i,j,k;
	int nkeep = nsweeps;
	int noob = 0;
	int ndup = 0;
	struct oh_token token;
	int* npersweep = NULL;
	qfits_header* outhdr = NULL;
	double *sortval = NULL;

	if (bignside == 0)
		bignside = 1;
	allsky = (bighp == -1);

    if (Nside % bignside) {
        ERROR("Fine healpixelization Nside must be a multiple of the coarse healpixelization Nside");
        return -1;
    }
	if (Nside > HP_MAX_INT_NSIDE) {
		ERROR("Error: maximum healpix Nside = %i", HP_MAX_INT_NSIDE);
		return -1;
	}

	NHP = 12 * Nside * Nside;
	logverb("Healpix Nside: %i, # healpixes on the whole sky: %i\n", Nside, NHP);
	if (!allsky) {
		logverb("Creating index for healpix %i, nside %i\n", bighp, bignside);
		logverb("Number of healpixes: %i\n", ((Nside/bignside)*(Nside/bignside)));
	}
	logverb("Healpix side length: %g arcmin.\n", healpix_side_length_arcmin(Nside));

	dubl = fitscolumn_double_type();
	if (!racol)
		racol = "RA";
	ra = fitstable_read_column(intable, racol, dubl);
	if (!ra) {
		ERROR("Failed to find RA column (%s) in table", racol);
		return -1;
	}
	if (!deccol)
		deccol = "DEC";
	dec = fitstable_read_column(intable, deccol, dubl);
	if (!dec) {
		ERROR("Failed to find DEC column (%s) in table", deccol);
		free(ra);
		return -1;
	}

	N = fitstable_nrows(intable);
	logverb("Have %i objects\n", N);

	// FIXME -- argsort and seek around the input table, and append to
	// starlists in order; OR read from the input table in sequence and
	// sort in the starlists?
	if (sortcol) {
		logverb("Sorting by %s...\n", sortcol);
		sortval = fitstable_read_column(intable, sortcol, dubl);
		if (!sortval) {
			ERROR("Failed to read sorting column \"%s\"", sortcol);
			free(ra);
			free(dec);
			return -1;
		}
		inorder = permuted_sort(sortval, sizeof(double),
								sort_ascending ? compare_doubles_asc : compare_doubles_desc,
								NULL, N);
		if (sort_min_cut > -HUGE_VAL) {
			logverb("Cutting to %s > %g...\n", sortcol, sort_min_cut);
			// Cut objects with sortval < sort_min_cut.
			if (sort_ascending) {
				// skipped objects are at the front -- find the first obj
				// to keep
				for (i=0; i<N; i++)
					if (sortval[inorder[i]] > sort_min_cut)
						break;
				// move the "inorder" indices down.
				if (i)
					memmove(inorder, inorder+i, (N-i)*sizeof(int));
				N -= i;
			} else {
				// skipped objects are at the end -- find the last obj to keep.
				for (i=N-1; i>=0; i--)
					if (sortval[inorder[i]] > sort_min_cut)
						break;
				N = i+1;
			}
			logverb("Cut to %i objects\n", N);
		}
		//free(sortval);
	}

	token.nside = bignside;
	token.finenside = Nside;
	token.hp = bighp;

	if (!allsky && nmargin) {
		int bigbighp, bighpx, bighpy;
		//int ninside;
		il* seeds = il_new(256);
		logverb("Finding healpixes in range...\n");
        healpix_decompose_xy(bighp, &bigbighp, &bighpx, &bighpy, bignside);
		//ninside = (Nside/bignside)*(Nside/bignside);
		// Prime the queue with the fine healpixes that are on the
		// boundary of the big healpix.
		for (i=0; i<((Nside / bignside) - 1); i++) {
			// add (i,0), (i,max), (0,i), and (0,max) healpixes
            int xx = i + bighpx * (Nside / bignside);
            int yy = i + bighpy * (Nside / bignside);
            int y0 =     bighpy * (Nside / bignside);
			// -1 prevents us from double-adding the corners.
            int y1 =(1 + bighpy)* (Nside / bignside) - 1;
            int x0 =     bighpx * (Nside / bignside);
            int x1 =(1 + bighpx)* (Nside / bignside) - 1;
            assert(xx < Nside);
            assert(yy < Nside);
            assert(x0 < Nside);
            assert(x1 < Nside);
            assert(y0 < Nside);
            assert(y1 < Nside);
			il_append(seeds, healpix_compose_xy(bigbighp, xx, y0, Nside));
			il_append(seeds, healpix_compose_xy(bigbighp, xx, y1, Nside));
			il_append(seeds, healpix_compose_xy(bigbighp, x0, yy, Nside));
			il_append(seeds, healpix_compose_xy(bigbighp, x1, yy, Nside));
		}
        logmsg("Number of boundary healpixes: %zu (Nside/bignside = %i)\n", il_size(seeds), Nside/bignside);

		myhps = healpix_region_search(-1, seeds, Nside, NULL, NULL,
									  outside_healpix, &token, nmargin);
		logmsg("Number of margin healpixes: %zu\n", il_size(myhps));
		il_free(seeds);

		il_sort(myhps, TRUE);
		// DEBUG
		il_check_consistency(myhps);
		il_check_sorted_ascending(myhps, TRUE);
	}

	dedupr2 = arcsec2distsq(dedup_radius);
	starlists = intmap_new(sizeof(int32_t), nkeep, 0, dense);

	logverb("Placing stars in grid cells...\n");
	for (i=0; i<N; i++) {
		int hp;
		bl* lst;
		int32_t j32;
		anbool oob;
		if (inorder) {
			j = inorder[i];
			//printf("Placing star %i (%i): sort value %s = %g, RA,Dec=%g,%g\n", i, j, sortcol, sortval[j], ra[j], dec[j]);
		} else
			j = i;
		
		hp = radecdegtohealpix(ra[j], dec[j], Nside);
		//printf("HP %i\n", hp);
		// in bounds?
		oob = FALSE;
		if (myhps) {
			oob = (outside_healpix(hp, &token) && !il_sorted_contains(myhps, hp));
		} else if (!allsky) {
			oob = (outside_healpix(hp, &token));
		}
		if (oob) {
			//printf("out of bounds.\n");
			noob++;
			continue;
		}

		lst = intmap_find(starlists, hp, TRUE);
		/*
		 printf("list has %i existing entries.\n", bl_size(lst));
		 for (k=0; k<bl_size(lst); k++) {
		 bl_get(lst, k, &j32);
		 printf("  %i: index %i, %s = %g\n", k, j32, sortcol, sortval[j32]);
		 }
		 */

		// is this list full?
		if (nkeep && (bl_size(lst) >= nkeep)) {
			// Here we assume we're working in sorted order: once the list is full we're done.
			//printf("Skipping: list is full.\n");
			continue;
		}

		if ((dedupr2 > 0.0) &&
			is_duplicate(hp, ra[j], dec[j], Nside, starlists, ra, dec, dedupr2)) {
			//printf("Skipping: duplicate\n");
			ndup++;
			continue;
		}

		// Add the new star (by index)
		j32 = j;
		bl_append(lst, &j32);
	}
	logverb("%i outside the healpix\n", noob);
	logverb("%i duplicates\n", ndup);

	il_free(myhps);
	myhps = NULL;
	free(inorder);
	inorder = NULL;
	free(ra);
	ra = NULL;
	free(dec);
	dec = NULL;

	outorder = malloc(N * sizeof(int));
	outi = 0;

	npersweep = calloc(nsweeps, sizeof(int));

	for (k=0; k<nsweeps; k++) {
		int starti = outi;
		int32_t j32;
		for (i=0;; i++) {
			bl* lst;
			int hp;
			if (!intmap_get_entry(starlists, i, &hp, &lst))
				break;
			if (bl_size(lst) <= k)
				continue;
			bl_get(lst, k, &j32);
			outorder[outi] = j32;
			//printf("sweep %i, cell #%i, hp %i, star %i, %s = %g\n", k, i, hp, j32, sortcol, sortval[j32]);
			outi++;
		}
		logmsg("Sweep %i: %i stars\n", k+1, outi - starti);
		npersweep[k] = outi - starti;

		if (sortcol) {
			// Re-sort within this sweep.
			permuted_sort(sortval, sizeof(double),
						  sort_ascending ? compare_doubles_asc : compare_doubles_desc,
						  outorder + starti, npersweep[k]);
			/*
			 for (i=0; i<npersweep[k]; i++) {
			 printf("  within sweep %i: star %i, j=%i, %s=%g\n",
			 k, i, outorder[starti + i], sortcol, sortval[outorder[starti + i]]);
			 }
			 */
		}

	}
	intmap_free(starlists);
	starlists = NULL;

	//////
	free(sortval);
	sortval = NULL;

	logmsg("Total: %i stars\n", outi);
	N = outi;

	outhdr = fitstable_get_primary_header(outtable);
    if (allsky)
        qfits_header_add(outhdr, "ALLSKY", "T", "All-sky catalog.", NULL);
    BOILERPLATE_ADD_FITS_HEADERS(outhdr);
    qfits_header_add(outhdr, "HISTORY", "This file was generated by the command-line:", NULL, NULL);
    fits_add_args(outhdr, args, argc);
    qfits_header_add(outhdr, "HISTORY", "(end of command line)", NULL, NULL);
	fits_add_long_history(outhdr, "uniformize-catalog args:");
	fits_add_long_history(outhdr, "  RA,Dec columns: %s,%s", racol, deccol);
	fits_add_long_history(outhdr, "  sort column: %s", sortcol);
	fits_add_long_history(outhdr, "  sort direction: %s", sort_ascending ? "ascending" : "descending");
	if (sort_ascending)
		fits_add_long_history(outhdr, "    (ie, for mag-like sort columns)");
	else
		fits_add_long_history(outhdr, "    (ie, for flux-like sort columns)");
	fits_add_long_history(outhdr, "  uniformization nside: %i", Nside);
	fits_add_long_history(outhdr, "    (ie, side length ~ %g arcmin)", healpix_side_length_arcmin(Nside));
	fits_add_long_history(outhdr, "  deduplication scale: %g arcsec", dedup_radius);
	fits_add_long_history(outhdr, "  number of sweeps: %i", nsweeps);

    fits_header_add_int(outhdr, "NSTARS", N, "Number of stars.");
    fits_header_add_int(outhdr, "HEALPIX", bighp, "Healpix covered by this catalog, with Nside=HPNSIDE");
    fits_header_add_int(outhdr, "HPNSIDE", bignside, "Nside of HEALPIX.");
	fits_header_add_int(outhdr, "CUTNSIDE", Nside, "uniformization scale (healpix nside)");
	fits_header_add_int(outhdr, "CUTMARG", nmargin, "margin size, in healpixels");
	//qfits_header_add(outhdr, "CUTBAND", cutband, "band on which the cut was made", NULL);
	fits_header_add_double(outhdr, "CUTDEDUP", dedup_radius, "deduplication radius [arcsec]");
	fits_header_add_int(outhdr, "CUTNSWEP", nsweeps, "number of sweeps");
	//fits_header_add_double(outhdr, "CUTMINMG", minmag, "minimum magnitude");
	//fits_header_add_double(outhdr, "CUTMAXMG", maxmag, "maximum magnitude");
	for (k=0; k<nsweeps; k++) {
		char key[64];
		sprintf(key, "SWEEP%i", (k+1));
        fits_header_add_int(outhdr, key, npersweep[k], "# stars added");
	}
	free(npersweep);

	if (fitstable_write_primary_header(outtable)) {
		ERROR("Failed to write primary header");
		return -1;
	}

	// Write output.
	fitstable_add_fits_columns_as_struct2(intable, outtable);
	if (fitstable_write_header(outtable)) {
		ERROR("Failed to write output table header");
		return -1;
	}
	logmsg("Writing output...\n");
	logverb("Row size: %i\n", fitstable_row_size(intable));
	if (fitstable_copy_rows_data(intable, outorder, N, outtable)) {
		ERROR("Failed to copy rows from input table to output");
		return -1;
	}
	if (fitstable_fix_header(outtable)) {
		ERROR("Failed to fix output table header");
		return -1;
	}
	free(outorder);
	return 0;
}
コード例 #16
0
ファイル: coadd-main.c プロジェクト: rasmi/astrometry.net
int main(int argc, char** args) {
    int argchar;
	char* progname = args[0];

	char* outfn = NULL;
	char* outwcsfn = NULL;
	int outwcsext = 0;

	anwcs_t* outwcs;

	sl* inimgfns = sl_new(16);
	sl* inwcsfns = sl_new(16);
	sl* inwtfns = sl_new(16);
	il* inimgexts = il_new(16);
	il* inwcsexts = il_new(16);
	il* inwtexts = il_new(16);

	int i;
	int loglvl = LOG_MSG;
	int order = 3;

	coadd_t* coadd;
	lanczos_args_t largs;

	double sigma = 0.0;
	anbool nearest = FALSE;
	anbool divweight = FALSE;

	int plane = 0;

    while ((argchar = getopt(argc, args, OPTIONS)) != -1)
        switch (argchar) {
		case '?':
        case 'h':
			printHelp(progname);
			exit(0);
		case 'D':
			divweight = TRUE;
			break;
		case 'p':
			plane = atoi(optarg);
			break;
		case 'N':
			nearest = TRUE;
			break;
		case 's':
			sigma = atof(optarg);
			break;
		case 'v':
			loglvl++;
			break;
		case 'e':
			outwcsext = atoi(optarg);
			break;
		case 'w':
			outwcsfn = optarg;
			break;
		case 'o':
			outfn = optarg;
			break;
		case 'O':
			order = atoi(optarg);
			break;
		}

	log_init(loglvl);
	fits_use_error_system();

	args += optind;
	argc -= optind;
	if (argc == 0 || argc % 6) {
		printHelp(progname);
		exit(-1);
	}

	for (i=0; i<argc/6; i++) {
		sl_append(inimgfns, args[6*i+0]);
		il_append(inimgexts, atoi(args[6*i+1]));
		sl_append(inwtfns, args[6*i+2]);
		il_append(inwtexts, atoi(args[6*i+3]));
		sl_append(inwcsfns, args[6*i+4]);
		il_append(inwcsexts, atoi(args[6*i+5]));
	}

	logmsg("Reading output WCS file %s\n", outwcsfn);
	outwcs = anwcs_open(outwcsfn, outwcsext);
	if (!outwcs) {
		ERROR("Failed to read WCS from file: %s ext %i\n", outwcsfn, outwcsext);
		exit(-1);
	}

	logmsg("Output image will be %i x %i\n", (int)anwcs_imagew(outwcs), (int)anwcs_imageh(outwcs));

	coadd = coadd_new(anwcs_imagew(outwcs), anwcs_imageh(outwcs));

	coadd->wcs = outwcs;

	if (nearest) {
		coadd->resample_func = nearest_resample_f;
		coadd->resample_token = NULL;
	} else {
		coadd->resample_func = lanczos_resample_f;
		largs.order = order;
		coadd->resample_token = &largs;
	}

	for (i=0; i<sl_size(inimgfns); i++) {
        anqfits_t* anq;
        anqfits_t* wanq;
		float* img;
		float* wt = NULL;
		anwcs_t* inwcs;
		char* fn;
		int ext;
		float overallwt = 1.0;
        int W, H;

		fn = sl_get(inimgfns, i);
		ext = il_get(inimgexts, i);
		logmsg("Reading input image \"%s\" ext %i\n", fn, ext);

        anq = anqfits_open(fn);
        if (!anq) {
            ERROR("Failed to open file \"%s\"\n", fn);
            exit(-1);
        }

        img = anqfits_readpix(anq, ext, 0, 0, 0, 0, plane,
                              PTYPE_FLOAT, NULL, &W, &H);
        if (!img) {
            ERROR("Failed to read image from ext %i of %s\n", ext, fn);
            exit(-1);
        }
        anqfits_close(anq);
		logmsg("Read image: %i x %i.\n", W, H);

		if (sigma > 0.0) {
			int k0, nk;
			float* kernel;
			logmsg("Smoothing by Gaussian with sigma=%g\n", sigma);
			kernel = convolve_get_gaussian_kernel_f(sigma, 4, &k0, &nk);
			convolve_separable_f(img, W, H, kernel, k0, nk, img, NULL);
			free(kernel);
		}

		fn = sl_get(inwcsfns, i);
		ext = il_get(inwcsexts, i);
		logmsg("Reading input WCS file \"%s\" ext %i\n", fn, ext);

		inwcs = anwcs_open(fn, ext);
		if (!inwcs) {
			ERROR("Failed to read WCS from file \"%s\" ext %i\n", fn, ext);
			exit(-1);
		}
		if (anwcs_pixel_scale(inwcs) == 0) {
			ERROR("Pixel scale from the WCS file is zero.  Usually this means the image has no valid WCS header.\n");
			exit(-1);
		}
		if (anwcs_imagew(inwcs) != W || anwcs_imageh(inwcs) != H) {
			ERROR("Size mismatch between image and WCS!");
			exit(-1);
		}

		fn = sl_get(inwtfns, i);
		ext = il_get(inwtexts, i);
		if (streq(fn, "none")) {
			logmsg("Not using weight image.\n");
			wt = NULL;
		} else if (file_exists(fn)) {
			logmsg("Reading input weight image \"%s\" ext %i\n", fn, ext);
            wanq = anqfits_open(fn);
            if (!wanq) {
                ERROR("Failed to open file \"%s\"\n", fn);
                exit(-1);
            }
            int wtW, wtH;
            wt = anqfits_readpix(anq, ext, 0, 0, 0, 0, 0,
                              PTYPE_FLOAT, NULL, &wtW, &wtH);
            if (!wt) {
                ERROR("Failed to read image from ext %i of %s\n", ext, fn);
                exit(-1);
            }
            anqfits_close(wanq);
			logmsg("Read image: %i x %i.\n", wtW, wtH);
			if (wtW != W || wtH != H) {
				ERROR("Size mismatch between image and weight!");
				exit(-1);
			}
		} else {
			char* endp;
			overallwt = strtod(fn, &endp);
			if (endp == fn) {
				ERROR("Weight: \"%s\" is neither a file nor a double.\n", fn);
				exit(-1);
			}
			logmsg("Parsed weight value \"%g\"\n", overallwt);
		}

		if (divweight && wt) {
			int j;
			logmsg("Dividing image by weight image...\n");
			for (j=0; j<(W*H); j++)
				img[j] /= wt[j];
		}

		coadd_add_image(coadd, img, wt, overallwt, inwcs);

		anwcs_free(inwcs);
        free(img);
		if (wt)
			free(wt);
	}

	//
	logmsg("Writing output: %s\n", outfn);

	coadd_divide_by_weight(coadd, 0.0);

	/*
	 if (fits_write_float_image_hdr(coadd->img, coadd->W, coadd->H, outfn)) {
	 ERROR("Failed to write output image %s", outfn);
	 exit(-1);
	 }
	 */
	/*
	 if (fits_write_float_image(coadd->img, coadd->W, coadd->H, outfn)) {
	 ERROR("Failed to write output image %s", outfn);
	 exit(-1);
	 }
	 */
	{
		qfitsdumper qoutimg;
		qfits_header* hdr;
		hdr = anqfits_get_header2(outwcsfn, outwcsext);
		if (!hdr) {
			ERROR("Failed to read WCS file \"%s\" ext %i\n", outwcsfn, outwcsext);
			exit(-1);
		}
		fits_header_mod_int(hdr, "NAXIS", 2, NULL);
		fits_header_set_int(hdr, "NAXIS1", coadd->W, "image width");
		fits_header_set_int(hdr, "NAXIS2", coadd->H, "image height");
		fits_header_modf(hdr, "BITPIX", "-32", "32-bit floats");
		memset(&qoutimg, 0, sizeof(qoutimg));
		qoutimg.filename = outfn;
		qoutimg.npix = coadd->W * coadd->H;
		qoutimg.fbuf = coadd->img;
		qoutimg.ptype = PTYPE_FLOAT;
		qoutimg.out_ptype = BPP_IEEE_FLOAT;
		if (fits_write_header_and_image(NULL, &qoutimg, coadd->W)) {
			ERROR("Failed to write FITS image to file \"%s\"", outfn);
			exit(-1);
		}
		qfits_header_destroy(hdr);
	}

	coadd_free(coadd);
	sl_free2(inimgfns);
	sl_free2(inwcsfns);
	sl_free2(inwtfns);
	il_free(inimgexts);
	il_free(inwcsexts);
	il_free(inwtexts);
	anwcs_free(outwcs);


	return 0;
}
コード例 #17
0
int main(int argc, char** args) {
    int c;
    char* rdlsfn = NULL;
    char* wcsfn = NULL;
    char* xylsfn = NULL;
    char* rcol = NULL;
    char* dcol = NULL;
    anbool forcetan = FALSE;
    il* fields;
    int ext = 0;
    double ra=HUGE_VAL, dec=HUGE_VAL;
    anbool wcslib = FALSE;
    int loglvl = LOG_MSG;

    fields = il_new(16);

    while ((c = getopt(argc, args, OPTIONS)) != -1) {
        switch (c) {
        case 'v':
            loglvl++;
            break;
        case 'L':
            wcslib = TRUE;
            break;
        case 'r':
            ra = atof(optarg);
            break;
        case 'd':
            dec = atof(optarg);
            break;
        case 'e':
            ext = atoi(optarg);
            break;
        case 'h':
            print_help(args[0]);
            exit(0);
        case 't':
            forcetan = TRUE;
            break;
        case 'o':
            xylsfn = optarg;
            break;
        case 'i':
            rdlsfn = optarg;
            break;
        case 'w':
            wcsfn = optarg;
            break;
        case 'f':
            il_append(fields, atoi(optarg));
            break;
        case 'R':
            rcol = optarg;
            break;
        case 'D':
            dcol = optarg;
            break;
        }
    }

    log_init(loglvl);

    if (optind != argc) {
        print_help(args[0]);
        exit(-1);
    }

    if (!(wcsfn && ((rdlsfn && xylsfn) || ((ra != HUGE_VAL) && (dec != HUGE_VAL))))) {
        print_help(args[0]);
        exit(-1);
    }

    if (!rdlsfn) {
        double x,y;
        anwcs_t* wcs = NULL;

        // read WCS.
        if (wcslib) {
            wcs = anwcs_open_wcslib(wcsfn, ext);
        } else if (forcetan) {
            wcs = anwcs_open_tan(wcsfn, ext);
        } else {
            wcs = anwcs_open(wcsfn, ext);
        }
        if (!wcs) {
            ERROR("Failed to read WCS file");
            exit(-1);
        }
        logverb("Read WCS:\n");
        if (log_get_level() >= LOG_VERB) {
            anwcs_print(wcs, log_get_fid());
        }

        // convert immediately.
        if (anwcs_radec2pixelxy(wcs, ra, dec, &x, &y)) {
            ERROR("The given RA,Dec is on the opposite side of the sky.");
            exit(-1);
        }
        printf("RA,Dec (%.10f, %.10f) -> pixel (%.10f, %.10f)\n", ra, dec, x, y);
        anwcs_free(wcs);
        exit(0);
    }


    if (wcs_rd2xy(wcsfn, ext, rdlsfn, xylsfn,
                  rcol, dcol, forcetan, wcslib, fields)) {
        ERROR("wcs-rd2xy failed");
        exit(-1);
    }

    return 0;
}
コード例 #18
0
int main(int argc, char** args) {
    int c;
    FILE* fconst = NULL;
    uint32_t nstars;
    size_t mapsize;
    void* map;
    unsigned char* hip;
    FILE* fhip = NULL;
    int i;
	pl* cstars;
	il* alluniqstars;
	sl* shortnames;

    while ((c = getopt(argc, args, OPTIONS)) != -1) {
        switch (c) {
        case 'h':
            print_help(args[0]);
            exit(0);
        }
    }

    if (optind != argc) {
        print_help(args[0]);
        exit(-1);
    }

	for (i=0; i<sizeof(const_dirs)/sizeof(char*); i++) {
		char fn[256];
		snprintf(fn, sizeof(fn), "%s/%s", const_dirs[i], constfn);
		fprintf(stderr, "render_constellation: Trying file: %s\n", fn);
		fconst = fopen(fn, "rb");
		if (fconst)
			break;
	}
	if (!fconst) {
		fprintf(stderr, "render_constellation: couldn't open any constellation files.\n");
		return -1;
	}

	for (i=0; i<sizeof(hip_dirs)/sizeof(char*); i++) {
		char fn[256];
		snprintf(fn, sizeof(fn), "%s/%s", hip_dirs[i], hipparcos_fn);
		fprintf(stderr, "render_constellation: Trying hip file: %s\n", fn);
		fhip = fopen(fn, "rb");
		if (fhip)
			break;
	}
	if (!fhip) {
		fprintf(stderr, "render_constellation: unhip\n");
		return -1;
	}

	// first 32-bit int: 
	if (fread(&nstars, 4, 1, fhip) != 1) {
		fprintf(stderr, "render_constellation: failed to read nstars.\n");
		return -1;
	}
	v32_letoh(&nstars);
	fprintf(stderr, "render_constellation: Found %i Hipparcos stars\n", nstars);

	mapsize = nstars * HIP_SIZE + HIP_OFFSET;
	map = mmap(0, mapsize, PROT_READ, MAP_SHARED, fileno(fhip), 0);
	hip = ((unsigned char*)map) + HIP_OFFSET;

	// for each constellation, its il* of lines.
	cstars = pl_new(16);
	alluniqstars = il_new(16);
	shortnames = sl_new(16);

	for (c=0;; c++) {
		char shortname[16];
		int nlines;
		int i;
		il* stars;

		if (feof(fconst))
			break;

		if (fscanf(fconst, "%s %d ", shortname, &nlines) != 2) {
			fprintf(stderr, "failed to parse name+nlines (constellation %i)\n", c);
			fprintf(stderr, "file offset: %i (%x)\n",
					(int)ftello(fconst), (int)ftello(fconst));
			return -1;
		}
		//fprintf(stderr, "Name: %s.  Nlines %i.\n", shortname, nlines);

		stars = il_new(16);

		sl_append(shortnames, shortname);
		pl_append(cstars, stars);

		for (i=0; i<nlines; i++) {
			int star1, star2;

			if (fscanf(fconst, " %d %d", &star1, &star2) != 2) {
				fprintf(stderr, "failed parse star1+star2\n");
				return -1;
			}

			il_insert_unique_ascending(alluniqstars, star1);
			il_insert_unique_ascending(alluniqstars, star2);

			il_append(stars, star1);
			il_append(stars, star2);
		}
		fscanf(fconst, "\n");
	}
	fprintf(stderr, "render_constellations: Read %i constellations.\n", c);

	printf("static const int constellations_N = %i;\n", sl_size(shortnames));

	/*
	  for (c=0; c<sl_size(shortnames); c++) {
	  printf("static const char* shortname_%i = \"%s\";\n", c, sl_get(shortnames, c));
	  }
	  printf("static const char* shortnames[] = {");
	  for (c=0; c<sl_size(shortnames); c++) {
	  printf("shortname_%i,", c);
	  }
	  printf("};\n");
	*/
	printf("static const char* shortnames[] = {");
	for (c=0; c<sl_size(shortnames); c++) {
		printf("\"%s\",", sl_get(shortnames, c));
	}
	printf("};\n");

	printf("static const int constellation_nlines[] = {");
	for (c=0; c<pl_size(cstars); c++) {
		il* stars = pl_get(cstars, c);
		printf("%i,", il_size(stars)/2);
	}
	printf("};\n");

	for (c=0; c<pl_size(cstars); c++) {
		il* stars = pl_get(cstars, c);
		printf("static const int constellation_lines_%i[] = {", c);
		for (i=0; i<il_size(stars); i++) {
			int s = il_get(stars, i);
			int ms = il_index_of(alluniqstars, s);
			printf("%s%i", (i?",":""), ms);
		}
		printf("};\n");
	}

	printf("static const int* constellation_lines[] = {");
	for (c=0; c<pl_size(cstars); c++) {
		printf("constellation_lines_%i,", c);
	}
	printf("};\n");

	printf("static const int stars_N = %i;\n", il_size(alluniqstars));

	printf("static const double star_positions[] = {");
	for (i=0; i<il_size(alluniqstars); i++) {
		int s = il_get(alluniqstars, i);
		double ra, dec;
		hip_get_radec(hip, s, &ra, &dec);
		printf("%g,%g,", ra, dec);
	}
	printf("};\n");

	munmap(map, mapsize);
	
	fclose(fconst);
	fclose(fhip);

	return 0;
}
コード例 #19
0
ファイル: wcs-rd2xy.c プロジェクト: blackball/an-test6
int wcs_rd2xy(const char* wcsfn, int wcsext,
			  const char* rdlsfn, const char* xylsfn,
              const char* racol, const char* deccol,
			  anbool forcetan, anbool forcewcslib,
              il* fields) {
	xylist_t* xyls = NULL;
	rdlist_t* rdls = NULL;
	anwcs_t* wcs = NULL;
	int i;
    anbool alloced_fields = FALSE;
    int rtn = -1;

	// read WCS.
	if (forcewcslib) {
		wcs = anwcs_open_wcslib(wcsfn, wcsext);
	} else if (forcetan) {
		wcs = anwcs_open_tan(wcsfn, wcsext);
	} else {
		wcs = anwcs_open(wcsfn, wcsext);
	}
	if (!wcs) {
		ERROR("Failed to read WCS file \"%s\", extension %i", wcsfn, wcsext);
		return -1;
	}

	// read RDLS.
	rdls = rdlist_open(rdlsfn);
	if (!rdls) {
		ERROR("Failed to read an RA,Dec list from file %s", rdlsfn);
        goto bailout;
	}
	if (racol)
        rdlist_set_raname(rdls, racol);
	if (deccol)
		rdlist_set_decname(rdls, deccol);

	// write XYLS.
	xyls = xylist_open_for_writing(xylsfn);
	if (!xyls) {
		ERROR("Failed to open file %s to write XYLS", xylsfn);
        goto bailout;
	}
	if (xylist_write_primary_header(xyls)) {
		ERROR("Failed to write header to XYLS file %s", xylsfn);
        goto bailout;
	}

    if (!fields) {
        alloced_fields = TRUE;
        fields = il_new(16);
    }
	if (!il_size(fields)) {
		// add all fields.
		int NF = rdlist_n_fields(rdls);
		for (i=1; i<=NF; i++)
			il_append(fields, i);
	}

	for (i=0; i<il_size(fields); i++) {
		int fieldnum = il_get(fields, i);
		int j;
        starxy_t xy;
        rd_t rd;

        if (!rdlist_read_field_num(rdls, fieldnum, &rd)) {
			ERROR("Failed to read rdls file \"%s\" field %i", rdlsfn, fieldnum);
            goto bailout;
        }

        starxy_alloc_data(&xy, rd_n(&rd), FALSE, FALSE);

		if (xylist_write_header(xyls)) {
			ERROR("Failed to write xyls field header");
            goto bailout;
		}

		for (j=0; j<rd_n(&rd); j++) {
			double x, y, ra, dec;
            ra  = rd_getra (&rd, j);
            dec = rd_getdec(&rd, j);
			if (anwcs_radec2pixelxy(wcs, ra, dec, &x, &y)) {
				ERROR("Point RA,Dec = (%g,%g) projects to the opposite side of the sphere", ra, dec);
				starxy_set(&xy, j, NAN, NAN);
				continue;
			}
            starxy_set(&xy, j, x, y);
		}
        if (xylist_write_field(xyls, &xy)) {
            ERROR("Failed to write xyls field");
            goto bailout;
        }
		if (xylist_fix_header(xyls)) {
            ERROR("Failed to fix xyls field header");
            goto bailout;
		}
        xylist_next_field(xyls);

        starxy_free_data(&xy);
        rd_free_data(&rd);
	}

	if (xylist_fix_primary_header(xyls) ||
		xylist_close(xyls)) {
		ERROR("Failed to fix header of XYLS file");
        goto bailout;
	}
    xyls = NULL;

	if (rdlist_close(rdls)) {
		ERROR("Failed to close RDLS file");
        goto bailout;
	}
    rdls = NULL;

    rtn = 0;

 bailout:
    if (alloced_fields)
        il_free(fields);
    if (rdls)
        rdlist_close(rdls);
    if (xyls)
        xylist_close(xyls);
	if (wcs)
		anwcs_free(wcs);
    return rtn;
}
コード例 #20
0
ファイル: wcs-xy2rd-main.c プロジェクト: rasmi/astrometry.net
int main(int argc, char** args) {
	int c;
	char* rdlsfn = NULL;
	char* wcsfn = NULL;
	char* xylsfn = NULL;
	char* xcol = NULL;
	char* ycol = NULL;
	anbool forcetan = FALSE;
	anbool forcewcslib = FALSE;
	anbool forcewcstools = FALSE;
	anbool printhms = FALSE;
	il* fields;
	int ext = 0;
	double x, y;
	int loglvl = LOG_MSG;

	x = y = HUGE_VAL;
	fields = il_new(16);

    while ((c = getopt(argc, args, OPTIONS)) != -1) {
        switch (c) {
		case 'v':
			loglvl++;
			break;
		case 's':
			printhms = TRUE;
			break;
		case 'L':
			forcewcslib = TRUE;
			break;
		case 'T':
			forcewcstools = TRUE;
			break;
		case 'x':
			x = atof(optarg);
			break;
		case 'y':
			y = atof(optarg);
			break;
		case 'e':
			ext = atoi(optarg);
			break;
        case 'h':
			print_help(args[0]);
			exit(0);
		case 't':
			forcetan = TRUE;
			break;
		case 'o':
			rdlsfn = optarg;
			break;
		case 'i':
			xylsfn = optarg;
			break;
		case 'w':
			wcsfn = optarg;
			break;
		case 'f':
			il_append(fields, atoi(optarg));
			break;
		case 'X':
			xcol = optarg;
			break;
		case 'Y':
			ycol = optarg;
			break;
		}
	}

	log_init(loglvl);

	if (optind != argc) {
		print_help(args[0]);
		exit(-1);
	}

	if (!(wcsfn && ((rdlsfn && xylsfn) || ((x != HUGE_VAL) && (y != HUGE_VAL))))) {
		print_help(args[0]);
		exit(-1);
	}

	if (!xylsfn) {
		double ra,dec;
		anwcs_t* wcs = NULL;

		// read WCS.
		if (forcewcslib) {
			wcs = anwcs_open_wcslib(wcsfn, ext);
		} else if (forcewcstools) {
			wcs = anwcs_open_wcstools(wcsfn, ext);
		} else if (forcetan) {
			wcs = anwcs_open_tan(wcsfn, ext);
		} else {
			wcs = anwcs_open(wcsfn, ext);
		}
		if (!wcs) {
			ERROR("Failed to read WCS file \"%s\", extension %i", wcsfn, ext);
			exit(-1);
		}

		logverb("Read WCS:\n");
		if (log_get_level() >= LOG_VERB) {
			anwcs_print(wcs, log_get_fid());
		}

		// convert immediately.
		anwcs_pixelxy2radec(wcs, x, y, &ra, &dec);
		printf("Pixel (%.10f, %.10f) -> RA,Dec (%.10f, %.10f)\n", x, y, ra, dec);
		if (printhms) {
			char str[32];
			ra2hmsstring(ra, str);
			printf("                       RA,Dec (%20s, ", str);
			dec2dmsstring(dec, str);
			printf("%20s)\n", str);
		}
		anwcs_free(wcs);
		exit(0);
	}

    if (wcs_xy2rd(wcsfn, ext, xylsfn, rdlsfn, 
                  xcol, ycol, forcetan, forcewcslib, fields)) {
        ERROR("wcs-xy2rd failed");
        exit(-1);
    }

	return 0;
}
コード例 #21
0
static void dualtree_rs_recurse(kdtree_t* xtree, kdtree_t* ytree,
								il* xnodes, il* xleaves,
								bl* xnodebbs, bl* xleafbbs,
								int ynode,
								ttype* ybb,
								double maxd2,
								rangesearch_callback cb, void* baton) {
	int leafmarker;
	il* childnodes;
	int i, N;
	ttype oldbbval;
	ttype splitval;
	uint8_t splitdim;

	// if the query node is a leaf...
	if (KD_IS_LEAF(ytree, ynode)) {
		// ... then run the result function on each x node
		/*
		 if (callbacks->start_results)
		 callbacks->start_results(callbacks->start_extra, ytree, ynode);
		 */
		if (cb) {
			// non-leaf nodes
			N = il_size(xnodes);
			for (i=0; i<N; i++)
				dtrs_nodes(xtree, ytree, il_get(xnodes, i), ynode, maxd2, cb, baton);
		    // leaf nodes
			N = il_size(xleaves);
			for (i=0; i<N; i++)
				dtrs_nodes(xtree, ytree, il_get(xleaves, i), ynode, maxd2, cb, baton);
		}
		/*
		 if (callbacks->end_results)
		 callbacks->end_results(callbacks->end_extra, ytree, ynode);
		 */
		return;
	}

	// if there are search leaves but no search nodes, run the result
	// function on each leaf.  (Note that the query node is not a leaf!)
	if (!il_size(xnodes)) {
		/*
		 result_function result = callbacks->result;
		 void* result_extra = callbacks->result_extra;
		 if (callbacks->start_results)
		 callbacks->start_results(callbacks->start_extra, ytree, ynode);
		 */
		// leaf nodes
		if (result) {
			N = il_size(xleaves);
			for (i=0; i<N; i++)
				dtrs_nodes(xtree, ytree, il_get(xleaves, i), ynode, maxd2, cb, baton);
			//result(result_extra, xtree, il_get(leaves, i), ytree, ynode);
		}
		/*
		 if (callbacks->end_results)
		 callbacks->end_results(callbacks->end_extra, ytree, ynode);
		 */
		return;
	}

	leafmarker = il_size(leaves);
	childnodes = il_new(256);

#define BBLO(bb, d) ((bb)[2*(d)])
#define BBHI(bb, d) ((bb)[(2*(d))+1])

	N = il_size(xnodes);
	for (i=0; i<N; i++) {
		int child1, child2;
		int xnode = il_get(xnodes, i);
		ttype* xbb = bl_access(xnodebbs, i);
		ttype* leftbb;
		ttype* rightbb;

		/*
		 node-node range...
		 if (!decision(decision_extra, xtree, xnode, ytree, ynode))
		 continue;
		 */
		split_dim_and_value(xtree, xnode, &splitdim, &splitval);
		child1 = KD_CHILD_LEFT(xnode);
		if (KD_IS_LEAF(xtree, child1)) {
			il_append(xleaves, child1);
			il_append(xleaves, child2);
			leftbb  = bl_append(xleafbbs, xbb);
			rightbb = bl_append(xleafbbs, xbb);
		} else {
			il_append(childnodes, child1);
			il_append(childnodes, child2);
			leftbb  = bl_append(xnodebbs, xbb);
			rightbb = bl_append(xnodebbs, xbb);
		}
		BBHI(leftbb,  splitdim) = splitval;
		BBLO(rightbb, splitdim) = splitval;
	}

	printf("dualtree: start left child of y node %i: %i\n", ynode, KD_CHILD_LEFT(ynode));
	// recurse on the Y children!
	split_dim_and_value(ytree, ynode, &splitdim, &splitval);
	// update y bb for the left child: max(splitdim) = splitval
	oldbbval = BBHI(ybb, splitdim);
	BBHI(ybb, splitdim) = splitval;
	dualtree_recurse(xtree, ytree, childnodes, leaves,
					 KD_CHILD_LEFT(ynode), callbacks);
	BBHI(ybb, splitdim) = oldbbval;
	printf("dualtree: done left child of y node %i: %i\n", ynode, KD_CHILD_LEFT(ynode));

	printf("dualtree: start right child of y node %i: %i\n", ynode, KD_CHILD_RIGHT(ynode));
	// update y bb for the right child: min(splitdim) = splitval
	oldbbval = BBLO(ybb, splitdim);
	BBLO(ybb, splitdim) = splitval;
	dualtree_recurse(xtree, ytree, childnodes, leaves,
					 KD_CHILD_RIGHT(ynode), callbacks);
	BBLO(ybb, splitdim) = oldbbval;
	printf("dualtree: done right child of y node %i: %i\n", ynode, KD_CHILD_LEFT(ynode));

	// put the "leaves" list back the way it was...
	il_remove_index_range(leaves, leafmarker, il_size(leaves)-leafmarker);
	il_free(childnodes);
}
コード例 #22
0
ファイル: dfind2.c プロジェクト: olebole/astrometry.net
int DFIND2(const IMGTYPE* image,
           int nx,
           int ny,
           int* object,
		   int* pnobjects) {
	int ix, iy, i;
	int maxgroups = initial_max_groups;
	label_t *equivs = malloc(sizeof(label_t) * maxgroups);
	int maxlabel = 0;

	/* Keep track of 'on' pixels to avoid later rescanning */
    il* on_pixels = il_new(256);

	/* Find blobs and track equivalences */
	for (iy = 0; iy < ny; iy++) {
		for (ix = 0; ix < nx; ix++) {
			int thislabel, thislabelmin;

			object[nx*iy+ix] = -1;
			if (!image[nx*iy+ix])
				continue;

			/* Store location of each 'on' pixel. */
            il_append(on_pixels, nx * iy + ix);

            /* If the pixel to the left [exists and] is on, this pixel
             joins its group. */
			if (ix && image[nx*iy+ix-1]) {
				/* Old group */
				object[nx*iy+ix] = object[nx*iy+ix-1];

			} else {
				/* New blob */
				// FIXME this part should become uf_new_group()
				if (maxlabel >= maxgroups) {
					maxgroups *= 2;
					equivs = realloc(equivs, sizeof(label_t) * maxgroups);
					assert(equivs);
				}
				object[nx*iy+ix] = maxlabel;
				equivs[maxlabel] = maxlabel;
				maxlabel++;

				if (maxlabel == LABEL_MAX) {
                    logverb("Ran out of labels.  Relabelling...\n");
                    maxlabel = relabel_image(on_pixels, maxlabel, equivs, object);
                    logverb("After relabelling, we need %i labels\n", maxlabel);
                    if (maxlabel == LABEL_MAX) {
                        ERROR("Ran out of labels.");
                        exit(-1);
                    }
				}
			}

			thislabel  = object[nx*iy + ix];

			/* Compute minimum equivalence label for this pixel */
			thislabelmin = collapsing_find_minlabel(thislabel, equivs);

			if (iy == 0)
				continue;

			/* Check three pixels above this one which are 'neighbours' */
			for (i = MAX(0, ix - 1); i <= MIN(ix + 1, nx - 1); i++) {
				if (image[nx*(iy-1)+i]) {
					int otherlabel = object[nx*(iy-1) + i];

					/* Find min of the other */
					int otherlabelmin = collapsing_find_minlabel(otherlabel, equivs);

					/* Merge groups if necessary */
					if (thislabelmin != otherlabelmin) {
						int oldlabelmin = MAX(thislabelmin, otherlabelmin);
						int newlabelmin = MIN(thislabelmin, otherlabelmin);
						thislabelmin = newlabelmin;
						equivs[oldlabelmin] = newlabelmin;
						equivs[thislabel] = newlabelmin;
						/* Update other pixel too */
						object[nx*(iy-1) + i] = newlabelmin;
					} 
				}
			}
			object[nx*iy + ix] = thislabelmin;
		}
	}

	/* Re-label the groups before returning */
    maxlabel = relabel_image(on_pixels, maxlabel, equivs, object);
    //logverb("After final relabelling, %i labels were used.\n", maxlabel);
	if (pnobjects)
		*pnobjects = maxlabel;

	free(equivs);
	il_free(on_pixels);
	return 1;
}
コード例 #23
0
ファイル: solvedfile.c プロジェクト: Carl4/astrometry.net
// lastfield = 0 for no limit.
static il* solvedfile_getall_val(char* fn, int firstfield, int lastfield, int maxfields, int val) {
	FILE* f;
	off_t end;
	int fields = 0;
	il* list;
	int i;
	unsigned char* map;

	list = il_new(256);

	f = fopen(fn, "rb");
	if (!f) {
		// if file doesn't exist, assume no fields are solved.
		if (val == 0) {
			for (i=firstfield; i<=lastfield; i++) {
				il_append(list, i);
				fields++;
				if (fields == maxfields)
					break;
			}
		}
		return list;
	}

	if (fseek(f, 0, SEEK_END) ||
		((end = ftello(f)) == -1)) {
		fprintf(stderr, "Error: seeking to end of file %s: %s\n",
				fn, strerror(errno));
		fclose(f);
		il_free(list);
		return NULL;
	}
    // 1-index
    firstfield--;
    lastfield--;
	if (end <= firstfield) {
		fclose(f);
		return list;
	}

	map = mmap(NULL, end, PROT_READ, MAP_SHARED, fileno(f), 0);
	fclose(f);
	if (map == MAP_FAILED) {
		fprintf(stderr, "Error: couldn't mmap file %s: %s\n", fn, strerror(errno));
		il_free(list);
		return NULL;
	}

	for (i=firstfield; ((lastfield == -1) || (i<=lastfield)) && (i < end); i++) {
		if (map[i] == val) {
            // 1-index
			il_append(list, i+1);
			if (il_size(list) == maxfields)
				break;
		}
	}

	munmap(map, end);

	if (val == 0) {
		// fields larger than the file size are unsolved.
		for (i=end; i<=lastfield; i++) {
			if (il_size(list) == maxfields)
				break;
            // 1-index
			il_append(list, i+1);
		}
	}
	return list;
}
コード例 #24
0
ファイル: test_bl.c プロジェクト: Carl4/astrometry.net
void test_big_list(CuTest* tc) {
    // Test size_t sizes and indices of bl's.
    // Test ptrdiff_t as -1 or index
    CuAssertTrue(tc, -1 == BL_NOT_FOUND);
    CuAssertTrue(tc, BL_NOT_FOUND < 0);
    CuAssertTrue(tc, sizeof(size_t) == sizeof(ptrdiff_t));

    // Create a fake list so we don't have to allocate 16 GB of list to test.
    int blocksize = 1048576;
    il* big = il_new(blocksize);
    // that's 1<<20 ~ 1e6 elements per block

    // now need 1<<12 ~ 4096 blocks to overflow a 32-bit int
    int i;
    int N = 4096;
    bl_node* nodes = calloc(N, sizeof(bl_node));
    for (i=1; i<N; i++) {
        nodes[i-1].next = nodes+i;
        nodes[i-1].N = blocksize;
    }
    nodes[N-1].N = blocksize;
    big->head = nodes;
    big->tail = nodes + (N-1);
    big->N = (size_t)blocksize * (size_t)N;

    bl_print_structure(big);

    printf("N %zu\n", il_size(big));
    printf("check: %s\n", (bl_check_consistency(big) ? "bad" : "ok"));

    int* p = il_append(big, 42);
    printf("appended: %i\n", *p);
    CuAssertIntEquals(tc, 42, *p);
    CuAssertTrue(tc, 4294967297L == il_size(big));

    size_t index = 4294967296L;
    int v = il_get(big, index);
    CuAssertIntEquals(tc, 42, v);

    big->last_access = NULL;
    big->last_access_n = 0;

    v = il_get(big, index);
    CuAssertIntEquals(tc, 42, v);

    for (i=0; i<blocksize*2; i++) {
        il_push(big, i);
    }

    il* split = il_new(1024);

    bl_split(big, split, (size_t)blocksize * (size_t)N);

    printf("split: %zu, %zu\n", il_size(big), il_size(split));
    CuAssertIntEquals(tc, 42, il_get(split, 0));
    CuAssertIntEquals(tc, 3, il_get(split, 4));

    il_append_list(big, split);

    CuAssertTrue(tc, 4297064449L == il_size(big));

    int* arr = calloc(1024, sizeof(int));

    bl_copy(big, (size_t)blocksize * (size_t)N, 1024, arr);

    CuAssertIntEquals(tc, 42, arr[0]);
    CuAssertIntEquals(tc,  3, arr[4]);
}
コード例 #25
0
ファイル: wcs-xy2rd.c プロジェクト: Carl4/astrometry.net
int wcs_xy2rd(const char* wcsfn, int ext,
			  const char* xylsfn, const char* rdlsfn,
              const char* xcol, const char* ycol,
			  int forcetan,
			  int forcewcslib,
              il* fields) {
	rdlist_t* rdls = NULL;
	xylist_t* xyls = NULL;
	anwcs_t* wcs = NULL;
	int i;
    int rtn = -1;
    anbool alloced_fields = FALSE;

	// read WCS.
	if (forcewcslib) {
		wcs = anwcs_open_wcslib(wcsfn, ext);
	} else if (forcetan) {
		wcs = anwcs_open_tan(wcsfn, ext);
	} else {
		wcs = anwcs_open(wcsfn, ext);
	}
	if (!wcs) {
		ERROR("Failed to read WCS file \"%s\", extension %i", wcsfn, ext);
		return -1;
	}

	// read XYLS.
	xyls = xylist_open(xylsfn);
	if (!xyls) {
		ERROR("Failed to read an xylist from file %s", xylsfn);
		goto bailout;
	}
    xylist_set_include_flux(xyls, FALSE);
    xylist_set_include_background(xyls, FALSE);
	if (xcol)
		xylist_set_xname(xyls, xcol);
	if (ycol)
		xylist_set_yname(xyls, ycol);

	// write RDLS.
	rdls = rdlist_open_for_writing(rdlsfn);
	if (!rdls) {
		ERROR("Failed to open file %s to write RDLS.\n", rdlsfn);
		goto bailout;
	}
	if (rdlist_write_primary_header(rdls)) {
		ERROR("Failed to write header to RDLS file %s.\n", rdlsfn);
		goto bailout;
	}

    if (!fields) {
        alloced_fields = TRUE;
        fields = il_new(16);
    }
	if (!il_size(fields)) {
		// add all fields.
		int NF = xylist_n_fields(xyls);
		for (i=1; i<=NF; i++)
			il_append(fields, i);
	}

	logverb("Processing %zu extensions...\n", il_size(fields));
	for (i=0; i<il_size(fields); i++) {
		int fieldind = il_get(fields, i);
        starxy_t xy;
        rd_t rd;
		int j;

        if (!xylist_read_field_num(xyls, fieldind, &xy)) {
			ERROR("Failed to read xyls file %s, field %i", xylsfn, fieldind);
			goto bailout;
        }

		if (rdlist_write_header(rdls)) {
			ERROR("Failed to write rdls field header to %s", rdlsfn);
			goto bailout;
		}

        rd_alloc_data(&rd, starxy_n(&xy));

		for (j=0; j<starxy_n(&xy); j++) {
            double x, y, ra, dec;
            x = starxy_getx(&xy, j);
            y = starxy_gety(&xy, j);
			anwcs_pixelxy2radec(wcs, x, y, &ra, &dec);
            rd_setra (&rd, j, ra);
            rd_setdec(&rd, j, dec);
		}

        if (rdlist_write_field(rdls, &rd)) {
            ERROR("Failed to write rdls field to %s", rdlsfn);
			goto bailout;
        }
        rd_free_data(&rd);
        starxy_free_data(&xy);

		if (rdlist_fix_header(rdls)) {
			ERROR("Failed to fix rdls field header for %s", rdlsfn);
			goto bailout;
		}

        rdlist_next_field(rdls);
	}

	if (rdlist_fix_primary_header(rdls) ||
		rdlist_close(rdls)) {
		ERROR("Failed to fix header of RDLS file %s", rdlsfn);
		goto bailout;
	}
	rdls = NULL;

	if (xylist_close(xyls)) {
		ERROR("Failed to close XYLS file %s", xylsfn);
		goto bailout;
	}
	xyls = NULL;
	rtn = 0;

 bailout:
    if (alloced_fields)
        il_free(fields);
    if (rdls)
        rdlist_close(rdls);
    if (xyls)
        xylist_close(xyls);
	if (wcs)
		anwcs_free(wcs);
    return rtn;
}
コード例 #26
0
ファイル: wcs-pv2sip.c プロジェクト: blackball/an-test6
int wcs_pv2sip(const char* wcsinfn, int ext,
			   const char* wcsoutfn,
			   anbool scamp_head_file,
			   double* xy, int Nxy,
			   int imageW, int imageH,
			   anbool forcetan) {
	qfits_header* hdr = NULL;
	double* radec = NULL;
	int rtn = -1;
	tan_t tanwcs;
	double x,y, px,py;
	double xyz[3];

	double* xorig = NULL;
	double* yorig = NULL;
	double* rddist = NULL;
	int i, j;

	//           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, 5, 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, 0, 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;

	if (scamp_head_file) {
		size_t sz = 0;
		char* txt;
		char* prefix;
		int np;
		int nt;
		unsigned char* txthdr;
		sl* lines;
		int i;
		txt = file_get_contents(wcsinfn, &sz, TRUE);
		if (!txt) {
			ERROR("Failed to read file %s", wcsinfn);
			goto bailout;
		}
		lines = sl_split(NULL, txt, "\n");
		prefix =
			"SIMPLE  =                    T / Standard FITS file                             "
			"BITPIX  =                    8 / ASCII or bytes array                           "
			"NAXIS   =                    0 / Minimal header                                 "
			"EXTEND  =                    T / There may be FITS ext                          "
			"WCSAXES =                    2 /                                                ";
		np = strlen(prefix);
		nt = np + FITS_LINESZ * sl_size(lines);
		txthdr = malloc(nt);
		memset(txthdr, ' ', np + FITS_LINESZ * sl_size(lines));
		memcpy(txthdr, prefix, np);
		for (i=0; i<sl_size(lines); i++)
			memcpy(txthdr + np + i*FITS_LINESZ, sl_get(lines, i), strlen(sl_get(lines, i)));
		sl_free2(lines);
		hdr = qfits_header_read_hdr_string(txthdr, nt);
		free(txthdr);
		free(txt);
	} else {
		char* ct;
		hdr = anqfits_get_header2(wcsinfn, ext);

		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");
		}
	}
	if (!hdr) {
		ERROR("Failed to read header: file %s, ext %i\n", wcsinfn, ext);
		goto bailout;
	}
	
	tan_read_header(hdr, &tanwcs);

	for (i=0; i<sizeof(pv1)/sizeof(double); i++) {
		char key[10];
		sprintf(key, "PV1_%i", i);
		pv1[i] = qfits_header_getdouble(hdr, key, 0.0);
		sprintf(key, "PV2_%i", i);
		pv2[i] = qfits_header_getdouble(hdr, key, 0.0);
	}

	xorig = malloc(Nxy * sizeof(double));
	yorig = malloc(Nxy * sizeof(double));
	rddist = malloc(2 * Nxy * sizeof(double));

	for (j=0; j<Nxy; j++) {
		xorig[j] = xy[2*j+0];
		yorig[j] = xy[2*j+1];

		tan_pixelxy2iwc(&tanwcs, xorig[j], yorig[j], &x, &y);
		r = sqrt(x*x + y*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]];
			py += pv2[i] * ypows[xp[i]] * xpows[yp[i]] * rpows[rp[i]];
		}
		tan_iwc2xyzarr(&tanwcs, px, py, xyz);
		xyzarr2radecdeg(xyz, rddist+2*j, rddist+2*j+1);
	}

	//
	{
		starxy_t sxy;
		tweak_t* t;
		il* imgi;
		il* refi;
		int sip_order = 5;
		int sip_inv_order = 5;

		sxy.N = Nxy;
		sxy.x = xorig;
		sxy.y = yorig;

		imgi = il_new(256);
		refi = il_new(256);
		for (i=0; i<Nxy; i++) {
			il_append(imgi, i);
			il_append(refi, i);
		}

		t = tweak_new();
		t->sip->a_order = t->sip->b_order = sip_order;
		t->sip->ap_order = t->sip->bp_order = sip_inv_order;
		tweak_push_wcs_tan(t, &tanwcs);
		tweak_push_ref_ad_array(t, rddist, Nxy);
		tweak_push_image_xy(t, &sxy);
		tweak_push_correspondence_indices(t, imgi, refi, NULL, NULL);
		tweak_go_to(t, TWEAK_HAS_LINEAR_CD);
		if (imageW)
			t->sip->wcstan.imagew = imageW;
		if (imageH)
			t->sip->wcstan.imageh = imageH;
		sip_write_to_file(t->sip, wcsoutfn);
		tweak_free(t);
	}
	rtn = 0;

 bailout:
	free(xorig);
	free(yorig);
	free(rddist);
	qfits_header_destroy(hdr);
	free(radec);
	return rtn;
}
コード例 #27
0
ファイル: keirthing.c プロジェクト: Carl4/astrometry.net
int main(int argc, char** args) {
	int c;
	dl* xys = dl_new(16);
	dl* radecs = dl_new(16);
	dl* otherradecs = dl_new(16);

	double* xy;
	double* xyz;
	int i, N;
	tan_t tan, tan2, tan3;
	int W=0, H=0;
	double crpix[] = { HUGE_VAL, HUGE_VAL };
	int loglvl = LOG_MSG;
	FILE* logstream = stderr;
	int order = 1;

    while ((c = getopt(argc, args, OPTIONS)) != -1) {
        switch (c) {
		case 'v':
			loglvl++;
			break;
		case 'h':
			exit(0);
		case 'o':
			order = atoi(optarg);
			break;
		case 'W':
			W = atoi(optarg);
			break;
		case 'H':
			H = atoi(optarg);
			break;
		case 'X':
			crpix[0] = atof(optarg);
			break;
		case 'Y':
			crpix[1] = atof(optarg);
			break;
		}
	}
	if (optind != argc) {
		exit(-1);
	}
	log_init(loglvl);
	log_to(logstream);
	errors_log_to(logstream);

	if (W == 0 || H == 0) {
		logerr("Need -W, -H\n");
		exit(-1);
	}
	if (crpix[0] == HUGE_VAL)
		crpix[0] = W/2.0;
	if (crpix[1] == HUGE_VAL)
		crpix[1] = H/2.0;

	while (1) {
		double x,y,ra,dec;
		if (fscanf(stdin, "%lf %lf %lf %lf\n", &x, &y, &ra, &dec) < 4)
			break;
		if (x == -1 && y == -1) {
			dl_append(otherradecs, ra);
			dl_append(otherradecs, dec);
		} else {
			dl_append(xys, x);
			dl_append(xys, y);
			dl_append(radecs, ra);
			dl_append(radecs, dec);
		}
	}
	logmsg("Read %i x,y,ra,dec tuples\n", dl_size(xys)/2);

	N = dl_size(xys)/2;
	xy = dl_to_array(xys);
	xyz = malloc(3 * N * sizeof(double));
	for (i=0; i<N; i++)
		radecdeg2xyzarr(dl_get(radecs, 2*i), dl_get(radecs, 2*i+1), xyz + i*3);
	dl_free(xys);
	dl_free(radecs);

	fit_tan_wcs(xyz, xy, N, &tan, NULL);
	tan.imagew = W;
	tan.imageh = H;

	logmsg("Computed TAN WCS:\n");
	tan_print_to(&tan, logstream);

	sip_t* sip;
	{
		tweak_t* t = tweak_new();
		starxy_t* sxy = starxy_new(N, FALSE, FALSE);
		il* imginds = il_new(256);
		il* refinds = il_new(256);

		for (i=0; i<N; i++) {
			starxy_set_x(sxy, i, xy[2*i+0]);
			starxy_set_y(sxy, i, xy[2*i+1]);
		}
		tweak_init(t);
		tweak_push_ref_xyz(t, xyz, N);
		tweak_push_image_xy(t, sxy);
		for (i=0; i<N; i++) {
			il_append(imginds, i);
			il_append(refinds, i);
		}
		// unweighted; no dist2s
		tweak_push_correspondence_indices(t, imginds, refinds, NULL, NULL);

		tweak_push_wcs_tan(t, &tan);
		t->sip->a_order = t->sip->b_order = t->sip->ap_order = t->sip->bp_order = order;

		for (i=0; i<10; i++) {
			// go to TWEAK_HAS_LINEAR_CD -> do_sip_tweak
			// t->image has the indices of corresponding image stars
			// t->ref   has the indices of corresponding catalog stars
			tweak_go_to(t, TWEAK_HAS_LINEAR_CD);
			logmsg("\n");
			sip_print(t->sip);
			t->state &= ~TWEAK_HAS_LINEAR_CD;
		}
		tan_write_to_file(&t->sip->wcstan, "kt1.wcs");
		sip = t->sip;
	}

	for (i=0; i<dl_size(otherradecs)/2; i++) {
		double ra, dec, x,y;
		ra = dl_get(otherradecs, 2*i);
		dec = dl_get(otherradecs, 2*i+1);
		if (!sip_radec2pixelxy(sip, ra, dec, &x, &y)) {
			logerr("Not in tangent plane: %g,%g\n", ra, dec);
			exit(-1);
			//continue;
		}
		printf("%g %g\n", x, y);
	}

	/*
	 blind_wcs_move_tangent_point(xyz, xy, N, crpix, &tan, &tan2);
	 blind_wcs_move_tangent_point(xyz, xy, N, crpix, &tan2, &tan3);
	 logmsg("Moved tangent point to (%g,%g):\n", crpix[0], crpix[1]);
	 tan_print_to(&tan3, logstream);
	 tan_write_to_file(&tan, "kt1.wcs");
	 tan_write_to_file(&tan3, "kt2.wcs");
	 */

	dl_free(otherradecs);
	free(xy);
	free(xyz);
	return 0;
}
コード例 #28
0
ファイル: test_tweak.c プロジェクト: dstndstn/astrometry.net
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;
}
コード例 #29
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;
}
コード例 #30
0
int main(int argc, char** args) {
    int argchar;
    kdtree_t* kd;
    int Nleaf = 25;
    char* infn = NULL;
    char* outfn = NULL;
    char* tychofn = NULL;
    char* crossfn = NULL;
	char* progname = args[0];
    FILE* f;

    tycstar_t* tycstars = NULL;
    int Ntyc = 0;

	int exttype  = KDT_EXT_DOUBLE;
	int datatype = KDT_DATA_U32;
	int treetype = KDT_TREE_U32;
	int tt;
	int buildopts = 0;
	int i, N, D;

    dl* ras;
    dl* decs;
    dl* hds;

    fl* mag1s;
    fl* mag2s;
    fl* mag3s;

    int nbad = 0;
    int nox = 0;

    int* hd;
    double* xyz;

    qfits_header* hdr;

    while ((argchar = getopt (argc, args, OPTIONS)) != -1)
        switch (argchar) {
        case 'T':
            tychofn = optarg;
            break;
        case 'X':
            crossfn = optarg;
            break;
        case 'R':
            Nleaf = (int)strtoul(optarg, NULL, 0);
            break;
		case 't':
			treetype = kdtree_kdtype_parse_tree_string(optarg);
			break;
		case 'd':
			datatype = kdtree_kdtype_parse_data_string(optarg);
			break;
		case 'b':
			buildopts |= KD_BUILD_BBOX;
			break;
		case 's':
			buildopts |= KD_BUILD_SPLIT;
			break;
		case 'S':
			buildopts |= KD_BUILD_SPLITDIM;
			break;
        case '?':
            fprintf(stderr, "Unknown option `-%c'.\n", optopt);
        case 'h':
			printHelp(progname);
            return 0;
        default:
            return -1;
        }

    if (optind != argc - 2) {
        printHelp(progname);
        exit(-1);
    }

    infn = args[optind];
    outfn = args[optind+1];

	if (!(buildopts & (KD_BUILD_BBOX | KD_BUILD_SPLIT))) {
		printf("You need bounding-boxes or splitting planes!\n");
		printHelp(progname);
		exit(-1);
	}

    if (tychofn || crossfn) {
        if (!(tychofn && crossfn)) {
            printf("You need both -T <Tycho2> and -X <Crossref> to do cross-referencing.\n");
            exit(-1);
        }
    }

    if (tychofn) {
        int i, N;
        tycho2_fits* tyc;
        FILE* f;
        int nx, nox;
		int lastgrass = 0;

        tyc = tycho2_fits_open(tychofn);
        if (!tyc) {
            ERROR("Failed to open Tycho-2 catalog.");
            exit(-1);
        }
        printf("Reading Tycho-2 catalog...\n");

        N = tycho2_fits_count_entries(tyc);
        tycstars = calloc(N, sizeof(tycstar_t));

        for (i=0; i<N; i++) {
            tycho2_entry* te;
			int grass = (i*80 / N);
			if (grass != lastgrass) {
				printf(".");
				fflush(stdout);
				lastgrass = grass;
			}
			te = tycho2_fits_read_entry(tyc);
            tycstars[i].tyc1 = te->tyc1;
            tycstars[i].tyc2 = te->tyc2;
            tycstars[i].tyc3 = te->tyc3;
            tycstars[i].ra   = te->ra;
            tycstars[i].dec  = te->dec;
            tycstars[i].mag_BT = te->mag_BT;
            tycstars[i].mag_VT = te->mag_VT;
            tycstars[i].mag_HP = te->mag_HP;
        }
        tycho2_fits_close(tyc);

        printf("Sorting...\n");
        qsort(tycstars, N, sizeof(tycstar_t), compare_tycs);
        Ntyc = N;

        f = fopen(crossfn, "rb");
        if (!f) {
            SYSERROR("Failed to open cross-reference file %s", crossfn);
            exit(-1);
        }

        nx = 0;
        nox = 0;
        while (TRUE) {
            char buf[1024];
            int tyc1, tyc2, tyc3, hd, nhd, ntyc;
            char ftyc, sptype0, sptype1, sptype2;
            tycstar_t* s;

            if (!fgets(buf, sizeof(buf), f)) {
                if (ferror(f)) {
                    SYSERROR("Failed to read a line of text from the cross-reference file");
                    exit(-1);
                }
                break;
            }

            if (sscanf(buf, " %d %d %d%c %d %c%c%c %d %d",
                       &tyc1, &tyc2, &tyc3, &ftyc, &hd,
                       &sptype0, &sptype1, &sptype2, &nhd, &ntyc) != 10) {
                ERROR("Failed to parse line: \"%s\"", buf);
            }

            //printf("%i %i %i %i %i %i\n", tyc1, tyc2, tyc3, hd, nhd, ntyc);
            s = find_tycho(tycstars, Ntyc, tyc1, tyc2, tyc3);
            if (!s) {
                ERROR("Failed to find Tycho-2 star %i-%i-%i", tyc1, tyc2, tyc3);
                nox++;
            } else {
                s->hd = hd;
                s->ntyc = ntyc;
            }
            nx++;
        }
        fclose(f);

        printf("Read %i cross-references.\n", nx);
        printf("Failed to find %i cross-referenced Tycho-2 stars.\n", nox);

        printf("Sorting...\n");
        qsort(tycstars, N, sizeof(tycstar_t), compare_hds);
    }

    f = fopen(infn, "rb");
    if (!f) {
        SYSERROR("Failed to open input file %s", infn);
        exit(-1);
    }

    ras = dl_new(1024);
    decs = dl_new(1024);
    hds = il_new(1024);

    mag1s = fl_new(1024);
    mag2s = fl_new(1024);
    mag3s = fl_new(1024);

    printf("Reading HD catalog...\n");
    for (;;) {
        char buf[1024];
        double ra, dec;
        int hd;
        float mag1, mag2, mag3;

        mag1 = mag2 = mag3 = 0.0;

        if (!fgets(buf, sizeof(buf), f)) {
            if (ferror(f)) {
                SYSERROR("Failed to read a line of text from the input file");
                exit(-1);
            }
            break;
        }

        if (buf[0] == '#')
            continue;
        if (buf[0] == '\n')
            continue;

        if (sscanf(buf, " %lf| %lf| %d", &ra, &dec, &hd) < 3) {
            // ignore three invalid lines
            if (nbad > 3) {
                ERROR("Failed to parse line: \"%s\"", buf);
            }
            nbad++;
        } else {

            if (tycstars) {
                tycstar_t* s = find_hd(tycstars, Ntyc, hd);
                if (!s) {
                    //printf("Failed to find cross-ref for HD %i\n", hd);
                    nox++;
                } else {
                    ra = s->ra;
                    dec = s->dec;

                    mag1 = s->mag_VT;
                    mag2 = s->mag_BT;
                    mag3 = s->mag_HP;
                }
            }

            dl_append(ras, ra);
            dl_append(decs, dec);
            il_append(hds, hd);
            fl_append(mag1s, mag1);
            fl_append(mag2s, mag2);
            fl_append(mag3s, mag3);
        }
    }
    fclose(f);

    N = dl_size(ras);
    printf("Read %i entries and %i bad lines.\n", N, nbad);

    if (dl_size(ras) != HD_NENTRIES) {
        printf("WARNING: expected %i Henry Draper catalog entries.\n", HD_NENTRIES);
    }

    if (nox) {
        printf("Found %i HD entries with no cross-reference (expect this to be about 1%%)\n", nox);
    }

    hd = malloc(sizeof(int) * N);
    il_copy(hds, 0, N, hd);
    il_free(hds);
    for (i=0; i<N; i++)
        if (hd[i] != i+1) {
            printf("Line %i is HD %i\n", i+1, hd[i]);
            break;
        }
    // HACK  - don't allocate 'em in the first place...
    free(hd);

    xyz = malloc(sizeof(double) * 3 * N);
    for (i=0; i<N; i++) {
        radecdeg2xyzarr(dl_get(ras, i), dl_get(decs, i), xyz + 3*i);
    }

    dl_free(ras);
    dl_free(decs);

	tt = kdtree_kdtypes_to_treetype(exttype, treetype, datatype);
	D = 3;
	{
		// limits of the kdtree...
        double lo[] = {-1.0, -1.0, -1.0};
        double hi[] = { 1.0,  1.0,  1.0};
        kd = kdtree_new(N, D, Nleaf);
        kdtree_set_limits(kd, lo, hi);
	}
	printf("Building tree...\n");
	kd = kdtree_build(kd, xyz, N, D, Nleaf, tt, buildopts);

    hdr = qfits_header_default();
    qfits_header_add(hdr, "AN_FILE", "HDTREE", "Henry Draper catalog kdtree", NULL);
    BOILERPLATE_ADD_FITS_HEADERS(hdr);
    fits_add_long_history(hdr, "This file was created by the following command-line:");
    fits_add_args(hdr, args, argc);

    if (kdtree_fits_write(kd, outfn, hdr)) {
        ERROR("Failed to write kdtree");
        exit(-1);
    }

    // Write mags as tag-along table.
    {
        fitstable_t* tag;
        tag = fitstable_open_for_appending(outfn);
        if (!tag) {
            ERROR("Failed to open kd-tree file for appending");
            exit(-1);
        }

        fitstable_add_write_column(tag, fitscolumn_float_type(), "MAG_VT", "");
        fitstable_add_write_column(tag, fitscolumn_float_type(), "MAG_BT", "");
        fitstable_add_write_column(tag, fitscolumn_float_type(), "MAG_HP", "");

        if (fitstable_write_header(tag)) {
            ERROR("Failed to write tag-along header");
            exit(-1);
        }

        for (i=0; i<N; i++) {
            fitstable_write_row(tag, fl_get(mag1s, i), fl_get(mag2s, i),
                                fl_get(mag3s, i));
        }
        if (fitstable_fix_header(tag)) {
            ERROR("Failed to fix tag-along header");
            exit(-1);
        }
        if (fitstable_close(tag)) {
            ERROR("Failed to close tag-along data");
            exit(-1);
        }
    }
    fl_free(mag1s);
    fl_free(mag2s);
    fl_free(mag3s);

    printf("Done.\n");

	qfits_header_destroy(hdr);
    free(xyz);
    kdtree_free(kd);
    free(tycstars);

    return 0;
}