static void add_headers(qfits_header* hdr, char** argv, int argc, qfits_header* startreehdr, anbool circle, int npasses) { int i; BOILERPLATE_ADD_FITS_HEADERS(hdr); qfits_header_add(hdr, "HISTORY", "This file was created by the program \"hpquads\".", NULL, NULL); qfits_header_add(hdr, "HISTORY", "hpquads command line:", NULL, NULL); fits_add_args(hdr, argv, argc); qfits_header_add(hdr, "HISTORY", "(end of hpquads command line)", NULL, NULL); qfits_header_add(startreehdr, "HISTORY", "** History entries copied from the input file:", NULL, NULL); fits_copy_all_headers(startreehdr, hdr, "HISTORY"); qfits_header_add(startreehdr, "HISTORY", "** End of history entries.", NULL, NULL); qfits_header_add(hdr, "CXDX", "T", "All codes have the property cx<=dx.", NULL); qfits_header_add(hdr, "CXDXLT1", "T", "All codes have the property cx+dx<=1.", NULL); qfits_header_add(hdr, "MIDHALF", "T", "All codes have the property cx+dx<=1.", NULL); an_fits_copy_header(startreehdr, hdr, "ALLSKY"); qfits_header_add(hdr, "CIRCLE", (circle ? "T" : "F"), (circle ? "Stars C,D live in the circle defined by AB." : "Stars C,D live in the box defined by AB."), NULL); // add placeholders... for (i=0; i<npasses; i++) { char key[64]; sprintf(key, "PASS%i", i+1); qfits_header_add(hdr, key, "-1", "placeholder", NULL); } }
int main(int argc, char** args) { char* outfn = "ucac4_%03i.fits"; int c; int startoptind; int nrecords, nfiles; int Nside = 9; ucac4_fits** ucacs; int i, HP; int slicecounts[1800]; while ((c = getopt(argc, args, OPTIONS)) != -1) { switch (c) { case '?': case 'h': print_help(args[0]); exit(0); case 'N': Nside = atoi(optarg); break; case 'o': outfn = optarg; break; } } log_init(LOG_MSG); if (!outfn || (optind == argc)) { print_help(args[0]); exit(-1); } if (Nside < 1) { fprintf(stderr, "Nside must be >= 1.\n"); print_help(args[0]); exit(-1); } HP = 12 * Nside * Nside; printf("Nside = %i, using %i healpixes.\n", Nside, HP); ucacs = calloc(HP, sizeof(ucac4_fits*)); memset(slicecounts, 0, 1800 * sizeof(uint)); nrecords = 0; nfiles = 0; startoptind = optind; for (; optind<argc; optind++) { char* infn; FILE* fid; BZFILE* bzfid; int bzerr; int i; infn = args[optind]; printf("Reading %s\n", infn); if ((optind > startoptind) && ((optind - startoptind) % 100 == 0)) { printf("\nReading file %i of %i: %s\n", optind - startoptind, argc - startoptind, infn); } fflush(stdout); fid = fopen(infn, "rb"); if (!fid) { SYSERROR("Couldn't open input file \"%s\"", infn); exit(-1); } // MAGIC 1: bzip verbosity: [0=silent, 4=debug] // 0: small -- don't use less memory bzfid = BZ2_bzReadOpen(&bzerr, fid, 1, 0, NULL, 0); CHECK_BZERR(); for (i=0;; i++) { ucac4_entry entry; int hp; char buf[UCAC4_RECORD_SIZE]; int nr; anbool eof = 0; nr = BZ2_bzRead(&bzerr, bzfid, buf, UCAC4_RECORD_SIZE); if ((bzerr == BZ_STREAM_END) && (nr == UCAC4_RECORD_SIZE)) eof = TRUE; else CHECK_BZERR(); if (ucac4_parse_entry(&entry, buf)) { ERROR("Failed to parse UCAC4 entry %i in file \"%s\".", i, infn); exit(-1); } hp = radecdegtohealpix(entry.ra, entry.dec, Nside); if (!ucacs[hp]) { char fn[256]; sprintf(fn, outfn, hp); ucacs[hp] = ucac4_fits_open_for_writing(fn); if (!ucacs[hp]) { ERROR("Failed to initialize FITS file %i (filename %s)", hp, fn); exit(-1); } fits_header_add_int(ucacs[hp]->header, "HEALPIX", hp, "The healpix number of this catalog."); fits_header_add_int(ucacs[hp]->header, "NSIDE", Nside, "The healpix resolution."); BOILERPLATE_ADD_FITS_HEADERS(ucacs[hp]->header); qfits_header_add(ucacs[hp]->header, "HISTORY", "Created by the program \"ucac4tofits\"", NULL, NULL); qfits_header_add(ucacs[hp]->header, "HISTORY", "ucac4tofits command line:", NULL, NULL); fits_add_args(ucacs[hp]->header, args, argc); qfits_header_add(ucacs[hp]->header, "HISTORY", "(end of command line)", NULL, NULL); if (ucac4_fits_write_headers(ucacs[hp])) { ERROR("Failed to write header for FITS file %s", fn); exit(-1); } } if (ucac4_fits_write_entry(ucacs[hp], &entry)) { ERROR("Failed to write FITS entry"); exit(-1); } nrecords++; if (eof) break; } BZ2_bzReadClose(&bzerr, bzfid); fclose(fid); nfiles++; printf("\n"); } printf("\n"); // close all the files... for (i=0; i<HP; i++) { if (!ucacs[i]) continue; if (ucac4_fits_fix_headers(ucacs[i]) || ucac4_fits_close(ucacs[i])) { ERROR("Failed to close file %i", i); } } printf("Read %u files, %u records.\n", nfiles, nrecords); free(ucacs); return 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; }
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; }
startree_t* startree_build(fitstable_t* intable, const char* racol, const char* deccol, // keep RA,Dec in the tag-along table? //anbool keep_radec, // KDT_DATA_*, KDT_TREE_* int datatype, int treetype, // KD_BUILD_* int buildopts, int Nleaf, char** args, int argc) { double* ra = NULL; double* dec = NULL; double* xyz = NULL; int N; startree_t* starkd = NULL; int tt; int d; double low[3]; double high[3]; qfits_header* hdr; qfits_header* inhdr; int i; if (!racol) racol = "RA"; if (!deccol) deccol = "DEC"; if (!datatype) datatype = KDT_DATA_U32; if (!treetype) treetype = KDT_TREE_U32; if (!buildopts) buildopts = KD_BUILD_SPLIT; if (!Nleaf) Nleaf = 25; ra = fitstable_read_column(intable, racol, TFITS_BIN_TYPE_D); if (!ra) { ERROR("Failed to read RA from column %s", racol); goto bailout; } dec = fitstable_read_column(intable, deccol, TFITS_BIN_TYPE_D); if (!dec) { ERROR("Failed to read RA from column %s", racol); goto bailout; } N = fitstable_nrows(intable); xyz = malloc(N * 3 * sizeof(double)); if (!xyz) { SYSERROR("Failed to malloc xyz array to build startree"); goto bailout; } radecdeg2xyzarrmany(ra, dec, xyz, N); free(ra); ra = NULL; free(dec); dec = NULL; starkd = startree_new(); if (!starkd) { ERROR("Failed to allocate startree"); goto bailout; } tt = kdtree_kdtypes_to_treetype(KDT_EXT_DOUBLE, treetype, datatype); starkd->tree = kdtree_new(N, 3, Nleaf); for (d=0; d<3; d++) { low[d] = -1.0; high[d] = 1.0; } kdtree_set_limits(starkd->tree, low, high); logverb("Building star kdtree...\n"); starkd->tree = kdtree_build(starkd->tree, xyz, N, 3, Nleaf, tt, buildopts); if (!starkd->tree) { ERROR("Failed to build star kdtree"); startree_close(starkd); starkd = NULL; goto bailout; } starkd->tree->name = strdup(STARTREE_NAME); inhdr = fitstable_get_primary_header(intable); hdr = startree_header(starkd); an_fits_copy_header(inhdr, hdr, "HEALPIX"); an_fits_copy_header(inhdr, hdr, "HPNSIDE"); an_fits_copy_header(inhdr, hdr, "ALLSKY"); an_fits_copy_header(inhdr, hdr, "JITTER"); an_fits_copy_header(inhdr, hdr, "CUTNSIDE"); an_fits_copy_header(inhdr, hdr, "CUTMARG"); an_fits_copy_header(inhdr, hdr, "CUTDEDUP"); an_fits_copy_header(inhdr, hdr, "CUTNSWEP"); //fits_copy_header(inhdr, hdr, "CUTBAND"); //fits_copy_header(inhdr, hdr, "CUTMINMG"); //fits_copy_header(inhdr, hdr, "CUTMAXMG"); BOILERPLATE_ADD_FITS_HEADERS(hdr); qfits_header_add(hdr, "HISTORY", "This file was created by the command-line:", NULL, NULL); fits_add_args(hdr, args, argc); qfits_header_add(hdr, "HISTORY", "(end of command line)", NULL, NULL); qfits_header_add(hdr, "HISTORY", "** History entries copied from the input file:", NULL, NULL); fits_copy_all_headers(inhdr, hdr, "HISTORY"); qfits_header_add(hdr, "HISTORY", "** End of history entries.", NULL, NULL); for (i=1;; i++) { char key[16]; int n; sprintf(key, "SWEEP%i", i); n = qfits_header_getint(inhdr, key, -1); if (n == -1) break; an_fits_copy_header(inhdr, hdr, key); } bailout: if (ra) free(ra); if (dec) free(dec); if (xyz) free(xyz); return starkd; }
int main(int argc, char** args) { char* outfn = NULL; int c; int startoptind; int nrecords, nobs, nfiles; int Nside = 8; usnob_fits** usnobs; int i, HP; int slicecounts[180]; while ((c = getopt(argc, args, OPTIONS)) != -1) { switch (c) { case '?': case 'h': print_help(args[0]); exit(0); case 'N': Nside = atoi(optarg); break; case 'o': outfn = optarg; break; } } if (!outfn || (optind == argc)) { print_help(args[0]); exit(-1); } if (Nside < 1) { fprintf(stderr, "Nside must be >= 1.\n"); print_help(args[0]); exit(-1); } HP = 12 * Nside * Nside; printf("Nside = %i, using %i healpixes.\n", Nside, HP); { struct rlimit lim; getrlimit(RLIMIT_NOFILE, &lim); printf("Maximum number of files that can be opened: %li soft, %li hard\n", (long int)lim.rlim_cur, (long int)lim.rlim_max); if (lim.rlim_cur < HP) { printf("\n\nWARNING: This process is likely to fail - probably after working for many hours!\n\n\n"); sleep(5); } } usnobs = calloc(HP, sizeof(usnob_fits*)); memset(slicecounts, 0, 180 * sizeof(uint)); nrecords = 0; nobs = 0; nfiles = 0; printf("Reading USNO files... "); fflush(stdout); startoptind = optind; for (; optind<argc; optind++) { char* infn; FILE* fid; unsigned char* map; size_t map_size; int i; int lastgrass; infn = args[optind]; fid = fopen(infn, "rb"); if (!fid) { fprintf(stderr, "Couldn't open input file %s: %s\n", infn, strerror(errno)); exit(-1); } printf("Reading file %i of %i: %s\n", optind - startoptind, argc - startoptind, infn); if (fseeko(fid, 0, SEEK_END)) { fprintf(stderr, "Couldn't seek to end of input file %s: %s\n", infn, strerror(errno)); exit(-1); } map_size = ftello(fid); fseeko(fid, 0, SEEK_SET); map = mmap(NULL, map_size, PROT_READ, MAP_SHARED, fileno(fid), 0); if (map == MAP_FAILED) { fprintf(stderr, "Couldn't mmap input file %s: %s\n", infn, strerror(errno)); exit(-1); } fclose(fid); if (map_size % USNOB_RECORD_SIZE) { fprintf(stderr, "Warning, input file %s has size %u which is not divisible into %i-byte records.\n", infn, (unsigned int)map_size, USNOB_RECORD_SIZE); } lastgrass = 0; for (i=0; i<map_size; i+=USNOB_RECORD_SIZE) { usnob_entry entry; int hp; int slice; if ((i * 80 / map_size) != lastgrass) { printf("."); fflush(stdout); lastgrass = i * 80 / map_size; } if (usnob_parse_entry(map + i, &entry)) { fprintf(stderr, "Failed to parse USNOB entry: offset %i in file %s.\n", i, infn); exit(-1); } // compute the usnob_id based on its DEC slice and index. slice = (int)(entry.dec + 90.0); assert(slice < 180); assert((slicecounts[slice] & 0xff000000) == 0); entry.usnob_id = (slice << 24) | (slicecounts[slice]); slicecounts[slice]++; hp = radectohealpix(deg2rad(entry.ra), deg2rad(entry.dec), Nside); if (!usnobs[hp]) { char fn[256]; qfits_header* hdr; sprintf(fn, outfn, hp); usnobs[hp] = usnob_fits_open_for_writing(fn); if (!usnobs[hp]) { fprintf(stderr, "Failed to initialized FITS file %i (filename %s).\n", hp, fn); exit(-1); } if (usnob_fits_remove_an_diffraction_spike_column(usnobs[hp])) { fprintf(stderr, "Failed to remove the AN_DIFFRACTION_SPIKE column.\n"); exit(-1); } hdr = usnob_fits_get_header(usnobs[hp]); assert(hdr); // header remarks... fits_header_add_int(hdr, "HEALPIX", hp, "The healpix number of this catalog."); fits_header_add_int(hdr, "NSIDE", Nside, "The healpix resolution."); BOILERPLATE_ADD_FITS_HEADERS(hdr); qfits_header_add(hdr, "HISTORY", "Created by the program \"usnobtofits\"", NULL, NULL); qfits_header_add(hdr, "HISTORY", "usnobtofits command line:", NULL, NULL); fits_add_args(hdr, args, argc); qfits_header_add(hdr, "HISTORY", "(end of command line)", NULL, NULL); if (usnob_fits_write_headers(usnobs[hp])) { fprintf(stderr, "Failed to write header for FITS file %s.\n", fn); exit(-1); } } if (usnob_fits_write_entry(usnobs[hp], &entry)) { fprintf(stderr, "Failed to write FITS entry.\n"); exit(-1); } nrecords++; nobs += (entry.ndetections == 0 ? 1 : entry.ndetections); } munmap(map, map_size); nfiles++; printf("\n"); } // close all the files... for (i=0; i<HP; i++) { if (!usnobs[i]) continue; if (usnob_fits_fix_headers(usnobs[i]) || usnob_fits_close(usnobs[i])) { fprintf(stderr, "Failed to close file %i: %s\n", i, strerror(errno)); } } printf("Read %u files, %u records, %u observations.\n", nfiles, nrecords, nobs); free(usnobs); return 0; }
int unpermute_stars(startree_t* treein, quadfile_t* qfin, startree_t** p_treeout, quadfile_t* qfout, anbool dosweeps, anbool check, char** args, int argc) { startree_t* treeout; int i; int N; int healpix = -1; int hpnside = 0; int starhp = -1; int lastgrass; qfits_header* qouthdr; qfits_header* qinhdr; anbool allsky; assert(p_treeout); N = startree_N(treein); allsky = qfits_header_getboolean(startree_header(treein), "ALLSKY", 0); if (allsky) logverb("Star kd-tree is all-sky\n"); else { starhp = qfits_header_getint(startree_header(treein), "HEALPIX", -1); if (starhp == -1) ERROR("Warning, input star kdtree didn't have a HEALPIX header.\n"); hpnside = qfits_header_getint(startree_header(treein), "HPNSIDE", 1); healpix = starhp; logverb("Star kd-tree covers healpix %i, nside %i\n", healpix, hpnside); } qfout->healpix = healpix; qfout->hpnside = hpnside; qfout->numstars = qfin->numstars; qfout->dimquads = qfin->dimquads; qfout->index_scale_upper = qfin->index_scale_upper; qfout->index_scale_lower = qfin->index_scale_lower; qfout->indexid = qfin->indexid; qouthdr = quadfile_get_header(qfout); qinhdr = quadfile_get_header(qfin); an_fits_copy_header(qinhdr, qouthdr, "ALLSKY"); BOILERPLATE_ADD_FITS_HEADERS(qouthdr); qfits_header_add(qouthdr, "HISTORY", "This file was created by the program \"unpermute-stars\".", NULL, NULL); qfits_header_add(qouthdr, "HISTORY", "unpermute-stars command line:", NULL, NULL); fits_add_args(qouthdr, args, argc); qfits_header_add(qouthdr, "HISTORY", "(end of unpermute-stars command line)", NULL, NULL); qfits_header_add(qouthdr, "HISTORY", "** unpermute-stars: history from input:", NULL, NULL); fits_copy_all_headers(qinhdr, qouthdr, "HISTORY"); qfits_header_add(qouthdr, "HISTORY", "** unpermute-stars: end of history from input.", NULL, NULL); qfits_header_add(qouthdr, "COMMENT", "** unpermute-stars: comments from input:", NULL, NULL); fits_copy_all_headers(qinhdr, qouthdr, "COMMENT"); qfits_header_add(qouthdr, "COMMENT", "** unpermute-stars: end of comments from input.", NULL, NULL); if (quadfile_write_header(qfout)) { ERROR("Failed to write quadfile header.\n"); return -1; } logmsg("Writing quads...\n"); startree_compute_inverse_perm(treein); if (check) { logmsg("Running quadfile_check()...\n"); if (quadfile_check(qfin)) { ERROR("quadfile_check() failed"); return -1; } logmsg("Check passed.\n"); logmsg("Checking inverse permutation...\n"); if (startree_check_inverse_perm(treein)) { ERROR("check failed!"); return -1; } logmsg("Running startree kdtree_check()...\n"); if (kdtree_check(treein->tree)) { ERROR("kdtree_check() failed"); return -1; } logmsg("Check passed.\n"); } lastgrass = 0; for (i=0; i<qfin->numquads; i++) { int j; unsigned int stars[qfin->dimquads]; if (i*80/qfin->numquads != lastgrass) { logmsg("."); fflush(stdout); lastgrass = i*80/qfin->numquads; } if (quadfile_get_stars(qfin, i, stars)) { ERROR("Failed to read quadfile entry.\n"); return -1; } for (j=0; j<qfin->dimquads; j++) stars[j] = treein->inverse_perm[stars[j]]; if (quadfile_write_quad(qfout, stars)) { ERROR("Failed to write quadfile entry.\n"); return -1; } } logmsg("\n"); if (quadfile_fix_header(qfout)) { ERROR("Failed to fix quadfile header"); return -1; } treeout = startree_new(); treeout->tree = malloc(sizeof(kdtree_t)); memcpy(treeout->tree, treein->tree, sizeof(kdtree_t)); treeout->tree->perm = NULL; an_fits_copy_header(startree_header(treein), startree_header(treeout), "HEALPIX"); an_fits_copy_header(startree_header(treein), startree_header(treeout), "HPNSIDE"); an_fits_copy_header(startree_header(treein), startree_header(treeout), "ALLSKY"); an_fits_copy_header(startree_header(treein), startree_header(treeout), "JITTER"); an_fits_copy_header(startree_header(treein), startree_header(treeout), "CUTNSIDE"); an_fits_copy_header(startree_header(treein), startree_header(treeout), "CUTMARG"); an_fits_copy_header(startree_header(treein), startree_header(treeout), "CUTBAND"); an_fits_copy_header(startree_header(treein), startree_header(treeout), "CUTDEDUP"); an_fits_copy_header(startree_header(treein), startree_header(treeout), "CUTNSWEP"); an_fits_copy_header(startree_header(treein), startree_header(treeout), "CUTMINMG"); an_fits_copy_header(startree_header(treein), startree_header(treeout), "CUTMAXMG"); qfits_header_add(startree_header(treeout), "HISTORY", "unpermute-stars command line:", NULL, NULL); fits_add_args(startree_header(treeout), args, argc); qfits_header_add(startree_header(treeout), "HISTORY", "(end of unpermute-stars command line)", NULL, NULL); qfits_header_add(startree_header(treeout), "HISTORY", "** unpermute-stars: history from input:", NULL, NULL); fits_copy_all_headers(startree_header(treein), startree_header(treeout), "HISTORY"); qfits_header_add(startree_header(treeout), "HISTORY", "** unpermute-stars: end of history from input.", NULL, NULL); qfits_header_add(startree_header(treeout), "COMMENT", "** unpermute-stars: comments from input:", NULL, NULL); fits_copy_all_headers(startree_header(treein), startree_header(treeout), "COMMENT"); qfits_header_add(startree_header(treeout), "COMMENT", "** unpermute-stars: end of comments from input.", NULL, NULL); if (dosweeps) { // copy sweepX headers. for (i=1;; i++) { char key[16]; int n; sprintf(key, "SWEEP%i", i); n = qfits_header_getint(treein->header, key, -1); if (n == -1) break; an_fits_copy_header(treein->header, treeout->header, key); } // compute sweep array. treeout->sweep = malloc(N * sizeof(uint8_t)); for (i=0; i<N; i++) { int ind = treein->tree->perm[i]; // Stars are sorted first by sweep and then by brightness within // the sweep. Instead of just storing the sweep number, we can // store a quantization of the total-ordered rank. treeout->sweep[i] = (uint8_t)floor((float)256.0 * (float)ind / (float)N); } } *p_treeout = treeout; return 0; }
int main(int argc, char *argv[]) { int argchar; char* progname = argv[0]; char** inputfiles = NULL; int ninputfiles = 0; int i; int firstfield=0, lastfield=INT_MAX-1; int firstfieldfile=1, lastfieldfile=INT_MAX-1; matchfile** mfs; MatchObj** mos; anbool* eofs; anbool* eofieldfile; int nread = 0; int f; int fieldfile; int totalsolved, totalunsolved; int mode = MODE_BEST; double logodds_tosolve = -HUGE_VAL; anbool agree = FALSE; MatchObj* bestmo; bl* keepers; bl* leftovers = NULL; while ((argchar = getopt (argc, argv, OPTIONS)) != -1) { switch (argchar) { case 'S': solvedfile = optarg; break; case 's': solvedserver = optarg; break; case 'F': mode = MODE_FIRST; break; case 'a': mode = MODE_ALL; break; case 'r': ratio_tosolve = atof(optarg); logodds_tosolve = log(ratio_tosolve); break; case 'f': ninfield_tosolve = atoi(optarg); break; case 'M': agreefname = optarg; break; case 'L': leftoverfname = optarg; break; case 'I': firstfieldfile = atoi(optarg); break; case 'J': lastfieldfile = atoi(optarg); break; case 'A': firstfield = atoi(optarg); break; case 'B': lastfield = atoi(optarg); break; case 'h': default: printHelp(progname); exit(-1); } } if (optind < argc) { ninputfiles = argc - optind; inputfiles = argv + optind; } else { printHelp(progname); exit(-1); } if (lastfield < firstfield) { fprintf(stderr, "Last field (-B) must be at least as big as first field (-A)\n"); exit(-1); } if (solvedserver) if (solvedclient_set_server(solvedserver)) { fprintf(stderr, "Failed to set solved server.\n"); exit(-1); } if (leftoverfname) { leftovermf = matchfile_open_for_writing(leftoverfname); if (!leftovermf) { fprintf(stderr, "Failed to open file %s to write leftover matches.\n", leftoverfname); exit(-1); } BOILERPLATE_ADD_FITS_HEADERS(leftovermf->header); qfits_header_add(leftovermf->header, "HISTORY", "This file was created by the program \"agreeable\".", NULL, NULL); if (matchfile_write_headers(leftovermf)) { fprintf(stderr, "Failed to write leftovers matchfile header.\n"); exit(-1); } leftovers = bl_new(256, sizeof(MatchObj)); } if (agreefname) { agreemf = matchfile_open_for_writing(agreefname); if (!agreemf) { fprintf(stderr, "Failed to open file %s to write agreeing matches.\n", agreefname); exit(-1); } BOILERPLATE_ADD_FITS_HEADERS(agreemf->header); qfits_header_add(agreemf->header, "HISTORY", "This file was created by the program \"agreeable\".", NULL, NULL); if (matchfile_write_headers(agreemf)) { fprintf(stderr, "Failed to write agreeing matchfile header.\n"); exit(-1); } agree = TRUE; } solved = il_new(256); unsolved = il_new(256); keepers = bl_new(256, sizeof(MatchObj)); totalsolved = totalunsolved = 0; mos = calloc(ninputfiles, sizeof(MatchObj*)); eofs = calloc(ninputfiles, sizeof(anbool)); eofieldfile = malloc(ninputfiles * sizeof(anbool)); mfs = malloc(ninputfiles * sizeof(matchfile*)); for (i=0; i<ninputfiles; i++) { fprintf(stderr, "Opening file %s...\n", inputfiles[i]); mfs[i] = matchfile_open(inputfiles[i]); if (!mfs[i]) { fprintf(stderr, "Failed to open matchfile %s.\n", inputfiles[i]); exit(-1); } } // we assume the matchfiles are sorted by field id and number. for (fieldfile=firstfieldfile; fieldfile<=lastfieldfile; fieldfile++) { anbool alldone = TRUE; memset(eofieldfile, 0, ninputfiles * sizeof(anbool)); for (f=firstfield; f<=lastfield; f++) { int fieldnum = f; anbool donefieldfile; anbool solved_it; bl* writematches = NULL; // quit if we've reached the end of all the input files. alldone = TRUE; for (i=0; i<ninputfiles; i++) if (!eofs[i]) { alldone = FALSE; break; } if (alldone) break; // move on to the next fieldfile if all the input files have been // exhausted. donefieldfile = TRUE; for (i=0; i<ninputfiles; i++) if (!eofieldfile[i] && !eofs[i]) { donefieldfile = FALSE; break; } if (donefieldfile) break; // start a new field. fprintf(stderr, "File %i, Field %i.\n", fieldfile, f); solved_it = FALSE; bestmo = NULL; for (i=0; i<ninputfiles; i++) { int nr = 0; int ns = 0; while (1) { if (eofs[i]) break; if (!mos[i]) mos[i] = matchfile_read_match(mfs[i]); if (unlikely(!mos[i])) { eofs[i] = TRUE; break; } // skip past entries that are out of range... if ((mos[i]->fieldfile < firstfieldfile) || (mos[i]->fieldfile > lastfieldfile) || (mos[i]->fieldnum < firstfield) || (mos[i]->fieldnum > lastfield)) { mos[i] = NULL; ns++; continue; } if (mos[i]->fieldfile > fieldfile) eofieldfile[i] = TRUE; if (mos[i]->fieldfile != fieldfile) break; assert(mos[i]->fieldnum >= fieldnum); if (mos[i]->fieldnum != fieldnum) break; nread++; if (nread % 10000 == 9999) { fprintf(stderr, "."); fflush(stderr); } // if we've already found a solution, skip past the // remaining matches in this file... if (solved_it && (mode == MODE_FIRST)) { ns++; mos[i] = NULL; continue; } nr++; if ((mos[i]->logodds >= logodds_tosolve) && (mos[i]->nindex >= ninfield_tosolve)) { solved_it = TRUE; // (note, we get a pointer to its position in the list) mos[i] = bl_append(keepers, mos[i]); if (!bestmo || mos[i]->logodds > bestmo->logodds) bestmo = mos[i]; } else if (leftovers) { bl_append(leftovers, mos[i]); } mos[i] = NULL; } if (nr || ns) fprintf(stderr, "File %s: read %i matches, skipped %i matches.\n", inputfiles[i], nr, ns); } // which matches do we want to write out? if (agree) { writematches = bl_new(256, sizeof(MatchObj)); switch (mode) { case MODE_BEST: case MODE_FIRST: if (bestmo) bl_append(writematches, bestmo); break; case MODE_ALL: bl_append_list(writematches, keepers); break; } } write_field(writematches, leftovers, fieldfile, fieldnum); if (agree) bl_free(writematches); if (leftovers) bl_remove_all(leftovers); if (keepers) bl_remove_all(keepers); fprintf(stderr, "This file: %i fields solved, %i unsolved.\n", il_size(solved), il_size(unsolved)); fprintf(stderr, "Grand total: %i solved, %i unsolved.\n", totalsolved + il_size(solved), totalunsolved + il_size(unsolved)); } totalsolved += il_size(solved); totalunsolved += il_size(unsolved); il_remove_all(solved); il_remove_all(unsolved); if (alldone) break; } for (i=0; i<ninputfiles; i++) matchfile_close(mfs[i]); free(mfs); free(mos); free(eofs); fprintf(stderr, "\nRead %i matches.\n", nread); fflush(stderr); if (keepers) bl_free(keepers); if (leftovers) bl_free(leftovers); il_free(solved); il_free(unsolved); if (leftovermf) { matchfile_fix_headers(leftovermf); matchfile_close(leftovermf); } if (agreemf) { matchfile_fix_headers(agreemf); matchfile_close(agreemf); } return 0; }
int main(int argc, char *argv[]) { char* progname = argv[0]; int argidx, argchar; char *idxfname = NULL; char *quadfname = NULL; il** quadlist; quadfile* quads; qidxfile* qidx; int q; int i; int numused; qfits_header* quadhdr; qfits_header* qidxhdr; int dimquads; anbool check = FALSE; int loglvl = LOG_MSG; if (argc <= 2) { printHelp(progname); exit(-1); } while ((argchar = getopt (argc, argv, OPTIONS)) != -1) switch (argchar) { case 'c': check = TRUE; break; case 'v': loglvl++; break; case 'i': quadfname = optarg; break; case 'o': idxfname = optarg; break; case '?': fprintf(stderr, "Unknown option `-%c'.\n", optopt); case 'h': printHelp(progname); exit(-1); default: return (OPT_ERR); } log_init(loglvl); if (optind < argc) { for (argidx = optind; argidx < argc; argidx++) fprintf (stderr, "Non-option argument %s\n", argv[argidx]); printHelp(progname); exit(-1); } logmsg("quadidx: indexing quads in \"%s\"...\n", quadfname); logmsg("will write to file \"%s\".\n", idxfname); quads = quadfile_open(quadfname); if (!quads) { ERROR("Couldn't open quads file \"%s\"", quadfname); exit(-1); } logmsg("%u quads, %u stars.\n", quads->numquads, quads->numstars); if (check) { logmsg("Running quadfile_check()...\n"); if (quadfile_check(quads)) { ERROR("quadfile_check() failed"); exit(-1); } logmsg("Check passed.\n"); } quadlist = calloc(quads->numstars, sizeof(il*)); if (!quadlist) { SYSERROR("Failed to allocate list of quad contents"); exit(-1); } dimquads = quadfile_dimquads(quads); for (q=0; q<quads->numquads; q++) { unsigned int inds[dimquads]; quadfile_get_stars(quads, q, inds); // append this quad index to the lists of each of its stars. for (i=0; i<dimquads; i++) { il* list; int starind = inds[i]; list = quadlist[starind]; // create the list if necessary if (!list) { list = il_new(10); quadlist[starind] = list; } il_append(list, q); } } // first count numused: // how many stars are members of quads. numused = 0; for (i=0; i<quads->numstars; i++) { il* list = quadlist[i]; if (!list) continue; numused++; } logmsg("%u stars used\n", numused); qidx = qidxfile_open_for_writing(idxfname, quads->numstars, quads->numquads); if (!qidx) { logmsg("Couldn't open outfile qidx file %s.\n", idxfname); exit(-1); } quadhdr = quadfile_get_header(quads); qidxhdr = qidxfile_get_header(qidx); an_fits_copy_header(quadhdr, qidxhdr, "INDEXID"); an_fits_copy_header(quadhdr, qidxhdr, "HEALPIX"); BOILERPLATE_ADD_FITS_HEADERS(qidxhdr); qfits_header_add(qidxhdr, "HISTORY", "This file was created by the program \"quadidx\".", NULL, NULL); qfits_header_add(qidxhdr, "HISTORY", "quadidx command line:", NULL, NULL); fits_add_args(qidxhdr, argv, argc); qfits_header_add(qidxhdr, "HISTORY", "(end of quadidx command line)", NULL, NULL); qfits_header_add(qidxhdr, "HISTORY", "** History entries copied from the input file:", NULL, NULL); fits_copy_all_headers(quadhdr, qidxhdr, "HISTORY"); qfits_header_add(qidxhdr, "HISTORY", "** End of history entries.", NULL, NULL); if (qidxfile_write_header(qidx)) { logmsg("Couldn't write qidx header (%s).\n", idxfname); exit(-1); } for (i=0; i<quads->numstars; i++) { int thisnumq; //int thisstar; int* stars; // bad variable name - list of quads this star is in. il* list = quadlist[i]; if (list) { thisnumq = (uint)il_size(list); stars = malloc(thisnumq * sizeof(uint)); il_copy(list, 0, thisnumq, (int*)stars); } else { thisnumq = 0; stars = NULL; } //thisstar = i; if (qidxfile_write_star(qidx, stars, thisnumq)) { logmsg("Couldn't write star to qidx file (%s).\n", idxfname); exit(-1); } if (list) { free(stars); il_free(list); quadlist[i] = NULL; } } free(quadlist); quadfile_close(quads); if (qidxfile_close(qidx)) { logmsg("Failed to close qidx file.\n"); exit(-1); } logmsg(" done.\n"); return 0; }