int plot_annotations_add_named_target(plotann_t* ann, const char* name) { target_t tar; int i, N; // Try bright stars N = bright_stars_n(); for (i=0; i<N; i++) { const brightstar_t* bs = bright_stars_get(i); if (!bs->name && !bs->common_name) continue; if (strcaseeq(name, bs->name) || strcaseeq(name, bs->common_name)) { tar.ra = bs->ra; tar.dec = bs->dec; if (strcaseeq(name, bs->name)) tar.name = bs->name; else tar.name = bs->common_name; logmsg("Found %s: RA,Dec (%g,%g)\n", name, bs->ra, bs->dec); bl_append(ann->targets, &tar); return 0; } } // Try NGC objects ngc_entry* e = ngc_get_entry_named(name); if (!e) { ERROR("Failed to find target named \"%s\"", name); return -1; } tar.name = ngc_get_name_list(e, " / "); tar.ra = e->ra; tar.dec = e->dec; logmsg("Found %s: RA,Dec (%g,%g)\n", tar.name, tar.ra, tar.dec); bl_append(ann->targets, &tar); return 0; }
bl* henry_draper_get(hd_catalog_t* hdcat, double racenter, double deccenter, double r_arcsec) { double r2; double xyz[3]; kdtree_qres_t* q; bl* res; int i; hd_entry_t hd; radecdeg2xyzarr(racenter, deccenter, xyz); r2 = arcsec2distsq(r_arcsec); q = kdtree_rangesearch(hdcat->kd, xyz, r2); if (!q) { return NULL; } res = bl_new(256, sizeof(hd_entry_t)); for (i=0; i<q->nres; i++) { double* pt = q->results.d + i*3; xyzarr2radecdeg(pt, &(hd.ra), &(hd.dec)); hd.hd = q->inds[i] + 1; bl_append(res, &hd); } kdtree_free_query(q); return res; }
void test_try_all_codes(pquad* pq, unsigned int* fieldstars, int dimquad, solver_t* solver, double tol2) { int sorted[dimquad]; int i; fflush(NULL); printf("test_try_all_codes: ["); for (i=0; i<dimquad; i++) { printf("%s%i", (i?" ":""), fieldstars[i]); } printf("]"); // sort AB and C[DE]... memcpy(sorted, fieldstars, dimquad * sizeof(int)); qsort(sorted, 2, sizeof(int), compare_ints_asc); qsort(sorted+2, dimquad-2, sizeof(int), compare_ints_asc); printf(" -> ["); for (i=0; i<dimquad; i++) { printf("%s%i", (i?" ":""), sorted[i]); } printf("]\n"); fflush(NULL); bl_append(quadlist, sorted); }
bl* opts_from_array(const an_option_t* opts, int N, bl* lst) { int i; if (!lst) lst = bl_new(4, sizeof(an_option_t)); for (i=0; i<N; i++) bl_append(lst, opts + i); return lst; }
void plot_annotations_add_target(plotann_t* ann, double ra, double dec, const char* name) { target_t tar; memset(&tar, 0, sizeof(target_t)); tar.ra = ra; tar.dec = dec; tar.name = strdup(name); logmsg("Added target \"%s\" at (%g,%g)\n", tar.name, tar.ra, tar.dec); bl_append(ann->targets, &tar); }
static void add_quad(quadbuilder_t* qb, unsigned int* stars, void* vtoken) { int i; hpquads_t* me = vtoken; bl_append(me->quadlist, stars); if (me->count_uses) { for (i=0; i<me->dimquads; i++) me->nuses[stars[i]]++; } qb->stop_creating = TRUE; me->quad_created = TRUE; }
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; }
static int write_row_data(fitstable_t* table, void* data, int R) { assert(table); assert(data); if (in_memory(table)) { ensure_row_list_exists(table); bl_append(table->rows, data); // ? table->table->nr++; return 0; } if (R == 0) R = fitstable_row_size(table); if (fwrite(data, 1, R, table->fid) != R) { SYSERROR("Failed to write a row to %s", table->fn); return -1; } assert(table->table); table->table->nr++; return 0; }
void test_try_permutations(int* stars, double* code, int dimquad, solver_t* s) { int i; fflush(NULL); /* printf("test_try_permutations: ["); for (i=0; i<dimquad; i++) { printf("%s%i", (i?" ":""), stars[i]); } printf("]\n"); */ printf("{"); for (i=0; i<dimquad; i++) { printf("%s%i", (i?",":""), stars[i]); } printf("}, "); fflush(NULL); bl_append(quadlist, stars); if (quad_obeys_invariants(NULL, code, dimquad, 0)) ninv++; }
void fitstable_next_extension(fitstable_t* tab) { if (is_writing(tab)) fits_pad_file(tab->fid); if (in_memory(tab)) { fitsext_t ext; if (!tab->table) return; // update NAXIS2 fitstable_fix_header(tab); ext.table = tab->table; ext.header = tab->header; ext.rows = tab->rows; bl_append(tab->extensions, &ext); tab->rows = NULL; } else { qfits_table_close(tab->table); qfits_header_destroy(tab->header); } tab->extension++; tab->table = NULL; tab->header = NULL; }
void* bl_push(bl* list, const void* data) { return bl_append(list, data); }
static fitscol_t* fitstable_add_column(fitstable_t* tab, fitscol_t* col) { col = bl_append(tab->cols, col); col->csize = fits_get_atom_size(col->ctype); col->fitssize = fits_get_atom_size(col->fitstype); return col; }
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** args) { int argchar; char* infn = NULL; char* outfn = NULL; unsigned int row; int bits; FILE* fid = stdin; FILE* fout = stdout; int loglvl = LOG_MSG; char* progname = args[0]; int bzero = 0; int outformat; qfits_header* hdr; unsigned int plane; off_t datastart; anbool onepass = FALSE; bl* pixcache = NULL; #if HAVE_NETPBM struct pam img; tuple * tuplerow; #else void* rowbuf; #endif int W, H, depth, maxval; while ((argchar = getopt (argc, args, OPTIONS)) != -1) switch (argchar) { case '?': case 'h': printHelp(progname); exit(0); case 'v': loglvl++; break; case 'q': loglvl--; break; case 'o': outfn = optarg; break; } log_init(loglvl); log_to(stderr); fits_use_error_system(); if (optind == argc) { // ok, stdin to stdout. } else if (optind == argc-1) { infn = args[optind]; } else if (optind == argc-2) { infn = args[optind]; outfn = args[optind+1]; } else { printHelp(progname); exit(-1); } if (infn && !streq(infn, "-")) { fid = fopen(infn, "rb"); if (!fid) { SYSERROR("Failed to open input file %s", infn); exit(-1); } } if (outfn) { fout = fopen(outfn, "wb"); if (!fid) { SYSERROR("Failed to open output file %s", outfn); exit(-1); } } else outfn = "stdout"; #if HAVE_NETPBM pm_init(args[0], 0); pnm_readpaminit(fid, &img, // PAM_STRUCT_SIZE isn't defined until Netpbm 10.23 (July 2004) #if defined(PAM_STRUCT_SIZE) PAM_STRUCT_SIZE(tuple_type) #else sizeof(struct pam) #endif ); W = img.width; H = img.height; depth = img.depth; maxval = img.maxval; tuplerow = pnm_allocpamrow(&img); bits = pm_maxvaltobits(img.maxval); bits = (bits <= 8) ? 8 : 16; #else // No NETPBM if (parse_pnm_header(fid, &W, &H, &depth, &maxval)) { ERROR("Failed to parse PNM header from file: %s\n", infn ? infn : "<stdin>"); exit(-1); } bits = 8 * maxval_to_bytes(maxval); rowbuf = malloc(W * depth * (bits/8)); #endif logmsg("Read file %s: %i x %i pixels x %i color(s); maxval %i\n", infn ? infn : "stdin", W, H, depth, maxval); if (bits == 8) outformat = BPP_8_UNSIGNED; else { outformat = BPP_16_SIGNED; if (maxval >= INT16_MAX) bzero = 0x8000; } logmsg("Using %i-bit output\n", bits); hdr = fits_get_header_for_image3(W, H, outformat, depth, NULL); if (bzero) fits_header_add_int(hdr, "BZERO", bzero, "Number that has been subtracted from pixel values"); if (qfits_header_dump(hdr, fout)) { ERROR("Failed to write FITS header to file %s", outfn); exit(-1); } qfits_header_destroy(hdr); datastart = ftello(fid); // Figure out if we can seek backward in this input file... if ((fid == stdin) || (fseeko(fid, 0, SEEK_SET) || fseeko(fid, datastart, SEEK_SET))) // Nope! onepass = TRUE; if (onepass && depth > 1) { logmsg("Reading in one pass\n"); pixcache = bl_new(16384, bits/8); } for (plane=0; plane<depth; plane++) { if (plane > 0) { if (fseeko(fid, datastart, SEEK_SET)) { SYSERROR("Failed to seek back to start of image data"); exit(-1); } } for (row = 0; row<H; row++) { unsigned int column; #if HAVE_NETPBM pnm_readpamrow(&img, tuplerow); #else read_pnm_row(fid, W, depth, maxval, rowbuf); #endif for (column = 0; column<W; column++) { int rtn; int pixval; #if HAVE_NETPBM pixval = tuplerow[column][plane]; #else pixval = (bits == 8 ? ((uint8_t *)rowbuf)[column*depth + plane] : ((uint16_t*)rowbuf)[column*depth + plane]); #endif if (outformat == BPP_8_UNSIGNED) rtn = fits_write_data_B(fout, pixval); else rtn = fits_write_data_I(fout, pixval-bzero, TRUE); if (rtn) { ERROR("Failed to write FITS pixel"); exit(-1); } } if (onepass && depth > 1) { for (column = 0; column<W; column++) { for (plane=1; plane<depth; plane++) { int pixval; #if HAVE_NETPBM pixval = tuplerow[column][plane]; #else pixval = (bits == 8 ? ((uint8_t *)rowbuf)[column*depth + plane] : ((uint16_t*)rowbuf)[column*depth + plane]); #endif if (outformat == BPP_8_UNSIGNED) { uint8_t pix = pixval; bl_append(pixcache, &pix); } else { int16_t pix = pixval - bzero; bl_append(pixcache, &pix); } } } } } } #if HAVE_NETPBM pnm_freepamrow(tuplerow); #else free(rowbuf); #endif if (pixcache) { int i, j; int step = (depth - 1); logverb("Writing %zu queued pixels\n", bl_size(pixcache)); for (plane=1; plane<depth; plane++) { j = (plane - 1); for (i=0; i<(W * H); i++) { int rtn; if (outformat == BPP_8_UNSIGNED) { uint8_t* pix = bl_access(pixcache, j); rtn = fits_write_data_B(fout, *pix); } else { int16_t* pix = bl_access(pixcache, j); rtn = fits_write_data_I(fout, *pix, TRUE); } if (rtn) { ERROR("Failed to write FITS pixel"); exit(-1); } j += step; } } bl_free(pixcache); } if (fid != stdin) fclose(fid); if (fits_pad_file(fout)) { ERROR("Failed to pad output file \"%s\"", outfn); return -1; } if (fout != stdout) if (fclose(fout)) { SYSERROR("Failed to close output file %s", outfn); exit(-1); } 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; }
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); }
void* bl_extend(bl* list) { return bl_append(list, NULL); }
static void add_cmd(plot_args_t* pargs, cairocmd_t* cmd) { bl_append(pargs->cairocmds, cmd); }
// One of "struc" or "ap" should be non-null. static int write_one(fitstable_t* table, const void* struc, anbool flip, va_list* ap) { int i; char* buf = NULL; int Nbuf = 0; int ret = 0; int nc = ncols(table); char* thisrow = NULL; int rowoff = 0; if (in_memory(table)) { ensure_row_list_exists(table); thisrow = calloc(1, bl_datasize(table->rows)); } for (i=0; i<nc; i++) { fitscol_t* col; const char* columndata; col = getcol(table, i); if (col->in_struct) { if (struc) columndata = struc + col->coffset; else columndata = NULL; } else { if (struc) columndata = NULL; else columndata = va_arg(*ap, void *); } // If "columndata" is NULL, fits_write_data_array // skips the required number of bytes. // This allows both structs and normal columns to coexist // (in theory -- is this ever used?) // (yes, by blind.c when writing rdls and correspondence files // with tag-along data...) if (columndata && col->fitstype != col->ctype) { int sz = MAX(256, MAX(col->csize, col->fitssize) * col->arraysize); if (sz > Nbuf) { free(buf); buf = malloc(sz); } fits_convert_data(buf, col->fitssize, col->fitstype, columndata, col->csize, col->ctype, col->arraysize, 1); columndata = buf; } if (in_memory(table)) { int nb = fitscolumn_get_size(col); memcpy(thisrow + rowoff, columndata, nb); rowoff += nb; } else { ret = fits_write_data_array(table->fid, columndata, col->fitstype, col->arraysize, flip); if (ret) break; } } free(buf); if (in_memory(table)) bl_append(table->rows, thisrow); free(thisrow); table->table->nr++; return ret; }
static void bl_sort_rec(bl* list, void* pivot, int (*compare)(const void* v1, const void* v2, void* userdata), void* userdata) { bl* less; bl* equal; bl* greater; int i; bl_node* node; // Empty case if (!list->head) return; // Base case: list with only one block. if (list->head == list->tail) { bl_node* node; struct funcandtoken ft; ft.compare = compare; ft.userdata = userdata; node = list->head; QSORT_R(NODE_DATA(node), node->N, list->datasize, &ft, qcompare); return; } less = bl_new(list->blocksize, list->datasize); equal = bl_new(list->blocksize, list->datasize); greater = bl_new(list->blocksize, list->datasize); for (node=list->head; node; node=node->next) { char* data = NODE_CHARDATA(node); for (i=0; i<node->N; i++) { int val = compare(data, pivot, userdata); if (val < 0) bl_append(less, data); else if (val > 0) bl_append(greater, data); else bl_append(equal, data); data += list->datasize; } } // recurse before freeing anything... bl_sort_with_userdata(less, compare, userdata); bl_sort_with_userdata(greater, compare, userdata); for (node=list->head; node;) { bl_node* next; next = node->next; bl_free_node(node); node = next; } list->head = NULL; list->tail = NULL; list->N = 0; list->last_access = NULL; list->last_access_n = 0; if (less->N) { list->head = less->head; list->tail = less->tail; list->N = less->N; } if (equal->N) { if (list->N) { list->tail->next = equal->head; list->tail = equal->tail; } else { list->head = equal->head; list->tail = equal->tail; } list->N += equal->N; } if (greater->N) { if (list->N) { list->tail->next = greater->head; list->tail = greater->tail; } else { list->head = greater->head; list->tail = greater->tail; } list->N += greater->N; } // note, these are supposed to be "free", not "bl_free"; we've stolen // the blocks, we're just freeing the headers. free(less); free(equal); free(greater); }
/** * Insert the element "data" into the list, such that its index is "index". * All elements that previously had indices "index" and above are moved * one position to the right. */ void bl_insert(bl* list, int index, const void* data) { bl_node* node; int nskipped; if (list->N == index) { bl_append(list, data); return; } node = find_node(list, index, &nskipped); list->last_access = node; list->last_access_n = nskipped; // if the node is full: // if we're inserting at the end of this node, then create a new node. // else, shift all but the last element, add in this element, and // add the last element to a new node. if (node->N == list->blocksize) { int localindex, nshift; bl_node* next = node->next; bl_node* destnode; localindex = index - nskipped; // if the next node exists and is not full, then insert the overflowing // element at the front. otherwise, create a new node. if (next && (next->N < list->blocksize)) { // shift the existing elements up by one position... memmove(NODE_CHARDATA(next) + list->datasize, NODE_CHARDATA(next), next->N * list->datasize); destnode = next; } else { // create and insert a new node. bl_node* newnode = bl_new_node(list); newnode->next = next; node->next = newnode; if (!newnode->next) list->tail = newnode; destnode = newnode; } if (localindex == node->N) { // the new element becomes the first element in the destination node. memcpy(NODE_CHARDATA(destnode), data, list->datasize); } else { // the last element in this node is added to the destination node. memcpy(NODE_CHARDATA(destnode), NODE_CHARDATA(node) + (node->N-1)*list->datasize, list->datasize); // shift the end portion of this node up by one... nshift = node->N - localindex - 1; memmove(NODE_CHARDATA(node) + (localindex+1) * list->datasize, NODE_CHARDATA(node) + localindex * list->datasize, nshift * list->datasize); // insert the new element... memcpy(NODE_CHARDATA(node) + localindex * list->datasize, data, list->datasize); } destnode->N++; list->N++; } else { // shift... int localindex, nshift; localindex = index - nskipped; nshift = node->N - localindex; memmove(NODE_CHARDATA(node) + (localindex+1) * list->datasize, NODE_CHARDATA(node) + localindex * list->datasize, nshift * list->datasize); // insert... memcpy(NODE_CHARDATA(node) + localindex * list->datasize, data, list->datasize); node->N++; list->N++; } }
int main(int argc, char** args) { int c; anbool help = FALSE; char* outdir = NULL; char* cmd; int i, j, f; int inputnum; int rtn; sl* engineargs; int nbeargs; anbool fromstdin = FALSE; anbool overwrite = FALSE; anbool cont = FALSE; anbool skip_solved = FALSE; anbool makeplots = TRUE; double plotscale = 1.0; char* inbgfn = NULL; char* bgfn = NULL; char* me; anbool verbose = FALSE; int loglvl = LOG_MSG; char* outbase = NULL; anbool usecurl = TRUE; bl* opts; augment_xylist_t theallaxy; augment_xylist_t* allaxy = &theallaxy; int nmyopts; char* removeopts = "ixo\x01"; char* newfits; char* kmz = NULL; char* scamp = NULL; char* scampconfig = NULL; char* index_xyls; anbool just_augment = FALSE; anbool engine_batch = FALSE; bl* batchaxy = NULL; bl* batchsf = NULL; sl* outfiles; sl* tempfiles; // these are deleted after the outer loop over input files sl* tempfiles2; sl* tempdirs; anbool timestamp = FALSE; anbool tempaxy = FALSE; errors_print_on_exit(stderr); fits_use_error_system(); me = find_executable(args[0], NULL); engineargs = sl_new(16); append_executable(engineargs, "astrometry-engine", me); // output filenames. outfiles = sl_new(16); tempfiles = sl_new(4); tempfiles2 = sl_new(4); tempdirs = sl_new(4); rtn = 0; nmyopts = sizeof(options)/sizeof(an_option_t); opts = opts_from_array(options, nmyopts, NULL); augment_xylist_add_options(opts); // remove duplicate short options. for (i=0; i<nmyopts; i++) { an_option_t* opt1 = bl_access(opts, i); for (j=nmyopts; j<bl_size(opts); j++) { an_option_t* opt2 = bl_access(opts, j); if (opt2->shortopt == opt1->shortopt) bl_remove_index(opts, j); } } // remove unwanted augment-xylist options. for (i=0; i<strlen(removeopts); i++) { for (j=nmyopts; j<bl_size(opts); j++) { an_option_t* opt2 = bl_access(opts, j); if (opt2->shortopt == removeopts[i]) bl_remove_index(opts, j); } } // which options are left? /*{ char options[256]; memset(options, 0, 256); printf("options:\n"); for (i=0; i<bl_size(opts); i++) { an_option_t* opt = bl_access(opts, i); printf(" %c (%i) %s\n", opt->shortopt, (int)opt->shortopt, opt->name); options[(int)((opt->shortopt + 256) % 256)] = 1; } printf("Remaining short opts:\n"); for (i=0; i<256; i++) { if (!options[i]) printf(" %c (%i, 0x%x)\n", (char)i, i, i); } }*/ augment_xylist_init(allaxy); // default output filename patterns. allaxy->axyfn = "%s.axy"; allaxy->matchfn = "%s.match"; allaxy->rdlsfn = "%s.rdls"; allaxy->solvedfn = "%s.solved"; allaxy->wcsfn = "%s.wcs"; allaxy->corrfn = "%s.corr"; newfits = "%s.new"; index_xyls = "%s-indx.xyls"; while (1) { int res; c = opts_getopt(opts, argc, args); //printf("option %c (%i)\n", c, (int)c); if (c == -1) break; switch (c) { case '\x91': allaxy->axyfn = optarg; break; case '\x90': tempaxy = TRUE; break; case '\x88': timestamp = TRUE; break; case '\x84': plotscale = atof(optarg); break; case '\x85': inbgfn = optarg; break; case '\x87': allaxy->assume_fits_image = TRUE; break; case '(': engine_batch = TRUE; break; case '@': just_augment = TRUE; break; case 'U': index_xyls = optarg; break; case 'n': scampconfig = optarg; break; case 'i': scamp = optarg; break; case 'Z': kmz = optarg; break; case 'N': newfits = optarg; break; case 'h': help = TRUE; break; case 'v': sl_append(engineargs, "--verbose"); verbose = TRUE; allaxy->verbosity++; loglvl++; break; case 'D': outdir = optarg; break; case 'o': outbase = optarg; break; case 'b': case '\x89': sl_append(engineargs, "--config"); append_escape(engineargs, optarg); break; case 'f': fromstdin = TRUE; break; case 'O': overwrite = TRUE; break; case 'p': makeplots = FALSE; break; case 'G': usecurl = FALSE; break; case 'K': cont = TRUE; break; case 'J': skip_solved = TRUE; break; default: res = augment_xylist_parse_option(c, optarg, allaxy); if (res) { rtn = -1; goto dohelp; } } } if ((optind == argc) && !fromstdin) { printf("ERROR: You didn't specify any files to process.\n"); help = TRUE; } if (help) { dohelp: print_help(args[0], opts); exit(rtn); } bl_free(opts); // --dont-augment: advertised as just write xy file, // so quit after doing that. if (allaxy->dont_augment) { just_augment = TRUE; } log_init(loglvl); if (timestamp) log_set_timestamp(TRUE); if (kmz && starts_with(kmz, "-")) logmsg("Do you really want to save KMZ to the file named \"%s\" ??\n", kmz); if (starts_with(newfits, "-")) { logmsg("Do you really want to save the new FITS file to the file named \"%s\" ??\n", newfits); } if (engine_batch) { batchaxy = bl_new(16, sizeof(augment_xylist_t)); batchsf = bl_new(16, sizeof(solve_field_args_t)); } // Allow (some of the) default filenames to be disabled by setting them to "none". allaxy->matchfn = none_is_null(allaxy->matchfn); allaxy->rdlsfn = none_is_null(allaxy->rdlsfn); allaxy->solvedfn = none_is_null(allaxy->solvedfn); allaxy->solvedinfn = none_is_null(allaxy->solvedinfn); allaxy->wcsfn = none_is_null(allaxy->wcsfn); allaxy->corrfn = none_is_null(allaxy->corrfn); newfits = none_is_null(newfits); index_xyls = none_is_null(index_xyls); if (outdir) { if (mkdir_p(outdir)) { ERROR("Failed to create output directory %s", outdir); exit(-1); } } // number of engine args not specific to a particular file nbeargs = sl_size(engineargs); f = optind; inputnum = 0; while (1) { char* infile = NULL; anbool isxyls; char* reason; int len; char* base; char* basedir; char* basefile = NULL; char *objsfn=NULL; char *ppmfn=NULL; char* downloadfn = NULL; char* suffix = NULL; sl* cmdline; anbool ctrlc; anbool isurl; augment_xylist_t theaxy; augment_xylist_t* axy = &theaxy; int j; solve_field_args_t thesf; solve_field_args_t* sf = &thesf; anbool want_pnm = FALSE; // reset augment-xylist args. memcpy(axy, allaxy, sizeof(augment_xylist_t)); memset(sf, 0, sizeof(solve_field_args_t)); if (fromstdin) { char fnbuf[1024]; if (!fgets(fnbuf, sizeof(fnbuf), stdin)) { if (ferror(stdin)) SYSERROR("Failed to read a filename from stdin"); break; } len = strlen(fnbuf); if (fnbuf[len-1] == '\n') fnbuf[len-1] = '\0'; infile = fnbuf; logmsg("Reading input file \"%s\"...\n", infile); } else { if (f == argc) break; infile = args[f]; f++; logmsg("Reading input file %i of %i: \"%s\"...\n", f - optind, argc - optind, infile); } inputnum++; cmdline = sl_new(16); if (!engine_batch) { // Remove arguments that might have been added in previous trips through this loop sl_remove_from(engineargs, nbeargs); } // Choose the base path/filename for output files. if (outbase) asprintf_safe(&basefile, outbase, inputnum, infile); else basefile = basename_safe(infile); //logverb("Base filename: %s\n", basefile); isurl = (!file_exists(infile) && (starts_with(infile, "http://") || starts_with(infile, "ftp://"))); if (outdir) basedir = strdup(outdir); else { if (isurl) basedir = strdup("."); else basedir = dirname_safe(infile); } //logverb("Base directory: %s\n", basedir); asprintf_safe(&base, "%s/%s", basedir, basefile); //logverb("Base name for output files: %s\n", base); // trim .gz, .bz2 // hmm, we drop the suffix in this case... len = strlen(base); if (ends_with(base, ".gz")) base[len-3] = '\0'; else if (ends_with(base, ".bz2")) base[len-4] = '\0'; len = strlen(base); // trim .xx / .xxx / .xxxx if (len >= 5) { for (j=3; j<=5; j++) { if (base[len - j] == '/') break; if (base[len - j] == '.') { base[len - j] = '\0'; suffix = base + len - j + 1; break; } } } logverb("Base: \"%s\", basefile \"%s\", basedir \"%s\", suffix \"%s\"\n", base, basefile, basedir, suffix); if (tempaxy) { axy->axyfn = create_temp_file("axy", axy->tempdir); sl_append_nocopy(tempfiles2, axy->axyfn); } else axy->axyfn = sl_appendf(outfiles, axy->axyfn, base); if (axy->matchfn) axy->matchfn = sl_appendf(outfiles, axy->matchfn, base); if (axy->rdlsfn) axy->rdlsfn = sl_appendf(outfiles, axy->rdlsfn, base); if (axy->solvedfn) axy->solvedfn = sl_appendf(outfiles, axy->solvedfn, base); if (axy->wcsfn) axy->wcsfn = sl_appendf(outfiles, axy->wcsfn, base); if (axy->corrfn) axy->corrfn = sl_appendf(outfiles, axy->corrfn, base); if (axy->cancelfn) axy->cancelfn = sl_appendf(outfiles, axy->cancelfn, base); if (axy->keepxylsfn) axy->keepxylsfn = sl_appendf(outfiles, axy->keepxylsfn, base); if (axy->pnmfn) axy->pnmfn = sl_appendf(outfiles, axy->pnmfn, base); if (newfits) sf->newfitsfn = sl_appendf(outfiles, newfits, base); if (kmz) sf->kmzfn = sl_appendf(outfiles, kmz, base); if (index_xyls) sf->indxylsfn = sl_appendf(outfiles, index_xyls, base); if (scamp) sf->scampfn = sl_appendf(outfiles, scamp, base); if (scampconfig) sf->scampconfigfn = sl_appendf(outfiles, scampconfig, base); if (makeplots) { objsfn = sl_appendf(outfiles, "%s-objs.png", base); sf->redgreenfn = sl_appendf(outfiles, "%s-indx.png", base); sf->ngcfn = sl_appendf(outfiles, "%s-ngc.png", base); } if (isurl) { if (suffix) downloadfn = sl_appendf(outfiles, "%s.%s", base, suffix); else downloadfn = sl_appendf(outfiles, "%s", base); } if (axy->solvedinfn) asprintf_safe(&axy->solvedinfn, axy->solvedinfn, base); // Do %s replacement on --verify-wcs entries... if (sl_size(axy->verifywcs)) { sl* newlist = sl_new(4); for (j=0; j<sl_size(axy->verifywcs); j++) sl_appendf(newlist, sl_get(axy->verifywcs, j), base); axy->verifywcs = newlist; } // ... and plot-bg if (inbgfn) asprintf_safe(&bgfn, inbgfn, base); if (axy->solvedinfn && axy->solvedfn && streq(axy->solvedfn, axy->solvedinfn)) { // solved input and output files are the same: don't delete the input! sl_remove_string(outfiles, axy->solvedfn); free(axy->solvedfn); axy->solvedfn = axy->solvedinfn; } free(basedir); free(basefile); if (skip_solved) { char* tocheck[] = { axy->solvedinfn, axy->solvedfn }; for (j=0; j<sizeof(tocheck)/sizeof(char*); j++) { if (!tocheck[j]) continue; logverb("Checking for solved file %s\n", tocheck[j]); if (file_exists(tocheck[j])) { logmsg("Solved file exists: %s; skipping this input file.\n", tocheck[j]); goto nextfile; } else { logverb("File \"%s\" does not exist.\n", tocheck[j]); } } } // Check for overlap between input and output filenames for (i = 0; i < sl_size(outfiles); i++) { char* fn = sl_get(outfiles, i); if (streq(fn, infile)) { logmsg("Output filename \"%s\" is the same as your input file.\n" "Refusing to continue.\n" "You can either choose a different output filename, or\n" "rename your input file to have a different extension.\n", fn); goto nextfile; } } // Check for (and possibly delete) existing output filenames. for (i = 0; i < sl_size(outfiles); i++) { char* fn = sl_get(outfiles, i); if (!file_exists(fn)) continue; if (cont) { } else if (overwrite) { if (unlink(fn)) { SYSERROR("Failed to delete an already-existing output file \"%s\"", fn); exit(-1); } } else { logmsg("Output file already exists: \"%s\".\n" "Use the --overwrite flag to overwrite existing files,\n" " or the --continue flag to not overwrite existing files but still try solving.\n", fn); logmsg("Continuing to next input file.\n"); goto nextfile; } } // if we're making "redgreen" plot, we need: if (sf->redgreenfn) { // -- index xylist if (!sf->indxylsfn) { sf->indxylsfn = create_temp_file("indxyls", axy->tempdir); sl_append_nocopy(tempfiles, sf->indxylsfn); } // -- match file. if (!axy->matchfn) { axy->matchfn = create_temp_file("match", axy->tempdir); sl_append_nocopy(tempfiles, axy->matchfn); } } // if index xyls file is needed, we need: if (sf->indxylsfn) { // -- wcs if (!axy->wcsfn) { axy->wcsfn = create_temp_file("wcs", axy->tempdir); sl_append_nocopy(tempfiles, axy->wcsfn); } // -- rdls if (!axy->rdlsfn) { axy->rdlsfn = create_temp_file("rdls", axy->tempdir); sl_append_nocopy(tempfiles, axy->rdlsfn); } } // Download URL... if (isurl) { sl_append(cmdline, usecurl ? "curl" : "wget"); if (!verbose) sl_append(cmdline, usecurl ? "--silent" : "--quiet"); sl_append(cmdline, usecurl ? "--output" : "-O"); append_escape(cmdline, downloadfn); append_escape(cmdline, infile); cmd = sl_implode(cmdline, " "); logmsg("Downloading...\n"); if (run_command(cmd, &ctrlc)) { ERROR("%s command %s", sl_get(cmdline, 0), (ctrlc ? "was cancelled" : "failed")); exit(-1); } sl_remove_all(cmdline); free(cmd); infile = downloadfn; } if (makeplots) want_pnm = TRUE; if (axy->assume_fits_image) { axy->imagefn = infile; if (axy->pnmfn) want_pnm = TRUE; } else { logverb("Checking if file \"%s\" ext %i is xylist or image: ", infile, axy->extension); fflush(NULL); reason = NULL; isxyls = xylist_is_file_xylist(infile, axy->extension, axy->xcol, axy->ycol, &reason); logverb(isxyls ? "xyls\n" : "image\n"); if (!isxyls) logverb(" (not xyls because: %s)\n", reason); free(reason); fflush(NULL); if (isxyls) axy->xylsfn = infile; else { axy->imagefn = infile; want_pnm = TRUE; } } if (want_pnm && !axy->pnmfn) { ppmfn = create_temp_file("ppm", axy->tempdir); sl_append_nocopy(tempfiles, ppmfn); axy->pnmfn = ppmfn; axy->force_ppm = TRUE; } axy->keep_fitsimg = (newfits || scamp); if (augment_xylist(axy, me)) { ERROR("augment-xylist failed"); exit(-1); } if (just_augment) goto nextfile; if (makeplots) { // Check that the plotting executables were built... char* exec = find_executable("plotxy", me); free(exec); if (!exec) { logmsg("Couldn't find \"plotxy\" executable - maybe you didn't build the plotting programs?\n"); logmsg("Disabling plots.\n"); makeplots = FALSE; } } if (makeplots) { // source extraction overlay if (plot_source_overlay(axy, me, objsfn, plotscale, bgfn)) makeplots = FALSE; } append_escape(engineargs, axy->axyfn); if (file_readable(axy->wcsfn)) axy->wcs_last_mod = file_get_last_modified_time(axy->wcsfn); else axy->wcs_last_mod = 0; if (!engine_batch) { run_engine(engineargs); after_solved(axy, sf, makeplots, me, verbose, axy->tempdir, tempdirs, tempfiles, plotscale, bgfn); } else { bl_append(batchaxy, axy); bl_append(batchsf, sf ); } fflush(NULL); // clean up and move on to the next file. nextfile: free(base); sl_free2(cmdline); if (!engine_batch) { free(axy->fitsimgfn); free(axy->solvedinfn); free(bgfn); // erm. if (axy->verifywcs != allaxy->verifywcs) sl_free2(axy->verifywcs); sl_remove_all(outfiles); if (!axy->no_delete_temp) delete_temp_files(tempfiles, tempdirs); } errors_print_stack(stdout); errors_clear_stack(); logmsg("\n"); } if (engine_batch) { run_engine(engineargs); for (i=0; i<bl_size(batchaxy); i++) { augment_xylist_t* axy = bl_access(batchaxy, i); solve_field_args_t* sf = bl_access(batchsf, i); after_solved(axy, sf, makeplots, me, verbose, axy->tempdir, tempdirs, tempfiles, plotscale, bgfn); errors_print_stack(stdout); errors_clear_stack(); logmsg("\n"); free(axy->fitsimgfn); free(axy->solvedinfn); // erm. if (axy->verifywcs != allaxy->verifywcs) sl_free2(axy->verifywcs); } if (!allaxy->no_delete_temp) delete_temp_files(tempfiles, tempdirs); bl_free(batchaxy); bl_free(batchsf); } if (!allaxy->no_delete_temp) delete_temp_files(tempfiles2, NULL); sl_free2(outfiles); sl_free2(tempfiles); sl_free2(tempfiles2); sl_free2(tempdirs); sl_free2(engineargs); free(me); augment_xylist_free_contents(allaxy); return 0; }