il* constellations_get_unique_stars(int c) { il* uniq; const int* lines; int i; check_const_num(c); uniq = il_new(16); lines = constellation_lines[c]; for (i=0; i<2*constellation_nlines[c]; i++) { il_insert_unique_ascending(uniq, lines[i]); } return uniq; }
int plot_index_plot(const char* command, cairo_t* cairo, plot_args_t* pargs, void* baton) { plotindex_t* args = (plotindex_t*)baton; int i; double ra, dec, radius; double xyz[3]; double r2; pad_qidxes(args); plotstuff_builtin_apply(cairo, pargs); if (plotstuff_get_radec_center_and_radius(pargs, &ra, &dec, &radius)) { ERROR("Failed to get RA,Dec center and radius"); return -1; } radecdeg2xyzarr(ra, dec, xyz); r2 = deg2distsq(radius); logmsg("Field RA,Dec,radius = (%g,%g), %g deg\n", ra, dec, radius); logmsg("distsq: %g\n", r2); for (i=0; i<pl_size(args->indexes); i++) { index_t* index = pl_get(args->indexes, i); int j, N; int DQ; double px,py; if (args->stars) { // plot stars double* radecs = NULL; startree_search_for(index->starkd, xyz, r2, NULL, &radecs, NULL, &N); if (N) { assert(radecs); } logmsg("Found %i stars in range in index %s\n", N, index->indexname); for (j=0; j<N; j++) { logverb(" RA,Dec (%g,%g) -> x,y (%g,%g)\n", radecs[2*j], radecs[2*j+1], px, py); if (!plotstuff_radec2xy(pargs, radecs[j*2], radecs[j*2+1], &px, &py)) { ERROR("Failed to convert RA,Dec %g,%g to pixels\n", radecs[j*2], radecs[j*2+1]); continue; } cairoutils_draw_marker(cairo, pargs->marker, px, py, pargs->markersize); cairo_stroke(cairo); } free(radecs); } if (args->quads) { DQ = index_get_quad_dim(index); qidxfile* qidx = pl_get(args->qidxes, i); if (qidx) { int* stars; int Nstars; il* quadlist = il_new(256); // find stars in range. startree_search_for(index->starkd, xyz, r2, NULL, NULL, &stars, &Nstars); logmsg("Found %i stars in range of index %s\n", N, index->indexname); logmsg("Using qidx file.\n"); // find quads that each star is a member of. for (j=0; j<Nstars; j++) { uint32_t* quads; int Nquads; int k; if (qidxfile_get_quads(qidx, stars[j], &quads, &Nquads)) { ERROR("Failed to get quads for star %i\n", stars[j]); return -1; } for (k=0; k<Nquads; k++) il_insert_unique_ascending(quadlist, quads[k]); } for (j=0; j<il_size(quadlist); j++) { plotquad(cairo, pargs, args, index, il_get(quadlist, j), DQ); } } else { // plot quads N = index_nquads(index); for (j=0; j<N; j++) { plotquad(cairo, pargs, args, index, j, DQ); } } } } return 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; }
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; }
void test_il_insert_unique_ascending(CuTest* tc) { int i; il* x = il_new(4); il_insert_unique_ascending(x,2); il_insert_unique_ascending(x,4); il_insert_unique_ascending(x,4); il_insert_unique_ascending(x,7); il_insert_unique_ascending(x,4); il_insert_unique_ascending(x,4); il_insert_unique_ascending(x,8); il_insert_unique_ascending(x,5); il_insert_unique_ascending(x,0); il_insert_unique_ascending(x,5); il_insert_unique_ascending(x,5); il_insert_unique_ascending(x,5); il_insert_unique_ascending(x,4); il_insert_unique_ascending(x,5); il_insert_unique_ascending(x,6); il_insert_unique_ascending(x,7); il_insert_unique_ascending(x,7); il_insert_unique_ascending(x,7); il_insert_unique_ascending(x,7); il_insert_unique_ascending(x,1); il_insert_unique_ascending(x,1); il_insert_unique_ascending(x,3); il_insert_unique_ascending(x,1); il_insert_unique_ascending(x,1); il_insert_unique_ascending(x,0); il_print(x); CuAssertIntEquals(tc, il_check_consistency(x), 0); CuAssertIntEquals(tc, il_check_sorted_ascending(x, 1), 0); for (i=0;i<il_size(x);i++) CuAssertIntEquals(tc, i, il_get(x, i)); il_free(x); }